#include #include #include #include #include #include #include #ifdef _WIN32 /* Microsoft & Microsoft compatible compilers have _mkdir(x); not mkdir(x,y) */ #include #undef mkdir #define mkdir(d, p) _mkdir(d) #endif char *ilist=0; /* the interrupt list itself */ char **line=0; /* pointers to start of each line */ char *tag=0; /* info about each line */ int nlines=0; /* number of lines and tags */ int *tables=0; int ntables=0; char zero32[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; typedef struct { int line; int intno; int regno; char *desc; } IntInfo; IntInfo *int_info; int int_count; typedef struct { int num; char *desc; int *xref; } CatInfo; char *flag_names[] = { "UUndocumented function", "upartially documented function", "Pavailable only in protected mode", "Ravailable only in real or V86 mode", "Ccallout or callback (usually hooked rather than called)", "Oobsolete (no longer present in current versions)", 0 }; CatInfo flags[256]; char *category_names[] = { "!Administrative information", "-no classification", "Aapplications", "aaccess software (screen readers, etc)", "BBIOS", "bvendor-specific BIOS extensions", "CCPU-generated", "ccaches/spoolers", "DDOS kernel", "ddisk I/O enhancements", "EDOS extenders", "eelectronic mail", "FFAX", "ffile manipulation", "Gdebuggers/debugging tools", "ggames", "Hhardware", "hvendor-specific hardware", "IIBM workstation/terminal emulators", "isystem info/monitoring", "JJapanese", "jjoke programs", "Kkeyboard enhancers", "kfile/disk compression", "lshells/command interpreters", "Mmouse/pointing device", "mmemory management", "Nnetwork", "nnon-traditional input devices", "Oother operating systems", "Pprinter enhancements", "ppower management", "QDESQview/TopView and Quarterdeck programs", "Rremote control/file access", "rruntime support", "Sserial I/O", "ssound/speech", "TDOS-based task switchers/multitaskers", "tTSR libraries", "Uresident utilities", "uemulators", "Vvideo", "vvirus/antivirus", "WMS Windows", "Xexpansion bus BIOSes", "ysecurity", "*reserved (and not otherwise classified)", 0 }; CatInfo categories[256]; int byint[256]; void read_files(char *path) { int i; FILE *f; char buf[100]; int num_bytes = 0; int num_files = 0; printf("scanning files... "); fflush(stdout); for (i='a'; i<'z'; i++) { struct stat s; sprintf(buf, "%s/interrup.%c", path, i); if (stat(buf, &s)) break; num_files++; num_bytes += s.st_size; } printf("%d files [a..%c], %d bytes\n", num_files, num_files+'a'-1, num_bytes); ilist = (char *)malloc(num_bytes+2); if (ilist == 0) { printf("\nNot enough memory to read files in.\n"); exit(1); } printf("loading files... "); fflush(stdout); num_bytes = 0; for (i='a'; i<'z'; i++) { struct stat s; int r; sprintf(buf, "%s/interrup.%c", path, i); if (stat(buf, &s)) break; f = fopen(buf, "r"); if (f == 0) break; putchar(i); fflush(stdout); r = fread(ilist+num_bytes, 1, s.st_size, f); num_bytes += r; fclose(f); } ilist[num_bytes] = 0; printf("... done.\n"); printf("Building line table... "); fflush(stdout); nlines = 0; for (i=0; i ntables-1) ntables = cpi+1; } } int_info = (IntInfo *)malloc(int_count * sizeof(IntInfo)); #if 0 dump_cat(flags, "flag"); dump_cat(categories, "category"); printf("Counts by interrupt\n"); for (i=0; i<256; i++) { printf("%10d 0x%02x\n", byint[i], i); } printf("Tables: %d\n", ntables); #endif tables = (int *)malloc(ntables * sizeof(int)); memset(tables, 0, ntables * sizeof(int)); printf(" %d interrupts, %d tables, done.\n", int_count, ntables); fflush(stdout); } void pass2() { int i; char *cp; printf("pass 2..."); fflush(stdout); init_cat2(flags); init_cat2(categories); int_count = -1; for (i=0; id+1) cp--; *cp = 0; tag[i] = 1; int_count++; int_info[int_count].line = i; int_info[int_count].intno = -1; int_info[int_count].regno = -1; int_info[int_count].desc = d; if (isxdigit(line[i][10]) && isxdigit(line[i][11]) && line[i][8] != '!') { int x; sscanf(line[i]+10, "%02x", &x); int_info[int_count].intno = x; if (isxdigit(line[i][12]) && isxdigit(line[i][13])) { sscanf(line[i]+12, "%02x", &x); int_info[int_count].regno = x; } } } cp = strstr(line[i], "(Table "); if (cp && isdigit(cp[7]) && cp[12] == ')') { int cpi = atoi(cp+7); int l = i; while (line[l-1][0] != 0 && line[l-1][0] != '\r') l--; /* find first line of table */ tables[cpi] = l; tag[l] = 1; } } printf(" done.\n"); fflush(stdout); } FILE * int_to_file(char *pfx, int n) { static char opfx[10] = { 1, 0 }; static char l2done[100]; char buf[100]; FILE *rv; int d1, d3; if (strcmp(opfx, pfx)) { memset(l2done, 0, 100); strcpy(opfx, pfx); } d1 = n % 100; d3 = (n/100); sprintf(buf, "%s/%02d", pfx, d1); if (!l2done[d1]) { l2done[d1] = 1; mkdir(buf, 0777); } sprintf(buf, "%s/%02d/%d.html", pfx, d1, d3); rv = fopen(buf, "w"); return rv; } char * int_to_filename(char *pfx, int n) { static char buf[100], *bp; int d1, d3; d1 = n % 100; d3 = (n/100); sprintf(buf, "%s/%02d/%d.html", pfx, d1, d3); return buf; } void header(FILE *f, char *fmt, ...) { char buf[1000]; va_list ap=0; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); fprintf(f, "\n", buf); /* fprintf(f, "%s\n

%s

\n", buf, buf); */ } void trailer(FILE *f) { fprintf(f, "\n\n"); /* fprintf(f, "\n"); */ } void put_line(FILE *f, char *l) { while (*l) { if (*l == '#' && isdigit(l[1])) { fprintf(f, "%.6s", int_to_filename("it", atoi(l+1)), l); l += 5; } else if (strncmp(l, "(Table ", 7) == 0 && l[12] == ')') { l += 11; } else if (*l == '&') fputs("&", f); else if (*l == '<') fputs("<", f); else if (*l == '>') fputs(">", f); else fputc(*l, f); l++; } fputc('\n', f); } void output() { int i, l; int fi1=-2, fi2=-2; FILE *f0=0, *f1=0, *f2=0; char itag[256]; printf("output..."); fflush(stdout); printf(" tables..."); fflush(stdout); mkdir("it", 0777); for (i=0; i", tf); l = tables[i]; do { put_line(tf, line[l]); l++; } while (tag[l] == 0); trailer(tf); fclose(tf); } printf("%05d\b\b\b\b\b", i); fflush(stdout); } printf(" \b\b\b\b\b", i); fflush(stdout); printf(" interrupts..."); fflush(stdout); mkdir("id", 0777); for (i=0; i%s\n", categories[line[l][8]].desc); if (*lp != '-') { fprintf(df, "
Flags: "); while (*lp && flags[*lp].desc) { fputs(flags[*lp].desc, df); lp++; if (flags[*lp].desc) fputs(", ", df); } while (*lp && *lp != '-') lp++; } fprintf(df, "

\n

INT %02X %s\n\n", int_info[i].intno, lp);
	l += 2;
      }
      else
      {
	fputs("
", df);
	l++; /* skip line with desc, we already printed it */
      }

      do {
	put_line(df, line[l]);
	l++;
      } while (tag[l] == 0);
      trailer(df);
      fclose(df);
    }
    printf("%05d\b\b\b\b\b", i);
    fflush(stdout);
  }
  printf("     \b\b\b\b\b", i);
  fflush(stdout);

  printf(" indices...");
  fflush(stdout);
  mkdir("ix", 0777);
  f0 = fopen("ix/index.html", "w");
  header(f0, "Ralf Browns Interrupt List");
  fputs("
", f0);
  for (i=0; i%02X", j, j);
	    else
	      fprintf(f1, "   ");
	    if ((j&15) == 15)
	      fprintf(f1, "\n");
	  }
	}
	trailer(f1);
	fclose(f1);
      }
      if (byint[int_info[i].intno] < 30)
	sprintf(fn, "ix/%02X.html", int_info[i].intno);
      else
      {
	sprintf(fn, "ix/%02X", int_info[i].intno);
	mkdir(fn, 0777);
	sprintf(fn, "ix/%02X/index.html", int_info[i].intno);
      }
      fi1 = int_info[i].intno;
      memset(itag, 0, 256);
      f1 = fopen(fn, "w");
      if (f1 == 0)
      {
	perror(fn);
	exit(1);
      }
      header(f1, "Interrupt 0x%02X", fi1);
      fputs("
", f1);
      fi2 = -2;
    }
    if (int_info[i].regno != fi2 && int_info[i].regno != -1)
    {
      char fn[100];
      if (byint[int_info[i].intno] < 30)
	f2 = f1;
      else
      {
	if (f2 && f2 != f1)
	{
	  trailer(f2);
	  fclose(f2);
	}
	itag[int_info[i].regno] = 1;
	sprintf(fn, "ix/%02X/%02X.html", int_info[i].intno, int_info[i].regno);
	fi2 = int_info[i].regno;
	f2 = fopen(fn, "w");
	if (f2 == 0)
	{
	  perror(fn);
	  exit(1);
	}
	header(f2, "Int 0x%02X, AH=0x%02x", fi1, fi2);
	fputs("
", f2);
      }
    }

    if (int_info[i].intno == -1)
    {
      if (strcmp(int_info[i].desc, "Section")
	  && strcmp(int_info[i].desc, "Admin"))
	fprintf(f0, "%s\n",
		int_to_filename("../id", i),
		int_info[i].desc);
    }
    else if (int_info[i].regno == -1)
    {
      if (byint[int_info[i].intno] < 30)
	fprintf(f1, "%s %s\n",
		int_to_filename("../id", i),
		int_info[i].desc, line[int_info[i].line+1]);
      else
	fprintf(f1, "%s %s\n",
		int_to_filename("../../id", i),
		int_info[i].desc, line[int_info[i].line+1]);
    }
    else
    {
      if (f2 == f1)
	fprintf(f2, "%s %s\n",
		int_to_filename("../id", i),
		int_info[i].desc, line[int_info[i].line+1]);
      else
	fprintf(f2, "%s %s\n",
		int_to_filename("../../id", i),
		int_info[i].desc, line[int_info[i].line+1]);
    }
  }
  printf("   \b\b\b", i);
  fflush(stdout);

  fprintf(f0, "\n");
  for (i=0; i<256; i++)
  {
    if (byint[i])
    {
      if (byint[i] < 30)
	fprintf(f0, " %02X", i, i);
      else
	fprintf(f0, " %02X", i, i);
    }
    else
      fprintf(f0, "   ");
    if ((i&15) == 15)
      fprintf(f0, "\n");
  }

  trailer(f0);
  fclose(f0);
  if (f1)
  {
    int  j;
    fprintf(f1, "\n");
    for (j=0; j<256; j++)
    {
      if ((j%16)==0 && memcmp(zero32, itag+j, 32)==0)
	j += 15;
      else
      {
	if (itag[j])
	  fprintf(f1, " %02X", j, j);
	else
	  fprintf(f1, "   ");
	if ((j&15) == 15)
	  fprintf(f1, "\n");
      }
    }
    trailer(f1);
    fclose(f1);
  }
  if (f2 && f2 != f1)
  {
    trailer(f2);
    fclose(f2);
  }

  printf(" done.\n");
  fflush(stdout);
}

int
main(int argc, char **argv)
{
  read_files(argc>1?argv[1]:".");
  pass1();
  pass2();
  output();
  return 0;
}