LEX 'ATBINLX6' ID #5E MSG 0 POLL 0 ENTRY ATBIN$ CHAR #F ENTRY BTA$ CHAR #F KEY 'ATBIN$' TOKEN #B9 KEY 'BTA$' TOKEN #BA ENDTXT * 5E B9 F m0615B ATBIN$ * COPYRIGHT 1989 BY MICHAEL MARKOV - NOT FOR COMMERCIAL USE **************************************** * ATBINLX4 corrected a bug that flawed the BTA$ keyword in * BINLEX6 and MMLEXV04. The flaw was two-fold: first, BTA$ * did not check available memory, which could result in * Memory Lost if you did not have memory to spare. Second, * BTA$ made inefficient use of the stack, which aggravated * the first problem.. * * Both problems were solved when I realized that BTA$ converts * one to eight bytes into a single byte. Since the resulting * string is alway smaller than the input string, both goals * could be achieved by storing the resulting string right back * into the space on the stack that was used by the input string. * * ATBINLX6 improves on ATBINLX4 by a) reducing the LEX file length * significantly, and b) improving execution speed by a factor * of roughly two. * * ATBIN$ converts an ASCII string into a binary representation * of said string. For example, ATBIN$('A') => '01000001'. * * BTA$ performs the inverse operation, converting a binary * representation to the original ASCII string. It is important * to note that BTA$ right-justifies bits, just as if it added * leading '0' bytes to the input string to make sure the length * of the input string is an exact multiple of 8. This is unlike * the DOT2DOT$ and RASTER$ keywords that are otherwise equivalent. * DOT2DOT$ and RASTER$ left-justify bits. * * ATBINLX4 and ATBINLX6 are both on SWAP11 to remind us all * that folks who program in assembly tend to quit when the damn * keyword finally does what you want it to do... The relatively * long time it takes to assemble source files (unless you are * lucky enough to have an HP Portable or a PC with enough RAM to * run AREUH conveniently) generally discourages trial & error * experimentation to optimize your LEX. Here, 'tis I who should * hide my face in shame for the defficiencies of my earlier offerings. * * COPYRIGHT 1989 BY MICHAEL MARKOV - NOT FOR COMMERCIAL USE ******************************************************** ATBpop A=0 W preclear A (set-up for clean ASRB) GOSBVL #0BD38 =POP1S pop string GOSBVL #1A460 =D=AVMS standard set-up for STKCH/ADHEAD C=C+A A just past start of string R1=C save it, set-up for ADHEAD RTN NIBHEX 411 * ATBIN$ entry point ATBIN$ GOSUB ATBpop C=C-A A Calculate proposed end of output string C=C-A A this is 8 times the length of the input $ C=C-A A note that we work from end to start, C=C-A A overwriting the copy of the original string C=C-A A on the stack, maximizing available memory C=C-A A C=C-A A C=C-A A ?D>C A check to see if we have enough memory GOYES m061E5 to GOVLNG #0944D =MEMERR (sorry) R3=C This is the address D1 should point-out CD0EX when we jump to ADHEAD. Also, D0 is out output ptr. R0=C Save D0 in R0 ASRB convert input string length from nibs to bytes ABEX A use B[A] for counter P= 15 16 nibs/ 8 bytes, less 1 NXTWRD B=B-1 A have we processed the last input byte? GOC ATBex yes, quitting time LCHEX 0303030303030303 no, load '0' bytes in C[W] (w. wrap-around) A=DAT1 B get input byte D1=D1+ 2 advance pointer to next byte BIT1 P=P-1 set pointer to the '0' nibs of output in C A=A+A B test bit. If clear, we go do the next bit GONC BIT0 bit is clear, do not edit C[P] C=C+1 P bit is set, convert '0' nib to '1'. '30' byte becomes '31'. BIT0 P=P-1 move to next '0' nib GONC BIT1 if P#0 go do next bit WRIWRD DAT0=C W else output binary equivalent of byte D0=D0+ 16 advance output pointer GONC NXTWRD B.E.T. note that P= 15 when we get to WRIWRD m061E5 GOVLNG #0944D =MEMERR ATBex C=R3 done converting. Now set-up D1 for ADHEAD D1=C BTAen C=R0 restore D0 D0=C ST=0 0 we do not want to return from ADHEAD P= 0 (required entry condition for ADHEAD) GOVLNG #181B7 =ADHEAD * Note that D[A]= AVMEMS, another entry condition for ADHEAD NIBHEX 411 BTA$ GOSUB ATBpop D1=C set both the input & output pointers past CD0EX start of string, and save D0 R0=C C=A B how many input bytes in excess of a multiple of 8? CSRC CSRB P=C 15 P has count ASR W A has the number of output bytes corresponding to * sets of 8 input bytes C=0 A preclear to handle partial byte P=P-1 if P#0, go do the partial byte stuff GONC NXTBIT OUTB A=A-1 A have we output the last byte? GOC BTAen yes, quitting time P= 7 counter, we do 8 input bytes NXTBIT D0=D0- 2 advance input pointer C=DAT0 XS read least significant nib C=C+C B shift previous bits out of the way C=C-1 XS if nib=0, then the bit is clear GOC BITOFF and we skip the next step C=C+1 B no. If not '0', then we assume it is '1' BITOFF P=P-1 test for end of output byte GONC NXTBIT no, keep going D1=D1- 2 yes, advance the pointer & output it. DAT1=C B GONC OUTB and go do the next output byte, if any (B.E.T.) END