home *** CD-ROM | disk | FTP | other *** search
- From: skrenta@blekko.UUCP (Rich Skrenta)
- Newsgroups: alt.sources
- Subject: a2 - Apple II emulator, part 2/2
- Message-ID: <123@blekko.UUCP>
- Date: 23 May 90 16:35:40 GMT
-
-
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # This archive contains:
- # cli.c cli.h commands.c dos.c
- # hex.c jump.c main.c mapper.c
- # mem.c parse.c prodos.c screen.c
- # table.c vidout.c
- #
-
- echo x - cli.c
- cat >cli.c <<'@EOF'
- /*
- * 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 <setjmp.h>
- #include <signal.h>
- #include "a2.h"
- #include "cli.h"
-
-
- FILE *logging_fp = NULL;
- long breakpoint = -1;
- long trace_lo = -1;
- long trace_hi;
- int in_cli;
-
- unsigned short lpoint; /* point where dissassembly occurs */
- long phantom_location = -1;
- int map_to_upper = 1;
- jmp_buf jb;
-
- cli_catch() {
- signal(SIGINT,cli_catch);
- printf("\n");
- longjmp(jb,1);
- }
-
- cli()
- {
- char foo[200];
-
- restore_term();
- MoveCursor(term_lines, 0);
- status(stdout);
- in_cli = TRUE;
- lpoint = Pc;
- signal(SIGINT, cli_catch);
- setjmp(jb);
- do {
- printf(">>>");
- if (fgets(foo, 200, stdin) == NULL) {
- printf("\n");
- exit(0);
- }
- foo[strlen(foo)-1] = '\0';
- if (parse(first_tbl, foo)) {
- running = FALSE;
- tracing = FALSE;
- return; /* single step; no redraw */
- }
- } while (in_cli);
-
- set_term();
- redraw_screen();
- if (breakpoint != -1 || trace_lo != -1) {
- tracing = TRUE;
- running = FALSE;
- } else {
- tracing = FALSE;
- running = TRUE;
- }
- }
-
-
- status(fp)
- FILE *fp;
- {
-
- diss(Pc, fp);
- flags(fp);
- }
-
-
- @EOF
-
- chmod 644 cli.c
-
- echo x - cli.h
- cat >cli.h <<'@EOF'
- /*
- * 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
- */
-
-
-
- /*
- * Return codes for match(), find_box(), and parse()
- */
-
- #define NO_MATCH -1 /* strings are different */
- #define PARTIAL -3 /* partial match */
- #define IDENTICAL -4 /* strings matched perfectly */
-
- #define AMBIGUOUS -2 /* amiguous match */
- #define OK -5 /* command executed ok */
- #define NOT_IMPLEMENTED -6 /* haven't written this one yet */
- #define DISPLAY -7 /* redisplay the diss & flags line */
-
- #define MAXSTACK 100
-
- struct cmdtbl {
- char *name;
- int (*func)();
- };
-
- extern long breakpoint;
- extern struct cmdtbl first_tbl[];
- extern int in_cli;
- extern long trace_lo, trace_hi;
- extern long get_hex_number();
- extern FILE *logging_fp;
- extern char *getenv();
- extern char *split();
-
- @EOF
-
- chmod 644 cli.h
-
- echo x - commands.c
- cat >commands.c <<'@EOF'
- /*
- * 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 <ctype.h>
- #include <signal.h>
- #include "a2.h"
- #include "cli.h"
-
-
- extern unsigned short lpoint;
- extern long phantom_location;
- extern char *getcwd();
- extern int map_to_upper;
- extern char escape_char;
- long get_hex_number();
-
- char diskname[2][200]; /* disk names stored here */
-
- struct point_stack {
- unsigned short data[MAXSTACK];
- int sp;
- } pstack;
-
- init_point(){
- pstack.sp = -1;
- }
-
- pop_point(rest)
- char *rest;
- {
- if (pstack.sp < 0 ) {
- printf("stack empty\n");
- return OK;
- }
- switch (*rest){
- case 'l':
- case 'L':
- printf("%x\n", lpoint = pstack.data[pstack.sp--]);
- break;
- case 'p':
- case 'P':
- printf("%x\n", lpoint = pstack.data[pstack.sp--]);
- break;
- default :
- printf("pop [lp]\n");
- break;
- }
- return(OK);
- }
-
- dup_point(rest)
- char *rest;
- {
- if (pstack.sp < 0 ) {
- printf("stack empty\n");
- return OK;
- }
- switch (*rest){
- case 'l':
- case 'L':
- lpoint = pstack.data[pstack.sp];
- break;
- case 'p':
- case 'P':
- lpoint = pstack.data[pstack.sp];
- break;
- default :
- printf("dup [lp]\n");
- break;
- }
- return(OK);
- }
-
- push_point(rest)
- char *rest;
- {
- long value;
- char *addr;
-
- assert (pstack.sp < MAXSTACK);
- switch (*rest){
- case 'l':
- case 'L':
- pstack.data[++pstack.sp] = lpoint;
- break;
- case 'p':
- case 'P':
- pstack.data[++pstack.sp] = Pc;
- break;
- default:
- addr = rest;
- rest = split(rest);
- value = get_hex_number(addr);
- if (value == -1L)
- printf("push [l|p|<addr>]\n");
- else
- pstack.data[++pstack.sp]=(unsigned short)value;
- break;
- }
- return(OK);
- }
-
-
- clb(junk)
- char *junk;
- {
-
- B = 0;
- return(DISPLAY);
- }
-
-
- seb(junk)
- char *junk;
- {
-
- B = 1;
- return(DISPLAY);
- }
-
-
- clc(junk)
- char *junk;
- {
- C = 0;
- return(DISPLAY);
- }
-
-
- sec(junk)
- char *junk;
- {
- C = 1;
- return(DISPLAY);
- }
-
-
- sev(junk)
- char *junk;
- {
- V = 1;
- return(DISPLAY);
- }
-
-
- clv(junk)
- char *junk;
- {
- V = 0;
- return(DISPLAY);
- }
-
-
- sed(junk)
- char *junk;
- {
- D = 1;
- return(DISPLAY);
- }
-
-
- cld(junk)
- char *junk;
- {
- D = 0;
- return(DISPLAY);
- }
-
-
- sei(junk)
- char *junk;
- {
- I = 1;
- return(DISPLAY);
- }
-
-
- clri(junk)
- char *junk;
- {
- I = 0;
- return(DISPLAY);
- }
-
-
- sen(junk)
- char *junk;
- {
- N = 1;
- return(DISPLAY);
- }
-
-
- cln(junk)
- char *junk;
- {
- N = 0;
- return(DISPLAY);
- }
-
-
- sez(junk)
- char *junk;
- {
- NZ = 0;
- return(DISPLAY);
- }
-
-
- clz(junk)
- char *junk;
- {
- NZ = 1;
- return(DISPLAY);
- }
-
-
- quit_emulator(junk)
- char *junk;
- {
- exit(0);
- }
-
-
-
- ver(junk)
- char *junk;
- {
- printf("a2 - Apple II emulator (c) Copyright 1990 by Rich Skrenta & Tom Markson\n");
- return(OK);
- }
-
-
- refresh(junk)
- char *junk;
- {
-
- in_cli = FALSE;
- return(OK);
- }
-
-
- shell_escape(rest)
- char *rest;
- {
- char line[100];
- char *s;
-
- s = getenv("SHELL");
- if (s == NULL)
- s = "/bin/sh";
-
- strcpy(line, s);
-
- if (*rest != '\0') {
- strcat(line, " -c '");
- strcat(line, rest);
- strcat(line, "'");
- }
- system(line);
-
- printf("\n");
- return(OK);
- }
-
-
- do_soft_reset(rest)
- char *rest;
- {
-
- Pc = mem[0xFFFC] | (mem[0xFFFD] << 8);
- return(DISPLAY);
- }
-
-
- do_bload(rest)
- char *rest;
- {
- char *first;
- char *file;
- unsigned short start;
- long foo;
-
- file = rest;
- rest = split(rest);
- first = rest;
- rest = split(rest);
- foo = get_hex_number(first);
- if (foo == -1) {
- printf("usage: bload file hex-address\n");
- return(OK);
- }
- start = (unsigned int) foo;
- bload(file, start);
-
- return(OK);
- }
-
-
- do_bsave(rest)
- char *rest;
- {
- char *startc, *sizec, *file;
- unsigned short start, size;
- long istart, iend;
- file = rest;
- rest = split(rest);
- startc = rest;
- rest = split(rest);
- sizec = rest;
- rest = split(rest);
- istart = get_hex_number(startc);
- iend = get_hex_number(sizec);
- if ((istart == -1) || (iend == -1))
- printf("usage: bsave file hex-address hex-length\n");
- else {
- start = (unsigned short) istart;
- size = (unsigned short) iend;
- bsave(file, start, size);
- }
-
- return(OK);
- }
-
-
-
- show_point(rest)
- char *rest;
- {
-
- lpoint = Pc;
- return(DISPLAY);
- }
-
-
- hack(rest)
- char *rest;
- {
- extern int cur_track;
-
- cur_track = get_hex_number(rest);
- return(OK);
- }
-
-
- do_jump(rest)
- char *rest;
- {
- char *start;
- long istart;
- start = rest;
- rest = split(rest);
- istart = get_hex_number(start);
-
- if (istart == -1) {
- printf("usage: jmp <hex address>\n");
- return(OK);
- } else {
- Pc = istart & 0xFFFF;
- return(DISPLAY);
- }
- }
-
-
-
- trace(rest)
- char *rest;
- {
- char *addr1, *addr2, *file;
- long addr1i, addr2i;
-
- addr1 = rest;
- rest = split(rest);
- addr2 = rest;
- rest = split(rest);
- file = rest;
- rest = split(rest);
- addr1i = get_hex_number(addr1);
- addr2i = get_hex_number(addr2);
- if (addr1i == -1 && addr2i == -1) {
- if (trace_lo == -1)
- printf("No trace region set\n");
- else
- printf("Tracing between $%.4X and $%.4x\n",
- trace_lo, trace_hi);
- return(OK);
- }
-
- if (addr1i == -1 || addr2i == -1) {
- printf("usage: trace [low high]\n");
- return(OK);
- }
-
- if (logging_fp == NULL) {
- if (*file == '\0' || file == NULL) {
- printf("Trace log will go to file 'trace'.\n");
- file = "trace";
- }
- logging_fp = fopen(file, "w");
- if (logging_fp == NULL) {
- perror("can't open trace file");
- trace_lo = -1;
- return(OK);
- }
- }
-
- trace_lo = addr1i & 0xFFFF;
- trace_hi = addr2i & 0xFFFF;
-
- return(OK);
- }
-
-
- ldx(rest)
- char *rest;
- {
- long number;
- char *first;
-
- first = rest;
- rest = split(rest);
- number = get_hex_number(first);
-
- number &= 0xFF;
- if (number < 0) {
- printf("usage: ldx <hex number>\n");
- return(OK);
- }
-
- X = number & 0xFF;
- return(DISPLAY);
- }
-
-
- ldy(rest)
- char *rest;
- {
- long number;
- char *first;
- first = rest;
- rest = split(rest);
- number = get_hex_number(first);
-
- if (number < 0) {
- printf("usage: ldy <hex number>\n");
- return(OK);
- }
-
- Y = number & 0xFF;
- return(DISPLAY);
- }
-
-
- lda(rest)
- char *rest;
- {
- long number;
- char *first;
- first = rest;
- rest = split(rest);
- number = get_hex_number(first);
- if (number < 0) {
- printf("usage: lda <hex number>\n");
- return(OK);
- }
-
- A = number & 0xFF;
- return(DISPLAY);
- }
-
-
- lds(rest)
- char *rest;
- {
- long number;
- char *first;
- first = rest;
- rest = split(rest);
- number = get_hex_number(first);
- if (number < 0) {
- printf("usage: lds <hex number>\n");
- return(OK);
- }
-
- Sp = number & 0xFF;
- return(DISPLAY);
- }
-
-
- set_break_point(rest)
- char *rest;
- {
- long addr;
- char *first;
- first = rest;
- rest = split(rest);
- addr = get_hex_number(first);
- if (addr == -1)
- if (breakpoint == -1)
- printf("no breakpoint set\n");
- else
- printf("break point set at %x\n",
- (unsigned short)breakpoint);
- else
- breakpoint = addr;
- running = FALSE;
- return(OK);
- }
-
-
- clear_break_point(rest)
- char *rest;
- {
- breakpoint = -1;
- return(OK);
- }
-
-
- notrace(junk)
- char *junk;
- {
-
- trace_lo = -1;
- if (logging_fp == NULL)
- return(OK);
- else
- fclose(logging_fp);
- logging_fp = NULL;
- return(OK);
- }
-
-
- insert_disk(rest)
- char *rest;
- {
- char *name;
- char *which;
- int fd;
- int read_only = 0;
-
- name = rest;
- rest = split(rest);
- which = rest;
- rest = split(rest);
-
- if (name == NULL || *name == '\0') {
- printf("usage: insert <file name> [drive]\n");
- return(OK);
- }
-
- fd = open(name, 2); /* attempt open for read/write */
- if (fd >= 0)
- read_only = 0;
- else { /* attempt open read only */
- read_only = 1;
- fd = open(name, 0);
- }
- if (fd < 0) {
- fprintf(stderr, "can't open %s: ", name);
- perror("");
- return(OK);
- }
-
- if (*which == '2')
- drive = 1;
- else
- drive = 0;
-
- if (disk[drive] >= 0)
- close(disk[drive]);
-
- strcpy(diskname[drive], name);
-
- disk[drive] = fd;
- write_prot[drive] = read_only;
-
- printf("disk %d inserted, %swrite protected\n", drive + 1,
- read_only ? "" : "not ");
-
- return(OK);
- }
-
-
- dissassemble(rest)
- char *rest;
- {
- unsigned short start,end;
- long istart;
- long iend;
- int count = 0;
- char *first,*last;
-
- first = rest;
- rest = split(rest);
- last = rest;
- rest = split(rest);
-
- istart = get_hex_number(first);
- iend = get_hex_number(last);
- if (istart != -1)
- lpoint = istart;
- if (iend == -1)
- iend=65537;
- while ( (long) lpoint < iend) {
- lpoint += diss(lpoint, stdout);
- printf("\n");
- count++;
- if (iend == 65537)
- if (count > term_lines-3)
- break;
- }
- return OK;
- }
-
- ascii_dump(l,h)
- unsigned short l,h;
- {
- while (l < h) {
- if (isprint(mem[l]))
- printf("%c",mem[l]);
- else
- printf(".");
- l++;
- }
- }
-
- hex_dump(rest)
- char *rest;
- {
- char *start,*end;
- unsigned short last, addr,oaddr;
- long iaddr1,iaddr2;
- int count;
-
- start = rest;
- rest = split(rest);
- end = rest;
- rest = split(rest);
- iaddr1 = get_hex_number( start );
- iaddr2 = get_hex_number( end );
-
- if (iaddr2 != -1 && iaddr1 > iaddr2)
- return(OK);
-
- if (iaddr1 != -1)
- lpoint = (unsigned short) iaddr1;
- if (iaddr2 == -1)
- last = lpoint + 1;
- else
- last = (unsigned short) iaddr2 + 1;
-
- last &= 0xFFFF;
-
- addr = lpoint;
- count = 0;
- printf("%.4X: ", addr);
- oaddr = addr;
- do {
- if (count % 16 == 0 && count != 0) {
- ascii_dump(oaddr,addr);
- oaddr = addr;
- printf("\n%.4X: ", addr);
- }
- printf("%.2X ", mem[addr]);
- addr++;
- count++;
- } while (addr != last);
- while ((count % 16) != 0) {
- printf(" "); /* 3 spaces dd_ */
- count++;
- }
- ascii_dump(oaddr,addr);
- printf("\n");
- return(OK);
- }
-
- deposit(rest)
- char *rest;
- {
- char *addr;
- char *value;
- unsigned short location;
- long iloc;
- unsigned char val;
- int fired_once;
-
- addr = rest;
- rest = split(rest);
- fired_once = 0;
- iloc = get_hex_number(addr);
- if (iloc == -1) {
- printf("usage: deposit <addr> <value> [<value>...]\n");
- return(OK);
- }
-
- location = (unsigned short) iloc;
- do {
- value = rest;
- rest = split(rest);
- val = get_hex_number(value);
- if (val == -1) {
- if (!fired_once)
- printf("Invalid or Missing Hex address\n");
- return OK;
- }
- mem[location++] = val;
- fired_once = 1;
- } while (*rest != '\0');
-
- return(OK);
- }
-
- phantom_trace(rest)
- char *rest;
- {
- char *phantoms;
- char *addr1s;
- char *addr2s;
- char *file;
- long phantom;
- long low_val,high_val;
- int err = 0;
-
- phantoms = rest;
- rest = split(rest);
- addr1s = rest;
- rest = split(rest);
- addr2s = rest;
- rest = split(rest);
- file = rest;
- rest = split(rest);
-
- phantom = (unsigned short)get_hex_number(phantoms);
- low_val = get_hex_number(addr1s);
- high_val = get_hex_number(addr2s);
- if (*phantoms == '\0') {
- if (phantom_location == -1) {
- printf("The phantom sleeps.");
- if (trace_lo != -1 && trace_hi != -1)
- printf("however, a trace is active.");
- printf("\n");
- } else
- printf("the phantom waits until Pc = %.4X and then traces from %.4X to %.4X\n",phantom_location,trace_lo,trace_hi);
- return(OK);
- }
- if (low_val == -1 || high_val == -1 || phantom == -1) {
- printf("usage: phantom <addr> <addr> <addr> [file]\n");
- return OK;
- } phantom_location = phantom; trace_lo = low_val; trace_hi = high_val; if (logging_fp == NULL) {
- if (*file == '\0' || file == NULL) {
- printf("the phantom will trace to file 'trace'.\n");
- file = "trace";
- }
- logging_fp = fopen(file, "w");
- if (logging_fp == NULL) {
- perror("can't open trace file");
- trace_lo = -1;
- return(OK);
- }
- }
- return OK;
- }
-
- no_phantom_trace(rest)
- char *rest;
- {
- phantom_location = -1;
- trace_lo = -1;
- printf("the phantom goes to sleep.\n");
- if (logging_fp == NULL)
- return OK;
- fclose(logging_fp);
- logging_fp = NULL;
- return OK;
- }
-
- cd(rest)
- char *rest;
- {
-
- char *first;
- char path[200];
-
- first = rest;
- rest = split(rest);
- if (*first != '\0') {
- if (chdir(first)) {
- perror("cd");
- printf("CWD remains ");
- }
- }
- printf("%s\n",getcwd(path,198));
- return OK;
- }
-
- map(rest)
- char *rest;
- {
- map_to_upper = !map_to_upper;
- printf("Uppercase Mapping is %s\n",(map_to_upper)?"On":"Off");
- return OK;
- }
-
- sex(rest)
- char *rest;
- {
- printf("You'll need a real Apple for that sort of thing\n");
- return OK;
- }
-
-
- help(rest)
- char *rest;
- {
- printf("![command] Escape to Unix\n");
- printf(". Display Current Pc Point\n");
- printf("bload file addr load binary file into mem at addr\n");
- printf("breakpoint [addr] Set the Breakpoint to addr\n");
- printf("bsave file start end Save Memory from start to end in file\n");
- printf("cd [directory] Set/Show Current Working Directory\n");
- printf("cl[cdinvz] Clear appropriate Status Bit\n");
- printf("continue Resume Execution of Emulator\n");
- printf("deposit addr [val]+ Put val(s) into addr\n");
- printf("dup [l|p] duplicate top of stack into l or p\n");
- printf("escape char set escape char to be char \n");
- printf("examine addr Display Value in addr\n");
- printf("insert file drive# Make file disk in drive#\n");
- printf("jmp addr Make Pc=addr\n");
- printf("ld[asxy] val Load Register with val\n");
- printf("list [addr] [addr] Dissassemble at point or addr\n");
- printf("map Toggle lower -> upper case mapping\n");
- printf("nobreak Turn off breakpoint\n");
- printf("pop [l|p] get p or l from top of stack\n");
- printf("push [l|p|<addr> push l,p, or hex addr on stack\n");
- printf("reset Pc = Apple Reset Vector\n");
- printf("se[cdinvz] Set appropriate Status Flag\n");
- printf("trace [addr] [addr] Trace Between addresses/display trace point\n");
- return OK;
- }
-
- set_escape_char(rest)
- char *rest;
- {
- char c;
- if (*rest != '\0')
- escape_char = *rest;
- printf("escape character is ");
- if (isprint(escape_char))
- printf("%c",(int)escape_char);
- else
- printf("^%c",(char)escape_char+64);
- printf(" (0x%.2X)",(int)escape_char);
- printf("\n");
- return(OK);
- }
-
- disk_names(rest)
- char *rest;
- {
-
- printf("drive 1: %s\n", disk[0] >= 0 ? diskname[0] : "empty");
- printf("drive 2: %s\n", disk[1] >= 0 ? diskname[1] : "empty");
- return(OK);
- }
- @EOF
-
- chmod 644 commands.c
-
- echo x - dos.c
- cat >dos.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
-
- char *rwts_func[] = {"-s", "", "-w", "-?", "-f"};
-
-
- rwts() {
- char s[50];
- unsigned short iob;
- unsigned short buf;
- int track;
- int sector;
- int cmd;
- char zero_buf[256];
- int i;
-
- mem[0x48] = Y;
- mem[0x49] = A;
- mem[0x6F8] = 2;
- mem[0x4F8] = 4;
-
- iob = join(Y, A);
-
- track = mem[iob + 4];
- sector = mem[iob + 5];
- buf = join(mem[iob + 8], mem[iob + 9]);
- cmd = mem[iob + 12];
-
- if (cmd > 4)
- cmd = 3; /* unknown command */
-
- if (mem[iob + 2] == 2)
- drive = 1;
- else
- drive = 0;
-
- if ((cmd == 2 || cmd == 4) && write_prot[drive]) {
- C = 1;
- mem[iob + 13] = 0x10; /* Write protected */
- DO_RTS;
- return;
- }
-
- if (mem[iob] != 1
- || disk[drive] < 0
- || track > 35
- || sector > 15
- || cmd == 3
- || buf > 0xFE00) {
- C = 1;
- mem[iob + 13] = 0x40; /* IO Error */
- DO_RTS;
- return;
- }
-
- sprintf(s, "rwts%s t=%d s=%d%s", rwts_func[cmd],
- track, sector, drive ? " d2" : "");
- info(s);
-
- switch (cmd) {
- case 0: /* seek */
- break;
-
- case 1: /* read */
- read_disk(track, sector, &mem[buf]);
- break;
-
- case 2: /* write */
- write_disk(track, sector, &mem[buf]);
- break;
-
- case 4: /* format */
- for (i = 0; i < 256; i++)
- zero_buf[i] = 0;
-
- for (track = 0; track < 35; track++)
- for (sector = 0; sector < 16; sector++)
- write_disk(track, sector, zero_buf);
- break;
- }
-
- C = 0;
- A = 0;
- DO_RTS;
- }
-
- @EOF
-
- chmod 644 dos.c
-
- echo x - hex.c
- cat >hex.c <<'@EOF'
-
- /*
- * Turn an Apple II monitor ROM hex dump back into binary data
- * usage: hex < hex_data > bin_data
- */
-
-
- #include <stdio.h>
-
- main() {
- char buf[100];
- int i, j;
- int addr;
- int m[8];
- unsigned char c;
-
- while (fgets(buf, 100, stdin) != NULL) {
- i = sscanf(buf, "%x- %x %x %x %x %x %x %x %x",
- &addr, &m[0], &m[1], &m[2], &m[3], &m[4], &m[5],
- &m[6], &m[7]);
-
- for (j = 1; j < i; j++) {
- c = m[j - 1];
- write(1, &c, 1);
- }
- }
- }
-
- @EOF
-
- chmod 644 hex.c
-
- echo x - jump.c
- cat >jump.c <<'@EOF'
- /*
- * 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 <fcntl.h>
- #include "a2.h"
-
- #define jump_check(a,b,c,d) (mem[Pc]==a && mem[Pc+1]==b && mem[Pc+2]==c && mem[Pc+3]==d)
-
- /*
- * In order to improve performance, we intercept the PC on JSR's
- * and JMP's to certain locations and handled the intented function
- * in C instead of letting the emulator interpret 6502.
- *
- * This is done for video output, to produce an acceptable scroll;
- * for the boot prom, so it crashes if there is no disk in the drive;
- * and for other miscellaneous routines such as WAIT for speed.
- *
- * In most cases the interceptor routine checks to see if the code it's
- * intercepting looks like what it thinks should be there; it doesn't
- * snatch the PC if the first four bytes of the routine don't match.
- */
-
-
- #define I_WAIT 1 /* defeat ROM WAIT routine */
- #define I_PRODOS 2 /* Prodos high level intercept */
- #define I_RWTS 3 /* DOS 3.3 high-level intercept */
- #define I_BELL 4 /* don't toggle C030, output a bell */
- #define I_VIDOUT 5 /* speeds up scrolling tremendously */
- #define I_BOOT 6 /* crash if no disk on boot */
- #define I_BOOTWAIT 7 /* defeat delay loops in DOS boot */
- #define I_BOOTPATCH 8 /* patch dos for fast raw access */
-
-
- extern int map_to_upper;
- extern unsigned char disk_ref();
-
-
- set_special_jumps() {
- extern int set_c0();
- extern int set_writep();
-
- mem[0x43] = 0x60; /* for ProDos boot */
-
- jmp_tbl[0xBD00] = I_RWTS;
- jmp_tbl[0xC600] = I_BOOT;
- jmp_tbl[0xC680] = I_PRODOS; /* patched into boot prom below */
- jmp_tbl[0x9D84] = I_BOOTPATCH; /* fast raw dos access */
- jmp_tbl[0xFBD9] = I_BELL;
- jmp_tbl[0xFBFD] = I_VIDOUT;
- jmp_tbl[0xFCA8] = I_WAIT;
-
- jmp_tbl[0x3A00] = I_BOOTWAIT;
-
- mem_set[0xC0] = set_c0;
- mem_set[0xC6] = set_writep; /* write protect disk prom */
-
- #if 0
- mem[0xC600] = 0; /* flag for boot interception */
- mem[0xC601] = 0x20; /* disk prom magic number */
- mem[0xC603] = 0x00;
- mem[0xC605] = 0x03;
- mem[0xC607] = 0x3C;
- #endif
-
- /*
- * Patch boot rom for fake Prodos driver
- */
-
- mem[0xC6FF] = 0x80; /* C680 is driver address */
- mem[0xC6FE] = 0x1F; /* info about device */
-
- screen_setup();
- }
-
-
- jump(key)
- int key;
- {
- int i;
-
- switch (key) {
- case I_WAIT: /* FCA8 */
- if (jump_check(0x38, 0x48, 0xE9, 0x01)) {
- A = 0;
- N = 0;
- V = 0;
- C = 1;
- DO_RTS;
- }
- break;
-
- case I_PRODOS: /* C680 */
- prodos();
- break;
-
- case I_RWTS: /* BD00 */
- if (jump_check(0x84, 0x48, 0x85, 0x49))
- rwts();
- break;
-
- case I_BELL: /* FBD9 */
- if (jump_check(0x60, 0x87, 0xD0, 0x12)) {
- putchar(7);
- fflush(stdout);
- DO_RTS;
- }
- break;
-
- case I_VIDOUT: /* FBFD */
- if (jump_check(0xC9, 0xA0, 0xB0, 0xEF))
- vidout();
- break;
-
- case I_BOOT: /* C600 */
- if (disk[0] < 0) {
- info("boot: no disk");
- PCINC; /* BRK into the monitor */
- push(high(Pc));
- push(low(Pc));
- B = 1;
- push(get_status());
- Pc = mem[0xFFFE] | (mem[0xFFFF] << 8);
- return;
- }
- info("boot");
-
- /*
- * We read the second half of a 512 byte block in case we're
- * booting something that depends on this being a newer boot prom
- */
-
- drive = 0;
- read_disk(0, 14, &mem[0x900]);
- break;
-
- /*
- * Standard DOS 3.3 has some pretty gross delay loops in its
- * boot code. The following patches defeat two of them.
- * This could be dangerous; it seems to work, but DOS's original
- * side effects are not maintained. Comment out the jmp_tbl assignment
- * of I_BOOTWAIT above if you are distrustful.
- *
- * Interesting. Dos relocates the patches when it moves into higher
- * memory. If you boot with a fast-booting dos that doesn't have the
- * delays at 3A00, but still has them at BA00 & BD9E when it starts
- * up, it will be slow if you turn off RWTS interception and use the
- * raw interface. However, slow-booting real DOS that gets patched
- * while it's booting will have a faster raw interface, since it
- * relocated the patches...
- */
-
- case I_BOOTWAIT: /* 3A00 */
- if (jump_check(0xA2, 0x11, 0xCA, 0xD0)) {
- mem[0x3A00] = 0x60; /* RTS */
- if (mem[0x3D9E] == 0xA0
- && mem[0x3D9F] == 0x12
- && mem[0x3DA0] == 0x88) {
- mem[0x3D9E] = 0x4C; /* JMP past it */
- mem[0x3D9F] = 0xAB;
- mem[0x3DA0] = 0x3D; /* gets relocated */
- }
- }
- break;
-
- /*
- * This one is unnecessary since we do high-level RWTS interception
- */
-
- case I_BOOTPATCH: /* 9D84 */
- if (jump_check(0xAD, 0xE9, 0xB7, 0x4A)) {
- if (mem[0xBA00] == 0xA2
- && mem[0xBA01] == 0x11
- && mem[0xBA02] == 0xCA) {
- mem[0xBA00] = 0x60; /* RTS */
- if (mem[0xBD9E] == 0xA0
- && mem[0xBD9F] == 0x12
- && mem[0xBDA0] == 0x88) {
- mem[0xBD9E] = 0x4C;
- mem[0xBD9F] = 0xAB;
- mem[0xBDA0] = 0xBD;
- }
- }
- }
- break;
-
- default:
- fprintf(stderr, "bad jump intercept key: %d\n", key);
- assert(FALSE);
- }
- }
-
-
- static int key_clear = TRUE;
- static unsigned char last_key = 0;
- static unsigned char temp_key;
-
- extern int save_flags;
-
- unsigned char
- mem_map(a)
- unsigned short a;
- {
-
- switch (a) {
- case 0xC000:
- if (key_clear) {
- fcntl (0, F_SETFL, save_flags | O_NDELAY);
-
- if (read (0, &temp_key, 1) == 1) {
- key_clear = FALSE;
- if (temp_key == '\n')
- temp_key = '\r';
- else if (temp_key == 127)
- temp_key = 8;
- if (map_to_upper)
- temp_key = toupper(temp_key);
- last_key = temp_key | 0x80;
- }
-
- fcntl (0, F_SETFL, save_flags);
- }
- return(last_key);
-
- case 0xC010:
- key_clear = TRUE;
- last_key &= 0x7F;
- return(0); /* what should this be? */
-
- case 0xC011:
- if (bank2_enable)
- return(0xFF);
- return(0x00);
-
- case 0xC012:
- if (ram_read)
- return(0xFF);
- return(0x00);
-
- case 0xC080: case 0xC081: case 0xC082: case 0xC083:
- case 0xC088: case 0xC089: case 0xC08A: case 0xC08B:
- ram_card(a);
- return(0x00);
-
- /*
- * Slot 6 Disk II memory map
- */
-
- case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3:
- case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7:
- case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB:
- case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF:
- return( disk_ref(a, 0) );
-
- #if 0
- /*
- * Keep the boot prom magic number from appearing if there is
- * no disk in the drive
- */
-
- case 0xC600:
- case 0xC601:
- if (disk[0] < 0)
- return(0);
- break;
- #endif
-
- }
-
- return(mem[a]); /* default */
- }
-
-
- set_c0(a, n)
- unsigned short a;
- unsigned char n;
- {
-
- switch (a & 0xFF) {
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15:
- case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B:
- case 0x1C: case 0x1D: case 0x1E: case 0x1F:
- key_clear = TRUE;
- last_key &= 0x7F;
- break;
-
- case 0x80: case 0x81: case 0x82: case 0x83:
- case 0x88: case 0x89: case 0x8A: case 0x8B:
- ram_card(a);
- break;
-
- /*
- * Slot 6 Disk II memory map
- */
-
- case 0xC0E0: case 0xC0E1: case 0xC0E2: case 0xC0E3:
- case 0xC0E4: case 0xC0E5: case 0xC0E6: case 0xC0E7:
- case 0xC0E8: case 0xC0E9: case 0xC0EA: case 0xC0EB:
- case 0xC0EC: case 0xC0ED: case 0xC0EE: case 0xC0EF:
- disk_ref(a, n);
- break;
-
- default:
- mem[a] = n;
- }
- }
-
-
- @EOF
-
- chmod 644 jump.c
-
- echo x - main.c
- cat >main.c <<'@EOF'
- /*
- * 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);
- }
-
- @EOF
-
- chmod 644 main.c
-
- echo x - mapper.c
- cat >mapper.c <<'@EOF'
-
- #include <stdio.h>
-
-
- /*
- * Map a disk image in Prodos block ordering to DOS 3.3 block ordering
- * usage: mapper < old_image > new_image
- */
-
- main() {
- unsigned char buf[4096];
- int track;
-
- for (track = 0; track < 35; track++) {
- if (read(0, buf, 4096) != 4096) {
- perror("bad read");
- exit(1);
- }
-
- write(1, buf, 256);
- write(1, &buf[0xE00], 256);
- write(1, &buf[0xD00], 256);
- write(1, &buf[0xC00], 256);
- write(1, &buf[0xB00], 256);
- write(1, &buf[0xA00], 256);
- write(1, &buf[0x900], 256);
- write(1, &buf[0x800], 256);
- write(1, &buf[0x700], 256);
- write(1, &buf[0x600], 256);
- write(1, &buf[0x500], 256);
- write(1, &buf[0x400], 256);
- write(1, &buf[0x300], 256);
- write(1, &buf[0x200], 256);
- write(1, &buf[0x100], 256);
- write(1, &buf[0xF00], 256);
- }
- }
-
-
- @EOF
-
- chmod 644 mapper.c
-
- echo x - mem.c
- cat >mem.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
- unsigned char mem[65536]; /* 64K memory image */
- unsigned char jmp_tbl[65536]; /* jmp & jsr interceptor functions */
- int (*mem_set[256])(); /* memory store interceptors */
-
- unsigned char rom[0x3000];
- unsigned char ram[0x2000];
- unsigned char bank1[0x1000];
- unsigned char bank2[0x1000];
-
-
- int ram_read = 0;
- int ram_write = 0;
- int bank2_enable = 0;
-
-
- memory_setup() {
- long i;
- int set_writep();
-
- for (i = 0; i < 256; i++)
- mem_set[i] = NULL;
-
- for (i = 0; i < 65536; i++)
- jmp_tbl[i] = 0;
-
- writep(set_writep);
- ram_copy(&mem[0xD000], rom, 0x3000);
- }
-
-
- ram_copy(from, to, len)
- unsigned char *from;
- unsigned char *to;
- int len;
- {
-
- while (len--)
- *to++ = *from++;
- }
-
-
- /*
- * Write protect/unprotect D000-FFFF
- */
- writep(fn)
- int (*fn)();
- {
- int i;
-
- for (i = 0xD0; i <= 0xFF; i++)
- mem_set[i] = fn;
- }
-
-
- set_writep(a, n)
- unsigned short a;
- unsigned char n;
- {
- /* Just eat it. */
- }
-
-
- set_ramwrite(a, n)
- unsigned short a;
- unsigned char n;
- {
-
- if (a >= 0xE000)
- ram[a - 0xE000] = n;
- else if (bank2_enable)
- bank2[a - 0xD000] = n;
- else
- bank1[a - 0xD000] = n;
- }
-
-
-
-
- ram_card(addr)
- unsigned short addr;
- {
-
- if (ram_read) {
- ram_copy(&mem[0xE000], ram, 0x2000);
- if (bank2_enable)
- ram_copy(&mem[0xD000], bank2, 0x1000);
- else
- ram_copy(&mem[0xD000], bank1, 0x1000);
- }
-
- switch (addr & 0x000F) {
- case 0x00: /* C080 */
- ram_read = 1;
- ram_write = 0;
- bank2_enable = 1;
-
- ram_copy(ram, &mem[0xE000], 0x2000);
- ram_copy(bank2, &mem[0xD000], 0x1000);
- writep(set_writep);
- break;
-
- case 0x01: /* C081 */
- ram_read = 0;
- ram_write = 1;
- bank2_enable = 1;
-
- ram_copy(rom, &mem[0xD000], 0x3000);
- writep(set_ramwrite);
- break;
-
- case 0x02: /* C082 */
- ram_read = 0;
- ram_write = 0;
- bank2_enable = 1;
-
- ram_copy(rom, &mem[0xD000], 0x3000);
- writep(set_writep);
- break;
-
- case 0x03: /* C083 */
- ram_read = 1;
- ram_write = 1;
- bank2_enable = 1;
-
- ram_copy(ram, &mem[0xE000], 0x2000);
- ram_copy(bank2, &mem[0xD000], 0x1000);
- writep(NULL);
- break;
-
- case 0x08: /* C088 */
- ram_read = 1;
- ram_write = 0;
- bank2_enable = 0;
-
- ram_copy(ram, &mem[0xE000], 0x2000);
- ram_copy(bank1, &mem[0xD000], 0x1000);
- writep(set_writep);
- break;
-
- case 0x09: /* C089 */
- ram_read = 0;
- ram_write = 1;
- bank2_enable = 0;
- ram_copy(rom, &mem[0xD000], 0x3000);
- writep(set_ramwrite);
- break;
-
- case 0x0a: /* C08A */
- ram_read = 0;
- ram_write = 0;
- bank2_enable = 0;
- ram_copy(rom, &mem[0xD000], 0x3000);
- writep(set_writep);
- break;
-
- case 0x0b: /* C08B */
- ram_read = 1;
- ram_write = 1;
- bank2_enable = 0;
- ram_copy(ram, &mem[0xE000], 0x2000);
- ram_copy(bank1, &mem[0xD000], 0x1000);
- writep(NULL);
- break;
- }
- }
-
- @EOF
-
- chmod 644 mem.c
-
- echo x - parse.c
- cat >parse.c <<'@EOF'
- /*
- * 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 <ctype.h>
- #include "a2.h"
- #include "cli.h"
-
-
- char *
- split(s)
- char *s;
- {
- char *t;
- extern char *strchr();
-
- assert(s != NULL);
-
- t = strchr(s, ' ');
- if (t == NULL)
- return("");
-
- assert(*t == ' ');
-
- *t++ = '\0';
-
- while (*t && *t == ' ')
- t++;
-
- return(t);
- }
-
-
- match(a, b)
- char *a;
- char *b;
- {
-
- assert(a != NULL);
- assert(b != NULL);
-
- if (*b == '.' && strlen(b) > 1)
- b++;
- while (*a && *b) {
- if (toupper(*a) != toupper(*b))
- return(NO_MATCH);
- a++;
- b++;
- }
-
- if (!*a) {
- if (!*b)
- return(IDENTICAL);
- else
- return(PARTIAL);
- } else
- return(NO_MATCH);
- }
-
-
- is_hex_number(s)
- char *s;
- {
- char *temp;
- temp = s;
- assert(s != NULL);
- while (*s)
- if (!isxdigit(*s++))
- return(FALSE);
- if (temp != s)
- return TRUE;
- else
- return FALSE;
- }
-
-
- long get_hex_number(s)
- char *s;
- {
- unsigned int x;
- if (is_hex_number(s))
- sscanf(s, "%x", &x);
- else
- return(-1);
- return( (long) x );
- }
-
-
- parse_str(tbl, s, t)
- struct cmdtbl tbl[];
- char *s;
- char *t; /* to be passed to handler functions */
- {
- int i;
- int ret;
- int partial = -1;
- int count = 0;
-
- i = 0;
- while (tbl[i].name != NULL) {
- ret = match(s, tbl[i].name);
- if (ret == IDENTICAL) {
- partial = i;
- count = 0;
- break;
- } else if (ret == PARTIAL) {
- partial = i;
- count++;
- }
-
- i++;
- }
-
- if (partial == -1)
- return(NO_MATCH);
-
- if (count > 1)
- return(AMBIGUOUS);
-
- if (tbl[partial].func == NULL)
- return(NOT_IMPLEMENTED);
-
- assert(t != NULL);
- return (*tbl[partial].func)(t);
- }
-
-
-
- parse(tbl, s)
- struct cmdtbl tbl[];
- char *s;
- {
- int ret;
- char buf[1024];
- char *t;
-
- if (*s == '!') { /* shell escape-ish thing */
- shell_escape(++s);
- return(FALSE);
- }
-
- t = split(s);
-
- if (*s == '\0') {
- return(TRUE); /* single step */
-
- } else if (strcmp(s, "?") == 0) {
- dump_list(tbl, "Command, one of the following:\n\n");
-
- } else switch (parse_str(tbl, s, t)) {
- case AMBIGUOUS:
- printf("Ambiguous command '%s'.\n", s);
- break;
-
- case NO_MATCH:
- printf("Unknown command. Type ? for a list.\n");
- break;
-
- case NOT_IMPLEMENTED:
- printf("Sorry, command not implemented yet.\n");
- break;
-
- case OK:
- break;
-
- case DISPLAY:
- status(stdout);
- break;
-
- default:
- assert(FALSE);
- }
-
- return(FALSE);
- }
-
-
- dump_list(tbl, header)
- struct cmdtbl tbl[];
- char *header;
- {
- int i, count;
- char buf[1024];
-
- printf(header);
- i = 0;
- count = 0;
- while (tbl[i].name != NULL) {
- if (*tbl[i].name != '.' || strlen(tbl[i].name) == 1) {
- if (count % 4 == 3)
- printf(" %-15s\n", tbl[i].name);
- else
- printf(" %-15s", tbl[i].name);
-
- count++;
- }
- i++;
- }
-
- if (count % 4 != 0)
- printf("\n");
- }
-
-
- @EOF
-
- chmod 644 parse.c
-
- echo x - prodos.c
- cat >prodos.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
- #define BSIZE 512 /* block size */
- #define D1SIZE 280 /* Size of disk 1 */
- #define D2SIZE 1024 /* Size of disk 2 */
-
-
- /*
- * Prodos to DOS 3.3 block mapping
- */
-
- int conv1[] = { 0x00, 0x0D, 0x0B, 0x09, 0x07, 0x05, 0x03, 0x01 };
- int conv2[] = { 0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x0F };
-
-
-
- proformat()
- {
-
- if (write_prot[drive]) {
- C = 1;
- A = 0x2B; /* Write protected */
- return;
- }
-
- C = 0;
- A = 0;
- }
-
-
- proread()
- {
- int block;
- unsigned short ptr;
- int track, sector;
- char s[50];
-
- block = join(mem[0x46], mem[0x47]);
- ptr = join(mem[0x44], mem[0x45]);
-
- sprintf(s, "proread b=%d", block);
- info(s);
-
- track = block / 8;
- sector = conv1[block % 8];
-
- read_disk(track, sector, &mem[ptr]);
- ptr += 0x100;
-
- sector = conv2[block % 8];
- read_disk(track, sector, &mem[ptr]);
-
- C = 0;
- A = 0;
- }
-
-
- prowrite()
- {
- int block;
- unsigned short ptr;
- int track;
- int sector;
- char s[50];
-
- if (write_prot[drive]) {
- C = 1;
- A = 0x2B; /* Write protected */
- return;
- }
-
- block = join(mem[0x46], mem[0x47]);
- ptr = join(mem[0x44], mem[0x45]);
-
- sprintf(s, "prowrite b=%d", block);
- info(s);
-
- track = block / 8;
- sector = conv1[block % 8];
-
- write_disk(track, sector, &mem[ptr]);
- ptr += 0x100;
-
- sector = conv2[block % 8];
- write_disk(track, sector, &mem[ptr]);
-
- C = 0;
- A = 0;
- }
-
-
- prostatus()
- {
-
- C = 0;
- A = 0;
- Y = high(D1SIZE);
- X = low(D1SIZE);
- }
-
-
- prodos()
- {
-
- if (mem[0x43] < 0x80)
- drive = 0;
- else
- drive = 1;
-
- if (disk[drive] < 0) {
- C = 1;
- A = 0x27; /* IO Error */
-
- } else switch (mem[0x42]) {
- case 0:
- prostatus();
- break;
- case 1:
- proread();
- break;
- case 2:
- prowrite();
- break;
- case 3:
- proformat();
- break;
- }
-
- DO_RTS;
- }
-
- @EOF
-
- chmod 644 prodos.c
-
- echo x - screen.c
- cat >screen.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
- extern char screen_map[]; /* at the bottom of this file */
- extern int text1[];
-
-
- int line1[0x400];
- int col1[0x400];
-
-
- info(s)
- char *s;
- {
-
- MoveCursor(0, 57);
- printf("%-20s", s);
-
- last_line = -1;
- last_col = -1;
- fflush(stdout);
- }
-
-
- screen_setup() {
- extern int set_text1f();
- int line, col;
- int addr, base;
- int i;
-
- for (i = 0; i < 0x400; i++) {
- line1[i] = -1;
- col1[i] = -1;
- }
-
- mem_set[0x04] = set_text1f;
- mem_set[0x05] = set_text1f;
- mem_set[0x06] = set_text1f;
- mem_set[0x07] = set_text1f;
-
- for (line = 0; line < 24; line++) {
- base = text1[line];
- for (col = 0; col < 40; col++) {
- addr = base + col;
- mem[addr] = 0xA0;
- line1[addr - 0x400] = line;
- col1[addr - 0x400] = col;
- }
- }
- }
-
-
- int last_line = -1;
- int last_col = -1;
-
-
- #define appleout(n) if (n >= 0x80) putchar(screen_map[n]); else { StartInverse(); putchar(screen_map[n]); EndInverse(); }
-
-
- set_text1f(addr, n)
- unsigned short addr;
- unsigned char n;
- {
- int line, col;
- unsigned char c;
-
- if (mem[addr] == n) /* no change, don't do anything */
- return;
-
- mem[addr] = n;
- line = line1[addr - 0x400];
- col = col1[addr - 0x400];
-
- if (line == -1)
- return;
-
- /*
- * Stuff to try to make updating more efficient
- * Is it really worth it?
- */
-
- if (line == last_line) {
- if (col == 0)
- putchar('\r');
- else switch (col - last_col) {
- case 4:
- c = mem[addr - 3]; appleout(c);
- c = mem[addr - 2]; appleout(c);
- c = mem[addr - 1]; appleout(c);
- break;
- case 3:
- c = mem[addr - 2]; appleout(c);
- c = mem[addr - 1]; appleout(c);
- break;
- case 2:
- c = mem[addr - 1]; appleout(c);
- break;
- case 1: /* already there */
- break;
- case 0:
- putchar('\b');
- break;
- case -1:
- putchar('\b'); putchar('\b');
- break;
- case -2:
- putchar('\b'); putchar('\b'); putchar('\b');
- break;
- case -3:
- putchar('\b'); putchar('\b'); putchar('\b');
- putchar('\b');
- break;
- default:
- MoveCursor(line, col);
- }
- } else
- MoveCursor(line, col);
-
- appleout(n);
- fflush(stdout);
-
- last_line = line;
- last_col = col;
- }
-
-
- set_text1(addr, n)
- unsigned short addr;
- unsigned char n;
- {
- int line, col;
- unsigned char c;
-
- if (mem[addr] == n) /* no change, don't do anything */
- return;
-
- mem[addr] = n;
- line = line1[addr - 0x400];
- col = col1[addr - 0x400];
-
- if (line == -1)
- return;
-
- /*
- * Stuff to try to make updating more efficient
- * Is it really worth it?
- */
-
- if (line == last_line) {
- if (col == 0)
- putchar('\r');
- else switch (col - last_col) {
- case 4:
- c = mem[addr - 3]; appleout(c);
- c = mem[addr - 2]; appleout(c);
- c = mem[addr - 1]; appleout(c);
- break;
- case 3:
- c = mem[addr - 2]; appleout(c);
- c = mem[addr - 1]; appleout(c);
- break;
- case 2:
- c = mem[addr - 1]; appleout(c);
- break;
- case 1: /* already there */
- break;
- case 0:
- putchar('\b');
- break;
- case -1:
- putchar('\b'); putchar('\b');
- break;
- case -2:
- putchar('\b'); putchar('\b'); putchar('\b');
- break;
- case -3:
- putchar('\b'); putchar('\b'); putchar('\b');
- putchar('\b');
- break;
- default:
- MoveCursor(line, col);
- }
- } else
- MoveCursor(line, col);
-
- appleout(n);
-
- last_line = line;
- last_col = col;
- }
-
-
- redraw_screen() {
- int i, j;
- unsigned short base;
- unsigned char c;
-
- ClearScreen();
- for (i = 0; i < 24; i++) {
- base = text1[i];
- for (j = 0; j < 40; j++) {
- c = mem[base + j];
- appleout(c);
- }
- if (i < 23)
- putchar('\n');
- }
-
- last_line = -1;
- last_col = -1;
-
- fflush(stdout);
- }
-
-
- /*
- * Screen display mapping table
- */
-
- char screen_map[] = {
-
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* $00 */
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* $08 */
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* $10 */
- 'X', 'Y', 'Z', '[', '\\',']', '^', '_', /* $18 */
- ' ', '!', '"', '#', '$', '%', '&', '\'', /* $20 */
- '(', ')', '*', '+', ',', '-', '.', '/', /* $28 */
- '0', '1', '2', '3', '4', '5', '6', '7', /* $30 */
- '8', '9', ':', ';', '<', '=', '>', '?', /* $38 */
-
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* $40 */
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* $48 */
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* $50 */
- 'X', 'Y', 'Z', '[', '\\',']', '^', '_', /* $58 */
- ' ', '!', '"', '#', '$', '%', '&', '\'', /* $60 */
- '(', ')', '*', '+', ',', '-', '.', '/', /* $68 */
- '0', '1', '2', '3', '4', '5', '6', '7', /* $70 */
- '8', '9', ':', ';', '<', '=', '>', '?', /* $78 */
-
- '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* $80 */
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* $88 */
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* $90 */
- 'x', 'y', 'z', '[', '\\',']', '^', '_', /* $98 */
- ' ', '!', '"', '#', '$', '%', '&', '\'', /* $A0 */
- '(', ')', '*', '+', ',', '-', '.', '/', /* $A8 */
- '0', '1', '2', '3', '4', '5', '6', '7', /* $B0 */
- '8', '9', ':', ';', '<', '=', '>', '?', /* $B8 */
-
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* $C0 */
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* $C8 */
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* $D0 */
- 'X', 'Y', 'Z', '[', '\\',']', '^', '_', /* $D8 */
- ' ', '!', '"', '#', '$', '%', '&', '\'', /* $E0 */
- '(', ')', '*', '+', ',', '-', '.', '/', /* $E8 */
- '0', '1', '2', '3', '4', '5', '6', '7', /* $F0 */
- '8', '9', ':', ';', '<', '=', '>', '?', /* $F8 */
-
- };
-
- int text1[] = {
- 0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
- 0x428, 0x4A8, 0x528, 0x5A8, 0x628, 0x6A8, 0x728, 0x7A8,
- 0x450, 0x4D0, 0x550, 0x5D0, 0x650, 0x6D0, 0x750, 0x7D0,
- 0x478, 0x4F8, 0x578, 0x5F8, 0x678, 0x6F8, 0x778, 0x7F8
- };
-
- @EOF
-
- chmod 644 screen.c
-
- echo x - table.c
- cat >table.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
-
- struct op_info opcode[] = {
- {"brk", M_NONE}, /* 0x0 */
- {"ora", M_INDX}, /* 0x1 */
- {"", M_NONE}, /* 0x2 */
- {"", M_NONE}, /* 0x3 */
- {"tsb", M_ZP}, /* 0x4 */ /* 65C02 */
- {"ora", M_ZP}, /* 0x5 */
- {"asl", M_ZP}, /* 0x6 */
- {"", M_NONE}, /* 0x7 */
- {"php", M_NONE}, /* 0x8 */
- {"ora", M_IMM}, /* 0x9 */
- {"asl", M_NONE}, /* 0xa */
- {"", M_NONE}, /* 0xb */
- {"tsb", M_ABS}, /* 0xc */ /* 65C02 */
- {"ora", M_ABS}, /* 0xd */
- {"asl", M_ABS}, /* 0xe */
- {"", M_NONE}, /* 0xf */
- {"bpl", M_REL}, /* 0x10 */
- {"ora", M_INDY}, /* 0x11 */
- {"ora", M_ZIND}, /* 0x12 */ /* 65C02 */
- {"", M_NONE}, /* 0x13 */
- {"trb", M_ZP}, /* 0x14 */ /* 65C02 */
- {"ora", M_ZPX}, /* 0x15 */
- {"asl", M_ZPX}, /* 0x16 */
- {"", M_NONE}, /* 0x17 */
- {"clc", M_NONE}, /* 0x18 */
- {"ora", M_ABSY}, /* 0x19 */
- {"ina", M_NONE}, /* 0x1a */ /* 65C02 */
- {"", M_NONE}, /* 0x1b */
- {"trb", M_ABS}, /* 0x1c */ /* 65C02 */
- {"ora", M_ABSX}, /* 0x1d */
- {"asl", M_ABSX}, /* 0x1e */
- {"", M_NONE}, /* 0x1f */
- {"jsr", M_ABS}, /* 0x20 */
- {"and", M_INDX}, /* 0x21 */
- {"", M_NONE}, /* 0x22 */
- {"", M_NONE}, /* 0x23 */
- {"bit", M_ZP}, /* 0x24 */
- {"and", M_ZP}, /* 0x25 */
- {"rol", M_ZP}, /* 0x26 */
- {"", M_NONE}, /* 0x27 */
- {"plp", M_NONE}, /* 0x28 */
- {"and", M_IMM}, /* 0x29 */
- {"rol", M_NONE}, /* 0x2a */
- {"", M_NONE}, /* 0x2b */
- {"bit", M_ABS}, /* 0x2c */
- {"and", M_ABS}, /* 0x2d */
- {"rol", M_ABS}, /* 0x2e */
- {"", M_NONE}, /* 0x2f */
- {"bmi", M_REL}, /* 0x30 */
- {"and", M_INDY}, /* 0x31 */
- {"and", M_ZIND}, /* 0x32 */ /* 65C02 */
- {"", M_NONE}, /* 0x33 */
- {"bit", M_ZPX}, /* 0x34 */ /* 65C02 */
- {"and", M_ZPX}, /* 0x35 */
- {"rol", M_ZPX}, /* 0x36 */
- {"", M_NONE}, /* 0x37 */
- {"sec", M_NONE}, /* 0x38 */
- {"and", M_ABSY}, /* 0x39 */
- {"dey", M_NONE}, /* 0x3a */ /* 65C02 */
- {"", M_NONE}, /* 0x3b */
- {"bit", M_ABSX}, /* 0x3c */ /* 65C02 */
- {"and", M_ABSX}, /* 0x3d */
- {"rol", M_ABSX}, /* 0x3e */
- {"", M_NONE}, /* 0x3f */
- {"rti", M_NONE}, /* 0x40 */
- {"eor", M_INDX}, /* 0x41 */
- {"", M_NONE}, /* 0x42 */
- {"", M_NONE}, /* 0x43 */
- {"", M_NONE}, /* 0x44 */
- {"eor", M_ZP}, /* 0x45 */
- {"lsr", M_ZP}, /* 0x46 */
- {"", M_NONE}, /* 0x47 */
- {"pha", M_NONE}, /* 0x48 */
- {"eor", M_IMM}, /* 0x49 */
- {"lsr", M_NONE}, /* 0x4a */
- {"", M_NONE}, /* 0x4b */
- {"jmp", M_ABS}, /* 0x4c */
- {"eor", M_ABS}, /* 0x4d */
- {"lsr", M_ABS}, /* 0x4e */
- {"", M_NONE}, /* 0x4f */
- {"bvc", M_REL}, /* 0x50 */
- {"eor", M_INDY}, /* 0x51 */
- {"eor", M_ZIND}, /* 0x52 */ /* 65C02 */
- {"", M_NONE}, /* 0x53 */
- {"", M_NONE}, /* 0x54 */
- {"eor", M_ZPX}, /* 0x55 */
- {"lsr", M_ZPX}, /* 0x56 */
- {"", M_NONE}, /* 0x57 */
- {"cli", M_NONE}, /* 0x58 */
- {"eor", M_ABSY}, /* 0x59 */
- {"phy", M_NONE}, /* 0x5a */ /* 65C02 */
- {"", M_NONE}, /* 0x5b */
- {"", M_NONE}, /* 0x5c */
- {"eor", M_ABSX}, /* 0x5d */
- {"lsr", M_ABSX}, /* 0x5e */
- {"", M_NONE}, /* 0x5f */
- {"rts", M_NONE}, /* 0x60 */
- {"adc", M_INDX}, /* 0x61 */
- {"", M_NONE}, /* 0x62 */
- {"", M_NONE}, /* 0x63 */
- {"stz", M_ZP}, /* 0x64 */ /* 65C02 */
- {"adc", M_ZP}, /* 0x65 */
- {"ror", M_ZP}, /* 0x66 */
- {"", M_NONE}, /* 0x67 */
- {"pla", M_NONE}, /* 0x68 */
- {"adc", M_IMM}, /* 0x69 */
- {"ror", M_NONE}, /* 0x6a */
- {"", M_NONE}, /* 0x6b */
- {"jmp", M_IND}, /* 0x6c */
- {"adc", M_ABS}, /* 0x6d */
- {"ror", M_ABS}, /* 0x6e */
- {"", M_NONE}, /* 0x6f */
- {"bvs", M_REL}, /* 0x70 */
- {"adc", M_INDX}, /* 0x71 */
- {"adc", M_ZIND}, /* 0x72 */ /* 65C02 */
- {"", M_NONE}, /* 0x73 */
- {"stz", M_ZPX}, /* 0x74 */ /* 65C02 */
- {"adc", M_ZPX}, /* 0x75 */
- {"ror", M_ZPX}, /* 0x76 */
- {"", M_NONE}, /* 0x77 */
- {"sei", M_NONE}, /* 0x78 */
- {"adc", M_ABSY}, /* 0x79 */
- {"ply", M_NONE}, /* 0x7a */ /* 65C02 */
- {"", M_NONE}, /* 0x7b */
- {"jmp", M_ABINDX}, /* 0x7c */ /* 65C02 */
- {"adc", M_ABSX}, /* 0x7d */
- {"ror", M_ABSX}, /* 0x7e */
- {"", M_NONE}, /* 0x7f */
- {"bra", M_REL}, /* 0x80 */ /* 65C02 */
- {"sta", M_INDX}, /* 0x81 */
- {"", M_NONE}, /* 0x82 */
- {"", M_NONE}, /* 0x83 */
- {"sty", M_ZP}, /* 0x84 */
- {"sta", M_ZP}, /* 0x85 */
- {"stx", M_ZP}, /* 0x86 */
- {"", M_NONE}, /* 0x87 */
- {"dey", M_NONE}, /* 0x88 */
- {"", M_NONE}, /* 0x89 */
- {"txa", M_NONE}, /* 0x8a */
- {"", M_NONE}, /* 0x8b */
- {"sty", M_ABS}, /* 0x8c */
- {"sta", M_ABS}, /* 0x8d */
- {"stx", M_ABS}, /* 0x8e */
- {"", M_NONE}, /* 0x8f */
- {"bcc", M_REL}, /* 0x90 */
- {"sta", M_INDY}, /* 0x91 */
- {"sta", M_ZIND}, /* 0x92 */ /* 65C02 */
- {"", M_NONE}, /* 0x93 */
- {"sty", M_ZPX}, /* 0x94 */
- {"sta", M_ZPX}, /* 0x95 */
- {"stx", M_ZPX}, /* 0x96 */
- {"", M_NONE}, /* 0x97 */
- {"tya", M_NONE}, /* 0x98 */
- {"sta", M_ABSY}, /* 0x99 */
- {"txs", M_NONE}, /* 0x9a */
- {"", M_NONE}, /* 0x9b */
- {"stz", M_ABS}, /* 0x9c */ /* 65C02 */
- {"sta", M_ABSX}, /* 0x9d */
- {"stz", M_ABSX}, /* 0x9e */ /* 65C02 */
- {"", M_NONE}, /* 0x9f */
- {"ldy", M_IMM}, /* 0xa0 */
- {"lda", M_INDX}, /* 0xa1 */
- {"ldx", M_IMM}, /* 0xa2 */
- {"", M_NONE}, /* 0xa3 */
- {"ldy", M_ZP}, /* 0xa4 */
- {"lda", M_ZP}, /* 0xa5 */
- {"ldx", M_ZP}, /* 0xa6 */
- {"", M_NONE}, /* 0xa7 */
- {"tay", M_NONE}, /* 0xa8 */
- {"lda", M_IMM}, /* 0xa9 */
- {"tax", M_NONE}, /* 0xaa */
- {"", M_NONE}, /* 0xab */
- {"ldy", M_ABS}, /* 0xac */
- {"lda", M_ABS}, /* 0xad */
- {"ldx", M_ABS}, /* 0xae */
- {"", M_NONE}, /* 0xaf */
- {"bcs", M_REL}, /* 0xb0 */
- {"lda", M_INDY}, /* 0xb1 */
- {"lda", M_ZIND}, /* 0xb2 */ /* 65C02 */
- {"", M_NONE}, /* 0xb3 */
- {"ldy", M_ZPX}, /* 0xb4 */
- {"lda", M_ZPX}, /* 0xb5 */
- {"ldx", M_ZPY}, /* 0xb6 */
- {"", M_NONE}, /* 0xb7 */
- {"clv", M_NONE}, /* 0xb8 */
- {"lda", M_ABSY}, /* 0xb9 */
- {"tsx", M_NONE}, /* 0xba */
- {"", M_NONE}, /* 0xbb */
- {"ldy", M_ABSX}, /* 0xbc */
- {"lda", M_ABSX}, /* 0xbd */
- {"ldx", M_ABSY}, /* 0xbe */
- {"", M_NONE}, /* 0xbf */
- {"cpy", M_IMM}, /* 0xc0 */
- {"cmp", M_INDX}, /* 0xc1 */
- {"", M_NONE}, /* 0xc2 */
- {"", M_NONE}, /* 0xc3 */
- {"cpy", M_ZP}, /* 0xc4 */
- {"cmp", M_ZP}, /* 0xc5 */
- {"dec", M_ZP}, /* 0xc6 */
- {"", M_NONE}, /* 0xc7 */
- {"iny", M_NONE}, /* 0xc8 */
- {"cmp", M_IMM}, /* 0xc9 */
- {"dex", M_NONE}, /* 0xca */
- {"", M_NONE}, /* 0xcb */
- {"cpy", M_ABS}, /* 0xcc */
- {"cmp", M_ABS}, /* 0xcd */
- {"dec", M_ABS}, /* 0xce */
- {"", M_NONE}, /* 0xcf */
- {"bne", M_REL}, /* 0xd0 */
- {"cmp", M_INDY}, /* 0xd1 */
- {"cmp", M_ZIND}, /* 0xd2 */ /* 65C02 */
- {"", M_NONE}, /* 0xd3 */
- {"", M_NONE}, /* 0xd4 */
- {"cmp", M_ZPX}, /* 0xd5 */
- {"dec", M_ZPX}, /* 0xd6 */
- {"", M_NONE}, /* 0xd7 */
- {"cld", M_NONE}, /* 0xd8 */
- {"cmp", M_ABSY}, /* 0xd9 */
- {"phx", M_NONE}, /* 0xda */ /* 65C02 */
- {"", M_NONE}, /* 0xdb */
- {"", M_NONE}, /* 0xdc */
- {"cmp", M_ABSX}, /* 0xdd */
- {"dec", M_ABSX}, /* 0xde */
- {"", M_NONE}, /* 0xdf */
- {"cpx", M_IMM}, /* 0xe0 */
- {"sbc", M_INDX}, /* 0xe1 */
- {"", M_NONE}, /* 0xe2 */
- {"", M_NONE}, /* 0xe3 */
- {"cpx", M_ZP}, /* 0xe4 */
- {"sbc", M_ZP}, /* 0xe5 */
- {"inc", M_ZP}, /* 0xe6 */
- {"", M_NONE}, /* 0xe7 */
- {"inx", M_NONE}, /* 0xe8 */
- {"sbc", M_IMM}, /* 0xe9 */
- {"nop", M_NONE}, /* 0xea */
- {"", M_NONE}, /* 0xeb */
- {"cpx", M_ABS}, /* 0xec */
- {"sbc", M_ABS}, /* 0xed */
- {"inc", M_ABS}, /* 0xee */
- {"", M_NONE}, /* 0xef */
- {"beq", M_REL}, /* 0xf0 */
- {"sbc", M_INDY}, /* 0xf1 */
- {"sbc", M_ZIND}, /* 0xf2 */ /* 65C02 */
- {"", M_NONE}, /* 0xf3 */
- {"", M_NONE}, /* 0xf4 */
- {"sbc", M_ZPX}, /* 0xf5 */
- {"inc", M_ZPX}, /* 0xf6 */
- {"", M_NONE}, /* 0xf7 */
- {"sed", M_NONE}, /* 0xf8 */
- {"sbc", M_ABSY}, /* 0xf9 */
- {"plx", M_NONE}, /* 0xfa */ /* 65C02 */
- {"", M_NONE}, /* 0xfb */
- {"", M_NONE}, /* 0xfc */
- {"sbc", M_ABSX}, /* 0xfd */
- {"inc", M_ABSX}, /* 0xfe */
- {"", M_NONE}, /* 0xff */
- };
-
-
- diss(pc, fp)
- unsigned short pc;
- FILE *fp;
- {
- char *s;
- int count;
- int tmp;
- unsigned short addr;
- unsigned char one, two, three;
-
- fprintf(fp, "%.4X: ", pc);
-
- addr = pc;
- one = mem[pc++];
- two = mem[pc++];
- three = mem[pc++];
-
- s = opcode[one].name;
-
- if (s == NULL || *s == '\0')
- s = "???";
-
- switch (opcode[one].add_mode) {
- case 0:
- fprintf(fp, "%.2x %s ", one, s);
- count = 1;
- break;
-
- case M_ZP:
- fprintf(fp, "%.2x %.2x %s $%.2x ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_ZPX:
- fprintf(fp, "%.2x %.2x %s $%.2x,X ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_ZPY:
- fprintf(fp, "%.2x %.2x %s $%.2x,Y ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_IND:
- fprintf(fp, "%.2x %.2x %.2x %s ($%.4x) ",
- one, two, three, s,
- join(two, three));
- count = 3;
- break;
-
- case M_INDX:
- fprintf(fp, "%.2x %.2x %s ($%.2x,X) ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_INDY:
- fprintf(fp, "%.2x %.2x %s ($%.2x),Y ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_ABS:
- fprintf(fp, "%.2x %.2x %.2x %s $%.4x ",
- one, two, three, s,
- join(two, three));
- count = 3;
- break;
-
- case M_ABSX:
- fprintf(fp, "%.2x %.2x %.2x %s $%.4x,X ",
- one, two, three, s,
- join(two, three));
- count = 3;
- break;
-
- case M_ABSY:
- fprintf(fp, "%.2x %.2x %.2x %s $%.4x,Y ",
- one, two, three, s,
- join(two, three));
- count = 3;
- break;
-
- case M_IMM:
- fprintf(fp, "%.2x %.2x %s #$%.2x ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_REL:
- tmp = two;
- if (tmp > 127)
- tmp = tmp - 256;
- tmp += addr + 2;
- tmp &= 0xFFFF;
-
- fprintf(fp, "%.2x %.2x %s $%.4x ",
- one, two, s, tmp);
- count = 2;
- break;
-
- case M_ZIND:
- fprintf(fp, "%.2x %.2x %s ($%.2x) ",
- one, two, s, two);
- count = 2;
- break;
-
- case M_ABINDX:
- fprintf(fp, "%.2x %.2x %.2x %s ($%.4x,X)",
- one, two, three, s,
- join(two, three));
- count = 3;
- break;
-
- default:
- fprintf(fp, "%.2x %s ", "???", one);
- count = 1;
- }
-
- return(count);
- }
-
- flags(fp)
- FILE *fp;
- {
- fprintf(fp, " A=%.2X X=%.2X Y=%.2X SP=%.2X", A, X, Y, Sp);
- fprintf(fp, " N%d V%d B%d D%d I%d Z%d C%d\n",
- !!N, !!V, !!B, !!D, !!I, !NZ, !!C);
- }
-
- @EOF
-
- chmod 644 table.c
-
- echo x - vidout.c
- cat >vidout.c <<'@EOF'
- /*
- * 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 "a2.h"
-
-
- #define WNDLFT 0x20
- #define WNDWDTH 0x21
- #define WNDTOP 0x22
- #define WNDBTM 0x23
- #define CH 0x24
- #define CV 0x25
- #define BASL 0x28
- #define BASH 0x29
- #define BAS2L 0x2A
- #define BAS2H 0x2B
-
-
-
- /*
- * VIDOUT at $FBFD
- */
-
- vidout() {
- unsigned short ptr;
-
- if (A >= 0xA0 || A < 0x80) {
- ptr = join(mem[BASL], mem[BASH]) + mem[CH];
- set_text1f(ptr, A);
- mem[CH]++;
- if (mem[CH] >= mem[WNDWDTH])
- mem[CH] = 0;
- else {
- DO_RTS;
- return;
- }
- } else if (A == 0x8D)
- mem[CH] = 0;
- else if (A != 0x8A) {
- Pc = 0xFC0C;
- return;
- }
-
- A = ++mem[CV];
- if (A < mem[WNDBTM]) {
- Pc = 0xFC24;
- return;
- }
- mem[CV]--;
-
- scroll();
- }
-
-
- /*
- * SCROLL at $FC70
- */
-
- scroll() {
- int top;
- unsigned short bas, bas2, ptr;
- int width;
- int i;
- int scrl2_normal;
-
- if (mem[0x21] == 40 && mem[0x22] == 0 && mem[0x23] == 24) {
- MoveCursor(term_lines, 0);
- putchar('\n');
- last_line = -1;
- last_col = -1;
- fflush(stdout);
- scrl2_normal = FALSE;
- } else
- scrl2_normal = TRUE;
-
- top = mem[WNDTOP];
- width = mem[WNDWDTH] - 1;
- bas = text1[top % 32] + mem[WNDLFT];
-
- while (1) {
- bas2 = bas;
-
- if (++top >= mem[WNDBTM]) {
- mem[BASL] = low(bas);
- mem[BASH] = high(bas);
- Pc = 0xFC95;
- fflush(stdout);
- return;
- }
-
- bas = text1[top % 32] + mem[WNDLFT];
- ptr = bas;
-
- if (scrl2_normal)
- for (i = 0; i <= width; i++)
- set_text1(bas2++, mem[ptr++]);
- else
- for (i = 0; i <= width; i++)
- mem[bas2++] = mem[ptr++];
- }
- }
-
-
- @EOF
-
- chmod 644 vidout.c
-
- exit 0
- --
- skrenta@blekko.commodore.com
-