/* >> yam10.c 12-20-82 * File unsqueezer module from Richard Greenlaw's USQ * and other vital functions */ #define EXT #include "yam.h" #ifdef XMODEM #define CICHAR BCICHAR #define CIREADY BCIREADY #endif /* *** Stuff for first translation module *** */ #define USDLE 0x90 /* *** Stuff for second translation module *** */ #define SPEOF 256 /* special endfile token */ #define LARGE 30000 int bpos; /* last bit position read */ int curin; /* last byte value read */ /* Variables associated with repetition decoding */ int repct; /*Number of times to return value*/ int value; /*current byte value or EOF */ unsqueeze() { int i, c; int numnodes; /* size of decoding tree */ /* Initialization */ init_cr(); init_huff(); /* Process rest of header (SQMAGIC already read) */ getw(fin); /* ignore checksum ... */ /* List current and original file names */ fprintf(stderr, "%s -> ", Tname); while(c = getc(fin)) putc(c, stderr); putc('\n', stderr); numnodes = getw(fin); if(numnodes < 0 || numnodes >= NUMVALS) { printf(stderr, "%s has invalid decode tree size\n", Tname); return ERROR; } /* Initialize for possible empty tree (SPEOF only) */ Utility.dnode[0].children[0] = -(SPEOF + 1); Utility.dnode[0].children[1] = -(SPEOF + 1); /* Get decoding tree from file */ for(i = 0; i < numnodes; ++i) { Utility.dnode[i].children[0] = getw(fin); Utility.dnode[i].children[1] = getw(fin); } while((c = getcr()) != CPMEOF) { if( !(c=putcty(c))) continue; if(c==003 || c==CAN || c==013) { return c; } } return CPMEOF; } /* initialize decoding functions */ init_cr() { repct = 0; } init_huff() { bpos = 99; /* force initial read */ } /* Get bytes with decoding - this decodes repetition, * calls getuhuff to decode file stream into byte * level code with only repetition encoding. * * The code is simple passing through of bytes except * that USDLE is encoded as USDLE-zero and other values * repeated more than twice are encoded as value-USDLE-count. */ int getcr() { int c; if(repct > 0) { /* Expanding a repeated char */ --repct; return value; } else { /* Nothing unusual */ if((c = getuhuff()) != USDLE) { /* It's not the special delimiter */ value = c; if(value == CPMEOF) repct = LARGE; return value; } else { /* Special token */ if((repct = getuhuff()) == 0) /* USDLE, zero represents USDLE */ return USDLE; else { /* Begin expanding repetition */ repct -= 2; /* 2nd time */ return value; } } } } /* Decode file stream into a byte level code with only * repetition encoding remaining. */ int getuhuff() { int i; /* Follow bit stream in tree to a leaf*/ i = 0; /* Start at root of tree */ do { if(++bpos > 7) { if((curin = getc(fin)) == ERROR) return ERROR; bpos = 0; /* move a level deeper in tree */ i = Utility.dnode[i].children[1 & curin]; } else i = Utility.dnode[i].children[1 & (curin >>= 1)]; } while(i >= 0); /* Decode fake node index to original data value */ i = -(i + 1); /* Decode special endfile token to normal EOF */ i = (i == SPEOF) ? CPMEOF : i; return i; } char putcty(c) char c; { #ifdef RXNONO if(index(c, RXNONO)) return 0; #endif if(UsePutchar) putchar(c); else { #ifdef BTTYOUT BTTYOUT(c); #else #ifdef COREADY while (!COREADY) ; #endif TTYOUT(c); #endif } if(CIREADY) { if((c=(CICHAR&KBMASK))==XOFF) { if((c=getcty())==003 || c==CAN || c==013) return c; } else return c; } return FALSE; } char getcty() { while (!CIREADY) ; return (CICHAR&KBMASK); } listfile(name) char *name; { int c; closetx(TRUE); #ifndef XMODEM putcty('\f'); /* line printer form-feed if ^P */ #endif if(opentx(name)==ERROR) return ERROR; #ifdef XMODEM sendline(022); /* bracket with ^R and ^T for squelch */ #endif #ifdef USQ if((c=getw(fin))==SQMAGIC) c=unsqueeze(); else if(c != ERROR) { putcty(c); putcty(c>>8); /* pdp-11 sequence */ #else else { #endif while((c=getc(fin))!=EOF && c != CPMEOF) { if( !(c=putcty(c))) continue; if(c==003 || c==CAN || c==013) { break; } } } if(c != CPMEOF) putchar('\n'); /* record complete xmsn iff terminated by (CPM)EOF */ closetx(c != CPMEOF); #ifdef XMODEM sendline(024); /* squelch in case user downloading */ #endif /* cancel rest of files if ^C or ^X */ if(c==003 || c==CAN) return ERROR; else return OK; } /* fill buf with count chars padding with ^Z for CPM */ filbuf(buf, count) char *buf; { register c, m; m=count; while((c=getc(fin))!=EOF) { *buf++ =c; if(--m == 0) break; } if(m==count) return 0; else while(--m>=0) *buf++ = 032; return count; } cmdeq(s,p) char *s, *p; { while(*p) if(*s++ != *p++) return 0; return 1; } /* local tell-it-like-it-is string write function with no kbd check */ lputs(s) char *s; { while(*s) { #ifdef COREADY while (!COREADY) ; #endif TTYOUT(*s++); } }