]> git.saurik.com Git - apple/boot.git/blame_incremental - i386/cdboot/cdboot.s
boot-132.tar.gz
[apple/boot.git] / i386 / cdboot / cdboot.s
... / ...
CommitLineData
1; Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
2;
3; @APPLE_LICENSE_HEADER_START@
4;
5; Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
6; Reserved. This file contains Original Code and/or Modifications of
7; Original Code as defined in and that are subject to the Apple Public
8; Source License Version 2.0 (the "License"). You may not use this file
9; except in compliance with the License. Please obtain a copy of the
10; License at http://www.apple.com/publicsource and read it before using
11; this file.
12;
13; The Original Code and all software distributed under the License are
14; distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15; EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16; INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17; FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
18; License for the specific language governing rights and limitations
19; under the License.
20;
21; @APPLE_LICENSE_HEADER_END@
22
23DEBUG EQU 0
24
25%macro DebugCharMacro 1
26 push ax
27 mov al, %1
28 call putc
29 pop ax
30%endmacro
31%macro DebugPauseMacro 0
32 push ax
33 call getc
34 pop ax
35%endmacro
36
37%if DEBUG
38%define DebugChar(x) DebugCharMacro x
39%define DebugPause(x) DebugPauseMacro
40%else
41%define DebugChar(x)
42%define DebugPause(x)
43%endif
44
45kBoot2Sectors EQU 126 ; sectors to load for boot2
46kBoot2Address EQU 0x0200 ; boot2 load address
47kBoot2Segment EQU 0x2000 ; boot2 load segment
48
49kBoot0Stack EQU 0xFFF0 ; boot0 stack pointer
50
51kReadBuffer EQU 0x1000 ; disk data buffer address
52
53kVolSectorOffset EQU 0x47 ; offset in buffer of sector number
54 ; in volume descriptor
55kBootSectorOffset EQU 0x28 ; offset in boot catalog
56 ; of sector number to load boot file
57kBootCountOffset EQU 0x26 ; offset in boot catalog
58 ; of number of sectors to read
59
60
61 code16
62 ORG 0x7c00
63
64 SEGMENT .text
65
66start:
67 cli
68 jmp 0:start1
69 times 8-($-$$) nop ; Put boot information table at offset 8
70
71 ; El Torito boot information table, filled in by the
72 ; mkisofs -boot-info-table option, if used.
73bi_pvd: dd 0 ; LBA of primary volume descriptor
74bi_file: dd 0 ; LBA of boot file
75bi_length: dd 0 ; Length of boot file
76bi_csum: dd 0 ; Checksum of boot file
77bi_reserved: times 10 dd 0 ; Reserved
78
79start1:
80 xor ax, ax ; zero %ax
81 mov ss, ax ; setup the
82 mov sp, kBoot0Stack ; stack
83 sti
84 cld ; increment SI after each lodsb call
85 mov ds, ax ; setup the
86 mov es, ax ; data segments
87 ;; BIOS boot drive is in DL
88
89 DebugChar('!')
90 DebugPause()
91
92%if DEBUG
93 mov eax, [kBoot2LoadAddr]
94 call print_hex
95 call getc
96%endif
97
98 ;;
99 ;; The BIOS likely didn't load the rest of the booter,
100 ;; so we have to fetch it ourselves.
101 ;;
102 xor ax, ax
103 mov es, ax
104 mov bx, kReadBuffer
105 mov al, 1
106 mov ecx, 17
107 call read_lba
108 jc error
109
110 DebugChar('A')
111
112 mov ecx, [kReadBuffer + kVolSectorOffset]
113%if DEBUG
114 mov eax, ecx
115 call print_hex
116 DebugPause()
117%endif
118 mov al, 1
119 call read_lba
120 jc error
121
122 ;; Now we have the boot catalog in the buffer.
123 ;; Really we should look at the validation entry, but oh well.
124
125 DebugChar('B')
126
127 mov ecx, [kReadBuffer + kBootSectorOffset]
128 inc ecx ; skip the first sector which is what we are in
129%if DEBUG
130 mov eax, ecx
131 call print_hex
132 DebugPause()
133%endif
134
135 mov ax, kBoot2Segment
136 mov es, ax
137
138 mov al, kBoot2Sectors / 4
139 mov bx, kBoot2Address
140 call read_lba
141 jc error
142
143 DebugChar('C')
144%if DEBUG
145 mov eax, [es:kBoot2Address]
146 call print_hex
147 DebugPause()
148%endif
149
150 xor ax, ax
151 mov es, ax
152
153 DebugChar('X')
154 DebugPause()
155
156 ;; Jump to newly-loaded booter
157 jmp kBoot2Segment:kBoot2Address
158
159error:
160 mov al, 'E'
161 call putc
162 hlt
163
164 ;;
165 ;; Support functions
166 ;;
167
168;--------------------------------------------------------------------------
169; read_lba - Read sectors from CD using LBA addressing.
170;
171; Arguments:
172; AL = number of 2048-byte sectors to read (valid from 1-127).
173; ES:BX = pointer to where the sectors should be stored.
174; ECX = sector offset in partition
175; DL = drive number (0x80 + unit number)
176;
177; Returns:
178; CF = 0 success
179; 1 error
180;
181read_lba:
182 pushad ; save all registers
183 mov bp, sp ; save current SP
184
185 ;
186 ; Create the Disk Address Packet structure for the
187 ; INT13/F42 (Extended Read Sectors) on the stack.
188 ;
189
190 ; push DWORD 0 ; offset 12, upper 32-bit LBA
191 push ds ; For sake of saving memory,
192 push ds ; push DS register, which is 0.
193
194 push ecx
195
196 push es ; offset 6, memory segment
197
198 push bx ; offset 4, memory offset
199
200 xor ah, ah ; offset 3, must be 0
201 push ax ; offset 2, number of sectors
202
203 push WORD 16 ; offset 0-1, packet size
204
205 ;
206 ; INT13 Func 42 - Extended Read Sectors
207 ;
208 ; Arguments:
209 ; AH = 0x42
210 ; DL = drive number (80h + drive unit)
211 ; DS:SI = pointer to Disk Address Packet
212 ;
213 ; Returns:
214 ; AH = return status (sucess is 0)
215 ; carry = 0 success
216 ; 1 error
217 ;
218 ; Packet offset 2 indicates the number of sectors read
219 ; successfully.
220 ;
221 mov si, sp
222 mov ah, 0x42
223 int 0x13
224
225 jnc .exit
226
227 DebugChar('R') ; indicate INT13/F42 error
228
229 ;
230 ; Issue a disk reset on error.
231 ; Should this be changed to Func 0xD to skip the diskette controller
232 ; reset?
233 ;
234 xor ax, ax ; Func 0
235 int 0x13 ; INT 13
236 stc ; set carry to indicate error
237
238.exit:
239 mov sp, bp ; restore SP
240 popad
241 ret
242
243;;
244;; Display a single character from AL.
245;;
246putc: pushad
247 mov bx, 0x1 ; attribute for output
248 mov ah, 0xe ; BIOS: put_char
249 int 0x10 ; call BIOS, print char in %al
250 popad
251 ret
252
253;;
254;; Get a character from the keyboard and return it in AL.
255;;
256getc: mov ah, 0
257 int 0x16
258 ret
259
260%if DEBUG
261;--------------------------------------------------------------------------
262; Write the 4-byte value to the console in hex.
263;
264; Arguments:
265; EAX = Value to be displayed in hex.
266;
267print_hex:
268 pushad
269 mov cx, WORD 4
270 bswap eax
271.loop
272 push ax
273 ror al, 4
274 call print_nibble ; display upper nibble
275 pop ax
276 call print_nibble ; display lower nibble
277 ror eax, 8
278 loop .loop
279
280 mov al, 10 ; carriage return
281 call putc
282 mov al, 13
283 call putc
284 popad
285 ret
286
287print_nibble:
288 and al, 0x0f
289 add al, '0'
290 cmp al, '9'
291 jna .print_ascii
292 add al, 'A' - '9' - 1
293.print_ascii:
294 call putc
295 ret
296
297%endif ; DEBUG
298
299
300
301 ;; Pad this file to a size of 2048 bytes (one CD sector).
302pad:
303 times 2048-($-$$) db 0
304
305 ;; Location of loaded boot2 code.
306kBoot2LoadAddr equ $
307
308 END