
%include "bootdef.inc"

[bits 16]

org 0x7c00

	jmp short start

; --------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag     DB      90H             ; 0002h - 0EH for INT13 AH=42 READ
brOEM           DB      'MSDOS5.0'      ; 0003h - OEM ID - Windows 95B
brBPS           DW      512             ; 000Bh - Bytes per sector
brSPC           DB      1               ; 000Dh - Sector per cluster
brSc_b4_fat	DW      1               ; 000Eh - Reserved sectors
brFATs          DB      2               ; 0010h - FAT copies
brRootEntries   DW      0E0H		; 0011h - Root directory entries
brSectorCount   DW      2880		; 0013h - Sectors in volume, < 32MB
brMedia         DB      240		; 0015h - Media descriptor
brSPF           DW      9               ; 0016h - Sectors per FAT
brSc_p_trk	DW      18              ; 0018h - Sectors per head/track
brHPC           DW      2		; 001Ah - Heads per cylinder
brSc_b4_prt	DD      0               ; 001Ch - Hidden sectors
brSectors       DD      0	        ; 0020h - Total number of sectors
brDrive		DB      0               ; 0024h - Physical drive no.
		DB      0               ; 0025h - Reserved (FAT32)
		DB      29H             ; 0026h - Extended boot record sig (FAT32)
brSerialNum     DD      404418EAH       ; 0027h - Volume serial number
brLabel         DB      'Holtrops OS'   ; 002Bh - Volume label
brFSID          DB      'FAT12   '      ; 0036h - File System ID
;------------------------------------------------------------------------

start:
	jmp	0:jmphere		;ensure that cs=0 and ip=0x7c00...
jmphere:
	;dl=drive number, save it!
	xor	ax, ax
	mov	ds, ax
	mov	[brDrive], dl
	cli
	mov	ss, ax
	mov	sp, 0x7Bfe		;right under boot sector
	sti

	mov	ax, 0xb800
	mov	ds, ax
	mov	es, ax

	xor	di, di
	mov	ax, 0x0700
	mov	cx, 2000
cls:
	stosw
	loop	cls

enable_a20:
	in	al, 0x64
	test	al, 2
	jnz	enable_a20
	mov	al, 0xD1
	out	0x64, al
ea20_2:	in	al, 0x64
	and	ax, byte 2
	jnz	ea20_2
	mov	al, 0xDF
	out	0x60, al

unreal:
	xor	ax, ax
	mov	es, ax
	mov	ds, ax

	lgdt	[gdtr]		;load gdt
	cli
	push	es
	push	ds		;save segment values
	mov	ebx, cr0
	inc	bl
	mov	cr0, ebx	;pmode!
	mov	ax, KERNEL_DATA
	mov	es, ax
	mov	ds, ax		;load segment limits
	dec	bl
	mov	cr0, ebx	;back to real mode!
	pop	ds
	pop	es		;segments back, with 4gb limits!
	sti

;now lets read in the FAT and root directory so we can search for the stage2 file...
	mov	ax, 0x0209		;FAT1
	mov	cx, 0x0002
	xor	dh, dh
	mov	dl, [brDrive]
	mov	bx, BOOT_FAT_SEG
	mov	es, bx
	xor	bx, bx
	int	0x13

	mov	ax, 0x020E		;root directory
	mov	cx, 0x0002		;cyl/sect
	mov	dh, 0x01		;head
	mov	dl, [brDrive]		;drive
	mov	bx, BOOT_ROOT_SEG
	mov	es, bx
	xor	bx, bx
	int	0x13

;k now read root directory
	mov	bx, BOOT_ROOT_SEG
	mov	ds, bx
	xor	si, si			;k now ds:si points to beginning of root directory
	mov	es, si
	mov	cx, 224			;max root entries
loop_compare:
	mov	di, stage2
	push	cx
	push	si			;save pointer to root dir entry
	mov	cx, 11
loop_name:
	cmpsb
	loopz	loop_name
	jnz	goon			;cx didn't get to zero, bad file
	pop	si
	pop	cx
	jmp	found_file		;good file, ds:si points to start of root directory entry
goon:
	pop	si
	pop	cx
	add	si, 32
	loop	loop_compare

error:
	jmp	$			;halt! no kernel file found!

found_file:				;ds:si points to root dir entry
	xor	ax, ax
	mov	gs, ax
	mov	ax, BOOT_STAGE2_SEG
	mov	es, ax

	mov	ax, [ds:si+26]
	mov	bx, BOOT_FAT_SEG
	mov	ds, bx			;ds points to beginning of FAT
	xor	di, di

readstage2_loop:
	cmp	ax, 0xff7
	jg	readstage2_done
	inc	di
	push	ax
	call	getCHSfromCluster
	mov	ax, 0x0201
	mov	dl, [gs:BOOT_DRIVE]
	xor	bx, bx
	int	0x13
	mov	bx, es
	add	bx, 0x0020
	mov	es, bx
	pop	ax			;current logical cluster #

	mov	cx, ax			;cx=logical cluster
	mov	dx, 3
	mul	dx
	shr	ax, 1			;ax=logical cluster * 3 / 2
	mov	si, ax
	test	cl, 1			;is bit0 set?
	jnz	odd_cluster
even_cluster:
	lodsw
	and	ax, 0x0fff
	jmp	got_cluster
odd_cluster:
	lodsw
	shr	ax, 4
got_cluster:
	jmp	readstage2_loop

readstage2_done:

	jmp	0:BOOT_STAGE2_ADD

;------------------------------------------------------
getCHSfromCluster:
	;input: ax=lba of sector on floppy (0-2879)
	add	ax, 31			;convert logical cluster# to lba#
	xor	dx, dx			;lba->chs
	mov	bx, 18
	div	bx
	inc	dx
	mov	cl, dl			;sector# (1-18)
	xor	dx, dx
	mov	bx, 2
	div	bx
	mov	ch, al			;cylinder# (0-79)
	mov	dh, dl			;head# (0-1)
	ret


;-------------------------------------------------------
gdtr:
	dw	gdt_end-gdt-1
	dd	gdt
gdt:
	dd	0
	dd	0

KERNEL_DATA equ $-gdt
	db	0xff		;segment 16 = 4gb data
	db	0xff
	db	0x00
	db	0x00
	db	0x00
	db	0x92
	db	0xcf		;cf
	db	0x00

gdt_end:



stage2:	db	"STAGE2  BIN"

times 510-($-$$)	db 0

db	0x55, 0xaa

