2 ; SCCSID = @(#)sysinit1.asm 1.7 85/10/24
3 TITLE BIOS SYSTEM INITIALIZATION
5 ;==============================================================================
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 ;==============================================================================
51 STACKSW EQU TRUE
;Include Switchable Hardware Stacks
52 IBMJAPVER EQU FALSE
;If TRUE set KANJI true also
54 ALTVECT EQU FALSE
;Switch to build ALTVECT version
56 MYCDS_SIZE equ
88 ;J.K. Size of Curdir_List. If it is not
57 ;the same, then will generate compile error.
67 ;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS.
71 include smdossym
.inc ;J.K. Reduced version of DOSSYM.INC
75 include smifssym
.inc ;AN000;
76 include defems
.inc ;AN010;
77 include DEVMARK
.inc ;AN005;
84 ;AN000 J.K. If MYCDS_SIZE <> CURDIRLEN, then force a compilatiaon error.
85 if MYCDS_SIZE NE CURDIRLEN
86 %
OUT \a\a\a !!! SYSINIT1 COMPILATION FAILED
. DIFFERENT CDS SIZE !!!
87 .ERRE MYCDS_SIZE
EQ CURDIRLEN
94 ;---------------------------------------
95 ;Equates for Main stack and stack Initialization program
108 AllocByte equ
es:byte ptr [bp+0]
109 IntLevel equ
es:byte ptr [bp+1]
110 SavedSP equ
es:word ptr [bp+2]
111 SavedSS equ
es:word ptr [bp+4]
112 NewSP equ
es:word ptr [bp+6]
119 ;External variables in IBMBIO for INT19h handling rouitne. J.K. 10/23/86
120 CODE segment public 'code'
123 IRP AA
,<02,08,09,0A
,0B,0C
,0D,0E
,70,72,73,74,76,77>
124 EXTRN Int19OLD
&AA
:dword
128 ;---------------------------------------
129 ;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track
130 MULTRK_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.
133 MULTRK_OFF1 EQU
00000000B ;initial value. No "Multitrack=" command entered.
134 MULTRK_OFF2 EQU
00000001B ;User specified Multitrack=off.
136 CODE segment public 'code'
137 EXTRN MulTrk_flag
:word ;AN002;
139 ;J.K. 6/29/87 End of Multi-track definition.
141 SYSINITSEG
SEGMENT PUBLIC 'SYSTEM_INIT'
143 ASSUME
CS:SYSINITSEG
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
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;
155 EXTRN INT24
:NEAR,MEM_ERR
:NEAR
157 extrn Multi_Pass
:NEAR ;AN024;
159 extrn Error_Line
:near
161 PUBLIC CURRENT_DOS_LOCATION
162 PUBLIC FINAL_DOS_LOCATION
171 PUBLIC CNTRYFILEHANDLE
173 public Big_Media_Flag
;AN021;Set by IBMINIT
176 ;Internal Stack Information
182 PUBLIC dosinfo
,entry_point
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
199 public Buffer_LineNum
204 public Buffer_Slash_X
;AN023;
205 public ConfigMsgFlag
;AN014;
206 public Do_Install_Exec
;AN019;
207 public Multi_Pass_Id
;AN024;
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
219 Endstackcode
label byte
227 CURRENT_DOS_LOCATION
DW 0000
230 ENTRY_POINT
LABEL DWORD
232 FINAL_DOS_LOCATION
DW 0000
233 DEVICE_LIST
DD 00000000
235 SYSI_Country
LABEL DWORD ;J.K. 5/29/86 Pointer to
236 DW 0000 ;country table in DOS
239 Fake_Floppy_Drv db 0 ;AN001;Set to 1 if this machine
240 ;does not have any floppies!!!
241 Big_Media_Flag db 0 ;AN021;Set by IBMINIT if > 32 MB fixed media exist.
243 ;Variables for Stack Initialization Program.
245 STACK_COUNT
DW DefaultCount
246 STACK_SIZE
DW DefaultSize
247 STACK_ADDR
DD 00000000
249 ; various default values
252 DEFAULT_DRIVE
DB 00 ;initialized by IBMINIT.
253 BUFFERS
DW -1 ; initialized during buffer allocation
254 H_Buffers dw 0 ;AN000; # of the Heuristic buffers. Initially 0.
255 Buffer_Pages dw 0 ;AN000; # of extended memory pages for the buffer.
256 BufferBuckets dw 0 ;AN000;
257 Buffer_odds dw 0 ;AN000;
258 SingleBufferSize dw ?
;AN000; Maximum sector size + buffer header
259 MaxNumBuf1 db 15 ;AN026;Num of buffers in a bucket group 1.
260 MaxNumBuf2 db 15 ;AN026;Num of buffers in a possible bucket group 2.
261 NthBuck db 0 ;AN026; 1st bucket group = 1st bucket through Nth Bucket. The rest = second group
268 EMS_SAVE_BUF
DB 0,0,0,0,0,0,0,0,0,0,0,0
272 FILES
DB 8 ; enough files for pipe
273 FCBS
DB 4 ; performance for recycling
274 Keep
DB 0 ; keep original set
275 NUM_CDS
DB 5 ; 5 net drives
279 COMMAND_LINE DB 2,0,"P
" ;Default Command.com Args
283 LineCount dw 0 ;AN000; Line count in config.sys
284 ShowCount db ' ',CR,LF,'$' ;AN000; Used to convert Linecount to ASCII.
285 Buffer_LineNum dw 0 ;AN000; Line count for "BUFFERS
=" command if entered.
287 Sys_Model_Byte db 0FFh ;model byte used in SYSINIT
288 Sys_Scnd_Model_Byte db 0 ;secondary model byte used in SYSINIT
290 Buffer_Slash_X db 0 ;AN000;AN023; BUFFERS= ... /X option entered.
291 Real_IBM_Page_Id dw 0 ;AN029;
292 IBM_Frame_Seg dw 0 ;AN000; segment value for physical IBM page frame.
293 Frame_Info_Buffer dw (MAX_NUM_PAGEFRAME * 4) dup (0) ;AN010; For EMS. as per spec. 2 words per entry
294 EMSHandleName db 'BUFFERS ' ;AN010; 8 char. EMS handle name
295 EMS_Ctrl_Tab dd 0 ;AN010;
296 EMS_State_Buf dd 0 ;AN010;
297 BUF_PREV_OFF dw 0 ;AN020;
298 EMS_Buf_First dw 0 ;AN020;
301 COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO>
304 ;------------------------------------------------------------------
305 ;J.K. 2/23/87 ;variables for INSTALL= command.
307 Multi_Pass_Id db 0 ;AN024;AN027;
308 Install_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
313 Config_Size dw 0 ;AN000; size of config.sys file. Set by SYSCONF.ASM
314 Sysinit_Base_Ptr dd 0 ;AN000; pointer to SYSINIT_BASE
315 Sysinit_Ptr dd 0 ;AN000; returning addr. from SYSINIT_BASE
316 CheckSum dw 0 ;AN000; Used by Sum_up
318 Ldexec_FCB db 20 dup (' ') ;AN000;big enough
319 Ldexec_Line db 0 ;AN000;# of parm characters
320 Ldexec_start db ' ' ;AN000;
321 Ldexec_parm db 80 dup (0) ;AN000;
323 INSTEXE EXEC0 <0,Ldexec_Line,Ldexec_FCB,Ldexec_FCB> ;AN000;
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;
342 ;;Extended attribute value
343 ;EA_INSTALLABLE equ 4 ;AN008;Value for Installable file
345 ;------------------------------------------------------------------
346 ;J.K. 5/15/87 ;Request header, variables for IFS= command.
348 IFS_Flag dw 0 ;AN000; Set to 1 if it is an IFS.
349 IS_IFS equ 00000001b ;IFS command?
350 NOT_IFS equ 11111110b
352 IFS_RH IFSRH <LENGTH_INIT, IFSINIT,,,,> ;AN000; IFS initialization request packet
354 ;------------------------------------------------------------------
355 ;Variables for Comment=
356 COM_Level db 0 ;AN000;level of " " in command line
357 CMMT db 0 ;AN000;length of COMMENT string token
358 CMMT1 db 0 ;AN000;token
359 CMMT2 db 0 ;AN000;token
360 Cmd_Indicator db ? ;AN000;
361 DoNotShowNum db 0 ;AN000;
363 ;------------------------------------------------------------------
365 Org_Count dw 0000 ;AN019;
367 CntryFilehandle DW 0000
368 Old_Area dw 0 ;AN013;
369 Impossible_Owner_Size dw 0 ;AN013; Paragraph
370 ;------------------------------------------------------------------
371 BucketPTR LABEL dword ;AN000;
372 BUFPTR LABEL DWORD ;LEAVE THIS STUFF IN ORDER!
379 PACKET DB 24 ;AN014; Was 22
381 DB 0 ;INITIALIZE CODE
388 ConfigMsgFlag dw 0 ;AN014;AN022; Used to control "Error
in CONFIG
.SYS line
#" message
390 TempStack DB 80h DUP (?)
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*****************************************************************
399 cmp ah, 0 ; double check
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
406 No_ROM_Config: ; Old ROM
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)
420 test ax,1 ; has floppy ?
422 mov cs:Fake_Floppy_Drv,1 ; no floppy, fake.
424 ;SB34SYSINIT1001********************************************************
431 MOV CX,cs:[MEMORY_SIZE]
432 CMP CX,1 ; 1 means do scan
434 MOV CX,2048 ;START SCANNING AT 32K BOUNDARY
448 MOV cs:[MEMORY_SIZE],CX
451 IF IBMVER OR IBMJAPVER
452 MOV CX,cs:[MEMORY_SIZE]
455 NOSCAN: ; CX is mem size in para
460 MOV AX,OFFSET SYSSIZE
462 SUB CX,AX ;Compute new sysinit location
464 MOV CX,OFFSET SYSSIZE + 1
465 SHR CX,1 ;Divide by 2 to get words
466 REP MOVSW ;RELOCATE SYSINIT
478 ; MOVE THE DOS TO ITS PROPER LOCATION
482 ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING
484 MOV AX,[CURRENT_DOS_LOCATION] ; Where it is (set by BIOS)
486 MOV AX,[FINAL_DOS_LOCATION] ; Where it is going (set by BIOS)
497 LDS SI,[DEVICE_LIST] ; Set for call to DOSINIT
498 MOV DX,[MEMORY_SIZE] ; Set for call to DOSINIT
503 MOV SP,OFFSET LOCSTACK ; Set stack
508 STI ; Leave INTs disabled for ALTVECT
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
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.
524 les di, dosinfo ;es:di -> dosinfo
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
536 int 15h ;check extended memory size
538 mov es:[di].SYSI_EXT_MEM,ax ;save extended memory size
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;
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
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
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;
557 Not_386_System: ;AN003;
558 MOV AL,ES:[DI.SYSI_NUMIO]
559 MOV DriveNumber,AL ; Save start of installable block drvs
562 SUB AX,11H ; room for header we will copy shortly
563 mov cx, [SingleBufferSize] ;AN020;Temporary Single buffer area
567 shr cx, 1 ;AN020; Paragraphs
570 MOV [CONFBOT],AX ; Temp "unsafe
" location
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;
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;
589 PUSH DS ; Save as input to RE_INIT
593 CALL TEMPCDS ; Set up CDSs so RE_INIT and SYSINIT
594 ; can make DISK system calls
596 POP DS ; Recover DS input to RE_INIT
600 CALL RE_INIT ; Re-call the BIOS
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.
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
621 MOV DX,OFFSET INT24 ;SET UP INT 24 HANDLER
622 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
627 INT 21H ;FIRST TIME FAILS
629 INT 21H ;SECOND TIME GETS IT
631 MOV [MEMHI],AX ; MEMHI:MEMLO now points to
632 ; start of free memory
634 MOV DX,OFFSET BOOTMES
635 invoke PRINT ;Print message DOSINIT couldn't
641 MOV DL,[DEFAULT_DRIVE]
643 JZ NODRVSET ; BIOS didn't say
645 MOV AH,SET_DEFAULT_DRIVE
646 INT 21H ;SELECT THE DISK
647 ;J.K. 2/23/87 Modified to handle INSTALL= command.
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;
655 test Install_Flag, HAVE_INSTALL_CMD ;AN019;
657 inc cs:Multi_Pass_Id ;AN024;
658 call Multi_Pass ;AN019;AN024; Execute INSTALL= commands
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.
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;
667 mov ah, 49h ;AN000; Free allocated memory for command.com
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.
677 mov ax, cs:[Old_Area] ;AN013;
679 mov bx, cs:[Impossible_Owner_Size] ;AN013;
680 mov ah, SETBLOCK ;AN013;
684 MOV ES,AX ;Point to arena
685 MOV ES:[arena_owner],8 ;Set impossible owner
688 Skip_Free_SYSINITBASE: ;AN013;
690 MOV BP,DS ;SAVE COMMAND.COM SEGMENT
694 SUB BX,10H ; Point to current PHP
699 REP MOVSW ; Copy it to new location for shell
700 MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate
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
711 ; SET UP THE PARAMETERS FOR COMMAND
714 MOV SI,OFFSET COMMAND_LINE+1
725 COMTRANLP: ;FIND LENGTH OF COMMAND LINE
728 STOSB ;COPY COMMAND LINE IN
732 MOV AL,CR ; CR terminate
736 MOV ES:[80H],CL ; Set up header
737 MOV AL,[DEFAULT_DRIVE]
740 MOV [COMMAND_LINE],CL ;Count
743 MOV DX,OFFSET COMMND ;NOW POINTING TO FILE DESCRIPTION
746 MOV ES,BP ;SET LOAD ADDRESS
748 CALL LDFIL ;READ IN COMMAND
752 MOV AH,SET_DMA ;SET DISK TRANFER ADDRESS
758 XOR AX,AX ;PUSH A WORD OF ZEROS
760 PUSH BP ;SET HIGH PART OF JUMP ADDRESS
762 PUSH AX ;SET LOW PART OF JUMP ADDRESS
764 RET ;CRANK UP COMMAND!
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.
777 PUSH DX ; Save pointer to name
779 ; First, find out where the command interpreter is going to go.
782 INT 21H ;Get biggest piece
784 INT 21H ;SECOND TIME GETS IT
788 INT 21H ; Give it right back
790 ; ES:0 points to Block, and BP is the size of the block
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.
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.
803 MOV AX,(OPEN SHL 8) ;OPEN THE FILE being EXECED
804 STC ;IN CASE OF INT 24
807 MOV BX,AX ;Handle in BX
810 MOV AX,(LSEEK SHL 8) OR 2
811 STC ;IN CASE OF INT 24
812 INT 21H ; Get file size in DX:AX
814 ; Convert size in DX:AX to para in AX
815 ADD AX,15 ; Round up size for conversion to para
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.
831 POP DX ; Recover pointer to name
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
841 STC ;IN CASE OF INT 24
842 INT 21H ;GO START UP COMMAND
844 ; NOTE FALL THROUGH IF EXEC RETURNS (an error)
847 MOV DX,OFFSET BADCOM ;WANT TO PRINT COMMAND ERROR
856 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
858 MOV ES:[DI.SYSI_NCDS],CL
860 MOV AH,SIZE curdir_list
865 MOV [ALLOCLIM],SI ; Can't alloc past here!
866 MOV WORD PTR ES:[DI.SYSI_CDS + 2],SI
868 MOV WORD PTR ES:[DI.SYSI_CDS],0
869 LDS SI,ES:[DI.SYSI_DPB]
875 MOV AX,WORD PTR [FOOSTRNG]
877 MOV AX,WORD PTR [FOOSTRNG + 2]
879 INC BYTE PTR [FOOSTRNG]
882 MOV CX,curdir_flags - 4
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
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.
902 cmp cs:Fake_Floppy_Drv,1 ;fake drive ?
904 cmp ds:[si].dpb_drive,02 ;check for a: or b:
907 ;SB34SYSINIT1003*************************************************************
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.
925 STOSW ; curdir_devptr
928 LDS SI,[SI.dpb_next_dpb]
933 STOSW ; curdir_user_word
936 mov ax, 0 ;AN000;Clear out 7 bytes (curdir_type,
937 stosw ;AN000; curdir_ifs_hdr, curdir_fsda)
942 MOV BYTE PTR [FOOSTRNG],"A
"
945 ;------------------------------------------------------------------------------
947 ;------------------------------------------------------------------------------
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
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.
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
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;
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.
972 MulTrk_Flag_Done: ;AN002;
986 mov al, DEVMARK_FILES ;AN005;
987 call SetDevMark ;AN005; Set DEVMARK for SFTS (FILES)
989 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
990 ; IT DOES SIGN EXTEND.
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
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
1005 ADD [MEMLO],AX ;ALLOCATE MEMORY
1007 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO
1008 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1009 INVOKE ROUND ; Check for mem error before the STOSB
1012 REP STOSB ;CLEAN OUT THE STUFF
1014 ;------------------------------------------------------------------------------
1016 ;------------------------------------------------------------------------------
1021 mov al, DEVMARK_FCBS ;AN005;='X'
1022 call SetDevMark ;AN005;
1024 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1025 ; IT DOES SIGN EXTEND.
1028 LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA
1030 MOV WORD PTR [DI+SYSI_FCB],BX
1031 MOV WORD PTR [DI+SYSI_FCB+2],DX ;SET POINTER TO NEW Table
1034 MOV [DI+SYSI_keep],BX
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
1043 MUL BL ;AX = NUMBER OF BYTES TO CLEAR
1044 ADD [MEMLO],AX ;ALLOCATE MEMORY
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
1052 PUSH CX ; save count
1053 MOV CX,SIZE sf_entry ; number of bytes to fill
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
1062 ;------------------------------------------------------------------------------
1064 ;------------------------------------------------------------------------------
1066 ; Search through the list of media supported and allocate 3 buffers if the
1067 ; capacity of the drive is > 360KB
1069 CMP [BUFFERS], -1 ; Has buffers been already set?
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.
1076 jmp DOBUFF ; the user entered the buffers=.
1079 mov [H_Buffers], 0 ;AN000; Default is no heuristic buffers.
1080 MOV [BUFFERS], 2 ; Default to 2 buffers
1083 LES BP,CS:[DOSINFO] ; Search through the DPB's
1084 LES BP,DWORD PTR ES:[BP.SYSI_DPB] ; Get first DPB
1086 ASSUME DS:SYSINITSEG
1091 ; Test if the drive supports removeable media
1092 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1094 MOV AX, (IOCTL SHL 8) OR 8
1097 ; Ignore fixed disks
1098 OR AX, AX ; AX is nonzero if disk is nonremoveable
1101 ; Get parameters of drive
1103 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1105 MOV DX, OFFSET DeviceParameters
1106 MOV AX, (IOCTL SHL 8) OR GENERIC_IOCTL
1107 MOV CX, (RAWIO SHL 8) OR GET_DEVICE_PARAMETERS
1109 JC NOSETBUF ; Get next DPB if driver doesn't support
1112 ; Determine capacity of drive
1113 ; Media Capacity = #Sectors * Bytes/Sector
1114 MOV BX, WORD PTR DeviceParameters.DP_BPB.BPB_TotalSectors
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
1122 DIV CX ; Scale sector size in factor of
1125 MUL BX ; AX = #sectors * size factor
1126 OR DX, DX ; Just in case of LARGE floppies
1128 CMP AX, 720 ; 720 Sectors * size factor of 1
1132 jmp Chk_Memsize_for_Buffers ; Now check the memory size for default buffer count
1133 ; JMP BUFSET ; Jump out of search loop
1135 CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1
1136 jz Chk_Memsize_for_Buffers
1138 LES BP,ES:[BP.DPB_NEXT_DPB]
1141 ;J.K. 10/15/86 DCR00014.
1142 ;From DOS 3.3, the default number of buffers will be changed according to the
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.
1150 Chk_Memsize_for_Buffers:
1151 cmp [memory_size], 2000h
1154 cmp [memory_size], 4000h
1157 cmp [memory_size], 8000h
1166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1167 ;J.K. Here we should put extended stuff and new allocation scheme!!!
1168 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1169 ;*******************************************************************************
1171 ; Function: Actually allocate BUFFERS into the (extended) memory and initialize*
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. *
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 *
1187 ; BuffINFO.Cache_Count - # of caches to be installed. *
1190 ; BufferBuckets set. *
1191 ; MaxNumBuf1, MaxNumBuf2, and NthBuck set. *
1193 ; Subroutines to be called: *
1197 ; IF (BuffINFO.EMS_MODE == -1) THEN *
1199 ; IF BUFFERS < 30 THEN *
1200 ; {# of Bucket = 1; MaxNumBuf1 = BUFFERS; NthBuck = 1} *
1202 ; # of Bucket = BUFFERS/15; *
1203 ; r = BUFFERS mod 15; *
1204 ; IF r == 0 THEN NthBuck = # of Bucket *
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*
1216 ; # of Bucket = Buffer_Pages * 2; /* 2 buckets per page *
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; *
1225 ; IF (EMS_MODE <> -1) THEN *
1227 ; ELSE /*Do not use the extended memory */ *
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; *
1236 ;*******************************************************************************
1238 lds bx, cs:[DosInfo] ;AN000; ds:bx -> SYSINITVAR
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;
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;
1252 mov ax, [Buffers] ;AN000; < 99
1253 cmp al, 30 ;AN026; if less than 30,
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...
1263 mov cl, 15 ;AN026; Magic number 15.
1264 div cl ;AN026; al=# of buckets, ah=remainders
1265 push ax ;AN026; save the result
1267 mov [BufferBuckets], ax ;AN026;
1268 mov ds:[bx.HASH_COUNT], ax ;AN026;
1271 ; $IF Z ;AN026;if no remainders
1273 mov [NthBuck], al ;AN026;then set NthBuck=# of bucket for Set_Buffer proc.
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
1284 add [MaxNumBuf1], al ;AN026;
1285 mov ax, [BufferBuckets] ;AN026;
1286 mov [NthBuck], al ;AN026;
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.
1300 ; $ELSE ;AN000; Use the extended memory.
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;
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]
1326 push ds ;AN000; Save Buffer info. ptr.
1328 cmp ds:[bx.EMS_MODE], -1 ;AN000;
1331 call Set_EMS_Buffer ;AN000;
1335 call Set_Buffer ;AN000;
1340 ;Now set the secondary buffer if specified.
1341 cmp [H_Buffers], 0 ;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
1353 mov [Memlo], ax ;AN000;
1354 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1358 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1359 ;J.K. END OF NEW BUFFER SCHEME.
1360 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1363 ; DEC [BUFFERS] ; FIRST DEC acounts for buffer already
1365 ; JZ BUF1 ; All done
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]
1384 ;------------------------------------------------------------------------------
1386 ;------------------------------------------------------------------------------
1390 mov ax, DEVMARK_CDS ;AN005;='L'
1391 call SetDevMark ;AN005;
1394 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
1396 JAE GOTNCDS ; User setting must be at least NUMIO
1400 MOV ES:[DI.SYSI_NCDS],CL
1402 MOV WORD PTR ES:[DI.SYSI_CDS + 2],AX
1404 MOV WORD PTR ES:[DI.SYSI_CDS],AX
1406 MOV AH,SIZE curdir_list
1410 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1411 INVOKE ROUND ; Check for mem error before initializing
1412 LDS SI,ES:[DI.SYSI_DPB]
1414 LES DI,ES:[DI.SYSI_CDS]
1417 ;------------------------------------------------------------------------------
1418 ; Allocate Space for Internal Stack
1419 ;------------------------------------------------------------------------------
1425 ASSUME DS:SYSINITSEG
1428 ;Don't install the system stack on the PCjr. Ignore STACKS=command too.
1429 CMP [Sys_Model_Byte], 0FDh ; PCjr = 0FDh
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.
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 ?
1445 cmp [Sys_Model_Byte], 0FEh ;PC/XT or PC Portable ?
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
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'
1462 mov es, ax ;ES -> Seg. the stack code is going to move.
1466 xor si,si ;!!We know that Stack code is at the beginning of SYSINIT.
1468 mov cx, offset Endstackcode
1470 call Round ;Have enough space for relocation?
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
1478 ; Space for Internal Stack area = STACK_COUNT(ENTRYSIZE + STACK_SIZE)
1480 ADD AX, [STACK_SIZE]
1481 MOV CX, [STACK_COUNT]
1483 call ParaRound ; Convert size to pargraphs
1485 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;To set the DEVMARK_SIZE for Stack by ROUND routine.
1486 INVOKE ROUND ; Check for memory error before
1488 CALL StackInit ; Initialize hardware stack. CS=DS=sysinitseg, ES=Relocated stack code & data
1495 ASSUME DS:SYSINITSEG
1498 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1499 ; IT DOES SIGN EXTEND.
1501 XOR BX,BX ;Close standard input
1505 RCCLLOOP: ;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.
1511 MOV DX,OFFSET CONDEV
1513 MOV AH,OPEN ;OPEN CON FOR READ/WRITE
1514 STC ; Set for possible INT 24
1521 MOV BX,1 ;close standard output
1526 MOV BX,AX ;New device handle
1528 INT 21H ;Dup to 1, STDOUT
1530 INT 21H ;Dup to 2, STDERR
1532 GOAUX2: MOV DX,OFFSET AUXDEV
1533 MOV AL,2 ;READ/WRITE ACCESS
1536 MOV DX,OFFSET PRNDEV
1537 MOV AL,1 ;WRITE ONLY
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
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
1563 ; ;For Round-Up machine
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
1570 cmp [sys_model_byte], 0FDh ;PCjr?
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
1582 out dx,al ; out 02f3h,0ffh
1584 out dx,al ; out 02f4h,0ffh
1586 out dx,al ; out 02f5h,0ffh
1588 out dx,al ; out 02f6h,0ffh
1590 out dx,al ; out 02f7h,0ffh
1591 ;SB33045*******************************************************************
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*
1603 ; Test feature byte for secondary interrupt controller ;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*
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
1620 finishrearm: ; ;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*******************************************************************
1627 ;J.K. 9/29/86 Global Rearm end *******************
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.
1637 ; test [Install_Flag], HAVE_INSTALL_CMD ;AN019;;AN021;install sysinit base all the time.
1638 ; jz Skip_SYSINIT_BASE ;AN019;
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;
1656 mov di, [memhi] ;AN000;
1658 assume es:nothing ;AN000;
1659 mov word ptr [sysinit_base_ptr+2],di ;AN000; save this entry for the next use.
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.
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.
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
1677 ;------------------------------------------------------------------------------
1678 ;Skip_SYSINIT_BASE: ;AN021;
1683 mov [Old_Area], ax ;AN013; Save [AREA]
1684 MOV ES,AX ;CALC WHAT WE NEEDED
1687 INT 21H ;GIVE THE REST BACK
1691 MOV ES,AX ;Point to arena
1692 MOV ES:[arena_owner],8 ;Set impossible owner
1695 mov bx,0ffffh ;AN000;
1696 mov ah,Alloc ;AN000;
1698 mov ah,Alloc ;AN000;
1699 int 21h ;AN000; Allocate the rest of the memory
1701 mov [memhi],ax ;AN000; Start of the allocated memory
1702 mov [memlo],0 ;AN000; to be used next.
1704 ;;;; At this moment, memory from [MEMHI]:0 to Top-of-the memory is
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.
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;
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))
1731 ; MOV BX,0FFFFH ;ALLOCATE THE REST OF MEM FOR COMMAND
1739 ; test cs:[Install_Flag],IS_INSTALL ;AN000;
1740 ; jnz DO_Install_Exec ;AN000;
1746 Do_Install_Exec proc near ;AN000; Now, handles INSTALL= command.
1748 push si ;AN000; save SI for config.sys again.
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
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;
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;
1775 ; jmp SysInitPtr ;AN012;
1776 ;EA_Installable_OK: ;AN012;
1779 mov cs:Ldexec_start, ' ' ;AN015; Clear out the parm area
1780 mov di, offset Ldexec_parm ;AN000;
1781 InstallFilename: ;AN000; skip the file name
1782 lodsb ;AN000; al = ds:si; si++
1784 je Got_InstallParm ;AN000;
1785 jmp InstallFilename ;AN000;
1786 Got_InstallParm: ;AN000; copy the parameters to Ldexec_parm
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.
1793 jmp Got_Installparm ;AN000;
1794 Done_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.
1799 Install_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;
1807 mov es:CheckSum, ax ;AN000; save the value of the sum
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.
1816 ;J.K. This is the returning address from SYSINIT_BASE.
1817 SYSINITPTR: ;AN000; returning far address from SYSINIT_BASE
1818 pop si ;AN000; restore SI for CONFIG.SYS file.
1822 pop ds ;AN000; now ds - sysinitseg, es - confbot
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.
1829 jmp Install_Exit_Ret
1831 test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc?
1832 jnz Install_Exit_Ret ;AN021; Just exit.
1835 cmp ah, 3 ;AN017;Only accept "Stay Resident
" prog.
1836 je Install_Exit_Ret ;AN017;
1837 call Error_Line ;AN017;Inform the user
1838 Install_Error_Exit: ;AN021;
1842 Do_Install_Exec endp
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
1870 Sysinit_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.
1888 mov dx, Mem_alloc_err_msg ;AN000;
1890 Stall_now: jmp Stall_now ;AN000;
1892 SysInit_Base_End: jmp es:Sysinit_Ptr ;AN000; return back to sysinit module
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.
1904 mov ax,es:ConfBot ;AN021;
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.
1913 add ax, ds:word ptr [si] ;AN000;
1917 ;Now, sum up SYSINIT module.
1918 Sum_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
1925 add ax, es:word ptr [si] ;AN000;
1932 Sysinit_Base_SS equ $-Sysinit_Base ;AN000;
1934 Sysinit_Base_SP equ $-Sysinit_Base ;AN000;
1936 Mem_Alloc_Err_msg equ $-Sysinit_Base ;AN000;
1937 ;include BASEMES.INC ;AN000; Memory allocation error message
1938 include MSBIO.CL4 ;AN011; Memory allocation error message
1939 End_Sysinit_Base label byte ;AN000;
1940 SIZE_SYSINIT_BASE equ $-Sysinit_Base ;AN000;
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.
1949 ;; Carry set when DOS function call fails.
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;
1968 ; mov al, Ext_Attr_Value ;AN008;
1975 ;Get_Ext_Attribute endp ;AN008;
1978 ;------------------------------------------------------------------------------
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. *
1991 ; Buffers - Number of buffers *
1992 ; Buffer_LineNum - Saved line number to be used in case of Error case *
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. *
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 }; *
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; *
2015 ;*******************************************************************************
2018 push di ;AN000; save es, di
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;
2026 ; $IF NZ,AND,LONG ;AN004;
2030 les di, cs:[DosInfo] ;AN000; es:di -> SYSINITVAR
2031 les di, es:[di.SYSI_BUF] ;AN000; now, es:di -> BuffInfo
2033 mov ah, EMS_STATUS ;AN000; get the status of EMS = 40h
2035 or ah, ah ;AN000; EMS installed?
2036 ; $IF Z,AND,LONG ;AN000;
2040 mov ah, EMS_VERSION ;AN010;=46h
2042 cmp AL, EMSVERSION ;AN010;40h = 4.0
2043 ; $IF AE,AND,LONG ;AN010;
2047 call Check_IBM_PageID ;AN000; IBM (compatible) mode?
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
2059 mov es:[di.EMS_NPA640], ax
2060 mov es:[di.EMS_SAFE_FLAG], 1
2063 ; $IF NC,AND,LONG ;AN000;
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.
2074 cmp al, EMS_MAP_BUFF_SIZE ;AN010; Curretly=12 bytes
2075 ; $IF BE,AND ;AN010;
2077 mov ah, EQ_PAGES ;AN000; Get number of unallocated & total pages = 42h
2078 int EMS_INT ;AN000; result in BX
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;
2086 mov cs:[Buffer_Pages], ax ;AN000;
2087 mov bx, ax ;AN000; prepare for Get handle call.
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.
2093 ; $IF Z ;AN000; pages allocated.
2095 mov ah, EMS_HANDLE_NAME ;AN010;
2096 mov al, SET_HANDLE_NAME ;AN010;
2102 mov si, offset EMSHandleName ;AN010;
2103 int EMS_INT ;AN010; Set the handle name
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;
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;
2121 add di, EMS_MAP_BUFF ;AN010;
2122 mov word ptr cs:[EMS_state_Buf],di ;AN010;
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
2143 Set_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 *
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 *
2161 ;Output: Buffers, hash buckets and Hash table entries established. *
2162 ; [Memhi]:[Memlo] = address of the next available free space. *
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; *
2173 ; Next buffer ptr += buffer size; *
2176 ; MEMHI:MEMLO = Current Buffer_Bucket add + (# of odd * buffer size)*
2178 ;*******************************************************************************
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
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.
2191 xor di, di ;AN000;es:di -> hash bucket
2194 ; $DO ;AN000;For each buffer in the bucket
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?
2201 cmp cl, [MaxNumBuf1] ;AN026; last buffer of the 1st group?
2205 cmp cl, [MaxNumBuf2] ;AN026; last buffer of the 2nd group?
2209 ; $IF E ;AN020;Yes, last buffer
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
2215 mov di, ax ;AN000;adjust next buffer position
2216 ; $ENDDO E ;AN000;flag set already for testing last buffer.
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;
2229 Set_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 *
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. *
2244 ;Output: Buffers, hash buckets and Hash table entries established. *
2246 ; { For (each page) *
2247 ; { Map the page; /*Map the page into Page frame *
2248 ; For (each bucket) /*Each page has two buckets */ *
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 *
2258 ; Next buffer ptr = 0; *
2260 ; Next buffer ptr += buffer size; *
2265 ;*******************************************************************************
2267 assume ds:nothing ;AN000;to make sure.
2272 mov ax, offset ems_save_buf
2273 mov word ptr cs:[ems_state_buf], ax
2275 pop word ptr cs:[ems_state_buf+2]
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,
2286 call Map_Page ;AN000;map it to IBM physical page 254.
2287 mov di, cs:IBM_Frame_Seg ;AN000;
2289 xor di, di ;AN000;es:di -> bucket
2292 ; $DO ;AN000;For each bucket,
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
2300 ; $DO ;AN000;For each buffer in a bucket,
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?
2307 mov cs:[EMS_Buf_First], di ;AN020;then save the offset value
2310 cmp cx, MAXBUFFINBUCKET ;AN000;
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
2322 mov di, ax ;AN000;advance di to the next buffer position.
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
2331 inc bx ;AN000;increse logical page number
2332 cmp bx, cs:[Buffer_Pages] ;AN000;reached the maximum page number?
2335 call Restore_MAP_State ;AN010;
2340 Set_Buffer_Info proc
2341 ;Function: Set buf_link, buf_id, Buf_Sector
2342 ;In: ES:DI -> Buffer header to be set.
2345 ; Above entries set.
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
2357 Set_Buffer_Info endp
2359 Check_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)
2364 ;Out: Carry clear and IBM_Frame_Seg set if it exist. All registers saved.
2374 mov ax, 1B00h ;AN029;AN030;AN0 Check EMS int 2fh installed.
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
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.
2386 jmp short Cp_ID_Ret ;AN029;
2391 mov ah, GET_PAGE_FRAME ;AN010;=58h
2392 mov al, GET_NUM_PAGEFRAME ;AN010;=01h How many page frames?
2396 cmp cx, MAX_NUM_PAGEFRAME ;AN010;
2397 ja hkn_err ;AN010; cannot handle this big number
2399 mov ah, GET_PAGE_FRAME ;AN010;
2400 mov al, GET_PAGEFRAME_TAB ;AN010;
2401 mov di, offset Frame_info_Buffer ;AN010;
2405 jnz cp_IBM_Err ;AN010;
2409 ; mov cs:[FIRST_PAGE], dx
2411 ; mov cs:[FIRST_PAGE+2], dx
2417 cmp es:[di], 0a000h ; is current page above 640K
2418 jb next ; NO - goto check_last
2420 inc dx ; count the no. of pages above 640K
2426 mov cs:[FIRST_PAGE], ax
2428 mov cs:[FIRST_PAGE+2], ax
2431 mov ax, cs:[FIRST_PAGE]
2432 cmp ax, es:[di] ; is this page less than the one we have in
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
2438 mov cs:[FIRST_PAGE+2], ax
2441 hkn_err: jmp cp_ibm_err
2444 mov ax, cs:[LAST_PAGE] ;
2445 cmp ax, es:[di] ; is this page greater than the one we have in
2447 ja next ; NO - goto next
2448 mov ax, es:[di] ; update LAST_PAGE with this value.
2449 mov cs:[LAST_PAGE], ax
2451 mov cs:[LAST_PAGE+2], ax
2457 cmp dx, 3 ; there should be at least 3 pages
2458 ; above 640K for the buffers to be
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
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;
2478 Cp_IBM_Err: ;AN010;;AN029;
2480 jmp short Cp_ID_Ret ;AN000;;AN029;
2482 ;Got_IBM_ID: ;AN000;
2483 ; mov ax, word ptr es:[di] ;AN010;Physical seg. addr.
2484 ; mov cs:IBM_Frame_Seg, ax ;AN000;
2494 Check_IBM_PageID endp
2497 Save_Map_State proc ;AN010;
2498 ;Function: Save the map state.
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
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
2521 Restore_Map_State proc ;AN010;
2525 lds si, cs:EMS_state_Buf ;AN010;
2526 mov ah, EMAP_STATE ;AN010;
2527 mov al, SET_MAP_STATE ;AN010;
2533 Restore_Map_State endp
2535 Map_Page proc near ;AN000;
2536 ;Function: Map the logical page in BX of handle in DX to the physical page 255
2538 ; BX = logical page number
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.
2546 mov ah, EMAP_L_TO_P ;AN000;
2547 mov al, byte ptr cs:Real_IBM_PAGE_ID ;AN029;= 255
2551 Map_Page endp ;AN000;
2555 ;In: DX;AX - operand
2557 ; Important: DX should be less than CX.
2558 ;out: AX - Quotient (Rounded up)
2567 ;------------------------------------------------------------------------------
2568 ;J.K. 5/6/86. IBMSTACK initialization routine.
2576 ;------------------------------------------------------------------------------
2579 ;Set the DEVMARK for MEM command.
2580 ;In: [MEMHI] - the address to place DEVMARK
2582 ; AL = ID for DEVMARK_ID
2583 ;OUT: DEVMARK established.
2584 ; the address saved in cs:[DevMark_Addr]
2585 ; [MEMHI] increase by 1.
2590 mov cx, cs:[memhi] ;AN005;
2591 mov cs:[DevMark_Addr],cx ;AN005;
2593 mov es:[DEVMARK_ID], al ;AN005;
2595 mov es:[DEVMARK_SEG], cx ;AN007;
2599 inc cs:[memhi] ;AN005;
2603 ;*******************************************************************************
2604 ;Function: Load SHARE.EXE, if Big_Media_Flag = 1 and SHARE.EXE has not been *
2606 ; This routine will use the same path for SHELL= command. *
2607 ; If SHELL= command has not been entered, then default to the root *
2609 ; If load fails, then issue message "Warning
: SHARE
.EXE
not loaded
" *
2611 ;Input: Big_Media_Flag, COMMND *
2612 ;Output: Share.exe loaded if necessary. *
2614 ;*******************************************************************************
2615 LoadShare 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
2621 cmp al, 0ffh ;AN021;
2622 jz LShare_Ret ;AN021;Share already loaded!
2628 mov si, offset COMMND ;AN021;
2629 mov di, offset PathString ;AN021;
2630 LShare_String: ;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
2635 LShare_Tail: ;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;
2644 LShare_Got_Tail: ;AN021;di -> "\" or ":"
2646 LShare_Got_Tail_0: ;AN021;
2647 mov si, offset LShare
;AN021;
2648 LShare_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"
2660 mov dx, offset ShareWarnMsg
;AN021;WARNING! SHARE should be loaded...
2661 invoke Print
;AN021;
2664 LoadShare endp
;AN021;