Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / commands / i386 / pc / drivemap_int13h.S
blob3c87521b63e1caf734cfd0c3ad9513cdbd90fd2e
1 /* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
2 /*
3  *  GRUB  --  GRand Unified Bootloader
4  *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
5  *
6  *  GRUB is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  GRUB is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18  */
20 #include <grub/symbol.h>
22 #define INT13H_OFFSET(x) ((x) - LOCAL (base))
24 .code16
26 /* Copy starts here.  When deployed, this code must be segment-aligned.  */
28 /* The replacement int13 handler.   Preserve all registers.  */
29 FUNCTION(grub_drivemap_handler)
30 LOCAL (base):
31         /* Save %dx for future restore. */
32         push    %dx
33         /* Push flags. Used to simulate interrupt with original flags. */
34         pushf
36         /* Map the drive number (always in DL).  */
37         push    %ax
38         push    %bx
39 #ifdef __APPLE__
40         LOCAL(mapstart_offset) = INT13H_OFFSET(LOCAL (mapstart)) 
41         movw    $LOCAL(mapstart_offset), %bx
42 #else
43         movw    $INT13H_OFFSET(LOCAL (mapstart)), %bx
44 #endif
46 more_remaining:
47         movw    %cs:(%bx), %ax
48         cmpb    %ah, %al
49         jz      not_found /* DRV=DST => map end - drive not remapped, keep DL.  */
50         inc     %bx
51         inc     %bx
52         cmpb    %dl, %al
53         jnz     more_remaining /* Not found, but more remaining, loop.  */
54         movb    %ah, %dl /* Found - drive remapped, modify DL.  */
56 not_found:
57         pop     %bx
58         pop     %ax
60         /* If the call isn't ah=0x8 or ah=0x15 we must restore %dx.  */
61         cmpb    $0x8, %ah
62         jz      norestore
63         cmpb    $0x15, %ah
64         jz      norestore
66         /* Restore flags.  */
67         popf
68         pushf
70 #ifdef __APPLE__
71         LOCAL(oldhandler_offset) = INT13H_OFFSET (LOCAL (oldhandler))
72         lcall *%cs:LOCAL(oldhandler_offset)
73 #else
74         lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
75 #endif
77         push    %bp
78         mov     %sp, %bp
80 tail:
81         /* Save new flags below %esp so the caller will recieve new flags.  */
82         pushf
83         pop     %dx
84         mov     %dx, 8(%bp)
86         pop     %bp
88         /* Restore %dx.  */
89         pop     %dx
90         iret
92 norestore:
94         /* Restore flags.  */
95         popf
96         pushf
98 #ifdef __APPLE__
99         lcall *%cs:LOCAL(oldhandler_offset)
100 #else
101         lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
102 #endif
104         push    %bp
105         mov     %sp, %bp
107         /* Save %dx. So it won't be restored to original value.  */
108         mov     %dx, 2(%bp)
110         jmp tail
112 /* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
113    IVT entries (thus PI:SC in mem).  */
114 VARIABLE(grub_drivemap_oldhandler)
115 LOCAL (oldhandler):
116         .word 0x0, 0x0
118 /* This label MUST be at the end of the copied block, since the installer code
119    reserves additional space for mappings at runtime and copies them over it.  */
120         .align 2
121         
122 VARIABLE(grub_drivemap_mapstart)
123 LOCAL (mapstart):
124         .byte 0