From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/BIOS/SYSINIT1.ASM | 2668 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2668 insertions(+) create mode 100644 v4.0/src/BIOS/SYSINIT1.ASM (limited to 'v4.0/src/BIOS/SYSINIT1.ASM') diff --git a/v4.0/src/BIOS/SYSINIT1.ASM b/v4.0/src/BIOS/SYSINIT1.ASM new file mode 100644 index 0000000..7869b76 --- /dev/null +++ b/v4.0/src/BIOS/SYSINIT1.ASM @@ -0,0 +1,2668 @@ + 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 + \ No newline at end of file -- cgit v1.2.3