home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CBM Funet Archive
/
cbm-funet-archive-2003.iso
/
cbm
/
programming
/
msdos
/
xa214f.lzh
/
xa214f
/
src
/
xa.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-20
|
22KB
|
885 lines
/*
XA65 - 6502 CROSS ASSEMBLER AND UTILITY SUITE
cOPYRIGHT (c) 1989-1998 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 <CTYPE.H>
#INCLUDE <STRING.H>
#INCLUDE <STDIO.H>
#INCLUDE <STDLIB.H>
#INCLUDE <UNISTD.H>
#INCLUDE <TIME.H>
/* STRUCTS AND DEFS */
#INCLUDE "XAH.H"
#INCLUDE "XAH2.H"
/* EXPORTED FUNCTIONS ARE DEFINED HERE */
#INCLUDE "XAR.H"
#INCLUDE "XA.H"
#INCLUDE "XAM.H"
#INCLUDE "XAL.H"
#INCLUDE "XAP.H"
#INCLUDE "XAT.H"
#INCLUDE "XAO.H"
/* EXPORTED GLOBALS */
INT NCMOS,CMOSFL;
INT MASM = 0;
INT NOLINK = 0;
INT ROMABLE = 0;
INT ROMADR = 0;
INT NOGLOB = 0;
INT SHOWBLK = 0;
/* LOCAL VARIABLES */
STATIC CONST CHAR *COPYRIGHT={$7b}
"cROSS-aSSEMBLER 65XX v2.1.4F 20APR1998 (C) 1989-98 BY a.fACHAT\N"{$7d};
STATIC CHAR OUT[maxline];
STATIC TIME_T TIM1,TIM2;
STATIC file *FPOUT,*FPERR,*FPLAB;
STATIC INT NER = 0;
STATIC INT ALIGN = 1;
STATIC VOID PRINTSTAT(VOID);
STATIC VOID USAGE(VOID);
STATIC INT SETFEXT(CHAR*,CHAR*);
STATIC INT X_INIT(VOID);
STATIC INT PASS1(VOID);
STATIC INT PASS2(VOID);
STATIC INT PUTTMP(INT);
STATIC INT PUTTMPS(SIGNED CHAR*,INT);
STATIC VOID CHRPUT(INT);
STATIC INT GETLINE(CHAR*);
STATIC VOID LINEOUT(VOID);
STATIC LONG GA_P1(VOID);
STATIC LONG GM_P1(VOID);
/* TEXT */
INT SEGMENT;
INT TLEN=0, TBASE=0X1000;
INT DLEN=0, DBASE=0X0400;
INT BLEN=0, BBASE=0X4000;
INT ZLEN=0, ZBASE=4;
INT FMODE=0;
INT RELMODE=0;
INT PC[seg_max];/* SEGMENTS */
INT MAIN(INT ARGC,CHAR *ARGV[])
{$7b}
INT ER=1,I;
SIGNED CHAR *S=null;
INT MIFILES = 5;
INT NIFILES = 0;
INT VERBOSE = 0;
INT OLDFILE = 0;
INT NO_LINK = 0;
CHAR **IFILES;
CHAR *OFILE;
CHAR *EFILE;
CHAR *LFILE;
CHAR *IFILE;
CHAR OLD_E[maxline];
CHAR OLD_L[maxline];
CHAR OLD_O[maxline];
TIM1=TIME(null);
NCMOS=0;
CMOSFL=1;
IFILES = MALLOC(MIFILES*SIZEOF(CHAR*));
AFILE = ALLOC_FILE();
IF(ARGC<=1)
{$7b}
USAGE();
RETURN(1);
{$7d}
OFILE="A.O65";
EFILE=null;
LFILE=null;
IF(PP_INIT()) {$7b}
LOGOUT("FATAL: PP: NO MEMORY!");
RETURN 1;
{$7d}
IF(B_INIT()) {$7b}
LOGOUT("FATAL: B: NO MEMORY!");
RETURN 1;
{$7d}
IF(L_INIT()) {$7b}
LOGOUT("FATAL: L: NO MEMORY!");
RETURN 1;
{$7d}
I=1;
WHILE(I<ARGC) {$7b}
IF(ARGV[I][0]=='-') {$7b}
SWITCH(ARGV[I][1]) {$7b}
CASE 'm':
MASM = 1;/* masm COMPATIBILITY MODE */
BREAK;
CASE 'a':/* MAKE TEXT SEGMENT START SO THAT TEXT RELOCATION
IS NOT NECESSARY WHEN _FILE_ STARTS AT ADR */
ROMABLE = 2;
IF(ARGV[I][2]==0) ROMADR = ATOI(ARGV[++I]);
ELSE ROMADR = ATOI(ARGV[I]+2);
BREAK;
CASE 'g':
NOGLOB = 1;
BREAK;
CASE 'l':/* DEFINE GLOBAL LABEL */
IF(ARGV[I][2]) LG_SET(ARGV[I]+2);
BREAK;
CASE 'r':
RELMODE = 1;
BREAK;
CASE 'd':
S = (SIGNED CHAR*)STRSTR(ARGV[I]+2,"=");
IF(S) *S = ' ';
PP_DEFINE(ARGV[I]+2);
BREAK;
CASE 'C':
NO_LINK = 1;
FMODE {$7c}= fm_obj;
BREAK;
CASE 'V':
VERBOSE = 1;
BREAK;
CASE 'c':
CMOSFL = 0;
BREAK;
CASE 'b':
SHOWBLK = 1;
BREAK;
CASE 'X':/* OLD FILENAME BEHAVIOUR */
OLDFILE = 1;
BREAK;
CASE 'i':
IF(ARGV[I][2]==0) {$7b}
REG_INCLUDE(ARGV[++I]);
{$7d} ELSE {$7b}
REG_INCLUDE(ARGV[I]+2);
{$7d}
BREAK;
CASE 'O':
IF(ARGV[I][2]==0) {$7b}
OFILE=ARGV[++I];
{$7d} ELSE {$7b}
OFILE=ARGV[I]+2;
{$7d}
BREAK;
CASE 'L':
IF(ARGV[I][2]==0) {$7b}
LFILE=ARGV[++I];
{$7d} ELSE {$7b}
LFILE=ARGV[I]+2;
{$7d}
BREAK;
CASE 'E':
IF(ARGV[I][2]==0) {$7b}
EFILE=ARGV[++I];
{$7d} ELSE {$7b}
EFILE=ARGV[I]+2;
{$7d}
BREAK;
CASE 'B':/* SET SEGMENT BASE ADDRESSES */
SWITCH(ARGV[I][2]) {$7b}
CASE 'T':
IF(ARGV[I][3]==0) TBASE = ATOI(ARGV[++I]);
ELSE TBASE = ATOI(ARGV[I]+3);
BREAK;
CASE 'D':
IF(ARGV[I][3]==0) DBASE = ATOI(ARGV[++I]);
ELSE DBASE = ATOI(ARGV[I]+3);
BREAK;
CASE 'B':
IF(ARGV[I][3]==0) BBASE = ATOI(ARGV[++I]);
ELSE BBASE = ATOI(ARGV[I]+3);
BREAK;
CASE 'Z':
IF(ARGV[I][3]==0) ZBASE = ATOI(ARGV[++I]);
ELSE ZBASE = ATOI(ARGV[I]+3);
BREAK;
DEFAULT:
FPRINTF(STDERR,"UNKNOW SEGMENT TYPE '%C' - IGNORING!\N",
ARGV[I][2]);
BREAK;
{$7d}
BREAK;
CASE 0:
FPRINTF(STDERR, "sINGLE DASH '-' ON COMMAND LINE - IGNORING!\N");
BREAK;
DEFAULT:
FPRINTF(STDERR, "uNKNOWN OPTION '%C' - IGNORING!\N",ARGV[I][1]);
BREAK;
{$7d}
{$7d} ELSE {$7b}/* NO OPTION -> FILENAME */
IFILES[NIFILES++] = ARGV[I];
IF(NIFILES>=MIFILES) {$7b}
MIFILES += 5;
IFILES=REALLOC(IFILES, MIFILES*SIZEOF(CHAR*));
IF(!IFILES) {$7b}
FPRINTF(STDERR, "oOPS: COULDN'T ALLOC ENOUGH MEM FOR FILELIST TABLE..!\N");
EXIT(1);
{$7d}
{$7d}
{$7d}
I++;
{$7d}
IF(!NIFILES) {$7b}
FPRINTF(STDERR, "nO INPUT FILES GIVEN!\N");
EXIT(0);
{$7d}
IF(OLDFILE) {$7b}
STRCPY(OLD_E, IFILES[0]);
STRCPY(OLD_O, IFILES[0]);
STRCPY(OLD_L, IFILES[0]);
IF(SETFEXT(OLD_E,".ERR")==0) EFILE = OLD_E;
IF(SETFEXT(OLD_O,".OBJ")==0) OFILE = OLD_O;
IF(SETFEXT(OLD_L,".LAB")==0) LFILE = OLD_L;
{$7d}
FPLAB= LFILE ? XFOPEN(LFILE,"W") : null;
FPERR= EFILE ? XFOPEN(EFILE,"W") : null;
IF(!STRCMP(OFILE,"-")) {$7b}
OFILE=null;
FPOUT = STDOUT;
{$7d} ELSE {$7b}
FPOUT= XFOPEN(OFILE,"WB");
{$7d}
IF(!FPOUT) {$7b}
FPRINTF(STDERR, "cOULDN'T OPEN OUTPUT FILE!\N");
EXIT(1);
{$7d}
IF(VERBOSE) FPRINTF(STDERR, "%S",COPYRIGHT);
IF(1 /*!M_INIT()*/)
{$7b}
IF(1 /*!B_INIT()*/)
{$7b}
IF(1 /*!L_INIT()*/)
{$7b}
/*IF(!PP_INIT())*/
{$7b}
IF(!X_INIT())
{$7b}
IF(FPERR) FPRINTF(FPERR,"%S",COPYRIGHT);
IF(VERBOSE) LOGOUT(CTIME(&TIM1));
/* pASS 1 */
PC[seg_abs]= 0;/* ABS ADDRESSING */
SEG_START(FMODE, TBASE, DBASE, BBASE, ZBASE, 0, RELMODE);
IF(RELMODE) {$7b}
R_MODE(rmode_reloc);
SEGMENT = seg_text;
{$7d} ELSE {$7b}
R_MODE(rmode_abs);
{$7d}
NOLINK = NO_LINK;
FOR (I=0; I<NIFILES; I++)
{$7b}
IFILE = IFILES[I];
SPRINTF(OUT,"XaSS65: pASS 1: %S\N",IFILE);
IF(VERBOSE) LOGOUT(OUT);
ER=PP_OPEN(IFILE);
IF(!ER) {$7b}
ER=PASS1();
PP_CLOSE();
{$7d} ELSE {$7b}
SPRINTF(OUT, "cOULDN'T OPEN SOURCE FILE '%S'!\N", IFILE);
LOGOUT(OUT);
{$7d}
{$7d}
IF((ER=B_DEPTH())) {$7b}
SPRINTF(OUT,"sTILL %D BLOCKS OPEN AT END OF FILE!\N",ER);
LOGOUT(OUT);
{$7d}
IF(TBASE & (ALIGN-1)) {$7b}
SPRINTF(OUT,"wARNING: TEXT SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", TBASE, ALIGN);
LOGOUT(OUT);
{$7d}
IF(DBASE & (ALIGN-1)) {$7b}
SPRINTF(OUT,"wARNING: DATA SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", DBASE, ALIGN);
LOGOUT(OUT);
{$7d}
IF(BBASE & (ALIGN-1)) {$7b}
SPRINTF(OUT,"wARNING: BSS SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", BBASE, ALIGN);
LOGOUT(OUT);
{$7d}
IF(ZBASE & (ALIGN-1)) {$7b}
SPRINTF(OUT,"wARNING: ZERO SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", ZBASE, ALIGN);
LOGOUT(OUT);
{$7d}
SWITCH(ALIGN) {$7b}
CASE 1: BREAK;
CASE 2: FMODE {$7c}= 1; BREAK;
CASE 4: FMODE {$7c}= 2; BREAK;
CASE 256: FMODE {$7c}=3; BREAK;
{$7d}
IF((!ER) && RELMODE)
H_WRITE(FPOUT, FMODE, TLEN, DLEN, BLEN, ZLEN, 0);
IF(!ER)
{$7b}
IF(VERBOSE) LOGOUT("XaSS65: pASS 2:\N");
SEG_PASS2();
IF(!RELMODE) {$7b}
R_MODE(rmode_abs);
{$7d} ELSE {$7b}
R_MODE(rmode_reloc);
SEGMENT = seg_text;
{$7d}
ER=PASS2();
{$7d}
IF(FPLAB) PRINTLLIST(FPLAB);
TIM2=TIME(null);
IF(VERBOSE) PRINTSTAT();
IF((!ER) && RELMODE) SEG_END(FPOUT);/* WRITE RELOC/LABEL INFO */
IF(FPERR) FCLOSE(FPERR);
IF(FPLAB) FCLOSE(FPLAB);
IF(FPOUT) FCLOSE(FPOUT);
{$7d} ELSE {$7b}
LOGOUT("FATAL: X: NO MEMORY!\N");
{$7d}
PP_END();
/* {$7d} ELSE {$7b}
LOGOUT("FATAL: PP: NO MEMORY!");*/
{$7d}
{$7d} ELSE {$7b}
LOGOUT("FATAL: L: NO MEMORY!\N");
{$7d}
{$7d} ELSE {$7b}
LOGOUT("FATAL: B: NO MEMORY!\N");
{$7d}
/*M_EXIT();*/
{$7d} ELSE {$7b}
LOGOUT("nOT ENOUGH MEMORY AVAILABLE!\N");
{$7d}
IF(NER {$7c}{$7c} ER)
{$7b}
FPRINTF(STDERR, "bREAK AFTER %D ERROR%C\N",NER,NER?'S':0);
/*UNLINK();*/
IF(OFILE) {$7b}
UNLINK(OFILE);
{$7d}
{$7d}
FREE(IFILES);
RETURN( (ER {$7c}{$7c} NER) ? 1 : 0 );
{$7d}
STATIC VOID PRINTSTAT(VOID)
{$7b}
LOGOUT("sTATISTICS:\N");
SPRINTF(OUT," %8D OF %8D LABEL USED\N",GA_LAB(),GM_LAB()); LOGOUT(OUT);
SPRINTF(OUT," %8LD OF %8LD BYTE LABEL-MEMORY USED\N",GA_LABM(),GM_LABM()); LOGOUT(OUT);
SPRINTF(OUT," %8D OF %8D pp-DEFS USED\N",GA_PP(),GM_PP()); LOGOUT(OUT);
SPRINTF(OUT," %8LD OF %8LD BYTE pp-MEMORY USED\N",GA_PPM(),GM_PPM()); LOGOUT(OUT);
SPRINTF(OUT," %8LD OF %8LD BYTE BUFFER MEMORY USED\N",GA_P1(),GM_P1()); LOGOUT(OUT);
SPRINTF(OUT," %8D BLOCKS USED\N",GA_BLK()); LOGOUT(OUT);
SPRINTF(OUT," %8LD SECONDS USED\N",(LONG)DIFFTIME(TIM2,TIM1)); LOGOUT(OUT);
{$7d}
#DEFINEFPUTW(A,FP)FPUTC((A)&255,FP);FPUTC((A>>8)&255,FP)
INT H_LENGTH(VOID) {$7b}
RETURN 26+O_LENGTH();
{$7d}
#IF 0
/* WRITE HEADER FOR RELOCATABLE OUTPUT FORMAT */
INT H_WRITE(file *FP, INT TBASE, INT TLEN, INT DBASE, INT DLEN,
INT BBASE, INT BLEN, INT ZBASE, INT ZLEN) {$7b}
FPUTC(1, FP);/* VERSION BYTE */
FPUTC(0, FP);/* HI ADDRESS 0 -> NO c64 */
FPUTC("O", FP);
FPUTC("6", FP);
FPUTC("5", FP);
FPUTC(0, FP);/* FORMAT VERSION */
FPUTW(MODE, FP);/* FILE MODE */
FPUTW(TBASE,FP);/* TEXT BASE */
FPUTW(TLEN,FP);/* TEXT LENGTH */
FPUTW(DBASE,FP);/* DATA BASE */
FPUTW(DLEN,FP);/* DATA LENGTH */
FPUTW(BBASE,FP);/* BSS BASE */
FPUTW(BLEN,FP);/* BSS LENGTH */
FPUTW(ZBASE,FP);/* ZEROP BASE */
FPUTW(ZLEN,FP);/* ZEROP LENGTH */
O_WRITE(FP);
RETURN 0;
{$7d}
#ENDIF
STATIC INT SETFEXT(CHAR *S, CHAR *EXT)
{$7b}
INT J,I=(INT)STRLEN(S);
IF(I>maxline-5)
RETURN(-1);
FOR(J=I-1;J>=0;J--)
{$7b}
IF(S[J]==dirchar)
{$7b}
STRCPY(S+I,EXT);
BREAK;
{$7d}
IF(S[J]=='.')
{$7b}
STRCPY(S+J,EXT);
BREAK;
{$7d}
{$7d}
IF(!J)
STRCPY(S+I,EXT);
RETURN(0);
{$7d}
/*
STATIC CHAR *TMP;
STATIC UNSIGNED LONG TMPZ;
STATIC UNSIGNED LONG TMPE;
*/
STATIC LONG GA_P1(VOID)
{$7b}
RETURN(AFILE->MN.TMPZ);
{$7d}
STATIC LONG GM_P1(VOID)
{$7b}
RETURN(tmpmem);
{$7d}
#IFNDEF ABS
#DEFINE ABS(A) ((A)>=0 ? A : -A)
#ENDIF
STATIC INT PASS2(VOID)
{$7b}
INT C,ER,L,LL,I,AL;
dATEI DATEI;
SIGNED CHAR *DATASEG=null;
SIGNED CHAR *DATAP=null;
IF((DATASEG=MALLOC(DLEN))) {$7b}
IF(!DATASEG) {$7b}
FPRINTF(STDERR, "cOULDN'T ALLOC DATASEG MEMORY...\N");
EXIT(1);
{$7d}
DATAP=DATASEG;
{$7d}
FILEP=&DATEI;
AFILE->MN.TMPE=0l;
WHILE(NER<20 && AFILE->MN.TMPE<AFILE->MN.TMPZ)
{$7b}
L=AFILE->MN.TMP[AFILE->MN.TMPE++];
LL=L;
IF(!L)
{$7b}
IF(AFILE->MN.TMP[AFILE->MN.TMPE]==t_line)
{$7b}
DATEI.FLINE=(AFILE->MN.TMP[AFILE->MN.TMPE+1]&255)+(AFILE->MN.TMP[AFILE->MN.TMPE+2]<<8);
AFILE->MN.TMPE+=3;
{$7d} ELSE
IF(AFILE->MN.TMP[AFILE->MN.TMPE]==t_file)
{$7b}
DATEI.FLINE=(AFILE->MN.TMP[AFILE->MN.TMPE+1]&255)+(AFILE->MN.TMP[AFILE->MN.TMPE+2]<<8);
STRCPY(DATEI.FNAME,(CHAR*) AFILE->MN.TMP+AFILE->MN.TMPE+3);
AFILE->MN.TMPE+=3+STRLEN(DATEI.FNAME);
{$7d}
{$7d} ELSE
{$7b}
ER=T_P2(AFILE->MN.TMP+AFILE->MN.TMPE,&LL,0,&AL);
IF(ER==e_noline)
{$7b}
{$7d} ELSE
IF(ER==e_ok)
{$7b}
IF(SEGMENT<seg_data) {$7b}
FOR(I=0;I<LL;I++)
CHRPUT(AFILE->MN.TMP[AFILE->MN.TMPE+I]);
{$7d} ELSE IF (SEGMENT==seg_data && DATAP) {$7b}
MEMCPY(DATAP,AFILE->MN.TMP+AFILE->MN.TMPE,LL);
DATAP+=LL;
{$7d}
{$7d} ELSE
IF(ER==e_dsb)
{$7b}
C=AFILE->MN.TMP[AFILE->MN.TMPE];
IF(SEGMENT<seg_data) {$7b}
/*PRINTF("e_dsb, LL=%D, L=%D, C=%C\N",LL,L,AFILE->MN.TMP[AFILE->MN.TMPE]);*/
FOR(I=0;I<LL;I++)
CHRPUT(C);
{$7d} ELSE IF (SEGMENT==seg_data && DATAP) {$7b}
MEMSET(DATAP, C, LL);
DATAP+=LL;
{$7d}
{$7d} ELSE
{$7b}
ERROUT(ER);
{$7d}
{$7d}
AFILE->MN.TMPE+=ABS(L);
{$7d}
IF(RELMODE) {$7b}
IF((LL=FWRITE(DATASEG, 1, DLEN, FPOUT))<DLEN) {$7b}
FPRINTF(STDERR, "pROBLEMS WRITING %D BYTES, RETURN GIVES %D\N",DLEN,LL);
{$7d}
{$7d}
RETURN(NER);
{$7d}
STATIC INT PASS1(VOID)
{$7b}
SIGNED CHAR O[maxline];
INT L,ER, AL;
TLEN=0;
NER=0;
WHILE(!(ER=GETLINE(S)))
{$7b}
ER=T_P1((SIGNED CHAR*)S,O,&L,&AL);
SWITCH(SEGMENT) {$7b}
CASE seg_abs:
CASE seg_text: TLEN += AL; BREAK;
CASE seg_data: DLEN += AL; BREAK;
CASE seg_bss : BLEN += AL; BREAK;
CASE seg_zero: ZLEN += AL; BREAK;
{$7d}
/*PRINTF(": ER= %D, L=%D, TMPZ=%D\N",ER,L,TMPZ);*/
IF(L)
{$7b}
IF(ER)
{$7b}
IF(ER==e_okdef)
{$7b}
IF(!(ER=PUTTMP(L)))
ER=PUTTMPS(O,L);
{$7d} ELSE
IF(ER==e_noline)
ER=e_ok;
{$7d} ELSE
{$7b}
IF(!(ER=PUTTMP(-L)))
ER=PUTTMPS(O,L);
{$7d}
{$7d}
IF(ER)
{$7b}
LINEOUT();
ERROUT(ER);
{$7d}
/* PRINTF("TMPZ =%D\N",AFILE->MN.TMPZ);
*/
{$7d}
IF(ER!=e_eof)
ERROUT(ER);
/*{$7b} INT I; PRINTF("pASS 1 \N");
FOR(I=0;I<AFILE->MN.TMPZ;I++)
FPRINTF(STDERR, " %02X",AFILE->MN.TMP[I]);
GETCHAR();{$7d}*/
RETURN(NER);
{$7d}
STATIC VOID USAGE(VOID)
{$7b}
FPRINTF(STDERR, "%S",COPYRIGHT);
FPRINTF(STDERR, "USAGE : XA {$7b} OPTION {$7c} SOURCEFILE {$7d}\N"
"OPTIONS:\N"
" -V = VERBOSE OUTPUT\N"
" -X = OLD FILENAME BEHAVIOUR (OVERRIDES -O, -E, -L)\N"
" -c = NO cmos-OPCODES\N"
" -b = SHOW LINES WITH BLOCK OPEN/CLOSE\N"
" -C = PRODUCE O65 OBJECT INSTEAD OF EXECUTABLE FILES (I.E. DO NOT LINK)\N"
" -O FILENAME = SETS OUTPUT FILENAME, DEFAULT IS 'A.O65'\N"
" a FILENAME OF '-' SETS STDOUT AS OUTPUT FILE\N"
" -E FILENAME = SETS ERRORLOG FILENAME, DEFAULT IS NONE\N"
" -L FILENAME = SETS LABELLIST FILENAME, DEFAULT IS NONE\N"
" -m = ALLOW \":\" TO APPEAR IN COMMENTS, FOR masm COMPATIBILITY\N"
" -r = START ASSEMBLER IN RELOCATING MODE\N"
" -lLABEL = DEFINES 'LABEL' AS ABSOLUTE, UNDEFINED LABEL EVEN WHEN LINKING\N"
" -B? ADR = SET SEGMENT BASE ADDRESS TO INTEGER VALUE ADR. \N"
" '?' STANDS FOR T(EXT), D(ATA), B(SS) AND Z(ERO) SEGMENT\N"
" (ADDRESS CAN BE GIVEN MORE THAN ONCE, LATEST IS TAKEN)\N"
" -a ADR = MAKE TEXT SEGMENT START AT AN ADDRESS THAT WHEN THE _FILE_\N"
" STARTS AT ADR, RELOCATION IS NOT NECESSARY. oVERRIDES -BT\N"
" oTHER SEGMENTS HAVE TO BE TAKE CARE OF WITH -B?\N"
" -g = SUPPRESS LIST OF EXPORTED GLOBALS\N"
" -ddef=text = DEFINES A PREPROCESSOR REPLACEMENT\N"
" -iDIR = ADD DIRECTORY 'DIR' TO INCLUDE PATH (BEFORE xainput)\N"
"eNVIRONMENT:\N"
" xainput = INCLUDE FILE PATH; COMPONENTS DIVIDED BY ','\N"
" xaoutput= OUTPUT FILE PATH\N"
);
{$7d}
#DEFINE anzerr 30
#DEFINE anzwarn 6
/*
STATIC CHAR *ERTXT[] = {$7b} "sYNTAX","lABEL DEFINIERT",
"lABEL NICHT DEFINIERT","lABELTABELLE VOLL",
"lABEL ERWARTET","sPEICHER VOLL","iLLEGALER oPCODE",
"fALSCHE aDRESSIERUNGSART","bRANCH AUSSERHALB DES bEREICHS",
"uEBERLAUF","dIVISION DURCH nULL","pSEUDO-oPCODE ERWARTET",
"bLOCK-sTACK-uEBERLAUF","dATEI NICHT GEFUNDEN",
"eND OF fILE","bLOCK-sTRUKTUR NICHT ABGESCHLOSSEN",
"nObLK","nOkEY","nOlINE","okdEF","dsb","nEWlINE",
"nEWfILE","cmos-bEFEHL","PP:fALSCHE aNZAHL pARAMETER" {$7d};
*/
STATIC CHAR *ERTXT[] = {$7b} "sYNTAX","lABEL DEFINED",
"lABEL NOT DEFINED","lABELTAB FULL",
"lABEL EXPECTED","NO MORE MEMORY","iLLEGAL OPCODE",
"wRONG ADDRESSING MODE","bRANCH OUT OF RANGE",
"oVERFLOW","dIVISION BY ZERO","pSEUDO-OPCODE EXPECTED",
"bLOCK STACK OVERFLOW","FILE NOT FOUND",
"eND OF FILE","tOO MANY BLOCK CLOSE",
"nObLK","nOkEY","nOlINE","okdEF","dsb","nEWlINE",
"nEWfILE","cmos-bEFEHL","PP:wRONG PARAMETER COUNT",
"iLLEGAL POINTER ARITHMETIC", "iLLEGAL SEGMENT",
"fILE HEADER OPTION TOO LONG",
"fILE oPTION NOT AT FILE START (WHEN rom-ABLE)",
"iLLEGAL ALIGN VALUE",
/* WARNINGS START HERE */
"cUTTING WORD RELOCATION IN BYTE VALUE",
"bYTE RELOCATION IN WORD VALUE",
"iLLEGAL POINTER ARITHMETIC",
"aDDRESS ACCESS TO LOW OR HIGH BYTE POINTER",
"hIGH BYTE ACCESS TO LOW BYTE POINTER",
"lOW BYTE ACCESS TO HIGH BYTE POINTER" {$7d};
STATIC INT GL;
STATIC INT GF;
STATIC INT X_INIT(VOID)
{$7b}
RETURN 0;
#IF 0
INT ER=0;
/*ER=M_ALLOC(tmpmem,&TMP);*/
AFILE->MN.TMP=MALLOC(tmpmem);
IF(!AFILE->MN.TMP) ER=e_nomem;
AFILE->MN.TMPZ=0l;
RETURN(ER);
#ENDIF
{$7d}
STATIC INT PUTTMP(INT C)
{$7b}
INT ER=e_nomem;
/*PRINTF("PUTTMP: AFILE=%P, TMP=%P, TMPZ=%D\N",AFILE, AFILE?AFILE->MN.TMP:0, AFILE?AFILE->MN.TMPZ:0);*/
IF(AFILE->MN.TMPZ<tmpmem)
{$7b}
AFILE->MN.TMP[AFILE->MN.TMPZ++]=C;
ER=e_ok;
{$7d}
RETURN(ER);
{$7d}
STATIC INT PUTTMPS(SIGNED CHAR *S, INT L)
{$7b}
INT I=0,ER=e_nomem;
IF(AFILE->MN.TMPZ+L<tmpmem)
{$7b}
WHILE(I<L)
AFILE->MN.TMP[AFILE->MN.TMPZ++]=S[I++];
ER=e_ok;
{$7d}
RETURN(ER);
{$7d}
STATIC CHAR L[maxline];
STATIC INT GETLINE(CHAR *S)
{$7b}
STATIC INT EC;
STATIC INT I,C;
INT HKFL,J;
J=HKFL=0;
EC=e_ok;
IF(!GL)
{$7b}
DO
{$7b}
EC=PGETLINE(L);
I=0;
WHILE(L[I]==' ')
I++;
WHILE(L[I]!='\0' && ISDIGIT(L[I]))
I++;
GF=1;
IF(EC==e_newline)
{$7b}
PUTTMP(0);
PUTTMP(t_line);
PUTTMP((FILEP->FLINE)&255);
PUTTMP(((FILEP->FLINE)>>8)&255);
EC=e_ok;
{$7d} ELSE
IF(EC==e_newfile)
{$7b}
PUTTMP(0);
PUTTMP(t_file);
PUTTMP((FILEP->FLINE)&255);
PUTTMP(((FILEP->FLINE)>>8)&255);
PUTTMPS((SIGNED CHAR*)FILEP->FNAME,
1+(INT)STRLEN(FILEP->FNAME));
EC=e_ok;
{$7d}
{$7d} WHILE(!EC && L[I]=='\0');
{$7d}
GL=0;
IF(!EC)
{$7b}
DO {$7b}
C=S[J]=L[I++];
IF (C=='\"')
HKFL^=1;
IF (C=='\0')
BREAK;
IF ((!MASM) && C==':' && !HKFL)
{$7b}
GL=1;
BREAK;
{$7d}
J++;
{$7d} WHILE (C!='\0' && J<maxline-1 && I<maxline-1);
S[J]='\0';
{$7d} ELSE
S[0]='\0';
RETURN(EC);
{$7d}
VOID SET_ALIGN(INT A) {$7b}
ALIGN = (A>ALIGN)?A:ALIGN;
{$7d}
STATIC VOID LINEOUT(VOID)
{$7b}
IF(GF)
{$7b}
LOGOUT(FILEP->FLINEP);
LOGOUT("\N");
GF=0;
{$7d}
{$7d}
VOID ERROUT(INT ER)
{$7b}
IF (ER<-anzerr {$7c}{$7c} ER>-1) {$7b}
IF(ER>=-(anzerr+anzwarn) && ER < -anzerr) {$7b}
SPRINTF(OUT,"%S:LINE %D: %04X: wARNING - %S\N",
FILEP->FNAME, FILEP->FLINE, PC[SEGMENT], ERTXT[-ER-1]);
{$7d} ELSE {$7b}
/* SPRINTF(OUT,"%S:zEILE %D: %04X:uNBEKANNTER fEHLER nR.: %D\N",*/
SPRINTF(OUT,"%S:LINE %D: %04X: uNKNOWN ERROR # %D\N",
FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],ER);
NER++;
{$7d}
{$7d} ELSE {$7b}
IF (ER==e_nodef)
SPRINTF(OUT,"%S:LINE %D: %04X:lABEL '%S' NOT DEFINED\N",
FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],LZ);
ELSE
SPRINTF(OUT,"%S:LINE %D: %04X:%S ERROR\N",
FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],ERTXT[-ER-1]);
NER++;
{$7d}
LOGOUT(OUT);
{$7d}
STATIC VOID CHRPUT(INT C)
{$7b}
/* PRINTF(" %02X",C&255);*/
PUTC( C&0X00FF,FPOUT);
{$7d}
VOID LOGOUT(CHAR *S)
{$7b}
FPRINTF(STDERR, "%S",S);
IF(FPERR)
FPRINTF(FPERR,"%S",S);
{$7d}