xref: /reactos/boot/freeldr/bootsect/dosmbr.S (revision d2aeaba5)
1/*
2 * COPYRIGHT:       See COPYING in the top level directory
3 * PROJECT:         ReactOS Bootsector for ISO file system
4 * PURPOSE:         Normal DOS boot sector
5 *                  Ported to NASM from FreeDOS fdisk 1.2.0 by:
6 * PROGRAMMERS:     Casper Hornstrup (chorns@users.sourceforge.net)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <asm.inc>
12
13//-----------------------------------------------------------------------
14//   ENTRY (copied from freedos bootsector)
15//
16// IN: DL = boot drive
17// OUT: DL = boot drive
18//
19//-----------------------------------------------------------------------
20
21.code16
22real_start:
23    cli
24    cld
25    xor ax, ax
26    mov ss, ax          // initialize stack
27    mov ds, ax
28    mov bp, HEX(7c00)
29    lea sp, [bp-32]
30    sti
31
32    /* Copy 512 bytes of MBR to 1fe0:7c00 */
33    mov ax, HEX(1FE0)
34    mov es, ax
35    mov si, bp
36    mov di, bp
37    mov cx, 256
38    rep movsw
39
40    /* Jump into relocated code */
41    ljmp16 HEX(1FE0), cont
42cont:
43
44    /* Setup segment registers */
45    mov ds, ax
46    mov ss, ax
47    xor ax, ax
48    mov es, ax
49
50    /* Search for active partition */
51    lea di, [bp + HEX(1be)] // start of partition table
52test_next_for_active:
53    test byte ptr ds:[di], HEX(80)
54    jne active_partition_found
55    add di, 16                    // next table
56    cmp di, HEX(07c00) + HEX(1fe) // scanned beyond end of table ??
57    jb test_next_for_active
58
59/*****************************************************************/
60    call print
61    .asciz "No active partition found"
62
63WAIT_FOR_REBOOT:
64    jmp WAIT_FOR_REBOOT
65
66
67/*****************************************************************/
68trouble_reading_drive:
69    call print
70    .asciz "Read error while reading drive"
71    jmp WAIT_FOR_REBOOT
72
73/*****************************************************************/
74
75invalid_partition_code:
76    call print
77    .asciz "Partition signature != 55AA"
78
79    jmp WAIT_FOR_REBOOT
80
81/*****************************************************************/
82
83active_partition_found:
84//  call print
85//  .asciz "Loading active partition"
86
87    call read_boot_sector
88
89    jc  trouble_reading_drive
90
91    cmp word ptr es:[HEX(7c00)+HEX(1fe)], HEX(0aa55)
92    jne invalid_partition_code
93
94    ljmp16 0, HEX(7c00)            // and jump to boot sector code
95
96/*****************************
97 * read_boot_sector
98 *
99 * IN: DI--> partition info
100 * OUT:CARRY
101 *****************************/
102read_boot_sector:
103    /* check for LBA support */
104    mov bx, HEX(55aa)
105    mov ah, HEX(41)
106    int HEX(13)
107
108    jc  StandardBios    //  if (regs.b.x != 0xaa55 || (regs.flags & 0x01))
109    cmp bx, HEX(0aa55)  //    goto StandardBios;
110    jne StandardBios
111
112    /* if DAP cannot be used, don't use LBA
113       if ((regs.c.x & 1) == 0)
114           goto StandardBios; */
115    test cl, 1
116    jz StandardBios
117
118    jmp short LBABios
119
120
121_bios_LBA_address_packet:
122    .byte 16
123    .byte 0
124    .byte 4         // read four sectors - why not
125    .byte 0
126    .word HEX(7c00) // fixed boot address for DOS sector
127    .word HEX(0000)
128
129_bios_LBA_low:
130    .word 0
131_bios_LBA_high:
132    .word 0
133    .word 0,0
134
135
136LBABios:
137    // copy start address of partition to DAP
138    mov ax, [di + 8]
139    mov word ptr ds:[_bios_LBA_low], ax
140    mov ax,[di + 8 + 2]
141    mov word ptr ds:[_bios_LBA_high], ax
142
143    mov ax, HEX(4200)    //  regs.a.x = LBA_READ;
144    mov si, offset _bios_LBA_address_packet // regs.si = FP_OFF(&dap);
145
146    int HEX(13)
147    ret
148
149/*****************************************************************
150 * read disk, using standard BIOS
151 */
152StandardBios:
153    mov ax, HEX(0204)               //  regs.a.x = 0x0201;
154    mov bx, HEX(7c00)               //  regs.b.x = FP_OFF(buffer);
155
156    /* regs.c.x =
157       ((chs.Cylinder & 0xff) << 8) + ((chs.Cylinder & 0x300) >> 2) +
158        ; chs.Sector;
159         that was easy ;-) */
160    mov cx, word ptr ds:[di + 2]
161    mov dh, byte ptr ds:[di + 1]    //  regs.d.b.h = chs.Head;
162                                    //  regs.es = FP_SEG(buffer);
163    int HEX(13)
164    ret
165
166/****** PRINT
167 * prints text after call to this function.
168 */
169print_1char:
170    xor bx, bx                   // video page 0
171    mov ah, HEX(0E)              // else print it
172    int HEX(10)                  // via TTY mode
173print:
174    pop si                       // this is the first character
175print1:
176    lodsb                        // get token
177    push si                      // stack up potential return address
178    cmp al, 0                    // end of string?
179    jne print_1char              // until done
180    ret                          // and jump to it
181
182.org 510
183    .byte HEX(55), HEX(0aa)
184
185.endcode16
186
187END
188