]> git.saurik.com Git - apple/boot.git/blob - i386/libsaio/bios.s
9654a12fba59f624fc19e512715b053ad36447f0
[apple/boot.git] / i386 / libsaio / bios.s
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright 1993 NeXT Computer, Inc.
26 * All rights reserved.
27 *
28 * Harness for calling real-mode BIOS functions.
29 */
30
31 #include <architecture/i386/asm_help.h>
32 #include "memory.h"
33
34 #define data32 .byte 0x66
35 #define addr32 .byte 0x67
36
37 #define O_INT 0
38 #define O_EAX 4
39 #define O_EBX 8
40 #define O_ECX 12
41 #define O_EDX 16
42 #define O_EDI 20
43 #define O_ESI 24
44 #define O_EBP 28
45 #define O_CS 32
46 #define O_DS 34
47 #define O_ES 36
48 #define O_FLG 38
49
50 .data
51 .lcomm save_eax, 4,2
52 .lcomm save_edx, 4,2
53 .lcomm save_es, 2,1
54 .lcomm save_flag, 2,1
55 .lcomm new_eax, 4,2
56 .lcomm new_edx, 4,2
57 .lcomm new_es, 2,1
58
59 .text
60
61 /*============================================================================
62 * Call real-mode BIOS INT functions.
63 *
64 */
65 LABEL(_bios)
66 enter $0, $0
67 pushal
68
69 movl 8(%ebp), %edx // address of save area
70 movb O_INT(%edx), %al // save int number
71 movb %al, do_int+1
72
73 movl O_EBX(%edx), %ebx
74 movl O_ECX(%edx), %ecx
75 movl O_EDI(%edx), %edi
76 movl O_ESI(%edx), %esi
77 movl O_EBP(%edx), %ebp
78 movl %edx, save_edx
79 movl O_EAX(%edx), %eax
80 movl %eax, new_eax
81 movl O_EDX(%edx), %eax
82 movl %eax, new_edx
83 movw O_ES(%edx), %ax
84 movl %ax, new_es
85
86 call __prot_to_real
87
88 data32
89 addr32
90 mov OFFSET16(new_eax), %eax
91 data32
92 addr32
93 mov OFFSET16(new_edx), %edx
94 data32
95 addr32
96 mov OFFSET16(new_es), %es
97
98 do_int:
99 int $0x00
100 pushf
101 data32
102 addr32
103 movl %eax, OFFSET16(save_eax)
104 popl %eax // actually pop %ax
105 addr32
106 movl %eax, OFFSET16(save_flag) // actually movw
107 mov %es, %ax
108 addr32
109 movl %eax, OFFSET16(save_es) // actually movw
110 data32
111 call __real_to_prot
112
113 movl %edx, new_edx // save new edx before clobbering
114 movl save_edx, %edx
115 movl new_edx, %eax // now move it into buffer
116 movl %eax, O_EDX(%edx)
117 movl save_eax, %eax
118 movl %eax, O_EAX(%edx)
119 movw save_es, %ax
120 movw %ax, O_ES(%edx)
121 movw save_flag, %ax
122 movw %ax, O_FLG(%edx)
123 movl %ebx, O_EBX(%edx)
124 movl %ecx, O_ECX(%edx)
125 movl %edi, O_EDI(%edx)
126 movl %esi, O_ESI(%edx)
127 movl %ebp, O_EBP(%edx)
128
129 popal
130 leave
131
132 ret
133
134 /*============================================================================
135 * Determines the total system memory size using various BIOS Int 15 calls.
136 *
137 */
138 LABEL(_get_memsize)
139 enter $0, $0 # create frame pointer (32 bit operand/stack)
140 pushal # save all registers
141
142 movl 8(%ebp), %ebx # push input structure pointer to stack
143 pushl %ebx
144
145 call __prot_to_real # switch to real mode
146
147 ##################################################################
148 # In real mode.
149 # Do not forget the opcode overrides, since the assembler
150 # does not know we have made a transition to 16-bit operation.
151 ##################################################################
152
153 data32
154 movl $0xE801, %eax # Get memory size
155 clc
156 int $0x15
157 data32
158 jnc getmsz_e801
159
160 data32
161 movl $0xDA88, %eax # Get memory size
162 clc
163 int $0x15
164 data32
165 jnc getmsz_da88
166
167 movb $0x8A, %ah # Get memory size
168 clc
169 int $0x15
170 data32
171 jnc getmsz_8a
172
173 movb $0x88, %ah # Get memory size
174 clc
175 int $0x15
176 data32
177 jnc getmsz_88
178
179 xorl %edx, %edx # Error, cannot get memory size
180 xorl %eax, %eax
181
182 getmsz_done:
183 data32
184 addr32
185 pushl %eax # Push EAX to 32-bit stack
186
187 data32
188 call __real_to_prot # Back to protected mode. EAX is modified.
189
190 ##################################################################
191 # Back to protected mode.
192 ##################################################################
193
194 popl %eax # Pop EAX from stack
195 popl %ebx # Pop pointer to register structure
196
197 # Copy the result to the input structure pointed to by a pointer
198 # which is on top of the stack. Write register EAX and EDX to the
199 # structure.
200
201 movl %eax, O_EAX(%ebx)
202 movl %edx, O_EDX(%ebx)
203
204 popal # restore all registers
205 leave # undo enter operator
206 ret
207
208 getmsz_88:
209 orl %eax, %eax
210 data32
211 jz getmsz_64m
212 xorl %edx, %edx
213
214 getmsz_8a:
215 data32
216 movl $1024, %ebx # Add in 1M
217 addl %ebx, %eax
218 adcl $0, %edx
219 data32
220 jmp getmsz_done
221
222 getmsz_64m:
223 data32
224 movl $1, %edx
225 xorl %eax, %eax
226 data32
227 jmp getmsz_done
228
229 getmsz_da88:
230 xor %dh, %dh
231 movb %cl, %dl
232 movl %ebx, %eax
233 data32
234 jmp getmsz_8a
235
236 getmsz_e801:
237 xorl %edx, %edx
238 orl %ebx, %ebx
239 data32
240 jz getmsz_88
241
242 data32
243 movl $64, %eax
244 mul %ebx
245
246 data32
247 movl $16384, %ebx
248 addl %ebx, %eax
249 adcl $0, %edx
250
251 data32
252 jmp getmsz_done