Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page From: page@swan.ulowell.edu (Bob Page) Newsgroups: comp.sources.amiga Subject: v02i053: dis6502 - disassemble 6502 object code Message-ID: <10051@swan.ulowell.edu> Date: 4 Nov 88 22:41:47 GMT Organization: University of Lowell, Computer Science Dept. Lines: 2058 Approved: page@swan.ulowell.edu Submitted-by: finkel@taurus.BITNET (Udi Finkelstein) Posting-number: Volume 2, Issue 53 Archive-name: applications/dis6502.1 Dis6502 disassembles 6502 binary files. Binary formats understood include C64, Atari and boot files. Equate and control files can be included to name well-known locations and to control the disassembly process. The output includes a cross reference. # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # Makefile.unix # c64.predefs # dis.1 # dis.h # dis.notes # initopts.c # lex.c # lex.l # main.c # print.c # ref.c # tbl.c # This archive created: Fri Nov 4 17:33:09 1988 cat << \SHAR_EOF > Makefile OBJS = main.o initopts.o lex.o ref.o print.o tbl.o SRCS = dis.h main.c initopts.c lex.l ref.c print.c tbl.c CFLAGS = +p -n -DAMIGA dis: $(OBJS) ln -g $(OBJS) -o dis -lcl32 tbl.o: dis.h tbl.c initopts.o: dis.h initopts.c main.o: dis.h main.c lex.c: lex.l lex.o: lex.c dis.h ref.o: dis.h ref.c print.o: dis.h print.c SHAR_EOF cat << \SHAR_EOF > Makefile.unix OBJS = main.o initopts.o lex.o ref.o print.o tbl.o SRCS = dis.h main.c initopts.c lex.l ref.c print.c tbl.c CFLAGS = -O dis: $(OBJS) cc $(OBJS) -o dis tbl.o: dis.h tbl.c cc -c tbl.c initopts.o: dis.h initopts.c main.o: dis.h main.c lex.o: lex.c lex.c: dis.h lex.l ref.o: dis.h ref.c print.o: dis.h print.c dis.man: dis.1 nroff -man dis.1 > dis.man install: dis cp dis /a/rgb/bin/dis6502 clean: rm -f $(OBJS) lex.c dis.man clobber: clean rm -f dis ckpt: $(SRCS) ci -l $(SRCS) lint: dis.h main.c initopts.c lex.c ref.c print.c tbl.c lint dis.h main.c initopts.c lex.c ref.c print.c tbl.c shar: Makefile dis.1 $(SRCS) shar -f shar Makefile dis.1 $(SRCS) SHAR_EOF cat << \SHAR_EOF > c64.predefs 1 CINT .EQ $FF81 2 IOINIT .EQ $FF84 3 RAMTAS .EQ $FF87 4 RESTOR .EQ $FF8A 5 VECTOR .EQ $FF8D 6 SETMSG .EQ $FF90 7 SECOND .EQ $FF93 8 TKSA .EQ $FF96 9 MEMTOP .EQ $FF99 10 MEMBOT .EQ $FF9C 11 SCNKEY .EQ $FF9F 12 SETTMO .EQ $FFA2 13 ACPTR .EQ $FFA5 14 CIOUT .EQ $FFA8 15 UNTLK .EQ $FFAB 16 UNLSN .EQ $FFAE 17 LISTEN .EQ $FFB1 18 TALK .EQ $FFB4 19 READST .EQ $FFB7 20 SETLFS .EQ $FFBA 21 SETNAM .EQ $FFBD 22 OPEN .EQ $FFC0 23 CLOSE .EQ $FFC3 24 CHKIN .EQ $FFC6 25 CHKOUT .EQ $FFC9 26 CLRCHN .EQ $FFCC 27 CHRIN .EQ $FFCF 28 CHROUT .EQ $FFD2 29 LOAD .EQ $FFD5 30 SAVE .EQ $FFD8 31 SETTIM .EQ $FFDB 32 RDTIME .EQ $FFDE 33 STOP .EQ $FFE1 34 GETIN .EQ $FFE4 35 CLALL .EQ $FFE7 36 UDTIME .EQ $FFEA 37 SCREEN .EQ $FFED 38 PLOT .EQ $FFF0 39 IOBASE .EQ $FFF3 40 IERRORLO .EQ $0300 41 IERRORHI .EQ $0301 42 IMAINLO .EQ $0302 43 IMAINHI .EQ $0303 44 ICRNCHLO .EQ $0304 45 ICRNCHHI .EQ $0305 46 IQPLOPLO .EQ $0306 47 IQPLOPHI .EQ $0307 48 IGONELO .EQ $0308 49 IGONEHI .EQ $0309 50 IEVALLO .EQ $030A 51 IEVALHI .EQ $030B 52 SAREG .EQ $030C 53 SXREG .EQ $030D 54 SYREG .EQ $030E 55 SPREG .EQ $030F 56 USRPOK .EQ $0310 57 USRADDLO .EQ $0311 58 USRADDHI .EQ $0312 59 CINVLO .EQ $0314 60 CINVHI .EQ $0315 61 CBINVLO .EQ $0316 62 CBINVHI .EQ $0317 63 NMINVLO .EQ $0318 64 NMINVHI .EQ $0319 65 IOPENLO .EQ $031A 66 IOPENHI .EQ $031B 67 ICLOSELO .EQ $031C 68 ICLOSEHI .EQ $031D 69 ICKINLO .EQ $031E 70 ICKINHI .EQ $031F 71 ICKOUTLO .EQ $0320 72 ICKOUTHI .EQ $0321 73 ICLRCHLO .EQ $0322 74 ICLRCHHI .EQ $0323 75 IBASINLO .EQ $0324 76 IBASINHI .EQ $0325 77 IBSOUTLO .EQ $0326 78 IBSOUTHI .EQ $0327 79 ISTOPLO .EQ $0328 80 ISTOPHI .EQ $0329 81 IGETINLO .EQ $032A 82 IGETINHI .EQ $032B 83 ICLALLLO .EQ $032C 84 ICLALLHI .EQ $032D 85 USRCMDLO .EQ $032E 86 USRCMDHI .EQ $032F 87 ILOADLO .EQ $0330 88 ILOADHI .EQ $0331 89 ISAVELO .EQ $0332 90 ISAVEHI .EQ $0333 91 TBUFFER .EQ $033C 92 VICSCN .EQ $0400 SHAR_EOF cat << \SHAR_EOF > dis.1 .TH DIS6502 1 "1 OCT 1986" .UC 4 .SH NAME dis6502 \- Disassemble 6502 object code .SH SYNOPSIS .I dis6502 [ .I \-b ] [ .I -p \fIpfile\fP ] .I file .LP .SH DESCRIPTION .I Dis6502 disassembles 6502 binary files. Binary formats understood include Atari binary files (L menu command) and boot files. Equate and control files can be included via the .I -p option to name well known locations and to control the disassembly process. The output includes a cross reference. .PP The disassembly process is a two pass operation: First the program flow is traced starting with the init and run parameters in the file headers. The dump routine then prints out the information. .PP The command line options are: .TP .I \-b Assume that the file is a boot file, not a load file. .TP .I \-p \fIpfile\fP Read in the predefine file \fIpfile\fP. Up to 20 \fI-p\fP options may be included. .PP Lines in pfile consist of: .PP lineno name .eq number .PP .stop number .PP .trace number .PP .I Lineno refers to a decimal number. .I Number may be a decimal number or may be a hexadecimal number (the first character of the number should be "$"). For example, "$21b5" is the hexadecimal number 21b5. .I Name is a sequence of numbers and characters starting with a letter. .I .trace causes the trace process to continue at the address given. .I .stop causes the trace process to stop at the address given. .SH AUTHOR Robert Bond .SH BUGS SHAR_EOF cat << \SHAR_EOF > dis.h #include #define NPREDEF 10 extern char *predef[]; extern int npredef; extern char *file; extern char *progname; extern int bopt; #ifndef AMIGA extern unsigned char f[]; extern unsigned char d[]; #else extern unsigned char *d,*f; #endif #define getword(x) (d[x] + (d[x+1] << 8)) #define getbyte(x) (d[x]) /* f bits */ #define LOADED 1 /* Location loaded */ #define JREF 2 /* Referenced as jump/branch dest */ #define DREF 4 /* Referenced as data */ #define SREF 8 /* Referenced as subroutine dest */ #define NAMED 0x10 /* Has a name */ #define TDONE 0x20 /* Has been traced */ #define ISOP 0x40 /* Is a valid instruction opcode */ struct info { char opn[4]; int nb; int flag; }; extern struct info optbl[]; /* Flags */ /* Where control goes */ #define NORM 1 #define JUMP 2 #define FORK 4 #define STOP 8 #define CTLMASK (NORM|JUMP|FORK|STOP) /* Instruction format */ #define IMM 0x20 #define ABS 0x40 #define ACC 0x80 #define IMP 0x100 #define INX 0x200 #define INY 0x400 #define ZPX 0x800 #define ABX 0x1000 #define ABY 0x2000 #define REL 0x4000 #define IND 0x8000 #define ZPY 0x10000 #define ZPG 0x20000 #define ILL 0x40000 #define ADRMASK (IMM|ABS|ACC|IMP|INX|INY|ZPX|ABX|ABY|REL|IND|ZPY|ZPG|ILL) struct ref_chain { struct ref_chain *next; int who; }; struct ref_chain *get_ref(); char *get_name(); /* lex junk */ #define EQ 256 #define NUMBER 257 #define NAME 258 #define COMMENT 259 #define LI 260 #define TSTART 261 #define TSTOP 262 extern FILE *yyin, *yyout; int lineno; int yywrap(), yyerror(); char *emalloc(); typedef union { int ival; char *sval; } VALUE; extern VALUE token; SHAR_EOF cat << \SHAR_EOF > dis.notes Some notes about Robert Bond's 'dis' program, Amiga version. This is a quick & dirty port of a 6502 reverse assembler I that I had under my hand for a long time. I didn't bother optimizing the stuff too much, I just wanted to see it working. This is the sort of 'dirty' ports where you first compiler the original file, then watch the compiler errors, and fix the errors in the file, without looking anywhere else in it. Therefor: 1) 'dis' requires C:Sort ( too much bother to replace ) & C:Type ( I AM lazy!!!) 2) I still don't understand why are the line numbers needed in the c64.predef file. I don't have much UNIX experience, and no experience at all with lex. lex code is like chinese to me, but reading the perdef I think that the line numbers are ignored and are used only to easily identify '.eq' lines. 3) The program is recursive, too much recursive! the trace routine calls itself not only on branches, but every instruction! large stacks ( even 50K isn't too much for large programs ), are welcomed... I will modify this as soon as I'll have time. it should be easy to remove recursion in the non branch/jmp instructions. branches must have recursion. I also enhanced the original package, and added support for c64 binary file, which wasn't there before. ( It had only ATARI load/boot files ). The C64 file format was much simpler than those other 2 formats. To select C64 file format, use the '-c' flag. I also included a c64.predefs file with some C64 constant addresses. Also, FYI, lex.c was generated on a SUN from lex.l and then downloaded to the Amiga. lex.c was also __edited__ before compilation. I know that it's a no-no to edit machine-generated files, but it was necessary. Udi Finkelstein 10 Glitzenstein st. Tel Aviv 64686 Israel Phone: 972-3-263-927 BITNET: finkel@taurus.BITNET ( Best ) UUCP: ...!uunet!ulysses!attibr!althea!finkel ( Try avoiding this ) ARPA: finkel%taurus@cunyvm.cuny.edu ( Same as BITNET ) FIDO: Udi Finkelstein ( At 2:40/117 or 2:40/135 If you can get there at all!) SHAR_EOF cat << \SHAR_EOF > initopts.c /* * * dis [-p predefineds] file * * The -p option may be repeated. */ #include "dis.h" char *predef[NPREDEF]; int npredef = 0; char *file; char *progname = "dis"; int bopt = 0; initopts(argc,argv) int argc; char *argv[]; { int ai; char *ca; int fileset = 0; progname = argv[0]; while (--argc) { if ((*++argv)[0] == '-') { ca = *argv; for(ai = 1; ca[ai] != '\0'; ai++) switch (ca[ai]) { case 'p': predef[npredef] = *++argv; npredef++; argc--; break; case 'b': bopt = 1; break; case 'c': bopt = 2; break; default: crash("Invalid option letter"); } } else if (!fileset) { file = *argv; fileset++; } else crash("Usage: [-{c|b}] [-p predef] file"); } if (!fileset) crash("Usage: [-{c|b}] [-p predef] file"); } SHAR_EOF cat << \SHAR_EOF > lex.c # include "stdio.h" # define U(x) x # define NLSTATE yyprevious=YYNEWLINE # define BEGIN yybgin = yysvec + 1 + # define INITIAL 0 # define YYLERR yysvec # define YYSTATE (yyestate-yysvec-1) # define YYOPTIM 1 # define YYLMAX BUFSIZ # define output(c) putc(c,yyout) # define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) # define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;} # define yymore() (yymorfg=1) # define ECHO fprintf(yyout, "%s",yytext) # define REJECT { nstr = yyreject(); goto yyfussy;} int yyleng; extern char yytext[]; int yymorfg; extern char *yysptr, yysbuf[]; int yytchar; FILE *yyin = {stdin}, *yyout = {stdout}; extern int yylineno; struct yysvf { struct yywork *yystoff; struct yysvf *yyother; int *yystops;}; struct yysvf *yyestate; extern struct yysvf yysvec[], *yybgin; #undef ECHO #include "dis.h" #ifndef AMIGA int lineno = 0; #endif char *strcpy(); # define YYNEWLINE 10 yylex(){ int nstr; extern int yyprevious; while((nstr = yylook()) >= 0) yyfussy: switch(nstr){ case 0: if(yywrap()) return(0); break; case 1: { ; } break; case 2: { lineno++; return '\n'; } break; case 3: { return EQ; } break; case 4: { return LI; } break; case 5: { return EQ; } break; case 6: { return LI; } break; case 7: { return TSTART; } break; case 8: { return TSTOP; } break; case 9: { (void)sscanf(yytext, "%d", &token.ival); return NUMBER; } break; case 10: { (void)sscanf(yytext+1, "%x", &token.ival); return NUMBER; } break; case 11: { token.sval = emalloc((unsigned) strlen(yytext)+1); (void)strcpy((char *)token.sval, (char *)yytext); return NAME; } break; case 12: { return COMMENT; } break; case 13: { return yytext[0]; } break; case -1: break; default: fprintf(yyout,"bad switch yylook %d",nstr); } return(0); } /* end of yylex */ char * emalloc(n) unsigned n; { char *ptr, *malloc(); if ((ptr = malloc(n)) == (char *) 0) { (void) fprintf(stderr,"out of core"); exit(1); } return ptr; } int yyvstop[] = { 0, 13, 0, 1, 13, 0, 2, 0, 13, 0, 12, 13, 0, 13, 0, 9, 13, 0, 11, 13, 0, 10, 0, 12, 0, 9, 0, 11, 0, 3, 0, 4, 0, 5, 0, 6, 0, 8, 0, 7, 0, 0}; # define YYTYPE char struct yywork { YYTYPE verify, advance; } yycrank[] = { 0,0, 0,0, 1,3, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 1,4, 1,5, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 7,12, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 7,12, 7,0, 12,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 1,6, 2,6, 0,0, 0,0, 0,0, 0,0, 1,7, 2,7, 0,0, 0,0, 1,8, 2,8, 1,9, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 1,10, 7,12, 0,0, 0,0, 0,0, 0,0, 1,10, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 8,13, 0,0, 0,0, 0,0, 0,0, 7,12, 0,0, 8,14, 0,0, 0,0, 0,0, 7,12, 0,0, 0,0, 14,22, 0,0, 0,0, 1,3, 0,0, 0,0, 0,0, 0,0, 13,21, 0,0, 0,0, 0,0, 6,11, 6,11, 6,11, 6,11, 6,11, 6,11, 8,15, 0,0, 0,0, 7,12, 0,0, 0,0, 0,0, 8,16, 0,0, 0,0, 0,0, 26,28, 0,0, 0,0, 8,17, 8,18, 9,19, 9,19, 9,19, 9,19, 9,19, 9,19, 9,19, 9,19, 9,19, 9,19, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 15,23, 16,24, 17,25, 18,26, 25,27, 27,29, 28,30, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 30,31, 0,0, 0,0, 0,0, 10,20, 0,0, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 10,20, 0,0}; struct yysvf yysvec[] = { 0, 0, 0, yycrank+-1, 0, 0, yycrank+-2, yysvec+1, 0, yycrank+0, 0, yyvstop+1, yycrank+0, 0, yyvstop+3, yycrank+0, 0, yyvstop+6, yycrank+8, 0, yyvstop+8, yycrank+-19, 0, yyvstop+10, yycrank+10, 0, yyvstop+13, yycrank+79, 0, yyvstop+15, yycrank+89, 0, yyvstop+18, yycrank+0, yysvec+6, yyvstop+21, yycrank+-20, yysvec+7, yyvstop+23, yycrank+20, 0, 0, yycrank+20, 0, 0, yycrank+34, 0, 0, yycrank+43, 0, 0, yycrank+33, 0, 0, yycrank+36, 0, 0, yycrank+0, yysvec+9, yyvstop+25, yycrank+0, yysvec+10, yyvstop+27, yycrank+0, 0, yyvstop+29, yycrank+0, 0, yyvstop+31, yycrank+0, 0, yyvstop+33, yycrank+0, 0, yyvstop+35, yycrank+40, 0, 0, yycrank+25, 0, 0, yycrank+40, 0, 0, yycrank+54, 0, 0, yycrank+0, 0, yyvstop+37, yycrank+79, 0, 0, yycrank+0, 0, yyvstop+39, 0, 0, 0}; struct yywork *yytop = yycrank+211; struct yysvf *yybgin = yysvec+1; char yymatch[] = { 00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 011 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , '0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' , '0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 , 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'G' , 'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' , 'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' , 'G' ,'G' ,'G' ,01 ,01 ,01 ,01 ,'_' , 01 ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'G' , 'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' , 'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' ,'G' , 'G' ,'G' ,'G' ,01 ,01 ,01 ,01 ,01 , 0}; char yyextra[] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0}; #ifndef lint static char ncform_sccsid[] = "@(#)ncform 1.2 86/10/08 SMI"; /* from S5R2 1.2 */ #endif int yylineno =1; # define YYU(x) x # define NLSTATE yyprevious=YYNEWLINE char yytext[YYLMAX]; struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; char yysbuf[YYLMAX]; char *yysptr = yysbuf; int *yyfnd; extern struct yysvf *yyestate; int yyprevious = YYNEWLINE; yylook(){ register struct yysvf *yystate, **lsp; register struct yywork *yyt; struct yysvf *yyz; int yych, yyfirst; struct yywork *yyr; # ifdef LEXDEBUG int debug; # endif char *yylastch; /* start off machines */ # ifdef LEXDEBUG debug = 0; # endif yyfirst=1; if (!yymorfg) yylastch = yytext; else { yymorfg=0; yylastch = yytext+yyleng; } for(;;){ lsp = yylstate; yyestate = yystate = yybgin; if (yyprevious==YYNEWLINE) yystate++; for (;;){ # ifdef LEXDEBUG if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1); # endif yyt = yystate->yystoff; if(yyt == yycrank && !yyfirst){ /* may not be any transitions */ yyz = yystate->yyother; if(yyz == 0)break; if(yyz->yystoff == yycrank)break; } *yylastch++ = yych = input(); yyfirst=0; tryagain: # ifdef LEXDEBUG if(debug){ fprintf(yyout,"char "); allprint(yych); putchar('\n'); } # endif yyr = yyt; if ( (int)yyt > (int)yycrank){ yyt = yyr + yych; if (yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } } # ifdef YYOPTIM else if((int)yyt < (int)yycrank) { /* r < yycrank */ yyt = yyr = yycrank+(yycrank-yyt); # ifdef LEXDEBUG if(debug)fprintf(yyout,"compressed state\n"); # endif yyt = yyt + yych; if(yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } yyt = yyr + YYU(yymatch[yych]); # ifdef LEXDEBUG if(debug){ fprintf(yyout,"try fall back character "); allprint(YYU(yymatch[yych])); putchar('\n'); } # endif if(yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transition */ {unput(*--yylastch);break;} *lsp++ = yystate = yyt->advance+yysvec; goto contin; } } if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){ # ifdef LEXDEBUG if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1); # endif goto tryagain; } # endif else {unput(*--yylastch);break;} contin: # ifdef LEXDEBUG if(debug){ fprintf(yyout,"state %d char ",yystate-yysvec-1); allprint(yych); putchar('\n'); } # endif ; } # ifdef LEXDEBUG if(debug){ fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1); allprint(yych); putchar('\n'); } # endif while (lsp-- > yylstate){ *yylastch-- = 0; if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){ yyolsp = lsp; if(yyextra[*yyfnd]){ /* must backup */ while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){ lsp--; unput(*yylastch--); } } yyprevious = YYU(*yylastch); yylsp = lsp; yyleng = yylastch-yytext+1; yytext[yyleng] = 0; # ifdef LEXDEBUG if(debug){ fprintf(yyout,"\nmatch "); sprint(yytext); fprintf(yyout," action %d\n",*yyfnd); } # endif return(*yyfnd++); } unput(*yylastch); } if (yytext[0] == 0 /* && feof(yyin) */) { yysptr=yysbuf; return(0); } yyprevious = yytext[0] = input(); if (yyprevious>0) output(yyprevious); yylastch=yytext; # ifdef LEXDEBUG if(debug)putchar('\n'); # endif } } yyback(p, m) int *p; { if (p==0) return(0); while (*p) { if (*p++ == m) return(1); } return(0); } /* the following are only used in the lex library */ yyinput(){ return(input()); } yyoutput(c) int c; { output(c); } yyunput(c) int c; { unput(c); } SHAR_EOF cat << \SHAR_EOF > lex.l %{ #undef ECHO #include "dis.h" int lineno = 0; char *strcpy(); %} %% [ \t] { ; } [\n] { lineno++; return '\n'; } \.EQ { return EQ; } \.LI { return LI; } \.eq { return EQ; } \.li { return LI; } ".trace" { return TSTART; } ".stop" { return TSTOP; } [0-9]+ { (void)sscanf(yytext, "%d", &token.ival); return NUMBER; } \$[A-Fa-f0-9]+ { (void)sscanf(yytext+1, "%x", &token.ival); return NUMBER; } [A-Za-z][A-Za-z0-9_]* { token.sval = emalloc((unsigned) strlen(yytext)+1); (void)strcpy((char *)token.sval, (char *)yytext); return NAME; } \*.* { return COMMENT; } . { return yytext[0]; } %% char * emalloc(n) unsigned n; { char *ptr, *malloc(); if ((ptr = malloc(n)) == (char *) 0) { (void) fprintf(stderr,"out of core"); exit(1); } return ptr; } SHAR_EOF cat << \SHAR_EOF > main.c #include "dis.h" #define NTSTART 20 char *cur_file = NULL; /* the file thats open */ int pre_index = 0; int tstart[NTSTART]; /* .trace directive keep locations */ int tstarti = 0; VALUE token; #ifdef AMIGA unsigned char *d,*f; /* Manx has a bug preventing us from declaring arrays >64K */ extern unsigned char *calloc(); #else unsigned char d[0x10000]; /* The data */ unsigned char f[0x10000]; /* Flags for memory usage */ #endif #define RUNLOC 0x2e0 #define INITLOC 0x2e2 main(argc, argv) int argc; char *argv[]; { int i; #ifdef AMIGA d = calloc(0x10000,1); f = calloc(0x10000,1); #endif initopts(argc, argv); if (npredef > 0) { cur_file = predef[0]; pre_index++; yyin = fopen(cur_file, "r"); if (!yyin) crash ("Cant open predefine file"); get_predef(); } switch (bopt) { case 0: loadboot(); break; case 1: loadfile(); break; case 2: c64loadfile(); break; } for (i = 0; i 0x10000 || loc < 0) crash("Number out of range"); if (tstarti == NTSTART) crash("Too many .trace directives"); tstart[tstarti++] = loc; while (yylex() != '\n') ; break; case TSTOP: if (yylex() != NUMBER) crash(".stop needs a number operand"); loc = token.ival; if (loc > 0x10000 || loc < 0) crash("Number out of range"); f[loc] |= TDONE; while (yylex() != '\n') ; break; case NUMBER: switch (yylex()) { case LI: case COMMENT: while (yylex() != '\n') ; break; case '\n': break; case NAME: name = token.sval; if (yylex() != EQ) crash("Only EQ and LI supported in defines file"); if (yylex() != NUMBER) crash("EQ operand must be a number"); loc = token.ival; if (loc > 0x10000 || loc < 0) crash("Number out of range"); f[loc] |= NAMED; save_name(loc, name); while (yylex() != '\n') ; break; default: crash("Invalid line in predef file"); } break; default: crash("Invalid line in predef file"); } } loadboot() { struct boot_hdr { unsigned char flags; unsigned char nsec; unsigned char base_low; unsigned char base_hi; unsigned char init_low; unsigned char init_hi; } bh; FILE *fp; int base_addr; register int i; int len; fp = fopen(file, "r"); cur_file = NULL; if (!fp) { fprintf(stderr, "Cant open %s\n", file); #ifdef AMIGA free(d); free(f); #endif exit(1); } if(fread((char *)&bh, sizeof(bh), 1, fp) != 1) crash("Input too short"); base_addr = bh.base_low + (bh.base_hi << 8); len = bh.nsec * 128; rewind(fp); if (fread((char *)&d[base_addr], 1, len, fp) != len) crash("input too short"); for(i = base_addr; len > 0; len--) f[i++] |= LOADED; start_trace(base_addr+6, "**BOOT**"); } loadfile() { FILE *fp; int base_addr; int last_addr; register int i; int had_header; int tmp; had_header = 0; fp = fopen(file, "r"); cur_file = NULL; if (!fp) { fprintf(stderr, "Cant open %s\n", file); #ifdef AMIGA free(d); free(f); #endif exit(1); } for(;;) { i = getc(fp); if (i == EOF) { if (f[RUNLOC] & LOADED & f[RUNLOC+1]) { i = getword(RUNLOC); start_trace(i, "**RUN**"); } return; } i = i | (getc(fp) << 8); if (i == 0xffff) { had_header = 1; base_addr = getc(fp); base_addr = base_addr | (getc(fp) << 8); if (base_addr < 0 || base_addr > 0xffff) crash("Invalid base addr in input file"); } else { if (!had_header) crash("Invalid header in input file"); base_addr = i; } last_addr = getc(fp); last_addr = last_addr | (getc(fp) << 8); if (last_addr < base_addr || last_addr > 0xffff) crash("Invalid length in input file"); printf("Load: %4x -> %4x\n", base_addr, last_addr); for(i = base_addr; i <= last_addr; i++) { tmp = getc(fp); if (tmp == EOF) crash("File too small"); d[i] = tmp; f[i] |= LOADED; } if (f[INITLOC] & LOADED & f[INITLOC+1]) { i = getword(INITLOC); start_trace(i, "**INIT**"); } f[INITLOC] &= ~LOADED; f[INITLOC+1] &= ~LOADED; } } c64loadfile() { FILE *fp; unsigned int base_addr,i; int c; fp = fopen(file, "r"); cur_file = NULL; if (!fp) { fprintf(stderr, "Cant open %s\n", file); #ifdef AMIGA free(d); free(f); #endif exit(1); } base_addr = getc(fp); i = ( base_addr += ( (unsigned int)getc(fp) << 8 ) ); while( (c = getc(fp)) != EOF) { d[i] = c; f[i++] |= LOADED; } start_trace(base_addr, "**C64BIN**"); } start_trace(loc, name) unsigned int loc; char *name; { printf("Trace: %4x %s\n", loc, name); f[loc] |= (NAMED | SREF); if (!get_name(loc)) save_name(loc, name); save_ref(0, loc); trace(loc); } trace(addr) register unsigned int addr; { int opcode; register struct info *ip; int operand; int istart; if (f[addr] & TDONE) return; else f[addr] |= TDONE; istart = addr; opcode = getbyte(addr); ip = &optbl[opcode]; if (ip->flag & ILL) return; f[addr] |= ISOP; addr++; /* Get the operand */ switch(ip->nb) { case 1: break; case 2: operand = getbyte(addr); f[addr++] |= TDONE; break; case 3: operand = getword(addr); f[addr++] |= TDONE; f[addr++] |= TDONE; break; } /* Mark data references */ switch (ip->flag & ADRMASK) { case IMM: case ACC: case IMP: case REL: case IND: break; case ABS: if (ip->flag & (JUMP | FORK)) break; /* Fall into */ case ABX: case ABY: case INX: case INY: case ZPG: case ZPX: case ZPY: f[operand] |= DREF; save_ref(istart, operand); break; default: crash("Optable error"); break; } /* Trace the next instruction */ switch (ip->flag & CTLMASK) { case NORM: trace(addr); break; case JUMP: f[operand] |= JREF; save_ref(istart, operand); trace(operand); break; case FORK: if (ip->flag & REL) { if (operand > 127) operand = (~0xff | operand); operand = operand + addr; f[operand] |= JREF; } else { f[operand] |= SREF; } save_ref(istart, operand); trace(operand); trace(addr); break; case STOP: break; default: crash("Optable error"); break; } } int yywrap() { (void)fclose(yyin); if (npredef == pre_index) { return(1); } else { lineno = 0; cur_file = predef[pre_index]; pre_index++; yyin = fopen(cur_file, "r"); if (!yyin) crash("Can't open predefines file"); return (0); } } SHAR_EOF cat << \SHAR_EOF > print.c #include #include "dis.h" char *strcpy(); char *strcat(); dumpitout() { int i; for(i = 0; i<0x10000;) { if (f[i] & LOADED) { if (f[i] & SREF && f[i] & ISOP) printf("\n\n\n"); printf("%04x ",i); print_bytes(i); print_label(i); if (f[i] & ISOP) i += print_inst(i); else i += print_data(i); printf("\n"); } else { i++; } } print_refs(); } pchar(c) int c; { if (isascii(c) && isprint(c)) return(c); return('.'); } char * lname(i) int i; { static char buf[20]; char t; if (f[i] & NAMED) return(get_name(i)); if ((i > 0) && ((f[i-1] & (NAMED | DREF)) == (NAMED | DREF))) { (void)strcpy(buf, get_name(i-1)); (void)strcat(buf, "+1"); return (buf); } if (f[i] & SREF) t = 'S'; else if (f[i] & JREF) t = 'L'; else if (f[i] & DREF) t = 'D'; else t = 'X'; (void)sprintf(buf, "%c%x", t, i); return (buf); } print_label(i) { if (f[i] & (NAMED | JREF | SREF | DREF)) printf("%-10s", lname(i)); else printf("%10s"," "); } print_bytes(addr) int addr; { register struct info *ip; if ((f[addr] & ISOP) == 0) { printf(" "); return; } ip = &optbl[getbyte(addr)]; switch (ip->nb) { case 1: printf("%02x ", getbyte(addr)); break; case 2: printf("%02x %02x ", getbyte(addr), getbyte(addr+1)); break; case 3: printf("%02x %02x %02x ", getbyte(addr), getbyte(addr+1), getbyte(addr+2)); break; } } print_inst(addr) int addr; { int opcode; register struct info *ip; int operand; opcode = getbyte(addr); ip = &optbl[opcode]; printf("%s ", ip->opn); addr++; switch(ip->nb) { case 1: break; case 2: operand = getbyte(addr); break; case 3: operand = getword(addr); break; } if (ip->flag & REL) { if (operand > 127) operand = (~0xff | operand); operand = operand + ip->nb + addr - 1; } switch (ip->flag & ADRMASK) { case IMM: printf("#$%02x * %d %c", operand, operand, pchar(operand)); break; case ACC: case IMP: break; case REL: case ABS: case ZPG: printf("%s ", lname(operand)); break; case IND: printf("(%s) ", lname(operand)); break; case ABX: case ZPX: printf("%s,X ", lname(operand)); break; case ABY: case ZPY: printf("%s,Y ", lname(operand)); break; case INX: printf("(%s,X) ", lname(operand)); break; case INY: printf("(%s),Y", lname(operand)); break; default: break; } return(ip->nb); } print_data(i) { int count; int j; int start; start = i; printf(".DB %02x ", getbyte(i)); count = 1; i++; for (j = 1; j < 8; j++) { if (f[i] & (JREF | SREF | DREF) || ((f[i] & LOADED) == 0)) break; else printf("%02x ", getbyte(i)); i++; count++; } for (j = count; j < 8; j++) printf(" "); printf(" * "); for (j = start; j < i ; j++) printf("%c", pchar((int)getbyte(j))); return (count); } print_refs() { char tname[50]; char cmd[200]; FILE *fp; register struct ref_chain *rp; register int i; int npline; #ifndef AMIGA (void)sprintf(tname, "dis.%d", getpid()); (void)sprintf(cmd, "sort %s; rm %s", tname, tname); #else (void)sprintf(tname, "dis.%ld", FindTask(0L)); (void)sprintf(cmd, "Sort from %s to %s", tname, &tname[3] ); #endif fp = fopen(tname, "w"); if (!fp) crash("Cant open temporary file/n"); for (i = 0; i<0x10000; i++) { if(f[i] & (JREF|SREF|DREF)) { rp = get_ref(i); if (!rp) { fprintf(stderr, "No ref %d\n", i); break; } fprintf(fp, "%-8s %04x ", lname(i), i); npline = 0; while (rp) { fprintf(fp, "%04x ", rp->who); npline++; if (npline == 12) { fprintf(fp,"\n"); fprintf(fp,"%-8s %04x ",lname(i),i); npline = 0; } rp = rp->next; } fprintf(fp, "\n"); } } (void)fclose(fp); printf("\n\n\n\n\nCross References\n\n"); printf("%-8s Value References\n", "Symbol"); (void)fflush (stdout); #ifndef AMIGA (void)system(cmd); #else (void)Execute(cmd,0L,0L); (void)sprintf(cmd, "Type %s",&tname[3]); (void)Execute(cmd,0L,Output()); DeleteFile(tname); DeleteFile(&tname[3]); #endif } SHAR_EOF cat << \SHAR_EOF > ref.c #include "dis.h" #define HTSIZE 0x1000 /* Power of 2 */ #define HTMASK (HTSIZE-1) struct hashslot { int addr; /* The key */ struct ref_chain *ref; /* Who references it */ char *name; /* The symbolic name (if it has one) */ }; struct hashslot hashtbl[HTSIZE]; /* the hash table */ struct hashslot * hash(loc, allocate) int loc; int allocate; { int probes; register struct hashslot *hp; hp = &hashtbl[loc & HTMASK]; probes = 0; while (probes< HTSIZE) { if (hp->addr == loc) return(hp); if (hp->name == NULL && hp->ref == NULL) { if (allocate) { hp->addr = loc; return(hp); } else { return(NULL); } } hp++; if (hp == &hashtbl[HTSIZE]) hp = &hashtbl[0]; probes++; } crash("Hash table full"); /*NOTREACHED*/ } save_ref(refer, refee) int refer; int refee; { struct ref_chain *rc; struct hashslot *hp; rc = (struct ref_chain *)emalloc(sizeof(*rc)); rc->who = refer; hp = hash(refee, 1); rc->next = hp->ref; hp->ref = rc; } save_name(loc, name) int loc; char *name; { struct hashslot *hp; hp = hash(loc, 1); hp->name = name; } struct ref_chain * get_ref(loc) { struct hashslot *hp; hp = hash(loc, 0); if (!hp) return(NULL); return(hp->ref); } char * get_name(loc) { struct hashslot *hp; hp = hash(loc, 0); if (!hp) return(NULL); return(hp->name); } SHAR_EOF cat << \SHAR_EOF > tbl.c #include "dis.h" struct info optbl[256] = { /* 00 */ { { 'B', 'R', 'K', 0, }, 1, IMP|STOP, }, /* 01 */ { { 'O', 'R', 'A', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 05 */ { { 'O', 'R', 'A', 0, }, 2, ZPG|NORM, }, /* 06 */ { { 'A', 'S', 'L', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 08 */ { { 'P', 'H', 'P', 0, }, 1, IMP|NORM, }, /* 09 */ { { 'O', 'R', 'A', 0, }, 2, IMM|NORM, }, /* 0a */ { { 'A', 'S', 'L', 0, }, 1, ACC|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 0d */ { { 'O', 'R', 'A', 0, }, 3, ABS|NORM, }, /* 0e */ { { 'A', 'S', 'L', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 10 */ { { 'B', 'P', 'L', 0, }, 2, REL|FORK, }, /* 11 */ { { 'O', 'R', 'A', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 15 */ { { 'O', 'R', 'A', 0, }, 2, ZPX|NORM, }, /* 16 */ { { 'A', 'S', 'L', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 18 */ { { 'C', 'L', 'C', 0, }, 1, IMP|NORM, }, /* 19 */ { { 'O', 'R', 'A', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 1d */ { { 'O', 'R', 'A', 0, }, 3, ABX|NORM, }, /* 1e */ { { 'A', 'S', 'L', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 20 */ { { 'J', 'S', 'R', 0, }, 3, ABS|FORK, }, /* 21 */ { { 'A', 'N', 'D', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 24 */ { { 'B', 'I', 'T', 0, }, 2, ZPG|NORM, }, /* 25 */ { { 'A', 'N', 'D', 0, }, 2, ZPG|NORM, }, /* 26 */ { { 'R', 'O', 'L', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 28 */ { { 'P', 'L', 'P', 0, }, 1, IMP|NORM, }, /* 29 */ { { 'A', 'N', 'D', 0, }, 2, IMM|NORM, }, /* 2a */ { { 'R', 'O', 'L', 0, }, 1, ACC|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 2c */ { { 'B', 'I', 'T', 0, }, 3, ABS|NORM, }, /* 2d */ { { 'A', 'N', 'D', 0, }, 3, ABS|NORM, }, /* 2e */ { { 'R', 'O', 'L', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 30 */ { { 'B', 'M', 'I', 0, }, 2, REL|FORK, }, /* 31 */ { { 'A', 'N', 'D', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 35 */ { { 'A', 'N', 'D', 0, }, 2, ZPX|NORM, }, /* 36 */ { { 'R', 'O', 'L', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 38 */ { { 'S', 'E', 'C', 0, }, 1, IMP|NORM, }, /* 39 */ { { 'A', 'N', 'D', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 3d */ { { 'A', 'N', 'D', 0, }, 3, ABX|NORM, }, /* 3e */ { { 'R', 'O', 'L', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 40 */ { { 'R', 'T', 'I', 0, }, 1, IMP|STOP, }, /* 41 */ { { 'E', 'O', 'R', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 45 */ { { 'E', 'O', 'R', 0, }, 2, ZPG|NORM, }, /* 46 */ { { 'L', 'S', 'R', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 48 */ { { 'P', 'H', 'A', 0, }, 1, IMP|NORM, }, /* 49 */ { { 'E', 'O', 'R', 0, }, 2, IMM|NORM, }, /* 4a */ { { 'L', 'S', 'R', 0, }, 1, ACC|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 4c */ { { 'J', 'M', 'P', 0, }, 3, ABS|JUMP, }, /* 4d */ { { 'E', 'O', 'R', 0, }, 3, ABS|NORM, }, /* 4e */ { { 'L', 'S', 'R', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 50 */ { { 'B', 'V', 'C', 0, }, 2, REL|FORK, }, /* 51 */ { { 'E', 'O', 'R', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 55 */ { { 'E', 'O', 'R', 0, }, 2, ZPX|NORM, }, /* 56 */ { { 'L', 'S', 'R', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 58 */ { { 'C', 'L', 'I', 0, }, 1, IMP|NORM, }, /* 59 */ { { 'E', 'O', 'R', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 5d */ { { 'E', 'O', 'R', 0, }, 3, ABX|NORM, }, /* 5e */ { { 'L', 'S', 'R', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 60 */ { { 'R', 'T', 'S', 0, }, 1, IMP|STOP, }, /* 61 */ { { 'A', 'D', 'C', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 65 */ { { 'A', 'D', 'C', 0, }, 2, ZPG|NORM, }, /* 66 */ { { 'R', 'O', 'R', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 68 */ { { 'P', 'L', 'A', 0, }, 1, IMP|NORM, }, /* 69 */ { { 'A', 'D', 'C', 0, }, 2, IMM|NORM, }, /* 6a */ { { 'R', 'O', 'R', 0, }, 1, ACC|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 6c */ { { 'J', 'M', 'P', 0, }, 3, IND|STOP, }, /* 6d */ { { 'A', 'D', 'C', 0, }, 3, ABS|NORM, }, /* 6e */ { { 'R', 'O', 'R', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 70 */ { { 'B', 'V', 'S', 0, }, 2, REL|FORK, }, /* 71 */ { { 'A', 'D', 'C', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 75 */ { { 'A', 'D', 'C', 0, }, 2, ZPX|NORM, }, /* 76 */ { { 'R', 'O', 'R', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 78 */ { { 'S', 'E', 'I', 0, }, 1, IMP|NORM, }, /* 79 */ { { 'A', 'D', 'C', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 7d */ { { 'A', 'D', 'C', 0, }, 3, ABX|NORM, }, /* 7e */ { { 'R', 'O', 'R', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 81 */ { { 'S', 'T', 'A', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 84 */ { { 'S', 'T', 'Y', 0, }, 2, ZPG|NORM, }, /* 85 */ { { 'S', 'T', 'A', 0, }, 2, ZPG|NORM, }, /* 86 */ { { 'S', 'T', 'X', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 88 */ { { 'D', 'E', 'Y', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 8a */ { { 'T', 'X', 'A', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 8c */ { { 'S', 'T', 'Y', 0, }, 3, ABS|NORM, }, /* 8d */ { { 'S', 'T', 'A', 0, }, 3, ABS|NORM, }, /* 8e */ { { 'S', 'T', 'X', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 90 */ { { 'B', 'C', 'C', 0, }, 2, REL|FORK, }, /* 91 */ { { 'S', 'T', 'A', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 94 */ { { 'S', 'T', 'Y', 0, }, 2, ZPX|NORM, }, /* 95 */ { { 'S', 'T', 'A', 0, }, 2, ZPX|NORM, }, /* 96 */ { { 'S', 'T', 'X', 0, }, 2, ZPY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 98 */ { { 'T', 'Y', 'A', 0, }, 1, IMP|NORM, }, /* 99 */ { { 'S', 'T', 'A', 0, }, 3, ABY|NORM, }, /* 9a */ { { 'T', 'X', 'S', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 9d */ { { 'S', 'T', 'A', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* a0 */ { { 'L', 'D', 'Y', 0, }, 2, IMM|NORM, }, /* a1 */ { { 'L', 'D', 'A', 0, }, 2, INX|NORM, }, /* a2 */ { { 'L', 'D', 'X', 0, }, 2, IMM|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* a4 */ { { 'L', 'D', 'Y', 0, }, 2, ZPG|NORM, }, /* a5 */ { { 'L', 'D', 'A', 0, }, 2, ZPG|NORM, }, /* a6 */ { { 'L', 'D', 'X', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* a8 */ { { 'T', 'A', 'Y', 0, }, 1, IMP|NORM, }, /* a9 */ { { 'L', 'D', 'A', 0, }, 2, IMM|NORM, }, /* aa */ { { 'T', 'A', 'X', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* ac */ { { 'L', 'D', 'Y', 0, }, 3, ABS|NORM, }, /* ad */ { { 'L', 'D', 'A', 0, }, 3, ABS|NORM, }, /* ae */ { { 'L', 'D', 'X', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* b0 */ { { 'B', 'C', 'S', 0, }, 2, REL|FORK, }, /* b1 */ { { 'L', 'D', 'A', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* b4 */ { { 'L', 'D', 'Y', 0, }, 2, ZPX|NORM, }, /* b5 */ { { 'L', 'D', 'A', 0, }, 2, ZPX|NORM, }, /* b6 */ { { 'L', 'D', 'X', 0, }, 2, ZPY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* b8 */ { { 'C', 'L', 'V', 0, }, 1, IMP|NORM, }, /* b9 */ { { 'L', 'D', 'A', 0, }, 3, ABY|NORM, }, /* ba */ { { 'T', 'S', 'X', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* bc */ { { 'L', 'D', 'Y', 0, }, 3, ABX|NORM, }, /* bd */ { { 'L', 'D', 'A', 0, }, 3, ABX|NORM, }, /* be */ { { 'L', 'D', 'X', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* c0 */ { { 'C', 'P', 'Y', 0, }, 2, IMM|NORM, }, /* c1 */ { { 'C', 'M', 'P', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* c4 */ { { 'C', 'P', 'Y', 0, }, 2, ZPG|NORM, }, /* c5 */ { { 'C', 'M', 'P', 0, }, 2, ZPG|NORM, }, /* c6 */ { { 'D', 'E', 'C', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* c8 */ { { 'I', 'N', 'Y', 0, }, 1, IMP|NORM, }, /* c9 */ { { 'C', 'M', 'P', 0, }, 2, IMM|NORM, }, /* ca */ { { 'D', 'E', 'X', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* cc */ { { 'C', 'P', 'Y', 0, }, 3, ABS|NORM, }, /* cd */ { { 'C', 'M', 'P', 0, }, 3, ABS|NORM, }, /* ce */ { { 'D', 'E', 'C', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* d0 */ { { 'B', 'N', 'E', 0, }, 2, REL|FORK, }, /* d1 */ { { 'C', 'M', 'P', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* d5 */ { { 'C', 'M', 'P', 0, }, 2, ZPX|NORM, }, /* d6 */ { { 'D', 'E', 'C', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* d8 */ { { 'C', 'L', 'D', 0, }, 1, IMP|NORM, }, /* d9 */ { { 'C', 'M', 'P', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* dd */ { { 'C', 'M', 'P', 0, }, 3, ABX|NORM, }, /* de */ { { 'D', 'E', 'C', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* e0 */ { { 'C', 'P', 'X', 0, }, 2, IMM|NORM, }, /* e1 */ { { 'S', 'B', 'C', 0, }, 2, INX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* e4 */ { { 'C', 'P', 'X', 0, }, 2, ZPG|NORM, }, /* e5 */ { { 'S', 'B', 'C', 0, }, 2, ZPG|NORM, }, /* e6 */ { { 'I', 'N', 'C', 0, }, 2, ZPG|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* e8 */ { { 'I', 'N', 'X', 0, }, 1, IMP|NORM, }, /* e9 */ { { 'S', 'B', 'C', 0, }, 2, IMM|NORM, }, /* ea */ { { 'N', 'O', 'P', 0, }, 1, IMP|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* ec */ { { 'C', 'P', 'X', 0, }, 3, ABS|NORM, }, /* ed */ { { 'S', 'B', 'C', 0, }, 3, ABS|NORM, }, /* ee */ { { 'I', 'N', 'C', 0, }, 3, ABS|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* f0 */ { { 'B', 'E', 'Q', 0, }, 2, REL|FORK, }, /* f1 */ { { 'S', 'B', 'C', 0, }, 2, INY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* f5 */ { { 'S', 'B', 'C', 0, }, 2, ZPX|NORM, }, /* f6 */ { { 'I', 'N', 'C', 0, }, 2, ZPX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* f8 */ { { 'S', 'E', 'D', 0, }, 1, IMP|NORM, }, /* f9 */ { { 'S', 'B', 'C', 0, }, 3, ABY|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, /* fd */ { { 'S', 'B', 'C', 0, }, 3, ABX|NORM, }, /* fe */ { { 'I', 'N', 'C', 0, }, 3, ABX|NORM, }, /* 00 */ { { '?', '?', '?', 0, }, 1, ILL|NORM, }, }; SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.