[WINE]
[reactos.git] / boot / freeldr / freeldr / arch / i386 / int386.S
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 .text
21 .code16
22
23 #define ASM
24 #include <arch.h>
25
26 /* Only these flags are propagated into Int386() */
27 #define FLAGS_PROP (I386FLAG_CF | \
28 I386FLAG_ZF | \
29 I386FLAG_SF)
30
31 Int386_REGS:
32
33 Int386_eax:
34 .long 0
35 Int386_ebx:
36 .long 0
37 Int386_ecx:
38 .long 0
39 Int386_edx:
40 .long 0
41
42 Int386_esi:
43 .long 0
44 Int386_edi:
45 .long 0
46
47 Int386_ds:
48 .word 0
49 Int386_es:
50 .word 0
51 Int386_fs:
52 .word 0
53 Int386_gs:
54 .word 0
55
56 Int386_eflags:
57 .long 0
58
59 Int386_vector:
60 .long 0
61 Int386_regsin:
62 .long 0
63 Int386_regsout:
64 .long 0
65
66 /*
67 * int Int386(int ivec, REGS* in, REGS* out);
68 */
69 EXTERN(_Int386)
70 .code32
71
72 /* Get the function parameters */
73 movl 0x04(%esp),%eax
74 movl %eax,Int386_vector
75 movb %al,Int386_vector_opcode
76 movl 0x08(%esp),%eax
77 movl %eax,Int386_regsin
78 movl 0x0c(%esp),%eax
79 movl %eax,Int386_regsout
80
81 /* Save all registers + segment registers */
82 pushw %ds
83 pushw %es
84 pushw %fs
85 pushw %gs
86 pushal
87
88 /* Copy the input regs to our variables */
89 movl $Int386_REGS,%edi
90 movl Int386_regsin,%esi
91 movl $0x24,%ecx
92 cld
93 rep
94 movsb
95
96 call switch_to_real
97 .code16
98
99 /* Setup the registers */
100 movw %cs:Int386_ds,%ax
101 movw %ax,%ds /* DS register */
102 movw %cs:Int386_es,%ax
103 movw %ax,%es /* ES register */
104 movw %cs:Int386_fs,%ax
105 movw %ax,%fs /* FS register */
106 movw %cs:Int386_gs,%ax
107 movw %ax,%gs /* GS register */
108
109 /* Prepare EFLAGS for recover */
110 pushf
111 movw %cs:Int386_eflags, %ax
112 popw %cx
113 andw $FLAGS_PROP, %ax
114 andw $~FLAGS_PROP, %cx
115 orw %cx, %ax
116 pushw %ax
117
118 /* Recover general purpose registers */
119 movl %cs:Int386_eax,%eax /* EAX register */
120 movl %cs:Int386_ebx,%ebx /* EBX register */
121 movl %cs:Int386_ecx,%ecx /* ECX register */
122 movl %cs:Int386_edx,%edx /* EDX register */
123
124 movl %cs:Int386_esi,%esi /* ESI register */
125 movl %cs:Int386_edi,%edi /* EDI register */
126
127 /* Recover previously prepared flags */
128 popf
129
130 /* Do not set the flags register */
131 /* only return its value in regsout */
132 //pushl Int386_eflags
133 //popfl /* EFLAGS register */
134
135 /* Call the interrupt vector */
136 /*int Int386_vector*/
137 Int386_int_opcode:
138 .byte 0xcd
139 Int386_vector_opcode:
140 .byte 0x00
141
142 /* Save the registers */
143 movl %eax,%cs:Int386_eax /* EAX register */
144 movl %ebx,%cs:Int386_ebx /* EBX register */
145 movl %ecx,%cs:Int386_ecx /* ECX register */
146 movl %edx,%cs:Int386_edx /* EDX register */
147
148 movl %esi,%cs:Int386_esi /* ESI register */
149 movl %edi,%cs:Int386_edi /* EDI register */
150
151 movw %ds,%ax /* DS register */
152 movw %ax,%cs:Int386_ds
153 movw %es,%ax /* ES register */
154 movw %ax,%cs:Int386_es
155 movw %fs,%ax /* FS register */
156 movw %ax,%cs:Int386_fs
157 movw %gs,%ax /* GS register */
158 movw %ax,%cs:Int386_gs
159
160 pushf
161 popw %cs:Int386_eflags /* EFLAGS register */
162
163 call switch_to_prot
164 .code32
165
166 /* Copy the variables to the output regs */
167 movl $Int386_REGS,%esi
168 movl Int386_regsout,%edi
169 movl $0x24,%ecx
170 cld
171 rep
172 movsb
173
174 /* Restore segment and all other registers */
175
176
177 popal
178 popw %gs
179 popw %fs
180 popw %es
181 popw %ds
182
183 /* Get return value */
184 movl Int386_eax,%eax
185
186 ret