PAGE ,132 ; ; SCCSID = @(#)sysinit1.asm 1.7 85/10/24 TITLE BIOS SYSTEM INITIALIZATION %OUT ...SYSINIT1 ;============================================================================== ;REVISION HISTORY: ;AN000 - New for DOS Version 4.00 - J.K. ;AC000 - Changed for DOS Version 4.00 - J.K. ;AN00x - PTM number for DOS Version 4.00 - J.K. ;============================================================================== ;AN001; p40 Boot from the system with no floppy diskette drives 6/26/87 J.K. ;AN002; d24 MultiTrack= command added. 6/29/87 J.K. ;AN003; d9 Double word mov for 386 machine 7/15/87 J.K. ;AN004; p447 BUFFERS = 50 /E without EMS installed hangs 8/25/87 J.K. ;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K. ;AN006; p851 Installable files not recognized corretly. 9/08/87 J.K. ;AN007; p1299 Set the second entry of DEVMARK for MEM command 9/25/87 J.K. ;AN008; p1361 New Extended Attribute 9/28/87 J.K. ;AN009; p1326 Buffers = 50 /e hangs 9/28/87 J.K. ;AN010; New EMS Interface ;AN011; New Message SKL file 10/20/87 J.K. ;AN012; P2211 Setting EA=7 for ANSI.SYS hangs the system 11/02/87 J.K. ;AN013; p2343 Set the name for SYSINIT_BASE for MEM command 11/11/87 J.K. ;AN014; D358 New device driver INIT function package 12/03/87 J.K. ;AN015; For Installed module with no parameter 12/11/87 J.K. ;AN016; D285 Undo the Extended Attribute handling 12/17/87 J.K. ;AN017; P2806 Show "Error in CONFIG.SYS ..." for INSTALL= command 12/17/87 J.K. ;AN018; P2914 Add Extended Memory Size in SYSVAR 01/05/88 J.K. ;AN019; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K. ;AN020; P3497 Performace fix for new buffer scheme 02/15/88 J.K. ;AN021; D486 SHARE installation for big media 02/23/88 J.K. ;AN022; D493 Undo D358 & do not show error message for device driv02/24/88 J.K. ;AN023; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K. ;AN024; D506 Take out the order dependency of the IFS= 03/28/88 J.K. ;AN025; P4086 Memory allocation error when loading SHARE.EXE 03/31/88 J.K. ;AN026; D517 New Balanced Real memory buffer set up scheme 04/18/88 J.K. ;AN027; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K. ;AN028; P4669 SHARE /NC causes an error 05/03/88 J.K. ;AN029; P4759 Install EMS INT2fh, INT 67h handler 05/12/88 J.K. ;AN030; P4934 P4759 INT 2Fh handler number be changed to 1Bh 05/20/88 J.K. ;============================================================================== TRUE EQU 0FFFFh FALSE EQU 0 CR equ 13 LF equ 10 TAB equ 9 IBMVER EQU TRUE IBM EQU IBMVER STACKSW EQU TRUE ;Include Switchable Hardware Stacks IBMJAPVER EQU FALSE ;If TRUE set KANJI true also MSVER EQU FALSE ALTVECT EQU FALSE ;Switch to build ALTVECT version KANJI EQU FALSE MYCDS_SIZE equ 88 ;J.K. Size of Curdir_List. If it is not ;the same, then will generate compile error. ; IF IBMJAPVER NOEXEC EQU TRUE ELSE NOEXEC EQU FALSE ENDIF DOSSIZE EQU 0A000H ;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS. .xlist ; INCLUDE dossym.INC include smdossym.inc ;J.K. Reduced version of DOSSYM.INC INCLUDE devsym.INC include ioctl.INC include BIOSTRUC.INC include smifssym.inc ;AN000; include defems.inc ;AN010; include DEVMARK.inc ;AN005; include cputype.inc include version.inc .list ;AN000 J.K. If MYCDS_SIZE <> CURDIRLEN, then force a compilatiaon error. if MYCDS_SIZE NE CURDIRLEN %OUT  !!! SYSINIT1 COMPILATION FAILED. DIFFERENT CDS SIZE !!! .ERRE MYCDS_SIZE EQ CURDIRLEN endif IF NOT IBMJAPVER EXTRN RE_INIT:FAR ENDIF ;--------------------------------------- ;Equates for Main stack and stack Initialization program IF STACKSW EntrySize equ 8 MinCount equ 8 DefaultCount equ 9 MaxCount equ 64 MinSize equ 32 DefaultSize equ 128 MaxSize equ 512 AllocByte equ es:byte ptr [bp+0] IntLevel equ es:byte ptr [bp+1] SavedSP equ es:word ptr [bp+2] SavedSS equ es:word ptr [bp+4] NewSP equ es:word ptr [bp+6] Free equ 0 allocated equ 1 overflowed equ 2 clobbered equ 3 ;External variables in IBMBIO for INT19h handling rouitne. J.K. 10/23/86 CODE segment public 'code' EXTRN Int19sem:byte IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77> EXTRN Int19OLD&AA:dword ENDM CODE ends ENDIF ;--------------------------------------- ;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns ; it on after handling CONFIG.SYS file as a ; default value, if MulTrk_flag = MULTRK_OFF1. MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered. MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off. CODE segment public 'code' EXTRN MulTrk_flag:word ;AN002; CODE ends ;J.K. 6/29/87 End of Multi-track definition. SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING EXTRN BADCOM:BYTE EXTRN SYSSIZE:BYTE EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE extrn DeviceParameters:byte extrn DevMark_Addr:word extrn SetDevMarkFlag:byte extrn PathString:byte ;AN021; extrn LShare:byte ;AN021; extrn ShareWarnMsg:byte ;AN021; EXTRN INT24:NEAR,MEM_ERR:NEAR EXTRN DOCONF:NEAR extrn Multi_Pass:NEAR ;AN024; extrn BadLoad:near extrn Error_Line:near PUBLIC CURRENT_DOS_LOCATION PUBLIC FINAL_DOS_LOCATION PUBLIC DEVICE_LIST PUBLIC SYSI_COUNTRY PUBLIC MEMORY_SIZE PUBLIC DEFAULT_DRIVE PUBLIC BUFFERS PUBLIC FILES PUBLIC NUM_CDS PUBLIC SYSINIT PUBLIC CNTRYFILEHANDLE PUBLIC COMMAND_LINE public Big_Media_Flag ;AN021;Set by IBMINIT IF STACKSW ;Internal Stack Information PUBLIC STACK_COUNT PUBLIC STACK_SIZE PUBLIC STACK_ADDR ENDIF PUBLIC dosinfo,entry_point PUBLIC fcbs,keep PUBLIC confbot,alloclim PUBLIC zero,sepchr,STALL PUBLIC count,chrptr,org_count PUBLIC bufptr,memlo,prmblk,memhi PUBLIC ldoff,area,PACKET,UNITCOUNT PUBLIC BREAK_ADDR,BPB_ADDR,drivenumber public Config_Size public Install_Flag public COM_Level public CMMT public CMMT1 public CMMT2 public Cmd_Indicator public LineCount public ShowCount public Buffer_LineNum public DoNotShowNum public IFS_Flag public IFS_RH public H_Buffers public Buffer_Slash_X ;AN023; public ConfigMsgFlag ;AN014; public Do_Install_Exec ;AN019; public Multi_Pass_Id ;AN024; ; SYSINIT$: IF STACKSW .SALL include MSSTACK.INC ;Main stack program and data definitions ; include STKMES.INC ;Fatal stack error message include MSBIO.CL5 ;Fatal stack error message .XALL public Endstackcode Endstackcode label byte ENDIF ; SYSINIT: JMP GOINIT DOSINFO LABEL DWORD DW 0000 CURRENT_DOS_LOCATION DW 0000 MSDOS LABEL DWORD ENTRY_POINT LABEL DWORD DW 0000 FINAL_DOS_LOCATION DW 0000 DEVICE_LIST DD 00000000 SYSI_Country LABEL DWORD ;J.K. 5/29/86 Pointer to DW 0000 ;country table in DOS DW 0000 Fake_Floppy_Drv db 0 ;AN001;Set to 1 if this machine ;does not have any floppies!!! Big_Media_Flag db 0 ;AN021;Set by IBMINIT if > 32 MB fixed media exist. ; ;Variables for Stack Initialization Program. IF STACKSW STACK_COUNT DW DefaultCount STACK_SIZE DW DefaultSize STACK_ADDR DD 00000000 ENDIF ; various default values MEMORY_SIZE DW 0001 DEFAULT_DRIVE DB 00 ;initialized by IBMINIT. BUFFERS DW -1 ; initialized during buffer allocation H_Buffers dw 0 ;AN000; # of the Heuristic buffers. Initially 0. Buffer_Pages dw 0 ;AN000; # of extended memory pages for the buffer. BufferBuckets dw 0 ;AN000; Buffer_odds dw 0 ;AN000; SingleBufferSize dw ? ;AN000; Maximum sector size + buffer header MaxNumBuf1 db 15 ;AN026;Num of buffers in a bucket group 1. MaxNumBuf2 db 15 ;AN026;Num of buffers in a possible bucket group 2. NthBuck db 0 ;AN026; 1st bucket group = 1st bucket through Nth Bucket. The rest = second group IF BUFFERFLAG FIRST_PAGE DW 0, 0 LAST_PAGE DW 0, 0 NPA640 DW 0 EMS_SAVE_BUF DB 0,0,0,0,0,0,0,0,0,0,0,0 ENDIF FILES DB 8 ; enough files for pipe FCBS DB 4 ; performance for recycling Keep DB 0 ; keep original set NUM_CDS DB 5 ; 5 net drives CONFBOT DW ? ALLOCLIM DW ? FOOSTRNG DB "A:\",0 COMMAND_LINE DB 2,0,"P" ;Default Command.com Args DB 29 DUP (0) ZERO DB 0 SepChr DB 0 LineCount dw 0 ;AN000; Line count in config.sys ShowCount db ' ',CR,LF,'$' ;AN000; Used to convert Linecount to ASCII. Buffer_LineNum dw 0 ;AN000; Line count for "BUFFERS=" command if entered. Sys_Model_Byte db 0FFh ;model byte used in SYSINIT Sys_Scnd_Model_Byte db 0 ;secondary model byte used in SYSINIT ; Buffer_Slash_X db 0 ;AN000;AN023; BUFFERS= ... /X option entered. Real_IBM_Page_Id dw 0 ;AN029; IBM_Frame_Seg dw 0 ;AN000; segment value for physical IBM page frame. Frame_Info_Buffer dw (MAX_NUM_PAGEFRAME * 4) dup (0) ;AN010; For EMS. as per spec. 2 words per entry EMSHandleName db 'BUFFERS ' ;AN010; 8 char. EMS handle name EMS_Ctrl_Tab dd 0 ;AN010; EMS_State_Buf dd 0 ;AN010; BUF_PREV_OFF dw 0 ;AN020; EMS_Buf_First dw 0 ;AN020; IF NOT NOEXEC COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO> ENDIF ;------------------------------------------------------------------ ;J.K. 2/23/87 ;variables for INSTALL= command. Multi_Pass_Id db 0 ;AN024;AN027; Install_Flag dw 0 ;AN000; HAVE_INSTALL_CMD equ 00000001b ;AN019; CONFIG.SYS has INSTALL= commands HAS_INSTALLED equ 00000010b ;AN019; SYSINIT_BASE installed. SHARE_INSTALL equ 00000100b ;AN021; Used to install SHARE.EXE Config_Size dw 0 ;AN000; size of config.sys file. Set by SYSCONF.ASM Sysinit_Base_Ptr dd 0 ;AN000; pointer to SYSINIT_BASE Sysinit_Ptr dd 0 ;AN000; returning addr. from SYSINIT_BASE CheckSum dw 0 ;AN000; Used by Sum_up Ldexec_FCB db 20 dup (' ') ;AN000;big enough Ldexec_Line db 0 ;AN000;# of parm characters Ldexec_start db ' ' ;AN000; Ldexec_parm db 80 dup (0) ;AN000; INSTEXE EXEC0 <0,Ldexec_Line,Ldexec_FCB,Ldexec_FCB> ;AN000; ;AN016; Undo the extended attribute handling ;EA_QueryList label byte ; dw 1 ;AN008; I need just one EA info. ; db 02h ;AN008; Type is BINARY ; dw 8000h ;AN008; Flag is SYSTEM DEFINED. ; db 8 ;AN008; Length of name is 8 bytes ; db 'FILETYPE' ;AN008; Name is FILETYPE ;Ext_Attr_List dw 1 ;AN008; Just 1 Extended attribute List ; db 2 ;AN008;EA_TYPE ; dw 8000h ;AN008;FLAG ; db 0 ;AN008;Failure reason ; db 8 ;AN008;Length of NAME ; dw 1 ;AN008;Length of VALUE ; db 'FILETYPE' ;AN008;Name ;Ext_Attr_Value db 0 ;AN008;Value ;SIZE_EXT_ATTR_LIST equ $-Ext_Attr_List ;AN008; ; ;;Extended attribute value ;EA_INSTALLABLE equ 4 ;AN008;Value for Installable file ;------------------------------------------------------------------ ;J.K. 5/15/87 ;Request header, variables for IFS= command. IFS_Flag dw 0 ;AN000; Set to 1 if it is an IFS. IS_IFS equ 00000001b ;IFS command? NOT_IFS equ 11111110b IFS_RH IFSRH ;AN000; IFS initialization request packet ;------------------------------------------------------------------ ;Variables for Comment= COM_Level db 0 ;AN000;level of " " in command line CMMT db 0 ;AN000;length of COMMENT string token CMMT1 db 0 ;AN000;token CMMT2 db 0 ;AN000;token Cmd_Indicator db ? ;AN000; DoNotShowNum db 0 ;AN000; ;------------------------------------------------------------------ COUNT DW 0000 Org_Count dw 0000 ;AN019; CHRPTR DW 0000 CntryFilehandle DW 0000 Old_Area dw 0 ;AN013; Impossible_Owner_Size dw 0 ;AN013; Paragraph ;------------------------------------------------------------------ BucketPTR LABEL dword ;AN000; BUFPTR LABEL DWORD ;LEAVE THIS STUFF IN ORDER! MEMLO DW 0 PRMBLK LABEL WORD MEMHI DW 0 LDOFF DW 0 AREA DW 0 PACKET DB 24 ;AN014; Was 22 DB 0 DB 0 ;INITIALIZE CODE DW 0 DB 8 DUP (?) UNITCOUNT DB 0 BREAK_ADDR DD 0 BPB_ADDR DD 0 DriveNumber DB 0 ConfigMsgFlag dw 0 ;AN014;AN022; Used to control "Error in CONFIG.SYS line #" message TempStack DB 80h DUP (?) GOINIT: ;J.K. before doing anything else, let's set the model byte ;SB33043***************************************************************** mov ah,0c0h ;get system configuration ;SB ;3.30* int 15h ; * ;SB ;3.30* ;SB33043***************************************************************** jc No_ROM_Config cmp ah, 0 ; double check jne No_ROM_Config mov al, ES:[BX.bios_SD_modelbyte] mov cs:[Sys_Model_Byte], al mov al, ES:[BX.bios_SD_scnd_modelbyte] mov cs:[Sys_Scnd_Model_Byte], al jmp short Move_Myself No_ROM_Config: ; Old ROM mov ax, 0f000h mov ds, ax mov al, byte ptr ds:[0fffeh] mov cs:[Sys_Model_Byte], al ;set the model byte. ;J.K.6/24/87 Set Fake_Floppy_Drv if there is no diskette drives in this machine. ;SB34SYSINIT1001******************************************************** ;SB execute the equipment determination interrupt and then ;SB check the returned value to see if we have any floppy drives ;SB if we have no floppy drive we set cs:Fake_Floppy_Drv to 1 ;SB See the AT Tech Ref BIOS listings for help on the equipment ;SB flag interrupt (11h) int 11h test ax,1 ; has floppy ? jnz Move_Myself mov cs:Fake_Floppy_Drv,1 ; no floppy, fake. ;SB34SYSINIT1001******************************************************** Move_Myself: CLD ; Set up move XOR SI,SI MOV DI,SI IF MSVER MOV CX,cs:[MEMORY_SIZE] CMP CX,1 ; 1 means do scan JNZ NOSCAN MOV CX,2048 ;START SCANNING AT 32K BOUNDARY XOR BX,BX MEMSCAN:INC CX JZ SETEND MOV DS,CX MOV AL,[BX] NOT AL MOV [BX],AL CMP AL,[BX] NOT AL MOV [BX],AL JZ MEMSCAN SETEND: MOV cs:[MEMORY_SIZE],CX ENDIF IF IBMVER OR IBMJAPVER MOV CX,cs:[MEMORY_SIZE] ENDIF NOSCAN: ; CX is mem size in para MOV AX,CS MOV DS,AX ASSUME DS:SYSINITSEG MOV AX,OFFSET SYSSIZE Call ParaRound SUB CX,AX ;Compute new sysinit location MOV ES,CX MOV CX,OFFSET SYSSIZE + 1 SHR CX,1 ;Divide by 2 to get words REP MOVSW ;RELOCATE SYSINIT ASSUME ES:SYSINITSEG PUSH ES MOV AX,OFFSET SYSIN PUSH AX AAA_DUMMY PROC FAR RET AAA_DUMMY ENDP ; ; MOVE THE DOS TO ITS PROPER LOCATION ; SYSIN: ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING MOV AX,[CURRENT_DOS_LOCATION] ; Where it is (set by BIOS) MOV DS,AX MOV AX,[FINAL_DOS_LOCATION] ; Where it is going (set by BIOS) MOV ES,AX ASSUME ES:NOTHING XOR SI,SI MOV DI,SI MOV CX,DOSSIZE/2 REP MOVSW LDS SI,[DEVICE_LIST] ; Set for call to DOSINIT MOV DX,[MEMORY_SIZE] ; Set for call to DOSINIT CLI MOV AX,CS MOV SS,AX MOV SP,OFFSET LOCSTACK ; Set stack ASSUME SS:SYSINITSEG IF NOT ALTVECT STI ; Leave INTs disabled for ALTVECT ENDIF LOCSTACK LABEL BYTE CALL MSDOS ; Call DOSINIT ;ES:DI -> SysInitVars_Ext mov ax, word ptr es:[di.SYSI_InitVars] ;J.K. 5/29/86 mov word ptr [dosinfo], ax mov ax, word ptr es:[di.SYSI_InitVars+2] mov word ptr [dosinfo+2],ax ;set the sysvar pointer mov ax, word ptr es:[di.SYSI_Country_Tab] mov word ptr [SYSI_Country],ax mov ax, word ptr es:[di.SYSI_Country_Tab+2] mov word ptr [SYSI_Country+2],ax ;set the SYSI_Country pointer J.K. les di, dosinfo ;es:di -> dosinfo clc ;AN018;Get the extended memory size ;SB34SYSINIT1002************************************************************** ;SB execute the get extended memory size subfunction in the BIOS INT 15h ;SB if the function reports an error do nothing else store the extended ;SB memory size reported at the appropriate location in the dosinfo buffer ;SB currently pointed to by es:di. Use the offsets specified in the ;SB definition of the sysinitvars struct in inc\sysvar.inc ;SB 5 LOCS mov ah,88h int 15h ;check extended memory size jc No_Ext_Memory mov es:[di].SYSI_EXT_MEM,ax ;save extended memory size No_Ext_Memory: ;SB34SYSINIT1002************************************************************** mov word ptr es:[di.SYSI_IFS], -1 ;AN000; Initialize SYSI_IFS chain. mov word ptr es:[di.SYSI_IFS+2], -1 ;AN000; mov ax, es:[di.SYSI_MAXSEC] ;AN020; Get the sector size add ax, BUFINSIZ ;AN020; size of buffer header mov [SingleBufferSize], ax ;AN020; total size for a buffer mov al, Default_Drive ;AN000;Get the 1 based boot drive number set by IBMINIT mov es:[di.SYSI_BOOT_DRIVE], al ;AN000; set SYSI_BOOT_DRIVE ; Determine if 386 system... Get_CPU_Type ; macro to determine cpu type cmp ax, 2 ; is it a 386? jne Not_386_System ; no: don't mess with flag mov es:[di.SYSI_DWMOVE], 1 ;AN003; Not_386_System: ;AN003; MOV AL,ES:[DI.SYSI_NUMIO] MOV DriveNumber,AL ; Save start of installable block drvs MOV AX,CS SUB AX,11H ; room for header we will copy shortly mov cx, [SingleBufferSize] ;AN020;Temporary Single buffer area shr cx, 1 ;AN020; shr cx, 1 ;AN020; shr cx, 1 ;AN020; shr cx, 1 ;AN020; Paragraphs inc cx ;AN020; sub ax, cx ;AN020; MOV [CONFBOT],AX ; Temp "unsafe" location push es ;AN020; push di ;AN020; les di, es:[di.SYSI_BUF] ;AN020;get the buffer hash entry pointer les di, es:[di.HASH_PTR] ;AN020; mov word ptr es:[di.BUFFER_BUCKET],0 ;AN020; mov word ptr es:[di.BUFFER_BUCKET+2], ax ;AN020; mov es, ax ;AN020; xor ax, ax ;AN020; mov di, ax ;AN020;es:di -> Single buffer mov es:[di.BUF_NEXT], ax ;AN020;points to itself mov es:[di.BUF_PREV], ax ;AN020;points to itself mov word ptr es:[di.BUF_ID],00FFh ;AN020;free buffer, clear flag mov word ptr es:[di.BUF_SECTOR], 0 ;AN020; mov word ptr es:[di.BUF_SECTOR+2], 0 ;AN020; pop di ;AN020; pop es ;AN020; PUSH DS ; Save as input to RE_INIT PUSH CS POP DS ASSUME DS:SYSINITSEG CALL TEMPCDS ; Set up CDSs so RE_INIT and SYSINIT ; can make DISK system calls POP DS ; Recover DS input to RE_INIT ASSUME DS:NOTHING IF NOT IBMJAPVER CALL RE_INIT ; Re-call the BIOS ENDIF STI ; INTs OK CLD ; MAKE SURE ; DOSINIT has set up a default "process" (PHP) at DS:0. We will move it out ; of the way by putting it just below SYSINIT at end of memory. MOV BX,CS SUB BX,10H MOV ES,BX XOR SI,SI MOV DI,SI MOV CX,80H REP MOVSW MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate MOV AH,SET_CURRENT_PDB INT 21H ; Tell DOS we moved it PUSH DS PUSH CS POP DS ASSUME DS:SYSINITSEG MOV DX,OFFSET INT24 ;SET UP INT 24 HANDLER MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H INT 21H MOV BX,0FFFFH MOV AH,ALLOC INT 21H ;FIRST TIME FAILS MOV AH,ALLOC INT 21H ;SECOND TIME GETS IT MOV [AREA],AX MOV [MEMHI],AX ; MEMHI:MEMLO now points to ; start of free memory IF ALTVECT MOV DX,OFFSET BOOTMES invoke PRINT ;Print message DOSINIT couldn't ENDIF POP DS ASSUME DS:NOTHING MOV DL,[DEFAULT_DRIVE] OR DL,DL JZ NODRVSET ; BIOS didn't say DEC DL ;A = 0 MOV AH,SET_DEFAULT_DRIVE INT 21H ;SELECT THE DISK ;J.K. 2/23/87 Modified to handle INSTALL= command. NODRVSET: CALL DOCONF ;DO THE CONFIG STUFF inc cs:Multi_Pass_Id ;AN027; call Multi_Pass ;AN027; inc cs:Multi_Pass_Id ;AN024; call Multi_Pass ;AN024; call EndFile test Install_Flag, HAVE_INSTALL_CMD ;AN019; jz DoLast ;AN019; inc cs:Multi_Pass_Id ;AN024; call Multi_Pass ;AN019;AN024; Execute INSTALL= commands ;J.K. [AREA] has the segment address for the allocated memory of SYSINIT,CONFBOT. ;Free the CONFBOT area used for CONFIG.SYS and SYSINIT itself. DoLast: call LoadShare ;AN021; Try to load share.exe, if needed. mov cs:[DoNotShowNum], 1 ;AN000; Done with CONFIG.SYS. Do not show line number message. mov cx, [area] ;AN000; mov es, cx ;AN000; mov ah, 49h ;AN000; Free allocated memory for command.com int 21h ;AN000; test cs:[Install_flag], HAS_INSTALLED ;AN013; SYSINIT_BASE installed? jz Skip_Free_SYSINITBASE ;AN013; No. ;Set Block from the Old_Area with Impossible_Owner_size. ;This will free the unnecessary SYSINIT_BASE that had been put in memory to ;handle INSTALL= command. push es ;AN013; push bx ;AN013; mov ax, cs:[Old_Area] ;AN013; mov es, ax ;AN013; mov bx, cs:[Impossible_Owner_Size] ;AN013; mov ah, SETBLOCK ;AN013; int 21h ;AN013; MOV AX,ES ;AN013; DEC AX ;AN013; MOV ES,AX ;Point to arena MOV ES:[arena_owner],8 ;Set impossible owner pop bx ;AN013; pop es ;AN013; Skip_Free_SYSINITBASE: ;AN013; IF NOEXEC MOV BP,DS ;SAVE COMMAND.COM SEGMENT PUSH DS POP ES MOV BX,CS SUB BX,10H ; Point to current PHP MOV DS,BX XOR SI,SI MOV DI,SI MOV CX,80H REP MOVSW ; Copy it to new location for shell MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate MOV BX,ES MOV AH,SET_CURRENT_PDB INT 21H ; Tell DOS we moved it MOV ES:[PDB_PARENT_PID],ES ;WE ARE THE ROOT ENDIF PUSH CS POP DS ASSUME DS:SYSINITSEG ; ; SET UP THE PARAMETERS FOR COMMAND ; MOV SI,OFFSET COMMAND_LINE+1 IF NOEXEC MOV DI,81H ELSE PUSH DS POP ES MOV DI,SI ENDIF MOV CL,-1 COMTRANLP: ;FIND LENGTH OF COMMAND LINE INC CL LODSB STOSB ;COPY COMMAND LINE IN OR AL,AL JNZ COMTRANLP DEC DI MOV AL,CR ; CR terminate STOSB IF NOEXEC MOV ES:[80H],CL ; Set up header MOV AL,[DEFAULT_DRIVE] MOV ES:[5CH],AL ELSE MOV [COMMAND_LINE],CL ;Count ENDIF MOV DX,OFFSET COMMND ;NOW POINTING TO FILE DESCRIPTION IF NOEXEC MOV ES,BP ;SET LOAD ADDRESS MOV BX,100H CALL LDFIL ;READ IN COMMAND JC COMERR MOV DS,BP MOV DX,80H MOV AH,SET_DMA ;SET DISK TRANFER ADDRESS INT 21H CLI MOV SS,BP MOV SP,DX STI XOR AX,AX ;PUSH A WORD OF ZEROS PUSH AX PUSH BP ;SET HIGH PART OF JUMP ADDRESS MOV AX,100H PUSH AX ;SET LOW PART OF JUMP ADDRESS CCC PROC FAR RET ;CRANK UP COMMAND! CCC ENDP ELSE ; We are going to open the command interpreter and size it as is done in ; LDFIL. The reason we must do this is that SYSINIT is in free memory. If ; there is not enough room for the command interpreter, EXEC will probably ; overlay our stack and code so when it returns with an error SYSINIT won't be ; here to catch it. This code is not perfect (for instance .EXE command ; interpreters are possible) because it does its sizing based on the ; assumption that the file being loaded is a .COM file. It is close enough to ; correctness to be usable. PUSH DX ; Save pointer to name ; First, find out where the command interpreter is going to go. MOV BX,0FFFFH MOV AH,ALLOC INT 21H ;Get biggest piece MOV AH,ALLOC INT 21H ;SECOND TIME GETS IT JC MEMERRJX ; Oooops MOV ES,AX MOV AH,DEALLOC INT 21H ; Give it right back MOV BP,BX ; ES:0 points to Block, and BP is the size of the block ; in para. ; We will now adjust the size in BP DOWN by the size of SYSINIT. We ; need to do this because EXEC might get upset if some of the EXEC ; data in SYSINIT is overlayed during the EXEC. MOV BX,[MEMORY_SIZE] MOV AX,CS SUB BX,AX ; BX is size of SYSINIT in Para ADD BX,11H ; Add the SYSINIT PHP SUB BP,BX ; BAIS down JC MEMERRJX ; No Way. MOV AX,(OPEN SHL 8) ;OPEN THE FILE being EXECED STC ;IN CASE OF INT 24 INT 21H JC COMERR ; Ooops MOV BX,AX ;Handle in BX XOR CX,CX XOR DX,DX MOV AX,(LSEEK SHL 8) OR 2 STC ;IN CASE OF INT 24 INT 21H ; Get file size in DX:AX JC COMERR ; Convert size in DX:AX to para in AX ADD AX,15 ; Round up size for conversion to para ADC DX,0 MOV CL,4 SHR AX,CL MOV CL,12 SHL DX,CL ; Low nibble of DX to high nibble OR AX,DX ; AX is now # of para for file ADD AX,10H ; 100H byte PHP CMP AX,BP ; Will it fit? JB OKLD ; Jump if yes. MEMERRJX: JMP MEM_ERR OKLD: MOV AH,CLOSE INT 21H ; Close file POP DX ; Recover pointer to name PUSH CS POP ES ASSUME ES:SYSINITSEG MOV BX,OFFSET COMEXE ; Point to EXEC block MOV WORD PTR [BX.EXEC0_COM_LINE+2],CS ; Set segments MOV WORD PTR [BX.EXEC0_5C_FCB+2],CS MOV WORD PTR [BX.EXEC0_6C_FCB+2],CS XOR AX,AX ;Load and go MOV AH,EXEC STC ;IN CASE OF INT 24 INT 21H ;GO START UP COMMAND ENDIF ; NOTE FALL THROUGH IF EXEC RETURNS (an error) COMERR: MOV DX,OFFSET BADCOM ;WANT TO PRINT COMMAND ERROR INVOKE BADFIL STALL: JMP STALL PUBLIC TEMPCDS TEMPCDS: ASSUME DS:SYSINITSEG LES DI,[DOSINFO] MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO] XOR CH,CH MOV ES:[DI.SYSI_NCDS],CL MOV AL,CL MOV AH,SIZE curdir_list MUL AH call ParaRound MOV SI,[CONFBOT] SUB SI,AX MOV [ALLOCLIM],SI ; Can't alloc past here! MOV WORD PTR ES:[DI.SYSI_CDS + 2],SI MOV AX,SI MOV WORD PTR ES:[DI.SYSI_CDS],0 LDS SI,ES:[DI.SYSI_DPB] ASSUME DS:NOTHING MOV ES,AX XOR DI,DI FOOSET: ; Init CDSs MOV AX,WORD PTR [FOOSTRNG] STOSW MOV AX,WORD PTR [FOOSTRNG + 2] STOSW INC BYTE PTR [FOOSTRNG] XOR AX,AX PUSH CX MOV CX,curdir_flags - 4 REP STOSB CMP SI,-1 ; JNZ NORMCDS ;J.K. 6/24/87 Should handle the system that does not have any floppies. ;J.K. In this case, we are going to pretended there are two dummy floppies ;J.K. in the system. Still they have DPB and CDS, but we are going to ;J.K. 0 out Curdir_Flags, Curdir_devptr of CDS so IBMDOS can issue ;J.K. "Invalid drive specification" message when the user try to ;J.K. access them. je Fooset_Zero ;AN001;Don't have any physical drive. ;SB34SYSINIT1003************************************************************* ;SB Check to see if we are faking floppy drives. If not go to NORMCDS. ;SB If we are faking floppy drives then see if this CDS being initialised ;SB is for drive a: or b: by checking the appropriate field in the DPB ;SB pointed to by ds:si. If not for a: or b: then go to NORMCDS. If ;Sb for a: or b: then execute the code given below starting at Fooset_Zero. ;SB For dpb offsets look at inc\dpb.inc. ;SB 5 LOCS cmp cs:Fake_Floppy_Drv,1 ;fake drive ? jnz NORMCDS cmp ds:[si].dpb_drive,02 ;check for a: or b: jae NORMCDS ;SB34SYSINIT1003************************************************************* Fooset_Zero: ;AN001; XOR AX,AX MOV CL,3 REP STOSW POP CX JMP SHORT FINCDS NORMCDS: POP CX ;J.K. If a non-fat based media is detected (by DPB.NumberOfFat == 0), then ; set curdir_flags to 0. This is for signaling IBMDOS and IFSfunc that ; this media is a non-fat based one. cmp [SI.dpb_FAT_count], 0 ;AN000; Non fat system? je SetNormCDS ;AN000; Yes. Set curdir_Flags to 0. AX = 0 now. MOV AX,CURDIR_INUSE ;AN000; else, FAT system. set the flag to CURDIR_INUSE. SetNormCDS: ;AN000; STOSW ; curdir_flags MOV AX,SI STOSW ; curdir_devptr MOV AX,DS STOSW LDS SI,[SI.dpb_next_dpb] FINCDS: MOV AX,-1 STOSW ; curdir_ID STOSW ; curdir_ID STOSW ; curdir_user_word mov ax,2 stosw ; curdir_end mov ax, 0 ;AN000;Clear out 7 bytes (curdir_type, stosw ;AN000; curdir_ifs_hdr, curdir_fsda) stosw ;AN000; stosw ;AN000; stosb ;AN000; LOOP FOOSET MOV BYTE PTR [FOOSTRNG],"A" return ;------------------------------------------------------------------------------ ; Allocate FILEs ;------------------------------------------------------------------------------ ENDFILE: ; WE ARE NOW SETTING UP FINAL CDSs, BUFFERS, FILES, FCSs STRINGs etc. We no ; longer need the space taken by The TEMP stuff below CONFBOT, so set ALLOCLIM ; to CONFBOT. ;J.K. 2/23/87 If this procedure has been called to take care of INSTALL= command, ;then we have to save ES,SI registers. ; test [Install_Flag],IS_INSTALL ;AN000; Called to handle INSTALL=? ; jz ENDFILE_Cont ;AN000; ; push es ;AN000; Save es,si for CONFIG.SYS ; push si ;AN000; ; test [Install_Flag],HAS_INSTALLED ;AN000; Sysinit_base already installed? ; jz ENDFILE_Cont ;AN000; No. Install it. ; jmp DO_Install_EXEC ;AN000; Just handle "INSTALL=" cmd only. ;ENDFILE_Cont: ;AN000; push ds ;AN002; mov ax, Code ;AN002; mov ds, ax ;AN002; assume ds:Code cmp MulTrk_flag, MULTRK_OFF1 ;AN002;=0, MULTRACK= command entered? jne MulTrk_Flag_Done ;AN002; or MulTrk_flag, MULTRK_ON ;AN002; Default will be ON. MulTrk_Flag_Done: ;AN002; pop ds ;AN002; assume ds:nothing MOV AX,[CONFBOT] MOV [ALLOCLIM],AX PUSH CS POP DS INVOKE ROUND MOV AL,[FILES] SUB AL,5 JBE DOFCBS push ax ;AN005; mov al, DEVMARK_FILES ;AN005; call SetDevMark ;AN005; Set DEVMARK for SFTS (FILES) pop ax ;AN005; XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!! ; IT DOES SIGN EXTEND. MOV BX,[MEMLO] MOV DX,[MEMHI] LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA LDS DI,[DI+SYSI_SFT] ;DS:BP POINTS TO SFT MOV WORD PTR [DI+SFLINK],BX MOV WORD PTR [DI+SFLINK+2],DX ;SET POINTER TO NEW SFT PUSH CS POP DS LES DI,DWORD PTR [MEMLO] ;POINT TO NEW SFT MOV WORD PTR ES:[DI+SFLINK],-1 MOV ES:[DI+SFCOUNT],AX MOV BL,SIZE SF_ENTRY MUL BL ;AX = NUMBER OF BYTES TO CLEAR MOV CX,AX ADD [MEMLO],AX ;ALLOCATE MEMORY MOV AX,6 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO or [SetDevMarkFlag], FOR_DEVMARK ;AN005; INVOKE ROUND ; Check for mem error before the STOSB ADD DI,AX XOR AX,AX REP STOSB ;CLEAN OUT THE STUFF ;------------------------------------------------------------------------------ ; Allocate FCBs ;------------------------------------------------------------------------------ DOFCBS: PUSH CS POP DS INVOKE ROUND mov al, DEVMARK_FCBS ;AN005;='X' call SetDevMark ;AN005; MOV AL,[FCBS] XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!! ; IT DOES SIGN EXTEND. MOV BX,[MEMLO] MOV DX,[MEMHI] LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA ASSUME DS:NOTHING MOV WORD PTR [DI+SYSI_FCB],BX MOV WORD PTR [DI+SYSI_FCB+2],DX ;SET POINTER TO NEW Table MOV BL,CS:Keep XOR BH,BH MOV [DI+SYSI_keep],BX PUSH CS POP DS ASSUME DS:SYSINITSEG LES DI,DWORD PTR [MEMLO] ;POINT TO NEW Table MOV WORD PTR ES:[DI+SFLINK],-1 MOV ES:[DI+SFCOUNT],AX MOV BL,SIZE SF_ENTRY MOV CX,AX MUL BL ;AX = NUMBER OF BYTES TO CLEAR ADD [MEMLO],AX ;ALLOCATE MEMORY MOV AX,size sf-2 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO or [SetDevMarkFlag], FOR_DEVMARK ;AN005; INVOKE ROUND ; Check for mem error before the STOSB ADD DI,AX ;Skip over header MOV AL,"A" FillLoop: PUSH CX ; save count MOV CX,SIZE sf_entry ; number of bytes to fill cld REP STOSB ; filled MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_ref_count],0 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position],0 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position+2],0 POP CX LOOP FillLoop ;------------------------------------------------------------------------------ ; Allocate Buffers ;------------------------------------------------------------------------------ ; Search through the list of media supported and allocate 3 buffers if the ; capacity of the drive is > 360KB CMP [BUFFERS], -1 ; Has buffers been already set? je DoDefaultBuff cmp Buffer_Slash_X, 1 ;AN000; jne DO_Buffer ;AN000; call DoEMS ;AN000; Carry set if (enough) EMS is not available jc DoDefaultBuff ;AN000; Error. Just use default buffer. DO_Buffer: jmp DOBUFF ; the user entered the buffers=. DoDefaultBuff: mov [H_Buffers], 0 ;AN000; Default is no heuristic buffers. MOV [BUFFERS], 2 ; Default to 2 buffers PUSH AX PUSH DS LES BP,CS:[DOSINFO] ; Search through the DPB's LES BP,DWORD PTR ES:[BP.SYSI_DPB] ; Get first DPB ASSUME DS:SYSINITSEG PUSH CS POP DS NEXTDPB: ; Test if the drive supports removeable media MOV BL, BYTE PTR ES:[BP.DPB_DRIVE] INC BL MOV AX, (IOCTL SHL 8) OR 8 INT 21H ; Ignore fixed disks OR AX, AX ; AX is nonzero if disk is nonremoveable JNZ NOSETBUF ; Get parameters of drive XOR BX, BX MOV BL, BYTE PTR ES:[BP.DPB_DRIVE] INC BL MOV DX, OFFSET DeviceParameters MOV AX, (IOCTL SHL 8) OR GENERIC_IOCTL MOV CX, (RAWIO SHL 8) OR GET_DEVICE_PARAMETERS INT 21H JC NOSETBUF ; Get next DPB if driver doesn't support ; Generic IOCTL ; Determine capacity of drive ; Media Capacity = #Sectors * Bytes/Sector MOV BX, WORD PTR DeviceParameters.DP_BPB.BPB_TotalSectors ; To keep the magnitude of the media capacity within a word, ; scale the sector size ; (ie. 1 -> 512 bytes, 2 -> 1024 bytes, ...) MOV AX, WORD PTR DeviceParameters.DP_BPB.BPB_BytesPerSector XOR DX, DX MOV CX, 512 DIV CX ; Scale sector size in factor of ; 512 bytes MUL BX ; AX = #sectors * size factor OR DX, DX ; Just in case of LARGE floppies JNZ SETBUF CMP AX, 720 ; 720 Sectors * size factor of 1 JBE NOSETBUF SETBUF: MOV [BUFFERS], 3 jmp Chk_Memsize_for_Buffers ; Now check the memory size for default buffer count ; JMP BUFSET ; Jump out of search loop NOSETBUF: CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1 jz Chk_Memsize_for_Buffers ; JZ BUFSET LES BP,ES:[BP.DPB_NEXT_DPB] JMP NEXTDPB ;J.K. 10/15/86 DCR00014. ;From DOS 3.3, the default number of buffers will be changed according to the ;memory size too. ; Default buffers = 2 ; If diskette Media > 360 kb, then default buffers = 3 ; If memory size > 128 kb (2000H para), then default buffers = 5 ; If memory size > 256 kb (4000H para), then default buffers = 10 ; If memory size > 512 kb (8000H para), then default buffers = 15. Chk_Memsize_for_Buffers: cmp [memory_size], 2000h jbe BufSet mov [buffers], 5 cmp [memory_size], 4000h jbe BufSet mov [buffers], 10 cmp [memory_size], 8000h jbe BufSet mov [buffers], 15 BUFSET: ASSUME DS:NOTHING POP DS POP AX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;J.K. Here we should put extended stuff and new allocation scheme!!! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;******************************************************************************* ; * ; Function: Actually allocate BUFFERS into the (extended) memory and initialize* ; it. * ; If it is installed in real memory, the number of buffers in each * ; bucket will be balanced out as far as possible for perfermance. * ; Also, if the user specified the secondary buffer cache, it will * ; be installed in the real memory. * ; * ; Input : * ; BuffINFO.EMS_MODE - 0=IBM mode, -1 = do not use extended memory. * ; BuffINFO.Frame_Page - Page frame 0 segment address * ; MEMHI:MEMLO - Start of the next available memory * ; Buffer_Pages = Number of extended memory pages for buffer * ; BUFFERS = Number of buffers * ; H_Buffers = Number of secondary buffers * ; * ; Output: * ; BuffINFO.Cache_Count - # of caches to be installed. * ; Hash table set. * ; BuffINFO set. * ; BufferBuckets set. * ; MaxNumBuf1, MaxNumBuf2, and NthBuck set. * ; * ; Subroutines to be called: * ; * ; Logic: * ; { * ; IF (BuffINFO.EMS_MODE == -1) THEN * ; { * ; IF BUFFERS < 30 THEN * ; {# of Bucket = 1; MaxNumBuf1 = BUFFERS; NthBuck = 1} * ; ELSE { * ; # of Bucket = BUFFERS/15; * ; r = BUFFERS mod 15; * ; IF r == 0 THEN NthBuck = # of Bucket * ; ELSE * ; { * ; AddBuff = r / # of Bucket; * ; NthBuck = r mod # of Bucket; * ; MaxNumBuf1 = 15 + AddBuff; /* 1st Bucket - Nth Bucket* ; MaxNumBuf2 = 15 + AddBuff +1;/*(N+1)th Bucket to last* ; } * ; } * ; } * ; ELSE * ; { * ; # of Bucket = Buffer_Pages * 2; /* 2 buckets per page * ; }; * ; * ; /*Now allocate memory for Hash table */ * ; Hash Table Size = (size Buffer_Hash_Entry) * # of Bucket; * ; Set BuffINFO.Hash_ptr to MEMHI:MEMLO; * ; Adjust MEMHI:MEMLO according to Hash table size; * ; * ; /*Set buffers*/ * ; IF (EMS_MODE <> -1) THEN * ; Set_EMS_Buffer * ; ELSE /*Do not use the extended memory */ * ; Set_Buffer; * ;/*Now set the caches if specified.*/ * ; IF (BuffINFO.Cache_count > 0) THEN * ; {Set BuffINFO.Cache_ptr to MEMHI:MEMLO; * ; MEMHI:MEMLO = MEMHI:MEMLO + 512 * BuffINFO.Cache_count; * ; }; * ; }; * ; * ;******************************************************************************* DOBUFF: ;AN000; lds bx, cs:[DosInfo] ;AN000; ds:bx -> SYSINITVAR mov ax, [Buffers] ;AN000;Set SYSI_BUFFERS mov word ptr ds:[bx.SYSI_BUFFERS], ax ;AN000; mov ax, [H_Buffers] ;AN000; mov word ptr ds:[bx.SYSI_BUFFERS+2], ax ;AN000; lds bx, ds:[bx.SYSI_BUF] ;AN000; now, ds:bx -> BuffInfo cmp ds:[bx.EMS_MODE], -1 ;AN000; ; $IF E, LONG ;AN000; JE $$XL1 JMP $$IF1 $$XL1: xor dx, dx ;AN000; mov ax, [Buffers] ;AN000; < 99 cmp al, 30 ;AN026; if less than 30, ; $IF B ;AN026; JNB $$IF2 mov [BufferBuckets], 1 ;AN026; then put every buffer mov ds:[bx.HASH_COUNT], 1 ;AN026; into one bucket mov [MaxNumBuf1], al ;AN026; mov [NthBuck], 1 ;AN026; ; $ELSE ;AN026; else... JMP SHORT $$EN2 $$IF2: mov cl, 15 ;AN026; Magic number 15. div cl ;AN026; al=# of buckets, ah=remainders push ax ;AN026; save the result xor ah, ah ;AN026; mov [BufferBuckets], ax ;AN026; mov ds:[bx.HASH_COUNT], ax ;AN026; pop ax ;AN026; or ah, ah ;AN026; ; $IF Z ;AN026;if no remainders JNZ $$IF4 mov [NthBuck], al ;AN026;then set NthBuck=# of bucket for Set_Buffer proc. ; $ELSE ;AN026;else JMP SHORT $$EN4 $$IF4: mov cl, al ;AN026; mov al, ah ;AN026;remainder/# of buckets xor ah, ah ;AN026; = div cl ;AN026;al=additional num of buffers or ah, ah ;AN026;ah=Nth bucket ; $IF Z ;AN026; JNZ $$IF6 add [MaxNumBuf1], al ;AN026; mov ax, [BufferBuckets] ;AN026; mov [NthBuck], al ;AN026; ; $ELSE ;AN026; JMP SHORT $$EN6 $$IF6: mov [NthBuck], ah ;AN026; add [MaxNumBuf1], al ;AN026;MaxNumNuf are initially set to 15. add [MaxNumBuf2], al ;AN026; inc [MaxNumBuf1] ;AN026;Additional 1 more buffer for group 1 buckets. ; $ENDIF ;AN026; $$EN6: ; $ENDIF ;AN026; $$EN4: ; $ENDIF ;AN026; $$EN2: ; $ELSE ;AN000; Use the extended memory. JMP SHORT $$EN1 $$IF1: mov ax, [Buffer_Pages] ;AN000; mov cx, MAXBUCKETINPAGE ;AN000; mul cx ;AN000; gauranteed to be word boundary. mov [BufferBuckets], ax ;AN000; mov ds:[bx.HASH_COUNT], ax ;AN000; ; $ENDIF ;AN000; $$EN1: invoke Round ;AN000; get [MEMHI]:[MEMLO] mov al, DEVMARK_BUF ;AN005; ='B' call SetDevMark ;AN005; ;Now, allocate Hash table at [memhi]:[memlo]. AX = Hash_Count. mov ax, [BufferBuckets] ;AN026; # of buckets==Hash_Count mov cx, size BUFFER_HASH_ENTRY ;AN000; mul cx ;AN000; now AX = Size of hash table. les di, ds:[bx.HASH_PTR] ;AN000; save Single buffer address. mov cx, [MemLo] ;AN000; mov word ptr ds:[bx.HASH_PTR], cx ;AN000; set BuffINFO.HASH_PTR mov cx, [MemHi] ;AN000; mov word ptr ds:[bx.HASH_PTR+2], cx ;AN000; mov [Memlo], ax ;AN000; or [SetDevMarkFlag], FOR_DEVMARK ;AN005; call Round ;AN000; get new [memhi]:[memlo] ;Allocate buffers push ds ;AN000; Save Buffer info. ptr. push bx ;AN000; cmp ds:[bx.EMS_MODE], -1 ;AN000; ; $IF NE ;AN000; JE $$IF13 call Set_EMS_Buffer ;AN000; ; $ELSE ;AN000; JMP SHORT $$EN13 $$IF13: call Set_Buffer ;AN000; ; $ENDIF ;AN000; $$EN13: pop bx ;AN000; pop ds ;AN000; ;Now set the secondary buffer if specified. cmp [H_Buffers], 0 ;AN000; ; $IF NE ;AN000; JE $$IF16 call Round ;AN000; mov cx, [MemLo] ;AN000; mov word ptr ds:[bx.CACHE_PTR], cx ;AN000; mov cx, [MemHi] ;AN000; mov word ptr ds:[bx.CACHE_PTR+2], cx ;AN000; mov cx, [H_Buffers] ;AN000; mov ds:[bx.CACHE_COUNT], cx ;AN000; mov ax, 512 ;AN000; 512 byte mul cx ;AN000; mov [Memlo], ax ;AN000; or [SetDevMarkFlag], FOR_DEVMARK ;AN005; call Round ;AN000; ; $ENDIF ;AN000; $$IF16: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;J.K. END OF NEW BUFFER SCHEME. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;DOBUFF: ; INVOKE ROUND ; DEC [BUFFERS] ; FIRST DEC acounts for buffer already ; ; in system. ; JZ BUF1 ; All done ; PUSH DS ; LES DI,BUFPTR ; LDS BX,DOSINFO ; MOV AX,WORD PTR [BX.SYSI_BUF] ; Link in new buffer ; MOV WORD PTR ES:[DI.buf_link],AX ; MOV AX,WORD PTR [BX.SYSI_BUF+2] ; MOV WORD PTR ES:[DI.buf_link+2],AX ; MOV WORD PTR [BX.SYSI_BUF],DI ; MOV WORD PTR [BX.SYSI_BUF+2],ES ; MOV WORD PTR ES:[DI.buf_ID],00FFH ;NEW BUFFER FREE ; mov word ptr es:[di.buf_Sector],0 ;AN000; ; mov word ptr es:[di.buf_Sector+2],0 ;AN000; ; MOV BX,[BX.SYSI_MAXSEC] ; POP DS ; ADD BX,BUFINSIZ ; ADD [MEMLO],BX ; JMP DOBUFF ;------------------------------------------------------------------------------ ; Allocate CDSs ;------------------------------------------------------------------------------ BUF1: INVOKE ROUND push ax ;AN005; mov ax, DEVMARK_CDS ;AN005;='L' call SetDevMark ;AN005; pop ax ;AN005; LES DI,[DOSINFO] MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO] CMP CL,[NUM_CDS] JAE GOTNCDS ; User setting must be at least NUMIO MOV CL,[NUM_CDS] GOTNCDS: XOR CH,CH MOV ES:[DI.SYSI_NCDS],CL MOV AX,[MEMHI] MOV WORD PTR ES:[DI.SYSI_CDS + 2],AX MOV AX,[MEMLO] MOV WORD PTR ES:[DI.SYSI_CDS],AX MOV AL,CL MOV AH,SIZE curdir_list MUL AH call ParaRound ADD [MEMHI],AX or [SetDevMarkFlag], FOR_DEVMARK ;AN005; INVOKE ROUND ; Check for mem error before initializing LDS SI,ES:[DI.SYSI_DPB] ASSUME DS:NOTHING LES DI,ES:[DI.SYSI_CDS] CALL FOOSET ;------------------------------------------------------------------------------ ; Allocate Space for Internal Stack ;------------------------------------------------------------------------------ IF STACKSW PUSH CS POP DS ASSUME DS:SYSINITSEG IF IBM ;Don't install the system stack on the PCjr. Ignore STACKS=command too. CMP [Sys_Model_Byte], 0FDh ; PCjr = 0FDh JE SkipStack_brdg ENDIF ;J.K. 10/15/86 DCR00013 ;If the use does not entered STACKS= command, as a default, do not install ;sytem stacks for PC1, PC XT, PC Portable cases. ;Otherwise, install it to the user specified value or to the default ;value of 9, 128 for the rest of the system. cmp word ptr [stack_addr], -1 ;Has the user entered "stacks=" command? je DoInstallStack ;Then install as specified by the user cmp [Sys_Scnd_Model_Byte], 0 ;PC1, XT has the secondary model byte = 0 jne DoInstallStack ;Other model should have default stack of 9, 128 cmp [Sys_Model_Byte], 0FFh ;PC1 ? je SkipStack_brdg cmp [Sys_Model_Byte], 0FEh ;PC/XT or PC Portable ? jne DoInstallStack SkipStack_Brdg: jmp SkipStack DoInstallStack: mov ax, [stack_count] ;J.K. Stack_count = 0? cmp ax, 0 ;then, stack size must be 0 too. jz SkipStack_brdg ;Don't install stack. ;J.K. 10/21/86 Dynamic Relocation of Stack code. call Round ;[memhi] = Seg. for stack code ;[memlo] = 0 ;J.K. Set DEVMARK block into memory for MEM command ;J.K. DEVMARK_ID = 'S' for stack mov al, DEVMARK_STK ;AN005;='S' call SetDevMark mov ax, [memhi] mov es, ax ;ES -> Seg. the stack code is going to move. assume es:nothing push cs pop ds xor si,si ;!!We know that Stack code is at the beginning of SYSINIT. xor di,di mov cx, offset Endstackcode mov [memlo],cx call Round ;Have enough space for relocation? rep movsb mov ax, [memlo] mov word ptr [stack_addr],ax ;set for stack area initialization mov ax, [memhi] ;This will be used by Stack_Init routine. mov word ptr [stack_addr+2],ax ; Space for Internal Stack area = STACK_COUNT(ENTRYSIZE + STACK_SIZE) MOV AX, EntrySize ADD AX, [STACK_SIZE] MOV CX, [STACK_COUNT] MUL CX call ParaRound ; Convert size to pargraphs ADD [MEMHI], AX or [SetDevMarkFlag], FOR_DEVMARK ;AN005;To set the DEVMARK_SIZE for Stack by ROUND routine. INVOKE ROUND ; Check for memory error before ; continuing CALL StackInit ; Initialize hardware stack. CS=DS=sysinitseg, ES=Relocated stack code & data SkipStack: ENDIF PUSH CS POP DS ASSUME DS:SYSINITSEG MOV AL,[FILES] XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!! ; IT DOES SIGN EXTEND. MOV CX,AX XOR BX,BX ;Close standard input MOV AH,CLOSE INT 21H MOV BX,2 RCCLLOOP: ;Close everybody but standard output MOV AH,CLOSE ; Need output so we can print message INT 21H ; in case we can't get new one open. INC BX LOOP RCCLLOOP MOV DX,OFFSET CONDEV MOV AL,2 MOV AH,OPEN ;OPEN CON FOR READ/WRITE STC ; Set for possible INT 24 INT 21H JNC GOAUX INVOKE BADFIL JMP SHORT GOAUX2 GOAUX: PUSH AX MOV BX,1 ;close standard output MOV AH,CLOSE INT 21H POP AX MOV BX,AX ;New device handle MOV AH,XDUP INT 21H ;Dup to 1, STDOUT MOV AH,XDUP INT 21H ;Dup to 2, STDERR GOAUX2: MOV DX,OFFSET AUXDEV MOV AL,2 ;READ/WRITE ACCESS INVOKE OPEN_DEV MOV DX,OFFSET PRNDEV MOV AL,1 ;WRITE ONLY INVOKE OPEN_DEV ;J.K.9/29/86 ******************* ;Global Rearm command for Shared Interrupt devices attached in the system; ;Shared interrupt attachment has some problem when it issues interrupt ;during a warm reboot. Once the interrupt is presented by the attachment, ;no further interrupts on that level will be presented until a global rearm ;is issued. By the request of the system architecture group, IBMBIO will ;issue a global rearm after every device driver is loaded. ;To issue a global rearm: ;For PC1, XT, Palace ; OUT 02F2h, XX ; Interrupt level 2 ; OUT 02F3h, XX ; Interrupt level 3 ; OUT 02F4h, XX ; Interrupt level 4 ; OUT 02F5h, XX ; Interrupt level 5 ; OUT 02F6h, XX ; Interrupt level 6 ; OUT 02F7h, XX ; Interrupt level 7 ; ; ;For PC AT, in addition to the above commands, ; ;need to handle the secondary interrupt handler ; OUT 06F2h, XX ; Interrupt level 10 ; OUT 06F3h, XX ; Interrupt level 11 ; OUT 06F4h, XX ; Interrupt level 12 ; OUT 06F6h, XX ; Interrupt level 14 ; OUT 06F7h, XX ; Interrupt level 15 ; ; ;For Round-Up machine ; None. ; where XX stands for any value. ; For your information, after Naples level machine, the system service bios ; call (INT 15h), function AH=0C0h returns the system configuration parameters ; cmp [sys_model_byte], 0FDh ;PCjr? ; je GoCheckInstall je Set_Sysinit_Base ;SB33045******************************************************************* push ax ;Save Regs ;SB ;3.30* push bx ; * ;SB ;3.30* push dx ; * ;SB ;3.30* push es ; * ;SB ;3.30* mov al,0ffh ;Reset h/w by writing to port ;SB ;3.30* mov dx,2f2h ;Get starting address ;SB ;3.30* out dx,al ; out 02f2h,0ffh inc dx out dx,al ; out 02f3h,0ffh inc dx out dx,al ; out 02f4h,0ffh inc dx out dx,al ; out 02f5h,0ffh inc dx out dx,al ; out 02f6h,0ffh inc dx out dx,al ; out 02f7h,0ffh ;SB33045******************************************************************* ;SB33046******************************************************************* ;SB Secondary global rearm ;3.30 mov ax,0f000h ;Get machine type ;SB ;3.30* mov es,ax ; * ;SB ;3.30* cmp byte ptr es:[0fffeh],0fch ;Q:Is it a AT type machine ;SB ;3.30* je startrearm ; *if AT no need to check mov ah,0c0h ;Get system configuration ;SB ;3.30* int 15h ; * ;SB ;3.30* jc finishrearm ; *jmp if old rom ;SB ;3.30* ; ;SB ;3.30* ; Test feature byte for secondary interrupt controller ;SB ;3.30* ; ;SB ;3.30* test es:[bx.bios_SD_featurebyte1],ScndIntController ; ;SB ;3.30* je finishrearm ;Jmp if it is there ;SB ;3.30* startrearm: mov al,0ffh ;Write any pattern to port ;SB ;3.30* mov dx,6f2h ;Get starting address ;SB ;3.30* out dx,al ;out 06f2h,0ffh inc dx ;Bump address ;SB ;3.30* out dx,al ;out 06f3h,0ffh inc dx ;Bump address ;SB ;3.30* out dx,al ;out 06f4h,0ffh inc dx ;Bump address ;SB ;3.30* inc dx ;Bump address ;SB ;3.30* out dx,al ;out 06f6h,0ffh inc dx ;Bump address ;SB ;3.30* out dx,al ;out 06f7h,0ffh finishrearm: ; ;SB ;3.30* pop es ;Restore regs ;SB ;3.30* pop dx ; * ;SB ;3.30* pop bx ; * ;SB ;3.30* pop ax ; * ;SB ;3.30* ;SB33046******************************************************************* ;J.K. 9/29/86 Global Rearm end ******************* ;------------------------------------------------------------------------------ ; Allocate SYSINIT_BASE for INSTALL= command ;------------------------------------------------------------------------------ ;J.K. SYSINIT_BASE allocation. ;Check if ENDFILE has been called to handle INSTALL= command. Set_Sysinit_Base: ;GoCheckInstall: ; test [Install_Flag], HAVE_INSTALL_CMD ;AN019;;AN021;install sysinit base all the time. ; jz Skip_SYSINIT_BASE ;AN019; ;J.K.-------------------------------------------------------------------------- ;SYSINIT_BASE will be established in the secure area of ;lower memory when it handles the first INSTALL= command. ;SYSINIT_BASE is the place where the actual EXEC function will be called and ;will check SYSINIT module in high memory if it is damaged by the application ;program. If SYSINIT module has been broken, then "Memory error..." message ;is displayed by SYSINIT_BASE. ;------------------------------------------------------------------------------ push ax ;AN013; Set DEVMARK for MEM command mov ax, [memhi] ;AN013; sub ax, [area] ;AN013; mov [Impossible_owner_size], ax ;AN013;Remember the size in case. mov al, DEVMARK_INST ;AN013; call SetDevMark ;AN013; pop ax ;AN013; mov di, [memhi] ;AN000; mov es, di ;AN000; assume es:nothing ;AN000; mov word ptr [sysinit_base_ptr+2],di ;AN000; save this entry for the next use. xor di, di ;AN000; mov word ptr [sysinit_base_ptr], di ;AN000; es:di -> destination. mov si, offset SYSINIT_BASE ;AN000; ds:si -> source code to be relocated. mov cx, Size_SYSINIT_BASE ;AN000; add [memlo],cx ;AN000; or cs:[SetDevMarkFlag], FOR_DEVMARK ;AN013; call round ;AN000; check mem error. Also, readjust MEMHI for the next use. rep movsb ;AN000; reallocate it. mov word ptr [Sysinit_Ptr], offset SYSINITPTR ;AN000; Returing address from mov word ptr [Sysinit_Ptr+2], cs ;AN000; SYSINIT_BASE back to SYSINIT. or [Install_Flag],HAS_INSTALLED ;AN000; Set the flag. ;------------------------------------------------------------------------------ ; Free the rest of the memory from MEMHI to CONFBOT. Still from CONFBOT to ; the top of the memory will be allocated for SYSINIT and CONFIG.SYS if ; HAVE_INSTALL_CMD. ;------------------------------------------------------------------------------ ;Skip_SYSINIT_BASE: ;AN021; INVOKE ROUND MOV BX,[MEMHI] MOV AX,[AREA] mov [Old_Area], ax ;AN013; Save [AREA] MOV ES,AX ;CALC WHAT WE NEEDED SUB BX,AX MOV AH,SETBLOCK INT 21H ;GIVE THE REST BACK PUSH ES MOV AX,ES DEC AX MOV ES,AX ;Point to arena MOV ES:[arena_owner],8 ;Set impossible owner POP ES mov bx,0ffffh ;AN000; mov ah,Alloc ;AN000; int 21h ;AN000; mov ah,Alloc ;AN000; int 21h ;AN000; Allocate the rest of the memory mov [memhi],ax ;AN000; Start of the allocated memory mov [memlo],0 ;AN000; to be used next. ;;;; At this moment, memory from [MEMHI]:0 to Top-of-the memory is ;;;; allocated. ;;;; To protect sysinit, confbot module (From CONFBOT (or =ALLOCLIM at ;;;; this time) to the Top-of-the memory), here we are going to ;;;; 1). "SETBLOCK" from MEMHI to CONFBOT. ;;;; 2). "ALLOC" from CONFBOT to the top of the memory. ;;;; 3). "Free Alloc Memory" from MEMHI to CONFBOT. ;Memory allocation for SYSINIT, CONFBOT module. mov es, ax ;AN000; mov bx, [confbot] ;AN000; sub bx, ax ;AN000; CONFBOT - MEMHI dec bx ;AN000; Make a room for the memory block id. dec bx ;AN000; make sure!!!. mov ah, SETBLOCK ;AN000; int 21h ;AN000; this will free (CONFBOT to top of memory) mov bx, 0ffffh ;AN000; mov ah, ALLOC ;AN000; int 21h ;AN000; mov ah, ALLOC ;AN000; int 21h ;AN000; allocate (CONFBOT to top of memory) mov [area],ax ;AN000; Save Allocated memory segment. ;AN000; Need this to free this area for COMMAND.COM. mov es, [memhi] ;AN000; mov ah, 49h ;AN000; Free Allocated Memory. int 21h ;AN000; Free (Memhi to CONFBOT(=AREA)) ; IF NOEXEC ; MOV BX,0FFFFH ;ALLOCATE THE REST OF MEM FOR COMMAND ; MOV AH,ALLOC ; INT 21H ; MOV AH,ALLOC ; INT 21H ; MOV DS,AX ; ENDIF ; test cs:[Install_Flag],IS_INSTALL ;AN000; ; jnz DO_Install_Exec ;AN000; ENDFILE_Ret: return Do_Install_Exec proc near ;AN000; Now, handles INSTALL= command. push si ;AN000; save SI for config.sys again. ;;;; We are going to call LOAD/EXEC function. ;;;;;Set ES:BX to the parameter block here;;;;;;; ;;;;;Set DS:DX to the ASCIIZ string. Remember that we already has 0 ;;;;;after the filename. So parameter starts after that. If next ;;;;;character is a line feed (i.e. 10), then assume that the 0 ;;;;;we already encountered used to be a carrage return. In this ;;;;;case, let's set the length to 0 which will be followed by ;;;;;carridge return. ;J.K. ES:SI -> command line in CONFIG.SYS. Points to the first non blank ;character after =. push es ;AN000; push ds ;AN000; pop es ;AN000; pop ds ;AN000; es->sysinitseg, ds->confbot seg assume ds:nothing ;AN000; mov dx, si ;AN000; ds:dx->file name,0 in CONFIG.SYS image. ;AN016; UNDO THE EXTENDED ATTRIBUTES HANDLING ; mov ax, OPEN SHL 8 ;AN008; ; int 21h ;AN008; ; jc SysInitPtr ;AN008; ; mov bx, ax ;AN008;handle ; call Get_Ext_Attribute ;AN008;Get the extended attribute. ; cmp al, EA_INSTALLABLE ;AN008; ; je EA_Installable_OK ;AN012; ; stc ;AN012; ; jmp SysInitPtr ;AN012; ;EA_Installable_OK: ;AN012; xor cx,cx ;AN000; cld ;AN000; mov cs:Ldexec_start, ' ' ;AN015; Clear out the parm area mov di, offset Ldexec_parm ;AN000; InstallFilename: ;AN000; skip the file name lodsb ;AN000; al = ds:si; si++ cmp al, 0 ;AN000; je Got_InstallParm ;AN000; jmp InstallFilename ;AN000; Got_InstallParm: ;AN000; copy the parameters to Ldexec_parm lodsb ;AN000; mov es:[di], al ;AN000; cmp al, LF ;AN000;AN028; line feed? je Done_InstallParm ;AN000;AN028; inc cl ;AN000; # of char. in the parm. inc di ;AN000; jmp Got_Installparm ;AN000; Done_Installparm: ;AN000; mov byte ptr cs:[Ldexec_line], cl ;AN000; length of the parm. cmp cl, 0 ;AN015;If no parm, then jne Install_Seg_Set ;AN015; let the parm area mov byte ptr cs:[Ldexec_Start],CR ;AN015; starts with CR. Install_Seg_Set: ;AN015; mov word ptr cs:0, 0 ;AN000; Make a null environment segment mov ax, cs ;AN000; by overlap JMP instruction of SYSINITSEG. mov cs:[INSTEXE.EXEC0_ENVIRON],ax ;AN000; Set the environment seg. mov word ptr cs:[INSTEXE.EXEC0_COM_LINE+2],ax ;AN000; Set the seg. mov word ptr cs:[INSTEXE.EXEC0_5C_FCB+2],ax ;AN000; mov word ptr cs:[INSTEXE.EXEC0_6C_FCB+2],ax ;AN000; call Sum_up ;AN000; mov es:CheckSum, ax ;AN000; save the value of the sum xor ax,ax ;AN000; mov ah, EXEC ;AN000; Load/Exec mov bx, offset INSTEXE ;AN000; ES:BX -> parm block. push es ;AN000; Save es,ds for Load/Exec push ds ;AN000; these registers will be restored in SYSINIT_BASE. jmp cs:dword ptr SYSINIT_BASE_PTR ;AN000; jmp to SYSINIT_BASE to execute ; LOAD/EXEC function and check sum. ;J.K. This is the returning address from SYSINIT_BASE. SYSINITPTR: ;AN000; returning far address from SYSINIT_BASE pop si ;AN000; restore SI for CONFIG.SYS file. push es ;AN000; push ds ;AN000; pop es ;AN000; pop ds ;AN000; now ds - sysinitseg, es - confbot jnc Exec_Exit_Code test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc? jnz Install_Error_Exit ;AN021; Just exit with carry set. push si ;AN000; Error in loading the file for INSTALL=. call BadLoad ;AN000; ES:SI-> path,filename,0. pop si ;AN000; jmp Install_Exit_Ret Exec_Exit_Code: test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc? jnz Install_Exit_Ret ;AN021; Just exit. mov ah, 4dh ;AN017; int 21h ;AN017; cmp ah, 3 ;AN017;Only accept "Stay Resident" prog. je Install_Exit_Ret ;AN017; call Error_Line ;AN017;Inform the user Install_Error_Exit: ;AN021; stc ;AN021; Install_Exit_Ret: ret Do_Install_Exec endp Public ParaRound ParaRound: ADD AX,15 RCR AX,1 SHR AX,1 SHR AX,1 SHR AX,1 return ;------------------------------------------------------------------------------ ;J.K. SYSINIT_BASE module. ;In: After relocation, ; AX = 4B00h - Load and execute the program DOS function. ; DS = CONFBOT. Segment of CONFIG.SYS file image ; ES = Sysinitseg. Segment of SYSINIT module itself. ; DS:DX = pointer to ASCIIZ string of the path,filename to be executed. ; ES:BX = pointer to a parameter block for load. ; SYSSIZE (Byte) - offset vaule of End of SYSINIT module label ; BIGSIZE (word) - # of word from CONFBOT to SYSSIZE. ; CHKSUM (word) - Sum of every byte from CONFBOT to SYSSIZE in a ; word boundary moduler form. ; SYSINIT_PTR (dword ptr) - Return address to SYSINIT module. ;Note: SYSINIT should save necessary registers and when the control is back public Sysinit_Base Sysinit_Base: ;AN000; mov word ptr cs:SYSINIT_BASE_SS, SS ;AN000; save stack mov word ptr cs:SYSINIT_BASE_SP, SP ;AN000; int 21h ;AN000; LOAD/EXEC DOS call. mov SS, word ptr cs:SYSINIT_BASE_SS ;AN000; restore stack mov SP, word ptr cs:SYSINIT_BASE_SP ;AN000; pop ds ;AN000; restore CONFBOT seg pop es ;AN000; restore SYSINITSEG jc SysInit_Base_End ;AN000; LOAD/EXEC function failed. ;At this time, I don't have to worry about ;that SYSINIT module has been broken or not. call Sum_up ;AN000; Otherwise, check if it is good. cmp es:CheckSum, AX ;AN000; je SysInit_Base_End ;AN000; ;Memory broken. Show "Memory allocation error" message and stall. mov ah, 09h ;AN000; push cs ;AN000; pop ds ;AN000; mov dx, Mem_alloc_err_msg ;AN000; int 21h ;AN000; Stall_now: jmp Stall_now ;AN000; SysInit_Base_End: jmp es:Sysinit_Ptr ;AN000; return back to sysinit module Sum_up: ;AN000; ;In: ; ES - SYSINITSEG. ;OUT: AX - Result ;Remark: Since this routine will only check starting from "LocStack" to the end of ; Sysinit segment, the data area, and the current stack area are not ; coverd. In this sense, this check sum routine only gives a minimal ; gaurantee to be safe. ;First sum up CONFBOT seg. push ds ;AN021; mov ax,es:ConfBot ;AN021; mov ds,ax ;AN021; xor si,si ;AN000; xor ax,ax ;AN000; mov cx,es:Config_Size ;AN000; If CONFIG_SIZE has been broken, then this ;whole test better fail. shr cx, 1 ;AN000; make it a word count jz Sum_Sys_Code ;AN025; When CONFIG.SYS file not exist. Sum1: ;AN000; add ax, ds:word ptr [si] ;AN000; inc si ;AN000; inc si ;AN000; loop Sum1 ;AN000; ;Now, sum up SYSINIT module. Sum_Sys_Code: ;AN025; mov si, offset LocStack ;AN000; Starting after the stack. ;AN000; This does not cover the possible STACK code!!! mov cx, offset SYSSIZE ;AN000; SYSSIZE is the label at the end of SYSINIT sub cx, si ;AN000; From After_Checksum to SYSSIZE shr cx, 1 ;AN000; Sum2: ;AN000; add ax, es:word ptr [si] ;AN000; inc si ;AN000; inc si ;AN000; loop Sum2 ;AN000; pop ds ;AN021; ret ;AN000; Sysinit_Base_SS equ $-Sysinit_Base ;AN000; dw ? ;AN000; Sysinit_Base_SP equ $-Sysinit_Base ;AN000; dw ? ;AN000; Mem_Alloc_Err_msg equ $-Sysinit_Base ;AN000; ;include BASEMES.INC ;AN000; Memory allocation error message include MSBIO.CL4 ;AN011; Memory allocation error message End_Sysinit_Base label byte ;AN000; SIZE_SYSINIT_BASE equ $-Sysinit_Base ;AN000; ; ;AN016; Undo the extended attribute handling ; public Get_Ext_Attribute ;Get_Ext_Attribute proc near ;AN008; ;;In: BX - file handle ;;Out: AL = The extended attribute got from the handle. ;; AX destroyed. ;; Carry set when DOS function call fails. ; ; push ds ;AN008; ; push si ;AN008; ; push es ;AN008; ; push di ;AN008; ; push cx ;AN008; ; ; push cs ;AN008; ; pop ds ;AN008; ; push cs ;AN008; ; pop es ;AN008; ; ; mov Ext_Attr_Value, 0ffh ;AN008; Initialize to unrealistic value ; mov ax, 5702h ;AN008;Get extended attribute by handle thru LIST ; mov si, offset EA_QueryList ;AN008; ; mov di, offset Ext_Attr_List ;AN008; ; mov cx, SIZE_EXT_ATTR_LIST ;AN008; ; int 21h ;AN008; ; mov al, Ext_Attr_Value ;AN008; ; pop cx ;AN008; ; pop di ;AN008; ; pop es ;AN008; ; pop si ;AN008; ; pop ds ;AN008; ; ret ;AN008; ;Get_Ext_Attribute endp ;AN008; ;------------------------------------------------------------------------------ DoEMS proc near ;******************************************************************************* ; Function: Called prior to DOBUFF subroutine. Only called when /E option * ; for the buffers= command has been specified. * ; This routine will check if the extended memory is avaiable, * ; and determine what is the page number. We only use physical page * ; 254. if it is there, then this routine will calculate the number * ; of pages needed for buffers and will allocate logical pages in the * ; extended memory and get the page handle of them. * ; * ; Input : * ; Buffers - Number of buffers * ; Buffer_LineNum - Saved line number to be used in case of Error case * ; * ; Output: * ; BuffINFO.EMS_Handle * ; Buffer_Pages = Number of pages for buffer in the extended memory. * ; BuffINFO.EMS_MODE = -1 No extended memory or Non-IBM compatible mode. * ; Buffers = the number will be changed to be a multiple of 30. * ; Carry set if no extended memory exist or if it is not big enough. * ; AX, BX, CX, DX destroyed. * ; * ; Logic: * ; { * ; Get EMS Version (AH=46h); * ; If (EMS not installed or it is not IBM compatible or * ; (Available_pages * 30 < Buffers) then * ; {Show error message "Error in CONFIG.SYS line #"; * ; Set carry; Exit }; * ; else * ; Buffer_Pages = Roundup(BUFFERS/30); /* Round up 30 buffers per page*/ * ; Buffers = Buffer_Pages * 30; /* Set the new number of Buffers*/* ; Allocate Buffer_Pages (AH=43h) and set EMS_Handle; * ; }; * ; * ;******************************************************************************* push es ;AN000; push di ;AN000; save es, di push si ;AN010; push bx ;AN010; xor di,di ;AN004; if vector pointer of mov es, di ;AN004; EMS (INT 67h) is 0,0 mov di, word ptr es:[EMS_INT * 4] ;AN004; then error. mov ax, word ptr es:[EMS_INT * 4 +2] ;AN009; or ax,di ;AN009; ; $IF NZ,AND,LONG ;AN004; JNZ $$XL2 JMP $$IF18 $$XL2: les di, cs:[DosInfo] ;AN000; es:di -> SYSINITVAR les di, es:[di.SYSI_BUF] ;AN000; now, es:di -> BuffInfo mov ah, EMS_STATUS ;AN000; get the status of EMS = 40h int EMS_INT ;AN000; or ah, ah ;AN000; EMS installed? ; $IF Z,AND,LONG ;AN000; JZ $$XL3 JMP $$IF18 $$XL3: mov ah, EMS_VERSION ;AN010;=46h int EMS_INT ;AN010; cmp AL, EMSVERSION ;AN010;40h = 4.0 ; $IF AE,AND,LONG ;AN010; JAE $$XL4 JMP $$IF18 $$XL4: call Check_IBM_PageID ;AN000; IBM (compatible) mode? IF BUFFERFLAG mov ax, cs:[LAST_PAGE] mov es:[di.EMS_LAST_PAGE], ax mov ax, cs:[LAST_PAGE+2] mov es:[di.EMS_LAST_PAGE+2], ax mov ax, cs:[FIRST_PAGE] mov es:[di.EMS_FIRST_PAGE], ax mov ax, cs:[FIRST_PAGE+2] mov es:[di.EMS_FIRST_PAGE+2], ax mov ax, cs:[NPA640] mov es:[di.EMS_NPA640], ax mov es:[di.EMS_SAFE_FLAG], 1 ENDIF ; $IF NC,AND,LONG ;AN000; JNC $$XL5 JMP $$IF18 $$XL5: mov ah, EMAP_STATE ;AN010; Check if the size of mov al, GET_MAP_SIZE ;AN010; the MAP state table mov bx, 1 ;AN010; # of pages int EMS_INT ;AN010; is acceptable. or ah, ah ;AN010; ; $IF Z,AND ;AN010; JNZ $$IF18 cmp al, EMS_MAP_BUFF_SIZE ;AN010; Curretly=12 bytes ; $IF BE,AND ;AN010; JNBE $$IF18 mov ah, EQ_PAGES ;AN000; Get number of unallocated & total pages = 42h int EMS_INT ;AN000; result in BX xor dx, dx ;AN000; mov ax, cs:[Buffers] ;AN000; mov cx, MAXBUFFINBUCKET*MAXBUCKETINPAGE ;AN000; call Roundup ;AN000; find out how many pages are needed. cmp bx, ax ;AN000; AX is the number of pages for [buffers] ; $IF AE,AND ;AN000; JNAE $$IF18 mov cs:[Buffer_Pages], ax ;AN000; mov bx, ax ;AN000; prepare for Get handle call. mul cx ;AN000; mov cs:[Buffers], ax ;AN000; set new [Buffers] for the extended memory. mov ah, E_GET_HANDLE ;AN000; allocate pages = 43h int EMS_INT ;AN000; page handle in DX. or ah, ah ;AN000; ; $IF Z ;AN000; pages allocated. JNZ $$IF18 mov ah, EMS_HANDLE_NAME ;AN010; mov al, SET_HANDLE_NAME ;AN010; push es ;AN010; push di ;AN010; push ds ;AN010; push cs ;AN010; pop ds ;AN010; mov si, offset EMSHandleName ;AN010; int EMS_INT ;AN010; Set the handle name pop ds ;AN010; pop di ;AN010; pop es ;AN010; xor ah,ah ;AN010; mov es:[di.EMS_MODE], ah ;AN000; put 0 in EMS_mode. mov es:[di.EMS_HANDLE], dx ;AN000; save EMS handle mov ax, cs:[IBM_Frame_Seg] ;AN010; mov es:[di.EMS_PAGE_FRAME],ax ;AN010; mov ax, cs:[Real_IBM_Page_Id] ;AN029; mov es:[di.EMS_PAGEFRAME_NUMBER], ax;AN029; mov ax, es ;AN010; mov word ptr cs:[EMS_Ctrl_tab+2],ax ;AN010; mov word ptr cs:[EMS_state_buf+2],ax;AN010; push di ;AN010;save di-> Buffinfo add di, EMS_SEG_CNT ;AN010; mov word ptr cs:[EMS_Ctrl_tab], di ;AN010; pop di ;AN010; add di, EMS_MAP_BUFF ;AN010; mov word ptr cs:[EMS_state_Buf],di ;AN010; clc ;AN000; ; $ELSE ;AN000; JMP SHORT $$EN18 $$IF18: mov ax, cs:[Buffer_LineNum] ;AN000; Show error message. push cs:[LineCount] ;AN017; Save current line count mov cs:[LineCount], ax ;AN000; Now, we can change Linecount call Error_Line ;AN000; since we are through with CONFIG.SYS file. pop cs:[LineCount] ;AN017; Restore line count stc ;AN000; ; $ENDIF $$EN18: pop bx ;AN010; pop si ;AN010; pop di ;AN000; pop es ;AN000; ret ;AN000; DoEMS endp ; Set_Buffer proc near ;******************************************************************************* ;Function: Set buffers in the real memory. * ; For each hash table entry, set the pointer to the * ; corresponding hash bucket. * ; Lastly set the memhi, memlo for the next available free address. * ; ** At the request of IBMDOS, each hash bucket will start at the * ; ** new segment. * ; * ;Input: ds:bx -> BuffInfo. * ; [Memhi]:[MemLo = 0] = available space for the hash bucket. * ; BufferInfo.Hash_Ptr -> Hash table. * ; BufferBuckets = # of buckets to install. * ; SingleBufferSize = Buffer header size + Sector size * ; MaxNumBuff1 = Number of buffers in the first group of buckets * ; MaxNumBuff2 = Number of buffers in the second group of buckets * ; NthBuck = 1st thru Nth bucket are the first group * ; * ;Output: Buffers, hash buckets and Hash table entries established. * ; [Memhi]:[Memlo] = address of the next available free space. * ; * ; { For (every bucket) * ; { Set Hash table entry; * ; Next buffer ptr = buffer size; * ; For (every buffer in the bucket) * ; { Calll Set_Buffer_Info; /*Set link, id... */ * ; IF (last buffer in a bucket) THEN * ; {last buffer's next_ptr -> first buffer; * ; first buffer's prev_ptr -> last buffer; * ; }; * ; Next buffer ptr += buffer size; * ; }; * ; }; * ; MEMHI:MEMLO = Current Buffer_Bucket add + (# of odd * buffer size)* ; }; * ;******************************************************************************* assume ds:nothing ;AN000;to make sure. lds bx, ds:[bx.HASH_PTR] ;AN000;now, ds:bx -> hash table xor dx, dx ;AN026;To be used to count buckets ; $DO ;AN000;For each bucket $$DO21: inc dl ;AN026; Current bucket number mov word ptr ds:[bx.BUFFER_BUCKET],0 ;AN000;Memlo is 0 after ROUND. mov di, [MemHi] ;AN000; mov word ptr ds:[bx.BUFFER_BUCKET+2], di ;AN000;Hash entry set. mov word ptr ds:[bx.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0. mov es, di ;AN000; xor di, di ;AN000;es:di -> hash bucket xor cx, cx ;AN000 xor ax, ax ;AN000 ; $DO ;AN000;For each buffer in the bucket $$DO22: call Set_Buffer_Info ;AN000;Set buf_link, buf_id... inc cx ;AN000;buffer number cmp dl, [NthBuck] ;AN026;Current bucket number > NthBuck? ; $IF BE ;AN026; JNBE $$IF23 cmp cl, [MaxNumBuf1] ;AN026; last buffer of the 1st group? ; $ELSE ;AN026; JMP SHORT $$EN23 $$IF23: cmp cl, [MaxNumBuf2] ;AN026; last buffer of the 2nd group? ; $ENDIF ;AN026; $$EN23: ; $IF E ;AN020;Yes, last buffer JNE $$IF26 mov word ptr es:[di.BUF_NEXT], 0 ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain) mov word ptr es:[BUF_PREV], di ;AN020;the first buffer's prev -> the last buffer ; $ENDIF ;AN020; $$IF26: mov di, ax ;AN000;adjust next buffer position ; $ENDDO E ;AN000;flag set already for testing last buffer. JNE $$DO22 add [Memlo], ax ;AN000;AX is the size of this bucket. or [SetDevMarkFlag], FOR_DEVMARK ;AN005;Update DEVMARK_SIZE call Round ;AN000;memhi:memlo adjusted for the next bucket. add bx, size BUFFER_HASH_ENTRY ;AN000;ds:bx -> next hash entry. dec [BufferBuckets] ;AN000; ; $ENDDO Z ;AN000; JNZ $$DO21 ret ;AN000; Set_Buffer endp ; Set_EMS_Buffer proc near ;******************************************************************************* ;Function: Set buffers in the extended memory. * ; For each hash table entry, set the pointer to the corresponding * ; hash bucket. * ; * ;Input: ds:bx -> BuffInfo. * ; BuffINFO.Hash_Ptr -> Hash table. * ; BuffINFO.EMS_Handle = EMS handle * ; Buffers = tatal # of buffers to install. * ; Multiple of MAXBUFFINBUCKET*MAXBUCKETINPAGE. * ; Buffer_Pages = # of extended memory pages for buffers. * ; BufferBuckets = # of buckets to install. * ; SingleBufferSize = Buffer header size + Sector size. * ; * ;Output: Buffers, hash buckets and Hash table entries established. * ; * ; { For (each page) * ; { Map the page; /*Map the page into Page frame * ; For (each bucket) /*Each page has two buckets */ * ; { * ; Set EMS_Page; * ; Set Buffer_Bucket; * ; Next buffer ptr = buffer size; * ; For (every buffer) /*A bucket has 15 buffers */ * ; { Set Buf_link to Next buffer ptr; * ; Set Buffer_ID to free; * ; If (last buffer in this bucket) THEN * ; {Buf_link = -1; * ; Next buffer ptr = 0; * ; }; * ; Next buffer ptr += buffer size; * ; }; * ; }; * ; }; * ; }; * ;******************************************************************************* assume ds:nothing ;AN000;to make sure. IF BUFFERFLAG push ax mov ax, offset ems_save_buf mov word ptr cs:[ems_state_buf], ax push cs pop word ptr cs:[ems_state_buf+2] pop ax ENDIF call Save_MAP_State ;AN010; mov dx, es:[bx.EMS_Handle] ;AN000;save EMS_Handle lds si, ds:[bx.HASH_PTR] ;AN000;now ds:si -> Hash table xor bx, bx ;AN000;starting logical page number. ; $DO ;AN000;For each page, $$DO30: call Map_Page ;AN000;map it to IBM physical page 254. mov di, cs:IBM_Frame_Seg ;AN000; mov es, di ;AN000 xor di, di ;AN000;es:di -> bucket xor ax, ax ;AN000 xor cx, cx ;AN000 ; $DO ;AN000;For each bucket, $$DO31: mov ds:[si.EMS_PAGE_NUM], bx ;AN000;set the logical page number in Hash table. mov word ptr ds:[si.BUFFER_BUCKET], di ;AN000;set the offset in hash table for this bucket. mov word ptr ds:[si.BUFFER_BUCKET+2], es ;AN000;set the segment value in hash table. mov word ptr ds:[si.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0. push cx ;AN000;save bucket number xor cx, cx ;AN000; ; $DO ;AN000;For each buffer in a bucket, $$DO32: call Set_Buffer_Info ;AN000;AX adjusted for the next buffer. inc cx ;AN000;inc number of buffers in this bucket. cmp cx, 1 ;AN020;The first buffer in the bucket? ; $IF E ;AN020; JNE $$IF33 mov cs:[EMS_Buf_First], di ;AN020;then save the offset value ; $ENDIF ;AN020; $$IF33: cmp cx, MAXBUFFINBUCKET ;AN000; ; $IF E ;AN000 JNE $$IF35 push word ptr cs:[EMS_Buf_First] ;AN020; pop word ptr es:[di.BUF_NEXT] ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain) push di ;AN020;save di push di ;AN020;di-> last buffer mov di, cs:[EMS_Buf_First] ;AN020;es:di-> first buffer pop word ptr es:[di.BUF_PREV] ;AN020;the first buffer's prev -> the last buffer pop di ;AN020;restore di ; $ENDIF ;AN000; $$IF35: mov di, ax ;AN000;advance di to the next buffer position. ; $ENDDO E ;AN000; JNE $$DO32 add si, size BUFFER_HASH_ENTRY ;AN000;ds:si -> next hash table entry pop cx ;AN000;restore bucket number inc cx ;AN000;next bucket cmp cx, MAXBUCKETINPAGE ;AN000;2 buckets per page ; $ENDDO E ;AN000; JNE $$DO31 inc bx ;AN000;increse logical page number cmp bx, cs:[Buffer_Pages] ;AN000;reached the maximum page number? ; $ENDDO E ;AN000; JNE $$DO30 call Restore_MAP_State ;AN010; ret ;AN000; Set_EMS_Buffer endp Set_Buffer_Info proc ;Function: Set buf_link, buf_id, Buf_Sector ;In: ES:DI -> Buffer header to be set. ; AX = DI ;Out: ; Above entries set. push [Buf_Prev_Off] ;AN020; pop es:[di.BUF_PREV] ;AN020; mov Buf_Prev_Off, ax ;AN020; add ax, [SingleBufferSize] ;AN000;adjust ax mov word ptr es:[di.BUF_NEXT], ax ;AN020; mov word ptr es:[di.BUF_ID], 00FFh ;AN000;new buffer free mov word ptr es:[di.BUF_SECTOR], 0 ;AN000;To compensate the MASM 3 bug mov word ptr es:[di.BUF_SECTOR+2],0 ;AN000;To compensate the MASM 3 bug ret ;AN000; Set_Buffer_Info endp Check_IBM_PageID proc near ;Function: check if the physical page 255 exists. (Physical page 255 is only ; one we are intereseted in, and this will be used for BUFFER ; manipulation by IBMBIO, IBMDOS) ;In: nothing ;Out: Carry clear and IBM_Frame_Seg set if it exist. All registers saved. push es ;AN000; push ax ;AN000; push bx ;AN000; push cx ;AN000; push dx ;AN000; push di ;AN010; IF NOT BUFFERFLAG mov ax, 1B00h ;AN029;AN030;AN0 Check EMS int 2fh installed. int 2fh ;AN029; cmp al, 0ffh ;AN029; jne Cp_IBM_Err ;AN029;If not installed, then no IBM page. mov ax, 1B01h ;AN029;AN030;Then ask if IBM page exists. mov di, IBM_PAGE_ID ;AN029;=255 int 2fh ;AN029; or ah, ah ;AN029; jnz Cp_IBM_Err ;AN029;;No IBM Page mov cs:IBM_Frame_Seg, es ;AN029;;Save Physical IBM page frame addr. mov cs:Real_IBM_Page_Id, di ;AN029;;Real page number for it. clc ;AN029; jmp short Cp_ID_Ret ;AN029; ELSE push cs ;AN000; pop es ;AN000; mov ah, GET_PAGE_FRAME ;AN010;=58h mov al, GET_NUM_PAGEFRAME ;AN010;=01h How many page frames? int EMS_INT ;AN010; or ah, ah ;AN010; jnz hkn_err ;AN010; cmp cx, MAX_NUM_PAGEFRAME ;AN010; ja hkn_err ;AN010; cannot handle this big number push cx ;AN010; mov ah, GET_PAGE_FRAME ;AN010; mov al, GET_PAGEFRAME_TAB ;AN010; mov di, offset Frame_info_Buffer ;AN010; int EMS_INT ;AN010; pop cx ;AN010; or ah, ah ;AN010; jnz cp_IBM_Err ;AN010; Cp_IBM_ID: ;AN010; ; mov dx, es:[di] ; mov cs:[FIRST_PAGE], dx ; mov dx, es:[di+2] ; mov cs:[FIRST_PAGE+2], dx xor dx, dx ; int 3 find_page: cmp es:[di], 0a000h ; is current page above 640K jb next ; NO - goto check_last inc dx ; count the no. of pages above 640K cmp dx, 1 jne first_ok mov ax, es:[di] mov cs:[FIRST_PAGE], ax mov ax, es:[di+2] mov cs:[FIRST_PAGE+2], ax first_ok: mov ax, cs:[FIRST_PAGE] cmp ax, es:[di] ; is this page less than the one we have in ; FIRST_PAGE jbe check_last ; NO - goto check_last mov ax, es:[di] ; update FIRST_PAGE with this page segment mov cs:[FIRST_PAGE], ax mov ax, es:[di+2] mov cs:[FIRST_PAGE+2], ax jmp next hkn_err: jmp cp_ibm_err check_last: mov ax, cs:[LAST_PAGE] ; cmp ax, es:[di] ; is this page greater than the one we have in ; LAST_PAGE? ja next ; NO - goto next mov ax, es:[di] ; update LAST_PAGE with this value. mov cs:[LAST_PAGE], ax mov ax, es:[di+2] mov cs:[LAST_PAGE+2], ax next: add di, 4 loop find_page cmp dx, 3 ; there should be at least 3 pages ; above 640K for the buffers to be ; installed. jb Cp_IBM_Err mov ax, cs:[LAST_PAGE] mov cs:IBM_Frame_Seg, ax mov ax, cs:[LAST_PAGE+2] mov cs:Real_IBM_Page_Id, ax mov cs:[NPA640], dx clc jmp short Cp_Id_Ret ENDIF ; cmp word ptr es:[di+2], IBM_PAGE_ID ;AN010; the second word is the id ; je Got_IBM_ID ;AN010; ; add di, 4 ;AN010; advance to the next row (4 bytes) ; loop Cp_IBM_ID ;AN010; Cp_IBM_Err: ;AN010;;AN029; stc ;AN000;;AN029; jmp short Cp_ID_Ret ;AN000;;AN029; ;Got_IBM_ID: ;AN000; ; mov ax, word ptr es:[di] ;AN010;Physical seg. addr. ; mov cs:IBM_Frame_Seg, ax ;AN000; ; clc ;AN000; Cp_ID_Ret: ;AN000; pop di ;AN010; pop dx ;AN000; pop cx ;AN000; pop bx ;AN000; pop ax ;AN000; pop es ;AN000; ret ;AN000; Check_IBM_PageID endp ; Save_Map_State proc ;AN010; ;Function: Save the map state. ;In) ; EMS_Ctrl_Tab = double word pointer to EMS_state control table address ; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address ;Out) Map state saved push ax ;AN010; push ds ;AN010; push si ;AN010; push es ;AN010; push di ;AN010; lds si, cs:EMS_Ctrl_Tab ;AN010; les di, cs:EMS_state_Buf ;AN010; mov ah, EMAP_STATE ;AN010; =4Fh mov al, GET_MAP_STATE ;AN010; =00h int EMS_INT ;AN010; pop di ;AN010; pop es ;AN010; pop si ;AN010; pop ds ;AN010; pop ax ;AN010; ret ;AN010; Save_Map_State endp ; Restore_Map_State proc ;AN010; push ax ;AN010; push ds ;AN010; push si ;AN010; lds si, cs:EMS_state_Buf ;AN010; mov ah, EMAP_STATE ;AN010; mov al, SET_MAP_STATE ;AN010; int EMS_INT ;AN010; pop si ;AN010; pop ds ;AN010; pop ax ;AN010; ret ;AN010; Restore_Map_State endp ; Map_Page proc near ;AN000; ;Function: Map the logical page in BX of handle in DX to the physical page 255 ;In) ; BX = logical page number ; DX = EMS handle ; EMS_Ctrl_Tab = double word pointer to EMS_state control table address ; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address ;Out) Logical page mapped into first phsical page frame. ; AX saved. push ax ;AN000; mov ah, EMAP_L_TO_P ;AN000; mov al, byte ptr cs:Real_IBM_PAGE_ID ;AN029;= 255 int EMS_INT ;AN000; pop ax ;AN000; ret ;AN000; Map_Page endp ;AN000; ; Roundup proc ;In: DX;AX - operand ; CX - divisor ; Important: DX should be less than CX. ;out: AX - Quotient (Rounded up) div cx ;AN000; or dx, dx ;AN000; jz RU_ret ;AN000; inc AX ;AN000; RU_ret: ;AN000; ret ;AN000; Roundup endp ;------------------------------------------------------------------------------ ;J.K. 5/6/86. IBMSTACK initialization routine. IF STACKSW .SALL INCLUDE STKINIT.INC .XALL ENDIF ;------------------------------------------------------------------------------ public SetDevMark SetDevMark proc ;Set the DEVMARK for MEM command. ;In: [MEMHI] - the address to place DEVMARK ; [MEMLO] = 0 ; AL = ID for DEVMARK_ID ;OUT: DEVMARK established. ; the address saved in cs:[DevMark_Addr] ; [MEMHI] increase by 1. push es ;AN005; push cx ;AN005; mov cx, cs:[memhi] ;AN005; mov cs:[DevMark_Addr],cx ;AN005; mov es, cx ;AN005; mov es:[DEVMARK_ID], al ;AN005; inc cx ;AN007; mov es:[DEVMARK_SEG], cx ;AN007; pop cx ;AN005; pop es ;AN005; inc cs:[memhi] ;AN005; ret ;AN005; SetDevMark endp ;******************************************************************************* ;Function: Load SHARE.EXE, if Big_Media_Flag = 1 and SHARE.EXE has not been * ; loaded yet. * ; This routine will use the same path for SHELL= command. * ; If SHELL= command has not been entered, then default to the root * ; directory. * ; If load fails, then issue message "Warning: SHARE.EXE not loaded" * ; * ;Input: Big_Media_Flag, COMMND * ;Output: Share.exe loaded if necessary. * ; * ;******************************************************************************* LoadShare proc near ;AN021; cmp Big_Media_Flag, 1 ;AN021; jne LShare_Ret ;AN021; ;Check if SHARE is already loaded. mov ax, 1000h ;AN021;multShare installation check int 2fh ;AN021; cmp al, 0ffh ;AN021; jz LShare_Ret ;AN021;Share already loaded! ;SHARE not loaded. push cs ;AN021; pop ds ;AN021; push cs ;AN021; pop es ;AN021; mov si, offset COMMND ;AN021; mov di, offset PathString ;AN021; LShare_String: ;AN021; movsb ;AN021; cmp byte ptr [di-1], 0 ;AN021;reached to the end? jne LShare_string ;AN021; mov si, offset PathString ;AN021;SI= start of PathString LShare_Tail: ;AN021; dec di ;AN021; cmp byte ptr [di], "\" ;AN021; je LShare_Got_Tail ;AN021; cmp byte ptr [di], ":" ;AN021; je LShare_Got_Tail ;AN021; cmp di, si ;AN021;No path case (e.g. SHELL=command.com) je LShare_Got_Tail_0 ;AN021; jmp LShare_Tail ;AN021; LShare_Got_Tail: ;AN021;di -> "\" or ":" inc di ;AN021; LShare_Got_Tail_0: ;AN021; mov si, offset LShare ;AN021; LShare_Set_Filename: ;AN021; movsb ;AN021;Tag "SHARE.EXE",0,0Ah to the path. cmp byte ptr [di-1], 0Ah ;AN021;Line feed? jne LShare_Set_Filename ;AN021; ;Now, we got a path,filename with no parameters for SHARE.EXE mov si, offset PathString ;AN021; or Install_Flag, SHARE_INSTALL ;AN021;Signals Do_Install_Exec that this is for SHARE.EXE. call Do_Install_Exec ;AN021;execute it. jnc LShare_Ret ;AN021;No problem ;Load/Exec failed. Show "Warning: SHARE should be loaded for large media" push cs ;AN021; pop ds ;AN021; mov dx, offset ShareWarnMsg ;AN021;WARNING! SHARE should be loaded... invoke Print ;AN021; LShare_Ret: ;AN021; ret ;AN021; LoadShare endp ;AN021; SYSINITSEG ENDS END