This commit was generated by cvs2svn to compensate for changes in r10,
[reactos.git] / reactos / loaders / boot / osldr.asm
index f43af30..0915d18 100644 (file)
-;\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