/* * File: putobj.c * * Contains: putobj, bytdsk, putrel, dskword, outnam, * chkhed * * This routine will store a byte of code in the object buffer. */ #include "asm.h" static char xcount; char chkhed_sw = 0; extern int ObjBytes; /*. ************************************************************************* * * * putobj * * ------ * * * * * * * * * ************************************************************************* */ void putobj() { #if DEBUG printf("putobj\n"); #endif if (!(is_on(AFADIS) || is_on(AFSYMB) || ascdno)) return; if (frstsw == 0 && mode != ASEG) chkhed(); if (is_on(AFO4HD)) putrel(); if (is_on(AFADIS)) { turn_off(AFADIS); clsrec(); } if (ascdno) { bytdsk(ascdno); ascdno = 0; } } /*. ************************************************************************* * * * clsrec * * ------ * * * * close an object record * * * * * * * ************************************************************************* */ void clsrec() { register int i; register unsigned char *optr; #if DEBUG printf("clsrec\n"); #endif if (frstsw == 0 && mode != ASEG) chkhed(); if (opnrec && objbuf[0]) { #if DEBUG printf("clsrec: write to object file\n"); printf("clsrec: count=%d high address=%02X low address=%02X\n",objbuf[0],objbuf[1],objbuf[2]); #endif if (mode == ASEG) { xwrite(':'); chksum = 0; optr = objbuf; for(i = 0; i < (NUM_BYTES + 1);) { ++i; putchk(*optr++); } putchk(0); i = objbuf[0]; while(i--) putchk(*optr++); puthex((~chksum) + 1); xwrite('\n'); } else { putX(1); objbuf[0] += 2; putX(objbuf[0]); putX(objbuf[2]); putX(objbuf[1]); optr = &objbuf[3]; objbuf[0] -= 2; i = objbuf[0]; while(i--) putX(*optr++); } opnrec = 0; objbuf[0] = 0; } } /*. ************************************************************************* * * * endrec * * ------ * * * * * * * * * ************************************************************************* */ void endrec() { register unsigned char head1, head2; clsrec(); if (mathfg & MFEXT) { proces(); head1 = O3H; head2 = 2; asscod[0] = odint1 & BYTMSK; asscod[1] = (odint1 >> 8) & BYTMSK; traout(odint1, head1, head2); } else { head1 = (hdchg == 1) ? 2 : hdchg; head2 = (mathfg & MFRLEX) ? 3 : 2; traout(addisr, head1, head2); } (void) fclose(objfile); objfile = 0; } /*. ************************************************************************* * * * putrel * * ------ * * * * output relocatable object * * * * * * * ************************************************************************* */ void putrel() { register int i = 0; #if DEBUG printf("putrel\n"); #endif turn_off(AFO4HD | AFADIS); if (outchg != O7H && !ascdno && (mathfg & MFENT) == 0) return; if (outchg != O7H && ascdno && mathfg & MFRLEX) { /* * dump leading code */ ++adroff; i = (adroff <= ascdno) ? adroff : ascdno; bytdsk(i); adroff -= i; ascdno -= i; } clsrec(); putX(outchg); putX(o4cnt); putX(is_on(AFHILO) ? hilow : (hilow | O4FULL)); if (mathfg & MFENT) dskword(entadr); if (is_on(AFHILO)) { turn_off(AFHILO); dskword(hladdr); ascdno = 0; } else if (outchg != O7H && (mathfg & MFRLEX) == 0) dskword(0); else { putX(asscod[i++]); putX(asscod[i]); ascdno = 0; } if (hilow & O4NAME) { if (hilow & O4ENT) outnam(o4entb, slenth); if (hilow & O4EXT) outnam(o4extb, slenth); } } /*. ************************************************************************* * * * bytdsk * * ------ * * * put one byte in the object code buffer * * * * * * * ************************************************************************* */ void bytdsk(counter) register int counter; { register unsigned char *cptr,*aptr; #if DEBUG printf("bytdsk\n"); printf("bytdsk: counter = %d\n",counter); printf("bytdsk: addisr=%04X\n",addisr); #endif if (opnrec == 0) openr(); /* * get pointer to objbuf size counter */ cptr = objbuf; aptr = asscod; while(counter--) { if (objbuf[0] == MAXOBJ || (mode == ASEG && objbuf[0] == ObjBytes)) { clsrec(); openr(); } objbuf[ocount++] = *aptr++; (*cptr)++; ++addisr; } #if DEBUG printf("bytdsk: addisr=%04X\n",addisr); #endif } /*. ************************************************************************* * * * dskword * * * * output a word to disk * * * * * * * ************************************************************************* */ void dskword(value) register unsigned short value; { puthex(value & BYTMSK); puthex((value >> 8) & BYTMSK); } /*. ************************************************************************* * * * outnam * * ------ * * * * output a name to the relocatable header * * * * * * * ************************************************************************* */ void outnam(pnt,length) register char *pnt; register int length; { register int i; i = 0; while(length--) putX((pnt[i]) ? pnt[i++] : SPACE); } /*. ************************************************************************* * * * chkhed * * ------ * * * * check if 06 header needs to be output and output it * * * * * * * ************************************************************************* */ void chkhed() { #if DEBUG printf("chkhed\n"); printf("chkhed:frstsw=%d absflg=%d\n",frstsw,mode); #endif hdflag = ptable[pdef]; frstsw = 1; if (chkhed_sw == 0) { putX(0x04); putX(0x01); chkhed_sw = 1; } putX(O6H); putX(10); putX(hdflag); putX(slenth); dskword(eaddr); outnam(pbuffr, 6); hdflag = 0; } /*. ************************************************************************* * * * openr * * ----- * * * * open an object record * * * * * * * ************************************************************************* */ void openr() { #if DEBUG printf("openr\n"); printf("openr: addisr=%04X offset=%d\n",addisr,offset); #endif ocount = 3; addisr += offset; objbuf[0] = 0; objbuf[1] = (addisr >> 8) & BYTMSK; objbuf[2] = addisr & BYTMSK; opnrec = 1; } /*. ************************************************************************* * * * putchk * * ------ * * * * write a byte WITH checksum * * * * * * * ************************************************************************* */ void putchk(byte) unsigned char byte; { chksum += byte; (void) fprintf(objfile,"%02X",byte); xcount += 2; if (xcount >= 79) { fprintf(objfile,"\n"); xcount = 0; } } /*. ************************************************************************* * * * puthex * * ------ * * * * write a byte WITHOUT checksum * * * * * * * ************************************************************************* */ void puthex(byte) unsigned char byte; { if (mode == ASEG) { fprintf(objfile,"%02X",byte); xcount += 2; if (xcount >= 79) { fprintf(objfile,"\n"); xcount = 0; } } else putX(byte); } /*. ************************************************************************* * * * xwrite * * ------ * * * * write a byte to the disk file * * * * * * * ************************************************************************* */ void xwrite(byte) unsigned char byte; { putX(byte); if (byte == '\n') { xcount = 0; return; } xcount++; if (xcount >= 80) { putX('\n'); xcount = 0; } } /*. ************************************************************************* * * * traout * * ------ * * * * output the transfer address * * * * * * * ************************************************************************* */ void traout(address, head1, head2) unsigned short address; unsigned char head1, head2; { if (mode == ASEG) { xwrite(':'); puthex(0); chksum = 0; putchk(address >> 8); putchk(address); putchk(1); puthex((~chksum) + 1); xwrite('\n'); } else { putX(head1); putX(head2); putX(address & BYTMSK); putX((address >> 8) & BYTMSK); if (mathfg & MFEXT) outnam(o4extb,slenth); } } void putX(byte) unsigned char byte; { (void) putc(byte, objfile); }