]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/BOOT/MSBOOT.ASM
1 Page
60,132 ;\ f SCCSID = @(#)msboot.asm 1.1 85/05/13
2 TITLE BOOT SECTOR
1 OF TRACK
0 - BOOT LOADER
4 ; Rev 1.0 ChrisP, AaronR and others. 2.0 format boot
6 ; Rev 3.0 MarkZ PC/AT enhancements
8 ; Rev 3.1 MarkZ 3.1 in label due to vagaries of SYSing to IBM drive D's
9 ; This resulted in the BPB being off by 1. So we now trust
10 ; 2.0 and 3.1 boot sectors and disbelieve 3.0.
12 ; Rev 3.2 LeeAc Modify layout of extended BPB for >32M support
13 ; Move PHYDRV to 3rd byte from end of sector
14 ; so that it won't have to be moved again
15 ; FORMAT and SYS count on PHYDRV being in a known location
17 ; Rev. 3.3 D.C. L. Changed Sec 9 EOT field from 15 to 18. May 29, 1986.
19 ; Rev 3.31 MarkT The COUNT value has a bogus check (JBE????) to determine
20 ; if we've loaded in all the sectors of IBMBIO. This will
21 ; cause too big of a load if the sectors per track is high
22 ; enough, causing either a stack overflow or the boot code
25 ; Rev 4.00 J. K. For DOS 4.00 Modified to handle the extended BPB, and
26 ; 32 bit sector number calculation to enable the primary
27 ; partition be started beyond 32 MB boundary.
30 ; The ROM in the IBM PC starts the boot process by performing a hardware
31 ; initialization and a verification of all external devices. If all goes
32 ; well, it will then load from the boot drive the sector from track 0, head 0,
33 ; sector 1. This sector is placed at physical address 07C00h. The initial
34 ; registers are set up as follows: CS=DS=ES=SS=0. IP=7C00h, SP=0400H.
36 ; The code in this sector is responsible for locating the MSDOS device drivers
37 ; (IBMBIO) and for placing the directory sector with this information at
38 ; physical address 00500h. After loading in this sector, it reads in the
39 ; entirety of the BIOS at BIOSEG:0 and does a long jump to that point.
41 ; If no BIOS/DOS pair is found an error message is displayed and the user is
42 ; prompted to reinsert another disk. If there is a disk error during the
43 ; process, a message is displayed and things are halted.
45 ; At the beginning of the boot sector, there is a table which describes the
46 ; MSDOS structure of the media. This is equivalent to the BPB with some
47 ; additional information describing the physical layout of the driver (heads,
50 ;==============================================================================
52 ;AN000 - New for DOS Version 4.00 - J.K.
53 ;AC000 - Changed for DOS Version 4.00 - J.K.
54 ;AN00x - PTM number for DOS Version 4.00 - J.K.
55 ;==============================================================================
56 ;AN001; d52 Make the fixed positioned variable "CURHD" to be local. 7/6/87 J.K.
57 ;AN002; d48 Change head settle at boot time. 7/7/87 J.K.
58 ;AN003; P1820 New message SKL file 10/20/87 J.K.
59 ;AN004; D304 New structrue of Boot record for OS2. 11/09/87 J.K.
60 ;==============================================================================
62 ORIGIN EQU 7C00H
; Origin of bootstrap LOADER
63 BIOSEG EQU 70H
; destingation segment of BIOS
64 BioOff EQU 700H
; offset of bios
68 IBMLOADSIZE equ
3 ;J.K. Size of IBMLOAD module in sectors
73 ; Define the destination segment of the BIOS, including the initialization
76 SEGBIOS
SEGMENT AT BIOSEG
81 ASSUME
CS:CODE,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
88 DSKADR
= 1EH
*4 ;POINTER TO DRIVE PARAMETERS
93 ;----------------------------------------------------------
95 ; THE FOLLOWING DATA CONFIGURES THE BOOT PROGRAM
96 ; FOR ANY TYPE OF DRIVE OR HARDFILE
106 ByteSec
DW cbSec
; SIZE OF A PHYSICAL SECTOR
107 DB 8 ; SECTORS PER ALLOCATION UNIT
108 cSecRes
DW 1 ; NUMBER OF RESERVED SECTORS
109 cFat
DB 2 ; NUMBER OF FATS
110 DirNum
DW 512 ; NUMBER OF DIREC ENTRIES
111 cTotSec
DW 4*17*305-1 ; NUMBER OF SECTORS - NUMBER OF HIDDEN SECTORS
112 ; (0 when 32 bit sector number)
113 MEDIA
DB 0F8H ; MEDIA BYTE
114 cSecFat
DW 8 ; NUMBER OF FAT SECTORS
115 SECLIM
DW 17 ; SECTORS PER TRACK
116 HDLIM
DW 4 ; NUMBER OF SURFACES
117 Ext_cSecHid
label dword
118 cSecHid_L
DW 1 ;AN000; NUMBER OF HIDDEN SECTORS
119 cSecHid_H dw 0 ;AN000; high order word of Hiden Sectors
120 Ext_cTotSec
label dword
121 ctotsec_L dw 0 ;AN000; 32 bit version of NUMBER OF SECTORS
122 ctotsec_H dw 0 ;AN000; (when 16 bit version is zero)
124 Phydrv db 80h
;AN004;
125 Curhd db 0h
;AN004; Current Head
126 Ext_Boot_Sig db 41 ;AN000;
127 Boot_Serial dd 0 ;AN000;
128 Boot_Vol_Label db 'NO NAME ' ;AN000;
129 Boot_System_id db 'FAT12 ' ;AN000;
131 ;J.K. Danger!!! If not 32 bit sector number calculation, FORMAT should
132 ;set the value of cSecHid_h and Ext_cTotSec to 0 !!!
138 Sec9 equ
byte ptr UDATA
+0 ;11 byte diskette parm. table
139 BIOS$_L EQU
WORD PTR UDATA
+11
140 BIOS$_H equ
word ptr UDATA
+13 ;AN000;
141 CURTRK EQU
WORD PTR UDATA
+15
142 CURSEC EQU
BYTE PTR UDATA
+17
143 DIR$_L EQU
WORD PTR UDATA
+18
144 Dir$_H equ
word ptr UDATA
+20 ;AN000;
148 ; First thing is to reset the stack to a better and more known place. The ROM
149 ; may change, but we'd like to get the stack in the correct place.
151 CLI ;Stop interrupts till stack ok
153 MOV SS,AX ;Work in stack just below this routine
160 ; We copy the disk parameter table into a local area. We scan the table above
161 ; for non-zero parameters. Any we see get changed to their non-zero values.
163 ;J.K. We copy the disk parameter table into a local area (overlayed into the
164 ;code), and set the head settle time to 1, and End of Track to SECLIM given
168 LDS SI,DWORD PTR SS:[BX] ; get address of disk table
169 PUSH DS ; save original vector for possible
177 %
OUT Don
't destroy unexcuted
code yet!!!
181 pop ds ;AN000; DS = ES = code = 0.
182 assume
ds:code ;AN000;
183 ; mov byte ptr [di-2], 1 ;AN000; Head settle time
184 ;J.K. Change the head settle to 15 ms will slow the boot time quite a bit!!!
185 mov byte ptr [di-2], 0fh ;AN002; Head settle time
186 mov cx, SECLIM
;AN004;
187 mov byte ptr [di-7], cl ;AN000; End of Track
189 ; Place in new disk parameter table vector.
194 ; We may now turn interrupts back on. Before this, there is a small window
195 ; when a reboot command may come in when the disk parameter table is garbage
197 STI ;Interrupts OK now
199 ; Reset the disk system just in case any thing funny has happened.
201 INT 13H
;Reset the system
205 ; The system is now prepared for us to begin reading. First, determine
206 ; logical sector numbers of the start of the directory and the start of the
210 cmp cTotSec
,ax ;AN000; 32 bit calculation?
212 mov cx,cTotSec
;AN000;
213 mov cTotSec_L
,cx ;AN000; cTotSec_L,cTotSec_H will be used for calculation
215 MOV AL,cFat
;Determine sector dir starts on
218 adc DX,cSecHid_H
;AN000;
221 MOV [DIR$_L
],AX ; DX;AX = cFat*cSecFat + cSecRes + cSecHid
222 mov [DIR$_H
],DX ;AN000;
224 mov [BIOS$_H
],DX ;AN000;
226 ; Take into account size of directory (only know number of directory entries)
228 MOV AX,cbDirEnt
; bytes per directory entry
229 MUL DirNum
; convert to bytes in directory
230 MOV BX,ByteSec
; add in sector size
232 DEC AX ; decrement so that we round up
233 DIV BX ; convert to sector number
234 ADD [BIOS$_L
],AX ; Start sector # of Data area
235 adc [BIOS$_H
],0 ;AN000;
238 ; We load in the first directory sector and examine it to make sure the the
239 ; BIOS and DOS are the first two directory entries. If they are not found,
240 ; the user is prompted to insert a new disk. The directory sector is loaded
243 MOV BX,DirOff
; sector to go in at 00500h
244 mov dx,[DIR$_H
] ;AN000;
245 MOV AX,[DIR$_L
] ; logical sector of directory
246 CALL DODIV
; convert to sector, track, head
247 jc CKErr
;AN000; Overflow? BPB must be wrong!!
248 ; MOV AX,0201H ; disk read 1 sector
249 mov al, 1 ;AN000; disk read 1 sector
250 CALL DOCALL
; do the disk read
251 JB CKERR
; if errors try to recover
253 ; Now we scan for the presence of IBMBIO COM and IBMDOS COM. Check the
254 ; first directory entry.
258 MOV SI,OFFSET BIO
; point to "ibmbio com"
259 REPZ CMPSB ; see if the same
260 JNZ CKERR
; if not there advise the user
262 ; Found the BIOS. Check the second directory entry.
265 MOV SI,OFFSET DOS
; point to "ibmdos com"
271 ; There has been some recoverable error. Display a message and wait for a
274 CKERR: MOV SI,OFFSET SYSMSG
; point to no system message
275 ErrOut: CALL WRITE
; and write on the screen
276 XOR AH,AH ; wait for response
277 INT 16H
; get character from keyboard
278 POP SI ; reset disk parameter table back to
282 INT 19h
; Continue in loop till good disk
285 pop ax ;adjust the stack
288 jmp short Ckerr
;display message and reboot.
290 ;J.K. We don't have the following error message any more!!!
291 ;J.K. Sysmsg is fine. This will save space by eliminating DMSSG message.
292 ;RERROR: MOV SI,OFFSET DMSSG ; DISK ERROR MESSAGE
296 ; We now begin to load the BIOS in. Compute the number of sectors needed.
297 ; J.K. All we have to do is just read in sectors contiguously IBMLOADSIZE
298 ; J.K. times. We here assume that IBMLOAD module is contiguous. Currently
299 ; J.K. we estimate that IBMLOAD module will not be more than 3 sectors.
302 mov BX,BioOff
;offset of ibmbio(IBMLOAD) to be loaded.
303 mov CX,IBMLOADSIZE
;# of sectors to read.
304 mov AX, [BIOS$_L
] ;Sector number to read.
305 mov DX, [BIOS$_H
] ;AN000;
310 call DODIV
;AN000; DX;AX = sector number.
311 jc Load_Failure
;AN000; Adjust stack. Show error message
312 mov al, 1 ;AN000; Read 1 sector at a time.
313 ;This is to handle a case of media
314 ;when the first sector of IBMLOAD is the
315 ;the last sector in a track.
316 call DOCALL
;AN000; Read the sector.
320 jc CkErr
;AN000; Read error?
321 add AX,1 ;AN000; Next sector number.
323 add BX,ByteSec
;AN000; adjust buffer address.
324 loop Do_While
;AN000;
327 ; MOV AX,BiosFS ; get file size
328 ; XOR DX,DX ; presume < 64K
329 ; DIV ByteSec ; convert to sectors
330 ; INC AL ; reading in one more can't hurt
331 ; MOV COUNT,AL ; Store running count
332 ; MOV AX,BIOS$ ; get logical sector of beginning of BIOS
333 ; MOV BIOSAV,AX ; store away for real bios later
334 ; MOV BX,BioOff ; Load address from BIOSSEG
337 ; ES:BX points to area to read.
338 ; Count is the number of sectors remaining.
339 ; BIOS$ is the next logical sector number to read
342 ; MOV AX,BIOS$ ; Starting sector
345 ; CurHD is the head for this next disk request
346 ; CurTrk is the track for this next request
347 ; CurSec is the beginning sector number for this request
349 ; Compute the number of sectors that we may be able to read in a single ROM
356 ; AX is the number of sectors that we may read.
360 ;New code for Rev 3.31
361 ;*****************************************************************************
363 ; CMP COUNT,AL ;Is sectors we can read more than we need?
364 ; JAE GOT_SECTORS ;No, it is okay
365 ; MOV AL,COUNT ;Yes, only read in what is left
369 ;*****************************************************************************
377 ; JB RERROR ; If errors report and go to ROM BASIC
378 ; SUB COUNT,AL ; Are we finished?
380 ;Old code replaced by Rev 3.3
381 ;********************************************************************
382 ; JBE DISKOK ; Yes -- transfer control to the DOS
383 ;********************************************************************
384 ;New code for Rev 3.3
387 ; JZ DISKOK ; Yes -- transfer control to the DOS
389 ;********************************************************************
392 ; ADD BIOS$,AX ; increment logical sector position
393 ; MUL ByteSec ; determine next offset for read
394 ; ADD BX,AX ; (BX)=(BX)+(SI)*(Bytes per sector)
395 ; JMP LOOPRD ; Get next track
397 ; IBMINIT requires the following input conditions:
399 ; DL = INT 13 drive number we booted from
401 ;J.K.I1. BX was the First data sector on disk (0-based)
402 ;J.K.I1. IBMBIO init routine should check if the boot record is the
403 ;J.K.I1. extended one by looking at the extended_boot_signature.
404 ;J.K.I1. If it is, then should us AX;BX for the starting data sector number.
409 MOV bx,[BIOS$_L
] ;AN000; J.K.I1.Get bios sector in bx
410 mov ax,[BIOS$_H
] ;AN000; J.K.I1.
411 JMP FAR PTR BIOS
;CRANK UP THE DOS
413 WRITE: LODSB ;GET NEXT CHARACTER
414 OR AL,AL ;clear the high bit
415 JZ ENDWR
;ERROR MESSAGE UP, JUMP TO BASIC
416 MOV AH,14 ;WILL WRITE CHARACTER & ATTRIBUTE
418 INT 10H
;PRINT THE CHARACTER
421 ; convert a logical sector into Track/sector/head. AX has the logical
423 ; J.K. DX;AX has the sector number. Because of not enough space, we are
424 ; going to use Simple 32 bit division here.
425 ; Carry set if DX;AX is too big to handle.
429 cmp dx,Seclim
;AN000; To prevent overflow!!!
430 jae DivOverFlow
;AN000; Compare high word with the divisor.
431 DIV SECLIM
;AX = Total tracks, DX = sector number
432 INC DL ;Since we assume SecLim < 255 (a byte), DH =0.
434 MOV CURSEC
, DL ;save it
437 MOV CURHD
,DL ;Also, Hdlim < 255.
447 ;J.K.We don't have space for the following full 32 bit division.
448 ; convert a logical sector into Track/sector/head. AX has the logical
450 ; J.K. DX;AX has the sector number.
458 ; div SecLim ;J.K.Temp_H;AX = total tracks, DX=sector
459 ; INC DL ;Since we assume SecLim < 255 (a byte), DH =0.
460 ; ;Cursec is 1-based.
461 ; MOV CURSEC, DL ;save it
468 ; div HdLim ;J.K.Temp_H;AX=total cyliners,DX=head
469 ; MOV CURHD,DL ;Also, Hdlim < 255.
481 ; Issue one read request. ES:BX have the transfer address, AL is the number
484 DOCALL: MOV AH,ROM_DISKRD
;AC000;=2
496 ; include ibmbtmes.inc
497 include boot
.cl1
;AN003;
508 Free EQU
(cbSec
- 4) - ($-$start
) ;AC000;
509 ;Free EQU (cbSec - 5) - ($-$start)
511 %
out FATAL PROBLEM
:boot sector is too
large
514 org origin
+ (cbSec
- 2) ;AN004;
515 ; org origin + (cbSec - 5)
517 ;Warning!! Do not change the position of following unless
518 ;Warning!! you change BOOTFORM.INC (in COMMON subdirectory) file.
519 ;Format should set this EOT value for IBMBOOT.
520 ;FEOT db 12h ;AN000; set by FORMAT. AN004;Use SecLim in BPB instead.
521 ; FORMAT and SYS count on CURHD,PHYDRV being right here
522 ;J.K. CURHD has been deleted since it is not being used by anybody.
523 ;CURHD DB ? ;AN001;Unitialized (J.K. Maybe don't need this).
524 ;PHYDRV db 0 ;AN000;moved into the header part.
525 ; Boot sector signature