home *** CD-ROM | disk | FTP | other *** search
- /* Assembler for the MOS Technology 650X series of microprocessors
- * Written by J. H. Van Ornum (201) 949-1781
- * AT&T Bell Laboratories
- * Holmdel, NJ
- *
- *
- * Two changes to version 1.4 have been made to "port" as6502 to CP/M(tm).
- * A "tolower()" function call was add to the command line processing
- * code to (re)map the command line arguments to lower case (CP/M
- * converts all command line arguments to upper case). The readline()
- * function has code added to "ignore" the '\r' character (CP/M includes
- * the \r character along with \n).
- *
- * The ability to process multiple files on the command line has been
- * added. Now one can do, for example:
- *
- * as6502 -nisvo header.file source.file data.file ...
- *
- * George V. Wilder
- * IX 1A-360 x1937
- * ihuxp!gvw1
- *
- * All files merged and modified for Macintosh, 02.27.95
- * R. T. Kneusel
- *
- * Mac changes commented out, look for MACINTOSH if you want
- * them back in. RTK, 24-Jul-97
- *
- * John Saeger was here. (john@whimsey.com)
- * ----------------------------------------
- * (July 7, 1998)
- *
- * Mac changes and CPMEOF removed.
- * Merged header file (no more assm.h).
- * Removed split address mode.
- * Always print symbol table at end of listing.
- * Reversed sense of lflag (default off).
- * Increased size of symbol table.
- * Removed debug printout, but print symbol table usage at end of listing.
- * Added org pseudo op.
- * Added binary file output to 6502.bin.
- * Added error message "Can't relocate backwards."
- * Removed text file output 6502.out.
- * Reversed sense of oflag (default on).
- * Reformat listing line slightly, allow more source lines.
- * Adopted larger opcode and step tables from Joel Swank's Amiga version of as6502.
- * Added undocumented opcodes, and addressing mode IMM3 (for undoc NOOPs).
- * Disallow . as first char in symbol name. Means current value of location counter.
- * Modify Class2() to prevent backward relocation if undefined label.
- * ----------------------------------------
- *
- *
- * Paul Baxter was Here 6/21/2000
- * Mac Compatable AGAIN
- * use function prototypes
- * use global notation g### for global vars
- * clean up argument parsing
- * set maxmum symbol size to 512 bytes (just because)
- * now use -l -v -o etc instead of -lvo (makes it compatable for MPW commando)
- * arguments may be passed in any order
- * fix list position for comments with one byte opcodes
- * use stdin for input file if none given
- * use stderr for error messages
- * add .incl directive
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <console.h>
- #include <MixedMode.h>
-
- #define LAST_CH_POS 132
- #define SFIELD 23
- #define STABSZ 32000 /* was 6000 */
- #define SBOLSZ 512
-
- /*
- * symbol flags
- */
- #define DEFZRO 2 /* defined - page zero address */
- #define MDEF 3 /* multiply defined */
- #define UNDEF 1 /* undefined - may be zero page */
- #define DEFABS 4 /* defined - two byte address */
- #define UNDEFAB 5 /* undefined - two byte address */
-
- /*
- * operation code flags
- */
- #define PSEUDO 0x6000
- #define CLASS1 0x2000
- #define CLASS2 0x4000
-
- #define IMM3 0x8000 /* opval + 0x80 2 byte for NOOP # */
- #define IMM1 0x1000 /* opval + 0x00 2 byte */
- #define IMM2 0x0800 /* opval + 0x08 2 byte */
- #define ABS 0x0400 /* opval + 0x0C 3 byte */
- #define ZER 0x0200 /* opval + 0x04 2 byte */
- #define INDX 0x0100 /* opval + 0x00 2 byte */
- #define ABSY2 0x0080 /* opval + 0x1C 3 byte */
- #define INDY 0x0040 /* opval + 0x10 2 byte */
- #define ZERX 0x0020 /* opval + 0x14 2 byte */
- #define ABSX 0x0010 /* opval + 0x1C 3 byte */
- #define ABSY 0x0008 /* opval + 0x18 3 byte */
- #define ACC 0x0004 /* opval + 0x08 1 byte */
- #define IND 0x0002 /* opval + 0x2C 3 byte */
- #define ZERY 0x0001 /* opval + 0x14 2 byte */
-
- /*
- * pass flags
- */
- #define FIRST_PASS 0
- #define LAST_PASS 1
- #define DONE 2
-
- #define EOL '\n'
- #define kHASH_SIZE 128
- #define kHEX_SIZE 5
-
- FILE *gIptr; /* input file */
- FILE *gBinptr; /* output file */
- unsigned int gFile_loc; /* gets location counter on first write,
- then incremented byte by byte.
- fill is written to file to make file_loc==loccnt
- when there is a re-org */
- int gErrcnt; /* error counter */
- int gInited = 0; /* Bin file created */
- int gHash_tbl[kHASH_SIZE]; /* pointers to starting links in gSymtab */
- char gHex[kHEX_SIZE]; /* hexadecimal character buffer */
- unsigned int gLoccnt; /* location counter */
- int gLablptr; /* label pointer into symbol table */
- int gNxt_free; /* next free location in gSymtab */
- int gOpflg; /* operation code flags */
- int gOpval; /* operation code value */
- int gPass; /* pass counter */
- char gPrlnbuf[LAST_CH_POS+1];/* print line buffer */
- unsigned int gSlnum; /* source line number counter */
- char gSymtab[STABSZ]; /* symbol table */
- /* struct sym_tab */
- /* { char size; */
- /* char chars[size]; */
- /* char flag; */
- /* int value; */
- /* int next_pointer */
- /* } */
- char gSymbol0[SBOLSZ]; /* temporary symbol storage */
- int gUdtype; /* undefined symbol type */
- int gUndef; /* undefined symbol in expression flg */
- int gValue; /* operand field value */
- char gZpref; /* zero page reference flag */
-
-
- int gIflag=0; /* ignore .nlst flag */
- int gLflag=0; /* enable listing flag */
- int gSflag=0; /* do a symbol table print at end of listing */
- int gOflag=1; /* object output flag */
- int gVflag=0; /* printversion flag */
- int gDflag=0; /* Diagnostoc flag */
- int gNextInputFile=0; /* source file index */
- int gLastInputFile=0; /* last file index */
- char* gFiles[] = { /* array of files to be processed */
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", ""
- };
- #define kMAXFILES sizeof(gFiles) / sizeof(char*)
-
- void DefaultOption(int* var);
- void NoOutputOption(int* var);
- void VersionOption(int* var);
- void ListingOption(int* var);
- void PrintOpTable(int* val);
-
-
- typedef void (*OptionFunPtr)(int* var);
- typedef struct {
- char* option;
- int* variable;
- OptionFunPtr fun;
- } OptionSet;
- OptionSet gOptions[] = {
- { "-i", &gIflag, ListingOption},
- { "-l", &gLflag, DefaultOption},
- { "-s", &gSflag, DefaultOption },
- { "-v", &gVflag, VersionOption },
- { "-o", &gOflag, NoOutputOption },
- { "-d", &gDflag, PrintOpTable }
- };
- #define kNumOptions sizeof(gOptions) / sizeof(OptionSet)
-
- int gField[] =
- {
- SFIELD,
- SFIELD + 8,
- SFIELD + 14,
- SFIELD + 23,
- SFIELD + 43,
- SFIELD + 75
- };
-
- #define A 0x20)+('A'&0x1f))
- #define B 0x20)+('B'&0x1f))
- #define C 0x20)+('C'&0x1f))
- #define D 0x20)+('D'&0x1f))
- #define E 0x20)+('E'&0x1f))
- #define F 0x20)+('F'&0x1f))
- #define G 0x20)+('G'&0x1f))
- #define H 0x20)+('H'&0x1f))
- #define I 0x20)+('I'&0x1f))
- #define J 0x20)+('J'&0x1f))
- #define K 0x20)+('K'&0x1f))
- #define L 0x20)+('L'&0x1f))
- #define M 0x20)+('M'&0x1f))
- #define N 0x20)+('N'&0x1f))
- #define O 0x20)+('O'&0x1f))
- #define P 0x20)+('P'&0x1f))
- #define Q 0x20)+('Q'&0x1f))
- #define R 0x20)+('R'&0x1f))
- #define S 0x20)+('S'&0x1f))
- #define T 0x20)+('T'&0x1f))
- #define U 0x20)+('U'&0x1f))
- #define V 0x20)+('V'&0x1f))
- #define W 0x20)+('W'&0x1f))
- #define X 0x20)+('X'&0x1f))
- #define Y 0x20)+('Y'&0x1f))
- #define Z 0x20)+('Z'&0x1f))
-
-
-
- #define OPSIZE 127 /* # of opcodes in optab - 1 */
-
- int gOptab[] = /* nmemonic operation code table */
- { /* '.' = 31, '*' = 30, '=' = 29 */
- ((0*0x20)+(29)),PSEUDO,1, /* = */
- ((((0*0x20)+(30))*0x20)+(29)),PSEUDO,3, /* *= */
- ((((((0*A*D*C,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0x61,
- ((((((0*A*N*C,IMM1,0x0b,
- ((((((0*A*N*D,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0x21,
- ((((((0*A*N*E,IMM1,0x8b,
- ((((((0*A*R*R,IMM1,0x6b,
- ((((((0*A*S*L,ABS|ZER|ZERX|ABSX|ACC,0x02,
- ((((((0*A*S*R,IMM1,0x4b,
- ((((((0*B*C*C,CLASS2,0x90,
- ((((((0*B*C*S,CLASS2,0xb0,
- ((((((0*B*E*Q,CLASS2,0xf0,
- ((((((0*B*I*T,ABS|ZER,0x20,
- ((((((0*B*M*I,CLASS2,0x30,
- ((((((0*B*N*E,CLASS2,0xd0,
- ((((((0*B*P*L,CLASS2,0x10,
- ((((((0*B*R*K,CLASS1,0x00,
- ((((((0*B*V*C,CLASS2,0x50,
- ((((((0*B*V*S,CLASS2,0x70,
- ((((((0*C*L*C,CLASS1,0x18,
- ((((((0*C*L*D,CLASS1,0xd8,
- ((((((0*C*L*I,CLASS1,0x58,
- ((((((0*C*L*V,CLASS1,0xb8,
- ((((((0*C*M*P,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0xc1,
- ((((((0*C*P*X,IMM1|ABS|ZER,0xe0,
- ((((((0*C*P*Y,IMM1|ABS|ZER,0xc0,
- ((((((0*D*C*P,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0xc3,
- ((((((0*D*E*C,ABS|ZER|ZERX|ABSX,0xc2,
- ((((((0*D*E*X,CLASS1,0xca,
- ((((((0*D*E*Y,CLASS1,0x88,
- ((((((0*E*O*R,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0x41,
- ((((((0*I*N*C,ABS|ZER|ZERX|ABSX,0xe2,
- ((((((0*I*N*X,CLASS1,0xe8,
- ((((((0*I*N*Y,CLASS1,0xc8,
- ((((((0*I*S*B,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0xe3,
- ((((((0*J*A*M,CLASS1,0x02,
- ((((((0*J*M*P,ABS|IND,0x40,
- ((((((0*J*S*R,ABS,0x14,
- ((((((0*L*A*S,ABSY,0xa3,
- ((((((0*L*A*X,ZER|ZERY|ABS|ABSY2|INDX|INDY,0xa3,
- ((((((0*L*D*A,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0xa1,
- ((((((0*L*D*X,IMM1|ABS|ZER|ABSY2|ZERY,0xa2,
- ((((((0*L*D*Y,IMM1|ABS|ZER|ABSX|ZERX,0xa0,
- ((((((0*L*S*R,ABS|ZER|ZERX|ABSX|ACC,0x42,
- ((((((0*L*X*A,IMM1,0xab,
- ((((((0*N*O*P,CLASS1,0xea, /* 0x39f0 */
- ((((((0*N*O*O^((0*P,IMM3|ZER|ZERX|ABS|ABSX,0x00, /* 0x39ff */
- ((((((0*O*R*A,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0x01,
- ((((((0*O*R*G,PSEUDO,3,
- ((((((0*P*H*A,CLASS1,0x48,
- ((((((0*P*H*P,CLASS1,0x08,
- ((((((0*P*L*A,CLASS1,0x68,
- ((((((0*P*L*P,CLASS1,0x28,
- ((((((0*R*L*A,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0x23,
- ((((((0*R*O*L,ABS|ZER|ZERX|ABSX|ACC,0x22,
- ((((((0*R*O*R,ABS|ZER|ZERX|ABSX|ACC,0x62,
- ((((((0*R*R*A,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0x63,
- ((((((0*R*T*I,CLASS1,0x40,
- ((((((0*R*T*S,CLASS1,0x60,
- ((((((0*S*A*X,ZER|ZERY|ABS|INDX,0x83,
- ((((((0*S*B*C,IMM2|ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0xe1,
- ((((((0*S*B*X,IMM1,0xcb,
- ((((((0*S*E*C,CLASS1,0x38,
- ((((((0*S*E*D,CLASS1,0xf8,
- ((((((0*S*E*I,CLASS1,0x78,
- ((((((0*S*H*A,ABSY2|INDY,0x83,
- ((((((0*S*H*S,ABSY,0x83,
- ((((((0*S*H*X,ABSY,0x86,
- ((((((0*S*H*Y,ABSX,0x80,
- ((((((0*S*L*O,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0x03,
- ((((((0*S*R*E,ZER|ZERX|ABS|ABSX|ABSY|INDX|INDY,0x43,
- ((((((0*S*T*A,ABS|ZER|INDX|INDY|ZERX|ABSX|ABSY,0x81,
- ((((((0*S*T*X,ABS|ZER|ZERY,0x82,
- ((((((0*S*T*Y,ABS|ZER|ZERX,0x80,
- ((((((0*T*A*X,CLASS1,0xaa,
- ((((((0*T*A*Y,CLASS1,0xa8,
- ((((((0*T*S*X,CLASS1,0xba,
- ((((((0*T*X*A,CLASS1,0x8a,
- ((((((0*T*X*S,CLASS1,0x9a,
- ((((((0*T*Y*A,CLASS1,0x98,
- ((((((0*U*S*B^((0*C,IMM1,0xeb,
- ((((((0*0x20)+(31))*W*O^((((0*R*D,PSEUDO,2, /* 0x7cab */
- ((((((0*0x20)+(31))*I*N^((((0*C*L,PSEUDO,7, /* 0x7d42 */
- ((((((0*0x20)+(31))*B*Y^((((0*T*E,PSEUDO,0, /* 0x7edc */
- ((((((0*0x20)+(31))*D*B^((((0*Y*T,PSEUDO,6, /* 0x7fb6 */
- ((((((0*0x20)+(31))*N*L^((((0*S*T,PSEUDO,5, /* 0x7fb8 */
- ((((((0*0x20)+(31))*L*I^((((0*S*T,PSEUDO,4, /* 0x7ffd */
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0,
- 0x7fff,0,0
- };
-
- /* binary search steps for opcode table */
-
- int gStep[] =
- {
- 3*((OPSIZE+1)/2),
- 3*((((OPSIZE+1)/2)+1)/2),
- 3*((((((OPSIZE+1)/2)+1)/2)+1)/2),
- 3*((((((((OPSIZE+1)/2)+1)/2)+1)/2)+1)/2),
- 3*((((((((((OPSIZE+1)/2)+1)/2)+1)/2)+1)/2)+1)/2),
- 3*(2),
- 3*(1),
- 0
- };
-
- int initialize(char* theFile);
- int readline(void);
- int assemble(void);
- int stprnt(void);
- int wrapup(void);
- int binputc (char ch, FILE * fileptr);
- int hexcon(int digit, int num);
- int println(void);
- int colsym(int * ip);
- int stlook(void);
- int oplook(int *ip);
- int labldef(int lval);
- int error(char* stptr);
- int loadlc(int val, int f, int outflg);
- int pseudo(int* ip);
- int class1(void);
- int class2(int* ip);
- int class3(int* ip);
- int stinstal(void);
- int loadv(int val, int f, int outflg);
- int symval(int* ip);
- int evaluate(int* ip);
- int colnum(int* ip);
- void parseArgs( int argc, char *argv[]);
- void FixUpAPP(void);
-
- int main(int argc, char *argv[]);
- #define k6502CPU 3
-
-
-
- RoutineDescriptor myDescriptor = {
- _MixedModeMagic,
- kRoutineDescriptorVersion, // version
- kSelectorsAreNotIndexable, // Routine Descriptor Flags
- 0, // reserved1
- 0, // reserved2
- 0, // selectorInfo
- 0, // routineCount
- {
- 0, // procInfo
- 0, // reserved
- k6502CPU, // ISA
- kProcDescriptorIsRelative, // routineFlags
- (ProcPtr)sizeof(myDescriptor), // WHERE
- 0, // reserved2
- 0 // selector
- }
- };
-
-
- int main(int argc, char *argv[])
- {
- int i;
- int localspot[kMAXFILES];
-
- argc = ccommand(&argv);
-
- gPass = FIRST_PASS;
- for (i = 0; i < kHASH_SIZE; i++)
- gHash_tbl[i] = -1;
-
- gErrcnt = gLoccnt = gSlnum = 0;
-
- while (gPass != DONE) {
-
- parseArgs(argc, argv);
- initialize(gFiles[gNextInputFile]);
-
- if (gPass == FIRST_PASS) {
- localspot[gNextInputFile] = gLoccnt; // save start position of file
- }
- else if(gPass == LAST_PASS) {
- gLoccnt = localspot[gNextInputFile]; // restore start position of file
- gSlnum = 0; // Line number
- }
-
- while (readline() != -1)
- assemble();
-
- if (gErrcnt != 0) {
- gPass = DONE;
- fprintf(stderr, "Terminated with error counter = %d\n", gErrcnt);
- }
-
- switch (gPass) {
- case FIRST_PASS:
- // see if we have any more files to do
- if (gFiles[gNextInputFile + 1][0] == 0) {
- gPass = LAST_PASS;
- gNextInputFile = 0;
- }
- else {
- gNextInputFile++;
- }
- break;
-
- case LAST_PASS:
- // see if we have any more files to do
- if (gFiles[gNextInputFile + 1][0] == 0) {
- gPass = DONE;
- if (gSflag) {
- stprnt();
- }
- }
- else {
- gNextInputFile++;
- }
- break;
-
- default:
- break;
- }
- wrapup();
- }
-
- FixUpAPP();
-
- return(0);
- }
-
- /*****************************************************************************/
-
- /* initialize opens files */
-
- int initialize(char* theFile)
- {
- UInt32 jumpcode;
-
- if (theFile[0] == 0) {
- gIptr = stdin;
- }
- else if ((gIptr = fopen(theFile, "r")) == NULL) {
- fprintf(stderr, "Open error for file '%s'.\n", theFile);
- exit(1);
- }
-
- if ((gInited == 0) && (gOflag == 1)) {
- if ((gBinptr = fopen("6502.bin", "wb")) == NULL) {
- fprintf(stderr, "Can't create 6502.bin.\n");
- exit(1);
- }
- jumpcode = 0x00000001;
- fwrite(&jumpcode, sizeof(jumpcode), 1, gBinptr);
- fwrite(&myDescriptor, sizeof(myDescriptor), 1, gBinptr);
- gInited++;
- }
- return 0;
- }
-
-
- /* readline reads and formats an input line */
-
- int readline(void)
- {
- int i; /* pointer into prlnbuf */
- int j; /* pointer to current field start */
- int ch; /* current character */
- int cmnt; /* comment line flag */
- int spcnt; /* consecutive space counter */
- int string; /* ASCII string flag */
- int temp1; /* temp used for line number conversion */
-
- temp1 = ++gSlnum;
- for (i = 0; i < LAST_CH_POS; i++)
- gPrlnbuf[i] = ' ';
- i = 4;
- while (temp1 != 0) { /* put source line number into prlnbuf */
- gPrlnbuf[i--] = temp1 % 10 + '0';
- temp1 /= 10;
- }
- i = SFIELD;
- cmnt = spcnt = string = 0;
- j = 1;
- while ((ch = getc(gIptr)) != EOL) {
- gPrlnbuf[i++] = ch;
- if ((ch == ' ') && (string == 0)) {
- if (spcnt != 0)
- --i;
- else if (cmnt == 0) {
- ++spcnt;
- if (i < gField[j])
- i = gField[j];
- if (++j > 3) {
- spcnt = 0;
- ++cmnt;
- }
- }
- }
- else if (ch == '\t') {
- gPrlnbuf[i - 1] = ' ';
- spcnt = 0;
- if (cmnt == 0) {
- if (i < gField[j])
- i = gField[j];
- if (++j > 3)
- ++cmnt;
- }
- else i = (i + 8) & 0x78;
- }
- else if ((ch == ';') && (string == 0)) {
- spcnt = 0;
- if (i == SFIELD + 1)
- ++cmnt;
- else if (gPrlnbuf[i - 2] != '\'') {
- ++cmnt;
- gPrlnbuf[i-1] = ' ';
- if (i <= gField[3])
- i = gField[3] + 1;
- gPrlnbuf[i++] = ';';
- }
- }
- else if (ch == EOF)
- return(-1);
- else {
- if ((ch == '"') && (cmnt == 0))
- string = string ^ 1;
- spcnt = 0;
- if (i >= LAST_CH_POS - 1)
- --i;
- }
- }
- gPrlnbuf[i] = 0;
- return(0);
- }
-
- /*
- * binputc() output a binary character to a binary file
- */
-
- int binputc (char ch, FILE * fileptr)
- {
- return fwrite(&ch, 1, 1, fileptr);
- }
-
- /*
- * wrapup() closes the source file
- */
-
- int wrapup(void)
- {
-
- if (gIptr != stdin)
- fclose(gIptr);
-
- if ((gPass == DONE) && (gOflag != 0) && (gInited > 0)) {
- fclose(gBinptr);
- }
- return 0;
- }
-
- /* symbol table print
- */
-
- int stprnt(void)
- {
- int i, j, k;
-
- // fputc('\014', stdout);
- fprintf(stdout, "\n\nSymbol Table\n\n");
- i = 0;
- while ((j = gSymtab[i++]) != 0) {
- for (k = j; k > 0; k--)
- fputc(gSymtab[i++], stdout);
- for (k = 20 - j; k > 0; k--)
- fputc(' ', stdout);
- ++i;
- j = (gSymtab[i++] & 0xff);
- j += (gSymtab[i++] << 8);
- hexcon(4, j);
- fprintf(stdout, "\t%c%c%c%c\n",
- gHex[1], gHex[2], gHex[3], gHex[4]);
- i += 2;
- }
-
- fprintf(stdout, "\nUsed %d bytes of symbol table space out of %d.\n", gNxt_free, STABSZ);
- return 0;
- }
-
- /* translate source line to machine language */
-
- int assemble(void)
- {
- int flg;
- int i; /* prlnbuf pointer */
-
- if ((gPrlnbuf[SFIELD] == ';') | (gPrlnbuf[SFIELD] == 0)) {
- if (gPass == LAST_PASS)
- println();
- return 0;
- }
- gLablptr = -1;
- i = SFIELD;
- gUdtype = UNDEF;
- if (colsym(&i) != 0 && (gLablptr = stlook()) == -1)
- return 0;
- while (gPrlnbuf[++i] == ' ')
- ; /* find first non-space */
- if ((flg = oplook(&i)) < 0) { /* collect operation code */
- labldef(gLoccnt);
- if (flg == -1)
- error("Invalid operation code");
- if ((flg == -2) && (gPass == LAST_PASS)) {
- if (gLablptr != -1)
- loadlc(gLoccnt, 1, 0);
- println();
- }
- return 0;
- }
- if (gOpflg == PSEUDO)
- pseudo(&i);
- else if (labldef(gLoccnt) == -1)
- return 0;
- else {
- if (gOpflg == CLASS1)
- class1();
- else if (gOpflg == CLASS2)
- class2(&i);
- else class3(&i);
- }
- return 0;
- }
-
- /****************************************************************************/
-
- /* printline prints the contents of prlnbuf */
-
- int println(void)
- {
- if (gLflag > 0)
- fprintf(stdout, "%s\n", gPrlnbuf);
-
- return 0;
- }
-
- /* colsym() collects a symbol from prlnbuf into gSymbol0[],
- * leaves prlnbuf pointer at first invalid symbol character,
- * returns 0 if no symbol collected
- */
-
- int colsym(int * ip)
- {
- int valid;
- int i;
- char ch;
-
- valid = 1;
- i = 0;
- while (valid == 1) {
- ch = gPrlnbuf[*ip];
- if (ch == '_' || ch == '.')
- ;
- else if (ch >= 'a' && ch <= 'z')
- ;
- else if (ch >= 'A' && ch <= 'Z')
- ;
- else if (i >= 1 && ch >= '0' && ch <= '9')
- ;
- else if (i == 1 && ch == '=')
- ;
- else valid = 0;
- if (valid == 1) {
- if (i < SBOLSZ - 1)
- gSymbol0[++i] = ch;
- (*ip)++;
- }
- }
- if (i == 1) {
- switch (gSymbol0[1]) {
- case 'A': case 'a':
- case 'X': case 'x':
- case 'Y': case 'y':
- error("Symbol is reserved (A, X or Y)");
- i = 0;
- }
- }
- gSymbol0[0] = i;
- return(i);
- }
-
- /* symbol table lookup
- * if found, return pointer to symbol
- * else, install symbol as undefined, and return pointer
- */
-
- int stlook(void)
- {
- int found;
- int hptr;
- int j;
- int nptr;
- int pptr;
- int ptr;
-
- hptr = 0;
- for (j = 0; j < gSymbol0[0]; j++)
- hptr += gSymbol0[j];
- hptr %= kHASH_SIZE;
- ptr = gHash_tbl[hptr];
- if (ptr == -1) { /* no entry for this link */
- gHash_tbl[hptr] = gNxt_free;
- return(stinstal());
- }
- while (gSymtab[ptr] != 0) { /* 0 count = end of table */
- found = 1;
- for (j = 0; j <= gSymbol0[0]; j++) {
- if (gSymbol0[j] != gSymtab[ptr + j]) {
- found = 0;
- pptr = ptr + gSymtab[ptr] + 4;
- nptr = (gSymtab[pptr + 1] << 8) + (gSymtab[pptr] & 0xff);
- nptr &= 0xffff;
- if (nptr == 0) {
- gSymtab[ptr + gSymtab[ptr] + 4] = gNxt_free & 0xff;
- gSymtab[ptr + gSymtab[ptr] + 5] = (gNxt_free >> 8) & 0xff;
- return(stinstal());
- }
- ptr = nptr;
- break;
- }
- }
- if (found == 1)
- return(ptr);
- }
- error("Symbol not found");
- return(-1);
- }
-
- /* install symbol into gSymtab
- */
- int stinstal(void)
- {
- register int j;
- register int ptr1;
- register int ptr2;
-
- ptr1 = ptr2 = gNxt_free;
- if ((ptr1 + gSymbol0[0] + 6) >= STABSZ) {
- error("Symbol table full");
- return(-1);
- }
- for (j = 0; j <= gSymbol0[0]; j++)
- gSymtab[ptr1++] = gSymbol0[j];
- gSymtab[ptr1] = gUdtype;
- gNxt_free = ptr1 + 5;
- return(ptr2);
- }
-
- /* operation code table lookup
- * if found, return pointer to symbol,
- * else, return -1
- */
-
- int oplook(int *ip)
- {
- register char ch;
- register int i;
- register int j;
- int k;
- int temp[2];
-
- i = j = 0;
- temp[0] = temp[1] = 0;
- while((ch=gPrlnbuf[*ip])!= ' ' && ch!= 0 && ch!= '\t' && ch!= ';') {
- if (ch >= 'A' && ch <= 'Z')
- ch &= 0x1f;
- else if (ch >= 'a' && ch <= 'z')
- ch &= 0x1f;
- else if (ch == '.')
- ch = 31;
- else if (ch == '*')
- ch = 30;
- else if (ch == '=')
- ch = 29;
- else return(-1);
- temp[j] = (temp[j] * 0x20) + (ch & 0xff);
- if (ch == 29)
- break;
- ++(*ip);
- if (++i >= 3) {
- i = 0;
- if (++j >= 2) {
- return(-1);
- }
- }
- }
- if ((j = temp[0]^temp[1]) == 0)
- return(-2);
- k = 0;
- i = gStep[k] - 3;
- do {
- if (j == gOptab[i]) {
- gOpflg = gOptab[++i];
- gOpval= gOptab[++i];
- return(i);
- }
- else if (j < gOptab[i])
- i -= gStep[++k];
- else i += gStep[++k];
- } while (gStep[k] != 0);
- return(-1);
- }
-
-
- /* error printing routine */
-
- int error(char* stptr)
- {
- loadlc(gLoccnt, 0, 1);
- gLoccnt += 3;
- loadv(0,0,0);
- loadv(0,1,0);
- loadv(0,2,0);
- fprintf(stderr, "%s\n", gPrlnbuf);
- fprintf(stderr, "%s\n", stptr);
- gErrcnt++;
-
- return 0;
- }
-
- /* load 16 bit value in printable form into prlnbuf */
-
- int loadlc(int val, int f, int outflg)
- {
- static int first_write=1; /* first write to output file */
- int i;
-
- i = 7 + 7*f;
- hexcon(4, val);
-
- gPrlnbuf[i++] = gHex[1];
- gPrlnbuf[i++] = gHex[2];
- gPrlnbuf[i++] = gHex[3];
- gPrlnbuf[i] = gHex[4];
-
- if ((gPass == LAST_PASS) && (gOflag != 0) && (outflg != 0)) {
- if (first_write) {
- gFile_loc = gLoccnt;
- first_write = 0;
- }
- if (gFile_loc > gLoccnt) {
-
- /* can't call error from here, error calls us */
-
- fprintf(stderr, "%s\n", gPrlnbuf);
- fprintf(stderr, "Can't relocate backwards.\n");
- gErrcnt++;
- return 0;
- }
- while (gFile_loc < gLoccnt) {
- binputc(0, gBinptr);
- ++gFile_loc;
- }
- }
- return 0;
- }
-
- /* load value in hex into prlnbuf[contents[i]] */
- /* and output hex characters to obuf if LAST_PASS & oflag == 1 */
-
- int loadv(int val, int f, int outflg)
- {
-
- hexcon(2, val);
- gPrlnbuf[13 + 3*f] = gHex[1];
- gPrlnbuf[14 + 3*f] = gHex[2];
- if ((gPass == LAST_PASS) && (gOflag != 0) && (outflg != 0)) {
- binputc(val, gBinptr);
- ++gFile_loc;
- }
- return 0;
- }
-
- /* convert number supplied as argument to hexadecimal in hex[digit] (lsd)
- through hex[1] (msd) */
-
- int hexcon(int digit, int num)
- {
-
- for (; digit > 0; digit--) {
- gHex[digit] = (num & 0x0f) + '0';
- if (gHex[digit] > '9')
- gHex[digit] += 'A' -'9' - 1;
- num >>= 4;
- }
- return 0;
- }
-
- /* assign <value> to label pointed to by gLablptr,
- * checking for valid definition, etc.
- */
-
- int labldef(int lval)
- {
- int i;
-
- if (gLablptr != -1) {
- gLablptr += gSymtab[gLablptr] + 1;
- if (gPass == FIRST_PASS) {
- if (gSymtab[gLablptr] == UNDEF) {
- gSymtab[gLablptr + 1] = lval & 0xff;
- i = gSymtab[gLablptr + 2] = (lval >> 8) & 0xff;
- if (i == 0)
- gSymtab[gLablptr] = DEFZRO;
- else gSymtab[gLablptr] = DEFABS;
- }
- else if (gSymtab[gLablptr] == UNDEFAB) {
- gSymtab[gLablptr] = DEFABS;
- gSymtab[gLablptr + 1] = lval & 0xff;
- gSymtab[gLablptr + 2] = (lval >> 8) & 0xff;
- }
- else {
- gSymtab[gLablptr] = MDEF;
- gSymtab[gLablptr + 1] = 0;
- gSymtab[gLablptr + 2] = 0;
- error("Label multiply defined");
- return(-1);
- }
- }
- else {
- i = (gSymtab[gLablptr + 2] << 8) +
- (gSymtab[gLablptr+1] & 0xff);
- i &= 0xffff;
- if (i != lval && gPass == LAST_PASS) {
- error("Sync error");
- return(-1);
- }
- }
- }
- return(0);
- }
-
- /* determine the value of the symbol,
- * given pointer to first character of symbol in gSymtab
- */
-
- int symval(int* ip)
- {
- int ptr;
- int svalue;
-
- svalue = 0;
- colsym(ip);
- if ((ptr = stlook()) == -1)
- gUndef = 1; /* no room error */
- else if (gSymtab[ptr + gSymtab[ptr] + 1] == UNDEF)
- gUndef = 1;
- else if (gSymtab[ptr + gSymtab[ptr] + 1] == UNDEFAB)
- gUndef = 1;
- else svalue = ((gSymtab[ptr + gSymtab[ptr] + 3] << 8) +
- (gSymtab[ptr + gSymtab[ptr] + 2] & 0xff)) & 0xffff;
- if (gSymtab[ptr + gSymtab[ptr] + 1] == DEFABS)
- gZpref = 1;
- if (gUndef != 0)
- gZpref = 1;
- return(svalue);
- }
-
-
- /* class 1 machine operations processor - 1 byte, no operand field */
-
- int class1(void)
- {
- if (gPass == LAST_PASS) {
- loadlc(gLoccnt, 0, 1);
- loadv(gOpval, 0, 1);
- println();
- }
- gLoccnt++;
- return 0;
- }
-
-
- /* class 2 machine operations processor - 2 byte, relative addressing */
-
- int class2(int* ip)
- {
-
- if (gPass == LAST_PASS) {
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- if (evaluate(ip) != 0) {
- gLoccnt += 2;
- return 0;
- }
- loadlc(gLoccnt, 0, 1);
- loadv(gOpval, 0, 1);
- gLoccnt += 2;
- if ((gValue -= gLoccnt) >= -128 && gValue < 128) {
- loadv(gValue, 1, 1);
- println();
- }
- else error("Invalid branch address");
- }
- else gLoccnt += 2;
-
- return 0;
- }
-
-
- /* class 3 machine operations processor - various addressing modes */
-
- int class3(int* ip)
- {
- char ch;
- int code;
- int flag;
- int i;
- int ztmask;
-
- while ((ch = gPrlnbuf[++(*ip)]) == ' ')
- ;
- switch(ch) {
- case 0:
- case ';':
- error("Operand field missing");
- return 0;
- case 'A':
- case 'a':
- if ((ch = gPrlnbuf[*ip + 1]) == ' ' || ch == 0) {
- flag = ACC;
- break;
- }
- default:
- switch(ch = gPrlnbuf[*ip]) {
- case '#': case '=':
- flag = IMM1 | IMM2 | IMM3;
- ++(*ip);
- break;
- case '(':
- flag = IND | INDX | INDY;
- ++(*ip);
- break;
- default:
- flag = ABS | ZER | ZERX | ABSX | ABSY | ABSY2 | ZERY;
- }
- if ((flag & (INDX | INDY | ZER | ZERX | ZERY) & gOpflg) != 0)
- gUdtype = UNDEFAB;
- if (evaluate(ip) != 0)
- return 0;
- if (gZpref != 0) {
- flag &= (ABS | ABSX | ABSY | ABSY2 | IND | IMM1 | IMM2 | IMM3);
- ztmask = 0;
- }
- else ztmask = ZER | ZERX | ZERY;
- code = 0;
- i = 0;
- while (( ch = gPrlnbuf[(*ip)++]) != ' ' && ch != 0 && i++ < 4) {
- code *= 8;
- switch(ch) {
- case ')': /* ) = 4 */
- ++code;
- case ',': /* , = 3 */
- ++code;
- case 'X': /* X = 2 */
- case 'x':
- ++code;
- case 'Y': /* Y = 1 */
- case 'y':
- ++code;
- break;
- default:
- flag = 0;
- }
- }
- switch(code) {
- case 0: /* no termination characters */
- flag &= (ABS | ZER | IMM1 | IMM2 | IMM3);
- break;
- case 4: /* termination = ) */
- flag &= IND;
- break;
- case 25: /* termination = ,Y */
- flag &= (ABSY | ABSY2 | ZERY);
- break;
- case 26: /* termination = ,X */
- flag &= (ABSX | ZERX);
- break;
- case 212: /* termination = ,X) */
- flag &= INDX;
- break;
- case 281: /* termination = ),Y */
- flag &= INDY;
- break;
- default:
- flag = 0;
- }
- }
- if ((gOpflg &= flag) == 0) {
- error("Invalid addressing mode");
- return 0;
- }
- if ((gOpflg & ztmask) != 0)
- gOpflg &= ztmask;
- switch(gOpflg) {
- case ACC: /* single byte - class 3 */
- if (gPass == LAST_PASS) {
- loadlc(gLoccnt, 0, 1);
- loadv(gOpval + 8, 0, 1);
- println();
- }
- gLoccnt++;
- return 0;
-
- case IMM3: /* double byte - class 3 */
- gOpval += 108;
-
- case ZERX: case ZERY:
- gOpval += 4;
- case INDY:
- gOpval += 8;
- case IMM2:
- gOpval += 4;
- case ZER:
- gOpval += 4;
- case INDX: case IMM1:
- if (gPass == LAST_PASS) {
- loadlc(gLoccnt, 0, 1);
- loadv(gOpval, 0, 1);
- loadv(gValue, 1, 1);
- println();
- }
- gLoccnt += 2;
- return 0;
- case IND: /* triple byte - class 3 */
- gOpval += 16;
- case ABSX:
- case ABSY2:
- gOpval += 4;
- case ABSY:
- gOpval += 12;
- case ABS:
- if (gPass == LAST_PASS) {
- gOpval += 12;
- loadlc(gLoccnt, 0, 1);
- loadv(gOpval, 0, 1);
- loadv(gValue, 1, 1);
- loadv(gValue >> 8, 2, 1);
- println();
- }
- gLoccnt += 3;
- return 0;
- default:
- error("Invalid addressing mode");
- return 0;
- }
- }
-
- /* pseudo operations processor */
-
- int pseudo(int* ip)
- {
- int count;
- int i;
- int tvalue, index;
- FILE* saveFile;
- int saveLine;
- char tempstr[FILENAME_MAX];
-
- switch(gOpval) {
- case 0: /* .byte pseudo */
- labldef(gLoccnt);
- loadlc(gLoccnt, 0, 1);
- while (gPrlnbuf[++(*ip)] == ' ')
- ; /* field */
- count = 0;
- do {
- if (gPrlnbuf[*ip] == '"') {
- while ((tvalue = gPrlnbuf[++(*ip)]) != '"') {
- if (tvalue == 0) {
- error("Unterminated ASCII string");
- return 0;
- }
- if (tvalue == '\\')
- switch(tvalue = gPrlnbuf[++(*ip)]) {
- case 'n':
- tvalue = EOL;
- break;
- case 't':
- tvalue = '\t';
- break;
- }
- gLoccnt++;
- if (gPass == LAST_PASS) {
- loadv(tvalue, count, 1);
- if (++count >= 3) {
- println();
- for (i = 0; i < SFIELD; i++)
- gPrlnbuf[i] = ' ';
- gPrlnbuf[i] = 0;
- count = 0;
- loadlc(gLoccnt, 0, 1);
- }
- }
- }
- ++(*ip);
- }
- else {
- if (evaluate(ip) != 0) {
- gLoccnt++;
- return 0;
- }
- gLoccnt++;
- if (gValue > 0xff) {
- error("Operand field size error");
- return 0;
- }
- else if (gPass == LAST_PASS) {
- loadv(gValue, count, 1);
- if (++count >= 3) {
- println();
- for (i = 0; i < SFIELD; i++)
- gPrlnbuf[i] = ' ';
- gPrlnbuf[i] = 0;
- count = 0;
- loadlc(gLoccnt, 0, 1);
- }
- }
- }
- } while (gPrlnbuf[(*ip)++] == ',');
- if ((gPass == LAST_PASS) && (count != 0))
- println();
- return 0;
- case 1: /* = pseudo */
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- if (evaluate(ip) != 0)
- return 0;
- labldef(gValue);
- if (gPass == LAST_PASS) {
- loadlc(gValue, 1, 0);
- println();
- }
- return 0;
- case 2: /* .word pseudo */
- labldef(gLoccnt);
- loadlc(gLoccnt, 0, 1);
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- do {
- if (evaluate(ip) != 0) {
- gLoccnt += 2;
- return 0;
- }
- gLoccnt += 2;
- if (gPass == LAST_PASS) {
- loadv(gValue, 0, 1);
- loadv(gValue>>8, 1, 1);
- println();
- for (i = 0; i < SFIELD; i++)
- gPrlnbuf[i] = ' ';
- gPrlnbuf[i] = 0;
- loadlc(gLoccnt, 0, 1);
- }
- } while (gPrlnbuf[(*ip)++] == ',');
- return 0;
- case 3: /* *= pseudo */
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- if (gPrlnbuf[*ip] == '*') {
- if (evaluate(ip) != 0)
- return 0;
- if (gUndef != 0) {
- error("Undefined symbol in operand field.");
- return 0;
- }
- tvalue = gLoccnt;
- }
- else {
- if (evaluate(ip) != 0)
- return 0;
- if (gUndef != 0) {
- error("Undefined symbol in operand field.");
- return 0;
- }
- tvalue = gValue;
- }
- gLoccnt = gValue;
- labldef(tvalue);
- if (gPass == LAST_PASS) {
- loadlc(tvalue, 1, 0);
- println();
- }
- return 0;
- case 4: /* .list pseudo */
- if (gLflag >= 0)
- gLflag = 1;
- return 0;
- case 5: /* .nlst pseudo */
- if (gLflag >= 0)
- gLflag = gIflag;
- return 0;
- case 6: /* .dbyt pseudo */
- labldef(gLoccnt);
- loadlc(gLoccnt, 0, 1);
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- do {
- if (evaluate(ip) != 0) {
- gLoccnt += 2;
- return 0;
- }
- gLoccnt += 2;
- if (gPass == LAST_PASS) {
- loadv(gValue>>8, 0, 1);
- loadv(gValue, 1, 1);
- println();
- for (i = 0; i < SFIELD; i++)
- gPrlnbuf[i] = ' ';
- gPrlnbuf[i] = 0;
- loadlc(gLoccnt, 0, 1);
- }
- } while (gPrlnbuf[(*ip)++] == ',');
- return 0;
-
- case 7: /* .incl pseudo */
- while (gPrlnbuf[++(*ip)] == ' ')
- ;
- if (gPrlnbuf[*ip] == '"') {
- index = 0;
-
- while ((tvalue = gPrlnbuf[++(*ip)]) != '"') {
- if (tvalue == 0) {
- error("Unterminated ASCII string");
- return 0;
- }
- if (tvalue == '\\') {
- switch(tvalue = gPrlnbuf[++(*ip)]) {
- case 'n':
- tvalue = EOL;
- break;
- case 't':
- tvalue = '\t';
- break;
- }
- }
- tempstr[index++] = tvalue;
- }
- ++(*ip);
- tempstr[index++] = 0x00;
- if (gPass == LAST_PASS)
- println();
-
- saveFile = gIptr;
- saveLine = gSlnum;
-
- gSlnum = 0;
- initialize(tempstr);
- while (readline() != -1)
- assemble();
- wrapup();
-
- gSlnum = saveLine;
- gIptr = saveFile;
-
- }
- else {
- error("Unspecified include file");
- }
- return 0;
- }
- return 0;
- }
-
- /* evaluate expression */
-
- int evaluate(int* ip)
- {
- int tvalue;
- int invalid;
- int parflg, value2;
- char ch;
- char op;
- char op2;
-
- op = '+';
- parflg = gZpref = gUndef = gValue = invalid = 0;
- /* hcj: gZpref should reflect the value of the expression, not the value of
- the intermediate symbols
- */
- while ((ch=gPrlnbuf[*ip]) != ' ' && ch != ')' && ch != ',' && ch != ';') {
- tvalue = 0;
- if (ch == '$' || ch == '@' || ch == '%')
- tvalue = colnum(ip);
- else if (ch >= '0' && ch <= '9')
- tvalue = colnum(ip);
- else if (ch >= 'a' && ch <= 'z')
- tvalue = symval(ip);
- else if (ch >= 'A' && ch <= 'Z')
- tvalue = symval(ip);
- else if ((ch == '_') /* || (ch == '.') */)
- tvalue = symval(ip);
- else if ((ch == '*') || (ch == '.')) {
- tvalue = gLoccnt;
- ++(*ip);
- }
- else if (ch == '\'') {
- ++(*ip);
- tvalue = gPrlnbuf[*ip] & 0xff;
- ++(*ip);
- }
- else if (ch == '[') {
- if (parflg == 1) {
- error("Too many ['s in expression");
- invalid++;
- }
- else {
- value2 = gValue;
- op2 = op;
- gValue = tvalue = 0;
- op = '+';
- parflg = 1;
- }
- goto next;
- }
- else if (ch == ']') {
- if (parflg == 0) {
- error("No matching [ for ] in expression");
- invalid++;
- }
- else {
- parflg = 0;
- tvalue = gValue;
- gValue = value2;
- op = op2;
- }
- ++(*ip);
- }
- switch(op) {
- case '+':
- gValue += tvalue;
- break;
- case '-':
- gValue -= tvalue;
- break;
- case '/':
- gValue = (unsigned) gValue/tvalue;
- break;
- case '*':
- gValue *= tvalue;
- break;
- case '%':
- gValue = (unsigned) gValue%tvalue;
- break;
- case '^':
- gValue ^= tvalue;
- break;
- case '~':
- gValue = ~tvalue;
- break;
- case '&':
- gValue &= tvalue;
- break;
- case '|':
- gValue |= tvalue;
- break;
- case '>':
- tvalue >>= 8; /* fall through to '<' */
- case '<':
- if (gValue != 0) {
- error("High or low byte operator not first in operand field");
- }
- gValue = tvalue & 0xff;
- gZpref = 0;
- break;
- default:
- invalid++;
- }
- if ((op=gPrlnbuf[*ip]) == ' '
- || op == ')'
- || op == ','
- || op == ';')
- break;
- else if (op != ']')
- next: ++(*ip);
- }
- if (parflg == 1) {
- error("Missing ] in expression");
- return(1);
- }
- if (gValue < 0 || gValue >= 256) {
- gZpref = 1;
- }
- if (gUndef != 0) {
- if (gPass != FIRST_PASS) {
- error("Undefined symbol in operand field");
- invalid++;
- }
- gValue = 0;
- }
- else if (invalid != 0)
- {
- error("Invalid operand field");
- }
- else {
- /*
- This is the only way out that may not signal error
- */
- if (gValue < 0 || gValue >= 256) {
- gZpref = 1;
- }
- else {
- gZpref = 0;
- }
- }
- return(invalid);
- }
-
- /* collect number operand */
-
- int colnum(int* ip)
- {
- int mul;
- int nval;
- char ch;
-
- nval = 0;
- if ((ch = gPrlnbuf[*ip]) == '$')
- mul = 16;
- else if (ch >= '1' && ch <= '9') {
- mul = 10;
- nval = ch - '0';
- }
- else if (ch == '@' || ch == '0')
- mul = 8;
- else if (ch == '%')
- mul = 2;
- while ((ch = gPrlnbuf[++(*ip)] - '0') >= 0) {
- if (ch > 9) {
- ch -= ('A' - '9' - 1);
- if (ch > 15)
- ch -= ('a' - 'A');
- if (ch > 15)
- break;
- if (ch < 10)
- break;
- }
- if (ch >= mul)
- break;
- nval = (nval * mul) + ch;
- }
- return(nval);
- }
-
- /* parse the arguments */
-
- void parseArgs( int argc, char *argv[])
- {
- int filecount = 0;
- int argindex, opIndex, len, found;
- char tempstr[FILENAME_MAX];
-
- for (argindex = 1; argindex < argc; argindex++) {
-
- strcpy(tempstr, argv[argindex]);
- for (len = 0; tempstr[len]; len--)
- tempstr[len] = tolower(tempstr[len]);
-
- found = 0;
- for (opIndex = 0; opIndex < kNumOptions; opIndex++) {
- if (strcmp(gOptions[opIndex].option, tempstr) == 0) {
- (*(gOptions[opIndex].fun))(gOptions[opIndex].variable);
- found = 1;
- break;
- }
- }
- if (!found) {
- gFiles[filecount++] = argv[argindex];
- }
- }
- gLastInputFile = filecount;
- }
-
- /* set a compile option to on */
- void DefaultOption(int* var)
- {
- *var = 1;
- }
-
- /* set a compile option to off */
- void NoOutputOption(int* var)
- {
- *var = 0;
- }
-
- /* Display version */
- void VersionOption(int* var)
- {
- *var = 1;
-
- if (gPass == FIRST_PASS) {
- fprintf(stdout, "\nas6502 - %s %s\n", __DATE__, __TIME__);
- }
-
- }
-
- /* Display FileName */
- void ListingOption(int* var)
- {
- *var = 1;
- if (gPass == LAST_PASS) {
- fprintf(stdout, "\n\t%s\n\n", gFiles[gNextInputFile]);
- }
- }
-
-
- #define PRINTOPVAL(n,x) if (((n) & ##x) == ##x) { printf(#x " "); op &= ~##x; }
-
- void PrintOpTable(int* val)
- {
- int* curOp = gOptab, op, temp;
- char curbyte, outbyte[10], count, x;
- *val = 1;
- if (gPass == FIRST_PASS) {
- do {
- op = *curOp++;
- temp = op;
- count = 0;
- do {
- curbyte = temp % 0x20;
- if (curbyte <= 26) {
- outbyte[count] = curbyte + ('A' -1);
- }
- else {
- switch (curbyte) {
- case 0x1d:
- outbyte[count] = '=';
- break;
-
- case 0x1e:
- outbyte[count] = '*';
- break;
-
- case 0x1f:
- default:
- outbyte[count] = '.';
- break;
- }
- }
- count++;
- temp /= 0x20;
- } while (temp);
- outbyte[count] = 0;
- count--;
- for (temp = 0; temp < (count >> 1) + 1; temp++) {
- x = outbyte[temp];
- outbyte[temp] = outbyte[count - temp];
- outbyte[count - temp] = x;
- }
- if (outbyte[0] == '.') {
- printf(".????");
- }
- else {
- printf("%5.5s",outbyte);
- }
- printf(" 0x%-4.4x ", op);
-
- op = *curOp++;
- PRINTOPVAL(op,PSEUDO);
- PRINTOPVAL(op,CLASS1);
- PRINTOPVAL(op,CLASS2);
- PRINTOPVAL(op,IMM3);
- PRINTOPVAL(op,IMM1);
- PRINTOPVAL(op,IMM2);
- PRINTOPVAL(op,ABS);
- PRINTOPVAL(op,ZER);
- PRINTOPVAL(op,INDX);
- PRINTOPVAL(op,ABSY2);
- PRINTOPVAL(op,INDY);
- PRINTOPVAL(op,ZERX);
- PRINTOPVAL(op,ABSX);
- PRINTOPVAL(op,ABSY);
- PRINTOPVAL(op,ACC);
- PRINTOPVAL(op,IND);
- PRINTOPVAL(op,ZERY);
-
- op = *curOp++;
- printf("0x%-2.2x\n", op);
-
- } while (*curOp != 0x7fff);
- }
- }
-
- void FixUpAPP(void)
- {
- FSSpec myFSSpec;
- OSErr err;
- FInfo fndrInfo;
- SInt16 refNum;
- SInt32 curEOF;
- Handle myHandle, codeZero;
-
- err = FSMakeFSSpec(0,0,"\p6502.bin",&myFSSpec);
- if (err) return;
-
- err = FSpGetFInfo(&myFSSpec,&fndrInfo);
- fndrInfo.fdType = 'APPL';
- err = FSpSetFInfo(&myFSSpec,&fndrInfo);
-
- err = FSpOpenDF(&myFSSpec,fsRdWrPerm,&refNum);
- err = GetEOF(refNum,&curEOF);
- myHandle = NewHandle(curEOF);
-
- err = FSRead(refNum, &curEOF, *myHandle);
- FSClose(refNum);
-
- codeZero = GetResource('COde', 0);
- DetachResource(codeZero);
-
- HCreateResFile(myFSSpec.vRefNum, myFSSpec.parID, myFSSpec.name);
- refNum = HOpenResFile(myFSSpec.vRefNum, myFSSpec.parID, myFSSpec.name, fsRdWrPerm);
- err = ResError();
-
- if (!err) {
- UseResFile(refNum);
- AddResource(myHandle, 'CODE', 1, "\p");
- ChangedResource(myHandle);
- WriteResource(myHandle);
-
- AddResource(codeZero, 'CODE', 0, "\p");
- ChangedResource(codeZero);
- WriteResource(codeZero);
-
- CloseResFile(refNum);
- }
-
- }