/* 
   Pcm: a PC eMulator
   Copyright (C) 1992 Electronetics, Inc.  All rights reserved.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <fcntl.h>

#ifdef sun
#include <sys/types.h>
#include <sys/stat.h>
#endif /* sun */

#define extern
#include "sim.h"

extern int xwin;
int pcm_quit;

#ifndef SABER
/* Saber is reported to have trouble with varargs */
#include <varargs.h>

pcmexit(va_alist)
va_dcl {
  va_list args;
  char buf[10], *format;
  va_start(args);
  format = va_arg(args, char *);
  if (xwin) {
    window_exit();
  }
  vprintf(format, args);
  if (!pcm_quit) {
    printf("hit return to exit\n");
    fflush(stdout);
    gets(buf);
  }
  exit(1);
}
#endif

char *xmalloc(size)
int size; {
  char *rval, *malloc();
  if ((rval = malloc(size)) == NULL) {
    pcmexit("Out of core: %d bytes\n",size);
  }
  return rval;
}

extern char *keyfile;

main(argc, argv)
int argc; char *argv[]; {
  unsigned char *pc;
  int i;
  for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-') {
      switch(argv[i][1]) {
      }
    }
  }
  init_machine();
  init_int();
  pc = (unsigned char *)cold_boot();
  interpret_loop(pc);
}

init_machine() {
  int i = 0, nmatch;
  FILE *rc, *keys = NULL;  
  unsigned char buf[512];
  unsigned char arg[128],opt1[128],opt2[128];
  char *strchr(), *cp;
  init_parity();
/*
 * read .pcmrc file
 */
  if (!(rc = fopen(".pcmrc","r"))) {
    pcmexit("error reading .pcmrc\n");
  }
  while (fgets(buf, 127, rc)) {
    if (buf[0] == '#') continue;
    if (cp = strchr(buf,'\n')) {
      *cp = 0;
    }
    if ((nmatch = sscanf(buf,"%s %s %s",arg,opt1,opt2)) >= 2) {
      if (!strcmp(arg,"floppy")) {
        if (nmatch != 3 || assign_floppy(opt1,numdrives,opt2)) {
          printf("Bad floppy assignment ignored\n");
          continue;
        }
        numdrives++;
      }
      else if (!strcmp(arg,"bios")) {
/*
 * Read in bios
 */
        if ((i = open(opt1,0)) < 0) {
          pcmexit("Fatal Error: bios file \"%s\" not found\n",opt1);
        }
        read (i,pc_mem+0xfe000,8192);
        close(i);
      }
      else if (!strcmp(arg,"keys")) {
/*
 * Read key mapping info
 */
        if (!(keys = fopen(opt1,"r"))) {
          perror(opt1);
        }
      }
    }
    else if (nmatch == 1) {
      printf("%s ignored\n",arg);
    }
  }
  fclose(rc);
  if (numdrives == 0) {
    pcmexit("Fatal Error: No boot device\n");
  }
  if (!keys) {
    pcmexit("Fatal Error: Bad or missing key map file\n");
  }
  if (init_window(keys)) {
    pcmexit("Cannot initialize window\n");
  }
#ifdef READ_TIME
  if (!(trfile = fopen("time.read","r"))) {
    pcmexit("time.read not readable\n");
  }
#endif /* READ_TIME */
#ifdef WRITE_TIME
  if (!(twfile = fopen("time.write","w"))) {
    pcmexit("time.write not writable\n");
  }
#endif /* WRITE_TIME */
}

assign_floppy(name,curdrive,flptype)
char *name;
int curdrive; 
char *flptype;{
  if ((disk[curdrive].fd = open(name, O_NDELAY | O_RDWR | O_EXCL)) > 0) {
    disk[curdrive].readonly = 0;
  }
  else if ((disk[curdrive].fd = open(name, O_NDELAY | O_RDONLY)) > 0) {
    disk[curdrive].readonly = 1;
  }
  else {
    perror(name);
    disk[curdrive].fd = 0;
    return 1;
  }
  if (!strcmp(flptype,"360k")) {
    disk[curdrive].heads = 2;
    disk[curdrive].tracks = 40;
    disk[curdrive].sectors = 9;
  }
  else if (!strcmp(flptype,"720k")) {
    disk[curdrive].heads = 2;
    disk[curdrive].tracks = 80;
    disk[curdrive].sectors = 9;
  }
  else if (!strcmp(flptype,"1.2m")) {
    disk[curdrive].heads = 2;
    disk[curdrive].tracks = 80;
    disk[curdrive].sectors = 15;
  }
  else if (!strcmp(flptype,"1.44m")) {
    disk[curdrive].heads = 2;
    disk[curdrive].tracks = 80;
    disk[curdrive].sectors = 18;
  }
  else {
    printf("unknown media type %s\n",flptype);
    close(disk[curdrive].fd);
    disk[curdrive].fd = 0;
    return 1;
  }
  lseek(disk[curdrive].fd,0,0);
#ifdef sun
  {
    struct stat sbuf;
    if (!fstat(disk[curdrive].fd, &sbuf) && 
        (sbuf.st_mode & S_IFCHR) && 
        !floppy_setup(curdrive)) {
      disk[curdrive].devicep = 1;
    }
  }  
#endif /* sun */
  return 0;
}
