Tvùrce webu je i pro tebe! Postav tøeba web. Bez grafika. Bez kodéra. Hned.
wz

BOOT.ASM

Boot Loader

Compilation: NASM16.EXE -o BOOT.BIN BOOT.ASM


; ============================================================================
;
;                     Litos Boot Sector (Floppy disk)
;
; ============================================================================

DISKTAB_SIZE	EQU	16		; size of disk table (with extra bytes)
SECTOR_SIZE	EQU	512		; sector size
BOOTSEG		EQU	100h		; booting segment (=2nd 4KB page)

; ----------------------------------------------------------------------------
;             Start of the boot sector (starting at 0000:7C00)
; ----------------------------------------------------------------------------

SECTION		.text
BITS		16

		org	7C00h		; booting address of boot sector

Start:		jmp	Init		; jump to starting routine

; ------------- Setup data (this can be set by the installator)

SectRead	dw	800		; 3: number of sectors to read
Disk		db	0		; 5: system disk (0=A:, 80h=C:)
Heads		db	2		; 6: number of heads
Sectors		db	18		; 7: number of sectors per track

Message		db	"Error loading system.",13,10
		db	"Press any key...",13,10,0

DiskTab:				; disk table (16 bytes)

; ------------- Init temporary stack (for calling int 12h)
	
Init:		cli			; disable interrupts
		xor	ax,ax		; AX <- 0
		mov	ds,ax		; DS <- 0 this segment
		mov	si,7C00h	; SI <- offset of the boot sector
		mov	ss,ax		; SS <- 0
		mov	sp,si		; SP <- end of stack
		sti			; enable interrupt

; ------------- Determining top of memory (usualy 0A000h)

		int	12h		; AX <- get memory size in 1 KB blocks
		mov	cl,6		; number of rotations
		shl	ax,cl		; segment address of the top of memory
		sub	ax,7E0h		; correction of the segment address

; ------------- Init stack (lies below new beginning of the boot sector)

		cli			; disable interrupts
		mov	ss,ax		; SS <- destination segment
		mov	es,ax		; ES <- destination segment

; ------------- Moving loader high

		mov	di,si		; DI <- offset of the boot sector
		mov	cx,100h		; CX <- 256 length of sector in words
		cld			; direction up
		rep	movsw		; moving sector up

; ------------- Jump to new boot sector

		push	es		; segment of far jump
		push	word Continue	; offset of far jump
		retf			; jump to new sector

; ------------- Load disk param table

Continue:	mov	bx,4*1eh	; address of INT 1Eh vector
		lds	si,[bx]		; DS:SI <- address of disk param table
		push	ds		; push old address DS of table
		push	si		; push old address SI of table
		mov	cl,DISKTAB_SIZE	; CX <- length of disk param table
		mov	di,DiskTab	; DI <- buffer for disk param table
		rep	movsb		; load disk param table

; From this point DS:SI (original disk param table) is pushed in the stack!!!
		
; ------------- Set address of new disk param table

		mov	ds,cx		; DS <- 0		
		mov	word [bx],DiskTab; offset of new disk table
		mov	[bx+2],es	; segment of new disk table

; ------------- Set new parameters of disk param table

		mov	ds,ax		; DS <- this segment
		mov	al,[Sectors]	; number of sectors per track
		mov	[di+4-DISKTAB_SIZE],al; number of last sector on track
		mov	byte [di+9-DISKTAB_SIZE],15 ; start-up time for floppy
		sti			; enable interrupt

; ------------- Reset disk system

		xor	ax,ax		; AX <- 0
		mov	dl,[Disk]	; DL <- disk to reset
		int	13h		; reset disk system

; ------------- Prepare to read system

		mov	bx,BOOTSEG	; BX <- start segment to read system to
		mov	si,[SectRead]	; Sectors to read
		mov	cx,2		; CL <- 2 sector, CH <- 0 cylinder
		mov	dh,0		; DH <- 0 head

; ------------- Determine number of sectors in one read

Read:		mov	di,3		; DI <- 3 error counter
		mov	ah,0		; AH <- 0
		mov	al,[Sectors]	; AL <- number of sectors per track
		inc	ax		; AL = number of sectors + 1
		sub	al,cl		; AL = sectors to the end of track
      		cmp	ax,si		; compare to sectors to read
		jbe	Read1		; number of sectors is OK
		mov	ax,si		; limit number of sectors

; ------------- Limit number of sectors to not overlap 64 KB boundary

Read1:		mov	ah,al		; AH <- number of sectors to read
		mov	bp,bx		; BP <- destination segment
		shl	bp,1
		shl	bp,1
		shl	bp,1
		shl	bp,1		; BP * 16 (offset)
		mov	al,0		; AL <- sector counter
Read2:		inc	ax		; increase number of sectors
		add	bp,SECTOR_SIZE	; add 1 sector
		jc	Read3		; next sector will be behind 64 KB
		cmp	al,ah		; will there be next sector?
		jb	Read2		; test next sector

; ------------- Push registers

Read3:		push	ax		; push AX (number of sectors to read)
		push	bx		; push BX (destination segment)
		push	cx		; push CX (sector and cylinder)
		push	dx		; push DX (head)
		push	si		; push SI (sectors to read)
		push	di		; push DI (error counter)

; ------------- Read group of sectors (AL=num, CH=cyl, CL=sect, DH=head, BX=seg)

		mov	ah,2		; function to read sectors
		mov	dl,[Disk]	; DL <- disk to read from
		mov	es,bx		; ES <- destination segment
		xor	bx,bx		; BX <- 0 destination offset
		int	13h		; read sectors

; ------------- Pop register

		pop	di		; pop DI (error counter)
		pop	si		; pop SI (sectors to read)
		pop	dx		; pop DX (head)
		pop	cx		; pop CX (sector and cylinder)
		pop	bx		; pop BX (destination segment)
		pop	ax		; pop AX (number of sectors to read)
		jc	Error		; error

; ------------- Test first data sector

		cmp	bx,BOOTSEG	; is it first data sector?
		jne	Read4		; it is not first data sector
		cmp	word [es:4],8A26h ; test identifier
		jne	ErrorLast	; error, invalid sector

; ------------- Count sectors

Read4:		mov	ah,0		; AX = number of sectors in one read
		sub	si,ax		; SI <- decrement number of sectors
		jz	AllOK		; all sectors are loaded

; ------------- Increase sector number

		add	cl,al		; CL = new sector number

; ------------- Increase destination segment

		push	cx		; push CX
		mov	cl,5		; CL <- rotations
		shl	ax,cl		; AX = segment shift
		add	bx,ax		; BX = increase segment address
		pop	cx		; pop CX

; ------------- Check destination segment

		mov	ax,cs		; AX <- this segment
		sub	ax,(SECTOR_SIZE+128)/16 ; reserve for stack
		cmp	ax,bx		; memory error?
		jbe	ErrorLast	; memory error

; ------------- Next sectors

		cmp	cl,[Sectors]	; is it last sector on track?
		jbe	Read		; there are another sectors on track
		mov	cl,1		; CL <- 1 sector of next track
		inc	dh		; DH = next head
		cmp	dh,[Heads]	; overflow number of heads?
		jb	Read		; number of head is OK
		mov	dh,0		; head on next track
		inc	ch		; CH = next cylinder
		jmp	Read		; read next sectors

; ------------- ALL OK: Return old disk param table

AllOK:		mov	dl,[Disk]	; DL <- disk number
		xor	ax,ax		; AX <- 0
		mov	ds,ax		; DS <- 0
		pop	ax		; AX <- offset of old disk param table
		mov	[4*1Eh],ax	; pop offset of old disk param table
		pop	ax		; AX <- segmnet of old disk param table
		mov	[4*1Eh+2],ax	; pop segment of old disk param table

; ------------- Kill motor of floppy disks

		push	dx		; push DX		
		mov	dx,3F2h		; DX <- diskette port
		mov	al,0		; AL <- 0
		out	dx,al		; switch motors off
		pop	dx		; pop DX

; ------------- Jump to system in memory (jump to Start in LITOS.ASM)

		push	ds		; push 0, segment of new system
		mov	ax,BOOTSEG*16	; AX <- destination segment as offset
		push	ax		; push AX, offset of new system
		retf			; jump to new system

; ------------- ERROR: next attempt

Error:		dec	di		; error counter
		jz	ErrorLast	; it was last error

; ------------- Reset disk and try again

		push	ax		; push AX (number of sectors)
		push	dx		; push DX (head)
		xor	ax,ax		; AX <- 0
		mov	dl,[Disk]	; DL <- disk to reset
		int	13h		; reset disk system
		pop	dx		; pop DX (head)
		pop	ax		; pop AX (number of sectors)
		jmp	Read3		; next attempt

; ------------- Return old disk param table

ErrorLast:	xor	ax,ax		; AX <- 0
		mov	ds,ax		; DS <- 0
		pop	ax		; AX <- offset of old disk param table
		mov	[4*1Eh],ax	; pop offset of old disk param table
		pop	ax		; AX <- segmnet of old disk param table
		mov	[4*1Eh+2],ax	; pop segment of old disk param table

; ------------- ERROR: Display error message

		push	cs		; push CS
		pop	ds		; DS <- this segment
		mov	si,Message	; information message
NextChar:	cld			; set direction up
		lodsb			; AL <- load next character from DS:SI
		or	al,al		; AL == 0? (is it end of text?)
		jz	KeyPress	; end of text
		mov	ah,0eh		; AH <- function code		
		mov	bx,7		; BL <- color of text, BH <- page 0
		push	si		; push SI
		int	10h		; print character
		pop	si		; pop SI
		jmp	short NextChar	; next character

; ------------- ERROR: Waiting for a key

KeyPress:	mov	ah,0		; AH <- function code
		int	16h		; waiting for a key

; ------------- ERROR: Repeat booting

		int	19h		; repeat booting

; ------------- Align to sector size

		times 512 - 2 - ($ - Start) db	0

		dw	0aa55h		; Boot sector magic

Back to source browser