home *** CD-ROM | disk | FTP | other *** search
- /* ╧BJECT ╞ILE ╥EVERSE ┴SSEMBLER
- * ┴UTHOR: ═ARK ╥. ╥INFRET
- * ─ATE: 05/13/85
- * ╞ILENAME: RA1.C
- * ╚ISTORY:
- *
- * 11/02/85 - ╧UTPUT .DEF, .REF
- *
- * 04/13/86 - ╞IXED XDEF LIST LINKING PROBLEM, ADDED 'STANDARD' SYMBOL
- * DEFINITIONS.
- *
- * 04/15/86 - ╔NHIBIT MULTIPLE .REF'S TO SAME SYMBOL
- */
- #INCLUDE "RA.H"
-
- /* EXTERNAL DATA */
- EXTERN STRUCT LABEL *XDEFHD,*XDEFTL; /* HD,TL OF XDEF LABEL LIST */
- EXTERN STRUCT LABEL *XREFHD,*XREFTL; /* HD AND TL POINTERS FOR XREF LIST */
- EXTERN ╞╔╠┼ LST; /* LISTING FILE */
- EXTERN ╞╔╠┼ OBJ; /* OBJECT FILE */
- EXTERN UNSIGNED BIAS,CODESZ,RELSZ,XREFSZ,DATASZ;
- EXTERN CHAR *CODEBUF; /* CODE BUFFER */
- EXTERN UNSIGNED PROMPT; /* INTERACTIVE MODE FLAG */
- EXTERN UNSIGNED *RELBUF; /* RELOCATION DATA */
-
- /* GLOBAL DATA */
- STRUCT LABEL *NEWLBL; /* NEW LABEL POINTER */
-
- /****************/
- MAIN (ARGC, ARGV)
- UNSIGNED ARGC;
- CHAR **ARGV;
- █
-
- LST = STDOUT; /* DEFAULT IS STANDARD OUTPUT */
- BIAS = 0X1800; /* STARTING ADDRESS FOR SHELL PROGRAMS */
- PROMPT = 0; /* NON-INTERACTIVE MODE */
-
- WHILE (ARGC>2) █
- IF (!STRCMP(*++ARGV,"-L")) █ /* LISTING OPTION */
- IF ((LST=OPENFILE(*++ARGV,"W"))==╬╒╠╠ ▀▀ FERROR()) █
- PRINTF("CAN'T OPEN LISTING FILE, %S\N",*ARGV);
- EXIT();
- ▌
- ARGC -= 2;
- ▌
- ELSE IF (!STRCMP(*ARGV,"-P")) █ /* INTERACTIVE OPTION */
- PROMPT = 1;
- ARGC--;
- ▌
- ELSE IF (!STRCMP(*ARGV,"-A")) █ /* CHANGE BIAS */
- SSCANF(*++ARGV,"%X",&BIAS);
- ARGC -= 2;
- ▌
- ELSE █
- PRINTF("--BAD OPTION: %S\N",*ARGV);
- EXIT();
- ▌
- ▌ /* END WHILE */
-
- IF (ARGC<2) USAGE();
-
- IF ((OBJ = OPENFILE(*++ARGV, "R")) == ╬╒╠╠ ▀▀ FERROR()) █
- PRINTF ("CAN'T OPEN OBJECT FILE, %S\N", *ARGV);
- ▌
- ELSE █
- REVERSE ();
- FCLOSE (OBJ);
- ▌
- ▌
-
- /*
- * ─ISPLAY CORRECT PROGRAM USAGE.
- *
- */
- USAGE()
- █
- PRINTF("USAGE: RA [OPTIONS] OBJECT FILE\N");
- PRINTF("OPTIONS:\N");
- PRINTF(" -P ENABLE FORMAT PROMPTING\N");
- PRINTF(" -L LISTFILE (OUTPUT TO LISTFILE)\N");
- PRINTF(" -A ADDRESS (ALIGN AT HEX ADDRESS)\N");
- EXIT();
- ▌
-
- REVERSE()
- █
- XDEFHD = ╬╒╠╠;
- XDEFTL = ╬╒╠╠;
- XREFHD = ╬╒╠╠;
- XREFTL = ╬╒╠╠;
- GETCODE(); /* INPUT CODE SEGMENT */
- GETREL(); /* GET RELOCATION DATA */
- DEFSTD(); /* DEFINE 'STANDARD' SYMBOLS */
- GETXDEF(); /* GET EXTERNAL ID'S */
- GETXREF(); /* GET EXTERNAL REF'S */
- RVRS(); /* DO REVERSE ASSEMBLY */
- ▌
-
- /* ╔NPUT CODE SEGMENT */
- GETCODE()
- █
- CHAR *MALLOC();
-
- CODESZ = GETW(OBJ);
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"├ODE ╙IZE: %5D(─) / %X(╪)\N",CODESZ,CODESZ);
- #ENDIF
- CODEBUF = MALLOC(CODESZ);
- FREAD(CODEBUF,1,CODESZ,OBJ);
- ▌
-
- /*
- * ╔NPUT RELOCATION INFORMATION AND PERFORM RELOCATION.
- *
- */
-
- GETREL()
- █
- CHAR *MALLOC();
- CHAR *CP; /* TEMP CODE POINTER */
- UNSIGNED AD,CNT1,CNT2;
- UNSIGNED *RP;
-
- RELSZ = GETW(OBJ);
- RELBUF = (INT *) MALLOC(RELSZ*2);
- FREAD(RELBUF,2,RELSZ,OBJ);
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"%D RELOCATION ENTRIES\N",RELSZ);
- CNT1 = RELSZ;
- CNT2 = 0;
- RP = RELBUF;
- WHILE (CNT1--) █
- FPRINTF(LST,"%04X ",*RP++);
- IF (++CNT2 == 8) █
- FPUTC('\N',LST);
- CNT2=0;
- ▌
- ▌
- FPRINTF(LST,"\N;--------------------\N");
- #ENDIF
-
- /* ╥ELOCATE THE CODE ACCORDING TO 'BIAS' */
- RP = RELBUF;
- CNT1 = RELSZ;
- WHILE (CNT1--) █
- /*
- * ├OMPUTE POINTER INTO CODE BUFFER. ╔T IS IMPORTANT TO NOTE THAT THE
- * RELOCATION ENTRY ALWAYS ASSUMES THAT AN OPCODE IS PRESENT (3 BYTE CODE
- * ENTRY). ╘HUS, RELOCATION ENTRIES WHICH MODIFY CHARACTER STRING POINTERS
- * APPEAR TO BE ONE LESS THAN THEY SHOULD BE.
- *
- */
- CP = CODEBUF + *RP++ + 1;
- AD = *CP; /* GET LOW BYTE OF ADDRESS */
- AD = AD ▀ (*(CP+1) << 8); /* 'OR' WITH UPPER BYTE */
- AD = AD + BIAS; /* RELOCATE */
- *CP = AD; /* PUT BACK LOWER */
- *(CP+1) = (AD >> 8); /* PUT BACK UPPER */
- ▌
- ▌
-
- /* ─EFINE 'STANDARD' LABELS
- ╘HIS ROUTINE INPUTS THE CONTENTS OF THE FILE 'RA.SYMBOLS' AND ADDS
- THE DEFINITIONS FOUND THEREIN TO THE LIST OF GLOBAL SYMBOLS. ╨LEASE
- NOTE THAT THESE SYMBOLS ARE NOT EXTERNALIZED WITH .DEF STATEMENTS AS
- THE EXTERNAL SYMBOLS FROM THE OBJECT FILE ARE. ╘HE SYMBOL DEFINITIONS
- ARE OUTPUT TO THE DISASSEMBLY LISTING AS THEY ARE DEFINED.
- */
-
- DEFSTD()
- █
- ╞╔╠┼ SYMFILE;
- CHAR *MALLOC();
- REGISTER UNSIGNED I;
- STRUCT LABEL *NEWLBL;
- CHAR *P;
- UNSIGNED SYMLENG,OFFSET;
- CHAR C,LINE[81],SYM[═┴╪╔─+1];
-
- IF ((SYMFILE=FOPEN("RA.SYMBOLS","R"))==╬╒╠╠ ▀▀ FERROR()) █
- PRINTF("├AN'T LOAD SYMBOLS!\N");
- RETURN;
- ▌
-
- P = "C$$START"; /* SPECIAL FIRST SYMBOL */
- NEWLBL = (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL));
- NEWLBL->NEXT = ╬╒╠╠;
- NEWLBL->NAME = MALLOC(STRLEN(P)+1);
- STRCPY(NEWLBL->NAME,P);
- NEWLBL->OFFSET = BIAS;
- NEWLBL->FLAG = 1;
- NEWLBL->GLOBAL = 1;
-
- ADDSYM(NEWLBL);
-
- WHILE (FGETS(LINE,81,SYMFILE)) █
- IF (*LINE != ';') █
- P = LINE; /* COPY STRING POINTER */
- SYMLENG = 0;
- WHILE ((C = *P++) != ' ') █
- IF (SYMLENG < ═┴╪╔─) SYM[SYMLENG++] = C;
- ▌
- SYM[SYMLENG] = 0; /* NULL TERMINATOR */
- IF (SYMLENG) █
- NEWLBL = (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL));
- NEWLBL->NAME = MALLOC(++SYMLENG);
- STRCPY(NEWLBL->NAME,SYM);
- NEWLBL->OFFSET = GETADDR(P);
- NEWLBL->FLAG = ╬╒╠╠;
- NEWLBL->GLOBAL = ╬╒╠╠;
- NEWLBL->NEXT = ╬╒╠╠;
- ADDSYM(NEWLBL); /* ADD LOCAL SYMBOL DEF */
- FPRINTF(LST,"%-12S = $%04X\N",SYM,NEWLBL->OFFSET);
- ▌
- ELSE PRINTF("┬AD SYMBOL DEFINITION:\N%S",LINE);
- ▌
- ▌
- FCLOSE(SYMFILE);
- ▌
-
- /* ╔NPUT AN ADDRESS VALUE AS EITHER DECIMAL (DEFAULT) OR HEXADECIMAL IF
- PRECEDED BY '0X'. ╘HIS ROUTINE WAS ADDED BECAUSE IT APPEARS THAT SCANF
- DOES NOT PROPERLY HANDLE HEX VALUES. (?)
- */
-
- INT GETADDR(S)
- CHAR *S;
- █
- CHAR C;
- CHAR BASE = 10;
- UNSIGNED VALUE;
-
- WHILE ((C=*S++)==' ' ▀▀ C == '0');
- IF ((C == '\N') ▀▀ (C == 0)) RETURN -1;
- IF (C == 'X' ▀▀ C == '╪') BASE = 16;
- WHILE (ISALNUM((C=*S++))) █
- VALUE *= BASE;
- IF (C>='0' && C<='9') VALUE += (C-'0');
- ELSE █
- IF (BASE==10) RETURN -1;
- IF ((C>='A' && C<='F')) VALUE += (10 + C-'A');
- ELSE IF (C>='┴' && C<='╞') VALUE += (10 + C-'┴');
- ELSE RETURN -1;
- ▌
- ▌
- RETURN VALUE;
- ▌
-
- /* ╔NPUT EXTERNAL IDENTIFIERS */
-
- GETXDEF()
- █
- CHAR *MALLOC();
-
- UNSIGNED COUNT,I,OFST;
- CHAR ID[═┴╪╔─];
-
- COUNT = GETW(OBJ); /* GET COUNT OF ID'S */
-
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"%D EXTERNAL DEFINITIONS\N",COUNT);
- #ENDIF
-
- WHILE (COUNT--) █
- IF (!(NEWLBL = (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL)))) █
- FPRINTF(LST,"╧UT OF MEMORY!");
- ABORT();
- ▌
- GETID(ID,OBJ); /* INPUT IDENTIFIER */
- NEWLBL->NAME = MALLOC(STRLEN(ID)+1);
- STRCPY(NEWLBL->NAME,ID);
- NEWLBL->FLAG = GETC(OBJ);
- OFST = GETW(OBJ);
-
- /* RELOCATE SYMBOL TO START ADDRESS */
-
- IF (NEWLBL->FLAG) OFST += BIAS;
- NEWLBL->OFFSET = OFST;
- NEWLBL->GLOBAL = 1;
- NEWLBL->NEXT = ╬╒╠╠;
- ADDSYM(NEWLBL); /* ADD SYMBOL */
- ▌
- ▌
-
- /* ┴DD SYMBOL TO GLOBAL SYMBOL LIST
- ** ├ALLED WITH:
- ** ╙YMBOL DEFINITION
- */
- ADDSYM(LBL)
- STRUCT LABEL *LBL;
- █
- STRUCT LABEL *CUR,*PREV;
-
- IF (XDEFHD == ╬╒╠╠) █ /* FIRST ENTRY */
- XDEFHD = LBL;
- XDEFTL = LBL;
- ▌
- ELSE █
- IF (LBL->OFFSET < XDEFTL->OFFSET) █ /* ╧UT OF ORDER? */
- CUR = XDEFHD;
- PREV = XDEFHD; /* INSERT INTO LIST */
- WHILE (CUR) █
- IF (LBL->OFFSET < CUR-> OFFSET) █
- IF (CUR==XDEFHD) █ /* NEW FIRST ELEMENT? */
- LBL->NEXT = XDEFHD;
- XDEFHD = LBL;
- BREAK;
- ▌
- ELSE █
- PREV->NEXT = LBL;
- LBL->NEXT = CUR;
- BREAK;
- ▌
- ▌
- ELSE █
- PREV = CUR;
- CUR = CUR->NEXT;
- ▌
- ▌
- ▌
- ELSE █ /* ADD TO END OF LIST */
- XDEFTL->NEXT = LBL;
- XDEFTL = LBL;
- ▌
- ▌
- ▌
-
- /*
- * ╔NPUT EXTERNAL REFERENCES
- *
- */
-
- GETXREF()
- █
- STRUCT LABEL *MALLOC();
-
- UNSIGNED COUNT,PRINTIT;
- STRUCT LABEL *NEWXREF,*TESTREF;
- CHAR ID[═┴╪╔─];
-
- COUNT=GETW(OBJ); /* GET NUMBER OF XREFS */
-
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"%D EXTERNAL REFERENCES.\N\N",COUNT);
- #ENDIF
-
- WHILE (COUNT--) █
- GETID(ID,OBJ); /* INPUT IDENTIFIER */
- NEWXREF=MALLOC(SIZEOF(STRUCT LABEL));
- NEWXREF->NAME = MALLOC(STRLEN(ID));
- STRCPY(NEWXREF->NAME,ID);
- NEWXREF->NEXT = ╬╒╠╠;
- NEWXREF->FLAG = GETW(OBJ);
- NEWXREF->OFFSET = GETW(OBJ)+BIAS;
- NEWXREF->GLOBAL = 1;
-
- PRINTIT = 1; /* ASSUME .REF IS UNIQUE */
-
- IF (XREFHD==╬╒╠╠) █/* FIRST ENTRY */
- XREFHD = NEWXREF;
- XREFTL = NEWXREF;
- ▌
- ELSE █
- TESTREF = XREFHD;
- WHILE (TESTREF) █
- IF (!STRCMP(TESTREF->NAME,NEWXREF->NAME)) █
- PRINTIT = 0;
- BREAK;
- ▌
- TESTREF = TESTREF->NEXT;
- ▌
- XREFTL->NEXT = NEWXREF;
- XREFTL = NEWXREF;
- ▌
- IF (PRINTIT)
- FPRINTF(LST," .REF %S\N",NEWXREF->NAME);
- ▌
- ▌
- /*
- * ╔NPUT IDENTIFIER FROM FILE, REPLACING 'KLUDGE' CHARACTERS
- *
- */
-
- GETID(S,F)
- CHAR *S;
- ╞╔╠┼ F;
- █
- CHAR *S1;
- CHAR C;
-
- S1 = S; /* SAVE COPY OF POINTER */
- WHILE (*S++ = GETC(F))
- ;
-
- IF (!ISALPHA(*S1)) █ /* KLUDGE LABEL? */
- *S1++ = '.';
- IF (*S1) █ /* MORE THAN 1 CHARACTER? */
- *S1++ = '.';
- ▌
- ▌
- WHILE (C=*S1) █ /* CHECK REST OF LABEL */
- IF (!ISPRINT(C)) *S1 += ('A'-1); /* MAKE PRINTABLE CHARACTER */
- S1++;
- ▌
- ▌
-
- /* ╧PEN A FILE, ALLOWING DEVICE NUMBER SPECIFICATION. */
-
- OPENFILE(NAME,HOW)
- CHAR *NAME,HOW;
-
- █
- CHAR *XNAME;
- CHAR C;
- UNSIGNED DVC;
- UNSIGNED STAT;
-
- XNAME = NAME; /* COPY POINTER */
- DVC = 8; /* DEFAULT IS DEVICE 8 */
- IF ((C=*XNAME) == '#') █
- XNAME++;
- IF (((C=*XNAME) == '8') ▀▀ ((C=*XNAME) == '9')) █
- XNAME++;
- DVC = (8 + (C - '8'));
- IF (*XNAME==':') XNAME++;
- ELSE █
- PRINTF("MISSING ':' IN DEVICE SPECIFICATION\N%S\N",XNAME);
- RETURN ╬╒╠╠;
- ▌
- ▌
- ELSE █
- PRINTF("ILLEGAL DEVICE NUMBER:\N%S\N",XNAME);
- RETURN ╬╒╠╠;
- ▌
- ▌
-
- DEVICE(DVC);
- STAT = FOPEN(XNAME,HOW);
- DEVICE(8);
- RETURN STAT;
- ▌
-