-;\r
-; Loads the kernel and any required modules\r
-;\r
-\r
-org 0\r
-\r
-;\r
-; Segment where we are loaded\r
-;\r
-LOADSEG equ 02000h\r
-\r
-;\r
-; Segment used for temporay storage\r
-;\r
-WORKSEG equ 01000h\r
-\r
-\r
-KERNELBASE equ 05000h\r
-\r
-;\r
-; Offsets of work areas\r
-;\r
-FAT_CHAIN equ 0h\r
-\r
-DIR_BUFFER equ 4000h\r
-END_DIR_BUFFER equ 0ffe0h\r
-\r
-FAT_SEG equ 03000h\r
-\r
-\r
-;\r
-; These are all on the stack\r
-;\r
-%define oem [bp+3]\r
-%define bytesPerSector [bp+0bh]\r
-%define sectPerCluster [bp+0dh]\r
-%define resSectors [bp+0eh]\r
-%define nFats [bp+10h]\r
-%define nRootDir [bp+11h]\r
-%define nSectors [bp+13h]\r
-%define MID [bp+15h]\r
-%define sectPerFat [bp+16h]\r
-%define sectPerTrack [bp+18h]\r
-%define nHeads [bp+1ah]\r
-%define nHidden [bp+1ch]\r
-%define nHidden_hi [bp+1eh]\r
-%define nSectorHuge [bp+20h]\r
-%define drive [bp+24h]\r
-%define extBoot [bp+26h]\r
-%define volid [bp+27h]\r
-%define vollabel [bp+2bh]\r
-%define filesys 36h\r
-\r
-RETRYCOUNT equ 5\r
-\r
-%define fat_start [bp-4] ; first FAT sector\r
-%define fat_start_hi [bp-2]\r
-%define root_dir_start [bp-8] ; first root directory sector\r
-%define root_dir_start_hi [bp-6]\r
-%define data_start [bp-12] ; first data sector\r
-%define data_start_hi [bp-10]\r
-\r
-\r
-entry:\r
- mov drive,dl\r
- \r
- mov ax,LOADSEG\r
- mov ds,ax\r
-\r
-\r
- ;\r
- ; Print out a message\r
- ;\r
- mov di,loadmsg\r
- call printmsg\r
-\r
-\r
- ;\r
- ; Check here for shift pressed and if so display boot menu\r
- ;\r
-\r
- ;\r
- ; Load the entire fat\r
- ;\r
-; mov ax,fat_start\r
-; mov dx,fat_start_hi\r
-; mov di,sectPerFat\r
-; mov ax,FAT_SEG\r
-; mov es,ax\r
-; mov bx,0\r
-; call readDisk\r
-\r
-\r
- ;\r
- ; Load root directory\r
- ;\r
- mov ax,WORKSEG\r
- mov es,ax\r
-\r
- mov dx,root_dir_start_hi\r
- mov ax,root_dir_start\r
- mov bx,DIR_BUFFER\r
- mov di,nRootDir\r
- shr di,4\r
- mov di,1\r
- call readDisk\r
- jc disk_error\r
-\r
- ;\r
- ; Look for a directory called boot\r
- ; \r
- mov di,DIR_BUFFER\r
- cld\r
- mov cx,4\r
-l1:\r
- mov si,boot_dir_name\r
-; cmp byte [di],0\r
-; je boot_error\r
- repe cmpsb\r
- je found_it\r
- or di,31\r
- inc di\r
- cmp di,END_DIR_BUFFER\r
- jge boot_error\r
- jmp l1\r
-\r
-\r
-boot_error:\r
- mov di,errormsg\r
- call printmsg\r
-l3:\r
- jmp l3\r
-\r
-disk_error:\r
- mov di,errormsg1\r
- call printmsg\r
- jmp l3\r
-\r
-\r
-\r
-found_it:\r
- mov di,msg1\r
- call printmsg\r
-\r
- ;\r
- ; Load the boot directory found above\r
- ;\r
- sub di,4\r
- call readFile\r
-\r
-l2:\r
- jmp l2\r
-\r
-;\r
-; readFile\r
-;\r
-%define file_length [di+01ch]\r
-%define start_cluster [di+01ah]\r
-readFile:\r
- cmp byte extBoot, 29h\r
- jne fat_12\r
- cmp byte [bp+filesys+4], '6' ; check for FAT-16 system\r
- je fat_16\r
-\r
-fat_12:\r
- mov di,msg2\r
- call printmsg\r
-l4:\r
- jmp l4\r
-\r
-fat_16:\r
- mov di,msg3\r
- call printmsg\r
- jmp l4\r
- \r
- \r
-\r
-; readDisk: Reads a number of sectors into memory.\r
-;\r
-; Call with: DX:AX = 32-bit DOS sector number\r
-; DI = number of sectors to read\r
-; ES:BX = destination buffer\r
-; ES must be 64k aligned (1000h, 2000h etc).\r
-;\r
-; Returns: CF set on error\r
-; ES:BX points one byte after the last byte read. \r
-\r
-readDisk:\r
- push bp\r
- push si\r
-read_next: push dx\r
- push ax\r
-\r
- ;\r
- ; translate sector number to BIOS parameters\r
- ;\r
-\r
- ;\r
- ; abs = sector offset in track\r
- ; + head * sectPerTrack offset in cylinder\r
- ; + track * sectPerTrack * nHeads offset in platter\r
- ; \r
- ; t1 = abs / sectPerTrack (ax has t1)\r
- ; sector = abs mod sectPerTrack (cx has sector)\r
- ;\r
- div word sectPerTrack\r
- mov cx, dx\r
-\r
- ;\r
- ; t1 = head + track * nHeads\r
- ;\r
- ; track = t1 / nHeads (ax has track)\r
- ; head = t1 mod nHeads (dl has head)\r
- ;\r
- xor dx, dx\r
- div word nHeads\r
-\r
- ; the following manipulations are necessary in order to \r
- ; properly place parameters into registers.\r
- ; ch = cylinder number low 8 bits\r
- ; cl = 7-6: cylinder high two bits\r
- ; 5-0: sector\r
- mov dh, dl ; save head into dh for bios\r
- ror ah, 1 ; move track high bits into\r
- ror ah, 1 ; bits 7-6 (assumes top = 0)\r
- xchg al, ah ; swap for later\r
- mov dl, byte sectPerTrack\r
- sub dl, cl\r
- inc cl ; sector offset from 1\r
- or cx, ax ; merge cylinder into sector\r
- mov al, dl ; al has # of sectors left\r
-\r
- ; Calculate how many sectors can be transfered in this read\r
- ; due to dma boundary conditions.\r
- push dx\r
-\r
- mov si, di ; temp register save\r
- ; this computes remaining bytes because of modulo 65536\r
- ; nature of dma boundary condition\r
- mov ax, bx ; get offset pointer\r
- neg ax ; and convert to bytes\r
- jz ax_min_1 ; started at seg:0, skip ahead\r
-\r
- xor dx, dx ; convert to sectors\r
- div word bytesPerSector\r
- \r
- cmp ax, di ; check remainder vs. asked\r
- jb ax_min_1 ; less, skip ahead\r
- mov si, ax ; transfer only what we can\r
-\r
-ax_min_1: pop dx\r
-\r
- ; Check that request sectors do not exceed track boundary\r
- mov si, sectPerTrack\r
- inc si\r
- mov ax, cx ; get the sector/cyl byte\r
- and ax, 03fh ; and mask out sector\r
- sub si, ax ; si has how many we can read\r
- mov ax, di\r
- cmp si, di ; see if asked <= available\r
- jge ax_min_2\r
- mov ax, si ; get what can be xfered\r
-\r
-ax_min_2: mov si, RETRYCOUNT\r
- mov ah, 2\r
- mov dl, drive\r
-\r
-retry: push ax\r
- int 13h\r
- pop ax\r
- jnc read_ok\r
- push ax\r
- xor ax, ax ; reset the drive\r
- int 13h\r
- pop ax\r
- dec si\r
- jnz retry\r
- stc\r
- pop ax\r
- pop dx\r
- pop si\r
- pop bp\r
- ret\r
-\r
-read_next_jmp: jmp short read_next\r
-read_ok: xor ah, ah \r
- mov si, ax ; AX = SI = number of sectors read \r
- mul word bytesPerSector ; AX = number of bytes read\r
- add bx, ax ; add number of bytes read to BX\r
- jnc no_incr_es ; if overflow...\r
-\r
- mov ax, es \r
- add ah, 10h ; ...add 1000h to ES\r
- mov es, ax\r
- \r
-no_incr_es: pop ax\r
- pop dx ; DX:AX = last sector number\r
-\r
- add ax, si\r
- adc dx, 0 ; DX:AX = next sector to read\r
- sub di, si ; if there is anything left to read,\r
- jg read_next_jmp ; continue\r
-\r
- clc\r
- pop si\r
- pop bp\r
- ret\r
-\r
-;\r
-; Print string (DI = start) \r
-;\r
-printmsg:\r
- push ax\r
- push bx\r
- push di\r
- mov ah,0eh\r
- mov bh,0\r
- mov bl,07h\r
-.l1\r
- mov al,[di]\r
- cmp al,0\r
- je .l2\r
- inc di\r
- int 10h\r
- jmp .l1\r
-.l2\r
- pop di\r
- pop bx\r
- pop ax\r
- ret\r
-\r
-\r
-\r
-loadmsg db "Starting ReactOS...",0xd,0xa,0\r
-boot_dir_name db 'BOOT'\r
-errormsg db "Files missing on boot disk",0\r
-errormsg1 db "Disk read error",0\r
-msg1 db "Found boot directory",0xd,0xa,0\r
-msg2 db 'FAT12',0\r
-msg3 db 'FAT16',0\r
+;
+; Loads the kernel and any required modules
+;
+
+org 0
+
+;
+; Segment where we are loaded
+;
+LOADSEG equ 02000h
+
+;
+; Segment used for temporay storage
+;
+WORKSEG equ 01000h
+
+
+KERNELBASE equ 05000h
+
+;
+; Offsets of work areas
+;
+FAT_CHAIN equ 0h
+
+DIR_BUFFER equ 4000h
+END_DIR_BUFFER equ 0ffe0h
+
+FAT_SEG equ 03000h
+
+
+;
+; These are all on the stack
+;
+%define oem [bp+3]
+%define bytesPerSector [bp+0bh]
+%define sectPerCluster [bp+0dh]
+%define resSectors [bp+0eh]
+%define nFats [bp+10h]
+%define nRootDir [bp+11h]
+%define nSectors [bp+13h]
+%define MID [bp+15h]
+%define sectPerFat [bp+16h]
+%define sectPerTrack [bp+18h]
+%define nHeads [bp+1ah]
+%define nHidden [bp+1ch]
+%define nHidden_hi [bp+1eh]
+%define nSectorHuge [bp+20h]
+%define drive [bp+24h]
+%define extBoot [bp+26h]
+%define volid [bp+27h]
+%define vollabel [bp+2bh]
+%define filesys 36h
+
+RETRYCOUNT equ 5
+
+%define fat_start [bp-4] ; first FAT sector
+%define fat_start_hi [bp-2]
+%define root_dir_start [bp-8] ; first root directory sector
+%define root_dir_start_hi [bp-6]
+%define data_start [bp-12] ; first data sector
+%define data_start_hi [bp-10]
+
+
+entry:
+ mov drive,dl
+
+ mov ax,LOADSEG
+ mov ds,ax
+
+
+ ;
+ ; Print out a message
+ ;
+ mov di,loadmsg
+ call printmsg
+
+
+ ;
+ ; Check here for shift pressed and if so display boot menu
+ ;
+
+ ;
+ ; Load the entire fat
+ ;
+; mov ax,fat_start
+; mov dx,fat_start_hi
+; mov di,sectPerFat
+; mov ax,FAT_SEG
+; mov es,ax
+; mov bx,0
+; call readDisk
+
+
+ ;
+ ; Load root directory
+ ;
+ mov ax,WORKSEG
+ mov es,ax
+
+ mov dx,root_dir_start_hi
+ mov ax,root_dir_start
+ mov bx,DIR_BUFFER
+ mov di,nRootDir
+ shr di,4
+ mov di,1
+ call readDisk
+ jc disk_error
+
+ ;
+ ; Look for a directory called boot
+ ;
+ mov di,DIR_BUFFER
+ cld
+ mov cx,4
+l1:
+ mov si,boot_dir_name
+; cmp byte [di],0
+; je boot_error
+ repe cmpsb
+ je found_it
+ or di,31
+ inc di
+ cmp di,END_DIR_BUFFER
+ jge boot_error
+ jmp l1
+
+
+boot_error:
+ mov di,errormsg
+ call printmsg
+l3:
+ jmp l3
+
+disk_error:
+ mov di,errormsg1
+ call printmsg
+ jmp l3
+
+
+
+found_it:
+ mov di,msg1
+ call printmsg
+
+ ;
+ ; Load the boot directory found above
+ ;
+ sub di,4
+ call readFile
+
+l2:
+ jmp l2
+
+;
+; readFile
+;
+%define file_length [di+01ch]
+%define start_cluster [di+01ah]
+readFile:
+ cmp byte extBoot, 29h
+ jne fat_12
+ cmp byte [bp+filesys+4], '6' ; check for FAT-16 system
+ je fat_16
+
+fat_12:
+ mov di,msg2
+ call printmsg
+l4:
+ jmp l4
+
+fat_16:
+ mov di,msg3
+ call printmsg
+ jmp l4
+
+
+
+; readDisk: Reads a number of sectors into memory.
+;
+; Call with: DX:AX = 32-bit DOS sector number
+; DI = number of sectors to read
+; ES:BX = destination buffer
+; ES must be 64k aligned (1000h, 2000h etc).
+;
+; Returns: CF set on error
+; ES:BX points one byte after the last byte read.
+
+readDisk:
+ push bp
+ push si
+read_next: push dx
+ push ax
+
+ ;
+ ; translate sector number to BIOS parameters
+ ;
+
+ ;
+ ; abs = sector offset in track
+ ; + head * sectPerTrack offset in cylinder
+ ; + track * sectPerTrack * nHeads offset in platter
+ ;
+ ; t1 = abs / sectPerTrack (ax has t1)
+ ; sector = abs mod sectPerTrack (cx has sector)
+ ;
+ div word sectPerTrack
+ mov cx, dx
+
+ ;
+ ; t1 = head + track * nHeads
+ ;
+ ; track = t1 / nHeads (ax has track)
+ ; head = t1 mod nHeads (dl has head)
+ ;
+ xor dx, dx
+ div word nHeads
+
+ ; the following manipulations are necessary in order to
+ ; properly place parameters into registers.
+ ; ch = cylinder number low 8 bits
+ ; cl = 7-6: cylinder high two bits
+ ; 5-0: sector
+ mov dh, dl ; save head into dh for bios
+ ror ah, 1 ; move track high bits into
+ ror ah, 1 ; bits 7-6 (assumes top = 0)
+ xchg al, ah ; swap for later
+ mov dl, byte sectPerTrack
+ sub dl, cl
+ inc cl ; sector offset from 1
+ or cx, ax ; merge cylinder into sector
+ mov al, dl ; al has # of sectors left
+
+ ; Calculate how many sectors can be transfered in this read
+ ; due to dma boundary conditions.
+ push dx
+
+ mov si, di ; temp register save
+ ; this computes remaining bytes because of modulo 65536
+ ; nature of dma boundary condition
+ mov ax, bx ; get offset pointer
+ neg ax ; and convert to bytes
+ jz ax_min_1 ; started at seg:0, skip ahead
+
+ xor dx, dx ; convert to sectors
+ div word bytesPerSector
+
+ cmp ax, di ; check remainder vs. asked
+ jb ax_min_1 ; less, skip ahead
+ mov si, ax ; transfer only what we can
+
+ax_min_1: pop dx
+
+ ; Check that request sectors do not exceed track boundary
+ mov si, sectPerTrack
+ inc si
+ mov ax, cx ; get the sector/cyl byte
+ and ax, 03fh ; and mask out sector
+ sub si, ax ; si has how many we can read
+ mov ax, di
+ cmp si, di ; see if asked <= available
+ jge ax_min_2
+ mov ax, si ; get what can be xfered
+
+ax_min_2: mov si, RETRYCOUNT
+ mov ah, 2
+ mov dl, drive
+
+retry: push ax
+ int 13h
+ pop ax
+ jnc read_ok
+ push ax
+ xor ax, ax ; reset the drive
+ int 13h
+ pop ax
+ dec si
+ jnz retry
+ stc
+ pop ax
+ pop dx
+ pop si
+ pop bp
+ ret
+
+read_next_jmp: jmp short read_next
+read_ok: xor ah, ah
+ mov si, ax ; AX = SI = number of sectors read
+ mul word bytesPerSector ; AX = number of bytes read
+ add bx, ax ; add number of bytes read to BX
+ jnc no_incr_es ; if overflow...
+
+ mov ax, es
+ add ah, 10h ; ...add 1000h to ES
+ mov es, ax
+
+no_incr_es: pop ax
+ pop dx ; DX:AX = last sector number
+
+ add ax, si
+ adc dx, 0 ; DX:AX = next sector to read
+ sub di, si ; if there is anything left to read,
+ jg read_next_jmp ; continue
+
+ clc
+ pop si
+ pop bp
+ ret
+
+;
+; Print string (DI = start)
+;
+printmsg:
+ push ax
+ push bx
+ push di
+ mov ah,0eh
+ mov bh,0
+ mov bl,07h
+.l1
+ mov al,[di]
+ cmp al,0
+ je .l2
+ inc di
+ int 10h
+ jmp .l1
+.l2
+ pop di
+ pop bx
+ pop ax
+ ret
+
+
+
+loadmsg db "Starting ReactOS...",0xd,0xa,0
+boot_dir_name db 'BOOT'
+errormsg db "Files missing on boot disk",0
+errormsg1 db "Disk read error",0
+msg1 db "Found boot directory",0xd,0xa,0
+msg2 db 'FAT12',0
+msg3 db 'FAT16',0