summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/SYSINIT1.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/BIOS/SYSINIT1.ASM')
-rw-r--r--v4.0/src/BIOS/SYSINIT1.ASM2668
1 files changed, 2668 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/SYSINIT1.ASM b/v4.0/src/BIOS/SYSINIT1.ASM
new file mode 100644
index 0000000..7869b76
--- /dev/null
+++ b/v4.0/src/BIOS/SYSINIT1.ASM
@@ -0,0 +1,2668 @@
1 PAGE ,132 ;
2; SCCSID = @(#)sysinit1.asm 1.7 85/10/24
3TITLE BIOS SYSTEM INITIALIZATION
4%OUT ...SYSINIT1
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001; p40 Boot from the system with no floppy diskette drives 6/26/87 J.K.
12;AN002; d24 MultiTrack= command added. 6/29/87 J.K.
13;AN003; d9 Double word mov for 386 machine 7/15/87 J.K.
14;AN004; p447 BUFFERS = 50 /E without EMS installed hangs 8/25/87 J.K.
15;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K.
16;AN006; p851 Installable files not recognized corretly. 9/08/87 J.K.
17;AN007; p1299 Set the second entry of DEVMARK for MEM command 9/25/87 J.K.
18;AN008; p1361 New Extended Attribute 9/28/87 J.K.
19;AN009; p1326 Buffers = 50 /e hangs 9/28/87 J.K.
20;AN010; New EMS Interface
21;AN011; New Message SKL file 10/20/87 J.K.
22;AN012; P2211 Setting EA=7 for ANSI.SYS hangs the system 11/02/87 J.K.
23;AN013; p2343 Set the name for SYSINIT_BASE for MEM command 11/11/87 J.K.
24;AN014; D358 New device driver INIT function package 12/03/87 J.K.
25;AN015; For Installed module with no parameter 12/11/87 J.K.
26;AN016; D285 Undo the Extended Attribute handling 12/17/87 J.K.
27;AN017; P2806 Show "Error in CONFIG.SYS ..." for INSTALL= command 12/17/87 J.K.
28;AN018; P2914 Add Extended Memory Size in SYSVAR 01/05/88 J.K.
29;AN019; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K.
30;AN020; P3497 Performace fix for new buffer scheme 02/15/88 J.K.
31;AN021; D486 SHARE installation for big media 02/23/88 J.K.
32;AN022; D493 Undo D358 & do not show error message for device driv02/24/88 J.K.
33;AN023; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K.
34;AN024; D506 Take out the order dependency of the IFS= 03/28/88 J.K.
35;AN025; P4086 Memory allocation error when loading SHARE.EXE 03/31/88 J.K.
36;AN026; D517 New Balanced Real memory buffer set up scheme 04/18/88 J.K.
37;AN027; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K.
38;AN028; P4669 SHARE /NC causes an error 05/03/88 J.K.
39;AN029; P4759 Install EMS INT2fh, INT 67h handler 05/12/88 J.K.
40;AN030; P4934 P4759 INT 2Fh handler number be changed to 1Bh 05/20/88 J.K.
41;==============================================================================
42
43TRUE EQU 0FFFFh
44FALSE EQU 0
45CR equ 13
46LF equ 10
47TAB equ 9
48
49IBMVER EQU TRUE
50IBM EQU IBMVER
51STACKSW EQU TRUE ;Include Switchable Hardware Stacks
52IBMJAPVER EQU FALSE ;If TRUE set KANJI true also
53MSVER EQU FALSE
54ALTVECT EQU FALSE ;Switch to build ALTVECT version
55KANJI EQU FALSE
56MYCDS_SIZE equ 88 ;J.K. Size of Curdir_List. If it is not
57 ;the same, then will generate compile error.
58
59;
60 IF IBMJAPVER
61NOEXEC EQU TRUE
62 ELSE
63NOEXEC EQU FALSE
64 ENDIF
65
66DOSSIZE EQU 0A000H
67;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS.
68
69.xlist
70; INCLUDE dossym.INC
71 include smdossym.inc ;J.K. Reduced version of DOSSYM.INC
72 INCLUDE devsym.INC
73 include ioctl.INC
74 include BIOSTRUC.INC
75 include smifssym.inc ;AN000;
76 include defems.inc ;AN010;
77 include DEVMARK.inc ;AN005;
78 include cputype.inc
79
80 include version.inc
81
82.list
83
84;AN000 J.K. If MYCDS_SIZE <> CURDIRLEN, then force a compilatiaon error.
85 if MYCDS_SIZE NE CURDIRLEN
86 %OUT  !!! SYSINIT1 COMPILATION FAILED. DIFFERENT CDS SIZE !!!
87 .ERRE MYCDS_SIZE EQ CURDIRLEN
88 endif
89
90 IF NOT IBMJAPVER
91 EXTRN RE_INIT:FAR
92 ENDIF
93
94;---------------------------------------
95;Equates for Main stack and stack Initialization program
96 IF STACKSW
97
98EntrySize equ 8
99
100MinCount equ 8
101DefaultCount equ 9
102MaxCount equ 64
103
104MinSize equ 32
105DefaultSize equ 128
106MaxSize equ 512
107
108AllocByte equ es:byte ptr [bp+0]
109IntLevel equ es:byte ptr [bp+1]
110SavedSP equ es:word ptr [bp+2]
111SavedSS equ es:word ptr [bp+4]
112NewSP equ es:word ptr [bp+6]
113Free equ 0
114allocated equ 1
115overflowed equ 2
116clobbered equ 3
117
118
119;External variables in IBMBIO for INT19h handling rouitne. J.K. 10/23/86
120CODE segment public 'code'
121 EXTRN Int19sem:byte
122
123 IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77>
124 EXTRN Int19OLD&AA:dword
125 ENDM
126CODE ends
127 ENDIF
128;---------------------------------------
129;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track
130MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns
131 ; it on after handling CONFIG.SYS file as a
132 ; default value, if MulTrk_flag = MULTRK_OFF1.
133MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered.
134MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off.
135
136CODE segment public 'code'
137 EXTRN MulTrk_flag:word ;AN002;
138CODE ends
139;J.K. 6/29/87 End of Multi-track definition.
140
141SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
142
143ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
144
145 EXTRN BADCOM:BYTE
146 EXTRN SYSSIZE:BYTE
147 EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE
148 extrn DeviceParameters:byte
149 extrn DevMark_Addr:word
150 extrn SetDevMarkFlag:byte
151 extrn PathString:byte ;AN021;
152 extrn LShare:byte ;AN021;
153 extrn ShareWarnMsg:byte ;AN021;
154
155 EXTRN INT24:NEAR,MEM_ERR:NEAR
156 EXTRN DOCONF:NEAR
157 extrn Multi_Pass:NEAR ;AN024;
158 extrn BadLoad:near
159 extrn Error_Line:near
160
161 PUBLIC CURRENT_DOS_LOCATION
162 PUBLIC FINAL_DOS_LOCATION
163 PUBLIC DEVICE_LIST
164 PUBLIC SYSI_COUNTRY
165 PUBLIC MEMORY_SIZE
166 PUBLIC DEFAULT_DRIVE
167 PUBLIC BUFFERS
168 PUBLIC FILES
169 PUBLIC NUM_CDS
170 PUBLIC SYSINIT
171 PUBLIC CNTRYFILEHANDLE
172 PUBLIC COMMAND_LINE
173 public Big_Media_Flag ;AN021;Set by IBMINIT
174
175 IF STACKSW
176 ;Internal Stack Information
177 PUBLIC STACK_COUNT
178 PUBLIC STACK_SIZE
179 PUBLIC STACK_ADDR
180 ENDIF
181
182 PUBLIC dosinfo,entry_point
183 PUBLIC fcbs,keep
184 PUBLIC confbot,alloclim
185 PUBLIC zero,sepchr,STALL
186 PUBLIC count,chrptr,org_count
187 PUBLIC bufptr,memlo,prmblk,memhi
188 PUBLIC ldoff,area,PACKET,UNITCOUNT
189 PUBLIC BREAK_ADDR,BPB_ADDR,drivenumber
190 public Config_Size
191 public Install_Flag
192 public COM_Level
193 public CMMT
194 public CMMT1
195 public CMMT2
196 public Cmd_Indicator
197 public LineCount
198 public ShowCount
199 public Buffer_LineNum
200 public DoNotShowNum
201 public IFS_Flag
202 public IFS_RH
203 public H_Buffers
204 public Buffer_Slash_X ;AN023;
205 public ConfigMsgFlag ;AN014;
206 public Do_Install_Exec ;AN019;
207 public Multi_Pass_Id ;AN024;
208
209
210;
211SYSINIT$:
212 IF STACKSW
213.SALL
214 include MSSTACK.INC ;Main stack program and data definitions
215; include STKMES.INC ;Fatal stack error message
216 include MSBIO.CL5 ;Fatal stack error message
217.XALL
218 public Endstackcode
219Endstackcode label byte
220 ENDIF
221
222;
223SYSINIT:
224 JMP GOINIT
225DOSINFO LABEL DWORD
226 DW 0000
227CURRENT_DOS_LOCATION DW 0000
228
229MSDOS LABEL DWORD
230ENTRY_POINT LABEL DWORD
231 DW 0000
232FINAL_DOS_LOCATION DW 0000
233DEVICE_LIST DD 00000000
234
235SYSI_Country LABEL DWORD ;J.K. 5/29/86 Pointer to
236 DW 0000 ;country table in DOS
237 DW 0000
238
239Fake_Floppy_Drv db 0 ;AN001;Set to 1 if this machine
240 ;does not have any floppies!!!
241Big_Media_Flag db 0 ;AN021;Set by IBMINIT if > 32 MB fixed media exist.
242;
243;Variables for Stack Initialization Program.
244 IF STACKSW
245STACK_COUNT DW DefaultCount
246STACK_SIZE DW DefaultSize
247STACK_ADDR DD 00000000
248 ENDIF
249; various default values
250
251MEMORY_SIZE DW 0001
252DEFAULT_DRIVE DB 00 ;initialized by IBMINIT.
253BUFFERS DW -1 ; initialized during buffer allocation
254H_Buffers dw 0 ;AN000; # of the Heuristic buffers. Initially 0.
255Buffer_Pages dw 0 ;AN000; # of extended memory pages for the buffer.
256BufferBuckets dw 0 ;AN000;
257Buffer_odds dw 0 ;AN000;
258SingleBufferSize dw ? ;AN000; Maximum sector size + buffer header
259MaxNumBuf1 db 15 ;AN026;Num of buffers in a bucket group 1.
260MaxNumBuf2 db 15 ;AN026;Num of buffers in a possible bucket group 2.
261NthBuck db 0 ;AN026; 1st bucket group = 1st bucket through Nth Bucket. The rest = second group
262
263IF BUFFERFLAG
264
265FIRST_PAGE DW 0, 0
266LAST_PAGE DW 0, 0
267NPA640 DW 0
268EMS_SAVE_BUF DB 0,0,0,0,0,0,0,0,0,0,0,0
269
270ENDIF
271
272FILES DB 8 ; enough files for pipe
273FCBS DB 4 ; performance for recycling
274Keep DB 0 ; keep original set
275NUM_CDS DB 5 ; 5 net drives
276CONFBOT DW ?
277ALLOCLIM DW ?
278FOOSTRNG DB "A:\",0
279COMMAND_LINE DB 2,0,"P" ;Default Command.com Args
280 DB 29 DUP (0)
281ZERO DB 0
282SepChr DB 0
283LineCount dw 0 ;AN000; Line count in config.sys
284ShowCount db ' ',CR,LF,'$' ;AN000; Used to convert Linecount to ASCII.
285Buffer_LineNum dw 0 ;AN000; Line count for "BUFFERS=" command if entered.
286
287Sys_Model_Byte db 0FFh ;model byte used in SYSINIT
288Sys_Scnd_Model_Byte db 0 ;secondary model byte used in SYSINIT
289;
290Buffer_Slash_X db 0 ;AN000;AN023; BUFFERS= ... /X option entered.
291Real_IBM_Page_Id dw 0 ;AN029;
292IBM_Frame_Seg dw 0 ;AN000; segment value for physical IBM page frame.
293Frame_Info_Buffer dw (MAX_NUM_PAGEFRAME * 4) dup (0) ;AN010; For EMS. as per spec. 2 words per entry
294EMSHandleName db 'BUFFERS ' ;AN010; 8 char. EMS handle name
295EMS_Ctrl_Tab dd 0 ;AN010;
296EMS_State_Buf dd 0 ;AN010;
297BUF_PREV_OFF dw 0 ;AN020;
298EMS_Buf_First dw 0 ;AN020;
299
300 IF NOT NOEXEC
301COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO>
302 ENDIF
303
304;------------------------------------------------------------------
305;J.K. 2/23/87 ;variables for INSTALL= command.
306
307Multi_Pass_Id db 0 ;AN024;AN027;
308Install_Flag dw 0 ;AN000;
309 HAVE_INSTALL_CMD equ 00000001b ;AN019; CONFIG.SYS has INSTALL= commands
310 HAS_INSTALLED equ 00000010b ;AN019; SYSINIT_BASE installed.
311 SHARE_INSTALL equ 00000100b ;AN021; Used to install SHARE.EXE
312
313Config_Size dw 0 ;AN000; size of config.sys file. Set by SYSCONF.ASM
314Sysinit_Base_Ptr dd 0 ;AN000; pointer to SYSINIT_BASE
315Sysinit_Ptr dd 0 ;AN000; returning addr. from SYSINIT_BASE
316CheckSum dw 0 ;AN000; Used by Sum_up
317
318Ldexec_FCB db 20 dup (' ') ;AN000;big enough
319Ldexec_Line db 0 ;AN000;# of parm characters
320Ldexec_start db ' ' ;AN000;
321Ldexec_parm db 80 dup (0) ;AN000;
322
323INSTEXE EXEC0 <0,Ldexec_Line,Ldexec_FCB,Ldexec_FCB> ;AN000;
324
325;AN016; Undo the extended attribute handling
326;EA_QueryList label byte
327; dw 1 ;AN008; I need just one EA info.
328; db 02h ;AN008; Type is BINARY
329; dw 8000h ;AN008; Flag is SYSTEM DEFINED.
330; db 8 ;AN008; Length of name is 8 bytes
331; db 'FILETYPE' ;AN008; Name is FILETYPE
332;Ext_Attr_List dw 1 ;AN008; Just 1 Extended attribute List
333; db 2 ;AN008;EA_TYPE
334; dw 8000h ;AN008;FLAG
335; db 0 ;AN008;Failure reason
336; db 8 ;AN008;Length of NAME
337; dw 1 ;AN008;Length of VALUE
338; db 'FILETYPE' ;AN008;Name
339;Ext_Attr_Value db 0 ;AN008;Value
340;SIZE_EXT_ATTR_LIST equ $-Ext_Attr_List ;AN008;
341;
342;;Extended attribute value
343;EA_INSTALLABLE equ 4 ;AN008;Value for Installable file
344
345;------------------------------------------------------------------
346;J.K. 5/15/87 ;Request header, variables for IFS= command.
347
348IFS_Flag dw 0 ;AN000; Set to 1 if it is an IFS.
349 IS_IFS equ 00000001b ;IFS command?
350 NOT_IFS equ 11111110b
351
352IFS_RH IFSRH <LENGTH_INIT, IFSINIT,,,,> ;AN000; IFS initialization request packet
353
354;------------------------------------------------------------------
355;Variables for Comment=
356COM_Level db 0 ;AN000;level of " " in command line
357CMMT db 0 ;AN000;length of COMMENT string token
358CMMT1 db 0 ;AN000;token
359CMMT2 db 0 ;AN000;token
360Cmd_Indicator db ? ;AN000;
361DoNotShowNum db 0 ;AN000;
362
363;------------------------------------------------------------------
364COUNT DW 0000
365Org_Count dw 0000 ;AN019;
366CHRPTR DW 0000
367CntryFilehandle DW 0000
368Old_Area dw 0 ;AN013;
369Impossible_Owner_Size dw 0 ;AN013; Paragraph
370;------------------------------------------------------------------
371BucketPTR LABEL dword ;AN000;
372BUFPTR LABEL DWORD ;LEAVE THIS STUFF IN ORDER!
373MEMLO DW 0
374PRMBLK LABEL WORD
375MEMHI DW 0
376LDOFF DW 0
377AREA DW 0
378
379PACKET DB 24 ;AN014; Was 22
380 DB 0
381 DB 0 ;INITIALIZE CODE
382 DW 0
383 DB 8 DUP (?)
384UNITCOUNT DB 0
385BREAK_ADDR DD 0
386BPB_ADDR DD 0
387DriveNumber DB 0
388ConfigMsgFlag dw 0 ;AN014;AN022; Used to control "Error in CONFIG.SYS line #" message
389
390TempStack DB 80h DUP (?)
391
392GOINIT:
393;J.K. before doing anything else, let's set the model byte
394;SB33043*****************************************************************
395 mov ah,0c0h ;get system configuration ;SB ;3.30*
396 int 15h ; * ;SB ;3.30*
397;SB33043*****************************************************************
398 jc No_ROM_Config
399 cmp ah, 0 ; double check
400 jne No_ROM_Config
401 mov al, ES:[BX.bios_SD_modelbyte]
402 mov cs:[Sys_Model_Byte], al
403 mov al, ES:[BX.bios_SD_scnd_modelbyte]
404 mov cs:[Sys_Scnd_Model_Byte], al
405 jmp short Move_Myself
406No_ROM_Config: ; Old ROM
407 mov ax, 0f000h
408 mov ds, ax
409 mov al, byte ptr ds:[0fffeh]
410 mov cs:[Sys_Model_Byte], al ;set the model byte.
411;J.K.6/24/87 Set Fake_Floppy_Drv if there is no diskette drives in this machine.
412;SB34SYSINIT1001********************************************************
413;SB execute the equipment determination interrupt and then
414;SB check the returned value to see if we have any floppy drives
415;SB if we have no floppy drive we set cs:Fake_Floppy_Drv to 1
416;SB See the AT Tech Ref BIOS listings for help on the equipment
417;SB flag interrupt (11h)
418
419 int 11h
420 test ax,1 ; has floppy ?
421 jnz Move_Myself
422 mov cs:Fake_Floppy_Drv,1 ; no floppy, fake.
423
424;SB34SYSINIT1001********************************************************
425Move_Myself:
426 CLD ; Set up move
427 XOR SI,SI
428 MOV DI,SI
429
430 IF MSVER
431 MOV CX,cs:[MEMORY_SIZE]
432 CMP CX,1 ; 1 means do scan
433 JNZ NOSCAN
434 MOV CX,2048 ;START SCANNING AT 32K BOUNDARY
435 XOR BX,BX
436
437MEMSCAN:INC CX
438 JZ SETEND
439 MOV DS,CX
440 MOV AL,[BX]
441 NOT AL
442 MOV [BX],AL
443 CMP AL,[BX]
444 NOT AL
445 MOV [BX],AL
446 JZ MEMSCAN
447SETEND:
448 MOV cs:[MEMORY_SIZE],CX
449 ENDIF
450
451 IF IBMVER OR IBMJAPVER
452 MOV CX,cs:[MEMORY_SIZE]
453 ENDIF
454
455NOSCAN: ; CX is mem size in para
456 MOV AX,CS
457 MOV DS,AX
458ASSUME DS:SYSINITSEG
459
460 MOV AX,OFFSET SYSSIZE
461 Call ParaRound
462 SUB CX,AX ;Compute new sysinit location
463 MOV ES,CX
464 MOV CX,OFFSET SYSSIZE + 1
465 SHR CX,1 ;Divide by 2 to get words
466 REP MOVSW ;RELOCATE SYSINIT
467
468 ASSUME ES:SYSINITSEG
469
470 PUSH ES
471 MOV AX,OFFSET SYSIN
472 PUSH AX
473
474AAA_DUMMY PROC FAR
475 RET
476AAA_DUMMY ENDP
477;
478; MOVE THE DOS TO ITS PROPER LOCATION
479;
480SYSIN:
481
482 ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING
483
484 MOV AX,[CURRENT_DOS_LOCATION] ; Where it is (set by BIOS)
485 MOV DS,AX
486 MOV AX,[FINAL_DOS_LOCATION] ; Where it is going (set by BIOS)
487 MOV ES,AX
488
489 ASSUME ES:NOTHING
490
491 XOR SI,SI
492 MOV DI,SI
493
494 MOV CX,DOSSIZE/2
495 REP MOVSW
496
497 LDS SI,[DEVICE_LIST] ; Set for call to DOSINIT
498 MOV DX,[MEMORY_SIZE] ; Set for call to DOSINIT
499
500 CLI
501 MOV AX,CS
502 MOV SS,AX
503 MOV SP,OFFSET LOCSTACK ; Set stack
504
505 ASSUME SS:SYSINITSEG
506
507 IF NOT ALTVECT
508 STI ; Leave INTs disabled for ALTVECT
509 ENDIF
510LOCSTACK LABEL BYTE
511
512 CALL MSDOS ; Call DOSINIT
513 ;ES:DI -> SysInitVars_Ext
514 mov ax, word ptr es:[di.SYSI_InitVars] ;J.K. 5/29/86
515 mov word ptr [dosinfo], ax
516 mov ax, word ptr es:[di.SYSI_InitVars+2]
517 mov word ptr [dosinfo+2],ax ;set the sysvar pointer
518
519 mov ax, word ptr es:[di.SYSI_Country_Tab]
520 mov word ptr [SYSI_Country],ax
521 mov ax, word ptr es:[di.SYSI_Country_Tab+2]
522 mov word ptr [SYSI_Country+2],ax ;set the SYSI_Country pointer J.K.
523
524 les di, dosinfo ;es:di -> dosinfo
525
526 clc ;AN018;Get the extended memory size
527;SB34SYSINIT1002**************************************************************
528;SB execute the get extended memory size subfunction in the BIOS INT 15h
529;SB if the function reports an error do nothing else store the extended
530;SB memory size reported at the appropriate location in the dosinfo buffer
531;SB currently pointed to by es:di. Use the offsets specified in the
532;SB definition of the sysinitvars struct in inc\sysvar.inc
533;SB 5 LOCS
534
535 mov ah,88h
536 int 15h ;check extended memory size
537 jc No_Ext_Memory
538 mov es:[di].SYSI_EXT_MEM,ax ;save extended memory size
539No_Ext_Memory:
540
541;SB34SYSINIT1002**************************************************************
542 mov word ptr es:[di.SYSI_IFS], -1 ;AN000; Initialize SYSI_IFS chain.
543 mov word ptr es:[di.SYSI_IFS+2], -1 ;AN000;
544
545 mov ax, es:[di.SYSI_MAXSEC] ;AN020; Get the sector size
546 add ax, BUFINSIZ ;AN020; size of buffer header
547 mov [SingleBufferSize], ax ;AN020; total size for a buffer
548
549 mov al, Default_Drive ;AN000;Get the 1 based boot drive number set by IBMINIT
550 mov es:[di.SYSI_BOOT_DRIVE], al ;AN000; set SYSI_BOOT_DRIVE
551
552; Determine if 386 system...
553 Get_CPU_Type ; macro to determine cpu type
554 cmp ax, 2 ; is it a 386?
555 jne Not_386_System ; no: don't mess with flag
556 mov es:[di.SYSI_DWMOVE], 1 ;AN003;
557Not_386_System: ;AN003;
558 MOV AL,ES:[DI.SYSI_NUMIO]
559 MOV DriveNumber,AL ; Save start of installable block drvs
560
561 MOV AX,CS
562 SUB AX,11H ; room for header we will copy shortly
563 mov cx, [SingleBufferSize] ;AN020;Temporary Single buffer area
564 shr cx, 1 ;AN020;
565 shr cx, 1 ;AN020;
566 shr cx, 1 ;AN020;
567 shr cx, 1 ;AN020; Paragraphs
568 inc cx ;AN020;
569 sub ax, cx ;AN020;
570 MOV [CONFBOT],AX ; Temp "unsafe" location
571
572 push es ;AN020;
573 push di ;AN020;
574 les di, es:[di.SYSI_BUF] ;AN020;get the buffer hash entry pointer
575 les di, es:[di.HASH_PTR] ;AN020;
576 mov word ptr es:[di.BUFFER_BUCKET],0 ;AN020;
577 mov word ptr es:[di.BUFFER_BUCKET+2], ax ;AN020;
578 mov es, ax ;AN020;
579 xor ax, ax ;AN020;
580 mov di, ax ;AN020;es:di -> Single buffer
581 mov es:[di.BUF_NEXT], ax ;AN020;points to itself
582 mov es:[di.BUF_PREV], ax ;AN020;points to itself
583 mov word ptr es:[di.BUF_ID],00FFh ;AN020;free buffer, clear flag
584 mov word ptr es:[di.BUF_SECTOR], 0 ;AN020;
585 mov word ptr es:[di.BUF_SECTOR+2], 0 ;AN020;
586 pop di ;AN020;
587 pop es ;AN020;
588
589 PUSH DS ; Save as input to RE_INIT
590 PUSH CS
591 POP DS
592ASSUME DS:SYSINITSEG
593 CALL TEMPCDS ; Set up CDSs so RE_INIT and SYSINIT
594 ; can make DISK system calls
595
596 POP DS ; Recover DS input to RE_INIT
597ASSUME DS:NOTHING
598
599 IF NOT IBMJAPVER
600 CALL RE_INIT ; Re-call the BIOS
601 ENDIF
602
603 STI ; INTs OK
604 CLD ; MAKE SURE
605; DOSINIT has set up a default "process" (PHP) at DS:0. We will move it out
606; of the way by putting it just below SYSINIT at end of memory.
607 MOV BX,CS
608 SUB BX,10H
609 MOV ES,BX
610 XOR SI,SI
611 MOV DI,SI
612 MOV CX,80H
613 REP MOVSW
614 MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate
615 MOV AH,SET_CURRENT_PDB
616 INT 21H ; Tell DOS we moved it
617 PUSH DS
618 PUSH CS
619 POP DS
620ASSUME DS:SYSINITSEG
621 MOV DX,OFFSET INT24 ;SET UP INT 24 HANDLER
622 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
623 INT 21H
624
625 MOV BX,0FFFFH
626 MOV AH,ALLOC
627 INT 21H ;FIRST TIME FAILS
628 MOV AH,ALLOC
629 INT 21H ;SECOND TIME GETS IT
630 MOV [AREA],AX
631 MOV [MEMHI],AX ; MEMHI:MEMLO now points to
632 ; start of free memory
633 IF ALTVECT
634 MOV DX,OFFSET BOOTMES
635 invoke PRINT ;Print message DOSINIT couldn't
636 ENDIF
637
638 POP DS
639ASSUME DS:NOTHING
640
641 MOV DL,[DEFAULT_DRIVE]
642 OR DL,DL
643 JZ NODRVSET ; BIOS didn't say
644 DEC DL ;A = 0
645 MOV AH,SET_DEFAULT_DRIVE
646 INT 21H ;SELECT THE DISK
647;J.K. 2/23/87 Modified to handle INSTALL= command.
648NODRVSET:
649 CALL DOCONF ;DO THE CONFIG STUFF
650 inc cs:Multi_Pass_Id ;AN027;
651 call Multi_Pass ;AN027;
652 inc cs:Multi_Pass_Id ;AN024;
653 call Multi_Pass ;AN024;
654 call EndFile
655 test Install_Flag, HAVE_INSTALL_CMD ;AN019;
656 jz DoLast ;AN019;
657 inc cs:Multi_Pass_Id ;AN024;
658 call Multi_Pass ;AN019;AN024; Execute INSTALL= commands
659
660;J.K. [AREA] has the segment address for the allocated memory of SYSINIT,CONFBOT.
661;Free the CONFBOT area used for CONFIG.SYS and SYSINIT itself.
662DoLast:
663 call LoadShare ;AN021; Try to load share.exe, if needed.
664 mov cs:[DoNotShowNum], 1 ;AN000; Done with CONFIG.SYS. Do not show line number message.
665 mov cx, [area] ;AN000;
666 mov es, cx ;AN000;
667 mov ah, 49h ;AN000; Free allocated memory for command.com
668 int 21h ;AN000;
669
670 test cs:[Install_flag], HAS_INSTALLED ;AN013; SYSINIT_BASE installed?
671 jz Skip_Free_SYSINITBASE ;AN013; No.
672;Set Block from the Old_Area with Impossible_Owner_size.
673;This will free the unnecessary SYSINIT_BASE that had been put in memory to
674;handle INSTALL= command.
675 push es ;AN013;
676 push bx ;AN013;
677 mov ax, cs:[Old_Area] ;AN013;
678 mov es, ax ;AN013;
679 mov bx, cs:[Impossible_Owner_Size] ;AN013;
680 mov ah, SETBLOCK ;AN013;
681 int 21h ;AN013;
682 MOV AX,ES ;AN013;
683 DEC AX ;AN013;
684 MOV ES,AX ;Point to arena
685 MOV ES:[arena_owner],8 ;Set impossible owner
686 pop bx ;AN013;
687 pop es ;AN013;
688Skip_Free_SYSINITBASE: ;AN013;
689 IF NOEXEC
690 MOV BP,DS ;SAVE COMMAND.COM SEGMENT
691 PUSH DS
692 POP ES
693 MOV BX,CS
694 SUB BX,10H ; Point to current PHP
695 MOV DS,BX
696 XOR SI,SI
697 MOV DI,SI
698 MOV CX,80H
699 REP MOVSW ; Copy it to new location for shell
700 MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate
701 MOV BX,ES
702 MOV AH,SET_CURRENT_PDB
703 INT 21H ; Tell DOS we moved it
704 MOV ES:[PDB_PARENT_PID],ES ;WE ARE THE ROOT
705 ENDIF
706
707 PUSH CS
708 POP DS
709ASSUME DS:SYSINITSEG
710;
711; SET UP THE PARAMETERS FOR COMMAND
712;
713
714 MOV SI,OFFSET COMMAND_LINE+1
715
716 IF NOEXEC
717 MOV DI,81H
718 ELSE
719 PUSH DS
720 POP ES
721 MOV DI,SI
722 ENDIF
723
724 MOV CL,-1
725COMTRANLP: ;FIND LENGTH OF COMMAND LINE
726 INC CL
727 LODSB
728 STOSB ;COPY COMMAND LINE IN
729 OR AL,AL
730 JNZ COMTRANLP
731 DEC DI
732 MOV AL,CR ; CR terminate
733 STOSB
734
735 IF NOEXEC
736 MOV ES:[80H],CL ; Set up header
737 MOV AL,[DEFAULT_DRIVE]
738 MOV ES:[5CH],AL
739 ELSE
740 MOV [COMMAND_LINE],CL ;Count
741 ENDIF
742
743 MOV DX,OFFSET COMMND ;NOW POINTING TO FILE DESCRIPTION
744
745 IF NOEXEC
746 MOV ES,BP ;SET LOAD ADDRESS
747 MOV BX,100H
748 CALL LDFIL ;READ IN COMMAND
749 JC COMERR
750 MOV DS,BP
751 MOV DX,80H
752 MOV AH,SET_DMA ;SET DISK TRANFER ADDRESS
753 INT 21H
754 CLI
755 MOV SS,BP
756 MOV SP,DX
757 STI
758 XOR AX,AX ;PUSH A WORD OF ZEROS
759 PUSH AX
760 PUSH BP ;SET HIGH PART OF JUMP ADDRESS
761 MOV AX,100H
762 PUSH AX ;SET LOW PART OF JUMP ADDRESS
763CCC PROC FAR
764 RET ;CRANK UP COMMAND!
765CCC ENDP
766
767 ELSE
768; We are going to open the command interpreter and size it as is done in
769; LDFIL. The reason we must do this is that SYSINIT is in free memory. If
770; there is not enough room for the command interpreter, EXEC will probably
771; overlay our stack and code so when it returns with an error SYSINIT won't be
772; here to catch it. This code is not perfect (for instance .EXE command
773; interpreters are possible) because it does its sizing based on the
774; assumption that the file being loaded is a .COM file. It is close enough to
775; correctness to be usable.
776
777 PUSH DX ; Save pointer to name
778
779; First, find out where the command interpreter is going to go.
780 MOV BX,0FFFFH
781 MOV AH,ALLOC
782 INT 21H ;Get biggest piece
783 MOV AH,ALLOC
784 INT 21H ;SECOND TIME GETS IT
785 JC MEMERRJX ; Oooops
786 MOV ES,AX
787 MOV AH,DEALLOC
788 INT 21H ; Give it right back
789 MOV BP,BX
790; ES:0 points to Block, and BP is the size of the block
791; in para.
792
793; We will now adjust the size in BP DOWN by the size of SYSINIT. We
794; need to do this because EXEC might get upset if some of the EXEC
795; data in SYSINIT is overlayed during the EXEC.
796 MOV BX,[MEMORY_SIZE]
797 MOV AX,CS
798 SUB BX,AX ; BX is size of SYSINIT in Para
799 ADD BX,11H ; Add the SYSINIT PHP
800 SUB BP,BX ; BAIS down
801 JC MEMERRJX ; No Way.
802
803 MOV AX,(OPEN SHL 8) ;OPEN THE FILE being EXECED
804 STC ;IN CASE OF INT 24
805 INT 21H
806 JC COMERR ; Ooops
807 MOV BX,AX ;Handle in BX
808 XOR CX,CX
809 XOR DX,DX
810 MOV AX,(LSEEK SHL 8) OR 2
811 STC ;IN CASE OF INT 24
812 INT 21H ; Get file size in DX:AX
813 JC COMERR
814 ; Convert size in DX:AX to para in AX
815 ADD AX,15 ; Round up size for conversion to para
816 ADC DX,0
817 MOV CL,4
818 SHR AX,CL
819 MOV CL,12
820 SHL DX,CL ; Low nibble of DX to high nibble
821 OR AX,DX ; AX is now # of para for file
822 ADD AX,10H ; 100H byte PHP
823 CMP AX,BP ; Will it fit?
824 JB OKLD ; Jump if yes.
825MEMERRJX:
826 JMP MEM_ERR
827
828OKLD:
829 MOV AH,CLOSE
830 INT 21H ; Close file
831 POP DX ; Recover pointer to name
832 PUSH CS
833 POP ES
834 ASSUME ES:SYSINITSEG
835 MOV BX,OFFSET COMEXE ; Point to EXEC block
836 MOV WORD PTR [BX.EXEC0_COM_LINE+2],CS ; Set segments
837 MOV WORD PTR [BX.EXEC0_5C_FCB+2],CS
838 MOV WORD PTR [BX.EXEC0_6C_FCB+2],CS
839 XOR AX,AX ;Load and go
840 MOV AH,EXEC
841 STC ;IN CASE OF INT 24
842 INT 21H ;GO START UP COMMAND
843 ENDIF
844; NOTE FALL THROUGH IF EXEC RETURNS (an error)
845
846COMERR:
847 MOV DX,OFFSET BADCOM ;WANT TO PRINT COMMAND ERROR
848 INVOKE BADFIL
849STALL: JMP STALL
850
851 PUBLIC TEMPCDS
852TEMPCDS:
853ASSUME DS:SYSINITSEG
854 LES DI,[DOSINFO]
855
856 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
857 XOR CH,CH
858 MOV ES:[DI.SYSI_NCDS],CL
859 MOV AL,CL
860 MOV AH,SIZE curdir_list
861 MUL AH
862 call ParaRound
863 MOV SI,[CONFBOT]
864 SUB SI,AX
865 MOV [ALLOCLIM],SI ; Can't alloc past here!
866 MOV WORD PTR ES:[DI.SYSI_CDS + 2],SI
867 MOV AX,SI
868 MOV WORD PTR ES:[DI.SYSI_CDS],0
869 LDS SI,ES:[DI.SYSI_DPB]
870ASSUME DS:NOTHING
871 MOV ES,AX
872 XOR DI,DI
873
874FOOSET: ; Init CDSs
875 MOV AX,WORD PTR [FOOSTRNG]
876 STOSW
877 MOV AX,WORD PTR [FOOSTRNG + 2]
878 STOSW
879 INC BYTE PTR [FOOSTRNG]
880 XOR AX,AX
881 PUSH CX
882 MOV CX,curdir_flags - 4
883 REP STOSB
884 CMP SI,-1
885; JNZ NORMCDS
886;J.K. 6/24/87 Should handle the system that does not have any floppies.
887;J.K. In this case, we are going to pretended there are two dummy floppies
888;J.K. in the system. Still they have DPB and CDS, but we are going to
889;J.K. 0 out Curdir_Flags, Curdir_devptr of CDS so IBMDOS can issue
890;J.K. "Invalid drive specification" message when the user try to
891;J.K. access them.
892 je Fooset_Zero ;AN001;Don't have any physical drive.
893;SB34SYSINIT1003*************************************************************
894;SB Check to see if we are faking floppy drives. If not go to NORMCDS.
895;SB If we are faking floppy drives then see if this CDS being initialised
896;SB is for drive a: or b: by checking the appropriate field in the DPB
897;SB pointed to by ds:si. If not for a: or b: then go to NORMCDS. If
898;Sb for a: or b: then execute the code given below starting at Fooset_Zero.
899;SB For dpb offsets look at inc\dpb.inc.
900;SB 5 LOCS
901
902 cmp cs:Fake_Floppy_Drv,1 ;fake drive ?
903 jnz NORMCDS
904 cmp ds:[si].dpb_drive,02 ;check for a: or b:
905 jae NORMCDS
906
907;SB34SYSINIT1003*************************************************************
908Fooset_Zero: ;AN001;
909 XOR AX,AX
910 MOV CL,3
911 REP STOSW
912 POP CX
913 JMP SHORT FINCDS
914NORMCDS:
915 POP CX
916;J.K. If a non-fat based media is detected (by DPB.NumberOfFat == 0), then
917; set curdir_flags to 0. This is for signaling IBMDOS and IFSfunc that
918; this media is a non-fat based one.
919 cmp [SI.dpb_FAT_count], 0 ;AN000; Non fat system?
920 je SetNormCDS ;AN000; Yes. Set curdir_Flags to 0. AX = 0 now.
921 MOV AX,CURDIR_INUSE ;AN000; else, FAT system. set the flag to CURDIR_INUSE.
922SetNormCDS: ;AN000;
923 STOSW ; curdir_flags
924 MOV AX,SI
925 STOSW ; curdir_devptr
926 MOV AX,DS
927 STOSW
928 LDS SI,[SI.dpb_next_dpb]
929FINCDS:
930 MOV AX,-1
931 STOSW ; curdir_ID
932 STOSW ; curdir_ID
933 STOSW ; curdir_user_word
934 mov ax,2
935 stosw ; curdir_end
936 mov ax, 0 ;AN000;Clear out 7 bytes (curdir_type,
937 stosw ;AN000; curdir_ifs_hdr, curdir_fsda)
938 stosw ;AN000;
939 stosw ;AN000;
940 stosb ;AN000;
941 LOOP FOOSET
942 MOV BYTE PTR [FOOSTRNG],"A"
943 return
944
945;------------------------------------------------------------------------------
946; Allocate FILEs
947;------------------------------------------------------------------------------
948ENDFILE:
949; WE ARE NOW SETTING UP FINAL CDSs, BUFFERS, FILES, FCSs STRINGs etc. We no
950; longer need the space taken by The TEMP stuff below CONFBOT, so set ALLOCLIM
951; to CONFBOT.
952
953;J.K. 2/23/87 If this procedure has been called to take care of INSTALL= command,
954;then we have to save ES,SI registers.
955
956; test [Install_Flag],IS_INSTALL ;AN000; Called to handle INSTALL=?
957; jz ENDFILE_Cont ;AN000;
958; push es ;AN000; Save es,si for CONFIG.SYS
959; push si ;AN000;
960; test [Install_Flag],HAS_INSTALLED ;AN000; Sysinit_base already installed?
961; jz ENDFILE_Cont ;AN000; No. Install it.
962; jmp DO_Install_EXEC ;AN000; Just handle "INSTALL=" cmd only.
963;ENDFILE_Cont: ;AN000;
964
965 push ds ;AN002;
966 mov ax, Code ;AN002;
967 mov ds, ax ;AN002;
968 assume ds:Code
969 cmp MulTrk_flag, MULTRK_OFF1 ;AN002;=0, MULTRACK= command entered?
970 jne MulTrk_Flag_Done ;AN002;
971 or MulTrk_flag, MULTRK_ON ;AN002; Default will be ON.
972MulTrk_Flag_Done: ;AN002;
973 pop ds ;AN002;
974 assume ds:nothing
975
976 MOV AX,[CONFBOT]
977 MOV [ALLOCLIM],AX
978
979 PUSH CS
980 POP DS
981 INVOKE ROUND
982 MOV AL,[FILES]
983 SUB AL,5
984 JBE DOFCBS
985 push ax ;AN005;
986 mov al, DEVMARK_FILES ;AN005;
987 call SetDevMark ;AN005; Set DEVMARK for SFTS (FILES)
988 pop ax ;AN005;
989 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
990 ; IT DOES SIGN EXTEND.
991 MOV BX,[MEMLO]
992 MOV DX,[MEMHI]
993 LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA
994 LDS DI,[DI+SYSI_SFT] ;DS:BP POINTS TO SFT
995 MOV WORD PTR [DI+SFLINK],BX
996 MOV WORD PTR [DI+SFLINK+2],DX ;SET POINTER TO NEW SFT
997 PUSH CS
998 POP DS
999 LES DI,DWORD PTR [MEMLO] ;POINT TO NEW SFT
1000 MOV WORD PTR ES:[DI+SFLINK],-1
1001 MOV ES:[DI+SFCOUNT],AX
1002 MOV BL,SIZE SF_ENTRY
1003 MUL BL ;AX = NUMBER OF BYTES TO CLEAR
1004 MOV CX,AX
1005 ADD [MEMLO],AX ;ALLOCATE MEMORY
1006 MOV AX,6
1007 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO
1008 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1009 INVOKE ROUND ; Check for mem error before the STOSB
1010 ADD DI,AX
1011 XOR AX,AX
1012 REP STOSB ;CLEAN OUT THE STUFF
1013
1014;------------------------------------------------------------------------------
1015; Allocate FCBs
1016;------------------------------------------------------------------------------
1017DOFCBS:
1018 PUSH CS
1019 POP DS
1020 INVOKE ROUND
1021 mov al, DEVMARK_FCBS ;AN005;='X'
1022 call SetDevMark ;AN005;
1023 MOV AL,[FCBS]
1024 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1025 ; IT DOES SIGN EXTEND.
1026 MOV BX,[MEMLO]
1027 MOV DX,[MEMHI]
1028 LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA
1029 ASSUME DS:NOTHING
1030 MOV WORD PTR [DI+SYSI_FCB],BX
1031 MOV WORD PTR [DI+SYSI_FCB+2],DX ;SET POINTER TO NEW Table
1032 MOV BL,CS:Keep
1033 XOR BH,BH
1034 MOV [DI+SYSI_keep],BX
1035 PUSH CS
1036 POP DS
1037 ASSUME DS:SYSINITSEG
1038 LES DI,DWORD PTR [MEMLO] ;POINT TO NEW Table
1039 MOV WORD PTR ES:[DI+SFLINK],-1
1040 MOV ES:[DI+SFCOUNT],AX
1041 MOV BL,SIZE SF_ENTRY
1042 MOV CX,AX
1043 MUL BL ;AX = NUMBER OF BYTES TO CLEAR
1044 ADD [MEMLO],AX ;ALLOCATE MEMORY
1045 MOV AX,size sf-2
1046 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO
1047 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1048 INVOKE ROUND ; Check for mem error before the STOSB
1049 ADD DI,AX ;Skip over header
1050 MOV AL,"A"
1051FillLoop:
1052 PUSH CX ; save count
1053 MOV CX,SIZE sf_entry ; number of bytes to fill
1054 cld
1055 REP STOSB ; filled
1056 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_ref_count],0
1057 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position],0
1058 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position+2],0
1059 POP CX
1060 LOOP FillLoop
1061
1062;------------------------------------------------------------------------------
1063; Allocate Buffers
1064;------------------------------------------------------------------------------
1065
1066; Search through the list of media supported and allocate 3 buffers if the
1067; capacity of the drive is > 360KB
1068
1069 CMP [BUFFERS], -1 ; Has buffers been already set?
1070 je DoDefaultBuff
1071 cmp Buffer_Slash_X, 1 ;AN000;
1072 jne DO_Buffer ;AN000;
1073 call DoEMS ;AN000; Carry set if (enough) EMS is not available
1074 jc DoDefaultBuff ;AN000; Error. Just use default buffer.
1075DO_Buffer:
1076 jmp DOBUFF ; the user entered the buffers=.
1077
1078DoDefaultBuff:
1079 mov [H_Buffers], 0 ;AN000; Default is no heuristic buffers.
1080 MOV [BUFFERS], 2 ; Default to 2 buffers
1081 PUSH AX
1082 PUSH DS
1083 LES BP,CS:[DOSINFO] ; Search through the DPB's
1084 LES BP,DWORD PTR ES:[BP.SYSI_DPB] ; Get first DPB
1085
1086ASSUME DS:SYSINITSEG
1087 PUSH CS
1088 POP DS
1089
1090NEXTDPB:
1091 ; Test if the drive supports removeable media
1092 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1093 INC BL
1094 MOV AX, (IOCTL SHL 8) OR 8
1095 INT 21H
1096
1097; Ignore fixed disks
1098 OR AX, AX ; AX is nonzero if disk is nonremoveable
1099 JNZ NOSETBUF
1100
1101; Get parameters of drive
1102 XOR BX, BX
1103 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1104 INC BL
1105 MOV DX, OFFSET DeviceParameters
1106 MOV AX, (IOCTL SHL 8) OR GENERIC_IOCTL
1107 MOV CX, (RAWIO SHL 8) OR GET_DEVICE_PARAMETERS
1108 INT 21H
1109 JC NOSETBUF ; Get next DPB if driver doesn't support
1110 ; Generic IOCTL
1111
1112; Determine capacity of drive
1113; Media Capacity = #Sectors * Bytes/Sector
1114 MOV BX, WORD PTR DeviceParameters.DP_BPB.BPB_TotalSectors
1115
1116; To keep the magnitude of the media capacity within a word,
1117; scale the sector size
1118; (ie. 1 -> 512 bytes, 2 -> 1024 bytes, ...)
1119 MOV AX, WORD PTR DeviceParameters.DP_BPB.BPB_BytesPerSector
1120 XOR DX, DX
1121 MOV CX, 512
1122 DIV CX ; Scale sector size in factor of
1123 ; 512 bytes
1124
1125 MUL BX ; AX = #sectors * size factor
1126 OR DX, DX ; Just in case of LARGE floppies
1127 JNZ SETBUF
1128 CMP AX, 720 ; 720 Sectors * size factor of 1
1129 JBE NOSETBUF
1130SETBUF:
1131 MOV [BUFFERS], 3
1132 jmp Chk_Memsize_for_Buffers ; Now check the memory size for default buffer count
1133; JMP BUFSET ; Jump out of search loop
1134NOSETBUF:
1135 CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1
1136 jz Chk_Memsize_for_Buffers
1137; JZ BUFSET
1138 LES BP,ES:[BP.DPB_NEXT_DPB]
1139 JMP NEXTDPB
1140
1141;J.K. 10/15/86 DCR00014.
1142;From DOS 3.3, the default number of buffers will be changed according to the
1143;memory size too.
1144; Default buffers = 2
1145; If diskette Media > 360 kb, then default buffers = 3
1146; If memory size > 128 kb (2000H para), then default buffers = 5
1147; If memory size > 256 kb (4000H para), then default buffers = 10
1148; If memory size > 512 kb (8000H para), then default buffers = 15.
1149
1150Chk_Memsize_for_Buffers:
1151 cmp [memory_size], 2000h
1152 jbe BufSet
1153 mov [buffers], 5
1154 cmp [memory_size], 4000h
1155 jbe BufSet
1156 mov [buffers], 10
1157 cmp [memory_size], 8000h
1158 jbe BufSet
1159 mov [buffers], 15
1160
1161BUFSET:
1162ASSUME DS:NOTHING
1163 POP DS
1164 POP AX
1165
1166;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1167;J.K. Here we should put extended stuff and new allocation scheme!!!
1168;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1169;*******************************************************************************
1170; *
1171; Function: Actually allocate BUFFERS into the (extended) memory and initialize*
1172; it. *
1173; If it is installed in real memory, the number of buffers in each *
1174; bucket will be balanced out as far as possible for perfermance. *
1175; Also, if the user specified the secondary buffer cache, it will *
1176; be installed in the real memory. *
1177; *
1178; Input : *
1179; BuffINFO.EMS_MODE - 0=IBM mode, -1 = do not use extended memory. *
1180; BuffINFO.Frame_Page - Page frame 0 segment address *
1181; MEMHI:MEMLO - Start of the next available memory *
1182; Buffer_Pages = Number of extended memory pages for buffer *
1183; BUFFERS = Number of buffers *
1184; H_Buffers = Number of secondary buffers *
1185; *
1186; Output: *
1187; BuffINFO.Cache_Count - # of caches to be installed. *
1188; Hash table set. *
1189; BuffINFO set. *
1190; BufferBuckets set. *
1191; MaxNumBuf1, MaxNumBuf2, and NthBuck set. *
1192; *
1193; Subroutines to be called: *
1194; *
1195; Logic: *
1196; { *
1197; IF (BuffINFO.EMS_MODE == -1) THEN *
1198; { *
1199; IF BUFFERS < 30 THEN *
1200; {# of Bucket = 1; MaxNumBuf1 = BUFFERS; NthBuck = 1} *
1201; ELSE { *
1202; # of Bucket = BUFFERS/15; *
1203; r = BUFFERS mod 15; *
1204; IF r == 0 THEN NthBuck = # of Bucket *
1205; ELSE *
1206; { *
1207; AddBuff = r / # of Bucket; *
1208; NthBuck = r mod # of Bucket; *
1209; MaxNumBuf1 = 15 + AddBuff; /* 1st Bucket - Nth Bucket*
1210; MaxNumBuf2 = 15 + AddBuff +1;/*(N+1)th Bucket to last*
1211; } *
1212; } *
1213; } *
1214; ELSE *
1215; { *
1216; # of Bucket = Buffer_Pages * 2; /* 2 buckets per page *
1217; }; *
1218; *
1219; /*Now allocate memory for Hash table */ *
1220; Hash Table Size = (size Buffer_Hash_Entry) * # of Bucket; *
1221; Set BuffINFO.Hash_ptr to MEMHI:MEMLO; *
1222; Adjust MEMHI:MEMLO according to Hash table size; *
1223; *
1224; /*Set buffers*/ *
1225; IF (EMS_MODE <> -1) THEN *
1226; Set_EMS_Buffer *
1227; ELSE /*Do not use the extended memory */ *
1228; Set_Buffer; *
1229;/*Now set the caches if specified.*/ *
1230; IF (BuffINFO.Cache_count > 0) THEN *
1231; {Set BuffINFO.Cache_ptr to MEMHI:MEMLO; *
1232; MEMHI:MEMLO = MEMHI:MEMLO + 512 * BuffINFO.Cache_count; *
1233; }; *
1234; }; *
1235; *
1236;*******************************************************************************
1237DOBUFF: ;AN000;
1238 lds bx, cs:[DosInfo] ;AN000; ds:bx -> SYSINITVAR
1239
1240 mov ax, [Buffers] ;AN000;Set SYSI_BUFFERS
1241 mov word ptr ds:[bx.SYSI_BUFFERS], ax ;AN000;
1242 mov ax, [H_Buffers] ;AN000;
1243 mov word ptr ds:[bx.SYSI_BUFFERS+2], ax ;AN000;
1244
1245 lds bx, ds:[bx.SYSI_BUF] ;AN000; now, ds:bx -> BuffInfo
1246 cmp ds:[bx.EMS_MODE], -1 ;AN000;
1247; $IF E, LONG ;AN000;
1248 JE $$XL1
1249 JMP $$IF1
1250$$XL1:
1251 xor dx, dx ;AN000;
1252 mov ax, [Buffers] ;AN000; < 99
1253 cmp al, 30 ;AN026; if less than 30,
1254; $IF B ;AN026;
1255 JNB $$IF2
1256 mov [BufferBuckets], 1 ;AN026; then put every buffer
1257 mov ds:[bx.HASH_COUNT], 1 ;AN026; into one bucket
1258 mov [MaxNumBuf1], al ;AN026;
1259 mov [NthBuck], 1 ;AN026;
1260; $ELSE ;AN026; else...
1261 JMP SHORT $$EN2
1262$$IF2:
1263 mov cl, 15 ;AN026; Magic number 15.
1264 div cl ;AN026; al=# of buckets, ah=remainders
1265 push ax ;AN026; save the result
1266 xor ah, ah ;AN026;
1267 mov [BufferBuckets], ax ;AN026;
1268 mov ds:[bx.HASH_COUNT], ax ;AN026;
1269 pop ax ;AN026;
1270 or ah, ah ;AN026;
1271; $IF Z ;AN026;if no remainders
1272 JNZ $$IF4
1273 mov [NthBuck], al ;AN026;then set NthBuck=# of bucket for Set_Buffer proc.
1274; $ELSE ;AN026;else
1275 JMP SHORT $$EN4
1276$$IF4:
1277 mov cl, al ;AN026;
1278 mov al, ah ;AN026;remainder/# of buckets
1279 xor ah, ah ;AN026; =
1280 div cl ;AN026;al=additional num of buffers
1281 or ah, ah ;AN026;ah=Nth bucket
1282; $IF Z ;AN026;
1283 JNZ $$IF6
1284 add [MaxNumBuf1], al ;AN026;
1285 mov ax, [BufferBuckets] ;AN026;
1286 mov [NthBuck], al ;AN026;
1287; $ELSE ;AN026;
1288 JMP SHORT $$EN6
1289$$IF6:
1290 mov [NthBuck], ah ;AN026;
1291 add [MaxNumBuf1], al ;AN026;MaxNumNuf are initially set to 15.
1292 add [MaxNumBuf2], al ;AN026;
1293 inc [MaxNumBuf1] ;AN026;Additional 1 more buffer for group 1 buckets.
1294; $ENDIF ;AN026;
1295$$EN6:
1296; $ENDIF ;AN026;
1297$$EN4:
1298; $ENDIF ;AN026;
1299$$EN2:
1300; $ELSE ;AN000; Use the extended memory.
1301 JMP SHORT $$EN1
1302$$IF1:
1303 mov ax, [Buffer_Pages] ;AN000;
1304 mov cx, MAXBUCKETINPAGE ;AN000;
1305 mul cx ;AN000; gauranteed to be word boundary.
1306 mov [BufferBuckets], ax ;AN000;
1307 mov ds:[bx.HASH_COUNT], ax ;AN000;
1308; $ENDIF ;AN000;
1309$$EN1:
1310 invoke Round ;AN000; get [MEMHI]:[MEMLO]
1311 mov al, DEVMARK_BUF ;AN005; ='B'
1312 call SetDevMark ;AN005;
1313;Now, allocate Hash table at [memhi]:[memlo]. AX = Hash_Count.
1314 mov ax, [BufferBuckets] ;AN026; # of buckets==Hash_Count
1315 mov cx, size BUFFER_HASH_ENTRY ;AN000;
1316 mul cx ;AN000; now AX = Size of hash table.
1317 les di, ds:[bx.HASH_PTR] ;AN000; save Single buffer address.
1318 mov cx, [MemLo] ;AN000;
1319 mov word ptr ds:[bx.HASH_PTR], cx ;AN000; set BuffINFO.HASH_PTR
1320 mov cx, [MemHi] ;AN000;
1321 mov word ptr ds:[bx.HASH_PTR+2], cx ;AN000;
1322 mov [Memlo], ax ;AN000;
1323 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1324 call Round ;AN000; get new [memhi]:[memlo]
1325;Allocate buffers
1326 push ds ;AN000; Save Buffer info. ptr.
1327 push bx ;AN000;
1328 cmp ds:[bx.EMS_MODE], -1 ;AN000;
1329; $IF NE ;AN000;
1330 JE $$IF13
1331 call Set_EMS_Buffer ;AN000;
1332; $ELSE ;AN000;
1333 JMP SHORT $$EN13
1334$$IF13:
1335 call Set_Buffer ;AN000;
1336; $ENDIF ;AN000;
1337$$EN13:
1338 pop bx ;AN000;
1339 pop ds ;AN000;
1340;Now set the secondary buffer if specified.
1341 cmp [H_Buffers], 0 ;AN000;
1342; $IF NE ;AN000;
1343 JE $$IF16
1344 call Round ;AN000;
1345 mov cx, [MemLo] ;AN000;
1346 mov word ptr ds:[bx.CACHE_PTR], cx ;AN000;
1347 mov cx, [MemHi] ;AN000;
1348 mov word ptr ds:[bx.CACHE_PTR+2], cx ;AN000;
1349 mov cx, [H_Buffers] ;AN000;
1350 mov ds:[bx.CACHE_COUNT], cx ;AN000;
1351 mov ax, 512 ;AN000; 512 byte
1352 mul cx ;AN000;
1353 mov [Memlo], ax ;AN000;
1354 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1355 call Round ;AN000;
1356; $ENDIF ;AN000;
1357$$IF16:
1358;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1359;J.K. END OF NEW BUFFER SCHEME.
1360;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1361;DOBUFF:
1362; INVOKE ROUND
1363; DEC [BUFFERS] ; FIRST DEC acounts for buffer already
1364; ; in system.
1365; JZ BUF1 ; All done
1366; PUSH DS
1367; LES DI,BUFPTR
1368; LDS BX,DOSINFO
1369; MOV AX,WORD PTR [BX.SYSI_BUF] ; Link in new buffer
1370; MOV WORD PTR ES:[DI.buf_link],AX
1371; MOV AX,WORD PTR [BX.SYSI_BUF+2]
1372; MOV WORD PTR ES:[DI.buf_link+2],AX
1373; MOV WORD PTR [BX.SYSI_BUF],DI
1374; MOV WORD PTR [BX.SYSI_BUF+2],ES
1375; MOV WORD PTR ES:[DI.buf_ID],00FFH ;NEW BUFFER FREE
1376; mov word ptr es:[di.buf_Sector],0 ;AN000;
1377; mov word ptr es:[di.buf_Sector+2],0 ;AN000;
1378; MOV BX,[BX.SYSI_MAXSEC]
1379; POP DS
1380; ADD BX,BUFINSIZ
1381; ADD [MEMLO],BX
1382; JMP DOBUFF
1383
1384;------------------------------------------------------------------------------
1385; Allocate CDSs
1386;------------------------------------------------------------------------------
1387BUF1:
1388 INVOKE ROUND
1389 push ax ;AN005;
1390 mov ax, DEVMARK_CDS ;AN005;='L'
1391 call SetDevMark ;AN005;
1392 pop ax ;AN005;
1393 LES DI,[DOSINFO]
1394 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
1395 CMP CL,[NUM_CDS]
1396 JAE GOTNCDS ; User setting must be at least NUMIO
1397 MOV CL,[NUM_CDS]
1398GOTNCDS:
1399 XOR CH,CH
1400 MOV ES:[DI.SYSI_NCDS],CL
1401 MOV AX,[MEMHI]
1402 MOV WORD PTR ES:[DI.SYSI_CDS + 2],AX
1403 MOV AX,[MEMLO]
1404 MOV WORD PTR ES:[DI.SYSI_CDS],AX
1405 MOV AL,CL
1406 MOV AH,SIZE curdir_list
1407 MUL AH
1408 call ParaRound
1409 ADD [MEMHI],AX
1410 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1411 INVOKE ROUND ; Check for mem error before initializing
1412 LDS SI,ES:[DI.SYSI_DPB]
1413ASSUME DS:NOTHING
1414 LES DI,ES:[DI.SYSI_CDS]
1415 CALL FOOSET
1416
1417;------------------------------------------------------------------------------
1418; Allocate Space for Internal Stack
1419;------------------------------------------------------------------------------
1420
1421 IF STACKSW
1422
1423 PUSH CS
1424 POP DS
1425 ASSUME DS:SYSINITSEG
1426
1427 IF IBM
1428;Don't install the system stack on the PCjr. Ignore STACKS=command too.
1429 CMP [Sys_Model_Byte], 0FDh ; PCjr = 0FDh
1430 JE SkipStack_brdg
1431 ENDIF
1432
1433;J.K. 10/15/86 DCR00013
1434;If the use does not entered STACKS= command, as a default, do not install
1435;sytem stacks for PC1, PC XT, PC Portable cases.
1436;Otherwise, install it to the user specified value or to the default
1437;value of 9, 128 for the rest of the system.
1438
1439 cmp word ptr [stack_addr], -1 ;Has the user entered "stacks=" command?
1440 je DoInstallStack ;Then install as specified by the user
1441 cmp [Sys_Scnd_Model_Byte], 0 ;PC1, XT has the secondary model byte = 0
1442 jne DoInstallStack ;Other model should have default stack of 9, 128
1443 cmp [Sys_Model_Byte], 0FFh ;PC1 ?
1444 je SkipStack_brdg
1445 cmp [Sys_Model_Byte], 0FEh ;PC/XT or PC Portable ?
1446 jne DoInstallStack
1447SkipStack_Brdg:
1448 jmp SkipStack
1449DoInstallStack:
1450 mov ax, [stack_count] ;J.K. Stack_count = 0?
1451 cmp ax, 0 ;then, stack size must be 0 too.
1452 jz SkipStack_brdg ;Don't install stack.
1453;J.K. 10/21/86 Dynamic Relocation of Stack code.
1454 call Round ;[memhi] = Seg. for stack code
1455 ;[memlo] = 0
1456;J.K. Set DEVMARK block into memory for MEM command
1457;J.K. DEVMARK_ID = 'S' for stack
1458 mov al, DEVMARK_STK ;AN005;='S'
1459 call SetDevMark
1460
1461 mov ax, [memhi]
1462 mov es, ax ;ES -> Seg. the stack code is going to move.
1463 assume es:nothing
1464 push cs
1465 pop ds
1466 xor si,si ;!!We know that Stack code is at the beginning of SYSINIT.
1467 xor di,di
1468 mov cx, offset Endstackcode
1469 mov [memlo],cx
1470 call Round ;Have enough space for relocation?
1471 rep movsb
1472
1473 mov ax, [memlo]
1474 mov word ptr [stack_addr],ax ;set for stack area initialization
1475 mov ax, [memhi] ;This will be used by Stack_Init routine.
1476 mov word ptr [stack_addr+2],ax
1477
1478; Space for Internal Stack area = STACK_COUNT(ENTRYSIZE + STACK_SIZE)
1479 MOV AX, EntrySize
1480 ADD AX, [STACK_SIZE]
1481 MOV CX, [STACK_COUNT]
1482 MUL CX
1483 call ParaRound ; Convert size to pargraphs
1484 ADD [MEMHI], AX
1485 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;To set the DEVMARK_SIZE for Stack by ROUND routine.
1486 INVOKE ROUND ; Check for memory error before
1487 ; continuing
1488 CALL StackInit ; Initialize hardware stack. CS=DS=sysinitseg, ES=Relocated stack code & data
1489
1490SkipStack:
1491 ENDIF
1492
1493 PUSH CS
1494 POP DS
1495 ASSUME DS:SYSINITSEG
1496
1497 MOV AL,[FILES]
1498 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1499 ; IT DOES SIGN EXTEND.
1500 MOV CX,AX
1501 XOR BX,BX ;Close standard input
1502 MOV AH,CLOSE
1503 INT 21H
1504 MOV BX,2
1505RCCLLOOP: ;Close everybody but standard output
1506 MOV AH,CLOSE ; Need output so we can print message
1507 INT 21H ; in case we can't get new one open.
1508 INC BX
1509 LOOP RCCLLOOP
1510
1511 MOV DX,OFFSET CONDEV
1512 MOV AL,2
1513 MOV AH,OPEN ;OPEN CON FOR READ/WRITE
1514 STC ; Set for possible INT 24
1515 INT 21H
1516 JNC GOAUX
1517 INVOKE BADFIL
1518 JMP SHORT GOAUX2
1519
1520GOAUX: PUSH AX
1521 MOV BX,1 ;close standard output
1522 MOV AH,CLOSE
1523 INT 21H
1524 POP AX
1525
1526 MOV BX,AX ;New device handle
1527 MOV AH,XDUP
1528 INT 21H ;Dup to 1, STDOUT
1529 MOV AH,XDUP
1530 INT 21H ;Dup to 2, STDERR
1531
1532GOAUX2: MOV DX,OFFSET AUXDEV
1533 MOV AL,2 ;READ/WRITE ACCESS
1534 INVOKE OPEN_DEV
1535
1536 MOV DX,OFFSET PRNDEV
1537 MOV AL,1 ;WRITE ONLY
1538 INVOKE OPEN_DEV
1539
1540;J.K.9/29/86 *******************
1541;Global Rearm command for Shared Interrupt devices attached in the system;
1542;Shared interrupt attachment has some problem when it issues interrupt
1543;during a warm reboot. Once the interrupt is presented by the attachment,
1544;no further interrupts on that level will be presented until a global rearm
1545;is issued. By the request of the system architecture group, IBMBIO will
1546;issue a global rearm after every device driver is loaded.
1547;To issue a global rearm: ;For PC1, XT, Palace
1548; OUT 02F2h, XX ; Interrupt level 2
1549; OUT 02F3h, XX ; Interrupt level 3
1550; OUT 02F4h, XX ; Interrupt level 4
1551; OUT 02F5h, XX ; Interrupt level 5
1552; OUT 02F6h, XX ; Interrupt level 6
1553; OUT 02F7h, XX ; Interrupt level 7
1554;
1555; ;For PC AT, in addition to the above commands,
1556; ;need to handle the secondary interrupt handler
1557; OUT 06F2h, XX ; Interrupt level 10
1558; OUT 06F3h, XX ; Interrupt level 11
1559; OUT 06F4h, XX ; Interrupt level 12
1560; OUT 06F6h, XX ; Interrupt level 14
1561; OUT 06F7h, XX ; Interrupt level 15
1562;
1563; ;For Round-Up machine
1564; None.
1565; where XX stands for any value.
1566; For your information, after Naples level machine, the system service bios
1567; call (INT 15h), function AH=0C0h returns the system configuration parameters
1568;
1569
1570 cmp [sys_model_byte], 0FDh ;PCjr?
1571; je GoCheckInstall
1572 je Set_Sysinit_Base
1573;SB33045*******************************************************************
1574 push ax ;Save Regs ;SB ;3.30*
1575 push bx ; * ;SB ;3.30*
1576 push dx ; * ;SB ;3.30*
1577 push es ; * ;SB ;3.30*
1578 mov al,0ffh ;Reset h/w by writing to port ;SB ;3.30*
1579 mov dx,2f2h ;Get starting address ;SB ;3.30*
1580 out dx,al ; out 02f2h,0ffh
1581 inc dx
1582 out dx,al ; out 02f3h,0ffh
1583 inc dx
1584 out dx,al ; out 02f4h,0ffh
1585 inc dx
1586 out dx,al ; out 02f5h,0ffh
1587 inc dx
1588 out dx,al ; out 02f6h,0ffh
1589 inc dx
1590 out dx,al ; out 02f7h,0ffh
1591;SB33045*******************************************************************
1592
1593;SB33046*******************************************************************
1594;SB Secondary global rearm ;3.30
1595 mov ax,0f000h ;Get machine type ;SB ;3.30*
1596 mov es,ax ; * ;SB ;3.30*
1597 cmp byte ptr es:[0fffeh],0fch ;Q:Is it a AT type machine ;SB ;3.30*
1598 je startrearm ; *if AT no need to check
1599 mov ah,0c0h ;Get system configuration ;SB ;3.30*
1600 int 15h ; * ;SB ;3.30*
1601 jc finishrearm ; *jmp if old rom ;SB ;3.30*
1602; ;SB ;3.30*
1603; Test feature byte for secondary interrupt controller ;SB ;3.30*
1604; ;SB ;3.30*
1605 test es:[bx.bios_SD_featurebyte1],ScndIntController ; ;SB ;3.30*
1606 je finishrearm ;Jmp if it is there ;SB ;3.30*
1607startrearm:
1608 mov al,0ffh ;Write any pattern to port ;SB ;3.30*
1609 mov dx,6f2h ;Get starting address ;SB ;3.30*
1610 out dx,al ;out 06f2h,0ffh
1611 inc dx ;Bump address ;SB ;3.30*
1612 out dx,al ;out 06f3h,0ffh
1613 inc dx ;Bump address ;SB ;3.30*
1614 out dx,al ;out 06f4h,0ffh
1615 inc dx ;Bump address ;SB ;3.30*
1616 inc dx ;Bump address ;SB ;3.30*
1617 out dx,al ;out 06f6h,0ffh
1618 inc dx ;Bump address ;SB ;3.30*
1619 out dx,al ;out 06f7h,0ffh
1620finishrearm: ; ;SB ;3.30*
1621 pop es ;Restore regs ;SB ;3.30*
1622 pop dx ; * ;SB ;3.30*
1623 pop bx ; * ;SB ;3.30*
1624 pop ax ; * ;SB ;3.30*
1625;SB33046*******************************************************************
1626
1627;J.K. 9/29/86 Global Rearm end *******************
1628
1629;------------------------------------------------------------------------------
1630; Allocate SYSINIT_BASE for INSTALL= command
1631;------------------------------------------------------------------------------
1632;J.K. SYSINIT_BASE allocation.
1633;Check if ENDFILE has been called to handle INSTALL= command.
1634
1635Set_Sysinit_Base:
1636;GoCheckInstall:
1637; test [Install_Flag], HAVE_INSTALL_CMD ;AN019;;AN021;install sysinit base all the time.
1638; jz Skip_SYSINIT_BASE ;AN019;
1639
1640;J.K.--------------------------------------------------------------------------
1641;SYSINIT_BASE will be established in the secure area of
1642;lower memory when it handles the first INSTALL= command.
1643;SYSINIT_BASE is the place where the actual EXEC function will be called and
1644;will check SYSINIT module in high memory if it is damaged by the application
1645;program. If SYSINIT module has been broken, then "Memory error..." message
1646;is displayed by SYSINIT_BASE.
1647;------------------------------------------------------------------------------
1648 push ax ;AN013; Set DEVMARK for MEM command
1649 mov ax, [memhi] ;AN013;
1650 sub ax, [area] ;AN013;
1651 mov [Impossible_owner_size], ax ;AN013;Remember the size in case.
1652 mov al, DEVMARK_INST ;AN013;
1653 call SetDevMark ;AN013;
1654 pop ax ;AN013;
1655
1656 mov di, [memhi] ;AN000;
1657 mov es, di ;AN000;
1658 assume es:nothing ;AN000;
1659 mov word ptr [sysinit_base_ptr+2],di ;AN000; save this entry for the next use.
1660 xor di, di ;AN000;
1661 mov word ptr [sysinit_base_ptr], di ;AN000; es:di -> destination.
1662 mov si, offset SYSINIT_BASE ;AN000; ds:si -> source code to be relocated.
1663 mov cx, Size_SYSINIT_BASE ;AN000;
1664 add [memlo],cx ;AN000;
1665 or cs:[SetDevMarkFlag], FOR_DEVMARK ;AN013;
1666 call round ;AN000; check mem error. Also, readjust MEMHI for the next use.
1667 rep movsb ;AN000; reallocate it.
1668
1669 mov word ptr [Sysinit_Ptr], offset SYSINITPTR ;AN000; Returing address from
1670 mov word ptr [Sysinit_Ptr+2], cs ;AN000; SYSINIT_BASE back to SYSINIT.
1671 or [Install_Flag],HAS_INSTALLED ;AN000; Set the flag.
1672
1673;------------------------------------------------------------------------------
1674; Free the rest of the memory from MEMHI to CONFBOT. Still from CONFBOT to
1675; the top of the memory will be allocated for SYSINIT and CONFIG.SYS if
1676; HAVE_INSTALL_CMD.
1677;------------------------------------------------------------------------------
1678;Skip_SYSINIT_BASE: ;AN021;
1679
1680 INVOKE ROUND
1681 MOV BX,[MEMHI]
1682 MOV AX,[AREA]
1683 mov [Old_Area], ax ;AN013; Save [AREA]
1684 MOV ES,AX ;CALC WHAT WE NEEDED
1685 SUB BX,AX
1686 MOV AH,SETBLOCK
1687 INT 21H ;GIVE THE REST BACK
1688 PUSH ES
1689 MOV AX,ES
1690 DEC AX
1691 MOV ES,AX ;Point to arena
1692 MOV ES:[arena_owner],8 ;Set impossible owner
1693 POP ES
1694
1695 mov bx,0ffffh ;AN000;
1696 mov ah,Alloc ;AN000;
1697 int 21h ;AN000;
1698 mov ah,Alloc ;AN000;
1699 int 21h ;AN000; Allocate the rest of the memory
1700
1701 mov [memhi],ax ;AN000; Start of the allocated memory
1702 mov [memlo],0 ;AN000; to be used next.
1703
1704 ;;;; At this moment, memory from [MEMHI]:0 to Top-of-the memory is
1705 ;;;; allocated.
1706 ;;;; To protect sysinit, confbot module (From CONFBOT (or =ALLOCLIM at
1707 ;;;; this time) to the Top-of-the memory), here we are going to
1708 ;;;; 1). "SETBLOCK" from MEMHI to CONFBOT.
1709 ;;;; 2). "ALLOC" from CONFBOT to the top of the memory.
1710 ;;;; 3). "Free Alloc Memory" from MEMHI to CONFBOT.
1711;Memory allocation for SYSINIT, CONFBOT module.
1712 mov es, ax ;AN000;
1713 mov bx, [confbot] ;AN000;
1714 sub bx, ax ;AN000; CONFBOT - MEMHI
1715 dec bx ;AN000; Make a room for the memory block id.
1716 dec bx ;AN000; make sure!!!.
1717 mov ah, SETBLOCK ;AN000;
1718 int 21h ;AN000; this will free (CONFBOT to top of memory)
1719 mov bx, 0ffffh ;AN000;
1720 mov ah, ALLOC ;AN000;
1721 int 21h ;AN000;
1722 mov ah, ALLOC ;AN000;
1723 int 21h ;AN000; allocate (CONFBOT to top of memory)
1724 mov [area],ax ;AN000; Save Allocated memory segment.
1725 ;AN000; Need this to free this area for COMMAND.COM.
1726 mov es, [memhi] ;AN000;
1727 mov ah, 49h ;AN000; Free Allocated Memory.
1728 int 21h ;AN000; Free (Memhi to CONFBOT(=AREA))
1729
1730; IF NOEXEC
1731; MOV BX,0FFFFH ;ALLOCATE THE REST OF MEM FOR COMMAND
1732; MOV AH,ALLOC
1733; INT 21H
1734; MOV AH,ALLOC
1735; INT 21H
1736; MOV DS,AX
1737; ENDIF
1738
1739; test cs:[Install_Flag],IS_INSTALL ;AN000;
1740; jnz DO_Install_Exec ;AN000;
1741
1742ENDFILE_Ret:
1743 return
1744
1745
1746Do_Install_Exec proc near ;AN000; Now, handles INSTALL= command.
1747
1748 push si ;AN000; save SI for config.sys again.
1749
1750 ;;;; We are going to call LOAD/EXEC function.
1751 ;;;;;Set ES:BX to the parameter block here;;;;;;;
1752 ;;;;;Set DS:DX to the ASCIIZ string. Remember that we already has 0
1753 ;;;;;after the filename. So parameter starts after that. If next
1754 ;;;;;character is a line feed (i.e. 10), then assume that the 0
1755 ;;;;;we already encountered used to be a carrage return. In this
1756 ;;;;;case, let's set the length to 0 which will be followed by
1757 ;;;;;carridge return.
1758;J.K. ES:SI -> command line in CONFIG.SYS. Points to the first non blank
1759;character after =.
1760 push es ;AN000;
1761 push ds ;AN000;
1762 pop es ;AN000;
1763 pop ds ;AN000; es->sysinitseg, ds->confbot seg
1764 assume ds:nothing ;AN000;
1765 mov dx, si ;AN000; ds:dx->file name,0 in CONFIG.SYS image.
1766;AN016; UNDO THE EXTENDED ATTRIBUTES HANDLING
1767; mov ax, OPEN SHL 8 ;AN008;
1768; int 21h ;AN008;
1769; jc SysInitPtr ;AN008;
1770; mov bx, ax ;AN008;handle
1771; call Get_Ext_Attribute ;AN008;Get the extended attribute.
1772; cmp al, EA_INSTALLABLE ;AN008;
1773; je EA_Installable_OK ;AN012;
1774; stc ;AN012;
1775; jmp SysInitPtr ;AN012;
1776;EA_Installable_OK: ;AN012;
1777 xor cx,cx ;AN000;
1778 cld ;AN000;
1779 mov cs:Ldexec_start, ' ' ;AN015; Clear out the parm area
1780 mov di, offset Ldexec_parm ;AN000;
1781InstallFilename: ;AN000; skip the file name
1782 lodsb ;AN000; al = ds:si; si++
1783 cmp al, 0 ;AN000;
1784 je Got_InstallParm ;AN000;
1785 jmp InstallFilename ;AN000;
1786Got_InstallParm: ;AN000; copy the parameters to Ldexec_parm
1787 lodsb ;AN000;
1788 mov es:[di], al ;AN000;
1789 cmp al, LF ;AN000;AN028; line feed?
1790 je Done_InstallParm ;AN000;AN028;
1791 inc cl ;AN000; # of char. in the parm.
1792 inc di ;AN000;
1793 jmp Got_Installparm ;AN000;
1794Done_Installparm: ;AN000;
1795 mov byte ptr cs:[Ldexec_line], cl ;AN000; length of the parm.
1796 cmp cl, 0 ;AN015;If no parm, then
1797 jne Install_Seg_Set ;AN015; let the parm area
1798 mov byte ptr cs:[Ldexec_Start],CR ;AN015; starts with CR.
1799Install_Seg_Set: ;AN015;
1800 mov word ptr cs:0, 0 ;AN000; Make a null environment segment
1801 mov ax, cs ;AN000; by overlap JMP instruction of SYSINITSEG.
1802 mov cs:[INSTEXE.EXEC0_ENVIRON],ax ;AN000; Set the environment seg.
1803 mov word ptr cs:[INSTEXE.EXEC0_COM_LINE+2],ax ;AN000; Set the seg.
1804 mov word ptr cs:[INSTEXE.EXEC0_5C_FCB+2],ax ;AN000;
1805 mov word ptr cs:[INSTEXE.EXEC0_6C_FCB+2],ax ;AN000;
1806 call Sum_up ;AN000;
1807 mov es:CheckSum, ax ;AN000; save the value of the sum
1808 xor ax,ax ;AN000;
1809 mov ah, EXEC ;AN000; Load/Exec
1810 mov bx, offset INSTEXE ;AN000; ES:BX -> parm block.
1811 push es ;AN000; Save es,ds for Load/Exec
1812 push ds ;AN000; these registers will be restored in SYSINIT_BASE.
1813 jmp cs:dword ptr SYSINIT_BASE_PTR ;AN000; jmp to SYSINIT_BASE to execute
1814 ; LOAD/EXEC function and check sum.
1815
1816;J.K. This is the returning address from SYSINIT_BASE.
1817SYSINITPTR: ;AN000; returning far address from SYSINIT_BASE
1818 pop si ;AN000; restore SI for CONFIG.SYS file.
1819 push es ;AN000;
1820 push ds ;AN000;
1821 pop es ;AN000;
1822 pop ds ;AN000; now ds - sysinitseg, es - confbot
1823 jnc Exec_Exit_Code
1824 test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc?
1825 jnz Install_Error_Exit ;AN021; Just exit with carry set.
1826 push si ;AN000; Error in loading the file for INSTALL=.
1827 call BadLoad ;AN000; ES:SI-> path,filename,0.
1828 pop si ;AN000;
1829 jmp Install_Exit_Ret
1830Exec_Exit_Code:
1831 test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc?
1832 jnz Install_Exit_Ret ;AN021; Just exit.
1833 mov ah, 4dh ;AN017;
1834 int 21h ;AN017;
1835 cmp ah, 3 ;AN017;Only accept "Stay Resident" prog.
1836 je Install_Exit_Ret ;AN017;
1837 call Error_Line ;AN017;Inform the user
1838Install_Error_Exit: ;AN021;
1839 stc ;AN021;
1840Install_Exit_Ret:
1841 ret
1842Do_Install_Exec endp
1843
1844Public ParaRound
1845ParaRound:
1846 ADD AX,15
1847 RCR AX,1
1848 SHR AX,1
1849 SHR AX,1
1850 SHR AX,1
1851 return
1852
1853;------------------------------------------------------------------------------
1854;J.K. SYSINIT_BASE module.
1855;In: After relocation,
1856; AX = 4B00h - Load and execute the program DOS function.
1857; DS = CONFBOT. Segment of CONFIG.SYS file image
1858; ES = Sysinitseg. Segment of SYSINIT module itself.
1859; DS:DX = pointer to ASCIIZ string of the path,filename to be executed.
1860; ES:BX = pointer to a parameter block for load.
1861; SYSSIZE (Byte) - offset vaule of End of SYSINIT module label
1862; BIGSIZE (word) - # of word from CONFBOT to SYSSIZE.
1863; CHKSUM (word) - Sum of every byte from CONFBOT to SYSSIZE in a
1864; word boundary moduler form.
1865; SYSINIT_PTR (dword ptr) - Return address to SYSINIT module.
1866;Note: SYSINIT should save necessary registers and when the control is back
1867
1868
1869 public Sysinit_Base
1870Sysinit_Base: ;AN000;
1871 mov word ptr cs:SYSINIT_BASE_SS, SS ;AN000; save stack
1872 mov word ptr cs:SYSINIT_BASE_SP, SP ;AN000;
1873 int 21h ;AN000; LOAD/EXEC DOS call.
1874 mov SS, word ptr cs:SYSINIT_BASE_SS ;AN000; restore stack
1875 mov SP, word ptr cs:SYSINIT_BASE_SP ;AN000;
1876 pop ds ;AN000; restore CONFBOT seg
1877 pop es ;AN000; restore SYSINITSEG
1878 jc SysInit_Base_End ;AN000; LOAD/EXEC function failed.
1879 ;At this time, I don't have to worry about
1880 ;that SYSINIT module has been broken or not.
1881 call Sum_up ;AN000; Otherwise, check if it is good.
1882 cmp es:CheckSum, AX ;AN000;
1883 je SysInit_Base_End ;AN000;
1884;Memory broken. Show "Memory allocation error" message and stall.
1885 mov ah, 09h ;AN000;
1886 push cs ;AN000;
1887 pop ds ;AN000;
1888 mov dx, Mem_alloc_err_msg ;AN000;
1889 int 21h ;AN000;
1890Stall_now: jmp Stall_now ;AN000;
1891
1892SysInit_Base_End: jmp es:Sysinit_Ptr ;AN000; return back to sysinit module
1893
1894Sum_up: ;AN000;
1895;In:
1896; ES - SYSINITSEG.
1897;OUT: AX - Result
1898;Remark: Since this routine will only check starting from "LocStack" to the end of
1899; Sysinit segment, the data area, and the current stack area are not
1900; coverd. In this sense, this check sum routine only gives a minimal
1901; gaurantee to be safe.
1902;First sum up CONFBOT seg.
1903 push ds ;AN021;
1904 mov ax,es:ConfBot ;AN021;
1905 mov ds,ax ;AN021;
1906 xor si,si ;AN000;
1907 xor ax,ax ;AN000;
1908 mov cx,es:Config_Size ;AN000; If CONFIG_SIZE has been broken, then this
1909 ;whole test better fail.
1910 shr cx, 1 ;AN000; make it a word count
1911 jz Sum_Sys_Code ;AN025; When CONFIG.SYS file not exist.
1912Sum1: ;AN000;
1913 add ax, ds:word ptr [si] ;AN000;
1914 inc si ;AN000;
1915 inc si ;AN000;
1916 loop Sum1 ;AN000;
1917;Now, sum up SYSINIT module.
1918Sum_Sys_Code: ;AN025;
1919 mov si, offset LocStack ;AN000; Starting after the stack.
1920 ;AN000; This does not cover the possible STACK code!!!
1921 mov cx, offset SYSSIZE ;AN000; SYSSIZE is the label at the end of SYSINIT
1922 sub cx, si ;AN000; From After_Checksum to SYSSIZE
1923 shr cx, 1 ;AN000;
1924Sum2: ;AN000;
1925 add ax, es:word ptr [si] ;AN000;
1926 inc si ;AN000;
1927 inc si ;AN000;
1928 loop Sum2 ;AN000;
1929 pop ds ;AN021;
1930 ret ;AN000;
1931
1932Sysinit_Base_SS equ $-Sysinit_Base ;AN000;
1933 dw ? ;AN000;
1934Sysinit_Base_SP equ $-Sysinit_Base ;AN000;
1935 dw ? ;AN000;
1936Mem_Alloc_Err_msg equ $-Sysinit_Base ;AN000;
1937;include BASEMES.INC ;AN000; Memory allocation error message
1938include MSBIO.CL4 ;AN011; Memory allocation error message
1939End_Sysinit_Base label byte ;AN000;
1940SIZE_SYSINIT_BASE equ $-Sysinit_Base ;AN000;
1941
1942;
1943;AN016; Undo the extended attribute handling
1944; public Get_Ext_Attribute
1945;Get_Ext_Attribute proc near ;AN008;
1946;;In: BX - file handle
1947;;Out: AL = The extended attribute got from the handle.
1948;; AX destroyed.
1949;; Carry set when DOS function call fails.
1950;
1951; push ds ;AN008;
1952; push si ;AN008;
1953; push es ;AN008;
1954; push di ;AN008;
1955; push cx ;AN008;
1956;
1957; push cs ;AN008;
1958; pop ds ;AN008;
1959; push cs ;AN008;
1960; pop es ;AN008;
1961;
1962; mov Ext_Attr_Value, 0ffh ;AN008; Initialize to unrealistic value
1963; mov ax, 5702h ;AN008;Get extended attribute by handle thru LIST
1964; mov si, offset EA_QueryList ;AN008;
1965; mov di, offset Ext_Attr_List ;AN008;
1966; mov cx, SIZE_EXT_ATTR_LIST ;AN008;
1967; int 21h ;AN008;
1968; mov al, Ext_Attr_Value ;AN008;
1969; pop cx ;AN008;
1970; pop di ;AN008;
1971; pop es ;AN008;
1972; pop si ;AN008;
1973; pop ds ;AN008;
1974; ret ;AN008;
1975;Get_Ext_Attribute endp ;AN008;
1976
1977
1978;------------------------------------------------------------------------------
1979
1980DoEMS proc near
1981;*******************************************************************************
1982; Function: Called prior to DOBUFF subroutine. Only called when /E option *
1983; for the buffers= command has been specified. *
1984; This routine will check if the extended memory is avaiable, *
1985; and determine what is the page number. We only use physical page *
1986; 254. if it is there, then this routine will calculate the number *
1987; of pages needed for buffers and will allocate logical pages in the *
1988; extended memory and get the page handle of them. *
1989; *
1990; Input : *
1991; Buffers - Number of buffers *
1992; Buffer_LineNum - Saved line number to be used in case of Error case *
1993; *
1994; Output: *
1995; BuffINFO.EMS_Handle *
1996; Buffer_Pages = Number of pages for buffer in the extended memory. *
1997; BuffINFO.EMS_MODE = -1 No extended memory or Non-IBM compatible mode. *
1998; Buffers = the number will be changed to be a multiple of 30. *
1999; Carry set if no extended memory exist or if it is not big enough. *
2000; AX, BX, CX, DX destroyed. *
2001; *
2002; Logic: *
2003; { *
2004; Get EMS Version (AH=46h); *
2005; If (EMS not installed or it is not IBM compatible or *
2006; (Available_pages * 30 < Buffers) then *
2007; {Show error message "Error in CONFIG.SYS line #"; *
2008; Set carry; Exit }; *
2009; else *
2010; Buffer_Pages = Roundup(BUFFERS/30); /* Round up 30 buffers per page*/ *
2011; Buffers = Buffer_Pages * 30; /* Set the new number of Buffers*/*
2012; Allocate Buffer_Pages (AH=43h) and set EMS_Handle; *
2013; }; *
2014; *
2015;*******************************************************************************
2016
2017 push es ;AN000;
2018 push di ;AN000; save es, di
2019 push si ;AN010;
2020 push bx ;AN010;
2021 xor di,di ;AN004; if vector pointer of
2022 mov es, di ;AN004; EMS (INT 67h) is 0,0
2023 mov di, word ptr es:[EMS_INT * 4] ;AN004; then error.
2024 mov ax, word ptr es:[EMS_INT * 4 +2] ;AN009;
2025 or ax,di ;AN009;
2026; $IF NZ,AND,LONG ;AN004;
2027 JNZ $$XL2
2028 JMP $$IF18
2029$$XL2:
2030 les di, cs:[DosInfo] ;AN000; es:di -> SYSINITVAR
2031 les di, es:[di.SYSI_BUF] ;AN000; now, es:di -> BuffInfo
2032
2033 mov ah, EMS_STATUS ;AN000; get the status of EMS = 40h
2034 int EMS_INT ;AN000;
2035 or ah, ah ;AN000; EMS installed?
2036; $IF Z,AND,LONG ;AN000;
2037 JZ $$XL3
2038 JMP $$IF18
2039$$XL3:
2040 mov ah, EMS_VERSION ;AN010;=46h
2041 int EMS_INT ;AN010;
2042 cmp AL, EMSVERSION ;AN010;40h = 4.0
2043; $IF AE,AND,LONG ;AN010;
2044 JAE $$XL4
2045 JMP $$IF18
2046$$XL4:
2047 call Check_IBM_PageID ;AN000; IBM (compatible) mode?
2048
2049IF BUFFERFLAG
2050 mov ax, cs:[LAST_PAGE]
2051 mov es:[di.EMS_LAST_PAGE], ax
2052 mov ax, cs:[LAST_PAGE+2]
2053 mov es:[di.EMS_LAST_PAGE+2], ax
2054 mov ax, cs:[FIRST_PAGE]
2055 mov es:[di.EMS_FIRST_PAGE], ax
2056 mov ax, cs:[FIRST_PAGE+2]
2057 mov es:[di.EMS_FIRST_PAGE+2], ax
2058 mov ax, cs:[NPA640]
2059 mov es:[di.EMS_NPA640], ax
2060 mov es:[di.EMS_SAFE_FLAG], 1
2061ENDIF
2062
2063; $IF NC,AND,LONG ;AN000;
2064 JNC $$XL5
2065 JMP $$IF18
2066$$XL5:
2067 mov ah, EMAP_STATE ;AN010; Check if the size of
2068 mov al, GET_MAP_SIZE ;AN010; the MAP state table
2069 mov bx, 1 ;AN010; # of pages
2070 int EMS_INT ;AN010; is acceptable.
2071 or ah, ah ;AN010;
2072; $IF Z,AND ;AN010;
2073 JNZ $$IF18
2074 cmp al, EMS_MAP_BUFF_SIZE ;AN010; Curretly=12 bytes
2075; $IF BE,AND ;AN010;
2076 JNBE $$IF18
2077 mov ah, EQ_PAGES ;AN000; Get number of unallocated & total pages = 42h
2078 int EMS_INT ;AN000; result in BX
2079 xor dx, dx ;AN000;
2080 mov ax, cs:[Buffers] ;AN000;
2081 mov cx, MAXBUFFINBUCKET*MAXBUCKETINPAGE ;AN000;
2082 call Roundup ;AN000; find out how many pages are needed.
2083 cmp bx, ax ;AN000; AX is the number of pages for [buffers]
2084; $IF AE,AND ;AN000;
2085 JNAE $$IF18
2086 mov cs:[Buffer_Pages], ax ;AN000;
2087 mov bx, ax ;AN000; prepare for Get handle call.
2088 mul cx ;AN000;
2089 mov cs:[Buffers], ax ;AN000; set new [Buffers] for the extended memory.
2090 mov ah, E_GET_HANDLE ;AN000; allocate pages = 43h
2091 int EMS_INT ;AN000; page handle in DX.
2092 or ah, ah ;AN000;
2093; $IF Z ;AN000; pages allocated.
2094 JNZ $$IF18
2095 mov ah, EMS_HANDLE_NAME ;AN010;
2096 mov al, SET_HANDLE_NAME ;AN010;
2097 push es ;AN010;
2098 push di ;AN010;
2099 push ds ;AN010;
2100 push cs ;AN010;
2101 pop ds ;AN010;
2102 mov si, offset EMSHandleName ;AN010;
2103 int EMS_INT ;AN010; Set the handle name
2104 pop ds ;AN010;
2105 pop di ;AN010;
2106 pop es ;AN010;
2107 xor ah,ah ;AN010;
2108 mov es:[di.EMS_MODE], ah ;AN000; put 0 in EMS_mode.
2109 mov es:[di.EMS_HANDLE], dx ;AN000; save EMS handle
2110 mov ax, cs:[IBM_Frame_Seg] ;AN010;
2111 mov es:[di.EMS_PAGE_FRAME],ax ;AN010;
2112 mov ax, cs:[Real_IBM_Page_Id] ;AN029;
2113 mov es:[di.EMS_PAGEFRAME_NUMBER], ax;AN029;
2114 mov ax, es ;AN010;
2115 mov word ptr cs:[EMS_Ctrl_tab+2],ax ;AN010;
2116 mov word ptr cs:[EMS_state_buf+2],ax;AN010;
2117 push di ;AN010;save di-> Buffinfo
2118 add di, EMS_SEG_CNT ;AN010;
2119 mov word ptr cs:[EMS_Ctrl_tab], di ;AN010;
2120 pop di ;AN010;
2121 add di, EMS_MAP_BUFF ;AN010;
2122 mov word ptr cs:[EMS_state_Buf],di ;AN010;
2123 clc ;AN000;
2124; $ELSE ;AN000;
2125 JMP SHORT $$EN18
2126$$IF18:
2127 mov ax, cs:[Buffer_LineNum] ;AN000; Show error message.
2128 push cs:[LineCount] ;AN017; Save current line count
2129 mov cs:[LineCount], ax ;AN000; Now, we can change Linecount
2130 call Error_Line ;AN000; since we are through with CONFIG.SYS file.
2131 pop cs:[LineCount] ;AN017; Restore line count
2132 stc ;AN000;
2133; $ENDIF
2134$$EN18:
2135 pop bx ;AN010;
2136 pop si ;AN010;
2137 pop di ;AN000;
2138 pop es ;AN000;
2139 ret ;AN000;
2140DoEMS endp
2141
2142;
2143Set_Buffer proc near
2144;*******************************************************************************
2145;Function: Set buffers in the real memory. *
2146; For each hash table entry, set the pointer to the *
2147; corresponding hash bucket. *
2148; Lastly set the memhi, memlo for the next available free address. *
2149; ** At the request of IBMDOS, each hash bucket will start at the *
2150; ** new segment. *
2151; *
2152;Input: ds:bx -> BuffInfo. *
2153; [Memhi]:[MemLo = 0] = available space for the hash bucket. *
2154; BufferInfo.Hash_Ptr -> Hash table. *
2155; BufferBuckets = # of buckets to install. *
2156; SingleBufferSize = Buffer header size + Sector size *
2157; MaxNumBuff1 = Number of buffers in the first group of buckets *
2158; MaxNumBuff2 = Number of buffers in the second group of buckets *
2159; NthBuck = 1st thru Nth bucket are the first group *
2160; *
2161;Output: Buffers, hash buckets and Hash table entries established. *
2162; [Memhi]:[Memlo] = address of the next available free space. *
2163; *
2164; { For (every bucket) *
2165; { Set Hash table entry; *
2166; Next buffer ptr = buffer size; *
2167; For (every buffer in the bucket) *
2168; { Calll Set_Buffer_Info; /*Set link, id... */ *
2169; IF (last buffer in a bucket) THEN *
2170; {last buffer's next_ptr -> first buffer; *
2171; first buffer's prev_ptr -> last buffer; *
2172; }; *
2173; Next buffer ptr += buffer size; *
2174; }; *
2175; }; *
2176; MEMHI:MEMLO = Current Buffer_Bucket add + (# of odd * buffer size)*
2177; }; *
2178;*******************************************************************************
2179
2180 assume ds:nothing ;AN000;to make sure.
2181 lds bx, ds:[bx.HASH_PTR] ;AN000;now, ds:bx -> hash table
2182 xor dx, dx ;AN026;To be used to count buckets
2183; $DO ;AN000;For each bucket
2184$$DO21:
2185 inc dl ;AN026; Current bucket number
2186 mov word ptr ds:[bx.BUFFER_BUCKET],0 ;AN000;Memlo is 0 after ROUND.
2187 mov di, [MemHi] ;AN000;
2188 mov word ptr ds:[bx.BUFFER_BUCKET+2], di ;AN000;Hash entry set.
2189 mov word ptr ds:[bx.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0.
2190 mov es, di ;AN000;
2191 xor di, di ;AN000;es:di -> hash bucket
2192 xor cx, cx ;AN000
2193 xor ax, ax ;AN000
2194; $DO ;AN000;For each buffer in the bucket
2195$$DO22:
2196 call Set_Buffer_Info ;AN000;Set buf_link, buf_id...
2197 inc cx ;AN000;buffer number
2198 cmp dl, [NthBuck] ;AN026;Current bucket number > NthBuck?
2199; $IF BE ;AN026;
2200 JNBE $$IF23
2201 cmp cl, [MaxNumBuf1] ;AN026; last buffer of the 1st group?
2202; $ELSE ;AN026;
2203 JMP SHORT $$EN23
2204$$IF23:
2205 cmp cl, [MaxNumBuf2] ;AN026; last buffer of the 2nd group?
2206; $ENDIF ;AN026;
2207$$EN23:
2208
2209; $IF E ;AN020;Yes, last buffer
2210 JNE $$IF26
2211 mov word ptr es:[di.BUF_NEXT], 0 ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain)
2212 mov word ptr es:[BUF_PREV], di ;AN020;the first buffer's prev -> the last buffer
2213; $ENDIF ;AN020;
2214$$IF26:
2215 mov di, ax ;AN000;adjust next buffer position
2216; $ENDDO E ;AN000;flag set already for testing last buffer.
2217 JNE $$DO22
2218 add [Memlo], ax ;AN000;AX is the size of this bucket.
2219 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;Update DEVMARK_SIZE
2220 call Round ;AN000;memhi:memlo adjusted for the next bucket.
2221 add bx, size BUFFER_HASH_ENTRY ;AN000;ds:bx -> next hash entry.
2222 dec [BufferBuckets] ;AN000;
2223; $ENDDO Z ;AN000;
2224 JNZ $$DO21
2225 ret ;AN000;
2226Set_Buffer endp
2227
2228;
2229Set_EMS_Buffer proc near
2230;*******************************************************************************
2231;Function: Set buffers in the extended memory. *
2232; For each hash table entry, set the pointer to the corresponding *
2233; hash bucket. *
2234; *
2235;Input: ds:bx -> BuffInfo. *
2236; BuffINFO.Hash_Ptr -> Hash table. *
2237; BuffINFO.EMS_Handle = EMS handle *
2238; Buffers = tatal # of buffers to install. *
2239; Multiple of MAXBUFFINBUCKET*MAXBUCKETINPAGE. *
2240; Buffer_Pages = # of extended memory pages for buffers. *
2241; BufferBuckets = # of buckets to install. *
2242; SingleBufferSize = Buffer header size + Sector size. *
2243; *
2244;Output: Buffers, hash buckets and Hash table entries established. *
2245; *
2246; { For (each page) *
2247; { Map the page; /*Map the page into Page frame *
2248; For (each bucket) /*Each page has two buckets */ *
2249; { *
2250; Set EMS_Page; *
2251; Set Buffer_Bucket; *
2252; Next buffer ptr = buffer size; *
2253; For (every buffer) /*A bucket has 15 buffers */ *
2254; { Set Buf_link to Next buffer ptr; *
2255; Set Buffer_ID to free; *
2256; If (last buffer in this bucket) THEN *
2257; {Buf_link = -1; *
2258; Next buffer ptr = 0; *
2259; }; *
2260; Next buffer ptr += buffer size; *
2261; }; *
2262; }; *
2263; }; *
2264; }; *
2265;*******************************************************************************
2266
2267 assume ds:nothing ;AN000;to make sure.
2268
2269IF BUFFERFLAG
2270
2271 push ax
2272 mov ax, offset ems_save_buf
2273 mov word ptr cs:[ems_state_buf], ax
2274 push cs
2275 pop word ptr cs:[ems_state_buf+2]
2276 pop ax
2277
2278ENDIF
2279
2280 call Save_MAP_State ;AN010;
2281 mov dx, es:[bx.EMS_Handle] ;AN000;save EMS_Handle
2282 lds si, ds:[bx.HASH_PTR] ;AN000;now ds:si -> Hash table
2283 xor bx, bx ;AN000;starting logical page number.
2284; $DO ;AN000;For each page,
2285$$DO30:
2286 call Map_Page ;AN000;map it to IBM physical page 254.
2287 mov di, cs:IBM_Frame_Seg ;AN000;
2288 mov es, di ;AN000
2289 xor di, di ;AN000;es:di -> bucket
2290 xor ax, ax ;AN000
2291 xor cx, cx ;AN000
2292; $DO ;AN000;For each bucket,
2293$$DO31:
2294 mov ds:[si.EMS_PAGE_NUM], bx ;AN000;set the logical page number in Hash table.
2295 mov word ptr ds:[si.BUFFER_BUCKET], di ;AN000;set the offset in hash table for this bucket.
2296 mov word ptr ds:[si.BUFFER_BUCKET+2], es ;AN000;set the segment value in hash table.
2297 mov word ptr ds:[si.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0.
2298 push cx ;AN000;save bucket number
2299 xor cx, cx ;AN000;
2300; $DO ;AN000;For each buffer in a bucket,
2301$$DO32:
2302 call Set_Buffer_Info ;AN000;AX adjusted for the next buffer.
2303 inc cx ;AN000;inc number of buffers in this bucket.
2304 cmp cx, 1 ;AN020;The first buffer in the bucket?
2305; $IF E ;AN020;
2306 JNE $$IF33
2307 mov cs:[EMS_Buf_First], di ;AN020;then save the offset value
2308; $ENDIF ;AN020;
2309$$IF33:
2310 cmp cx, MAXBUFFINBUCKET ;AN000;
2311; $IF E ;AN000
2312 JNE $$IF35
2313 push word ptr cs:[EMS_Buf_First] ;AN020;
2314 pop word ptr es:[di.BUF_NEXT] ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain)
2315 push di ;AN020;save di
2316 push di ;AN020;di-> last buffer
2317 mov di, cs:[EMS_Buf_First] ;AN020;es:di-> first buffer
2318 pop word ptr es:[di.BUF_PREV] ;AN020;the first buffer's prev -> the last buffer
2319 pop di ;AN020;restore di
2320; $ENDIF ;AN000;
2321$$IF35:
2322 mov di, ax ;AN000;advance di to the next buffer position.
2323; $ENDDO E ;AN000;
2324 JNE $$DO32
2325 add si, size BUFFER_HASH_ENTRY ;AN000;ds:si -> next hash table entry
2326 pop cx ;AN000;restore bucket number
2327 inc cx ;AN000;next bucket
2328 cmp cx, MAXBUCKETINPAGE ;AN000;2 buckets per page
2329; $ENDDO E ;AN000;
2330 JNE $$DO31
2331 inc bx ;AN000;increse logical page number
2332 cmp bx, cs:[Buffer_Pages] ;AN000;reached the maximum page number?
2333; $ENDDO E ;AN000;
2334 JNE $$DO30
2335 call Restore_MAP_State ;AN010;
2336 ret ;AN000;
2337Set_EMS_Buffer endp
2338
2339
2340Set_Buffer_Info proc
2341;Function: Set buf_link, buf_id, Buf_Sector
2342;In: ES:DI -> Buffer header to be set.
2343; AX = DI
2344;Out:
2345; Above entries set.
2346
2347
2348 push [Buf_Prev_Off] ;AN020;
2349 pop es:[di.BUF_PREV] ;AN020;
2350 mov Buf_Prev_Off, ax ;AN020;
2351 add ax, [SingleBufferSize] ;AN000;adjust ax
2352 mov word ptr es:[di.BUF_NEXT], ax ;AN020;
2353 mov word ptr es:[di.BUF_ID], 00FFh ;AN000;new buffer free
2354 mov word ptr es:[di.BUF_SECTOR], 0 ;AN000;To compensate the MASM 3 bug
2355 mov word ptr es:[di.BUF_SECTOR+2],0 ;AN000;To compensate the MASM 3 bug
2356 ret ;AN000;
2357Set_Buffer_Info endp
2358
2359Check_IBM_PageID proc near
2360;Function: check if the physical page 255 exists. (Physical page 255 is only
2361; one we are intereseted in, and this will be used for BUFFER
2362; manipulation by IBMBIO, IBMDOS)
2363;In: nothing
2364;Out: Carry clear and IBM_Frame_Seg set if it exist. All registers saved.
2365 push es ;AN000;
2366 push ax ;AN000;
2367 push bx ;AN000;
2368 push cx ;AN000;
2369 push dx ;AN000;
2370 push di ;AN010;
2371
2372IF NOT BUFFERFLAG
2373
2374 mov ax, 1B00h ;AN029;AN030;AN0 Check EMS int 2fh installed.
2375 int 2fh ;AN029;
2376 cmp al, 0ffh ;AN029;
2377 jne Cp_IBM_Err ;AN029;If not installed, then no IBM page.
2378 mov ax, 1B01h ;AN029;AN030;Then ask if IBM page exists.
2379 mov di, IBM_PAGE_ID ;AN029;=255
2380 int 2fh ;AN029;
2381 or ah, ah ;AN029;
2382 jnz Cp_IBM_Err ;AN029;;No IBM Page
2383 mov cs:IBM_Frame_Seg, es ;AN029;;Save Physical IBM page frame addr.
2384 mov cs:Real_IBM_Page_Id, di ;AN029;;Real page number for it.
2385 clc ;AN029;
2386 jmp short Cp_ID_Ret ;AN029;
2387
2388ELSE
2389 push cs ;AN000;
2390 pop es ;AN000;
2391 mov ah, GET_PAGE_FRAME ;AN010;=58h
2392 mov al, GET_NUM_PAGEFRAME ;AN010;=01h How many page frames?
2393 int EMS_INT ;AN010;
2394 or ah, ah ;AN010;
2395 jnz hkn_err ;AN010;
2396 cmp cx, MAX_NUM_PAGEFRAME ;AN010;
2397 ja hkn_err ;AN010; cannot handle this big number
2398 push cx ;AN010;
2399 mov ah, GET_PAGE_FRAME ;AN010;
2400 mov al, GET_PAGEFRAME_TAB ;AN010;
2401 mov di, offset Frame_info_Buffer ;AN010;
2402 int EMS_INT ;AN010;
2403 pop cx ;AN010;
2404 or ah, ah ;AN010;
2405 jnz cp_IBM_Err ;AN010;
2406Cp_IBM_ID: ;AN010;
2407
2408; mov dx, es:[di]
2409; mov cs:[FIRST_PAGE], dx
2410; mov dx, es:[di+2]
2411; mov cs:[FIRST_PAGE+2], dx
2412
2413 xor dx, dx
2414
2415; int 3
2416find_page:
2417 cmp es:[di], 0a000h ; is current page above 640K
2418 jb next ; NO - goto check_last
2419
2420 inc dx ; count the no. of pages above 640K
2421
2422 cmp dx, 1
2423 jne first_ok
2424
2425 mov ax, es:[di]
2426 mov cs:[FIRST_PAGE], ax
2427 mov ax, es:[di+2]
2428 mov cs:[FIRST_PAGE+2], ax
2429
2430first_ok:
2431 mov ax, cs:[FIRST_PAGE]
2432 cmp ax, es:[di] ; is this page less than the one we have in
2433 ; FIRST_PAGE
2434 jbe check_last ; NO - goto check_last
2435 mov ax, es:[di] ; update FIRST_PAGE with this page segment
2436 mov cs:[FIRST_PAGE], ax
2437 mov ax, es:[di+2]
2438 mov cs:[FIRST_PAGE+2], ax
2439 jmp next
2440
2441hkn_err: jmp cp_ibm_err
2442
2443check_last:
2444 mov ax, cs:[LAST_PAGE] ;
2445 cmp ax, es:[di] ; is this page greater than the one we have in
2446 ; LAST_PAGE?
2447 ja next ; NO - goto next
2448 mov ax, es:[di] ; update LAST_PAGE with this value.
2449 mov cs:[LAST_PAGE], ax
2450 mov ax, es:[di+2]
2451 mov cs:[LAST_PAGE+2], ax
2452
2453next:
2454 add di, 4
2455 loop find_page
2456
2457 cmp dx, 3 ; there should be at least 3 pages
2458 ; above 640K for the buffers to be
2459 ; installed.
2460 jb Cp_IBM_Err
2461
2462 mov ax, cs:[LAST_PAGE]
2463 mov cs:IBM_Frame_Seg, ax
2464 mov ax, cs:[LAST_PAGE+2]
2465 mov cs:Real_IBM_Page_Id, ax
2466 mov cs:[NPA640], dx
2467 clc
2468 jmp short Cp_Id_Ret
2469
2470ENDIF
2471
2472
2473; cmp word ptr es:[di+2], IBM_PAGE_ID ;AN010; the second word is the id
2474; je Got_IBM_ID ;AN010;
2475; add di, 4 ;AN010; advance to the next row (4 bytes)
2476; loop Cp_IBM_ID ;AN010;
2477
2478Cp_IBM_Err: ;AN010;;AN029;
2479 stc ;AN000;;AN029;
2480 jmp short Cp_ID_Ret ;AN000;;AN029;
2481
2482;Got_IBM_ID: ;AN000;
2483; mov ax, word ptr es:[di] ;AN010;Physical seg. addr.
2484; mov cs:IBM_Frame_Seg, ax ;AN000;
2485; clc ;AN000;
2486Cp_ID_Ret: ;AN000;
2487 pop di ;AN010;
2488 pop dx ;AN000;
2489 pop cx ;AN000;
2490 pop bx ;AN000;
2491 pop ax ;AN000;
2492 pop es ;AN000;
2493 ret ;AN000;
2494Check_IBM_PageID endp
2495
2496;
2497Save_Map_State proc ;AN010;
2498;Function: Save the map state.
2499;In)
2500; EMS_Ctrl_Tab = double word pointer to EMS_state control table address
2501; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address
2502;Out) Map state saved
2503 push ax ;AN010;
2504 push ds ;AN010;
2505 push si ;AN010;
2506 push es ;AN010;
2507 push di ;AN010;
2508 lds si, cs:EMS_Ctrl_Tab ;AN010;
2509 les di, cs:EMS_state_Buf ;AN010;
2510 mov ah, EMAP_STATE ;AN010; =4Fh
2511 mov al, GET_MAP_STATE ;AN010; =00h
2512 int EMS_INT ;AN010;
2513 pop di ;AN010;
2514 pop es ;AN010;
2515 pop si ;AN010;
2516 pop ds ;AN010;
2517 pop ax ;AN010;
2518 ret ;AN010;
2519Save_Map_State endp
2520;
2521Restore_Map_State proc ;AN010;
2522 push ax ;AN010;
2523 push ds ;AN010;
2524 push si ;AN010;
2525 lds si, cs:EMS_state_Buf ;AN010;
2526 mov ah, EMAP_STATE ;AN010;
2527 mov al, SET_MAP_STATE ;AN010;
2528 int EMS_INT ;AN010;
2529 pop si ;AN010;
2530 pop ds ;AN010;
2531 pop ax ;AN010;
2532 ret ;AN010;
2533Restore_Map_State endp
2534;
2535Map_Page proc near ;AN000;
2536;Function: Map the logical page in BX of handle in DX to the physical page 255
2537;In)
2538; BX = logical page number
2539; DX = EMS handle
2540; EMS_Ctrl_Tab = double word pointer to EMS_state control table address
2541; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address
2542;Out) Logical page mapped into first phsical page frame.
2543; AX saved.
2544
2545 push ax ;AN000;
2546 mov ah, EMAP_L_TO_P ;AN000;
2547 mov al, byte ptr cs:Real_IBM_PAGE_ID ;AN029;= 255
2548 int EMS_INT ;AN000;
2549 pop ax ;AN000;
2550 ret ;AN000;
2551Map_Page endp ;AN000;
2552;
2553
2554Roundup proc
2555;In: DX;AX - operand
2556; CX - divisor
2557; Important: DX should be less than CX.
2558;out: AX - Quotient (Rounded up)
2559
2560 div cx ;AN000;
2561 or dx, dx ;AN000;
2562 jz RU_ret ;AN000;
2563 inc AX ;AN000;
2564RU_ret: ;AN000;
2565 ret ;AN000;
2566Roundup endp
2567;------------------------------------------------------------------------------
2568;J.K. 5/6/86. IBMSTACK initialization routine.
2569 IF STACKSW
2570.SALL
2571
2572INCLUDE STKINIT.INC
2573
2574.XALL
2575 ENDIF
2576;------------------------------------------------------------------------------
2577 public SetDevMark
2578SetDevMark proc
2579;Set the DEVMARK for MEM command.
2580;In: [MEMHI] - the address to place DEVMARK
2581; [MEMLO] = 0
2582; AL = ID for DEVMARK_ID
2583;OUT: DEVMARK established.
2584; the address saved in cs:[DevMark_Addr]
2585; [MEMHI] increase by 1.
2586
2587 push es ;AN005;
2588 push cx ;AN005;
2589
2590 mov cx, cs:[memhi] ;AN005;
2591 mov cs:[DevMark_Addr],cx ;AN005;
2592 mov es, cx ;AN005;
2593 mov es:[DEVMARK_ID], al ;AN005;
2594 inc cx ;AN007;
2595 mov es:[DEVMARK_SEG], cx ;AN007;
2596
2597 pop cx ;AN005;
2598 pop es ;AN005;
2599 inc cs:[memhi] ;AN005;
2600 ret ;AN005;
2601SetDevMark endp
2602
2603;*******************************************************************************
2604;Function: Load SHARE.EXE, if Big_Media_Flag = 1 and SHARE.EXE has not been *
2605; loaded yet. *
2606; This routine will use the same path for SHELL= command. *
2607; If SHELL= command has not been entered, then default to the root *
2608; directory. *
2609; If load fails, then issue message "Warning: SHARE.EXE not loaded" *
2610; *
2611;Input: Big_Media_Flag, COMMND *
2612;Output: Share.exe loaded if necessary. *
2613; *
2614;*******************************************************************************
2615LoadShare proc near ;AN021;
2616 cmp Big_Media_Flag, 1 ;AN021;
2617 jne LShare_Ret ;AN021;
2618;Check if SHARE is already loaded.
2619 mov ax, 1000h ;AN021;multShare installation check
2620 int 2fh ;AN021;
2621 cmp al, 0ffh ;AN021;
2622 jz LShare_Ret ;AN021;Share already loaded!
2623;SHARE not loaded.
2624 push cs ;AN021;
2625 pop ds ;AN021;
2626 push cs ;AN021;
2627 pop es ;AN021;
2628 mov si, offset COMMND ;AN021;
2629 mov di, offset PathString ;AN021;
2630LShare_String: ;AN021;
2631 movsb ;AN021;
2632 cmp byte ptr [di-1], 0 ;AN021;reached to the end?
2633 jne LShare_string ;AN021;
2634 mov si, offset PathString ;AN021;SI= start of PathString
2635LShare_Tail: ;AN021;
2636 dec di ;AN021;
2637 cmp byte ptr [di], "\" ;AN021;
2638 je LShare_Got_Tail ;AN021;
2639 cmp byte ptr [di], ":" ;AN021;
2640 je LShare_Got_Tail ;AN021;
2641 cmp di, si ;AN021;No path case (e.g. SHELL=command.com)
2642 je LShare_Got_Tail_0 ;AN021;
2643 jmp LShare_Tail ;AN021;
2644LShare_Got_Tail: ;AN021;di -> "\" or ":"
2645 inc di ;AN021;
2646LShare_Got_Tail_0: ;AN021;
2647 mov si, offset LShare ;AN021;
2648LShare_Set_Filename: ;AN021;
2649 movsb ;AN021;Tag "SHARE.EXE",0,0Ah to the path.
2650 cmp byte ptr [di-1], 0Ah ;AN021;Line feed?
2651 jne LShare_Set_Filename ;AN021;
2652;Now, we got a path,filename with no parameters for SHARE.EXE
2653 mov si, offset PathString ;AN021;
2654 or Install_Flag, SHARE_INSTALL ;AN021;Signals Do_Install_Exec that this is for SHARE.EXE.
2655 call Do_Install_Exec ;AN021;execute it.
2656 jnc LShare_Ret ;AN021;No problem
2657;Load/Exec failed. Show "Warning: SHARE should be loaded for large media"
2658 push cs ;AN021;
2659 pop ds ;AN021;
2660 mov dx, offset ShareWarnMsg ;AN021;WARNING! SHARE should be loaded...
2661 invoke Print ;AN021;
2662LShare_Ret: ;AN021;
2663 ret ;AN021;
2664LoadShare endp ;AN021;
2665
2666SYSINITSEG ENDS
2667 END
2668 \ No newline at end of file