=== Trace listing source: gshare.lst 1 ; Title Share_1 - IBM CONFIDENTIAL 2 ; $SALUT (0,36,41,44) 3 %include "sharehdr.mac" 1 <1> ; page 80,132 2 <1> ;******************* START OF SPECIFICATIONS *********************************** 3 <1> ; 4 <1> ; MODULE NAME: SHARE.EXE (a true EXE file) 5 <1> ; 6 <1> ; DESCRIPTIVE NAME: SHARE resident service routines - part 1 - GSHARE.SAL 7 <1> ; - part 2 - GSHARE2.SAL 8 <1> ; - part 3 - SHARESR.SAL 9 <1> ; 10 <1> ; FUNCTION: Provide file sharing services for DOS 11 <1> ; 12 <1> ; ENTRY POINT: DOS Jump Table - installed by SHARE at initalization 13 <1> ; 14 <1> ; MFT_Enter 1 15 <1> ; MFTClose 2 16 <1> ; MFTClu 3 17 <1> ; MFTCloseP 4 18 <1> ; MFTCloN 5 19 <1> ; Set_Mult_Block 6 20 <1> ; Clr_Mult_Block 7 21 <1> ; Chk_Block 8 22 <1> ; MFT_Get 9 23 <1> ; 24 <1> ; INPUT: See Prolog to individual entry points 25 <1> ; 26 <1> ; EXIT NORMAL: CF = 0 and requested task performed. 27 <1> ; 28 <1> ; EXIT ERROR: CF = 1 ans error code in AX 29 <1> ; 30 <1> ; INTERNAL REFERENCES: 31 <1> ; 32 <1> ; ROUTINES: Set_Block BCS 33 <1> ; Clr_Block CSL 34 <1> ; CLP CUC 35 <1> ; Load_Regs CSI 36 <1> ; ASC GOM 37 <1> ; 38 <1> ; DATA AREAS: 39 <1> ; 40 <1> ; EXTERNAL REFERENCES: INT 21 INT 2F 41 <1> ; together with: 42 <1> ; 43 <1> ; fnm:near, rsc:near, rmn:near, cps:near, ofl:near, sle:near, interr:near 44 <1> ; 45 <1> ; ROUTINES: 46 <1> ; 47 <1> ; DATA AREAS: 48 <1> ; 49 <1> ; NOTES: The second part of this utility is GSHARE2.ASM 50 <1> ; 51 <1> ; REVISION HISTORY: Version 1.0 09/09/83 - first release GL 52 <1> ; 09/13/83 - Installability MZ 53 <1> ; 01/11/84 - FCB compatability changes MZ 54 <1> ; PTM P000438 08/21/86 - SFT LCK FIELDS not 0 error DL 55 <1> ; Ax000 Ver 4.0 04/15/87 - changed:- Set_Block FJG 56 <1> ; - Clr_Block FJG 57 <1> ; - Chk_Block FJG 58 <1> ; - CLP FJG 59 <1> ; new: - Set_Mult_Block FJG 60 <1> ; - Clr_Mult_Block FJG 61 <1> ; - Load_Regs FJG 62 <1> ; - Clr_List FJG 63 <1> ; Ax002 PTM P001658 10/15/87 - changed I/F to IBMDOS FJG 64 <1> ; Ax003 PTM P002064 10/15/87 - ShSU SFT - IFS call error FJG 65 <1> ; Ax004 PTM P002121 10/29/87 - Clr_Mult_Block cx=-1 err FJG 66 <1> ; Ax005 PTM P002322 11/06/87 - Call_IFS - 2F semaphore FJG 67 <1> ; Ax006 DCR D000494 12/17/87 - DOS 4.00 function reductionFJG 68 <1> ; Ax007 PTM P003841 03/17/88 - access error for Turbo L FJG 69 <1> ; Ax008 PTM P003880 03/17/88 - duped handle error FJG 70 <1> ; Ax009 PTM P003910 03/17/88 - wrong parse error format FJG 71 <1> ; Ax010 DCR D000526 04/27/88 - add /nc switch support FJG 72 <1> ; Ax011 PTM P004546 05/03/88 - add /nc support to fShare FJG 4 ; 5 ; Label: "The DOS SHARE Utility" 6 ; "Version 4.00 (C) Copyright 1988 Microsoft" 7 ; "Licenced Material - Program Property of Microsoft" 8 ; 9 ;******************* END OF SPECIFICATIONS ************************************* 10 === Switch to base=000000h -> "SHARE" 11 section SHARE align=16 PUBLIC class=SHARE 12 extrn fnm:near, rsc:near, rmn:near, cps:near, ofl:near, sle:near, interr:near 13 14 ; NAME Sharer 15 16 [list -] 16 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 16 ****************** warning: out: BPB.INC... [-w+user] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 16 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 24 25 %ifndef IBM 26 %iassign IBM 0 27 %endif 28 %ifndef Installed 29 %iassign Installed 0 30 %endif 31 32 %iassign Installed TRUE ; for installed version 33 34 ; NASM original macros 35 36 %imacro OFF 2.nolist 37 %if Installed 38 mov %1, offset %2 39 %else 40 mov %1, offset %2 wrt DOSGROUP 41 %endif 42 %endmacro 43 44 %unimacro detectstripangles 4.nolist 45 46 %imacro detectstripangles 4.nolist 47 %defstr %%param %4 48 %assign ?%2 0 49 %assign ?%3 0 50 %rep 16 51 %substr %%opening %%param 1 52 %ifidn %%opening, '<' 53 %substr %%param %%param 2,-1 54 %assign ?%2 ?%2 + 1 55 %endif 56 %endrep 57 %rep 16 58 %strlen %%length %%param 59 %substr %%closing %%param %%length 60 %ifidn %%closing, '>' 61 %substr %%param %%param 1,-2 62 %assign ?%3 ?%3 + 1 63 %endif 64 %endrep 65 %deftok %%token %%param 66 %define ?%1 %%token 67 %endmacro 68 69 %unimacro errnz 1.nolist 70 71 %imacro errnz 1.nolist 72 detectstripangles %%token, %%opening, %%closing, %1 73 %if ? %+ %%token 74 %error %1 <> 0, ERRNZ failed 75 %endif 76 %endmacro 77 78 ; end of NASM original macros 79 80 mft equ MFT ; NASM port label 81 quux equ mft 82 83 ; if we are installed, then define the base code segment of the sharer first 84 85 %IF Installed === Switch to base=000000h -> "SHARE" 86 section SHARE 87 ; (no prior section) ; Share ENDS 88 ; include the rest of the segment definitions for normal msdos 89 ; We CANNOT include dosseg because start is not declared para in that file 90 91 ; $SALUT (4,9,17,36) 92 === Switch to base=001DC0h -> "DOSSTART" 93 section DOSSTART align=16 PUBLIC class=DOSSTART 94 ; (no prior section) ; DOSSTART ENDS 95 === Switch to base=001DC0h -> "START" 96 section START align=1 PUBLIC class=START 97 ; (no prior section) ; START ENDS 98 === Switch to base=001DC0h -> "CONSTANTS" 99 section CONSTANTS align=2 PUBLIC class=CONST 100 ; (no prior section) ; CONSTANTS ENDS 101 === Switch to base=001DC0h -> "DATA" 102 section DATA align=2 PUBLIC class=DATA 103 ; (no prior section) ; DATA ENDS 104 === Switch to base=001DC0h -> "TABLE" 105 section TABLE align=1 PUBLIC class=TABLE 106 ; (no prior section) ; TABLE ENDS 107 === Switch to base=001DC0h -> "CODE" 108 section CODE align=1 PUBLIC class=CODE 109 ; (no prior section) ; CODE ENDS 110 === Switch to base=001DC0h -> "LAST" 111 section LAST align=16 PUBLIC class=LAST 112 ; (no prior section) ; LAST ENDS 113 114 group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE LAST 115 %ELSE 116 %include "dosseg.nas" 117 %ENDIF 118 === Switch to base=0032E0h -> "STACK" 119 section STACK stack class=STACK 120 ; (no prior section) ; STACK ENDS 121 === Switch to base=001DC0h -> "DATA" 122 section DATA 123 Extrn ThisSFT:DWORD ; pointer to SFT entry 124 Extrn User_ID:WORD 125 Extrn Proc_ID:WORD 126 Extrn WFP_START:WORD 127 Extrn BytPos:DWORD 128 extrn OpenBuf:BYTE 129 extrn user_in_ax:WORD 130 %IF debug 131 Extrn BugLev:WORD 132 Extrn BugTyp:WORD 133 %include "bugtyp.nas" 134 %ENDIF 135 ; (no prior section) ; DATA ENDS 136 137 ; if we are not installed, then the code here is just part of the normal 138 ; MSDOS code segment otherwise, define our own code segment 139 140 ; .sall 141 %IFN INSTALLED === Switch to base=001DC0h -> "CODE" 142 section CODE 143 ASSUME SS:DOSGROUP,CS:DOSGROUP 144 %ELSE === Switch to base=000000h -> "SHARE" 145 section SHARE 146 ASSUME SS:DOSGROUP,CS:SHARE 147 %ENDIF 148 149 extrn MFT:BYTE 150 extrn skip_check:BYTE 151 152 %include "mft.mac" 1 <1> BREAK 2 <1> 3 <1> ;** MSDOS MFT definitions 4 <1> ; 5 <1> ; The Master File Table (MFT) associates the cannonicalized pathnames, lock 6 <1> ; records and SFTs for all files open on this machine. 7 <1> ; 8 <1> ; The MFT implementation employs a single memory buffer which is used from 9 <1> ; both ends. This gives the effect (at least until they run into each 10 <1> ; other) of two independent buffers. 11 <1> ; 12 <1> ; MFT buffer 13 <1> ; ========== 14 <1> ; The MFT buffer contains MFT name records and free space. It uses a 15 <1> ; classic heap architecture: freed name records are marked free and 16 <1> ; conglomerated with any adjacent free space. When one is to create a name 17 <1> ; entry the free list is searched first-fit. The list of name and free 18 <1> ; records is always terminated by a single END record. 19 <1> ; 20 <1> ; LOCK buffer 21 <1> ; =========== 22 <1> ; The lock buffer contains fixed format records containing record locking 23 <1> ; information. Since they are fixed format the space is handled as a series 24 <1> ; of chains: one for each MFT name record and one for the free list. No 25 <1> ; garbage collection is necessary. 26 <1> ; 27 <1> ; Space allocation 28 <1> ; ================ 29 <1> ; The MFT is managed as a heap. Empty blocks are allocated on a first-fit 30 <1> ; basis. If there is no single large enough empty block the list is garbage 31 <1> ; collected. 32 <1> ; 33 <1> ; MFT name records: 34 <1> ; 35 <1> ; 8 16 8 16 32 16 n 36 <1> ; |------|-----|-----|------|------|------|---------~~~~~~---------| 37 <1> ; | FLAG | LEN | SUM | LPTR | SPTR | SERL | <.asciz string> | 38 <1> ; --------------------------------------------------~~~~~~---------- 39 <1> ; 40 <1> ; FLAG = record type flag 41 <1> ; LEN = total byte length of record. 42 <1> ; SUM = sum of bytes in asciz string. Used to speed 43 <1> ; searches 44 <1> ; LPTR= pointer to first record in lock chain segment 45 <1> ; is MFT segment 46 <1> ; SPTR= pointer to first sft in sft chain 47 <1> ; SERL= serial number 48 <1> ; = name string, zero-byte terminated. There 49 <1> ; may be garbage bytes following the 00 byte; 50 <1> ; these are counted in the LEN field. 51 <1> ; 52 <1> ; 53 <1> ; MFT free records 54 <1> ; 55 <1> ; 8 16 56 <1> ; |------|-----|----~~~~~~~~~~~~~~~~~~~~~~~~~~~---------| 57 <1> ; | FLAG | LEN | free | 58 <1> ; ------------------~~~~~~~~~~~~~~~~~~~~~~~~~~~---------- 59 <1> ; 60 <1> ; FLAG = record type flag 61 <1> ; LEN = total byte length of record. 62 <1> ; 63 <1> ; 64 <1> ; MFT END records 65 <1> ; 66 <1> ; 8 67 <1> ; |------| 68 <1> ; | FLAG | 69 <1> ; -------- 70 <1> ; 71 <1> ; FLAG = record type flag 72 <1> 73 <1> ;** MFT definitions 74 <1> ;* 75 <1> ;* NOTE: the flag and length fields are identical for all record types 76 <1> ;* (except the END type has no length) This must remain so as 77 <1> ;* some code depends upon it. 78 <1> ;* 79 <1> ;* NOTE: Many routines check for "n-1" of the N flag values and if no 80 <1> ;* match is found assume the flag value must be the remaining 81 <1> ;* possibility. If you add or remove flag values you must check 82 <1> ;* all references to mft_flag. 83 <1> 84 <1> MFT_entry STRUC 85 <1> 0 00000000 ?? mft_flag DB ? ; flag/len field 0 00000001 ???? mft_len DW ? 0 00000003 ?? mft_sum DB ? ; string sum word 0 00000004 ???? mft_lptr DW ? ; LCK pointer 0 00000006 ???????? mft_sptr DD ? ; sft pointer 0 0000000A ???? mft_serl DW ? ; serial number 0 0000000C ?? mft_name DB ? ; offset to start of name 93 <1> 94 <1> MFT_entry ENDS 95 <1> 96 <1> MFLG_NAM EQU 1 ; min value for name record 97 <1> MFLG_FRE EQU 0 ; free record 98 <1> MFLG_END EQU -1 ; end record 99 <1> 100 <1> ;* Record Lock Record (RLR): 101 <1> ; 102 <1> ; 16 32 32 32 103 <1> ; |-------|--------|--------|--------| 104 <1> ; | NEXT | FBA | LBA | SPTR | 105 <1> ; | | lo hi | lo hi | | 106 <1> ; ------------|--------|-------------- 107 <1> ; 108 <1> ; CHAIN = pointer to next RLR. 0 if end 109 <1> ; FBA = offset of 1st byte of locked region 110 <1> ; LBA = offset of last byte of locked region 111 <1> ; SPTR = pointer to SFT lock was issued on 112 <1> 113 <1> RLR_entry STRUC 114 <1> 0 00000000 ???? rlr_next DW ? ; chain to next RLR, 0 if end 0 00000002 ???? rlr_fba DW ? ; first byte addr (offset) of reigion 0 00000004 ???? DW ? 0 00000006 ???? rlr_lba DW ? ; last byte addr of region 0 00000008 ???? DW ? 0 0000000A ???????? rlr_sptr DD ? ; SFT pointer 0 0000000E ???? rlr_pid dw ? ; process id of issuer 0 00000010 ???? rlr_type dw ? ; lock type 123 <1> RLR_entry ENDS 124 <1> 125 <1> rlr_lall equ 00h ; lock all ops 126 <1> rlr_lwr equ 01h ; lock write ops 127 <1> 128 <1> ; 129 <1> ; A pictorial diagram for the linkages is as follows: 130 <1> ; 131 <1> ; +---sptr------+ 132 <1> ; V | 133 <1> ; +---+<----------|---sptr------+------------+ 134 <1> ; |SFT+----+ | | | 135 <1> ; +-+-+ | +-+-+ +--+-+ +--+-+ 136 <1> ; V +--->|MFT+-lptr->-|LOCK+-next->|LOCK+->0 137 <1> ; +---+ | +---+ +----+ +----+ 138 <1> ; |SFT+----+ ^ 139 <1> ; +-+-+ | 140 <1> ; | | 141 <1> ; +-------------+ 142 <1> ; 143 <1> ; 144 <1> 145 <1> ;** 146 <1> ; 147 <1> ; Interesting behavior should be noted: 148 <1> ; 149 <1> ; The sharer must maintain information on files in three forms: 150 <1> ; 151 <1> ; local/remote handles. These are normal handles and behave in no 152 <1> ; strange manner. They are identified by SF_mode not having the 153 <1> ; sfIsFCB flag nor by having the sf_mode = 70. No problems with 154 <1> ; locking. No problems with open. No problems with close. 155 <1> ; CloseByName will iterate closes until the mft disappears. 156 <1> ; CloseUser will iterate closes until no SFT for the particular user 157 <1> ; appears. CloseProcess will iterate closes until no SFT for the 158 <1> ; particular user/process appears. 159 <1> ; 160 <1> ; local FCBs. There are no corresponding SFT's for these as the SFTs 161 <1> ; are cached but will be valid for the particular file. There is 162 <1> ; one SFT for each open on a file by a specific process. These are 163 <1> ; identified the sfIsFCB flag in the sf_mode field. When multiple 164 <1> ; opens occur, we merely find the sf pertinent to the file and 165 <1> ; process. Close decrements the ref count. CloseByName, CloseUser, 166 <1> ; CloseProcess will iterate closes until no more SFTs exist. 167 <1> ; 168 <1> ; handles with mode 70. These represent FCB's open across the network. 169 <1> ; As such, identical sfts may have been collapsed by the $open code. 170 <1> ; This results in a reuse of the same SFT. The $Open code must 171 <1> ; correctly set the ref-count for the sft to reflect the number of 172 <1> ; collapses that have occurred. These are identified by a 70 in the 173 <1> ; SF_mode field. There can be no locking on these SFTs. Open must 174 <1> ; scan the list of SFTs for the file and increment its ref count 175 <1> ; appropriately. 153 154 FreLock equ Frelock ; NASM port label 155 PUBLIC FreLock,Serial 156 157 %IF installed 0 00000000 ???? Frelock DW ? ; FWA of lock free list 159 %ELSE 160 Frelock DW OFFSET lck8 wrt DOSGROUP ; FWA of lock free list 161 %ENDIF 0 00000002 0000 Serial DW 0 ; serial number 0 00000004 0000 DS_Org dw 0 ;an000;DS on entry to routine 164 165 ZERO EQU 0 166 ONE EQU 1 167 168 FRAME struc 169 0 00000000 ???? SavedBP dw ? 0 00000002 ???? RetOFF dw ? 0 00000004 ???? Parm_1 dw ? 0 00000006 ???? Parm_2 dw ? 174 175 FRAME ends 176 177 ; $SALUT (4,4,9,41) 178 179 BREAK 180 181 ;******************* START OF SPECIFICATIONS *********************************** 182 ; 183 ; MSDOS MFT Functions 184 ; 185 ; The Master File Table (MFT) associates the cannonicalized pathnames, 186 ; lock records and SFTs for all files open on this machine. 187 ; 188 ; These functions are supplied to maintain the MFT and extract 189 ; information from it. All MFT access should be via these routines so 190 ; that the MFT structure can remain flexible. 191 ; 192 ;******************* END OF SPECIFICATIONS ************************************* 193 194 BREAK 195 196 ;******************* START OF SPECIFICATIONS *********************************** 197 ; 198 ; mft_enter - make an entry in the MFT 199 ; 200 ; mft_enter is called to make an entry in the MFT. 201 ; mft_enter checks for a file sharing conflict: 202 ; No conflict: 203 ; A new MFT entry is created, or the existing one updated, 204 ; as appropriate. 205 ; Conflicts: 206 ; The existing MFT is left alone. Note that if we had to 207 ; create a new MFT there cannot be, by definition, sharing 208 ; conflicts. 209 ; If no conflict has been discovered, the SFT list for the file is 210 ; checked for one that matches the following conditions: 211 ; 212 ; If mode == 70 then 213 ; don't link in SFT 214 ; increment refcount 215 ; If mode&sfIsFCB and userids match and process ids match then 216 ; don't link in SFT 217 ; 218 ; ENTRY ThisSFT points to an SFT structure. The sf_mode field 219 ; contains the desired sharing mode. 220 ; WFP_Start is an offset from DOSGroup of the full pathname for 221 ; the file 222 ; User_ID = 16-bit user id of issuer 223 ; Proc_ID = 16-bit process id of issuer 224 ; (DS) = (SS) = DOSGroup 225 ; EXIT 'C' clear if no error' 226 ; 'C' set if error 227 ; (ax) = error code 228 ; USES ALL but DS 229 ; 230 ;******************* END OF SPECIFICATIONS ************************************* 231 232 Procedure mft_enter,NEAR 232 ****************** warning: proc mft_enter... [-w+user] 233 234 ; int 3 0 00000006 90 nop 0 00000007 90 nop 237 0 00000008 E8[0000] EnterCrit critShare 239 240 DOSAssume SS, , "MFT_Enter entry" 241 ASSUME ES:NOTHING,SS:DOSGROUP 0 0000000B 1E push ds 243 244 ; find or make a name record 245 246 WFP_Start equ WFP_START ; NASM port label 0 0000000C 8B36[0000] mov si,[WFP_Start] ; (DS:SI) = FBA of file name 0 00000010 B001 mov al,1 ; allow creation of MFT entry 0 00000012 06 push es 250 251 ASSUME DS:NOTHING 252 253 FNM equ fnm ; NASM port label 0 00000013 E8[0000] call FNM ; find or create name in MFT 0 00000016 07 pop es 0 00000017 B82400 mov ax,error_sharing_buffer_exceeded 0 0000001A 7208 jc ent9 ; not enough space 258 ; 259 ; (bx) = fwa name record 260 ; 0 0000001C 36C536[0000] lds si,[ss:ThisSFT] 0 00000021 E88702 call ASC ; try to add to chain 263 264 ; As noted above, we don't have to worry about an "empty" name record 265 ; being left if ASC refuses to add the SFT - ASC cannot refuse if we had 266 ; just created the MFT... 267 268 ; return. 269 ; 270 ; 'C' and (Ax) setup appropriately 271 0 00000024 1F ent9: pop ds 273 0 00000025 E8[0000] LeaveCrit critShare 275 0 00000028 C3 ret 277 278 EndProc mft_enter 279 280 BREAK 281 282 ;******************* START OF SPECIFICATIONS *********************************** 283 ; 284 ; MFTclose 285 ; 286 ; MFTclose(SFT) 287 ; 288 ; MFTclose removes the SFT entry from the MFT structure. If this was 289 ; the last SFT for the particular file the file's entry is also removed 290 ; from the MFT structure. If the sharer is installed after some 291 ; processing has been done, the MFT field of the SFTs will be 0; we must 292 ; ignore these guys. 293 ; 294 ; If the sft indicates FCB, we do nothing special. The SFT behaves 295 ; EXACTLY like a normal handle. 296 ; 297 ; If the sft indicates mode 70 then we do nothing special. These are 298 ; normal HANDLES. 299 ; 300 ; Note that we always care about the SFT refcount. A refcount of 1 301 ; means that the SFT is going idle and that we need to remove the sft 302 ; from the chain. 303 ; 304 ; ENTRY (ES:DI) points to an SFT structure 305 ; (DS) = (SS) = DOSGroup 306 ; EXIT NONE 307 ; USES ALL but DS, ES:DI 308 ; 309 ;******************* END OF SPECIFICATIONS ************************************* 310 311 Procedure MFTclose,NEAR 311 ****************** warning: proc MFTclose... [-w+user] 312 313 ; int 3 0 00000029 90 nop 0 0000002A 90 nop 316 0 0000002B E8[0000] EnterCrit critShare 318 319 DOSAssume SS,,"MFTClose entry" 320 ASSUME ES:NOTHING 0 0000002E 268B4533 mov ax,[es:di + sf_MFT] 322 323 fmt TypShare,LevShEntry,<"MFTClose by $x:$x of $x:$x ($x)\n">, 324 0 00000032 09C0 or ax,ax 0 00000034 741B jz mcl10 ; No entry for it, ignore (carry clear) 0 00000036 1E push ds 0 00000037 06 push es 0 00000038 57 push di 330 ;;;call CSL ; clear SFT locks ;AC008; 331 332 ASSUME DS:NOTHING 333 0 00000039 268B05 mov ax,[es:di + sf_ref_count] ; (ax) = ref count 335 ; 336 ; We need to release information in one of two spots. First, when the SFT has 337 ; a ref count of 0. Here, there are no more referents and, thus, no sharing 338 ; record need be kept. Second, the ref count may be -1 indicating that the 339 ; sft is being kept but that the sharing information is no longer needed. 340 ; This occurs in creates of existing files, where we verify the allowed 341 ; access, truncate the file and regain the access. If the truncation 342 ; generates an error, we do NOT want to have the access locked down. 343 ; 344 345 0 0000003C 09C0 OR AX,AX 0 0000003E 7403 jz mcl85 ; ref count is 0 - don't dechain 0 00000040 40 inc ax ; -1 + 1 = 0. Busy sft. 0 00000041 750B jnz mcl9 350 mcl85: 0 00000043 E84203 call CSL ; clear SFT locks ;AC008; 352 RSC equ rsc ; NASM port label 0 00000046 E8[0000] call RSC ; remove sft from chain 0 00000049 7503 jnz mcl9 ; not the last sft for this name 355 RMN equ rmn ; NASM port label 0 0000004B E8[0000] call RMN ; remove name record 357 mcl9: 0 0000004E 5F pop di ; restore regs for exit 0 0000004F 07 pop es 0 00000050 1F pop ds 361 mcl10: 0 00000051 E8[0000] LeaveCrit critShare 363 0 00000054 C3 ret 365 366 EndProc MFTclose 367 368 BREAK 369 370 ;******************* START OF SPECIFICATIONS *********************************** 371 ; 372 ; MFTcloseU 373 ; 374 ; MFTcloseM(UID) 375 ; 376 ; MFTcloseM removes all entrys for user UID from the MFT structure. We 377 ; walk the MFT structure closing all relevant SFT's for the user. 378 ; We do it the dumb way, iterating closes until the SF ref count is 379 ; 0. 380 ; 381 ; ENTRY User_ID = 16-bit user id of issuer 382 ; (SS) + DOSGroup 383 ; EXIT 'C' clear 384 ; USES ALL 385 ; 386 ;******************* END OF SPECIFICATIONS ************************************* 387 388 Procedure MFTclU,NEAR 388 ****************** warning: proc MFTclU... [-w+user] 389 390 ; int 3 0 00000055 90 nop 0 00000056 90 nop 393 394 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 395 0 00000057 E8[0000] EnterCrit critShare 0 0000005A 36A1[0000] mov ax,[ss:User_ID] 398 399 fmt TypShare,LevShEntry,<"\nCloseUser $x\n">, 400 0 0000005E 29DB sub bx,bx ; insensitive to PID 0 00000060 29D2 sub dx,dx 0 00000062 E8A702 invoke BCS ; bulk close the SFTs 0 00000065 E8[0000] LeaveCrit critShare 0 00000068 C3 return 406 EndProc MFTclU 407 408 BREAK 409 410 ;******************* START OF SPECIFICATIONS *********************************** 411 ; 412 ; MFTcloseP 413 ; 414 ; MFTcloseP(PID, UID) 415 ; 416 ; MFTcloseP removes all entrys for process PID on machine MID from the 417 ; MFT structure. We walk the MFT structure closing all relevant 418 ; SFT's. Do it the dumb way by iterating closes until the SFTs 419 ; disappear. 420 ; 421 ; ENTRY (SS) = DOSGROUP 422 ; User_ID = 16-bit user id of issuer 423 ; Proc_ID = 16-bit process id of issuer 424 ; EXIT 'C' clear 425 ; USES ALL 426 ; 427 ;******************* END OF SPECIFICATIONS ************************************* 428 429 Procedure MFTcloseP,NEAR 429 ****************** warning: proc MFTcloseP... [-w+user] 430 431 ; int 3 0 00000069 90 nop 0 0000006A 90 nop 434 435 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 436 0 0000006B E8[0000] EnterCrit critShare 0 0000006E 36A1[0000] mov ax,[ss:User_ID] 0 00000072 BBFFFF mov bx,-1 0 00000075 368B16[0000] mov dx,[ss:Proc_ID] 441 442 fmt TypShare,LevShEntry,<"\nClose UID/PID $x:$x\n">, 443 0 0000007A E88F02 call BCS ; Bulk close the SFTs 0 0000007D E8[0000] LeaveCrit critShare 446 0 00000080 C3 ret 448 449 EndProc MFTcloseP 450 451 BREAK 452 453 ;******************* START OF SPECIFICATIONS *********************************** 454 ; 455 ; MFTcloseN 456 ; 457 ; MFTcloseN(name) 458 ; 459 ; MFTcloseN removes all entrys for the given file from the MFT 460 ; structure. 461 ; 462 ; NOTE: this function is used infrequently and need not be fast. 463 ; (although for typical use it's not all that slow...) 464 ; 465 ; ENTRY DS:SI point to dpl. 466 ; (SS) = DOSGroup 467 ; EXIT 'C' clear if no error 468 ; 'C' set if error 469 ; AX = error_path_not_found if not currently open 470 ; USES ALL 471 ; 472 ;******************* END OF SPECIFICATIONS ************************************* 473 474 Procedure MFTcloN,NEAR 474 ****************** warning: proc MFTcloN... [-w+user] 475 476 ; int 3 0 00000081 90 nop 0 00000082 90 nop 479 480 ASSUME SS:DOSGROUP,ES:NOTHING,DS:NOTHING 481 0 00000083 E8[0000] EnterCrit critShare 0 00000086 8B5406 MOV DX,[SI + DPL_DX] 0 00000089 8E5C0C MOV DS,[SI + DPL_DS] 0 0000008C 89D6 mov si,dx ; (DS:SI) = fwa name 0 0000008E 28C0 sub al,al ; don't create if not found 0 00000090 1E push ds 0 00000091 56 push si 0 00000092 E8[0000] call FNM ; find name in MFT 0 00000095 B80300 mov ax,error_path_not_found ; assume error 0 00000098 7229 jc mclo9 ; not found exit 492 493 ; Name was found. Lets yank the SFT entrys one at a time. 494 0 0000009A C47F06 mclo1: les di,[bx + mft_sptr] ; (ES:DI) = SFT address 0 0000009D 36893E[0000] mov WORD PTR [ss:ThisSFT],di 0 000000A2 368C06[0200] mov WORD PTR [ss:ThisSFT+2],es ; point to SFT 0 000000A7 26833D01 cmp word [es:di + sf_ref_count],1 0 000000AB 7503 jnz mclo15 500 CPS equ cps ; NASM port label 0 000000AD E8[0000] call CPS 502 mclo15: 0 000000B0 161F Context DS 504 505 %IF installed 506 multDOS equ MultDOS ; NASM port equate 0 000000B2 B80112 MOV AX,(multDOS << 8) + 1 0 000000B5 CD2F INT 2FH 509 %ELSE 510 call DOS_Close 511 %ENDIF 512 mclo2: 513 514 ASSUME DS:NOTHING 515 0 000000B7 5E pop si 0 000000B8 1F pop ds 0 000000B9 1E push ds 0 000000BA 56 push si 0 000000BB 28C0 sub al,al ; don't create an entry 0 000000BD E8[0000] call FNM ; find the name gain 0 000000C0 73D8 jnc mclo1 ; got still more 0 000000C2 F8 clc 524 525 ; exit. 'C' and (ax) setup 526 ; 527 ; (TOS+2:TOS) = address of ASCIZ string 528 0 000000C3 5E mclo9: pop si ; clean stack 0 000000C4 1F pop ds 0 000000C5 E8[0000] LeaveCrit critShare 532 0 000000C8 C3 ret 534 535 EndProc MFTcloN 536 537 BREAK 538 539 ;******************* START OF SPECIFICATIONS *********************************** 540 ; 541 ; NAME: Set_Mult_Block - Set Multiple Block Locks 542 ; 543 ; FUNCTION: Set_Mult_Block sets a lock on 1 or more specified ranges 544 ; of a file. An error is returned if any lock range conflicts 545 ; with another. Ranges of Locks are cleared via Clr_Mult_Block. 546 ; 547 ; In DOS 3.3 only one lock range could be set at a time using 548 ; Set_Block. For DOS 4.00 this routine will replace Set_Block 549 ; in the jump table and will make repeated calls to Set_Block 550 ; in order to process 1 or more lock ranges. 551 ; 552 ; NOTE: - This is an all new interface to IBMDOS 553 ; 554 ; INPUT: (AL) = 0 - lock all 555 ; = 80 - lock write 556 ; (CX) = the number of lock ranges 557 ; (DS:DX) = pointer to the range list 558 ; (ES:DI) = SFT address 559 ; User_ID = 16-bit user id of issuer 560 ; Proc_ID = 16-bit process id of issuer 561 ; (SS) = DOSGroup 562 ; 563 ; OUTPUT: Lock records filled in for all blocks specified 564 ; 565 ; REGISTERS USED: ALL but DS 566 ; (NOT RESTORED) 567 ; 568 ; LINKAGE: IBMDOS Jump Table 569 ; 570 ; EXTERNAL Invoke: Load_Regs, Set_Block, Clr_Block 571 ; REFERENCES: 572 ; 573 ; NORMAL 'C' clear if no error 574 ; EXIT: 575 ; 576 ; ERROR 'C' set if error 577 ; EXIT: (ax) = error code 578 ; ('error_lock_violation' if conflicting locks) 579 ; 580 ; CHANGE 04/15/87 - First release 581 ; LOG: 582 ; 583 ;******************* END OF SPECIFICATIONS ************************************* 584 ;******************+ START OF PSEUDOCODE +************************************** 585 ; 586 ; START Set_Mult_Block 587 ; 588 ; count = start_count 589 ; search till count = 0 590 ; invoke Load_Regs 591 ; invoke Set_Block 592 ; exit if error 593 ; clear_count = start_count - current_count 594 ; loop till clear_count = 0 595 ; invoke Load_Regs 596 ; invoke Clr_Block 597 ; leave if error 598 ; end loop 599 ; set error status 600 ; orelse 601 ; endloop 602 ; set successful status 603 ; endsrch 604 ; if error status 605 ; load return code 606 ; endif 607 ; return 608 ; 609 ; END Set_Mult_Block 610 ; 611 ;******************+ END OF PSEUDOCODE +************************************** 612 613 Procedure Set_Mult_Block,NEAR 613 ****************** warning: proc Set_Mult_Block... [-w+user] 614 615 ; PUSH DS ;ICE 616 ; push bx ;ICE 617 ; push ax ;ICE 618 619 ; mov bx,0140H ;ICE 620 ; xor ax,ax ;ICE 621 ; mov ds,ax ;ICE 622 ; mov ax,word ptr [ds:bx] ;ICE 623 ; mov word ptr [ds:bx],ax ;ICE 624 625 ; pop ax ;ICE 626 ; pop bx ;ICE 627 ; POP DS ;ICE 628 629 630 0 000000C9 E8[0000] EnterCrit critShare ; ;AN000; 632 633 ASSUME ES:NOTHING,DS:NOTHING ; ;AN000; 634 ; set up for loop 635 636 ; WE HAVE: (from IBMDOS) | WE NEED: (for Set_Block) 637 638 ; (AL) = 0 - lock all | (BX) = 0 lock all operations 639 ; = 80- lock write | = 1 lock write operations 640 ; (CX) = the number of lock ranges | (CX:DX) = offset of area 641 ; (DS:DX) = pointer to the range list | (SI:AX) = length of area 642 ; (ES:DI) = SFT address | (ES:DI) = SFT address 643 644 ; int 3 0 000000CC 90 nop 0 000000CD 90 nop 647 0 000000CE 2E8C1E[0400] mov [cs:DS_Org],ds ;an000;save entry DS 649 0 000000D3 161F Context DS ; ;AN000; 0 000000D5 83F901 CMP CX,01h ;DO WE HAVE A COUNT? ;AN000; 652 653 ;; $if ae ; if the count was valid ;AN000; 654 ; $if e ; if the count was valid ;AC006; 0 000000D8 750A JNE D_$IF1 656 657 ;; PUSH CX ; count = start_count ;AN000; 658 ;; PUSH DX ; save pointer to range list ;AN000; 0 000000DA 89D5 MOV BP,DX ; save current index into list ;AN000; 660 ;; AND AX,0080H ; clear high byte and be sure low is ;AN000; 661 ; set if applicable 662 ;; ROL AL,1 ; move high bit to bit 0 663 ;; MOV BX,AX ; SET UP TYPE OF LOCK ;AN000; 664 665 ;; $do ; loop till count = 0 ;AN000; 666 ;; cmp cx,00 ;an000;see if at end 667 ;; $leave e ;an000;exit if at end 668 ;; push cx ;an000;save cx - our counter 669 ;; push di ;an000;save di - our SFT pointer 670 load_regs equ Load_Regs ; NASM port label 0 000000DC E80F00 call load_regs ;an000;load the registers for call 672 ; to set_block 673 set_block equ Set_Block ; NASM port label 0 000000DF E85400 call set_block ;an000;set the lock block 675 ;; pop di ;an000;restore our SFT pointer 676 ;; pop cx ;an000;restore cx - our counter 677 ;; $leave c ;an000;on error exit loop 678 ;; dec cx ;an000;decrease counter 679 ;; $enddo ;an000;end loop 680 681 ;; $if c ;an000;if an error occurred 682 ;; pop dx ;an000;restore range list pointer 683 ;; pop ax ;an000;obtain original count 684 ;; sub ax,cx ;an000;determine how many locks set 685 ;; mov cx,ax ;an000;set the loop counter with count 686 ;; mov bp,dx ;an000;set bp to point to range list 687 ;; $do ;an000;while cx not = 0 688 ;; cmp cx,00 ;an000;at end? 689 ;; $leave e ;an000;yes, exit 690 ;; push cx ;an000;save cx - our counter 691 ;; push di ;an000;save di - our SFT pointer 692 ;; call load_regs ;an000;load the registers for call 693 ; to clr_block 694 ;; call clr_block ;an000;clear the locks 695 ;; pop di ;an000;restore our SFT pointer 696 ;; pop cx ;an000;restore cx - our counter 697 ;; $leave c ;an000;on error exit 698 ;; dec cx ;an000;decrease counter 699 ;; $enddo ;an000; 700 ;; stc ;an000;signal an error occurred 701 ;; $else ;an000;no error occurred in locking 702 ;; pop ax ;an000;clear off the stack 703 ;; pop ax ;an000; to balance it 704 ;; clc ;an000;signal no error occurred 705 ;; $endif ;an000; 706 ; $else ;an000;cx was 0 - this is an error 0 000000E2 EB01 JMP SHORT D_$EN1 708 D_$IF1: 0 000000E4 F9 stc ;an000;signal an error occurred 710 ; $endif ; ;an000; 711 D_$EN1: 712 713 ; $if c ; if there was an error ;AN000; 0 000000E5 7303 JNC D_$IF4 0 000000E7 B82100 MOV AX,error_lock_violation ; load the return code ;AN000; 716 ; $endif ; endif there was an error ;AN000; 717 D_$IF4: 718 0 000000EA E8[0000] LeaveCrit critShare ; ;AN000; 720 0 000000ED C3 ret ; return - all set ;AN000; 722 723 EndProc Set_Mult_Block 724 725 BREAK 726 727 ;******************* START OF SPECIFICATIONS *********************************** 728 ; 729 ; NAME: Load_Regs - Load Registers for ?_Block calls 730 ; 731 ; FUNCTION: This subroutine loads the High and Low Offsets and the 732 ; High and Low lengths for Lock ranges from the Range List. 733 ; 734 ; INPUT: (DS_Org:PB) - Range list entry to be loaded 735 ; 736 ; OUTPUT: (DX) - Low Offset 737 ; (CX) - High Offset 738 ; (AX) - Low Length 739 ; (SI) - High Length 740 ; 741 ; REGISTERS USED: AX CX DX BP SI 742 ; (NOT RESTORED) 743 ; 744 ; LINKAGE: Called by: Set_Mult_Block, Clr_Mult_Block 745 ; 746 ; EXTERNAL none 747 ; REFERENCES: 748 ; 749 ; NORMAL none 750 ; EXIT: 751 ; 752 ; ERROR none 753 ; EXIT: 754 ; 755 ; CHANGE 04/15/87 - first release 756 ; LOG: 757 ; 758 ;******************* END OF SPECIFICATIONS ************************************* 759 ;******************+ START OF PSEUDOCODE +************************************** 760 ; 761 ; START Load_Regs 762 ; 763 ; recover index into range list 764 ; advance pointer to next entry 765 ; load DX - Low Offset 766 ; load CX - High Offset 767 ; load AX - Low Length 768 ; load SI - High Length 769 ; return 770 ; 771 ; END Load_Regs 772 ; 773 ;******************+ END OF PSEUDOCODE +************************************** 774 775 Procedure Load_Regs,NEAR 775 ****************** warning: proc Load_Regs... [-w+user] 776 0 000000EE 1E push ds ; save our DS ;an000; 0 000000EF 2E8E1E[0400] mov ds,[cs:DS_Org] ; get range list segment ;an000; 0 000000F4 89EE mov si,bp ; recover pointer ;AN000; 0 000000F6 83C508 ADD BP,08h ; move to next entry in list ;AN000; 0 000000F9 8B14 MOV DX,[SI] ; low position ;AN000; 0 000000FB 8B4C02 MOV CX,[SI+2] ; high position ;AN000; 0 000000FE 8B4404 MOV AX,[SI+4] ; low length ;AN000; 0 00000101 8B7406 MOV SI,[SI+6] ; high length ;AN000; 0 00000104 1F pop ds ; restore DS ;an000; 786 0 00000105 C3 ret ; ;AN000; 788 789 EndProc Load_Regs 790 791 BREAK 792 793 ;******************* START OF SPECIFICATIONS *********************************** 794 ; 795 ; NAME: Clr_Mult_Block - Clear Multiple Block Locks 796 ; 797 ; FUNCTION: Clr_Mult_Block removes the locks on 1 or more specified 798 ; ranges of a file. An error is returned if any lock range 799 ; does not exactly match. Ranges of Locks are set via 800 ; Set_Mult_Block. 801 ; 802 ; In DOS 3.3 only one lock range could be cleared at a time 803 ; using Clr_Block. For DOS 4.00 this routine will replace 804 ; Clr_Block in the jump table and will make repeated calls 805 ; to Set_Block in order to process 1 or more lock ranges. 806 ; 807 ; NOTE: - This is an all new interface to IBMDOS 808 ; - an unlock all 'lock all' request will unlock both 809 ; 'lock all' and 'lock write'. 810 ; - an unlock all 'lock write' request will not unlock 811 ; 'lock all's. It will only unlock 'lock write's. 812 ; (if you can understand the above statement, 813 ; understanding the code will be easy!) 814 ; 815 ; INPUT: (AL) = 0 - lock all 816 ; = 80- lock write 817 ; (CX) = the number of lock ranges - NB: all if -1 *** 818 ; (DS:DX) = pointer to the range list 819 ; (ES:DI) = SFT address 820 ; User_ID = 16-bit user id of issuer 821 ; Proc_ID = 16-bit process id of issuer 822 ; (SS) = DOSGroup 823 ; 824 ; OUTPUT: Lock records filled in for all blocks specified 825 ; 826 ; REGISTERS USED: ALL but DS 827 ; (NOT RESTORED) 828 ; 829 ; LINKAGE: IBMDOS Jump Table 830 ; 831 ; EXTERNAL Invoke: Load_Regs, Set_Block, Clr_Block, Clr_List 832 ; REFERENCES: 833 ; 834 ; NORMAL 'C' clear if no error 835 ; EXIT: 836 ; 837 ; ERROR 'C' set if error 838 ; EXIT: (ax) = error code 839 ; ('error_lock_violation' if conflicting locks) 840 ; 841 ; CHANGE 04/15/87 - First release 842 ; LOG: 843 ; 844 ;******************* END OF SPECIFICATIONS ************************************* 845 ;******************+ START OF PSEUDOCODE +************************************** 846 ; 847 ; START Clr_Mult_Block 848 ; 849 ; if count is valid and 850 ; if file (SFT) is 'shared' then 851 ; if count = all 852 ; find first RLR 853 ; loop till all RLR cleared 854 ; if PROC_ID matches and 855 ; if UID matches and 856 ; if SFT matches then 857 ; if ulocking lock_all or 858 ; if this RLR is lock_write 859 ; clear the lock 860 ; endif 861 ; endif 862 ; find next RLR 863 ; end loop 864 ; else 865 ; invoke Clr_List 866 ; endif 867 ; set successful status 868 ; else 869 ; set error status 870 ; endif 871 ; if error 872 ; load return code 873 ; endif 874 ; 875 ; ret 876 ; 877 ; END Clr_Mult_Block 878 ; 879 ;******************+ END OF PSEUDOCODE +************************************** 880 881 Procedure clr_mult_block,NEAR 881 ****************** warning: proc clr_mult_block... [-w+user] 882 883 884 lock_all equ 0h 885 886 ; PUSH DS ;ICE 887 ; push bx ;ICE 888 ; push ax ;ICE 889 890 ; mov bx,0140H ;ICE 891 ; xor ax,ax ;ICE 892 ; mov ds,ax ;ICE 893 ; mov ax,word ptr [ds:bx] ;ICE 894 ; mov word ptr [ds:bx],ax ;ICE 895 896 ; pop ax ;ICE 897 ; pop bx ;ICE 898 ; POP DS ;ICE 899 0 00000106 E8[0000] EnterCrit critShare ; ;AN000; 901 902 ASSUME ES:NOTHING,DS:NOTHING ; ;AN000; 903 904 ; int 3 0 00000109 90 nop 0 0000010A 90 nop 907 0 0000010B 2E8C1E[0400] mov [cs:DS_Org],DS ;an000;save entry DS 909 0 00000110 161F Context DS ; ;AN000; 911 0 00000112 83F901 CMP CX,01h ; do we have a count? ;AN000; 913 ;; $IF AE,AND ; IF A VALID COUNT 914 ; $IF E,AND ; IF A VALID COUNT ;AC006; 0 00000115 750E JNE D_$IF6 916 sf_mft equ sf_MFT ; NASM port equate 0 00000117 26837D3300 cmp word [es:di + sf_mft],0 ; is this SFT shared? ;AN000; 918 ; $IF NE ; AND IF FILE IS 'SHARED' THEN 0 0000011C 7407 JE D_$IF6 920 921 ; WE HAVE: (from IBMDOS) | WE NEED: 922 923 ; (AL) = 0 - lock all | (AX) = 0 lock all operations 924 ; = 80- lock write | = 1 lock write operations 925 ; (CX) = - 1 (unlock all locks) | (DS) = CS 926 ; | (DS:DI) = previous RLR 927 ; | (DS:SI) = current RLR 928 ; (ES:DI) = current SFT | 929 930 ;; and ax,0080h ;be sure it is set right (mask 80 bit) ;AC002; 931 ; existing interface 932 ;; rol al,1 ;put high bit in bit 0 ;AC002; 933 934 ;; CMP CX,-1h ; ;AN000; 935 ;; $IF E ; IF unlock all locks then ;AN000; 936 937 ;; push cs ; ;AN000; 938 ;; pop ds ; ;AN000; 939 ;; mov cx,di ; ES:CX is the SFT ;AN004; 940 941 ; ASSUME ds:nothing 942 943 ;; mov si,[es:di].sf_mft ; DS:SI points to MFT ;AN000; 944 945 ;; lea di,[si].mft_lptr ; DS:DI = addr of ptr to lock record ;AN000; 946 ;; mov si,[di] ; DS:SI = address of 1st lock record ;AN000; 947 948 ;; $DO ; loop through the RLR's ;AN000; 949 950 ; DS:DI = points to previous RLR or MFT if no RLR. 951 ; DS:SI = points to current RLR 952 ; ES:CX = SFT address 953 ; AX = lock type 954 955 ;; and si,si ; are we at the end of the chain? ;AN000; 956 ;; $LEAVE Z ; we'er done with CF = 0 ;AN000; 957 958 ;; mov bp,[si].rlr_pid ; get PROC_ID ;AN000; 959 ;; cmp bp,PROC_ID ; is it ours? ;AN000; 960 ;; $IF E,AND ; ;AN000; 961 ;; mov bp,es ; ;AN000; 962 ;; cmp bp,WORD PTR [si].rlr_sptr+2 ; ;AC004; 963 ;; $IF E,AND ; ;AN000; 964 ;; cmp cx,WORD PTR [si].rlr_sptr ; ;AC004; 965 ;; mov si,[di] ; restore pointer to current (using ;AN000; 966 ; previous) 967 ;; $IF E ; if it is ours ;AN000; 968 969 ; this is it. its OURS ! 970 971 ;; cmp ax,lock_all ; ;AN000; 972 973 ;; $IF E,OR ; if unlocking all or ;AN000; 974 975 ;; mov bp,[si].rlr_type ; get lock type ;AN000; 976 ;; cmp bp,rlr_lall ; is it lock all? ;AN000; 977 978 ;; $IF NE ; if not a LOCK ALL lock ;AN000; 979 980 ; remove the RLR from the chain 981 982 ;; mov bx,[si].rlr_next ; get the pointer to the next RLR ;AN000; 983 ;; mov [di],bx ; install it in the last ;AN000; 984 985 ; put defunct lock record on the free chain 986 987 ;; mov bx,Frelock ; ;AN000; 988 ;; mov [si].rlr_next,bx ; ;AN000; 989 ;; mov Frelock,si ; ;AN000; 990 ;; mov si,di ; back up to last ;AN000; 991 992 ;; $ENDIF ; should we unlock it ;AN000; 993 994 ;; $ENDIF ; it was ours! ;AN000; 995 996 ; advance to next RLR 997 998 ;; mov di,si ; load address of next RLR ;AN000; 999 ;; mov si,[di] ; update pointer to next RLR ;AN000; 1000 1001 ;; $ENDDO ; loop back to the start ;AN000; 1002 1003 ;; $ELSE ; else, its a LIST ! ;AN000; 1004 1005 ; set up for loop 1006 1007 ; WE HAVE: (from IBMDOS) | WE NEED: (for Clr_Block) 1008 1009 ; (AX) = 0 - lock all | (BX) = 0 lock all operations 1010 ; = 1 - lock write | = 1 lock write operations 1011 ; (CX) = the number of lock ranges | (CX:DX) = offset of area 1012 ; (DS:DX) = pointer to the range list | (SI:AX) = length of area 1013 ; (ES:DI) = SFT address | (ES:DI) = SFT address 1014 1015 ;; PUSH CX ; count = start_count ;AN000; 1016 ;; PUSH DX ; save pointer to range list ;AN000; 0 0000011E 89D5 MOV BP,DX ; save current index into list ;AN000; 1018 ;; MOV BX,AX ; SET UP TYPE OF LOCK ;AN000; 1019 0 00000120 E80C00 call Clr_List ; call Clr_List to process the list ;AN000; 1021 1022 ;; $ENDIF ; ;AN000; 1023 1024 ; $ELSE ; NOT VALID 0 00000123 EB01 JMP SHORT D_$EN6 1026 D_$IF6: 1027 0 00000125 F9 STC ; ;AN000; 1029 1030 ; $ENDIF ; VALID/INVALID ;AN000; 1031 D_$EN6: 1032 1033 ; $IF C ; if carry is set ;AN000; 0 00000126 7303 JNC D_$IF9 0 00000128 B82100 MOV AX,error_lock_violation ; load error condition ;AN000; 1036 ; $ENDIF ; carry not set ;AN000; 1037 D_$IF9: 1038 0 0000012B E8[0000] LeaveCrit critShare ; ;AN000; 1040 0 0000012E C3 ret ; return - all set ;AN000; 1042 1043 EndProc clr_mult_block 1044 1045 BREAK 1046 1047 ;******************* START OF SPECIFICATIONS *********************************** 1048 ; 1049 ; NAME: Clr_List - Clear a list of user specified locks 1050 ; 1051 ; FUNCTION: Clr_List makes multiple calls to Clr_Block to clear 1052 ; multiple lock ranges of a file. An error is returned 1053 ; if any lock range does not exactly match. Ranges of 1054 ; Locks are then set via Set_Mult_Block. 1055 ; 1056 ; 1057 ; INPUT: (BX) = 0 lock all operations 1058 ; = 1 lock write operations 1059 ; (CX:DX) = offset of area 1060 ; (SI:AX) = length of area 1061 ; (ES:DI) = SFT address 1062 ; (SS:SP+2)= original index \ see FRAME struc 1063 ; (SS:SP+4)= original count / 1064 ; 1065 ; OUTPUT: Lock records removed for all blocks specified 1066 ; Stack cleard on return 1067 ; 1068 ; REGISTERS USED: ALL but DS 1069 ; (NOT RESTORED) 1070 ; 1071 ; LINKAGE: IBMDOS Jump Table 1072 ; 1073 ; EXTERNAL Invoke: Load_Regs, Set_Block, Clr_Block 1074 ; REFERENCES: 1075 ; 1076 ; NORMAL 'C' clear if no error 1077 ; EXIT: 1078 ; 1079 ; ERROR 'C' set if error 1080 ; EXIT: (ax) = error code 1081 ; ('error_lock_violation' if conflicting locks) 1082 ; 1083 ; CHANGE 04/15/87 - First release 1084 ; LOG: 1085 ; 1086 ;******************* END OF SPECIFICATIONS ************************************* 1087 ;******************+ START OF PSEUDOCODE +************************************** 1088 ; 1089 ; START Clr_List 1090 ; 1091 ; search till count = 0 1092 ; set up for call 1093 ; call clr_Block 1094 ; exit if c 1095 ; clear_count = start_count - current_count 1096 ; loop till clear_count = 0 1097 ; set up for call 1098 ; call Set_Block 1099 ; end loop 1100 ; set error status 1101 ; orelse 1102 ; endloop 1103 ; set successful status 1104 ; endsrch 1105 ; return 1106 ; 1107 ; END Clr_List 1108 ; 1109 ;******************+ END OF PSEUDOCODE +************************************** 1110 1111 Procedure Clr_List,NEAR 1111 ****************** warning: proc Clr_List... [-w+user] 1112 1113 ;; $do ;an000;while cx not = 0 1114 ;; cmp cx,00 ;an000;at end? 1115 ;; $leave e ;an000;yes 1116 ;; push cx ;an000;save cx - our counter 1117 ;; push di ;an000;save di - our SFT pointer 0 0000012F E8BCFF call load_regs ;an000;set up for clr_block call 1119 ;; push bp ; save pointer to range entry ;AN000; 1120 clr_block equ Clr_Block ; NASM port label 0 00000132 E84300 call clr_block ;an000;remove the lock 1122 ;; pop bp ; recover pointer to range entry ;AN000; 1123 ;; pop di ;an000;restore our SFT pointer 1124 ;; pop cx ;an000;restore cx - our counter 1125 ;; $leave c ;an000;leave on error 1126 ;; dec cx ;an000;decrease counter 1127 ;; $enddo ;an000; 1128 1129 ;; $if c ;an000;an error occurred 1130 ;; push bp ;an000;save bp 1131 ;; mov bp,sp ;an000;get sp 1132 ;; mov dx,[bp].parm_1 ;an000;recover original index 1133 ;; mov ax,[bp].Parm_2 ; original count ;AN000; 1134 ;; pop bp 1135 ;; SUB AX,CX ; how many did we do? ;AN000; 1136 ;; MOV CX,AX ; set up the loop ;AN000; 1137 ;; MOV BP,DX ; save the index ;AN000; 1138 1139 ;; $DO ; ;AN000; 1140 ;; cmp cx,00 ;an000;at end? 1141 ;; $leave e ;an000;yes 1142 ;; push cx ;an000;save cx - our counter 1143 ;; push di ;an000;save di - our SFT pointer 1144 ;; call load_regs ;an000;set up for set_block call 1145 ;; call set_block ;an000;reset the locks 1146 ;; pop di ;an000;restore our SFT pointer 1147 ;; pop cx ;an000;restore cx - our counter 1148 ;; $leave c ;an000;leave on error 1149 ;; dec cx ;an000;decrease counter 1150 ;; $enddo ;an000; 1151 ;; stc ;an000;signal an error 1152 ;; $else ;an000; 1153 ;; clc ;an000;signal no error 1154 ;; $endif ;an000; 1155 1156 ;; ret 4 ; return (clear Parm_1 & Parm_2) ;AN000; 0 00000135 C3 ret ; return (clear Parm_1 & Parm_2) ;AC006; 1158 1159 EndProc Clr_List 1160 1161 1162 BREAK 1163 1164 ;******************* START OF SPECIFICATIONS *********************************** 1165 ; 1166 ; NAME: Set_Block - set byte range lock on a file 1167 ; 1168 ; FUNCTION: Set_Block sets a lock on a specified range of a file. An 1169 ; error is returned if the lock conflicts with another. 1170 ; Locks are cleared via clr_block. 1171 ; 1172 ; INPUT: (ES:DI) = SFT address 1173 ; (CX:DX) = offset of area 1174 ; (SI:AX) = length of area 1175 ; (BX) = 0 lock all operations 1176 ; = 1 lock write operations 1177 ; User_ID = 16-bit user id of issuer 1178 ; Proc_ID = 16-bit process id of issuer 1179 ; (SS) = DOSGroup 1180 ; 1181 ; OUTPUT: Lock records removed for all blocks specified 1182 ; 1183 ; REGISTERS USED: ALL but DS, BP 1184 ; (NOT RESTORED) 1185 ; 1186 ; LINKAGE: Invoked by: Set_Mult_Block 1187 ; 1188 ; EXTERNAL Invoke: CLP (SLE), OFL 1189 ; REFERENCES: 1190 ; 1191 ; NORMAL 'C' clear if no error 1192 ; EXIT: 1193 ; 1194 ; ERROR 'C' set if error 1195 ; EXIT: 1196 ; 1197 ; CHANGE 04/15/87 - lock only write support 1198 ; LOG: 1199 ; 1200 ;******************* END OF SPECIFICATIONS ************************************* 1201 ;******************+ START OF PSEUDOCODE +************************************** 1202 ; 1203 ; START Set_Block 1204 ; 1205 ; if a valid SFT and 1206 ; invoke CLP 1207 ; if no lock conflicts and 1208 ; invoke OFL 1209 ; if empty lock record available 1210 ; store SFT pointer 1211 ; store lock range 1212 ; add RLR to the chain 1213 ; store PROC_ID 1214 ; store rlr_type 1215 ; set successful return status 1216 ; else 1217 ; set error return status 1218 ; endif 1219 ; return 1220 ; 1221 ; END Set_Block 1222 ; 1223 ;******************+ END OF PSEUDOCODE +************************************** 1224 1225 Procedure Set_Block,NEAR 1225 ****************** warning: proc Set_Block... [-w+user] 1226 1227 ASSUME ES:NOTHING,DS:NOTHING 1228 0 00000136 161F Context DS 1230 0 00000138 55 push bp ; preserve (bp) ;AN000; 0 00000139 1E push ds ; preserve (ds) 1233 ;; push bx ; preserve (bx) ;AN000; 0 0000013A 26837D3300 cmp word [es:di + sf_mft],ZERO 1235 ; $if nz,and ; if file is SHARED and ;AC000; 0 0000013F 7430 JZ D_$IF11 0 00000141 57 push di 1238 clp equ CLP ; NASM port label 0 00000142 E87800 call clp ; do common setup code 1240 1241 ASSUME DS:NOTHING 1242 0 00000145 5D pop bp 1244 ; $if nc,and ; if no (lock conflict) error and ;AC000; 0 00000146 7229 JC D_$IF11 1246 1247 ; Its ok to set this lock. Get a free block and fill it in 1248 ; (es:bp) = sft 1249 ; (ds:si) = pointer to name record 1250 ; (ax:bx) = fba lock area 1251 ; (cx:dx) = lba lock area 1252 ; (ds:di) = pointer to pointer to previous lock 1253 ; (TOS) = saved (bx) 1254 ; (TOS+1) = saved (ds) 1255 ; (TOS+2) = saved (bp) 1256 1257 OFL equ ofl ; NASM port label 0 00000148 E8[0000] call OFL ; (ds:di) = pointer to new, orphan lock record 1259 ; $if nc ; if space available ;AC000; 0 0000014B 7224 JC D_$IF11 0 0000014D 896D0A mov WORD PTR [di + rlr_sptr],bp ; store SFT offset 0 00000150 8C450C mov WORD PTR [di + rlr_sptr + 2],es ; store SFT offset 0 00000153 894504 mov [di + rlr_fba + 2],ax 0 00000156 895D02 mov [di + rlr_fba],bx ; store lock range 0 00000159 894D08 mov [di + rlr_lba + 2],cx 0 0000015C 895506 mov [di + rlr_lba],dx 1267 1268 ; add to front of chain 1269 ; 1270 ; (ds:si) = fwa MFT name record 1271 0 0000015F 8B4404 mov ax,[si + mft_lptr] 0 00000162 8905 mov [di + rlr_next],ax 0 00000164 897C04 mov [si + mft_lptr],di 1275 ; 1276 ; Set process ID of lock 1277 ; 1278 proc_id equ Proc_ID ; NASM port label 0 00000167 36A1[0000] mov ax,[ss:proc_id] 0 0000016B 89450E mov [di + rlr_pid],ax 1281 1282 ; 1283 ;; pop bx ; recover lock type ;AN000; 1284 ;; push bx ; restore the stack ;AN000; 1285 ;; mov [di].rlr_type,bx ; set the rlr_type field ;AN000; 0 0000016E F8 clc ; we finished OK 1287 1288 ; $else ; ;AC000; 0 0000016F EB04 JMP SHORT D_$EN11 1290 D_$IF11: 1291 0 00000171 B82100 mov ax,error_lock_violation 0 00000174 F9 stc 1294 1295 ; $endif ; ;AC000; 1296 D_$EN11: 1297 1298 ;; pop bx ; ;AN000; 0 00000175 1F pop ds 0 00000176 5D pop bp ; ;AC000; 1301 0 00000177 C3 ret ; return - all set 1303 1304 EndProc Set_Block 1305 1306 BREAK 1307 1308 ;******************* START OF SPECIFICATIONS *********************************** 1309 ; 1310 ; NAME: Clr_Block - clear byte range lock on a file 1311 ; 1312 ; FUNCTION: Clr_Block clears a lock on a specified range of a file. 1313 ; Locks are set via set_block. 1314 ; 1315 ; INPUT: (ES:DI) = SFT address 1316 ; (CX:DX) = offset of area 1317 ; (SI:AX) = length of area 1318 ; (BX) = 0 lock all operations 1319 ; = 1 lock write operations 1320 ; User_ID = 16-bit user id of issuer 1321 ; Proc_ID = 16-bit process id of issuer 1322 ; (SS) = DOSGroup 1323 ; 1324 ; OUTPUT: Lock record removed for block specified. 1325 ; 1326 ; REGISTERS USED: ALL but DS 1327 ; (NOT RESTORED) 1328 ; 1329 ; LINKAGE: Invoked by: Clr_Mult_Block 1330 ; 1331 ; EXTERNAL Invoke: CLP (SLE), OFL 1332 ; REFERENCES: 1333 ; 1334 ; NORMAL 'C' clear if no error 1335 ; EXIT: 1336 ; 1337 ; ERROR 'C' set if error 1338 ; EXIT: (ax) = error code 1339 ; ('error_lock_violation' if conflicting locks or 1340 ; range does not exactly match previous lock) 1341 ; 1342 ; CHANGE 04/15/87 - lock only write support 1343 ; LOG: 1344 ; 1345 ;******************* END OF SPECIFICATIONS ************************************* 1346 ;******************+ START OF PSEUDOCODE +************************************** 1347 ; 1348 ; START Clr_Block 1349 ; 1350 ; if file is SHARED and 1351 ; if lock is valid and 1352 ; if SFT matches and 1353 ; if PROC_ID matches 1354 ; if lock_reqest = lock_type 1355 ; unchain the lock 1356 ; put defunct lock on free chain 1357 ; clear error status 1358 ; else 1359 ; set error status 1360 ; endif 1361 ; else 1362 ; flush the stack 1363 ; set error status 1364 ; endif 1365 ; if error 1366 ; load return code 1367 ; endif 1368 ; return 1369 ; 1370 ; END Clr_Block 1371 ; 1372 ;******************+ END OF PSEUDOCODE +************************************** 1373 1374 Procedure Clr_Block,NEAR 1374 ****************** warning: proc Clr_Block... [-w+user] 1375 1376 ASSUME ES:NOTHING,DS:NOTHING 1377 0 00000178 161F Context DS 0 0000017A 1E push ds 1380 ;; push bx ; save type of operation ;AN000; 0 0000017B 26837D3300 cmp word [es:di + sf_mft],ZERO 1382 1383 ; $if nz,and ; if file is SHARED and ;AC000; 0 00000180 7433 JZ D_$IF14 1385 0 00000182 57 push di 0 00000183 E83700 call clp ; do common setup code 1388 1389 ASSUME DS:NOTHING 1390 0 00000186 5D pop bp ; ES:BP points to sft. 1392 ;; pop bx ; recover the type of operation ;AN000; 1393 1394 ; $if c,and ; if lock exists and ;AC000; 0 00000187 732C JNC D_$IF14 1396 ; $if z,and ; if range given correctly and ;AC000; 0 00000189 752A JNZ D_$IF14 1398 ; 1399 ; We've got the lock 1400 ; 1401 ; (ds:di) = address of pointer (offset) to previous lock record 1402 ; (es:BP) = sft address 1403 ; 1404 ; Now comes the tricky part. Is the lock for us? Does the lock match the SFT 1405 ; that was given us? If not, then error. 1406 ; 0 0000018B 8B35 mov si,[di] ; (DS:SI) = address of lock record 0 0000018D 396C0A cmp word ptr [si + rlr_sptr],bp 1409 1410 ; $if z,and ; if SFT matches and ;AC000; 0 00000190 7523 JNZ D_$IF14 1412 0 00000192 8CC5 mov bp,es 0 00000194 396C0C cmp word ptr [si + rlr_sptr + 2],bp 1415 ; $if z,and ; (check both words of SFT pointer) ;AC000; 0 00000197 751C JNZ D_$IF14 0 00000199 368B2E[0000] mov bp,[ss:proc_id] 0 0000019E 396C0E cmp [si + rlr_pid],bp 1419 1420 ;; $if z,and ; if PROC_ID matches ;AC000; 1421 ; $if z ; if PROC_ID matches ;AC006; 0 000001A1 7512 JNZ D_$IF14 1423 ; 1424 ; Make sure that the type of request and the lock type match 1425 ; 1426 ;; cmp bx,lock_all ; ;AN000; 1427 1428 ;; $IF E,OR ; if unlocking all or ;AN000; 1429 1430 ;; mov bp,[si].rlr_type ; get lock type ;AN000; 1431 ;; cmp bp,rlr_lall ; is it lock all? ;AN000; 1432 1433 ;; $IF NE ; if not a LOCK ALL lock ;AN000; 1434 ; 1435 ; The locks match the proper open invocation. Unchain the lock 1436 ; 0 000001A3 8B04 mov ax,[si + rlr_next] 0 000001A5 8905 mov [di],ax ; chain it out 1439 1440 ; put defunct lock record on the free chain 1441 ; 1442 ; (ds:si) = address of freed lock rec 1443 0 000001A7 2EA1[0000] mov ax,[cs:Frelock] 0 000001AB 8904 mov [si + rlr_next],ax 0 000001AD 2E8936[0000] mov [cs:Frelock],si 0 000001B2 F8 clc 1448 1449 ; $else ; we have an error ;AC000; 0 000001B3 EB01 JMP SHORT D_$EN14 1451 D_$IF14: 1452 0 000001B5 F9 stc 1454 1455 ; $endif ; Endif - an error ;AC000; 1456 D_$EN14: 1457 1458 ; $if c ; If an error was found ;AC000; 0 000001B6 7303 JNC D_$IF17 1460 0 000001B8 B82100 mov ax,error_lock_violation 1462 1463 ; $endif ; Endif - an error was found ;AC000; 1464 D_$IF17: 1465 0 000001BB 1F pop ds ; restore DS 1467 0 000001BC C3 ret 1469 1470 1471 EndProc Clr_Block 1472 1473 BREAK 1474 1475 ;******************* START OF SPECIFICATIONS *********************************** 1476 ; 1477 ; NAME: CLP - Common Lock Preamble 1478 ; 1479 ; FUNCTION: This routine contains a common code fragment for set_block 1480 ; and clr_block. 1481 ; 1482 ; INPUT: (ES:DI) = SFT address 1483 ; (CX:DX) = offset of area 1484 ; (SI:AX) = length of area 1485 ; User_ID = 16-bit user id of issuer 1486 ; Proc_ID = 16-bit process id of issuer 1487 ; (SS) = (DS) = DOSGroup 1488 ; 1489 ; OUTPUT: (ds:si) = MFT address 1490 ; 1491 ; REGISTERS USED: ALL but ES 1492 ; (NOT RESTORED) 1493 ; 1494 ; LINKAGE: Invoked by: Set_Block, Clr_Block 1495 ; 1496 ; EXTERNAL Invoke: SLE 1497 ; REFERENCES: 1498 ; 1499 ; NORMAL 'C' clear if no overlap 1500 ; EXIT: (ax:bx) = offset of first byte in range 1501 ; (cx:dx) = offset of last byte in range 1502 ; 1503 ; ERROR 'C' set if overlap 1504 ; EXIT: 'Z' set if 1-to-1 match 1505 ; (di) points to previous lock 1506 ; 1507 ; CHANGE 04/15/87 - lock only write support 1508 ; LOG: 1509 ; 1510 ;******************* END OF SPECIFICATIONS ************************************* 1511 ;******************+ START OF PSEUDOCODE +************************************** 1512 ; 1513 ; START CLP 1514 ; 1515 ; shuffle arguments 1516 ; if valid length 1517 ; invoke SLE 1518 ; set successful return status 1519 ; else 1520 ; set error return status 1521 ; endif 1522 ; return 1523 ; 1524 ; END CLP 1525 ; 1526 ;******************+ END OF PSEUDOCODE +************************************** 1527 1528 Procedure CLP,NEAR 1528 ****************** warning: proc CLP... [-w+user] 1529 0 000001BD 89D3 mov bx,dx ; shuffle arguments 0 000001BF 92 xchg dx,ax 0 000001C0 91 xchg ax,cx ; (ax:bx) = offset 0 000001C1 89F1 mov cx,si ; (cx:dx) = length 1534 0 000001C3 09D6 or si,dx ; see if length is 0 1536 1537 ; $if nz,and ; if length is > 0 and ;AC000; 0 000001C5 7424 JZ D_$IF19 1539 0 000001C7 01DA add dx,bx 0 000001C9 11C1 adc cx,ax ; (cx:dx) = lba+1 1542 1543 ; $if nc,or ; no carry is ok ;AC000; 0 000001CB 7306 JNC D_$LL19 1545 0 000001CD 89D6 mov si,dx 0 000001CF 09CE or si,cx 1548 1549 ; $if z ; if !> 0 then ;AC000; 0 000001D1 7518 JNZ D_$IF19 1551 D_$LL19: 1552 0 000001D3 83EA01 sub dx,1 ; (cx:dx) = lba of locked region 0 000001D6 83D900 sbb cx,0 1555 0 000001D9 0E push cs 0 000001DA 1F pop ds 1558 ; (es:di) is sft 0 000001DB 56 push si 0 000001DC 268B7533 mov si,[es:di + sf_mft] 0 000001E0 56 push si 0 000001E1 BF0100 mov di,1 ; Find own locks 1563 SLE equ sle ; NASM port label 0 000001E4 E8[0000] call SLE 1565 ; di points to previous lock record 0 000001E7 5E pop si 0 000001E8 5D pop bp 1568 1569 ; $else ; we have an error ;AC000; 0 000001E9 EB07 JMP SHORT D_$EN19 1571 D_$IF19: 1572 0 000001EB 31F6 xor si,si 0 000001ED 46 inc si ; carry unchanged, zero reset 0 000001EE B82100 mov ax,error_lock_violation ; assume error 0 000001F1 F9 stc 1577 1578 ; $endif ; endif - we have an error ;AC000; 1579 D_$EN19: 1580 0 000001F2 C3 ret 1582 1583 EndProc CLP 1584 1585 BREAK 1586 1587 ;******************* START OF SPECIFICATIONS *********************************** 1588 ; 1589 ; NAME: Chk_Block - check range lock on a file 1590 ; 1591 ; FUNCTION: Chk_Block is called to interogate the lock status of a 1592 ; region of a file. 1593 ; 1594 ; NOTE: This routine is called for every disk I/O operation 1595 ; and MUST BE FAST 1596 ; 1597 ; INPUT: (ES:DI) points to an SFT structure 1598 ; (AL) = 80h - Write operation = 0 - any non write operation 1599 ; (CX) is the number of bytes being read or written 1600 ; BytPos is a long (low first) offset into the file 1601 ; of the I/O 1602 ; User_ID = 16-bit user id of issuer 1603 ; Proc_ID = 16-bit process id of issuer 1604 ; (SS) = DOSGroup 1605 ; 1606 ; OUTPUT: CF set according to status and presence of locks (see below) 1607 ; 1608 ; REGISTERS USED: ALL but ES,DI,CX,DS 1609 ; (NOT RESTORED) 1610 ; 1611 ; LINKAGE: IBMDOS Jump Table 1612 ; 1613 ; NORMAL 'C' clear if no error 1614 ; EXIT: 1615 ; 1616 ; ERROR 'C' set if error 1617 ; EXIT: (ax) = error code 1618 ; ('error_lock_violation' if conflicting locks) 1619 ; 1620 ; CHANGE 04/15/87 - lock only write support 1621 ; LOG: 1622 ; 1623 ;******************* END OF SPECIFICATIONS ************************************* 1624 ;******************+ START OF PSEUDOCODE +************************************** 1625 ; 1626 ; START Chk_Block 1627 ; 1628 ; if shared SFT and 1629 ; if locks exist 1630 ; invoke SLE 1631 ; if lock conflicts occur (error) 1632 ; if this is !write operation and 1633 ; if a write lock found 1634 ; set successfull status 1635 ; else 1636 ; set error status 1637 ; endif 1638 ; else no error 1639 ; flush stack 1640 ; endif 1641 ; endif 1642 ; 1643 ; ret 1644 ; 1645 ; END Chk_Block 1646 ; 1647 ;******************+ END OF PSEUDOCODE +************************************** 1648 1649 Procedure Chk_Block,NEAR 1649 ****************** warning: proc Chk_Block... [-w+user] 1650 1651 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 1652 1653 write_op equ 080h ; write operation requested ;AN000; 1654 lock_all equ 0h ; lock all specified ;AN000; 1655 1656 ; PUSH DS ;ICE 1657 ; push bx ;ICE 1658 ; push ax ;ICE 1659 1660 ; mov bx,0140H ;ICE 1661 ; xor ax,ax ;ICE 1662 ; mov ds,ax ;ICE 1663 ; mov ax,word ptr [ds:bx] ;ICE 1664 ; mov word ptr [ds:bx],ax ;ICE 1665 1666 ; pop ax ;ICE 1667 ; pop bx ;ICE 1668 ; POP DS ;ICE 0 000001F3 E8[0000] EnterCrit critShare 1670 1671 ; int 3 0 000001F6 90 nop 0 000001F7 90 nop 1674 0 000001F8 06 PUSH ES 0 000001F9 57 PUSH DI 0 000001FA 51 PUSH CX 0 000001FB 1E PUSH DS 0 000001FC 26837D3300 cmp word [es:di + sf_mft],0 1680 1681 ; $if nz,and ; if the file is SHARED and ;AC000; 0 00000201 742C JZ D_$IF22 1683 0 00000203 0E push cs 0 00000204 1F pop ds 0 00000205 268B7533 mov si,[es:di + sf_MFT] ; (DS:SI) = address of MFT record 0 00000209 F74404FFFF test word [si + mft_lptr],-1 1688 1689 ; $if nz,and ; if there are locks on this file and ;AC000; 0 0000020E 741F JZ D_$IF22 1691 0 00000210 83E901 sub cx,1 ; (cx) = count-1 0 00000213 F5 cmc 1694 1695 ; $if c ; there are bytes to lock ;AC000; 0 00000214 7319 JNC D_$IF22 1697 1698 ;; push ax ; preserve type of operation ;AN000; 1699 ; DOS passes AL = 80 for writes 1700 ; = 00 for reads 1701 0 00000216 36A1[0200] mov ax,WORD PTR [ss:BytPos+2] 0 0000021A 368B1E[0000] mov bx,WORD PTR [ss:BytPos] ; (ax:bx) = offset 0 0000021F 89CA mov dx,cx 0 00000221 29C9 sub cx,cx 0 00000223 01DA add dx,bx 0 00000225 11C1 adc cx,ax ; (cx:dx) = lba of lock area 0 00000227 29FF sub di,di ; ignore own locks 0 00000229 E8[0000] call SLE 1710 ;; pop ax ; recover type of opperation ;AN000; 1711 1712 ; upon return DS:SI points to the RLR with the conflict 1713 1714 ;; $if c ; if lock conflicts occur - error ;AC000; 1715 1716 ; now we must check what type of lock exists 1717 ; and the type of operation in progress. 1718 1719 ;; cmp al,write_op ; ;AN000; 1720 1721 ;; $if ne,and ; if NOT a write operation and ;AN000; 1722 1723 ;; cmp [si].rlr_type,rlr_lwr ; ;AN000; 1724 1725 ;; $if e ; if write locked (NOT all locked) ;AN000; 1726 1727 ;; clc ; then not true conflict - clear error ;AN000; 1728 1729 ;; $else ; else it IS a valid conflict ;AC000; 1730 1731 ;; stc ; true error - set error status 1732 1733 ;; $endif ; endif - a valid conflict ;AC000; 1734 1735 1736 ;; $endif ; endif - conflicts ;AC000; 1737 0 0000022C B82100 mov ax,error_lock_violation ; assume error 1739 1740 ; $endif ; endif - no need to check ;AC000; 1741 D_$IF22: 1742 1743 ; exit 1744 ; 1745 ; 'C' and (ax) setup 1746 0 0000022F 1F POP DS 0 00000230 59 POP CX 0 00000231 5F POP DI 0 00000232 07 POP ES 0 00000233 E8[0000] LeaveCrit critShare 1752 0 00000236 C3 ret ; exit 1754 1755 EndProc Chk_Block 1756 1757 BREAK 1758 1759 ;******************* START OF SPECIFICATIONS *********************************** 1760 ; 1761 ; MFT_get - get an entry from the MFT 1762 ; 1763 ; MFT_get is used to return information from the MFT. System utilities 1764 ; use this capability to produce status displays. 1765 ; 1766 ; MFT_get first locates the (BX)'th file in the list (no particular 1767 ; ordering is promised). It returns that name and the UID of 1768 ; the (CX)'th SFT on that file and the number of locks on that 1769 ; file via that SFT. 1770 ; 1771 ; ENTRY DS:SI point to DPL which contains: 1772 ; (dBX) = zero-based file index 1773 ; (dCX) = zero-based SFT index 1774 ; (SS) = DOSGroup 1775 ; EXIT 'C' clear if no error 1776 ; ES:DI buffer is filled in with BX'th file name 1777 ; (BX) = user id of SFT 1778 ; (CX) = # of locks via SFT 1779 ; 'C' set if error 1780 ; (ax) = error code 1781 ; ('error_no_more_files' if either index is out 1782 ; of range) 1783 ; 1784 ;******************* END OF SPECIFICATIONS ************************************* 1785 1786 Procedure MFT_get,NEAR 1786 ****************** warning: proc MFT_get... [-w+user] 1787 1788 ; int 3 0 00000237 90 nop 0 00000238 90 nop 1791 1792 ASSUME DS:NOTHING,ES:NOTHING 1793 0 00000239 E8[0000] EnterCrit critShare 0 0000023C 8B5C02 MOV BX,[SI + DPL_BX] 0 0000023F 8B4C04 MOV CX,[SI + DPL_CX] 0 00000242 1607 Context ES 0 00000244 BF[0000] MOV DI,OFFSET OpenBuf wrt DOSGROUP 1799 0 00000247 87D9 xchg bx,cx ; (cx) = file index 0 00000249 0E push cs 0 0000024A 1F pop ds 1803 0 0000024B BE[0000] Off SI,mft ; (ds:si) = fwa of OFFSET MFT 1805 1806 ; scan forward until next name 1807 0 0000024E 803C00 mget1: cmp byte [si + mft_flag],MFLG_FRE 0 00000251 7405 jz mget3 ; is free space 0 00000253 7C24 jl mget7 ; is END 1811 1812 ; have another name. see if this satisfies caller 1813 0 00000255 E306 jcxz mget4 ; caller is happy 0 00000257 49 dec cx 0 00000258 037401 mget3: add si,[si + mft_len] ; skip name record 0 0000025B EBF1 JMP SHORT mget1 1818 1819 ; we've located the file name. 1820 ; 1821 ; (bx) = SFT index 1822 ; (DS:SI) = MFT entry 1823 ; (ES:DI) = address of caller's buffer 1824 0 0000025D 57 mget4: push di 0 0000025E 56 push si ; save table offset 0 0000025F 83C60C add si,mft_name 0 00000262 AC mget5: lodsb 0 00000263 AA stosb ; copy name into caller's buffer 0 00000264 08C0 or al,al 0 00000266 75FA jnz mget5 0 00000268 5E pop si ; (DS:SI) = name record address 0 00000269 87D9 xchg bx,cx ; (cx) = SFT chain count 0 0000026B C57C06 lds di,[si + mft_sptr] 0 0000026E E311 mget6: jcxz mget8 ; have reached the SFT we wanted 0 00000270 49 dec cx 0 00000271 C57D2B lds di,[di + sf_chain] ; get next link 0 00000274 09FF or di,di 0 00000276 75F6 jnz mget6 ; follow chain some more 0 00000278 5F pop di ; (es:di) = buffer address 1841 1842 ;** The file or SFT index was too large - return w/ error 1843 0 00000279 B81200 mget7: mov ax,error_no_more_files 0 0000027C F9 stc 0 0000027D E8[0000] LeaveCrit critShare 1847 0 00000280 C3 ret 1849 1850 ;** We've got the SFT he wants. Lets count the locks 1851 ; 1852 ; (es:TOS) = buffer address 1853 ; (DS:DI) = address of SFT 1854 ; (si) = address of mft 1855 0 00000281 8B4505 mget8: mov ax,[DI + sf_flags] 0 00000284 8CDA mov dx,ds ; save segment 0 00000286 0E push cs 0 00000287 1F pop ds 0 00000288 8B7404 mov si,[si + mft_lptr] ; (DS:SI) = Lock record address 0 0000028B 29C9 sub cx,cx ; clear counter 1862 0 0000028D 09F6 mget9: or si,si 0 0000028F 740F jz mget11 ; no more 0 00000291 3B7C0A cmp di,WORD PTR [si + rlr_sptr] 0 00000294 7506 jnz mget10 0 00000296 3B540C cmp dx,word PTR [si + rlr_sptr + 2] 0 00000299 7501 jnz mget10 0 0000029B 41 inc cx 0 0000029C 8B34 mget10: mov si,[si + rlr_next] 0 0000029E EBED JMP SHORT mget9 1872 1873 ; Done counting locks. return the info 1874 ; 1875 ; (cx) = count of locks 1876 ; (es:TOS) = buffer address 1877 0 000002A0 8EDA mget11: mov ds,dx 1879 SF_UID equ sf_UID ; NASM port equate 0 000002A2 8B5D2F mov bx,[di + SF_UID] ; (bx) = UID 0 000002A5 5F pop di 0 000002A6 F8 clc 0 000002A7 E8[0000] LeaveCrit critShare 1884 0 000002AA C3 ret 1886 1887 EndProc MFT_get 1888 1889 BREAK 1890 1891 ;******************* START OF SPECIFICATIONS *********************************** 1892 ; 1893 ; ASC - Add SFT to Chain 1894 ; 1895 ; ASC is called to add an SFT to the front of the chain. 1896 ; 1897 ; ASC checks the file share mode bits on the other SFTs in the chain and 1898 ; reports a conflict. The new SFT is NOT ADDED in the case of 1899 ; conflicts. 1900 ; 1901 ; ENTRY (BX) = FBA MFT name record 1902 ; (DS:SI) = SFT address 1903 ; EXIT 'C' clear if added 1904 ; (ds:si) point to sft 1905 ; (bx) offset of mft 1906 ; 'C' set if conflict 1907 ; (ax) = error code 1908 ; USES ALL 1909 ; 1910 ;******************* END OF SPECIFICATIONS ************************************* 1911 1912 Procedure ASC,NEAR 1912 ****************** warning: proc ASC... [-w+user] 1913 0 000002AB 837C3300 cmp word [si + sf_MFT],0 0 000002AF 753A jnz asc9 ; already on chain - internal error 1916 1917 ; The SFT looks good... lets see if there are any use conflicts 1918 1919 ; Message 1,<"Adding sft "> 1920 0 000002B1 36A1[0000] mov ax,[ss:User_ID] ; place user information in SFT 0 000002B5 89442F mov [si + sf_UID],ax ; do it before CUC (he checks UID) 0 000002B8 36A1[0000] mov ax,[ss:Proc_ID] 0 000002BC 894431 mov [si + sf_PID],ax 1925 0 000002BF 2E803E[0000]01 cmp byte [cs:skip_check],1 1927 ; $if ne ; 0 000002C5 7403 JE D_$IF24 1929 0 000002C7 E82301 call CUC ; check use conflicts 1931 1932 ; $endif 1933 D_$IF24: 1934 0 000002CA 721E jc asc8 ; use conflicts - forget it 1936 1937 ; MessageNum AX 1938 1939 ; MessageNum AX 1940 ; Message 1,<" to "> 1941 ; MEssageNum DS 1942 ; Message 1,<":"> 1943 ; MessageNum SI 1944 ; Message 1,<" "> 1945 0 000002CC 895C33 mov [si + sf_MFT],bx ; make SFT point to MFT 1947 1948 ; MessageNum [si].sf_mft 1949 ; Message 1,<13,10> 1950 0 000002CF 8B4C02 mov cx,[si + sf_mode] ; (cx) = open mode 0 000002D2 8CDA mov dx,ds ; (dx:si) = SFT address 0 000002D4 0E push cs 0 000002D5 1F pop ds ; (ds:bx) = MFT address 1955 1956 ; 1957 ; Not special file and no previous sft found OR normal SFT. We link it in 1958 ; at the head of the list. 1959 ; 1960 ; (dx:si) point to sft 1961 ; (ds:bx) point to mft 1962 ; 0 000002D6 C47F06 les di,[bx + mft_sptr] ; get first link 0 000002D9 897706 mov word ptr [bx + mft_sptr],si ; link in this sft 0 000002DC 895708 mov word ptr [bx + mft_sptr + 2],dx ; link in this sft 0 000002DF 8EDA mov ds,dx 0 000002E1 897C2B mov word ptr [si + sf_chain],di 0 000002E4 8C442D mov word ptr [si + sf_chain + 2],es 0 000002E7 8EDA asc75: mov ds,dx ; point back to sft 1970 0 000002E9 F8 clc 0 000002EA C3 asc8: ret 1973 1974 ; the SFT is already in use... internal error 1975 0 000002EB 50 asc9: push ax 0 000002EC B8[F202] off ax,ascerr 1978 INTERR equ interr ; NASM port label 0 000002EF E8[0000] call INTERR ; NEVER RETURNS 0 000002F2 4153433A2073667420 ascerr db "ASC: sft already in use", 13, 10, 0 0 000002FB 616C72656164792069 0 00000304 6E207573650D0A00 1981 1982 EndProc ASC 1983 1984 1985 BREAK 1986 1987 ;******************* START OF SPECIFICATIONS *********************************** 1988 ; 1989 ; BCS - Bulk Close of SFTs 1990 ; 1991 ; BCS scans the MFT structures looking for SFTs that match a UID (and 1992 ; perhaps a PID). The SFTs are closed. The MFT name record is removed 1993 ; if all its SFTs are closed. 1994 ; 1995 ; BCS is called with a PID and a PID MASK. The SFT is closed if its UID 1996 ; matches the supplied UID AND (PID_ & PIDMASK) == PID_supplied 1997 ; 1998 ; We walk the MFT structure closing all relevant SFT's. There is no 1999 ; need for special handling of 70 handles or FCBs. 2000 ; 2001 ; Note that we call DOS_close to close the SFT; DOS_close in turn calls 2002 ; mftclose which may remove the SFT and even the MFT. This means that 2003 ; the MFT may vanish as we are working on it. Whenever we call 2004 ; DOS_close we'll know the next SFT and, if there is no next SFT we'll 2005 ; know the next MFT. (If the MFT were released a pointer to the carcass 2006 ; is not of any help. An MFT carcass cannot help find the next MFT 2007 ; record) 2008 ; 2009 ; ENTRY (AX) = UID to match 2010 ; (BX) = PID mask 2011 ; (DX) = PID value 2012 ; EXIT 'C' clear 2013 ; USES ALL 2014 ; 2015 ;******************* END OF SPECIFICATIONS ************************************* 2016 2017 ASSUME SS:DOSGROUP 2018 2019 Procedure BCS,NEAR 2019 ****************** warning: proc BCS... [-w+user] 2020 0 0000030C 0E push cs 0 0000030D 1F pop ds 2023 0 0000030E BE[0000] Off SI,mft ; start at beginning of buffer 2025 2026 ; scan forward to the nearest name record (we may be at it now) 2027 ; 2028 ; (DS:SI) = record pointer 2029 0 00000311 803C00 bcs1: cmp byte [si + mft_flag],MFLG_FRE 0 00000314 7C07 jl bcs16 ; at end of names, all done 0 00000316 7F08 jg bcs2 ; have a name record 2033 0 00000318 037401 bcs1$5: add si,[si + mft_len] ; skip record and loop 0 0000031B EBF4 jmp bcs1 2036 0 0000031D EB67 bcs16: jmp bcs9 0 0000031F 90 nop ; identicalise 2039 0 00000320 C47C06 bcs2: les di,[si + mft_sptr] ; got name record - get first SFT 2041 ; run down SFT chain 2042 ; 2043 ; (es:di) = FBA next SFT 2044 ; (ds:si) = FBA name record 2045 ; (ax) = UID to match 2046 ; (bx) = PID mask 2047 ; (dx) = PID value 2048 0 00000323 09FF bcs3: or di,di 0 00000325 74F1 jz bcs1$5 ; at end of SFT chain 0 00000327 263B452F cmp ax,[es:di + sf_UID] 0 0000032B 750A jnz bcs4 ; not a match 0 0000032D 268B4D31 mov cx,[es:di + sf_PID] 0 00000331 21D9 and cx,bx ; apply mask 0 00000333 39D1 cmp cx,dx 0 00000335 7406 jz bcs51 ; got a match 2057 bcs4: 0 00000337 26C47D2B les di,[es:di + sf_chain] 0 0000033B EBE6 JMP bcs3 ; chain to next SFT 2060 2061 2062 ; We have an SFT to close 2063 ; 2064 ; (es:di) = FBA SFT to be closed 2065 ; 2066 ; (ds:si) = FBA name record 2067 ; (ax) = UID to match 2068 ; (bx) = PID mask 2069 ; (dx) = PID value 2070 0 0000033D 26C7050100 bcs51: mov word [es:di + sf_ref_count],1 0 00000342 50 push ax 0 00000343 53 push bx 0 00000344 52 push dx ; save ID values (ax,bx,dx) and mask 0 00000345 1E push ds 0 00000346 56 push si ; save name record address (ds:si) 0 00000347 268B752B mov si,word ptr [es:di + sf_chain] 0 0000034B 09F6 or si,si 0 0000034D 750E jnz bcs7 ; isnt last sft, MFT will remain 2080 2081 ; yup, this is the last sft for this MFT, the MFT may evaporate. we have 2082 ; to find the next one NOW, and remember it 2083 0 0000034F 5E pop si ; undo saved name record address 0 00000350 1F pop ds 0 00000351 037401 bcs6: add si,[si + mft_len] ; go to next guy 0 00000354 803C00 cmp byte [si + mft_flag],MFLG_FRE 0 00000357 74F8 jz bcs6 ; must be a non-free guy 0 00000359 1E push ds 0 0000035A 56 push si ; resave our new next MFT 0 0000035B 29F6 sub si,si ; no next sft 2092 2093 ; Allright, we're ready to call the DOS. 2094 ; 2095 ; (es:di) = FBA sft to be closed 2096 ; ((sp)) = long address of current or next MFT 2097 ; ((sp)+4) = PID value 2098 ; ((sp)+6) = PID mask 2099 ; ((sp)+8) = UID value 2100 0 0000035D 36893E[0000] bcs7: mov WORD PTR [ss:ThisSFT],di 0 00000362 368C06[0200] mov WORD PTR [ss:ThisSFT+2],es 0 00000367 268E452D mov es,word ptr [es:di + sf_chain + 2] 0 0000036B 0656 SaveReg 0 0000036D E8[0000] call CPS ; clear JFN 0 00000370 161F Context DS 2107 2108 multDos equ MultDOS ; NASM port equate 0 00000372 B80112CD2F CallInstall DOS_Close,multDos,1 2110 2111 ASSUME DS:NOTHING 2112 0 00000377 5F07 RestoreReg ; (es:DI) = offset of next sft 0 00000379 5E pop si 0 0000037A 1F pop ds ; (DS:SI) = fwa of current or next MFT 0 0000037B 5A pop dx 0 0000037C 5B pop bx 0 0000037D 58 pop ax 0 0000037E 09FF or di,di 0 00000380 7502 jnz bcs85 ; have more sft's 0 00000382 EB8D JMP bcs1 ; look at this new MFT 0 00000384 EB9D bcs85: jmp bcs3 2123 2124 ; All Done 2125 0 00000386 F8 bcs9: clc 2127 0 00000387 C3 ret 2129 2130 EndProc BCS 2131 2132 BREAK 2133 2134 ;******************* START OF SPECIFICATIONS *********************************** 2135 ; 2136 ; CSL - Clear SFT Locks 2137 ; 2138 ; CSL clears any locks associated with this SFT. 2139 ; 2140 ; ENTRY (ES:DI) = SFT address 2141 ; EXIT (ES:DI) unchanged 2142 ; USES All but ES,DI 2143 ; 2144 ;******************* END OF SPECIFICATIONS ************************************* 2145 2146 Procedure CSL,NEAR 2146 ****************** warning: proc CSL... [-w+user] 2147 0 00000388 268B7533 mov si,[es:di + sf_MFT] 0 0000038C 0E push cs 0 0000038D 1F pop ds 0 0000038E 8D5C04 lea bx,[si + mft_lptr] ; (DS:BX) = addr of lock ptr 0 00000391 8B37 mov si,[bx] ; (DS:SI) = fba first lock record 2153 2154 ; scan the locks looking for belongers. 2155 ; 2156 ; (es:di) = SFT address 2157 ; (ds:si) = this lock address 2158 ; (ds:bx) = address of link (offset value) to this lock (prev lock) 2159 0 00000393 09F6 csl1: or si,si 0 00000395 7437 jz csl3 ; done with lock list 0 00000397 3B7C0A cmp di,word ptr [si + rlr_sptr] 0 0000039A 752C jnz csl2 ; not my lock 0 0000039C 8CC0 mov ax,es 0 0000039E 3B440C cmp ax,word ptr [si + rlr_sptr + 2] 0 000003A1 7525 jnz csl2 ; not my lock 2167 ; 2168 ; Make sure that the lock REALLY belongs to the correct process 2169 ; 0 000003A3 36813E[0000]045D cmp word [ss:user_in_ax], (ServerCall << 8) + 4 ; only check if ; @@01 0 000003AA 7509 jnz csl15 ; process specific; @@01 0 000003AC 36A1[0000] mov ax,[ss:Proc_ID] 0 000003B0 3B440E cmp ax,[si + rlr_pid] ; is process ID of lock = this PID? 0 000003B3 7513 jnz csl2 ; nope, skip this lock 2175 2176 ; got a lock to remove 2177 2178 csl15: 0 000003B5 8B14 mov dx,[si + rlr_next] 0 000003B7 8917 mov [bx],dx ; link him out 0 000003B9 2EA1[0000] mov ax,[cs:Frelock] 0 000003BD 8904 mov [si + rlr_next],ax 0 000003BF 2E8936[0000] mov [cs:Frelock],si 0 000003C4 89D6 mov si,dx ; (DS:SI) = next lock address 0 000003C6 EBCB JMP SHORT csl1 2186 2187 ERRNZ rlr_next ; lock is not ours... follow chain 0 000003C8 89F3 csl2: mov bx,si 0 000003CA 8B34 mov si,[si + rlr_next] 0 000003CC EBC5 JMP SHORT csl1 2191 2192 ; All done 2193 0 000003CE C3 csl3: ret 2195 2196 EndProc CSL 2197 2198 ASSUME DS:NOTHING 2199 2200 BREAK 2201 2202 ;******************* START OF SPECIFICATIONS *********************************** 2203 ; 2204 ; Use conflict table 2205 ; 2206 ; Algorithm: 2207 ; 2208 ; if ((newmode == COMPAT) or (oldmode == COMPAT)) 2209 ; and (user ID's match) 2210 ; then accept 2211 ; else 2212 ; for new and old mode, compute index of (SH*3)+ACC 2213 ; shift right table[new_index] by old_index+2; 2214 ; 'C' set if FAIL 2215 ; 2216 ; The bit in the old_index position indicates the success or failure. 0 2217 ; => allow access, 1 => fail access 2218 ; 2219 ;******************* END OF SPECIFICATIONS ************************************* 2220 2221 PUBLIC CUCA 2222 0 000003CF FFFF CUCA: DW 0ffffh ; Compat Read 0 000003D1 FFFF DW 0ffffh ; Compat Write 0 000003D3 FFFF DW 0ffffh ; Compat Read/Write 0 000003D5 FFFF DW 0ffffh ; Deny R/W Read 0 000003D7 FFFF DW 0ffffh ; Deny R/W Write 0 000003D9 FFFF DW 0ffffh ; Deny R/W Read/Write 0 000003DB 7FDF DW 0df7fh ; Deny W Read 0 000003DD FFDB DW 0dbffh ; Deny W Write 0 000003DF FFDF DW 0dfffh ; Deny W Read/Write 0 000003E1 FFBE DW 0beffh ; Deny R Read 0 000003E3 FFB7 DW 0b7ffh ; Deny R Write 0 000003E5 FFBF DW 0bfffh ; Deny R Read/Write 0 000003E7 7F1C DW 01c7fh ; Deny None Read 0 000003E9 FF03 DW 003ffh ; Deny None Write 0 000003EB FF1F DW 01fffh ; Deny None Read/Write 2238 2239 ; 4443 3322 2111 000 2240 ; Deny/Compat / DDDD DDDD DDDD CCCx 2241 ; DenyRead / R RR RRR 2242 ; DenyWrite 1st Access =< WW WWWW 2243 ; AccessRead \ R RR RR RR R R R 2244 ; AccessWrite \ WW W W WW WW WW 2245 ; x 1111 1111 1111 1111 2246 ; C R 00 1111 1111 1111 1111 ffff 2247 ; C W 01 1111 1111 1111 1111 ffff 2248 ; C RW 02 1111 1111 1111 1111 ffff 2249 2250 ; DRWR 10 1111 1111 1111 1111 ffff 2251 ; DRW W 11 1111 1111 1111 1111 ffff 2252 ; DRWRW 12 1111 1111 1111 1111 ffff 2253 ; D WR 20 1101 1111 0111 1111 df7f 2254 2255 ; D W W 21 1101 1011 1111 1111 dbff 2256 ; D WRW 22 1101 1111 1111 1111 dfff 2257 ; DR R 30 1011 1110 1111 1111 beff 2258 ; DR W 31 1011 0111 1111 1111 b7ff 2259 2260 ; DR RW 32 1011 1111 1111 1111 bfff 2261 ; D R 40 0001 1100 0111 1111 1c7f 2262 ; D W 41 0000 0011 1111 1111 03ff 2263 ; D RW 42 0001 1111 1111 1111 1fff 2264 2265 ; In order to allow the greatest number of accesses, compatability read mode 2266 ; is treated as deny-write read. The other compatability modes are treated 2267 ; as deny-both. 2268 2269 ;******************* START OF SPECIFICATIONS *********************************** 2270 ; 2271 ; CUC - check usage conflicts 2272 ; 2273 ; CUC is called to see if a would-be open would generate a share 2274 ; conflict with an existing open. See CUCA for the algorithm and table 2275 ; format. 2276 ; 2277 ; ENTRY (BX) = FBA MFT name record 2278 ; (DS:SI) = SFT address 2279 ; EXIT 'C' clear if OK 2280 ; 'C' set if conflict 2281 ; (ax) = error code 2282 ; USES ALL but arguments (BX, DS:SI) 2283 ; 2284 ;******************* END OF SPECIFICATIONS ************************************* 2285 2286 Procedure CUC,NEAR 2286 ****************** warning: proc CUC... [-w+user] 2287 0 000003ED 1E push ds 0 000003EE 07 pop es 0 000003EF 89F7 mov di,si ; (es:di) = FBA SFT record 2291 gom equ GOM ; NASM port label 0 000003F1 E86B00 call gom ; get open mode 0 000003F4 88C5 mov ch,al 0 000003F6 80E5F0 and ch,sharing_mask ; (ch) = new guy share 0 000003F9 7402 jz cuc0 ; new guy is compatability mode 0 000003FB B5F0 mov ch,sharing_mask 2297 csi equ CSI ; NASM port label 0 000003FD E84100 cuc0: call csi ; compute share index 0 00000400 01C0 add ax,ax ; *2 for word index 0 00000402 96 xchg ax,si ; (si) = share table index 0 00000403 0E push cs 0 00000404 1F pop ds ; (ds:bx) = FBA MFT record 0 00000405 2E8B94[CF03] mov dx,WORD PTR [cs:CUCA + si] ; (dx) = share mask 0 0000040A C57706 lds si,[bx + mft_sptr] ; (ds:si) = first sft guy 2305 2306 ; ready to do access compares. 2307 ; 2308 ; (ds:si) = address of next sft 2309 ; (es:di) = address of new sft 2310 ; (dx) = share word from CUCA 2311 ; (cs:bx) = MFT offset 2312 ; (ch) = 0 if new SFT is compatibilty mode, else sharing_mask 2313 0 0000040D 09F6 cuc1: or si,si 0 0000040F 742B jz cuc9 ; at end of chain, no problems 0 00000411 E84B00 call gom ; if not FCB, then mode in al is good 0 00000414 88C4 mov ah,al 0 00000416 80E4F0 and ah,sharing_mask ; (ah) = sharing mode 0 00000419 08EC or ah,ch ; (ah) = 0 iff new and old is SH_COMP 0 0000041B 7509 jnz cuc2 ; neither is SH_COMP 2321 2322 ; Both the old and the new guy are SH_COMP mode. If the UIDs match, 2323 ; step onward. If they don't match do normal share check. 2324 0 0000041D 268B6D2F mov bp,[es:di + sf_UID] 0 00000421 3B6C2F cmp bp,[si + sf_UID] 0 00000424 740D jz cuc20 ; equal => next sft to check 2328 0 00000426 E81800 cuc2: call csi ; compute the share index 0 00000429 40 inc ax 0 0000042A 40 inc ax 0 0000042B 86C1 xchg al,cl ; (cl) = shift count 0 0000042D 89D0 mov ax,dx 0 0000042F D3F8 sar ax,cl ; select the bit 0 00000431 7205 jc cuc8 ; a conflict! 2336 cuc20: 0 00000433 C5742B lds si,[si + sf_chain] 0 00000436 EBD5 JMP cuc1 ; chain to next SFT and try again 2339 2340 ; Have a share conflict 2341 0 00000438 B82000 cuc8: mov ax,error_sharing_violation ; assume share conflict 0 0000043B F9 stc 2344 2345 ; done with compare. Restore regs and return 2346 ; 2347 ; 'C' set as appropriate 2348 ; (es:di) = new SFT address 2349 ; (ax) set as appropriate 2350 ; (bx) = MFT offset 2351 0 0000043C 06 cuc9: push es 0 0000043D 1F pop ds 0 0000043E 89FE mov si,di 2355 0 00000440 C3 ret 2357 2358 EndProc CUC 2359 2360 BREAK 2361 2362 ;******************* START OF SPECIFICATIONS *********************************** 2363 ; 2364 ; csi - compute share index 2365 ; 2366 ; 2367 ; If the mode byte has a leading 7 then it is interpreted as a 0 2368 ; csi turns a mode byte into an index from 0 to 14: 2369 ; 2370 ; (share index)*3 + (access index) 2371 ; 2372 ; ENTRY (al) = mode byte 2373 ; EXIT (ax) = index 2374 ; USES AX, CL 2375 ; 2376 ;******************* END OF SPECIFICATIONS ************************************* 2377 2378 Procedure CSI,NEAR 2378 ****************** warning: proc CSI... [-w+user] 2379 0 00000441 88C4 mov ah,al 0 00000443 80E40F and ah,access_mask ; (ah) = access bits 0 00000446 24F0 and al,sharing_mask ; (al) = share bites 2383 ERRNZ sharing_mask-0F0h 0 00000448 3C70 cmp al,sharing_net_FCB 0 0000044A 7502 jnz csi1 0 0000044C 30C0 xor al,al 2387 csi1: 0 0000044E D0E8 shr al,1 0 00000450 D0E8 shr al,1 0 00000452 D0E8 shr al,1 0 00000454 88C1 mov cl,al ; (cl) = SHVAL*2 0 00000456 D0E8 shr al,1 0 00000458 00C8 add al,cl ; (al) = SHVAL*3 0 0000045A 00E0 add al,ah ; (al) = SH*3 + ACC 0 0000045C 28E4 sub ah,ah 2396 0 0000045E C3 ret 2398 2399 EndProc CSI 2400 2401 Break 2402 2403 ;******************* START OF SPECIFICATIONS *********************************** 2404 ; 2405 ; GOM - get open mode 2406 ; 2407 ; Find the correct open mode given the encoded sf_mode. Note that files 2408 ; marked READ-ONLY and are opened in compatability read-only are treated as 2409 ; deny-write read-only. FCB opens are sharing_compat open_for_both and 2410 ; net FCB opens are sharing_compat 2411 ; 2412 ; Entry: (DS:SI) points to SFT 2413 ; Exit: (AL) has correct mode 2414 ; Uses: (AX) 2415 ;******************* END OF SPECIFICATIONS ************************************* 2416 2417 Procedure GOM,NEAR 2417 ****************** warning: proc GOM... [-w+user] 2418 0 0000045F 8B4402 mov ax,[si + sf_mode] 2420 sf_IsFCB equ sf_isfcb ; NASM port equate 0 00000462 A90080 TEST AX,sf_IsFCB 0 00000465 7402 jz gom1 ; if not FCB, then mode in al is good 0 00000467 B002 mov al,sharing_compat+open_for_both 2424 gom1: 0 00000469 88C4 mov ah,al 0 0000046B 80E4F0 and ah,sharing_mask 0 0000046E 80FC70 cmp ah,sharing_net_FCB ; is sharing from net FCB? 0 00000471 7504 jnz gom2 ; no, got good mode 0 00000473 240F and al,access_mask ; yes, convert to compat mode sharing 0 00000475 0C00 or al,sharing_compat 2431 ; 2432 ; The sharing mode and access mode in AL is now correct for the file. See if 2433 ; mode is compatability. If so and file is read-only, convert access mode to 2434 ; deny-write read. 2435 ; 2436 gom2: 0 00000477 88C4 mov ah,al 0 00000479 80E4F0 and ah,sharing_mask 0 0000047C 7401C3 retnz ; not compatability, return. 0 0000047F F6440401 test byte [si + sf_attr],attr_read_only 0 00000483 74F9 retz ; not read-only 0 00000485 B020 mov al,sharing_deny_write + open_for_read 2443 0 00000487 C3 ret 2445 2446 EndProc GOM === Trace listing source: gshare2.lst 1 ; Title Share_2 2 ; $SALUT (0,36,41,44) 3 %include "sharehdr.mac" 1 <1> ; page 80,132 2 <1> ;******************* START OF SPECIFICATIONS *********************************** 3 <1> ; 4 <1> ; MODULE NAME: SHARE.EXE (a true EXE file) 5 <1> ; 6 <1> ; DESCRIPTIVE NAME: SHARE resident service routines - part 1 - GSHARE.SAL 7 <1> ; - part 2 - GSHARE2.SAL 8 <1> ; - part 3 - SHARESR.SAL 9 <1> ; 10 <1> ; FUNCTION: Provide file sharing services for DOS 11 <1> ; 12 <1> ; ENTRY POINT: DOS Jump Table - installed by SHARE at initalization 13 <1> ; 14 <1> ; MFT_Enter 1 15 <1> ; MFTClose 2 16 <1> ; MFTClu 3 17 <1> ; MFTCloseP 4 18 <1> ; MFTCloN 5 19 <1> ; Set_Mult_Block 6 20 <1> ; Clr_Mult_Block 7 21 <1> ; Chk_Block 8 22 <1> ; MFT_Get 9 23 <1> ; 24 <1> ; INPUT: See Prolog to individual entry points 25 <1> ; 26 <1> ; EXIT NORMAL: CF = 0 and requested task performed. 27 <1> ; 28 <1> ; EXIT ERROR: CF = 1 ans error code in AX 29 <1> ; 30 <1> ; INTERNAL REFERENCES: 31 <1> ; 32 <1> ; ROUTINES: Set_Block BCS 33 <1> ; Clr_Block CSL 34 <1> ; CLP CUC 35 <1> ; Load_Regs CSI 36 <1> ; ASC GOM 37 <1> ; 38 <1> ; DATA AREAS: 39 <1> ; 40 <1> ; EXTERNAL REFERENCES: INT 21 INT 2F 41 <1> ; together with: 42 <1> ; 43 <1> ; fnm:near, rsc:near, rmn:near, cps:near, ofl:near, sle:near, interr:near 44 <1> ; 45 <1> ; ROUTINES: 46 <1> ; 47 <1> ; DATA AREAS: 48 <1> ; 49 <1> ; NOTES: The second part of this utility is GSHARE2.ASM 50 <1> ; 51 <1> ; REVISION HISTORY: Version 1.0 09/09/83 - first release GL 52 <1> ; 09/13/83 - Installability MZ 53 <1> ; 01/11/84 - FCB compatability changes MZ 54 <1> ; PTM P000438 08/21/86 - SFT LCK FIELDS not 0 error DL 55 <1> ; Ax000 Ver 4.0 04/15/87 - changed:- Set_Block FJG 56 <1> ; - Clr_Block FJG 57 <1> ; - Chk_Block FJG 58 <1> ; - CLP FJG 59 <1> ; new: - Set_Mult_Block FJG 60 <1> ; - Clr_Mult_Block FJG 61 <1> ; - Load_Regs FJG 62 <1> ; - Clr_List FJG 63 <1> ; Ax002 PTM P001658 10/15/87 - changed I/F to IBMDOS FJG 64 <1> ; Ax003 PTM P002064 10/15/87 - ShSU SFT - IFS call error FJG 65 <1> ; Ax004 PTM P002121 10/29/87 - Clr_Mult_Block cx=-1 err FJG 66 <1> ; Ax005 PTM P002322 11/06/87 - Call_IFS - 2F semaphore FJG 67 <1> ; Ax006 DCR D000494 12/17/87 - DOS 4.00 function reductionFJG 68 <1> ; Ax007 PTM P003841 03/17/88 - access error for Turbo L FJG 69 <1> ; Ax008 PTM P003880 03/17/88 - duped handle error FJG 70 <1> ; Ax009 PTM P003910 03/17/88 - wrong parse error format FJG 71 <1> ; Ax010 DCR D000526 04/27/88 - add /nc switch support FJG 72 <1> ; Ax011 PTM P004546 05/03/88 - add /nc support to fShare FJG 4 ; 5 ; Label: "The DOS SHARE Utility" 6 ; "Version 4.00 (C) Copyright 1988 Microsoft" 7 ; "Licenced Material - Program Property of Microsoft" 8 ; 9 ;******************* END OF SPECIFICATIONS ************************************* 10 === Switch to base=000000h -> "SHARE" 11 section SHARE align=1 PUBLIC class=SHARE 12 13 ; NAME Sharer2 14 15 ; INCLUDE DOSSYM.INC 16 ; INCLUDE SYSMSG.INC 17 [list -] 17 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 17 ****************** warning: out: BPB.INC... [-w+user] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 17 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 22 ; .cref 23 [list +] 24 ; page 80,132 25 26 MSG_UTILNAME 303 <1> stripangles %defstr %%string, %1 304 <1> %strlen %%length %%string 305 <1> %assign %%ii 1 306 <1> %define %%name "" 307 <1> %rep %%length 308 <1> %substr %%cc %%string %%ii 309 <1> %assign %%ii %%ii + 1 310 <1> %if %%cc >= 'A' && %%cc <= 'Z' 311 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <1> %endif 313 <1> %strcat %%name %%name,%%cc 314 <1> %endrep 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 315 <1> %strcat %%name %%name,".ctl" 316 <1> %unimacro equ 1+.nolist 317 <1> %imacro equ 1+.nolist 318 <1> %defstr %%string %00 319 <1> %substr %%cc %%string 1 320 <1> %ifidni %%cc, "$" 321 <1> %iassign %00 %1 322 <1> %else 323 <1> %00 equ %1 324 <1> %endif 325 <1> %endmacro 326 <1> %include %%name 1 <2> $M_NUM_CLS EQU 1 327 <1> %unimacro equ 1+.nolist 328 <1> %iassign $M_STRUC TRUE 329 <1> 330 <1> %include "msgserv.nas" 1 <2> ;=== Push trace listing source: msgserv.nas 2 <2> 3 <2> ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * 4 <2> ; 5 <2> ; MODULE NAME: MSGSERV.SAL 6 <2> ; 7 <2> ; DESCRIPTIVE NAME: Message Services SALUT file 8 <2> ; 9 <2> ; FUNCTION: This module incorporates all the messages services and 10 <2> ; is called upon at build time to INCLUDE the code requested 11 <2> ; by a utility. Code is requested using the macro MSG_SERVICES. 12 <2> ; 13 <2> ; ENTRY POINT: Since this a collection of subroutines, entry point is at 14 <2> ; requested procedure. 15 <2> ; 16 <2> ; INPUT: Since this a collection of subroutines, input is dependent on function 17 <2> ; requested. 18 <2> ; 19 <2> ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 20 <2> ; 21 <2> ; EXIT-ERROR: In all cases, CARRY FLAG = 1 22 <2> ; 23 <2> ; INTERNAL REFERENCES: (list of included subroutines) 24 <2> ; 25 <2> ; - SYSLOADMSG 26 <2> ; - SYSDISPMSG 27 <2> ; - SYSGETMSG 28 <2> ; 29 <2> ; 30 <2> ; EXTERNAL REFERENCES: None 31 <2> ; 32 <2> ; NOTES: At build time, some modules must be included. These are only included 33 <2> ; once using assembler switches. Other logic is included at the request 34 <2> ; of the utility. 35 <2> ; 36 <2> ; COMR and COMT are assembler switches to conditionally assemble code 37 <2> ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident 38 <2> ; storage and multiple EQUates. 39 <2> ; 40 <2> ; REVISION HISTORY: Created MAY 1987 41 <2> ; 42 <2> ; Label: DOS - - Message Retriever 43 <2> ; (c) Copyright 1988 Microsoft 44 <2> ; 45 <2> ; 46 <2> ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * 47 <2> ; Page 48 <2> 49 <2> ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting 50 <2> 51 <2> %IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN 52 <2> %iassign $M_STRUC FALSE ;;AN000;; Let the assembler know that we have 53 <2> ;;AN000;; and include them 54 <2> 55 <2> ; PAGE 56 <2> ; SUBTTL DOS - Message Retriever - MSGSTR.INC Module 57 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 <2> ;; 59 <2> ;; STRUCTURE: $M_SUBLIST_STRUC 60 <2> ;; 61 <2> ;; Replacable parameters are described by a sublist structure 62 <2> ;; 63 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 <2> ;; 65 <2> $M_SUBLIST_STRUC STRUC ;;AN000;; 66 <2> ;; 0 00000488 ?? $M_S_SIZE DB ? ;11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) 0 00000489 ?? $M_S_RESV DB ? ;0 ;;AN000;; RESERVED 0 0000048A ???????? $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item 0 0000048E ?? $M_S_ID DB ? ;;AN000;; n of %n 0 0000048F ?? $M_S_FLAG DB ? ;;AN000;; Data-type flags 0 00000490 ?? $M_S_MAXW DB ? ;;AN000;; Maximum field width 0 00000491 ?? $M_S_MINW DB ? ;;AN000;; Minimum field width 0 00000492 ?? $M_S_PAD DB ? ;;AN000;; Character for Pad field 75 <2> ;; 76 <2> $M_SUBLIST_STRUC ENDS ;;AN000;; 76 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 77 <2> ;; 78 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 <2> ;; 80 <2> ;; STRUCTURE: $M_CLASS_ID 81 <2> ;; 82 <2> ;; Each class will be defined by this structure. 83 <2> ;; 84 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 <2> ;; 86 <2> EXPECTED_VERSION equ expected_version ; NASM port equate 87 <2> 88 <2> $M_CLASS_ID STRUC ;;AN000;; 89 <2> ;; 0 00000488 ?? $M_CLS_ID DB ? ;-1 ;;AN000;; Class identifer 0 00000489 ???? $M_COMMAND_VER DW ? ;EXPECTED_VERSION ;;AN003;; COMMAND.COM version check 0 0000048B ?? $M_NUM_CLS_MSG DB ? ;0 ;;AN000;; Total number of message in class 93 <2> ;; 94 <2> $M_CLASS_ID ENDS ;; 94 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 95 <2> ;;AN000;; 96 <2> $M_CLASS_ID_SZ EQU $M_CLASS_ID_struc_size ;;AN000;; 97 <2> ;; 98 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 <2> ;; 100 <2> ;; STRUCTURE: $M_ID_STRUC 101 <2> ;; 102 <2> ;; Each message will be defined by this structure. 103 <2> ;; 104 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 105 <2> ;; 106 <2> $M_ID STRUC ;;AN000;; 107 <2> ;; 0 00000488 ???? $M_NUM DW ? ;-1 ;;AN000;; Message Number 0 0000048A ???? $M_TXT_PTR DW ? ;;AN000;; Pointer to message text 110 <2> ;; 111 <2> $M_ID ENDS ;;AN000;; 111 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 112 <2> ;;AN000;; Status Flag Values: 113 <2> $M_ID_SZ EQU $M_ID_struc_size ;;AN000;; 114 <2> ;; 115 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 <2> ;; 117 <2> ;; STRUCTURE: $M_RES_ADDRS 118 <2> ;; 119 <2> ;; Resident data area definition of variables 120 <2> ;; 121 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122 <2> ;; 123 <2> $M_RES_ADDRS STRUC ;;AN000;; 124 <2> ;; 0 00000488 ???????? $M_EXT_ERR_ADDRS DD ? ;0 ;;AN000;; Allow pointers to THREE Extended error locations 0 0000048C ???????? $M_EXT_FILE DD ? ;0 ;;AN001;; 0 00000490 ???????? $M_EXT_COMMAND DD ? ;0 ;;AN000;; 0 00000494 ???????? $M_EXT_TERM DD ? ;-1 ;;AN000;; 0 00000498 ???????? $M_PARSE_COMMAND DD ? ;0 ;;AN000;; 0 0000049C ???????? $M_PARSE_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Parse error locations 0 000004A0 ???????? $M_PARSE_TERM DD ? ;-1 ;;AN000;; 0 000004A4 ???????? $M_CRIT_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Critical error locations 0 000004A8 ???????? $M_CRIT_COMMAND DD ? ;0 ;;AN000;; 0 000004AC ???????? $M_CRIT_TERM DD ? ;-1 ;;AN000;; 0 000004B0 ???????? $M_DISK_PROC_ADDR DD ? ;-1 ;;AN004;; Address of READ_DISK_PROC 0 000004B4 ???????? $M_CLASS_ADDRS DD $M_NUM_CLS DUP (?) ;(0) ;;AN000;; Allow pointers to specified classes 0 000004B8 ???????? $M_CLS_TERM DD ? ;-1 ;;AN000;; 0 000004BC ???????? $M_DBCS_VEC DD ? ;0 ;;AN000;; Save DBCS vector 0 000004C0 ???? $M_HANDLE DW ? ;;AN000;; 0 000004C2 ?? $M_SIZE DB ? ;0 ;;AN000;; 0 000004C3 ???? $M_CRLF DB ?,? ;0DH,0AH ;;AN004;; CR LF message 0 000004C5 ?? $M_CLASS DB ? ;;AN004;; Saved class 0 000004C6 ???? $M_RETURN_ADDR DW ? ;;AN000;; 0 000004C8 ???? $M_MSG_NUM DW ? ;$M_NULL ;;AN000;; 0 000004CA ???? $M_DIVISOR DW ? ;10 ;;AN000;; Default = 10 (must be a WORD for division) 146 00000044 <2> $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP (?) ;("$") ;;AN000;; Temporary buffer 0 0000050C ?? $M_BUF_TERM DB ? ;"$" ;;AN000;; 148 <2> 149 <2> $M_RES_ADDRS ENDS ;;AN000;; 149 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 150 <2> ;; 151 <2> $M_RES_ADDRS_SZ EQU $M_RES_ADDRS_struc_size ;;AN000;; 152 <2> ;; 153 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 <2> ;; 155 <2> ;; STRUCTURE: $M_COUNTRY_INFO 156 <2> ;; 157 <2> ;; Important fields of the Get Country Information call 158 <2> ;; 159 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 <2> ;; 161 <2> $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation 162 <2> ;; 163 00000000 <2> $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc 0 000004CC ???? $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format 0 000004CE ?????????? $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; 0 000004D3 ???? $M_THOU_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Thou Separator 0 000004D5 ???? $M_DECI_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Decimal Separator 0 000004D7 ???? $M_DATE_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Date Separator 0 000004D9 ???? $M_TIME_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Time Separator 0 000004DB ?? $M_CURR_FORMAT DB ? ;;AN000;; 0 000004DC ?? $M_SIG_DIGS_CU DB ? ;;AN000;; 0 000004DD ?? $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format 173 <2> ;; 174 <2> $M_COUNTRY_INFO ENDS ;;AN000;; 174 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 176 <2> ;; 177 <2> %ELSE ;;AN000;; ELSE if we have already included the STRUCTURES 178 <2> ; 179 <2> ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section 180 <2> 181 <2> %IF MSGDATA ;;AN000;; IF this is a request to include the data area 182 <2> %iassign MSGDATA FALSE ;;AN000;; Let the assembler know not to include it again 183 <2> ;;AN000;; and include it 184 <2> ; PAGE 185 <2> ; SUBTTL DOS - Message Retriever - MSGRES.TAB Module 186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187 <2> ;; 188 <2> ;; DATA NAME: $M_RES_TABLE 189 <2> ;; 190 <2> ;; REFERENCE LABEL: $M_RT 191 <2> ;; 192 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 193 <2> 194 <2> %if 0 ; disabled for now, figure out later 195 <2> %IF COMR ;;AN000;; Since COMMAND.COM includes this twice 196 <2> $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no 197 <2> $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur 198 <2> $M_ALTLABEL equ TRUE ;;AN000;; Flag that label was changed 199 <2> %ELSE ;;AN000;; 200 <2> $M_RT LABEL BYTE ;;AN000;; 201 <2> %ENDIF 202 <2> %endif 203 <2> $M_RT: ; NASM structure instance 204 <2> $M_RES_ADDRS_size equ $M_RES_ADDRS_struc_size ; NASM port equate 205 <2> istruc $M_RES_ADDRS 206 <2> at $M_EXT_ERR_ADDRS 207 <2> dd 0 208 <2> at $M_EXT_FILE 209 <2> dd 0 210 <2> at $M_EXT_COMMAND 211 <2> dd 0 212 <2> at $M_EXT_TERM 213 <2> dd -1 214 <2> at $M_PARSE_COMMAND 215 <2> dd 0 216 <2> at $M_PARSE_ADDRS 217 <2> dd 0 218 <2> at $M_PARSE_TERM 219 <2> dd -1 220 <2> at $M_CRIT_ADDRS 221 <2> dd 0 222 <2> at $M_CRIT_COMMAND 223 <2> dd 0 224 <2> at $M_CRIT_TERM 225 <2> dd -1 226 <2> at $M_DISK_PROC_ADDR 227 <2> dd -1 228 <2> at $M_CLASS_ADDRS 229 <2> times $M_NUM_CLS dd 0 230 <2> at $M_CLS_TERM 231 <2> dd -1 232 <2> at $M_DBCS_VEC 233 <2> dd 0 234 <2> at $M_HANDLE 235 <2> dw 0 236 <2> at $M_SIZE 237 <2> db 0 238 <2> at $M_CRLF 239 <2> db 0Dh, 0Ah 240 <2> at $M_CLASS 241 <2> db 0 242 <2> at $M_RETURN_ADDR 243 <2> dw 0 244 <2> at $M_MSG_NUM 245 <2> dw 0 246 <2> at $M_DIVISOR 247 <2> dw 10 248 <2> at $M_TEMP_BUF 249 <2> times $M_TEMP_BUF_SZ db "$" 250 <2> at $M_BUF_TERM 251 <2> db "$" 252 <2> iend 253 <2> ;; 254 <2> %include "copyrigh.mac" ;;AN001;; Include Copyright 1988 Microsoft 255 <2> ;; 256 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 257 <2> %ENDIF ;;AN000;; END of include of Data table 258 <2> 259 <2> ; 260 <2> %IFN $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN 261 <2> ;; don't include any more code 262 <2> ;;AN000;; Figure out what other code to include 263 <2> %IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code 264 <2> %IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) 265 <2> $M_RT EQU $M_RT2 ;;AN003;; 266 <2> %ENDIF 267 <2> %iassign DISK_PROC FALSE ;;AN003;; Yes, THEN include it and reset flag 268 <2> ; PAGE 269 <2> ; SUBTTL DOS - Message Retriever - DISK_PROC Module 270 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 271 <2> ;; 272 <2> ;; PROC NAME: DISK_PROC 273 <2> ;; 274 <2> ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended 275 <2> ;; errors from disk\diskette 276 <2> ;; INPUTS: AX has the message number 277 <2> ;; DX has the message class 278 <2> ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is 279 <2> ;; assumed to be set!! 280 <2> ;; 281 <2> ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text 282 <2> ;; 283 <2> ;; 284 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 285 <2> ;; 286 <2> PUBLIC READ_DISK_PROC ;; 287 <2> ;; 288 <2> READ_DISK_PROC PROC FAR ;;AN003;; 289 <2> 290 <2> PUSH AX ;;AN003;; Save everything 291 <2> PUSH BX ;;AN003;; 292 <2> PUSH DX ;;AN003;; 293 <2> PUSH SI ;;AN003;; 294 <2> PUSH BP ;;AN003;; 295 <2> PUSH DS ;;AN003;; 296 <2> PUSH DI ;;AN003;; 297 <2> MOV BP,AX ;;AN003;; Save message number 298 <2> MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function 299 <2> LEA SI,[COMSPEC wrt RESGROUP] ;;AN003;; Get addressibilty to COMMAND.COM 300 <2> PUSH CS ;;AN003;; 301 <2> POP DS ;;AN003;; 302 <2> MOV DI,-1 ;;AN003;; No extended attribute list 303 <2> MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error 304 <2> MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag 305 <2> INT 21H ;;AN003;; Open the file 306 <2> POP DI ;;AN003;; Retreive LSEEK pointer 307 <2> ;;AN003;; Error ? 308 <2> ; $IF NC,LONG ;;AN003;; No, 309 <2> JNC $MXL1 310 <2> JMP $MIF1 311 <2> $MXL1: 312 <2> PUSH DI ;;AN003;; Save LSEEK pointer 313 <2> MOV BX,AX ;;AN003;; Set handle in BX 314 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors 315 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 316 <2> MOV DX,DI ;;AN003;; 317 <2> INT 21H ;;AN003;; LSEEK the file 318 <2> POP DX ;;AN003;; Retreive LSEEK pointer 319 <2> ;;AN003;; Error ? 320 <2> ; $IF NC ;;AN003;; No, 321 <2> JC $MIF2 322 <2> INC CX ;;AN003;; Set flag to first pass 323 <2> ; $DO ;;AN003;; 324 <2> $MDO3: 325 <2> PUSH DX ;;AN003;; Save LSEEK pointer 326 <2> PUSH CX ;;AN003;; Save first pass flag 327 <2> PUSH AX ;;AN003;; Save number of messages (if set yet) 328 <2> XOR SI,SI ;;AN003;; Reset buffer index 329 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 330 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header 331 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 332 <2> INT 21H ;;AN003;; Read it 333 <2> MOV DI,DX ;;AN003;; 334 <2> POP AX ;;AN003;; 335 <2> POP CX ;;AN003;; 336 <2> OR CX,CX ;;AN003;; 337 <2> ; $IF NZ ;;AN003;; 338 <2> JZ $MIF4 339 <2> XOR CX,CX ;;AN003;; Set flag to second pass 340 <2> XOR AH,AH ;;AN003;; Get number of messages in class 341 <2> MOV AL,[DI + $M_NUM_CLS_MSG] ;;AN003;; 342 <2> MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index 343 <2> CMP word [DI + $M_COMMAND_VER],EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? 344 <2> ; $ENDIF ;;AN003;; 345 <2> $MIF4: 346 <2> POP DX ;;AN003;; 347 <2> ; $IF Z ;;AN003;; Yes, 348 <2> JNZ $MIF6 349 <2> ; $SEARCH ;;AN003;; 350 <2> $MDO7: 351 <2> CMP BP,WORD PTR [$M_RT + $M_TEMP_BUF + SI] ;;AN003;; Is this the message I'm looking for? 352 <2> ; $EXITIF Z ;;AN003;; Yes, (ZF=1) 353 <2> JNZ $MIF7 354 <2> CLC ;;AN003;; Reset carry, exit search 355 <2> ; $ORELSE ;;AN003;; No, (ZF=0) 356 <2> JMP SHORT $MSR7 357 <2> $MIF7: 358 <2> ADD SI,$M_ID_SZ ;;AN003;; Increment index 359 <2> ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header 360 <2> DEC AX ;;AN003;; Decrement # of messages left 361 <2> ; $LEAVE Z ;;AN003;; Have we exhausted all messages? 362 <2> JZ $MEN7 363 <2> CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? 364 <2> ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) 365 <2> JNA $MDO7 366 <2> $MEN7: 367 <2> STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) 368 <2> ; $ENDSRCH ;;AN003;; 369 <2> $MSR7: 370 <2> ; $ELSE ;;AN003;; No, 371 <2> JMP SHORT $MEN6 372 <2> $MIF6: 373 <2> XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop 374 <2> STC ;;AN003;; Set Carry 375 <2> ; $ENDIF ;;AN003;; 376 <2> $MEN6: 377 <2> ; $ENDDO Z ;;AN003;; Get next buffer full if needed 378 <2> JNZ $MDO3 379 <2> ;;AN003;; Error ? 380 <2> ; $IF NC ;;AN003;; No, 381 <2> JC $MIF16 382 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message 383 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 384 <2> ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header 385 <2> ADD DX,WORD PTR [$M_RT + $M_TEMP_BUF + SI + 2] ;;AN003;; Add offset from msg structure 386 <2> INT 21H ;;AN003;; LSEEK the file 387 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 388 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message 389 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 390 <2> INT 21H ;;AN003;; Read it 391 <2> MOV DI,DX ;;AN003;; into the temp buffer 392 <2> PUSH DS ;;AN003;; into the temp buffer 393 <2> POP ES ;;AN003;; into the temp buffer 394 <2> ; $ENDIF ;;AN003;; 395 <2> $MIF16: 396 <2> ; $ENDIF ;;AN003;; 397 <2> $MIF2: 398 <2> PUSHF ;;AN003;; Close file handle 399 <2> MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle 400 <2> INT 21H ;;AN003;; 401 <2> $M_POPF ;;AN003;; 402 <2> ; $ENDIF ;;AN003;; Yes there was an error, 403 <2> $MIF1: 404 <2> POP DS ;;AN003;; 405 <2> POP BP ;;AN003;; 406 <2> POP SI ;;AN003;; 407 <2> POP DX ;;AN003;; 408 <2> POP BX ;;AN003;; 409 <2> POP AX ;;AN003;; 410 <2> ;;AN003;; abort everything 411 <2> RET ;;AN003;; 412 <2> 413 <2> READ_DISK_PROC ENDP ;;AN003;; 414 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 415 <2> %ENDIF ;;AN003;; END of include for DISK_PROC 416 <2> ; 417 <2> 418 <2> %IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO 419 <2> %iassign SETSTDIO FALSE ;;AN000;; Yes, THEN include it and reset flag 420 <2> ; PAGE 421 <2> ; SUBTTL DOS - Message Retriever - SETSTDIO Module 422 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 423 <2> ;; 424 <2> ;; PROC NAME: SETSTDIO 425 <2> ;; 426 <2> ;; FUNCTION: 427 <2> ;; INPUTS: 428 <2> ;; 429 <2> ;; OUPUTS: 430 <2> ;; 431 <2> ;; 432 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 433 <2> ;; 434 <2> %IF FARmsg ;AN001; 435 <2> SETSTDINON PROC FAR ;AN001; 436 <2> %ELSE ;AN001; 437 <2> SETSTDINON PROC NEAR ;AN001; 438 <2> %ENDIF ;AN001; 439 <2> PUSH AX ;AN002; Save changed regs 440 <2> PUSH BX ;AN002; 441 <2> PUSH DX ;AN002; 442 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 443 <2> MOV BX,STDIN ;AN001; 444 <2> XOR DX,DX ;AN001; 445 <2> INT 21H ;AN001; 446 <2> 447 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 448 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 449 <2> INT 21H ;AN001; 450 <2> POP DX ;AN002; Restore Regs 451 <2> POP BX ;AN002; 452 <2> POP AX ;AN002; 453 <2> 454 <2> RET ;AN001; 455 <2> ;AN001; 456 <2> SETSTDINON ENDP ;AN001; 457 <2> 458 <2> %IF FARmsg ;AN001; 459 <2> SETSTDINOFF PROC FAR ;AN001; 460 <2> %ELSE ;AN001; 461 <2> SETSTDINOFF PROC NEAR ;AN001; 462 <2> %ENDIF ;AN001; 463 <2> 464 <2> PUSH AX ;AN002; Save changed regs 465 <2> PUSH BX ;AN002; 466 <2> PUSH DX ;AN002; 467 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 468 <2> MOV BX,STDIN ;AN001; 469 <2> XOR DX,DX ;AN001; 470 <2> INT 21H ;AN001; 471 <2> 472 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 473 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 474 <2> INT 21H ;AN001; 475 <2> POP DX ;AN002; Restore Regs 476 <2> POP BX ;AN002; 477 <2> POP AX ;AN002; 478 <2> 479 <2> RET ;AN001; 480 <2> 481 <2> SETSTDINOFF ENDP ;AN001; 482 <2> 483 <2> %IF FARmsg ;AN001; 484 <2> SETSTDOUTON PROC FAR ;AN001; 485 <2> %ELSE ;AN001; 486 <2> SETSTDOUTON PROC NEAR ;AN001; 487 <2> %ENDIF ;AN001; 488 <2> 489 <2> PUSH AX ;AN002; Save changed regs 490 <2> PUSH BX ;AN002; 491 <2> PUSH DX ;AN002; 492 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 493 <2> MOV BX,STDOUT ;AN001; 494 <2> XOR DX,DX ;AN001; 495 <2> INT 21H ;AN001; 496 <2> 497 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 498 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 499 <2> INT 21H ;AN001; 500 <2> POP DX ;AN002; Restore Regs 501 <2> POP BX ;AN002; 502 <2> POP AX ;AN002; 503 <2> 504 <2> RET ;AN001; 505 <2> 506 <2> SETSTDOUTON ENDP ;AN001; 507 <2> 508 <2> %IF FARmsg ;AN001; 509 <2> SETSTDOUTOFF PROC FAR ;AN001; 510 <2> %ELSE ;AN001; 511 <2> SETSTDOUTOFF PROC NEAR 512 <2> %ENDIF ;AN001; 513 <2> 514 <2> PUSH AX ;AN002; Save changed regs 515 <2> PUSH BX ;AN002; 516 <2> PUSH DX ;AN002; 517 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 518 <2> MOV BX,STDOUT ;AN001; 519 <2> XOR DX,DX ;AN001; 520 <2> INT 21H ;AN001; 521 <2> 522 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 523 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 524 <2> INT 21H ;AN001; 525 <2> POP DX ;AN002; Restore Regs 526 <2> POP BX ;AN002; 527 <2> POP AX ;AN002; 528 <2> 529 <2> RET ;AN001; 530 <2> 531 <2> SETSTDOUTOFF ENDP ;AN001; 532 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 533 <2> %ENDIF ;;AN000;; END of include for SETSTDIO 534 <2> ; 535 <2> %IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? 536 <2> %IF COMR ;;AN000;; 537 <2> $M_RT EQU $M_RT2 ;;AN000;; 538 <2> %ENDIF 539 <2> %iassign LOADmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 540 <2> ; PAGE 541 <2> ; SUBTTL DOS - Message Retriever - LOADMSG.ASM Module 542 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 543 <2> ;; 544 <2> ;; PROC NAME: SYSLOADMSG 545 <2> ;; 546 <2> ;; FUNCTION: 547 <2> ;; INPUTS: 548 <2> ;; 549 <2> ;; OUPUTS: 550 <2> ;; 551 <2> ;; 552 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 553 <2> ;; 554 <2> %IF FARmsg ;;AN000;; 555 <2> SYSLOADMSG PROC FAR ;;AN000;; 556 <2> %ELSE ;;AN000;; 557 <2> SYSLOADMSG PROC NEAR ;;AN000;; 558 <2> %ENDIF ;;AN000;; 559 <2> PUSH AX ;;AN000; 560 <2> PUSH BX ;;AN000; 561 <2> PUSH DX ;;AN000; 562 <2> PUSH ES ;;AN000; 563 <2> PUSH DI ;;AN000; 564 <2> XOR CX,CX ;;AN000; Reset to zero 565 <2> MOV ES,CX ;;AN000; 566 <2> XOR DI,DI ;;AN000; 567 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 568 <2> MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM 569 <2> INT 2FH ;;AN000;; Private interface 570 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 571 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND],DI ;;AN000;; 572 <2> ;; 573 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 574 <2> MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM 575 <2> INT 2FH ;;AN000;; Private interface 576 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 577 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND],DI ;;AN000;; 578 <2> ;; 579 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 580 <2> MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM 581 <2> INT 2FH ;;AN000;; Private interface 582 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 583 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND],DI ;;AN000;; 584 <2> 585 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 586 <2> MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE 587 <2> INT 2FH ;;AN001;; Private interface 588 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE+2],ES ;;AN001;; Move into first avaliable table location 589 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE],DI ;;AN001;; 590 <2> 591 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 592 <2> Extrn READ_DISK_PROC:Far ;;AN003;; 593 <2> %ELSE ;; 594 <2> %IF FARmsg ;;AN000;; 595 <2> CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 596 <2> %ELSE ;;AN000;; 597 <2> CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 598 <2> %ENDIF ;;AN000;; 599 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 600 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS],DI ;;AN000;; 601 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 602 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS],DI ;;AN000;; 603 <2> ;; 604 <2> %IF FARmsg ;;AN000;; 605 <2> CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 606 <2> %ELSE ;;AN000;; 607 <2> CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 608 <2> %ENDIF ;;AN000;; 609 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 610 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS],DI ;;AN000;; 611 <2> %ENDIF ;; 612 <2> ;; 613 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 614 <2> MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM 615 <2> INT 2FH ;;AN001;; Private interface 616 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR+2],ES ;;AN001;; Move into first avaliable table location 617 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR],DI ;;AN001;; 618 <2> 619 <2> $M_BUILD_PTRS $M_NUM_CLS ;;AN000;; Build all utility classes 620 <2> ;;AN000;; 621 <2> CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector 622 <2> 623 <2> %IFN NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed 624 <2> CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK 625 <2> %ENDIF ;;AN000;; 626 <2> ;;AN000;; 627 <2> %IFN NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed 628 <2> CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK 629 <2> %ENDIF ;;AN000;; 630 <2> ;;AN000;; 631 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 632 <2> CLC ;;AN000;; Make sure carry is clear 633 <2> %ELSE ;;AN000;; ELSE 634 <2> PUSH CX ;;AN000;; 635 <2> CALL $M_VERSION_CHECK ;;AN000;; Check Version 636 <2> %ENDIF ;;AN000;; 637 <2> ;; Error ? 638 <2> ; $IF NC ;;AN000;; No. 639 <2> JC $MIF20 640 <2> %IFN NOVERCHECKmsg ;;AN000;; IF version check was not supressed 641 <2> POP CX ;;AN000;; Reset stack 642 <2> %ENDIF ;;AN000;; 643 <2> POP DI ;;AN000;; Restore REGS 644 <2> POP ES ;;AN000;; 645 <2> POP DX ;;AN000;; 646 <2> POP BX ;;AN000;; 647 <2> POP AX ;;AN000;; 648 <2> ; $ELSE ;;AN000;; Yes, 649 <2> JMP SHORT $MEN20 650 <2> $MIF20: 651 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 652 <2> ADD SP,10 ;;AN000;; 653 <2> STC ;;AN000;; Reset carry flag 654 <2> %ELSE ;;AN000;; IF version check is to be supressed 655 <2> ADD SP,12 ;;AN000;; 656 <2> STC ;;AN000;; Reset carry flag 657 <2> %ENDIF ;;AN000;; IF version check is to be supressed 658 <2> ; $ENDIF ;;AN000;; 659 <2> $MEN20: 660 <2> RET ;;AN000;; 661 <2> ;; 662 <2> SYSLOADMSG ENDP ;;AN000;; 663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 664 <2> ; PAGE 665 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 666 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 667 <2> ;; 668 <2> ;; Proc Name: $M_GET_DBCS_VEC 669 <2> ;; 670 <2> ;; Function: Get the DBCS vector and save it for later use 671 <2> ;; 672 <2> ;; Inputs: None 673 <2> ;; 674 <2> ;; Outputs: None 675 <2> ;; 676 <2> ;; Regs Changed: 677 <2> ;; 678 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 679 <2> ;; 680 <2> $M_GET_DBCS_VEC PROC NEAR ;;AN000;; 681 <2> ;; 682 <2> PUSH AX ;;AN000;; Save character to check 683 <2> PUSH SI ;;AN000;; 684 <2> PUSH DS ;;AN000;; 685 <2> MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment 686 <2> INT 21H ;;AN000;; Get environment pointer 687 <2> PUSH DS ;;AN000;; Get environment pointer 688 <2> POP ES ;;AN000;; Get environment pointer 689 <2> POP DS ;;AN000;; Get environment pointer 690 <2> ; $IF NC ;;AN000;; 691 <2> JC $MIF23 692 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC],SI ;;AN000;; Save DBCS Vector 693 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC+2],ES ;;AN000;; 694 <2> ; $ENDIF ;;AN000;; 695 <2> $MIF23: 696 <2> POP SI ;;AN000;; 697 <2> POP AX ;;AN000;; Retrieve character to check 698 <2> RET ;;AN000;; Return 699 <2> ;; 700 <2> $M_GET_DBCS_VEC ENDP ;; 701 <2> ;; 702 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 703 <2> %IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? 704 <2> %ELSE ;AN001; Yes, THEN include it 705 <2> ; PAGE 706 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc 707 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 708 <2> ;; 709 <2> ;; Proc Name: $M_CHECKSTDIN 710 <2> ;; 711 <2> ;; Function: 712 <2> ;; 713 <2> ;; Inputs: None 714 <2> ;; 715 <2> ;; Outputs: 716 <2> ;; 717 <2> ;; Regs Changed: 718 <2> ;; 719 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 720 <2> ;; 721 <2> $M_CHECKSTDIN PROC NEAR ;AN001; 722 <2> 723 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 724 <2> MOV BX,STDIN ;AN001; 725 <2> XOR DX,DX ;AN001; 726 <2> INT 21H ;AN001; 727 <2> 728 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 729 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 730 <2> INT 21H ;AN001; 731 <2> 732 <2> RET ;AN001; 733 <2> 734 <2> $M_CHECKSTDIN ENDP ;AN001; 735 <2> ;; 736 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 737 <2> %ENDIF ;AN001; END of include for EOF Check 738 <2> %IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? 739 <2> %ELSE ;AN001; Yes, THEN include it 740 <2> ; PAGE 741 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc 742 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 743 <2> ;; 744 <2> ;; Proc Name: $M_CHECKSTDOUT 745 <2> ;; 746 <2> ;; Function: 747 <2> ;; 748 <2> ;; Inputs: None 749 <2> ;; 750 <2> ;; Outputs: 751 <2> ;; 752 <2> ;; Regs Changed: 753 <2> ;; 754 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 755 <2> ;; 756 <2> $M_CHECKSTDOUT PROC NEAR ;AN001; 757 <2> 758 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 759 <2> MOV BX,STDOUT ;AN001; 760 <2> XOR DX,DX ;AN001; 761 <2> INT 21H ;AN001; 762 <2> 763 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 764 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 765 <2> INT 21H ;AN001; 766 <2> 767 <2> RET ;AN001; 768 <2> 769 <2> $M_CHECKSTDOUT ENDP ;AN001; 770 <2> ;; 771 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 772 <2> %ENDIF ;AN001; END of include for Disk Full Check 773 <2> %IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? 774 <2> %ELSE ;;AN000;; Yes, THEN include it 775 <2> ; PAGE 776 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 778 <2> ;; 779 <2> ;; Proc Name: $M_VERSION_CHECK 780 <2> ;; 781 <2> ;; Function: Determine if DOS version is within allowable limits 782 <2> ;; 783 <2> ;; Inputs: None 784 <2> ;; 785 <2> ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version 786 <2> ;; Registers set for SYSDISPMSG 787 <2> ;; CARRY_FLAG = 0 if Correct DOS version 788 <2> ;; 789 <2> ;; Regs Changed: AX 790 <2> ;; 791 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 792 <2> 793 <2> check_amis: 794 <2> push ax 795 <2> push ds 796 <2> push si 797 <2> push es 798 <2> push di 799 <2> push dx 800 <2> push ax ; version number, last on stack 801 <2> 802 <2> mov ah, 0 ; multiplex number = 0 803 <2> .loop: 804 <2> mov al, 0 805 <2> int 2Dh ; installation check 806 <2> cmp al, -1 ; multiplexer installed ? 807 <2> jne .next ; no --> 808 <2> push cs 809 <2> pop ds 810 <2> mov si, offset amis_sign ; ds:si -> amis_sign (for lDOS) 811 <2> mov es, dx ; es:di -> multiplexer's sign 812 <2> mov cx, 8 ; 16 bytes 813 <2> repe cmpsw ; compare 814 <2> jne .next ; not us --> 815 <2> mov dx, cs ; dx:si -> amis_id 816 <2> mov al, 11h 817 <2> int 2Dh ; CHG: al, bx, cx, dx, si, di 818 <2> cmp al, 0 ; id call supported ? 819 <2> je .unsup ; no, allow if alt version --> 820 <2> pop dx 821 <2> xor dx, dx ; 2D.MM11 supported, mark that we need it 822 <2> push dx 823 <2> cmp al, 0F0h ; CY if below 0F0h 824 <2> jmp .done 825 <2> 826 <2> .next: 827 <2> inc ah ; next multiplex number 828 <2> jnz .loop ; ZR if done, NZ if more to check --> 829 <2> .unsup: 830 <2> stc ; multiplexer not found 831 <2> ; or function not supported 832 <2> .done: 833 <2> ; CY if not an lDOS revision with our id supported, 834 <2> ; on stack: alt_expected_version if it's fine and either 835 <2> ; no multiplexer or func 11h not supported 836 <2> ; new_expected_version if not fine and either 837 <2> ; no multiplexer or func 11h not suppprted, 838 <2> ; 0 if multiplexer found, func 11h supported, but 839 <2> ; our id is unsupported 840 <2> ; NC if lDOS revision with multiplexer and our id supported 841 <2> pop bx 842 <2> pop dx 843 <2> pop di 844 <2> pop es 845 <2> pop si 846 <2> pop ds 847 <2> pop ax 848 <2> jnc alt_good_DOS ; id is supported --> 849 <2> cmp bx, alt_expected_version ; is it fine ? 850 <2> je alt_good_DOS ; yes --> (NC) 851 <2> jmp $MIF25 ; no, cancel program --> 852 <2> 853 <2> $M_VERSION_CHECK PROC NEAR ;;AN000;; 854 <2> ;; 855 <2> MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC 856 <2> INT 21H ;;AN000;; 857 <2> ;; 858 <2> cmp ax,new_expected_version ; compare with DOS version 859 <2> je check_amis 860 <2> cmp ax,alt_expected_version ; compare with DOS version 861 <2> je check_amis 862 <2> CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct 863 <2> ; $IF E ;;AN000;; 864 <2> JNE $MIF25 865 <2> alt_good_DOS: 866 <2> CLC ;;AN000;; Clear the carry flag 867 <2> ; $ELSE ;;AN000;; ELSE 868 <2> JMP SHORT $MEN25 869 <2> $MIF25: 870 <2> %IFN COMR ;; ** Special case for RESIDENT COMMAND.COM 871 <2> CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH 872 <2> ; $IF B ;;AN000;; No, 873 <2> JNB $MIF27 874 <2> MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) 875 <2> ; $ELSE ;;AN000;; Yes, 876 <2> JMP SHORT $MEN27 877 <2> $MIF27: 878 <2> MOV BX,STDERR ;;AN000;; Standard Error 879 <2> ; $ENDIF ;;AN000;; 880 <2> $MEN27: 881 <2> %ELSE 882 <2> MOV BX,NO_HANDLE ;;AN000;; No handle 883 <2> %ENDIF 884 <2> MOV AX,1 ;;AN000;; Set message # 1 885 <2> MOV CX,NO_REPLACE ;;AN000;; No replacable parms 886 <2> MOV DL,NO_INPUT ;;AN000;; No input 887 <2> MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message 888 <2> STC ;;AN000;; Set Carry Flag 889 <2> ; $ENDIF ;;AN000;; 890 <2> $MEN25: 891 <2> ;; 892 <2> RET ;;AN000;; Return 893 <2> ;; 894 <2> $M_VERSION_CHECK ENDP ;; 895 <2> ;; 896 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 897 <2> %ENDIF ;;AN000;; END of include for DOS version check 898 <2> %ENDIF ;;AN000;; END of include for SYSLOADMSG 899 <2> ; 900 <2> %IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 901 <2> %IF COMR ;;AN000;; 902 <2> $M_RT EQU $M_RT2 ;;AN000;; 903 <2> %ENDIF ;;AN000;; 904 <2> GETmsg equ FALSE ;;AN000;; Yes, THEN include it and reset flag 905 <2> ; PAGE 906 <2> ; SUBTTL DOS - Message Retriever - GETMSG.ASM Module 907 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 <2> ;; 909 <2> ;; Proc Name: SYSGETMSG 910 <2> ;; 911 <2> ;; Function: The GET service returns the segment, offset and size of the 912 <2> ;; message text to the caller based on a message number. 913 <2> ;; The GET function will not display the message thus assumes 914 <2> ;; caller will handle replaceable parameters. 915 <2> ;; 916 <2> ;; Inputs: 917 <2> ;; 918 <2> ;; Outputs: 919 <2> ;; 920 <2> ;; Psuedocode: 921 <2> ;; Call $M_GET_MSG_ADDRESS 922 <2> ;; IF MSG_NUM exists THEN 923 <2> ;; Set DS:SI = MSG_TXT_PTR + 1 924 <2> ;; CARRY_FLAG = 0 925 <2> ;; ELSE 926 <2> ;; CARRY_FLAG = 1 927 <2> ;; ENDIF 928 <2> ;; 929 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 <2> ;; 931 <2> %IF FARmsg ;;AN000;; 932 <2> SYSGETMSG PROC FAR ;;AN000;; 933 <2> %ELSE ;;AN000;; 934 <2> SYSGETMSG PROC NEAR ;;AN000;; 935 <2> %ENDIF ;;AN000;; 936 <2> ;; 937 <2> ;; Save registers needed later 938 <2> 939 <2> PUSH AX ;;AN000;; Save changed regs 940 <2> PUSH ES ;;AN000;; 941 <2> PUSH DI ;;AN000;; 942 <2> PUSH BP ;;AN000;; 943 <2> ;; 944 <2> %IF FARmsg ;;AN000;; 945 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 946 <2> %ELSE ;;AN000;; 947 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 948 <2> %ENDIF ;;AN000;; Return message in ES:DI 949 <2> ; $IF NC ;;AN000;; Message found? 950 <2> JC $MIF31 951 <2> CMP DH,UTILITY_MSG_CLASS 952 <2> CLC ;;AN000;; 953 <2> ; $IF NE 954 <2> JE $MIF32 955 <2> PUSH ES ;;AN000;; 956 <2> POP DS ;;AN000;; Return message in DS:SI 957 <2> ; $ELSE 958 <2> JMP SHORT $MEN32 959 <2> $MIF32: 960 <2> %IF FARmsg ;;AN000;; Yes, 961 <2> PUSH ES ;;AN000;; 962 <2> POP DS ;;AN000;; Return message in DS:SI 963 <2> %ELSE ;;AN000;; 964 <2> PUSH CS ;;AN000;; Return message in DS:SI 965 <2> POP DS ;;AN000;; 966 <2> %ENDIF ;;AN000;; 967 <2> ; $ENDIF ;;AN000;; 968 <2> $MEN32: 969 <2> MOV SI,DI ;;AN000;; Return message in DS:SI 970 <2> ; $ENDIF ;;AN000;; 971 <2> $MIF31: 972 <2> ;; 973 <2> POP BP ;;AN000;; Restore changed regs 974 <2> POP DI ;;AN000;; 975 <2> POP ES ;;AN000;; 976 <2> POP AX ;;AN000;; 977 <2> ;; 978 <2> RET ;;AN000;; Return 979 <2> ;; 980 <2> SYSGETMSG ENDP ;; 981 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 982 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 983 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 984 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 985 <2> ;; 986 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 987 <2> ;; 988 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 989 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 990 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 991 <2> ;; IF CX > 1 THEN ES:DI points to the specified message 992 <2> ;; REGS CHANGED: ES,DI,CX 993 <2> ;; 994 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 995 <2> ;; 996 <2> %IF FARmsg ;;AN000;; 997 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 998 <2> %ELSE ;;AN000;; 999 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 1000 <2> %ENDIF ;;AN000;; 1001 <2> ;; 1002 <2> PUSH SI ;;AN000;; 1003 <2> PUSH BX ;;AN000;; 1004 <2> XOR SI,SI ;;AN000;; Use SI as an index 1005 <2> XOR CX,CX ;;AN000;; Use CX as an size 1006 <2> ; $DO ;;AN000;; 1007 <2> $MDO36: 1008 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 1009 <2> ; $IF E ;;AN000;; Yes, 1010 <2> JNE $MIF37 1011 <2> %IF FARmsg ;;AN000;; 1012 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1013 <2> MOV BX,ES ;;AN000; 1014 <2> %ELSE ;;AN000;; 1015 <2> MOV DI,WORD PTR [$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1016 <2> MOV BX,DI ;;AN000; 1017 <2> %ENDIF ;;AN000;; 1018 <2> ; $ELSE ;;AN000;; No, 1019 <2> JMP SHORT $MEN37 1020 <2> $MIF37: 1021 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 1022 <2> ; $IF NE ;;AN000;; Yes, 1023 <2> JE $MIF39 1024 <2> LES DI,[$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 1025 <2> MOV BX,ES ;;AN000; 1026 <2> ; $ELSE ;;AN000;; No, extended errors were specified 1027 <2> JMP SHORT $MEN39 1028 <2> $MIF39: 1029 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 1030 <2> ; $IF AE,AND ;;AN000;; 1031 <2> JNAE $MIF41 1032 <2> CMP AX,$M_CRIT_HI ;;AN000;; 1033 <2> ; $IF BE ;;AN000;; Yes, 1034 <2> JNBE $MIF41 1035 <2> LES DI,[$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 1036 <2> MOV BX,ES ;;AN000; 1037 <2> ; $ELSE ;;AN000;; 1038 <2> JMP SHORT $MEN41 1039 <2> $MIF41: 1040 <2> LES DI,[$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 1041 <2> MOV BX,ES ;;AN000; 1042 <2> ; $ENDIF ;;AN000;; 1043 <2> $MEN41: 1044 <2> ; $ENDIF ;;AN000;; 1045 <2> $MEN39: 1046 <2> ; $ENDIF ;;AN000;; 1047 <2> $MEN37: 1048 <2> ;; 1049 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 1050 <2> ; $IF E ;;AN000;; Yes, 1051 <2> JNE $MIF46 1052 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 1053 <2> ; $IF E ;;AN000;; Yes, 1054 <2> JNE $MIF47 1055 <2> STC ;;AN000;; Set the carry flag 1056 <2> ; $ELSE ;;AN000;; No, 1057 <2> JMP SHORT $MEN47 1058 <2> $MIF47: 1059 <2> MOV [$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 1060 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 1061 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 1062 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 1063 <2> CLC ;;AN000;; 1064 <2> ; $ENDIF ;;AN000;; No, 1065 <2> $MEN47: 1066 <2> ; $ELSE ;;AN000;; 1067 <2> JMP SHORT $MEN46 1068 <2> $MIF46: 1069 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 1070 <2> ; $IF NE ;;AN001;; Yes, 1071 <2> JE $MIF51 1072 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 1073 <2> ; $ENDIF ;;AN000;; 1074 <2> $MIF51: 1075 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 1076 <2> CLC ;;AN000;; 1077 <2> ; $ENDIF ;;AN000;; 1078 <2> $MEN46: 1079 <2> ; $LEAVE C ;;AN000;; 1080 <2> JC $MEN36 1081 <2> OR CX,CX ;;AN000;; Was the message found? 1082 <2> ; $ENDDO NZ,LONG ;;AN000;; 1083 <2> JNZ $MXL2 1084 <2> JMP $MDO36 1085 <2> $MXL2: 1086 <2> $MEN36: 1087 <2> 1088 <2> PUSHF ;;AN006;; Save the flag state 1089 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 1090 <2> ; $IF E ;;AN006;; Yes, 1091 <2> JNE $MIF56 1092 <2> PUSH DX ;;AN006;; Save all needed registers 1093 <2> PUSH BP ;;AN006;; 1094 <2> PUSH CX ;;AN006;; 1095 <2> PUSH ES ;;AN006;; 1096 <2> PUSH DI ;;AN006;; 1097 <2> PUSH AX ;;AN006;; 1098 <2> 1099 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 1100 <2> INT 2FH ;;AN006;; 1101 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 1102 <2> POP AX ;;AN006;; Restore msg number 1103 <2> ; $IF E ;;AN006;; Yes, 1104 <2> JNE $MIF57 1105 <2> MOV BX,AX ;;AN006;; BX is the extended error number 1106 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 1107 <2> INT 2FH ;;AN006;; Call IFSFUNC 1108 <2> ; $ELSE ;;AN006;; No, 1109 <2> JMP SHORT $MEN57 1110 <2> $MIF57: 1111 <2> STC ;;AN006;; Carry conditon 1112 <2> ; $ENDIF ;;AN006;; 1113 <2> $MEN57: 1114 <2> 1115 <2> ; $IF C ;;AN006;; Was there an update? 1116 <2> JNC $MIF60 1117 <2> POP DI ;;AN006;; No, 1118 <2> POP ES ;;AN006;; Restore old pointer 1119 <2> POP CX ;;AN006;; 1120 <2> ; $ELSE ;;AN006;; Yes 1121 <2> JMP SHORT $MEN60 1122 <2> $MIF60: 1123 <2> ADD SP,6 ;;AN006;; Throw away old pointer 1124 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 1125 <2> ; $ENDIF ;;AN006;; 1126 <2> $MEN60: 1127 <2> POP BP ;;AN006;; Restore other Regs 1128 <2> POP DX ;;AN006;; 1129 <2> ; $ENDIF ;;AN006;; 1130 <2> $MIF56: 1131 <2> $M_POPF ;;AN006;; Restore the flag state 1132 <2> 1133 <2> POP BX ;;AN000;; 1134 <2> POP SI ;;AN000;; 1135 <2> RET ;;AN000;; Return ES:DI pointing to the message 1136 <2> ;; 1137 <2> $M_GET_MSG_ADDRESS ENDP ;; 1138 <2> ;; 1139 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 1140 <2> ;; 1141 <2> PUSH DI ;;AN006;; Save position 1142 <2> PUSH AX ;;AN006;; 1143 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 1144 <2> XOR AL,AL ;;AN006;; Prepare compare register 1145 <2> REPNE SCASB ;;AN006;; Scan for zero 1146 <2> NOT CX ;;AN006;; Change decrement into number 1147 <2> DEC CX ;;AN006;; Don't include the zero 1148 <2> POP AX ;;AN006;; 1149 <2> POP DI ;;AN006;; Restore position 1150 <2> RET ;;AN006;; 1151 <2> ;; 1152 <2> $M_SET_LEN_IN_CX ENDP ;; 1153 <2> ;; 1154 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1155 <2> ;; 1156 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 1157 <2> ;; 1158 <2> ;; FUNCTION: To scan thru message headers until message is found 1159 <2> ;; INPUTS: ES:DI points to beginning of msg headers 1160 <2> ;; CX contains the number of messages in class 1161 <2> ;; DH contains the message class 1162 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 1163 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 1164 <2> ;; 1165 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1166 <2> ;; 1167 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 1168 <2> ;; 1169 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 1170 <2> ; $IF E,AND ;;AN004;; Yes, 1171 <2> JNE $MIF64 1172 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 1173 <2> ; $IF NE ;;AN004;; Yes, 1174 <2> JE $MIF64 1175 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 1176 <2> ; $IF E ;;AN004;; . . . and . . . 1177 <2> JNE $MIF65 1178 <2> PUSH AX ;;AN004;; Reset the special message number 1179 <2> MOV AX,[$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 1180 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1181 <2> POP AX ;;AN004;; Reset the special message number 1182 <2> ; $ELSE ;;AN004;; Get the old message number 1183 <2> JMP SHORT $MEN65 1184 <2> $MIF65: 1185 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1186 <2> ; $ENDIF ;;AN004;; Get the old message number 1187 <2> $MEN65: 1188 <2> ; $ELSE ;;AN004;; 1189 <2> JMP SHORT $MEN64 1190 <2> $MIF64: 1191 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 1192 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1193 <2> ; $IF NE ;;AN001;; 1194 <2> JE $MIF69 1195 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 1196 <2> ; $ELSE ;;AN001;; 1197 <2> JMP SHORT $MEN69 1198 <2> $MIF69: 1199 <2> %IF FARmsg ;;AN001;; 1200 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1201 <2> %ELSE 1202 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1203 <2> %ENDIF 1204 <2> ; $IF E ;;AN002;; pointer (hopefully) 1205 <2> JNE $MIF71 1206 <2> %IF FARmsg ;;AN001;; 1207 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1208 <2> %ELSE 1209 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1210 <2> %ENDIF 1211 <2> ; $ENDIF ;;AN002;; go on to the next class 1212 <2> $MIF71: 1213 <2> ; $ENDIF ;;AN001;; 1214 <2> $MEN69: 1215 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 1216 <2> STC ;;AN004;; Flag that we haven't found anything yet 1217 <2> ; $ENDIF ;;AN004;; 1218 <2> $MEN64: 1219 <2> 1220 <2> ; $IF C ;;AN004;; Have we found anything yet? 1221 <2> JNC $MIF75 1222 <2> CLC ;;AN004;; No, reset carry 1223 <2> ; $SEARCH ;;AN000;; 1224 <2> $MDO76: 1225 <2> OR CX,CX ;;AN000;; Do we have any to check? 1226 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1227 <2> JZ $MEN76 1228 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1229 <2> ; $IF NE ;;AN001;; 1230 <2> JE $MIF78 1231 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 1232 <2> ; $ELSE ;;AN001;; 1233 <2> JMP SHORT $MEN78 1234 <2> $MIF78: 1235 <2> %IF FARmsg ;;AN001;; 1236 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 1237 <2> %ELSE 1238 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 1239 <2> %ENDIF 1240 <2> ; $ENDIF 1241 <2> $MEN78: 1242 <2> ; $EXITIF E ;;AN000;; 1243 <2> JNE $MIF76 1244 <2> ; $ORELSE ;;AN000; 1245 <2> JMP SHORT $MSR76 1246 <2> $MIF76: 1247 <2> DEC CX ;;AN000;; No, well do we have more to check? 1248 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1249 <2> JZ $MEN76 1250 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 1251 <2> ; $ENDLOOP ;;AN000;; 1252 <2> JMP SHORT $MDO76 1253 <2> $MEN76: 1254 <2> STC ;;AN000;; 1255 <2> ; $ENDSRCH ;;AN000;; Check next message 1256 <2> $MSR76: 1257 <2> ; $IF NC ;;AN000;; Did we find the message? 1258 <2> JC $MIF86 1259 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 1260 <2> CLC ;;AN001;; 1261 <2> ; $IF E ;;AN001;; 1262 <2> JNE $MIF87 1263 <2> %IF FARmsg ;;AN001;; 1264 <2> %ELSE ;;AN000;; 1265 <2> PUSH CS ;;AN000;; 1266 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 1267 <2> %ENDIF 1268 <2> ; $ENDIF ;;AN001;; 1269 <2> $MIF87: 1270 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 1271 <2> ; $ENDIF ;;AN004;; 1272 <2> $MIF86: 1273 <2> ; $ENDIF ;;AN004;; 1274 <2> $MIF75: 1275 <2> ;; Yes, great we can return with CX > 0 1276 <2> 1277 <2> ; $IF NC ;;AN000;; Did we find the message? 1278 <2> JC $MIF91 1279 <2> XOR CH,CH ;;AN000;; 1280 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 1281 <2> INC DI ;;AN000;; Increment past length 1282 <2> ; $ENDIF ;;AN004;; 1283 <2> $MIF91: 1284 <2> 1285 <2> MOV byte [$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 1286 <2> RET ;;AN000;; Return 1287 <2> ;; 1288 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 1289 <2> ;; 1290 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1291 <2> %ENDIF ;;AN000;; END of include of common subroutines 1292 <2> %ENDIF ;;AN000;; END of include of SYSGETMSG 1293 <2> ; 1294 <2> %IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 1295 <2> %IF COMR ;;AN000;; 1296 <2> $M_RT EQU $M_RT2 ;;AN000;; 1297 <2> %ENDIF ;;AN000;; 1298 <2> %iassign DISPLAYmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 1299 <2> ; PAGE 1300 <2> ; SUBTTL DOS - Message Retriever - DISPMSG.ASM Module 1301 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1302 <2> ;; 1303 <2> ;; Proc Name: SYSDISPMSG 1304 <2> ;; 1305 <2> ;; Function: The DISPLAY service will output a defined message to a handle 1306 <2> ;; requested by the caller. It also provides function to display 1307 <2> ;; messages when handles are not applicable (ie. DOS function calls 1308 <2> ;; 00h to 0Ah) Replaceable parameters are allowed and are 1309 <2> ;; defined previous to entry. 1310 <2> ;; 1311 <2> ;; It is assumes that a PRELOAD function has already determined 1312 <2> ;; the addressibilty internally to the message retriever services. 1313 <2> ;; Inputs: 1314 <2> ;; 1315 <2> ;; Outputs: 1316 <2> ;; 1317 <2> ;; Psuedocode: 1318 <2> ;; Save registers needed later 1319 <2> ;; Get address of the message requested 1320 <2> ;; IF Message number exists THEN 1321 <2> ;; IF replacable parameters were specified THEN 1322 <2> ;; Display message with replacable parms 1323 <2> ;; ELSE 1324 <2> ;; Display string without replacable parms 1325 <2> ;; ENDIF 1326 <2> ;; IF character input was requested THEN 1327 <2> ;; Wait for character input 1328 <2> ;; ENDIF 1329 <2> ;; Clear CARRY FLAG 1330 <2> ;; ELSE 1331 <2> ;; Set CARRY FLAG 1332 <2> ;; ENDIF 1333 <2> ;; Return 1334 <2> ;; 1335 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1336 <2> ;; 1337 <2> %IF FARmsg ;;AN000;; 1338 <2> SYSDISPMSG PROC FAR ;;AN000;; 1339 <2> %ELSE ;;AN000;; 1340 <2> SYSDISPMSG PROC NEAR ;;AN000;; 1341 <2> %ENDIF ;;AN000;; 1342 <2> ;; 1343 <2> ;; Save registers and values needed later 1344 <2> 1345 <2> PUSH AX ;;AN000;; Save changed REGs 1346 <2> PUSH BX ;;AN000;; 1347 <2> PUSH CX ;;AN000;; 1348 <2> PUSH BP ;;AN000;; 1349 <2> PUSH DI ;;AN000;; Save pointer to input buffer (offset) 1350 <2> PUSH ES ;;AN000;; Save pointer to input buffer (segment) 1351 <2> PUSH DX ;;AN000;; Save Input/Class request 1352 <2> 1353 <2> MOV BP,CX ;;AN000;; Use BP to hold replace count 1354 <2> MOV WORD PTR [cs:$M_RT + $M_HANDLE],BX ;;AN000;; Save handle 1355 <2> MOV BYTE PTR [cs:$M_RT + $M_CLASS],DH ;;AN004;; Save class 1356 <2> 1357 <2> ;; Get address of the message requested 1358 <2> 1359 <2> %IF FARmsg ;;AN000;; 1360 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1361 <2> %ELSE ;;AN000;; 1362 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1363 <2> %ENDIF ;;AN000;; 1364 <2> OR CX,CX ;;AN000;; Was message found? 1365 <2> ; $IF NZ ;;AN000;; YES, Message address in ES:DI 1366 <2> JZ $MIF93 1367 <2> 1368 <2> ;; Test if replacable parameters were specified 1369 <2> 1370 <2> OR BP,BP ;;AN000;; Were replacable parameters requested 1371 <2> ; $IF Z ;;AN000;; 1372 <2> JNZ $MIF94 1373 <2> 1374 <2> ;; Display string without replacable parms 1375 <2> 1376 <2> CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message 1377 <2> ; $ELSE ;;AN000;; 1378 <2> JMP SHORT $MEN94 1379 <2> $MIF94: 1380 <2> %IF $M_REPLACE ;;AN000;; 1381 <2> 1382 <2> ;; Display message with replacable parms 1383 <2> 1384 <2> CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions 1385 <2> %ENDIF ;;AN000;; 1386 <2> ; $ENDIF ;;AN000;; 1387 <2> $MEN94: 1388 <2> ; $IF NC 1389 <2> JC $MIF97 1390 <2> 1391 <2> POP DX ;;AN000;; Get Input/Class request 1392 <2> 1393 <2> CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. 1394 <2> 1395 <2> POP ES ;;AN000;; Get location of input buffer (if specified) 1396 <2> POP DI ;;AN000;; 1397 <2> 1398 <2> ;; Test if character input was requested 1399 <2> 1400 <2> %IF INPUTmsg ;;AN000;; 1401 <2> OR DL,DL ;;AN000;; Was Wait-For-Input requested? 1402 <2> ; $IF NZ ;;AN000;; 1403 <2> JZ $MIF98 1404 <2> CALL $M_WAIT_FOR_INPUT ;;AN000;; 1405 <2> ; $ENDIF ;;AN000;; 1406 <2> $MIF98: 1407 <2> %ENDIF ;;AN000;; 1408 <2> ; $ELSE ;;AN000;; 1409 <2> JMP SHORT $MEN97 1410 <2> $MIF97: 1411 <2> ADD SP,6 ;;AN000;; 1412 <2> STC ;;AN000;; Reset carry flag 1413 <2> ; $ENDIF ;;AN000;; 1414 <2> $MEN97: 1415 <2> ; $ELSE ;;AN000;; No, 1416 <2> JMP SHORT $MEN93 1417 <2> $MIF93: 1418 <2> POP ES ;;AN000;; Get pointer to input buffer (segment) 1419 <2> POP DI ;;AN000;; Get base pointer to first sublist (offset) 1420 <2> POP DX ;;AN000;; Get base pointer to first sublist (segment) 1421 <2> STC ;;AN000;; Set carry flag 1422 <2> ; $ENDIF ;;AN000;; 1423 <2> $MEN93: 1424 <2> ;; 1425 <2> ; $IF NC ;;AN000;; Was there an error? 1426 <2> JC $MIF104 1427 <2> POP BP ;;AN000;; No, 1428 <2> POP CX ;;AN000;; 1429 <2> POP BX ;;AN000;; 1430 <2> %IF INPUTmsg ;;AN000;; 1431 <2> ADD SP,2 ;;AN000;; 1432 <2> %ELSE ;AN000; 1433 <2> POP AX ;;AN000;; 1434 <2> %ENDIF ;;AN000;; 1435 <2> ; $ELSE ;;AN000;; Yes, 1436 <2> JMP SHORT $MEN104 1437 <2> $MIF104: 1438 <2> ADD SP,8 ;;AN000;; Eliminate from stack 1439 <2> STC ;;AN000;; 1440 <2> ; $ENDIF ;;AN000;; 1441 <2> $MEN104: 1442 <2> ;; 1443 <2> RET ;;AN000;; Return 1444 <2> ;; 1445 <2> SYSDISPMSG ENDP ;;AN000;; 1446 <2> ;; 1447 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1448 <2> ; 1449 <2> ;; 1450 <2> ;; PROC NAME: $M_DISPLAY_STRING 1451 <2> ;; 1452 <2> ;; FUNCTION: Will display or write string 1453 <2> ;; INPUTS: ES:DI points to beginning of message 1454 <2> ;; CX contains the length of string to write (if applicable) 1455 <2> ;; OUTPUTS: None 1456 <2> ;; REGS Revised: None 1457 <2> ;; 1458 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1459 <2> ;; 1460 <2> $M_DISPLAY_STRING PROC NEAR ;;AN000;; 1461 <2> ;; 1462 <2> PUSH AX ;;AN000;; 1463 <2> PUSH BX ;;AN000;; 1464 <2> PUSH DX ;;AN000;; 1465 <2> ;; 1466 <2> MOV BX,[cs:$M_RT + $M_HANDLE] ;;AN000;; Retrieve handle 1467 <2> ;; 1468 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 1469 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1470 <2> %ELSE 1471 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1472 <2> ; $IF E ;;AN000;; 1473 <2> JNE $MIF107 1474 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1475 <2> ; $ELSE ;;AN000;; 1476 <2> JMP SHORT $MEN107 1477 <2> $MIF107: 1478 <2> CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle 1479 <2> ; $ENDIF ;;AN000;; 1480 <2> $MEN107: 1481 <2> ;AN001; 1482 <2> ; $IF C ;;AN000;; Was there an error? 1483 <2> JNC $MIF110 1484 <2> MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, 1485 <2> MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error 1486 <2> INT 21H ;;AN000;; 1487 <2> XOR AH,AH ;;AN000;; Clear AH 1488 <2> ADD SP,6 ;;AN000;; Clean up stack 1489 <2> STC ;;AN000;; Flag that there was an error 1490 <2> ; $ELSE ;;AN000;; No, 1491 <2> JMP SHORT $MEN110 1492 <2> $MIF110: 1493 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1494 <2> ; $IF NE ;;AN000;; 1495 <2> JE $MIF112 1496 <2> CMP AX,CX ;AN001; Was it ALL written? 1497 <2> ; $IF NE ;AN001; No, 1498 <2> JE $MIF113 1499 <2> CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error 1500 <2> ADD SP,6 ;AN001; Clean up stack 1501 <2> STC ;AN001; Flag that there was an error 1502 <2> ; $ENDIF ;AN001; 1503 <2> $MIF113: 1504 <2> ; $ENDIF ;AN001; 1505 <2> $MIF112: 1506 <2> ; $ENDIF ;;AN000;; 1507 <2> $MEN110: 1508 <2> %ENDIF 1509 <2> ; $IF NC ;;AN000;; Was there ANY error? 1510 <2> JC $MIF117 1511 <2> POP DX ;;AN000;; Restore regs 1512 <2> POP BX ;;AN000;; 1513 <2> POP AX ;;AN000;; 1514 <2> ; $ENDIF ;;AN000;; 1515 <2> $MIF117: 1516 <2> RET ;;AN000;; Return 1517 <2> ;; 1518 <2> $M_DISPLAY_STRING ENDP ;;AN000;; 1519 <2> ;; 1520 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1521 <2> ;; 1522 <2> ;; PROC NAME: $M_DISPLAY_$_STRING 1523 <2> ;; 1524 <2> ;; FUNCTION: Will display a $ terminated string 1525 <2> ;; INPUTS: ES:DI points to beginning of message text (not the length) 1526 <2> ;; OUPUTS: None 1527 <2> ;; REGS USED: AX,DX 1528 <2> ;; 1529 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1530 <2> ;; 1531 <2> $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; 1532 <2> ;; 1533 <2> PUSH DS ;;AN000;; 1534 <2> PUSH ES ;;AN000;; 1535 <2> POP DS ;;AN000;; Set DS to segment of message text 1536 <2> %IFN COMR 1537 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1538 <2> ; $IF E ;;AN000;; Yes, 1539 <2> JNE $MIF119 1540 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1541 <2> MOV DL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1542 <2> INT 21H ;;AN000;; Write character 1543 <2> POP DS ;;AN000;; Set DS to segment of message text 1544 <2> MOV AL,DL ;;AN000;; Get the character in AL 1545 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1546 <2> PUSH DS ;;AN000;; 1547 <2> PUSH ES ;;AN000;; 1548 <2> POP DS ;;AN000;; Set DS to segment of message text 1549 <2> ; $IF C ;;AN000;; Yes, 1550 <2> JNC $MIF120 1551 <2> MOV DL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 1552 <2> INT 21H ;;AN000;; Write character 1553 <2> CLC ;;AN000;; Clear the DBCS indicator 1554 <2> ; $ENDIF ;;AN000;; 1555 <2> $MIF120: 1556 <2> ; $ELSE ;;AN000;; No, 1557 <2> JMP SHORT $MEN119 1558 <2> $MIF119: 1559 <2> %ENDIF 1560 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1561 <2> ; $DO ;;AN002;; No, 1562 <2> $MDO123: 1563 <2> OR CX,CX ;;AN002;; Are there any left to display? 1564 <2> ; $LEAVE Z ;;AN002;; Yes, 1565 <2> JZ $MEN123 1566 <2> MOV DL,BYTE PTR [ES:DI] ;;AN002;; Get the character 1567 <2> INT 21H ;;AN002;; Display the character 1568 <2> INC DI ;;AN002;; Set pointer to next character 1569 <2> DEC CX ;;AN002;; Count this character 1570 <2> ; $ENDDO Z ;;AN002;; No, 1571 <2> JNZ $MDO123 1572 <2> $MEN123: 1573 <2> %IFN COMR 1574 <2> ; $ENDIF ;;AN000;; 1575 <2> $MEN119: 1576 <2> %ENDIF 1577 <2> CLC ;;AN000;; Char functions used don't return carry as error 1578 <2> POP DS ;;AN000;; 1579 <2> RET ;;AN000;; 1580 <2> ;; 1581 <2> $M_DISPLAY_$_STRING ENDP ;;AN000;; 1582 <2> ;; 1583 <2> %IFN COMR 1584 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1585 <2> ;; 1586 <2> ;; PROC NAME: $M_DISPLAY_H_STRING 1587 <2> ;; 1588 <2> ;; FUNCTION: Will display a string to a specified handle 1589 <2> ;; INPUTS: ES:DI points to beginning of message 1590 <2> ;; CX contains the number of bytes to write 1591 <2> ;; BX contains the handle to write to 1592 <2> ;; OUPUTS: None 1593 <2> ;; REGS USED: AX,DX 1594 <2> ;; 1595 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1596 <2> ;; 1597 <2> $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; 1598 <2> ;; 1599 <2> XOR AX,AX ;;AN002;; Set number of bytes written to 0 1600 <2> OR CX,CX ;;AN002;; For performance, don't write if not necessary 1601 <2> ; $IF NZ ;;AN002;; Any chars to write? 1602 <2> JZ $MIF127 1603 <2> PUSH DS ;;AN000;; Yes, 1604 <2> PUSH ES ;;AN000;; 1605 <2> POP DS ;;AN000;; Set DS to segment of message text 1606 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1607 <2> MOV DX,DI ;;AN000;; Pointer to data to write 1608 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1609 <2> ; $IF E ;;AN000;; Yes, 1610 <2> JNE $MIF128 1611 <2> INT 21H ;;AN000;; Write character 1612 <2> POP DS ;;AN000;; Set DS to segment of message text 1613 <2> PUSH AX ;;AN000;; 1614 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1615 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1616 <2> POP AX ;;AN000;; Set DS to segment of message text 1617 <2> PUSH DS ;;AN000;; 1618 <2> PUSH ES ;;AN000;; 1619 <2> POP DS ;;AN000;; Set DS to segment of message text 1620 <2> ; $IF C ;;AN000;; Yes, 1621 <2> JNC $MIF129 1622 <2> CLC ;;AN000;; Clear the DBCS indicator 1623 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1624 <2> INC DX ;;AN000;; Point to next character 1625 <2> INT 21H ;;AN000;; Write character 1626 <2> ; $ENDIF ;;AN000;; 1627 <2> $MIF129: 1628 <2> ; $ELSE ;;AN000;; No, 1629 <2> JMP SHORT $MEN128 1630 <2> $MIF128: 1631 <2> INT 21H ;;AN000;; Write String at DS:SI to handle 1632 <2> ; $ENDIF ;;AN000;; 1633 <2> $MEN128: 1634 <2> POP DS ;;AN000;; 1635 <2> ; $ENDIF ;;AN002;; 1636 <2> $MIF127: 1637 <2> ;; 1638 <2> RET ;;AN000;; 1639 <2> ;; 1640 <2> $M_DISPLAY_H_STRING ENDP ;;AN000;; 1641 <2> ;; 1642 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1643 <2> ;; 1644 <2> ;; PROC NAME: $M_GET_EXT_ERR_39 1645 <2> ;; 1646 <2> ;; FUNCTION: Will set registers for extended error #39 1647 <2> ;; INPUTS: None 1648 <2> ;; OUPUTS: AX,BX,CX set 1649 <2> ;; REGS USED: 1650 <2> ;; 1651 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1652 <2> ;; 1653 <2> $M_GET_EXT_ERR_39 PROC NEAR ;AN001; 1654 <2> ;; 1655 <2> MOV AX,EXT_ERR_39 ;AN001; Set AX=39 1656 <2> MOV BX,(ERROR_CLASS_39 >> 8) + ACTION_39 ;AN001; Set BH=1 BL=4 1657 <2> MOV CH,LOCUS_39 ;AN001; Set CH=1 1658 <2> ;AN001; 1659 <2> RET ;AN001; 1660 <2> ;; 1661 <2> $M_GET_EXT_ERR_39 ENDP ;AN001; 1662 <2> ;; 1663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1664 <2> %ENDIF 1665 <2> ;; 1666 <2> ;; PROC NAME: $M_ADD_CRLF 1667 <2> ;; 1668 <2> ;; FUNCTION: Will decide whether to display a CRLF 1669 <2> ;; INPUTS: DX contains the Input/Class requested 1670 <2> ;; OUTPUTS: None 1671 <2> ;; REGS Revised: CX,ES,DI 1672 <2> ;; 1673 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1674 <2> ;; 1675 <2> $M_ADD_CRLF PROC NEAR ;;AN004;; 1676 <2> ;; 1677 <2> CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1678 <2> ; $IF NE ;;AN004;; No, 1679 <2> JE $MIF134 1680 <2> TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? 1681 <2> ; $IF Z ;;AN004;; No, 1682 <2> JNZ $MIF135 1683 <2> PUSH DS ;;AN004;; 1684 <2> POP ES ;;AN004;; Set ES to data segment 1685 <2> LEA DI,[$M_RT + $M_CRLF] ;;AN004;; Point at CRLF message 1686 <2> MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size 1687 <2> CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF 1688 <2> ; $ENDIF ;;AN004;; 1689 <2> $MIF135: 1690 <2> ; $ENDIF ;;AN004;; 1691 <2> $MIF134: 1692 <2> RET ;;AN004;; Return 1693 <2> ;; 1694 <2> $M_ADD_CRLF ENDP ;;AN004;; 1695 <2> ;; 1696 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1697 <2> ;; 1698 <2> ;; PROC NAME: $M_IS_IT_DBCS 1699 <2> ;; 1700 <2> ;; FUNCTION: Will decide whether character is Single or Double Byte 1701 <2> ;; INPUTS: AL contains the byte to be checked 1702 <2> ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range 1703 <2> ;; Carry flag = 1 if byte IS in DBCS range 1704 <2> ;; REGS USED: All restored 1705 <2> ;; 1706 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1707 <2> ;; 1708 <2> $M_IS_IT_DBCS PROC NEAR ;;AN000;; 1709 <2> ;; 1710 <2> PUSH ES ;;AN000;; Save Extra segment register 1711 <2> PUSH DI ;;AN000;; Save SI register 1712 <2> ;; 1713 <2> LES DI,[cs:$M_RT + $M_DBCS_VEC] ;;AN000;; 1714 <2> OR DI,DI ;;AN000;; Was the DBCS vector set? 1715 <2> ; $IF NZ ;;AN000;; 1716 <2> JZ $MIF138 1717 <2> ; $DO ;;AN000;; 1718 <2> $MDO139: 1719 <2> CMP WORD PTR [ES:DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? 1720 <2> CLC ;;AN000;; 1721 <2> ; $LEAVE E ;;AN000;; 1722 <2> JE $MEN139 1723 <2> ;; No, 1724 <2> CMP AL,BYTE PTR [ES:DI] ;;AN000;; Does the character fall in the DBCS range? 1725 <2> ; $IF AE,AND ;;AN000;; 1726 <2> JNAE $MIF141 1727 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Does the character fall in the DBCS range? 1728 <2> ; $IF BE ;;AN000;; 1729 <2> JNBE $MIF141 1730 <2> STC ;;AN000;; Yes, 1731 <2> ; $ENDIF ;;AN000;; Set carry flag 1732 <2> $MIF141: 1733 <2> INC DI ;;AN000;; No, 1734 <2> INC DI ;;AN000;; Go to next vector 1735 <2> ; $ENDDO ;;AN000;; 1736 <2> JMP SHORT $MDO139 1737 <2> $MEN139: 1738 <2> ; $ENDIF ;;AN000;; 1739 <2> $MIF138: 1740 <2> 1741 <2> POP DI ;;AN000;; 1742 <2> POP ES ;;AN000;; Restore SI register 1743 <2> RET ;;AN000;; Return 1744 <2> ;; 1745 <2> $M_IS_IT_DBCS ENDP ;;AN000;; 1746 <2> ;; 1747 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1748 <2> ;; 1749 <2> ;; PROC NAME: $M_CONVERT2ASC 1750 <2> ;; 1751 <2> ;; FUNCTION: Convert a binary number to a ASCII string 1752 <2> ;; INPUTS: DX:AX contains the number to be converted 1753 <2> ;; $M_RT_DIVISOR contains the divisor 1754 <2> ;; OUPUTS: CX contains the number of characters 1755 <2> ;; Top of stack --> Last character 1756 <2> ;; . . . 1757 <2> ;; Bot of stack --> First character 1758 <2> ;; REGS USED: 1759 <2> ;; 1760 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1761 <2> ;; 1762 <2> $M_CONVERT2ASC PROC NEAR ;;AN000;; 1763 <2> ;; 1764 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Save Return Address 1765 <2> XOR BX,BX ;;AN000;; Use BP as a swapping register 1766 <2> ;; 1767 <2> XCHG BX,AX ;;AN000;; Initialize - Low Word in BP 1768 <2> XCHG AX,DX ;;AN000;; - High Word in AX 1769 <2> ; $DO ;;AN000;; DO UNTIL Low Word becomes zero 1770 <2> $MDO145: 1771 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide High Word by divisor 1772 <2> XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder 1773 <2> ;; and save reduced High Word in BP 1774 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide Low Word by divisor 1775 <2> CMP DX,9 ;;AN000;; Make a digit of the remainder 1776 <2> ; $IF A ;;AN000;; IF 10 to 15, 1777 <2> JNA $MIF146 1778 <2> ADD DL,55 ;;AN000;; Make A to F ASCII 1779 <2> ; $ELSE ;;AN000;; IF 0 to 9, 1780 <2> JMP SHORT $MEN146 1781 <2> $MIF146: 1782 <2> ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII 1783 <2> ; $ENDIF ;;AN000;; 1784 <2> $MEN146: 1785 <2> PUSH DX ;;AN000;; Save the digit on the stack 1786 <2> INC CX ;;AN000;; Count that digit 1787 <2> OR AX,AX ;;AN000;; Are we done? 1788 <2> ; $LEAVE Z,AND ;;AN000;; 1789 <2> JNZ $MLL149 1790 <2> OR BX,BX ;;AN000;; AX and BX must be ZERO!! 1791 <2> ; $LEAVE Z ;;AN000;; No, 1792 <2> JZ $MEN145 1793 <2> $MLL149: 1794 <2> %IFN COMR 1795 <2> CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark 1796 <2> ; $IF E ;;AN000;; Yes, 1797 <2> JNE $MIF150 1798 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1799 <2> ; $IF E ;;AN000;; Yes, 1800 <2> JNE $MIF151 1801 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1802 <2> INC CX ;;AN000;; 1803 <2> ; $ENDIF ;;AN000;; 1804 <2> $MIF151: 1805 <2> ; $ELSE ;;AN000;; No, 1806 <2> JMP SHORT $MEN150 1807 <2> $MIF150: 1808 <2> CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark 1809 <2> ; $IF E ;;AN000;; Yes, 1810 <2> JNE $MIF154 1811 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1812 <2> ; $IF E ;;AN000;; Yes, 1813 <2> JNE $MIF155 1814 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1815 <2> INC CX ;;AN000;; 1816 <2> ; $ENDIF ;;AN000;; 1817 <2> $MIF155: 1818 <2> ; $ELSE ;;AN000;; No, 1819 <2> JMP SHORT $MEN154 1820 <2> $MIF154: 1821 <2> CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark 1822 <2> ; $IF E ;;AN000;; Yes, 1823 <2> JNE $MIF158 1824 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1825 <2> ; $IF E ;;AN000;; Yes, 1826 <2> JNE $MIF159 1827 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1828 <2> INC CX ;;AN000;; 1829 <2> ; $ENDIF ;;AN000;; 1830 <2> $MIF159: 1831 <2> ; $ENDIF ;;AN000;; 1832 <2> $MIF158: 1833 <2> ; $ENDIF ;;AN000;; 1834 <2> $MEN154: 1835 <2> ; $ENDIF ;;AN000;; 1836 <2> $MEN150: 1837 <2> %ENDIF 1838 <2> XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word 1839 <2> ;;AN000;; and Revised Low Word 1840 <2> XOR DX,DX ;;AN000;; Reset remainder 1841 <2> ; $ENDDO ;;AN000;; NEXT 1842 <2> JMP SHORT $MDO145 1843 <2> $MEN145: 1844 <2> ;;AN000;; Yes, 1845 <2> XOR DX,DX ;;AN000;; Reset remainder 1846 <2> XOR AX,AX ;;AN000;; Reset remainder 1847 <2> PUSH word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Restore Return Address 1848 <2> RET ;;AN000;; Return 1849 <2> ;; 1850 <2> $M_CONVERT2ASC ENDP ;;AN000;; 1851 <2> ;; 1852 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1853 <2> ;; 1854 <2> ;; PROC NAME: $M_DISPLAY_MESSAGE 1855 <2> ;; 1856 <2> ;; FUNCTION: Will display or write entire message (with replacable parameters) 1857 <2> ;; INPUTS: ES:DI points to beginning of message 1858 <2> ;; DS:SI points to first sublist structure in chain 1859 <2> ;; BX contains the handle to write to (if applicable) 1860 <2> ;; CX contains the length of string to write (before substitutions) 1861 <2> ;; BP contains the count of replacables 1862 <2> ;; 1863 <2> ;; OUTPUTS: 1864 <2> ;; REGS USED: All 1865 <2> ;; 1866 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1867 <2> ;; 1868 <2> $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; 1869 <2> ;; 1870 <2> ; $DO ;;AN000;; Note: DS:SI -> message 1871 <2> $MDO165: 1872 <2> XOR DX,DX ;;AN000;; Set size = 0 1873 <2> OR CX,CX ;;AN000;; Are we finished the message yet? 1874 <2> ; $IF NZ ;;AN000;; No, 1875 <2> JZ $MIF166 1876 <2> MOV AH,"%" ;;AN000;; Prepare to scan for % 1877 <2> MOV AL,0 ;;AN004;; 1878 <2> ;; 1879 <2> ; $DO ;;AN000;; Scan through string until % 1880 <2> $MDO167: 1881 <2> CMP BYTE PTR [ES:DI],AH ;;AN000;; Is this character NOT a % 1882 <2> ; $LEAVE E,AND ;;AN000;; No, 1883 <2> JNE $MLL168 1884 <2> CMP BYTE PTR [ES:DI+1],AH ;;AN000;; Is the next character also a % 1885 <2> ; $LEAVE NE,AND ;;AN000;; No, 1886 <2> JE $MLL168 1887 <2> CMP AL,AH ;;AN000;; Was the character before a % 1888 <2> ; $LEAVE NE ;;AN000;; No, GREAT found it 1889 <2> JNE $MEN167 1890 <2> $MLL168: 1891 <2> MOV AL,BYTE PTR [ES:DI] ;;AN004;; Yes, (to any of the above) 1892 <2> CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? 1893 <2> ; $IF C ;;AN004;; Yes, 1894 <2> JNC $MIF169 1895 <2> INC DI ;;AN004;; Increment past second part 1896 <2> ; $ENDIF ;;AN004;; 1897 <2> $MIF169: 1898 <2> INC DI ;;AN000;; Next character in string 1899 <2> INC DX ;;AN000;; Size = Size + 1 1900 <2> DEC CX ;;AN000;; Decrement total size 1901 <2> ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line 1902 <2> JNZ $MDO167 1903 <2> $MEN167: 1904 <2> ; $ENDIF ;;AN000;; 1905 <2> $MIF166: 1906 <2> ;; 1907 <2> PUSH SI ;;AN000;; Save beginning of sublists 1908 <2> XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) 1909 <2> OR BP,BP ;;AN000;; Do we have any replacables to do? 1910 <2> ; $IF NZ ;;AN000;; Yes, 1911 <2> JZ $MIF173 1912 <2> DEC BP ;;AN000;; Decrement number of replacables 1913 <2> 1914 <2> ;; Search through sublists to find applicable one 1915 <2> 1916 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 1917 <2> ; $IF E ;;AN000;; No, 1918 <2> JNE $MIF174 1919 <2> ; $SEARCH ;;AN000;; 1920 <2> $MDO175: 1921 <2> MOV AL,[$M_SL + $M_S_ID] ;;AN000;; Get ID byte 1922 <2> ADD AL,30H ;;AN000;; Convert to ASCII 1923 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Is this the right sublist? 1924 <2> ; $EXITIF E ;;AN000;; 1925 <2> JNE $MIF175 1926 <2> ; $ORELSE ;;AN000;; No, 1927 <2> JMP SHORT $MSR175 1928 <2> $MIF175: 1929 <2> CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 1930 <2> ; $LEAVE E,AND ;;AN000;; Yes, 1931 <2> JNE $MLL178 1932 <2> OR DX,DX ;;AN000;; Are we at the end of the message? 1933 <2> ; $LEAVE Z ;;AN000;; No, 1934 <2> JZ $MEN175 1935 <2> $MLL178: 1936 <2> ADD SI,WORD PTR [$M_SL + $M_S_SIZE] ;;AN000;; Next SUBLIST 1937 <2> ; $ENDLOOP ;;AN000;; Yes, 1938 <2> JMP SHORT $MDO175 1939 <2> $MEN175: 1940 <2> CMP byte [cs:$M_RT + $M_CLASS],UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1941 <2> ; $IF E ;;AN004;; Yes, 1942 <2> JNE $MIF180 1943 <2> INC DX ;;AN000;; Remember to display CR,LF 1944 <2> INC DX ;;AN000;; at the end of the message 1945 <2> DEC CX ;;AN000;; Adjust message length 1946 <2> DEC CX ;;AN000;; 1947 <2> DEC DI ;;AN000;; Adjust ending address of message 1948 <2> DEC DI ;;AN000;; 1949 <2> ; $ELSE ;;AN004;; No, 1950 <2> JMP SHORT $MEN180 1951 <2> $MIF180: 1952 <2> MOV DX,-1 ;;AN004;; Set special case 1953 <2> ; $ENDIF ;;AN004;; 1954 <2> $MEN180: 1955 <2> ; $ENDSRCH ;;AN000;; 1956 <2> $MSR175: 1957 <2> ; $ENDIF ;;AN000;; 1958 <2> $MIF174: 1959 <2> ; $ENDIF ;;AN000;; 1960 <2> $MIF173: 1961 <2> 1962 <2> ;; Prepare and display this part of message 1963 <2> 1964 <2> PUSH DI ;;AN000;; Save pointer to replace number 1965 <2> SUB DI,CX ;;AN000;; Determine beginning of string 1966 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) 1967 <2> POP DI ;;AN000;; Get back pointer to replace number 1968 <2> POP CX ;;AN000;; Clean up stack in case error 1969 <2> ; $LEAVE C,LONG ;;AN000;; Fail if carry was set 1970 <2> JNC $MXL3 1971 <2> JMP $MEN165 1972 <2> nop ; identicalise 1973 <2> $MXL3: 1974 <2> PUSH CX ;;AN000;; 1975 <2> 1976 <2> ;; Save and reset pointer registers 1977 <2> 1978 <2> MOV CX,DX ;;AN000;; Get the size of the rest of the message 1979 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? 1980 <2> ; $IF NE ;;AN000;; No, 1981 <2> JE $MIF187 1982 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1983 <2> ; $IF NZ ;;AN000;; No, 1984 <2> JZ $MIF188 1985 <2> DEC CX ;;AN000;; Decrement total size (%) 1986 <2> DEC CX ;;AN000;; Decrement total size (#) 1987 <2> INC DI ;;AN000;; Go past % 1988 <2> INC DI ;;AN000;; Go past replace number 1989 <2> ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) 1990 <2> JMP SHORT $MEN188 1991 <2> $MIF188: 1992 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 1993 <2> ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC 1994 <2> $MEN188: 1995 <2> ; $ELSE ;;AN000;; 1996 <2> JMP SHORT $MEN187 1997 <2> $MIF187: 1998 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1999 <2> ; $IF Z ;;AN004;; No, 2000 <2> JNZ $MIF192 2001 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 2002 <2> ; $ELSE ;;AN000;; No, 2003 <2> JMP SHORT $MEN192 2004 <2> $MIF192: 2005 <2> CMP CX,-1 ;;AN004;; Are we at the end of the message? 2006 <2> ; $IF Z ;;AN004;; No, 2007 <2> JNZ $MIF194 2008 <2> XOR CX,CX ;;AN004;; 2009 <2> ; $ENDIF ;;AN000;; 2010 <2> $MIF194: 2011 <2> OR DI,DI ;;AN004;; Turn ZF off 2012 <2> ; $ENDIF ;;AN000;; 2013 <2> $MEN192: 2014 <2> ; $ENDIF ;;AN000;; Note this will not leave because INC 2015 <2> $MEN187: 2016 <2> ; $LEAVE Z ;;AN000;; 2017 <2> JZ $MEN165 2018 <2> PUSH BP ;;AN000;; Save the replace count 2019 <2> PUSH DI ;;AN000;; Save location to complete message 2020 <2> PUSH ES ;;AN000;; 2021 <2> PUSH CX ;;AN000;; Save size of the rest of the message 2022 <2> XOR CX,CX ;;AN000;; Reset CX used for character count 2023 <2> 2024 <2> ;; Determine what action is required on parameter 2025 <2> 2026 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2027 <2> ; $IF E ;;AN000;; 2028 <2> JNE $MIF199 2029 <2> 2030 <2> %IF CHARmsg ;;AN000;; Was Char specified? 2031 <2> Char_Type equ Char_type ; NASM port equate 2032 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2033 <2> ; $IF Z ;;AN000;; 2034 <2> JNZ $MIF200 2035 <2> 2036 <2> ;; Character type requested 2037 <2> ;;AN000;; 2038 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2039 <2> CALL $M_CHAR_REPLACE ;;AN000;; 2040 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2041 <2> JMP SHORT $MEN200 2042 <2> $MIF200: 2043 <2> %ENDIF ;;AN000;; 2044 <2> %IF NUMmsg ;;AN000;; Was Nnmeric type specified? 2045 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2046 <2> ; $IF Z,OR ;;AN000;; 2047 <2> JZ $MLL202 2048 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2049 <2> ; $IF Z,OR ;;AN000;; 2050 <2> JZ $MLL202 2051 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Bin_Hex_Type & $M_TYPE_MASK ;;AN000;; 2052 <2> ; $IF Z ;;AN000;; 2053 <2> JNZ $MIF202 2054 <2> $MLL202: 2055 <2> 2056 <2> ;; Numeric type requested 2057 <2> 2058 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2059 <2> CALL $M_BIN2ASC_REPLACE ;;AN000;; 2060 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2061 <2> JMP SHORT $MEN202 2062 <2> $MIF202: 2063 <2> %ENDIF ;;AN000;; 2064 <2> %IF DATEmsg ;;AN000;; Was date specified? 2065 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Date_Type & $M_TYPE_MASK ;;AN000;; 2066 <2> ; $IF E ;;AN000;; 2067 <2> JNE $MIF204 2068 <2> 2069 <2> ;; Date type requested 2070 <2> 2071 <2> CALL $M_DATE_REPLACE ;;AN000;; 2072 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2073 <2> JMP SHORT $MEN204 2074 <2> $MIF204: 2075 <2> %ENDIF ;;AN000;; 2076 <2> %IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? 2077 <2> 2078 <2> ;; Time type requested (Default if we have not matched until here) 2079 <2> 2080 <2> CALL $M_TIME_REPLACE ;;AN000;; 2081 <2> %ENDIF ;;AN000;; 2082 <2> 2083 <2> %IF DATEmsg ;;AN000;; 2084 <2> ; $ENDIF ;;AN000;; 2085 <2> $MEN204: 2086 <2> %ENDIF ;;AN000;; 2087 <2> %IF NUMmsg ;;AN000;; 2088 <2> ; $ENDIF ;;AN000;; 2089 <2> $MEN202: 2090 <2> %ENDIF ;;AN000;; 2091 <2> %IF CHARmsg ;;AN000;; 2092 <2> ; $ENDIF ;;AN000;; 2093 <2> $MEN200: 2094 <2> %ENDIF ;;AN000;; 2095 <2> 2096 <2> %IF $M_REPLACE ;;AN000;; 2097 <2> ;; With the replace information of the Stack, display the replaceable field 2098 <2> 2099 <2> CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace 2100 <2> %ENDIF ;;AN000;; 2101 <2> ;; None of the above - Extended/Parse replace 2102 <2> ; $ELSE ;;AN000;; 2103 <2> JMP SHORT $MEN199 2104 <2> $MIF199: 2105 <2> %IFN COMR 2106 <2> CALL $M_EXT_PAR_REPLACE ;;AN000;; 2107 <2> %ENDIF 2108 <2> ; $ENDIF ;;AN000;; 2109 <2> $MEN199: 2110 <2> 2111 <2> ;; We must go back and complete the message after the replacable parameter if there is any left 2112 <2> 2113 <2> ; $IF NC ;;AN000;; IF there was an error displaying then EXIT 2114 <2> JC $MIF211 2115 <2> POP CX ;;AN000;; Get size of the rest of the message 2116 <2> POP ES ;;AN000;; Get address of the rest of the message 2117 <2> POP DI ;;AN000;; 2118 <2> POP BP ;;AN000;; Get replacment count 2119 <2> POP SI ;;AN000;; ELSE get address of first sublist structure 2120 <2> ; $ELSE ;;AN000;; 2121 <2> JMP SHORT $MEN211 2122 <2> $MIF211: 2123 <2> ADD SP,10 ;;AN000;; Clean up stack if error 2124 <2> STC ;;AN000;; 2125 <2> ; $ENDIF ;;AN000;; 2126 <2> $MEN211: 2127 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2128 <2> ; $ENDDO NE,OR ;;AN000;; 2129 <2> JNE $MLL214 2130 <2> ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message 2131 <2> JC $MXL4 2132 <2> JMP $MDO165 2133 <2> $MXL4: 2134 <2> $MLL214: 2135 <2> $MEN165: 2136 <2> ;; IF there was an error displaying then EXIT 2137 <2> MOV word [cs:$M_RT + $M_MSG_NUM],0 ;;AN000;; Reset message number to null 2138 <2> RET ;;AN000;; Return 2139 <2> ;; 2140 <2> $M_DISPLAY_MESSAGE ENDP ;;AN000;; 2141 <2> %IFN COMR 2142 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2143 <2> ;; 2144 <2> ;; PROC NAME: $M_EXT_PAR_REPLACE 2145 <2> ;; 2146 <2> ;; FUNCTION: 2147 <2> ;; INPUTS: 2148 <2> ;; OUPUTS: 2149 <2> ;; 2150 <2> ;; REGS USED: 2151 <2> ;; 2152 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2153 <2> ;; 2154 <2> $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; 2155 <2> ;; 2156 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2157 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN000;; Prepare for get binary value (LOW) 2158 <2> MOV word [cs:$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2159 <2> ;; 2160 <2> CALL $M_CONVERT2ASC ;;AN000;; 2161 <2> ;; 2162 <2> ; $DO ;;AN000;; 2163 <2> $MDO215: 2164 <2> POP AX ;;AN000;; Get character in register 2165 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2166 <2> INC BX ;;AN000;; Increase buffer count 2167 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2168 <2> ; $IF E ;;AN000;; Yes, 2169 <2> JNE $MIF216 2170 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2171 <2> ; $ENDIF ;;AN000;; 2172 <2> $MIF216: 2173 <2> DEC CL ;;AN000;; Have we completed replace? 2174 <2> ; $ENDDO Z ;;AN000;; 2175 <2> JNZ $MDO215 2176 <2> ;; 2177 <2> MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer 2178 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],AX ;;AN000;; Move char into the buffer 2179 <2> INC BX ;;AN000;; Increase buffer count 2180 <2> INC BX ;;AN000;; Increase buffer count 2181 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2182 <2> RET ;;AN000:: 2183 <2> ;; 2184 <2> $M_EXT_PAR_REPLACE ENDP ;;AN000;; 2185 <2> ;; 2186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2187 <2> %ENDIF 2188 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 2189 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 2190 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2191 <2> ;; 2192 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 2193 <2> ;; 2194 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 2195 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 2196 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2197 <2> ;; IF CX > 1 THEN DS:SI points to the specified message 2198 <2> ;; REGS CHANGED: ES,DI,CX,DS,SI 2199 <2> ;; 2200 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2201 <2> ;; 2202 <2> %IF FARmsg ;;AN000;; 2203 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 2204 <2> %ELSE ;;AN000;; 2205 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 2206 <2> %ENDIF ;;AN000;; 2207 <2> ;; 2208 <2> PUSH SI ;;AN000;; 2209 <2> PUSH BX ;;AN000;; 2210 <2> XOR SI,SI ;;AN000;; Use SI as an index 2211 <2> XOR CX,CX ;;AN000;; Use CX as an size 2212 <2> ; $DO ;;AN000;; 2213 <2> $MDO219: 2214 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 2215 <2> ; $IF E ;;AN000;; Yes, 2216 <2> JNE $MIF220 2217 <2> %IF FARmsg ;;AN000;; 2218 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2219 <2> MOV BX,ES ;;AN000; 2220 <2> %ELSE ;;AN000;; 2221 <2> MOV DI,WORD PTR [cs:$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2222 <2> MOV BX,DI ;;AN000; 2223 <2> %ENDIF ;;AN000;; 2224 <2> ; $ELSE ;;AN000;; No, 2225 <2> JMP SHORT $MEN220 2226 <2> $MIF220: 2227 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 2228 <2> ; $IF NE ;;AN000;; Yes, 2229 <2> JE $MIF222 2230 <2> LES DI,[cs:$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 2231 <2> MOV BX,ES ;;AN000; 2232 <2> ; $ELSE ;;AN000;; No, extended errors were specified 2233 <2> JMP SHORT $MEN222 2234 <2> $MIF222: 2235 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 2236 <2> ; $IF AE,AND ;;AN000;; 2237 <2> JNAE $MIF224 2238 <2> CMP AX,$M_CRIT_HI ;;AN000;; 2239 <2> ; $IF BE ;;AN000;; Yes, 2240 <2> JNBE $MIF224 2241 <2> LES DI,[cs:$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 2242 <2> MOV BX,ES ;;AN000; 2243 <2> ; $ELSE ;;AN000;; 2244 <2> JMP SHORT $MEN224 2245 <2> $MIF224: 2246 <2> LES DI,[cs:$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 2247 <2> MOV BX,ES ;;AN000; 2248 <2> ; $ENDIF ;;AN000;; 2249 <2> $MEN224: 2250 <2> ; $ENDIF ;;AN000;; 2251 <2> $MEN222: 2252 <2> ; $ENDIF ;;AN000;; 2253 <2> $MEN220: 2254 <2> ;; 2255 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 2256 <2> ; $IF E ;;AN000;; Yes, 2257 <2> JNE $MIF229 2258 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 2259 <2> ; $IF E ;;AN000;; Yes, 2260 <2> JNE $MIF230 2261 <2> STC ;;AN000;; Set the carry flag 2262 <2> ; $ELSE ;;AN000;; No, 2263 <2> JMP SHORT $MEN230 2264 <2> $MIF230: 2265 <2> MOV [cs:$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 2266 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 2267 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 2268 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 2269 <2> CLC ;;AN000;; 2270 <2> ; $ENDIF ;;AN000;; No, 2271 <2> $MEN230: 2272 <2> ; $ELSE ;;AN000;; 2273 <2> JMP SHORT $MEN229 2274 <2> $MIF229: 2275 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 2276 <2> ; $IF NE ;;AN001;; Yes, 2277 <2> JE $MIF234 2278 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 2279 <2> ; $ENDIF ;;AN000;; 2280 <2> $MIF234: 2281 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 2282 <2> CLC ;;AN000;; 2283 <2> ; $ENDIF ;;AN000;; 2284 <2> $MEN229: 2285 <2> ; $LEAVE C ;;AN000;; 2286 <2> JC $MEN219 2287 <2> OR CX,CX ;;AN000;; Was the message found? 2288 <2> ; $ENDDO NZ,LONG ;;AN000;; 2289 <2> JNZ $MXL5 2290 <2> JMP $MDO219 2291 <2> $MXL5: 2292 <2> $MEN219: 2293 <2> 2294 <2> PUSHF ;;AN006;; Save the flag state 2295 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 2296 <2> ; $IF E ;;AN006;; Yes, 2297 <2> JNE $MIF239 2298 <2> PUSH DX ;;AN006;; Save all needed registers 2299 <2> PUSH BP ;;AN006;; 2300 <2> PUSH CX ;;AN006;; 2301 <2> PUSH ES ;;AN006;; 2302 <2> PUSH DI ;;AN006;; 2303 <2> PUSH AX ;;AN006;; 2304 <2> 2305 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 2306 <2> INT 2FH ;;AN006;; 2307 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 2308 <2> POP AX ;;AN006;; Restore msg number 2309 <2> ; $IF E ;;AN006;; Yes, 2310 <2> JNE $MIF240 2311 <2> MOV BX,AX ;;AN006;; BX is the extended error number 2312 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 2313 <2> INT 2FH ;;AN006;; Call IFSFUNC 2314 <2> ; $ELSE ;;AN006;; No, 2315 <2> JMP SHORT $MEN240 2316 <2> $MIF240: 2317 <2> STC ;;AN006;; Carry conditon 2318 <2> ; $ENDIF ;;AN006;; 2319 <2> $MEN240: 2320 <2> 2321 <2> ; $IF C ;;AN006;; Was there an update? 2322 <2> JNC $MIF243 2323 <2> POP DI ;;AN006;; No, 2324 <2> POP ES ;;AN006;; Restore old pointer 2325 <2> POP CX ;;AN006;; 2326 <2> ; $ELSE ;;AN006;; Yes 2327 <2> JMP SHORT $MEN243 2328 <2> $MIF243: 2329 <2> ADD SP,6 ;;AN006;; Throw away old pointer 2330 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 2331 <2> ; $ENDIF ;;AN006;; 2332 <2> $MEN243: 2333 <2> POP BP ;;AN006;; Restore other Regs 2334 <2> POP DX ;;AN006;; 2335 <2> ; $ENDIF ;;AN006;; 2336 <2> $MIF239: 2337 <2> $M_POPF ;;AN006;; Restore the flag state 2338 <2> 2339 <2> POP BX ;;AN000;; 2340 <2> POP SI ;;AN000;; 2341 <2> RET ;;AN000;; Return ES:DI pointing to the message 2342 <2> ;; 2343 <2> $M_GET_MSG_ADDRESS ENDP ;; 2344 <2> ;; 2345 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 2346 <2> ;; 2347 <2> PUSH DI ;;AN006;; Save position 2348 <2> PUSH AX ;;AN006;; 2349 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 2350 <2> XOR AL,AL ;;AN006;; Prepare compare register 2351 <2> REPNE SCASB ;;AN006;; Scan for zero 2352 <2> NOT CX ;;AN006;; Change decrement into number 2353 <2> DEC CX ;;AN006;; Don't include the zero 2354 <2> POP AX ;;AN006;; 2355 <2> POP DI ;;AN006;; Restore position 2356 <2> RET ;;AN006;; 2357 <2> ;; 2358 <2> $M_SET_LEN_IN_CX ENDP ;; 2359 <2> ;; 2360 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2361 <2> ;; 2362 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 2363 <2> ;; 2364 <2> ;; FUNCTION: To scan thru message headers until message is found 2365 <2> ;; INPUTS: ES:DI points to beginning of msg headers 2366 <2> ;; CX contains the number of messages in class 2367 <2> ;; DH contains the message class 2368 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2369 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 2370 <2> ;; 2371 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2372 <2> ;; 2373 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 2374 <2> ;; 2375 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 2376 <2> ; $IF E,AND ;;AN004;; Yes, 2377 <2> JNE $MIF247 2378 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 2379 <2> ; $IF NE ;;AN004;; Yes, 2380 <2> JE $MIF247 2381 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 2382 <2> ; $IF E ;;AN004;; . . . and . . . 2383 <2> JNE $MIF248 2384 <2> PUSH AX ;;AN004;; Reset the special message number 2385 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 2386 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2387 <2> POP AX ;;AN004;; Reset the special message number 2388 <2> ; $ELSE ;;AN004;; Get the old message number 2389 <2> JMP SHORT $MEN248 2390 <2> $MIF248: 2391 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2392 <2> ; $ENDIF ;;AN004;; Get the old message number 2393 <2> $MEN248: 2394 <2> ; $ELSE ;;AN004;; 2395 <2> JMP SHORT $MEN247 2396 <2> $MIF247: 2397 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 2398 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2399 <2> ; $IF NE ;;AN001;; 2400 <2> JE $MIF252 2401 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 2402 <2> ; $ELSE ;;AN001;; 2403 <2> JMP SHORT $MEN252 2404 <2> $MIF252: 2405 <2> %IF FARmsg ;;AN001;; 2406 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2407 <2> %ELSE 2408 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2409 <2> %ENDIF 2410 <2> ; $IF E ;;AN002;; pointer (hopefully) 2411 <2> JNE $MIF254 2412 <2> %IF FARmsg ;;AN001;; 2413 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2414 <2> %ELSE 2415 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2416 <2> %ENDIF 2417 <2> ; $ENDIF ;;AN002;; go on to the next class 2418 <2> $MIF254: 2419 <2> ; $ENDIF ;;AN001;; 2420 <2> $MEN252: 2421 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 2422 <2> STC ;;AN004;; Flag that we haven't found anything yet 2423 <2> ; $ENDIF ;;AN004;; 2424 <2> $MEN247: 2425 <2> 2426 <2> ; $IF C ;;AN004;; Have we found anything yet? 2427 <2> JNC $MIF258 2428 <2> CLC ;;AN004;; No, reset carry 2429 <2> ; $SEARCH ;;AN000;; 2430 <2> $MDO259: 2431 <2> OR CX,CX ;;AN000;; Do we have any to check? 2432 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2433 <2> JZ $MEN259 2434 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2435 <2> ; $IF NE ;;AN001;; 2436 <2> JE $MIF261 2437 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 2438 <2> ; $ELSE ;;AN001;; 2439 <2> JMP SHORT $MEN261 2440 <2> $MIF261: 2441 <2> %IF FARmsg ;;AN001;; 2442 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 2443 <2> %ELSE 2444 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 2445 <2> %ENDIF 2446 <2> ; $ENDIF 2447 <2> $MEN261: 2448 <2> ; $EXITIF E ;;AN000;; 2449 <2> JNE $MIF259 2450 <2> ; $ORELSE ;;AN000; 2451 <2> JMP SHORT $MSR259 2452 <2> $MIF259: 2453 <2> DEC CX ;;AN000;; No, well do we have more to check? 2454 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2455 <2> JZ $MEN259 2456 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 2457 <2> ; $ENDLOOP ;;AN000;; 2458 <2> JMP SHORT $MDO259 2459 <2> $MEN259: 2460 <2> STC ;;AN000;; 2461 <2> ; $ENDSRCH ;;AN000;; Check next message 2462 <2> $MSR259: 2463 <2> ; $IF NC ;;AN000;; Did we find the message? 2464 <2> JC $MIF269 2465 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 2466 <2> CLC ;;AN001;; 2467 <2> ; $IF E ;;AN001;; 2468 <2> JNE $MIF270 2469 <2> %IF FARmsg ;;AN001;; 2470 <2> %ELSE ;;AN000;; 2471 <2> PUSH CS ;;AN000;; 2472 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 2473 <2> %ENDIF 2474 <2> ; $ENDIF ;;AN001;; 2475 <2> $MIF270: 2476 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 2477 <2> ; $ENDIF ;;AN004;; 2478 <2> $MIF269: 2479 <2> ; $ENDIF ;;AN004;; 2480 <2> $MIF258: 2481 <2> ;; Yes, great we can return with CX > 0 2482 <2> 2483 <2> ; $IF NC ;;AN000;; Did we find the message? 2484 <2> JC $MIF274 2485 <2> XOR CH,CH ;;AN000;; 2486 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 2487 <2> INC DI ;;AN000;; Increment past length 2488 <2> ; $ENDIF ;;AN004;; 2489 <2> $MIF274: 2490 <2> 2491 <2> MOV byte [cs:$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 2492 <2> RET ;;AN000;; Return 2493 <2> ;; 2494 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 2495 <2> ;; 2496 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2497 <2> %ENDIF ;;AN000;; END of include of common subroutines 2498 <2> ; 2499 <2> %IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms 2500 <2> %iassign $M_REPLACE FALSE ;;AN000;; Tell the assembler we did 2501 <2> ;; 2502 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2503 <2> $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; 2504 <2> ;; 2505 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2506 <2> %IFN COMR 2507 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) 2508 <2> ; $IF E ;;AN000;; Yes, 2509 <2> JNE $MIF276 2510 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE_HYP ;;AN000;; Move in a " -" 2511 <2> INC BX ;;AN000;; Increment count 2512 <2> INC BX ;;AN000;; Increment count 2513 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE ;;AN000;; Move in a " " 2514 <2> INC BX ;;AN000;; Increment count 2515 <2> CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case 2516 <2> ; $ENDIF ;;AN000;; If it fails we will catch it later 2517 <2> $MIF276: 2518 <2> %ENDIF 2519 <2> 2520 <2> POP BP ;;AN000;; Remember the return address 2521 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2522 <2> XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack 2523 <2> 2524 <2> MOV [cs:$M_RT + $M_SIZE],CL ;;AN000;; Save size to later clear stack 2525 <2> MOV AL,BYTE PTR [$M_SL + $M_S_MINW] ;;AN000;; Get the minimum width 2526 <2> ;; 2527 <2> CMP AL,CL ;;AN000;; Do we need pad chars added? 2528 <2> ; $IF A ;;AN000;; Yes, 2529 <2> JNA $MIF278 2530 <2> SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. 2531 <2> MOV DH,AL ;;AN000;; Save the number of pad characters 2532 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be right aligned? 2533 <2> ; $IF NZ ;;AN000;; Yes, 2534 <2> JZ $MIF279 2535 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2536 <2> $MDO280: 2537 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2538 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2539 <2> INC BX ;;AN000;; 2540 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2541 <2> ; $IF E ;;AN000;; Yes, 2542 <2> JNE $MIF281 2543 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2544 <2> ; $ENDIF ;;AN000;; 2545 <2> $MIF281: 2546 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2547 <2> ; $ENDDO Z ;;AN000;; No, next pad character 2548 <2> JNZ $MDO280 2549 <2> ; $ENDIF ;;AN000;; 2550 <2> $MIF279: 2551 <2> ; $ENDIF ;;AN000;; Yes, 2552 <2> $MIF278: 2553 <2> ;; 2554 <2> CMP BYTE [$M_SL + $M_S_MAXW],$M_UNLIM_W ;;AN000;; Is maximum width unlimited? 2555 <2> ; $IF NE ;;AN000;; 2556 <2> JE $MIF286 2557 <2> CMP BYTE PTR [$M_SL + $M_S_MAXW],CL ;;AN000;; Will we exceed maximum width? 2558 <2> ; $IF B ;;AN000;; Yes, 2559 <2> JNB $MIF287 2560 <2> SUB CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Calculate how many extra chars 2561 <2> MOV DL,CL ;;AN000;; Remember how many chars to pop off 2562 <2> MOV CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Set new string length 2563 <2> ; $ENDIF ;;AN000;; 2564 <2> $MIF287: 2565 <2> ; $ENDIF ;;AN000;; 2566 <2> $MIF286: 2567 <2> OR CX,CX ;;AN000;; 2568 <2> ; $IF NZ ;;AN000;; 2569 <2> JZ $MIF290 2570 <2> ; $DO ;;AN000;; Begin filling buffer with string 2571 <2> $MDO291: 2572 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2573 <2> ; $IF Z,AND ;;AN000;; 2574 <2> JNZ $MIF292 2575 <2> Char_field_ASCIIZ equ Char_Field_ASCIIZ ; NASM port equate 2576 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ; Is this replace a ASCIIZ string? 2577 <2> ; $IF NZ ;;AN000;; Yes, 2578 <2> JZ $MIF292 2579 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get first character from string 2580 <2> INC DI ;;AN000;; Next character in string 2581 <2> ; $ELSE ;;AN000;; No, 2582 <2> JMP SHORT $MEN292 2583 <2> $MIF292: 2584 <2> POP AX ;;AN000;; Get character in register 2585 <2> ; $ENDIF ;;AN000;; 2586 <2> $MEN292: 2587 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2588 <2> INC BX ;;AN000;; Increase buffer count 2589 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2590 <2> ; $IF E ;;AN000;; Yes, 2591 <2> JNE $MIF295 2592 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2593 <2> ; $ENDIF ;;AN000;; 2594 <2> $MIF295: 2595 <2> DEC CL ;;AN000;; Have we completed replace? 2596 <2> ; $ENDDO Z ;;AN000;; Test again 2597 <2> JNZ $MDO291 2598 <2> ; $ENDIF ;;AN000;; 2599 <2> $MIF290: 2600 <2> ;; 2601 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be left aligned? 2602 <2> ; $IF Z ;;AN000;; Yes, 2603 <2> JNZ $MIF299 2604 <2> OR DH,DH ;;AN000;; Do we need pad chars added? 2605 <2> ; $IF NZ ;;AN000;; Yes, 2606 <2> JZ $MIF300 2607 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2608 <2> $MDO301: 2609 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2610 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2611 <2> INC BX ;;AN000;; 2612 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2613 <2> ; $IF E ;;AN000;; Yes, 2614 <2> JNE $MIF302 2615 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2616 <2> ; $ENDIF ;;AN000;; 2617 <2> $MIF302: 2618 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2619 <2> ; $ENDDO Z ;;AN000;; Test again 2620 <2> JNZ $MDO301 2621 <2> ; $ENDIF ;;AN000;; 2622 <2> $MIF300: 2623 <2> ; $ENDIF ;;AN000;; 2624 <2> $MIF299: 2625 <2> ;; 2626 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2627 <2> ; $IF Z,AND ;;AN000;; 2628 <2> JNZ $MIF307 2629 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? 2630 <2> ; $IF NZ ;;AN000;; Yes, 2631 <2> JZ $MIF307 2632 <2> ; $ELSE ;;AN000;; 2633 <2> JMP SHORT $MEN307 2634 <2> $MIF307: 2635 <2> OR DL,DL ;;AN000;; 2636 <2> ; $IF NE ;;AN000;; 2637 <2> JE $MIF309 2638 <2> ; $DO ;;AN000;; 2639 <2> $MDO310: 2640 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable 2641 <2> DEC DL ;;AN000;; Are we done? 2642 <2> ; $ENDDO Z ;;AN000;; 2643 <2> JNZ $MDO310 2644 <2> ; $ENDIF ;;AN000;; 2645 <2> $MIF309: 2646 <2> ; $ENDIF ;;AN000;; 2647 <2> $MEN307: 2648 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time 2649 <2> PUSH BP ;;AN000;; Restore the return address 2650 <2> ;; 2651 <2> RET ;;AN000;; 2652 <2> ;; 2653 <2> $M_DISPLAY_REPLACE ENDP ;;AN000;; 2654 <2> ;; 2655 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2656 <2> ;; 2657 <2> ;; PROC NAME: $M_FLUSH_BUFFER 2658 <2> ;; 2659 <2> ;; FUNCTION: Display the contents of the temporary buffer 2660 <2> ;; INPUTS: DI contains the number of bytes to display 2661 <2> ;; OUTPUTS: BX reset to zero 2662 <2> ;; 2663 <2> ;; REGS USED: 2664 <2> ;; 2665 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2666 <2> ;; 2667 <2> $M_FLUSH_BUF PROC NEAR ;;AN000;; 2668 <2> ;; 2669 <2> PUSH CX ;;AN000;; Save changed regs 2670 <2> PUSH ES ;;AN000;; 2671 <2> PUSH DI ;;AN000;; 2672 <2> PUSH DS ;;AN000;; Set ES pointing to buffer 2673 <2> POP ES ;;AN000;; 2674 <2> ;; 2675 <2> MOV CX,BX ;;AN000;; Set number of bytes to display 2676 <2> XOR BX,BX ;;AN000;; Reset buffer counter 2677 <2> LEA DI,[$M_RT + $M_TEMP_BUF] ;;AN000;; Reset buffer location pointer 2678 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer 2679 <2> ;; 2680 <2> ; $IF NC ;;AN000;; Error? 2681 <2> JC $MIF314 2682 <2> POP DI ;;AN000;; No, Restore changed regs 2683 <2> POP ES ;;AN000;; 2684 <2> POP CX ;;AN000;; 2685 <2> ; $ELSE ;;AN000;; Yes, 2686 <2> JMP SHORT $MEN314 2687 <2> $MIF314: 2688 <2> ADD SP,6 ;;AN000;; Fix stack 2689 <2> STC ;;AN000;; 2690 <2> ; $ENDIF ;;AN000;; Error? 2691 <2> $MEN314: 2692 <2> ;; 2693 <2> RET ;;AN000;; Return 2694 <2> ;; 2695 <2> $M_FLUSH_BUF ENDP ;;AN000;; 2696 <2> ;; 2697 <2> ;; 2698 <2> %IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? 2699 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2700 <2> %iassign $M_CHAR_ONLY TRUE ;;AN000;; replacement code later 2701 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2702 <2> ;; 2703 <2> ;; PROC NAME: $M_CHAR_REPLACE 2704 <2> ;; 2705 <2> ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace 2706 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2707 <2> ;; ES:DI contains the VALUE from SUBLIST 2708 <2> ;; OUTPUTS: CX contains number of characters on stack 2709 <2> ;; Top of stack --> Last character 2710 <2> ;; . . . 2711 <2> ;; Bot of stack --> First character 2712 <2> ;; 2713 <2> ;; OTHER REGS Revised: AX 2714 <2> ;; 2715 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2716 <2> ;; 2717 <2> $M_CHAR_REPLACE PROC NEAR ;;AN000;; 2718 <2> ;; 2719 <2> POP BP ;;AN000;; Save return address 2720 <2> TEST byte [$M_SL + $M_S_FLAG],~ Char_Field_Char & $M_SIZE_MASK ;;AN000;; Was Character specified? 2721 <2> ; $IF Z ;;AN000;; Yes, 2722 <2> JNZ $MIF317 2723 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2724 <2> PUSH AX ;;AN000;; Put it on the stack 2725 <2> INC CX ;;AN000;; Increase the count 2726 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 2727 <2> ; $IF C ;;AN000;; Yes, 2728 <2> JNC $MIF318 2729 <2> MOV AL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 2730 <2> PUSH AX ;;AN000;; Put it on the stack 2731 <2> CLC ;;AN000;; Clear the carry 2732 <2> ; $ENDIF ;;AN000;; 2733 <2> $MIF318: 2734 <2> ; $ELSE ;;AN000;; No, it was an ASCIIZ string 2735 <2> JMP SHORT $MEN317 2736 <2> $MIF317: 2737 <2> ; $DO ;;AN000;; 2738 <2> $MDO321: 2739 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2740 <2> OR AL,AL ;;AN000;; Is it the NULL? 2741 <2> ; $LEAVE Z ;;AN000;; No, 2742 <2> JZ $MEN321 2743 <2> INC DI ;;AN000;; Next character 2744 <2> INC CX ;;AN000;; Increment the count 2745 <2> ; $ENDDO ;;AN000;; Yes, 2746 <2> JMP SHORT $MDO321 2747 <2> $MEN321: 2748 <2> SUB DI,CX ;;AN000;; Set SI at the beginning of the string 2749 <2> ; $ENDIF ;;AN000;; 2750 <2> $MEN317: 2751 <2> ;;AN000;; 2752 <2> PUSH BP ;;AN000;; Restore return address 2753 <2> RET ;;AN000;; Return 2754 <2> ;; 2755 <2> $M_CHAR_REPLACE ENDP ;;AN000;; 2756 <2> ;; 2757 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2758 <2> %ENDIF ;;AN000;; END of include of CHAR replace code 2759 <2> ; 2760 <2> %IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? 2761 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2762 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2763 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2764 <2> ;; 2765 <2> ;; PROC NAME: $M_BIN2ASC_REPLACE 2766 <2> ;; 2767 <2> ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string 2768 <2> ;; and prepare to display 2769 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2770 <2> ;; ES:DI contains the VALUE from SUBLIST 2771 <2> ;; OUTPUTS: CX contains number of characters on stack 2772 <2> ;; Top of stack --> Last character 2773 <2> ;; . . . 2774 <2> ;; Bot of stack --> First character 2775 <2> ;; OTHER REGS Revised: BX,DX,AX 2776 <2> ;; 2777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2778 <2> ;; 2779 <2> $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; 2780 <2> ;; 2781 <2> POP BP ;;AN000;; Save return address 2782 <2> ;; 2783 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2784 <2> XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) 2785 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE16 ;;AN000;; Set default divisor 2786 <2> XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) 2787 <2> %IFN COMR 2788 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_BYTE & $M_SIZE_MASK ;;AN000;; Was BYTE specified? 2789 <2> ; $IF Z ;;AN000;; 2790 <2> JNZ $MIF325 2791 <2> MOV AL, BYTE PTR [ES:DI] ;;AN000;; Setup byte in AL 2792 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2793 <2> ; $IF Z ;;AN000;; 2794 <2> JNZ $MIF326 2795 <2> TEST AL,10000000b ;;AN000;; Is this number negative? 2796 <2> ; $IF NZ ;;AN000;; Yes, 2797 <2> JZ $MIF327 2798 <2> INC BX ;;AN000;; Remember that it was negative 2799 <2> AND AL,01111111b ;;AN000;; Make it positive 2800 <2> ; $ENDIF ;;AN000;; 2801 <2> $MIF327: 2802 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2803 <2> ; $ENDIF ;;AN000;; 2804 <2> $MIF326: 2805 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2806 <2> ; $IF Z ;;AN000;; 2807 <2> JNZ $MIF330 2808 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2809 <2> ; $ENDIF ;;AN000;; 2810 <2> $MIF330: 2811 <2> ; $ELSE ;;AN000;; 2812 <2> JMP SHORT $MEN325 2813 <2> $MIF325: 2814 <2> %ENDIF 2815 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_WORD & $M_SIZE_MASK ;;AN000;; Was WORD specified? 2816 <2> ; $IF Z ;;AN000;; 2817 <2> JNZ $MIF333 2818 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup byte in AL 2819 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;; AN000;; Was Signed binary specified? 2820 <2> ; $IF Z ;;AN000;; 2821 <2> JNZ $MIF334 2822 <2> TEST AH,10000000b ;;AN000;; Is this number negative? 2823 <2> ; $IF NZ ;;AN000;; Yes, 2824 <2> JZ $MIF335 2825 <2> INC BX ;;AN000;; Remember that it was negative 2826 <2> AND AH,01111111b ;;AN000;; Make it positive 2827 <2> ; $ENDIF ;;AN000;; 2828 <2> $MIF335: 2829 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2830 <2> ; $ENDIF ;;AN000;; 2831 <2> $MIF334: 2832 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2833 <2> ; $IF Z ;;AN000;; 2834 <2> JNZ $MIF338 2835 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2836 <2> ; $ENDIF ;;AN000;; 2837 <2> $MIF338: 2838 <2> ; $ELSE ;;AN000;; 2839 <2> JMP SHORT $MEN333 2840 <2> $MIF333: 2841 <2> %IFN COMR 2842 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup Double word in DX:AX 2843 <2> MOV DX, WORD PTR [ES:DI + 2] ;;AN000;; 2844 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2845 <2> ; $IF Z ;;AN000;; 2846 <2> JNZ $MIF341 2847 <2> TEST DH,10000000b ;;AN000;; Is this number negative? 2848 <2> ; $IF NZ ;;AN000;; Yes, 2849 <2> JZ $MIF342 2850 <2> INC BX ;;AN000;; Remember that it was negative 2851 <2> AND DH,01111111b ;;AN000;; Make it positive 2852 <2> ; $ENDIF ;;AN000;; 2853 <2> $MIF342: 2854 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2855 <2> ; $ENDIF ;;AN000;; 2856 <2> $MIF341: 2857 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2858 <2> ; $IF Z ;;AN000;; 2859 <2> JNZ $MIF345 2860 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2861 <2> ; $ENDIF ;;AN000;; 2862 <2> $MIF345: 2863 <2> %ENDIF 2864 <2> ; $ENDIF ;;AN000;; 2865 <2> $MEN333: 2866 <2> ; $ENDIF ;;AN000;; 2867 <2> $MEN325: 2868 <2> ;; 2869 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string 2870 <2> %IFN COMR 2871 <2> OR BX,BX ;;AN000;; 2872 <2> ; $IF NZ ;;AN000;; Was number negative? 2873 <2> JZ $MIF349 2874 <2> XOR DX,DX ;;AN000;; Yes, 2875 <2> MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number 2876 <2> PUSH DX ;;AN000;; 2877 <2> ; $ENDIF ;;AN000;; No, 2878 <2> $MIF349: 2879 <2> %ENDIF 2880 <2> ;; 2881 <2> PUSH BP ;;AN000;; Restore return address 2882 <2> RET ;;AN000;; Return 2883 <2> ;; 2884 <2> $M_BIN2ASC_REPLACE ENDP ;;AN000;; 2885 <2> ;; 2886 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2887 <2> %ENDIF ;;AN000;; END of include of NUM replace code 2888 <2> ; 2889 <2> %IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? 2890 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2891 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2892 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2893 <2> ;; 2894 <2> ;; PROC NAME: $M_DATE_REPLACE 2895 <2> ;; 2896 <2> ;; FUNCTION: Convert a date to a decimal ASCII string using current 2897 <2> ;; country format and prepare to display 2898 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2899 <2> ;; ES:DI points at VALUE from SUBLIST 2900 <2> ;; OUTPUTS: CX contains number of characters on stack 2901 <2> ;; Top of stack --> Last character 2902 <2> ;; . . . 2903 <2> ;; Bot of stack --> First character 2904 <2> ;; OTHER REGS Revised: DX, AX 2905 <2> ;; 2906 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2907 <2> ;; 2908 <2> $M_DATE_REPLACE PROC NEAR ;;AN000;; 2909 <2> ;; 2910 <2> POP BP ;;AN000;; Save return address 2911 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2912 <2> CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT 2913 <2> ;;AN000;; All O.K.? 2914 <2> XOR DX,DX ;;AN000;; Reset DX value 2915 <2> XOR AX,AX ;;AN000;; Reset AX value 2916 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],0 ;;AN000;; USA Date Format 2917 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2918 <2> JNE $MIF351 2919 <2> CALL $M_YEAR ;;AN000;; Get Year 2920 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2921 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2922 <2> INC CX ;;AN000;; Increment count 2923 <2> XOR AX,AX ;;AN000;; Reset AX value 2924 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2925 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2926 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2927 <2> INC CX ;;AN000;; Increment count 2928 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2929 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2930 <2> ; $ENDIF ;;AN000;; 2931 <2> $MIF351: 2932 <2> ;; 2933 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],1 ;;AN000;; EUROPE Date Format 2934 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2935 <2> JNE $MIF353 2936 <2> CALL $M_YEAR ;;AN000;; Get Year 2937 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2938 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2939 <2> INC CX ;;AN000;; 2940 <2> XOR AX,AX ;;AN000;; Reset AX 2941 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2942 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2943 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2944 <2> INC CX ;;AN000;; 2945 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2946 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2947 <2> ; $ENDIF ;;AN000;; 2948 <2> $MIF353: 2949 <2> ;; 2950 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],2 ;;AN000;; JAPAN Date Format 2951 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2952 <2> JNE $MIF355 2953 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2954 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2955 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2956 <2> INC CX ;;AN000;; 2957 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2958 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2959 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2960 <2> INC CX ;;AN000;; 2961 <2> CALL $M_YEAR ;;AN000;; Get Year 2962 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2963 <2> ; $ENDIF ;;AN000;; 2964 <2> $MIF355: 2965 <2> ;; 2966 <2> PUSH BP ;;AN000;; Restore return address 2967 <2> RET ;;AN000;; Return 2968 <2> ;; 2969 <2> $M_DATE_REPLACE ENDP ;;AN000;; 2970 <2> ;; 2971 <2> $M_GET_DATE PROC NEAR ;;AN000;; 2972 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 2973 <2> MOV AL,0 ;;AN000;; Get current country info 2974 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 2975 <2> INT 21H ;;AN000;; 2976 <2> ; $IF C ;;AN000;; No, 2977 <2> JNC $MIF357 2978 <2> MOV WORD [$M_RT + $M_DATE_FORMAT],$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) 2979 <2> MOV BYTE [$M_RT + $M_DATE_SEPARA],$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) 2980 <2> ; $ENDIF ;;AN000;; 2981 <2> $MIF357: 2982 <2> RET ;;AN000;; 2983 <2> $M_GET_DATE ENDP ;;AN000;; 2984 <2> ;; 2985 <2> $M_YEAR PROC NEAR ;;AN000;; 2986 <2> MOV AX,WORD PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Year 2987 <2> TEST byte [$M_SL + $M_S_FLAG],Date_MDY_4 & $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? 2988 <2> ; $IF Z ;;AN000;; 2989 <2> JNZ $MIF359 2990 <2> CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year 2991 <2> ; $IF A ;;AN000;; 2992 <2> JNA $MIF360 2993 <2> MOV AX,$M_MAX_2_YEAR ;;AN000;; 2994 <2> ; $ENDIF ;;AN000;; 2995 <2> $MIF360: 2996 <2> ; $ENDIF ;;AN000;; 2997 <2> $MIF359: 2998 <2> RET ;;AN000;; 2999 <2> $M_YEAR ENDP ;;AN000;; 3000 <2> ;; 3001 <2> $M_CONVERTDATE PROC NEAR ;;AN000;; 3002 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3003 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3004 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3005 <2> DEC CX ;;AN000;; Test if size only grew by 1 3006 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3007 <2> ; $IF E ;;AN000;; Yes, 3008 <2> JNE $MIF363 3009 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3010 <2> PUSH AX ;;AN000;; Save it 3011 <2> INC CX ;;AN000;; Count it 3012 <2> ; $ENDIF ;;AN000;; 3013 <2> $MIF363: 3014 <2> INC CX ;;AN000;; Restore CX 3015 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3016 <2> RET ;;AN000;; 3017 <2> $M_CONVERTDATE ENDP ;;AN000;; 3018 <2> ;; 3019 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3020 <2> %ENDIF ;;AN000;; END of include of DATE replace code 3021 <2> ; 3022 <2> %IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? 3023 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 3024 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 3025 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3026 <2> ;; 3027 <2> ;; PROC NAME: $M_TIME_REPLACE 3028 <2> ;; 3029 <2> ;; FUNCTION: Convert a time to a decimal ASCII string 3030 <2> ;; and prepare to display 3031 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 3032 <2> ;; ES:DI points at VALUE from SUBLIST 3033 <2> ;; OUTPUTS: CX contains number of characters on stack 3034 <2> ;; Top of stack --> Last character 3035 <2> ;; . . . 3036 <2> ;; Bot of stack --> First character 3037 <2> ;; REGS USED: BP,CX,AX 3038 <2> ;; 3039 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3040 <2> ;; 3041 <2> $M_TIME_REPLACE PROC NEAR ;;AN000;; 3042 <2> ;; 3043 <2> POP BP ;;AN000;; Save return address 3044 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 3045 <2> CALL $M_GET_TIME ;;AN000;; All O.K.? 3046 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3047 <2> ; $IF NZ ;;AN000;; Yes, 3048 <2> JZ $MIF365 3049 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3050 <2> ; $IF E ;;AN000;; Yes, 3051 <2> JNE $MIF366 3052 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3053 <2> CMP AL,12 ;;AN000;; Is hour 12 or less? 3054 <2> ; $IF L,OR ;;AN000;; or 3055 <2> JL $MLL367 3056 <2> CMP AL,23 ;;AN000;; Is hour 24 or greater? 3057 <2> ; $IF G ;;AN000;; Yes, 3058 <2> JNG $MIF367 3059 <2> $MLL367: 3060 <2> MOV AL,$M_AM ;;AN000;; 3061 <2> PUSH AX ;;AN000;; Push an "a" to represent AM. 3062 <2> INC CX ;;AN000;; 3063 <2> ; $ELSE ;;AN000;; No, 3064 <2> JMP SHORT $MEN367 3065 <2> $MIF367: 3066 <2> MOV AL,$M_PM ;;AN000;; 3067 <2> PUSH AX ;;AN000;; Push an "p" to represent PM. 3068 <2> INC CX ;;AN000;; 3069 <2> ; $ENDIF ;;AN000;; 3070 <2> $MEN367: 3071 <2> ; $ENDIF ;;AN000;; 3072 <2> $MIF366: 3073 <2> ; $ENDIF ;;AN000;; 3074 <2> $MIF365: 3075 <2> ;; 3076 <2> XOR AX,AX ;;AN000;; 3077 <2> XOR DX,DX ;;AN000;; 3078 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3079 <2> ; $IF NZ ;;AN000;; 3080 <2> JZ $MIF372 3081 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Hundreds 3082 <2> CALL $M_CONVERTTIME ;;AN000;; 3083 <2> PUSH WORD [$M_RT + $M_DECI_SEPARA] ;;AN000;; 3084 <2> INC CX ;;AN000;; 3085 <2> ; $ENDIF ;;AN000;; 3086 <2> $MIF372: 3087 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3088 <2> ; $IF NZ,OR ;;AN000;; 3089 <2> JNZ $MLL374 3090 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSS_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? 3091 <2> ; $IF NZ ;;AN000;; 3092 <2> JZ $MIF374 3093 <2> $MLL374: 3094 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Seconds 3095 <2> CALL $M_CONVERTTIME ;;AN000;; 3096 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3097 <2> INC CX ;;AN000;; 3098 <2> ; $ENDIF ;;AN000;; 3099 <2> $MIF374: 3100 <2> ;; Do Hour/Min (12 Hour) 3101 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+1] ;;AN000;; Get Minutes 3102 <2> CALL $M_CONVERTTIME ;;AN000;; 3103 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3104 <2> INC CX ;;AN000;; 3105 <2> ;; 3106 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3107 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3108 <2> ; $IF NZ ;;AN000;; Yes, 3109 <2> JZ $MIF376 3110 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3111 <2> ; $IF E ;;AN000;; Yes, 3112 <2> JNE $MIF377 3113 <2> CMP AL,13 ;;AN000;; Is hour less than 12? 3114 <2> ; $IF GE ;;AN000;; Yes, 3115 <2> JNGE $MIF378 3116 <2> SUB AL,12 ;;AN000;; Set to a 12 hour value 3117 <2> ; $ENDIF ;;AN000;; 3118 <2> $MIF378: 3119 <2> CMP AL,0 ;;AN000;; Is hour less than 12? 3120 <2> ; $IF E ;;AN000;; Yes, 3121 <2> JNE $MIF380 3122 <2> MOV AL,12 ;;AN000;; Set to a 12 hour value 3123 <2> ; $ENDIF ;;AN000;; 3124 <2> $MIF380: 3125 <2> ; $ENDIF ;;AN000;; 3126 <2> $MIF377: 3127 <2> ; $ENDIF ;;AN000;; 3128 <2> $MIF376: 3129 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII 3130 <2> ;; 3131 <2> PUSH BP ;;AN000;; Restore return address 3132 <2> RET ;;AN000;; Return 3133 <2> ;; 3134 <2> $M_TIME_REPLACE ENDP ;;AN000;; 3135 <2> ;; 3136 <2> $M_GET_TIME PROC NEAR ;;AN000;; 3137 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 3138 <2> MOV AL,0 ;;AN000;; Get current country info 3139 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 3140 <2> INT 21H ;;AN000;; 3141 <2> ; $IF C ;;AN000;; No, 3142 <2> JNC $MIF384 3143 <2> MOV WORD [$M_RT + $M_TIME_FORMAT],$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) 3144 <2> MOV BYTE [$M_RT + $M_TIME_SEPARA],$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) 3145 <2> MOV BYTE [$M_RT + $M_DECI_SEPARA],$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) 3146 <2> ; $ENDIF ;;AN000;; 3147 <2> $MIF384: 3148 <2> RET ;;AN000;; 3149 <2> $M_GET_TIME ENDP ;;AN000;; 3150 <2> ;; 3151 <2> $M_CONVERTTIME PROC NEAR ;;AN000;; 3152 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3153 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3154 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3155 <2> DEC CX ;;AN000;; Test if size only grew by 1 3156 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3157 <2> ; $IF E ;;AN000;; Yes, 3158 <2> JNE $MIF386 3159 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3160 <2> PUSH AX ;;AN000;; Save it 3161 <2> INC CX ;;AN000;; Count it 3162 <2> ; $ENDIF ;;AN000;; 3163 <2> $MIF386: 3164 <2> INC CX ;;AN000;; Restore CX 3165 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3166 <2> RET ;;AN000;; 3167 <2> $M_CONVERTTIME ENDP ;;AN000;; 3168 <2> ;; 3169 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3170 <2> %ENDIF ;;AN000;; END of include of TIME replace 3171 <2> %ENDIF ;;AN000;; END of include of Replacement common code 3172 <2> ; 3173 <2> %IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? 3174 <2> INPUTmsg equ FALSE ;;AN000;; Yes, THEN include it and reset the flag 3175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3176 <2> ;; 3177 <2> ;; PROC NAME: $M_WAIT_FOR_INPUT 3178 <2> ;; 3179 <2> ;; FUNCTION: To accept keyed input and return extended key value 3180 <2> ;; in AX register 3181 <2> ;; INPUTS: DL contains the DOS function requested for input 3182 <2> ;; OUPUTS: AX contains the extended key value that was read 3183 <2> ;; REGS USED: 3184 <2> ;; 3185 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3186 <2> ;; 3187 <2> $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; 3188 <2> ;; 3189 <2> PUSH CX ;;AN000;; Save CX 3190 <2> PUSH DX ;;AN000;; Save DX 3191 <2> PUSH DS ;;AN000;; Save Data segment 3192 <2> ;; 3193 <2> CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? 3194 <2> ; $IF A ;;AN001;; Yes, 3195 <2> JNA $MIF388 3196 <2> MOV AL,DL ;;AN001;; Mov function into AL 3197 <2> AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble 3198 <2> MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function 3199 <2> ; $ELSE ;;AN001;; No, 3200 <2> JMP SHORT $MEN388 3201 <2> $MIF388: 3202 <2> MOV AH,DL ;;AN000;; Put DOS function in AH 3203 <2> ; $ENDIF ;;AN001;; 3204 <2> $MEN388: 3205 <2> PUSH ES ;;AN000;; Get output buffer segment 3206 <2> POP DS ;;AN000;; 3207 <2> MOV DX,DI ;;AN000;; Get output buffer offset in case needed 3208 <2> INT 21H ;;AN000;; Get keyboard input 3209 <2> POP DS ;;AN000;; 3210 <2> 3211 <2> CMP DL,DOS_BUF_KEYB_INP ;;AN000;; 3212 <2> CLC ;;AN000;; 3213 <2> ; $IF NE ;;AN000;; If character input 3214 <2> JE $MIF391 3215 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? 3216 <2> ; $IF C ;;AN000;; 3217 <2> JNC $MIF392 3218 <2> MOV CL,AL ;;AN000;; Save first character 3219 <2> MOV AH,DL ;;AN001;; Get back function 3220 <2> INT 21H ;;AN000;; Get keyboard input 3221 <2> MOV AH,CL ;;AN000;; Retreive first character AX = xxxx 3222 <2> CLC ;;AN000;; Clear carry condition 3223 <2> ; $ELSE ;;AN000;; 3224 <2> JMP SHORT $MEN392 3225 <2> $MIF392: 3226 <2> MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS 3227 <2> ; $ENDIF ;;AN000;; 3228 <2> $MEN392: 3229 <2> ; $ENDIF ;;AN000;; 3230 <2> $MIF391: 3231 <2> ;; 3232 <2> ; $IF NC ;;AN000;; 3233 <2> JC $MIF396 3234 <2> POP DX ;;AN000;; 3235 <2> POP CX ;;AN000;; 3236 <2> ; $ELSE ;;AN000;; 3237 <2> JMP SHORT $MEN396 3238 <2> $MIF396: 3239 <2> ADD SP,4 ;;AN000;; 3240 <2> STC ;;AN000;; Reset carry flag 3241 <2> ; $ENDIF ;;AN000;; 3242 <2> $MEN396: 3243 <2> RET ;;AN000;; Return 3244 <2> ;; 3245 <2> $M_WAIT_FOR_INPUT ENDP ;;AN000;; 3246 <2> ;; 3247 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3248 <2> %ENDIF ;;AN000;; END of include of Wait for Input 3249 <2> %ENDIF ;;AN000;; END of include of SYSDISPMSG 3250 <2> %ENDIF ;;AN000;; END of include of MSG_DATA_ONLY 3251 <2> %ENDIF ;;AN000;; END of include of Structure only 3252 <2> 3253 <2> ;=== Pop trace listing source 3254 <2> 331 <1> 27 28 ShareDataVersion equ 1 29 30 %ifndef IBM 31 %iassign IBM 0 32 %endif 33 %ifndef Installed 34 %iassign Installed 0 35 %endif 36 37 %iassign Installed TRUE ; for installed version 38 39 ; NASM original macros 40 41 %imacro OFF 2.nolist 42 %if Installed 43 mov %1, offset %2 44 %else 45 mov %1, offset %2 wrt DOSGROUP 46 %endif 47 %endmacro 48 49 %unimacro detectstripangles 4.nolist 50 51 %imacro detectstripangles 4.nolist 52 %defstr %%param %4 53 %assign ?%2 0 54 %assign ?%3 0 55 %rep 16 56 %substr %%opening %%param 1 57 %ifidn %%opening, '<' 58 %substr %%param %%param 2,-1 59 %assign ?%2 ?%2 + 1 60 %endif 61 %endrep 62 %rep 16 63 %strlen %%length %%param 64 %substr %%closing %%param %%length 65 %ifidn %%closing, '>' 66 %substr %%param %%param 1,-2 67 %assign ?%3 ?%3 + 1 68 %endif 69 %endrep 70 %deftok %%token %%param 71 %define ?%1 %%token 72 %endmacro 73 74 %unimacro errnz 1.nolist 75 76 %imacro errnz 1.nolist 77 detectstripangles %%token, %%opening, %%closing, %1 78 %if ? %+ %%token 79 %error %1 <> 0, ERRNZ failed 80 %endif 81 %endmacro 82 83 ; end of NASM original macros 84 85 mft equ MFT ; NASM port label 86 quux equ mft 87 88 ;--------------------------------------- 89 ; if we are installed, then define the 90 ; base code segment of the sharer first 91 ;--------------------------------------- 92 ; $SALUT (4,9,17,36) 93 94 %IF Installed 95 === Switch to base=000000h -> "SHARE" 96 section SHARE 97 ; (no prior section) ; Share ENDS 98 99 %ENDIF 100 101 ;--------------------------------------- 102 ; include the rest of the segment 103 ; definitions for normal msdos 104 105 ; segment ordering for MSDOS 106 107 ;--------------------------------------- 108 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> 2 <2> %include "lmacros3.mac" 1 <3> [list -] 1 ****************** <3> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <4> [list -] 14 <3> [list -] 3 <2> === Switch to base=001DC0h -> "DOSSTART" 4 <2> addsection DOSSTART, align=16 PUBLIC class=DOSSTART 5 <2> ; (no prior section) ; DOSSTART ENDS 6 <2> === Switch to base=001DC0h -> "DOSSTARTJUMP" 7 <2> addsection DOSSTARTJUMP, align=1 PUBLIC class=START 8 <2> ; (no prior section) ; DOSSTARTJUMP ENDS 9 <2> === Switch to base=001DC0h -> "CONSTANTS" 10 <2> addsection CONSTANTS, align=2 PUBLIC class=CONST 11 <2> ; (no prior section) ; CONSTANTS ENDS 12 <2> === Switch to base=001DC0h -> "DATA" 13 <2> addsection DATA, align=2 PUBLIC class=DATA 14 <2> ; (no prior section) ; DATA ENDS 15 <2> === Switch to base=001DC0h -> "TABLE" 16 <2> addsection TABLE, align=2 PUBLIC class=TABLE 17 <2> ; (no prior section) ; TABLE ENDS 18 <2> === Switch to base=001DC0h -> "DOSDATATABLE" 19 <2> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE 20 <2> ; (no prior section) ; DOSDATATABLE ENDS 21 <2> === Switch to base=001DC0h -> "DOSDATACODE" 22 <2> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE 23 <2> ; (no prior section) ; DOSDATACODE ENDS 24 <2> === Switch to base=001DC0h -> "DOSBIODATA" 25 <2> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA 26 <2> === Switch to base=001DC0h -> "LAST" 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 31 <2> 32 <2> %include "entryseg.nas" 1 <3> 2 <3> %ifndef ENTRYSEGNAS 3 <3> %define ENTRYSEGNAS 1 4 <3> 5 <3> %include "lmacros3.mac" 1 <4> [list -] 6 <3> === Switch to base=003490h -> "DOSENTRY" 7 <3> addsection DOSENTRY, class=%[DOSENTRY] 8 <3> 9 <3> group DOSENTRYGROUP DOSENTRY 10 <3> 11 <3> %endif 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=003490h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001DC0h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 109 === Switch to base=001DC0h -> "CONSTANTS" 110 section CONSTANTS 111 112 extrn DataVersion:BYTE ; version number of DOS data. 113 extrn JShare:BYTE ; location of DOS jump table. 114 extrn sftFCB:DWORD ; [SYSTEM] pointer to FCB cache table 115 extrn KeepCount:WORD ; [SYSTEM] LRU count for FCB cache 116 extrn CurrentPDB:WORD 117 118 ; (no prior section) ; CONSTANTS ENDS 119 === Switch to base=001DC0h -> "DATA" 120 section DATA 121 122 extrn ThisSFT:DWORD ; pointer to SFT entry 123 extrn WFP_start:WORD ; pointer to name string 124 extrn User_ID:WORD 125 extrn Proc_ID:WORD 126 extrn SFT_addr:DWORD 127 extrn Arena_Head:WORD 128 extrn fshare:BYTE 129 extrn pJFN:DWORD 130 extrn JFN:WORD 131 132 %IF DEBUG 133 134 extrn BugLev:WORD 135 extrn BugTyp:WORD 136 %include "bugtyp.nas" 137 138 %ENDIF 139 140 141 ; (no prior section) ; DATA ENDS 142 143 ;--------------------------------------- 144 ; if we are not installed, then the 145 ; code here is just part of the normal 146 ; MSDOS code segment otherwise, 147 ; define our own code segment 148 ;--------------------------------------- 149 150 ; .sall 151 ; %IF INSTALLED 152 === Switch to base=000000h -> "SHARE" 153 section SHARE 154 155 ASSUME SS:DOSGROUP,CS:SHARE 156 157 ; %ELSE 158 ; 159 ;section CODE align=1 PUBLIC class=CODE 160 ; 161 ; ASSUME SS:DOSGROUP,CS:DOSGROUP 162 ; 163 ; %ENDIF 164 165 Extrn FreLock:WORD,Serial:WORD 166 Extrn MFT_Enter:NEAR,MFTClose:NEAR,MFTClu:NEAR,MFTCloseP:NEAR 167 Extrn MFTCloN:NEAR 168 Extrn Set_Mult_Block:NEAR,Clr_Mult_Block:NEAR,Chk_Block:NEAR 169 Extrn MFT_Get:NEAR 170 171 [list -] 174 175 ; $SALUT (4,4,9,41) 176 177 BREAK 178 179 ;******************* START OF SPECIFICATIONS *********************************** 180 ; 181 ; FNM - Find name in MFT 182 ; 183 ; FNM searches the MFT for a name record. 184 ; 185 ; ENTRY (DS:SI) = pointer to name string (.asciz) 186 ; (al) = 1 to create record if non exists 187 ; = 0 otherwise 188 ; EXIT 'C' clear if found or created 189 ; (DS:BX) = address of MFT name record 190 ; 'C' set if error 191 ; If not to create, item not found 192 ; (DS:SI) unchanged 193 ; If to create, am out of space 194 ; (ax) = error code 195 ; USES ALL 196 ; 197 ;******************* END OF SPECIFICATIONS ************************************* 198 199 Procedure FNM,NEAR 199 ****************** warning: proc FNM... [-w+user] 200 0 00000488 1E push ds ; save string address 0 00000489 56 push si 0 0000048A 86F8 xchg bh,al ; (bh) = create flag 0 0000048C 08FF or bh,bh ; if not creating 0 0000048E 7400 jz fnm01 ; skip sft test 206 207 ;--------------------------------------- 208 ; run down through string counting 209 ; and summing 210 ;--------------------------------------- 211 0 00000490 29D2 fnm01: sub dx,dx ; (dx) = byte count 0 00000492 28DB sub bl,bl ; (bl) = sum 214 0 00000494 AC fnm1: lodsb ; (al) = next char 0 00000495 00C3 add bl,al 0 00000497 80D300 adc bl,0 0 0000049A 42 inc dx 0 0000049B 20C0 and al,al 0 0000049D 75F5 jnz fnm1 ; terminate after null char 221 222 ;--------------------------------------- 223 ; Info computed. 224 ; Start searching name list 225 226 ; (bh) = create flag 227 ; (bl) = sum byte 228 ; (dx) = byte count 229 ; (TOS+2:TOS) = name string address 230 ;--------------------------------------- 231 ; Magic code for DOSREINIT start ! 0 0000049F 0E push cs 0 000004A0 1F pop ds 234 0 000004A1 BE[2F06] Off SI,mft 236 0 000004A4 803C00 fnm2: cmp byte [si + mft_flag],MFLG_FRE 238 ; Magic code for DOSREINIT end ! 0 000004A7 7C21 jl fnm10 ; at end - name not found 0 000004A9 7405 jz fnm4 ; is free, just skip it 0 000004AB 3A5C03 cmp bl,[si + mft_sum] ; do sums compare? 0 000004AE 7405 jz fnm5 ; its a match - look further 0 000004B0 037401 fnm4: add si,[si + mft_len] ; not a match... skip it 0 000004B3 EBEF JMP SHORT fnm2 245 ;--------------------------------------- 246 ; name checksums match 247 ; - compare the actual strings 248 ; 249 ; (dx) = length 250 ; (ds:si = MFT address 251 ; (bh) = create flag 252 ; (bl) = sum byte 253 ; (dx) = byte count 254 ; (TOS+2:TOS) = name string address 255 ;--------------------------------------- 256 0 000004B5 89D1 fnm5: mov cx,dx ; (cx) = length to match 0 000004B7 5F pop di 0 000004B8 07 pop es ; (ES:DI) = fba given name 0 000004B9 06 push es 0 000004BA 57 push di 0 000004BB 56 push si ; save MFT offset 0 000004BC 83C60C add si,mft_name ; (ds:si) = fwa string in record 0 000004BF F3A6 repz cmpsb 0 000004C1 5E pop si ; (ds:si) = fwa name record 0 000004C2 75EC jnz fnm4 ; not a match 267 268 ;--------------------------------------- 269 ; Yes, we've found it. Return the info 270 ; 271 ; (TOS+2:TOS) = name string address 272 ;--------------------------------------- 273 274 fmt TypShare,LevMFTSrch,<"FNM found name record at $x\n">, 0 000004C4 58 pop ax ; discard unneeded stack stuff 0 000004C5 58 pop ax 0 000004C6 89F3 mov bx,si ; (ds:bx) = fwa name record 0 000004C8 F8 clc 279 0 000004C9 C3 ret 281 ;--------------------------------------- 282 ;** 283 ;** Its not in the list 284 ;** - lets find a free spot and put 285 ;** it there 286 ; 287 ; (bh) = create flag 288 ; (bl) = sum byte 289 ; (dx) = string length 290 ; (TOS+2:TOS) = ASCIZ string address 291 ; (ds) = SEG CODE 292 ;--------------------------------------- 293 fnm10: 0 000004CA 20FF and bh,bh 0 000004CC 7507 jnz fnm10$5 ; yes, insert it 0 000004CE 5E pop si 0 000004CF 1F pop ds ; no insert, its a "not found" 0 000004D0 F9 stc 299 300 fmt TypShare,LevMFTSrch,<"FNM failing\n"> 301 0 000004D1 B80300 mov ax,error_path_not_found 303 0 000004D4 C3 ret 305 306 fnm10$5: 0 000004D5 83C20C add dx,mft_name ; (dx) = minimum space needed 308 0 000004D8 BE[2F06] off SI,mft 310 0 000004DB 803C00 fnm11: cmp byte [si + mft_flag],MFLG_FRE 312 313 %IFN DEBUG 0 000004DE 7C57 jl fnm20 ; at END, am out of space 315 %ELSE 316 jl fnm20j 317 %ENDIF 318 0 000004E0 7405 jz fnm12 ; is a free record 0 000004E2 037401 add si,[si + mft_len] ; skip name record 0 000004E5 EBF4 JMP SHORT fnm11 322 323 %IF DEBUG 324 fnm20j: jmp fnm20 325 %ENDIF 326 0 000004E7 8B4401 fnm12: mov ax,[si + mft_len] ; Have free record, (ax) = total length 0 000004EA 39D0 cmp ax,dx 0 000004EC 7304 jnc fnm13 ; big enough 0 000004EE 01C6 add si,ax 0 000004F0 EBE9 JMP SHORT fnm11 ; not large enough - move on 332 333 ;--------------------------------------- 334 ; OK, we have a record which is big 335 ; enough. If its large enough to hold 336 ; another name record of 6 characters 337 ; than we'll split the block, else 338 ; we'll just use the whole thing 339 ; 340 ; (ax) = size of free record 341 ; (dx) = size needed 342 ; (ds:si) = address of free record 343 ; (bl) = sum byte 344 ; (TOS+2:TOS) = name string address 345 ;--------------------------------------- 346 0 000004F2 29D0 fnm13: sub ax,dx ; (ax) = total size of proposed fragment 0 000004F4 83F812 cmp ax,mft_name+6 0 000004F7 720C jc fnm14 ; not big enough to split 0 000004F9 53 push bx ; save sum byte 0 000004FA 89D3 mov bx,dx ; (bx) = offset to start of new name record 0 000004FC C60000 mov byte [bx + si + mft_flag],MFLG_FRE 0 000004FF 894001 mov [bx + si + mft_len],ax ; setup tail as free record 0 00000502 29C0 sub ax,ax ; don't extend this record 0 00000504 5B pop bx ; restore sum byte 0 00000505 01C2 fnm14: add dx,ax ; (dx) = total length of this record 0 00000507 895401 mov [si + mft_len],dx 0 0000050A 885C03 mov [si + mft_sum],bl 0 0000050D C60401 mov byte [si + mft_flag],MFLG_NAM 360 361 fmt TypShare,LevMFTSrch,<"FNM creating record at $x\n">, 362 0 00000510 1E push ds 0 00000511 07 pop es ; (es) = MFT segment for "stow" 0 00000512 29C0 sub ax,ax 0 00000514 89F7 mov di,si 0 00000516 83C704 add di,mft_lptr 0 00000519 AB stosw ; zero LCK pointer 369 ERRNZ mft_sptr-mft_lptr-2 370 ; add di,mft_sptr-mft_lptr-2 0 0000051A AB stosw ; zero SFT pointer 0 0000051B AB stosw ; zero SFT pointer 373 serial equ Serial ; NASM port label 0 0000051C 2EFF06[0000] inc word [cs:serial] ; bump serial number 0 00000521 2EA1[0000] mov ax,[cs:serial] 376 ERRNZ mft_serl-mft_sptr-4 377 ; ADD di,mft_serl-mft_sptr-4 0 00000525 AB stosw 379 ;--------------------------------------- 380 ; We're all setup except for the name. 381 ; Note that we'll block copy the whole 382 ; name field, even though the name may 383 ; be shorter than that (we may have 384 ; declined to fragment this memory block) 385 ; 386 ; (dx) = total length of this record 387 ; (ds:si) = address of working record 388 ; (es) = (ds) 389 ; (TOS+2:TOS) = name string address 390 ;--------------------------------------- 0 00000526 89D1 mov cx,dx 0 00000528 83E90C sub cx,mft_name ; compute total size of name area 393 ERRNZ mft_name-mft_serl-2 394 ; add di,mft_name-mft_serl-2 ; (ES:DI) = target address 0 0000052B 89F0 mov ax,si ; save name record offset 0 0000052D 5E pop si 0 0000052E 1F pop ds 0 0000052F F3A4 rep movsb 0 00000531 89C3 mov bx,ax ; (bx) = name record offset 0 00000533 06 push es 0 00000534 1F pop ds ; (DS:BX) = name record offset 0 00000535 F8 clc 403 0 00000536 C3 ret 405 406 ;** 407 ;** OUT OF FREE SPACE 408 ;** 409 ;** This is tough, folks. Lets trigger a garbage collection and see if 410 ;** there is enough room. If there is, we'll hop back and relook for a 411 ;** free hunk; if there isnt enough space, its error-city! 412 ; 413 ; WARNING: it is important that the garbage collector be told how big a 414 ; name record hole we're looking for... if the size given GCM 415 ; is too small we'll loop doing "no space; collect; no space; 416 ; ...) 417 ; 418 ; (dx) = total length of desired name record 419 ; (ds) = SEG CODE 420 ; (bl) = sum byte 421 ; (TOS+2:TOS) = name string address 422 423 fnm20: 0 00000537 89D0 mov ax,dx ; (ax) = size wanted 0 00000539 83EA0C sub dx,mft_name ; (dx) = string length for reentry at fnm10 0 0000053C 52 push dx 0 0000053D 53 push bx 0 0000053E E80B00 call GCM ; garbage collect MFT 0 00000541 5B pop bx 0 00000542 5A pop dx 431 432 %IF DEBUG 433 jnc fnm10j 434 %ELSE 0 00000543 7385 jnc fnm10 ; go back and find that space 436 %ENDIF 437 438 ;--------------------------------------- 439 ; no space, return w/error 440 ;--------------------------------------- 441 0 00000545 58 fnm50: pop ax 0 00000546 58 pop ax ; clean stack 0 00000547 B82400 mov ax,error_sharing_buffer_exceeded 0 0000054A F9 stc 446 0 0000054B C3 ret 448 449 %IF DEBUG 450 fnm10j: jmp fnm10 451 %ENDIF 452 453 EndProc FNM 454 455 BREAK 456 457 ;******************* START OF SPECIFICATIONS *********************************** 458 ; 459 ; GCM - Garbage Collect MFT 460 ; 461 ; GCM runs down the MFT structure squeezing out the free space and 462 ; putting it into one free block at the end. This is a traditional heap 463 ; collection process. We must be sure to update the pointer in the 464 ; SFTs. This presumes no adjacent free blocks. 465 ; 466 ; ENTRY (ax) = space desired in last free block 467 ; (DS) + SEG CODE 468 ; EXIT 'C' clear if enough space in block 469 ; 'C' set if not enough space 470 ; 471 ;******************* END OF SPECIFICATIONS ************************************* 472 473 Procedure GCM,NEAR 473 ****************** warning: proc GCM... [-w+user] 474 0 0000054C 50 push ax ; save target 0 0000054D BE[2F06] off si,mft ; (si) = from pointer 0 00000550 89F7 mov di,si ; (di) = to pointer 478 479 ;--------------------------------------- 480 ; (DI) points to the beginning of 481 ; a free space block 482 ; (SI) points to the next block. 483 ;--------------------------------------- 484 0 00000552 8B4C01 gcm1: mov cx,[si + mft_len] ; (cx) = size of whatever it is 0 00000555 803C00 cmp byte [si + mft_flag],MFLG_FRE 0 00000558 7C3D jl gcm10 ; END marker 0 0000055A 750B jnz gcm2 ; have a name record 489 490 ;--------------------------------------- 491 ; (SI) points to a free block. 492 ; We coalesce it by changing the size. 493 ;--------------------------------------- 0 0000055C 39FE cmp si,di 0 0000055E 7403 jz gcm15 ; do NOT coalesce a block with itself 0 00000560 014D01 add [di + mft_len],cx ; coalesce 497 gcm15: 0 00000563 01CE add si,cx ; skip the empty one 0 00000565 EBEB JMP SHORT gcm1 500 ;--------------------------------------- 501 ; (SI) points to a non-free, 502 ; non-last block. 503 ; (DI) points to the beginning of a 504 ; free block. 505 ; 506 ; We move the non-free block down over 507 ; the free block 508 ;--------------------------------------- 0 00000567 39FE gcm2: cmp si,di 0 00000569 7506 jnz gcm3 ; have to copy 511 512 ;--------------------------------------- 513 ; SI = DI => we are at a boundary 514 ; between allocated blocks. 515 ; We do no copying. 516 ;--------------------------------------- 0 0000056B 01CE add si,cx 0 0000056D 89F7 mov di,si ; no emptys yet... no need to copy 0 0000056F EBE1 JMP SHORT gcm1 520 ;--------------------------------------- 521 ; CX is length of allocated block. 522 ; - Move it 523 ;--------------------------------------- 524 0 00000571 89FB gcm3: mov bx,di ; (DS:BX) = new home for this record 0 00000573 8CD8 mov ax,ds 0 00000575 8EC0 mov es,ax 0 00000577 F3A4 rep movsb 529 ;--------------------------------------- 530 ; We've moved the record, now fix up 531 ; the pointers in the SFT chain 532 ; 533 ; (si) = address of next record 534 ; (di) = address of next free byte 535 ; (bx) = address of record in its new home 536 ; (TOS) = needed space 537 ;--------------------------------------- 0 00000579 57 push di 0 0000057A 1E push ds 0 0000057B C57F06 lds di,[bx + mft_sptr] ; (ds:di) = chain of SFT 0 0000057E 09FF gcm4: or di,di 0 00000580 7408 jz gcm5 ; no more SFT 543 sf_mft equ sf_MFT ; NASM port equate 0 00000582 895D33 mov [di + sf_mft],bx ; install new MFT position 0 00000585 C57D2B lds di,[di + sf_chain] ; link to next 0 00000588 EBF4 JMP gcm4 ; fix next SFT 547 0 0000058A 1F gcm5: pop ds 0 0000058B 5F pop di 550 ;--------------------------------------- 551 ; (DI) points to beginning of 552 ; new free record (moved) 553 ; (SI) points to next record 554 ; 555 ; Make sure that the (DI) record 556 ; has correct format 557 ;--------------------------------------- 558 0 0000058C C60500 mov byte [di + mft_flag],MFLG_FRE ; indicate free record 0 0000058F 897501 mov [di + mft_len],si ; calculate correct length 0 00000592 297D01 sub [di + mft_len],di 562 ;--------------------------------------- 563 ; MFT now has correct record structure. 564 ; Go find more free blocks 565 ;--------------------------------------- 0 00000595 EBBB JMP SHORT gcm1 567 ;--------------------------------------- 568 ; We have scanned the entire table, 569 ; compacting all empty records together. 570 ; 571 ; (di) = first free byte in table 572 ; (si) = address of END record 573 ; (TOS) = size needed 574 ; 575 ; Be extra careful!!! 576 ;--------------------------------------- 0 00000597 89F0 gcm10: mov ax,si 0 00000599 29F8 sub ax,di ; (ax) = free space 0 0000059B 5B pop bx ; (bx) = space wanted 0 0000059C 29D8 sub ax,bx 581 0 0000059E C3 ret 583 584 EndProc GCM 585 586 BREAK 587 588 ;******************* START OF SPECIFICATIONS *********************************** 589 ; 590 ; RMN - Remove MFT Name record 591 ; 592 ; RMN removes a name record from the MFT list. The record is marked 593 ; free and all free space is coalesced. 594 ; 595 ; ENTRY (DS:BX) = FBA MFT name record 596 ; EXIT to INTERR if lock and SFT chains are not empty 597 ; USES ALL 598 ; 599 ;******************* END OF SPECIFICATIONS ************************************* 600 601 Procedure RMN,NEAR 601 ****************** warning: proc RMN... [-w+user] 602 0 0000059F 89DE mov si,bx 0 000005A1 8B4406 mov ax,word ptr [si + mft_sptr] 0 000005A4 0B4404 or ax,word ptr [si + mft_lptr] 0 000005A7 7509 jnz RMNIER1 ; not clean - internal error 0 000005A9 89DE mov si,bx ; (ds:si) = fwa name record 608 0 000005AB C60400 mov byte [si + mft_flag],MFLG_FRE ; mark free 610 611 mrg equ MRG ; NASM port label 0 000005AE E82400 call mrg ; coalesce all free space 613 0 000005B1 C3 ret 615 0 000005B2 50 RMNIER1:push ax 0 000005B3 B8[3101] off ax,rmnerr1 618 0 000005B6 E8E103 RMNIER: call INTERR ; internal error 620 0 000005B9 524D4E3A2053465420 rmnerr1 db "RMN: SFT LCK fields not 0", 13, 10, 0 0 000005C2 4C434B206669656C64 0 000005CB 73206E6F7420300D0A 0 000005D4 00 622 623 EndProc RMN 624 625 Break 626 627 ;******************* START OF SPECIFICATIONS *********************************** 628 ; 629 ; MRG - merge all free space 630 ; 631 ; MRG - walk through mft merging adjacent free space. 632 ; 633 ; Inputs: ds = CS 634 ; Outputs: none (all free space coalesced) 635 ; Registers Revised: none 636 ; 637 ;******************* END OF SPECIFICATIONS ************************************* 638 639 Procedure MRG,near 639 ****************** warning: proc MRG... [-w+user] 640 641 assume ds:nothing,es:nothing 642 0 000005D5 56 push si 0 000005D6 53 push bx 645 0 000005D7 BE[2F06] off si,mft ; start at beginning 0 000005DA 8B5C01 mrg1: mov bx,[si + mft_len] ; get length 0 000005DD 803C00 cmp byte [si + mft_flag],MFLG_FRE ; is record free? 0 000005E0 7C13 jl mrg9 ; done. 0 000005E2 7404 jz mrg2 ; yes, try to merge with next 0 000005E4 01DE mrg15: add si,bx ; advance to next 0 000005E6 EBF2 jmp mrg1 653 ;--------------------------------------- 654 ; (si) points to free record. 655 ; - See if next is free 656 ;--------------------------------------- 0 000005E8 803800 mrg2: cmp byte [bx + si + mft_flag],MFLG_FRE 0 000005EB 75F7 jnz mrg15 ; not free, go scan again 0 000005ED 8B5801 mov bx,[bx + si + mft_len] ; get length of next guy 0 000005F0 015C01 add [si + mft_len],bx ; increase our length 0 000005F3 EBE5 jmp mrg1 ; and check again 0 000005F5 5B mrg9: pop bx 0 000005F6 5E pop si 664 0 000005F7 C3 ret 666 667 EndProc MRG 668 669 BREAK 670 671 ;******************* START OF SPECIFICATIONS *********************************** 672 ; 673 ; RSC - Remove SFT from SFT chain 674 ; 675 ; RSC removes a given SFT from its chain. The caller must insure that 676 ; any locks have been cleared and that the SFT is indeed free. The 677 ; sf_mft field is zeroed to indicate that this SFT is no longer chained. 678 ; 679 ; NOTE - RSC does NOT remove the name record if this was the last SFT on 680 ; it. The caller must check for this and remove it, if 681 ; necessary. 682 ; 683 ; ENTRY (ES:DI) = SFT address 684 ; EXIT (DS:BX) = FBA name record for this SFT 685 ; 'Z' set if this is the last SFT 686 ; USES ALL 687 ; 688 ;******************* END OF SPECIFICATIONS ************************************* 689 690 Procedure RSC,NEAR 690 ****************** warning: proc RSC... [-w+user] 691 0 000005F8 0E push cs 0 000005F9 1F pop ds 694 0 000005FA 8CC0 mov ax,es ; easy spot for compare 0 000005FC 268B5D33 mov bx,[es:di + sf_mft] 0 00000600 8D77DB lea si,[bx + mft_sptr - sf_chain] ; [ds:si].sf_chain point to prev link 0 00000603 09F6 rsc1: or si,si 0 00000605 742A jz rscier 0 00000607 397C2B cmp word ptr [si + sf_chain],di 0 0000060A 7505 jnz rsc15 0 0000060C 39442D cmp word ptr [si + sf_chain + 2],ax 0 0000060F 7405 jz rsc2 0 00000611 C5742B rsc15: lds si,[si + sf_chain] 0 00000614 EBED jmp rsc1 706 ;--------------------------------------- 707 ; (es:di) is sft 708 ; (ds:si) is prev sft link 709 ;--------------------------------------- 0 00000616 268B452B rsc2: mov ax,word ptr [es:di + sf_chain] 0 0000061A 89442B mov word ptr [si + sf_chain],ax 0 0000061D 268B452D mov ax,word ptr [es:di + sf_chain + 2] 0 00000621 89442D mov word ptr [si + sf_chain + 2],ax 714 0 00000624 0E push cs 0 00000625 1F pop ds 0 00000626 31DB xor bx,bx 0 00000628 26875D33 xchg bx,[es:di + sf_MFT] ; (DS:bx) = MFT address 719 ; and 0 MFT pointer (show free) 0 0000062C 837F0600 cmp word ptr [bx + mft_sptr],0 ; set z flag if no more sft 721 0 00000630 C3 ret 723 0 00000631 50 rscier: push ax 0 00000632 B8[B001] off ax,rscerr 726 727 interr equ INTERR ; NASM port label 0 00000635 E86203 call interr 729 0 00000638 5253433A2053465420 rscerr db "RSC: SFT not in SFT list", 13, 10, 0 0 00000641 6E6F7420696E205346 0 0000064A 54206C6973740D0A00 731 732 EndProc RSC 733 734 BREAK 735 736 ;******************* START OF SPECIFICATIONS *********************************** 737 ; 738 ; SLE - Scan for Lock Entry 739 ; 740 ; SLE scans a lock list looking for a lock range that overlaps the 741 ; caller-supplied range. SLE indicates: 742 ; 743 ; no overlap 744 ; partial overlay 745 ; 1-to-1 match 746 ; 747 ; ENTRY (AX:BX) = FBA of area 748 ; (CX:DX) = LBA of area 749 ; (DS:SI) = address of name record 750 ; (DI) = 0 to ignore locks by User_ID Proc_ID ThisSFT 751 ; = 1 to consider all locks 752 ; EXIT 'C' clear if no overlap 753 ; AX,BX,CX,DX preserved 754 ; 'C' set if overlap 755 ; (di) = address of pointer to found record 756 ; (i.e., DS:((di)) = address of lock record) 757 ; 'Z' set if 1-to-1 match 758 ; USES ALL but (ds), (es) (also see EXIT) 759 ; 760 ;******************* END OF SPECIFICATIONS ************************************* 761 762 Procedure SLE,NEAR 762 ****************** warning: proc SLE... [-w+user] 763 0 00000653 06 push es 0 00000654 21FF and di,di 0 00000656 9C pushf ; Z set to ignore own locks 0 00000657 8D7C04 lea di,[si + mft_lptr] ; (ds:di) = addr of ptr to lock record 0 0000065A 8B35 mov si,[di] ; (ds:si) = address of 1st lock record 769 770 ;--------------------------------------- 771 ; check out next lock 772 ; 773 ; (ds:si) = address of next lock record 774 ; (ds:di) = address of pointer to next 775 ; lock record 776 ; (TOS) = flags (Z set to ignore 777 ; own locks) 778 ; (TOS+1) = Saved ES 779 ;--------------------------------------- 0 0000065C 21F6 sle1: and si,si 0 0000065E 7462 jz sle9 ; list exhaused, ergo no overlap 0 00000660 9D popf ; 0 00000661 9C pushf 0 00000662 752A jnz sle2 ; am to check all locks 785 786 ;--------------------------------------- 787 ; am to ignore own locks... 788 ; check the user and proc IDs on this one 789 ;--------------------------------------- 790 791 ;dcl - this code used to compare the process id in the sft pointed to by the 792 ; lock. now we compare the lock process id to the current process id. this 793 ; allows a child process to lock an area and then do i/o with it. before, 794 ; the child could lock it, but then could not access it 795 796 0 00000664 8B6C0E mov bp,[si + rlr_pid] ;dcl 798 Proc_id equ Proc_ID ; NASM port label 0 00000667 363B2E[0000] cmp bp,[ss:Proc_id] ;dcl 0 0000066C 751C jnz sce1$5 ;dcl 0 0000066E C4740A les si,[si + rlr_sptr] ; (si) = sft address ;dcl 0 00000671 268B6C2F mov bp,[es:si + sf_UID] ;dcl 0 00000675 363B2E[0000] cmp bp,[ss:User_ID] ;dcl 0 0000067A 750E jnz sce1$5 ; doesn't belong to user ;dcl 0 0000067C 8CC5 mov bp,es ;dcl 0 0000067E 363B2E[0200] cmp bp,WORD PTR [ss:ThisSFT+2] 0 00000683 7505 jnz sce1$5 0 00000685 363B36[0000] cmp si,WORD PTR [ss:ThisSFT] 0 0000068A 8B35 sce1$5: mov si,[di] ; (ds:si) = address of next lock record 0 0000068C 7418 jz sle3 ; owned by user - ignore 811 0 0000068E 89D5 sle2: mov bp,dx 0 00000690 2B6C02 sub bp,[si + rlr_fba] ; compare proposed last to first of record 0 00000693 89CD mov bp,cx 0 00000695 1B6C04 sbb bp,[si + rlr_fba + 2] 0 00000698 720C jc sle3 ; proposed is above current 0 0000069A 8B6C06 mov bp,[si + rlr_lba] 0 0000069D 29DD sub bp,bx ; compare proposed first to last of record 0 0000069F 8B6C08 mov bp,[si + rlr_lba + 2] 0 000006A2 19C5 sbb bp,ax 0 000006A4 7306 jnc sle5 ; we have a hit 822 823 ;--------------------------------------- 824 ; This entry is harmless... 825 ; chain to the next one 826 ;--------------------------------------- 827 ERRNZ rlr_next 828 0 000006A6 89F7 sle3: mov di,si ; save addr of pointer to next 0 000006A8 8B35 mov si,[di] 0 000006AA EBB0 JMP SHORT sle1 832 ;--------------------------------------- 833 ; We have an overlap. 834 ; - See if its an exact match 835 ; 836 ; (ds:di) = address of pointer 837 ; (offset only) to the lock record 838 ; (ds:si) = address of lock record 839 ; (TOS) = flags ('Z' set if to ignore 840 ; own locks) 841 ; (TOS+1) = saved (es) 842 ;--------------------------------------- 843 0 000006AC 334404 sle5: xor ax,[si + rlr_fba + 2] ; require a 4-word match 0 000006AF 335C02 xor bx,[si + rlr_fba] 0 000006B2 334C08 xor cx,[si + rlr_lba + 2] 0 000006B5 335406 xor dx,[si + rlr_lba] 0 000006B8 09D8 or ax,bx 0 000006BA 09C8 or ax,cx 0 000006BC 09D0 or ax,dx ; 'Z' set if exact match 0 000006BE F9 stc ; flag an overlap 0 000006BF B82100 mov ax,error_lock_violation 0 000006C2 5D sle9: pop bp ; discard flags (pushf) 0 000006C3 07 pop es ; restore (es) 855 856 ;--------------------------------------- 857 ; (ds:si) = address of lock record 858 ; for Chk_Block 859 ;--------------------------------------- 0 000006C4 C3 ret 861 862 EndProc SLE 863 864 BREAK 865 866 ;******************* START OF SPECIFICATIONS *********************************** 867 ; 868 ; OFL - obtain free lock-record 869 ; 870 ; OFL returns a free lock-record, if one can be had. 871 ; 872 ; ENTRY (DS) = MFT Segment 873 ; EXIT 'C' clear if OK 874 ; (DI) = FBA lock record 875 ; 'C' set if no space 876 ; (ax) = error code 877 ; USES DI, FLAGS 878 ; 879 ;******************* END OF SPECIFICATIONS ************************************* 880 881 Procedure OFL,NEAR 881 ****************** warning: proc OFL... [-w+user] 882 883 Frelock equ FreLock ; NASM port label 0 000006C5 2E8B3E[0000] mov di,[cs:Frelock] 0 000006CA 21FF and di,di 886 887 ; $if nz ; if something there 0 000006CC 7409 JZ D_$IF1 889 0 000006CE FF35 push word [di + rlr_next] 0 000006D0 2E8F06[0000] pop word [cs:Frelock] ; chain off of the list 892 ; exit with 'C' clear 893 894 ; $else ; none on free list 0 000006D5 EB04 JMP SHORT D_$EN1 896 D_$IF1: 897 0 000006D7 B82400 mov ax,error_sharing_buffer_exceeded ; None on free list, give up until 0 000006DA F9 stc ; garbage collector is ready 900 901 ; $endif 902 D_$EN1: 903 0 000006DB C3 ret 905 906 EndProc OFL 907 908 Break 909 910 ;******************* START OF SPECIFICATIONS *********************************** 911 ; 912 ; CPS - close process SFT. 913 ; 914 ; During maintenance, it is necessary to close a 915 ; file given ONLY the SFT. This necessitates walking all PDB's JFN 916 ; tables looking for the SFN. The difficult part is in generating the 917 ; SFN from the SFT. This is done by enumerating SFT's and comparing for 918 ; the correct SFT. Finding all PDBs is easy: walk arena and check 919 ; owner fields 920 ; 921 ; Inputs: ThisSFT points to SFT of interest 922 ; Outputs: Handle is closed on user 923 ; Registers Revised: none 924 ; 925 ;******************* END OF SPECIFICATIONS ************************************* 926 927 Procedure CPS,NEAR 927 ****************** warning: proc CPS... [-w+user] 928 929 ASSUME DS:NOTHING,ES:NOTHING 930 0 000006DC 1E560657505351 SaveReg 932 0 000006E3 36C536[0000] lds si,[ss:ThisSFT] 0 000006E8 31DB xor bx,bx 935 cps01: 936 937 multDOS equ MultDOS ; NASM port equate 0 000006EA 53B81612CD2F5B CallInstall SFFromSFN,multDOS,22,bx,bx 939 0 000006F1 727A jc cps31 ; no more SFN's. Must be FCB. 941 0 000006F3 B81412CD2F CallInstall PointComp,multDOS,20 943 0 000006F8 7403 jz cps02 ; found matching SFN, go scan. 0 000006FA 43 inc bx ; did not match, go back for more 0 000006FB EBED jmp cps01 947 ;--------------------------------------- 948 ; BL is the sfn we want to find. Walk 949 ; the memory arena enumerating all PDB's 950 ; and zap the handle tables for the 951 ; specified sfn. 952 ;--------------------------------------- 953 cps02: 0 000006FD 88D8 mov al,bl 0 000006FF 31F6 xor si, si 0 00000701 368E1E[0000] mov ds,[ss:Arena_Head] ; get first arena pointer 957 958 ;--------------------------------------- 959 ; [DS:0] is the arena header. 960 ; AL is sfn to be closed 961 ;--------------------------------------- 962 cps1: 0 00000706 46 inc si ; loop detection 0 00000707 745C jz cps3 ; stop if looped --> 0 00000709 8B0E0100 mov cx,[arena_owner] 0 0000070D 8CDB mov bx,ds 0 0000070F 43 inc bx ; is the owner the same as the current 0 00000710 39D9 cmp cx,bx ; block? 0 00000712 7518 jnz cps2 ; no, go skip some more... 970 971 ;--------------------------------------- 972 ; CX:0 is the correct pointer to a PDB. 973 ;--------------------------------------- 0 00000714 1E push ds 0 00000715 8ED9 mov ds,cx 976 ;--------------------------------------- 977 ; Given a PDB at DS:0, scan his handle 978 ; table and then loop through the next 979 ; PDB link. 980 ;--------------------------------------- 981 cps15: 0 00000717 813E0000CD20 cmp word [PDB_Exit_Call], 20CDh ; harden: is this a valid PSP ? 0 0000071D 750C jne .skip ; no --> 0 0000071F E85300 call CPJ ; free for this PDB 0 00000722 C50E3800 lds cx,[PDB_Next_PDB] ; advance to next 0 00000726 83F9FF cmp cx,-1 0 00000729 75EC jnz cps15 ; there is another link to process 988 .skip: 0 0000072B 1F pop ds 990 ;--------------------------------------- 991 ; We have processed the current 992 ; allocation block pointed to by DS. 993 ; [DS:0] is the allocation block 994 ;--------------------------------------- 995 cps2: 0 0000072C 803E00005A cmp byte [arena_signature], 'Z' 0 00000731 751C jne .not_Z 0 00000733 50 push ax 0 00000734 B86112 mov ax, 1261h 0 00000737 CD2F int 2Fh ; get first UMCB 0 00000739 83F801 cmp ax, 1 ; none ? 0 0000073C 760E jbe .pop 0 0000073E 83F8FF cmp ax, -1 ; none ? 0 00000741 7409 je .pop 0 00000743 E81500 call nextmcb ; bx => next MCB 0 00000746 39D8 cmp ax, bx ; is it the first UMCB ? 0 00000748 58 pop ax 0 00000749 74BB je cps1 ; yes, so we continue --> 0 0000074B A8 db 0A8h ; skip pop 1010 .pop: 0 0000074C 58 pop ax 0 0000074D EB16 jmp cps3 ; no more blocks to do 1013 1014 .not_Z: 0 0000074F 803E00004D cmp byte [arena_signature], 'M' 0 00000754 750F jne cps3 ; corrupted --> 0 00000756 E80200 call nextmcb 0 00000759 EBAB jmp cps1 1019 1020 1021 nextmcb: 0 0000075B 8CDB mov bx,ds ; get current address 1023 Arena_size equ arena_size ; NASM port equate 0 0000075D 031E0300 add bx,[Arena_size] ; add on size of block 0 00000761 43 inc bx ; remember size of header 0 00000762 8EDB mov ds,bx ; link to next 0 00000764 C3 retn 1028 ;--------------------------------------- 1029 ; Just for good measure, use CurrentPDB 1030 ; and clean off him 1031 ;--------------------------------------- 1032 cps3: 0 00000765 368E1E[0000] mov ds,[ss:CurrentPDB] 1034 0 0000076A E80800 call CPJ 1036 1037 cps31: 1038 0 0000076D 595B585F075E1F RestoreReg 1040 0 00000774 C3 ret 1042 1043 EndProc CPS 1044 1045 ;******************* START OF SPECIFICATIONS *********************************** 1046 ; 1047 ; CPJ - 1048 ; 1049 ; Scan JFN table for SFT # and put in -1 if found 1050 ; 1051 ; Input: DS:0 is PDB 1052 ; AL is SFT index # of interest 1053 ; 1054 ; Output: None 1055 ; 1056 ; Uses: Flags,CX,ES,DI 1057 ; 1058 ;******************* END OF SPECIFICATIONS ************************************* 1059 1060 Procedure CPJ,NEAR 1060 ****************** warning: proc CPJ... [-w+user] 1061 1062 assume ds:nothing,es:nothing 1063 1064 PDB_JFN_length equ PDB_JFN_Length ; NASM port equate 0 00000775 8B0E3200 mov cx,[PDB_JFN_length] 1066 PDB_JFN_pointer equ PDB_JFN_Pointer ; NASM port equate 0 00000779 C43E3400 les di,[PDB_JFN_pointer] 0 0000077D FC cld 1069 cpj1: 0 0000077E E30C jcxz CPJret ; no more entries 0 00000780 F2AE repne scasb 1072 0 00000782 7401C3 retnz ; none found 1074 0 00000785 26C645FFFF mov byte ptr [es:di-1],-1 ; free this 0 0000078A EBF2 jmp cpj1 ; keep looking 1077 CPJret: 0 0000078C C3 ret 1079 1080 EndProc CPJ 1081 1082 Break 1083 1084 ;******************* START OF SPECIFICATIONS *********************************** 1085 ; 1086 ; SFM - convert a pointer to a mft entry into the serial number for that 1087 ; entry. We keep these around to see if a FCB really points to the correct 1088 ; SFT. 1089 ; 1090 ; Inputs: BX is the mft pointer 1091 ; Outputs: BX is the serial number 1092 ; Registers Revised: none 1093 ; 1094 ;******************* END OF SPECIFICATIONS ************************************* 1095 1096 Procedure SFM,NEAR 1096 ****************** warning: proc SFM... [-w+user] 1097 1098 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 1099 0 0000078D 2E8B5F0A mov bx,[cs:bx + mft_serl] 1101 0 00000791 C3 ret 1103 1104 EndProc SFM 1105 1106 Break 1107 1108 ;******************* START OF SPECIFICATIONS *********************************** 1109 ; 1110 ; ShChk - check a fcb for share related information 1111 ; 1112 ; ShChk - checks the reserved field contents of an FCB with a SFT to see 1113 ; if they represent the same file. The open ref count must be > 0. 1114 ; 1115 ; Inputs: DS:SI point to FCB 1116 ; ES:DI point to SFT 1117 ; Outputs: Carry Set if contents do not match 1118 ; Carry clear if contents match 1119 ; BX has first cluster 1120 ; Registers Revised: none 1121 ; 1122 ;******************* END OF SPECIFICATIONS ************************************* 1123 1124 Procedure ShChk,NEAR 1124 ****************** warning: proc ShChk... [-w+user] 1125 1126 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 1127 0 00000792 26833D00 CMP word [ES:DI + sf_ref_count],0 0 00000796 7410 JZ BadSFT 0 00000798 268B5D33 MOV BX,[ES:DI + sf_mft] ; Local file or dev with sharing 1131 0 0000079C E8EEFF call SFM 1133 0 0000079F 3B5C1C CMP BX,[SI + fcb_l_mfs] 0 000007A2 7504 JNZ BadSFT 0 000007A4 8B5C1A MOV BX,[SI + fcb_l_firclus] 1137 0 000007A7 C3 ret 1139 0 000007A8 F9 BadSFT: stc 1141 0 000007A9 C3 ret 1143 1144 EndProc ShChk 1145 1146 Break 1147 1148 ;******************* START OF SPECIFICATIONS *********************************** 1149 ; 1150 ; ShSave - save information from SFT into an FCB 1151 ; 1152 ; ShSave - copy information into the reserved area of an FCB from a SFT. 1153 ; This is so that we can later match the SFT with the FCB. 1154 ; 1155 ; Inputs: ES:DI point to SFT 1156 ; DS:SI point to FCB 1157 ; Outputs: FCB reserved field is filled in 1158 ; BL = FCBSHARE 1159 ; Registers Revised: AX,BX 1160 ; 1161 ;******************* END OF SPECIFICATIONS ************************************* 1162 1163 Procedure ShSave,NEAR 1163 ****************** warning: proc ShSave... [-w+user] 1164 1165 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 1166 0 000007AA 268A4504 MOV AL,[ES:DI + sf_attr] ; move attribute (for reopen) 0 000007AE 88441E MOV [SI + FCB_l_attr],AL 0 000007B1 268B450B MOV AX,[ES:DI + sf_firclus] ; get first cluster 0 000007B5 89441A MOV [SI + FCB_l_firclus],AX 0 000007B8 268B5D33 MOV BX,[ES:DI + sf_mft] ; get sharing pointer 1172 0 000007BC E8CEFF call SFM 1174 0 000007BF 895C1C MOV [SI + FCB_l_mfs],BX 0 000007C2 B3C0 MOV BL,FCBSHARE 1177 0 000007C4 C3 ret 1179 1180 EndProc ShSave 1181 1182 Break 1183 1184 ;******************* START OF SPECIFICATIONS *********************************** 1185 ; 1186 ; ShCol - collapse identical handle SFTs in mode 70 only 1187 ; 1188 ; ShCol - collapse same 70-mode handles together. This represents network 1189 ; originated FCBs. Since FCB's are incredibly mis-behaved, we collapse the 1190 ; SFT's for identical files, thus using a single sft for each file instead 1191 ; of a separate sft for each instance of the file. 1192 ; 1193 ; Note that the redirectors will collapse multiple instances of these 1194 ; files together. FCB's are pretty misbehaved, so the redirector will 1195 ; inform us of EACH close done on an FCB. Therefore, we must increment 1196 ; the ref count each time we see a collapse here. 1197 ; 1198 ; Inputs: DS:SI ThisSFT has new sft to find. 1199 ; Outputs: Carry set - no matching SFT was found 1200 ; Carry clear - matching SFT was found and all collapsing done. 1201 ; AX has proper handle 1202 ; Registers Revised: all. 1203 ; 1204 ;******************* END OF SPECIFICATIONS ************************************* 1205 1206 Procedure ShCol,NEAR 1206 ****************** warning: proc ShCol... [-w+user] 1207 1208 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:DOSGROUP 1209 1210 ;--------------------------------------- 1211 ; Collapse the files ONLY if 1212 ; the mode is for net FCB's 1213 ;--------------------------------------- 1214 0 000007C5 8A4402 MOV AL,BYTE PTR [SI + sf_mode] 0 000007C8 24F0 AND AL,sharing_mask 0 000007CA 3C70 CMP AL,sharing_net_FCB 0 000007CC 7577 JNZ UseJFN 1219 1220 ;--------------------------------------- 1221 ; In share support 1222 ;--------------------------------------- 1223 0 000007CE 31DB XOR BX,BX ; for (i=0; sffromsfn(i); i++) { 1225 OpenScan: 1226 0 000007D0 53B81612CD2F5B CallInstall SFFromSFN,multDOS,22,bx,bx 1228 0 000007D7 726C JC UseJFN 1230 0 000007D9 B81412CD2F CallInstall PointComp,multDOS,20 ; if (!pointcomp (s,d)) 1232 0 000007DE 742A JZ OpenNext 0 000007E0 26833D00 CMP word [ES:DI + sf_ref_count],0 0 000007E4 7424 JZ OpenNext 0 000007E6 268B4502 MOV AX,[ES:DI + sf_mode] 0 000007EA 3B4402 CMP AX,[SI + sf_mode] 0 000007ED 751B JNZ OpenNext 0 000007EF 268B4533 MOV AX,[ES:DI + sf_mft] 0 000007F3 3B4433 CMP AX,[SI + sf_mft] 0 000007F6 7512 JNZ OpenNext 0 000007F8 268B452F MOV AX,WORD PTR [ES:DI + sf_UID] 1243 sf_uid equ sf_UID ; NASM port equate 0 000007FC 3B442F CMP AX,WORD PTR [SI + sf_uid] 0 000007FF 7509 JNZ OpenNext 1246 sf_pid equ sf_PID ; NASM port equate 0 00000801 268B4531 MOV AX,WORD PTR [ES:DI + sf_pid] 0 00000805 3B4431 CMP AX,WORD PTR [SI + sf_pid] 0 00000808 7403 JZ OpenFound 1250 OpenNext: 0 0000080A 43 INC BX 0 0000080B EBC3 JMP OpenScan 1253 ;-------------------------------------- 1254 ; DS:SI points to an sft which is a 1255 ; duplicate of that found in 1256 ; ES:DI is the older one. 1257 ; 1258 ; We call mftclose to release the 1259 ; appropriate info. 1260 ;-------------------------------------- 1261 OpenFound: 0 0000080D C7040000 MOV word [SI + sf_ref_count],0 ; free 'new' sft 1263 0 00000811 1E56065753 SaveReg 1265 0 00000816 161F Context DS 1267 0 00000818 C43E[0000] LES DI,[ThisSFT] 1269 0 0000081C E8[0000] call MFTClose 1271 0 0000081F 585F075E1F RestoreReg 1273 1274 ASSUME DS:NOTHING 1275 0 00000824 26FF05 INC word [ES:DI + sf_ref_count] ; d->refcount++; 0 00000827 31DB XOR BX,BX ; find jfn with sfn as contents 1278 JFNScan: 1279 0 00000829 50B82012CD2F58 CallInstall pJFNFromHandle,multDOS,32,AX,AX 1281 0 00000830 7213 JC UseJFN ; ran out of handles? 0 00000832 263A05 CMP AL,BYTE PTR [ES:DI] ; does JFN have SFN? 1284 JFNfound equ JFNFound ; NASM port label 0 00000835 7403 jz JFNfound ; YES, go return JFN 0 00000837 43 INC BX ; no, look at next 0 00000838 EBEF JMP JFNScan 1288 JFNFound: 0 0000083A 36C536[0000] LDS SI,[ss:pJFN] 0 0000083F C604FF MOV BYTE PTR [SI],0FFh ; free JFN 0 00000842 89D8 MOV AX,BX ; return JFN 1292 0 00000844 C3 ret 1294 1295 UseJFN: 0 00000845 36A1[0000] MOV AX,[ss:JFN] 1297 0 00000849 C3 ret 1299 1300 EndProc ShCol 1301 1302 Break 1303 1304 ;******************* START OF SPECIFICATIONS *********************************** 1305 ; 1306 ; ShCloseFile - close a particular file for a particular UID/PID 1307 ; 1308 ; ShCloseFile - Compatability mode programs will often delete files that 1309 ; they had open. This was perfectly valid in the 2.0 days, but this 1310 ; presents a reliability problem in the network based operating environment. 1311 ; As a result, both RENAME and DELETE will call us to see if the file is 1312 ; open by is only. If it is not open or is open by us only, we close it. 1313 ; Note that we will ONLY close compatability SFTs. 1314 ; Otherwise, we signal and error. 1315 ; 1316 ; Inputs: WFT_Start has a DOSGROUP offset to the file name 1317 ; DS is DOSGroup 1318 ; Outputs: nothing relevant. 1319 ; Registers Revised: None. 1320 ; 1321 ;******************* END OF SPECIFICATIONS ************************************* 1322 1323 Procedure ShCloseFile,NEAR 1323 ****************** warning: proc ShCloseFile... [-w+user] 1324 1325 ASSUME DS:DOSGroup,ES:NOTHING,SS:DOSGroup 1326 0 0000084A 505351525657551E06 SaveReg 1328 0 00000853 E85102 EnterCrit critShare 1330 1331 ShCl: 1332 WFP_Start equ WFP_start ; NASM port label 0 00000856 8B36[0000] MOV SI,[WFP_Start] 0 0000085A 30C0 XOR AL,AL 1335 0 0000085C E829FC call FNM ; attempt to find name in list 1337 1338 ASSUME DS:NOTHING 1339 0 0000085F 7249 JC ShCloseDone ; can't find, signal success 1341 1342 ;-------------------------------------- 1343 ; We have found a file in the MFT. 1344 ; Walk the open sft list to find 1345 ; the SFTs for the current UID/PID. 1346 ;-------------------------------------- 0 00000861 8CD9 MOV CX,DS 0 00000863 C57706 LDS SI,[BX + mft_sptr] 1349 ShClCheck: 0 00000866 36A1[0000] MOV AX,[ss:Proc_ID] 0 0000086A 394431 CMP [SI + sf_PID],AX 0 0000086D 753B JNZ ShCloseDone 0 0000086F 36A1[0000] MOV AX,[ss:User_ID] 0 00000873 39442F CMP [SI + sf_UID],AX 0 00000876 7532 JNZ ShCloseDone 0 00000878 8B4402 MOV AX,[SI + sf_mode] 0 0000087B 25F000 AND AX,sharing_mask 1358 sharing_net_fcb equ sharing_net_FCB ; NASM port equate 0 0000087E 83F870 CMP AX,sharing_net_fcb 0 00000881 7405 jz ShClNext 0 00000883 83F800 CMP AX,sharing_compat 1362 ShCloseDOne equ ShCloseDone ; NASM port label 0 00000886 7522 jnz ShCloseDOne 1364 ShClNext: 0 00000888 C5742B LDS SI,[SI + sf_chain] 0 0000088B 09F6 OR SI,SI 0 0000088D 75D7 JNZ ShClCheck 0 0000088F 8ED9 MOV DS,CX 0 00000891 C57706 LDS SI,[BX + mft_sptr] 1370 ;-------------------------------------- 1371 ; Everything matches. Set up ThisSFT 1372 ; and walk the chain from the beginning. 1373 ;-------------------------------------- 0 00000894 368936[0000] MOV WORD PTR [ss:ThisSFT],SI 0 00000899 368C1E[0200] MOV WORD PTR [ss:ThisSFT+2],DS 1376 ;-------------------------------------- 1377 ; Close all handles for this SFT 1378 ;-------------------------------------- 0 0000089E E83BFE call CPS 1380 ;-------------------------------------- 1381 ; Close the sft itself. 1382 ;-------------------------------------- 0 000008A1 161F Context DS 1384 1385 multDos equ MultDOS ; NASM port equate 0 000008A3 B80112CD2F CallInstall DOS_Close,multDos,1 1387 ;-------------------------------------- 1388 ; The SFT may be free and we have no 1389 ; idea where the next is. Go and loop 1390 ; all over. 1391 ;-------------------------------------- 0 000008A8 EBAC JMP ShCl 1393 ;-------------------------------------- 1394 ; There are no more SFTs to close. Leave 1395 ;--------------------------------------- 1396 ShCloseDone: 1397 0 000008AA E80202 LeaveCrit critShare 1399 0 000008AD F9 STC 1401 0 000008AE 071F5D5F5E5A595B58 RestoreReg 1403 0 000008B7 C3 ret 1405 1406 EndProc ShCloseFile 1407 1408 ; .xall 1409 Break 1410 ;******************* START OF SPECIFICATIONS *********************************** 1411 ; 1412 ; NAME: ShSU - update all SFTs for a specified change> 1413 ; 1414 ; FUNCTION: In a shared environment, we want to propogate the SFT 1415 ; changes for a particular file to all other SFTs for that 1416 ; file. The types of things we propogate are: 1417 ; 1418 ; - Time of last write - we only do this on CLOSE and on 1419 ; FILETIMES. 1420 ; 1421 ; - Size and allocation information - we do this ONLY when 1422 ; we change sf_size. 1423 ; 1424 ; We achieve this by walking the linked list of SFTs for the 1425 ; file. See PSEUDOCODE below 1426 ; 1427 ; INPUT: ES.DI has SFT that was just Revised. 1428 ; AX = 0 for updating of time from ES:DI into old sfts 1429 ; AX = 1 for updating of size/allocation for growth from ES:DI 1430 ; AX = 2 for updating of size/allocation for shrink from ES:DI 1431 ; AX = 3 for new instance copy into ES:DI 1432 ; AX = 4 for update of codepage and high attribute 1433 ; 1434 ; OUTPUT: All relevant SFTs are updated. 1435 ; 1436 ; REGISTERS USED: All except ES:DI and DS:SI 1437 ; (NOT RESTORED) 1438 ; 1439 ; LINKAGE: DOS Jump Table 1440 ; 1441 ; EXTERNAL Invoke: New_Sft, Call_IFS 1442 ; REFERENCES: Callinstall 1443 ; 1444 ; NORMAL - 1445 ; EXIT: 1446 ; 1447 ; ERROR - 1448 ; EXIT: 1449 ; 1450 ; CHANGE 04/15/87 - Major overhaul and IFS support 1451 ; LOG: 1452 ; 1453 ;******************* END OF SPECIFICATIONS ************************************* 1454 ;******************+ START OF PSEUDOCODE +************************************** 1455 ; 1456 ; START ShSU 1457 ; 1458 ; if not a device and 1459 ; if not a network 1460 ; search 1461 ; if our SFT 1462 ; advance to next SFT 1463 ; endif 1464 ; leave if no more SFT's 1465 ; exitif cx = 3 1466 ; invoke New_Sft 1467 ; orelse 1468 ; if cx = 0 1469 ; update time 1470 ; update date 1471 ; if non - FAT file system 1472 ; call IFSFUNC 1473 ; endif 1474 ; else cx = 1 or 2 1475 ; update size 1476 ; if non - FAT file system 1477 ; call IFSFUNC 1478 ; else 1479 ; update first cluster 1480 ; if cx = 2 or 1481 ; if lstclus un-set from create 1482 ; update cluster position 1483 ; update last cluster 1484 ; endif 1485 ; endif 1486 ; endif 1487 ; advance to next SFT 1488 ; endloop 1489 ; endsearch 1490 ; endif 1491 ; return 1492 ; 1493 ; END ShSU 1494 ; 1495 ;******************+ END OF PSEUDOCODE +************************************** 1496 1497 Procedure ShSU,near 1497 ****************** warning: proc ShSU... [-w+user] 1498 1499 ASSUME DS:NOTHING,ES:NOTHING 1500 0 000008B8 90 nop 1502 ; int 3 0 000008B9 90 nop 1504 1505 ifs_flag equ 8000h ; ;AN000; 1506 ;--------------------------------------- 1507 ; Do nothing for device or network 1508 ;--------------------------------------- 0 000008BA 268B5D02 mov bx,[es:di + sf_mode] 0 000008BE 81E38080 and bx,sf_isnet + devid_device 1511 1512 ; $if z,and,long ; if not device and ;AC000; 0 000008C2 7403 JZ D_$XL1 0 000008C4 E98F00 JMP D_$IF4 1515 D_$XL1: 1516 0 000008C7 268B5D33 mov bx,[es:di + sf_MFT] 0 000008CB 09DB or bx,bx 1519 1520 ; $if nz,,long ; if not network ;AC000; 0 000008CD 7503 JNZ D_$XL2 0 000008CF E98400 JMP D_$IF4 1523 D_$XL2: 1524 0 000008D2 E8D201 EnterCrit critShare 1526 ;--------------------------------------- 1527 ; Walk the sft chain for this file and 1528 ; skip the current SFT (ES:DI) 1529 ;--------------------------------------- 0 000008D5 1E56 SaveReg 1531 1532 MFT_SPTR equ mft_sptr ; NASM port equate 0 000008D7 2EC57706 lds si,[cs:bx + MFT_SPTR] 0 000008DB 89C1 mov cx,ax 1535 1536 ; $search ; ;AC000; 1537 D_$DO5: 1538 0 000008DD B81412CD2F CallInstall PointComp,multDOS,20 ; pointers different? 1540 1541 ; $if z ; if ourselves ;AC000; 0 000008E2 7503 JNZ D_$IF6 1543 0 000008E4 C5742B lds si,[si + sf_chain] ; move to next ;AC000; 1545 1546 ; $endif ; endif - ourselves ;AC000; 1547 D_$IF6: 1548 0 000008E7 09F6 or si,si 1550 1551 ; $leave z ; ;AC000; 0 000008E9 7466 JZ D_$EN5 1553 1554 ;--------------------------------------- 1555 ; CX = 0 for updating of time 1556 ; CX = 1 for updating of size/allocation 1557 ; for growth 1558 ; CX = 2 for updating of size/allocation 1559 ; for shrink 1560 ; CX = 3 for new instance copy. 1561 ;--------------------------------------- 0 000008EB 83F902 cmp cx,2 ; ;AC000; 1563 1564 ; $exitif a ; ;AC000; 0 000008EE 760A JNA D_$IF5 1566 ;--------------------------------------- 1567 ; CX = 3 for new instance copy. 1568 ; CX = 4 for codepage and high attrib update 1569 ;--------------------------------------- 0 000008F0 83F903 cmp cx,3 ; cx = 3 ? ;an000; 1571 ; $if e ; yes ;an000; 0 000008F3 7503 JNE D_$IF10 0 000008F5 E85F00 call New_Sft ; ;AN000; 1574 ;; $else ; cx = 4 ;an000; 1575 ;; call New_CP_Attrib ; update codepage and high attrib ;an000; 1576 ; $endif ; ;an000; 1577 D_$IF10: 1578 1579 ; $orelse ; ;AC000; 0 000008F8 EB57 JMP SHORT D_$SR5 1581 D_$IF5: 1582 0 000008FA 09C9 or cx,cx 1584 1585 ; $if z ; if cx = 0 then ;AC000; 0 000008FC 751A JNZ D_$IF13 1587 ;--------------------------------------- 1588 ; CX = 0 for updating of time 1589 ; 1590 ; Copy time from ES:DI into DS:SI 1591 ;--------------------------------------- 0 000008FE 268B5D0D mov bx,[es:di + sf_time] 0 00000902 895C0D mov [si + sf_time],bx 0 00000905 268B5D0F mov bx,[es:di + sf_date] 0 00000909 895C0F mov [si + sf_date],bx 0 0000090C F744050080 test word [si + sf_flags],ifs_flag ; ;AN000; 1597 1598 ; $if nz ; if non-FAT ;AC003; 0 00000911 7403 JZ D_$IF14 1600 0 00000913 E87C00 call Call_IFS ; tell IFS of SFT change ;AN000; 1602 1603 ; $endif ; endif non- FAT ;AN000; 1604 D_$IF14: 1605 1606 ; $else ; else - must be >0 and <2 ;AC000; 0 00000916 EB34 JMP SHORT D_$EN13 1608 D_$IF13: 1609 ;--------------------------------------- 1610 ; CX = 1 for updating of size/allocation 1611 ; for growth 1612 ; CX = 2 for updating of size/allocation 1613 ; for shrink 1614 ; 1615 ; We always copy size and firclus 1616 ;--------------------------------------- 0 00000918 268B5D11 mov bx,word ptr [es:di + sf_size] 0 0000091C 895C11 mov word ptr [si + sf_size],bx 0 0000091F 268B5D13 mov bx,word ptr [es:di + sf_size + 2] 0 00000923 895C13 mov word ptr [si + sf_size + 2],bx 0 00000926 F744050080 test word [si + sf_flags],ifs_flag ; ;AN000; 1622 1623 ; $if nz ; if non-FAT ;AC003; 0 0000092B 7405 JZ D_$IF17 1625 0 0000092D E86200 invoke Call_IFS ; tell IFS of SFT change ;AN000; 1627 1628 ; $else ; else - its FAT ;AN000; 0 00000930 EB1A JMP SHORT D_$EN17 1630 D_$IF17: 1631 0 00000932 268B5D0B mov bx,[es:di + sf_firclus] 0 00000936 895C0B mov [si + sf_firclus],bx 0 00000939 83F902 cmp cx,2 ; ;AC000; 1635 1636 ; $if z,or ; if SFT is shrinking or ;AC000; 0 0000093C 7406 JZ D_$LL19 1638 0 0000093E 837C3500 cmp word [si + sf_lstclus],0 ; lstclus UN-set from a create? ;AC000; 1640 1641 ; $if z ; If it is, set lstclus and cluspos too;AC000; 0 00000942 7508 JNZ D_$IF19 1643 D_$LL19: 1644 ;--------------------------------------- 1645 ; Shrink the file, move in new cluspos 1646 ; and lstclus 1647 ;--------------------------------------- 0 00000944 C744190000 mov word [si + sf_cluspos],0 ; retrace from start 0 00000949 895C35 mov [si + sf_lstclus],bx ; ditto 1650 1651 ; $endif ; endif - set lstclus and cluspos ;AC000; 1652 D_$IF19: 1653 1654 ; $endif ; endif FAT ;AN000; 1655 D_$EN17: 1656 1657 ; $endif ; enndif - > 0 ;AC000; 1658 D_$EN13: 1659 ;--------------------------------------- 1660 ; Link to next SFT 1661 ;--------------------------------------- 0 0000094C C5742B lds si,[si + sf_chain] 1663 1664 ; $endloop ; ;AC000; 0 0000094F EB8C JMP SHORT D_$DO5 1666 D_$EN5: 1667 1668 ; $endsrch ; ;AC000; 1669 D_$SR5: 1670 ;--------------------------------------- 1671 ; All Done 1672 ;--------------------------------------- 0 00000951 5E1F RestoreReg 1674 0 00000953 E85901 LeaveCrit critShare 1676 1677 ; $endif ; endif - device and network ;AC000; 1678 D_$IF4: 1679 0 00000956 C3 ret 1681 1682 EndProc ShSU 1683 1684 Break 1685 1686 ;******************* START OF SPECIFICATIONS *********************************** 1687 ; 1688 ; NAME: New_Sft - update a new SFT 1689 ; 1690 ; FUNCTION: Copy all SFT information into a NEW sft of a SHARED file. 1691 ; 1692 ; 1693 ; INPUT: ES.DI has SFT that was just Revised. 1694 ; DS:SI has SFT that is to be updated 1695 ; 1696 ; OUTPUT: SFT is updated. 1697 ; 1698 ; REGISTERS USED: AX, BX 1699 ; (NOT RESTORED) 1700 ; 1701 ; LINKAGE: Invoked by: ShSU 1702 ; 1703 ; EXTERNAL Invoke: Call_IFS 1704 ; REFERENCES: 1705 ; 1706 ; CHANGE 04/15/87 - First release 1707 ; LOG: 1708 ; 1709 ;******************* END OF SPECIFICATIONS ************************************* 1710 ;******************+ START OF PSEUDOCODE +************************************** 1711 ; 1712 ; START New_Sft 1713 ; 1714 ; update time 1715 ; update date 1716 ; update size 1717 ; if non - FAT file system 1718 ; call IFSFUNC 1719 ; else 1720 ; update first cluster 1721 ; update cluster position 1722 ; update last cluster 1723 ; endif 1724 ; return 1725 ; 1726 ; END New_Sft 1727 ; 1728 ;******************+ END OF PSEUDOCODE +************************************** 1729 1730 Procedure New_Sft,near ; ;AN000; 1730 ****************** warning: proc New_Sft... [-w+user] 1731 0 00000957 8B5C0D mov bx,[si + sf_time] ; update time 0 0000095A 26895D0D mov [es:di + sf_time],bx 0 0000095E 8B5C0F mov bx,[si + sf_date] ; update date 0 00000961 26895D0F mov [es:di + sf_date],bx 0 00000965 8B5C11 mov bx,word ptr [si + sf_size] ; update size 0 00000968 26895D11 mov word ptr [es:di + sf_size],bx 0 0000096C 8B5C13 mov bx,word ptr [si + sf_size + 2] 0 0000096F 26895D13 mov word ptr [es:di + sf_size + 2],bx 0 00000973 26F745050080 test word [es:di + sf_flags],ifs_flag ; ;AN000; 1741 1742 ; $if nz ; if non-FAT ;AC003; 0 00000979 7405 JZ D_$IF26 1744 0 0000097B E81400 call Call_IFS ; tell IFS of SFT change ;AN000; 1746 1747 ; $else ; else - its FAT ;AN000; 0 0000097E EB11 JMP SHORT D_$EN26 1749 D_$IF26: 1750 0 00000980 8B5C0B mov bx,[si + sf_firclus] ; update first cluster 0 00000983 26895D0B mov [es:di + sf_firclus],bx 0 00000987 26C745190000 mov word [es:di + sf_cluspos],0 ; retrace from start 0 0000098D 26895D35 mov [es:di + sf_lstclus],bx ; ditto 1755 1756 ; $endif ; endif FAT ;AN000; 1757 D_$EN26: 1758 0 00000991 C3 ret ; we'er done ;AN000; 1760 1761 EndProc New_Sft ; ;AN000; 1762 1763 Break 1764 1765 ;******************* START OF SPECIFICATIONS *********************************** 1766 ; 1767 ; NAME: New_CP_Attrib - Update codepage and attrib in SFT 1768 ; 1769 ; FUNCTION: Copy all codepage and attrib into SFT of a SHARED file. 1770 ; 1771 ; 1772 ; INPUT: ES.DI has SFT that was just Revised. 1773 ; DS:SI has SFT that is to be updated 1774 ; 1775 ; OUTPUT: SFT is updated. 1776 ; 1777 ; REGISTERS USED: AX, BX 1778 ; (NOT RESTORED) 1779 ; 1780 ; LINKAGE: Invoked by: ShSU 1781 ; 1782 ; EXTERNAL Invoke: Call_IFS 1783 ; REFERENCES: 1784 ; 1785 ; CHANGE 10/06/87 - First release - D. M. Sewell 1786 ; LOG: 1787 ; 1788 ;******************* END OF SPECIFICATIONS ************************************* 1789 ;******************+ START OF PSEUDOCODE +************************************** 1790 ; 1791 ; START New_CP_Attrib 1792 ; 1793 ; Update codepage 1794 ; Update high attribute 1795 ; $if ifs_flag 1796 ; call Call_IFS 1797 ; $endif 1798 ; return 1799 ; 1800 ; END New_CP_Attrib 1801 ; 1802 ;******************+ END OF PSEUDOCODE +************************************** 1803 1804 ;; Procedure New_CP_Attrib,near ; ;AN000; 1805 1806 ;; mov bx,[es:di].SF_Codepage ; update codepage ;an000; 1807 ;; mov [si].SF_Codepage,bx ;an000; dms; 1808 ;; mov bl,[es:di].SF_Attr_Hi ; update high attribute ;an000; 1809 ;; mov [si].SF_Attr,bl ;an000; dms; 1810 ;; test [es:di].sf_flags,ifs_flag ; ;AN000; 1811 1812 ;; $if nz ; if non-FAT ;AC003; 1813 1814 ;; call Call_IFS ; tell IFS of SFT change ;AN000; 1815 1816 ;; $endif ; endif FAT ;AN000; 1817 1818 ;; ret ; we'er done ;AN000; 1819 1820 ;; EndProc New_CP_Attrib ; ;AN000; 1821 1822 1823 Break 1824 1825 ;******************* START OF SPECIFICATIONS *********************************** 1826 ; 1827 ; NAME: Call_IFS - warn IFS that SFT has changed 1828 ; 1829 ; FUNCTION: Call IFS thru 2F interupt. 1830 ; 1831 ; INPUT: DS.SI points to SFT that was just Revised. 1832 ; 1833 ; OUTPUT: none 1834 ; 1835 ; REGISTERS USED: AX 1836 ; (NOT RESTORED) 1837 ; 1838 ; LINKAGE: Invoked by: ShSU, New_SFT 1839 ; 1840 ; EXTERNAL Callinstall 1841 ; REFERENCES: 1842 ; 1843 ; CHANGE 04/15/87 - First release 1844 ; LOG: 1845 ; 1846 ;******************* END OF SPECIFICATIONS ************************************* 1847 ;******************+ START OF PSEUDOCODE +************************************** 1848 ; 1849 ; START Call_IFS 1850 ; 1851 ; set up for INT 1852 ; INT 2F 1853 ; return 1854 ; 1855 ; END Call_IFS 1856 ; 1857 ;******************+ END OF PSEUDOCODE +************************************** 1858 1859 Procedure Call_IFS,near ; ;AN000; 1859 ****************** warning: proc Call_IFS... [-w+user] 1860 0 00000992 51B82C11CD2F59 CallInstall BlockUpdate,MultIFS,44,CX,CX ; ;AC005; 1862 0 00000999 C3 ret ; ;AN000; 1864 1865 EndProc Call_IFS ; ;AN000; 1866 1867 Break 1868 1869 ;******************* START OF SPECIFICATIONS *********************************** 1870 ; 1871 ; INTERR - INTernal ERRor routines 1872 ; 1873 ;******************* END OF SPECIFICATIONS ************************************* 1874 1875 Procedure INTERR,NEAR 1875 ****************** warning: proc INTERR... [-w+user] 1876 1877 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING 1878 0 0000099A 53561E SaveReg ; save registers that get clobbered 1880 0 0000099D 0E push cs ; gain addressability 0 0000099E 1F pop ds 0 0000099F 89C6 mov si,ax ; get message to print 1884 0 000009A1 E80B00 call gout 1886 0 000009A4 BE[3305] off si,IntErrMsg 1888 0 000009A7 E80500 call gout 1890 0 000009AA 1F5E5B RestoreReg 1892 0 000009AD EBFE INTERRL:jmp INTERRL ; hang here - we're sick 1894 0 000009AF AC gout: lodsb 0 000009B0 08C0 or al,al 0 000009B2 7501C3 retz 0 000009B5 B40E mov ah,14 0 000009B7 CD10 int 10h 0 000009B9 EBF4 jmp gout 1901 0 000009BB 53686172653A20496E IntErrMsg DB "Share: Internal error", 13, 10, 0 0 000009C4 7465726E616C206572 0 000009CD 726F720D0A00 1903 1904 EndProc INTERR 1905 1906 Break 1907 1908 %IF installed 1909 1910 public skip_check 1911 0 000009D3 00 skip_check db 0 ; start with do checking 1913 0 000009D4 00 state_change db 0 ; SHARE change in state flag 1915 ; 0 - no change in state 1916 ; 1 - SHARE load state has changed 1917 0 000009D5 CBEB10000000004B42 iispentry i2F 0 000009DE 00EBF400 1919 1920 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:NOTHING 1921 multSHARE equ MultSHARE ; NASM port equate 0 000009E8 80FC10 cmp ah,multSHARE 0 000009EB 757D jnz strict short ContJ 1924 1925 ; Its for SHARE! Check to see who is calling: 1926 1927 ; AL = 1928 ; 81h its us, with /NC - set skip_check 1929 ; - return 0F0h - end init 1930 ; 80h its us 1931 ; if skip_check is reset 1932 ; - return 0FFh - loaded 1933 ; if skip_check is set 1934 ; - reset skip_check 1935 ; - return 0F0h - end init 1936 ; 1937 ; 40h its IFSFUNC - return 0FFh - loaded 1938 ; 1939 ; 00h its anyone else - clear skip_check 1940 ; - return 0FFh - loaded 1941 0 000009ED A880 test al,80h ; is it share? ;AN010; 1943 ; $if nz ; if it is ;AN010; 0 000009EF 7436 JZ D_$IF29 0 000009F1 2401 and al,1 ; is /NC set ;AN010; 0 000009F3 B0F0 mov al,0F0H ; assume a quiet return ;AN010; 1947 ; $if nz ; if it is ;AN010; 0 000009F5 7416 JZ D_$IF30 0 000009F7 2E803E[4B05]01 cmp byte [cs:skip_check],1 ; is skip_check set ? ;AN011; 1950 ; $if ne ; if it is ;AN011; 0 000009FD 7406 JE D_$IF31 0 000009FF 2EC606[4C05]01 mov byte [cs:state_change],1 ; set the change state flag ;AN011; 1953 ; $endif ; ;AN011; 1954 D_$IF31: 0 00000A05 2EC606[4B05]01 mov byte [cs:skip_check],1 ; set skip_check ;AN010; 1956 ; $else ; /NC not requested ;AN010; 0 00000A0B EB18 JMP SHORT D_$EN30 1958 D_$IF30: 0 00000A0D 2E803E[4B05]01 cmp byte [cs:skip_check],1 ; is skip_check set ? ;AN010; 1960 ; $if e ; if it is ;AN010; 0 00000A13 750E JNE D_$IF34 0 00000A15 2EC606[4C05]01 mov byte [cs:state_change],1 ; set the change state flag ;AN011; 0 00000A1B 2EC606[4B05]00 mov byte [cs:skip_check],0 ; reset skip_check ;AN010; 1964 ; $else ; else , its already clear ;AN010; 0 00000A21 EB02 JMP SHORT D_$EN34 1966 D_$IF34: 0 00000A23 B0FF mov al,0FFH ; and we are loaded ;AN010; 1968 ; $endif ; ;AN010; 1969 D_$EN34: 1970 ; $endif ; ;AN010; 1971 D_$EN30: 1972 1973 ; $else ; ;AN010; 0 00000A25 EB1E JMP SHORT D_$EN29 1975 D_$IF29: 0 00000A27 3C40 cmp al,40h ; is it IFSFUNC? ;AN010; 1977 ; $if ne ; if it is not ;AN010; 0 00000A29 7418 JE D_$IF39 1979 0 00000A2B 08C0 or al,al ; loop it any other value caus' ;AC010; 1981 Freeze: 1982 freeze equ Freeze ; NASM port label 0 00000A2D 75FE jnz freeze ; no one should EVER issue this ;AC010; 0 00000A2F 2E803E[4B05]01 cmp byte [cs:skip_check],1 ; is skip_check set ? ;AN010; 1985 ; $if e ; if it is ;AN011; 0 00000A35 7506 JNE D_$IF40 0 00000A37 2EC606[4C05]01 mov byte [cs:state_change],1 ; set the change state flag ;AN011; 1988 ; $endif ; ;AN011; 1989 D_$IF40: 0 00000A3D 2EC606[4B05]00 mov byte [cs:skip_check],0 ; and believe it ! ;AN011; 1991 1992 ; $endif ; ;AN010; 1993 D_$IF39: 0 00000A43 B0FF mov al,0FFH ; else - say we are here ;AN010; 1995 ; $endif ; ;AN010; 1996 D_$EN29: 0 00000A45 2E803E[4C05]01 cmp byte [cs:state_change],1 ; SHARE installed state may have change;AN011;d 1998 ; $if e ; - update DOS ;AN011; 0 00000A4B 751C JNE D_$IF44 0 00000A4D 50 push ax ; ;AN011; 0 00000A4E 06 push es ; this is interesting - ;AN011; 0 00000A4F B452 MOV AH,Get_In_Vars ; if SHARE =1 and DOS =1 - no change;AN011; 0 00000A51 CD21 INT 21h ; if SHARE = ;AN011; 2004 2005 ASSUME ES:DOSGROUP 2006 0 00000A53 2EA0[4B05] mov al,[cs:skip_check] ; get the SHARE operating mode ;AN011; 0 00000A57 3C01 cmp al,1 ; is it a /nc - tell DOS " 1 " ;AN011; 2009 ; $if ne ; if not ;AN011; 0 00000A59 7402 JE D_$IF45 0 00000A5B FEC8 dec al ; "full" SHARE - tell DOS " -1 " ;AN011; 2012 ; $endif ; ;AN011; 2013 D_$IF45: 2014 fShare equ fshare ; NASM port label 0 00000A5D 26A2[0000] MOV [es:fShare],al ; tell DOS we are here ;AN011; 0 00000A61 07 pop es ; ;AN011; 0 00000A62 58 pop ax ; ;AN011; 0 00000A63 2EC606[4C05]00 mov byte [cs:state_change],0 ; REset the change state flag ;AN011; 2019 ; $endif ; ;AN011; 2020 D_$IF44: 2021 2022 ASSUME ES:nothing 2023 0 00000A69 CF iret 2025 ContJ: 0 00000A6A 2EFF2E[5005] JMP far [cs:i2F.next] 2027 2028 2029 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:DOSGroup 2030 2031 %macro shareentry 1-* 2032 %rep %0 2033 J%1 proc far 2034 call %1 2035 ret 2036 J%1 endp 2037 %rotate 1 2038 %endrep 2039 %endmacro 2040 2041 shareentry MFT_Enter, MFTClose, MFTClu, MFTCloseP, MFTCloN, Set_Mult_Block, Clr_Mult_Block 2032 <1> %rep %0 2033 <1> J%1 proc far 2034 <1> call %1 2035 <1> ret 2036 <1> J%1 endp 2037 <1> %rotate 1 2038 <1> %endrep 2033 <2> J%1 proc far 0 00000A6F E8[0000] call %1 0 00000A72 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A73 E8[0000] call %1 0 00000A76 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A77 E8[0000] call %1 0 00000A7A CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A7B E8[0000] call %1 0 00000A7E CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A7F E8[0000] call %1 0 00000A82 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A83 E8[0000] call %1 0 00000A86 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A87 E8[0000] call %1 0 00000A8A CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2042 shareentry Chk_Block, MFT_Get, ShSave, ShChk, ShCol, ShCloseFile, ShSU 2032 <1> %rep %0 2033 <1> J%1 proc far 2034 <1> call %1 2035 <1> ret 2036 <1> J%1 endp 2037 <1> %rotate 1 2038 <1> %endrep 2033 <2> J%1 proc far 0 00000A8B E8[0000] call %1 0 00000A8E CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A8F E8[0000] call %1 0 00000A92 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A93 E814FD call %1 0 00000A96 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A97 E8F8FC call %1 0 00000A9A CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A9B E827FD call %1 0 00000A9E CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000A9F E8A8FD call %1 0 00000AA2 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2033 <2> J%1 proc far 0 00000AA3 E812FE call %1 0 00000AA6 CB ret 2036 <2> J%1 endp 2037 <2> %rotate 1 2043 2044 Procedure EcritShare,NEAR 2044 ****************** warning: proc EcritShare... [-w+user] 0 00000AA7 50 PUSH AX 0 00000AA8 B80180 MOV AX,8000h+critShare 2047 int_ibm equ int_IBM ; NASM port equate 0 00000AAB CD2A INT int_ibm 0 00000AAD 58 POP AX 0 00000AAE C3 ret 2051 EndProc EcritShare 2052 2053 Procedure LcritShare,NEAR 2053 ****************** warning: proc LcritShare... [-w+user] 0 00000AAF 50 PUSH AX 0 00000AB0 B80181 MOV AX,8100h+critShare 0 00000AB3 CD2A INT int_ibm 0 00000AB5 58 POP AX 0 00000AB6 C3 ret 2059 EndProc LcritShare 2060 2061 %ENDIF 2062 2063 BREAK 2064 2065 ;******************* START OF SPECIFICATIONS *********************************** 2066 ; 2067 ; first MFT record 2068 ; 2069 ; Note that the name field can have garbage after the trailing 2070 ; 00 byte. This is because the field might be too long, but 2071 ; not long enough (at least 16 extra bytes) to fragment. 2072 ; in this case we copy the length of the string area, not 2073 ; the length of the string and thus may copy tailing garbage. 2074 ; 2075 ;******************* END OF SPECIFICATIONS ************************************* 2076 2077 PoolSize equ 2048 2078 2079 PUBLIC MFT 2080 0 00000AB7 00 MFT DB 0 ; free 0 00000AB8 0008 DW PoolSize ; PoolSize bytes long 2083 2084 ; %IFn Installed 2085 ; 2086 ; DB (PoolSize-3) DUP(0) ; leave rest of record 2087 ;MEND DB -1 ; END record 2088 ; 2089 ;lck1 DW 0 ; link 2090 ; DB RLR_entry_struc_size-2 DUP(0) 2091 ;lck2 DW OFFSET lck1 wrt DOSGROUP ; link 2092 ; DB RLR_entry_struc_size-2 DUP(0) 2093 ;lck3 DW OFFSET lck2 wrt DOSGROUP ; link 2094 ; DB RLR_entry_struc_size-2 DUP(0) 2095 ;lck4 DW OFFSET lck3 wrt DOSGROUP ; link 2096 ; DB RLR_entry_struc_size-2 DUP(0) 2097 ;lck5 DW OFFSET lck4 wrt DOSGROUP ; link 2098 ; DB RLR_entry_struc_size-2 DUP(0) 2099 ;lck6 DW OFFSET lck5 wrt DOSGROUP ; link 2100 ; DB RLR_entry_struc_size-2 DUP(0) 2101 ;lck7 DW OFFSET lck6 wrt DOSGROUP ; link 2102 ; DB RLR_entry_struc_size-2 DUP(0) 2103 ;lck8 DW OFFSET lck7 wrt DOSGROUP ; link 2104 ; DB RLR_entry_struc_size-2 DUP(0) 2105 ; 2106 ;section SHARE ; CODE ENDS 2107 ; 2108 ; %warning out: Ignore this END error (blasted assembler) 2109 ; 2110 ; %ENDIF 2111 2112 %IF Installed 2113 2114 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:NOTHING 2115 2116 shareinit equ SHAREINIT ; NASM port label 2117 shareinit_minus_MFT equ shareinit - MFT 2118 %IF shareinit_minus_MFT LT PoolSize 0 00000ABA 0008 InitSpace DW PoolSize 2120 %ELSE 2121 InitSpace DW shareinit_minus_MFT 2122 %ENDIF 0 00000ABC 1400 InitLocks DW 20 2124 2125 2126 JTable LABEL BYTE 0 00000ABE ???????? DD ? 0 00000AC2 [E705][0000] dw JMFT_Enter, seg JMFT_Enter ; 1 MFT_enter 0 00000AC6 [EB05][0000] dw JMFTClose, seg JMFTClose ; 2 MFTClose 0 00000ACA [EF05][0000] dw JMFTClu, seg JMFTClu ; 3 MFTClu 0 00000ACE [F305][0000] dw JMFTCloseP, seg JMFTCloseP ; 4 MFTCloseP 0 00000AD2 [F705][0000] dw JMFTCloN, seg JMFTCloN ; 5 MFTCloN 0 00000AD6 [FB05][0000] dw JSet_Mult_Block, seg JSet_Mult_Block ; 6 Set_Mult_Block 0 00000ADA [FF05][0000] dw JClr_Mult_Block, seg JClr_Mult_Block ; 7 Clr_Mult_Block 0 00000ADE [0306][0000] dw JChk_Block, seg JChk_Block ; 8 Chk_Block 0 00000AE2 [0706][0000] dw JMFT_Get, seg JMFT_Get ; 9 MFT_get 0 00000AE6 [0B06][0000] dw JShSave, seg JShSave ; 10 ShSave 0 00000AEA [0F06][0000] dw JShChk, seg JShChk ; 11 ShChk 0 00000AEE [1306][0000] dw JShCol, seg JShCol ; 12 ShCol 0 00000AF2 [1706][0000] dw JShCloseFile, seg JShCloseFile ; 13 ShCloseFile 0 00000AF6 [1B06][0000] dw JShSU, seg JShSU ; 14 ShSU 2142 JTableLen equ $ - JTable 2143 2144 ; $SALUT (4,9,17,36) 2145 ;--------------------------------------- 2146 ; STRUCTURE TO DEFINE ADDITIONAL 2147 ; COMMAND LINE PARAMETERS 2148 ;--------------------------------------- 2149 PARMS LABEL DWORD 0 00000AFA [7606] DW OFFSET PARMSX ; POINTER TO PARMS STRUCTURE 0 00000AFC 00 DB 0 ; NO DELIMITER LIST FOLLOWS 0 00000AFD 00 DB 0 ; NUMBER OF ADDITIONAL DELIMITERS 2153 2154 ;--------------------------------------- 2155 ; STRUCTURE TO DEFINE SORT 2156 ; SYNTAX REQUIREMENTS 2157 ;--------------------------------------- 2158 PARMSX LABEL BYTE 0 00000AFE 0000 DB 0,0 ; THERE ARE NO POSITIONAL PARAMETERS 0 00000B00 01 DB 1 ; THERE ARE ONLY ONE TYPE OF SWITCH 0 00000B01 [7D06] DW OFFSET SW ; POINTER TO THE SWITCH DEFINITION AREA 0 00000B03 0000 DW 0 ; THERE ARE NO KEYWORDS IN SHARE SYNTAX 2163 2164 ;--------------------------------------- 2165 ; STRUCTURE TO DEFINE THE SWITCHES 2166 ;--------------------------------------- 2167 2168 SW LABEL WORD 0 00000B05 0180 DW 08001H ; MUST BE NUMERIC 0 00000B07 0000 DW 0 ; NO FUNCTION FLAGS 0 00000B09 [9B06] DW OFFSET SWITCH_BUFF ; PLACE RESULT IN SWITCH BUFFER 0 00000B0B [9006] DW OFFSET VALUES ; NEED VALUE LIST 0 00000B0D 03 DB 3 ; TWO SWITCHES IN FOLLOWING LIST 0 00000B0E 2F4600 F_SW DB "/F",0 ; /F: INDICATES n FILESPACE REQUESTED 0 00000B11 2F4C00 L_SW DB "/L",0 ; /L: INDICATES m LOCKS REQUESTED 0 00000B14 2F4E4300 N_SW DB "/NC",0 ; /NC: INDICATES no checking required 2177 2178 2179 ;--------------------------------------- 2180 ; VALUE LIST DEFINITION FOR n 2181 ;--------------------------------------- 2182 2183 VALUES LABEL BYTE 0 00000B18 01 DB 1 ; ONE VALUE ALLOWED 0 00000B19 01 DB 1 ; ONLY ONE RANGE 0 00000B1A 01 DB FILE_SWITCH ; IDENTIFY IT AS n 0 00000B1B 01000000FFFF0000 DD 1,65535 ; USER CAN SPECIFY /+1 THROUGH /+65535 2188 2189 ;--------------------------------------- 2190 ; RETURN BUFFER FOR SWITCH INFORMATION 2191 ;--------------------------------------- 2192 ; $SALUT (4,17,27,36) 2193 2194 SWITCH_BUFF LABEL BYTE 0 00000B23 ?? SW_TYPE DB ? ; TYPE RETURNED 0 00000B24 ?? SW_ITEM_TAG DB ? ; SPACE FOR ITEM TAG 0 00000B25 ???? SW_SYN DW ? ; POINTER TO SWITCH LIST ENTRY 0 00000B27 ???????? SW_VALUE DD ? ; SPACE FOR VALUE 2199 2200 ; $SALUT (4,4,9,41) 2201 2202 Break 2203 2204 ;******************* START OF SPECIFICATIONS *********************************** 2205 ; 2206 ; INIT - INITalization routines 2207 ; 2208 ;******************* END OF SPECIFICATIONS ************************************* 2209 2210 Procedure Init,NEAR 2210 ****************** warning: proc Init... [-w+user] 2211 0 00000B2B 0E PUSH CS 0 00000B2C 1F POP DS 2214 2215 ASSUME DS:SHARE 2216 0 00000B2D 8B1E[3206] MOV BX,[InitSpace] 2218 0 00000B31 83EB03 SUB BX,3 0 00000B34 BE[2F06] MOV SI,OFFSET MFT 0 00000B37 895C01 MOV WORD PTR [SI+1],BX ; length of first item 0 00000B3A 01DE ADD SI,BX ; link to end of structure 0 00000B3C C604FF MOV BYTE PTR [SI],-1 ; signal end 0 00000B3F 46 INC SI ; point to next free byte 2225 2226 initlocks equ InitLocks ; NASM port label 0 00000B40 8B0E[3406] MOV CX,[initlocks] ; count for loop 0 00000B44 B80000 MOV AX,0 2229 2230 ; $do ; ;AC000; 2231 D_$DO48: 2232 2233 RLR_next equ rlr_next ; NASM port equate 0 00000B47 8904 MOV [SI + RLR_next],AX ; link in previous 0 00000B49 89F0 MOV AX,SI ; this is now previous 2236 RLR_Entry_struc_size equ RLR_entry_struc_size ; NASM port equate 0 00000B4B 83C612 ADD SI,RLR_Entry_struc_size ; move to next object 2238 2239 ; $enddo loop ; ;AC000; 0 00000B4E E2F7 LOOP D_$DO48 2241 0 00000B50 A3[0000] MOV [FreLock],AX ; point to beginning of free list 2243 0 00000B53 8CCA MOV DX,CS 0 00000B55 8CC3 MOV BX,ES 0 00000B57 29DA SUB DX,BX 0 00000B59 83C60F ADD SI,15 0 00000B5C D1DE RCR SI,1 0 00000B5E D1EE SHR SI,1 0 00000B60 D1EE SHR SI,1 0 00000B62 D1EE SHR SI,1 2252 0 00000B64 01D6 ADD SI,DX 0 00000B66 56 PUSH SI ; # of paras for share on stack 2255 0 00000B67 B82F35 MOV AX,(Get_Interrupt_Vector << 8) + 2Fh 0 00000B6A CD21 INT 21h 0 00000B6C 891E[5005] MOV WORD PTR [i2F.next],BX 0 00000B70 8C06[5205] MOV WORD PTR [i2F.next + 2],ES 0 00000B74 B82F25 MOV AX,(Set_Interrupt_Vector << 8) + 2Fh 0 00000B77 BA[4E05] MOV DX, i2F 0 00000B7A CD21 INT 21h 2263 ;--------------------------------------- 2264 ; Notify the DOS that we are around so that 2265 ; the DOS can make expensive calls to us. 2266 ;--------------------------------------- 0 00000B7C B452 MOV AH,Get_In_Vars 0 00000B7E CD21 INT 21h 2269 2270 ASSUME ES:DOSGROUP 2271 0 00000B80 A0[4B05] mov al,[skip_check] ; get the SHARE operating mode ;AN011; 0 00000B83 3C01 cmp al,1 ; is it a /nc - tell DOS " 1 " ;AN011; 2274 2275 ; $if ne ; if not ;AN011; 0 00000B85 7402 JE D_$IF50 0 00000B87 FEC8 dec al ; "full" SHARE - tell DOS " -1 " ;AN011; 2278 ; $endif ; 2279 D_$IF50: 2280 0 00000B89 26A2[0000] MOV [es:fShare],al ; tell DOS we are here ;AC011; 2282 ;--------------------------------------- 2283 ; Cram in the new jump table 2284 ;--------------------------------------- 0 00000B8D FA CLI 0 00000B8E BE[3606] MOV SI,OFFSET JTable 0 00000B91 BF[0000] MOV DI,OFFSET JShare 0 00000B94 B91E00 MOV CX,JTableLen/2 0 00000B97 F3A5 REP MOVSW 2290 ;--------------------------------------- 2291 ; Examine the size of the FCB cache. 2292 ; If it is NOT the system default of 4,0 2293 ; change it (via reallocation) to 16,8. 2294 ; The old table is lost. 2295 ;--------------------------------------- 2296 ASSUME DS:NOTHING 2297 0 00000B99 26833E[0000]00 CMP word [es:KeepCount],0 2299 2300 ; $if z,and ; if the ",0" part and ;AC000; 0 00000B9F 754F JNZ D_$IF52 2302 0 00000BA1 26C5771A LDS SI,[ES:BX + SYSI_FCB] ; point to the existing cache 2304 sfCount equ SFCount ; NASM port equate 0 00000BA5 837C0404 CMP word [SI + sfCount],4 2306 2307 ; $if z ; if the "4," part then ;AC000; 0 00000BA9 7545 JNZ D_$IF52 2309 2310 ;--------------------------------------- 2311 ; Whammo, we need to allocate 16 * size 2312 ; of SF_entry + size of sfTable. 2313 ; Compute this size in paragraphs 2314 ;--------------------------------------- 0 00000BAB B81000 MOV AX,16 0 00000BAE B93B00 MOV CX,sf_entry_struc_size 0 00000BB1 F7E1 MUL CX 2318 sf_struc_size equ SF_struc_size ; NASM port equate 0 00000BB3 83C006 ADD AX,(sf_struc_size) - 2 2320 ;--------------------------------------- 2321 ; This size is in bytes... 2322 ; Round up to paragraph size 2323 ;--------------------------------------- 0 00000BB6 83C00F ADD AX,0Fh 0 00000BB9 D1D8 RCR AX,1 0 00000BBB D1E8 SHR AX,1 0 00000BBD D1E8 SHR AX,1 0 00000BBF D1E8 SHR AX,1 2329 ;--------------------------------------- 2330 ; AX is the number of paragraphs to add. 2331 ; Word on stack is current TNR size. 2332 ; Make dos point to new table 2333 ;--------------------------------------- 0 00000BC1 26C7471A0000 MOV WORD PTR [ES:BX + SYSI_FCB],0 0 00000BC7 268C571C MOV WORD PTR [ES:BX + SYSI_FCB + 2],SS 0 00000BCB 5E POP SI 0 00000BCC 2601771C ADD WORD PTR [ES:BX + SYSI_FCB + 2],SI 2338 ;--------------------------------------- 2339 ; Initialize table parts, next link 2340 ; and size 2341 ;--------------------------------------- 0 00000BD0 268E5F1C MOV DS,WORD PTR [ES:BX + SYSI_FCB + 2] 2343 sfLink equ SFLink ; NASM port equate 0 00000BD4 C7060000FFFF MOV WORD PTR [sfLink],-1 0 00000BDA C7060200FFFF MOV WORD PTR [sfLink+2],-1 2346 sfcount equ SFCount ; NASM port equate 0 00000BE0 C70604001000 MOV word [sfcount],16 2348 ;--------------------------------------- 2349 ; Set up succeeding LRU size 2350 ;--------------------------------------- 0 00000BE6 26C706[0000]0800 MOV word [es:KeepCount],8 2352 0 00000BED 01C6 ADD SI,AX 0 00000BEF 56 PUSH SI 2355 2356 ; $endif ; endif - "4,0" ;AC000; 2357 D_$IF52: 2358 2359 ;--------------------------------------- 2360 ; Clean out the FCB Cache 2361 ;--------------------------------------- 0 00000BF0 26C47F1A LES DI,[ES:BX + SYSI_FCB] 2363 2364 ASSUME ES:Nothing 2365 0 00000BF4 268B4D04 MOV CX,[ES:DI + SFCount] 0 00000BF8 8D7D06 LEA DI,[DI + SFTable] 2368 2369 ; $do ; ;AC000; 2370 D_$DO54: 2371 0 00000BFB 26C7050000 MOV word [ES:DI + sf_ref_count],0 0 00000C00 26C745150000 MOV WORD PTR [ES:DI + sf_position],0 0 00000C06 26C745170000 MOV WORD PTR [ES:DI + sf_position + 2],0 0 00000C0C 83C73B ADD DI,sf_entry_struc_size 2376 2377 ; $enddo loop ; ;AC000; 0 00000C0F E2EA LOOP D_$DO54 2379 0 00000C11 FB STI 2381 2382 ASSUME ES:NOTHING 2383 0 00000C12 31DB XOR BX,BX 0 00000C14 B90500 MOV CX,5 ; StdIN,StdOUT,StdERR,StdAUX,StdPRN 2386 2387 ; $do ; Close STD handles before ;AC000; 2388 D_$DO56: 2389 ; keep process 2390 CLOSE equ Close ; NASM port equate 0 00000C17 B43E MOV AH,CLOSE 0 00000C19 CD21 INT 21H 0 00000C1B 43 INC BX 2394 2395 ; $enddo loop ; ;AC000; 0 00000C1C E2F9 LOOP D_$DO56 2397 0 00000C1E 5A POP DX ; T+R size in DX 0 00000C1F B80031 MOV AX,(Keep_Process << 8) + 0 0 00000C22 CD21 INT 21h 2401 EXIT equ Exit ; NASM port equate 0 00000C24 B8014C MOV AX,(EXIT << 8) + 1 0 00000C27 CD21 INT 21h ; We'er now resident, return to DOS 2404 2405 EndProc Init 2406 2407 Break 2408 2409 ;******************* START OF SPECIFICATIONS *********************************** 2410 ; 2411 ; SHAREINIT - Share initialization entry point 2412 ; 2413 ;******************* END OF SPECIFICATIONS ************************************* 2414 2415 ..start: 2416 Procedure SHAREINIT,NEAR 2416 ****************** warning: proc SHAREINIT... [-w+user] 2417 2418 ASSUME CS:SHARE,DS:NOTHING,ES:NOTHING,SS:STACK 2419 2420 ; int 3 0 00000C29 90 nop 0 00000C2A 90 nop 2423 2424 0 00000C2B 1E PUSH DS ; save PSP segment for later stack ;AC001; 2426 ; relocation 2427 2428 ;--------------------------------------- 2429 ; Load Messages 2430 ;--------------------------------------- 0 00000C2C E8AE00 call ShLoadMsg ; ;AN000; 2432 ;--------------------------------------- 2433 ; At this point, the DOS version is OK. 2434 ; (checked by SYSLOADMSG) 2435 ; Now - Check the DOS data version 2436 ;--------------------------------------- 2437 ; $if c,or ; if not same as us ;AC009; 0 00000C2F 720C JC D_$LL58 2439 0 00000C31 B452 MOV AH,Get_In_Vars 0 00000C33 CD21 INT 21h 2442 2443 ASSUME ES:DOSGROUP 2444 0 00000C35 26803E[0000]01 CMP byte [es:DataVersion],ShareDataVersion 2446 2447 ASSUME ES:NOTHING 2448 2449 ; $if ne ; if not same as us ;AC000; 0 00000C3B 7406 JE D_$IF58 2451 D_$LL58: 2452 Utility_Msg_CLASS equ UTILITY_MSG_CLASS ; NASM port equate 0 00000C3D B801FF mov ax,(Utility_Msg_CLASS << 8) + Bad_DOS_Ver ; ;AN000; 0 00000C40 E8BB00 call ShDispMsg ; ;AN000; 2455 ; $endif ; endif - not same as us ;AC000; 2456 D_$IF58: 2457 2458 ;--------------------------------------- 2459 ; Deallocate memory if possible 2460 ;--------------------------------------- 2461 pdb_environ equ PDB_environ ; NASM port equate 0 00000C43 A12C00 mov ax,[pdb_environ] 0 00000C46 09C0 or ax,ax 2464 2465 ; $if nz ; if > 0 deallocate memory ;AC000; 0 00000C48 7406 JZ D_$IF60 0 00000C4A 8EC0 mov es,ax 2468 dealloc equ Dealloc ; NASM port equate 0 00000C4C B449 mov ah,dealloc 0 00000C4E CD21 int 21h 2471 ; $endif ; endif - > 0 deallocate memory ;AC000; 2472 D_$IF60: 2473 2474 ;--------------------------------------- 2475 ; Parse the command line 2476 ;--------------------------------------- 0 00000C50 E81501 call ShComndParse ; ;AN000; 2478 ;--------------------------------------- 2479 ; Check to see if share already installed. 2480 ;--------------------------------------- 0 00000C53 2EA0[4B05] mov al,[cs:skip_check] ; ;AN010; 0 00000C57 0C80 or al,80h ; signal its SHARE calling ;AN010; 2483 multShare equ MultSHARE ; NASM port equate 0 00000C59 B410 mov ah,multShare ; ;AC010; 0 00000C5B CD2F INT 2Fh ; ;AC010; 0 00000C5D 3CFF CMP AL,0FFh ; ;AC010; 2487 2488 ; $if z ; if we'er already loaded ;AC010; 0 00000C5F 7506 JNZ D_$IF62 0 00000C61 B802FF mov ax,(UTILITY_MSG_CLASS << 8) + Sh_Already_Loaded ; ;AC010; 0 00000C64 E89700 call ShDispMsg ; ;AC010; 2492 ; $endif ; endif - we'er already loaded ;AC010; 2493 D_$IF62: 2494 2495 ;--------------------------------------- 2496 ; Check to see if share installed and 2497 ; a toggle was just performed 2498 ;--------------------------------------- 0 00000C67 3CF0 CMP AL,0F0h ; ;AN010; 2500 2501 ; $if z ; if we'er already loaded ;AN010; 0 00000C69 7505 JNZ D_$IF64 2503 0 00000C6B B8004C MOV AX,(EXIT << 8) ; ;AN010; 0 00000C6E CD21 INT 21h ; Return to DOS with RC = 0 ;AN010; 2506 2507 ; $endif ; endif - we'er already loaded ;AN010; 2508 D_$IF64: 2509 2510 ;--------------------------------------- 2511 ; All set to initialize the world. 2512 ; Make sure that we have enough memory 2513 ; for everything in our little 64K here. 2514 ; First get avail count of paras. 2515 ;--------------------------------------- 0 00000C70 07 pop es ; recover PSP segment ;AC002; 0 00000C71 06 push es ; ;AC002; 0 00000C72 8CCB MOV BX,CS 2519 PDB_Block_Len equ PDB_block_len ; NASM port equate 0 00000C74 26A10200 MOV AX,[ES:PDB_Block_Len] 0 00000C78 29D8 SUB AX,BX 2522 ;--------------------------------------- 2523 ; AX has the number of paragraphs 2524 ; available to us after the beginning 2525 ; of CS. Max this out at 64K. 2526 ;--------------------------------------- 0 00000C7A 3D0010 CMP AX,1000h 2528 2529 ; $if a ; if more than we can handle ;AC000; 0 00000C7D 7603 JNA D_$IF66 0 00000C7F B80010 MOV AX,1000h ; force it 2532 ; $endif ; endif - more than we can handle ;AC000; 2533 D_$IF66: 2534 2535 ;--------------------------------------- 2536 ; Take AX paragraphs and convert them 2537 ; into BX:CX bytes. 2538 ;--------------------------------------- 0 00000C82 31DB XOR BX,BX 0 00000C84 D1E0 SHL AX,1 0 00000C86 D1E0 SHL AX,1 0 00000C88 D1E0 SHL AX,1 0 00000C8A D1E0 SHL AX,1 0 00000C8C 83D300 ADC BX,0 0 00000C8F 89C1 MOV CX,AX 2546 ;--------------------------------------- 2547 ; compute in DX:AX, the size 2548 ; requested by the user 2549 ;--------------------------------------- 0 00000C91 2EA1[3406] MOV AX,[cs:initlocks] 0 00000C95 BE1200 MOV SI,RLR_Entry_struc_size 0 00000C98 F7E6 MUL SI 0 00000C9A 05[2F06] ADD AX,OFFSET MFT 0 00000C9D 83D200 ADC DX,0 0 00000CA0 2E0306[3206] ADD AX,[cs:InitSpace] 0 00000CA5 83D200 ADC DX,0 2557 ;--------------------------------------- 2558 ; Compare the 32 bit sizes DX:AX and BX:CX. 2559 ; If BX:CX is smaller, then we 2560 ; are out of memory. 2561 ;--------------------------------------- 2562 0 00000CA8 39DA CMP DX,BX ; try upper half first 2564 2565 ; $if a,or ; if most significant is bigger or ;AC000; 0 00000CAA 7706 JA D_$LL68 2567 2568 ; $if e,and ; if equal and ;AC000; 0 00000CAC 750A JNE D_$IF68 2570 0 00000CAE 39C8 CMP AX,CX ; 2572 2573 ; $if a ; if least significant is bigger ;AC000; 0 00000CB0 7606 JNA D_$IF68 2575 D_$LL68: 2576 0 00000CB2 B80801 mov ax,(EXT_ERR_CLASS << 8) + No_Mem_Error ; issue error message ;AN000; 2578 0 00000CB5 E84600 call ShDispMsg ; ;AN000; 2580 2581 ; $endif ; endif - bigger ;AC000; 2582 D_$IF68: 2583 2584 ;-------------------------------------- 2585 ; Move stack to PSP area. Otherwise we 2586 ; will run into problems with growing 2587 ; the stack into the lock records. 2588 ;--------------------------------------- 0 00000CB8 58 POP AX ; this is the entry value for DS (PSP) ;AC001; 0 00000CB9 8ED0 MOV SS,AX ; ;AC001; 0 00000CBB BC0001 MOV SP,100h ; ;AC001; 2592 2593 ASSUME SS:NOTHING 2594 ;--------------------------------------- 2595 ; Continue with rest of initialization 2596 ;--------------------------------------- 2597 INIT equ Init ; NASM port label 0 00000CBE E96AFE JMP INIT 2599 2600 EndProc SHAREINIT 2601 2602 global amis_sign 0 00000CC1 00 even 2604 amis_sign: 0 00000CC2 65636D20 .ven: fill 8, 32, db "ecm" 0 00000CCA 6C444F5320 .prod: fill 8, 32, db "lDOS" 2607 amis_id: ; must be directly after amis_sign 0 00000CD2 0000 dw 0 0 00000CD4 0000 .seq: dw 0 ; sequential number 0 00000CD6 06736861726572 .us: counted "sharer" ; our id name 2611 2612 2613 Break 2614 2615 ;******************* START OF SPECIFICATIONS *********************************** 2616 ; 2617 ; NAME: ShLoadMsg - Share Load Message 2618 ; 2619 ; FUNCTION: Load the Share messages into the message buffer. 2620 ; 2621 ; INPUT: None 2622 ; 2623 ; OUTPUT: Messages loaded into the message buffer and Message 2624 ; Sevices code initalized 2625 ; 2626 ; REGISTERS USED: DI AX CX DX 2627 ; (NOT RESTORED) 2628 ; 2629 ; LINKAGE: Call near 2630 ; 2631 ; NORMAL CF = O 2632 ; EXIT: 2633 ; 2634 ; ERROR CF = 1 2635 ; EXIT: 2636 ; 2637 ; CHANGE 04/15/87 - First release 2638 ; LOG: 2639 ; 2640 ;******************* END OF SPECIFICATIONS ************************************* 2641 2642 ;--------------------------------------- 2643 ; Message Equates 2644 ;--------------------------------------- 2645 2646 ; $SALUT (4,27,34,41) 2647 2648 Bad_DOS_Ver equ 1 ; Incorrect DOS version ;AN000; 2649 Sh_Already_Loaded equ 2 ; SHARE already loaded message number ;AN000; 2650 No_Mem_Error equ 8 ; insufficient memory message number ;AN000; 2651 2652 ; $SALUT (4,4,9,41) 2653 2654 Procedure ShLoadMsg,near ; ;AN000; 2654 ****************** warning: proc ShLoadMsg... [-w+user] 2655 ;--------------------------------------- 2656 ; Load the Messages 2657 ;--------------------------------------- 2658 EXTRN SYSLOADMSG:NEAR ; ;AN000; 2659 0 00000CDD E8[0000] call SYSLOADMSG ; ;AN000; 2661 2662 ; $IF C ; if we have a MAJOR problem ;AN000; 0 00000CE0 730A JNC D_$IF70 0 00000CE2 88F4 mov ah,dh ; save the class 0 00000CE4 E81700 call ShDispMsg ; ;AN000; 2666 ; For pre DOS 2.0, we may come back 0 00000CE7 31C0 xor ax,ax ; here - so do it the old way 0 00000CE9 16 push ss ; just in case 0 00000CEA 50 push ax ; 2670 2671 xxx proc far ; ;AN000; 0 00000CEB CB ret ; ;AN000; 2673 xxx endp ; ;AN000; 2674 2675 ; $ENDIF ; endif - we have a MAJOR problem ;AN000; 2676 D_$IF70: 2677 2678 0 00000CEC C3 ret ; ;AN000; 2680 2681 EndProc ShLoadMsg ; 2682 2683 Break 2684 2685 ;******************* START OF SPECIFICATIONS *********************************** 2686 ; 2687 ; NAME: ShDispMsg - Share Display Message 2688 ; 2689 ; FUNCTION: Display the messages for share 2690 ; 2691 ; INPUT: AX = message number - AH - Class 2692 ; AL - Number 2693 ; 2694 ; OUTPUT: - Messages output to Output Device 2695 ; - Exit to DOS 2696 ; 2697 ; REGISTERS USED: CX DX 2698 ; (NOT RESTORED) 2699 ; 2700 ; LINKAGE: Call near 2701 ; 2702 ; NORMAL CF = O 2703 ; EXIT: 2704 ; 2705 ; ERROR CF = 1 2706 ; EXIT: CX = 0 - INCORRECT DOS VERSION 2707 ; 2708 ; CHANGE 04/15/87 - First release 2709 ; LOG: 2710 ; 2711 ;******************* END OF SPECIFICATIONS ************************************* 2712 2713 ; $SALUT (4,27,34,41) 2714 2715 ; The following structure is a 2716 ; SYSMSG SUBLIST control block. 2717 ; It is initalized for the "already 2718 ; installed " message. The parse 2719 ; routine will set it up to work 2720 ; for parseing. 2721 SUBLIST LABEL WORD 2722 0 00000CED 0B db sub_size ; size of sublist 0 00000CEE 00 db 0 ; reserved 0 00000CEF [7008] msg_offset dw offset SHARE_Name ; insert 'SHARE' 2726 2727 msg_segment LABEL WORD 2728 2729 %IFN INSTALLED 2730 2731 dw CODE 2732 2733 %ELSE 2734 0 00000CF1 [0000] dw SHARE 2736 2737 %ENDIF 2738 0 00000CF3 01 num_ins db 1 ; only one insert 0 00000CF4 10 db Char_Field_ASCIIZ ; data type flag - ascii z string 0 00000CF5 05 max_ins db SHARE_Name_Size ; maximum field size 0 00000CF6 05 min_ins db SHARE_Name_Size ; minimum field size 0 00000CF7 20 db " " ; pad character 2744 2745 sub_size equ $ - SUBLIST 2746 2747 SHARE_Name LABEL WORD 2748 0 00000CF8 5348415245 db "SHARE" 2750 2751 Share_Name equ SHARE_Name ; NASM port label 2752 SHARE_Name_Size equ $ - Share_Name 2753 0 00000CFD 00 db 0 ; make it a Z string 2755 ; $SALUT (4,4,9,41) 2756 2757 Procedure ShDispMsg,near ; ;AN000; 2757 ****************** warning: proc ShDispMsg... [-w+user] 2758 ;--------------------------------------- 2759 ; Set up required parameters 2760 ;-------------------------------------- 0 00000CFE BB0200 MOV BX,STDERR ;display message on STD ERROR ;AN000; 0 00000D01 31C9 XOR CX,CX ;no substitution required ;AN000; 0 00000D03 31D2 XOR DX,DX ;set flags to 0 ;AN000; 0 00000D05 FECE DEC DH ;and class to utility ;AN000; 0 00000D07 80FC02 cmp ah,PARSE_ERR_CLASS ; 2766 ; $if be,and ; ;AC009; 0 00000D0A 7726 JNBE D_$IF72 0 00000D0C 88E6 mov dh,ah ; 2769 ; $if e ; set up implied substitution ;AC009; 0 00000D0E 7522 JNE D_$IF72 2771 2772 ASSUME DS:nothing,ES:DOSGROUP 2773 0 00000D10 2E880E[6B08] mov [cs:num_ins],cl ; set number of inserts to 0 ;AN009; 0 00000D15 2EC606[6D08]30 mov BYTE [cs:max_ins],030h ; set maximum size of insert ;AN009; 0 00000D1B 2EC606[6E08]01 mov BYTE [cs:min_ins],1 ; set minimum size of insert ;AN009; 0 00000D21 1E push ds ; set up segment ;AN009; 0 00000D22 2E8F06[6908] pop word [cs:msg_segment] ; ;AN009; 0 00000D27 C60400 mov BYTE PTR [si],0 ; turn it into a ASCIIZ string ;AN009; 0 00000D2A 2E3B36[6708] cmp si,[cs:msg_offset] ; is there something there? ;AN009; 2781 ; $if a ; if it is... ;AN009; 0 00000D2F 7601 JNA D_$IF73 0 00000D31 41 inc cx ; ;AN009; 2784 ; $endif ; ;AN009; 2785 D_$IF73: 2786 ; $endif ; 2787 D_$IF72: 0 00000D32 3C02 cmp al,Sh_Already_Loaded ; SHARE already loaded message ? ;AN000; 2789 ; $if e ; if it is... ;AN000; 0 00000D34 7508 JNE D_$IF76 0 00000D36 41 inc cx ; 2792 SHARE_name equ SHARE_Name ; NASM port label 0 00000D37 2EC706[6708][7008] mov word [cs:msg_offset],OFFSET SHARE_name ; ensure the pointer is right ;AN010; 2794 ; $endif ; 2795 D_$IF76: 0 00000D3E 0E push cs ; ensure that SYSMSG has proper ;AC009; 0 00000D3F 1F pop ds ; addressability ;AC009; 0 00000D40 8D36[6508] lea si,[SUBLIST] ; point to sublist ;AC009; 0 00000D44 30E4 xor ah,ah ; ;AN000; 2800 2801 ;-------------------------------------- 2802 ; Output the Message 2803 ;--------------------------------------- 2804 EXTRN SYSDISPMSG:NEAR ; ;AN000; 2805 0 00000D46 E8[0000] CALL SYSDISPMSG ; ;AN000; 2807 2808 ; $IF C ; if error occured ;AN000; 0 00000D49 7306 JNC D_$IF78 2810 0 00000D4B E80900 CALL Get_DOS_Error ; a DOS extended error occured ;AN000; 0 00000D4E E8[0000] CALL SYSDISPMSG ; try to issue it ;AN000; 2813 2814 ; $ENDIF ; endif - error occured ;AN000; 2815 D_$IF78: 2816 0 00000D51 B8FF4C MOV AX,(EXIT << 8) + 0FFH ; exit to DOS ;AN000; 0 00000D54 CD21 INT 21h ; ;AN000; 2819 0 00000D56 C3 ret ; may return if pre DOS 2.0 ;AN000; 2821 2822 EndProc ShDispMsg ; ;AN000; 2823 2824 BREAK < Get_DOS_Error > 2825 2826 ;******************* START OF SPECIFICATIONS *********************************** 2827 ;Routine name: Get_DOS_Error 2828 ;******************************************************************************* 2829 ; 2830 ;Description: Call DOS to obtain DOS extended error # 2831 ; 2832 ;Called Procedures: None 2833 ; 2834 ;Input: None 2835 ; 2836 ;Output: AX = error number 2837 ; DH = DOS extended error class 2838 ; 2839 ;Change History: Created 5/01/87 FG 2840 ; 2841 ;******************* END OF SPECIFICATIONS ************************************* 2842 ;******************+ START OF PSEUDOCODE +************************************** 2843 ; 2844 ; START Get_DOS_Error 2845 ; 2846 ; call DOS for extended error (INT21 GetExtendedError + 00 <5900>) 2847 ; set up registers for return 2848 ; ret 2849 ; 2850 ; END Get_DOS_Error 2851 ; 2852 ;******************- END OF PSEUDOCODE -************************************** 2853 2854 public Get_DOS_Error 2855 2856 Get_DOS_Error PROC NEAR 2857 0 00000D57 B80059 mov ax,(GetExtendedError << 8) ; DOS ext. error ;AN000; 0 00000D5A 31DB xor bx,bx 0 00000D5C 06 push es ; ;AN000; 0 00000D5D CD21 INT 21h ; GetExtendedError + not_used <5900>;AN000; 0 00000D5F 07 pop es 0 00000D60 BB0200 mov bx,STDERR ; fix up bx ;AN000; 0 00000D63 31C9 xor cx,cx ; fix up cx ;AN000; 0 00000D65 B601 mov dh,EXT_ERR_CLASS ; set class to dos error 2866 0 00000D67 C3 ret ; ;AN000; 2868 2869 ENDPROC Get_DOS_Error 2870 2871 Break 2872 2873 ;******************* START OF SPECIFICATIONS *********************************** 2874 ; 2875 ; NAME: ShComndParse - Share Command line Parser 2876 ; 2877 ; FUNCTION: Call the DOS PARSE Service Routines to process the command 2878 ; line. Search for valid switches (/F:n and /L:m) and 2879 ; update the values for file size and number of locks accordingly 2880 ; 2881 ; INPUT: Parameter string from command line in the PSP 2882 ; 2883 ; OUTPUT: INITspace and INITlocks are updated. 2884 ; 2885 ; REGISTERS USED: ES DI AX BX CX DX 2886 ; (NOT RESTORED) 2887 ; 2888 ; LINKAGE: Call 2889 ; 2890 ; NORMAL - If /F:n specified, then INITspace is updated. 2891 ; EXIT: - If /L:m specified, then INITlocks is updated. 2892 ; 2893 ; ERROR If user enters: 2894 ; EXIT: - any parameter or switch other than /F:n or /L:m 2895 ; - an invalid value for "n" or "m" 2896 ; then this routine will display the "Invalid Parameter" 2897 ; error message and terminate. 2898 ; 2899 ; EXTERNAL - System parse service routines 2900 ; REFERENCES: - INT21 - GET PSP Function Call 062h 2901 ; 2902 ; CHANGE 04/15/87 - First release 2903 ; LOG: 2904 ; 2905 ;******************* END OF SPECIFICATIONS ************************************* 2906 ;******************+ START OF PSEUDOCODE +************************************** 2907 ; 2908 ; START 2909 ; 2910 ; return 2911 ; 2912 ; END 2913 ; 2914 ;******************- END OF PSEUDOCODE -************************************* 2915 2916 ; $SALUT (4,27,34,41) 2917 2918 ;-------------------------------------- 2919 ; Parse Equates 2920 ;-------------------------------------- 2921 2922 EOL equ -1 ; Indicator for End-Of-Line ;AN000; 2923 NOERROR equ 0 ; Return Indicator for No Errors ;AN000; 2924 FILE_SWITCH equ 1 ; this is a file switch ;AN000; 2925 LOCK_SWITCH equ 2 ; this is a lock switch ;AN000; 2926 Syntax_Error equ 9 ; maximum PARSE error # ;AN000; 2927 2928 ; $SALUT (4,4,9,41) 2929 2930 Procedure ShComndParse,near ; ;AN000; 2930 ****************** warning: proc ShComndParse... [-w+user] 2931 ;-------------------------------------- 2932 ; Get address of command line 2933 ;-------------------------------------- 2934 EXTRN SYSPARSE:NEAR ; ;AN000; 2935 0 00000D68 BE8100 MOV SI,0081H ; OFFSET OF COMMAND LINE IN PSP ;AN000; 0 00000D6B B462 MOV AH,62H ; AH=GET PSP ADDRESS FUNCTION CALL ;AN000; 0 00000D6D CD21 INT 21H ; PSP SEGMENT RETURNED IN BX ;AN000; 0 00000D6F 8EDB MOV DS,BX ; PUT PSP SEG IN DS ;AN000; 0 00000D71 B90000 MOV CX,0 ; NUMBER OF PARMS PROCESSED SO FAR ;AN000; 0 00000D74 0E PUSH CS ; ;AN000; 0 00000D75 07 POP ES ; ;AN000; 2943 2944 ASSUME ES:SHARE ; ;AN000; 2945 2946 ;-------------------------------------- 2947 ; Loop for each operand at DS:SI 2948 ;-------------------------------------- 2949 ; $do ; ;AN000; 2950 D_$DO80: 2951 0 00000D76 8D3E[7206] LEA DI,[PARMS] ; ADDRESS OF PARSE CONTROLS ;AN000; 0 00000D7A BA0000 MOV DX,0 ; RESERVED ;AN000; 0 00000D7D 268936[6708] mov [es:msg_offset],si ; save the start scan point ;AC009; 0 00000D82 E8[0000] CALL SYSPARSE ; PARSE IT! ;AN000; 0 00000D85 83F8FF CMP AX,EOL ; ARE WE AT END OF COMMAND LINE ? ;AN000; 2957 2958 ; $leave e ; ;AN000; 0 00000D88 7456 JE D_$EN80 2960 0 00000D8A 83F800 CMP AX,NOERROR ; ANY ERRORS? ;AN000; 2962 2963 ; $if ne,or ; if parse says error or ;AN000; 0 00000D8D 750B JNE D_$LL82 2965 0 00000D8F B80900 MOV AX,Syntax_Error ; Parse syntax error - just in case ;AN000; 0 00000D92 89D3 MOV BX,DX ; PLACE RESULT ADDRESS IN BX ;AN000; 0 00000D94 81FB[9B06] CMP BX,OFFSET SWITCH_BUFF ; ;AN000; 2969 2970 ; $if ne ; if no pointer ;AN000; 0 00000D98 7403 JE D_$IF82 2972 D_$LL82: 2973 0 00000D9A E84400 call PARSE_ERROR ; call error routine ;AN000; 2975 2976 ; $endif ; endif - error ;AN000; 2977 D_$IF82: 2978 0 00000D9D 26A1[9F06] MOV AX,WORD PTR [es:SW_VALUE] ; load the value ;AN000; 0 00000DA1 268B1E[9D06] MOV BX,[es:SW_SYN] ; load pointer to synonym ;AN000; 2981 2982 ;-------------------------------------- 2983 ; If user said /F:n, then 2984 ;-------------------------------------- 2985 0 00000DA6 81FB[8606] CMP BX,OFFSET F_SW ; IF USER SPECIFIED /F ;AN000; 2987 2988 ; $if e ; ;AN000; 0 00000DAA 750D JNE D_$IF84 2990 2991 INITspace equ InitSpace ; NASM port label 0 00000DAC 263906[3206] CMP [es:INITspace],AX ; is default < requested ? ;AN000; 2993 2994 ; $if b ; if default is < ;AN000; 0 00000DB1 7304 JNB D_$IF85 0 00000DB3 26A3[3206] MOV [es:INITspace],AX ; save the new value ;AN000; 2997 ; $endif ; endif (else leave it alone) ;AN000; 2998 D_$IF85: 2999 3000 ; $else ; else - CHECK FOR LOCKS ;AN000; 0 00000DB7 EB25 JMP SHORT D_$EN84 3002 D_$IF84: 3003 3004 ;--------------------------------------- 3005 ; If user said /L:m, then update INITlocks 3006 ;--------------------------------------- 0 00000DB9 81FB[8906] CMP BX,OFFSET L_SW ; IF USER SPECIFIED /L ;AN000; 3008 3009 ; $if e ; if it is ;AN000; 0 00000DBD 750D JNE D_$IF88 3011 3012 INITlocks equ InitLocks ; NASM port label 0 00000DBF 263906[3406] CMP [es:INITlocks],AX ; is default < requested ? ;AN000; 3014 3015 ; $if b ; if default is < ;AN000; 0 00000DC4 7304 JNB D_$IF89 0 00000DC6 26A3[3406] MOV [es:INITlocks],AX ; save the value ;AN000; 3018 ; $endif ; endif (else leave it alone) ;AN000; 3019 D_$IF89: 3020 3021 ; $else ; else - CHECK FOR TOGGLE ;AN010; 0 00000DCA EB12 JMP SHORT D_$EN88 3023 D_$IF88: 3024 3025 ;--------------------------------------- 3026 ; If user said /NC, then update check_flag 3027 ;--------------------------------------- 0 00000DCC 81FB[8C06] CMP BX,OFFSET N_SW ; IF USER SPECIFIED /NC ;AN010; 3029 ; $if ne ; if error ;AC010; 0 00000DD0 7406 JE D_$IF92 0 00000DD2 B80900 MOV AX,Syntax_Error ; Parse syntax error ;AN000; 0 00000DD5 E80900 call PARSE_ERROR ; call error routine ;AN000; 3033 ; $endif ; endif - error ;AC010; 3034 D_$IF92: 3035 0 00000DD8 26C606[4B05]01 mov byte [es:skip_check],1 ; set the skip check flag ;AN010; 3037 3038 ; $endif ; endif - CHECK FOR TOGGLE ;AN010; 3039 D_$EN88: 3040 3041 ; $endif ; endif - CHECK FOR LOCKS ;AN000; 3042 D_$EN84: 3043 3044 ; $enddo ; CHECK FOR NEXT PARM ;AN000; 0 00000DDE EB96 JMP SHORT D_$DO80 3046 D_$EN80: 3047 0 00000DE0 C3 ret ; NORMAL RETURN TO CALLER ;AN000; 3049 3050 ;--------------------------------------- 3051 ; If any other parameter specified, 3052 ; display message and quit 3053 ;--------------------------------------- 3054 PARSE_ERROR: ; ;AN000; 3055 0 00000DE1 3C09 cmp al,Syntax_Error ; error 1 to 9 ? ;AN000; 3057 3058 ; $if a ; if parse error ;AN000; 0 00000DE3 7602 JNA D_$IF97 3060 0 00000DE5 B009 mov al,Syntax_Error ; Parse syntax error 3062 3063 ; $endif ; endif errors ;AN000; 3064 D_$IF97: 3065 0 00000DE7 8D1E[6B09] lea bx,[Parse_Ret_Code] 0 00000DEB 2ED7 cs xlatb 0 00000DED B402 mov ah,PARSE_ERR_CLASS ; set class to parse error ;AN000; 3069 0 00000DEF E80CFF CALL ShDispMsg ; display the parse error ;AN000; 3071 0 00000DF2 C3 ret ; this should never be used 3073 3074 Parse_Ret_Code label byte 3075 0 00000DF3 00 db 0 ; Ret Code 0 - 0 00000DF4 09 db 9 ; Ret Code 1 - Too many parameters 0 00000DF5 09 db 9 ; Ret Code 2 - Required parameter missing 0 00000DF6 03 db 3 ; Ret Code 3 - Invalid switch 0 00000DF7 09 db 9 ; Ret Code 4 - Invalid keyword 0 00000DF8 09 db 9 ; Ret Code 5 - (reserved) 0 00000DF9 06 db 6 ; Ret Code 6 - Parm val out of range 0 00000DFA 09 db 9 ; Ret Code 7 - Parameter val not allowed 0 00000DFB 09 db 9 ; Ret Code 8 - Parameter val not allowed 0 00000DFC 09 db 9 ; Ret Code 9 - Parm format not correct 3086 3087 EndProc ShComndParse ; ;AN000; 3088 3089 %include "msgdcl.mac" 1 <1> ; This Macro was removed from sysmsg.inc. We had to remove this 2 <1> ; macro and put it into it's own include file in order to clear up 3 <1> ; some assembly errors. MS MASM will not allow a public declaration 4 <1> ; during the second pass of the assembler. IBM MASM will allow this. 5 <1> ; 6 <1> ; 7 <1> ; 8 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 9 <1> ;; $M_DECLARE Macro 10 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 11 <1> 12 <1> ; NASM original macros 13 <1> 14 <1> %imacro $M_DECLARE 1 15 <1> %iassign $M_DCOUNT 0 16 <1> %rep %1 17 <1> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <1> $M_DECLARE2 $M_DCOUNT 19 <1> %endrep 20 <1> 21 <1> %IF COMR 22 <1> EXTRN $M_RT2:BYTE 23 <1> %ELSE 24 <1> EXTRN $M_RT:BYTE 25 <1> %ENDIF 26 <1> 27 <1> $M_CHECK $M_MSGSERV_1 ; If this subroutine is not in this assembly, 28 <1> $M_CHECK $M_MSGSERV_2 ; If this subroutine is not in this assembly, 29 <1> %endmacro 30 <1> 31 <1> %imacro $M_DECLARE2 1 32 <1> %IFN COMR ; IF Not resident COMMAND.COM 33 <1> %IFN COMT ; IF Not transient COMMAND.COM 34 <1> %IF FARmsg 35 <1> EXTRN $M_CLS_%1:FAR 36 <1> %ELSE 37 <1> EXTRN $M_CLS_%1:NEAR 38 <1> %ENDIF 39 <1> %ELSE ; ELSE 40 <1> %ifnidni $M_CLS_%1, $M_CLS_1 ; IF NOT $M_CLS_1 or 41 <1> %ifnidni $M_CLS_%1, $M_CLS_2 ; IF NOT $M_CLS_2 then 42 <1> %IF FARmsg ; 43 <1> EXTRN $M_CLS_%1:FAR 44 <1> %ELSE ; 45 <1> EXTRN $M_CLS_%1:NEAR 46 <1> %ENDIF ; 47 <1> %ENDIF ; 48 <1> %ENDIF ; 49 <1> %ENDIF ; 50 <1> %ELSE ; ELSE 51 <1> %ifnidni $M_CLS_%1, $M_CLS_1 ; IF NOT $M_CLS_1 or 52 <1> %ifnidni $M_CLS_%1, $M_CLS_2 ; IF NOT $M_CLS_2 then 53 <1> %IF FARmsg ; 54 <1> EXTRN $M_CLS_%1:FAR 55 <1> %ELSE ; 56 <1> EXTRN $M_CLS_%1:NEAR 57 <1> %ENDIF ; 58 <1> %ENDIF ; 59 <1> %ENDIF ; 60 <1> %ENDIF ; 61 <1> %ENDMacro ; 62 <1> ; 63 <1> %imacro $M_CHECK 1 64 <1> %IF FARmsg ; 65 <1> EXTRN %1:FAR ; Must be external 66 <1> %ELSE ; 67 <1> EXTRN %1:NEAR ; Must be external 68 <1> %ENDIF ; 69 <1> %ENDMacro ; 70 <1> 71 <1> $M_DECLARE $M_NUM_CLS ; Declare any class not in this assembly 15 <2> %iassign $M_DCOUNT 0 16 <2> %rep %1 17 <2> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <2> $M_DECLARE2 $M_DCOUNT 19 <2> %endrep 17 <3> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <3> $M_DECLARE2 $M_DCOUNT 32 <4> %IFN COMR 33 <4> %IFN COMT 34 <4> %IF FARmsg 35 <4> EXTRN $M_CLS_%1:FAR 36 <4> %ELSE 37 <4> EXTRN $M_CLS_%1:NEAR 38 <4> %ENDIF 39 <4> %ELSE 40 <4> %ifnidni $M_CLS_%1, $M_CLS_1 41 <4> %ifnidni $M_CLS_%1, $M_CLS_2 42 <4> %IF FARmsg 43 <4> EXTRN $M_CLS_%1:FAR 44 <4> %ELSE 45 <4> EXTRN $M_CLS_%1:NEAR 46 <4> %ENDIF 47 <4> %ENDIF 48 <4> %ENDIF 49 <4> %ENDIF 50 <4> %ELSE 51 <4> %ifnidni $M_CLS_%1, $M_CLS_1 52 <4> %ifnidni $M_CLS_%1, $M_CLS_2 53 <4> %IF FARmsg 54 <4> EXTRN $M_CLS_%1:FAR 55 <4> %ELSE 56 <4> EXTRN $M_CLS_%1:NEAR 57 <4> %ENDIF 58 <4> %ENDIF 59 <4> %ENDIF 60 <4> %ENDIF 20 <2> 21 <2> %IF COMR 22 <2> EXTRN $M_RT2:BYTE 23 <2> %ELSE 24 <2> EXTRN $M_RT:BYTE 25 <2> %ENDIF 26 <2> 27 <2> $M_CHECK $M_MSGSERV_1 64 <3> %IF FARmsg 65 <3> EXTRN %1:FAR 66 <3> %ELSE 67 <3> EXTRN %1:NEAR 68 <3> %ENDIF 28 <2> $M_CHECK $M_MSGSERV_2 64 <3> %IF FARmsg 65 <3> EXTRN %1:FAR 66 <3> %ELSE 67 <3> EXTRN %1:NEAR 68 <3> %ENDIF 3090 3091 ; (no prior section) ; SHARE ENDS 3092 === Switch to base=0032E0h -> "STACK" 3093 section STACK stack class=STACK 3094 00000000 DB 278 + 128 DUP (?) ; 278 == IBM's ROM requirements 3095 ; (no prior section) ; STACK ENDS 3096 3097 %ENDIF 3098 3099 END shareinit 3100 3101 3102 === Trace listing source: sharesr.lst 1 ; Title Sharesr - IBM CONFIDENTIAL 2 ; $SALUT (0,36,41,44) 3 %include "sharehdr.mac" 1 <1> ; page 80,132 2 <1> ;******************* START OF SPECIFICATIONS *********************************** 3 <1> ; 4 <1> ; MODULE NAME: SHARE.EXE (a true EXE file) 5 <1> ; 6 <1> ; DESCRIPTIVE NAME: SHARE resident service routines - part 1 - GSHARE.SAL 7 <1> ; - part 2 - GSHARE2.SAL 8 <1> ; - part 3 - SHARESR.SAL 9 <1> ; 10 <1> ; FUNCTION: Provide file sharing services for DOS 11 <1> ; 12 <1> ; ENTRY POINT: DOS Jump Table - installed by SHARE at initalization 13 <1> ; 14 <1> ; MFT_Enter 1 15 <1> ; MFTClose 2 16 <1> ; MFTClu 3 17 <1> ; MFTCloseP 4 18 <1> ; MFTCloN 5 19 <1> ; Set_Mult_Block 6 20 <1> ; Clr_Mult_Block 7 21 <1> ; Chk_Block 8 22 <1> ; MFT_Get 9 23 <1> ; 24 <1> ; INPUT: See Prolog to individual entry points 25 <1> ; 26 <1> ; EXIT NORMAL: CF = 0 and requested task performed. 27 <1> ; 28 <1> ; EXIT ERROR: CF = 1 ans error code in AX 29 <1> ; 30 <1> ; INTERNAL REFERENCES: 31 <1> ; 32 <1> ; ROUTINES: Set_Block BCS 33 <1> ; Clr_Block CSL 34 <1> ; CLP CUC 35 <1> ; Load_Regs CSI 36 <1> ; ASC GOM 37 <1> ; 38 <1> ; DATA AREAS: 39 <1> ; 40 <1> ; EXTERNAL REFERENCES: INT 21 INT 2F 41 <1> ; together with: 42 <1> ; 43 <1> ; fnm:near, rsc:near, rmn:near, cps:near, ofl:near, sle:near, interr:near 44 <1> ; 45 <1> ; ROUTINES: 46 <1> ; 47 <1> ; DATA AREAS: 48 <1> ; 49 <1> ; NOTES: The second part of this utility is GSHARE2.ASM 50 <1> ; 51 <1> ; REVISION HISTORY: Version 1.0 09/09/83 - first release GL 52 <1> ; 09/13/83 - Installability MZ 53 <1> ; 01/11/84 - FCB compatability changes MZ 54 <1> ; PTM P000438 08/21/86 - SFT LCK FIELDS not 0 error DL 55 <1> ; Ax000 Ver 4.0 04/15/87 - changed:- Set_Block FJG 56 <1> ; - Clr_Block FJG 57 <1> ; - Chk_Block FJG 58 <1> ; - CLP FJG 59 <1> ; new: - Set_Mult_Block FJG 60 <1> ; - Clr_Mult_Block FJG 61 <1> ; - Load_Regs FJG 62 <1> ; - Clr_List FJG 63 <1> ; Ax002 PTM P001658 10/15/87 - changed I/F to IBMDOS FJG 64 <1> ; Ax003 PTM P002064 10/15/87 - ShSU SFT - IFS call error FJG 65 <1> ; Ax004 PTM P002121 10/29/87 - Clr_Mult_Block cx=-1 err FJG 66 <1> ; Ax005 PTM P002322 11/06/87 - Call_IFS - 2F semaphore FJG 67 <1> ; Ax006 DCR D000494 12/17/87 - DOS 4.00 function reductionFJG 68 <1> ; Ax007 PTM P003841 03/17/88 - access error for Turbo L FJG 69 <1> ; Ax008 PTM P003880 03/17/88 - duped handle error FJG 70 <1> ; Ax009 PTM P003910 03/17/88 - wrong parse error format FJG 71 <1> ; Ax010 DCR D000526 04/27/88 - add /nc switch support FJG 72 <1> ; Ax011 PTM P004546 05/03/88 - add /nc support to fShare FJG 4 ; 5 ; Label: "The DOS SHARE Utility" 6 ; "Version 4.00 (C) Copyright 1988 Microsoft" 7 ; "Licenced Material - Program Property of Microsoft" 8 ; 9 ;******************* END OF SPECIFICATIONS ************************************* 10 === Switch to base=000000h -> "SHARE" 11 section SHARE align=1 PUBLIC class=SHARE 12 ; NAME Sharsr 13 14 [list -] 14 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 21 22 MSG_UTILNAME 303 <1> stripangles %defstr %%string, %1 304 <1> %strlen %%length %%string 305 <1> %assign %%ii 1 306 <1> %define %%name "" 307 <1> %rep %%length 308 <1> %substr %%cc %%string %%ii 309 <1> %assign %%ii %%ii + 1 310 <1> %if %%cc >= 'A' && %%cc <= 'Z' 311 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <1> %endif 313 <1> %strcat %%name %%name,%%cc 314 <1> %endrep 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 308 <2> %substr %%cc %%string %%ii 309 <2> %assign %%ii %%ii + 1 310 <2> %if %%cc >= 'A' && %%cc <= 'Z' 311 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 312 <2> %endif 313 <2> %strcat %%name %%name,%%cc 315 <1> %strcat %%name %%name,".ctl" 316 <1> %unimacro equ 1+.nolist 317 <1> %imacro equ 1+.nolist 318 <1> %defstr %%string %00 319 <1> %substr %%cc %%string 1 320 <1> %ifidni %%cc, "$" 321 <1> %iassign %00 %1 322 <1> %else 323 <1> %00 equ %1 324 <1> %endif 325 <1> %endmacro 326 <1> %include %%name 1 <2> $M_NUM_CLS EQU 1 327 <1> %unimacro equ 1+.nolist 328 <1> %iassign $M_STRUC TRUE 329 <1> 330 <1> %include "msgserv.nas" 1 <2> ;=== Push trace listing source: msgserv.nas 2 <2> 3 <2> ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * 4 <2> ; 5 <2> ; MODULE NAME: MSGSERV.SAL 6 <2> ; 7 <2> ; DESCRIPTIVE NAME: Message Services SALUT file 8 <2> ; 9 <2> ; FUNCTION: This module incorporates all the messages services and 10 <2> ; is called upon at build time to INCLUDE the code requested 11 <2> ; by a utility. Code is requested using the macro MSG_SERVICES. 12 <2> ; 13 <2> ; ENTRY POINT: Since this a collection of subroutines, entry point is at 14 <2> ; requested procedure. 15 <2> ; 16 <2> ; INPUT: Since this a collection of subroutines, input is dependent on function 17 <2> ; requested. 18 <2> ; 19 <2> ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 20 <2> ; 21 <2> ; EXIT-ERROR: In all cases, CARRY FLAG = 1 22 <2> ; 23 <2> ; INTERNAL REFERENCES: (list of included subroutines) 24 <2> ; 25 <2> ; - SYSLOADMSG 26 <2> ; - SYSDISPMSG 27 <2> ; - SYSGETMSG 28 <2> ; 29 <2> ; 30 <2> ; EXTERNAL REFERENCES: None 31 <2> ; 32 <2> ; NOTES: At build time, some modules must be included. These are only included 33 <2> ; once using assembler switches. Other logic is included at the request 34 <2> ; of the utility. 35 <2> ; 36 <2> ; COMR and COMT are assembler switches to conditionally assemble code 37 <2> ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident 38 <2> ; storage and multiple EQUates. 39 <2> ; 40 <2> ; REVISION HISTORY: Created MAY 1987 41 <2> ; 42 <2> ; Label: DOS - - Message Retriever 43 <2> ; (c) Copyright 1988 Microsoft 44 <2> ; 45 <2> ; 46 <2> ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * 47 <2> ; Page 48 <2> 49 <2> ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting 50 <2> 51 <2> %IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN 52 <2> %iassign $M_STRUC FALSE ;;AN000;; Let the assembler know that we have 53 <2> ;;AN000;; and include them 54 <2> 55 <2> ; PAGE 56 <2> ; SUBTTL DOS - Message Retriever - MSGSTR.INC Module 57 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 <2> ;; 59 <2> ;; STRUCTURE: $M_SUBLIST_STRUC 60 <2> ;; 61 <2> ;; Replacable parameters are described by a sublist structure 62 <2> ;; 63 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 <2> ;; 65 <2> $M_SUBLIST_STRUC STRUC ;;AN000;; 66 <2> ;; 0 00000DFD ?? $M_S_SIZE DB ? ;11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) 0 00000DFE ?? $M_S_RESV DB ? ;0 ;;AN000;; RESERVED 0 00000DFF ???????? $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item 0 00000E03 ?? $M_S_ID DB ? ;;AN000;; n of %n 0 00000E04 ?? $M_S_FLAG DB ? ;;AN000;; Data-type flags 0 00000E05 ?? $M_S_MAXW DB ? ;;AN000;; Maximum field width 0 00000E06 ?? $M_S_MINW DB ? ;;AN000;; Minimum field width 0 00000E07 ?? $M_S_PAD DB ? ;;AN000;; Character for Pad field 75 <2> ;; 76 <2> $M_SUBLIST_STRUC ENDS ;;AN000;; 76 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 77 <2> ;; 78 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 <2> ;; 80 <2> ;; STRUCTURE: $M_CLASS_ID 81 <2> ;; 82 <2> ;; Each class will be defined by this structure. 83 <2> ;; 84 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 <2> ;; 86 <2> EXPECTED_VERSION equ expected_version ; NASM port equate 87 <2> 88 <2> $M_CLASS_ID STRUC ;;AN000;; 89 <2> ;; 0 00000DFD ?? $M_CLS_ID DB ? ;-1 ;;AN000;; Class identifer 0 00000DFE ???? $M_COMMAND_VER DW ? ;EXPECTED_VERSION ;;AN003;; COMMAND.COM version check 0 00000E00 ?? $M_NUM_CLS_MSG DB ? ;0 ;;AN000;; Total number of message in class 93 <2> ;; 94 <2> $M_CLASS_ID ENDS ;; 94 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 95 <2> ;;AN000;; 96 <2> $M_CLASS_ID_SZ EQU $M_CLASS_ID_struc_size ;;AN000;; 97 <2> ;; 98 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 <2> ;; 100 <2> ;; STRUCTURE: $M_ID_STRUC 101 <2> ;; 102 <2> ;; Each message will be defined by this structure. 103 <2> ;; 104 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 105 <2> ;; 106 <2> $M_ID STRUC ;;AN000;; 107 <2> ;; 0 00000DFD ???? $M_NUM DW ? ;-1 ;;AN000;; Message Number 0 00000DFF ???? $M_TXT_PTR DW ? ;;AN000;; Pointer to message text 110 <2> ;; 111 <2> $M_ID ENDS ;;AN000;; 111 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 112 <2> ;;AN000;; Status Flag Values: 113 <2> $M_ID_SZ EQU $M_ID_struc_size ;;AN000;; 114 <2> ;; 115 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 <2> ;; 117 <2> ;; STRUCTURE: $M_RES_ADDRS 118 <2> ;; 119 <2> ;; Resident data area definition of variables 120 <2> ;; 121 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122 <2> ;; 123 <2> $M_RES_ADDRS STRUC ;;AN000;; 124 <2> ;; 0 00000DFD ???????? $M_EXT_ERR_ADDRS DD ? ;0 ;;AN000;; Allow pointers to THREE Extended error locations 0 00000E01 ???????? $M_EXT_FILE DD ? ;0 ;;AN001;; 0 00000E05 ???????? $M_EXT_COMMAND DD ? ;0 ;;AN000;; 0 00000E09 ???????? $M_EXT_TERM DD ? ;-1 ;;AN000;; 0 00000E0D ???????? $M_PARSE_COMMAND DD ? ;0 ;;AN000;; 0 00000E11 ???????? $M_PARSE_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Parse error locations 0 00000E15 ???????? $M_PARSE_TERM DD ? ;-1 ;;AN000;; 0 00000E19 ???????? $M_CRIT_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Critical error locations 0 00000E1D ???????? $M_CRIT_COMMAND DD ? ;0 ;;AN000;; 0 00000E21 ???????? $M_CRIT_TERM DD ? ;-1 ;;AN000;; 0 00000E25 ???????? $M_DISK_PROC_ADDR DD ? ;-1 ;;AN004;; Address of READ_DISK_PROC 0 00000E29 ???????? $M_CLASS_ADDRS DD $M_NUM_CLS DUP (?) ;(0) ;;AN000;; Allow pointers to specified classes 0 00000E2D ???????? $M_CLS_TERM DD ? ;-1 ;;AN000;; 0 00000E31 ???????? $M_DBCS_VEC DD ? ;0 ;;AN000;; Save DBCS vector 0 00000E35 ???? $M_HANDLE DW ? ;;AN000;; 0 00000E37 ?? $M_SIZE DB ? ;0 ;;AN000;; 0 00000E38 ???? $M_CRLF DB ?,? ;0DH,0AH ;;AN004;; CR LF message 0 00000E3A ?? $M_CLASS DB ? ;;AN004;; Saved class 0 00000E3B ???? $M_RETURN_ADDR DW ? ;;AN000;; 0 00000E3D ???? $M_MSG_NUM DW ? ;$M_NULL ;;AN000;; 0 00000E3F ???? $M_DIVISOR DW ? ;10 ;;AN000;; Default = 10 (must be a WORD for division) 146 00000044 <2> $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP (?) ;("$") ;;AN000;; Temporary buffer 0 00000E81 ?? $M_BUF_TERM DB ? ;"$" ;;AN000;; 148 <2> 149 <2> $M_RES_ADDRS ENDS ;;AN000;; 149 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 150 <2> ;; 151 <2> $M_RES_ADDRS_SZ EQU $M_RES_ADDRS_struc_size ;;AN000;; 152 <2> ;; 153 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 <2> ;; 155 <2> ;; STRUCTURE: $M_COUNTRY_INFO 156 <2> ;; 157 <2> ;; Important fields of the Get Country Information call 158 <2> ;; 159 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 <2> ;; 161 <2> $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation 162 <2> ;; 163 00000000 <2> $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc 0 00000E41 ???? $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format 0 00000E43 ?????????? $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; 0 00000E48 ???? $M_THOU_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Thou Separator 0 00000E4A ???? $M_DECI_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Decimal Separator 0 00000E4C ???? $M_DATE_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Date Separator 0 00000E4E ???? $M_TIME_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Time Separator 0 00000E50 ?? $M_CURR_FORMAT DB ? ;;AN000;; 0 00000E51 ?? $M_SIG_DIGS_CU DB ? ;;AN000;; 0 00000E52 ?? $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format 173 <2> ;; 174 <2> $M_COUNTRY_INFO ENDS ;;AN000;; 174 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 176 <2> ;; 177 <2> %ELSE ;;AN000;; ELSE if we have already included the STRUCTURES 178 <2> ; 179 <2> ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section 180 <2> 181 <2> %IF MSGDATA ;;AN000;; IF this is a request to include the data area 182 <2> %iassign MSGDATA FALSE ;;AN000;; Let the assembler know not to include it again 183 <2> ;;AN000;; and include it 184 <2> ; PAGE 185 <2> ; SUBTTL DOS - Message Retriever - MSGRES.TAB Module 186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187 <2> ;; 188 <2> ;; DATA NAME: $M_RES_TABLE 189 <2> ;; 190 <2> ;; REFERENCE LABEL: $M_RT 191 <2> ;; 192 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 193 <2> 194 <2> %if 0 ; disabled for now, figure out later 195 <2> %IF COMR ;;AN000;; Since COMMAND.COM includes this twice 196 <2> $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no 197 <2> $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur 198 <2> $M_ALTLABEL equ TRUE ;;AN000;; Flag that label was changed 199 <2> %ELSE ;;AN000;; 200 <2> $M_RT LABEL BYTE ;;AN000;; 201 <2> %ENDIF 202 <2> %endif 203 <2> $M_RT: ; NASM structure instance 204 <2> $M_RES_ADDRS_size equ $M_RES_ADDRS_struc_size ; NASM port equate 205 <2> istruc $M_RES_ADDRS 206 <2> at $M_EXT_ERR_ADDRS 207 <2> dd 0 208 <2> at $M_EXT_FILE 209 <2> dd 0 210 <2> at $M_EXT_COMMAND 211 <2> dd 0 212 <2> at $M_EXT_TERM 213 <2> dd -1 214 <2> at $M_PARSE_COMMAND 215 <2> dd 0 216 <2> at $M_PARSE_ADDRS 217 <2> dd 0 218 <2> at $M_PARSE_TERM 219 <2> dd -1 220 <2> at $M_CRIT_ADDRS 221 <2> dd 0 222 <2> at $M_CRIT_COMMAND 223 <2> dd 0 224 <2> at $M_CRIT_TERM 225 <2> dd -1 226 <2> at $M_DISK_PROC_ADDR 227 <2> dd -1 228 <2> at $M_CLASS_ADDRS 229 <2> times $M_NUM_CLS dd 0 230 <2> at $M_CLS_TERM 231 <2> dd -1 232 <2> at $M_DBCS_VEC 233 <2> dd 0 234 <2> at $M_HANDLE 235 <2> dw 0 236 <2> at $M_SIZE 237 <2> db 0 238 <2> at $M_CRLF 239 <2> db 0Dh, 0Ah 240 <2> at $M_CLASS 241 <2> db 0 242 <2> at $M_RETURN_ADDR 243 <2> dw 0 244 <2> at $M_MSG_NUM 245 <2> dw 0 246 <2> at $M_DIVISOR 247 <2> dw 10 248 <2> at $M_TEMP_BUF 249 <2> times $M_TEMP_BUF_SZ db "$" 250 <2> at $M_BUF_TERM 251 <2> db "$" 252 <2> iend 253 <2> ;; 254 <2> %include "copyrigh.mac" ;;AN001;; Include Copyright 1988 Microsoft 255 <2> ;; 256 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 257 <2> %ENDIF ;;AN000;; END of include of Data table 258 <2> 259 <2> ; 260 <2> %IFN $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN 261 <2> ;; don't include any more code 262 <2> ;;AN000;; Figure out what other code to include 263 <2> %IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code 264 <2> %IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) 265 <2> $M_RT EQU $M_RT2 ;;AN003;; 266 <2> %ENDIF 267 <2> %iassign DISK_PROC FALSE ;;AN003;; Yes, THEN include it and reset flag 268 <2> ; PAGE 269 <2> ; SUBTTL DOS - Message Retriever - DISK_PROC Module 270 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 271 <2> ;; 272 <2> ;; PROC NAME: DISK_PROC 273 <2> ;; 274 <2> ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended 275 <2> ;; errors from disk\diskette 276 <2> ;; INPUTS: AX has the message number 277 <2> ;; DX has the message class 278 <2> ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is 279 <2> ;; assumed to be set!! 280 <2> ;; 281 <2> ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text 282 <2> ;; 283 <2> ;; 284 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 285 <2> ;; 286 <2> PUBLIC READ_DISK_PROC ;; 287 <2> ;; 288 <2> READ_DISK_PROC PROC FAR ;;AN003;; 289 <2> 290 <2> PUSH AX ;;AN003;; Save everything 291 <2> PUSH BX ;;AN003;; 292 <2> PUSH DX ;;AN003;; 293 <2> PUSH SI ;;AN003;; 294 <2> PUSH BP ;;AN003;; 295 <2> PUSH DS ;;AN003;; 296 <2> PUSH DI ;;AN003;; 297 <2> MOV BP,AX ;;AN003;; Save message number 298 <2> MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function 299 <2> LEA SI,[COMSPEC wrt RESGROUP] ;;AN003;; Get addressibilty to COMMAND.COM 300 <2> PUSH CS ;;AN003;; 301 <2> POP DS ;;AN003;; 302 <2> MOV DI,-1 ;;AN003;; No extended attribute list 303 <2> MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error 304 <2> MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag 305 <2> INT 21H ;;AN003;; Open the file 306 <2> POP DI ;;AN003;; Retreive LSEEK pointer 307 <2> ;;AN003;; Error ? 308 <2> ; $IF NC,LONG ;;AN003;; No, 309 <2> JNC $MXL1 310 <2> JMP $MIF1 311 <2> $MXL1: 312 <2> PUSH DI ;;AN003;; Save LSEEK pointer 313 <2> MOV BX,AX ;;AN003;; Set handle in BX 314 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors 315 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 316 <2> MOV DX,DI ;;AN003;; 317 <2> INT 21H ;;AN003;; LSEEK the file 318 <2> POP DX ;;AN003;; Retreive LSEEK pointer 319 <2> ;;AN003;; Error ? 320 <2> ; $IF NC ;;AN003;; No, 321 <2> JC $MIF2 322 <2> INC CX ;;AN003;; Set flag to first pass 323 <2> ; $DO ;;AN003;; 324 <2> $MDO3: 325 <2> PUSH DX ;;AN003;; Save LSEEK pointer 326 <2> PUSH CX ;;AN003;; Save first pass flag 327 <2> PUSH AX ;;AN003;; Save number of messages (if set yet) 328 <2> XOR SI,SI ;;AN003;; Reset buffer index 329 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 330 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header 331 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 332 <2> INT 21H ;;AN003;; Read it 333 <2> MOV DI,DX ;;AN003;; 334 <2> POP AX ;;AN003;; 335 <2> POP CX ;;AN003;; 336 <2> OR CX,CX ;;AN003;; 337 <2> ; $IF NZ ;;AN003;; 338 <2> JZ $MIF4 339 <2> XOR CX,CX ;;AN003;; Set flag to second pass 340 <2> XOR AH,AH ;;AN003;; Get number of messages in class 341 <2> MOV AL,[DI + $M_NUM_CLS_MSG] ;;AN003;; 342 <2> MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index 343 <2> CMP word [DI + $M_COMMAND_VER],EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? 344 <2> ; $ENDIF ;;AN003;; 345 <2> $MIF4: 346 <2> POP DX ;;AN003;; 347 <2> ; $IF Z ;;AN003;; Yes, 348 <2> JNZ $MIF6 349 <2> ; $SEARCH ;;AN003;; 350 <2> $MDO7: 351 <2> CMP BP,WORD PTR [$M_RT + $M_TEMP_BUF + SI] ;;AN003;; Is this the message I'm looking for? 352 <2> ; $EXITIF Z ;;AN003;; Yes, (ZF=1) 353 <2> JNZ $MIF7 354 <2> CLC ;;AN003;; Reset carry, exit search 355 <2> ; $ORELSE ;;AN003;; No, (ZF=0) 356 <2> JMP SHORT $MSR7 357 <2> $MIF7: 358 <2> ADD SI,$M_ID_SZ ;;AN003;; Increment index 359 <2> ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header 360 <2> DEC AX ;;AN003;; Decrement # of messages left 361 <2> ; $LEAVE Z ;;AN003;; Have we exhausted all messages? 362 <2> JZ $MEN7 363 <2> CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? 364 <2> ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) 365 <2> JNA $MDO7 366 <2> $MEN7: 367 <2> STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) 368 <2> ; $ENDSRCH ;;AN003;; 369 <2> $MSR7: 370 <2> ; $ELSE ;;AN003;; No, 371 <2> JMP SHORT $MEN6 372 <2> $MIF6: 373 <2> XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop 374 <2> STC ;;AN003;; Set Carry 375 <2> ; $ENDIF ;;AN003;; 376 <2> $MEN6: 377 <2> ; $ENDDO Z ;;AN003;; Get next buffer full if needed 378 <2> JNZ $MDO3 379 <2> ;;AN003;; Error ? 380 <2> ; $IF NC ;;AN003;; No, 381 <2> JC $MIF16 382 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message 383 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 384 <2> ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header 385 <2> ADD DX,WORD PTR [$M_RT + $M_TEMP_BUF + SI + 2] ;;AN003;; Add offset from msg structure 386 <2> INT 21H ;;AN003;; LSEEK the file 387 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 388 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message 389 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 390 <2> INT 21H ;;AN003;; Read it 391 <2> MOV DI,DX ;;AN003;; into the temp buffer 392 <2> PUSH DS ;;AN003;; into the temp buffer 393 <2> POP ES ;;AN003;; into the temp buffer 394 <2> ; $ENDIF ;;AN003;; 395 <2> $MIF16: 396 <2> ; $ENDIF ;;AN003;; 397 <2> $MIF2: 398 <2> PUSHF ;;AN003;; Close file handle 399 <2> MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle 400 <2> INT 21H ;;AN003;; 401 <2> $M_POPF ;;AN003;; 402 <2> ; $ENDIF ;;AN003;; Yes there was an error, 403 <2> $MIF1: 404 <2> POP DS ;;AN003;; 405 <2> POP BP ;;AN003;; 406 <2> POP SI ;;AN003;; 407 <2> POP DX ;;AN003;; 408 <2> POP BX ;;AN003;; 409 <2> POP AX ;;AN003;; 410 <2> ;;AN003;; abort everything 411 <2> RET ;;AN003;; 412 <2> 413 <2> READ_DISK_PROC ENDP ;;AN003;; 414 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 415 <2> %ENDIF ;;AN003;; END of include for DISK_PROC 416 <2> ; 417 <2> 418 <2> %IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO 419 <2> %iassign SETSTDIO FALSE ;;AN000;; Yes, THEN include it and reset flag 420 <2> ; PAGE 421 <2> ; SUBTTL DOS - Message Retriever - SETSTDIO Module 422 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 423 <2> ;; 424 <2> ;; PROC NAME: SETSTDIO 425 <2> ;; 426 <2> ;; FUNCTION: 427 <2> ;; INPUTS: 428 <2> ;; 429 <2> ;; OUPUTS: 430 <2> ;; 431 <2> ;; 432 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 433 <2> ;; 434 <2> %IF FARmsg ;AN001; 435 <2> SETSTDINON PROC FAR ;AN001; 436 <2> %ELSE ;AN001; 437 <2> SETSTDINON PROC NEAR ;AN001; 438 <2> %ENDIF ;AN001; 439 <2> PUSH AX ;AN002; Save changed regs 440 <2> PUSH BX ;AN002; 441 <2> PUSH DX ;AN002; 442 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 443 <2> MOV BX,STDIN ;AN001; 444 <2> XOR DX,DX ;AN001; 445 <2> INT 21H ;AN001; 446 <2> 447 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 448 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 449 <2> INT 21H ;AN001; 450 <2> POP DX ;AN002; Restore Regs 451 <2> POP BX ;AN002; 452 <2> POP AX ;AN002; 453 <2> 454 <2> RET ;AN001; 455 <2> ;AN001; 456 <2> SETSTDINON ENDP ;AN001; 457 <2> 458 <2> %IF FARmsg ;AN001; 459 <2> SETSTDINOFF PROC FAR ;AN001; 460 <2> %ELSE ;AN001; 461 <2> SETSTDINOFF PROC NEAR ;AN001; 462 <2> %ENDIF ;AN001; 463 <2> 464 <2> PUSH AX ;AN002; Save changed regs 465 <2> PUSH BX ;AN002; 466 <2> PUSH DX ;AN002; 467 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 468 <2> MOV BX,STDIN ;AN001; 469 <2> XOR DX,DX ;AN001; 470 <2> INT 21H ;AN001; 471 <2> 472 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 473 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 474 <2> INT 21H ;AN001; 475 <2> POP DX ;AN002; Restore Regs 476 <2> POP BX ;AN002; 477 <2> POP AX ;AN002; 478 <2> 479 <2> RET ;AN001; 480 <2> 481 <2> SETSTDINOFF ENDP ;AN001; 482 <2> 483 <2> %IF FARmsg ;AN001; 484 <2> SETSTDOUTON PROC FAR ;AN001; 485 <2> %ELSE ;AN001; 486 <2> SETSTDOUTON PROC NEAR ;AN001; 487 <2> %ENDIF ;AN001; 488 <2> 489 <2> PUSH AX ;AN002; Save changed regs 490 <2> PUSH BX ;AN002; 491 <2> PUSH DX ;AN002; 492 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 493 <2> MOV BX,STDOUT ;AN001; 494 <2> XOR DX,DX ;AN001; 495 <2> INT 21H ;AN001; 496 <2> 497 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 498 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 499 <2> INT 21H ;AN001; 500 <2> POP DX ;AN002; Restore Regs 501 <2> POP BX ;AN002; 502 <2> POP AX ;AN002; 503 <2> 504 <2> RET ;AN001; 505 <2> 506 <2> SETSTDOUTON ENDP ;AN001; 507 <2> 508 <2> %IF FARmsg ;AN001; 509 <2> SETSTDOUTOFF PROC FAR ;AN001; 510 <2> %ELSE ;AN001; 511 <2> SETSTDOUTOFF PROC NEAR 512 <2> %ENDIF ;AN001; 513 <2> 514 <2> PUSH AX ;AN002; Save changed regs 515 <2> PUSH BX ;AN002; 516 <2> PUSH DX ;AN002; 517 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 518 <2> MOV BX,STDOUT ;AN001; 519 <2> XOR DX,DX ;AN001; 520 <2> INT 21H ;AN001; 521 <2> 522 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 523 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 524 <2> INT 21H ;AN001; 525 <2> POP DX ;AN002; Restore Regs 526 <2> POP BX ;AN002; 527 <2> POP AX ;AN002; 528 <2> 529 <2> RET ;AN001; 530 <2> 531 <2> SETSTDOUTOFF ENDP ;AN001; 532 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 533 <2> %ENDIF ;;AN000;; END of include for SETSTDIO 534 <2> ; 535 <2> %IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? 536 <2> %IF COMR ;;AN000;; 537 <2> $M_RT EQU $M_RT2 ;;AN000;; 538 <2> %ENDIF 539 <2> %iassign LOADmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 540 <2> ; PAGE 541 <2> ; SUBTTL DOS - Message Retriever - LOADMSG.ASM Module 542 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 543 <2> ;; 544 <2> ;; PROC NAME: SYSLOADMSG 545 <2> ;; 546 <2> ;; FUNCTION: 547 <2> ;; INPUTS: 548 <2> ;; 549 <2> ;; OUPUTS: 550 <2> ;; 551 <2> ;; 552 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 553 <2> ;; 554 <2> %IF FARmsg ;;AN000;; 555 <2> SYSLOADMSG PROC FAR ;;AN000;; 556 <2> %ELSE ;;AN000;; 557 <2> SYSLOADMSG PROC NEAR ;;AN000;; 558 <2> %ENDIF ;;AN000;; 559 <2> PUSH AX ;;AN000; 560 <2> PUSH BX ;;AN000; 561 <2> PUSH DX ;;AN000; 562 <2> PUSH ES ;;AN000; 563 <2> PUSH DI ;;AN000; 564 <2> XOR CX,CX ;;AN000; Reset to zero 565 <2> MOV ES,CX ;;AN000; 566 <2> XOR DI,DI ;;AN000; 567 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 568 <2> MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM 569 <2> INT 2FH ;;AN000;; Private interface 570 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 571 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND],DI ;;AN000;; 572 <2> ;; 573 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 574 <2> MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM 575 <2> INT 2FH ;;AN000;; Private interface 576 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 577 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND],DI ;;AN000;; 578 <2> ;; 579 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 580 <2> MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM 581 <2> INT 2FH ;;AN000;; Private interface 582 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 583 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND],DI ;;AN000;; 584 <2> 585 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 586 <2> MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE 587 <2> INT 2FH ;;AN001;; Private interface 588 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE+2],ES ;;AN001;; Move into first avaliable table location 589 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE],DI ;;AN001;; 590 <2> 591 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 592 <2> Extrn READ_DISK_PROC:Far ;;AN003;; 593 <2> %ELSE ;; 594 <2> %IF FARmsg ;;AN000;; 595 <2> CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 596 <2> %ELSE ;;AN000;; 597 <2> CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 598 <2> %ENDIF ;;AN000;; 599 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 600 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS],DI ;;AN000;; 601 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 602 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS],DI ;;AN000;; 603 <2> ;; 604 <2> %IF FARmsg ;;AN000;; 605 <2> CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 606 <2> %ELSE ;;AN000;; 607 <2> CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 608 <2> %ENDIF ;;AN000;; 609 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 610 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS],DI ;;AN000;; 611 <2> %ENDIF ;; 612 <2> ;; 613 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 614 <2> MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM 615 <2> INT 2FH ;;AN001;; Private interface 616 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR+2],ES ;;AN001;; Move into first avaliable table location 617 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR],DI ;;AN001;; 618 <2> 619 <2> $M_BUILD_PTRS $M_NUM_CLS ;;AN000;; Build all utility classes 620 <2> ;;AN000;; 621 <2> CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector 622 <2> 623 <2> %IFN NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed 624 <2> CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK 625 <2> %ENDIF ;;AN000;; 626 <2> ;;AN000;; 627 <2> %IFN NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed 628 <2> CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK 629 <2> %ENDIF ;;AN000;; 630 <2> ;;AN000;; 631 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 632 <2> CLC ;;AN000;; Make sure carry is clear 633 <2> %ELSE ;;AN000;; ELSE 634 <2> PUSH CX ;;AN000;; 635 <2> CALL $M_VERSION_CHECK ;;AN000;; Check Version 636 <2> %ENDIF ;;AN000;; 637 <2> ;; Error ? 638 <2> ; $IF NC ;;AN000;; No. 639 <2> JC $MIF20 640 <2> %IFN NOVERCHECKmsg ;;AN000;; IF version check was not supressed 641 <2> POP CX ;;AN000;; Reset stack 642 <2> %ENDIF ;;AN000;; 643 <2> POP DI ;;AN000;; Restore REGS 644 <2> POP ES ;;AN000;; 645 <2> POP DX ;;AN000;; 646 <2> POP BX ;;AN000;; 647 <2> POP AX ;;AN000;; 648 <2> ; $ELSE ;;AN000;; Yes, 649 <2> JMP SHORT $MEN20 650 <2> $MIF20: 651 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 652 <2> ADD SP,10 ;;AN000;; 653 <2> STC ;;AN000;; Reset carry flag 654 <2> %ELSE ;;AN000;; IF version check is to be supressed 655 <2> ADD SP,12 ;;AN000;; 656 <2> STC ;;AN000;; Reset carry flag 657 <2> %ENDIF ;;AN000;; IF version check is to be supressed 658 <2> ; $ENDIF ;;AN000;; 659 <2> $MEN20: 660 <2> RET ;;AN000;; 661 <2> ;; 662 <2> SYSLOADMSG ENDP ;;AN000;; 663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 664 <2> ; PAGE 665 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 666 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 667 <2> ;; 668 <2> ;; Proc Name: $M_GET_DBCS_VEC 669 <2> ;; 670 <2> ;; Function: Get the DBCS vector and save it for later use 671 <2> ;; 672 <2> ;; Inputs: None 673 <2> ;; 674 <2> ;; Outputs: None 675 <2> ;; 676 <2> ;; Regs Changed: 677 <2> ;; 678 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 679 <2> ;; 680 <2> $M_GET_DBCS_VEC PROC NEAR ;;AN000;; 681 <2> ;; 682 <2> PUSH AX ;;AN000;; Save character to check 683 <2> PUSH SI ;;AN000;; 684 <2> PUSH DS ;;AN000;; 685 <2> MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment 686 <2> INT 21H ;;AN000;; Get environment pointer 687 <2> PUSH DS ;;AN000;; Get environment pointer 688 <2> POP ES ;;AN000;; Get environment pointer 689 <2> POP DS ;;AN000;; Get environment pointer 690 <2> ; $IF NC ;;AN000;; 691 <2> JC $MIF23 692 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC],SI ;;AN000;; Save DBCS Vector 693 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC+2],ES ;;AN000;; 694 <2> ; $ENDIF ;;AN000;; 695 <2> $MIF23: 696 <2> POP SI ;;AN000;; 697 <2> POP AX ;;AN000;; Retrieve character to check 698 <2> RET ;;AN000;; Return 699 <2> ;; 700 <2> $M_GET_DBCS_VEC ENDP ;; 701 <2> ;; 702 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 703 <2> %IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? 704 <2> %ELSE ;AN001; Yes, THEN include it 705 <2> ; PAGE 706 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc 707 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 708 <2> ;; 709 <2> ;; Proc Name: $M_CHECKSTDIN 710 <2> ;; 711 <2> ;; Function: 712 <2> ;; 713 <2> ;; Inputs: None 714 <2> ;; 715 <2> ;; Outputs: 716 <2> ;; 717 <2> ;; Regs Changed: 718 <2> ;; 719 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 720 <2> ;; 721 <2> $M_CHECKSTDIN PROC NEAR ;AN001; 722 <2> 723 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 724 <2> MOV BX,STDIN ;AN001; 725 <2> XOR DX,DX ;AN001; 726 <2> INT 21H ;AN001; 727 <2> 728 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 729 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 730 <2> INT 21H ;AN001; 731 <2> 732 <2> RET ;AN001; 733 <2> 734 <2> $M_CHECKSTDIN ENDP ;AN001; 735 <2> ;; 736 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 737 <2> %ENDIF ;AN001; END of include for EOF Check 738 <2> %IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? 739 <2> %ELSE ;AN001; Yes, THEN include it 740 <2> ; PAGE 741 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc 742 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 743 <2> ;; 744 <2> ;; Proc Name: $M_CHECKSTDOUT 745 <2> ;; 746 <2> ;; Function: 747 <2> ;; 748 <2> ;; Inputs: None 749 <2> ;; 750 <2> ;; Outputs: 751 <2> ;; 752 <2> ;; Regs Changed: 753 <2> ;; 754 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 755 <2> ;; 756 <2> $M_CHECKSTDOUT PROC NEAR ;AN001; 757 <2> 758 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 759 <2> MOV BX,STDOUT ;AN001; 760 <2> XOR DX,DX ;AN001; 761 <2> INT 21H ;AN001; 762 <2> 763 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 764 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 765 <2> INT 21H ;AN001; 766 <2> 767 <2> RET ;AN001; 768 <2> 769 <2> $M_CHECKSTDOUT ENDP ;AN001; 770 <2> ;; 771 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 772 <2> %ENDIF ;AN001; END of include for Disk Full Check 773 <2> %IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? 774 <2> %ELSE ;;AN000;; Yes, THEN include it 775 <2> ; PAGE 776 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 778 <2> ;; 779 <2> ;; Proc Name: $M_VERSION_CHECK 780 <2> ;; 781 <2> ;; Function: Determine if DOS version is within allowable limits 782 <2> ;; 783 <2> ;; Inputs: None 784 <2> ;; 785 <2> ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version 786 <2> ;; Registers set for SYSDISPMSG 787 <2> ;; CARRY_FLAG = 0 if Correct DOS version 788 <2> ;; 789 <2> ;; Regs Changed: AX 790 <2> ;; 791 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 792 <2> 793 <2> check_amis: 794 <2> push ax 795 <2> push ds 796 <2> push si 797 <2> push es 798 <2> push di 799 <2> push dx 800 <2> push ax ; version number, last on stack 801 <2> 802 <2> mov ah, 0 ; multiplex number = 0 803 <2> .loop: 804 <2> mov al, 0 805 <2> int 2Dh ; installation check 806 <2> cmp al, -1 ; multiplexer installed ? 807 <2> jne .next ; no --> 808 <2> push cs 809 <2> pop ds 810 <2> mov si, offset amis_sign ; ds:si -> amis_sign (for lDOS) 811 <2> mov es, dx ; es:di -> multiplexer's sign 812 <2> mov cx, 8 ; 16 bytes 813 <2> repe cmpsw ; compare 814 <2> jne .next ; not us --> 815 <2> mov dx, cs ; dx:si -> amis_id 816 <2> mov al, 11h 817 <2> int 2Dh ; CHG: al, bx, cx, dx, si, di 818 <2> cmp al, 0 ; id call supported ? 819 <2> je .unsup ; no, allow if alt version --> 820 <2> pop dx 821 <2> xor dx, dx ; 2D.MM11 supported, mark that we need it 822 <2> push dx 823 <2> cmp al, 0F0h ; CY if below 0F0h 824 <2> jmp .done 825 <2> 826 <2> .next: 827 <2> inc ah ; next multiplex number 828 <2> jnz .loop ; ZR if done, NZ if more to check --> 829 <2> .unsup: 830 <2> stc ; multiplexer not found 831 <2> ; or function not supported 832 <2> .done: 833 <2> ; CY if not an lDOS revision with our id supported, 834 <2> ; on stack: alt_expected_version if it's fine and either 835 <2> ; no multiplexer or func 11h not supported 836 <2> ; new_expected_version if not fine and either 837 <2> ; no multiplexer or func 11h not suppprted, 838 <2> ; 0 if multiplexer found, func 11h supported, but 839 <2> ; our id is unsupported 840 <2> ; NC if lDOS revision with multiplexer and our id supported 841 <2> pop bx 842 <2> pop dx 843 <2> pop di 844 <2> pop es 845 <2> pop si 846 <2> pop ds 847 <2> pop ax 848 <2> jnc alt_good_DOS ; id is supported --> 849 <2> cmp bx, alt_expected_version ; is it fine ? 850 <2> je alt_good_DOS ; yes --> (NC) 851 <2> jmp $MIF25 ; no, cancel program --> 852 <2> 853 <2> $M_VERSION_CHECK PROC NEAR ;;AN000;; 854 <2> ;; 855 <2> MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC 856 <2> INT 21H ;;AN000;; 857 <2> ;; 858 <2> cmp ax,new_expected_version ; compare with DOS version 859 <2> je check_amis 860 <2> cmp ax,alt_expected_version ; compare with DOS version 861 <2> je check_amis 862 <2> CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct 863 <2> ; $IF E ;;AN000;; 864 <2> JNE $MIF25 865 <2> alt_good_DOS: 866 <2> CLC ;;AN000;; Clear the carry flag 867 <2> ; $ELSE ;;AN000;; ELSE 868 <2> JMP SHORT $MEN25 869 <2> $MIF25: 870 <2> %IFN COMR ;; ** Special case for RESIDENT COMMAND.COM 871 <2> CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH 872 <2> ; $IF B ;;AN000;; No, 873 <2> JNB $MIF27 874 <2> MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) 875 <2> ; $ELSE ;;AN000;; Yes, 876 <2> JMP SHORT $MEN27 877 <2> $MIF27: 878 <2> MOV BX,STDERR ;;AN000;; Standard Error 879 <2> ; $ENDIF ;;AN000;; 880 <2> $MEN27: 881 <2> %ELSE 882 <2> MOV BX,NO_HANDLE ;;AN000;; No handle 883 <2> %ENDIF 884 <2> MOV AX,1 ;;AN000;; Set message # 1 885 <2> MOV CX,NO_REPLACE ;;AN000;; No replacable parms 886 <2> MOV DL,NO_INPUT ;;AN000;; No input 887 <2> MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message 888 <2> STC ;;AN000;; Set Carry Flag 889 <2> ; $ENDIF ;;AN000;; 890 <2> $MEN25: 891 <2> ;; 892 <2> RET ;;AN000;; Return 893 <2> ;; 894 <2> $M_VERSION_CHECK ENDP ;; 895 <2> ;; 896 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 897 <2> %ENDIF ;;AN000;; END of include for DOS version check 898 <2> %ENDIF ;;AN000;; END of include for SYSLOADMSG 899 <2> ; 900 <2> %IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 901 <2> %IF COMR ;;AN000;; 902 <2> $M_RT EQU $M_RT2 ;;AN000;; 903 <2> %ENDIF ;;AN000;; 904 <2> GETmsg equ FALSE ;;AN000;; Yes, THEN include it and reset flag 905 <2> ; PAGE 906 <2> ; SUBTTL DOS - Message Retriever - GETMSG.ASM Module 907 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 <2> ;; 909 <2> ;; Proc Name: SYSGETMSG 910 <2> ;; 911 <2> ;; Function: The GET service returns the segment, offset and size of the 912 <2> ;; message text to the caller based on a message number. 913 <2> ;; The GET function will not display the message thus assumes 914 <2> ;; caller will handle replaceable parameters. 915 <2> ;; 916 <2> ;; Inputs: 917 <2> ;; 918 <2> ;; Outputs: 919 <2> ;; 920 <2> ;; Psuedocode: 921 <2> ;; Call $M_GET_MSG_ADDRESS 922 <2> ;; IF MSG_NUM exists THEN 923 <2> ;; Set DS:SI = MSG_TXT_PTR + 1 924 <2> ;; CARRY_FLAG = 0 925 <2> ;; ELSE 926 <2> ;; CARRY_FLAG = 1 927 <2> ;; ENDIF 928 <2> ;; 929 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 <2> ;; 931 <2> %IF FARmsg ;;AN000;; 932 <2> SYSGETMSG PROC FAR ;;AN000;; 933 <2> %ELSE ;;AN000;; 934 <2> SYSGETMSG PROC NEAR ;;AN000;; 935 <2> %ENDIF ;;AN000;; 936 <2> ;; 937 <2> ;; Save registers needed later 938 <2> 939 <2> PUSH AX ;;AN000;; Save changed regs 940 <2> PUSH ES ;;AN000;; 941 <2> PUSH DI ;;AN000;; 942 <2> PUSH BP ;;AN000;; 943 <2> ;; 944 <2> %IF FARmsg ;;AN000;; 945 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 946 <2> %ELSE ;;AN000;; 947 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 948 <2> %ENDIF ;;AN000;; Return message in ES:DI 949 <2> ; $IF NC ;;AN000;; Message found? 950 <2> JC $MIF31 951 <2> CMP DH,UTILITY_MSG_CLASS 952 <2> CLC ;;AN000;; 953 <2> ; $IF NE 954 <2> JE $MIF32 955 <2> PUSH ES ;;AN000;; 956 <2> POP DS ;;AN000;; Return message in DS:SI 957 <2> ; $ELSE 958 <2> JMP SHORT $MEN32 959 <2> $MIF32: 960 <2> %IF FARmsg ;;AN000;; Yes, 961 <2> PUSH ES ;;AN000;; 962 <2> POP DS ;;AN000;; Return message in DS:SI 963 <2> %ELSE ;;AN000;; 964 <2> PUSH CS ;;AN000;; Return message in DS:SI 965 <2> POP DS ;;AN000;; 966 <2> %ENDIF ;;AN000;; 967 <2> ; $ENDIF ;;AN000;; 968 <2> $MEN32: 969 <2> MOV SI,DI ;;AN000;; Return message in DS:SI 970 <2> ; $ENDIF ;;AN000;; 971 <2> $MIF31: 972 <2> ;; 973 <2> POP BP ;;AN000;; Restore changed regs 974 <2> POP DI ;;AN000;; 975 <2> POP ES ;;AN000;; 976 <2> POP AX ;;AN000;; 977 <2> ;; 978 <2> RET ;;AN000;; Return 979 <2> ;; 980 <2> SYSGETMSG ENDP ;; 981 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 982 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 983 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 984 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 985 <2> ;; 986 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 987 <2> ;; 988 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 989 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 990 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 991 <2> ;; IF CX > 1 THEN ES:DI points to the specified message 992 <2> ;; REGS CHANGED: ES,DI,CX 993 <2> ;; 994 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 995 <2> ;; 996 <2> %IF FARmsg ;;AN000;; 997 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 998 <2> %ELSE ;;AN000;; 999 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 1000 <2> %ENDIF ;;AN000;; 1001 <2> ;; 1002 <2> PUSH SI ;;AN000;; 1003 <2> PUSH BX ;;AN000;; 1004 <2> XOR SI,SI ;;AN000;; Use SI as an index 1005 <2> XOR CX,CX ;;AN000;; Use CX as an size 1006 <2> ; $DO ;;AN000;; 1007 <2> $MDO36: 1008 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 1009 <2> ; $IF E ;;AN000;; Yes, 1010 <2> JNE $MIF37 1011 <2> %IF FARmsg ;;AN000;; 1012 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1013 <2> MOV BX,ES ;;AN000; 1014 <2> %ELSE ;;AN000;; 1015 <2> MOV DI,WORD PTR [$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1016 <2> MOV BX,DI ;;AN000; 1017 <2> %ENDIF ;;AN000;; 1018 <2> ; $ELSE ;;AN000;; No, 1019 <2> JMP SHORT $MEN37 1020 <2> $MIF37: 1021 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 1022 <2> ; $IF NE ;;AN000;; Yes, 1023 <2> JE $MIF39 1024 <2> LES DI,[$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 1025 <2> MOV BX,ES ;;AN000; 1026 <2> ; $ELSE ;;AN000;; No, extended errors were specified 1027 <2> JMP SHORT $MEN39 1028 <2> $MIF39: 1029 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 1030 <2> ; $IF AE,AND ;;AN000;; 1031 <2> JNAE $MIF41 1032 <2> CMP AX,$M_CRIT_HI ;;AN000;; 1033 <2> ; $IF BE ;;AN000;; Yes, 1034 <2> JNBE $MIF41 1035 <2> LES DI,[$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 1036 <2> MOV BX,ES ;;AN000; 1037 <2> ; $ELSE ;;AN000;; 1038 <2> JMP SHORT $MEN41 1039 <2> $MIF41: 1040 <2> LES DI,[$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 1041 <2> MOV BX,ES ;;AN000; 1042 <2> ; $ENDIF ;;AN000;; 1043 <2> $MEN41: 1044 <2> ; $ENDIF ;;AN000;; 1045 <2> $MEN39: 1046 <2> ; $ENDIF ;;AN000;; 1047 <2> $MEN37: 1048 <2> ;; 1049 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 1050 <2> ; $IF E ;;AN000;; Yes, 1051 <2> JNE $MIF46 1052 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 1053 <2> ; $IF E ;;AN000;; Yes, 1054 <2> JNE $MIF47 1055 <2> STC ;;AN000;; Set the carry flag 1056 <2> ; $ELSE ;;AN000;; No, 1057 <2> JMP SHORT $MEN47 1058 <2> $MIF47: 1059 <2> MOV [$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 1060 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 1061 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 1062 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 1063 <2> CLC ;;AN000;; 1064 <2> ; $ENDIF ;;AN000;; No, 1065 <2> $MEN47: 1066 <2> ; $ELSE ;;AN000;; 1067 <2> JMP SHORT $MEN46 1068 <2> $MIF46: 1069 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 1070 <2> ; $IF NE ;;AN001;; Yes, 1071 <2> JE $MIF51 1072 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 1073 <2> ; $ENDIF ;;AN000;; 1074 <2> $MIF51: 1075 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 1076 <2> CLC ;;AN000;; 1077 <2> ; $ENDIF ;;AN000;; 1078 <2> $MEN46: 1079 <2> ; $LEAVE C ;;AN000;; 1080 <2> JC $MEN36 1081 <2> OR CX,CX ;;AN000;; Was the message found? 1082 <2> ; $ENDDO NZ,LONG ;;AN000;; 1083 <2> JNZ $MXL2 1084 <2> JMP $MDO36 1085 <2> $MXL2: 1086 <2> $MEN36: 1087 <2> 1088 <2> PUSHF ;;AN006;; Save the flag state 1089 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 1090 <2> ; $IF E ;;AN006;; Yes, 1091 <2> JNE $MIF56 1092 <2> PUSH DX ;;AN006;; Save all needed registers 1093 <2> PUSH BP ;;AN006;; 1094 <2> PUSH CX ;;AN006;; 1095 <2> PUSH ES ;;AN006;; 1096 <2> PUSH DI ;;AN006;; 1097 <2> PUSH AX ;;AN006;; 1098 <2> 1099 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 1100 <2> INT 2FH ;;AN006;; 1101 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 1102 <2> POP AX ;;AN006;; Restore msg number 1103 <2> ; $IF E ;;AN006;; Yes, 1104 <2> JNE $MIF57 1105 <2> MOV BX,AX ;;AN006;; BX is the extended error number 1106 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 1107 <2> INT 2FH ;;AN006;; Call IFSFUNC 1108 <2> ; $ELSE ;;AN006;; No, 1109 <2> JMP SHORT $MEN57 1110 <2> $MIF57: 1111 <2> STC ;;AN006;; Carry conditon 1112 <2> ; $ENDIF ;;AN006;; 1113 <2> $MEN57: 1114 <2> 1115 <2> ; $IF C ;;AN006;; Was there an update? 1116 <2> JNC $MIF60 1117 <2> POP DI ;;AN006;; No, 1118 <2> POP ES ;;AN006;; Restore old pointer 1119 <2> POP CX ;;AN006;; 1120 <2> ; $ELSE ;;AN006;; Yes 1121 <2> JMP SHORT $MEN60 1122 <2> $MIF60: 1123 <2> ADD SP,6 ;;AN006;; Throw away old pointer 1124 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 1125 <2> ; $ENDIF ;;AN006;; 1126 <2> $MEN60: 1127 <2> POP BP ;;AN006;; Restore other Regs 1128 <2> POP DX ;;AN006;; 1129 <2> ; $ENDIF ;;AN006;; 1130 <2> $MIF56: 1131 <2> $M_POPF ;;AN006;; Restore the flag state 1132 <2> 1133 <2> POP BX ;;AN000;; 1134 <2> POP SI ;;AN000;; 1135 <2> RET ;;AN000;; Return ES:DI pointing to the message 1136 <2> ;; 1137 <2> $M_GET_MSG_ADDRESS ENDP ;; 1138 <2> ;; 1139 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 1140 <2> ;; 1141 <2> PUSH DI ;;AN006;; Save position 1142 <2> PUSH AX ;;AN006;; 1143 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 1144 <2> XOR AL,AL ;;AN006;; Prepare compare register 1145 <2> REPNE SCASB ;;AN006;; Scan for zero 1146 <2> NOT CX ;;AN006;; Change decrement into number 1147 <2> DEC CX ;;AN006;; Don't include the zero 1148 <2> POP AX ;;AN006;; 1149 <2> POP DI ;;AN006;; Restore position 1150 <2> RET ;;AN006;; 1151 <2> ;; 1152 <2> $M_SET_LEN_IN_CX ENDP ;; 1153 <2> ;; 1154 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1155 <2> ;; 1156 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 1157 <2> ;; 1158 <2> ;; FUNCTION: To scan thru message headers until message is found 1159 <2> ;; INPUTS: ES:DI points to beginning of msg headers 1160 <2> ;; CX contains the number of messages in class 1161 <2> ;; DH contains the message class 1162 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 1163 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 1164 <2> ;; 1165 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1166 <2> ;; 1167 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 1168 <2> ;; 1169 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 1170 <2> ; $IF E,AND ;;AN004;; Yes, 1171 <2> JNE $MIF64 1172 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 1173 <2> ; $IF NE ;;AN004;; Yes, 1174 <2> JE $MIF64 1175 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 1176 <2> ; $IF E ;;AN004;; . . . and . . . 1177 <2> JNE $MIF65 1178 <2> PUSH AX ;;AN004;; Reset the special message number 1179 <2> MOV AX,[$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 1180 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1181 <2> POP AX ;;AN004;; Reset the special message number 1182 <2> ; $ELSE ;;AN004;; Get the old message number 1183 <2> JMP SHORT $MEN65 1184 <2> $MIF65: 1185 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1186 <2> ; $ENDIF ;;AN004;; Get the old message number 1187 <2> $MEN65: 1188 <2> ; $ELSE ;;AN004;; 1189 <2> JMP SHORT $MEN64 1190 <2> $MIF64: 1191 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 1192 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1193 <2> ; $IF NE ;;AN001;; 1194 <2> JE $MIF69 1195 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 1196 <2> ; $ELSE ;;AN001;; 1197 <2> JMP SHORT $MEN69 1198 <2> $MIF69: 1199 <2> %IF FARmsg ;;AN001;; 1200 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1201 <2> %ELSE 1202 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1203 <2> %ENDIF 1204 <2> ; $IF E ;;AN002;; pointer (hopefully) 1205 <2> JNE $MIF71 1206 <2> %IF FARmsg ;;AN001;; 1207 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1208 <2> %ELSE 1209 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1210 <2> %ENDIF 1211 <2> ; $ENDIF ;;AN002;; go on to the next class 1212 <2> $MIF71: 1213 <2> ; $ENDIF ;;AN001;; 1214 <2> $MEN69: 1215 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 1216 <2> STC ;;AN004;; Flag that we haven't found anything yet 1217 <2> ; $ENDIF ;;AN004;; 1218 <2> $MEN64: 1219 <2> 1220 <2> ; $IF C ;;AN004;; Have we found anything yet? 1221 <2> JNC $MIF75 1222 <2> CLC ;;AN004;; No, reset carry 1223 <2> ; $SEARCH ;;AN000;; 1224 <2> $MDO76: 1225 <2> OR CX,CX ;;AN000;; Do we have any to check? 1226 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1227 <2> JZ $MEN76 1228 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1229 <2> ; $IF NE ;;AN001;; 1230 <2> JE $MIF78 1231 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 1232 <2> ; $ELSE ;;AN001;; 1233 <2> JMP SHORT $MEN78 1234 <2> $MIF78: 1235 <2> %IF FARmsg ;;AN001;; 1236 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 1237 <2> %ELSE 1238 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 1239 <2> %ENDIF 1240 <2> ; $ENDIF 1241 <2> $MEN78: 1242 <2> ; $EXITIF E ;;AN000;; 1243 <2> JNE $MIF76 1244 <2> ; $ORELSE ;;AN000; 1245 <2> JMP SHORT $MSR76 1246 <2> $MIF76: 1247 <2> DEC CX ;;AN000;; No, well do we have more to check? 1248 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1249 <2> JZ $MEN76 1250 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 1251 <2> ; $ENDLOOP ;;AN000;; 1252 <2> JMP SHORT $MDO76 1253 <2> $MEN76: 1254 <2> STC ;;AN000;; 1255 <2> ; $ENDSRCH ;;AN000;; Check next message 1256 <2> $MSR76: 1257 <2> ; $IF NC ;;AN000;; Did we find the message? 1258 <2> JC $MIF86 1259 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 1260 <2> CLC ;;AN001;; 1261 <2> ; $IF E ;;AN001;; 1262 <2> JNE $MIF87 1263 <2> %IF FARmsg ;;AN001;; 1264 <2> %ELSE ;;AN000;; 1265 <2> PUSH CS ;;AN000;; 1266 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 1267 <2> %ENDIF 1268 <2> ; $ENDIF ;;AN001;; 1269 <2> $MIF87: 1270 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 1271 <2> ; $ENDIF ;;AN004;; 1272 <2> $MIF86: 1273 <2> ; $ENDIF ;;AN004;; 1274 <2> $MIF75: 1275 <2> ;; Yes, great we can return with CX > 0 1276 <2> 1277 <2> ; $IF NC ;;AN000;; Did we find the message? 1278 <2> JC $MIF91 1279 <2> XOR CH,CH ;;AN000;; 1280 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 1281 <2> INC DI ;;AN000;; Increment past length 1282 <2> ; $ENDIF ;;AN004;; 1283 <2> $MIF91: 1284 <2> 1285 <2> MOV byte [$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 1286 <2> RET ;;AN000;; Return 1287 <2> ;; 1288 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 1289 <2> ;; 1290 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1291 <2> %ENDIF ;;AN000;; END of include of common subroutines 1292 <2> %ENDIF ;;AN000;; END of include of SYSGETMSG 1293 <2> ; 1294 <2> %IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 1295 <2> %IF COMR ;;AN000;; 1296 <2> $M_RT EQU $M_RT2 ;;AN000;; 1297 <2> %ENDIF ;;AN000;; 1298 <2> %iassign DISPLAYmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 1299 <2> ; PAGE 1300 <2> ; SUBTTL DOS - Message Retriever - DISPMSG.ASM Module 1301 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1302 <2> ;; 1303 <2> ;; Proc Name: SYSDISPMSG 1304 <2> ;; 1305 <2> ;; Function: The DISPLAY service will output a defined message to a handle 1306 <2> ;; requested by the caller. It also provides function to display 1307 <2> ;; messages when handles are not applicable (ie. DOS function calls 1308 <2> ;; 00h to 0Ah) Replaceable parameters are allowed and are 1309 <2> ;; defined previous to entry. 1310 <2> ;; 1311 <2> ;; It is assumes that a PRELOAD function has already determined 1312 <2> ;; the addressibilty internally to the message retriever services. 1313 <2> ;; Inputs: 1314 <2> ;; 1315 <2> ;; Outputs: 1316 <2> ;; 1317 <2> ;; Psuedocode: 1318 <2> ;; Save registers needed later 1319 <2> ;; Get address of the message requested 1320 <2> ;; IF Message number exists THEN 1321 <2> ;; IF replacable parameters were specified THEN 1322 <2> ;; Display message with replacable parms 1323 <2> ;; ELSE 1324 <2> ;; Display string without replacable parms 1325 <2> ;; ENDIF 1326 <2> ;; IF character input was requested THEN 1327 <2> ;; Wait for character input 1328 <2> ;; ENDIF 1329 <2> ;; Clear CARRY FLAG 1330 <2> ;; ELSE 1331 <2> ;; Set CARRY FLAG 1332 <2> ;; ENDIF 1333 <2> ;; Return 1334 <2> ;; 1335 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1336 <2> ;; 1337 <2> %IF FARmsg ;;AN000;; 1338 <2> SYSDISPMSG PROC FAR ;;AN000;; 1339 <2> %ELSE ;;AN000;; 1340 <2> SYSDISPMSG PROC NEAR ;;AN000;; 1341 <2> %ENDIF ;;AN000;; 1342 <2> ;; 1343 <2> ;; Save registers and values needed later 1344 <2> 1345 <2> PUSH AX ;;AN000;; Save changed REGs 1346 <2> PUSH BX ;;AN000;; 1347 <2> PUSH CX ;;AN000;; 1348 <2> PUSH BP ;;AN000;; 1349 <2> PUSH DI ;;AN000;; Save pointer to input buffer (offset) 1350 <2> PUSH ES ;;AN000;; Save pointer to input buffer (segment) 1351 <2> PUSH DX ;;AN000;; Save Input/Class request 1352 <2> 1353 <2> MOV BP,CX ;;AN000;; Use BP to hold replace count 1354 <2> MOV WORD PTR [cs:$M_RT + $M_HANDLE],BX ;;AN000;; Save handle 1355 <2> MOV BYTE PTR [cs:$M_RT + $M_CLASS],DH ;;AN004;; Save class 1356 <2> 1357 <2> ;; Get address of the message requested 1358 <2> 1359 <2> %IF FARmsg ;;AN000;; 1360 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1361 <2> %ELSE ;;AN000;; 1362 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1363 <2> %ENDIF ;;AN000;; 1364 <2> OR CX,CX ;;AN000;; Was message found? 1365 <2> ; $IF NZ ;;AN000;; YES, Message address in ES:DI 1366 <2> JZ $MIF93 1367 <2> 1368 <2> ;; Test if replacable parameters were specified 1369 <2> 1370 <2> OR BP,BP ;;AN000;; Were replacable parameters requested 1371 <2> ; $IF Z ;;AN000;; 1372 <2> JNZ $MIF94 1373 <2> 1374 <2> ;; Display string without replacable parms 1375 <2> 1376 <2> CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message 1377 <2> ; $ELSE ;;AN000;; 1378 <2> JMP SHORT $MEN94 1379 <2> $MIF94: 1380 <2> %IF $M_REPLACE ;;AN000;; 1381 <2> 1382 <2> ;; Display message with replacable parms 1383 <2> 1384 <2> CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions 1385 <2> %ENDIF ;;AN000;; 1386 <2> ; $ENDIF ;;AN000;; 1387 <2> $MEN94: 1388 <2> ; $IF NC 1389 <2> JC $MIF97 1390 <2> 1391 <2> POP DX ;;AN000;; Get Input/Class request 1392 <2> 1393 <2> CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. 1394 <2> 1395 <2> POP ES ;;AN000;; Get location of input buffer (if specified) 1396 <2> POP DI ;;AN000;; 1397 <2> 1398 <2> ;; Test if character input was requested 1399 <2> 1400 <2> %IF INPUTmsg ;;AN000;; 1401 <2> OR DL,DL ;;AN000;; Was Wait-For-Input requested? 1402 <2> ; $IF NZ ;;AN000;; 1403 <2> JZ $MIF98 1404 <2> CALL $M_WAIT_FOR_INPUT ;;AN000;; 1405 <2> ; $ENDIF ;;AN000;; 1406 <2> $MIF98: 1407 <2> %ENDIF ;;AN000;; 1408 <2> ; $ELSE ;;AN000;; 1409 <2> JMP SHORT $MEN97 1410 <2> $MIF97: 1411 <2> ADD SP,6 ;;AN000;; 1412 <2> STC ;;AN000;; Reset carry flag 1413 <2> ; $ENDIF ;;AN000;; 1414 <2> $MEN97: 1415 <2> ; $ELSE ;;AN000;; No, 1416 <2> JMP SHORT $MEN93 1417 <2> $MIF93: 1418 <2> POP ES ;;AN000;; Get pointer to input buffer (segment) 1419 <2> POP DI ;;AN000;; Get base pointer to first sublist (offset) 1420 <2> POP DX ;;AN000;; Get base pointer to first sublist (segment) 1421 <2> STC ;;AN000;; Set carry flag 1422 <2> ; $ENDIF ;;AN000;; 1423 <2> $MEN93: 1424 <2> ;; 1425 <2> ; $IF NC ;;AN000;; Was there an error? 1426 <2> JC $MIF104 1427 <2> POP BP ;;AN000;; No, 1428 <2> POP CX ;;AN000;; 1429 <2> POP BX ;;AN000;; 1430 <2> %IF INPUTmsg ;;AN000;; 1431 <2> ADD SP,2 ;;AN000;; 1432 <2> %ELSE ;AN000; 1433 <2> POP AX ;;AN000;; 1434 <2> %ENDIF ;;AN000;; 1435 <2> ; $ELSE ;;AN000;; Yes, 1436 <2> JMP SHORT $MEN104 1437 <2> $MIF104: 1438 <2> ADD SP,8 ;;AN000;; Eliminate from stack 1439 <2> STC ;;AN000;; 1440 <2> ; $ENDIF ;;AN000;; 1441 <2> $MEN104: 1442 <2> ;; 1443 <2> RET ;;AN000;; Return 1444 <2> ;; 1445 <2> SYSDISPMSG ENDP ;;AN000;; 1446 <2> ;; 1447 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1448 <2> ; 1449 <2> ;; 1450 <2> ;; PROC NAME: $M_DISPLAY_STRING 1451 <2> ;; 1452 <2> ;; FUNCTION: Will display or write string 1453 <2> ;; INPUTS: ES:DI points to beginning of message 1454 <2> ;; CX contains the length of string to write (if applicable) 1455 <2> ;; OUTPUTS: None 1456 <2> ;; REGS Revised: None 1457 <2> ;; 1458 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1459 <2> ;; 1460 <2> $M_DISPLAY_STRING PROC NEAR ;;AN000;; 1461 <2> ;; 1462 <2> PUSH AX ;;AN000;; 1463 <2> PUSH BX ;;AN000;; 1464 <2> PUSH DX ;;AN000;; 1465 <2> ;; 1466 <2> MOV BX,[cs:$M_RT + $M_HANDLE] ;;AN000;; Retrieve handle 1467 <2> ;; 1468 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 1469 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1470 <2> %ELSE 1471 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1472 <2> ; $IF E ;;AN000;; 1473 <2> JNE $MIF107 1474 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1475 <2> ; $ELSE ;;AN000;; 1476 <2> JMP SHORT $MEN107 1477 <2> $MIF107: 1478 <2> CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle 1479 <2> ; $ENDIF ;;AN000;; 1480 <2> $MEN107: 1481 <2> ;AN001; 1482 <2> ; $IF C ;;AN000;; Was there an error? 1483 <2> JNC $MIF110 1484 <2> MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, 1485 <2> MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error 1486 <2> INT 21H ;;AN000;; 1487 <2> XOR AH,AH ;;AN000;; Clear AH 1488 <2> ADD SP,6 ;;AN000;; Clean up stack 1489 <2> STC ;;AN000;; Flag that there was an error 1490 <2> ; $ELSE ;;AN000;; No, 1491 <2> JMP SHORT $MEN110 1492 <2> $MIF110: 1493 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1494 <2> ; $IF NE ;;AN000;; 1495 <2> JE $MIF112 1496 <2> CMP AX,CX ;AN001; Was it ALL written? 1497 <2> ; $IF NE ;AN001; No, 1498 <2> JE $MIF113 1499 <2> CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error 1500 <2> ADD SP,6 ;AN001; Clean up stack 1501 <2> STC ;AN001; Flag that there was an error 1502 <2> ; $ENDIF ;AN001; 1503 <2> $MIF113: 1504 <2> ; $ENDIF ;AN001; 1505 <2> $MIF112: 1506 <2> ; $ENDIF ;;AN000;; 1507 <2> $MEN110: 1508 <2> %ENDIF 1509 <2> ; $IF NC ;;AN000;; Was there ANY error? 1510 <2> JC $MIF117 1511 <2> POP DX ;;AN000;; Restore regs 1512 <2> POP BX ;;AN000;; 1513 <2> POP AX ;;AN000;; 1514 <2> ; $ENDIF ;;AN000;; 1515 <2> $MIF117: 1516 <2> RET ;;AN000;; Return 1517 <2> ;; 1518 <2> $M_DISPLAY_STRING ENDP ;;AN000;; 1519 <2> ;; 1520 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1521 <2> ;; 1522 <2> ;; PROC NAME: $M_DISPLAY_$_STRING 1523 <2> ;; 1524 <2> ;; FUNCTION: Will display a $ terminated string 1525 <2> ;; INPUTS: ES:DI points to beginning of message text (not the length) 1526 <2> ;; OUPUTS: None 1527 <2> ;; REGS USED: AX,DX 1528 <2> ;; 1529 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1530 <2> ;; 1531 <2> $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; 1532 <2> ;; 1533 <2> PUSH DS ;;AN000;; 1534 <2> PUSH ES ;;AN000;; 1535 <2> POP DS ;;AN000;; Set DS to segment of message text 1536 <2> %IFN COMR 1537 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1538 <2> ; $IF E ;;AN000;; Yes, 1539 <2> JNE $MIF119 1540 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1541 <2> MOV DL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1542 <2> INT 21H ;;AN000;; Write character 1543 <2> POP DS ;;AN000;; Set DS to segment of message text 1544 <2> MOV AL,DL ;;AN000;; Get the character in AL 1545 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1546 <2> PUSH DS ;;AN000;; 1547 <2> PUSH ES ;;AN000;; 1548 <2> POP DS ;;AN000;; Set DS to segment of message text 1549 <2> ; $IF C ;;AN000;; Yes, 1550 <2> JNC $MIF120 1551 <2> MOV DL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 1552 <2> INT 21H ;;AN000;; Write character 1553 <2> CLC ;;AN000;; Clear the DBCS indicator 1554 <2> ; $ENDIF ;;AN000;; 1555 <2> $MIF120: 1556 <2> ; $ELSE ;;AN000;; No, 1557 <2> JMP SHORT $MEN119 1558 <2> $MIF119: 1559 <2> %ENDIF 1560 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1561 <2> ; $DO ;;AN002;; No, 1562 <2> $MDO123: 1563 <2> OR CX,CX ;;AN002;; Are there any left to display? 1564 <2> ; $LEAVE Z ;;AN002;; Yes, 1565 <2> JZ $MEN123 1566 <2> MOV DL,BYTE PTR [ES:DI] ;;AN002;; Get the character 1567 <2> INT 21H ;;AN002;; Display the character 1568 <2> INC DI ;;AN002;; Set pointer to next character 1569 <2> DEC CX ;;AN002;; Count this character 1570 <2> ; $ENDDO Z ;;AN002;; No, 1571 <2> JNZ $MDO123 1572 <2> $MEN123: 1573 <2> %IFN COMR 1574 <2> ; $ENDIF ;;AN000;; 1575 <2> $MEN119: 1576 <2> %ENDIF 1577 <2> CLC ;;AN000;; Char functions used don't return carry as error 1578 <2> POP DS ;;AN000;; 1579 <2> RET ;;AN000;; 1580 <2> ;; 1581 <2> $M_DISPLAY_$_STRING ENDP ;;AN000;; 1582 <2> ;; 1583 <2> %IFN COMR 1584 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1585 <2> ;; 1586 <2> ;; PROC NAME: $M_DISPLAY_H_STRING 1587 <2> ;; 1588 <2> ;; FUNCTION: Will display a string to a specified handle 1589 <2> ;; INPUTS: ES:DI points to beginning of message 1590 <2> ;; CX contains the number of bytes to write 1591 <2> ;; BX contains the handle to write to 1592 <2> ;; OUPUTS: None 1593 <2> ;; REGS USED: AX,DX 1594 <2> ;; 1595 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1596 <2> ;; 1597 <2> $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; 1598 <2> ;; 1599 <2> XOR AX,AX ;;AN002;; Set number of bytes written to 0 1600 <2> OR CX,CX ;;AN002;; For performance, don't write if not necessary 1601 <2> ; $IF NZ ;;AN002;; Any chars to write? 1602 <2> JZ $MIF127 1603 <2> PUSH DS ;;AN000;; Yes, 1604 <2> PUSH ES ;;AN000;; 1605 <2> POP DS ;;AN000;; Set DS to segment of message text 1606 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1607 <2> MOV DX,DI ;;AN000;; Pointer to data to write 1608 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1609 <2> ; $IF E ;;AN000;; Yes, 1610 <2> JNE $MIF128 1611 <2> INT 21H ;;AN000;; Write character 1612 <2> POP DS ;;AN000;; Set DS to segment of message text 1613 <2> PUSH AX ;;AN000;; 1614 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1615 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1616 <2> POP AX ;;AN000;; Set DS to segment of message text 1617 <2> PUSH DS ;;AN000;; 1618 <2> PUSH ES ;;AN000;; 1619 <2> POP DS ;;AN000;; Set DS to segment of message text 1620 <2> ; $IF C ;;AN000;; Yes, 1621 <2> JNC $MIF129 1622 <2> CLC ;;AN000;; Clear the DBCS indicator 1623 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1624 <2> INC DX ;;AN000;; Point to next character 1625 <2> INT 21H ;;AN000;; Write character 1626 <2> ; $ENDIF ;;AN000;; 1627 <2> $MIF129: 1628 <2> ; $ELSE ;;AN000;; No, 1629 <2> JMP SHORT $MEN128 1630 <2> $MIF128: 1631 <2> INT 21H ;;AN000;; Write String at DS:SI to handle 1632 <2> ; $ENDIF ;;AN000;; 1633 <2> $MEN128: 1634 <2> POP DS ;;AN000;; 1635 <2> ; $ENDIF ;;AN002;; 1636 <2> $MIF127: 1637 <2> ;; 1638 <2> RET ;;AN000;; 1639 <2> ;; 1640 <2> $M_DISPLAY_H_STRING ENDP ;;AN000;; 1641 <2> ;; 1642 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1643 <2> ;; 1644 <2> ;; PROC NAME: $M_GET_EXT_ERR_39 1645 <2> ;; 1646 <2> ;; FUNCTION: Will set registers for extended error #39 1647 <2> ;; INPUTS: None 1648 <2> ;; OUPUTS: AX,BX,CX set 1649 <2> ;; REGS USED: 1650 <2> ;; 1651 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1652 <2> ;; 1653 <2> $M_GET_EXT_ERR_39 PROC NEAR ;AN001; 1654 <2> ;; 1655 <2> MOV AX,EXT_ERR_39 ;AN001; Set AX=39 1656 <2> MOV BX,(ERROR_CLASS_39 >> 8) + ACTION_39 ;AN001; Set BH=1 BL=4 1657 <2> MOV CH,LOCUS_39 ;AN001; Set CH=1 1658 <2> ;AN001; 1659 <2> RET ;AN001; 1660 <2> ;; 1661 <2> $M_GET_EXT_ERR_39 ENDP ;AN001; 1662 <2> ;; 1663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1664 <2> %ENDIF 1665 <2> ;; 1666 <2> ;; PROC NAME: $M_ADD_CRLF 1667 <2> ;; 1668 <2> ;; FUNCTION: Will decide whether to display a CRLF 1669 <2> ;; INPUTS: DX contains the Input/Class requested 1670 <2> ;; OUTPUTS: None 1671 <2> ;; REGS Revised: CX,ES,DI 1672 <2> ;; 1673 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1674 <2> ;; 1675 <2> $M_ADD_CRLF PROC NEAR ;;AN004;; 1676 <2> ;; 1677 <2> CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1678 <2> ; $IF NE ;;AN004;; No, 1679 <2> JE $MIF134 1680 <2> TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? 1681 <2> ; $IF Z ;;AN004;; No, 1682 <2> JNZ $MIF135 1683 <2> PUSH DS ;;AN004;; 1684 <2> POP ES ;;AN004;; Set ES to data segment 1685 <2> LEA DI,[$M_RT + $M_CRLF] ;;AN004;; Point at CRLF message 1686 <2> MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size 1687 <2> CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF 1688 <2> ; $ENDIF ;;AN004;; 1689 <2> $MIF135: 1690 <2> ; $ENDIF ;;AN004;; 1691 <2> $MIF134: 1692 <2> RET ;;AN004;; Return 1693 <2> ;; 1694 <2> $M_ADD_CRLF ENDP ;;AN004;; 1695 <2> ;; 1696 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1697 <2> ;; 1698 <2> ;; PROC NAME: $M_IS_IT_DBCS 1699 <2> ;; 1700 <2> ;; FUNCTION: Will decide whether character is Single or Double Byte 1701 <2> ;; INPUTS: AL contains the byte to be checked 1702 <2> ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range 1703 <2> ;; Carry flag = 1 if byte IS in DBCS range 1704 <2> ;; REGS USED: All restored 1705 <2> ;; 1706 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1707 <2> ;; 1708 <2> $M_IS_IT_DBCS PROC NEAR ;;AN000;; 1709 <2> ;; 1710 <2> PUSH ES ;;AN000;; Save Extra segment register 1711 <2> PUSH DI ;;AN000;; Save SI register 1712 <2> ;; 1713 <2> LES DI,[cs:$M_RT + $M_DBCS_VEC] ;;AN000;; 1714 <2> OR DI,DI ;;AN000;; Was the DBCS vector set? 1715 <2> ; $IF NZ ;;AN000;; 1716 <2> JZ $MIF138 1717 <2> ; $DO ;;AN000;; 1718 <2> $MDO139: 1719 <2> CMP WORD PTR [ES:DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? 1720 <2> CLC ;;AN000;; 1721 <2> ; $LEAVE E ;;AN000;; 1722 <2> JE $MEN139 1723 <2> ;; No, 1724 <2> CMP AL,BYTE PTR [ES:DI] ;;AN000;; Does the character fall in the DBCS range? 1725 <2> ; $IF AE,AND ;;AN000;; 1726 <2> JNAE $MIF141 1727 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Does the character fall in the DBCS range? 1728 <2> ; $IF BE ;;AN000;; 1729 <2> JNBE $MIF141 1730 <2> STC ;;AN000;; Yes, 1731 <2> ; $ENDIF ;;AN000;; Set carry flag 1732 <2> $MIF141: 1733 <2> INC DI ;;AN000;; No, 1734 <2> INC DI ;;AN000;; Go to next vector 1735 <2> ; $ENDDO ;;AN000;; 1736 <2> JMP SHORT $MDO139 1737 <2> $MEN139: 1738 <2> ; $ENDIF ;;AN000;; 1739 <2> $MIF138: 1740 <2> 1741 <2> POP DI ;;AN000;; 1742 <2> POP ES ;;AN000;; Restore SI register 1743 <2> RET ;;AN000;; Return 1744 <2> ;; 1745 <2> $M_IS_IT_DBCS ENDP ;;AN000;; 1746 <2> ;; 1747 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1748 <2> ;; 1749 <2> ;; PROC NAME: $M_CONVERT2ASC 1750 <2> ;; 1751 <2> ;; FUNCTION: Convert a binary number to a ASCII string 1752 <2> ;; INPUTS: DX:AX contains the number to be converted 1753 <2> ;; $M_RT_DIVISOR contains the divisor 1754 <2> ;; OUPUTS: CX contains the number of characters 1755 <2> ;; Top of stack --> Last character 1756 <2> ;; . . . 1757 <2> ;; Bot of stack --> First character 1758 <2> ;; REGS USED: 1759 <2> ;; 1760 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1761 <2> ;; 1762 <2> $M_CONVERT2ASC PROC NEAR ;;AN000;; 1763 <2> ;; 1764 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Save Return Address 1765 <2> XOR BX,BX ;;AN000;; Use BP as a swapping register 1766 <2> ;; 1767 <2> XCHG BX,AX ;;AN000;; Initialize - Low Word in BP 1768 <2> XCHG AX,DX ;;AN000;; - High Word in AX 1769 <2> ; $DO ;;AN000;; DO UNTIL Low Word becomes zero 1770 <2> $MDO145: 1771 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide High Word by divisor 1772 <2> XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder 1773 <2> ;; and save reduced High Word in BP 1774 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide Low Word by divisor 1775 <2> CMP DX,9 ;;AN000;; Make a digit of the remainder 1776 <2> ; $IF A ;;AN000;; IF 10 to 15, 1777 <2> JNA $MIF146 1778 <2> ADD DL,55 ;;AN000;; Make A to F ASCII 1779 <2> ; $ELSE ;;AN000;; IF 0 to 9, 1780 <2> JMP SHORT $MEN146 1781 <2> $MIF146: 1782 <2> ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII 1783 <2> ; $ENDIF ;;AN000;; 1784 <2> $MEN146: 1785 <2> PUSH DX ;;AN000;; Save the digit on the stack 1786 <2> INC CX ;;AN000;; Count that digit 1787 <2> OR AX,AX ;;AN000;; Are we done? 1788 <2> ; $LEAVE Z,AND ;;AN000;; 1789 <2> JNZ $MLL149 1790 <2> OR BX,BX ;;AN000;; AX and BX must be ZERO!! 1791 <2> ; $LEAVE Z ;;AN000;; No, 1792 <2> JZ $MEN145 1793 <2> $MLL149: 1794 <2> %IFN COMR 1795 <2> CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark 1796 <2> ; $IF E ;;AN000;; Yes, 1797 <2> JNE $MIF150 1798 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1799 <2> ; $IF E ;;AN000;; Yes, 1800 <2> JNE $MIF151 1801 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1802 <2> INC CX ;;AN000;; 1803 <2> ; $ENDIF ;;AN000;; 1804 <2> $MIF151: 1805 <2> ; $ELSE ;;AN000;; No, 1806 <2> JMP SHORT $MEN150 1807 <2> $MIF150: 1808 <2> CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark 1809 <2> ; $IF E ;;AN000;; Yes, 1810 <2> JNE $MIF154 1811 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1812 <2> ; $IF E ;;AN000;; Yes, 1813 <2> JNE $MIF155 1814 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1815 <2> INC CX ;;AN000;; 1816 <2> ; $ENDIF ;;AN000;; 1817 <2> $MIF155: 1818 <2> ; $ELSE ;;AN000;; No, 1819 <2> JMP SHORT $MEN154 1820 <2> $MIF154: 1821 <2> CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark 1822 <2> ; $IF E ;;AN000;; Yes, 1823 <2> JNE $MIF158 1824 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1825 <2> ; $IF E ;;AN000;; Yes, 1826 <2> JNE $MIF159 1827 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1828 <2> INC CX ;;AN000;; 1829 <2> ; $ENDIF ;;AN000;; 1830 <2> $MIF159: 1831 <2> ; $ENDIF ;;AN000;; 1832 <2> $MIF158: 1833 <2> ; $ENDIF ;;AN000;; 1834 <2> $MEN154: 1835 <2> ; $ENDIF ;;AN000;; 1836 <2> $MEN150: 1837 <2> %ENDIF 1838 <2> XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word 1839 <2> ;;AN000;; and Revised Low Word 1840 <2> XOR DX,DX ;;AN000;; Reset remainder 1841 <2> ; $ENDDO ;;AN000;; NEXT 1842 <2> JMP SHORT $MDO145 1843 <2> $MEN145: 1844 <2> ;;AN000;; Yes, 1845 <2> XOR DX,DX ;;AN000;; Reset remainder 1846 <2> XOR AX,AX ;;AN000;; Reset remainder 1847 <2> PUSH word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Restore Return Address 1848 <2> RET ;;AN000;; Return 1849 <2> ;; 1850 <2> $M_CONVERT2ASC ENDP ;;AN000;; 1851 <2> ;; 1852 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1853 <2> ;; 1854 <2> ;; PROC NAME: $M_DISPLAY_MESSAGE 1855 <2> ;; 1856 <2> ;; FUNCTION: Will display or write entire message (with replacable parameters) 1857 <2> ;; INPUTS: ES:DI points to beginning of message 1858 <2> ;; DS:SI points to first sublist structure in chain 1859 <2> ;; BX contains the handle to write to (if applicable) 1860 <2> ;; CX contains the length of string to write (before substitutions) 1861 <2> ;; BP contains the count of replacables 1862 <2> ;; 1863 <2> ;; OUTPUTS: 1864 <2> ;; REGS USED: All 1865 <2> ;; 1866 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1867 <2> ;; 1868 <2> $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; 1869 <2> ;; 1870 <2> ; $DO ;;AN000;; Note: DS:SI -> message 1871 <2> $MDO165: 1872 <2> XOR DX,DX ;;AN000;; Set size = 0 1873 <2> OR CX,CX ;;AN000;; Are we finished the message yet? 1874 <2> ; $IF NZ ;;AN000;; No, 1875 <2> JZ $MIF166 1876 <2> MOV AH,"%" ;;AN000;; Prepare to scan for % 1877 <2> MOV AL,0 ;;AN004;; 1878 <2> ;; 1879 <2> ; $DO ;;AN000;; Scan through string until % 1880 <2> $MDO167: 1881 <2> CMP BYTE PTR [ES:DI],AH ;;AN000;; Is this character NOT a % 1882 <2> ; $LEAVE E,AND ;;AN000;; No, 1883 <2> JNE $MLL168 1884 <2> CMP BYTE PTR [ES:DI+1],AH ;;AN000;; Is the next character also a % 1885 <2> ; $LEAVE NE,AND ;;AN000;; No, 1886 <2> JE $MLL168 1887 <2> CMP AL,AH ;;AN000;; Was the character before a % 1888 <2> ; $LEAVE NE ;;AN000;; No, GREAT found it 1889 <2> JNE $MEN167 1890 <2> $MLL168: 1891 <2> MOV AL,BYTE PTR [ES:DI] ;;AN004;; Yes, (to any of the above) 1892 <2> CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? 1893 <2> ; $IF C ;;AN004;; Yes, 1894 <2> JNC $MIF169 1895 <2> INC DI ;;AN004;; Increment past second part 1896 <2> ; $ENDIF ;;AN004;; 1897 <2> $MIF169: 1898 <2> INC DI ;;AN000;; Next character in string 1899 <2> INC DX ;;AN000;; Size = Size + 1 1900 <2> DEC CX ;;AN000;; Decrement total size 1901 <2> ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line 1902 <2> JNZ $MDO167 1903 <2> $MEN167: 1904 <2> ; $ENDIF ;;AN000;; 1905 <2> $MIF166: 1906 <2> ;; 1907 <2> PUSH SI ;;AN000;; Save beginning of sublists 1908 <2> XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) 1909 <2> OR BP,BP ;;AN000;; Do we have any replacables to do? 1910 <2> ; $IF NZ ;;AN000;; Yes, 1911 <2> JZ $MIF173 1912 <2> DEC BP ;;AN000;; Decrement number of replacables 1913 <2> 1914 <2> ;; Search through sublists to find applicable one 1915 <2> 1916 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 1917 <2> ; $IF E ;;AN000;; No, 1918 <2> JNE $MIF174 1919 <2> ; $SEARCH ;;AN000;; 1920 <2> $MDO175: 1921 <2> MOV AL,[$M_SL + $M_S_ID] ;;AN000;; Get ID byte 1922 <2> ADD AL,30H ;;AN000;; Convert to ASCII 1923 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Is this the right sublist? 1924 <2> ; $EXITIF E ;;AN000;; 1925 <2> JNE $MIF175 1926 <2> ; $ORELSE ;;AN000;; No, 1927 <2> JMP SHORT $MSR175 1928 <2> $MIF175: 1929 <2> CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 1930 <2> ; $LEAVE E,AND ;;AN000;; Yes, 1931 <2> JNE $MLL178 1932 <2> OR DX,DX ;;AN000;; Are we at the end of the message? 1933 <2> ; $LEAVE Z ;;AN000;; No, 1934 <2> JZ $MEN175 1935 <2> $MLL178: 1936 <2> ADD SI,WORD PTR [$M_SL + $M_S_SIZE] ;;AN000;; Next SUBLIST 1937 <2> ; $ENDLOOP ;;AN000;; Yes, 1938 <2> JMP SHORT $MDO175 1939 <2> $MEN175: 1940 <2> CMP byte [cs:$M_RT + $M_CLASS],UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1941 <2> ; $IF E ;;AN004;; Yes, 1942 <2> JNE $MIF180 1943 <2> INC DX ;;AN000;; Remember to display CR,LF 1944 <2> INC DX ;;AN000;; at the end of the message 1945 <2> DEC CX ;;AN000;; Adjust message length 1946 <2> DEC CX ;;AN000;; 1947 <2> DEC DI ;;AN000;; Adjust ending address of message 1948 <2> DEC DI ;;AN000;; 1949 <2> ; $ELSE ;;AN004;; No, 1950 <2> JMP SHORT $MEN180 1951 <2> $MIF180: 1952 <2> MOV DX,-1 ;;AN004;; Set special case 1953 <2> ; $ENDIF ;;AN004;; 1954 <2> $MEN180: 1955 <2> ; $ENDSRCH ;;AN000;; 1956 <2> $MSR175: 1957 <2> ; $ENDIF ;;AN000;; 1958 <2> $MIF174: 1959 <2> ; $ENDIF ;;AN000;; 1960 <2> $MIF173: 1961 <2> 1962 <2> ;; Prepare and display this part of message 1963 <2> 1964 <2> PUSH DI ;;AN000;; Save pointer to replace number 1965 <2> SUB DI,CX ;;AN000;; Determine beginning of string 1966 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) 1967 <2> POP DI ;;AN000;; Get back pointer to replace number 1968 <2> POP CX ;;AN000;; Clean up stack in case error 1969 <2> ; $LEAVE C,LONG ;;AN000;; Fail if carry was set 1970 <2> JNC $MXL3 1971 <2> JMP $MEN165 1972 <2> nop ; identicalise 1973 <2> $MXL3: 1974 <2> PUSH CX ;;AN000;; 1975 <2> 1976 <2> ;; Save and reset pointer registers 1977 <2> 1978 <2> MOV CX,DX ;;AN000;; Get the size of the rest of the message 1979 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? 1980 <2> ; $IF NE ;;AN000;; No, 1981 <2> JE $MIF187 1982 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1983 <2> ; $IF NZ ;;AN000;; No, 1984 <2> JZ $MIF188 1985 <2> DEC CX ;;AN000;; Decrement total size (%) 1986 <2> DEC CX ;;AN000;; Decrement total size (#) 1987 <2> INC DI ;;AN000;; Go past % 1988 <2> INC DI ;;AN000;; Go past replace number 1989 <2> ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) 1990 <2> JMP SHORT $MEN188 1991 <2> $MIF188: 1992 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 1993 <2> ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC 1994 <2> $MEN188: 1995 <2> ; $ELSE ;;AN000;; 1996 <2> JMP SHORT $MEN187 1997 <2> $MIF187: 1998 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1999 <2> ; $IF Z ;;AN004;; No, 2000 <2> JNZ $MIF192 2001 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 2002 <2> ; $ELSE ;;AN000;; No, 2003 <2> JMP SHORT $MEN192 2004 <2> $MIF192: 2005 <2> CMP CX,-1 ;;AN004;; Are we at the end of the message? 2006 <2> ; $IF Z ;;AN004;; No, 2007 <2> JNZ $MIF194 2008 <2> XOR CX,CX ;;AN004;; 2009 <2> ; $ENDIF ;;AN000;; 2010 <2> $MIF194: 2011 <2> OR DI,DI ;;AN004;; Turn ZF off 2012 <2> ; $ENDIF ;;AN000;; 2013 <2> $MEN192: 2014 <2> ; $ENDIF ;;AN000;; Note this will not leave because INC 2015 <2> $MEN187: 2016 <2> ; $LEAVE Z ;;AN000;; 2017 <2> JZ $MEN165 2018 <2> PUSH BP ;;AN000;; Save the replace count 2019 <2> PUSH DI ;;AN000;; Save location to complete message 2020 <2> PUSH ES ;;AN000;; 2021 <2> PUSH CX ;;AN000;; Save size of the rest of the message 2022 <2> XOR CX,CX ;;AN000;; Reset CX used for character count 2023 <2> 2024 <2> ;; Determine what action is required on parameter 2025 <2> 2026 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2027 <2> ; $IF E ;;AN000;; 2028 <2> JNE $MIF199 2029 <2> 2030 <2> %IF CHARmsg ;;AN000;; Was Char specified? 2031 <2> Char_Type equ Char_type ; NASM port equate 2032 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2033 <2> ; $IF Z ;;AN000;; 2034 <2> JNZ $MIF200 2035 <2> 2036 <2> ;; Character type requested 2037 <2> ;;AN000;; 2038 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2039 <2> CALL $M_CHAR_REPLACE ;;AN000;; 2040 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2041 <2> JMP SHORT $MEN200 2042 <2> $MIF200: 2043 <2> %ENDIF ;;AN000;; 2044 <2> %IF NUMmsg ;;AN000;; Was Nnmeric type specified? 2045 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2046 <2> ; $IF Z,OR ;;AN000;; 2047 <2> JZ $MLL202 2048 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2049 <2> ; $IF Z,OR ;;AN000;; 2050 <2> JZ $MLL202 2051 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Bin_Hex_Type & $M_TYPE_MASK ;;AN000;; 2052 <2> ; $IF Z ;;AN000;; 2053 <2> JNZ $MIF202 2054 <2> $MLL202: 2055 <2> 2056 <2> ;; Numeric type requested 2057 <2> 2058 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2059 <2> CALL $M_BIN2ASC_REPLACE ;;AN000;; 2060 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2061 <2> JMP SHORT $MEN202 2062 <2> $MIF202: 2063 <2> %ENDIF ;;AN000;; 2064 <2> %IF DATEmsg ;;AN000;; Was date specified? 2065 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Date_Type & $M_TYPE_MASK ;;AN000;; 2066 <2> ; $IF E ;;AN000;; 2067 <2> JNE $MIF204 2068 <2> 2069 <2> ;; Date type requested 2070 <2> 2071 <2> CALL $M_DATE_REPLACE ;;AN000;; 2072 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2073 <2> JMP SHORT $MEN204 2074 <2> $MIF204: 2075 <2> %ENDIF ;;AN000;; 2076 <2> %IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? 2077 <2> 2078 <2> ;; Time type requested (Default if we have not matched until here) 2079 <2> 2080 <2> CALL $M_TIME_REPLACE ;;AN000;; 2081 <2> %ENDIF ;;AN000;; 2082 <2> 2083 <2> %IF DATEmsg ;;AN000;; 2084 <2> ; $ENDIF ;;AN000;; 2085 <2> $MEN204: 2086 <2> %ENDIF ;;AN000;; 2087 <2> %IF NUMmsg ;;AN000;; 2088 <2> ; $ENDIF ;;AN000;; 2089 <2> $MEN202: 2090 <2> %ENDIF ;;AN000;; 2091 <2> %IF CHARmsg ;;AN000;; 2092 <2> ; $ENDIF ;;AN000;; 2093 <2> $MEN200: 2094 <2> %ENDIF ;;AN000;; 2095 <2> 2096 <2> %IF $M_REPLACE ;;AN000;; 2097 <2> ;; With the replace information of the Stack, display the replaceable field 2098 <2> 2099 <2> CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace 2100 <2> %ENDIF ;;AN000;; 2101 <2> ;; None of the above - Extended/Parse replace 2102 <2> ; $ELSE ;;AN000;; 2103 <2> JMP SHORT $MEN199 2104 <2> $MIF199: 2105 <2> %IFN COMR 2106 <2> CALL $M_EXT_PAR_REPLACE ;;AN000;; 2107 <2> %ENDIF 2108 <2> ; $ENDIF ;;AN000;; 2109 <2> $MEN199: 2110 <2> 2111 <2> ;; We must go back and complete the message after the replacable parameter if there is any left 2112 <2> 2113 <2> ; $IF NC ;;AN000;; IF there was an error displaying then EXIT 2114 <2> JC $MIF211 2115 <2> POP CX ;;AN000;; Get size of the rest of the message 2116 <2> POP ES ;;AN000;; Get address of the rest of the message 2117 <2> POP DI ;;AN000;; 2118 <2> POP BP ;;AN000;; Get replacment count 2119 <2> POP SI ;;AN000;; ELSE get address of first sublist structure 2120 <2> ; $ELSE ;;AN000;; 2121 <2> JMP SHORT $MEN211 2122 <2> $MIF211: 2123 <2> ADD SP,10 ;;AN000;; Clean up stack if error 2124 <2> STC ;;AN000;; 2125 <2> ; $ENDIF ;;AN000;; 2126 <2> $MEN211: 2127 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2128 <2> ; $ENDDO NE,OR ;;AN000;; 2129 <2> JNE $MLL214 2130 <2> ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message 2131 <2> JC $MXL4 2132 <2> JMP $MDO165 2133 <2> $MXL4: 2134 <2> $MLL214: 2135 <2> $MEN165: 2136 <2> ;; IF there was an error displaying then EXIT 2137 <2> MOV word [cs:$M_RT + $M_MSG_NUM],0 ;;AN000;; Reset message number to null 2138 <2> RET ;;AN000;; Return 2139 <2> ;; 2140 <2> $M_DISPLAY_MESSAGE ENDP ;;AN000;; 2141 <2> %IFN COMR 2142 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2143 <2> ;; 2144 <2> ;; PROC NAME: $M_EXT_PAR_REPLACE 2145 <2> ;; 2146 <2> ;; FUNCTION: 2147 <2> ;; INPUTS: 2148 <2> ;; OUPUTS: 2149 <2> ;; 2150 <2> ;; REGS USED: 2151 <2> ;; 2152 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2153 <2> ;; 2154 <2> $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; 2155 <2> ;; 2156 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2157 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN000;; Prepare for get binary value (LOW) 2158 <2> MOV word [cs:$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2159 <2> ;; 2160 <2> CALL $M_CONVERT2ASC ;;AN000;; 2161 <2> ;; 2162 <2> ; $DO ;;AN000;; 2163 <2> $MDO215: 2164 <2> POP AX ;;AN000;; Get character in register 2165 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2166 <2> INC BX ;;AN000;; Increase buffer count 2167 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2168 <2> ; $IF E ;;AN000;; Yes, 2169 <2> JNE $MIF216 2170 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2171 <2> ; $ENDIF ;;AN000;; 2172 <2> $MIF216: 2173 <2> DEC CL ;;AN000;; Have we completed replace? 2174 <2> ; $ENDDO Z ;;AN000;; 2175 <2> JNZ $MDO215 2176 <2> ;; 2177 <2> MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer 2178 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],AX ;;AN000;; Move char into the buffer 2179 <2> INC BX ;;AN000;; Increase buffer count 2180 <2> INC BX ;;AN000;; Increase buffer count 2181 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2182 <2> RET ;;AN000:: 2183 <2> ;; 2184 <2> $M_EXT_PAR_REPLACE ENDP ;;AN000;; 2185 <2> ;; 2186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2187 <2> %ENDIF 2188 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 2189 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 2190 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2191 <2> ;; 2192 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 2193 <2> ;; 2194 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 2195 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 2196 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2197 <2> ;; IF CX > 1 THEN DS:SI points to the specified message 2198 <2> ;; REGS CHANGED: ES,DI,CX,DS,SI 2199 <2> ;; 2200 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2201 <2> ;; 2202 <2> %IF FARmsg ;;AN000;; 2203 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 2204 <2> %ELSE ;;AN000;; 2205 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 2206 <2> %ENDIF ;;AN000;; 2207 <2> ;; 2208 <2> PUSH SI ;;AN000;; 2209 <2> PUSH BX ;;AN000;; 2210 <2> XOR SI,SI ;;AN000;; Use SI as an index 2211 <2> XOR CX,CX ;;AN000;; Use CX as an size 2212 <2> ; $DO ;;AN000;; 2213 <2> $MDO219: 2214 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 2215 <2> ; $IF E ;;AN000;; Yes, 2216 <2> JNE $MIF220 2217 <2> %IF FARmsg ;;AN000;; 2218 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2219 <2> MOV BX,ES ;;AN000; 2220 <2> %ELSE ;;AN000;; 2221 <2> MOV DI,WORD PTR [cs:$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2222 <2> MOV BX,DI ;;AN000; 2223 <2> %ENDIF ;;AN000;; 2224 <2> ; $ELSE ;;AN000;; No, 2225 <2> JMP SHORT $MEN220 2226 <2> $MIF220: 2227 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 2228 <2> ; $IF NE ;;AN000;; Yes, 2229 <2> JE $MIF222 2230 <2> LES DI,[cs:$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 2231 <2> MOV BX,ES ;;AN000; 2232 <2> ; $ELSE ;;AN000;; No, extended errors were specified 2233 <2> JMP SHORT $MEN222 2234 <2> $MIF222: 2235 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 2236 <2> ; $IF AE,AND ;;AN000;; 2237 <2> JNAE $MIF224 2238 <2> CMP AX,$M_CRIT_HI ;;AN000;; 2239 <2> ; $IF BE ;;AN000;; Yes, 2240 <2> JNBE $MIF224 2241 <2> LES DI,[cs:$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 2242 <2> MOV BX,ES ;;AN000; 2243 <2> ; $ELSE ;;AN000;; 2244 <2> JMP SHORT $MEN224 2245 <2> $MIF224: 2246 <2> LES DI,[cs:$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 2247 <2> MOV BX,ES ;;AN000; 2248 <2> ; $ENDIF ;;AN000;; 2249 <2> $MEN224: 2250 <2> ; $ENDIF ;;AN000;; 2251 <2> $MEN222: 2252 <2> ; $ENDIF ;;AN000;; 2253 <2> $MEN220: 2254 <2> ;; 2255 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 2256 <2> ; $IF E ;;AN000;; Yes, 2257 <2> JNE $MIF229 2258 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 2259 <2> ; $IF E ;;AN000;; Yes, 2260 <2> JNE $MIF230 2261 <2> STC ;;AN000;; Set the carry flag 2262 <2> ; $ELSE ;;AN000;; No, 2263 <2> JMP SHORT $MEN230 2264 <2> $MIF230: 2265 <2> MOV [cs:$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 2266 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 2267 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 2268 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 2269 <2> CLC ;;AN000;; 2270 <2> ; $ENDIF ;;AN000;; No, 2271 <2> $MEN230: 2272 <2> ; $ELSE ;;AN000;; 2273 <2> JMP SHORT $MEN229 2274 <2> $MIF229: 2275 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 2276 <2> ; $IF NE ;;AN001;; Yes, 2277 <2> JE $MIF234 2278 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 2279 <2> ; $ENDIF ;;AN000;; 2280 <2> $MIF234: 2281 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 2282 <2> CLC ;;AN000;; 2283 <2> ; $ENDIF ;;AN000;; 2284 <2> $MEN229: 2285 <2> ; $LEAVE C ;;AN000;; 2286 <2> JC $MEN219 2287 <2> OR CX,CX ;;AN000;; Was the message found? 2288 <2> ; $ENDDO NZ,LONG ;;AN000;; 2289 <2> JNZ $MXL5 2290 <2> JMP $MDO219 2291 <2> $MXL5: 2292 <2> $MEN219: 2293 <2> 2294 <2> PUSHF ;;AN006;; Save the flag state 2295 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 2296 <2> ; $IF E ;;AN006;; Yes, 2297 <2> JNE $MIF239 2298 <2> PUSH DX ;;AN006;; Save all needed registers 2299 <2> PUSH BP ;;AN006;; 2300 <2> PUSH CX ;;AN006;; 2301 <2> PUSH ES ;;AN006;; 2302 <2> PUSH DI ;;AN006;; 2303 <2> PUSH AX ;;AN006;; 2304 <2> 2305 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 2306 <2> INT 2FH ;;AN006;; 2307 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 2308 <2> POP AX ;;AN006;; Restore msg number 2309 <2> ; $IF E ;;AN006;; Yes, 2310 <2> JNE $MIF240 2311 <2> MOV BX,AX ;;AN006;; BX is the extended error number 2312 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 2313 <2> INT 2FH ;;AN006;; Call IFSFUNC 2314 <2> ; $ELSE ;;AN006;; No, 2315 <2> JMP SHORT $MEN240 2316 <2> $MIF240: 2317 <2> STC ;;AN006;; Carry conditon 2318 <2> ; $ENDIF ;;AN006;; 2319 <2> $MEN240: 2320 <2> 2321 <2> ; $IF C ;;AN006;; Was there an update? 2322 <2> JNC $MIF243 2323 <2> POP DI ;;AN006;; No, 2324 <2> POP ES ;;AN006;; Restore old pointer 2325 <2> POP CX ;;AN006;; 2326 <2> ; $ELSE ;;AN006;; Yes 2327 <2> JMP SHORT $MEN243 2328 <2> $MIF243: 2329 <2> ADD SP,6 ;;AN006;; Throw away old pointer 2330 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 2331 <2> ; $ENDIF ;;AN006;; 2332 <2> $MEN243: 2333 <2> POP BP ;;AN006;; Restore other Regs 2334 <2> POP DX ;;AN006;; 2335 <2> ; $ENDIF ;;AN006;; 2336 <2> $MIF239: 2337 <2> $M_POPF ;;AN006;; Restore the flag state 2338 <2> 2339 <2> POP BX ;;AN000;; 2340 <2> POP SI ;;AN000;; 2341 <2> RET ;;AN000;; Return ES:DI pointing to the message 2342 <2> ;; 2343 <2> $M_GET_MSG_ADDRESS ENDP ;; 2344 <2> ;; 2345 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 2346 <2> ;; 2347 <2> PUSH DI ;;AN006;; Save position 2348 <2> PUSH AX ;;AN006;; 2349 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 2350 <2> XOR AL,AL ;;AN006;; Prepare compare register 2351 <2> REPNE SCASB ;;AN006;; Scan for zero 2352 <2> NOT CX ;;AN006;; Change decrement into number 2353 <2> DEC CX ;;AN006;; Don't include the zero 2354 <2> POP AX ;;AN006;; 2355 <2> POP DI ;;AN006;; Restore position 2356 <2> RET ;;AN006;; 2357 <2> ;; 2358 <2> $M_SET_LEN_IN_CX ENDP ;; 2359 <2> ;; 2360 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2361 <2> ;; 2362 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 2363 <2> ;; 2364 <2> ;; FUNCTION: To scan thru message headers until message is found 2365 <2> ;; INPUTS: ES:DI points to beginning of msg headers 2366 <2> ;; CX contains the number of messages in class 2367 <2> ;; DH contains the message class 2368 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2369 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 2370 <2> ;; 2371 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2372 <2> ;; 2373 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 2374 <2> ;; 2375 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 2376 <2> ; $IF E,AND ;;AN004;; Yes, 2377 <2> JNE $MIF247 2378 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 2379 <2> ; $IF NE ;;AN004;; Yes, 2380 <2> JE $MIF247 2381 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 2382 <2> ; $IF E ;;AN004;; . . . and . . . 2383 <2> JNE $MIF248 2384 <2> PUSH AX ;;AN004;; Reset the special message number 2385 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 2386 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2387 <2> POP AX ;;AN004;; Reset the special message number 2388 <2> ; $ELSE ;;AN004;; Get the old message number 2389 <2> JMP SHORT $MEN248 2390 <2> $MIF248: 2391 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2392 <2> ; $ENDIF ;;AN004;; Get the old message number 2393 <2> $MEN248: 2394 <2> ; $ELSE ;;AN004;; 2395 <2> JMP SHORT $MEN247 2396 <2> $MIF247: 2397 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 2398 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2399 <2> ; $IF NE ;;AN001;; 2400 <2> JE $MIF252 2401 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 2402 <2> ; $ELSE ;;AN001;; 2403 <2> JMP SHORT $MEN252 2404 <2> $MIF252: 2405 <2> %IF FARmsg ;;AN001;; 2406 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2407 <2> %ELSE 2408 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2409 <2> %ENDIF 2410 <2> ; $IF E ;;AN002;; pointer (hopefully) 2411 <2> JNE $MIF254 2412 <2> %IF FARmsg ;;AN001;; 2413 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2414 <2> %ELSE 2415 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2416 <2> %ENDIF 2417 <2> ; $ENDIF ;;AN002;; go on to the next class 2418 <2> $MIF254: 2419 <2> ; $ENDIF ;;AN001;; 2420 <2> $MEN252: 2421 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 2422 <2> STC ;;AN004;; Flag that we haven't found anything yet 2423 <2> ; $ENDIF ;;AN004;; 2424 <2> $MEN247: 2425 <2> 2426 <2> ; $IF C ;;AN004;; Have we found anything yet? 2427 <2> JNC $MIF258 2428 <2> CLC ;;AN004;; No, reset carry 2429 <2> ; $SEARCH ;;AN000;; 2430 <2> $MDO259: 2431 <2> OR CX,CX ;;AN000;; Do we have any to check? 2432 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2433 <2> JZ $MEN259 2434 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2435 <2> ; $IF NE ;;AN001;; 2436 <2> JE $MIF261 2437 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 2438 <2> ; $ELSE ;;AN001;; 2439 <2> JMP SHORT $MEN261 2440 <2> $MIF261: 2441 <2> %IF FARmsg ;;AN001;; 2442 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 2443 <2> %ELSE 2444 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 2445 <2> %ENDIF 2446 <2> ; $ENDIF 2447 <2> $MEN261: 2448 <2> ; $EXITIF E ;;AN000;; 2449 <2> JNE $MIF259 2450 <2> ; $ORELSE ;;AN000; 2451 <2> JMP SHORT $MSR259 2452 <2> $MIF259: 2453 <2> DEC CX ;;AN000;; No, well do we have more to check? 2454 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2455 <2> JZ $MEN259 2456 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 2457 <2> ; $ENDLOOP ;;AN000;; 2458 <2> JMP SHORT $MDO259 2459 <2> $MEN259: 2460 <2> STC ;;AN000;; 2461 <2> ; $ENDSRCH ;;AN000;; Check next message 2462 <2> $MSR259: 2463 <2> ; $IF NC ;;AN000;; Did we find the message? 2464 <2> JC $MIF269 2465 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 2466 <2> CLC ;;AN001;; 2467 <2> ; $IF E ;;AN001;; 2468 <2> JNE $MIF270 2469 <2> %IF FARmsg ;;AN001;; 2470 <2> %ELSE ;;AN000;; 2471 <2> PUSH CS ;;AN000;; 2472 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 2473 <2> %ENDIF 2474 <2> ; $ENDIF ;;AN001;; 2475 <2> $MIF270: 2476 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 2477 <2> ; $ENDIF ;;AN004;; 2478 <2> $MIF269: 2479 <2> ; $ENDIF ;;AN004;; 2480 <2> $MIF258: 2481 <2> ;; Yes, great we can return with CX > 0 2482 <2> 2483 <2> ; $IF NC ;;AN000;; Did we find the message? 2484 <2> JC $MIF274 2485 <2> XOR CH,CH ;;AN000;; 2486 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 2487 <2> INC DI ;;AN000;; Increment past length 2488 <2> ; $ENDIF ;;AN004;; 2489 <2> $MIF274: 2490 <2> 2491 <2> MOV byte [cs:$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 2492 <2> RET ;;AN000;; Return 2493 <2> ;; 2494 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 2495 <2> ;; 2496 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2497 <2> %ENDIF ;;AN000;; END of include of common subroutines 2498 <2> ; 2499 <2> %IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms 2500 <2> %iassign $M_REPLACE FALSE ;;AN000;; Tell the assembler we did 2501 <2> ;; 2502 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2503 <2> $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; 2504 <2> ;; 2505 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2506 <2> %IFN COMR 2507 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) 2508 <2> ; $IF E ;;AN000;; Yes, 2509 <2> JNE $MIF276 2510 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE_HYP ;;AN000;; Move in a " -" 2511 <2> INC BX ;;AN000;; Increment count 2512 <2> INC BX ;;AN000;; Increment count 2513 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE ;;AN000;; Move in a " " 2514 <2> INC BX ;;AN000;; Increment count 2515 <2> CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case 2516 <2> ; $ENDIF ;;AN000;; If it fails we will catch it later 2517 <2> $MIF276: 2518 <2> %ENDIF 2519 <2> 2520 <2> POP BP ;;AN000;; Remember the return address 2521 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2522 <2> XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack 2523 <2> 2524 <2> MOV [cs:$M_RT + $M_SIZE],CL ;;AN000;; Save size to later clear stack 2525 <2> MOV AL,BYTE PTR [$M_SL + $M_S_MINW] ;;AN000;; Get the minimum width 2526 <2> ;; 2527 <2> CMP AL,CL ;;AN000;; Do we need pad chars added? 2528 <2> ; $IF A ;;AN000;; Yes, 2529 <2> JNA $MIF278 2530 <2> SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. 2531 <2> MOV DH,AL ;;AN000;; Save the number of pad characters 2532 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be right aligned? 2533 <2> ; $IF NZ ;;AN000;; Yes, 2534 <2> JZ $MIF279 2535 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2536 <2> $MDO280: 2537 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2538 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2539 <2> INC BX ;;AN000;; 2540 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2541 <2> ; $IF E ;;AN000;; Yes, 2542 <2> JNE $MIF281 2543 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2544 <2> ; $ENDIF ;;AN000;; 2545 <2> $MIF281: 2546 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2547 <2> ; $ENDDO Z ;;AN000;; No, next pad character 2548 <2> JNZ $MDO280 2549 <2> ; $ENDIF ;;AN000;; 2550 <2> $MIF279: 2551 <2> ; $ENDIF ;;AN000;; Yes, 2552 <2> $MIF278: 2553 <2> ;; 2554 <2> CMP BYTE [$M_SL + $M_S_MAXW],$M_UNLIM_W ;;AN000;; Is maximum width unlimited? 2555 <2> ; $IF NE ;;AN000;; 2556 <2> JE $MIF286 2557 <2> CMP BYTE PTR [$M_SL + $M_S_MAXW],CL ;;AN000;; Will we exceed maximum width? 2558 <2> ; $IF B ;;AN000;; Yes, 2559 <2> JNB $MIF287 2560 <2> SUB CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Calculate how many extra chars 2561 <2> MOV DL,CL ;;AN000;; Remember how many chars to pop off 2562 <2> MOV CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Set new string length 2563 <2> ; $ENDIF ;;AN000;; 2564 <2> $MIF287: 2565 <2> ; $ENDIF ;;AN000;; 2566 <2> $MIF286: 2567 <2> OR CX,CX ;;AN000;; 2568 <2> ; $IF NZ ;;AN000;; 2569 <2> JZ $MIF290 2570 <2> ; $DO ;;AN000;; Begin filling buffer with string 2571 <2> $MDO291: 2572 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2573 <2> ; $IF Z,AND ;;AN000;; 2574 <2> JNZ $MIF292 2575 <2> Char_field_ASCIIZ equ Char_Field_ASCIIZ ; NASM port equate 2576 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ; Is this replace a ASCIIZ string? 2577 <2> ; $IF NZ ;;AN000;; Yes, 2578 <2> JZ $MIF292 2579 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get first character from string 2580 <2> INC DI ;;AN000;; Next character in string 2581 <2> ; $ELSE ;;AN000;; No, 2582 <2> JMP SHORT $MEN292 2583 <2> $MIF292: 2584 <2> POP AX ;;AN000;; Get character in register 2585 <2> ; $ENDIF ;;AN000;; 2586 <2> $MEN292: 2587 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2588 <2> INC BX ;;AN000;; Increase buffer count 2589 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2590 <2> ; $IF E ;;AN000;; Yes, 2591 <2> JNE $MIF295 2592 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2593 <2> ; $ENDIF ;;AN000;; 2594 <2> $MIF295: 2595 <2> DEC CL ;;AN000;; Have we completed replace? 2596 <2> ; $ENDDO Z ;;AN000;; Test again 2597 <2> JNZ $MDO291 2598 <2> ; $ENDIF ;;AN000;; 2599 <2> $MIF290: 2600 <2> ;; 2601 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be left aligned? 2602 <2> ; $IF Z ;;AN000;; Yes, 2603 <2> JNZ $MIF299 2604 <2> OR DH,DH ;;AN000;; Do we need pad chars added? 2605 <2> ; $IF NZ ;;AN000;; Yes, 2606 <2> JZ $MIF300 2607 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2608 <2> $MDO301: 2609 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2610 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2611 <2> INC BX ;;AN000;; 2612 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2613 <2> ; $IF E ;;AN000;; Yes, 2614 <2> JNE $MIF302 2615 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2616 <2> ; $ENDIF ;;AN000;; 2617 <2> $MIF302: 2618 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2619 <2> ; $ENDDO Z ;;AN000;; Test again 2620 <2> JNZ $MDO301 2621 <2> ; $ENDIF ;;AN000;; 2622 <2> $MIF300: 2623 <2> ; $ENDIF ;;AN000;; 2624 <2> $MIF299: 2625 <2> ;; 2626 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2627 <2> ; $IF Z,AND ;;AN000;; 2628 <2> JNZ $MIF307 2629 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? 2630 <2> ; $IF NZ ;;AN000;; Yes, 2631 <2> JZ $MIF307 2632 <2> ; $ELSE ;;AN000;; 2633 <2> JMP SHORT $MEN307 2634 <2> $MIF307: 2635 <2> OR DL,DL ;;AN000;; 2636 <2> ; $IF NE ;;AN000;; 2637 <2> JE $MIF309 2638 <2> ; $DO ;;AN000;; 2639 <2> $MDO310: 2640 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable 2641 <2> DEC DL ;;AN000;; Are we done? 2642 <2> ; $ENDDO Z ;;AN000;; 2643 <2> JNZ $MDO310 2644 <2> ; $ENDIF ;;AN000;; 2645 <2> $MIF309: 2646 <2> ; $ENDIF ;;AN000;; 2647 <2> $MEN307: 2648 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time 2649 <2> PUSH BP ;;AN000;; Restore the return address 2650 <2> ;; 2651 <2> RET ;;AN000;; 2652 <2> ;; 2653 <2> $M_DISPLAY_REPLACE ENDP ;;AN000;; 2654 <2> ;; 2655 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2656 <2> ;; 2657 <2> ;; PROC NAME: $M_FLUSH_BUFFER 2658 <2> ;; 2659 <2> ;; FUNCTION: Display the contents of the temporary buffer 2660 <2> ;; INPUTS: DI contains the number of bytes to display 2661 <2> ;; OUTPUTS: BX reset to zero 2662 <2> ;; 2663 <2> ;; REGS USED: 2664 <2> ;; 2665 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2666 <2> ;; 2667 <2> $M_FLUSH_BUF PROC NEAR ;;AN000;; 2668 <2> ;; 2669 <2> PUSH CX ;;AN000;; Save changed regs 2670 <2> PUSH ES ;;AN000;; 2671 <2> PUSH DI ;;AN000;; 2672 <2> PUSH DS ;;AN000;; Set ES pointing to buffer 2673 <2> POP ES ;;AN000;; 2674 <2> ;; 2675 <2> MOV CX,BX ;;AN000;; Set number of bytes to display 2676 <2> XOR BX,BX ;;AN000;; Reset buffer counter 2677 <2> LEA DI,[$M_RT + $M_TEMP_BUF] ;;AN000;; Reset buffer location pointer 2678 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer 2679 <2> ;; 2680 <2> ; $IF NC ;;AN000;; Error? 2681 <2> JC $MIF314 2682 <2> POP DI ;;AN000;; No, Restore changed regs 2683 <2> POP ES ;;AN000;; 2684 <2> POP CX ;;AN000;; 2685 <2> ; $ELSE ;;AN000;; Yes, 2686 <2> JMP SHORT $MEN314 2687 <2> $MIF314: 2688 <2> ADD SP,6 ;;AN000;; Fix stack 2689 <2> STC ;;AN000;; 2690 <2> ; $ENDIF ;;AN000;; Error? 2691 <2> $MEN314: 2692 <2> ;; 2693 <2> RET ;;AN000;; Return 2694 <2> ;; 2695 <2> $M_FLUSH_BUF ENDP ;;AN000;; 2696 <2> ;; 2697 <2> ;; 2698 <2> %IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? 2699 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2700 <2> %iassign $M_CHAR_ONLY TRUE ;;AN000;; replacement code later 2701 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2702 <2> ;; 2703 <2> ;; PROC NAME: $M_CHAR_REPLACE 2704 <2> ;; 2705 <2> ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace 2706 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2707 <2> ;; ES:DI contains the VALUE from SUBLIST 2708 <2> ;; OUTPUTS: CX contains number of characters on stack 2709 <2> ;; Top of stack --> Last character 2710 <2> ;; . . . 2711 <2> ;; Bot of stack --> First character 2712 <2> ;; 2713 <2> ;; OTHER REGS Revised: AX 2714 <2> ;; 2715 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2716 <2> ;; 2717 <2> $M_CHAR_REPLACE PROC NEAR ;;AN000;; 2718 <2> ;; 2719 <2> POP BP ;;AN000;; Save return address 2720 <2> TEST byte [$M_SL + $M_S_FLAG],~ Char_Field_Char & $M_SIZE_MASK ;;AN000;; Was Character specified? 2721 <2> ; $IF Z ;;AN000;; Yes, 2722 <2> JNZ $MIF317 2723 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2724 <2> PUSH AX ;;AN000;; Put it on the stack 2725 <2> INC CX ;;AN000;; Increase the count 2726 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 2727 <2> ; $IF C ;;AN000;; Yes, 2728 <2> JNC $MIF318 2729 <2> MOV AL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 2730 <2> PUSH AX ;;AN000;; Put it on the stack 2731 <2> CLC ;;AN000;; Clear the carry 2732 <2> ; $ENDIF ;;AN000;; 2733 <2> $MIF318: 2734 <2> ; $ELSE ;;AN000;; No, it was an ASCIIZ string 2735 <2> JMP SHORT $MEN317 2736 <2> $MIF317: 2737 <2> ; $DO ;;AN000;; 2738 <2> $MDO321: 2739 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2740 <2> OR AL,AL ;;AN000;; Is it the NULL? 2741 <2> ; $LEAVE Z ;;AN000;; No, 2742 <2> JZ $MEN321 2743 <2> INC DI ;;AN000;; Next character 2744 <2> INC CX ;;AN000;; Increment the count 2745 <2> ; $ENDDO ;;AN000;; Yes, 2746 <2> JMP SHORT $MDO321 2747 <2> $MEN321: 2748 <2> SUB DI,CX ;;AN000;; Set SI at the beginning of the string 2749 <2> ; $ENDIF ;;AN000;; 2750 <2> $MEN317: 2751 <2> ;;AN000;; 2752 <2> PUSH BP ;;AN000;; Restore return address 2753 <2> RET ;;AN000;; Return 2754 <2> ;; 2755 <2> $M_CHAR_REPLACE ENDP ;;AN000;; 2756 <2> ;; 2757 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2758 <2> %ENDIF ;;AN000;; END of include of CHAR replace code 2759 <2> ; 2760 <2> %IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? 2761 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2762 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2763 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2764 <2> ;; 2765 <2> ;; PROC NAME: $M_BIN2ASC_REPLACE 2766 <2> ;; 2767 <2> ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string 2768 <2> ;; and prepare to display 2769 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2770 <2> ;; ES:DI contains the VALUE from SUBLIST 2771 <2> ;; OUTPUTS: CX contains number of characters on stack 2772 <2> ;; Top of stack --> Last character 2773 <2> ;; . . . 2774 <2> ;; Bot of stack --> First character 2775 <2> ;; OTHER REGS Revised: BX,DX,AX 2776 <2> ;; 2777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2778 <2> ;; 2779 <2> $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; 2780 <2> ;; 2781 <2> POP BP ;;AN000;; Save return address 2782 <2> ;; 2783 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2784 <2> XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) 2785 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE16 ;;AN000;; Set default divisor 2786 <2> XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) 2787 <2> %IFN COMR 2788 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_BYTE & $M_SIZE_MASK ;;AN000;; Was BYTE specified? 2789 <2> ; $IF Z ;;AN000;; 2790 <2> JNZ $MIF325 2791 <2> MOV AL, BYTE PTR [ES:DI] ;;AN000;; Setup byte in AL 2792 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2793 <2> ; $IF Z ;;AN000;; 2794 <2> JNZ $MIF326 2795 <2> TEST AL,10000000b ;;AN000;; Is this number negative? 2796 <2> ; $IF NZ ;;AN000;; Yes, 2797 <2> JZ $MIF327 2798 <2> INC BX ;;AN000;; Remember that it was negative 2799 <2> AND AL,01111111b ;;AN000;; Make it positive 2800 <2> ; $ENDIF ;;AN000;; 2801 <2> $MIF327: 2802 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2803 <2> ; $ENDIF ;;AN000;; 2804 <2> $MIF326: 2805 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2806 <2> ; $IF Z ;;AN000;; 2807 <2> JNZ $MIF330 2808 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2809 <2> ; $ENDIF ;;AN000;; 2810 <2> $MIF330: 2811 <2> ; $ELSE ;;AN000;; 2812 <2> JMP SHORT $MEN325 2813 <2> $MIF325: 2814 <2> %ENDIF 2815 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_WORD & $M_SIZE_MASK ;;AN000;; Was WORD specified? 2816 <2> ; $IF Z ;;AN000;; 2817 <2> JNZ $MIF333 2818 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup byte in AL 2819 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;; AN000;; Was Signed binary specified? 2820 <2> ; $IF Z ;;AN000;; 2821 <2> JNZ $MIF334 2822 <2> TEST AH,10000000b ;;AN000;; Is this number negative? 2823 <2> ; $IF NZ ;;AN000;; Yes, 2824 <2> JZ $MIF335 2825 <2> INC BX ;;AN000;; Remember that it was negative 2826 <2> AND AH,01111111b ;;AN000;; Make it positive 2827 <2> ; $ENDIF ;;AN000;; 2828 <2> $MIF335: 2829 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2830 <2> ; $ENDIF ;;AN000;; 2831 <2> $MIF334: 2832 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2833 <2> ; $IF Z ;;AN000;; 2834 <2> JNZ $MIF338 2835 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2836 <2> ; $ENDIF ;;AN000;; 2837 <2> $MIF338: 2838 <2> ; $ELSE ;;AN000;; 2839 <2> JMP SHORT $MEN333 2840 <2> $MIF333: 2841 <2> %IFN COMR 2842 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup Double word in DX:AX 2843 <2> MOV DX, WORD PTR [ES:DI + 2] ;;AN000;; 2844 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2845 <2> ; $IF Z ;;AN000;; 2846 <2> JNZ $MIF341 2847 <2> TEST DH,10000000b ;;AN000;; Is this number negative? 2848 <2> ; $IF NZ ;;AN000;; Yes, 2849 <2> JZ $MIF342 2850 <2> INC BX ;;AN000;; Remember that it was negative 2851 <2> AND DH,01111111b ;;AN000;; Make it positive 2852 <2> ; $ENDIF ;;AN000;; 2853 <2> $MIF342: 2854 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2855 <2> ; $ENDIF ;;AN000;; 2856 <2> $MIF341: 2857 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2858 <2> ; $IF Z ;;AN000;; 2859 <2> JNZ $MIF345 2860 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2861 <2> ; $ENDIF ;;AN000;; 2862 <2> $MIF345: 2863 <2> %ENDIF 2864 <2> ; $ENDIF ;;AN000;; 2865 <2> $MEN333: 2866 <2> ; $ENDIF ;;AN000;; 2867 <2> $MEN325: 2868 <2> ;; 2869 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string 2870 <2> %IFN COMR 2871 <2> OR BX,BX ;;AN000;; 2872 <2> ; $IF NZ ;;AN000;; Was number negative? 2873 <2> JZ $MIF349 2874 <2> XOR DX,DX ;;AN000;; Yes, 2875 <2> MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number 2876 <2> PUSH DX ;;AN000;; 2877 <2> ; $ENDIF ;;AN000;; No, 2878 <2> $MIF349: 2879 <2> %ENDIF 2880 <2> ;; 2881 <2> PUSH BP ;;AN000;; Restore return address 2882 <2> RET ;;AN000;; Return 2883 <2> ;; 2884 <2> $M_BIN2ASC_REPLACE ENDP ;;AN000;; 2885 <2> ;; 2886 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2887 <2> %ENDIF ;;AN000;; END of include of NUM replace code 2888 <2> ; 2889 <2> %IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? 2890 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2891 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2892 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2893 <2> ;; 2894 <2> ;; PROC NAME: $M_DATE_REPLACE 2895 <2> ;; 2896 <2> ;; FUNCTION: Convert a date to a decimal ASCII string using current 2897 <2> ;; country format and prepare to display 2898 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2899 <2> ;; ES:DI points at VALUE from SUBLIST 2900 <2> ;; OUTPUTS: CX contains number of characters on stack 2901 <2> ;; Top of stack --> Last character 2902 <2> ;; . . . 2903 <2> ;; Bot of stack --> First character 2904 <2> ;; OTHER REGS Revised: DX, AX 2905 <2> ;; 2906 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2907 <2> ;; 2908 <2> $M_DATE_REPLACE PROC NEAR ;;AN000;; 2909 <2> ;; 2910 <2> POP BP ;;AN000;; Save return address 2911 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2912 <2> CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT 2913 <2> ;;AN000;; All O.K.? 2914 <2> XOR DX,DX ;;AN000;; Reset DX value 2915 <2> XOR AX,AX ;;AN000;; Reset AX value 2916 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],0 ;;AN000;; USA Date Format 2917 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2918 <2> JNE $MIF351 2919 <2> CALL $M_YEAR ;;AN000;; Get Year 2920 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2921 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2922 <2> INC CX ;;AN000;; Increment count 2923 <2> XOR AX,AX ;;AN000;; Reset AX value 2924 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2925 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2926 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2927 <2> INC CX ;;AN000;; Increment count 2928 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2929 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2930 <2> ; $ENDIF ;;AN000;; 2931 <2> $MIF351: 2932 <2> ;; 2933 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],1 ;;AN000;; EUROPE Date Format 2934 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2935 <2> JNE $MIF353 2936 <2> CALL $M_YEAR ;;AN000;; Get Year 2937 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2938 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2939 <2> INC CX ;;AN000;; 2940 <2> XOR AX,AX ;;AN000;; Reset AX 2941 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2942 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2943 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2944 <2> INC CX ;;AN000;; 2945 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2946 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2947 <2> ; $ENDIF ;;AN000;; 2948 <2> $MIF353: 2949 <2> ;; 2950 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],2 ;;AN000;; JAPAN Date Format 2951 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2952 <2> JNE $MIF355 2953 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2954 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2955 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2956 <2> INC CX ;;AN000;; 2957 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2958 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2959 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2960 <2> INC CX ;;AN000;; 2961 <2> CALL $M_YEAR ;;AN000;; Get Year 2962 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2963 <2> ; $ENDIF ;;AN000;; 2964 <2> $MIF355: 2965 <2> ;; 2966 <2> PUSH BP ;;AN000;; Restore return address 2967 <2> RET ;;AN000;; Return 2968 <2> ;; 2969 <2> $M_DATE_REPLACE ENDP ;;AN000;; 2970 <2> ;; 2971 <2> $M_GET_DATE PROC NEAR ;;AN000;; 2972 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 2973 <2> MOV AL,0 ;;AN000;; Get current country info 2974 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 2975 <2> INT 21H ;;AN000;; 2976 <2> ; $IF C ;;AN000;; No, 2977 <2> JNC $MIF357 2978 <2> MOV WORD [$M_RT + $M_DATE_FORMAT],$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) 2979 <2> MOV BYTE [$M_RT + $M_DATE_SEPARA],$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) 2980 <2> ; $ENDIF ;;AN000;; 2981 <2> $MIF357: 2982 <2> RET ;;AN000;; 2983 <2> $M_GET_DATE ENDP ;;AN000;; 2984 <2> ;; 2985 <2> $M_YEAR PROC NEAR ;;AN000;; 2986 <2> MOV AX,WORD PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Year 2987 <2> TEST byte [$M_SL + $M_S_FLAG],Date_MDY_4 & $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? 2988 <2> ; $IF Z ;;AN000;; 2989 <2> JNZ $MIF359 2990 <2> CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year 2991 <2> ; $IF A ;;AN000;; 2992 <2> JNA $MIF360 2993 <2> MOV AX,$M_MAX_2_YEAR ;;AN000;; 2994 <2> ; $ENDIF ;;AN000;; 2995 <2> $MIF360: 2996 <2> ; $ENDIF ;;AN000;; 2997 <2> $MIF359: 2998 <2> RET ;;AN000;; 2999 <2> $M_YEAR ENDP ;;AN000;; 3000 <2> ;; 3001 <2> $M_CONVERTDATE PROC NEAR ;;AN000;; 3002 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3003 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3004 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3005 <2> DEC CX ;;AN000;; Test if size only grew by 1 3006 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3007 <2> ; $IF E ;;AN000;; Yes, 3008 <2> JNE $MIF363 3009 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3010 <2> PUSH AX ;;AN000;; Save it 3011 <2> INC CX ;;AN000;; Count it 3012 <2> ; $ENDIF ;;AN000;; 3013 <2> $MIF363: 3014 <2> INC CX ;;AN000;; Restore CX 3015 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3016 <2> RET ;;AN000;; 3017 <2> $M_CONVERTDATE ENDP ;;AN000;; 3018 <2> ;; 3019 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3020 <2> %ENDIF ;;AN000;; END of include of DATE replace code 3021 <2> ; 3022 <2> %IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? 3023 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 3024 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 3025 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3026 <2> ;; 3027 <2> ;; PROC NAME: $M_TIME_REPLACE 3028 <2> ;; 3029 <2> ;; FUNCTION: Convert a time to a decimal ASCII string 3030 <2> ;; and prepare to display 3031 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 3032 <2> ;; ES:DI points at VALUE from SUBLIST 3033 <2> ;; OUTPUTS: CX contains number of characters on stack 3034 <2> ;; Top of stack --> Last character 3035 <2> ;; . . . 3036 <2> ;; Bot of stack --> First character 3037 <2> ;; REGS USED: BP,CX,AX 3038 <2> ;; 3039 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3040 <2> ;; 3041 <2> $M_TIME_REPLACE PROC NEAR ;;AN000;; 3042 <2> ;; 3043 <2> POP BP ;;AN000;; Save return address 3044 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 3045 <2> CALL $M_GET_TIME ;;AN000;; All O.K.? 3046 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3047 <2> ; $IF NZ ;;AN000;; Yes, 3048 <2> JZ $MIF365 3049 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3050 <2> ; $IF E ;;AN000;; Yes, 3051 <2> JNE $MIF366 3052 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3053 <2> CMP AL,12 ;;AN000;; Is hour 12 or less? 3054 <2> ; $IF L,OR ;;AN000;; or 3055 <2> JL $MLL367 3056 <2> CMP AL,23 ;;AN000;; Is hour 24 or greater? 3057 <2> ; $IF G ;;AN000;; Yes, 3058 <2> JNG $MIF367 3059 <2> $MLL367: 3060 <2> MOV AL,$M_AM ;;AN000;; 3061 <2> PUSH AX ;;AN000;; Push an "a" to represent AM. 3062 <2> INC CX ;;AN000;; 3063 <2> ; $ELSE ;;AN000;; No, 3064 <2> JMP SHORT $MEN367 3065 <2> $MIF367: 3066 <2> MOV AL,$M_PM ;;AN000;; 3067 <2> PUSH AX ;;AN000;; Push an "p" to represent PM. 3068 <2> INC CX ;;AN000;; 3069 <2> ; $ENDIF ;;AN000;; 3070 <2> $MEN367: 3071 <2> ; $ENDIF ;;AN000;; 3072 <2> $MIF366: 3073 <2> ; $ENDIF ;;AN000;; 3074 <2> $MIF365: 3075 <2> ;; 3076 <2> XOR AX,AX ;;AN000;; 3077 <2> XOR DX,DX ;;AN000;; 3078 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3079 <2> ; $IF NZ ;;AN000;; 3080 <2> JZ $MIF372 3081 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Hundreds 3082 <2> CALL $M_CONVERTTIME ;;AN000;; 3083 <2> PUSH WORD [$M_RT + $M_DECI_SEPARA] ;;AN000;; 3084 <2> INC CX ;;AN000;; 3085 <2> ; $ENDIF ;;AN000;; 3086 <2> $MIF372: 3087 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3088 <2> ; $IF NZ,OR ;;AN000;; 3089 <2> JNZ $MLL374 3090 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSS_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? 3091 <2> ; $IF NZ ;;AN000;; 3092 <2> JZ $MIF374 3093 <2> $MLL374: 3094 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Seconds 3095 <2> CALL $M_CONVERTTIME ;;AN000;; 3096 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3097 <2> INC CX ;;AN000;; 3098 <2> ; $ENDIF ;;AN000;; 3099 <2> $MIF374: 3100 <2> ;; Do Hour/Min (12 Hour) 3101 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+1] ;;AN000;; Get Minutes 3102 <2> CALL $M_CONVERTTIME ;;AN000;; 3103 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3104 <2> INC CX ;;AN000;; 3105 <2> ;; 3106 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3107 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3108 <2> ; $IF NZ ;;AN000;; Yes, 3109 <2> JZ $MIF376 3110 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3111 <2> ; $IF E ;;AN000;; Yes, 3112 <2> JNE $MIF377 3113 <2> CMP AL,13 ;;AN000;; Is hour less than 12? 3114 <2> ; $IF GE ;;AN000;; Yes, 3115 <2> JNGE $MIF378 3116 <2> SUB AL,12 ;;AN000;; Set to a 12 hour value 3117 <2> ; $ENDIF ;;AN000;; 3118 <2> $MIF378: 3119 <2> CMP AL,0 ;;AN000;; Is hour less than 12? 3120 <2> ; $IF E ;;AN000;; Yes, 3121 <2> JNE $MIF380 3122 <2> MOV AL,12 ;;AN000;; Set to a 12 hour value 3123 <2> ; $ENDIF ;;AN000;; 3124 <2> $MIF380: 3125 <2> ; $ENDIF ;;AN000;; 3126 <2> $MIF377: 3127 <2> ; $ENDIF ;;AN000;; 3128 <2> $MIF376: 3129 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII 3130 <2> ;; 3131 <2> PUSH BP ;;AN000;; Restore return address 3132 <2> RET ;;AN000;; Return 3133 <2> ;; 3134 <2> $M_TIME_REPLACE ENDP ;;AN000;; 3135 <2> ;; 3136 <2> $M_GET_TIME PROC NEAR ;;AN000;; 3137 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 3138 <2> MOV AL,0 ;;AN000;; Get current country info 3139 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 3140 <2> INT 21H ;;AN000;; 3141 <2> ; $IF C ;;AN000;; No, 3142 <2> JNC $MIF384 3143 <2> MOV WORD [$M_RT + $M_TIME_FORMAT],$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) 3144 <2> MOV BYTE [$M_RT + $M_TIME_SEPARA],$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) 3145 <2> MOV BYTE [$M_RT + $M_DECI_SEPARA],$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) 3146 <2> ; $ENDIF ;;AN000;; 3147 <2> $MIF384: 3148 <2> RET ;;AN000;; 3149 <2> $M_GET_TIME ENDP ;;AN000;; 3150 <2> ;; 3151 <2> $M_CONVERTTIME PROC NEAR ;;AN000;; 3152 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3153 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3154 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3155 <2> DEC CX ;;AN000;; Test if size only grew by 1 3156 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3157 <2> ; $IF E ;;AN000;; Yes, 3158 <2> JNE $MIF386 3159 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3160 <2> PUSH AX ;;AN000;; Save it 3161 <2> INC CX ;;AN000;; Count it 3162 <2> ; $ENDIF ;;AN000;; 3163 <2> $MIF386: 3164 <2> INC CX ;;AN000;; Restore CX 3165 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3166 <2> RET ;;AN000;; 3167 <2> $M_CONVERTTIME ENDP ;;AN000;; 3168 <2> ;; 3169 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3170 <2> %ENDIF ;;AN000;; END of include of TIME replace 3171 <2> %ENDIF ;;AN000;; END of include of Replacement common code 3172 <2> ; 3173 <2> %IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? 3174 <2> INPUTmsg equ FALSE ;;AN000;; Yes, THEN include it and reset the flag 3175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3176 <2> ;; 3177 <2> ;; PROC NAME: $M_WAIT_FOR_INPUT 3178 <2> ;; 3179 <2> ;; FUNCTION: To accept keyed input and return extended key value 3180 <2> ;; in AX register 3181 <2> ;; INPUTS: DL contains the DOS function requested for input 3182 <2> ;; OUPUTS: AX contains the extended key value that was read 3183 <2> ;; REGS USED: 3184 <2> ;; 3185 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3186 <2> ;; 3187 <2> $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; 3188 <2> ;; 3189 <2> PUSH CX ;;AN000;; Save CX 3190 <2> PUSH DX ;;AN000;; Save DX 3191 <2> PUSH DS ;;AN000;; Save Data segment 3192 <2> ;; 3193 <2> CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? 3194 <2> ; $IF A ;;AN001;; Yes, 3195 <2> JNA $MIF388 3196 <2> MOV AL,DL ;;AN001;; Mov function into AL 3197 <2> AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble 3198 <2> MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function 3199 <2> ; $ELSE ;;AN001;; No, 3200 <2> JMP SHORT $MEN388 3201 <2> $MIF388: 3202 <2> MOV AH,DL ;;AN000;; Put DOS function in AH 3203 <2> ; $ENDIF ;;AN001;; 3204 <2> $MEN388: 3205 <2> PUSH ES ;;AN000;; Get output buffer segment 3206 <2> POP DS ;;AN000;; 3207 <2> MOV DX,DI ;;AN000;; Get output buffer offset in case needed 3208 <2> INT 21H ;;AN000;; Get keyboard input 3209 <2> POP DS ;;AN000;; 3210 <2> 3211 <2> CMP DL,DOS_BUF_KEYB_INP ;;AN000;; 3212 <2> CLC ;;AN000;; 3213 <2> ; $IF NE ;;AN000;; If character input 3214 <2> JE $MIF391 3215 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? 3216 <2> ; $IF C ;;AN000;; 3217 <2> JNC $MIF392 3218 <2> MOV CL,AL ;;AN000;; Save first character 3219 <2> MOV AH,DL ;;AN001;; Get back function 3220 <2> INT 21H ;;AN000;; Get keyboard input 3221 <2> MOV AH,CL ;;AN000;; Retreive first character AX = xxxx 3222 <2> CLC ;;AN000;; Clear carry condition 3223 <2> ; $ELSE ;;AN000;; 3224 <2> JMP SHORT $MEN392 3225 <2> $MIF392: 3226 <2> MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS 3227 <2> ; $ENDIF ;;AN000;; 3228 <2> $MEN392: 3229 <2> ; $ENDIF ;;AN000;; 3230 <2> $MIF391: 3231 <2> ;; 3232 <2> ; $IF NC ;;AN000;; 3233 <2> JC $MIF396 3234 <2> POP DX ;;AN000;; 3235 <2> POP CX ;;AN000;; 3236 <2> ; $ELSE ;;AN000;; 3237 <2> JMP SHORT $MEN396 3238 <2> $MIF396: 3239 <2> ADD SP,4 ;;AN000;; 3240 <2> STC ;;AN000;; Reset carry flag 3241 <2> ; $ENDIF ;;AN000;; 3242 <2> $MEN396: 3243 <2> RET ;;AN000;; Return 3244 <2> ;; 3245 <2> $M_WAIT_FOR_INPUT ENDP ;;AN000;; 3246 <2> ;; 3247 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3248 <2> %ENDIF ;;AN000;; END of include of Wait for Input 3249 <2> %ENDIF ;;AN000;; END of include of SYSDISPMSG 3250 <2> %ENDIF ;;AN000;; END of include of MSG_DATA_ONLY 3251 <2> %ENDIF ;;AN000;; END of include of Structure only 3252 <2> 3253 <2> ;=== Pop trace listing source 3254 <2> 331 <1> 23 === Switch to base=000000h -> "SHARE" 24 section SHARE 25 ; (no prior section) ; Share ENDS === Switch to base=000000h -> "SHARE" 26 section SHARE 27 28 SYSPARSE equ SysParse ; NASM port label 29 PUBLIC SYSDISPMSG, SYSLOADMSG, SYSPARSE 30 extrn amis_sign:byte 31 32 ASSUME CS:Share,DS:nothing,ES:nothing 33 34 ; include Message Code 35 36 37 ; .xcref 38 39 40 MSG_SERVICES "MSGDATA" 364 <1> %iassign $M_SERVICE FALSE 365 <1> %rep %0 366 <1> %iassign $M_INCLUDE TRUE 367 <1> %iassign MSG_SERVICES_MATCHED 0 368 <1> %ifidni %1, "MSGDATA" 369 <1> %iassign MSGDATA TRUE 370 <1> %iassign $M_SERVICE TRUE 371 <1> %iassign $M_INCLUDE FALSE 372 <1> %iassign MSG_SERVICES_MATCHED 1 373 <1> %else 374 <1> %iassign $M_MSGDATA_ONLY FALSE 375 <1> %endif 376 <1> 377 <1> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <1> 379 <1> %ifidni %1,"COMR" 380 <1> %iassign COMR TRUE 381 <1> %iassign $M_SERVICE TRUE 382 <1> %iassign $M_INCLUDE FALSE 383 <1> %iassign MSG_SERVICES_MATCHED 1 384 <1> %elifidni %1,"COMT" 385 <1> %iassign COMT TRUE 386 <1> %iassign $M_SERVICE TRUE 387 <1> %iassign $M_INCLUDE FALSE 388 <1> %iassign MSG_SERVICES_MATCHED 1 389 <1> %elifidni %1,"SETSTDIO" 390 <1> %iassign SETSTDIO TRUE 391 <1> %iassign $M_SERVICE TRUE 392 <1> %iassign $M_INCLUDE FALSE 393 <1> %iassign MSG_SERVICES_MATCHED 1 394 <1> %elifidni %1,"NOCHECKSTDIN" 395 <1> %iassign NOCHECKSTDIN TRUE 396 <1> %iassign $M_SERVICE TRUE 397 <1> %iassign $M_INCLUDE FALSE 398 <1> %iassign MSG_SERVICES_MATCHED 1 399 <1> %elifidni %1,"NOCHECKSTDOUT" 400 <1> %iassign NOCHECKSTDOUT TRUE 401 <1> %iassign $M_SERVICE TRUE 402 <1> %iassign $M_INCLUDE FALSE 403 <1> %iassign MSG_SERVICES_MATCHED 1 404 <1> %elifidni %1,"DISK_PROC" 405 <1> %iassign DISK_PROC TRUE 406 <1> %iassign $M_SERVICE TRUE 407 <1> %iassign $M_INCLUDE FALSE 408 <1> %iassign MSG_SERVICES_MATCHED 1 409 <1> %endif 410 <1> 411 <1> %IF $M_INCLUDE 412 <1> %define %%string %1 413 <1> %strlen %%length %%string 414 <1> %assign %%ii 1 415 <1> %define %%name "" 416 <1> %rep %%length 417 <1> %substr %%cc %%string %%ii 418 <1> %assign %%ii %%ii + 1 419 <1> %if %%cc >= 'A' && %%cc <= 'Z' 420 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <1> %endif 422 <1> %strcat %%name %%name,%%cc 423 <1> %endrep 424 <1> %include %%name 425 <1> %ENDIF 426 <1> 427 <1> %rotate 1 428 <1> %endrep 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 424 <2> %include %%name 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 429 <1> 430 <1> %IF $M_SERVICE 431 <1> 432 <1> %include "msgserv.nas" 1 <2> ;=== Push trace listing source: msgserv.nas 2 <2> 3 <2> ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * 4 <2> ; 5 <2> ; MODULE NAME: MSGSERV.SAL 6 <2> ; 7 <2> ; DESCRIPTIVE NAME: Message Services SALUT file 8 <2> ; 9 <2> ; FUNCTION: This module incorporates all the messages services and 10 <2> ; is called upon at build time to INCLUDE the code requested 11 <2> ; by a utility. Code is requested using the macro MSG_SERVICES. 12 <2> ; 13 <2> ; ENTRY POINT: Since this a collection of subroutines, entry point is at 14 <2> ; requested procedure. 15 <2> ; 16 <2> ; INPUT: Since this a collection of subroutines, input is dependent on function 17 <2> ; requested. 18 <2> ; 19 <2> ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 20 <2> ; 21 <2> ; EXIT-ERROR: In all cases, CARRY FLAG = 1 22 <2> ; 23 <2> ; INTERNAL REFERENCES: (list of included subroutines) 24 <2> ; 25 <2> ; - SYSLOADMSG 26 <2> ; - SYSDISPMSG 27 <2> ; - SYSGETMSG 28 <2> ; 29 <2> ; 30 <2> ; EXTERNAL REFERENCES: None 31 <2> ; 32 <2> ; NOTES: At build time, some modules must be included. These are only included 33 <2> ; once using assembler switches. Other logic is included at the request 34 <2> ; of the utility. 35 <2> ; 36 <2> ; COMR and COMT are assembler switches to conditionally assemble code 37 <2> ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident 38 <2> ; storage and multiple EQUates. 39 <2> ; 40 <2> ; REVISION HISTORY: Created MAY 1987 41 <2> ; 42 <2> ; Label: DOS - - Message Retriever 43 <2> ; (c) Copyright 1988 Microsoft 44 <2> ; 45 <2> ; 46 <2> ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * 47 <2> ; Page 48 <2> 49 <2> ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting 50 <2> 51 <2> %IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN 52 <2> %iassign $M_STRUC FALSE ;;AN000;; Let the assembler know that we have 53 <2> ;;AN000;; and include them 54 <2> 55 <2> ; PAGE 56 <2> ; SUBTTL DOS - Message Retriever - MSGSTR.INC Module 57 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 <2> ;; 59 <2> ;; STRUCTURE: $M_SUBLIST_STRUC 60 <2> ;; 61 <2> ;; Replacable parameters are described by a sublist structure 62 <2> ;; 63 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 <2> ;; 65 <2> $M_SUBLIST_STRUC STRUC ;;AN000;; 66 <2> ;; 67 <2> $M_S_SIZE DB ? ;11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) 68 <2> $M_S_RESV DB ? ;0 ;;AN000;; RESERVED 69 <2> $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item 70 <2> $M_S_ID DB ? ;;AN000;; n of %n 71 <2> $M_S_FLAG DB ? ;;AN000;; Data-type flags 72 <2> $M_S_MAXW DB ? ;;AN000;; Maximum field width 73 <2> $M_S_MINW DB ? ;;AN000;; Minimum field width 74 <2> $M_S_PAD DB ? ;;AN000;; Character for Pad field 75 <2> ;; 76 <2> $M_SUBLIST_STRUC ENDS ;;AN000;; 77 <2> ;; 78 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 <2> ;; 80 <2> ;; STRUCTURE: $M_CLASS_ID 81 <2> ;; 82 <2> ;; Each class will be defined by this structure. 83 <2> ;; 84 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 <2> ;; 86 <2> EXPECTED_VERSION equ expected_version ; NASM port equate 87 <2> 88 <2> $M_CLASS_ID STRUC ;;AN000;; 89 <2> ;; 90 <2> $M_CLS_ID DB ? ;-1 ;;AN000;; Class identifer 91 <2> $M_COMMAND_VER DW ? ;EXPECTED_VERSION ;;AN003;; COMMAND.COM version check 92 <2> $M_NUM_CLS_MSG DB ? ;0 ;;AN000;; Total number of message in class 93 <2> ;; 94 <2> $M_CLASS_ID ENDS ;; 95 <2> ;;AN000;; 96 <2> $M_CLASS_ID_SZ EQU $M_CLASS_ID_struc_size ;;AN000;; 97 <2> ;; 98 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 <2> ;; 100 <2> ;; STRUCTURE: $M_ID_STRUC 101 <2> ;; 102 <2> ;; Each message will be defined by this structure. 103 <2> ;; 104 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 105 <2> ;; 106 <2> $M_ID STRUC ;;AN000;; 107 <2> ;; 108 <2> $M_NUM DW ? ;-1 ;;AN000;; Message Number 109 <2> $M_TXT_PTR DW ? ;;AN000;; Pointer to message text 110 <2> ;; 111 <2> $M_ID ENDS ;;AN000;; 112 <2> ;;AN000;; Status Flag Values: 113 <2> $M_ID_SZ EQU $M_ID_struc_size ;;AN000;; 114 <2> ;; 115 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 <2> ;; 117 <2> ;; STRUCTURE: $M_RES_ADDRS 118 <2> ;; 119 <2> ;; Resident data area definition of variables 120 <2> ;; 121 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122 <2> ;; 123 <2> $M_RES_ADDRS STRUC ;;AN000;; 124 <2> ;; 125 <2> $M_EXT_ERR_ADDRS DD ? ;0 ;;AN000;; Allow pointers to THREE Extended error locations 126 <2> $M_EXT_FILE DD ? ;0 ;;AN001;; 127 <2> $M_EXT_COMMAND DD ? ;0 ;;AN000;; 128 <2> $M_EXT_TERM DD ? ;-1 ;;AN000;; 129 <2> $M_PARSE_COMMAND DD ? ;0 ;;AN000;; 130 <2> $M_PARSE_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Parse error locations 131 <2> $M_PARSE_TERM DD ? ;-1 ;;AN000;; 132 <2> $M_CRIT_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Critical error locations 133 <2> $M_CRIT_COMMAND DD ? ;0 ;;AN000;; 134 <2> $M_CRIT_TERM DD ? ;-1 ;;AN000;; 135 <2> $M_DISK_PROC_ADDR DD ? ;-1 ;;AN004;; Address of READ_DISK_PROC 136 <2> $M_CLASS_ADDRS DD $M_NUM_CLS DUP (?) ;(0) ;;AN000;; Allow pointers to specified classes 137 <2> $M_CLS_TERM DD ? ;-1 ;;AN000;; 138 <2> $M_DBCS_VEC DD ? ;0 ;;AN000;; Save DBCS vector 139 <2> $M_HANDLE DW ? ;;AN000;; 140 <2> $M_SIZE DB ? ;0 ;;AN000;; 141 <2> $M_CRLF DB ?,? ;0DH,0AH ;;AN004;; CR LF message 142 <2> $M_CLASS DB ? ;;AN004;; Saved class 143 <2> $M_RETURN_ADDR DW ? ;;AN000;; 144 <2> $M_MSG_NUM DW ? ;$M_NULL ;;AN000;; 145 <2> $M_DIVISOR DW ? ;10 ;;AN000;; Default = 10 (must be a WORD for division) 146 <2> $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP (?) ;("$") ;;AN000;; Temporary buffer 147 <2> $M_BUF_TERM DB ? ;"$" ;;AN000;; 148 <2> 149 <2> $M_RES_ADDRS ENDS ;;AN000;; 150 <2> ;; 151 <2> $M_RES_ADDRS_SZ EQU $M_RES_ADDRS_struc_size ;;AN000;; 152 <2> ;; 153 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 <2> ;; 155 <2> ;; STRUCTURE: $M_COUNTRY_INFO 156 <2> ;; 157 <2> ;; Important fields of the Get Country Information call 158 <2> ;; 159 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 <2> ;; 161 <2> $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation 162 <2> ;; 163 <2> $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc 164 <2> $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format 165 <2> $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; 166 <2> $M_THOU_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Thou Separator 167 <2> $M_DECI_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Decimal Separator 168 <2> $M_DATE_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Date Separator 169 <2> $M_TIME_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Time Separator 170 <2> $M_CURR_FORMAT DB ? ;;AN000;; 171 <2> $M_SIG_DIGS_CU DB ? ;;AN000;; 172 <2> $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format 173 <2> ;; 174 <2> $M_COUNTRY_INFO ENDS ;;AN000;; 175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 176 <2> ;; 177 <2> %ELSE ;;AN000;; ELSE if we have already included the STRUCTURES 178 <2> ; 179 <2> ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section 180 <2> 181 <2> %IF MSGDATA ;;AN000;; IF this is a request to include the data area 182 <2> %iassign MSGDATA FALSE ;;AN000;; Let the assembler know not to include it again 183 <2> ;;AN000;; and include it 184 <2> ; PAGE 185 <2> ; SUBTTL DOS - Message Retriever - MSGRES.TAB Module 186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187 <2> ;; 188 <2> ;; DATA NAME: $M_RES_TABLE 189 <2> ;; 190 <2> ;; REFERENCE LABEL: $M_RT 191 <2> ;; 192 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 193 <2> 194 <2> %if 0 ; disabled for now, figure out later 195 <2> %IF COMR ;;AN000;; Since COMMAND.COM includes this twice 196 <2> $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no 197 <2> $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur 198 <2> $M_ALTLABEL equ TRUE ;;AN000;; Flag that label was changed 199 <2> %ELSE ;;AN000;; 200 <2> $M_RT LABEL BYTE ;;AN000;; 201 <2> %ENDIF 202 <2> %endif 203 <2> $M_RT: ; NASM structure instance 204 <2> $M_RES_ADDRS_size equ $M_RES_ADDRS_struc_size ; NASM port equate 205 <2> istruc $M_RES_ADDRS 206 <2> at $M_EXT_ERR_ADDRS 0 00000DFD 00000000 dd 0 208 <2> at $M_EXT_FILE 0 00000E01 00000000 dd 0 210 <2> at $M_EXT_COMMAND 0 00000E05 00000000 dd 0 212 <2> at $M_EXT_TERM 0 00000E09 FFFFFFFF dd -1 214 <2> at $M_PARSE_COMMAND 0 00000E0D 00000000 dd 0 216 <2> at $M_PARSE_ADDRS 0 00000E11 00000000 dd 0 218 <2> at $M_PARSE_TERM 0 00000E15 FFFFFFFF dd -1 220 <2> at $M_CRIT_ADDRS 0 00000E19 00000000 dd 0 222 <2> at $M_CRIT_COMMAND 0 00000E1D 00000000 dd 0 224 <2> at $M_CRIT_TERM 0 00000E21 FFFFFFFF dd -1 226 <2> at $M_DISK_PROC_ADDR 0 00000E25 FFFFFFFF dd -1 228 <2> at $M_CLASS_ADDRS 0 00000E29 00000000 times $M_NUM_CLS dd 0 230 <2> at $M_CLS_TERM 0 00000E2D FFFFFFFF dd -1 232 <2> at $M_DBCS_VEC 0 00000E31 00000000 dd 0 234 <2> at $M_HANDLE 0 00000E35 0000 dw 0 236 <2> at $M_SIZE 0 00000E37 00 db 0 238 <2> at $M_CRLF 0 00000E38 0D0A db 0Dh, 0Ah 240 <2> at $M_CLASS 0 00000E3A 00 db 0 242 <2> at $M_RETURN_ADDR 0 00000E3B 0000 dw 0 244 <2> at $M_MSG_NUM 0 00000E3D 0000 dw 0 246 <2> at $M_DIVISOR 0 00000E3F 0A00 dw 10 248 <2> at $M_TEMP_BUF 0 00000E41 24 times $M_TEMP_BUF_SZ db "$" 250 <2> at $M_BUF_TERM 0 00000E81 24 db "$" 252 <2> iend 253 <2> ;; 254 <2> %include "copyrigh.mac" ;;AN001;; Include Copyright 1988 Microsoft 0 00000E82 4D5320444F53205665 DB "MS DOS Version 4.00 (C)Copyright 1988 Microsoft Corp" 0 00000E8B 7273696F6E20342E30 0 00000E94 3020284329436F7079 0 00000E9D 726967687420313938 0 00000EA6 38204D6963726F736F 0 00000EAF 667420436F7270 0 00000EB6 4C6963656E73656420 DB "Licensed Material - Property of Microsoft " 0 00000EBF 4D6174657269616C20 0 00000EC8 2D2050726F70657274 0 00000ED1 79206F66204D696372 0 00000EDA 6F736F66742020 255 <2> ;; 256 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 257 <2> %ENDIF ;;AN000;; END of include of Data table 258 <2> 259 <2> ; 260 <2> %IFN $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN 261 <2> ;; don't include any more code 262 <2> ;;AN000;; Figure out what other code to include 263 <2> %IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code 264 <2> %IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) 265 <2> $M_RT EQU $M_RT2 ;;AN003;; 266 <2> %ENDIF 267 <2> %iassign DISK_PROC FALSE ;;AN003;; Yes, THEN include it and reset flag 268 <2> ; PAGE 269 <2> ; SUBTTL DOS - Message Retriever - DISK_PROC Module 270 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 271 <2> ;; 272 <2> ;; PROC NAME: DISK_PROC 273 <2> ;; 274 <2> ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended 275 <2> ;; errors from disk\diskette 276 <2> ;; INPUTS: AX has the message number 277 <2> ;; DX has the message class 278 <2> ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is 279 <2> ;; assumed to be set!! 280 <2> ;; 281 <2> ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text 282 <2> ;; 283 <2> ;; 284 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 285 <2> ;; 286 <2> PUBLIC READ_DISK_PROC ;; 287 <2> ;; 288 <2> READ_DISK_PROC PROC FAR ;;AN003;; 289 <2> 290 <2> PUSH AX ;;AN003;; Save everything 291 <2> PUSH BX ;;AN003;; 292 <2> PUSH DX ;;AN003;; 293 <2> PUSH SI ;;AN003;; 294 <2> PUSH BP ;;AN003;; 295 <2> PUSH DS ;;AN003;; 296 <2> PUSH DI ;;AN003;; 297 <2> MOV BP,AX ;;AN003;; Save message number 298 <2> MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function 299 <2> LEA SI,[COMSPEC wrt RESGROUP] ;;AN003;; Get addressibilty to COMMAND.COM 300 <2> PUSH CS ;;AN003;; 301 <2> POP DS ;;AN003;; 302 <2> MOV DI,-1 ;;AN003;; No extended attribute list 303 <2> MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error 304 <2> MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag 305 <2> INT 21H ;;AN003;; Open the file 306 <2> POP DI ;;AN003;; Retreive LSEEK pointer 307 <2> ;;AN003;; Error ? 308 <2> ; $IF NC,LONG ;;AN003;; No, 309 <2> JNC $MXL1 310 <2> JMP $MIF1 311 <2> $MXL1: 312 <2> PUSH DI ;;AN003;; Save LSEEK pointer 313 <2> MOV BX,AX ;;AN003;; Set handle in BX 314 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors 315 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 316 <2> MOV DX,DI ;;AN003;; 317 <2> INT 21H ;;AN003;; LSEEK the file 318 <2> POP DX ;;AN003;; Retreive LSEEK pointer 319 <2> ;;AN003;; Error ? 320 <2> ; $IF NC ;;AN003;; No, 321 <2> JC $MIF2 322 <2> INC CX ;;AN003;; Set flag to first pass 323 <2> ; $DO ;;AN003;; 324 <2> $MDO3: 325 <2> PUSH DX ;;AN003;; Save LSEEK pointer 326 <2> PUSH CX ;;AN003;; Save first pass flag 327 <2> PUSH AX ;;AN003;; Save number of messages (if set yet) 328 <2> XOR SI,SI ;;AN003;; Reset buffer index 329 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 330 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header 331 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 332 <2> INT 21H ;;AN003;; Read it 333 <2> MOV DI,DX ;;AN003;; 334 <2> POP AX ;;AN003;; 335 <2> POP CX ;;AN003;; 336 <2> OR CX,CX ;;AN003;; 337 <2> ; $IF NZ ;;AN003;; 338 <2> JZ $MIF4 339 <2> XOR CX,CX ;;AN003;; Set flag to second pass 340 <2> XOR AH,AH ;;AN003;; Get number of messages in class 341 <2> MOV AL,[DI + $M_NUM_CLS_MSG] ;;AN003;; 342 <2> MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index 343 <2> CMP word [DI + $M_COMMAND_VER],EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? 344 <2> ; $ENDIF ;;AN003;; 345 <2> $MIF4: 346 <2> POP DX ;;AN003;; 347 <2> ; $IF Z ;;AN003;; Yes, 348 <2> JNZ $MIF6 349 <2> ; $SEARCH ;;AN003;; 350 <2> $MDO7: 351 <2> CMP BP,WORD PTR [$M_RT + $M_TEMP_BUF + SI] ;;AN003;; Is this the message I'm looking for? 352 <2> ; $EXITIF Z ;;AN003;; Yes, (ZF=1) 353 <2> JNZ $MIF7 354 <2> CLC ;;AN003;; Reset carry, exit search 355 <2> ; $ORELSE ;;AN003;; No, (ZF=0) 356 <2> JMP SHORT $MSR7 357 <2> $MIF7: 358 <2> ADD SI,$M_ID_SZ ;;AN003;; Increment index 359 <2> ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header 360 <2> DEC AX ;;AN003;; Decrement # of messages left 361 <2> ; $LEAVE Z ;;AN003;; Have we exhausted all messages? 362 <2> JZ $MEN7 363 <2> CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? 364 <2> ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) 365 <2> JNA $MDO7 366 <2> $MEN7: 367 <2> STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) 368 <2> ; $ENDSRCH ;;AN003;; 369 <2> $MSR7: 370 <2> ; $ELSE ;;AN003;; No, 371 <2> JMP SHORT $MEN6 372 <2> $MIF6: 373 <2> XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop 374 <2> STC ;;AN003;; Set Carry 375 <2> ; $ENDIF ;;AN003;; 376 <2> $MEN6: 377 <2> ; $ENDDO Z ;;AN003;; Get next buffer full if needed 378 <2> JNZ $MDO3 379 <2> ;;AN003;; Error ? 380 <2> ; $IF NC ;;AN003;; No, 381 <2> JC $MIF16 382 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message 383 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 384 <2> ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header 385 <2> ADD DX,WORD PTR [$M_RT + $M_TEMP_BUF + SI + 2] ;;AN003;; Add offset from msg structure 386 <2> INT 21H ;;AN003;; LSEEK the file 387 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 388 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message 389 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 390 <2> INT 21H ;;AN003;; Read it 391 <2> MOV DI,DX ;;AN003;; into the temp buffer 392 <2> PUSH DS ;;AN003;; into the temp buffer 393 <2> POP ES ;;AN003;; into the temp buffer 394 <2> ; $ENDIF ;;AN003;; 395 <2> $MIF16: 396 <2> ; $ENDIF ;;AN003;; 397 <2> $MIF2: 398 <2> PUSHF ;;AN003;; Close file handle 399 <2> MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle 400 <2> INT 21H ;;AN003;; 401 <2> $M_POPF ;;AN003;; 402 <2> ; $ENDIF ;;AN003;; Yes there was an error, 403 <2> $MIF1: 404 <2> POP DS ;;AN003;; 405 <2> POP BP ;;AN003;; 406 <2> POP SI ;;AN003;; 407 <2> POP DX ;;AN003;; 408 <2> POP BX ;;AN003;; 409 <2> POP AX ;;AN003;; 410 <2> ;;AN003;; abort everything 411 <2> RET ;;AN003;; 412 <2> 413 <2> READ_DISK_PROC ENDP ;;AN003;; 414 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 415 <2> %ENDIF ;;AN003;; END of include for DISK_PROC 416 <2> ; 417 <2> 418 <2> %IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO 419 <2> %iassign SETSTDIO FALSE ;;AN000;; Yes, THEN include it and reset flag 420 <2> ; PAGE 421 <2> ; SUBTTL DOS - Message Retriever - SETSTDIO Module 422 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 423 <2> ;; 424 <2> ;; PROC NAME: SETSTDIO 425 <2> ;; 426 <2> ;; FUNCTION: 427 <2> ;; INPUTS: 428 <2> ;; 429 <2> ;; OUPUTS: 430 <2> ;; 431 <2> ;; 432 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 433 <2> ;; 434 <2> %IF FARmsg ;AN001; 435 <2> SETSTDINON PROC FAR ;AN001; 436 <2> %ELSE ;AN001; 437 <2> SETSTDINON PROC NEAR ;AN001; 438 <2> %ENDIF ;AN001; 439 <2> PUSH AX ;AN002; Save changed regs 440 <2> PUSH BX ;AN002; 441 <2> PUSH DX ;AN002; 442 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 443 <2> MOV BX,STDIN ;AN001; 444 <2> XOR DX,DX ;AN001; 445 <2> INT 21H ;AN001; 446 <2> 447 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 448 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 449 <2> INT 21H ;AN001; 450 <2> POP DX ;AN002; Restore Regs 451 <2> POP BX ;AN002; 452 <2> POP AX ;AN002; 453 <2> 454 <2> RET ;AN001; 455 <2> ;AN001; 456 <2> SETSTDINON ENDP ;AN001; 457 <2> 458 <2> %IF FARmsg ;AN001; 459 <2> SETSTDINOFF PROC FAR ;AN001; 460 <2> %ELSE ;AN001; 461 <2> SETSTDINOFF PROC NEAR ;AN001; 462 <2> %ENDIF ;AN001; 463 <2> 464 <2> PUSH AX ;AN002; Save changed regs 465 <2> PUSH BX ;AN002; 466 <2> PUSH DX ;AN002; 467 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 468 <2> MOV BX,STDIN ;AN001; 469 <2> XOR DX,DX ;AN001; 470 <2> INT 21H ;AN001; 471 <2> 472 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 473 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 474 <2> INT 21H ;AN001; 475 <2> POP DX ;AN002; Restore Regs 476 <2> POP BX ;AN002; 477 <2> POP AX ;AN002; 478 <2> 479 <2> RET ;AN001; 480 <2> 481 <2> SETSTDINOFF ENDP ;AN001; 482 <2> 483 <2> %IF FARmsg ;AN001; 484 <2> SETSTDOUTON PROC FAR ;AN001; 485 <2> %ELSE ;AN001; 486 <2> SETSTDOUTON PROC NEAR ;AN001; 487 <2> %ENDIF ;AN001; 488 <2> 489 <2> PUSH AX ;AN002; Save changed regs 490 <2> PUSH BX ;AN002; 491 <2> PUSH DX ;AN002; 492 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 493 <2> MOV BX,STDOUT ;AN001; 494 <2> XOR DX,DX ;AN001; 495 <2> INT 21H ;AN001; 496 <2> 497 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 498 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 499 <2> INT 21H ;AN001; 500 <2> POP DX ;AN002; Restore Regs 501 <2> POP BX ;AN002; 502 <2> POP AX ;AN002; 503 <2> 504 <2> RET ;AN001; 505 <2> 506 <2> SETSTDOUTON ENDP ;AN001; 507 <2> 508 <2> %IF FARmsg ;AN001; 509 <2> SETSTDOUTOFF PROC FAR ;AN001; 510 <2> %ELSE ;AN001; 511 <2> SETSTDOUTOFF PROC NEAR 512 <2> %ENDIF ;AN001; 513 <2> 514 <2> PUSH AX ;AN002; Save changed regs 515 <2> PUSH BX ;AN002; 516 <2> PUSH DX ;AN002; 517 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 518 <2> MOV BX,STDOUT ;AN001; 519 <2> XOR DX,DX ;AN001; 520 <2> INT 21H ;AN001; 521 <2> 522 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 523 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 524 <2> INT 21H ;AN001; 525 <2> POP DX ;AN002; Restore Regs 526 <2> POP BX ;AN002; 527 <2> POP AX ;AN002; 528 <2> 529 <2> RET ;AN001; 530 <2> 531 <2> SETSTDOUTOFF ENDP ;AN001; 532 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 533 <2> %ENDIF ;;AN000;; END of include for SETSTDIO 534 <2> ; 535 <2> %IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? 536 <2> %IF COMR ;;AN000;; 537 <2> $M_RT EQU $M_RT2 ;;AN000;; 538 <2> %ENDIF 539 <2> %iassign LOADmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 540 <2> ; PAGE 541 <2> ; SUBTTL DOS - Message Retriever - LOADMSG.ASM Module 542 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 543 <2> ;; 544 <2> ;; PROC NAME: SYSLOADMSG 545 <2> ;; 546 <2> ;; FUNCTION: 547 <2> ;; INPUTS: 548 <2> ;; 549 <2> ;; OUPUTS: 550 <2> ;; 551 <2> ;; 552 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 553 <2> ;; 554 <2> %IF FARmsg ;;AN000;; 555 <2> SYSLOADMSG PROC FAR ;;AN000;; 556 <2> %ELSE ;;AN000;; 557 <2> SYSLOADMSG PROC NEAR ;;AN000;; 558 <2> %ENDIF ;;AN000;; 559 <2> PUSH AX ;;AN000; 560 <2> PUSH BX ;;AN000; 561 <2> PUSH DX ;;AN000; 562 <2> PUSH ES ;;AN000; 563 <2> PUSH DI ;;AN000; 564 <2> XOR CX,CX ;;AN000; Reset to zero 565 <2> MOV ES,CX ;;AN000; 566 <2> XOR DI,DI ;;AN000; 567 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 568 <2> MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM 569 <2> INT 2FH ;;AN000;; Private interface 570 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 571 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND],DI ;;AN000;; 572 <2> ;; 573 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 574 <2> MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM 575 <2> INT 2FH ;;AN000;; Private interface 576 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 577 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND],DI ;;AN000;; 578 <2> ;; 579 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 580 <2> MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM 581 <2> INT 2FH ;;AN000;; Private interface 582 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 583 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND],DI ;;AN000;; 584 <2> 585 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 586 <2> MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE 587 <2> INT 2FH ;;AN001;; Private interface 588 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE+2],ES ;;AN001;; Move into first avaliable table location 589 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE],DI ;;AN001;; 590 <2> 591 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 592 <2> Extrn READ_DISK_PROC:Far ;;AN003;; 593 <2> %ELSE ;; 594 <2> %IF FARmsg ;;AN000;; 595 <2> CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 596 <2> %ELSE ;;AN000;; 597 <2> CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 598 <2> %ENDIF ;;AN000;; 599 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 600 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS],DI ;;AN000;; 601 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 602 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS],DI ;;AN000;; 603 <2> ;; 604 <2> %IF FARmsg ;;AN000;; 605 <2> CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 606 <2> %ELSE ;;AN000;; 607 <2> CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 608 <2> %ENDIF ;;AN000;; 609 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 610 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS],DI ;;AN000;; 611 <2> %ENDIF ;; 612 <2> ;; 613 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 614 <2> MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM 615 <2> INT 2FH ;;AN001;; Private interface 616 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR+2],ES ;;AN001;; Move into first avaliable table location 617 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR],DI ;;AN001;; 618 <2> 619 <2> $M_BUILD_PTRS $M_NUM_CLS ;;AN000;; Build all utility classes 620 <2> ;;AN000;; 621 <2> CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector 622 <2> 623 <2> %IFN NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed 624 <2> CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK 625 <2> %ENDIF ;;AN000;; 626 <2> ;;AN000;; 627 <2> %IFN NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed 628 <2> CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK 629 <2> %ENDIF ;;AN000;; 630 <2> ;;AN000;; 631 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 632 <2> CLC ;;AN000;; Make sure carry is clear 633 <2> %ELSE ;;AN000;; ELSE 634 <2> PUSH CX ;;AN000;; 635 <2> CALL $M_VERSION_CHECK ;;AN000;; Check Version 636 <2> %ENDIF ;;AN000;; 637 <2> ;; Error ? 638 <2> ; $IF NC ;;AN000;; No. 639 <2> JC $MIF20 640 <2> %IFN NOVERCHECKmsg ;;AN000;; IF version check was not supressed 641 <2> POP CX ;;AN000;; Reset stack 642 <2> %ENDIF ;;AN000;; 643 <2> POP DI ;;AN000;; Restore REGS 644 <2> POP ES ;;AN000;; 645 <2> POP DX ;;AN000;; 646 <2> POP BX ;;AN000;; 647 <2> POP AX ;;AN000;; 648 <2> ; $ELSE ;;AN000;; Yes, 649 <2> JMP SHORT $MEN20 650 <2> $MIF20: 651 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 652 <2> ADD SP,10 ;;AN000;; 653 <2> STC ;;AN000;; Reset carry flag 654 <2> %ELSE ;;AN000;; IF version check is to be supressed 655 <2> ADD SP,12 ;;AN000;; 656 <2> STC ;;AN000;; Reset carry flag 657 <2> %ENDIF ;;AN000;; IF version check is to be supressed 658 <2> ; $ENDIF ;;AN000;; 659 <2> $MEN20: 660 <2> RET ;;AN000;; 661 <2> ;; 662 <2> SYSLOADMSG ENDP ;;AN000;; 663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 664 <2> ; PAGE 665 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 666 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 667 <2> ;; 668 <2> ;; Proc Name: $M_GET_DBCS_VEC 669 <2> ;; 670 <2> ;; Function: Get the DBCS vector and save it for later use 671 <2> ;; 672 <2> ;; Inputs: None 673 <2> ;; 674 <2> ;; Outputs: None 675 <2> ;; 676 <2> ;; Regs Changed: 677 <2> ;; 678 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 679 <2> ;; 680 <2> $M_GET_DBCS_VEC PROC NEAR ;;AN000;; 681 <2> ;; 682 <2> PUSH AX ;;AN000;; Save character to check 683 <2> PUSH SI ;;AN000;; 684 <2> PUSH DS ;;AN000;; 685 <2> MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment 686 <2> INT 21H ;;AN000;; Get environment pointer 687 <2> PUSH DS ;;AN000;; Get environment pointer 688 <2> POP ES ;;AN000;; Get environment pointer 689 <2> POP DS ;;AN000;; Get environment pointer 690 <2> ; $IF NC ;;AN000;; 691 <2> JC $MIF23 692 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC],SI ;;AN000;; Save DBCS Vector 693 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC+2],ES ;;AN000;; 694 <2> ; $ENDIF ;;AN000;; 695 <2> $MIF23: 696 <2> POP SI ;;AN000;; 697 <2> POP AX ;;AN000;; Retrieve character to check 698 <2> RET ;;AN000;; Return 699 <2> ;; 700 <2> $M_GET_DBCS_VEC ENDP ;; 701 <2> ;; 702 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 703 <2> %IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? 704 <2> %ELSE ;AN001; Yes, THEN include it 705 <2> ; PAGE 706 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc 707 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 708 <2> ;; 709 <2> ;; Proc Name: $M_CHECKSTDIN 710 <2> ;; 711 <2> ;; Function: 712 <2> ;; 713 <2> ;; Inputs: None 714 <2> ;; 715 <2> ;; Outputs: 716 <2> ;; 717 <2> ;; Regs Changed: 718 <2> ;; 719 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 720 <2> ;; 721 <2> $M_CHECKSTDIN PROC NEAR ;AN001; 722 <2> 723 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 724 <2> MOV BX,STDIN ;AN001; 725 <2> XOR DX,DX ;AN001; 726 <2> INT 21H ;AN001; 727 <2> 728 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 729 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 730 <2> INT 21H ;AN001; 731 <2> 732 <2> RET ;AN001; 733 <2> 734 <2> $M_CHECKSTDIN ENDP ;AN001; 735 <2> ;; 736 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 737 <2> %ENDIF ;AN001; END of include for EOF Check 738 <2> %IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? 739 <2> %ELSE ;AN001; Yes, THEN include it 740 <2> ; PAGE 741 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc 742 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 743 <2> ;; 744 <2> ;; Proc Name: $M_CHECKSTDOUT 745 <2> ;; 746 <2> ;; Function: 747 <2> ;; 748 <2> ;; Inputs: None 749 <2> ;; 750 <2> ;; Outputs: 751 <2> ;; 752 <2> ;; Regs Changed: 753 <2> ;; 754 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 755 <2> ;; 756 <2> $M_CHECKSTDOUT PROC NEAR ;AN001; 757 <2> 758 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 759 <2> MOV BX,STDOUT ;AN001; 760 <2> XOR DX,DX ;AN001; 761 <2> INT 21H ;AN001; 762 <2> 763 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 764 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 765 <2> INT 21H ;AN001; 766 <2> 767 <2> RET ;AN001; 768 <2> 769 <2> $M_CHECKSTDOUT ENDP ;AN001; 770 <2> ;; 771 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 772 <2> %ENDIF ;AN001; END of include for Disk Full Check 773 <2> %IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? 774 <2> %ELSE ;;AN000;; Yes, THEN include it 775 <2> ; PAGE 776 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 778 <2> ;; 779 <2> ;; Proc Name: $M_VERSION_CHECK 780 <2> ;; 781 <2> ;; Function: Determine if DOS version is within allowable limits 782 <2> ;; 783 <2> ;; Inputs: None 784 <2> ;; 785 <2> ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version 786 <2> ;; Registers set for SYSDISPMSG 787 <2> ;; CARRY_FLAG = 0 if Correct DOS version 788 <2> ;; 789 <2> ;; Regs Changed: AX 790 <2> ;; 791 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 792 <2> 793 <2> check_amis: 794 <2> push ax 795 <2> push ds 796 <2> push si 797 <2> push es 798 <2> push di 799 <2> push dx 800 <2> push ax ; version number, last on stack 801 <2> 802 <2> mov ah, 0 ; multiplex number = 0 803 <2> .loop: 804 <2> mov al, 0 805 <2> int 2Dh ; installation check 806 <2> cmp al, -1 ; multiplexer installed ? 807 <2> jne .next ; no --> 808 <2> push cs 809 <2> pop ds 810 <2> mov si, offset amis_sign ; ds:si -> amis_sign (for lDOS) 811 <2> mov es, dx ; es:di -> multiplexer's sign 812 <2> mov cx, 8 ; 16 bytes 813 <2> repe cmpsw ; compare 814 <2> jne .next ; not us --> 815 <2> mov dx, cs ; dx:si -> amis_id 816 <2> mov al, 11h 817 <2> int 2Dh ; CHG: al, bx, cx, dx, si, di 818 <2> cmp al, 0 ; id call supported ? 819 <2> je .unsup ; no, allow if alt version --> 820 <2> pop dx 821 <2> xor dx, dx ; 2D.MM11 supported, mark that we need it 822 <2> push dx 823 <2> cmp al, 0F0h ; CY if below 0F0h 824 <2> jmp .done 825 <2> 826 <2> .next: 827 <2> inc ah ; next multiplex number 828 <2> jnz .loop ; ZR if done, NZ if more to check --> 829 <2> .unsup: 830 <2> stc ; multiplexer not found 831 <2> ; or function not supported 832 <2> .done: 833 <2> ; CY if not an lDOS revision with our id supported, 834 <2> ; on stack: alt_expected_version if it's fine and either 835 <2> ; no multiplexer or func 11h not supported 836 <2> ; new_expected_version if not fine and either 837 <2> ; no multiplexer or func 11h not suppprted, 838 <2> ; 0 if multiplexer found, func 11h supported, but 839 <2> ; our id is unsupported 840 <2> ; NC if lDOS revision with multiplexer and our id supported 841 <2> pop bx 842 <2> pop dx 843 <2> pop di 844 <2> pop es 845 <2> pop si 846 <2> pop ds 847 <2> pop ax 848 <2> jnc alt_good_DOS ; id is supported --> 849 <2> cmp bx, alt_expected_version ; is it fine ? 850 <2> je alt_good_DOS ; yes --> (NC) 851 <2> jmp $MIF25 ; no, cancel program --> 852 <2> 853 <2> $M_VERSION_CHECK PROC NEAR ;;AN000;; 854 <2> ;; 855 <2> MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC 856 <2> INT 21H ;;AN000;; 857 <2> ;; 858 <2> cmp ax,new_expected_version ; compare with DOS version 859 <2> je check_amis 860 <2> cmp ax,alt_expected_version ; compare with DOS version 861 <2> je check_amis 862 <2> CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct 863 <2> ; $IF E ;;AN000;; 864 <2> JNE $MIF25 865 <2> alt_good_DOS: 866 <2> CLC ;;AN000;; Clear the carry flag 867 <2> ; $ELSE ;;AN000;; ELSE 868 <2> JMP SHORT $MEN25 869 <2> $MIF25: 870 <2> %IFN COMR ;; ** Special case for RESIDENT COMMAND.COM 871 <2> CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH 872 <2> ; $IF B ;;AN000;; No, 873 <2> JNB $MIF27 874 <2> MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) 875 <2> ; $ELSE ;;AN000;; Yes, 876 <2> JMP SHORT $MEN27 877 <2> $MIF27: 878 <2> MOV BX,STDERR ;;AN000;; Standard Error 879 <2> ; $ENDIF ;;AN000;; 880 <2> $MEN27: 881 <2> %ELSE 882 <2> MOV BX,NO_HANDLE ;;AN000;; No handle 883 <2> %ENDIF 884 <2> MOV AX,1 ;;AN000;; Set message # 1 885 <2> MOV CX,NO_REPLACE ;;AN000;; No replacable parms 886 <2> MOV DL,NO_INPUT ;;AN000;; No input 887 <2> MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message 888 <2> STC ;;AN000;; Set Carry Flag 889 <2> ; $ENDIF ;;AN000;; 890 <2> $MEN25: 891 <2> ;; 892 <2> RET ;;AN000;; Return 893 <2> ;; 894 <2> $M_VERSION_CHECK ENDP ;; 895 <2> ;; 896 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 897 <2> %ENDIF ;;AN000;; END of include for DOS version check 898 <2> %ENDIF ;;AN000;; END of include for SYSLOADMSG 899 <2> ; 900 <2> %IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 901 <2> %IF COMR ;;AN000;; 902 <2> $M_RT EQU $M_RT2 ;;AN000;; 903 <2> %ENDIF ;;AN000;; 904 <2> GETmsg equ FALSE ;;AN000;; Yes, THEN include it and reset flag 905 <2> ; PAGE 906 <2> ; SUBTTL DOS - Message Retriever - GETMSG.ASM Module 907 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 <2> ;; 909 <2> ;; Proc Name: SYSGETMSG 910 <2> ;; 911 <2> ;; Function: The GET service returns the segment, offset and size of the 912 <2> ;; message text to the caller based on a message number. 913 <2> ;; The GET function will not display the message thus assumes 914 <2> ;; caller will handle replaceable parameters. 915 <2> ;; 916 <2> ;; Inputs: 917 <2> ;; 918 <2> ;; Outputs: 919 <2> ;; 920 <2> ;; Psuedocode: 921 <2> ;; Call $M_GET_MSG_ADDRESS 922 <2> ;; IF MSG_NUM exists THEN 923 <2> ;; Set DS:SI = MSG_TXT_PTR + 1 924 <2> ;; CARRY_FLAG = 0 925 <2> ;; ELSE 926 <2> ;; CARRY_FLAG = 1 927 <2> ;; ENDIF 928 <2> ;; 929 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 <2> ;; 931 <2> %IF FARmsg ;;AN000;; 932 <2> SYSGETMSG PROC FAR ;;AN000;; 933 <2> %ELSE ;;AN000;; 934 <2> SYSGETMSG PROC NEAR ;;AN000;; 935 <2> %ENDIF ;;AN000;; 936 <2> ;; 937 <2> ;; Save registers needed later 938 <2> 939 <2> PUSH AX ;;AN000;; Save changed regs 940 <2> PUSH ES ;;AN000;; 941 <2> PUSH DI ;;AN000;; 942 <2> PUSH BP ;;AN000;; 943 <2> ;; 944 <2> %IF FARmsg ;;AN000;; 945 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 946 <2> %ELSE ;;AN000;; 947 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 948 <2> %ENDIF ;;AN000;; Return message in ES:DI 949 <2> ; $IF NC ;;AN000;; Message found? 950 <2> JC $MIF31 951 <2> CMP DH,UTILITY_MSG_CLASS 952 <2> CLC ;;AN000;; 953 <2> ; $IF NE 954 <2> JE $MIF32 955 <2> PUSH ES ;;AN000;; 956 <2> POP DS ;;AN000;; Return message in DS:SI 957 <2> ; $ELSE 958 <2> JMP SHORT $MEN32 959 <2> $MIF32: 960 <2> %IF FARmsg ;;AN000;; Yes, 961 <2> PUSH ES ;;AN000;; 962 <2> POP DS ;;AN000;; Return message in DS:SI 963 <2> %ELSE ;;AN000;; 964 <2> PUSH CS ;;AN000;; Return message in DS:SI 965 <2> POP DS ;;AN000;; 966 <2> %ENDIF ;;AN000;; 967 <2> ; $ENDIF ;;AN000;; 968 <2> $MEN32: 969 <2> MOV SI,DI ;;AN000;; Return message in DS:SI 970 <2> ; $ENDIF ;;AN000;; 971 <2> $MIF31: 972 <2> ;; 973 <2> POP BP ;;AN000;; Restore changed regs 974 <2> POP DI ;;AN000;; 975 <2> POP ES ;;AN000;; 976 <2> POP AX ;;AN000;; 977 <2> ;; 978 <2> RET ;;AN000;; Return 979 <2> ;; 980 <2> SYSGETMSG ENDP ;; 981 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 982 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 983 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 984 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 985 <2> ;; 986 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 987 <2> ;; 988 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 989 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 990 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 991 <2> ;; IF CX > 1 THEN ES:DI points to the specified message 992 <2> ;; REGS CHANGED: ES,DI,CX 993 <2> ;; 994 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 995 <2> ;; 996 <2> %IF FARmsg ;;AN000;; 997 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 998 <2> %ELSE ;;AN000;; 999 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 1000 <2> %ENDIF ;;AN000;; 1001 <2> ;; 1002 <2> PUSH SI ;;AN000;; 1003 <2> PUSH BX ;;AN000;; 1004 <2> XOR SI,SI ;;AN000;; Use SI as an index 1005 <2> XOR CX,CX ;;AN000;; Use CX as an size 1006 <2> ; $DO ;;AN000;; 1007 <2> $MDO36: 1008 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 1009 <2> ; $IF E ;;AN000;; Yes, 1010 <2> JNE $MIF37 1011 <2> %IF FARmsg ;;AN000;; 1012 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1013 <2> MOV BX,ES ;;AN000; 1014 <2> %ELSE ;;AN000;; 1015 <2> MOV DI,WORD PTR [$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1016 <2> MOV BX,DI ;;AN000; 1017 <2> %ENDIF ;;AN000;; 1018 <2> ; $ELSE ;;AN000;; No, 1019 <2> JMP SHORT $MEN37 1020 <2> $MIF37: 1021 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 1022 <2> ; $IF NE ;;AN000;; Yes, 1023 <2> JE $MIF39 1024 <2> LES DI,[$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 1025 <2> MOV BX,ES ;;AN000; 1026 <2> ; $ELSE ;;AN000;; No, extended errors were specified 1027 <2> JMP SHORT $MEN39 1028 <2> $MIF39: 1029 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 1030 <2> ; $IF AE,AND ;;AN000;; 1031 <2> JNAE $MIF41 1032 <2> CMP AX,$M_CRIT_HI ;;AN000;; 1033 <2> ; $IF BE ;;AN000;; Yes, 1034 <2> JNBE $MIF41 1035 <2> LES DI,[$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 1036 <2> MOV BX,ES ;;AN000; 1037 <2> ; $ELSE ;;AN000;; 1038 <2> JMP SHORT $MEN41 1039 <2> $MIF41: 1040 <2> LES DI,[$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 1041 <2> MOV BX,ES ;;AN000; 1042 <2> ; $ENDIF ;;AN000;; 1043 <2> $MEN41: 1044 <2> ; $ENDIF ;;AN000;; 1045 <2> $MEN39: 1046 <2> ; $ENDIF ;;AN000;; 1047 <2> $MEN37: 1048 <2> ;; 1049 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 1050 <2> ; $IF E ;;AN000;; Yes, 1051 <2> JNE $MIF46 1052 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 1053 <2> ; $IF E ;;AN000;; Yes, 1054 <2> JNE $MIF47 1055 <2> STC ;;AN000;; Set the carry flag 1056 <2> ; $ELSE ;;AN000;; No, 1057 <2> JMP SHORT $MEN47 1058 <2> $MIF47: 1059 <2> MOV [$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 1060 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 1061 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 1062 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 1063 <2> CLC ;;AN000;; 1064 <2> ; $ENDIF ;;AN000;; No, 1065 <2> $MEN47: 1066 <2> ; $ELSE ;;AN000;; 1067 <2> JMP SHORT $MEN46 1068 <2> $MIF46: 1069 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 1070 <2> ; $IF NE ;;AN001;; Yes, 1071 <2> JE $MIF51 1072 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 1073 <2> ; $ENDIF ;;AN000;; 1074 <2> $MIF51: 1075 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 1076 <2> CLC ;;AN000;; 1077 <2> ; $ENDIF ;;AN000;; 1078 <2> $MEN46: 1079 <2> ; $LEAVE C ;;AN000;; 1080 <2> JC $MEN36 1081 <2> OR CX,CX ;;AN000;; Was the message found? 1082 <2> ; $ENDDO NZ,LONG ;;AN000;; 1083 <2> JNZ $MXL2 1084 <2> JMP $MDO36 1085 <2> $MXL2: 1086 <2> $MEN36: 1087 <2> 1088 <2> PUSHF ;;AN006;; Save the flag state 1089 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 1090 <2> ; $IF E ;;AN006;; Yes, 1091 <2> JNE $MIF56 1092 <2> PUSH DX ;;AN006;; Save all needed registers 1093 <2> PUSH BP ;;AN006;; 1094 <2> PUSH CX ;;AN006;; 1095 <2> PUSH ES ;;AN006;; 1096 <2> PUSH DI ;;AN006;; 1097 <2> PUSH AX ;;AN006;; 1098 <2> 1099 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 1100 <2> INT 2FH ;;AN006;; 1101 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 1102 <2> POP AX ;;AN006;; Restore msg number 1103 <2> ; $IF E ;;AN006;; Yes, 1104 <2> JNE $MIF57 1105 <2> MOV BX,AX ;;AN006;; BX is the extended error number 1106 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 1107 <2> INT 2FH ;;AN006;; Call IFSFUNC 1108 <2> ; $ELSE ;;AN006;; No, 1109 <2> JMP SHORT $MEN57 1110 <2> $MIF57: 1111 <2> STC ;;AN006;; Carry conditon 1112 <2> ; $ENDIF ;;AN006;; 1113 <2> $MEN57: 1114 <2> 1115 <2> ; $IF C ;;AN006;; Was there an update? 1116 <2> JNC $MIF60 1117 <2> POP DI ;;AN006;; No, 1118 <2> POP ES ;;AN006;; Restore old pointer 1119 <2> POP CX ;;AN006;; 1120 <2> ; $ELSE ;;AN006;; Yes 1121 <2> JMP SHORT $MEN60 1122 <2> $MIF60: 1123 <2> ADD SP,6 ;;AN006;; Throw away old pointer 1124 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 1125 <2> ; $ENDIF ;;AN006;; 1126 <2> $MEN60: 1127 <2> POP BP ;;AN006;; Restore other Regs 1128 <2> POP DX ;;AN006;; 1129 <2> ; $ENDIF ;;AN006;; 1130 <2> $MIF56: 1131 <2> $M_POPF ;;AN006;; Restore the flag state 1132 <2> 1133 <2> POP BX ;;AN000;; 1134 <2> POP SI ;;AN000;; 1135 <2> RET ;;AN000;; Return ES:DI pointing to the message 1136 <2> ;; 1137 <2> $M_GET_MSG_ADDRESS ENDP ;; 1138 <2> ;; 1139 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 1140 <2> ;; 1141 <2> PUSH DI ;;AN006;; Save position 1142 <2> PUSH AX ;;AN006;; 1143 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 1144 <2> XOR AL,AL ;;AN006;; Prepare compare register 1145 <2> REPNE SCASB ;;AN006;; Scan for zero 1146 <2> NOT CX ;;AN006;; Change decrement into number 1147 <2> DEC CX ;;AN006;; Don't include the zero 1148 <2> POP AX ;;AN006;; 1149 <2> POP DI ;;AN006;; Restore position 1150 <2> RET ;;AN006;; 1151 <2> ;; 1152 <2> $M_SET_LEN_IN_CX ENDP ;; 1153 <2> ;; 1154 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1155 <2> ;; 1156 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 1157 <2> ;; 1158 <2> ;; FUNCTION: To scan thru message headers until message is found 1159 <2> ;; INPUTS: ES:DI points to beginning of msg headers 1160 <2> ;; CX contains the number of messages in class 1161 <2> ;; DH contains the message class 1162 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 1163 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 1164 <2> ;; 1165 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1166 <2> ;; 1167 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 1168 <2> ;; 1169 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 1170 <2> ; $IF E,AND ;;AN004;; Yes, 1171 <2> JNE $MIF64 1172 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 1173 <2> ; $IF NE ;;AN004;; Yes, 1174 <2> JE $MIF64 1175 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 1176 <2> ; $IF E ;;AN004;; . . . and . . . 1177 <2> JNE $MIF65 1178 <2> PUSH AX ;;AN004;; Reset the special message number 1179 <2> MOV AX,[$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 1180 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1181 <2> POP AX ;;AN004;; Reset the special message number 1182 <2> ; $ELSE ;;AN004;; Get the old message number 1183 <2> JMP SHORT $MEN65 1184 <2> $MIF65: 1185 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1186 <2> ; $ENDIF ;;AN004;; Get the old message number 1187 <2> $MEN65: 1188 <2> ; $ELSE ;;AN004;; 1189 <2> JMP SHORT $MEN64 1190 <2> $MIF64: 1191 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 1192 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1193 <2> ; $IF NE ;;AN001;; 1194 <2> JE $MIF69 1195 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 1196 <2> ; $ELSE ;;AN001;; 1197 <2> JMP SHORT $MEN69 1198 <2> $MIF69: 1199 <2> %IF FARmsg ;;AN001;; 1200 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1201 <2> %ELSE 1202 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1203 <2> %ENDIF 1204 <2> ; $IF E ;;AN002;; pointer (hopefully) 1205 <2> JNE $MIF71 1206 <2> %IF FARmsg ;;AN001;; 1207 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1208 <2> %ELSE 1209 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1210 <2> %ENDIF 1211 <2> ; $ENDIF ;;AN002;; go on to the next class 1212 <2> $MIF71: 1213 <2> ; $ENDIF ;;AN001;; 1214 <2> $MEN69: 1215 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 1216 <2> STC ;;AN004;; Flag that we haven't found anything yet 1217 <2> ; $ENDIF ;;AN004;; 1218 <2> $MEN64: 1219 <2> 1220 <2> ; $IF C ;;AN004;; Have we found anything yet? 1221 <2> JNC $MIF75 1222 <2> CLC ;;AN004;; No, reset carry 1223 <2> ; $SEARCH ;;AN000;; 1224 <2> $MDO76: 1225 <2> OR CX,CX ;;AN000;; Do we have any to check? 1226 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1227 <2> JZ $MEN76 1228 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1229 <2> ; $IF NE ;;AN001;; 1230 <2> JE $MIF78 1231 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 1232 <2> ; $ELSE ;;AN001;; 1233 <2> JMP SHORT $MEN78 1234 <2> $MIF78: 1235 <2> %IF FARmsg ;;AN001;; 1236 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 1237 <2> %ELSE 1238 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 1239 <2> %ENDIF 1240 <2> ; $ENDIF 1241 <2> $MEN78: 1242 <2> ; $EXITIF E ;;AN000;; 1243 <2> JNE $MIF76 1244 <2> ; $ORELSE ;;AN000; 1245 <2> JMP SHORT $MSR76 1246 <2> $MIF76: 1247 <2> DEC CX ;;AN000;; No, well do we have more to check? 1248 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1249 <2> JZ $MEN76 1250 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 1251 <2> ; $ENDLOOP ;;AN000;; 1252 <2> JMP SHORT $MDO76 1253 <2> $MEN76: 1254 <2> STC ;;AN000;; 1255 <2> ; $ENDSRCH ;;AN000;; Check next message 1256 <2> $MSR76: 1257 <2> ; $IF NC ;;AN000;; Did we find the message? 1258 <2> JC $MIF86 1259 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 1260 <2> CLC ;;AN001;; 1261 <2> ; $IF E ;;AN001;; 1262 <2> JNE $MIF87 1263 <2> %IF FARmsg ;;AN001;; 1264 <2> %ELSE ;;AN000;; 1265 <2> PUSH CS ;;AN000;; 1266 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 1267 <2> %ENDIF 1268 <2> ; $ENDIF ;;AN001;; 1269 <2> $MIF87: 1270 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 1271 <2> ; $ENDIF ;;AN004;; 1272 <2> $MIF86: 1273 <2> ; $ENDIF ;;AN004;; 1274 <2> $MIF75: 1275 <2> ;; Yes, great we can return with CX > 0 1276 <2> 1277 <2> ; $IF NC ;;AN000;; Did we find the message? 1278 <2> JC $MIF91 1279 <2> XOR CH,CH ;;AN000;; 1280 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 1281 <2> INC DI ;;AN000;; Increment past length 1282 <2> ; $ENDIF ;;AN004;; 1283 <2> $MIF91: 1284 <2> 1285 <2> MOV byte [$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 1286 <2> RET ;;AN000;; Return 1287 <2> ;; 1288 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 1289 <2> ;; 1290 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1291 <2> %ENDIF ;;AN000;; END of include of common subroutines 1292 <2> %ENDIF ;;AN000;; END of include of SYSGETMSG 1293 <2> ; 1294 <2> %IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 1295 <2> %IF COMR ;;AN000;; 1296 <2> $M_RT EQU $M_RT2 ;;AN000;; 1297 <2> %ENDIF ;;AN000;; 1298 <2> %iassign DISPLAYmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 1299 <2> ; PAGE 1300 <2> ; SUBTTL DOS - Message Retriever - DISPMSG.ASM Module 1301 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1302 <2> ;; 1303 <2> ;; Proc Name: SYSDISPMSG 1304 <2> ;; 1305 <2> ;; Function: The DISPLAY service will output a defined message to a handle 1306 <2> ;; requested by the caller. It also provides function to display 1307 <2> ;; messages when handles are not applicable (ie. DOS function calls 1308 <2> ;; 00h to 0Ah) Replaceable parameters are allowed and are 1309 <2> ;; defined previous to entry. 1310 <2> ;; 1311 <2> ;; It is assumes that a PRELOAD function has already determined 1312 <2> ;; the addressibilty internally to the message retriever services. 1313 <2> ;; Inputs: 1314 <2> ;; 1315 <2> ;; Outputs: 1316 <2> ;; 1317 <2> ;; Psuedocode: 1318 <2> ;; Save registers needed later 1319 <2> ;; Get address of the message requested 1320 <2> ;; IF Message number exists THEN 1321 <2> ;; IF replacable parameters were specified THEN 1322 <2> ;; Display message with replacable parms 1323 <2> ;; ELSE 1324 <2> ;; Display string without replacable parms 1325 <2> ;; ENDIF 1326 <2> ;; IF character input was requested THEN 1327 <2> ;; Wait for character input 1328 <2> ;; ENDIF 1329 <2> ;; Clear CARRY FLAG 1330 <2> ;; ELSE 1331 <2> ;; Set CARRY FLAG 1332 <2> ;; ENDIF 1333 <2> ;; Return 1334 <2> ;; 1335 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1336 <2> ;; 1337 <2> %IF FARmsg ;;AN000;; 1338 <2> SYSDISPMSG PROC FAR ;;AN000;; 1339 <2> %ELSE ;;AN000;; 1340 <2> SYSDISPMSG PROC NEAR ;;AN000;; 1341 <2> %ENDIF ;;AN000;; 1342 <2> ;; 1343 <2> ;; Save registers and values needed later 1344 <2> 1345 <2> PUSH AX ;;AN000;; Save changed REGs 1346 <2> PUSH BX ;;AN000;; 1347 <2> PUSH CX ;;AN000;; 1348 <2> PUSH BP ;;AN000;; 1349 <2> PUSH DI ;;AN000;; Save pointer to input buffer (offset) 1350 <2> PUSH ES ;;AN000;; Save pointer to input buffer (segment) 1351 <2> PUSH DX ;;AN000;; Save Input/Class request 1352 <2> 1353 <2> MOV BP,CX ;;AN000;; Use BP to hold replace count 1354 <2> MOV WORD PTR [cs:$M_RT + $M_HANDLE],BX ;;AN000;; Save handle 1355 <2> MOV BYTE PTR [cs:$M_RT + $M_CLASS],DH ;;AN004;; Save class 1356 <2> 1357 <2> ;; Get address of the message requested 1358 <2> 1359 <2> %IF FARmsg ;;AN000;; 1360 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1361 <2> %ELSE ;;AN000;; 1362 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1363 <2> %ENDIF ;;AN000;; 1364 <2> OR CX,CX ;;AN000;; Was message found? 1365 <2> ; $IF NZ ;;AN000;; YES, Message address in ES:DI 1366 <2> JZ $MIF93 1367 <2> 1368 <2> ;; Test if replacable parameters were specified 1369 <2> 1370 <2> OR BP,BP ;;AN000;; Were replacable parameters requested 1371 <2> ; $IF Z ;;AN000;; 1372 <2> JNZ $MIF94 1373 <2> 1374 <2> ;; Display string without replacable parms 1375 <2> 1376 <2> CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message 1377 <2> ; $ELSE ;;AN000;; 1378 <2> JMP SHORT $MEN94 1379 <2> $MIF94: 1380 <2> %IF $M_REPLACE ;;AN000;; 1381 <2> 1382 <2> ;; Display message with replacable parms 1383 <2> 1384 <2> CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions 1385 <2> %ENDIF ;;AN000;; 1386 <2> ; $ENDIF ;;AN000;; 1387 <2> $MEN94: 1388 <2> ; $IF NC 1389 <2> JC $MIF97 1390 <2> 1391 <2> POP DX ;;AN000;; Get Input/Class request 1392 <2> 1393 <2> CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. 1394 <2> 1395 <2> POP ES ;;AN000;; Get location of input buffer (if specified) 1396 <2> POP DI ;;AN000;; 1397 <2> 1398 <2> ;; Test if character input was requested 1399 <2> 1400 <2> %IF INPUTmsg ;;AN000;; 1401 <2> OR DL,DL ;;AN000;; Was Wait-For-Input requested? 1402 <2> ; $IF NZ ;;AN000;; 1403 <2> JZ $MIF98 1404 <2> CALL $M_WAIT_FOR_INPUT ;;AN000;; 1405 <2> ; $ENDIF ;;AN000;; 1406 <2> $MIF98: 1407 <2> %ENDIF ;;AN000;; 1408 <2> ; $ELSE ;;AN000;; 1409 <2> JMP SHORT $MEN97 1410 <2> $MIF97: 1411 <2> ADD SP,6 ;;AN000;; 1412 <2> STC ;;AN000;; Reset carry flag 1413 <2> ; $ENDIF ;;AN000;; 1414 <2> $MEN97: 1415 <2> ; $ELSE ;;AN000;; No, 1416 <2> JMP SHORT $MEN93 1417 <2> $MIF93: 1418 <2> POP ES ;;AN000;; Get pointer to input buffer (segment) 1419 <2> POP DI ;;AN000;; Get base pointer to first sublist (offset) 1420 <2> POP DX ;;AN000;; Get base pointer to first sublist (segment) 1421 <2> STC ;;AN000;; Set carry flag 1422 <2> ; $ENDIF ;;AN000;; 1423 <2> $MEN93: 1424 <2> ;; 1425 <2> ; $IF NC ;;AN000;; Was there an error? 1426 <2> JC $MIF104 1427 <2> POP BP ;;AN000;; No, 1428 <2> POP CX ;;AN000;; 1429 <2> POP BX ;;AN000;; 1430 <2> %IF INPUTmsg ;;AN000;; 1431 <2> ADD SP,2 ;;AN000;; 1432 <2> %ELSE ;AN000; 1433 <2> POP AX ;;AN000;; 1434 <2> %ENDIF ;;AN000;; 1435 <2> ; $ELSE ;;AN000;; Yes, 1436 <2> JMP SHORT $MEN104 1437 <2> $MIF104: 1438 <2> ADD SP,8 ;;AN000;; Eliminate from stack 1439 <2> STC ;;AN000;; 1440 <2> ; $ENDIF ;;AN000;; 1441 <2> $MEN104: 1442 <2> ;; 1443 <2> RET ;;AN000;; Return 1444 <2> ;; 1445 <2> SYSDISPMSG ENDP ;;AN000;; 1446 <2> ;; 1447 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1448 <2> ; 1449 <2> ;; 1450 <2> ;; PROC NAME: $M_DISPLAY_STRING 1451 <2> ;; 1452 <2> ;; FUNCTION: Will display or write string 1453 <2> ;; INPUTS: ES:DI points to beginning of message 1454 <2> ;; CX contains the length of string to write (if applicable) 1455 <2> ;; OUTPUTS: None 1456 <2> ;; REGS Revised: None 1457 <2> ;; 1458 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1459 <2> ;; 1460 <2> $M_DISPLAY_STRING PROC NEAR ;;AN000;; 1461 <2> ;; 1462 <2> PUSH AX ;;AN000;; 1463 <2> PUSH BX ;;AN000;; 1464 <2> PUSH DX ;;AN000;; 1465 <2> ;; 1466 <2> MOV BX,[cs:$M_RT + $M_HANDLE] ;;AN000;; Retrieve handle 1467 <2> ;; 1468 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 1469 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1470 <2> %ELSE 1471 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1472 <2> ; $IF E ;;AN000;; 1473 <2> JNE $MIF107 1474 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1475 <2> ; $ELSE ;;AN000;; 1476 <2> JMP SHORT $MEN107 1477 <2> $MIF107: 1478 <2> CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle 1479 <2> ; $ENDIF ;;AN000;; 1480 <2> $MEN107: 1481 <2> ;AN001; 1482 <2> ; $IF C ;;AN000;; Was there an error? 1483 <2> JNC $MIF110 1484 <2> MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, 1485 <2> MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error 1486 <2> INT 21H ;;AN000;; 1487 <2> XOR AH,AH ;;AN000;; Clear AH 1488 <2> ADD SP,6 ;;AN000;; Clean up stack 1489 <2> STC ;;AN000;; Flag that there was an error 1490 <2> ; $ELSE ;;AN000;; No, 1491 <2> JMP SHORT $MEN110 1492 <2> $MIF110: 1493 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1494 <2> ; $IF NE ;;AN000;; 1495 <2> JE $MIF112 1496 <2> CMP AX,CX ;AN001; Was it ALL written? 1497 <2> ; $IF NE ;AN001; No, 1498 <2> JE $MIF113 1499 <2> CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error 1500 <2> ADD SP,6 ;AN001; Clean up stack 1501 <2> STC ;AN001; Flag that there was an error 1502 <2> ; $ENDIF ;AN001; 1503 <2> $MIF113: 1504 <2> ; $ENDIF ;AN001; 1505 <2> $MIF112: 1506 <2> ; $ENDIF ;;AN000;; 1507 <2> $MEN110: 1508 <2> %ENDIF 1509 <2> ; $IF NC ;;AN000;; Was there ANY error? 1510 <2> JC $MIF117 1511 <2> POP DX ;;AN000;; Restore regs 1512 <2> POP BX ;;AN000;; 1513 <2> POP AX ;;AN000;; 1514 <2> ; $ENDIF ;;AN000;; 1515 <2> $MIF117: 1516 <2> RET ;;AN000;; Return 1517 <2> ;; 1518 <2> $M_DISPLAY_STRING ENDP ;;AN000;; 1519 <2> ;; 1520 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1521 <2> ;; 1522 <2> ;; PROC NAME: $M_DISPLAY_$_STRING 1523 <2> ;; 1524 <2> ;; FUNCTION: Will display a $ terminated string 1525 <2> ;; INPUTS: ES:DI points to beginning of message text (not the length) 1526 <2> ;; OUPUTS: None 1527 <2> ;; REGS USED: AX,DX 1528 <2> ;; 1529 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1530 <2> ;; 1531 <2> $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; 1532 <2> ;; 1533 <2> PUSH DS ;;AN000;; 1534 <2> PUSH ES ;;AN000;; 1535 <2> POP DS ;;AN000;; Set DS to segment of message text 1536 <2> %IFN COMR 1537 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1538 <2> ; $IF E ;;AN000;; Yes, 1539 <2> JNE $MIF119 1540 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1541 <2> MOV DL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1542 <2> INT 21H ;;AN000;; Write character 1543 <2> POP DS ;;AN000;; Set DS to segment of message text 1544 <2> MOV AL,DL ;;AN000;; Get the character in AL 1545 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1546 <2> PUSH DS ;;AN000;; 1547 <2> PUSH ES ;;AN000;; 1548 <2> POP DS ;;AN000;; Set DS to segment of message text 1549 <2> ; $IF C ;;AN000;; Yes, 1550 <2> JNC $MIF120 1551 <2> MOV DL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 1552 <2> INT 21H ;;AN000;; Write character 1553 <2> CLC ;;AN000;; Clear the DBCS indicator 1554 <2> ; $ENDIF ;;AN000;; 1555 <2> $MIF120: 1556 <2> ; $ELSE ;;AN000;; No, 1557 <2> JMP SHORT $MEN119 1558 <2> $MIF119: 1559 <2> %ENDIF 1560 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1561 <2> ; $DO ;;AN002;; No, 1562 <2> $MDO123: 1563 <2> OR CX,CX ;;AN002;; Are there any left to display? 1564 <2> ; $LEAVE Z ;;AN002;; Yes, 1565 <2> JZ $MEN123 1566 <2> MOV DL,BYTE PTR [ES:DI] ;;AN002;; Get the character 1567 <2> INT 21H ;;AN002;; Display the character 1568 <2> INC DI ;;AN002;; Set pointer to next character 1569 <2> DEC CX ;;AN002;; Count this character 1570 <2> ; $ENDDO Z ;;AN002;; No, 1571 <2> JNZ $MDO123 1572 <2> $MEN123: 1573 <2> %IFN COMR 1574 <2> ; $ENDIF ;;AN000;; 1575 <2> $MEN119: 1576 <2> %ENDIF 1577 <2> CLC ;;AN000;; Char functions used don't return carry as error 1578 <2> POP DS ;;AN000;; 1579 <2> RET ;;AN000;; 1580 <2> ;; 1581 <2> $M_DISPLAY_$_STRING ENDP ;;AN000;; 1582 <2> ;; 1583 <2> %IFN COMR 1584 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1585 <2> ;; 1586 <2> ;; PROC NAME: $M_DISPLAY_H_STRING 1587 <2> ;; 1588 <2> ;; FUNCTION: Will display a string to a specified handle 1589 <2> ;; INPUTS: ES:DI points to beginning of message 1590 <2> ;; CX contains the number of bytes to write 1591 <2> ;; BX contains the handle to write to 1592 <2> ;; OUPUTS: None 1593 <2> ;; REGS USED: AX,DX 1594 <2> ;; 1595 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1596 <2> ;; 1597 <2> $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; 1598 <2> ;; 1599 <2> XOR AX,AX ;;AN002;; Set number of bytes written to 0 1600 <2> OR CX,CX ;;AN002;; For performance, don't write if not necessary 1601 <2> ; $IF NZ ;;AN002;; Any chars to write? 1602 <2> JZ $MIF127 1603 <2> PUSH DS ;;AN000;; Yes, 1604 <2> PUSH ES ;;AN000;; 1605 <2> POP DS ;;AN000;; Set DS to segment of message text 1606 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1607 <2> MOV DX,DI ;;AN000;; Pointer to data to write 1608 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1609 <2> ; $IF E ;;AN000;; Yes, 1610 <2> JNE $MIF128 1611 <2> INT 21H ;;AN000;; Write character 1612 <2> POP DS ;;AN000;; Set DS to segment of message text 1613 <2> PUSH AX ;;AN000;; 1614 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1615 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1616 <2> POP AX ;;AN000;; Set DS to segment of message text 1617 <2> PUSH DS ;;AN000;; 1618 <2> PUSH ES ;;AN000;; 1619 <2> POP DS ;;AN000;; Set DS to segment of message text 1620 <2> ; $IF C ;;AN000;; Yes, 1621 <2> JNC $MIF129 1622 <2> CLC ;;AN000;; Clear the DBCS indicator 1623 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1624 <2> INC DX ;;AN000;; Point to next character 1625 <2> INT 21H ;;AN000;; Write character 1626 <2> ; $ENDIF ;;AN000;; 1627 <2> $MIF129: 1628 <2> ; $ELSE ;;AN000;; No, 1629 <2> JMP SHORT $MEN128 1630 <2> $MIF128: 1631 <2> INT 21H ;;AN000;; Write String at DS:SI to handle 1632 <2> ; $ENDIF ;;AN000;; 1633 <2> $MEN128: 1634 <2> POP DS ;;AN000;; 1635 <2> ; $ENDIF ;;AN002;; 1636 <2> $MIF127: 1637 <2> ;; 1638 <2> RET ;;AN000;; 1639 <2> ;; 1640 <2> $M_DISPLAY_H_STRING ENDP ;;AN000;; 1641 <2> ;; 1642 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1643 <2> ;; 1644 <2> ;; PROC NAME: $M_GET_EXT_ERR_39 1645 <2> ;; 1646 <2> ;; FUNCTION: Will set registers for extended error #39 1647 <2> ;; INPUTS: None 1648 <2> ;; OUPUTS: AX,BX,CX set 1649 <2> ;; REGS USED: 1650 <2> ;; 1651 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1652 <2> ;; 1653 <2> $M_GET_EXT_ERR_39 PROC NEAR ;AN001; 1654 <2> ;; 1655 <2> MOV AX,EXT_ERR_39 ;AN001; Set AX=39 1656 <2> MOV BX,(ERROR_CLASS_39 >> 8) + ACTION_39 ;AN001; Set BH=1 BL=4 1657 <2> MOV CH,LOCUS_39 ;AN001; Set CH=1 1658 <2> ;AN001; 1659 <2> RET ;AN001; 1660 <2> ;; 1661 <2> $M_GET_EXT_ERR_39 ENDP ;AN001; 1662 <2> ;; 1663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1664 <2> %ENDIF 1665 <2> ;; 1666 <2> ;; PROC NAME: $M_ADD_CRLF 1667 <2> ;; 1668 <2> ;; FUNCTION: Will decide whether to display a CRLF 1669 <2> ;; INPUTS: DX contains the Input/Class requested 1670 <2> ;; OUTPUTS: None 1671 <2> ;; REGS Revised: CX,ES,DI 1672 <2> ;; 1673 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1674 <2> ;; 1675 <2> $M_ADD_CRLF PROC NEAR ;;AN004;; 1676 <2> ;; 1677 <2> CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1678 <2> ; $IF NE ;;AN004;; No, 1679 <2> JE $MIF134 1680 <2> TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? 1681 <2> ; $IF Z ;;AN004;; No, 1682 <2> JNZ $MIF135 1683 <2> PUSH DS ;;AN004;; 1684 <2> POP ES ;;AN004;; Set ES to data segment 1685 <2> LEA DI,[$M_RT + $M_CRLF] ;;AN004;; Point at CRLF message 1686 <2> MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size 1687 <2> CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF 1688 <2> ; $ENDIF ;;AN004;; 1689 <2> $MIF135: 1690 <2> ; $ENDIF ;;AN004;; 1691 <2> $MIF134: 1692 <2> RET ;;AN004;; Return 1693 <2> ;; 1694 <2> $M_ADD_CRLF ENDP ;;AN004;; 1695 <2> ;; 1696 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1697 <2> ;; 1698 <2> ;; PROC NAME: $M_IS_IT_DBCS 1699 <2> ;; 1700 <2> ;; FUNCTION: Will decide whether character is Single or Double Byte 1701 <2> ;; INPUTS: AL contains the byte to be checked 1702 <2> ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range 1703 <2> ;; Carry flag = 1 if byte IS in DBCS range 1704 <2> ;; REGS USED: All restored 1705 <2> ;; 1706 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1707 <2> ;; 1708 <2> $M_IS_IT_DBCS PROC NEAR ;;AN000;; 1709 <2> ;; 1710 <2> PUSH ES ;;AN000;; Save Extra segment register 1711 <2> PUSH DI ;;AN000;; Save SI register 1712 <2> ;; 1713 <2> LES DI,[cs:$M_RT + $M_DBCS_VEC] ;;AN000;; 1714 <2> OR DI,DI ;;AN000;; Was the DBCS vector set? 1715 <2> ; $IF NZ ;;AN000;; 1716 <2> JZ $MIF138 1717 <2> ; $DO ;;AN000;; 1718 <2> $MDO139: 1719 <2> CMP WORD PTR [ES:DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? 1720 <2> CLC ;;AN000;; 1721 <2> ; $LEAVE E ;;AN000;; 1722 <2> JE $MEN139 1723 <2> ;; No, 1724 <2> CMP AL,BYTE PTR [ES:DI] ;;AN000;; Does the character fall in the DBCS range? 1725 <2> ; $IF AE,AND ;;AN000;; 1726 <2> JNAE $MIF141 1727 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Does the character fall in the DBCS range? 1728 <2> ; $IF BE ;;AN000;; 1729 <2> JNBE $MIF141 1730 <2> STC ;;AN000;; Yes, 1731 <2> ; $ENDIF ;;AN000;; Set carry flag 1732 <2> $MIF141: 1733 <2> INC DI ;;AN000;; No, 1734 <2> INC DI ;;AN000;; Go to next vector 1735 <2> ; $ENDDO ;;AN000;; 1736 <2> JMP SHORT $MDO139 1737 <2> $MEN139: 1738 <2> ; $ENDIF ;;AN000;; 1739 <2> $MIF138: 1740 <2> 1741 <2> POP DI ;;AN000;; 1742 <2> POP ES ;;AN000;; Restore SI register 1743 <2> RET ;;AN000;; Return 1744 <2> ;; 1745 <2> $M_IS_IT_DBCS ENDP ;;AN000;; 1746 <2> ;; 1747 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1748 <2> ;; 1749 <2> ;; PROC NAME: $M_CONVERT2ASC 1750 <2> ;; 1751 <2> ;; FUNCTION: Convert a binary number to a ASCII string 1752 <2> ;; INPUTS: DX:AX contains the number to be converted 1753 <2> ;; $M_RT_DIVISOR contains the divisor 1754 <2> ;; OUPUTS: CX contains the number of characters 1755 <2> ;; Top of stack --> Last character 1756 <2> ;; . . . 1757 <2> ;; Bot of stack --> First character 1758 <2> ;; REGS USED: 1759 <2> ;; 1760 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1761 <2> ;; 1762 <2> $M_CONVERT2ASC PROC NEAR ;;AN000;; 1763 <2> ;; 1764 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Save Return Address 1765 <2> XOR BX,BX ;;AN000;; Use BP as a swapping register 1766 <2> ;; 1767 <2> XCHG BX,AX ;;AN000;; Initialize - Low Word in BP 1768 <2> XCHG AX,DX ;;AN000;; - High Word in AX 1769 <2> ; $DO ;;AN000;; DO UNTIL Low Word becomes zero 1770 <2> $MDO145: 1771 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide High Word by divisor 1772 <2> XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder 1773 <2> ;; and save reduced High Word in BP 1774 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide Low Word by divisor 1775 <2> CMP DX,9 ;;AN000;; Make a digit of the remainder 1776 <2> ; $IF A ;;AN000;; IF 10 to 15, 1777 <2> JNA $MIF146 1778 <2> ADD DL,55 ;;AN000;; Make A to F ASCII 1779 <2> ; $ELSE ;;AN000;; IF 0 to 9, 1780 <2> JMP SHORT $MEN146 1781 <2> $MIF146: 1782 <2> ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII 1783 <2> ; $ENDIF ;;AN000;; 1784 <2> $MEN146: 1785 <2> PUSH DX ;;AN000;; Save the digit on the stack 1786 <2> INC CX ;;AN000;; Count that digit 1787 <2> OR AX,AX ;;AN000;; Are we done? 1788 <2> ; $LEAVE Z,AND ;;AN000;; 1789 <2> JNZ $MLL149 1790 <2> OR BX,BX ;;AN000;; AX and BX must be ZERO!! 1791 <2> ; $LEAVE Z ;;AN000;; No, 1792 <2> JZ $MEN145 1793 <2> $MLL149: 1794 <2> %IFN COMR 1795 <2> CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark 1796 <2> ; $IF E ;;AN000;; Yes, 1797 <2> JNE $MIF150 1798 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1799 <2> ; $IF E ;;AN000;; Yes, 1800 <2> JNE $MIF151 1801 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1802 <2> INC CX ;;AN000;; 1803 <2> ; $ENDIF ;;AN000;; 1804 <2> $MIF151: 1805 <2> ; $ELSE ;;AN000;; No, 1806 <2> JMP SHORT $MEN150 1807 <2> $MIF150: 1808 <2> CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark 1809 <2> ; $IF E ;;AN000;; Yes, 1810 <2> JNE $MIF154 1811 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1812 <2> ; $IF E ;;AN000;; Yes, 1813 <2> JNE $MIF155 1814 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1815 <2> INC CX ;;AN000;; 1816 <2> ; $ENDIF ;;AN000;; 1817 <2> $MIF155: 1818 <2> ; $ELSE ;;AN000;; No, 1819 <2> JMP SHORT $MEN154 1820 <2> $MIF154: 1821 <2> CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark 1822 <2> ; $IF E ;;AN000;; Yes, 1823 <2> JNE $MIF158 1824 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1825 <2> ; $IF E ;;AN000;; Yes, 1826 <2> JNE $MIF159 1827 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1828 <2> INC CX ;;AN000;; 1829 <2> ; $ENDIF ;;AN000;; 1830 <2> $MIF159: 1831 <2> ; $ENDIF ;;AN000;; 1832 <2> $MIF158: 1833 <2> ; $ENDIF ;;AN000;; 1834 <2> $MEN154: 1835 <2> ; $ENDIF ;;AN000;; 1836 <2> $MEN150: 1837 <2> %ENDIF 1838 <2> XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word 1839 <2> ;;AN000;; and Revised Low Word 1840 <2> XOR DX,DX ;;AN000;; Reset remainder 1841 <2> ; $ENDDO ;;AN000;; NEXT 1842 <2> JMP SHORT $MDO145 1843 <2> $MEN145: 1844 <2> ;;AN000;; Yes, 1845 <2> XOR DX,DX ;;AN000;; Reset remainder 1846 <2> XOR AX,AX ;;AN000;; Reset remainder 1847 <2> PUSH word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Restore Return Address 1848 <2> RET ;;AN000;; Return 1849 <2> ;; 1850 <2> $M_CONVERT2ASC ENDP ;;AN000;; 1851 <2> ;; 1852 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1853 <2> ;; 1854 <2> ;; PROC NAME: $M_DISPLAY_MESSAGE 1855 <2> ;; 1856 <2> ;; FUNCTION: Will display or write entire message (with replacable parameters) 1857 <2> ;; INPUTS: ES:DI points to beginning of message 1858 <2> ;; DS:SI points to first sublist structure in chain 1859 <2> ;; BX contains the handle to write to (if applicable) 1860 <2> ;; CX contains the length of string to write (before substitutions) 1861 <2> ;; BP contains the count of replacables 1862 <2> ;; 1863 <2> ;; OUTPUTS: 1864 <2> ;; REGS USED: All 1865 <2> ;; 1866 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1867 <2> ;; 1868 <2> $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; 1869 <2> ;; 1870 <2> ; $DO ;;AN000;; Note: DS:SI -> message 1871 <2> $MDO165: 1872 <2> XOR DX,DX ;;AN000;; Set size = 0 1873 <2> OR CX,CX ;;AN000;; Are we finished the message yet? 1874 <2> ; $IF NZ ;;AN000;; No, 1875 <2> JZ $MIF166 1876 <2> MOV AH,"%" ;;AN000;; Prepare to scan for % 1877 <2> MOV AL,0 ;;AN004;; 1878 <2> ;; 1879 <2> ; $DO ;;AN000;; Scan through string until % 1880 <2> $MDO167: 1881 <2> CMP BYTE PTR [ES:DI],AH ;;AN000;; Is this character NOT a % 1882 <2> ; $LEAVE E,AND ;;AN000;; No, 1883 <2> JNE $MLL168 1884 <2> CMP BYTE PTR [ES:DI+1],AH ;;AN000;; Is the next character also a % 1885 <2> ; $LEAVE NE,AND ;;AN000;; No, 1886 <2> JE $MLL168 1887 <2> CMP AL,AH ;;AN000;; Was the character before a % 1888 <2> ; $LEAVE NE ;;AN000;; No, GREAT found it 1889 <2> JNE $MEN167 1890 <2> $MLL168: 1891 <2> MOV AL,BYTE PTR [ES:DI] ;;AN004;; Yes, (to any of the above) 1892 <2> CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? 1893 <2> ; $IF C ;;AN004;; Yes, 1894 <2> JNC $MIF169 1895 <2> INC DI ;;AN004;; Increment past second part 1896 <2> ; $ENDIF ;;AN004;; 1897 <2> $MIF169: 1898 <2> INC DI ;;AN000;; Next character in string 1899 <2> INC DX ;;AN000;; Size = Size + 1 1900 <2> DEC CX ;;AN000;; Decrement total size 1901 <2> ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line 1902 <2> JNZ $MDO167 1903 <2> $MEN167: 1904 <2> ; $ENDIF ;;AN000;; 1905 <2> $MIF166: 1906 <2> ;; 1907 <2> PUSH SI ;;AN000;; Save beginning of sublists 1908 <2> XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) 1909 <2> OR BP,BP ;;AN000;; Do we have any replacables to do? 1910 <2> ; $IF NZ ;;AN000;; Yes, 1911 <2> JZ $MIF173 1912 <2> DEC BP ;;AN000;; Decrement number of replacables 1913 <2> 1914 <2> ;; Search through sublists to find applicable one 1915 <2> 1916 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 1917 <2> ; $IF E ;;AN000;; No, 1918 <2> JNE $MIF174 1919 <2> ; $SEARCH ;;AN000;; 1920 <2> $MDO175: 1921 <2> MOV AL,[$M_SL + $M_S_ID] ;;AN000;; Get ID byte 1922 <2> ADD AL,30H ;;AN000;; Convert to ASCII 1923 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Is this the right sublist? 1924 <2> ; $EXITIF E ;;AN000;; 1925 <2> JNE $MIF175 1926 <2> ; $ORELSE ;;AN000;; No, 1927 <2> JMP SHORT $MSR175 1928 <2> $MIF175: 1929 <2> CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 1930 <2> ; $LEAVE E,AND ;;AN000;; Yes, 1931 <2> JNE $MLL178 1932 <2> OR DX,DX ;;AN000;; Are we at the end of the message? 1933 <2> ; $LEAVE Z ;;AN000;; No, 1934 <2> JZ $MEN175 1935 <2> $MLL178: 1936 <2> ADD SI,WORD PTR [$M_SL + $M_S_SIZE] ;;AN000;; Next SUBLIST 1937 <2> ; $ENDLOOP ;;AN000;; Yes, 1938 <2> JMP SHORT $MDO175 1939 <2> $MEN175: 1940 <2> CMP byte [cs:$M_RT + $M_CLASS],UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1941 <2> ; $IF E ;;AN004;; Yes, 1942 <2> JNE $MIF180 1943 <2> INC DX ;;AN000;; Remember to display CR,LF 1944 <2> INC DX ;;AN000;; at the end of the message 1945 <2> DEC CX ;;AN000;; Adjust message length 1946 <2> DEC CX ;;AN000;; 1947 <2> DEC DI ;;AN000;; Adjust ending address of message 1948 <2> DEC DI ;;AN000;; 1949 <2> ; $ELSE ;;AN004;; No, 1950 <2> JMP SHORT $MEN180 1951 <2> $MIF180: 1952 <2> MOV DX,-1 ;;AN004;; Set special case 1953 <2> ; $ENDIF ;;AN004;; 1954 <2> $MEN180: 1955 <2> ; $ENDSRCH ;;AN000;; 1956 <2> $MSR175: 1957 <2> ; $ENDIF ;;AN000;; 1958 <2> $MIF174: 1959 <2> ; $ENDIF ;;AN000;; 1960 <2> $MIF173: 1961 <2> 1962 <2> ;; Prepare and display this part of message 1963 <2> 1964 <2> PUSH DI ;;AN000;; Save pointer to replace number 1965 <2> SUB DI,CX ;;AN000;; Determine beginning of string 1966 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) 1967 <2> POP DI ;;AN000;; Get back pointer to replace number 1968 <2> POP CX ;;AN000;; Clean up stack in case error 1969 <2> ; $LEAVE C,LONG ;;AN000;; Fail if carry was set 1970 <2> JNC $MXL3 1971 <2> JMP $MEN165 1972 <2> nop ; identicalise 1973 <2> $MXL3: 1974 <2> PUSH CX ;;AN000;; 1975 <2> 1976 <2> ;; Save and reset pointer registers 1977 <2> 1978 <2> MOV CX,DX ;;AN000;; Get the size of the rest of the message 1979 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? 1980 <2> ; $IF NE ;;AN000;; No, 1981 <2> JE $MIF187 1982 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1983 <2> ; $IF NZ ;;AN000;; No, 1984 <2> JZ $MIF188 1985 <2> DEC CX ;;AN000;; Decrement total size (%) 1986 <2> DEC CX ;;AN000;; Decrement total size (#) 1987 <2> INC DI ;;AN000;; Go past % 1988 <2> INC DI ;;AN000;; Go past replace number 1989 <2> ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) 1990 <2> JMP SHORT $MEN188 1991 <2> $MIF188: 1992 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 1993 <2> ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC 1994 <2> $MEN188: 1995 <2> ; $ELSE ;;AN000;; 1996 <2> JMP SHORT $MEN187 1997 <2> $MIF187: 1998 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1999 <2> ; $IF Z ;;AN004;; No, 2000 <2> JNZ $MIF192 2001 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 2002 <2> ; $ELSE ;;AN000;; No, 2003 <2> JMP SHORT $MEN192 2004 <2> $MIF192: 2005 <2> CMP CX,-1 ;;AN004;; Are we at the end of the message? 2006 <2> ; $IF Z ;;AN004;; No, 2007 <2> JNZ $MIF194 2008 <2> XOR CX,CX ;;AN004;; 2009 <2> ; $ENDIF ;;AN000;; 2010 <2> $MIF194: 2011 <2> OR DI,DI ;;AN004;; Turn ZF off 2012 <2> ; $ENDIF ;;AN000;; 2013 <2> $MEN192: 2014 <2> ; $ENDIF ;;AN000;; Note this will not leave because INC 2015 <2> $MEN187: 2016 <2> ; $LEAVE Z ;;AN000;; 2017 <2> JZ $MEN165 2018 <2> PUSH BP ;;AN000;; Save the replace count 2019 <2> PUSH DI ;;AN000;; Save location to complete message 2020 <2> PUSH ES ;;AN000;; 2021 <2> PUSH CX ;;AN000;; Save size of the rest of the message 2022 <2> XOR CX,CX ;;AN000;; Reset CX used for character count 2023 <2> 2024 <2> ;; Determine what action is required on parameter 2025 <2> 2026 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2027 <2> ; $IF E ;;AN000;; 2028 <2> JNE $MIF199 2029 <2> 2030 <2> %IF CHARmsg ;;AN000;; Was Char specified? 2031 <2> Char_Type equ Char_type ; NASM port equate 2032 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2033 <2> ; $IF Z ;;AN000;; 2034 <2> JNZ $MIF200 2035 <2> 2036 <2> ;; Character type requested 2037 <2> ;;AN000;; 2038 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2039 <2> CALL $M_CHAR_REPLACE ;;AN000;; 2040 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2041 <2> JMP SHORT $MEN200 2042 <2> $MIF200: 2043 <2> %ENDIF ;;AN000;; 2044 <2> %IF NUMmsg ;;AN000;; Was Nnmeric type specified? 2045 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2046 <2> ; $IF Z,OR ;;AN000;; 2047 <2> JZ $MLL202 2048 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2049 <2> ; $IF Z,OR ;;AN000;; 2050 <2> JZ $MLL202 2051 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Bin_Hex_Type & $M_TYPE_MASK ;;AN000;; 2052 <2> ; $IF Z ;;AN000;; 2053 <2> JNZ $MIF202 2054 <2> $MLL202: 2055 <2> 2056 <2> ;; Numeric type requested 2057 <2> 2058 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2059 <2> CALL $M_BIN2ASC_REPLACE ;;AN000;; 2060 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2061 <2> JMP SHORT $MEN202 2062 <2> $MIF202: 2063 <2> %ENDIF ;;AN000;; 2064 <2> %IF DATEmsg ;;AN000;; Was date specified? 2065 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Date_Type & $M_TYPE_MASK ;;AN000;; 2066 <2> ; $IF E ;;AN000;; 2067 <2> JNE $MIF204 2068 <2> 2069 <2> ;; Date type requested 2070 <2> 2071 <2> CALL $M_DATE_REPLACE ;;AN000;; 2072 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2073 <2> JMP SHORT $MEN204 2074 <2> $MIF204: 2075 <2> %ENDIF ;;AN000;; 2076 <2> %IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? 2077 <2> 2078 <2> ;; Time type requested (Default if we have not matched until here) 2079 <2> 2080 <2> CALL $M_TIME_REPLACE ;;AN000;; 2081 <2> %ENDIF ;;AN000;; 2082 <2> 2083 <2> %IF DATEmsg ;;AN000;; 2084 <2> ; $ENDIF ;;AN000;; 2085 <2> $MEN204: 2086 <2> %ENDIF ;;AN000;; 2087 <2> %IF NUMmsg ;;AN000;; 2088 <2> ; $ENDIF ;;AN000;; 2089 <2> $MEN202: 2090 <2> %ENDIF ;;AN000;; 2091 <2> %IF CHARmsg ;;AN000;; 2092 <2> ; $ENDIF ;;AN000;; 2093 <2> $MEN200: 2094 <2> %ENDIF ;;AN000;; 2095 <2> 2096 <2> %IF $M_REPLACE ;;AN000;; 2097 <2> ;; With the replace information of the Stack, display the replaceable field 2098 <2> 2099 <2> CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace 2100 <2> %ENDIF ;;AN000;; 2101 <2> ;; None of the above - Extended/Parse replace 2102 <2> ; $ELSE ;;AN000;; 2103 <2> JMP SHORT $MEN199 2104 <2> $MIF199: 2105 <2> %IFN COMR 2106 <2> CALL $M_EXT_PAR_REPLACE ;;AN000;; 2107 <2> %ENDIF 2108 <2> ; $ENDIF ;;AN000;; 2109 <2> $MEN199: 2110 <2> 2111 <2> ;; We must go back and complete the message after the replacable parameter if there is any left 2112 <2> 2113 <2> ; $IF NC ;;AN000;; IF there was an error displaying then EXIT 2114 <2> JC $MIF211 2115 <2> POP CX ;;AN000;; Get size of the rest of the message 2116 <2> POP ES ;;AN000;; Get address of the rest of the message 2117 <2> POP DI ;;AN000;; 2118 <2> POP BP ;;AN000;; Get replacment count 2119 <2> POP SI ;;AN000;; ELSE get address of first sublist structure 2120 <2> ; $ELSE ;;AN000;; 2121 <2> JMP SHORT $MEN211 2122 <2> $MIF211: 2123 <2> ADD SP,10 ;;AN000;; Clean up stack if error 2124 <2> STC ;;AN000;; 2125 <2> ; $ENDIF ;;AN000;; 2126 <2> $MEN211: 2127 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2128 <2> ; $ENDDO NE,OR ;;AN000;; 2129 <2> JNE $MLL214 2130 <2> ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message 2131 <2> JC $MXL4 2132 <2> JMP $MDO165 2133 <2> $MXL4: 2134 <2> $MLL214: 2135 <2> $MEN165: 2136 <2> ;; IF there was an error displaying then EXIT 2137 <2> MOV word [cs:$M_RT + $M_MSG_NUM],0 ;;AN000;; Reset message number to null 2138 <2> RET ;;AN000;; Return 2139 <2> ;; 2140 <2> $M_DISPLAY_MESSAGE ENDP ;;AN000;; 2141 <2> %IFN COMR 2142 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2143 <2> ;; 2144 <2> ;; PROC NAME: $M_EXT_PAR_REPLACE 2145 <2> ;; 2146 <2> ;; FUNCTION: 2147 <2> ;; INPUTS: 2148 <2> ;; OUPUTS: 2149 <2> ;; 2150 <2> ;; REGS USED: 2151 <2> ;; 2152 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2153 <2> ;; 2154 <2> $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; 2155 <2> ;; 2156 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2157 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN000;; Prepare for get binary value (LOW) 2158 <2> MOV word [cs:$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2159 <2> ;; 2160 <2> CALL $M_CONVERT2ASC ;;AN000;; 2161 <2> ;; 2162 <2> ; $DO ;;AN000;; 2163 <2> $MDO215: 2164 <2> POP AX ;;AN000;; Get character in register 2165 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2166 <2> INC BX ;;AN000;; Increase buffer count 2167 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2168 <2> ; $IF E ;;AN000;; Yes, 2169 <2> JNE $MIF216 2170 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2171 <2> ; $ENDIF ;;AN000;; 2172 <2> $MIF216: 2173 <2> DEC CL ;;AN000;; Have we completed replace? 2174 <2> ; $ENDDO Z ;;AN000;; 2175 <2> JNZ $MDO215 2176 <2> ;; 2177 <2> MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer 2178 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],AX ;;AN000;; Move char into the buffer 2179 <2> INC BX ;;AN000;; Increase buffer count 2180 <2> INC BX ;;AN000;; Increase buffer count 2181 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2182 <2> RET ;;AN000:: 2183 <2> ;; 2184 <2> $M_EXT_PAR_REPLACE ENDP ;;AN000;; 2185 <2> ;; 2186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2187 <2> %ENDIF 2188 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 2189 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 2190 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2191 <2> ;; 2192 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 2193 <2> ;; 2194 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 2195 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 2196 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2197 <2> ;; IF CX > 1 THEN DS:SI points to the specified message 2198 <2> ;; REGS CHANGED: ES,DI,CX,DS,SI 2199 <2> ;; 2200 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2201 <2> ;; 2202 <2> %IF FARmsg ;;AN000;; 2203 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 2204 <2> %ELSE ;;AN000;; 2205 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 2206 <2> %ENDIF ;;AN000;; 2207 <2> ;; 2208 <2> PUSH SI ;;AN000;; 2209 <2> PUSH BX ;;AN000;; 2210 <2> XOR SI,SI ;;AN000;; Use SI as an index 2211 <2> XOR CX,CX ;;AN000;; Use CX as an size 2212 <2> ; $DO ;;AN000;; 2213 <2> $MDO219: 2214 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 2215 <2> ; $IF E ;;AN000;; Yes, 2216 <2> JNE $MIF220 2217 <2> %IF FARmsg ;;AN000;; 2218 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2219 <2> MOV BX,ES ;;AN000; 2220 <2> %ELSE ;;AN000;; 2221 <2> MOV DI,WORD PTR [cs:$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2222 <2> MOV BX,DI ;;AN000; 2223 <2> %ENDIF ;;AN000;; 2224 <2> ; $ELSE ;;AN000;; No, 2225 <2> JMP SHORT $MEN220 2226 <2> $MIF220: 2227 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 2228 <2> ; $IF NE ;;AN000;; Yes, 2229 <2> JE $MIF222 2230 <2> LES DI,[cs:$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 2231 <2> MOV BX,ES ;;AN000; 2232 <2> ; $ELSE ;;AN000;; No, extended errors were specified 2233 <2> JMP SHORT $MEN222 2234 <2> $MIF222: 2235 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 2236 <2> ; $IF AE,AND ;;AN000;; 2237 <2> JNAE $MIF224 2238 <2> CMP AX,$M_CRIT_HI ;;AN000;; 2239 <2> ; $IF BE ;;AN000;; Yes, 2240 <2> JNBE $MIF224 2241 <2> LES DI,[cs:$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 2242 <2> MOV BX,ES ;;AN000; 2243 <2> ; $ELSE ;;AN000;; 2244 <2> JMP SHORT $MEN224 2245 <2> $MIF224: 2246 <2> LES DI,[cs:$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 2247 <2> MOV BX,ES ;;AN000; 2248 <2> ; $ENDIF ;;AN000;; 2249 <2> $MEN224: 2250 <2> ; $ENDIF ;;AN000;; 2251 <2> $MEN222: 2252 <2> ; $ENDIF ;;AN000;; 2253 <2> $MEN220: 2254 <2> ;; 2255 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 2256 <2> ; $IF E ;;AN000;; Yes, 2257 <2> JNE $MIF229 2258 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 2259 <2> ; $IF E ;;AN000;; Yes, 2260 <2> JNE $MIF230 2261 <2> STC ;;AN000;; Set the carry flag 2262 <2> ; $ELSE ;;AN000;; No, 2263 <2> JMP SHORT $MEN230 2264 <2> $MIF230: 2265 <2> MOV [cs:$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 2266 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 2267 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 2268 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 2269 <2> CLC ;;AN000;; 2270 <2> ; $ENDIF ;;AN000;; No, 2271 <2> $MEN230: 2272 <2> ; $ELSE ;;AN000;; 2273 <2> JMP SHORT $MEN229 2274 <2> $MIF229: 2275 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 2276 <2> ; $IF NE ;;AN001;; Yes, 2277 <2> JE $MIF234 2278 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 2279 <2> ; $ENDIF ;;AN000;; 2280 <2> $MIF234: 2281 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 2282 <2> CLC ;;AN000;; 2283 <2> ; $ENDIF ;;AN000;; 2284 <2> $MEN229: 2285 <2> ; $LEAVE C ;;AN000;; 2286 <2> JC $MEN219 2287 <2> OR CX,CX ;;AN000;; Was the message found? 2288 <2> ; $ENDDO NZ,LONG ;;AN000;; 2289 <2> JNZ $MXL5 2290 <2> JMP $MDO219 2291 <2> $MXL5: 2292 <2> $MEN219: 2293 <2> 2294 <2> PUSHF ;;AN006;; Save the flag state 2295 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 2296 <2> ; $IF E ;;AN006;; Yes, 2297 <2> JNE $MIF239 2298 <2> PUSH DX ;;AN006;; Save all needed registers 2299 <2> PUSH BP ;;AN006;; 2300 <2> PUSH CX ;;AN006;; 2301 <2> PUSH ES ;;AN006;; 2302 <2> PUSH DI ;;AN006;; 2303 <2> PUSH AX ;;AN006;; 2304 <2> 2305 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 2306 <2> INT 2FH ;;AN006;; 2307 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 2308 <2> POP AX ;;AN006;; Restore msg number 2309 <2> ; $IF E ;;AN006;; Yes, 2310 <2> JNE $MIF240 2311 <2> MOV BX,AX ;;AN006;; BX is the extended error number 2312 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 2313 <2> INT 2FH ;;AN006;; Call IFSFUNC 2314 <2> ; $ELSE ;;AN006;; No, 2315 <2> JMP SHORT $MEN240 2316 <2> $MIF240: 2317 <2> STC ;;AN006;; Carry conditon 2318 <2> ; $ENDIF ;;AN006;; 2319 <2> $MEN240: 2320 <2> 2321 <2> ; $IF C ;;AN006;; Was there an update? 2322 <2> JNC $MIF243 2323 <2> POP DI ;;AN006;; No, 2324 <2> POP ES ;;AN006;; Restore old pointer 2325 <2> POP CX ;;AN006;; 2326 <2> ; $ELSE ;;AN006;; Yes 2327 <2> JMP SHORT $MEN243 2328 <2> $MIF243: 2329 <2> ADD SP,6 ;;AN006;; Throw away old pointer 2330 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 2331 <2> ; $ENDIF ;;AN006;; 2332 <2> $MEN243: 2333 <2> POP BP ;;AN006;; Restore other Regs 2334 <2> POP DX ;;AN006;; 2335 <2> ; $ENDIF ;;AN006;; 2336 <2> $MIF239: 2337 <2> $M_POPF ;;AN006;; Restore the flag state 2338 <2> 2339 <2> POP BX ;;AN000;; 2340 <2> POP SI ;;AN000;; 2341 <2> RET ;;AN000;; Return ES:DI pointing to the message 2342 <2> ;; 2343 <2> $M_GET_MSG_ADDRESS ENDP ;; 2344 <2> ;; 2345 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 2346 <2> ;; 2347 <2> PUSH DI ;;AN006;; Save position 2348 <2> PUSH AX ;;AN006;; 2349 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 2350 <2> XOR AL,AL ;;AN006;; Prepare compare register 2351 <2> REPNE SCASB ;;AN006;; Scan for zero 2352 <2> NOT CX ;;AN006;; Change decrement into number 2353 <2> DEC CX ;;AN006;; Don't include the zero 2354 <2> POP AX ;;AN006;; 2355 <2> POP DI ;;AN006;; Restore position 2356 <2> RET ;;AN006;; 2357 <2> ;; 2358 <2> $M_SET_LEN_IN_CX ENDP ;; 2359 <2> ;; 2360 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2361 <2> ;; 2362 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 2363 <2> ;; 2364 <2> ;; FUNCTION: To scan thru message headers until message is found 2365 <2> ;; INPUTS: ES:DI points to beginning of msg headers 2366 <2> ;; CX contains the number of messages in class 2367 <2> ;; DH contains the message class 2368 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2369 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 2370 <2> ;; 2371 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2372 <2> ;; 2373 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 2374 <2> ;; 2375 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 2376 <2> ; $IF E,AND ;;AN004;; Yes, 2377 <2> JNE $MIF247 2378 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 2379 <2> ; $IF NE ;;AN004;; Yes, 2380 <2> JE $MIF247 2381 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 2382 <2> ; $IF E ;;AN004;; . . . and . . . 2383 <2> JNE $MIF248 2384 <2> PUSH AX ;;AN004;; Reset the special message number 2385 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 2386 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2387 <2> POP AX ;;AN004;; Reset the special message number 2388 <2> ; $ELSE ;;AN004;; Get the old message number 2389 <2> JMP SHORT $MEN248 2390 <2> $MIF248: 2391 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2392 <2> ; $ENDIF ;;AN004;; Get the old message number 2393 <2> $MEN248: 2394 <2> ; $ELSE ;;AN004;; 2395 <2> JMP SHORT $MEN247 2396 <2> $MIF247: 2397 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 2398 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2399 <2> ; $IF NE ;;AN001;; 2400 <2> JE $MIF252 2401 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 2402 <2> ; $ELSE ;;AN001;; 2403 <2> JMP SHORT $MEN252 2404 <2> $MIF252: 2405 <2> %IF FARmsg ;;AN001;; 2406 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2407 <2> %ELSE 2408 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2409 <2> %ENDIF 2410 <2> ; $IF E ;;AN002;; pointer (hopefully) 2411 <2> JNE $MIF254 2412 <2> %IF FARmsg ;;AN001;; 2413 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2414 <2> %ELSE 2415 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2416 <2> %ENDIF 2417 <2> ; $ENDIF ;;AN002;; go on to the next class 2418 <2> $MIF254: 2419 <2> ; $ENDIF ;;AN001;; 2420 <2> $MEN252: 2421 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 2422 <2> STC ;;AN004;; Flag that we haven't found anything yet 2423 <2> ; $ENDIF ;;AN004;; 2424 <2> $MEN247: 2425 <2> 2426 <2> ; $IF C ;;AN004;; Have we found anything yet? 2427 <2> JNC $MIF258 2428 <2> CLC ;;AN004;; No, reset carry 2429 <2> ; $SEARCH ;;AN000;; 2430 <2> $MDO259: 2431 <2> OR CX,CX ;;AN000;; Do we have any to check? 2432 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2433 <2> JZ $MEN259 2434 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2435 <2> ; $IF NE ;;AN001;; 2436 <2> JE $MIF261 2437 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 2438 <2> ; $ELSE ;;AN001;; 2439 <2> JMP SHORT $MEN261 2440 <2> $MIF261: 2441 <2> %IF FARmsg ;;AN001;; 2442 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 2443 <2> %ELSE 2444 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 2445 <2> %ENDIF 2446 <2> ; $ENDIF 2447 <2> $MEN261: 2448 <2> ; $EXITIF E ;;AN000;; 2449 <2> JNE $MIF259 2450 <2> ; $ORELSE ;;AN000; 2451 <2> JMP SHORT $MSR259 2452 <2> $MIF259: 2453 <2> DEC CX ;;AN000;; No, well do we have more to check? 2454 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2455 <2> JZ $MEN259 2456 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 2457 <2> ; $ENDLOOP ;;AN000;; 2458 <2> JMP SHORT $MDO259 2459 <2> $MEN259: 2460 <2> STC ;;AN000;; 2461 <2> ; $ENDSRCH ;;AN000;; Check next message 2462 <2> $MSR259: 2463 <2> ; $IF NC ;;AN000;; Did we find the message? 2464 <2> JC $MIF269 2465 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 2466 <2> CLC ;;AN001;; 2467 <2> ; $IF E ;;AN001;; 2468 <2> JNE $MIF270 2469 <2> %IF FARmsg ;;AN001;; 2470 <2> %ELSE ;;AN000;; 2471 <2> PUSH CS ;;AN000;; 2472 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 2473 <2> %ENDIF 2474 <2> ; $ENDIF ;;AN001;; 2475 <2> $MIF270: 2476 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 2477 <2> ; $ENDIF ;;AN004;; 2478 <2> $MIF269: 2479 <2> ; $ENDIF ;;AN004;; 2480 <2> $MIF258: 2481 <2> ;; Yes, great we can return with CX > 0 2482 <2> 2483 <2> ; $IF NC ;;AN000;; Did we find the message? 2484 <2> JC $MIF274 2485 <2> XOR CH,CH ;;AN000;; 2486 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 2487 <2> INC DI ;;AN000;; Increment past length 2488 <2> ; $ENDIF ;;AN004;; 2489 <2> $MIF274: 2490 <2> 2491 <2> MOV byte [cs:$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 2492 <2> RET ;;AN000;; Return 2493 <2> ;; 2494 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 2495 <2> ;; 2496 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2497 <2> %ENDIF ;;AN000;; END of include of common subroutines 2498 <2> ; 2499 <2> %IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms 2500 <2> %iassign $M_REPLACE FALSE ;;AN000;; Tell the assembler we did 2501 <2> ;; 2502 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2503 <2> $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; 2504 <2> ;; 2505 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2506 <2> %IFN COMR 2507 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) 2508 <2> ; $IF E ;;AN000;; Yes, 2509 <2> JNE $MIF276 2510 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE_HYP ;;AN000;; Move in a " -" 2511 <2> INC BX ;;AN000;; Increment count 2512 <2> INC BX ;;AN000;; Increment count 2513 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE ;;AN000;; Move in a " " 2514 <2> INC BX ;;AN000;; Increment count 2515 <2> CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case 2516 <2> ; $ENDIF ;;AN000;; If it fails we will catch it later 2517 <2> $MIF276: 2518 <2> %ENDIF 2519 <2> 2520 <2> POP BP ;;AN000;; Remember the return address 2521 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2522 <2> XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack 2523 <2> 2524 <2> MOV [cs:$M_RT + $M_SIZE],CL ;;AN000;; Save size to later clear stack 2525 <2> MOV AL,BYTE PTR [$M_SL + $M_S_MINW] ;;AN000;; Get the minimum width 2526 <2> ;; 2527 <2> CMP AL,CL ;;AN000;; Do we need pad chars added? 2528 <2> ; $IF A ;;AN000;; Yes, 2529 <2> JNA $MIF278 2530 <2> SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. 2531 <2> MOV DH,AL ;;AN000;; Save the number of pad characters 2532 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be right aligned? 2533 <2> ; $IF NZ ;;AN000;; Yes, 2534 <2> JZ $MIF279 2535 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2536 <2> $MDO280: 2537 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2538 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2539 <2> INC BX ;;AN000;; 2540 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2541 <2> ; $IF E ;;AN000;; Yes, 2542 <2> JNE $MIF281 2543 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2544 <2> ; $ENDIF ;;AN000;; 2545 <2> $MIF281: 2546 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2547 <2> ; $ENDDO Z ;;AN000;; No, next pad character 2548 <2> JNZ $MDO280 2549 <2> ; $ENDIF ;;AN000;; 2550 <2> $MIF279: 2551 <2> ; $ENDIF ;;AN000;; Yes, 2552 <2> $MIF278: 2553 <2> ;; 2554 <2> CMP BYTE [$M_SL + $M_S_MAXW],$M_UNLIM_W ;;AN000;; Is maximum width unlimited? 2555 <2> ; $IF NE ;;AN000;; 2556 <2> JE $MIF286 2557 <2> CMP BYTE PTR [$M_SL + $M_S_MAXW],CL ;;AN000;; Will we exceed maximum width? 2558 <2> ; $IF B ;;AN000;; Yes, 2559 <2> JNB $MIF287 2560 <2> SUB CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Calculate how many extra chars 2561 <2> MOV DL,CL ;;AN000;; Remember how many chars to pop off 2562 <2> MOV CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Set new string length 2563 <2> ; $ENDIF ;;AN000;; 2564 <2> $MIF287: 2565 <2> ; $ENDIF ;;AN000;; 2566 <2> $MIF286: 2567 <2> OR CX,CX ;;AN000;; 2568 <2> ; $IF NZ ;;AN000;; 2569 <2> JZ $MIF290 2570 <2> ; $DO ;;AN000;; Begin filling buffer with string 2571 <2> $MDO291: 2572 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2573 <2> ; $IF Z,AND ;;AN000;; 2574 <2> JNZ $MIF292 2575 <2> Char_field_ASCIIZ equ Char_Field_ASCIIZ ; NASM port equate 2576 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ; Is this replace a ASCIIZ string? 2577 <2> ; $IF NZ ;;AN000;; Yes, 2578 <2> JZ $MIF292 2579 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get first character from string 2580 <2> INC DI ;;AN000;; Next character in string 2581 <2> ; $ELSE ;;AN000;; No, 2582 <2> JMP SHORT $MEN292 2583 <2> $MIF292: 2584 <2> POP AX ;;AN000;; Get character in register 2585 <2> ; $ENDIF ;;AN000;; 2586 <2> $MEN292: 2587 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2588 <2> INC BX ;;AN000;; Increase buffer count 2589 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2590 <2> ; $IF E ;;AN000;; Yes, 2591 <2> JNE $MIF295 2592 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2593 <2> ; $ENDIF ;;AN000;; 2594 <2> $MIF295: 2595 <2> DEC CL ;;AN000;; Have we completed replace? 2596 <2> ; $ENDDO Z ;;AN000;; Test again 2597 <2> JNZ $MDO291 2598 <2> ; $ENDIF ;;AN000;; 2599 <2> $MIF290: 2600 <2> ;; 2601 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be left aligned? 2602 <2> ; $IF Z ;;AN000;; Yes, 2603 <2> JNZ $MIF299 2604 <2> OR DH,DH ;;AN000;; Do we need pad chars added? 2605 <2> ; $IF NZ ;;AN000;; Yes, 2606 <2> JZ $MIF300 2607 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2608 <2> $MDO301: 2609 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2610 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2611 <2> INC BX ;;AN000;; 2612 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2613 <2> ; $IF E ;;AN000;; Yes, 2614 <2> JNE $MIF302 2615 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2616 <2> ; $ENDIF ;;AN000;; 2617 <2> $MIF302: 2618 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2619 <2> ; $ENDDO Z ;;AN000;; Test again 2620 <2> JNZ $MDO301 2621 <2> ; $ENDIF ;;AN000;; 2622 <2> $MIF300: 2623 <2> ; $ENDIF ;;AN000;; 2624 <2> $MIF299: 2625 <2> ;; 2626 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2627 <2> ; $IF Z,AND ;;AN000;; 2628 <2> JNZ $MIF307 2629 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? 2630 <2> ; $IF NZ ;;AN000;; Yes, 2631 <2> JZ $MIF307 2632 <2> ; $ELSE ;;AN000;; 2633 <2> JMP SHORT $MEN307 2634 <2> $MIF307: 2635 <2> OR DL,DL ;;AN000;; 2636 <2> ; $IF NE ;;AN000;; 2637 <2> JE $MIF309 2638 <2> ; $DO ;;AN000;; 2639 <2> $MDO310: 2640 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable 2641 <2> DEC DL ;;AN000;; Are we done? 2642 <2> ; $ENDDO Z ;;AN000;; 2643 <2> JNZ $MDO310 2644 <2> ; $ENDIF ;;AN000;; 2645 <2> $MIF309: 2646 <2> ; $ENDIF ;;AN000;; 2647 <2> $MEN307: 2648 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time 2649 <2> PUSH BP ;;AN000;; Restore the return address 2650 <2> ;; 2651 <2> RET ;;AN000;; 2652 <2> ;; 2653 <2> $M_DISPLAY_REPLACE ENDP ;;AN000;; 2654 <2> ;; 2655 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2656 <2> ;; 2657 <2> ;; PROC NAME: $M_FLUSH_BUFFER 2658 <2> ;; 2659 <2> ;; FUNCTION: Display the contents of the temporary buffer 2660 <2> ;; INPUTS: DI contains the number of bytes to display 2661 <2> ;; OUTPUTS: BX reset to zero 2662 <2> ;; 2663 <2> ;; REGS USED: 2664 <2> ;; 2665 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2666 <2> ;; 2667 <2> $M_FLUSH_BUF PROC NEAR ;;AN000;; 2668 <2> ;; 2669 <2> PUSH CX ;;AN000;; Save changed regs 2670 <2> PUSH ES ;;AN000;; 2671 <2> PUSH DI ;;AN000;; 2672 <2> PUSH DS ;;AN000;; Set ES pointing to buffer 2673 <2> POP ES ;;AN000;; 2674 <2> ;; 2675 <2> MOV CX,BX ;;AN000;; Set number of bytes to display 2676 <2> XOR BX,BX ;;AN000;; Reset buffer counter 2677 <2> LEA DI,[$M_RT + $M_TEMP_BUF] ;;AN000;; Reset buffer location pointer 2678 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer 2679 <2> ;; 2680 <2> ; $IF NC ;;AN000;; Error? 2681 <2> JC $MIF314 2682 <2> POP DI ;;AN000;; No, Restore changed regs 2683 <2> POP ES ;;AN000;; 2684 <2> POP CX ;;AN000;; 2685 <2> ; $ELSE ;;AN000;; Yes, 2686 <2> JMP SHORT $MEN314 2687 <2> $MIF314: 2688 <2> ADD SP,6 ;;AN000;; Fix stack 2689 <2> STC ;;AN000;; 2690 <2> ; $ENDIF ;;AN000;; Error? 2691 <2> $MEN314: 2692 <2> ;; 2693 <2> RET ;;AN000;; Return 2694 <2> ;; 2695 <2> $M_FLUSH_BUF ENDP ;;AN000;; 2696 <2> ;; 2697 <2> ;; 2698 <2> %IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? 2699 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2700 <2> %iassign $M_CHAR_ONLY TRUE ;;AN000;; replacement code later 2701 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2702 <2> ;; 2703 <2> ;; PROC NAME: $M_CHAR_REPLACE 2704 <2> ;; 2705 <2> ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace 2706 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2707 <2> ;; ES:DI contains the VALUE from SUBLIST 2708 <2> ;; OUTPUTS: CX contains number of characters on stack 2709 <2> ;; Top of stack --> Last character 2710 <2> ;; . . . 2711 <2> ;; Bot of stack --> First character 2712 <2> ;; 2713 <2> ;; OTHER REGS Revised: AX 2714 <2> ;; 2715 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2716 <2> ;; 2717 <2> $M_CHAR_REPLACE PROC NEAR ;;AN000;; 2718 <2> ;; 2719 <2> POP BP ;;AN000;; Save return address 2720 <2> TEST byte [$M_SL + $M_S_FLAG],~ Char_Field_Char & $M_SIZE_MASK ;;AN000;; Was Character specified? 2721 <2> ; $IF Z ;;AN000;; Yes, 2722 <2> JNZ $MIF317 2723 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2724 <2> PUSH AX ;;AN000;; Put it on the stack 2725 <2> INC CX ;;AN000;; Increase the count 2726 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 2727 <2> ; $IF C ;;AN000;; Yes, 2728 <2> JNC $MIF318 2729 <2> MOV AL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 2730 <2> PUSH AX ;;AN000;; Put it on the stack 2731 <2> CLC ;;AN000;; Clear the carry 2732 <2> ; $ENDIF ;;AN000;; 2733 <2> $MIF318: 2734 <2> ; $ELSE ;;AN000;; No, it was an ASCIIZ string 2735 <2> JMP SHORT $MEN317 2736 <2> $MIF317: 2737 <2> ; $DO ;;AN000;; 2738 <2> $MDO321: 2739 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2740 <2> OR AL,AL ;;AN000;; Is it the NULL? 2741 <2> ; $LEAVE Z ;;AN000;; No, 2742 <2> JZ $MEN321 2743 <2> INC DI ;;AN000;; Next character 2744 <2> INC CX ;;AN000;; Increment the count 2745 <2> ; $ENDDO ;;AN000;; Yes, 2746 <2> JMP SHORT $MDO321 2747 <2> $MEN321: 2748 <2> SUB DI,CX ;;AN000;; Set SI at the beginning of the string 2749 <2> ; $ENDIF ;;AN000;; 2750 <2> $MEN317: 2751 <2> ;;AN000;; 2752 <2> PUSH BP ;;AN000;; Restore return address 2753 <2> RET ;;AN000;; Return 2754 <2> ;; 2755 <2> $M_CHAR_REPLACE ENDP ;;AN000;; 2756 <2> ;; 2757 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2758 <2> %ENDIF ;;AN000;; END of include of CHAR replace code 2759 <2> ; 2760 <2> %IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? 2761 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2762 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2763 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2764 <2> ;; 2765 <2> ;; PROC NAME: $M_BIN2ASC_REPLACE 2766 <2> ;; 2767 <2> ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string 2768 <2> ;; and prepare to display 2769 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2770 <2> ;; ES:DI contains the VALUE from SUBLIST 2771 <2> ;; OUTPUTS: CX contains number of characters on stack 2772 <2> ;; Top of stack --> Last character 2773 <2> ;; . . . 2774 <2> ;; Bot of stack --> First character 2775 <2> ;; OTHER REGS Revised: BX,DX,AX 2776 <2> ;; 2777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2778 <2> ;; 2779 <2> $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; 2780 <2> ;; 2781 <2> POP BP ;;AN000;; Save return address 2782 <2> ;; 2783 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2784 <2> XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) 2785 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE16 ;;AN000;; Set default divisor 2786 <2> XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) 2787 <2> %IFN COMR 2788 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_BYTE & $M_SIZE_MASK ;;AN000;; Was BYTE specified? 2789 <2> ; $IF Z ;;AN000;; 2790 <2> JNZ $MIF325 2791 <2> MOV AL, BYTE PTR [ES:DI] ;;AN000;; Setup byte in AL 2792 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2793 <2> ; $IF Z ;;AN000;; 2794 <2> JNZ $MIF326 2795 <2> TEST AL,10000000b ;;AN000;; Is this number negative? 2796 <2> ; $IF NZ ;;AN000;; Yes, 2797 <2> JZ $MIF327 2798 <2> INC BX ;;AN000;; Remember that it was negative 2799 <2> AND AL,01111111b ;;AN000;; Make it positive 2800 <2> ; $ENDIF ;;AN000;; 2801 <2> $MIF327: 2802 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2803 <2> ; $ENDIF ;;AN000;; 2804 <2> $MIF326: 2805 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2806 <2> ; $IF Z ;;AN000;; 2807 <2> JNZ $MIF330 2808 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2809 <2> ; $ENDIF ;;AN000;; 2810 <2> $MIF330: 2811 <2> ; $ELSE ;;AN000;; 2812 <2> JMP SHORT $MEN325 2813 <2> $MIF325: 2814 <2> %ENDIF 2815 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_WORD & $M_SIZE_MASK ;;AN000;; Was WORD specified? 2816 <2> ; $IF Z ;;AN000;; 2817 <2> JNZ $MIF333 2818 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup byte in AL 2819 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;; AN000;; Was Signed binary specified? 2820 <2> ; $IF Z ;;AN000;; 2821 <2> JNZ $MIF334 2822 <2> TEST AH,10000000b ;;AN000;; Is this number negative? 2823 <2> ; $IF NZ ;;AN000;; Yes, 2824 <2> JZ $MIF335 2825 <2> INC BX ;;AN000;; Remember that it was negative 2826 <2> AND AH,01111111b ;;AN000;; Make it positive 2827 <2> ; $ENDIF ;;AN000;; 2828 <2> $MIF335: 2829 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2830 <2> ; $ENDIF ;;AN000;; 2831 <2> $MIF334: 2832 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2833 <2> ; $IF Z ;;AN000;; 2834 <2> JNZ $MIF338 2835 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2836 <2> ; $ENDIF ;;AN000;; 2837 <2> $MIF338: 2838 <2> ; $ELSE ;;AN000;; 2839 <2> JMP SHORT $MEN333 2840 <2> $MIF333: 2841 <2> %IFN COMR 2842 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup Double word in DX:AX 2843 <2> MOV DX, WORD PTR [ES:DI + 2] ;;AN000;; 2844 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2845 <2> ; $IF Z ;;AN000;; 2846 <2> JNZ $MIF341 2847 <2> TEST DH,10000000b ;;AN000;; Is this number negative? 2848 <2> ; $IF NZ ;;AN000;; Yes, 2849 <2> JZ $MIF342 2850 <2> INC BX ;;AN000;; Remember that it was negative 2851 <2> AND DH,01111111b ;;AN000;; Make it positive 2852 <2> ; $ENDIF ;;AN000;; 2853 <2> $MIF342: 2854 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2855 <2> ; $ENDIF ;;AN000;; 2856 <2> $MIF341: 2857 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2858 <2> ; $IF Z ;;AN000;; 2859 <2> JNZ $MIF345 2860 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2861 <2> ; $ENDIF ;;AN000;; 2862 <2> $MIF345: 2863 <2> %ENDIF 2864 <2> ; $ENDIF ;;AN000;; 2865 <2> $MEN333: 2866 <2> ; $ENDIF ;;AN000;; 2867 <2> $MEN325: 2868 <2> ;; 2869 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string 2870 <2> %IFN COMR 2871 <2> OR BX,BX ;;AN000;; 2872 <2> ; $IF NZ ;;AN000;; Was number negative? 2873 <2> JZ $MIF349 2874 <2> XOR DX,DX ;;AN000;; Yes, 2875 <2> MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number 2876 <2> PUSH DX ;;AN000;; 2877 <2> ; $ENDIF ;;AN000;; No, 2878 <2> $MIF349: 2879 <2> %ENDIF 2880 <2> ;; 2881 <2> PUSH BP ;;AN000;; Restore return address 2882 <2> RET ;;AN000;; Return 2883 <2> ;; 2884 <2> $M_BIN2ASC_REPLACE ENDP ;;AN000;; 2885 <2> ;; 2886 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2887 <2> %ENDIF ;;AN000;; END of include of NUM replace code 2888 <2> ; 2889 <2> %IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? 2890 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2891 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2892 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2893 <2> ;; 2894 <2> ;; PROC NAME: $M_DATE_REPLACE 2895 <2> ;; 2896 <2> ;; FUNCTION: Convert a date to a decimal ASCII string using current 2897 <2> ;; country format and prepare to display 2898 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2899 <2> ;; ES:DI points at VALUE from SUBLIST 2900 <2> ;; OUTPUTS: CX contains number of characters on stack 2901 <2> ;; Top of stack --> Last character 2902 <2> ;; . . . 2903 <2> ;; Bot of stack --> First character 2904 <2> ;; OTHER REGS Revised: DX, AX 2905 <2> ;; 2906 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2907 <2> ;; 2908 <2> $M_DATE_REPLACE PROC NEAR ;;AN000;; 2909 <2> ;; 2910 <2> POP BP ;;AN000;; Save return address 2911 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2912 <2> CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT 2913 <2> ;;AN000;; All O.K.? 2914 <2> XOR DX,DX ;;AN000;; Reset DX value 2915 <2> XOR AX,AX ;;AN000;; Reset AX value 2916 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],0 ;;AN000;; USA Date Format 2917 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2918 <2> JNE $MIF351 2919 <2> CALL $M_YEAR ;;AN000;; Get Year 2920 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2921 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2922 <2> INC CX ;;AN000;; Increment count 2923 <2> XOR AX,AX ;;AN000;; Reset AX value 2924 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2925 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2926 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2927 <2> INC CX ;;AN000;; Increment count 2928 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2929 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2930 <2> ; $ENDIF ;;AN000;; 2931 <2> $MIF351: 2932 <2> ;; 2933 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],1 ;;AN000;; EUROPE Date Format 2934 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2935 <2> JNE $MIF353 2936 <2> CALL $M_YEAR ;;AN000;; Get Year 2937 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2938 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2939 <2> INC CX ;;AN000;; 2940 <2> XOR AX,AX ;;AN000;; Reset AX 2941 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2942 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2943 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2944 <2> INC CX ;;AN000;; 2945 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2946 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2947 <2> ; $ENDIF ;;AN000;; 2948 <2> $MIF353: 2949 <2> ;; 2950 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],2 ;;AN000;; JAPAN Date Format 2951 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2952 <2> JNE $MIF355 2953 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2954 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2955 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2956 <2> INC CX ;;AN000;; 2957 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2958 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2959 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2960 <2> INC CX ;;AN000;; 2961 <2> CALL $M_YEAR ;;AN000;; Get Year 2962 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2963 <2> ; $ENDIF ;;AN000;; 2964 <2> $MIF355: 2965 <2> ;; 2966 <2> PUSH BP ;;AN000;; Restore return address 2967 <2> RET ;;AN000;; Return 2968 <2> ;; 2969 <2> $M_DATE_REPLACE ENDP ;;AN000;; 2970 <2> ;; 2971 <2> $M_GET_DATE PROC NEAR ;;AN000;; 2972 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 2973 <2> MOV AL,0 ;;AN000;; Get current country info 2974 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 2975 <2> INT 21H ;;AN000;; 2976 <2> ; $IF C ;;AN000;; No, 2977 <2> JNC $MIF357 2978 <2> MOV WORD [$M_RT + $M_DATE_FORMAT],$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) 2979 <2> MOV BYTE [$M_RT + $M_DATE_SEPARA],$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) 2980 <2> ; $ENDIF ;;AN000;; 2981 <2> $MIF357: 2982 <2> RET ;;AN000;; 2983 <2> $M_GET_DATE ENDP ;;AN000;; 2984 <2> ;; 2985 <2> $M_YEAR PROC NEAR ;;AN000;; 2986 <2> MOV AX,WORD PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Year 2987 <2> TEST byte [$M_SL + $M_S_FLAG],Date_MDY_4 & $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? 2988 <2> ; $IF Z ;;AN000;; 2989 <2> JNZ $MIF359 2990 <2> CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year 2991 <2> ; $IF A ;;AN000;; 2992 <2> JNA $MIF360 2993 <2> MOV AX,$M_MAX_2_YEAR ;;AN000;; 2994 <2> ; $ENDIF ;;AN000;; 2995 <2> $MIF360: 2996 <2> ; $ENDIF ;;AN000;; 2997 <2> $MIF359: 2998 <2> RET ;;AN000;; 2999 <2> $M_YEAR ENDP ;;AN000;; 3000 <2> ;; 3001 <2> $M_CONVERTDATE PROC NEAR ;;AN000;; 3002 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3003 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3004 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3005 <2> DEC CX ;;AN000;; Test if size only grew by 1 3006 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3007 <2> ; $IF E ;;AN000;; Yes, 3008 <2> JNE $MIF363 3009 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3010 <2> PUSH AX ;;AN000;; Save it 3011 <2> INC CX ;;AN000;; Count it 3012 <2> ; $ENDIF ;;AN000;; 3013 <2> $MIF363: 3014 <2> INC CX ;;AN000;; Restore CX 3015 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3016 <2> RET ;;AN000;; 3017 <2> $M_CONVERTDATE ENDP ;;AN000;; 3018 <2> ;; 3019 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3020 <2> %ENDIF ;;AN000;; END of include of DATE replace code 3021 <2> ; 3022 <2> %IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? 3023 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 3024 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 3025 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3026 <2> ;; 3027 <2> ;; PROC NAME: $M_TIME_REPLACE 3028 <2> ;; 3029 <2> ;; FUNCTION: Convert a time to a decimal ASCII string 3030 <2> ;; and prepare to display 3031 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 3032 <2> ;; ES:DI points at VALUE from SUBLIST 3033 <2> ;; OUTPUTS: CX contains number of characters on stack 3034 <2> ;; Top of stack --> Last character 3035 <2> ;; . . . 3036 <2> ;; Bot of stack --> First character 3037 <2> ;; REGS USED: BP,CX,AX 3038 <2> ;; 3039 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3040 <2> ;; 3041 <2> $M_TIME_REPLACE PROC NEAR ;;AN000;; 3042 <2> ;; 3043 <2> POP BP ;;AN000;; Save return address 3044 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 3045 <2> CALL $M_GET_TIME ;;AN000;; All O.K.? 3046 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3047 <2> ; $IF NZ ;;AN000;; Yes, 3048 <2> JZ $MIF365 3049 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3050 <2> ; $IF E ;;AN000;; Yes, 3051 <2> JNE $MIF366 3052 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3053 <2> CMP AL,12 ;;AN000;; Is hour 12 or less? 3054 <2> ; $IF L,OR ;;AN000;; or 3055 <2> JL $MLL367 3056 <2> CMP AL,23 ;;AN000;; Is hour 24 or greater? 3057 <2> ; $IF G ;;AN000;; Yes, 3058 <2> JNG $MIF367 3059 <2> $MLL367: 3060 <2> MOV AL,$M_AM ;;AN000;; 3061 <2> PUSH AX ;;AN000;; Push an "a" to represent AM. 3062 <2> INC CX ;;AN000;; 3063 <2> ; $ELSE ;;AN000;; No, 3064 <2> JMP SHORT $MEN367 3065 <2> $MIF367: 3066 <2> MOV AL,$M_PM ;;AN000;; 3067 <2> PUSH AX ;;AN000;; Push an "p" to represent PM. 3068 <2> INC CX ;;AN000;; 3069 <2> ; $ENDIF ;;AN000;; 3070 <2> $MEN367: 3071 <2> ; $ENDIF ;;AN000;; 3072 <2> $MIF366: 3073 <2> ; $ENDIF ;;AN000;; 3074 <2> $MIF365: 3075 <2> ;; 3076 <2> XOR AX,AX ;;AN000;; 3077 <2> XOR DX,DX ;;AN000;; 3078 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3079 <2> ; $IF NZ ;;AN000;; 3080 <2> JZ $MIF372 3081 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Hundreds 3082 <2> CALL $M_CONVERTTIME ;;AN000;; 3083 <2> PUSH WORD [$M_RT + $M_DECI_SEPARA] ;;AN000;; 3084 <2> INC CX ;;AN000;; 3085 <2> ; $ENDIF ;;AN000;; 3086 <2> $MIF372: 3087 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3088 <2> ; $IF NZ,OR ;;AN000;; 3089 <2> JNZ $MLL374 3090 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSS_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? 3091 <2> ; $IF NZ ;;AN000;; 3092 <2> JZ $MIF374 3093 <2> $MLL374: 3094 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Seconds 3095 <2> CALL $M_CONVERTTIME ;;AN000;; 3096 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3097 <2> INC CX ;;AN000;; 3098 <2> ; $ENDIF ;;AN000;; 3099 <2> $MIF374: 3100 <2> ;; Do Hour/Min (12 Hour) 3101 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+1] ;;AN000;; Get Minutes 3102 <2> CALL $M_CONVERTTIME ;;AN000;; 3103 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3104 <2> INC CX ;;AN000;; 3105 <2> ;; 3106 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3107 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3108 <2> ; $IF NZ ;;AN000;; Yes, 3109 <2> JZ $MIF376 3110 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3111 <2> ; $IF E ;;AN000;; Yes, 3112 <2> JNE $MIF377 3113 <2> CMP AL,13 ;;AN000;; Is hour less than 12? 3114 <2> ; $IF GE ;;AN000;; Yes, 3115 <2> JNGE $MIF378 3116 <2> SUB AL,12 ;;AN000;; Set to a 12 hour value 3117 <2> ; $ENDIF ;;AN000;; 3118 <2> $MIF378: 3119 <2> CMP AL,0 ;;AN000;; Is hour less than 12? 3120 <2> ; $IF E ;;AN000;; Yes, 3121 <2> JNE $MIF380 3122 <2> MOV AL,12 ;;AN000;; Set to a 12 hour value 3123 <2> ; $ENDIF ;;AN000;; 3124 <2> $MIF380: 3125 <2> ; $ENDIF ;;AN000;; 3126 <2> $MIF377: 3127 <2> ; $ENDIF ;;AN000;; 3128 <2> $MIF376: 3129 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII 3130 <2> ;; 3131 <2> PUSH BP ;;AN000;; Restore return address 3132 <2> RET ;;AN000;; Return 3133 <2> ;; 3134 <2> $M_TIME_REPLACE ENDP ;;AN000;; 3135 <2> ;; 3136 <2> $M_GET_TIME PROC NEAR ;;AN000;; 3137 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 3138 <2> MOV AL,0 ;;AN000;; Get current country info 3139 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 3140 <2> INT 21H ;;AN000;; 3141 <2> ; $IF C ;;AN000;; No, 3142 <2> JNC $MIF384 3143 <2> MOV WORD [$M_RT + $M_TIME_FORMAT],$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) 3144 <2> MOV BYTE [$M_RT + $M_TIME_SEPARA],$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) 3145 <2> MOV BYTE [$M_RT + $M_DECI_SEPARA],$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) 3146 <2> ; $ENDIF ;;AN000;; 3147 <2> $MIF384: 3148 <2> RET ;;AN000;; 3149 <2> $M_GET_TIME ENDP ;;AN000;; 3150 <2> ;; 3151 <2> $M_CONVERTTIME PROC NEAR ;;AN000;; 3152 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3153 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3154 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3155 <2> DEC CX ;;AN000;; Test if size only grew by 1 3156 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3157 <2> ; $IF E ;;AN000;; Yes, 3158 <2> JNE $MIF386 3159 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3160 <2> PUSH AX ;;AN000;; Save it 3161 <2> INC CX ;;AN000;; Count it 3162 <2> ; $ENDIF ;;AN000;; 3163 <2> $MIF386: 3164 <2> INC CX ;;AN000;; Restore CX 3165 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3166 <2> RET ;;AN000;; 3167 <2> $M_CONVERTTIME ENDP ;;AN000;; 3168 <2> ;; 3169 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3170 <2> %ENDIF ;;AN000;; END of include of TIME replace 3171 <2> %ENDIF ;;AN000;; END of include of Replacement common code 3172 <2> ; 3173 <2> %IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? 3174 <2> INPUTmsg equ FALSE ;;AN000;; Yes, THEN include it and reset the flag 3175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3176 <2> ;; 3177 <2> ;; PROC NAME: $M_WAIT_FOR_INPUT 3178 <2> ;; 3179 <2> ;; FUNCTION: To accept keyed input and return extended key value 3180 <2> ;; in AX register 3181 <2> ;; INPUTS: DL contains the DOS function requested for input 3182 <2> ;; OUPUTS: AX contains the extended key value that was read 3183 <2> ;; REGS USED: 3184 <2> ;; 3185 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3186 <2> ;; 3187 <2> $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; 3188 <2> ;; 3189 <2> PUSH CX ;;AN000;; Save CX 3190 <2> PUSH DX ;;AN000;; Save DX 3191 <2> PUSH DS ;;AN000;; Save Data segment 3192 <2> ;; 3193 <2> CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? 3194 <2> ; $IF A ;;AN001;; Yes, 3195 <2> JNA $MIF388 3196 <2> MOV AL,DL ;;AN001;; Mov function into AL 3197 <2> AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble 3198 <2> MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function 3199 <2> ; $ELSE ;;AN001;; No, 3200 <2> JMP SHORT $MEN388 3201 <2> $MIF388: 3202 <2> MOV AH,DL ;;AN000;; Put DOS function in AH 3203 <2> ; $ENDIF ;;AN001;; 3204 <2> $MEN388: 3205 <2> PUSH ES ;;AN000;; Get output buffer segment 3206 <2> POP DS ;;AN000;; 3207 <2> MOV DX,DI ;;AN000;; Get output buffer offset in case needed 3208 <2> INT 21H ;;AN000;; Get keyboard input 3209 <2> POP DS ;;AN000;; 3210 <2> 3211 <2> CMP DL,DOS_BUF_KEYB_INP ;;AN000;; 3212 <2> CLC ;;AN000;; 3213 <2> ; $IF NE ;;AN000;; If character input 3214 <2> JE $MIF391 3215 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? 3216 <2> ; $IF C ;;AN000;; 3217 <2> JNC $MIF392 3218 <2> MOV CL,AL ;;AN000;; Save first character 3219 <2> MOV AH,DL ;;AN001;; Get back function 3220 <2> INT 21H ;;AN000;; Get keyboard input 3221 <2> MOV AH,CL ;;AN000;; Retreive first character AX = xxxx 3222 <2> CLC ;;AN000;; Clear carry condition 3223 <2> ; $ELSE ;;AN000;; 3224 <2> JMP SHORT $MEN392 3225 <2> $MIF392: 3226 <2> MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS 3227 <2> ; $ENDIF ;;AN000;; 3228 <2> $MEN392: 3229 <2> ; $ENDIF ;;AN000;; 3230 <2> $MIF391: 3231 <2> ;; 3232 <2> ; $IF NC ;;AN000;; 3233 <2> JC $MIF396 3234 <2> POP DX ;;AN000;; 3235 <2> POP CX ;;AN000;; 3236 <2> ; $ELSE ;;AN000;; 3237 <2> JMP SHORT $MEN396 3238 <2> $MIF396: 3239 <2> ADD SP,4 ;;AN000;; 3240 <2> STC ;;AN000;; Reset carry flag 3241 <2> ; $ENDIF ;;AN000;; 3242 <2> $MEN396: 3243 <2> RET ;;AN000;; Return 3244 <2> ;; 3245 <2> $M_WAIT_FOR_INPUT ENDP ;;AN000;; 3246 <2> ;; 3247 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3248 <2> %ENDIF ;;AN000;; END of include of Wait for Input 3249 <2> %ENDIF ;;AN000;; END of include of SYSDISPMSG 3250 <2> %ENDIF ;;AN000;; END of include of MSG_DATA_ONLY 3251 <2> %ENDIF ;;AN000;; END of include of Structure only 3252 <2> 3253 <2> ;=== Pop trace listing source 3254 <2> 433 <1> 434 <1> %ENDIF 435 <1> 41 42 MSG_SERVICES "LOADmsg" 364 <1> %iassign $M_SERVICE FALSE 365 <1> %rep %0 366 <1> %iassign $M_INCLUDE TRUE 367 <1> %iassign MSG_SERVICES_MATCHED 0 368 <1> %ifidni %1, "MSGDATA" 369 <1> %iassign MSGDATA TRUE 370 <1> %iassign $M_SERVICE TRUE 371 <1> %iassign $M_INCLUDE FALSE 372 <1> %iassign MSG_SERVICES_MATCHED 1 373 <1> %else 374 <1> %iassign $M_MSGDATA_ONLY FALSE 375 <1> %endif 376 <1> 377 <1> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <1> 379 <1> %ifidni %1,"COMR" 380 <1> %iassign COMR TRUE 381 <1> %iassign $M_SERVICE TRUE 382 <1> %iassign $M_INCLUDE FALSE 383 <1> %iassign MSG_SERVICES_MATCHED 1 384 <1> %elifidni %1,"COMT" 385 <1> %iassign COMT TRUE 386 <1> %iassign $M_SERVICE TRUE 387 <1> %iassign $M_INCLUDE FALSE 388 <1> %iassign MSG_SERVICES_MATCHED 1 389 <1> %elifidni %1,"SETSTDIO" 390 <1> %iassign SETSTDIO TRUE 391 <1> %iassign $M_SERVICE TRUE 392 <1> %iassign $M_INCLUDE FALSE 393 <1> %iassign MSG_SERVICES_MATCHED 1 394 <1> %elifidni %1,"NOCHECKSTDIN" 395 <1> %iassign NOCHECKSTDIN TRUE 396 <1> %iassign $M_SERVICE TRUE 397 <1> %iassign $M_INCLUDE FALSE 398 <1> %iassign MSG_SERVICES_MATCHED 1 399 <1> %elifidni %1,"NOCHECKSTDOUT" 400 <1> %iassign NOCHECKSTDOUT TRUE 401 <1> %iassign $M_SERVICE TRUE 402 <1> %iassign $M_INCLUDE FALSE 403 <1> %iassign MSG_SERVICES_MATCHED 1 404 <1> %elifidni %1,"DISK_PROC" 405 <1> %iassign DISK_PROC TRUE 406 <1> %iassign $M_SERVICE TRUE 407 <1> %iassign $M_INCLUDE FALSE 408 <1> %iassign MSG_SERVICES_MATCHED 1 409 <1> %endif 410 <1> 411 <1> %IF $M_INCLUDE 412 <1> %define %%string %1 413 <1> %strlen %%length %%string 414 <1> %assign %%ii 1 415 <1> %define %%name "" 416 <1> %rep %%length 417 <1> %substr %%cc %%string %%ii 418 <1> %assign %%ii %%ii + 1 419 <1> %if %%cc >= 'A' && %%cc <= 'Z' 420 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <1> %endif 422 <1> %strcat %%name %%name,%%cc 423 <1> %endrep 424 <1> %include %%name 425 <1> %ENDIF 426 <1> 427 <1> %rotate 1 428 <1> %endrep 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 424 <2> %include %%name 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 429 <1> 430 <1> %IF $M_SERVICE 431 <1> 432 <1> %include "msgserv.nas" 1 <2> ;=== Push trace listing source: msgserv.nas 2 <2> 3 <2> ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * 4 <2> ; 5 <2> ; MODULE NAME: MSGSERV.SAL 6 <2> ; 7 <2> ; DESCRIPTIVE NAME: Message Services SALUT file 8 <2> ; 9 <2> ; FUNCTION: This module incorporates all the messages services and 10 <2> ; is called upon at build time to INCLUDE the code requested 11 <2> ; by a utility. Code is requested using the macro MSG_SERVICES. 12 <2> ; 13 <2> ; ENTRY POINT: Since this a collection of subroutines, entry point is at 14 <2> ; requested procedure. 15 <2> ; 16 <2> ; INPUT: Since this a collection of subroutines, input is dependent on function 17 <2> ; requested. 18 <2> ; 19 <2> ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 20 <2> ; 21 <2> ; EXIT-ERROR: In all cases, CARRY FLAG = 1 22 <2> ; 23 <2> ; INTERNAL REFERENCES: (list of included subroutines) 24 <2> ; 25 <2> ; - SYSLOADMSG 26 <2> ; - SYSDISPMSG 27 <2> ; - SYSGETMSG 28 <2> ; 29 <2> ; 30 <2> ; EXTERNAL REFERENCES: None 31 <2> ; 32 <2> ; NOTES: At build time, some modules must be included. These are only included 33 <2> ; once using assembler switches. Other logic is included at the request 34 <2> ; of the utility. 35 <2> ; 36 <2> ; COMR and COMT are assembler switches to conditionally assemble code 37 <2> ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident 38 <2> ; storage and multiple EQUates. 39 <2> ; 40 <2> ; REVISION HISTORY: Created MAY 1987 41 <2> ; 42 <2> ; Label: DOS - - Message Retriever 43 <2> ; (c) Copyright 1988 Microsoft 44 <2> ; 45 <2> ; 46 <2> ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * 47 <2> ; Page 48 <2> 49 <2> ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting 50 <2> 51 <2> %IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN 52 <2> %iassign $M_STRUC FALSE ;;AN000;; Let the assembler know that we have 53 <2> ;;AN000;; and include them 54 <2> 55 <2> ; PAGE 56 <2> ; SUBTTL DOS - Message Retriever - MSGSTR.INC Module 57 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 <2> ;; 59 <2> ;; STRUCTURE: $M_SUBLIST_STRUC 60 <2> ;; 61 <2> ;; Replacable parameters are described by a sublist structure 62 <2> ;; 63 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 <2> ;; 65 <2> $M_SUBLIST_STRUC STRUC ;;AN000;; 66 <2> ;; 67 <2> $M_S_SIZE DB ? ;11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) 68 <2> $M_S_RESV DB ? ;0 ;;AN000;; RESERVED 69 <2> $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item 70 <2> $M_S_ID DB ? ;;AN000;; n of %n 71 <2> $M_S_FLAG DB ? ;;AN000;; Data-type flags 72 <2> $M_S_MAXW DB ? ;;AN000;; Maximum field width 73 <2> $M_S_MINW DB ? ;;AN000;; Minimum field width 74 <2> $M_S_PAD DB ? ;;AN000;; Character for Pad field 75 <2> ;; 76 <2> $M_SUBLIST_STRUC ENDS ;;AN000;; 77 <2> ;; 78 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 <2> ;; 80 <2> ;; STRUCTURE: $M_CLASS_ID 81 <2> ;; 82 <2> ;; Each class will be defined by this structure. 83 <2> ;; 84 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 <2> ;; 86 <2> EXPECTED_VERSION equ expected_version ; NASM port equate 87 <2> 88 <2> $M_CLASS_ID STRUC ;;AN000;; 89 <2> ;; 90 <2> $M_CLS_ID DB ? ;-1 ;;AN000;; Class identifer 91 <2> $M_COMMAND_VER DW ? ;EXPECTED_VERSION ;;AN003;; COMMAND.COM version check 92 <2> $M_NUM_CLS_MSG DB ? ;0 ;;AN000;; Total number of message in class 93 <2> ;; 94 <2> $M_CLASS_ID ENDS ;; 95 <2> ;;AN000;; 96 <2> $M_CLASS_ID_SZ EQU $M_CLASS_ID_struc_size ;;AN000;; 97 <2> ;; 98 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 <2> ;; 100 <2> ;; STRUCTURE: $M_ID_STRUC 101 <2> ;; 102 <2> ;; Each message will be defined by this structure. 103 <2> ;; 104 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 105 <2> ;; 106 <2> $M_ID STRUC ;;AN000;; 107 <2> ;; 108 <2> $M_NUM DW ? ;-1 ;;AN000;; Message Number 109 <2> $M_TXT_PTR DW ? ;;AN000;; Pointer to message text 110 <2> ;; 111 <2> $M_ID ENDS ;;AN000;; 112 <2> ;;AN000;; Status Flag Values: 113 <2> $M_ID_SZ EQU $M_ID_struc_size ;;AN000;; 114 <2> ;; 115 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 <2> ;; 117 <2> ;; STRUCTURE: $M_RES_ADDRS 118 <2> ;; 119 <2> ;; Resident data area definition of variables 120 <2> ;; 121 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122 <2> ;; 123 <2> $M_RES_ADDRS STRUC ;;AN000;; 124 <2> ;; 125 <2> $M_EXT_ERR_ADDRS DD ? ;0 ;;AN000;; Allow pointers to THREE Extended error locations 126 <2> $M_EXT_FILE DD ? ;0 ;;AN001;; 127 <2> $M_EXT_COMMAND DD ? ;0 ;;AN000;; 128 <2> $M_EXT_TERM DD ? ;-1 ;;AN000;; 129 <2> $M_PARSE_COMMAND DD ? ;0 ;;AN000;; 130 <2> $M_PARSE_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Parse error locations 131 <2> $M_PARSE_TERM DD ? ;-1 ;;AN000;; 132 <2> $M_CRIT_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Critical error locations 133 <2> $M_CRIT_COMMAND DD ? ;0 ;;AN000;; 134 <2> $M_CRIT_TERM DD ? ;-1 ;;AN000;; 135 <2> $M_DISK_PROC_ADDR DD ? ;-1 ;;AN004;; Address of READ_DISK_PROC 136 <2> $M_CLASS_ADDRS DD $M_NUM_CLS DUP (?) ;(0) ;;AN000;; Allow pointers to specified classes 137 <2> $M_CLS_TERM DD ? ;-1 ;;AN000;; 138 <2> $M_DBCS_VEC DD ? ;0 ;;AN000;; Save DBCS vector 139 <2> $M_HANDLE DW ? ;;AN000;; 140 <2> $M_SIZE DB ? ;0 ;;AN000;; 141 <2> $M_CRLF DB ?,? ;0DH,0AH ;;AN004;; CR LF message 142 <2> $M_CLASS DB ? ;;AN004;; Saved class 143 <2> $M_RETURN_ADDR DW ? ;;AN000;; 144 <2> $M_MSG_NUM DW ? ;$M_NULL ;;AN000;; 145 <2> $M_DIVISOR DW ? ;10 ;;AN000;; Default = 10 (must be a WORD for division) 146 <2> $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP (?) ;("$") ;;AN000;; Temporary buffer 147 <2> $M_BUF_TERM DB ? ;"$" ;;AN000;; 148 <2> 149 <2> $M_RES_ADDRS ENDS ;;AN000;; 150 <2> ;; 151 <2> $M_RES_ADDRS_SZ EQU $M_RES_ADDRS_struc_size ;;AN000;; 152 <2> ;; 153 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 <2> ;; 155 <2> ;; STRUCTURE: $M_COUNTRY_INFO 156 <2> ;; 157 <2> ;; Important fields of the Get Country Information call 158 <2> ;; 159 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 <2> ;; 161 <2> $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation 162 <2> ;; 163 <2> $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc 164 <2> $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format 165 <2> $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; 166 <2> $M_THOU_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Thou Separator 167 <2> $M_DECI_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Decimal Separator 168 <2> $M_DATE_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Date Separator 169 <2> $M_TIME_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Time Separator 170 <2> $M_CURR_FORMAT DB ? ;;AN000;; 171 <2> $M_SIG_DIGS_CU DB ? ;;AN000;; 172 <2> $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format 173 <2> ;; 174 <2> $M_COUNTRY_INFO ENDS ;;AN000;; 175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 176 <2> ;; 177 <2> %ELSE ;;AN000;; ELSE if we have already included the STRUCTURES 178 <2> ; 179 <2> ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section 180 <2> 181 <2> %IF MSGDATA ;;AN000;; IF this is a request to include the data area 182 <2> %iassign MSGDATA FALSE ;;AN000;; Let the assembler know not to include it again 183 <2> ;;AN000;; and include it 184 <2> ; PAGE 185 <2> ; SUBTTL DOS - Message Retriever - MSGRES.TAB Module 186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187 <2> ;; 188 <2> ;; DATA NAME: $M_RES_TABLE 189 <2> ;; 190 <2> ;; REFERENCE LABEL: $M_RT 191 <2> ;; 192 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 193 <2> 194 <2> %if 0 ; disabled for now, figure out later 195 <2> %IF COMR ;;AN000;; Since COMMAND.COM includes this twice 196 <2> $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no 197 <2> $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur 198 <2> $M_ALTLABEL equ TRUE ;;AN000;; Flag that label was changed 199 <2> %ELSE ;;AN000;; 200 <2> $M_RT LABEL BYTE ;;AN000;; 201 <2> %ENDIF 202 <2> %endif 203 <2> $M_RT: ; NASM structure instance 204 <2> $M_RES_ADDRS_size equ $M_RES_ADDRS_struc_size ; NASM port equate 205 <2> istruc $M_RES_ADDRS 206 <2> at $M_EXT_ERR_ADDRS 207 <2> dd 0 208 <2> at $M_EXT_FILE 209 <2> dd 0 210 <2> at $M_EXT_COMMAND 211 <2> dd 0 212 <2> at $M_EXT_TERM 213 <2> dd -1 214 <2> at $M_PARSE_COMMAND 215 <2> dd 0 216 <2> at $M_PARSE_ADDRS 217 <2> dd 0 218 <2> at $M_PARSE_TERM 219 <2> dd -1 220 <2> at $M_CRIT_ADDRS 221 <2> dd 0 222 <2> at $M_CRIT_COMMAND 223 <2> dd 0 224 <2> at $M_CRIT_TERM 225 <2> dd -1 226 <2> at $M_DISK_PROC_ADDR 227 <2> dd -1 228 <2> at $M_CLASS_ADDRS 229 <2> times $M_NUM_CLS dd 0 230 <2> at $M_CLS_TERM 231 <2> dd -1 232 <2> at $M_DBCS_VEC 233 <2> dd 0 234 <2> at $M_HANDLE 235 <2> dw 0 236 <2> at $M_SIZE 237 <2> db 0 238 <2> at $M_CRLF 239 <2> db 0Dh, 0Ah 240 <2> at $M_CLASS 241 <2> db 0 242 <2> at $M_RETURN_ADDR 243 <2> dw 0 244 <2> at $M_MSG_NUM 245 <2> dw 0 246 <2> at $M_DIVISOR 247 <2> dw 10 248 <2> at $M_TEMP_BUF 249 <2> times $M_TEMP_BUF_SZ db "$" 250 <2> at $M_BUF_TERM 251 <2> db "$" 252 <2> iend 253 <2> ;; 254 <2> %include "copyrigh.mac" ;;AN001;; Include Copyright 1988 Microsoft 255 <2> ;; 256 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 257 <2> %ENDIF ;;AN000;; END of include of Data table 258 <2> 259 <2> ; 260 <2> %IFN $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN 261 <2> ;; don't include any more code 262 <2> ;;AN000;; Figure out what other code to include 263 <2> %IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code 264 <2> %IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) 265 <2> $M_RT EQU $M_RT2 ;;AN003;; 266 <2> %ENDIF 267 <2> %iassign DISK_PROC FALSE ;;AN003;; Yes, THEN include it and reset flag 268 <2> ; PAGE 269 <2> ; SUBTTL DOS - Message Retriever - DISK_PROC Module 270 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 271 <2> ;; 272 <2> ;; PROC NAME: DISK_PROC 273 <2> ;; 274 <2> ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended 275 <2> ;; errors from disk\diskette 276 <2> ;; INPUTS: AX has the message number 277 <2> ;; DX has the message class 278 <2> ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is 279 <2> ;; assumed to be set!! 280 <2> ;; 281 <2> ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text 282 <2> ;; 283 <2> ;; 284 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 285 <2> ;; 286 <2> PUBLIC READ_DISK_PROC ;; 287 <2> ;; 288 <2> READ_DISK_PROC PROC FAR ;;AN003;; 289 <2> 290 <2> PUSH AX ;;AN003;; Save everything 291 <2> PUSH BX ;;AN003;; 292 <2> PUSH DX ;;AN003;; 293 <2> PUSH SI ;;AN003;; 294 <2> PUSH BP ;;AN003;; 295 <2> PUSH DS ;;AN003;; 296 <2> PUSH DI ;;AN003;; 297 <2> MOV BP,AX ;;AN003;; Save message number 298 <2> MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function 299 <2> LEA SI,[COMSPEC wrt RESGROUP] ;;AN003;; Get addressibilty to COMMAND.COM 300 <2> PUSH CS ;;AN003;; 301 <2> POP DS ;;AN003;; 302 <2> MOV DI,-1 ;;AN003;; No extended attribute list 303 <2> MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error 304 <2> MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag 305 <2> INT 21H ;;AN003;; Open the file 306 <2> POP DI ;;AN003;; Retreive LSEEK pointer 307 <2> ;;AN003;; Error ? 308 <2> ; $IF NC,LONG ;;AN003;; No, 309 <2> JNC $MXL1 310 <2> JMP $MIF1 311 <2> $MXL1: 312 <2> PUSH DI ;;AN003;; Save LSEEK pointer 313 <2> MOV BX,AX ;;AN003;; Set handle in BX 314 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors 315 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 316 <2> MOV DX,DI ;;AN003;; 317 <2> INT 21H ;;AN003;; LSEEK the file 318 <2> POP DX ;;AN003;; Retreive LSEEK pointer 319 <2> ;;AN003;; Error ? 320 <2> ; $IF NC ;;AN003;; No, 321 <2> JC $MIF2 322 <2> INC CX ;;AN003;; Set flag to first pass 323 <2> ; $DO ;;AN003;; 324 <2> $MDO3: 325 <2> PUSH DX ;;AN003;; Save LSEEK pointer 326 <2> PUSH CX ;;AN003;; Save first pass flag 327 <2> PUSH AX ;;AN003;; Save number of messages (if set yet) 328 <2> XOR SI,SI ;;AN003;; Reset buffer index 329 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 330 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header 331 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 332 <2> INT 21H ;;AN003;; Read it 333 <2> MOV DI,DX ;;AN003;; 334 <2> POP AX ;;AN003;; 335 <2> POP CX ;;AN003;; 336 <2> OR CX,CX ;;AN003;; 337 <2> ; $IF NZ ;;AN003;; 338 <2> JZ $MIF4 339 <2> XOR CX,CX ;;AN003;; Set flag to second pass 340 <2> XOR AH,AH ;;AN003;; Get number of messages in class 341 <2> MOV AL,[DI + $M_NUM_CLS_MSG] ;;AN003;; 342 <2> MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index 343 <2> CMP word [DI + $M_COMMAND_VER],EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? 344 <2> ; $ENDIF ;;AN003;; 345 <2> $MIF4: 346 <2> POP DX ;;AN003;; 347 <2> ; $IF Z ;;AN003;; Yes, 348 <2> JNZ $MIF6 349 <2> ; $SEARCH ;;AN003;; 350 <2> $MDO7: 351 <2> CMP BP,WORD PTR [$M_RT + $M_TEMP_BUF + SI] ;;AN003;; Is this the message I'm looking for? 352 <2> ; $EXITIF Z ;;AN003;; Yes, (ZF=1) 353 <2> JNZ $MIF7 354 <2> CLC ;;AN003;; Reset carry, exit search 355 <2> ; $ORELSE ;;AN003;; No, (ZF=0) 356 <2> JMP SHORT $MSR7 357 <2> $MIF7: 358 <2> ADD SI,$M_ID_SZ ;;AN003;; Increment index 359 <2> ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header 360 <2> DEC AX ;;AN003;; Decrement # of messages left 361 <2> ; $LEAVE Z ;;AN003;; Have we exhausted all messages? 362 <2> JZ $MEN7 363 <2> CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? 364 <2> ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) 365 <2> JNA $MDO7 366 <2> $MEN7: 367 <2> STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) 368 <2> ; $ENDSRCH ;;AN003;; 369 <2> $MSR7: 370 <2> ; $ELSE ;;AN003;; No, 371 <2> JMP SHORT $MEN6 372 <2> $MIF6: 373 <2> XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop 374 <2> STC ;;AN003;; Set Carry 375 <2> ; $ENDIF ;;AN003;; 376 <2> $MEN6: 377 <2> ; $ENDDO Z ;;AN003;; Get next buffer full if needed 378 <2> JNZ $MDO3 379 <2> ;;AN003;; Error ? 380 <2> ; $IF NC ;;AN003;; No, 381 <2> JC $MIF16 382 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message 383 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 384 <2> ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header 385 <2> ADD DX,WORD PTR [$M_RT + $M_TEMP_BUF + SI + 2] ;;AN003;; Add offset from msg structure 386 <2> INT 21H ;;AN003;; LSEEK the file 387 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 388 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message 389 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 390 <2> INT 21H ;;AN003;; Read it 391 <2> MOV DI,DX ;;AN003;; into the temp buffer 392 <2> PUSH DS ;;AN003;; into the temp buffer 393 <2> POP ES ;;AN003;; into the temp buffer 394 <2> ; $ENDIF ;;AN003;; 395 <2> $MIF16: 396 <2> ; $ENDIF ;;AN003;; 397 <2> $MIF2: 398 <2> PUSHF ;;AN003;; Close file handle 399 <2> MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle 400 <2> INT 21H ;;AN003;; 401 <2> $M_POPF ;;AN003;; 402 <2> ; $ENDIF ;;AN003;; Yes there was an error, 403 <2> $MIF1: 404 <2> POP DS ;;AN003;; 405 <2> POP BP ;;AN003;; 406 <2> POP SI ;;AN003;; 407 <2> POP DX ;;AN003;; 408 <2> POP BX ;;AN003;; 409 <2> POP AX ;;AN003;; 410 <2> ;;AN003;; abort everything 411 <2> RET ;;AN003;; 412 <2> 413 <2> READ_DISK_PROC ENDP ;;AN003;; 414 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 415 <2> %ENDIF ;;AN003;; END of include for DISK_PROC 416 <2> ; 417 <2> 418 <2> %IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO 419 <2> %iassign SETSTDIO FALSE ;;AN000;; Yes, THEN include it and reset flag 420 <2> ; PAGE 421 <2> ; SUBTTL DOS - Message Retriever - SETSTDIO Module 422 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 423 <2> ;; 424 <2> ;; PROC NAME: SETSTDIO 425 <2> ;; 426 <2> ;; FUNCTION: 427 <2> ;; INPUTS: 428 <2> ;; 429 <2> ;; OUPUTS: 430 <2> ;; 431 <2> ;; 432 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 433 <2> ;; 434 <2> %IF FARmsg ;AN001; 435 <2> SETSTDINON PROC FAR ;AN001; 436 <2> %ELSE ;AN001; 437 <2> SETSTDINON PROC NEAR ;AN001; 438 <2> %ENDIF ;AN001; 439 <2> PUSH AX ;AN002; Save changed regs 440 <2> PUSH BX ;AN002; 441 <2> PUSH DX ;AN002; 442 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 443 <2> MOV BX,STDIN ;AN001; 444 <2> XOR DX,DX ;AN001; 445 <2> INT 21H ;AN001; 446 <2> 447 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 448 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 449 <2> INT 21H ;AN001; 450 <2> POP DX ;AN002; Restore Regs 451 <2> POP BX ;AN002; 452 <2> POP AX ;AN002; 453 <2> 454 <2> RET ;AN001; 455 <2> ;AN001; 456 <2> SETSTDINON ENDP ;AN001; 457 <2> 458 <2> %IF FARmsg ;AN001; 459 <2> SETSTDINOFF PROC FAR ;AN001; 460 <2> %ELSE ;AN001; 461 <2> SETSTDINOFF PROC NEAR ;AN001; 462 <2> %ENDIF ;AN001; 463 <2> 464 <2> PUSH AX ;AN002; Save changed regs 465 <2> PUSH BX ;AN002; 466 <2> PUSH DX ;AN002; 467 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 468 <2> MOV BX,STDIN ;AN001; 469 <2> XOR DX,DX ;AN001; 470 <2> INT 21H ;AN001; 471 <2> 472 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 473 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 474 <2> INT 21H ;AN001; 475 <2> POP DX ;AN002; Restore Regs 476 <2> POP BX ;AN002; 477 <2> POP AX ;AN002; 478 <2> 479 <2> RET ;AN001; 480 <2> 481 <2> SETSTDINOFF ENDP ;AN001; 482 <2> 483 <2> %IF FARmsg ;AN001; 484 <2> SETSTDOUTON PROC FAR ;AN001; 485 <2> %ELSE ;AN001; 486 <2> SETSTDOUTON PROC NEAR ;AN001; 487 <2> %ENDIF ;AN001; 488 <2> 489 <2> PUSH AX ;AN002; Save changed regs 490 <2> PUSH BX ;AN002; 491 <2> PUSH DX ;AN002; 492 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 493 <2> MOV BX,STDOUT ;AN001; 494 <2> XOR DX,DX ;AN001; 495 <2> INT 21H ;AN001; 496 <2> 497 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 498 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 499 <2> INT 21H ;AN001; 500 <2> POP DX ;AN002; Restore Regs 501 <2> POP BX ;AN002; 502 <2> POP AX ;AN002; 503 <2> 504 <2> RET ;AN001; 505 <2> 506 <2> SETSTDOUTON ENDP ;AN001; 507 <2> 508 <2> %IF FARmsg ;AN001; 509 <2> SETSTDOUTOFF PROC FAR ;AN001; 510 <2> %ELSE ;AN001; 511 <2> SETSTDOUTOFF PROC NEAR 512 <2> %ENDIF ;AN001; 513 <2> 514 <2> PUSH AX ;AN002; Save changed regs 515 <2> PUSH BX ;AN002; 516 <2> PUSH DX ;AN002; 517 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 518 <2> MOV BX,STDOUT ;AN001; 519 <2> XOR DX,DX ;AN001; 520 <2> INT 21H ;AN001; 521 <2> 522 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 523 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 524 <2> INT 21H ;AN001; 525 <2> POP DX ;AN002; Restore Regs 526 <2> POP BX ;AN002; 527 <2> POP AX ;AN002; 528 <2> 529 <2> RET ;AN001; 530 <2> 531 <2> SETSTDOUTOFF ENDP ;AN001; 532 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 533 <2> %ENDIF ;;AN000;; END of include for SETSTDIO 534 <2> ; 535 <2> %IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? 536 <2> %IF COMR ;;AN000;; 537 <2> $M_RT EQU $M_RT2 ;;AN000;; 538 <2> %ENDIF 539 <2> %iassign LOADmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 540 <2> ; PAGE 541 <2> ; SUBTTL DOS - Message Retriever - LOADMSG.ASM Module 542 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 543 <2> ;; 544 <2> ;; PROC NAME: SYSLOADMSG 545 <2> ;; 546 <2> ;; FUNCTION: 547 <2> ;; INPUTS: 548 <2> ;; 549 <2> ;; OUPUTS: 550 <2> ;; 551 <2> ;; 552 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 553 <2> ;; 554 <2> %IF FARmsg ;;AN000;; 555 <2> SYSLOADMSG PROC FAR ;;AN000;; 556 <2> %ELSE ;;AN000;; 557 <2> SYSLOADMSG PROC NEAR ;;AN000;; 558 <2> %ENDIF ;;AN000;; 0 00000EE1 50 PUSH AX ;;AN000; 0 00000EE2 53 PUSH BX ;;AN000; 0 00000EE3 52 PUSH DX ;;AN000; 0 00000EE4 06 PUSH ES ;;AN000; 0 00000EE5 57 PUSH DI ;;AN000; 0 00000EE6 31C9 XOR CX,CX ;;AN000; Reset to zero 0 00000EE8 8EC1 MOV ES,CX ;;AN000; 0 00000EEA 31FF XOR DI,DI ;;AN000; 0 00000EEC B82E12 MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 0 00000EEF B200 MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM 0 00000EF1 CD2F INT 2FH ;;AN000;; Private interface 0 00000EF3 2E8C06[0A00] MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 0 00000EF8 2E893E[0800] MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND],DI ;;AN000;; 572 <2> ;; 0 00000EFD B82E12 MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 0 00000F00 B202 MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM 0 00000F02 CD2F INT 2FH ;;AN000;; Private interface 0 00000F04 2E8C06[1200] MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 0 00000F09 2E893E[1000] MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND],DI ;;AN000;; 578 <2> ;; 0 00000F0E B82E12 MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 0 00000F11 B204 MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM 0 00000F13 CD2F INT 2FH ;;AN000;; Private interface 0 00000F15 2E8C06[2200] MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 0 00000F1A 2E893E[2000] MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND],DI ;;AN000;; 584 <2> 0 00000F1F B82E12 MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 0 00000F22 B206 MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE 0 00000F24 CD2F INT 2FH ;;AN001;; Private interface 0 00000F26 2E8C06[0600] MOV WORD PTR [cs:$M_RT + $M_EXT_FILE+2],ES ;;AN001;; Move into first avaliable table location 0 00000F2B 2E893E[0400] MOV WORD PTR [cs:$M_RT + $M_EXT_FILE],DI ;;AN001;; 590 <2> 591 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 592 <2> Extrn READ_DISK_PROC:Far ;;AN003;; 593 <2> %ELSE ;; 594 <2> %IF FARmsg ;;AN000;; 595 <2> CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 596 <2> %ELSE ;;AN000;; 0 00000F30 E86A06 CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 598 <2> %ENDIF ;;AN000;; 0 00000F33 2E8C06[0200] MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 0 00000F38 2E893E[0000] MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS],DI ;;AN000;; 0 00000F3D 2E8C06[1E00] MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 0 00000F42 2E893E[1C00] MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS],DI ;;AN000;; 603 <2> ;; 604 <2> %IF FARmsg ;;AN000;; 605 <2> CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 606 <2> %ELSE ;;AN000;; 0 00000F47 E8D106 CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 608 <2> %ENDIF ;;AN000;; 0 00000F4A 2E8C06[1600] MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 0 00000F4F 2E893E[1400] MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS],DI ;;AN000;; 611 <2> %ENDIF ;; 612 <2> ;; 0 00000F54 B82E12 MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 0 00000F57 B208 MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM 0 00000F59 CD2F INT 2FH ;;AN001;; Private interface 0 00000F5B 2E8C06[2A00] MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR+2],ES ;;AN001;; Move into first avaliable table location 0 00000F60 2E893E[2800] MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR],DI ;;AN001;; 618 <2> 619 <2> $M_BUILD_PTRS $M_NUM_CLS ;;AN000;; Build all utility classes 444 <3> %iassign $M_INDEX 0 445 <3> %if COMR 446 <3> $M_MAKE_COMR 447 <3> %elif COMT 448 <3> $M_MAKE_COMT 449 <3> %else 450 <3> %iassign $M_INDEX 0 451 <3> %iassign $M_COUNT 0 452 <3> %rep %1 453 <3> %iassign $M_COUNT $M_COUNT + 1 454 <3> $M_MAKE $M_COUNT 455 <3> %endrep 453 <4> %iassign $M_COUNT $M_COUNT + 1 454 <4> $M_MAKE $M_COUNT 464 <5> %IF FARmsg 465 <5> CALL FAR $M_CLS_%1 466 <5> MOV WORD PTR [cs:$M_RT + $M_CLASS_ADDRS+$M_INDEX+2],ES 467 <5> MOV WORD PTR [cs:$M_RT + $M_CLASS_ADDRS+$M_INDEX],DI 468 <5> %ELSE 0 00000F65 E8F905 CALL $M_CLS_%1 0 00000F68 2E893E[2C00] MOV WORD PTR [cs:$M_RT + $M_CLASS_ADDRS+$M_INDEX],DI 471 <5> %ENDIF 472 <5> %iassign $M_INDEX $M_INDEX + 4 473 <5> 456 <3> %endif 620 <2> ;;AN000;; 0 00000F6D E81900 CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector 622 <2> 623 <2> %IFN NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed 0 00000F70 E83000 CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK 625 <2> %ENDIF ;;AN000;; 626 <2> ;;AN000;; 627 <2> %IFN NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed 0 00000F73 E84000 CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK 629 <2> %ENDIF ;;AN000;; 630 <2> ;;AN000;; 631 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 632 <2> CLC ;;AN000;; Make sure carry is clear 633 <2> %ELSE ;;AN000;; ELSE 0 00000F76 51 PUSH CX ;;AN000;; 0 00000F77 E89600 CALL $M_VERSION_CHECK ;;AN000;; Check Version 636 <2> %ENDIF ;;AN000;; 637 <2> ;; Error ? 638 <2> ; $IF NC ;;AN000;; No. 0 00000F7A 7208 JC $MIF20 640 <2> %IFN NOVERCHECKmsg ;;AN000;; IF version check was not supressed 0 00000F7C 59 POP CX ;;AN000;; Reset stack 642 <2> %ENDIF ;;AN000;; 0 00000F7D 5F POP DI ;;AN000;; Restore REGS 0 00000F7E 07 POP ES ;;AN000;; 0 00000F7F 5A POP DX ;;AN000;; 0 00000F80 5B POP BX ;;AN000;; 0 00000F81 58 POP AX ;;AN000;; 648 <2> ; $ELSE ;;AN000;; Yes, 0 00000F82 EB04 JMP SHORT $MEN20 650 <2> $MIF20: 651 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 652 <2> ADD SP,10 ;;AN000;; 653 <2> STC ;;AN000;; Reset carry flag 654 <2> %ELSE ;;AN000;; IF version check is to be supressed 0 00000F84 83C40C ADD SP,12 ;;AN000;; 0 00000F87 F9 STC ;;AN000;; Reset carry flag 657 <2> %ENDIF ;;AN000;; IF version check is to be supressed 658 <2> ; $ENDIF ;;AN000;; 659 <2> $MEN20: 0 00000F88 C3 RET ;;AN000;; 661 <2> ;; 662 <2> SYSLOADMSG ENDP ;;AN000;; 663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 664 <2> ; PAGE 665 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 666 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 667 <2> ;; 668 <2> ;; Proc Name: $M_GET_DBCS_VEC 669 <2> ;; 670 <2> ;; Function: Get the DBCS vector and save it for later use 671 <2> ;; 672 <2> ;; Inputs: None 673 <2> ;; 674 <2> ;; Outputs: None 675 <2> ;; 676 <2> ;; Regs Changed: 677 <2> ;; 678 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 679 <2> ;; 680 <2> $M_GET_DBCS_VEC PROC NEAR ;;AN000;; 681 <2> ;; 0 00000F89 50 PUSH AX ;;AN000;; Save character to check 0 00000F8A 56 PUSH SI ;;AN000;; 0 00000F8B 1E PUSH DS ;;AN000;; 0 00000F8C B80063 MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment 0 00000F8F CD21 INT 21H ;;AN000;; Get environment pointer 0 00000F91 1E PUSH DS ;;AN000;; Get environment pointer 0 00000F92 07 POP ES ;;AN000;; Get environment pointer 0 00000F93 1F POP DS ;;AN000;; Get environment pointer 690 <2> ; $IF NC ;;AN000;; 0 00000F94 720A JC $MIF23 0 00000F96 2E8936[3400] MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC],SI ;;AN000;; Save DBCS Vector 0 00000F9B 2E8C06[3600] MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC+2],ES ;;AN000;; 694 <2> ; $ENDIF ;;AN000;; 695 <2> $MIF23: 0 00000FA0 5E POP SI ;;AN000;; 0 00000FA1 58 POP AX ;;AN000;; Retrieve character to check 0 00000FA2 C3 RET ;;AN000;; Return 699 <2> ;; 700 <2> $M_GET_DBCS_VEC ENDP ;; 701 <2> ;; 702 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 703 <2> %IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? 704 <2> %ELSE ;AN001; Yes, THEN include it 705 <2> ; PAGE 706 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc 707 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 708 <2> ;; 709 <2> ;; Proc Name: $M_CHECKSTDIN 710 <2> ;; 711 <2> ;; Function: 712 <2> ;; 713 <2> ;; Inputs: None 714 <2> ;; 715 <2> ;; Outputs: 716 <2> ;; 717 <2> ;; Regs Changed: 718 <2> ;; 719 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 720 <2> ;; 721 <2> $M_CHECKSTDIN PROC NEAR ;AN001; 722 <2> 0 00000FA3 B80044 MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 0 00000FA6 BB0000 MOV BX,STDIN ;AN001; 0 00000FA9 31D2 XOR DX,DX ;AN001; 0 00000FAB CD21 INT 21H ;AN001; 727 <2> 0 00000FAD 80CE01 OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 0 00000FB0 B80144 MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 0 00000FB3 CD21 INT 21H ;AN001; 731 <2> 0 00000FB5 C3 RET ;AN001; 733 <2> 734 <2> $M_CHECKSTDIN ENDP ;AN001; 735 <2> ;; 736 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 737 <2> %ENDIF ;AN001; END of include for EOF Check 738 <2> %IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? 739 <2> %ELSE ;AN001; Yes, THEN include it 740 <2> ; PAGE 741 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc 742 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 743 <2> ;; 744 <2> ;; Proc Name: $M_CHECKSTDOUT 745 <2> ;; 746 <2> ;; Function: 747 <2> ;; 748 <2> ;; Inputs: None 749 <2> ;; 750 <2> ;; Outputs: 751 <2> ;; 752 <2> ;; Regs Changed: 753 <2> ;; 754 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 755 <2> ;; 756 <2> $M_CHECKSTDOUT PROC NEAR ;AN001; 757 <2> 0 00000FB6 B80044 MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 0 00000FB9 BB0100 MOV BX,STDOUT ;AN001; 0 00000FBC 31D2 XOR DX,DX ;AN001; 0 00000FBE CD21 INT 21H ;AN001; 762 <2> 0 00000FC0 80CE01 OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 0 00000FC3 B80144 MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 0 00000FC6 CD21 INT 21H ;AN001; 766 <2> 0 00000FC8 C3 RET ;AN001; 768 <2> 769 <2> $M_CHECKSTDOUT ENDP ;AN001; 770 <2> ;; 771 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 772 <2> %ENDIF ;AN001; END of include for Disk Full Check 773 <2> %IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? 774 <2> %ELSE ;;AN000;; Yes, THEN include it 775 <2> ; PAGE 776 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 778 <2> ;; 779 <2> ;; Proc Name: $M_VERSION_CHECK 780 <2> ;; 781 <2> ;; Function: Determine if DOS version is within allowable limits 782 <2> ;; 783 <2> ;; Inputs: None 784 <2> ;; 785 <2> ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version 786 <2> ;; Registers set for SYSDISPMSG 787 <2> ;; CARRY_FLAG = 0 if Correct DOS version 788 <2> ;; 789 <2> ;; Regs Changed: AX 790 <2> ;; 791 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 792 <2> 793 <2> check_amis: 0 00000FC9 50 push ax 0 00000FCA 1E push ds 0 00000FCB 56 push si 0 00000FCC 06 push es 0 00000FCD 57 push di 0 00000FCE 52 push dx 0 00000FCF 50 push ax ; version number, last on stack 801 <2> 0 00000FD0 B400 mov ah, 0 ; multiplex number = 0 803 <2> .loop: 0 00000FD2 B000 mov al, 0 0 00000FD4 CD2D int 2Dh ; installation check 0 00000FD6 3CFF cmp al, -1 ; multiplexer installed ? 0 00000FD8 7520 jne .next ; no --> 0 00000FDA 0E push cs 0 00000FDB 1F pop ds 0 00000FDC BE[0000] mov si, offset amis_sign ; ds:si -> amis_sign (for lDOS) 0 00000FDF 8EC2 mov es, dx ; es:di -> multiplexer's sign 0 00000FE1 B90800 mov cx, 8 ; 16 bytes 0 00000FE4 F3A7 repe cmpsw ; compare 0 00000FE6 7512 jne .next ; not us --> 0 00000FE8 8CCA mov dx, cs ; dx:si -> amis_id 0 00000FEA B011 mov al, 11h 0 00000FEC CD2D int 2Dh ; CHG: al, bx, cx, dx, si, di 0 00000FEE 3C00 cmp al, 0 ; id call supported ? 0 00000FF0 740C je .unsup ; no, allow if alt version --> 0 00000FF2 5A pop dx 0 00000FF3 31D2 xor dx, dx ; 2D.MM11 supported, mark that we need it 0 00000FF5 52 push dx 0 00000FF6 3CF0 cmp al, 0F0h ; CY if below 0F0h 0 00000FF8 EB05 jmp .done 825 <2> 826 <2> .next: 0 00000FFA FEC4 inc ah ; next multiplex number 0 00000FFC 75D4 jnz .loop ; ZR if done, NZ if more to check --> 829 <2> .unsup: 0 00000FFE F9 stc ; multiplexer not found 831 <2> ; or function not supported 832 <2> .done: 833 <2> ; CY if not an lDOS revision with our id supported, 834 <2> ; on stack: alt_expected_version if it's fine and either 835 <2> ; no multiplexer or func 11h not supported 836 <2> ; new_expected_version if not fine and either 837 <2> ; no multiplexer or func 11h not suppprted, 838 <2> ; 0 if multiplexer found, func 11h supported, but 839 <2> ; our id is unsupported 840 <2> ; NC if lDOS revision with multiplexer and our id supported 0 00000FFF 5B pop bx 0 00001000 5A pop dx 0 00001001 5F pop di 0 00001002 07 pop es 0 00001003 5E pop si 0 00001004 1F pop ds 0 00001005 58 pop ax 0 00001006 731B jnc alt_good_DOS ; id is supported --> 0 00001008 81FB051A cmp bx, alt_expected_version ; is it fine ? 0 0000100C 7415 je alt_good_DOS ; yes --> (NC) 0 0000100E EB16 jmp $MIF25 ; no, cancel program --> 852 <2> 853 <2> $M_VERSION_CHECK PROC NEAR ;;AN000;; 854 <2> ;; 0 00001010 B430 MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC 0 00001012 CD21 INT 21H ;;AN000;; 857 <2> ;; 0 00001014 3D0526 cmp ax,new_expected_version ; compare with DOS version 0 00001017 74B0 je check_amis 0 00001019 3D051A cmp ax,alt_expected_version ; compare with DOS version 0 0000101C 74AB je check_amis 0 0000101E 83F804 CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct 863 <2> ; $IF E ;;AN000;; 0 00001021 7503 JNE $MIF25 865 <2> alt_good_DOS: 0 00001023 F8 CLC ;;AN000;; Clear the carry flag 867 <2> ; $ELSE ;;AN000;; ELSE 0 00001024 EB18 JMP SHORT $MEN25 869 <2> $MIF25: 870 <2> %IFN COMR ;; ** Special case for RESIDENT COMMAND.COM 0 00001026 83F802 CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH 872 <2> ; $IF B ;;AN000;; No, 0 00001029 7305 JNB $MIF27 0 0000102B BBFFFF MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) 875 <2> ; $ELSE ;;AN000;; Yes, 0 0000102E EB03 JMP SHORT $MEN27 877 <2> $MIF27: 0 00001030 BB0200 MOV BX,STDERR ;;AN000;; Standard Error 879 <2> ; $ENDIF ;;AN000;; 880 <2> $MEN27: 881 <2> %ELSE 882 <2> MOV BX,NO_HANDLE ;;AN000;; No handle 883 <2> %ENDIF 0 00001033 B80100 MOV AX,1 ;;AN000;; Set message # 1 0 00001036 B90000 MOV CX,NO_REPLACE ;;AN000;; No replacable parms 0 00001039 B200 MOV DL,NO_INPUT ;;AN000;; No input 0 0000103B B6FF MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message 0 0000103D F9 STC ;;AN000;; Set Carry Flag 889 <2> ; $ENDIF ;;AN000;; 890 <2> $MEN25: 891 <2> ;; 0 0000103E C3 RET ;;AN000;; Return 893 <2> ;; 894 <2> $M_VERSION_CHECK ENDP ;; 895 <2> ;; 896 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 897 <2> %ENDIF ;;AN000;; END of include for DOS version check 898 <2> %ENDIF ;;AN000;; END of include for SYSLOADMSG 899 <2> ; 900 <2> %IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 901 <2> %IF COMR ;;AN000;; 902 <2> $M_RT EQU $M_RT2 ;;AN000;; 903 <2> %ENDIF ;;AN000;; 904 <2> GETmsg equ FALSE ;;AN000;; Yes, THEN include it and reset flag 905 <2> ; PAGE 906 <2> ; SUBTTL DOS - Message Retriever - GETMSG.ASM Module 907 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 <2> ;; 909 <2> ;; Proc Name: SYSGETMSG 910 <2> ;; 911 <2> ;; Function: The GET service returns the segment, offset and size of the 912 <2> ;; message text to the caller based on a message number. 913 <2> ;; The GET function will not display the message thus assumes 914 <2> ;; caller will handle replaceable parameters. 915 <2> ;; 916 <2> ;; Inputs: 917 <2> ;; 918 <2> ;; Outputs: 919 <2> ;; 920 <2> ;; Psuedocode: 921 <2> ;; Call $M_GET_MSG_ADDRESS 922 <2> ;; IF MSG_NUM exists THEN 923 <2> ;; Set DS:SI = MSG_TXT_PTR + 1 924 <2> ;; CARRY_FLAG = 0 925 <2> ;; ELSE 926 <2> ;; CARRY_FLAG = 1 927 <2> ;; ENDIF 928 <2> ;; 929 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 <2> ;; 931 <2> %IF FARmsg ;;AN000;; 932 <2> SYSGETMSG PROC FAR ;;AN000;; 933 <2> %ELSE ;;AN000;; 934 <2> SYSGETMSG PROC NEAR ;;AN000;; 935 <2> %ENDIF ;;AN000;; 936 <2> ;; 937 <2> ;; Save registers needed later 938 <2> 939 <2> PUSH AX ;;AN000;; Save changed regs 940 <2> PUSH ES ;;AN000;; 941 <2> PUSH DI ;;AN000;; 942 <2> PUSH BP ;;AN000;; 943 <2> ;; 944 <2> %IF FARmsg ;;AN000;; 945 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 946 <2> %ELSE ;;AN000;; 947 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 948 <2> %ENDIF ;;AN000;; Return message in ES:DI 949 <2> ; $IF NC ;;AN000;; Message found? 950 <2> JC $MIF31 951 <2> CMP DH,UTILITY_MSG_CLASS 952 <2> CLC ;;AN000;; 953 <2> ; $IF NE 954 <2> JE $MIF32 955 <2> PUSH ES ;;AN000;; 956 <2> POP DS ;;AN000;; Return message in DS:SI 957 <2> ; $ELSE 958 <2> JMP SHORT $MEN32 959 <2> $MIF32: 960 <2> %IF FARmsg ;;AN000;; Yes, 961 <2> PUSH ES ;;AN000;; 962 <2> POP DS ;;AN000;; Return message in DS:SI 963 <2> %ELSE ;;AN000;; 964 <2> PUSH CS ;;AN000;; Return message in DS:SI 965 <2> POP DS ;;AN000;; 966 <2> %ENDIF ;;AN000;; 967 <2> ; $ENDIF ;;AN000;; 968 <2> $MEN32: 969 <2> MOV SI,DI ;;AN000;; Return message in DS:SI 970 <2> ; $ENDIF ;;AN000;; 971 <2> $MIF31: 972 <2> ;; 973 <2> POP BP ;;AN000;; Restore changed regs 974 <2> POP DI ;;AN000;; 975 <2> POP ES ;;AN000;; 976 <2> POP AX ;;AN000;; 977 <2> ;; 978 <2> RET ;;AN000;; Return 979 <2> ;; 980 <2> SYSGETMSG ENDP ;; 981 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 982 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 983 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 984 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 985 <2> ;; 986 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 987 <2> ;; 988 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 989 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 990 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 991 <2> ;; IF CX > 1 THEN ES:DI points to the specified message 992 <2> ;; REGS CHANGED: ES,DI,CX 993 <2> ;; 994 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 995 <2> ;; 996 <2> %IF FARmsg ;;AN000;; 997 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 998 <2> %ELSE ;;AN000;; 999 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 1000 <2> %ENDIF ;;AN000;; 1001 <2> ;; 1002 <2> PUSH SI ;;AN000;; 1003 <2> PUSH BX ;;AN000;; 1004 <2> XOR SI,SI ;;AN000;; Use SI as an index 1005 <2> XOR CX,CX ;;AN000;; Use CX as an size 1006 <2> ; $DO ;;AN000;; 1007 <2> $MDO36: 1008 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 1009 <2> ; $IF E ;;AN000;; Yes, 1010 <2> JNE $MIF37 1011 <2> %IF FARmsg ;;AN000;; 1012 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1013 <2> MOV BX,ES ;;AN000; 1014 <2> %ELSE ;;AN000;; 1015 <2> MOV DI,WORD PTR [$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1016 <2> MOV BX,DI ;;AN000; 1017 <2> %ENDIF ;;AN000;; 1018 <2> ; $ELSE ;;AN000;; No, 1019 <2> JMP SHORT $MEN37 1020 <2> $MIF37: 1021 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 1022 <2> ; $IF NE ;;AN000;; Yes, 1023 <2> JE $MIF39 1024 <2> LES DI,[$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 1025 <2> MOV BX,ES ;;AN000; 1026 <2> ; $ELSE ;;AN000;; No, extended errors were specified 1027 <2> JMP SHORT $MEN39 1028 <2> $MIF39: 1029 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 1030 <2> ; $IF AE,AND ;;AN000;; 1031 <2> JNAE $MIF41 1032 <2> CMP AX,$M_CRIT_HI ;;AN000;; 1033 <2> ; $IF BE ;;AN000;; Yes, 1034 <2> JNBE $MIF41 1035 <2> LES DI,[$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 1036 <2> MOV BX,ES ;;AN000; 1037 <2> ; $ELSE ;;AN000;; 1038 <2> JMP SHORT $MEN41 1039 <2> $MIF41: 1040 <2> LES DI,[$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 1041 <2> MOV BX,ES ;;AN000; 1042 <2> ; $ENDIF ;;AN000;; 1043 <2> $MEN41: 1044 <2> ; $ENDIF ;;AN000;; 1045 <2> $MEN39: 1046 <2> ; $ENDIF ;;AN000;; 1047 <2> $MEN37: 1048 <2> ;; 1049 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 1050 <2> ; $IF E ;;AN000;; Yes, 1051 <2> JNE $MIF46 1052 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 1053 <2> ; $IF E ;;AN000;; Yes, 1054 <2> JNE $MIF47 1055 <2> STC ;;AN000;; Set the carry flag 1056 <2> ; $ELSE ;;AN000;; No, 1057 <2> JMP SHORT $MEN47 1058 <2> $MIF47: 1059 <2> MOV [$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 1060 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 1061 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 1062 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 1063 <2> CLC ;;AN000;; 1064 <2> ; $ENDIF ;;AN000;; No, 1065 <2> $MEN47: 1066 <2> ; $ELSE ;;AN000;; 1067 <2> JMP SHORT $MEN46 1068 <2> $MIF46: 1069 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 1070 <2> ; $IF NE ;;AN001;; Yes, 1071 <2> JE $MIF51 1072 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 1073 <2> ; $ENDIF ;;AN000;; 1074 <2> $MIF51: 1075 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 1076 <2> CLC ;;AN000;; 1077 <2> ; $ENDIF ;;AN000;; 1078 <2> $MEN46: 1079 <2> ; $LEAVE C ;;AN000;; 1080 <2> JC $MEN36 1081 <2> OR CX,CX ;;AN000;; Was the message found? 1082 <2> ; $ENDDO NZ,LONG ;;AN000;; 1083 <2> JNZ $MXL2 1084 <2> JMP $MDO36 1085 <2> $MXL2: 1086 <2> $MEN36: 1087 <2> 1088 <2> PUSHF ;;AN006;; Save the flag state 1089 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 1090 <2> ; $IF E ;;AN006;; Yes, 1091 <2> JNE $MIF56 1092 <2> PUSH DX ;;AN006;; Save all needed registers 1093 <2> PUSH BP ;;AN006;; 1094 <2> PUSH CX ;;AN006;; 1095 <2> PUSH ES ;;AN006;; 1096 <2> PUSH DI ;;AN006;; 1097 <2> PUSH AX ;;AN006;; 1098 <2> 1099 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 1100 <2> INT 2FH ;;AN006;; 1101 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 1102 <2> POP AX ;;AN006;; Restore msg number 1103 <2> ; $IF E ;;AN006;; Yes, 1104 <2> JNE $MIF57 1105 <2> MOV BX,AX ;;AN006;; BX is the extended error number 1106 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 1107 <2> INT 2FH ;;AN006;; Call IFSFUNC 1108 <2> ; $ELSE ;;AN006;; No, 1109 <2> JMP SHORT $MEN57 1110 <2> $MIF57: 1111 <2> STC ;;AN006;; Carry conditon 1112 <2> ; $ENDIF ;;AN006;; 1113 <2> $MEN57: 1114 <2> 1115 <2> ; $IF C ;;AN006;; Was there an update? 1116 <2> JNC $MIF60 1117 <2> POP DI ;;AN006;; No, 1118 <2> POP ES ;;AN006;; Restore old pointer 1119 <2> POP CX ;;AN006;; 1120 <2> ; $ELSE ;;AN006;; Yes 1121 <2> JMP SHORT $MEN60 1122 <2> $MIF60: 1123 <2> ADD SP,6 ;;AN006;; Throw away old pointer 1124 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 1125 <2> ; $ENDIF ;;AN006;; 1126 <2> $MEN60: 1127 <2> POP BP ;;AN006;; Restore other Regs 1128 <2> POP DX ;;AN006;; 1129 <2> ; $ENDIF ;;AN006;; 1130 <2> $MIF56: 1131 <2> $M_POPF ;;AN006;; Restore the flag state 1132 <2> 1133 <2> POP BX ;;AN000;; 1134 <2> POP SI ;;AN000;; 1135 <2> RET ;;AN000;; Return ES:DI pointing to the message 1136 <2> ;; 1137 <2> $M_GET_MSG_ADDRESS ENDP ;; 1138 <2> ;; 1139 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 1140 <2> ;; 1141 <2> PUSH DI ;;AN006;; Save position 1142 <2> PUSH AX ;;AN006;; 1143 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 1144 <2> XOR AL,AL ;;AN006;; Prepare compare register 1145 <2> REPNE SCASB ;;AN006;; Scan for zero 1146 <2> NOT CX ;;AN006;; Change decrement into number 1147 <2> DEC CX ;;AN006;; Don't include the zero 1148 <2> POP AX ;;AN006;; 1149 <2> POP DI ;;AN006;; Restore position 1150 <2> RET ;;AN006;; 1151 <2> ;; 1152 <2> $M_SET_LEN_IN_CX ENDP ;; 1153 <2> ;; 1154 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1155 <2> ;; 1156 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 1157 <2> ;; 1158 <2> ;; FUNCTION: To scan thru message headers until message is found 1159 <2> ;; INPUTS: ES:DI points to beginning of msg headers 1160 <2> ;; CX contains the number of messages in class 1161 <2> ;; DH contains the message class 1162 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 1163 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 1164 <2> ;; 1165 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1166 <2> ;; 1167 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 1168 <2> ;; 1169 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 1170 <2> ; $IF E,AND ;;AN004;; Yes, 1171 <2> JNE $MIF64 1172 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 1173 <2> ; $IF NE ;;AN004;; Yes, 1174 <2> JE $MIF64 1175 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 1176 <2> ; $IF E ;;AN004;; . . . and . . . 1177 <2> JNE $MIF65 1178 <2> PUSH AX ;;AN004;; Reset the special message number 1179 <2> MOV AX,[$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 1180 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1181 <2> POP AX ;;AN004;; Reset the special message number 1182 <2> ; $ELSE ;;AN004;; Get the old message number 1183 <2> JMP SHORT $MEN65 1184 <2> $MIF65: 1185 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1186 <2> ; $ENDIF ;;AN004;; Get the old message number 1187 <2> $MEN65: 1188 <2> ; $ELSE ;;AN004;; 1189 <2> JMP SHORT $MEN64 1190 <2> $MIF64: 1191 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 1192 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1193 <2> ; $IF NE ;;AN001;; 1194 <2> JE $MIF69 1195 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 1196 <2> ; $ELSE ;;AN001;; 1197 <2> JMP SHORT $MEN69 1198 <2> $MIF69: 1199 <2> %IF FARmsg ;;AN001;; 1200 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1201 <2> %ELSE 1202 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1203 <2> %ENDIF 1204 <2> ; $IF E ;;AN002;; pointer (hopefully) 1205 <2> JNE $MIF71 1206 <2> %IF FARmsg ;;AN001;; 1207 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1208 <2> %ELSE 1209 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1210 <2> %ENDIF 1211 <2> ; $ENDIF ;;AN002;; go on to the next class 1212 <2> $MIF71: 1213 <2> ; $ENDIF ;;AN001;; 1214 <2> $MEN69: 1215 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 1216 <2> STC ;;AN004;; Flag that we haven't found anything yet 1217 <2> ; $ENDIF ;;AN004;; 1218 <2> $MEN64: 1219 <2> 1220 <2> ; $IF C ;;AN004;; Have we found anything yet? 1221 <2> JNC $MIF75 1222 <2> CLC ;;AN004;; No, reset carry 1223 <2> ; $SEARCH ;;AN000;; 1224 <2> $MDO76: 1225 <2> OR CX,CX ;;AN000;; Do we have any to check? 1226 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1227 <2> JZ $MEN76 1228 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1229 <2> ; $IF NE ;;AN001;; 1230 <2> JE $MIF78 1231 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 1232 <2> ; $ELSE ;;AN001;; 1233 <2> JMP SHORT $MEN78 1234 <2> $MIF78: 1235 <2> %IF FARmsg ;;AN001;; 1236 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 1237 <2> %ELSE 1238 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 1239 <2> %ENDIF 1240 <2> ; $ENDIF 1241 <2> $MEN78: 1242 <2> ; $EXITIF E ;;AN000;; 1243 <2> JNE $MIF76 1244 <2> ; $ORELSE ;;AN000; 1245 <2> JMP SHORT $MSR76 1246 <2> $MIF76: 1247 <2> DEC CX ;;AN000;; No, well do we have more to check? 1248 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1249 <2> JZ $MEN76 1250 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 1251 <2> ; $ENDLOOP ;;AN000;; 1252 <2> JMP SHORT $MDO76 1253 <2> $MEN76: 1254 <2> STC ;;AN000;; 1255 <2> ; $ENDSRCH ;;AN000;; Check next message 1256 <2> $MSR76: 1257 <2> ; $IF NC ;;AN000;; Did we find the message? 1258 <2> JC $MIF86 1259 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 1260 <2> CLC ;;AN001;; 1261 <2> ; $IF E ;;AN001;; 1262 <2> JNE $MIF87 1263 <2> %IF FARmsg ;;AN001;; 1264 <2> %ELSE ;;AN000;; 1265 <2> PUSH CS ;;AN000;; 1266 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 1267 <2> %ENDIF 1268 <2> ; $ENDIF ;;AN001;; 1269 <2> $MIF87: 1270 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 1271 <2> ; $ENDIF ;;AN004;; 1272 <2> $MIF86: 1273 <2> ; $ENDIF ;;AN004;; 1274 <2> $MIF75: 1275 <2> ;; Yes, great we can return with CX > 0 1276 <2> 1277 <2> ; $IF NC ;;AN000;; Did we find the message? 1278 <2> JC $MIF91 1279 <2> XOR CH,CH ;;AN000;; 1280 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 1281 <2> INC DI ;;AN000;; Increment past length 1282 <2> ; $ENDIF ;;AN004;; 1283 <2> $MIF91: 1284 <2> 1285 <2> MOV byte [$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 1286 <2> RET ;;AN000;; Return 1287 <2> ;; 1288 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 1289 <2> ;; 1290 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1291 <2> %ENDIF ;;AN000;; END of include of common subroutines 1292 <2> %ENDIF ;;AN000;; END of include of SYSGETMSG 1293 <2> ; 1294 <2> %IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 1295 <2> %IF COMR ;;AN000;; 1296 <2> $M_RT EQU $M_RT2 ;;AN000;; 1297 <2> %ENDIF ;;AN000;; 1298 <2> %iassign DISPLAYmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 1299 <2> ; PAGE 1300 <2> ; SUBTTL DOS - Message Retriever - DISPMSG.ASM Module 1301 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1302 <2> ;; 1303 <2> ;; Proc Name: SYSDISPMSG 1304 <2> ;; 1305 <2> ;; Function: The DISPLAY service will output a defined message to a handle 1306 <2> ;; requested by the caller. It also provides function to display 1307 <2> ;; messages when handles are not applicable (ie. DOS function calls 1308 <2> ;; 00h to 0Ah) Replaceable parameters are allowed and are 1309 <2> ;; defined previous to entry. 1310 <2> ;; 1311 <2> ;; It is assumes that a PRELOAD function has already determined 1312 <2> ;; the addressibilty internally to the message retriever services. 1313 <2> ;; Inputs: 1314 <2> ;; 1315 <2> ;; Outputs: 1316 <2> ;; 1317 <2> ;; Psuedocode: 1318 <2> ;; Save registers needed later 1319 <2> ;; Get address of the message requested 1320 <2> ;; IF Message number exists THEN 1321 <2> ;; IF replacable parameters were specified THEN 1322 <2> ;; Display message with replacable parms 1323 <2> ;; ELSE 1324 <2> ;; Display string without replacable parms 1325 <2> ;; ENDIF 1326 <2> ;; IF character input was requested THEN 1327 <2> ;; Wait for character input 1328 <2> ;; ENDIF 1329 <2> ;; Clear CARRY FLAG 1330 <2> ;; ELSE 1331 <2> ;; Set CARRY FLAG 1332 <2> ;; ENDIF 1333 <2> ;; Return 1334 <2> ;; 1335 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1336 <2> ;; 1337 <2> %IF FARmsg ;;AN000;; 1338 <2> SYSDISPMSG PROC FAR ;;AN000;; 1339 <2> %ELSE ;;AN000;; 1340 <2> SYSDISPMSG PROC NEAR ;;AN000;; 1341 <2> %ENDIF ;;AN000;; 1342 <2> ;; 1343 <2> ;; Save registers and values needed later 1344 <2> 1345 <2> PUSH AX ;;AN000;; Save changed REGs 1346 <2> PUSH BX ;;AN000;; 1347 <2> PUSH CX ;;AN000;; 1348 <2> PUSH BP ;;AN000;; 1349 <2> PUSH DI ;;AN000;; Save pointer to input buffer (offset) 1350 <2> PUSH ES ;;AN000;; Save pointer to input buffer (segment) 1351 <2> PUSH DX ;;AN000;; Save Input/Class request 1352 <2> 1353 <2> MOV BP,CX ;;AN000;; Use BP to hold replace count 1354 <2> MOV WORD PTR [cs:$M_RT + $M_HANDLE],BX ;;AN000;; Save handle 1355 <2> MOV BYTE PTR [cs:$M_RT + $M_CLASS],DH ;;AN004;; Save class 1356 <2> 1357 <2> ;; Get address of the message requested 1358 <2> 1359 <2> %IF FARmsg ;;AN000;; 1360 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1361 <2> %ELSE ;;AN000;; 1362 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1363 <2> %ENDIF ;;AN000;; 1364 <2> OR CX,CX ;;AN000;; Was message found? 1365 <2> ; $IF NZ ;;AN000;; YES, Message address in ES:DI 1366 <2> JZ $MIF93 1367 <2> 1368 <2> ;; Test if replacable parameters were specified 1369 <2> 1370 <2> OR BP,BP ;;AN000;; Were replacable parameters requested 1371 <2> ; $IF Z ;;AN000;; 1372 <2> JNZ $MIF94 1373 <2> 1374 <2> ;; Display string without replacable parms 1375 <2> 1376 <2> CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message 1377 <2> ; $ELSE ;;AN000;; 1378 <2> JMP SHORT $MEN94 1379 <2> $MIF94: 1380 <2> %IF $M_REPLACE ;;AN000;; 1381 <2> 1382 <2> ;; Display message with replacable parms 1383 <2> 1384 <2> CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions 1385 <2> %ENDIF ;;AN000;; 1386 <2> ; $ENDIF ;;AN000;; 1387 <2> $MEN94: 1388 <2> ; $IF NC 1389 <2> JC $MIF97 1390 <2> 1391 <2> POP DX ;;AN000;; Get Input/Class request 1392 <2> 1393 <2> CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. 1394 <2> 1395 <2> POP ES ;;AN000;; Get location of input buffer (if specified) 1396 <2> POP DI ;;AN000;; 1397 <2> 1398 <2> ;; Test if character input was requested 1399 <2> 1400 <2> %IF INPUTmsg ;;AN000;; 1401 <2> OR DL,DL ;;AN000;; Was Wait-For-Input requested? 1402 <2> ; $IF NZ ;;AN000;; 1403 <2> JZ $MIF98 1404 <2> CALL $M_WAIT_FOR_INPUT ;;AN000;; 1405 <2> ; $ENDIF ;;AN000;; 1406 <2> $MIF98: 1407 <2> %ENDIF ;;AN000;; 1408 <2> ; $ELSE ;;AN000;; 1409 <2> JMP SHORT $MEN97 1410 <2> $MIF97: 1411 <2> ADD SP,6 ;;AN000;; 1412 <2> STC ;;AN000;; Reset carry flag 1413 <2> ; $ENDIF ;;AN000;; 1414 <2> $MEN97: 1415 <2> ; $ELSE ;;AN000;; No, 1416 <2> JMP SHORT $MEN93 1417 <2> $MIF93: 1418 <2> POP ES ;;AN000;; Get pointer to input buffer (segment) 1419 <2> POP DI ;;AN000;; Get base pointer to first sublist (offset) 1420 <2> POP DX ;;AN000;; Get base pointer to first sublist (segment) 1421 <2> STC ;;AN000;; Set carry flag 1422 <2> ; $ENDIF ;;AN000;; 1423 <2> $MEN93: 1424 <2> ;; 1425 <2> ; $IF NC ;;AN000;; Was there an error? 1426 <2> JC $MIF104 1427 <2> POP BP ;;AN000;; No, 1428 <2> POP CX ;;AN000;; 1429 <2> POP BX ;;AN000;; 1430 <2> %IF INPUTmsg ;;AN000;; 1431 <2> ADD SP,2 ;;AN000;; 1432 <2> %ELSE ;AN000; 1433 <2> POP AX ;;AN000;; 1434 <2> %ENDIF ;;AN000;; 1435 <2> ; $ELSE ;;AN000;; Yes, 1436 <2> JMP SHORT $MEN104 1437 <2> $MIF104: 1438 <2> ADD SP,8 ;;AN000;; Eliminate from stack 1439 <2> STC ;;AN000;; 1440 <2> ; $ENDIF ;;AN000;; 1441 <2> $MEN104: 1442 <2> ;; 1443 <2> RET ;;AN000;; Return 1444 <2> ;; 1445 <2> SYSDISPMSG ENDP ;;AN000;; 1446 <2> ;; 1447 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1448 <2> ; 1449 <2> ;; 1450 <2> ;; PROC NAME: $M_DISPLAY_STRING 1451 <2> ;; 1452 <2> ;; FUNCTION: Will display or write string 1453 <2> ;; INPUTS: ES:DI points to beginning of message 1454 <2> ;; CX contains the length of string to write (if applicable) 1455 <2> ;; OUTPUTS: None 1456 <2> ;; REGS Revised: None 1457 <2> ;; 1458 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1459 <2> ;; 1460 <2> $M_DISPLAY_STRING PROC NEAR ;;AN000;; 1461 <2> ;; 1462 <2> PUSH AX ;;AN000;; 1463 <2> PUSH BX ;;AN000;; 1464 <2> PUSH DX ;;AN000;; 1465 <2> ;; 1466 <2> MOV BX,[cs:$M_RT + $M_HANDLE] ;;AN000;; Retrieve handle 1467 <2> ;; 1468 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 1469 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1470 <2> %ELSE 1471 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1472 <2> ; $IF E ;;AN000;; 1473 <2> JNE $MIF107 1474 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1475 <2> ; $ELSE ;;AN000;; 1476 <2> JMP SHORT $MEN107 1477 <2> $MIF107: 1478 <2> CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle 1479 <2> ; $ENDIF ;;AN000;; 1480 <2> $MEN107: 1481 <2> ;AN001; 1482 <2> ; $IF C ;;AN000;; Was there an error? 1483 <2> JNC $MIF110 1484 <2> MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, 1485 <2> MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error 1486 <2> INT 21H ;;AN000;; 1487 <2> XOR AH,AH ;;AN000;; Clear AH 1488 <2> ADD SP,6 ;;AN000;; Clean up stack 1489 <2> STC ;;AN000;; Flag that there was an error 1490 <2> ; $ELSE ;;AN000;; No, 1491 <2> JMP SHORT $MEN110 1492 <2> $MIF110: 1493 <2> CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1494 <2> ; $IF NE ;;AN000;; 1495 <2> JE $MIF112 1496 <2> CMP AX,CX ;AN001; Was it ALL written? 1497 <2> ; $IF NE ;AN001; No, 1498 <2> JE $MIF113 1499 <2> CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error 1500 <2> ADD SP,6 ;AN001; Clean up stack 1501 <2> STC ;AN001; Flag that there was an error 1502 <2> ; $ENDIF ;AN001; 1503 <2> $MIF113: 1504 <2> ; $ENDIF ;AN001; 1505 <2> $MIF112: 1506 <2> ; $ENDIF ;;AN000;; 1507 <2> $MEN110: 1508 <2> %ENDIF 1509 <2> ; $IF NC ;;AN000;; Was there ANY error? 1510 <2> JC $MIF117 1511 <2> POP DX ;;AN000;; Restore regs 1512 <2> POP BX ;;AN000;; 1513 <2> POP AX ;;AN000;; 1514 <2> ; $ENDIF ;;AN000;; 1515 <2> $MIF117: 1516 <2> RET ;;AN000;; Return 1517 <2> ;; 1518 <2> $M_DISPLAY_STRING ENDP ;;AN000;; 1519 <2> ;; 1520 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1521 <2> ;; 1522 <2> ;; PROC NAME: $M_DISPLAY_$_STRING 1523 <2> ;; 1524 <2> ;; FUNCTION: Will display a $ terminated string 1525 <2> ;; INPUTS: ES:DI points to beginning of message text (not the length) 1526 <2> ;; OUPUTS: None 1527 <2> ;; REGS USED: AX,DX 1528 <2> ;; 1529 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1530 <2> ;; 1531 <2> $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; 1532 <2> ;; 1533 <2> PUSH DS ;;AN000;; 1534 <2> PUSH ES ;;AN000;; 1535 <2> POP DS ;;AN000;; Set DS to segment of message text 1536 <2> %IFN COMR 1537 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1538 <2> ; $IF E ;;AN000;; Yes, 1539 <2> JNE $MIF119 1540 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1541 <2> MOV DL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1542 <2> INT 21H ;;AN000;; Write character 1543 <2> POP DS ;;AN000;; Set DS to segment of message text 1544 <2> MOV AL,DL ;;AN000;; Get the character in AL 1545 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1546 <2> PUSH DS ;;AN000;; 1547 <2> PUSH ES ;;AN000;; 1548 <2> POP DS ;;AN000;; Set DS to segment of message text 1549 <2> ; $IF C ;;AN000;; Yes, 1550 <2> JNC $MIF120 1551 <2> MOV DL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 1552 <2> INT 21H ;;AN000;; Write character 1553 <2> CLC ;;AN000;; Clear the DBCS indicator 1554 <2> ; $ENDIF ;;AN000;; 1555 <2> $MIF120: 1556 <2> ; $ELSE ;;AN000;; No, 1557 <2> JMP SHORT $MEN119 1558 <2> $MIF119: 1559 <2> %ENDIF 1560 <2> MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1561 <2> ; $DO ;;AN002;; No, 1562 <2> $MDO123: 1563 <2> OR CX,CX ;;AN002;; Are there any left to display? 1564 <2> ; $LEAVE Z ;;AN002;; Yes, 1565 <2> JZ $MEN123 1566 <2> MOV DL,BYTE PTR [ES:DI] ;;AN002;; Get the character 1567 <2> INT 21H ;;AN002;; Display the character 1568 <2> INC DI ;;AN002;; Set pointer to next character 1569 <2> DEC CX ;;AN002;; Count this character 1570 <2> ; $ENDDO Z ;;AN002;; No, 1571 <2> JNZ $MDO123 1572 <2> $MEN123: 1573 <2> %IFN COMR 1574 <2> ; $ENDIF ;;AN000;; 1575 <2> $MEN119: 1576 <2> %ENDIF 1577 <2> CLC ;;AN000;; Char functions used don't return carry as error 1578 <2> POP DS ;;AN000;; 1579 <2> RET ;;AN000;; 1580 <2> ;; 1581 <2> $M_DISPLAY_$_STRING ENDP ;;AN000;; 1582 <2> ;; 1583 <2> %IFN COMR 1584 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1585 <2> ;; 1586 <2> ;; PROC NAME: $M_DISPLAY_H_STRING 1587 <2> ;; 1588 <2> ;; FUNCTION: Will display a string to a specified handle 1589 <2> ;; INPUTS: ES:DI points to beginning of message 1590 <2> ;; CX contains the number of bytes to write 1591 <2> ;; BX contains the handle to write to 1592 <2> ;; OUPUTS: None 1593 <2> ;; REGS USED: AX,DX 1594 <2> ;; 1595 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1596 <2> ;; 1597 <2> $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; 1598 <2> ;; 1599 <2> XOR AX,AX ;;AN002;; Set number of bytes written to 0 1600 <2> OR CX,CX ;;AN002;; For performance, don't write if not necessary 1601 <2> ; $IF NZ ;;AN002;; Any chars to write? 1602 <2> JZ $MIF127 1603 <2> PUSH DS ;;AN000;; Yes, 1604 <2> PUSH ES ;;AN000;; 1605 <2> POP DS ;;AN000;; Set DS to segment of message text 1606 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1607 <2> MOV DX,DI ;;AN000;; Pointer to data to write 1608 <2> CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1609 <2> ; $IF E ;;AN000;; Yes, 1610 <2> JNE $MIF128 1611 <2> INT 21H ;;AN000;; Write character 1612 <2> POP DS ;;AN000;; Set DS to segment of message text 1613 <2> PUSH AX ;;AN000;; 1614 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 1615 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 1616 <2> POP AX ;;AN000;; Set DS to segment of message text 1617 <2> PUSH DS ;;AN000;; 1618 <2> PUSH ES ;;AN000;; 1619 <2> POP DS ;;AN000;; Set DS to segment of message text 1620 <2> ; $IF C ;;AN000;; Yes, 1621 <2> JNC $MIF129 1622 <2> CLC ;;AN000;; Clear the DBCS indicator 1623 <2> MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 1624 <2> INC DX ;;AN000;; Point to next character 1625 <2> INT 21H ;;AN000;; Write character 1626 <2> ; $ENDIF ;;AN000;; 1627 <2> $MIF129: 1628 <2> ; $ELSE ;;AN000;; No, 1629 <2> JMP SHORT $MEN128 1630 <2> $MIF128: 1631 <2> INT 21H ;;AN000;; Write String at DS:SI to handle 1632 <2> ; $ENDIF ;;AN000;; 1633 <2> $MEN128: 1634 <2> POP DS ;;AN000;; 1635 <2> ; $ENDIF ;;AN002;; 1636 <2> $MIF127: 1637 <2> ;; 1638 <2> RET ;;AN000;; 1639 <2> ;; 1640 <2> $M_DISPLAY_H_STRING ENDP ;;AN000;; 1641 <2> ;; 1642 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1643 <2> ;; 1644 <2> ;; PROC NAME: $M_GET_EXT_ERR_39 1645 <2> ;; 1646 <2> ;; FUNCTION: Will set registers for extended error #39 1647 <2> ;; INPUTS: None 1648 <2> ;; OUPUTS: AX,BX,CX set 1649 <2> ;; REGS USED: 1650 <2> ;; 1651 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1652 <2> ;; 1653 <2> $M_GET_EXT_ERR_39 PROC NEAR ;AN001; 1654 <2> ;; 1655 <2> MOV AX,EXT_ERR_39 ;AN001; Set AX=39 1656 <2> MOV BX,(ERROR_CLASS_39 >> 8) + ACTION_39 ;AN001; Set BH=1 BL=4 1657 <2> MOV CH,LOCUS_39 ;AN001; Set CH=1 1658 <2> ;AN001; 1659 <2> RET ;AN001; 1660 <2> ;; 1661 <2> $M_GET_EXT_ERR_39 ENDP ;AN001; 1662 <2> ;; 1663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1664 <2> %ENDIF 1665 <2> ;; 1666 <2> ;; PROC NAME: $M_ADD_CRLF 1667 <2> ;; 1668 <2> ;; FUNCTION: Will decide whether to display a CRLF 1669 <2> ;; INPUTS: DX contains the Input/Class requested 1670 <2> ;; OUTPUTS: None 1671 <2> ;; REGS Revised: CX,ES,DI 1672 <2> ;; 1673 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1674 <2> ;; 1675 <2> $M_ADD_CRLF PROC NEAR ;;AN004;; 1676 <2> ;; 1677 <2> CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1678 <2> ; $IF NE ;;AN004;; No, 1679 <2> JE $MIF134 1680 <2> TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? 1681 <2> ; $IF Z ;;AN004;; No, 1682 <2> JNZ $MIF135 1683 <2> PUSH DS ;;AN004;; 1684 <2> POP ES ;;AN004;; Set ES to data segment 1685 <2> LEA DI,[$M_RT + $M_CRLF] ;;AN004;; Point at CRLF message 1686 <2> MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size 1687 <2> CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF 1688 <2> ; $ENDIF ;;AN004;; 1689 <2> $MIF135: 1690 <2> ; $ENDIF ;;AN004;; 1691 <2> $MIF134: 1692 <2> RET ;;AN004;; Return 1693 <2> ;; 1694 <2> $M_ADD_CRLF ENDP ;;AN004;; 1695 <2> ;; 1696 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1697 <2> ;; 1698 <2> ;; PROC NAME: $M_IS_IT_DBCS 1699 <2> ;; 1700 <2> ;; FUNCTION: Will decide whether character is Single or Double Byte 1701 <2> ;; INPUTS: AL contains the byte to be checked 1702 <2> ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range 1703 <2> ;; Carry flag = 1 if byte IS in DBCS range 1704 <2> ;; REGS USED: All restored 1705 <2> ;; 1706 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1707 <2> ;; 1708 <2> $M_IS_IT_DBCS PROC NEAR ;;AN000;; 1709 <2> ;; 1710 <2> PUSH ES ;;AN000;; Save Extra segment register 1711 <2> PUSH DI ;;AN000;; Save SI register 1712 <2> ;; 1713 <2> LES DI,[cs:$M_RT + $M_DBCS_VEC] ;;AN000;; 1714 <2> OR DI,DI ;;AN000;; Was the DBCS vector set? 1715 <2> ; $IF NZ ;;AN000;; 1716 <2> JZ $MIF138 1717 <2> ; $DO ;;AN000;; 1718 <2> $MDO139: 1719 <2> CMP WORD PTR [ES:DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? 1720 <2> CLC ;;AN000;; 1721 <2> ; $LEAVE E ;;AN000;; 1722 <2> JE $MEN139 1723 <2> ;; No, 1724 <2> CMP AL,BYTE PTR [ES:DI] ;;AN000;; Does the character fall in the DBCS range? 1725 <2> ; $IF AE,AND ;;AN000;; 1726 <2> JNAE $MIF141 1727 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Does the character fall in the DBCS range? 1728 <2> ; $IF BE ;;AN000;; 1729 <2> JNBE $MIF141 1730 <2> STC ;;AN000;; Yes, 1731 <2> ; $ENDIF ;;AN000;; Set carry flag 1732 <2> $MIF141: 1733 <2> INC DI ;;AN000;; No, 1734 <2> INC DI ;;AN000;; Go to next vector 1735 <2> ; $ENDDO ;;AN000;; 1736 <2> JMP SHORT $MDO139 1737 <2> $MEN139: 1738 <2> ; $ENDIF ;;AN000;; 1739 <2> $MIF138: 1740 <2> 1741 <2> POP DI ;;AN000;; 1742 <2> POP ES ;;AN000;; Restore SI register 1743 <2> RET ;;AN000;; Return 1744 <2> ;; 1745 <2> $M_IS_IT_DBCS ENDP ;;AN000;; 1746 <2> ;; 1747 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1748 <2> ;; 1749 <2> ;; PROC NAME: $M_CONVERT2ASC 1750 <2> ;; 1751 <2> ;; FUNCTION: Convert a binary number to a ASCII string 1752 <2> ;; INPUTS: DX:AX contains the number to be converted 1753 <2> ;; $M_RT_DIVISOR contains the divisor 1754 <2> ;; OUPUTS: CX contains the number of characters 1755 <2> ;; Top of stack --> Last character 1756 <2> ;; . . . 1757 <2> ;; Bot of stack --> First character 1758 <2> ;; REGS USED: 1759 <2> ;; 1760 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1761 <2> ;; 1762 <2> $M_CONVERT2ASC PROC NEAR ;;AN000;; 1763 <2> ;; 1764 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Save Return Address 1765 <2> XOR BX,BX ;;AN000;; Use BP as a swapping register 1766 <2> ;; 1767 <2> XCHG BX,AX ;;AN000;; Initialize - Low Word in BP 1768 <2> XCHG AX,DX ;;AN000;; - High Word in AX 1769 <2> ; $DO ;;AN000;; DO UNTIL Low Word becomes zero 1770 <2> $MDO145: 1771 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide High Word by divisor 1772 <2> XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder 1773 <2> ;; and save reduced High Word in BP 1774 <2> DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide Low Word by divisor 1775 <2> CMP DX,9 ;;AN000;; Make a digit of the remainder 1776 <2> ; $IF A ;;AN000;; IF 10 to 15, 1777 <2> JNA $MIF146 1778 <2> ADD DL,55 ;;AN000;; Make A to F ASCII 1779 <2> ; $ELSE ;;AN000;; IF 0 to 9, 1780 <2> JMP SHORT $MEN146 1781 <2> $MIF146: 1782 <2> ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII 1783 <2> ; $ENDIF ;;AN000;; 1784 <2> $MEN146: 1785 <2> PUSH DX ;;AN000;; Save the digit on the stack 1786 <2> INC CX ;;AN000;; Count that digit 1787 <2> OR AX,AX ;;AN000;; Are we done? 1788 <2> ; $LEAVE Z,AND ;;AN000;; 1789 <2> JNZ $MLL149 1790 <2> OR BX,BX ;;AN000;; AX and BX must be ZERO!! 1791 <2> ; $LEAVE Z ;;AN000;; No, 1792 <2> JZ $MEN145 1793 <2> $MLL149: 1794 <2> %IFN COMR 1795 <2> CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark 1796 <2> ; $IF E ;;AN000;; Yes, 1797 <2> JNE $MIF150 1798 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1799 <2> ; $IF E ;;AN000;; Yes, 1800 <2> JNE $MIF151 1801 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1802 <2> INC CX ;;AN000;; 1803 <2> ; $ENDIF ;;AN000;; 1804 <2> $MIF151: 1805 <2> ; $ELSE ;;AN000;; No, 1806 <2> JMP SHORT $MEN150 1807 <2> $MIF150: 1808 <2> CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark 1809 <2> ; $IF E ;;AN000;; Yes, 1810 <2> JNE $MIF154 1811 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1812 <2> ; $IF E ;;AN000;; Yes, 1813 <2> JNE $MIF155 1814 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1815 <2> INC CX ;;AN000;; 1816 <2> ; $ENDIF ;;AN000;; 1817 <2> $MIF155: 1818 <2> ; $ELSE ;;AN000;; No, 1819 <2> JMP SHORT $MEN154 1820 <2> $MIF154: 1821 <2> CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark 1822 <2> ; $IF E ;;AN000;; Yes, 1823 <2> JNE $MIF158 1824 <2> CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1825 <2> ; $IF E ;;AN000;; Yes, 1826 <2> JNE $MIF159 1827 <2> PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 1828 <2> INC CX ;;AN000;; 1829 <2> ; $ENDIF ;;AN000;; 1830 <2> $MIF159: 1831 <2> ; $ENDIF ;;AN000;; 1832 <2> $MIF158: 1833 <2> ; $ENDIF ;;AN000;; 1834 <2> $MEN154: 1835 <2> ; $ENDIF ;;AN000;; 1836 <2> $MEN150: 1837 <2> %ENDIF 1838 <2> XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word 1839 <2> ;;AN000;; and Revised Low Word 1840 <2> XOR DX,DX ;;AN000;; Reset remainder 1841 <2> ; $ENDDO ;;AN000;; NEXT 1842 <2> JMP SHORT $MDO145 1843 <2> $MEN145: 1844 <2> ;;AN000;; Yes, 1845 <2> XOR DX,DX ;;AN000;; Reset remainder 1846 <2> XOR AX,AX ;;AN000;; Reset remainder 1847 <2> PUSH word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Restore Return Address 1848 <2> RET ;;AN000;; Return 1849 <2> ;; 1850 <2> $M_CONVERT2ASC ENDP ;;AN000;; 1851 <2> ;; 1852 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1853 <2> ;; 1854 <2> ;; PROC NAME: $M_DISPLAY_MESSAGE 1855 <2> ;; 1856 <2> ;; FUNCTION: Will display or write entire message (with replacable parameters) 1857 <2> ;; INPUTS: ES:DI points to beginning of message 1858 <2> ;; DS:SI points to first sublist structure in chain 1859 <2> ;; BX contains the handle to write to (if applicable) 1860 <2> ;; CX contains the length of string to write (before substitutions) 1861 <2> ;; BP contains the count of replacables 1862 <2> ;; 1863 <2> ;; OUTPUTS: 1864 <2> ;; REGS USED: All 1865 <2> ;; 1866 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1867 <2> ;; 1868 <2> $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; 1869 <2> ;; 1870 <2> ; $DO ;;AN000;; Note: DS:SI -> message 1871 <2> $MDO165: 1872 <2> XOR DX,DX ;;AN000;; Set size = 0 1873 <2> OR CX,CX ;;AN000;; Are we finished the message yet? 1874 <2> ; $IF NZ ;;AN000;; No, 1875 <2> JZ $MIF166 1876 <2> MOV AH,"%" ;;AN000;; Prepare to scan for % 1877 <2> MOV AL,0 ;;AN004;; 1878 <2> ;; 1879 <2> ; $DO ;;AN000;; Scan through string until % 1880 <2> $MDO167: 1881 <2> CMP BYTE PTR [ES:DI],AH ;;AN000;; Is this character NOT a % 1882 <2> ; $LEAVE E,AND ;;AN000;; No, 1883 <2> JNE $MLL168 1884 <2> CMP BYTE PTR [ES:DI+1],AH ;;AN000;; Is the next character also a % 1885 <2> ; $LEAVE NE,AND ;;AN000;; No, 1886 <2> JE $MLL168 1887 <2> CMP AL,AH ;;AN000;; Was the character before a % 1888 <2> ; $LEAVE NE ;;AN000;; No, GREAT found it 1889 <2> JNE $MEN167 1890 <2> $MLL168: 1891 <2> MOV AL,BYTE PTR [ES:DI] ;;AN004;; Yes, (to any of the above) 1892 <2> CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? 1893 <2> ; $IF C ;;AN004;; Yes, 1894 <2> JNC $MIF169 1895 <2> INC DI ;;AN004;; Increment past second part 1896 <2> ; $ENDIF ;;AN004;; 1897 <2> $MIF169: 1898 <2> INC DI ;;AN000;; Next character in string 1899 <2> INC DX ;;AN000;; Size = Size + 1 1900 <2> DEC CX ;;AN000;; Decrement total size 1901 <2> ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line 1902 <2> JNZ $MDO167 1903 <2> $MEN167: 1904 <2> ; $ENDIF ;;AN000;; 1905 <2> $MIF166: 1906 <2> ;; 1907 <2> PUSH SI ;;AN000;; Save beginning of sublists 1908 <2> XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) 1909 <2> OR BP,BP ;;AN000;; Do we have any replacables to do? 1910 <2> ; $IF NZ ;;AN000;; Yes, 1911 <2> JZ $MIF173 1912 <2> DEC BP ;;AN000;; Decrement number of replacables 1913 <2> 1914 <2> ;; Search through sublists to find applicable one 1915 <2> 1916 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 1917 <2> ; $IF E ;;AN000;; No, 1918 <2> JNE $MIF174 1919 <2> ; $SEARCH ;;AN000;; 1920 <2> $MDO175: 1921 <2> MOV AL,[$M_SL + $M_S_ID] ;;AN000;; Get ID byte 1922 <2> ADD AL,30H ;;AN000;; Convert to ASCII 1923 <2> CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Is this the right sublist? 1924 <2> ; $EXITIF E ;;AN000;; 1925 <2> JNE $MIF175 1926 <2> ; $ORELSE ;;AN000;; No, 1927 <2> JMP SHORT $MSR175 1928 <2> $MIF175: 1929 <2> CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 1930 <2> ; $LEAVE E,AND ;;AN000;; Yes, 1931 <2> JNE $MLL178 1932 <2> OR DX,DX ;;AN000;; Are we at the end of the message? 1933 <2> ; $LEAVE Z ;;AN000;; No, 1934 <2> JZ $MEN175 1935 <2> $MLL178: 1936 <2> ADD SI,WORD PTR [$M_SL + $M_S_SIZE] ;;AN000;; Next SUBLIST 1937 <2> ; $ENDLOOP ;;AN000;; Yes, 1938 <2> JMP SHORT $MDO175 1939 <2> $MEN175: 1940 <2> CMP byte [cs:$M_RT + $M_CLASS],UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1941 <2> ; $IF E ;;AN004;; Yes, 1942 <2> JNE $MIF180 1943 <2> INC DX ;;AN000;; Remember to display CR,LF 1944 <2> INC DX ;;AN000;; at the end of the message 1945 <2> DEC CX ;;AN000;; Adjust message length 1946 <2> DEC CX ;;AN000;; 1947 <2> DEC DI ;;AN000;; Adjust ending address of message 1948 <2> DEC DI ;;AN000;; 1949 <2> ; $ELSE ;;AN004;; No, 1950 <2> JMP SHORT $MEN180 1951 <2> $MIF180: 1952 <2> MOV DX,-1 ;;AN004;; Set special case 1953 <2> ; $ENDIF ;;AN004;; 1954 <2> $MEN180: 1955 <2> ; $ENDSRCH ;;AN000;; 1956 <2> $MSR175: 1957 <2> ; $ENDIF ;;AN000;; 1958 <2> $MIF174: 1959 <2> ; $ENDIF ;;AN000;; 1960 <2> $MIF173: 1961 <2> 1962 <2> ;; Prepare and display this part of message 1963 <2> 1964 <2> PUSH DI ;;AN000;; Save pointer to replace number 1965 <2> SUB DI,CX ;;AN000;; Determine beginning of string 1966 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) 1967 <2> POP DI ;;AN000;; Get back pointer to replace number 1968 <2> POP CX ;;AN000;; Clean up stack in case error 1969 <2> ; $LEAVE C,LONG ;;AN000;; Fail if carry was set 1970 <2> JNC $MXL3 1971 <2> JMP $MEN165 1972 <2> nop ; identicalise 1973 <2> $MXL3: 1974 <2> PUSH CX ;;AN000;; 1975 <2> 1976 <2> ;; Save and reset pointer registers 1977 <2> 1978 <2> MOV CX,DX ;;AN000;; Get the size of the rest of the message 1979 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? 1980 <2> ; $IF NE ;;AN000;; No, 1981 <2> JE $MIF187 1982 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1983 <2> ; $IF NZ ;;AN000;; No, 1984 <2> JZ $MIF188 1985 <2> DEC CX ;;AN000;; Decrement total size (%) 1986 <2> DEC CX ;;AN000;; Decrement total size (#) 1987 <2> INC DI ;;AN000;; Go past % 1988 <2> INC DI ;;AN000;; Go past replace number 1989 <2> ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) 1990 <2> JMP SHORT $MEN188 1991 <2> $MIF188: 1992 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 1993 <2> ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC 1994 <2> $MEN188: 1995 <2> ; $ELSE ;;AN000;; 1996 <2> JMP SHORT $MEN187 1997 <2> $MIF187: 1998 <2> OR CX,CX ;;AN000;; Are we finished the whole message? 1999 <2> ; $IF Z ;;AN004;; No, 2000 <2> JNZ $MIF192 2001 <2> POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 2002 <2> ; $ELSE ;;AN000;; No, 2003 <2> JMP SHORT $MEN192 2004 <2> $MIF192: 2005 <2> CMP CX,-1 ;;AN004;; Are we at the end of the message? 2006 <2> ; $IF Z ;;AN004;; No, 2007 <2> JNZ $MIF194 2008 <2> XOR CX,CX ;;AN004;; 2009 <2> ; $ENDIF ;;AN000;; 2010 <2> $MIF194: 2011 <2> OR DI,DI ;;AN004;; Turn ZF off 2012 <2> ; $ENDIF ;;AN000;; 2013 <2> $MEN192: 2014 <2> ; $ENDIF ;;AN000;; Note this will not leave because INC 2015 <2> $MEN187: 2016 <2> ; $LEAVE Z ;;AN000;; 2017 <2> JZ $MEN165 2018 <2> PUSH BP ;;AN000;; Save the replace count 2019 <2> PUSH DI ;;AN000;; Save location to complete message 2020 <2> PUSH ES ;;AN000;; 2021 <2> PUSH CX ;;AN000;; Save size of the rest of the message 2022 <2> XOR CX,CX ;;AN000;; Reset CX used for character count 2023 <2> 2024 <2> ;; Determine what action is required on parameter 2025 <2> 2026 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2027 <2> ; $IF E ;;AN000;; 2028 <2> JNE $MIF199 2029 <2> 2030 <2> %IF CHARmsg ;;AN000;; Was Char specified? 2031 <2> Char_Type equ Char_type ; NASM port equate 2032 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2033 <2> ; $IF Z ;;AN000;; 2034 <2> JNZ $MIF200 2035 <2> 2036 <2> ;; Character type requested 2037 <2> ;;AN000;; 2038 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2039 <2> CALL $M_CHAR_REPLACE ;;AN000;; 2040 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2041 <2> JMP SHORT $MEN200 2042 <2> $MIF200: 2043 <2> %ENDIF ;;AN000;; 2044 <2> %IF NUMmsg ;;AN000;; Was Nnmeric type specified? 2045 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2046 <2> ; $IF Z,OR ;;AN000;; 2047 <2> JZ $MLL202 2048 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2049 <2> ; $IF Z,OR ;;AN000;; 2050 <2> JZ $MLL202 2051 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Bin_Hex_Type & $M_TYPE_MASK ;;AN000;; 2052 <2> ; $IF Z ;;AN000;; 2053 <2> JNZ $MIF202 2054 <2> $MLL202: 2055 <2> 2056 <2> ;; Numeric type requested 2057 <2> 2058 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2059 <2> CALL $M_BIN2ASC_REPLACE ;;AN000;; 2060 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2061 <2> JMP SHORT $MEN202 2062 <2> $MIF202: 2063 <2> %ENDIF ;;AN000;; 2064 <2> %IF DATEmsg ;;AN000;; Was date specified? 2065 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Date_Type & $M_TYPE_MASK ;;AN000;; 2066 <2> ; $IF E ;;AN000;; 2067 <2> JNE $MIF204 2068 <2> 2069 <2> ;; Date type requested 2070 <2> 2071 <2> CALL $M_DATE_REPLACE ;;AN000;; 2072 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2073 <2> JMP SHORT $MEN204 2074 <2> $MIF204: 2075 <2> %ENDIF ;;AN000;; 2076 <2> %IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? 2077 <2> 2078 <2> ;; Time type requested (Default if we have not matched until here) 2079 <2> 2080 <2> CALL $M_TIME_REPLACE ;;AN000;; 2081 <2> %ENDIF ;;AN000;; 2082 <2> 2083 <2> %IF DATEmsg ;;AN000;; 2084 <2> ; $ENDIF ;;AN000;; 2085 <2> $MEN204: 2086 <2> %ENDIF ;;AN000;; 2087 <2> %IF NUMmsg ;;AN000;; 2088 <2> ; $ENDIF ;;AN000;; 2089 <2> $MEN202: 2090 <2> %ENDIF ;;AN000;; 2091 <2> %IF CHARmsg ;;AN000;; 2092 <2> ; $ENDIF ;;AN000;; 2093 <2> $MEN200: 2094 <2> %ENDIF ;;AN000;; 2095 <2> 2096 <2> %IF $M_REPLACE ;;AN000;; 2097 <2> ;; With the replace information of the Stack, display the replaceable field 2098 <2> 2099 <2> CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace 2100 <2> %ENDIF ;;AN000;; 2101 <2> ;; None of the above - Extended/Parse replace 2102 <2> ; $ELSE ;;AN000;; 2103 <2> JMP SHORT $MEN199 2104 <2> $MIF199: 2105 <2> %IFN COMR 2106 <2> CALL $M_EXT_PAR_REPLACE ;;AN000;; 2107 <2> %ENDIF 2108 <2> ; $ENDIF ;;AN000;; 2109 <2> $MEN199: 2110 <2> 2111 <2> ;; We must go back and complete the message after the replacable parameter if there is any left 2112 <2> 2113 <2> ; $IF NC ;;AN000;; IF there was an error displaying then EXIT 2114 <2> JC $MIF211 2115 <2> POP CX ;;AN000;; Get size of the rest of the message 2116 <2> POP ES ;;AN000;; Get address of the rest of the message 2117 <2> POP DI ;;AN000;; 2118 <2> POP BP ;;AN000;; Get replacment count 2119 <2> POP SI ;;AN000;; ELSE get address of first sublist structure 2120 <2> ; $ELSE ;;AN000;; 2121 <2> JMP SHORT $MEN211 2122 <2> $MIF211: 2123 <2> ADD SP,10 ;;AN000;; Clean up stack if error 2124 <2> STC ;;AN000;; 2125 <2> ; $ENDIF ;;AN000;; 2126 <2> $MEN211: 2127 <2> CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2128 <2> ; $ENDDO NE,OR ;;AN000;; 2129 <2> JNE $MLL214 2130 <2> ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message 2131 <2> JC $MXL4 2132 <2> JMP $MDO165 2133 <2> $MXL4: 2134 <2> $MLL214: 2135 <2> $MEN165: 2136 <2> ;; IF there was an error displaying then EXIT 2137 <2> MOV word [cs:$M_RT + $M_MSG_NUM],0 ;;AN000;; Reset message number to null 2138 <2> RET ;;AN000;; Return 2139 <2> ;; 2140 <2> $M_DISPLAY_MESSAGE ENDP ;;AN000;; 2141 <2> %IFN COMR 2142 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2143 <2> ;; 2144 <2> ;; PROC NAME: $M_EXT_PAR_REPLACE 2145 <2> ;; 2146 <2> ;; FUNCTION: 2147 <2> ;; INPUTS: 2148 <2> ;; OUPUTS: 2149 <2> ;; 2150 <2> ;; REGS USED: 2151 <2> ;; 2152 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2153 <2> ;; 2154 <2> $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; 2155 <2> ;; 2156 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2157 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN000;; Prepare for get binary value (LOW) 2158 <2> MOV word [cs:$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2159 <2> ;; 2160 <2> CALL $M_CONVERT2ASC ;;AN000;; 2161 <2> ;; 2162 <2> ; $DO ;;AN000;; 2163 <2> $MDO215: 2164 <2> POP AX ;;AN000;; Get character in register 2165 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2166 <2> INC BX ;;AN000;; Increase buffer count 2167 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2168 <2> ; $IF E ;;AN000;; Yes, 2169 <2> JNE $MIF216 2170 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2171 <2> ; $ENDIF ;;AN000;; 2172 <2> $MIF216: 2173 <2> DEC CL ;;AN000;; Have we completed replace? 2174 <2> ; $ENDDO Z ;;AN000;; 2175 <2> JNZ $MDO215 2176 <2> ;; 2177 <2> MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer 2178 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],AX ;;AN000;; Move char into the buffer 2179 <2> INC BX ;;AN000;; Increase buffer count 2180 <2> INC BX ;;AN000;; Increase buffer count 2181 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2182 <2> RET ;;AN000:: 2183 <2> ;; 2184 <2> $M_EXT_PAR_REPLACE ENDP ;;AN000;; 2185 <2> ;; 2186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2187 <2> %ENDIF 2188 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 2189 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 2190 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2191 <2> ;; 2192 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 2193 <2> ;; 2194 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 2195 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 2196 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2197 <2> ;; IF CX > 1 THEN DS:SI points to the specified message 2198 <2> ;; REGS CHANGED: ES,DI,CX,DS,SI 2199 <2> ;; 2200 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2201 <2> ;; 2202 <2> %IF FARmsg ;;AN000;; 2203 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 2204 <2> %ELSE ;;AN000;; 2205 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 2206 <2> %ENDIF ;;AN000;; 2207 <2> ;; 2208 <2> PUSH SI ;;AN000;; 2209 <2> PUSH BX ;;AN000;; 2210 <2> XOR SI,SI ;;AN000;; Use SI as an index 2211 <2> XOR CX,CX ;;AN000;; Use CX as an size 2212 <2> ; $DO ;;AN000;; 2213 <2> $MDO219: 2214 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 2215 <2> ; $IF E ;;AN000;; Yes, 2216 <2> JNE $MIF220 2217 <2> %IF FARmsg ;;AN000;; 2218 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2219 <2> MOV BX,ES ;;AN000; 2220 <2> %ELSE ;;AN000;; 2221 <2> MOV DI,WORD PTR [cs:$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2222 <2> MOV BX,DI ;;AN000; 2223 <2> %ENDIF ;;AN000;; 2224 <2> ; $ELSE ;;AN000;; No, 2225 <2> JMP SHORT $MEN220 2226 <2> $MIF220: 2227 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 2228 <2> ; $IF NE ;;AN000;; Yes, 2229 <2> JE $MIF222 2230 <2> LES DI,[cs:$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 2231 <2> MOV BX,ES ;;AN000; 2232 <2> ; $ELSE ;;AN000;; No, extended errors were specified 2233 <2> JMP SHORT $MEN222 2234 <2> $MIF222: 2235 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 2236 <2> ; $IF AE,AND ;;AN000;; 2237 <2> JNAE $MIF224 2238 <2> CMP AX,$M_CRIT_HI ;;AN000;; 2239 <2> ; $IF BE ;;AN000;; Yes, 2240 <2> JNBE $MIF224 2241 <2> LES DI,[cs:$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 2242 <2> MOV BX,ES ;;AN000; 2243 <2> ; $ELSE ;;AN000;; 2244 <2> JMP SHORT $MEN224 2245 <2> $MIF224: 2246 <2> LES DI,[cs:$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 2247 <2> MOV BX,ES ;;AN000; 2248 <2> ; $ENDIF ;;AN000;; 2249 <2> $MEN224: 2250 <2> ; $ENDIF ;;AN000;; 2251 <2> $MEN222: 2252 <2> ; $ENDIF ;;AN000;; 2253 <2> $MEN220: 2254 <2> ;; 2255 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 2256 <2> ; $IF E ;;AN000;; Yes, 2257 <2> JNE $MIF229 2258 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 2259 <2> ; $IF E ;;AN000;; Yes, 2260 <2> JNE $MIF230 2261 <2> STC ;;AN000;; Set the carry flag 2262 <2> ; $ELSE ;;AN000;; No, 2263 <2> JMP SHORT $MEN230 2264 <2> $MIF230: 2265 <2> MOV [cs:$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 2266 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 2267 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 2268 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 2269 <2> CLC ;;AN000;; 2270 <2> ; $ENDIF ;;AN000;; No, 2271 <2> $MEN230: 2272 <2> ; $ELSE ;;AN000;; 2273 <2> JMP SHORT $MEN229 2274 <2> $MIF229: 2275 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 2276 <2> ; $IF NE ;;AN001;; Yes, 2277 <2> JE $MIF234 2278 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 2279 <2> ; $ENDIF ;;AN000;; 2280 <2> $MIF234: 2281 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 2282 <2> CLC ;;AN000;; 2283 <2> ; $ENDIF ;;AN000;; 2284 <2> $MEN229: 2285 <2> ; $LEAVE C ;;AN000;; 2286 <2> JC $MEN219 2287 <2> OR CX,CX ;;AN000;; Was the message found? 2288 <2> ; $ENDDO NZ,LONG ;;AN000;; 2289 <2> JNZ $MXL5 2290 <2> JMP $MDO219 2291 <2> $MXL5: 2292 <2> $MEN219: 2293 <2> 2294 <2> PUSHF ;;AN006;; Save the flag state 2295 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 2296 <2> ; $IF E ;;AN006;; Yes, 2297 <2> JNE $MIF239 2298 <2> PUSH DX ;;AN006;; Save all needed registers 2299 <2> PUSH BP ;;AN006;; 2300 <2> PUSH CX ;;AN006;; 2301 <2> PUSH ES ;;AN006;; 2302 <2> PUSH DI ;;AN006;; 2303 <2> PUSH AX ;;AN006;; 2304 <2> 2305 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 2306 <2> INT 2FH ;;AN006;; 2307 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 2308 <2> POP AX ;;AN006;; Restore msg number 2309 <2> ; $IF E ;;AN006;; Yes, 2310 <2> JNE $MIF240 2311 <2> MOV BX,AX ;;AN006;; BX is the extended error number 2312 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 2313 <2> INT 2FH ;;AN006;; Call IFSFUNC 2314 <2> ; $ELSE ;;AN006;; No, 2315 <2> JMP SHORT $MEN240 2316 <2> $MIF240: 2317 <2> STC ;;AN006;; Carry conditon 2318 <2> ; $ENDIF ;;AN006;; 2319 <2> $MEN240: 2320 <2> 2321 <2> ; $IF C ;;AN006;; Was there an update? 2322 <2> JNC $MIF243 2323 <2> POP DI ;;AN006;; No, 2324 <2> POP ES ;;AN006;; Restore old pointer 2325 <2> POP CX ;;AN006;; 2326 <2> ; $ELSE ;;AN006;; Yes 2327 <2> JMP SHORT $MEN243 2328 <2> $MIF243: 2329 <2> ADD SP,6 ;;AN006;; Throw away old pointer 2330 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 2331 <2> ; $ENDIF ;;AN006;; 2332 <2> $MEN243: 2333 <2> POP BP ;;AN006;; Restore other Regs 2334 <2> POP DX ;;AN006;; 2335 <2> ; $ENDIF ;;AN006;; 2336 <2> $MIF239: 2337 <2> $M_POPF ;;AN006;; Restore the flag state 2338 <2> 2339 <2> POP BX ;;AN000;; 2340 <2> POP SI ;;AN000;; 2341 <2> RET ;;AN000;; Return ES:DI pointing to the message 2342 <2> ;; 2343 <2> $M_GET_MSG_ADDRESS ENDP ;; 2344 <2> ;; 2345 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 2346 <2> ;; 2347 <2> PUSH DI ;;AN006;; Save position 2348 <2> PUSH AX ;;AN006;; 2349 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 2350 <2> XOR AL,AL ;;AN006;; Prepare compare register 2351 <2> REPNE SCASB ;;AN006;; Scan for zero 2352 <2> NOT CX ;;AN006;; Change decrement into number 2353 <2> DEC CX ;;AN006;; Don't include the zero 2354 <2> POP AX ;;AN006;; 2355 <2> POP DI ;;AN006;; Restore position 2356 <2> RET ;;AN006;; 2357 <2> ;; 2358 <2> $M_SET_LEN_IN_CX ENDP ;; 2359 <2> ;; 2360 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2361 <2> ;; 2362 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 2363 <2> ;; 2364 <2> ;; FUNCTION: To scan thru message headers until message is found 2365 <2> ;; INPUTS: ES:DI points to beginning of msg headers 2366 <2> ;; CX contains the number of messages in class 2367 <2> ;; DH contains the message class 2368 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2369 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 2370 <2> ;; 2371 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2372 <2> ;; 2373 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 2374 <2> ;; 2375 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 2376 <2> ; $IF E,AND ;;AN004;; Yes, 2377 <2> JNE $MIF247 2378 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 2379 <2> ; $IF NE ;;AN004;; Yes, 2380 <2> JE $MIF247 2381 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 2382 <2> ; $IF E ;;AN004;; . . . and . . . 2383 <2> JNE $MIF248 2384 <2> PUSH AX ;;AN004;; Reset the special message number 2385 <2> MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 2386 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2387 <2> POP AX ;;AN004;; Reset the special message number 2388 <2> ; $ELSE ;;AN004;; Get the old message number 2389 <2> JMP SHORT $MEN248 2390 <2> $MIF248: 2391 <2> CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2392 <2> ; $ENDIF ;;AN004;; Get the old message number 2393 <2> $MEN248: 2394 <2> ; $ELSE ;;AN004;; 2395 <2> JMP SHORT $MEN247 2396 <2> $MIF247: 2397 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 2398 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2399 <2> ; $IF NE ;;AN001;; 2400 <2> JE $MIF252 2401 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 2402 <2> ; $ELSE ;;AN001;; 2403 <2> JMP SHORT $MEN252 2404 <2> $MIF252: 2405 <2> %IF FARmsg ;;AN001;; 2406 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2407 <2> %ELSE 2408 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2409 <2> %ENDIF 2410 <2> ; $IF E ;;AN002;; pointer (hopefully) 2411 <2> JNE $MIF254 2412 <2> %IF FARmsg ;;AN001;; 2413 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2414 <2> %ELSE 2415 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2416 <2> %ENDIF 2417 <2> ; $ENDIF ;;AN002;; go on to the next class 2418 <2> $MIF254: 2419 <2> ; $ENDIF ;;AN001;; 2420 <2> $MEN252: 2421 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 2422 <2> STC ;;AN004;; Flag that we haven't found anything yet 2423 <2> ; $ENDIF ;;AN004;; 2424 <2> $MEN247: 2425 <2> 2426 <2> ; $IF C ;;AN004;; Have we found anything yet? 2427 <2> JNC $MIF258 2428 <2> CLC ;;AN004;; No, reset carry 2429 <2> ; $SEARCH ;;AN000;; 2430 <2> $MDO259: 2431 <2> OR CX,CX ;;AN000;; Do we have any to check? 2432 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2433 <2> JZ $MEN259 2434 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2435 <2> ; $IF NE ;;AN001;; 2436 <2> JE $MIF261 2437 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 2438 <2> ; $ELSE ;;AN001;; 2439 <2> JMP SHORT $MEN261 2440 <2> $MIF261: 2441 <2> %IF FARmsg ;;AN001;; 2442 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 2443 <2> %ELSE 2444 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 2445 <2> %ENDIF 2446 <2> ; $ENDIF 2447 <2> $MEN261: 2448 <2> ; $EXITIF E ;;AN000;; 2449 <2> JNE $MIF259 2450 <2> ; $ORELSE ;;AN000; 2451 <2> JMP SHORT $MSR259 2452 <2> $MIF259: 2453 <2> DEC CX ;;AN000;; No, well do we have more to check? 2454 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 2455 <2> JZ $MEN259 2456 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 2457 <2> ; $ENDLOOP ;;AN000;; 2458 <2> JMP SHORT $MDO259 2459 <2> $MEN259: 2460 <2> STC ;;AN000;; 2461 <2> ; $ENDSRCH ;;AN000;; Check next message 2462 <2> $MSR259: 2463 <2> ; $IF NC ;;AN000;; Did we find the message? 2464 <2> JC $MIF269 2465 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 2466 <2> CLC ;;AN001;; 2467 <2> ; $IF E ;;AN001;; 2468 <2> JNE $MIF270 2469 <2> %IF FARmsg ;;AN001;; 2470 <2> %ELSE ;;AN000;; 2471 <2> PUSH CS ;;AN000;; 2472 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 2473 <2> %ENDIF 2474 <2> ; $ENDIF ;;AN001;; 2475 <2> $MIF270: 2476 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 2477 <2> ; $ENDIF ;;AN004;; 2478 <2> $MIF269: 2479 <2> ; $ENDIF ;;AN004;; 2480 <2> $MIF258: 2481 <2> ;; Yes, great we can return with CX > 0 2482 <2> 2483 <2> ; $IF NC ;;AN000;; Did we find the message? 2484 <2> JC $MIF274 2485 <2> XOR CH,CH ;;AN000;; 2486 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 2487 <2> INC DI ;;AN000;; Increment past length 2488 <2> ; $ENDIF ;;AN004;; 2489 <2> $MIF274: 2490 <2> 2491 <2> MOV byte [cs:$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 2492 <2> RET ;;AN000;; Return 2493 <2> ;; 2494 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 2495 <2> ;; 2496 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2497 <2> %ENDIF ;;AN000;; END of include of common subroutines 2498 <2> ; 2499 <2> %IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms 2500 <2> %iassign $M_REPLACE FALSE ;;AN000;; Tell the assembler we did 2501 <2> ;; 2502 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2503 <2> $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; 2504 <2> ;; 2505 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2506 <2> %IFN COMR 2507 <2> CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) 2508 <2> ; $IF E ;;AN000;; Yes, 2509 <2> JNE $MIF276 2510 <2> MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE_HYP ;;AN000;; Move in a " -" 2511 <2> INC BX ;;AN000;; Increment count 2512 <2> INC BX ;;AN000;; Increment count 2513 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE ;;AN000;; Move in a " " 2514 <2> INC BX ;;AN000;; Increment count 2515 <2> CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case 2516 <2> ; $ENDIF ;;AN000;; If it fails we will catch it later 2517 <2> $MIF276: 2518 <2> %ENDIF 2519 <2> 2520 <2> POP BP ;;AN000;; Remember the return address 2521 <2> XOR BX,BX ;;AN000;; Use BX for buffer count 2522 <2> XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack 2523 <2> 2524 <2> MOV [cs:$M_RT + $M_SIZE],CL ;;AN000;; Save size to later clear stack 2525 <2> MOV AL,BYTE PTR [$M_SL + $M_S_MINW] ;;AN000;; Get the minimum width 2526 <2> ;; 2527 <2> CMP AL,CL ;;AN000;; Do we need pad chars added? 2528 <2> ; $IF A ;;AN000;; Yes, 2529 <2> JNA $MIF278 2530 <2> SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. 2531 <2> MOV DH,AL ;;AN000;; Save the number of pad characters 2532 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be right aligned? 2533 <2> ; $IF NZ ;;AN000;; Yes, 2534 <2> JZ $MIF279 2535 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2536 <2> $MDO280: 2537 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2538 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2539 <2> INC BX ;;AN000;; 2540 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2541 <2> ; $IF E ;;AN000;; Yes, 2542 <2> JNE $MIF281 2543 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2544 <2> ; $ENDIF ;;AN000;; 2545 <2> $MIF281: 2546 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2547 <2> ; $ENDDO Z ;;AN000;; No, next pad character 2548 <2> JNZ $MDO280 2549 <2> ; $ENDIF ;;AN000;; 2550 <2> $MIF279: 2551 <2> ; $ENDIF ;;AN000;; Yes, 2552 <2> $MIF278: 2553 <2> ;; 2554 <2> CMP BYTE [$M_SL + $M_S_MAXW],$M_UNLIM_W ;;AN000;; Is maximum width unlimited? 2555 <2> ; $IF NE ;;AN000;; 2556 <2> JE $MIF286 2557 <2> CMP BYTE PTR [$M_SL + $M_S_MAXW],CL ;;AN000;; Will we exceed maximum width? 2558 <2> ; $IF B ;;AN000;; Yes, 2559 <2> JNB $MIF287 2560 <2> SUB CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Calculate how many extra chars 2561 <2> MOV DL,CL ;;AN000;; Remember how many chars to pop off 2562 <2> MOV CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Set new string length 2563 <2> ; $ENDIF ;;AN000;; 2564 <2> $MIF287: 2565 <2> ; $ENDIF ;;AN000;; 2566 <2> $MIF286: 2567 <2> OR CX,CX ;;AN000;; 2568 <2> ; $IF NZ ;;AN000;; 2569 <2> JZ $MIF290 2570 <2> ; $DO ;;AN000;; Begin filling buffer with string 2571 <2> $MDO291: 2572 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2573 <2> ; $IF Z,AND ;;AN000;; 2574 <2> JNZ $MIF292 2575 <2> Char_field_ASCIIZ equ Char_Field_ASCIIZ ; NASM port equate 2576 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ; Is this replace a ASCIIZ string? 2577 <2> ; $IF NZ ;;AN000;; Yes, 2578 <2> JZ $MIF292 2579 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get first character from string 2580 <2> INC DI ;;AN000;; Next character in string 2581 <2> ; $ELSE ;;AN000;; No, 2582 <2> JMP SHORT $MEN292 2583 <2> $MIF292: 2584 <2> POP AX ;;AN000;; Get character in register 2585 <2> ; $ENDIF ;;AN000;; 2586 <2> $MEN292: 2587 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 2588 <2> INC BX ;;AN000;; Increase buffer count 2589 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2590 <2> ; $IF E ;;AN000;; Yes, 2591 <2> JNE $MIF295 2592 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2593 <2> ; $ENDIF ;;AN000;; 2594 <2> $MIF295: 2595 <2> DEC CL ;;AN000;; Have we completed replace? 2596 <2> ; $ENDDO Z ;;AN000;; Test again 2597 <2> JNZ $MDO291 2598 <2> ; $ENDIF ;;AN000;; 2599 <2> $MIF290: 2600 <2> ;; 2601 <2> TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be left aligned? 2602 <2> ; $IF Z ;;AN000;; Yes, 2603 <2> JNZ $MIF299 2604 <2> OR DH,DH ;;AN000;; Do we need pad chars added? 2605 <2> ; $IF NZ ;;AN000;; Yes, 2606 <2> JZ $MIF300 2607 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2608 <2> $MDO301: 2609 <2> MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 2610 <2> MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 2611 <2> INC BX ;;AN000;; 2612 <2> CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2613 <2> ; $IF E ;;AN000;; Yes, 2614 <2> JNE $MIF302 2615 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2616 <2> ; $ENDIF ;;AN000;; 2617 <2> $MIF302: 2618 <2> DEC DH ;;AN000;; Have we filled with enough pad chars? 2619 <2> ; $ENDDO Z ;;AN000;; Test again 2620 <2> JNZ $MDO301 2621 <2> ; $ENDIF ;;AN000;; 2622 <2> $MIF300: 2623 <2> ; $ENDIF ;;AN000;; 2624 <2> $MIF299: 2625 <2> ;; 2626 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2627 <2> ; $IF Z,AND ;;AN000;; 2628 <2> JNZ $MIF307 2629 <2> TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? 2630 <2> ; $IF NZ ;;AN000;; Yes, 2631 <2> JZ $MIF307 2632 <2> ; $ELSE ;;AN000;; 2633 <2> JMP SHORT $MEN307 2634 <2> $MIF307: 2635 <2> OR DL,DL ;;AN000;; 2636 <2> ; $IF NE ;;AN000;; 2637 <2> JE $MIF309 2638 <2> ; $DO ;;AN000;; 2639 <2> $MDO310: 2640 <2> POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable 2641 <2> DEC DL ;;AN000;; Are we done? 2642 <2> ; $ENDDO Z ;;AN000;; 2643 <2> JNZ $MDO310 2644 <2> ; $ENDIF ;;AN000;; 2645 <2> $MIF309: 2646 <2> ; $ENDIF ;;AN000;; 2647 <2> $MEN307: 2648 <2> CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time 2649 <2> PUSH BP ;;AN000;; Restore the return address 2650 <2> ;; 2651 <2> RET ;;AN000;; 2652 <2> ;; 2653 <2> $M_DISPLAY_REPLACE ENDP ;;AN000;; 2654 <2> ;; 2655 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2656 <2> ;; 2657 <2> ;; PROC NAME: $M_FLUSH_BUFFER 2658 <2> ;; 2659 <2> ;; FUNCTION: Display the contents of the temporary buffer 2660 <2> ;; INPUTS: DI contains the number of bytes to display 2661 <2> ;; OUTPUTS: BX reset to zero 2662 <2> ;; 2663 <2> ;; REGS USED: 2664 <2> ;; 2665 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2666 <2> ;; 2667 <2> $M_FLUSH_BUF PROC NEAR ;;AN000;; 2668 <2> ;; 2669 <2> PUSH CX ;;AN000;; Save changed regs 2670 <2> PUSH ES ;;AN000;; 2671 <2> PUSH DI ;;AN000;; 2672 <2> PUSH DS ;;AN000;; Set ES pointing to buffer 2673 <2> POP ES ;;AN000;; 2674 <2> ;; 2675 <2> MOV CX,BX ;;AN000;; Set number of bytes to display 2676 <2> XOR BX,BX ;;AN000;; Reset buffer counter 2677 <2> LEA DI,[$M_RT + $M_TEMP_BUF] ;;AN000;; Reset buffer location pointer 2678 <2> CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer 2679 <2> ;; 2680 <2> ; $IF NC ;;AN000;; Error? 2681 <2> JC $MIF314 2682 <2> POP DI ;;AN000;; No, Restore changed regs 2683 <2> POP ES ;;AN000;; 2684 <2> POP CX ;;AN000;; 2685 <2> ; $ELSE ;;AN000;; Yes, 2686 <2> JMP SHORT $MEN314 2687 <2> $MIF314: 2688 <2> ADD SP,6 ;;AN000;; Fix stack 2689 <2> STC ;;AN000;; 2690 <2> ; $ENDIF ;;AN000;; Error? 2691 <2> $MEN314: 2692 <2> ;; 2693 <2> RET ;;AN000;; Return 2694 <2> ;; 2695 <2> $M_FLUSH_BUF ENDP ;;AN000;; 2696 <2> ;; 2697 <2> ;; 2698 <2> %IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? 2699 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2700 <2> %iassign $M_CHAR_ONLY TRUE ;;AN000;; replacement code later 2701 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2702 <2> ;; 2703 <2> ;; PROC NAME: $M_CHAR_REPLACE 2704 <2> ;; 2705 <2> ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace 2706 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2707 <2> ;; ES:DI contains the VALUE from SUBLIST 2708 <2> ;; OUTPUTS: CX contains number of characters on stack 2709 <2> ;; Top of stack --> Last character 2710 <2> ;; . . . 2711 <2> ;; Bot of stack --> First character 2712 <2> ;; 2713 <2> ;; OTHER REGS Revised: AX 2714 <2> ;; 2715 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2716 <2> ;; 2717 <2> $M_CHAR_REPLACE PROC NEAR ;;AN000;; 2718 <2> ;; 2719 <2> POP BP ;;AN000;; Save return address 2720 <2> TEST byte [$M_SL + $M_S_FLAG],~ Char_Field_Char & $M_SIZE_MASK ;;AN000;; Was Character specified? 2721 <2> ; $IF Z ;;AN000;; Yes, 2722 <2> JNZ $MIF317 2723 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2724 <2> PUSH AX ;;AN000;; Put it on the stack 2725 <2> INC CX ;;AN000;; Increase the count 2726 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 2727 <2> ; $IF C ;;AN000;; Yes, 2728 <2> JNC $MIF318 2729 <2> MOV AL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 2730 <2> PUSH AX ;;AN000;; Put it on the stack 2731 <2> CLC ;;AN000;; Clear the carry 2732 <2> ; $ENDIF ;;AN000;; 2733 <2> $MIF318: 2734 <2> ; $ELSE ;;AN000;; No, it was an ASCIIZ string 2735 <2> JMP SHORT $MEN317 2736 <2> $MIF317: 2737 <2> ; $DO ;;AN000;; 2738 <2> $MDO321: 2739 <2> MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 2740 <2> OR AL,AL ;;AN000;; Is it the NULL? 2741 <2> ; $LEAVE Z ;;AN000;; No, 2742 <2> JZ $MEN321 2743 <2> INC DI ;;AN000;; Next character 2744 <2> INC CX ;;AN000;; Increment the count 2745 <2> ; $ENDDO ;;AN000;; Yes, 2746 <2> JMP SHORT $MDO321 2747 <2> $MEN321: 2748 <2> SUB DI,CX ;;AN000;; Set SI at the beginning of the string 2749 <2> ; $ENDIF ;;AN000;; 2750 <2> $MEN317: 2751 <2> ;;AN000;; 2752 <2> PUSH BP ;;AN000;; Restore return address 2753 <2> RET ;;AN000;; Return 2754 <2> ;; 2755 <2> $M_CHAR_REPLACE ENDP ;;AN000;; 2756 <2> ;; 2757 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2758 <2> %ENDIF ;;AN000;; END of include of CHAR replace code 2759 <2> ; 2760 <2> %IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? 2761 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2762 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2763 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2764 <2> ;; 2765 <2> ;; PROC NAME: $M_BIN2ASC_REPLACE 2766 <2> ;; 2767 <2> ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string 2768 <2> ;; and prepare to display 2769 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2770 <2> ;; ES:DI contains the VALUE from SUBLIST 2771 <2> ;; OUTPUTS: CX contains number of characters on stack 2772 <2> ;; Top of stack --> Last character 2773 <2> ;; . . . 2774 <2> ;; Bot of stack --> First character 2775 <2> ;; OTHER REGS Revised: BX,DX,AX 2776 <2> ;; 2777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2778 <2> ;; 2779 <2> $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; 2780 <2> ;; 2781 <2> POP BP ;;AN000;; Save return address 2782 <2> ;; 2783 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2784 <2> XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) 2785 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE16 ;;AN000;; Set default divisor 2786 <2> XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) 2787 <2> %IFN COMR 2788 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_BYTE & $M_SIZE_MASK ;;AN000;; Was BYTE specified? 2789 <2> ; $IF Z ;;AN000;; 2790 <2> JNZ $MIF325 2791 <2> MOV AL, BYTE PTR [ES:DI] ;;AN000;; Setup byte in AL 2792 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2793 <2> ; $IF Z ;;AN000;; 2794 <2> JNZ $MIF326 2795 <2> TEST AL,10000000b ;;AN000;; Is this number negative? 2796 <2> ; $IF NZ ;;AN000;; Yes, 2797 <2> JZ $MIF327 2798 <2> INC BX ;;AN000;; Remember that it was negative 2799 <2> AND AL,01111111b ;;AN000;; Make it positive 2800 <2> ; $ENDIF ;;AN000;; 2801 <2> $MIF327: 2802 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2803 <2> ; $ENDIF ;;AN000;; 2804 <2> $MIF326: 2805 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2806 <2> ; $IF Z ;;AN000;; 2807 <2> JNZ $MIF330 2808 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2809 <2> ; $ENDIF ;;AN000;; 2810 <2> $MIF330: 2811 <2> ; $ELSE ;;AN000;; 2812 <2> JMP SHORT $MEN325 2813 <2> $MIF325: 2814 <2> %ENDIF 2815 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_WORD & $M_SIZE_MASK ;;AN000;; Was WORD specified? 2816 <2> ; $IF Z ;;AN000;; 2817 <2> JNZ $MIF333 2818 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup byte in AL 2819 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;; AN000;; Was Signed binary specified? 2820 <2> ; $IF Z ;;AN000;; 2821 <2> JNZ $MIF334 2822 <2> TEST AH,10000000b ;;AN000;; Is this number negative? 2823 <2> ; $IF NZ ;;AN000;; Yes, 2824 <2> JZ $MIF335 2825 <2> INC BX ;;AN000;; Remember that it was negative 2826 <2> AND AH,01111111b ;;AN000;; Make it positive 2827 <2> ; $ENDIF ;;AN000;; 2828 <2> $MIF335: 2829 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2830 <2> ; $ENDIF ;;AN000;; 2831 <2> $MIF334: 2832 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2833 <2> ; $IF Z ;;AN000;; 2834 <2> JNZ $MIF338 2835 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2836 <2> ; $ENDIF ;;AN000;; 2837 <2> $MIF338: 2838 <2> ; $ELSE ;;AN000;; 2839 <2> JMP SHORT $MEN333 2840 <2> $MIF333: 2841 <2> %IFN COMR 2842 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup Double word in DX:AX 2843 <2> MOV DX, WORD PTR [ES:DI + 2] ;;AN000;; 2844 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2845 <2> ; $IF Z ;;AN000;; 2846 <2> JNZ $MIF341 2847 <2> TEST DH,10000000b ;;AN000;; Is this number negative? 2848 <2> ; $IF NZ ;;AN000;; Yes, 2849 <2> JZ $MIF342 2850 <2> INC BX ;;AN000;; Remember that it was negative 2851 <2> AND DH,01111111b ;;AN000;; Make it positive 2852 <2> ; $ENDIF ;;AN000;; 2853 <2> $MIF342: 2854 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2855 <2> ; $ENDIF ;;AN000;; 2856 <2> $MIF341: 2857 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2858 <2> ; $IF Z ;;AN000;; 2859 <2> JNZ $MIF345 2860 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2861 <2> ; $ENDIF ;;AN000;; 2862 <2> $MIF345: 2863 <2> %ENDIF 2864 <2> ; $ENDIF ;;AN000;; 2865 <2> $MEN333: 2866 <2> ; $ENDIF ;;AN000;; 2867 <2> $MEN325: 2868 <2> ;; 2869 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string 2870 <2> %IFN COMR 2871 <2> OR BX,BX ;;AN000;; 2872 <2> ; $IF NZ ;;AN000;; Was number negative? 2873 <2> JZ $MIF349 2874 <2> XOR DX,DX ;;AN000;; Yes, 2875 <2> MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number 2876 <2> PUSH DX ;;AN000;; 2877 <2> ; $ENDIF ;;AN000;; No, 2878 <2> $MIF349: 2879 <2> %ENDIF 2880 <2> ;; 2881 <2> PUSH BP ;;AN000;; Restore return address 2882 <2> RET ;;AN000;; Return 2883 <2> ;; 2884 <2> $M_BIN2ASC_REPLACE ENDP ;;AN000;; 2885 <2> ;; 2886 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2887 <2> %ENDIF ;;AN000;; END of include of NUM replace code 2888 <2> ; 2889 <2> %IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? 2890 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2891 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2892 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2893 <2> ;; 2894 <2> ;; PROC NAME: $M_DATE_REPLACE 2895 <2> ;; 2896 <2> ;; FUNCTION: Convert a date to a decimal ASCII string using current 2897 <2> ;; country format and prepare to display 2898 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2899 <2> ;; ES:DI points at VALUE from SUBLIST 2900 <2> ;; OUTPUTS: CX contains number of characters on stack 2901 <2> ;; Top of stack --> Last character 2902 <2> ;; . . . 2903 <2> ;; Bot of stack --> First character 2904 <2> ;; OTHER REGS Revised: DX, AX 2905 <2> ;; 2906 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2907 <2> ;; 2908 <2> $M_DATE_REPLACE PROC NEAR ;;AN000;; 2909 <2> ;; 2910 <2> POP BP ;;AN000;; Save return address 2911 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2912 <2> CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT 2913 <2> ;;AN000;; All O.K.? 2914 <2> XOR DX,DX ;;AN000;; Reset DX value 2915 <2> XOR AX,AX ;;AN000;; Reset AX value 2916 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],0 ;;AN000;; USA Date Format 2917 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2918 <2> JNE $MIF351 2919 <2> CALL $M_YEAR ;;AN000;; Get Year 2920 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2921 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2922 <2> INC CX ;;AN000;; Increment count 2923 <2> XOR AX,AX ;;AN000;; Reset AX value 2924 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2925 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2926 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2927 <2> INC CX ;;AN000;; Increment count 2928 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2929 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2930 <2> ; $ENDIF ;;AN000;; 2931 <2> $MIF351: 2932 <2> ;; 2933 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],1 ;;AN000;; EUROPE Date Format 2934 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2935 <2> JNE $MIF353 2936 <2> CALL $M_YEAR ;;AN000;; Get Year 2937 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2938 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2939 <2> INC CX ;;AN000;; 2940 <2> XOR AX,AX ;;AN000;; Reset AX 2941 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2942 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2943 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2944 <2> INC CX ;;AN000;; 2945 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2946 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2947 <2> ; $ENDIF ;;AN000;; 2948 <2> $MIF353: 2949 <2> ;; 2950 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],2 ;;AN000;; JAPAN Date Format 2951 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2952 <2> JNE $MIF355 2953 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2954 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2955 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2956 <2> INC CX ;;AN000;; 2957 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2958 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2959 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2960 <2> INC CX ;;AN000;; 2961 <2> CALL $M_YEAR ;;AN000;; Get Year 2962 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2963 <2> ; $ENDIF ;;AN000;; 2964 <2> $MIF355: 2965 <2> ;; 2966 <2> PUSH BP ;;AN000;; Restore return address 2967 <2> RET ;;AN000;; Return 2968 <2> ;; 2969 <2> $M_DATE_REPLACE ENDP ;;AN000;; 2970 <2> ;; 2971 <2> $M_GET_DATE PROC NEAR ;;AN000;; 2972 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 2973 <2> MOV AL,0 ;;AN000;; Get current country info 2974 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 2975 <2> INT 21H ;;AN000;; 2976 <2> ; $IF C ;;AN000;; No, 2977 <2> JNC $MIF357 2978 <2> MOV WORD [$M_RT + $M_DATE_FORMAT],$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) 2979 <2> MOV BYTE [$M_RT + $M_DATE_SEPARA],$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) 2980 <2> ; $ENDIF ;;AN000;; 2981 <2> $MIF357: 2982 <2> RET ;;AN000;; 2983 <2> $M_GET_DATE ENDP ;;AN000;; 2984 <2> ;; 2985 <2> $M_YEAR PROC NEAR ;;AN000;; 2986 <2> MOV AX,WORD PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Year 2987 <2> TEST byte [$M_SL + $M_S_FLAG],Date_MDY_4 & $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? 2988 <2> ; $IF Z ;;AN000;; 2989 <2> JNZ $MIF359 2990 <2> CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year 2991 <2> ; $IF A ;;AN000;; 2992 <2> JNA $MIF360 2993 <2> MOV AX,$M_MAX_2_YEAR ;;AN000;; 2994 <2> ; $ENDIF ;;AN000;; 2995 <2> $MIF360: 2996 <2> ; $ENDIF ;;AN000;; 2997 <2> $MIF359: 2998 <2> RET ;;AN000;; 2999 <2> $M_YEAR ENDP ;;AN000;; 3000 <2> ;; 3001 <2> $M_CONVERTDATE PROC NEAR ;;AN000;; 3002 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3003 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3004 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3005 <2> DEC CX ;;AN000;; Test if size only grew by 1 3006 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3007 <2> ; $IF E ;;AN000;; Yes, 3008 <2> JNE $MIF363 3009 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3010 <2> PUSH AX ;;AN000;; Save it 3011 <2> INC CX ;;AN000;; Count it 3012 <2> ; $ENDIF ;;AN000;; 3013 <2> $MIF363: 3014 <2> INC CX ;;AN000;; Restore CX 3015 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3016 <2> RET ;;AN000;; 3017 <2> $M_CONVERTDATE ENDP ;;AN000;; 3018 <2> ;; 3019 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3020 <2> %ENDIF ;;AN000;; END of include of DATE replace code 3021 <2> ; 3022 <2> %IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? 3023 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 3024 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 3025 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3026 <2> ;; 3027 <2> ;; PROC NAME: $M_TIME_REPLACE 3028 <2> ;; 3029 <2> ;; FUNCTION: Convert a time to a decimal ASCII string 3030 <2> ;; and prepare to display 3031 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 3032 <2> ;; ES:DI points at VALUE from SUBLIST 3033 <2> ;; OUTPUTS: CX contains number of characters on stack 3034 <2> ;; Top of stack --> Last character 3035 <2> ;; . . . 3036 <2> ;; Bot of stack --> First character 3037 <2> ;; REGS USED: BP,CX,AX 3038 <2> ;; 3039 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3040 <2> ;; 3041 <2> $M_TIME_REPLACE PROC NEAR ;;AN000;; 3042 <2> ;; 3043 <2> POP BP ;;AN000;; Save return address 3044 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 3045 <2> CALL $M_GET_TIME ;;AN000;; All O.K.? 3046 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3047 <2> ; $IF NZ ;;AN000;; Yes, 3048 <2> JZ $MIF365 3049 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3050 <2> ; $IF E ;;AN000;; Yes, 3051 <2> JNE $MIF366 3052 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3053 <2> CMP AL,12 ;;AN000;; Is hour 12 or less? 3054 <2> ; $IF L,OR ;;AN000;; or 3055 <2> JL $MLL367 3056 <2> CMP AL,23 ;;AN000;; Is hour 24 or greater? 3057 <2> ; $IF G ;;AN000;; Yes, 3058 <2> JNG $MIF367 3059 <2> $MLL367: 3060 <2> MOV AL,$M_AM ;;AN000;; 3061 <2> PUSH AX ;;AN000;; Push an "a" to represent AM. 3062 <2> INC CX ;;AN000;; 3063 <2> ; $ELSE ;;AN000;; No, 3064 <2> JMP SHORT $MEN367 3065 <2> $MIF367: 3066 <2> MOV AL,$M_PM ;;AN000;; 3067 <2> PUSH AX ;;AN000;; Push an "p" to represent PM. 3068 <2> INC CX ;;AN000;; 3069 <2> ; $ENDIF ;;AN000;; 3070 <2> $MEN367: 3071 <2> ; $ENDIF ;;AN000;; 3072 <2> $MIF366: 3073 <2> ; $ENDIF ;;AN000;; 3074 <2> $MIF365: 3075 <2> ;; 3076 <2> XOR AX,AX ;;AN000;; 3077 <2> XOR DX,DX ;;AN000;; 3078 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3079 <2> ; $IF NZ ;;AN000;; 3080 <2> JZ $MIF372 3081 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Hundreds 3082 <2> CALL $M_CONVERTTIME ;;AN000;; 3083 <2> PUSH WORD [$M_RT + $M_DECI_SEPARA] ;;AN000;; 3084 <2> INC CX ;;AN000;; 3085 <2> ; $ENDIF ;;AN000;; 3086 <2> $MIF372: 3087 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3088 <2> ; $IF NZ,OR ;;AN000;; 3089 <2> JNZ $MLL374 3090 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSS_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? 3091 <2> ; $IF NZ ;;AN000;; 3092 <2> JZ $MIF374 3093 <2> $MLL374: 3094 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Seconds 3095 <2> CALL $M_CONVERTTIME ;;AN000;; 3096 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3097 <2> INC CX ;;AN000;; 3098 <2> ; $ENDIF ;;AN000;; 3099 <2> $MIF374: 3100 <2> ;; Do Hour/Min (12 Hour) 3101 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+1] ;;AN000;; Get Minutes 3102 <2> CALL $M_CONVERTTIME ;;AN000;; 3103 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3104 <2> INC CX ;;AN000;; 3105 <2> ;; 3106 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3107 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3108 <2> ; $IF NZ ;;AN000;; Yes, 3109 <2> JZ $MIF376 3110 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3111 <2> ; $IF E ;;AN000;; Yes, 3112 <2> JNE $MIF377 3113 <2> CMP AL,13 ;;AN000;; Is hour less than 12? 3114 <2> ; $IF GE ;;AN000;; Yes, 3115 <2> JNGE $MIF378 3116 <2> SUB AL,12 ;;AN000;; Set to a 12 hour value 3117 <2> ; $ENDIF ;;AN000;; 3118 <2> $MIF378: 3119 <2> CMP AL,0 ;;AN000;; Is hour less than 12? 3120 <2> ; $IF E ;;AN000;; Yes, 3121 <2> JNE $MIF380 3122 <2> MOV AL,12 ;;AN000;; Set to a 12 hour value 3123 <2> ; $ENDIF ;;AN000;; 3124 <2> $MIF380: 3125 <2> ; $ENDIF ;;AN000;; 3126 <2> $MIF377: 3127 <2> ; $ENDIF ;;AN000;; 3128 <2> $MIF376: 3129 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII 3130 <2> ;; 3131 <2> PUSH BP ;;AN000;; Restore return address 3132 <2> RET ;;AN000;; Return 3133 <2> ;; 3134 <2> $M_TIME_REPLACE ENDP ;;AN000;; 3135 <2> ;; 3136 <2> $M_GET_TIME PROC NEAR ;;AN000;; 3137 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 3138 <2> MOV AL,0 ;;AN000;; Get current country info 3139 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 3140 <2> INT 21H ;;AN000;; 3141 <2> ; $IF C ;;AN000;; No, 3142 <2> JNC $MIF384 3143 <2> MOV WORD [$M_RT + $M_TIME_FORMAT],$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) 3144 <2> MOV BYTE [$M_RT + $M_TIME_SEPARA],$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) 3145 <2> MOV BYTE [$M_RT + $M_DECI_SEPARA],$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) 3146 <2> ; $ENDIF ;;AN000;; 3147 <2> $MIF384: 3148 <2> RET ;;AN000;; 3149 <2> $M_GET_TIME ENDP ;;AN000;; 3150 <2> ;; 3151 <2> $M_CONVERTTIME PROC NEAR ;;AN000;; 3152 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3153 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3154 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3155 <2> DEC CX ;;AN000;; Test if size only grew by 1 3156 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3157 <2> ; $IF E ;;AN000;; Yes, 3158 <2> JNE $MIF386 3159 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3160 <2> PUSH AX ;;AN000;; Save it 3161 <2> INC CX ;;AN000;; Count it 3162 <2> ; $ENDIF ;;AN000;; 3163 <2> $MIF386: 3164 <2> INC CX ;;AN000;; Restore CX 3165 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3166 <2> RET ;;AN000;; 3167 <2> $M_CONVERTTIME ENDP ;;AN000;; 3168 <2> ;; 3169 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3170 <2> %ENDIF ;;AN000;; END of include of TIME replace 3171 <2> %ENDIF ;;AN000;; END of include of Replacement common code 3172 <2> ; 3173 <2> %IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? 3174 <2> INPUTmsg equ FALSE ;;AN000;; Yes, THEN include it and reset the flag 3175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3176 <2> ;; 3177 <2> ;; PROC NAME: $M_WAIT_FOR_INPUT 3178 <2> ;; 3179 <2> ;; FUNCTION: To accept keyed input and return extended key value 3180 <2> ;; in AX register 3181 <2> ;; INPUTS: DL contains the DOS function requested for input 3182 <2> ;; OUPUTS: AX contains the extended key value that was read 3183 <2> ;; REGS USED: 3184 <2> ;; 3185 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3186 <2> ;; 3187 <2> $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; 3188 <2> ;; 3189 <2> PUSH CX ;;AN000;; Save CX 3190 <2> PUSH DX ;;AN000;; Save DX 3191 <2> PUSH DS ;;AN000;; Save Data segment 3192 <2> ;; 3193 <2> CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? 3194 <2> ; $IF A ;;AN001;; Yes, 3195 <2> JNA $MIF388 3196 <2> MOV AL,DL ;;AN001;; Mov function into AL 3197 <2> AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble 3198 <2> MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function 3199 <2> ; $ELSE ;;AN001;; No, 3200 <2> JMP SHORT $MEN388 3201 <2> $MIF388: 3202 <2> MOV AH,DL ;;AN000;; Put DOS function in AH 3203 <2> ; $ENDIF ;;AN001;; 3204 <2> $MEN388: 3205 <2> PUSH ES ;;AN000;; Get output buffer segment 3206 <2> POP DS ;;AN000;; 3207 <2> MOV DX,DI ;;AN000;; Get output buffer offset in case needed 3208 <2> INT 21H ;;AN000;; Get keyboard input 3209 <2> POP DS ;;AN000;; 3210 <2> 3211 <2> CMP DL,DOS_BUF_KEYB_INP ;;AN000;; 3212 <2> CLC ;;AN000;; 3213 <2> ; $IF NE ;;AN000;; If character input 3214 <2> JE $MIF391 3215 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? 3216 <2> ; $IF C ;;AN000;; 3217 <2> JNC $MIF392 3218 <2> MOV CL,AL ;;AN000;; Save first character 3219 <2> MOV AH,DL ;;AN001;; Get back function 3220 <2> INT 21H ;;AN000;; Get keyboard input 3221 <2> MOV AH,CL ;;AN000;; Retreive first character AX = xxxx 3222 <2> CLC ;;AN000;; Clear carry condition 3223 <2> ; $ELSE ;;AN000;; 3224 <2> JMP SHORT $MEN392 3225 <2> $MIF392: 3226 <2> MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS 3227 <2> ; $ENDIF ;;AN000;; 3228 <2> $MEN392: 3229 <2> ; $ENDIF ;;AN000;; 3230 <2> $MIF391: 3231 <2> ;; 3232 <2> ; $IF NC ;;AN000;; 3233 <2> JC $MIF396 3234 <2> POP DX ;;AN000;; 3235 <2> POP CX ;;AN000;; 3236 <2> ; $ELSE ;;AN000;; 3237 <2> JMP SHORT $MEN396 3238 <2> $MIF396: 3239 <2> ADD SP,4 ;;AN000;; 3240 <2> STC ;;AN000;; Reset carry flag 3241 <2> ; $ENDIF ;;AN000;; 3242 <2> $MEN396: 3243 <2> RET ;;AN000;; Return 3244 <2> ;; 3245 <2> $M_WAIT_FOR_INPUT ENDP ;;AN000;; 3246 <2> ;; 3247 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3248 <2> %ENDIF ;;AN000;; END of include of Wait for Input 3249 <2> %ENDIF ;;AN000;; END of include of SYSDISPMSG 3250 <2> %ENDIF ;;AN000;; END of include of MSG_DATA_ONLY 3251 <2> %ENDIF ;;AN000;; END of include of Structure only 3252 <2> 3253 <2> ;=== Pop trace listing source 3254 <2> 433 <1> 434 <1> %ENDIF 435 <1> 43 44 MSG_SERVICES "DISPLAYmsg","CHARmsg" 364 <1> %iassign $M_SERVICE FALSE 365 <1> %rep %0 366 <1> %iassign $M_INCLUDE TRUE 367 <1> %iassign MSG_SERVICES_MATCHED 0 368 <1> %ifidni %1, "MSGDATA" 369 <1> %iassign MSGDATA TRUE 370 <1> %iassign $M_SERVICE TRUE 371 <1> %iassign $M_INCLUDE FALSE 372 <1> %iassign MSG_SERVICES_MATCHED 1 373 <1> %else 374 <1> %iassign $M_MSGDATA_ONLY FALSE 375 <1> %endif 376 <1> 377 <1> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <1> 379 <1> %ifidni %1,"COMR" 380 <1> %iassign COMR TRUE 381 <1> %iassign $M_SERVICE TRUE 382 <1> %iassign $M_INCLUDE FALSE 383 <1> %iassign MSG_SERVICES_MATCHED 1 384 <1> %elifidni %1,"COMT" 385 <1> %iassign COMT TRUE 386 <1> %iassign $M_SERVICE TRUE 387 <1> %iassign $M_INCLUDE FALSE 388 <1> %iassign MSG_SERVICES_MATCHED 1 389 <1> %elifidni %1,"SETSTDIO" 390 <1> %iassign SETSTDIO TRUE 391 <1> %iassign $M_SERVICE TRUE 392 <1> %iassign $M_INCLUDE FALSE 393 <1> %iassign MSG_SERVICES_MATCHED 1 394 <1> %elifidni %1,"NOCHECKSTDIN" 395 <1> %iassign NOCHECKSTDIN TRUE 396 <1> %iassign $M_SERVICE TRUE 397 <1> %iassign $M_INCLUDE FALSE 398 <1> %iassign MSG_SERVICES_MATCHED 1 399 <1> %elifidni %1,"NOCHECKSTDOUT" 400 <1> %iassign NOCHECKSTDOUT TRUE 401 <1> %iassign $M_SERVICE TRUE 402 <1> %iassign $M_INCLUDE FALSE 403 <1> %iassign MSG_SERVICES_MATCHED 1 404 <1> %elifidni %1,"DISK_PROC" 405 <1> %iassign DISK_PROC TRUE 406 <1> %iassign $M_SERVICE TRUE 407 <1> %iassign $M_INCLUDE FALSE 408 <1> %iassign MSG_SERVICES_MATCHED 1 409 <1> %endif 410 <1> 411 <1> %IF $M_INCLUDE 412 <1> %define %%string %1 413 <1> %strlen %%length %%string 414 <1> %assign %%ii 1 415 <1> %define %%name "" 416 <1> %rep %%length 417 <1> %substr %%cc %%string %%ii 418 <1> %assign %%ii %%ii + 1 419 <1> %if %%cc >= 'A' && %%cc <= 'Z' 420 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <1> %endif 422 <1> %strcat %%name %%name,%%cc 423 <1> %endrep 424 <1> %include %%name 425 <1> %ENDIF 426 <1> 427 <1> %rotate 1 428 <1> %endrep 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 424 <2> %include %%name 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 424 <2> %include %%name 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 429 <1> 430 <1> %IF $M_SERVICE 431 <1> 432 <1> %include "msgserv.nas" 1 <2> ;=== Push trace listing source: msgserv.nas 2 <2> 3 <2> ; * * * * * * * * * * * * START OF SPECIFICATIONS * * * * * * * * * * * * * * * 4 <2> ; 5 <2> ; MODULE NAME: MSGSERV.SAL 6 <2> ; 7 <2> ; DESCRIPTIVE NAME: Message Services SALUT file 8 <2> ; 9 <2> ; FUNCTION: This module incorporates all the messages services and 10 <2> ; is called upon at build time to INCLUDE the code requested 11 <2> ; by a utility. Code is requested using the macro MSG_SERVICES. 12 <2> ; 13 <2> ; ENTRY POINT: Since this a collection of subroutines, entry point is at 14 <2> ; requested procedure. 15 <2> ; 16 <2> ; INPUT: Since this a collection of subroutines, input is dependent on function 17 <2> ; requested. 18 <2> ; 19 <2> ; EXIT-NORMAL: In all cases, CARRY FLAG = 0 20 <2> ; 21 <2> ; EXIT-ERROR: In all cases, CARRY FLAG = 1 22 <2> ; 23 <2> ; INTERNAL REFERENCES: (list of included subroutines) 24 <2> ; 25 <2> ; - SYSLOADMSG 26 <2> ; - SYSDISPMSG 27 <2> ; - SYSGETMSG 28 <2> ; 29 <2> ; 30 <2> ; EXTERNAL REFERENCES: None 31 <2> ; 32 <2> ; NOTES: At build time, some modules must be included. These are only included 33 <2> ; once using assembler switches. Other logic is included at the request 34 <2> ; of the utility. 35 <2> ; 36 <2> ; COMR and COMT are assembler switches to conditionally assemble code 37 <2> ; for RESIDENT COMMAND.COM and TRANSIENT COMMAND.COM to reduce resident 38 <2> ; storage and multiple EQUates. 39 <2> ; 40 <2> ; REVISION HISTORY: Created MAY 1987 41 <2> ; 42 <2> ; Label: DOS - - Message Retriever 43 <2> ; (c) Copyright 1988 Microsoft 44 <2> ; 45 <2> ; 46 <2> ; * * * * * * * * * * * * END OF SPECIFICATIONS * * * * * * * * * * * * * * * * 47 <2> ; Page 48 <2> 49 <2> ; $SALUT $M (2,5,22,62) ;;AN000;; Set SALUT formatting 50 <2> 51 <2> %IF $M_STRUC ;;AN000;; IF we haven't included the structures yet THEN 52 <2> %iassign $M_STRUC FALSE ;;AN000;; Let the assembler know that we have 53 <2> ;;AN000;; and include them 54 <2> 55 <2> ; PAGE 56 <2> ; SUBTTL DOS - Message Retriever - MSGSTR.INC Module 57 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 58 <2> ;; 59 <2> ;; STRUCTURE: $M_SUBLIST_STRUC 60 <2> ;; 61 <2> ;; Replacable parameters are described by a sublist structure 62 <2> ;; 63 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 <2> ;; 65 <2> $M_SUBLIST_STRUC STRUC ;;AN000;; 66 <2> ;; 67 <2> $M_S_SIZE DB ? ;11 ;;AN000;; SUBLIST size (PTR to next SUBLIST) 68 <2> $M_S_RESV DB ? ;0 ;;AN000;; RESERVED 69 <2> $M_S_VALUE DD ? ;;AN000;; Time, Date or PTR to data item 70 <2> $M_S_ID DB ? ;;AN000;; n of %n 71 <2> $M_S_FLAG DB ? ;;AN000;; Data-type flags 72 <2> $M_S_MAXW DB ? ;;AN000;; Maximum field width 73 <2> $M_S_MINW DB ? ;;AN000;; Minimum field width 74 <2> $M_S_PAD DB ? ;;AN000;; Character for Pad field 75 <2> ;; 76 <2> $M_SUBLIST_STRUC ENDS ;;AN000;; 77 <2> ;; 78 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 <2> ;; 80 <2> ;; STRUCTURE: $M_CLASS_ID 81 <2> ;; 82 <2> ;; Each class will be defined by this structure. 83 <2> ;; 84 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 <2> ;; 86 <2> EXPECTED_VERSION equ expected_version ; NASM port equate 87 <2> 88 <2> $M_CLASS_ID STRUC ;;AN000;; 89 <2> ;; 90 <2> $M_CLS_ID DB ? ;-1 ;;AN000;; Class identifer 91 <2> $M_COMMAND_VER DW ? ;EXPECTED_VERSION ;;AN003;; COMMAND.COM version check 92 <2> $M_NUM_CLS_MSG DB ? ;0 ;;AN000;; Total number of message in class 93 <2> ;; 94 <2> $M_CLASS_ID ENDS ;; 95 <2> ;;AN000;; 96 <2> $M_CLASS_ID_SZ EQU $M_CLASS_ID_struc_size ;;AN000;; 97 <2> ;; 98 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 <2> ;; 100 <2> ;; STRUCTURE: $M_ID_STRUC 101 <2> ;; 102 <2> ;; Each message will be defined by this structure. 103 <2> ;; 104 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 105 <2> ;; 106 <2> $M_ID STRUC ;;AN000;; 107 <2> ;; 108 <2> $M_NUM DW ? ;-1 ;;AN000;; Message Number 109 <2> $M_TXT_PTR DW ? ;;AN000;; Pointer to message text 110 <2> ;; 111 <2> $M_ID ENDS ;;AN000;; 112 <2> ;;AN000;; Status Flag Values: 113 <2> $M_ID_SZ EQU $M_ID_struc_size ;;AN000;; 114 <2> ;; 115 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 116 <2> ;; 117 <2> ;; STRUCTURE: $M_RES_ADDRS 118 <2> ;; 119 <2> ;; Resident data area definition of variables 120 <2> ;; 121 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 122 <2> ;; 123 <2> $M_RES_ADDRS STRUC ;;AN000;; 124 <2> ;; 125 <2> $M_EXT_ERR_ADDRS DD ? ;0 ;;AN000;; Allow pointers to THREE Extended error locations 126 <2> $M_EXT_FILE DD ? ;0 ;;AN001;; 127 <2> $M_EXT_COMMAND DD ? ;0 ;;AN000;; 128 <2> $M_EXT_TERM DD ? ;-1 ;;AN000;; 129 <2> $M_PARSE_COMMAND DD ? ;0 ;;AN000;; 130 <2> $M_PARSE_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Parse error locations 131 <2> $M_PARSE_TERM DD ? ;-1 ;;AN000;; 132 <2> $M_CRIT_ADDRS DD ? ;0 ;;AN000;; Allow pointers to TWO Critical error locations 133 <2> $M_CRIT_COMMAND DD ? ;0 ;;AN000;; 134 <2> $M_CRIT_TERM DD ? ;-1 ;;AN000;; 135 <2> $M_DISK_PROC_ADDR DD ? ;-1 ;;AN004;; Address of READ_DISK_PROC 136 <2> $M_CLASS_ADDRS DD $M_NUM_CLS DUP (?) ;(0) ;;AN000;; Allow pointers to specified classes 137 <2> $M_CLS_TERM DD ? ;-1 ;;AN000;; 138 <2> $M_DBCS_VEC DD ? ;0 ;;AN000;; Save DBCS vector 139 <2> $M_HANDLE DW ? ;;AN000;; 140 <2> $M_SIZE DB ? ;0 ;;AN000;; 141 <2> $M_CRLF DB ?,? ;0DH,0AH ;;AN004;; CR LF message 142 <2> $M_CLASS DB ? ;;AN004;; Saved class 143 <2> $M_RETURN_ADDR DW ? ;;AN000;; 144 <2> $M_MSG_NUM DW ? ;$M_NULL ;;AN000;; 145 <2> $M_DIVISOR DW ? ;10 ;;AN000;; Default = 10 (must be a WORD for division) 146 <2> $M_TEMP_BUF DB $M_TEMP_BUF_SZ DUP (?) ;("$") ;;AN000;; Temporary buffer 147 <2> $M_BUF_TERM DB ? ;"$" ;;AN000;; 148 <2> 149 <2> $M_RES_ADDRS ENDS ;;AN000;; 150 <2> ;; 151 <2> $M_RES_ADDRS_SZ EQU $M_RES_ADDRS_struc_size ;;AN000;; 152 <2> ;; 153 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 154 <2> ;; 155 <2> ;; STRUCTURE: $M_COUNTRY_INFO 156 <2> ;; 157 <2> ;; Important fields of the Get Country Information call 158 <2> ;; 159 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 160 <2> ;; 161 <2> $M_COUNTRY_INFO STRUC ;;AN000;; Expected Country infomation 162 <2> ;; 163 <2> $M_HEADER DB $M_RES_ADDRS_SZ-$M_TEMP_BUF_SZ-1 DUP(?) ;;AN000;; Go past first part of struc 164 <2> $M_DATE_FORMAT DW ? ;;AN000;; <------- Date Format 165 <2> $M_CURR_SEPARA DB 5 DUP(?) ;;AN000;; 166 <2> $M_THOU_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Thou Separator 167 <2> $M_DECI_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Decimal Separator 168 <2> $M_DATE_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Date Separator 169 <2> $M_TIME_SEPARA DB ?,? ;?,0 ;;AN000;; <------- Time Separator 170 <2> $M_CURR_FORMAT DB ? ;;AN000;; 171 <2> $M_SIG_DIGS_CU DB ? ;;AN000;; 172 <2> $M_TIME_FORMAT DB ? ;;AN000;; <------- Time Format 173 <2> ;; 174 <2> $M_COUNTRY_INFO ENDS ;;AN000;; 175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 176 <2> ;; 177 <2> %ELSE ;;AN000;; ELSE if we have already included the STRUCTURES 178 <2> ; 179 <2> ; $SALUT $M (2,5,13,62) ;;AN000;; Set SALUT formatting for code section 180 <2> 181 <2> %IF MSGDATA ;;AN000;; IF this is a request to include the data area 182 <2> %iassign MSGDATA FALSE ;;AN000;; Let the assembler know not to include it again 183 <2> ;;AN000;; and include it 184 <2> ; PAGE 185 <2> ; SUBTTL DOS - Message Retriever - MSGRES.TAB Module 186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 187 <2> ;; 188 <2> ;; DATA NAME: $M_RES_TABLE 189 <2> ;; 190 <2> ;; REFERENCE LABEL: $M_RT 191 <2> ;; 192 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 193 <2> 194 <2> %if 0 ; disabled for now, figure out later 195 <2> %IF COMR ;;AN000;; Since COMMAND.COM includes this twice 196 <2> $M_RT EQU $M_RT2 ;;AN000;; we must redefine the label so no 197 <2> $M_RT2 LABEL BYTE ;;AN000;; assembly errors occur 198 <2> $M_ALTLABEL equ TRUE ;;AN000;; Flag that label was changed 199 <2> %ELSE ;;AN000;; 200 <2> $M_RT LABEL BYTE ;;AN000;; 201 <2> %ENDIF 202 <2> %endif 203 <2> $M_RT: ; NASM structure instance 204 <2> $M_RES_ADDRS_size equ $M_RES_ADDRS_struc_size ; NASM port equate 205 <2> istruc $M_RES_ADDRS 206 <2> at $M_EXT_ERR_ADDRS 207 <2> dd 0 208 <2> at $M_EXT_FILE 209 <2> dd 0 210 <2> at $M_EXT_COMMAND 211 <2> dd 0 212 <2> at $M_EXT_TERM 213 <2> dd -1 214 <2> at $M_PARSE_COMMAND 215 <2> dd 0 216 <2> at $M_PARSE_ADDRS 217 <2> dd 0 218 <2> at $M_PARSE_TERM 219 <2> dd -1 220 <2> at $M_CRIT_ADDRS 221 <2> dd 0 222 <2> at $M_CRIT_COMMAND 223 <2> dd 0 224 <2> at $M_CRIT_TERM 225 <2> dd -1 226 <2> at $M_DISK_PROC_ADDR 227 <2> dd -1 228 <2> at $M_CLASS_ADDRS 229 <2> times $M_NUM_CLS dd 0 230 <2> at $M_CLS_TERM 231 <2> dd -1 232 <2> at $M_DBCS_VEC 233 <2> dd 0 234 <2> at $M_HANDLE 235 <2> dw 0 236 <2> at $M_SIZE 237 <2> db 0 238 <2> at $M_CRLF 239 <2> db 0Dh, 0Ah 240 <2> at $M_CLASS 241 <2> db 0 242 <2> at $M_RETURN_ADDR 243 <2> dw 0 244 <2> at $M_MSG_NUM 245 <2> dw 0 246 <2> at $M_DIVISOR 247 <2> dw 10 248 <2> at $M_TEMP_BUF 249 <2> times $M_TEMP_BUF_SZ db "$" 250 <2> at $M_BUF_TERM 251 <2> db "$" 252 <2> iend 253 <2> ;; 254 <2> %include "copyrigh.mac" ;;AN001;; Include Copyright 1988 Microsoft 255 <2> ;; 256 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 257 <2> %ENDIF ;;AN000;; END of include of Data table 258 <2> 259 <2> ; 260 <2> %IFN $M_MSGDATA_ONLY ;;AN000;; IF this was a request for only the data table THEN 261 <2> ;; don't include any more code 262 <2> ;;AN000;; Figure out what other code to include 263 <2> %IF DISK_PROC ;;AN003;; Is the request to include the READ_DISK code 264 <2> %IF COMR ;;AN003;; (Only Resident COMMAND.COM should ask for it) 265 <2> $M_RT EQU $M_RT2 ;;AN003;; 266 <2> %ENDIF 267 <2> %iassign DISK_PROC FALSE ;;AN003;; Yes, THEN include it and reset flag 268 <2> ; PAGE 269 <2> ; SUBTTL DOS - Message Retriever - DISK_PROC Module 270 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 271 <2> ;; 272 <2> ;; PROC NAME: DISK_PROC 273 <2> ;; 274 <2> ;; FUNCTION: Used in COMMAND.COM if we need to access the Parse or Extended 275 <2> ;; errors from disk\diskette 276 <2> ;; INPUTS: AX has the message number 277 <2> ;; DX has the message class 278 <2> ;; AND ... the COMMAND.COM Variable RESGROUP:COMSPEC is 279 <2> ;; assumed to be set!! 280 <2> ;; 281 <2> ;; OUTPUTS: ES:DI points to message length (BYTE) followed by text 282 <2> ;; 283 <2> ;; 284 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 285 <2> ;; 286 <2> PUBLIC READ_DISK_PROC ;; 287 <2> ;; 288 <2> READ_DISK_PROC PROC FAR ;;AN003;; 289 <2> 290 <2> PUSH AX ;;AN003;; Save everything 291 <2> PUSH BX ;;AN003;; 292 <2> PUSH DX ;;AN003;; 293 <2> PUSH SI ;;AN003;; 294 <2> PUSH BP ;;AN003;; 295 <2> PUSH DS ;;AN003;; 296 <2> PUSH DI ;;AN003;; 297 <2> MOV BP,AX ;;AN003;; Save message number 298 <2> MOV AX,DOS_EXTENDED_OPEN ;;AN003;; Set INT 21 function 299 <2> LEA SI,[COMSPEC wrt RESGROUP] ;;AN003;; Get addressibilty to COMMAND.COM 300 <2> PUSH CS ;;AN003;; 301 <2> POP DS ;;AN003;; 302 <2> MOV DI,-1 ;;AN003;; No extended attribute list 303 <2> MOV BX,NO_CRIT_OPEN ;;AN003;; Don't generate critical error 304 <2> MOV DX,NOT_EX_FAIL_EX_OPEN ;;AN003;; Open Flag 305 <2> INT 21H ;;AN003;; Open the file 306 <2> POP DI ;;AN003;; Retreive LSEEK pointer 307 <2> ;;AN003;; Error ? 308 <2> ; $IF NC,LONG ;;AN003;; No, 309 <2> JNC $MXL1 310 <2> JMP $MIF1 311 <2> $MXL1: 312 <2> PUSH DI ;;AN003;; Save LSEEK pointer 313 <2> MOV BX,AX ;;AN003;; Set handle in BX 314 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; LSEEK to the errors 315 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 316 <2> MOV DX,DI ;;AN003;; 317 <2> INT 21H ;;AN003;; LSEEK the file 318 <2> POP DX ;;AN003;; Retreive LSEEK pointer 319 <2> ;;AN003;; Error ? 320 <2> ; $IF NC ;;AN003;; No, 321 <2> JC $MIF2 322 <2> INC CX ;;AN003;; Set flag to first pass 323 <2> ; $DO ;;AN003;; 324 <2> $MDO3: 325 <2> PUSH DX ;;AN003;; Save LSEEK pointer 326 <2> PUSH CX ;;AN003;; Save first pass flag 327 <2> PUSH AX ;;AN003;; Save number of messages (if set yet) 328 <2> XOR SI,SI ;;AN003;; Reset buffer index 329 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 330 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the first part of the header 331 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 332 <2> INT 21H ;;AN003;; Read it 333 <2> MOV DI,DX ;;AN003;; 334 <2> POP AX ;;AN003;; 335 <2> POP CX ;;AN003;; 336 <2> OR CX,CX ;;AN003;; 337 <2> ; $IF NZ ;;AN003;; 338 <2> JZ $MIF4 339 <2> XOR CX,CX ;;AN003;; Set flag to second pass 340 <2> XOR AH,AH ;;AN003;; Get number of messages in class 341 <2> MOV AL,[DI + $M_NUM_CLS_MSG] ;;AN003;; 342 <2> MOV SI,$M_CLASS_ID_SZ ;;AN003;; Initialize index 343 <2> CMP word [DI + $M_COMMAND_VER],EXPECTED_VERSION ;;AN003;; Is this the right version of COMMAND.COM? 344 <2> ; $ENDIF ;;AN003;; 345 <2> $MIF4: 346 <2> POP DX ;;AN003;; 347 <2> ; $IF Z ;;AN003;; Yes, 348 <2> JNZ $MIF6 349 <2> ; $SEARCH ;;AN003;; 350 <2> $MDO7: 351 <2> CMP BP,WORD PTR [$M_RT + $M_TEMP_BUF + SI] ;;AN003;; Is this the message I'm looking for? 352 <2> ; $EXITIF Z ;;AN003;; Yes, (ZF=1) 353 <2> JNZ $MIF7 354 <2> CLC ;;AN003;; Reset carry, exit search 355 <2> ; $ORELSE ;;AN003;; No, (ZF=0) 356 <2> JMP SHORT $MSR7 357 <2> $MIF7: 358 <2> ADD SI,$M_ID_SZ ;;AN003;; Increment index 359 <2> ADD DX,$M_ID_SZ ;;AN003;; Add offset of first header 360 <2> DEC AX ;;AN003;; Decrement # of messages left 361 <2> ; $LEAVE Z ;;AN003;; Have we exhausted all messages? 362 <2> JZ $MEN7 363 <2> CMP SI,$M_TEMP_BUF_SZ-1 ;;AN003;; No, Have we exhausted the buffer? 364 <2> ; $ENDLOOP A ;;AN003;; No, Check next message (ZF=1) 365 <2> JNA $MDO7 366 <2> $MEN7: 367 <2> STC ;;AN003;; Yes, (ZF=0) set error (ZF=0) 368 <2> ; $ENDSRCH ;;AN003;; 369 <2> $MSR7: 370 <2> ; $ELSE ;;AN003;; No, 371 <2> JMP SHORT $MEN6 372 <2> $MIF6: 373 <2> XOR CX,CX ;;AN003;; Set Zero flag to exit READ Loop 374 <2> STC ;;AN003;; Set Carry 375 <2> ; $ENDIF ;;AN003;; 376 <2> $MEN6: 377 <2> ; $ENDDO Z ;;AN003;; Get next buffer full if needed 378 <2> JNZ $MDO3 379 <2> ;;AN003;; Error ? 380 <2> ; $IF NC ;;AN003;; No, 381 <2> JC $MIF16 382 <2> MOV AX,DOS_LSEEK_FILE ;;AN003;; Prepare to LSEEK to the specific message 383 <2> XOR CX,CX ;;AN003;; Value has been set by COMMAND.COM 384 <2> ADD DX,$M_CLASS_ID_SZ ;;AN003;; Add offset of first header 385 <2> ADD DX,WORD PTR [$M_RT + $M_TEMP_BUF + SI + 2] ;;AN003;; Add offset from msg structure 386 <2> INT 21H ;;AN003;; LSEEK the file 387 <2> MOV AH,DOS_READ_BYTE ;;AN003;; Read 388 <2> MOV CX,$M_TEMP_BUF_SZ ;;AN003;; the message 389 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN003;; into the temp buffer 390 <2> INT 21H ;;AN003;; Read it 391 <2> MOV DI,DX ;;AN003;; into the temp buffer 392 <2> PUSH DS ;;AN003;; into the temp buffer 393 <2> POP ES ;;AN003;; into the temp buffer 394 <2> ; $ENDIF ;;AN003;; 395 <2> $MIF16: 396 <2> ; $ENDIF ;;AN003;; 397 <2> $MIF2: 398 <2> PUSHF ;;AN003;; Close file handle 399 <2> MOV AH,DOS_CLOSE_FILE ;;AN003;; Close file handle 400 <2> INT 21H ;;AN003;; 401 <2> $M_POPF ;;AN003;; 402 <2> ; $ENDIF ;;AN003;; Yes there was an error, 403 <2> $MIF1: 404 <2> POP DS ;;AN003;; 405 <2> POP BP ;;AN003;; 406 <2> POP SI ;;AN003;; 407 <2> POP DX ;;AN003;; 408 <2> POP BX ;;AN003;; 409 <2> POP AX ;;AN003;; 410 <2> ;;AN003;; abort everything 411 <2> RET ;;AN003;; 412 <2> 413 <2> READ_DISK_PROC ENDP ;;AN003;; 414 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 415 <2> %ENDIF ;;AN003;; END of include for DISK_PROC 416 <2> ; 417 <2> 418 <2> %IF SETSTDIO ;;AN000;; Is the request to include the code for SETSTDIO 419 <2> %iassign SETSTDIO FALSE ;;AN000;; Yes, THEN include it and reset flag 420 <2> ; PAGE 421 <2> ; SUBTTL DOS - Message Retriever - SETSTDIO Module 422 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 423 <2> ;; 424 <2> ;; PROC NAME: SETSTDIO 425 <2> ;; 426 <2> ;; FUNCTION: 427 <2> ;; INPUTS: 428 <2> ;; 429 <2> ;; OUPUTS: 430 <2> ;; 431 <2> ;; 432 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 433 <2> ;; 434 <2> %IF FARmsg ;AN001; 435 <2> SETSTDINON PROC FAR ;AN001; 436 <2> %ELSE ;AN001; 437 <2> SETSTDINON PROC NEAR ;AN001; 438 <2> %ENDIF ;AN001; 439 <2> PUSH AX ;AN002; Save changed regs 440 <2> PUSH BX ;AN002; 441 <2> PUSH DX ;AN002; 442 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 443 <2> MOV BX,STDIN ;AN001; 444 <2> XOR DX,DX ;AN001; 445 <2> INT 21H ;AN001; 446 <2> 447 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 448 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 449 <2> INT 21H ;AN001; 450 <2> POP DX ;AN002; Restore Regs 451 <2> POP BX ;AN002; 452 <2> POP AX ;AN002; 453 <2> 454 <2> RET ;AN001; 455 <2> ;AN001; 456 <2> SETSTDINON ENDP ;AN001; 457 <2> 458 <2> %IF FARmsg ;AN001; 459 <2> SETSTDINOFF PROC FAR ;AN001; 460 <2> %ELSE ;AN001; 461 <2> SETSTDINOFF PROC NEAR ;AN001; 462 <2> %ENDIF ;AN001; 463 <2> 464 <2> PUSH AX ;AN002; Save changed regs 465 <2> PUSH BX ;AN002; 466 <2> PUSH DX ;AN002; 467 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 468 <2> MOV BX,STDIN ;AN001; 469 <2> XOR DX,DX ;AN001; 470 <2> INT 21H ;AN001; 471 <2> 472 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 473 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 474 <2> INT 21H ;AN001; 475 <2> POP DX ;AN002; Restore Regs 476 <2> POP BX ;AN002; 477 <2> POP AX ;AN002; 478 <2> 479 <2> RET ;AN001; 480 <2> 481 <2> SETSTDINOFF ENDP ;AN001; 482 <2> 483 <2> %IF FARmsg ;AN001; 484 <2> SETSTDOUTON PROC FAR ;AN001; 485 <2> %ELSE ;AN001; 486 <2> SETSTDOUTON PROC NEAR ;AN001; 487 <2> %ENDIF ;AN001; 488 <2> 489 <2> PUSH AX ;AN002; Save changed regs 490 <2> PUSH BX ;AN002; 491 <2> PUSH DX ;AN002; 492 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 493 <2> MOV BX,STDOUT ;AN001; 494 <2> XOR DX,DX ;AN001; 495 <2> INT 21H ;AN001; 496 <2> 497 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 498 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 499 <2> INT 21H ;AN001; 500 <2> POP DX ;AN002; Restore Regs 501 <2> POP BX ;AN002; 502 <2> POP AX ;AN002; 503 <2> 504 <2> RET ;AN001; 505 <2> 506 <2> SETSTDOUTON ENDP ;AN001; 507 <2> 508 <2> %IF FARmsg ;AN001; 509 <2> SETSTDOUTOFF PROC FAR ;AN001; 510 <2> %ELSE ;AN001; 511 <2> SETSTDOUTOFF PROC NEAR 512 <2> %ENDIF ;AN001; 513 <2> 514 <2> PUSH AX ;AN002; Save changed regs 515 <2> PUSH BX ;AN002; 516 <2> PUSH DX ;AN002; 517 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 518 <2> MOV BX,STDOUT ;AN001; 519 <2> XOR DX,DX ;AN001; 520 <2> INT 21H ;AN001; 521 <2> 522 <2> AND DH,~ $M_CRIT_ERR_MASK ;AN001; Turn off bit 523 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 524 <2> INT 21H ;AN001; 525 <2> POP DX ;AN002; Restore Regs 526 <2> POP BX ;AN002; 527 <2> POP AX ;AN002; 528 <2> 529 <2> RET ;AN001; 530 <2> 531 <2> SETSTDOUTOFF ENDP ;AN001; 532 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 533 <2> %ENDIF ;;AN000;; END of include for SETSTDIO 534 <2> ; 535 <2> %IF LOADmsg ;;AN000;; Is the request to include the code for SYSLOADMSG ? 536 <2> %IF COMR ;;AN000;; 537 <2> $M_RT EQU $M_RT2 ;;AN000;; 538 <2> %ENDIF 539 <2> %iassign LOADmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 540 <2> ; PAGE 541 <2> ; SUBTTL DOS - Message Retriever - LOADMSG.ASM Module 542 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 543 <2> ;; 544 <2> ;; PROC NAME: SYSLOADMSG 545 <2> ;; 546 <2> ;; FUNCTION: 547 <2> ;; INPUTS: 548 <2> ;; 549 <2> ;; OUPUTS: 550 <2> ;; 551 <2> ;; 552 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 553 <2> ;; 554 <2> %IF FARmsg ;;AN000;; 555 <2> SYSLOADMSG PROC FAR ;;AN000;; 556 <2> %ELSE ;;AN000;; 557 <2> SYSLOADMSG PROC NEAR ;;AN000;; 558 <2> %ENDIF ;;AN000;; 559 <2> PUSH AX ;;AN000; 560 <2> PUSH BX ;;AN000; 561 <2> PUSH DX ;;AN000; 562 <2> PUSH ES ;;AN000; 563 <2> PUSH DI ;;AN000; 564 <2> XOR CX,CX ;;AN000; Reset to zero 565 <2> MOV ES,CX ;;AN000; 566 <2> XOR DI,DI ;;AN000; 567 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 568 <2> MOV DL,DOS_GET_EXTENDED ;;AN000;; Where are the Extended errors in COMMAND.COM 569 <2> INT 2FH ;;AN000;; Private interface 570 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 571 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_COMMAND],DI ;;AN000;; 572 <2> ;; 573 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 574 <2> MOV DL,DOS_GET_PARSE ;;AN000;; Where are the Parse errors in COMMAND.COM 575 <2> INT 2FH ;;AN000;; Private interface 576 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 577 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_COMMAND],DI ;;AN000;; 578 <2> ;; 579 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN000;; 2FH Interface 580 <2> MOV DL,DOS_GET_CRITICAL ;;AN000;; Where are the Critical errors in COMMAND.COM 581 <2> INT 2FH ;;AN000;; Private interface 582 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND+2],ES ;;AN000;; Move into first avaliable table location 583 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_COMMAND],DI ;;AN000;; 584 <2> 585 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 586 <2> MOV DL,DOS_GET_FILE ;;AN001;; Where are the FILE dependant in IFSFUNC.EXE 587 <2> INT 2FH ;;AN001;; Private interface 588 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE+2],ES ;;AN001;; Move into first avaliable table location 589 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_FILE],DI ;;AN001;; 590 <2> 591 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 592 <2> Extrn READ_DISK_PROC:Far ;;AN003;; 593 <2> %ELSE ;; 594 <2> %IF FARmsg ;;AN000;; 595 <2> CALL FAR PTR $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 596 <2> %ELSE ;;AN000;; 597 <2> CALL $M_MSGSERV_1 ;;AN000;; Get addressibilty to MSGSERV CLASS 1 (EXTENDED Errors) 598 <2> %ENDIF ;;AN000;; 599 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 600 <2> MOV WORD PTR [cs:$M_RT + $M_EXT_ERR_ADDRS],DI ;;AN000;; 601 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 602 <2> MOV WORD PTR [cs:$M_RT + $M_CRIT_ADDRS],DI ;;AN000;; 603 <2> ;; 604 <2> %IF FARmsg ;;AN000;; 605 <2> CALL FAR PTR $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 606 <2> %ELSE ;;AN000;; 607 <2> CALL $M_MSGSERV_2 ;;AN000;; Get addressibilty to MSGSERV CLASS 2 (PARSE Errors) 608 <2> %ENDIF ;;AN000;; 609 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS+2],ES ;;AN000;; Move into first avaliable table location 610 <2> MOV WORD PTR [cs:$M_RT + $M_PARSE_ADDRS],DI ;;AN000;; 611 <2> %ENDIF ;; 612 <2> ;; 613 <2> MOV AX,DOS_GET_EXT_PARSE_ADD ;;AN001;; 2FH Interface 614 <2> MOV DL,DOS_GET_ADDR ;;AN001;; Where is the READ_DISK_PROC in COMMAND.COM 615 <2> INT 2FH ;;AN001;; Private interface 616 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR+2],ES ;;AN001;; Move into first avaliable table location 617 <2> MOV WORD PTR [cs:$M_RT + $M_DISK_PROC_ADDR],DI ;;AN001;; 618 <2> 619 <2> $M_BUILD_PTRS $M_NUM_CLS ;;AN000;; Build all utility classes 620 <2> ;;AN000;; 621 <2> CALL $M_GET_DBCS_VEC ;;AN000;; Save the DBCS vector 622 <2> 623 <2> %IFN NOCHECKSTDIN ;;AN000;; IF EOF check is not to be suppressed 624 <2> CALL $M_CHECKSTDIN ;;AN000;; Set EOF CHECK 625 <2> %ENDIF ;;AN000;; 626 <2> ;;AN000;; 627 <2> %IFN NOCHECKSTDOUT ;;AN000;; IF Disk Full check is not to be suppressed 628 <2> CALL $M_CHECKSTDOUT ;;AN000;; Set Disk Full CHECK 629 <2> %ENDIF ;;AN000;; 630 <2> ;;AN000;; 631 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 632 <2> CLC ;;AN000;; Make sure carry is clear 633 <2> %ELSE ;;AN000;; ELSE 634 <2> PUSH CX ;;AN000;; 635 <2> CALL $M_VERSION_CHECK ;;AN000;; Check Version 636 <2> %ENDIF ;;AN000;; 637 <2> ;; Error ? 638 <2> ; $IF NC ;;AN000;; No. 639 <2> JC $MIF20 640 <2> %IFN NOVERCHECKmsg ;;AN000;; IF version check was not supressed 641 <2> POP CX ;;AN000;; Reset stack 642 <2> %ENDIF ;;AN000;; 643 <2> POP DI ;;AN000;; Restore REGS 644 <2> POP ES ;;AN000;; 645 <2> POP DX ;;AN000;; 646 <2> POP BX ;;AN000;; 647 <2> POP AX ;;AN000;; 648 <2> ; $ELSE ;;AN000;; Yes, 649 <2> JMP SHORT $MEN20 650 <2> $MIF20: 651 <2> %IF NOVERCHECKmsg ;;AN000;; IF version check is to be supressed 652 <2> ADD SP,10 ;;AN000;; 653 <2> STC ;;AN000;; Reset carry flag 654 <2> %ELSE ;;AN000;; IF version check is to be supressed 655 <2> ADD SP,12 ;;AN000;; 656 <2> STC ;;AN000;; Reset carry flag 657 <2> %ENDIF ;;AN000;; IF version check is to be supressed 658 <2> ; $ENDIF ;;AN000;; 659 <2> $MEN20: 660 <2> RET ;;AN000;; 661 <2> ;; 662 <2> SYSLOADMSG ENDP ;;AN000;; 663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 664 <2> ; PAGE 665 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 666 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 667 <2> ;; 668 <2> ;; Proc Name: $M_GET_DBCS_VEC 669 <2> ;; 670 <2> ;; Function: Get the DBCS vector and save it for later use 671 <2> ;; 672 <2> ;; Inputs: None 673 <2> ;; 674 <2> ;; Outputs: None 675 <2> ;; 676 <2> ;; Regs Changed: 677 <2> ;; 678 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 679 <2> ;; 680 <2> $M_GET_DBCS_VEC PROC NEAR ;;AN000;; 681 <2> ;; 682 <2> PUSH AX ;;AN000;; Save character to check 683 <2> PUSH SI ;;AN000;; 684 <2> PUSH DS ;;AN000;; 685 <2> MOV AX,DOS_GET_DBCS_INFO ;;AN000;; DOS function to get DBSC environment 686 <2> INT 21H ;;AN000;; Get environment pointer 687 <2> PUSH DS ;;AN000;; Get environment pointer 688 <2> POP ES ;;AN000;; Get environment pointer 689 <2> POP DS ;;AN000;; Get environment pointer 690 <2> ; $IF NC ;;AN000;; 691 <2> JC $MIF23 692 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC],SI ;;AN000;; Save DBCS Vector 693 <2> MOV WORD PTR [cs:$M_RT + $M_DBCS_VEC+2],ES ;;AN000;; 694 <2> ; $ENDIF ;;AN000;; 695 <2> $MIF23: 696 <2> POP SI ;;AN000;; 697 <2> POP AX ;;AN000;; Retrieve character to check 698 <2> RET ;;AN000;; Return 699 <2> ;; 700 <2> $M_GET_DBCS_VEC ENDP ;; 701 <2> ;; 702 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 703 <2> %IF NOCHECKSTDIN ;AN001; Are we suppose to include the code for Checking EOF ? 704 <2> %ELSE ;AN001; Yes, THEN include it 705 <2> ; PAGE 706 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDIN Proc 707 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 708 <2> ;; 709 <2> ;; Proc Name: $M_CHECKSTDIN 710 <2> ;; 711 <2> ;; Function: 712 <2> ;; 713 <2> ;; Inputs: None 714 <2> ;; 715 <2> ;; Outputs: 716 <2> ;; 717 <2> ;; Regs Changed: 718 <2> ;; 719 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 720 <2> ;; 721 <2> $M_CHECKSTDIN PROC NEAR ;AN001; 722 <2> 723 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 724 <2> MOV BX,STDIN ;AN001; 725 <2> XOR DX,DX ;AN001; 726 <2> INT 21H ;AN001; 727 <2> 728 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 729 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 730 <2> INT 21H ;AN001; 731 <2> 732 <2> RET ;AN001; 733 <2> 734 <2> $M_CHECKSTDIN ENDP ;AN001; 735 <2> ;; 736 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 737 <2> %ENDIF ;AN001; END of include for EOF Check 738 <2> %IF NOCHECKSTDOUT ;AN001; Are we suppose to include the code for Checking Disk Full? 739 <2> %ELSE ;AN001; Yes, THEN include it 740 <2> ; PAGE 741 <2> ; SUBTTL DOS - Message Retriever - $M_CHECKSTDOUT Proc 742 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 743 <2> ;; 744 <2> ;; Proc Name: $M_CHECKSTDOUT 745 <2> ;; 746 <2> ;; Function: 747 <2> ;; 748 <2> ;; Inputs: None 749 <2> ;; 750 <2> ;; Outputs: 751 <2> ;; 752 <2> ;; Regs Changed: 753 <2> ;; 754 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 755 <2> ;; 756 <2> $M_CHECKSTDOUT PROC NEAR ;AN001; 757 <2> 758 <2> MOV AX,DOS_IOCTL_GET_INFO ;AN001; Get info using IOCTL 759 <2> MOV BX,STDOUT ;AN001; 760 <2> XOR DX,DX ;AN001; 761 <2> INT 21H ;AN001; 762 <2> 763 <2> OR DH,$M_CRIT_ERR_MASK ;AN001; Turn on bit 764 <2> MOV AX,DOS_IOCTL_SET_INFO ;AN001; Set info using IOCTL 765 <2> INT 21H ;AN001; 766 <2> 767 <2> RET ;AN001; 768 <2> 769 <2> $M_CHECKSTDOUT ENDP ;AN001; 770 <2> ;; 771 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 772 <2> %ENDIF ;AN001; END of include for Disk Full Check 773 <2> %IF NOVERCHECKmsg ;;AN000;; Are we suppose to include the code for DOS version check? 774 <2> %ELSE ;;AN000;; Yes, THEN include it 775 <2> ; PAGE 776 <2> ; SUBTTL DOS - Message Retriever - $M_VERSION_CHECK Proc 777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 778 <2> ;; 779 <2> ;; Proc Name: $M_VERSION_CHECK 780 <2> ;; 781 <2> ;; Function: Determine if DOS version is within allowable limits 782 <2> ;; 783 <2> ;; Inputs: None 784 <2> ;; 785 <2> ;; Outputs: CARRY_FLAG = 1 if Incorrect DOS version 786 <2> ;; Registers set for SYSDISPMSG 787 <2> ;; CARRY_FLAG = 0 if Correct DOS version 788 <2> ;; 789 <2> ;; Regs Changed: AX 790 <2> ;; 791 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 792 <2> 793 <2> check_amis: 794 <2> push ax 795 <2> push ds 796 <2> push si 797 <2> push es 798 <2> push di 799 <2> push dx 800 <2> push ax ; version number, last on stack 801 <2> 802 <2> mov ah, 0 ; multiplex number = 0 803 <2> .loop: 804 <2> mov al, 0 805 <2> int 2Dh ; installation check 806 <2> cmp al, -1 ; multiplexer installed ? 807 <2> jne .next ; no --> 808 <2> push cs 809 <2> pop ds 810 <2> mov si, offset amis_sign ; ds:si -> amis_sign (for lDOS) 811 <2> mov es, dx ; es:di -> multiplexer's sign 812 <2> mov cx, 8 ; 16 bytes 813 <2> repe cmpsw ; compare 814 <2> jne .next ; not us --> 815 <2> mov dx, cs ; dx:si -> amis_id 816 <2> mov al, 11h 817 <2> int 2Dh ; CHG: al, bx, cx, dx, si, di 818 <2> cmp al, 0 ; id call supported ? 819 <2> je .unsup ; no, allow if alt version --> 820 <2> pop dx 821 <2> xor dx, dx ; 2D.MM11 supported, mark that we need it 822 <2> push dx 823 <2> cmp al, 0F0h ; CY if below 0F0h 824 <2> jmp .done 825 <2> 826 <2> .next: 827 <2> inc ah ; next multiplex number 828 <2> jnz .loop ; ZR if done, NZ if more to check --> 829 <2> .unsup: 830 <2> stc ; multiplexer not found 831 <2> ; or function not supported 832 <2> .done: 833 <2> ; CY if not an lDOS revision with our id supported, 834 <2> ; on stack: alt_expected_version if it's fine and either 835 <2> ; no multiplexer or func 11h not supported 836 <2> ; new_expected_version if not fine and either 837 <2> ; no multiplexer or func 11h not suppprted, 838 <2> ; 0 if multiplexer found, func 11h supported, but 839 <2> ; our id is unsupported 840 <2> ; NC if lDOS revision with multiplexer and our id supported 841 <2> pop bx 842 <2> pop dx 843 <2> pop di 844 <2> pop es 845 <2> pop si 846 <2> pop ds 847 <2> pop ax 848 <2> jnc alt_good_DOS ; id is supported --> 849 <2> cmp bx, alt_expected_version ; is it fine ? 850 <2> je alt_good_DOS ; yes --> (NC) 851 <2> jmp $MIF25 ; no, cancel program --> 852 <2> 853 <2> $M_VERSION_CHECK PROC NEAR ;;AN000;; 854 <2> ;; 855 <2> MOV AH,DOS_GET_VERSION ;;AN000;; Check that version matches VERSIONA.INC 856 <2> INT 21H ;;AN000;; 857 <2> ;; 858 <2> cmp ax,new_expected_version ; compare with DOS version 859 <2> je check_amis 860 <2> cmp ax,alt_expected_version ; compare with DOS version 861 <2> je check_amis 862 <2> CMP AX,EXPECTED_VERSION ;;AN000;; IF DOS_MAJOR is correct 863 <2> ; $IF E ;;AN000;; 864 <2> JNE $MIF25 865 <2> alt_good_DOS: 866 <2> CLC ;;AN000;; Clear the carry flag 867 <2> ; $ELSE ;;AN000;; ELSE 868 <2> JMP SHORT $MEN25 869 <2> $MIF25: 870 <2> %IFN COMR ;; ** Special case for RESIDENT COMMAND.COM 871 <2> CMP AX,LOWEST_4CH_VERSION ;;AN000;; Does this version support AH = 4CH 872 <2> ; $IF B ;;AN000;; No, 873 <2> JNB $MIF27 874 <2> MOV BX,NO_HANDLE ;;AN000;; No handle (version doesn't support) 875 <2> ; $ELSE ;;AN000;; Yes, 876 <2> JMP SHORT $MEN27 877 <2> $MIF27: 878 <2> MOV BX,STDERR ;;AN000;; Standard Error 879 <2> ; $ENDIF ;;AN000;; 880 <2> $MEN27: 881 <2> %ELSE 882 <2> MOV BX,NO_HANDLE ;;AN000;; No handle 883 <2> %ENDIF 884 <2> MOV AX,1 ;;AN000;; Set message # 1 885 <2> MOV CX,NO_REPLACE ;;AN000;; No replacable parms 886 <2> MOV DL,NO_INPUT ;;AN000;; No input 887 <2> MOV DH,UTILITY_MSG_CLASS ;;AN000;; Utility class message 888 <2> STC ;;AN000;; Set Carry Flag 889 <2> ; $ENDIF ;;AN000;; 890 <2> $MEN25: 891 <2> ;; 892 <2> RET ;;AN000;; Return 893 <2> ;; 894 <2> $M_VERSION_CHECK ENDP ;; 895 <2> ;; 896 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 897 <2> %ENDIF ;;AN000;; END of include for DOS version check 898 <2> %ENDIF ;;AN000;; END of include for SYSLOADMSG 899 <2> ; 900 <2> %IF GETmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 901 <2> %IF COMR ;;AN000;; 902 <2> $M_RT EQU $M_RT2 ;;AN000;; 903 <2> %ENDIF ;;AN000;; 904 <2> GETmsg equ FALSE ;;AN000;; Yes, THEN include it and reset flag 905 <2> ; PAGE 906 <2> ; SUBTTL DOS - Message Retriever - GETMSG.ASM Module 907 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 <2> ;; 909 <2> ;; Proc Name: SYSGETMSG 910 <2> ;; 911 <2> ;; Function: The GET service returns the segment, offset and size of the 912 <2> ;; message text to the caller based on a message number. 913 <2> ;; The GET function will not display the message thus assumes 914 <2> ;; caller will handle replaceable parameters. 915 <2> ;; 916 <2> ;; Inputs: 917 <2> ;; 918 <2> ;; Outputs: 919 <2> ;; 920 <2> ;; Psuedocode: 921 <2> ;; Call $M_GET_MSG_ADDRESS 922 <2> ;; IF MSG_NUM exists THEN 923 <2> ;; Set DS:SI = MSG_TXT_PTR + 1 924 <2> ;; CARRY_FLAG = 0 925 <2> ;; ELSE 926 <2> ;; CARRY_FLAG = 1 927 <2> ;; ENDIF 928 <2> ;; 929 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 930 <2> ;; 931 <2> %IF FARmsg ;;AN000;; 932 <2> SYSGETMSG PROC FAR ;;AN000;; 933 <2> %ELSE ;;AN000;; 934 <2> SYSGETMSG PROC NEAR ;;AN000;; 935 <2> %ENDIF ;;AN000;; 936 <2> ;; 937 <2> ;; Save registers needed later 938 <2> 939 <2> PUSH AX ;;AN000;; Save changed regs 940 <2> PUSH ES ;;AN000;; 941 <2> PUSH DI ;;AN000;; 942 <2> PUSH BP ;;AN000;; 943 <2> ;; 944 <2> %IF FARmsg ;;AN000;; 945 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 946 <2> %ELSE ;;AN000;; 947 <2> CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 948 <2> %ENDIF ;;AN000;; Return message in ES:DI 949 <2> ; $IF NC ;;AN000;; Message found? 950 <2> JC $MIF31 951 <2> CMP DH,UTILITY_MSG_CLASS 952 <2> CLC ;;AN000;; 953 <2> ; $IF NE 954 <2> JE $MIF32 955 <2> PUSH ES ;;AN000;; 956 <2> POP DS ;;AN000;; Return message in DS:SI 957 <2> ; $ELSE 958 <2> JMP SHORT $MEN32 959 <2> $MIF32: 960 <2> %IF FARmsg ;;AN000;; Yes, 961 <2> PUSH ES ;;AN000;; 962 <2> POP DS ;;AN000;; Return message in DS:SI 963 <2> %ELSE ;;AN000;; 964 <2> PUSH CS ;;AN000;; Return message in DS:SI 965 <2> POP DS ;;AN000;; 966 <2> %ENDIF ;;AN000;; 967 <2> ; $ENDIF ;;AN000;; 968 <2> $MEN32: 969 <2> MOV SI,DI ;;AN000;; Return message in DS:SI 970 <2> ; $ENDIF ;;AN000;; 971 <2> $MIF31: 972 <2> ;; 973 <2> POP BP ;;AN000;; Restore changed regs 974 <2> POP DI ;;AN000;; 975 <2> POP ES ;;AN000;; 976 <2> POP AX ;;AN000;; 977 <2> ;; 978 <2> RET ;;AN000;; Return 979 <2> ;; 980 <2> SYSGETMSG ENDP ;; 981 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 982 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 983 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 984 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 985 <2> ;; 986 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 987 <2> ;; 988 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 989 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 990 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 991 <2> ;; IF CX > 1 THEN ES:DI points to the specified message 992 <2> ;; REGS CHANGED: ES,DI,CX 993 <2> ;; 994 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 995 <2> ;; 996 <2> %IF FARmsg ;;AN000;; 997 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 998 <2> %ELSE ;;AN000;; 999 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 1000 <2> %ENDIF ;;AN000;; 1001 <2> ;; 1002 <2> PUSH SI ;;AN000;; 1003 <2> PUSH BX ;;AN000;; 1004 <2> XOR SI,SI ;;AN000;; Use SI as an index 1005 <2> XOR CX,CX ;;AN000;; Use CX as an size 1006 <2> ; $DO ;;AN000;; 1007 <2> $MDO36: 1008 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 1009 <2> ; $IF E ;;AN000;; Yes, 1010 <2> JNE $MIF37 1011 <2> %IF FARmsg ;;AN000;; 1012 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1013 <2> MOV BX,ES ;;AN000; 1014 <2> %ELSE ;;AN000;; 1015 <2> MOV DI,WORD PTR [$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 1016 <2> MOV BX,DI ;;AN000; 1017 <2> %ENDIF ;;AN000;; 1018 <2> ; $ELSE ;;AN000;; No, 1019 <2> JMP SHORT $MEN37 1020 <2> $MIF37: 1021 <2> TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 1022 <2> ; $IF NE ;;AN000;; Yes, 1023 <2> JE $MIF39 1024 <2> LES DI,[$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 1025 <2> MOV BX,ES ;;AN000; 1026 <2> ; $ELSE ;;AN000;; No, extended errors were specified 1027 <2> JMP SHORT $MEN39 1028 <2> $MIF39: 1029 <2> CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 1030 <2> ; $IF AE,AND ;;AN000;; 1031 <2> JNAE $MIF41 1032 <2> CMP AX,$M_CRIT_HI ;;AN000;; 1033 <2> ; $IF BE ;;AN000;; Yes, 1034 <2> JNBE $MIF41 1035 <2> LES DI,[$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 1036 <2> MOV BX,ES ;;AN000; 1037 <2> ; $ELSE ;;AN000;; 1038 <2> JMP SHORT $MEN41 1039 <2> $MIF41: 1040 <2> LES DI,[$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 1041 <2> MOV BX,ES ;;AN000; 1042 <2> ; $ENDIF ;;AN000;; 1043 <2> $MEN41: 1044 <2> ; $ENDIF ;;AN000;; 1045 <2> $MEN39: 1046 <2> ; $ENDIF ;;AN000;; 1047 <2> $MEN37: 1048 <2> ;; 1049 <2> CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 1050 <2> ; $IF E ;;AN000;; Yes, 1051 <2> JNE $MIF46 1052 <2> CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 1053 <2> ; $IF E ;;AN000;; Yes, 1054 <2> JNE $MIF47 1055 <2> STC ;;AN000;; Set the carry flag 1056 <2> ; $ELSE ;;AN000;; No, 1057 <2> JMP SHORT $MEN47 1058 <2> $MIF47: 1059 <2> MOV [$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 1060 <2> MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 1061 <2> MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 1062 <2> XOR SI,SI ;;AN000;; Reset the SI index to start again 1063 <2> CLC ;;AN000;; 1064 <2> ; $ENDIF ;;AN000;; No, 1065 <2> $MEN47: 1066 <2> ; $ELSE ;;AN000;; 1067 <2> JMP SHORT $MEN46 1068 <2> $MIF46: 1069 <2> CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 1070 <2> ; $IF NE ;;AN001;; Yes, 1071 <2> JE $MIF51 1072 <2> CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 1073 <2> ; $ENDIF ;;AN000;; 1074 <2> $MIF51: 1075 <2> ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 1076 <2> CLC ;;AN000;; 1077 <2> ; $ENDIF ;;AN000;; 1078 <2> $MEN46: 1079 <2> ; $LEAVE C ;;AN000;; 1080 <2> JC $MEN36 1081 <2> OR CX,CX ;;AN000;; Was the message found? 1082 <2> ; $ENDDO NZ,LONG ;;AN000;; 1083 <2> JNZ $MXL2 1084 <2> JMP $MDO36 1085 <2> $MXL2: 1086 <2> $MEN36: 1087 <2> 1088 <2> PUSHF ;;AN006;; Save the flag state 1089 <2> CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 1090 <2> ; $IF E ;;AN006;; Yes, 1091 <2> JNE $MIF56 1092 <2> PUSH DX ;;AN006;; Save all needed registers 1093 <2> PUSH BP ;;AN006;; 1094 <2> PUSH CX ;;AN006;; 1095 <2> PUSH ES ;;AN006;; 1096 <2> PUSH DI ;;AN006;; 1097 <2> PUSH AX ;;AN006;; 1098 <2> 1099 <2> MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 1100 <2> INT 2FH ;;AN006;; 1101 <2> CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 1102 <2> POP AX ;;AN006;; Restore msg number 1103 <2> ; $IF E ;;AN006;; Yes, 1104 <2> JNE $MIF57 1105 <2> MOV BX,AX ;;AN006;; BX is the extended error number 1106 <2> MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 1107 <2> INT 2FH ;;AN006;; Call IFSFUNC 1108 <2> ; $ELSE ;;AN006;; No, 1109 <2> JMP SHORT $MEN57 1110 <2> $MIF57: 1111 <2> STC ;;AN006;; Carry conditon 1112 <2> ; $ENDIF ;;AN006;; 1113 <2> $MEN57: 1114 <2> 1115 <2> ; $IF C ;;AN006;; Was there an update? 1116 <2> JNC $MIF60 1117 <2> POP DI ;;AN006;; No, 1118 <2> POP ES ;;AN006;; Restore old pointer 1119 <2> POP CX ;;AN006;; 1120 <2> ; $ELSE ;;AN006;; Yes 1121 <2> JMP SHORT $MEN60 1122 <2> $MIF60: 1123 <2> ADD SP,6 ;;AN006;; Throw away old pointer 1124 <2> CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 1125 <2> ; $ENDIF ;;AN006;; 1126 <2> $MEN60: 1127 <2> POP BP ;;AN006;; Restore other Regs 1128 <2> POP DX ;;AN006;; 1129 <2> ; $ENDIF ;;AN006;; 1130 <2> $MIF56: 1131 <2> $M_POPF ;;AN006;; Restore the flag state 1132 <2> 1133 <2> POP BX ;;AN000;; 1134 <2> POP SI ;;AN000;; 1135 <2> RET ;;AN000;; Return ES:DI pointing to the message 1136 <2> ;; 1137 <2> $M_GET_MSG_ADDRESS ENDP ;; 1138 <2> ;; 1139 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 1140 <2> ;; 1141 <2> PUSH DI ;;AN006;; Save position 1142 <2> PUSH AX ;;AN006;; 1143 <2> MOV CX,-1 ;;AN006;; Set CX for decrements 1144 <2> XOR AL,AL ;;AN006;; Prepare compare register 1145 <2> REPNE SCASB ;;AN006;; Scan for zero 1146 <2> NOT CX ;;AN006;; Change decrement into number 1147 <2> DEC CX ;;AN006;; Don't include the zero 1148 <2> POP AX ;;AN006;; 1149 <2> POP DI ;;AN006;; Restore position 1150 <2> RET ;;AN006;; 1151 <2> ;; 1152 <2> $M_SET_LEN_IN_CX ENDP ;; 1153 <2> ;; 1154 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1155 <2> ;; 1156 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 1157 <2> ;; 1158 <2> ;; FUNCTION: To scan thru message headers until message is found 1159 <2> ;; INPUTS: ES:DI points to beginning of msg headers 1160 <2> ;; CX contains the number of messages in class 1161 <2> ;; DH contains the message class 1162 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 1163 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 1164 <2> ;; 1165 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1166 <2> ;; 1167 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 1168 <2> ;; 1169 <2> CMP BX,1 ;;AN004;; Do we have an address to CALL? 1170 <2> ; $IF E,AND ;;AN004;; Yes, 1171 <2> JNE $MIF64 1172 <2> CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 1173 <2> ; $IF NE ;;AN004;; Yes, 1174 <2> JE $MIF64 1175 <2> CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 1176 <2> ; $IF E ;;AN004;; . . . and . . . 1177 <2> JNE $MIF65 1178 <2> PUSH AX ;;AN004;; Reset the special message number 1179 <2> MOV AX,[$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 1180 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1181 <2> POP AX ;;AN004;; Reset the special message number 1182 <2> ; $ELSE ;;AN004;; Get the old message number 1183 <2> JMP SHORT $MEN65 1184 <2> $MIF65: 1185 <2> CALL far [$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 1186 <2> ; $ENDIF ;;AN004;; Get the old message number 1187 <2> $MEN65: 1188 <2> ; $ELSE ;;AN004;; 1189 <2> JMP SHORT $MEN64 1190 <2> $MIF64: 1191 <2> XOR CX,CX ;;AN002;; CX = 0 will allow us to 1192 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1193 <2> ; $IF NE ;;AN001;; 1194 <2> JE $MIF69 1195 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 1196 <2> ; $ELSE ;;AN001;; 1197 <2> JMP SHORT $MEN69 1198 <2> $MIF69: 1199 <2> %IF FARmsg ;;AN001;; 1200 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1201 <2> %ELSE 1202 <2> CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 1203 <2> %ENDIF 1204 <2> ; $IF E ;;AN002;; pointer (hopefully) 1205 <2> JNE $MIF71 1206 <2> %IF FARmsg ;;AN001;; 1207 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1208 <2> %ELSE 1209 <2> MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 1210 <2> %ENDIF 1211 <2> ; $ENDIF ;;AN002;; go on to the next class 1212 <2> $MIF71: 1213 <2> ; $ENDIF ;;AN001;; 1214 <2> $MEN69: 1215 <2> ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 1216 <2> STC ;;AN004;; Flag that we haven't found anything yet 1217 <2> ; $ENDIF ;;AN004;; 1218 <2> $MEN64: 1219 <2> 1220 <2> ; $IF C ;;AN004;; Have we found anything yet? 1221 <2> JNC $MIF75 1222 <2> CLC ;;AN004;; No, reset carry 1223 <2> ; $SEARCH ;;AN000;; 1224 <2> $MDO76: 1225 <2> OR CX,CX ;;AN000;; Do we have any to check? 1226 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1227 <2> JZ $MEN76 1228 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; 1229 <2> ; $IF NE ;;AN001;; 1230 <2> JE $MIF78 1231 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 1232 <2> ; $ELSE ;;AN001;; 1233 <2> JMP SHORT $MEN78 1234 <2> $MIF78: 1235 <2> %IF FARmsg ;;AN001;; 1236 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 1237 <2> %ELSE 1238 <2> CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 1239 <2> %ENDIF 1240 <2> ; $ENDIF 1241 <2> $MEN78: 1242 <2> ; $EXITIF E ;;AN000;; 1243 <2> JNE $MIF76 1244 <2> ; $ORELSE ;;AN000; 1245 <2> JMP SHORT $MSR76 1246 <2> $MIF76: 1247 <2> DEC CX ;;AN000;; No, well do we have more to check? 1248 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 1249 <2> JZ $MEN76 1250 <2> ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 1251 <2> ; $ENDLOOP ;;AN000;; 1252 <2> JMP SHORT $MDO76 1253 <2> $MEN76: 1254 <2> STC ;;AN000;; 1255 <2> ; $ENDSRCH ;;AN000;; Check next message 1256 <2> $MSR76: 1257 <2> ; $IF NC ;;AN000;; Did we find the message? 1258 <2> JC $MIF86 1259 <2> CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 1260 <2> CLC ;;AN001;; 1261 <2> ; $IF E ;;AN001;; 1262 <2> JNE $MIF87 1263 <2> %IF FARmsg ;;AN001;; 1264 <2> %ELSE ;;AN000;; 1265 <2> PUSH CS ;;AN000;; 1266 <2> POP ES ;;AN000;; Return ES:DI pointing to the message 1267 <2> %ENDIF 1268 <2> ; $ENDIF ;;AN001;; 1269 <2> $MIF87: 1270 <2> ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 1271 <2> ; $ENDIF ;;AN004;; 1272 <2> $MIF86: 1273 <2> ; $ENDIF ;;AN004;; 1274 <2> $MIF75: 1275 <2> ;; Yes, great we can return with CX > 0 1276 <2> 1277 <2> ; $IF NC ;;AN000;; Did we find the message? 1278 <2> JC $MIF91 1279 <2> XOR CH,CH ;;AN000;; 1280 <2> MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 1281 <2> INC DI ;;AN000;; Increment past length 1282 <2> ; $ENDIF ;;AN004;; 1283 <2> $MIF91: 1284 <2> 1285 <2> MOV byte [$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 1286 <2> RET ;;AN000;; Return 1287 <2> ;; 1288 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 1289 <2> ;; 1290 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1291 <2> %ENDIF ;;AN000;; END of include of common subroutines 1292 <2> %ENDIF ;;AN000;; END of include of SYSGETMSG 1293 <2> ; 1294 <2> %IF DISPLAYmsg ;;AN000;; Is the request to include the code for SYSGETMSG ? 1295 <2> %IF COMR ;;AN000;; 1296 <2> $M_RT EQU $M_RT2 ;;AN000;; 1297 <2> %ENDIF ;;AN000;; 1298 <2> %iassign DISPLAYmsg FALSE ;;AN000;; Yes, THEN include it and reset flag 1299 <2> ; PAGE 1300 <2> ; SUBTTL DOS - Message Retriever - DISPMSG.ASM Module 1301 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1302 <2> ;; 1303 <2> ;; Proc Name: SYSDISPMSG 1304 <2> ;; 1305 <2> ;; Function: The DISPLAY service will output a defined message to a handle 1306 <2> ;; requested by the caller. It also provides function to display 1307 <2> ;; messages when handles are not applicable (ie. DOS function calls 1308 <2> ;; 00h to 0Ah) Replaceable parameters are allowed and are 1309 <2> ;; defined previous to entry. 1310 <2> ;; 1311 <2> ;; It is assumes that a PRELOAD function has already determined 1312 <2> ;; the addressibilty internally to the message retriever services. 1313 <2> ;; Inputs: 1314 <2> ;; 1315 <2> ;; Outputs: 1316 <2> ;; 1317 <2> ;; Psuedocode: 1318 <2> ;; Save registers needed later 1319 <2> ;; Get address of the message requested 1320 <2> ;; IF Message number exists THEN 1321 <2> ;; IF replacable parameters were specified THEN 1322 <2> ;; Display message with replacable parms 1323 <2> ;; ELSE 1324 <2> ;; Display string without replacable parms 1325 <2> ;; ENDIF 1326 <2> ;; IF character input was requested THEN 1327 <2> ;; Wait for character input 1328 <2> ;; ENDIF 1329 <2> ;; Clear CARRY FLAG 1330 <2> ;; ELSE 1331 <2> ;; Set CARRY FLAG 1332 <2> ;; ENDIF 1333 <2> ;; Return 1334 <2> ;; 1335 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1336 <2> ;; 1337 <2> %IF FARmsg ;;AN000;; 1338 <2> SYSDISPMSG PROC FAR ;;AN000;; 1339 <2> %ELSE ;;AN000;; 1340 <2> SYSDISPMSG PROC NEAR ;;AN000;; 1341 <2> %ENDIF ;;AN000;; 1342 <2> ;; 1343 <2> ;; Save registers and values needed later 1344 <2> 0 0000103F 50 PUSH AX ;;AN000;; Save changed REGs 0 00001040 53 PUSH BX ;;AN000;; 0 00001041 51 PUSH CX ;;AN000;; 0 00001042 55 PUSH BP ;;AN000;; 0 00001043 57 PUSH DI ;;AN000;; Save pointer to input buffer (offset) 0 00001044 06 PUSH ES ;;AN000;; Save pointer to input buffer (segment) 0 00001045 52 PUSH DX ;;AN000;; Save Input/Class request 1352 <2> 0 00001046 89CD MOV BP,CX ;;AN000;; Use BP to hold replace count 0 00001048 2E891E[3800] MOV WORD PTR [cs:$M_RT + $M_HANDLE],BX ;;AN000;; Save handle 0 0000104D 2E8836[3D00] MOV BYTE PTR [cs:$M_RT + $M_CLASS],DH ;;AN004;; Save class 1356 <2> 1357 <2> ;; Get address of the message requested 1358 <2> 1359 <2> %IF FARmsg ;;AN000;; 1360 <2> CALL FAR PTR $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1361 <2> %ELSE ;;AN000;; 0 00001052 E89502 CALL $M_GET_MSG_ADDRESS ;;AN000;; Scan thru classes to find message 1363 <2> %ENDIF ;;AN000;; 0 00001055 09C9 OR CX,CX ;;AN000;; Was message found? 1365 <2> ; $IF NZ ;;AN000;; YES, Message address in ES:DI 0 00001057 741C JZ $MIF93 1367 <2> 1368 <2> ;; Test if replacable parameters were specified 1369 <2> 0 00001059 09ED OR BP,BP ;;AN000;; Were replacable parameters requested 1371 <2> ; $IF Z ;;AN000;; 0 0000105B 7505 JNZ $MIF94 1373 <2> 1374 <2> ;; Display string without replacable parms 1375 <2> 0 0000105D E82600 CALL $M_DISPLAY_STRING ;;AN000;; No, great . . . Display message 1377 <2> ; $ELSE ;;AN000;; 0 00001060 EB03 JMP SHORT $MEN94 1379 <2> $MIF94: 1380 <2> %IF $M_REPLACE ;;AN000;; 1381 <2> 1382 <2> ;; Display message with replacable parms 1383 <2> 0 00001062 E87601 CALL $M_DISPLAY_MESSAGE ;;AN000;; Display the message with substitutions 1385 <2> %ENDIF ;;AN000;; 1386 <2> ; $ENDIF ;;AN000;; 1387 <2> $MEN94: 1388 <2> ; $IF NC 0 00001065 7208 JC $MIF97 1390 <2> 0 00001067 5A POP DX ;;AN000;; Get Input/Class request 1392 <2> 0 00001068 E8C300 CALL $M_ADD_CRLF ;;AN004;; Check if we need to add the CR LF chars. 1394 <2> 0 0000106B 07 POP ES ;;AN000;; Get location of input buffer (if specified) 0 0000106C 5F POP DI ;;AN000;; 1397 <2> 1398 <2> ;; Test if character input was requested 1399 <2> 1400 <2> %IF INPUTmsg ;;AN000;; 1401 <2> OR DL,DL ;;AN000;; Was Wait-For-Input requested? 1402 <2> ; $IF NZ ;;AN000;; 1403 <2> JZ $MIF98 1404 <2> CALL $M_WAIT_FOR_INPUT ;;AN000;; 1405 <2> ; $ENDIF ;;AN000;; 1406 <2> $MIF98: 1407 <2> %ENDIF ;;AN000;; 1408 <2> ; $ELSE ;;AN000;; 0 0000106D EB04 JMP SHORT $MEN97 1410 <2> $MIF97: 0 0000106F 83C406 ADD SP,6 ;;AN000;; 0 00001072 F9 STC ;;AN000;; Reset carry flag 1413 <2> ; $ENDIF ;;AN000;; 1414 <2> $MEN97: 1415 <2> ; $ELSE ;;AN000;; No, 0 00001073 EB04 JMP SHORT $MEN93 1417 <2> $MIF93: 0 00001075 07 POP ES ;;AN000;; Get pointer to input buffer (segment) 0 00001076 5F POP DI ;;AN000;; Get base pointer to first sublist (offset) 0 00001077 5A POP DX ;;AN000;; Get base pointer to first sublist (segment) 0 00001078 F9 STC ;;AN000;; Set carry flag 1422 <2> ; $ENDIF ;;AN000;; 1423 <2> $MEN93: 1424 <2> ;; 1425 <2> ; $IF NC ;;AN000;; Was there an error? 0 00001079 7206 JC $MIF104 0 0000107B 5D POP BP ;;AN000;; No, 0 0000107C 59 POP CX ;;AN000;; 0 0000107D 5B POP BX ;;AN000;; 1430 <2> %IF INPUTmsg ;;AN000;; 1431 <2> ADD SP,2 ;;AN000;; 1432 <2> %ELSE ;AN000; 0 0000107E 58 POP AX ;;AN000;; 1434 <2> %ENDIF ;;AN000;; 1435 <2> ; $ELSE ;;AN000;; Yes, 0 0000107F EB04 JMP SHORT $MEN104 1437 <2> $MIF104: 0 00001081 83C408 ADD SP,8 ;;AN000;; Eliminate from stack 0 00001084 F9 STC ;;AN000;; 1440 <2> ; $ENDIF ;;AN000;; 1441 <2> $MEN104: 1442 <2> ;; 0 00001085 C3 RET ;;AN000;; Return 1444 <2> ;; 1445 <2> SYSDISPMSG ENDP ;;AN000;; 1446 <2> ;; 1447 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1448 <2> ; 1449 <2> ;; 1450 <2> ;; PROC NAME: $M_DISPLAY_STRING 1451 <2> ;; 1452 <2> ;; FUNCTION: Will display or write string 1453 <2> ;; INPUTS: ES:DI points to beginning of message 1454 <2> ;; CX contains the length of string to write (if applicable) 1455 <2> ;; OUTPUTS: None 1456 <2> ;; REGS Revised: None 1457 <2> ;; 1458 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1459 <2> ;; 1460 <2> $M_DISPLAY_STRING PROC NEAR ;;AN000;; 1461 <2> ;; 0 00001086 50 PUSH AX ;;AN000;; 0 00001087 53 PUSH BX ;;AN000;; 0 00001088 52 PUSH DX ;;AN000;; 1465 <2> ;; 0 00001089 2E8B1E[3800] MOV BX,[cs:$M_RT + $M_HANDLE] ;;AN000;; Retrieve handle 1467 <2> ;; 1468 <2> %IF COMR ;; ** Special case for RESIDENT COMMAND.COM 1469 <2> CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1470 <2> %ELSE 0 0000108E 83FBFF CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1472 <2> ; $IF E ;;AN000;; 0 00001091 7505 JNE $MIF107 0 00001093 E82C00 CALL $M_DISPLAY_$_STRING ;;AN000;; No, display $ terminated string 1475 <2> ; $ELSE ;;AN000;; 0 00001096 EB03 JMP SHORT $MEN107 1477 <2> $MIF107: 0 00001098 E85C00 CALL $M_DISPLAY_H_STRING ;;AN000;; Yes, display string to handle 1479 <2> ; $ENDIF ;;AN000;; 1480 <2> $MEN107: 1481 <2> ;AN001; 1482 <2> ; $IF C ;;AN000;; Was there an error? 0 0000109B 730F JNC $MIF110 0 0000109D B459 MOV AH,DOS_GET_EXT_ERROR ;;AN000;; Yes, 0 0000109F BB0000 MOV BX,DOS_GET_EXT_ERROR_BX ;;AN000;; Get extended error 0 000010A2 CD21 INT 21H ;;AN000;; 0 000010A4 30E4 XOR AH,AH ;;AN000;; Clear AH 0 000010A6 83C406 ADD SP,6 ;;AN000;; Clean up stack 0 000010A9 F9 STC ;;AN000;; Flag that there was an error 1490 <2> ; $ELSE ;;AN000;; No, 0 000010AA EB10 JMP SHORT $MEN110 1492 <2> $MIF110: 0 000010AC 83FBFF CMP BX,$M_NO_HANDLE ;;AN000;; Was there a handle specified? 1494 <2> ; $IF NE ;;AN000;; 0 000010AF 740B JE $MIF112 0 000010B1 39C8 CMP AX,CX ;AN001; Was it ALL written? 1497 <2> ; $IF NE ;AN001; No, 0 000010B3 7407 JE $MIF113 0 000010B5 E86D00 CALL $M_GET_EXT_ERR_39 ;AN001; Set Extended error 0 000010B8 83C406 ADD SP,6 ;AN001; Clean up stack 0 000010BB F9 STC ;AN001; Flag that there was an error 1502 <2> ; $ENDIF ;AN001; 1503 <2> $MIF113: 1504 <2> ; $ENDIF ;AN001; 1505 <2> $MIF112: 1506 <2> ; $ENDIF ;;AN000;; 1507 <2> $MEN110: 1508 <2> %ENDIF 1509 <2> ; $IF NC ;;AN000;; Was there ANY error? 0 000010BC 7203 JC $MIF117 0 000010BE 5A POP DX ;;AN000;; Restore regs 0 000010BF 5B POP BX ;;AN000;; 0 000010C0 58 POP AX ;;AN000;; 1514 <2> ; $ENDIF ;;AN000;; 1515 <2> $MIF117: 0 000010C1 C3 RET ;;AN000;; Return 1517 <2> ;; 1518 <2> $M_DISPLAY_STRING ENDP ;;AN000;; 1519 <2> ;; 1520 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1521 <2> ;; 1522 <2> ;; PROC NAME: $M_DISPLAY_$_STRING 1523 <2> ;; 1524 <2> ;; FUNCTION: Will display a $ terminated string 1525 <2> ;; INPUTS: ES:DI points to beginning of message text (not the length) 1526 <2> ;; OUPUTS: None 1527 <2> ;; REGS USED: AX,DX 1528 <2> ;; 1529 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1530 <2> ;; 1531 <2> $M_DISPLAY_$_STRING PROC NEAR ;;AN000;; 1532 <2> ;; 0 000010C2 1E PUSH DS ;;AN000;; 0 000010C3 06 PUSH ES ;;AN000;; 0 000010C4 1F POP DS ;;AN000;; Set DS to segment of message text 1536 <2> %IFN COMR 0 000010C5 83F901 CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1538 <2> ; $IF E ;;AN000;; Yes, 0 000010C8 751B JNE $MIF119 0 000010CA B402 MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 0 000010CC 268A15 MOV DL,BYTE PTR [ES:DI] ;;AN000;; Get the character 0 000010CF CD21 INT 21H ;;AN000;; Write character 0 000010D1 1F POP DS ;;AN000;; Set DS to segment of message text 0 000010D2 88D0 MOV AL,DL ;;AN000;; Get the character in AL 0 000010D4 E86E00 CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 0 000010D7 1E PUSH DS ;;AN000;; 0 000010D8 06 PUSH ES ;;AN000;; 0 000010D9 1F POP DS ;;AN000;; Set DS to segment of message text 1549 <2> ; $IF C ;;AN000;; Yes, 0 000010DA 7307 JNC $MIF120 0 000010DC 268A5501 MOV DL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 0 000010E0 CD21 INT 21H ;;AN000;; Write character 0 000010E2 F8 CLC ;;AN000;; Clear the DBCS indicator 1554 <2> ; $ENDIF ;;AN000;; 1555 <2> $MIF120: 1556 <2> ; $ELSE ;;AN000;; No, 0 000010E3 EB0F JMP SHORT $MEN119 1558 <2> $MIF119: 1559 <2> %ENDIF 0 000010E5 B402 MOV AH,DOS_DISP_CHAR ;;AN000;; DOS Function to display CHARACTER 1561 <2> ; $DO ;;AN002;; No, 1562 <2> $MDO123: 0 000010E7 09C9 OR CX,CX ;;AN002;; Are there any left to display? 1564 <2> ; $LEAVE Z ;;AN002;; Yes, 0 000010E9 7409 JZ $MEN123 0 000010EB 268A15 MOV DL,BYTE PTR [ES:DI] ;;AN002;; Get the character 0 000010EE CD21 INT 21H ;;AN002;; Display the character 0 000010F0 47 INC DI ;;AN002;; Set pointer to next character 0 000010F1 49 DEC CX ;;AN002;; Count this character 1570 <2> ; $ENDDO Z ;;AN002;; No, 0 000010F2 75F3 JNZ $MDO123 1572 <2> $MEN123: 1573 <2> %IFN COMR 1574 <2> ; $ENDIF ;;AN000;; 1575 <2> $MEN119: 1576 <2> %ENDIF 0 000010F4 F8 CLC ;;AN000;; Char functions used don't return carry as error 0 000010F5 1F POP DS ;;AN000;; 0 000010F6 C3 RET ;;AN000;; 1580 <2> ;; 1581 <2> $M_DISPLAY_$_STRING ENDP ;;AN000;; 1582 <2> ;; 1583 <2> %IFN COMR 1584 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1585 <2> ;; 1586 <2> ;; PROC NAME: $M_DISPLAY_H_STRING 1587 <2> ;; 1588 <2> ;; FUNCTION: Will display a string to a specified handle 1589 <2> ;; INPUTS: ES:DI points to beginning of message 1590 <2> ;; CX contains the number of bytes to write 1591 <2> ;; BX contains the handle to write to 1592 <2> ;; OUPUTS: None 1593 <2> ;; REGS USED: AX,DX 1594 <2> ;; 1595 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1596 <2> ;; 1597 <2> $M_DISPLAY_H_STRING PROC NEAR ;;AN000;; 1598 <2> ;; 0 000010F7 31C0 XOR AX,AX ;;AN002;; Set number of bytes written to 0 0 000010F9 09C9 OR CX,CX ;;AN002;; For performance, don't write if not necessary 1601 <2> ; $IF NZ ;;AN002;; Any chars to write? 0 000010FB 7427 JZ $MIF127 0 000010FD 1E PUSH DS ;;AN000;; Yes, 0 000010FE 06 PUSH ES ;;AN000;; 0 000010FF 1F POP DS ;;AN000;; Set DS to segment of message text 0 00001100 B440 MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 0 00001102 89FA MOV DX,DI ;;AN000;; Pointer to data to write 0 00001104 83F901 CMP CX,$M_SINGLE_CHAR ;;AN000;; Is this a single character? 1609 <2> ; $IF E ;;AN000;; Yes, 0 00001107 7518 JNE $MIF128 0 00001109 CD21 INT 21H ;;AN000;; Write character 0 0000110B 1F POP DS ;;AN000;; Set DS to segment of message text 0 0000110C 50 PUSH AX ;;AN000;; 0 0000110D 268A05 MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 0 00001110 E83200 CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 0 00001113 58 POP AX ;;AN000;; Set DS to segment of message text 0 00001114 1E PUSH DS ;;AN000;; 0 00001115 06 PUSH ES ;;AN000;; 0 00001116 1F POP DS ;;AN000;; Set DS to segment of message text 1620 <2> ; $IF C ;;AN000;; Yes, 0 00001117 7306 JNC $MIF129 0 00001119 F8 CLC ;;AN000;; Clear the DBCS indicator 0 0000111A B440 MOV AH,DOS_WRITE_HANDLE ;;AN000;; DOS function to write to a handle 0 0000111C 42 INC DX ;;AN000;; Point to next character 0 0000111D CD21 INT 21H ;;AN000;; Write character 1626 <2> ; $ENDIF ;;AN000;; 1627 <2> $MIF129: 1628 <2> ; $ELSE ;;AN000;; No, 0 0000111F EB02 JMP SHORT $MEN128 1630 <2> $MIF128: 0 00001121 CD21 INT 21H ;;AN000;; Write String at DS:SI to handle 1632 <2> ; $ENDIF ;;AN000;; 1633 <2> $MEN128: 0 00001123 1F POP DS ;;AN000;; 1635 <2> ; $ENDIF ;;AN002;; 1636 <2> $MIF127: 1637 <2> ;; 0 00001124 C3 RET ;;AN000;; 1639 <2> ;; 1640 <2> $M_DISPLAY_H_STRING ENDP ;;AN000;; 1641 <2> ;; 1642 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1643 <2> ;; 1644 <2> ;; PROC NAME: $M_GET_EXT_ERR_39 1645 <2> ;; 1646 <2> ;; FUNCTION: Will set registers for extended error #39 1647 <2> ;; INPUTS: None 1648 <2> ;; OUPUTS: AX,BX,CX set 1649 <2> ;; REGS USED: 1650 <2> ;; 1651 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1652 <2> ;; 1653 <2> $M_GET_EXT_ERR_39 PROC NEAR ;AN001; 1654 <2> ;; 0 00001125 B82700 MOV AX,EXT_ERR_39 ;AN001; Set AX=39 0 00001128 BB0400 MOV BX,(ERROR_CLASS_39 >> 8) + ACTION_39 ;AN001; Set BH=1 BL=4 0 0000112B B501 MOV CH,LOCUS_39 ;AN001; Set CH=1 1658 <2> ;AN001; 0 0000112D C3 RET ;AN001; 1660 <2> ;; 1661 <2> $M_GET_EXT_ERR_39 ENDP ;AN001; 1662 <2> ;; 1663 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1664 <2> %ENDIF 1665 <2> ;; 1666 <2> ;; PROC NAME: $M_ADD_CRLF 1667 <2> ;; 1668 <2> ;; FUNCTION: Will decide whether to display a CRLF 1669 <2> ;; INPUTS: DX contains the Input/Class requested 1670 <2> ;; OUTPUTS: None 1671 <2> ;; REGS Revised: CX,ES,DI 1672 <2> ;; 1673 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1674 <2> ;; 1675 <2> $M_ADD_CRLF PROC NEAR ;;AN004;; 1676 <2> ;; 0 0000112E 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1678 <2> ; $IF NE ;;AN004;; No, 0 00001131 7411 JE $MIF134 0 00001133 F6C680 TEST DH,$M_NO_CRLF_MASK ;;AN004;; Are we to supress the CR LF? 1681 <2> ; $IF Z ;;AN004;; No, 0 00001136 750C JNZ $MIF135 0 00001138 1E PUSH DS ;;AN004;; 0 00001139 07 POP ES ;;AN004;; Set ES to data segment 0 0000113A 8D3E[3B00] LEA DI,[$M_RT + $M_CRLF] ;;AN004;; Point at CRLF message 0 0000113E B90200 MOV CX,$M_CRLF_SIZE ;;AN004;; Set the message size 0 00001141 E842FF CALL $M_DISPLAY_STRING ;;AN004;; Display the CRLF 1688 <2> ; $ENDIF ;;AN004;; 1689 <2> $MIF135: 1690 <2> ; $ENDIF ;;AN004;; 1691 <2> $MIF134: 0 00001144 C3 RET ;;AN004;; Return 1693 <2> ;; 1694 <2> $M_ADD_CRLF ENDP ;;AN004;; 1695 <2> ;; 1696 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1697 <2> ;; 1698 <2> ;; PROC NAME: $M_IS_IT_DBCS 1699 <2> ;; 1700 <2> ;; FUNCTION: Will decide whether character is Single or Double Byte 1701 <2> ;; INPUTS: AL contains the byte to be checked 1702 <2> ;; OUPUTS: Carry flag = 0 if byte is NOT in DBCS range 1703 <2> ;; Carry flag = 1 if byte IS in DBCS range 1704 <2> ;; REGS USED: All restored 1705 <2> ;; 1706 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1707 <2> ;; 1708 <2> $M_IS_IT_DBCS PROC NEAR ;;AN000;; 1709 <2> ;; 0 00001145 06 PUSH ES ;;AN000;; Save Extra segment register 0 00001146 57 PUSH DI ;;AN000;; Save SI register 1712 <2> ;; 0 00001147 2EC43E[3400] LES DI,[cs:$M_RT + $M_DBCS_VEC] ;;AN000;; 0 0000114C 09FF OR DI,DI ;;AN000;; Was the DBCS vector set? 1715 <2> ; $IF NZ ;;AN000;; 0 0000114E 7417 JZ $MIF138 1717 <2> ; $DO ;;AN000;; 1718 <2> $MDO139: 0 00001150 26833D00 CMP WORD PTR [ES:DI],$M_DBCS_TERM ;;AN000;; Is this the terminating flag? 0 00001154 F8 CLC ;;AN000;; 1721 <2> ; $LEAVE E ;;AN000;; 0 00001155 7410 JE $MEN139 1723 <2> ;; No, 0 00001157 263A05 CMP AL,BYTE PTR [ES:DI] ;;AN000;; Does the character fall in the DBCS range? 1725 <2> ; $IF AE,AND ;;AN000;; 0 0000115A 7207 JNAE $MIF141 0 0000115C 263A4501 CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Does the character fall in the DBCS range? 1728 <2> ; $IF BE ;;AN000;; 0 00001160 7701 JNBE $MIF141 0 00001162 F9 STC ;;AN000;; Yes, 1731 <2> ; $ENDIF ;;AN000;; Set carry flag 1732 <2> $MIF141: 0 00001163 47 INC DI ;;AN000;; No, 0 00001164 47 INC DI ;;AN000;; Go to next vector 1735 <2> ; $ENDDO ;;AN000;; 0 00001165 EBE9 JMP SHORT $MDO139 1737 <2> $MEN139: 1738 <2> ; $ENDIF ;;AN000;; 1739 <2> $MIF138: 1740 <2> 0 00001167 5F POP DI ;;AN000;; 0 00001168 07 POP ES ;;AN000;; Restore SI register 0 00001169 C3 RET ;;AN000;; Return 1744 <2> ;; 1745 <2> $M_IS_IT_DBCS ENDP ;;AN000;; 1746 <2> ;; 1747 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1748 <2> ;; 1749 <2> ;; PROC NAME: $M_CONVERT2ASC 1750 <2> ;; 1751 <2> ;; FUNCTION: Convert a binary number to a ASCII string 1752 <2> ;; INPUTS: DX:AX contains the number to be converted 1753 <2> ;; $M_RT_DIVISOR contains the divisor 1754 <2> ;; OUPUTS: CX contains the number of characters 1755 <2> ;; Top of stack --> Last character 1756 <2> ;; . . . 1757 <2> ;; Bot of stack --> First character 1758 <2> ;; REGS USED: 1759 <2> ;; 1760 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1761 <2> ;; 1762 <2> $M_CONVERT2ASC PROC NEAR ;;AN000;; 1763 <2> ;; 0 0000116A 2E8F06[3E00] POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Save Return Address 0 0000116F 31DB XOR BX,BX ;;AN000;; Use BP as a swapping register 1766 <2> ;; 0 00001171 93 XCHG BX,AX ;;AN000;; Initialize - Low Word in BP 0 00001172 92 XCHG AX,DX ;;AN000;; - High Word in AX 1769 <2> ; $DO ;;AN000;; DO UNTIL Low Word becomes zero 1770 <2> $MDO145: 0 00001173 2EF736[4200] DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide High Word by divisor 0 00001178 93 XCHG BX,AX ;;AN000;; Setup to divide Low Word using remainder 1773 <2> ;; and save reduced High Word in BP 0 00001179 2EF736[4200] DIV word [cs:$M_RT + $M_DIVISOR] ;;AN000;; Divide Low Word by divisor 0 0000117E 83FA09 CMP DX,9 ;;AN000;; Make a digit of the remainder 1776 <2> ; $IF A ;;AN000;; IF 10 to 15, 0 00001181 7605 JNA $MIF146 0 00001183 80C237 ADD DL,55 ;;AN000;; Make A to F ASCII 1779 <2> ; $ELSE ;;AN000;; IF 0 to 9, 0 00001186 EB03 JMP SHORT $MEN146 1781 <2> $MIF146: 0 00001188 80C230 ADD DL,'0' ;;AN000;; Make 0 to 9 ASCII 1783 <2> ; $ENDIF ;;AN000;; 1784 <2> $MEN146: 0 0000118B 52 PUSH DX ;;AN000;; Save the digit on the stack 0 0000118C 41 INC CX ;;AN000;; Count that digit 0 0000118D 09C0 OR AX,AX ;;AN000;; Are we done? 1788 <2> ; $LEAVE Z,AND ;;AN000;; 0 0000118F 7504 JNZ $MLL149 0 00001191 09DB OR BX,BX ;;AN000;; AX and BX must be ZERO!! 1791 <2> ; $LEAVE Z ;;AN000;; No, 0 00001193 743C JZ $MEN145 1793 <2> $MLL149: 1794 <2> %IFN COMR 0 00001195 83F903 CMP CX,$M_FIRST_THOU ;;AN000;; Are we at the first thousands mark 1796 <2> ; $IF E ;;AN000;; Yes, 0 00001198 750E JNE $MIF150 0 0000119A 807C0A2C CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1799 <2> ; $IF E ;;AN000;; Yes, 0 0000119E 7506 JNE $MIF151 0 000011A0 2EFF36[4B00] PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 0 000011A5 41 INC CX ;;AN000;; 1803 <2> ; $ENDIF ;;AN000;; 1804 <2> $MIF151: 1805 <2> ; $ELSE ;;AN000;; No, 0 000011A6 EB24 JMP SHORT $MEN150 1807 <2> $MIF150: 0 000011A8 83F906 CMP CX,$M_SECOND_THOU ;;AN000;; Are we at the first thousands mark 1809 <2> ; $IF E ;;AN000;; Yes, 0 000011AB 750E JNE $MIF154 0 000011AD 807C0A2C CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1812 <2> ; $IF E ;;AN000;; Yes, 0 000011B1 7506 JNE $MIF155 0 000011B3 2EFF36[4B00] PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 0 000011B8 41 INC CX ;;AN000;; 1816 <2> ; $ENDIF ;;AN000;; 1817 <2> $MIF155: 1818 <2> ; $ELSE ;;AN000;; No, 0 000011B9 EB11 JMP SHORT $MEN154 1820 <2> $MIF154: 0 000011BB 83F909 CMP CX,$M_THIRD_THOU ;;AN000;; Are we at the first thousands mark 1822 <2> ; $IF E ;;AN000;; Yes, 0 000011BE 750C JNE $MIF158 0 000011C0 807C0A2C CMP byte [$M_SL + $M_S_PAD],$M_COMMA ;;AN000;; Is the pad character a comma? 1825 <2> ; $IF E ;;AN000;; Yes, 0 000011C4 7506 JNE $MIF159 0 000011C6 2EFF36[4B00] PUSH WORD [cs:$M_RT + $M_THOU_SEPARA] ;;AN000;; Insert a thousand separator 0 000011CB 41 INC CX ;;AN000;; 1829 <2> ; $ENDIF ;;AN000;; 1830 <2> $MIF159: 1831 <2> ; $ENDIF ;;AN000;; 1832 <2> $MIF158: 1833 <2> ; $ENDIF ;;AN000;; 1834 <2> $MEN154: 1835 <2> ; $ENDIF ;;AN000;; 1836 <2> $MEN150: 1837 <2> %ENDIF 0 000011CC 93 XCHG AX,BX ;;AN000;; Setup to divide the reduced High Word 1839 <2> ;;AN000;; and Revised Low Word 0 000011CD 31D2 XOR DX,DX ;;AN000;; Reset remainder 1841 <2> ; $ENDDO ;;AN000;; NEXT 0 000011CF EBA2 JMP SHORT $MDO145 1843 <2> $MEN145: 1844 <2> ;;AN000;; Yes, 0 000011D1 31D2 XOR DX,DX ;;AN000;; Reset remainder 0 000011D3 31C0 XOR AX,AX ;;AN000;; Reset remainder 0 000011D5 2EFF36[3E00] PUSH word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Restore Return Address 0 000011DA C3 RET ;;AN000;; Return 1849 <2> ;; 1850 <2> $M_CONVERT2ASC ENDP ;;AN000;; 1851 <2> ;; 1852 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1853 <2> ;; 1854 <2> ;; PROC NAME: $M_DISPLAY_MESSAGE 1855 <2> ;; 1856 <2> ;; FUNCTION: Will display or write entire message (with replacable parameters) 1857 <2> ;; INPUTS: ES:DI points to beginning of message 1858 <2> ;; DS:SI points to first sublist structure in chain 1859 <2> ;; BX contains the handle to write to (if applicable) 1860 <2> ;; CX contains the length of string to write (before substitutions) 1861 <2> ;; BP contains the count of replacables 1862 <2> ;; 1863 <2> ;; OUTPUTS: 1864 <2> ;; REGS USED: All 1865 <2> ;; 1866 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1867 <2> ;; 1868 <2> $M_DISPLAY_MESSAGE PROC NEAR ;;AN000;; 1869 <2> ;; 1870 <2> ; $DO ;;AN000;; Note: DS:SI -> message 1871 <2> $MDO165: 0 000011DB 31D2 XOR DX,DX ;;AN000;; Set size = 0 0 000011DD 09C9 OR CX,CX ;;AN000;; Are we finished the message yet? 1874 <2> ; $IF NZ ;;AN000;; No, 0 000011DF 7421 JZ $MIF166 0 000011E1 B425 MOV AH,"%" ;;AN000;; Prepare to scan for % 0 000011E3 B000 MOV AL,0 ;;AN004;; 1878 <2> ;; 1879 <2> ; $DO ;;AN000;; Scan through string until % 1880 <2> $MDO167: 0 000011E5 263825 CMP BYTE PTR [ES:DI],AH ;;AN000;; Is this character NOT a % 1882 <2> ; $LEAVE E,AND ;;AN000;; No, 0 000011E8 750A JNE $MLL168 0 000011EA 26386501 CMP BYTE PTR [ES:DI+1],AH ;;AN000;; Is the next character also a % 1885 <2> ; $LEAVE NE,AND ;;AN000;; No, 0 000011EE 7404 JE $MLL168 0 000011F0 38E0 CMP AL,AH ;;AN000;; Was the character before a % 1888 <2> ; $LEAVE NE ;;AN000;; No, GREAT found it 0 000011F2 750E JNE $MEN167 1890 <2> $MLL168: 0 000011F4 268A05 MOV AL,BYTE PTR [ES:DI] ;;AN004;; Yes, (to any of the above) 0 000011F7 E84BFF CALL $M_IS_IT_DBCS ;;AN004;; Is this character the first part of a DBCS? 1893 <2> ; $IF C ;;AN004;; Yes, 0 000011FA 7301 JNC $MIF169 0 000011FC 47 INC DI ;;AN004;; Increment past second part 1896 <2> ; $ENDIF ;;AN004;; 1897 <2> $MIF169: 0 000011FD 47 INC DI ;;AN000;; Next character in string 0 000011FE 42 INC DX ;;AN000;; Size = Size + 1 0 000011FF 49 DEC CX ;;AN000;; Decrement total size 1901 <2> ; $ENDDO Z ;;AN000;; Exit scan if we're at the end of the line 0 00001200 75E3 JNZ $MDO167 1903 <2> $MEN167: 1904 <2> ; $ENDIF ;;AN000;; 1905 <2> $MIF166: 1906 <2> ;; 0 00001202 56 PUSH SI ;;AN000;; Save beginning of sublists 0 00001203 87CA XCHG CX,DX ;;AN000;; Get size of message to display (tot sz in DX) 0 00001205 09ED OR BP,BP ;;AN000;; Do we have any replacables to do? 1910 <2> ; $IF NZ ;;AN000;; Yes, 0 00001207 7435 JZ $MIF173 0 00001209 4D DEC BP ;;AN000;; Decrement number of replacables 1913 <2> 1914 <2> ;; Search through sublists to find applicable one 1915 <2> 0 0000120A 2E833E[4000]00 CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 1917 <2> ; $IF E ;;AN000;; No, 0 00001210 752C JNE $MIF174 1919 <2> ; $SEARCH ;;AN000;; 1920 <2> $MDO175: 0 00001212 8A4406 MOV AL,[$M_SL + $M_S_ID] ;;AN000;; Get ID byte 0 00001215 0430 ADD AL,30H ;;AN000;; Convert to ASCII 0 00001217 263A4501 CMP AL,BYTE PTR [ES:DI + 1] ;;AN000;; Is this the right sublist? 1924 <2> ; $EXITIF E ;;AN000;; 0 0000121B 7502 JNE $MIF175 1926 <2> ; $ORELSE ;;AN000;; No, 0 0000121D EB1F JMP SHORT $MSR175 1928 <2> $MIF175: 0 0000121F 3C30 CMP AL,$M_SPECIAL_CASE ;;AN000;; Does this sublist have ID = 0 1930 <2> ; $LEAVE E,AND ;;AN000;; Yes, 0 00001221 7504 JNE $MLL178 0 00001223 09D2 OR DX,DX ;;AN000;; Are we at the end of the message? 1933 <2> ; $LEAVE Z ;;AN000;; No, 0 00001225 7404 JZ $MEN175 1935 <2> $MLL178: 0 00001227 0334 ADD SI,WORD PTR [$M_SL + $M_S_SIZE] ;;AN000;; Next SUBLIST 1937 <2> ; $ENDLOOP ;;AN000;; Yes, 0 00001229 EBE7 JMP SHORT $MDO175 1939 <2> $MEN175: 0 0000122B 2E803E[3D00]FF CMP byte [cs:$M_RT + $M_CLASS],UTILITY_MSG_CLASS ;;AN004;; Is it a utility message? 1941 <2> ; $IF E ;;AN004;; Yes, 0 00001231 7508 JNE $MIF180 0 00001233 42 INC DX ;;AN000;; Remember to display CR,LF 0 00001234 42 INC DX ;;AN000;; at the end of the message 0 00001235 49 DEC CX ;;AN000;; Adjust message length 0 00001236 49 DEC CX ;;AN000;; 0 00001237 4F DEC DI ;;AN000;; Adjust ending address of message 0 00001238 4F DEC DI ;;AN000;; 1949 <2> ; $ELSE ;;AN004;; No, 0 00001239 EB03 JMP SHORT $MEN180 1951 <2> $MIF180: 0 0000123B BAFFFF MOV DX,-1 ;;AN004;; Set special case 1953 <2> ; $ENDIF ;;AN004;; 1954 <2> $MEN180: 1955 <2> ; $ENDSRCH ;;AN000;; 1956 <2> $MSR175: 1957 <2> ; $ENDIF ;;AN000;; 1958 <2> $MIF174: 1959 <2> ; $ENDIF ;;AN000;; 1960 <2> $MIF173: 1961 <2> 1962 <2> ;; Prepare and display this part of message 1963 <2> 0 0000123E 57 PUSH DI ;;AN000;; Save pointer to replace number 0 0000123F 29CF SUB DI,CX ;;AN000;; Determine beginning of string 0 00001241 E842FE CALL $M_DISPLAY_STRING ;;AN000;; Display string until % (or end) 0 00001244 5F POP DI ;;AN000;; Get back pointer to replace number 0 00001245 59 POP CX ;;AN000;; Clean up stack in case error 1969 <2> ; $LEAVE C,LONG ;;AN000;; Fail if carry was set 0 00001246 7303 JNC $MXL3 0 00001248 EB67 JMP $MEN165 0 0000124A 90 nop ; identicalise 1973 <2> $MXL3: 0 0000124B 51 PUSH CX ;;AN000;; 1975 <2> 1976 <2> ;; Save and reset pointer registers 1977 <2> 0 0000124C 89D1 MOV CX,DX ;;AN000;; Get the size of the rest of the message 0 0000124E 807C0600 CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the %0 case? 1980 <2> ; $IF NE ;;AN000;; No, 0 00001252 740D JE $MIF187 0 00001254 09C9 OR CX,CX ;;AN000;; Are we finished the whole message? 1983 <2> ; $IF NZ ;;AN000;; No, 0 00001256 7406 JZ $MIF188 0 00001258 49 DEC CX ;;AN000;; Decrement total size (%) 0 00001259 49 DEC CX ;;AN000;; Decrement total size (#) 0 0000125A 47 INC DI ;;AN000;; Go past % 0 0000125B 47 INC DI ;;AN000;; Go past replace number 1989 <2> ; $ELSE ;;AN000;; Yes, (Note this will not leave because INC) 0 0000125C EB01 JMP SHORT $MEN188 1991 <2> $MIF188: 0 0000125E 5E POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 1993 <2> ; $ENDIF ;;AN000;; Yes, Note this will not leave because INC 1994 <2> $MEN188: 1995 <2> ; $ELSE ;;AN000;; 0 0000125F EB10 JMP SHORT $MEN187 1997 <2> $MIF187: 0 00001261 09C9 OR CX,CX ;;AN000;; Are we finished the whole message? 1999 <2> ; $IF Z ;;AN004;; No, 0 00001263 7503 JNZ $MIF192 0 00001265 5E POP SI ;;AN000;; Get back pointer to beginning of SUBLISTs 2002 <2> ; $ELSE ;;AN000;; No, 0 00001266 EB09 JMP SHORT $MEN192 2004 <2> $MIF192: 0 00001268 83F9FF CMP CX,-1 ;;AN004;; Are we at the end of the message? 2006 <2> ; $IF Z ;;AN004;; No, 0 0000126B 7502 JNZ $MIF194 0 0000126D 31C9 XOR CX,CX ;;AN004;; 2009 <2> ; $ENDIF ;;AN000;; 2010 <2> $MIF194: 0 0000126F 09FF OR DI,DI ;;AN004;; Turn ZF off 2012 <2> ; $ENDIF ;;AN000;; 2013 <2> $MEN192: 2014 <2> ; $ENDIF ;;AN000;; Note this will not leave because INC 2015 <2> $MEN187: 2016 <2> ; $LEAVE Z ;;AN000;; 0 00001271 743E JZ $MEN165 0 00001273 55 PUSH BP ;;AN000;; Save the replace count 0 00001274 57 PUSH DI ;;AN000;; Save location to complete message 0 00001275 06 PUSH ES ;;AN000;; 0 00001276 51 PUSH CX ;;AN000;; Save size of the rest of the message 0 00001277 31C9 XOR CX,CX ;;AN000;; Reset CX used for character count 2023 <2> 2024 <2> ;; Determine what action is required on parameter 2025 <2> 0 00001279 2E833E[4000]00 CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2027 <2> ; $IF E ;;AN000;; 0 0000127F 7513 JNE $MIF199 2029 <2> 2030 <2> %IF CHARmsg ;;AN000;; Was Char specified? 2031 <2> Char_Type equ Char_type ; NASM port equate 0 00001281 F644070F TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2033 <2> ; $IF Z ;;AN000;; 0 00001285 7508 JNZ $MIF200 2035 <2> 2036 <2> ;; Character type requested 2037 <2> ;;AN000;; 0 00001287 C47C02 LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 0 0000128A E87102 CALL $M_CHAR_REPLACE ;;AN000;; 2040 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 0 0000128D EB00 JMP SHORT $MEN200 2042 <2> $MIF200: 2043 <2> %ENDIF ;;AN000;; 2044 <2> %IF NUMmsg ;;AN000;; Was Nnmeric type specified? 2045 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2046 <2> ; $IF Z,OR ;;AN000;; 2047 <2> JZ $MLL202 2048 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; 2049 <2> ; $IF Z,OR ;;AN000;; 2050 <2> JZ $MLL202 2051 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Bin_Hex_Type & $M_TYPE_MASK ;;AN000;; 2052 <2> ; $IF Z ;;AN000;; 2053 <2> JNZ $MIF202 2054 <2> $MLL202: 2055 <2> 2056 <2> ;; Numeric type requested 2057 <2> 2058 <2> LES DI,[$M_SL + $M_S_VALUE] ;;AN000;; Load pointer to replacing parameter 2059 <2> CALL $M_BIN2ASC_REPLACE ;;AN000;; 2060 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2061 <2> JMP SHORT $MEN202 2062 <2> $MIF202: 2063 <2> %ENDIF ;;AN000;; 2064 <2> %IF DATEmsg ;;AN000;; Was date specified? 2065 <2> TEST BYTE [$M_SL + $M_S_FLAG],~ Date_Type & $M_TYPE_MASK ;;AN000;; 2066 <2> ; $IF E ;;AN000;; 2067 <2> JNE $MIF204 2068 <2> 2069 <2> ;; Date type requested 2070 <2> 2071 <2> CALL $M_DATE_REPLACE ;;AN000;; 2072 <2> ; $ELSE ;;AN000;; Get the rest of the message to display 2073 <2> JMP SHORT $MEN204 2074 <2> $MIF204: 2075 <2> %ENDIF ;;AN000;; 2076 <2> %IF TIMEmsg ;;AN000;; Was time (12 hour format) specified? 2077 <2> 2078 <2> ;; Time type requested (Default if we have not matched until here) 2079 <2> 2080 <2> CALL $M_TIME_REPLACE ;;AN000;; 2081 <2> %ENDIF ;;AN000;; 2082 <2> 2083 <2> %IF DATEmsg ;;AN000;; 2084 <2> ; $ENDIF ;;AN000;; 2085 <2> $MEN204: 2086 <2> %ENDIF ;;AN000;; 2087 <2> %IF NUMmsg ;;AN000;; 2088 <2> ; $ENDIF ;;AN000;; 2089 <2> $MEN202: 2090 <2> %ENDIF ;;AN000;; 2091 <2> %IF CHARmsg ;;AN000;; 2092 <2> ; $ENDIF ;;AN000;; 2093 <2> $MEN200: 2094 <2> %ENDIF ;;AN000;; 2095 <2> 2096 <2> %IF $M_REPLACE ;;AN000;; 2097 <2> ;; With the replace information of the Stack, display the replaceable field 2098 <2> 0 0000128F E88A01 CALL $M_DISPLAY_REPLACE ;;AN000;; Display the replace 2100 <2> %ENDIF ;;AN000;; 2101 <2> ;; None of the above - Extended/Parse replace 2102 <2> ; $ELSE ;;AN000;; 0 00001292 EB03 JMP SHORT $MEN199 2104 <2> $MIF199: 2105 <2> %IFN COMR 0 00001294 E82200 CALL $M_EXT_PAR_REPLACE ;;AN000;; 2107 <2> %ENDIF 2108 <2> ; $ENDIF ;;AN000;; 2109 <2> $MEN199: 2110 <2> 2111 <2> ;; We must go back and complete the message after the replacable parameter if there is any left 2112 <2> 2113 <2> ; $IF NC ;;AN000;; IF there was an error displaying then EXIT 0 00001297 7207 JC $MIF211 0 00001299 59 POP CX ;;AN000;; Get size of the rest of the message 0 0000129A 07 POP ES ;;AN000;; Get address of the rest of the message 0 0000129B 5F POP DI ;;AN000;; 0 0000129C 5D POP BP ;;AN000;; Get replacment count 0 0000129D 5E POP SI ;;AN000;; ELSE get address of first sublist structure 2120 <2> ; $ELSE ;;AN000;; 0 0000129E EB04 JMP SHORT $MEN211 2122 <2> $MIF211: 0 000012A0 83C40A ADD SP,10 ;;AN000;; Clean up stack if error 0 000012A3 F9 STC ;;AN000;; 2125 <2> ; $ENDIF ;;AN000;; 2126 <2> $MEN211: 0 000012A4 2E833E[4000]00 CMP word [cs:$M_RT + $M_MSG_NUM],$M_NULL ;;AN000;; Is this an Extended/Parse case 2128 <2> ; $ENDDO NE,OR ;;AN000;; 0 000012AA 7505 JNE $MLL214 2130 <2> ; $ENDDO C,LONG ;;AN000;; Go back and display the rest of the message 0 000012AC 7203 JC $MXL4 0 000012AE E92AFF JMP $MDO165 2133 <2> $MXL4: 2134 <2> $MLL214: 2135 <2> $MEN165: 2136 <2> ;; IF there was an error displaying then EXIT 0 000012B1 2EC706[4000]0000 MOV word [cs:$M_RT + $M_MSG_NUM],0 ;;AN000;; Reset message number to null 0 000012B8 C3 RET ;;AN000;; Return 2139 <2> ;; 2140 <2> $M_DISPLAY_MESSAGE ENDP ;;AN000;; 2141 <2> %IFN COMR 2142 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2143 <2> ;; 2144 <2> ;; PROC NAME: $M_EXT_PAR_REPLACE 2145 <2> ;; 2146 <2> ;; FUNCTION: 2147 <2> ;; INPUTS: 2148 <2> ;; OUPUTS: 2149 <2> ;; 2150 <2> ;; REGS USED: 2151 <2> ;; 2152 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2153 <2> ;; 2154 <2> $M_EXT_PAR_REPLACE PROC NEAR ;;AN000;; 2155 <2> ;; 0 000012B9 31D2 XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 0 000012BB 2EA1[4000] MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN000;; Prepare for get binary value (LOW) 0 000012BF 2EC706[4200]0A00 MOV word [cs:$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2159 <2> ;; 0 000012C6 E8A1FE CALL $M_CONVERT2ASC ;;AN000;; 2161 <2> ;; 2162 <2> ; $DO ;;AN000;; 2163 <2> $MDO215: 0 000012C9 58 POP AX ;;AN000;; Get character in register 0 000012CA 2E8887[4400] MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 0 000012CF 43 INC BX ;;AN000;; Increase buffer count 0 000012D0 83FB40 CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2168 <2> ; $IF E ;;AN000;; Yes, 0 000012D3 7503 JNE $MIF216 0 000012D5 E80A02 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2171 <2> ; $ENDIF ;;AN000;; 2172 <2> $MIF216: 0 000012D8 FEC9 DEC CL ;;AN000;; Have we completed replace? 2174 <2> ; $ENDDO Z ;;AN000;; 0 000012DA 75ED JNZ $MDO215 2176 <2> ;; 0 000012DC B80D0A MOV AX,$M_CR_LF ;;AN000;; Move char into the buffer 0 000012DF 2E8987[4400] MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],AX ;;AN000;; Move char into the buffer 0 000012E4 43 INC BX ;;AN000;; Increase buffer count 0 000012E5 43 INC BX ;;AN000;; Increase buffer count 0 000012E6 E8F901 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 0 000012E9 C3 RET ;;AN000:: 2183 <2> ;; 2184 <2> $M_EXT_PAR_REPLACE ENDP ;;AN000;; 2185 <2> ;; 2186 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2187 <2> %ENDIF 2188 <2> %IF $M_SUBS ;;AN000;; Include the common subroutines if they haven't yet 2189 <2> %iassign $M_SUBS FALSE ;;AN000;; No, then include and reset the flag 2190 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2191 <2> ;; 2192 <2> ;; PROC NAME: $M_GET_MSG_ADDRESS 2193 <2> ;; 2194 <2> ;; FUNCTION: To scan thru classes to return pointer to the message header 2195 <2> ;; INPUTS: Access to $M_RES_ADDRESSES 2196 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2197 <2> ;; IF CX > 1 THEN DS:SI points to the specified message 2198 <2> ;; REGS CHANGED: ES,DI,CX,DS,SI 2199 <2> ;; 2200 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2201 <2> ;; 2202 <2> %IF FARmsg ;;AN000;; 2203 <2> $M_GET_MSG_ADDRESS PROC FAR ;;AN000;; 2204 <2> %ELSE ;;AN000;; 2205 <2> $M_GET_MSG_ADDRESS PROC NEAR ;;AN000;; 2206 <2> %ENDIF ;;AN000;; 2207 <2> ;; 0 000012EA 56 PUSH SI ;;AN000;; 0 000012EB 53 PUSH BX ;;AN000;; 0 000012EC 31F6 XOR SI,SI ;;AN000;; Use SI as an index 0 000012EE 31C9 XOR CX,CX ;;AN000;; Use CX as an size 2212 <2> ; $DO ;;AN000;; 2213 <2> $MDO219: 0 000012F0 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN000;; Were utility messages requested? 2215 <2> ; $IF E ;;AN000;; Yes, 0 000012F3 7509 JNE $MIF220 2217 <2> %IF FARmsg ;;AN000;; 2218 <2> LES DI,[$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 2219 <2> MOV BX,ES ;;AN000; 2220 <2> %ELSE ;;AN000;; 0 000012F5 2E8BBC[2C00] MOV DI,WORD PTR [cs:$M_RT + $M_CLASS_ADDRS + SI] ;;AN000;; Get address of class 0 000012FA 89FB MOV BX,DI ;;AN000; 2223 <2> %ENDIF ;;AN000;; 2224 <2> ; $ELSE ;;AN000;; No, 0 000012FC EB28 JMP SHORT $MEN220 2226 <2> $MIF220: 0 000012FE F6C602 TEST DH,PARSE_ERR_CLASS ;;AN000;; Were parse errors requested? 2228 <2> ; $IF NE ;;AN000;; Yes, 0 00001301 7409 JE $MIF222 0 00001303 2EC4BC[1000] LES DI,[cs:$M_RT + $M_PARSE_COMMAND + SI] ;;AN000;; Get address of class 0 00001308 8CC3 MOV BX,ES ;;AN000; 2232 <2> ; $ELSE ;;AN000;; No, extended errors were specified 0 0000130A EB1A JMP SHORT $MEN222 2234 <2> $MIF222: 0 0000130C 83F813 CMP AX,$M_CRIT_LO ;;AN000;; Is this a critical error? 2236 <2> ; $IF AE,AND ;;AN000;; 0 0000130F 720E JNAE $MIF224 0 00001311 83F827 CMP AX,$M_CRIT_HI ;;AN000;; 2239 <2> ; $IF BE ;;AN000;; Yes, 0 00001314 7709 JNBE $MIF224 0 00001316 2EC4BC[1C00] LES DI,[cs:$M_RT + $M_CRIT_ADDRS + SI] ;;AN000;; Get address of class 0 0000131B 8CC3 MOV BX,ES ;;AN000; 2243 <2> ; $ELSE ;;AN000;; 0 0000131D EB07 JMP SHORT $MEN224 2245 <2> $MIF224: 0 0000131F 2EC4BC[0000] LES DI,[cs:$M_RT + $M_EXT_ERR_ADDRS + SI] ;;AN000;; Get address of class 0 00001324 8CC3 MOV BX,ES ;;AN000; 2248 <2> ; $ENDIF ;;AN000;; 2249 <2> $MEN224: 2250 <2> ; $ENDIF ;;AN000;; 2251 <2> $MEN222: 2252 <2> ; $ENDIF ;;AN000;; 2253 <2> $MEN220: 2254 <2> ;; 0 00001326 83FBFF CMP BX,$M_TERMINATING_FLAG ;;AN000;; Are we finished all classes? 2256 <2> ; $IF E ;;AN000;; Yes, 0 00001329 7517 JNE $MIF229 0 0000132B 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN000;; Was it a UTILITY class? 2259 <2> ; $IF E ;;AN000;; Yes, 0 0000132E 7503 JNE $MIF230 0 00001330 F9 STC ;;AN000;; Set the carry flag 2262 <2> ; $ELSE ;;AN000;; No, 0 00001331 EB0D JMP SHORT $MEN230 2264 <2> $MIF230: 0 00001333 2EA3[4000] MOV [cs:$M_RT + $M_MSG_NUM],AX ;;AN000;; Save message number 0 00001337 B8FFFF MOV AX,$M_SPECIAL_MSG_NUM ;;AN000;; Set special message number 0 0000133A BD0100 MOV BP,$M_ONE_REPLACE ;;AN000;; Set one replace in message 0 0000133D 31F6 XOR SI,SI ;;AN000;; Reset the SI index to start again 0 0000133F F8 CLC ;;AN000;; 2270 <2> ; $ENDIF ;;AN000;; No, 2271 <2> $MEN230: 2272 <2> ; $ELSE ;;AN000;; 0 00001340 EB0C JMP SHORT $MEN229 2274 <2> $MIF229: 0 00001342 83FB00 CMP BX,$M_CLASS_NOT_EXIST ;;AN000;; Does this class exist? 2276 <2> ; $IF NE ;;AN001;; Yes, 0 00001345 7403 JE $MIF234 0 00001347 E85400 CALL $M_FIND_SPECIFIED_MSG ;;AN000;; Try to find the message 2279 <2> ; $ENDIF ;;AN000;; 2280 <2> $MIF234: 0 0000134A 83C604 ADD SI,$M_ADDR_SZ_FAR ;;AN000;; Get next class 0 0000134D F8 CLC ;;AN000;; 2283 <2> ; $ENDIF ;;AN000;; 2284 <2> $MEN229: 2285 <2> ; $LEAVE C ;;AN000;; 0 0000134E 7206 JC $MEN219 0 00001350 09C9 OR CX,CX ;;AN000;; Was the message found? 2288 <2> ; $ENDDO NZ,LONG ;;AN000;; 0 00001352 7502 JNZ $MXL5 0 00001354 EB9A JMP $MDO219 2291 <2> $MXL5: 2292 <2> $MEN219: 2293 <2> 0 00001356 9C PUSHF ;;AN006;; Save the flag state 0 00001357 80FE01 CMP DH,EXT_ERR_CLASS ;;AN006;; Was an extended error requested? 2296 <2> ; $IF E ;;AN006;; Yes, 0 0000135A 7529 JNE $MIF239 0 0000135C 52 PUSH DX ;;AN006;; Save all needed registers 0 0000135D 55 PUSH BP ;;AN006;; 0 0000135E 51 PUSH CX ;;AN006;; 0 0000135F 06 PUSH ES ;;AN006;; 0 00001360 57 PUSH DI ;;AN006;; 0 00001361 50 PUSH AX ;;AN006;; 2304 <2> 0 00001362 B80005 MOV AX,IFSFUNC_INSTALL_CHECK ;;AN006;; Check if IFSFUNC is installed 0 00001365 CD2F INT 2FH ;;AN006;; 0 00001367 3CFF CMP AL,IFSFUNC_INSTALLED ;;AN006;; Is it installed? 0 00001369 58 POP AX ;;AN006;; Restore msg number 2309 <2> ; $IF E ;;AN006;; Yes, 0 0000136A 7509 JNE $MIF240 0 0000136C 89C3 MOV BX,AX ;;AN006;; BX is the extended error number 0 0000136E B80205 MOV AX,IFS_GET_ERR_TEXT ;;AN006;; AX is the muliplex number 0 00001371 CD2F INT 2FH ;;AN006;; Call IFSFUNC 2314 <2> ; $ELSE ;;AN006;; No, 0 00001373 EB01 JMP SHORT $MEN240 2316 <2> $MIF240: 0 00001375 F9 STC ;;AN006;; Carry conditon 2318 <2> ; $ENDIF ;;AN006;; 2319 <2> $MEN240: 2320 <2> 2321 <2> ; $IF C ;;AN006;; Was there an update? 0 00001376 7305 JNC $MIF243 0 00001378 5F POP DI ;;AN006;; No, 0 00001379 07 POP ES ;;AN006;; Restore old pointer 0 0000137A 59 POP CX ;;AN006;; 2326 <2> ; $ELSE ;;AN006;; Yes 0 0000137B EB06 JMP SHORT $MEN243 2328 <2> $MIF243: 0 0000137D 83C406 ADD SP,6 ;;AN006;; Throw away old pointer 0 00001380 E80C00 CALL $M_SET_LEN_IN_CX ;;AN006;; Get the length of the ASCIIZ string 2331 <2> ; $ENDIF ;;AN006;; 2332 <2> $MEN243: 0 00001383 5D POP BP ;;AN006;; Restore other Regs 0 00001384 5A POP DX ;;AN006;; 2335 <2> ; $ENDIF ;;AN006;; 2336 <2> $MIF239: 0 00001385 EB01CF0EE8FBFF $M_POPF ;;AN006;; Restore the flag state 2338 <2> 0 0000138C 5B POP BX ;;AN000;; 0 0000138D 5E POP SI ;;AN000;; 0 0000138E C3 RET ;;AN000;; Return ES:DI pointing to the message 2342 <2> ;; 2343 <2> $M_GET_MSG_ADDRESS ENDP ;; 2344 <2> ;; 2345 <2> $M_SET_LEN_IN_CX PROC NEAR ;; 2346 <2> ;; 0 0000138F 57 PUSH DI ;;AN006;; Save position 0 00001390 50 PUSH AX ;;AN006;; 0 00001391 B9FFFF MOV CX,-1 ;;AN006;; Set CX for decrements 0 00001394 30C0 XOR AL,AL ;;AN006;; Prepare compare register 0 00001396 F2AE REPNE SCASB ;;AN006;; Scan for zero 0 00001398 F7D1 NOT CX ;;AN006;; Change decrement into number 0 0000139A 49 DEC CX ;;AN006;; Don't include the zero 0 0000139B 58 POP AX ;;AN006;; 0 0000139C 5F POP DI ;;AN006;; Restore position 0 0000139D C3 RET ;;AN006;; 2357 <2> ;; 2358 <2> $M_SET_LEN_IN_CX ENDP ;; 2359 <2> ;; 2360 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2361 <2> ;; 2362 <2> ;; PROC NAME: $M_FIND_SPECIFIED_MSG 2363 <2> ;; 2364 <2> ;; FUNCTION: To scan thru message headers until message is found 2365 <2> ;; INPUTS: ES:DI points to beginning of msg headers 2366 <2> ;; CX contains the number of messages in class 2367 <2> ;; DH contains the message class 2368 <2> ;; OUPUTS: IF CX = 0 THEN Message was not found 2369 <2> ;; IF CX > 1 THEN ES:DI points to header of specified message 2370 <2> ;; 2371 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2372 <2> ;; 2373 <2> $M_FIND_SPECIFIED_MSG PROC NEAR ;;AN000;; 2374 <2> ;; 0 0000139E 83FB01 CMP BX,1 ;;AN004;; Do we have an address to CALL? 2376 <2> ; $IF E,AND ;;AN004;; Yes, 0 000013A1 7521 JNE $MIF247 0 000013A3 2E833E[2800]FF CMP WORD [cs:$M_RT + $M_DISK_PROC_ADDR],-1 ;;AN004;; Do we have an address to CALL? 2379 <2> ; $IF NE ;;AN004;; Yes, 0 000013A9 7419 JE $MIF247 0 000013AB 83F8FF CMP AX,$M_SPECIAL_MSG_NUM ;;AN004;; Are we displaying a default Ext Err? 2382 <2> ; $IF E ;;AN004;; . . . and . . . 0 000013AE 750D JNE $MIF248 0 000013B0 50 PUSH AX ;;AN004;; Reset the special message number 0 000013B1 2EA1[4000] MOV AX,[cs:$M_RT + $M_MSG_NUM] ;;AN004;; Get the old message number 0 000013B5 2EFF1E[2800] CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 0 000013BA 58 POP AX ;;AN004;; Reset the special message number 2388 <2> ; $ELSE ;;AN004;; Get the old message number 0 000013BB EB05 JMP SHORT $MEN248 2390 <2> $MIF248: 0 000013BD 2EFF1E[2800] CALL far [cs:$M_RT + $M_DISK_PROC_ADDR] ;;AN004;; Call the READ_DISK_PROC to get error text 2392 <2> ; $ENDIF ;;AN004;; Get the old message number 2393 <2> $MEN248: 2394 <2> ; $ELSE ;;AN004;; 0 000013C2 EB1A JMP SHORT $MEN247 2396 <2> $MIF247: 0 000013C4 31C9 XOR CX,CX ;;AN002;; CX = 0 will allow us to 0 000013C6 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2399 <2> ; $IF NE ;;AN001;; 0 000013C9 7406 JE $MIF252 0 000013CB 268A4D03 MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN001;; Get number of messages in class 2402 <2> ; $ELSE ;;AN001;; 0 000013CF EB09 JMP SHORT $MEN252 2404 <2> $MIF252: 2405 <2> %IF FARmsg ;;AN001;; 2406 <2> CMP BYTE PTR [ES:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2407 <2> %ELSE 0 000013D1 2E3835 CMP BYTE PTR [CS:DI + $M_CLASS_ID],DH ;;AN002;; Check if class still exists at 2409 <2> %ENDIF 2410 <2> ; $IF E ;;AN002;; pointer (hopefully) 0 000013D4 7504 JNE $MIF254 2412 <2> %IF FARmsg ;;AN001;; 2413 <2> MOV CL,BYTE PTR [ES:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2414 <2> %ELSE 0 000013D6 2E8A4D03 MOV CL,BYTE PTR [CS:DI + $M_NUM_CLS_MSG] ;;AN000;; Get number of messages in class 2416 <2> %ENDIF 2417 <2> ; $ENDIF ;;AN002;; go on to the next class 2418 <2> $MIF254: 2419 <2> ; $ENDIF ;;AN001;; 2420 <2> $MEN252: 0 000013DA 83C704 ADD DI,$M_CLASS_ID_SZ ;;AN000;; Point past the class header 0 000013DD F9 STC ;;AN004;; Flag that we haven't found anything yet 2423 <2> ; $ENDIF ;;AN004;; 2424 <2> $MEN247: 2425 <2> 2426 <2> ; $IF C ;;AN004;; Have we found anything yet? 0 000013DE 732D JNC $MIF258 0 000013E0 F8 CLC ;;AN004;; No, reset carry 2429 <2> ; $SEARCH ;;AN000;; 2430 <2> $MDO259: 0 000013E1 09C9 OR CX,CX ;;AN000;; Do we have any to check? 2432 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 0 000013E3 7419 JZ $MEN259 0 000013E5 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN001;; 2435 <2> ; $IF NE ;;AN001;; 0 000013E8 7405 JE $MIF261 0 000013EA 263B05 CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN001;; Is this the message requested? 2438 <2> ; $ELSE ;;AN001;; 0 000013ED EB03 JMP SHORT $MEN261 2440 <2> $MIF261: 2441 <2> %IF FARmsg ;;AN001;; 2442 <2> CMP AX,WORD PTR [ES:DI + $M_NUM] ;;AN000;; Is this the message requested? 2443 <2> %ELSE 0 000013EF 2E3B05 CMP AX,WORD PTR [CS:DI + $M_NUM] ;;AN000;; Is this the message requested? 2445 <2> %ENDIF 2446 <2> ; $ENDIF 2447 <2> $MEN261: 2448 <2> ; $EXITIF E ;;AN000;; 0 000013F2 7502 JNE $MIF259 2450 <2> ; $ORELSE ;;AN000; 0 000013F4 EB09 JMP SHORT $MSR259 2452 <2> $MIF259: 0 000013F6 49 DEC CX ;;AN000;; No, well do we have more to check? 2454 <2> ; $LEAVE Z ;;AN000;; No, return with CX = 0 0 000013F7 7405 JZ $MEN259 0 000013F9 83C704 ADD DI,$M_ID_SZ ;;AN000;; Yes, skip past msg header 2457 <2> ; $ENDLOOP ;;AN000;; 0 000013FC EBE3 JMP SHORT $MDO259 2459 <2> $MEN259: 0 000013FE F9 STC ;;AN000;; 2461 <2> ; $ENDSRCH ;;AN000;; Check next message 2462 <2> $MSR259: 2463 <2> ; $IF NC ;;AN000;; Did we find the message? 0 000013FF 720C JC $MIF269 0 00001401 80FEFF CMP DH,UTILITY_MSG_CLASS ;;AN001;; Yes, is it a utility message? 0 00001404 F8 CLC ;;AN001;; 2467 <2> ; $IF E ;;AN001;; 0 00001405 7502 JNE $MIF270 2469 <2> %IF FARmsg ;;AN001;; 2470 <2> %ELSE ;;AN000;; 0 00001407 0E PUSH CS ;;AN000;; 0 00001408 07 POP ES ;;AN000;; Return ES:DI pointing to the message 2473 <2> %ENDIF 2474 <2> ; $ENDIF ;;AN001;; 2475 <2> $MIF270: 0 00001409 26037D02 ADD DI,WORD PTR [ES:DI + $M_TXT_PTR] ;;AN000;; Prepare ES:DI pointing to the message 2477 <2> ; $ENDIF ;;AN004;; 2478 <2> $MIF269: 2479 <2> ; $ENDIF ;;AN004;; 2480 <2> $MIF258: 2481 <2> ;; Yes, great we can return with CX > 0 2482 <2> 2483 <2> ; $IF NC ;;AN000;; Did we find the message? 0 0000140D 7206 JC $MIF274 0 0000140F 30ED XOR CH,CH ;;AN000;; 0 00001411 268A0D MOV CL,BYTE PTR [ES:DI] ;;AN000;; Move size into CX 0 00001414 47 INC DI ;;AN000;; Increment past length 2488 <2> ; $ENDIF ;;AN004;; 2489 <2> $MIF274: 2490 <2> 0 00001415 2EC606[3A00]00 MOV byte [cs:$M_RT + $M_SIZE],$M_NULL ;;AN004;; Reset variable 0 0000141B C3 RET ;;AN000;; Return 2493 <2> ;; 2494 <2> $M_FIND_SPECIFIED_MSG ENDP ;;AN000;; 2495 <2> ;; 2496 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2497 <2> %ENDIF ;;AN000;; END of include of common subroutines 2498 <2> ; 2499 <2> %IF $M_REPLACE ;;AN000;; Is the request to include the code for replaceable parms 2500 <2> %iassign $M_REPLACE FALSE ;;AN000;; Tell the assembler we did 2501 <2> ;; 2502 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2503 <2> $M_DISPLAY_REPLACE PROC NEAR ;;AN000;; 2504 <2> ;; 0 0000141C 31DB XOR BX,BX ;;AN000;; Use BX for buffer count 2506 <2> %IFN COMR 0 0000141E 807C0600 CMP byte [$M_SL + $M_S_ID],$M_SPECIAL_CASE-30H ;;AN000;; Is this the special case (convert to ASCII) 2508 <2> ; $IF E ;;AN000;; Yes, 0 00001422 7513 JNE $MIF276 0 00001424 2EC787[4400]202D MOV WORD PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE_HYP ;;AN000;; Move in a " -" 0 0000142B 43 INC BX ;;AN000;; Increment count 0 0000142C 43 INC BX ;;AN000;; Increment count 0 0000142D 2EC687[4400]20 MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],$M_SPACE ;;AN000;; Move in a " " 0 00001433 43 INC BX ;;AN000;; Increment count 0 00001434 E8AB00 CALL $M_FLUSH_BUF ;;AN000;; Write out " - " to prepare for special case 2516 <2> ; $ENDIF ;;AN000;; If it fails we will catch it later 2517 <2> $MIF276: 2518 <2> %ENDIF 2519 <2> 0 00001437 5D POP BP ;;AN000;; Remember the return address 0 00001438 31DB XOR BX,BX ;;AN000;; Use BX for buffer count 0 0000143A 31D2 XOR DX,DX ;;AN000;; Use DX for count of parms taken off the stack 2523 <2> 0 0000143C 2E880E[3A00] MOV [cs:$M_RT + $M_SIZE],CL ;;AN000;; Save size to later clear stack 0 00001441 8A4409 MOV AL,BYTE PTR [$M_SL + $M_S_MINW] ;;AN000;; Get the minimum width 2526 <2> ;; 0 00001444 38C8 CMP AL,CL ;;AN000;; Do we need pad chars added? 2528 <2> ; $IF A ;;AN000;; Yes, 0 00001446 761F JNA $MIF278 0 00001448 28C8 SUB AL,CL ;;AN000;; Calculate how many pad chars are needed. 0 0000144A 88C6 MOV DH,AL ;;AN000;; Save the number of pad characters 0 0000144C F6440780 TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be right aligned? 2533 <2> ; $IF NZ ;;AN000;; Yes, 0 00001450 7415 JZ $MIF279 2535 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2536 <2> $MDO280: 0 00001452 8A440A MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 0 00001455 2E8887[4400] MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 0 0000145A 43 INC BX ;;AN000;; 0 0000145B 83FB40 CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2541 <2> ; $IF E ;;AN000;; Yes, 0 0000145E 7503 JNE $MIF281 0 00001460 E87F00 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2544 <2> ; $ENDIF ;;AN000;; 2545 <2> $MIF281: 0 00001463 FECE DEC DH ;;AN000;; Have we filled with enough pad chars? 2547 <2> ; $ENDDO Z ;;AN000;; No, next pad character 0 00001465 75EB JNZ $MDO280 2549 <2> ; $ENDIF ;;AN000;; 2550 <2> $MIF279: 2551 <2> ; $ENDIF ;;AN000;; Yes, 2552 <2> $MIF278: 2553 <2> ;; 0 00001467 807C0800 CMP BYTE [$M_SL + $M_S_MAXW],$M_UNLIM_W ;;AN000;; Is maximum width unlimited? 2555 <2> ; $IF NE ;;AN000;; 0 0000146B 740D JE $MIF286 0 0000146D 384C08 CMP BYTE PTR [$M_SL + $M_S_MAXW],CL ;;AN000;; Will we exceed maximum width? 2558 <2> ; $IF B ;;AN000;; Yes, 0 00001470 7308 JNB $MIF287 0 00001472 2A4C08 SUB CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Calculate how many extra chars 0 00001475 88CA MOV DL,CL ;;AN000;; Remember how many chars to pop off 0 00001477 8A4C08 MOV CL,BYTE PTR [$M_SL + $M_S_MAXW] ;;AN000;; Set new string length 2563 <2> ; $ENDIF ;;AN000;; 2564 <2> $MIF287: 2565 <2> ; $ENDIF ;;AN000;; 2566 <2> $MIF286: 0 0000147A 09C9 OR CX,CX ;;AN000;; 2568 <2> ; $IF NZ ;;AN000;; 0 0000147C 7425 JZ $MIF290 2570 <2> ; $DO ;;AN000;; Begin filling buffer with string 2571 <2> $MDO291: 0 0000147E F644070F TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2573 <2> ; $IF Z,AND ;;AN000;; 0 00001482 750C JNZ $MIF292 2575 <2> Char_field_ASCIIZ equ Char_Field_ASCIIZ ; NASM port equate 0 00001484 F6440710 TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ; Is this replace a ASCIIZ string? 2577 <2> ; $IF NZ ;;AN000;; Yes, 0 00001488 7406 JZ $MIF292 0 0000148A 268A05 MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get first character from string 0 0000148D 47 INC DI ;;AN000;; Next character in string 2581 <2> ; $ELSE ;;AN000;; No, 0 0000148E EB01 JMP SHORT $MEN292 2583 <2> $MIF292: 0 00001490 58 POP AX ;;AN000;; Get character in register 2585 <2> ; $ENDIF ;;AN000;; 2586 <2> $MEN292: 0 00001491 2E8887[4400] MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move char into the buffer 0 00001496 43 INC BX ;;AN000;; Increase buffer count 0 00001497 83FB40 CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2590 <2> ; $IF E ;;AN000;; Yes, 0 0000149A 7503 JNE $MIF295 0 0000149C E84300 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2593 <2> ; $ENDIF ;;AN000;; 2594 <2> $MIF295: 0 0000149F FEC9 DEC CL ;;AN000;; Have we completed replace? 2596 <2> ; $ENDDO Z ;;AN000;; Test again 0 000014A1 75DB JNZ $MDO291 2598 <2> ; $ENDIF ;;AN000;; 2599 <2> $MIF290: 2600 <2> ;; 0 000014A3 F6440780 TEST BYTE [$M_SL + $M_S_FLAG],Right_Align ;;AN000;; Was replaceable parm to be left aligned? 2602 <2> ; $IF Z ;;AN000;; Yes, 0 000014A7 7519 JNZ $MIF299 0 000014A9 08F6 OR DH,DH ;;AN000;; Do we need pad chars added? 2605 <2> ; $IF NZ ;;AN000;; Yes, 0 000014AB 7415 JZ $MIF300 2607 <2> ; $DO ;;AN000;; Begin filling buffer with pad chars 2608 <2> $MDO301: 0 000014AD 8A440A MOV AL,BYTE PTR [$M_SL + $M_S_PAD] ;;AN000;; 0 000014B0 2E8887[4400] MOV BYTE PTR [cs:$M_RT + $M_TEMP_BUF + BX],AL ;;AN000;; Move in a pad char 0 000014B5 43 INC BX ;;AN000;; 0 000014B6 83FB40 CMP BX,$M_TEMP_BUF_SZ ;;AN000;; Is buffer full? 2613 <2> ; $IF E ;;AN000;; Yes, 0 000014B9 7503 JNE $MIF302 0 000014BB E82400 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer 2616 <2> ; $ENDIF ;;AN000;; 2617 <2> $MIF302: 0 000014BE FECE DEC DH ;;AN000;; Have we filled with enough pad chars? 2619 <2> ; $ENDDO Z ;;AN000;; Test again 0 000014C0 75EB JNZ $MDO301 2621 <2> ; $ENDIF ;;AN000;; 2622 <2> $MIF300: 2623 <2> ; $ENDIF ;;AN000;; 2624 <2> $MIF299: 2625 <2> ;; 0 000014C2 F644070F TEST BYTE [$M_SL + $M_S_FLAG],~ Char_Type & $M_TYPE_MASK ;;AN000;; 2627 <2> ; $IF Z,AND ;;AN000;; 0 000014C6 7508 JNZ $MIF307 0 000014C8 F6440710 TEST byte [$M_SL + $M_S_FLAG],Char_field_ASCIIZ & $M_SIZE_MASK ;;AN000;; Is this replace a ASCIIZ string? 2630 <2> ; $IF NZ ;;AN000;; Yes, 0 000014CC 7402 JZ $MIF307 2632 <2> ; $ELSE ;;AN000;; 0 000014CE EB0D JMP SHORT $MEN307 2634 <2> $MIF307: 0 000014D0 08D2 OR DL,DL ;;AN000;; 2636 <2> ; $IF NE ;;AN000;; 0 000014D2 7409 JE $MIF309 2638 <2> ; $DO ;;AN000;; 2639 <2> $MDO310: 0 000014D4 2E8F06[3E00] POP word [cs:$M_RT + $M_RETURN_ADDR] ;;AN000;; Clean Up stack using spare variable 0 000014D9 FECA DEC DL ;;AN000;; Are we done? 2642 <2> ; $ENDDO Z ;;AN000;; 0 000014DB 75F7 JNZ $MDO310 2644 <2> ; $ENDIF ;;AN000;; 2645 <2> $MIF309: 2646 <2> ; $ENDIF ;;AN000;; 2647 <2> $MEN307: 0 000014DD E80200 CALL $M_FLUSH_BUF ;;AN000;; Flush the buffer for the final time 0 000014E0 55 PUSH BP ;;AN000;; Restore the return address 2650 <2> ;; 0 000014E1 C3 RET ;;AN000;; 2652 <2> ;; 2653 <2> $M_DISPLAY_REPLACE ENDP ;;AN000;; 2654 <2> ;; 2655 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2656 <2> ;; 2657 <2> ;; PROC NAME: $M_FLUSH_BUFFER 2658 <2> ;; 2659 <2> ;; FUNCTION: Display the contents of the temporary buffer 2660 <2> ;; INPUTS: DI contains the number of bytes to display 2661 <2> ;; OUTPUTS: BX reset to zero 2662 <2> ;; 2663 <2> ;; REGS USED: 2664 <2> ;; 2665 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2666 <2> ;; 2667 <2> $M_FLUSH_BUF PROC NEAR ;;AN000;; 2668 <2> ;; 0 000014E2 51 PUSH CX ;;AN000;; Save changed regs 0 000014E3 06 PUSH ES ;;AN000;; 0 000014E4 57 PUSH DI ;;AN000;; 0 000014E5 1E PUSH DS ;;AN000;; Set ES pointing to buffer 0 000014E6 07 POP ES ;;AN000;; 2674 <2> ;; 0 000014E7 89D9 MOV CX,BX ;;AN000;; Set number of bytes to display 0 000014E9 31DB XOR BX,BX ;;AN000;; Reset buffer counter 0 000014EB 8D3E[4400] LEA DI,[$M_RT + $M_TEMP_BUF] ;;AN000;; Reset buffer location pointer 0 000014EF E894FB CALL $M_DISPLAY_STRING ;;AN000;; Display the buffer 2679 <2> ;; 2680 <2> ; $IF NC ;;AN000;; Error? 0 000014F2 7205 JC $MIF314 0 000014F4 5F POP DI ;;AN000;; No, Restore changed regs 0 000014F5 07 POP ES ;;AN000;; 0 000014F6 59 POP CX ;;AN000;; 2685 <2> ; $ELSE ;;AN000;; Yes, 0 000014F7 EB04 JMP SHORT $MEN314 2687 <2> $MIF314: 0 000014F9 83C406 ADD SP,6 ;;AN000;; Fix stack 0 000014FC F9 STC ;;AN000;; 2690 <2> ; $ENDIF ;;AN000;; Error? 2691 <2> $MEN314: 2692 <2> ;; 0 000014FD C3 RET ;;AN000;; Return 2694 <2> ;; 2695 <2> $M_FLUSH_BUF ENDP ;;AN000;; 2696 <2> ;; 2697 <2> ;; 2698 <2> %IF CHARmsg ;;AN000;; Is the request to include the code for CHAR replace? 2699 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2700 <2> %iassign $M_CHAR_ONLY TRUE ;;AN000;; replacement code later 2701 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2702 <2> ;; 2703 <2> ;; PROC NAME: $M_CHAR_REPLACE 2704 <2> ;; 2705 <2> ;; FUNCTION: Will prepare a single char or ASCIIZ string for replace 2706 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2707 <2> ;; ES:DI contains the VALUE from SUBLIST 2708 <2> ;; OUTPUTS: CX contains number of characters on stack 2709 <2> ;; Top of stack --> Last character 2710 <2> ;; . . . 2711 <2> ;; Bot of stack --> First character 2712 <2> ;; 2713 <2> ;; OTHER REGS Revised: AX 2714 <2> ;; 2715 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2716 <2> ;; 2717 <2> $M_CHAR_REPLACE PROC NEAR ;;AN000;; 2718 <2> ;; 0 000014FE 5D POP BP ;;AN000;; Save return address 0 000014FF F6440730 TEST byte [$M_SL + $M_S_FLAG],~ Char_Field_Char & $M_SIZE_MASK ;;AN000;; Was Character specified? 2721 <2> ; $IF Z ;;AN000;; Yes, 0 00001503 7512 JNZ $MIF317 0 00001505 268A05 MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 0 00001508 50 PUSH AX ;;AN000;; Put it on the stack 0 00001509 41 INC CX ;;AN000;; Increase the count 0 0000150A E838FC CALL $M_IS_IT_DBCS ;;AN000;; Is this the first byte of a DB character 2727 <2> ; $IF C ;;AN000;; Yes, 0 0000150D 7306 JNC $MIF318 0 0000150F 268A4501 MOV AL,BYTE PTR [ES:DI + 1] ;;AN000;; Get the next character 0 00001513 50 PUSH AX ;;AN000;; Put it on the stack 0 00001514 F8 CLC ;;AN000;; Clear the carry 2732 <2> ; $ENDIF ;;AN000;; 2733 <2> $MIF318: 2734 <2> ; $ELSE ;;AN000;; No, it was an ASCIIZ string 0 00001515 EB0D JMP SHORT $MEN317 2736 <2> $MIF317: 2737 <2> ; $DO ;;AN000;; 2738 <2> $MDO321: 0 00001517 268A05 MOV AL,BYTE PTR [ES:DI] ;;AN000;; Get the character 0 0000151A 08C0 OR AL,AL ;;AN000;; Is it the NULL? 2741 <2> ; $LEAVE Z ;;AN000;; No, 0 0000151C 7404 JZ $MEN321 0 0000151E 47 INC DI ;;AN000;; Next character 0 0000151F 41 INC CX ;;AN000;; Increment the count 2745 <2> ; $ENDDO ;;AN000;; Yes, 0 00001520 EBF5 JMP SHORT $MDO321 2747 <2> $MEN321: 0 00001522 29CF SUB DI,CX ;;AN000;; Set SI at the beginning of the string 2749 <2> ; $ENDIF ;;AN000;; 2750 <2> $MEN317: 2751 <2> ;;AN000;; 0 00001524 55 PUSH BP ;;AN000;; Restore return address 0 00001525 C3 RET ;;AN000;; Return 2754 <2> ;; 2755 <2> $M_CHAR_REPLACE ENDP ;;AN000;; 2756 <2> ;; 2757 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2758 <2> %ENDIF ;;AN000;; END of include of CHAR replace code 2759 <2> ; 2760 <2> %IF NUMmsg ;;AN000;; Is the request to include the code for NUM replace? 2761 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2762 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2763 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2764 <2> ;; 2765 <2> ;; PROC NAME: $M_BIN2ASC_REPLACE 2766 <2> ;; 2767 <2> ;; FUNCTION: Convert a signed or unsigned binary number to an ASCII string 2768 <2> ;; and prepare to display 2769 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2770 <2> ;; ES:DI contains the VALUE from SUBLIST 2771 <2> ;; OUTPUTS: CX contains number of characters on stack 2772 <2> ;; Top of stack --> Last character 2773 <2> ;; . . . 2774 <2> ;; Bot of stack --> First character 2775 <2> ;; OTHER REGS Revised: BX,DX,AX 2776 <2> ;; 2777 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2778 <2> ;; 2779 <2> $M_BIN2ASC_REPLACE PROC NEAR ;;AN000;; 2780 <2> ;; 2781 <2> POP BP ;;AN000;; Save return address 2782 <2> ;; 2783 <2> XOR DX,DX ;;AN000;; Prepare for get binary value (HIGH) 2784 <2> XOR AX,AX ;;AN000;; Prepare for get binary value (LOW) 2785 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE16 ;;AN000;; Set default divisor 2786 <2> XOR BX,BX ;;AN000;; Use BP as the NEG flag (if applicable) 2787 <2> %IFN COMR 2788 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_BYTE & $M_SIZE_MASK ;;AN000;; Was BYTE specified? 2789 <2> ; $IF Z ;;AN000;; 2790 <2> JNZ $MIF325 2791 <2> MOV AL, BYTE PTR [ES:DI] ;;AN000;; Setup byte in AL 2792 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2793 <2> ; $IF Z ;;AN000;; 2794 <2> JNZ $MIF326 2795 <2> TEST AL,10000000b ;;AN000;; Is this number negative? 2796 <2> ; $IF NZ ;;AN000;; Yes, 2797 <2> JZ $MIF327 2798 <2> INC BX ;;AN000;; Remember that it was negative 2799 <2> AND AL,01111111b ;;AN000;; Make it positive 2800 <2> ; $ENDIF ;;AN000;; 2801 <2> $MIF327: 2802 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2803 <2> ; $ENDIF ;;AN000;; 2804 <2> $MIF326: 2805 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2806 <2> ; $IF Z ;;AN000;; 2807 <2> JNZ $MIF330 2808 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2809 <2> ; $ENDIF ;;AN000;; 2810 <2> $MIF330: 2811 <2> ; $ELSE ;;AN000;; 2812 <2> JMP SHORT $MEN325 2813 <2> $MIF325: 2814 <2> %ENDIF 2815 <2> TEST byte [$M_SL + $M_S_FLAG],~ $M_WORD & $M_SIZE_MASK ;;AN000;; Was WORD specified? 2816 <2> ; $IF Z ;;AN000;; 2817 <2> JNZ $MIF333 2818 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup byte in AL 2819 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;; AN000;; Was Signed binary specified? 2820 <2> ; $IF Z ;;AN000;; 2821 <2> JNZ $MIF334 2822 <2> TEST AH,10000000b ;;AN000;; Is this number negative? 2823 <2> ; $IF NZ ;;AN000;; Yes, 2824 <2> JZ $MIF335 2825 <2> INC BX ;;AN000;; Remember that it was negative 2826 <2> AND AH,01111111b ;;AN000;; Make it positive 2827 <2> ; $ENDIF ;;AN000;; 2828 <2> $MIF335: 2829 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2830 <2> ; $ENDIF ;;AN000;; 2831 <2> $MIF334: 2832 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2833 <2> ; $IF Z ;;AN000;; 2834 <2> JNZ $MIF338 2835 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2836 <2> ; $ENDIF ;;AN000;; 2837 <2> $MIF338: 2838 <2> ; $ELSE ;;AN000;; 2839 <2> JMP SHORT $MEN333 2840 <2> $MIF333: 2841 <2> %IFN COMR 2842 <2> MOV AX, WORD PTR [ES:DI] ;;AN000;; Setup Double word in DX:AX 2843 <2> MOV DX, WORD PTR [ES:DI + 2] ;;AN000;; 2844 <2> TEST byte [$M_SL + $M_S_FLAG],~ Sgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2845 <2> ; $IF Z ;;AN000;; 2846 <2> JNZ $MIF341 2847 <2> TEST DH,10000000b ;;AN000;; Is this number negative? 2848 <2> ; $IF NZ ;;AN000;; Yes, 2849 <2> JZ $MIF342 2850 <2> INC BX ;;AN000;; Remember that it was negative 2851 <2> AND DH,01111111b ;;AN000;; Make it positive 2852 <2> ; $ENDIF ;;AN000;; 2853 <2> $MIF342: 2854 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2855 <2> ; $ENDIF ;;AN000;; 2856 <2> $MIF341: 2857 <2> TEST byte [$M_SL + $M_S_FLAG],~ Unsgn_Bin_Type & $M_TYPE_MASK ;;AN000;; Was Signed binary specified? 2858 <2> ; $IF Z ;;AN000;; 2859 <2> JNZ $MIF345 2860 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; 2861 <2> ; $ENDIF ;;AN000;; 2862 <2> $MIF345: 2863 <2> %ENDIF 2864 <2> ; $ENDIF ;;AN000;; 2865 <2> $MEN333: 2866 <2> ; $ENDIF ;;AN000;; 2867 <2> $MEN325: 2868 <2> ;; 2869 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert to ASCII string 2870 <2> %IFN COMR 2871 <2> OR BX,BX ;;AN000;; 2872 <2> ; $IF NZ ;;AN000;; Was number negative? 2873 <2> JZ $MIF349 2874 <2> XOR DX,DX ;;AN000;; Yes, 2875 <2> MOV DL,$M_NEG_SIGN ;;AN000;; Put "-" on the stack with the number 2876 <2> PUSH DX ;;AN000;; 2877 <2> ; $ENDIF ;;AN000;; No, 2878 <2> $MIF349: 2879 <2> %ENDIF 2880 <2> ;; 2881 <2> PUSH BP ;;AN000;; Restore return address 2882 <2> RET ;;AN000;; Return 2883 <2> ;; 2884 <2> $M_BIN2ASC_REPLACE ENDP ;;AN000;; 2885 <2> ;; 2886 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2887 <2> %ENDIF ;;AN000;; END of include of NUM replace code 2888 <2> ; 2889 <2> %IF DATEmsg ;;AN000;; Is the request to include the code for DATE replace? 2890 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 2891 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 2892 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2893 <2> ;; 2894 <2> ;; PROC NAME: $M_DATE_REPLACE 2895 <2> ;; 2896 <2> ;; FUNCTION: Convert a date to a decimal ASCII string using current 2897 <2> ;; country format and prepare to display 2898 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 2899 <2> ;; ES:DI points at VALUE from SUBLIST 2900 <2> ;; OUTPUTS: CX contains number of characters on stack 2901 <2> ;; Top of stack --> Last character 2902 <2> ;; . . . 2903 <2> ;; Bot of stack --> First character 2904 <2> ;; OTHER REGS Revised: DX, AX 2905 <2> ;; 2906 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2907 <2> ;; 2908 <2> $M_DATE_REPLACE PROC NEAR ;;AN000;; 2909 <2> ;; 2910 <2> POP BP ;;AN000;; Save return address 2911 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 2912 <2> CALL $M_GET_DATE ;;AN000;; Set date format/separator in $M_RT 2913 <2> ;;AN000;; All O.K.? 2914 <2> XOR DX,DX ;;AN000;; Reset DX value 2915 <2> XOR AX,AX ;;AN000;; Reset AX value 2916 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],0 ;;AN000;; USA Date Format 2917 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2918 <2> JNE $MIF351 2919 <2> CALL $M_YEAR ;;AN000;; Get Year 2920 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2921 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2922 <2> INC CX ;;AN000;; Increment count 2923 <2> XOR AX,AX ;;AN000;; Reset AX value 2924 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2925 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2926 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2927 <2> INC CX ;;AN000;; Increment count 2928 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2929 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2930 <2> ; $ENDIF ;;AN000;; 2931 <2> $MIF351: 2932 <2> ;; 2933 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],1 ;;AN000;; EUROPE Date Format 2934 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2935 <2> JNE $MIF353 2936 <2> CALL $M_YEAR ;;AN000;; Get Year 2937 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2938 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2939 <2> INC CX ;;AN000;; 2940 <2> XOR AX,AX ;;AN000;; Reset AX 2941 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2942 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2943 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2944 <2> INC CX ;;AN000;; 2945 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2946 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2947 <2> ; $ENDIF ;;AN000;; 2948 <2> $MIF353: 2949 <2> ;; 2950 <2> CMP WORD [$M_RT + $M_DATE_FORMAT],2 ;;AN000;; JAPAN Date Format 2951 <2> ; $IF E ;;AN000;; Beginning from end: (saved on the stack) 2952 <2> JNE $MIF355 2953 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Day 2954 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2955 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2956 <2> INC CX ;;AN000;; 2957 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Month 2958 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2959 <2> PUSH WORD [$M_RT + $M_DATE_SEPARA] ;;AN000;; 2960 <2> INC CX ;;AN000;; 2961 <2> CALL $M_YEAR ;;AN000;; Get Year 2962 <2> CALL $M_CONVERTDATE ;;AN000;; Convert it to an ASCII string 2963 <2> ; $ENDIF ;;AN000;; 2964 <2> $MIF355: 2965 <2> ;; 2966 <2> PUSH BP ;;AN000;; Restore return address 2967 <2> RET ;;AN000;; Return 2968 <2> ;; 2969 <2> $M_DATE_REPLACE ENDP ;;AN000;; 2970 <2> ;; 2971 <2> $M_GET_DATE PROC NEAR ;;AN000;; 2972 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 2973 <2> MOV AL,0 ;;AN000;; Get current country info 2974 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 2975 <2> INT 21H ;;AN000;; 2976 <2> ; $IF C ;;AN000;; No, 2977 <2> JNC $MIF357 2978 <2> MOV WORD [$M_RT + $M_DATE_FORMAT],$M_DEF_DATE_FORM ;;AN000;; Set default date format (BH) 2979 <2> MOV BYTE [$M_RT + $M_DATE_SEPARA],$M_DEF_DATE_SEP ;;AN000;; Set default date separator (BL) 2980 <2> ; $ENDIF ;;AN000;; 2981 <2> $MIF357: 2982 <2> RET ;;AN000;; 2983 <2> $M_GET_DATE ENDP ;;AN000;; 2984 <2> ;; 2985 <2> $M_YEAR PROC NEAR ;;AN000;; 2986 <2> MOV AX,WORD PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Year 2987 <2> TEST byte [$M_SL + $M_S_FLAG],Date_MDY_4 & $M_DATE_MASK ;;AN000;; Was Month/Day/Year (2 Digits) specified? 2988 <2> ; $IF Z ;;AN000;; 2989 <2> JNZ $MIF359 2990 <2> CMP AX,$M_MAX_2_YEAR ;;AN000;; Get Year 2991 <2> ; $IF A ;;AN000;; 2992 <2> JNA $MIF360 2993 <2> MOV AX,$M_MAX_2_YEAR ;;AN000;; 2994 <2> ; $ENDIF ;;AN000;; 2995 <2> $MIF360: 2996 <2> ; $ENDIF ;;AN000;; 2997 <2> $MIF359: 2998 <2> RET ;;AN000;; 2999 <2> $M_YEAR ENDP ;;AN000;; 3000 <2> ;; 3001 <2> $M_CONVERTDATE PROC NEAR ;;AN000;; 3002 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3003 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3004 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3005 <2> DEC CX ;;AN000;; Test if size only grew by 1 3006 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3007 <2> ; $IF E ;;AN000;; Yes, 3008 <2> JNE $MIF363 3009 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3010 <2> PUSH AX ;;AN000;; Save it 3011 <2> INC CX ;;AN000;; Count it 3012 <2> ; $ENDIF ;;AN000;; 3013 <2> $MIF363: 3014 <2> INC CX ;;AN000;; Restore CX 3015 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3016 <2> RET ;;AN000;; 3017 <2> $M_CONVERTDATE ENDP ;;AN000;; 3018 <2> ;; 3019 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3020 <2> %ENDIF ;;AN000;; END of include of DATE replace code 3021 <2> ; 3022 <2> %IF TIMEmsg ;;AN000;; Is the request to include the code for TIME replace? 3023 <2> %iassign $M_REPLACE TRUE ;;AN000;; Yes, THEN include it and flag that we will need common 3024 <2> %iassign $M_CHAR_ONLY FALSE ;;AN000;; replacement code later 3025 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3026 <2> ;; 3027 <2> ;; PROC NAME: $M_TIME_REPLACE 3028 <2> ;; 3029 <2> ;; FUNCTION: Convert a time to a decimal ASCII string 3030 <2> ;; and prepare to display 3031 <2> ;; INPUTS: DS:SI points at corresponding SUBLIST 3032 <2> ;; ES:DI points at VALUE from SUBLIST 3033 <2> ;; OUTPUTS: CX contains number of characters on stack 3034 <2> ;; Top of stack --> Last character 3035 <2> ;; . . . 3036 <2> ;; Bot of stack --> First character 3037 <2> ;; REGS USED: BP,CX,AX 3038 <2> ;; 3039 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3040 <2> ;; 3041 <2> $M_TIME_REPLACE PROC NEAR ;;AN000;; 3042 <2> ;; 3043 <2> POP BP ;;AN000;; Save return address 3044 <2> MOV word [$M_RT + $M_DIVISOR],$M_BASE10 ;;AN000;; Set default divisor 3045 <2> CALL $M_GET_TIME ;;AN000;; All O.K.? 3046 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3047 <2> ; $IF NZ ;;AN000;; Yes, 3048 <2> JZ $MIF365 3049 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3050 <2> ; $IF E ;;AN000;; Yes, 3051 <2> JNE $MIF366 3052 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3053 <2> CMP AL,12 ;;AN000;; Is hour 12 or less? 3054 <2> ; $IF L,OR ;;AN000;; or 3055 <2> JL $MLL367 3056 <2> CMP AL,23 ;;AN000;; Is hour 24 or greater? 3057 <2> ; $IF G ;;AN000;; Yes, 3058 <2> JNG $MIF367 3059 <2> $MLL367: 3060 <2> MOV AL,$M_AM ;;AN000;; 3061 <2> PUSH AX ;;AN000;; Push an "a" to represent AM. 3062 <2> INC CX ;;AN000;; 3063 <2> ; $ELSE ;;AN000;; No, 3064 <2> JMP SHORT $MEN367 3065 <2> $MIF367: 3066 <2> MOV AL,$M_PM ;;AN000;; 3067 <2> PUSH AX ;;AN000;; Push an "p" to represent PM. 3068 <2> INC CX ;;AN000;; 3069 <2> ; $ENDIF ;;AN000;; 3070 <2> $MEN367: 3071 <2> ; $ENDIF ;;AN000;; 3072 <2> $MIF366: 3073 <2> ; $ENDIF ;;AN000;; 3074 <2> $MIF365: 3075 <2> ;; 3076 <2> XOR AX,AX ;;AN000;; 3077 <2> XOR DX,DX ;;AN000;; 3078 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3079 <2> ; $IF NZ ;;AN000;; 3080 <2> JZ $MIF372 3081 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+3] ;;AN000;; Get Hundreds 3082 <2> CALL $M_CONVERTTIME ;;AN000;; 3083 <2> PUSH WORD [$M_RT + $M_DECI_SEPARA] ;;AN000;; 3084 <2> INC CX ;;AN000;; 3085 <2> ; $ENDIF ;;AN000;; 3086 <2> $MIF372: 3087 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSSHH_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec/Hunds (12 Hour) specified? 3088 <2> ; $IF NZ,OR ;;AN000;; 3089 <2> JNZ $MLL374 3090 <2> TEST byte [$M_SL + $M_S_FLAG],Time_HHMMSS_Cty & $M_SIZE_MASK ;;AN000;; Was Hour/Min/Sec (12 Hour) specified? 3091 <2> ; $IF NZ ;;AN000;; 3092 <2> JZ $MIF374 3093 <2> $MLL374: 3094 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+2] ;;AN000;; Get Seconds 3095 <2> CALL $M_CONVERTTIME ;;AN000;; 3096 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3097 <2> INC CX ;;AN000;; 3098 <2> ; $ENDIF ;;AN000;; 3099 <2> $MIF374: 3100 <2> ;; Do Hour/Min (12 Hour) 3101 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE+1] ;;AN000;; Get Minutes 3102 <2> CALL $M_CONVERTTIME ;;AN000;; 3103 <2> PUSH WORD [$M_RT + $M_TIME_SEPARA] ;;AN000;; 3104 <2> INC CX ;;AN000;; 3105 <2> ;; 3106 <2> MOV AL,BYTE PTR [$M_SL + $M_S_VALUE] ;;AN000;; Get Hours 3107 <2> TEST byte [$M_SL + $M_S_FLAG],Time_Cty_Type & $M_TIME_MASK ;;AN000;; Is this a request for current country info? 3108 <2> ; $IF NZ ;;AN000;; Yes, 3109 <2> JZ $MIF376 3110 <2> CMP BYTE [$M_RT + $M_TIME_FORMAT],0 ;;AN000;; Is the current country format 12 Hour? 3111 <2> ; $IF E ;;AN000;; Yes, 3112 <2> JNE $MIF377 3113 <2> CMP AL,13 ;;AN000;; Is hour less than 12? 3114 <2> ; $IF GE ;;AN000;; Yes, 3115 <2> JNGE $MIF378 3116 <2> SUB AL,12 ;;AN000;; Set to a 12 hour value 3117 <2> ; $ENDIF ;;AN000;; 3118 <2> $MIF378: 3119 <2> CMP AL,0 ;;AN000;; Is hour less than 12? 3120 <2> ; $IF E ;;AN000;; Yes, 3121 <2> JNE $MIF380 3122 <2> MOV AL,12 ;;AN000;; Set to a 12 hour value 3123 <2> ; $ENDIF ;;AN000;; 3124 <2> $MIF380: 3125 <2> ; $ENDIF ;;AN000;; 3126 <2> $MIF377: 3127 <2> ; $ENDIF ;;AN000;; 3128 <2> $MIF376: 3129 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to ASCII 3130 <2> ;; 3131 <2> PUSH BP ;;AN000;; Restore return address 3132 <2> RET ;;AN000;; Return 3133 <2> ;; 3134 <2> $M_TIME_REPLACE ENDP ;;AN000;; 3135 <2> ;; 3136 <2> $M_GET_TIME PROC NEAR ;;AN000;; 3137 <2> MOV AH,DOS_GET_COUNTRY ;;AN000;; Call DOS for country dependant info 3138 <2> MOV AL,0 ;;AN000;; Get current country info 3139 <2> LEA DX,[$M_RT + $M_TEMP_BUF] ;;AN000;; Set up addressibility to buffer 3140 <2> INT 21H ;;AN000;; 3141 <2> ; $IF C ;;AN000;; No, 3142 <2> JNC $MIF384 3143 <2> MOV WORD [$M_RT + $M_TIME_FORMAT],$M_DEF_TIME_FORM ;;AN000;; Set default time format (BH) 3144 <2> MOV BYTE [$M_RT + $M_TIME_SEPARA],$M_DEF_TIME_SEP ;;AN000;; Set default time separator (BL) 3145 <2> MOV BYTE [$M_RT + $M_DECI_SEPARA],$M_DEF_DECI_SEP ;;AN000;; Set default time separator (BL) 3146 <2> ; $ENDIF ;;AN000;; 3147 <2> $MIF384: 3148 <2> RET ;;AN000;; 3149 <2> $M_GET_TIME ENDP ;;AN000;; 3150 <2> ;; 3151 <2> $M_CONVERTTIME PROC NEAR ;;AN000;; 3152 <2> POP WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3153 <2> MOV [$M_RT + $M_SIZE],CL ;;AN000;; Save the size before conversion 3154 <2> CALL $M_CONVERT2ASC ;;AN000;; Convert it to an ASCII string 3155 <2> DEC CX ;;AN000;; Test if size only grew by 1 3156 <2> CMP CL,[$M_RT + $M_SIZE] ;;AN000;; Did size only grow by one 3157 <2> ; $IF E ;;AN000;; Yes, 3158 <2> JNE $MIF386 3159 <2> MOV AX,$M_TIMEDATE_PAD ;;AN000;; Get a pad character (0) 3160 <2> PUSH AX ;;AN000;; Save it 3161 <2> INC CX ;;AN000;; Count it 3162 <2> ; $ENDIF ;;AN000;; 3163 <2> $MIF386: 3164 <2> INC CX ;;AN000;; Restore CX 3165 <2> PUSH WORD [$M_RT + $M_TEMP_BUF] ;;AN000;; Save return address 3166 <2> RET ;;AN000;; 3167 <2> $M_CONVERTTIME ENDP ;;AN000;; 3168 <2> ;; 3169 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3170 <2> %ENDIF ;;AN000;; END of include of TIME replace 3171 <2> %ENDIF ;;AN000;; END of include of Replacement common code 3172 <2> ; 3173 <2> %IF INPUTmsg ;;AN000;; Is the request to include the code for NUM replace? 3174 <2> INPUTmsg equ FALSE ;;AN000;; Yes, THEN include it and reset the flag 3175 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3176 <2> ;; 3177 <2> ;; PROC NAME: $M_WAIT_FOR_INPUT 3178 <2> ;; 3179 <2> ;; FUNCTION: To accept keyed input and return extended key value 3180 <2> ;; in AX register 3181 <2> ;; INPUTS: DL contains the DOS function requested for input 3182 <2> ;; OUPUTS: AX contains the extended key value that was read 3183 <2> ;; REGS USED: 3184 <2> ;; 3185 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3186 <2> ;; 3187 <2> $M_WAIT_FOR_INPUT PROC NEAR ;;AN000;; 3188 <2> ;; 3189 <2> PUSH CX ;;AN000;; Save CX 3190 <2> PUSH DX ;;AN000;; Save DX 3191 <2> PUSH DS ;;AN000;; Save Data segment 3192 <2> ;; 3193 <2> CMP DL,DOS_CLR_KEYB_BUF_MASK ;;AN001;; Are we to clear the keyboard buffer? 3194 <2> ; $IF A ;;AN001;; Yes, 3195 <2> JNA $MIF388 3196 <2> MOV AL,DL ;;AN001;; Mov function into AL 3197 <2> AND AL,LOW_NIB_MASK ;;AN001;; Mask out the C in high nibble 3198 <2> MOV AH,DOS_CLR_KEYB_BUF ;;AN001;; Set input function 3199 <2> ; $ELSE ;;AN001;; No, 3200 <2> JMP SHORT $MEN388 3201 <2> $MIF388: 3202 <2> MOV AH,DL ;;AN000;; Put DOS function in AH 3203 <2> ; $ENDIF ;;AN001;; 3204 <2> $MEN388: 3205 <2> PUSH ES ;;AN000;; Get output buffer segment 3206 <2> POP DS ;;AN000;; 3207 <2> MOV DX,DI ;;AN000;; Get output buffer offset in case needed 3208 <2> INT 21H ;;AN000;; Get keyboard input 3209 <2> POP DS ;;AN000;; 3210 <2> 3211 <2> CMP DL,DOS_BUF_KEYB_INP ;;AN000;; 3212 <2> CLC ;;AN000;; 3213 <2> ; $IF NE ;;AN000;; If character input 3214 <2> JE $MIF391 3215 <2> CALL $M_IS_IT_DBCS ;;AN000;; Is this character DBCS? 3216 <2> ; $IF C ;;AN000;; 3217 <2> JNC $MIF392 3218 <2> MOV CL,AL ;;AN000;; Save first character 3219 <2> MOV AH,DL ;;AN001;; Get back function 3220 <2> INT 21H ;;AN000;; Get keyboard input 3221 <2> MOV AH,CL ;;AN000;; Retreive first character AX = xxxx 3222 <2> CLC ;;AN000;; Clear carry condition 3223 <2> ; $ELSE ;;AN000;; 3224 <2> JMP SHORT $MEN392 3225 <2> $MIF392: 3226 <2> MOV AH,0 ;;AN000;; AX = 00xx where xx is SBCS 3227 <2> ; $ENDIF ;;AN000;; 3228 <2> $MEN392: 3229 <2> ; $ENDIF ;;AN000;; 3230 <2> $MIF391: 3231 <2> ;; 3232 <2> ; $IF NC ;;AN000;; 3233 <2> JC $MIF396 3234 <2> POP DX ;;AN000;; 3235 <2> POP CX ;;AN000;; 3236 <2> ; $ELSE ;;AN000;; 3237 <2> JMP SHORT $MEN396 3238 <2> $MIF396: 3239 <2> ADD SP,4 ;;AN000;; 3240 <2> STC ;;AN000;; Reset carry flag 3241 <2> ; $ENDIF ;;AN000;; 3242 <2> $MEN396: 3243 <2> RET ;;AN000;; Return 3244 <2> ;; 3245 <2> $M_WAIT_FOR_INPUT ENDP ;;AN000;; 3246 <2> ;; 3247 <2> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3248 <2> %ENDIF ;;AN000;; END of include of Wait for Input 3249 <2> %ENDIF ;;AN000;; END of include of SYSDISPMSG 3250 <2> %ENDIF ;;AN000;; END of include of MSG_DATA_ONLY 3251 <2> %ENDIF ;;AN000;; END of include of Structure only 3252 <2> 3253 <2> ;=== Pop trace listing source 3254 <2> 433 <1> 434 <1> %ENDIF 435 <1> 45 46 MSG_SERVICES "SHARE.CLA","SHARE.CL1","SHARE.CL2" 364 <1> %iassign $M_SERVICE FALSE 365 <1> %rep %0 366 <1> %iassign $M_INCLUDE TRUE 367 <1> %iassign MSG_SERVICES_MATCHED 0 368 <1> %ifidni %1, "MSGDATA" 369 <1> %iassign MSGDATA TRUE 370 <1> %iassign $M_SERVICE TRUE 371 <1> %iassign $M_INCLUDE FALSE 372 <1> %iassign MSG_SERVICES_MATCHED 1 373 <1> %else 374 <1> %iassign $M_MSGDATA_ONLY FALSE 375 <1> %endif 376 <1> 377 <1> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <1> 379 <1> %ifidni %1,"COMR" 380 <1> %iassign COMR TRUE 381 <1> %iassign $M_SERVICE TRUE 382 <1> %iassign $M_INCLUDE FALSE 383 <1> %iassign MSG_SERVICES_MATCHED 1 384 <1> %elifidni %1,"COMT" 385 <1> %iassign COMT TRUE 386 <1> %iassign $M_SERVICE TRUE 387 <1> %iassign $M_INCLUDE FALSE 388 <1> %iassign MSG_SERVICES_MATCHED 1 389 <1> %elifidni %1,"SETSTDIO" 390 <1> %iassign SETSTDIO TRUE 391 <1> %iassign $M_SERVICE TRUE 392 <1> %iassign $M_INCLUDE FALSE 393 <1> %iassign MSG_SERVICES_MATCHED 1 394 <1> %elifidni %1,"NOCHECKSTDIN" 395 <1> %iassign NOCHECKSTDIN TRUE 396 <1> %iassign $M_SERVICE TRUE 397 <1> %iassign $M_INCLUDE FALSE 398 <1> %iassign MSG_SERVICES_MATCHED 1 399 <1> %elifidni %1,"NOCHECKSTDOUT" 400 <1> %iassign NOCHECKSTDOUT TRUE 401 <1> %iassign $M_SERVICE TRUE 402 <1> %iassign $M_INCLUDE FALSE 403 <1> %iassign MSG_SERVICES_MATCHED 1 404 <1> %elifidni %1,"DISK_PROC" 405 <1> %iassign DISK_PROC TRUE 406 <1> %iassign $M_SERVICE TRUE 407 <1> %iassign $M_INCLUDE FALSE 408 <1> %iassign MSG_SERVICES_MATCHED 1 409 <1> %endif 410 <1> 411 <1> %IF $M_INCLUDE 412 <1> %define %%string %1 413 <1> %strlen %%length %%string 414 <1> %assign %%ii 1 415 <1> %define %%name "" 416 <1> %rep %%length 417 <1> %substr %%cc %%string %%ii 418 <1> %assign %%ii %%ii + 1 419 <1> %if %%cc >= 'A' && %%cc <= 'Z' 420 <1> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <1> %endif 422 <1> %strcat %%name %%name,%%cc 423 <1> %endrep 424 <1> %include %%name 425 <1> %ENDIF 426 <1> 427 <1> %rotate 1 428 <1> %endrep 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 424 <2> %include %%name 1 <3> 2 <3> ; ---------------------------------------------------------- 3 <3> 4 <3> PUBLIC $M_CLS_1 5 <3> %warning out: ... Including message Class A 5 ****************** <3> warning: out: ... Including message Class A [-w+user] 6 <3> 7 <3> ; ---------------------------------------------------------- 8 <3> 9 <3> $M_CLASS_A_STRUC LABEL BYTE 10 <3> $M_CLASS_ID_size equ $M_CLASS_ID_struc_size ; NASM port equate 11 <3> istruc $M_CLASS_ID 12 <3> at $M_CLS_ID 0 00001526 FF db 0FFH 14 <3> at $M_COMMAND_VER 0 00001527 0400 dw EXPECTED_VERSION 16 <3> at $M_NUM_CLS_MSG 0 00001529 02 db Class_A_MessageCount 18 <3> iend 19 <3> 20 <3> ; ---------------------------------------------------------- 21 <3> 22 <3> 23 <3> $M_A_00001H_STRUC LABEL BYTE 24 <3> $M_ID_size equ $M_ID_struc_size ; NASM port equate 25 <3> istruc $M_ID 26 <3> at $M_NUM 0 0000152A 0100 dw 00001H 28 <3> at $M_TXT_PTR 0 0000152C 0800 dw $M_A_00001H_MSG-$M_A_00001H_STRUC 30 <3> iend 31 <3> 32 <3> $M_A_00002H_STRUC LABEL BYTE 33 <3> istruc $M_ID 34 <3> at $M_NUM 0 0000152E 0200 dw 00002H 36 <3> at $M_TXT_PTR 0 00001530 1C00 dw $M_A_00002H_MSG-$M_A_00002H_STRUC 38 <3> iend 39 <3> 40 <3> ; ---------------------------------------------------------- 41 <3> 42 <3> 43 <3> $M_A_00001H_MSG LABEL BYTE 0 00001532 17 DB $M_A_00001H_END-$M_A_00001H_MSG-1 0 00001533 496E636F7272656374 DB "Incorrect DOS version",CR,LF 0 0000153C 20444F532076657273 0 00001545 696F6E0D0A 46 <3> $M_A_00001H_END LABEL BYTE 47 <3> 48 <3> $M_A_00002H_MSG LABEL BYTE 0 0000154A 16 DB $M_A_00002H_END-$M_A_00002H_MSG-1 0 0000154B 253120616C72656164 DB "%1 already installed",CR,LF 0 00001554 7920696E7374616C6C 0 0000155D 65640D0A 51 <3> $M_A_00002H_END LABEL BYTE 52 <3> 53 <3> ; ---------------------------------------------------------- 54 <3> 55 <3> Class_A_MessageCount EQU 2 56 <3> 57 <3> ; ---------------------------------------------------------- 58 <3> 59 <3> %IF FARmsg 60 <3> $M_CLS_1 PROC FAR 61 <3> %ELSE 62 <3> $M_CLS_1 PROC NEAR 63 <3> %ENDIF 64 <3> 0 00001561 0E PUSH CS 0 00001562 07 POP ES 0 00001563 8D3E[2907] LEA DI,[$M_CLASS_A_STRUC] 0 00001567 83C141 ADD CX,$-$M_CLASS_A_STRUC 0 0000156A C3 RET 70 <3> 71 <3> $M_CLS_1 ENDP 72 <3> 73 <3> ; ---------------------------------------------------------- 74 <3> 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 424 <2> %include %%name 1 <3> 2 <3> ; ---------------------------------------------------------- 3 <3> 4 <3> PUBLIC $M_MSGSERV_1 5 <3> %warning out: ... Including message Class 1 5 ****************** <3> warning: out: ... Including message Class 1 [-w+user] 6 <3> 7 <3> ; ---------------------------------------------------------- 8 <3> 9 <3> $M_CLASS_1_STRUC LABEL BYTE 10 <3> $M_CLASS_ID_size equ $M_CLASS_ID_struc_size ; NASM port equate 11 <3> istruc $M_CLASS_ID 12 <3> at $M_CLS_ID 0 0000156B 01 db 001H 14 <3> at $M_COMMAND_VER 0 0000156C 0400 dw EXPECTED_VERSION 16 <3> at $M_NUM_CLS_MSG 0 0000156E 02 db Class_1_MessageCount 18 <3> iend 19 <3> 20 <3> ; ---------------------------------------------------------- 21 <3> 22 <3> 23 <3> $M_1_00008H_STRUC LABEL BYTE 24 <3> $M_ID_size equ $M_ID_struc_size ; NASM port equate 25 <3> istruc $M_ID 26 <3> at $M_NUM 0 0000156F 0800 dw 00008H 28 <3> at $M_TXT_PTR 0 00001571 0800 dw $M_1_00008H_MSG-$M_1_00008H_STRUC 30 <3> iend 31 <3> 32 <3> ; ---------------------------------------------------------- 33 <3> 34 <3> $M_1_FF_STRUC LABEL BYTE 35 <3> istruc $M_ID 36 <3> at $M_NUM 0 00001573 FFFF dw 0FFFFH 38 <3> at $M_TXT_PTR 0 00001575 1800 dw $M_1_FF_MSG-$M_1_FF_STRUC 40 <3> iend 41 <3> 42 <3> ; ---------------------------------------------------------- 43 <3> 44 <3> 45 <3> $M_1_00008H_MSG LABEL BYTE 0 00001577 13 DB $M_1_00008H_END-$M_1_00008H_MSG-1 0 00001578 496E73756666696369 DB "Insufficient memory" 0 00001581 656E74206D656D6F72 0 0000158A 79 48 <3> $M_1_00008H_END LABEL BYTE 49 <3> 50 <3> ; ---------------------------------------------------------- 51 <3> 52 <3> $M_1_FF_MSG LABEL BYTE 0 0000158B 11 DB $M_1_FF_END-$M_1_FF_MSG-1 0 0000158C 457874656E64656420 DB "Extended Error %1" 0 00001595 4572726F72202531 55 <3> $M_1_FF_END LABEL BYTE 56 <3> 57 <3> ; ---------------------------------------------------------- 58 <3> 59 <3> Class_1_MessageCount EQU 2 60 <3> 61 <3> ; ---------------------------------------------------------- 62 <3> 63 <3> %IF FARmsg 64 <3> $M_MSGSERV_1 PROC FAR 65 <3> %ELSE 66 <3> $M_MSGSERV_1 PROC NEAR 67 <3> %ENDIF 68 <3> 0 0000159D 0E PUSH CS 0 0000159E 07 POP ES 0 0000159F 8D3E[6E07] LEA DI,[$M_CLASS_1_STRUC] 0 000015A3 83C138 ADD CX,$-$M_CLASS_1_STRUC 0 000015A6 C3 RET 74 <3> 75 <3> $M_MSGSERV_1 Endp 76 <3> 77 <3> ; ---------------------------------------------------------- 78 <3> 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 366 <2> %iassign $M_INCLUDE TRUE 367 <2> %iassign MSG_SERVICES_MATCHED 0 368 <2> %ifidni %1, "MSGDATA" 369 <2> %iassign MSGDATA TRUE 370 <2> %iassign $M_SERVICE TRUE 371 <2> %iassign $M_INCLUDE FALSE 372 <2> %iassign MSG_SERVICES_MATCHED 1 373 <2> %else 374 <2> %iassign $M_MSGDATA_ONLY FALSE 375 <2> %endif 376 <2> 377 <2> MSG_SERVICES_list1 %1,"LOAD","NOVERCHECK","DISPLAY","GET","INPUT","CHAR","NUM","TIME","DATE","NEAR","FAR" 378 <2> 379 <2> %ifidni %1,"COMR" 380 <2> %iassign COMR TRUE 381 <2> %iassign $M_SERVICE TRUE 382 <2> %iassign $M_INCLUDE FALSE 383 <2> %iassign MSG_SERVICES_MATCHED 1 384 <2> %elifidni %1,"COMT" 385 <2> %iassign COMT TRUE 386 <2> %iassign $M_SERVICE TRUE 387 <2> %iassign $M_INCLUDE FALSE 388 <2> %iassign MSG_SERVICES_MATCHED 1 389 <2> %elifidni %1,"SETSTDIO" 390 <2> %iassign SETSTDIO TRUE 391 <2> %iassign $M_SERVICE TRUE 392 <2> %iassign $M_INCLUDE FALSE 393 <2> %iassign MSG_SERVICES_MATCHED 1 394 <2> %elifidni %1,"NOCHECKSTDIN" 395 <2> %iassign NOCHECKSTDIN TRUE 396 <2> %iassign $M_SERVICE TRUE 397 <2> %iassign $M_INCLUDE FALSE 398 <2> %iassign MSG_SERVICES_MATCHED 1 399 <2> %elifidni %1,"NOCHECKSTDOUT" 400 <2> %iassign NOCHECKSTDOUT TRUE 401 <2> %iassign $M_SERVICE TRUE 402 <2> %iassign $M_INCLUDE FALSE 403 <2> %iassign MSG_SERVICES_MATCHED 1 404 <2> %elifidni %1,"DISK_PROC" 405 <2> %iassign DISK_PROC TRUE 406 <2> %iassign $M_SERVICE TRUE 407 <2> %iassign $M_INCLUDE FALSE 408 <2> %iassign MSG_SERVICES_MATCHED 1 409 <2> %endif 410 <2> 411 <2> %IF $M_INCLUDE 412 <2> %define %%string %1 413 <2> %strlen %%length %%string 414 <2> %assign %%ii 1 415 <2> %define %%name "" 416 <2> %rep %%length 417 <2> %substr %%cc %%string %%ii 418 <2> %assign %%ii %%ii + 1 419 <2> %if %%cc >= 'A' && %%cc <= 'Z' 420 <2> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <2> %endif 422 <2> %strcat %%name %%name,%%cc 423 <2> %endrep 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 417 <3> %substr %%cc %%string %%ii 418 <3> %assign %%ii %%ii + 1 419 <3> %if %%cc >= 'A' && %%cc <= 'Z' 420 <3> %substr %%cc "abcdefghijklmnopqrstuvwxyz" (%%cc - 'A' + 1) 421 <3> %endif 422 <3> %strcat %%name %%name,%%cc 424 <2> %include %%name 1 <3> 2 <3> ; ---------------------------------------------------------- 3 <3> 4 <3> PUBLIC $M_MSGSERV_2 5 <3> %warning out: ... Including message Class 2 5 ****************** <3> warning: out: ... Including message Class 2 [-w+user] 6 <3> 7 <3> ; ---------------------------------------------------------- 8 <3> 9 <3> $M_CLASS_2_STRUC LABEL BYTE 10 <3> $M_CLASS_ID_size equ $M_CLASS_ID_struc_size ; NASM port equate 11 <3> istruc $M_CLASS_ID 12 <3> at $M_CLS_ID 0 000015A7 02 db 002H 14 <3> at $M_COMMAND_VER 0 000015A8 0400 dw EXPECTED_VERSION 16 <3> at $M_NUM_CLS_MSG 0 000015AA 04 db Class_2_MessageCount 18 <3> iend 19 <3> 20 <3> ; ---------------------------------------------------------- 21 <3> 22 <3> 23 <3> $M_2_00003H_STRUC LABEL BYTE 24 <3> $M_ID_size equ $M_ID_struc_size ; NASM port equate 25 <3> istruc $M_ID 26 <3> at $M_NUM 0 000015AB 0300 dw 00003H 28 <3> at $M_TXT_PTR 0 000015AD 1000 dw $M_2_00003H_MSG-$M_2_00003H_STRUC 30 <3> iend 31 <3> 32 <3> $M_2_00006H_STRUC LABEL BYTE 33 <3> istruc $M_ID 34 <3> at $M_NUM 0 000015AF 0600 dw 00006H 36 <3> at $M_TXT_PTR 0 000015B1 1B00 dw $M_2_00006H_MSG-$M_2_00006H_STRUC 38 <3> iend 39 <3> 40 <3> $M_2_00009H_STRUC LABEL BYTE 41 <3> istruc $M_ID 42 <3> at $M_NUM 0 000015B3 0900 dw 00009H 44 <3> at $M_TXT_PTR 0 000015B5 3C00 dw $M_2_00009H_MSG-$M_2_00009H_STRUC 46 <3> iend 47 <3> 48 <3> ; ---------------------------------------------------------- 49 <3> 50 <3> $M_2_FF_STRUC LABEL BYTE 51 <3> istruc $M_ID 52 <3> at $M_NUM 0 000015B7 FFFF dw 0FFFFH 54 <3> at $M_TXT_PTR 0 000015B9 5500 dw $M_2_FF_MSG-$M_2_FF_STRUC 56 <3> iend 57 <3> 58 <3> ; ---------------------------------------------------------- 59 <3> 60 <3> 61 <3> $M_2_00003H_MSG LABEL BYTE 0 000015BB 0E DB $M_2_00003H_END-$M_2_00003H_MSG-1 0 000015BC 496E76616C69642073 DB "Invalid switch" 0 000015C5 7769746368 64 <3> $M_2_00003H_END LABEL BYTE 65 <3> 66 <3> $M_2_00006H_MSG LABEL BYTE 0 000015CA 24 DB $M_2_00006H_END-$M_2_00006H_MSG-1 0 000015CB 506172616D65746572 DB "Parameter value not in allowed range" 0 000015D4 2076616C7565206E6F 0 000015DD 7420696E20616C6C6F 0 000015E6 7765642072616E6765 69 <3> $M_2_00006H_END LABEL BYTE 70 <3> 71 <3> $M_2_00009H_MSG LABEL BYTE 0 000015EF 1C DB $M_2_00009H_END-$M_2_00009H_MSG-1 0 000015F0 506172616D65746572 DB "Parameter format not correct" 0 000015F9 20666F726D6174206E 0 00001602 6F7420636F72726563 0 0000160B 74 74 <3> $M_2_00009H_END LABEL BYTE 75 <3> 76 <3> ; ---------------------------------------------------------- 77 <3> 78 <3> $M_2_FF_MSG LABEL BYTE 0 0000160C 0E DB $M_2_FF_END-$M_2_FF_MSG-1 0 0000160D 506172736520457272 DB "Parse Error %1" 0 00001616 6F72202531 81 <3> $M_2_FF_END LABEL BYTE 82 <3> 83 <3> ; ---------------------------------------------------------- 84 <3> 85 <3> Class_2_MessageCount EQU 4 86 <3> 87 <3> ; ---------------------------------------------------------- 88 <3> 89 <3> %IF FARmsg 90 <3> $M_MSGSERV_2 PROC FAR 91 <3> %ELSE 92 <3> $M_MSGSERV_2 PROC NEAR 93 <3> %ENDIF 94 <3> 0 0000161B 0E PUSH CS 0 0000161C 07 POP ES 0 0000161D 8D3E[AA07] LEA DI,[$M_CLASS_2_STRUC] 0 00001621 83C17A ADD CX,$-$M_CLASS_2_STRUC 0 00001624 C3 RET 100 <3> 101 <3> $M_MSGSERV_2 Endp 102 <3> 103 <3> ; ---------------------------------------------------------- 104 <3> 425 <2> %ENDIF 426 <2> 427 <2> %rotate 1 429 <1> 430 <1> %IF $M_SERVICE 431 <1> 432 <1> %include "msgserv.nas" 433 <1> 434 <1> %ENDIF 435 <1> 47 48 ; .cref 49 50 51 false equ 0 52 53 %iassign DateSW false 54 %iassign TimeSW false 55 %iassign CmpxSW false 56 %iassign KeySW false 57 %iassign DrvSW false 58 %iassign FileSW false 59 %iassign QusSW false 60 %iassign Val2SW false 61 %iassign Val3SW false 62 63 64 ; include parse.asm 65 ; .xcref 66 ;=== Push trace listing source: parse.nas 67 %include "parse.nas" ; NASM included file 1 <1> ; PAGE ;AN000; 2 <1> ; $SALUT (4,4,8,41) 3 <1> ;(deleted).XLIST 4 <1> ;(deleted)INCLUDE STRUC.INC ;AN020;structured macro definitions for .IF,.ELSE etc. 5 <1> ;(deleted).LIST 6 <1> ; 7 <1> ; NOTE: basesw must be set properly to allow the PARSER to access psdata. 8 <1> ; - basesw undefined means CS seg. override for psdata access. 9 <1> ; - basesw = 1 means DS seg. override for psdata access & 10 <1> ; DS must point to psdata. 11 <1> ; - basesw = 0 means ES seg. override for psdata access & 12 <1> ; ES must point to psdata. 13 <1> ; 14 <1> ; 15 <1> %IFNDEF basesw ;AN022; 16 <1> %idefine psdata_seg CS ;AN022; 17 <1> %ELSE ;AN022; 18 <1> %IF basesw ;AN022;IF "basesw EQU 1" specified by caller THEN 19 <1> %idefine psdata_seg DS ;AN022; 20 <1> %ELSE ;AN022; 21 <1> %idefine psdata_seg ES ;AN022;ELSE only other choice is ES (basesw EQU 0) 22 <1> %ENDIF ;AN022; 23 <1> %ENDIF ;AN022; 24 <1> 25 <1> %ifndef incsw ;AN000; (tm03) Someone doesn't want to include psdata 26 <1> %iassign incsw 1 ;AN000; include psdata.inc (tm03) 27 <1> %endif ;AN000; (tm03) 28 <1> %if incsw ;AN000; If incsw = 1 then (tm03) 29 <1> %include "psdata.mac" ;AN000; include psdata.inc (tm03) 1 <2> ;******************************************************************* 2 <2> ; Parser include file 3 <2> ;******************************************************************* 4 <2> %warning out: INCLUDING COMP=COMMON DSN=PSDATA.INC...;AN000; 4 ****************** <2> warning: out: INCLUDING COMP=COMMON DSN=PSDATA.INC... [-w+user] 5 <2> ; 6 <2> ;**** Default assemble switches definition ************************* 7 <2> 8 <2> %ifndef FarSW ;AN000; 9 <2> %iassign FarSW 0 ;AN000; Near call expected 10 <2> %endif ;AN000; 11 <2> 12 <2> %ifndef DateSW ;AN000; 13 <2> %iassign DateSW 1 ;AN000; Check date format 14 <2> %endif ;AN000; 15 <2> 16 <2> %ifndef TimeSW ;AN000; 17 <2> %iassign TimeSW 1 ;AN000; Check time format 18 <2> %endif ;AN000; 19 <2> 20 <2> %ifndef FileSW ;AN000; 21 <2> %iassign FileSW 1 ;AN000; Check file specification 22 <2> %endif ;AN000; 23 <2> 24 <2> %ifndef CAPSW ;AN000; 25 <2> %iassign CAPSW 1 ;AN000; Perform CAPS if specified 26 <2> %endif ;AN000; 27 <2> 28 <2> %ifndef CmpxSW ;AN000; 29 <2> %iassign CmpxSW 1 ;AN000; Check complex list 30 <2> %endif ;AN000; 31 <2> 32 <2> %ifndef NumSW ;AN000; 33 <2> %iassign NumSW 1 ;AN000; Check numeric value 34 <2> %endif ;AN000; 35 <2> 36 <2> %ifndef KeySW ;AN000; 37 <2> %iassign KeySW 1 ;AN000; Support keywords 38 <2> %endif ;AN000; 39 <2> 40 <2> %ifndef SwSW ;AN000; 41 <2> %iassign SwSW 1 ;AN000; Support switches 42 <2> %endif ;AN000; 43 <2> 44 <2> %ifndef Val1SW ;AN000; 45 <2> %iassign Val1SW 1 ;AN000; Support value definition 1 46 <2> %endif ;AN000; 47 <2> 48 <2> %ifndef Val2SW ;AN000; 49 <2> %iassign Val2SW 1 ;AN000; Support value definition 2 50 <2> %endif ;AN000; 51 <2> 52 <2> %ifndef Val3SW ;AN000; 53 <2> %iassign Val3SW 1 ;AN000; Support value definition 3 54 <2> %endif ;AN000; 55 <2> 56 <2> %ifndef DrvSW ;AN000; 57 <2> %iassign DrvSW 1 ;AN000; Support drive only format 58 <2> %endif ;AN000; 59 <2> 60 <2> %ifndef QusSW ;AN000; 61 <2> %iassign QusSW 1 ;AN000; Support quoted string format 62 <2> %endif ;AN000; 63 <2> 64 <2> %ifndef LFEOLSW ;AN028; 65 <2> %iassign LFEOLSW 1 ;AN028; Accept Line feed (0AH) as end of line 66 <2> %endif ;AN028; 67 <2> 68 <2> ;**** Equation field 69 <2> ;-------- Character code definition 70 <2> 71 <2> D_P_DBSP1 equ 81h ;AN000; 1st byte of DBCS blank 72 <2> D_P_DBSP2 equ 40h ;AN000; 2nd byte of DBCS blank 73 <2> D_P_Period equ "." ;AN020; 74 <2> D_P_Slash equ "/" ;AN020; 75 <2> D_P_Space equ " " ;AN000; SBCS blank 76 <2> D_P_Comma equ "," ;AN000; 77 <2> D_P_Switch equ "/" ;AN000; 78 <2> D_P_Keyword equ "=" ;AN000; 79 <2> D_P_Colon equ ":" ;AN000; 80 <2> D_P_Plus equ "+" ;AN000; 81 <2> D_P_Minus equ "-" ;AN000; 82 <2> D_P_Rparen equ ")" ;AN000; 83 <2> D_P_Lparen equ "(" ;AN000; 84 <2> ;(deleted ;AN025;) D_P_SQuote equ "'" 85 <2> D_P_DQuote equ '"' ;AN000; 86 <2> D_P_NULL equ 0 ;AN000; 87 <2> D_P_TAB equ 9 ;AN000; 88 <2> D_P_CR equ 0Dh ;AN000; 89 <2> D_P_LF equ 0Ah ;AN000; 90 <2> D_P_ASCII80 equ 80h ;AN000; ASCII 80h character code 91 <2> 92 <2> ;-------- Masks 93 <2> D_P_Make_Lower equ 20h ;AN000; make lower case character 94 <2> D_P_Make_Upper equ 0ffh-D_P_Make_Lower ;AN000; make upper case character 95 <2> 96 <2> ; PAGE ;AN000; 97 <2> ;-------- DOS function call related equs 98 <2> 99 <2> D_P_DOS_Get_CDI equ 3800h ;AN000; get country dependent information 100 <2> ; by this call, following information 101 <2> D_P_CDI struc ;AN000; is returned. 0 00000DFD ???? D_P_CDI_DateF dw ? ;0 ;AN000; 0 00000DFF ?????????? D_P_CDI_Money db ?,?,?,?,? ;0,0,0,0,0 ;AN000; 0 00000E04 ???? D_P_CDI_1000 db ?,? ;0,0 ;AN000; 0 00000E06 ???? D_P_CDI_Dec db ?,? ;0,0 ;AN000; 0 00000E08 ???? D_P_CDI_DateS db ?,? ;0,0 ;AN000; 0 00000E0A ???? D_P_CDI_TimeS db ?,? ;0,0 ;AN000; 0 00000E0C ?? db ? ;0 ;AN000; 0 00000E0D ?? db ? ;0 ;AN000; 0 00000E0E ?? D_P_CDI_TimeF db ? ;0 ;AN000; 0 00000E0F ???????? dw ?,? ;0,0 ;AN000; 0 00000E13 ???? db ?,? ;0,0 ;AN000; 113 00000018 <2> dw 5 dup (?) ;(0) ;AN000; 114 <2> D_P_CDI ends ;AN000; 115 <2> 116 <2> D_P_Date_MDY equ 0 ;AN000; 117 <2> D_P_Date_DMY equ 1 ;AN000; 118 <2> D_P_Date_YMD equ 2 ;AN000; 119 <2> ;------------- 120 <2> D_P_DOS_GetEV equ 6300h ;AN000; get DBCS EV call 121 <2> ;AN000; DS:SI will points to DBCS EV 122 <2> ;------------- 123 <2> D_P_DOS_Get_TBL equ 65h ;AN000; get uppercase table call 124 <2> ;AN000; following parameters are set 125 <2> ;AN000; to get casemap table. 126 <2> D_P_DOSTBL_Def equ -1 ;AN000; get default 127 <2> D_P_DOSTBL_BL equ 5 ;AN000; buffer length for Tbl pointer 128 <2> D_P_DOSTBL_File equ 4 ;AN000; get file uppercase table 129 <2> D_P_DOSTBL_Char equ 2 ;AN000; get character uppercase table 130 <2> ; By this call following information 131 <2> ; is returned. 132 <2> D_P_DOS_TBL struc ;AN000; 0 00000DFD ?? D_P_DOS_InfoID db ? ;0 ;AN000; information id for the table 0 00000DFE ???? D_P_DOS_TBL_Off dw ? ;0 ;AN000; offset address of the table 0 00000E00 ???? D_P_DOS_TBL_Seg dw ? ;0 ;AN000; segment address of the table 136 <2> D_P_DOS_TBL ends ;AN000; 137 <2> ; PAGE ;AN000; 138 <2> ;--------------------------------------------------------------------------------------------------------- 139 <2> ; PARMS LABEL BYTE 140 <2> ; DW PARMSX 141 <2> ; DB 2 ; NUMBER OF STRINGS (0, 1, 2) 142 <2> ; DB length ; LENGTH OF THE NEXT LIST, 0 IF NONE 143 <2> ; DB " .. " ; EXTRA DELIMITER LIST, 144 <2> ; ; TYPICAL ARE ";", "=" 145 <2> ; ; "," & WHITESPACE ALWAYS 146 <2> ; DB length ; LENGTH OF THE NEXT LIST, 0 IF NONE 147 <2> ; DB " .. " ; EXTRA END OF LINE LIST, CR, LF OR 0 ALWAYS 148 <2> ;--------------------------------------------------------------------------------------------------------- 149 <2> 150 <2> ;-------------------------------- PARMS block structure 151 <2> D_P_PARMS_Blk struc ;AN000; 0 00000DFD ???? D_P_PARMSX_Address dw ? ;0 ;AN000; Address of PARMSX 0 00000DFF ?? D_P_Num_Extra db ? ;0 ;AN000; Number of extra stuff 0 00000E00 ?? D_P_Len_Extra_Delim db ? ;0 ;AN000; Length of extra delimiter 155 <2> D_P_PARMS_Blk ends ;AN000; 156 <2> 157 <2> D_P_Len_PARMS equ 4 ;AN000; 158 <2> D_P_I_Use_Default equ 0 ;AN000; no extra stuff specified 159 <2> D_P_I_Have_Delim equ 1 ;AN000; extra delimiter specified 160 <2> D_P_I_Have_EOL equ 2 ;AN000; extra EOL specified 161 <2> 162 <2> ;--------------------------------------------------------------------------------------------------------- 163 <2> ; PARMSX LABEL BYTE 164 <2> ; DB minp,maxp ; MIN, MAX POSITIONAL OPERANDS ALLOWED 165 <2> ; DW CONTROL ; DESCRIPTION OF POSITIONAL 1 166 <2> ; : ; REPEATS maxp-1 TIMES 167 <2> ; DB maxs ; # OF SWITCHES 168 <2> ; DW CONTROL ; DESCRIPTION OF SWITCH 1 169 <2> ; : ; REPEATS maxs-1 TIMES 170 <2> ; DB maxk ; # OF KEYWORD 171 <2> ; DW CONTROL ; DESCRIPTION OF KEYWORD 1 172 <2> ; : ; REPEATS maxk-1 TIMES 173 <2> ;--------------------------------------------------------------------------------------------------------- 174 <2> 175 <2> ;-------------------------------- PARMSX block structure 176 <2> D_P_PARMSX_Blk struc ;AN000; 0 00000DFD ?? D_P_MinP db ? ;0 ;AN000; Minimum positional number 0 00000DFE ?? D_P_Maxp db ? ;0 ;AN000; Maximum positional number 0 00000DFF ???? D_P_1st_Control dw ? ;0 ;AN000; Address of the 1st CONTROL block 180 <2> D_P_PARMSX_Blk ends ;AN000; 181 <2> ; PAGE ;AN000; 182 <2> ;--------------------------------------------------------------------------------------------------------- 183 <2> ; << Control field definition >> 184 <2> ; 185 <2> ; 186 <2> ;CONTROL LABEL BYTE 187 <2> ; DW MATCH_FLAGS ; CONTROLS TYPE MATCHED 188 <2> ; ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) 189 <2> ; ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE CHECKED) 190 <2> ; ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) 191 <2> ; ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) 192 <2> ; ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) 193 <2> ; ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) 194 <2> ; ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) 195 <2> ; ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) 196 <2> ; ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) 197 <2> ; ; 0010H=IGNORE ":" AT END IN MATCH 198 <2> ; ; 0002H=REPEATS ALLOWED 199 <2> ; ; 0001H=OPTIONAL 200 <2> ; DW FUNCTION_FLAGS 201 <2> ; ; 0001H=CAP RESULT BY FILE TABLE 202 <2> ; ; 0002H=CAP RESULT BY CHAR TABLE 203 <2> ; ; 0010H=REMOVE ":" AT END 204 <2> ; (tm10) ; 0020H=colon is not necessary for switch 205 <2> ; DW RESULT ; RESULT BUFFER 206 <2> ; DW VALUES ; VALUE LISTS 207 <2> ; DB nid ; NUMBER OF KEYWORD/SWITCH SYNONYMS IN FOLLOWING LIST 208 <2> ; DB "...",0 ; IF n >0, KEYWORD 1 209 <2> ; : 210 <2> ; 211 <2> ;Note: 212 <2> ; - The MATCH_FLAG is bit significant. You can set, for example, TIME bit and 213 <2> ; DATE bit simalteniously. 214 <2> ; 215 <2> ; The parser examins each bit along with the following priority. 216 <2> ; 217 <2> ; COMPLEX -> DATE -> TIME -> NUMERIC VAL -> SIGNED NUMERIC VAL -> DRIVE -> 218 <2> ; FILE SPEC -> SIMPLE STRING. 219 <2> ; 220 <2> ; 221 <2> ; - When the FUNCTION_FLAG is 0001 or 0002, the STRING pointed to by a pointer 222 <2> ; in the result buffer is capitalized. 223 <2> ; 224 <2> ; - Match_Flags 0001H and 0002H have meaning only for the positional. 225 <2> ; 226 <2> ; 227 <2> ; - The "...",0 (bottom most line) does require '=' or '/'. When you need a 228 <2> ; switch, for example, '/A', then STRING points to; 229 <2> ; 230 <2> ; DB 1 ; number of following synonyms 231 <2> ; DB '/A',0 232 <2> ; 233 <2> ; When you need a keyword, for example, 'CODEPAGE=', then "...",0 will be; 234 <2> ; 235 <2> ; DB 1 ; number of following synonyms 236 <2> ; DB 'CODEPAGE=',0 237 <2> ; 238 <2> ; 239 <2> ; - "..." must consist of upper case characters only because the parser 240 <2> ; performs pattern matching after converting input to upper case (by 241 <2> ; using the current country upper case table) 242 <2> ; 243 <2> ; 244 <2> ; - One "..." can contain only one switch or keyword. If you need, for 245 <2> ; example /A and /B, the format will be; 246 <2> ; 247 <2> ; DB 2 ; number of following synonyms 248 <2> ; DB '/A',0 249 <2> ; DB '/B',0 250 <2> ;--------------------------------------------------------------------------------------------------------- 251 <2> 252 <2> ;**** Match_Flags 253 <2> 254 <2> D_P_Num_Val equ 8000h ;AN000; Numeric Value 255 <2> D_P_SNum_Val equ 4000h ;AN000; Signed numeric value 256 <2> D_P_Simple_S equ 2000h ;AN000; Simple string 257 <2> D_P_Date_S equ 1000h ;AN000; Date string 258 <2> D_P_Time_S equ 0800h ;AN000; Time string 259 <2> D_P_Cmpx_S equ 0400h ;AN000; Complex string 260 <2> D_P_File_Spc equ 0200h ;AN000; File Spec 261 <2> D_P_Drv_Only equ 0100h ;AN000; Drive Only 262 <2> D_P_Qu_String equ 0080h ;AN000; Quoted string 263 <2> D_P_Ig_Colon equ 0010h ;AN000; Ignore colon at end in match 264 <2> D_P_Repeat equ 0002h ;AN000; Repeat allowed 265 <2> D_P_Optional equ 0001h ;AN000; Optional 266 <2> 267 <2> ;**** Function flags 268 <2> 269 <2> D_P_CAP_File equ 0001h ;AN000; CAP result by file table 270 <2> D_P_CAP_Char equ 0002h ;AN000; CAP result by character table 271 <2> D_P_Rm_Colon equ 0010h ;AN000; Remove ":" at the end 272 <2> D_P_colon_is_not_necessary equ 0020h ;AN000;(tm10) /+10 and /+:10 273 <2> 274 <2> ;-------------------------------- Control block structure 275 <2> D_P_Control_Blk struc ;AN000; 0 00000DFD ???? D_P_Match_Flag dw ? ;0 ;AN000; Controls type matched 0 00000DFF ???? D_P_Function_Flag dw ? ;0 ;AN000; Function should be taken 0 00000E01 ???? D_P_Result_Buf dw ? ;0 ;AN000; Result buffer address 0 00000E03 ???? D_P_Value_List dw ? ;0 ;AN000; Value list address 0 00000E05 ?? D_P_nid db ? ;0 ;AN000; # of keyword/SW synonyms 0 00000E06 ?? D_P_KeyorSW db ? ;0 ;AN000; keyword or sw 282 <2> D_P_Control_Blk ends ;AN000; 283 <2> ; PAGE ;AN000; 284 <2> ;--------------------------------------------------------------------------------------------------------- 285 <2> ; << Value List Definition >> 286 <2> ; 287 <2> ;VALUES LABEL BYTE 288 <2> ; DB nval ; NUMBER OF VALUE DEFINITIONS (0 - 3) 289 <2> ; = 290 <2> ; = DB nrng ; NUMBER OF RANGES 291 <2> ; = =DB ITEM_TAG ; RETURN VALUE IF RANGE MATCHED 292 <2> ; = =DD X,Y ; RANGE OF VALUES 293 <2> ; = : 294 <2> ; = DB nnval ; NUMBER OF CHOICES 295 <2> ; = =DB ITEM_TAG ; RETURN VALUE IF NUMBER CHOICE MATCHED 296 <2> ; = =DD VALUE ; SPECIFIC CHOICE IF NUMBER 297 <2> ; = : 298 <2> ; = DB nstrval ; NUMBER OF CHOICES 299 <2> ; = =DB ITEM_TAG ; RETURN VALUE IF STRING CHOICE MATCHED 300 <2> ; = =DW STRING ; SPECIFIC CHOICE IF STING 301 <2> ; = : 302 <2> ; 303 <2> ;STRING DB "...",0 ; ASCIIZ STRING IMAGE 304 <2> ; 305 <2> ;Note: 306 <2> ; - ITEM_TAG must not be 0FFH, which will be used in the result buffer 307 <2> ; when no choice lists are provided. 308 <2> ; 309 <2> ; - STRING must consist of upper case characters only because the parser 310 <2> ; performs pattern matching after converting input to upper case (by 311 <2> ; using the current country upper case table) 312 <2> ;--------------------------------------------------------------------------------------------------------- 313 <2> 314 <2> D_P_nval_None equ 0 ;AN000; no value list ID 315 <2> D_P_nval_Range equ 1 ;AN000; range list ID 316 <2> D_P_nval_Value equ 2 ;AN000; value list ID 317 <2> D_P_nval_String equ 3 ;AN000; string list ID 318 <2> D_P_Len_Range equ 9 ;AN000; Length of a range choice(two DD plus one DB) 319 <2> D_P_Len_Value equ 5 ;AN000; Length of a value choice(one DD plus one DB) 320 <2> D_P_Len_String equ 3 ;AN000; Length of a string choice(one DW plus one DB) 321 <2> D_P_No_nrng equ 0 ;AN000; (tm07) no nrng. nnval must not be 0. 322 <2> 323 <2> D_P_Val_List struc ;AN000; 0 00000DFD ?? D_P_NumofList db ? ;0 ;AN000; number of following choice 0 00000DFE ???? D_P_Val_XL dw ? ;0 ;AN000; lower word of value 0 00000E00 ???? D_P_Val_XH dw ? ;0 ;AN000; higher word of value 0 00000E02 ???? D_P_Val_YL dw ? ;0 ;AN000; lower word of another value 0 00000E04 ???? D_P_Val_YH dw ? ;0 ;AN000; higher word of another value 329 <2> D_P_Val_List ends ;AN000; 330 <2> ; PAGE ;AN000; 331 <2> ;--------------------------------------------------------------------------------------------------------- 332 <2> ; << Result Buffer Definition >> 333 <2> ; 334 <2> ;RESULT LABEL BYTE ; BELOW FILLED IN FOR DEFAULTS 335 <2> ; DB type ; TYPE RETURNED: 0=RESERVED, 336 <2> ; ; 1=NUMBER, 2=LIST INDEX, 337 <2> ; ; 3=STRING, 4=COMPLEX, 338 <2> ; ; 5=FILESPEC, 6=DRIVE 339 <2> ; ; 7=DATE, 8=TIME 340 <2> ; ; 9=QUOTED STRING 341 <2> ; DB ITEM_TAG ; MATCHED ITEM TAG 342 <2> ; 343 <2> ; dw synonym@ ; es:@ points to found SYNONYM if provided. 344 <2> ; 345 <2> ; 346 <2> ; = DD n ; VALUE IF NUMBER 347 <2> ; = or 348 <2> ; = DW i ; INDEX (OFFSET) INTO VALUE LIST 349 <2> ; = ; (ES presents Segment address) 350 <2> ; = or 351 <2> ; = DD STRING ; OFFSET OF STRING VALUE 352 <2> ; = or 353 <2> ; = DB drv ; DRIVE NUMBER (1-A, 2-B,..., 26-Z) 354 <2> ; = or 355 <2> ; = DW YEAR ;(1980-2099) IN CASE OF DATE 356 <2> ; = DB MONTH ;(1-12) Note: Range check is not performed. 357 <2> ; = DB DATE ;(1-31) 0 is filled when the corresponding field was not specified. 358 <2> ; = or 359 <2> ; = DB HOUR ;(0-23) IN CASE OF TIME 360 <2> ; = DB MINUTES ;(0-59) Note: Range check is not performed . 361 <2> ; = DB SECONDS ;(0-59) 0 is filled when the corresponding field was not specified . 362 <2> ; = DB HUNDREDTHS ;(0-99) 363 <2> ; = 364 <2> ; 365 <2> ; 366 <2> ;Note: ITEM_TAG is 0FFH when the caller does not specify the choice 367 <2> ; list. 368 <2> ; 369 <2> ; YEAR: If the input value for the year is less than 100, parser 370 <2> ; adds 1900 to it. For example, when 87 is input to parser for 371 <2> ; the year value, he returns 1987. 372 <2> ;--------------------------------------------------------------------------------------------------------- 373 <2> 374 <2> ;-------------------------------- Result block structure 375 <2> D_P_Result_Blk struc ;AN000; 0 00000DFD ?? D_P_Type db ? ;0 ;AN000; Type returned 0 00000DFE ?? D_P_Item_Tag db ? ;0 ;AN000; Matched item tag 0 00000DFF ???? D_P_SYNONYM_Ptr dw ? ;0 ;AN000; pointer to Synonym list returned 0 00000E01 ???????? D_P_Picked_Val db ?,?,?,? ;0,0,0,0 ;AN000; value 380 <2> D_P_Result_Blk ends ;AN000; 381 <2> ;-------------------------------- 382 <2> ;**** values for the type field in the result block 383 <2> 384 <2> D_P_EOL equ 0 ;AN000; End of line 385 <2> D_P_Number equ 1 ;AN000; Number 386 <2> D_P_List_Idx equ 2 ;AN000; List Index 387 <2> D_P_String equ 3 ;AN000; String 388 <2> D_P_Complex equ 4 ;AN000; Complex 389 <2> D_P_File_Spec equ 5 ;AN000; File Spec 390 <2> D_P_Drive equ 6 ;AN000; Drive 391 <2> D_P_Date_F equ 7 ;AN000; Date 392 <2> D_P_Time_F equ 8 ;AN000; Time 393 <2> D_P_Quoted_String equ 9 ;AN000; Quoted String 394 <2> 395 <2> D_P_No_Tag equ 0FFH ;AN000; No ITEM_TAG found 396 <2> ;**** Return code 397 <2> ; 398 <2> ; following return code will be returned in the AX register. 399 <2> 400 <2> D_P_No_Error equ 0 ;AN000; No error 401 <2> D_P_Too_Many equ 1 ;AN000; Too many operands 402 <2> D_P_Op_Missing equ 2 ;AN000; Required operand missing 403 <2> D_P_Not_In_SW equ 3 ;AN000; Not in switch list provided 404 <2> D_P_Not_In_Key equ 4 ;AN000; Not in keyword list provided 405 <2> D_P_Out_Of_Range equ 6 ;AN000; Out of range specified 406 <2> D_P_Not_In_Val equ 7 ;AN000; Not in value list provided 407 <2> D_P_Not_In_Str equ 8 ;AN000; Not in string list provided 408 <2> D_P_Syntax equ 9 ;AN000; Syntax error 409 <2> D_P_RC_EOL equ -1 ;AN000; End of command line 410 <2> 411 <2> ; PAGE ;AN000; 412 <2> ;********************** Local Data ************************************* 0 00001625 0000 D_P_ORDINAL dw 0 ;AN000; Operand ordinal save area 0 00001627 0000 D_P_RC dw 0 ;AN000; Return code from parser 0 00001629 0000 D_P_SI_Save dw 0 ;AN000; Pointer of command buffer 0 0000162B 0000 D_P_DX dw 0 ;AN000; Return result buffer address 0 0000162D 00 D_P_Terminator db 0 ;AN000; Terminator code (ASCII) 0 0000162E 0000 D_P_DBCSEV_OFF dw 0 ;AN000; Offset of DBCS EV 0 00001630 0000 D_P_DBCSEV_SEG dw 0 ;AN000; Segment of DBCS EV 0 00001632 0000 D_P_Flags dw 0 ;AN000; Parser internal flags 421 <2> labelsize D_P_Flags1, byte, D_P_Flags ;AN038; to reference first byte flags 422 <2> labelsize D_P_Flags2, byte, D_P_Flags+1 ;AN038; to reference second byte flags only 423 <2> 424 <2> ;in second byte of D_P_Flags, referenced as D_P_Flags2: 425 <2> D_P_equ equ 01h ;AN000; "=" packed in string buffet 426 <2> D_P_Neg equ 02h ;AN000; Negative value 427 <2> D_P_Time12 equ 04h ;AN000; set when PM is specified 428 <2> D_P_Key_Cmp equ 08h ;AN000; set when keyword compare 429 <2> D_P_SW_Cmp equ 10h ;AN000; set when switch compare 430 <2> D_P_Extra equ 20h ;AN000; set when extra delimiter found 431 <2> D_P_SW equ 40h ;AN000; set when switch found (tm08) 432 <2> D_P_Signed equ 80h ;AN000; signed numeric specified 433 <2> 434 <2> ;in first byte of D_P_Flags, referenced as D_P_Flags1: 435 <2> D_P_time12am equ 01h ;AN038; set when AM is specified on time 436 <2> D_P_TIME_AGAIN EQU 02H ;AN039; SET WHEN READY TO RE-PARSE TIME 437 <2> 0 00001634 0000 D_P_SaveSI_Cmpx dw 0 ;AN000; save si for later use by complex 0 00001636 0000 D_P_KEYorSW_Ptr dw 0 ;AN000; points next to "=" or ":" code 0 00001638 0000 D_P_Save_EOB dw 0 ;AN000; save pointer to EOB 0 0000163A 0000 D_P_Found_SYNONYM dw 0 ;AN000; es:@ points to found synonym 442 <2> 0 0000163C 000000000000000000 D_P_STRING_BUF db 128 dup(0) ;AN000; Pick a operand from command line 0 00001645 000000000000000000 0 0000164E 000000000000000000 0 00001657 000000000000000000 0 00001660 000000000000000000 0 00001669 000000000000000000 0 00001672 000000000000000000 0 0000167B 000000000000000000 0 00001684 000000000000000000 0 0000168D 000000000000000000 0 00001696 000000000000000000 0 0000169F 000000000000000000 0 000016A8 000000000000000000 0 000016B1 000000000000000000 0 000016BA 0000 444 <2> D_P_STRING_BUF_END equ $ ;AN000; 445 <2> %IF TimeSw ;AN039; For TIME only 446 <2> D_P_ORIG_ORD DW 0 ;AN039; ORIGINAL ORDINAL FROM CX 447 <2> D_P_ORIG_STACK DW 0 ;AN039; ORIGINAL VALUE OF STACK FROM SP 448 <2> D_P_ORIG_SI DW 0 ;AN039; ORIGINAL START PARSE POINTER FROM SI 449 <2> %endif ;AN039; 450 <2> %IF DateSw+TimeSw ;AN000;(Check if date or time format is supported) 451 <2> ;------------------------------ 452 <2> ; 453 <2> D_P_Got_Time db 0 ;AN023; if 1, use Time delimiters 454 <2> D_P_NeedToBeRead equ 0ffffh ;AN000; 455 <2> 456 <2> D_P_COUNTRY_INFO: ; NASM structure instance 457 <2> D_P_CDI_size equ D_P_CDI_struc_size ; NASM port equate 458 <2> istruc D_P_CDI 459 <2> at D_P_CDI_DateF 460 <2> dw D_P_NeedToBeRead 461 <2> iend 462 <2> ; 463 <2> D_P_1st_Val dw 0 ;AN000; used when process date or time 464 <2> D_P_2nd_Val dw 0 ;AN000; used when process date or time 465 <2> D_P_3rd_Val dw 0 ;AN000; used when process date or time 466 <2> D_P_4th_Val dw 0 ;AN000; used when process date or time 467 <2> ;------------------------------ 468 <2> %endif ;AN000;(of DateSW+TimeSW) 0 000016BC FF D_P_Char_CAP_Ptr db 0ffh ;AN000; info id 0 000016BD 0000 dw 0 ;AN000; offset of char case map table 0 000016BF 0000 dw 0 ;AN000; segment of char case map table 472 <2> %IF CAPSW ;AN000;(Check if uppercase conversion is supported) 0 000016C1 FF D_P_File_CAP_Ptr db 0ffh ;AN000; info id 0 000016C2 0000 dw 0 ;AN000; offset of file case map table 0 000016C4 0000 dw 0 ;AN000; segment of file case map table 476 <2> %endif ;AN000;(of CAPSW) 477 <2> ; (tm06) IF FileSW ;AN000;(Check if file spec is supported) 478 <2> %IF FileSW+DrvSW ;AN000;(Check if file spec is supported) 479 <2> D_P_FileSp_Char db '[]|<>+=;"' ;AN000; delimitter of file spec 480 <2> D_P_FileSp_Len equ $-D_P_FileSp_Char ;AN000; 481 <2> %endif ;AN000;(of FileSW) 482 <2> ; (tm05) IF QusSW ;AN000;(Check if quoted string is supported) 483 <2> ;(deleted ;AN025;) IF QusSW+CmpxSW ; (tm05) ;AN000;(Check if quoted string is supported) 484 <2> ;(deleted ;AN025;) D_P_SorD_Quote db 0 ;AN000; keep double or single quote 485 <2> ;(deleted ;AN025;) %endif ;AN000;(of QueSW) 486 <2> %IF KeySW ;AN029; if keywords supported 487 <2> D_P_count_to_eol dw 0 ;AN029; count of chars not including EOL 488 <2> ; REGISTER EQUATES - SPECIAL USAGE FOR REGISTERS 489 <2> %idefine D_P_REG_BH_CG_SW BH ;AN029;0="NO CHANGES MADE", FF=CHANGES MADE 490 <2> %idefine D_P_REG_BL_DQ_SW BL ;AN029;0=NOT IN QUOTES,FF=IN QUOTES 491 <2> 492 <2> D_P_DOUBLE_QUOTE EQU '"' ;AN029; 493 <2> D_P_BL_EQ EQU "= " ;AN029; 494 <2> D_P_EQ_BL EQU " =" ;AN029; 495 <2> D_P_TB_EQ EQU 093DH ;AN029; ;"=" 496 <2> D_P_EQ_TB EQU 3D09H ;AN029; ;"=" 497 <2> %endif ;AN029; IF KeySW Supported 498 <2> 499 <2> ; delimiter parsing 500 <2> D_P_colon_period equ 01 ;AN032; check for colon & period 501 <2> D_P_period_only equ 02 ;AN032; check only for period 502 <2> 503 <2> ;filespec error flag 0 000016C6 00 D_P_err_flag db 00 ;AN033; flag set if filespec parsing error 505 <2> ;AN033; was detected. 506 <2> D_P_error_filespec equ 01 ;AN033; mask to set flag 507 <2> ;*********************************************************************** 30 <1> %endif ;AN000; endif (tm03) 31 <1> ; PAGE ;AN000; 32 <1> %warning out: INCLUDING COMP=COMMON DSN=PARSE.ASM...;AN000; 32 ****************** <1> warning: out: INCLUDING COMP=COMMON DSN=PARSE.ASM... [-w+user] 33 <1> ;*********************************************************************** 34 <1> ; SysParse; 35 <1> ; 36 <1> ; Function : Parser Entry 37 <1> ; 38 <1> ; Input: DS:SI -> command line 39 <1> ; ES:DI -> parameter block 40 <1> ; psdata_seg -> psdata.inc 41 <1> ; CX = operand ordinal 42 <1> ; 43 <1> ; Note: ES is the segment containing all the control blocks defined 44 <1> ; by the caller, except for the DOS COMMAND line parms, which 45 <1> ; is in DS. 46 <1> ; 47 <1> ; Output: CY = 1 error of caller, means invalid parameter block or 48 <1> ; invalid value list. But this parser does NOT implement 49 <1> ; this feature. Therefore CY always zero. 50 <1> ; 51 <1> ; CY = 0 AX = return code 52 <1> ; BL = terminated delimiter code 53 <1> ; CX = new operand ordinal 54 <1> ; SI = set past scaned operand 55 <1> ; DX = selected result buffer 56 <1> ; 57 <1> ; Use: D_P_Skip_Delim, D_P_Chk_EOL, D_P_Chk_Delim, D_P_Chk_DBCS 58 <1> ; D_P_Chk_Swtch, D_P_Chk_Pos_Control, D_P_Chk_Key_Control 59 <1> ; D_P_Chk_Sw_Control, D_P_Fill_Result 60 <1> ; 61 <1> ; Vars: D_P_Ordinal(RW), D_P_RC(RW), D_P_SI_Save(RW), D_P_DX(R), D_P_Terminator(R) 62 <1> ; D_P_SaveSI_Cmpx(W), D_P_Flags(RW), D_P_Found_SYNONYM(R), D_P_Save_EOB(W) 63 <1> ; 64 <1> ;-------- Modification History ----------------------------------------- 65 <1> ; 66 <1> ; 4/04/87 : Created by K. K, 67 <1> ; 4/28/87 : D_P_Val_YH assemble error (tm01) 68 <1> ; : JMP SHORT assemble error (tm02) 69 <1> ; 5/14/87 : Someone doesn't want to include psdata (tm03) 70 <1> ; 6/12/87 : D_P_Bridge is missing when TimeSw equ 0 and (CmpxSw equ 1 or 71 <1> ; DateSW equ 1) (tm04) 72 <1> ; 6/12/87 : D_P_SorD_Quote is missing when QusSw equ 0 and CmpxSW equ 1 73 <1> ; (tm05) in PSDATA.INC 74 <1> ; 6/12/87 : D_P_FileSp_Char and D_P_FileSP_Len are missing 75 <1> ; when FileSW equ 0 and DrvSW equ 1 (tm06) in PSDATA.INC 76 <1> ; 6/18/87 : $VAL1 and $VAL3, $VAL2 and $VAL3 can be used in the same 77 <1> ; value-list block (tm07) 78 <1> ; 6/20/87 : Add D_P_SW to check if there's an omiting parameter after 79 <1> ; switch (keyword) or not. If there is, backup si for next call 80 <1> ; (tm08) 81 <1> ; 6/24/87 : Complex Item checking does not work correctly when CmpSW equ 1 82 <1> ; and DateSW equ 0 and TimeSW equ 0 (tm09) 83 <1> ; 6/24/87 : New function flag D_P_colon_is_not_necessary for switch 84 <1> ; /+15 and /+:15 are allowed for user (tm10) 85 <1> ; 6/29/87 : ECS call changes DS register but it causes the address problem 86 <1> ; in user's routines. D_P_Chk_DBCS (tm11) 87 <1> ; 7/10/87 : Switch with no_match flag (0x0000H) does not work correctly 88 <1> ; (tm12) 89 <1> ; 7/10/87 : Invalid switch/keyword does not work correctly 90 <1> ; (tm13) 91 <1> ; 7/10/87 : Drive_only breaks 3 bytes after the result buffer 92 <1> ; (tm14) 93 <1> ; 7/12/87 : Too_Many_Operands sets DX=0 as the PARSE result 94 <1> ; (tm15) 95 <1> ; 7/24/87 : Negative lower bound on numeric ranges cause trouble 96 <1> 97 <1> ; 7/24/87 : Quoted strings being returned with quotes. 98 <1> 99 <1> ; 7/28/87 : Kerry S (;AN018;) 100 <1> ; Non optional value on switch (match flags<>0 and <>1) not flagged 101 <1> ; as an error when missing. Solution: return error 2. Modules 102 <1> ; affected: D_P_Chk_SW_Control. 103 <1> 104 <1> ; 7/29/87 : Kerry S (;AN019;) 105 <1> ; Now allow the optional bit in match flags for switches. This 106 <1> ; allows the switch to be encountered with a value or without a 107 <1> ; value and no error is returned. 108 <1> ; 109 <1> 110 <1> ; 8/28/87 : Ed K, Kerry S (;AN020;) 111 <1> ; 9/14/87 In PROC D_P_Get_DecNum, when checking for field separators 112 <1> ; within a date response, instead of checking just for the one 113 <1> ; character defined by the COUNTRY DEPENDENT INFO, check for 114 <1> ; all three chars, "-", "/", and ".". Change D_P_Chk_Switch to allow 115 <1> ; slashes in date strings when DateSw (assembler switch) is set. 116 <1> 117 <1> ; 9/1/87 : Kerry S (;AN021) 118 <1> ; In PROC D_P_String_Comp, when comparing the switch or keyword on 119 <1> ; the command line with the string in the control block the 120 <1> ; comparing was stopping at a colon (switch) or equal (keyword) 121 <1> ; on the command line and assuming a match. This allowed a shorter 122 <1> ; string on the command line than in the synonym list in the control 123 <1> ; block. I put in a test for a null in the control block so the 124 <1> ; string in the control block must be the same length as the string 125 <1> ; preceeding the colon or equal on the command line. 126 <1> 127 <1> ; 8/28/87 : Kerry S (;AN022;) 128 <1> ; All references to data in PSDATA.INC had CS overrides. This caused 129 <1> ; problems for people who included it themselves in a segment other 130 <1> ; than CS. Added switch to allow including PSDATA.INC in any 131 <1> ; segment. 132 <1> 133 <1> ; 9/16/87 : Ed K (;AN023;) PTM1040 134 <1> ; in D_P_set_cdi PROC, it assumes CS points to psdata. Change Push CS 135 <1> ; into PUSH PSDATA_SEG. In D_P_Get_DecNum PROC, fix AN020 136 <1> ; forced both TIME and DATE to use the delims, "-","/",".". 137 <1> ; Created FLag, in D_P_time_Format PROC, to request the delim in 138 <1> ; BL be used if TIME is being parsed. 139 <1> 140 <1> ; 9/24/87 : Ed K 141 <1> ; Removed the include to STRUC.INC. Replaced the STRUC macro 142 <1> ; invocations with their normally expanded code; made comments 143 <1> ; out of the STRUC macro invocation statements to maintain readability. 144 <1> 145 <1> ; 9/24/87 : Ed K (;AN024;) PTM1222 146 <1> ; When no CONTROL for a keyword found, tried to fill in RESULT 147 <1> ; pointed to by non-existant CONTROL. 148 <1> 149 <1> ; 10/15/87 : Ed K (;AN025;) PTM1672 150 <1> ; A quoted text string can be framed only by double quote. Remove 151 <1> ; support to frame quoted text string with single quote. 152 <1> ; (apostrophe) D_P_SorD_Quote is removed from PSDATA.INC. 153 <1> ; D_P_SQuote EQU also removed from PSDATA.INC. Any references to 154 <1> ; single quote in PROC prologues are left as is for history reasons. 155 <1> 156 <1> ; This fixes another bug, not mentioned in p1672, in that two 157 <1> ; quote chars within a quoted string is supposed to be reported as 158 <1> ; one quote character, but is reported as two quotes. This changed 159 <1> ; two instructions in PROC D_P_Quoted_Str. 160 <1> 161 <1> ; Also fixed are several JMP that caused a NOP, these changed to 162 <1> ; have the SHORT operator to avoid the unneeded NOP. 163 <1> 164 <1> ; The code and PSDATA.INC have been aligned for ease of reading. 165 <1> 166 <1> ; 10/26/87 : Ed K (;AN026;) PTM2041, DATE within SWITCH, BX reference to 167 <1> ; psdata buffer should have psdata_seg. 168 <1> 169 <1> ; 10/27/87 : Ed K (;AN027;) PTM2042 comma between keywords implies 170 <1> ; positional missing. 171 <1> 172 <1> ; 11/06/87 : Ed K (;AN028;) PTM 2315 Parser should not use line feed 173 <1> ; as a line delimiter, should use carriage return. 174 <1> ; Define switch: LFEOLSW, if on, accept LF as end of line char. 175 <1> 176 <1> ; 11/11/87 : Ed K (;AN029;) PTM 1651 GET RID OF WHITESPACE AROUND "=". 177 <1> 178 <1> ; 11/18/87 : Ed K (;AN030;) PTM 2551 If filename is just "", then 179 <1> ; endless loop since SI is returned still pointing to start 180 <1> ; of that parm. 181 <1> 182 <1> ; 11/19/87 : Ed K (;AN031;) PTM 2585 date & time getting bad values. 183 <1> ; Vector to returned string has CS instead of Psdata_Seg, but 184 <1> ; when tried to fix it on previous version, changed similar 185 <1> ; but wrong place. 186 <1> 187 <1> ; 12/09/87 : Bill L (;AN032;) PTM 2772 colon and period are now valid 188 <1> ; delimiters between hours, minutes, seconds for time. And period 189 <1> ; and comma are valid delimiters between seconds and 100th second. 190 <1> 191 <1> ; 12/14/87 : Bill L (;AN033;) PTM 2722 if illegal delimiter characters 192 <1> ; in a filespec, then flag an error. 193 <1> 194 <1> ; 12/22/87 : Bill L (;AN034;) All local data to parser is now 195 <1> ; indexed off of the psdata_seg equate instead of the DS register. 196 <1> ; Using this method, DS can point to the segment of PSP or to psdata 197 <1> ; --> local parser data. Why were some references to local data changed 198 <1> ; to do this before, but not all ????? 199 <1> 200 <1> ; 02/02/88 : Ed K (;AC035;) INSPECT utility, suggests optimizations. 201 <1> 202 <1> ; 02/05/88 : Ed K (;AN036;) P3372-UPPERCASE TRANSLATION, PSDATA_SEG HOSED. 203 <1> ; 204 <1> ; 02/08/88 : Ed K (;AN037;) P3410-AVOID POP OF CS, CHECK BASESW FIRST. 205 <1> 206 <1> ; 02/19/88 : Ed K (;AN038;) p3524 above noon and "am" should be error 207 <1> 208 <1> ; 02/23/88 : Ed K (;AN039;) p3518 accept "comma" and "period" as decimal 209 <1> ; separator in TIME before hundredths field. 210 <1> ; 211 <1> ;*********************************************************************** 212 <1> %IF FarSW ;AN000;(Check if need far return) 213 <1> SysParse proc far ;AN000; 214 <1> %ELSE ;AN000; 215 <1> SysParse proc near ;AN000; 216 <1> %ENDIF ;AN000;(of FarSW) 217 <1> ; $SALUT (4,9,17,41) 0 000016C7 2EC706[3508]0000 mov word [psdata_seg:D_P_Flags],0 ;AC034; Clear all internal flags 219 <1> %IF TimeSw ;AN039; FOR TIME ONLY 220 <1> MOV [PSDATA_SEG:D_P_ORIG_ORD],CX ;AN039; ORIGINAL ORDINAL FROM CX 221 <1> MOV [PSDATA_SEG:D_P_ORIG_STACK],SP ;AN039; ORIGINAL VALUE OF STACK FROM SP 222 <1> MOV [PSDATA_SEG:D_P_ORIG_SI],SI ;AN039; ORIGINAL START PARSE POINTER FROM SI 223 <1> D_P_REDO_TIME: ;AN039; try to parse time again 224 <1> %ENDIF ;AN039; FOR TIME ONLY 0 000016CE FC cld ;AN000; confirm forward direction 226 <1> D_P_ordinal equ D_P_ORDINAL ; NASM port label 0 000016CF 2E890E[2808] mov [psdata_seg:D_P_ordinal],cx ;AC034; save operand ordinal 0 000016D4 2EC706[2A08]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; Assume no error 0 000016DB 2EC706[3D08]0000 mov word [psdata_seg:D_P_Found_SYNONYM],0 ;AC034; initalize synonym pointer 230 <1> 0 000016E2 2EC706[2E08]0000 mov word [psdata_seg:D_P_DX],0 ;AC034; (tm15) 232 <1> %IF KeySW ;AN029; 233 <1> ;IN CASE THE USER PUT OPTIONAL WHITESPACE CHARS AROUND THE "=" USED IN 234 <1> ;KEYWORD DEFINITIONS, SCAN THE COMMAND LINE AND COMPRESS OUT ANY WHITESPACES 235 <1> ;NEXT TO "=" BEFORE STARTING THE USUAL PARSING. 236 <1> push cx ;AN029; 237 <1> push dx ;AN029; 238 <1> push di ;AN029; 239 <1> 240 <1> push si ;AN029; remember where command line starts 241 <1> mov cx,-1 ;AN029; init counter 242 <1> ; $do 243 <1> D_P_loc_eol: ;AN029; 244 <1> inc cx ;AN029; bump counter of chars up to EOL 245 <1> lodsb ;AN029; get a char from command line 246 <1> CALL D_P_Chk_EOL ;AN029; see if AL is EOL char 247 <1> 248 <1> ; enddo z 249 <1> D_P_loc_EOL equ D_P_loc_eol ; NASM port label 250 <1> jnz D_P_loc_EOL ;AN029; not found that EOL char 251 <1> 252 <1> D_P_count_to_EOL equ D_P_count_to_eol ; NASM port label 253 <1> mov [psdata_seg:D_P_count_to_EOL],cx ;AN029;AC034;; save count of chars up to EOL 254 <1> pop si ;AN029; restore start of command line 255 <1> 256 <1> ;scan command string for combinations including "=", 257 <1> ; and replace each with just the simple "=" 258 <1> 259 <1> ;REPEAT UNTIL ONE PASS IS MADE WHEREIN NO CHANGES WERE MADE 260 <1> ; $do 261 <1> D_P_DO1: ;AN029; 262 <1> push si ;AN029; remember where string started 263 <1> D_P_COUNT_TO_EOL equ D_P_count_to_eol ; NASM port label 264 <1> MOV CX,[psdata_seg:D_P_COUNT_TO_EOL] ;AN029;AC034;; set count to no. chars in string, 265 <1> ;AN029; not counting the EOL char 266 <1> XOR BX,BX ;AN029;SET D_P_REG_BL_DQ_SW TO "NOT IN QUOTES", AND... 267 <1> ;AN029;SET D_P_REG_BH_CG_SW TO "NO CHANGES MADE" 268 <1> ;MAKE ONE PASS THRU THE STRING, LOOKING AT EACH CHARACTER 269 <1> ; $do ;AN029; 270 <1> D_P_DO2: ;AN029; 271 <1> D_P_double_quote equ D_P_DOUBLE_QUOTE ; NASM port equate 272 <1> cmp BYTE PTR [SI],D_P_double_quote ;AN029; 273 <1> ; $if e ;AN029;if a double quote was found 274 <1> JNE D_P_IF3 ;AN029; 275 <1> NOT D_P_REG_BL_DQ_SW ;AN029;TOGGLE THE DOUBLE QUOTE STATE SWITCH 276 <1> ; $endif ;AN029; 277 <1> D_P_IF3: ;AN029; 278 <1> OR D_P_REG_BL_DQ_SW,D_P_REG_BL_DQ_SW ;AN029;IS THE DOUBLE QUOTE SWITCH SET? 279 <1> ; $if Z ;AN029;IF NOT IN DOUBLE QUOTES 280 <1> JNZ D_P_IF5 ;AN029; 281 <1> mov ax,word ptr [si] ;AN029; get pair to be checked out 282 <1> cmp ax,D_P_BL_EQ ;AN029;" =" 283 <1> ; $if e,or ;AN029; 284 <1> JE D_P_LL6 ;AN029; 285 <1> cmp ax,D_P_EQ_BL ;AN029;"= " 286 <1> ; $if e,or ;AN029; 287 <1> JE D_P_LL6 ;AN029; 288 <1> cmp ax,D_P_EQ_TB ;AN029; "=" 289 <1> ; $if e,or ;AN029; 290 <1> JE D_P_LL6 ;AN029; 291 <1> cmp ax,D_P_TB_EQ ;AN029;"=" 292 <1> ; $if e ;AN029;if this pair to be replaced with a single "=" 293 <1> JNE D_P_IF6 ;AN029; 294 <1> D_P_LL6: ;AN029; 295 <1> mov BYTE PTR [SI],D_P_Keyword ;AN029; "=" 296 <1> inc si ;AN029;point to next char after the new "=" 297 <1> mov di,si ;AN029;move target right after new "=" 298 <1> 299 <1> push si ;AN029;remember where i am, right after new "=" 300 <1> PUSH CX ;AN029;SAVE CURRENT COUNT 301 <1> inc si ;AN029;source is one beyond that 302 <1> push es ;AN029;remember the extra segment 303 <1> push ds ;AN029;temporarily, set source seg and 304 <1> pop es ;AN029; target seg to the command line seg 305 <1> rep movsb ;AN029;move chars left one position 306 <1> pop es ;AN029;restore the extra segment 307 <1> POP CX ;AN029;RESTORE CURRENT COUNT 308 <1> pop si ;AN029;back to where I was 309 <1> 310 <1> DEC SI ;AN029;LOOK AT FIRST CHAR JUST MOVED 311 <1> MOV D_P_REG_BH_CG_SW,-1 ;AN029;set switch to say "a change was made" 312 <1> DEC word [psdata_seg:D_P_COUNT_TO_EOL] ;AN029;AC034;;because just threw away a char 313 <1> dec CX ;AN029;DITTO 314 <1> ; $endif ;AN029;comparand pair found? 315 <1> D_P_IF6: ;AN029; 316 <1> ; $endif ;AN029;double quote switch? 317 <1> D_P_IF5: ;AN029; 318 <1> inc si ;AN029;bump index to look at next char in command string 319 <1> dec CX ;AN029;one less char to look at 320 <1> ;(deleted ;AC035;) CMP CX,0 ;AN029;is char count all gone yet? 321 <1> ; $enddo LE ;AN029;quit if no more chars 322 <1> JNLE D_P_DO2 ;AN029; 323 <1> pop si ;AN029;remember where string started 324 <1> OR D_P_REG_BH_CG_SW,D_P_REG_BH_CG_SW ;AN029;WAS "A CHANGE MADE"? 325 <1> ; $enddo Z ;AN029;QUIT when no changes were made 326 <1> JNZ D_P_DO1 ;AN029; 327 <1> pop di ;AN029; 328 <1> pop dx ;AN029; 329 <1> pop cx ;AN029; 330 <1> 331 <1> ;NOW THAT ALL WHITESPACE SURROUNDING "=" HAVE BEEN COMPRESSED OUT, 332 <1> ;RESUME NORMAL PARSING... 333 <1> %ENDIF ;AN029; KEYWORDS SUPPORTED? 0 000016E9 E89405 call D_P_Skip_Delim ;AN000; Move si to 1st non white space 0 000016EC 7313 jnc D_P_Start ;AN000; If EOL is not encountered, do parse 336 <1> 337 <1> ;--------------------------- End of Line 0 000016EE B8FFFF mov ax,D_P_RC_EOL ;AN000; set exit code to -1 0 000016F1 53 push bx ;AN000; 0 000016F2 268B1D mov bx,[es:di + D_P_PARMSX_Address] ;AN000; Get the PARMSX address to 0 000016F5 263A0F cmp cl,[es:bx + D_P_MinP] ;AN000; check ORDINAL to see if the minimum 0 000016F8 7303 jae D_P_Fin ;AN000; positional found. 343 <1> 0 000016FA B80200 mov ax,D_P_Op_Missing ;AN000; If no, set exit code to missing operand 345 <1> D_P_Fin: ;AN000; 0 000016FD 5B pop bx ;AN000; 0 000016FE E91D01 jmp D_P_Single_Exit ;AN000; return to the caller 348 <1> 349 <1> ;--------------------------- 350 <1> D_P_Start: ;AN000; 0 00001701 2E8936[3708] mov [psdata_seg:D_P_SaveSI_Cmpx],si ;AN000;AC034; save ptr to command line for later use by complex, 0 00001706 53 push bx ;AN000; quoted string or file spec. 0 00001707 57 push di ;AN000; 0 00001708 55 push bp ;AN000; 0 00001709 8D1E[3F08] lea bx,[D_P_STRING_BUF] ;AC034; set buffer to copy from command string 0 0000170D 2EF606[3608]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; 3/9 extra delimiter encountered ? 0 00001713 7543 jne D_P_Pack_End ;AN000; 3/9 if yes, no need to copy 358 <1> 359 <1> D_P_Pack_Loop: ;AN000; 0 00001715 AC lodsb ;AN000; Pick a operand from buffer 0 00001716 E82406 call D_P_Chk_Switch ;AN000; Check switch character 0 00001719 723C jc D_P_Pack_End_BY_EOL ;AN020; if carry set found delimiter type slash, need backup si, else continue 363 <1> 0 0000171B E88805 call D_P_Chk_EOL ;AN000; Check EOL character 0 0000171E 7437 je D_P_Pack_End_BY_EOL ;AN000; need backup si 366 <1> 0 00001720 E8B905 call D_P_Chk_Delim ;AN000; Check delimiter 0 00001723 7518 jne D_P_PL01 ;AN000; If no, process next byte 369 <1> 0 00001725 2EF606[3608]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; 3/9 If yes and white spec, 371 <1> ; (tm08)jne D_P_Pack_End ;AN000; 3/9 then 372 <1> D_P_Pack_End_backup_si equ D_P_PAck_End_backup_si ; NASM port label 0 0000172B 7505 jne D_P_Pack_End_backup_si ;AN000; (tm08) 374 <1> 0 0000172D E85005 call D_P_Skip_Delim ;AN000; skip subsequent white space,too 0 00001730 EB26 jmp short D_P_Pack_End ;AN000; finish copy by placing NUL at end 377 <1> 378 <1> D_P_PAck_End_backup_si: ;AN000; (tm08) 0 00001732 2EF606[3608]41 test byte [psdata_seg:D_P_Flags2],D_P_SW+D_P_equ ;AN000;AC034; (tm08) 0 00001738 741E je D_P_Pack_End ;AN000; (tm08) 381 <1> 0 0000173A 4E dec si ;AN000; (tm08) 0 0000173B EB1B jmp short D_P_Pack_End ;AN025; (tm08) 384 <1> 385 <1> D_P_PL01: ;AN000; 0 0000173D 2E8807 mov [psdata_seg:bx],al ;AN000; move byte to STRING_BUF 0 00001740 3C3D cmp al,D_P_Keyword ;AN000; if it is equal character, 0 00001742 7506 jne D_P_PL00 ;AN000; then 389 <1> 0 00001744 2E800E[3608]01 or byte [psdata_seg:D_P_Flags2],D_P_equ ;AC034; remember it in flag 391 <1> D_P_PL00: ;AN000; 0 0000174A 43 inc bx ;AN000; ready to see next byte 0 0000174B E80D06 call D_P_Chk_DBCS ;AN000; was it 1st byte of DBCS ? 0 0000174E 73C5 jnc D_P_Pack_Loop ;AN000; if no, process to next byte 395 <1> 0 00001750 AC lodsb ;AN000; if yes, store 0 00001751 2E8807 mov [psdata_seg:bx],al ;AN000; 2nd byte of DBCS 0 00001754 43 inc bx ;AN000; update pointer 0 00001755 EBBE jmp short D_P_Pack_Loop ;AN000; process to next byte 400 <1> 401 <1> D_P_Pack_End_BY_EOL: ;AN000; 0 00001757 4E dec si ;AN000; backup si pointer 403 <1> D_P_Pack_End: ;AN000; 0 00001758 2E8936[2C08] mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 0 0000175D 2EC60700 mov byte ptr [psdata_seg:bx],D_P_NULL ;AN000; put NULL at the end 0 00001761 2E891E[3B08] mov [psdata_seg:D_P_Save_EOB],bx ;AC034; 3/17/87 keep the address for later use of complex 0 00001766 268B1D mov bx,[es:di + D_P_PARMSX_Address] ;AN000; get PARMSX address 0 00001769 8D36[3F08] lea si,[D_P_STRING_BUF] ;AC034; 0 0000176D 2E803C2F cmp byte ptr [psdata_seg:si],D_P_Switch ;AN000; the operand begins w/ switch char ? 0 00001771 7430 je D_P_SW_Manager ;AN000; if yes, process as switch 411 <1> 0 00001773 2EF606[3608]01 test byte [psdata_seg:D_P_Flags2],D_P_equ ;AC034; the operand includes equal char ? 413 <1> D_P_Key_manager equ D_P_Key_Manager ; NASM port label 0 00001779 7554 jne D_P_Key_manager ;AN000; if yes, process as keyword 415 <1> 416 <1> D_P_Positional_Manager: ;AN000; else process as positional 417 <1> D_P_MaxP equ D_P_Maxp ; NASM port equate 0 0000177B 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 0000177F 30E4 xor ah,ah ;AN000; ax = maxp 0 00001781 2E3906[2808] cmp [psdata_seg:D_P_ORDINAL],ax ;AC034; too many positional ? 0 00001786 7312 jae D_P_Too_Many_Error ;AN000; if yes, set exit code to too many 422 <1> 0 00001788 2EA1[2808] mov ax,[psdata_seg:D_P_ORDINAL] ;AC034; see what the current ordinal 0 0000178C D1E0 shl ax,1 ;AN000; ax = ax*2 0 0000178E 43 inc bx ;AC035; add '2' to 0 0000178F 43 inc bx ;AC035; BX reg 427 <1> ;AN000; now bx points to 1st CONTROL 428 <1> ;(changed ;AC035;) add bx,2 ;AN000; now bx points to 1st CONTROL 0 00001790 01C3 add bx,ax ;AN000; now bx points to specified CONTROL address 0 00001792 268B1F mov bx,[es:bx] ;AN000; now bx points to specified CONTROL itself 0 00001795 E88800 call D_P_Chk_Pos_Control ;AN000; Do process for positional 0 00001798 EB69 jmp short D_P_Return_to_Caller ;AN000; and return to the caller 433 <1> 434 <1> D_P_Too_Many_Error: ;AN000; 0 0000179A 2EC706[2A08]0100 mov word [psdata_seg:D_P_RC],D_P_Too_Many ;AC034; set exit code 0 000017A1 EB60 jmp short D_P_Return_to_Caller ;AN000; and return to the caller 437 <1> ; 438 <1> D_P_SW_Manager: ;AN000; 0 000017A3 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 000017A7 30E4 xor ah,ah ;AN000; ax = maxp 0 000017A9 40 inc ax ;AN000; 0 000017AA D1E0 shl ax,1 ;AN000; ax = (ax+1)*2 0 000017AC 01C3 add bx,ax ;AN000; now bx points to maxs 0 000017AE 268A0F mov cl,[es:bx] ;AN000; 0 000017B1 30ED xor ch,ch ;AN000; cx = maxs 0 000017B3 09C9 or cx,cx ;AN000; at least one switch ? 0 000017B5 740F je D_P_SW_Not_Found ;AN000; 448 <1> 0 000017B7 43 inc bx ;AN000; now bx points to 1st CONTROL address 450 <1> 451 <1> D_P_SW_Mgr_Loop: ;AN000; 0 000017B8 53 push bx ;AN000; 0 000017B9 268B1F mov bx,[es:bx] ;AN000; bx points to Switch CONTROL itself 0 000017BC E8C600 call D_P_Chk_SW_Control ;AN000; do process for switch 0 000017BF 5B pop bx ;AN000; 0 000017C0 7341 jnc D_P_Return_to_Caller ;AN000; if the CONTROL is for the switch, exit 457 <1> 0 000017C2 43 inc bx ;AC035; add '2' to 0 000017C3 43 inc bx ;AC035; BX reg 460 <1> ;AN000; else bx points to the next CONTROL 461 <1> ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL 0 000017C4 E2F2 loop D_P_SW_Mgr_Loop ;AN000; and loop 463 <1> 464 <1> D_P_SW_Not_Found: ;AN000; 0 000017C6 2EC706[2A08]0300 mov word [psdata_seg:D_P_RC],D_P_Not_In_SW ;AC034; here no CONTROL for the switch has 0 000017CD EB34 jmp short D_P_Return_to_Caller0 ;AN000; not been found, means error. 467 <1> ; 468 <1> D_P_Key_Manager: ;AN000; 0 000017CF 268A4701 mov al,[es:bx + D_P_MaxP] ;AN000; get maxp 0 000017D3 30E4 xor ah,ah ;AN000; ax = maxp 0 000017D5 40 inc ax ;AN000; 0 000017D6 D1E0 shl ax,1 ;AN000; ax = (ax+1)*2 0 000017D8 01C3 add bx,ax ;AN000; now bx points to maxs 0 000017DA 268A07 mov al,[es:bx] ;AN000; 0 000017DD 30E4 xor ah,ah ;AN000; ax = maxs 0 000017DF D1E0 shl ax,1 ;AN000; 0 000017E1 40 inc ax ;AN000; ax = ax*2+1 0 000017E2 01C3 add bx,ax ;AN000; now bx points to maxk 0 000017E4 268A0F mov cl,[es:bx] ;AN000; 0 000017E7 30ED xor ch,ch ;AN000; cx = maxk 0 000017E9 09C9 or cx,cx ;AN000; at least one keyword ? 0 000017EB 740F je D_P_Key_Not_Found ;AN000; 483 <1> 0 000017ED 43 inc bx ;AN000; now bx points to 1st CONTROL 485 <1> 486 <1> D_P_Key_Mgr_Loop: ;AN000; 0 000017EE 53 push bx ;AN000; 0 000017EF 268B1F mov bx,[es:bx] ;AN000; bx points to keyword CONTROL itself 0 000017F2 E85D00 call D_P_Chk_Key_Control ;AN000; do process for keyword 0 000017F5 5B pop bx ;AN000; 0 000017F6 730B jnc D_P_Return_to_Caller ;AN000; if the CONTROL is for the keyword, exit 492 <1> 0 000017F8 43 inc bx ;AC035; add '2' to 0 000017F9 43 inc bx ;AC035; BX reg 495 <1> ;AN000; else bx points to the next CONTROL 496 <1> ;(changed ;AC035;) add bx,2 ;AN000; else bx points to the next CONTROL 0 000017FA E2F2 loop D_P_Key_Mgr_Loop ;AN000; and loop 498 <1> 499 <1> D_P_Key_Not_Found: ;AN000; 0 000017FC 2EC706[2A08]0400 mov word [psdata_seg:D_P_RC],D_P_Not_In_Key ;AC034; here no CONTROL for the keyword has 501 <1> D_P_Return_to_Caller0: ;AN000; not been found, means error. 502 <1> 503 <1> ;(deleted ;AN024;) mov bx,[es:bx-2] ;AN000; (tm13) backup bx 504 <1> 505 <1> ;(deleted ;AN024;) mov al,D_P_String ;AN000; Set 506 <1> ;(deleted ;AN024;) mov ah,D_P_No_Tag ;AN000; result 507 <1> ;(deleted ;AN024;) call D_P_Fill_Result ;AN000; buffer 508 <1> 509 <1> D_P_Return_to_Caller: ;AN000; 0 00001803 5D pop bp ;AN000; 0 00001804 5F pop di ;AN000; 0 00001805 5B pop bx ;AN000; 513 <1> D_P_Ordinal equ D_P_ORDINAL ; NASM port label 0 00001806 2E8B0E[2808] mov cx,[psdata_seg:D_P_Ordinal] ;AC034; return next ordinal 0 0000180B 2EA1[2A08] mov ax,[psdata_seg:D_P_RC] ;AC034; return exit code 0 0000180F 2E8B36[2C08] mov si,[psdata_seg:D_P_SI_Save] ;AC034; return next operand pointer 0 00001814 2E8B16[2E08] mov dx,[psdata_seg:D_P_DX] ;AC034; return result buffer address 0 00001819 2E8A1E[3008] mov bl,[psdata_seg:D_P_Terminator] ;AC034; return delimiter code found 519 <1> D_P_Single_Exit: ;AN000; 0 0000181E F8 clc ;AN000; 0 0000181F C3 ret ;AN000; 522 <1> SysParse endp ;AN000; 523 <1> ;PAGE ;AN000; 524 <1> ;*********************************************************************** 525 <1> ; D_P_Chk_Pos_Control 526 <1> ; 527 <1> ; Function: Parse CONTROL block for a positional 528 <1> ; 529 <1> ; Input: ES:BX -> CONTROL block 530 <1> ; psdata_seg:SI -> D_P_STRING_BUF 531 <1> ; 532 <1> ; Output: None 533 <1> ; 534 <1> ; Use: D_P_Fill_Result, D_P_Check_Match_Flags 535 <1> ; 536 <1> ; Vars: D_P_Ordinal(W), D_P_RC(W) 537 <1> ;*********************************************************************** 538 <1> D_P_Chk_Pos_Control proc ;AN000; 0 00001820 50 push ax ;AN000; 0 00001821 268B07 mov ax,[es:bx + D_P_Match_Flag] ;AN000; 0 00001824 A90200 test ax,D_P_Repeat ;AN000; repeat allowed ? 0 00001827 7505 jne D_P_CPC00 ;AN000; then do not increment ORDINAL 543 <1> 0 00001829 2EFF06[2808] inc word [psdata_seg:D_P_ORDINAL] ;AC034; update the ordinal 545 <1> D_P_CPC00: ;AN000; 0 0000182E 2E803C00 cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; no data ? 0 00001832 7519 jne D_P_CPC01 ;AN000; 548 <1> 0 00001834 A90100 test ax,D_P_Optional ;AN000; yes, then is it optional ? 0 00001837 7509 jne D_P_CPC02 ;AN000; 551 <1> 0 00001839 2EC706[2A08]0200 mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; no, then error 3/17/87 0 00001840 EB0E jmp short D_P_CPC_Exit ;AN000; 554 <1> 555 <1> D_P_CPC02: ;AN000; 0 00001842 50 push ax ;AN000; 0 00001843 B003 mov al,D_P_String ;AN000; if it is optional return NULL 0 00001845 B4FF mov ah,D_P_No_Tag ;AN000; no item tag indication 0 00001847 E89E00 call D_P_Fill_Result ;AN000; 0 0000184A 58 pop ax ;AN000; 0 0000184B EB03 jmp short D_P_CPC_Exit ;AN000; 562 <1> 563 <1> D_P_CPC01: ;AN000; 0 0000184D E81D01 call D_P_Check_Match_Flags ;AN000; 565 <1> D_P_CPC_Exit: ;AN000; 0 00001850 58 pop ax ;AN000; 0 00001851 C3 ret ;AN000; 568 <1> D_P_Chk_Pos_Control endp ;AN000; 569 <1> ;PAGE ;AN000; 570 <1> ;*********************************************************************** 571 <1> ; D_P_Chk_Key_Control 572 <1> ; 573 <1> ; Function: Parse CONTROL block for a keyword 574 <1> ; 575 <1> ; Input: ES:BX -> CONTROL block 576 <1> ; psdata_seg:SI -> D_P_STRING_BUF 577 <1> ; 578 <1> ; Output: CY = 1 : not match 579 <1> ; 580 <1> ; Use: D_P_Fill_Result, D_P_Search_KEYorSW, D_P_Check_Match_Flags 581 <1> ; 582 <1> ; Vars: D_P_RC(W), D_P_SaveSI_Cmpx(W), D_P_KEYorSW_Ptr(R), D_P_Flags(W) 583 <1> ;*********************************************************************** 584 <1> D_P_Chk_Key_Control proc ;AN000; 585 <1> %IF KeySW ;AN000;(Check if keyword is supported) 586 <1> or byte [psdata_seg:D_P_Flags2],D_P_Key_Cmp ;AC034; Indicate keyword for later string comparison 587 <1> call D_P_Search_KEYorSW ;AN000; Search the keyword in the CONTROL block 588 <1> jc D_P_Chk_Key_Err0 ;AN000; not found, then try next CONTROL 589 <1> 590 <1> and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Key_Cmp ;AC034; reset the indicator previously set 591 <1> ; 592 <1> push ax ;AN000; keyword= 593 <1> mov ax,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; ^ ^ 594 <1> sub ax,si ;AN000; SI KEYorSW 595 <1> add [psdata_seg:D_P_SaveSI_Cmpx],ax ;AC034; update for complex, quoted or file spec. 596 <1> pop ax ;AN000; 597 <1> ; 598 <1> mov si,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; set si just after equal char 599 <1> cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; any data after equal ? 600 <1> je D_P_Chk_Key_Err1 ;AN000; if no, syntax error 601 <1> 602 <1> call D_P_Check_Match_Flags ;AN000; else, process match flags 603 <1> clc ;AN000; 604 <1> jmp short D_P_Chk_Key_Exit ;AN000; 605 <1> 606 <1> D_P_Chk_Key_Err0: ;AN000; 607 <1> stc ;AN000; not found in keyword synonym list 608 <1> jmp short D_P_Chk_Key_Exit ;AN000; 609 <1> 610 <1> D_P_Chk_Key_Err1: ;AN000; 611 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; no parameter is not specified after "=" 612 <1> D_P_Chk_Key_ErrExit: ;AN000; 613 <1> push ax ;AN000; 614 <1> mov al,D_P_String ;AN000; set 615 <1> mov ah,D_P_No_Tag ;AN000; result 616 <1> call D_P_Fill_Result ;AN000; buffer 617 <1> pop ax ;AN000; 618 <1> clc ;AN000; 619 <1> D_P_Chk_Key_Exit: ;AN000; 620 <1> ret ;AN000; 621 <1> %ELSE ;AN000;(of IF KeySW) 0 00001852 F9 stc ;AN000;this logic works when the KeySW 0 00001853 C3 ret ;AN000;is reset. 624 <1> %ENDIF ;AN000;(of KeySW) 625 <1> D_P_Chk_Key_Control endp ;AN000; 626 <1> ;PAGE ;AN000; 627 <1> ;*********************************************************************** 628 <1> %IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) 629 <1> ; D_P_Search_KEYorSW: 630 <1> ; 631 <1> ; Function: Seach specified keyword or switch from CONTROL 632 <1> ; 633 <1> ; Input: ES:BX -> CONTROL block 634 <1> ; psdata_seg:SI -> D_P_STRING_BUF 635 <1> ; 636 <1> ; Output: CY = 1 : not match 637 <1> ; 638 <1> ; Use: D_P_String_Comp, D_P_MoveBP_NUL, D_P_Found_SYNONYM 639 <1> ;*********************************************************************** 640 <1> D_P_Search_KEYorSW proc ;AN000; 0 00001854 55 push bp ;AN000; 0 00001855 51 push cx ;AN000; 0 00001856 268A4F08 mov cl,[es:bx + D_P_nid] ;AN000; Get synonym count 0 0000185A 30ED xor ch,ch ;AN000; and set it to cx 0 0000185C 09C9 or cx,cx ;AN000; No synonyms specified ? 0 0000185E 740D je D_P_KEYorSW_Not_Found ;AN000; then indicate not found by CY 647 <1> 648 <1> D_P_KEYorSW equ D_P_KeyorSW ; NASM port equate 0 00001860 8D6F09 lea bp,[bx + D_P_KEYorSW] ;AN000; BP points to the 1st synonym 650 <1> D_P_KEYorSW_Loop: ;AN000; 0 00001863 E87703 call D_P_String_Comp ;AN000; compare string in buffer w/ the synonym 0 00001866 7308 jnc D_P_KEYorSW_Found ;AN000; If match, set it to synonym pointer 653 <1> 0 00001868 E80E00 call D_P_MoveBP_NUL ;AN000; else, bp points to the next string 0 0000186B E2F6 loop D_P_KEYorSW_Loop ;AN000; loop nid times 656 <1> D_P_KEYorSW_Not_Found: ;AN000; 0 0000186D F9 stc ;AN000; indicate not found in synonym list 0 0000186E EB06 jmp short D_P_KEYorSW_Exit ;AN000; and exit 659 <1> 660 <1> D_P_KEYorSW_Found: ;AN000; 0 00001870 2E892E[3D08] mov [psdata_seg:D_P_Found_SYNONYM],bp ;AC034; set synonym pointer 0 00001875 F8 clc ;AN000; indicate found 663 <1> D_P_KEYorSW_Exit: ;AN000; 0 00001876 59 pop cx ;AN000; 0 00001877 5D pop bp ;AN000; 0 00001878 C3 ret ;AN000; 667 <1> D_P_Search_KEYorSW endp ;AN000; 668 <1> ;*********************************************************************** 669 <1> ; D_P_MoveBP_NUL 670 <1> ;*********************************************************************** 671 <1> D_P_MoveBP_NUL proc ;AN000; 672 <1> D_P_MBP_Loop: ;AN000; 0 00001879 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000; Increment BP that points 0 0000187E 7403 je D_P_MBP_Exit ;AN000; to the synomym list 675 <1> 0 00001880 45 inc bp ;AN000; until 0 00001881 EBF6 jmp short D_P_MBP_Loop ;AN000; NULL encountered. 678 <1> 679 <1> D_P_MBP_Exit: ;AN000; 0 00001883 45 inc bp ;AN000; bp points to next to NULL 0 00001884 C3 ret ;AN000; 682 <1> D_P_MoveBP_NUL endp ;AN000; 683 <1> %ENDIF ;AN000;(of KeySW+SwSW) 684 <1> ;PAGE ;AN000; 685 <1> ;*********************************************************************** 686 <1> ; D_P_Chk_SW_Control 687 <1> ; 688 <1> ; Function: Parse CONTROL block for a switch 689 <1> ; 690 <1> ; Input: ES:BX -> CONTROL block 691 <1> ; psdata_seg:SI -> D_P_STRING_BUF 692 <1> ; 693 <1> ; Output: CY = 1 : not match 694 <1> ; 695 <1> ; Use: D_P_Fill_Result, D_P_Search_KEYorSW, D_P_Check_Match_Flags 696 <1> ; 697 <1> ; Vars: D_P_SaveSI_Cmpx(W), D_P_KEYorSW_Ptr(R), D_P_Flags(W) 698 <1> ;*********************************************************************** 699 <1> D_P_Chk_SW_Control proc ;AN000; 700 <1> 701 <1> 702 <1> %IF SwSW ;AN000;(Check if switch is supported) 703 <1> D_P_Sw_Cmp equ D_P_SW_Cmp ; NASM port equate 0 00001885 2E800E[3608]10 or byte [psdata_seg:D_P_Flags2],D_P_Sw_Cmp ;AC034; Indicate switch for later string comparison 0 0000188B E8C6FF call D_P_Search_KEYorSW ;AN000; Search the switch in the CONTROL block 0 0000188E 724A jc D_P_Chk_SW_Err0 ;AN000; not found, then try next CONTROL 707 <1> 0 00001890 2E8026[3608]EF and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Sw_Cmp ;AC034; reset the indicator previously set 709 <1> ; 0 00001896 50 push ax ;AN000; /switch: 0 00001897 2EA1[3908] mov ax,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; ^ ^ 0 0000189B 29F0 sub ax,si ;AN000; SI KEYorSW 0 0000189D 2E0106[3708] add [psdata_seg:D_P_SaveSI_Cmpx],ax ;AC034; update for complex list 0 000018A2 58 pop ax ;AN000; 715 <1> ; 0 000018A3 2E8B36[3908] mov si,[psdata_seg:D_P_KEYorSW_Ptr] ;AC034; set si at the end or colon 0 000018A8 2E803C00 cmp byte ptr [psdata_seg:si],D_P_NULL ;AN000; any data after colon 0 000018AC 7526 jne D_P_CSW00 ;AN000; if yes, process match flags 719 <1> 0 000018AE 2E807CFF3A cmp byte ptr [psdata_seg:si-1],D_P_Colon ;AN000; if no, the switch terminated by colon ? 0 000018B3 7509 jne D_P_Chk_if_data_required ;AN000; if yes, 722 <1> 0 000018B5 2EC706[2A08]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; return syntax error 0 000018BC EB1F jmp short D_P_Chk_SW_Exit ;AN000; 725 <1> 726 <1> D_P_Chk_if_data_required: ;AN018; no data, no colon 0 000018BE 26833F00 cmp word [es:bx + D_P_Match_Flag],0 ;AN018; should have data? zero match flag means switch followed by nothing is OK 0 000018C2 7419 je D_P_Chk_SW_Exit ;AN018; match flags not zero so should have something if optional bit is not on 729 <1> 0 000018C4 26F7070100 test word [es:bx + D_P_Match_Flag],D_P_Optional ;AN019; see if no value is valid 0 000018C9 7512 jnz D_P_Chk_SW_Exit ;AN019; if so, then leave, else yell 732 <1> 0 000018CB 2EC706[2A08]0200 mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; return required operand missing 0 000018D2 EB09 jmp short D_P_Chk_SW_Exit ;AN018; 735 <1> 736 <1> D_P_CSW00: ;AN000; 0 000018D4 E89600 call D_P_Check_Match_Flags ;AN000; process match flag 0 000018D7 F8 clc ;AN000; indicate match 0 000018D8 EB0D jmp short D_P_Chk_SW_Single_Exit ;AN000; 740 <1> 741 <1> D_P_Chk_SW_Err0: ;AN000; 0 000018DA F9 stc ;AN000; not found in switch synonym list 0 000018DB EB0A jmp short D_P_Chk_SW_Single_Exit ;AN000; 744 <1> 745 <1> D_P_Chk_SW_Exit: ;AN000; 0 000018DD 50 push ax ;AN000; 0 000018DE B003 mov al,D_P_String ;AN000; set 0 000018E0 B4FF mov ah,D_P_No_Tag ;AN000; result 0 000018E2 E80300 call D_P_Fill_Result ;AN000; buffer 0 000018E5 58 pop ax ;AN000; 0 000018E6 F8 clc ;AN000; 752 <1> D_P_Chk_SW_Single_Exit: ;AN000; 0 000018E7 C3 ret ;AN000; 754 <1> %ELSE ;AN000;(of IF SwSW) 755 <1> stc ;AN000; this logic works when the SwSW 756 <1> ret ;AN000; is reset. 757 <1> %ENDIF ;AN000;(of SwSW) 758 <1> D_P_Chk_SW_Control endp ;AN000; 759 <1> ;PAGE ;AN000; 760 <1> ;*********************************************************************** 761 <1> ; D_P_Fill_Result 762 <1> ; 763 <1> ; Function: Fill the result buffer 764 <1> ; 765 <1> ; Input: AH = Item tag 766 <1> ; AL = type 767 <1> ; AL = 1: CX,DX has 32bit number (CX = high) 768 <1> ; AL = 2: DX has index(offset) into value list 769 <1> ; AL = 6: DL has driver # (1-A, 2-B, ... , 26 - Z) 770 <1> ; AL = 7: DX has year, CL has month and CH has date 771 <1> ; AL = 8: DL has hours, DH has minutes, CL has secondsn, 772 <1> ; amd CH has hundredths 773 <1> ; AL = else: psdata_seg:SI points to returned string buffer 774 <1> ; ES:BX -> CONTROL block 775 <1> ; 776 <1> ; Output: None 777 <1> ; 778 <1> ; Use: D_P_Do_CAPS_String, D_P_Remove_Colon, D_P_Found_SYNONYM 779 <1> ; 780 <1> ; Vars: D_P_DX(W) 781 <1> ;*********************************************************************** 782 <1> D_P_Fill_Result proc ;AN000; 0 000018E8 57 push di ;AN000; 0 000018E9 268B7F04 mov di,[es:bx + D_P_Result_Buf] ;AN000; di points to result buffer 0 000018ED 2E893E[2E08] mov [psdata_seg:D_P_DX],di ;AC034; set returned result address 0 000018F2 268805 mov [es:di + D_P_Type],al ;AN000; store type 0 000018F5 26886501 mov [es:di + D_P_Item_Tag],ah ;AN000; store item tag 0 000018F9 50 push ax ;AN000; 0 000018FA 2EA1[3D08] mov ax,[psdata_seg:D_P_Found_SYNONYM] ;AC034; if yes, 0 000018FE 26894502 mov [es:di + D_P_SYNONYM_Ptr],ax ;AN000; then set it to the result 0 00001902 58 pop ax ;AN000; 792 <1> D_P_RLT04: ;AN000; 0 00001903 3C01 cmp al,D_P_Number ;AN000; if number 0 00001905 750A jne D_P_RLT00 ;AN000; 795 <1> 796 <1> D_P_RLT02: ;AN000; 0 00001907 26895504 mov word ptr [es:di + D_P_Picked_Val],dx ;AN000; then store 32bit 0 0000190B 26894D06 mov word ptr [es:di+2 + D_P_Picked_Val],cx ;AN000; number 0 0000190F EB5A jmp short D_P_RLT_Exit ;AN000; 800 <1> 801 <1> D_P_RLT00: ;AN000; 0 00001911 3C02 cmp al,D_P_List_Idx ;AN000; if list index 0 00001913 7506 jne D_P_RLT01 ;AN000; 804 <1> 0 00001915 26895504 mov word ptr [es:di + D_P_Picked_Val],dx ;AN000; then store list index 0 00001919 EB50 jmp short D_P_RLT_Exit ;AN000; 807 <1> 808 <1> D_P_RLT01: ;AN000; 0 0000191B 3C07 cmp al,D_P_Date_F ;AN000; Date format ? 0 0000191D 74E8 je D_P_RLT02 ;AN000; 811 <1> 0 0000191F 3C08 cmp al,D_P_Time_F ;AN000; Time format ? 0 00001921 74E4 je D_P_RLT02 ;AN000; 814 <1> ; 0 00001923 3C06 cmp al,D_P_Drive ;AN000; drive format ? 0 00001925 7506 jne D_P_RLT03 ;AN000; 817 <1> 0 00001927 26885504 mov byte ptr [es:di + D_P_Picked_Val],dl ;AN000; store drive number 0 0000192B EB3E jmp short D_P_RLT_Exit ;AN000; 820 <1> 821 <1> D_P_RLT03: ;AN000; 0 0000192D 3C04 cmp al,D_P_Complex ;AN000; complex format ? 0 0000192F 750F jne D_P_RLT05 ;AN000; 824 <1> 0 00001931 2EA1[3708] mov ax,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; then get pointer in command buffer 0 00001935 40 inc ax ;AN000; skip left Parentheses 0 00001936 26894504 mov word ptr [es:di + D_P_Picked_Val],ax ;AN000; store offset 0 0000193A 268C5D06 mov word ptr [es:di+2 + D_P_Picked_Val],ds ;AN000; store segment 0 0000193E EB2B jmp short D_P_RLT_Exit ;AN000; 830 <1> 831 <1> D_P_RLT05: ;AN000; 832 <1> ;------------------------ AL = 3, 5, or 9 0 00001940 26897504 mov word ptr [es:di + D_P_Picked_Val],si ;AN000; store offset of STRING_BUF 834 <1> ;(replaced ;AN031;) mov word ptr [es:di+word].D_P_Picked_Val,cs ;AN000; store segment of STRING_BUF 0 00001944 268C4D06 mov word ptr [es:di+2 + D_P_Picked_Val],Psdata_Seg ;AN031; store segment of STRING_BUF 836 <1> ; 0 00001948 50 push ax ;AN000; 0 00001949 26F6470201 test byte ptr [es:bx + D_P_Function_Flag],D_P_CAP_File ;AN000; need CAPS by file table? 0 0000194E 7404 je D_P_RLT_CAP00 ;AN000; 840 <1> 0 00001950 B004 mov al,D_P_DOSTBL_File ;AN000; use file upper case table 0 00001952 EB09 jmp short D_P_RLT_CAP02 ;AN000; 843 <1> 844 <1> D_P_RLT_CAP00: ;AN000; 0 00001954 26F6470202 test byte ptr [es:bx + D_P_Function_Flag],D_P_CAP_Char ;AN000; need CAPS by char table ? 0 00001959 7405 je D_P_RLT_CAP01 ;AN000; 847 <1> 0 0000195B B002 mov al,D_P_DOSTBL_Char ;AN000; use character upper case table 849 <1> D_P_RLT_CAP02: ;AN000; 0 0000195D E8B400 call D_P_Do_CAPS_String ;AN000; process CAPS along the table 851 <1> D_P_RLT_CAP01: ;AN000; 0 00001960 58 pop ax ;AN000; 0 00001961 26F6470210 test byte ptr [es:bx + D_P_Function_Flag],D_P_Rm_Colon ;AN000; removing colon at end ? 0 00001966 7403 je D_P_RLT_Exit ;AN000; 855 <1> 0 00001968 E88300 call D_P_Remove_Colon ;AN000; then process it. 857 <1> D_P_RLT_Exit: ;AN000; 0 0000196B 5F pop di ;AN000; 0 0000196C C3 ret ;AN000; 860 <1> D_P_Fill_Result endp ;AN000; 861 <1> ;PAGE ;AN000; 862 <1> ;*********************************************************************** 863 <1> ; D_P_Check_Match_Flags 864 <1> ; 865 <1> ; Function: Check the mutch_flags and make the exit code and set the 866 <1> ; result buffer 867 <1> ; 868 <1> ; Check for types in this order: 869 <1> ; Complex 870 <1> ; Date 871 <1> ; Time 872 <1> ; Drive 873 <1> ; Filespec 874 <1> ; Quoted String 875 <1> ; Simple String 876 <1> ; 877 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 878 <1> ; ES:BX -> CONTROL block 879 <1> ; 880 <1> ; Output: None 881 <1> ; 882 <1> ; Use: D_P_Value, P$_SValue, D_P_Simple_String, D_P_Date_Format 883 <1> ; D_P_Time_Format, D_P_Complex_Format, D_P_File_Foemat 884 <1> ; D_P_Drive_Format 885 <1> ;*********************************************************************** 886 <1> D_P_Check_Match_Flags proc ;AN000; 0 0000196D 2EC606[C908]00 mov byte [psdata_seg:D_P_err_flag],D_P_NULL ;AN033;AC034;; clear filespec error flag. 0 00001973 50 push ax ;AN000; 0 00001974 268B07 mov ax,[es:bx + D_P_Match_Flag] ;AN000; load match flag(16bit) to ax 890 <1> 0 00001977 09C0 or ax,ax ;AC035; test ax for zero 892 <1> ;(changed ;AC035;) cmp ax,0 ;AN000; (tm12) 0 00001979 7518 jne D_P_Mat ;AN000; (tm12) 894 <1> 0 0000197B 50 push ax ;AN000; (tm12) 0 0000197C 53 push bx ;AN000; (tm12) 0 0000197D 52 push dx ;AN000; (tm12) 0 0000197E 57 push di ;AN000; (tm12) 0 0000197F 2EC706[2A08]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; (tm12) 0 00001986 B4FF mov ah,D_P_No_Tag ;AN000; (tm12) 0 00001988 B003 mov al,D_P_String ;AN000; (tm12) 0 0000198A E85BFF call D_P_Fill_Result ;AN000; (tm12) 0 0000198D 5F pop di ;AN000; (tm12) 0 0000198E 5A pop dx ;AN000; (tm12) 0 0000198F 5B pop bx ;AN000; (tm12) 0 00001990 58 pop ax ;AN000; (tm12) 0 00001991 EB02 jmp short D_P_Bridge ;AC035; (tm12) 908 <1> 909 <1> D_P_Mat: ;AN000; (tm12) 910 <1> 911 <1> %IF CmpxSW ;AN000;(Check if complex item is supported) 912 <1> test ax,D_P_Cmpx_S ;AN000; Complex string 913 <1> je D_P_Match01 ;AN000; 914 <1> 915 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 916 <1> call D_P_Complex_Format ;AN000; do process 917 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 918 <1> jne D_P_Bridge ;AN000; 919 <1> 920 <1> D_P_Match01: ;AN000; 921 <1> %ENDIF ;AN000;(of CmpxSW) 922 <1> %IF DateSW ;AN000;(Check if date format is supported) 923 <1> test ax,D_P_Date_S ;AN000; Date string 924 <1> je D_P_Match02 ;AN000; 925 <1> 926 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 927 <1> call D_P_Date_Format ;AN000; do process 928 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 929 <1> jne D_P_Bridge ;AN000; 930 <1> 931 <1> D_P_Match02: ;AN000; 932 <1> %ENDIF ;AN000;(of DateSW) 933 <1> %IF TimeSW ;AN000;(Check if time format is supported) 934 <1> test ax,D_P_Time_S ;AN000; Time string 935 <1> je D_P_Match03 ;AN000; 936 <1> 937 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 938 <1> call D_P_Time_Format ;AN000; do process 939 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 940 <1> ; je D_P_Match03 ;AN000: 941 <1> 942 <1> jne D_P_Bridge ;AN000; (tm09) 943 <1> 944 <1> %ENDIF ;AN000;(of TimeSW) (tm04) 0 00001993 EB03 jmp short D_P_Match03 ;AN025; (tm09) 946 <1> 947 <1> D_P_Bridge: ;AN000; 948 <1> ; jmp short D_P_Match_Exit (tm02) 949 <1> 0 00001995 EB3E jmp D_P_Match_Exit ;AN000; (tm02) 0 00001997 90 nop ; identicalise 952 <1> 953 <1> D_P_Match03: ;AN000; 954 <1> ; ENDIF ;AN000;(of TimeSW) (tm04) 955 <1> %IF NumSW ;AN000;(Check if numeric value is supported) 0 00001998 A90080 test ax,D_P_Num_Val ;AN000; Numeric value 0 0000199B 7412 je D_P_Match04 ;AN000; 958 <1> 0 0000199D 2EC706[2A08]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 000019A4 E8FE00 call D_P_Value ;AN000; do process 0 000019A7 2E833E[2A08]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 0 000019AD 7526 jne D_P_Match_Exit ;AN000; 963 <1> 964 <1> D_P_Match04: ;AN000; 965 <1> D_P_SNUM_Val equ D_P_SNum_Val ; NASM port equate 0 000019AF A90040 test ax,D_P_SNUM_Val ;AN000; Signed numeric value 0 000019B2 7412 je D_P_Match05 ;AN000; 968 <1> 0 000019B4 2EC706[2A08]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 000019BB E8C300 call D_P_SValue ;AN000; do process 0 000019BE 2E833E[2A08]09 cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 0 000019C4 750F jne D_P_Match_Exit ;AN000; 973 <1> 974 <1> D_P_Match05: ;AN000; 975 <1> %ENDIF ;AN000;(of NumSW) 976 <1> %IF DrvSW ;AN000;(Check if drive only is supported) 977 <1> test ax,D_P_Drv_Only ;AN000; Drive only 978 <1> je D_P_Match06 ;AN000; 979 <1> 980 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 981 <1> call D_P_File_Format ;AN000; 1st, call file format 982 <1> call D_P_Drive_Format ;AN000; check drive format, next 983 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examinee the next type 984 <1> jne D_P_Match_Exit ;AN000; 985 <1> 986 <1> D_P_Match06: ;AN000; 987 <1> %ENDIF ;AN000;(of DrvSW) 988 <1> %IF FileSW ;AN000;(Check if file spec is supported) 989 <1> test ax,D_P_File_Spc ;AN000; File spec 990 <1> je D_P_Match07 ;AN000; 991 <1> 992 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 993 <1> call D_P_File_Format ;AN000; do process 994 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 995 <1> jne D_P_Match_Exit ;AN000; 996 <1> 997 <1> D_P_Match07: ;AN000; 998 <1> %ENDIF ;AN000;(of FileSW) 999 <1> %IF QusSW ;AN000;(Check if quoted string is supported) 1000 <1> test ax,D_P_Qu_String ;AN000; Quoted string 1001 <1> je D_P_Match08 ;AN000; 1002 <1> 1003 <1> mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 1004 <1> call D_P_Quoted_Format ;AN000; do process 1005 <1> cmp word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; if error, examine the next type 1006 <1> jne D_P_Match_Exit ;AN000; 1007 <1> 1008 <1> D_P_Match08: ;AN000; 1009 <1> %ENDIF ;AN000;(of QusSW) 0 000019C6 A90020 test ax,D_P_Simple_S ;AN000; Simple string 0 000019C9 740A je D_P_Match09 ;AN000; 1012 <1> 0 000019CB 2EC706[2A08]0000 mov word [psdata_seg:D_P_RC],D_P_No_Error ;AC034; assume no error 0 000019D2 E8E201 call D_P_Simple_String ;AN000; do process 1015 <1> ;;;; cmp psdata_seg:D_P_RC,D_P_Syntax ;AC034; These two lines will be alive 1016 <1> ;;;; jne D_P_Match_Exit ;when extending the match_flags. 1017 <1> D_P_Match09: ;AN000; 1018 <1> D_P_Match_Exit: ;AN000; 0 000019D5 2E803E[C908]01 cmp byte [psdata_seg:D_P_err_flag],D_P_error_filespec ;AC034; bad filespec ? 0 000019DB 750F jne D_P_Match2_Exit ;AN033; no, continue 0 000019DD 2E833E[2A08]00 cmp word [psdata_seg:D_P_RC],D_P_No_Error ;AN033;AC034;; check for other errors ? 0 000019E3 7507 jne D_P_Match2_Exit ;AN033; no, continue 0 000019E5 2EC706[2A08]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AN033;AC034;; set error flag 1024 <1> D_P_Match2_Exit: ;AN033; 0 000019EC 58 pop ax ;AN000; 0 000019ED C3 ret ;AN000; 1027 <1> D_P_Check_Match_Flags endp ;AN000; 1028 <1> ;PAGE ;AN000; 1029 <1> ;*********************************************************************** 1030 <1> ; D_P_Remove_Colon; 1031 <1> ; 1032 <1> ; Function: Remove colon at end 1033 <1> ; 1034 <1> ; Input: psdata_seg:SI points to string buffer to be examineed 1035 <1> ; 1036 <1> ; Output: None 1037 <1> ; 1038 <1> ; Use: D_P_Chk_DBCS 1039 <1> ;*********************************************************************** 1040 <1> D_P_Remove_Colon proc ;AN000; 0 000019EE 50 push ax ;AN000; 0 000019EF 56 push si ;AN000; 1043 <1> D_P_RCOL_Loop: ;AN000; 0 000019F0 2E8A04 mov al,[psdata_seg:si] ;AN000; get character 0 000019F3 08C0 or al,al ;AN000; end of string ? 0 000019F5 741A je D_P_RCOL_Exit ;AN000; if yes, just exit 1047 <1> 0 000019F7 3C3A cmp al,D_P_Colon ;AN000; is it colon ? 0 000019F9 750D jne D_P_RCOL00 ;AN000; 1050 <1> 0 000019FB 2E807C0100 cmp byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; if so, next is NULL ? 0 00001A00 7506 jne D_P_RCOL00 ;AN000; no, then next char 1053 <1> 0 00001A02 2EC60400 mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; yes, remove colon 0 00001A06 EB09 jmp short D_P_RCOL_Exit ;AN000; and exit. 1056 <1> 1057 <1> D_P_RCOL00: ;AN000; 0 00001A08 E85003 call D_P_Chk_DBCS ;AN000; if not colon, then check if 0 00001A0B 7301 jnc D_P_RCOL01 ;AN000; DBCS leading byte. 1060 <1> 0 00001A0D 46 inc si ;AN000; if yes, skip trailing byte 1062 <1> D_P_RCOL01: ;AN000; 0 00001A0E 46 inc si ;AN000; si points to next byte 0 00001A0F EBDF jmp short D_P_RCOL_Loop ;AN000; loop until NULL encountered 1065 <1> 1066 <1> D_P_RCOL_Exit: ;AN000; 0 00001A11 5E pop si ;AN000; 0 00001A12 58 pop ax ;AN000; 0 00001A13 C3 ret ;AN000; 1070 <1> D_P_Remove_Colon endp ;AN000; 1071 <1> ;PAGE ;AN000; 1072 <1> ;*********************************************************************** 1073 <1> ; D_P_Do_CAPS_String; 1074 <1> ; 1075 <1> ; Function: Perform capitalization along with the file case map table 1076 <1> ; or character case map table. 1077 <1> ; 1078 <1> ; Input: AL = 2 : Use character table 1079 <1> ; AL = 4 : Use file table 1080 <1> ; psdata_seg:SI points to string buffer to be capitalized 1081 <1> ; 1082 <1> ; Output: None 1083 <1> ; 1084 <1> ; Use: D_P_Do_CAPS_Char, D_P_Chk_DBCS 1085 <1> ;*********************************************************************** 1086 <1> D_P_Do_CAPS_String proc ;AN000; 0 00001A14 56 push si ;AN000; 0 00001A15 52 push dx ;AN000; 0 00001A16 88C2 mov dl,al ;AN000; save info id 1090 <1> 1091 <1> D_P_DCS_Loop: ;AN000; 0 00001A18 2E8A04 mov al,[psdata_seg:si] ;AN000; load charater and 0 00001A1B E83D03 call D_P_Chk_DBCS ;AN000; check if DBCS leading byte 0 00001A1E 720C jc D_P_DCS00 ;AN000; if yes, do not need CAPS 1095 <1> 0 00001A20 08C0 or al,al ;AN000; end of string ? 0 00001A22 740C je D_P_DCS_Exit ;AN000; then exit. 1098 <1> 0 00001A24 E80C00 call D_P_Do_CAPS_Char ;AN000; Here a SBCS char need to be CAPS 0 00001A27 2E8804 mov [psdata_seg:si],al ;AN000; stored upper case char to buffer 0 00001A2A EB01 jmp short D_P_DCS01 ;AN000; process nexit 1102 <1> D_P_DCS00: ;AN000; 0 00001A2C 46 inc si ;AN000; skip DBCS leading and trailing byte 1104 <1> D_P_DCS01: ;AN000; 0 00001A2D 46 inc si ;AN000; si point to next byte 0 00001A2E EBE8 jmp short D_P_DCS_Loop ;AN000; loop until NULL encountered 1107 <1> D_P_DCS_Exit: ;AN000; 0 00001A30 5A pop dx ;AN000; 0 00001A31 5E pop si ;AN000; 0 00001A32 C3 ret ;AN000; 1111 <1> D_P_Do_CAPS_String endp ;AN000; 1112 <1> ;PAGE ;AN000; 1113 <1> ;*********************************************************************** 1114 <1> ; D_P_Do_CAPS_Char; 1115 <1> ; 1116 <1> ; Function: Perform capitalization along with the file case map table 1117 <1> ; or character case map table. 1118 <1> ; 1119 <1> ; Input: DL = 2 : Use character table 1120 <1> ; DL = 4 : Use file table 1121 <1> ; AL = character to be capitalized 1122 <1> ; 1123 <1> ; Output: None 1124 <1> ; 1125 <1> ; Use: INT 21h /w AH=65h 1126 <1> ;*********************************************************************** 1127 <1> D_P_Do_CAPS_Char proc ;AN000; 0 00001A33 3C80 cmp al,D_P_ASCII80 ;AN000; need upper case table ? 0 00001A35 730C jae D_P_DCC_Go ;AN000; 1130 <1> 0 00001A37 3C61 cmp al,"a" ;AN000; if no, 0 00001A39 7245 jb D_P_CAPS_Ret ;AN000; check if "a" <= AL <= "z" 1133 <1> 0 00001A3B 3C7A cmp al,"z" ;AN000; 0 00001A3D 7741 ja D_P_CAPS_Ret ;AN000; if yes, make CAPS 1136 <1> 0 00001A3F 24DF and al,D_P_Make_Upper ;AN000; else do nothing. 0 00001A41 EB3D jmp short D_P_CAPS_Ret ;AN000; 1139 <1> 1140 <1> D_P_DCC_Go: ;AN000; 0 00001A43 53 push bx ;AN000; 0 00001A44 06 push es ;AN000; 0 00001A45 57 push di ;AN000; 1144 <1> %IF CAPSW ;AN000;(Check if uppercase conversion is supported) 0 00001A46 8D3E[C408] lea di,[D_P_File_CAP_Ptr] ;AC034; 0 00001A4A 80FA04 cmp dl,D_P_DOSTBL_File ;AN000; Use file CAPS table ? 0 00001A4D 7404 je D_P_DCC00 ;AN000; 1148 <1> 1149 <1> %ENDIF ;AN000;(of CAPSW) 0 00001A4F 8D3E[BF08] lea di,[D_P_Char_CAP_Ptr] ;AC034; or use char CAPS table ? 1151 <1> D_P_DCC00: ;AN000; 0 00001A53 2E3815 cmp [psdata_seg:di],dl ;AN000; already got table address ? 0 00001A56 7417 je D_P_DCC01 ;AN000; if no, 1154 <1> 1155 <1> ;In this next section, ES will be used to pass a 5 byte workarea to INT 21h, 1156 <1> ; the GET COUNTYRY INFO call. This usage of ES is required by the function 1157 <1> ; call, regardless of what base register is currently be defined as PSDATA_SEG. 1158 <1> ;BASESW EQU 0 means that ES is the psdata_seg reg. 1159 <1> 1160 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1161 <1> %IFN BASESW ;AN037; If ES is psdata base 1162 <1> push PSDATA_SEG ;AN037; save current base reg 1163 <1> %ENDIF ;AN037; 1164 <1> %ENDIF ;AN037; 1165 <1> 0 00001A58 50 push ax ;AN000; get CAPS table thru DOS call 0 00001A59 51 push cx ;AN000; 0 00001A5A 52 push dx ;AN000; 1169 <1> 1170 <1> 0 00001A5B 0E push PSDATA_SEG ;AC036; pass current base seg into 1172 <1> ;(Note: this used to push CS. BUG... 0 00001A5C 07 pop es ;AN000; ES reg, required for 1174 <1> ;get extended country information 0 00001A5D B465 mov ah,D_P_DOS_Get_TBL ;AN000; get extended CDI 0 00001A5F 88D0 mov al,dl ;AN000; upper case table 0 00001A61 BBFFFF mov bx,D_P_DOSTBL_Def ;AN000; get active CON 0 00001A64 B90500 mov cx,D_P_DOSTBL_BL ;AN000; buffer length 0 00001A67 BAFFFF mov dx,D_P_DOSTBL_Def ;AN000; get for default code page 1180 <1> ;DI already set to point to buffer 0 00001A6A CD21 int 21h ;AN000; es:di point to buffer that 1182 <1> ;now has been filled in with info 0 00001A6C 5A pop dx ;AN000; 0 00001A6D 59 pop cx ;AN000; 0 00001A6E 58 pop ax ;AN000; 1186 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1187 <1> %IFN BASESW ;AN037; If ES is psdata base 1188 <1> pop PSDATA_SEG ;AN037; restore current base reg 1189 <1> %ENDIF ;AN037; 1190 <1> %ENDIF ;AN037; 1191 <1> D_P_DCC01: ;AN000; 1192 <1> 1193 <1> ;In this next section, ES will be used as the base of the XLAT table, provided 1194 <1> ; by the previous GET COUNTRY INFO DOS call. This usage of ES is made 1195 <1> ; regardless of which base reg is currently the PSDATA_SEG reg. 1196 <1> 1197 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1198 <1> %IFN BASESW ;AN037; If ES is psdata base 1199 <1> push PSDATA_SEG ;AN037; save current base reg 1200 <1> %ENDIF ;AN037; 1201 <1> %ENDIF ;AN037; 0 00001A6F 2E8B5D01 mov bx,[psdata_seg:di+D_P_DOS_TBL_Off] ;AN000; get offset of table 0 00001A73 2E8E4503 mov es,[psdata_seg:di+D_P_DOS_TBL_Seg] ;AN000; get segment of table 0 00001A77 43 inc bx ;AC035; add '2' to 0 00001A78 43 inc bx ;AC035; BX reg 1206 <1> ;AN000; skip length field 1207 <1> ;(changed ;AN035;) add bx,word ;AN000; skip length field 0 00001A79 2C80 sub al,D_P_ASCII80 ;AN000; make char to index 0 00001A7B 26D7 es xlatb ;AN000; perform case map 1210 <1> 1211 <1> %IFDEF BASESW ;AN037; If BASESW has been defined, and 1212 <1> %IFN BASESW ;AN037; If ES is psdata base 1213 <1> pop PSDATA_SEG ;AN037; restore current base reg 1214 <1> %ENDIF ;AN037; 1215 <1> %ENDIF ;AN037; 0 00001A7D 5F pop di ;AN000; 0 00001A7E 07 pop es ;AN000; 0 00001A7F 5B pop bx ;AN000; 1219 <1> D_P_CAPS_Ret: ;AN000; 0 00001A80 C3 ret ;AN000; 1221 <1> D_P_Do_CAPS_Char endp ;AN000; 1222 <1> ;PAGE ;AN000; 1223 <1> ;*********************************************************************** 1224 <1> %IF NumSW ;AN000;(Check if numeric value is supported) 1225 <1> ; D_P_Value / D_P_SValue 1226 <1> ; 1227 <1> ; Function: Make 32bit value from psdata_seg:SI and see value list 1228 <1> ; and make result buffer. 1229 <1> ; D_P_SValue is an entry point for the signed value 1230 <1> ; and this will simply call D_P_Value after the handling 1231 <1> ; of the sign character, "+" or "-" 1232 <1> ; 1233 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1234 <1> ; ES:BX -> CONTROL block 1235 <1> ; 1236 <1> ; Output: None 1237 <1> ; 1238 <1> ; Use: D_P_Fill_Result, D_P_Check_OVF 1239 <1> ; 1240 <1> ; Vars: D_P_RC(W), D_P_Flags(RW) 1241 <1> ;*********************************************************************** 1242 <1> D_P_SValue proc ;AN000; when signed value here 0 00001A81 50 push ax ;AN000; 0 00001A82 2E800E[3608]80 or byte [psdata_seg:D_P_Flags2],D_P_Signed ;AC034; indicate a signed numeric 0 00001A88 2E8026[3608]FD and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Neg ;AC034; assume positive value 0 00001A8E 2E8A04 mov al,[psdata_seg:si] ;AN000; get sign 0 00001A91 3C2B cmp al,D_P_Plus ;AN000; "+" ? 0 00001A93 740A je D_P_SVal00 ;AN000; 1249 <1> 0 00001A95 3C2D cmp al,D_P_Minus ;AN000; "-" ? 0 00001A97 7507 jne D_P_Sval01 ;AN000; else 1252 <1> 0 00001A99 2E800E[3608]02 or byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; set this is negative value 1254 <1> D_P_SVal00: ;AN000; 0 00001A9F 46 inc si ;AN000; skip sign char 1256 <1> D_P_Sval01: ;AN000; 0 00001AA0 E80200 call D_P_Value ;AN000; and process value 0 00001AA3 58 pop ax ;AN000; 0 00001AA4 C3 ret ;AN000; 1260 <1> D_P_SValue endp ;AN000; 1261 <1> ;*********************************************************************** 1262 <1> D_P_Value proc ;AN000; 0 00001AA5 50 push ax ;AN000; 0 00001AA6 51 push cx ;AN000; 0 00001AA7 52 push dx ;AN000; 0 00001AA8 56 push si ;AN000; 0 00001AA9 31C9 xor cx,cx ;AN000; cx = higher 16 bits 0 00001AAB 31D2 xor dx,dx ;AN000; dx = lower 16 bits 0 00001AAD 53 push bx ;AN000; save control pointer 1270 <1> D_P_Value_Loop: ;AN000; 0 00001AAE 2E8A04 mov al,[psdata_seg:si] ;AN000; get character 0 00001AB1 08C0 or al,al ;AN000; end of line ? 0 00001AB3 7442 je D_P_Value00 ;AN000; 1274 <1> 0 00001AB5 E8F100 call D_P_0099 ;AN000; make asc(0..9) to bin(0..9) 0 00001AB8 7239 jc D_P_Value_Err0 ;AN000; 1277 <1> 0 00001ABA 30E4 xor ah,ah ;AN000; 0 00001ABC 89C5 mov bp,ax ;AN000; save binary number 0 00001ABE D1E2 shl dx,1 ;AN000; to have 2*x 0 00001AC0 D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00001AC2 E8D200 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00001AC5 722C jc D_P_Value_Err0 ;AN000; then error, exit 1284 <1> 0 00001AC7 89D3 mov bx,dx ;AN000; save low(2*x) 0 00001AC9 89C8 mov ax,cx ;AN000; save high(2*x) 0 00001ACB D1E2 shl dx,1 ;AN000; to have 4*x 0 00001ACD D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00001ACF E8C500 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00001AD2 721F jc D_P_Value_Err0 ;AN000; then error, exit 1291 <1> 0 00001AD4 D1E2 shl dx,1 ;AN000; to have 8*x 0 00001AD6 D1D1 rcl cx,1 ;AN000; shift left w/ carry 0 00001AD8 E8BC00 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00001ADB 7216 jc D_P_Value_Err0 ;AN000; then error, exit 1296 <1> 0 00001ADD 01DA add dx,bx ;AN000; now have 10*x 0 00001ADF 11C1 adc cx,ax ;AN000; 32bit ADD 0 00001AE1 E8B300 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00001AE4 720D jc D_P_Value_Err0 ;AN000; then error, exit 1301 <1> 0 00001AE6 01EA add dx,bp ;AN000; Add the current one degree decimal 0 00001AE8 83D100 adc cx,0 ;AN000; if carry, add 1 to high 16bit 0 00001AEB E8A900 call D_P_Check_OVF ;AN000; Overflow occurred ? 0 00001AEE 7203 jc D_P_Value_Err0 ;AN000; then error, exit 1306 <1> 0 00001AF0 46 inc si ;AN000; update pointer 0 00001AF1 EBBB jmp short D_P_Value_Loop ;AN000; loop until NULL encountered 1309 <1> ; 1310 <1> D_P_Value_Err0: ;AN000; 0 00001AF3 5B pop bx ;AN000; 0 00001AF4 E98D00 jmp D_P_Value_Err ;AN000; Bridge 1313 <1> ; 1314 <1> D_P_Value00: ;AN000; 0 00001AF7 5B pop bx ;AN000; restore control pointer 0 00001AF8 2EF606[3608]02 test byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; here cx,dx = 32bit value 0 00001AFE 740A je D_P_Value01 ;AN000; was it negative ? 1318 <1> 0 00001B00 F7D1 not cx ;AN000; + 0 00001B02 F7D2 not dx ;AN000; |- Make 2's complement 0 00001B04 83C201 add dx,1 ;AN000; | 0 00001B07 83D100 adc cx,0 ;AN000; + 1323 <1> D_P_Value01: ;AN000; / nval =0 0 00001B0A 268B7706 mov si,[es:bx + D_P_Value_List] ;AN000; si points to value list 0 00001B0E 268A04 mov al,[es:si] ;AN000; get nval 0 00001B11 3C00 cmp al,D_P_nval_None ;AN000; no value list ? 0 00001B13 7507 jne D_P_Value02 ;AN000; 1328 <1> 0 00001B15 B001 mov al,D_P_Number ;AN000; Set type 0 00001B17 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00001B19 EB74 jmp D_P_Value_Exit ;AN000; 0 00001B1B 90 nop ; identicalise 1333 <1> 1334 <1> D_P_Value02: ;AN000; / nval = 1 1335 <1> %IF Val1SW ;AN000;(Check if value list id #1 is supported) 1336 <1> ;(tm07) cmp al,D_P_nval_Range ;AN000; have range list ? 1337 <1> ;(tm07) jne D_P_Value03 ;AN000; 1338 <1> 0 00001B1C 46 inc si ;AN000; 0 00001B1D 268A04 mov al,[es:si] ;AN000; al = number of range 0 00001B20 3C00 cmp al,D_P_No_nrng ;AN000; (tm07) 0 00001B22 7460 je D_P_Value03 ;AN000; (tm07) 1343 <1> 0 00001B24 46 inc si ;AN000; si points to 1st item_tag 1345 <1> D_P_Val02_Loop: ;AN000; 0 00001B25 2EF606[3608]80 test byte [psdata_seg:D_P_Flags2],D_P_Signed ;AC034; 0 00001B2B 751E jne D_P_Val02_Sign ;AN000; 1348 <1> 0 00001B2D 263B4C03 cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 0 00001B31 7236 jb D_P_Val02_Next ;AN000; 1351 <1> 0 00001B33 7706 ja D_P_Val_In ;AN000; 1353 <1> 0 00001B35 263B5401 cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 0 00001B39 722E jb D_P_Val02_Next ;AN000; 1356 <1> 1357 <1> D_P_Val_In: ;AN000; 1358 <1> ;;;;;; cmp cx,es:D_P_Val_YH] ; comp cx with YH (tm01) 0 00001B3B 263B4C07 cmp cx,[es:si+D_P_Val_YH] ;AN000; comp cx with YH (tm01) 0 00001B3F 7728 ja D_P_Val02_Next ;AN000; 1361 <1> 0 00001B41 723A jb D_P_Val_Found ;AN000; 1363 <1> 0 00001B43 263B5405 cmp dx,[es:si+D_P_Val_YL] ;AN000; comp dx with YL 0 00001B47 7720 ja D_P_Val02_Next ;AN000; 1366 <1> 0 00001B49 EB32 jmp short D_P_Val_Found ;AN000; 1368 <1> 1369 <1> D_P_Val02_Sign: ;AN000; 0 00001B4B 263B4C03 cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 0 00001B4F 7C18 jl D_P_Val02_Next ;AN000; 1372 <1> 0 00001B51 7F06 jg D_P_SVal_In ;AN000; 1374 <1> 0 00001B53 263B5401 cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 0 00001B57 7C10 jl D_P_Val02_Next ;AN000; 1377 <1> 1378 <1> D_P_SVal_In: ;AN000; 0 00001B59 263B4C07 cmp cx,[es:si+D_P_Val_YH] ;AN000; comp cx with YH 0 00001B5D 7F0A jg D_P_Val02_Next ;AN000; 1381 <1> 0 00001B5F 7C1C jl D_P_Val_Found ;AN000; 1383 <1> 0 00001B61 263B5405 cmp dx,[es:si+D_P_Val_YL] ;AN000; comp dx with YL 0 00001B65 7F02 jg D_P_Val02_Next ;AN000; 1386 <1> 0 00001B67 EB14 jmp short D_P_Val_Found ;AN000; 1388 <1> 1389 <1> D_P_Val02_Next: ;AN000; 0 00001B69 83C609 add si,D_P_Len_Range ;AN000; 0 00001B6C FEC8 dec al ;AN000; loop nrng times in AL 0 00001B6E 75B5 jne D_P_Val02_Loop ;AN000; 1393 <1> ; / Not found 1394 <1> D_P_Out_of_Range equ D_P_Out_Of_Range ; NASM port equate 0 00001B70 2EC706[2A08]0600 mov word [psdata_seg:D_P_RC],D_P_Out_of_Range ;AC034; 0 00001B77 B001 mov al,D_P_Number ;AN000; 0 00001B79 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00001B7B EB12 jmp short D_P_Value_Exit ;AN000; 1399 <1> 1400 <1> %ENDIF ;AN000;(of Val1SW) 1401 <1> %IF Val1SW+Val2SW ;AN000;(Check if value list id #1 or #2 is supported) 1402 <1> D_P_Val_Found: ;AN000; 0 00001B7D B001 mov al,D_P_Number ;AN000; 0 00001B7F 268A24 mov ah,[es:si] ;AN000; found ITEM_TAG set 0 00001B82 EB0B jmp short D_P_Value_Exit ;AN000; 1406 <1> 1407 <1> %ENDIF ;AN000;(of Val1SW+Val2SW) 1408 <1> D_P_Value03: ;AN000; / nval = 2 1409 <1> %IF Val2SW ;AN000;(Check if value list id #2 is supported) 1410 <1> ;;;; cmp al,D_P_nval_Value ; have match list ? ASSUME nval=2, 1411 <1> ;;;; jne D_P_Value04 ; even if it is 3 or more. 1412 <1> ;(tm07) inc si ;AN000; 1413 <1> ;(tm07) mov al,[es:si] ;AN000; al = nrng 1414 <1> mov ah,D_P_Len_Range ;AN000; 1415 <1> mul ah ;AN000; Skip nrng field 1416 <1> inc ax ;AN000; 1417 <1> add si,ax ;AN000; si points to nnval 1418 <1> mov al,[es:si] ;AN000; get nnval 1419 <1> inc si ;AN000; si points to 1st item_tag 1420 <1> D_P_Val03_Loop: ;AN000; 1421 <1> cmp cx,[es:si+D_P_Val_XH] ;AN000; comp cx with XH 1422 <1> jne D_P_Val03_Next ;AN000; 1423 <1> 1424 <1> cmp dx,[es:si+D_P_Val_XL] ;AN000; comp dx with XL 1425 <1> je D_P_Val_Found ;AN000; 1426 <1> 1427 <1> D_P_Val03_Next: ;AN000; 1428 <1> add si,D_P_Len_Value ;AN000; points to next value choice 1429 <1> dec al ;AN000; loop nval times in AL 1430 <1> jne D_P_Val03_Loop ;AN000; 1431 <1> ;AN000; / Not found 1432 <1> D_P_Not_in_Val equ D_P_Not_In_Val ; NASM port equate 1433 <1> mov word [psdata_seg:D_P_RC],D_P_Not_in_Val ;AC034; 1434 <1> mov al,D_P_Number ;AN000; 1435 <1> mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1436 <1> jmp short D_P_Value_Exit ;AN000; 1437 <1> 1438 <1> %ENDIF ;AN000;(of Val2SW) 1439 <1> D_P_Value04: ;AN000; / nval = 3 or else 1440 <1> D_P_Value_Err: ;AN000; 0 00001B84 2EC706[2A08]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 0 00001B8B B003 mov al,D_P_String ;AN000; Set type 0 00001B8D B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1444 <1> D_P_Value_Exit: ;AN000; 0 00001B8F E856FD call D_P_Fill_Result ;AN000; 0 00001B92 5E pop si ;AN000; 0 00001B93 5A pop dx ;AN000; 0 00001B94 59 pop cx ;AN000; 0 00001B95 58 pop ax ;AN000; 0 00001B96 C3 ret ;AN000; 1451 <1> D_P_Value endp ;AN000; 1452 <1> ;PAGE ;AN000; 1453 <1> ;*********************************************************************** 1454 <1> ; D_P_Check_OVF 1455 <1> ; 1456 <1> ; Function: Check if overflow is occurred with consideration of 1457 <1> ; signed or un-signed numeric value 1458 <1> ; 1459 <1> ; Input: Flag register 1460 <1> ; 1461 <1> ; Output: CY = 1 : Overflow 1462 <1> ; 1463 <1> ; Vars: D_P_Flags(R) 1464 <1> ;*********************************************************************** 1465 <1> D_P_Check_OVF proc ;AN000; 0 00001B97 9C pushf ;AN000; 0 00001B98 2EF606[3608]02 test byte [psdata_seg:D_P_Flags2],D_P_Neg ;AC034; is it negative value ? 0 00001B9E 7502 jne D_P_COVF ;AN000; if no, check overflow 1469 <1> 0 00001BA0 9D popf ;AN000; by the CY bit 0 00001BA1 C3 ret ;AN000; 1472 <1> 1473 <1> D_P_COVF: ;AN000; 0 00001BA2 9D popf ;AN000; else, 0 00001BA3 7002 jo D_P_COVF00 ;AN000; check overflow by the OF 1476 <1> 0 00001BA5 F8 clc ;AN000; indicate it with CY bit 0 00001BA6 C3 ret ;AN000; CY=0 means no overflow 1479 <1> 1480 <1> D_P_COVF00: ;AN000; 0 00001BA7 F9 stc ;AN000; and CY=1 means overflow 0 00001BA8 C3 ret ;AN000; 1483 <1> D_P_Check_OVF endp ;AN000; 1484 <1> %ENDIF ;AN000;(of FarSW) 1485 <1> ;*********************************************************************** 1486 <1> ; D_P_0099; 1487 <1> ; 1488 <1> ; Function: Make ASCII 0-9 to Binary 0-9 1489 <1> ; 1490 <1> ; Input: AL = character code 1491 <1> ; 1492 <1> ; Output: CY = 1 : AL is not number 1493 <1> ; CY = 0 : AL contains binary value 1494 <1> ;*********************************************************************** 1495 <1> D_P_0099 proc ;AN000; 0 00001BA9 3C30 cmp al,"0" ;AN000; 0 00001BAB 7208 jb D_P_0099Err ;AN000; must be 0 =< al =< 9 1498 <1> 0 00001BAD 3C39 cmp al,"9" ;AN000; 0 00001BAF 7704 ja D_P_0099Err ;AN000; must be 0 =< al =< 9 1501 <1> 0 00001BB1 2C30 sub al,"0" ;AN000; make char -> bin 0 00001BB3 F8 clc ;AN000; indicate no error 0 00001BB4 C3 ret ;AN000; 1505 <1> 1506 <1> D_P_0099Err: ;AN000; 0 00001BB5 F9 stc ;AN000; indicate error 0 00001BB6 C3 ret ;AN000; 1509 <1> D_P_0099 endp ;AN000; 1510 <1> ;PAGE ;AN000; 1511 <1> ;*********************************************************************** 1512 <1> ; D_P_Simple_String 1513 <1> ; 1514 <1> ; Function: See value list for the simple string 1515 <1> ; and make result buffer. 1516 <1> ; 1517 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1518 <1> ; ES:BX -> CONTROL block 1519 <1> ; 1520 <1> ; Output: None 1521 <1> ; 1522 <1> ; Use: D_P_Fill_Result, D_P_String_Comp 1523 <1> ; 1524 <1> ; Vars: D_P_RC(W) 1525 <1> ;*********************************************************************** 1526 <1> D_P_Simple_String proc ;AN000; 0 00001BB7 50 push ax ;AN000; 0 00001BB8 53 push bx ;AN000; 0 00001BB9 52 push dx ;AN000; 0 00001BBA 57 push di ;AN000; 0 00001BBB 268B7F06 mov di,[es:bx + D_P_Value_List] ;AN000; di points to value list 0 00001BBF 268A05 mov al,[es:di] ;AN000; get nval 0 00001BC2 08C0 or al,al ;AN000; no value list ? 0 00001BC4 7504 jne D_P_Sim00 ;AN000; then 1535 <1> 0 00001BC6 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 0 00001BC8 EB09 jmp short D_P_Sim_Exit ;AN000; and set result buffer 1538 <1> 1539 <1> D_P_Sim00: ;AN000; 1540 <1> %IF Val3SW+KeySW ;AN000;(Check if keyword or value list id #3 is supported) 1541 <1> cmp al,D_P_nval_String ;AN000; String choice list provided ? 1542 <1> jne D_P_Sim01 ;AN000; if no, syntax error 1543 <1> 1544 <1> inc di ;AN000; 1545 <1> mov al,[es:di] ;AN000; al = nrng 1546 <1> mov ah,D_P_Len_Range ;AN000; 1547 <1> mul ah ;AN000; Skip nrng field 1548 <1> inc ax ;AN000; ax = (nrng*9)+1 1549 <1> add di,ax ;AN000; di points to nnval 1550 <1> mov al,[es:di] ;AN000; get nnval 1551 <1> mov ah,D_P_Len_Value ;AN000; 1552 <1> mul ah ;AN000; Skip nnval field 1553 <1> inc ax ;AN000; ax = (nnval*5)+1 1554 <1> add di,ax ;AN000; di points to nstrval 1555 <1> mov al,[es:di] ;AN000; get nstrval 1556 <1> inc di ;AC035; add '2' to 1557 <1> inc di ;AC035; DI reg 1558 <1> ;AN000; di points to 1st string in list 1559 <1> ;(replaced ;AC035;) add di,2 ;AN000; di points to 1st string in list 1560 <1> D_P_Sim_Loop: ;AN000; 1561 <1> mov bp,[es:di] ;AN000; get string pointer 1562 <1> call D_P_String_Comp ;AN000; compare it with operand 1563 <1> jnc D_P_Sim_Found ;AN000; found on list ? 1564 <1> 1565 <1> add di,D_P_Len_String ;AN000; if no, point to next choice 1566 <1> dec al ;AN000; loop nstval times in AL 1567 <1> jne D_P_Sim_Loop ;AN000; 1568 <1> ;AN000; / Not found 1569 <1> mov word [psdata_seg:D_P_RC],D_P_Not_In_Str ;AC034; 1570 <1> mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1571 <1> jmp short D_P_Sim_Exit ;AN000; 1572 <1> 1573 <1> D_P_Sim_Found: ;AN000; 1574 <1> mov ah,[es:di-1] ;AN000; set item_tag 1575 <1> mov al,D_P_List_Idx ;AN000; 1576 <1> mov dx,[es:di] ;AN000; get address of STRING 1577 <1> jmp short D_P_Sim_Exit0 ;AN000; 1578 <1> %ENDIF ;AN000;(of Val3SW+KeySW) 1579 <1> D_P_Sim01: ;AN000; 0 00001BCA 2EC706[2A08]0900 mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 0 00001BD1 B4FF mov ah,D_P_No_Tag ;AN000; No ITEM_TAG set 1582 <1> D_P_Sim_Exit: ;AN000; 0 00001BD3 B003 mov al,D_P_String ;AN000; Set type 1584 <1> D_P_Sim_Exit0: ;AN000; 0 00001BD5 E810FD call D_P_Fill_Result ;AN000; 0 00001BD8 5F pop di ;AN000; 0 00001BD9 5A pop dx ;AN000; 0 00001BDA 5B pop bx ;AN000; 0 00001BDB 58 pop ax ;AN000; 0 00001BDC C3 ret ;AN000; 1591 <1> D_P_Simple_String endp ;AN000; 1592 <1> ;PAGE ;AN000; 1593 <1> ;*********************************************************************** 1594 <1> ; D_P_String_Comp: 1595 <1> ; 1596 <1> ; Function: Compare two string 1597 <1> ; 1598 <1> ; Input: psdata_seg:SI -> 1st string 1599 <1> ; ES:BP -> 2nd string (Must be upper case) 1600 <1> ; ES:BX -> CONTROL block 1601 <1> ; 1602 <1> ; Output: CY = 1 if not match 1603 <1> ; 1604 <1> ; Use: D_P_Chk_DBCS, D_P_Do_CAPS_Char 1605 <1> ; 1606 <1> ; Vars: D_P_KEYor_SW_Ptr(W), D_P_Flags(R). D_P_KEYorSW_Ptr 1607 <1> ;*********************************************************************** 1608 <1> D_P_String_Comp proc ;AN000; 0 00001BDD 50 push ax ;AN000; 0 00001BDE 55 push bp ;AN000; 0 00001BDF 52 push dx ;AN000; 0 00001BE0 56 push si ;AN000; 0 00001BE1 B202 mov dl,D_P_DOSTBL_Char ;AN000; use character case map table 1614 <1> D_P_SCOM_Loop: ;AN000; 0 00001BE3 2E8A04 mov al,[psdata_seg:si] ;AN000; get command character 0 00001BE6 E87201 call D_P_Chk_DBCS ;AN000; DBCS ? 0 00001BE9 723C jc D_P_SCOM00 ;AN000; yes,DBCS 1618 <1> 0 00001BEB E845FE call D_P_Do_CAPS_Char ;AN000; else, upper case map before comparison 1620 <1> %IF KeySW+SwSW ;AN000;(Check if keyword or switch is supported) 0 00001BEE 2EF606[3608]08 test byte [psdata_seg:D_P_Flags2],D_P_Key_Cmp ;AC034; keyword search ? 0 00001BF4 740D je D_P_SCOM04 ;AN000; 1623 <1> 0 00001BF6 3C3D cmp al,D_P_Keyword ;AN000; "=" is delimiter 0 00001BF8 751F jne D_P_SCOM03 ;AN000;IF "=" on command line AND (bp+1=> char after the "=" in synonym list) 1626 <1> 0 00001BFA 26807E0100 cmp byte ptr [es:bp+1],D_P_NULL ;AN021; at end of keyword string in the control block THEN 1628 <1> D_P_SCOM_DIFFER equ D_P_SCOM_Differ ; NASM port label 0 00001BFF 7571 jne D_P_SCOM_DIFFER ;AN021; 1630 <1> 0 00001C01 EB13 jmp short D_P_SCOM05 ;AN000; keyword found in synonym list 1632 <1> 1633 <1> D_P_SCOM04: ;AN000; 0 00001C03 2EF606[3608]10 test byte [psdata_seg:D_P_Flags2],D_P_SW_Cmp ;AC034; switch search ? 0 00001C09 740E je D_P_SCOM03 ;AN000; 1636 <1> 0 00001C0B 3C3A cmp al,D_P_Colon ;AN000; ":" is delimiter, at end of switch on command line 0 00001C0D 750A jne D_P_SCOM03 ;AN000; continue compares 1639 <1> 0 00001C0F 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN021; IF at end of switch on command AND 0 00001C14 755C jne D_P_SCOM_DIFFER ;AN021; at end of switch string in the control block THEN 1642 <1> 1643 <1> D_P_SCOM05: ;AN000; found a match 0 00001C16 46 inc si ;AN000; si points to just after "=" or ":" 0 00001C17 EB5C jmp short D_P_SCOM_Same ;AN000; exit 1646 <1> 1647 <1> D_P_SCOM03: ;AN000; 1648 <1> %ENDIF ;AN000;(of KeySW+SwSW) 0 00001C19 263A4600 cmp al,[es:bp] ;AN000; compare operand w/ a synonym 0 00001C1D 751D jne D_P_SCOM_Differ0 ;AN000; if different, check ignore colon option 1651 <1> 0 00001C1F 08C0 or al,al ;AN000; end of line 0 00001C21 7452 je D_P_SCOM_Same ;AN000; if so, exit 1654 <1> 0 00001C23 46 inc si ;AN000; update operand pointer 0 00001C24 45 inc bp ;AN000; and synonym pointer 0 00001C25 EB13 jmp short D_P_SCOM01 ;AN000; loop until NULL or "=" or ":" found in case 1658 <1> 1659 <1> D_P_SCOM00: ;AN000; Here al is DBCS leading byte 0 00001C27 263A4600 cmp al,[es:bp] ;AN000; compare leading byte 0 00001C2B 7545 jne D_P_SCOM_Differ ;AN000; if not match, say different 1662 <1> 0 00001C2D 46 inc si ;AN000; else, load next byte 0 00001C2E 2E8A04 mov al,[psdata_seg:si] ;AN000; and 0 00001C31 45 inc bp ;AN000; 0 00001C32 263A4600 cmp al,[es:bp] ;AN000; compare 2nd byte 0 00001C36 753A jne D_P_SCOM_Differ ;AN000; if not match, say different, too 1668 <1> 0 00001C38 46 inc si ;AN000; else update operand pointer 0 00001C39 45 inc bp ;AN000; and synonym pointer 1671 <1> D_P_SCOM01: ;AN000; 0 00001C3A EBA7 jmp short D_P_SCOM_Loop ;AN000; loop until NULL or "=" or "/" found in case 1673 <1> 1674 <1> D_P_SCOM_Differ0: ;AN000; 1675 <1> 1676 <1> %IF SwSW ;AN000;(tm10) 0 00001C3C 2EF606[3608]40 test byte [psdata_seg:D_P_Flags2],D_P_SW ;AC034;(tm10) 0 00001C42 740F je D_P_not_applicable ;AN000;(tm10) 1679 <1> 0 00001C44 26F747022000 test word [es:bx + D_P_Function_Flag],D_P_colon_is_not_necessary ;AN000;(tm10) 0 00001C4A 7407 je D_P_not_applicable ;AN000;(tm10) 1682 <1> 0 00001C4C 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000;(tm10) 1684 <1> ;(deleted ;AN025;) jne D_P_not_applicable ;AN000;(tm10) 0 00001C51 7422 je D_P_SCOM_Same ;AN025;(tm10) 1686 <1> 1687 <1> D_P_not_applicable: ;AN000;(tm10) 1688 <1> %ENDIF ;AN000;(tm10) 1689 <1> 0 00001C53 26F7071000 test word [es:bx + D_P_Match_Flag],D_P_Ig_Colon ;AN000; ignore colon option specified ? 0 00001C58 7418 je D_P_SCOM_Differ ;AN000; if no, say different. 1692 <1> 0 00001C5A 3C3A cmp al,D_P_Colon ;AN000; End up with ":" and 0 00001C5C 7509 jne D_P_SCOM02 ;AN000; subseqently 1695 <1> 0 00001C5E 26807E0000 cmp byte ptr [es:bp],D_P_NULL ;AN000; NULL ? 0 00001C63 750D jne D_P_SCOM_Differ ;AN000; if no, say different 1698 <1> 0 00001C65 EB0E jmp short D_P_SCOM_Same ;AN000; else, say same 1700 <1> 1701 <1> D_P_SCOM02: ;AN000; 0 00001C67 3C00 cmp al,D_P_NULL ;AN000; end up NULL and : 0 00001C69 7507 jne D_P_SCOM_Differ ;AN000; 1704 <1> 0 00001C6B 26807E003A cmp byte ptr [es:bp],D_P_Colon ;AN000; if no, say different 0 00001C70 7403 je D_P_SCOM_Same ;AN000; else, say same 1707 <1> 1708 <1> D_P_SCOM_Differ: ;AN000; 0 00001C72 F9 stc ;AN000; indicate not found 0 00001C73 EB06 jmp short D_P_SCOM_Exit ;AN000; 1711 <1> 1712 <1> D_P_SCOM_Same: ;AN000; 0 00001C75 2E8936[3908] mov [psdata_seg:D_P_KEYorSW_Ptr],si ;AC034; for later use by keyword or switch 0 00001C7A F8 clc ;AN000; indicate found 1715 <1> D_P_SCOM_Exit: ;AN000; 0 00001C7B 5E pop si ;AN000; 0 00001C7C 5A pop dx ;AN000; 0 00001C7D 5D pop bp ;AN000; 0 00001C7E 58 pop ax ;AN000; 0 00001C7F C3 ret ;AN000; 1721 <1> D_P_String_Comp endp ;AN000; 1722 <1> ;PAGE ;AN000; 1723 <1> ;*********************************************************************** 1724 <1> %IF DateSW ;AN000;(Check if date format is supported) 1725 <1> ; D_P_Date_Format 1726 <1> ; 1727 <1> ; Function: Convert a date string to DOS date format for int 21h 1728 <1> ; with format validation. 1729 <1> ; 1730 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1731 <1> ; ES:BX -> CONTROL block 1732 <1> ; 1733 <1> ; Output: None 1734 <1> ; 1735 <1> ; Use: D_P_Fill_Result, D_P_Set_CDI, D_P_Get_DecNum 1736 <1> ; 1737 <1> ; Vars: D_P_RC(W), D_P_1st_Val(RW), D_P_2nd_Val(RW), D_P_3rd_Val(RW) 1738 <1> ;*********************************************************************** 1739 <1> D_P_Date_Format proc ;AN000; 1740 <1> push ax ;AN000; 1741 <1> push cx ;AN000; 1742 <1> push dx ;AN000; 1743 <1> push si ;AN000; 1744 <1> push bx ;AN000; 1745 <1> push si ;AN000; 1746 <1> call D_P_Set_CDI ;AN000; set country dependent information before process 1747 <1> ; mov bl,[psdata_seg:si].D_P_CDI_DateS ;load date separator ;AN020; (deleted) 1748 <1> ; note: the country info is still needed 1749 <1> ; to determine the order of the fields, 1750 <1> ; but the separator char is no longer used. 1751 <1> pop si ;AN000; 1752 <1> mov word [psdata_seg:D_P_1st_Val],0 ;AC034; set initial value 1753 <1> mov word [psdata_seg:D_P_2nd_Val],0 ;AC034; set initial value 1754 <1> mov word [psdata_seg:D_P_3rd_Val],0 ;AC034; set initial value 1755 <1> call D_P_Get_DecNum ;AN000; get 1st number 1756 <1> jc D_P_DateF_Err0 ;AN000;-----------------------+ 1757 <1> 1758 <1> mov [psdata_seg:D_P_1st_Val],ax ;AC034; | 1759 <1> or bl,bl ;AN000; end of line ? | 1760 <1> je D_P_DateF_YMD ;AN000; | 1761 <1> 1762 <1> call D_P_Get_DecNum ;AN000; get 2nd number | 1763 <1> jc D_P_DateF_Error ;AN000; | 1764 <1> 1765 <1> mov [psdata_seg:D_P_2nd_Val],ax ;AC034; | 1766 <1> or bl,bl ;AN000; end of line ? | 1767 <1> je D_P_DateF_YMD ;AN000; | 1768 <1> 1769 <1> call D_P_Get_DecNum ;AN000; get 3rd number | 1770 <1> D_P_DateF_Err0: ;AN000; Bridge <-----------+ 1771 <1> jc D_P_DateF_Error ;AN000; 1772 <1> 1773 <1> mov [psdata_seg:D_P_3rd_Val],ax ;AC034; 1774 <1> or bl,bl ;AN000; end of line ? 1775 <1> jne D_P_DateF_Error ;AN000; 1776 <1> 1777 <1> D_P_DateF_YMD: ;AN000; 1778 <1> D_P_Country_Info equ D_P_COUNTRY_INFO ; NASM port label 1779 <1> mov bx,[psdata_seg:D_P_Country_Info + D_P_CDI_DateF] ;AC034; get date format 1780 <1> cmp bx,D_P_Date_YMD ;AN000; 1781 <1> je D_P_DateF00 ;AN000; 1782 <1> 1783 <1> mov ax,[psdata_seg:D_P_1st_Val] ;AC034; 1784 <1> or ah,ah ;AN000; 1785 <1> jne D_P_DateF_Error ;AN000; 1786 <1> 1787 <1> mov cl,al ;AN000; set month 1788 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 1789 <1> or ah,ah ;AN000; if overflow, error. 1790 <1> jne D_P_DateF_Error ;AN000; 1791 <1> 1792 <1> mov ch,al ;AN000; set date 1793 <1> mov dx,[psdata_seg:D_P_3rd_Val] ;AC034; set year 1794 <1> cmp bx,D_P_Date_DMY ;AN000; from here format = MDY 1795 <1> jne D_P_DateF01 ;AN000; if it is DMY 1796 <1> 1797 <1> xchg ch,cl ;AN000; then swap M <-> D 1798 <1> D_P_DateF01: ;AN000; 1799 <1> jmp short D_P_DateF02 ;AN000; 1800 <1> 1801 <1> D_P_DateF00: ;AN000; / here format = YMD 1802 <1> mov dx,[psdata_seg:D_P_1st_Val] ;AC034; set year 1803 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 1804 <1> or ah,ah ;AN000; if overflow, error 1805 <1> jne D_P_DateF_Error ;AN000; 1806 <1> 1807 <1> mov cl,al ;AN000; set month 1808 <1> mov ax,[psdata_seg:D_P_3rd_Val] ;AC034; 1809 <1> or ah,ah ;AN000; if overflow, error 1810 <1> jne D_P_DateF_Error ;AN000; 1811 <1> 1812 <1> mov ch,al ;AN000; set date 1813 <1> D_P_DateF02: ;AN000; 1814 <1> cmp dx,100 ;AN000; year is less that 100 ? 1815 <1> jae D_P_DateF03 ;AN000; 1816 <1> 1817 <1> add dx,1900 ;AN000; set year 19xx 1818 <1> D_P_DateF03: ;AN000; 1819 <1> pop bx ;AN000; recover CONTROL block 1820 <1> pop si ;AN000; recover string pointer 1821 <1> mov ah,D_P_No_Tag ;AN000; set 1822 <1> mov al,D_P_Date_F ;AN000; result 1823 <1> call D_P_Fill_Result ;AN000; buffer 1824 <1> jmp short D_P_Date_Format_Exit ;AN000; to Date 1825 <1> 1826 <1> D_P_DateF_Error: ;AN000; 1827 <1> pop bx ;AN000; recover CONTROL block 1828 <1> pop si ;AN000; recover string pointer 1829 <1> mov ah,D_P_No_Tag ;AN000; set 1830 <1> mov al,D_P_String ;AN000; result 1831 <1> call D_P_Fill_Result ;AN000; buffer to string 1832 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; indicate syntax error 1833 <1> D_P_Date_Format_Exit: ;AN000; 1834 <1> pop dx ;AN000; 1835 <1> pop cx ;AN000; 1836 <1> pop ax ;AN000; 1837 <1> ret ;AN000; 1838 <1> D_P_Date_Format endp ;AN000; 1839 <1> %ENDIF ;AN000;(of DateSW) 1840 <1> ;PAGE ;AN000; 1841 <1> ;*********************************************************************** 1842 <1> %IF TimeSW+DateSW ;AN000;(Check if time or date format is supported) 1843 <1> ; D_P_Set_CDI: 1844 <1> ; 1845 <1> ; Function: Read CDI from DOS if it has not been read yet 1846 <1> ; 1847 <1> ; Input: None 1848 <1> ; 1849 <1> ; Output: psdata_seg:SI -> CDI 1850 <1> ; 1851 <1> ; Use: INT 21h w/ AH = 38h 1852 <1> ;*********************************************************************** 1853 <1> D_P_Set_CDI proc ;AN000; 1854 <1> lea si,[D_P_Country_Info] ;AC034; 1855 <1> cmp word [psdata_seg:si + D_P_CDI_DateF],D_P_NeedToBeRead ;AN000; already read ? 1856 <1> je D_P_Read_CDI ;AN000; 1857 <1> 1858 <1> jmp short D_P_Set_CDI_Exit ;AN000; then do nothing 1859 <1> 1860 <1> D_P_Read_CDI: ;AN000; else read CDI thru DOS 1861 <1> push ds ;AN000; 1862 <1> push dx ;AN000; 1863 <1> push ax ;AN000; 1864 <1> push PSDATA_SEG ;AC023; 1865 <1> pop ds ;AN000; set segment register 1866 <1> mov ax,D_P_DOS_Get_CDI ;AN000; get country information 1867 <1> mov dx,si ;AN000; set offset of CDI in local data area 1868 <1> int 21h ;AN000; 1869 <1> pop ax ;AN000; 1870 <1> pop dx ;AN000; 1871 <1> pop ds ;AN000; 1872 <1> D_P_Set_CDI_Exit: ;AN000; 1873 <1> ret ;AN000; 1874 <1> D_P_Set_CDI endp ;AN000; 1875 <1> ;PAGE ;AN000; 1876 <1> ;*********************************************************************** 1877 <1> ; D_P_Get_DecNum: 1878 <1> ; 1879 <1> ; Function: Read a chcrater code from psdata_seg:SI until specified delimiter 1880 <1> ; or NULL encountered. And make a decimal number. 1881 <1> ; 1882 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1883 <1> ; 1884 <1> ; Output: BL = delimiter code or NULL 1885 <1> ; AX = Decimal number 1886 <1> ; SI advanced to the next number 1887 <1> ; CY = 1 : Syntax error, AL = Latest examineed number 1888 <1> ; 1889 <1> ; Use: D_P_0099 1890 <1> ;*********************************************************************** 1891 <1> D_P_Get_DecNum proc ;AN000; 1892 <1> push cx ;AN000; 1893 <1> push dx ;AN000; 1894 <1> xor cx,cx ;AN000; cx will have final value 1895 <1> D_P_GetNum_Loop: ;AN000; 1896 <1> mov al,[psdata_seg:si] ;AN000; load character 1897 <1> or al,al ;AN000; end of line ? 1898 <1> je D_P_GetNum00 ;AN000; if yes, exit 1899 <1> 1900 <1> cmp byte [psdata_seg:D_P_Got_Time],0 ;AC034; ;is this numeric in a time field? ;AC023 1901 <1> je D_P_Do_Date_Delims ;AN000;no, go check out Date delimiters ;AC023 1902 <1> 1903 <1> ; Determine which delimiter(s) to check for. Colon & period or period only 1904 <1> cmp bl,D_P_colon_period ;AN032; ;Time 1905 <1> jne D_P_Do_Time_Delim1 ;AN032; ;only check for period 1906 <1> 1907 <1> cmp al,D_P_Colon ;AN032; ;Is this a valid delimiter ? 1908 <1> je D_P_GetNum01 ;AN032; ;yes, exit 1909 <1> 1910 <1> D_P_Do_Time_Delim1: ;AN000; 1911 <1> cmp al,D_P_Period ;;AC032;;AC023;Is this a valid delimiter ? 1912 <1> je D_P_GetNum01 ;AC023; yes, exit 1913 <1> 1914 <1> jmp short D_P_Neither_Delims ;AN023; 1915 <1> 1916 <1> D_P_Do_Date_Delims: ;AN000; 1917 <1> ;Regardless of the date delimiter character specified in the country 1918 <1> ;dependent information, check for the presence of any one of these 1919 <1> ;three field delimiters: "-", "/", or ".". 1920 <1> cmp al,D_P_Minus ;AN020;is this a date delimiter character? 1921 <1> je D_P_GetNum01 ;AN020;if yes, exit 1922 <1> 1923 <1> cmp al,D_P_Slash ;AN020;is this a date delimiter character? 1924 <1> je D_P_GetNum01 ;AN020;if yes, exit 1925 <1> 1926 <1> cmp al,D_P_Period ;AN020;is this a date delimiter character? 1927 <1> je D_P_GetNum01 ;AN000; if yes, exit 1928 <1> 1929 <1> D_P_Neither_Delims: ;AN023; 1930 <1> 1931 <1> call D_P_0099 ;AN000; convert it to binary 1932 <1> jc D_P_GetNum_Exit ;AN000; if error exit 1933 <1> 1934 <1> mov ah,0 ;AN000; 1935 <1> xchg ax,cx ;AN000; 1936 <1> mov dx,10 ;AN000; 1937 <1> mul dx ;AN000; ax = ax * 10 1938 <1> or dx,dx ;AN000; overflow 1939 <1> jne D_P_GetNum02 ;AN000; then exit 1940 <1> 1941 <1> add ax,cx ;AN000; 1942 <1> jc D_P_GetNum_Exit ;AN000; 1943 <1> 1944 <1> xchg ax,cx ;AN000; 1945 <1> inc si ;AN000; 1946 <1> jmp short D_P_GetNum_Loop ;AN000; 1947 <1> 1948 <1> D_P_GetNum00: ;AN000; 1949 <1> mov bl,al ;AN000; set bl to NULL 1950 <1> clc ;AN000; indicate no error 1951 <1> jmp short D_P_GetNum_Exit ;AN000; 1952 <1> 1953 <1> D_P_GetNum01: ;AN000; 1954 <1> inc si ;AN000; si points to next number 1955 <1> clc ;AN000; indicate no error 1956 <1> jmp short D_P_GetNum_Exit ;AN000; 1957 <1> 1958 <1> D_P_GetNum02: ;AN000; 1959 <1> stc ;AN000; indicate error 1960 <1> D_P_GetNum_Exit: ;AN000; 1961 <1> mov ax,cx ;AN000;return value 1962 <1> pop dx ;AN000; 1963 <1> pop cx ;AN000; 1964 <1> ret ;AN000; 1965 <1> D_P_Get_DecNum endp ;AN000; 1966 <1> %ENDIF ;AN000;(of TimeSW+DateSW) 1967 <1> ;PAGE ;AN000; 1968 <1> ;*********************************************************************** 1969 <1> %IF TimeSW ;AN000;(Check if time format is supported) 1970 <1> ; D_P_Time_Format 1971 <1> ; 1972 <1> ; Function: Convert a time string to DOS time format for int 21h 1973 <1> ; with format validation. 1974 <1> ; 1975 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 1976 <1> ; ES:BX -> CONTROL block 1977 <1> ; 1978 <1> ; Output: None 1979 <1> ; 1980 <1> ; Use: D_P_Fill_Result, D_P_Set_CDI, D_P_Get_DecNum, D_P_Time_2412 1981 <1> ; 1982 <1> ; Vars: D_P_RC(W), D_P_Flags(R), D_P_1st_Val(RW), D_P_2nd_Val(RW) 1983 <1> ; D_P_3rd_Val(RW), D_P_4th_Val(RW) 1984 <1> ;*********************************************************************** 1985 <1> D_P_Time_Format proc ;AN000; 1986 <1> push ax ;AN000; 1987 <1> push cx ;AN000; 1988 <1> push dx ;AN000; 1989 <1> push si ;AN000; 1990 <1> push bx ;AN000; 1991 <1> push si ;AN000; 1992 <1> call D_P_Set_CDI ;AN000; Set country independent 1993 <1> ; information before process 1994 <1> ;(AN032; deleted) mov bl,[psdata_seg:si].D_P_CDI_TimeS ;load time separator 1995 <1> ;(AN032; deleted) mov bh,[psdata_seg:si].D_P_CDI_Dec ;load decimal separator 1996 <1> test byte ptr [psdata_seg:si + D_P_CDI_TimeF],1 ;AN000; 24 hour system 1997 <1> pop si ;AN000; 1998 <1> jne D_P_TimeF00 ;AN000; if no, means 12 hour system 1999 <1> 2000 <1> call D_P_Time_2412 ;AN000; this routine handle "am" "pm" 2001 <1> D_P_TimeF00: ;AN000; 2002 <1> mov word [psdata_seg:D_P_1st_Val],0 ;AC034; set initial value 2003 <1> mov word [psdata_seg:D_P_2nd_Val],0 ;AC034; set initial value 2004 <1> mov word [psdata_seg:D_P_3rd_Val],0 ;AC034; set initial value 2005 <1> mov word [psdata_seg:D_P_4th_Val],0 ;AC034; set initial value 2006 <1> mov byte [psdata_seg:D_P_Got_Time],1 ;AN023;AC034;; use time delimiter 2007 <1> mov bl,D_P_colon_period ;AN032; flag, indicates use of 2008 <1> ; delimiters between hours, 2009 <1> ; minutes,seconds 2010 <1> call D_P_Get_DecNum ;AN000; get 1st number 2011 <1> jc D_P_TimeF_Err0 ;AN000; 2012 <1> 2013 <1> mov [psdata_seg:D_P_1st_Val],ax ;AC034; 2014 <1> or bl,bl ;AN000; end of line ? 2015 <1> D_P_TimeF_Rlt equ D_P_TimeF_RLT ; NASM port label 2016 <1> je D_P_TimeF_Rlt ;AN000; 2017 <1> 2018 <1> call D_P_Get_DecNum ;AN000; get 2nd number 2019 <1> jc D_P_TimeF_Err0 ;AC038; if OK 2020 <1> 2021 <1> mov [psdata_seg:D_P_2nd_Val],ax ;AC034; 2022 <1> or bl,bl ;AN000; end of line ? 2023 <1> je D_P_TimeF_Rlt ;AN000; 2024 <1> 2025 <1> ;(;AN032; deleted) mov bl,bh ;set decimal separator 2026 <1> mov bl,D_P_period_only ;AN032; flag, which to decimal separator 2027 <1> call D_P_Get_DecNum ;AN000; get 3rd number 2028 <1> jc D_P_TimeF_Err0 ;AC039; if problem, bridge to error 2029 <1> 2030 <1> mov [psdata_seg:D_P_3rd_Val],ax ;AC034; 2031 <1> or bl,bl ;AN000; end of line ? 2032 <1> ;(DELETED ;AN039;) je D_P_TimeF_Rlt ;AN000; 2033 <1> jne D_P_Time_4 ;AN039; NOT END OF LINE, 2034 <1> ;AN039; GO TO 4TH NUMBER 2035 <1> D_P_Time_Again equ D_P_TIME_AGAIN ; NASM port equate 2036 <1> test byte [psdata_seg:D_P_Flags1],D_P_Time_Again ;AN039; HAS TIME PARSE 2037 <1> ;AN039; BEEN REPEATED? 2038 <1> jnz D_P_TimeF_Rlt ;AN039; yes, this is really 2039 <1> ;AN039; the end of line 2040 <1> ;AN039; no, time has not been repeated 2041 <1> mov si,[psdata_seg:D_P_SI_Save] ;AN039; get where parser quit 2042 <1> ;AN039; in command line 2043 <1> cmp byte ptr [si-1],D_P_Comma ;AN039; look at delimiter 2044 <1> ;AN039; from command line 2045 <1> jne D_P_TimeF_Rlt ;AN039; was not a comma, this is 2046 <1> ;AN039; really end of line 2047 <1> ;AN039; is comma before hundredths, 2048 <1> ;AN039; redo TIME 2049 <1> mov byte ptr [si-1],D_P_Period ;AN039; change that ambiguous 2050 <1> ;AN039; comma to a decimal point 2051 <1> ;AN039; parse can understand 2052 <1> mov word [psdata_seg:D_P_Flags],0 ;AN039; Clear all internal flags 2053 <1> or byte [psdata_seg:D_P_Flags1],D_P_Time_Again ;AN039; indicate TIME 2054 <1> ;AN039; is being repeated 2055 <1> mov cx,[psdata_seg:D_P_ORIG_ORD] ;AN039; ORIGINAL ORDINAL FROM CX 2056 <1> mov sp,[psdata_seg:D_P_ORIG_STACK] ;AN039; ORIGINAL VALUE 2057 <1> ;AN039; OF STACK FROM SP 2058 <1> mov si,[psdata_seg:D_P_ORIG_SI] ;AN039; ORIGINAL START 2059 <1> ;AN039; PARSE POINTER FROM SI 2060 <1> D_P_Redo_Time equ D_P_REDO_TIME ; NASM port label 2061 <1> jmp D_P_Redo_Time ;AN039; go try TIME again 2062 <1> ; =============================================================== 2063 <1> D_P_Time_4: ;AN039; READY FOR 4TH (HUNDREDTHS) NUMBER 2064 <1> call D_P_Get_DecNum ;AN000; get 4th number 2065 <1> D_P_TimeF_Err0: ;AN000; Bridge 2066 <1> jc D_P_TimeF_Error ;AN000; 2067 <1> 2068 <1> mov [psdata_seg:D_P_4th_Val],ax ;AC034; 2069 <1> or bl,bl ;AN000; After hundredth, no data allowed 2070 <1> jne D_P_TimeF_Error ;AN000; if some, then error 2071 <1> 2072 <1> D_P_TimeF_RLT: ;AN000; 2073 <1> mov ax,[psdata_seg:D_P_1st_Val] ;AC034; 2074 <1> or ah,ah ;AN000; if overflow then error 2075 <1> jne D_P_TimeF_Err ;AN000; 2076 <1> 2077 <1> D_P_Time12am equ D_P_time12am ; NASM port equate 2078 <1> test byte [psdata_seg:D_P_Flags1],D_P_Time12am ;AN038;if "am" specified 2079 <1> jz D_P_Time_notAM ;AN038;skip if no "AM" specified 2080 <1> ;since "AM" was specified, 2081 <1> cmp al,12 ;AN038: if hour specified as later than noon 2082 <1> ja D_P_TimeF_Err ;AN038; error if "AM" on more than noon 2083 <1> jne D_P_Time_notAM ;AN038; for noon exactly, 2084 <1> 2085 <1> xor al,al ;AN038; set hour = zero 2086 <1> D_P_Time_notAM: ;AN038; 2087 <1> test byte [psdata_seg:D_P_Flags2],D_P_Time12 ;AC034; if 12 hour system and pm is specified 2088 <1> je D_P_TimeSkip00 ;AN000; then 2089 <1> 2090 <1> cmp al,12 ;AN038; if 12:00 o'clock already 2091 <1> je D_P_TimeSkip00 ;AN038; it is PM already 2092 <1> 2093 <1> add al,12 ;AN000; add 12 hours to make it afternoon 2094 <1> jc D_P_TimeF_Err ;AN000; if overflow then error 2095 <1> 2096 <1> cmp al,24 ;AN038; after adding 12, now cannot be >24 2097 <1> ja D_P_TimeF_Err ;AN038; if too big, error 2098 <1> 2099 <1> D_P_TimeSkip00: ;AN000; 2100 <1> mov dl,al ;AN000; set hour 2101 <1> mov ax,[psdata_seg:D_P_2nd_Val] ;AC034; 2102 <1> or ah,ah ;AN000; if overflow then error 2103 <1> jne D_P_TimeF_Err ;AN000; 2104 <1> 2105 <1> mov dh,al ;AN000; set minute 2106 <1> mov ax,[psdata_seg:D_P_3rd_Val] ;AC034; 2107 <1> or ah,ah ;AN000; if overflow then error 2108 <1> jne D_P_TimeF_Err ;AN000; 2109 <1> 2110 <1> mov cl,al ;AN000; set second 2111 <1> mov ax,[psdata_seg:D_P_4th_Val] ;AC034; 2112 <1> or ah,ah ;AN000; if overflow then error 2113 <1> jne D_P_TimeF_Err ;AN000; 2114 <1> 2115 <1> mov ch,al ;AN000; set hundredth 2116 <1> pop bx ;AN000; recover CONTROL block 2117 <1> pop si ;AN000; recover string pointer 2118 <1> mov ah,D_P_No_Tag ;AN000; set 2119 <1> mov al,D_P_Time_F ;AN000; result 2120 <1> call D_P_Fill_Result ;AN000; buffer 2121 <1> jmp short D_P_Time_Format_Exit ;AN000; to time 2122 <1> 2123 <1> D_P_TimeF_Error: ;AN000; 2124 <1> D_P_TimeF_Err: ;AN000; 2125 <1> pop bx ;AN000; recover CONTROL block 2126 <1> pop si ;AN000; recover string pointer 2127 <1> mov ah,D_P_No_Tag ;AN000; set 2128 <1> mov al,D_P_String ;AN000; result 2129 <1> call D_P_Fill_Result ;AN000; buffer to string 2130 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; return syntax error 2131 <1> D_P_Time_Format_Exit: ;AN000; 2132 <1> mov byte [psdata_seg:D_P_Got_Time],0 ;AN023;AC034;; finished with this time field 2133 <1> pop dx ;AN000; 2134 <1> pop cx ;AN000; 2135 <1> pop ax ;AN000; 2136 <1> ret ;AN000; 2137 <1> D_P_Time_Format endp ;AN000; 2138 <1> ;PAGE ;AN000; 2139 <1> ;*********************************************************************** 2140 <1> ; D_P_Time_2412: 2141 <1> ; 2142 <1> ; Function: Remove "a", "p", "am", or "pm" from the end of stinrg 2143 <1> ; 2144 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2145 <1> ; 2146 <1> ; Output: Set D_P_Time12 flag when the string is terminated by "p" 2147 <1> ; or "pm" 2148 <1> ; 2149 <1> ; Vars: D_P_Flags(W) 2150 <1> ;*********************************************************************** 2151 <1> D_P_Time_2412 proc ;AN000; 2152 <1> push ax ;AN000; 2153 <1> push si ;AN000; 2154 <1> D_P_T12_Loop: ;AN000; 2155 <1> mov al,[psdata_seg:si] ;AN000; Move 2156 <1> inc si ;AN000; si 2157 <1> or al,al ;AN000; to 2158 <1> jne D_P_T12_Loop ;AN000; end of string 2159 <1> 2160 <1> mov al,[psdata_seg:si-2] ;AN000; get char just before NULL 2161 <1> or al,D_P_Make_Lower ;AN000; lower case map 2162 <1> cmp al,"p" ;AN000; only "p" of "pm" ? 2163 <1> je D_P_T1200 ;AN000; 2164 <1> 2165 <1> cmp al,"a" ;AN000; only "a" of "am" ? 2166 <1> je D_P_T1201 ;AN000; 2167 <1> 2168 <1> cmp al,"m" ;AN000; "m" of "am" or "pm" 2169 <1> jne D_P_T12_Exit ;AN000; 2170 <1> 2171 <1> dec si ;AN000; 2172 <1> mov al,[psdata_seg:si-2] ;AN000; 2173 <1> D_P_Make_lower equ D_P_Make_Lower ; NASM port equate 2174 <1> or al,D_P_Make_lower ;AN000; lower case map 2175 <1> cmp al,"p" ;AN000; "p" of "pm" ? 2176 <1> je D_P_T1200 ;AN000; 2177 <1> 2178 <1> cmp al,"a" ;AN000; "a" of "am" ? 2179 <1> je D_P_T1201 ;AN000; go process "a" 2180 <1> 2181 <1> jmp short D_P_T12_Exit ;AN000; no special chars found 2182 <1> 2183 <1> D_P_T1200: ;AN000; "P" found 2184 <1> or byte [psdata_seg:D_P_Flags2],D_P_Time12 ;AC034; flag "PM" found 2185 <1> jmp short D_P_Tclr_chr ;AN038; go clear the special char 2186 <1> 2187 <1> D_P_T1201: ;AN000; "A" found 2188 <1> D_P_Time12AM equ D_P_time12am ; NASM port equate 2189 <1> or byte [psdata_seg:D_P_Flags1],D_P_Time12AM ;AN038; flag "AM" found 2190 <1> D_P_Tclr_chr: ;AN038; 2191 <1> mov byte ptr [psdata_seg:si-2],D_P_NULL ;AN000; null out special char 2192 <1> D_P_T12_Exit: ;AN000; 2193 <1> pop si ;AN000; 2194 <1> pop ax ;AN000; 2195 <1> ret ;AN000; 2196 <1> D_P_Time_2412 endp ;AN000; 2197 <1> %ENDIF ;AN000;(of TimeSW) 2198 <1> ;PAGE ;AN000; 2199 <1> ;*********************************************************************** 2200 <1> %IF CmpxSW ;AN000;(Check if complex item is supported) 2201 <1> ; D_P_Complex_Format: 2202 <1> ; 2203 <1> ; Function: Check if the input string is valid complex format. 2204 <1> ; And set the result buffer. 2205 <1> ; 2206 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2207 <1> ; ES:BX -> CONTROL block 2208 <1> ; 2209 <1> ; Output: None 2210 <1> ; 2211 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_Chk_EOL, D_P_Skip_Delim 2212 <1> ; D_P_Quoted_str, D_P_Chk_DSQuote 2213 <1> ; 2214 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_SaveSI_Cmpx(R), D_P_Save_EOB(R) 2215 <1> ;*********************************************************************** 2216 <1> D_P_Complex_Format proc ;AN000; 2217 <1> push ax ;AN000; 2218 <1> push bx ;AN000; 2219 <1> push si ;AN000; 2220 <1> mov bx,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; bx points to user buffer 2221 <1> cmp byte ptr [bx],D_P_Lparen ;AN000; 1st char = left parentheses 2222 <1> jne D_P_Cmpx_Err ;AN000; 2223 <1> 2224 <1> xor ah,ah ;AN000; ah = parentheses counter 2225 <1> D_P_Cmpx_Loop: ;AN000; 2226 <1> mov al,[bx] ;AN000; load character from command buffer 2227 <1> call D_P_Chk_EOL ;AN000; if it is one of EOL 2228 <1> je D_P_CmpxErr0 ;AN000; then error exit. 2229 <1> 2230 <1> cmp al,D_P_Lparen ;AN000; left parentheses ? 2231 <1> jne D_P_Cmpx00 ;AN000; then 2232 <1> 2233 <1> inc ah ;AC035; add '1' to AH reg 2234 <1> ;AN000; increment parentheses counter 2235 <1> ;(replaced ;AC035;) add ah,1 ;AN000; increment parentheses counter 2236 <1> jc D_P_CmpxErr0 ;AN000; if overflow, error 2237 <1> D_P_Cmpx00: ;AN000; 2238 <1> cmp al,D_P_Rparen ;AN000; right parentheses ? 2239 <1> jne D_P_Cmpx01 ;AN000; then 2240 <1> 2241 <1> dec ah ;AC035; subtract '1' from AH reg 2242 <1> ;AN000; decrement parentheses counter 2243 <1> ;(changed ;AC035;) sub ah,1 ;AN000; decrement parentheses counter 2244 <1> jc D_P_CmpxErr0 ;AN000; if overflow error 2245 <1> 2246 <1> je D_P_Cmpx03 ;AN000; ok, valid complex 2247 <1> 2248 <1> D_P_Cmpx01: ;AN000; 2249 <1> ;(deleted ;AN025;) call D_P_Chk_DSQuote ;AN000; double or single quotation mark ? 3/17/KK 2250 <1> cmp al,D_P_DQuote ;AN025; double quotation mark? 2251 <1> jne D_P_Cmpx04 ;AN000; 3/17/KK 2252 <1> 2253 <1> mov [psdata_seg:si],al ;AN000; here quoted string is found in the complex list. 2254 <1> inc si ;AN000; 2255 <1> inc bx ;AN000; bx points to 2nd character 2256 <1> call D_P_Quoted_Str ;AN000; skip pointers until closing of quoted string 2257 <1> jc D_P_CmpxErr0 ;AN000; if error in quoted string syntax then exit 2258 <1> 2259 <1> jmp short D_P_Cmpx05 ;AN000; 2260 <1> 2261 <1> D_P_Cmpx04: ;AN000; 2262 <1> call D_P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? 2263 <1> jnc D_P_Cmpx02 ;AN000; 2264 <1> 2265 <1> mov [psdata_seg:si],al ;AN000; then store 1st byte 2266 <1> inc si ;AN000; 2267 <1> inc bx ;AN000; 2268 <1> mov al,[bx] ;AN000; load 2nd byte 2269 <1> D_P_Cmpx02: ;AN000; 2270 <1> mov [psdata_seg:si],al ;AN000; store SBCS or 2nd byte of DBCS 2271 <1> D_P_Cmpx05: ;AN000; 2272 <1> inc si ;AN000; 2273 <1> inc bx ;AN000; 2274 <1> jmp short D_P_Cmpx_Loop ;AN000; loop 2275 <1> ;---- ;AN000; 2276 <1> D_P_Cmpx03: ;AN000; 2277 <1> mov byte ptr [psdata_seg:si],al ;AN000; 2278 <1> mov byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; 2279 <1> mov byte ptr [bx],D_P_NULL ;AN000; replace right parentheses with NULL 2280 <1> mov si,bx ;AN000; skip whitespaces 2281 <1> inc si ;AN000; after 2282 <1> call D_P_Skip_Delim ;AN000; right parentheses 2283 <1> mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 2284 <1> jmp short D_P_Cmpx_Exit ;AN000; 2285 <1> 2286 <1> D_P_CmpxErr0: ;AN000; 2287 <1> mov si,[psdata_seg:D_P_Save_EOB] ;AC034; if EOF encountered, restore 2288 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; EOB mark 2289 <1> D_P_Cmpx_Err: ;AN000; 2290 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 2291 <1> D_P_Cmpx_Exit: ;AN000; 2292 <1> mov ah,D_P_No_Tag ;AN000; 2293 <1> mov al,D_P_Complex ;AN000; 2294 <1> pop si ;AN000; 2295 <1> pop bx ;AN000; 2296 <1> call D_P_Fill_Result ;AN000; 2297 <1> pop ax ;AN000; 2298 <1> ret ;AN000; 2299 <1> D_P_Complex_Format endp ;AN000; 2300 <1> %ENDIF ;AN000;(of CpmxSW) 2301 <1> ;PAGE ;AN000; 2302 <1> ;*********************************************************************** 2303 <1> %IF QusSW ;AN000;(Check if quoted string is supported) 2304 <1> ; D_P_Quoted_Format: 2305 <1> ; 2306 <1> ; Function: Check if the input string is valid quoted string format. 2307 <1> ; And set the result buffer. 2308 <1> ; 2309 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2310 <1> ; ES:BX -> CONTROL block 2311 <1> ; 2312 <1> ; Output: None 2313 <1> ; 2314 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_Chk_EOL, D_P_Skip_Delim 2315 <1> ; D_P_Chk_DSQuote, D_P_Quoted_Str 2316 <1> ; 2317 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_SaveSI_Cmpx(R),D_P_Save_EOB(R) 2318 <1> ;*********************************************************************** 2319 <1> D_P_Quoted_Format proc ;AN000; 2320 <1> push ax ;AN000; 2321 <1> push bx ;AN000; 2322 <1> push si ;AN000; 2323 <1> mov bx,[psdata_seg:D_P_SaveSI_Cmpx] ;AC034; bx points to user buffer 2324 <1> mov al,byte ptr [bx] ;AN000; get 1st character 2325 <1> ;(deleted ;AN025;) call D_P_Chk_DSQuote ;AN000; is it single or double quote ? 2326 <1> cmp al,D_P_DQuote ;AN025; double quotation mark? 2327 <1> jne D_P_Qus_Err ;AN000; if no, error 2328 <1> 2329 <1> ; mov [psdata_seg:si],al ;AN000; move it to internal buffer 2330 <1> ; inc si ;AN000; 2331 <1> inc bx ;AN000; bx points to 2nd character 2332 <1> call D_P_Quoted_Str ;AN000; skip pointers to the closing of quoted string 2333 <1> jc D_P_Qus_Err0 ;AN000; if invali quoted string syntax, exit 2334 <1> 2335 <1> mov byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; end up with NULL 2336 <1> mov si,bx ;AN000; 2337 <1> inc si ;AN000; 2338 <1> call D_P_Skip_Delim ;AN000; skip whitespaces after closing quote 2339 <1> mov [psdata_seg:D_P_SI_Save],si ;AC034; save next pointer, SI 2340 <1> jmp short D_P_Qus_Exit ;AN000; 2341 <1> 2342 <1> D_P_Qus_Err0: ;AN000; 2343 <1> mov si,[psdata_seg:D_P_Save_EOB] ;AC034; if EOF encountered, restore 2344 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; EOB mark 2345 <1> D_P_Qus_Err: ;AN000;AN000 2346 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; indicate syntax error 2347 <1> D_P_Qus_Exit: ;AN000; 2348 <1> mov ah,D_P_No_Tag ;AN000; set 2349 <1> mov al,D_P_Quoted_String ;AN000; result 2350 <1> pop si ;AN000; buffer 2351 <1> pop bx ;AN000; to 2352 <1> call D_P_Fill_Result ;AN000; quoted string 2353 <1> pop ax ;AN000; 2354 <1> ret ;AN000; 2355 <1> D_P_Quoted_Format endp ;AN000; 2356 <1> %ENDIF ;AN000;(of QusSW) 2357 <1> ;PAGE ;AN000; 2358 <1> ;*********************************************************************** 2359 <1> ; D_P_Chk_DSQuote; 2360 <1> ; 2361 <1> ; Function: Check if AL is double quotation or single quotation 2362 <1> ; 2363 <1> ; Input: AL = byte to be examineed 2364 <1> ; 2365 <1> ; Output: ZF on if AL is single or double quotetaion 2366 <1> ; 2367 <1> ; Vars: D_P_SorD_Quote(W) 2368 <1> ;*********************************************************************** 2369 <1> %IF QusSW+CmpxSW ;AN000;(Check if quoted string or complex item is supported) 2370 <1> ;(deleted ;AN025;) D_P_Chk_DSQuote proc ; 2371 <1> ;(deleted ;AN025;) mov D_P_SorD_Quote,D_P_SQuote ; 3/17/87 assume single quote 2372 <1> ;(deleted ;AN025;) cmp al,D_P_DQuote ; 1st char = double quotation ? 2373 <1> ;(deleted ;AN025;) jne D_P_CDSQ00 ; 3/17/87 2374 <1> ;(deleted ;AN025;) mov D_P_SorD_Quote,al ; 3/17/87 set bigning w/ double quote 2375 <1> ;(deleted ;AN025;) ret ; 3/17/87 2376 <1> ;(deleted ;AN025;) D_P_CDSQ00: ; 3/17/87 2377 <1> ;(deleted ;AN025;) cmp al,D_P_SQuote ; 1st char = single quotation ? 2378 <1> ;(deleted ;AN025;) ret ; 2379 <1> ;(deleted ;AN025;) D_P_Chk_DSQuote endp ; 2380 <1> ; PAGE ;AN000; 2381 <1> ;*********************************************************************** 2382 <1> ; D_P_Quoted_Str: 2383 <1> ; 2384 <1> ; Function: Copy chracacter from ES:BX to psdata_seg:SI until closing single 2385 <1> ; (double) quotation found. 2386 <1> ; 2387 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2388 <1> ; ES:BX -> Operand in command buffer 2389 <1> ; 2390 <1> ; Output: CY on indicates EOF encounterd before closing quotation 2391 <1> ; BX and SI 2392 <1> ; 2393 <1> ; 2394 <1> ; Vars: D_P_SorD_Quote(R) 2395 <1> ;*********************************************************************** 2396 <1> D_P_Quoted_Str proc ;AN000; 2397 <1> push ax ;AN000; 2398 <1> D_P_Qus_Loop: ;AN000; 2399 <1> mov ax,[bx] ;AN000; 3/17/87 2400 <1> call D_P_Chk_EOL ;AN000; 2401 <1> je D_P_Qustr_Err0 ;AN000; 2402 <1> 2403 <1> ;(deleted ;AN025;) cmp al,D_P_SorD_Quote ;AN000; quotation ? 3/17/87 2404 <1> cmp al,D_P_DQuote ;AN025; double quote? 2405 <1> jne D_P_Qus00 ;AN000; 2406 <1> 2407 <1> ;(deleted ;AN025;) cmp ah,D_P_SorD_Quote ;AN000; contiguous quotation 3/17/87 2408 <1> cmp ah,D_P_DQuote ;AN025; double quote? 2409 <1> jne D_P_Qus02 ;AN000; 2410 <1> 2411 <1> ;(deleted ;AN025:) mov word ptr [psdata_seg:si],ax ;AN000; 3/17/87 2412 <1> mov byte ptr [psdata_seg:si],al ;AN025; save one of the quotes 2413 <1> ;(deleted ;AN025:) add si,2 ;AN000; 2414 <1> 2415 <1> inc si ;AC035; add '1' to SI reg 2416 <1> ;AN025; adjust target index 2417 <1> ;(changed ;AC035;) add si,1 ;AN025; adjust target index 2418 <1> inc bx ;AC035; add '2' to 2419 <1> inc bx ;AC035; BX reg 2420 <1> ;AN000; adjust source index by 2 to skip extra quote 2421 <1> ;(changed ;AC035;) add bx,2 ;AN000; adjust source index by 2 to skip extra quote 2422 <1> jmp short D_P_Qus_Loop ;AN000; 2423 <1> 2424 <1> D_P_Qus00: ;AN000; 2425 <1> call D_P_Chk_DBCS ;AN000; was it a lead byte of DBCS ? 2426 <1> jnc D_P_Qus01 ;AN000; 2427 <1> 2428 <1> mov [psdata_seg:si],al ;AN000; store 1st byte 2429 <1> inc si ;AN000; 2430 <1> inc bx ;AN000; 2431 <1> mov al,[bx] ;AN000; load 2nd byte 2432 <1> D_P_Qus01: ;AN000; 2433 <1> mov [psdata_seg:si],al ;AN000; store SBCS or 2nd byte of DBCS 2434 <1> inc si ;AN000; 2435 <1> inc bx ;AN000; 2436 <1> jmp short D_P_Qus_Loop ;AN000; 2437 <1> 2438 <1> D_P_Qustr_Err0: ;AN000; 2439 <1> stc ;AN000; indicate error 2440 <1> jmp short D_P_Quoted_Str_Exit ;AN000; 2441 <1> 2442 <1> D_P_Qus02: ;AN000; 2443 <1> mov byte ptr [psdata_seg:si],0 ;AN000; 2444 <1> clc ;AN000; indicate no error 2445 <1> D_P_Quoted_Str_Exit: ;AN000; 2446 <1> pop ax ;AN000; 2447 <1> ret ;AN000; 2448 <1> D_P_Quoted_Str endp ;AN000; 2449 <1> %ENDIF ;AN000;(of QusSW+CmpxSW) 2450 <1> ;PAGE ;AN000; 2451 <1> ;*********************************************************************** 2452 <1> %IF FileSW+DrvSW ;AN000;(Check if file spec or drive only is supported) 2453 <1> ; D_P_File_Format; 2454 <1> ; 2455 <1> ; Function: Check if the input string is valid file spec format. 2456 <1> ; And set the result buffer. 2457 <1> ; 2458 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2459 <1> ; ES:BX -> CONTROL block 2460 <1> ; 2461 <1> ; Output: None 2462 <1> ; 2463 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS, D_P_FileSp_Chk 2464 <1> ; 2465 <1> ; Vars: D_P_RC(W), D_P_SI_Save(W), D_P_Terminator(W), D_P_SaveSI_Cmpx(R) 2466 <1> ; D_P_SaveSI_Cmpx(R) 2467 <1> ;*********************************************************************** 2468 <1> D_P_File_Format proc ;AN000; 2469 <1> push ax ;AN000; 2470 <1> push di ;AN000; 2471 <1> push si ;AN000; 2472 <1> D_P_SaveSI_cmpx equ D_P_SaveSI_Cmpx ; NASM port label 2473 <1> mov di,[psdata_seg:D_P_SaveSI_cmpx] ;AC034; get user buffer address 2474 <1> D_P_FileF_Loop0: ;AN000; / skip special characters 2475 <1> mov al,[psdata_seg:si] ;AN000; load character 2476 <1> or al,al ;AN000; end of line ? 2477 <1> je D_P_FileF_Err ;AN000; if yes, error exit 2478 <1> 2479 <1> call D_P_FileSp_Chk ;AN000; else, check if file special character 2480 <1> jne D_P_FileF03 ;AN000; if yes, 2481 <1> 2482 <1> ;AN033; deleted inc di ;skip 2483 <1> ;AN033; deleted inc si ; the 2484 <1> ;AN033; deleted jmp short D_P_FileF_Loop0 ; character 2485 <1> mov byte [psdata_seg:D_P_err_flag],D_P_error_filespec ;AN033;AC034;; set error flag- bad char. 2486 <1> pop si ;AN033; 2487 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN033; 2488 <1> pop di ;AN033; 2489 <1> jmp short D_P_FileF02 ;AN033; 2490 <1> 2491 <1> 2492 <1> D_P_FileF_Err: ;AN000; 2493 <1> pop si ;AN000; 2494 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; 2495 <1> ;(deleted ;AN030;) mov di,D_P_SaveSI_cmpx ;AN000; get user buffer address 2496 <1> ;(deleted ;AN030;) mov D_P_SI_Save,di ;AN000; update pointer to user buffer 2497 <1> pop di ;AN000; 2498 <1> test word [es:bx + D_P_Match_Flag],D_P_Optional ;AN000; is it optional ? 2499 <1> jne D_P_FileF02 ;AN000; 2500 <1> 2501 <1> mov word [psdata_seg:D_P_RC],D_P_Op_Missing ;AC034; 3/17/87 2502 <1> jmp short D_P_FileF02 ;AN000; 2503 <1> 2504 <1> D_P_FileF03: ;AN000; 2505 <1> pop ax ;AN000; discard save si 2506 <1> push si ;AN000; save new si 2507 <1> D_P_FileF_Loop1: ;AN000; 2508 <1> mov al,[psdata_seg:si] ;AN000; load character (not special char) 2509 <1> or al,al ;AN000; end of line ? 2510 <1> je D_P_FileF_RLT ;AN000; 2511 <1> 2512 <1> call D_P_FileSp_Chk ;AN000; File special character ? 2513 <1> je D_P_FileF00 ;AN000; 2514 <1> 2515 <1> call D_P_Chk_DBCS ;AN000; no, then DBCS ? 2516 <1> jnc D_P_FileF01 ;AN000; 2517 <1> inc di ;AN000; if yes, skip next byte 2518 <1> inc si ;AN000; 2519 <1> D_P_FileF01: ;AN000; 2520 <1> inc di ;AN000; 2521 <1> inc si ;AN000; 2522 <1> jmp short D_P_FileF_Loop1 ;AN000; 2523 <1> ; 2524 <1> D_P_FileF00: ;AN000; 2525 <1> mov [psdata_seg:D_P_Terminator],al ;AC034; 2526 <1> mov byte ptr [psdata_seg:si],D_P_NULL ;AN000; update end of string 2527 <1> inc di ;AN000; 2528 <1> mov [psdata_seg:D_P_SI_Save],di ;AC034; update next pointer in command line 2529 <1> D_P_FileF_RLT: ;AN000; 2530 <1> pop si ;AN000; 2531 <1> pop di ;AN000; 2532 <1> D_P_FileF02: ;AN000; 2533 <1> 2534 <1> pop ax ;AN000; (tm14) 2535 <1> test ax,D_P_File_Spc ;AN000; (tm14) 2536 <1> je D_P_Drv_Only_Exit ;AN000; (tm14) 2537 <1> 2538 <1> push ax ;AN000; (tm14) 2539 <1> 2540 <1> mov ah,D_P_No_Tag ;AN000; set 2541 <1> mov al,D_P_File_Spec ;AN000; result 2542 <1> call D_P_Fill_Result ;AN000; buffer to file spec 2543 <1> pop ax ;AN000; 2544 <1> 2545 <1> D_P_Drv_Only_Exit: ;AN000; (tm14) 2546 <1> 2547 <1> ret ;AN000; 2548 <1> D_P_File_Format endp ;AN000; 2549 <1> ;PAGE ;AN000; 2550 <1> ;*********************************************************************** 2551 <1> ; D_P_FileSp_Chk 2552 <1> ; 2553 <1> ; Function: Check if the input byte is one of file special characters 2554 <1> ; 2555 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2556 <1> ; AL = character code to be examineed 2557 <1> ; 2558 <1> ; Output: ZF = 1 , AL is one of special characters 2559 <1> ;*********************************************************************** 2560 <1> D_P_FileSp_Chk proc ;AN000; 2561 <1> push bx ;AN000; 2562 <1> push cx ;AN000; 2563 <1> lea bx,[D_P_FileSp_Char] ;AC034; special character table 2564 <1> mov cx,D_P_FileSp_Len ;AN000; load length of it 2565 <1> D_P_FileSp_Loop: ;AN000; 2566 <1> cmp al,[psdata_seg:bx] ;AN000; is it one of special character ? 2567 <1> je D_P_FileSp_Exit ;AN000; 2568 <1> 2569 <1> inc bx ;AN000; 2570 <1> loop D_P_FileSp_Loop ;AN000; 2571 <1> 2572 <1> inc cx ;AN000; reset ZF 2573 <1> D_P_FileSp_Exit: ;AN000; 2574 <1> pop cx ;AN000; 2575 <1> pop bx ;AN000; 2576 <1> ret ;AN000; 2577 <1> D_P_FileSp_Chk endp ;AN000; 2578 <1> %ENDIF ;AN000;(of FileSW+DrvSW) 2579 <1> ;PAGE ;AN000; 2580 <1> ;*********************************************************************** 2581 <1> %IF DrvSW ;AN000;(Check if drive only is supported) 2582 <1> ; D_P_Drive_Format; 2583 <1> ; 2584 <1> ; Function: Check if the input string is valid drive only format. 2585 <1> ; And set the result buffer. 2586 <1> ; 2587 <1> ; Input: psdata_seg:SI -> D_P_STRING_BUF 2588 <1> ; ES:BX -> CONTROL block 2589 <1> ; 2590 <1> ; Output: None 2591 <1> ; 2592 <1> ; Use: D_P_Fill_Result, D_P_Chk_DBCS 2593 <1> ; 2594 <1> ; Vars: D_P_RC(W) 2595 <1> ;*********************************************************************** 2596 <1> D_P_Drive_Format proc ;AN000; 2597 <1> push ax ;AN000; 2598 <1> push dx ;AN000; 2599 <1> mov al,[psdata_seg:si] ;AN000; 2600 <1> or al,al ;AN000; if null string 2601 <1> je D_P_Drv_Exit ;AN000; do nothing 2602 <1> 2603 <1> call D_P_Chk_DBCS ;AN000; is it leading byte ? 2604 <1> jc D_P_Drv_Err ;AN000; 2605 <1> 2606 <1> cmp word ptr [psdata_seg:si+1],D_P_Colon ;AN000; "d", ":", 0 ? 2607 <1> je D_P_DrvF00 ;AN000; 2608 <1> 2609 <1> test word [es:bx + D_P_Match_Flag],D_P_Ig_Colon ;AN000; colon can be ignored? 2610 <1> je D_P_Drv_Err ;AN000; 2611 <1> 2612 <1> cmp byte ptr [psdata_seg:si+1],D_P_NULL ;AN000; "d", 0 ? 2613 <1> jne D_P_Drv_Err ;AN000; 2614 <1> 2615 <1> D_P_DrvF00: ;AN000; 2616 <1> or al,D_P_Make_Lower ;AN000; lower case 2617 <1> cmp al,"a" ;AN000; drive letter must 2618 <1> jb D_P_Drv_Err ;AN000; in range of 2619 <1> 2620 <1> cmp al,"z" ;AN000; "a" - "z" 2621 <1> ja D_P_Drv_Err ;AN000; if no, error 2622 <1> 2623 <1> sub al,"a"-1 ;AN000; make text drive to binary drive 2624 <1> mov dl,al ;AN000; set 2625 <1> mov ah,D_P_No_Tag ;AN000; result 2626 <1> mov al,D_P_Drive ;AN000; buffer 2627 <1> call D_P_Fill_Result ;AN000; to drive 2628 <1> jmp short D_P_Drv_Exit ;AN000; 2629 <1> 2630 <1> D_P_Drv_Err: ;AN000; 2631 <1> mov word [psdata_seg:D_P_RC],D_P_Syntax ;AC034; 2632 <1> D_P_Drv_Exit: ;AN000; 2633 <1> pop dx ;AN000; 2634 <1> pop ax ;AN000; 2635 <1> ret ;AN000; 2636 <1> D_P_Drive_Format endp ;AN000; 2637 <1> %ENDIF ;AN000;(of DrvSW) 2638 <1> ;PAGE ;AN000; 2639 <1> ;*********************************************************************** 2640 <1> ; D_P_Skip_Delim; 2641 <1> ; 2642 <1> ; Function: Skip delimiters specified in the PARMS list, white space 2643 <1> ; and comma. 2644 <1> ; 2645 <1> ; Input: DS:SI -> Command String 2646 <1> ; ES:DI -> Parameter List 2647 <1> ; 2648 <1> ; Output: CY = 1 if the end of line encounterd 2649 <1> ; CY = 0 then SI move to 1st non-delimiter character 2650 <1> ; AL = Last examineed character 2651 <1> ; 2652 <1> ; Use: D_P_Chk_EOL, D_P_Chk_Delim, 2653 <1> ; 2654 <1> ; Vars: D_P_Flags(R) 2655 <1> ;*********************************************************************** 2656 <1> D_P_Skip_Delim proc ;AN000; 2657 <1> D_P_Skip_Delim_Loop: ;AN000; 0 00001C80 AC LODSB ;AN000; 0 00001C81 E82200 call D_P_Chk_EOL ;AN000; is it EOL character ? 0 00001C84 7418 je D_P_Skip_Delim_CY ;AN000; if yes, exit w/ CY on 2661 <1> 0 00001C86 E85300 call D_P_Chk_Delim ;AN000; is it one of delimiters ? 0 00001C89 7516 jne D_P_Skip_Delim_NCY ;AN000; if no, exit w/ CY off 2664 <1> 0 00001C8B 2EF606[3608]20 test byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; extra delim or comma found ? 0 00001C91 74ED je D_P_Skip_Delim_Loop ;AN000; if no, loop 2667 <1> 0 00001C93 2EF606[3608]41 test byte [psdata_seg:D_P_Flags2],D_P_SW+D_P_equ ;AC034; /x , or xxx=zzz , (tm08) 0 00001C99 7409 je short D_P_Exit_At_Extra ;AN000; no switch, no keyword (tm08) 2670 <1> 0 00001C9B 4E dec si ;AN000; backup si for next call (tm08) 0 00001C9C EB06 jmp short D_P_Exit_At_Extra ;AN000; else exit w/ CY off 2673 <1> 2674 <1> D_P_Skip_Delim_CY: ;AN000; 0 00001C9E F9 stc ;AN000; indicate EOL 0 00001C9F EB01 jmp short D_P_Skip_Delim_Exit ;AN000; 2677 <1> 2678 <1> D_P_Skip_Delim_NCY: ;AN000; 0 00001CA1 F8 clc ;AN000; indicate non delim 2680 <1> D_P_Skip_Delim_Exit: ;AN000; in this case, need 0 00001CA2 4E dec si ;AN000; backup index pointer 0 00001CA3 C3 ret ;AN000; 2683 <1> 2684 <1> D_P_Exit_At_Extra: ;AN000; 0 00001CA4 F8 clc ;AN000; indicate extra delim 0 00001CA5 C3 ret ;AN000; 2687 <1> D_P_Skip_Delim endp ;AN000; 2688 <1> ;PAGE ;AN000; 2689 <1> ;*********************************************************************** 2690 <1> ; D_P_Chk_EOL; 2691 <1> ; 2692 <1> ; Function: Check if AL is one of End of Line characters. 2693 <1> ; 2694 <1> ; Input: AL = character code 2695 <1> ; ES:DI -> Parameter List 2696 <1> ; 2697 <1> ; Output: ZF = 1 if one of End of Line characters 2698 <1> ;********************************************************************** 2699 <1> D_P_Chk_EOL proc ;AN000; 0 00001CA6 53 push bx ;AN000; 0 00001CA7 51 push cx ;AN000; 0 00001CA8 3C0D cmp al,D_P_CR ;AN000; Carriage return ? 0 00001CAA 742D je D_P_Chk_EOL_Exit ;AN000; 2704 <1> 0 00001CAC 3C00 cmp al,D_P_NULL ;AN000; zero ? 0 00001CAE 7429 je D_P_Chk_EOL_Exit ;AN000; 2707 <1> 2708 <1> %IF LFEOLSW ;AN028; IF LF TO BE ACCEPTED AS EOL 0 00001CB0 3C0A cmp al,D_P_LF ;AN000; Line feed ? 0 00001CB2 7425 je D_P_Chk_EOL_Exit ;AN000; 2711 <1> %ENDIF ;AN028; 2712 <1> 0 00001CB4 26807D0202 cmp byte ptr [es:di + D_P_Num_Extra],D_P_I_Have_EOL ;AN000; EOL character specified ? 0 00001CB9 721E jb D_P_Chk_EOL_Exit ;AN000; 2715 <1> 0 00001CBB 31DB xor bx,bx ;AN000; 0 00001CBD 268A5D03 mov bl,[es:di + D_P_Len_Extra_Delim] ;AN000; get length of delimiter list 0 00001CC1 83C304 add bx,D_P_Len_PARMS ;AN000; skip it 0 00001CC4 26803900 cmp byte ptr [es:bx+di],D_P_I_Use_Default ;AN000; No extra EOL character ? 0 00001CC8 740D je D_P_Chk_EOL_NZ ;AN000; 2721 <1> 0 00001CCA 31C9 xor cx,cx ;AN000; Get number of extra chcracter 0 00001CCC 268A09 mov cl,[es:bx+di] ;AN000; 2724 <1> D_P_Chk_EOL_Loop: ;AN000; 0 00001CCF 43 inc bx ;AN000; 0 00001CD0 263A01 cmp al,[es:bx+di] ;AN000; Check extra EOL character 0 00001CD3 7404 je D_P_Chk_EOL_Exit ;AN000; 2728 <1> 0 00001CD5 E2F8 loop D_P_Chk_EOL_Loop ;AN000; 2730 <1> 2731 <1> D_P_Chk_EOL_NZ: ;AN000; 0 00001CD7 3C0D cmp al,D_P_CR ;AN000; reset ZF 2733 <1> D_P_Chk_EOL_Exit: ;AN000; 0 00001CD9 59 pop cx ;AN000; 0 00001CDA 5B pop bx ;AN000; 0 00001CDB C3 ret ;AN000; 2737 <1> D_P_Chk_EOL endp ;AN000; 2738 <1> ;PAGE ;AN000; 2739 <1> ;*********************************************************************** 2740 <1> ; D_P_Chk_Delim; 2741 <1> ; 2742 <1> ; Function: Check if AL is one of delimiter characters. 2743 <1> ; if AL+[si] is DBCS blank, it is replaced with two SBCS 2744 <1> ; blanks. 2745 <1> ; 2746 <1> ; Input: AL = character code 2747 <1> ; DS:SI -> Next Character 2748 <1> ; ES:DI -> Parameter List 2749 <1> ; 2750 <1> ; Output: ZF = 1 if one of delimiter characters 2751 <1> ; SI points to the next character 2752 <1> ; Vars: D_P_Terminator(W), D_P_Flags(W) 2753 <1> ;*********************************************************************** 2754 <1> D_P_Chk_Delim proc ;AN000; 0 00001CDC 53 push bx ;AN000; 0 00001CDD 51 push cx ;AN000; 0 00001CDE 2EC606[3008]20 mov byte [psdata_seg:D_P_Terminator],D_P_Space ;AC034; Assume terminated by space 0 00001CE4 2E8026[3608]DF and byte [psdata_seg:D_P_Flags2],0ffh-D_P_Extra ;AC034; 0 00001CEA 3C20 cmp al,D_P_Space ;AN000; Space ? 0 00001CEC 7436 je D_P_Chk_Delim_Exit ;AN000; 2761 <1> 0 00001CEE 3C09 cmp al,D_P_TAB ;AN000; TAB ? 0 00001CF0 7432 je D_P_Chk_Delim_Exit ;AN000; 2764 <1> 0 00001CF2 3C2C cmp al,D_P_Comma ;AN000; Comma ? 0 00001CF4 7431 je D_P_Chk_Delim_Exit0 ;AN000; 2767 <1> 2768 <1> D_P_Chk_Delim00: ;AN000; 0 00001CF6 3C81 cmp al,D_P_DBSP1 ;AN000; 1st byte of DBCS Space ? 0 00001CF8 750C jne D_P_Chk_Delim01 ;AN000; 2771 <1> 0 00001CFA 803C40 cmp byte ptr [si],D_P_DBSP2 ;AN000; 2nd byte of DBCS Space ? 0 00001CFD 7507 jne D_P_Chk_Delim01 ;AN000; 2774 <1> 0 00001CFF B020 mov al,D_P_Space ;AN000; 0 00001D01 46 inc si ;AN000; make si point to next character 0 00001D02 38C0 cmp al,al ;AN000; Set ZF 0 00001D04 EB1E jmp short D_P_Chk_Delim_Exit ;AN000; 2779 <1> 2780 <1> D_P_Chk_Delim01: ;AN000; 0 00001D06 26807D0201 cmp byte ptr [es:di + D_P_Num_Extra],D_P_I_Have_Delim ;AN000; delimiter character specified ? 0 00001D0B 7217 jb D_P_Chk_Delim_Exit ;AN000; 2783 <1> 0 00001D0D 31C9 xor cx,cx ;AN000; 0 00001D0F 268A4D03 mov cl,[es:di + D_P_Len_Extra_Delim] ;AN000; get length of delimiter list 0 00001D13 09C9 or cx,cx ;AN000; No extra Delim character ? 0 00001D15 740B je D_P_Chk_Delim_NZ ;AN000; 2788 <1> 0 00001D17 BB0300 mov bx,D_P_Len_PARMS-1 ;AN000; set bx to 1st extra delimiter 2790 <1> D_P_Chk_Delim_Loop: ;AN000; 0 00001D1A 43 inc bx ;AN000; 0 00001D1B 263A01 cmp al,[es:bx+di] ;AN000; Check extra Delim character 0 00001D1E 7407 je D_P_Chk_Delim_Exit0 ;AN000; 2794 <1> 0 00001D20 E2F8 loop D_P_Chk_Delim_Loop ;AN000; examine all extra delimiter 2796 <1> 2797 <1> D_P_Chk_Delim_NZ: ;AN000; 0 00001D22 3C20 cmp al,D_P_Space ;AN000; reset ZF 2799 <1> D_P_Chk_Delim_Exit: ;AN000; 2800 <1> ;;;; jne D_P_ChkDfin 2801 <1> ;;;; mov psdata_seg:D_P_Terminator,al ;AN034; 2802 <1> D_P_ChkDfin: ;AN000; 0 00001D24 59 pop cx ;AN000; 0 00001D25 5B pop bx ;AN000; 0 00001D26 C3 ret ;AN000; 2806 <1> 2807 <1> D_P_Chk_Delim_Exit0: ;AN000; 0 00001D27 2EA2[3008] mov [psdata_seg:D_P_Terminator],al ;AC034; keep terminated delimiter 2809 <1> D_P_Equ equ D_P_equ ; NASM port equate 0 00001D2B 2EF606[3608]01 test byte [psdata_seg:D_P_Flags2],D_P_Equ ;AN027;AC034;; if terminating a key= 0 00001D31 7506 jnz D_P_No_Set_Extra ;AN027; then do not set the EXTRA bit 2812 <1> 0 00001D33 2E800E[3608]20 or byte [psdata_seg:D_P_Flags2],D_P_Extra ;AC034; flag terminated extra delimiter or comma 2814 <1> D_P_No_Set_Extra: ;AN027; 0 00001D39 38C0 cmp al,al ;AN000; set ZF 0 00001D3B EBE7 jmp short D_P_Chk_Delim_Exit ;AN000; 2817 <1> 2818 <1> D_P_Chk_Delim endp ;AN000; 2819 <1> ;PAGE ;AN000; 2820 <1> ;*********************************************************************** 2821 <1> ; D_P_Chk_Switch; 2822 <1> ; 2823 <1> ; Function: Check if AL is the switch character not in first position of 2824 <1> ; D_P_STRING_BUF 2825 <1> ; 2826 <1> ; Input: AL = character code 2827 <1> ; BX = current pointer within D_P_String_Buf 2828 <1> ; SI =>next char on command line (following the one in AL) 2829 <1> ; 2830 <1> ; Output: CF = 1 (set)if AL is switch character, and not in first 2831 <1> ; position, and has no chance of being part of a date string, 2832 <1> ; i.e. should be treated as a delimiter. 2833 <1> 2834 <1> ; CF = 0 (reset, cleared) if AL is not a switch char, is in the first 2835 <1> ; position, or is a slash but may be part of a date string, i.e. 2836 <1> ; should not be treated as a delimiter. 2837 <1> ; 2838 <1> ; Vars: D_P_Terminator(W) 2839 <1> 2840 <1> ; Use: D_P_0099 2841 <1> ;*********************************************************************** 2842 <1> D_P_Chk_Switch proc ;AN000; 2843 <1> 2844 <1> ;AN020;; Function: Check if AL is the switch character from 2nd position of D_P_STRING_BUF 2845 <1> ;AN020;; Output: ZF = 1 if switch character 2846 <1> ;AN020;; lea bp,D_P_STRING_BUF ;AN000; 2847 <1> ;AN020;; cmp bx,bp ;AN000; 1st position ? 2848 <1> ;AN020;; je D_P_Chk_S_Exit_1 ;AN000; 2849 <1> ;AN020;; cmp al,D_P_Switch ;AN000; 2850 <1> ;AN020;; jmp short D_P_Chk_S_Exit_0 ;AN000; 2851 <1> ;AN020;;D_P_Chk_S_Exit_1: ;AN000; 2852 <1> ;AN020;; cmp al,D_P_Switch ;AN000; (tm08) 2853 <1> ;AN020;; jne D_P_Nop ;AN000; (tm08) 2854 <1> ;AN020;; or D_P_Flags2,D_P_SW ;AN000; (tm08) It could be valid switch 2855 <1> ;AN020;;D_P_Nop: ;AN000; (tm08) 2856 <1> ;AN020;; inc bp ;AN000; 2857 <1> ;AN020;; cmp bx,bp ;AN000; reset ZF 2858 <1> ;AN020;;D_P_Chk_S_Exit_0: ;AN000; 2859 <1> ;AN020;; jne D_P_Chk_S_Exit ;AN000; 2860 <1> ;AN020;; mov D_P_Terminator,al ;AN000; store switch character 2861 <1> ;AN020;;D_P_Chk_S_Exit: ;AN000; 2862 <1> 2863 <1> D_P_String_Buf equ D_P_STRING_BUF ; NASM port label 0 00001D3D 8D2E[3F08] LEA BP,[D_P_String_Buf] ;AN020;AC034; BP=OFFSET of D_P_String_Buf even in group addressing 2865 <1> ; .IF THEN ;AN020;IF not first char THEN 0 00001D41 39EB cmp BX,BP ;AN000; 0 00001D43 740A je D_P_STRUC_L2 ;AN000; 2868 <1> 2869 <1> ; .IF THEN ;AN020;otherwise see if a slash 0 00001D45 3C2F cmp AL,D_P_Switch ;AN000; 0 00001D47 7503 jne D_P_STRUC_L5 ;AN000; 2872 <1> 0 00001D49 F9 STC ;AN020;not in first position and is slash, now see if might be in date string 2874 <1> %IF DateSw ;AN020;caller looking for date, see if this may be part of one 2875 <1> PUSH AX ;AN020;save input char 2876 <1> MOV AL,[PSDATA_SEG:BX-1] ;AN026;AL=char before the current char 2877 <1> CALL D_P_0099 ;AN020;return carry set if not numeric 2878 <1> ; .IF NC ;AND ;AN020;IF previous char numeric AND 2879 <1> jc D_P_STRUC_L7 ;AN000; 2880 <1> 2881 <1> MOV AL,[SI] ;AN020;AL=char after the current char 2882 <1> CALL D_P_0099 ;AN020;return carry set if not numeric 2883 <1> ;(deleted) .IF NC THEN ;AN020;IF next char numeric THEN could be a date 2884 <1> ;(deleted) CLC ;AN020;reset CF so "/" not treated as a delimiter 2885 <1> ;(deleted) .ENDIF ;AN026; 2886 <1> ; .ENDIF ;AN020;ENDIF looks like date (number/number) 2887 <1> D_P_STRUC_L7: ;AN000; 2888 <1> POP AX ;AN020;restore AL to input char 2889 <1> %ENDIF ;AN020;DateSw 2890 <1> ; .ELSE ;AN020; 0 00001D4A EB0E jmp short D_P_STRUC_L1 ;AN000; 2892 <1> 2893 <1> D_P_STRUC_L5: ;AN000; 0 00001D4C F8 CLC ;AN020;not a slash 2895 <1> ; .ENDIF ;AN020; 2896 <1> ; .ELSE ;AN020;is first char in the buffer, ZF=0 0 00001D4D EB0B jmp short D_P_STRUC_L1 ;AN000; 2898 <1> 2899 <1> D_P_STRUC_L2: ;AN000; 2900 <1> ; .IF THEN ;AN020; 0 00001D4F 3C2F cmp AL,D_P_Switch ;AN000; 0 00001D51 7506 jne D_P_STRUC_L12 ;AN000; 2903 <1> 0 00001D53 2E800E[3608]40 OR byte [psdata_seg:D_P_Flags2],D_P_SW ;AN020;AC034;;could be valid switch, first char and is slash 2905 <1> ; .ENDIF ;AN020; 2906 <1> D_P_STRUC_L12: ;AN000; 0 00001D59 F8 CLC ;AN020;CF=0 indicating first char 2908 <1> ; .ENDIF ;AN020; 2909 <1> D_P_STRUC_L1: ;AN000; 2910 <1> 0 00001D5A C3 ret ;AN000; 2912 <1> D_P_Chk_Switch endp ;AN000; 2913 <1> ; PAGE ;AN000; 2914 <1> ;************************************************************************** 2915 <1> ; D_P_Chk_DBCS: 2916 <1> ; 2917 <1> ; Function: Check if a specified byte is in ranges of the DBCS lead bytes 2918 <1> ; 2919 <1> ; Input: 2920 <1> ; AL = Code to be examineed 2921 <1> ; 2922 <1> ; Output: 2923 <1> ; If CF is on then a lead byte of DBCS 2924 <1> ; 2925 <1> ; Use: INT 21h w/AH=63 2926 <1> ; 2927 <1> ; Vars: D_P_DBCSEV_Seg(RW), D_P_DBCSEV_Off(RW) 2928 <1> ;*************************************************************************** 2929 <1> D_P_Chk_DBCS PROC ;AN000; 2930 <1> ; 0 00001D5B 1E PUSH DS ;AN000; 0 00001D5C 56 PUSH SI ;AN000; 0 00001D5D 53 PUSH bx ;AN000; (tm11) 0 00001D5E 2E833E[3308]00 CMP word [psdata_seg:D_P_DBCSEV_SEG],0 ;AC034; ALREADY SET ? 0 00001D64 7527 JNE D_P_DBCS00 ;AN000; 2936 <1> 0 00001D66 50 PUSH AX ;AN000; 2938 <1> ; PUSH BX ;AN000; (tm11) 0 00001D67 1E PUSH ds ;AN000; (tm11) 0 00001D68 51 PUSH CX ;AN000; 0 00001D69 52 PUSH DX ;AN000; 0 00001D6A 57 PUSH DI ;AN000; 0 00001D6B 55 PUSH BP ;AN000; 0 00001D6C 06 PUSH ES ;AN000; 0 00001D6D 31F6 XOR SI,SI ;AN000; 0 00001D6F 8EDE MOV DS,SI ;AN000; 0 00001D71 B80063 MOV AX,D_P_DOS_GetEV ;AN000; GET DBCS EV CALL 0 00001D74 CD21 INT 21H ;AN000; 2949 <1> 2950 <1> ; MOV AX,DS ;AN000; (tm11) 2951 <1> ; OR AX,AX ;AN000; (tm11) 0 00001D76 8CDB MOV bx,DS ;AN000; (tm11) 0 00001D78 09DB OR bx,bx ;AN000; (tm11) 0 00001D7A 07 POP ES ;AN000; 0 00001D7B 5D POP BP ;AN000; 0 00001D7C 5F POP DI ;AN000; 0 00001D7D 5A POP DX ;AN000; 0 00001D7E 59 POP CX ;AN000; 2959 <1> ; POP BX ;AN000; (tm11) 0 00001D7F 1F POP ds ;AN000; (tm11) 0 00001D80 58 POP AX ;AN000; 0 00001D81 7429 JE D_P_NON_DBCS ;AN000; 2963 <1> 2964 <1> D_P_DBCS02: ;AN000; 0 00001D83 2E8936[3108] MOV [psdata_seg:D_P_DBCSEV_OFF],SI ;AC034; save EV offset 2966 <1> ; MOV psdata_seg:D_P_DBCSEV_SEG,DS ;AC034; save EV segment 0 00001D88 2E891E[3308] MOV [psdata_seg:D_P_DBCSEV_SEG],bx ;AC034; save EV segment (tm11) 2968 <1> D_P_DBCS00: ;AN000; 0 00001D8D 2E8B36[3108] MOV SI,[psdata_seg:D_P_DBCSEV_OFF] ;AC034; load EV offset 0 00001D92 2E8E1E[3308] MOV DS,[psdata_seg:D_P_DBCSEV_SEG] ;AC034; and segment 2971 <1> 2972 <1> D_P_DBCS_LOOP: ;AN000; 0 00001D97 833C00 CMP WORD PTR [SI],0 ;AN000; zero vector ? 0 00001D9A 7410 JE D_P_NON_DBCS ;AN000; then exit 2975 <1> 0 00001D9C 3A04 CMP AL,[SI] ;AN000; 0 00001D9E 7208 JB D_P_DBCS01 ;AN000; Check if AL is in 2978 <1> 0 00001DA0 3A4401 CMP AL,[SI+1] ;AN000; range of 0 00001DA3 7703 JA D_P_DBCS01 ;AN000; the vector 2981 <1> 0 00001DA5 F9 STC ;AN000; if yes, indicate DBCS and exit 0 00001DA6 EB05 JMP short D_P_DBCS_EXIT ;AN000; 2984 <1> 2985 <1> D_P_DBCS01: ;AN000; 0 00001DA8 46 INC SI ;AC035; add '2' to 0 00001DA9 46 INC SI ;AC035; SI reg 2988 <1> ;AN000; get next vector 2989 <1> ;(changed ;AC035;) ADD SI,2 ;AN000; get next vector 0 00001DAA EBEB JMP short D_P_DBCS_LOOP ;AN000; loop until zero vector found 2991 <1> 2992 <1> D_P_NON_DBCS: ;AN000; 0 00001DAC F8 CLC ;AN000; indicate SBCS 2994 <1> D_P_DBCS_EXIT: ;AN000; 0 00001DAD 5B POP bx ;AN000; (tm11) 0 00001DAE 5E POP SI ;AN000; 0 00001DAF 1F POP DS ;AN000; 0 00001DB0 C3 RET ;AN000; 2999 <1> D_P_Chk_DBCS ENDP ;AN000; 68 ;=== Pop trace listing source 69 %include "msgdcl.mac" 1 <1> ; This Macro was removed from sysmsg.inc. We had to remove this 2 <1> ; macro and put it into it's own include file in order to clear up 3 <1> ; some assembly errors. MS MASM will not allow a public declaration 4 <1> ; during the second pass of the assembler. IBM MASM will allow this. 5 <1> ; 6 <1> ; 7 <1> ; 8 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 9 <1> ;; $M_DECLARE Macro 10 <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 11 <1> 12 <1> ; NASM original macros 13 <1> 14 <1> %imacro $M_DECLARE 1 15 <1> %iassign $M_DCOUNT 0 16 <1> %rep %1 17 <1> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <1> $M_DECLARE2 $M_DCOUNT 19 <1> %endrep 20 <1> 21 <1> %IF COMR 22 <1> EXTRN $M_RT2:BYTE 23 <1> %ELSE 24 <1> EXTRN $M_RT:BYTE 25 <1> %ENDIF 26 <1> 27 <1> $M_CHECK $M_MSGSERV_1 ; If this subroutine is not in this assembly, 28 <1> $M_CHECK $M_MSGSERV_2 ; If this subroutine is not in this assembly, 29 <1> %endmacro 30 <1> 31 <1> %imacro $M_DECLARE2 1 32 <1> %IFN COMR ; IF Not resident COMMAND.COM 33 <1> %IFN COMT ; IF Not transient COMMAND.COM 34 <1> %IF FARmsg 35 <1> EXTRN $M_CLS_%1:FAR 36 <1> %ELSE 37 <1> EXTRN $M_CLS_%1:NEAR 38 <1> %ENDIF 39 <1> %ELSE ; ELSE 40 <1> %ifnidni $M_CLS_%1, $M_CLS_1 ; IF NOT $M_CLS_1 or 41 <1> %ifnidni $M_CLS_%1, $M_CLS_2 ; IF NOT $M_CLS_2 then 42 <1> %IF FARmsg ; 43 <1> EXTRN $M_CLS_%1:FAR 44 <1> %ELSE ; 45 <1> EXTRN $M_CLS_%1:NEAR 46 <1> %ENDIF ; 47 <1> %ENDIF ; 48 <1> %ENDIF ; 49 <1> %ENDIF ; 50 <1> %ELSE ; ELSE 51 <1> %ifnidni $M_CLS_%1, $M_CLS_1 ; IF NOT $M_CLS_1 or 52 <1> %ifnidni $M_CLS_%1, $M_CLS_2 ; IF NOT $M_CLS_2 then 53 <1> %IF FARmsg ; 54 <1> EXTRN $M_CLS_%1:FAR 55 <1> %ELSE ; 56 <1> EXTRN $M_CLS_%1:NEAR 57 <1> %ENDIF ; 58 <1> %ENDIF ; 59 <1> %ENDIF ; 60 <1> %ENDIF ; 61 <1> %ENDMacro ; 62 <1> ; 63 <1> %imacro $M_CHECK 1 64 <1> %IF FARmsg ; 65 <1> EXTRN %1:FAR ; Must be external 66 <1> %ELSE ; 67 <1> EXTRN %1:NEAR ; Must be external 68 <1> %ENDIF ; 69 <1> %ENDMacro ; 70 <1> 71 <1> $M_DECLARE $M_NUM_CLS ; Declare any class not in this assembly 15 <2> %iassign $M_DCOUNT 0 16 <2> %rep %1 17 <2> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <2> $M_DECLARE2 $M_DCOUNT 19 <2> %endrep 17 <3> %iassign $M_DCOUNT $M_DCOUNT + 1 18 <3> $M_DECLARE2 $M_DCOUNT 32 <4> %IFN COMR 33 <4> %IFN COMT 34 <4> %IF FARmsg 35 <4> EXTRN $M_CLS_%1:FAR 36 <4> %ELSE 37 <4> EXTRN $M_CLS_%1:NEAR 38 <4> %ENDIF 39 <4> %ELSE 40 <4> %ifnidni $M_CLS_%1, $M_CLS_1 41 <4> %ifnidni $M_CLS_%1, $M_CLS_2 42 <4> %IF FARmsg 43 <4> EXTRN $M_CLS_%1:FAR 44 <4> %ELSE 45 <4> EXTRN $M_CLS_%1:NEAR 46 <4> %ENDIF 47 <4> %ENDIF 48 <4> %ENDIF 49 <4> %ENDIF 50 <4> %ELSE 51 <4> %ifnidni $M_CLS_%1, $M_CLS_1 52 <4> %ifnidni $M_CLS_%1, $M_CLS_2 53 <4> %IF FARmsg 54 <4> EXTRN $M_CLS_%1:FAR 55 <4> %ELSE 56 <4> EXTRN $M_CLS_%1:NEAR 57 <4> %ENDIF 58 <4> %ENDIF 59 <4> %ENDIF 60 <4> %ENDIF 20 <2> 21 <2> %IF COMR 22 <2> EXTRN $M_RT2:BYTE 23 <2> %ELSE 24 <2> EXTRN $M_RT:BYTE 25 <2> %ENDIF 26 <2> 27 <2> $M_CHECK $M_MSGSERV_1 64 <3> %IF FARmsg 65 <3> EXTRN %1:FAR 66 <3> %ELSE 67 <3> EXTRN %1:NEAR 68 <3> %ENDIF 28 <2> $M_CHECK $M_MSGSERV_2 64 <3> %IF FARmsg 65 <3> EXTRN %1:FAR 66 <3> %ELSE 67 <3> EXTRN %1:NEAR 68 <3> %ENDIF 70 ; .cref 71 72 73 74 ; (no prior section) ; Share ENDS 75 END 76 77 === Trace listing source: sharelnk.lst 1 ; PAGE ,132 ;  2 ; SCCSID = @(#)SHARELNK.asm 1.0 87/05/11 3 ;TITLE SHARELNK LINK FIX ROUTINES - Routines to resolve SHARE externals 4 ;NAME SHARELNK 5 === Switch to base=001DC0h -> "CODE" 6 section CODE align=1 PUBLIC class=CODE 7 ; (no prior section) ; code ENDS 8 9 [list -] 9 ****************** warning: out: ... for DOS Version 4.00 ... [-w+user] 9 ****************** warning: out: BPB.INC... [-w+user] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: out: ... CLONE version build switch on ... [-w+user] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: out: DEVSYM.INC... [-w+user] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 9 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 15 16 %include "dosseg.nas" 1 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 2 <1> ; SCCSID = @(#)dosseg.asm 1.1 85/04/10 3 <1> ; 4 <1> ; segment ordering for MSDOS 5 <1> ; 6 <1> 7 <1> %include "ddataseg.nas" 1 <2> === Switch to base=001DC0h -> "DOSSTART" 2 <2> section DOSSTART align=16 PUBLIC class=DOSSTART 3 <2> ; (no prior section) ; DOSSTART ENDS 4 <2> === Switch to base=001DC0h -> "START" 5 <2> section START align=1 PUBLIC class=START 6 <2> ; (no prior section) ; START ENDS 7 <2> === Switch to base=001DC0h -> "CONSTANTS" 8 <2> section CONSTANTS align=2 PUBLIC class=CONST 9 <2> ; (no prior section) ; CONSTANTS ENDS 10 <2> === Switch to base=001DC0h -> "DATA" 11 <2> section DATA align=2 PUBLIC class=DATA 12 <2> ; (no prior section) ; DATA ENDS 13 <2> === Switch to base=001DC0h -> "TABLE" 14 <2> section TABLE align=2 PUBLIC class=TABLE 15 <2> ; (no prior section) ; TABLE ENDS 16 <2> === Switch to base=001DC0h -> "CODE" 17 <2> section CODE align=1 PUBLIC class=CODE 17 ****************** <2> warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 18 <2> ; (no prior section) ; CODE ENDS 19 <2> === Switch to base=001DC0h -> "DOSDATATABLE" 20 <2> section DOSDATATABLE align=2 PUBLIC class=DOSDATACODE 21 <2> ; (no prior section) ; DOSDATATABLE ENDS 22 <2> === Switch to base=001DC0h -> "DOSDATACODE" 23 <2> section DOSDATACODE align=1 PUBLIC class=DOSDATACODE 24 <2> ; (no prior section) ; DOSDATACODE ENDS 25 <2> === Switch to base=001DC0h -> "LAST" 26 <2> section LAST align=16 PUBLIC class=LAST 27 <2> ; (no prior section) ; LAST ENDS 28 <2> 29 <2> group DOSGROUP DOSSTART START CONSTANTS DATA TABLE CODE DOSDATATABLE DOSDATACODE LAST 8 <1> 9 <1> %include "dcodeseg.nas" 1 <2> 2 <2> %ifndef DCODESEGNAS 3 <2> %assign DCODESEGNAS 1 4 <2> === Switch to base=003490h -> "DOSCODETABLE" 5 <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <2> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <2> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <2> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <2> 12 <2> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <2> 14 <2> %endif 10 <1> === Switch to base=001DC0h -> "LAST" 11 <1> section LAST 12 <1> ; (no prior section) ; LAST ENDS 17 18 === Switch to base=001DC0h -> "CODE" 19 section CODE align=1 PUBLIC class=CODE 19 ****************** warning: segment attributes specified on redeclaration of segment: ignoring [-w+other] 20 ASSUME CS:dosgroup 21 0 00000FEE ?? times 52Fh db ? 23 24 ; (no prior section) ; code ENDS 25 END === Trace listing source: ../../INC/nibdosn.lst 1 %include "nobits.mac" 1 <1> %imacro stripparens 2.nolist 2 <1> %defstr %%param %2 3 <1> %rep 16 4 <1> %substr %%opening %%param 1 5 <1> %ifidn %%opening, '(' 6 <1> %substr %%param %%param 2,-1 7 <1> %endif 8 <1> %endrep 9 <1> %rep 16 10 <1> %strlen %%length %%param 11 <1> %substr %%closing %%param %%length 12 <1> %ifidn %%closing, ')' 13 <1> %substr %%param %%param 1,-2 14 <1> %endif 15 <1> %endrep 16 <1> %deftok %%token %%param 17 <1> %1 %%token 18 <1> %endmacro 19 <1> 20 <1> %imacro db 1-*.nolist 21 <1> %rep %0 22 <1> %define %%param %1 23 <1> %define %%multi 24 <1> %defstr %%string %%param 25 <1> %strlen %%stringlength %%string 26 <1> %assign %%index 1 27 <1> %rep %%stringlength 28 <1> %substr %%checkblank %%string %%index 29 <1> %ifidni %%checkblank, '"' 30 <1> %elifidni %%checkblank, "'" 31 <1> %else 32 <1> %deftok %%checkblank %%checkblank 33 <1> %ifempty %%checkblank 34 <1> %substr %%dup %%string %%index + 1,4 35 <1> %deftok %%dup %%dup 36 <1> %assign %%isdup 0 37 <1> %ifidni %%dup, dup 38 <1> %assign %%isdup 1 39 <1> %elifidni %%dup, dup( 40 <1> %assign %%isdup 1 41 <1> %endif 42 <1> %if %%isdup 43 <1> %substr %%multi %%string 1, %%index - 1 44 <1> %deftok %%multi %%multi 45 <1> %substr %%string %%string %%index + 5, -1 46 <1> %deftok %%token %%string 47 <1> %undef %%param 48 <1> stripparens %define %%param, %%token 49 <1> %assign %%length 1 50 <1> %ifstr %%param 51 <1> %strlen %%length %%param 52 <1> %endif 53 <1> %rep %%length * %%multi 54 <1> db ? 55 <1> %endrep 56 <1> %exitrep 57 <1> %endif 58 <1> %endif 59 <1> %endif 60 <1> %assign %%index %%index + 1 61 <1> %endrep 62 <1> %ifempty %%multi 63 <1> %assign %%length 1 64 <1> %ifstr %%param 65 <1> %strlen %%length %%param 66 <1> %endif 67 <1> %rep %%length 68 <1> db ? 69 <1> %endrep 70 <1> %endif 71 <1> %rotate 1 72 <1> %endrep 73 <1> %endmacro 74 <1> 75 <1> %imacro dw 1-*.nolist 76 <1> %rep %0 77 <1> %define %%param %1 78 <1> %define %%multi 79 <1> %defstr %%string %%param 80 <1> %strlen %%stringlength %%string 81 <1> %assign %%index 1 82 <1> %rep %%stringlength 83 <1> %substr %%checkblank %%string %%index 84 <1> %ifidni %%checkblank, '"' 85 <1> %elifidni %%checkblank, "'" 86 <1> %else 87 <1> %deftok %%checkblank %%checkblank 88 <1> %ifempty %%checkblank 89 <1> %substr %%dup %%string %%index + 1,4 90 <1> %deftok %%dup %%dup 91 <1> %assign %%isdup 0 92 <1> %ifidni %%dup, dup 93 <1> %assign %%isdup 1 94 <1> %elifidni %%dup, dup( 95 <1> %assign %%isdup 1 96 <1> %endif 97 <1> %if %%isdup 98 <1> %substr %%multi %%string 1, %%index - 1 99 <1> %deftok %%multi %%multi 100 <1> %substr %%string %%string %%index + 5, -1 101 <1> %deftok %%token %%string 102 <1> %undef %%param 103 <1> stripparens %define %%param, %%token 104 <1> %assign %%length 1 105 <1> %ifstr %%param 106 <1> %strlen %%length %%param 107 <1> %assign %%length (%%length + 1) / 2 108 <1> %endif 109 <1> %rep %%length * %%multi 110 <1> dw ? 111 <1> %endrep 112 <1> %exitrep 113 <1> %endif 114 <1> %endif 115 <1> %endif 116 <1> %assign %%index %%index + 1 117 <1> %endrep 118 <1> %ifempty %%multi 119 <1> %assign %%length 1 120 <1> %ifstr %%param 121 <1> %strlen %%length %%param 122 <1> %assign %%length (%%length + 1) / 2 123 <1> %endif 124 <1> %rep %%length 125 <1> dw ? 126 <1> %endrep 127 <1> %endif 128 <1> %rotate 1 129 <1> %endrep 130 <1> %endmacro 131 <1> 132 <1> %imacro dd 1-*.nolist 133 <1> %rep %0 134 <1> %define %%param %1 135 <1> %define %%multi 136 <1> %defstr %%string %%param 137 <1> %strlen %%stringlength %%string 138 <1> %assign %%index 1 139 <1> %rep %%stringlength 140 <1> %substr %%checkblank %%string %%index 141 <1> %ifidni %%checkblank, '"' 142 <1> %elifidni %%checkblank, "'" 143 <1> %else 144 <1> %deftok %%checkblank %%checkblank 145 <1> %ifempty %%checkblank 146 <1> %substr %%dup %%string %%index + 1,4 147 <1> %deftok %%dup %%dup 148 <1> %assign %%isdup 0 149 <1> %ifidni %%dup, dup 150 <1> %assign %%isdup 1 151 <1> %elifidni %%dup, dup( 152 <1> %assign %%isdup 1 153 <1> %endif 154 <1> %if %%isdup 155 <1> %substr %%multi %%string 1, %%index - 1 156 <1> %deftok %%multi %%multi 157 <1> %substr %%string %%string %%index + 5, -1 158 <1> %deftok %%token %%string 159 <1> %undef %%param 160 <1> stripparens %define %%param, %%token 161 <1> %assign %%length 1 162 <1> %ifstr %%param 163 <1> %strlen %%length %%param 164 <1> %assign %%length (%%length + 3) / 4 165 <1> %endif 166 <1> %rep %%length * %%multi 167 <1> dd ? 168 <1> %endrep 169 <1> %exitrep 170 <1> %endif 171 <1> %endif 172 <1> %endif 173 <1> %assign %%index %%index + 1 174 <1> %endrep 175 <1> %ifempty %%multi 176 <1> %assign %%length 1 177 <1> %ifstr %%param 178 <1> %strlen %%length %%param 179 <1> %assign %%length (%%length + 3) / 4 180 <1> %endif 181 <1> %rep %%length 182 <1> dd ? 183 <1> %endrep 184 <1> %endif 185 <1> %rotate 1 186 <1> %endrep 187 <1> %endmacro 2 %define DONOBITS 3 %include "nibdos.nas" 1 <1> ; SCCSID = @(#)nibdos.asm 1.1 85/04/10 2 <1> ;TITLE NIBDOS 3 <1> ;NAME MSDOS_3 4 <1> 5 <1> ;=== Push trace listing source: mssw.nas 6 <1> %include "mssw.nas" ; NASM included file 1 <2> ; SCCSID = @(#)ibmsw.asm 1.1 85/04/10 2 <2> 3 <2> %include "version.mac" 1 <3> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <3> TRUE EQU 0FFFFh 3 <3> TRUEBYTE EQU 0FFh 4 <3> FALSE EQU 0 5 <3> 6 <3> ; 7 <3> ; Use the following switches to control cmacros.inc 8 <3> ; 9 <3> ?PLM equ 0 10 <3> ?WIN equ 0 11 <3> 12 <3> memS EQU 1 ; Small model 13 <3> ; 14 <3> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <3> ; version of the operating system 16 <3> ; 17 <3> ; The below chart will indicate how to set the switches to build the various 18 <3> ; versions 19 <3> ; 20 <3> ; IBMVER IBMCOPYRIGHT 21 <3> ; -------------------------------------------------------- 22 <3> ; IBM Version | TRUE TRUE 23 <3> ; -------------------------------------------------------- 24 <3> ; MS Version | FALSE FALSE 25 <3> ; -------------------------------------------------------- 26 <3> ; Clone Version | TRUE FALSE 27 <3> ; 28 <3> IBMVER EQU TRUE 29 <3> IBMCOPYRIGHT EQU FALSE 30 <3> 31 <3> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <3> 33 <3> %ifndef MSVER 34 <3> MSVER EQU ~ IBMVER 35 <3> %endif 36 <3> IBM EQU IBMVER 37 <3> ; 38 <3> ; 39 <3> %IF IBMVER 40 <3> %IF IBMCOPYRIGHT 41 <3> %warning out: ... IBM version build switch on ... 42 <3> %ELSE 43 <3> %warning out: ... CLONE version build switch on ... 43 ****************** <3> warning: out: ... CLONE version build switch on ... [-w+user] 44 <3> %ENDIF 45 <3> %ELSE 46 <3> %IFN IBMCOPYRIGHT 47 <3> %warning out: ... MS version build switch on ... 48 <3> %ELSE 49 <3> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <3> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <3> %ENDIF 52 <3> %ENDIF 53 <3> ; 54 <3> ; 55 <3> ;*************************************************************************** 56 <3> ;* The following switches are for DBCS or SBCS support * 57 <3> ;* * 58 <3> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <3> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <3> ;* * 61 <3> ;*************************************************************************** 62 <3> ; 63 <3> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <3> 65 <3> ; 66 <3> ; Switch INTERNAT for DBCS support 67 <3> ; 68 <3> INTERNAT EQU FALSE 69 <3> ; 70 <3> %IF INTERNAT 71 <3> %ifndef KANJI 72 <3> KANJI EQU TRUE 73 <3> %endif 74 <3> IBMJAPAN EQU TRUE 75 <3> %ELSE 76 <3> %ifndef KANJI 77 <3> KANJI EQU FALSE 78 <3> %endif 79 <3> IBMJAPAN EQU FALSE 80 <3> %ENDIF 81 <3> 82 <3> %ifndef altvect ; avoid jerking off vector.inc 83 <3> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <3> %endif 85 <3> 86 <3> ; 87 <3> ; Country code switches 88 <3> ; The default contry code is assumed as USA. 89 <3> ; 90 <3> %IF INTERNAT 91 <3> KOREA EQU TRUE 92 <3> JAPAN EQU FALSE 93 <3> %ELSE 94 <3> KOREA EQU FALSE 95 <3> JAPAN EQU FALSE 96 <3> %ENDIF 97 <3> ; 98 <3> %IF INTERNAT 99 <3> %warning out: Internat(ECS) version build switch on 100 <3> %ENDIF 4 <2> 5 <2> ibmver equ IBMVER ; NASM port equate 6 <2> IBM EQU ibmver 7 <2> WANG EQU FALSE 8 <2> 9 <2> ; Set this switch to cause DOS to move itself to the end of memory 10 <2> HIGHMEM EQU FALSE 11 <2> 12 <2> ; Turn on switch below to allow testing disk code with DEBUG. It sets 13 <2> ; up a different stack for disk I/O (functions > 11) than that used for 14 <2> ; character I/O which effectively makes the DOS re-entrant. 15 <2> 16 <2> %IF IBM 17 <2> ESCCH EQU 0 ; character to begin escape seq. 18 <2> CANCEL EQU 27 ;Cancel with escape 19 <2> TOGLPRN EQU TRUE ;One key toggles printer echo 20 <2> ZEROEXT EQU TRUE 21 <2> %ELSE 22 <2> ESCCH EQU 1BH 23 <2> CANCEL EQU "X"-"@" ;Cancel with Ctrl-X 24 <2> TOGLPRN EQU FALSE ;Separate keys for printer echo on 25 <2> ;and off 26 <2> ZEROEXT EQU TRUE 27 <2> %ENDIF 28 <2> 7 <1> ;=== Pop trace listing source 8 <1> ;=== Push trace listing source: msconst.nas 9 <1> %include "msconst.nas" ; NASM included file 1 <2> ; SCCSID = @(#)msconst.asm 1.4 85/09/12 2 <2> ; Revision history 3 <2> ; AN000 version 4.00 Jan. 1988 4 <2> ; AN007 fake version check for IBMCACHE.COM 5 <2> ;=== Push trace listing source: mshead.nas 6 <2> %include "mshead.nas" ; NASM included file 1 <3> ; SCCSID = @(#)mshead.asm 1.1 85/04/10 2 <3> ; TITLE MSHEAD.ASM -- MS-DOS DEFINITIONS 3 <3> ;PAGE 4 <3> ; MS-DOS High-performance operating system for the 8086 version 1.28 5 <3> ; by Microsoft MSDOS development group: 6 <3> ; TP (Ret.) 7 <3> ; AR 8 <3> ; NP (Parenting) 9 <3> ; MZ 10 <3> ; CP (BIOS) (ret.) 11 <3> 12 <3> ; ****************** Revision History ************************* 13 <3> ; >> EVERY change must noted below!! << 14 <3> ; 15 <3> ; 0.34 12/29/80 General release, updating all past customers 16 <3> ; 0.42 02/25/81 32-byte directory entries added 17 <3> ; 0.56 03/23/81 Variable record and sector sizes 18 <3> ; 0.60 03/27/81 Ctrl-C exit changes, including register save on user stack 19 <3> ; 0.74 04/15/81 Recognize I/O devices with file names 20 <3> ; 0.75 04/17/81 Improve and correct buffer handling 21 <3> ; 0.76 04/23/81 Correct directory size when not 2^N entries 22 <3> ; 0.80 04/27/81 Add console input without echo, Functions 7 & 8 23 <3> ; 1.00 04/28/81 Renumber for general release 24 <3> ; 1.01 05/12/81 Fix bug in `STORE' 25 <3> ; 1.10 07/21/81 Fatal error trapping, NUL device, hidden files, date & time, 26 <3> ; RENAME fix, general cleanup 27 <3> ; 1.11 09/03/81 Don't set CURRENT BLOCK to 0 on open; fix SET FILE SIZE 28 <3> ; 1.12 10/09/81 Zero high half of CURRENT BLOCK after all (CP/M programs don't) 29 <3> ; 1.13 10/29/81 Fix classic "no write-through" error in buffer handling 30 <3> ; 1.20 12/31/81 Add time to FCB; separate FAT from DPT; Kill SMALLDIR; Add 31 <3> ; FLUSH and MAPDEV calls; allow disk mapping in DSKCHG; Lots 32 <3> ; of smaller improvements 33 <3> ; 1.21 01/06/82 HIGHMEM switch to run DOS in high memory 34 <3> ; 1.22 01/12/82 Add VERIFY system call to enable/disable verify after write 35 <3> ; 1.23 02/11/82 Add defaulting to parser; use variable escape character Don't 36 <3> ; zero extent field in IBM version (back to 1.01!) 37 <3> ; 1.24 03/01/82 Restore fcn. 27 to 1.0 level; add fcn. 28 38 <3> ; 1.25 03/03/82 Put marker (00) at end of directory to speed searches 39 <3> ; 1.26 03/03/82 Directory buffers searched as a circular queue, current buffer 40 <3> ; is searched first when possible to minimize I/O 41 <3> ; 03/03/82 STORE routine optimized to tack on partial sector tail as 42 <3> ; full sector write when file is growing 43 <3> ; 03/09/82 Multiple I/O buffers 44 <3> ; 03/29/82 Two bugs: Delete all case resets search to start at beginning 45 <3> ; of directory (infinite loop possible otherwise), DSKRESET 46 <3> ; must invalidate all buffers (disk and directory). 47 <3> ; 1.27 03/31/82 Installable device drivers 48 <3> ; Function call 47 - Get pointer to device table list 49 <3> ; Function call 48 - Assign CON AUX LIST 50 <3> ; 04/01/82 Spooler interrupt (INT 28) added. 51 <3> ; 1.28 04/15/82 DOS retructured to use ASSUMEs and PROC labels around system 52 <3> ; call entries. Most CS relative references changed to SS 53 <3> ; relative with an eye toward putting a portion of the DOS in 54 <3> ; ROM. DOS source also broken into header, data and code pieces 55 <3> ; 04/15/82 GETDMA and GETVECT calls added as 24 and 32. These calls 56 <3> ; return the current values. 57 <3> ; 04/15/82 INDOS flag implemented for interrupt processing along with 58 <3> ; call to return flag location (call 29) 59 <3> ; 04/15/82 Volume ID attribute added 60 <3> ; 04/17/82 Changed ABORT return to user to a long ret from a long jump to 61 <3> ; avoid a CS relative reference. 62 <3> ; 04/17/82 Put call to STATCHK in dispatcher to catch ^C more often 63 <3> ; 04/20/82 Added INT int_upooler into loop ^S wait 64 <3> ; 04/22/82 Dynamic disk I/O buffer allocation and call to manage them 65 <3> ; call 49. 66 <3> ; 04/23/82 Added GETDSKPTDL as call 50, similar to GETFATPT(DL), returns 67 <3> ; address of DPB 68 <3> ; 04/29/82 Mod to WRTDEV to look for ^C or ^S at console input when 69 <3> ; writting to console device via file I/O. Added a console 70 <3> ; output attribute to devices. 71 <3> ; 04/30/82 Call to en/dis able ^C check in dispatcher Call 51 72 <3> ; 04/30/82 Code to allow assignment of func 1-12 to disk files as well 73 <3> ; as devices.... pipes, redirection now possible 74 <3> ; 04/30/82 Expanded GETLIST call to 2.0 standard 75 <3> ; 05/04/82 Change to INT int_fatal_abort callout int HARDERR_DOS. DOS SS 76 <3> ; (data segment) stashed in ES, INT int_fatal_abort routines must 77 <3> ; preserve ES. This mod so HARDERR_DOS can be ROMed. 78 <3> ; 1.29 06/01/82 Installable block and character devices as per 2.0 spec 79 <3> ; 06/04/82 Fixed Bug in CLOSE regarding call to CHKFATWRT. It got left 80 <3> ; out back about 1.27 or so (oops). ARR 81 <3> ; 1.30 06/07/82 Directory sector buffering added to main DOS buffer queue 82 <3> ; 1.40 06/15/82 Tree structured directories. XENIX Path Parser MKDIR CHDIR 83 <3> ; RMDIR Xenix calls 84 <3> ; 1.41 06/13/82 Made GETBUFFR call PLACEBUF 85 <3> ; 1.50 06/17/82 FATs cached in buffer pool, get FAT pointer calls disappear 86 <3> ; Frees up lots of memory. 87 <3> ; 1.51 06/24/82 BREAKDOWN Revised to do EXACT one sector read/write through 88 <3> ; system buffers 89 <3> ; 1.52 06/30/82 OPEN, CLOSE, READ, WRITE, DUP, DUP2, LSEEK implemented 90 <3> ; 1.53 07/01/82 OPEN CLOSE mod for Xenix calls, saves and gets remote dir 91 <3> ; 1.54 07/11/82 Function calls 1-12 make use of new 2.0 PDB. Init code 92 <3> ; changed to set file handle environment. 93 <3> ; 2.00 08/01/82 Number for IBM release 94 <3> ; 01/19/83 No environ bug in EXEC 95 <3> ; 01/19/83 MS-DOS OEM INT 21 extensions (SET_OEM_HANDLER) 96 <3> ; 01/19/83 Performance bug fix in cooked write to NUL 97 <3> ; 01/27/83 Growcnt fixed for 32-bits 98 <3> ; 01/27/83 Find-first problem after create 99 <3> ; 2.01 02/17/83 International DOS 100 <3> ; 2.10 03/09/83 Start of NETWORK support 101 <3> ; New Buffer structure 102 <3> ; New Sytem file table structure 103 <3> ; FCB moved to internal representation 104 <3> ; DOS re-organized 105 <3> ; 2.11 04/21/83 Continuation of 2.10, preliminary Network 106 <3> ; device interface. 107 <3> ; 2.50 09/12/83 More network stuff 108 <3> ; 109 <3> ; ************************************************************* 110 <3> 111 <3> [list -] 111 ****************** <3> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <7> [list -] 14 <6> [list -] 3 <5> === Switch to base=001DC0h -> "DOSSTART" 4 <5> addsection DOSSTART, align=16 PUBLIC class=DOSSTART 5 <5> ; (no prior section) ; DOSSTART ENDS 6 <5> === Switch to base=001DC0h -> "DOSSTARTJUMP" 7 <5> addsection DOSSTARTJUMP, align=1 PUBLIC class=START 8 <5> ; (no prior section) ; DOSSTARTJUMP ENDS 9 <5> === Switch to base=001DC0h -> "CONSTANTS" 10 <5> addsection CONSTANTS, align=2 PUBLIC class=CONST 11 <5> ; (no prior section) ; CONSTANTS ENDS 12 <5> === Switch to base=001DC0h -> "DATA" 13 <5> addsection DATA, align=2 PUBLIC class=DATA 14 <5> ; (no prior section) ; DATA ENDS 15 <5> === Switch to base=001DC0h -> "TABLE" 16 <5> addsection TABLE, align=2 PUBLIC class=TABLE 17 <5> ; (no prior section) ; TABLE ENDS 18 <5> === Switch to base=001DC0h -> "DOSDATATABLE" 19 <5> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE 20 <5> ; (no prior section) ; DOSDATATABLE ENDS 21 <5> === Switch to base=001DC0h -> "DOSDATACODE" 22 <5> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE 23 <5> ; (no prior section) ; DOSDATACODE ENDS 24 <5> === Switch to base=001DC0h -> "DOSBIODATA" 25 <5> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA 26 <5> === Switch to base=001DC0h -> "LAST" 27 <5> addsection LAST, align=16 PUBLIC class=LAST 28 <5> ; (no prior section) ; LAST ENDS 29 <5> 30 <5> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST 31 <5> 32 <5> %include "entryseg.nas" 1 <6> 2 <6> %ifndef ENTRYSEGNAS 3 <6> %define ENTRYSEGNAS 1 4 <6> 5 <6> %include "lmacros3.mac" 1 <7> [list -] 6 <6> === Switch to base=003490h -> "DOSENTRY" 7 <6> addsection DOSENTRY, class=%[DOSENTRY] 8 <6> 9 <6> group DOSENTRYGROUP DOSENTRY 10 <6> 11 <6> %endif 8 <4> 9 <4> %include "dcodeseg.nas" 1 <5> 2 <5> %ifndef DCODESEGNAS 3 <5> %assign DCODESEGNAS 1 4 <5> === Switch to base=003490h -> "DOSCODETABLE" 5 <5> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <5> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <5> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <5> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <5> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <5> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <5> 12 <5> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <5> 14 <5> %endif 10 <4> === Switch to base=001DC0h -> "LAST" 11 <4> section LAST 12 <4> ; (no prior section) ; LAST ENDS 122 <3> 123 <3> %include "dossym.mac" 1 <4> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 2 <4> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 3 <4> ; PAGE 80,132 4 <4> TRUE EQU 0FFFFh 5 <4> FALSE EQU 0 6 <4> 7 <4> Installed equ TRUE 8 <4> %IFNDEF DEBUG 9 <4> DEBUG equ FALSE 10 <4> %ENDIF 11 <4> %IFNDEF debug 12 <4> debug equ DEBUG 13 <4> %ENDIF 14 <4> 15 <4> %if 0 16 <4> DBCS equ FALSE ; for fixmem.pl operation 17 <4> %endif 18 <4> 19 <4> ; NASM original macros 20 <4> 21 <4> %macro DBCS 1.nolist 22 <4> %defstr %%string %1 23 <4> %substr %%prefix %%string 1,2 24 <4> %substr %%suffix %%string 3,-1 25 <4> %ifnidni %%prefix, "= " 26 <4> %error Unexpected DBCS prefix 27 <4> %endif 28 <4> %deftok %%token %%suffix 29 <4> %xdefine DBCS %%token 30 <4> %endmacro 31 <4> 32 <4> %include "DBCS.SW" 1 <5> DBCS = FALSE 2 <5> 33 <4> %unmacro DBCS 1.nolist 34 <4> 35 <4> ; end of NASM original macros 36 <4> 37 <4> %include "dosmac.mac" 1 <5> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 3 <5> ; 4 <5> ; Macro file for MSDOS. 5 <5> ; 6 <5> 7 <5> %ifndef __DOSMAC_MAC__ 8 <5> %assign __DOSMAC_MAC__ 1 9 <5> 10 <5> TRUE EQU 0FFFFh 11 <5> FALSE EQU 0 12 <5> 13 <5> 14 <5> ; NASM original macros (comment for fixmem.pl) 15 <5> 16 <5> ;SUBTTL BREAK a listing into pages and give new subtitles 17 <5> ;PAGE 18 <5> %imacro BREAK 0-1+.nolist 19 <5> ;SUBTTL subtitle 20 <5> ;PAGE 21 <5> %endmacro 22 <5> ;.xcref break 23 <5> 24 <5> BREAK 25 <5> 26 <5> %if 0 27 <5> AsmVars Macro varlist 28 <5> IRP var, 29 <5> AsmVar var 30 <5> ENDM 31 <5> ENDM 32 <5> 33 <5> AsmVar Macro var 34 <5> IFNDEF var 35 <5> var = FALSE 36 <5> ENDIF 37 <5> ENDM 38 <5> %endif 39 <5> 40 <5> BREAK 41 <5> 42 <5> ; 43 <5> ; declare a variable external and allocate a size 44 <5> ; 45 <5> ;AsmVar InstalledData 46 <5> %ifndef InstalledData 47 <5> %define InstalledData 0 48 <5> %endif 49 <5> 50 <5> %imacro I_NEED 1-2.nolist 51 <5> %ifn InstalledData === Switch to base=001DC0h -> "DATA" 52 <5> [section DATA] 53 <5> %IFIDNi %2, WORD 54 <5> EXTRN %1:WORD 55 <5> %ELSE 56 <5> %IFIDNi %2, DWORD 57 <5> EXTRN %1:DWORD 58 <5> %ELSE 59 <5> EXTRN %1:BYTE 60 <5> %ENDIF 61 <5> %ENDIF 62 <5> __SECT__ 63 <5> %ENDIF 64 <5> %endmacro 65 <5> ;.xcref I_need 66 <5> 67 <5> ; 68 <5> ; call a procedure that may be external. The call will be short. 69 <5> ; 70 <5> %imacro invoke 1.nolist 71 <5> ;.xcref 72 <5> EXTRN %1:NEAR 73 <5> ;.cref 74 <5> CALL %1 75 <5> %endmacro 76 <5> ;.xcref invoke 77 <5> 78 <5> ;PAGE 79 <5> ; 80 <5> ; jump to a label that may be external. The jump will be near. 81 <5> ; 82 <5> %imacro transfer 1.nolist 83 <5> ;.xcref 84 <5> EXTRN %1:NEAR 85 <5> ;.cref 86 <5> JUMP %1 87 <5> %endmacro 88 <5> ;.xcref transfer 89 <5> 90 <5> ; 91 <5> ; get a short address in a word 92 <5> ; 93 <5> %imacro short_addr 1.nolist 94 <5> %ifnidn %1, ? 95 <5> EXTRN %1:NEAR 96 <5> DW OFFSET %1 97 <5> %ELSE 98 <5> DW ? 99 <5> %ENDIF 100 <5> %endmacro 101 <5> ;.xcref short_addr 102 <5> 103 <5> ; 104 <5> ; get a long address in a dword 105 <5> ; 106 <5> %imacro long_addr 1.nolist 107 <5> EXTRN %1:NEAR 108 <5> DD %1 109 <5> %endmacro 110 <5> ;.xcref long_addr 111 <5> 112 <5> ; 113 <5> ; declare a PROC near or far but PUBLIC nonetheless 114 <5> ; 115 <5> ;.xcref ?frame 116 <5> ;.xcref ?aframe 117 <5> ;.xcref ?stackdepth 118 <5> ;.xcref ?initstack 119 <5> %assign ?frame 0 ; initial 120 <5> %assign ?aframe 0 ; initial 121 <5> %assign ?stackdepth 0 ; initial stack size 122 <5> %assign ?initstack 0 ; initial stack size 123 <5> 124 <5> %imacro procedure 1-2.nolist 125 <5> %assign ?frame 0 126 <5> %assign ?aframe 2 ;; remember the pushed BP 127 <5> %warning proc %1... 128 <5> %1 PROC %2 129 <5> PUBLIC %1 130 <5> %assign ?initstack ?stackdepth ;; beginning of procedure 131 <5> %endmacro 132 <5> ;.xcref procedure 133 <5> 134 <5> ; 135 <5> ; end a procedure and check that stack depth is preserved 136 <5> ; 137 <5> %imacro EndProc 1-2.nolist 138 <5> %ifnidni %2, NoCheck ;; check the stack size 139 <5> %if ?initstack != ?stackdepth ;; is it different? 140 <5> %warning ***** Possible stack size error in %1 ***** 141 <5> %endif 142 <5> %endif 143 <5> %1 ENDP 144 <5> %endmacro 145 <5> ;.xcref endproc 146 <5> ;PAGE 147 <5> ; 148 <5> ; define a data item to be public and of an appropriate size/type 149 <5> ; 150 <5> 151 <5> %imacro stripangles 2.nolist 152 <5> %defstr %%param %2 153 <5> %rep 16 154 <5> %substr %%opening %%param 1 155 <5> %ifidn %%opening, '<' 156 <5> %substr %%param %%param 2,-1 157 <5> %endif 158 <5> %endrep 159 <5> %rep 16 160 <5> %strlen %%length %%param 161 <5> %substr %%closing %%param %%length 162 <5> %ifidn %%closing, '>' 163 <5> %substr %%param %%param 1,-2 164 <5> %endif 165 <5> %endrep 166 <5> %deftok %%token %%param 167 <5> %1 %%token 168 <5> %endmacro 169 <5> 170 <5> %imacro I_AM 2-*.nolist 171 <5> ;I_AM MACRO name,size,init 172 <5> %xdefine %%name %1 173 <5> ;; declare the type of the object 174 <5> %IFIDNi %2, WORD 175 <5> %1 LABEL WORD 176 <5> %assign I_AM_SIZE 1 177 <5> %assign I_AM_LEN 2 178 <5> %ELSE 179 <5> %IFIDNi %2, DWORD 180 <5> %1 LABEL DWORD 181 <5> %assign I_AM_SIZE 2 182 <5> %assign I_AM_LEN 2 183 <5> %ELSE 184 <5> %IFIDNi %2, BYTE 185 <5> %1 LABEL BYTE 186 <5> %assign I_AM_SIZE 1 187 <5> %assign I_AM_LEN 1 188 <5> %ELSE 189 <5> %1 LABEL BYTE 190 <5> %undef I_AM_SIZE 191 <5> stripangles %assign I_AM_SIZE, %2 192 <5> %assign I_AM_LEN 1 193 <5> %ENDIF 194 <5> %ENDIF 195 <5> %ENDIF 196 <5> ;; declare the object public 197 <5> PUBLIC %%name 198 <5> ;; if no initialize then allocate blank storage 199 <5> %IF %0 == 2 200 <5> DB I_AM_SIZE*I_AM_LEN DUP (?) 201 <5> %ELSE 202 <5> %ifn InstalledData 203 <5> %rotate 2 204 <5> %rep %0 - 2 205 <5> %IF I_AM_LEN == 1 206 <5> stripangles db, %1 207 <5> %ELSE 208 <5> stripangles dw, %1 209 <5> %ENDIF 210 <5> %assign I_AM_SIZE I_AM_SIZE - 1 211 <5> %rotate 1 212 <5> %endrep 213 <5> %IF I_AM_SIZE != 0 214 <5> %error ***** initialization of %%name not complete ***** 215 <5> %ENDIF 216 <5> %ELSE 217 <5> DB I_AM_SIZE*I_AM_LEN DUP (?) 218 <5> %ENDIF 219 <5> %ENDIF 220 <5> %endmacro 221 <5> 222 <5> %imacro I_AM_NOBITS 2-*.nolist 223 <5> ;I_AM MACRO name,size,init 224 <5> %xdefine %%name %1 225 <5> ;; declare the type of the object 226 <5> %IFIDNi %2, WORD 227 <5> %1 LABEL WORD 228 <5> %assign I_AM_SIZE 1 229 <5> %assign I_AM_LEN 2 230 <5> %ELSE 231 <5> %IFIDNi %2, DWORD 232 <5> %1 LABEL DWORD 233 <5> %assign I_AM_SIZE 2 234 <5> %assign I_AM_LEN 2 235 <5> %ELSE 236 <5> %IFIDNi %2, BYTE 237 <5> %1 LABEL BYTE 238 <5> %assign I_AM_SIZE 1 239 <5> %assign I_AM_LEN 1 240 <5> %ELSE 241 <5> %1 LABEL BYTE 242 <5> %undef I_AM_SIZE 243 <5> stripangles %assign I_AM_SIZE, %2 244 <5> %assign I_AM_LEN 1 245 <5> %ENDIF 246 <5> %ENDIF 247 <5> %ENDIF 248 <5> ;; declare the object public 249 <5> PUBLIC %%name 250 <5> ;; if no initialize then allocate blank storage 251 <5> %IF %0 == 2 252 <5> resb I_AM_SIZE*I_AM_LEN 253 <5> %ELSE 254 <5> %ifn InstalledData 255 <5> %rotate 2 256 <5> %rep %0 - 2 257 <5> %IF I_AM_LEN == 1 258 <5> resb 1 259 <5> %ELSE 260 <5> resw 1 261 <5> %ENDIF 262 <5> %assign I_AM_SIZE I_AM_SIZE - 1 263 <5> %rotate 1 264 <5> %endrep 265 <5> %IF I_AM_SIZE != 0 266 <5> %error ***** initialization of %%name not complete ***** 267 <5> %ENDIF 268 <5> %ELSE 269 <5> resb I_AM_SIZE*I_AM_LEN 270 <5> %ENDIF 271 <5> %ENDIF 272 <5> %endmacro 273 <5> 274 <5> ;.xcref I_AM 275 <5> ;.xcref I_AM_SIZE 276 <5> ;.xcref I_AM_LEN 277 <5> %assign I_AM_SIZE 0 278 <5> %assign I_AM_LEN 0 279 <5> 280 <5> ;PAGE 281 <5> 282 <5> ; 283 <5> ; define an entry in a procedure 284 <5> ; 285 <5> %imacro entry 1.nolist 286 <5> %1: 287 <5> PUBLIC %1 288 <5> %endmacro 289 <5> ;.xcref entry 290 <5> 291 <5> BREAK 292 <5> 293 <5> %imacro error 1.nolist 294 <5> ;.xcref 295 <5> MOV AL, %1 296 <5> transfer SYS_RET_ERR 297 <5> ;.cref 298 <5> %endmacro 299 <5> ;.xcref error 300 <5> 301 <5> BREAK 302 <5> ; 303 <5> ; given a label either 2 byte jump to another label _J 304 <5> ; if it is near enough or 3 byte jump to 305 <5> ; 306 <5> 307 <5> %imacro jump 1.nolist 308 <5> ;.xcref 309 <5> 310 <5> %ifndef %1_J ;; is this the first invocation 311 <5> %%a: JMP %1 312 <5> %ELSE 313 <5> %IF (%1_J >= $) || ($-%1_J > 126) 314 <5> %%a: JMP %1 ;; is the jump too far away? 315 <5> %ELSE 316 <5> %%a: JMP %1_J ;; do the short one... 317 <5> %ENDIF 318 <5> %ENDIF 319 <5> %ixdefine %1_j %%a 320 <5> ;.cref 321 <5> %endmacro 322 <5> ;.xcref jump 323 <5> 324 <5> BREAK 325 <5> 326 <5> %imacro return 0.nolist 327 <5> %%a: 328 <5> RET 329 <5> %xdefine ret_l %%a 330 <5> %endmacro 331 <5> ;.xcref return 332 <5> 333 <5> BREAK 334 <5> 335 <5> %imacro condret 2.nolist 336 <5> %assign %%exit 0 337 <5> %ifdef ret_l ;; if ret_l is defined 338 <5> %if (($ - ret_l) <= 126) && ($ > ret_l) 339 <5> ;; if ret_l is near enough then 340 <5> %%a: j%1 ret_l ;; a: j to ret_l 341 <5> %xdefine ret_%1 %%a ;; define ret_ to be a: 342 <5> %assign %%exit 1 343 <5> %endif 344 <5> %endif 345 <5> %ifn %%exit 346 <5> %ifdef ret_%1 ;; if ret_ defined 347 <5> %if (($ - ret_%1) <= 126) && ($ > ret_%1) 348 <5> ;; if ret_ is near enough 349 <5> %%a: j%1 ret_%1 ;; a: j to ret_ 350 <5> %xdefine ret_%1 %%a ;; define ret_ to be a: 351 <5> %assign %%exit 1 352 <5> %endif 353 <5> %endif 354 <5> %endif 355 <5> %ifn %%exit 356 <5> j%2 %%a ;; j a: 357 <5> return ;; return 358 <5> %%a: ;; a: 359 <5> %xdefine ret_%1 ret_l ;; define ret_ to be ret_l 360 <5> %endif 361 <5> %endmacro 362 <5> ;.xcref condret 363 <5> 364 <5> BREAK 365 <5> 366 <5> %imacro retz 0.nolist 367 <5> condret z,nz 368 <5> %endmacro 369 <5> ;.xcref retz 370 <5> 371 <5> BREAK 372 <5> 373 <5> %imacro retnz 0.nolist 374 <5> condret nz,z 375 <5> %endmacro 376 <5> ;.xcref retnz 377 <5> 378 <5> BREAK 379 <5> 380 <5> %imacro retc 0.nolist 381 <5> condret c,nc 382 <5> %endmacro 383 <5> ;.xcref retc 384 <5> 385 <5> BREAK 386 <5> 387 <5> %imacro retnc 0.nolist 388 <5> condret nc,c 389 <5> %endmacro 390 <5> ;.xcref retnc 391 <5> 392 <5> BREAK 393 <5> 394 <5> %imacro context 1.nolist 395 <5> PUSH SS 396 <5> stripangles POP, %1 397 <5> ; ASSUME %1:DOSGROUP 398 <5> %endmacro 399 <5> ;.xcref context 400 <5> 401 <5> BREAK 402 <5> 403 <5> %imacro SaveReg 0-*.nolist ;; push those registers 404 <5> %rep %0 405 <5> %assign ?stackdepth ?stackdepth + 1 406 <5> stripangles push, %1 407 <5> %rotate 1 408 <5> %endrep 409 <5> %endmacro 410 <5> ;.xcref SaveReg 411 <5> 412 <5> BREAK 413 <5> 414 <5> %imacro RestoreReg 0-*.nolist ;; pop those registers 415 <5> %rep %0 416 <5> %assign ?stackdepth ?stackdepth - 1 417 <5> stripangles pop, %1 418 <5> %rotate 1 419 <5> %endrep 420 <5> %endmacro 421 <5> ;.xcref RestoreReg 422 <5> 423 <5> BREAK 424 <5> 425 <5> %imacro EnterCrit 1.nolist 426 <5> Invoke E%1 427 <5> %endmacro 428 <5> 429 <5> %imacro LeaveCrit 1.nolist 430 <5> Invoke L%1 431 <5> %endmacro 432 <5> 433 <5> Break 434 <5> 435 <5> ;AsmVars 436 <5> %ifndef ShareF 437 <5> %idefine ShareF 0 438 <5> %endif 439 <5> %ifndef Cargs 440 <5> %idefine Cargs 0 441 <5> %endif 442 <5> %ifndef Redirector 443 <5> %idefine Redirector 0 444 <5> %endif 445 <5> %ifndef debug 446 <5> %idefine debug 0 447 <5> %endif 448 <5> 449 <5> %if debug 450 <5> %imacro fmt 3-*.nolist 451 <5> ;fmt MACRO typ,lev,fmts,args 452 <5> ;local a,b,c 453 <5> PUSHF 454 <5> %IFNempty %1 455 <5> TEST word [BugTyp],%1 456 <5> JZ %%c 457 <5> CMP word [BugLev],%2 458 <5> JB %%c 459 <5> %ENDIF 460 <5> PUSH AX 461 <5> PUSH BP 462 <5> MOV BP,SP 463 <5> %If (! sharef) && (! redirector) === Switch to base=001DC0h -> "TABLE" 464 <5> [section Table] 465 <5> %%a: db %3,0 466 <5> __SECT__ 467 <5> MOV AX,OFFSET %%a wrt DOSGROUP 468 <5> %else 469 <5> jmp short %%b 470 <5> %%a: db %3,0 471 <5> %if sharef 472 <5> %%b: mov ax,offset %%a wrt share 473 <5> %else 474 <5> %%b: mov ax,offset %%a wrt netwrk 475 <5> %endif 476 <5> %endif 477 <5> PUSH AX 478 <5> %iassign cargs 2 479 <5> %rotate 3 480 <5> %rep %0 - 3 481 <5> %ifidni ax, %1 482 <5> MOV AX,[BP+2] 483 <5> %ELSE 484 <5> MOV AX, %1 485 <5> %ENDIF 486 <5> PUSH AX 487 <5> %iassign cargs cargs + 2 488 <5> %rotate 1 489 <5> %endrep 490 <5> invoke PFMT 491 <5> ADD SP, Cargs 492 <5> POP BP 493 <5> POP AX 494 <5> %%c: 495 <5> POPF 496 <5> %endmacro 497 <5> %else 498 <5> %imacro fmt 3-*.nolist 499 <5> %endmacro 500 <5> %endif 501 <5> 502 <5> Break 503 <5> 504 <5> ;AsmVar Debug,$temp 505 <5> 506 <5> %imacro detectstripangles 4.nolist 507 <5> %defstr %%param %4 508 <5> %assign ?%2 0 509 <5> %assign ?%3 0 510 <5> %rep 16 511 <5> %substr %%opening %%param 1 512 <5> %ifidn %%opening, '<' 513 <5> %substr %%param %%param 2,-1 514 <5> %assign ?%2 ?%2 + 1 515 <5> %endif 516 <5> %endrep 517 <5> %rep 16 518 <5> %strlen %%length %%param 519 <5> %substr %%closing %%param %%length 520 <5> %ifidn %%closing, '>' 521 <5> %substr %%param %%param 1,-2 522 <5> %assign ?%3 ?%3 + 1 523 <5> %endif 524 <5> %endrep 525 <5> %deftok %%token %%param 526 <5> %define ?%1 %%token 527 <5> %endmacro 528 <5> 529 <5> 530 <5> %IF debug 531 <5> %imacro DOSAssume 3-*.nolist 532 <5> ;DOSAssume Macro reg,reglist,message 533 <5> %ifidni %1, CS 534 <5> %assign %%temp 1 535 <5> %else 536 <5> %ifidni %1, SS 537 <5> %assign %%temp 0 538 <5> %else 539 <5> %error ***** Invalid DOS register %1 in DOSAssume ***** 540 <5> %endif 541 <5> %endif 542 <5> %rotate 1 543 <5> %assign %%level 0 544 <5> %assign %%amount %0 - 1 545 <5> %rep 16 546 <5> detectstripangles %%token, %%opening, %%closing, %1 547 <5> %assign %%level %%level + ? %+ %%opening 548 <5> %assign %%level %%level - ? %+ %%closing 549 <5> %ifidni ? %+ %%token, DS 550 <5> %assign %%temp %%temp | 2 551 <5> %else 552 <5> %ifidni ? %+ %%token, ES 553 <5> %assign %%temp %%temp | 4 554 <5> %else 555 <5> %error ***** Invalid register reg in DOSAssume ***** 556 <5> %endif 557 <5> %endif 558 <5> %assign %%amount %%amount - 1 559 <5> %rotate 1 560 <5> %if %%level <= 0 561 <5> %exitrep 562 <5> %endif 563 <5> %endrep 564 <5> 565 <5> PUSH AX 566 <5> MOV AX, %%temp 567 <5> PUSH AX 568 <5> %IF SHAREF 569 <5> MOV AX,OFFSET %%a 570 <5> %ELSE 571 <5> MOV AX,OFFSET %%a wrt DOSGroup 572 <5> %ENDIF 573 <5> PUSH AX 574 <5> Invoke SegCheck 575 <5> POP AX 576 <5> %IFN SHAREF === Switch to base=001DC0h -> "TABLE" 577 <5> [section Table] 578 <5> %ELSE 579 <5> JMP SHORT %%b 580 <5> %ENDIF 581 <5> %%a: 582 <5> %rep %%amount 583 <5> DB %1 584 <5> %rotate 1 585 <5> %endrep 586 <5> db 0 587 <5> %IFN SHAREF 588 <5> __SECT__ 589 <5> %ELSE 590 <5> %%b: 591 <5> %ENDIF 592 <5> ;IRP r, 593 <5> ; ASSUME r:DOSGroup 594 <5> ;ENDM 595 <5> %endmacro 596 <5> %ELSE 597 <5> %imacro DOSAssume 3-*.nolist 598 <5> ;DOSAssume Macro reg,reglist,message 599 <5> ;IRP r, 600 <5> ; ASSUME r:DOSGroup 601 <5> ;ENDM 602 <5> %endmacro 603 <5> %ENDIF 604 <5> 605 <5> BREAK 606 <5> 607 <5> %if 0 608 <5> ;IF DEBUG 609 <5> Assert MACRO kind, objs, message 610 <5> LOCAL a,b 611 <5> IFIDN , 612 <5> CMP objs,0 613 <5> JZ a 614 <5> fmt <>,<>, 615 <5> a: 616 <5> ELSE 617 <5> IFIDN , 618 <5> CMP objs,0 619 <5> JNZ a 620 <5> fmt <>,<>, 621 <5> a: 622 <5> ELSE 623 <5> PUSH AX 624 <5> IRP obj, 625 <5> PUSH obj 626 <5> ENDM 627 <5> IF SHAREF 628 <5> MOV AX,OFFSET b 629 <5> ELSE 630 <5> MOV AX,OFFSET DOSGroup:b 631 <5> ENDIF 632 <5> PUSH AX 633 <5> IFIDN , 634 <5> Invoke BUFCheck 635 <5> ENDIF 636 <5> IFIDN , 637 <5> Invoke SFTCheck 638 <5> ENDIF 639 <5> IFIDN , 640 <5> Invoke DPBCheck 641 <5> ENDIF 642 <5> POP AX 643 <5> IF SHAREF 644 <5> JMP SHORT a 645 <5> b DB Message,0 646 <5> a: 647 <5> ELSE === Switch to base=001DC0h -> "TABLE" 648 <5> Table segment 649 <5> b db Message,0 === Switch to base=001DC0h -> "TABLE" 650 <5> Table ends 651 <5> ENDIF 652 <5> ENDIF 653 <5> ENDIF 654 <5> ENDM 655 <5> %ELSE 656 <5> %imacro Assert 0-*.nolist 657 <5> %endmacro 658 <5> %ENDIF 659 <5> 660 <5> %ifndef Installed 661 <5> %idefine Installed 1 662 <5> %endif 663 <5> 664 <5> Break 665 <5> 666 <5> %imacro CallInstall 3-*.nolist 667 <5> ;CallInstall MACRO name,mpx,fn,save,restore 668 <5> %define %%name %1 669 <5> %assign %%mpx %2 670 <5> %assign %%fn %3 671 <5> %IF Installed 672 <5> %rotate 3 673 <5> %assign %%level 0 674 <5> %assign %%amountsaved 0 675 <5> %rep %0 - 3 676 <5> %ifnempty %1 677 <5> detectstripangles %%token, %%opening, %%closing, %1 678 <5> %assign %%level %%level + ? %+ %%opening 679 <5> %assign %%level %%level - ? %+ %%closing 680 <5> SaveReg ? %+ %%token 681 <5> %endif 682 <5> %assign %%amountsaved %%amountsaved + 1 683 <5> %rotate 1 684 <5> %if %%level <= 0 685 <5> %exitrep 686 <5> %endif 687 <5> %endrep 688 <5> MOV AX,(%%mpx << 8) + %%fn 689 <5> INT 2Fh 690 <5> %assign %%level 0 691 <5> %assign %%amountrestored 0 692 <5> %rep %0 - 3 - %%amountsaved 693 <5> %ifnempty %1 694 <5> detectstripangles %%token, %%opening, %%closing, %1 695 <5> %assign %%level %%level + ? %+ %%opening 696 <5> %assign %%level %%level - ? %+ %%closing 697 <5> RestoreReg ? %+ %%token 698 <5> %endif 699 <5> %assign %%amountrestored %%amountrestored + 1 700 <5> %rotate 1 701 <5> %if %%level <= 0 702 <5> %exitrep 703 <5> %endif 704 <5> %endrep 705 <5> %if %%level > 0 || %0 != 3 + %%amountsaved + %%amountrestored 706 <5> %error Wrong amount saved or restored 707 <5> %endif 708 <5> %ELSE 709 <5> Invoke %%name 710 <5> %ENDIF 711 <5> %endmacro 712 <5> 713 <5> Break 714 <5> 715 <5> %imacro localvar 2.nolist 716 <5> %ifidni %2, BYTE 717 <5> %assign ?frame ?frame + 1 718 <5> %assign %%a ?frame 719 <5> labelsize %1, byte, bp - %%a 720 <5> %else 721 <5> %ifidni %2, WORD 722 <5> %assign ?frame ?frame + 2 723 <5> %assign %%a ?frame 724 <5> labelsize %1, word, bp - %%a 725 <5> %else 726 <5> %ifidni %2, DWORD 727 <5> %assign ?frame ?frame + 4 728 <5> %assign %%a ?frame 729 <5> labelsize %1 %+ l, word, bp - %%a 730 <5> labelsize %1 %+ h, word, bp - %%a + 2 731 <5> labelsize %1, dword, bp - %%a 732 <5> %else 733 <5> %assign ?frame ?frame + %2 734 <5> %assign %%a ?frame 735 <5> labelsize %1, byte, bp - %%a 736 <5> %endif 737 <5> %endif 738 <5> %endif 739 <5> %endmacro 740 <5> 741 <5> %imacro enter 0.nolist 742 <5> push bp 743 <5> mov bp,sp 744 <5> sub sp,?frame 745 <5> %endmacro 746 <5> 747 <5> %imacro leave 0.nolist 748 <5> mov sp,bp 749 <5> pop bp 750 <5> %endmacro 751 <5> 752 <5> 753 <5> %imacro argvar 2.nolist 754 <5> %ifidni %2, BYTE 755 <5> %assign %%a ?aframe 756 <5> %assign ?aframe ?aframe + 1 757 <5> labelsize %1, byte, bp + %%a 758 <5> %else 759 <5> %ifidni %2, WORD 760 <5> %assign %%a ?aframe 761 <5> %assign ?aframe ?aframe + 2 762 <5> labelsize %1, word, bp + %%a 763 <5> %else 764 <5> %ifidni %2, DWORD 765 <5> %assign %%a ?aframe 766 <5> %assign ?aframe ?aframe + 4 767 <5> labelsize %1 %+ l, word, bp + %%a 768 <5> labelsize %1 %+ h, word, bp + %%a + 2 769 <5> labelsize %1, dword, bp + %%a 770 <5> %else 771 <5> %assign %%a ?aframe 772 <5> %assign ?aframe ?aframe + %2 773 <5> labelsize %1, byte, bp + %%a 774 <5> %endif 775 <5> %endif 776 <5> %endif 777 <5> %endmacro 778 <5> 779 <5> BREAK 780 <5> 781 <5> %imacro errnz 1.nolist 782 <5> detectstripangles %%token, %%opening, %%closing, %1 783 <5> %if ? %+ %%token 784 <5> %error %1 <> 0 785 <5> %endif 786 <5> %endmacro 787 <5> 788 <5> %endif 38 <4> 39 <4> %include "versiona.mac" 1 <5> 2 <5> major_version equ 4 ;Major DOS version 3 <5> minor_version equ 00 ;Minor DOS Version 4 <5> 5 <5> MINOR_VERSION equ minor_version ; NASM port equate 6 <5> MAJOR_VERSION equ major_version ; NASM port equate 7 <5> expected_version equ (MINOR_VERSION << 8)+MAJOR_VERSION 8 <5> 9 <5> alt_major_version equ 5 ;Major DOS version 10 <5> alt_minor_version equ 26 ;Minor DOS Version 11 <5> 12 <5> alt_expected_version equ (alt_minor_version << 8) + alt_major_version 13 <5> 14 <5> %warning out: ... for DOS Version 4.00 ... 14 ****************** <5> warning: out: ... for DOS Version 4.00 ... [-w+user] 15 <5> 16 <5> ;****************************** 17 <5> ;Each assembler program should: 18 <5> ; mov ah,030h ;DOS Get Version function 19 <5> ; int 021h ;Version ret. in AX,minor version first 20 <5> ; cmp ax,expected_version ;ALL utilities should check for an 21 <5> ; jne error_handler ; EXACT version match. 22 <5> ;****************************** 23 <5> 40 <4> 41 <4> BREAK 42 <4> 43 <4> c_DEL EQU 7Fh ; ASCII rubout or delete previous char 44 <4> c_BS EQU 08h ; ^H ASCII backspace 45 <4> c_CR EQU 0Dh ; ^M ASCII carriage return 46 <4> c_LF EQU 0Ah ; ^J ASCII linefeed 47 <4> c_ETB EQU 17h ; ^W ASCII end of transmission 48 <4> c_NAK EQU 15h ; ^U ASCII negative acknowledge 49 <4> c_ETX EQU 03h ; ^C ASCII end of text 50 <4> c_HT EQU 09h ; ^I ASCII tab 51 <4> 52 <4> BREAK 53 <4> 54 <4> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 55 <4> ; ; 56 <4> ; C A V E A T P R O G R A M M E R ; 57 <4> ; ; 58 <4> ; Certain structures, constants and system calls below are private to ; 59 <4> ; the DOS and are extremely version-dependent. They may change at any ; 60 <4> ; time at the implementors' whim. As a result, they must not be ; 61 <4> ; documented to the general public. If an extreme case arises, they ; 62 <4> ; must be documented with this warning. ; 63 <4> ; ; 64 <4> ; Those structures and constants that are subject to the above will be ; 65 <4> ; marked and bracketed with the flag: ; 66 <4> ; ; 67 <4> ; C A V E A T P R O G R A M M E R ; 68 <4> ; ; 69 <4> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 70 <4> 71 <4> %include "bpb.mac" 1 <5> %warning out: BPB.INC... 1 ****************** <5> warning: out: BPB.INC... [-w+user] 2 <5> ; SCCSID = @(#)BPB.ASM 1.1 85/04/29 3 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 4 <5> ; C A V E A T P R O G R A M M E R ; 5 <5> ; ; 6 <5> 7 <5> ; BIOS PARAMETER BLOCK DEFINITION 8 <5> ; THIS STRUCTURE IS USED TO BUILD A FULL DPB 9 <5> 10 <5> BPBLOCK STRUC 0 00000D12 ???? BPSECSZ DW ? ; SIZE IN BYTES OF PHYSICAL SECTOR 0 00000D14 ?? BPCLUS DB ? ; SECTORS/ALLOC UNIT 0 00000D15 ???? BPRES DW ? ; NUMBER OF RESERVED SECTORS 0 00000D17 ?? BPFTCNT DB ? ; NUMBER OF FATS 0 00000D18 ???? BPDRCNT DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00000D1A ???? BPSCCNT DW ? ; TOTAL NUMBER OF SECTORS 0 00000D1C ?? BPMEDIA DB ? ; MEDIA DESCRIPTOR BYTE 0 00000D1D ???? BPFTSEC DW ? ; NUMBER OF SECTORS TAKEN UP BY ONE FAT 19 <5> BPBLOCK ENDS 20 <5> 21 <5> A_BPB STRUC 0 00000D12 ???? BPB_BYTESPERSECTOR DW ? 0 00000D14 ?? BPB_SECTORSPERCLUSTER DB ? 0 00000D15 ???? BPB_RESERVEDSECTORS DW ? 0 00000D17 ?? BPB_NUMBEROFFATS DB ? 0 00000D18 ???? BPB_ROOTENTRIES DW ? 0 00000D1A ???? BPB_TOTALSECTORS DW ? 0 00000D1C ?? BPB_MEDIADESCRIPTOR DB ? 0 00000D1D ???? BPB_SECTORSPERFAT DW ? 0 00000D1F ???? BPB_SECTORSPERTRACK DW ? 0 00000D21 ???? BPB_HEADS DW ? 0 00000D23 ???? BPB_HIDDENSECTORS DW ? 0 00000D25 ???? DW ? 0 00000D27 ???? BPB_BIGTOTALSECTORS DW ? 0 00000D29 ???? DW ? 0 00000D2B ???????????? DB 6 DUP(?) 37 <5> A_BPB ENDS 38 <5> ; ; 39 <5> ; C A V E A T P R O G R A M M E R ; 40 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 72 <4> 73 <4> %include "buffer.mac" 1 <5> %include "buf2sw.mac" 1 <6> %define BUF2 1 2 <5> 3 <5> ; SCCSID = @(#)buffer.asm 1.1 85/04/09 4 <5> BREAK 5 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 6 <5> ; C A V E A T P R O G R A M M E R ; 7 <5> ; ; 8 <5> 9 <5> %ifdef BUF2 10 <5> 11 <5> ; Field definition for I/O buffer information 12 <5> 13 <5> BUFFINFO STRUC 0 00000D12 ???????? NEXTBUF DD ? ; Pointer to next buffer in list 15 <5> ; The next two items are often refed as a word 16 <5> buf_ID: 0 00000D16 ?? BUFDRV DB ? ; Logical drive # assoc with buffer FF = free 18 <5> buf_flags: 0 00000D17 ?? BUFDATAFLAG db ? 0 00000D18 ?? BUFPRI DB ? ; Buffer selection priority (see EQUs below) 0 00000D19 ?? alignb 2 22 <5> buf_sector: 0 00000D1A ???????? BUFSECNO dd ? ; Sector number of buffer 24 <5> alignb 2 0 00000D1E ???????? BUFDRVDP DD ? ; Pointer to drive parameters 26 <5> BUFFINFO ENDS 27 <5> 28 <5> BUFINSIZ EQU BUFFINFO_struc_size 29 <5> ; Size of structure in bytes 30 <5> BUFINSIZE equ BUFINSIZ 31 <5> 32 <5> FREEPRI EQU 0 33 <5> LBRPRI EQU 2 ; Last byte of buffer read 34 <5> LBWPRI EQU 4 ; Last byte written 35 <5> RPRI EQU 6 ; Read but not last byte 36 <5> WPRI EQU 8 ; Written but not last byte 37 <5> DIRPRI EQU 15 ; Directory Sector 38 <5> FATPRI EQU 30 ; FAT sector 39 <5> 40 <5> buf_dirty EQU 01000000B 41 <5> buf_isDATA EQU 00001000B 42 <5> buf_isDIR EQU 00000100B 43 <5> buf_isFAT EQU 00000010B 44 <5> buf_type_0 EQU 11110001B ; AND sets type to "none" 45 <5> 46 <5> %else 47 <5> 48 <5> ; Field definition for I/O buffer information 49 <5> 50 <5> BUFFINFO STRUC 51 <5> buf_next DW ? ; Pointer to next buffer in list 52 <5> buf_prev DW ? ; Pointer to prev buffer in list 53 <5> buf_ID DB ? ; Drive of buffer (bit 7 = 0) 54 <5> ; SFT table index (bit 7 = 1) 55 <5> ; = FFH if buffer free 56 <5> buf_flags DB ? ; Bit 7 = 1 if Remote file buffer 57 <5> ; = 0 if Local device buffer 58 <5> ; Bit 6 = 1 if buffer dirty 59 <5> ; Bit 5 = Reserved 60 <5> ; Bit 4 = Search bit (bit 7 = 1) 61 <5> ; Bit 3 = 1 if buffer is DATA 62 <5> ; Bit 2 = 1 if buffer is DIR 63 <5> ; Bit 1 = 1 if buffer is FAT 64 <5> ; Bit 0 = Reserved 65 <5> buf_sector DD ? ; Sector number of buffer (bit 7 = 0) 66 <5> ; The next two items are often refed as a word (bit 7 = 0) 67 <5> buf_wrtcnt DB ? ; For FAT sectors, # times sector written out 68 <5> buf_wrtcntinc DW ? ; " " " , # sectors between each write 69 <5> buf_DPB DD ? ; Pointer to drive parameters 70 <5> buf_fill DW ? ; How full buffer is (bit 7 = 1) 71 <5> buf_reserved DB ? ; make DWORD boundary for 386 72 <5> BUFFINFO ENDS 73 <5> 74 <5> labelsize buf_offset, dword, buf_sector 75 <5> ;For bit 7 = 1, this is the byte 76 <5> ;offset of the start of the buffer in 77 <5> ;the file pointed to by buf_ID. Thus 78 <5> ;the buffer starts at location 79 <5> ;buf_offset in the file and contains 80 <5> ;buf_fill bytes. 81 <5> 82 <5> BUFINSIZ EQU BUFFINFO_struc_size 83 <5> ; Size of structure in bytes 84 <5> 85 <5> buf_Free EQU 0FFh ; buf_id of free buffer 86 <5> 87 <5> ;Flag byte masks 88 <5> buf_isnet EQU 10000000B 89 <5> buf_dirty EQU 01000000B 90 <5> 91 <5> buf_isDATA EQU 00001000B 92 <5> buf_isDIR EQU 00000100B 93 <5> buf_isFAT EQU 00000010B 94 <5> buf_type_0 EQU 11110001B ; AND sets type to "none" 95 <5> 96 <5> buf_NetID EQU BUFINSIZ 97 <5> 98 <5> ; 99 <5> ; Buffer Hash Entry Structure 100 <5> 101 <5> BUFFER_HASH_ENTRY STRUC ; DOS 4.00 102 <5> EMS_PAGE_NUM DW ? ; logical page number for EMS handle 103 <5> BUFFER_BUCKET DD ? ; pointer to buffers 104 <5> DIRTY_COUNT DB ? ; number of dirty buffers 105 <5> BUFFER_RESERVED DB ? ; reserved 106 <5> BUFFER_HASH_ENTRY ENDS 107 <5> 108 <5> MaxBuffinBucket EQU 15 ; Max number of buffers per bucket 109 <5> MaxBucketinPage EQU 2 ; Max number of buckets per 16kb page 110 <5> 111 <5> %endif 112 <5> 113 <5> ; ; 114 <5> ; C A V E A T P R O G R A M M E R ; 115 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 74 <4> 75 <4> BREAK 76 <4> ; Location of user registers relative user stack pointer 77 <4> 78 <4> user_environ STRUC 0 00000D12 ???? user_AX DW ? 0 00000D14 ???? user_BX DW ? 0 00000D16 ???? user_CX DW ? 0 00000D18 ???? user_DX DW ? 0 00000D1A ???? user_SI DW ? 0 00000D1C ???? user_DI DW ? 0 00000D1E ???? user_BP DW ? 0 00000D20 ???? user_DS DW ? 0 00000D22 ???? user_ES DW ? 0 00000D24 ???? user_IP DW ? 0 00000D26 ???? user_CS DW ? 0 00000D28 ???? user_F DW ? 91 <4> user_environ ENDS 92 <4> 93 <4> %include "sysvar.mac" 1 <5> ; SCCSID = @(#)sysvar.asm 1.1 85/04/10 2 <5> %include "version.mac" 1 <6> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <6> TRUE EQU 0FFFFh 3 <6> TRUEBYTE EQU 0FFh 4 <6> FALSE EQU 0 5 <6> 6 <6> ; 7 <6> ; Use the following switches to control cmacros.inc 8 <6> ; 9 <6> ?PLM equ 0 10 <6> ?WIN equ 0 11 <6> 12 <6> memS EQU 1 ; Small model 13 <6> ; 14 <6> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <6> ; version of the operating system 16 <6> ; 17 <6> ; The below chart will indicate how to set the switches to build the various 18 <6> ; versions 19 <6> ; 20 <6> ; IBMVER IBMCOPYRIGHT 21 <6> ; -------------------------------------------------------- 22 <6> ; IBM Version | TRUE TRUE 23 <6> ; -------------------------------------------------------- 24 <6> ; MS Version | FALSE FALSE 25 <6> ; -------------------------------------------------------- 26 <6> ; Clone Version | TRUE FALSE 27 <6> ; 28 <6> IBMVER EQU TRUE 29 <6> IBMCOPYRIGHT EQU FALSE 30 <6> 31 <6> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <6> 33 <6> %ifndef MSVER 34 <6> MSVER EQU ~ IBMVER 35 <6> %endif 36 <6> IBM EQU IBMVER 37 <6> ; 38 <6> ; 39 <6> %IF IBMVER 40 <6> %IF IBMCOPYRIGHT 41 <6> %warning out: ... IBM version build switch on ... 42 <6> %ELSE 43 <6> %warning out: ... CLONE version build switch on ... 43 ****************** <6> warning: out: ... CLONE version build switch on ... [-w+user] 44 <6> %ENDIF 45 <6> %ELSE 46 <6> %IFN IBMCOPYRIGHT 47 <6> %warning out: ... MS version build switch on ... 48 <6> %ELSE 49 <6> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <6> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <6> %ENDIF 52 <6> %ENDIF 53 <6> ; 54 <6> ; 55 <6> ;*************************************************************************** 56 <6> ;* The following switches are for DBCS or SBCS support * 57 <6> ;* * 58 <6> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <6> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <6> ;* * 61 <6> ;*************************************************************************** 62 <6> ; 63 <6> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <6> 65 <6> ; 66 <6> ; Switch INTERNAT for DBCS support 67 <6> ; 68 <6> INTERNAT EQU FALSE 69 <6> ; 70 <6> %IF INTERNAT 71 <6> %ifndef KANJI 72 <6> KANJI EQU TRUE 73 <6> %endif 74 <6> IBMJAPAN EQU TRUE 75 <6> %ELSE 76 <6> %ifndef KANJI 77 <6> KANJI EQU FALSE 78 <6> %endif 79 <6> IBMJAPAN EQU FALSE 80 <6> %ENDIF 81 <6> 82 <6> %ifndef altvect ; avoid jerking off vector.inc 83 <6> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <6> %endif 85 <6> 86 <6> ; 87 <6> ; Country code switches 88 <6> ; The default contry code is assumed as USA. 89 <6> ; 90 <6> %IF INTERNAT 91 <6> KOREA EQU TRUE 92 <6> JAPAN EQU FALSE 93 <6> %ELSE 94 <6> KOREA EQU FALSE 95 <6> JAPAN EQU FALSE 96 <6> %ENDIF 97 <6> ; 98 <6> %IF INTERNAT 99 <6> %warning out: Internat(ECS) version build switch on 100 <6> %ENDIF 3 <5> 4 <5> SysInitVars STRUC 0 00000D12 ???????? SYSI_DPB DD ? ; DPB chain 0 00000D16 ???????? SYSI_SFT DD ? ; SFT chain 0 00000D1A ???????? SYSI_CLOCK DD ? ; CLOCK device 0 00000D1E ???????? SYSI_CON DD ? ; CON device 0 00000D22 ???? SYSI_MAXSEC DW ? ; maximum sector size 0 00000D24 ???????? SYSI_BUF DD ? ; points to Hashinitvar 0 00000D28 ???????? SYSI_CDS DD ? ; CDS list 0 00000D2C ???????? SYSI_FCB DD ? ; FCB chain 0 00000D30 ???? SYSI_Keep DW ? ; keep count 0 00000D32 ?? SYSI_NUMIO DB ? ; Number of block devices 0 00000D33 ?? SYSI_NCDS DB ? ; number of CDS's 0 00000D34 ???????? SYSI_DEV DD ? ; device list 0 00000D38 ???? SYSI_ATTR DW ? ; null device attribute word 0 00000D3A ???? SYSI_STRAT DW ? ; null device strategy entry point 0 00000D3C ???? SYSI_INTER DW ? ; null device interrupt entry point 0 00000D3E ???????????????? SYSI_NAME DB 8 DUP(?) ; null device name 0 00000D46 ?? SYSI_SPLICE DB ? ; TRUE -> splicees being done 0 00000D47 ???? SYSI_IBMDOS_SIZE DW ? ; DOS size in paragraphs 0 00000D49 ???????? SYSI_IFS_DOSCALL@ DD ? ; IFS DOS service rountine entry 0 00000D4D ???????? SYSI_IFS DD ? ; IFS header chain 0 00000D51 ???????? SYSI_BUFFERS DW ?,? ; BUFFERS= values (m,n) 0 00000D55 ?? SYSI_BOOT_DRIVE DB ? ; boot drive A=1 B=2,.. 0 00000D56 ?? SYSI_DWMOVE DB ? ; 1 if 386 machine 0 00000D57 ???? SYSI_EXT_MEM DW ? ; Extended memory size in KB. 29 <5> SysInitVars ENDS 30 <5> 31 <5> ;This is added for more information exchage between DOS, BIOS. 32 <5> ;DOS will give the pointer to SysInitTable in ES:DI. - J.K. 5/29/86 33 <5> SysInitVars_Ext struc 0 00000D12 ???????? SYSI_InitVars DD ? ; Points to the above structure. 0 00000D16 ???????? SYSI_Country_Tab DD ? ; DOS_Country_cdpg_info 36 <5> SysInitVars_Ext ends 37 <5> 38 <5> ;The SYSI_BUF of SysInitVars points to the follwong structure 39 <5> EMS_MAP_BUFF_SIZE EQU 12 ; EMS map buffer size 40 <5> 41 <5> Buffinfo STRUC 0 00000D12 ???????? Hash_ptr DD ? ; pointer to Hash table 0 00000D16 ???? Hash_count DW ? ; number of Hash entries 0 00000D18 ???????? Cache_ptr DD ? ; pointer to secondary cache 0 00000D1C ???? Cache_count DW ? ; number of secondary cache entries 46 <5> 47 <5> %IF BUFFERFLAG 48 <5> 0 00000D1E ?? EMS_SAFE_FLAG DB ? 0 00000D1F ???????? EMS_LAST_PAGE DW ?, ? 0 00000D23 ???????? EMS_FIRST_PAGE DW ?, ? 0 00000D27 ???? EMS_NPA640 DW ? 53 <5> 54 <5> %ENDIF 55 <5> 0 00000D29 ?? EMS_mode DB ? ; no EMS = -1 0 00000D2A ???? EMS_handle DW ? ; EMS handle for buffers 0 00000D2C ???? EMS_PageFrame_Number DW ? ; EMS page frame number 0 00000D2E ???? EMS_Seg_Cnt DW ? ; EMS segment count 0 00000D30 ???? EMS_Page_Frame DW ? ; EMS page frame segment address 0 00000D32 ???? EMS_reserved DW ? ; EMS segment count 62 <5> 63 <5> %IF BUFFERFLAG 0 00000D34 ?? EMS_Map_Buff DB ? ; map buffer 65 <5> %ELSE 66 <5> EMS_Map_Buff DB 12 dup(?) 67 <5> %ENDIF 68 <5> 69 <5> Buffinfo ENDS 70 <5> 71 <5> 72 <5> 73 <5> 74 <5> 75 <5> 76 <5> 77 <5> 94 <4> 95 <4> %include "vector.mac" 1 <5> ; SCCSID = @(#)vector.asm 1.1 85/04/10 2 <5> BREAK 3 <5> 4 <5> ;Asmvar AltVect 5 <5> %ifndef AltVect 6 <5> %iassign AltVect 0 7 <5> %endif 8 <5> 9 <5> INTTAB EQU 20H 10 <5> inttab equ INTTAB ; NASM port equate 11 <5> INTBASE EQU 4 * inttab 12 <5> ENTRYPOINT EQU INTBASE+40H 13 <5> 14 <5> %IF ALTVECT 15 <5> ALTTAB EQU 0F0H 16 <5> ALTBASE EQU 4 * ALTTAB 17 <5> %ENDIF 18 <5> 19 <5> ; 20 <5> ; interrupt assignments 21 <5> ; 22 <5> %IFN ALTVECT 23 <5> int_abort EQU INTTAB ; abort process 24 <5> int_command EQU int_abort+1 ; call MSDOS 25 <5> int_terminate EQU int_abort+2 ; int to terminate address 26 <5> int_ctrl_c EQU int_abort+3 ; ^c trapper 27 <5> int_fatal_abort EQU int_abort+4 ; hard disk error 28 <5> int_disk_read EQU int_abort+5 ; logical sector disk read 29 <5> int_disk_write EQU int_abort+6 ; logical sector disk write 30 <5> int_keep_process EQU int_abort+7 ; terminate program and stay 31 <5> ; resident 32 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <5> ; C A V E A T P R O G R A M M E R ; 34 <5> ; ; 35 <5> int_spooler EQU int_abort+8 ; spooler call 36 <5> int_fastcon EQU int_abort+9 ; fast CON interrupt 37 <5> int_IBM EQU int_abort+10; critical section maintenance 38 <5> ; ; 39 <5> ; C A V E A T P R O G R A M M E R ; 40 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <5> %ELSE 42 <5> int_abort EQU INTTAB ; abort process 43 <5> int_command EQU int_abort+1 ; call MSDOS 44 <5> int_terminate EQU ALTTAB ; int to terminate address 45 <5> int_ctrl_c EQU int_terminate+1 ; ^c trapper 46 <5> int_fatal_abort EQU int_terminate+2 ; hard disk error 47 <5> int_disk_read EQU int_abort+5 ; logical sector disk read 48 <5> int_disk_write EQU int_abort+6 ; logical sector disk write 49 <5> int_keep_process EQU int_abort+7 ; terminate program and stay resident 50 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 51 <5> ; C A V E A T P R O G R A M M E R ; 52 <5> ; ; 53 <5> int_spooler EQU int_terminate+3 ; spooler call 54 <5> int_fastcon EQU int_abort+9 ; fast CON interrupt 55 <5> ; ; 56 <5> ; C A V E A T P R O G R A M M E R ; 57 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <5> %ENDIF 59 <5> 60 <5> addr_int_abort EQU 4 * int_abort 61 <5> addr_int_command EQU 4 * int_command 62 <5> addr_int_terminate EQU 4 * int_terminate 63 <5> addr_int_ctrl_c EQU 4 * int_ctrl_c 64 <5> addr_int_fatal_abort EQU 4 * int_fatal_abort 65 <5> addr_int_disk_read EQU 4 * int_disk_read 66 <5> addr_int_disk_write EQU 4 * int_disk_write 67 <5> addr_int_keep_process EQU 4 * int_keep_process 68 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 69 <5> ; C A V E A T P R O G R A M M E R ; 70 <5> ; ; 71 <5> addr_int_spooler EQU 4 * int_spooler 72 <5> addr_int_fastcon EQU 4 * int_fastcon 73 <5> addr_int_IBM EQU 4 * int_IBM 74 <5> ; ; 75 <5> ; C A V E A T P R O G R A M M E R ; 76 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 96 <4> 97 <4> %include "mult.mac" 1 <5> ; SCCSID = @(#)mult.asm 1.2 85/04/12 2 <5> Break 3 <5> 4 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <5> ; C A V E A T P R O G R A M M E R ; 6 <5> ; ; 7 <5> ; Critical section definitions 8 <5> ; 9 <5> ; These below are subject to leave-all sections 10 <5> critDisk EQU 1 ; Disk I/O critical section 11 <5> critDevice EQU 2 ; Device I/O critical section 12 <5> critShare EQU 1 ; Sharer I/O critical section 13 <5> critMem EQU 1 ; memory maintenance critical section 14 <5> critNet EQU 5 ; network critical section 15 <5> critSFT EQU 1 ; sft table allocation 16 <5> critIFS EQU 6 ; ifsfunc critical section 17 <5> ; These below are not subject to leave-all sections 18 <5> critASSIGN EQU 8 ; Assign has munged a system call 19 <5> ; ; 20 <5> ; C A V E A T P R O G R A M M E R ; 21 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 22 <5> 23 <5> ; 24 <5> ; The current set of defined multiplex channels is (* means documented): 25 <5> ; 26 <5> ; Channel(h) Issuer Receiver Function 27 <5> ; 00 server PSPRINT print job control 28 <5> ; *01 print/apps PRINT Queueing of files 29 <5> ; 02 BIOS REDIR signal open/close of printers 30 <5> ; 31 <5> ; 05 command REDIR obtain text of net int 24 message 32 <5> ; *06 server/assign ASSIGN Install check 33 <5> ; 34 <5> ; 08 external driver IBMBIO interface to internal routines 35 <5> ; 36 <5> ; 10 sharer/server Sharer install check 37 <5> ; 11 DOS/server Redir install check/redirection funcs 38 <5> ; 12 sharer/redir DOS dos functions and structure maint 39 <5> ; 13 MSNET MSNET movement of NCBs 40 <5> ; 13 external driver IBMBIO Reset_Int_13, allows installation 41 <5> ; of alternative INT_13 drivers after 42 <5> ; boot_up 43 <5> ; 14 (IBM) DOS NLSFUNC down load NLS country info,DOS 3.3 44 <5> ; 14 (MS) APPS POPUP MSDOS 4 popup screen functions 45 <5> ; 15 APPS MSCDEX CD-ROM extensions interface 46 <5> ; 16 WIN386 WIN386 Windows communications 47 <5> ; 17 Clipboard WINDOWS Clipboard interface 48 <5> ; *18 Applications MS-Manger Toggle interface to manager 49 <5> ; 19 Shell 50 <5> ; 1A Ansi.sys 51 <5> ; 1B Fastopen,Vdisk IBMBIO EMS INT 67H stub handler 52 <5> ; 53 <5> ; AC Graphics 54 <5> ; AD NLS (toronto) 55 <5> ; AE 56 <5> ; AF Mode 57 <5> ; B0 GRAFTABL GRAFTABL 58 <5> ; 59 <5> 60 <5> 61 <5> ;MUX 00-3F reserverd for IBM 62 <5> ;MUX 80-BF reserverd for IBM 63 <5> ;MUX 40-7F reserved for Microsoft 64 <5> ;MUX C0-FF users 65 <5> 66 <5> 67 <5> 68 <5> MultSHARE EQU 10h ; sharer 69 <5> ; 1 MFT_enter 70 <5> ; 2 MFTClose 71 <5> ; 3 MFTclU 72 <5> ; 4 MFTCloseP 73 <5> ; 5 MFTCloN 74 <5> ; 6 set_block 75 <5> ; 7 clr_block 76 <5> ; 8 chk_block 77 <5> ; 9 MFT_get 78 <5> ; 10 ShSave 79 <5> ; 11 ShChk 80 <5> ; 12 ShCol 81 <5> ; 13 ShCloseFile 82 <5> 83 <5> MultNET EQU 11h ; Network support 84 <5> MultIFS EQU 11h ; Network support 85 <5> ; 1 IFS_RMDIR 86 <5> ; 2 IFS_SEQ_RMDIR 87 <5> ; 3 IFS_MKDIR 88 <5> ; 4 IFS_SEQ_MKDIR 89 <5> ; 5 IFS_CHDIR 90 <5> ; 6 IFS_CLOSE 91 <5> ; 7 IFS_COMMIT 92 <5> ; 8 IFS_READ 93 <5> ; 9 IFS_WRITE 94 <5> ; 10 IFS_LOCK 95 <5> ; 11 IFS_UNLOCK 96 <5> ; 12 IFS_DISK_INFO 97 <5> ; 13 IFS_SET_FILE_ATTRIBUTE 98 <5> ; 14 IFS_SEQ_SET_FILE_ATTRIBUTE 99 <5> ; 15 IFS_GET_FILE_INFO 100 <5> ; 16 IFS_SEQ_GET_FILE_INFO 101 <5> ; 17 IFS_RENAME 102 <5> ; 18 IFS_SEQ_RENAME 103 <5> ; 19 IFS_DELETE 104 <5> ; 20 IFS_SEQ_DELETE 105 <5> ; 21 IFS_OPEN 106 <5> ; 22 IFS_SEQ_OPEN 107 <5> ; 23 IFS_CREATE 108 <5> ; 24 IFS_SEQ_CREATE 109 <5> ; 25 IFS_SEQ_SEARCH_FIRST 110 <5> ; 26 IFS_SEQ_SEARCH_NEXT 111 <5> ; 27 IFS_SEARCH_FIRST 112 <5> ; 28 IFS_SEARCH_NEXT 113 <5> ; 29 IFS_ABORT 114 <5> ; 30 IFS_ASSOPER 115 <5> ; 31 Printer_SET_STRING 116 <5> ; 32 IFSFlushBuf 117 <5> ; 33 IFSBufWrite 118 <5> ; 34 IFSResetEnvironment 119 <5> ; 35 IFSSpoolCheck 120 <5> ; 36 IFSSpoolClose 121 <5> 122 <5> MultDOS EQU 12h ; DOS call back 123 <5> ; 1 DOS_CLOSE 124 <5> ; 2 RECSET 125 <5> ; 3 Get DOSGROUP 126 <5> ; 4 PATHCHRCMP 127 <5> ; 5 OUT 128 <5> ; 6 NET_I24_ENTRY 129 <5> ; 7 PLACEBUF 130 <5> ; 8 FREE_SFT 131 <5> ; 9 BUFWRITE 132 <5> ; 10 SHARE_VIOLATION 133 <5> ; 11 SHARE_ERROR 134 <5> ; 12 SET_SFT_MODE 135 <5> ; 13 DATE16 136 <5> ; 14 SETVISIT 137 <5> ; 15 SCANPLACE 138 <5> ; 16 SKIPVISIT 139 <5> ; 17 StrCpy 140 <5> ; 18 StrLen 141 <5> ; 19 Ucase 142 <5> ; 20 POINTCOMP 143 <5> ; 21 CHECKFLUSH 144 <5> ; 22 SFFromSFN 145 <5> ; 23 GetCDSFromDrv 146 <5> ; 24 Get_User_Stack 147 <5> ; 25 GetThisDrv 148 <5> ; 26 DriveFromText 149 <5> ; 27 SETYEAR 150 <5> ; 28 DSUM 151 <5> ; 29 DSLIDE 152 <5> ; 30 StrCmp 153 <5> ; 31 initcds 154 <5> ; 32 pjfnfromhandle 155 <5> ; 33 $NameTrans 156 <5> ; 34 CAL_LK 157 <5> ; 35 DEVNAME 158 <5> ; 36 Idle 159 <5> ; 37 DStrLen 160 <5> ; 38 NLS_OPEN DOS 3.3 161 <5> ; 39 $CLOSE DOS 3.3 162 <5> ; 40 NLS_LSEEK DOS 3.3 163 <5> ; 41 $READ DOS 3.3 164 <5> ; 42 FastInit DOS 4.0 165 <5> ; 43 NLS_IOCTL DOS 3.3 166 <5> ; 44 GetDevList DOS 3.3 167 <5> ; 45 NLS_GETEXT DOS 3.3 168 <5> ; 46 MSG_RETRIEVAL DOS 4.0 169 <5> ; 47 FAKE_VERSION DOS 4.0 170 <5> ; 171 <5> NLSFUNC EQU 14h ; NLSFUNC CALL , DOS 3.3 172 <5> ; 0 NLSInstall 173 <5> ; 1 ChgCodePage 174 <5> ; 2 GetExtInfo 175 <5> ; 3 SetCodePage 176 <5> ; 4 GetCntry 177 <5> ; 178 <5> ;FASTOPEN is not chained through INT 2F ; DOS 3.3 F.C. 179 <5> ; it calls Multdos 42 to set up an entry routine address 180 <5> ; 0 Install status (reserved) 181 <5> ; 1 Lookup 182 <5> ; 2 Insert 183 <5> ; 3 Delete 184 <5> ; 4 Purge (reserved) 98 <4> 99 <4> BREAK 100 <4> ; MSDOS partitions the disk into 4 sections: 101 <4> ; 102 <4> ; phys sector 0: +-------------------+ 103 <4> ; | | boot/reserved | 104 <4> ; | +-------------------+ 105 <4> ; | | File allocation | 106 <4> ; v | table(s) | 107 <4> ; | (multiple copies | 108 <4> ; | are kept) | 109 <4> ; +-------------------+ 110 <4> ; | Directory | 111 <4> ; +-------------------+ 112 <4> ; | File space | 113 <4> ; +-------------------+ 114 <4> ; | Unaddressable | 115 <4> ; | (to end of disk) | 116 <4> ; +-------------------+ 117 <4> ; 118 <4> ; All partition boundaries are sector boundaries. The size of the FAT is 119 <4> ; adjusted to maximize the file space addressable. 120 <4> 121 <4> %include "dirent.mac" 1 <5> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 3 <5> Break 4 <5> 5 <5> ; 6 <5> ; +---------------------------+ 7 <5> ; | (12 BYTE) filename/ext | 0 0 8 <5> ; +---------------------------+ 9 <5> ; | (BYTE) attributes | 11 B 10 <5> ; +---------------------------+ 11 <5> ; | (10 BYTE) reserved | 12 C 12 <5> ; +---------------------------+ 13 <5> ; | (WORD) time of last write | 22 16 14 <5> ; +---------------------------+ 15 <5> ; | (WORD) date of last write | 24 18 16 <5> ; +---------------------------+ 17 <5> ; | (WORD) First cluster | 26 1A 18 <5> ; +---------------------------+ 19 <5> ; | (DWORD) file size | 28 1C 20 <5> ; +---------------------------+ 21 <5> ; 22 <5> ; First byte of filename = E5 -> free directory entry 23 <5> ; = 00 -> end of allocated directory 24 <5> ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour 25 <5> ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 26 <5> ; 27 <5> 28 <5> dir_entry STRUC 0 00000D12 ?????????????????? dir_name DB 11 DUP (?) ; file name 29 00000009 ???? <5> 0 00000D1D ?? dir_attr DB ? ; attribute bits 0 00000D1E ???? dir_codepg dw ? ; code page DOS 4.00 0 00000D20 ???? dir_extcluster dw ? ; extended attribute starting cluster 0 00000D22 ?? dir_attr2 db ? ; reserved 0 00000D23 ?????????? dir_pad DB 5 DUP (?) ; reserved for expansion 0 00000D28 ???? dir_time DW ? ; time of last write 0 00000D2A ???? dir_date DW ? ; date of last write 0 00000D2C ???? dir_first DW ? ; first allocation unit of file 0 00000D2E ???? dir_size_l DW ? ; low 16 bits of file size 0 00000D30 ???? dir_size_h DW ? ; high 16 bits of file size 40 <5> dir_entry ENDS 41 <5> 42 <5> attr_read_only EQU 1h 43 <5> attr_hidden EQU 2h 44 <5> attr_system EQU 4h 45 <5> attr_volume_id EQU 8h 46 <5> attr_directory EQU 10h 47 <5> attr_archive EQU 20h 48 <5> attr_device EQU 40h ; This is a VERY special bit. 49 <5> ; NO directory entry on a disk EVER 50 <5> ; has this bit set. It is set non-zero 51 <5> ; when a device is found by GETPATH 52 <5> 53 <5> attr_all EQU attr_hidden+attr_system+attr_directory 54 <5> ; OR of hard attributes for FINDENTRY 55 <5> 56 <5> attr_ignore EQU attr_read_only+attr_archive+attr_device 57 <5> ; ignore this(ese) attribute(s) during 58 <5> ; search first/next 59 <5> 60 <5> attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive 61 <5> ; changeable via CHMOD 122 <4> 123 <4> BREAK 124 <4> ; 125 <4> ; The File Allocation Table uses a 12-bit entry for each allocation unit on 126 <4> ; the disk. These entries are packed, two for every three bytes. The contents 127 <4> ; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result 128 <4> ; to the base address of the Allocation Table; 3) fetching the 16-bit word 129 <4> ; at this address; 4) If N was odd (so that N*1.5 was not an integer), shift 130 <4> ; the word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry 131 <4> ; number zero is used as an end-of-file trap in the OS and is passed to the 132 <4> ; BIOS to help determine disk format. Entry 1 is reserved for future use. 133 <4> ; The first available allocation unit is assigned entry number two, and even 134 <4> ; though it is the first, is called cluster 2. Entries greater than 0FF8H 135 <4> ; (12-bit fats) or 0FFF8H (16-bit fats) are end of file marks; entries of zero 136 <4> ; are unallocated. Otherwise, the contents of a FAT entry is the number of 137 <4> ; the next cluster in the file. 138 <4> ; 139 <4> ; Clusters with bad sectors are tagged with FF7H. Any non-zero number would 140 <4> ; do because these clusters show as allocated, but are not part of any 141 <4> ; allocation chain and thus will never be allocated to a file. A particular 142 <4> ; number is selected so that disk checking programs know what to do (ie. a 143 <4> ; cluster with entry FF7H which is not in a chain is not an error). 144 <4> 145 <4> %include "dpb.mac" 1 <5> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 3 <5> BREAK 4 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <5> ; C A V E A T P R O G R A M M E R ; 6 <5> ; ; 7 <5> dpb STRUC 0 00000D12 ?? dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) 0 00000D13 ?? dpb_UNIT DB ? ; Driver unit number of DPB 0 00000D14 ???? dpb_sector_size DW ? ; Size of physical sector in bytes 0 00000D16 ?? dpb_cluster_mask DB ? ; Sectors/cluster - 1 0 00000D17 ?? dpb_cluster_shift DB ? ; Log2 of sectors/cluster 0 00000D18 ???? dpb_first_FAT DW ? ; Starting record of FATs 0 00000D1A ?? dpb_FAT_count DB ? ; Number of FATs for this drive 0 00000D1B ???? dpb_root_entries DW ? ; Number of directory entries 0 00000D1D ???? dpb_first_sector DW ? ; First sector of first cluster 0 00000D1F ???? dpb_max_cluster DW ? ; Number of clusters on drive + 1 0 00000D21 ???? dpb_FAT_size DW ? ;;Number of records occupied by FAT 0 00000D23 ???? dpb_dir_sector DW ? ; Starting record of directory 0 00000D25 ???????? dpb_driver_addr DD ? ; Pointer to driver 0 00000D29 ?? dpb_media DB ? ; Media byte 0 00000D2A ?? dpb_first_access DB ? ; This is initialized to -1 to force a media 23 <5> ; check the first time this DPB is used 0 00000D2B ???????? dpb_next_dpb DD ? ; Pointer to next Drive parameter block 0 00000D2F ???? dpb_next_free DW ? ; Cluster # of last allocated cluster 0 00000D31 ???? dpb_free_cnt DW ? ; Count of free clusters, -1 if unknown 27 <5> dpb ENDS 28 <5> 29 <5> DPBSIZ EQU dpb_struc_size ; Size of the structure in bytes 30 <5> 31 <5> DSKSIZ equ dpb_max_cluster ; Size of disk (temp used during init only) 32 <5> ; ; 33 <5> ; C A V E A T P R O G R A M M E R ; 34 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 146 <4> 147 <4> %include "curdir.mac" 1 <5> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 3 <5> BREAK 4 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <5> ; C A V E A T P R O G R A M M E R ; 6 <5> ; ; 7 <5> ; CDS items are used bu the internal routines to store cluster numbers and ; 8 <5> ; network identifiers for each logical name. The ID field is used dually, ; 9 <5> ; both as net ID and for a cluster number for local devices. In the case ; 10 <5> ; of local devices, the cluster number will be -1 if there is a potential ; 11 <5> ; of the disk being changed or if the path must be recracked. The END ; 12 <5> ; field is the location of the end of the definition. No .. is allowed ; 13 <5> ; past this point ; 14 <5> 15 <5> DIRSTRLEN EQU 64+3 ; Max length in bytes of directory strings 16 <5> TEMPLEN EQU DIRSTRLEN*2 17 <5> 18 <5> curdir_list STRUC 0 00000D12 ?????????????????? curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 19 00000009 ??????????????????- <5> 19 00000012 ??????????????????- <5> 19 0000001B ??????????????????- <5> 19 00000024 ??????????????????- <5> 19 0000002D ??????????????????- <5> 19 00000036 ??????????????????- <5> 19 0000003F ???????? <5> 0 00000D55 ???? curdir_flags DW ? ; various flags 0 00000D57 ???????? curdir_devptr DD ? ; local pointer to DPB or net device 0 00000D5B ???? curdir_ID DW ? ; cluster of current dir (net ID) 0 00000D5D ???? DW ? 0 00000D5F ???? curdir_user_word DW ? 0 00000D61 ???? curdir_end DW ? ; end of assignment 0 00000D63 ?? curdir_type DB ? ; IFS drive (2=ifs, 4=netuse) 0 00000D64 ???????? curdir_ifs_hdr DD ? ; Ptr to File System Header 0 00000D68 ???? curdir_fsda DB 2 DUP (?) ; File System Dependent Data Area 29 <5> curdir_list ENDS 30 <5> 31 <5> curdirLen EQU curdir_list_struc_size ; Needed for screwed up 32 <5> ; ASM87 which doesn't allow 33 <5> ; Size directive as a macro 34 <5> ; argument 35 <5> labelsize curdir_netID, dword, curdir_ID 36 <5> 37 <5> ;Flag word masks 38 <5> curdir_isnet EQU 1000000000000000B 39 <5> curdir_isifs EQU 1000000000000000B ; DOS 4.00 40 <5> curdir_inuse EQU 0100000000000000B 41 <5> curdir_splice EQU 0010000000000000B 42 <5> curdir_local EQU 0001000000000000B 43 <5> ; ; 44 <5> ; C A V E A T P R O G R A M M E R ; 45 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 148 <4> 149 <4> %include "cpmfcb.mac" 1 <5> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 3 <5> ;BREAK 4 <5> 5 <5> ; 6 <5> ; Field definition for FCBs 7 <5> ; The FCB has the following structure: 8 <5> ; 9 <5> ; +---------------------------+ 10 <5> ; | Drive indicator(byte) | 11 <5> ; +---------------------------+ 12 <5> ; | Filename (8 chars) | 13 <5> ; +---------------------------+ 14 <5> ; | Extension (3 chars) | 15 <5> ; +---------------------------+ 16 <5> ; | Current Extent(word) | 17 <5> ; +---------------------------+ 18 <5> ; | Record size (word) | 19 <5> ; +---------------------------+ 20 <5> ; | File Size (2 words) | 21 <5> ; +---------------------------+ 22 <5> ; | Date of write | 23 <5> ; +---------------------------+ 24 <5> ; | Time of write | 25 <5> ; +---------------------------+ 26 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 27 <5> ; C A V E A T P R O G R A M M E R ; 28 <5> ; ; 29 <5> ; +---------------------------+ 30 <5> ; | 8 bytes reserved | 31 <5> ; +---------------------------+ 32 <5> ; ; 33 <5> ; C A V E A T P R O G R A M M E R ; 34 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 35 <5> ; | next record number | 36 <5> ; +---------------------------+ 37 <5> ; | random record number | 38 <5> ; +---------------------------+ 39 <5> ; 40 <5> 41 <5> sys_fcb STRUC 0 00000D12 ?? fcb_drive DB ? 0 00000D13 ???????????????? fcb_name DB 8 DUP (?) 0 00000D1B ?????? fcb_ext DB 3 DUP (?) 0 00000D1E ???? fcb_EXTENT DW ? 0 00000D20 ???? fcb_RECSIZ DW ? ; Size of record (user settable) 0 00000D22 ???? fcb_FILSIZ DW ? ; Size of file in bytes; used with the 48 <5> ; following word 0 00000D24 ???? fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT 0 00000D26 ???? fcb_FDATE DW ? ; Date of last writing 0 00000D28 ???? fcb_FTIME DW ? ; Time of last writing 52 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 53 <5> ; C A V E A T P R O G R A M M E R ; 54 <5> ; ; 0 00000D2A ???????????????? fcb_reserved DB 8 DUP (?) ; RESERVED 56 <5> ; ; 57 <5> ; C A V E A T P R O G R A M M E R ; 58 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D32 ?? fcb_NR DB ? ; Next record 0 00000D33 ???????? fcb_RR DB 4 DUP (?) ; Random record 61 <5> sys_fcb ENDS 62 <5> 63 <5> FILDIRENT equ fcb_FILSIZ ; Used only by SEARCH FIRST and SEARCH 64 <5> ; NEXT 65 <5> 66 <5> labelsize fcb_sfn, byte, fcb_reserved 67 <5> 68 <5> ; Note that fcb_net_handle, fcb_nsl_drive, fcb_nsld_drive and fcb_l_drive 69 <5> ; all must point to the same byte. Otherwise, the FCBRegen will fail. 70 <5> ; NOTE about this byte (fcb_nsl_drive) 71 <5> ; The high two bits of this byte are used as follows to indicate the FCB type 72 <5> ; 00 means a local file or device with sharing loaded 73 <5> ; 10 means a remote (network) file 74 <5> ; 01 means a local file with no sharing loaded 75 <5> ; 11 means a local device with no sharing loaded 76 <5> 77 <5> ; 78 <5> ; Network FCB 79 <5> ; 80 <5> labelsize fcb_net_drive, byte, fcb_reserved+1 81 <5> labelsize fcb_net_handle, word, fcb_reserved+2 82 <5> labelsize fcb_netID, dword, fcb_reserved+4 83 <5> 84 <5> ; 85 <5> ; No sharing local file FCB 86 <5> ; 87 <5> labelsize fcb_nsl_drive, byte, fcb_reserved+1 88 <5> labelsize fcb_nsl_bits, byte, fcb_reserved+2 89 <5> labelsize fcb_nsl_firclus, word, fcb_reserved+3 90 <5> labelsize fcb_nsl_dirsec, word, fcb_reserved+5 91 <5> labelsize fcb_nsl_dirpos, byte, fcb_reserved+7 92 <5> 93 <5> ; 94 <5> ; No sharing local device FCB 95 <5> ; 96 <5> labelsize fcb_nsld_drive, byte, fcb_reserved+1 97 <5> labelsize fcb_nsld_drvptr, dword, fcb_reserved+2 98 <5> 99 <5> ; 100 <5> ; Sharing local FCB 101 <5> ; 102 <5> labelsize fcb_l_drive, byte, fcb_reserved+1 103 <5> labelsize fcb_l_firclus, word, fcb_reserved+2 104 <5> labelsize fcb_l_mfs, word, fcb_reserved+4 105 <5> labelsize fcb_l_attr, byte, fcb_reserved+6 106 <5> 107 <5> ; 108 <5> ; Bogusness: the four cases are: 109 <5> ; 110 <5> ; local file 00 111 <5> ; local device 40 112 <5> ; local sharing C0 113 <5> ; network 80 114 <5> ; 115 <5> ; Since sharing and network collide, we cannot use a test instruction for 116 <5> ; deciding whether a network or a share check in involved 117 <5> ; 118 <5> FCBDEVICE EQU 040h 119 <5> FCBNETWORK EQU 080h 120 <5> FCBSHARE EQU 0C0h 121 <5> 122 <5> ; FCBSPECIAL must be able to mask off both net and share 123 <5> FCBSPECIAL EQU 080h 124 <5> FCBMASK EQU 0C0h 150 <4> 151 <4> %include "find.mac" 1 <5> ; SCCSID = @(#)find.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)find.asm 1.1 85/04/10 3 <5> Break 4 <5> 5 <5> find_buf STRUC 6 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 7 <5> ; C A V E A T P R O G R A M M E R ; 8 <5> ; ; 0 00000D12 ?? find_buf_drive DB ? ; drive of search 0 00000D13 ?????????????????? find_buf_name DB 11 DUP (?) ; formatted name 10 0000000A ???? <5> 0 00000D1E ?? find_buf_sattr DB ? ; attribute of search 0 00000D1F ???? find_buf_LastEnt DW ? ; LastEnt 0 00000D21 ???? find_buf_DirStart DW ? ; DirStart 0 00000D23 ???????? find_buf_NetID DB 4 DUP (?) ; Reserved for NET 15 <5> ; ; 16 <5> ; C A V E A T P R O G R A M M E R ; 17 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 18 <5> 0 00000D27 ?? find_buf_attr DB ? ; attribute found 0 00000D28 ???? find_buf_time DW ? ; time 0 00000D2A ???? find_buf_date DW ? ; date 0 00000D2C ???? find_buf_size_l DW ? ; low(size) 0 00000D2E ???? find_buf_size_h DW ? ; high(size) 0 00000D30 ?????????????????? find_buf_pname DB 13 DUP (?) ; packed name 24 00000027 ???????? <5> 25 <5> find_buf ENDS 152 <4> 153 <4> %include "pdb.mac" 1 <5> ; SCCSID = @(#)pdb.asm 1.1 85/04/10 2 <5> BREAK 3 <5> 4 <5> ; 5 <5> ; Process data block (otherwise known as program header) 6 <5> ; 7 <5> 8 <5> FilPerProc EQU 20 9 <5> 10 <5> Process_data_block STRUC 0 00000D12 ???? PDB_Exit_Call DW ? ; INT int_abort system terminate 0 00000D14 ???? PDB_block_len DW ? ; size of execution block 0 00000D16 ?? DB ? 0 00000D17 ?????????? PDB_CPM_Call DB 5 DUP (?) ; ancient call to system 0 00000D1C ???????? PDB_Exit DD ? ; pointer to exit routine 0 00000D20 ???????? PDB_Ctrl_C DD ? ; pointer to ^C routine 0 00000D24 ???????? PDB_Fatal_abort DD ? ; pointer to fatal error 18 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 19 <5> ; C A V E A T P R O G R A M M E R ; 20 <5> ; ; 0 00000D28 ???? PDB_Parent_PID DW ? ; PID of parent (terminate PID) 0 00000D2A ?????????????????? PDB_JFN_Table DB FilPerProc DUP (?) 22 00000021 ??????????????????- <5> 22 0000002A ???? <5> 23 <5> ; indices into system table 24 <5> ; ; 25 <5> ; C A V E A T P R O G R A M M E R ; 26 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D3E ???? PDB_environ DW ? ; seg addr of environment 28 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 29 <5> ; C A V E A T P R O G R A M M E R ; 30 <5> ; ; 0 00000D40 ???????? PDB_User_stack DD ? ; stack of self during system calls 0 00000D44 ???? PDB_JFN_Length DW ? ; number of handles allowed 0 00000D46 ???????? PDB_JFN_Pointer DD ? ; pointer to JFN table 0 00000D4A ???????? PDB_Next_PDB DD ? ; pointer to nested PDB's 0 00000D4E ?????????????????? PDB_PAD1 DB 14h DUP (?) 35 00000045 ??????????????????- <5> 35 0000004E ???? <5> 36 <5> ; ; 37 <5> ; C A V E A T P R O G R A M M E R ; 38 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D62 ?????????? PDB_Call_system DB 5 DUP (?) ; portable method of system call 40 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <5> ; C A V E A T P R O G R A M M E R ; 42 <5> ; ; 0 00000D67 ?????????????? PDB_PAD2 DB 7h DUP (?) 44 <5> ; ; 45 <5> ; C A V E A T P R O G R A M M E R ; 46 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 47 <5> Process_data_block ENDS 48 <5> 49 <5> labelsize PDB_InterCon, byte, PDB_PAD1 ; 2/12/KK 50 <5> labelsize PDB_Append, byte, PDB_PAD1+1 ; 2/12/KK 154 <4> 155 <4> %include "exe.mac" 1 <5> ; SCCSID = @(#)exe.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)exe.asm 1.1 85/04/10 3 <5> BREAK 4 <5> ; 5 <5> ; EXEC arg block - load/go program 6 <5> ; 7 <5> 8 <5> ; 9 <5> ; The following get used as arguments to the EXEC system call. They indicate 10 <5> ; whether or not the program is executed or whether or not a program header 11 <5> ; gets created. 12 <5> ; 13 <5> exec_func_no_execute EQU 1 ; no execute bit 14 <5> exec_func_overlay EQU 2 ; overlay bit 15 <5> 16 <5> Exec0 STRUC 0 00000D12 ???? Exec0_environ DW ? ; seg addr of environment 0 00000D14 ???????? Exec0_com_line DD ? ; pointer to asciz command line 0 00000D18 ???????? Exec0_5C_FCB DD ? ; default fcb at 5C 0 00000D1C ???????? Exec0_6C_FCB DD ? ; default fcb at 6C 21 <5> Exec0 ENDS 22 <5> 23 <5> Exec1 STRUC 0 00000D12 ???? Exec1_environ DW ? ; seg addr of environment 0 00000D14 ???????? Exec1_com_line DD ? ; pointer to asciz command line 0 00000D18 ???????? Exec1_5C_FCB DD ? ; default fcb at 5C 0 00000D1C ???????? Exec1_6C_FCB DD ? ; default fcb at 6C 0 00000D20 ???? Exec1_SP DW ? ; stack pointer of program 0 00000D22 ???? Exec1_SS DW ? ; stack seg register of program 0 00000D24 ???? Exec1_IP DW ? ; entry point IP 0 00000D26 ???? Exec1_CS DW ? ; entry point CS 32 <5> Exec1 ENDS 33 <5> 34 <5> Exec3 STRUC 0 00000D12 ???? Exec3_load_addr DW ? ; seg address of load point 0 00000D14 ???? Exec3_reloc_fac DW ? ; relocation factor 37 <5> Exec3 ENDS 38 <5> 39 <5> ; 40 <5> ; Exit codes in upper byte 41 <5> ; 42 <5> Exit_terminate EQU 0 43 <5> Exit_abort EQU 0 44 <5> Exit_Ctrl_C EQU 1 45 <5> Exit_Hard_Error EQU 2 46 <5> Exit_Keep_process EQU 3 47 <5> 48 <5> ; 49 <5> ; EXE file header 50 <5> ; 51 <5> 52 <5> EXE_file STRUC 0 00000D12 ???? exe_signature DW ? ; must contain 4D5A (yay zibo!) 0 00000D14 ???? exe_len_mod_512 DW ? ; low 9 bits of length 0 00000D16 ???? exe_pages DW ? ; number of 512b pages in file 0 00000D18 ???? exe_rle_count DW ? ; count of reloc entries 0 00000D1A ???? exe_par_dir DW ? ; number of paragraphs before image 0 00000D1C ???? exe_min_BSS DW ? ; minimum number of para of BSS 0 00000D1E ???? exe_max_BSS DW ? ; max number of para of BSS 0 00000D20 ???? exe_SS DW ? ; stack of image 0 00000D22 ???? exe_SP DW ? ; SP of image 0 00000D24 ???? exe_chksum DW ? ; checksum of file (ignored) 0 00000D26 ???? exe_IP DW ? ; IP of entry 0 00000D28 ???? exe_CS DW ? ; CS of entry 0 00000D2A ???? exe_rle_table DW ? ; byte offset of reloc table 0 00000D2C ???? exe_iov DW ? ; overlay number (0 for root) 0 00000D2E ???????? exe_sym_tab DD ? ; offset of symbol table in file 68 <5> EXE_file ENDS 69 <5> 70 <5> exe_valid_signature EQU 5A4Dh 71 <5> exe_valid_old_signature EQU 4D5Ah 72 <5> 73 <5> symbol_entry STRUC 0 00000D12 ???????? sym_value DD ? 0 00000D16 ???? sym_type DW ? 0 00000D18 ?? sym_len DB ? 0 00000D19 ?????????????????? sym_name DB 255 dup (?) 77 00000010 ??????????????????- <5> 77 00000019 ??????????????????- <5> 77 00000022 ??????????????????- <5> 77 0000002B ??????????????????- <5> 77 00000034 ??????????????????- <5> 77 0000003D ??????????????????- <5> 77 00000046 ??????????????????- <5> 77 0000004F ??????????????????- <5> 77 00000058 ??????????????????- <5> 77 00000061 ??????????????????- <5> 77 0000006A ??????????????????- <5> 77 00000073 ??????????????????- <5> 77 0000007C ??????????????????- <5> 77 00000085 ??????????????????- <5> 77 0000008E ??????????????????- <5> 77 00000097 ??????????????????- <5> 77 000000A0 ??????????????????- <5> 77 000000A9 ??????????????????- <5> 77 000000B2 ??????????????????- <5> 77 000000BB ??????????????????- <5> 77 000000C4 ??????????????????- <5> 77 000000CD ??????????????????- <5> 77 000000D6 ??????????????????- <5> 77 000000DF ??????????????????- <5> 77 000000E8 ??????????????????- <5> 77 000000F1 ??????????????????- <5> 77 000000FA ??????????????????- <5> 77 00000103 ?????? <5> 78 <5> symbol_entry ENDS 156 <4> 157 <4> %include "sf.mac" 1 <5> ; SCCSID = @(#)sf.asm 1.1 85/04/10 2 <5> BREAK 3 <5> ; 4 <5> ; AN000 version 4.00 Jan. 1988 5 <5> ; AN003 PTM 3680 -- make NAME offset the same as before (<=3.30) 6 <5> ; AN009 PTM 3839 reorder SFT for MS WINDOWS 7 <5> 8 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 9 <5> ; C A V E A T P R O G R A M M E R ; 10 <5> ; ; 11 <5> ; 12 <5> ; system file table 13 <5> ; 14 <5> 15 <5> SF STRUC 0 00000D12 ???????? SFLink DD ? 0 00000D16 ???? SFCount DW ? ; number of entries 0 00000D18 ???? SFTable DW ? ; beginning of array of the following 19 <5> SF ENDS 20 <5> 21 <5> ; 22 <5> ; system file table entry 23 <5> ; 24 <5> 25 <5> sf_entry STRUC 0 00000D12 ???? sf_ref_count DW ? ; number of processes sharing entry 27 <5> ; if FCB then ref count 0 00000D14 ???? sf_mode DW ? ; mode of access or high bit on if FCB 0 00000D16 ?? sf_attr DB ? ; attribute of file 0 00000D17 ???? sf_flags DW ? ;Bits 8-15 31 <5> ; Bit 15 = 1 if remote file 32 <5> ; = 0 if local file or device 33 <5> ; Bit 14 = 1 if date/time is not to be 34 <5> ; set from clock at CLOSE. Set by 35 <5> ; FILETIMES and FCB_CLOSE. Reset by 36 <5> ; other reseters of the dirty bit 37 <5> ; (WRITE) 38 <5> ; Bit 13 = Pipe bit (reserved) 39 <5> ; 40 <5> ; Bits 0-7 (old FCB_devid bits) 41 <5> ; If remote file or local file, bit 42 <5> ; 6=0 if dirty Device ID number, bits 43 <5> ; 0-5 if local file. 44 <5> ; bit 7=0 for local file, bit 7 45 <5> ; =1 for local I/O device 46 <5> ; If local I/O device, bit 6=0 if EOF (input) 47 <5> ; Bit 5=1 if Raw mode 48 <5> ; Bit 0=1 if console input device 49 <5> ; Bit 1=1 if console output device 50 <5> ; Bit 2=1 if null device 51 <5> ; Bit 3=1 if clock device 0 00000D19 ???????? sf_devptr DD ? ; Points to DPB if local file, points 53 <5> ; to device header if local device, 54 <5> ; points to net device header if 55 <5> ; remote 0 00000D1D ???? sf_firclus DW ? ; First cluster of file (bit 15 = 0) 0 00000D1F ???? sf_time DW ? ; Time associated with file 0 00000D21 ???? sf_date DW ? ; Date associated with file 0 00000D23 ???????? sf_size DD ? ; Size associated with file 0 00000D27 ???????? sf_position DD ? ; Read/Write pointer or LRU count for FCBs 61 <5> ; 62 <5> ; Starting here, the next 7 bytes may be used by the file system to store an 63 <5> ; ID 64 <5> ; 0 00000D2B ???? sf_cluspos DW ? ; Position of last cluster accessed 0 00000D2D ???????? sf_dirsec DD ? ; Sector number of directory sector for 67 <5> ; for this file 0 00000D31 ?? sf_dirpos DB ? ; Offset of this entry in the above 69 <5> ; 70 <5> ; End of 7 bytes of file-system specific info. 71 <5> ; 0 00000D32 ?????????????????? sf_name DB 11 DUP (?) ; 11 character name that is in the 72 00000029 ???? <5> 73 <5> ; directory entry. This is used by 74 <5> ; close to detect file deleted and 75 <5> ; disk changed errors. 76 <5> 77 <5> ; SHARING INFO 0 00000D3D ???????? sf_chain DD ? ; link to next SF 0 00000D41 ???? sf_UID DW ? 0 00000D43 ???? sf_PID DW ? 0 00000D45 ???? sf_MFT DW ? 0 00000D47 ???? sf_lstclus DW ? ;AN009; Last cluster accessed 0 00000D49 ???????? sf_IFS_HDR DD ? 84 <5> sf_entry ENDS 85 <5> 86 <5> labelsize sf_fsda, byte, sf_cluspos ;DOS 4.00 87 <5> labelsize sf_serial_ID, word, sf_firclus ;DOS 4.00 88 <5> labelsize sf_netid, byte, sf_cluspos 89 <5> labelsize sf_OpenAge, word, sf_position+2 90 <5> labelsize sf_LRU, word, sf_position 91 <5> 92 <5> sf_default_number EQU 5h 93 <5> 94 <5> ; 95 <5> ; Note that we need to mark an SFT as being busy for OPEN/CREATE. This is 96 <5> ; because an INT 24 may prevent us from 'freeing' it. We mark this as such 97 <5> ; by placing a -1 in the ref_count field. 98 <5> ; 99 <5> 100 <5> sf_busy EQU -1 101 <5> 102 <5> 103 <5> ; mode mask for FCB detection 104 <5> sf_isfcb EQU 1000000000000000B 105 <5> 106 <5> ; Flag word masks 107 <5> sf_isnet EQU 1000000000000000B 108 <5> sf_close_nodate EQU 0100000000000000B 109 <5> sf_pipe EQU 0010000000000000B 110 <5> sf_no_inherit EQU 0001000000000000B 111 <5> sf_net_spool EQU 0000100000000000B 112 <5> Handle_Fail_I24 EQU 0000000100000000B ;BIT 8 - DISK FULL I24 ERROR 113 <5> 114 <5> ; Local file/device flag masks 115 <5> devid_file_clean EQU 40h ; true if file and not written 116 <5> devid_file_mask_drive EQU 3Fh ; mask for drive number 117 <5> 118 <5> devid_device EQU 80h ; true if a device 119 <5> devid_device_EOF EQU 40h ; true if end of file reached 120 <5> devid_device_raw EQU 20h ; true if in raw mode 121 <5> devid_device_special EQU 10h ; true if special device 122 <5> devid_device_clock EQU 08h ; true if clock device 123 <5> devid_device_null EQU 04h ; true if null device 124 <5> devid_device_con_out EQU 02h ; true if console output 125 <5> devid_device_con_in EQU 01h ; true if consle input 126 <5> ; ; 127 <5> ; C A V E A T P R O G R A M M E R ; 128 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 129 <5> 130 <5> ; 131 <5> ; structure of devid field as returned by IOCTL is: 132 <5> ; 133 <5> ; BIT 7 6 5 4 3 2 1 0 134 <5> ; |---|---|---|---|---|---|---|---| 135 <5> ; | I | E | R | S | I | I | I | I | 136 <5> ; | S | O | A | P | S | S | S | S | 137 <5> ; | D | F | W | E | C | N | C | C | 138 <5> ; | E | | | C | L | U | O | I | 139 <5> ; | V | | | L | K | L | T | N | 140 <5> ; |---|---|---|---|---|---|---|---| 141 <5> ; ISDEV = 1 if this channel is a device 142 <5> ; = 0 if this channel is a disk file 143 <5> ; 144 <5> ; If ISDEV = 1 145 <5> ; 146 <5> ; EOF = 0 if End Of File on input 147 <5> ; RAW = 1 if this device is in Raw mode 148 <5> ; = 0 if this device is cooked 149 <5> ; ISCLK = 1 if this device is the clock device 150 <5> ; ISNUL = 1 if this device is the null device 151 <5> ; ISCOT = 1 if this device is the console output 152 <5> ; ISCIN = 1 if this device is the console input 153 <5> ; 154 <5> ; If ISDEV = 0 155 <5> ; EOF = 0 if channel has been written 156 <5> ; Bits 0-5 are the block device number for 157 <5> ; the channel (0 = A, 1 = B, ...) 158 <5> ; 159 <5> devid_ISDEV EQU 80h 160 <5> devid_EOF EQU 40h 161 <5> devid_RAW EQU 20h 162 <5> devid_SPECIAL EQU 10H 163 <5> devid_ISCLK EQU 08h 164 <5> devid_ISNUL EQU 04h 165 <5> devid_ISCOT EQU 02h 166 <5> devid_ISCIN EQU 01h 167 <5> 168 <5> devid_block_dev EQU 1Fh ; mask for block device number 158 <4> 159 <4> %include "arena.mac" 1 <5> ; SCCSID = @(#)arena.asm 1.1 85/04/09 2 <5> ;BREAK 3 <5> 4 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <5> ; C A V E A T P R O G R A M M E R ; 6 <5> ; ; 7 <5> ; 8 <5> ; arena item 9 <5> ; 10 <5> arena STRUC 0 00000D12 ?? arena_signature DB ? ; 4D for valid item, 5A for last item 0 00000D13 ???? arena_owner DW ? ; owner of arena item 0 00000D15 ???? arena_size DW ? ; size in paragraphs of item 0 00000D17 ?????? arena_reserved DB 3 DUP(?) ; reserved 0 00000D1A ???????????????? arena_name DB 8 DUP(?) ; owner file name 16 <5> arena ENDS 17 <5> 18 <5> ; 19 <5> ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature 20 <5> ; and arena_owner_system are all equal to zero and are contained in DI. Change 21 <5> ; them and change ALLOC.ASM. 22 <5> 23 <5> arena_owner_system EQU 0 ; free block indication 24 <5> 25 <5> arena_signature_normal EQU 4Dh ; valid signature, not end of arena 26 <5> arena_signature_end EQU 5Ah ; valid signature, last block in arena 27 <5> ; ; 28 <5> ; C A V E A T P R O G R A M M E R ; 29 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 30 <5> 160 <4> 161 <4> %include "intnat.mac" 1 <5> ; SCCSID = @(#)intnat.asm 1.1 85/04/10 2 <5> BREAK 3 <5> 4 <5> ; 5 <5> ; Current structure of the data returned by the international call 6 <5> ; 7 <5> internat_block STRUC 0 00000D12 ???? Date_tim_format DW ? ; 0-USA, 1-EUR, 2-JAP 0 00000D14 ?? Currency_sym DB ? ; Currency Symbol 5 bytes 0 00000D15 ?? DB ? 0 00000D16 ?? DB ? 0 00000D17 ?? DB ? 0 00000D18 ?? DB ? 0 00000D19 ?? Thous_sep DB ? ; Thousands separator 2 bytes 0 00000D1A ?? DB ? 0 00000D1B ?? Decimal_sep DB ? ; Decimal separator 2 bytes 0 00000D1C ?? DB ? 0 00000D1D ?? Date_sep DB ? ; Date separator 2 bytes 0 00000D1E ?? DB ? 0 00000D1F ?? Time_sep DB ? ; Decimal separator 2 bytes 0 00000D20 ?? DB ? 0 00000D21 ?? Bit_field DB ? ; Bit values 23 <5> ; Bit 0 = 0 if currency symbol first 24 <5> ; = 1 if currency symbol last 25 <5> ; Bit 1 = 0 if No space after currency symbol 26 <5> ; = 1 if space after currency symbol 0 00000D22 ?? Currency_cents DB ? ; Number of places after currency dec point 0 00000D23 ?? Time_24 DB ? ; 1 if 24 hour time, 0 if 12 hour time 0 00000D24 ???? Map_call DW ? ; Address of case mapping call (DWORD) 0 00000D26 ???? DW ? ; THIS IS TWO WORDS SO IT CAN BE INITIALIZED 31 <5> ; in pieces. 0 00000D28 ?? Data_sep DB ? ; Data list separator character 0 00000D29 ?? DB ? 34 <5> internat_block ENDS 35 <5> 36 <5> ; 37 <5> ; Max size of the block returned by the INTERNATIONAL call 38 <5> ; 39 <5> internat_block_max EQU 32 162 <4> 163 <4> %include "mi.mac" 1 <5> ; SCCSID = @(#)mi.asm 1.1 85/04/10 2 <5> BREAK 3 <5> 4 <5> mi_INT EQU 0CDh 5 <5> mi_Long_JMP EQU 0EAh 6 <5> mi_Long_CALL EQU 09Ah 7 <5> mi_Long_RET EQU 0CBh 8 <5> mi_Near_RET EQU 0C3h 9 <5> 10 <5> ; xxxxoditszxaxpxc 11 <5> f_Overflow EQU 0000100000000000B 12 <5> f_Direction EQU 0000010000000000B 13 <5> f_Interrupt EQU 0000001000000000B 14 <5> f_Trace EQU 0000000100000000B 15 <5> f_Sign EQU 0000000010000000B 16 <5> f_Zero EQU 0000000001000000B 17 <5> f_Aux EQU 0000000000010000B 18 <5> f_Parity EQU 0000000000000100B 19 <5> f_Carry EQU 0000000000000001B 164 <4> 165 <4> fChk equ 1 166 <4> fDelim equ 2 167 <4> fSpChk equ 4 168 <4> fFCB equ 8 169 <4> 170 <4> %include "filemode.mac" 1 <5> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 3 <5> BREAK 4 <5> 5 <5> stdin EQU 0 6 <5> stdout EQU 1 7 <5> stderr EQU 2 8 <5> stdaux EQU 3 9 <5> stdprn EQU 4 10 <5> 11 <5> BREAK 12 <5> 13 <5> access_mask EQU 0FH 14 <5> open_for_read EQU 00h 15 <5> open_for_write EQU 01h 16 <5> open_for_both EQU 02h 17 <5> 18 <5> sharing_mask EQU 0F0H 19 <5> sharing_compat EQU 000H 20 <5> sharing_deny_both EQU 010H 21 <5> sharing_deny_write EQU 020H 22 <5> sharing_deny_read EQU 030H 23 <5> sharing_deny_none EQU 040H 24 <5> sharing_net_FCB EQU 070h 25 <5> sharing_no_inherit EQU 080H 26 <5> 27 <5> BREAK 28 <5> 29 <5> no_code_page_check EQU 0100H 30 <5> int_24_error EQU 2000H 31 <5> auto_commit_write EQU 4000H 32 <5> ext_open_on EQU 01H 33 <5> ext_file_not_exists EQU 04H 34 <5> ext_open_I24_off EQU 02H 35 <5> io_mode_id EQU 00000010B 36 <5> reserved_bits_mask EQU 0FE00H 37 <5> exists_mask EQU 0FH 38 <5> not_exists_mask EQU 0F0H 39 <5> action_opened EQU 01H 40 <5> action_created_opened EQU 02H 41 <5> action_replaced_opened EQU 03H 42 <5> 43 <5> ext_exists_open EQU 01H 44 <5> ext_exists_fail EQU 0H 45 <5> ext_nexists_create EQU 10H 46 <5> 47 <5> 48 <5> 49 <5> ext_open_parm struc 0 00000D12 ???????? ext_set_list dd ? 0 00000D16 ???? ext_num_of_parm dw ? 52 <5> ext_open_parm ends 53 <5> 54 <5> 55 <5> 171 <4> 172 <4> %include "error.mac" 1 <5> ; SCCSID = @(#)error.asm 1.1 85/04/10 2 <5> ; SCCSID = @(#)error.asm 1.1 85/04/10 3 <5> BREAK 4 <5> 5 <5> ; 6 <5> ; XENIX calls all return error codes through AX. If an error occurred then 7 <5> ; the carry bit will be set and the error code is in AX. If no error occurred 8 <5> ; then the carry bit is reset and AX contains returned info. 9 <5> ; 10 <5> ; Since the set of error codes is being extended as we extend the operating 11 <5> ; system, we have provided a means for applications to ask the system for a 12 <5> ; recommended course of action when they receive an error. 13 <5> ; 14 <5> ; The GetExtendedError system call returns a universal error, an error 15 <5> ; location and a recommended course of action. The universal error code is 16 <5> ; a symptom of the error REGARDLESS of the context in which GetExtendedError 17 <5> ; is issued. 18 <5> ; 19 <5> 20 <5> ; 21 <5> ; These are the 2.0 error codes 22 <5> ; 23 <5> error_invalid_function EQU 1 24 <5> error_file_not_found EQU 2 25 <5> error_path_not_found EQU 3 26 <5> error_too_many_open_files EQU 4 27 <5> error_access_denied EQU 5 28 <5> error_invalid_handle EQU 6 29 <5> error_arena_trashed EQU 7 30 <5> error_not_enough_memory EQU 8 31 <5> error_invalid_block EQU 9 32 <5> error_bad_environment EQU 10 33 <5> error_bad_format EQU 11 34 <5> error_invalid_access EQU 12 35 <5> error_invalid_data EQU 13 36 <5> ;**** reserved EQU 14 ; ***** 37 <5> error_invalid_drive EQU 15 38 <5> error_current_directory EQU 16 39 <5> error_not_same_device EQU 17 40 <5> error_no_more_files EQU 18 41 <5> ; 42 <5> ; These are the universal int 24 mappings for the old INT 24 set of errors 43 <5> ; 44 <5> error_write_protect EQU 19 45 <5> error_bad_unit EQU 20 46 <5> error_not_ready EQU 21 47 <5> error_bad_command EQU 22 48 <5> error_CRC EQU 23 49 <5> error_bad_length EQU 24 50 <5> error_Seek EQU 25 51 <5> error_not_DOS_disk EQU 26 52 <5> error_sector_not_found EQU 27 53 <5> error_out_of_paper EQU 28 54 <5> error_write_fault EQU 29 55 <5> error_read_fault EQU 30 56 <5> error_gen_failure EQU 31 57 <5> ; 58 <5> ; These are the new 3.0 error codes reported through INT 24 59 <5> ; 60 <5> error_sharing_violation EQU 32 61 <5> error_lock_violation EQU 33 62 <5> error_wrong_disk EQU 34 63 <5> error_FCB_unavailable EQU 35 64 <5> error_sharing_buffer_exceeded EQU 36 65 <5> error_Code_Page_Mismatched EQU 37 ; DOS 4.00 ;AN000; 66 <5> error_handle_EOF EQU 38 ; DOS 4.00 ;AN000; 67 <5> error_handle_Disk_Full EQU 39 ; DOS 4.00 ;AN000; 68 <5> ; 69 <5> ; New OEM network-related errors are 50-79 70 <5> ; 71 <5> error_not_supported EQU 50 72 <5> ; 73 <5> ; End of INT 24 reportable errors 74 <5> ; 75 <5> error_file_exists EQU 80 76 <5> error_DUP_FCB EQU 81 ; ***** 77 <5> error_cannot_make EQU 82 78 <5> error_FAIL_I24 EQU 83 79 <5> ; 80 <5> ; New 3.0 network related error codes 81 <5> ; 82 <5> error_out_of_structures EQU 84 83 <5> error_Already_assigned EQU 85 84 <5> error_invalid_password EQU 86 85 <5> error_invalid_parameter EQU 87 86 <5> error_NET_write_fault EQU 88 87 <5> error_sys_comp_not_loaded EQU 90 ; DOS 4.00 ;AN000; 88 <5> 89 <5> BREAK 90 <5> 91 <5> error_I24_write_protect EQU 0 92 <5> error_I24_bad_unit EQU 1 93 <5> error_I24_not_ready EQU 2 94 <5> error_I24_bad_command EQU 3 95 <5> error_I24_CRC EQU 4 96 <5> error_I24_bad_length EQU 5 97 <5> error_I24_Seek EQU 6 98 <5> error_I24_not_DOS_disk EQU 7 99 <5> error_I24_sector_not_found EQU 8 100 <5> error_I24_out_of_paper EQU 9 101 <5> error_I24_write_fault EQU 0Ah 102 <5> error_I24_read_fault EQU 0Bh 103 <5> error_I24_gen_failure EQU 0Ch 104 <5> ; NOTE: Code 0DH is used by MT-DOS. 105 <5> error_I24_wrong_disk EQU 0Fh 106 <5> 107 <5> ; THE FOLLOWING ARE MASKS FOR THE AH REGISTER ON Int 24 108 <5> 109 <5> Allowed_FAIL EQU 00001000B 110 <5> Allowed_RETRY EQU 00010000B 111 <5> Allowed_IGNORE EQU 00100000B 112 <5> ;NOTE: ABORT is ALWAYS allowed 113 <5> 114 <5> I24_operation EQU 00000001B ;Z if READ,NZ if Write 115 <5> I24_area EQU 00000110B ; 00 if DOS 116 <5> ; 01 if FAT 117 <5> ; 10 if root DIR 118 <5> ; 11 if DATA 119 <5> I24_class EQU 10000000B ;Z if DISK, NZ if FAT or char 120 <5> 121 <5> BREAK 122 <5> 123 <5> ; Values for error CLASS 124 <5> 125 <5> errCLASS_OutRes EQU 1 ; Out of Resource 126 <5> errCLASS_TempSit EQU 2 ; Temporary Situation 127 <5> errCLASS_Auth EQU 3 ; Permission problem 128 <5> errCLASS_Intrn EQU 4 ; Internal System Error 129 <5> errCLASS_HrdFail EQU 5 ; Hardware Failure 130 <5> errCLASS_SysFail EQU 6 ; System Failure 131 <5> errCLASS_Apperr EQU 7 ; Application Error 132 <5> errCLASS_NotFnd EQU 8 ; Not Found 133 <5> errCLASS_BadFmt EQU 9 ; Bad Format 134 <5> errCLASS_Locked EQU 10 ; Locked 135 <5> errCLASS_Media EQU 11 ; Media Failure 136 <5> errCLASS_Already EQU 12 ; Collision with Existing Item 137 <5> errCLASS_Unk EQU 13 ; Unknown/other 138 <5> 139 <5> ; Values for error ACTION 140 <5> 141 <5> errACT_Retry EQU 1 ; Retry 142 <5> errACT_DlyRet EQU 2 ; Delay Retry, retry after pause 143 <5> errACT_User EQU 3 ; Ask user to regive info 144 <5> errACT_Abort EQU 4 ; abort with clean up 145 <5> errACT_Panic EQU 5 ; abort immediately 146 <5> errACT_Ignore EQU 6 ; ignore 147 <5> errACT_IntRet EQU 7 ; Retry after User Intervention 148 <5> 149 <5> ; Values for error LOCUS 150 <5> 151 <5> errLOC_Unk EQU 1 ; No appropriate value 152 <5> errLOC_Disk EQU 2 ; Random Access Mass Storage 153 <5> errLOC_Net EQU 3 ; Network 154 <5> errLOC_SerDev EQU 4 ; Serial Device 155 <5> errLOC_Mem EQU 5 ; Memory 173 <4> 174 <4> %include "syscall.mac" 1 <5> ; SCCSID = @(#)syscall.asm 1.1 85/04/10 2 <5> ;BREAK 3 <5> ;SUBTTL system call definitions 4 <5> ;PAGE 5 <5> 6 <5> Abort EQU 0 ; 0 0 7 <5> Std_Con_Input EQU 1 ; 1 1 8 <5> Std_Con_Output EQU 2 ; 2 2 9 <5> Std_Aux_Input EQU 3 ; 3 3 10 <5> Std_Aux_Output EQU 4 ; 4 4 11 <5> Std_Printer_Output EQU 5 ; 5 5 12 <5> Raw_Con_IO EQU 6 ; 6 6 13 <5> Raw_Con_Input EQU 7 ; 7 7 14 <5> Std_Con_Input_No_Echo EQU 8 ; 8 8 15 <5> Std_Con_String_Output EQU 9 ; 9 9 16 <5> Std_Con_String_Input EQU 10 ; 10 A 17 <5> Std_Con_Input_Status EQU 11 ; 11 B 18 <5> Std_Con_Input_Flush EQU 12 ; 12 C 19 <5> Disk_Reset EQU 13 ; 13 D 20 <5> Set_Default_Drive EQU 14 ; 14 E 21 <5> FCB_Open EQU 15 ; 15 F 22 <5> FCB_Close EQU 16 ; 16 10 23 <5> Dir_Search_First EQU 17 ; 17 11 24 <5> Dir_Search_Next EQU 18 ; 18 12 25 <5> FCB_Delete EQU 19 ; 19 13 26 <5> FCB_Seq_Read EQU 20 ; 20 14 27 <5> FCB_Seq_Write EQU 21 ; 21 15 28 <5> FCB_Create EQU 22 ; 22 16 29 <5> FCB_Rename EQU 23 ; 23 17 30 <5> Get_Default_Drive EQU 25 ; 25 19 31 <5> Set_DMA EQU 26 ; 26 1A 32 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <5> ; C A V E A T P R O G R A M M E R ; 34 <5> ; ; 35 <5> Get_Default_DPB EQU 31 ; 31 1F 36 <5> ; ; 37 <5> ; C A V E A T P R O G R A M M E R ; 38 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 39 <5> FCB_Random_Read EQU 33 ; 33 21 40 <5> FCB_Random_Write EQU 34 ; 34 22 41 <5> Get_FCB_File_Length EQU 35 ; 35 23 42 <5> Get_FCB_Position EQU 36 ; 36 24 43 <5> Set_Interrupt_Vector EQU 37 ; 37 25 44 <5> Create_Process_Data_Block EQU 38 ; 38 26 45 <5> FCB_Random_Read_Block EQU 39 ; 39 27 46 <5> FCB_Random_Write_Block EQU 40 ; 40 28 47 <5> Parse_File_Descriptor EQU 41 ; 41 29 48 <5> Get_Date EQU 42 ; 42 2A 49 <5> Set_Date EQU 43 ; 43 2B 50 <5> Get_Time EQU 44 ; 44 2C 51 <5> Set_Time EQU 45 ; 45 2D 52 <5> Set_Verify_On_Write EQU 46 ; 46 2E 53 <5> ; Extended functionality group 54 <5> Get_DMA EQU 47 ; 47 2F 55 <5> Get_Version EQU 48 ; 48 30 56 <5> Keep_Process EQU 49 ; 49 31 57 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <5> ; C A V E A T P R O G R A M M E R ; 59 <5> ; ; 60 <5> Get_DPB EQU 50 ; 50 32 61 <5> ; ; 62 <5> ; C A V E A T P R O G R A M M E R ; 63 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 64 <5> Set_CTRL_C_Trapping EQU 51 ; 51 33 65 <5> Get_InDOS_Flag EQU 52 ; 52 34 66 <5> Get_Interrupt_Vector EQU 53 ; 53 35 67 <5> Get_Drive_Freespace EQU 54 ; 54 36 68 <5> Char_Oper EQU 55 ; 55 37 69 <5> International EQU 56 ; 56 38 70 <5> ; Directory Group 71 <5> MKDir EQU 57 ; 57 39 72 <5> RMDir EQU 58 ; 58 3A 73 <5> CHDir EQU 59 ; 59 3B 74 <5> ; File Group 75 <5> Creat EQU 60 ; 60 3C 76 <5> Open EQU 61 ; 61 3D 77 <5> Close EQU 62 ; 62 3E 78 <5> Read EQU 63 ; 63 3F 79 <5> Write EQU 64 ; 64 40 80 <5> Unlink EQU 65 ; 65 41 81 <5> LSeek EQU 66 ; 66 42 82 <5> CHMod EQU 67 ; 67 43 83 <5> IOCtl EQU 68 ; 68 44 84 <5> XDup EQU 69 ; 69 45 85 <5> XDup2 EQU 70 ; 70 46 86 <5> Current_Dir EQU 71 ; 71 47 87 <5> ; Memory Group 88 <5> Alloc EQU 72 ; 72 48 89 <5> Dealloc EQU 73 ; 73 49 90 <5> Setblock EQU 74 ; 74 4A 91 <5> ; Process Group 92 <5> Exec EQU 75 ; 75 4B 93 <5> Exit EQU 76 ; 76 4C 94 <5> WaitProcess EQU 77 ; 77 4D 95 <5> Find_First EQU 78 ; 78 4E 96 <5> ; Special Group 97 <5> Find_Next EQU 79 ; 79 4F 98 <5> ; SPECIAL SYSTEM GROUP 99 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 100 <5> ; C A V E A T P R O G R A M M E R ; 101 <5> ; ; 102 <5> Set_Current_PDB EQU 80 ; 80 50 103 <5> Get_Current_PDB EQU 81 ; 81 51 104 <5> Get_In_Vars EQU 82 ; 82 52 105 <5> SetDPB EQU 83 ; 83 53 106 <5> ; ; 107 <5> ; C A V E A T P R O G R A M M E R ; 108 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 109 <5> Get_Verify_On_Write EQU 84 ; 84 54 110 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 111 <5> ; C A V E A T P R O G R A M M E R ; 112 <5> ; ; 113 <5> Dup_PDB EQU 85 ; 85 55 114 <5> ; ; 115 <5> ; C A V E A T P R O G R A M M E R ; 116 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 117 <5> Rename EQU 86 ; 86 56 118 <5> File_Times EQU 87 ; 87 57 119 <5> AllocOper EQU 88 ; 88 58 120 <5> ; Network extention system calls 121 <5> GetExtendedError EQU 89 ; 89 59 122 <5> CreateTempFile EQU 90 ; 90 5A 123 <5> CreateNewFile EQU 91 ; 91 5B 124 <5> LockOper EQU 92 ; 92 5C Lock and Unlock 125 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 126 <5> ; C A V E A T P R O G R A M M E R ; 127 <5> ; ; 128 <5> ServerCall EQU 93 ; 93 5D CommitAll, ServerDOSCall, 129 <5> ; CloseByName, CloseUser, 130 <5> ; CloseUserProcess, 131 <5> ; GetOpenFileList 132 <5> ; ; 133 <5> ; C A V E A T P R O G R A M M E R ; 134 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 135 <5> UserOper EQU 94 ; 94 5E Get and Set 136 <5> AssignOper EQU 95 ; 95 5F On, Off, Get, Set, Cancel 137 <5> xNameTrans EQU 96 ; 96 60 138 <5> PathParse EQU 97 ; 97 61 139 <5> GetCurrentPSP EQU 98 ; 98 62 140 <5> Hongeul EQU 99 ; 99 63 141 <5> ECS_CALL EQU 99 ; 99 63 ;; DBCS support 142 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 143 <5> ; C A V E A T P R O G R A M M E R ; 144 <5> ; ; 145 <5> Set_Printer_Flag EQU 100 ; 100 64 146 <5> ; ; 147 <5> ; C A V E A T P R O G R A M M E R ; 148 <5> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 149 <5> GetExtCntry EQU 101 ; 101 65 150 <5> GetSetCdPg EQU 102 ; 102 66 151 <5> ExtHandle EQU 103 ; 103 67 152 <5> Commit EQU 104 ; 104 68 153 <5> GetSetMediaID EQU 105 ; 105 69 154 <5> IFS_IOCTL EQU 107 ; 107 6B 155 <5> ExtOpen EQU 108 ; 108 6C 156 <5> ; 157 <5> ; 158 <5> Set_Oem_Handler EQU 248 ; 248 F8 159 <5> OEM_C1 EQU 249 ; 249 F9 160 <5> OEM_C2 EQU 250 ; 250 FA 161 <5> OEM_C3 EQU 251 ; 251 FB 162 <5> OEM_C4 EQU 252 ; 252 FC 163 <5> OEM_C5 EQU 253 ; 253 FD 164 <5> OEM_C6 EQU 254 ; 254 FE 165 <5> OEM_C7 EQU 255 ; 255 FF 175 <4> 176 <4> ;SUBTTL 177 <4> 124 <3> %include "devsym.mac" 1 <4> %warning out: DEVSYM.INC... 1 ****************** <4> warning: out: DEVSYM.INC... [-w+user] 2 <4> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <4> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <4> 5 <4> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <4> SYSDEV STRUC 0 00000D12 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00000D16 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00000D18 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 00000D1A ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 00000D1C ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <4> SYSDEV ENDS 13 <4> 14 <4> ; 15 <4> ; ATTRIBUTE BIT MASKS 16 <4> ; 17 <4> ; CHARACTER DEVICES: 18 <4> ; 19 <4> ; BIT 15 -> MUST BE 1 20 <4> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <4> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <4> ; 12 -> UNUSED 23 <4> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <4> ; 10 -> MUST BE 0 25 <4> ; 9 -> MUST BE 0 26 <4> ; 8 -> UNUSED 27 <4> ; 7 -> UNUSED 28 <4> ; 6 -> UNUSED 29 <4> ; 5 -> UNUSED 30 <4> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <4> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <4> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <4> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <4> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <4> ; 36 <4> ; BLOCK DEVICES: 37 <4> ; 38 <4> ; BIT 15 -> MUST BE 0 39 <4> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <4> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <4> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <4> ; THE SAME PLACE. 43 <4> ; 12 -> UNUSED 44 <4> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <4> ; 10 -> MUST BE 0 46 <4> ; 9 -> MUST BE 0 47 <4> ; 8 -> UNUSED 48 <4> ; 7 -> UNUSED 49 <4> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <4> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <4> ; 5 -> UNUSED 52 <4> ; 4 -> UNUSED 53 <4> ; 3 -> UNUSED 54 <4> ; 2 -> UNUSED 55 <4> ; 1 -> UNUSED 56 <4> ; 0 -> UNUSED 57 <4> ; 58 <4> 59 <4> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <4> CHARDEV EQU 8000H 61 <4> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <4> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <4> ; COMP MEDIA. 64 <4> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <4> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <4> ; NOT. CURRENTLY BLOCK ONLY. 67 <4> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <4> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <4> ; ENTRY POINTS, 0 IF NOT 70 <4> 71 <4> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <4> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <4> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <4> ; ITS CURRENT FORM. 75 <4> 76 <4> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <4> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <4> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <4> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <4> 81 <4> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <4> ;DEVICE SUPPORTS SET/GET MAP OF 83 <4> ;LOGICAL DRIVES, AND SUPPORTS 84 <4> ;GENERIC IOCTL CALLS. 85 <4> ;FOR CHARACTER DEVICES, THIS 86 <4> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <4> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <4> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <4> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <4> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <4> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <4> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <4> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <4> 95 <4> ;STATIC REQUEST HEADER 96 <4> SRHEAD STRUC 0 00000D12 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00000D13 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00000D14 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00000D15 ???? REQSTAT DW ? ;STATUS WORD 0 00000D17 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <4> SRHEAD ENDS 103 <4> 104 <4> ;STATUS WORD MASKS 105 <4> STERR EQU 8000H ;BIT 15 - ERROR 106 <4> STBUI EQU 0200H ;BIT 9 - BUISY 107 <4> STDON EQU 0100H ;BIT 8 - DONE 108 <4> STECODE EQU 00FFH ;ERROR CODE 109 <4> ; 2/12/KK 110 <4> ; Interim character identifier 2/12/KK 111 <4> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <4> 113 <4> ;FUNCTION CODES 114 <4> DEVINIT EQU 0 ;INITIALIZATION 115 <4> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <4> DEVMDCH EQU 1 ;MEDIA CHECK 117 <4> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <4> DEVBPB EQU 2 ;GET BPB 119 <4> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <4> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <4> DEVRD EQU 4 ;READ 122 <4> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <4> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <4> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <4> DEVIST EQU 6 ;INPUT STATUS 126 <4> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <4> DEVIFL EQU 7 ;INPUT FLUSH 128 <4> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <4> DEVWRT EQU 8 ;WRITE 130 <4> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <4> DEVOST EQU 10 ;OUTPUT STATUS 132 <4> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <4> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <4> DEVOPN EQU 13 ;DEVICE OPEN 135 <4> DEVCLS EQU 14 ;DEVICE CLOSE 136 <4> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <4> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <4> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <4> GENIOCTL EQU 19 140 <4> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <4> ; 20 142 <4> ; 21 143 <4> ; 22 144 <4> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <4> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <4> QUERYGENIOCTL equ 25 ; query generic IOCTL support (MS-DOS v5+) 147 <4> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 148 <4> 149 <4> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 150 <4> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 151 <4> 152 <4> ; GENERIC IOCTL REQUEST STRUCTURE 153 <4> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 154 <4> ; 155 <4> IOCTL_REQ STRUC 0 00000D12 ?????????????????? DB (SRHEAD_struc_size) DUP(?) 156 00000009 ???????? <4> 157 <4> ; GENERIC IOCTL ADDITION. 0 00000D1F ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 00000D20 ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 00000D21 ???? REG_SI DW ? 0 00000D23 ???? REG_DI DW ? 0 00000D25 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 163 <4> IOCTL_REQ ENDS 164 <4> 165 <4> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 166 <4> GEN_IOCTL_WRT_TRK EQU 40H 167 <4> GEN_IOCTL_RD_TRK EQU 60H 168 <4> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 169 <4> 170 <4> ;; 32-bit absolute read/write input list structure 171 <4> 172 <4> ABS_32RW STRUC 0 00000D12 ???????? SECTOR_RBA DD ? ; relative block address 0 00000D16 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00000D18 ???????? BUFFER_ADDR DD ? ; data addrress 176 <4> ABS_32RW ENDS 177 <4> 178 <4> ;; media ID info 179 <4> 180 <4> MEDIA_ID_INFO STRUC 0 00000D12 ???? MEDIA_level DW ? ; info level 0 00000D14 ???????? MEDIA_Serial DD ? ; serial # 0 00000D18 ?????????????????? MEDIA_Label DB 11 dup (?) ;volume label 183 0000000F ???? <4> 0 00000D23 ???????????????? MEDIA_System DB 8 dup (?) ;system type 185 <4> MEDIA_ID_INFO ENDS 186 <4> 187 <4> ;; equates for DOS34_FLAG 188 <4> 189 <4> IFS_ABSRW EQU 00001H ;IFS absolute read/write 190 <4> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 191 <4> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 192 <4> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 193 <4> FROM_DISK_RESET EQU 00004H ;from disk reset 194 <4> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 195 <4> From_String_Output EQU 00008H ;from con string output 196 <4> NO_From_String_Output EQU 0FFF7H ;not from con string output 197 <4> From_DOS_WRITE EQU 00010H ;from dos_write 198 <4> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 199 <4> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 200 <4> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 201 <4> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 202 <4> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 203 <4> DBCS_VOLID EQU 00080H ;indicate from volume id 204 <4> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 205 <4> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 206 <4> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 207 <4> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 208 <4> X25_special EQU 00800H ;flag for X25 driver 125 <3> [list +] 126 <3> 127 <3> %ifndef Installed 128 <3> %iassign Installed 0 129 <3> %endif 130 <3> === Switch to base=001DC0h -> "DOSSTARTJUMP" 131 <3> section DOSSTARTJUMP 132 <3> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 133 <3> 134 <3> %ifndef DONOBITS 135 <3> JMP near ptr DOSINIT 136 <3> %else ; DONOBITS 0 00000000 ?????? db ?,?,? 138 <3> %endif ; DONOBITS 139 <3> 140 <3> ; (no prior section) ; DOSSTARTJUMP ENDS 141 <3> === Switch to base=001DC0h -> "LAST" 142 <3> section LAST 143 <3> Extrn DOSINIT:NEAR 144 <3> ; (no prior section) ; LAST ENDS 145 <3> 7 <2> ;=== Pop trace listing source 8 <2> %include "version.mac" 1 <3> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <3> TRUE EQU 0FFFFh 3 <3> TRUEBYTE EQU 0FFh 4 <3> FALSE EQU 0 5 <3> 6 <3> ; 7 <3> ; Use the following switches to control cmacros.inc 8 <3> ; 9 <3> ?PLM equ 0 10 <3> ?WIN equ 0 11 <3> 12 <3> memS EQU 1 ; Small model 13 <3> ; 14 <3> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <3> ; version of the operating system 16 <3> ; 17 <3> ; The below chart will indicate how to set the switches to build the various 18 <3> ; versions 19 <3> ; 20 <3> ; IBMVER IBMCOPYRIGHT 21 <3> ; -------------------------------------------------------- 22 <3> ; IBM Version | TRUE TRUE 23 <3> ; -------------------------------------------------------- 24 <3> ; MS Version | FALSE FALSE 25 <3> ; -------------------------------------------------------- 26 <3> ; Clone Version | TRUE FALSE 27 <3> ; 28 <3> IBMVER EQU TRUE 29 <3> IBMCOPYRIGHT EQU FALSE 30 <3> 31 <3> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <3> 33 <3> %ifndef MSVER 34 <3> MSVER EQU ~ IBMVER 35 <3> %endif 36 <3> IBM EQU IBMVER 37 <3> ; 38 <3> ; 39 <3> %IF IBMVER 40 <3> %IF IBMCOPYRIGHT 41 <3> %warning out: ... IBM version build switch on ... 42 <3> %ELSE 43 <3> %warning out: ... CLONE version build switch on ... 43 ****************** <3> warning: out: ... CLONE version build switch on ... [-w+user] 44 <3> %ENDIF 45 <3> %ELSE 46 <3> %IFN IBMCOPYRIGHT 47 <3> %warning out: ... MS version build switch on ... 48 <3> %ELSE 49 <3> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <3> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <3> %ENDIF 52 <3> %ENDIF 53 <3> ; 54 <3> ; 55 <3> ;*************************************************************************** 56 <3> ;* The following switches are for DBCS or SBCS support * 57 <3> ;* * 58 <3> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <3> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <3> ;* * 61 <3> ;*************************************************************************** 62 <3> ; 63 <3> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <3> 65 <3> ; 66 <3> ; Switch INTERNAT for DBCS support 67 <3> ; 68 <3> INTERNAT EQU FALSE 69 <3> ; 70 <3> %IF INTERNAT 71 <3> %ifndef KANJI 72 <3> KANJI EQU TRUE 73 <3> %endif 74 <3> IBMJAPAN EQU TRUE 75 <3> %ELSE 76 <3> %ifndef KANJI 77 <3> KANJI EQU FALSE 78 <3> %endif 79 <3> IBMJAPAN EQU FALSE 80 <3> %ENDIF 81 <3> 82 <3> %ifndef altvect ; avoid jerking off vector.inc 83 <3> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <3> %endif 85 <3> 86 <3> ; 87 <3> ; Country code switches 88 <3> ; The default contry code is assumed as USA. 89 <3> ; 90 <3> %IF INTERNAT 91 <3> KOREA EQU TRUE 92 <3> JAPAN EQU FALSE 93 <3> %ELSE 94 <3> KOREA EQU FALSE 95 <3> JAPAN EQU FALSE 96 <3> %ENDIF 97 <3> ; 98 <3> %IF INTERNAT 99 <3> %warning out: Internat(ECS) version build switch on 100 <3> %ENDIF 9 <2> %include "lmacros1.mac" 1 <3> [list -] 10 <2> %include "entryseg.nas" 1 <3> 2 <3> %ifndef ENTRYSEGNAS 3 <3> %define ENTRYSEGNAS 1 4 <3> 5 <3> %include "lmacros3.mac" 6 <3> === Switch to base=003490h -> "DOSENTRY" 7 <3> addsection DOSENTRY, class=%[DOSENTRY] 8 <3> 9 <3> group DOSENTRYGROUP DOSENTRY 10 <3> 11 <3> %endif 11 <2> 12 <2> extern okcallentry, badcallentry 13 <2> === Switch to base=003490h -> "DOSCODECODE" 14 <2> section DOSCODECODE 15 <2> Extrn LeaveDOS:NEAR 16 <2> Extrn BadCall:FAR, OKCall:FAR 17 <2> ; (no prior section) ; DOSCODECODE ENDS 18 <2> === Switch to base=001DC0h -> "LAST" 19 <2> section LAST 20 <2> extrn SYSBUF:byte 21 <2> ; (no prior section) ; LAST ENDS 22 <2> 23 <2> Break 24 <2> 25 <2> ; 26 <2> ; We need to identify the parts of the data area that are relevant to tasks 27 <2> ; and those that are relevant to the system as a whole. Under 3.0, the system 28 <2> ; data will be gathered with the system code. The process data under 2.x will 29 <2> ; be available for swapping and under 3.0 it will be allocated per-process. 30 <2> ; 31 <2> ; The data that is system data will be identified by [SYSTEM] in the comments 32 <2> ; describing that data item. 33 <2> ; 34 <2> 35 <2> %ifndef Kanji 36 <2> %iassign Kanji 0 37 <2> %endif 38 <2> %ifndef Debug 39 <2> %iassign Debug 0 40 <2> %endif 41 <2> %ifndef Redirector 42 <2> %iassign Redirector 0 43 <2> %endif 44 <2> %ifndef ShareF 45 <2> %iassign ShareF 0 46 <2> %endif 47 <2> === Switch to base=003490h -> "DOSENTRY" 48 <2> section DOSENTRY 49 <2> extern ifsentry 50 <2> === Switch to base=001DC0h -> "CONSTANTS" 51 <2> section CONSTANTS 52 <2> 53 <2> extrn sfTabl:DWORD 54 <2> 55 <2> ;ORG 0 56 <2> 57 <2> EVEN 58 <2> ; 59 <2> ; WANGO!!! The following word is used by SHARE and REDIR to determin data 60 <2> ; area compatability. This location must be incremented EACH TIME the data 61 <2> ; area here gets mucked with. 62 <2> ; 63 <2> ; Also, do NOT change this position relative to 0. wrt DOSGROUP 64 <2> ; 65 <2> Public MSCT001S,MSCT001E 66 <2> MSCT001S: 0 00000004 ???? I_am DataVersion,WORD,<1> ;AC000; [SYSTEM] version number for DOS DATA 68 <2> 69 <2> %warning "out: WARNING!!! Debug fields are being included!!!" 69 ****************** <2> warning: out: WARNING!!! Debug fields are being included!!! [-w+user] 0 00000006 ???????? DB "BUG " ; THIS FIELD MUST BE EVEN # OF BYTES 70 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 0 0000000A ???? I_am BugTyp,WORD,<0> 0 0000000C ???? I_am BugLev,WORD,<0> 73 <2> %include "bugtyp.nas" 1 <3> ; SCCSID = @(#)bugtyp.asm 1.1 85/04/09 2 <3> ; 3 <3> ; debugging types and levels for MSDOS 4 <3> ; 5 <3> 6 <3> TypAccess EQU 0001h 7 <3> LevSFN EQU 0000h 8 <3> LevBUSY EQU 0001h 9 <3> 10 <3> TypShare EQU 0002h 11 <3> LevShEntry EQU 0000h 12 <3> LevMFTSrch EQU 0001h 13 <3> 14 <3> TypSect EQU 0004h 15 <3> LevEnter EQU 0000h 16 <3> LevLeave EQU 0001h 17 <3> LevReq EQU 0002h 18 <3> 19 <3> TypSMB EQU 0008h 20 <3> LevSMBin EQU 0000h 21 <3> LevSMBout EQU 0001h 22 <3> LevParm EQU 0002h 23 <3> LevASCIZ EQU 0003h 24 <3> LevSDB EQU 0004h 25 <3> LevVarlen EQU 0005h 26 <3> 27 <3> TypNCB EQU 0010h 28 <3> LevNCBin EQU 0000h 29 <3> LevNCBout EQU 0001h 30 <3> 31 <3> TypSeg EQU 0020h 32 <3> LevAll EQU 0000h 33 <3> 34 <3> TypSyscall EQU 0040h 35 <3> LevLog EQU 0000h 36 <3> LevArgs EQU 0001h 37 <3> 38 <3> TypInt24 EQU 0080h 39 <3> LevLog EQU 0000h 40 <3> 41 <3> TypProlog EQU 0100h 42 <3> LevLog EQU 0000h 43 <3> 44 <3> TypInt EQU 0200h 45 <3> LevLog equ 0000h 46 <3> 47 <3> typFCB equ 0400h 48 <3> LevLog equ 0000h 49 <3> LevCheck equ 0001h 74 <2> 0 0000000E ???? I_am MYNUM,WORD,<0> ; [SYSTEM] A number that goes with MYNAME 0 00000010 ???? I_am FCBLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache 0 00000012 ???? I_am OpenLRU,WORD,<0> ; [SYSTEM] LRU count for FCB cache opens 78 <2> ; NOTE: We include the decl of OEM_HANDLER in IBM DOS even though it is not used. 79 <2> ; This allows the REDIRector to work on either IBM or MS-DOS. 80 <2> PUBLIC OEM_HANDLER 0 00000014 ???????? OEM_HANDLER DD -1 ; [SYSTEM] Pointer to OEM handler code 82 <2> DOSGroup equ DOSGROUP ; NASM port equate 0 00000018 ???? I_am LeaveAddr,WORD,<> ; [SYSTEM] 0 0000001A ???? I_am RetryCount,WORD,<3> ; [SYSTEM] Share retries 0 0000001C ???? I_am RetryLoop,WORD,<1> ; [SYSTEM] Share retries 0 0000001E ???????? I_am LastBuffer,DWORD,<-1,-1>; [SYSTEM] Buffer queue recency pointer 0 00000022 ???? I_am CONTPOS,WORD ; [SYSTEM] location in buffer of next read 0 00000024 ???? I_am arena_head,WORD ; [SYSTEM] Segment # of first arena in memory 89 <2> ; The following block of data is used by SYSINIT. Do not change the order or 90 <2> ; size of this block 91 <2> PUBLIC SYSINITVAR ; [SYSTEM] 92 <2> SYSINITVAR LABEL WORD ; [SYSTEM] 0 00000026 ???????? I_am DPBHEAD,DWORD,<0,0> ; [SYSTEM] Pointer to head of DPB-FAT list 94 <2> DosGroup equ DOSGROUP ; NASM port equate 0 0000002A ???????? I_am sft_addr,DWORD,<,?> ; [SYSTEM] Pointer to first SFT table 0 0000002E ???????? I_am BCLOCK,DWORD ; [SYSTEM] The CLOCK device 0 00000032 ???????? I_am BCON,DWORD ; [SYSTEM] Console device entry points 0 00000036 ???? I_am MAXSEC,WORD,<128> ; [SYSTEM] Maximum allowed sector size 99 <2> %ifdef BUF2 0 00000038 ???????? dd -1 101 <2> %else 102 <2> I_am BUFFHEAD,DWORD ; [SYSTEM] Pointer to head of buffer queue 103 <2> %endif 0 0000003C ???????? I_am CDSADDR,DWORD ; [SYSTEM] Pointer to curdir structure table 0 00000040 ???????? I_am sftFCB,DWORD ; [SYSTEM] pointer to FCB cache table 0 00000044 ???? I_am KeepCount,WORD ; [SYSTEM] count of FCB opens to keep 0 00000046 ?? I_am NUMIO,BYTE ; [SYSTEM] Number of disk tables 0 00000047 ?? I_am CDSCOUNT,BYTE ; [SYSTEM] Number of CDS structures in above 109 <2> ; A fake header for the NUL device 0 00000048 ???????? I_am NULDEV,DWORD ; [SYSTEM] Link to rest of device list 0 0000004C ???? DW DEVTYP | ISNULL ; [SYSTEM] Null device attributes 0 0000004E ???? short_addr SNULDEV ; [SYSTEM] Strategy entry point 0 00000050 ???? short_addr INULDEV ; [SYSTEM] Interrupt entry point 0 00000052 ???????????????? DB "NUL " ; [SYSTEM] Name of null device 114 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 114 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 114 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 114 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 0 0000005A ?? I_am Splices,BYTE,<0> ; [SYSTEM] TRUE => splices being done 0 0000005B ???? I_am Special_Entries,WORD,<0>; [SYSTEM] address of specail entries ;AN000; 0 0000005D ???????? I_am IFS_DOS_CALL,DWORD, ; [SYSTEM] entry for IFS DOS service ;AN000; 0 00000061 ???????? I_am IFS_HEADER,DWORD ; [SYSTEM] IFS header chain ;AN000; 0 00000065 ???? I_am BUFFERS_PARM1,WORD,<0> ; [SYSTEM] value of BUFFERS= ,m ;AN000; 0 00000067 ???? I_am BUFFERS_PARM2,WORD,<0> ; [SYSTEM] value of BUFFERS= ,n ;AN000; 0 00000069 ?? I_am BOOTDRIVE,BYTE ; [SYSTEM] the boot drive ;AN000; 0 0000006A ?? I_am DDMOVE,BYTE,<0> ; [SYSTEM] 1 if we need DWORD move ;AN000; 0 0000006B ???? I_am EXT_MEM_SIZE,WORD,<0> ; [SYSTEM] extended memory size ;AN000; 124 <2> 125 <2> %ifndef BUF2 126 <2> PUBLIC HASHINITVAR ; [SYSTEM] ;AN000; 127 <2> HASHINITVAR LABEL WORD ; [SYSTEM] ;AN000; 128 <2> I_am BUF_HASH_PTR,DWORD ; [SYSTEM] buffer Hash table addr ;AN000; 129 <2> I_am BUF_HASH_COUNT,WORD,<1> ; [SYSTEM] number of Hash entries ;AN000; 130 <2> I_am SC_CACHE_PTR,DWORD ; [SYSTEM] secondary cache pointer ;AN000; 131 <2> I_am SC_CACHE_COUNT,WORD,<0> ; [SYSTEM] secondary cache count ;AN000; 132 <2> 133 <2> %IF BUFFERFLAG 134 <2> I_am BUF_EMS_SAFE_FLAG,BYTE,<1> ; indicates whether the page used by buffers is safe or not 135 <2> I_am BUF_EMS_LAST_PAGE,4,<0,0,0,0> ; holds the last page above 640k 136 <2> I_am BUF_EMS_FIRST_PAGE,4,<0,0,0,0> ; holds the first page above 640K 137 <2> I_am BUF_EMS_NPA640,WORD,<0> ; holds the number of pages above 640K 138 <2> 139 <2> %ENDIF 140 <2> 141 <2> I_am BUF_EMS_MODE,BYTE,<-1> ; [SYSTEM] EMS mode ;AN000; 142 <2> I_am BUF_EMS_HANDLE,WORD ; [SYSTEM] buffer EMS handle ;AN000; 143 <2> I_am BUF_EMS_PAGE_FRAME,WORD ,<-1>;[SYSTEM] EMS page frame number ;AN000; 144 <2> I_am BUF_EMS_SEG_CNT,WORD,<1>; [SYSTEM] EMS seg count ;AN000; 145 <2> I_am BUF_EMS_PFRAME,WORD ; [SYSTEM] EMS page frame seg address ;AN000; 146 <2> I_am BUF_EMS_RESERV,WORD,<0> ; [SYSTEM] reserved ;AN000; 147 <2> 148 <2> %IF BUFFERFLAG 149 <2> I_am BUF_EMS_MAP_BUFF,1,<0> ; this is not used to save the state of the 150 <2> ; of the buffers page. this one byte is 151 <2> ; retained to keep the size of this data 152 <2> ; block the same. 153 <2> %ELSE 154 <2> I_am BUF_EMS_MAP_BUFF,12,<0,0,0,0,0,0,0,0,0,0,0,0> ; map buufer ;AN000; 155 <2> %ENDIF 156 <2> %endif 157 <2> 158 <2> %ifdef BUF2 0 0000006D ?? align 2, db ? 0 0000006E ???? I_am BUF2_Dirty_Count,WORD,0 0 00000070 ???????? I_am BUFFHEAD,DWORD ; [SYSTEM] Pointer to head of buffer queue 0 00000074 ???????? I_am BuffFree,DWORD 163 <2> %endif 164 <2> 165 <2> ; End of SYSINITVar block 166 <2> 0 00000078 ?? _fill 90h, ?, DataVersion - 4 168 <2> 169 <2> ; 170 <2> ; Sharer jump table 171 <2> ; 172 <2> PUBLIC JShare 173 <2> EVEN 174 <2> JShare LABEL DWORD 0 00000090 ???????? DW OFFSET badcallentry, DOSENTRY 0 00000094 ???????? DW OFFSET okcallentry, DOSENTRY ; 1 MFT_enter 0 00000098 ???????? DW OFFSET okcallentry, DOSENTRY ; 2 MFTClose 0 0000009C ???????? DW OFFSET badcallentry, DOSENTRY ; 3 MFTclU 0 000000A0 ???????? DW OFFSET badcallentry, DOSENTRY ; 4 MFTCloseP 0 000000A4 ???????? DW OFFSET badcallentry, DOSENTRY ; 5 MFTCloN 0 000000A8 ???????? DW OFFSET badcallentry, DOSENTRY ; 6 set_block 0 000000AC ???????? DW OFFSET badcallentry, DOSENTRY ; 7 clr_block 0 000000B0 ???????? DW OFFSET okcallentry, DOSENTRY ; 8 chk_block 0 000000B4 ???????? DW OFFSET badcallentry, DOSENTRY ; 9 MFT_get 0 000000B8 ???????? DW OFFSET badcallentry, DOSENTRY ; 10 ShSave 0 000000BC ???????? DW OFFSET badcallentry, DOSENTRY ; 11 ShChk 0 000000C0 ???????? DW OFFSET okcallentry , DOSENTRY ; 12 ShCol 0 000000C4 ???????? DW OFFSET badcallentry, DOSENTRY ; 13 ShCloseFile 0 000000C8 ???????? DW OFFSET badcallentry, DOSENTRY ; 14 ShSU 190 <2> 191 <2> MSCT001E: 192 <2> ; (no prior section) ; CONSTANTS ENDS 193 <2> 194 <2> 10 <1> ;=== Pop trace listing source 11 <1> END === Trace listing source: ../../INC/const2n.lst 1 %include "nobits.mac" 1 <1> %imacro stripparens 2.nolist 2 <1> %defstr %%param %2 3 <1> %rep 16 4 <1> %substr %%opening %%param 1 5 <1> %ifidn %%opening, '(' 6 <1> %substr %%param %%param 2,-1 7 <1> %endif 8 <1> %endrep 9 <1> %rep 16 10 <1> %strlen %%length %%param 11 <1> %substr %%closing %%param %%length 12 <1> %ifidn %%closing, ')' 13 <1> %substr %%param %%param 1,-2 14 <1> %endif 15 <1> %endrep 16 <1> %deftok %%token %%param 17 <1> %1 %%token 18 <1> %endmacro 19 <1> 20 <1> %imacro db 1-*.nolist 21 <1> %rep %0 22 <1> %define %%param %1 23 <1> %define %%multi 24 <1> %defstr %%string %%param 25 <1> %strlen %%stringlength %%string 26 <1> %assign %%index 1 27 <1> %rep %%stringlength 28 <1> %substr %%checkblank %%string %%index 29 <1> %ifidni %%checkblank, '"' 30 <1> %elifidni %%checkblank, "'" 31 <1> %else 32 <1> %deftok %%checkblank %%checkblank 33 <1> %ifempty %%checkblank 34 <1> %substr %%dup %%string %%index + 1,4 35 <1> %deftok %%dup %%dup 36 <1> %assign %%isdup 0 37 <1> %ifidni %%dup, dup 38 <1> %assign %%isdup 1 39 <1> %elifidni %%dup, dup( 40 <1> %assign %%isdup 1 41 <1> %endif 42 <1> %if %%isdup 43 <1> %substr %%multi %%string 1, %%index - 1 44 <1> %deftok %%multi %%multi 45 <1> %substr %%string %%string %%index + 5, -1 46 <1> %deftok %%token %%string 47 <1> %undef %%param 48 <1> stripparens %define %%param, %%token 49 <1> %assign %%length 1 50 <1> %ifstr %%param 51 <1> %strlen %%length %%param 52 <1> %endif 53 <1> %rep %%length * %%multi 54 <1> db ? 55 <1> %endrep 56 <1> %exitrep 57 <1> %endif 58 <1> %endif 59 <1> %endif 60 <1> %assign %%index %%index + 1 61 <1> %endrep 62 <1> %ifempty %%multi 63 <1> %assign %%length 1 64 <1> %ifstr %%param 65 <1> %strlen %%length %%param 66 <1> %endif 67 <1> %rep %%length 68 <1> db ? 69 <1> %endrep 70 <1> %endif 71 <1> %rotate 1 72 <1> %endrep 73 <1> %endmacro 74 <1> 75 <1> %imacro dw 1-*.nolist 76 <1> %rep %0 77 <1> %define %%param %1 78 <1> %define %%multi 79 <1> %defstr %%string %%param 80 <1> %strlen %%stringlength %%string 81 <1> %assign %%index 1 82 <1> %rep %%stringlength 83 <1> %substr %%checkblank %%string %%index 84 <1> %ifidni %%checkblank, '"' 85 <1> %elifidni %%checkblank, "'" 86 <1> %else 87 <1> %deftok %%checkblank %%checkblank 88 <1> %ifempty %%checkblank 89 <1> %substr %%dup %%string %%index + 1,4 90 <1> %deftok %%dup %%dup 91 <1> %assign %%isdup 0 92 <1> %ifidni %%dup, dup 93 <1> %assign %%isdup 1 94 <1> %elifidni %%dup, dup( 95 <1> %assign %%isdup 1 96 <1> %endif 97 <1> %if %%isdup 98 <1> %substr %%multi %%string 1, %%index - 1 99 <1> %deftok %%multi %%multi 100 <1> %substr %%string %%string %%index + 5, -1 101 <1> %deftok %%token %%string 102 <1> %undef %%param 103 <1> stripparens %define %%param, %%token 104 <1> %assign %%length 1 105 <1> %ifstr %%param 106 <1> %strlen %%length %%param 107 <1> %assign %%length (%%length + 1) / 2 108 <1> %endif 109 <1> %rep %%length * %%multi 110 <1> dw ? 111 <1> %endrep 112 <1> %exitrep 113 <1> %endif 114 <1> %endif 115 <1> %endif 116 <1> %assign %%index %%index + 1 117 <1> %endrep 118 <1> %ifempty %%multi 119 <1> %assign %%length 1 120 <1> %ifstr %%param 121 <1> %strlen %%length %%param 122 <1> %assign %%length (%%length + 1) / 2 123 <1> %endif 124 <1> %rep %%length 125 <1> dw ? 126 <1> %endrep 127 <1> %endif 128 <1> %rotate 1 129 <1> %endrep 130 <1> %endmacro 131 <1> 132 <1> %imacro dd 1-*.nolist 133 <1> %rep %0 134 <1> %define %%param %1 135 <1> %define %%multi 136 <1> %defstr %%string %%param 137 <1> %strlen %%stringlength %%string 138 <1> %assign %%index 1 139 <1> %rep %%stringlength 140 <1> %substr %%checkblank %%string %%index 141 <1> %ifidni %%checkblank, '"' 142 <1> %elifidni %%checkblank, "'" 143 <1> %else 144 <1> %deftok %%checkblank %%checkblank 145 <1> %ifempty %%checkblank 146 <1> %substr %%dup %%string %%index + 1,4 147 <1> %deftok %%dup %%dup 148 <1> %assign %%isdup 0 149 <1> %ifidni %%dup, dup 150 <1> %assign %%isdup 1 151 <1> %elifidni %%dup, dup( 152 <1> %assign %%isdup 1 153 <1> %endif 154 <1> %if %%isdup 155 <1> %substr %%multi %%string 1, %%index - 1 156 <1> %deftok %%multi %%multi 157 <1> %substr %%string %%string %%index + 5, -1 158 <1> %deftok %%token %%string 159 <1> %undef %%param 160 <1> stripparens %define %%param, %%token 161 <1> %assign %%length 1 162 <1> %ifstr %%param 163 <1> %strlen %%length %%param 164 <1> %assign %%length (%%length + 3) / 4 165 <1> %endif 166 <1> %rep %%length * %%multi 167 <1> dd ? 168 <1> %endrep 169 <1> %exitrep 170 <1> %endif 171 <1> %endif 172 <1> %endif 173 <1> %assign %%index %%index + 1 174 <1> %endrep 175 <1> %ifempty %%multi 176 <1> %assign %%length 1 177 <1> %ifstr %%param 178 <1> %strlen %%length %%param 179 <1> %assign %%length (%%length + 3) / 4 180 <1> %endif 181 <1> %rep %%length 182 <1> dd ? 183 <1> %endrep 184 <1> %endif 185 <1> %rotate 1 186 <1> %endrep 187 <1> %endmacro 2 %define DONOBITS 3 %include "const2.nas" 1 <1> ; SCCSID = @(#)const2.asm 1.4 85/07/24 2 <1> ;TITLE CONST2 - More constants data 3 <1> ;NAME CONST2 4 <1> 5 <1> [list -] 5 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <5> [list -] 14 <4> [list -] 3 <3> === Switch to base=001DC0h -> "DOSSTART" 4 <3> addsection DOSSTART, align=16 PUBLIC class=DOSSTART 5 <3> ; (no prior section) ; DOSSTART ENDS 6 <3> === Switch to base=001DC0h -> "DOSSTARTJUMP" 7 <3> addsection DOSSTARTJUMP, align=1 PUBLIC class=START 8 <3> ; (no prior section) ; DOSSTARTJUMP ENDS 9 <3> === Switch to base=001DC0h -> "CONSTANTS" 10 <3> addsection CONSTANTS, align=2 PUBLIC class=CONST 11 <3> ; (no prior section) ; CONSTANTS ENDS 12 <3> === Switch to base=001DC0h -> "DATA" 13 <3> addsection DATA, align=2 PUBLIC class=DATA 14 <3> ; (no prior section) ; DATA ENDS 15 <3> === Switch to base=001DC0h -> "TABLE" 16 <3> addsection TABLE, align=2 PUBLIC class=TABLE 17 <3> ; (no prior section) ; TABLE ENDS 18 <3> === Switch to base=001DC0h -> "DOSDATATABLE" 19 <3> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE 20 <3> ; (no prior section) ; DOSDATATABLE ENDS 21 <3> === Switch to base=001DC0h -> "DOSDATACODE" 22 <3> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE 23 <3> ; (no prior section) ; DOSDATACODE ENDS 24 <3> === Switch to base=001DC0h -> "DOSBIODATA" 25 <3> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA 26 <3> === Switch to base=001DC0h -> "LAST" 27 <3> addsection LAST, align=16 PUBLIC class=LAST 28 <3> ; (no prior section) ; LAST ENDS 29 <3> 30 <3> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST 31 <3> 32 <3> %include "entryseg.nas" 1 <4> 2 <4> %ifndef ENTRYSEGNAS 3 <4> %define ENTRYSEGNAS 1 4 <4> 5 <4> %include "lmacros3.mac" 1 <5> [list -] 6 <4> === Switch to base=003490h -> "DOSENTRY" 7 <4> addsection DOSENTRY, class=%[DOSENTRY] 8 <4> 9 <4> group DOSENTRYGROUP DOSENTRY 10 <4> 11 <4> %endif 8 <2> 9 <2> %include "dcodeseg.nas" 1 <3> 2 <3> %ifndef DCODESEGNAS 3 <3> %assign DCODESEGNAS 1 4 <3> === Switch to base=003490h -> "DOSCODETABLE" 5 <3> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <3> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <3> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <3> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <3> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <3> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <3> 12 <3> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <3> 14 <3> %endif 10 <2> === Switch to base=001DC0h -> "LAST" 11 <2> section LAST 12 <2> ; (no prior section) ; LAST ENDS 8 <1> %include "dossym.mac" 1 <2> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dossym.asm 1.1 85/04/10 3 <2> ; PAGE 80,132 4 <2> TRUE EQU 0FFFFh 5 <2> FALSE EQU 0 6 <2> 7 <2> Installed equ TRUE 8 <2> %IFNDEF DEBUG 9 <2> DEBUG equ FALSE 10 <2> %ENDIF 11 <2> %IFNDEF debug 12 <2> debug equ DEBUG 13 <2> %ENDIF 14 <2> 15 <2> %if 0 16 <2> DBCS equ FALSE ; for fixmem.pl operation 17 <2> %endif 18 <2> 19 <2> ; NASM original macros 20 <2> 21 <2> %macro DBCS 1.nolist 22 <2> %defstr %%string %1 23 <2> %substr %%prefix %%string 1,2 24 <2> %substr %%suffix %%string 3,-1 25 <2> %ifnidni %%prefix, "= " 26 <2> %error Unexpected DBCS prefix 27 <2> %endif 28 <2> %deftok %%token %%suffix 29 <2> %xdefine DBCS %%token 30 <2> %endmacro 31 <2> 32 <2> %include "DBCS.SW" 1 <3> DBCS = FALSE 2 <3> 33 <2> %unmacro DBCS 1.nolist 34 <2> 35 <2> ; end of NASM original macros 36 <2> 37 <2> %include "dosmac.mac" 1 <3> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 3 <3> ; 4 <3> ; Macro file for MSDOS. 5 <3> ; 6 <3> 7 <3> %ifndef __DOSMAC_MAC__ 8 <3> %assign __DOSMAC_MAC__ 1 9 <3> 10 <3> TRUE EQU 0FFFFh 11 <3> FALSE EQU 0 12 <3> 13 <3> 14 <3> ; NASM original macros (comment for fixmem.pl) 15 <3> 16 <3> ;SUBTTL BREAK a listing into pages and give new subtitles 17 <3> ;PAGE 18 <3> %imacro BREAK 0-1+.nolist 19 <3> ;SUBTTL subtitle 20 <3> ;PAGE 21 <3> %endmacro 22 <3> ;.xcref break 23 <3> 24 <3> BREAK 25 <3> 26 <3> %if 0 27 <3> AsmVars Macro varlist 28 <3> IRP var, 29 <3> AsmVar var 30 <3> ENDM 31 <3> ENDM 32 <3> 33 <3> AsmVar Macro var 34 <3> IFNDEF var 35 <3> var = FALSE 36 <3> ENDIF 37 <3> ENDM 38 <3> %endif 39 <3> 40 <3> BREAK 41 <3> 42 <3> ; 43 <3> ; declare a variable external and allocate a size 44 <3> ; 45 <3> ;AsmVar InstalledData 46 <3> %ifndef InstalledData 47 <3> %define InstalledData 0 48 <3> %endif 49 <3> 50 <3> %imacro I_NEED 1-2.nolist 51 <3> %ifn InstalledData === Switch to base=001DC0h -> "DATA" 52 <3> [section DATA] 53 <3> %IFIDNi %2, WORD 54 <3> EXTRN %1:WORD 55 <3> %ELSE 56 <3> %IFIDNi %2, DWORD 57 <3> EXTRN %1:DWORD 58 <3> %ELSE 59 <3> EXTRN %1:BYTE 60 <3> %ENDIF 61 <3> %ENDIF 62 <3> __SECT__ 63 <3> %ENDIF 64 <3> %endmacro 65 <3> ;.xcref I_need 66 <3> 67 <3> ; 68 <3> ; call a procedure that may be external. The call will be short. 69 <3> ; 70 <3> %imacro invoke 1.nolist 71 <3> ;.xcref 72 <3> EXTRN %1:NEAR 73 <3> ;.cref 74 <3> CALL %1 75 <3> %endmacro 76 <3> ;.xcref invoke 77 <3> 78 <3> ;PAGE 79 <3> ; 80 <3> ; jump to a label that may be external. The jump will be near. 81 <3> ; 82 <3> %imacro transfer 1.nolist 83 <3> ;.xcref 84 <3> EXTRN %1:NEAR 85 <3> ;.cref 86 <3> JUMP %1 87 <3> %endmacro 88 <3> ;.xcref transfer 89 <3> 90 <3> ; 91 <3> ; get a short address in a word 92 <3> ; 93 <3> %imacro short_addr 1.nolist 94 <3> %ifnidn %1, ? 95 <3> EXTRN %1:NEAR 96 <3> DW OFFSET %1 97 <3> %ELSE 98 <3> DW ? 99 <3> %ENDIF 100 <3> %endmacro 101 <3> ;.xcref short_addr 102 <3> 103 <3> ; 104 <3> ; get a long address in a dword 105 <3> ; 106 <3> %imacro long_addr 1.nolist 107 <3> EXTRN %1:NEAR 108 <3> DD %1 109 <3> %endmacro 110 <3> ;.xcref long_addr 111 <3> 112 <3> ; 113 <3> ; declare a PROC near or far but PUBLIC nonetheless 114 <3> ; 115 <3> ;.xcref ?frame 116 <3> ;.xcref ?aframe 117 <3> ;.xcref ?stackdepth 118 <3> ;.xcref ?initstack 119 <3> %assign ?frame 0 ; initial 120 <3> %assign ?aframe 0 ; initial 121 <3> %assign ?stackdepth 0 ; initial stack size 122 <3> %assign ?initstack 0 ; initial stack size 123 <3> 124 <3> %imacro procedure 1-2.nolist 125 <3> %assign ?frame 0 126 <3> %assign ?aframe 2 ;; remember the pushed BP 127 <3> %warning proc %1... 128 <3> %1 PROC %2 129 <3> PUBLIC %1 130 <3> %assign ?initstack ?stackdepth ;; beginning of procedure 131 <3> %endmacro 132 <3> ;.xcref procedure 133 <3> 134 <3> ; 135 <3> ; end a procedure and check that stack depth is preserved 136 <3> ; 137 <3> %imacro EndProc 1-2.nolist 138 <3> %ifnidni %2, NoCheck ;; check the stack size 139 <3> %if ?initstack != ?stackdepth ;; is it different? 140 <3> %warning ***** Possible stack size error in %1 ***** 141 <3> %endif 142 <3> %endif 143 <3> %1 ENDP 144 <3> %endmacro 145 <3> ;.xcref endproc 146 <3> ;PAGE 147 <3> ; 148 <3> ; define a data item to be public and of an appropriate size/type 149 <3> ; 150 <3> 151 <3> %imacro stripangles 2.nolist 152 <3> %defstr %%param %2 153 <3> %rep 16 154 <3> %substr %%opening %%param 1 155 <3> %ifidn %%opening, '<' 156 <3> %substr %%param %%param 2,-1 157 <3> %endif 158 <3> %endrep 159 <3> %rep 16 160 <3> %strlen %%length %%param 161 <3> %substr %%closing %%param %%length 162 <3> %ifidn %%closing, '>' 163 <3> %substr %%param %%param 1,-2 164 <3> %endif 165 <3> %endrep 166 <3> %deftok %%token %%param 167 <3> %1 %%token 168 <3> %endmacro 169 <3> 170 <3> %imacro I_AM 2-*.nolist 171 <3> ;I_AM MACRO name,size,init 172 <3> %xdefine %%name %1 173 <3> ;; declare the type of the object 174 <3> %IFIDNi %2, WORD 175 <3> %1 LABEL WORD 176 <3> %assign I_AM_SIZE 1 177 <3> %assign I_AM_LEN 2 178 <3> %ELSE 179 <3> %IFIDNi %2, DWORD 180 <3> %1 LABEL DWORD 181 <3> %assign I_AM_SIZE 2 182 <3> %assign I_AM_LEN 2 183 <3> %ELSE 184 <3> %IFIDNi %2, BYTE 185 <3> %1 LABEL BYTE 186 <3> %assign I_AM_SIZE 1 187 <3> %assign I_AM_LEN 1 188 <3> %ELSE 189 <3> %1 LABEL BYTE 190 <3> %undef I_AM_SIZE 191 <3> stripangles %assign I_AM_SIZE, %2 192 <3> %assign I_AM_LEN 1 193 <3> %ENDIF 194 <3> %ENDIF 195 <3> %ENDIF 196 <3> ;; declare the object public 197 <3> PUBLIC %%name 198 <3> ;; if no initialize then allocate blank storage 199 <3> %IF %0 == 2 200 <3> DB I_AM_SIZE*I_AM_LEN DUP (?) 201 <3> %ELSE 202 <3> %ifn InstalledData 203 <3> %rotate 2 204 <3> %rep %0 - 2 205 <3> %IF I_AM_LEN == 1 206 <3> stripangles db, %1 207 <3> %ELSE 208 <3> stripangles dw, %1 209 <3> %ENDIF 210 <3> %assign I_AM_SIZE I_AM_SIZE - 1 211 <3> %rotate 1 212 <3> %endrep 213 <3> %IF I_AM_SIZE != 0 214 <3> %error ***** initialization of %%name not complete ***** 215 <3> %ENDIF 216 <3> %ELSE 217 <3> DB I_AM_SIZE*I_AM_LEN DUP (?) 218 <3> %ENDIF 219 <3> %ENDIF 220 <3> %endmacro 221 <3> 222 <3> %imacro I_AM_NOBITS 2-*.nolist 223 <3> ;I_AM MACRO name,size,init 224 <3> %xdefine %%name %1 225 <3> ;; declare the type of the object 226 <3> %IFIDNi %2, WORD 227 <3> %1 LABEL WORD 228 <3> %assign I_AM_SIZE 1 229 <3> %assign I_AM_LEN 2 230 <3> %ELSE 231 <3> %IFIDNi %2, DWORD 232 <3> %1 LABEL DWORD 233 <3> %assign I_AM_SIZE 2 234 <3> %assign I_AM_LEN 2 235 <3> %ELSE 236 <3> %IFIDNi %2, BYTE 237 <3> %1 LABEL BYTE 238 <3> %assign I_AM_SIZE 1 239 <3> %assign I_AM_LEN 1 240 <3> %ELSE 241 <3> %1 LABEL BYTE 242 <3> %undef I_AM_SIZE 243 <3> stripangles %assign I_AM_SIZE, %2 244 <3> %assign I_AM_LEN 1 245 <3> %ENDIF 246 <3> %ENDIF 247 <3> %ENDIF 248 <3> ;; declare the object public 249 <3> PUBLIC %%name 250 <3> ;; if no initialize then allocate blank storage 251 <3> %IF %0 == 2 252 <3> resb I_AM_SIZE*I_AM_LEN 253 <3> %ELSE 254 <3> %ifn InstalledData 255 <3> %rotate 2 256 <3> %rep %0 - 2 257 <3> %IF I_AM_LEN == 1 258 <3> resb 1 259 <3> %ELSE 260 <3> resw 1 261 <3> %ENDIF 262 <3> %assign I_AM_SIZE I_AM_SIZE - 1 263 <3> %rotate 1 264 <3> %endrep 265 <3> %IF I_AM_SIZE != 0 266 <3> %error ***** initialization of %%name not complete ***** 267 <3> %ENDIF 268 <3> %ELSE 269 <3> resb I_AM_SIZE*I_AM_LEN 270 <3> %ENDIF 271 <3> %ENDIF 272 <3> %endmacro 273 <3> 274 <3> ;.xcref I_AM 275 <3> ;.xcref I_AM_SIZE 276 <3> ;.xcref I_AM_LEN 277 <3> %assign I_AM_SIZE 0 278 <3> %assign I_AM_LEN 0 279 <3> 280 <3> ;PAGE 281 <3> 282 <3> ; 283 <3> ; define an entry in a procedure 284 <3> ; 285 <3> %imacro entry 1.nolist 286 <3> %1: 287 <3> PUBLIC %1 288 <3> %endmacro 289 <3> ;.xcref entry 290 <3> 291 <3> BREAK 292 <3> 293 <3> %imacro error 1.nolist 294 <3> ;.xcref 295 <3> MOV AL, %1 296 <3> transfer SYS_RET_ERR 297 <3> ;.cref 298 <3> %endmacro 299 <3> ;.xcref error 300 <3> 301 <3> BREAK 302 <3> ; 303 <3> ; given a label either 2 byte jump to another label _J 304 <3> ; if it is near enough or 3 byte jump to 305 <3> ; 306 <3> 307 <3> %imacro jump 1.nolist 308 <3> ;.xcref 309 <3> 310 <3> %ifndef %1_J ;; is this the first invocation 311 <3> %%a: JMP %1 312 <3> %ELSE 313 <3> %IF (%1_J >= $) || ($-%1_J > 126) 314 <3> %%a: JMP %1 ;; is the jump too far away? 315 <3> %ELSE 316 <3> %%a: JMP %1_J ;; do the short one... 317 <3> %ENDIF 318 <3> %ENDIF 319 <3> %ixdefine %1_j %%a 320 <3> ;.cref 321 <3> %endmacro 322 <3> ;.xcref jump 323 <3> 324 <3> BREAK 325 <3> 326 <3> %imacro return 0.nolist 327 <3> %%a: 328 <3> RET 329 <3> %xdefine ret_l %%a 330 <3> %endmacro 331 <3> ;.xcref return 332 <3> 333 <3> BREAK 334 <3> 335 <3> %imacro condret 2.nolist 336 <3> %assign %%exit 0 337 <3> %ifdef ret_l ;; if ret_l is defined 338 <3> %if (($ - ret_l) <= 126) && ($ > ret_l) 339 <3> ;; if ret_l is near enough then 340 <3> %%a: j%1 ret_l ;; a: j to ret_l 341 <3> %xdefine ret_%1 %%a ;; define ret_ to be a: 342 <3> %assign %%exit 1 343 <3> %endif 344 <3> %endif 345 <3> %ifn %%exit 346 <3> %ifdef ret_%1 ;; if ret_ defined 347 <3> %if (($ - ret_%1) <= 126) && ($ > ret_%1) 348 <3> ;; if ret_ is near enough 349 <3> %%a: j%1 ret_%1 ;; a: j to ret_ 350 <3> %xdefine ret_%1 %%a ;; define ret_ to be a: 351 <3> %assign %%exit 1 352 <3> %endif 353 <3> %endif 354 <3> %endif 355 <3> %ifn %%exit 356 <3> j%2 %%a ;; j a: 357 <3> return ;; return 358 <3> %%a: ;; a: 359 <3> %xdefine ret_%1 ret_l ;; define ret_ to be ret_l 360 <3> %endif 361 <3> %endmacro 362 <3> ;.xcref condret 363 <3> 364 <3> BREAK 365 <3> 366 <3> %imacro retz 0.nolist 367 <3> condret z,nz 368 <3> %endmacro 369 <3> ;.xcref retz 370 <3> 371 <3> BREAK 372 <3> 373 <3> %imacro retnz 0.nolist 374 <3> condret nz,z 375 <3> %endmacro 376 <3> ;.xcref retnz 377 <3> 378 <3> BREAK 379 <3> 380 <3> %imacro retc 0.nolist 381 <3> condret c,nc 382 <3> %endmacro 383 <3> ;.xcref retc 384 <3> 385 <3> BREAK 386 <3> 387 <3> %imacro retnc 0.nolist 388 <3> condret nc,c 389 <3> %endmacro 390 <3> ;.xcref retnc 391 <3> 392 <3> BREAK 393 <3> 394 <3> %imacro context 1.nolist 395 <3> PUSH SS 396 <3> stripangles POP, %1 397 <3> ; ASSUME %1:DOSGROUP 398 <3> %endmacro 399 <3> ;.xcref context 400 <3> 401 <3> BREAK 402 <3> 403 <3> %imacro SaveReg 0-*.nolist ;; push those registers 404 <3> %rep %0 405 <3> %assign ?stackdepth ?stackdepth + 1 406 <3> stripangles push, %1 407 <3> %rotate 1 408 <3> %endrep 409 <3> %endmacro 410 <3> ;.xcref SaveReg 411 <3> 412 <3> BREAK 413 <3> 414 <3> %imacro RestoreReg 0-*.nolist ;; pop those registers 415 <3> %rep %0 416 <3> %assign ?stackdepth ?stackdepth - 1 417 <3> stripangles pop, %1 418 <3> %rotate 1 419 <3> %endrep 420 <3> %endmacro 421 <3> ;.xcref RestoreReg 422 <3> 423 <3> BREAK 424 <3> 425 <3> %imacro EnterCrit 1.nolist 426 <3> Invoke E%1 427 <3> %endmacro 428 <3> 429 <3> %imacro LeaveCrit 1.nolist 430 <3> Invoke L%1 431 <3> %endmacro 432 <3> 433 <3> Break 434 <3> 435 <3> ;AsmVars 436 <3> %ifndef ShareF 437 <3> %idefine ShareF 0 438 <3> %endif 439 <3> %ifndef Cargs 440 <3> %idefine Cargs 0 441 <3> %endif 442 <3> %ifndef Redirector 443 <3> %idefine Redirector 0 444 <3> %endif 445 <3> %ifndef debug 446 <3> %idefine debug 0 447 <3> %endif 448 <3> 449 <3> %if debug 450 <3> %imacro fmt 3-*.nolist 451 <3> ;fmt MACRO typ,lev,fmts,args 452 <3> ;local a,b,c 453 <3> PUSHF 454 <3> %IFNempty %1 455 <3> TEST word [BugTyp],%1 456 <3> JZ %%c 457 <3> CMP word [BugLev],%2 458 <3> JB %%c 459 <3> %ENDIF 460 <3> PUSH AX 461 <3> PUSH BP 462 <3> MOV BP,SP 463 <3> %If (! sharef) && (! redirector) === Switch to base=001DC0h -> "TABLE" 464 <3> [section Table] 465 <3> %%a: db %3,0 466 <3> __SECT__ 467 <3> MOV AX,OFFSET %%a wrt DOSGROUP 468 <3> %else 469 <3> jmp short %%b 470 <3> %%a: db %3,0 471 <3> %if sharef 472 <3> %%b: mov ax,offset %%a wrt share 473 <3> %else 474 <3> %%b: mov ax,offset %%a wrt netwrk 475 <3> %endif 476 <3> %endif 477 <3> PUSH AX 478 <3> %iassign cargs 2 479 <3> %rotate 3 480 <3> %rep %0 - 3 481 <3> %ifidni ax, %1 482 <3> MOV AX,[BP+2] 483 <3> %ELSE 484 <3> MOV AX, %1 485 <3> %ENDIF 486 <3> PUSH AX 487 <3> %iassign cargs cargs + 2 488 <3> %rotate 1 489 <3> %endrep 490 <3> invoke PFMT 491 <3> ADD SP, Cargs 492 <3> POP BP 493 <3> POP AX 494 <3> %%c: 495 <3> POPF 496 <3> %endmacro 497 <3> %else 498 <3> %imacro fmt 3-*.nolist 499 <3> %endmacro 500 <3> %endif 501 <3> 502 <3> Break 503 <3> 504 <3> ;AsmVar Debug,$temp 505 <3> 506 <3> %imacro detectstripangles 4.nolist 507 <3> %defstr %%param %4 508 <3> %assign ?%2 0 509 <3> %assign ?%3 0 510 <3> %rep 16 511 <3> %substr %%opening %%param 1 512 <3> %ifidn %%opening, '<' 513 <3> %substr %%param %%param 2,-1 514 <3> %assign ?%2 ?%2 + 1 515 <3> %endif 516 <3> %endrep 517 <3> %rep 16 518 <3> %strlen %%length %%param 519 <3> %substr %%closing %%param %%length 520 <3> %ifidn %%closing, '>' 521 <3> %substr %%param %%param 1,-2 522 <3> %assign ?%3 ?%3 + 1 523 <3> %endif 524 <3> %endrep 525 <3> %deftok %%token %%param 526 <3> %define ?%1 %%token 527 <3> %endmacro 528 <3> 529 <3> 530 <3> %IF debug 531 <3> %imacro DOSAssume 3-*.nolist 532 <3> ;DOSAssume Macro reg,reglist,message 533 <3> %ifidni %1, CS 534 <3> %assign %%temp 1 535 <3> %else 536 <3> %ifidni %1, SS 537 <3> %assign %%temp 0 538 <3> %else 539 <3> %error ***** Invalid DOS register %1 in DOSAssume ***** 540 <3> %endif 541 <3> %endif 542 <3> %rotate 1 543 <3> %assign %%level 0 544 <3> %assign %%amount %0 - 1 545 <3> %rep 16 546 <3> detectstripangles %%token, %%opening, %%closing, %1 547 <3> %assign %%level %%level + ? %+ %%opening 548 <3> %assign %%level %%level - ? %+ %%closing 549 <3> %ifidni ? %+ %%token, DS 550 <3> %assign %%temp %%temp | 2 551 <3> %else 552 <3> %ifidni ? %+ %%token, ES 553 <3> %assign %%temp %%temp | 4 554 <3> %else 555 <3> %error ***** Invalid register reg in DOSAssume ***** 556 <3> %endif 557 <3> %endif 558 <3> %assign %%amount %%amount - 1 559 <3> %rotate 1 560 <3> %if %%level <= 0 561 <3> %exitrep 562 <3> %endif 563 <3> %endrep 564 <3> 565 <3> PUSH AX 566 <3> MOV AX, %%temp 567 <3> PUSH AX 568 <3> %IF SHAREF 569 <3> MOV AX,OFFSET %%a 570 <3> %ELSE 571 <3> MOV AX,OFFSET %%a wrt DOSGroup 572 <3> %ENDIF 573 <3> PUSH AX 574 <3> Invoke SegCheck 575 <3> POP AX 576 <3> %IFN SHAREF === Switch to base=001DC0h -> "TABLE" 577 <3> [section Table] 578 <3> %ELSE 579 <3> JMP SHORT %%b 580 <3> %ENDIF 581 <3> %%a: 582 <3> %rep %%amount 583 <3> DB %1 584 <3> %rotate 1 585 <3> %endrep 586 <3> db 0 587 <3> %IFN SHAREF 588 <3> __SECT__ 589 <3> %ELSE 590 <3> %%b: 591 <3> %ENDIF 592 <3> ;IRP r, 593 <3> ; ASSUME r:DOSGroup 594 <3> ;ENDM 595 <3> %endmacro 596 <3> %ELSE 597 <3> %imacro DOSAssume 3-*.nolist 598 <3> ;DOSAssume Macro reg,reglist,message 599 <3> ;IRP r, 600 <3> ; ASSUME r:DOSGroup 601 <3> ;ENDM 602 <3> %endmacro 603 <3> %ENDIF 604 <3> 605 <3> BREAK 606 <3> 607 <3> %if 0 608 <3> ;IF DEBUG 609 <3> Assert MACRO kind, objs, message 610 <3> LOCAL a,b 611 <3> IFIDN , 612 <3> CMP objs,0 613 <3> JZ a 614 <3> fmt <>,<>, 615 <3> a: 616 <3> ELSE 617 <3> IFIDN , 618 <3> CMP objs,0 619 <3> JNZ a 620 <3> fmt <>,<>, 621 <3> a: 622 <3> ELSE 623 <3> PUSH AX 624 <3> IRP obj, 625 <3> PUSH obj 626 <3> ENDM 627 <3> IF SHAREF 628 <3> MOV AX,OFFSET b 629 <3> ELSE 630 <3> MOV AX,OFFSET DOSGroup:b 631 <3> ENDIF 632 <3> PUSH AX 633 <3> IFIDN , 634 <3> Invoke BUFCheck 635 <3> ENDIF 636 <3> IFIDN , 637 <3> Invoke SFTCheck 638 <3> ENDIF 639 <3> IFIDN , 640 <3> Invoke DPBCheck 641 <3> ENDIF 642 <3> POP AX 643 <3> IF SHAREF 644 <3> JMP SHORT a 645 <3> b DB Message,0 646 <3> a: 647 <3> ELSE === Switch to base=001DC0h -> "TABLE" 648 <3> Table segment 649 <3> b db Message,0 === Switch to base=001DC0h -> "TABLE" 650 <3> Table ends 651 <3> ENDIF 652 <3> ENDIF 653 <3> ENDIF 654 <3> ENDM 655 <3> %ELSE 656 <3> %imacro Assert 0-*.nolist 657 <3> %endmacro 658 <3> %ENDIF 659 <3> 660 <3> %ifndef Installed 661 <3> %idefine Installed 1 662 <3> %endif 663 <3> 664 <3> Break 665 <3> 666 <3> %imacro CallInstall 3-*.nolist 667 <3> ;CallInstall MACRO name,mpx,fn,save,restore 668 <3> %define %%name %1 669 <3> %assign %%mpx %2 670 <3> %assign %%fn %3 671 <3> %IF Installed 672 <3> %rotate 3 673 <3> %assign %%level 0 674 <3> %assign %%amountsaved 0 675 <3> %rep %0 - 3 676 <3> %ifnempty %1 677 <3> detectstripangles %%token, %%opening, %%closing, %1 678 <3> %assign %%level %%level + ? %+ %%opening 679 <3> %assign %%level %%level - ? %+ %%closing 680 <3> SaveReg ? %+ %%token 681 <3> %endif 682 <3> %assign %%amountsaved %%amountsaved + 1 683 <3> %rotate 1 684 <3> %if %%level <= 0 685 <3> %exitrep 686 <3> %endif 687 <3> %endrep 688 <3> MOV AX,(%%mpx << 8) + %%fn 689 <3> INT 2Fh 690 <3> %assign %%level 0 691 <3> %assign %%amountrestored 0 692 <3> %rep %0 - 3 - %%amountsaved 693 <3> %ifnempty %1 694 <3> detectstripangles %%token, %%opening, %%closing, %1 695 <3> %assign %%level %%level + ? %+ %%opening 696 <3> %assign %%level %%level - ? %+ %%closing 697 <3> RestoreReg ? %+ %%token 698 <3> %endif 699 <3> %assign %%amountrestored %%amountrestored + 1 700 <3> %rotate 1 701 <3> %if %%level <= 0 702 <3> %exitrep 703 <3> %endif 704 <3> %endrep 705 <3> %if %%level > 0 || %0 != 3 + %%amountsaved + %%amountrestored 706 <3> %error Wrong amount saved or restored 707 <3> %endif 708 <3> %ELSE 709 <3> Invoke %%name 710 <3> %ENDIF 711 <3> %endmacro 712 <3> 713 <3> Break 714 <3> 715 <3> %imacro localvar 2.nolist 716 <3> %ifidni %2, BYTE 717 <3> %assign ?frame ?frame + 1 718 <3> %assign %%a ?frame 719 <3> labelsize %1, byte, bp - %%a 720 <3> %else 721 <3> %ifidni %2, WORD 722 <3> %assign ?frame ?frame + 2 723 <3> %assign %%a ?frame 724 <3> labelsize %1, word, bp - %%a 725 <3> %else 726 <3> %ifidni %2, DWORD 727 <3> %assign ?frame ?frame + 4 728 <3> %assign %%a ?frame 729 <3> labelsize %1 %+ l, word, bp - %%a 730 <3> labelsize %1 %+ h, word, bp - %%a + 2 731 <3> labelsize %1, dword, bp - %%a 732 <3> %else 733 <3> %assign ?frame ?frame + %2 734 <3> %assign %%a ?frame 735 <3> labelsize %1, byte, bp - %%a 736 <3> %endif 737 <3> %endif 738 <3> %endif 739 <3> %endmacro 740 <3> 741 <3> %imacro enter 0.nolist 742 <3> push bp 743 <3> mov bp,sp 744 <3> sub sp,?frame 745 <3> %endmacro 746 <3> 747 <3> %imacro leave 0.nolist 748 <3> mov sp,bp 749 <3> pop bp 750 <3> %endmacro 751 <3> 752 <3> 753 <3> %imacro argvar 2.nolist 754 <3> %ifidni %2, BYTE 755 <3> %assign %%a ?aframe 756 <3> %assign ?aframe ?aframe + 1 757 <3> labelsize %1, byte, bp + %%a 758 <3> %else 759 <3> %ifidni %2, WORD 760 <3> %assign %%a ?aframe 761 <3> %assign ?aframe ?aframe + 2 762 <3> labelsize %1, word, bp + %%a 763 <3> %else 764 <3> %ifidni %2, DWORD 765 <3> %assign %%a ?aframe 766 <3> %assign ?aframe ?aframe + 4 767 <3> labelsize %1 %+ l, word, bp + %%a 768 <3> labelsize %1 %+ h, word, bp + %%a + 2 769 <3> labelsize %1, dword, bp + %%a 770 <3> %else 771 <3> %assign %%a ?aframe 772 <3> %assign ?aframe ?aframe + %2 773 <3> labelsize %1, byte, bp + %%a 774 <3> %endif 775 <3> %endif 776 <3> %endif 777 <3> %endmacro 778 <3> 779 <3> BREAK 780 <3> 781 <3> %imacro errnz 1.nolist 782 <3> detectstripangles %%token, %%opening, %%closing, %1 783 <3> %if ? %+ %%token 784 <3> %error %1 <> 0 785 <3> %endif 786 <3> %endmacro 787 <3> 788 <3> %endif 38 <2> 39 <2> %include "versiona.mac" 1 <3> 2 <3> major_version equ 4 ;Major DOS version 3 <3> minor_version equ 00 ;Minor DOS Version 4 <3> 5 <3> MINOR_VERSION equ minor_version ; NASM port equate 6 <3> MAJOR_VERSION equ major_version ; NASM port equate 7 <3> expected_version equ (MINOR_VERSION << 8)+MAJOR_VERSION 8 <3> 9 <3> alt_major_version equ 5 ;Major DOS version 10 <3> alt_minor_version equ 26 ;Minor DOS Version 11 <3> 12 <3> alt_expected_version equ (alt_minor_version << 8) + alt_major_version 13 <3> 14 <3> %warning out: ... for DOS Version 4.00 ... 14 ****************** <3> warning: out: ... for DOS Version 4.00 ... [-w+user] 15 <3> 16 <3> ;****************************** 17 <3> ;Each assembler program should: 18 <3> ; mov ah,030h ;DOS Get Version function 19 <3> ; int 021h ;Version ret. in AX,minor version first 20 <3> ; cmp ax,expected_version ;ALL utilities should check for an 21 <3> ; jne error_handler ; EXACT version match. 22 <3> ;****************************** 23 <3> 40 <2> 41 <2> BREAK 42 <2> 43 <2> c_DEL EQU 7Fh ; ASCII rubout or delete previous char 44 <2> c_BS EQU 08h ; ^H ASCII backspace 45 <2> c_CR EQU 0Dh ; ^M ASCII carriage return 46 <2> c_LF EQU 0Ah ; ^J ASCII linefeed 47 <2> c_ETB EQU 17h ; ^W ASCII end of transmission 48 <2> c_NAK EQU 15h ; ^U ASCII negative acknowledge 49 <2> c_ETX EQU 03h ; ^C ASCII end of text 50 <2> c_HT EQU 09h ; ^I ASCII tab 51 <2> 52 <2> BREAK 53 <2> 54 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 55 <2> ; ; 56 <2> ; C A V E A T P R O G R A M M E R ; 57 <2> ; ; 58 <2> ; Certain structures, constants and system calls below are private to ; 59 <2> ; the DOS and are extremely version-dependent. They may change at any ; 60 <2> ; time at the implementors' whim. As a result, they must not be ; 61 <2> ; documented to the general public. If an extreme case arises, they ; 62 <2> ; must be documented with this warning. ; 63 <2> ; ; 64 <2> ; Those structures and constants that are subject to the above will be ; 65 <2> ; marked and bracketed with the flag: ; 66 <2> ; ; 67 <2> ; C A V E A T P R O G R A M M E R ; 68 <2> ; ; 69 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 70 <2> 71 <2> %include "bpb.mac" 1 <3> %warning out: BPB.INC... 1 ****************** <3> warning: out: BPB.INC... [-w+user] 2 <3> ; SCCSID = @(#)BPB.ASM 1.1 85/04/29 3 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 4 <3> ; C A V E A T P R O G R A M M E R ; 5 <3> ; ; 6 <3> 7 <3> ; BIOS PARAMETER BLOCK DEFINITION 8 <3> ; THIS STRUCTURE IS USED TO BUILD A FULL DPB 9 <3> 10 <3> BPBLOCK STRUC 0 00000D12 ???? BPSECSZ DW ? ; SIZE IN BYTES OF PHYSICAL SECTOR 0 00000D14 ?? BPCLUS DB ? ; SECTORS/ALLOC UNIT 0 00000D15 ???? BPRES DW ? ; NUMBER OF RESERVED SECTORS 0 00000D17 ?? BPFTCNT DB ? ; NUMBER OF FATS 0 00000D18 ???? BPDRCNT DW ? ; NUMBER OF DIRECTORY ENTRIES 0 00000D1A ???? BPSCCNT DW ? ; TOTAL NUMBER OF SECTORS 0 00000D1C ?? BPMEDIA DB ? ; MEDIA DESCRIPTOR BYTE 0 00000D1D ???? BPFTSEC DW ? ; NUMBER OF SECTORS TAKEN UP BY ONE FAT 19 <3> BPBLOCK ENDS 20 <3> 21 <3> A_BPB STRUC 0 00000D12 ???? BPB_BYTESPERSECTOR DW ? 0 00000D14 ?? BPB_SECTORSPERCLUSTER DB ? 0 00000D15 ???? BPB_RESERVEDSECTORS DW ? 0 00000D17 ?? BPB_NUMBEROFFATS DB ? 0 00000D18 ???? BPB_ROOTENTRIES DW ? 0 00000D1A ???? BPB_TOTALSECTORS DW ? 0 00000D1C ?? BPB_MEDIADESCRIPTOR DB ? 0 00000D1D ???? BPB_SECTORSPERFAT DW ? 0 00000D1F ???? BPB_SECTORSPERTRACK DW ? 0 00000D21 ???? BPB_HEADS DW ? 0 00000D23 ???? BPB_HIDDENSECTORS DW ? 0 00000D25 ???? DW ? 0 00000D27 ???? BPB_BIGTOTALSECTORS DW ? 0 00000D29 ???? DW ? 0 00000D2B ???????????? DB 6 DUP(?) 37 <3> A_BPB ENDS 38 <3> ; ; 39 <3> ; C A V E A T P R O G R A M M E R ; 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 72 <2> 73 <2> %include "buffer.mac" 1 <3> %include "buf2sw.mac" 1 <4> %define BUF2 1 2 <3> 3 <3> ; SCCSID = @(#)buffer.asm 1.1 85/04/09 4 <3> BREAK 5 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 6 <3> ; C A V E A T P R O G R A M M E R ; 7 <3> ; ; 8 <3> 9 <3> %ifdef BUF2 10 <3> 11 <3> ; Field definition for I/O buffer information 12 <3> 13 <3> BUFFINFO STRUC 0 00000D12 ???????? NEXTBUF DD ? ; Pointer to next buffer in list 15 <3> ; The next two items are often refed as a word 16 <3> buf_ID: 0 00000D16 ?? BUFDRV DB ? ; Logical drive # assoc with buffer FF = free 18 <3> buf_flags: 0 00000D17 ?? BUFDATAFLAG db ? 0 00000D18 ?? BUFPRI DB ? ; Buffer selection priority (see EQUs below) 0 00000D19 ?? alignb 2 22 <3> buf_sector: 0 00000D1A ???????? BUFSECNO dd ? ; Sector number of buffer 24 <3> alignb 2 0 00000D1E ???????? BUFDRVDP DD ? ; Pointer to drive parameters 26 <3> BUFFINFO ENDS 27 <3> 28 <3> BUFINSIZ EQU BUFFINFO_struc_size 29 <3> ; Size of structure in bytes 30 <3> BUFINSIZE equ BUFINSIZ 31 <3> 32 <3> FREEPRI EQU 0 33 <3> LBRPRI EQU 2 ; Last byte of buffer read 34 <3> LBWPRI EQU 4 ; Last byte written 35 <3> RPRI EQU 6 ; Read but not last byte 36 <3> WPRI EQU 8 ; Written but not last byte 37 <3> DIRPRI EQU 15 ; Directory Sector 38 <3> FATPRI EQU 30 ; FAT sector 39 <3> 40 <3> buf_dirty EQU 01000000B 41 <3> buf_isDATA EQU 00001000B 42 <3> buf_isDIR EQU 00000100B 43 <3> buf_isFAT EQU 00000010B 44 <3> buf_type_0 EQU 11110001B ; AND sets type to "none" 45 <3> 46 <3> %else 47 <3> 48 <3> ; Field definition for I/O buffer information 49 <3> 50 <3> BUFFINFO STRUC 51 <3> buf_next DW ? ; Pointer to next buffer in list 52 <3> buf_prev DW ? ; Pointer to prev buffer in list 53 <3> buf_ID DB ? ; Drive of buffer (bit 7 = 0) 54 <3> ; SFT table index (bit 7 = 1) 55 <3> ; = FFH if buffer free 56 <3> buf_flags DB ? ; Bit 7 = 1 if Remote file buffer 57 <3> ; = 0 if Local device buffer 58 <3> ; Bit 6 = 1 if buffer dirty 59 <3> ; Bit 5 = Reserved 60 <3> ; Bit 4 = Search bit (bit 7 = 1) 61 <3> ; Bit 3 = 1 if buffer is DATA 62 <3> ; Bit 2 = 1 if buffer is DIR 63 <3> ; Bit 1 = 1 if buffer is FAT 64 <3> ; Bit 0 = Reserved 65 <3> buf_sector DD ? ; Sector number of buffer (bit 7 = 0) 66 <3> ; The next two items are often refed as a word (bit 7 = 0) 67 <3> buf_wrtcnt DB ? ; For FAT sectors, # times sector written out 68 <3> buf_wrtcntinc DW ? ; " " " , # sectors between each write 69 <3> buf_DPB DD ? ; Pointer to drive parameters 70 <3> buf_fill DW ? ; How full buffer is (bit 7 = 1) 71 <3> buf_reserved DB ? ; make DWORD boundary for 386 72 <3> BUFFINFO ENDS 73 <3> 74 <3> labelsize buf_offset, dword, buf_sector 75 <3> ;For bit 7 = 1, this is the byte 76 <3> ;offset of the start of the buffer in 77 <3> ;the file pointed to by buf_ID. Thus 78 <3> ;the buffer starts at location 79 <3> ;buf_offset in the file and contains 80 <3> ;buf_fill bytes. 81 <3> 82 <3> BUFINSIZ EQU BUFFINFO_struc_size 83 <3> ; Size of structure in bytes 84 <3> 85 <3> buf_Free EQU 0FFh ; buf_id of free buffer 86 <3> 87 <3> ;Flag byte masks 88 <3> buf_isnet EQU 10000000B 89 <3> buf_dirty EQU 01000000B 90 <3> 91 <3> buf_isDATA EQU 00001000B 92 <3> buf_isDIR EQU 00000100B 93 <3> buf_isFAT EQU 00000010B 94 <3> buf_type_0 EQU 11110001B ; AND sets type to "none" 95 <3> 96 <3> buf_NetID EQU BUFINSIZ 97 <3> 98 <3> ; 99 <3> ; Buffer Hash Entry Structure 100 <3> 101 <3> BUFFER_HASH_ENTRY STRUC ; DOS 4.00 102 <3> EMS_PAGE_NUM DW ? ; logical page number for EMS handle 103 <3> BUFFER_BUCKET DD ? ; pointer to buffers 104 <3> DIRTY_COUNT DB ? ; number of dirty buffers 105 <3> BUFFER_RESERVED DB ? ; reserved 106 <3> BUFFER_HASH_ENTRY ENDS 107 <3> 108 <3> MaxBuffinBucket EQU 15 ; Max number of buffers per bucket 109 <3> MaxBucketinPage EQU 2 ; Max number of buckets per 16kb page 110 <3> 111 <3> %endif 112 <3> 113 <3> ; ; 114 <3> ; C A V E A T P R O G R A M M E R ; 115 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 74 <2> 75 <2> BREAK 76 <2> ; Location of user registers relative user stack pointer 77 <2> 78 <2> user_environ STRUC 0 00000D12 ???? user_AX DW ? 0 00000D14 ???? user_BX DW ? 0 00000D16 ???? user_CX DW ? 0 00000D18 ???? user_DX DW ? 0 00000D1A ???? user_SI DW ? 0 00000D1C ???? user_DI DW ? 0 00000D1E ???? user_BP DW ? 0 00000D20 ???? user_DS DW ? 0 00000D22 ???? user_ES DW ? 0 00000D24 ???? user_IP DW ? 0 00000D26 ???? user_CS DW ? 0 00000D28 ???? user_F DW ? 91 <2> user_environ ENDS 92 <2> 93 <2> %include "sysvar.mac" 1 <3> ; SCCSID = @(#)sysvar.asm 1.1 85/04/10 2 <3> %include "version.mac" 1 <4> ; Some modules really want TRUE to be 0FFH. Best to let them have their way. 2 <4> TRUE EQU 0FFFFh 3 <4> TRUEBYTE EQU 0FFh 4 <4> FALSE EQU 0 5 <4> 6 <4> ; 7 <4> ; Use the following switches to control cmacros.inc 8 <4> ; 9 <4> ?PLM equ 0 10 <4> ?WIN equ 0 11 <4> 12 <4> memS EQU 1 ; Small model 13 <4> ; 14 <4> ; Use the switches below to produce the standard Microsoft version or the IBM 15 <4> ; version of the operating system 16 <4> ; 17 <4> ; The below chart will indicate how to set the switches to build the various 18 <4> ; versions 19 <4> ; 20 <4> ; IBMVER IBMCOPYRIGHT 21 <4> ; -------------------------------------------------------- 22 <4> ; IBM Version | TRUE TRUE 23 <4> ; -------------------------------------------------------- 24 <4> ; MS Version | FALSE FALSE 25 <4> ; -------------------------------------------------------- 26 <4> ; Clone Version | TRUE FALSE 27 <4> ; 28 <4> IBMVER EQU TRUE 29 <4> IBMCOPYRIGHT EQU FALSE 30 <4> 31 <4> BUFFERFLAG EQU ~ IBMCOPYRIGHT 32 <4> 33 <4> %ifndef MSVER 34 <4> MSVER EQU ~ IBMVER 35 <4> %endif 36 <4> IBM EQU IBMVER 37 <4> ; 38 <4> ; 39 <4> %IF IBMVER 40 <4> %IF IBMCOPYRIGHT 41 <4> %warning out: ... IBM version build switch on ... 42 <4> %ELSE 43 <4> %warning out: ... CLONE version build switch on ... 43 ****************** <4> warning: out: ... CLONE version build switch on ... [-w+user] 44 <4> %ENDIF 45 <4> %ELSE 46 <4> %IFN IBMCOPYRIGHT 47 <4> %warning out: ... MS version build switch on ... 48 <4> %ELSE 49 <4> %warning out: !!!!!!!!! VERSION SWITCHES SET INCORECTLY !!!!!!!!! 50 <4> %warning out: !!!!!!!!! CHECK SETTINGS IN INC\VERSION.INC !!!!!!!!! 51 <4> %ENDIF 52 <4> %ENDIF 53 <4> ; 54 <4> ; 55 <4> ;*************************************************************************** 56 <4> ;* The following switches are for DBCS or SBCS support * 57 <4> ;* * 58 <4> ;* Set INTERNAT EQU TRUE FOR DBCS * 59 <4> ;* Set INTERNAT EQU FALSE FOR SBCS * 60 <4> ;* * 61 <4> ;*************************************************************************** 62 <4> ; 63 <4> IBMJAPVER EQU FALSE ;If TRUE set KANJI true also 64 <4> 65 <4> ; 66 <4> ; Switch INTERNAT for DBCS support 67 <4> ; 68 <4> INTERNAT EQU FALSE 69 <4> ; 70 <4> %IF INTERNAT 71 <4> %ifndef KANJI 72 <4> KANJI EQU TRUE 73 <4> %endif 74 <4> IBMJAPAN EQU TRUE 75 <4> %ELSE 76 <4> %ifndef KANJI 77 <4> KANJI EQU FALSE 78 <4> %endif 79 <4> IBMJAPAN EQU FALSE 80 <4> %ENDIF 81 <4> 82 <4> %ifndef altvect ; avoid jerking off vector.inc 83 <4> ALTVECT EQU FALSE ;Switch to build ALTVECT version 84 <4> %endif 85 <4> 86 <4> ; 87 <4> ; Country code switches 88 <4> ; The default contry code is assumed as USA. 89 <4> ; 90 <4> %IF INTERNAT 91 <4> KOREA EQU TRUE 92 <4> JAPAN EQU FALSE 93 <4> %ELSE 94 <4> KOREA EQU FALSE 95 <4> JAPAN EQU FALSE 96 <4> %ENDIF 97 <4> ; 98 <4> %IF INTERNAT 99 <4> %warning out: Internat(ECS) version build switch on 100 <4> %ENDIF 3 <3> 4 <3> SysInitVars STRUC 0 00000D12 ???????? SYSI_DPB DD ? ; DPB chain 0 00000D16 ???????? SYSI_SFT DD ? ; SFT chain 0 00000D1A ???????? SYSI_CLOCK DD ? ; CLOCK device 0 00000D1E ???????? SYSI_CON DD ? ; CON device 0 00000D22 ???? SYSI_MAXSEC DW ? ; maximum sector size 0 00000D24 ???????? SYSI_BUF DD ? ; points to Hashinitvar 0 00000D28 ???????? SYSI_CDS DD ? ; CDS list 0 00000D2C ???????? SYSI_FCB DD ? ; FCB chain 0 00000D30 ???? SYSI_Keep DW ? ; keep count 0 00000D32 ?? SYSI_NUMIO DB ? ; Number of block devices 0 00000D33 ?? SYSI_NCDS DB ? ; number of CDS's 0 00000D34 ???????? SYSI_DEV DD ? ; device list 0 00000D38 ???? SYSI_ATTR DW ? ; null device attribute word 0 00000D3A ???? SYSI_STRAT DW ? ; null device strategy entry point 0 00000D3C ???? SYSI_INTER DW ? ; null device interrupt entry point 0 00000D3E ???????????????? SYSI_NAME DB 8 DUP(?) ; null device name 0 00000D46 ?? SYSI_SPLICE DB ? ; TRUE -> splicees being done 0 00000D47 ???? SYSI_IBMDOS_SIZE DW ? ; DOS size in paragraphs 0 00000D49 ???????? SYSI_IFS_DOSCALL@ DD ? ; IFS DOS service rountine entry 0 00000D4D ???????? SYSI_IFS DD ? ; IFS header chain 0 00000D51 ???????? SYSI_BUFFERS DW ?,? ; BUFFERS= values (m,n) 0 00000D55 ?? SYSI_BOOT_DRIVE DB ? ; boot drive A=1 B=2,.. 0 00000D56 ?? SYSI_DWMOVE DB ? ; 1 if 386 machine 0 00000D57 ???? SYSI_EXT_MEM DW ? ; Extended memory size in KB. 29 <3> SysInitVars ENDS 30 <3> 31 <3> ;This is added for more information exchage between DOS, BIOS. 32 <3> ;DOS will give the pointer to SysInitTable in ES:DI. - J.K. 5/29/86 33 <3> SysInitVars_Ext struc 0 00000D12 ???????? SYSI_InitVars DD ? ; Points to the above structure. 0 00000D16 ???????? SYSI_Country_Tab DD ? ; DOS_Country_cdpg_info 36 <3> SysInitVars_Ext ends 37 <3> 38 <3> ;The SYSI_BUF of SysInitVars points to the follwong structure 39 <3> EMS_MAP_BUFF_SIZE EQU 12 ; EMS map buffer size 40 <3> 41 <3> Buffinfo STRUC 0 00000D12 ???????? Hash_ptr DD ? ; pointer to Hash table 0 00000D16 ???? Hash_count DW ? ; number of Hash entries 0 00000D18 ???????? Cache_ptr DD ? ; pointer to secondary cache 0 00000D1C ???? Cache_count DW ? ; number of secondary cache entries 46 <3> 47 <3> %IF BUFFERFLAG 48 <3> 0 00000D1E ?? EMS_SAFE_FLAG DB ? 0 00000D1F ???????? EMS_LAST_PAGE DW ?, ? 0 00000D23 ???????? EMS_FIRST_PAGE DW ?, ? 0 00000D27 ???? EMS_NPA640 DW ? 53 <3> 54 <3> %ENDIF 55 <3> 0 00000D29 ?? EMS_mode DB ? ; no EMS = -1 0 00000D2A ???? EMS_handle DW ? ; EMS handle for buffers 0 00000D2C ???? EMS_PageFrame_Number DW ? ; EMS page frame number 0 00000D2E ???? EMS_Seg_Cnt DW ? ; EMS segment count 0 00000D30 ???? EMS_Page_Frame DW ? ; EMS page frame segment address 0 00000D32 ???? EMS_reserved DW ? ; EMS segment count 62 <3> 63 <3> %IF BUFFERFLAG 0 00000D34 ?? EMS_Map_Buff DB ? ; map buffer 65 <3> %ELSE 66 <3> EMS_Map_Buff DB 12 dup(?) 67 <3> %ENDIF 68 <3> 69 <3> Buffinfo ENDS 70 <3> 71 <3> 72 <3> 73 <3> 74 <3> 75 <3> 76 <3> 77 <3> 94 <2> 95 <2> %include "vector.mac" 1 <3> ; SCCSID = @(#)vector.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ;Asmvar AltVect 5 <3> %ifndef AltVect 6 <3> %iassign AltVect 0 7 <3> %endif 8 <3> 9 <3> INTTAB EQU 20H 10 <3> inttab equ INTTAB ; NASM port equate 11 <3> INTBASE EQU 4 * inttab 12 <3> ENTRYPOINT EQU INTBASE+40H 13 <3> 14 <3> %IF ALTVECT 15 <3> ALTTAB EQU 0F0H 16 <3> ALTBASE EQU 4 * ALTTAB 17 <3> %ENDIF 18 <3> 19 <3> ; 20 <3> ; interrupt assignments 21 <3> ; 22 <3> %IFN ALTVECT 23 <3> int_abort EQU INTTAB ; abort process 24 <3> int_command EQU int_abort+1 ; call MSDOS 25 <3> int_terminate EQU int_abort+2 ; int to terminate address 26 <3> int_ctrl_c EQU int_abort+3 ; ^c trapper 27 <3> int_fatal_abort EQU int_abort+4 ; hard disk error 28 <3> int_disk_read EQU int_abort+5 ; logical sector disk read 29 <3> int_disk_write EQU int_abort+6 ; logical sector disk write 30 <3> int_keep_process EQU int_abort+7 ; terminate program and stay 31 <3> ; resident 32 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ; ; 35 <3> int_spooler EQU int_abort+8 ; spooler call 36 <3> int_fastcon EQU int_abort+9 ; fast CON interrupt 37 <3> int_IBM EQU int_abort+10; critical section maintenance 38 <3> ; ; 39 <3> ; C A V E A T P R O G R A M M E R ; 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> %ELSE 42 <3> int_abort EQU INTTAB ; abort process 43 <3> int_command EQU int_abort+1 ; call MSDOS 44 <3> int_terminate EQU ALTTAB ; int to terminate address 45 <3> int_ctrl_c EQU int_terminate+1 ; ^c trapper 46 <3> int_fatal_abort EQU int_terminate+2 ; hard disk error 47 <3> int_disk_read EQU int_abort+5 ; logical sector disk read 48 <3> int_disk_write EQU int_abort+6 ; logical sector disk write 49 <3> int_keep_process EQU int_abort+7 ; terminate program and stay resident 50 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 51 <3> ; C A V E A T P R O G R A M M E R ; 52 <3> ; ; 53 <3> int_spooler EQU int_terminate+3 ; spooler call 54 <3> int_fastcon EQU int_abort+9 ; fast CON interrupt 55 <3> ; ; 56 <3> ; C A V E A T P R O G R A M M E R ; 57 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <3> %ENDIF 59 <3> 60 <3> addr_int_abort EQU 4 * int_abort 61 <3> addr_int_command EQU 4 * int_command 62 <3> addr_int_terminate EQU 4 * int_terminate 63 <3> addr_int_ctrl_c EQU 4 * int_ctrl_c 64 <3> addr_int_fatal_abort EQU 4 * int_fatal_abort 65 <3> addr_int_disk_read EQU 4 * int_disk_read 66 <3> addr_int_disk_write EQU 4 * int_disk_write 67 <3> addr_int_keep_process EQU 4 * int_keep_process 68 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 69 <3> ; C A V E A T P R O G R A M M E R ; 70 <3> ; ; 71 <3> addr_int_spooler EQU 4 * int_spooler 72 <3> addr_int_fastcon EQU 4 * int_fastcon 73 <3> addr_int_IBM EQU 4 * int_IBM 74 <3> ; ; 75 <3> ; C A V E A T P R O G R A M M E R ; 76 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 96 <2> 97 <2> %include "mult.mac" 1 <3> ; SCCSID = @(#)mult.asm 1.2 85/04/12 2 <3> Break 3 <3> 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; Critical section definitions 8 <3> ; 9 <3> ; These below are subject to leave-all sections 10 <3> critDisk EQU 1 ; Disk I/O critical section 11 <3> critDevice EQU 2 ; Device I/O critical section 12 <3> critShare EQU 1 ; Sharer I/O critical section 13 <3> critMem EQU 1 ; memory maintenance critical section 14 <3> critNet EQU 5 ; network critical section 15 <3> critSFT EQU 1 ; sft table allocation 16 <3> critIFS EQU 6 ; ifsfunc critical section 17 <3> ; These below are not subject to leave-all sections 18 <3> critASSIGN EQU 8 ; Assign has munged a system call 19 <3> ; ; 20 <3> ; C A V E A T P R O G R A M M E R ; 21 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 22 <3> 23 <3> ; 24 <3> ; The current set of defined multiplex channels is (* means documented): 25 <3> ; 26 <3> ; Channel(h) Issuer Receiver Function 27 <3> ; 00 server PSPRINT print job control 28 <3> ; *01 print/apps PRINT Queueing of files 29 <3> ; 02 BIOS REDIR signal open/close of printers 30 <3> ; 31 <3> ; 05 command REDIR obtain text of net int 24 message 32 <3> ; *06 server/assign ASSIGN Install check 33 <3> ; 34 <3> ; 08 external driver IBMBIO interface to internal routines 35 <3> ; 36 <3> ; 10 sharer/server Sharer install check 37 <3> ; 11 DOS/server Redir install check/redirection funcs 38 <3> ; 12 sharer/redir DOS dos functions and structure maint 39 <3> ; 13 MSNET MSNET movement of NCBs 40 <3> ; 13 external driver IBMBIO Reset_Int_13, allows installation 41 <3> ; of alternative INT_13 drivers after 42 <3> ; boot_up 43 <3> ; 14 (IBM) DOS NLSFUNC down load NLS country info,DOS 3.3 44 <3> ; 14 (MS) APPS POPUP MSDOS 4 popup screen functions 45 <3> ; 15 APPS MSCDEX CD-ROM extensions interface 46 <3> ; 16 WIN386 WIN386 Windows communications 47 <3> ; 17 Clipboard WINDOWS Clipboard interface 48 <3> ; *18 Applications MS-Manger Toggle interface to manager 49 <3> ; 19 Shell 50 <3> ; 1A Ansi.sys 51 <3> ; 1B Fastopen,Vdisk IBMBIO EMS INT 67H stub handler 52 <3> ; 53 <3> ; AC Graphics 54 <3> ; AD NLS (toronto) 55 <3> ; AE 56 <3> ; AF Mode 57 <3> ; B0 GRAFTABL GRAFTABL 58 <3> ; 59 <3> 60 <3> 61 <3> ;MUX 00-3F reserverd for IBM 62 <3> ;MUX 80-BF reserverd for IBM 63 <3> ;MUX 40-7F reserved for Microsoft 64 <3> ;MUX C0-FF users 65 <3> 66 <3> 67 <3> 68 <3> MultSHARE EQU 10h ; sharer 69 <3> ; 1 MFT_enter 70 <3> ; 2 MFTClose 71 <3> ; 3 MFTclU 72 <3> ; 4 MFTCloseP 73 <3> ; 5 MFTCloN 74 <3> ; 6 set_block 75 <3> ; 7 clr_block 76 <3> ; 8 chk_block 77 <3> ; 9 MFT_get 78 <3> ; 10 ShSave 79 <3> ; 11 ShChk 80 <3> ; 12 ShCol 81 <3> ; 13 ShCloseFile 82 <3> 83 <3> MultNET EQU 11h ; Network support 84 <3> MultIFS EQU 11h ; Network support 85 <3> ; 1 IFS_RMDIR 86 <3> ; 2 IFS_SEQ_RMDIR 87 <3> ; 3 IFS_MKDIR 88 <3> ; 4 IFS_SEQ_MKDIR 89 <3> ; 5 IFS_CHDIR 90 <3> ; 6 IFS_CLOSE 91 <3> ; 7 IFS_COMMIT 92 <3> ; 8 IFS_READ 93 <3> ; 9 IFS_WRITE 94 <3> ; 10 IFS_LOCK 95 <3> ; 11 IFS_UNLOCK 96 <3> ; 12 IFS_DISK_INFO 97 <3> ; 13 IFS_SET_FILE_ATTRIBUTE 98 <3> ; 14 IFS_SEQ_SET_FILE_ATTRIBUTE 99 <3> ; 15 IFS_GET_FILE_INFO 100 <3> ; 16 IFS_SEQ_GET_FILE_INFO 101 <3> ; 17 IFS_RENAME 102 <3> ; 18 IFS_SEQ_RENAME 103 <3> ; 19 IFS_DELETE 104 <3> ; 20 IFS_SEQ_DELETE 105 <3> ; 21 IFS_OPEN 106 <3> ; 22 IFS_SEQ_OPEN 107 <3> ; 23 IFS_CREATE 108 <3> ; 24 IFS_SEQ_CREATE 109 <3> ; 25 IFS_SEQ_SEARCH_FIRST 110 <3> ; 26 IFS_SEQ_SEARCH_NEXT 111 <3> ; 27 IFS_SEARCH_FIRST 112 <3> ; 28 IFS_SEARCH_NEXT 113 <3> ; 29 IFS_ABORT 114 <3> ; 30 IFS_ASSOPER 115 <3> ; 31 Printer_SET_STRING 116 <3> ; 32 IFSFlushBuf 117 <3> ; 33 IFSBufWrite 118 <3> ; 34 IFSResetEnvironment 119 <3> ; 35 IFSSpoolCheck 120 <3> ; 36 IFSSpoolClose 121 <3> 122 <3> MultDOS EQU 12h ; DOS call back 123 <3> ; 1 DOS_CLOSE 124 <3> ; 2 RECSET 125 <3> ; 3 Get DOSGROUP 126 <3> ; 4 PATHCHRCMP 127 <3> ; 5 OUT 128 <3> ; 6 NET_I24_ENTRY 129 <3> ; 7 PLACEBUF 130 <3> ; 8 FREE_SFT 131 <3> ; 9 BUFWRITE 132 <3> ; 10 SHARE_VIOLATION 133 <3> ; 11 SHARE_ERROR 134 <3> ; 12 SET_SFT_MODE 135 <3> ; 13 DATE16 136 <3> ; 14 SETVISIT 137 <3> ; 15 SCANPLACE 138 <3> ; 16 SKIPVISIT 139 <3> ; 17 StrCpy 140 <3> ; 18 StrLen 141 <3> ; 19 Ucase 142 <3> ; 20 POINTCOMP 143 <3> ; 21 CHECKFLUSH 144 <3> ; 22 SFFromSFN 145 <3> ; 23 GetCDSFromDrv 146 <3> ; 24 Get_User_Stack 147 <3> ; 25 GetThisDrv 148 <3> ; 26 DriveFromText 149 <3> ; 27 SETYEAR 150 <3> ; 28 DSUM 151 <3> ; 29 DSLIDE 152 <3> ; 30 StrCmp 153 <3> ; 31 initcds 154 <3> ; 32 pjfnfromhandle 155 <3> ; 33 $NameTrans 156 <3> ; 34 CAL_LK 157 <3> ; 35 DEVNAME 158 <3> ; 36 Idle 159 <3> ; 37 DStrLen 160 <3> ; 38 NLS_OPEN DOS 3.3 161 <3> ; 39 $CLOSE DOS 3.3 162 <3> ; 40 NLS_LSEEK DOS 3.3 163 <3> ; 41 $READ DOS 3.3 164 <3> ; 42 FastInit DOS 4.0 165 <3> ; 43 NLS_IOCTL DOS 3.3 166 <3> ; 44 GetDevList DOS 3.3 167 <3> ; 45 NLS_GETEXT DOS 3.3 168 <3> ; 46 MSG_RETRIEVAL DOS 4.0 169 <3> ; 47 FAKE_VERSION DOS 4.0 170 <3> ; 171 <3> NLSFUNC EQU 14h ; NLSFUNC CALL , DOS 3.3 172 <3> ; 0 NLSInstall 173 <3> ; 1 ChgCodePage 174 <3> ; 2 GetExtInfo 175 <3> ; 3 SetCodePage 176 <3> ; 4 GetCntry 177 <3> ; 178 <3> ;FASTOPEN is not chained through INT 2F ; DOS 3.3 F.C. 179 <3> ; it calls Multdos 42 to set up an entry routine address 180 <3> ; 0 Install status (reserved) 181 <3> ; 1 Lookup 182 <3> ; 2 Insert 183 <3> ; 3 Delete 184 <3> ; 4 Purge (reserved) 98 <2> 99 <2> BREAK 100 <2> ; MSDOS partitions the disk into 4 sections: 101 <2> ; 102 <2> ; phys sector 0: +-------------------+ 103 <2> ; | | boot/reserved | 104 <2> ; | +-------------------+ 105 <2> ; | | File allocation | 106 <2> ; v | table(s) | 107 <2> ; | (multiple copies | 108 <2> ; | are kept) | 109 <2> ; +-------------------+ 110 <2> ; | Directory | 111 <2> ; +-------------------+ 112 <2> ; | File space | 113 <2> ; +-------------------+ 114 <2> ; | Unaddressable | 115 <2> ; | (to end of disk) | 116 <2> ; +-------------------+ 117 <2> ; 118 <2> ; All partition boundaries are sector boundaries. The size of the FAT is 119 <2> ; adjusted to maximize the file space addressable. 120 <2> 121 <2> %include "dirent.mac" 1 <3> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 3 <3> Break 4 <3> 5 <3> ; 6 <3> ; +---------------------------+ 7 <3> ; | (12 BYTE) filename/ext | 0 0 8 <3> ; +---------------------------+ 9 <3> ; | (BYTE) attributes | 11 B 10 <3> ; +---------------------------+ 11 <3> ; | (10 BYTE) reserved | 12 C 12 <3> ; +---------------------------+ 13 <3> ; | (WORD) time of last write | 22 16 14 <3> ; +---------------------------+ 15 <3> ; | (WORD) date of last write | 24 18 16 <3> ; +---------------------------+ 17 <3> ; | (WORD) First cluster | 26 1A 18 <3> ; +---------------------------+ 19 <3> ; | (DWORD) file size | 28 1C 20 <3> ; +---------------------------+ 21 <3> ; 22 <3> ; First byte of filename = E5 -> free directory entry 23 <3> ; = 00 -> end of allocated directory 24 <3> ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour 25 <3> ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 26 <3> ; 27 <3> 28 <3> dir_entry STRUC 0 00000D12 ?????????????????? dir_name DB 11 DUP (?) ; file name 29 00000009 ???? <3> 0 00000D1D ?? dir_attr DB ? ; attribute bits 0 00000D1E ???? dir_codepg dw ? ; code page DOS 4.00 0 00000D20 ???? dir_extcluster dw ? ; extended attribute starting cluster 0 00000D22 ?? dir_attr2 db ? ; reserved 0 00000D23 ?????????? dir_pad DB 5 DUP (?) ; reserved for expansion 0 00000D28 ???? dir_time DW ? ; time of last write 0 00000D2A ???? dir_date DW ? ; date of last write 0 00000D2C ???? dir_first DW ? ; first allocation unit of file 0 00000D2E ???? dir_size_l DW ? ; low 16 bits of file size 0 00000D30 ???? dir_size_h DW ? ; high 16 bits of file size 40 <3> dir_entry ENDS 41 <3> 42 <3> attr_read_only EQU 1h 43 <3> attr_hidden EQU 2h 44 <3> attr_system EQU 4h 45 <3> attr_volume_id EQU 8h 46 <3> attr_directory EQU 10h 47 <3> attr_archive EQU 20h 48 <3> attr_device EQU 40h ; This is a VERY special bit. 49 <3> ; NO directory entry on a disk EVER 50 <3> ; has this bit set. It is set non-zero 51 <3> ; when a device is found by GETPATH 52 <3> 53 <3> attr_all EQU attr_hidden+attr_system+attr_directory 54 <3> ; OR of hard attributes for FINDENTRY 55 <3> 56 <3> attr_ignore EQU attr_read_only+attr_archive+attr_device 57 <3> ; ignore this(ese) attribute(s) during 58 <3> ; search first/next 59 <3> 60 <3> attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive 61 <3> ; changeable via CHMOD 122 <2> 123 <2> BREAK 124 <2> ; 125 <2> ; The File Allocation Table uses a 12-bit entry for each allocation unit on 126 <2> ; the disk. These entries are packed, two for every three bytes. The contents 127 <2> ; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result 128 <2> ; to the base address of the Allocation Table; 3) fetching the 16-bit word 129 <2> ; at this address; 4) If N was odd (so that N*1.5 was not an integer), shift 130 <2> ; the word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry 131 <2> ; number zero is used as an end-of-file trap in the OS and is passed to the 132 <2> ; BIOS to help determine disk format. Entry 1 is reserved for future use. 133 <2> ; The first available allocation unit is assigned entry number two, and even 134 <2> ; though it is the first, is called cluster 2. Entries greater than 0FF8H 135 <2> ; (12-bit fats) or 0FFF8H (16-bit fats) are end of file marks; entries of zero 136 <2> ; are unallocated. Otherwise, the contents of a FAT entry is the number of 137 <2> ; the next cluster in the file. 138 <2> ; 139 <2> ; Clusters with bad sectors are tagged with FF7H. Any non-zero number would 140 <2> ; do because these clusters show as allocated, but are not part of any 141 <2> ; allocation chain and thus will never be allocated to a file. A particular 142 <2> ; number is selected so that disk checking programs know what to do (ie. a 143 <2> ; cluster with entry FF7H which is not in a chain is not an error). 144 <2> 145 <2> %include "dpb.mac" 1 <3> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> dpb STRUC 0 00000D12 ?? dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) 0 00000D13 ?? dpb_UNIT DB ? ; Driver unit number of DPB 0 00000D14 ???? dpb_sector_size DW ? ; Size of physical sector in bytes 0 00000D16 ?? dpb_cluster_mask DB ? ; Sectors/cluster - 1 0 00000D17 ?? dpb_cluster_shift DB ? ; Log2 of sectors/cluster 0 00000D18 ???? dpb_first_FAT DW ? ; Starting record of FATs 0 00000D1A ?? dpb_FAT_count DB ? ; Number of FATs for this drive 0 00000D1B ???? dpb_root_entries DW ? ; Number of directory entries 0 00000D1D ???? dpb_first_sector DW ? ; First sector of first cluster 0 00000D1F ???? dpb_max_cluster DW ? ; Number of clusters on drive + 1 0 00000D21 ???? dpb_FAT_size DW ? ;;Number of records occupied by FAT 0 00000D23 ???? dpb_dir_sector DW ? ; Starting record of directory 0 00000D25 ???????? dpb_driver_addr DD ? ; Pointer to driver 0 00000D29 ?? dpb_media DB ? ; Media byte 0 00000D2A ?? dpb_first_access DB ? ; This is initialized to -1 to force a media 23 <3> ; check the first time this DPB is used 0 00000D2B ???????? dpb_next_dpb DD ? ; Pointer to next Drive parameter block 0 00000D2F ???? dpb_next_free DW ? ; Cluster # of last allocated cluster 0 00000D31 ???? dpb_free_cnt DW ? ; Count of free clusters, -1 if unknown 27 <3> dpb ENDS 28 <3> 29 <3> DPBSIZ EQU dpb_struc_size ; Size of the structure in bytes 30 <3> 31 <3> DSKSIZ equ dpb_max_cluster ; Size of disk (temp used during init only) 32 <3> ; ; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 146 <2> 147 <2> %include "curdir.mac" 1 <3> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; CDS items are used bu the internal routines to store cluster numbers and ; 8 <3> ; network identifiers for each logical name. The ID field is used dually, ; 9 <3> ; both as net ID and for a cluster number for local devices. In the case ; 10 <3> ; of local devices, the cluster number will be -1 if there is a potential ; 11 <3> ; of the disk being changed or if the path must be recracked. The END ; 12 <3> ; field is the location of the end of the definition. No .. is allowed ; 13 <3> ; past this point ; 14 <3> 15 <3> DIRSTRLEN EQU 64+3 ; Max length in bytes of directory strings 16 <3> TEMPLEN EQU DIRSTRLEN*2 17 <3> 18 <3> curdir_list STRUC 0 00000D12 ?????????????????? curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 19 00000009 ??????????????????- <3> 19 00000012 ??????????????????- <3> 19 0000001B ??????????????????- <3> 19 00000024 ??????????????????- <3> 19 0000002D ??????????????????- <3> 19 00000036 ??????????????????- <3> 19 0000003F ???????? <3> 0 00000D55 ???? curdir_flags DW ? ; various flags 0 00000D57 ???????? curdir_devptr DD ? ; local pointer to DPB or net device 0 00000D5B ???? curdir_ID DW ? ; cluster of current dir (net ID) 0 00000D5D ???? DW ? 0 00000D5F ???? curdir_user_word DW ? 0 00000D61 ???? curdir_end DW ? ; end of assignment 0 00000D63 ?? curdir_type DB ? ; IFS drive (2=ifs, 4=netuse) 0 00000D64 ???????? curdir_ifs_hdr DD ? ; Ptr to File System Header 0 00000D68 ???? curdir_fsda DB 2 DUP (?) ; File System Dependent Data Area 29 <3> curdir_list ENDS 30 <3> 31 <3> curdirLen EQU curdir_list_struc_size ; Needed for screwed up 32 <3> ; ASM87 which doesn't allow 33 <3> ; Size directive as a macro 34 <3> ; argument 35 <3> labelsize curdir_netID, dword, curdir_ID 36 <3> 37 <3> ;Flag word masks 38 <3> curdir_isnet EQU 1000000000000000B 39 <3> curdir_isifs EQU 1000000000000000B ; DOS 4.00 40 <3> curdir_inuse EQU 0100000000000000B 41 <3> curdir_splice EQU 0010000000000000B 42 <3> curdir_local EQU 0001000000000000B 43 <3> ; ; 44 <3> ; C A V E A T P R O G R A M M E R ; 45 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 148 <2> 149 <2> %include "cpmfcb.mac" 1 <3> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)cpmfcb.asm 1.1 85/04/10 3 <3> ;BREAK 4 <3> 5 <3> ; 6 <3> ; Field definition for FCBs 7 <3> ; The FCB has the following structure: 8 <3> ; 9 <3> ; +---------------------------+ 10 <3> ; | Drive indicator(byte) | 11 <3> ; +---------------------------+ 12 <3> ; | Filename (8 chars) | 13 <3> ; +---------------------------+ 14 <3> ; | Extension (3 chars) | 15 <3> ; +---------------------------+ 16 <3> ; | Current Extent(word) | 17 <3> ; +---------------------------+ 18 <3> ; | Record size (word) | 19 <3> ; +---------------------------+ 20 <3> ; | File Size (2 words) | 21 <3> ; +---------------------------+ 22 <3> ; | Date of write | 23 <3> ; +---------------------------+ 24 <3> ; | Time of write | 25 <3> ; +---------------------------+ 26 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 27 <3> ; C A V E A T P R O G R A M M E R ; 28 <3> ; ; 29 <3> ; +---------------------------+ 30 <3> ; | 8 bytes reserved | 31 <3> ; +---------------------------+ 32 <3> ; ; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 35 <3> ; | next record number | 36 <3> ; +---------------------------+ 37 <3> ; | random record number | 38 <3> ; +---------------------------+ 39 <3> ; 40 <3> 41 <3> sys_fcb STRUC 0 00000D12 ?? fcb_drive DB ? 0 00000D13 ???????????????? fcb_name DB 8 DUP (?) 0 00000D1B ?????? fcb_ext DB 3 DUP (?) 0 00000D1E ???? fcb_EXTENT DW ? 0 00000D20 ???? fcb_RECSIZ DW ? ; Size of record (user settable) 0 00000D22 ???? fcb_FILSIZ DW ? ; Size of file in bytes; used with the 48 <3> ; following word 0 00000D24 ???? fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT 0 00000D26 ???? fcb_FDATE DW ? ; Date of last writing 0 00000D28 ???? fcb_FTIME DW ? ; Time of last writing 52 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 53 <3> ; C A V E A T P R O G R A M M E R ; 54 <3> ; ; 0 00000D2A ???????????????? fcb_reserved DB 8 DUP (?) ; RESERVED 56 <3> ; ; 57 <3> ; C A V E A T P R O G R A M M E R ; 58 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D32 ?? fcb_NR DB ? ; Next record 0 00000D33 ???????? fcb_RR DB 4 DUP (?) ; Random record 61 <3> sys_fcb ENDS 62 <3> 63 <3> FILDIRENT equ fcb_FILSIZ ; Used only by SEARCH FIRST and SEARCH 64 <3> ; NEXT 65 <3> 66 <3> labelsize fcb_sfn, byte, fcb_reserved 67 <3> 68 <3> ; Note that fcb_net_handle, fcb_nsl_drive, fcb_nsld_drive and fcb_l_drive 69 <3> ; all must point to the same byte. Otherwise, the FCBRegen will fail. 70 <3> ; NOTE about this byte (fcb_nsl_drive) 71 <3> ; The high two bits of this byte are used as follows to indicate the FCB type 72 <3> ; 00 means a local file or device with sharing loaded 73 <3> ; 10 means a remote (network) file 74 <3> ; 01 means a local file with no sharing loaded 75 <3> ; 11 means a local device with no sharing loaded 76 <3> 77 <3> ; 78 <3> ; Network FCB 79 <3> ; 80 <3> labelsize fcb_net_drive, byte, fcb_reserved+1 81 <3> labelsize fcb_net_handle, word, fcb_reserved+2 82 <3> labelsize fcb_netID, dword, fcb_reserved+4 83 <3> 84 <3> ; 85 <3> ; No sharing local file FCB 86 <3> ; 87 <3> labelsize fcb_nsl_drive, byte, fcb_reserved+1 88 <3> labelsize fcb_nsl_bits, byte, fcb_reserved+2 89 <3> labelsize fcb_nsl_firclus, word, fcb_reserved+3 90 <3> labelsize fcb_nsl_dirsec, word, fcb_reserved+5 91 <3> labelsize fcb_nsl_dirpos, byte, fcb_reserved+7 92 <3> 93 <3> ; 94 <3> ; No sharing local device FCB 95 <3> ; 96 <3> labelsize fcb_nsld_drive, byte, fcb_reserved+1 97 <3> labelsize fcb_nsld_drvptr, dword, fcb_reserved+2 98 <3> 99 <3> ; 100 <3> ; Sharing local FCB 101 <3> ; 102 <3> labelsize fcb_l_drive, byte, fcb_reserved+1 103 <3> labelsize fcb_l_firclus, word, fcb_reserved+2 104 <3> labelsize fcb_l_mfs, word, fcb_reserved+4 105 <3> labelsize fcb_l_attr, byte, fcb_reserved+6 106 <3> 107 <3> ; 108 <3> ; Bogusness: the four cases are: 109 <3> ; 110 <3> ; local file 00 111 <3> ; local device 40 112 <3> ; local sharing C0 113 <3> ; network 80 114 <3> ; 115 <3> ; Since sharing and network collide, we cannot use a test instruction for 116 <3> ; deciding whether a network or a share check in involved 117 <3> ; 118 <3> FCBDEVICE EQU 040h 119 <3> FCBNETWORK EQU 080h 120 <3> FCBSHARE EQU 0C0h 121 <3> 122 <3> ; FCBSPECIAL must be able to mask off both net and share 123 <3> FCBSPECIAL EQU 080h 124 <3> FCBMASK EQU 0C0h 150 <2> 151 <2> %include "find.mac" 1 <3> ; SCCSID = @(#)find.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)find.asm 1.1 85/04/10 3 <3> Break 4 <3> 5 <3> find_buf STRUC 6 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 7 <3> ; C A V E A T P R O G R A M M E R ; 8 <3> ; ; 0 00000D12 ?? find_buf_drive DB ? ; drive of search 0 00000D13 ?????????????????? find_buf_name DB 11 DUP (?) ; formatted name 10 0000000A ???? <3> 0 00000D1E ?? find_buf_sattr DB ? ; attribute of search 0 00000D1F ???? find_buf_LastEnt DW ? ; LastEnt 0 00000D21 ???? find_buf_DirStart DW ? ; DirStart 0 00000D23 ???????? find_buf_NetID DB 4 DUP (?) ; Reserved for NET 15 <3> ; ; 16 <3> ; C A V E A T P R O G R A M M E R ; 17 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 18 <3> 0 00000D27 ?? find_buf_attr DB ? ; attribute found 0 00000D28 ???? find_buf_time DW ? ; time 0 00000D2A ???? find_buf_date DW ? ; date 0 00000D2C ???? find_buf_size_l DW ? ; low(size) 0 00000D2E ???? find_buf_size_h DW ? ; high(size) 0 00000D30 ?????????????????? find_buf_pname DB 13 DUP (?) ; packed name 24 00000027 ???????? <3> 25 <3> find_buf ENDS 152 <2> 153 <2> %include "pdb.mac" 1 <3> ; SCCSID = @(#)pdb.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ; 5 <3> ; Process data block (otherwise known as program header) 6 <3> ; 7 <3> 8 <3> FilPerProc EQU 20 9 <3> 10 <3> Process_data_block STRUC 0 00000D12 ???? PDB_Exit_Call DW ? ; INT int_abort system terminate 0 00000D14 ???? PDB_block_len DW ? ; size of execution block 0 00000D16 ?? DB ? 0 00000D17 ?????????? PDB_CPM_Call DB 5 DUP (?) ; ancient call to system 0 00000D1C ???????? PDB_Exit DD ? ; pointer to exit routine 0 00000D20 ???????? PDB_Ctrl_C DD ? ; pointer to ^C routine 0 00000D24 ???????? PDB_Fatal_abort DD ? ; pointer to fatal error 18 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 19 <3> ; C A V E A T P R O G R A M M E R ; 20 <3> ; ; 0 00000D28 ???? PDB_Parent_PID DW ? ; PID of parent (terminate PID) 0 00000D2A ?????????????????? PDB_JFN_Table DB FilPerProc DUP (?) 22 00000021 ??????????????????- <3> 22 0000002A ???? <3> 23 <3> ; indices into system table 24 <3> ; ; 25 <3> ; C A V E A T P R O G R A M M E R ; 26 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D3E ???? PDB_environ DW ? ; seg addr of environment 28 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 29 <3> ; C A V E A T P R O G R A M M E R ; 30 <3> ; ; 0 00000D40 ???????? PDB_User_stack DD ? ; stack of self during system calls 0 00000D44 ???? PDB_JFN_Length DW ? ; number of handles allowed 0 00000D46 ???????? PDB_JFN_Pointer DD ? ; pointer to JFN table 0 00000D4A ???????? PDB_Next_PDB DD ? ; pointer to nested PDB's 0 00000D4E ?????????????????? PDB_PAD1 DB 14h DUP (?) 35 00000045 ??????????????????- <3> 35 0000004E ???? <3> 36 <3> ; ; 37 <3> ; C A V E A T P R O G R A M M E R ; 38 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D62 ?????????? PDB_Call_system DB 5 DUP (?) ; portable method of system call 40 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <3> ; C A V E A T P R O G R A M M E R ; 42 <3> ; ; 0 00000D67 ?????????????? PDB_PAD2 DB 7h DUP (?) 44 <3> ; ; 45 <3> ; C A V E A T P R O G R A M M E R ; 46 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 47 <3> Process_data_block ENDS 48 <3> 49 <3> labelsize PDB_InterCon, byte, PDB_PAD1 ; 2/12/KK 50 <3> labelsize PDB_Append, byte, PDB_PAD1+1 ; 2/12/KK 154 <2> 155 <2> %include "exe.mac" 1 <3> ; SCCSID = @(#)exe.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)exe.asm 1.1 85/04/10 3 <3> BREAK 4 <3> ; 5 <3> ; EXEC arg block - load/go program 6 <3> ; 7 <3> 8 <3> ; 9 <3> ; The following get used as arguments to the EXEC system call. They indicate 10 <3> ; whether or not the program is executed or whether or not a program header 11 <3> ; gets created. 12 <3> ; 13 <3> exec_func_no_execute EQU 1 ; no execute bit 14 <3> exec_func_overlay EQU 2 ; overlay bit 15 <3> 16 <3> Exec0 STRUC 0 00000D12 ???? Exec0_environ DW ? ; seg addr of environment 0 00000D14 ???????? Exec0_com_line DD ? ; pointer to asciz command line 0 00000D18 ???????? Exec0_5C_FCB DD ? ; default fcb at 5C 0 00000D1C ???????? Exec0_6C_FCB DD ? ; default fcb at 6C 21 <3> Exec0 ENDS 22 <3> 23 <3> Exec1 STRUC 0 00000D12 ???? Exec1_environ DW ? ; seg addr of environment 0 00000D14 ???????? Exec1_com_line DD ? ; pointer to asciz command line 0 00000D18 ???????? Exec1_5C_FCB DD ? ; default fcb at 5C 0 00000D1C ???????? Exec1_6C_FCB DD ? ; default fcb at 6C 0 00000D20 ???? Exec1_SP DW ? ; stack pointer of program 0 00000D22 ???? Exec1_SS DW ? ; stack seg register of program 0 00000D24 ???? Exec1_IP DW ? ; entry point IP 0 00000D26 ???? Exec1_CS DW ? ; entry point CS 32 <3> Exec1 ENDS 33 <3> 34 <3> Exec3 STRUC 0 00000D12 ???? Exec3_load_addr DW ? ; seg address of load point 0 00000D14 ???? Exec3_reloc_fac DW ? ; relocation factor 37 <3> Exec3 ENDS 38 <3> 39 <3> ; 40 <3> ; Exit codes in upper byte 41 <3> ; 42 <3> Exit_terminate EQU 0 43 <3> Exit_abort EQU 0 44 <3> Exit_Ctrl_C EQU 1 45 <3> Exit_Hard_Error EQU 2 46 <3> Exit_Keep_process EQU 3 47 <3> 48 <3> ; 49 <3> ; EXE file header 50 <3> ; 51 <3> 52 <3> EXE_file STRUC 0 00000D12 ???? exe_signature DW ? ; must contain 4D5A (yay zibo!) 0 00000D14 ???? exe_len_mod_512 DW ? ; low 9 bits of length 0 00000D16 ???? exe_pages DW ? ; number of 512b pages in file 0 00000D18 ???? exe_rle_count DW ? ; count of reloc entries 0 00000D1A ???? exe_par_dir DW ? ; number of paragraphs before image 0 00000D1C ???? exe_min_BSS DW ? ; minimum number of para of BSS 0 00000D1E ???? exe_max_BSS DW ? ; max number of para of BSS 0 00000D20 ???? exe_SS DW ? ; stack of image 0 00000D22 ???? exe_SP DW ? ; SP of image 0 00000D24 ???? exe_chksum DW ? ; checksum of file (ignored) 0 00000D26 ???? exe_IP DW ? ; IP of entry 0 00000D28 ???? exe_CS DW ? ; CS of entry 0 00000D2A ???? exe_rle_table DW ? ; byte offset of reloc table 0 00000D2C ???? exe_iov DW ? ; overlay number (0 for root) 0 00000D2E ???????? exe_sym_tab DD ? ; offset of symbol table in file 68 <3> EXE_file ENDS 69 <3> 70 <3> exe_valid_signature EQU 5A4Dh 71 <3> exe_valid_old_signature EQU 4D5Ah 72 <3> 73 <3> symbol_entry STRUC 0 00000D12 ???????? sym_value DD ? 0 00000D16 ???? sym_type DW ? 0 00000D18 ?? sym_len DB ? 0 00000D19 ?????????????????? sym_name DB 255 dup (?) 77 00000010 ??????????????????- <3> 77 00000019 ??????????????????- <3> 77 00000022 ??????????????????- <3> 77 0000002B ??????????????????- <3> 77 00000034 ??????????????????- <3> 77 0000003D ??????????????????- <3> 77 00000046 ??????????????????- <3> 77 0000004F ??????????????????- <3> 77 00000058 ??????????????????- <3> 77 00000061 ??????????????????- <3> 77 0000006A ??????????????????- <3> 77 00000073 ??????????????????- <3> 77 0000007C ??????????????????- <3> 77 00000085 ??????????????????- <3> 77 0000008E ??????????????????- <3> 77 00000097 ??????????????????- <3> 77 000000A0 ??????????????????- <3> 77 000000A9 ??????????????????- <3> 77 000000B2 ??????????????????- <3> 77 000000BB ??????????????????- <3> 77 000000C4 ??????????????????- <3> 77 000000CD ??????????????????- <3> 77 000000D6 ??????????????????- <3> 77 000000DF ??????????????????- <3> 77 000000E8 ??????????????????- <3> 77 000000F1 ??????????????????- <3> 77 000000FA ??????????????????- <3> 77 00000103 ?????? <3> 78 <3> symbol_entry ENDS 156 <2> 157 <2> %include "sf.mac" 1 <3> ; SCCSID = @(#)sf.asm 1.1 85/04/10 2 <3> BREAK 3 <3> ; 4 <3> ; AN000 version 4.00 Jan. 1988 5 <3> ; AN003 PTM 3680 -- make NAME offset the same as before (<=3.30) 6 <3> ; AN009 PTM 3839 reorder SFT for MS WINDOWS 7 <3> 8 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 9 <3> ; C A V E A T P R O G R A M M E R ; 10 <3> ; ; 11 <3> ; 12 <3> ; system file table 13 <3> ; 14 <3> 15 <3> SF STRUC 0 00000D12 ???????? SFLink DD ? 0 00000D16 ???? SFCount DW ? ; number of entries 0 00000D18 ???? SFTable DW ? ; beginning of array of the following 19 <3> SF ENDS 20 <3> 21 <3> ; 22 <3> ; system file table entry 23 <3> ; 24 <3> 25 <3> sf_entry STRUC 0 00000D12 ???? sf_ref_count DW ? ; number of processes sharing entry 27 <3> ; if FCB then ref count 0 00000D14 ???? sf_mode DW ? ; mode of access or high bit on if FCB 0 00000D16 ?? sf_attr DB ? ; attribute of file 0 00000D17 ???? sf_flags DW ? ;Bits 8-15 31 <3> ; Bit 15 = 1 if remote file 32 <3> ; = 0 if local file or device 33 <3> ; Bit 14 = 1 if date/time is not to be 34 <3> ; set from clock at CLOSE. Set by 35 <3> ; FILETIMES and FCB_CLOSE. Reset by 36 <3> ; other reseters of the dirty bit 37 <3> ; (WRITE) 38 <3> ; Bit 13 = Pipe bit (reserved) 39 <3> ; 40 <3> ; Bits 0-7 (old FCB_devid bits) 41 <3> ; If remote file or local file, bit 42 <3> ; 6=0 if dirty Device ID number, bits 43 <3> ; 0-5 if local file. 44 <3> ; bit 7=0 for local file, bit 7 45 <3> ; =1 for local I/O device 46 <3> ; If local I/O device, bit 6=0 if EOF (input) 47 <3> ; Bit 5=1 if Raw mode 48 <3> ; Bit 0=1 if console input device 49 <3> ; Bit 1=1 if console output device 50 <3> ; Bit 2=1 if null device 51 <3> ; Bit 3=1 if clock device 0 00000D19 ???????? sf_devptr DD ? ; Points to DPB if local file, points 53 <3> ; to device header if local device, 54 <3> ; points to net device header if 55 <3> ; remote 0 00000D1D ???? sf_firclus DW ? ; First cluster of file (bit 15 = 0) 0 00000D1F ???? sf_time DW ? ; Time associated with file 0 00000D21 ???? sf_date DW ? ; Date associated with file 0 00000D23 ???????? sf_size DD ? ; Size associated with file 0 00000D27 ???????? sf_position DD ? ; Read/Write pointer or LRU count for FCBs 61 <3> ; 62 <3> ; Starting here, the next 7 bytes may be used by the file system to store an 63 <3> ; ID 64 <3> ; 0 00000D2B ???? sf_cluspos DW ? ; Position of last cluster accessed 0 00000D2D ???????? sf_dirsec DD ? ; Sector number of directory sector for 67 <3> ; for this file 0 00000D31 ?? sf_dirpos DB ? ; Offset of this entry in the above 69 <3> ; 70 <3> ; End of 7 bytes of file-system specific info. 71 <3> ; 0 00000D32 ?????????????????? sf_name DB 11 DUP (?) ; 11 character name that is in the 72 00000029 ???? <3> 73 <3> ; directory entry. This is used by 74 <3> ; close to detect file deleted and 75 <3> ; disk changed errors. 76 <3> 77 <3> ; SHARING INFO 0 00000D3D ???????? sf_chain DD ? ; link to next SF 0 00000D41 ???? sf_UID DW ? 0 00000D43 ???? sf_PID DW ? 0 00000D45 ???? sf_MFT DW ? 0 00000D47 ???? sf_lstclus DW ? ;AN009; Last cluster accessed 0 00000D49 ???????? sf_IFS_HDR DD ? 84 <3> sf_entry ENDS 85 <3> 86 <3> labelsize sf_fsda, byte, sf_cluspos ;DOS 4.00 87 <3> labelsize sf_serial_ID, word, sf_firclus ;DOS 4.00 88 <3> labelsize sf_netid, byte, sf_cluspos 89 <3> labelsize sf_OpenAge, word, sf_position+2 90 <3> labelsize sf_LRU, word, sf_position 91 <3> 92 <3> sf_default_number EQU 5h 93 <3> 94 <3> ; 95 <3> ; Note that we need to mark an SFT as being busy for OPEN/CREATE. This is 96 <3> ; because an INT 24 may prevent us from 'freeing' it. We mark this as such 97 <3> ; by placing a -1 in the ref_count field. 98 <3> ; 99 <3> 100 <3> sf_busy EQU -1 101 <3> 102 <3> 103 <3> ; mode mask for FCB detection 104 <3> sf_isfcb EQU 1000000000000000B 105 <3> 106 <3> ; Flag word masks 107 <3> sf_isnet EQU 1000000000000000B 108 <3> sf_close_nodate EQU 0100000000000000B 109 <3> sf_pipe EQU 0010000000000000B 110 <3> sf_no_inherit EQU 0001000000000000B 111 <3> sf_net_spool EQU 0000100000000000B 112 <3> Handle_Fail_I24 EQU 0000000100000000B ;BIT 8 - DISK FULL I24 ERROR 113 <3> 114 <3> ; Local file/device flag masks 115 <3> devid_file_clean EQU 40h ; true if file and not written 116 <3> devid_file_mask_drive EQU 3Fh ; mask for drive number 117 <3> 118 <3> devid_device EQU 80h ; true if a device 119 <3> devid_device_EOF EQU 40h ; true if end of file reached 120 <3> devid_device_raw EQU 20h ; true if in raw mode 121 <3> devid_device_special EQU 10h ; true if special device 122 <3> devid_device_clock EQU 08h ; true if clock device 123 <3> devid_device_null EQU 04h ; true if null device 124 <3> devid_device_con_out EQU 02h ; true if console output 125 <3> devid_device_con_in EQU 01h ; true if consle input 126 <3> ; ; 127 <3> ; C A V E A T P R O G R A M M E R ; 128 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 129 <3> 130 <3> ; 131 <3> ; structure of devid field as returned by IOCTL is: 132 <3> ; 133 <3> ; BIT 7 6 5 4 3 2 1 0 134 <3> ; |---|---|---|---|---|---|---|---| 135 <3> ; | I | E | R | S | I | I | I | I | 136 <3> ; | S | O | A | P | S | S | S | S | 137 <3> ; | D | F | W | E | C | N | C | C | 138 <3> ; | E | | | C | L | U | O | I | 139 <3> ; | V | | | L | K | L | T | N | 140 <3> ; |---|---|---|---|---|---|---|---| 141 <3> ; ISDEV = 1 if this channel is a device 142 <3> ; = 0 if this channel is a disk file 143 <3> ; 144 <3> ; If ISDEV = 1 145 <3> ; 146 <3> ; EOF = 0 if End Of File on input 147 <3> ; RAW = 1 if this device is in Raw mode 148 <3> ; = 0 if this device is cooked 149 <3> ; ISCLK = 1 if this device is the clock device 150 <3> ; ISNUL = 1 if this device is the null device 151 <3> ; ISCOT = 1 if this device is the console output 152 <3> ; ISCIN = 1 if this device is the console input 153 <3> ; 154 <3> ; If ISDEV = 0 155 <3> ; EOF = 0 if channel has been written 156 <3> ; Bits 0-5 are the block device number for 157 <3> ; the channel (0 = A, 1 = B, ...) 158 <3> ; 159 <3> devid_ISDEV EQU 80h 160 <3> devid_EOF EQU 40h 161 <3> devid_RAW EQU 20h 162 <3> devid_SPECIAL EQU 10H 163 <3> devid_ISCLK EQU 08h 164 <3> devid_ISNUL EQU 04h 165 <3> devid_ISCOT EQU 02h 166 <3> devid_ISCIN EQU 01h 167 <3> 168 <3> devid_block_dev EQU 1Fh ; mask for block device number 158 <2> 159 <2> %include "arena.mac" 1 <3> ; SCCSID = @(#)arena.asm 1.1 85/04/09 2 <3> ;BREAK 3 <3> 4 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <3> ; C A V E A T P R O G R A M M E R ; 6 <3> ; ; 7 <3> ; 8 <3> ; arena item 9 <3> ; 10 <3> arena STRUC 0 00000D12 ?? arena_signature DB ? ; 4D for valid item, 5A for last item 0 00000D13 ???? arena_owner DW ? ; owner of arena item 0 00000D15 ???? arena_size DW ? ; size in paragraphs of item 0 00000D17 ?????? arena_reserved DB 3 DUP(?) ; reserved 0 00000D1A ???????????????? arena_name DB 8 DUP(?) ; owner file name 16 <3> arena ENDS 17 <3> 18 <3> ; 19 <3> ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature 20 <3> ; and arena_owner_system are all equal to zero and are contained in DI. Change 21 <3> ; them and change ALLOC.ASM. 22 <3> 23 <3> arena_owner_system EQU 0 ; free block indication 24 <3> 25 <3> arena_signature_normal EQU 4Dh ; valid signature, not end of arena 26 <3> arena_signature_end EQU 5Ah ; valid signature, last block in arena 27 <3> ; ; 28 <3> ; C A V E A T P R O G R A M M E R ; 29 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 30 <3> 160 <2> 161 <2> %include "intnat.mac" 1 <3> ; SCCSID = @(#)intnat.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> ; 5 <3> ; Current structure of the data returned by the international call 6 <3> ; 7 <3> internat_block STRUC 0 00000D12 ???? Date_tim_format DW ? ; 0-USA, 1-EUR, 2-JAP 0 00000D14 ?? Currency_sym DB ? ; Currency Symbol 5 bytes 0 00000D15 ?? DB ? 0 00000D16 ?? DB ? 0 00000D17 ?? DB ? 0 00000D18 ?? DB ? 0 00000D19 ?? Thous_sep DB ? ; Thousands separator 2 bytes 0 00000D1A ?? DB ? 0 00000D1B ?? Decimal_sep DB ? ; Decimal separator 2 bytes 0 00000D1C ?? DB ? 0 00000D1D ?? Date_sep DB ? ; Date separator 2 bytes 0 00000D1E ?? DB ? 0 00000D1F ?? Time_sep DB ? ; Decimal separator 2 bytes 0 00000D20 ?? DB ? 0 00000D21 ?? Bit_field DB ? ; Bit values 23 <3> ; Bit 0 = 0 if currency symbol first 24 <3> ; = 1 if currency symbol last 25 <3> ; Bit 1 = 0 if No space after currency symbol 26 <3> ; = 1 if space after currency symbol 0 00000D22 ?? Currency_cents DB ? ; Number of places after currency dec point 0 00000D23 ?? Time_24 DB ? ; 1 if 24 hour time, 0 if 12 hour time 0 00000D24 ???? Map_call DW ? ; Address of case mapping call (DWORD) 0 00000D26 ???? DW ? ; THIS IS TWO WORDS SO IT CAN BE INITIALIZED 31 <3> ; in pieces. 0 00000D28 ?? Data_sep DB ? ; Data list separator character 0 00000D29 ?? DB ? 34 <3> internat_block ENDS 35 <3> 36 <3> ; 37 <3> ; Max size of the block returned by the INTERNATIONAL call 38 <3> ; 39 <3> internat_block_max EQU 32 162 <2> 163 <2> %include "mi.mac" 1 <3> ; SCCSID = @(#)mi.asm 1.1 85/04/10 2 <3> BREAK 3 <3> 4 <3> mi_INT EQU 0CDh 5 <3> mi_Long_JMP EQU 0EAh 6 <3> mi_Long_CALL EQU 09Ah 7 <3> mi_Long_RET EQU 0CBh 8 <3> mi_Near_RET EQU 0C3h 9 <3> 10 <3> ; xxxxoditszxaxpxc 11 <3> f_Overflow EQU 0000100000000000B 12 <3> f_Direction EQU 0000010000000000B 13 <3> f_Interrupt EQU 0000001000000000B 14 <3> f_Trace EQU 0000000100000000B 15 <3> f_Sign EQU 0000000010000000B 16 <3> f_Zero EQU 0000000001000000B 17 <3> f_Aux EQU 0000000000010000B 18 <3> f_Parity EQU 0000000000000100B 19 <3> f_Carry EQU 0000000000000001B 164 <2> 165 <2> fChk equ 1 166 <2> fDelim equ 2 167 <2> fSpChk equ 4 168 <2> fFCB equ 8 169 <2> 170 <2> %include "filemode.mac" 1 <3> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)filemode.asm 1.1 85/04/10 3 <3> BREAK 4 <3> 5 <3> stdin EQU 0 6 <3> stdout EQU 1 7 <3> stderr EQU 2 8 <3> stdaux EQU 3 9 <3> stdprn EQU 4 10 <3> 11 <3> BREAK 12 <3> 13 <3> access_mask EQU 0FH 14 <3> open_for_read EQU 00h 15 <3> open_for_write EQU 01h 16 <3> open_for_both EQU 02h 17 <3> 18 <3> sharing_mask EQU 0F0H 19 <3> sharing_compat EQU 000H 20 <3> sharing_deny_both EQU 010H 21 <3> sharing_deny_write EQU 020H 22 <3> sharing_deny_read EQU 030H 23 <3> sharing_deny_none EQU 040H 24 <3> sharing_net_FCB EQU 070h 25 <3> sharing_no_inherit EQU 080H 26 <3> 27 <3> BREAK 28 <3> 29 <3> no_code_page_check EQU 0100H 30 <3> int_24_error EQU 2000H 31 <3> auto_commit_write EQU 4000H 32 <3> ext_open_on EQU 01H 33 <3> ext_file_not_exists EQU 04H 34 <3> ext_open_I24_off EQU 02H 35 <3> io_mode_id EQU 00000010B 36 <3> reserved_bits_mask EQU 0FE00H 37 <3> exists_mask EQU 0FH 38 <3> not_exists_mask EQU 0F0H 39 <3> action_opened EQU 01H 40 <3> action_created_opened EQU 02H 41 <3> action_replaced_opened EQU 03H 42 <3> 43 <3> ext_exists_open EQU 01H 44 <3> ext_exists_fail EQU 0H 45 <3> ext_nexists_create EQU 10H 46 <3> 47 <3> 48 <3> 49 <3> ext_open_parm struc 0 00000D12 ???????? ext_set_list dd ? 0 00000D16 ???? ext_num_of_parm dw ? 52 <3> ext_open_parm ends 53 <3> 54 <3> 55 <3> 171 <2> 172 <2> %include "error.mac" 1 <3> ; SCCSID = @(#)error.asm 1.1 85/04/10 2 <3> ; SCCSID = @(#)error.asm 1.1 85/04/10 3 <3> BREAK 4 <3> 5 <3> ; 6 <3> ; XENIX calls all return error codes through AX. If an error occurred then 7 <3> ; the carry bit will be set and the error code is in AX. If no error occurred 8 <3> ; then the carry bit is reset and AX contains returned info. 9 <3> ; 10 <3> ; Since the set of error codes is being extended as we extend the operating 11 <3> ; system, we have provided a means for applications to ask the system for a 12 <3> ; recommended course of action when they receive an error. 13 <3> ; 14 <3> ; The GetExtendedError system call returns a universal error, an error 15 <3> ; location and a recommended course of action. The universal error code is 16 <3> ; a symptom of the error REGARDLESS of the context in which GetExtendedError 17 <3> ; is issued. 18 <3> ; 19 <3> 20 <3> ; 21 <3> ; These are the 2.0 error codes 22 <3> ; 23 <3> error_invalid_function EQU 1 24 <3> error_file_not_found EQU 2 25 <3> error_path_not_found EQU 3 26 <3> error_too_many_open_files EQU 4 27 <3> error_access_denied EQU 5 28 <3> error_invalid_handle EQU 6 29 <3> error_arena_trashed EQU 7 30 <3> error_not_enough_memory EQU 8 31 <3> error_invalid_block EQU 9 32 <3> error_bad_environment EQU 10 33 <3> error_bad_format EQU 11 34 <3> error_invalid_access EQU 12 35 <3> error_invalid_data EQU 13 36 <3> ;**** reserved EQU 14 ; ***** 37 <3> error_invalid_drive EQU 15 38 <3> error_current_directory EQU 16 39 <3> error_not_same_device EQU 17 40 <3> error_no_more_files EQU 18 41 <3> ; 42 <3> ; These are the universal int 24 mappings for the old INT 24 set of errors 43 <3> ; 44 <3> error_write_protect EQU 19 45 <3> error_bad_unit EQU 20 46 <3> error_not_ready EQU 21 47 <3> error_bad_command EQU 22 48 <3> error_CRC EQU 23 49 <3> error_bad_length EQU 24 50 <3> error_Seek EQU 25 51 <3> error_not_DOS_disk EQU 26 52 <3> error_sector_not_found EQU 27 53 <3> error_out_of_paper EQU 28 54 <3> error_write_fault EQU 29 55 <3> error_read_fault EQU 30 56 <3> error_gen_failure EQU 31 57 <3> ; 58 <3> ; These are the new 3.0 error codes reported through INT 24 59 <3> ; 60 <3> error_sharing_violation EQU 32 61 <3> error_lock_violation EQU 33 62 <3> error_wrong_disk EQU 34 63 <3> error_FCB_unavailable EQU 35 64 <3> error_sharing_buffer_exceeded EQU 36 65 <3> error_Code_Page_Mismatched EQU 37 ; DOS 4.00 ;AN000; 66 <3> error_handle_EOF EQU 38 ; DOS 4.00 ;AN000; 67 <3> error_handle_Disk_Full EQU 39 ; DOS 4.00 ;AN000; 68 <3> ; 69 <3> ; New OEM network-related errors are 50-79 70 <3> ; 71 <3> error_not_supported EQU 50 72 <3> ; 73 <3> ; End of INT 24 reportable errors 74 <3> ; 75 <3> error_file_exists EQU 80 76 <3> error_DUP_FCB EQU 81 ; ***** 77 <3> error_cannot_make EQU 82 78 <3> error_FAIL_I24 EQU 83 79 <3> ; 80 <3> ; New 3.0 network related error codes 81 <3> ; 82 <3> error_out_of_structures EQU 84 83 <3> error_Already_assigned EQU 85 84 <3> error_invalid_password EQU 86 85 <3> error_invalid_parameter EQU 87 86 <3> error_NET_write_fault EQU 88 87 <3> error_sys_comp_not_loaded EQU 90 ; DOS 4.00 ;AN000; 88 <3> 89 <3> BREAK 90 <3> 91 <3> error_I24_write_protect EQU 0 92 <3> error_I24_bad_unit EQU 1 93 <3> error_I24_not_ready EQU 2 94 <3> error_I24_bad_command EQU 3 95 <3> error_I24_CRC EQU 4 96 <3> error_I24_bad_length EQU 5 97 <3> error_I24_Seek EQU 6 98 <3> error_I24_not_DOS_disk EQU 7 99 <3> error_I24_sector_not_found EQU 8 100 <3> error_I24_out_of_paper EQU 9 101 <3> error_I24_write_fault EQU 0Ah 102 <3> error_I24_read_fault EQU 0Bh 103 <3> error_I24_gen_failure EQU 0Ch 104 <3> ; NOTE: Code 0DH is used by MT-DOS. 105 <3> error_I24_wrong_disk EQU 0Fh 106 <3> 107 <3> ; THE FOLLOWING ARE MASKS FOR THE AH REGISTER ON Int 24 108 <3> 109 <3> Allowed_FAIL EQU 00001000B 110 <3> Allowed_RETRY EQU 00010000B 111 <3> Allowed_IGNORE EQU 00100000B 112 <3> ;NOTE: ABORT is ALWAYS allowed 113 <3> 114 <3> I24_operation EQU 00000001B ;Z if READ,NZ if Write 115 <3> I24_area EQU 00000110B ; 00 if DOS 116 <3> ; 01 if FAT 117 <3> ; 10 if root DIR 118 <3> ; 11 if DATA 119 <3> I24_class EQU 10000000B ;Z if DISK, NZ if FAT or char 120 <3> 121 <3> BREAK 122 <3> 123 <3> ; Values for error CLASS 124 <3> 125 <3> errCLASS_OutRes EQU 1 ; Out of Resource 126 <3> errCLASS_TempSit EQU 2 ; Temporary Situation 127 <3> errCLASS_Auth EQU 3 ; Permission problem 128 <3> errCLASS_Intrn EQU 4 ; Internal System Error 129 <3> errCLASS_HrdFail EQU 5 ; Hardware Failure 130 <3> errCLASS_SysFail EQU 6 ; System Failure 131 <3> errCLASS_Apperr EQU 7 ; Application Error 132 <3> errCLASS_NotFnd EQU 8 ; Not Found 133 <3> errCLASS_BadFmt EQU 9 ; Bad Format 134 <3> errCLASS_Locked EQU 10 ; Locked 135 <3> errCLASS_Media EQU 11 ; Media Failure 136 <3> errCLASS_Already EQU 12 ; Collision with Existing Item 137 <3> errCLASS_Unk EQU 13 ; Unknown/other 138 <3> 139 <3> ; Values for error ACTION 140 <3> 141 <3> errACT_Retry EQU 1 ; Retry 142 <3> errACT_DlyRet EQU 2 ; Delay Retry, retry after pause 143 <3> errACT_User EQU 3 ; Ask user to regive info 144 <3> errACT_Abort EQU 4 ; abort with clean up 145 <3> errACT_Panic EQU 5 ; abort immediately 146 <3> errACT_Ignore EQU 6 ; ignore 147 <3> errACT_IntRet EQU 7 ; Retry after User Intervention 148 <3> 149 <3> ; Values for error LOCUS 150 <3> 151 <3> errLOC_Unk EQU 1 ; No appropriate value 152 <3> errLOC_Disk EQU 2 ; Random Access Mass Storage 153 <3> errLOC_Net EQU 3 ; Network 154 <3> errLOC_SerDev EQU 4 ; Serial Device 155 <3> errLOC_Mem EQU 5 ; Memory 173 <2> 174 <2> %include "syscall.mac" 1 <3> ; SCCSID = @(#)syscall.asm 1.1 85/04/10 2 <3> ;BREAK 3 <3> ;SUBTTL system call definitions 4 <3> ;PAGE 5 <3> 6 <3> Abort EQU 0 ; 0 0 7 <3> Std_Con_Input EQU 1 ; 1 1 8 <3> Std_Con_Output EQU 2 ; 2 2 9 <3> Std_Aux_Input EQU 3 ; 3 3 10 <3> Std_Aux_Output EQU 4 ; 4 4 11 <3> Std_Printer_Output EQU 5 ; 5 5 12 <3> Raw_Con_IO EQU 6 ; 6 6 13 <3> Raw_Con_Input EQU 7 ; 7 7 14 <3> Std_Con_Input_No_Echo EQU 8 ; 8 8 15 <3> Std_Con_String_Output EQU 9 ; 9 9 16 <3> Std_Con_String_Input EQU 10 ; 10 A 17 <3> Std_Con_Input_Status EQU 11 ; 11 B 18 <3> Std_Con_Input_Flush EQU 12 ; 12 C 19 <3> Disk_Reset EQU 13 ; 13 D 20 <3> Set_Default_Drive EQU 14 ; 14 E 21 <3> FCB_Open EQU 15 ; 15 F 22 <3> FCB_Close EQU 16 ; 16 10 23 <3> Dir_Search_First EQU 17 ; 17 11 24 <3> Dir_Search_Next EQU 18 ; 18 12 25 <3> FCB_Delete EQU 19 ; 19 13 26 <3> FCB_Seq_Read EQU 20 ; 20 14 27 <3> FCB_Seq_Write EQU 21 ; 21 15 28 <3> FCB_Create EQU 22 ; 22 16 29 <3> FCB_Rename EQU 23 ; 23 17 30 <3> Get_Default_Drive EQU 25 ; 25 19 31 <3> Set_DMA EQU 26 ; 26 1A 32 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <3> ; C A V E A T P R O G R A M M E R ; 34 <3> ; ; 35 <3> Get_Default_DPB EQU 31 ; 31 1F 36 <3> ; ; 37 <3> ; C A V E A T P R O G R A M M E R ; 38 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 39 <3> FCB_Random_Read EQU 33 ; 33 21 40 <3> FCB_Random_Write EQU 34 ; 34 22 41 <3> Get_FCB_File_Length EQU 35 ; 35 23 42 <3> Get_FCB_Position EQU 36 ; 36 24 43 <3> Set_Interrupt_Vector EQU 37 ; 37 25 44 <3> Create_Process_Data_Block EQU 38 ; 38 26 45 <3> FCB_Random_Read_Block EQU 39 ; 39 27 46 <3> FCB_Random_Write_Block EQU 40 ; 40 28 47 <3> Parse_File_Descriptor EQU 41 ; 41 29 48 <3> Get_Date EQU 42 ; 42 2A 49 <3> Set_Date EQU 43 ; 43 2B 50 <3> Get_Time EQU 44 ; 44 2C 51 <3> Set_Time EQU 45 ; 45 2D 52 <3> Set_Verify_On_Write EQU 46 ; 46 2E 53 <3> ; Extended functionality group 54 <3> Get_DMA EQU 47 ; 47 2F 55 <3> Get_Version EQU 48 ; 48 30 56 <3> Keep_Process EQU 49 ; 49 31 57 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <3> ; C A V E A T P R O G R A M M E R ; 59 <3> ; ; 60 <3> Get_DPB EQU 50 ; 50 32 61 <3> ; ; 62 <3> ; C A V E A T P R O G R A M M E R ; 63 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 64 <3> Set_CTRL_C_Trapping EQU 51 ; 51 33 65 <3> Get_InDOS_Flag EQU 52 ; 52 34 66 <3> Get_Interrupt_Vector EQU 53 ; 53 35 67 <3> Get_Drive_Freespace EQU 54 ; 54 36 68 <3> Char_Oper EQU 55 ; 55 37 69 <3> International EQU 56 ; 56 38 70 <3> ; Directory Group 71 <3> MKDir EQU 57 ; 57 39 72 <3> RMDir EQU 58 ; 58 3A 73 <3> CHDir EQU 59 ; 59 3B 74 <3> ; File Group 75 <3> Creat EQU 60 ; 60 3C 76 <3> Open EQU 61 ; 61 3D 77 <3> Close EQU 62 ; 62 3E 78 <3> Read EQU 63 ; 63 3F 79 <3> Write EQU 64 ; 64 40 80 <3> Unlink EQU 65 ; 65 41 81 <3> LSeek EQU 66 ; 66 42 82 <3> CHMod EQU 67 ; 67 43 83 <3> IOCtl EQU 68 ; 68 44 84 <3> XDup EQU 69 ; 69 45 85 <3> XDup2 EQU 70 ; 70 46 86 <3> Current_Dir EQU 71 ; 71 47 87 <3> ; Memory Group 88 <3> Alloc EQU 72 ; 72 48 89 <3> Dealloc EQU 73 ; 73 49 90 <3> Setblock EQU 74 ; 74 4A 91 <3> ; Process Group 92 <3> Exec EQU 75 ; 75 4B 93 <3> Exit EQU 76 ; 76 4C 94 <3> WaitProcess EQU 77 ; 77 4D 95 <3> Find_First EQU 78 ; 78 4E 96 <3> ; Special Group 97 <3> Find_Next EQU 79 ; 79 4F 98 <3> ; SPECIAL SYSTEM GROUP 99 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 100 <3> ; C A V E A T P R O G R A M M E R ; 101 <3> ; ; 102 <3> Set_Current_PDB EQU 80 ; 80 50 103 <3> Get_Current_PDB EQU 81 ; 81 51 104 <3> Get_In_Vars EQU 82 ; 82 52 105 <3> SetDPB EQU 83 ; 83 53 106 <3> ; ; 107 <3> ; C A V E A T P R O G R A M M E R ; 108 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 109 <3> Get_Verify_On_Write EQU 84 ; 84 54 110 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 111 <3> ; C A V E A T P R O G R A M M E R ; 112 <3> ; ; 113 <3> Dup_PDB EQU 85 ; 85 55 114 <3> ; ; 115 <3> ; C A V E A T P R O G R A M M E R ; 116 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 117 <3> Rename EQU 86 ; 86 56 118 <3> File_Times EQU 87 ; 87 57 119 <3> AllocOper EQU 88 ; 88 58 120 <3> ; Network extention system calls 121 <3> GetExtendedError EQU 89 ; 89 59 122 <3> CreateTempFile EQU 90 ; 90 5A 123 <3> CreateNewFile EQU 91 ; 91 5B 124 <3> LockOper EQU 92 ; 92 5C Lock and Unlock 125 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 126 <3> ; C A V E A T P R O G R A M M E R ; 127 <3> ; ; 128 <3> ServerCall EQU 93 ; 93 5D CommitAll, ServerDOSCall, 129 <3> ; CloseByName, CloseUser, 130 <3> ; CloseUserProcess, 131 <3> ; GetOpenFileList 132 <3> ; ; 133 <3> ; C A V E A T P R O G R A M M E R ; 134 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 135 <3> UserOper EQU 94 ; 94 5E Get and Set 136 <3> AssignOper EQU 95 ; 95 5F On, Off, Get, Set, Cancel 137 <3> xNameTrans EQU 96 ; 96 60 138 <3> PathParse EQU 97 ; 97 61 139 <3> GetCurrentPSP EQU 98 ; 98 62 140 <3> Hongeul EQU 99 ; 99 63 141 <3> ECS_CALL EQU 99 ; 99 63 ;; DBCS support 142 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 143 <3> ; C A V E A T P R O G R A M M E R ; 144 <3> ; ; 145 <3> Set_Printer_Flag EQU 100 ; 100 64 146 <3> ; ; 147 <3> ; C A V E A T P R O G R A M M E R ; 148 <3> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 149 <3> GetExtCntry EQU 101 ; 101 65 150 <3> GetSetCdPg EQU 102 ; 102 66 151 <3> ExtHandle EQU 103 ; 103 67 152 <3> Commit EQU 104 ; 104 68 153 <3> GetSetMediaID EQU 105 ; 105 69 154 <3> IFS_IOCTL EQU 107 ; 107 6B 155 <3> ExtOpen EQU 108 ; 108 6C 156 <3> ; 157 <3> ; 158 <3> Set_Oem_Handler EQU 248 ; 248 F8 159 <3> OEM_C1 EQU 249 ; 249 F9 160 <3> OEM_C2 EQU 250 ; 250 FA 161 <3> OEM_C3 EQU 251 ; 251 FB 162 <3> OEM_C4 EQU 252 ; 252 FC 163 <3> OEM_C5 EQU 253 ; 253 FD 164 <3> OEM_C6 EQU 254 ; 254 FE 165 <3> OEM_C7 EQU 255 ; 255 FF 175 <2> 176 <2> ;SUBTTL 177 <2> 9 <1> %include "devsym.mac" 1 <2> %warning out: DEVSYM.INC... 1 ****************** <2> warning: out: DEVSYM.INC... [-w+user] 2 <2> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <2> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <2> 5 <2> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <2> SYSDEV STRUC 0 00000D12 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00000D16 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00000D18 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 00000D1A ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 00000D1C ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <2> SYSDEV ENDS 13 <2> 14 <2> ; 15 <2> ; ATTRIBUTE BIT MASKS 16 <2> ; 17 <2> ; CHARACTER DEVICES: 18 <2> ; 19 <2> ; BIT 15 -> MUST BE 1 20 <2> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <2> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <2> ; 12 -> UNUSED 23 <2> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <2> ; 10 -> MUST BE 0 25 <2> ; 9 -> MUST BE 0 26 <2> ; 8 -> UNUSED 27 <2> ; 7 -> UNUSED 28 <2> ; 6 -> UNUSED 29 <2> ; 5 -> UNUSED 30 <2> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <2> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <2> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <2> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <2> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <2> ; 36 <2> ; BLOCK DEVICES: 37 <2> ; 38 <2> ; BIT 15 -> MUST BE 0 39 <2> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <2> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <2> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <2> ; THE SAME PLACE. 43 <2> ; 12 -> UNUSED 44 <2> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <2> ; 10 -> MUST BE 0 46 <2> ; 9 -> MUST BE 0 47 <2> ; 8 -> UNUSED 48 <2> ; 7 -> UNUSED 49 <2> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <2> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <2> ; 5 -> UNUSED 52 <2> ; 4 -> UNUSED 53 <2> ; 3 -> UNUSED 54 <2> ; 2 -> UNUSED 55 <2> ; 1 -> UNUSED 56 <2> ; 0 -> UNUSED 57 <2> ; 58 <2> 59 <2> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <2> CHARDEV EQU 8000H 61 <2> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <2> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <2> ; COMP MEDIA. 64 <2> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <2> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <2> ; NOT. CURRENTLY BLOCK ONLY. 67 <2> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <2> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <2> ; ENTRY POINTS, 0 IF NOT 70 <2> 71 <2> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <2> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <2> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <2> ; ITS CURRENT FORM. 75 <2> 76 <2> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <2> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <2> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <2> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <2> 81 <2> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <2> ;DEVICE SUPPORTS SET/GET MAP OF 83 <2> ;LOGICAL DRIVES, AND SUPPORTS 84 <2> ;GENERIC IOCTL CALLS. 85 <2> ;FOR CHARACTER DEVICES, THIS 86 <2> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <2> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <2> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <2> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <2> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <2> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <2> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <2> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <2> 95 <2> ;STATIC REQUEST HEADER 96 <2> SRHEAD STRUC 0 00000D12 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00000D13 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00000D14 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00000D15 ???? REQSTAT DW ? ;STATUS WORD 0 00000D17 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <2> SRHEAD ENDS 103 <2> 104 <2> ;STATUS WORD MASKS 105 <2> STERR EQU 8000H ;BIT 15 - ERROR 106 <2> STBUI EQU 0200H ;BIT 9 - BUISY 107 <2> STDON EQU 0100H ;BIT 8 - DONE 108 <2> STECODE EQU 00FFH ;ERROR CODE 109 <2> ; 2/12/KK 110 <2> ; Interim character identifier 2/12/KK 111 <2> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <2> 113 <2> ;FUNCTION CODES 114 <2> DEVINIT EQU 0 ;INITIALIZATION 115 <2> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <2> DEVMDCH EQU 1 ;MEDIA CHECK 117 <2> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <2> DEVBPB EQU 2 ;GET BPB 119 <2> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <2> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <2> DEVRD EQU 4 ;READ 122 <2> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <2> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <2> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <2> DEVIST EQU 6 ;INPUT STATUS 126 <2> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <2> DEVIFL EQU 7 ;INPUT FLUSH 128 <2> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <2> DEVWRT EQU 8 ;WRITE 130 <2> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <2> DEVOST EQU 10 ;OUTPUT STATUS 132 <2> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <2> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <2> DEVOPN EQU 13 ;DEVICE OPEN 135 <2> DEVCLS EQU 14 ;DEVICE CLOSE 136 <2> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <2> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <2> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <2> GENIOCTL EQU 19 140 <2> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <2> ; 20 142 <2> ; 21 143 <2> ; 22 144 <2> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <2> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <2> QUERYGENIOCTL equ 25 ; query generic IOCTL support (MS-DOS v5+) 147 <2> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 148 <2> 149 <2> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 150 <2> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 151 <2> 152 <2> ; GENERIC IOCTL REQUEST STRUCTURE 153 <2> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 154 <2> ; 155 <2> IOCTL_REQ STRUC 0 00000D12 ?????????????????? DB (SRHEAD_struc_size) DUP(?) 156 00000009 ???????? <2> 157 <2> ; GENERIC IOCTL ADDITION. 0 00000D1F ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 00000D20 ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 00000D21 ???? REG_SI DW ? 0 00000D23 ???? REG_DI DW ? 0 00000D25 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 163 <2> IOCTL_REQ ENDS 164 <2> 165 <2> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 166 <2> GEN_IOCTL_WRT_TRK EQU 40H 167 <2> GEN_IOCTL_RD_TRK EQU 60H 168 <2> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 169 <2> 170 <2> ;; 32-bit absolute read/write input list structure 171 <2> 172 <2> ABS_32RW STRUC 0 00000D12 ???????? SECTOR_RBA DD ? ; relative block address 0 00000D16 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00000D18 ???????? BUFFER_ADDR DD ? ; data addrress 176 <2> ABS_32RW ENDS 177 <2> 178 <2> ;; media ID info 179 <2> 180 <2> MEDIA_ID_INFO STRUC 0 00000D12 ???? MEDIA_level DW ? ; info level 0 00000D14 ???????? MEDIA_Serial DD ? ; serial # 0 00000D18 ?????????????????? MEDIA_Label DB 11 dup (?) ;volume label 183 0000000F ???? <2> 0 00000D23 ???????????????? MEDIA_System DB 8 dup (?) ;system type 185 <2> MEDIA_ID_INFO ENDS 186 <2> 187 <2> ;; equates for DOS34_FLAG 188 <2> 189 <2> IFS_ABSRW EQU 00001H ;IFS absolute read/write 190 <2> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 191 <2> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 192 <2> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 193 <2> FROM_DISK_RESET EQU 00004H ;from disk reset 194 <2> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 195 <2> From_String_Output EQU 00008H ;from con string output 196 <2> NO_From_String_Output EQU 0FFF7H ;not from con string output 197 <2> From_DOS_WRITE EQU 00010H ;from dos_write 198 <2> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 199 <2> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 200 <2> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 201 <2> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 202 <2> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 203 <2> DBCS_VOLID EQU 00080H ;indicate from volume id 204 <2> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 205 <2> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 206 <2> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 207 <2> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 208 <2> X25_special EQU 00800H ;flag for X25 driver 10 <1> ;.cref 11 <1> [list +] 12 <1> 13 <1> Break 14 <1> 15 <1> ; 16 <1> ; We need to identify the parts of the data area that are relevant to tasks 17 <1> ; and those that are relevant to the system as a whole. Under 3.0, the system 18 <1> ; data will be gathered with the system code. The process data under 2.x will 19 <1> ; be available for swapping and under 3.0 it will be allocated per-process. 20 <1> ; 21 <1> ; The data that is system data will be identified by [SYSTEM] in the comments 22 <1> ; describing that data item. 23 <1> ; 24 <1> 25 <1> %ifndef Kanji 26 <1> %iassign Kanji 0 27 <1> %endif 28 <1> %ifndef Debug 29 <1> %iassign Debug 0 30 <1> %endif 31 <1> %ifndef Redirector 32 <1> %iassign Redirector 0 33 <1> %endif 34 <1> %ifndef ShareF 35 <1> %iassign ShareF 0 36 <1> %endif 37 <1> === Switch to base=001DC0h -> "CONSTANTS" 38 <1> section CONSTANTS 39 <1> 40 <1> ; 41 <1> ; Table of routines for assignable devices 42 <1> ; 43 <1> ; MSDOS allows assignment if the following standard devices: 44 <1> ; stdin (usually CON input) 45 <1> ; stdout (usually CON output) 46 <1> ; auxin (usually AUX input) 47 <1> ; auxout (usually AUX output) 48 <1> ; stdlpt (usually PRN output) 49 <1> ; 50 <1> ; SPECIAL NOTE: 51 <1> ; Status of a file is a strange idea. We choose to handle it in this 52 <1> ; manner: If we're not at end-of-file, then we always say that we have a 53 <1> ; character. Otherwise, we return ^Z as the character and set the ZERO 54 <1> ; flag. In this manner we can support program written under the old DOS 55 <1> ; (they use ^Z as EOF on devices) and programs written under the new DOS 56 <1> ; (they use the ZERO flag as EOF). 57 <1> 58 <1> ; Default SFTs for boot up 59 <1> 60 <1> CONST001S equ CONST001s ; NASM port label 61 <1> CONST001E equ CONST001e ; NASM port label 62 <1> Public CONST001S,CONST001E 63 <1> CONST001s label byte 64 <1> PUBLIC sftabl 65 <1> sftabl LABEL DWORD ; [SYSTEM] file table 0 000000CC ???? DW -1 ; [SYSTEM] link to next table 0 000000CE ???? DW -1 ; [SYSTEM] link seg to next table 0 000000D0 ???? DW sf_default_number ; [SYSTEM] Number of entries in table 0 000000D2 ?????????????????? DB sf_default_number * sf_entry_struc_size DUP (0); [SYSTEM] 69 0000000F ??????????????????- <1> 69 00000018 ??????????????????- <1> 69 00000021 ??????????????????- <1> 69 0000002A ??????????????????- <1> 69 00000033 ??????????????????- <1> 69 0000003C ??????????????????- <1> 69 00000045 ??????????????????- <1> 69 0000004E ??????????????????- <1> 69 00000057 ??????????????????- <1> 69 00000060 ??????????????????- <1> 69 00000069 ??????????????????- <1> 69 00000072 ??????????????????- <1> 69 0000007B ??????????????????- <1> 69 00000084 ??????????????????- <1> 69 0000008D ??????????????????- <1> 69 00000096 ??????????????????- <1> 69 0000009F ??????????????????- <1> 69 000000A8 ??????????????????- <1> 69 000000B1 ??????????????????- <1> 69 000000BA ??????????????????- <1> 69 000000C3 ??????????????????- <1> 69 000000CC ??????????????????- <1> 69 000000D5 ??????????????????- <1> 69 000000DE ??????????????????- <1> 69 000000E7 ??????????????????- <1> 69 000000F0 ??????????????????- <1> 69 000000F9 ??????????????????- <1> 69 00000102 ??????????????????- <1> 69 0000010B ??????????????????- <1> 69 00000114 ??????????????????- <1> 69 0000011D ??????????????????- <1> 69 00000126 ?????????????? <1> 70 <1> 71 <1> ; the next two variables relate to the position of the logical stdout/stdin 72 <1> ; cursor. They are only meaningful when stdin/stdout are assigned to the 73 <1> ; console. 0 000001F9 ?? I_am CARPOS,BYTE ; [SYSTEM] cursor position in stdin 0 000001FA ?? I_am STARTPOS,BYTE ; [SYSTEM] position of cursor at beginning of buffered input call 0 000001FB ?????????????????? I_am INBUF,128 ; [SYSTEM] general device input buffer 76 00000138 ??????????????????- <1> 76 00000141 ??????????????????- <1> 76 0000014A ??????????????????- <1> 76 00000153 ??????????????????- <1> 76 0000015C ??????????????????- <1> 76 00000165 ??????????????????- <1> 76 0000016E ??????????????????- <1> 76 00000177 ??????????????????- <1> 76 00000180 ??????????????????- <1> 76 00000189 ??????????????????- <1> 76 00000192 ??????????????????- <1> 76 0000019B ??????????????????- <1> 76 000001A4 ??????????????????- <1> 76 000001AD ???? <1> 0 0000027B ?????????????????? I_am CONBUF,131 ; [SYSTEM] The rest of INBUF and console buffer 77 000001B8 ??????????????????- <1> 77 000001C1 ??????????????????- <1> 77 000001CA ??????????????????- <1> 77 000001D3 ??????????????????- <1> 77 000001DC ??????????????????- <1> 77 000001E5 ??????????????????- <1> 77 000001EE ??????????????????- <1> 77 000001F7 ??????????????????- <1> 77 00000200 ??????????????????- <1> 77 00000209 ??????????????????- <1> 77 00000212 ??????????????????- <1> 77 0000021B ??????????????????- <1> 77 00000224 ??????????????????- <1> 77 0000022D ?????????? <1> 78 <1> 0 000002FE ?? I_am PFLAG,BYTE ; [SYSTEM] printer echoing flag 0 000002FF ?? I_am VERFLG,BYTE ; [SYSTEM] Initialize with verify off 0 00000300 ?? I_am CharCo,BYTE,<00000011B> ; [SYSTEM] Allows statchks every 4 chars... 0 00000301 ?? I_am chSwitch,BYTE,<'/'> ; [SYSTEM] current switch character 0 00000302 ?? I_am AllocMethod,BYTE ; [SYSTEM] how to alloc first(best)last 0 00000303 ?? I_am fShare,BYTE,<0> ; [SYSTEM] TRUE => sharing installed 0 00000304 ?? I_am DIFFNAM,BYTE,<1> ; [SYSTEM] Indicates when MYNAME has 86 <1> ; changed 0 00000305 ?????????????????? I_am MYNAME,16,<32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32> 87 00000242 ?????????????? <1> 88 <1> ; [SYSTEM] My network name 89 <1> 90 <1> 91 <1> ; 92 <1> ; The following table is a list of addresses that the sharer patches to be 93 <1> ; PUSH AX to enable the critical sections 94 <1> ; 95 <1> PUBLIC CritPatch 96 <1> CritPatch LABEL WORD 97 <1> %macro critpatchentry 1.nolist 98 <1> %IF (! REDIRECTOR) && (! SHAREF) 99 <1> Short_Addr patch_dosdata_E%1 100 <1> Short_Addr patch_dosdata_L%1 101 <1> %ELSE 102 <1> DW 0 103 <1> DW 0 104 <1> %ENDIF 105 <1> %endmacro 0 00000315 ???????? critpatchentry critDisk 0 00000319 ???????? critpatchentry critDevice 0 0000031D ???? DW 0 109 <1> 110 <1> ; 111 <1> ; WARNING!!! PRINT and PSPRINT *REQUIRE* ErrorMode to precede INDOS. 112 <1> ; Also, IBM server 1.0 requires this also. 113 <1> ; 0 0000031F ?? EVEN ; Force swap area to start on word boundry 115 <1> PUBLIC SWAP_START 116 <1> SWAP_START LABEL BYTE 0 00000320 ?? I_am ErrorMode,BYTE ; Flag for INT 24 processing 0 00000321 ?? I_am INDOS,BYTE,<0> ; DOS status for interrupt processing 0 00000322 ?? I_am WPErr,BYTE,<-1> ; Write protect error flag 0 00000323 ?? I_am EXTERR_LOCUS,BYTE ; Extended Error Locus 0 00000324 ???? I_am EXTERR,WORD,<0> ; Extended Error code 122 <1> 123 <1> ;WARNING Following two bytes Accessed as word in $GetExtendedError 0 00000326 ?? I_am EXTERR_ACTION,BYTE ; Extended Error Action 0 00000327 ?? I_am EXTERR_CLASS,BYTE ; Extended Error Class 126 <1> ; end warning 127 <1> 0 00000328 ???????? I_am EXTERRPT,DWORD ; Extended Error pointer 0 0000032C ???????? I_am DMAADD,DWORD,<80h,?> ; User's disk transfer address (disp/seg) 0 00000330 ???? I_am CurrentPDB,WORD ; Current process identifier 0 00000332 ???? I_am ConC_spsave,WORD ; saved SP before ^C 0 00000334 ???? I_am exit_code,WORD ; exit code of last proc. 0 00000336 ?? I_am CURDRV,BYTE ; Default drive (init A) 0 00000337 ?? I_am CNTCFLAG,BYTE,<0> ; ^C check in dispatch disabled 135 <1> ; F.C. 2/17/86 0 00000338 ?? I_am CPSWFLAG,BYTE,<0> ; Code Page Switching Flag DOS 4.00 0 00000339 ?? I_am CPSWSAVE,BYTE,<0> ; copy of above in case of ABORT 138 <1> EVEN 139 <1> PUBLIC Swap_Always 140 <1> Swap_Always LABEL BYTE 0 0000033A ???? I_am USER_IN_AX,WORD ; User INPUT AX value (used for 142 <1> ; extended error type stuff. NOTE: 143 <1> ; does not have Correct value on 144 <1> ; 1-12, OEM, Get/Set CurrentPDB, 145 <1> ; GetExtendedError system calls 0 0000033C ???? I_am PROC_ID,WORD,<0> ; PID for sharing (0 = local) 0 0000033E ???? I_am USER_ID,WORD,<0> ; Machine for sharing (0 = local) 0 00000340 ???? I_am FirstArena,WORD ; first free block found 0 00000342 ???? I_am BestArena,WORD ; best free block found 0 00000344 ???? I_am LastArena,WORD ; last free block found 0 00000346 ???? I_am EndMem,WORD ; End of memory used in DOSINIT 0 00000348 ???? I_am LASTENT,WORD ; Last entry for directory search 153 <1> 0 0000034A ?? I_am FAILERR,BYTE,<0> ; NZ if user did FAIL on I 24 0 0000034B ?? I_am ALLOWED,BYTE,<0> ; Allowed I 24 answers (see allowed_) 0 0000034C ?? I_am NoSetDir,BYTE ; true -> do not set directory 0 0000034D ?? I_am DidCTRLC,BYTE ; true -> we did a ^C exit 0 0000034E ?? I_am SpaceFlag,BYTE ; true -> embedded spaces are allowed in FCB 159 <1> ; Warning! The following items are accessed as a WORD in TIME.ASM 0 0000034F ?? EVEN 0 00000350 ?? I_am DAY,BYTE,<0> ; Day of month 0 00000351 ?? I_am MONTH,BYTE,<0> ; Month of year 0 00000352 ???? I_am YEAR,WORD,<0> ; Year (with century) 0 00000354 ???? I_am DAYCNT_DOS,WORD,<-1> ; Day count from beginning of year 0 00000356 ?? I_am WEEKDAY,BYTE,<0> ; Day of week 166 <1> ; end warning 0 00000357 ?? I_am CONSWAP,BYTE ; TRUE => console was swapped during device read 0 00000358 ?? I_am IDLEINT,BYTE,<1> ; TRUE => idle int is allowed 0 00000359 ?? I_am fAborting,BYTE,<0> ; TRUE => abort in progress 170 <1> 171 <1> ; Combination of all device call parameters 172 <1> PUBLIC DEVCALL ; 173 <1> DEVCALL: 174 <1> SRHEAD_size equ SRHEAD_struc_size ; NASM port equate 175 <1> istruc SRHEAD 0 0000035A 00 iend 177 <1> PUBLIC CALLUNIT 178 <1> CALLUNIT LABEL BYTE ; unit number for disk 179 <1> CALLFLSH LABEL WORD ; 0 00000367 ?? I_am CALLMED,BYTE ; media byte 181 <1> CALLBR LABEL DWORD ; 182 <1> PUBLIC CALLXAD ; 183 <1> CALLXAD LABEL DWORD ; 0 00000368 ?? I_am CALLRBYT,BYTE ; 185 <1> PUBLIC CALLVIDM ; 186 <1> CALLVIDM LABEL DWORD ; 0 00000369 ?????? DB 3 DUP(?) ; 188 <1> CallBPB equ CALLBPB ; NASM port label 189 <1> PUBLIC CallBPB ; 190 <1> CALLBPB LABEL DWORD ; 0 0000036C ???? I_am CALLSCNT,WORD ; 192 <1> PUBLIC CALLSSEC 193 <1> CALLSSEC LABEL WORD ; 0 0000036E ???? DW ? ; 0 00000370 ???????? I_am CALLVIDRW,DWORD ; 196 <1> ; 0 00000374 ???????? I_am CALLNEWSC,DWORD ; starting sector for >32mb 0 00000378 ???????? I_am CALLDEVAD,DWORD ; stash for device entry point 199 <1> ; 200 <1> ; Same as above for I/O calls ; 201 <1> ; 202 <1> IOCall equ IOCALL ; NASM port label 203 <1> PUBLIC IOCall ; 204 <1> IOCALL: 205 <1> istruc SRHEAD 0 0000037C 00 iend 207 <1> IOFLSH LABEL WORD ; 208 <1> PUBLIC IORCHR ; 209 <1> IORCHR LABEL BYTE ; 0 00000389 ?? I_am IOMED,BYTE ; 0 0000038A ???????? I_am IOXAD,DWORD ; 0 0000038E ???? I_am IOSCNT,WORD ; 0 00000390 ???? I_am IOSSEC,WORD ; 214 <1> ; Call struct for DSKSTATCHK ; 0 00000392 ???? I_am DSKSTCALL,2, ; 0 00000394 ?? I_am DSKSTCOM,1, ; 0 00000395 ???? I_am DSKSTST,WORD ; 0 00000397 ???????????????? DB 8 DUP (0) ; 0 0000039F ?? I_am DSKCHRET,BYTE ; 0 000003A0 ???? short_addr DEVIOBUF ; 0 000003A2 ???? DW ? ; DOS segment set at Init 0 000003A4 ???? I_AM DSKSTCNT,WORD,<1> ; 0 000003A6 ???? DW 0 ; 224 <1> 0 000003A8 ?? I_am CreatePDB,BYTE ; flag for creating a process 226 <1> PUBLIC Lock_Buffer ; 227 <1> Lock_Buffer LABEL DWORD ;MS. DOS Lock Buffer for Ext Lock 0 000003A9 ???????? DD ? ;MS. position 0 000003AD ???????? DD ? ;MS. length 230 <1> CONST001e label byte 231 <1> 232 <1> ; (no prior section) ; CONSTANTS ENDS 233 <1> END === Trace listing source: ../../INC/msdatan.lst 1 %include "nobits.mac" 1 <1> %imacro stripparens 2.nolist 2 <1> %defstr %%param %2 3 <1> %rep 16 4 <1> %substr %%opening %%param 1 5 <1> %ifidn %%opening, '(' 6 <1> %substr %%param %%param 2,-1 7 <1> %endif 8 <1> %endrep 9 <1> %rep 16 10 <1> %strlen %%length %%param 11 <1> %substr %%closing %%param %%length 12 <1> %ifidn %%closing, ')' 13 <1> %substr %%param %%param 1,-2 14 <1> %endif 15 <1> %endrep 16 <1> %deftok %%token %%param 17 <1> %1 %%token 18 <1> %endmacro 19 <1> 20 <1> %imacro db 1-*.nolist 21 <1> %rep %0 22 <1> %define %%param %1 23 <1> %define %%multi 24 <1> %defstr %%string %%param 25 <1> %strlen %%stringlength %%string 26 <1> %assign %%index 1 27 <1> %rep %%stringlength 28 <1> %substr %%checkblank %%string %%index 29 <1> %ifidni %%checkblank, '"' 30 <1> %elifidni %%checkblank, "'" 31 <1> %else 32 <1> %deftok %%checkblank %%checkblank 33 <1> %ifempty %%checkblank 34 <1> %substr %%dup %%string %%index + 1,4 35 <1> %deftok %%dup %%dup 36 <1> %assign %%isdup 0 37 <1> %ifidni %%dup, dup 38 <1> %assign %%isdup 1 39 <1> %elifidni %%dup, dup( 40 <1> %assign %%isdup 1 41 <1> %endif 42 <1> %if %%isdup 43 <1> %substr %%multi %%string 1, %%index - 1 44 <1> %deftok %%multi %%multi 45 <1> %substr %%string %%string %%index + 5, -1 46 <1> %deftok %%token %%string 47 <1> %undef %%param 48 <1> stripparens %define %%param, %%token 49 <1> %assign %%length 1 50 <1> %ifstr %%param 51 <1> %strlen %%length %%param 52 <1> %endif 53 <1> %rep %%length * %%multi 54 <1> db ? 55 <1> %endrep 56 <1> %exitrep 57 <1> %endif 58 <1> %endif 59 <1> %endif 60 <1> %assign %%index %%index + 1 61 <1> %endrep 62 <1> %ifempty %%multi 63 <1> %assign %%length 1 64 <1> %ifstr %%param 65 <1> %strlen %%length %%param 66 <1> %endif 67 <1> %rep %%length 68 <1> db ? 69 <1> %endrep 70 <1> %endif 71 <1> %rotate 1 72 <1> %endrep 73 <1> %endmacro 74 <1> 75 <1> %imacro dw 1-*.nolist 76 <1> %rep %0 77 <1> %define %%param %1 78 <1> %define %%multi 79 <1> %defstr %%string %%param 80 <1> %strlen %%stringlength %%string 81 <1> %assign %%index 1 82 <1> %rep %%stringlength 83 <1> %substr %%checkblank %%string %%index 84 <1> %ifidni %%checkblank, '"' 85 <1> %elifidni %%checkblank, "'" 86 <1> %else 87 <1> %deftok %%checkblank %%checkblank 88 <1> %ifempty %%checkblank 89 <1> %substr %%dup %%string %%index + 1,4 90 <1> %deftok %%dup %%dup 91 <1> %assign %%isdup 0 92 <1> %ifidni %%dup, dup 93 <1> %assign %%isdup 1 94 <1> %elifidni %%dup, dup( 95 <1> %assign %%isdup 1 96 <1> %endif 97 <1> %if %%isdup 98 <1> %substr %%multi %%string 1, %%index - 1 99 <1> %deftok %%multi %%multi 100 <1> %substr %%string %%string %%index + 5, -1 101 <1> %deftok %%token %%string 102 <1> %undef %%param 103 <1> stripparens %define %%param, %%token 104 <1> %assign %%length 1 105 <1> %ifstr %%param 106 <1> %strlen %%length %%param 107 <1> %assign %%length (%%length + 1) / 2 108 <1> %endif 109 <1> %rep %%length * %%multi 110 <1> dw ? 111 <1> %endrep 112 <1> %exitrep 113 <1> %endif 114 <1> %endif 115 <1> %endif 116 <1> %assign %%index %%index + 1 117 <1> %endrep 118 <1> %ifempty %%multi 119 <1> %assign %%length 1 120 <1> %ifstr %%param 121 <1> %strlen %%length %%param 122 <1> %assign %%length (%%length + 1) / 2 123 <1> %endif 124 <1> %rep %%length 125 <1> dw ? 126 <1> %endrep 127 <1> %endif 128 <1> %rotate 1 129 <1> %endrep 130 <1> %endmacro 131 <1> 132 <1> %imacro dd 1-*.nolist 133 <1> %rep %0 134 <1> %define %%param %1 135 <1> %define %%multi 136 <1> %defstr %%string %%param 137 <1> %strlen %%stringlength %%string 138 <1> %assign %%index 1 139 <1> %rep %%stringlength 140 <1> %substr %%checkblank %%string %%index 141 <1> %ifidni %%checkblank, '"' 142 <1> %elifidni %%checkblank, "'" 143 <1> %else 144 <1> %deftok %%checkblank %%checkblank 145 <1> %ifempty %%checkblank 146 <1> %substr %%dup %%string %%index + 1,4 147 <1> %deftok %%dup %%dup 148 <1> %assign %%isdup 0 149 <1> %ifidni %%dup, dup 150 <1> %assign %%isdup 1 151 <1> %elifidni %%dup, dup( 152 <1> %assign %%isdup 1 153 <1> %endif 154 <1> %if %%isdup 155 <1> %substr %%multi %%string 1, %%index - 1 156 <1> %deftok %%multi %%multi 157 <1> %substr %%string %%string %%index + 5, -1 158 <1> %deftok %%token %%string 159 <1> %undef %%param 160 <1> stripparens %define %%param, %%token 161 <1> %assign %%length 1 162 <1> %ifstr %%param 163 <1> %strlen %%length %%param 164 <1> %assign %%length (%%length + 3) / 4 165 <1> %endif 166 <1> %rep %%length * %%multi 167 <1> dd ? 168 <1> %endrep 169 <1> %exitrep 170 <1> %endif 171 <1> %endif 172 <1> %endif 173 <1> %assign %%index %%index + 1 174 <1> %endrep 175 <1> %ifempty %%multi 176 <1> %assign %%length 1 177 <1> %ifstr %%param 178 <1> %strlen %%length %%param 179 <1> %assign %%length (%%length + 3) / 4 180 <1> %endif 181 <1> %rep %%length 182 <1> dd ? 183 <1> %endrep 184 <1> %endif 185 <1> %rotate 1 186 <1> %endrep 187 <1> %endmacro 2 %define DONOBITS 3 %include "msdata.nas" 1 <1> ; SCCSID = @(#)ibmdata.asm 1.1 85/04/10 2 <1> ; 3 <1> ; DATA Segment for DOS. 4 <1> ; 5 <1> 6 <1> ;page 255,132 7 <1> 8 <1> [list -] 8 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 8 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <5> [list -] 14 <4> [list -] 3 <3> === Switch to base=001DC0h -> "DOSSTART" 4 <3> addsection DOSSTART, align=16 PUBLIC class=DOSSTART 5 <3> ; (no prior section) ; DOSSTART ENDS 6 <3> === Switch to base=001DC0h -> "DOSSTARTJUMP" 7 <3> addsection DOSSTARTJUMP, align=1 PUBLIC class=START 8 <3> ; (no prior section) ; DOSSTARTJUMP ENDS 9 <3> === Switch to base=001DC0h -> "CONSTANTS" 10 <3> addsection CONSTANTS, align=2 PUBLIC class=CONST 11 <3> ; (no prior section) ; CONSTANTS ENDS 12 <3> === Switch to base=001DC0h -> "DATA" 13 <3> addsection DATA, align=2 PUBLIC class=DATA 14 <3> ; (no prior section) ; DATA ENDS 15 <3> === Switch to base=001DC0h -> "TABLE" 16 <3> addsection TABLE, align=2 PUBLIC class=TABLE 17 <3> ; (no prior section) ; TABLE ENDS 18 <3> === Switch to base=001DC0h -> "DOSDATATABLE" 19 <3> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE 20 <3> ; (no prior section) ; DOSDATATABLE ENDS 21 <3> === Switch to base=001DC0h -> "DOSDATACODE" 22 <3> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE 23 <3> ; (no prior section) ; DOSDATACODE ENDS 24 <3> === Switch to base=001DC0h -> "DOSBIODATA" 25 <3> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA 26 <3> === Switch to base=001DC0h -> "LAST" 27 <3> addsection LAST, align=16 PUBLIC class=LAST 28 <3> ; (no prior section) ; LAST ENDS 29 <3> 30 <3> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST 31 <3> 32 <3> %include "entryseg.nas" 1 <4> 2 <4> %ifndef ENTRYSEGNAS 3 <4> %define ENTRYSEGNAS 1 4 <4> 5 <4> %include "lmacros3.mac" 1 <5> [list -] 6 <4> === Switch to base=003490h -> "DOSENTRY" 7 <4> addsection DOSENTRY, class=%[DOSENTRY] 8 <4> 9 <4> group DOSENTRYGROUP DOSENTRY 10 <4> 11 <4> %endif 8 <2> 9 <2> %include "dcodeseg.nas" 1 <3> 2 <3> %ifndef DCODESEGNAS 3 <3> %assign DCODESEGNAS 1 4 <3> === Switch to base=003490h -> "DOSCODETABLE" 5 <3> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <3> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <3> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <3> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <3> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <3> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <3> 12 <3> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <3> 14 <3> %endif 10 <2> === Switch to base=001DC0h -> "LAST" 11 <2> section LAST 12 <2> ; (no prior section) ; LAST ENDS 14 <1> debug equ FALSE ; No dossym (too big) 15 <1> %include "dosmac.mac" 1 <2> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dosmac.asm 1.1 85/04/10 3 <2> ; 4 <2> ; Macro file for MSDOS. 5 <2> ; 6 <2> 7 <2> %ifndef __DOSMAC_MAC__ 8 <2> %assign __DOSMAC_MAC__ 1 9 <2> 10 <2> TRUE EQU 0FFFFh 11 <2> FALSE EQU 0 12 <2> 13 <2> 14 <2> ; NASM original macros (comment for fixmem.pl) 15 <2> 16 <2> ;SUBTTL BREAK a listing into pages and give new subtitles 17 <2> ;PAGE 18 <2> %imacro BREAK 0-1+.nolist 19 <2> ;SUBTTL subtitle 20 <2> ;PAGE 21 <2> %endmacro 22 <2> ;.xcref break 23 <2> 24 <2> BREAK 25 <2> 26 <2> %if 0 27 <2> AsmVars Macro varlist 28 <2> IRP var, 29 <2> AsmVar var 30 <2> ENDM 31 <2> ENDM 32 <2> 33 <2> AsmVar Macro var 34 <2> IFNDEF var 35 <2> var = FALSE 36 <2> ENDIF 37 <2> ENDM 38 <2> %endif 39 <2> 40 <2> BREAK 41 <2> 42 <2> ; 43 <2> ; declare a variable external and allocate a size 44 <2> ; 45 <2> ;AsmVar InstalledData 46 <2> %ifndef InstalledData 47 <2> %define InstalledData 0 48 <2> %endif 49 <2> 50 <2> %imacro I_NEED 1-2.nolist 51 <2> %ifn InstalledData === Switch to base=001DC0h -> "DATA" 52 <2> [section DATA] 53 <2> %IFIDNi %2, WORD 54 <2> EXTRN %1:WORD 55 <2> %ELSE 56 <2> %IFIDNi %2, DWORD 57 <2> EXTRN %1:DWORD 58 <2> %ELSE 59 <2> EXTRN %1:BYTE 60 <2> %ENDIF 61 <2> %ENDIF 62 <2> __SECT__ 63 <2> %ENDIF 64 <2> %endmacro 65 <2> ;.xcref I_need 66 <2> 67 <2> ; 68 <2> ; call a procedure that may be external. The call will be short. 69 <2> ; 70 <2> %imacro invoke 1.nolist 71 <2> ;.xcref 72 <2> EXTRN %1:NEAR 73 <2> ;.cref 74 <2> CALL %1 75 <2> %endmacro 76 <2> ;.xcref invoke 77 <2> 78 <2> ;PAGE 79 <2> ; 80 <2> ; jump to a label that may be external. The jump will be near. 81 <2> ; 82 <2> %imacro transfer 1.nolist 83 <2> ;.xcref 84 <2> EXTRN %1:NEAR 85 <2> ;.cref 86 <2> JUMP %1 87 <2> %endmacro 88 <2> ;.xcref transfer 89 <2> 90 <2> ; 91 <2> ; get a short address in a word 92 <2> ; 93 <2> %imacro short_addr 1.nolist 94 <2> %ifnidn %1, ? 95 <2> EXTRN %1:NEAR 96 <2> DW OFFSET %1 97 <2> %ELSE 98 <2> DW ? 99 <2> %ENDIF 100 <2> %endmacro 101 <2> ;.xcref short_addr 102 <2> 103 <2> ; 104 <2> ; get a long address in a dword 105 <2> ; 106 <2> %imacro long_addr 1.nolist 107 <2> EXTRN %1:NEAR 108 <2> DD %1 109 <2> %endmacro 110 <2> ;.xcref long_addr 111 <2> 112 <2> ; 113 <2> ; declare a PROC near or far but PUBLIC nonetheless 114 <2> ; 115 <2> ;.xcref ?frame 116 <2> ;.xcref ?aframe 117 <2> ;.xcref ?stackdepth 118 <2> ;.xcref ?initstack 119 <2> %assign ?frame 0 ; initial 120 <2> %assign ?aframe 0 ; initial 121 <2> %assign ?stackdepth 0 ; initial stack size 122 <2> %assign ?initstack 0 ; initial stack size 123 <2> 124 <2> %imacro procedure 1-2.nolist 125 <2> %assign ?frame 0 126 <2> %assign ?aframe 2 ;; remember the pushed BP 127 <2> %warning proc %1... 128 <2> %1 PROC %2 129 <2> PUBLIC %1 130 <2> %assign ?initstack ?stackdepth ;; beginning of procedure 131 <2> %endmacro 132 <2> ;.xcref procedure 133 <2> 134 <2> ; 135 <2> ; end a procedure and check that stack depth is preserved 136 <2> ; 137 <2> %imacro EndProc 1-2.nolist 138 <2> %ifnidni %2, NoCheck ;; check the stack size 139 <2> %if ?initstack != ?stackdepth ;; is it different? 140 <2> %warning ***** Possible stack size error in %1 ***** 141 <2> %endif 142 <2> %endif 143 <2> %1 ENDP 144 <2> %endmacro 145 <2> ;.xcref endproc 146 <2> ;PAGE 147 <2> ; 148 <2> ; define a data item to be public and of an appropriate size/type 149 <2> ; 150 <2> 151 <2> %imacro stripangles 2.nolist 152 <2> %defstr %%param %2 153 <2> %rep 16 154 <2> %substr %%opening %%param 1 155 <2> %ifidn %%opening, '<' 156 <2> %substr %%param %%param 2,-1 157 <2> %endif 158 <2> %endrep 159 <2> %rep 16 160 <2> %strlen %%length %%param 161 <2> %substr %%closing %%param %%length 162 <2> %ifidn %%closing, '>' 163 <2> %substr %%param %%param 1,-2 164 <2> %endif 165 <2> %endrep 166 <2> %deftok %%token %%param 167 <2> %1 %%token 168 <2> %endmacro 169 <2> 170 <2> %imacro I_AM 2-*.nolist 171 <2> ;I_AM MACRO name,size,init 172 <2> %xdefine %%name %1 173 <2> ;; declare the type of the object 174 <2> %IFIDNi %2, WORD 175 <2> %1 LABEL WORD 176 <2> %assign I_AM_SIZE 1 177 <2> %assign I_AM_LEN 2 178 <2> %ELSE 179 <2> %IFIDNi %2, DWORD 180 <2> %1 LABEL DWORD 181 <2> %assign I_AM_SIZE 2 182 <2> %assign I_AM_LEN 2 183 <2> %ELSE 184 <2> %IFIDNi %2, BYTE 185 <2> %1 LABEL BYTE 186 <2> %assign I_AM_SIZE 1 187 <2> %assign I_AM_LEN 1 188 <2> %ELSE 189 <2> %1 LABEL BYTE 190 <2> %undef I_AM_SIZE 191 <2> stripangles %assign I_AM_SIZE, %2 192 <2> %assign I_AM_LEN 1 193 <2> %ENDIF 194 <2> %ENDIF 195 <2> %ENDIF 196 <2> ;; declare the object public 197 <2> PUBLIC %%name 198 <2> ;; if no initialize then allocate blank storage 199 <2> %IF %0 == 2 200 <2> DB I_AM_SIZE*I_AM_LEN DUP (?) 201 <2> %ELSE 202 <2> %ifn InstalledData 203 <2> %rotate 2 204 <2> %rep %0 - 2 205 <2> %IF I_AM_LEN == 1 206 <2> stripangles db, %1 207 <2> %ELSE 208 <2> stripangles dw, %1 209 <2> %ENDIF 210 <2> %assign I_AM_SIZE I_AM_SIZE - 1 211 <2> %rotate 1 212 <2> %endrep 213 <2> %IF I_AM_SIZE != 0 214 <2> %error ***** initialization of %%name not complete ***** 215 <2> %ENDIF 216 <2> %ELSE 217 <2> DB I_AM_SIZE*I_AM_LEN DUP (?) 218 <2> %ENDIF 219 <2> %ENDIF 220 <2> %endmacro 221 <2> 222 <2> %imacro I_AM_NOBITS 2-*.nolist 223 <2> ;I_AM MACRO name,size,init 224 <2> %xdefine %%name %1 225 <2> ;; declare the type of the object 226 <2> %IFIDNi %2, WORD 227 <2> %1 LABEL WORD 228 <2> %assign I_AM_SIZE 1 229 <2> %assign I_AM_LEN 2 230 <2> %ELSE 231 <2> %IFIDNi %2, DWORD 232 <2> %1 LABEL DWORD 233 <2> %assign I_AM_SIZE 2 234 <2> %assign I_AM_LEN 2 235 <2> %ELSE 236 <2> %IFIDNi %2, BYTE 237 <2> %1 LABEL BYTE 238 <2> %assign I_AM_SIZE 1 239 <2> %assign I_AM_LEN 1 240 <2> %ELSE 241 <2> %1 LABEL BYTE 242 <2> %undef I_AM_SIZE 243 <2> stripangles %assign I_AM_SIZE, %2 244 <2> %assign I_AM_LEN 1 245 <2> %ENDIF 246 <2> %ENDIF 247 <2> %ENDIF 248 <2> ;; declare the object public 249 <2> PUBLIC %%name 250 <2> ;; if no initialize then allocate blank storage 251 <2> %IF %0 == 2 252 <2> resb I_AM_SIZE*I_AM_LEN 253 <2> %ELSE 254 <2> %ifn InstalledData 255 <2> %rotate 2 256 <2> %rep %0 - 2 257 <2> %IF I_AM_LEN == 1 258 <2> resb 1 259 <2> %ELSE 260 <2> resw 1 261 <2> %ENDIF 262 <2> %assign I_AM_SIZE I_AM_SIZE - 1 263 <2> %rotate 1 264 <2> %endrep 265 <2> %IF I_AM_SIZE != 0 266 <2> %error ***** initialization of %%name not complete ***** 267 <2> %ENDIF 268 <2> %ELSE 269 <2> resb I_AM_SIZE*I_AM_LEN 270 <2> %ENDIF 271 <2> %ENDIF 272 <2> %endmacro 273 <2> 274 <2> ;.xcref I_AM 275 <2> ;.xcref I_AM_SIZE 276 <2> ;.xcref I_AM_LEN 277 <2> %assign I_AM_SIZE 0 278 <2> %assign I_AM_LEN 0 279 <2> 280 <2> ;PAGE 281 <2> 282 <2> ; 283 <2> ; define an entry in a procedure 284 <2> ; 285 <2> %imacro entry 1.nolist 286 <2> %1: 287 <2> PUBLIC %1 288 <2> %endmacro 289 <2> ;.xcref entry 290 <2> 291 <2> BREAK 292 <2> 293 <2> %imacro error 1.nolist 294 <2> ;.xcref 295 <2> MOV AL, %1 296 <2> transfer SYS_RET_ERR 297 <2> ;.cref 298 <2> %endmacro 299 <2> ;.xcref error 300 <2> 301 <2> BREAK 302 <2> ; 303 <2> ; given a label either 2 byte jump to another label _J 304 <2> ; if it is near enough or 3 byte jump to 305 <2> ; 306 <2> 307 <2> %imacro jump 1.nolist 308 <2> ;.xcref 309 <2> 310 <2> %ifndef %1_J ;; is this the first invocation 311 <2> %%a: JMP %1 312 <2> %ELSE 313 <2> %IF (%1_J >= $) || ($-%1_J > 126) 314 <2> %%a: JMP %1 ;; is the jump too far away? 315 <2> %ELSE 316 <2> %%a: JMP %1_J ;; do the short one... 317 <2> %ENDIF 318 <2> %ENDIF 319 <2> %ixdefine %1_j %%a 320 <2> ;.cref 321 <2> %endmacro 322 <2> ;.xcref jump 323 <2> 324 <2> BREAK 325 <2> 326 <2> %imacro return 0.nolist 327 <2> %%a: 328 <2> RET 329 <2> %xdefine ret_l %%a 330 <2> %endmacro 331 <2> ;.xcref return 332 <2> 333 <2> BREAK 334 <2> 335 <2> %imacro condret 2.nolist 336 <2> %assign %%exit 0 337 <2> %ifdef ret_l ;; if ret_l is defined 338 <2> %if (($ - ret_l) <= 126) && ($ > ret_l) 339 <2> ;; if ret_l is near enough then 340 <2> %%a: j%1 ret_l ;; a: j to ret_l 341 <2> %xdefine ret_%1 %%a ;; define ret_ to be a: 342 <2> %assign %%exit 1 343 <2> %endif 344 <2> %endif 345 <2> %ifn %%exit 346 <2> %ifdef ret_%1 ;; if ret_ defined 347 <2> %if (($ - ret_%1) <= 126) && ($ > ret_%1) 348 <2> ;; if ret_ is near enough 349 <2> %%a: j%1 ret_%1 ;; a: j to ret_ 350 <2> %xdefine ret_%1 %%a ;; define ret_ to be a: 351 <2> %assign %%exit 1 352 <2> %endif 353 <2> %endif 354 <2> %endif 355 <2> %ifn %%exit 356 <2> j%2 %%a ;; j a: 357 <2> return ;; return 358 <2> %%a: ;; a: 359 <2> %xdefine ret_%1 ret_l ;; define ret_ to be ret_l 360 <2> %endif 361 <2> %endmacro 362 <2> ;.xcref condret 363 <2> 364 <2> BREAK 365 <2> 366 <2> %imacro retz 0.nolist 367 <2> condret z,nz 368 <2> %endmacro 369 <2> ;.xcref retz 370 <2> 371 <2> BREAK 372 <2> 373 <2> %imacro retnz 0.nolist 374 <2> condret nz,z 375 <2> %endmacro 376 <2> ;.xcref retnz 377 <2> 378 <2> BREAK 379 <2> 380 <2> %imacro retc 0.nolist 381 <2> condret c,nc 382 <2> %endmacro 383 <2> ;.xcref retc 384 <2> 385 <2> BREAK 386 <2> 387 <2> %imacro retnc 0.nolist 388 <2> condret nc,c 389 <2> %endmacro 390 <2> ;.xcref retnc 391 <2> 392 <2> BREAK 393 <2> 394 <2> %imacro context 1.nolist 395 <2> PUSH SS 396 <2> stripangles POP, %1 397 <2> ; ASSUME %1:DOSGROUP 398 <2> %endmacro 399 <2> ;.xcref context 400 <2> 401 <2> BREAK 402 <2> 403 <2> %imacro SaveReg 0-*.nolist ;; push those registers 404 <2> %rep %0 405 <2> %assign ?stackdepth ?stackdepth + 1 406 <2> stripangles push, %1 407 <2> %rotate 1 408 <2> %endrep 409 <2> %endmacro 410 <2> ;.xcref SaveReg 411 <2> 412 <2> BREAK 413 <2> 414 <2> %imacro RestoreReg 0-*.nolist ;; pop those registers 415 <2> %rep %0 416 <2> %assign ?stackdepth ?stackdepth - 1 417 <2> stripangles pop, %1 418 <2> %rotate 1 419 <2> %endrep 420 <2> %endmacro 421 <2> ;.xcref RestoreReg 422 <2> 423 <2> BREAK 424 <2> 425 <2> %imacro EnterCrit 1.nolist 426 <2> Invoke E%1 427 <2> %endmacro 428 <2> 429 <2> %imacro LeaveCrit 1.nolist 430 <2> Invoke L%1 431 <2> %endmacro 432 <2> 433 <2> Break 434 <2> 435 <2> ;AsmVars 436 <2> %ifndef ShareF 437 <2> %idefine ShareF 0 438 <2> %endif 439 <2> %ifndef Cargs 440 <2> %idefine Cargs 0 441 <2> %endif 442 <2> %ifndef Redirector 443 <2> %idefine Redirector 0 444 <2> %endif 445 <2> %ifndef debug 446 <2> %idefine debug 0 447 <2> %endif 448 <2> 449 <2> %if debug 450 <2> %imacro fmt 3-*.nolist 451 <2> ;fmt MACRO typ,lev,fmts,args 452 <2> ;local a,b,c 453 <2> PUSHF 454 <2> %IFNempty %1 455 <2> TEST word [BugTyp],%1 456 <2> JZ %%c 457 <2> CMP word [BugLev],%2 458 <2> JB %%c 459 <2> %ENDIF 460 <2> PUSH AX 461 <2> PUSH BP 462 <2> MOV BP,SP 463 <2> %If (! sharef) && (! redirector) === Switch to base=001DC0h -> "TABLE" 464 <2> [section Table] 465 <2> %%a: db %3,0 466 <2> __SECT__ 467 <2> MOV AX,OFFSET %%a wrt DOSGROUP 468 <2> %else 469 <2> jmp short %%b 470 <2> %%a: db %3,0 471 <2> %if sharef 472 <2> %%b: mov ax,offset %%a wrt share 473 <2> %else 474 <2> %%b: mov ax,offset %%a wrt netwrk 475 <2> %endif 476 <2> %endif 477 <2> PUSH AX 478 <2> %iassign cargs 2 479 <2> %rotate 3 480 <2> %rep %0 - 3 481 <2> %ifidni ax, %1 482 <2> MOV AX,[BP+2] 483 <2> %ELSE 484 <2> MOV AX, %1 485 <2> %ENDIF 486 <2> PUSH AX 487 <2> %iassign cargs cargs + 2 488 <2> %rotate 1 489 <2> %endrep 490 <2> invoke PFMT 491 <2> ADD SP, Cargs 492 <2> POP BP 493 <2> POP AX 494 <2> %%c: 495 <2> POPF 496 <2> %endmacro 497 <2> %else 498 <2> %imacro fmt 3-*.nolist 499 <2> %endmacro 500 <2> %endif 501 <2> 502 <2> Break 503 <2> 504 <2> ;AsmVar Debug,$temp 505 <2> 506 <2> %imacro detectstripangles 4.nolist 507 <2> %defstr %%param %4 508 <2> %assign ?%2 0 509 <2> %assign ?%3 0 510 <2> %rep 16 511 <2> %substr %%opening %%param 1 512 <2> %ifidn %%opening, '<' 513 <2> %substr %%param %%param 2,-1 514 <2> %assign ?%2 ?%2 + 1 515 <2> %endif 516 <2> %endrep 517 <2> %rep 16 518 <2> %strlen %%length %%param 519 <2> %substr %%closing %%param %%length 520 <2> %ifidn %%closing, '>' 521 <2> %substr %%param %%param 1,-2 522 <2> %assign ?%3 ?%3 + 1 523 <2> %endif 524 <2> %endrep 525 <2> %deftok %%token %%param 526 <2> %define ?%1 %%token 527 <2> %endmacro 528 <2> 529 <2> 530 <2> %IF debug 531 <2> %imacro DOSAssume 3-*.nolist 532 <2> ;DOSAssume Macro reg,reglist,message 533 <2> %ifidni %1, CS 534 <2> %assign %%temp 1 535 <2> %else 536 <2> %ifidni %1, SS 537 <2> %assign %%temp 0 538 <2> %else 539 <2> %error ***** Invalid DOS register %1 in DOSAssume ***** 540 <2> %endif 541 <2> %endif 542 <2> %rotate 1 543 <2> %assign %%level 0 544 <2> %assign %%amount %0 - 1 545 <2> %rep 16 546 <2> detectstripangles %%token, %%opening, %%closing, %1 547 <2> %assign %%level %%level + ? %+ %%opening 548 <2> %assign %%level %%level - ? %+ %%closing 549 <2> %ifidni ? %+ %%token, DS 550 <2> %assign %%temp %%temp | 2 551 <2> %else 552 <2> %ifidni ? %+ %%token, ES 553 <2> %assign %%temp %%temp | 4 554 <2> %else 555 <2> %error ***** Invalid register reg in DOSAssume ***** 556 <2> %endif 557 <2> %endif 558 <2> %assign %%amount %%amount - 1 559 <2> %rotate 1 560 <2> %if %%level <= 0 561 <2> %exitrep 562 <2> %endif 563 <2> %endrep 564 <2> 565 <2> PUSH AX 566 <2> MOV AX, %%temp 567 <2> PUSH AX 568 <2> %IF SHAREF 569 <2> MOV AX,OFFSET %%a 570 <2> %ELSE 571 <2> MOV AX,OFFSET %%a wrt DOSGroup 572 <2> %ENDIF 573 <2> PUSH AX 574 <2> Invoke SegCheck 575 <2> POP AX 576 <2> %IFN SHAREF === Switch to base=001DC0h -> "TABLE" 577 <2> [section Table] 578 <2> %ELSE 579 <2> JMP SHORT %%b 580 <2> %ENDIF 581 <2> %%a: 582 <2> %rep %%amount 583 <2> DB %1 584 <2> %rotate 1 585 <2> %endrep 586 <2> db 0 587 <2> %IFN SHAREF 588 <2> __SECT__ 589 <2> %ELSE 590 <2> %%b: 591 <2> %ENDIF 592 <2> ;IRP r, 593 <2> ; ASSUME r:DOSGroup 594 <2> ;ENDM 595 <2> %endmacro 596 <2> %ELSE 597 <2> %imacro DOSAssume 3-*.nolist 598 <2> ;DOSAssume Macro reg,reglist,message 599 <2> ;IRP r, 600 <2> ; ASSUME r:DOSGroup 601 <2> ;ENDM 602 <2> %endmacro 603 <2> %ENDIF 604 <2> 605 <2> BREAK 606 <2> 607 <2> %if 0 608 <2> ;IF DEBUG 609 <2> Assert MACRO kind, objs, message 610 <2> LOCAL a,b 611 <2> IFIDN , 612 <2> CMP objs,0 613 <2> JZ a 614 <2> fmt <>,<>, 615 <2> a: 616 <2> ELSE 617 <2> IFIDN , 618 <2> CMP objs,0 619 <2> JNZ a 620 <2> fmt <>,<>, 621 <2> a: 622 <2> ELSE 623 <2> PUSH AX 624 <2> IRP obj, 625 <2> PUSH obj 626 <2> ENDM 627 <2> IF SHAREF 628 <2> MOV AX,OFFSET b 629 <2> ELSE 630 <2> MOV AX,OFFSET DOSGroup:b 631 <2> ENDIF 632 <2> PUSH AX 633 <2> IFIDN , 634 <2> Invoke BUFCheck 635 <2> ENDIF 636 <2> IFIDN , 637 <2> Invoke SFTCheck 638 <2> ENDIF 639 <2> IFIDN , 640 <2> Invoke DPBCheck 641 <2> ENDIF 642 <2> POP AX 643 <2> IF SHAREF 644 <2> JMP SHORT a 645 <2> b DB Message,0 646 <2> a: 647 <2> ELSE === Switch to base=001DC0h -> "TABLE" 648 <2> Table segment 649 <2> b db Message,0 === Switch to base=001DC0h -> "TABLE" 650 <2> Table ends 651 <2> ENDIF 652 <2> ENDIF 653 <2> ENDIF 654 <2> ENDM 655 <2> %ELSE 656 <2> %imacro Assert 0-*.nolist 657 <2> %endmacro 658 <2> %ENDIF 659 <2> 660 <2> %ifndef Installed 661 <2> %idefine Installed 1 662 <2> %endif 663 <2> 664 <2> Break 665 <2> 666 <2> %imacro CallInstall 3-*.nolist 667 <2> ;CallInstall MACRO name,mpx,fn,save,restore 668 <2> %define %%name %1 669 <2> %assign %%mpx %2 670 <2> %assign %%fn %3 671 <2> %IF Installed 672 <2> %rotate 3 673 <2> %assign %%level 0 674 <2> %assign %%amountsaved 0 675 <2> %rep %0 - 3 676 <2> %ifnempty %1 677 <2> detectstripangles %%token, %%opening, %%closing, %1 678 <2> %assign %%level %%level + ? %+ %%opening 679 <2> %assign %%level %%level - ? %+ %%closing 680 <2> SaveReg ? %+ %%token 681 <2> %endif 682 <2> %assign %%amountsaved %%amountsaved + 1 683 <2> %rotate 1 684 <2> %if %%level <= 0 685 <2> %exitrep 686 <2> %endif 687 <2> %endrep 688 <2> MOV AX,(%%mpx << 8) + %%fn 689 <2> INT 2Fh 690 <2> %assign %%level 0 691 <2> %assign %%amountrestored 0 692 <2> %rep %0 - 3 - %%amountsaved 693 <2> %ifnempty %1 694 <2> detectstripangles %%token, %%opening, %%closing, %1 695 <2> %assign %%level %%level + ? %+ %%opening 696 <2> %assign %%level %%level - ? %+ %%closing 697 <2> RestoreReg ? %+ %%token 698 <2> %endif 699 <2> %assign %%amountrestored %%amountrestored + 1 700 <2> %rotate 1 701 <2> %if %%level <= 0 702 <2> %exitrep 703 <2> %endif 704 <2> %endrep 705 <2> %if %%level > 0 || %0 != 3 + %%amountsaved + %%amountrestored 706 <2> %error Wrong amount saved or restored 707 <2> %endif 708 <2> %ELSE 709 <2> Invoke %%name 710 <2> %ENDIF 711 <2> %endmacro 712 <2> 713 <2> Break 714 <2> 715 <2> %imacro localvar 2.nolist 716 <2> %ifidni %2, BYTE 717 <2> %assign ?frame ?frame + 1 718 <2> %assign %%a ?frame 719 <2> labelsize %1, byte, bp - %%a 720 <2> %else 721 <2> %ifidni %2, WORD 722 <2> %assign ?frame ?frame + 2 723 <2> %assign %%a ?frame 724 <2> labelsize %1, word, bp - %%a 725 <2> %else 726 <2> %ifidni %2, DWORD 727 <2> %assign ?frame ?frame + 4 728 <2> %assign %%a ?frame 729 <2> labelsize %1 %+ l, word, bp - %%a 730 <2> labelsize %1 %+ h, word, bp - %%a + 2 731 <2> labelsize %1, dword, bp - %%a 732 <2> %else 733 <2> %assign ?frame ?frame + %2 734 <2> %assign %%a ?frame 735 <2> labelsize %1, byte, bp - %%a 736 <2> %endif 737 <2> %endif 738 <2> %endif 739 <2> %endmacro 740 <2> 741 <2> %imacro enter 0.nolist 742 <2> push bp 743 <2> mov bp,sp 744 <2> sub sp,?frame 745 <2> %endmacro 746 <2> 747 <2> %imacro leave 0.nolist 748 <2> mov sp,bp 749 <2> pop bp 750 <2> %endmacro 751 <2> 752 <2> 753 <2> %imacro argvar 2.nolist 754 <2> %ifidni %2, BYTE 755 <2> %assign %%a ?aframe 756 <2> %assign ?aframe ?aframe + 1 757 <2> labelsize %1, byte, bp + %%a 758 <2> %else 759 <2> %ifidni %2, WORD 760 <2> %assign %%a ?aframe 761 <2> %assign ?aframe ?aframe + 2 762 <2> labelsize %1, word, bp + %%a 763 <2> %else 764 <2> %ifidni %2, DWORD 765 <2> %assign %%a ?aframe 766 <2> %assign ?aframe ?aframe + 4 767 <2> labelsize %1 %+ l, word, bp + %%a 768 <2> labelsize %1 %+ h, word, bp + %%a + 2 769 <2> labelsize %1, dword, bp + %%a 770 <2> %else 771 <2> %assign %%a ?aframe 772 <2> %assign ?aframe ?aframe + %2 773 <2> labelsize %1, byte, bp + %%a 774 <2> %endif 775 <2> %endif 776 <2> %endif 777 <2> %endmacro 778 <2> 779 <2> BREAK 780 <2> 781 <2> %imacro errnz 1.nolist 782 <2> detectstripangles %%token, %%opening, %%closing, %1 783 <2> %if ? %+ %%token 784 <2> %error %1 <> 0 785 <2> %endif 786 <2> %endmacro 787 <2> 788 <2> %endif 16 <1> %include "sf.mac" 1 <2> ; SCCSID = @(#)sf.asm 1.1 85/04/10 2 <2> BREAK 3 <2> ; 4 <2> ; AN000 version 4.00 Jan. 1988 5 <2> ; AN003 PTM 3680 -- make NAME offset the same as before (<=3.30) 6 <2> ; AN009 PTM 3839 reorder SFT for MS WINDOWS 7 <2> 8 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 9 <2> ; C A V E A T P R O G R A M M E R ; 10 <2> ; ; 11 <2> ; 12 <2> ; system file table 13 <2> ; 14 <2> 15 <2> SF STRUC 0 00000D12 ???????? SFLink DD ? 0 00000D16 ???? SFCount DW ? ; number of entries 0 00000D18 ???? SFTable DW ? ; beginning of array of the following 19 <2> SF ENDS 20 <2> 21 <2> ; 22 <2> ; system file table entry 23 <2> ; 24 <2> 25 <2> sf_entry STRUC 0 00000D12 ???? sf_ref_count DW ? ; number of processes sharing entry 27 <2> ; if FCB then ref count 0 00000D14 ???? sf_mode DW ? ; mode of access or high bit on if FCB 0 00000D16 ?? sf_attr DB ? ; attribute of file 0 00000D17 ???? sf_flags DW ? ;Bits 8-15 31 <2> ; Bit 15 = 1 if remote file 32 <2> ; = 0 if local file or device 33 <2> ; Bit 14 = 1 if date/time is not to be 34 <2> ; set from clock at CLOSE. Set by 35 <2> ; FILETIMES and FCB_CLOSE. Reset by 36 <2> ; other reseters of the dirty bit 37 <2> ; (WRITE) 38 <2> ; Bit 13 = Pipe bit (reserved) 39 <2> ; 40 <2> ; Bits 0-7 (old FCB_devid bits) 41 <2> ; If remote file or local file, bit 42 <2> ; 6=0 if dirty Device ID number, bits 43 <2> ; 0-5 if local file. 44 <2> ; bit 7=0 for local file, bit 7 45 <2> ; =1 for local I/O device 46 <2> ; If local I/O device, bit 6=0 if EOF (input) 47 <2> ; Bit 5=1 if Raw mode 48 <2> ; Bit 0=1 if console input device 49 <2> ; Bit 1=1 if console output device 50 <2> ; Bit 2=1 if null device 51 <2> ; Bit 3=1 if clock device 0 00000D19 ???????? sf_devptr DD ? ; Points to DPB if local file, points 53 <2> ; to device header if local device, 54 <2> ; points to net device header if 55 <2> ; remote 0 00000D1D ???? sf_firclus DW ? ; First cluster of file (bit 15 = 0) 0 00000D1F ???? sf_time DW ? ; Time associated with file 0 00000D21 ???? sf_date DW ? ; Date associated with file 0 00000D23 ???????? sf_size DD ? ; Size associated with file 0 00000D27 ???????? sf_position DD ? ; Read/Write pointer or LRU count for FCBs 61 <2> ; 62 <2> ; Starting here, the next 7 bytes may be used by the file system to store an 63 <2> ; ID 64 <2> ; 0 00000D2B ???? sf_cluspos DW ? ; Position of last cluster accessed 0 00000D2D ???????? sf_dirsec DD ? ; Sector number of directory sector for 67 <2> ; for this file 0 00000D31 ?? sf_dirpos DB ? ; Offset of this entry in the above 69 <2> ; 70 <2> ; End of 7 bytes of file-system specific info. 71 <2> ; 0 00000D32 ?????????????????? sf_name DB 11 DUP (?) ; 11 character name that is in the 72 00000029 ???? <2> 73 <2> ; directory entry. This is used by 74 <2> ; close to detect file deleted and 75 <2> ; disk changed errors. 76 <2> 77 <2> ; SHARING INFO 0 00000D3D ???????? sf_chain DD ? ; link to next SF 0 00000D41 ???? sf_UID DW ? 0 00000D43 ???? sf_PID DW ? 0 00000D45 ???? sf_MFT DW ? 0 00000D47 ???? sf_lstclus DW ? ;AN009; Last cluster accessed 0 00000D49 ???????? sf_IFS_HDR DD ? 84 <2> sf_entry ENDS 85 <2> 86 <2> labelsize sf_fsda, byte, sf_cluspos ;DOS 4.00 87 <2> labelsize sf_serial_ID, word, sf_firclus ;DOS 4.00 88 <2> labelsize sf_netid, byte, sf_cluspos 89 <2> labelsize sf_OpenAge, word, sf_position+2 90 <2> labelsize sf_LRU, word, sf_position 91 <2> 92 <2> sf_default_number EQU 5h 93 <2> 94 <2> ; 95 <2> ; Note that we need to mark an SFT as being busy for OPEN/CREATE. This is 96 <2> ; because an INT 24 may prevent us from 'freeing' it. We mark this as such 97 <2> ; by placing a -1 in the ref_count field. 98 <2> ; 99 <2> 100 <2> sf_busy EQU -1 101 <2> 102 <2> 103 <2> ; mode mask for FCB detection 104 <2> sf_isfcb EQU 1000000000000000B 105 <2> 106 <2> ; Flag word masks 107 <2> sf_isnet EQU 1000000000000000B 108 <2> sf_close_nodate EQU 0100000000000000B 109 <2> sf_pipe EQU 0010000000000000B 110 <2> sf_no_inherit EQU 0001000000000000B 111 <2> sf_net_spool EQU 0000100000000000B 112 <2> Handle_Fail_I24 EQU 0000000100000000B ;BIT 8 - DISK FULL I24 ERROR 113 <2> 114 <2> ; Local file/device flag masks 115 <2> devid_file_clean EQU 40h ; true if file and not written 116 <2> devid_file_mask_drive EQU 3Fh ; mask for drive number 117 <2> 118 <2> devid_device EQU 80h ; true if a device 119 <2> devid_device_EOF EQU 40h ; true if end of file reached 120 <2> devid_device_raw EQU 20h ; true if in raw mode 121 <2> devid_device_special EQU 10h ; true if special device 122 <2> devid_device_clock EQU 08h ; true if clock device 123 <2> devid_device_null EQU 04h ; true if null device 124 <2> devid_device_con_out EQU 02h ; true if console output 125 <2> devid_device_con_in EQU 01h ; true if consle input 126 <2> ; ; 127 <2> ; C A V E A T P R O G R A M M E R ; 128 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 129 <2> 130 <2> ; 131 <2> ; structure of devid field as returned by IOCTL is: 132 <2> ; 133 <2> ; BIT 7 6 5 4 3 2 1 0 134 <2> ; |---|---|---|---|---|---|---|---| 135 <2> ; | I | E | R | S | I | I | I | I | 136 <2> ; | S | O | A | P | S | S | S | S | 137 <2> ; | D | F | W | E | C | N | C | C | 138 <2> ; | E | | | C | L | U | O | I | 139 <2> ; | V | | | L | K | L | T | N | 140 <2> ; |---|---|---|---|---|---|---|---| 141 <2> ; ISDEV = 1 if this channel is a device 142 <2> ; = 0 if this channel is a disk file 143 <2> ; 144 <2> ; If ISDEV = 1 145 <2> ; 146 <2> ; EOF = 0 if End Of File on input 147 <2> ; RAW = 1 if this device is in Raw mode 148 <2> ; = 0 if this device is cooked 149 <2> ; ISCLK = 1 if this device is the clock device 150 <2> ; ISNUL = 1 if this device is the null device 151 <2> ; ISCOT = 1 if this device is the console output 152 <2> ; ISCIN = 1 if this device is the console input 153 <2> ; 154 <2> ; If ISDEV = 0 155 <2> ; EOF = 0 if channel has been written 156 <2> ; Bits 0-5 are the block device number for 157 <2> ; the channel (0 = A, 1 = B, ...) 158 <2> ; 159 <2> devid_ISDEV EQU 80h 160 <2> devid_EOF EQU 40h 161 <2> devid_RAW EQU 20h 162 <2> devid_SPECIAL EQU 10H 163 <2> devid_ISCLK EQU 08h 164 <2> devid_ISNUL EQU 04h 165 <2> devid_ISCOT EQU 02h 166 <2> devid_ISCIN EQU 01h 167 <2> 168 <2> devid_block_dev EQU 1Fh ; mask for block device number 17 <1> %include "dirent.mac" 1 <2> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dirent.asm 1.1 85/04/10 3 <2> Break 4 <2> 5 <2> ; 6 <2> ; +---------------------------+ 7 <2> ; | (12 BYTE) filename/ext | 0 0 8 <2> ; +---------------------------+ 9 <2> ; | (BYTE) attributes | 11 B 10 <2> ; +---------------------------+ 11 <2> ; | (10 BYTE) reserved | 12 C 12 <2> ; +---------------------------+ 13 <2> ; | (WORD) time of last write | 22 16 14 <2> ; +---------------------------+ 15 <2> ; | (WORD) date of last write | 24 18 16 <2> ; +---------------------------+ 17 <2> ; | (WORD) First cluster | 26 1A 18 <2> ; +---------------------------+ 19 <2> ; | (DWORD) file size | 28 1C 20 <2> ; +---------------------------+ 21 <2> ; 22 <2> ; First byte of filename = E5 -> free directory entry 23 <2> ; = 00 -> end of allocated directory 24 <2> ; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour 25 <2> ; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980 26 <2> ; 27 <2> 28 <2> dir_entry STRUC 0 00000D12 ?????????????????? dir_name DB 11 DUP (?) ; file name 29 00000009 ???? <2> 0 00000D1D ?? dir_attr DB ? ; attribute bits 0 00000D1E ???? dir_codepg dw ? ; code page DOS 4.00 0 00000D20 ???? dir_extcluster dw ? ; extended attribute starting cluster 0 00000D22 ?? dir_attr2 db ? ; reserved 0 00000D23 ?????????? dir_pad DB 5 DUP (?) ; reserved for expansion 0 00000D28 ???? dir_time DW ? ; time of last write 0 00000D2A ???? dir_date DW ? ; date of last write 0 00000D2C ???? dir_first DW ? ; first allocation unit of file 0 00000D2E ???? dir_size_l DW ? ; low 16 bits of file size 0 00000D30 ???? dir_size_h DW ? ; high 16 bits of file size 40 <2> dir_entry ENDS 41 <2> 42 <2> attr_read_only EQU 1h 43 <2> attr_hidden EQU 2h 44 <2> attr_system EQU 4h 45 <2> attr_volume_id EQU 8h 46 <2> attr_directory EQU 10h 47 <2> attr_archive EQU 20h 48 <2> attr_device EQU 40h ; This is a VERY special bit. 49 <2> ; NO directory entry on a disk EVER 50 <2> ; has this bit set. It is set non-zero 51 <2> ; when a device is found by GETPATH 52 <2> 53 <2> attr_all EQU attr_hidden+attr_system+attr_directory 54 <2> ; OR of hard attributes for FINDENTRY 55 <2> 56 <2> attr_ignore EQU attr_read_only+attr_archive+attr_device 57 <2> ; ignore this(ese) attribute(s) during 58 <2> ; search first/next 59 <2> 60 <2> attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive 61 <2> ; changeable via CHMOD 18 <1> %include "curdir.mac" 1 <2> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)curdir.asm 1.1 85/04/10 3 <2> BREAK 4 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <2> ; C A V E A T P R O G R A M M E R ; 6 <2> ; ; 7 <2> ; CDS items are used bu the internal routines to store cluster numbers and ; 8 <2> ; network identifiers for each logical name. The ID field is used dually, ; 9 <2> ; both as net ID and for a cluster number for local devices. In the case ; 10 <2> ; of local devices, the cluster number will be -1 if there is a potential ; 11 <2> ; of the disk being changed or if the path must be recracked. The END ; 12 <2> ; field is the location of the end of the definition. No .. is allowed ; 13 <2> ; past this point ; 14 <2> 15 <2> DIRSTRLEN EQU 64+3 ; Max length in bytes of directory strings 16 <2> TEMPLEN EQU DIRSTRLEN*2 17 <2> 18 <2> curdir_list STRUC 0 00000D12 ?????????????????? curdir_text DB DIRSTRLEN DUP (?) ; text of assignment and curdir 19 00000009 ??????????????????- <2> 19 00000012 ??????????????????- <2> 19 0000001B ??????????????????- <2> 19 00000024 ??????????????????- <2> 19 0000002D ??????????????????- <2> 19 00000036 ??????????????????- <2> 19 0000003F ???????? <2> 0 00000D55 ???? curdir_flags DW ? ; various flags 0 00000D57 ???????? curdir_devptr DD ? ; local pointer to DPB or net device 0 00000D5B ???? curdir_ID DW ? ; cluster of current dir (net ID) 0 00000D5D ???? DW ? 0 00000D5F ???? curdir_user_word DW ? 0 00000D61 ???? curdir_end DW ? ; end of assignment 0 00000D63 ?? curdir_type DB ? ; IFS drive (2=ifs, 4=netuse) 0 00000D64 ???????? curdir_ifs_hdr DD ? ; Ptr to File System Header 0 00000D68 ???? curdir_fsda DB 2 DUP (?) ; File System Dependent Data Area 29 <2> curdir_list ENDS 30 <2> 31 <2> curdirLen EQU curdir_list_struc_size ; Needed for screwed up 32 <2> ; ASM87 which doesn't allow 33 <2> ; Size directive as a macro 34 <2> ; argument 35 <2> labelsize curdir_netID, dword, curdir_ID 36 <2> 37 <2> ;Flag word masks 38 <2> curdir_isnet EQU 1000000000000000B 39 <2> curdir_isifs EQU 1000000000000000B ; DOS 4.00 40 <2> curdir_inuse EQU 0100000000000000B 41 <2> curdir_splice EQU 0010000000000000B 42 <2> curdir_local EQU 0001000000000000B 43 <2> ; ; 44 <2> ; C A V E A T P R O G R A M M E R ; 45 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 19 <1> %include "dpb.mac" 1 <2> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)dpb.asm 1.1 85/04/10 3 <2> BREAK 4 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <2> ; C A V E A T P R O G R A M M E R ; 6 <2> ; ; 7 <2> dpb STRUC 0 00000D12 ?? dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...) 0 00000D13 ?? dpb_UNIT DB ? ; Driver unit number of DPB 0 00000D14 ???? dpb_sector_size DW ? ; Size of physical sector in bytes 0 00000D16 ?? dpb_cluster_mask DB ? ; Sectors/cluster - 1 0 00000D17 ?? dpb_cluster_shift DB ? ; Log2 of sectors/cluster 0 00000D18 ???? dpb_first_FAT DW ? ; Starting record of FATs 0 00000D1A ?? dpb_FAT_count DB ? ; Number of FATs for this drive 0 00000D1B ???? dpb_root_entries DW ? ; Number of directory entries 0 00000D1D ???? dpb_first_sector DW ? ; First sector of first cluster 0 00000D1F ???? dpb_max_cluster DW ? ; Number of clusters on drive + 1 0 00000D21 ???? dpb_FAT_size DW ? ;;Number of records occupied by FAT 0 00000D23 ???? dpb_dir_sector DW ? ; Starting record of directory 0 00000D25 ???????? dpb_driver_addr DD ? ; Pointer to driver 0 00000D29 ?? dpb_media DB ? ; Media byte 0 00000D2A ?? dpb_first_access DB ? ; This is initialized to -1 to force a media 23 <2> ; check the first time this DPB is used 0 00000D2B ???????? dpb_next_dpb DD ? ; Pointer to next Drive parameter block 0 00000D2F ???? dpb_next_free DW ? ; Cluster # of last allocated cluster 0 00000D31 ???? dpb_free_cnt DW ? ; Count of free clusters, -1 if unknown 27 <2> dpb ENDS 28 <2> 29 <2> DPBSIZ EQU dpb_struc_size ; Size of the structure in bytes 30 <2> 31 <2> DSKSIZ equ dpb_max_cluster ; Size of disk (temp used during init only) 32 <2> ; ; 33 <2> ; C A V E A T P R O G R A M M E R ; 34 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 20 <1> %include "buffer.mac" 1 <2> %include "buf2sw.mac" 1 <3> %define BUF2 1 2 <2> 3 <2> ; SCCSID = @(#)buffer.asm 1.1 85/04/09 4 <2> BREAK 5 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 6 <2> ; C A V E A T P R O G R A M M E R ; 7 <2> ; ; 8 <2> 9 <2> %ifdef BUF2 10 <2> 11 <2> ; Field definition for I/O buffer information 12 <2> 13 <2> BUFFINFO STRUC 0 00000D12 ???????? NEXTBUF DD ? ; Pointer to next buffer in list 15 <2> ; The next two items are often refed as a word 16 <2> buf_ID: 0 00000D16 ?? BUFDRV DB ? ; Logical drive # assoc with buffer FF = free 18 <2> buf_flags: 0 00000D17 ?? BUFDATAFLAG db ? 0 00000D18 ?? BUFPRI DB ? ; Buffer selection priority (see EQUs below) 0 00000D19 ?? alignb 2 22 <2> buf_sector: 0 00000D1A ???????? BUFSECNO dd ? ; Sector number of buffer 24 <2> alignb 2 0 00000D1E ???????? BUFDRVDP DD ? ; Pointer to drive parameters 26 <2> BUFFINFO ENDS 27 <2> 28 <2> BUFINSIZ EQU BUFFINFO_struc_size 29 <2> ; Size of structure in bytes 30 <2> BUFINSIZE equ BUFINSIZ 31 <2> 32 <2> FREEPRI EQU 0 33 <2> LBRPRI EQU 2 ; Last byte of buffer read 34 <2> LBWPRI EQU 4 ; Last byte written 35 <2> RPRI EQU 6 ; Read but not last byte 36 <2> WPRI EQU 8 ; Written but not last byte 37 <2> DIRPRI EQU 15 ; Directory Sector 38 <2> FATPRI EQU 30 ; FAT sector 39 <2> 40 <2> buf_dirty EQU 01000000B 41 <2> buf_isDATA EQU 00001000B 42 <2> buf_isDIR EQU 00000100B 43 <2> buf_isFAT EQU 00000010B 44 <2> buf_type_0 EQU 11110001B ; AND sets type to "none" 45 <2> 46 <2> %else 47 <2> 48 <2> ; Field definition for I/O buffer information 49 <2> 50 <2> BUFFINFO STRUC 51 <2> buf_next DW ? ; Pointer to next buffer in list 52 <2> buf_prev DW ? ; Pointer to prev buffer in list 53 <2> buf_ID DB ? ; Drive of buffer (bit 7 = 0) 54 <2> ; SFT table index (bit 7 = 1) 55 <2> ; = FFH if buffer free 56 <2> buf_flags DB ? ; Bit 7 = 1 if Remote file buffer 57 <2> ; = 0 if Local device buffer 58 <2> ; Bit 6 = 1 if buffer dirty 59 <2> ; Bit 5 = Reserved 60 <2> ; Bit 4 = Search bit (bit 7 = 1) 61 <2> ; Bit 3 = 1 if buffer is DATA 62 <2> ; Bit 2 = 1 if buffer is DIR 63 <2> ; Bit 1 = 1 if buffer is FAT 64 <2> ; Bit 0 = Reserved 65 <2> buf_sector DD ? ; Sector number of buffer (bit 7 = 0) 66 <2> ; The next two items are often refed as a word (bit 7 = 0) 67 <2> buf_wrtcnt DB ? ; For FAT sectors, # times sector written out 68 <2> buf_wrtcntinc DW ? ; " " " , # sectors between each write 69 <2> buf_DPB DD ? ; Pointer to drive parameters 70 <2> buf_fill DW ? ; How full buffer is (bit 7 = 1) 71 <2> buf_reserved DB ? ; make DWORD boundary for 386 72 <2> BUFFINFO ENDS 73 <2> 74 <2> labelsize buf_offset, dword, buf_sector 75 <2> ;For bit 7 = 1, this is the byte 76 <2> ;offset of the start of the buffer in 77 <2> ;the file pointed to by buf_ID. Thus 78 <2> ;the buffer starts at location 79 <2> ;buf_offset in the file and contains 80 <2> ;buf_fill bytes. 81 <2> 82 <2> BUFINSIZ EQU BUFFINFO_struc_size 83 <2> ; Size of structure in bytes 84 <2> 85 <2> buf_Free EQU 0FFh ; buf_id of free buffer 86 <2> 87 <2> ;Flag byte masks 88 <2> buf_isnet EQU 10000000B 89 <2> buf_dirty EQU 01000000B 90 <2> 91 <2> buf_isDATA EQU 00001000B 92 <2> buf_isDIR EQU 00000100B 93 <2> buf_isFAT EQU 00000010B 94 <2> buf_type_0 EQU 11110001B ; AND sets type to "none" 95 <2> 96 <2> buf_NetID EQU BUFINSIZ 97 <2> 98 <2> ; 99 <2> ; Buffer Hash Entry Structure 100 <2> 101 <2> BUFFER_HASH_ENTRY STRUC ; DOS 4.00 102 <2> EMS_PAGE_NUM DW ? ; logical page number for EMS handle 103 <2> BUFFER_BUCKET DD ? ; pointer to buffers 104 <2> DIRTY_COUNT DB ? ; number of dirty buffers 105 <2> BUFFER_RESERVED DB ? ; reserved 106 <2> BUFFER_HASH_ENTRY ENDS 107 <2> 108 <2> MaxBuffinBucket EQU 15 ; Max number of buffers per bucket 109 <2> MaxBucketinPage EQU 2 ; Max number of buckets per 16kb page 110 <2> 111 <2> %endif 112 <2> 113 <2> ; ; 114 <2> ; C A V E A T P R O G R A M M E R ; 115 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 21 <1> %include "arena.mac" 1 <2> ; SCCSID = @(#)arena.asm 1.1 85/04/09 2 <2> ;BREAK 3 <2> 4 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 5 <2> ; C A V E A T P R O G R A M M E R ; 6 <2> ; ; 7 <2> ; 8 <2> ; arena item 9 <2> ; 10 <2> arena STRUC 0 00000D12 ?? arena_signature DB ? ; 4D for valid item, 5A for last item 0 00000D13 ???? arena_owner DW ? ; owner of arena item 0 00000D15 ???? arena_size DW ? ; size in paragraphs of item 0 00000D17 ?????? arena_reserved DB 3 DUP(?) ; reserved 0 00000D1A ???????????????? arena_name DB 8 DUP(?) ; owner file name 16 <2> arena ENDS 17 <2> 18 <2> ; 19 <2> ; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature 20 <2> ; and arena_owner_system are all equal to zero and are contained in DI. Change 21 <2> ; them and change ALLOC.ASM. 22 <2> 23 <2> arena_owner_system EQU 0 ; free block indication 24 <2> 25 <2> arena_signature_normal EQU 4Dh ; valid signature, not end of arena 26 <2> arena_signature_end EQU 5Ah ; valid signature, last block in arena 27 <2> ; ; 28 <2> ; C A V E A T P R O G R A M M E R ; 29 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 30 <2> 22 <1> %include "vector.mac" 1 <2> ; SCCSID = @(#)vector.asm 1.1 85/04/10 2 <2> BREAK 3 <2> 4 <2> ;Asmvar AltVect 5 <2> %ifndef AltVect 6 <2> %iassign AltVect 0 7 <2> %endif 8 <2> 9 <2> INTTAB EQU 20H 10 <2> inttab equ INTTAB ; NASM port equate 11 <2> INTBASE EQU 4 * inttab 12 <2> ENTRYPOINT EQU INTBASE+40H 13 <2> 14 <2> %IF ALTVECT 15 <2> ALTTAB EQU 0F0H 16 <2> ALTBASE EQU 4 * ALTTAB 17 <2> %ENDIF 18 <2> 19 <2> ; 20 <2> ; interrupt assignments 21 <2> ; 22 <2> %IFN ALTVECT 23 <2> int_abort EQU INTTAB ; abort process 24 <2> int_command EQU int_abort+1 ; call MSDOS 25 <2> int_terminate EQU int_abort+2 ; int to terminate address 26 <2> int_ctrl_c EQU int_abort+3 ; ^c trapper 27 <2> int_fatal_abort EQU int_abort+4 ; hard disk error 28 <2> int_disk_read EQU int_abort+5 ; logical sector disk read 29 <2> int_disk_write EQU int_abort+6 ; logical sector disk write 30 <2> int_keep_process EQU int_abort+7 ; terminate program and stay 31 <2> ; resident 32 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 33 <2> ; C A V E A T P R O G R A M M E R ; 34 <2> ; ; 35 <2> int_spooler EQU int_abort+8 ; spooler call 36 <2> int_fastcon EQU int_abort+9 ; fast CON interrupt 37 <2> int_IBM EQU int_abort+10; critical section maintenance 38 <2> ; ; 39 <2> ; C A V E A T P R O G R A M M E R ; 40 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <2> %ELSE 42 <2> int_abort EQU INTTAB ; abort process 43 <2> int_command EQU int_abort+1 ; call MSDOS 44 <2> int_terminate EQU ALTTAB ; int to terminate address 45 <2> int_ctrl_c EQU int_terminate+1 ; ^c trapper 46 <2> int_fatal_abort EQU int_terminate+2 ; hard disk error 47 <2> int_disk_read EQU int_abort+5 ; logical sector disk read 48 <2> int_disk_write EQU int_abort+6 ; logical sector disk write 49 <2> int_keep_process EQU int_abort+7 ; terminate program and stay resident 50 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 51 <2> ; C A V E A T P R O G R A M M E R ; 52 <2> ; ; 53 <2> int_spooler EQU int_terminate+3 ; spooler call 54 <2> int_fastcon EQU int_abort+9 ; fast CON interrupt 55 <2> ; ; 56 <2> ; C A V E A T P R O G R A M M E R ; 57 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 58 <2> %ENDIF 59 <2> 60 <2> addr_int_abort EQU 4 * int_abort 61 <2> addr_int_command EQU 4 * int_command 62 <2> addr_int_terminate EQU 4 * int_terminate 63 <2> addr_int_ctrl_c EQU 4 * int_ctrl_c 64 <2> addr_int_fatal_abort EQU 4 * int_fatal_abort 65 <2> addr_int_disk_read EQU 4 * int_disk_read 66 <2> addr_int_disk_write EQU 4 * int_disk_write 67 <2> addr_int_keep_process EQU 4 * int_keep_process 68 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 69 <2> ; C A V E A T P R O G R A M M E R ; 70 <2> ; ; 71 <2> addr_int_spooler EQU 4 * int_spooler 72 <2> addr_int_fastcon EQU 4 * int_fastcon 73 <2> addr_int_IBM EQU 4 * int_IBM 74 <2> ; ; 75 <2> ; C A V E A T P R O G R A M M E R ; 76 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 23 <1> %include "devsym.mac" 1 <2> %warning out: DEVSYM.INC... 1 ****************** <2> warning: out: DEVSYM.INC... [-w+user] 2 <2> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 3 <2> ; SCCSID = @(#)DEVSYM.ASM 1.10 85/09/04 4 <2> 5 <2> ; THE DEVICE TABLE LIST HAS THE FORM: 6 <2> SYSDEV STRUC 0 00000D12 ???????? SDEVNEXT DD ? ;POINTER TO NEXT DEVICE HEADER 0 00000D16 ???? SDEVATT DW ? ;ATTRIBUTES OF THE DEVICE 0 00000D18 ???? SDEVSTRAT DW ? ;STRATEGY ENTRY POINT 0 00000D1A ???? SDEVINT DW ? ;INTERRUPT ENTRY POINT 0 00000D1C ???????????????? SDEVNAME DB 8 DUP (?) ;NAME OF DEVICE (ONLY FIRST BYTE USED FOR BLOCK) 12 <2> SYSDEV ENDS 13 <2> 14 <2> ; 15 <2> ; ATTRIBUTE BIT MASKS 16 <2> ; 17 <2> ; CHARACTER DEVICES: 18 <2> ; 19 <2> ; BIT 15 -> MUST BE 1 20 <2> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 21 <2> ; 13 -> 1 IF THE DEVICE SUPPORTS OUTPUT-UNTIL-BUSY 22 <2> ; 12 -> UNUSED 23 <2> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE 24 <2> ; 10 -> MUST BE 0 25 <2> ; 9 -> MUST BE 0 26 <2> ; 8 -> UNUSED 27 <2> ; 7 -> UNUSED 28 <2> ; 6 -> UNUSED 29 <2> ; 5 -> UNUSED 30 <2> ; 4 -> 1 IF DEVICE IS RECIPIENT OF INT 29H 31 <2> ; 3 -> 1 IF DEVICE IS CLOCK DEVICE 32 <2> ; 2 -> 1 IF DEVICE IS NULL DEVICE 33 <2> ; 1 -> 1 IF DEVICE IS CONSOLE OUTPUT 34 <2> ; 0 -> 1 IF DEVICE IS CONSOLE INPUT 35 <2> ; 36 <2> ; BLOCK DEVICES: 37 <2> ; 38 <2> ; BIT 15 -> MUST BE 0 39 <2> ; 14 -> 1 IF THE DEVICE UNDERSTANDS IOCTL CONTROL STRINGS 40 <2> ; 13 -> 1 IF THE DEVICE DETERMINES MEDIA BY EXAMINING THE FAT ID BYTE. 41 <2> ; THIS REQUIRES THE FIRST SECTOR OF THE FAT TO *ALWAYS* RESIDE IN 42 <2> ; THE SAME PLACE. 43 <2> ; 12 -> UNUSED 44 <2> ; 11 -> 1 IF THE DEVICE UNDERSTANDS OPEN/CLOSE/REMOVABLE MEDIA 45 <2> ; 10 -> MUST BE 0 46 <2> ; 9 -> MUST BE 0 47 <2> ; 8 -> UNUSED 48 <2> ; 7 -> UNUSED 49 <2> ; 6 -> IF DEVICE HAS SUPPORT FOR GETMAP/SETMAP OF LOGICAL DRIVES. 50 <2> ; IF THE DEVICE UNDERSTANDS GENERIC IOCTL FUNCTION CALLS. 51 <2> ; 5 -> UNUSED 52 <2> ; 4 -> UNUSED 53 <2> ; 3 -> UNUSED 54 <2> ; 2 -> UNUSED 55 <2> ; 1 -> UNUSED 56 <2> ; 0 -> UNUSED 57 <2> ; 58 <2> 59 <2> DEVTYP EQU 8000H ; BIT 15 - 1 IF CHAR, 0 IF BLOCK 60 <2> CHARDEV EQU 8000H 61 <2> DEVIOCTL EQU 4000H ; BIT 14 - CONTROL MODE BIT 62 <2> ISFATBYDEV EQU 2000H ; BIT 13 - DEVICE USES FAT ID BYTES, 63 <2> ; COMP MEDIA. 64 <2> OUTTILBUSY EQU 2000H ; OUTPUT UNTIL BUSY IS ENABLED 65 <2> ISNET EQU 1000H ; BIT 12 - 1 IF A NET DEVICE, 0 IF 66 <2> ; NOT. CURRENTLY BLOCK ONLY. 67 <2> DEVOPCL EQU 0800H ; BIT 11 - 1 IF THIS DEVICE HAS 68 <2> ; OPEN,CLOSE AND REMOVABLE MEDIA 69 <2> ; ENTRY POINTS, 0 IF NOT 70 <2> 71 <2> EXTENTBIT EQU 0400H ; BIT 10 - CURRENTLY 0 ON ALL DEVS 72 <2> ; THIS BIT IS RESERVED FOR FUTURE USE 73 <2> ; TO EXTEND THE DEVICE HEADER BEYOND 74 <2> ; ITS CURRENT FORM. 75 <2> 76 <2> ; NOTE BIT 9 IS CURRENTLY USED ON IBM SYSTEMS TO INDICATE "DRIVE IS SHARED". 77 <2> ; SEE IOCTL FUNCTION 9. THIS USE IS NOT DOCUMENTED, IT IS USED BY SOME 78 <2> ; OF THE UTILITIES WHICH ARE SUPPOSED TO FAIL ON SHARED DRIVES ON SERVER 79 <2> ; MACHINES (FORMAT,CHKDSK,RECOVER,..). 80 <2> 81 <2> DEV320 EQU 0040H ;BIT 6 - FOR BLOCK DEVICES, THIS 82 <2> ;DEVICE SUPPORTS SET/GET MAP OF 83 <2> ;LOGICAL DRIVES, AND SUPPORTS 84 <2> ;GENERIC IOCTL CALLS. 85 <2> ;FOR CHARACTER DEVICES, THIS 86 <2> ;DEVICE SUPPORTS GENERIC IOCTL. 87 <2> ;THIS IS A DOS 3.2 DEVICE DRIVER. 88 <2> ISSPEC EQU 0010H ;BIT 4 - THIS DEVICE IS SPECIAL 89 <2> ISCLOCK EQU 0008H ;BIT 3 - THIS DEVICE IS THE CLOCK DEVICE. 90 <2> ISNULL EQU 0004H ;BIT 2 - THIS DEVICE IS THE NULL DEVICE. 91 <2> ISCOUT EQU 0002H ;BIT 1 - THIS DEVICE IS THE CONSOLE OUTPUT. 92 <2> ISCIN EQU 0001H ;BIT 0 - THIS DEVICE IS THE CONSOLE INPUT. 93 <2> EXTDRVR EQU 0002H ;BIT 1 - BLOCK DEVICE EXTNDED DRIVER 94 <2> 95 <2> ;STATIC REQUEST HEADER 96 <2> SRHEAD STRUC 0 00000D12 ?? REQLEN DB ? ;LENGTH IN BYTES OF REQUEST BLOCK 0 00000D13 ?? REQUNIT DB ? ;DEVICE UNIT NUMBER 0 00000D14 ?? REQFUNC DB ? ;TYPE OF REQUEST 0 00000D15 ???? REQSTAT DW ? ;STATUS WORD 0 00000D17 ???????????????? DB 8 DUP(?) ;RESERVED FOR QUEUE LINKS 102 <2> SRHEAD ENDS 103 <2> 104 <2> ;STATUS WORD MASKS 105 <2> STERR EQU 8000H ;BIT 15 - ERROR 106 <2> STBUI EQU 0200H ;BIT 9 - BUISY 107 <2> STDON EQU 0100H ;BIT 8 - DONE 108 <2> STECODE EQU 00FFH ;ERROR CODE 109 <2> ; 2/12/KK 110 <2> ; Interim character identifier 2/12/KK 111 <2> Ddkey EQU 0000010000000000B ; 2/12/KK 112 <2> 113 <2> ;FUNCTION CODES 114 <2> DEVINIT EQU 0 ;INITIALIZATION 115 <2> DINITHL EQU 26 ;SIZE OF INIT HEADER 116 <2> DEVMDCH EQU 1 ;MEDIA CHECK 117 <2> DMEDHL EQU 15 ;SIZE OF MEDIA CHECK HEADER 118 <2> DEVBPB EQU 2 ;GET BPB 119 <2> DEVRDIOCTL EQU 3 ;IOCTL READ 120 <2> DBPBHL EQU 22 ;SIZE OF GET BPB HEADER 121 <2> DEVRD EQU 4 ;READ 122 <2> DRDWRHL EQU 22 ;SIZE OF RD/WR HEADER 123 <2> DEVRDND EQU 5 ;NON DESTRUCTIVE READ NO WAIT (CHARACTER DEVS) 124 <2> DRDNDHL EQU 14 ;SIZE OF NON DESTRUCTIVE READ HEADER 125 <2> DEVIST EQU 6 ;INPUT STATUS 126 <2> DSTATHL EQU 13 ;SIZE OF STATUS HEADER 127 <2> DEVIFL EQU 7 ;INPUT FLUSH 128 <2> DFLSHL EQU 15 ;SIZE OF FLUSH HEADER 129 <2> DEVWRT EQU 8 ;WRITE 130 <2> DEVWRTV EQU 9 ;WRITE WITH VERIFY 131 <2> DEVOST EQU 10 ;OUTPUT STATUS 132 <2> DEVOFL EQU 11 ;OUTPUT FLUSH 133 <2> DEVWRIOCTL EQU 12 ;IOCTL WRITE 134 <2> DEVOPN EQU 13 ;DEVICE OPEN 135 <2> DEVCLS EQU 14 ;DEVICE CLOSE 136 <2> DOPCLHL EQU 13 ;SIZE OF OPEN/CLOSE HEADER 137 <2> DEVRMD EQU 15 ;REMOVABLE MEDIA 138 <2> REMHL EQU 13 ;SIZE OF REMOVABLE MEDIA HEADER 139 <2> GENIOCTL EQU 19 140 <2> ; THE NEXT THREE ARE USED IN DOS 4.0 141 <2> ; 20 142 <2> ; 21 143 <2> ; 22 144 <2> DEVGETOWN EQU 23 ;GET DEVICE OWNER 145 <2> DEVSETOWN EQU 24 ;SET DEVICE OWNER 146 <2> QUERYGENIOCTL equ 25 ; query generic IOCTL support (MS-DOS v5+) 147 <2> OWNHL EQU 13 ;SIZE OF DEVICE OWNER HEADER 148 <2> 149 <2> DEVOUT EQU 16 ; OUTPUT UNTIL BUSY. 150 <2> DEVOUTL EQU DEVWRT ; LENGTH OF OUTPUT UNTIL BUSY 151 <2> 152 <2> ; GENERIC IOCTL REQUEST STRUCTURE 153 <2> ; SEE THE DOS 4.0 DEVICE DRIVER SPEC FOR FURTHER ELABORATION. 154 <2> ; 155 <2> IOCTL_REQ STRUC 0 00000D12 ?????????????????? DB (SRHEAD_struc_size) DUP(?) 156 00000009 ???????? <2> 157 <2> ; GENERIC IOCTL ADDITION. 0 00000D1F ?? MAJORFUNCTION DB ? ;FUNCTION CODE 0 00000D20 ?? MINORFUNCTION DB ? ;FUNCTION CATEGORY 0 00000D21 ???? REG_SI DW ? 0 00000D23 ???? REG_DI DW ? 0 00000D25 ???????? GENERICIOCTL_PACKET DD ? ; POINTER TO DATA BUFFER 163 <2> IOCTL_REQ ENDS 164 <2> 165 <2> ; DEFINITIONS FOR IOCTL_REQ.MINORFUNCTION 166 <2> GEN_IOCTL_WRT_TRK EQU 40H 167 <2> GEN_IOCTL_RD_TRK EQU 60H 168 <2> GEN_IOCTL_FN_TST EQU 20H ; USED TO DIFF. BET READS AND WRTS 169 <2> 170 <2> ;; 32-bit absolute read/write input list structure 171 <2> 172 <2> ABS_32RW STRUC 0 00000D12 ???????? SECTOR_RBA DD ? ; relative block address 0 00000D16 ???? ABS_RW_COUNT DW ? ; number of sectors to be transferred 0 00000D18 ???????? BUFFER_ADDR DD ? ; data addrress 176 <2> ABS_32RW ENDS 177 <2> 178 <2> ;; media ID info 179 <2> 180 <2> MEDIA_ID_INFO STRUC 0 00000D12 ???? MEDIA_level DW ? ; info level 0 00000D14 ???????? MEDIA_Serial DD ? ; serial # 0 00000D18 ?????????????????? MEDIA_Label DB 11 dup (?) ;volume label 183 0000000F ???? <2> 0 00000D23 ???????????????? MEDIA_System DB 8 dup (?) ;system type 185 <2> MEDIA_ID_INFO ENDS 186 <2> 187 <2> ;; equates for DOS34_FLAG 188 <2> 189 <2> IFS_ABSRW EQU 00001H ;IFS absolute read/write 190 <2> NO_IFS_ABSRW EQU 0FFFEH ;no IFS absolute read/write 191 <2> IFS_DRIVE_RESET EQU 00002H ;IFS drvive reset 192 <2> NO_IFS_DRIVE_RESET EQU 0FFFDH ;no IFS drive reset 193 <2> FROM_DISK_RESET EQU 00004H ;from disk reset 194 <2> NO_FROM_DISK_RESET EQU 0FFFBH ;not from disk reset 195 <2> From_String_Output EQU 00008H ;from con string output 196 <2> NO_From_String_Output EQU 0FFF7H ;not from con string output 197 <2> From_DOS_WRITE EQU 00010H ;from dos_write 198 <2> NO_From_DOS_WRITE EQU 0FFEFH ;not from dos_write 199 <2> Force_I24_Fail EQU 00020H ;form IFS CALL BACK 200 <2> NO_Force_I24_Fail EQU 0FFDFH ;not form IFS CALL BACK 201 <2> Disable_EOF_I24 EQU 00040H ;disable EOF int24 for input status 202 <2> NO_Disable_EOF_I24 EQU 0FFBFH ;disable EOF int24 for input status 203 <2> DBCS_VOLID EQU 00080H ;indicate from volume id 204 <2> DBCS_VOLID2 EQU 00100H ;indicate 8th char is DBCS 205 <2> CTRL_BREAK_FLAG EQU 00200H ;indicate control break is input 206 <2> NO_CTRL_BREAK_FLAG EQU 0FDFFH ;reset control break 207 <2> SEARCH_FASTOPEN EQU 00400H ;set fastopen flag for search 208 <2> X25_special EQU 00800H ;flag for X25 driver 24 <1> %include "pdb.mac" 1 <2> ; SCCSID = @(#)pdb.asm 1.1 85/04/10 2 <2> BREAK 3 <2> 4 <2> ; 5 <2> ; Process data block (otherwise known as program header) 6 <2> ; 7 <2> 8 <2> FilPerProc EQU 20 9 <2> 10 <2> Process_data_block STRUC 0 00000D12 ???? PDB_Exit_Call DW ? ; INT int_abort system terminate 0 00000D14 ???? PDB_block_len DW ? ; size of execution block 0 00000D16 ?? DB ? 0 00000D17 ?????????? PDB_CPM_Call DB 5 DUP (?) ; ancient call to system 0 00000D1C ???????? PDB_Exit DD ? ; pointer to exit routine 0 00000D20 ???????? PDB_Ctrl_C DD ? ; pointer to ^C routine 0 00000D24 ???????? PDB_Fatal_abort DD ? ; pointer to fatal error 18 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 19 <2> ; C A V E A T P R O G R A M M E R ; 20 <2> ; ; 0 00000D28 ???? PDB_Parent_PID DW ? ; PID of parent (terminate PID) 0 00000D2A ?????????????????? PDB_JFN_Table DB FilPerProc DUP (?) 22 00000021 ??????????????????- <2> 22 0000002A ???? <2> 23 <2> ; indices into system table 24 <2> ; ; 25 <2> ; C A V E A T P R O G R A M M E R ; 26 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D3E ???? PDB_environ DW ? ; seg addr of environment 28 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 29 <2> ; C A V E A T P R O G R A M M E R ; 30 <2> ; ; 0 00000D40 ???????? PDB_User_stack DD ? ; stack of self during system calls 0 00000D44 ???? PDB_JFN_Length DW ? ; number of handles allowed 0 00000D46 ???????? PDB_JFN_Pointer DD ? ; pointer to JFN table 0 00000D4A ???????? PDB_Next_PDB DD ? ; pointer to nested PDB's 0 00000D4E ?????????????????? PDB_PAD1 DB 14h DUP (?) 35 00000045 ??????????????????- <2> 35 0000004E ???? <2> 36 <2> ; ; 37 <2> ; C A V E A T P R O G R A M M E R ; 38 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 0 00000D62 ?????????? PDB_Call_system DB 5 DUP (?) ; portable method of system call 40 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 41 <2> ; C A V E A T P R O G R A M M E R ; 42 <2> ; ; 0 00000D67 ?????????????? PDB_PAD2 DB 7h DUP (?) 44 <2> ; ; 45 <2> ; C A V E A T P R O G R A M M E R ; 46 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 47 <2> Process_data_block ENDS 48 <2> 49 <2> labelsize PDB_InterCon, byte, PDB_PAD1 ; 2/12/KK 50 <2> labelsize PDB_Append, byte, PDB_PAD1+1 ; 2/12/KK 25 <1> %include "find.mac" 1 <2> ; SCCSID = @(#)find.asm 1.1 85/04/10 2 <2> ; SCCSID = @(#)find.asm 1.1 85/04/10 3 <2> Break 4 <2> 5 <2> find_buf STRUC 6 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 7 <2> ; C A V E A T P R O G R A M M E R ; 8 <2> ; ; 0 00000D12 ?? find_buf_drive DB ? ; drive of search 0 00000D13 ?????????????????? find_buf_name DB 11 DUP (?) ; formatted name 10 0000000A ???? <2> 0 00000D1E ?? find_buf_sattr DB ? ; attribute of search 0 00000D1F ???? find_buf_LastEnt DW ? ; LastEnt 0 00000D21 ???? find_buf_DirStart DW ? ; DirStart 0 00000D23 ???????? find_buf_NetID DB 4 DUP (?) ; Reserved for NET 15 <2> ; ; 16 <2> ; C A V E A T P R O G R A M M E R ; 17 <2> ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; 18 <2> 0 00000D27 ?? find_buf_attr DB ? ; attribute found 0 00000D28 ???? find_buf_time DW ? ; time 0 00000D2A ???? find_buf_date DW ? ; date 0 00000D2C ???? find_buf_size_l DW ? ; low(size) 0 00000D2E ???? find_buf_size_h DW ? ; high(size) 0 00000D30 ?????????????????? find_buf_pname DB 13 DUP (?) ; packed name 24 00000027 ???????? <2> 25 <2> find_buf ENDS 26 <1> %include "mi.mac" 1 <2> ; SCCSID = @(#)mi.asm 1.1 85/04/10 2 <2> BREAK 3 <2> 4 <2> mi_INT EQU 0CDh 5 <2> mi_Long_JMP EQU 0EAh 6 <2> mi_Long_CALL EQU 09Ah 7 <2> mi_Long_RET EQU 0CBh 8 <2> mi_Near_RET EQU 0C3h 9 <2> 10 <2> ; xxxxoditszxaxpxc 11 <2> f_Overflow EQU 0000100000000000B 12 <2> f_Direction EQU 0000010000000000B 13 <2> f_Interrupt EQU 0000001000000000B 14 <2> f_Trace EQU 0000000100000000B 15 <2> f_Sign EQU 0000000010000000B 16 <2> f_Zero EQU 0000000001000000B 17 <2> f_Aux EQU 0000000000010000B 18 <2> f_Parity EQU 0000000000000100B 19 <2> f_Carry EQU 0000000000000001B 27 <1> ;.cref 28 <1> [list +] 29 <1> 30 <1> ;TITLE IBMDATA - DATA segment for DOS 31 <1> ;NAME IBMDATA 32 <1> 33 <1> %iassign installed TRUE 34 <1> 35 <1> ;=== Push trace listing source: ms_data.nas 36 <1> %include "ms_data.nas" ; NASM included file 1 <2> %include "nasmorg.mac" 1 <3> 2 <3> %if 0 3 <3> 4 <3> NASM macros to replace JWasm org directive 5 <3> 2024 by E. C. Masloch, Public Domain 6 <3> 7 <3> %endif 8 <3> 9 <3> %imacro org 1-2.nolist db 0 10 <3> times (%1) - ($ - $$) %2 11 <3> %endmacro 2 <2> 3 <2> ; SCCSID = @(#)msdata.asm 1.8 85/09/12 4 <2> %ifndef Kanji 5 <2> %iassign Kanji 0 6 <2> %endif 7 <2> %ifndef Debug 8 <2> %iassign Debug 0 9 <2> %endif 10 <2> %ifndef Redirector 11 <2> %iassign Redirector 0 12 <2> %endif 13 <2> %ifndef ShareF 14 <2> %iassign ShareF 0 15 <2> %endif 16 <2> 17 <2> Break 18 <2> 19 <2> %define RECORDED none, none 20 <2> %macro record 2.nolist 21 <2> %%before: 22 <2> %1 23 <2> %%after: 24 <2> %assign %%i 0 25 <2> %rep %%after - %%before 26 <2> %assign %%offset %%before + %%i - MSDAT001S 27 <2> %xdefine RECORDED RECORDED, %%offset, %2 28 <2> %assign %%i %%i + 1 29 <2> %endrep 30 <2> %endmacro 31 <2> === Switch to base=001DC0h -> "DATA" 32 <2> section DATA 33 <2> ; Init code overlaps with data area below 34 <2> 35 <2> absolute $ 36 <2> 37 <2> ORG 0, resb 1 38 <2> MSDAT001E equ MSDAT001e ; NASM port label 39 <2> PUBLIC MSDAT001S,MSDAT001E 40 <2> MSDAT001S label byte 41 <2> 0 000003B6 ???????????? I_am_nobits TIMEBUF,6 ; Time read from clock device 0 000003BC ???? I_am_nobits DEVIOBUF,2 ; Buffer for I/O under file assignment 44 <2> ; 45 <2> ; The following areas are used as temp buffer in EXEC system call 46 <2> ; 47 00000008 <2> I_am_nobits OPENBUF,128 ; buffer for name operations 48 00000088 <2> I_am_nobits RenBuf,128 ; buffer for rename destination 49 <2> ; Buffer for search calls 50 00000108 <2> I_am_nobits SEARCHBUF,53 ; internal search buffer 51 0000013D <2> I_am_nobits DummyCDS,curdirLen 52 <2> ; 53 <2> ; End of contiguous buffer 54 <2> ; 55 <2> 56 <2> ; 57 <2> ; Temporary directory entry for use by many routines. Device directory 58 <2> ; entries (bogus) are built here. 59 <2> ; 60 <2> DevFCB equ DEVFCB ; NASM port label 61 <2> PUBLIC DevFCB 62 <2> DEVFCB LABEL BYTE ; Uses NAME1, NAME2, combined 63 <2> ; WARNING.. do not alter position of NAME1 relative to DEVFCB 64 <2> ; without first examining BUILD_DEVICE_ENT. Look carefully at DOS_RENAME 65 <2> ; as well as it is the only guy who uses NAME2 and DESTSTART. 66 00000195 <2> I_am_nobits NAME1,12 ; File name buffer 67 000001A1 <2> I_am_nobits NAME2,13 ; 0 00000564 ???? I_am_nobits DESTSTART,WORD ; 69 <2> DIR_ENTRY_struc_size equ dir_entry_struc_size ; NASM port equate 0 00000566 ?????????? DB ((DIR_ENTRY_struc_size) - ($ - DEVFCB)) DUP (?) 71 <2> ; 72 <2> ; End Temporary directory entry. 73 <2> ; 0 0000056B ?? I_am_nobits ATTRIB,BYTE ; storage for file attributes 0 0000056C ?? I_am_nobits EXTFCB,BYTE ; TRUE => extended FCB in use 0 0000056D ?? I_am_nobits SATTRIB,BYTE ; Storage for search attributes 77 <2> %if EXTFCB + 1 != SATTRIB ; used in macro2.nas 78 <2> %error Unexpected layout 79 <2> %endif 0 0000056E ?? I_am_nobits open_access,BYTE ; access of open system call 0 0000056F ?? I_am_nobits FoundDel,BYTE ; true => file was deleted 0 00000570 ?? I_am_nobits Found_dev,BYTE ; true => search found a device 0 00000571 ?? I_am_nobits fSplice,BYTE ; true => do a splice in transpath 0 00000572 ?? I_am_nobits fSharing,BYTE ; TRUE => no redirection 0 00000573 ?? I_am_nobits SECCLUSPOS,BYTE ; Position of first sector within cluster 0 00000574 ?? I_am_nobits TRANS,BYTE ; 0 00000575 ?? I_am_nobits READOP,BYTE ; 0 00000576 ?? I_am_nobits THISDRV,BYTE ; 0 00000577 ?? I_am_nobits CLUSFAC,BYTE ; 0 00000578 ?? I_am_nobits CLUSSPLIT,BYTE ; 0 00000579 ?? I_am_nobits INSMODE,BYTE ; true => insert mode in buffered read 0 0000057A ?? I_am_nobits cMeta,BYTE ; count of meta'ed components found 0 0000057B ?? I_am_nobits VOLID,BYTE ; 0 0000057C ?? I_am_nobits exit_type,BYTE ; type of exit... 95 <2> 0 0000057D ?? record alignb 2, 90h 97 <2> 98 <2> ; WARNING - the following two items are accessed as a word 0 0000057E ?? I_am_nobits CREATING,BYTE ; true => creating a file 0 0000057F ?? I_am_nobits DELALL,BYTE ; true => deleting everything 101 <2> 0 00000580 ???????? I_am_nobits EXITHOLD,DWORD ; Temp location for proc terminate 0 00000584 ???? I_am_nobits user_SP,WORD ; User SP for system call 0 00000586 ???? I_am_nobits user_SS,WORD ; User SS for system call 0 00000588 ???? I_am_nobits CONTSTK,WORD ; 0 0000058A ???????? I_am_nobits THISDPB,DWORD ; 0 0000058E ???? I_am_nobits CLUSSAVE,WORD ; 0 00000590 ???????? I_am_nobits CLUSSEC,DWORD ;>32mb AC0000 0 00000594 ???? I_am_nobits PREREAD,WORD ; 0 means preread; 1 means optional 0 00000596 ???? I_am_nobits FATBYT,WORD ; Used by ALLOCATE 0 00000598 ???? I_am_nobits FATBYTE,WORD ; Used by $SLEAZEFUNC 0 0000059A ???????? I_am_nobits DEVPT,DWORD ; 0 0000059E ???????? I_am_nobits THISSFT,DWORD ; Address of user SFT 0 000005A2 ???????? I_am_nobits THISCDS,DWORD ; Address of current CDS 0 000005A6 ???????? I_am_nobits THISFCB,DWORD ; Address of user FCB 0 000005AA ???? record {I_am_nobits SFN,WORD,<-1>}, 255 ; SystemFileNumber found for accessfile 0 000005AC ???? I_am_nobits JFN,WORD ; JobFileNumber found for accessfile 0 000005AE ???????? I_am_nobits PJFN,DWORD ; PointerJobFileNumber found for accessfile 0 000005B2 ???? I_am_nobits WFP_START,WORD ; 0 000005B4 ???? I_am_nobits REN_WFP,WORD ; 0 000005B6 ???? I_am_nobits CURR_DIR_END,WORD ; 0 000005B8 ???? I_am_nobits NEXTADD,WORD ; 0 000005BA ???? I_am_nobits LASTPOS,WORD ; 0 000005BC ???? I_am_nobits CLUSNUM,WORD ; 0 000005BE ???????? I_am_nobits DIRSEC,DWORD ;>32mb AC0000 0 000005C2 ???? I_am_nobits DIRSTART,WORD ; 0 000005C4 ???????? I_am_nobits SECPOS,DWORD ;>32mb Position of first sector accessed 0 000005C8 ???????? I_am_nobits VALSEC,DWORD ;>32mb Number of valid (previously written) 129 <2> ; sectors 0 000005CC ???? I_am_nobits BYTSECPOS,WORD ; Position of first byte within sector 0 000005CE ???????? I_am_nobits BYTPOS,4 ; Byte position in file of access 0 000005D2 ???? I_am_nobits BYTCNT1,WORD ; No. of bytes in first sector 0 000005D4 ???? I_am_nobits BYTCNT2,WORD ; No. of bytes in last sector 0 000005D6 ???? I_am_nobits SECCNT_DOS,WORD ; No. of whole sectors 0 000005D8 ???? I_am_nobits ENTFREE,WORD ; 0 000005DA ???? I_am_nobits ENTLAST,WORD ; 0 000005DC ???? I_am_nobits NXTCLUSNUM,WORD ; 0 000005DE ???????? I_am_nobits GROWCNT,DWORD ; 0 000005E2 ???????? I_am_nobits CURBUF,DWORD ; 0 000005E6 ???????? I_am_nobits CONSft,DWORD ; SFT of console swapped guy. 0 000005EA ???? I_am_nobits SaveBX,WORD ; 0 000005EC ???? I_am_nobits SaveDS,WORD ; 0 000005EE ???? I_am_nobits restore_tmp,WORD ; return address for restore world 0 000005F0 ???? I_am_nobits NSS,WORD 0 000005F2 ???? I_am_nobits NSP,WORD 0 000005F4 ???? I_am_nobits EXTOPEN_FLAG,WORD,<0> ;FT. extended open input flag ;AN000; 0 000005F6 ?? I_am_nobits EXTOPEN_ON,BYTE,<0> ;FT. extended open conditional flag ;AN000; 0 000005F7 ???? I_am_nobits EXTOPEN_IO_MODE,WORD,<0>;FT. extende open io mode ;AN000; 0 000005F9 ???? I_am_nobits SAVE_DI,WORD ;FT. extende open saved DI ;AN000; 0 000005FB ???? I_am_nobits SAVE_ES,WORD ;FT. extende open saved ES ;AN000; 0 000005FD ???? I_am_nobits SAVE_DX,WORD ;FT. extende open saved DX ;AN000; 0 000005FF ???? I_am_nobits SAVE_CX,WORD ;FT. extende open saved CX ;AN000; 0 00000601 ???? I_am_nobits SAVE_BX,WORD ;FT. extende open saved BX ;AN000; 0 00000603 ???? I_am_nobits SAVE_SI,WORD ;FT. extende open saved SI ;AN000; 0 00000605 ???? I_am_nobits SAVE_DS,WORD ;FT. extende open saved DS ;AN000; 0 00000607 ???? I_am_nobits HIGH_SECTOR,WORD,<0> ;>32mb higher sector # ;AN000; 0 00000609 ???? I_am_nobits HIGH_SECTOR_TEMP,WORD,<0>;>32mb high sector # ;AN000; 0 0000060B ?? I_am_nobits DISK_FULL,BYTE ;>32mb indicating disk full when 1 ;AN000; 0 0000060C ???? I_am_nobits TEMP_VAR,WORD ; temporary variable for everyone ;AN000; 0 0000060E ???? I_am_nobits TEMP_VAR2,WORD ; temporary variable 2 for everyone ;AN000; 0 00000610 ?? I_am_nobits DrvErr,BYTE ; used to save drive error ;AN000; 0 00000611 ???? I_am_nobits DOS34_FLAG,WORD,<0> ; common flag for DOS 3.4 ;AN000; 0 00000613 ???????? I_am_nobits NO_FILTER_PATH,DWORD ; pointer to orignal path ;AN000; 0 00000617 ???????? I_am_nobits NO_FILTER_DPATH,DWORD ; pointer to orignal path of destination;AN000; 0 0000061B ???? I_am_nobits Callback_SS,WORD ;AN000; call back SS for system call 0 0000061D ???? I_am_nobits Callback_SP,WORD ;AN000; call back SP for system call 0 0000061F ?? I_am_nobits Callback_flag,BYTE,<0> ;AN000; call back flag 168 <2> 169 <2> 170 <2> ; make those pushes fast!!! 171 <2> record alignb 2, 90h 172 <2> StackSize equ 180h ; gross but effective 173 <2> ;;;StackSize = 300h ; This is a "trial" change IBM hasn't 174 <2> ;;; ; made up their minds about 175 <2> 176 <2> ; 177 <2> ; WARNING!!!! DskStack may grow into AUXSTACK due to interrupt service. 178 <2> ; This is NO problem as long as AUXSTACK comes immediately before DSKSTACK 179 <2> ; 180 <2> 181 <2> PUBLIC RENAMEDMA,AuxStack,DskStack,IOStack 182 <2> RENAMEDMA LABEL BYTE ; See DOS_RENAME 183 <2> 0 00000620 ?????????????????? DB StackSize DUP (?) ; 184 00000273 ??????????????????- <2> 184 0000027C ??????????????????- <2> 184 00000285 ??????????????????- <2> 184 0000028E ??????????????????- <2> 184 00000297 ??????????????????- <2> 184 000002A0 ??????????????????- <2> 184 000002A9 ??????????????????- <2> 184 000002B2 ??????????????????- <2> 184 000002BB ??????????????????- <2> 184 000002C4 ??????????????????- <2> 184 000002CD ??????????????????- <2> 184 000002D6 ??????????????????- <2> 184 000002DF ??????????????????- <2> 184 000002E8 ??????????????????- <2> 184 000002F1 ??????????????????- <2> 184 000002FA ??????????????????- <2> 184 00000303 ??????????????????- <2> 184 0000030C ??????????????????- <2> 184 00000315 ??????????????????- <2> 184 0000031E ??????????????????- <2> 184 00000327 ??????????????????- <2> 184 00000330 ??????????????????- <2> 184 00000339 ??????????????????- <2> 184 00000342 ??????????????????- <2> 184 0000034B ??????????????????- <2> 184 00000354 ??????????????????- <2> 184 0000035D ??????????????????- <2> 184 00000366 ??????????????????- <2> 184 0000036F ??????????????????- <2> 184 00000378 ??????????????????- <2> 184 00000381 ??????????????????- <2> 184 0000038A ??????????????????- <2> 184 00000393 ??????????????????- <2> 184 0000039C ??????????????????- <2> 184 000003A5 ??????????????????- <2> 184 000003AE ??????????????????- <2> 184 000003B7 ??????????????????- <2> 184 000003C0 ??????????????????- <2> 184 000003C9 ??????????????????- <2> 184 000003D2 ??????????????????- <2> 184 000003DB ??????????????????- <2> 184 000003E4 ???????????? <2> 185 <2> AuxStack LABEL BYTE 186 <2> 0 000007A0 ?????????????????? DB StackSize DUP (?) ; 187 000003F3 ??????????????????- <2> 187 000003FC ??????????????????- <2> 187 00000405 ??????????????????- <2> 187 0000040E ??????????????????- <2> 187 00000417 ??????????????????- <2> 187 00000420 ??????????????????- <2> 187 00000429 ??????????????????- <2> 187 00000432 ??????????????????- <2> 187 0000043B ??????????????????- <2> 187 00000444 ??????????????????- <2> 187 0000044D ??????????????????- <2> 187 00000456 ??????????????????- <2> 187 0000045F ??????????????????- <2> 187 00000468 ??????????????????- <2> 187 00000471 ??????????????????- <2> 187 0000047A ??????????????????- <2> 187 00000483 ??????????????????- <2> 187 0000048C ??????????????????- <2> 187 00000495 ??????????????????- <2> 187 0000049E ??????????????????- <2> 187 000004A7 ??????????????????- <2> 187 000004B0 ??????????????????- <2> 187 000004B9 ??????????????????- <2> 187 000004C2 ??????????????????- <2> 187 000004CB ??????????????????- <2> 187 000004D4 ??????????????????- <2> 187 000004DD ??????????????????- <2> 187 000004E6 ??????????????????- <2> 187 000004EF ??????????????????- <2> 187 000004F8 ??????????????????- <2> 187 00000501 ??????????????????- <2> 187 0000050A ??????????????????- <2> 187 00000513 ??????????????????- <2> 187 0000051C ??????????????????- <2> 187 00000525 ??????????????????- <2> 187 0000052E ??????????????????- <2> 187 00000537 ??????????????????- <2> 187 00000540 ??????????????????- <2> 187 00000549 ??????????????????- <2> 187 00000552 ??????????????????- <2> 187 0000055B ??????????????????- <2> 187 00000564 ???????????? <2> 188 <2> DskStack LABEL BYTE 189 <2> 0 00000920 ?????????????????? DB StackSize DUP (?) ; 190 00000573 ??????????????????- <2> 190 0000057C ??????????????????- <2> 190 00000585 ??????????????????- <2> 190 0000058E ??????????????????- <2> 190 00000597 ??????????????????- <2> 190 000005A0 ??????????????????- <2> 190 000005A9 ??????????????????- <2> 190 000005B2 ??????????????????- <2> 190 000005BB ??????????????????- <2> 190 000005C4 ??????????????????- <2> 190 000005CD ??????????????????- <2> 190 000005D6 ??????????????????- <2> 190 000005DF ??????????????????- <2> 190 000005E8 ??????????????????- <2> 190 000005F1 ??????????????????- <2> 190 000005FA ??????????????????- <2> 190 00000603 ??????????????????- <2> 190 0000060C ??????????????????- <2> 190 00000615 ??????????????????- <2> 190 0000061E ??????????????????- <2> 190 00000627 ??????????????????- <2> 190 00000630 ??????????????????- <2> 190 00000639 ??????????????????- <2> 190 00000642 ??????????????????- <2> 190 0000064B ??????????????????- <2> 190 00000654 ??????????????????- <2> 190 0000065D ??????????????????- <2> 190 00000666 ??????????????????- <2> 190 0000066F ??????????????????- <2> 190 00000678 ??????????????????- <2> 190 00000681 ??????????????????- <2> 190 0000068A ??????????????????- <2> 190 00000693 ??????????????????- <2> 190 0000069C ??????????????????- <2> 190 000006A5 ??????????????????- <2> 190 000006AE ??????????????????- <2> 190 000006B7 ??????????????????- <2> 190 000006C0 ??????????????????- <2> 190 000006C9 ??????????????????- <2> 190 000006D2 ??????????????????- <2> 190 000006DB ??????????????????- <2> 190 000006E4 ???????????? <2> 191 <2> IOStack LABEL BYTE 192 <2> 193 <2> 194 <2> ; patch space for Boca folks. 195 <2> ; Say What????!!! This does NOT go into the swappable area! 196 <2> ; NOTE: We include the decl of ibmpatch in ms-dos even though it is not needed. 197 <2> ; This allows the REDIRector to work on either IBM or MS-DOS. 198 <2> 199 <2> PUBLIC IBMPATCH 200 <2> IBMPATCH label byte 0 00000AA0 ?? I_am_nobits PRINTER_FLAG,BYTE,<0> ; [SYSTEM] status of PRINT utility 0 00000AA1 ?? I_am_nobits VOLCHNG_FLAG,BYTE,<0> ; [SYSTEM] true if volume label created 0 00000AA2 ?? I_am_nobits VIRTUAL_OPEN,BYTE,<0> ; [SYSTEM] non-zero if we opened a virtual file 204 <2> 205 <2> ; Following 4 variables moved to MSDATA.asm from MSTABLE.asm (P4986) 0 00000AA3 ?? I_am_nobits FSeek_drive,BYTE ;AN000; fastseek drive # 0 00000AA4 ???? I_am_nobits FSeek_firclus,WORD ;AN000; fastseek first cluster # 0 00000AA6 ???? I_am_nobits FSeek_logclus,WORD ;AN000; fastseek logical cluster # 0 00000AA8 ???? I_am_nobits FSeek_logsave,WORD ;AN000; fastseek returned log clus # 210 <2> %ifndef BUF2 211 <2> record {I_am_nobits ACT_PAGE,WORD,<-1>}, 255 ;;;;;;; ;BL ; active EMS page ;AN000; 212 <2> %endif 213 <2> 214 <2> ; lDOS extensions 215 <2> record alignb 2, 90h 0 00000AAA ???? I_am_nobits CLUSTER_FACTOR_EDR,WORD 0 00000AAC ???? I_am_nobits CLUSTER_NEXT_EDR,WORD 0 00000AAE ???? I_am_nobits dosdata_to_doscode,WORD 219 <2> dosdata_to_doscode_segment equ dosdata_to_doscode 220 <2> global dosdata_to_doscode_segment 0 00000AB0 ???? record {I_am_nobits first_umcb, word, <-1>}, 255 0 00000AB2 ?? I_am_nobits enable_uma, byte 0 00000AB3 ?? I_am_nobits alloc_strategy_ext, byte 0 00000AB4 ???? I_am_nobits first_hmcb, word 0 00000AB6 ?? I_am_nobits doslocation3306, byte 0 00000AB7 ?? I_am_nobits doslocation3001, byte 0 00000AB8 ???? I_am_nobits backdoor_free_mcb_exec, word 0 00000ABA ???????? record {I_am_nobits backdoor_indicator, dword, <-1, -1>}, 255 229 <2> 0 00000ABE ???????? I_am_nobits shell_return_address, dword 0 00000AC2 ?? record {I_am_nobits shell_return_has_been_freed, byte, <-1>}, 255 232 <2> 233 <2> SWAP_END LABEL BYTE 234 <2> PUBLIC SWAP_END 235 <2> 236 <2> ; THE FOLLOWING BYTE MUST BE HERE, IMMEDIATELY FOLLOWING SWAP_END. IT CANNOT 237 <2> ; BE USED. If the size of the swap data area is ODD, it will be rounded up 238 <2> ; to include this byte. 0 00000AC3 ?? DB ? 240 <2> 241 <2> ibmpatch equ IBMPATCH ; NASM port label 0 00000AC4 ?????????????????? DB (512+80+32-(SWAP_END-ibmpatch)) DUP (?) 242 00000717 ??????????????????- <2> 242 00000720 ??????????????????- <2> 242 00000729 ??????????????????- <2> 242 00000732 ??????????????????- <2> 242 0000073B ??????????????????- <2> 242 00000744 ??????????????????- <2> 242 0000074D ??????????????????- <2> 242 00000756 ??????????????????- <2> 242 0000075F ??????????????????- <2> 242 00000768 ??????????????????- <2> 242 00000771 ??????????????????- <2> 242 0000077A ??????????????????- <2> 242 00000783 ??????????????????- <2> 242 0000078C ??????????????????- <2> 242 00000795 ??????????????????- <2> 242 0000079E ??????????????????- <2> 242 000007A7 ??????????????????- <2> 242 000007B0 ??????????????????- <2> 242 000007B9 ??????????????????- <2> 242 000007C2 ??????????????????- <2> 242 000007CB ??????????????????- <2> 242 000007D4 ??????????????????- <2> 242 000007DD ??????????????????- <2> 242 000007E6 ??????????????????- <2> 242 000007EF ??????????????????- <2> 242 000007F8 ??????????????????- <2> 242 00000801 ??????????????????- <2> 242 0000080A ??????????????????- <2> 242 00000813 ??????????????????- <2> 242 0000081C ??????????????????- <2> 242 00000825 ??????????????????- <2> 242 0000082E ??????????????????- <2> 242 00000837 ??????????????????- <2> 242 00000840 ??????????????????- <2> 242 00000849 ??????????????????- <2> 242 00000852 ??????????????????- <2> 242 0000085B ??????????????????- <2> 242 00000864 ??????????????????- <2> 242 0000086D ??????????????????- <2> 242 00000876 ??????????????????- <2> 242 0000087F ??????????????????- <2> 242 00000888 ??????????????????- <2> 242 00000891 ??????????????????- <2> 242 0000089A ??????????????????- <2> 242 000008A3 ??????????????????- <2> 242 000008AC ??????????????????- <2> 242 000008B5 ??????????????????- <2> 242 000008BE ??????????????????- <2> 242 000008C7 ??????????????????- <2> 242 000008D0 ??????????????????- <2> 242 000008D9 ??????????????????- <2> 242 000008E2 ??????????????????- <2> 242 000008EB ??????????????????- <2> 242 000008F4 ??????????????????- <2> 242 000008FD ??????????????????- <2> 242 00000906 ??????????????????- <2> 242 0000090F ??????????????????- <2> 242 00000918 ??????????????????- <2> 242 00000921 ??????????????????- <2> 242 0000092A ??????????????????- <2> 242 00000933 ??????????????????- <2> 242 0000093C ??????????????????- <2> 242 00000945 ??????????????????- <2> 242 0000094E ??????????????????- <2> 242 00000957 ???????? <2> 243 <2> 244 <2> MSDAT001e label byte 245 <2> 246 <2> ;.xall 247 <2> 248 <2> ; (no prior section) ; DATA ENDS 249 <2> 37 <1> ;=== Pop trace listing source 38 <1> ;=== Push trace listing source: msinit.nas 39 <1> %include "msinit.nas" ; NASM included file 1 <2> ; SCCSID = @(#)msinit.asm 1.2 85/07/23 2 <2> ; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE 3 <2> ; AN000 version 4.0 Jan. 1988 4 <2> ; AN007 PTM 3957 - fake version for IBMCACHE.COM 5 <2> ; AN008 PTM 4070 - fake version for MS WINDOWS 6 <2> [list -] 6 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 11 <2> %include "entrysw.mac" 1 <3> 2 <3> DOSENTRYADJUSTSEGMENT equ 60h - 26h 3 <3> DOSENTRYADJUSTOFFSET equ DOSENTRYADJUSTSEGMENT * 16 4 <3> 5 <3> DOSENTRYDEVICEBASE equ 10h 12 <2> %include "lstruct.mac" 1 <3> [list -] 13 <3> [list -] 13 <2> %include "entryseg.nas" 1 <3> 2 <3> %ifndef ENTRYSEGNAS 3 <3> %define ENTRYSEGNAS 1 4 <3> 5 <3> %include "lmacros3.mac" 6 <3> === Switch to base=003490h -> "DOSENTRY" 7 <3> addsection DOSENTRY, class=%[DOSENTRY] 8 <3> 9 <3> group DOSENTRYGROUP DOSENTRY 10 <3> 11 <3> %endif 14 <2> [list +] 15 <2> 16 <2> extern i20, i21, i25, i26, i27, i2F, i2D, call5, i23, i24, entry_iret, i31 17 <2> 18 <2> I_need DMAAdd,DWORD ; current dma address 19 <2> I_need DPBHead,DWORD ; long pointer to DPB chain 20 <2> I_need SFT_Addr,DWORD ; pointer to open file list 21 <2> I_need NumIO,BYTE ; number of physical drives 22 <2> I_need BuffHead,DWORD ; pointer to buffer chain 23 <2> I_need EndMem,WORD ; first unavailable address in memory 24 <2> I_need CurrentPDB,WORD ; current process ID 25 <2> I_need CreatePDB,BYTE ; TRUE => create a new PDB 26 <2> I_need Arena_Head,WORD ; paragraph address of head of arena 27 <2> I_need sfTabl,BYTE ; internal file table 28 <2> I_need SysInitVar,BYTE ; label for internal structures 29 <2> I_need NulDev,DWORD ; long pointer to device chain 30 <2> I_need BCon,DWORD ; pointer to console device 31 <2> I_need BClock,DWORD ; pointer to clock device 32 <2> I_need CallUnit,BYTE ; unit field in dd packet 33 <2> I_need CallBPB,DWORD ; returned BPB from DD 34 <2> I_need Maxsec,WORD 35 <2> I_need Dskchret,BYTE 36 <2> I_need Devcall,BYTE 37 <2> i_need Header,BYTE 38 <2> I_need JShare,DWORD 39 <2> I_need COUNTRY_CDPG,BYTE ; country info table, DOS 3.3 40 <2> I_need SysInitTable,BYTE ; sys init table for SYSINIT 41 <2> I_need FastOpenTable,BYTE ; table for FASTOPEN 42 <2> I_need FETCHI_TAG,WORD ; TAG CHECK 43 <2> I_need Special_Entries,WORD ; address of special entries ;AN007; 44 <2> I_need IFS_DOS_CALL,DWORD ; IFS IBMDOS CALL entry ;AN000; 45 <2> I_need HASHINITVAR,WORD ; hash table variables ;AN000; 46 <2> I_need Packet_Temp,WORD ; used for initial Hash table;AN000; 47 <2> I_need BUF_HASH_PTR,DWORD ; used for initial Hash table;AN000; 48 <2> I_need SWAP_ALWAYS_AREA,DWORD ; swap always area addr ;AN000; 49 <2> I_need SWAP_ALWAYS_AREA_LEN,WORD; swap always area length ;AN000; 50 <2> I_need SWAP_IN_DOS,DWORD ; swap in dos area ;AN000; 51 <2> I_need SWAP_IN_DOS_LEN,WORD ; swap in dos area length ;AN000; 52 <2> I_need SWAP_AREA_LEN,WORD ; swap area length ;AN000; 53 <2> I_need SWAP_START,BYTE ; swap start addr ;AN000; 54 <2> I_need SWAP_ALWAYS,BYTE ; swap always addr ;AN000; 55 <2> I_need Hash_Temp,WORD ; temporary Hash table ;AN000; 56 <2> 57 <2> i_need CallDevAd,DWORD 58 <2> === Switch to base=001DC0h -> "DATA" 59 <2> section DATA 60 <2> ; ORG 0 ; reset to beginning of data segment 61 <2> 62 <2> %ifdef DONOBITS 0 00000D0D [list -] 196 <2> 197 <2> ; (no prior section) ; DATA ENDS 198 <2> 199 <2> ; the next segment defines a new class that MUST appear last in the link map. 200 <2> ; This defines several important locations for the initialization process that 201 <2> ; must be the first available locations of free memory. 202 <2> === Switch to base=001DC0h -> "LAST" 203 <2> section LAST 204 <2> 205 <2> %ifdef DONOBITS 206 <2> [list -] 1263 <2> 1264 <2> ; (no prior section) ; LAST ENDS 40 <1> ;=== Pop trace listing source 41 <1> END === Trace listing source: ../../INC/msdosmen.lst 1 %include "nobits.mac" 1 <1> %imacro stripparens 2.nolist 2 <1> %defstr %%param %2 3 <1> %rep 16 4 <1> %substr %%opening %%param 1 5 <1> %ifidn %%opening, '(' 6 <1> %substr %%param %%param 2,-1 7 <1> %endif 8 <1> %endrep 9 <1> %rep 16 10 <1> %strlen %%length %%param 11 <1> %substr %%closing %%param %%length 12 <1> %ifidn %%closing, ')' 13 <1> %substr %%param %%param 1,-2 14 <1> %endif 15 <1> %endrep 16 <1> %deftok %%token %%param 17 <1> %1 %%token 18 <1> %endmacro 19 <1> 20 <1> %imacro db 1-*.nolist 21 <1> %rep %0 22 <1> %define %%param %1 23 <1> %define %%multi 24 <1> %defstr %%string %%param 25 <1> %strlen %%stringlength %%string 26 <1> %assign %%index 1 27 <1> %rep %%stringlength 28 <1> %substr %%checkblank %%string %%index 29 <1> %ifidni %%checkblank, '"' 30 <1> %elifidni %%checkblank, "'" 31 <1> %else 32 <1> %deftok %%checkblank %%checkblank 33 <1> %ifempty %%checkblank 34 <1> %substr %%dup %%string %%index + 1,4 35 <1> %deftok %%dup %%dup 36 <1> %assign %%isdup 0 37 <1> %ifidni %%dup, dup 38 <1> %assign %%isdup 1 39 <1> %elifidni %%dup, dup( 40 <1> %assign %%isdup 1 41 <1> %endif 42 <1> %if %%isdup 43 <1> %substr %%multi %%string 1, %%index - 1 44 <1> %deftok %%multi %%multi 45 <1> %substr %%string %%string %%index + 5, -1 46 <1> %deftok %%token %%string 47 <1> %undef %%param 48 <1> stripparens %define %%param, %%token 49 <1> %assign %%length 1 50 <1> %ifstr %%param 51 <1> %strlen %%length %%param 52 <1> %endif 53 <1> %rep %%length * %%multi 54 <1> db ? 55 <1> %endrep 56 <1> %exitrep 57 <1> %endif 58 <1> %endif 59 <1> %endif 60 <1> %assign %%index %%index + 1 61 <1> %endrep 62 <1> %ifempty %%multi 63 <1> %assign %%length 1 64 <1> %ifstr %%param 65 <1> %strlen %%length %%param 66 <1> %endif 67 <1> %rep %%length 68 <1> db ? 69 <1> %endrep 70 <1> %endif 71 <1> %rotate 1 72 <1> %endrep 73 <1> %endmacro 74 <1> 75 <1> %imacro dw 1-*.nolist 76 <1> %rep %0 77 <1> %define %%param %1 78 <1> %define %%multi 79 <1> %defstr %%string %%param 80 <1> %strlen %%stringlength %%string 81 <1> %assign %%index 1 82 <1> %rep %%stringlength 83 <1> %substr %%checkblank %%string %%index 84 <1> %ifidni %%checkblank, '"' 85 <1> %elifidni %%checkblank, "'" 86 <1> %else 87 <1> %deftok %%checkblank %%checkblank 88 <1> %ifempty %%checkblank 89 <1> %substr %%dup %%string %%index + 1,4 90 <1> %deftok %%dup %%dup 91 <1> %assign %%isdup 0 92 <1> %ifidni %%dup, dup 93 <1> %assign %%isdup 1 94 <1> %elifidni %%dup, dup( 95 <1> %assign %%isdup 1 96 <1> %endif 97 <1> %if %%isdup 98 <1> %substr %%multi %%string 1, %%index - 1 99 <1> %deftok %%multi %%multi 100 <1> %substr %%string %%string %%index + 5, -1 101 <1> %deftok %%token %%string 102 <1> %undef %%param 103 <1> stripparens %define %%param, %%token 104 <1> %assign %%length 1 105 <1> %ifstr %%param 106 <1> %strlen %%length %%param 107 <1> %assign %%length (%%length + 1) / 2 108 <1> %endif 109 <1> %rep %%length * %%multi 110 <1> dw ? 111 <1> %endrep 112 <1> %exitrep 113 <1> %endif 114 <1> %endif 115 <1> %endif 116 <1> %assign %%index %%index + 1 117 <1> %endrep 118 <1> %ifempty %%multi 119 <1> %assign %%length 1 120 <1> %ifstr %%param 121 <1> %strlen %%length %%param 122 <1> %assign %%length (%%length + 1) / 2 123 <1> %endif 124 <1> %rep %%length 125 <1> dw ? 126 <1> %endrep 127 <1> %endif 128 <1> %rotate 1 129 <1> %endrep 130 <1> %endmacro 131 <1> 132 <1> %imacro dd 1-*.nolist 133 <1> %rep %0 134 <1> %define %%param %1 135 <1> %define %%multi 136 <1> %defstr %%string %%param 137 <1> %strlen %%stringlength %%string 138 <1> %assign %%index 1 139 <1> %rep %%stringlength 140 <1> %substr %%checkblank %%string %%index 141 <1> %ifidni %%checkblank, '"' 142 <1> %elifidni %%checkblank, "'" 143 <1> %else 144 <1> %deftok %%checkblank %%checkblank 145 <1> %ifempty %%checkblank 146 <1> %substr %%dup %%string %%index + 1,4 147 <1> %deftok %%dup %%dup 148 <1> %assign %%isdup 0 149 <1> %ifidni %%dup, dup 150 <1> %assign %%isdup 1 151 <1> %elifidni %%dup, dup( 152 <1> %assign %%isdup 1 153 <1> %endif 154 <1> %if %%isdup 155 <1> %substr %%multi %%string 1, %%index - 1 156 <1> %deftok %%multi %%multi 157 <1> %substr %%string %%string %%index + 5, -1 158 <1> %deftok %%token %%string 159 <1> %undef %%param 160 <1> stripparens %define %%param, %%token 161 <1> %assign %%length 1 162 <1> %ifstr %%param 163 <1> %strlen %%length %%param 164 <1> %assign %%length (%%length + 3) / 4 165 <1> %endif 166 <1> %rep %%length * %%multi 167 <1> dd ? 168 <1> %endrep 169 <1> %exitrep 170 <1> %endif 171 <1> %endif 172 <1> %endif 173 <1> %assign %%index %%index + 1 174 <1> %endrep 175 <1> %ifempty %%multi 176 <1> %assign %%length 1 177 <1> %ifstr %%param 178 <1> %strlen %%length %%param 179 <1> %assign %%length (%%length + 3) / 4 180 <1> %endif 181 <1> %rep %%length 182 <1> dd ? 183 <1> %endrep 184 <1> %endif 185 <1> %rotate 1 186 <1> %endrep 187 <1> %endmacro 2 %define DONOBITS 3 %include "msdosme.nas" 1 <1> ; SCCSID = @(#)ibmdosmes.asm 1.1 85/04/10 2 <1> ; 3 <1> ; Standard device IO for MSDOS (first 12 function calls) 4 <1> ; 5 <1> debug equ 0 6 <1> [list -] 6 ****************** <1> warning: out: ... CLONE version build switch on ... [-w+user] 6 ****************** <1> warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi] 14 <5> [list -] 14 <4> [list -] 3 <3> === Switch to base=001DC0h -> "DOSSTART" 4 <3> addsection DOSSTART, align=16 PUBLIC class=DOSSTART 5 <3> ; (no prior section) ; DOSSTART ENDS 6 <3> === Switch to base=001DC0h -> "DOSSTARTJUMP" 7 <3> addsection DOSSTARTJUMP, align=1 PUBLIC class=START 8 <3> ; (no prior section) ; DOSSTARTJUMP ENDS 9 <3> === Switch to base=001DC0h -> "CONSTANTS" 10 <3> addsection CONSTANTS, align=2 PUBLIC class=CONST 11 <3> ; (no prior section) ; CONSTANTS ENDS 12 <3> === Switch to base=001DC0h -> "DATA" 13 <3> addsection DATA, align=2 PUBLIC class=DATA 14 <3> ; (no prior section) ; DATA ENDS 15 <3> === Switch to base=001DC0h -> "TABLE" 16 <3> addsection TABLE, align=2 PUBLIC class=TABLE 17 <3> ; (no prior section) ; TABLE ENDS 18 <3> === Switch to base=001DC0h -> "DOSDATATABLE" 19 <3> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE 20 <3> ; (no prior section) ; DOSDATATABLE ENDS 21 <3> === Switch to base=001DC0h -> "DOSDATACODE" 22 <3> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE 23 <3> ; (no prior section) ; DOSDATACODE ENDS 24 <3> === Switch to base=001DC0h -> "DOSBIODATA" 25 <3> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA 26 <3> === Switch to base=001DC0h -> "LAST" 27 <3> addsection LAST, align=16 PUBLIC class=LAST 28 <3> ; (no prior section) ; LAST ENDS 29 <3> 30 <3> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST 31 <3> 32 <3> %include "entryseg.nas" 1 <4> 2 <4> %ifndef ENTRYSEGNAS 3 <4> %define ENTRYSEGNAS 1 4 <4> 5 <4> %include "lmacros3.mac" 1 <5> [list -] 6 <4> === Switch to base=003490h -> "DOSENTRY" 7 <4> addsection DOSENTRY, class=%[DOSENTRY] 8 <4> 9 <4> group DOSENTRYGROUP DOSENTRY 10 <4> 11 <4> %endif 8 <2> 9 <2> %include "dcodeseg.nas" 1 <3> 2 <3> %ifndef DCODESEGNAS 3 <3> %assign DCODESEGNAS 1 4 <3> === Switch to base=003490h -> "DOSCODETABLE" 5 <3> section DOSCODETABLE align=2 PUBLIC class=DOSCODE 6 <3> ; (no prior section) ; DOSCODETABLE ENDS === Switch to base=003490h -> "DOSCODECODE" 7 <3> section DOSCODECODE align=1 PUBLIC class=DOSCODE 8 <3> ; (no prior section) ; DOSCODECODE ENDS === Switch to base=003490h -> "DOSBIOCODE" 9 <3> section DOSBIOCODE align=2 PUBLIC class=DOSCODE === Switch to base=003490h -> "BIOCODE" 10 <3> section BIOCODE align=2 PUBLIC class=DOSCODE 11 <3> 12 <3> group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE 13 <3> 14 <3> %endif 10 <2> === Switch to base=001DC0h -> "LAST" 11 <2> section LAST 12 <2> ; (no prior section) ; LAST ENDS 12 <1> ;.cref 13 <1> [list +] 14 <1> 15 <1> ;TITLE IBMDOSMES - DOS OEM dependancies 16 <1> ;NAME IBMDOSMES 17 <1> 18 <1> ;=== Push trace listing source: dosmes.nas 19 <1> %include "dosmes.nas" ; NASM included file 1 <2> ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 2 <2> ; SCCSID = @(#)dosmes.asm 1.7 85/10/23 3 <2> ; 4 <2> ; Message file for Internationalized messages. There is 5 <2> ; only one message here available for translation. 6 <2> ; 7 <2> ; 8 <2> ; Revision history 9 <2> ; A000 version 4.00 Jan. 1988 10 <2> ; 11 <2> 12 <2> %IFNdef KANJI 13 <2> %iassign KANJI FALSE 14 <2> %ENDIF 15 <2> 16 <2> %IFNdef Rainbow 17 <2> %iassign Rainbow FALSE 18 <2> %ENDIF 19 <2> 20 <2> [list -] 20 ****************** <2> warning: out: ... for DOS Version 4.00 ... [-w+user] 20 ****************** <2> warning: out: BPB.INC... [-w+user] 20 ****************** <2> warning: out: ... CLONE version build switch on ... [-w+user] 28 <2> === Switch to base=001DC0h -> "CONSTANTS" 29 <2> section CONSTANTS 30 <2> 31 <2> UserNum equ USERNUM ; NASM port label 32 <2> OEMNum equ OEMNUM ; NASM port label 33 <2> PUBLIC UserNum, OEMNum 34 <2> Public DMES001S,DMES001E 35 <2> DMES001S Label byte 0 000003B2 ???? USERNUM DW ? ; 24 bit user number 0 000003B4 ?? DB ? 38 <2> OEMNUM: 39 <2> %if 0 40 <2> %IF IBM 41 <2> %IF IBMCOPYRIGHT 42 <2> DB 0 ; 8 bit OEM number 43 <2> %ELSE 44 <2> DB 0FFH ; 8 bit OEM number 45 <2> %ENDIF 46 <2> %ELSE 47 <2> DB 0FFH 48 <2> %ENDIF 49 <2> %else 0 000003B5 ?? db 26h ; lDOS OEM number = 26h 51 <2> %endif 52 <2> 53 <2> DMES001E label byte 54 <2> ; (no prior section) ; CONSTANTS ENDS 55 <2> === Switch to base=001DC0h -> "TABLE" 56 <2> section TABLE ; in DOSDATA 57 <2> Public DMES002S 58 <2> DMES002S label byte 59 <2> 60 <2> 61 <2> ; The following table is used for DOS 3.3 62 <2> ;DOS country and code page information is defined here for DOS 3.3. 63 <2> ;The initial value for ccDosCountry is 1 (USA). 64 <2> ;The initial value for ccDosCodepage is 850. 65 <2> ; 66 <2> ; 67 <2> PUBLIC COUNTRY_CDPG,UCASE_TAB,FILE_UCASE_TAB 68 <2> PUBLIC FILE_CHAR_TAB 69 <2> ; 70 <2> ; country and code page infomation 71 <2> ; 72 <2> COUNTRY_CDPG label byte 73 <2> 0 00000D12 ???????????????? db 0,0,0,0,0,0,0,0 ; reserved words 0 00000D1A ?????????????????? db '\COUNTRY.SYS',0 ; path name of country.sys 75 00000011 ???????? <2> 0 00000D27 ?????????????????? db 51 dup (?) 76 0000001E ??????????????????- <2> 76 00000027 ??????????????????- <2> 76 00000030 ??????????????????- <2> 76 00000039 ??????????????????- <2> 76 00000042 ???????????? <2> 0 00000D5A ???? dw 437 ; system code page id 0 00000D5C ???? dw 6 ; number of entries 0 00000D5E ?? db SetUcase ; Ucase type 0 00000D5F ???? dw OFFSET UCASE_TAB wrt DOSGROUP ;pointer to upper case table 0 00000D61 ???? dw 0 ; segment of poiter 0 00000D63 ?? db SetUcaseFile ; Ucase file char type 0 00000D64 ???? dw OFFSET FILE_UCASE_TAB wrt DOSGROUP ;pointer to file upper case table 0 00000D66 ???? dw 0 ; segment of poiter 0 00000D68 ?? db SetFileList ; valid file chars type 0 00000D69 ???? dw OFFSET FILE_CHAR_TAB wrt DOSGROUP ;pointer to valid file char tab 0 00000D6B ???? dw 0 ; segment of poiter 0 00000D6D ?? db SetCollate ; collate type 0 00000D6E ???? dw OFFSET COLLATE_TAB wrt DOSGROUP ;pointer to collate table 0 00000D70 ???? dw 0 ; segment of poiter 0 00000D72 ?? db SetDBCS ;AN000; DBCS Ev 2/12/KK 0 00000D73 ???? dw OFFSET DBCS_TAB wrt DOSGROUP ;AN000;;pointer to DBCS Ev table 2/12/KK 0 00000D75 ???? dw 0 ;AN000; segment of poiter 2/12/KK 0 00000D77 ?? db SetCountryInfo ; country info type 0 00000D78 ???? dw NEW_COUNTRY_SIZE ; extended country info size 0 00000D7A ???? dw 1 ; USA country id 0 00000D7C ???? dw 437 ; USA system code page id 0 00000D7E ???? dw 0 ; date format 0 00000D80 ?????????? db '$',0,0,0,0 ; currency symbol 0 00000D85 ???? db ',',0 ; thousand separator 0 00000D87 ???? db '.',0 ; decimal separator 0 00000D89 ???? db '-',0 ; date separator 0 00000D8B ???? db ':',0 ; time separator 0 00000D8D ?? db 0 ; currency format flag 0 00000D8E ?? db 2 ; # of disgit in currency 0 00000D8F ?? db 0 ; time format 0 00000D90 ???? dw casemap + DOSENTRYADJUSTOFFSET ;mono case routine entry point 0 00000D92 ???? dw DOSENTRY - DOSENTRYADJUSTSEGMENT ; segment of entry point 0 00000D94 ???? db ',',0 ; data list separator 0 00000D96 ???????????????? dw 0,0,0,0,0 ; reserved 110 0000008C ???? <2> 111 <2> 112 <2> 113 <2> 114 <2> ; 115 <2> ; 116 <2> ; 117 <2> ; 118 <2> ; 119 <2> ; upper case table 120 <2> ; 121 <2> UCASE_TAB label byte 0 00000DA0 ???? dw 128 0 00000DA2 ???????????????? db 128,154,069,065,142,065,143,128 0 00000DAA ???????????????? db 069,069,069,073,073,073,142,143 0 00000DB2 ???????????????? db 144,146,146,079,153,079,085,085 0 00000DBA ???????????????? db 089,153,154,155,156,157,158,159 0 00000DC2 ???????????????? db 065,073,079,085,165,165,166,167 0 00000DCA ???????????????? db 168,169,170,171,172,173,174,175 0 00000DD2 ???????????????? db 176,177,178,179,180,181,182,183 0 00000DDA ???????????????? db 184,185,186,187,188,189,190,191 0 00000DE2 ???????????????? db 192,193,194,195,196,197,198,199 0 00000DEA ???????????????? db 200,201,202,203,204,205,206,207 0 00000DF2 ???????????????? db 208,209,210,211,212,213,214,215 0 00000DFA ???????????????? db 216,217,218,219,220,221,222,223 0 00000E02 ???????????????? db 224,225,226,227,228,229,230,231 0 00000E0A ???????????????? db 232,233,234,235,236,237,238,239 0 00000E12 ???????????????? db 240,241,242,243,244,245,246,247 0 00000E1A ???????????????? db 248,249,250,251,252,253,254,255 139 <2> 140 <2> ; 141 <2> ; file upper case table 142 <2> ; 143 <2> FILE_UCASE_TAB label byte 0 00000E22 ???? dw 128 0 00000E24 ???????????????? db 128,154,069,065,142,065,143,128 0 00000E2C ???????????????? db 069,069,069,073,073,073,142,143 0 00000E34 ???????????????? db 144,146,146,079,153,079,085,085 0 00000E3C ???????????????? db 089,153,154,155,156,157,158,159 0 00000E44 ???????????????? db 065,073,079,085,165,165,166,167 0 00000E4C ???????????????? db 168,169,170,171,172,173,174,175 0 00000E54 ???????????????? db 176,177,178,179,180,181,182,183 0 00000E5C ???????????????? db 184,185,186,187,188,189,190,191 0 00000E64 ???????????????? db 192,193,194,195,196,197,198,199 0 00000E6C ???????????????? db 200,201,202,203,204,205,206,207 0 00000E74 ???????????????? db 208,209,210,211,212,213,214,215 0 00000E7C ???????????????? db 216,217,218,219,220,221,222,223 0 00000E84 ???????????????? db 224,225,226,227,228,229,230,231 0 00000E8C ???????????????? db 232,233,234,235,236,237,238,239 0 00000E94 ???????????????? db 240,241,242,243,244,245,246,247 0 00000E9C ???????????????? db 248,249,250,251,252,253,254,255 161 <2> 162 <2> ; 163 <2> ; file char list 164 <2> ; 165 <2> FILE_CHAR_TAB label byte 0 00000EA4 ???? dw 22 ; length 0 00000EA6 ?????? db 1,0,255 ; include all 0 00000EA9 ?????? db 0,0,20h ; exclude 0 - 20h 0 00000EAC ?????????????????? db 2,14,'."/\[]:|<>+=;,' ; exclude 14 special 169 ****************** <2> warning: unterminated string (missing `'') [-w+pp-open-string] 169 000001A3 ?????????????? <2> 0 00000EBC ?????????????????? db 24 dup (?) ; reserved 170 000001B3 ??????????????????- <2> 170 000001BC ???????????? <2> 171 <2> ; 172 <2> ; collate table 173 <2> ; 174 <2> COLLATE_TAB label byte 0 00000ED4 ???? dw 256 0 00000ED6 ???????????????? db 0,1,2,3,4,5,6,7 0 00000EDE ???????????????? db 8,9,10,11,12,13,14,15 0 00000EE6 ???????????????? db 16,17,18,19,20,21,22,23 0 00000EEE ???????????????? db 24,25,26,27,28,29,30,31 0 00000EF6 ???????????????? db " ","!",'"',"#","$","%","&","'" 180 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 0 00000EFE ???????????????? db "(",")","*","+",",","-",".","/" 0 00000F06 ???????????????? db "0","1","2","3","4","5","6","7" 0 00000F0E ???????????????? db "8","9",":",";","<","=",">","?" 183 ****************** <2> warning: unterminated string (missing `"') [-w+pp-open-string] 0 00000F16 ???????????????? db "@","A","B","C","D","E","F","G" 0 00000F1E ???????????????? db "H","I","J","K","L","M","N","O" 0 00000F26 ???????????????? db "P","Q","R","S","T","U","V","W" 0 00000F2E ???????????????? db "X","Y","Z","[","\","]","^","_" 0 00000F36 ???????????????? db "`","A","B","C","D","E","F","G" 188 ****************** <2> warning: unterminated string (missing ``') [-w+pp-open-string] 0 00000F3E ???????????????? db "H","I","J","K","L","M","N","O" 0 00000F46 ???????????????? db "P","Q","R","S","T","U","V","W" 0 00000F4E ???????????????? db "X","Y","Z","{","|","}","~",127 0 00000F56 ???????????????? db "C","U","E","A","A","A","A","C" 0 00000F5E ???????????????? db "E","E","E","I","I","I","A","A" 0 00000F66 ???????????????? db "E","A","A","O","O","O","U","U" 0 00000F6E ???????????????? db "Y","O","U","$","$","$","$","$" 0 00000F76 ???????????????? db "A","I","O","U","N","N",166,167 0 00000F7E ???????????????? db "?",169,170,171,172,"!",'"','"' 0 00000F86 ???????????????? db 176,177,178,179,180,181,182,183 0 00000F8E ???????????????? db 184,185,186,187,188,189,190,191 0 00000F96 ???????????????? db 192,193,194,195,196,197,198,199 0 00000F9E ???????????????? db 200,201,202,203,204,205,206,207 0 00000FA6 ???????????????? db 208,209,210,211,212,213,214,215 0 00000FAE ???????????????? db 216,217,218,219,220,221,222,223 0 00000FB6 ???? db 224,"S" 0 00000FB8 ???????????? db 226,227,228,229,230,231 0 00000FBE ???????????????? db 232,233,234,235,236,237,238,239 0 00000FC6 ???????????????? db 240,241,242,243,244,245,246,247 0 00000FCE ???????????????? db 248,249,250,251,252,253,254,255 209 <2> ; 210 <2> ; dbcs is not supported in DOS 3.3 211 <2> ; DBCS_TAB CC_DBCS <> 212 <2> ; 213 <2> ; DBCS for DOS 4.00 2/12/KK 214 <2> PUBLIC DBCS_TAB 215 <2> DBCS_TAB label byte ;AN000; 2/12/KK 0 00000FD6 ???? dw 0 ;AN000; 2/12/KK max number 0 00000FD8 ?????????????????? db 16 dup(0) ;AN000; 2/12/KK 217 000002CF ?????????????? <2> 218 <2> 219 <2> ; dw 6 ; 2/12/KK 220 <2> ; db 081h,09fh ; 2/12/KK 221 <2> ; db 0e0h,0fch ; 2/12/KK 222 <2> ; db 0,0 ; 2/12/KK 223 <2> ; 224 <2> ; 225 <2> === Switch to base=003490h -> "DOSCODETABLE" 226 <2> section DOSCODETABLE 227 <2> 228 <2> ;=== Push trace listing source: divmes.nas 229 <2> %include "divmes.nas" ; NASM included file 1 <3> ; THIS IS THE ONLY DOS "MESSAGE". IT DOES NOT NEED A TERMINATOR. 2 <3> PUBLIC DIVMES 3 <3> Public DIVM001S,DIVM001E 4 <3> DIVM001S label byte 5 <3> 6 <3> ;=== Push trace listing source: msdos.cl1 7 <3> %include "msdos.cl1" ; NASM included file 1 <4> ; msdos.cl1 2 <4> 3 <4> 4 <4> ;_______________________ 5 <4> 0 00000002 ?????????????????? DIVMES DB 13,10,"Divide overflow",13,10 6 00000009 ??????????????????- <4> 6 00000012 ?? <4> 8 <3> ;=== Pop trace listing source 9 <3> 10 <3> PUBLIC DivMesLen 11 <3> DivMes equ DIVMES ; NASM port label 0 00000015 ???? DivMesLen DW $-DivMes ; Length of the above message in bytes 13 <3> DIVM001E label byte 230 <2> ;=== Pop trace listing source 231 <2> === Switch to base=001DC0h -> "TABLE" 232 <2> section TABLE ; in DOSDATA 233 <2> 234 <2> ;=== Push trace listing source: yesno.nas 235 <2> %include "yesno.nas" ; NASM included file 1 <3> ; This is for contry Yes and No 2 <3> PUBLIC NLS_YES,NLS_yes2,NLS_NO,NLS_no2 3 <3> ;=== Push trace listing source: msdos.cl3 4 <3> %include "msdos.cl3" ; NASM included file 1 <4> ; msdos.cl3 2 <4> 3 <4> 4 <4> ;_______________________ 5 <4> 0 00000FE8 ?? NLS_YES DB "Y" 7 <4> 8 <4> ;_______________________ 9 <4> 0 00000FE9 ?? NLS_NO DB "N" 11 <4> 12 <4> ;_______________________ 13 <4> 0 00000FEA ?? NLS_yes2 DB "y" 15 <4> 16 <4> ;_______________________ 17 <4> 0 00000FEB ?? NLS_no2 DB "n" 5 <3> ;=== Pop trace listing source 236 <2> ;=== Pop trace listing source 237 <2> 238 <2> 239 <2> %ifndef DONOBITS 240 <2> === Switch to base=003490h -> "DOSCODECODE" 241 <2> section DOSCODECODE 242 <2> 243 <2> extern doscode_getdosdata 244 <2> 245 <2> relocated casemap 246 <2> assume ds:nothing, es:nothing, ss:nothing 247 <2> push ax 248 <2> call doscode_getdosdata 249 <2> push ax 250 <2> mov ax, MAP_CASE 251 <2> push ax 252 <2> retf 253 <2> 254 <2> === Switch to base=001DC0h -> "DOSDATACODE" 255 <2> section DOSDATACODE ; in DOSDATA 256 <2> 257 <2> ;CASE MAPPER ROUTINE FOR 80H-FFH character range, DOS 3.3 258 <2> ; ENTRY: AL = Character to map 259 <2> ; EXIT: AL = The converted character 260 <2> ; Alters no registers except AL and flags. 261 <2> ; The routine should do nothing to chars below 80H. 262 <2> ; 263 <2> ; Example: 264 <2> 265 <2> Procedure MAP_CASE,FAR 266 <2> ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING 267 <2> pop ax 268 <2> CMP AL,80H 269 <2> JAE Map1 ;Map no chars below 80H ever 270 <2> RET 271 <2> Map1: 272 <2> SUB AL,80H ;Turn into index value 273 <2> PUSH DS 274 <2> PUSH BX 275 <2> MOV BX,OFFSET UCASE_TAB + 2 wrt DOSGROUP ; access with cs 276 <2> FINISH: 277 <2> PUSH CS ;Move to DS 278 <2> POP DS 279 <2> assume ds:DOSGROUP 280 <2> xlatb ;Get upper case character 281 <2> POP BX 282 <2> POP DS 283 <2> assume ds:nothing 284 <2> L_RET: RET 285 <2> EndProc MAP_CASE 286 <2> 287 <2> ;SUBTTL EDIT FUNCTION ASSIGNMENTS AND HEADERS 288 <2> ;PAGE 289 <2> ; The following two tables implement the current buffered input editing 290 <2> ; routines. The tables are pairwise associated in reverse order for ease 291 <2> ; in indexing. That is; The first entry in ESCTAB corresponds to the last 292 <2> ; entry in ESCFUNC, and the last entry in ESCTAB to the first entry in ESCFUNC. 293 <2> 294 <2> %endif ; DONOBITS 295 <2> 296 <2> === Switch to base=001DC0h -> "TABLE" 297 <2> section TABLE ; in DOSDATA 298 <2> PUBLIC CANCHAR 0 00000FEC ?? CANCHAR DB CANCEL ;Cancel line character 300 <2> PUBLIC ESCCHAR 0 00000FED ?? ESCCHAR DB ESCCH ;Lead-in character for escape sequences 302 <2> === Switch to base=003490h -> "DOSCODETABLE" 303 <2> section DOSCODETABLE 304 <2> %IFN Rainbow 305 <2> ESCTAB LABEL BYTE 306 <2> %IFN IBM 307 <2> %IF WANG 308 <2> DB 0C0h ; ^Z inserter 309 <2> DB 0C1H ; Copy one char 310 <2> DB 0C1H ; Copy one char 311 <2> DB 0C7H ; Skip one char 312 <2> DB 08AH ; Copy to char 313 <2> DB 088H ; Skip to char 314 <2> DB 09AH ; Copy line 315 <2> DB 0CBH ; Kill line (no change in template) 316 <2> DB 08BH ; Reedit line (new template) 317 <2> DB 0C3H ; Backspace 318 <2> DB 0C6H ; Enter insert mode 319 <2> DB 0D6H ; Exit insert mode 320 <2> DB 0C6H ; Escape character 321 <2> DB 0C6H ; End of table 322 <2> %ELSE 323 <2> ; VT52 equivalences 324 <2> DB "Z" ; ^Z inserter 325 <2> DB "S" ; F1 Copy one char 326 <2> DB "S" ; F1 Copy one char 327 <2> DB "V" ; F4 Skip one char 328 <2> DB "T" ; F2 Copy to char 329 <2> DB "W" ; F5 Skip to char 330 <2> DB "U" ; F3 Copy line 331 <2> DB "E" ; SHIFT ERASE Kill line (no change in template) 332 <2> DB "J" ; ERASE Reedit line (new template) 333 <2> DB "D" ; LEFT Backspace 334 <2> DB "P" ; BLUE Enter insert mode 335 <2> DB "Q" ; RED Exit insert mode 336 <2> DB "R" ; GRAY Escape character 337 <2> DB "R" ; End of table 338 <2> %ENDIF 339 <2> %ENDIF 340 <2> %IF IBM 0 00000017 ?? DB 64 ; Ctrl-Z - F6 0 00000018 ?? DB 77 ; Copy one char - --> 0 00000019 ?? DB 59 ; Copy one char - F1 0 0000001A ?? DB 83 ; Skip one char - DEL 0 0000001B ?? DB 60 ; Copy to char - F2 0 0000001C ?? DB 62 ; Skip to char - F4 0 0000001D ?? DB 61 ; Copy line - F3 0 0000001E ?? DB 61 ; Kill line (no change to template ) - Not used 0 0000001F ?? DB 63 ; Reedit line (new template) - F5 0 00000020 ?? DB 75 ; Backspace - <-- 0 00000021 ?? DB 82 ; Enter insert mode - INS (toggle) 0 00000022 ?? DB 82 ; Exit insert mode - INS (toggle) 0 00000023 ?? DB 65 ; Escape character - F7 0 00000024 ?? DB 65 ; End of table 355 <2> %ENDIF 356 <2> ESCEND LABEL BYTE 357 <2> ESCTABLEN EQU ESCEND-ESCTAB 358 <2> === Switch to base=001DC0h -> "DOSDATATABLE" 359 <2> section DOSDATATABLE ; in DOSDATA 360 <2> 361 <2> align 2, db 0 362 <2> ESCFUNC LABEL WORD 0 000016B6 ???? short_addr GETCH ; Ignore the escape sequence 0 000016B8 ???? short_addr TWOESC 0 000016BA ???? short_addr EXITINS 0 000016BC ???? short_addr ENTERINS 0 000016BE ???? short_addr BACKSP 0 000016C0 ???? short_addr REEDIT 0 000016C2 ???? short_addr KILNEW 0 000016C4 ???? short_addr COPYLIN 0 000016C6 ???? short_addr SKIPSTR 0 000016C8 ???? short_addr COPYSTR 0 000016CA ???? short_addr SKIPONE 0 000016CC ???? short_addr COPYONE 0 000016CE ???? short_addr COPYONE 0 000016D0 ???? short_addr CTRLZ 377 <2> %ENDIF 378 <2> 379 <2> %ifndef DONOBITS 380 <2> === Switch to base=003490h -> "DOSCODECODE" 381 <2> section DOSCODECODE ; TABLE ENDS 382 <2> 383 <2> ; 384 <2> ; OEMFunction key is expected to process a single function 385 <2> ; key input from a device and dispatch to the proper 386 <2> ; routines leaving all registers UNTOUCHED. 387 <2> ; 388 <2> ; Inputs: CS, SS are DOSGROUP 389 <2> ; Outputs: None. This function is expected to JMP to one of 390 <2> ; the following labels: 391 <2> ; 392 <2> ; GetCh - ignore the sequence 393 <2> ; TwoEsc - insert an ESCChar in the buffer 394 <2> ; ExitIns - toggle insert mode 395 <2> ; EnterIns - toggle insert mode 396 <2> ; BackSp - move backwards one space 397 <2> ; ReEdit - reedit the line with a new template 398 <2> ; KilNew - discard the current line and start from scratch 399 <2> ; CopyLin - copy the rest of the template into the line 400 <2> ; SkipStr - read the next character and skip to it in the template 401 <2> ; CopyStr - read next char and copy from template to line until char 402 <2> ; SkipOne - advance position in template one character 403 <2> ; CopyOne - copy next character in template into line 404 <2> ; CtrlZ - place a ^Z into the template 405 <2> ; Registers that are allowed to be modified by this function are: 406 <2> ; AX, CX, BP 407 <2> 408 <2> Procedure OEMFunctionKey,NEAR 409 <2> ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP 410 <2> %IF DBCS ;AN000; 411 <2> extrn intCNE0:near ;AN000; 2/17/KK 412 <2> CALL intCNE0 ;AN000; 2/17/KK 413 <2> %ELSE ;AN000; 414 <2> invoke D_std_con_input_no_echo ; Get the second byte of the sequence 415 <2> %ENDIF ;AN000; 416 <2> %IFN Rainbow 417 <2> MOV CL,ESCTABLEN ; length of table for scan 418 <2> push es 419 <2> PUSH DI ; save DI (cannot change it!) 420 <2> push cs 421 <2> pop es 422 <2> assume es:DOSCODEGROUP 423 <2> MOV DI,OFFSET ESCTAB ; offset of second byte table ; access with es 424 <2> REPNE SCASB ; Look it up in the table 425 <2> POP DI ; restore DI 426 <2> pop es 427 <2> assume es:nothing 428 <2> SHL CX,1 ; convert byte offset to word 429 <2> MOV BP,CX ; move to indexable register 430 <2> JMP [BP+OFFSET ESCFUNC wrt DOSGROUP] ; Go to the right routine 431 <2> %ENDIF 432 <2> %IF Rainbow 433 <2> 434 <2> TransferIf MACRO value,address 435 <2> local a 436 <2> CMP AL,[value] 437 <2> JNZ a 438 <2> transfer address 439 <2> a: 440 <2> ENDM 441 <2> 442 <2> CMP AL,'[' ; is it second lead char 443 <2> JZ EatParm ; yes, go walk tree 444 <2> GoGetCh: 445 <2> transfer GetCh ; no, ignore sequence 446 <2> EatParm: 447 <2> invoke D_std_con_input_no_echo ; get argument 448 <2> CMP AL,'A' ; is it alphabetic arg? 449 <2> JAE EatAlpha ; yes, go snarf one up 450 <2> XOR BP,BP ; init digit counter 451 <2> JMP InDigit ; jump into internal eat digit routine 452 <2> EatNum: 453 <2> invoke D_std_con_input_no_echo ; get next digit 454 <2> InDigit: 455 <2> CMP AL,'9' ; still a digit? 456 <2> JA CheckNumEnd ; no, go check for end char 457 <2> SUB AL,'0' ; turn into potential digit 458 <2> JL GoGetCh ; oops, not a digit, ignore 459 <2> MOV CX,BP ; save BP for 10 multiply 460 <2> CBW ; make AL into AX 461 <2> SHL BP,1 ; 2*BP 462 <2> SHL BP,1 ; 4*BP 463 <2> ADD BP,CX ; 5*BP 464 <2> SHL BP,1 ; 10*BP 465 <2> ADD BP,AX ; 10*BP + digit 466 <2> JMP EatNum ; continue with number 467 <2> CheckNumEnd: 468 <2> CMP AL,7Eh ; is it end char ~ 469 <2> JNZ GoGetCh ; nope, ignore key sequence 470 <2> MOV AX,BP 471 <2> transferIf 1,SkipStr ; FIND key 472 <2> transferIf 2,EnterIns ; INSERT HERE key 473 <2> transferIf 3,SkipOne ; REMOVE 474 <2> transferIf 4,CopyStr ; SELECT 475 <2> transferIf 17,TwoEsc ; INTERRUPT 476 <2> transferIf 18,ReEdit ; RESUME 477 <2> transferIf 19,KilNew ; CANCEL 478 <2> transferIf 21,CtrlZ ; EXIT 479 <2> transferIf 29,CopyLin ; DO 480 <2> JMP GoGetCh 481 <2> EatAlpha: 482 <2> CMP AL,'O' ; is it O? 483 <2> JA GoGetCh ; no, after assume bogus 484 <2> JZ EatPQRS ; eat the rest of the bogus key 485 <2> transferIf 'C',CopyOne ; RIGHT 486 <2> transferIf 'D',BackSp ; LEFT 487 <2> JMP GoGetCh 488 <2> EatPQRS: 489 <2> invoke D_std_con_input_no_echo ; eat char after O 490 <2> JMP GoGetCh 491 <2> %ENDIF 492 <2> 493 <2> EndProc OEMFunctionKey 494 <2> 495 <2> ; (no prior section) ; DOSCODECODE ENDS 496 <2> 497 <2> %endif ; DONOBITS 498 <2> 499 <2> END 20 <1> ;=== Pop trace listing source