home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
-
-
- 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]);
-
- 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);
- }
-
-