; Загрузочный сектор дискеты MS DOS 5.0
; flat assembler v. 1.49
;
format binary
use16
ORG 7C00h
start:
jmp near begin
nop
;----------------------------------------------------------------
abOem db 'MSDOS5.0'
; BPB - BIOS Parameter Block
wSectSize dw 512
bClustSects db 1
wResSects dw 1
bFatCnt db 2
wRootEntries dw 224
wTotSects dw 2880
bMedia db 0F0h
wFatSects dw 9
wSectsPerTrk dw 18
wHeads dw 2
lHidSects dw 0
HiddenSectorsHi dw 0
lBigTotSect dd 0
bDrvNo db 0
res1 db 0
bExtBootSig db 29h
lSerNo dd 3E2911E4h
abVolLabel db 'LABEL_NAME '
abFileSysID db 'FAT12 '
;-----------------------------------------------------------------
begin:
virtual at begin
DPT:
times 11 db ? ;Diskette Parameter Table
DataLoc dd ?
CylNo dw ? ; номер цилиндра
SectNo db ? ; номер сектора на дорожке
RootLoc dd ?
end virtual
cli
xor ax,ax
mov ss,ax
mov sp,7C00h
push ss
pop es
mov bx,78h ; Diskette Parameter Table (DPT - Int 1Eh)
lds si,[ss:bx] ; адрес DPT --> ds:si
push ds
push si
push ss
push bx
mov di,DPT
mov cx,11 ; длина DPT
cld
repe movsb ; копирование DPT
push es
pop ds ; восстановить ds = 0
mov byte [di-2],0Fh ; Head-settle time
mov cx,[wSectsPerTrk]
mov [di-7],cl ; bLastTrack
mov [bx+2],ax ; замена вектора 1Eh
mov word [bx],DPT
sti
int 13h ; RESET DISK SYSTEM
jb mError
xor ax,ax ; ax = 0
cmp [wTotSects],ax
jz longdisk ; > 32Mb
mov cx,[wTotSects]
mov word [lBigTotSect],cx
longdisk:
mov al,[bFatCnt]
mul [wFatSects]
add ax,[lHidSects]
adc dx,[lHidSects+2]
add ax,[wResSects]
adc dx, 0
; Сохраняем номер первого сектора Root Dir
mov word [RootLoc],ax
mov word [RootLoc+2],dx
mov word [DataLoc],ax
mov word [DataLoc+2],dx
mov ax,32 ; длина записи в оглавлении
mul [wRootEntries]
mov bx,[wSectSize]
add ax,bx
dec ax ; ax-1
div bx
; Сохраняем номер первого сектора данных
add word [DataLoc],ax
adc word [DataLoc+2],0
;
mov bx,500h ; Адрес буфера
mov dx,word [RootLoc+2]
mov ax,word [RootLoc]
call ReadParamCalc
jb mError
mov al,1
call SectRead ; читаем первый сектор оглавления
jb mError
mov di,bx
mov cx,11
mov si,aIoSys
repe cmpsb ; имя файла в первой записи оглавления
; = aIoSys ?
jnz mError ; нет
lea di,[bx+20h] ; вторая запись оглавления
mov cx,11
repe cmpsb ; = aMsdosSys ?
jz LoadIoSys ; да
mError:
mov si,sNonSystemDisk
call putmsg ; вывод сообщения об ошибке
xor ax, ax
int 16h ; ждем нажатия AnyKey
pop si
pop ds
pop word [si]
pop word [si+2]
int 19h ; Перезагрузка
CalcError: ; CODE XREF: seg000:7D26j
pop ax
pop ax
pop ax
jmp near mError
; ----------------------------------------------------------
; формула вычисления номера сектора по номеру кластера в FAT
; Sector = DataStart + ((AnyClusterNo-2) * bClustSects)
; ----------------------------------------------------------
LoadIoSys:
mov ax,[bx+1Ah] ; wClstrNo (в записи оглавления)
dec ax
dec ax
mov bl,[bClustSects]
xor bh,bh
mul bx
add ax,word [DataLoc]
adc dx,word [DataLoc+2]
mov bx,700h ; адрес для чтения IO.SYS
mov cx,3 ; кол-во читаемых секторов = 3
SectRD:
push ax
push dx
push cx
call ReadParamCalc
jb CalcError ; error
mov al,1 ; кол-во секторов для Int 13h
call SectRead
pop cx
pop dx
pop ax
jb mError
add ax,1 ; следующий сектор
adc dx,0
add bx,[wSectSize]
loop SectRD ; cx=cx-1
mov ch,[bMedia]
mov dl,[bDrvNo]
mov bx,word [DataLoc]
mov ax,word [DataLoc+2]
jmp far 70h:0 ; передача управления в IO.SYS
; ---- Подпрограмма вывода сообщения на экран ----
putmsg:
lodsb ; символ для вывода на экран
or al,al ; =0 ?
jz procend ; да
mov ah,0Eh ; TTY
mov bx,7
int 10h ; TTY WRITE
jmp near putmsg
;---- Подпрограмма подготовки параметров для чтения сектора ----
ReadParamCalc:
cmp dx,[wSectsPerTrk]
jnb ParamError
div word [wSectsPerTrk]
inc dl ; остаток + 1
mov [SectNo],dl ; номер сектора на дорожке
xor dx, dx ; dx=0
div [wHeads]
mov [res1],dl ; номер головки
mov [CylNo],ax ; номер цилиндра
clc
retn
ParamError:
stc
procend:
retn
;---- Подпрограмма чтения сектора ----
SectRead:
mov ah,2 ; читать сектор
mov dx,[CylNo] ; номер цилиндра
mov cl,6
shl dh,cl
or dh,[SectNo] ; номер сектора на дорожке
mov cx,dx
xchg ch,cl
mov dl,[bDrvNo] ; номер диска
mov dh,[res1] ; номер головки
int 13h ; читать сектор в память
retn
;-----------------------------------------------------------------
sNonSystemDisk db 0Dh,0Ah
db 'Non-System disk or disk error',0Dh,0Ah
db 'Replace and press any key when ready',0Dh,0Ah,0
aIoSys db 'IO SYS'
aMsdosSys db 'MSDOS SYS'
times (200h-($-start)-2) db 0
dw 0AA55h
; конец программы
|