home *** CD-ROM | disk | FTP | other *** search
-
- /*
- XA65 - 6502 CROSS ASSEMBLER AND UTILITY SUITE
- LD65 - O65 RELOCATABLE OBJECT FILE LINKER
- cOPYRIGHT (c) 1997 aNDR{$e9} fACHAT (A.FACHAT@PHYSIK.TU-CHEMNITZ.DE)
-
- tHIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
- IT UNDER THE TERMS OF THE gnu gENERAL pUBLIC lICENSE AS PUBLISHED BY
- THE fREE sOFTWARE fOUNDATION; EITHER VERSION 2 OF THE lICENSE, OR
- (AT YOUR OPTION) ANY LATER VERSION.
-
- tHIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
- BUT without any warranty; WITHOUT EVEN THE IMPLIED WARRANTY OF
- merchantability OR fitness for a particular purpose. sEE THE
- gnu gENERAL pUBLIC lICENSE FOR MORE DETAILS.
-
- yOU SHOULD HAVE RECEIVED A COPY OF THE gnu gENERAL pUBLIC lICENSE
- ALONG WITH THIS PROGRAM; IF NOT, WRITE TO THE fREE sOFTWARE
- fOUNDATION, iNC., 675 mASS aVE, cAMBRIDGE, ma 02139, usa.
- */
-
- #INCLUDE <STDIO.H>
- #INCLUDE <STDLIB.H>
- #INCLUDE <SYS/STAT.H>
- #INCLUDE <UNISTD.H>
- #INCLUDE <ERRNO.H>
- #INCLUDE <STRING.H>
-
- #DEFINEbuf(9*2+8)/* 16 BIT HEADER */
-
- TYPEDEF STRUCT {$7b}
- CHAR *NAME;
- INTLEN;
- {$7d} UNDEFS;
-
- TYPEDEF STRUCT {$7b}
- CHAR *FNAME;
- SIZE_T FSIZE;
- UNSIGNED CHAR*BUF;
- INTTBASE, TLEN, DBASE, DLEN, BBASE, BLEN, ZBASE, ZLEN;
- INTTDIFF, DDIFF, BDIFF, ZDIFF;
- INTTPOS, DPOS, UPOS, TRPOS, DRPOS, GPOS;
- INTLASTTRELOC, LASTDRELOC;
- INTNUNDEF;
- UNDEFS *UD;
- {$7d} FILE65;
-
- TYPEDEF STRUCT {$7b}
- CHAR *NAME;
- INTLEN;/* LENGTH OF LABELNAME */
- INTFL;/* 0=OK, 1=MULTIPLY DEFINED */
- INTVAL;/* ADDRESS VALUE */
- INTSEG;/* SEGMENT */
- FILE65*FILE;/* IN WHICH FILE IS IT? */
- {$7d} GLOB;
-
- FILE65 *LOAD_FILE(CHAR *FNAME);
-
- INT READ_OPTIONS(UNSIGNED CHAR *F);
- INT READ_UNDEF(UNSIGNED CHAR *F, FILE65 *FP);
- INT LEN_RELOC_SEG(UNSIGNED CHAR *BUF, INT RI);
- INT RELOC_SEG(UNSIGNED CHAR *BUF, INT ADR, INT RI, INT *LRELOC, FILE65 *FP);
- UNSIGNED CHAR *RELOC_GLOBALS(UNSIGNED CHAR *, FILE65 *FP);
- INT READ_GLOBALS(FILE65 *FILE);
- INT WRITE_OPTIONS(file *FP, FILE65 *FILE);
- INT WRITE_RELOC(FILE65 *FP[], INT NFP, file *F);
- INT WRITE_GLOBALS(file *FP);
-
- FILE65 FILE;
- UNSIGNED CHAR CMP[] = {$7b} 1, 0, 'O', '6', '5' {$7d};
- UNSIGNED CHAR HDR[26] = {$7b} 1, 0, 'O', '6', '5', 0 {$7d};
-
- VOID USAGE(VOID) {$7b}
- PRINTF("LD65: LINK 'O65' FILES\N"
- " LD65 [OPTIONS] [FILENAMES...]\N"
- "OPTIONS:\N"
- " -V = PRINT VERSION NUMBER\N"
- " -H, -? = PRINT THIS HELP\N"
- " -B? ADR = RELOCATES SEGMENT '?' (I.E. 'T' FOR TEXT SEGMENT,\N"
- " 'D' FOR DATA, 'B' FOR BSS AND 'Z' FOR ZEROPAGE) TO THE NEW\N"
- " ADDRESS 'ADR'.\N"
- " -O FILE = USES 'FILE' AS OUTPUT FILE. OTHERWISE WRITE TO 'A.O65'.\N"
- " -g = SUPPRESS WRITING OF GLOBALS\N"
- );
- EXIT(0);
- {$7d}
-
- INT MAIN(INT ARGC, CHAR *ARGV[]) {$7b}
- INT NOGLOB=0;
- INT I = 1;
- INT TBASE = 0X0400, DBASE = 0X1000, BBASE = 0X4000, ZBASE = 0X0002;
- INT TTLEN, TDLEN, TBLEN, TZLEN;
- CHAR *OUTFILE = "A.O65";
- INT J, JM;
- FILE65 *FILE, **FP = null;
- file *FD;
-
- IF(ARGC<=1) USAGE();
-
- /* READ OPTIONS */
- WHILE(I<ARGC && ARGV[I][0]=='-') {$7b}
- /* PROCESS OPTIONS */
- SWITCH(ARGV[I][1]) {$7b}
- CASE 'V':
- PRINTF("RELOC65 VERSION 0.1 (C) 1997 A.FACHAT\N");
- BREAK;
- CASE 'g':
- NOGLOB=1;
- BREAK;
- CASE 'O':
- IF(ARGV[I][2]) OUTFILE=ARGV[I]+2;
- ELSE OUTFILE=ARGV[++I];
- BREAK;
- CASE 'B':
- SWITCH(ARGV[I][2]) {$7b}
- CASE 'T':
- IF(ARGV[I][3]) TBASE = ATOI(ARGV[I]+3);
- ELSE TBASE = ATOI(ARGV[++I]);
- BREAK;
- CASE 'D':
- IF(ARGV[I][3]) DBASE = ATOI(ARGV[I]+3);
- ELSE DBASE = ATOI(ARGV[++I]);
- BREAK;
- CASE 'B':
- IF(ARGV[I][3]) BBASE = ATOI(ARGV[I]+3);
- ELSE BBASE = ATOI(ARGV[++I]);
- BREAK;
- CASE 'Z':
- IF(ARGV[I][3]) ZBASE = ATOI(ARGV[I]+3);
- ELSE ZBASE = ATOI(ARGV[++I]);
- BREAK;
- DEFAULT:
- PRINTF("uNKNOWN SEGMENT TYPE '%C' - IGNORED!\N", ARGV[I][2]);
- BREAK;
- {$7d}
- BREAK;
- CASE 'H':
- CASE '?':
- USAGE();
- DEFAULT:
- FPRINTF(STDERR,"FILE65: %S UNKNOWN OPTION, USE '-?' FOR HELP\N",ARGV[I]);
- BREAK;
- {$7d}
- I++;
- {$7d}
- /* EACH FILE IS LOADED FIRST */
- J=0; JM=0; FP=null;
- WHILE(I<ARGC) {$7b}
- FILE65 *F;
- F = LOAD_FILE(ARGV[I]);
- IF(F) {$7b}
- IF(J>=JM) FP=REALLOC(FP, (JM=(JM?JM*2:10))*SIZEOF(FILE65*));
- IF(!FP) {$7b} FPRINTF(STDERR,"oOPS, NO MORE MEMORY\N"); EXIT(1); {$7d}
- FP[J++] = F;
- {$7d}
- I++;
- {$7d}
-
- /* NOW [TDBZ]BASE HOLDS NEW SEGMENT BASE ADDRESS */
- /* SET TOTAL LENGTH TO ZERO */
- TTLEN = TDLEN = TBLEN = TZLEN = 0;
-
- /* FIND NEW ADDRESSES FOR THE FILES AND READ GLOBALS */
- FOR(I=0;I<J;I++) {$7b}
- FILE = FP[I];
-
- FILE->TDIFF = ((TBASE + TTLEN) - FILE->TBASE);
- FILE->DDIFF = ((DBASE + TDLEN) - FILE->DBASE);
- FILE->BDIFF = ((BBASE + TBLEN) - FILE->BBASE);
- FILE->ZDIFF = ((ZBASE + TZLEN) - FILE->ZBASE);
- /*PRINTF("TBASE=%04X, FILE->TBASE=%04X, TTLEN=%04X -> TDIFF=%04X\N",
- TBASE, FILE->TBASE, TTLEN, FILE->TDIFF);*/
- TTLEN += FILE->TLEN;
- TDLEN += FILE->DLEN;
- TBLEN += FILE->BLEN;
- TZLEN += FILE->ZLEN;
-
- READ_GLOBALS(FILE);
- {$7d}
-
- FOR(I=0;I<J;I++) {$7b}
- FILE = FP[I];
-
- RELOC_SEG(FILE->BUF,
- FILE->TPOS,
- FILE->TRPOS,
- &(FILE->LASTTRELOC),
- FILE);
- RELOC_SEG(FILE->BUF,
- FILE->DPOS,
- FILE->DRPOS,
- &(FILE->LASTDRELOC),
- FILE);
- RELOC_GLOBALS(FILE->BUF+FILE->GPOS, FILE);
-
- FILE->TBASE += FILE->TDIFF;
- FILE->DBASE += FILE->DDIFF;
- FILE->BBASE += FILE->BDIFF;
- FILE->ZBASE += FILE->ZDIFF;
-
- FILE->LASTTRELOC += FILE->TBASE - FILE->TPOS;
- FILE->LASTDRELOC += FILE->DBASE - FILE->DPOS;
-
- {$7d}
-
- HDR[ 6] = 0; HDR[ 7] = 0;
- HDR[ 8] = TBASE & 255; HDR[ 9] = (TBASE>>8) & 255;
- HDR[10] = TTLEN & 255; HDR[11] = (TTLEN >>8)& 255;
- HDR[12] = DBASE & 255; HDR[13] = (DBASE>>8) & 255;
- HDR[14] = TDLEN & 255; HDR[15] = (TDLEN >>8)& 255;
- HDR[16] = BBASE & 255; HDR[17] = (BBASE>>8) & 255;
- HDR[18] = TBLEN & 255; HDR[19] = (TBLEN >>8)& 255;
- HDR[20] = ZBASE & 255; HDR[21] = (ZBASE>>8) & 255;
- HDR[22] = TZLEN & 255; HDR[23] = (TZLEN >>8)& 255;
- HDR[24] = 0; HDR[25] = 0;
-
- FD = FOPEN(OUTFILE, "WB");
- IF(!FD) {$7b}
- FPRINTF(STDERR,"cOULDN'T OPEN OUTPUT FILE %S (%S)\N",
- OUTFILE, STRERROR(ERRNO));
- EXIT(2);
- {$7d}
- FWRITE(HDR, 1, 26, FD);
- /* THIS WRITES _ALL_ OPTIONS FROM _ALL_FILES! */
- FOR(I=0;I<J;I++) {$7b}
- WRITE_OPTIONS(FD, FP[I]);
- {$7d}
- FPUTC(0,FD);
- /* WRITE TEXT SEGMENT */
- FOR(I=0;I<J;I++) {$7b}
- FWRITE(FP[I]->BUF + FP[I]->TPOS, 1, FP[I]->TLEN, FD);
- {$7d}
- /* WRITE DATA SEGMENT */
- FOR(I=0;I<J;I++) {$7b}
- FWRITE(FP[I]->BUF + FP[I]->DPOS, 1, FP[I]->DLEN, FD);
- {$7d}
- WRITE_RELOC(FP, J, FD);
- IF(!NOGLOB) {$7b}
- WRITE_GLOBALS(FD);
- {$7d} ELSE {$7b}
- FPUTC(0,FD);
- FPUTC(0,FD);
- {$7d}
-
- FCLOSE(FD);
- RETURN 0;
- {$7d}
-
- /***************************************************************************/
-
- INT WRITE_OPTIONS(file *FP, FILE65 *FILE) {$7b}
- RETURN FWRITE(FILE->BUF+buf, 1, FILE->TPOS-buf-1, FP);
- {$7d}
-
- INT READ_OPTIONS(UNSIGNED CHAR *BUF) {$7b}
- INT C, L=0;
-
- C=BUF[0];
- WHILE(C && C!=eof) {$7b}
- C&=255;
- L+=C;
- C=BUF[L];
- {$7d}
- RETURN ++L;
- {$7d}
-
- INT READ_UNDEF(UNSIGNED CHAR *BUF, FILE65 *FILE) {$7b}
- INT I, N, L = 2, LL;
-
- N = BUF[0] + 256*BUF[1];
-
- FILE->NUNDEF = N;
- FILE->UD = MALLOC(N*SIZEOF(UNDEFS));
- IF(!FILE->UD) {$7b}
- FPRINTF(STDERR,"oOPS, NO MORE MEMORY\N");
- EXIT(1);
- {$7d}
- I=0;
- WHILE(I<N){$7b}
- FILE->UD[I].NAME = (CHAR*) BUF+L;
- LL=L;
- WHILE(BUF[L++]);
- FILE->UD[I].LEN = L-LL-1;
- /*PRINTF("READ UNDEF '%S'(%P), LEN=%D, LL=%D, L=%D\N",
- FILE->UD[I].NAME, FILE->UD[I].NAME, FILE->UD[I].LEN,LL,L);*/
- I++;
- {$7d}
- /*PRINTF("RETURN L=%D\N",L);*/
- RETURN L;
- {$7d}
-
- INT LEN_RELOC_SEG(UNSIGNED CHAR *BUF, INT RI) {$7b}
- INT TYPE, SEG;
-
- /*PRINTF("TDIFF=%04X, DDIFF=%04X, BDIFF=%04X, ZDIFF=%04X\N",
- FP->TDIFF, FP->DDIFF, FP->BDIFF, FP->ZDIFF);*/
- WHILE(BUF[RI]) {$7b}
- IF((BUF[RI] & 255) == 255) {$7b}
- RI++;
- {$7d} ELSE {$7b}
- RI++;
- TYPE = BUF[RI] & 0XE0;
- SEG = BUF[RI] & 0X07;
- /*PRINTF("RELOC ENTRY @ RTAB=%P (OFFSET=%D), ADR=%04X, TYPE=%02X, SEG=%D\N",BUF+RI-1, *(BUF+RI-1), ADR, TYPE, SEG);*/
- RI++;
- SWITCH(TYPE) {$7b}
- CASE 0X80:
- BREAK;
- CASE 0X40:
- RI++;
- BREAK;
- CASE 0X20:
- BREAK;
- {$7d}
- IF(SEG==0) RI+=2;
- {$7d}
- {$7d}
- RETURN ++RI;
- {$7d}
-
- #DEFINERELDIFF(S) (((S)==2)?FP->TDIFF:(((S)==3)?FP->DDIFF:(((S)==4)?FP->BDIFF:(((S)==5)?FP->ZDIFF:0))))
-
- UNSIGNED CHAR *RELOC_GLOBALS(UNSIGNED CHAR *BUF, FILE65 *FP) {$7b}
- INT N, OLD, NEW, SEG;
-
- N = BUF[0] + 256*BUF[1];
- BUF +=2;
-
- WHILE(N) {$7b}
- /*PRINTF("RELOCATING %S, ", BUF);*/
- WHILE(*(BUF++));
- SEG = *BUF;
- OLD = BUF[1] + 256*BUF[2];
- NEW = OLD + RELDIFF(SEG);
- /*PRINTF("OLD=%04X, SEG=%D, REL=%04X, NEW=%04X\N", OLD, SEG, RELDIFF(SEG), NEW);*/
- BUF[1] = NEW & 255;
- BUF[2] = (NEW>>8) & 255;
- BUF +=3;
- N--;
- {$7d}
- RETURN BUF;
- {$7d}
-
- /***************************************************************************/
-
- FILE65 *LOAD_FILE(CHAR *FNAME) {$7b}
- FILE65 *FILE;
- STRUCT STAT FS;
- file *FP;
- INT MODE, HLEN;
- SIZE_T N;
-
- FILE=MALLOC(SIZEOF(FILE65));
- IF(!FILE) {$7b}
- FPRINTF(STDERR,"oOPS, NOT ENOUGH MEMORY!\N");
- EXIT(1);
- {$7d}
-
- /*PRINTF("LOAD_FILE(%S)\N",FNAME);*/
-
- FILE->FNAME=FNAME;
- STAT(FNAME, &FS);
- FILE->FSIZE=FS.ST_SIZE;
- FILE->BUF=MALLOC(FILE->FSIZE);
- IF(!FILE->BUF) {$7b}
- FPRINTF(STDERR,"oOPS, NO MORE MEMORY!\N");
- EXIT(1);
- {$7d}
-
- FP = FOPEN(FNAME,"RB");
- IF(FP) {$7b}
- N = FREAD(FILE->BUF, 1, FILE->FSIZE, FP);
- FCLOSE(FP);
- IF((N>=FILE->FSIZE) && (!MEMCMP(FILE->BUF, CMP, 5))) {$7b}
- MODE=FILE->BUF[7]*256+FILE->BUF[6];
- IF(MODE & 0X2000) {$7b}
- FPRINTF(STDERR,"FILE65: %S: 32 BIT SIZE NOT SUPPORTED\N", FNAME);
- FREE(FILE->BUF); FREE(FILE); FILE=null;
- {$7d} ELSE
- IF(MODE & 0X4000) {$7b}
- FPRINTF(STDERR,"FILE65: %S: PAGEWISE RELOCATION NOT SUPPORTED\N",
- FNAME);
- FREE(FILE->BUF); FREE(FILE); FILE=null;
- {$7d} ELSE {$7b}
- HLEN = buf+READ_OPTIONS(FILE->BUF+buf);
-
- FILE->TBASE = FILE->BUF[ 9]*256+FILE->BUF[ 8];
- FILE->TLEN = FILE->BUF[11]*256+FILE->BUF[10];
- FILE->DBASE = FILE->BUF[13]*256+FILE->BUF[12];
- FILE->DLEN = FILE->BUF[15]*256+FILE->BUF[14];
- FILE->BBASE = FILE->BUF[17]*256+FILE->BUF[16];
- FILE->BLEN = FILE->BUF[19]*256+FILE->BUF[18];
- FILE->ZBASE = FILE->BUF[21]*256+FILE->BUF[20];
- FILE->ZLEN = FILE->BUF[23]*256+FILE->BUF[21];
-
- FILE->TPOS = HLEN;
- FILE->DPOS = HLEN + FILE->TLEN;
- FILE->UPOS = FILE->DPOS + FILE->DLEN;
- FILE->TRPOS= FILE->UPOS + READ_UNDEF(FILE->BUF+FILE->UPOS, FILE);
- FILE->DRPOS= LEN_RELOC_SEG(FILE->BUF, FILE->TRPOS);
- FILE->GPOS = LEN_RELOC_SEG(FILE->BUF, FILE->DRPOS);
- {$7d}
- {$7d} ELSE
- FPRINTF(STDERR,"FILE65: %S: %S\N", FNAME, STRERROR(ERRNO));
- {$7d} ELSE
- FPRINTF(STDERR,"FILE65: %S: %S\N", FNAME, STRERROR(ERRNO));
-
- RETURN FILE;
- {$7d}
-
- /***************************************************************************/
-
- GLOB *GP = null;
- INT GM=0;
- INT G=0;
-
- INT WRITE_RELOC(FILE65 *FP[], INT NFP, file *F) {$7b}
- INT TPC, PC, I;
- UNSIGNED CHAR *P;
- INT LOW, SEG, TYP, LAB;
-
- /* NO UNDEFINED LABLES ? todo */
- FPUTC(0,F);
- FPUTC(0,F);
-
- TPC = FP[0]->TBASE-1;
-
- FOR(I=0;I<NFP;I++) {$7b}
- PC = FP[I]->TBASE-1;
- P = FP[I]->BUF + FP[I]->TRPOS;
-
- WHILE(*P) {$7b}
- WHILE((*P)==255) {$7b} PC+=254; P++; {$7d}
- PC+=*(P++);
- SEG=(*P)&7;
- TYP=(*P)&0XE0;
- IF(TYP==0X40) LOW=*(++P);
- P++;
- IF(SEG==0) {$7b}
- LAB=P[0]+256*P[1];
- SEG=GP[LAB].SEG;
- P+=2;
- {$7d}
- IF(SEG>1) {$7b}
- WHILE(PC-TPC>254) {$7b}
- FPUTC(255,F);
- TPC+=254;
- {$7d}
- FPUTC(PC-TPC, F);
- TPC=PC;
- FPUTC(TYP {$7c} SEG, F);
- IF(TYP==0X40) {$7b}
- FPUTC(LOW,F);
- {$7d}
- {$7d}
- {$7d}
- {$7d}
- FPUTC(0,F);
-
- TPC = FP[0]->DBASE-1;
-
- FOR(I=0;I<NFP;I++) {$7b}
- PC = FP[I]->DBASE-1;
- P = FP[I]->BUF + FP[I]->DRPOS;
-
- WHILE(*P) {$7b}
- WHILE((*P)==255) {$7b} PC+=254; P++; {$7d}
- PC+=*(P++);
- SEG=(*P)&7;
- TYP=(*P)&0XE0;
- IF(TYP==0X40) LOW=*(++P);
- P++;
- IF(SEG==0) {$7b}
- LAB=P[0]+256*P[1];
- SEG=GP[LAB].SEG;
- P+=2;
- {$7d}
- IF(SEG>1) {$7b}
- WHILE(PC-TPC>254) {$7b}
- FPUTC(255,F);
- TPC+=254;
- {$7d}
- FPUTC(PC-TPC, F);
- TPC=PC;
- FPUTC(TYP {$7c} SEG, F);
- IF(TYP==0X40) {$7b}
- FPUTC(LOW,F);
- {$7d}
- {$7d}
- {$7d}
- {$7d}
- FPUTC(0,F);
-
- RETURN 0;
- {$7d}
-
- INT WRITE_GLOBALS(file *FP) {$7b}
- INT I;
-
- FPUTC(G&255, FP);
- FPUTC((G>>8)&255, FP);
-
- FOR(I=0;I<G;I++) {$7b}
- FPRINTF(FP,"%S%C%C%C%C",GP[I].NAME,0,GP[I].SEG,
- GP[I].VAL & 255, (GP[I].VAL>>8)&255);
- {$7d}
- RETURN 0;
- {$7d}
-
- INT READ_GLOBALS(FILE65 *FP) {$7b}
- INT I, L, N, OLD, NEW, SEG, LL;
- CHAR *NAME;
- UNSIGNED CHAR *BUF = FP->BUF + FP->GPOS;
-
- N = BUF[0] + 256*BUF[1];
- BUF +=2;
-
- WHILE(N) {$7b}
- /*PRINTF("READING %S, ", BUF);*/
- NAME = (CHAR*) BUF;
- L=0;
- WHILE(BUF[L++]);
- BUF+=L;
- LL=L-1;
- SEG = *BUF;
- OLD = BUF[1] + 256*BUF[2];
- NEW = OLD + RELDIFF(SEG);
- /*PRINTF("OLD=%04X, SEG=%D, REL=%04X, NEW=%04X\N", OLD, SEG, RELDIFF(SEG), NEW);*/
-
- /* MULTIPLY DEFINED? */
- FOR(I=0;I<G;I++) {$7b}
- IF(LL==GP[I].LEN && !STRCMP(NAME, GP[I].NAME)) {$7b}
- FPRINTF(STDERR,"wARNING: LABEL '%S' MULTIPLY DEFINED (%S AND %S)\N",
- NAME, FP->FNAME, GP[I].FILE->FNAME);
- GP[I].FL = 1;
- BREAK;
- {$7d}
- {$7d}
- /* NOT ALREADY DEFINED */
- IF(I>=G) {$7b}
- IF(G>=GM) {$7b}
- GP = REALLOC(GP, (GM=(GM?2*GM:40))*SIZEOF(GLOB));
- IF(!GP) {$7b}
- FPRINTF(STDERR,"oOPS, NO MORE MEMORY\N");
- EXIT(1);
- {$7d}
- {$7d}
- IF(G>=0X10000) {$7b}
- FPRINTF(STDERR,"oUTCH, MAXIMUM NUMBER OF LABELS (65536) EXCEEDED!\N");
- EXIT(3);
- {$7d}
- GP[G].NAME = NAME;
- GP[G].LEN = LL;
- GP[G].SEG = SEG;
- GP[G].VAL = NEW;
- GP[G].FL = 0;
- GP[G].FILE = FP;
- /*PRINTF("SET LABEL '%S' (L=%D, SEG=%D, VAL=%04X)\N", GP[G].NAME,
- GP[G].LEN, GP[G].SEG, GP[G].VAL);*/
- G++;
- {$7d}
-
- BUF +=3;
- N--;
- {$7d}
- RETURN 0;
- {$7d}
-
- INT FIND_GLOBAL(UNSIGNED CHAR *BP, FILE65 *FP, INT *SEG) {$7b}
- INT I,L;
- CHAR *N;
- INT NL = BP[0]+256*BP[1];
-
- L=FP->UD[NL].LEN;
- N=FP->UD[NL].NAME;
- /*PRINTF("FIND_GLOBAL(%S (LEN=%D))\N",N,L);*/
-
- FOR(I=0;I<G;I++) {$7b}
- IF(GP[I].LEN == L && !STRCMP(GP[I].NAME, N)) {$7b}
- *SEG = GP[I].SEG;
- BP[0] = I & 255; BP[1] = (I>>8) & 255;
- /*PRINTF("RETURN GP[%D]=%S (LEN=%D), VAL=%04X\N",I,GP[I].NAME,GP[I].LEN,GP[I].VAL);*/
- RETURN GP[I].VAL;
- {$7d}
- {$7d}
- FPRINTF(STDERR,"wARNING: UNDEFINED LABEL '%S' IN FILE %S\N",
- N, FP->FNAME);
- RETURN 0;
- {$7d}
-
- INT RELOC_SEG(UNSIGNED CHAR *BUF, INT ADR, INT RI, INT *LRELOC, FILE65 *FP) {$7b}
- INT TYPE, SEG, OLD, NEW;
-
- ADR--;
- /*PRINTF("TDIFF=%04X, DDIFF=%04X, BDIFF=%04X, ZDIFF=%04X\N",
- FP->TDIFF, FP->DDIFF, FP->BDIFF, FP->ZDIFF);*/
- WHILE(BUF[RI]) {$7b}
- IF((BUF[RI] & 255) == 255) {$7b}
- ADR += 254;
- RI++;
- {$7d} ELSE {$7b}
- ADR += BUF[RI] & 255;
- RI++;
- TYPE = BUF[RI] & 0XE0;
- SEG = BUF[RI] & 0X07;
- /*PRINTF("RELOC ENTRY @ RTAB=%P (OFFSET=%D), ADR=%04X, TYPE=%02X, SEG=%D\N",BUF+RI-1, *(BUF+RI-1), ADR, TYPE, SEG);*/
- RI++;
- SWITCH(TYPE) {$7b}
- CASE 0X80:
- OLD = BUF[ADR] + 256*BUF[ADR+1];
- IF(SEG) NEW = OLD + RELDIFF(SEG);
- ELSE NEW = OLD + FIND_GLOBAL(BUF+RI, FP, &SEG);
- /*PRINTF("OLD=%04X, NEW=%04X\N",OLD,NEW);*/
- BUF[ADR] = NEW & 255;
- BUF[ADR+1] = (NEW>>8)&255;
- BREAK;
- CASE 0X40:
- OLD = BUF[ADR]*256 + BUF[RI];
- IF(SEG) NEW = OLD + RELDIFF(SEG);
- ELSE NEW = OLD + FIND_GLOBAL(BUF+RI+1, FP, &SEG);
- BUF[ADR] = (NEW>>8)&255;
- BUF[RI] = NEW & 255;
- RI++;
- BREAK;
- CASE 0X20:
- OLD = BUF[ADR];
- IF(SEG) NEW = OLD + RELDIFF(SEG);
- ELSE NEW = OLD + FIND_GLOBAL(BUF+RI, FP, &SEG);
- BUF[ADR] = NEW & 255;
- BREAK;
- {$7d}
- IF(SEG==0) RI+=2;
- {$7d}
- {$7d}
- *LRELOC = ADR;
- RETURN ++RI;
- {$7d}
-
-
-