Загрузочный сектор дискеты MS DOS 5.0

Ниже приведен результат реконструкции программы, записанной в загрузочном секторе дискеты для операционной системы MS DOS 5.0
 
; Загрузочный сектор дискеты 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

; конец программы

[Назад] [↑]
Hosted by uCoz