summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM')
-rw-r--r--v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM1811
1 files changed, 1811 insertions, 0 deletions
diff --git a/v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM b/v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM
new file mode 100644
index 0000000..a855e3f
--- /dev/null
+++ b/v4.0/src/CMD/NLSFUNC/NLSFUNC.ASM
@@ -0,0 +1,1811 @@
1
2 PAGE ,132 ;
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;*************************************************************************
21subttl get extended country data
22page
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****************************************
216subttl Revision History
217page
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;*******************************************************************************
275subttl macros
276page
277PUSHALL 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
283POPALL 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
298EXTRN SYSPARSE:NEAR
299
300subttl NLSFUNC data
301page
302NLS_DATA SEGMENT byte PUBLIC 'DATA'
303
304;Copyright 1988 Microsoft
305;***************************** MSG DATA ************************************
306UTILITY db "NLSFUNC",0 ;AC000;
307;***************************** MSG DATA ************************************
308
309.xlist
310include copyrigh.inc ;AN000;
311include struc.inc
312include DOESMAC.INC
313include MULT.INC
314include sf.inc ;AN001;
315include DOSCNTRY.INC
316include DEVSYM.INC
317include SYSMSG.INC ;AN000;
318include FUNCDBCS.INC ;AN000;
319include MSG2NLS.INC
320include FUNCPARM.INC ;AN000;
321
322MSG_UTILNAME <NLSFUNC> ;AN000;
323
324.list
325MULT_NLSFUNC equ 14h
326INSTALLED equ 0ffh
327; nlsfunc function codes
328CHG_CODEPAGE equ 1
329GET_EXT_CTY_INFO equ 2
330SET_CODEPAGE equ 3
331GET_CTY_INFO equ 4
332
333INVALID_FUNCTION equ 1 ;=J
334INVALID_DATA equ 13 ;=L
335;FILE_NOT_FOUND equ 2 ;=J(=L no longer explicitly used)
336;TAB equ 9
337;CR equ 13
338PAD_CHAR equ ' ' ;AN000;
339BAD_INVOKE equ 65 ;=E
340UPCASE_A equ 'A'
341BUFFSIZE equ 512 ; ;AC000;REDUCTION OF ORIGINAL (128 BYTES) TO STORE
342LOCATE_INFOTYPE equ 18 ;THE DEVICE LIST & THE OLD COUNTRY INFO
343CTL_BUFF equ 256 ; ;AC000;
344ID_TAG equ 8
345DATA_BUFF_LENG equ (BUFFSIZE - CTL_BUFF)
346MAXBUFF_FIT equ (BUFFSIZE - (CTL_BUFF + ID_TAG))
347DATA_N_ID equ (CTL_BUFF + ID_TAG)
348SETCTY_LENG equ 38
349;SPACE equ ' '
350BACKSLASH equ '\'
351PERIOD equ '.'
352;COLON equ ':'
353;
354;**************** NEW VARIABLE ****************
355subttl NLSFUNC data
356page
357IN_DEX equ bp ;AN000;
358FILESPEC_PTR equ byte ptr ds:[in_dex] ;AN000;
359FILEVAL equ 0100h ;convert data block after checking for the
360 ;AN000;
361 ;drive only to look for the filespec
362CL_NUM equ 81h ;command line at the PSP
363 ;AN000;
364;**************** NEW VARIABLE ****************
365;interrupts
366SET_INT equ 25h
367GET_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
380MSG_SERVICES <MSGDATA>
381
382ID_CHECK db 1 ;resident variable re-initialize
383ALL_DONE db 0 ;resident variable re-initialize
384GET_EXT db 0 ;resident variable re-initialize
385INFO_ID db 0 ;resident variable re-initialize
386DONT_CLOSE db 0 ;if open or close error,this is set
387
388RES_PARASIZE dw 0 ;adjusted size for terminate & stay func.
389ERROR_CODE db 0 ;contains extended error code val
390FUNC_CODE db 0 ;save function number
391GOOD_PAR db 0
392PARSE_ERR db 0
393
394SI_DOSLOCATE dw 0
395DS_DOSLOCATE dw 0
396SAVEDX dw 0 ;=FC file offset
397SAVECX dw 0 ;=FC
398NOFFSET dw 2 ;=FC
399CSIZE dw 0
400CCODE dw 0
401CPAGE dw 0
402VALID_FUNC db 0 ;Flag to check for valid function #
403EXIT_STAY db 0
404FILENAME db "COUNTRY.SYS",0
405PATH_SPEC db 64 dup(0) ;used to build path parameter
406USER_PATH db 0 ;=I
407PAR_RETC dw 0
408NO_PARMS db 0
409GOOD_PATH db 0
410PATHSEG DW 0
411SW_SPEC dW 0
412LENGTH_HOLD db 0
413;***CNS
414CUR_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000
415OLD_PTR DW 0 ;AN003;; keeps track of parameter position ;AN000
416;***CNS
417;********************************************************************************
418NLS_BUFFER db BUFFSIZE dup (?) ;NLS BUFFER to transfer data
419
420
421DATASIZE equ $-NLS_DATA
422
423NLS_DATA ENDS
424
425NLS_INIT_CODE SEGMENT BYTE PUBLIC 'CODE'
426
427 ASSUME CS:NLS_INIT_CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING
428
429
430
431INT_2f_NEXT DD ? ;Chain location.
432TEMPHOLD DW 0
433subttl resident code
434page
435;**************************** resident portion ********************************
436
437NLSRES_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
442IS_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
452SEL_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
493FUNCODE_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
503FUNCODE4: ;Get Country Data - old 38 call =F
504 mov bp,1 ;set info_id to 1 =F
505 jmp short FUNCODE2 ; =F
506
507
508FUNCODE3_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
523fc3_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
530FUNCODE2: ;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
540FUNCODE1: ;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
547CLOSE_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
555RES_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
565NC_IRET: ; =K
566 pop ds ;restore user's data segment =K moved
567 pop es ;=C =K moved
568 iret ;Return to DOS
569
570NO_CLOSE:
571 mov ALL_DONE,al ;=J
572 inc DONT_CLOSE
573
574;if an error was detected
575
576ERROR_ROUTINE:
577 mov al,ALL_DONE
578 cmp DONT_CLOSE,1
579 je RES_EXIT
580 jmp CLOSE_FILE
581
582
583NLSRES_CODE ENDP
584;*******************************END OF NLSRES_CODE******************************
585subttl resident main routine
586page
587;*******************************RES_MAIN****************************************
588RES_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
605RES_MAIN ENDP
606;*******************************END RES_MAIN************************************
607subttl check open procedure
608page
609;******************************CHECK OPEN PROCEDURE****************************
610CHK_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
617co_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
626co_user: lea dx,PATH_SPEC
627 CallInstall Dosopen,Multdos,38,<BX,DS,ES,SI,DI>,<DI,SI,ES,DS,BX>
628
629co_10: jc BADREP_FILE ;bx contains the
630 mov bx,ax ;file handle
631 jmp short END_OPEN
632
633BADREP_FILE:
634 mov ALL_DONE,al ;=J
635 inc DONT_CLOSE
636
637END_OPEN:
638 ret
639
640 CHK_OPEN ENDP
641;******************************END OF CHKOPEN**********************************
642subttl transfer country data
643page
644;******************************TRANS_CTY__DATA ********************************
645TRANS_CTY_DATA PROC NEAR
646
647TRANSTART:
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
657CHK_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
662GET_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
675COUNT_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
682FIND_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
701IN_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
712NEXT_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
721READERROR: pop cx ;=FC
722 jmp END_TRANS ;=FC
723
724FOUND_CTY2: mov dx,word ptr ds:[si+4] ;=FC from now on,this is
725 mov CPAGE,dx ;=FC the code page
726
727FOUND_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
733NUM_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
738SETDOSCTY_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
766CHK_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
782TRANSALL:
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
789GET_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
796SEEK_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
815IS_EXTENDED:
816 cmp GET_EXT,1
817 jne CHK_OVERWRITE
818 call GETEXT_CTY
819 jmp short SETDOSCTY_NEXT
820
821
822CHK_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
838DOS_MOVE:
839 call CHK_ADJUST ;now check to see if the entire
840 ;table fits
841
842SETDOSCTY_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
861CTLSEEKnREAD:
862 clc ;=G
863 jmp short END_TRANS ;exit
864
865
866
867DATASEEKnREAD:
868 mov ALL_DONE,al ;=J
869 pop cx
870 pop si
871 pop di
872 jmp short END_TRANS
873
874BAD_SETID:
875 mov ALL_DONE,INVALID_FUNCTION ;=J
876 jmp short FINDCTY_FAIL ;=J
877
878BAD_FILE:
879 mov ALL_DONE,INVALID_FUNCTION ;=J
880
881FINDCTY_FAIL:
882 stc
883
884END_TRANS:
885 pop di ;Restore header start
886 ret
887
888
889
890TRANS_CTY_DATA ENDP
891
892;******************************END TRANS_CTY_DATA ******************************
893subttl get DOS country destination
894page
895;****************************GETCTY_DEST***********************************************
896GetDOSCty_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
909GetCntryDest:
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
917GetCntryDest_1:
918 add di, NEW_COUNTRY_SIZE + 1 ;next data id
919
920GetCntryDest_loop:
921 loop GetCntryDest
922 stc
923 jmp short GetCntryDest_exit
924
925GetCntryDest_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
933GetCntryDest_OK1:
934
935 les di, dword ptr es:[di+1] ;get the destination in ES:DI
936 clc
937
938GetCntryDest_Exit:
939 pop cx
940 ret
941
942GetDOSCty_Dest endp
943;****************************GETDOSCTY_DEST*************************************
944subttl get extended country data
945page
946;****************************GETEXT_CTY*****************************************
947GETEXT_CTY proc
948
949JUSTONE_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
966ID_CTYINFO:
967 inc di ;=D (old code - add di,5) =F(moved).
968id_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
997id_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
1006TRUNC_SIZE:
1007 mov cx,bx ;=F
1008MOV_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
1013MOVE_CTY: pop bx ;=F
1014 mov CSIZE,cx ;=K
1015 add CSIZE,3 ;=K
1016 rep movsb
1017
1018GET_EXT_END:
1019 ret
1020
1021GETEXT_CTY endp
1022;*****************************END GETEXT_CTY*************************************
1023subttl read into control buffer
1024page
1025;**************************READ_CTLBUFF*****************************************
1026;
1027READ_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
1054NO_SEEK1:
1055 mov ALL_DONE,al ;=J
1056 jmp short RICB_exit
1057
1058NO_READ1:
1059 mov ALL_DONE,al ;=J
1060
1061RICB_exit: ;In this case 64 bytes
1062 ret
1063
1064READ_CTLBUFF endp
1065;****************************END READ_CTLBUFF***********************************
1066subttl check / adjust / move data into DOS buffer
1067page
1068;****************************CHK_ADJUST*****************************************
1069CHK_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
1086NEED_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
1104LAST_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
1109MOVE_DATA:
1110 rep movsb ;move data into DOS area
1111
1112ADJUST_END:
1113 pop ax
1114 ret
1115CHK_ADJUST ENDP
1116;*******************************END CHK_ADJUST *********************************
1117subttl walk through device drivers and invoke
1118page
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
1122WALK_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
1140char_test:
1141 test es:[di].sdevatt,devtyp ;check attribute word for
1142 jne open_device
1143 jmp GET_NEXT_DEVICE ;character device.
1144
1145OPEN_DEVICE:
1146 push si
1147 push di ;set up asciiz filename
1148 add di,10 ;for DOS file open
1149 mov cx,8
1150
1151set_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
1159done_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
1171end_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
1177INVOKE_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
1196invoke_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
1230NODBCS_CP:
1231 add cx,-2 ;AN002; reset counter before CP addition
1232
1233;****CHANGE
1234
1235DB_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
1258NO_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
1281CLOSE_DEVICE:
1282 CallInstall Dosclose,multdos,39,<DS,SI,ES,DI>,<DI,ES,SI,DS>
1283 jc dev_open_close_error ; ignore this =FC
1284
1285GET_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
1291DEVICE_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
1300dev_open_close_error:
1301 mov ALL_DONE,BAD_INVOKE
1302 jmp GET_NEXT_DEVICE
1303
1304END_WALK_DEVICES:
1305
1306
1307 ret
1308
1309WALK_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
1326Chk_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
1343Chk_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
1349Chk_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;
1356Chk_Rvst_Next: ;AN001;
1357 sub di, 4 ;AN001; move the pointer to the next entry
1358 jmp Chk_Rvst_While ;AN001;
1359Chk_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
1363Chk_Rvst_Ret: ;AN001;
1364 pop di ;AN001;
1365 pop es ;AN001;
1366 pop bx ;AN001;
1367 pop ax ;AN001;
1368 ret ;AN001;
1369Chk_Revisit endp
1370
1371subttl end nlsfunc resident code
1372page
1373 NLSRES_LENG equ $-NLSRES_CODE+DATASIZE
1374subttl initialization
1375page
1376;***************************** NLSFUNC Initialization **************************
1377
1378 ASSUME CS:NLS_INIT_CODE,SS:STACK
1379
1380
1381
1382MAIN 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
1429NO_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 *********************************************
1459subttl parse
1460page
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
1479PROCESS_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
1508RE_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
1733PROCESS_PATH ENDP
1734
1735;
1736
1737;****************************** CNS *******************************************
1738subttl install NLSFUNC
1739page
1740;******************************** INSTALL NLSFUNC *****************************
1741
1742INSTALL_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
1796INSTALL_NLS ENDP
1797
1798msg_services <LOADmsg> ;AN000;
1799msg_services <DISPLAYmsg,CHARmsg> ;AN000;
1800msg_services <nlsfunc.cl1,nlsfunc.cl2,nlsfunc.cla> ;AN000;
1801
1802;******************************** END OF NLS_INIT_CODE **************************
1803NLS_INIT_CODE ENDS
1804subttl stack
1805page
1806
1807STACK SEGMENT PARA STACK 'STACK'
1808 DB 512 DUP (?)
1809STACK ENDS
1810
1811 END MAIN