syslinux-3.08-2 sources from FC4
[bootcd.git] / syslinux / sample / mdiskchk.c
1 /* -*- c -*- ------------------------------------------------------------- *
2  *   
3  *   Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
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, 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.
10  *
11  * ----------------------------------------------------------------------- */
12 /* $Id: mdiskchk.c,v 1.7 2004/12/30 21:57:12 hpa Exp $ */
13
14 /*
15  * mdiskchk.c
16  *
17  * DOS program to check for the existence of a memdisk.
18  *
19  * This program can be compiled for DOS with the OpenWatcom compiler
20  * (http://www.openwatcom.org/):
21  *
22  * wcl -3 -osx -mt mdiskchk.c
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <i86.h>                /* For MK_FP() */
28
29 typedef unsigned long  uint32_t;
30 typedef unsigned short uint16_t;
31 typedef unsigned char  uint8_t;
32
33 struct memdiskinfo {
34   uint16_t bytes;               /* Bytes from memdisk */
35   uint16_t version;             /* Memdisk version */
36   uint32_t base;                /* Base of disk in high memory */
37   uint32_t size;                /* Size of disk in sectors */
38   char far * cmdline;           /* Command line */
39   void far * oldint13;          /* Old INT 13h */
40   void far * oldint15;          /* Old INT 15h */
41   uint16_t olddosmem;
42   uint8_t  bootloaderid;
43
44   uint8_t _pad;
45
46   /* We add our own fields at the end */
47   int cylinders;
48   int heads;
49   int sectors;
50 };
51
52 struct memdiskinfo * query_memdisk(int drive)
53 {
54   static struct memdiskinfo mm;
55   uint32_t _eax, _ebx, _ecx, _edx;
56   uint16_t _es, _di;
57   unsigned char _dl = drive;
58   uint16_t bytes;
59
60   __asm {
61     .386 ;
62     mov eax, 454d0800h ;
63     mov ecx, 444d0000h ;
64     mov edx, 53490000h ;
65     mov dl, _dl ;
66     mov ebx, 3f4b0000h ;
67     int 13h ;
68     mov _eax, eax ;
69     mov _ecx, ecx ;
70     mov _edx, edx ;
71     mov _ebx, ebx ;
72     mov _es, es ;
73     mov _di, di ;
74   }
75   
76   if ( _eax >> 16 != 0x4d21 ||
77        _ecx >> 16 != 0x4d45 ||
78        _edx >> 16 != 0x4944 ||
79        _ebx >> 16 != 0x4b53 )
80     return NULL;
81
82   memset(&mm, 0, sizeof mm);
83
84   bytes = *(uint16_t far *)MK_FP(_es, _di);
85
86   /* 27 is the most we know how to handle */
87   if ( bytes > 27 )
88     bytes = 27;
89
90   _fmemcpy((void far *)&mm, (void far *)MK_FP(_es,_di), bytes);
91
92   mm.cylinders = ((_ecx >> 8) & 0xff) + ((_ecx & 0xc0) << 2) + 1;
93   mm.heads     = ((_edx >> 8) & 0xff) + 1;
94   mm.sectors   = (_ecx & 0x3f);
95   
96   return &mm;
97 }
98
99 const char *bootloadername(uint8_t id)
100 {
101   static const struct {
102     uint8_t id, mask;
103     const char *name;
104   } *lp, list[] =
105     {
106       { 0x10, 0xf0, "LILO" },
107       { 0x20, 0xf0, "LOADLIN" },
108       { 0x31, 0xff, "SYSLINUX" },
109       { 0x32, 0xff, "PXELINUX" },
110       { 0x33, 0xff, "ISOLINUX" },
111       { 0x34, 0xff, "EXTLINUX" },
112       { 0x30, 0xf0, "SYSLINUX family" },
113       { 0x40, 0xf0, "Etherboot" },
114       { 0x50, 0xf0, "ELILO" },
115       { 0x70, 0xf0, "GrUB" },
116       { 0x80, 0xf0, "U-Boot" },
117       { 0x00, 0x00, "unknown" }
118     };
119
120   for ( lp = list ; ; lp++ ) {
121     if ( ((id ^ lp->id) & lp->mask) == 0 )
122       return lp->name;
123   }
124 }
125
126 int main(int argc, char *argv[])
127 {
128   int d;
129   int found = 0;
130   struct memdiskinfo *m;
131
132   for ( d = 0 ; d <= 0xff ; d++ ) {
133     if ( (m = query_memdisk(d)) != NULL ) {
134       printf("Drive %02X is MEMDISK %u.%02u:\n"
135              "\tAddress = 0x%08lx, len = %lu sectors, chs = %u/%u/%u,\n"
136              "\tloader = 0x%02x (%s),\n"
137              "\tcmdline = %Fs\n",
138              d, m->version >> 8, m->version & 0xff,
139              m->base, m->size, m->cylinders, m->heads, m->sectors,
140              m->bootloaderid, bootloadername(m->bootloaderid),
141              m->cmdline);
142       found++;
143     }
144   }
145   
146   return found;
147 }