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