Adding upstream version 3.20.
[syslinux-debian/hramrach.git] / sample / mdiskchk.c
blob095bda27d9a11a0df1aa2b4956d357a9ea21bbd7
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 * ----------------------------------------------------------------------- */
14 * mdiskchk.c
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
24 #include <stdio.h>
25 #include <string.h>
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;
32 struct memdiskinfo {
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 */
40 uint16_t olddosmem;
41 uint8_t bootloaderid;
43 uint8_t _pad;
45 /* We add our own fields at the end */
46 int cylinders;
47 int heads;
48 int sectors;
51 struct memdiskinfo * query_memdisk(int drive)
53 static struct memdiskinfo mm;
54 uint32_t _eax, _ebx, _ecx, _edx;
55 uint16_t _es, _di;
56 unsigned char _dl = drive;
57 uint16_t bytes;
59 __asm {
60 .386 ;
61 mov eax, 454d0800h ;
62 mov ecx, 444d0000h ;
63 mov edx, 53490000h ;
64 mov dl, _dl ;
65 mov ebx, 3f4b0000h ;
66 int 13h ;
67 mov _eax, eax ;
68 mov _ecx, ecx ;
69 mov _edx, edx ;
70 mov _ebx, ebx ;
71 mov _es, es ;
72 mov _di, di ;
75 if ( _eax >> 16 != 0x4d21 ||
76 _ecx >> 16 != 0x4d45 ||
77 _edx >> 16 != 0x4944 ||
78 _ebx >> 16 != 0x4b53 )
79 return NULL;
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 */
86 if ( bytes > 27 )
87 bytes = 27;
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);
95 return &mm;
98 const char *bootloadername(uint8_t id)
100 static const struct {
101 uint8_t id, mask;
102 const char *name;
103 } *lp, list[] =
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 )
121 return lp->name;
125 int main(int argc, char *argv[])
127 int d;
128 int found = 0;
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"
136 "\tcmdline = %Fs\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),
140 m->cmdline);
141 found++;
145 return found;