///////////////////////
//boot sector section//
///////////////////////
//Notes:
//1- BIOS loads this sector to address 0000:7c00 then does a jump 0000:7c00
// to enter this executable at START:
//2- floppy disk parameter table at 0000:0078 (vector 1e) is valid
// this is an 11-byte structure of the form:
// struct FDCPARMS //typical
// { //value (1.44Mb)
// UC spec1; //0xdf sort=f,unload=f 1st FDC cmd specify byte
// UC spec2; //0x02 hd load=1 mode=DMA 2nd FDC cmd specify byte
// UC mtrwait; //0x25 timer ticks till motor off (about 3 sec)
// UC bps; //0x02 bytes per sector
// UC eot; //0x12 last sector on a track
// UC gap1; //0x1b intersector gap length
// UC datalen; //0xff ff=512
// UC gap3; //0x54 gap length for format
// UC fill; //0xf6 fill bytes for format command
// UC headsettle; //0x0f head settle time (msec)
// UC motorstart; //0x08 motor start time (1/8sec)
// };
// note also that this structure is incorporated into the fdcparms table
// in ChaOS floppy.ctp
//3- on legacy machines the only other valid input is register DL, which
// contains the drive ID which delivered the boot sector, usually 0
// for floppy drive A
//4- Bios Boot spec 1.0 (PnP) states that ES:DI points to the PnP
// installation check structure (struct PNPBIOS in pnp.hpp)
// as well DL being set to the drive number. This structure contains
// the entry point to BIOS PnP services
//5- failure to boot triggers a call to int 19h, which BIOS has set to
// bootstrap recovery, usually an attempt to boot from the next available
// device
//6- successful operation of the boot sector goes as follows:
// -reset diskette system
// -read first root directory sector to 0000:0900
// -locate LOADER.BIN in that sector
// -load LOADER.BIN to address 0000:0b00 and jump to 00b0:0000
//7- size and cluster of LOADER.BIN is taken from the directory entry,
// but upper 16 bits of size are ignored. In any case, the maximum length
// of LOADER.BIN is 0x7C00-0x700=0x7500 (29952 bytes), less any stack space
// in use. LOADER.BIN IS ASSUMED TO BE CONTIGUOUS from its start cluster
//
//8- passed-in parameter to LOADER.BIN are
// ch=media byte
// dl=boot drive
// ax:bx=is logical sector for drive data area
// root dir sector is still at 0:900
//9- byte at bse1 is a digit displayed at the beginning of the one and only
// error message from this sector "0:Insert system disk and press a key"
// by incrementing *bse1 the following error codes are valid:
// 0: Error resetting disk system
// 1: Prep track error (root directory sector > sectors per track)
// 2: Error reading root directory sector
// 3: LOADER.BIN not found in first root directory sector
// 4: Prep track error (LOADER.BIN > sectors per track)
// 5: Error reading LOADER.BIN
//
//these are symbols used in the code before they are declared
//the ChaOS assembler uses 'C' type data declarations
EX UC bse1[];
EX UC bsn1[];
EX UL bssig;
VD prep(VD);
VD BSL02a(VD);
#asm
BSSTART:
jmp BSL01
nop
//data can be freely declared in the code stream like this
;offset
UC oem "CHAOS " ; 3
UI bps 512 ; b bytes per sector
UC spc 1 ; d sectors per cluster
UI srs 1 ; e sectors reserved
UC fts 2 ;10 FATs
UI rts 224 ;11 root entries
UI tls 2880 ;13 total sectors
UC med 0xf0 ;15 media byte
UI spf 9 ;16 sectors per FAT
UI spt 18 ;18 sectors per track
UI hds 2 ;1a heads
UL hid 0 ;1c hidden sectors
UI rtl 0 ;20 reserved work area:total sectors
UI r1 0 ;22
UC rdr 0 ;24 reserved work area:drive
UC rhd 0 ;25 reserved work area:head
UC n29 0x29 ;26
UL r2 0 ;27
;;temporary work area overwriting boot sector volume label
UL dsc 0 ;2b logical sector no for disk data area
UI trk 0 ;2f current track
UC sec 0 ;31 sector
UL rsc 0 ;32 logical sector no for disk root directory
UC ftn "FAT12 " ;36
BSL01:
cli
mov sp,0xf800 ;stack will grow downwards from 7000:f800
sub ax,ax
mov ss,ax
mov es,ax
push es
pop ds
op 0xcc
mov si,bmBIOS ;relocate boot sector image to 0x700
mov di,bmBOOT
mov cx,0x100
op 0xf2
movsw
op 0xea ;far jump into relocated boot sector image
#endasm
UI bsofflo=&BSL02a;
#asm
UI bsoffhi
BSL02a:
//now boot sector is executing at 0000:0720ish
mov byte bssig,dl ;drive passed in by partition table or BIOS
inc byte bse1 ;errno is 1
sub ax,ax
cmp tls,ax
jz BSL02
mov cx,tls
mov rtl,cx
BSL02:
mov al,fts ;al=number of FATS
mul word spf ;multiply by sectors per FAT
add ax,word hid
adc dx,word hid+2 ;add dword hidden sector count
add ax,srs ;add word reserved sector count
adc dx,0 ;now we have logical sector for root directory
mov word rsc,ax
mov word rsc+2,dx ;store in dword rsc
mov word dsc,ax
mov word dsc+2,dx ;store in dword dsc
mov ax,32 ;ax is sizeof (DIRECTORY ENTRY)
mul word rts ;multiply root entries
mov bx,bps
add ax,bx
dec ax ;add bytes per sector - 1
div bx ;divide by sector size
add word dsc,ax
adc word dsc+2,0
mov bx,bmROOT ;es:bx->0000:0900
mov ax,word rsc
mov dx,word rsc+2
call prep
jc ERR01
inc byte bse1 ;errno is 2
mov al,1
call read ;read root dir 1st sector to 0000:0900
jc ERR01
inc byte bse1 ;errno is 3
mov cx,16 ;LOADER.BIN must be in first root directory
;sector, i.e. in the first 16 root entries
nextrootentry:
mov di,bx ;es:di->root dir entry
push cx
mov cx,11
mov si,&bsn1
rep cmpsb
pop cx
jz strap
add bx,32 ;advance to next entry
loop nextrootentry
ERR01: ;error, display "Non-System disk...etc"
mov si,&bse1
call errmsg
sub ax,ax
int 0x16 ;press a key
int 0x19
ERR02:
pop ax
pop ax
pop ax
jmp ERR01
strap:
inc byte bse1 ;errno is 4
mov ax,[bx+0x1c] ;ax is size of LOADER.BIN mod 64k!
add ax,511
mov cl,9
shr ax,cl
mov cx,ax ;cx is sectors we need
mov ax,[bx+0x1a] ;get cluster number of bootstrap
dec ax
dec ax
mov bl,spc ;get sectors per cluster
sub bh,bh
mul bx
add ax,word dsc
adc dx,word dsc+2 ;dx:ax is first sector of LOADER.BIN
mov bx,bmLOAD ;set DTA to 0:b00
nextsect:
push ax
push dx
push cx
call prep
jc ERR02
mov al,1
call read
pop cx
pop dx
pop ax
jc ERR01
inc byte bse1 ;errno is 5
add ax,1 ;increment logical sector number
adc dx,0
add bx,bps ;add sector size to DTA for next read
dec byte bse1 ;errno is 4 again
loop nextsect
;BOOTSTRAP is loaded and ready to rock and roll
;pass some info in registers to next stage
skip:
mov ch,med ;ch is media byte
mov dl,byte bssig ;dl is boot drive
mov bx,word dsc ;ax:bx is logical sector for drive data area
mov ax,word dsc+2 ;remember root dir sector is still at 0:900
op 0xea 0x00 0x0b 0x00 0x00 //jmp 0000:0b00); jump into LOADER.BIN
errmsg: ;output ASCIIZ string to screen
lodsb
or al,al
jz errout ;break on zero byte
mov ah,0x0e
mov bx,7
int 0x10
jmp errmsg
errout:
ret
prep:
push dx
push ax
op32
pop ax
push cx
op32
sub cx,cx
op32
sub dx,dx
mov cx,word spt
op32
div cx
inc dl
mov sec,dl
sub dx,dx
mov cx,word hds
op32
div cx
mov rhd,dl
mov trk,ax
clc
pop cx
ret
read:
mov ah,2
mov dx,word trk
mov cl,6
shl dh,cl
or dh,byte sec
mov cx,dx ;ch=sector, cl=track
xchg ch,cl ;ch=track, cl=sector
mov dl,byte bssig
mov dh,byte rhd
int 0x13
ret
org 0x8c9
UC bse1 "0:Insert system disk and press a key "
UC bse2[3] 0x0d 0x0a 0
UC bsn1 "LOADER BIN"
UL bssig 0xaa550000
#endasm