home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Misc / a2 / Source / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-21  |  4.7 KB  |  242 lines

  1. /*
  2.  *  a2, an Apple II emulator in C
  3.  *  (c) Copyright 1990 by Rich Skrenta
  4.  *
  5.  *  Command line interface written by Tom Markson
  6.  *
  7.  *  Distribution agreement:
  8.  *
  9.  *    You may freely copy or redistribute this software, so long
  10.  *    as there is no profit made from its use, sale, trade or
  11.  *    reproduction.  You may not change this copyright notice,
  12.  *    and it must be included prominently in any copy made.
  13.  *
  14.  *  Send emulator related mail to:  skrenta@blekko.commodore.com
  15.  *                    skrenta@blekko.uucp
  16.  */
  17.  
  18.  
  19.  
  20. #import    <stdio.h>
  21. #import    <libc.h>
  22. #import    <signal.h>
  23. #import    <fcntl.h>
  24. #import    "a2.h"
  25.  
  26.  
  27. int save_flags;            /* terminal flags */
  28. char escape_char = '~';
  29.  
  30. unsigned short Pc;
  31. unsigned char Sp = 0xFF;    /* stack pointer     */
  32. unsigned int  A = 0;        /* accumulator        */
  33. unsigned char X = 0;        /* X register        */
  34. unsigned char Y = 0;        /* Y register        */
  35.  
  36. unsigned int N = 0;        /* 7 - sign        */
  37. unsigned int V = 0;        /* 6 - Overflow        */
  38.                 /* 5 - Unused        */
  39. unsigned int B = 1;        /* 4 - Break        */
  40. unsigned int D = 0;        /* 3 - Decimal        */
  41. unsigned int I = 0;        /* 2 - Interrupt    */
  42. unsigned int NZ = 1;        /* 1 - Zero        */
  43. unsigned int C = 0;        /* 0 - Carry        */
  44.  
  45. int term_lines, term_cols;
  46. int running = TRUE;
  47. int tracing = FALSE;
  48.  
  49. int disk[] = {-1, -1};
  50. int write_prot[2];
  51. int drive = 0;
  52.  
  53.  
  54. void restore_term(void)
  55. {
  56.   
  57. #ifdef STUFFY_TURTLE
  58.   SetNormal();                /* Turn off inverse video */
  59. #endif
  60.   Raw(FALSE);
  61.   fcntl(0, F_SETFL, save_flags);
  62.   signal(SIGINT, SIG_DFL);
  63. }
  64.  
  65. void asfail( char    *file, int    line, char    *cond)
  66. {
  67.   fprintf(stderr, "assertion failure: %s (%d): %s\n", file, line, cond);
  68.   restore_term();
  69.   abort();
  70.   exit(1);
  71. }
  72.  
  73. void cleanup(int signum)
  74. {
  75.   restore_term();
  76.   exit(0);
  77. }
  78.  
  79.  
  80. void catch_intr(int signum)
  81. {
  82.   signal(SIGINT, catch_intr);
  83.   running = FALSE;
  84.   tracing = FALSE;
  85. }
  86.  
  87. void set_term(void)
  88. {
  89.   signal(SIGINT, catch_intr);
  90.   signal(SIGQUIT, cleanup);
  91.   signal(SIGTERM, cleanup);
  92.   save_flags = fcntl(0, F_GETFL, 0);
  93.   Raw(TRUE);
  94. }
  95.  
  96. int bload(char *fnam, unsigned short addr)
  97. {
  98.   int fd;
  99.   long len;
  100.   
  101.   if ((fd = open(fnam, O_RDONLY)) < 0) {
  102.     fprintf(stderr, "can't open %s: ", fnam);
  103.     perror("");
  104.     return(FALSE);
  105.   }
  106.   
  107.   len = 65536 - addr;
  108.   
  109.   if (len == 65536) {        /* stupid $%!*&#~ 16 bit systems */
  110.     if (read(fd, &mem[addr], 4096) < 0) {
  111.       fprintf(stderr, "bad read of %s: ", fnam);
  112.       perror("");
  113.       return(FALSE);
  114.     }
  115.     
  116.     addr += 4096;
  117.     len -= 4096;
  118.   }
  119.   
  120.   if (read(fd, &mem[addr], len) < 0) {
  121.     fprintf(stderr, "bad read of %s: ", fnam);
  122.     perror("");
  123.     return(FALSE);
  124.   }
  125.   
  126.   close(fd);
  127.   return(TRUE);
  128. }
  129.  
  130. void bsave(char *fnam, unsigned short addr, unsigned short size)
  131. {
  132.   int fd;
  133.   unsigned sizel;
  134.   int x;
  135.   sizel=size;
  136.   if (sizel==0) sizel=65535;
  137.   if ((fd=open(fnam,O_WRONLY|O_CREAT,0644)) < 0) {
  138.     printf("can't open %s: ", fnam);
  139.     perror("");
  140.     return;
  141.   }
  142.   x=write(fd,&mem[addr],sizel);
  143.   if (size == 0)
  144.     x=write(fd,&mem[65535],1);
  145.   if (x==-1) perror("write");
  146.   close(fd);
  147. }
  148.  
  149.  
  150. /*
  151.  *  I make certain assumptions about rollover so that I can do
  152.  *  things like X++ and know that if X is 0xFF it will rollover
  153.  *  to 0x00.  If I didn't know this I'd have to do X = (X+1) & 0xFF
  154.  *  If your machine assert fails on the code below you'll have to
  155.  *  rewrite the code that depends on rollover
  156.  */
  157.  
  158. void safety_check(void)
  159. {
  160.   unsigned char c;
  161.   unsigned short s;
  162.   
  163.   c = 0xFF;
  164.   assert(++c == 0x00);
  165.   assert(--c == 0xFF);
  166.   
  167.   s = 0xFFFF;
  168.   assert(++s == 0x0000);
  169.   assert(--s == 0xFFFF);
  170. }
  171.  
  172.  
  173. void simulator_main(int argc,char **argv)
  174. {
  175.   int c;
  176.   int errflag = 0;
  177.   char *f8rom, *d0rom;
  178.   int cli_first = FALSE;
  179.   
  180.   safety_check();
  181.   f8rom = "AUTOSTART.ROM";
  182.   d0rom = "APPLESOFT.ROM";
  183.   
  184.   while ((c = getopt(argc, argv, "cim")) != -1) {
  185.     switch (c) {
  186.     case 'c':
  187.       cli_first = TRUE;
  188.       break;
  189.       
  190.     case 'i':
  191.       d0rom = "INTEGER.ROM";
  192.       break;
  193.       
  194.     case 'm':
  195.       f8rom = "MONITOR.ROM";
  196.       break;
  197.       
  198.     case '?':
  199.     default:
  200.       errflag++;
  201.     }
  202.   }
  203.   
  204.   if (errflag) {
  205.     fprintf(stderr, "usage:  %s\n", argv[0]);
  206.     fprintf(stderr, "\t-m\tLoad MONITOR.ROM instead of AUTOSTART.ROM at $F800\n");
  207.     fprintf(stderr, "\t-i\tLoad INTEGER.ROM instead of APPLESOFT.ROM at $D000\n");
  208.     fprintf(stderr, "\t-c\tEnter command mode before executing any instructions\n");
  209.     exit(1);
  210.   }
  211.   
  212.   printf("a2 -- Apple II emulator.  Escape character is %c\n",
  213.      escape_char);
  214.   
  215.   if (!bload(f8rom, 0xF800))
  216.     exit(1);
  217.   bload(d0rom, 0xD000);
  218.   bload("DISK.PROM", 0xC600);
  219.   
  220.   if (!InitScreen())
  221.     exit(1);
  222.   ScreenSize(&term_lines, &term_cols);
  223.   
  224.   memory_setup();
  225.   set_special_jumps();
  226.   Pc = join(mem[0xFFFC], mem[0xFFFD]);
  227.  
  228.   /* mjhostet HACK */
  229.   insert_disk ("Samp.disk");
  230.  
  231.   
  232.   if (cli_first)
  233.     cli();
  234.   else
  235.     ClearScreen();
  236.   while (1) {
  237.     set_term();
  238.     run();
  239.     cli();
  240.   }
  241. }
  242.