]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/MISC2.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / MISC2.ASM
1 ; SCCSID = @(#)misc2.asm 1.1 85/04/10
2 TITLE MISC2 - Miscellanious routines for MS-DOS
3 NAME MISC2
4 ;
5 ; Miscellaneous useful routines
6 ;
7 ; StrCpy
8 ; StrCmp
9 ; Ucase
10 ; StrLen
11 ; DStrLen
12 ; Idle
13 ; TableDispatch
14 ; FastInit ; DOS 4.0
15 ; FastRet ; DOS 4.0
16 ; NLS_OPEN ; DOS 4.0
17 ; NLS_LSEEK ; DOS 4.0
18 ; Fake_User_Stack ; DOS 4.0
19 ; GetDevList ; DOS 4.0
20 ; NLS_IOCTL ; DOS 4.0
21 ; NLS_GETEXT ; DOS 4.0
22 ; MSG_RETRIEVAL ; DOS 4.0
23 ; Fake_Version ; DOS 4.0
24 ;
25 ; Revision history:
26 ;
27 ; Created: ARR 30 March 1983
28 ;
29 ; A000 version 4.0 Jan. 1988
30 ; A001 DCR 486 - Share installation for >32mb drives
31 ; A006 DCR 503 - fake version number for IBMCACHE
32
33 .xlist
34 ;
35 ; get the appropriate segment definitions
36 ;
37 include dosseg.asm
38
39 CODE SEGMENT BYTE PUBLIC 'CODE'
40 ASSUME SS:DOSGROUP,CS:DOSGROUP
41
42 .xcref
43 include dossym.inc
44 include fastseek.inc ;AN000;
45 include fastxxxx.inc ;AN000;
46 .cref
47 .list
48
49 i_need THISCDS,DWORD
50 I_Need RetryLoop,WORD
51 I_need fSharing,BYTE ; TRUE => server-issued call
52 I_need FastTable,BYTE ;AN000;
53 I_need FastFlg,BYTE ;AN000;
54 I_need User_SP_2F,WORD ;AN000;
55 I_need User_SP,WORD ;AN000;
56 I_need User_SS,WORD ;AN000;
57 I_need SysInitTable,BYTE ;AN000;
58 I_need EXTERR,WORD ;AN000;
59 I_need MSG_EXTERROR,DWORD ;AN000;
60 I_need fshare,byte ;AN001;
61 I_need Special_version,WORD ;AN006;
62 if debug
63 I_need BugLev,WORD
64 I_need BugTyp,WORD
65 include bugtyp.asm
66 endif
67
68 Break <STRCMP - compare two ASCIZ strings DS:SI to ES:DI>
69
70 ;
71 ; Strcmp - compare ASCIZ DS:SI to ES:DI. Case INSENSITIVE. '/' = '\'
72 ; Strings of different lengths don't match.
73 ; Inputs: DS:SI - pointer to source string ES:DI - pointer to dest string
74 ; Outputs: Z if strings same, NZ if different
75 ; Registers modified: NONE
76
77 Procedure StrCmp,NEAR
78 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING
79 SaveReg <SI,DI,AX>
80 Cmplp:
81 LODSB
82 IF DBCS ;AN000;
83 invoke testkanj ;AN000;; 2/13/KK
84 jz notkanj1 ;AN000;; 2/13/KK
85 dec si ;AN000;; Do source again 2/13/KK
86 cmpsb ;AN000;; First byte 2/13/KK
87 JNZ PopRet ;AN000;; Strings dif 2/13/KK
88 cmpsb ;AN000;; Second byte of kanji char 2/13/KK
89 JNZ PopRet ;AN000;; Strings dif 2/13/KK
90 mov al,byte ptr [SI-1] ;AN000;; Need last byte in AL 2/13/KK
91 jmp short Tend ;AN000;
92 notkanj1: ;AN000;; 2/13/KK
93 ENDIF ;AN000;
94 CALL uCase ; convert to upper case
95 Invoke PathChrCmp ; convert / to \
96 MOV AH,AL
97 MOV AL,ES:[DI]
98 INC DI
99 CALL uCase ; convert to upper case
100 Invoke PathChrCmp ; convert / to \
101 CMP AH,AL
102 JNZ PopRet ; Strings dif
103 Tend:
104 OR AL,AL
105 JNZ Cmplp ; More string
106 PopRet:
107 RestoreReg <AX,DI,SI>
108 return
109 EndProc StrCmp
110
111 Break <STRCPY - copy ASCIZ string from DS:SI to ES:DI>
112
113 ;
114 ; Strcpy - copy an ASCIZ string from DS:SI to ES:DI and make uppercase
115 ; FStrcpy - copy an ASCIZ string from DS:SI to ES:DI. no modification of
116 ; characters.
117 ;
118 ; Inputs: DS:SI - pointer to source string
119 ; ES:DI - pointer to destination string
120 ; Outputs: ES:DI point byte after nul byte at end of dest string
121 ; DS:SI point byte after nul byte at end of source string
122 ; Registers modified: SI,DI
123
124 Procedure StrCpy,NEAR
125 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING
126 SaveReg <AX>
127 CPYLoop:
128 LODSB
129 IF DBCS ;AN000;
130 invoke testkanj ;AN000;; 2/13/KK
131 jz notkanj2 ;AN000;; 2/13/KK
132 STOSB ;AN000;; 2/13/KK
133 LODSB ;AN000;; 2/13/KK
134 STOSB ;AN000;; 2/13/KK
135 jmp short CPYLoop ;AN000;; 3/31/KK
136
137 notkanj2: ;AN000;; 2/13/KK
138 ENDIF ;AN000;
139 CALL uCase ; convert to upper case
140 Invoke PathChrCmp ; convert / to \
141 STOSB
142 Tend2:
143 OR AL,AL
144 JNZ CPYLoop
145 RestoreReg <AX>
146 return
147 EndProc StrCpy
148
149 Procedure FStrCpy,NEAR
150 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING
151 SaveReg <AX>
152 FCPYLoop:
153 LODSB
154 STOSB
155 OR AL,AL
156 JNZ FCPYLoop
157 RestoreReg <AX>
158 return
159 EndProc FStrCpy
160
161 ;
162 ; Upper case the letter in AL. Most chars are non lowercase.
163 ;
164 Procedure uCase,NEAR
165 ; CMP AL,'a'
166 ; JAE Maybe
167 ; return
168 ;Maybe:
169 ; CMP AL,'z'
170 ; JA CaseRet
171 ; ADD AL,'A'-'a'
172 ;CaseRet:
173 ;;; 10/31/86 let's do file upper case for all DOS file names
174 invoke GetLet2
175 ;;; 10/31/86 let's do file upper case for all DOS file names
176 return
177 EndProc uCase
178
179 Break <StrLen - compute length of string ES:DI>
180
181 ;
182 ; StrLen - Compute length of string ES:DI
183 ; Inputs: ES:DI - pointer to string
184 ; Outputs: CX is size of string INCLUDING the NUL
185 ; Registers modified: CX
186
187 Procedure StrLen,NEAR
188 ASSUME CS:DOSGroup,SS:DOSGroup,DS:NOTHING,ES:NOTHING
189 PUSH DI
190 PUSH AX
191 MOV CX,-1
192 XOR AL,AL
193 REPNE SCASB
194 NOT CX
195 POP AX
196 POP DI
197 return
198 EndProc StrLen
199
200 ;
201 ; DStrLen - Compute length of string DS:SI
202 ; Inputs: DS:SI - pointer to string
203 ; Outputs: CX is size of string INCLUDING the NUL
204 ; Registers modified: CX
205 Procedure DStrLen,NEAR
206 CALL XCHGP
207 CALL StrLen
208 CALL XCHGP
209 return
210 EndProc DStrLen
211
212 Break <XCHGP - exchange source and destination pointers>
213
214 Procedure XCHGP,NEAR
215 SaveReg <DS,ES>
216 RestoreReg <DS,ES>
217 XCHG SI,DI
218 return
219 EndProc XCHGP
220
221 Break <Idle - wait for a specified amount of time>
222
223 ;
224 ; Idle - when retrying an operation due to a lock/sharing violation, we spin
225 ; until RetryLoop is exhausted.
226 ;
227 ; Inputs: RetryLoop is the number of times we spin
228 ; Outputs: Wait
229 ; Registers modified: none
230
231 Procedure Idle,NEAR
232 ASSUME CS:DOSGroup,SS:DOSGROUP,DS:NOTHING,ES:NOTHING
233 TEST fSharing,-1
234 retnz
235 SaveReg <CX>
236 MOV CX,RetryLoop
237 JCXZ Idle3
238 Idle1: PUSH CX
239 XOR CX,CX
240 Idle2: LOOP Idle2
241 POP CX
242 LOOP Idle1
243 Idle3: RestoreReg <CX>
244 return
245 EndProc Idle
246
247 Break <TableDispatch - dispatch to a table>
248
249 ;
250 ; TableDispatch - given a table and an index, jmp to the approptiate
251 ; routine. Preserve all input registers to the routine.
252 ;
253 ; Inputs: Push return address
254 ; Push Table address
255 ; Push index (byte)
256 ; Outputs: appropriate routine gets jumped to.
257 ; return indicates invalid index
258 ; Registers modified: none.
259
260 TableFrame STRUC
261 OldBP DW ?
262 OldRet DW ?
263 Index DB ?
264 Pad DB ?
265 Tab DW ?
266 NewRet DW ?
267 TableFrame ENDS
268
269 procedure TableDispatch,NEAR
270 ASSUME CS:DOSGroup,DS:NOTHING,SS:NOTHING,SS:NOTHING
271 PUSH BP
272 MOV BP,SP
273 PUSH BX ; save BX
274 MOV BX,[BP.Tab] ; get pointer to table
275 MOV BL,CS:[BX] ; maximum index
276 CMP [BP.Index],BL ; table error?
277 JAE TableError ; yes
278 MOV BL,[BP.Index] ; get desired table index
279 XOR BH,BH ; convert to word
280 SHL BX,1 ; convert to word pointer
281 INC BX ; point past first length byte
282 ADD BX,[BP.Tab] ; get real offset
283 MOV BX,CS:[BX] ; get contents of table entry
284 MOV [BP.Tab],BX ; put table entry into return address
285 POP BX ; restore BX
286 POP BP ; restore BP
287 ADD SP,4 ; clean off Index and our return addr
288 return ; do operation
289 TableError:
290 POP BX ; restore BX
291 POP BP ; restore BP
292 RET 6 ; clean off Index, Table and RetAddr
293 EndProc TableDispatch
294
295 Break <TestNet - determine if a CDS is for the network>
296
297 ;
298 ; TestNet - examine CDS pointed to by ThisCDS and see if it indicates a
299 ; network CDS. This will handle NULL cds also.
300 ;
301 ; Inputs: ThisCDS points to CDS or NULL
302 ; Outputs: ES:DI = ThisCDS
303 ; carry Set => network
304 ; carry Clear => local
305 ; Registers modified: none.
306
307 Procedure TestNet,NEAR
308 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
309 LES DI,ThisCDS
310 CMP DI,-1
311 JZ CMCRet ; UNC? carry is clear
312 TEST ES:[DI].curdir_flags,curdir_isnet
313 JNZ CMCret ; jump has carry clear
314 return ; carry is clear
315 CMCRet: CMC
316 return
317
318 EndProc TestNet
319
320 Break <IsSFTNet - see if an sft is for the network>
321
322 ;
323 ; IsSFTNet - examine SF pointed to by ES:DI and see if it indicates a
324 ; network file.
325 ;
326 ; Inputs: ES:DI point to SFT
327 ; Outputs: Zero set if not network sft
328 ; zero reset otherwise
329 ; Carry CLEAR!!!
330 ; Registers modified: none.
331
332 Procedure IsSFTNet,NEAR
333 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
334 TEST ES:[DI].sf_flags,sf_isnet
335 return
336 EndProc IsSFTNet
337
338 Break <FastInit - Initialize FastTable entries >
339
340 ; DOS 4.00 2/9/87
341 ; FastInit - initialize the FASTXXX routine entry
342 ; in the FastTable
343 ;
344 ; Inputs: BX = FASTXXX ID ( 1=fastopen, 2=fastseek,,,,)
345 ; DS:SI = address of FASTXXX routine entry
346 ; SI = -1 for query only
347 ; Outputs: Carry flag clear, if success
348 ; Carry flag set, if failure
349 ;
350 ;
351
352 Procedure FastInit,NEAR ;AN000;
353 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000;
354
355 MOV DI,OFFSET DOSGROUP:FastTable + 2 ;AN000;FO. points to fastxxx entry
356 DEC BX ;AN000;FO.;; decrement index
357 MOV DX,BX ;AN000;FO.;; save bx
358 SHL BX,1 ;AN000;FO.;; times 4 , each entry is DWORD
359 SHL BX,1 ;AN000;FO.
360 ADD DI,BX ;AN000;FO. index to the entry
361 MOV AX,WORD PTR CS:[DI+2] ;AN000;FO. get entry segment
362 fcheck: ;AN000;
363 MOV CX,CS ;AN000;FO.;; get DOS segment
364 CMP AX,CX ;AN000;FO.;; first time installed ?
365 JZ ok_install ;AN000;FO.;; yes
366 OR AX,AX ;AN000;FO.;
367 JZ ok_install ;AN000;FO.;
368 STC ;AN000;FO.;; already installed !
369 JMP SHORT FSret ;AN000;FO. set carry
370 ok_install: ;AN000;
371 CMP SI,-1 ;AN000;FO.; Query only ?
372 JZ FSret ;AN000;FO.; yes
373 MOV CX,DS ;AN000;FO.; get FASTXXX entry segment
374 MOV CX,DS ;AN000;FO.;; get FASTXXX entry segment
375 MOV WORD PTR CS:[DI+2],CX ;AN000;FO.;; initialize routine entry
376 MOV WORD PTR CS:[DI],SI ;AN000;FO.;; initialize routine offset
377 MOV DI,OFFSET DOSGROUP:FastFlg ;AN000;FO.; get addr of FASTXXX flags
378 ADD DI,DX ;AN000;FO.; index to a FASTXXX flag
379 OR byte ptr CS:[DI],Fast_yes ;AN000;FO.; indicate installed
380
381 FSret: ;AN000;
382 return ;AN000;FO.
383 EndProc FastInit ;AN000;FO.
384
385 Break <FastRet - initial routine in FastOpenTable >
386
387 ; DOS 3.3 6/10/86
388 ; FastRet - indicate FASTXXXX not in memory
389 ;
390 ; Inputs: None
391 ; Outputs: AX = -1 and carry flag set
392 ;
393 ; Registers modified: none.
394
395 Procedure FastRet,FAR
396 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
397 MOV AX,-1
398 STC
399 RET
400 EndProc FastRet
401
402 Break <NLS_OPEN - do $open for NLSFUNC >
403
404 ; DOS 3.3 6/10/86
405 ; NLS_OPEN - call $OPEN for NLSFUNC
406 ;
407 ; Inputs: Same input as $OPEN except CL = mode
408 ; Outputs: same output as $OPEN
409 ;
410
411 Procedure NLS_OPEN,NEAR
412 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
413
414 ; MOV BL,[CPSWFLAG] ; disable code page matching logic
415 ; MOV [CPSWFLAG],0
416 ; PUSH BX ; save current state
417
418 MOV AL,CL ; set up correct interface for $OPEN
419 invoke $OPEN
420
421 ; POP BX ; restore current state
422 ; MOV [CPSWFLAG],BL
423 RET
424 EndProc NLS_OPEN
425
426 Break <NLS_LSEEK - do $LSEEK for NLSFUNC >
427
428 ; DOS 3.3 6/10/86
429 ; NLS_LSEEK - call $LSEEK for NLSFUNC
430 ;
431 ; Inputs: BP = open mode
432 ; Outputs: same output as $LSEEK
433 ;
434
435 Procedure NLS_LSEEK,NEAR
436 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
437
438 PUSH [user_SP] ; save user stack
439 PUSH [user_SS]
440 CALL Fake_User_Stack
441 MOV AX,BP ; set up correct interface for $LSEEK
442 invoke $LSEEK
443 POP [user_SS] ; restore user stack
444 POP [user_SP]
445 RET
446 EndProc NLS_LSEEK
447
448
449 Break <Fake_User_Stack - save uesr stack >
450
451
452 ; DOS 3.3 6/10/86
453 ; Fake_User_Stack - save user stack pointer
454 ;
455
456 Procedure Fake_User_Stack,NEAR
457 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
458
459 MOV AX,[User_SP_2F] ; replace with INT 2F stack
460 MOV [user_SP],AX
461
462 MOV AX,CS
463 MOV [user_SS],AX ; DOSGROUP
464
465 RET
466 EndProc Fake_User_Stack
467
468 ;
469 Break <GetDevList - get device header list pointer>
470
471
472 ; DOS 3.3 7/25/86
473 ; GetDevList - get device header list pointer
474 ;
475 ; Output: AX:BX points to the device header list
476
477 Procedure GetDevList,NEAR
478 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
479
480 MOV SI,OFFSET DOSGROUP:SysInitTable
481 LDS SI,CS:[SI.SYSI_InitVars]
482
483 MOV AX,WORD PTR DS:[SI.SYSI_DEV]
484 MOV BX,WORD PTR DS:[SI.SYSI_DEV+2]
485
486 RET
487 EndProc GetDevList
488
489 Break <NLS_IOCTL - do $IOCTL for NLSFUNC >
490
491 ; DOS 3.3 7/25/86
492 ; NLS_IOCTL - call $IOCTL for NLSFUNC
493 ;
494 ; Inputs: BP = function code 0CH
495 ; Outputs: same output as generic $IOCTL
496 ;
497
498 Procedure NLS_IOCTL,NEAR
499 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
500
501 PUSH [user_SP] ; save user stack
502 PUSH [user_SS]
503 CALL Fake_User_Stack
504 MOV AX,BP ; set up correct interface for $LSEEK
505 invoke $IOCTL
506 POP [user_SS] ; restore user stack
507 POP [user_SP]
508 RET
509 EndProc NLS_IOCTL
510
511 Break <NLS_GETEXT- get extended error for NLSFUNC>
512
513 ; DOS 3.3 7/25/86
514 ; NLS_GETEXT -
515 ;
516 ; Inputs: none
517 ; Outputs: AX = extended error
518 ;
519
520 Procedure NLS_GETEXT,NEAR
521 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
522
523 MOV AX,CS:[EXTERR] ; return extended error
524 RET
525 EndProc NLS_GETEXT
526
527 Break <MSG_RETRIEVAL- get beginning addr of system and parser messages>
528
529 ; DOS 4.00
530 ;
531 ; Inputs: DL=0 get extended error message addr
532 ; =1 set extended error message addr
533 ; =2 get parser error message addr
534 ; =3 set parser error message addr
535 ; =4 get critical error message addr
536 ; =5 set critical error message addr
537 ; =6 get file system error message addr
538 ; =7 set file system error message addr
539 ; =8 get address for code reduction
540 ; =9 set address for code reduction
541 ; Function: get/set message address
542 ; Outputs: ES:DI points to addr when get
543 ;
544
545 Procedure MSG_RETRIEVAL,NEAR ;AN000;
546 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000;
547
548 PUSH AX ;AN000;;MS. save regs
549 PUSH SI ;AN000;;MS. save regs
550 MOV AX,DX ;AN000;;MS.
551 MOV SI,OFFSET DOSGROUP:MSG_EXTERROR ;AN000;;MS.
552 TEST AL,1 ;AN000;;MS. get ?
553 JZ toget ;AN000;;MS. yes
554 DEC AL ;AN000;;MS.
555 toget: ;AN000;
556 SHL AL,1 ;AN000;;MS. times 2
557 XOR AH,AH ;AN000;;MS.
558 ADD SI,AX ;AN000;;MS. position to the entry
559 TEST DL,1 ;AN000;;MS. get ?
560 JZ getget ;AN000;;MS. yes
561 MOV WORD PTR CS:[SI],DI ;AN000;;MS. set MSG
562 MOV WORD PTR CS:[SI+2],ES ;AN000;;MS. address to ES:DI
563 JMP SHORT MSGret ;AN000;;MS. exit
564 getget: ;AN000;
565 LES DI,DWORD PTR CS:[SI] ;AN000;;MS. get msg addr
566 MSGret: ;AN000;
567 POP SI ;AN000;;MS.
568 POP AX ;AN000;;MS.
569 return ;AN000;;MS. exit
570
571 EndProc MSG_RETRIEVAL ;AN000;
572
573
574 Break <Fake_version - set/reset version flag>
575
576 ;
577 ; Inputs: DL=0 current version number
578 ; <>0 special version number
579 ; Function: set special version number
580 ; Outputs: version number is changed
581 ;
582
583 Procedure Fake_version,NEAR ;AN000;
584 ASSUME CS:DOSGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN000;
585
586 MOV [Special_version],DX ;AN006;MS.
587 return ;AN006;;MS. exit
588
589 EndProc Fake_version ;AN006;;MS.
590
591
592
593 CODE ENDS
594 END