1 /* -*- c -*- ------------------------------------------------------------- *
3 * Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
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, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
16 * DOS program to check for the existence of a memdisk.
18 * This program can be compiled for DOS with the OpenWatcom compiler
19 * (http://www.openwatcom.org/):
21 * wcl -3 -osx -mt mdiskchk.c
26 #include <i86.h> /* For MK_FP() */
28 typedef unsigned long uint32_t;
29 typedef unsigned short uint16_t;
30 typedef unsigned char uint8_t;
33 uint16_t bytes
; /* Bytes from memdisk */
34 uint16_t version
; /* Memdisk version */
35 uint32_t base
; /* Base of disk in high memory */
36 uint32_t size
; /* Size of disk in sectors */
37 char far
* cmdline
; /* Command line */
38 void far
* oldint13
; /* Old INT 13h */
39 void far
* oldint15
; /* Old INT 15h */
45 /* We add our own fields at the end */
51 struct memdiskinfo
* query_memdisk(int drive
)
53 static struct memdiskinfo mm
;
54 uint32_t _eax
, _ebx
, _ecx
, _edx
;
56 unsigned char _dl
= drive
;
75 if ( _eax
>> 16 != 0x4d21 ||
76 _ecx
>> 16 != 0x4d45 ||
77 _edx
>> 16 != 0x4944 ||
78 _ebx
>> 16 != 0x4b53 )
81 memset(&mm
, 0, sizeof mm
);
83 bytes
= *(uint16_t far
*)MK_FP(_es
, _di
);
85 /* 27 is the most we know how to handle */
89 _fmemcpy((void far
*)&mm
, (void far
*)MK_FP(_es
,_di
), bytes
);
91 mm
.cylinders
= ((_ecx
>> 8) & 0xff) + ((_ecx
& 0xc0) << 2) + 1;
92 mm
.heads
= ((_edx
>> 8) & 0xff) + 1;
93 mm
.sectors
= (_ecx
& 0x3f);
98 const char *bootloadername(uint8_t id
)
100 static const struct {
105 { 0x10, 0xf0, "LILO" },
106 { 0x20, 0xf0, "LOADLIN" },
107 { 0x31, 0xff, "SYSLINUX" },
108 { 0x32, 0xff, "PXELINUX" },
109 { 0x33, 0xff, "ISOLINUX" },
110 { 0x34, 0xff, "EXTLINUX" },
111 { 0x30, 0xf0, "SYSLINUX family" },
112 { 0x40, 0xf0, "Etherboot" },
113 { 0x50, 0xf0, "ELILO" },
114 { 0x70, 0xf0, "GrUB" },
115 { 0x80, 0xf0, "U-Boot" },
116 { 0x00, 0x00, "unknown" }
119 for ( lp
= list
; ; lp
++ ) {
120 if ( ((id
^ lp
->id
) & lp
->mask
) == 0 )
125 int main(int argc
, char *argv
[])
129 struct memdiskinfo
*m
;
131 for ( d
= 0 ; d
<= 0xff ; d
++ ) {
132 if ( (m
= query_memdisk(d
)) != NULL
) {
133 printf("Drive %02X is MEMDISK %u.%02u:\n"
134 "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
135 "\tloader = 0x%02x (%s),\n"
137 d
, m
->version
>> 8, m
->version
& 0xff,
138 m
->base
, m
->size
, m
->cylinders
, m
->heads
, m
->sectors
,
139 m
->bootloaderid
, bootloadername(m
->bootloaderid
),