; 1. Setup stack and datasegment ; 2. Check for a 32 bit CPU ; 3. Get info from the booted drive ; 4. Check on which CHS the bootsector is ; 5. Load all System sectors ; 6. Set the correct values ; 7. jump to System ; changed by LTH, EKS, VP ; CHS positions and disk numbers are usually stored in cx and dx: ; ch = cylinder ; cl = sector and high cylinder ; dh = head ; dl = disk ;07/07/2000: bl=Boot Partition number [ML] bits 16 org 7C00h jmp Begin FILLBYTES align 8, db 255 SIGNATURE db '+V2_FS+', 0 ; 8 FS_VERSION db '001.001', 0 ; 16 MAXOBJECTS dd 128 ; 24 CUROBJECTS dd 0 ; 28 MAXSECTORS dd 000000B40H ; 32 0b40h-for fd, was a 011223344H FIRST_AVAILABLE dd 16 ; 36 SECTORS4SYSTEM16 db 0 ; 40 SECTORS4SYSTEM32 db 0 ; 41 FIRSTDATASECTOR dd 0 ; 42 V2OS db 13, 10, 'V2-OS', 0 LOADOK db 'Ok', 13, 10, 0 WrongCPUMsg db '32 bit processor required.', 0 BadPartTableMsg db 13, 10, 'Could not find the boot partition', 0 ErrorMsg db 13, 10 db 13, 10, 'di=', 0 db 13, 10, 'si=', 0 db 13, 10, 'bp=', 0 db 13, 10, 'sp=', 0 db 13, 10, 'bx=', 0 db 13, 10, 'dx=', 0 db 13, 10, 'cx=', 0 db 13, 10, 'ax=', 0 HexDigits db '0123456789ABCDEF' MAXSECTOR db 0 MAXHEAD db 0 ;---------------------------------------------------------------------------- ; In: cx, dh = CHS ; Out: cx, dh = new CHS ; Corrupted: al IncreaseCHS: mov al, cl ; DL contains the high cylinder and cl, 00111111b ; Kill the high cylinder stuff and al, 11000000b ; Kill the sector stuff inc cl ; Increase the sector cmp cl, [MAXSECTOR] ; Check Sector jna SectorStillOK mov cl, 1 ; Sector=1, increase head (sectors start at 1, not at zero!) inc dh cmp dh, [MAXHEAD] jna HeadStillOK mov dh, 0 ; Head=0, increase cylinder (heads start at 0) inc ch jno NoCylinderOverflow add al, 01000000b ; increase high cylinder NoCylinderOverflow: HeadStillOK: SectorStillOK: or cl, al ; Merge the high-cylinder and the sector ret ;---------------------------------------------------------------------------- ; In: es:di = Buffer ; si = Nr of sectors to read ; cx,dx = CHS and disk of the first sector ; Out: es:di = end of the data in the buffer ; cx,dx = CHS and disk of the next sector ; Corrupted: ax, bx, si, bp ReadSectors: mov bp, 10 jmp short ReadLoop RetryRead: dec bp jz Error mov ah, 0 ; Reset drive int 13h jc Error ReadLoop: mov bx, di mov ax, 0201h ; Read sectors int 13h jc RetryRead mov ax, 0e2eh ; Print a dot xor bx, bx int 10h call IncreaseCHS add di, 512 ; Get next sector dec si jnz ReadLoop ret ;---------------------------------------------------------------------------- ; In: cl = byte to display ; Corrupted: ax, bx, di, bp WriteHexByte: mov ah, 0eh ; Teletype output xor bx, bx ; Page 0, color 0 shld di, cx, 12 ; load high nibble into di and di, 15 mov al, [HexDigits + di] ; al = hex digit corresponding to di int 10h ; write it mov di, cx ; same procedure with the low nibble and di, 15 mov al, [HexDigits + di] int 10h ret ;---------------------------------------------------------------------------- ; In: ds:si = Zero terminated message ; Out: ds:si = next message (if starting after the displayed message) ; Corrupted: ax, bx, bp WriteMsg: mov ah, 0Eh ; Teletype output xor bx, bx ; Page 0, color 0 jmp short StartLoop NextLetter: int 10h ; 2nd, print it StartLoop: lodsb ; 1st, load next letter or al, al jnz NextLetter ret ;---------------------------------------------------------------------------- ; In: ah = error code Error: pusha mov si, ErrorMsg mov dl, 8 .loop call WriteMsg pop cx xchg cl, ch call WriteHexByte xchg cl, ch call WriteHexByte dec dl jnz .loop jmp short $ ;---------------------------------------------------------------------------- ; In: dl = bootdisk ; Out: Begin: cli ; Dont interrupt this xor ax,ax mov ds,ax ; Set the data segment to 0, (we use an offset of 7C00h) mov ss,ax ; StackSegment is zero too mov sp, 7C00h ; Stack grows downwards ; A small CPU check to determine if we run on a 386 ; see http://www.ddj.com/articles/1996/9611/9611n/9611n.htm for details push sp pop ax cmp ax, sp je AtLeast286 WrongCPU: mov si, WrongCPUMsg call WriteMsg jmp short $ AtLeast286: mov word [18h], WrongCPU ; install an exception handler mov [1ah], cs cwde ; and try out a 32 bit instruction push dx ; Save bootdisk mov ah,8 ; and get some information about it int 13h jc Error and cl, 00111111b ; we don't check cylinders mov [MAXSECTOR], cl mov [MAXHEAD], dh mov ah,0 ; Reset the bootdrive pop dx int 13h jc Error mov si, V2OS call WriteMsg mov ax, 60h ; The segment is used as disk buffer mov es, ax ; We don't know where System is at this point, so we have to find it out. ; If we have booted from floppy, it will be at 0:0:2 (chs) right after the ; bootsector. If we booted from HD, we must get the CHS from the partition ; table, In order to get the partition of which we have booted, we must look ; for an active V2OS-parition (ID=33h). ; BTW: the partition ID 33h is reserved. It's very likely that one of ; future FAT file systems will use it. mov cx, 1 ; cx and dx point to the first sector mov dh, 0 ; on the boot disk or dl, dl jns LoadSystem ; Since floppies are not partitioned, ; we can directly read System if we ; boot from a floppy. ; Booted from HD ; We need to load the partitiontable by loading the MBR into memory xor di, di ; The MBR will be overwritten later mov si, cx call ReadSectors mov si, 512-2-64 ; Point to the partitiontable mov cx, 4 FindBootPartition: test byte [es:si], 80h ; Check if this partition is active jz FindNext cmp byte [es:si + 4], 33h ; Check if it got the correct ID je FoundThePartition FindNext: add si,16 ; Point to the next partition entry loop FindBootPartition mov si, BadPartTableMsg call WriteMsg jmp short $ FoundThePartition mov bx,5 ;[ML] sub bl, cl ; partition number mov cx, [es:si + 2] ; Get CHS from the partition table mov dh, [es:si + 1] LoadSystem: ; cx and dx are set properly. Save this info before loading System push bx ;[ML] push cx ; Save sector, head, cylinder and disk push dx ; of the bootsector call IncreaseCHS ; skip the bootsector xor di, di ; Load System at 0600h (es is still 60h) movzx si, [SECTORS4SYSTEM16] call ReadSectors mov si, LOADOK call WriteMsg ; This info is needed before jumping to System. pop dx ; Retrieve stack-saved cylinder, head, sector pop cx ; and disk pop bx ; and partition[ML] ; System prefers cl=cylinder and ch=sector, switch them before entering System ; xchg cl,ch jmp 0050h:0100h ; Pad this bootsector out to 512 bytes. Generates a compiler error if the bootsector >512b ;LTH - if ya want to see the size of the code then comment out ;the next line (the times line) times 512-2-($-$$) db 90h dw 0AA55h ; Write boot signature