[CRT] Massively improve performance of rand_s
[reactos.git] / boot / freeldr / freeldr / arch / realmode / int386.inc
1
2 #include "../../include/arch/pc/pcbios.h"
3
4 Int386:
5 /* Save all registers + segment registers */
6 push ds
7 push es
8 push fs
9 push gs
10 pushad
11
12 /* Get the interrupt vector and patch the opcode */
13 mov al, byte ptr ds:[BSS_IntVector]
14 mov byte ptr ds:[Int386_vector_opcode], al
15
16 /* Get current EFLAGS and mask CF, ZF and SF */
17 pushf
18 pop cx
19 and cx, not (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
20
21 /* Get flags CF, ZF and SF from the REGS structure */
22 mov ax, word ptr cs:[BSS_RegisterSet + REGS_EFLAGS]
23 and ax, (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
24
25 /* Combine flags and set them */
26 or ax, cx
27 push ax
28 popf
29
30 /* Setup the registers */
31 mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
32 mov ds, ax
33 mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
34 mov es, ax
35 mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
36 mov fs, ax
37 mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
38 mov gs, ax
39
40 /* Setup ebp only if EBP != 0, otherwise use it only as output */
41 mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EBP]
42 test eax, eax
43 jz Int386_set_registers
44 mov ebp, eax
45
46 Int386_set_registers:
47 mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX]
48 mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX]
49 mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX]
50 mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX]
51 mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI]
52 mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI]
53 #if defined(SARCH_PC98)
54 /* Always set EBP register even if its equals zero.
55 * Otherwise the DISK BIOS calls will store garbage data in a output buffer.
56 */
57 mov ebp, dword ptr cs:[BSS_RegisterSet + REGS_EBP]
58 #endif
59
60 /* Call the interrupt vector */
61 /*int Int386_vector*/
62 .byte HEX(0cd)
63 Int386_vector_opcode:
64 .byte 00
65
66 /* Save the registers */
67 mov dword ptr cs:[BSS_RegisterSet + REGS_EAX], eax
68 mov dword ptr cs:[BSS_RegisterSet + REGS_EBX], ebx
69 mov dword ptr cs:[BSS_RegisterSet + REGS_ECX], ecx
70 mov dword ptr cs:[BSS_RegisterSet + REGS_EDX], edx
71 mov dword ptr cs:[BSS_RegisterSet + REGS_ESI], esi
72 mov dword ptr cs:[BSS_RegisterSet + REGS_EDI], edi
73 mov dword ptr cs:[BSS_RegisterSet + REGS_EBP], ebp
74
75 mov ax, ds
76 mov word ptr cs:[BSS_RegisterSet + REGS_DS], ax
77 mov ax, es
78 mov word ptr cs:[BSS_RegisterSet + REGS_ES], ax
79 mov ax, fs
80 mov word ptr cs:[BSS_RegisterSet + REGS_FS], ax
81 mov ax, gs
82 mov word ptr cs:[BSS_RegisterSet + REGS_GS], ax
83
84 pushfd
85 pop dword ptr cs:[BSS_RegisterSet + REGS_EFLAGS]
86
87 /* Restore all registers + segment registers */
88 popad
89 pop gs
90 pop fs
91 pop es
92 pop ds
93
94 ret