LEX 'RPTBLEX5' ID #5E MSG 0 POLL 0 ENTRY HUGE CHAR #F ENTRY RPTBIT CHAR #F ENTRY RPTBYT CHAR #F KEY 'HUGE$' TOKEN 20 KEY 'RPTBIT$' TOKEN 21 KEY 'RPTBYTE$' TOKEN 22 ENDTXT ******************************************* * * Copyright by M. Markov. January 1989 - NOT FOR COMMERCIAL USE * * SYNTAX: A$=RPTBYTE$(B$,N) * RPTBYTE$('ABCD',3) ==> 'AAABBBCCCDDD' * Intended use: with BINLEX to blow-up graphics pictures, that is * B$=BTA$(RPTBYTE$(ATBIN$(B$),N)) * RPTBYTE$ has obvious uses of its own in programs such as HUGEJET, where bytes * are used to represent bits (X8 multiplication). * * SYNTAX: A$=RPTBIT$(B$,N) * RPTBIT$('A',3) ==> CHR$(28)&CHR$(0)&CHR$(7) * This makes more sense when you look at the binary representations: * 'A' ==> '01000001' * RPTBIT$('A',3) ==> '000111000000000000000111' * * Intended use: to blow-up raster graphic strings or pictures horizontally, * making the pictures N time as wide. Vertical blow-up is achieved by printing * the row of raster graphics two or more times. * * The inverse operation, "shrinking" a picture by a factor of 2 or 3, would be * a nice enhancement, but methodology is not easy. I may do something about it * in the future, if I get some free time. * * RPTBLEX provides two alternatives for making raster graphic images that are * 1, 2, 3, 4, 5, .... times larger than the original raster graphic string or * bit-map. * * RPTBIT$ and RPTBYTE$ have obvious uses in programs such as JUMBOJET. They * eliminate the need for a half-dozen programs - now, you just specify the * desired size multiplier. Note that you now have more choices than are allowed * by DBLW$, which only allowed only multipliers of 2,4,8... Now, any integer * multiplier can be used. * * In the JUMBOJET SOFTFONTS package, the HUGEJET printing program uses MAP$ * (JPCROM, by Tapani Tarvainen) to convert binary representations of pixels * ('0' or '1') to (' ' or CHR$(252) ), respectively. While this is one of the * intended applications for MAP$, it is relatively slow and inconvenient... * * HUGE$(B$) is equivalent to MAP$(B$,'01',' '&CHR$(252)), but about 40% faster. * * Reference: TJDOTLEX, better known as DOT2DOTLX, CHHU Chronicle V2N7 * The disassembly of STRINGLX and STRBOOLX/GRAPHLX provided useful insights. ******************************************** NIBHEX 411 HUGE CD1EX save the header address in R0 R0=C D1=C restore the pointer A=0 W GOSBVL #0BD38 =POP1S Pop the parameter on the stack ASRB convert the length to a byte count B=A A use B[A] as a counter LCASC '0' D=C B LC(2) 252 CHR$(252) A=C B P= 1 Hconv B=B-1 A decrement counter, we want to exit on carry GOC HUGEen last byte was processed, or length was 0 to start with C=DAT1 B get byte in string ?D#C B GOYES HUGE1 C=C-1 P convert '0' to ' ' (HEX 30 to HEX 20) DAT1=C B D1=D1+ 2 GONC Hconv B.E.T. - go process next character, if any HUGEen C=R0 D1=C GOVLNG #0F23C =EXPR HUGE1 C=C-1 B convert '1' to '0' ?D#C B not '0'? GOYES argerr sorry, we expect ONLY '0' or '1' DAT1=A B store CHR$(252) D1=D1+ 2 advance to next character GONC Hconv B.E.T. - go process next character argerr GOVLNG #0BF19 ARGERR NIBHEX 8422 RPTBYT ST=1 0 GOTO RPTB01 * argerr LCHEX 0B eInvalid Arg * GOVLNG #09393 =MFERR NIBHEX 8422 RPTBIT ST=0 0 RPTB01 GOSBVL #136CB =RNDAHX GONC argerr D1=D1+ 16 ?A#0 A GOYES Smult A=A+1 A Smult R0=A save multiplier in R0 A=0 W Neat trick! After POP1S or REVPOP, you * can convert the string length from nibs to bytes without using another * register! (with ASRB) GOSBVL #0BD38 =POP1S pop string ?A#0 A GOYES notNul not a null string, go repeat D1=D1- 16 null string, we exit here GOVLNG #0F23C =EXPR notNul R2=A save string length GOSBVL #1A460 D=AVMEMS C=C+A A addr of first char R1=C save it in R1 C=R0 get the multiplier GOSBVL #1B349 =A-MULT on exit, A[A]=string length*multiplier C=R1 get addr of first char C=C-A A addr of proposed last char R3=C GOC o00C80 to GOVLNG #0944D =MEMERR GOSUB SAVED0 uses A[A], D0 CD0EX D0 @ proposed last char D0=D0- 16 room for header CD0EX D0=C D0=D0+ 16 our output pointer ?C>D A enough memory? GOYES rpt30 o00C80 GOVLNG #0944D =MEMERR sorry! rpt30 A=R2 input string length ASRB convert to byte count ?ST=1 0 RPTBYTE$? GOYES rpt31 yes, go to the byte duplication loop R2=A and save NXTBYT A=R2 byte counter A=A-1 A decrement R2=A store new count GOC bldhed done, go build head A=DAT1 B ASL W ASL W LCHEX 80 A=C B A=A+A W D1=D1+ 2 NXTBIT AR0EX B=A A AR0EX SB=0 ASRB ?SB=0 GOYES OUTBIT GONC NXTBYT B.E.T. OUTBIT B=B-1 A GOC NXTBIT C=A XS SB=0 CSRB ?SB=0 GOYES OUTBIT DAT0=C B LCHEX 80 D0=D0+ 2 GONC OUTBIT B.E.T. bldhed C=R3 last char D1=C set pointer GOSUB RESTD0 P= 0 ST=0 0 we want to return from ADHEAD GOVLNG #181B7 =ADHEAD add string header * The RPTBYTE$ code follows. rpt31 B=A A save string length in B[A] (nib length) nxtbyt B=B-1 A decrement counter GOC bldhed done, go build head A=DAT1 B C=R0 The multiplier wrtbyt C=C-1 A repeat counter GOC bytfin exit if count is 0 (carry) DAT0=A B D0=D0+ 2 GONC wrtbyt B.E.T. bytfin D1=D1+ 2 GONC nxtbyt B.E.T. RESTD0 D0=(5) #2F8BB RAM=FUNCD0 A=DAT0 A D0=A RTN SAVED0 AD0EX D0=(5) #2F8BB RAM=FUNCD0 DAT0=A A RTN END