The bootrecord
Back in 1999 I was active at the FreeDOS community. In those days I wrote this source that will create a boot record for a floppy disk. I called it 'chatty boot'.
The sourcecode.
Below is the source code for the bootloader. It fits within the 512 byte limit of the bootsector. I forgot if there was still room for the partition table. If there isn't, just kick out the redundant messages. The boot signature was included.
name bflop
title Floppy disk boot sector, bootable.
page 80, 120
; version 1.0 : Get it working first... : OK 19 jan 1999
; : Make it real chatty : OK 19 jan 1999
Chatty = 1 ; conditional assembly flag
; ----------------------
lf = 10 ; data equates
cr = 13
; ----------------------
RootFiles = 224 ; disk layout equates
FatSects = 9
Reserved = 1
Fats = 2
StartFat = Reserved ; First FAT starts here
StartDir = StartFat + Fats * FatSects ; First directory sector
DirSects = RootFiles / 16 ; Directory is this long
StartDat = StartDir + DirSects ; First sector which contains data
BootLoad = 07C00 ; Bootloader is loaded here
DirLoad = 08000 ; Directory is loaded in memory here
FatLoad = 0C000 ; FAT is loaded in memory here
IPLSegm = 02000 ; Segment of load address for IPL.SYS
IPLOffs = 0 ; Offset of address where to load IPL.SYS
; ----------------------
org 0
jmp short main
nop
; ----------------------
OEMname db 'DOS-2000'
BpS dw 512 ; bytes per sector
SpAllo db 1 ; sectors per allocation unit (=cluster)
ResSect dw Reserved ; reserved sectors, starting from sector 0
NrFats db Fats ; number of FAT's on this disk
FiR dw RootFiles ; number of entries in ROOT directory
Total dw 2880 ; number of sectors per disk
ToM db 0F0 ; Type of Media
SpF dw FatSects ; Sectors per Fat
SpT dw 18 ; sectors per Track
Heads dw 2 ; number of heads
Cluster dw 0
Sector dw 0 ; Hidden sectors
GrandTot dd 0
IntId db 0, 0
BootSign db 029 ; extended boot signature
VolumeID dd 0566E614A ; serial number ...
DiskLabl db 'DOS boot144' ; volume label
FATtype db 'FAT-12 ' ; FAT type
Drive db 'VeRsIoN=1.0', 0 ; for version control only
IPLaddr dw IPLOffs, IPLSegm
; ----------------------
StoreSi dw 0
L1: pop bx, ax
push si ; stack up return address
mov si, [StoreSi + BootLoad]
ret ; and jump to it
print: mov [StoreSi + BootLoad], si
pop si ; this is the first character
push ax, bx
mov bx, 0 ; video page 0
L0: cs lodsb ; get token
cmp al, 0 ; end of string?
je L1 ; if so, exit
mov ah, 0E ; else print it
int 010 ; via TTY mode
jmp L0 ; until done
; ----------------------
main: cld
cli
mov ax, cs ; cs = 0000
mov es, ax
mov ss, ax
mov ds, ax ; all segment registers are 0000
mov sp, BootLoad ; set stackpointer
sti
mov [Drive + BootLoad], dl
call print ; show message
db cr
db 'Booting: ', 0
mov ah, 0
mov dl, [Drive + BootLoad]
int 013 ; reset diskdrive
mov [Sector + BootLoad], StartDir
mov cx, DirSects
mov bx, DirLoad ; buffer at 0000:08000
call RdDisk
#IF chatty
call print
db '> directory loaded.', cr, lf, 0
#ENDIF
call print
db 'IPL.SYS ', 0
mov cx, RootFiles
mov si, DirLoad
mov di, offset IPLFile + BootLoad
L0: push cx, si, di
mov cx, LenIPL
repe cmpsb ; directory entry matches file to load?
pop di, si, cx
jz found
add si, 020 ; point to next entry in directory
loop L0 ; and loop back
call print
db 'absent. Press ENTER to reboot.', 0
GetOut: mov ah, 0
int 016 ; get key
int 019 ; and reboot
found: call print
db 'found. ', 0 ; print it
mov ax, [si + 01A] ; keep first datasector to load
mov [Cluster + BootLoad], ax ; save current cluster-number
mov [Sector + BootLoad], StartFat
mov cx, FatSects
mov bx, FatLoad
call RdDisk ; get FAT1 completely
#IF chatty
call print
db '> FAT loaded.', cr, lf, 0
#ENDIF
les bx, d [IPLaddr + BootLoad] ; prepare to load IPL.SYS
mov ax, [Cluster + BootLoad]
L0: add ax, StartDat - 2
mov [Sector + BootLoad], ax
call LoadSector ; get that sector
#IF chatty
call print
db '+', 0
#ENDIF
mov si, [Cluster + BootLoad] ; determine next cluster to load
mov ax, si
shl ax, 1
add si, ax
shr si, 1 ; si = CatEntry * 1.5
mov ax, FatLoad[si]
jnc >L2 ; if even address in FAT, jump
mov cl, 4
shr ax, cl
L2: and ax, 0FFF
cmp ax, 0FF7 ; 0FF8 and up mean "last cluster"
ja done
mov [Cluster + BootLoad], ax
add bx, 0200 ; adjust address to loead next sector
jmp L0 ; repeat until done
done: call print
db cr, lf
db 'Transferring control to IPL.SYS now.', 0
mov dl, [Drive + BootLoad]
jmp IPLSegm:IPLOffs
; ----------------------
LoadSector: ; load [Sector] to es:bx
push cx
mov ax, [Sector + BootLoad]
mov cl, 18 ; sectors per track
div cl ; ah = sector - 1
mov dh, al
and dh, bit 0 ; dh = head
shr al, 1
mov ch, al ; ch = track
mov cl, ah ; cl = sector
inc cl
mov dl, [Drive + BootLoad] ; dl = drive
mov ax, 0201
int 013 ; read one sector
pop cx
ret
; ----------------------
RdDisk: call LoadSector
jc RdDisk
#IF chatty
call print
db '-', 0
#ENDIF
add bx, 512
inc [Sector + BootLoad]
loop RdDisk ; repeat until all is in memory
ret
; ----------------------
IPLFile db 'IPL SYS'
LenIPL = $ - IPLfile
org 01FE
db 055, 0AA ; don't forget to sign!
Page created on April 9, 2006 and
Page equipped with FroogleBuster technology