home *** CD-ROM | disk | FTP | other *** search
- /*
- * ╥EVERSE ┴SSEMBLER
- * ╘RANSLATION ╥OUTINES
- * ╞ILENAME: RA2.C
- * ═ODIFIED:
- * 11/02/85 - ╥EMOVED DASHES BETWEEN EXTERNAL LABELS
- * 04/14/86 - ┴DDED 'SYMBOL+OFFSET' SYNTAX OUTPUT.
- */
- #INCLUDE "RA.H"
-
- /* EXTERNAL DATA */
- EXTERN ╞╔╠┼ OBJ;
- EXTERN ╞╔╠┼ LST;
- EXTERN STRUCT LABEL *XDEFHD;
- EXTERN STRUCT LABEL *XREFHD;
- EXTERN CHAR *CODEBUF;
- EXTERN UNSIGNED CODESZ,BIAS,DATASZ,PROMPT;
- EXTERN UNSIGNED *RELBUF;
-
- EXTERN CHAR *MTABLE[]; /* MNEMONIC STRINGS */
- EXTERN CHAR OPCODES[]; /* OPCODE TO MNEMONIC INDEX TRANSLATION */
- EXTERN CHAR AMODES[]; /* OPCODE TO ADDRESSING MODE TRANSLATION */
- EXTERN CHAR MODESZ[]; /* MODE TO ADDRESS FIELD SIZE */
- /*
- * ╨ACKAGE GLOBAL DATA
- *
- */
- CHAR *CODEPTR; /* CODE BUFFER POINTER */
- INT COUNT; /* CODE COUNTER */
- CHAR EFUNC; /* TRUE WHEN END OF FUNCTION DETECTED (C$106) */
- UNSIGNED LOC; /* CURRENT LOCATION */
- INT *RELPTR; /* RELOCATION INFO POINTER */
- STRUCT LABEL *CURSYM; /* CURRENT SYMBOL */
- STRUCT LABEL *XDEFPTR,*XREFPTR; /* POINTER TO NEXT XDEF, XREF */
-
- /*
- * ╨RINT ADDRESS VALUE AS EITHER A SYMBOLIC QUANTITY OR HEX VALUE
- * ├ALLED WITH:
- * ┴DDRESS, ADDRESSING MODE, SIZE (0-2)
- */
- PAV(A,M,S)
- UNSIGNED A,M,S;
- █
- IF (!CKREF()) █ /* XREF PENDING? */
- IF (M != ╔══) █ /* DON'T DO SYMBOL SEARCH FOR IMMEDIATE OPERANDS */
- IF (CKSYM(A)) RETURN;
- ▌
- IF (S==2) FPRINTF(LST,"$%04X",A);
- ELSE FPRINTF(LST,"$%02X",A);
- ▌
- ▌
-
- /*
- * ╨RINT ADDRESS FIELD BASED ON OPCODE
- * ├ALLED WITH:
- * ADDRESS
- * ADDRESSING MODE
- * SIZE (1 OR 2)
- */
- PAF(A,M,S)
- UNSIGNED A,M,S;
- █
- UNSIGNED ADDR; /* ADDRESS VALUE */
-
- SWITCH (M) /* PREFIX? */
- █
- CASE ┴├├: FPUTC('┴',LST);
- BREAK;
-
- CASE ╔══: FPUTC('#',LST);
- PAV(A,M,S);
- BREAK;
- CASE ┌┼╥:
- CASE ┴┬╙:
- PAV(A,M,S);
- BREAK;
-
- CASE ┌╨╪:
- CASE ┴┬╪: PAV(A,M,S);
- FPRINTF(LST,",╪");
- BREAK;
-
- CASE ┌╨┘:
- CASE ┴┬┘: PAV(A,M,S);
- FPRINTF(LST,",┘");
- BREAK;
-
- CASE ╔═╨: BREAK;
-
- CASE ╥┼╠:
- #UNDEF ╧╠─╫┴┘
-
- IF (A>=128) █ /* SIGN EXTEND */
- ADDR = (0XFF00 ▀ A);
- FPRINTF(LST,"*%D",ADDR+2);
- ▌
- ELSE █
- FPRINTF(LST,"*+%D",A+2);
- ▌
- #IFDEF ╧╠─╫┴┘
- ADDR=ADDR+LOC+2;
- PAV(ADDR,M,S);
- #ENDIF
- BREAK;
-
- CASE ╔╬─╪: FPUTC('(',LST);
- PAV(A,M,S);
- FPRINTF(LST,",╪)");
- BREAK;
-
- CASE ╔╬─┘: FPUTC('(',LST);
- PAV(A,M,S);
- FPRINTF(LST,"),┘");
- BREAK;
-
- CASE ╔╬─: FPUTC('(',LST);
- PAV(A,M,S);
- FPUTC(')',LST);
- BREAK;
-
- DEFAULT: FPRINTF(LST,"????");
-
- ▌
- ▌
-
- /*
- * ═AIN ROUTINE FOR THIS PACKAGE
- *
- */
- RVRS()
- █
- CHAR OP;
- UNSIGNED A1,A2,DEFCNT;
- UNSIGNED MODE,IMODE,SIZE,I;
-
- CODEPTR = CODEBUF;
- RELPTR = RELBUF;
- XDEFPTR = XDEFHD;
- XREFPTR = XREFHD;
- LOC = BIAS;
- COUNT = CODESZ;
- IMODE = 1; /* ALWAYS START IN INSTRUCTION MODE */
- EFUNC = 0;
- IF (!COUNT) CKDEF();
- ELSE
- WHILE (COUNT) █
- IF (CKDEF() ▀▀ EFUNC) IMODE=CKMODE();
- EFUNC = 0;
- IF (!OPCODES[*CODEPTR]) █ /* INVALID OPCODE? */
- FPRINTF(LST,";!!!╔NVALID OPCODE - SWITCHING TO BYTE MODE.\N");
- IMODE=0;
- ▌
- IF (IMODE==0) █
- DOBYTE();
- IF (COUNT) IMODE = CKMODE();
- ▌
- ELSE █ /* INSTRUCTION MODE */
- OP = *CODEPTR++;
- COUNT--;
- MODE = AMODES[OP];
- SIZE = MODESZ[MODE];
- A1=0;
- A2=0;
- IF (SIZE) █
- A1 = *CODEPTR++;
- COUNT--;
- IF (SIZE==2) █
- A2 = *CODEPTR++;
- COUNT--;
- ▌
- ▌
- IF (COUNT<0) █
- FPRINTF(LST,"--- CODE UNDERFLOW ---\N");
- ABORT();
- ▌
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"%02X %02X %02X / %04X ",OP,A1,A2,LOC);
- #ENDIF
- FPRINTF(LST," %S ",MTABLE[OPCODES[OP]]);
- IF (SIZE==2)
- A1 = A1 ▀ (A2 << 8);
- PAF(A1,MODE,SIZE); /* PRINT ADDRESS FIELD */
- FPUTC('\N',LST);
- LOC=LOC+SIZE+1;
- ▌ /* INSTRUCTION MODE */
- ▌ /* WHILE */
- DODATA(); /* OUTPUT DATA BLOCKS */
- FPUTC('\N',LST);
- ▌
-
- /*
- * ╞ORMAT DATA IN .BYTE MODE UNTIL A NEXT LABEL DEFINITION.
- *
- */
- DOBYTE()
- █
- UNSIGNED BYTECNT=8,FIRST=1;
-
- WHILE (COUNT) █
- IF (CKDEF()) BREAK;
- IF (BYTECNT==8) █
- IF (!FIRST) FPUTC('\N',LST);
- FIRST=0;
- BYTECNT=0;
- #IFDEF ─┼┬╒╟
- FPRINTF(LST," %04X ",LOC);
- #ENDIF
- FPRINTF(LST," .BYTE ");
- ▌
- FPRINTF(LST,"%C $%02X ",(BYTECNT>0 ? ',' : ' '),*CODEPTR++);
- BYTECNT++;
- COUNT--;
- LOC++;
- ▌ /* WHILE */
- FPUTC('\N',LST);
- ▌
-
- /*
- * ╙EE IF CURRENT LOCATION HAS ONE OR MORE LABELS DEFINED.
- * ╥ETURNS A COUNT OF LABELS DEFINED FOR THIS LOCATION.
- */
- CKDEF()
- █
- UNSIGNED DC;
-
- DC = 0;
- WHILE (XDEFPTR && (LOC >= XDEFPTR->OFFSET)) █
- IF (XDEFPTR->GLOBAL) █
- IF (!DC) █
- FPUTC('\N',LST); /* SKIP LINE ON FIRST LABEL */
- ▌
- DC++;
- IF ((XDEFPTR->FLAG==0) ▀▀ (XDEFPTR->OFFSET < LOC)) █ /* ABSOLUTE? */
- FPRINTF(LST,"%-12S = $%04X\N",XDEFPTR->NAME,XDEFPTR->OFFSET);
- ▌
- ELSE
- FPRINTF(LST,"%S\N",XDEFPTR->NAME);
- ▌
- CURSYM = XDEFPTR; /* SAVE CURRENT SYMBOL */
- XDEFPTR = XDEFPTR->NEXT;
- ▌
- RETURN(DC);
- ▌
-
- /*
- * ╙EE IF CURRENT LOCATION HAS AN EXTERNAL REFERENCE.
- *
- */
- CKREF()
- █
- IF (XREFPTR && (LOC == XREFPTR->OFFSET)) █
- /*
- * ╚ERE LIES A KLUDGE WHICH ASSISTS IN THE DETERMINATION OF THE FORMATTING
- * MODE TO BE USED. ╔F A REFERENCE TO RUNTIME ROUTINE ├$106 IS BEING MADE,
- * WE ARE ABOUT TO EXIT A FUNCTION. ╫HAT FOLLOWS COULD BE ANOTHER FUNCTION
- * OR IT COULD BE THE BEGINNING OF UNLABELED PRESET STRING OR ARRAY DATA.
- * ╘HE MAIN LOOP TESTS THE FLAG 'EFUNC' WHICH IS SET HERE TO SEE IF A MODE
- * CHECK IS NECESSARY.
- */
- EFUNC = !STRCMP(XREFPTR->NAME,"C$106");
- IF (XREFPTR->FLAG == 1) FPUTC('>',LST); /* HIGH ORDER BYTE */
- ELSE IF (XREFPTR->FLAG == 2) FPUTC('<',LST); /* LOW ORDER BYTE */
- FPRINTF(LST,"%S",XREFPTR->NAME);
- XREFPTR = XREFPTR->NEXT;
- IF (EFUNC) FPUTC('\N',LST);
- RETURN(1);
- ▌
- ELSE RETURN(0);
- ▌
-
- /*
- * ╙EE IF ADDRESS VALUE MATCHES EXTERNAL SYMBOL DEFINITION OFFSET
- * ╥ETURNS SYMBOL OFFSET IF FOUND, ZERO OTHERWISE. ╘HIS ASSUMES
- * THAT ZERO IS AN INVALID OFFSET, WHICH IN FACT, IT IS, SINCE THE
- * CODE AT ZERO IS ALWAYS A JMP C$START.
- */
- CKSYM(A)
- UNSIGNED A;
- █
- #DEFINE ═┴╪─╔╞╞ 127 /* MAX DISPLACEMENT FOR SYMBOL EXPRESSION */
-
- STRUCT LABEL *PTR,*CLOSEST;
- REGISTER UNSIGNED DIFF,MIN;
-
- PTR = XDEFHD; /* GET XDEF LIST POINTER */
- MIN = ═┴╪─╔╞╞ + 1;
- WHILE (PTR) █ /* NOTHING FANCY - JUST A LINEAR SEARCH */
- DIFF = A - PTR->OFFSET;
- IF ((A >= PTR->OFFSET) && (DIFF <= ═┴╪─╔╞╞)) █
- IF (DIFF == 0) █
- MIN = 0;
- CLOSEST = PTR;
- BREAK;
- ▌
- ELSE IF (DIFF < MIN) █
- MIN = DIFF;
- CLOSEST = PTR;
- ▌
- ▌
- PTR = PTR->NEXT;
- ▌
- IF (MIN <= ═┴╪─╔╞╞) █
- FPRINTF(LST,"%S",CLOSEST->NAME);
- IF (MIN) FPRINTF(LST,"+%D",MIN);
- RETURN(CLOSEST->OFFSET);
- ▌
- RETURN 0;
- ▌
-
- /*
- * ├HECK FOR FORMATTING MODE CHANGE.
- * ╥ETURNS 1 FOR INSTRUCTION MODE, 0 FOR .BYTE MODE
- *
- */
- CKMODE()
- █
- CHAR C1,C2; /* NEXT 2 BYTE VALUES */
- CHAR S[20]; /* RESPONSE STRING */
- C1 = *CODEPTR;
- C2 = *(CODEPTR+1);
-
- IF (PROMPT) █ /* USER WANTS AUTHORITY */
- PRINTF("CURRENT SYMBOL: %S\NFIRST 2 BYTES: %02X %02X\N",CURSYM->NAME,C1,C2);
- FOR (;;) █
- PRINTF("╔NSTRUCTION OR ┬YTE MODE? ");
- GETS(S);
- SWITCH(*S) █
- CASE '╔':
- CASE 'I': RETURN(1);
- CASE '┬':
- CASE 'B': RETURN(0);
- DEFAULT: PRINTF("┼NTER AN ╔ OR A ┬, PLEASE\N");
- ▌
- ▌
- ▌
- ELSE █
-
- /*********************************************************************
- * ╚ERE COMES THE BIG KLUDGE, FOLKS! ╔N ORDER TO DECIDE WHETHER THE *
- * CODE THAT FOLLOWS IS INSTRUCTION OR DATA, WE TEST FOR THE PATTERN *
- * 'STA $FB' WHICH SEEMS TO OCCUR AT THE ENTRY TO EVERY PROCEDURE. *
- * ┴NOTHER POSSIBILITY IS THE JMP C$START AT THE BEGINNING OF EACH *
- * CODE SEGMENT. *
- * ╔F THESE PATTERNS ARE NOT DETECTED, THEN SWITCH TO DATA MODE AND *
- * OUTPUT .BYTE DIRECTIVES. *
- *********************************************************************/
-
- IF ((C1==0X85) && (C2==0XFB))
- RETURN(1); /* SET INSTRUCTION MODE */
- ELSE IF (XREFPTR && (LOC == XREFPTR->OFFSET))
- RETURN 1;
- ELSE
- RETURN(0);
- ▌
- ▌
-
- /*
- * ╧UTPUT ─ATA ┬LOCKS
- *
- */
-
- DODATA()
- █
- UNSIGNED CNT,SIZE;
- CHAR ID[═┴╪╔─];
-
- CNT = GETW(OBJ); /* GET NUMBER OF ENTRIES */
- IF (CNT) █
- FPRINTF(LST,"\N;═ODULE DATA BLOCKS.\N");
-
- #IFDEF ─┼┬╒╟
- FPRINTF(LST,"%D DATA BLOCKS.\N",CNT);
- #ENDIF
-
- WHILE (CNT--) █
- GETID(ID,OBJ); /* GET IDENTIFIER */
- SIZE = GETW(OBJ);
- FPRINTF(LST,"%-10S .DSEG %D\N",ID,SIZE);
- ▌
- ▌
- ▌
-
-