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 >
C/C++ Source or Header  |  1998-04-20  |  22KB  |  885 lines

  1.  
  2. /*
  3.     XA65 - 6502 CROSS ASSEMBLER AND UTILITY SUITE
  4.     cOPYRIGHT (c) 1989-1998 aNDR{$e9} fACHAT (A.FACHAT@PHYSIK.TU-CHEMNITZ.DE)
  5.  
  6.     tHIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
  7.     IT UNDER THE TERMS OF THE gnu gENERAL pUBLIC lICENSE AS PUBLISHED BY
  8.     THE fREE sOFTWARE fOUNDATION; EITHER VERSION 2 OF THE lICENSE, OR
  9.     (AT YOUR OPTION) ANY LATER VERSION.
  10.  
  11.     tHIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
  12.     BUT without any warranty; WITHOUT EVEN THE IMPLIED WARRANTY OF
  13.     merchantability OR fitness for a particular purpose.  sEE THE
  14.     gnu gENERAL pUBLIC lICENSE FOR MORE DETAILS.
  15.  
  16.     yOU SHOULD HAVE RECEIVED A COPY OF THE gnu gENERAL pUBLIC lICENSE
  17.     ALONG WITH THIS PROGRAM; IF NOT, WRITE TO THE fREE sOFTWARE
  18.     fOUNDATION, iNC., 675 mASS aVE, cAMBRIDGE, ma 02139, usa.
  19. */
  20.  
  21.  
  22. #INCLUDE <CTYPE.H>
  23. #INCLUDE <STRING.H>
  24. #INCLUDE <STDIO.H>
  25. #INCLUDE <STDLIB.H>
  26. #INCLUDE <UNISTD.H>
  27. #INCLUDE <TIME.H>
  28.  
  29. /* STRUCTS AND DEFS */
  30.  
  31. #INCLUDE "XAH.H"
  32. #INCLUDE "XAH2.H"
  33.  
  34. /* EXPORTED FUNCTIONS ARE DEFINED HERE */
  35.  
  36. #INCLUDE "XAR.H"
  37. #INCLUDE "XA.H"
  38. #INCLUDE "XAM.H"
  39. #INCLUDE "XAL.H"
  40. #INCLUDE "XAP.H"
  41. #INCLUDE "XAT.H"
  42. #INCLUDE "XAO.H"
  43.  
  44. /* EXPORTED GLOBALS */
  45.  
  46. INT NCMOS,CMOSFL;
  47. INT MASM = 0;
  48. INT NOLINK = 0;
  49. INT ROMABLE = 0;
  50. INT ROMADR = 0;
  51. INT NOGLOB = 0;
  52. INT SHOWBLK = 0;
  53.  
  54. /* LOCAL VARIABLES */
  55.  
  56. STATIC CONST CHAR *COPYRIGHT={$7b}
  57. "cROSS-aSSEMBLER 65XX v2.1.4F 20APR1998 (C) 1989-98 BY a.fACHAT\N"{$7d};
  58.  
  59. STATIC CHAR OUT[maxline];
  60. STATIC TIME_T TIM1,TIM2;
  61. STATIC file *FPOUT,*FPERR,*FPLAB;
  62. STATIC INT NER = 0;
  63.  
  64. STATIC INT ALIGN = 1;
  65.  
  66. STATIC VOID PRINTSTAT(VOID);
  67. STATIC VOID USAGE(VOID);
  68. STATIC INT  SETFEXT(CHAR*,CHAR*);
  69. STATIC INT  X_INIT(VOID);
  70. STATIC INT  PASS1(VOID);
  71. STATIC INT  PASS2(VOID);
  72. STATIC INT  PUTTMP(INT);
  73. STATIC INT  PUTTMPS(SIGNED CHAR*,INT);
  74. STATIC VOID CHRPUT(INT);
  75. STATIC INT  GETLINE(CHAR*);
  76. STATIC VOID LINEOUT(VOID);
  77. STATIC LONG GA_P1(VOID);
  78. STATIC LONG GM_P1(VOID);
  79.  
  80. /* TEXT */
  81. INT SEGMENT;
  82. INT TLEN=0, TBASE=0X1000;
  83. INT DLEN=0, DBASE=0X0400;
  84. INT BLEN=0, BBASE=0X4000;
  85. INT ZLEN=0, ZBASE=4;
  86. INT FMODE=0;
  87. INT RELMODE=0;
  88.  
  89. INT PC[seg_max];/* SEGMENTS */
  90.  
  91. INT MAIN(INT ARGC,CHAR *ARGV[])
  92. {$7b}
  93.      INT ER=1,I;
  94.      SIGNED CHAR *S=null;
  95.  
  96.      INT MIFILES = 5;
  97.      INT NIFILES = 0;
  98.      INT VERBOSE = 0;
  99.      INT OLDFILE = 0;
  100.      INT NO_LINK = 0;
  101.  
  102.      CHAR **IFILES;
  103.      CHAR *OFILE;
  104.      CHAR *EFILE;
  105.      CHAR *LFILE;
  106.      CHAR *IFILE;
  107.  
  108.      CHAR OLD_E[maxline];
  109.      CHAR OLD_L[maxline];
  110.      CHAR OLD_O[maxline];
  111.  
  112.      TIM1=TIME(null);
  113.      
  114.      NCMOS=0;
  115.      CMOSFL=1;
  116.  
  117.      IFILES = MALLOC(MIFILES*SIZEOF(CHAR*));
  118.  
  119.      AFILE = ALLOC_FILE();
  120.  
  121.      IF(ARGC<=1)
  122.      {$7b}
  123.           USAGE();
  124.           RETURN(1);
  125.      {$7d}
  126.      
  127.      OFILE="A.O65";
  128.      EFILE=null;
  129.      LFILE=null;
  130.  
  131.      IF(PP_INIT()) {$7b}
  132.        LOGOUT("FATAL: PP: NO MEMORY!");
  133.        RETURN 1;
  134.      {$7d}
  135.      IF(B_INIT()) {$7b}
  136.        LOGOUT("FATAL: B: NO MEMORY!");
  137.        RETURN 1;
  138.      {$7d}
  139.      IF(L_INIT()) {$7b}
  140.        LOGOUT("FATAL: L: NO MEMORY!");
  141.        RETURN 1;
  142.      {$7d}
  143.  
  144.  
  145.      I=1;
  146.      WHILE(I<ARGC) {$7b}
  147. IF(ARGV[I][0]=='-') {$7b}
  148.   SWITCH(ARGV[I][1]) {$7b}
  149.   CASE 'm':
  150.    MASM = 1;/* masm COMPATIBILITY MODE */
  151. BREAK;
  152.   CASE 'a':/* MAKE TEXT SEGMENT START SO THAT TEXT RELOCATION
  153.    IS NOT NECESSARY WHEN _FILE_ STARTS AT ADR */
  154. ROMABLE = 2;
  155. IF(ARGV[I][2]==0) ROMADR = ATOI(ARGV[++I]);
  156. ELSE ROMADR = ATOI(ARGV[I]+2);
  157. BREAK;
  158.   CASE 'g':
  159. NOGLOB = 1;
  160. BREAK;
  161.   CASE 'l':/* DEFINE GLOBAL LABEL */
  162. IF(ARGV[I][2]) LG_SET(ARGV[I]+2);
  163. BREAK;
  164.   CASE 'r':
  165. RELMODE = 1; 
  166. BREAK;
  167.   CASE 'd':
  168. S = (SIGNED CHAR*)STRSTR(ARGV[I]+2,"=");
  169. IF(S) *S = ' ';
  170. PP_DEFINE(ARGV[I]+2);
  171. BREAK;
  172.   CASE 'C':
  173. NO_LINK = 1;
  174. FMODE {$7c}= fm_obj;
  175. BREAK;
  176.   CASE 'V':
  177. VERBOSE = 1; 
  178. BREAK;
  179.   CASE 'c':
  180. CMOSFL = 0;
  181. BREAK;
  182.   CASE 'b':
  183. SHOWBLK = 1;
  184. BREAK;
  185.   CASE 'X':/* OLD FILENAME BEHAVIOUR */
  186. OLDFILE = 1;
  187. BREAK;
  188.   CASE 'i':
  189. IF(ARGV[I][2]==0) {$7b}
  190.   REG_INCLUDE(ARGV[++I]);
  191. {$7d} ELSE {$7b}
  192.   REG_INCLUDE(ARGV[I]+2);
  193. {$7d}
  194. BREAK;
  195.   CASE 'O':
  196. IF(ARGV[I][2]==0) {$7b}
  197.   OFILE=ARGV[++I];
  198. {$7d} ELSE {$7b}
  199.   OFILE=ARGV[I]+2;
  200. {$7d}
  201. BREAK;
  202.   CASE 'L':
  203. IF(ARGV[I][2]==0) {$7b}
  204.   LFILE=ARGV[++I];
  205. {$7d} ELSE {$7b}
  206.   LFILE=ARGV[I]+2;
  207. {$7d}
  208. BREAK;
  209.   CASE 'E':
  210. IF(ARGV[I][2]==0) {$7b}
  211.   EFILE=ARGV[++I];
  212. {$7d} ELSE {$7b}
  213.   EFILE=ARGV[I]+2;
  214. {$7d}
  215. BREAK;
  216.   CASE 'B':/* SET SEGMENT BASE ADDRESSES */
  217. SWITCH(ARGV[I][2]) {$7b}
  218. CASE 'T':
  219. IF(ARGV[I][3]==0) TBASE = ATOI(ARGV[++I]);
  220. ELSE TBASE = ATOI(ARGV[I]+3);
  221. BREAK;
  222. CASE 'D':
  223. IF(ARGV[I][3]==0) DBASE = ATOI(ARGV[++I]);
  224. ELSE DBASE = ATOI(ARGV[I]+3);
  225. BREAK;
  226. CASE 'B':
  227. IF(ARGV[I][3]==0) BBASE = ATOI(ARGV[++I]);
  228. ELSE BBASE = ATOI(ARGV[I]+3);
  229. BREAK;
  230. CASE 'Z':
  231. IF(ARGV[I][3]==0) ZBASE = ATOI(ARGV[++I]);
  232. ELSE ZBASE = ATOI(ARGV[I]+3);
  233. BREAK;
  234. DEFAULT:
  235. FPRINTF(STDERR,"UNKNOW SEGMENT TYPE '%C' - IGNORING!\N",
  236. ARGV[I][2]);
  237. BREAK;
  238. {$7d}
  239. BREAK;
  240.   CASE 0:
  241. FPRINTF(STDERR, "sINGLE DASH '-' ON COMMAND LINE - IGNORING!\N");
  242. BREAK;
  243.   DEFAULT:
  244. FPRINTF(STDERR, "uNKNOWN OPTION '%C' - IGNORING!\N",ARGV[I][1]);
  245. BREAK;
  246.   {$7d}
  247. {$7d} ELSE {$7b}/* NO OPTION -> FILENAME */
  248.   IFILES[NIFILES++] = ARGV[I];
  249.   IF(NIFILES>=MIFILES) {$7b}
  250.     MIFILES += 5;
  251.     IFILES=REALLOC(IFILES, MIFILES*SIZEOF(CHAR*));
  252.     IF(!IFILES) {$7b}
  253. FPRINTF(STDERR, "oOPS: COULDN'T ALLOC ENOUGH MEM FOR FILELIST TABLE..!\N");
  254. EXIT(1);
  255.     {$7d}
  256.   {$7d}
  257. {$7d}
  258. I++;
  259.      {$7d}
  260.      IF(!NIFILES) {$7b}
  261. FPRINTF(STDERR, "nO INPUT FILES GIVEN!\N");
  262. EXIT(0);
  263.      {$7d}
  264.  
  265.      IF(OLDFILE) {$7b}
  266. STRCPY(OLD_E, IFILES[0]);
  267. STRCPY(OLD_O, IFILES[0]);
  268. STRCPY(OLD_L, IFILES[0]);
  269.  
  270. IF(SETFEXT(OLD_E,".ERR")==0) EFILE = OLD_E;
  271. IF(SETFEXT(OLD_O,".OBJ")==0) OFILE = OLD_O;
  272. IF(SETFEXT(OLD_L,".LAB")==0) LFILE = OLD_L;
  273.      {$7d}
  274.  
  275.      FPLAB= LFILE ? XFOPEN(LFILE,"W") : null;
  276.      FPERR= EFILE ? XFOPEN(EFILE,"W") : null;
  277.      IF(!STRCMP(OFILE,"-")) {$7b}
  278. OFILE=null;
  279.         FPOUT = STDOUT;
  280.      {$7d} ELSE {$7b}
  281.         FPOUT= XFOPEN(OFILE,"WB");
  282.      {$7d}
  283.      IF(!FPOUT) {$7b}
  284. FPRINTF(STDERR, "cOULDN'T OPEN OUTPUT FILE!\N");
  285. EXIT(1);
  286.      {$7d}
  287.  
  288.      IF(VERBOSE) FPRINTF(STDERR, "%S",COPYRIGHT);
  289.  
  290.      IF(1 /*!M_INIT()*/)
  291.      {$7b}
  292.        IF(1 /*!B_INIT()*/)
  293.        {$7b}
  294.          IF(1 /*!L_INIT()*/)
  295.          {$7b}
  296.            /*IF(!PP_INIT())*/
  297.            {$7b}
  298.              IF(!X_INIT())
  299.              {$7b}
  300.        IF(FPERR) FPRINTF(FPERR,"%S",COPYRIGHT);
  301.        IF(VERBOSE) LOGOUT(CTIME(&TIM1));
  302.  
  303.        /* pASS 1 */
  304.  
  305.                PC[seg_abs]= 0;/* ABS ADDRESSING */
  306.        SEG_START(FMODE, TBASE, DBASE, BBASE, ZBASE, 0, RELMODE);
  307.  
  308.        IF(RELMODE) {$7b}
  309.  R_MODE(rmode_reloc);
  310.  SEGMENT = seg_text;
  311.        {$7d} ELSE {$7b}
  312.  R_MODE(rmode_abs);
  313.        {$7d}
  314.  
  315.        NOLINK = NO_LINK;
  316.  
  317.                FOR (I=0; I<NIFILES; I++)
  318.                {$7b}
  319.  IFILE = IFILES[I];
  320.  
  321.                  SPRINTF(OUT,"XaSS65: pASS 1: %S\N",IFILE);
  322.                  IF(VERBOSE) LOGOUT(OUT);
  323.  
  324.                  ER=PP_OPEN(IFILE);
  325.                  IF(!ER) {$7b}
  326.                    ER=PASS1();
  327.                    PP_CLOSE();
  328.                  {$7d} ELSE {$7b}
  329.    SPRINTF(OUT, "cOULDN'T OPEN SOURCE FILE '%S'!\N", IFILE);
  330.    LOGOUT(OUT);
  331.                  {$7d}
  332.                {$7d}           
  333.  
  334.        IF((ER=B_DEPTH())) {$7b}
  335.  SPRINTF(OUT,"sTILL %D BLOCKS OPEN AT END OF FILE!\N",ER);
  336.  LOGOUT(OUT);
  337.        {$7d}
  338.  
  339.        IF(TBASE & (ALIGN-1)) {$7b}
  340.    SPRINTF(OUT,"wARNING: TEXT SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", TBASE, ALIGN);
  341.    LOGOUT(OUT);
  342.        {$7d}
  343.        IF(DBASE & (ALIGN-1)) {$7b}
  344.    SPRINTF(OUT,"wARNING: DATA SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", DBASE, ALIGN);
  345.    LOGOUT(OUT);
  346.        {$7d}
  347.        IF(BBASE & (ALIGN-1)) {$7b}
  348.    SPRINTF(OUT,"wARNING: BSS SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", BBASE, ALIGN);
  349.    LOGOUT(OUT);
  350.        {$7d}
  351.        IF(ZBASE & (ALIGN-1)) {$7b}
  352.    SPRINTF(OUT,"wARNING: ZERO SEGMENT ($%04X) START ADDRESS DOESN'T ALIGN TO %D!\N", ZBASE, ALIGN);
  353.    LOGOUT(OUT);
  354.        {$7d}
  355.        SWITCH(ALIGN) {$7b}
  356. CASE 1: BREAK;
  357. CASE 2: FMODE {$7c}= 1; BREAK;
  358. CASE 4: FMODE {$7c}= 2; BREAK;
  359. CASE 256: FMODE {$7c}=3; BREAK;
  360.        {$7d}
  361.        
  362.        IF((!ER) && RELMODE) 
  363. H_WRITE(FPOUT, FMODE, TLEN, DLEN, BLEN, ZLEN, 0);
  364.  
  365.  
  366.                IF(!ER)
  367.                {$7b}
  368.                     IF(VERBOSE) LOGOUT("XaSS65: pASS 2:\N");
  369.  
  370.     SEG_PASS2();
  371.  
  372.             IF(!RELMODE) {$7b}
  373.               R_MODE(rmode_abs);
  374.             {$7d} ELSE {$7b}
  375.               R_MODE(rmode_reloc);
  376.       SEGMENT = seg_text;
  377.             {$7d}
  378.                     ER=PASS2();
  379.                {$7d} 
  380.  
  381.                IF(FPLAB) PRINTLLIST(FPLAB);
  382.                TIM2=TIME(null);
  383.        IF(VERBOSE) PRINTSTAT();
  384.  
  385.        IF((!ER) && RELMODE) SEG_END(FPOUT);/* WRITE RELOC/LABEL INFO */
  386.                               
  387.                IF(FPERR) FCLOSE(FPERR);
  388.                IF(FPLAB) FCLOSE(FPLAB);
  389.                IF(FPOUT) FCLOSE(FPOUT);
  390.  
  391.              {$7d} ELSE {$7b}
  392.                LOGOUT("FATAL: X: NO MEMORY!\N");
  393.              {$7d}
  394.              PP_END();
  395. /*           {$7d} ELSE {$7b}
  396.              LOGOUT("FATAL: PP: NO MEMORY!");*/
  397.            {$7d}
  398.          {$7d} ELSE {$7b}
  399.           LOGOUT("FATAL: L: NO MEMORY!\N");
  400.          {$7d}
  401.        {$7d} ELSE {$7b}
  402.           LOGOUT("FATAL: B: NO MEMORY!\N");
  403.        {$7d}
  404.        /*M_EXIT();*/
  405.      {$7d} ELSE {$7b} 
  406.           LOGOUT("nOT ENOUGH MEMORY AVAILABLE!\N");
  407.      {$7d}
  408.  
  409.      IF(NER {$7c}{$7c} ER)
  410.      {$7b}
  411.           FPRINTF(STDERR, "bREAK AFTER %D ERROR%C\N",NER,NER?'S':0);
  412.   /*UNLINK();*/
  413.   IF(OFILE) {$7b}
  414.     UNLINK(OFILE);
  415.   {$7d}
  416.      {$7d}
  417.  
  418.      FREE(IFILES);
  419.  
  420.      RETURN( (ER {$7c}{$7c} NER) ? 1 : 0 );
  421. {$7d}
  422.  
  423. STATIC VOID PRINTSTAT(VOID)
  424. {$7b}
  425. LOGOUT("sTATISTICS:\N");
  426. SPRINTF(OUT," %8D OF %8D LABEL USED\N",GA_LAB(),GM_LAB()); LOGOUT(OUT);
  427. SPRINTF(OUT," %8LD OF %8LD BYTE LABEL-MEMORY USED\N",GA_LABM(),GM_LABM()); LOGOUT(OUT);
  428. SPRINTF(OUT," %8D OF %8D pp-DEFS USED\N",GA_PP(),GM_PP()); LOGOUT(OUT);
  429. SPRINTF(OUT," %8LD OF %8LD BYTE pp-MEMORY USED\N",GA_PPM(),GM_PPM()); LOGOUT(OUT);
  430. SPRINTF(OUT," %8LD OF %8LD BYTE BUFFER MEMORY USED\N",GA_P1(),GM_P1()); LOGOUT(OUT);
  431. SPRINTF(OUT," %8D BLOCKS USED\N",GA_BLK()); LOGOUT(OUT);
  432. SPRINTF(OUT," %8LD SECONDS USED\N",(LONG)DIFFTIME(TIM2,TIM1)); LOGOUT(OUT);
  433. {$7d}
  434.  
  435. #DEFINEFPUTW(A,FP)FPUTC((A)&255,FP);FPUTC((A>>8)&255,FP)
  436.  
  437. INT H_LENGTH(VOID) {$7b}
  438. RETURN 26+O_LENGTH();
  439. {$7d}
  440.  
  441. #IF 0
  442. /* WRITE HEADER FOR RELOCATABLE OUTPUT FORMAT */
  443. INT H_WRITE(file *FP, INT TBASE, INT TLEN, INT DBASE, INT DLEN, 
  444. INT BBASE, INT BLEN, INT ZBASE, INT ZLEN) {$7b}
  445.  
  446. FPUTC(1, FP);/* VERSION BYTE */
  447. FPUTC(0, FP);/* HI ADDRESS 0 -> NO c64 */
  448. FPUTC("O", FP);
  449. FPUTC("6", FP);
  450. FPUTC("5", FP);
  451. FPUTC(0, FP);/* FORMAT VERSION */
  452. FPUTW(MODE, FP);/* FILE MODE */
  453. FPUTW(TBASE,FP);/* TEXT BASE */
  454. FPUTW(TLEN,FP);/* TEXT LENGTH */
  455. FPUTW(DBASE,FP);/* DATA BASE */
  456. FPUTW(DLEN,FP);/* DATA LENGTH */
  457. FPUTW(BBASE,FP);/* BSS BASE */
  458. FPUTW(BLEN,FP);/* BSS LENGTH */
  459. FPUTW(ZBASE,FP);/* ZEROP BASE */
  460. FPUTW(ZLEN,FP);/* ZEROP LENGTH */
  461.  
  462. O_WRITE(FP);
  463.  
  464. RETURN 0;
  465. {$7d}
  466. #ENDIF
  467.  
  468. STATIC INT SETFEXT(CHAR *S, CHAR *EXT)
  469. {$7b}
  470.      INT J,I=(INT)STRLEN(S);
  471.  
  472.      IF(I>maxline-5)
  473.           RETURN(-1);
  474.           
  475.      FOR(J=I-1;J>=0;J--)
  476.      {$7b}
  477.           IF(S[J]==dirchar)
  478.           {$7b}
  479.                STRCPY(S+I,EXT);
  480.                BREAK;
  481.           {$7d}
  482.           IF(S[J]=='.')
  483.           {$7b}
  484.                STRCPY(S+J,EXT);
  485.                BREAK;
  486.           {$7d}
  487.      {$7d}
  488.      IF(!J)
  489.           STRCPY(S+I,EXT);
  490.  
  491.      RETURN(0);
  492. {$7d}
  493.  
  494. /*
  495. STATIC CHAR *TMP;
  496. STATIC UNSIGNED LONG TMPZ;
  497. STATIC UNSIGNED LONG TMPE;
  498. */
  499.  
  500. STATIC LONG GA_P1(VOID)
  501. {$7b}
  502. RETURN(AFILE->MN.TMPZ);
  503. {$7d}
  504. STATIC LONG GM_P1(VOID)
  505. {$7b}
  506. RETURN(tmpmem);
  507. {$7d}
  508.  
  509. #IFNDEF ABS
  510. #DEFINE ABS(A) ((A)>=0 ? A : -A)
  511. #ENDIF
  512.  
  513. STATIC INT PASS2(VOID)
  514. {$7b}
  515.      INT C,ER,L,LL,I,AL;
  516.      dATEI DATEI;
  517.      SIGNED CHAR *DATASEG=null;
  518.      SIGNED CHAR *DATAP=null;
  519.  
  520.      IF((DATASEG=MALLOC(DLEN))) {$7b}
  521.        IF(!DATASEG) {$7b}
  522.  FPRINTF(STDERR, "cOULDN'T ALLOC DATASEG MEMORY...\N");
  523.  EXIT(1);
  524.        {$7d}
  525.        DATAP=DATASEG;
  526.      {$7d}
  527.      FILEP=&DATEI;
  528.      AFILE->MN.TMPE=0l;
  529.  
  530.      WHILE(NER<20 && AFILE->MN.TMPE<AFILE->MN.TMPZ)
  531.      {$7b}
  532.           L=AFILE->MN.TMP[AFILE->MN.TMPE++];
  533.           LL=L;
  534.  
  535.           IF(!L)
  536.           {$7b}
  537.                IF(AFILE->MN.TMP[AFILE->MN.TMPE]==t_line)
  538.                {$7b}
  539.                     DATEI.FLINE=(AFILE->MN.TMP[AFILE->MN.TMPE+1]&255)+(AFILE->MN.TMP[AFILE->MN.TMPE+2]<<8);
  540.                     AFILE->MN.TMPE+=3;
  541.                {$7d} ELSE
  542.                IF(AFILE->MN.TMP[AFILE->MN.TMPE]==t_file)
  543.                {$7b}
  544.                     DATEI.FLINE=(AFILE->MN.TMP[AFILE->MN.TMPE+1]&255)+(AFILE->MN.TMP[AFILE->MN.TMPE+2]<<8);
  545.                     STRCPY(DATEI.FNAME,(CHAR*) AFILE->MN.TMP+AFILE->MN.TMPE+3);
  546.                     AFILE->MN.TMPE+=3+STRLEN(DATEI.FNAME);
  547.                {$7d}
  548.           {$7d} ELSE
  549.           {$7b}
  550.                ER=T_P2(AFILE->MN.TMP+AFILE->MN.TMPE,&LL,0,&AL);
  551.           
  552.                IF(ER==e_noline)
  553.                {$7b}
  554.                {$7d} ELSE
  555.                IF(ER==e_ok)
  556.                {$7b}
  557.   IF(SEGMENT<seg_data) {$7b} 
  558.                     FOR(I=0;I<LL;I++)
  559.                          CHRPUT(AFILE->MN.TMP[AFILE->MN.TMPE+I]);
  560.   {$7d} ELSE IF (SEGMENT==seg_data && DATAP) {$7b}
  561.     MEMCPY(DATAP,AFILE->MN.TMP+AFILE->MN.TMPE,LL);
  562.     DATAP+=LL;
  563.   {$7d}
  564.                {$7d} ELSE
  565.                IF(ER==e_dsb)
  566.                {$7b}
  567.                   C=AFILE->MN.TMP[AFILE->MN.TMPE];
  568.   IF(SEGMENT<seg_data) {$7b}
  569.                     /*PRINTF("e_dsb, LL=%D, L=%D, C=%C\N",LL,L,AFILE->MN.TMP[AFILE->MN.TMPE]);*/
  570.                     FOR(I=0;I<LL;I++)
  571.                          CHRPUT(C);
  572.   {$7d} ELSE IF (SEGMENT==seg_data && DATAP) {$7b}
  573.     MEMSET(DATAP, C, LL);
  574.     DATAP+=LL;
  575.   {$7d}
  576.                {$7d} ELSE
  577.                {$7b}
  578.                     ERROUT(ER);
  579.                {$7d}
  580.           {$7d}
  581.           AFILE->MN.TMPE+=ABS(L);
  582.      {$7d}
  583.      IF(RELMODE) {$7b}
  584.        IF((LL=FWRITE(DATASEG, 1, DLEN, FPOUT))<DLEN) {$7b}
  585. FPRINTF(STDERR, "pROBLEMS WRITING %D BYTES, RETURN GIVES %D\N",DLEN,LL);
  586.        {$7d}
  587.      {$7d}
  588.  
  589.      RETURN(NER);
  590. {$7d}     
  591.      
  592.  
  593. STATIC INT PASS1(VOID)
  594. {$7b}
  595.      SIGNED CHAR O[maxline];
  596.      INT L,ER, AL;
  597.  
  598.      TLEN=0;
  599.      NER=0;
  600.      WHILE(!(ER=GETLINE(S)))
  601.      {$7b}         
  602.           ER=T_P1((SIGNED CHAR*)S,O,&L,&AL);
  603.   SWITCH(SEGMENT) {$7b}
  604.     CASE seg_abs:
  605.     CASE seg_text: TLEN += AL; BREAK;
  606.     CASE seg_data: DLEN += AL; BREAK;
  607.     CASE seg_bss : BLEN += AL; BREAK;
  608.     CASE seg_zero: ZLEN += AL; BREAK;
  609.   {$7d}
  610.  
  611.           /*PRINTF(": ER= %D, L=%D, TMPZ=%D\N",ER,L,TMPZ);*/
  612.  
  613.           IF(L)
  614.           {$7b}
  615.             IF(ER)
  616.             {$7b}
  617.                IF(ER==e_okdef)
  618.                {$7b}
  619.                     IF(!(ER=PUTTMP(L)))
  620.                          ER=PUTTMPS(O,L);
  621.                {$7d} ELSE
  622.                IF(ER==e_noline)
  623.                     ER=e_ok;
  624.             {$7d} ELSE
  625.             {$7b}
  626.                IF(!(ER=PUTTMP(-L)))
  627.                     ER=PUTTMPS(O,L);
  628.             {$7d}
  629.           {$7d}
  630.           IF(ER)
  631.           {$7b}
  632.                LINEOUT();
  633.                ERROUT(ER);
  634.           {$7d}
  635.  
  636. /*          PRINTF("TMPZ =%D\N",AFILE->MN.TMPZ);
  637. */
  638.      {$7d} 
  639.  
  640.      IF(ER!=e_eof)
  641.           ERROUT(ER);
  642.  
  643.           
  644.  
  645.      /*{$7b} INT I; PRINTF("pASS 1 \N");
  646.      FOR(I=0;I<AFILE->MN.TMPZ;I++)
  647.           FPRINTF(STDERR, " %02X",AFILE->MN.TMP[I]);
  648.      GETCHAR();{$7d}*/
  649.  
  650.      RETURN(NER);
  651. {$7d}
  652.  
  653.  
  654. STATIC VOID USAGE(VOID)
  655. {$7b}
  656.      FPRINTF(STDERR, "%S",COPYRIGHT);
  657.      FPRINTF(STDERR, "USAGE : XA {$7b} OPTION {$7c} SOURCEFILE {$7d}\N"
  658.     "OPTIONS:\N"
  659.     " -V          = VERBOSE OUTPUT\N"
  660.     " -X          = OLD FILENAME BEHAVIOUR (OVERRIDES -O, -E, -L)\N"
  661.             " -c          = NO cmos-OPCODES\N"
  662.             " -b          = SHOW LINES WITH BLOCK OPEN/CLOSE\N"
  663.             " -C          = PRODUCE O65 OBJECT INSTEAD OF EXECUTABLE FILES (I.E. DO NOT LINK)\N"
  664.     " -O FILENAME = SETS OUTPUT FILENAME, DEFAULT IS 'A.O65'\N"
  665.     "               a FILENAME OF '-' SETS STDOUT AS OUTPUT FILE\N"
  666.     " -E FILENAME = SETS ERRORLOG FILENAME, DEFAULT IS NONE\N"
  667.     " -L FILENAME = SETS LABELLIST FILENAME, DEFAULT IS NONE\N"
  668.     " -m          = ALLOW \":\" TO APPEAR IN COMMENTS, FOR masm COMPATIBILITY\N"
  669.     " -r          = START ASSEMBLER IN RELOCATING MODE\N"
  670.     " -lLABEL     = DEFINES 'LABEL' AS ABSOLUTE, UNDEFINED LABEL EVEN WHEN LINKING\N"
  671.     " -B? ADR     = SET SEGMENT BASE ADDRESS TO INTEGER VALUE ADR. \N"
  672.     "               '?' STANDS FOR T(EXT), D(ATA), B(SS) AND Z(ERO) SEGMENT\N"
  673.             "               (ADDRESS CAN BE GIVEN MORE THAN ONCE, LATEST IS TAKEN)\N"
  674.     " -a ADR      = MAKE TEXT SEGMENT START AT AN ADDRESS THAT WHEN THE _FILE_\N"
  675.     "               STARTS AT ADR, RELOCATION IS NOT NECESSARY. oVERRIDES -BT\N"
  676.     "               oTHER SEGMENTS HAVE TO BE TAKE CARE OF WITH -B?\N"
  677.      " -g          = SUPPRESS LIST OF EXPORTED GLOBALS\N"
  678.     " -ddef=text  = DEFINES A PREPROCESSOR REPLACEMENT\N"
  679.     " -iDIR      = ADD DIRECTORY 'DIR' TO INCLUDE PATH (BEFORE xainput)\N"
  680.             "eNVIRONMENT:\N"
  681.             " xainput = INCLUDE FILE PATH; COMPONENTS DIVIDED BY ','\N"
  682.             " xaoutput= OUTPUT FILE PATH\N"
  683. );
  684. {$7d}
  685.  
  686. #DEFINE   anzerr    30
  687. #DEFINE   anzwarn   6
  688.  
  689. /*
  690. STATIC CHAR *ERTXT[] = {$7b} "sYNTAX","lABEL DEFINIERT",
  691.           "lABEL NICHT DEFINIERT","lABELTABELLE VOLL",
  692.           "lABEL ERWARTET","sPEICHER VOLL","iLLEGALER oPCODE",
  693.           "fALSCHE aDRESSIERUNGSART","bRANCH AUSSERHALB DES bEREICHS",
  694.           "uEBERLAUF","dIVISION DURCH nULL","pSEUDO-oPCODE ERWARTET",
  695.           "bLOCK-sTACK-uEBERLAUF","dATEI NICHT GEFUNDEN",
  696.           "eND OF fILE","bLOCK-sTRUKTUR NICHT ABGESCHLOSSEN",
  697.           "nObLK","nOkEY","nOlINE","okdEF","dsb","nEWlINE",
  698.           "nEWfILE","cmos-bEFEHL","PP:fALSCHE aNZAHL pARAMETER" {$7d};
  699. */
  700. STATIC CHAR *ERTXT[] = {$7b} "sYNTAX","lABEL DEFINED",
  701.           "lABEL NOT DEFINED","lABELTAB FULL",
  702.           "lABEL EXPECTED","NO MORE MEMORY","iLLEGAL OPCODE",
  703.           "wRONG ADDRESSING MODE","bRANCH OUT OF RANGE",
  704.           "oVERFLOW","dIVISION BY ZERO","pSEUDO-OPCODE EXPECTED",
  705.           "bLOCK STACK OVERFLOW","FILE NOT FOUND",
  706.           "eND OF FILE","tOO MANY BLOCK CLOSE",
  707.           "nObLK","nOkEY","nOlINE","okdEF","dsb","nEWlINE",
  708.           "nEWfILE","cmos-bEFEHL","PP:wRONG PARAMETER COUNT",
  709.   "iLLEGAL POINTER ARITHMETIC", "iLLEGAL SEGMENT",
  710.   "fILE HEADER OPTION TOO LONG",
  711.   "fILE oPTION NOT AT FILE START (WHEN rom-ABLE)",
  712.   "iLLEGAL ALIGN VALUE",
  713.   /* WARNINGS START HERE */
  714.   "cUTTING WORD RELOCATION IN BYTE VALUE",
  715.   "bYTE RELOCATION IN WORD VALUE",
  716.   "iLLEGAL POINTER ARITHMETIC",
  717.   "aDDRESS ACCESS TO LOW OR HIGH BYTE POINTER",
  718.   "hIGH BYTE ACCESS TO LOW BYTE POINTER",
  719.   "lOW BYTE ACCESS TO HIGH BYTE POINTER" {$7d};
  720.  
  721. STATIC INT GL;
  722. STATIC INT GF;  
  723.  
  724. STATIC INT X_INIT(VOID)
  725. {$7b}
  726. RETURN 0;
  727. #IF 0
  728.      INT ER=0;
  729.      /*ER=M_ALLOC(tmpmem,&TMP);*/
  730.      AFILE->MN.TMP=MALLOC(tmpmem);
  731.      IF(!AFILE->MN.TMP) ER=e_nomem;
  732.      AFILE->MN.TMPZ=0l;
  733.      RETURN(ER);
  734. #ENDIF
  735. {$7d}
  736.  
  737. STATIC INT PUTTMP(INT C)
  738. {$7b}
  739.      INT ER=e_nomem;
  740. /*PRINTF("PUTTMP: AFILE=%P, TMP=%P, TMPZ=%D\N",AFILE, AFILE?AFILE->MN.TMP:0, AFILE?AFILE->MN.TMPZ:0);*/
  741.      IF(AFILE->MN.TMPZ<tmpmem)
  742.      {$7b}
  743.           AFILE->MN.TMP[AFILE->MN.TMPZ++]=C;
  744.           ER=e_ok;
  745.      {$7d}
  746.      RETURN(ER);
  747. {$7d}
  748.  
  749. STATIC INT PUTTMPS(SIGNED CHAR *S, INT L)
  750. {$7b}
  751.      INT I=0,ER=e_nomem;
  752.      
  753.      IF(AFILE->MN.TMPZ+L<tmpmem)
  754.      {$7b}
  755.           WHILE(I<L)
  756.                AFILE->MN.TMP[AFILE->MN.TMPZ++]=S[I++];
  757.  
  758.           ER=e_ok;
  759.      {$7d}
  760.      RETURN(ER);
  761. {$7d}
  762.  
  763. STATIC CHAR L[maxline];
  764.  
  765. STATIC INT GETLINE(CHAR *S)
  766. {$7b}
  767.      STATIC INT EC;
  768.      STATIC INT I,C;
  769.      INT HKFL,J;
  770.  
  771.      J=HKFL=0;
  772.      EC=e_ok;
  773.  
  774.      IF(!GL)
  775.      {$7b}
  776.           DO
  777.           {$7b}
  778.                EC=PGETLINE(L);
  779.                I=0;
  780.                WHILE(L[I]==' ')
  781.                     I++;
  782.                WHILE(L[I]!='\0' && ISDIGIT(L[I]))
  783.                     I++;
  784.                GF=1;
  785.  
  786.                IF(EC==e_newline)
  787.                {$7b}
  788.                     PUTTMP(0);
  789.                     PUTTMP(t_line);
  790.                     PUTTMP((FILEP->FLINE)&255);
  791.                     PUTTMP(((FILEP->FLINE)>>8)&255);
  792.                     EC=e_ok;
  793.                {$7d} ELSE
  794.                IF(EC==e_newfile)
  795.                {$7b}
  796.                     PUTTMP(0);
  797.                     PUTTMP(t_file);
  798.                     PUTTMP((FILEP->FLINE)&255);
  799.                     PUTTMP(((FILEP->FLINE)>>8)&255);
  800.                     PUTTMPS((SIGNED CHAR*)FILEP->FNAME,
  801. 1+(INT)STRLEN(FILEP->FNAME));
  802.                     EC=e_ok;
  803.                {$7d}
  804.           {$7d} WHILE(!EC && L[I]=='\0');
  805.      {$7d}
  806.  
  807.      GL=0;
  808.      IF(!EC)
  809.      {$7b}
  810.           DO {$7b}
  811.                C=S[J]=L[I++];
  812.  
  813.                IF (C=='\"')
  814.                     HKFL^=1;
  815.                IF (C=='\0')
  816.                     BREAK;
  817.                IF ((!MASM) && C==':' && !HKFL)
  818.                {$7b}
  819.                     GL=1;
  820.                     BREAK;
  821.                {$7d}
  822.                J++;
  823.           {$7d} WHILE (C!='\0' && J<maxline-1 && I<maxline-1);
  824.      
  825.           S[J]='\0';
  826.      {$7d} ELSE
  827.           S[0]='\0';
  828.  
  829.      RETURN(EC);
  830. {$7d}
  831.  
  832. VOID SET_ALIGN(INT A) {$7b}
  833. ALIGN = (A>ALIGN)?A:ALIGN;
  834. {$7d}
  835.  
  836. STATIC VOID LINEOUT(VOID)
  837. {$7b}
  838.      IF(GF)
  839.      {$7b}
  840.           LOGOUT(FILEP->FLINEP);
  841.           LOGOUT("\N");
  842.           GF=0;
  843.      {$7d}
  844. {$7d}
  845.  
  846. VOID ERROUT(INT ER)
  847. {$7b}
  848.      IF (ER<-anzerr {$7c}{$7c} ER>-1) {$7b}
  849. IF(ER>=-(anzerr+anzwarn) && ER < -anzerr) {$7b}
  850.   SPRINTF(OUT,"%S:LINE %D: %04X: wARNING - %S\N",
  851. FILEP->FNAME, FILEP->FLINE, PC[SEGMENT], ERTXT[-ER-1]);
  852. {$7d} ELSE {$7b}
  853.           /* SPRINTF(OUT,"%S:zEILE %D: %04X:uNBEKANNTER fEHLER nR.: %D\N",*/
  854.           SPRINTF(OUT,"%S:LINE %D: %04X: uNKNOWN ERROR # %D\N",
  855.                FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],ER);
  856.   NER++;
  857. {$7d}
  858.      {$7d} ELSE {$7b}
  859.        IF (ER==e_nodef)
  860.           SPRINTF(OUT,"%S:LINE %D: %04X:lABEL '%S' NOT DEFINED\N",
  861.                FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],LZ);
  862.        ELSE  
  863.           SPRINTF(OUT,"%S:LINE %D: %04X:%S ERROR\N",
  864.                FILEP->FNAME,FILEP->FLINE,PC[SEGMENT],ERTXT[-ER-1]);
  865.  
  866.        NER++;
  867.      {$7d}
  868.      LOGOUT(OUT);
  869. {$7d}
  870.  
  871. STATIC VOID CHRPUT(INT C)
  872. {$7b}
  873.      /*     PRINTF(" %02X",C&255);*/
  874.  
  875.      PUTC( C&0X00FF,FPOUT);
  876. {$7d}
  877.  
  878. VOID LOGOUT(CHAR *S)
  879. {$7b}
  880.      FPRINTF(STDERR, "%S",S);
  881.      IF(FPERR)
  882.           FPRINTF(FPERR,"%S",S);
  883. {$7d}
  884.  
  885.