9 Years
Discussion Span
Last Post by Garni
;0-10    File name (8 bytes) with extension (3 bytes)
;11      Attribute - a bitvector. Bit 0: read only. Bit 1: hidden.
;        Bit 2: system file. Bit 3: volume label. Bit 4: subdirectory.
;        Bit 5: archive. Bits 6-7: unused.
;12-21   Reserved (see below)
;22-23   Time (5/6/5 bits, for hour/minutes/doubleseconds)
;24-25   Date (7/4/5 bits, for year-since-1980/month/day)
;26-27   Starting cluster (0 for an empty file)
;28-31   Filesize in bytes


text segment word 'code'
assume cs:text, ds:text

org 7C00h

jmp short ldr

boot    proc

db ?                    ;byte not needed for short jump

OEMname         db     'OEM NAME'
SecSize         dw     512
ClustSize       db     1
reserved        dw     1
FATCnt          db     2
RootEntries     dw     224  ;max entries in root directory
unused1         dw     ?
mdb             db     0F0h
FATSize         dw     9
SecsPerTrk      dw     18
heads           dw     2
hidden          dd     10   ;sectors reserved for boot loader (5120 bytes available)
unused2         dd     0
drive           db     0
unused3         db     0
signature       db     29h
SerNum          dd     03C9A71BFh
VolumeLabel     db     'NO NAME   '
                db     'FAT12   '

xor ax,ax
mov cs,ax
mov ds,ax                   ;initialise segment registers
mov ss,ax
mov es,ax
mov sp, 0fffeh              ;set up stack

mov ax, FATSize             ;load sectors per track
mov bh, FATCnt
mul bh                      ;calculate number of FAT sectors
add ax, reserved            ;add on boot sector(s)
inc ax                      ;first sector of root directory
push ax
pop cx                      ;cl = first sector to read, ch = track 0
push cx                     ;save sector address of root directory
xor dh,dh                   ;dh = head 0
mov dl, drive               ;load drive number
mov bx, 8000H               ;es:bx -> buffer on DMA boundary
mov ax, 201H                ;read first sector of root directory into memory
int 13h
jc BadTrk0                  ;jump to error handler if read failed

mov si, 8000H               ;ds:si -> first directory entry
lea di, osldr               ;es:di -> loader's filename
mov cx, 11
repe cmpsb                  ;is loader present?
je ldr_found                ;if so, skip error handler

lea si, errmsg2             ;ds:si -> non system disk message
call disp                   ;display message
lea si, errmsg10
call disp
jmp short reboot            ;reboot computer

mov ax, RootEntries         
shr ax, 4                   ;ax = number of root directory sectors
pop cx                      ;pop seg address of root directory & track number
add cl,al                   ;cl = first sector after root directory
cmp cl, byte ptr SecsPerTrk ;isw cl > number of sectors on track?
jna la1                     ;no - so no adjustment necessary

sub cl, byte ptr SecsPerTrk ;sector number for track 0, head 1
xor dh, 1                   ;toggle head number

call read64k                ;read loader into memory
jnc ldr_read_ok             ;skip error handler if read was successful

lea si, errmsg1             ;ds:si -> error message
call disp                   ;display message
lea si, errmsg10
call disp

xor ah,ah                   ;wait for keystroke
int 16h
mov bx,472H                 ;0:472 = address of boot status word
mov word ptr [ bx ], 1234H  ;skip POST test
int 19h                     ;reboot

jmp ldr_addr                ;jump to osldr

osldr     db 'osldr   sys'

errmsg1   db 'Bad track 0 - Disk unusable.', 0dh, 0ah, 0
errmsg2   db 'Not a system disk', 0dh, 0ah, 0
errmsg10  db 'Strike any key', 0

ldr_addr  dd 8000H

boot endp

disp    proc

xor bh,bh               ;page number
lodsb                   ;load next character
or al,al                ;end of string?
jz EndDisp              ;if so jump out of loop

mov ah, 0Eh             ;display character
int 10h
jmp short nextChar      ;next character


disp    endp

read64k    proc    near
;dl = drive
;dh = head
;cl = sector
;ch = track
;bx -> buffer on DMA boundary

mov si,cx                ;save sector and track numbers
mov cx, 16               ;16 * 4096 byte pages = 64kb

xchg cx,si               ;cx = sector and track numbers, si = loop count
call readPage            ;read 4096 byte page into memory
jc read64kEnd

xchg si,cx               ;si = returned sector and track numbers, cx = loop count
loop nextPage            ;read next page



read64k    endp

readPage    proc    near
;dl = drive
;dh = head
;cl = sector
;ch = track
;bx -> buffer on DMA boundary

push bx
push cx
push dx
mov ax, 8              ;8 sectors = 4096 byte DMA page
push cx                ;save sector and track number
add cl,al              ;calculate end sector number
cmp cl, byte ptr SecsPerTrk
pop cx                 ;past end of track?
jna SameTrk            ;no - so skip special code
mov ax, SecsPerTrk     ;load al with number of sectors per track
sub al,cl
inc ax                 ;ax = number of sectors to read
push ax                
push bx
push cx
push dx
mov ah, 2              ;read sectors into buffer
int 13h
pop dx
pop cx
pop bx
pop ax                 ;ax = number of sectors read
jnc la3                ;skip error handler if carry clear

add sp, 8              ;pop pushed registers
stc                    ;flag error
ret                    ;return to caller

push ax                
shl ax, 9              ;ax = number of bytes read
add bx,ax              ;update buffer pointer ready for next read
pop ax
sub al, 8
neg al                 ;ax = number of remaining sectors to read
mov cl, 1              ;starting with sector 1
xor dh, 1              ;toggle head number
jnz SameTrk            ;jump if not back with head 0

inc ch                 ;otherwise increment track number

mov ah, 2              ;complete read
int 13h
jc la4                 ;return with carry set upon error

pop dx
pop cx
pop bx
add bx, 4096           ;increment bx by number of bytes in page
add cl, 8              ;increment starting sector by eight
cmp cl, byte ptr SecsPerTrk ;pased end of track?
jna la2                ;no - so skip handler

sub cl, byte ptr SecsPerTrk
xor dh, 1              ;toggle head number
jnz la2                ;if head != 0 do not increment track number

inc ch                 ;new track number

clc                    ;no error

readPage    endp

dw 0, 55AAH

text ends


Chances are you wiould need a utility to strip off the first 7C00H bytes after compiling and linking it. (Not yet tested or debugged by the way.)

This article has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.