:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / loaders / boot / boot.asm
1 ;
2 ; File:
3 ;                            boot.asm
4 ; Description:
5 ;                           DOS-C boot
6 ;
7 ;                       Copyright (c) 1997;                     
8 ;                           Svante Frey
9 ;                       All Rights Reserved
10 ;
11 ; This file is part of DOS-C.
12 ;
13 ; DOS-C is free software; you can redistribute it and/or
14 ; modify it under the terms of the GNU General Public License
15 ; as published by the Free Software Foundation; either version
16 ; 2, or (at your option) any later version.
17 ;
18 ; DOS-C is distributed in the hope that it will be useful, but
19 ; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
21 ; the GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public
24 ; License along with DOS-C; see the file COPYING.  If not,
25 ; write to the Free Software Foundation, 675 Mass Ave,
26 ; Cambridge, MA 02139, USA.
27 ;
28 ; $Logfile:   C:/dos-c/src/boot/boot.asv  $
29 ;
30 ; $Header$
31 ;
32 ; $Log$
33 ; Revision 1.1  2002/10/31 14:31:06  lace
34 ; :pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
35 ;
36 ; Revision 1.4  2000/06/25 03:59:14  dwelch
37 ;
38 ; Removed from redundant files from the mm directory
39 ; Added some preliminary work on the pager
40 ; Fixed ntoskrnl/mm/npool.c (This may have been the cause of the
41 ; problems reported with loading win32k.sys)
42 ; Fixed problems with reporting space used to store physical page
43 ; information
44 ; Added code to support MmSafeCopy{To/From}User interface work
45 ; (untested)
46 ; Added Event member of the PHYSICAL_PAGE structure to implement Philip
47 ; Susi's suggestion
48 ; Reworked section page-in code (not really tested)
49 ; Replaced inline string functions with gcc builtins to make debugging easier
50 ;
51 ; Revision 1.3  1998/08/25 04:37:43  rex
52 ; new release cleanup
53 ;
54 ; Revision 1.1.1.2  1998/08/25 04:27:38  rex
55 ; A much Needed Update
56 ;
57 ;       
58 ;          Rev 1.5   10 Jan 1997  4:58:06   patv
59 ;       Corrected copyright
60 ;       
61 ;          Rev 1.4   10 Jan 1997  4:52:50   patv
62 ;       Re-written to support C drive and eliminate restrictions on IPL.SYS
63 ;       
64 ;          Rev 1.3   29 Aug 1996 13:06:50   patv
65 ;       Bug fixes for v0.91b
66 ;       
67 ;          Rev 1.2   01 Sep 1995 17:56:44   patv
68 ;       First GPL release.
69 ;       
70 ;          Rev 1.1   30 Jul 1995 20:37:38   patv
71 ;       Initialized stack before use.
72 ;       
73 ;          Rev 1.0   02 Jul 1995 10:57:52   patv
74 ;       Initial revision.
75 ;
76
77 section .text
78
79                 org     0
80 Entry:          jmp     real_start
81
82 ;       bp is initialized to 7c00h
83 %define oem                  [bp+3]
84 %define bytesPerSector       [bp+0bh]
85 %define sectPerCluster       [bp+0dh]
86 %define resSectors           [bp+0eh]
87 %define nFats                [bp+10h]
88 %define nRootDir             [bp+11h]
89 %define nSectors             [bp+13h]
90 %define MID                  [bp+15h]
91 %define sectPerFat           [bp+16h]
92 %define sectPerTrack         [bp+18h]
93 %define nHeads               [bp+1ah]
94 %define nHidden              [bp+1ch]
95 %define nHidden_hi           [bp+1eh]
96 %define nSectorHuge          [bp+20h]
97 %define drive                [bp+24h]
98 %define extBoot              [bp+26h]
99 %define volid                [bp+27h]
100 %define vollabel             [bp+2bh]
101 %define filesys              36h
102
103 LOADSEG         equ     2000h
104
105 FATBUF          equ     4000h           ; offset of temporary buffer for FAT 
106                                         ; chain
107 RETRYCOUNT      equ     5               ; number of retries on disk errors
108
109 ;       Some extra variables that are created on the stack frame
110
111 %define fat_start       [bp-4]          ; first FAT sector
112 %define fat_start_hi    [bp-2]
113 %define root_dir_start  [bp-8]          ; first root directory sector
114 %define root_dir_start_hi [bp-6]
115 %define data_start      [bp-12]         ; first data sector
116 %define data_start_hi   [bp-10]
117
118 ;
119 ; Include macros for filesystem access
120 ;
121 %include "boot.inc"
122
123 ;
124 ;
125 ;
126                 TIMES 3eh-($-$$) DB 0
127
128 %define tempbuf         [bp+3eh]
129 load_seg        dw      LOADSEG
130
131 real_start:     cli
132                 cld
133                 mov     ax, cs
134                 mov     ss, ax          ; initialize stack      
135                 mov     bp, 7c00h
136                 lea     sp, [bp-20h]
137                 sti
138
139                 mov     es, ax
140                 mov     ds, ax
141                 mov     drive, dl       ; BIOS passes drive number in DL
142
143                 GETDRIVEPARMS
144
145                 FINDFILE                ; locate file in root directory
146                 jc      boot_error      ; fail if not found
147
148                 GETFATCHAIN             ; read FAT chain
149                 LOADFILE                ; load file (jumps to boot_sucess if successful)
150
151 boot_error:     mov     cx, ERRMSGLEN
152                 mov     si, errmsg+7c00h
153
154 next_char:      lodsb                   ; print error message
155                 mov     ah, 0eh
156                 xor     bh, bh
157                 int     10h
158                 loop    next_char
159
160                 xor     ah, ah
161                 int     16h             ; wait for keystroke
162                 int     19h             ; invoke bootstrap loader
163
164 boot_success:   mov     dl, drive
165
166                 db      0eah            ; far jump to LOADSEG:0000
167                 dw      0
168                 dw      LOADSEG
169
170
171 ;       readDisk:       Reads a number of sectors into memory.
172 ;
173 ;       Call with:      DX:AX = 32-bit DOS sector number
174 ;                       DI = number of sectors to read
175 ;                       ES:BX = destination buffer
176 ;                       ES must be 64k aligned (1000h, 2000h etc).
177 ;
178 ;       Returns:        CF set on error
179 ;                       ES:BX points one byte after the last byte read. 
180
181 readDisk:
182                 push    si
183 read_next:      push    dx
184                 push    ax
185
186                 ;
187                 ; translate sector number to BIOS parameters
188                 ;
189
190                 ;
191                 ; abs = sector                          offset in track
192                 ;     + head * sectPerTrack             offset in cylinder
193                 ;     + track * sectPerTrack * nHeads   offset in platter
194                 ; 
195                 ; t1     = abs  /  sectPerTrack         (ax has t1)
196                 ; sector = abs mod sectPerTrack         (cx has sector)
197                 ;
198                 div     word sectPerTrack
199                 mov     cx, dx
200
201                 ;
202                 ; t1   = head + track * nHeads
203                 ;
204                 ; track = t1  /  nHeads                 (ax has track)
205                 ; head  = t1 mod nHeads                 (dl has head)
206                 ;
207                 xor     dx, dx
208                 div     word nHeads
209
210                 ; the following manipulations are necessary in order to 
211                 ; properly place parameters into registers.
212                 ; ch = cylinder number low 8 bits
213                 ; cl = 7-6: cylinder high two bits
214                 ;      5-0: sector
215                 mov     dh, dl                  ; save head into dh for bios
216                 ror     ah, 1                   ; move track high bits into
217                 ror     ah, 1                   ; bits 7-6 (assumes top = 0)
218                 xchg    al, ah                  ; swap for later
219                 mov     dl, byte sectPerTrack
220                 sub     dl, cl
221                 inc     cl                      ; sector offset from 1
222                 or      cx, ax                  ; merge cylinder into sector
223                 mov     al, dl                  ; al has # of sectors left
224
225                 ; Calculate how many sectors can be transfered in this read
226                 ; due to dma boundary conditions.
227                 push    dx
228
229                 mov     si, di                  ; temp register save
230                 ; this computes remaining bytes because of modulo 65536
231                 ; nature of dma boundary condition
232                 mov     ax, bx                  ; get offset pointer
233                 neg     ax                      ; and convert to bytes
234                 jz      ax_min_1                ; started at seg:0, skip ahead
235
236                 xor     dx, dx                  ; convert to sectors
237                 div     word bytesPerSector
238                 
239                 cmp     ax, di                  ; check remainder vs. asked
240                 jb      ax_min_1                ; less, skip ahead
241                 mov     si, ax                  ; transfer only what we can
242
243 ax_min_1:       pop     dx
244
245                 ; Check that request sectors do not exceed track boundary
246                 mov     si, sectPerTrack
247                 inc     si
248                 mov     ax, cx                  ; get the sector/cyl byte
249                 and     ax, 03fh                ; and mask out sector
250                 sub     si, ax                  ; si has how many we can read
251                 mov     ax, di
252                 cmp     si, di                  ; see if asked <= available
253                 jge     ax_min_2
254                 mov     ax, si                  ; get what can be xfered
255
256 ax_min_2:       mov     si, RETRYCOUNT
257                 mov     ah, 2
258                 mov     dl, drive
259
260 retry:          push    ax
261                 int     13h
262                 pop     ax
263                 jnc     read_ok
264                 push    ax
265                 xor     ax, ax          ; reset the drive
266                 int     13h
267                 pop     ax
268                 dec     si
269                 jnz     retry
270                 stc
271                 pop     ax
272                 pop     dx
273                 pop     si
274                 ret
275
276 read_next_jmp:  jmp     short read_next
277 read_ok:        xor     ah, ah                          
278                 mov     si, ax                  ; AX = SI = number of sectors read      
279                 mul     word bytesPerSector ; AX = number of bytes read
280                 add     bx, ax                  ; add number of bytes read to BX
281                 jnc     no_incr_es              ; if overflow...
282
283                 mov     ax, es       
284                 add     ah, 10h                 ; ...add 1000h to ES
285                 mov     es, ax
286                 
287 no_incr_es:     pop     ax
288                 pop     dx                      ; DX:AX = last sector number
289
290                 add     ax, si
291                 adc     dx, 0                   ; DX:AX = next sector to read
292                 sub     di, si                  ; if there is anything left to read,
293                 jg      read_next_jmp           ; continue
294
295                 clc
296                 pop     si
297                 ret
298
299 errmsg          db      "Boot error"
300 ERRMSGLEN       equ     $ - errmsg
301
302
303 ;filename        db      "OSLDR   BIN"
304 filename        db      "KERNEL  BIN"
305
306                 TIMES 510-($-$$) DB 0 
307 sign            dw      0aa55h
308                 
309