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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / NLSFUNC / NLSFUNC.ASM
1
2 PAGE ,132 ;\ f
3 TITLE NLSFUNC - GET/SET CP & COUNTRY INFO CHCP SUPPORT
4 ;**************************************************************************
5 ;This is the NLSFUNC int2f command that supports the INT21h functions
6 ;Get_Extended Country Information and the Set_codepage...
7 ;NLSFUNC will read the COUNTRY.SYS information from disk , store the
8 ;data in a buffer , then move the information into a buffer
9 ;area specified by DOS.
10 ;d:NLSFUNC {path}
11 ; *
12 ;CHECKINSTALL: *
13 ;CheckRequest proc *
14 ; If installed previously *
15 ; report back error already installed and exit *
16 ; otherwise goto install *
17 ;Checkrequest endp *
18 ;*************************************************************************
19 ; NEW CODE *
20 ;*************************************************************************
21 subttl get extended country data
22 page
23 ;
24 ;***************************************
25 ;* Process_Path Procedure *
26 ;***************************************
27 ;* CALL SYSLOADMSG *
28 ;* Do DOS Version check *
29 ;* If ne X.X then (carry set) *
30 ;* CALL SYSDISPLAY_MSG *
31 ;* DISPLAY_MSG(Message number 001) *
32 ;* (001 - Incorrect DOS Version) *
33 ;* (Class 3 - Utility Msg) *
34 ;* exit *
35 ;* else *
36 ;* Establish addressability *
37 ;* to command line parms (DS:SI) *
38 ;* Establish addressability to PARM *
39 ;* control block (ES:DI) *
40 ;* *
41 ;* Call SYSPARSE for filename *
42 ;* GET Parse Block results *
43 ;* IF PARSE_ERROR *
44 ;* CALL SYSDISPLAY_MSG (Class 2)*
45 ;* DISPLAY_MSG = PARSE_NUM *
46 ;* ELSE *
47 ;* SUCCESSFUL_PARSE (0 or -1) *
48 ;* ENDIFELSE *
49 ;* GET_PARSE_RESULTS Path_Spec *
50 ;* IF No path exist then *
51 ;* assume current directory *
52 ;* assume default filename *
53 ;* ENDIF *
54 ;* IF No Drive exist then *
55 ;* Use Current Drive *
56 ;* ENDIF *
57 ;* IF No filename exist then *
58 ;* assume default filename *
59 ;* and concatenate with drive *
60 ;* ENDIF *
61 ;* CHECK_PATH *
62 ;* IF PATH EXIST THAN *
63 ;* INSTALL_NLS (NLS_RESCODE) *
64 ;* ENDIF *
65 ;* ELSE NOT PATH_EXIST THAN *
66 ;* GET_PARSE_RESULTS (Class 3) *
67 ;* PASS_TO_MSGTXT (Message 003) *
68 ;* (File not found %1) *
69 ;* ERR_CODE SET TO 2 *
70 ;* EXIT *
71 ;* ENDIFELSE *
72 ;* *
73 ;* INSTALL_NLS *
74 ;* CHECK INSTALL FLAG *
75 ;* IF INSTALLED *
76 ;* (Class 3) *
77 ;* PASS_TO_MGSTXT (Msg 002) *
78 ;* %1 already installed *
79 ;* ELSE *
80 ;* HOOK IN CODE *
81 ;* TERMINATE & STAY RESIDENT *
82 ;* ENDIFELSE *
83 ;* *
84 ;* *
85 ;* EXIT *
86 ;* CHECK FOR ERRORCODE *
87 ;* exit to DOS *
88 ;***************************************
89 ;
90 ;INSTALL:
91 ; Get the current 2f handler in the chain
92 ; make it the next install my handler in the
93 ; beginning of the the chain using get interrupt (25)
94 ; and set interrupt (35); Once in the chain
95 ; terminate and stay resident.
96 ;
97 ;DOS NEEDS ME.......
98 ;
99 ;Install Dos Interface Logic
100 ; Dos issues Call Install
101 ; Establish residency
102 ; If Mult Id is mine (* NLSFUNC*)
103 ; CheckInstall Status to see if installed or not
104 ; otherwise
105 ; jump to the next 2f handler
106 ;CheckInstall
107 ; If not installed returns
108 ; If installed program is executed (*NLSFUNC resident portion *)
109 ;*******************************************************************************
110 ;
111 ;Program Logic
112 ;
113 ; Check to make sure not reserved DOS number in the al
114 ;
115 ; Go establish which function is to be performed
116 ;
117 ;Sel_Func proc
118 ; mov FUNC_CODE,al
119 ; case
120 ; function code = 0
121 ; function code = 1
122 ; function code = 2
123 ; function code = 3
124 ; function code = 4
125 ; otherwise error_routine
126 ; return
127 ;Sel_Func endp
128
129
130 ;funcode0 proc
131 ;INSTALL NLSFUNC must be installed in mem
132 ; return 0FFh that I am installed
133 ;funcode0 endp
134
135 ;funcode1 proc
136 ; (* Means Set codepage and "select" device drivers*)
137 ; same at funcode 3 plus device drivers are invoked with the
138 ; specified code page.
139 ;funcode1 endp
140
141 ;funcode2 proc
142 ; (* Get_extended_country info issued by DOS not in buffer*)
143 ; BP = info_type
144 ; call trans_Cty_Data Proc
145 ; return
146 ;funcode2 endp
147
148 ;funcode3 proc
149 ; (* Means Set codepage *)
150 ; On entry DOS gives me the CODEP in BX & the CC in DX,SIZE in CX
151 ; Search for Country.sys file on disk
152 ; if file is found }BUFFER will exist in code 320 (can be altered)
153 ; the control buffer = 64 bytes of the buffer
154 ; the data buffer = 256 bytes of the buffer
155 ; call Trans_Cty_Data Proc
156 ; otherwise return an error flag
157 ; return
158 ;funcode3 endp
159
160
161 ;funcode4 proc
162 ; (* Get_extended_country info - old 38 call*)
163 ; set flag and same as funcode 2
164 ; data returned slightly Revised
165 ;funcode4 endp
166
167 ; ****************************
168 ; if selected is FUNCTION 1, 3
169 ; PassDOS_Data(*ES:DI*)
170 ; otherwise FUNCTION 2, 4
171 ; Get the INFO ID
172 ; Flag that it is function 2
173 ; PassUserData(*ES:DI*)
174 ; mov NO_ERRORS to ERROR_FLAG
175 ; ****************************
176 ;Trans_Cty_Data Proc
177 ; Open file(Dos call back 38)
178 ; Do an LSEEK to move CTY_INFO into NLSFUNC control buffer 39
179 ; Do an LSEEK to move tables into NLSFUNC data buffer 39
180 ; if R/W pointer ok on Disk
181 ; Read the file(Dos call back 38)
182 ; Check to see if it is FUNCTION 1 or FUNCTION 2
183 ; Flag if FUNCTION 2
184 ; if FUNCTION 2
185 ; Search for user specified INFO ID
186 ; until found or report back error to DOS & exit
187 ; if INFO ID is found
188 ; godo move the data and set the counter to zero (entry value)
189 ;
190 ;
191 ;
192 ;
193 ;MOVE_DATA: Manage transfer from disk to buffer
194 ; Check to see if entire entry can fit in to the data
195 ; buffer if not read the maximum allowed into buffer
196 ; Check to see what is left to read; read until no more
197 ; Search for appropriate field in the DOS INFO
198 ; if found move in info until complete
199 ; get the next entry until number of entries is 0
200 ; otherwise
201 ; report to DOS error and exit
202 ; loop back to read file until (all entries are Obtained) or (EOF)
203 ; Close file handle (Dos call back 40)
204 ; otherwise mov 05h to error_flag & jump to error_routine
205 ;
206 ; return
207 ;Trans ENDP
208 ;
209 ;
210 ;Error_routine proc
211 ; mov al,error_flag
212 ; return
213 ;error_routine endp
214 ;*******************************************************************************
215 ;**********************************INTRO****************************************
216 subttl Revision History
217 page
218 ;****************************** Revision History *************************** ;
219 ;
220 ; =A 7/29/86 RG PTM P64
221 ; Prevent overwrite of DOS monocase routine entry point during
222 ; transfer of SetCountryInfo.
223 ; For Get Ext Cty Info, put DOS monocase routine entry point into
224 ; user buffer.
225 ;
226 ; =B 7/29/86 RG PTM P67
227 ; Correct jump condition in ERROR_ROUTINE of NLSRES_CODE.
228 ; This prevents exit without COUNTRY.SYS file close.
229 ;
230 ; =C 7/30/86 RG PTM P85
231 ; Preserve ES register in NLSFUNC for IBMDOS.
232 ;
233 ; =D 7/31/86 RG PTM P86
234 ; Corrects information put into user buffer for Get Extended
235 ; Country Information.
236 ;
237 ; =E 7/31/85 RG DCR 18
238 ; CHCP support.
239 ;
240 ; =F 8/4/86 RG
241 ; Get Country Info - Revised info from Get Extended Country Info
242 ;
243 ; =G 8/5/86 RG
244 ; Correct carry set for good exit.
245 ;
246 ; =H 8/5/86 RG
247 ; Start extended info at length instead of signature.
248 ;
249 ; =FC 8/14/86 FChen
250 ; Insert code for control buff management and actual length retunred
251 ;
252 ; =I 8/20/86 RG
253 ; Improve path parameter parsing.
254 ;
255 ; =J 8/22/86 RG
256 ; Change error codes
257 ;
258 ; =K 8/28/86 RG
259 ; 65 call-get ext cty info put final csize (# bytes returned)
260 ; in cx on iret ;
261 ;
262 ; =L 11/7/86 RG
263 ; Set error to INVALID DATA (13) on no cp/cty match.
264 ;
265 ; =M 05/20/87 CNS
266 ; Additional re-design for structured code using STRUC
267 ; PARSER implementation
268 ; Message Retriever implementation
269 ; DBCS Support for Environmental Vector recognition (Walk Devices& IOCTL call)
270 ; Enable the Interrupt when NLSFUNC is loaded PTM ???
271 ;
272 ;AN001; P2685 NLSFUNC should not visit the same device repeatedly. 01/15/88 J.K.
273 ;AN002; P3934 Bad write on sacred DOS area - segmentation incorrect 03/22/88 CNS
274 ;*******************************************************************************
275 subttl macros
276 page
277 PUSHALL macro reg1,reg2,reg3 ;used to save all
278 push reg1 ;registers needed
279 push reg2 ;for DOS interactions
280 push reg3
281 endm
282
283 POPALL macro reg1,reg2,reg3 ;used to restore all
284 pop reg3 ;for DOS interactions
285 pop reg2
286 pop reg1
287 endm
288
289 ;SHOWERR macro msg,len_msg
290 ; mov ah,40h
291 ; mov bx,2
292 ; lea dx,msg ;displays error msgs
293 ; mov cx,len_msg
294 ; int 21h
295 ; endm
296
297
298 EXTRN SYSPARSE:NEAR
299
300 subttl NLSFUNC data
301 page
302 NLS_DATA SEGMENT byte PUBLIC 'DATA'
303
304 ;Copyright 1988 Microsoft
305 ;***************************** MSG DATA ************************************
306 UTILITY db "NLSFUNC",0 ;AC000;
307 ;***************************** MSG DATA ************************************
308
309 .xlist
310 include copyrigh.inc ;AN000;
311 include struc.inc
312 include DOESMAC.INC
313 include MULT.INC
314 include sf.inc ;AN001;
315 include DOSCNTRY.INC
316 include DEVSYM.INC
317 include SYSMSG.INC ;AN000;
318 include FUNCDBCS.INC ;AN000;
319 include MSG2NLS.INC
320 include FUNCPARM.INC ;AN000;
321
322 MSG_UTILNAME <NLSFUNC> ;AN000;
323
324 .list
325 MULT_NLSFUNC equ 14h
326 INSTALLED equ 0ffh
327 ; nlsfunc function codes
328 CHG_CODEPAGE equ 1
329 GET_EXT_CTY_INFO equ 2
330 SET_CODEPAGE equ 3
331 GET_CTY_INFO equ 4
332
333 INVALID_FUNCTION equ 1 ;=J
334 INVALID_DATA equ 13 ;=L
335 ;FILE_NOT_FOUND equ 2 ;=J(=L no longer explicitly used)
336 ;TAB equ 9
337 ;CR equ 13
338 PAD_CHAR equ ' ' ;AN000;
339 BAD_INVOKE equ 65 ;=E
340 UPCASE_A equ 'A'
341 BUFFSIZE equ 512 ; ;AC000;REDUCTION OF ORIGINAL (128 BYTES) TO STORE
342 LOCATE_INFOTYPE equ 18 ;THE DEVICE LIST & THE OLD COUNTRY INFO
343 CTL_BUFF equ 256 ; ;AC000;
344 ID_TAG equ 8
345 DATA_BUFF_LENG equ (BUFFSIZE - CTL_BUFF)
346 MAXBUFF_FIT equ (BUFFSIZE - (CTL_BUFF + ID_TAG))
347 DATA_N_ID equ (CTL_BUFF + ID_TAG)
348 SETCTY_LENG equ 38
349 ;SPACE equ ' '
350 BACKSLASH equ '\'
351 PERIOD equ '.'
352 ;COLON equ ':'
353 ;
354 ;**************** NEW VARIABLE ****************
355 subttl NLSFUNC data
356 page
357 IN_DEX equ bp ;AN000;
358 FILESPEC_PTR equ byte ptr ds:[in_dex] ;AN000;
359 FILEVAL equ 0100h ;convert data block after checking for the
360 ;AN000;
361 ;drive only to look for the filespec
362 CL_NUM equ 81h ;command line at the PSP
363 ;AN000;
364 ;**************** NEW VARIABLE ****************
365 ;interrupts
366 SET_INT equ 25h
367 GET_INT equ 35h
368 ;
369 ;dos call backs
370 ;dosopen equ 38
371 ;dosclose equ 39
372 ;lseek equ 40
373 ;dosread equ 41
374 ;
375 ;NO_ERRORS equ 0FFh
376
377 ;variable definition area
378 ;initialization area
379
380 MSG_SERVICES <MSGDATA>
381
382 ID_CHECK db 1 ;resident variable re-initialize
383 ALL_DONE db 0 ;resident variable re-initialize
384 GET_EXT db 0 ;resident variable re-initialize
385 INFO_ID db 0 ;resident variable re-initialize
386 DONT_CLOSE db 0 ;if open or close error,this is set
387
388 RES_PARASIZE dw 0 ;adjusted size for terminate & stay func.
389 ERROR_CODE db 0 ;contains extended error code val
390 FUNC_CODE db 0 ;save function number
391 GOOD_PAR db 0
392 PARSE_ERR db 0
393
394 SI_DOSLOCATE dw 0
395 DS_DOSLOCATE dw 0
396 SAVEDX dw 0 ;=FC file offset
397 SAVECX dw 0 ;=FC
398 NOFFSET dw 2 ;=FC
399 CSIZE dw 0
400 CCODE dw 0
401 CPAGE dw 0
402 VALID_FUNC db 0 ;Flag to check for valid function #
403 EXIT_STAY db 0
404 FILENAME db "COUNTRY.SYS",0
405 PATH_SPEC db 64 dup(0) ;used to build path parameter
406 USER_PATH db 0 ;=I
407 PAR_RETC dw 0
408 NO_PARMS db 0
409 GOOD_PATH db 0
410 PATHSEG DW 0
411 SW_SPEC dW 0
412 LENGTH_HOLD db 0
413 ;***CNS
414 CUR_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000
415 OLD_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000
416 ;***CNS
417 ;********************************************************************************
418 NLS_BUFFER db BUFFSIZE dup (?) ;NLS BUFFER to transfer data
419
420
421 DATASIZE equ $-NLS_DATA
422
423 NLS_DATA ENDS
424
425 NLS_INIT_CODE SEGMENT BYTE PUBLIC 'CODE'
426
427 ASSUME CS:NLS_INIT_CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING
428
429
430
431 INT_2f_NEXT DD ? ;Chain location.
432 TEMPHOLD DW 0
433 subttl resident code
434 page
435 ;**************************** resident portion ********************************
436
437 NLSRES_CODE PROC NEAR
438 cmp ah,MULT_NLSFUNC ;Check the mutliplex value
439 je IS_NLSFUNC ;the # is mine
440 jmp dword ptr INT_2F_NEXT ;Chain to* the next handler
441
442 IS_NLSFUNC:
443
444
445 cmp al,0f8h ;Make sure AL does not have reserved
446 ;DOS value 0F8 - 0FFH
447 jb SEL_FUNC ;Select the function code between 0,
448 ;1,2,3,4
449
450 iret ;return on reserved functions
451
452 SEL_FUNC:
453
454
455 push es ;=C
456 push ds ;save the user's data segment
457 push si
458 push ds
459 push ax ;save the function value
460 mov TEMPHOLD,ax
461
462
463 mov ax,NLS_DATA ;so it won't be hosed
464 mov ds,ax ;set the data segment to mine
465
466 ASSUME DS:NLS_DATA
467
468 pop ax
469 pop DS_DOSLOCATE
470 pop SI_DOSLOCATE
471
472 mov ID_CHECK,1 ;re-intialize flags
473 mov ALL_DONE,0 ;from resident portion
474 mov GET_EXT ,0
475 mov INFO_ID ,0
476 mov VALID_FUNC,0 ;Flag to check for valid function #
477 mov DONT_CLOSE,0 ;no open or close error yet
478
479 pushall bx,cx,dx ;save all DOS registers
480 pushall bp,si,di ;save all DOS registers
481 ; *************************** CNS **********************************************
482 sti ;;AN000;the interrupt for external devices
483 ;AN000;
484 ; *************************** CNS **********************************************
485 mov FUNC_CODE,al ;save function #
486 cmp al,0
487 jne FUNCODE_DOSTATE ;state is not 0
488 mov al,INSTALLED ;Tell DOS I am installed
489 ;state is 0
490 jmp RES_EXIT ;exit
491
492
493 FUNCODE_DOSTATE:
494 cmp al,CHG_CODEPAGE
495 je FUNCODE3_1
496 cmp al,GET_EXT_CTY_INFO
497 je FUNCODE2
498 cmp al,SET_CODEPAGE
499 je FUNCODE3_1
500 jmp FUNCODE4
501
502
503 FUNCODE4: ;Get Country Data - old 38 call =F
504 mov bp,1 ;set info_id to 1 =F
505 jmp short FUNCODE2 ; =F
506
507
508 FUNCODE3_1: ;Set Codepage/Get Country Information =E
509 les di,dword ptr SI_DOSLOCATE
510 ; cmp es:[di].ccDosCodePage,bx ;=E
511 ; jne fc3_1_10 ;=E
512 ; cmp es:[di].ccDosCountry,dx ;=E
513 ; jne fc3_1_10 ;=E
514 ; mov CPAGE,bx ;get the codepage value =E
515 ; jmp short fc3_1_20 ;=E
516 ;
517 ;fc3_1_10:
518 call RES_MAIN
519 jc ERROR_ROUTINE
520 CallInstall Dosclose,multdos,39,<ax,bx,cx,dx,ds,es>,<es,ds,dx,cx,bx,ax> ;close the file
521 jc NO_CLOSE
522
523 fc3_1_20:
524 cmp FUNC_CODE,1 ;=E
525 je FUNCODE1 ;=E
526 mov al,ALL_DONE ;=E
527 jmp short RES_EXIT ;=E
528
529
530 FUNCODE2: ;Get Extended Country Information
531 mov ax,bp ;information requested by the user
532 mov INFO_ID,al
533 mov GET_EXT,1 ;get extended cty into user buffer
534 call RES_MAIN
535 jc ERROR_ROUTINE
536
537 jmp short CLOSE_FILE ;=E
538
539
540 FUNCODE1: ;CHCP - Change Code Page =E
541 call WALK_DEVICES ;=E
542 mov al,ALL_DONE ;=E
543 jmp short RES_EXIT ;=E
544
545
546
547 CLOSE_FILE: ;DOS 3eh function close COUNTRY.SYS
548 mov al,ALL_DONE
549
550 CallInstall Dosclose,multdos,39,<ax,bx,cx,dx,ds,es>,<es,ds,dx,cx,bx,ax> ;close the file
551 jc NO_CLOSE
552 ;clear to let DOS know ok
553
554
555 RES_EXIT:
556 popall bp,si,di ;restore all DOS registers
557 popall bx,cx,dx ;restore all DOS registers
558
559 cmp FUNC_CODE,GET_EXT_CTY_INFO ; =K
560 jne NC_IRET ; =K
561 cmp al,0 ;if successful 65 call, put size =K
562 jne NC_IRET ;of info returned in CX =K
563 mov cx,CSIZE ; =K
564
565 NC_IRET: ; =K
566 pop ds ;restore user's data segment =K moved
567 pop es ;=C =K moved
568 iret ;Return to DOS
569
570 NO_CLOSE:
571 mov ALL_DONE,al ;=J
572 inc DONT_CLOSE
573
574 ;if an error was detected
575
576 ERROR_ROUTINE:
577 mov al,ALL_DONE
578 cmp DONT_CLOSE,1
579 je RES_EXIT
580 jmp CLOSE_FILE
581
582
583 NLSRES_CODE ENDP
584 ;*******************************END OF NLSRES_CODE******************************
585 subttl resident main routine
586 page
587 ;*******************************RES_MAIN****************************************
588 RES_MAIN PROC NEAR
589
590 mov VALID_FUNC,1 ;function exist
591 mov CPAGE,bx ;get the codepage value
592 mov CCODE,dx ;get the country code
593 mov CSIZE,cx ;size of the buffer
594 call CHK_OPEN ;go open file if possible
595 jc END_RES ;scan and read country info
596
597 mov ax,CCODE
598 mov dx,CPAGE
599 mov si,offset NLS_BUFFER
600 call Trans_Cty_Data
601 ;into my buffer & the dos buffer
602 END_RES:
603 ret
604
605 RES_MAIN ENDP
606 ;*******************************END RES_MAIN************************************
607 subttl check open procedure
608 page
609 ;******************************CHECK OPEN PROCEDURE****************************
610 CHK_OPEN PROC NEAR
611
612
613 xor cx,cx ;zero cx for open
614 cmp USER_PATH,1 ;either user supplied=I
615 je co_user ;or default DOS
616
617 co_dos: push ds ;save current ds value
618 push si ;save current si value
619 lds si,dword ptr SI_DOSLOCATE ;old dos ds si value
620 lea dx,ds:[si].ccPATH_COUNTRYSYS
621 CallInstall Dosopen,Multdos,38,<BX,DS,ES,SI,DI>,<DI,SI,ES,DS,BX>
622 pop si ;restore current si
623 pop ds ;restore current ds
624 jmp short co_10
625
626 co_user: lea dx,PATH_SPEC
627 CallInstall Dosopen,Multdos,38,<BX,DS,ES,SI,DI>,<DI,SI,ES,DS,BX>
628
629 co_10: jc BADREP_FILE ;bx contains the
630 mov bx,ax ;file handle
631 jmp short END_OPEN
632
633 BADREP_FILE:
634 mov ALL_DONE,al ;=J
635 inc DONT_CLOSE
636
637 END_OPEN:
638 ret
639
640 CHK_OPEN ENDP
641 ;******************************END OF CHKOPEN**********************************
642 subttl transfer country data
643 page
644 ;******************************TRANS_CTY__DATA ********************************
645 TRANS_CTY_DATA PROC NEAR
646
647 TRANSTART:
648 push di ;save start of CTY/CP INFO
649 ;get the size of the file
650 xor cx,cx ;clear cx to start at
651 xor dx,dx ;at the beginning of the
652 ;file
653 call READ_CTLBUFF ;Read in the file header
654 jnc CHK_INFOTYPE
655 jmp END_TRANS ;=G
656
657 CHK_INFOTYPE:
658 add si,LOCATE_INFOTYPE ;si > Country info type
659 cmp byte ptr ds:[si],1 ;only 1 type exist currently
660 je GET_INFOIDS
661 jmp BAD_FILE
662 GET_INFOIDS:
663 inc si ;si > set to file offset
664 mov dx,word ptr ds:[si] ;Get the Info file offset
665 mov cx,word ptr ds:[si+2] ;Doubleword
666
667 mov SAVEDX,dx ;=FC save offset
668 mov SAVECX,cx ;=FC for more than 1 buffer
669 mov NOFFSET,2 ;=FC start from beginning
670
671 call READ_CTLBUFF ;Read Info
672 jnc COUNT_ENTRIES
673 jmp END_TRANS ;=G
674
675 COUNT_ENTRIES:
676
677 mov cx,word ptr ds:[si] ;Get count of entries
678 ;in info
679 inc si ;next word
680 inc si ;si > Entry info packet
681
682 FIND_CTY: ;Search for CTY/CP combo
683
684 mov ax,word ptr ds:[si] ;=FC get size of entry
685 add ax,2 ;=FC include length filed
686 add NOFFSET,ax ;=FC look ahead
687 cmp NOFFSET,CTL_BUFF-4 ;=FC < (256 - 4)
688 jb IN_BUFF ;=FC
689 sub NOFFSET,ax ;=FC restore to old offset
690 push cx ;=FC save number of cntries
691 mov cx,SAVECX ;=FC get file offset
692 mov dx,SAVEDX ;=FC
693 add dx,NOFFSET ;=FC update to the entry
694 adc cx,0 ;=FC beginning
695 mov SAVECX,cx ;=FC save them for next use
696 mov SAVEDX,dx ;=FC
697 call READ_CTLBUFF ;=FC read next buffer in
698 jc READERROR ;=FC read error occurs
699 pop cx ;=FC restore number of cntries
700 mov NOFFSET,0 ;=FC a new beginning
701 IN_BUFF:
702
703 mov dx,CPAGE
704 mov ax,CCODE
705 cmp ax,word ptr ds:[si+2] ;compare country id
706 jne NEXT_CTY
707 cmp dx, word ptr ds:[si+4] ;compare code page id
708 je FOUND_CTY
709 cmp dx,0 ;=FC if default pick the
710 jz FOUND_CTY2 ;=FC 1st country
711
712 NEXT_CTY:
713 add si, word ptr ds:[si] ;next entry
714 inc si
715 inc si ;take a word for size of entry itself
716 loop FIND_CTY
717
718 mov ALL_DONE,INVALID_DATA ;if it exits the loop =J =L
719 jmp FINDCTY_FAIL ;then no cp/cty match
720
721 READERROR: pop cx ;=FC
722 jmp END_TRANS ;=FC
723
724 FOUND_CTY2: mov dx,word ptr ds:[si+4] ;=FC from now on,this is
725 mov CPAGE,dx ;=FC the code page
726
727 FOUND_CTY: ;found the matching entry
728 mov dx, word ptr ds:[si+10] ;get the file offset of country data
729 mov cx, word ptr ds:[si+12]
730 call READ_CTLBUFF
731 jnc NUM_ENTRY
732 jmp END_TRANS ;=G
733 NUM_ENTRY:
734 mov cx, word ptr ds:[si] ;get the number of entries to handle.
735 inc si
736 inc si ;SI -> first entry
737
738 SETDOSCTY_DATA:
739 .REPEAT
740 push di ;ES:DI -> DOS_COUNTRY_CDPG_INFO
741 push si ;si -> current entry in Control buffer
742 push cx ;save # of entry left
743
744 mov al, byte ptr ds:[si+2] ;get data entry id
745 xor ah,ah ;clear out for comparison with
746 ;info-id in case id is > 256
747
748
749
750 cmp GET_EXT,1 ;check to see if function 2
751 ;get_extended info was needed
752 jne TRANSALL ;if not assume function code 1
753 ;set codepage
754
755 cmp INFO_ID,-1 ;Minus 1 means return all of the
756 jne CHK_ID ;country info to the user
757 ;otherwise get the specific
758 ;info id and return only that info
759
760
761 pop cx ;error can not return all
762 pop si ;info accept for currently
763 pop di ;loaded control info in DOS
764 jmp BAD_SETID ;area
765
766 CHK_ID: cmp al,INFO_ID ;check to see if the selected
767 ;id is the same as the id in the
768 ;ctrl buffer area
769
770 jne SETDOSCTY_NEXT ;if not equal go search for the
771 ;next information id
772
773 pop cx ;Bingo!! Found it set counter
774 mov cx,1 ;to zero to exit loop
775 push cx
776 mov ID_CHECK,0 ;found a valid id
777 cmp GET_EXT,1 ;after transferring data to USER
778 je GET_ADDR ;area
779
780 ;set cx image in stack to force
781 ;exit loop
782 TRANSALL:
783
784
785
786 call GetDOSCTY_Dest ;get the address of destination in ES:DI
787 jc SetDOSCTY_NEXT ;No matching data entry id in DOS
788
789 GET_ADDR:
790
791 mov dx, word ptr ds:[si+4] ;get offset of data
792 mov cx, word ptr ds:[si+6]
793
794
795
796 SEEK_READ:
797
798 push ax ;=A save data id.
799 xor bp,bp ;DOS 4200h function
800 CallInstall Lseek,multdos,40,<bx,cx,ds,es,di,si>,<si,di,es,ds,cx,bx> ;move ptr
801 pop ax ;=A
802 jc DATASEEKNREAD
803 ;when ptr moved
804 mov dx,offset NLS_BUFFER +CTL_BUFF ;set the buffer to the beginning of the
805 ;data buffer area
806
807 mov cx,DATA_BUFF_LENG ;set to number of bytes in the
808 ;data buffer area
809 push ax ;=A
810 ;DOS 3fh
811 CallInstall Dosread,Multdos,41,<bx,cx,ds,es,di,si>,<si,di,es,ds,cx,bx> ;Read cx many bytes into the buffer
812 pop ax ;=A
813 jc DATASEEKNREAD
814
815 IS_EXTENDED:
816 cmp GET_EXT,1
817 jne CHK_OVERWRITE
818 call GETEXT_CTY
819 jmp short SETDOSCTY_NEXT
820
821
822 CHK_OVERWRITE: ;=A
823 ; If SetCountryInfo, then
824 ; put DOS monocase routine
825 ; entry point into
826 ; NLS_BUFFER so don't
827 ; write over. =A
828 cmp al,SetCountryInfo ;=A
829 jne DOS_MOVE ;=A
830 mov ax,word ptr es:[di+24] ;=A
831 mov word ptr ds:[NLS_BUFFER+CTL_BUFF + 32],ax ;=A
832 mov ax,word ptr es:[di+26] ;=A
833 mov word ptr ds:[NLS_BUFFER+CTL_BUFF + 34],ax ;=A
834
835 mov ax,CPAGE ;=FC, CPAGE is right
836 mov word ptr ds:[NLS_BUFFER+CTL_BUFF + 12],ax ;=FC
837
838 DOS_MOVE:
839 call CHK_ADJUST ;now check to see if the entire
840 ;table fits
841
842 SETDOSCTY_NEXT:
843
844 pop cx
845 pop si
846 pop di
847 add si, word ptr ds:[si]
848 inc si
849 inc si
850 dec cx
851 .UNTIL <cx eq 0> NEAR ;loop SETDOSCTY_DATA
852
853 ;Check for an invalid id
854 cmp GET_EXT,1 ;Check to see if a get_ext func 2 was issued
855 jne CTLSEEKnREAD ;if not move on
856 cmp ID_CHECK,1 ;if so check to see if an id was found
857 je BAD_SETID ;if none was found report an error
858 ;otherwise continue
859
860
861 CTLSEEKnREAD:
862 clc ;=G
863 jmp short END_TRANS ;exit
864
865
866
867 DATASEEKnREAD:
868 mov ALL_DONE,al ;=J
869 pop cx
870 pop si
871 pop di
872 jmp short END_TRANS
873
874 BAD_SETID:
875 mov ALL_DONE,INVALID_FUNCTION ;=J
876 jmp short FINDCTY_FAIL ;=J
877
878 BAD_FILE:
879 mov ALL_DONE,INVALID_FUNCTION ;=J
880
881 FINDCTY_FAIL:
882 stc
883
884 END_TRANS:
885 pop di ;Restore header start
886 ret
887
888
889
890 TRANS_CTY_DATA ENDP
891
892 ;******************************END TRANS_CTY_DATA ******************************
893 subttl get DOS country destination
894 page
895 ;****************************GETCTY_DEST***********************************************
896 GetDOSCty_Dest proc near
897 ;Get the destination address in the DOS country info table.
898 ;Input: AL - Data ID
899 ; ES:DI -> DOS_COUNTRY_CDPG_INFO
900 ;On return:
901 ; ES:DI -> Destination address of the matching data id
902 ; carry set if no matching data id found in DOS.
903
904 push cx
905 add di, ccNumber_of_entries ;skip the reserved area, syscodepage etc.
906 mov cx, word ptr es:[di] ;get the number of entries
907 inc di
908 inc di ;SI -> the first start entry id
909 GetCntryDest:
910 cmp byte ptr es:[di], al
911 je GetCntryDest_OK
912 cmp byte ptr es:[di], SetCountryInfo ;was it SetCountryInfo entry?
913 je GetCntryDest_1
914 add di, 5 ;next data id
915 jmp short GetCntryDest_loop
916
917 GetCntryDest_1:
918 add di, NEW_COUNTRY_SIZE + 1 ;next data id
919
920 GetCntryDest_loop:
921 loop GetCntryDest
922 stc
923 jmp short GetCntryDest_exit
924
925 GetCntryDest_OK:
926
927 cmp al, SetCountryInfo ;select country info?
928 jne GetCntryDest_OK1
929 inc di ;now DI -> ccCountryInfoLen
930 clc ;clear the carry
931 jmp short GetCntryDest_exit
932
933 GetCntryDest_OK1:
934
935 les di, dword ptr es:[di+1] ;get the destination in ES:DI
936 clc
937
938 GetCntryDest_Exit:
939 pop cx
940 ret
941
942 GetDOSCty_Dest endp
943 ;****************************GETDOSCTY_DEST*************************************
944 subttl get extended country data
945 page
946 ;****************************GETEXT_CTY*****************************************
947 GETEXT_CTY proc
948
949 JUSTONE_ID:
950 mov ah,func_code ;=F
951 cmp ah,GET_CTY_INFO ;=F
952 je id_ctyinfo1 ;=F
953
954 mov al,INFO_ID
955 mov byte ptr es:[di],al
956
957 cmp INFO_ID,SetCountryInfo ;SETCTY_INFO =D moved.
958 je ID_CTYINFO ;=D don't want ptr if 1.
959
960 mov word ptr es:[di+1],offset nls_buffer + ctl_buff+8 ;=H
961 mov word ptr es:[di+3],ds ;my current ds value
962 mov CSIZE,5 ;=K
963
964 jmp GET_EXT_END
965
966 ID_CTYINFO:
967 inc di ;=D (old code - add di,5) =F(moved).
968 id_ctyinfo1: ;=F
969 mov cx,CSIZE
970 ;next line used to be "add si,5"
971 ;si needs to point to cty info. =D
972 mov si,offset nls_buffer + ctl_buff + 8 ;=D
973
974 push es ;=A put DOS Monocase Routine
975 push di ;=A entry point in user buffer.
976 push ax ;=A
977 les di,dword ptr si_doslocate ;=A
978 mov ax,word ptr es:[di].ccMono_Ptr ;=A
979 mov word ptr ds:[si+24],ax ;=A
980 mov ax,word ptr es:[di].ccMono_Ptr+2 ;=A
981 mov word ptr ds:[si+26],ax ;=A
982
983 mov ax,CPAGE ;=FC trust CPAGE
984 mov word ptr ds:[si+4],ax ;=FC
985
986 pop ax ;=A
987 pop di ;=A
988 pop es ;=A
989
990 push bx ;=F
991 cmp ah,GET_CTY_INFO ;=F if get cty info(38) slide info
992 jne id_ctyinfo2 ;=F ptr up to date.
993 add si,6 ;=F
994 mov cx,old_country_size ;=FC
995 jmp MOVE_CTY ;=FC
996
997 id_ctyinfo2: mov bx,word ptr ds:[si] ;=FC get table size
998
999
1000 sub CSIZE,3 ;=FC size begins after length field
1001 mov cx,CSIZE ;=FC
1002
1003 cmp cx,bx ;=D was cmped to SETCTR_LENG
1004 ja TRUNC_SIZE ;=FC used to be jg
1005 jmp short MOV_SIZE
1006 TRUNC_SIZE:
1007 mov cx,bx ;=F
1008 MOV_SIZE:
1009 mov es:[di],cx ;=FC move actual length to user's buff
1010 add di,2 ;=FC update index
1011 add si,2 ;=FC skip length field
1012
1013 MOVE_CTY: pop bx ;=F
1014 mov CSIZE,cx ;=K
1015 add CSIZE,3 ;=K
1016 rep movsb
1017
1018 GET_EXT_END:
1019 ret
1020
1021 GETEXT_CTY endp
1022 ;*****************************END GETEXT_CTY*************************************
1023 subttl read into control buffer
1024 page
1025 ;**************************READ_CTLBUFF*****************************************
1026 ;
1027 READ_CTLBUFF proc near
1028 ;Move file pointer to CX:DX
1029 ;Read 64 bytes into the control buffer. Assume that the necessary data
1030 ;is within that limit.
1031 ;SI will be set to beginning of the offset my NLS_BUFFER hence DS:SI points to the control buffer.
1032 ;Entry: CX,DX offset from the start of the file where the read/write pointer
1033 ; be moved.
1034 ; BX - file handle
1035 ; DS - buffer seg.
1036 ;Return: The control data information is read into DS:0 - DS:0200.
1037 ; CX,DX value destroyed.
1038 ; Carry set if error in Reading file.
1039 ;
1040 ;Function 4200h
1041 xor bp,bp
1042 CallInstall Lseek,multdos,40,<bx,cx,ds,es,di,si>,<si,di,es,ds,cx,bx> ;move pointer
1043 jc NO_SEEK1
1044
1045 mov dx,offset NLS_BUFFER ;ds:dx -> control buffer
1046 mov si,dx ;index for the entire buffer
1047 ;read into the buffer function 3fh
1048 mov cx, CTL_BUFF ;XXX bytes. Size of the information
1049 CallInstall Dosread,multdos,41,<bx,cx,dx,ds,es,di,si>,<si,di,es,ds,dx,cx,bx> ;should be less than XXX bytes.
1050 jc NO_READ1
1051 jmp short RICB_exit
1052
1053
1054 NO_SEEK1:
1055 mov ALL_DONE,al ;=J
1056 jmp short RICB_exit
1057
1058 NO_READ1:
1059 mov ALL_DONE,al ;=J
1060
1061 RICB_exit: ;In this case 64 bytes
1062 ret
1063
1064 READ_CTLBUFF endp
1065 ;****************************END READ_CTLBUFF***********************************
1066 subttl check / adjust / move data into DOS buffer
1067 page
1068 ;****************************CHK_ADJUST*****************************************
1069 CHK_ADJUST PROC NEAR
1070
1071 push ax ;save info id
1072 mov si,offset NLS_BUFFER+DATA_N_ID ;start of buffer + tag id
1073 mov cx, word ptr ds:[si] ;get the length of the structure
1074
1075 inc cx
1076 inc cx
1077
1078 cmp cx,MAXBUFF_FIT
1079 jbe MOVE_DATA
1080 push cx
1081 mov cx,MAXBUFF_FIT
1082 rep movsb
1083 pop cx
1084 sub cx,MAXBUFF_FIT
1085
1086 NEED_ADJUST:
1087 mov dx,offset NLS_BUFFER+CTL_BUFF ;reset to the beginning of the data buffer
1088 mov si,dx ;reset to the beginning of the data buffer
1089 cmp cx,DATA_BUFF_LENG ;check to see if it fits for the nth read
1090 jbe LAST_READ ;last portion fits
1091 push cx ;save how much is left to read
1092 mov cx,DATA_BUFF_LENG ;set to how much you read at one time
1093
1094 ;read again ;function 3fh
1095 ;read into the data buffer
1096 CallInstall Dosread,multdos,41,<bx,cx,dx,ds,es,di,si>,<si,di,es,ds,dx,cx,bx> ;save the file handle
1097 jc ADJUST_END
1098
1099 rep movsb ;move data into DOS area
1100 pop cx ;restore size remaining to
1101 sub cx,DATA_BUFF_LENG ;be read get new size
1102 jmp NEED_ADJUST ;must read agian
1103
1104 LAST_READ:
1105 ;one more read 3f
1106 CallInstall Dosread,multdos,41,<bx,cx,dx,ds,es,di,si>,<si,di,es,ds,dx,cx,bx>
1107 jc ADJUST_END
1108
1109 MOVE_DATA:
1110 rep movsb ;move data into DOS area
1111
1112 ADJUST_END:
1113 pop ax
1114 ret
1115 CHK_ADJUST ENDP
1116 ;*******************************END CHK_ADJUST *********************************
1117 subttl walk through device drivers and invoke
1118 page
1119 ;************************ WALK DEVICE DRIVERS **********************************
1120 ;=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=E=
1121
1122 WALK_DEVICES PROC NEAR
1123
1124 mov si,offset NLS_BUFFER ;Prepare to hold device name
1125 push es ;AN001; Clear out NLS_BUFFER to 0
1126 push ds ;AN001;
1127 pop es ;AN001;
1128 mov di, si ;AN001; ES:DI-> NLS_BUFFER
1129 xor ax, ax ;AN001; AX=0
1130 mov cx, BUFFSIZE ;AN001;
1131 shr cx, 1 ;AN001; /2 to make a # of words
1132 rep stosw ;AN001;
1133 pop es ;AN001; Restore es
1134 ;Get ptr to hdr of 1st device.
1135 push si ;AN001;
1136 CallInstall GetDevLst,Multdos,44,<DS>,<DS>
1137 pop si ;AN001;
1138 mov es,bx ;bx:ax -> hdr.
1139 mov di,ax
1140 char_test:
1141 test es:[di].sdevatt,devtyp ;check attribute word for
1142 jne open_device
1143 jmp GET_NEXT_DEVICE ;character device.
1144
1145 OPEN_DEVICE:
1146 push si
1147 push di ;set up asciiz filename
1148 add di,10 ;for DOS file open
1149 mov cx,8
1150
1151 set_asciiz: mov al,es:[di]
1152 cmp al,20h
1153 je done_set_asciiz
1154 mov ds:[si],al
1155 inc di
1156 inc si
1157 loop set_asciiz
1158
1159 done_set_asciiz:xor al,al
1160 mov ds:[si],al
1161
1162 pop di
1163 pop si
1164
1165 mov cx,1 ;open for write
1166 mov dx,si
1167 CallInstall Dosopen,Multdos,38,<DS,SI,ES,DI>,<DI,ES,SI,DS>
1168 jnc end_open_device
1169 jmp GET_NEXT_DEVICE ; ignore this =FC
1170
1171 end_open_device:
1172 mov bx,ax ;put handle in bx
1173 call Chk_Revisit ;AN001; Have been here already?
1174 jnc INVOKE_DEVICE ;AN001; No, a new one.
1175 jmp CLOSE_DEVICE ;AN001; Yes. Close and ignore this.
1176
1177 INVOKE_DEVICE:
1178 push ds ;Check print queue first.
1179 push si ;Set up for 2f print call.
1180 clc
1181 mov ax,0106h ;2f call to command.com.
1182 int 2fh ;If print active: carry set,
1183 jnc invoke_it ;DS:SI -> hdr of printing device.
1184 cmp si,di ;Check if printing device is this
1185 jne invoke_it ;device. Match on ptr to device.
1186 mov ax,ds
1187 mov cx,es
1188 cmp ax,cx
1189 jne invoke_it
1190
1191 pop si
1192 pop ds
1193 mov ALL_DONE,BAD_INVOKE ;Match. Set invoke error.
1194 jmp CLOSE_DEVICE
1195
1196 invoke_it: pop si ;save the current
1197 pop ds ;environment
1198
1199 ;*************** CNS *********** Start of DBCS Support
1200 ; PUSH DS ;ICE
1201 ; push bx ;ICE
1202 ; push ax ;ICE
1203 ; mov bx,0140H ;ICE
1204 ; xor ax,ax ;ICE
1205 ; mov ds,ax ;ICE
1206 ; mov ax,word ptr ds:[bx] ;ICE
1207 ; mov word ptr ds:[bx],ax ;ICE
1208 ; POP ax ;ICE
1209 ; pop bx ;ICE
1210 ; pop ds ;ICE
1211 push di
1212 push bx
1213 push cx
1214 push es
1215 les di,dword ptr SI_DOSLOCATE ;get the environmental
1216 ;*************** CNS ******************
1217 ; mov bx,es:[di].ccDBCS_ptr ;values to allow
1218 ; mov es,es:[di].ccDBCS_ptr+2 ;recognition and
1219 ;*************** CNS ******************
1220 les bx,es:[di].ccDBCS_ptr
1221 mov cx,es:[bx] ;invocation of data
1222 add cx,2
1223 add bx,2 ;and ID for start
1224 mov di,offset pk.DBCS_EV ;and stop values for
1225 ;otherwise it is a DBCS
1226 ;****CHANGE ;or custom designed codepage
1227
1228 mov PK.PACKLEN,cx ;if packet length is zero
1229
1230 NODBCS_CP:
1231 add cx,-2 ;AN002; reset counter before CP addition
1232
1233 ;****CHANGE
1234
1235 DB_EVECS:
1236 cmp cx,0 ;AN002;no need to alter packet
1237 je NO_LOAD ;An002;initialized to zero
1238
1239
1240 .REPEAT ;;AN000;DBCS transmission
1241 ;AN000;
1242 mov al,es:[bx] ;;AN000;get the the contents
1243 ;***CNS ;AN000;
1244 mov ds:[di],al ;;AN002;of where the DBCS Points
1245 ;***CNS ;AN000;
1246 inc di ;;AN000;data packet for ioctl
1247 ;AN000;
1248 inc bx ;AN000;;call--- get the start
1249 ;stop values to load
1250 ;AN000;
1251 dec cx ;AN000;
1252
1253 .UNTIL <CX EQ 0 > ;AN000;
1254 ;invocation of 1 codepage
1255 ;standard codepage selection
1256
1257
1258 NO_LOAD:
1259
1260 pop es ;AN000;;accordingly & restore
1261 ;AN000;
1262 pop cx ;AN000;;values
1263 ;AN000;
1264 pop bx ;AN000;
1265 ;AN000;
1266 pop di ;AN000;
1267 ;AN000;;invoke codepage
1268 ;************************ CNS*** End of DBCS
1269
1270 ;Set up data packet for generic
1271 mov ax,cpage ;ioctl call.
1272 mov pk.packcpid,ax
1273 lea dx,pk
1274
1275 mov cx,004ah
1276 mov bp,0ch ;generic ioctl
1277 CallInstall IOCTL,multdos,43,<DS,SI,ES,DI,BX>,<BX,DI,ES,SI,DS>
1278 jc device_error
1279
1280
1281 CLOSE_DEVICE:
1282 CallInstall Dosclose,multdos,39,<DS,SI,ES,DI>,<DI,ES,SI,DS>
1283 jc dev_open_close_error ; ignore this =FC
1284
1285 GET_NEXT_DEVICE:
1286 cmp word ptr es:[di],0FFFFH
1287 je END_WALK_DEVICES
1288 les di,dword ptr es:[di]
1289 jmp char_test
1290
1291 DEVICE_ERROR:
1292 cmp ax,1
1293 je CLOSE_DEVICE
1294 CallInstall GetExtErr,multdos,45,<DS,SI,ES,DI,BX>,<BX,DI,ES,SI,DS>
1295 cmp ax,22
1296 je CLOSE_DEVICE
1297 mov ALL_DONE,BAD_INVOKE
1298 jmp CLOSE_DEVICE
1299
1300 dev_open_close_error:
1301 mov ALL_DONE,BAD_INVOKE
1302 jmp GET_NEXT_DEVICE
1303
1304 END_WALK_DEVICES:
1305
1306
1307 ret
1308
1309 WALK_DEVICES endp
1310 ;*********************** END WALK DEVICE DRIVERS *******************************
1311 ;************************ Chk_Revisit******************************************
1312 ;This routine will check if we are opening the same device driver again.
1313 ;If it is, then carry bit will set.
1314 ;This routine will use the NLS_BUFFER to keep the history of already
1315 ;visited device driver address (OFFSET,SEGMENT). NLS_BUFFER will be
1316 ;used from the end of the buffer towards to the front of the buffer.
1317 ;For 512 byte length and considering the front part used for OPEN device
1318 ;driver name string, this will handle appr. 126 devices maximum. which is
1319 ;sufficient enough. - J.K. 1/15/88
1320 ;IN: BX = file handle
1321 ; DS = NLS_BUFFER segment
1322 ;OUT: carry set = visited
1323 ; carry not set = new one.
1324 ; Other registers saved.
1325
1326 Chk_Revisit proc near
1327 push ax ;AN001;
1328 push bx ;AN001;
1329 push es ;AN001;
1330 push di ;AN001;
1331 mov ax, 1220h ;AN001; Get the spot of SFT
1332 int 2fh ;AN001;
1333 jc Chk_Rvst_Ret ;AN001; This won't happen
1334 xor bx, bx ;AN001;
1335 mov bl, byte ptr es:[di] ;AN001;
1336 mov ax, 1216h ;AN001; Get the SFT pointer
1337 int 2fh ;AN001; es:di-> SFT table
1338 jc Chk_Rvst_Ret ;AN001; This won't happen
1339 mov ax, word ptr es:[di].SF_DEVPTR ;AN001; offset of device
1340 mov bx, word ptr es:[di].SF_DEVPTR+2;AN001; Segment of device
1341 mov di, offset NLS_BUFFER ;AN001;
1342 add di, BUFFSIZE-2 ;AN001; ds:di-> last word of the buffer
1343 Chk_Rvst_While: ;AN001;
1344 cmp word ptr ds:[di], 0 ;AN001; di-> segment value
1345 jne Chk_Rvst_Cont ;AN001;
1346 cmp word ptr ds:[di-2], 0 ;AN001; offset
1347 jne Chk_Rvst_Cont ;AN001;
1348 jmp Chk_Rvst_New ;AN001; Encountered a blank entry in the buffer
1349 Chk_Rvst_Cont: ;AN001;
1350 cmp word ptr ds:[di], bx ;AN001;
1351 jne Chk_Rvst_Next ;AN001;
1352 cmp word ptr ds:[di-2], ax ;AN001;
1353 jne Chk_Rvst_Next ;AN001;
1354 stc ;AN001; found a match
1355 jmp Chk_Rvst_Ret ;AN001;
1356 Chk_Rvst_Next: ;AN001;
1357 sub di, 4 ;AN001; move the pointer to the next entry
1358 jmp Chk_Rvst_While ;AN001;
1359 Chk_Rvst_New: ;AN001;
1360 mov word ptr ds:[di],bx ;AN001; Keep the current open device segment
1361 mov word ptr ds:[di-2], ax ;AN001; and offset
1362 clc ;AN001; New device
1363 Chk_Rvst_Ret: ;AN001;
1364 pop di ;AN001;
1365 pop es ;AN001;
1366 pop bx ;AN001;
1367 pop ax ;AN001;
1368 ret ;AN001;
1369 Chk_Revisit endp
1370
1371 subttl end nlsfunc resident code
1372 page
1373 NLSRES_LENG equ $-NLSRES_CODE+DATASIZE
1374 subttl initialization
1375 page
1376 ;***************************** NLSFUNC Initialization **************************
1377
1378 ASSUME CS:NLS_INIT_CODE,SS:STACK
1379
1380
1381
1382 MAIN PROC FAR
1383
1384 mov ax,NLS_DATA ;set up data segment
1385 mov ds,ax
1386 assume ds:NLS_DATA
1387
1388 mov PATHSEG,ax
1389
1390 call SYSLOADMSG ;does DOS version check
1391
1392 .IF <NC>
1393 mov dx,NLSRES_LENG ;calculate paragraph
1394 add dx,15 ;add 15
1395 shr dx,1 ;divide by 16 to get conversion from
1396 shr dx,1 ;bytes to paragraphs
1397 shr dx,1
1398 shr dx,1
1399 add dx,11h ;size based on the byte size of
1400 mov RES_PARASIZE,dx ;the resident procedure
1401 call PROCESS_PATH
1402
1403 .ELSE
1404
1405 call SYSDISPMSG
1406
1407 .ENDIF
1408
1409 .IF <NO_PARMS eq 1> or
1410 .IF <GOOD_PATH eq 1>
1411 call INSTALL_NLS ;let's install NLSFUNC
1412 .IF <NC>
1413 mov EXIT_STAY,1 ;if nothing wrong occured
1414 .ENDIF
1415 .ENDIF
1416 ;determine path of exit
1417 ;error or residency
1418 ;****************************** EXIT PROG *********************************************
1419 push ax ;AN004;save existing values
1420 push es ;
1421 xor ax,ax
1422 mov ax,es:[2ch]
1423 cmp ax,0
1424 je NO_FREEDOM
1425 mov es,ax
1426 mov ax,4900H ;AN004;make the free allocate mem func
1427 int 21h ;
1428
1429 NO_FREEDOM:
1430 pop es ;AN004;restore existing values
1431 pop ax ;
1432
1433 .IF <EXIT_STAY eq 1> ;Terminate and stay resident
1434 mov bx,4 ;1st close file handles
1435 .REPEAT
1436 mov ah,3eh
1437 int 21h
1438 dec bx
1439 .UNTIL <BX eq 0>
1440
1441 mov ah,031h ;
1442 mov dx,RES_PARASIZE ;paragraphs allocated
1443 .ELSE
1444 clc
1445 mov ah,04ch ;value passed to ERRORLEVEL
1446 .ENDIF
1447
1448 mov al,ERROR_CODE ;check for an error
1449 int 21H
1450
1451
1452
1453
1454
1455
1456 MAIN ENDP
1457
1458 ;****************************** EXIT PROG *********************************************
1459 subttl parse
1460 page
1461 ; On entry: ES points at the PSP
1462 ; DS points at NLS_DATA
1463 ; DX was used to calculate paragraph size
1464 ;
1465 ; PARSER EFFECTS ES & DS wil be swapped
1466 ;
1467 ; Changes : ES:DI seg:off containing PARM Input Block
1468 ; to DS:SI seg:off containing command line
1469 ; segments
1470 ;
1471 ;
1472 ;
1473 ;
1474 ;
1475 ;
1476 ;****************************** PROCESS PATH ***********************************
1477 ;=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=I=
1478
1479 PROCESS_PATH PROC NEAR
1480
1481 ;to command line parms
1482
1483
1484 push es ;;AC000;e original es (nothing)
1485 ;AC000;
1486 push ds ;AC000;he original ds (Nls_data)
1487 ;AC002;
1488 push ds ;save for both es & ds to point at data
1489
1490 push es ;AC000;hat's in my es the PSP value
1491 ;AN000;
1492 push ds ;AN000;he segment id that points to my
1493 ;es now points to data
1494 pop es ;AC000;
1495 ;input parameter control block (NLS_DATA)
1496 ;AN000;
1497
1498 pop ds ;AN000; points to the segment for
1499 ;the command line string
1500 ;AN000;
1501
1502 ASSUME DS:NOTHING,ES:NLS_DATA
1503
1504 xor dx,dx
1505 xor cx,cx
1506
1507 ;***CNS
1508 RE_START:
1509 mov si,80h ;get the command line length
1510
1511 mov cl,byte ptr ds:[si] ;get the length for the counter
1512 ;
1513 mov LENGTH_HOLD,cl ;save the length of the command line
1514 ;
1515
1516
1517
1518 ; .IF <dx eq 0>
1519
1520 mov di,OFFSET NLS_BUFFER ;
1521 ; mov dx,1
1522 ; .ELSE
1523 ; mov di,OFFSET PATH_SPEC ;
1524 ; mov dx,-1
1525 ; .ENDIF
1526
1527 mov si,CL_NUM ;AN000; points to the offset command
1528 ;line input string at value 81h
1529 ;AN000;
1530
1531 rep movsb ;transfer command line to NLS_BUFFER
1532
1533 ; .IF <dx eq 1>
1534 ; jmp RE_START
1535 ; .ENDIF
1536
1537 ;***CNS
1538
1539
1540
1541
1542 mov di,OFFSET NLS_PARMS ;AN000; into ES of the PARMS INPUT
1543 ;BLOCK
1544 ;AN000;
1545 pop ds ; ds also point at NLS_DATA
1546
1547
1548 ASSUME DS:NLS_DATA
1549
1550
1551 mov si,OFFSET NLS_BUFFER ;si now points to the offset command
1552 ;***CNS
1553
1554 PUSH AX ;AN003;Save environment
1555 MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument
1556 MOV OLD_PTR,AX ;AN003;after saving the beginning the string
1557 MOV CUR_PTR,SI ;AN003;
1558 POP AX ;AN003;Restore the environment
1559
1560 ;***CNS
1561
1562
1563
1564 xor cx,cx ;AN000;l value should be atleast 1
1565 xor dx,dx ;AN000;ut dx for input into the PARSER
1566 ;AN000;
1567
1568 .WHILE <PAR_RETC eq 0> ;AN000;
1569 call SYSPARSE ;AN000;empt to parse
1570 ;***CNS
1571
1572 PUSH AX ;AN003;Save environment
1573 MOV AX,CUR_PTR ;AN003;Set advancing ptr to end of argument
1574 MOV OLD_PTR,AX ;AN003;after saving the beginning the string
1575 MOV CUR_PTR,SI ;AN003;
1576 POP AX ;AN003;Restore the environment
1577
1578 ;***CNS
1579 ;AN000;
1580 .IF <Res_type eq 5> ;AN000;ound
1581 ;AN000;
1582 mov USER_PATH,1 ;AN000;;path specified
1583 ;AC000;
1584 .ENDIF ;AN000;
1585
1586 mov PAR_RETC,AX ;AN000;;keep parsing until eoln
1587 ;AN000;
1588 .ENDWHILE ;AN000;
1589
1590
1591 .IF <PAR_RETC gt 0> ;AN000;;parse error
1592 ;***CNS
1593 ; .IF <PAR_RETC eq 3> ;AN003;IF invalid switch return command line
1594 ;
1595 ; mov ax,10
1596
1597
1598 LEA DI,PATH_SPEC ;AN003;Set PTR to look at the STRING
1599 PUSH SI ;AN003;Save current SI index
1600 PUSH AX
1601 MOV AX,OLD_PTR ;AN003;Last locale of the end of a PARAM
1602 SUB CUR_PTR,AX ;AN003;Get the length via the PSP
1603 MOV SI,CUR_PTR
1604 MOV CX,SI ;AN003;Save it in CX to move in the chars
1605 POP AX ;AN003;Restore the PTR to the command line position
1606
1607 MOV SI,OLD_PTR ;AN003;Last locale of the end of a PARAM
1608 REP MOVSB ;AN003;Move in the chars until no more
1609
1610 LEA DI,PATH_SPEC ;AN003;Set PTR to look at the STRING
1611
1612 POP SI ;AN003;Restore the PTR to the command line position
1613
1614
1615
1616
1617 mov cx,1 ;AN003;;
1618 mov bx,STDERR ;AN003;
1619 mov dl,no_input ;AN003;
1620 mov dh,PARSE_ERR_CLASS ;AN003;
1621 mov ds,PATHSEG ;AN003;
1622 mov si,OFFSET PARMLIST3 ;AN003;
1623 call SYSDISPMSG ;AN003;
1624 mov PARSE_ERR,1 ;AN003;;PARSE ERROR OCCURED
1625 ;***CNS
1626 ; .ELSE
1627
1628 ; xor cx,cx ;AN000;;
1629 ; mov bx,STDERR ;AN000;
1630 ; mov dl,no_input ;AN000;
1631 ; mov dh,PARSE_ERR_CLASS ;AN000;
1632 ; mov ds,PATHSEG ;AN000;
1633 ; mov si,0 ;AN000;
1634 ; call SYSDISPMSG ;AN000;
1635 ; mov PARSE_ERR,1 ;AN000;;PARSE ERROR OCCURED
1636 ;***CNS
1637 ; .ENDIF
1638 ;***CNS
1639 .ELSEIF <CX eq 1> ;AN000;ordinal check
1640 ;AN000;
1641 mov GOOD_PAR,1 ;AN000;you are at the end of the line
1642 ;AN000;
1643 .ELSE
1644 mov NO_PARMS,1 ;AN000;there is no argument go install
1645 .ENDIF ;AN000;NLSFUNC
1646
1647 .IF <PARSE_ERR eq 0> NEAR ;AN000;if not true you encountered a parse error
1648 .IF <GOOD_PAR eq 1> NEAR ;AN000;there is a parameter line available
1649 ;to parse
1650 ;AN000;
1651 ;Check the flags to see what
1652 ;was returned in the return block
1653
1654 lea di,path_spec ;AC000;es:di > final path_spec
1655 ;that will be used after fixup
1656
1657 .IF <USER_PATH gt 0> ;AC000;drive has been solved need
1658 ;to check the filespec
1659 ;now
1660 xor in_dex,in_dex ;AN000;clear ctr
1661 mov bx,Res_POFF ;AN000;get file spec ptr to text
1662 push ds ;AN000;prepare for entry
1663 mov ds,Res_PSEG ;AN000;
1664 mov in_dex,bx ;AN000;string seg value if filename
1665 .ENDIF ;user path ;AN000;
1666
1667
1668 .WHILE <Filespec_PTR ne NULL> ;load chars until no more
1669 ;AN000;
1670 ;AN000;
1671 mov al,FILESPEC_PTR ;AN000;
1672 mov byte ptr es:[di],al ;move value into pathspec and
1673 inc in_dex ;increment to next char position
1674 inc di ;AN000;
1675 .ENDWHILE
1676
1677 ;************************** CNS **********************************************
1678 ;The new method of checking for a "bogus" file will be to attempt an
1679 ;open on the path_spec if pathspec exist close path and continue if
1680 ;carry set stuff error code with 02 and exit.....
1681 ;*****************************************************************************
1682 ; push es ;AN000;
1683 pop ds ;into find first
1684 mov si,di ;AN000;
1685 xor cx,cx ;AN000;
1686 ;
1687 ASSUME DS:NLS_DATA
1688 ;
1689 mov byte ptr ds:[si],NULL ;add asciiz value
1690 ;AN000;
1691 lea dx,PATH_SPEC ;check full pathname
1692 mov ah,4eh
1693 int 21h
1694 ;set up addressability
1695 .IF <NC>
1696 clc ;ok-clear carry/exit
1697 mov GOOD_PATH,1
1698 .ELSE
1699 mov ax,FNF ;AN000;
1700 mov cx,1 ; ;AN000;
1701 mov bx,STDERR ;AN000;
1702 mov dl,no_input ;AN000;
1703 mov dh,UTILITY_MSG_CLASS ;AN000;
1704 mov ds,PATHSEG ;AN000;
1705 mov si,OFFSET PARMLIST1 ;AN000;
1706 call SYSDISPMSG ;AN000;
1707 mov ERROR_CODE,02 ;
1708 stc
1709 .ENDIF
1710
1711
1712
1713
1714
1715
1716
1717 .ENDIF ;EXIT on bad parse
1718 .ENDIF ;END OF PROCESS PATH
1719
1720
1721 pop ds ;AN000;;restore original ds (NLS_DATA)
1722 ;AN000;
1723 pop es ;AN000;;restore original es (nothing)
1724 ;AN000;
1725 ;AN000;;after munging around with the PARSER
1726
1727 ASSUME DS:NLS_DATA,ES:NOTHING
1728
1729 ret
1730
1731
1732
1733 PROCESS_PATH ENDP
1734
1735 ;
1736
1737 ;****************************** CNS *******************************************
1738 subttl install NLSFUNC
1739 page
1740 ;******************************** INSTALL NLSFUNC *****************************
1741
1742 INSTALL_NLS PROC NEAR
1743
1744 xor ax,ax ;clear the ax
1745 mov ah,MULT_NLSFUNC ;load in my multiplex
1746 INT 2fh ;id value 14
1747 or al,al ;check to see if
1748 ; jz DO_INSTALL ;hooked in the chain
1749 ; *********************** CNS *************************************************
1750
1751 .IF <Z> ;AN000
1752
1753 ;Install NLSFUNC
1754 mov al,2fh ;Get interrupt
1755 mov ah,GET_INT ;2f in the chain
1756 int 21h
1757 mov word ptr INT_2f_NEXT+2,ES ;store the address
1758 mov word ptr INT_2f_NEXT,BX ;to make the current
1759 push ds ;2f handler next in
1760 push cs ;the chain
1761 pop ds ;set Dataseg to the Code
1762 mov dx,offset NLSRES_CODE ;give start address
1763 mov al,2fh ;of resident logic
1764 mov ah,SET_INT ;set the 2f in the
1765 int 21h ;chain
1766 pop ds ;restore original ds
1767 ;terminate &
1768 ;stay
1769 ;FREE THE ENVIRONMENT ;no then install
1770
1771 ; push ax ;AN004;save existing values
1772 ; push es ;
1773 ; mov ah,49H ;AN004;make the free allocate mem func
1774 ; mov es,es:[2ch] ;AN004;get the segment address
1775 ; int 21h ;
1776 ; pop es ;AN004;restore existing values
1777 ; pop ax ;
1778
1779 .ELSE ;AN000;
1780 ;TBR Message retriever ;otherwise
1781 mov ax,ALLINS ;
1782 mov cx,1 ;
1783 mov bx,STDERR ;AN000;
1784 mov dl,no_input ;AN000;
1785 mov dh,UTILITY_MSG_CLASS ;AN000;
1786 mov ds,PATHSEG
1787 mov si,OFFSET PARMLIST2
1788 call SYSDISPMSG ;AN000;
1789 mov ERROR_CODE,80 ;UTILITY ERROR CODE
1790 stc
1791
1792 .ENDIF
1793
1794 ret
1795
1796 INSTALL_NLS ENDP
1797
1798 msg_services <LOADmsg> ;AN000;
1799 msg_services <DISPLAYmsg,CHARmsg> ;AN000;
1800 msg_services <nlsfunc.cl1,nlsfunc.cl2,nlsfunc.cla> ;AN000;
1801
1802 ;******************************** END OF NLS_INIT_CODE **************************
1803 NLS_INIT_CODE ENDS
1804 subttl stack
1805 page
1806
1807 STACK SEGMENT PARA STACK 'STACK'
1808 DB 512 DUP (?)
1809 STACK ENDS
1810
1811 END MAIN