DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

386 lines
10 KiB

; SCCSID = @(#)ibmboot.asm 1.1 85/05/13
TITLE BOOT SECTOR 1 OF TRACK 0 - BOOT LOADER
; Rev 1.0 ChrisP, AaronR and others. 2.0 format boot
;
; Rev 3.0 MarkZ Salmon enhancements
; 2.50 in label
; Rev 3.1 MarkZ 3.1 in label due to vagaries of SYSing to IBM drive D's
; This resulted in the BPB being off by 1. So we now trust
; 2.0 and 3.1 boot sectors and disbelieve 3.0.
;
; Rev 3.2 LeeAc Modify layout of extended BPB for >32M support
; Move PHYDRV to 3rd byte from end of sector
; so that it won't have to be moved again
; FORMAT and SYS count on PHYDRV being in a known location
;
; Rev. 3.3 DCLove Changed Sec 9 EOT field from 15 to 18. May 29, 1986.
;
; Rev 3.31 MarkT The COUNT value has a bogus check (JBE????) to determine
; if we've loaded in all the sectors of IO.SYS. This will
; cause too big of a load if the sectors per track is high
; enough, causing either a stack overflow or the boot code
; to be overwritten.
;
;
; The ROM in the IBM PC starts the boot process by performing a hardware
; initialization and a verification of all external devices. If all goes
; well, it will then load from the boot drive the sector from track 0, head 0,
; sector 1. This sector is placed at physical address 07C00h. The initial
; registers are set up as follows: CS=DS=ES=SS=0. IP=7C00h, SP=0400H.
;
; The code in this sector is responsible for locating the MSDOS device drivers
; (IO.SYS) and for placing the directory sector with this information at
; physical address 00500h. After loading in this sector, it reads in the
; entirety of the BIOS at BIOSEG:0 and does a long jump to that point.
;
; If no BIOS/DOS pair is found an error message is displayed and the user is
; prompted to reinsert another disk. If there is a disk error during the
; process, a message is displayed and things are halted.
;
; At the beginning of the boot sector, there is a table which describes the
; MSDOS structure of the media. This is equivalent to the BPB with some
; additional information describing the physical layout of the driver (heads,
; tracks, sectors)
;
ORIGIN EQU 7C00H ; Origin of bootstrap LOADER
BIOSEG EQU 70H ; destingation segment of BIOS
BioOff EQU 700H ; offset of bios
cbSec EQU 512
cbDirEnt EQU 32
DirOff EQU 500h
;
; Define the destination segment of the BIOS, including the initialization
; label
;
SEGBIOS SEGMENT AT BIOSEG
BIOS LABEL BYTE
SEGBIOS ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING
ORG DirOff + 1Ch
BiosFS LABEL WORD
ORG ORIGIN
DSKADR = 1EH*4 ;POINTER TO DRIVE PARAMETERS
Public $START
$START:
JMP START
;----------------------------------------------------------
;
; THE FOLLOWING DATA CONFIGURES THE BOOT PROGRAM
; FOR ANY TYPE OF DRIVE OR HARDFILE
;
DB "MSDOS"
DB "3.3"
ByteSec DW cbSec ; SIZE OF A PHYSICAL SECTOR
DB 8 ; SECTORS PER ALLOCATION UNIT
cSecRes DW 1 ; NUMBER OF RESERVED SECTORS
cFat DB 2 ; NUMBER OF FATS
DirNum DW 512 ; NUMBER OF DIREC ENTRIES
DW 4*17*305-1 ; NUMBER OF SECTORS - NUMBER OF HIDDEN SECTORS
MEDIA DB 0F8H ; MEDIA BYTE
cSecFat DW 8 ; NUMBER OF FAT SECTORS
SECLIM DW 17 ; SECTORS PER TRACK
HDLIM DW 4 ; NUMBER OF SURFACES
cSecHid DW 1 ; NUMBER OF HIDDEN SECTORS
dw 0 ; high order word of Hiden Sectors
dd 0 ; 32 bit version of NUMBER OF SECTORS
; (when 16 bit version is zero)
db 6 dup(?) ; reserved for later expansion
CURHD DB ? ; Unitialized
; this is an image of the disk parameter table. Zero entries are copied
; from the rom table at boot.
;
SEC9 DB 0 ; DISK_SPECIFY_1
DB 0 ; DISK_SPECIFY_2
DB 0 ; DISK_MOTOR_WAIT
DB 0 ; DISK_SECTOR_SIZ
DB 12h ; DISK_EOT
DB 0 ; DISK_RW_GAP
DB 0 ; DISK_DTL
DB 0 ; DISK_FORMT_GAP
DB 0 ; DISK_FILL
DB 1 ; DISK_HEAD_STTL
DB 0 ; DISK_MOTOR_STRT
Public UDATA
UDATA LABEL WORD
BIOS$ EQU WORD PTR UDATA+1
CURTRK EQU WORD PTR UDATA+3
CURSEC EQU BYTE PTR UDATA+5
COUNT EQU BYTE PTR UDATA+6 ; NUMBER OF BIOS SECTORS
BIOSAV EQU WORD PTR UDATA+7
DIR$ EQU WORD PTR UDATA+9
START:
;
; First thing is to reset the stack to a better and more known place. The ROM
; may change, but we'd like to get the stack in the correct place.
;
CLI ;Stop interrupts till stack ok
XOR AX,AX
MOV SS,AX ;Work in stack just below this routine
ASSUME SS:CODE
MOV SP,ORIGIN
PUSH SS
POP ES
ASSUME ES:CODE
;
; We copy the disk parameter table into a local area. We scan the table above
; for non-zero parameters. Any we see get changed to their non-zero values.
;
MOV BX,DSKADR
LDS SI,DWORD PTR SS:[BX] ; get address of disk table
PUSH DS ; save original vector for possible
PUSH SI ; restore
PUSH SS
PUSH BX
MOV DI,OFFSET Sec9
MOV CX,11
CLD
changeloop:
LODSB
CMP BYTE PTR ES:[DI],0 ; is the template zero?
JZ Store ; yes, store what we've got
MOV AL,ES:[DI]
Store:
STOSB
MOV AL,AH
LOOP ChangeLoop
;
; Place in new disk parameter table.
;
PUSH ES
POP DS
ASSUME DS:CODE
MOV [BX+2],AX
MOV [BX],OFFSET SEC9
;
; We may now turn interrupts back on. Before this, there is a small window
; when a reboot command may come in when the disk parameter table is garbage
;
STI ;Interrupts OK now
;
; Reset the disk system just in case any thing funny has happened.
;
INT 13H ;Reset the system
JC RERROR
;
; The system is now prepared for us to begin reading. First, determine
; logical sector numbers of the start of the directory and the start of the
; data area.
;
MOV AL,cFat ;Determine sector dir starts on
CBW
MUL cSecFat
ADD AX,cSecHid
ADD AX,cSecRes
MOV [DIR$],AX ; AX = cFat*cSecFat + cSecRes + cSecHid
MOV [BIOS$],AX
;
; Take into account size of directory (only know number of directory entries)
;
MOV AX,cbDirEnt ; bytes per directory entry
MUL DirNum ; convert to bytes in directory
MOV BX,ByteSec ; add in sector size
ADD AX,BX
DEC AX ; decrement so that we round up
DIV BX ; convert to sector number
ADD [BIOS$],AX
;
; We load in the first directory sector and examine it to make sure the the
; BIOS and DOS are the first two directory entries. If they are not found,
; the user is prompted to insert a new disk. The directory sector is loaded
; into 00500h
;
MOV BX,DirOff ; sector to go in at 00500h
MOV AX,DIR$ ; logical sector of directory
CALL DODIV ; convert to sector, track, head
MOV AX,0201H ; disk read 1 sector
CALL DOCALL ; do the disk read
JB CKERR ; if errors try to recover
;
; Now we scan for the presence of IO.SYS and MSDOS.SYS. Check the
; first directory entry.
;
MOV DI,BX
MOV CX,11
MOV SI,OFFSET BIO ; point to "bios com"
REPZ CMPSB ; see if the same
JNZ CKERR ; if not there advise the user
;
; Found the BIOS. Check the second directory entry.
;
LEA DI,[BX+20h]
MOV SI,OFFSET DOS ; point to "86dos com"
MOV CX,11
REPZ CMPSB
JZ DoLoad
;
; There has been some recoverable error. Display a message and wait for a
; keystroke.
;
CKERR: MOV SI,OFFSET SYSMSG ; point to no system message
ErrOut: CALL WRITE ; and write on the screen
XOR AH,AH ; wait for response
INT 16H ; get character from keyboard
POP SI ; reset disk parameter table back to
POP DS ; rom
POP [SI]
POP [SI+2]
INT 19h ; Continue in loop till good disk
RERROR: MOV SI,OFFSET DMSSG ; DISK ERROR MESSAGE
JMP ErrOut
;
; We now begin to load the BIOS in. Compute the number of sectors needed
;
DoLoad:
MOV AX,BiosFS ; get file size
XOR DX,DX ; presume < 64K
DIV ByteSec ; convert to sectors
INC AL ; reading in one more can't hurt
MOV COUNT,AL ; Store running count
MOV AX,BIOS$ ; get logical sector of beginning of BIOS
MOV BIOSAV,AX ; store away for real bios later
MOV BX,BioOff ; Load address from BIOSSEG
;
; Main read-in loop.
; ES:BX points to area to read.
; Count is the number of sectors remaining.
; BIOS$ is the next logical sector number to read
;
LOOPRD:
MOV AX,BIOS$ ; Starting sector
CALL DODIV
;
; CurHD is the head for this next disk request
; CurTrk is the track for this next request
; CurSec is the beginning sector number for this request
;
; Compute the number of sectors that we may be able to read in a single ROM
; request.
;
MOV AX,SECLIM
SUB AL,CURSEC
INC AX
;
; AX is the number of sectors that we may read.
;
;
;New code for Rev 3.31
;*****************************************************************************
CMP COUNT,AL ;Is sectors we can read more than we need?
JAE GOT_SECTORS ;No, it is okay
MOV AL,COUNT ;Yes, only read in what is left
GOT_SECTORS:
;*****************************************************************************
;End of change
;
PUSH AX
CALL DOCALL
POP AX
JB RERROR ; If errors report and go to ROM BASIC
SUB COUNT,AL ; Are we finished?
;
;Old code replaced by Rev 3.3
;********************************************************************
; JBE DISKOK ; Yes -- transfer control to the DOS
;********************************************************************
;New code for Rev 3.3
;
JZ DISKOK ; Yes -- transfer control to the DOS
;********************************************************************
;End of change
;
ADD BIOS$,AX ; increment logical sector position
MUL ByteSec ; determine next offset for read
ADD BX,AX ; (BX)=(BX)+(SI)*(Bytes per sector)
JMP LOOPRD ; Get next track
;
; IBMINIT requires the following input conditions:
;
; DL = INT 13 drive number we booted from
; CH = media byte
; BX = First data sector on disk (0-based)
;
DISKOK:
MOV CH,Media
MOV DL,PhyDrv
MOV BX,[BIOSAV] ;Get bios sector in bx
JMP FAR PTR BIOS ;CRANK UP THE DOS
WRITE: LODSB ;GET NEXT CHARACTER
OR AL,AL ;clear the high bit
JZ ENDWR ;ERROR MESSAGE UP, JUMP TO BASIC
MOV AH,14 ;WILL WRITE CHARACTER & ATTRIBUTE
MOV BX,7 ;ATTRIBUTE
INT 10H ;PRINT THE CHARACTER
JMP WRITE
;
; convert a logical sector into Track/sector/head. AX has the logical
; sector number
;
DODIV:
XOR DX,DX
DIV SECLIM
INC DL ; sector numbers are 1-based
MOV CURSEC,DL
XOR DX,DX
DIV HDLIM
MOV CURHD,DL
MOV CURTRK,AX
ENDWR: RET
;
; Issue one read request. ES:BX have the transfer address, AL is the number
; of sectors.
;
DOCALL: MOV AH,2
MOV DX,CURTRK
MOV CL,6
SHL DH,CL
OR DH,CURSEC
MOV CX,DX
XCHG CH,CL
MOV DL, PHYDRV
mov dh, curhd
INT 13H
RET
include messages.inc
BIO DB "IO SYS"
DOS DB "MSDOS SYS"
Free EQU (cbSec - 3) - ($-$start)
if Free LT 0
%out FATAL PROBLEM:boot sector is too large
endif
org origin + (cbSec - 3)
; FORMAT and SYS count on PHYDRV being right here
PHYDRV db 0
; Boot sector signature
db 55h,0aah
CODE ENDS
END