static int xa_getline(char *s) { static int ec; static int i,c; int hkfl,j,comcom; j=hkfl=comcom=0; ec=E_OK; if(!gl) { do { ec=pgetline(l); i=0; while(l[i]==' ') i++; while(l[i]!='\0' && isdigit(l[i])) i++; gf=1; if(ec==E_NEWLINE) { puttmp(0); puttmp(T_LINE); puttmp((filep->fline)&255); puttmp(((filep->fline)>>8)&255); ec=E_OK; } else if(ec==E_NEWFILE) { puttmp(0); puttmp(T_FILE); puttmp((filep->fline)&255); puttmp(((filep->fline)>>8)&255); puttmps((signed char*)&(filep->fname), sizeof(filep->fname)); /* puttmps((signed char*)filep->fname, 1+(int)strlen(filep->fname)); */ ec=E_OK; } } while(!ec && l[i]=='\0');
char * getnext(int must){ int c; char *beg; int prect,nlct; prect = nlct = 0; if(tptr > lastplace){ tptr = lastplace = temp; err = 0; inswitch = 0; } tp = lastplace; if(inswitch && tptr <= lastplace) if (isalnum((uchar)*lastplace)||ispunct((uchar)*lastplace)||isop((uchar)*lastplace))return(lastplace); space: while(isspace(c=Bgetc(input)))puttmp(c,1); beg = tp; puttmp(c,1); if(c == '/'){ if(puttmp(Bgetc(input),1) == '*'){ cont: while((c=Bgetc(input)) != '*'){ puttmp(c,0); if(must == 0 && c == '\n') if(nlct++ > 2)goto done; } puttmp(c,1); star: if(puttmp((c=Bgetc(input)),1) == '/'){ beg = tp; puttmp((c=Bgetc(input)),1); } else if(c == '*')goto star; else goto cont; } else goto done; } if(isspace(c))goto space; if(c == '#' && tp > temp+1 && *(tp-2) == '\n'){ if(prect++ > 2)goto done; while(puttmp((c=Bgetc(input)),1) != '\n') if(c == '\\')puttmp(Bgetc(input),1); goto space; } if(isalnum(c)){ while(isalnum(c = Bgetc(input)))puttmp(c,1); Bungetc(input); } done: puttmp('\0',1); lastplace = tp-1; inswitch = 1; return(beg); }
static int pass1(void) { signed char o[MAXLINE]; int l,er,temp_er,al; memode=0; xmode=0; tlen=0; ner=0; temp_er = 0; /*FIXIT*/ while(!(er=xa_getline(s))) { er=t_p1((signed char*)s,o,&l,&al); switch(segment) { 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; } /*printf(": er= %d, l=%d, tmpz=%d\n",er,l,tmpz); */ if(l) { if(er) { if(er==E_OKDEF) { if(!(er=puttmp(l))) er=puttmps(o,l); } else if(er==E_NOLINE) er=E_OK; } else { if(!(er=puttmp(-l))) er=puttmps(o,l); } } if(er) { lineout(); errout(er); } /* printf("tmpz =%d\n",afile->mn.tmpz); */ } if(er!=E_EOF) { fprintf(stderr, "foul through\n"); errout(er); } /* { int i; printf("Pass 1 \n"); for(i=0;i<afile->mn.tmpz;i++) fprintf(stderr, " %02x",255 & afile->mn.tmp[i]); getchar();} */ return(ner); }
int main(int argc,char *argv[]) { int er=1,i; signed char *s=NULL; char *tmpp; 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; n65816=0; cmosfl=1; w65816=0; /* default: 6502 only */ altppchar = '#' ; /* i.e., NO alternate char */ if((tmpp = strrchr(argv[0],'/'))) { tmpp++; } else { tmpp = argv[0]; } if( (!strcmp(tmpp,"xa65816")) || (!strcmp(tmpp,"XA65816")) || (!strcmp(tmpp,"xa816")) || (!strcmp(tmpp,"XA816")) ) { w65816 = 1; /* allow 65816 per default */ } /* default output charset for strings in quotes */ set_charset("ASCII"); ifiles = malloc(mifiles*sizeof(char*)); afile = alloc_file(); if (argc <= 1) { usage(w65816, stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(w65816, stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, authors, copyright); exit(0); } ofile="a.o65"; efile=NULL; lfile=NULL; if(pp_init()) { logout("fatal: pp: no memory!"); return 1; } if(b_init()) { logout("fatal: b: no memory!"); return 1; } if(l_init()) { logout("fatal: l: no memory!"); return 1; } i=1; while(i<argc) { if(argv[i][0]=='-') { switch(argv[i][1]) { case 'p': /* intentionally not allowing an argument to follow with a space to avoid - being seen as the alternate preprocessor char! */ if (argv[i][2] == '\0') { fprintf(stderr, "-p requires a character argument\n"); exit(1); } if (argv[i][2] == '#') fprintf(stderr, "using -p# is evidence of stupidity\n"); altppchar = argv[i][2]; if (argv[i][3] != '\0') fprintf(stderr, "warning: extra characters to -p ignored\n"); break; case 'M': masm = 1; /* MASM compatibility mode */ break; case 'O': /* output charset */ { char *name = NULL; if (argv[i][2] == 0) { name = argv[++i]; } else { name = argv[i]+2; } if (set_charset(name) < 0) { fprintf(stderr, "Output charset name '%s' unknown - ignoring! (check case?)\n", name); } } 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) romaddr = atoi(argv[++i]); else romaddr = 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': crossref = 1; 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 |= FM_OBJ; break; case 'v': verbose = 1; break; case 'C': cmosfl = 0; break; case 'W': w65816 = 0; break; case 'w': w65816 = 1; break; case 'B': showblk = 1; break; case 'x': /* old filename behaviour */ oldfile = 1; fprintf(stderr, "Warning: -x is now deprecated and may disappear in future versions!\n"); break; case 'I': if(argv[i][2]==0) { reg_include(argv[++i]); } else { reg_include(argv[i]+2); } break; case 'o': if(argv[i][2]==0) { ofile=argv[++i]; } else { ofile=argv[i]+2; } break; case 'l': if(argv[i][2]==0) { lfile=argv[++i]; } else { lfile=argv[i]+2; } break; case 'e': if(argv[i][2]==0) { efile=argv[++i]; } else { efile=argv[i]+2; } break; case 'b': /* set segment base addresses */ switch(argv[i][2]) { 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,"unknown segment type '%c' - ignoring!\n", argv[i][2]); break; } 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; } } else { /* no option -> filename */ ifiles[nifiles++] = argv[i]; if(nifiles>=mifiles) { mifiles += 5; ifiles=realloc(ifiles, mifiles*sizeof(char*)); if(!ifiles) { fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n"); exit(1); } } } i++; } if(!nifiles) { fprintf(stderr, "No input files given!\n"); exit(0); } if(oldfile) { 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; } fplab= lfile ? xfopen(lfile,"w") : NULL; fperr= efile ? xfopen(efile,"w") : NULL; if(!strcmp(ofile,"-")) { ofile=NULL; fpout = stdout; } else { fpout= xfopen(ofile,"wb"); } if(!fpout) { fprintf(stderr, "Couldn't open output file!\n"); exit(1); } if(verbose) fprintf(stderr, "%s\n",copyright); if(1 /*!m_init()*/) { if(1 /*!b_init()*/) { if(1 /*!l_init()*/) { /*if(!pp_init())*/ { if(!x_init()) { if(fperr) fprintf(fperr,"%s\n",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) { r_mode(RMODE_RELOC); segment = SEG_TEXT; } else { r_mode(RMODE_ABS); } nolink = no_link; for (i=0; i<nifiles; i++) { ifile = ifiles[i]; sprintf(out,"xAss65: Pass 1: %s\n",ifile); if(verbose) logout(out); er=pp_open(ifile); puttmp(0); puttmp(T_FILE); puttmp(0); puttmp(0); puttmps((signed char*)&ifile, sizeof(filep->fname)); if(!er) { er=pass1(); pp_close(); } else { sprintf(out, "Couldn't open source file '%s'!\n", ifile); logout(out); } } if((er=b_depth())) { sprintf(out,"Still %d blocks open at end of file!\n",er); logout(out); } if(tbase & (align-1)) { sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align); logout(out); } if(dbase & (align-1)) { sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align); logout(out); } if(bbase & (align-1)) { sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align); logout(out); } if(zbase & (align-1)) { sprintf(out,"Warning: zero segment ($%04x) start address doesn't align to %d!\n", zbase, align); logout(out); } if (n65816>0) fmode |= 0x8000; switch(align) { case 1: break; case 2: fmode |= 1; break; case 4: fmode |= 2; break; case 256: fmode |=3; break; } if((!er) && relmode) h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); if(!er) { if(verbose) logout("xAss65: Pass 2:\n"); seg_pass2(); if(!relmode) { r_mode(RMODE_ABS); } else { r_mode(RMODE_RELOC); segment = SEG_TEXT; } er=pass2(); } 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); } else { logout("fatal: x: no memory!\n"); } pp_end(); /* } else { logout("fatal: pp: no memory!");*/ } } else { logout("fatal: l: no memory!\n"); } } else { logout("fatal: b: no memory!\n"); } /*m_exit();*/ } else { logout("Not enough memory available!\n"); } if(ner || er) { fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); /*unlink();*/ if(ofile) { unlink(ofile); } } free(ifiles); return( (er || ner) ? 1 : 0 ); }