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