summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/FASTOPEN/FASTINIT.ASM')
-rw-r--r--v4.0/src/CMD/FASTOPEN/FASTINIT.ASM2970
1 files changed, 2970 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM b/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM
new file mode 100644
index 0000000..db21b58
--- /dev/null
+++ b/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM
@@ -0,0 +1,2970 @@
1 Page 84,132 ;
2
3TITLE FASTINIT - initialization code for FASTOPEN (May 13, 1988)
4
5;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
6; The entire Fastopen component is divided into 5 modules. They are:
7; Fastopen initialization routine-1, Fastopen initialization routine-2,
8; Fastopen which manages the directory/file cache buffers, the Fastseek
9; which manages the cluster information cache buffers and the
10; cache buffer which holds both directory and cluster information.
11;
12; These modules resides in different segments for the reason that they can
13; be overlayed conditionally, depending on the user request. For example
14; initially all segments are loaded into the memory. If fastopen reature is
15; not requested, the segment which contains Fastseek will be overlayed over
16; original Fastopen to save space. Segmentation is also usefull when Fastopen
17; and Fstseek need to copy into Expanded memory. Following figure shows
18; memory map of the FastOpen.
19;
20; Modules Segment
21;
22; Ú-------------------¿
23; ³ MAIN ³ CSEG_MAIN
24; Ã-------------------´
25; ³ FASTINIT1 ³ CSEG_MAIN
26; Ã-------------------´
27; ³ ³
28; ³ FASTOPEN ³ CSEG_OPEN
29; ³ ³
30; Ã-------------------´
31; ³ ³
32; ³ FASTSEEK ³ CSEG_SEEK
33; ³ ³
34; Ã-------------------´
35; ³ FASTINIT2 ³ CSEG_INIT
36; Ã-------------------´
37; ³ ³
38; ³ NAME AND ³
39; ³ EXTENT ³
40; ³ CACHE BUFFERS ³ CSEG_INIT
41; ³ ³
42; À-------------------Ù
43;
44; MAIN: This module provides DOS entry point into FASTOPEN. It also
45; dispatch various Fastopen and Fastseek functions. This module is
46; in the file FASTOPEN.asm
47;
48; FASTINIT-1: This module is called INIT_TREE which is also a part of the
49; Cseg_Main segment. This basically initializes both
50; Name and Extent drive headers, and sets up name and extent
51; cache buffers. This module can be found in the file
52; FASTINIT.asm
53;
54; FASTINIT-1: This module is called INIT which is part of the Cseg_Init
55; segment. This module parses the user commad, check memory
56; requirements, overlay Fastopen and Fastseek code and finally
57; installs the Fastopen to be stay resident. This module is
58; eventually overlayed by the cache buffers created during the
59; buffer initialization by FASTINIT-1 ( See INIT_TREE)
60; This module can be found in FASTINIT.asm
61;
62; FASTOPEN: This module is a collection of four Fastopen functions which
63; manage the File/Directory cache buffers. These functions are
64; in the file FASTOPEN.asm
65;
66; FASTSEEK: This module is a collection of six FastSeek functions which
67; manage queues associated with the cluster information
68; cache buffers. This module is found in the file FASTSEEK.asm.
69;
70;
71; Fastopen Code and Cache buffer Relocation
72; -----------------------------------------
73; If user specifies both n and m in the user command and /x, then
74; Cseg_Open, Cseg_Seek and Cseg_Init will be copied into a 16K page of the
75; Expanded Memory. If only n is specified, then Cseg_Open and Cseg_Init will
76; be copied. If only m is specified, then Cseg_Seek and Cseg_init will be
77; copied. After this the total size of the segments transferred will be
78; deblocked from the low memory to save available user space.
79;
80; If /x is not specified and only n is specified, then the Cseg_Init will
81; moved over to Cseg_Seek which is followed by a deblock of memory. If only
82; m is specified, then Cseg_Seek will moved over to Cseg_Open and the
83; Cseg_Init will be moved over to Cseg_Seek then deblocks the size Cseg_Open.
84;
85; WARNING: After every move you have to recalculate the Seg ID of moved
86; modules depending on how far it has been displaced and then
87; replace the Seg ID in the jump vectors used for accessing
88; functions in the moved modules. A wrong Seg ID can cause
89; instant System CRASH ...@%+(@!$#@@*&...
90;
91; Future Enhancements:
92;
93; 1. Modify Fastopen so that it can be run on removable media (Diskette).
94; At present only fixed disk is supported.
95;
96; 2. Allocate all Extent buffers during initialization. Now they are
97; done in run time. This may avoid using flags (-2) for discontinuous
98; buffers. Using (-2) requires buffers be filled with '0's during PURGE.
99;
100; 3. Mark the LRU extent every time buffer is changed, so that the
101; the buffers need not be searched during buffer recycling
102;
103; 4; Currently Fastopen code and cache is kept in one 16K page of the
104; Extended Memory. This puts a restriction on the size of the cache
105; buffer available in EMS usually about 8K. This can be avoided by
106; keeping code and cache buffers in two seperated pages, so that maximum
107; of 16K is available for cache buffers.
108;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
109;
110IF1
111 %OUT ASSEMBLING: FASTINIT - FASTOPEN initialization
112ENDIF
113NAME FASTINIT
114
115.XCREF
116.XLIST
117
118
119TRUE EQU 0FFFFh ;AN000;
120FALSE EQU 0 ;AN000;
121
122DBCS = FALSE ;AN000;
123Installed = TRUE ;AN000;
124
125IFNDEF DEBUG
126 DEBUG = FALSE
127ENDIF
128
129INCLUDE dosmac.inc ;AN000;
130INCLUDE vector.inc ;AN000;
131INCLUDE filemode.inc ;AN000;
132INCLUDE mult.inc ;AN000;
133include version.inc
134
135.LIST
136.CREF
137
138INCLUDE fastsegs.inc ;AN000;
139INCLUDE fastopen.inc ;AN000;
140INCLUDE SYSCALL.INC ; ;AN000;
141
142;-----------------------------------------------------------------------
143; EQUATES
144;-----------------------------------------------------------------------
145Top_mem EQU 02h ;Top of memory index in PSP ;AN000;
146Min_entry_num EQU 10 ;minimum name cache entries ;AN000;
147Max_entry_num EQU 999 ;maximum name cache entries ;AN000;
148Default_names EQU 34 ;default name cache entries ;AN000;
149Debug EQU 0 ;for callinstall ;AN000;
150Len_source_xname EQU 4 ;used for xname translate ;AN000;
151No_siblings EQU -1 ;indicate no siblings ;AN000;
152No_child EQU -1 ;indicate no children ;AN000;
153No_backward EQU -1 ;no backward pt yet ;AN000;
154Max_drives EQU 24 ;maximum number of drives allowed ;AN000;
155
156
157; ----------------- MESSAGE EQUATES -------------------------------------
158
159Not_enough_mem EQU 2 ;AN000;
160Invalid_switch EQU 3 ;AN000;
161Install1 EQU 4 ;AN000;
162Already_install EQU 5 ;AN000;
163Incorrect_param EQU 6 ;AN000;
164Too_many_entries EQU 7 ;AN000;
165Dup_drive EQU 8 ;AN000;
166Invalid_extent EQU 11 ;AN000;
167Invalid_name EQU 12 ;AN000;
168Ems_failed EQU 13 ;AN000;
169Ems_not_install EQU 14 ;AN000;
170Invalid_drive EQU 15 ;AN000;
171No_page_space EQU 16 ;AN000;
172Bad_Use_Message EQU 17
173Many_Ext_Entries EQU 18
174Many_Name_Entries EQU 19
175
176
177;------------ E M S SUPPORT EQUATES -------------------------------
178
179EMS_GET_STATUS EQU 40H ;AN000;
180EMS_GET_NUM_PAGES EQU 42H ;AN000;
181EMS_ALLOC_PAGES EQU 43H ;AN000;
182EMS_MAP_HANDLE EQU 44H ;AN000;
183EMS_GET_VERSION EQU 46H ;AN000;
184EMS_SAVE_STATE EQU 47H ;AN000;
185EMS_RESTORE_STATE EQU 48H ;AN000;;AN000;
186EMS_PAGE_SIZE EQU 4FH ;AN000;;AN000;
187EMS_2F_HANDLER EQU 1BH ;AN000;;AN000;
188
189IF NOT IBMCOPYRIGHT
190
191EMS_GET_COUNT EQU 5801H
192
193ELSE
194
195EMS_GET_COUNT EQU 5800H ;AN000;
196
197ENDIF
198
199EMS_GET_FRAME_ADDR EQU 5800H ;AN000;
200EMS_HANDLE_NAME EQU 53H
201EMS_INT EQU 67H ;AN000;
202SINGLE_SEGMENT EQU 1 ;AN000;
203
204
205;-------------------- STRUCTURES ---------------------------------
206
207PAGE_FRAME_STRUC STRUC ; EMS page frame structure ;AN000;
208
209 PAGE_SEG DW ? ;EMS page segment ;AN000;
210 PAGE_NUM DW ? ;EMS page number (only one page is used) ;AN000;
211
212PAGE_FRAME_STRUC ENDS
213
214BUFFER_ENTRY_SIZE EQU TYPE PAGE_FRAME_STRUC
215
216
217SUB_LIST STRUC ; Message handler sublist structure ;AN000;
218 DB 11 ; ;AN000;
219 DB 0 ; ;AN000;
220DATA_OFF DW 0 ; offset of data to be inserted ;AN000;
221DATA_SEG DW 0 ; offset of data to be inserted ;AN000;
222MSG_ID DB 0 ; n of %n ;AN000;
223FLAGS DB 0 ; Flags ;AN000;
224MAX_WIDTH DB 0 ; Maximum field width ;AN000;
225MIN_WIDTH DB 0 ; Minimum field width ;AN000;
226PAD_CHAR DB 0 ; character for pad field ;AN000;
227SUB_LIST ENDS ;AN000;
228
229;-------------------------------------------------------------------------------
230; Following two segments are used to define external variable that
231; are defined in two other segments.
232;-------------------------------------------------------------------------------
233
234CSEG_OPEN SEGMENT PARA PUBLIC 'CODE' ; Cseg_Open segment
235 EXTRN Open_name_cache_seg:word
236 EXTRN Open_Name_Drive_Buff:word
237 EXTRN End_Open:byte
238 EXTRN Chk_Flag:word
239 EXTRN VECTOR_LOOKUP:dword ; jump vector inside Cseg_Main to make
240 ; a FAR call to Fopen LookUp function within
241 ; the segment
242CSEG_OPEN ENDS
243
244
245CSEG_SEEK SEGMENT PARA PUBLIC 'CODE' ; Cseg_Seek segment
246 EXTRN Seek_Extent_Drive_buff:word
247 EXTRN Seek_Name_Drive_buff:word
248 EXTRN Seek_Name_Cache_buff:word
249 EXTRN Seek_Name_Cache_Seg:word
250 EXTRN Seek_Num_Of_Drives:word
251 EXTRN Seek_Total_Ext_Count:word
252 EXTRN Seek_Total_Name_Count:word
253 EXTRN End_Seek:byte
254 EXTRN Check_Flag:word
255 EXTRN VECTOR_DELETE:dword ; jump vector inside Cseg_Seek to make
256 ; a FAR call to FSeek Delete function within
257 ; the segment
258CSEG_SEEK ENDS
259
260
261
262
263
264;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
265CSEG_MAIN SEGMENT PARA PUBLIC 'CODE' ; MAIN segment
266
267; This segment is a continuation of the Cseg_Main segment in Fastopen.asm
268; and contains code to initializes name and extent drive buffers
269;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
270ASSUME CS:cseg_main,DS:nothing,SS:stack,ES:nothing
271
272EXTRN MAIN:FAR ;AN000;
273
274IF BUFFERFLAG
275
276extrn restore_page_state:near ; HKN 8/25/88
277
278extrn ems_save_handle1:word ; HKN
279extrn ems_page_number:word ; HKN
280
281ENDIF
282
283EXTRN Main_Total_Ext_Count:word ;AN000;
284EXTRN Main_Total_Name_Count:word ;AN000;
285EXTRN Main_Name_Drive_Buff:word ;AN000;
286EXTRN Main_Name_Cache_Buff:word ;AN000;
287EXTRN Main_Name_Cache_Seg:word ;AN000;
288EXTRN Main_Parambuff:byte ;AN000;
289EXTRN Main_extent_drive_Buff:word ;AN000;
290EXTRN Main_Num_Of_drives:word ;AN000;
291EXTRN Main_Ext_Count:word ;AN000;
292EXTRN Main_Ext_Cache_Size:word ;AN000;
293EXTRN Main_EMS_FLAG:word ;AN000;
294EXTRN Main_Res_Segs:word ;AN000;
295EXTRN Main_EMS_PAGE_SEG:word ;AN000;
296EXTRN Main_EMS_PAGE_SIZE:word ;AN000;
297
298EXTRN FOPEN_Insert:dword ;AN000;
299EXTRN FOPEN_Update:dword ;AN000;
300EXTRN FOPEN_Delete:dword ;AN000;
301EXTRN FOPEN_Lookup:dword ;AN000;
302IF BUFFERFLAG
303EXTRN FOPEN_Purge:dword
304ENDIF
305
306EXTRN FSEEK_Open:dword
307EXTRN FSEEK_Close:dword
308EXTRN FSEEK_Insert:dword
309EXTRN FSEEK_Delete:dword
310EXTRN FSEEK_Lookup:dword
311EXTRN FSEEK_Truncate:dword
312EXTRN FSEEK_Purge:dword
313
314;*************************************************************************
315;
316;SUBROUTINE: INIT_TREE (FASTINIT-1)
317;
318;FUNCTION: This routine builds 'N' name directory buffers under each drive
319; header. The second half of this routine initializes the extent
320; drive headers and makes the Fastopen code resident.
321;
322;INPUT: Drive_cache_header, End_Caches
323;
324;OUTPUT: Name_cache and Extent Cache entries installed for every
325; drive requested.
326;
327;*************************************************************************
328 IF ($-Cseg_Main) MOD 16 ;AN000;
329 ORG ($-Cseg_Main)+16-(($-Cseg_Main) MOD 16) ;AN000;
330 ENDIF ;AN000;
331End_Main1 label word ;AN000;
332
333
334INIT_TREE:
335 mov ax,cseg_Main ;get addressiblity to ;AN000;
336 mov ds,ax ;DS --> Cseg_Main ;AN000;
337 ASSUME ds:cseg_Main ;AN000;
338
339 cmp Main_Total_Name_Count,0 ;initialize Name drive headers?? ;AN000;
340 je Init_Ext_Drive_Hdrs ;no, init extent drive headers ;AN000;
341
342;-----------------------------------------------------------------------------
343; Following code adds 'n' directory entry buffers to each Name Drive headers,
344; depending on the value of 'n' specified with each drive ID
345;-----------------------------------------------------------------------------
346 mov si,Main_Name_Drive_Buff ;SI-->first Name drive cache buff
347 mov bx,Main_Name_Cache_Buff ;BX-->Name cache buffer
348 xor dx,dx
349 xor ax,ax
350
351 mov ax,Main_Name_Cache_Seg ;get addresability to CSeg_Init
352 mov ds,ax ;DS=addressablity to Cseg_Init
353 ASSUME ds:cseg_Init
354
355Set_Up_Cache:
356 mov [si].DCH_LRU_ROOT,bx ;set to point to first name
357 mov [si].DCH_NAME_BUFF,bx ;set to point to first name
358 mov cx,[si].DCH_num_entries ;get number of name records
359
360;-----------------------------------------------------------------------------
361; set up MRU and LRU pointers
362; AX points to last name record
363; BX points to current name record
364; DX points to next name record
365;-----------------------------------------------------------------------------
366 mov [bx].nMRU_ptr,-1 ;make first MRU -1
367 jmp short set_start
368
369Set_Up_Names:
370 mov [bx].nMRU_ptr,ax ;set up MRU
371 add ax,size name_record
372
373Set_Start:
374 mov [bx].nChild_ptr,no_child ;no children or siblings
375 mov [bx].nsibling_ptr,no_siblings ; right now
376 mov [bx].nBackward_ptr,no_backward
377 push es
378 push di
379 push ax
380
381 push ds
382 pop es ;ES-->name cache buffer
383 ASSUME es:Cseg_Init
384
385 mov ax, ' '
386 mov di, bx
387 add di, nCmpct_Dir_Info ;blank out the Dir name area
388 stosb ;the directory buffer
389 stosw
390 stosw
391 stosw
392 stosw
393 stosw
394
395 pop ax
396 pop di
397 pop es
398
399 mov dx,bx ;get name offset
400 add dx,size name_record ;get start of next name
401 dec cx ;decrement num_entries
402 jcxz get_next_drive ;if zero - get next drive
403 mov [bx].nLRU_ptr,dx ;LRU pointer - next name
404 add bx,size name_record ;
405 jmp set_up_names
406
407Get_Next_Drive:
408 mov [bx].nLRU_ptr,-1 ;LRU pointer - next name
409
410 mov [si].DCH_MRU_ROOT,bx ;set to point to last name
411 mov bx,dx ;get pointer to next name
412 cmp [si].dch_sibling_ptr,no_siblings ;is there any more to set up??
413 jz Init_Ext_Drive_Hdrs ; no - set extent drive headers
414 add ax,size name_record ; yes - get next name directory buffer
415 add si,size drive_cache_header ;point to next drive header
416 jmp set_up_cache
417
418
419;----------------------------------------------------------------------------
420; The following section initializes the Extent Drive Headers.
421; DS has addressability to MAIN segment (CSEG_MAIN) and ES has
422; addressability to Cache buffer segment (CSEG_INIT)
423;----------------------------------------------------------------------------
424Init_Ext_Drive_Hdrs:
425 mov ax,cseg_Main ;AN000;
426 mov ds,ax ;DS-->Cseg_Main ;AN000;
427 ASSUME ds:cseg_Main ;AN000;
428 ;AN000;
429 cmp Main_Total_Ext_Count,0 ;initialize extent drive buffers ?? ;AN000;
430 jne init_extent_cache ;yes - continue
431 jmp Init_exit ;no - exit ;AN000;
432
433;============================================================================
434; Fill extent cache buffer with zeros. Otherwise a (-2) left in the buffer
435; could generate a wrong Free buffer pointer since (-2) is the free buffer
436; mark.
437
438Init_Extent_Cache:
439 mov cx, Main_Ext_Cache_Size ; CX = extent buffer size ;AN000;
440 mov si,Main_Extent_Drive_Buff ; SI-->start of extent cache buff ;AN000;
441 push ds ;AN000;
442 mov ax,Main_Name_Cache_Seg
443 mov ds,ax ; DS-->new init seg (init segment ;AN000;
444 ASSUME ds:Cseg_Init ;AN000;
445 mov al,0 ; pattern "0" ;AN000;
446
447Next_Byte: ; may be in Extended memory)
448 mov [si],al ;AN000;
449 inc si ;AN000;
450 LOOP next_byte ;AN000;
451 pop ds ; retore original init seg ID ;AN000;
452;============================================================================
453
454
455Init_Set_Cache:
456 mov si,Main_Extent_Drive_Buff ; SI-->first extent drive header ;AN000;
457 mov cx,Main_num_of_drives ; number of drives
458 mov dx,0 ; drive counter
459 lea di,Main_ParamBuff ; DS:DI-->parameter buff contains ;AN000;
460 ; drive ID and number of extents ;AN000;
461 mov es,Main_name_cache_seg ; ES = addressability to Cseg_Init ;AN000;
462 ASSUME es:Cseg_Init ; ;AN000;
463 ;AN000;
464INIT_LOOP: ; ES:SI-->cache buffer ;AN000;
465 push cx ; save counter ;AN000;
466 add di,dx ; points to drive ID of this driv ;AN000;
467 xor ax,ax ;AN000;
468 mov ax,[di+2] ; get Extent Count ;AN000;
469 cmp ax, -1 ; any extent under this drive ?? ;AN000;
470 je skip_this_drive ; no - dont create header for this ;AN000;
471 ; this drive
472 mov ax,0 ; *** for debugging sequence count
473 mov es:[si].EXTENT_COUNT,ax ; *** use this area for sequence counting
474 xor ax,ax ;AN000;
475 mov ax,[di] ; get drive ID from drive ID buff ;AN000;
476 mov es:[si].DRIVE_NUMBER,ax ; save drive ID in drive header ;AN000;
477 mov bx, size Drive_Header ;AN000;
478 add bx,si ; BX-->Free area ;AN000;
479 mov es:[si].FREE_PTR,bx ; pointing to free area ;AN000;
480 ;AN000;
481 mov es:[si].MRU_HDR_PTR,-1 ; mark OPEN QUEUE empty ;AN000;
482 mov es:[si].CLOSE_PTR,-1 ; make CLOSE QUEUE empty ;AN000;
483 xor ax,ax ;AN000;
484 mov ax,[di+2] ; get extent count (n) ;AN000;
485 mov cx, size Extent_Header ; get extent size ;AN000;
486 mul cx ; AX=total cache for this drive ;AN000;
487 mov es:[si].BUFF_SIZE,ax ; save it as initial available size ;AN000;
488 mov es:[si].FREE_SIZE,ax ; save it as initial free size
489 add ax, size Drive_Header ; (2/9/88)
490 add ax,si ; AX-->offset to next drive hdr ;AN000;
491 mov es:[si].Next_Drv_hdr_Ptr,ax ; save next drive header ptr in ;AN000;
492 ; current drive header ;AN000;
493 mov bx,ax ;AN000;
494 mov ax,si ; save current header pointer ;AN000;
495 mov si,bx ; DS:SI-->next drive header ;AN000;
496 ;AN000;
497SKIP_THIS_DRIVE: ;AN000;
498 add dx,4 ; update index to next drive/extent ;AN000;
499 pop cx ; restore loop count ;AN000;
500 LOOP init_loop ; repeat for next drive number ;AN000;
501 ;AN000;
502 mov si,ax ;AN000;
503 mov es:[si].Next_Drv_hdr_Ptr,-1 ; mark current header as last
504 ; drive header
505;----------------------------------------------------------------------------
506; Close handles 0 - 4
507;----------------------------------------------------------------------------
508 mov bx,0
509Handle_Loop:
510 mov ah,03EH
511 INT 21H
512 inc bx
513 cmp bx,5
514 jne Handle_Loop
515
516;----------------------------------------------------------------------------
517; Get PSP segment and find the program environment segment and deallocate
518; the environment space.
519;----------------------------------------------------------------------------
520INIT_EXIT:
521 push ds
522 mov si,0081H
523 mov ah,62H
524 INT 21H ; get program PSP segment ;AN000;
525
526 mov ds,bx ; DS = PSP segment ;AN000;
527 mov si,02CH ; SI-->address of enviroment segment
528 mov ax,[si] ; AX = environment seg id
529 cmp ax,0 ; environment present ??
530 je dont_dealloc ; no - dont deallocate
531 mov es,ax
532 mov ah,49H
533 INT 21H ; deallocate environment
534Dont_Dealloc:
535 pop ds ; restore DS
536
537;----------------------------------------------------------------------------
538; Keep resident the Fastopen code and cache buffers. The size of the resident
539; area is in (Main_Res_Segs). Size may vary depending on whether Fastopen or
540; Fastseek or both or extent memory is specified.
541;----------------------------------------------------------------------------
542
543IF BUFFERFLAG
544
545 call restore_page_state ; HKN 8/25/88
546
547ENDIF
548
549 mov ah,KEEP_PROCESS ;remain resident
550 mov al,0 ;return code
551 mov dx,Main_Res_Segs ;size of area in paragraph
552 INT 21h ;keep resident and then return
553 ;control to DOS
554
555;----------------------------------------------------------------------------
556; Calculate the size of the MAIN module in bytes. First potion of this
557; segment can be found in the Fastopen.asm
558;----------------------------------------------------------------------------
559 IF ($-Cseg_Main) MOD 16 ;AN000;
560 ORG ($-Cseg_Main)+16-(($-Cseg_Main) MOD 16) ;AN000;
561 ENDIF ;AN000;
562End_Main label word ;AN000;
563
564
565CSEG_MAIN ENDS ; End of Cseg_Main segment
566page
567
568
569;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
570
571CSEG_INIT SEGMENT PUBLIC PARA 'CODE'
572
573;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
574 ASSUME cs:cseg_init,ds:cseg_init,ss:stack,es:cseg_init
575
576 EXTRN SYSPARSE:NEAR ;AN000;
577 EXTRN SYSLOADMSG:NEAR ;AN000;
578 EXTRN SYSDISPMSG:NEAR ;AN000;
579
580IF BUFFERFLAG
581 extrn save_ems_page_state:far ; HKN 8/25/88
582ENDIF
583
584
585;----------------------------------------------------------------------------
586; The cache buffers start from the first location of Cseg_Init.
587; First portion is the NAME DRIVE HEADERS, which is followed by
588; NAME CACHE BUFFER, which is followed by EXTENT DRIVE HEADER. Under each
589; extent drive header its cache buffer. 24 Name drive buffers are allocated
590; during assembly time. Remaining drive and cache buffers are allocated
591; during run time. Eventhough 24 name cache buffers are allocated during
592; assembly time, this number may be reduced to the specified number of drive
593; numbers during run time by overlaying other drive buffers over the unused ones.
594; The initialization code will be overlayed by name and extent cache buffs
595; during second half of the initialization which is in the MAIN module (see INit_Tree).
596;-----------------------------------------------------------------------------
597
598Drive_header_start label byte ;Name cache drive buffer
599Drive_Cache Drive_Cache_Header max_drives DUP (<>) ; header for 24 drives are reserved
600
601;-----------------------------------------------------------------------------
602; Anything below this point will be overlayed by the Cache Buffers
603; MSG retriever is placed after Cache buffer, so that the area can be
604;-----------------------------------------------------------------------------
605;=============================================================================
606; Non_Resident Data Area
607;=============================================================================
608INIT_VECTOR DD INIT_TREE ;jump vector to INIT_TREE ;AN000;
609MAIN_VECTOR DD MAIN ;entry point to MAIN routine ;AN000;
610source_xname DB " :\",0 ;used for xname translate ;AN000;
611target_xname DB 65 DUP (0) ;used for xname translate ;AN000;
612user_drive db 0 ;current user drive ;AN000;
613psp_seg dw 0 ;segment of psp ;AN000;
614stack_seg_start dw 0 ;segment of temporary stack ;AN000;
615stack_seg_end dw 0 ;AN000;
616num_of_drives dw 0 ;number of user specified drives ;AN000;
617Ext_Mem dw 0 ;=1 if exteded memory is enabled ;AN000;
618drive_id db " :",0 ;AN000;
619Parambuff db 50 dup (0)
620Parmbuff_Ptr dw 0 ;AN000;
621FRAME_COUNT dw 0 ;EMS frame count
622
623IF IBMCOPYRIGHT
624
625FRAME_BUFFER DB 30h DUP(0) ;EMS frame buffer
626
627ELSE
628
629FRAME_BUFFER DB 100h DUP(0) ; EMS frame buffer
630
631ENDIF
632
633IF BUFFERFLAG
634FST_PAGE DW 0,0 ; holds the second highest page above 640k
635ENDIF
636
637Cmdline_buff db 135 dup (0) ;command line buffer ;AN000;
638name_cache_seg dw Cseg_Init ;default to Init1 seg ;AN000;
639Ext_Count dw 0 ;total name extent entries ;AN000;
640extent_drive_Buff dw 0 ;ptr to extent drive ;AN000;
641name_cache_Buff dw 0 ;pointer to Name cache buffer ;AN000;
642EMS_FLAG dw 0 ;EMI flag 1= if EMI is enabled ;AN000;
643CHECK_QUEUE dw 0 ; = 1 if analyser is activated
644RES_SEGS dw 010H+020H ;PSP SIZE + STACK SIZE resident segment size
645EMS_PAGE_SEG DW 0 ;EMS code page segment ID ;AN000;
646EMS_PAGE_NUM DW 0 ;EMS physical page number ;AN000;
647Total_Ext_Count DW 0 ;Total extent entry count ;AN000;
648Total_Name_Count DW 0 ;Total Name entry count ;AN000;
649Total_Cache_Size DW 0 ;Total cache buffer size (name+extent) buffer ;AN000;
650Name_Cache_Size DW 0 ;Total name cache size (header + entry buffs)
651Name_Count DW 0 ;name entry count
652Name_Drive_Buff DW 0 ;name driver buffer address ;AN000;
653Ext_Cache_Size DW 0 ;extent buffer size ;AN000;
654Open_SegID DW 0 ;SegId of Cseg_Open after relocation ;AN000;
655Seek_SegID DW 0 ;SegId of Cseg_Seek " " ;AN000;
656Init_SegID DW 0 ;SegId of Cseg_Init " " ;AN000;
657MAIN_Size DW 0 ;size of Cseg_Main in Paragraph ;AN000;
658OPEN_Size DW 0 ;size of Cseg_Open in paragraph ;AN000;
659SEEK_Size DW 0 ;size of Cseg_Seek in paragraph ;AN000;
660
661;-----------------------------------------------------------------------;
662; EMS Support ;
663;-----------------------------------------------------------------------;
664EXT_HANDLE DW ? ; EMS handle for reference ;AN000;
665EMS_PAGESIZE DW ? ; EMS handle for reference ;AN000;
666EMS_FRAME_ADDR DW ? ; EMS handle for reference ;AN000;
667CURR_EMS_PAGE DB ? ; Current EMS page number ;AN000;
668HANDLE_NAME DB 'FASTOPEN',0 ; EMS handle name ;AN000;
669
670IF BUFFERFLAG
671SAVE_MAP_ADDR DD ? ; HKN 8/25/88
672ENDIF
673
674;---------------------------------------------------------------------------
675; PARSER Support
676;---------------------------------------------------------------------------
677CURRENT_PARM DW 81H ;POINTER INTO COMMAND OF CUREENT OPERANT ;AN000;
678NEXT_PARM DW 0 ;POINTER INTO COMMAND OF NEXT OPERAND ;AN000;
679ORDINAL DW 0 ;ORDINAL NUMBER OF MAIN PARSER LOOP ;AN000;
680ORDINAL1 DW 0 ;ORDINAL NUMBER OF COMPLEX ITEM LOOP ;AN000;
681PREV_TYPE DB 0 ;PREVIOUS POSITIONAL PARAMETER TYPE
682
683;---------------------------------------------------------------------------
684; PRINT_STDOUT input parameter save area
685;----------------------------------------------------------------------------
686SUBST_COUNT DW 0 ;message substitution count ;AN000;
687MSG_CLASS DB 0 ;message class ;AN000;
688INPUT_FLAG DB 0 ;Type of INT 21 used for KBD ;AN000;
689MSG_NUM DW 0 ;message number ;AN000;
690
691
692;----------------------------------------------------------------------------
693; Following three sublists are used by the Message Retriever
694;----------------------------------------------------------------------------
695SUBLIST1 LABEL DWORD ;SUBSTITUTE LIST 1
696 DB 11 ;sublist size ;AN000;
697 DB 0 ;reserved ;AN000;
698 DD 0 ;substition data Offset ;AN000;
699 DB 1 ;n of %n ;AN000;
700 DB 0 ;data type ;AN000;
701 DB 0 ;maximum field width ;AN000;
702 DB 0 ;minimum field width ;AN000;
703 DB 0 ;characters for Pad field ;AN000;
704
705
706SUBLIST2 LABEL DWORD ;SUBSTITUTE LIST 2
707 DB 11 ;sublist size ;AN000;
708 DB 0 ;reserved ;AN000;
709 DD 0 ;substition data Offset ;AN000;
710 DB 2 ;n of %n ;AN000;
711 DB 0 ;data type ;AN000;
712 DB 0 ;maximum field width ;AN000;
713 DB 0 ;minimum field width ;AN000;
714 DB 0 ;characters for Pad field ;AN000;
715
716
717
718;--------------------------------------------------------------------------
719; PARSER Control Blocks and Buffers
720;--------------------------------------------------------------------------
721
722PARMS label word
723 DW parmsx ;AN000;
724 DB 1 ; number of delemeters ;AN000;
725 DB 1 ; extra delimeters length ;AN000;
726 DB "=" ; extra delimeter expected ;AN000;
727 DB 0 ; extra end of line length ;AN000;
728 DB 0 ;AN000;
729
730
731PARMSX label byte ;AN000;
732par_min DB 1 ; min, max positional operands allowed ;AN000;
733par_max DB 2 ; min, max positional operands allowed ;AN000;
734 DW Pos1 ; offset into positonal-1 control block ;AN000;
735 DW Pos2 ; offset into positonal-1 control block ;AN000;
736par_sw DB 1 ; one switch ;AN000;
737 DW Switch ; offset into switch-1 control bloc ;AN000;
738 DB 0 ; no keywords ;AN000;
739 DB 0 ; 0 ;AN000;
740
741
742
743;------------------ POS2 CONTROL BLOCK --------------------------------------
744
745POS1 label word ; positional-1 control definition
746Pos1Type DW 0100H ; control type flag (drive only) ;AN000;
747 DW 0 ; function flags ;AN000;
748 DW Result ; offset into result buffer ;AN000;
749 DW value_pos1 ; offset value list buffer ;AN000;
750 DB 0 ; number of keyword/switch synonyms ;AN000;
751
752
753Value_Pos1 label byte ; postional parameter value expected ;AN000;
754 DB 0 ; no values expected ;AN000;
755
756
757
758;---------------- POS1 CONTROL BLOCK ----------------------------------------
759
760POS2 label word ; positional-2 control definition ;AN000;
761Pos2Type DW 08502H ; Control type (complex/integer/drive/ ;AN000;
762 ; repeat) ;AN000;
763 DW 0 ; function flags ;AN000;
764 DW Result ; offset into result buffer ;AN000;
765 DW value_pos2 ; offset value list buffer ;AN000;
766 DB 0 ; number of keyword/switch synonyms ;AN000;
767
768Value_Pos2 label byte
769 DB 0 ; either (n) or (m) will be returned
770
771
772
773;--------------- RESULT BUFFER ---------------------------------------------
774
775RESULT label byte ; postional2 parameter result buffer ;AN000;
776PosType DB ? ; type of operand returned ;AN000;
777Postag DB ? ; type of item tage returned ;AN000;
778synonym DW ? ; offset into synonyms returned ;AN000;
779valuelo DW ? ; space for drive number/integer/strin ;AN000;
780valuehi DW ? ;AN000;
781
782
783;---------------- SWITCH CONTROL BLOCK ------------------------------------------
784
785SWITCH label word ; switch control definition
786 DW 0 ; no match flag ;AN000;
787 DW 0 ; no function flags ;AN000;
788 DW Result ; offset into result buffer ;AN000;
789 DW value_sw1 ; offset value list buffer ;AN000;
790 DB 1 ; number of keyword/switch synonyms ;AN000;
791E_Switch DB "/X" ; /X option for extended memory access ;AN000;
792 DB 0 ;AN000;
793
794
795Result_sw1 label byte ; switch parameter result ;AN000;
796 DB ? ; type of operand returned ;AN000;
797 DB ? ; type of item tage returned ;AN000;
798Swval DW ? ; offset into synonyms returned ;AN000;
799 DB ? ; switch value ;AN000;
800
801
802Value_sw1 label byte ; switch parameter value expected ;AN000;
803 DB 0 ; no values expected ;AN000;
804
805
806
807
808
809
810
811;-----------------------------------------------------------------------------
812; INIT (FASTINIT-2)
813;-----------------------------------------------------------------------------
814;
815;SUBROUTINE: INIT
816;
817;FUNCTION: Performs FASTOPEN initialization function
818;
819;
820;NOTE: This routine is the starting routine of FASTOPEN
821;
822;-----------------------------------------------------------------------------
823
824START:
825 ; on entry DS and ES -->PSP ;AN000;
826 push cs ; DS-->Cseg_Init ;AN000;
827 pop ds ;AN000;
828 ASSUME ds:cseg_init ;AN000;
829 mov psp_seg,es ; save PSP segment for later use ;AN000;
830 push cs ;AN000;
831 pop es ; ES-->Cseg_Init ;AN000;
832 ASSUME es:cseg_init ;AN000;
833
834 CALL SYSLOADMSG ; Preload messages ;AN000;
835 jnc Parse_cmd_line ; If no error, parse command line ;AN000;
836
837 mov ax,1 ;AN000;
838 CALL SYSDISPMSG ; display error ;AN000;
839
840 mov ah,04ch ; Terminate ;AN000;
841 mov al,0 ; Errorlevel 0 (Compatible) ;AN000;
842 INT 021h ; exit to DOS
843
844Parse_Cmd_Line: ;AN000;
845 CALL PARSE ;Parse command line ;AN000;
846 lea si,parambuff ;drive ID buff address ;AN000;
847 mov ax,Total_name_Count ; ;AN000;
848 mov ax,Total_ext_Count ;AN000;
849 mov ax,num_of_drives ;AN000;
850 mov ax,ext_mem ;AN000;
851 jnc Check_Installed ;no, check if Fastopen already installed
852 jmp error_exit ;yes - exit ;AN000;
853
854Check_Installed:
855 CALL CHECK_INSTALL ; Fastopen installed ??
856 jnc Save_SegIDs ; no - save segment IDs
857 jmp error_exit ; yes - exit
858
859;-----------------------------------------------------------------------------
860; Set seg IDs of three segments.
861;-----------------------------------------------------------------------------
862Save_SegIds:
863 mov Open_SegID, Cseg_Open ;AN000;
864 mov Seek_SegID, Cseg_Seek ;AN000;
865 mov Init_SegID, Cseg_Init ;AN000;
866
867;-----------------------------------------------------------------------------
868; Compute the size of segments and cache buffers. Setup a temporary stack
869; to be used by the second half of initilization.
870;-----------------------------------------------------------------------------
871 CALL CHECK_MEM ;See if we have enough memory ;AN000;
872 jnc chk_extended_mem ;yes, check for extended memory ;AN000;
873 jmp error_exit ;no - display not enough mem msg ;AN000;
874
875;-----------------------------------------------------------------------------
876; Check if Extended Memeory is specified. If true, check if Extended memory is
877; available. Get segid of one extended memory page.
878;-----------------------------------------------------------------------------
879Chk_Extended_Mem:
880 cmp ext_mem,1 ; enable EMS ?? ;AN000;
881 jne Set_Data_Areas ; no, set data areas ;AN000;
882
883 CALL SET_EMS ; set expanded memory ;AN000;
884 jnc Set_Data_Areas ; if no error ;AN000;
885 jmp error_exit ; error exit ;AN000;
886
887;------------------------------------------------------------------------------
888; Copy Data and segid of Init segments to Main, Open and Seek segments.
889; If code is relocated, segids have to be adjusted later. (See Adjust_SegID)
890;------------------------------------------------------------------------------
891Set_Data_Areas:
892 CALL COPY_DATA ; copy data to other segments ;AN000;
893
894;-----------------------------------------------------------------------------
895; Relocate code to extended memory if extended memory is specified or
896; relocate in lower memory itself.
897;-----------------------------------------------------------------------------
898Relocate_Code:
899 CALL RELOCATE_SEGMENT ; Relocate the code cnd buffers ;AN000;
900
901;-----------------------------------------------------------------------------
902; Adjust the segids and jump vectors in other segments after code relocation
903;-----------------------------------------------------------------------------
904 CALL ADJUST_SEGIDS ; adjust segment ids after relocation ;AN000;
905
906;-----------------------------------------------------------------------------
907; Display FASTOPEN INSTALLED message. This must be done prior to the actual
908; installation.
909;-----------------------------------------------------------------------------
910Disp_Install_Msg: ; display FASTOPEN installed message
911 MOV AX,INSTALL1 ; message number ;AN000;
912 MOV MSG_NUM,AX ; set message number ;AN000;
913 MOV SUBST_COUNT,0 ; no message ;AN000;
914 MOV MSG_CLASS,-1 ; message class ;AN000;
915 MOV INPUT_FLAG,0 ; no input ;AN000;
916 CALL PRINT_STDOUT ; show message ;AN000;
917
918;-----------------------------------------------------------------------------
919; Install Fastopen
920;-----------------------------------------------------------------------------
921 CALL INSTALL_FASTOPEN ; Install Fastopen ;AN000;
922 jnc Setup_Stack ; Installed Ok, setup stack ;AN000;
923 jmp error_exit ; error - exit
924
925
926;----------------------------------------------------------------------------
927; Set Stack Values. This stack is used by the cache buffer initilization
928; portion of the code. This stack area will be eventually overlayed and
929; wont be used by either Fastopen or Fastseek functions in MAIN module.
930;----------------------------------------------------------------------------
931SETUP_STACK:
932 nop ;AN000;
933 CLI ;no interrupts allowed during stach change ;AN000;
934 mov SS,Stack_Seg_Start ;set up new stack ;AN000;
935 mov SP,0 ; ;AN000;
936 STI ;interrupts ok now ;AN000;
937 jmp INIT_VECTOR ;Jump to Cseg_Main to do second
938 ;phase of the initialization
939ERROR_EXIT:
940 mov al,1 ;set up return code
941 mov ah,exit ;set function code
942 INT INT_COMMAND ;exit to DOS
943
944
945
946
947;----------------------------------------------------------------------------
948; CHECK_INSTALL
949;----------------------------------------------------------------------------
950; Input: None
951;
952; Output:
953; IF Carry = 0 - Fastopen is not already installed
954;
955; IF Carry = 1 - Fastopen is already installed
956;
957;----------------------------------------------------------------------------
958; Use CALLINSTALL macro to see if FASTOPEN is already installed.
959; If carry flag set then FASTOPEN is installed. In this case display
960; Already Installed message.
961;----------------------------------------------------------------------------
962
963CHECK_INSTALL PROC NEAR
964
965 push ax ;save every registers that may
966 push bx ;be destroyed by DOS
967 push cx
968 push dx
969 push si
970 push di
971 push bp
972
973 push ds
974 mov bx, 1 ;Fastopen function code
975 mov si, -1 ;special check install code
976 CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed
977 pop ds
978 jc Install_Msg ;yes, display already installed
979 ;message
980;----------------------------------------------------------------------------
981; Check if Fastseek function is enabled. If true display Installed message
982;---------------------------------------------------------------------------- ;AN000;
983 push ds ;AN000;
984 mov si, -1 ;special check installed code
985 mov bx, 2 ;for Fastseek
986 CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed ;AN000;
987 pop ds ;AN000;
988 jnc Chk_Install_Exit ; no, exit ;AN000;
989
990Install_Msg: ;installed previously display message
991 MOV AX,ALREADY_INSTALL ;message number ;AN000;
992 MOV MSG_NUM,AX ;set message number ;AN000;
993 MOV SUBST_COUNT,0 ;no message substitution ;AN000;
994 MOV MSG_CLASS,-1 ;message class ;AN000;
995 MOV INPUT_FLAG,0 ;no input ;AN000;
996 CALL PRINT_STDOUT ;show message "Already Installed"
997 stc
998
999Chk_Install_Exit:
1000 pop bp ;restore registers
1001 pop di
1002 pop si
1003 pop dx
1004 pop cx
1005 pop bx
1006 pop ax
1007 ret ;return
1008
1009CHECK_INSTALL ENDP
1010
1011
1012
1013
1014
1015;----------------------------------------------------------------------------
1016; INSTALL_FASTOPEN
1017;----------------------------------------------------------------------------
1018; Input: Addrss of entry point to Fastopen resident code
1019;
1020; Output:
1021; IF Carry = 0
1022; Entry point to FASTOPEN resident code set
1023;
1024; IF Carry = 1 Error
1025;
1026; Calls: none
1027;----------------------------------------------------------------------------
1028; Use CALLINSTALL macro to see if FASTOPEN is already installed.
1029; If FASTOPEN is not installed, install it.
1030; If carry flag set then FASTOPEN is installed. In this case display
1031; already installed message.
1032;----------------------------------------------------------------------------
1033
1034INSTALL_FASTOPEN PROC NEAR
1035
1036 push ax ;Save every registers,point reg since
1037 push bx ;DOS may destroy it.
1038 push cx
1039 push dx
1040 push si
1041 push di
1042 push bp
1043
1044 cmp Total_Name_Count, 0 ;FastOpen enabled ?? ;AN000;
1045 je Install_Ext ;no - jump
1046
1047 push ds ;yes - install fastopen
1048 mov bx, 1 ;tell DOS that this is the
1049 lds si,Main_Vector
1050 CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed
1051 pop ds
1052 jc Install_Exit ;error - exit
1053
1054;----------------------------------------------------------------------------
1055; Check if Fastseek functions are enabled. If true, pass MAIN routine entry
1056; point and the Fastseek enabled information to DOS
1057;---------------------------------------------------------------------------- ;AN000;
1058Install_Ext:
1059 cmp Total_Ext_Count, 0 ; Fastseek enabled ?? ;AN000;
1060 jne ext_install ; yes - install fastseek ;AN000;
1061 clc ;AN000;
1062 jmp short Install_Exit ; no, exit ;AN000;
1063
1064Ext_Install:
1065 push ds ;AN000;
1066 mov bx, 2 ;tell DOS that this is the ;AN000;
1067 lds si,Main_Vector ;fastseek entry point ;AN000;
1068 CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed ;AN000;
1069 pop ds ;AN000;
1070 jnc short install_exit
1071 jmp short install_exit
1072
1073Installx_Msg: ;installed previously display message
1074 MOV AX,ALREADY_INSTALL ;message number ;AN000;
1075 MOV MSG_NUM,AX ;set message number ;AN000;
1076 MOV SUBST_COUNT,0 ;no message substitution ;AN000;
1077 MOV MSG_CLASS,-1 ;message class ;AN000;
1078 MOV INPUT_FLAG,0 ;no input ;AN000;
1079 CALL PRINT_STDOUT ;show message "Already Installed"
1080 stc
1081
1082Install_Exit:
1083 pop bp ;restore registers
1084 pop di
1085 pop si
1086 pop dx
1087 pop cx
1088 pop bx
1089 pop ax
1090 ret ;return
1091
1092INSTALL_FASTOPEN ENDP
1093
1094
1095
1096
1097
1098
1099;----------------------------------------------------------------------------
1100; CHECK_MEM
1101;----------------------------------------------------------------------------
1102; Function: Compute the total size of memory required by the Fasteopen.
1103; This includes both code and the cache buffers.
1104;
1105; Input: Name_Count, extent_count, Drive_cache, num_of_drives
1106;
1107; Output: Memory is validated, Resident segment size is calculated
1108; Temporary stack segment is set
1109;----------------------------------------------------------------------------
1110CHECK_MEM PROC NEAR ; DS-->Cseg_init
1111
1112;** Compute the total resident segment size and then add the cache buffer
1113;** size. The Resident segment size should be adjusted again after relocation.
1114
1115 mov Total_Cache_Size,0 ;reset total cache size (Name +Ext)
1116 mov Name_Cache_Size,0 ;reset Name cache buffer size
1117 mov ax, offset End_Main ;size of Main_Seg in bytes ;AN000;
1118 add ax,15 ;AN000;
1119 mov cl,4 ;convert size to paragraph ;AN000;
1120 shr ax,cl ;by dividng by 16 ;AN000;
1121 mov MAIN_Size, ax ;save MAIN segment size in para ;AN000;
1122 add Res_Segs,ax ;update resident seg count ;AN000;
1123 ;AN000;
1124 mov ax, offset End_Open ;size of Open_Seg in bytes ;AN000;
1125 add ax,15 ;AN000;
1126 mov cl,4 ;convert it to paragraph ;AN000;
1127 shr ax,cl ;AN000;
1128 mov OPEN_Size, ax ;save OPEN segment size in para ;AN000;
1129 add RES_SEGS,ax ;update resident seg count ;AN000;
1130 ;AN000;
1131 mov ax, offset End_Seek ;add size of Seek_Seg
1132 add ax,15 ;AN000;
1133 mov cl,4 ;AN000;
1134 shr ax,cl ; convert to para (divide by 16) ;AN000;
1135 mov SEEK_Size, ax ;save Seek segment size in para ;AN000;
1136 add RES_SEGS,ax ;update resident seg count ;AN000;
1137
1138;----------------------------------------------------------------------------
1139; Calculate the size of the NAME DRIVE HEADER BUFFERS
1140;----------------------------------------------------------------------------
1141 xor ax,ax ;reset the cache size register
1142 cmp total_Name_Count,0 ;Fastopen enabled ??
1143 je Check_ext_cache ;no - compute extent cache size
1144
1145 mov bx,offset DRIVE_CACHE ;get beginning of cache buff
1146 xor ax,ax
1147 mov al,size drive_cache_header ;get size of one name entry
1148 mul Num_Of_drives ;get total needed for drive cache
1149 add ax,bx ;set up correct offset
1150 add ax,15 ;round up to paragraph boundary
1151 mov cl,4
1152 shr ax,cl ;convert to paragraphs
1153 add RES_SEGS,ax ;update resident seg count
1154 mov Total_Cache_Size, ax ;update total cache buff size
1155 mov Name_Cache_Size, ax ;size in paragraph
1156
1157; Calculate the offset of the Name cache buffers
1158 shl ax,cl ;AX = offset to Name cache buff
1159 mov NAME_CACHE_BUFF,ax ;save Name cache address
1160
1161;-----------------------------------------------------------------------------
1162; Compute the size of the NAME CACHE buffer
1163;-----------------------------------------------------------------------------
1164 mov ax,size Name_Record
1165 mul Total_Name_Count
1166 add ax,15 ;round up to paragraph boundary
1167 mov cl,4
1168 shr ax,cl ;convert to paragraphs ( divide 16)
1169 add RES_SEGS,ax ;AX = End of Name cache buffers
1170 add Total_Cache_Size,ax ;update total cache buff size
1171 add Name_Cache_Size, ax ;
1172
1173Check_Ext_Cache:
1174 cmp total_ext_count,0 ;Fastseek enabled ??
1175 je Set_Stack ;no, set stack
1176
1177;---------------------------------------------------------------------------
1178; Compute the size of the Extent cache including drive headers
1179;---------------------------------------------------------------------------
1180Compute_Ext_Cache: ;calculate the extent buff offset
1181 mov ax,Name_Cache_Size
1182 mov cl,4
1183 shl ax,cl ;convert to bytes ( multiply by 16) ;AN000;
1184 mov EXTENT_DRIVE_BUFF, ax ;save EXTENT DRIVE BUFFER address ;AN000;
1185
1186 mov ax, size Drive_Header ;AN000;
1187 mul num_Of_drives ;calc size of drive header buff ;AN000;
1188 mov bx,ax ;save AX in BX ;AN000;
1189 mov ax, size Extent_Header ;size of one extent ;AN000;
1190 mul Total_Ext_Count ;calc size of extent buffers ;AN000;
1191 add ax,bx ;AX = size of extent buff in bytes ;AN000;
1192 mov ext_cache_size,ax ;save it for later use ;AN000;
1193 add ax,15 ;round up to paragraph boundary ;AN000;
1194 mov cl,4 ;AN000;
1195 shr ax,cl ;convert to paragraphs ;AN000;
1196 add RES_SEGS,ax ;update resident seg count ;AN000;
1197 add Total_Cache_Size,ax ;update total cache buff size
1198
1199
1200;----------------------------------------------------------------------------
1201; Setup stack segment followed by the extent cache buffers. This is a
1202; temporary stack used by the drive buffer initilization code in the
1203; Cseg_Main segment. This stack will be overlayed by the cache buffers.
1204;----------------------------------------------------------------------------
1205Set_Stack:
1206 mov ax,RES_SEGS ;AX=size of code and buffs in para
1207 add ax,PSP_Seg ;AX=segID of stack
1208 mov Stack_Seg_Start,ax ;start of the new STACK
1209 add ax,20h ;add the size of the stack
1210 mov Stack_Seg_End,ax ;get end of what we need
1211
1212 push ds ;
1213 mov ds,PSP_Seg ;access PSP for memory size
1214 mov si,Top_mem
1215 LODSW ;get total memory size
1216 pop ds
1217 sub ax,Stack_Seg_End ;see if there is enough for us
1218 jc Not_Enough_Memory ;no - error exit
1219 sub ax,1000h ;will there still be 64K ??
1220 jnc Check_Reloc_Size ;and return
1221
1222Not_Enough_Memory:
1223 MOV AX,NOT_ENOUGH_MEM ;message number ;AN000;
1224 MOV MSG_NUM,AX ;set message number ;AN000;
1225 MOV SUBST_COUNT,0 ;no message substitution ;AN000;
1226 MOV MSG_CLASS,-1 ;message class ;AN000;
1227 MOV INPUT_FLAG,0 ;no input ;AN000;
1228 CALL PRINT_STDOUT ;show message "Insufficient Memory" ;AN000;
1229 stc ;set error flag ;AN000;
1230 jmp short Set_Mem_Ret ;return ;AN000;
1231
1232;------------------------------------------------------------------------------
1233; If relocation is needed, then recalculate the size of resident segment
1234; If extended memory relocation, OPEN, SEEK and INIT segments will be
1235; eliminated from the current resident seg.
1236;-----------------------------------------------------------------------------
1237Check_Reloc_Size:
1238 cmp Ext_Mem,1 ; extended memory relocation ??
1239 jne Set_Mem_Exit ; no - exit ;AN000;
1240
1241;-----------------------------------------------------------------------------
1242; Check to see that the both code and the cache buffers fit in the
1243; exteneded memory one 16K page. Since the entire code segment and the
1244; cache buffers are going to be moved to XMA, that amount should be
1245; reduced from the size that should reside in the low memory.
1246;-----------------------------------------------------------------------------
1247 xor ax,ax
1248 xor bx,bx
1249 cmp total_Name_Count,0 ;Fastseek enabled ??
1250 je Skip_name_size ;no - skip name size
1251 mov ax, OPEN_SIZE ;size of Open seg in para ;AN000;
1252Skip_Name_Size:
1253 cmp total_ext_count,0 ;Fastseek enabled ??
1254 je Skip_Ext_Size ;no - skip extent size
1255 mov bx, SEEK_Size ;size of Seek_Seg in para ;AN000;
1256Skip_Ext_Size:
1257 add ax,bx
1258 add ax, Total_Cache_Size ;size of Init_Seg in para ;AN000;
1259 cmp ax, 0404H ;Less than 16K ?? ;AN000;
1260 jge Not_Enough_Space ;no - display message ;AN000;
1261
1262 mov ax, OPEN_SIZE ;size of Open seg in para ;AN000;
1263 add ax, SEEK_Size ;size of Seek_Seg in para ;AN000;
1264 add ax, Total_Cache_Size ;reduce resident seg size ;AN000;
1265 sub RES_SEGS,ax ;update resident seg count ;AN000;
1266
1267;-----------------------------------------------------------------------------
1268; If the code is to be moved to extended memory. There is no reason to
1269; keep Init_Tree in main memory. Remove that also to save space in base memory
1270;-----------------------------------------------------------------------------
1271 mov ax, offset End_Main1 ;size of Main_Seg until Init_Tree (bytes) ;AN000;
1272 add ax,15 ;AN000;
1273 mov cl,4 ;convert size to paragraph ;AN000;
1274 shr ax,cl ;by dividng by 16 ;AN000;
1275 mov bx,Main_Size ;bx=total size of Main seg including Init_Tree
1276 sub bx,ax ;bx=size after reducing Init_Tree
1277 sub RES_SEGS,bx ;update base memory resident seg count ;AN000;
1278 jmp short Set_Mem_Exit
1279 ;
1280Not_Enough_Space:
1281 MOV AX,NO_PAGE_SPACE ; not enough space in EMS page
1282 MOV MSG_NUM,AX ; set message number
1283 MOV SUBST_COUNT,0 ; no message
1284 MOV MSG_CLASS,-1 ; message class
1285 MOV INPUT_FLAG,0 ; no input
1286 CALL PRINT_STDOUT ; display message
1287 mov Ext_Mem, 0 ; RESET XMA FLAG
1288 stc
1289 jmp set_mem_ret
1290
1291Set_Mem_Exit: ;AN000;
1292 clc ;AN000;
1293
1294Set_Mem_Ret:
1295 ret ;AN000;
1296
1297CHECK_MEM endp
1298
1299
1300
1301
1302
1303;----------------------------------------------------------------------------
1304; RELOCATE
1305;----------------------------------------------------------------------------
1306; Function: Relocate Fastopen code and buffer in base memory or in
1307; Extended Memory. If base memory relocation, then
1308; relocate Cseg_Seek over Cseg_Open segment if the user
1309; didn't specify Fastopen (n). Relocate Cseg_Init over Cseg_Seek
1310; if user didn't specify Fastseek feature(m). If extended memory
1311; relocation, copy Cseg_Open, Cseg_Seek and Cseg_Init to
1312; a single page in extented memory if both Fastopen and Fastseek
1313; (n and m) are specified. Copy Cseg_open and Cseg_Init only if Fastseek
1314; feature (m) is not specified. Copy Cseg_Seek and Cseg_Init if
1315; FastOpen feature (n) is not specified
1316;
1317;----------------------------------------------------------------------------
1318
1319RELOCATE_SEGMENT PROC NEAR
1320 cmp Ext_Mem,1 ; Extended memory enabled ?? ;AN000;
1321 je Set_Seg_Ids ; yes - do extented memory relocation
1322 jmp Reloc_Low_Mem ; no - do low memory relocation ;AN000;
1323
1324;----------------------------------------------------------------------------
1325; Move Fastopen, FastSeek or both to the Extended memory
1326;----------------------------------------------------------------------------
1327Set_Seg_Ids:
1328 cld ; clear direction flag (increment si and di)
1329 cmp Total_Name_Count,0 ; Fastopen enabled ??
1330 jne Set_Open_Seg ; yes - set open seg in extented memory
1331
1332 mov ax,EMS_Page_Seg ; AX = seg id of Cseg_Seek in ext mem
1333 mov Seek_SegID,ax ; save it
1334 jmp Set_Seek_Seg ; no - fastopen, set Seek segment
1335
1336;-----------------------------------------------------------------------------
1337; ---- Extended Memory Relocation -----
1338; Setup Cseg_Open segment in Extended Memory
1339;------------------------------------------------------------------------------
1340Set_Open_Seg:
1341 mov ax,Cseg_Init ;
1342 mov ds,ax ; DS-->Cseg_Init
1343 ASSUME ds:Cseg_Init
1344 mov ax,EMS_Page_Seg ; AX = seg id of Cseg_Open in ext mem
1345 mov Open_SegID,ax ; save it
1346
1347Copy_Open_Seg:
1348 mov ax, offset End_Open ; size of Open seg in bytes ;AN000;
1349 mov cl,1
1350 shr ax,cl ; convert to words ;AN000;
1351 mov cx,ax ; CX = number of WORDS to transfer ;AN000;
1352 xor si,si ; offset of the source in low memory ;AN000;
1353 xor di,di ; offset of the destination in XMA ;AN000;
1354 mov ax,Cseg_Open ; set source segID ;AN000;
1355 mov ds,ax ; DS-->Cseg_Open ;AN000;
1356 ASSUME ds:Cseg_Open ;AN000;
1357 mov ax,Open_SegID ; set destination XMA seg id ;AN000;
1358 mov es,ax ; ES-->Extended memory page ;AN000;
1359 ASSUME es:nothing ;AN000;
1360 REP MOVSW ; copy Open segment to extended memory
1361 ; SI-->Cseg_Seek segment
1362 mov ax,Cseg_Init ; no - only Fastseek specified
1363 mov ds,ax ; DS-->Cseg_Init
1364 ASSUME ds:Cseg_Init
1365 cmp Total_Ext_Count,0 ; Fastseek enabled ??
1366 jne Set_Seek_id ; yes -set seek id
1367
1368 mov ax,Cseg_Seek ; only Fastopen is enabled ;AN000;
1369 sub ax,Cseg_Open ; AX = size of Cesg_Open segment ;AN000;
1370 add ax,EMS_Page_Seg ; AX = new seg ID of Cseg_Init in ext ;AN000;
1371 mov Init_SegID,ax ; only if Fastopen is specified ;AN000;
1372 jmp Copy_Init_Seg ; copy init_seg to extended memory
1373
1374;-----------------------------------------------------------------------------
1375; Setup Cseg_Seek segment in Extended Memory
1376;------------------------------------------------------------------------------
1377Set_Seek_Id:
1378 mov ax,Cseg_Seek ;
1379 sub ax,Cseg_Open ; AX = size of Cesg_Open segment ;AN000;
1380 add ax,EMS_Page_Seg ; AX = new seg ID of Cseg_Seek in ;AN000;
1381 mov Seek_SegID,ax ; extended memory ;AN000;
1382 jmp Copy_Seek_Seg
1383
1384Set_Seek_Seg: ; only Fastseek is specified
1385 xor si,si ; offset of the source in low memory ;AN000;
1386 xor di,di ; offset of the destination in XMA ;AN000;
1387
1388Copy_Seek_Seg:
1389 mov ax, offset End_Seek ;size of Cseg_Seek in bytes ;AN000;
1390 mov cl,1
1391 shr ax,cl ; convert to words ;AN000;
1392 mov cx,ax ; CX = number of WORDS to transfer ;AN000;
1393 xor si,si ; offset of the source in low memory ;AN000;
1394 xor di,di ; offset of the destination in XMA ;AN000;
1395 mov ax,Cseg_Seek ; set source segID ;AN000;
1396 mov ds,ax
1397 ASSUME ds:Cseg_Seek ;AN000;
1398 mov ax,Seek_SegID ; set destination XMA seg id ;AN000;
1399 mov es,ax
1400 ASSUME es:nothing ;AN000;
1401 REP MOVSW ; copy Seek segment to extended memory
1402 ; SI-->Cseg_Init segment
1403 mov ax,Cseg_Init ; no - only Fastseek specified
1404 mov ds,ax ; DS-->Cseg_Init
1405 ASSUME ds:Cseg_Init
1406 cmp total_Name_Count,0 ; FastOpen enabled ??
1407 jne Set_Init_Seg ; yes - set Init Segment
1408
1409 mov ax,Cseg_Init
1410 sub ax,Cseg_Seek ; ax = size of Cseg_Seek
1411 add ax,EMS_Page_Seg ; Cseg_Init id only if Fastseek is specified
1412 mov Init_SegID,ax ;
1413 jmp copy_init_seg ; copy cseg_init area to extentde memory
1414
1415;-----------------------------------------------------------------------------
1416; Setup Cseg_Init segment in Extended Memory
1417;------------------------------------------------------------------------------
1418Set_Init_seg:
1419 mov ax,Cseg_Init ; yes - set init seg id
1420 sub ax,Cseg_Open ; AX = size of Open_Cseg+Seek_Cseg
1421 add ax,EMS_Page_Seg ; new Cseg_Init id in XMA if both
1422 mov Init_SegID,ax ; Fastopen and Fastseek are enabled ;AN000;
1423
1424Copy_Init_Seg: ; comes here if no Cseg_Seek is required
1425 xor si,si ; offset of the source in low memory ;AN000;
1426 xor di,di ; offset of the destination in XMA ;AN000;
1427 mov ax, Total_Cache_Size ; size of Init seg area to be copied ;AN000;
1428 mov cl,4 ; in paragraph ;AN000;
1429 shl ax,cl ; convert to number of bytes ;AN000;
1430 mov cl,1 ;
1431 shr ax,cl ; convert to number ofwords ;AN000;
1432 mov cx,ax ; CX = number of WORDS to transfer ;AN000;
1433 mov ax,Cseg_Init ; set source segID ;AN000;
1434 mov ds,ax
1435 ASSUME ds:Cseg_Init ;AN000;
1436 mov ax,Init_SegID ; set destination XMA seg id ;AN000;
1437 mov es,ax
1438 ASSUME es:nothing ;AN000;
1439 REP MOVSW ; copy Init segment to extended memory
1440 jmp reloc_exit ; then return ;AN000;
1441
1442
1443;NOTE: No need to adjust the resident segment size (Res_Segs) since it is
1444; done in the routine (Check_Mem).
1445
1446
1447;-----------------------------------------------------------------------
1448; ---- LOW MEMORY RELOCATION ----
1449; Reloctae FastOpen or FastSeek or both in the low memory and adjust the
1450; resident size of the code.
1451;-----------------------------------------------------------------------
1452Reloc_LOW_Mem:
1453 cmp Total_Name_Count,0 ; Fastopen function enabled ??
1454 jne Check_Seek ; yes, check Fastseek function
1455
1456; Relocate Cseg_Seek segment over Cseg_Open segment
1457 mov ax, offset End_Seek ; size of Cseg_Seek in bytes ;AN000;
1458 mov cl,1
1459 shr ax,cl ; convert to words ;AN000;
1460 mov cx,ax ; CX = number of WORDS to transfer ;AN000;
1461 xor si,si ; offset of the source ;AN000;
1462 xor di,di ; offset of the destination ;AN000;;AN000;
1463 mov ax,Cseg_Seek ; set source segID ;AN000;
1464 mov ds,ax ; DS:SI-->Cseg_Seek ;AN000;
1465 ASSUME ds:Cseg_Seek ;AN000;
1466 mov ax,Cseg_Open ; set destination seg id ;AN000;
1467 mov es,ax ; ES:DI--> Cseg_Open ;AN000;
1468 ASSUME es:Cseg_Open ;AN000;
1469 ;AN000;
1470 REP MOVSW ; relocate code and cache buffer
1471 mov ax,OPEN_Size ; reduce Open seg size from
1472 sub RES_SEGS,ax ; the resident size
1473
1474;-----------------------------------------------------------------------
1475; Compute the new segID after relocation and save it
1476;-----------------------------------------------------------------------
1477 mov ax,Cseg_Init ;
1478 mov ds,ax ; DS-->Cseg_Init
1479 ASSUME ds:Cseg_Init
1480 mov ax,Cseg_Open ; AX = seg id of Cseg_Open in ext mem
1481 mov Seek_SegID,ax ; save it
1482 ;AN000;
1483 mov ax,Seek_Size ; AX = size of Cseg_Seek
1484 add ax,Cseg_Open ; AX = new seg ID of Cseg_Init in ext ;AN000;
1485 mov Init_SegID,ax ; save it ;AN000;
1486 jmp short reloc_exit ;then return ;AN000;
1487
1488Check_Seek:
1489 cmp Total_Ext_Count,0 ; Fastseek function enabled ??
1490 jne Reloc_Exit ; yes, no need for relocation
1491
1492;-----------------------------------------------------------------------
1493; Relocate first portion of the Cseg_Init over Cseg_Seek segment. The size
1494; this portion should be same as the current size of Drive cache headers
1495; Anything more will overlay on Cseg_Init code which is currently active.
1496;-----------------------------------------------------------------------
1497 mov ax, size Drive_Cache_Header ; size of one drive cache hdr
1498 mov cx,Max_Drives ; CX = maximum number of drives
1499 mul cx ; AX = size of Cseg_Init portion
1500 mov cl,1
1501 shr ax,cl ; AX = size of portion in words
1502 mov cx,ax ; CX = number of WORDS to transfer ;AN000;
1503 mov si,0 ; offset of the source ;AN000;
1504 mov di,0 ; offset of the destination ;AN000;;AN000;
1505 mov ax,Cseg_Init ; set source segID ;AN000;
1506 mov ds,ax ; DS:SI-->Cseg_Seek ;AN000;
1507 ASSUME ds:Cseg_Init ;AN000;
1508 mov ax,Cseg_Seek ; set destination seg id ;AN000;
1509 mov es,ax ; ES:DI--> Cseg_Open ;AN000;
1510 ASSUME es:Cseg_Seek ;AN000;
1511 ;AN000;
1512 REP MOVSW ; relocate Cseg_Init over Cseg_Seek
1513 mov ax,Seek_Size ; reduce Seek seg size from
1514 sub RES_SEGS,ax ; the resident size
1515
1516;-----------------------------------------------------------------------
1517; Compute the new segID after reloaction and save it
1518;-----------------------------------------------------------------------
1519 mov ax,Cseg_Init ;
1520 mov ds,ax ; DS-->Cseg_Init
1521 ASSUME ds:Cseg_Init
1522 mov ax,Cseg_Seek ; AX = seg id of Cseg_Open in ext mem
1523 mov Init_SegID,ax
1524
1525Reloc_Exit:
1526; copy the latest RES_SEGS size to Cseg_Main
1527 mov ax,Cseg_Init ; ;AN000;
1528 mov ds,ax ; DS-->Cseg_Init ;AN000;
1529 ASSUME ds:Cseg_Init ;AN000;
1530 mov ax,Cseg_Main ; set destination seg id ;AN000;;AN000;
1531 mov es,ax ; ES--> Cseg_Main ;AN000; ;AN000;
1532 ASSUME es:Cseg_Main ;AN000;;AN000;
1533 mov ax,Res_Segs ;AN000;
1534 mov es:Main_Res_Segs,ax ; save it ;AN000;
1535
1536 RET ;AN000;
1537
1538RELOCATE_SEGMENT ENDP
1539
1540
1541
1542
1543
1544
1545;-----------------------------------------------------------------------
1546; Procedure: COPY_DATA
1547;-----------------------------------------------------------------------
1548; Copy data values from Cseg_Init to other segments. I the code is relocated,
1549; seg IDs should be updated after relocation. This is done in "Update_SegID"
1550;
1551; Input: Variables inside Cseg_Open, CsegSeek and Cseg_Main segments
1552;
1553; Output: Data values copied to the above segments
1554;
1555;
1556;-----------------------------------------------------------------------
1557
1558COPY_DATA PROC NEAR
1559
1560 mov ax,cseg_init ;AN000;
1561 mov ds,ax ;DS--> Cseg_Init ;AN000;
1562 ASSUME ds:Cseg_init ;AN000;
1563 mov ax,cseg_Main ;AN000;
1564 mov es,ax ;ES--> CSEG_MAIN ;AN000;
1565 ASSUME es:Cseg_Main ;AN000;
1566 ;AN000;
1567 mov es:Main_Name_Cache_Seg, Cseg_Init ;AN000;
1568 mov ax,Num_Of_Drives ;AN000;
1569 mov es:Main_Num_Of_Drives,ax ;AN000;
1570 mov ax,ext_count ;AN000;
1571 mov es:Main_Ext_Count,ax ;AN000;
1572 mov ax,Extent_Drive_Buff ;AN000;
1573 mov es:Main_Extent_Drive_Buff,ax ;AN000;
1574 mov ax,Name_Cache_Buff ;AN000;
1575 mov es:Main_Name_Cache_Buff,ax ;AN000;
1576 mov ax,Name_Drive_Buff ;AN000;
1577 mov es:Main_Name_Drive_Buff,ax ;AN000;
1578 mov ax,Ems_Flag
1579 mov es:Main_EMS_FLAG,ax
1580 mov ax,EMS_PAGE_Seg ;AN000;
1581 mov es:Main_EMS_PAGE_Seg,ax ;AN000;
1582
1583IF BUFFERFLAG
1584 mov ax, EMS_PAGE_NUM
1585 mov es:ems_page_number, ax ;HKN
1586ENDIF
1587
1588 mov ax,EMS_PAGE_SIZE ;AN000;
1589 mov es:Main_EMS_PAGE_SIZE,ax ;AN000;
1590 mov ax,Total_Ext_Count ;AN000;
1591 mov es:Main_Total_Ext_Count,ax ;AN000;
1592 mov ax,Ext_Cache_Size ;AN000;
1593 mov es:Main_Ext_Cache_Size,ax ;AN000;
1594 mov ax,Total_Name_Count ;AN000;
1595 mov es:Main_Total_Name_Count,ax
1596
1597; Copy drive buffer to MAIN segment
1598 lea si,ParamBuff ;AN000;
1599 lea di,es:Main_ParamBuff ;AN000;
1600 mov cx,50 ;AN000;
1601
1602Paramloop:
1603 mov al,[si] ;AN000;
1604 mov es:[di],al ;AN000;
1605 inc si ;AN000;
1606 inc di ;AN000;
1607 LOOP paramloop ;AN000;
1608
1609;-----------------------------------------------------------------------
1610; Copy data values to OPEN segment (Cseg_Open)
1611;-----------------------------------------------------------------------
1612 mov ax,cseg_Open ;AN000;
1613 mov es,ax ;ES--> CSEG_Open ;AN000;
1614 ASSUME es:Cseg_Open ;AN000;
1615 mov si,offset drive_cache ;AN000;
1616 mov es:Open_Name_Drive_Buff,si ;AN000;
1617 mov es:Open_Name_Cache_Seg,Cseg_Init ;AN000;
1618 mov ax,check_Queue
1619 mov es:chk_Flag,ax
1620
1621;-----------------------------------------------------------------------
1622; Copy data values to SEEK segment (Cseg_Seek) for Fastseek functions
1623;-----------------------------------------------------------------------
1624 mov ax,cseg_Seek ;AN000;
1625 mov es,ax ;ES--> CSEG_Seek ;AN000;
1626 ASSUME es:Cseg_Seek ;AN000;
1627 mov si,Extent_Drive_Buff ;AN000;
1628 mov es:Seek_Extent_Drive_Buff,si ;AN000;
1629 mov es:Seek_Name_Cache_Seg,Cseg_Init ;AN000;
1630 mov ax,Num_Of_Drives ;AN000;
1631 mov es:Seek_Num_Of_Drives,ax ;AN000;
1632 mov ax,Total_Ext_Count ;AN000;
1633 mov es:Seek_Total_Ext_Count,ax ;AN000;
1634 mov ax,Total_Name_Count ;AN000;
1635 mov es:Seek_Total_name_Count,ax ;AN000;
1636 mov ax,Name_Cache_Buff ;AN000;
1637 mov es:Seek_Name_Cache_Buff,ax ;AN000;
1638 mov ax,Name_Drive_Buff ;AN000;
1639 mov es:Seek_Name_Drive_Buff,ax ;AN000;
1640 mov ax,check_Queue
1641 mov es:check_Flag,ax
1642 ;AN000;
1643 mov ax,cseg_Init ;AN000;
1644 mov es,ax ;ES addressability to CSEG_Init ;AN000;
1645 ASSUME es:Cseg_Init ;AN000;
1646 ;AN000;
1647 ret
1648
1649COPY_DATA ENDP
1650
1651
1652
1653
1654;-----------------------------------------------------------------------
1655; Procedure: ADJUST_SEGIDS
1656;-----------------------------------------------------------------------
1657; Function: Adjust segment Ids of various segments after relocation
1658;
1659; Input: SegID Vectors
1660;
1661; Output: SegIDs vectors are adjusted
1662;
1663; Note: The following segid and vectors are set previously either during
1664; link time or during initialization time. These SegIDS needs to
1665; be changed after the code and buffers are relocated.
1666;-----------------------------------------------------------------------
1667
1668ADJUST_SEGIDS PROC NEAR
1669
1670 mov ax,Cseg_Init ;AN000;
1671 mov ds,ax ;DS addressability to Cseg_Init ;AN000;
1672 ASSUME ds:Cseg_init ;AN000;;AN000;
1673 mov ax,cseg_Main ;AN000;
1674 mov es,ax ;ES addressability to CSEG_MAIN ;AN000;
1675 ASSUME es:Cseg_Main ;AN000;
1676
1677 mov bx, Init_segID ; copy seg ID of Init_Seg to ;AN000;
1678 mov es:Main_Name_Cache_Seg, bx ; Main seg ;AN000;
1679
1680 cmp Total_Name_Count,0 ; Fastopen function enabled ??
1681 je Adjust_Seek ; yes, Adjust Cseg_Seek ID
1682
1683 mov ax,Open_SegID ;AN000;
1684 mov es,ax ; ES addressability to CSEG_Open ;AN000;
1685 ASSUME es:Cseg_Open ; copy segid of init_seg to ;AN000;
1686 mov es:Open_Name_Cache_Seg, bx ; Open segment
1687
1688Adjust_Seek:
1689 cmp Total_Ext_Count,0 ;Fastopen function enabled ??
1690 je Adjust_Vectors ;yes, check Fastseek function
1691
1692 mov ax,Seek_SegID ;AN000;
1693 mov es,ax ; ES addressability to CSEG_Seek ;AN000;
1694 ASSUME es:Cseg_Seek ;AN000;
1695 mov es:Seek_Name_Cache_Seg, bx ;AN000;
1696
1697
1698; Adjust seg ids of jump vectors to Fastopen and Fastseek functions ;AN000;
1699Adjust_Vectors:
1700 mov ax,cseg_Main ;AN000;
1701 mov es,ax ;ES addressability to CSEG_MAIN ;AN000;
1702 ASSUME es:Cseg_Main ;AN000;
1703 ;DS addressability to Cseg_Init
1704 mov ax, Open_SegID ;AN000;
1705 mov word ptr es:FOPEN_Insert + word, ax ;AN000;
1706 mov word ptr es:FOPEN_Update + word, ax ;AN000;
1707 mov word ptr es:FOPEN_Delete + word, ax ;AN000;
1708 mov word ptr es:FOPEN_Lookup + word, ax ;AN000;
1709IF BUFFERFLAG
1710 mov word ptr es:FOPEN_Purge + word, ax ;TEL 9/29
1711ENDIF
1712
1713
1714 mov ax, Seek_SegID ;AN000;
1715 mov word ptr es:FSEEK_Open + word, ax ;AN000;
1716 mov word ptr es:FSEEK_Close + word, ax ;AN000;
1717 mov word ptr es:FSEEK_Insert + word, ax ;AN000;
1718 mov word ptr es:FSEEK_Delete + word, ax ;AN000;
1719 mov word ptr es:FSEEK_Lookup + word, ax ;AN000;
1720 mov word ptr es:FSEEK_Truncate + word, ax ;AN000;
1721 mov word ptr es:FSEEK_Purge + word, ax ;AN000;
1722
1723 cmp Total_Name_Count,0 ; Fastopen function enabled ??
1724 je Adjust_Delete ; no , exit
1725
1726; Change the segID of single Jump Vector inside Cseg_Main
1727 mov ax,cseg_Main ;AN000;;AN000;
1728 mov es,ax ;ES addressability to CSEG_MAIN ;AN000;;AN000;
1729 ASSUME es:Cseg_Main ;AN000;;AN000;
1730 mov ax,Open_SegID ;AN000;
1731 mov word ptr es:Vector_LookUp + word, ax ;;AN000;AN000;
1732
1733Adjust_Delete:
1734 cmp Total_Ext_Count,0 ; Fastseek function enabled ??
1735 je Adjust_Exit ; no , exit
1736
1737; Change the segID of single Jump Vector inside Cseg_Main
1738 mov ax,cseg_Main ;AN000;;AN000;
1739 mov es,ax ;ES addressability to CSEG_MAIN ;AN000;;AN000;
1740 ASSUME es:Cseg_Main ;AN000;;AN000;
1741 mov ax,Seek_SegID ;AN000;
1742 mov word ptr es:Vector_Delete + word, ax ;;AN000;AN000;
1743
1744Adjust_Exit:
1745 ret ;AN000;
1746 ;return
1747ADJUST_SEGIDS ENDP
1748
1749
1750
1751
1752
1753
1754
1755
1756;******************************************************************************
1757; *
1758; * MODULE: PARSE
1759; *
1760; * FUNCTION: Parse command line
1761; *
1762; * INPUT: FASTOPEN d: {=n | (n,m) } ... /x à
1763; * where à activates queue analyser for debugging
1764; *
1765; * OUTPUT: Command line is parsed
1766; *
1767; * RETURN SEQUENCE:
1768; *
1769; * If CY = 0 No error
1770; *
1771; * If CY = 1 Error
1772; *
1773; * EXTERNAL REFERENCES: SYSPARSE
1774; *
1775; *************************************************************************
1776
1777EOL EQU -1 ; Indicator for End-Of-Line
1778NOERROR EQU 0 ; Return Indicator for No Errors
1779
1780
1781PARSE PROC NEAR
1782
1783 mov num_of_drives,0 ; initialize drive count
1784 mov name_count,0
1785 mov ext_count,0
1786 mov Total_name_count,0 ;AN000;
1787 mov Total_ext_count,0 ;AN000;
1788 mov Prev_Type,0 ;AN000;
1789 mov Ext_Mem,0 ;AN000;
1790 mov Check_Queue,0 ;AN000;
1791 lea si,parambuff ; drive ID buff address ;AN000;
1792 mov parmbuff_Ptr,si ; save it ;AN000;
1793
1794;----------------------------------------------------------------------------
1795; Get command string address from PSP
1796;----------------------------------------------------------------------------
1797 mov si,0081H
1798 mov ah,62H
1799 INT 21H ; get program PSP segment ;AN000;
1800 mov PSP_Seg,bx ; save PSP segment ;AN000;
1801 ;AN000;
1802 mov ds,bx ; DS = PSP segment ;AN000;
1803 mov si,0081h ; SI-->beginning of parameter string in PSP
1804 lea di,cmdline_buff ; DI-->command param buffer ;AN000;
1805 mov cx,127 ; copy 127 bytes from PSP ;AN000;
1806
1807;----------------------------------------------------------------------------
1808; Copy command parameters from PSP to the command buffer
1809;----------------------------------------------------------------------------
1810Cmdloop:
1811 mov al,ds:[si] ; DS:SI-->Command line ;AN000;
1812 mov es:[di],al ; ES:DI-->program command buffer ;AN000;
1813 inc si ;AN000;
1814 inc di ;AN000;
1815 LOOP cmdloop ; copy command line
1816 push cs ;AN000;
1817 pop ds ;AN000;
1818
1819;----------------------------------------------------------------------------
1820; set parametrs for SysParse call
1821;----------------------------------------------------------------------------
1822 xor cx,cx ; no params processed so far ;AN000;
1823 MOV ORDINAL,CX ; SAVE initial ordinal value ;AN000;
1824 lea si,cmdline_buff ; ES:SI-->command line ;AN000;
1825 lea di,parms ; ES:DI-->parameter
1826 MOV CURRENT_PARM,SI ; pointer to next positional ;AN000;
1827
1828 mov ax,0100h ; Drive only
1829 mov pos1type,ax ; set positional control block 1 ;AN000;
1830 mov ax,08502h ; Numeric/Complex/Drive/Repeat
1831 mov pos2type,ax ; set positional control block 2 ;AN000;
1832 mov al,1 ; minimum 1 positional ;AN000;
1833 mov Par_Min,al ;
1834 mov al,2 ;AN000;
1835 mov Par_Max,al ; maximum 1 positional ;AN000;
1836 jmp short set_param
1837
1838;----------------------------------------------------------------------------
1839; MAIN PARSE LOOP
1840;----------------------------------------------------------------------------
1841PARSE_LOOP: ; MAIN PARSE LOOP
1842 mov ax,08502h ; number/drive ID/comlex/repeat
1843 mov pos1type,ax ; set positional control block ;AN000;
1844 mov ax,08502h ;
1845 mov pos2type,ax ;
1846 mov al,1 ; minimum 1 positional ;AN000;
1847 mov Par_Min,al ; set min
1848 mov al,2 ; maximum 2 positionals ;AN000;
1849 mov Par_Max,al ; set max ;AN000;
1850
1851Set_Param:
1852 mov Par_sw,1 ; set switch flag in PARSMX
1853 xor dx,dx
1854 push cs ;AN000;
1855 pop es ; ES=DS=CS ;AN000;
1856 LEA DI,PARMS ; ES:DI = PARSE CONTROL DEFINITON ;AN000;
1857 MOV SI,CURRENT_PARM ; DS:SI = next positional ;AN000;
1858 XOR DX,DX ; RESERVED, INIT TO ZERO ;AN000;
1859 MOV CX,ORDINAL ; OPERAND ORDINAL, INITIALLY ;AN000;
1860
1861 CALL SYSPARSE ; Parse current positional
1862
1863 mov Next_Parm,si ; save pointer to next positional ;AN000;
1864 mov ORDINAL,CX ; save current ordinal ;AN000;
1865 cmp ax,EOL ; END-OF-COMMAND string ?? ;AN000;
1866 jne Parse_chk_Error ; no - check error
1867
1868
1869;----------------------------------------------------------------------------
1870; If previous positional is a drive ID without Name or Extent count then assign
1871; default counts .
1872;----------------------------------------------------------------------------
1873 cmp Prev_Type,6 ; previous param = drive ID ;AN000;
1874 jne Take_Exit ; no - exit ;AN000;
1875 ;AN000;
1876 CALL PROC_DEFAULT ; yes - setup default counts for previous drive ;AN000;
1877 jnc Take_Exit ; exit ;AN000;
1878 jmp parse_Error ; error exit ;AN000;
1879
1880Take_Exit:
1881 CALL Verify_Counts ; verify the Total counts
1882 jnc Counts_OK ; exit if count ok
1883 jmp parse_error ; else error exit
1884
1885Counts_Ok:
1886 jmp parse_exit ; normal - exit
1887
1888
1889;----------------------------------------------------------------------------
1890; CHECK ERROR CONDITIONS
1891;----------------------------------------------------------------------------
1892Parse_Chk_Error: ; check for error conditions
1893 cmp ax,NOERROR ; any parse error ??
1894 jne verify_missing_oper ; yes - check missing operand
1895 jmp Chk_Result ; no - check result buffer ;AN000;
1896
1897Verify_Missing_Oper:
1898 cmp ax,2 ; yes - missing operand error??
1899 jne disp_error ; no - jump ;AN000;
1900
1901 cmp Prev_Type,0 ; yes - any previous parameters ??
1902 jne Chk_Prev_Drive ; yes, previous drive id ;AN000;
1903 mov MSG_CLASS,2
1904 MOV MSG_NUM,AX ; set message number ;AN000;
1905 MOV SUBST_COUNT,0 ; no message substitution ;AN000;
1906 MOV INPUT_FLAG,0 ; no input ;AN000;
1907 CALL PRINT_STDOUT ; show message ;AN000;
1908 stc ; set error flag ;AN000;
1909 jmp Parse_Exit ; exit
1910
1911;----------------------------------------------------------------------------
1912; If previous positional is drive ID without counts then assign default counts
1913;----------------------------------------------------------------------------
1914Chk_prev_drive:
1915 cmp Prev_Type,6 ; previous param = drive ID ?? ;AN000;
1916 jne Take_Exit1 ; no - exit ;AN000;
1917
1918 CALL PROC_DEFAULT ; yes - assign default ID
1919 jnc Take_Exit1 ; no error, verify counts ;AN000;
1920 jmp parse_Error ; error exit ;AN000;
1921
1922Take_Exit1:
1923 CALL Verify_Counts ; verify the Total counts
1924 jnc Counts_right ; count ok - check special case
1925 jmp parse_error ; error - exit
1926
1927Counts_right:
1928 cmp Prev_Type,0 ; no previous param ? (Special case) ;AN000;
1929 je invalid_operand ; no, exit ( FASTOPEN >TEMP ) case ;AN000;
1930 clc ;AN000;
1931 jmp parse_exit ; exit
1932
1933Invalid_Operand: ; else error
1934 jmp bad_param
1935
1936Disp_Error:
1937 cmp ax, 3 ; invalid switch type ??
1938 jne bad_param ; no -
1939 jmp Bad_Switch
1940
1941;----------------------------------------------------------------------------
1942; If user entered à to activate the analyser, than verify the previous
1943; drive case. If true, assign default name extent entries, set activation
1944; flag and take normal exit.
1945;----------------------------------------------------------------------------
1946Bad_Param:
1947 mov si,Current_Parm ; SI-->current parameter (analyser hook)
1948 mov al,0e0h ; à (hidden character to activate analyser)
1949 cmp [si],al ; activate analyser ??
1950 jne set_disp_param ; no - normal error
1951 mov Check_Queue,1 ; yes - set flag to activate analyser
1952 clc
1953 jmp Chk_Prev_Drive ; exit
1954
1955Set_Disp_Param:
1956 mov di,Next_Parm ; ending address of bad param (1/6/88)
1957 mov al,0
1958 mov ds:[di],al ; set termination character
1959 LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000;
1960 MOV AX,CURRENT_PARM ; starting address of bad parameter ;AN000;
1961 MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000;
1962 MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000;
1963 MOV [SI].MSG_ID,0 ; message ID ;AN000;
1964 MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000;
1965 MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000;
1966 MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000;
1967 mov ax,incorrect_param ; Error Code ;AN000;
1968 MOV MSG_NUM,AX ; set message number ;AN000;
1969 MOV SUBST_COUNT,1 ; substitution count ;AN000;
1970 MOV MSG_CLASS,-1 ; message class ;AN000;
1971 MOV INPUT_FLAG,0 ; no input ;AN000;
1972 CALL PRINT_STDOUT ; display message ;AN000;
1973 stc ; error flag
1974 jmp Parse_Exit ; exit (1/6/88 P2670)
1975
1976
1977;----------------------------------------------------------------------------
1978; CHECK POSITIONAL PARAMETER TYPE
1979;----------------------------------------------------------------------------
1980Chk_Result:
1981 push es ; get DS back to Program data segment ;AN000;
1982 pop ds ;AN000;
1983 cmp postype,1 ; number ?? ;AN000;
1984 jne chk_switch ;AN000;
1985 jmp short Proc_Name ; yes, process name entry ;AN000;
1986
1987chk_switch:
1988 cmp postype,3 ; switch ?? ;AN000;
1989 je Proc_sw ; yes, process switch ;AN000;
1990 cmp postype,6 ; drive id ?? ;AN000;
1991 je Proc_driveid ; yes, Process Drive ID ;AN000;
1992 cmp postype,4 ; complex item ?? ;AN000;
1993 jne disp_msg ;AN000;
1994 jmp Proc_complex ; yes, process Complex item ;AN000;
1995
1996disp_msg:
1997 mov ax,incorrect_param ; no, check reult buffer ;AN000;
1998 jmp bad_param ; else error ;AN000;
1999
2000Proc_Sw: jmp Proc_Switch ; process switch ;AN000;
2001
2002
2003
2004;----------------------------------------------------------------------------
2005; PROCESS DRIVE ID
2006;----------------------------------------------------------------------------
2007PROC_DRIVEID: ; PROCESS DRIVE ID
2008 cmp Prev_Type,6 ; previous param = drive ID ;AN000;
2009 jne check_drive_id ; no, jump ;AN000;
2010 ;AN000;
2011; if not set default name and extent entry count for previous drive
2012 CALL PROC_DEFAULT ; setup default counts ;AN000;
2013 jnc Check_Drive_id ; ;AN000;
2014 jmp parse_Error ;AN000;
2015
2016Check_Drive_Id: ; process current drive ID
2017 mov ax,ValueLo ; get drive letter number from result buff ;AN000;
2018 ; C:=3 D:=4 etc, Parser drive id convention ;AN000;
2019 add al,040H ; convert to drive letter ;AN000;
2020
2021 CALL CHECK_DRIVE ; validate drive ID ?? ;AN000;
2022 jnc set_drive_id ; yes, jump ;AN000;
2023 jmp Parse_Exit ; no, invalid drive id , exit ;AN000;
2024
2025Set_Drive_Id:
2026 inc num_of_drives ; update the drive count ;AN000;
2027 xor ax,ax ;AN000;
2028 mov ax,valuelo ; get drive number ;AN000;
2029 xor ah,ah ; only low byte is valid ;AN000;;AN000;
2030 mov di,ParmBuff_Ptr ; DS:DI-->driveID buffer ;AN000;
2031 dec ax ; C:=2 D:=3 E:=4 etc Fastopen drive id ;AN000;
2032 mov [di],ax ; save drive in Drive ID table ;AN000;
2033 add parmbuff_ptr,2 ; points to next extent count area ;AN000;
2034 mov al,PosTYpe ; set previous type before look for next ;AN000;
2035 mov Prev_Type,al ; positional parameter ;AN000;
2036 mov si,Next_Parm ; get pointer to next param (switch) ;AN000;
2037 mov Current_Parm,si ; ;AN000;
2038 jmp Parse_Loop ; look for next posistional parameter ;AN000;
2039
2040
2041;----------------------------------------------------------------------------
2042; PROCESS INTEGER ( C:=n ) followed by drive ID
2043;----------------------------------------------------------------------------
2044PROC_NAME:
2045 cmp Prev_Type, 6 ; previous type = drive ID
2046 je Get_Name_Value ; yes - jump
2047 mov ax,incorrect_param ; error code ;AN000;
2048 jmp bad_param
2049
2050Get_Name_Value:
2051 xor ax,ax ;AN000;
2052 mov ax,valuelo ; get name value ;AN000;
2053 cmp ax,10 ; check validity of the count ;AN000;
2054 jl Bad_Name_Count
2055 cmp ax,999 ;AN000;
2056 jle save_name_count ; count OK, save it ;AN000;
2057
2058Bad_Name_Count: ; bad name count
2059 mov ax,Invalid_Name ; error code ;AN000;
2060 jmp parse_error ; error - exit ;AN000;
2061
2062Save_Name_Count:
2063 mov name_count,ax ; save it (name count)
2064 add Total_Name_Count,ax ; update total name count
2065 mov di,ParmBuff_Ptr ; DS:DI-->driveID buffer ;AN000;
2066 mov ax,-1 ;AN000;
2067 mov [di],ax ; MARK this drive has no extent entry ;AN000;
2068 add parmbuff_ptr,2 ; points to extent count area ;AN000;
2069
2070Set_Drive_Hdr:
2071 mov ax,Name_Count ; get name count entry ;AN000;
2072 CALL SET_DRIVE_CACHE_HEADER ; Set Name cache header ;AN000;
2073 jnc set_min_max ; no error set min and max ;AN000;
2074 jmp parse_Error ; display error ;AN000;
2075
2076Set_Min_Max:
2077 mov al,1 ;AN000;
2078 mov Par_Min,al ; change min-max ;AN000;
2079 mov al,2 ;AN000;;AN000;
2080 mov Par_Max,al ;AN000;
2081 mov al,PosTYpe ; set previous type before look for next ;AN000;
2082 mov Prev_Type,al ;AN000;
2083 mov si,Next_Parm ; get pointer to next param (switch) ;AN000;
2084 mov Current_Parm,si ; ;AN000;
2085 mov ordinal,0 ;AN000;
2086 Jmp Parse_Loop ; parse nexy positional ;AN000;
2087
2088
2089;----------------------------------------------------------------------------
2090; PROCESS COMPLEX (n,m) followed by a drive id
2091;----------------------------------------------------------------------------
2092PROC_COMPLEX:
2093 cmp Prev_Type, 6 ; previous type = drive ID ??
2094 je Get_Cmplx_Item ; yes - ok
2095 mov ax,incorrect_param ; no - error, previous must be drive id ;AN000;
2096 jmp bad_param ; display error
2097
2098Get_Cmplx_Item:
2099 mov al, PosType ;
2100 mov Prev_Type,al ; save current type as previous
2101 lea di,valuelo ; DI-->result buffer ;AN000;
2102 mov si,[di] ; get next positional param address ;AN000;
2103 mov current_parm,si ; SI-->first complex item ;AN000;
2104 mov ax,08001h ; Control ( Numeric/Optional ) ;AN000;
2105 mov Pos1Type,ax ; change pos-param control block flag ;AN000;
2106 mov Pos2Type,ax ;AN000;
2107 mov al,1 ; atleast 1 or maximun two positionals in complex item ;AN000;
2108 mov Par_Min,al ; set minimum = 1
2109 mov al,2 ;AN000;
2110 mov Par_Max,al ; set maximum = 2 ;AN000;
2111 mov ordinal1,0 ; initialize ordinal for complex item loop ;AN000;
2112 mov par_sw,0 ; reset switch flag in PARMSX
2113
2114COMPLX_LOOP:
2115 xor dx,dx
2116 LEA DI,PARMS ;ES:DI = PARSE CONTROL DEFINITON ;AN000;
2117 MOV SI,CURRENT_PARM ;SI = COMMAND STRING, NEXT PARM ;AN000;
2118 XOR DX,DX ;RESERVED, INIT TO ZERO ;AN000;
2119 MOV CX,ORDINAL1 ;OPERAND ORDINAL, INITIALLY ZERO ;AN000;
2120
2121 CALL SYSPARSE ; parse positional param in complex item
2122
2123 cmp ax,NOERROR ; parse error ??
2124 je Chk_Complex_Result ; no, check result buffer ;AN000;
2125 cmp ax,EOL ; END-OF-COMMAND string ?? ;AN000;
2126 jne Complex_Error ; no, check error
2127 mov si,Next_Parm ; Set pointer to next param (4/3/88)
2128 mov Current_Parm,si ; set next param address before parsing ;AN000;
2129 jmp Parse_Loop ; go to main parse loop
2130
2131Complex_Error:
2132 mov ax,Incorrect_Param ; no, check reult buffer ;AN000;
2133 jmp bad_param ; display error
2134
2135;-------------------------------------------------------------------------------
2136; Ckeck The Result Buffer
2137;-------------------------------------------------------------------------------
2138Chk_Complex_Result:
2139 mov ordinal1,cx ; save current ordinal ;AN000; ;AN000;
2140 cmp postype,1 ; positional type = number ??
2141 je Proc_Complex_Name ; yes, process name entry ;AN000;
2142 cmp postype,3 ; positional type = String ??
2143 je Miss_param ; yes, process missing parameter
2144 mov ax,incorrect_param ; no, check reult buffer ;AN000;
2145 jmp bad_param
2146
2147Miss_Param:
2148 mov current_parm,si ; save current chara pointer ;AN000;
2149 jmp complx_loop ; get extent count
2150
2151
2152;-------------------------------------------------------------------------------
2153; PROCESS NAME ENTRY (n)
2154;-------------------------------------------------------------------------------
2155Proc_Complex_Name: ; PROCESS COMPLEX ITEM
2156 mov current_parm,si ; save current chara pointer ;AN000;
2157 cmp cx,2 ; second positional in the complex ;AN000;
2158 je proc_extent_entry ; yes, process Extent count ;AN000;
2159 xor ax,ax ; eles process Name Count ;AN000;
2160 mov ax,valuelo ; get name value from result buffer ;AN000;
2161 cmp ax,10 ; validate the name value for higher ;AN000;
2162 jl Name_Error ; and lower boundries ;AN000;
2163 cmp ax,Max_Entry_Num ; name entry count ok ??
2164 jg Name_Error ; no - error
2165 jmp short Store_Name_Count ; yes - store it
2166
2167Name_Error: ; invalid name count
2168 mov ax,invalid_name ; error code ;AN000;
2169 jmp parse_error ; display error
2170
2171Store_Name_Count:
2172 mov Name_Count,ax ; save it (name count) ;AN000; ;AN000;
2173 add Total_name_count,ax ; update total name count ;AN000; ;AN000;
2174
2175 CALL SET_DRIVE_CACHE_HEADER ; Set Name cache header ;AN000;
2176 jc Cant_Set_Header ; jump if error ;AN000;
2177 jmp Complx_loop ; look for extent count ;AN000;
2178
2179Cant_Set_Header:
2180 jmp Parse_Error ; error exit
2181
2182
2183;-------------------------------------------------------------------------------
2184; PROCESS EXTENT ENTRY (m)
2185;-------------------------------------------------------------------------------
2186Proc_Extent_Entry:
2187 mov ax,valuelo ; get extent count entry
2188 cmp ax,1 ; validate entry between 1 an 10 ;AN000;
2189 jl Extent_Error ;AN000;
2190 cmp ax,10
2191 jl set_default_ext ; if <10 set default entry 12
2192 cmp ax,Max_Entry_Num ; >999 ??
2193 jg Extent_Error ; yes - error
2194 jmp short Store_Extent_Count ; value OK, save it
2195
2196Set_Default_Ext: ; for count 1 throug 9 set default count 12
2197 mov ax,12
2198 jmp short Store_Extent_Count
2199
2200Extent_Error: ; invalid entry error
2201 mov ax,invalid_extent ; error code
2202 jmp parse_error ; display error ;AN000;
2203
2204Store_Extent_Count:
2205 mov ext_count,ax ; save the count
2206 add Total_Ext_count,ax ; update total extent count
2207 mov di,parmbuff_ptr ; DI-->drive/extent buffer ;AN000;
2208 mov [di],ax ; save in buffer ;AN000;
2209 add parmbuff_ptr,2 ; move pointer to next extent in buffer ;AN000;
2210 mov si,Next_Parm ; get pointer to next param
2211 mov Current_Parm,si ; set next param address before parsing ;AN000;
2212 mov Par_Sw,1 ; set switch flag in PARMSX
2213 Jmp Parse_Loop ; parse next positional parameter ;AN000;
2214
2215
2216;----------------------------------------------------------------------------
2217; PROCESS SWITCH (/X) OPTION
2218;----------------------------------------------------------------------------
2219Proc_Switch:
2220 cmp Prev_Type,0 ; any previous type ??
2221 je Switch_Error ; no - error
2222 cmp Ext_Mem,0 ; switch previously specified ?? ;AN000;
2223 je set_sw_flag ; no, set flag ;AN000;
2224
2225Switch_Error:
2226 mov ax,incorrect_param ; error code ;AN000;
2227 jmp bad_param ; error - /x could be specified only once
2228
2229Set_Sw_flag:
2230 cmp Prev_Type,6 ; previous param = drive ID 12/15 P2939 ;AN000;
2231 jne sw_save_Ptr ; no - continue 12/15 p2939 ;AN000;
2232 ;AN000;
2233 CALL PROC_DEFAULT ; yes setup default counts for previous drive ;AN000;
2234 jnc sw_save_ptr ; no error - continue 12/15 p2939 ;AN000;
2235 jmp short parse_Error ; error - exit 12/15 P2939 ;AN000;
2236
2237Sw_save_ptr:
2238 mov current_parm,si ; save current chara pointer ;AN000;
2239 mov bx,synonym ; get synonym (/x) ;AN000; ;AN000;
2240 cmp bx,offset e_switch ; /X ?? ;AN000;
2241 je set_extflag ; yes - check result buffer ;AN000;
2242 jmp Bad_Switch ; error exit
2243
2244Set_ExtFlag: ; no, check reult buffer
2245 mov Ext_Mem,1 ; yes, set Hi Memory flag ;AN000;
2246 mov si,Current_parm ; -->next parameter ;AN000;
2247 mov al,PosTYpe ; set prevvious type before look for next ;AN000;
2248 mov Prev_Type,al ;AN000;
2249 jmp parse_loop ;AN000;
2250
2251Bad_Switch:
2252 mov di,Next_Parm ; ending address of bad param 1/6/88
2253 mov al,0
2254 mov ds:[di],al ; set termination character
2255 LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000;
2256 MOV AX,CURRENT_PARM ; starting address of bad parameter ;AN000;
2257 MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000;
2258 MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000;
2259 MOV [SI].MSG_ID,0 ; message ID ;AN000;
2260 MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000;
2261 MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000;
2262 MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000;
2263 MOV BX,Invalid_Switch ; get message number
2264 MOV MSG_NUM,BX ; set message number ;AN000;
2265 MOV SUBST_COUNT,1 ; substitution count ;AN000;
2266 MOV MSG_CLASS,-1 ; message class ;AN000;
2267 MOV INPUT_FLAG,0 ; no input ;AN000;
2268 CALL PRINT_STDOUT ; display message ;AN000;
2269 stc ; error flag
2270 jmp Parse_Exit ; exit (1/6/88 P2670)
2271
2272
2273
2274;----------------------------------------------------------------------------
2275; PROCESS PARSE ERROR
2276;----------------------------------------------------------------------------
2277PARSE_ERROR: ; AX = meassage number
2278 MOV MSG_CLASS,-1 ; message class ;AN000;
2279 MOV MSG_NUM,AX ; set message number ;AN000;
2280 MOV SUBST_COUNT,0 ; no message substitution ;AN000;
2281 MOV INPUT_FLAG,0 ; no input ;AN000;
2282 CALL PRINT_STDOUT ; show message ;AN000;
2283 stc ; set error flag ;AN000;
2284
2285Parse_Exit: ; EXIT
2286 push cs ;AN000;
2287 pop ds ; DS - Program data area seg ;AN000;
2288 ret ;AN000; ;AN000;
2289PARSE ENDP ; end of parser
2290
2291
2292
2293
2294;----------------------------------------------------------------------------
2295;
2296; Procedure: PROC_DEFAULT
2297;
2298; Function: Process default parameters if name and extend counts
2299; are not specified with the drive id.
2300;
2301;----------------------------------------------------------------------------
2302
2303PROC_DEFAULT PROC ; PROCESS DEFAULT
2304 push si ; makesure to save next chara pointer ;AN000;
2305 mov ax,30h ; get default name count ;AN000;
2306 mov name_count,ax ; save it ;AN000;
2307 add Total_name_count,ax ; update total name count ;AN000;
2308 mov ext_count,ax ; save it ;AN000; ;AN000;
2309 add Total_Ext_count,ax ; save it ;AN000; ;AN000;
2310 mov di,ParmBuff_Ptr ; DS:DI-->parameter buffer ;AN000;
2311 mov [di],ax ; save in buffer ;AN000;
2312 add Parmbuff_ptr,2 ; points to next drive id position
2313 mov ax,Name_Count ;AN000;
2314 CALL Set_drive_Cache_Header ; Set Name cache header ;AN000;
2315
2316Default_Exit:
2317 pop si ;AN000;
2318 ret ; return ;AN000;
2319
2320PROC_DEFAULT ENDP
2321
2322
2323
2324
2325;----------------------------------------------------------------------------
2326; Procedure: VERIFY_COUNTS
2327;
2328; Function: Verify the validity of the name and extent counts
2329
2330;----------------------------------------------------------------------------
2331VERIFY_COUNTS PROC NEAR
2332
2333; Check the validity of NAME and EXTENT count entries
2334 cmp Total_ext_count,0 ; any extent param ?? ;AN000;
2335 je Chk_Name_Count ; no, dont check extent count ;AN000;
2336 cmp Total_ext_count, Max_Entry_Num ; check lower boundry ;AN000;
2337 jg invalid_ext ; error if not within ;AN000;
2338 clc ; Extent Count is valid
2339
2340; Extent count is OK, check Name count
2341Chk_Name_Count:
2342 cmp Total_Name_Count,0 ; any name param ?? ;AN000;
2343 je Verify_Exit ; no, dont check extent count ;AN000;
2344
2345 cmp Total_name_count, Max_Entry_Num ;AN000;
2346 jg invalid_name_entry ;AN000;
2347 clc ; Name count is OK ;AN000;
2348 jmp short verify_exit ; exit ;AN000;
2349
2350Invalid_ext:
2351 mov ax,many_ext_entries ; AX = error code ;AN000;
2352 stc
2353 jmp short verify_exit ;AN000;
2354
2355Invalid_name_entry:
2356 mov ax,many_name_entries ; AX = error code ;AN000;
2357 stc ;AN000;
2358
2359Verify_Exit: ;
2360
2361 RET ;AN000;
2362
2363VERIFY_COUNTS ENDP
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375;=========================================================================
2376; CHECK_DRIVE
2377;-----------------------------------------------------------------------
2378;
2379; INPUT: AL - Drive letter
2380;
2381; OUTPUT:
2382; If Carry = 0
2383; user_drive set to current entered drive letter
2384; num_Of_drives incremented
2385; If Carry = 1 error
2386;-----------------------------------------------------------------------
2387; 1) see if drive is valid and removable using int 21h IOCTL
2388;
2389; 2) use int 21h name translate to make sure that the drive is not
2390; redirected, substed, on another machine, or in any other way shape
2391; or form hosed.
2392;=========================================================================
2393
2394CHECK_DRIVE PROC NEAR
2395
2396 CALL Convert_To_Caps ; make sure it is a capital letter
2397 mov byte ptr user_drive,al ; save it in user drive
2398 mov byte ptr source_xname,al ; put in source string for call
2399
2400 mov bl,al ;put drive letter in bl
2401 sub bl,"A"-1 ;convert to 1 based number
2402
2403 mov ah,ioctl ;set up for removable call
2404 mov al,8 ;function code
2405 INT int_command
2406
2407 cmp ax,1 ;is drive fixed?
2408 jz okay_drive ;yes - see if it's subst
2409 cmp ax,0fh ;is drive valid?
2410 jnz hosed_drive ;yes - but hosed
2411
2412 mov ax,invalid_drive ; set bad drive message
2413 jmp short drive_Error ; display error message
2414
2415Okay_Drive:
2416 lea si,source_xname ; set up for name translate
2417 lea di,target_xname
2418 mov ax,xNameTrans SHL 8
2419 INT int_command ;do the translation
2420
2421 lea si,source_xname ;compare source and target drive
2422 lea di,target_xname
2423
2424 mov cx,Len_source_xname ;get count of invalid chars
2425 repz cmpsb ;compare until mismatch found
2426 jz check_drive_end ;no mismatch - exit
2427
2428Hosed_Drive:
2429 MOV AX,BAD_USE_MESSAGE ; message number
2430
2431Drive_Error:
2432 push ax ; save message number
2433 mov ax,Valuelo ; get drive letter number from result buff
2434 ; C:=3 D:=4 etc, Parser drive id convention
2435 add al,040H ; convert to drive letter
2436 lea si,Drive_Id ; DS:SI-->drive letter save area
2437 mov [si],al ; save drive letter in buffer
2438
2439 LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000;
2440 MOV AX,OFFSET DRIVE_ID ;AN000;
2441 MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000;
2442 MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000;
2443 MOV [SI].MSG_ID,1 ; message ID ;AN000;
2444 MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000;
2445 MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000;
2446 MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000;
2447 POP AX ; restore message number ;AN000;
2448 MOV MSG_NUM,AX ; set message number ;AN000;
2449 MOV SUBST_COUNT,1 ; substitution count ;AN000;
2450 MOV MSG_CLASS,-1 ; message class ;AN000;
2451 MOV INPUT_FLAG,0 ; no input ;AN000;
2452 CALL PRINT_STDOUT ; display message ;AN000;
2453 stc ; error flag
2454
2455Check_Drive_End:
2456 ret ; return
2457
2458CHECK_DRIVE endp
2459
2460
2461
2462
2463
2464;=========================================================================
2465; Procedure: SET_DRIVE_CACHE_HEADER
2466;
2467; Function: Set name cache drive header
2468;
2469; Input: ax contains number of entries for num_entries
2470; user_drive contains user drive for drive_letter
2471; num_Of_drives contains number of caches set up so far
2472; drive_cache offset of drive cache headers start
2473; Output:
2474; If successful:
2475; drive cache header set up
2476; user_drive reset to blank
2477; num_Of_drives incremented
2478; else
2479; bx set to error flag
2480; dx points to error message
2481;-----------------------------------------------------------------------
2482; 1) see if drive too many drives have been entered.
2483; 2) Walk through drive cache headers to make sure that the drive
2484; letter was not previously entered.
2485; 3) Set up drive cache header
2486;=========================================================================
2487
2488SET_DRIVE_CACHE_HEADER PROC NEAR
2489
2490 mov cx,num_of_drives ;get current count of drives
2491 mov bx,offset drive_cache ;get start of name drive cache
2492 mov dl,user_drive ;get user entered drive
2493 dec cx ;is this the 1st drive entered ?
2494 jcxz set_it_up ;yes - don't check
2495
2496 cmp num_Of_drives,max_drives ;no - check for maximum num of drives
2497 jng we_have_room ;yes - go check for dup drives
2498 mov ax,too_many_entries ;set up for error message
2499 stc ;set up error flag
2500 jmp short set_dheader_exit ;and exit
2501
2502;-----------------------------------------------------------------------
2503; Search through the drive headers to see the duplicate drive exist.
2504; If a new drive header at the bottom of the chain for the new drive.
2505; If no drives exist, then create the new header as the first drive header.
2506;-----------------------------------------------------------------------
2507We_Have_Room: ;BX-->current drive header
2508 cmp dl,[bx].dch_drive_letter ;drive header exist for this drive??
2509 jnz not_dup_drive ;no - continue
2510 mov ax,dup_drive ;yes - set up for error message
2511 stc
2512 jmp short set_dheader_exit ;exit
2513
2514Not_Dup_Drive:
2515 cmp [bx].dch_sibling_ptr,no_siblings ;any more header to search ??
2516 jz set_drive_sibling ;no - go create the new drive header
2517 add bx,size drive_cache_header ;yes - get pointer to next drive header
2518 jmp short we_have_room ;check it
2519
2520Set_drive_sibling:
2521 mov cx,bx ;save current header address
2522 add cx,size drive_cache_header ;pointer to next header
2523 mov [bx].dch_sibling_ptr,cx ;set pointer to new header from current hdr
2524 mov bx,cx ;BX-->new header
2525
2526Set_it_up:
2527 mov [bx].dch_drive_letter,dl ;save drive letter in new header
2528 mov [bx].dch_sibling_ptr,no_siblings ;mark new header as last header in chain
2529 mov [bx].dch_num_entries,ax ;save name count in new header
2530
2531Set_dheader_Exit: ; Exit
2532 ret
2533
2534SET_DRIVE_CACHE_HEADER ENDP
2535
2536
2537
2538
2539
2540subttl Convert to caps
2541page
2542;=========================================================================
2543; Procedure: Convert_to_caps
2544;
2545; CONVERT LOWER CASE CHARACTERS TO UPPER CASE
2546; Convert character in al to a capital letter.
2547
2548;=========================================================================
2549
2550CONVERT_TO_CAPS PROC NEAR
2551
2552 cmp al,"a"
2553 JNAE no_convert
2554 cmp al,"z"
2555 JNBE no_convert
2556 sub al,32
2557
2558No_Convert:
2559 ret ;and return
2560
2561CONVERT_TO_CAPS ENDP
2562
2563
2564
2565
2566
2567
2568
2569;=========================================================================
2570; SET_EMS : THIS MODULE SETS EMS FOR FASTOPEN CODE AND DATA
2571; PAGE 0 IN HIGH MEMORY IS MAPPED FOR CODE USING
2572; THE PHYSICAL PAGE FRAME AND PAGE 1 IS
2573; MAPPED FOR DATA USING PHYSICAL PAGE FRAME NUMBER
2574; TWO PHYSICAL PAGE FRAME SEG IDs ARE SAVED AND
2575; THEY WILL BE USED BY THE (MAIN) ROUTINE.
2576;
2577; INPUTS : NONE
2578;
2579; OUTPUTS : CY - ERROR
2580;
2581; NC - EMS_PAGE_SEG - SEG ID OF SINGLE PAGE FRAME
2582;=========================================================================
2583
2584SET_EMS PROC NEAR
2585 CALL EMS_CHECK1 ;SEE IF EMS INSTALLED ;AN000;
2586 JNC EMS_GET_PAGE ; yes, get page ;AN000;
2587
2588 MOV EMS_FLAG,0 ; Flag EMS not installed ;AN000;
2589 STC ; Make sure carry is Clear ;AN000;
2590 JMP EMS_EXIT ; Leave check routine ;AN000;
2591
2592EMS_GET_PAGE:
2593 PUSH ES ; save ES,DI they may destroy by 2F
2594 PUSH DI
2595
2596IF NOT BUFFERFLAG
2597
2598 MOV AH,EMS_2F_HANDLER
2599 XOR AL,AL
2600 INT 2FH ; see 2F is there
2601 CMP AL,0FFH
2602 JNE EMS_PAGE_ERR ; error, if not
2603
2604 MOV AH,EMS_2F_HANDLER
2605 MOV AL,0FFH
2606 MOV DI,0FEH
2607 INT 2FH ; get EMS page
2608 OR AH,AH
2609 JNZ EMS_PAGE_ERR
2610 MOV EMS_PAGE_SEG,ES ; SAVE PAGE SEG ID
2611 MOV EMS_PAGE_NUM,DI ; SAVE PHYSICAL PAGE NUMBER
2612
2613ELSE
2614
2615;---------------------------------------------------------------HKN 8/25/88
2616; Fastopen must get an EMS page like a well behaved program and
2617; should not grab a reserved page from the BIOS.
2618;
2619 mov cx, FRAME_COUNT
2620 xor ax, ax
2621 mov bx, ax
2622 mov dx, ax
2623
2624get_page:
2625 cmp es:[di], 0a000h ; is the page in ax above 640K
2626 jb next_page ; if no get next_page
2627
2628 mov bx, di ; we have a valid page
2629
2630 inc dx ; count the # of pages above 640K
2631
2632 cmp dx, 1
2633 je next_page
2634 sub di, 4
2635 mov ax, es:[di]
2636 mov [FST_PAGE], ax
2637 mov ax, es:[di+2]
2638 mov [FST_PAGE+2], ax
2639 mov di, bx ; restore di
2640
2641next_page:
2642 add di, 4
2643 loop get_page
2644 jne found_page
2645 jmp ems_page_err
2646
2647found_page:
2648; int 3
2649 cmp dx, 1
2650 jne second_last_page
2651 mov di, bx
2652 mov ax, es:[di]
2653 mov ems_page_seg, ax
2654 mov ax, es:[di+2]
2655 mov ems_page_num, ax
2656 jmp save_state
2657
2658second_last_page:
2659 mov ax, [FST_PAGE]
2660 mov ems_page_seg, ax
2661 mov ax, [FST_PAGE+2]
2662 mov ems_page_num, ax
2663
2664save_state:
2665 push es
2666 mov ax, Cseg_Main
2667 mov es, ax
2668 assume es:Cseg_Main
2669
2670 mov word ptr save_map_addr, offset es:save_ems_page_state
2671 mov word ptr save_map_addr + 2, ax
2672
2673 mov ax, ems_page_seg
2674 mov es:Main_EMS_PAGE_SEG, ax
2675 pop es
2676 assume es:Cseg_Init
2677 call [save_map_addr]
2678 jc ems_page_err
2679
2680;--------------------------------------------------------------------------
2681
2682ENDIF
2683
2684 POP DI
2685 POP ES
2686 JMP SHORT EMS_ALLOCATE_PAGE
2687
2688EMS_PAGE_ERR:
2689 POP DI
2690 POP ES
2691 STC ;yes, page not found ;AN000;
2692 JMP SHORT EMS_ERROR ;error exit ;AN000;
2693
2694;-----------------------------------------------------------------------
2695; Allocate one page
2696;-----------------------------------------------------------------------
2697EMS_ALLOCATE_PAGE:
2698 MOV BX,1 ;one page ;AN000;
2699 MOV AH,EMS_ALLOC_PAGES ;set op code ;AN000;
2700 INT EMS_INT ;allocate page ;AN000;
2701 OR AH,AH ;Was there an error allocating? ;AN000;
2702 JNZ EMS_ERROR ;yes - display error ;AN000;
2703 MOV EXT_HANDLE,DX ;no -Save EMS handle
2704
2705IF BUFFERFLAG
2706
2707;------------------------------------------------------HKN 8/25/88
2708; Must save ems handle in Cseg_Main also.
2709
2710 push es
2711 push ax
2712 mov ax, Cseg_Main
2713 mov es, ax
2714 assume es:Cseg_Main
2715 mov es:ems_save_handle1, dx
2716 pop ax
2717 pop es
2718 assume es:Cseg_Init
2719
2720ENDIF
2721
2722;-----------------------------------------------------------------------
2723; SET HANDLE NAME TO THE PAGE HANDLE
2724;-----------------------------------------------------------------------
2725 PUSH DS ;AN000;
2726 POP ES ;AN000;
2727 ASSUME ES:CSEG_INIT ;AN000;
2728 LEA SI,HANDLE_NAME ; DS:SI-->Handle name string ;AN000;
2729 MOV DX,EXT_HANDLE ; handle number ;AN000;
2730 MOV AH,EMS_HANDLE_NAME ;AN000;
2731 MOV AL,1 ; set op code code ;AN000;
2732 INT 67H ; set handle ;AN000;
2733 OR AH,AH ;AN000;
2734 JNZ EMS_ERROR ; jump if error ;AN000;
2735
2736;-----------------------------------------------------------------------
2737; Map logical page 0 in physical page frame FE (P254)
2738;-----------------------------------------------------------------------
2739 CALL MAP_FRAME ;map two pages ;AN000;
2740 JNC EMS_GET_SIZE ;no error, normal exit ;AN000;
2741
2742;-----------------------------------------------------------------------
2743; Get partial page map size
2744;-----------------------------------------------------------------------
2745EMS_GET_SIZE:
2746 MOV AH,EMS_PAGE_SIZE ;Allocate requested pages ;AN000;
2747 MOV AL,2
2748 INT EMS_INT ; ;AN000;
2749 OR AH,AH
2750 JNZ EMS_ERROR
2751 XOR AH,AH
2752 MOV EMS_PAGESIZE,AX ;save EMS page size
2753 CLC
2754 JMP SHORT EMS_EXIT
2755
2756EMS_ERROR:
2757 MOV AX,EMS_FAILED ;error message ;AN000;
2758 MOV MSG_NUM,AX ;save message number
2759 MOV SUBST_COUNT,0 ;no message substitution ;AN000;
2760 MOV MSG_CLASS,-1 ;message class ;AN000;
2761 MOV INPUT_FLAG,0 ;no input ;AN000;
2762 CALL PRINT_STDOUT ;show message "Incorrect Parameter" ;AN000;
2763 STC ; set error flag ;AN000;
2764
2765EMS_EXIT:
2766 RET ; Return ;AN000;
2767
2768SET_EMS ENDP
2769
2770
2771
2772
2773
2774
2775;=========================================================================
2776; EMS_CHECK1 : THIS MODULE DETERMINES WHETHER OR NOT EMS IS
2777; INSTALLED FOR THIS SESSION.
2778;
2779; INPUTS : NONE
2780;
2781; OUTPUTS : ES:BX - FRAME ARRAY
2782; CY - EMS NOT AVAILABLE
2783; NC - EMS AVAILABLE
2784;=========================================================================
2785
2786EMS_CHECK1 PROC NEAR ;EMS INSTALL CHECK
2787
2788 PUSH DS ;save ds ;AN000;
2789 XOR AX,AX ;set ax to 0 ;AN000;
2790 MOV DS,AX ;set ds to 0 ;AN000;
2791 CMP DS:WORD PTR[067h*4+0],0 ;see if int 67h is there ;AN000;
2792 POP DS ;restore ds ;AN000;
2793 JE EMS_NOT_INST1 ;no, EMS not installed ;AN000;
2794
2795 MOV AH,EMS_GET_STATUS ;YES, GET STATUS ;AN000;
2796 INT EMS_INT ;INT 67H ;AN000;
2797 CMP AH,0 ;EMS MANAGER PRESENT ??
2798 JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED
2799
2800 MOV AH,EMS_GET_VERSION ;YES, GET STATUS ;AN000; ;AN000;
2801 INT EMS_INT ;INT 67H ;AN000;;AN000;
2802 CMP AH,0 ;EMS MANAGER PRESENT ?? ;AN000;
2803 JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED ;AN000;
2804
2805 CMP AL,40H ;VERSION 4.0 ?? ;AN000;
2806 JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED ;AN000;
2807
2808 MOV AX,EMS_GET_COUNT
2809 INT EMS_INT ;GET ARRAY COUNT
2810 CMP AH,0
2811 JNE EMS_NOT_INST1
2812
2813 MOV FRAME_COUNT,CX
2814 MOV AX, BUFFER_ENTRY_SIZE
2815 MUL CX ; CALCULATE THE ARRAY SIZE BE RESERVED
2816
2817IF NOT IBMCOPYRIGHT
2818 CMP AX, 100h
2819ELSE
2820 CMP AX, 30H
2821ENDIF
2822
2823 JG EMS_NOT_INST1
2824
2825 MOV AX,EMS_GET_FRAME_ADDR ;YES, GET FRAME ADDRESS ;AN000;
2826 PUSH DS ;SWAP DS & ES ;AN000;
2827 POP ES ; ;AN000;
2828 LEA DI,FRAME_BUFFER ;ES:DI--> RESULT BUFFER ;AN000;
2829 INT EMS_INT ;GET FRAME ADDRESSES ;AN000;
2830 CMP AH,0 ;IS EMS INSTALLED ;AN000;
2831 JNE EMS_NOT_INST1 ;NO,exit
2832 CMP CX,FRAME_COUNT ; ;AN000;
2833 JNE SHORT EMS_NOT_INST1
2834
2835 CLC
2836 MOV EMS_FLAG,1 ; EMS IS ACTIVE, SET FLAG
2837 JMP EMS_CHECK1_EXIT
2838
2839EMS_NOT_INST1: ;EMS NOT INSTALLED
2840 MOV AX,EMS_NOT_INSTALL ;error message ;AN000;
2841 MOV MSG_NUM,AX ;set message number ;AN000;
2842 MOV SUBST_COUNT,0 ;no message substitution ;AN000;
2843 MOV MSG_CLASS,-1 ;message class ;AN000;
2844 MOV INPUT_FLAG,0 ;no input ;AN000;
2845 CALL PRINT_STDOUT ;show message
2846 STC ;FLAG EMS NOT INSTALLED ;AN000;
2847 ;AN000;
2848EMS_CHECK1_EXIT: ;EXIT ROUTINE
2849 RET ;RETURN TO CALLER ;AN000;
2850
2851EMS_CHECK1 ENDP
2852
2853
2854
2855
2856;=========================================================================
2857; MAP_FRAME : THIS MODULE MAPS TWO LOGICAL PAGES IN THE HIGH
2858; MEMORY TO TWO PHYSICAL PAGE FEAMES IN THE LOW
2859; MEMORY.
2860;
2861; INPUTS : EXT_HANDLE - HANDLE
2862;
2863; OUTPUTD CY - ERROR
2864; NC - PAGE IS MAPPED
2865;=========================================================================
2866
2867MAP_FRAME PROC NEAR ; MAP physical page frames
2868 PUSH BX ; DMS;
2869 XOR BX,BX ; Logical page 0 ;AN000;
2870 MOV AX,EMS_PAGE_NUM ; AL=Physical Page frame number ;AN000;
2871 MOV AH,EMS_MAP_HANDLE ; AH=EMS function to map page ;AN000;
2872 MOV DX,EXT_HANDLE ; EMS handle ;AN000;
2873 INT EMS_INT ;AN000;
2874 OR AH,AH ; Was there an error allocating? ;AN000;
2875 JNZ MAP_ERROR ; yes - set flag ;AN000;
2876 CLC
2877 JMP SHORT MAP_EXIT ; no - exit ;AN000;
2878
2879MAP_ERROR:
2880 STC ; set error flag ;AN000;
2881
2882MAP_EXIT:
2883 POP BX ;AN000;
2884 RET ; return ;AN000;
2885
2886
2887MAP_FRAME ENDP
2888
2889
2890
2891
2892
2893
2894
2895
2896;************************************************************
2897;*
2898;* SUBROUTINE NAME: PRINT_STDOUT
2899;*
2900;* SUBROUTINE FUNCTION:
2901;* Display the requested message to the specified handle
2902;*
2903;* INPUT:
2904;* Paramters in parater storage area
2905;* DS:SI-->Substitution List
2906;* ES:DI-->PTR to input buffer if buffered keyboard
2907;* input is specified (DL = 0A)
2908;* OUTPUT:
2909;* AX = Single character entered if DL=01
2910;* OR
2911;* ES:DI-->input buffer where string is returned if DL=0A
2912;*
2913;* The message corresponding to the requested msg number will
2914;* be written to Standard Out. Message substitution will
2915;* be performed if specified
2916;*
2917;* NORMAL EXIT:
2918;* Message will be successfully written to requested handle.
2919;*
2920;* ERROR EXIT:
2921;* None. Note that theoretically an error can be returned from
2922;* SYSDISPMSG, but there is nothing that the application can do.
2923;*
2924;* INTERNAL REFERENCES: SysDispMsg
2925;*
2926;* EXTERNAL REFERENCES:
2927;* None
2928;*
2929;************************************************************
2930PRINT_STDOUT PROC NEAR
2931 PUSH BX ;AN000;
2932 PUSH CX ;AN000;
2933 PUSH DX ;AN000;
2934
2935 MOV AX,MSG_NUM ; Message ID ;AN000;
2936 MOV BX,STDOUT ; standard input message handle ;AN000;
2937 MOV CX,SUBST_COUNT ; message substitution count ;AN000;
2938 MOV DH,MSG_CLASS ; message class ;AN000;
2939 MOV DL,INPUT_FLAG ; Type of INT 10 for KBD input ;AN000;
2940
2941 CALL SYSDISPMSG ; AX=Extended key value if wait ;AN000;
2942 ;for key ;AN000;
2943 JNC DISP_DONE ; If CARRY SET then registers
2944 ;will contain extended error info ;AN000;
2945 ; AX - Extended error Number
2946 ; BH - Error Class
2947 ; BL - Suggested action
2948DISP_DONE: ; CH - Locus
2949 POP DX ;AN000;
2950 POP CX ;AN000;
2951 POP BX ;AN000;
2952 ;AN000;
2953 RET
2954PRINT_STDOUT ENDP
2955
2956
2957CSEG_INIT ENDS
2958
2959
2960;===========================================================================
2961;;; STACK SEGMENT SIZE = 20 PARAGRAPHS
2962;===========================================================================
2963
2964STACK SEGMENT PARA STACK 'STACK'
2965 DB 64 dup("STACK ") ; 512 WORD STACK AREA ;AN000;
2966STACK ENDS
2967
2968
2969END START
2970