1 TITLE BIOS SYSTEM INITIALIZATION
8 IBMJAPVER EQU FALSE
; If TRUE set KANJI true also
10 ALTVECT EQU FALSE
; Switch to build ALTVECT version
14 IF IBMVER
OR IBMJAPVER
20 ; Set to agree with those in DOST:MSHEAD.ASM, ALTVECT version only
22 MINOR_VERSION EQU
0B ;2.11
26 ; Internal DOS data returned by DOSINIT
29 DPBHEAD
DD ?
; Pointer to head of DPB-FAT list
30 sft_addr
DD ?
; Pointer to first FCB table
31 ; The following address points to the CLOCK device
33 ; The following address is used by DISKSTATCHK it is always
34 ; points to the console input device header
35 BCON
DD ?
; Console device entry points
36 NUMIO
DB 0 ; Number of disk tables
37 MAXSEC
DW 0 ; Maximum allowed sector size
38 BUFFHEAD
DD ?
; Head of buffer queue
51 SYSINITSEG
SEGMENT PUBLIC 'SYSTEM_INIT'
53 ASSUME
CS:SYSINITSEG
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
55 EXTRN BADOPM
:BYTE,CRLFM
:BYTE,BADCOM
:BYTE
56 EXTRN BADSIZ_PRE
:BYTE,BADLD_PRE
:BYTE
57 EXTRN BADSIZ_POST
:BYTE,BADLD_POST
:BYTE
58 EXTRN SYSSIZE
:BYTE,BADCOUNTRY
:BYTE
60 PUBLIC CURRENT_DOS_LOCATION
61 PUBLIC FINAL_DOS_LOCATION
78 CURRENT_DOS_LOCATION
DW 0000
81 ENTRY_POINT
LABEL DWORD
83 FINAL_DOS_LOCATION
DW 0000
84 DEVICE_LIST
DD 00000000
87 DPBBUF_SIZ
DW (4472 + 15) / 16
94 COMMAND_LINE
DB 2,0,"P" ; Default Command.com Args
99 COMEXE EXEC0
<0,COMMAND_LINE
,DEFAULT_DRIVE
,ZERO
>
105 BUFPTR
LABEL DWORD ; LEAVE THIS STUFF IN ORDER!
114 DB 0 ; INITIALIZE CODE
130 MOV CX,2048 ; START SCANNING AT 32K BOUNDARY
147 IF IBMVER
OR IBMJAPVER
157 SUB CX,(DOSSIZE
/ 16) ; Leave room for DOS
158 SUB CX,CS:[DPBBUF_SIZ
] ; Allow OEM to tune
161 MOV AX,OFFSET SYSSIZE
+ 15
162 SHR AX,1 ; Divide by 16 for paras
168 MOV CX,OFFSET SYSSIZE
+ 1
169 SHR CX,1 ; Divide by 2 to get words
170 REP MOVSW ; RELOCATE SYSINIT
182 ; MOVE THE DOS TO ITS PROPER LOCATION
186 ASSUME
DS:NOTHING
,ES:SYSINITSEG
,SS:NOTHING
188 MOV AX,[CURRENT_DOS_LOCATION
]
190 MOV AX,[FINAL_DOS_LOCATION
]
206 MOV SP,OFFSET LOCSTACK
211 STI ; Leave INTs disabled for ALTVECT
216 MOV WORD PTR [DOSINFO
+2],ES ; SAVE POINTER TO DOS INFO
217 MOV WORD PTR [DOSINFO
],DI
221 CALL RE_INIT
; Re-call the BIOS
237 MOV CX,OFFSET SYSSIZE
+ 1
238 SHR CX,1 ; Divide by 2 to get words
242 MOV AX,OFFSET SECONDRELOC
252 MOV SP,OFFSET LOCSTACK
262 MOV AH,SET_CURRENT_PDB
269 MOV DX,OFFSET INT24
; SET UP INT 24 HANDLER
270 MOV AX,(SET_INTERRUPT_VECTOR
SHL 8) OR 24H
274 MOV DX,OFFSET BOOTMES
275 CALL PRINT
; Print message DOSINIT couldn't
280 MOV DL,[DEFAULT_DRIVE
]
284 MOV AH,SET_DEFAULT_DRIVE
285 INT 21H
; SELECT THE DISK
288 CALL DOCONF
; DO THE CONFIG STUFF
292 MOV AX,OFFSET SYSSIZE
+ 15
294 SHR AX,CL ; Divide by 16 to get para
302 MOV CX,OFFSET SYSSIZE
+ 1
303 SHR CX,1 ; Divide by 2 to get words
307 MOV AX,OFFSET THIRDRELOC
317 MOV SP,OFFSET LOCSTACK
322 MOV BP,DS ; SAVE COMMAND.COM SEGMENT
335 MOV AH,SET_CURRENT_PDB
338 MOV ES:[PDB_PARENT_PID
],ES ; WE ARE THE ROOT
347 XOR BX,BX ; Close standard input
351 RCCLLOOP: ; Close everybody but standard output
359 MOV AH,OPEN
; OPEN CON FOR READ/WRITE
367 MOV BX,1 ; close standard output
372 MOV BX,AX ; New device handle
374 INT 21H
; Dup to 1, STDOUT
376 INT 21H
; Dup to 2, STDERR
378 GOAUX2: MOV DX,OFFSET AUXDEV
379 MOV AL,2 ; READ/WRITE ACCESS
383 MOV AL,1 ; WRITE ONLY
386 ; SET UP THE PARAMETERS FOR COMMAND
389 MOV SI,OFFSET COMMAND_LINE
+1
400 COMTRANLP: ; FIND LENGTH OF COMMAND LINE
403 STOSB ; COPY COMMAND LINE IN
412 MOV AL,[DEFAULT_DRIVE
]
415 MOV [COMMAND_LINE
],CL ; Count
423 MOV DX,OFFSET COMMND
; NOW POINTING TO FILE DESCRIPTION
426 MOV ES,BP ; SET LOAD ADDRESS
428 CALL LDFIL
; READ IN COMMAND
437 XOR AX,AX ; PUSH A WORD OF ZEROS
439 MOV AH,SET_DMA
; SET DISK TRANFER ADDRESS
441 PUSH BP ; SET HIGH PART OF JUMP ADDRESS
443 PUSH AX ; SET LOW PART OF JUMP ADDRESS
445 RET ; CRANK UP COMMAND!
450 MOV WORD PTR [BX.EXEC0_COM_LINE
+2],CS
451 MOV WORD PTR [BX.EXEC0_5C_FCB
+2],CS
452 MOV WORD PTR [BX.EXEC0_6C_FCB
+2],CS
456 STC ; IN CASE OF INT 24
457 INT 21H
; GO START UP COMMAND
461 MOV DX,OFFSET BADCOM
; WANT TO PRINT COMMAND ERROR
473 INT 21H
; FIRST TIME FAILS
475 INT 21H
; SECOND TIME GETS IT
484 MOV AX,(CHAR_OPER
SHL 8) ; GET SWITCH CHARACTER
486 MOV [COMMAND_LINE
+1],DL
488 MOV DX,OFFSET CONFIG
; NOW POINTING TO FILE DESCRIPTION
489 MOV AX,OPEN
SHL 8 ; OPEN FILE "CONFIG.SYS"
490 STC ; IN CASE OF INT 24
491 INT 21H
; FUNCTION REQUEST
493 JMP NOPROB
; PROBLEM WITH OPEN
517 LDS DI,[DOSINFO
] ; GET POINTER TO DOS DATA
518 LDS DI,[DI+SFT_ADDR
] ; DS:BP POINTS TO SFT
519 MOV WORD PTR [DI+SFT_LINK
],BX
520 MOV WORD PTR [DI+SFT_LINK
+2],DX ; SET POINTER TO NEW SFT
523 LES DI,DWORD PTR [MEMLO
] ; POINT TO NEW SFT
524 MOV WORD PTR ES:[DI+SFT_LINK
],-1
525 MOV ES:[DI+SFT_COUNT
],AX
527 MUL BL ; AX = NUMBER OF BYTES TO CLEAR
533 ADD [MEMLO
],AX ; ALLOCATE MEMORY
535 ADD [MEMLO
],AX ; REMEMBER THE HEADER TOO
540 REP STOSB ; CLEAN OUT THE STUFF
560 MOV AX,WORD PTR [BX.BUFFHEAD
]
561 MOV WORD PTR ES:[DI.NEXTBUF
],AX
562 MOV AX,WORD PTR [BX.BUFFHEAD
+2]
563 MOV WORD PTR ES:[DI.NEXTBUF
+2],AX
565 MOV WORD PTR [BX.BUFFHEAD
],DI
566 MOV WORD PTR [BX.BUFFHEAD
+2],ES
568 MOV WORD PTR ES:[DI.BUFDRV
],00FFH ; NEW BUFFER FREE
582 MOV ES,AX ; CALC WHAT WE NEEDED
591 INT 21H
; GIVE THE REST BACK
598 MOV ES:[arena_owner
],8 ; Set impossible owner
612 MOV ES:[arena_owner
],8 ; Set impossible owner
628 MOV BX,0FFFFH ; ALLOCATE THE REST OF MEM FOR COMMAND
639 BADOP: MOV DX,OFFSET BADOPM
; WANT TO PRINT COMMAND ERROR
643 NOPROB: ; GET FILE SIZE (NOTE < 64K!!)
647 MOV AX,(LSEEK
SHL 8) OR 2
651 MOV AX,LSEEK
SHL 8 ; Reset pointer to beginning of file
656 MOV AX,OFFSET SYSSIZE
+ 15
664 SHR AX,CL ; NUMBER OF SEGMENTS
666 SUB DX,11H
; ROOM FOR HEADER
671 ASSUME
DS:NOTHING
,ES:NOTHING
675 STC ; IN CASE OF INT 24
676 INT 21H
; Function request
686 JC CONFERR
; IF NOT WE'VE GOT A PROBLEM
688 JZ GETCOM
; COULDN'T READ THE FILE
690 MOV DX,OFFSET CONFIG
; WANT TO PRINT CONFIG ERROR
695 CALL ORGANIZE
; ORGANIZE THE FILE
702 CMP AH,'B' ; BUFFER COMMAND?
715 CMP AL,'O' ; FIRST LETTER OF "ON"
719 CMP AL,'N' ; SECOND LETTER OF "ON"
721 MOV AH,SET_CTRL_C_TRAPPING
; TURN ON CONTROL-C CHECK
737 MOV WORD PTR [BPB_ADDR
],SI
738 MOV WORD PTR [BPB_ADDR
+2],ES
748 STC ; In case INT 24H
755 MOV AX,(LSEEK
SHL 8) OR 2
760 POP AX ; DX:AX is size of file
767 OR AX,DX ; AX is size in PARA
771 MOV [MEMHI
],CX ; Not enough memory
778 MOV WORD PTR [ENTRY_POINT
],AX
780 MOV WORD PTR [ENTRY_POINT
+2],AX ; SET ENTRY POINT
784 MOV [LDOFF
],AX ; SET LOAD OFFSET
789 MOV DX,SI ; DS:DX POINTS TO FILE NAME
792 LES BX,DWORD PTR CS:[MEMLO
]
793 CALL LDFIL
; LOAD IN THE DEVICE DRIVER
796 MOV BX,OFFSET PRMBLK
; ES:BX POINTS TO PARAMETERS
799 STC ; IN CASE OF INT 24
800 INT 21H
; LOAD IN THE DEVICE DRIVER
804 POP ES ; ES:SI BACK TO CONFIG.SYS
806 POP DS ; DS BACK TO SYSINIT
811 GOODLD: PUSH ES ; INITIALIZE THE DEVICE
825 MOV AX,WORD PTR [BREAK_ADDR
+2] ; REMOVE THE INIT CODE
834 MOV AX,WORD PTR [BREAK_ADDR
]; REMOVE THE INIT CODE
838 LDS DX,[ENTRY_POINT
] ; SET DS:DX TO HEADER
840 ADD SI,SDEVATT
; DS:SI POINTS TO ATTRIBUTES
841 LES DI,CS:[DOSINFO
] ; ES:DI POINT TO DOS INFO
842 MOV AX,DS:[SI] ; GET ATTRIBUTES
843 TEST AX,DEVTYP
; TEST IF BLOCK DEV
846 TEST AX,ISCIN
; IS IT A CONSOLE IN?
848 MOV WORD PTR ES:[DI.BCON
],DX
849 MOV WORD PTR ES:[DI.BCON
+2],DS
851 TRYCLK: TEST AX,ISCLOCK
; IS IT A CLOCK DEVICE?
853 MOV WORD PTR ES:[DI+BCLOCK
],DX
854 MOV WORD PTR ES:[DI+BCLOCK
+2],DS
858 MOV AL,CS:[UNITCOUNT
] ; IF NO UNITS FOUND....
863 MOV CS:[MEMLO
],0 ; ...ERASE THE DEVICE
873 MOV DL,ES:[DI.NUMIO
] ; GET NUMBER OF DEVICES
874 ADD ES:[DI.NUMIO
],AL ; UPDATE THE AMOUNT
876 LDS BX,CS:[BPB_ADDR
] ; POINT TO BPB ARRAY
879 LES BP,DWORD PTR ES:[BP.DPBHEAD
]; GET FIRST DPB
881 SCANDPB:CMP WORD PTR ES:[BP.DPB_NEXT_DPB
],-1
883 LES BP,ES:[BP.DPB_NEXT_DPB
]
887 MOV WORD PTR ES:[BP.DPB_NEXT_DPB
],AX
890 MOV AX,(DPBSIZ
+ 15) / 16
895 MOV WORD PTR ES:[BP.DPB_NEXT_DPB
+2],AX
896 LES BP,DWORD PTR CS:[MEMLO
]
899 ADD WORD PTR CS:[MEMLO
],DPBSIZ
902 MOV WORD PTR ES:[BP.DPB_NEXT_DPB
],-1
903 MOV ES:[BP.DPB_FIRST_ACCESS
],-1
905 MOV SI,[BX] ; DS:SI POINTS TO BPB
907 INC BX ; POINT TO NEXT GUY
908 MOV WORD PTR ES:[BP.DPB_DRIVE
],DX
909 MOV AH,SETDPB
; HIDDEN SYSTEM CALL
911 MOV AX,ES:[BP.DPB_SECTOR_SIZE
]
913 LES DI,CS:[DOSINFO
] ; ES:DI POINT TO DOS INFO
914 CMP AX,ES:[DI.MAXSEC
]
919 MOV DX,OFFSET BADSIZ_PRE
920 MOV BX,OFFSET BADSIZ_POST
926 LDS DX,CS:[ENTRY_POINT
]
927 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR
],DX
928 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR
+2],DS
936 LES DI,CS:[DOSINFO
] ; ES:DI = DOS TABLE
937 MOV CX,WORD PTR ES:[DI.DEVHEAD
] ; DX:CX = HEAD OF LIST
938 MOV DX,WORD PTR ES:[DI.DEVHEAD
+2]
940 LDS SI,CS:[ENTRY_POINT
] ; DS:SI = DEVICE LOCATION
941 MOV WORD PTR ES:[DI.DEVHEAD
],SI ; SET HEAD OF LIST IN DOS
942 MOV WORD PTR ES:[DI.DEVHEAD
+2],DS
943 MOV AX,DS:[SI] ; GET POINTER TO NEXT DEVICE
944 MOV WORD PTR CS:[ENTRY_POINT
],AX; AND SAVE IT
946 MOV WORD PTR DS:[SI],CX ; LINK IN THE DRIVER
947 MOV WORD PTR DS:[SI+2],DX
953 JMP GOODLD
; OTHERWISE PRETEND WE LOADED IT IN
963 MOV AH,INTERNATIONAL
; AL is country code
964 MOV DX,-1 ; Set country
967 MOV DX,OFFSET BADCOUNTRY
984 MOV AX,(CHAR_OPER
SHL 8) OR 1 ; SET SWITCH CHARACTER
985 MOV [COMMAND_LINE
+1],DL
992 CMP AL,'F' ; FIRST LETTER OF "FALSE"
994 MOV AX,(CHAR_OPER
SHL 8) OR 3 ; TURN ON "/DEV" PREFIX
1002 MOV [COMMAND_LINE
+1],0
1003 MOV DI,OFFSET COMMND
+ 1
1028 MOV DI,OFFSET COMMAND_LINE
+1
1037 GETCHR: MOV CX,COUNT
1055 ORG1: CALL GET
; SKIP LEADING CONTROL CHARACTERS
1064 MOV SI,OFFSET COMTAB
; Prepare to search command table
1073 ADD SI,CX ; Bump to next position without affecting flags
1075 LODSB ; Get indicator letter
1087 GOTCOM: STOSB ; SAVE INDICATOR CHAR IN BUFFER
1089 ORG2: CALL GET2
; SKIP NAME UNTIL DELIMETER
1093 CALL GET
; GET CHARS TO RIGHT OF EQUALS SIGN
1103 MOV BYTE PTR ES:[DI-1],0
1144 ; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE
1146 NEWLINE:CALL GETCHR
; SKIP NON-CONTROL CHARACTERS
1148 CMP AL,10 ; LOOK FOR LINE FEED
1166 INC SI ; Skip next char
1168 JCXZ CONVDONE
; Just ignore 1/2 kanji error
1169 ; Fall through, know AL is not in 'a'-'z' range
1199 XOR AX,AX ; Set zero
1205 XOR AX,AX ; Set zero
1213 ROUND: MOV AX,[MEMLO
]
1228 CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT
+2]
1229 ADD BX,WORD PTR CS:[ENTRY_POINT
]; Do a little relocation
1231 PUSH WORD PTR CS:[ENTRY_POINT
]
1232 MOV WORD PTR CS:[ENTRY_POINT
],AX
1233 MOV BX,OFFSET PACKET
1235 POP WORD PTR CS:[ENTRY_POINT
]
1238 BADNUM: POP AX ; POP RETURN ADDRESS
1251 GETNUM: XOR BX,BX ; running count is zero
1252 B2: CALL ToDigit
; do we have a digit
1253 JC BadNum
; no, bomb
1254 XCHG AX,BX ; put total in AX
1255 PUSH BX ; save digit
1256 MOV BX,10 ; base of arithmetic
1257 MUL BX ; shift by one decimal digit
1258 POP BX ; get back digit
1259 ADD AL,BL ; get total
1260 ADC AH,0 ; make that 16 bits
1261 JC BADNUM
; too big a number
1262 XCHG AX,BX ; stash total
1263 CALL GETCHR
; GET NEXT DIGIT
1264 JC B1
; no more characters
1265 OR AL,AL ; end of line separator?
1266 JNZ B2
; no, try as a valid character
1267 INC COUNT
; one more character to scan
1268 DEC CHRPTR
; back up over separator
1269 B1: MOV AX,BX ; get proper count
1273 ; ES:SI POINTS TO FILE NAME (NUL TERMINATED)
1274 ; DS:DX POINTS TO STRING TO OUTPUT IN FRONT OF NAME ($ TERM)
1281 MOV DX,OFFSET BADLD_PRE
; WANT TO PRINT CONFIG ERROR
1282 MOV BX,OFFSET BADLD_POST
1286 MOV AH,STD_CON_STRING_OUTPUT
1288 PRN1: MOV DL,ES:[SI]
1291 MOV AH,STD_CON_OUTPUT
1296 PRINT: MOV AH,STD_CON_STRING_OUTPUT
1300 ; LOAD FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX
1311 XOR AX,AX ; OPEN THE FILE
1313 STC ; IN CASE OF INT 24
1315 POP DX ; Trans addr is DS:DX
1318 PUSH ES ; READ THE FILE IN
1320 MOV BX,AX ; Handle in BX
1323 STC ; IN CASE OF INT 24
1326 MOV SI,DX ; CHECK FOR EXE FILE
1327 CMP WORD PTR [SI],"ZM"
1332 LDCLS: MOV AH,CLOSE
; CLOSE THE FILE
1344 ; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE
1345 ; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD
1351 MOV DX,OFFSET NULDEV
1356 XOR AX,AX ; GET DEVICE INFO
1371 INT24: ADD SP,6 ; RESTORE MACHINE STATE
1382 MOV AH,GET_DEFAULT_DRIVE
; INITIALIZE DOS
1390 DB "MS-DOS version "
1391 DB MAJOR_VERSION
+ "0"
1393 DB (MINOR_VERSION
/ 10) + "0"
1394 DB (MINOR_VERSION
MOD 10) + "0"
1396 DB "Copyright 1981,82 Microsoft Corp.",13,10,"$"
1399 NULDEV
DB "\DEV\NUL",0
1400 CONDEV
DB "\DEV\CON",0
1401 AUXDEV
DB "\DEV\AUX",0
1402 PRNDEV
DB "\DEV\PRN",0
1404 CONFIG
DB "\CONFIG.SYS",0
1406 COMMND
DB "\COMMAND.COM",0