ftp.nice.ch/pub/next/tools/emulators/a2.N.bs.tar.gz#/a2/main.c

This is main.c in view mode; [Download] [Up]

/*
 *  a2, an Apple II emulator in C
 *  (c) Copyright 1990 by Rich Skrenta
 *
 *  Command line interface written by Tom Markson
 *
 *  Distribution agreement:
 *
 *	You may freely copy or redistribute this software, so long
 *	as there is no profit made from its use, sale, trade or
 *	reproduction.  You may not change this copyright notice,
 *	and it must be included prominently in any copy made.
 *
 *  Send emulator related mail to:  skrenta@blekko.commodore.com
 *				    skrenta@blekko.uucp
 */



#include	<stdio.h>
#include	<signal.h>
#include	<fcntl.h>
#include	"a2.h"


int save_flags;			/* terminal flags */
char escape_char = '~';

unsigned short Pc;
unsigned char Sp = 0xFF;	/* stack pointer 	*/
unsigned int  A = 0;		/* accumulator		*/
unsigned char X = 0;		/* X register		*/
unsigned char Y = 0;		/* Y register		*/

unsigned int N = 0;		/* 7 - sign		*/
unsigned int V = 0;		/* 6 - Overflow		*/
				/* 5 - Unused		*/
unsigned int B = 1;		/* 4 - Break		*/
unsigned int D = 0;		/* 3 - Decimal		*/
unsigned int I = 0;		/* 2 - Interrupt	*/
unsigned int NZ = 1;		/* 1 - Zero		*/
unsigned int C = 0;		/* 0 - Carry		*/

int term_lines, term_cols;
int running = TRUE;
int tracing = FALSE;

int disk[] = {-1, -1};
int write_prot[2];
int drive = 0;


simulator_main(argc, argv)
     int argc;
     char **argv;
{
  int c;
  int errflag = 0;
  char *f8rom, *d0rom;
  int cli_first = FALSE;
  
  safety_check();
  f8rom = "AUTOSTART.ROM";
  d0rom = "APPLESOFT.ROM";
  
  while ((c = getopt(argc, argv, "cim")) != -1) {
    switch (c) {
    case 'c':
      cli_first = TRUE;
      break;
      
    case 'i':
      d0rom = "INTEGER.ROM";
      break;
      
    case 'm':
      f8rom = "MONITOR.ROM";
      break;
      
    case '?':
    default:
      errflag++;
    }
  }
  
  if (errflag) {
    fprintf(stderr, "usage:  %s\n", argv[0]);
    fprintf(stderr, "\t-m\tLoad MONITOR.ROM instead of AUTOSTART.ROM at $F800\n");
    fprintf(stderr, "\t-i\tLoad INTEGER.ROM instead of APPLESOFT.ROM at $D000\n");
    fprintf(stderr, "\t-c\tEnter command mode before executing any instructions\n");
    exit(1);
  }
  
  printf("a2 -- Apple II emulator.  Escape character is %c\n",
	 escape_char);
  
  if (!bload(f8rom, 0xF800))
    exit(1);
  bload(d0rom, 0xD000);
  bload("DISK.PROM", 0xC600);
  
  if (!InitScreen())
    exit(1);
  ScreenSize(&term_lines, &term_cols);
  
  memory_setup();
  set_special_jumps();
  Pc = join(mem[0xFFFC], mem[0xFFFD]);

  /* mjhostet HACK */
  insert_disk ("Samp.disk");

  
  if (cli_first)
    cli();
  else
    ClearScreen();
  while (1) {
    set_term();
    run();
    cli();
  }
}


restore_term() {
  
  /*	SetNormal();				/* Turn off inverse video */
  Raw(FALSE);
  fcntl(0, F_SETFL, save_flags);
  signal(SIGINT, SIG_DFL);
}


set_term() {
  int catch_intr();
  int cleanup();
  
  signal(SIGINT, catch_intr);
  signal(SIGQUIT, cleanup);
  signal(SIGTERM, cleanup);
  save_flags = fcntl(0, F_GETFL, 0);
  Raw(TRUE);
}


cleanup() {
  
  restore_term();
  exit(0);
}


catch_intr() {
  
  signal(SIGINT, catch_intr);
  running = FALSE;
  tracing = FALSE;
}


bload(fnam, addr)
     char *fnam;
     unsigned short addr;
{
  int fd;
  long len;
  
  fd = open(fnam, O_RDONLY);
  if (fd < 0) {
    fprintf(stderr, "can't open %s: ", fnam);
    perror("");
    return(FALSE);
  }
  
  len = 65536 - addr;
  
  if (len == 65536) {		/* stupid $%!*&#~ 16 bit systems */
    if (read(fd, &mem[addr], 4096) < 0) {
      fprintf(stderr, "bad read of %s: ", fnam);
      perror("");
      return(FALSE);
    }
    
    addr += 4096;
    len -= 4096;
  }
  
  if (read(fd, &mem[addr], len) < 0) {
    fprintf(stderr, "bad read of %s: ", fnam);
    perror("");
    return(FALSE);
  }
  
  close(fd);
  return(TRUE);
}

bsave(fnam, addr, size)
     char *fnam;
     unsigned short addr,size;
{
  int fd;
  unsigned sizel;
  int x;
  sizel=size;
  if (sizel==0) sizel=65535;
  fd=open(fnam,O_WRONLY|O_CREAT,0644);
  if (fd < 0) {
    printf("can't open %s: ", fnam);
    perror("");
    return;
  }
  x=write(fd,&mem[addr],sizel);
  if (size == 0)
    x=write(fd,&mem[65535],1);
  if (x==-1) perror("write");
  close(fd);
}


/*
 *  I make certain assumptions about rollover so that I can do
 *  things like X++ and know that if X is 0xFF it will rollover
 *  to 0x00.  If I didn't know this I'd have to do X = (X+1) & 0xFF
 *  If your machine assert fails on the code below you'll have to
 *  rewrite the code that depends on rollover
 */

safety_check() {
  unsigned char c;
  unsigned short s;
  
  c = 0xFF;
  assert(++c == 0x00);
  assert(--c == 0xFF);
  
  s = 0xFFFF;
  assert(++s == 0x0000);
  assert(--s == 0xFFFF);
}


asfail(file, line, cond)
     char	*file;
     int	line;
     char	*cond;
{
  fprintf(stderr, "assertion failure: %s (%d): %s\n", file, line, cond);
  restore_term();
  abort();
  exit(1);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.