home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / C64-128Toolkit / RA.ARC / RA1.C < prev    next >
Encoding:
C/C++ Source or Header  |  2019-04-13  |  9.9 KB  |  443 lines

  1. /* ╧BJECT ╞ILE ╥EVERSE ┴SSEMBLER
  2.  * ┴UTHOR:   ═ARK ╥. ╥INFRET
  3.  * ─ATE:     05/13/85
  4.  * ╞ILENAME: RA1.C
  5.  * ╚ISTORY:
  6.  *
  7.  *   11/02/85 - ╧UTPUT .DEF, .REF
  8.  *
  9.  *   04/13/86 - ╞IXED XDEF LIST LINKING PROBLEM, ADDED 'STANDARD' SYMBOL
  10.  *              DEFINITIONS.
  11.  *
  12.  *   04/15/86 - ╔NHIBIT MULTIPLE .REF'S TO SAME SYMBOL
  13.  */
  14. #INCLUDE "RA.H"
  15.  
  16. /* EXTERNAL DATA */
  17. EXTERN STRUCT LABEL *XDEFHD,*XDEFTL;  /* HD,TL OF XDEF LABEL LIST */
  18. EXTERN STRUCT LABEL *XREFHD,*XREFTL; /* HD AND TL POINTERS FOR XREF LIST */
  19. EXTERN ╞╔╠┼ LST;             /* LISTING FILE */
  20. EXTERN ╞╔╠┼ OBJ;             /* OBJECT FILE */
  21. EXTERN UNSIGNED BIAS,CODESZ,RELSZ,XREFSZ,DATASZ;
  22. EXTERN CHAR *CODEBUF;        /* CODE BUFFER     */
  23. EXTERN UNSIGNED PROMPT;      /* INTERACTIVE MODE FLAG */
  24. EXTERN UNSIGNED *RELBUF;     /* RELOCATION DATA */
  25.  
  26. /* GLOBAL DATA */
  27. STRUCT LABEL *NEWLBL;        /* NEW LABEL POINTER */
  28.  
  29. /****************/
  30. MAIN (ARGC, ARGV)
  31. UNSIGNED ARGC;
  32. CHAR **ARGV;
  33.  
  34.    LST = STDOUT;             /* DEFAULT IS STANDARD OUTPUT */
  35.    BIAS = 0X1800;            /* STARTING ADDRESS FOR SHELL PROGRAMS */
  36.    PROMPT = 0;               /* NON-INTERACTIVE MODE */
  37.  
  38.    WHILE (ARGC>2) █
  39.      IF (!STRCMP(*++ARGV,"-L")) █ /* LISTING OPTION */
  40.        IF ((LST=OPENFILE(*++ARGV,"W"))==╬╒╠╠ ▀▀ FERROR()) █
  41.          PRINTF("CAN'T OPEN LISTING FILE, %S\N",*ARGV);
  42.          EXIT();
  43.        ▌
  44.        ARGC -= 2;
  45.      ▌
  46.      ELSE IF (!STRCMP(*ARGV,"-P")) █ /* INTERACTIVE OPTION */
  47.        PROMPT = 1;
  48.        ARGC--;
  49.      ▌
  50.      ELSE IF (!STRCMP(*ARGV,"-A")) █ /* CHANGE BIAS */
  51.        SSCANF(*++ARGV,"%X",&BIAS);
  52.        ARGC -= 2;
  53.      ▌
  54.      ELSE █
  55.        PRINTF("--BAD OPTION: %S\N",*ARGV);
  56.        EXIT();
  57.      ▌
  58.    ▌ /* END WHILE */
  59.  
  60.    IF (ARGC<2) USAGE();
  61.  
  62.    IF ((OBJ = OPENFILE(*++ARGV, "R")) == ╬╒╠╠ ▀▀ FERROR()) █
  63.      PRINTF ("CAN'T OPEN OBJECT FILE, %S\N", *ARGV);
  64.    ▌
  65.    ELSE █
  66.      REVERSE ();
  67.      FCLOSE (OBJ);
  68.    ▌
  69.  
  70. /* 
  71.  * ─ISPLAY CORRECT PROGRAM USAGE.
  72.  *
  73.  */
  74. USAGE()
  75.   PRINTF("USAGE: RA [OPTIONS] OBJECT FILE\N");
  76.   PRINTF("OPTIONS:\N"); 
  77.   PRINTF("  -P ENABLE FORMAT PROMPTING\N");
  78.   PRINTF("  -L LISTFILE (OUTPUT TO LISTFILE)\N");
  79.   PRINTF("  -A ADDRESS (ALIGN AT HEX ADDRESS)\N");
  80.   EXIT();
  81.  
  82. REVERSE()
  83.   XDEFHD = ╬╒╠╠;
  84.   XDEFTL = ╬╒╠╠;
  85.   XREFHD = ╬╒╠╠;
  86.   XREFTL = ╬╒╠╠;
  87.   GETCODE();         /* INPUT CODE SEGMENT  */
  88.   GETREL();          /* GET RELOCATION DATA */
  89.   DEFSTD();          /* DEFINE 'STANDARD' SYMBOLS */
  90.   GETXDEF();         /* GET EXTERNAL ID'S   */
  91.   GETXREF();         /* GET EXTERNAL REF'S  */
  92.   RVRS();            /* DO REVERSE ASSEMBLY */
  93.  
  94. /* ╔NPUT CODE SEGMENT */
  95. GETCODE()
  96.   CHAR *MALLOC();
  97.  
  98.   CODESZ = GETW(OBJ);
  99. #IFDEF ─┼┬╒╟
  100.   FPRINTF(LST,"├ODE ╙IZE: %5D(─) / %X(╪)\N",CODESZ,CODESZ);
  101. #ENDIF
  102.   CODEBUF = MALLOC(CODESZ);
  103.   FREAD(CODEBUF,1,CODESZ,OBJ);
  104.  
  105. /* 
  106.  * ╔NPUT RELOCATION INFORMATION AND PERFORM RELOCATION.
  107.  *
  108.  */
  109.  
  110. GETREL()
  111.   CHAR *MALLOC();
  112.   CHAR *CP; /* TEMP CODE POINTER */
  113.   UNSIGNED AD,CNT1,CNT2;
  114.   UNSIGNED *RP;
  115.  
  116.   RELSZ = GETW(OBJ);
  117.   RELBUF = (INT *) MALLOC(RELSZ*2);
  118.   FREAD(RELBUF,2,RELSZ,OBJ);
  119. #IFDEF ─┼┬╒╟
  120.   FPRINTF(LST,"%D RELOCATION ENTRIES\N",RELSZ);
  121.   CNT1 = RELSZ;
  122.   CNT2 = 0;
  123.   RP = RELBUF;
  124.   WHILE (CNT1--) █
  125.     FPRINTF(LST,"%04X  ",*RP++);
  126.     IF (++CNT2 == 8) █
  127.       FPUTC('\N',LST);
  128.       CNT2=0;
  129.     ▌
  130.   ▌
  131.   FPRINTF(LST,"\N;--------------------\N");
  132. #ENDIF
  133.  
  134. /* ╥ELOCATE THE CODE ACCORDING TO 'BIAS' */
  135.   RP = RELBUF;
  136.   CNT1 = RELSZ;
  137.   WHILE (CNT1--) █
  138. /*
  139.  * ├OMPUTE POINTER INTO CODE BUFFER.  ╔T IS IMPORTANT TO NOTE THAT THE
  140.  * RELOCATION ENTRY ALWAYS ASSUMES THAT AN OPCODE IS PRESENT (3 BYTE CODE
  141.  * ENTRY).  ╘HUS, RELOCATION ENTRIES WHICH MODIFY CHARACTER STRING POINTERS
  142.  * APPEAR TO BE ONE LESS THAN THEY SHOULD BE.
  143.  *
  144.  */
  145.     CP = CODEBUF + *RP++ + 1;
  146.     AD = *CP;                 /* GET LOW BYTE OF ADDRESS */
  147.     AD = AD ▀ (*(CP+1) << 8); /* 'OR' WITH UPPER BYTE */
  148.     AD = AD + BIAS;           /* RELOCATE */    
  149.     *CP = AD;                 /* PUT BACK LOWER */
  150.     *(CP+1) = (AD >> 8);      /* PUT BACK UPPER */      
  151.   ▌
  152.  
  153. /* ─EFINE 'STANDARD' LABELS
  154.    ╘HIS ROUTINE INPUTS THE CONTENTS OF THE FILE 'RA.SYMBOLS' AND ADDS
  155.    THE DEFINITIONS FOUND THEREIN TO THE LIST OF GLOBAL SYMBOLS.  ╨LEASE
  156.    NOTE THAT THESE SYMBOLS ARE NOT EXTERNALIZED WITH .DEF STATEMENTS AS
  157.    THE EXTERNAL SYMBOLS FROM THE OBJECT FILE ARE.  ╘HE SYMBOL DEFINITIONS
  158.    ARE OUTPUT TO THE DISASSEMBLY LISTING AS THEY ARE DEFINED.
  159. */
  160.  
  161. DEFSTD()
  162.   ╞╔╠┼ SYMFILE;
  163.   CHAR *MALLOC();
  164.   REGISTER UNSIGNED I;
  165.   STRUCT LABEL *NEWLBL;
  166.   CHAR *P;
  167.   UNSIGNED SYMLENG,OFFSET;
  168.   CHAR C,LINE[81],SYM[═┴╪╔─+1];
  169.  
  170.   IF ((SYMFILE=FOPEN("RA.SYMBOLS","R"))==╬╒╠╠ ▀▀ FERROR()) █
  171.     PRINTF("├AN'T LOAD SYMBOLS!\N");
  172.     RETURN;
  173.   ▌
  174.  
  175.   P = "C$$START"; /* SPECIAL FIRST SYMBOL */
  176.   NEWLBL = (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL));
  177.   NEWLBL->NEXT = ╬╒╠╠;
  178.   NEWLBL->NAME = MALLOC(STRLEN(P)+1);
  179.   STRCPY(NEWLBL->NAME,P);
  180.   NEWLBL->OFFSET = BIAS;
  181.   NEWLBL->FLAG = 1;
  182.   NEWLBL->GLOBAL = 1;
  183.  
  184.   ADDSYM(NEWLBL);
  185.  
  186.   WHILE (FGETS(LINE,81,SYMFILE)) █
  187.     IF (*LINE != ';') █
  188.       P = LINE;  /* COPY STRING POINTER */
  189.       SYMLENG = 0;
  190.       WHILE ((C = *P++) != ' ') █
  191.         IF (SYMLENG < ═┴╪╔─) SYM[SYMLENG++] = C;
  192.       ▌
  193.       SYM[SYMLENG] = 0; /* NULL TERMINATOR */
  194.       IF (SYMLENG) █
  195.         NEWLBL =  (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL));
  196.         NEWLBL->NAME = MALLOC(++SYMLENG);
  197.         STRCPY(NEWLBL->NAME,SYM);
  198.         NEWLBL->OFFSET = GETADDR(P);
  199.         NEWLBL->FLAG = ╬╒╠╠;
  200.         NEWLBL->GLOBAL = ╬╒╠╠;
  201.         NEWLBL->NEXT = ╬╒╠╠;
  202.         ADDSYM(NEWLBL);  /* ADD LOCAL SYMBOL DEF */
  203.         FPRINTF(LST,"%-12S = $%04X\N",SYM,NEWLBL->OFFSET);
  204.       ▌
  205.       ELSE PRINTF("┬AD SYMBOL DEFINITION:\N%S",LINE);
  206.     ▌
  207.   ▌
  208.   FCLOSE(SYMFILE);
  209.  
  210. /* ╔NPUT AN ADDRESS VALUE AS EITHER DECIMAL (DEFAULT) OR HEXADECIMAL IF 
  211.    PRECEDED BY '0X'.  ╘HIS ROUTINE WAS ADDED BECAUSE IT APPEARS THAT SCANF
  212.    DOES NOT PROPERLY HANDLE HEX VALUES. (?)
  213. */
  214.  
  215. INT GETADDR(S)
  216. CHAR *S;
  217.   CHAR C;
  218.   CHAR BASE = 10;
  219.   UNSIGNED VALUE;
  220.  
  221.   WHILE ((C=*S++)==' ' ▀▀ C == '0');
  222.   IF ((C == '\N') ▀▀ (C == 0)) RETURN -1;
  223.   IF (C == 'X' ▀▀ C == '╪') BASE = 16;
  224.   WHILE (ISALNUM((C=*S++))) █
  225.     VALUE *= BASE;
  226.     IF (C>='0' && C<='9') VALUE += (C-'0');
  227.     ELSE █
  228.       IF (BASE==10) RETURN -1;
  229.       IF ((C>='A' && C<='F')) VALUE += (10 + C-'A');
  230.       ELSE IF (C>='┴' && C<='╞') VALUE += (10 + C-'┴');
  231.       ELSE RETURN -1;
  232.     ▌
  233.   ▌
  234.   RETURN VALUE;      
  235.   
  236. /* ╔NPUT EXTERNAL IDENTIFIERS */
  237.  
  238. GETXDEF()
  239.   CHAR *MALLOC();
  240.  
  241.   UNSIGNED COUNT,I,OFST;
  242.   CHAR ID[═┴╪╔─];
  243.  
  244.   COUNT = GETW(OBJ); /* GET COUNT OF ID'S */
  245.  
  246. #IFDEF ─┼┬╒╟
  247.   FPRINTF(LST,"%D EXTERNAL DEFINITIONS\N",COUNT);
  248. #ENDIF
  249.  
  250.   WHILE (COUNT--) █
  251.     IF (!(NEWLBL = (STRUCT LABEL *) MALLOC(SIZEOF(STRUCT LABEL)))) █
  252.       FPRINTF(LST,"╧UT OF MEMORY!");
  253.       ABORT();
  254.     ▌
  255.     GETID(ID,OBJ); /* INPUT IDENTIFIER */
  256.     NEWLBL->NAME = MALLOC(STRLEN(ID)+1);
  257.     STRCPY(NEWLBL->NAME,ID);
  258.     NEWLBL->FLAG = GETC(OBJ);
  259.     OFST = GETW(OBJ);
  260.  
  261. /* RELOCATE SYMBOL TO START ADDRESS */
  262.  
  263.     IF (NEWLBL->FLAG) OFST += BIAS;
  264.     NEWLBL->OFFSET = OFST;
  265.     NEWLBL->GLOBAL = 1;
  266.     NEWLBL->NEXT = ╬╒╠╠;
  267.     ADDSYM(NEWLBL);  /* ADD SYMBOL */
  268.   ▌
  269.  
  270. /* ┴DD SYMBOL TO GLOBAL SYMBOL LIST
  271. ** ├ALLED WITH:
  272. **   ╙YMBOL DEFINITION
  273. */
  274. ADDSYM(LBL)
  275. STRUCT LABEL *LBL;
  276.   STRUCT LABEL *CUR,*PREV;
  277.  
  278.   IF (XDEFHD == ╬╒╠╠) █ /* FIRST ENTRY */
  279.     XDEFHD = LBL;
  280.     XDEFTL = LBL;
  281.   ▌
  282.   ELSE █
  283.     IF (LBL->OFFSET < XDEFTL->OFFSET) █ /* ╧UT OF ORDER? */
  284.       CUR = XDEFHD;
  285.       PREV = XDEFHD; /* INSERT INTO LIST */
  286.       WHILE (CUR) █
  287.         IF (LBL->OFFSET < CUR-> OFFSET) █
  288.           IF (CUR==XDEFHD) █ /* NEW FIRST ELEMENT? */
  289.             LBL->NEXT = XDEFHD;
  290.             XDEFHD = LBL;
  291.             BREAK;
  292.           ▌
  293.           ELSE █
  294.            PREV->NEXT = LBL;
  295.            LBL->NEXT = CUR;
  296.            BREAK;
  297.           ▌
  298.         ▌
  299.         ELSE █
  300.           PREV = CUR;
  301.           CUR = CUR->NEXT;
  302.         ▌
  303.       ▌
  304.     ▌
  305.     ELSE █ /* ADD TO END OF LIST */
  306.       XDEFTL->NEXT = LBL;
  307.       XDEFTL = LBL;
  308.     ▌
  309.   ▌
  310.  
  311. /*
  312.  * ╔NPUT EXTERNAL REFERENCES
  313.  *
  314.  */
  315.  
  316. GETXREF()
  317.   STRUCT LABEL *MALLOC();
  318.  
  319.   UNSIGNED COUNT,PRINTIT;
  320.   STRUCT LABEL *NEWXREF,*TESTREF;
  321.   CHAR ID[═┴╪╔─];
  322.  
  323.   COUNT=GETW(OBJ); /* GET NUMBER OF XREFS */
  324.  
  325. #IFDEF ─┼┬╒╟
  326.   FPRINTF(LST,"%D EXTERNAL REFERENCES.\N\N",COUNT);
  327. #ENDIF
  328.  
  329.   WHILE (COUNT--) █
  330.     GETID(ID,OBJ); /* INPUT IDENTIFIER */
  331.     NEWXREF=MALLOC(SIZEOF(STRUCT LABEL));
  332.     NEWXREF->NAME = MALLOC(STRLEN(ID));
  333.     STRCPY(NEWXREF->NAME,ID);
  334.     NEWXREF->NEXT = ╬╒╠╠;
  335.     NEWXREF->FLAG = GETW(OBJ);
  336.     NEWXREF->OFFSET = GETW(OBJ)+BIAS;
  337.     NEWXREF->GLOBAL = 1;
  338.  
  339.     PRINTIT = 1;       /* ASSUME .REF IS UNIQUE */
  340.  
  341.     IF (XREFHD==╬╒╠╠) █/* FIRST ENTRY */
  342.       XREFHD = NEWXREF;
  343.       XREFTL = NEWXREF;
  344.     ▌
  345.     ELSE █
  346.       TESTREF = XREFHD;
  347.       WHILE (TESTREF) █
  348.         IF (!STRCMP(TESTREF->NAME,NEWXREF->NAME)) █
  349.           PRINTIT = 0;
  350.           BREAK;
  351.         ▌
  352.         TESTREF = TESTREF->NEXT;
  353.       ▌
  354.       XREFTL->NEXT = NEWXREF;
  355.       XREFTL = NEWXREF;
  356.     ▌ 
  357.     IF (PRINTIT)
  358.       FPRINTF(LST," .REF %S\N",NEWXREF->NAME);
  359.   ▌
  360. /*
  361.  * ╔NPUT IDENTIFIER FROM FILE, REPLACING 'KLUDGE' CHARACTERS
  362.  *
  363.  */
  364.  
  365. GETID(S,F)
  366. CHAR *S;
  367. ╞╔╠┼ F;
  368.   CHAR *S1;
  369.   CHAR C;
  370.  
  371.   S1 = S; /* SAVE COPY OF POINTER */
  372.   WHILE (*S++ = GETC(F))
  373.     ;
  374.  
  375.   IF (!ISALPHA(*S1)) █ /* KLUDGE LABEL? */
  376.     *S1++ = '.';
  377.     IF (*S1) █ /* MORE THAN 1 CHARACTER? */
  378.       *S1++ = '.';
  379.     ▌
  380.   ▌
  381.   WHILE (C=*S1) █    /* CHECK REST OF LABEL */
  382.     IF (!ISPRINT(C)) *S1 += ('A'-1); /* MAKE PRINTABLE CHARACTER */
  383.     S1++;
  384.   ▌
  385.  
  386. /* ╧PEN A FILE, ALLOWING DEVICE NUMBER SPECIFICATION. */
  387.  
  388. OPENFILE(NAME,HOW)
  389. CHAR *NAME,HOW;
  390.  
  391.   CHAR *XNAME;
  392.   CHAR C;
  393.   UNSIGNED DVC;
  394.   UNSIGNED STAT;
  395.  
  396.   XNAME = NAME; /* COPY POINTER */
  397.   DVC = 8;  /* DEFAULT IS DEVICE 8 */
  398.   IF ((C=*XNAME) == '#') █
  399.     XNAME++;
  400.     IF (((C=*XNAME) == '8') ▀▀ ((C=*XNAME) == '9')) █
  401.       XNAME++;
  402.       DVC = (8 + (C - '8'));
  403.       IF (*XNAME==':') XNAME++;
  404.       ELSE █
  405.         PRINTF("MISSING ':' IN DEVICE SPECIFICATION\N%S\N",XNAME);
  406.         RETURN ╬╒╠╠;
  407.         ▌
  408.       ▌
  409.     ELSE █
  410.       PRINTF("ILLEGAL DEVICE NUMBER:\N%S\N",XNAME);
  411.       RETURN ╬╒╠╠;
  412.       ▌
  413.     ▌
  414.  
  415.   DEVICE(DVC);
  416.   STAT = FOPEN(XNAME,HOW);
  417.   DEVICE(8);
  418.   RETURN STAT;
  419.