#@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr COM TOOL V1.0-------------A long time ago I made a useful utility to convert an appended (*) COM file into original data f}iles. That program was written in Turbo Basic and I've used it often. One day I thought about changing the program a little s}o it could also be used to get info from an appended COM file which is possible with 'Turbo dos' (option HEA). I also thought} about some more nice options and I finally decided to start all over again, but this time I would use assembly. The result }of my work is an very short executable (COM) file of about three kilobyte named COMTOOL.COM (CT). The program and source code } are shareware so please don't spread the program without this text. Shareware means that you should send me a donation if yo }u like the program or if you use source code (or parts of it!!).* An appended COM file is the final (executable) file which } mostly consists of many (short) files.With the program you can rip COM files and get info about a COM file. The usage is v }ery easy. Simply use the cursor keys (without the control key), the RETURN key and ESCape.After booting the program you'll }get a menu with only two options "Show info" and "Strip file".If you want to know how a certain COM file is build you can se}lect the 'Show info' option. When you select it (by pressing RETURN) it will ask you to select a drive (from 1 - 8). Yes! You} can use the ramdisk! After selecting the drive it will display the directory of that drive and the first item on the list wi}ll be displayed inverse. Now you can select the file by using the cursor keys and RETURN. Directly after selecting the file t}he program displays a table and starts to fill it with hex numbers. If you didn't select a COM file it will only load the who}le file and display the length.But if you choose a COM file it will nicely display the START and END addresses, followed by }the lenght of that part. If we're dealing with a RUN or INIT address the program will also display the contents of it in the }RUN/INI column. Hue what? Simple, you can exactly locate the RUN and INIT addresses of the examined COM file! Maybe you like }to roam around in a demo file, so now you can write all the addresses down (or make a screendump with help of Qmeg, Supermon }or whatever). It could happen that a "!" sign appears in the RUN/INI column. This means that CT discovered a part which was b}igger than 32K (this is the max. size of the CT buffer). There's nothing you can do about that or eh.. well, maybe I'll enlar}ge the buffer in a future version.Let's select the other option 'Strip COM file'. You'll notice that it's almost the same a}s the 'Show info' option. However, with this option you can actually strip the COM file and store its clothes on a disk!Ther}e's another difference, right after you've selected the 'load' file CT will ask you to select a drive again! This is nessesar}y because CT wants to know on which drive you would like to store the stripped parts. It won't ask for a 'save' file. The sav}e filename is build from the load filename and a number. For example, if you strip a file named 'LITTLE.COM' CT will create s}ave files like 'LITTLE.001', 'LITTLE.002' and so on. WARNING! Never strip a file with the extension '001' or any other number} because in that case CT could destroy the original!After displaying a normal START, END and LENGHT it will ask you if you w}ant to rip that part. If you answer 'N' it will continue to show the info of the next part. In case you answer 'Y', CT will s }tore that part on the earlier selected drive and a '*' sign appears in the RUN/INI column.The RESET key can be used to retu!}rn to DOS and press ESC if you want to go back to a previous level.So, what's the use of all this? I don't know why it's us"}eful for you but I'll tell you why I made/use my short utility.I've been programming for a long time in the ATMAS (assembler#}) and always got sick of all those short COM files. All my disks are full of these 'what the hell is this' files. Every time $}I made I demo I got a disk full of crap, the source code and the final COM file. Now I can simply delete all the crap and the%} only two things that remain are the source and the final version. CT can strip the final version into all those short files &}again so nothing is lost!Because of the fact that I now use ATMAS and ST-65 (a cross assembler for the XL/XE on the ST) ther'}e was another problem. Since ATMAS loves COM files and ST-65 loves pure data files (and I like pure data too because it's rel(}ocatable) I had to convert these files. This can be done with help of a simple Turbo Basic program but now I can use CT for t)}his job so I don't need to load Turbo Basic anymore.Some technical info:CT is loaded at $2800 so it won't cause trouble wi*}th most DOS's (I hope).The source is written for ST-65. More info about ST-65 can be found in the first issue of MegaZine.I+}n the source you can find a 'file selector'. If you like to use this please let me know.The 32K buffer starts at $3C00.I'm,} planning to release a more powerful version of CT in the future. Here's a list of possible extensions of the program:- A fi-}le builder which makes it easy to append files- A larger buffer (42K or 46K)- A print option- More features in the strip f.}unction.- A protector so you can protect COM files from people who want to change them with help of a sector editorWell, i/}f you can think of some more features please let me know so I can think about it!Greetinx!-Frankenstein-Reactions/donat0}ions to:The High-Tech TeamP.O. Box 1648800 AD Franeker(Frl.) Hollandut it!Greetinx!-Frankenstein-Reactions/donatK(0X.Y. - -(( -0.1 (.. ( , ,;. (..آ.L:(ש. (2}..к. 6*  . ( )*L2(// c,.H (h`.(((((( .` `3}... 6* U. - , - ) )` - ) - * * - - )-.) ,L. -.... ;-L)." , ,4}( g. . ). L.! .. )* - ,L)i(i -< < -L)<<`.. -.i..i5}. )-`<.<.`<.<.`.8.......` {- , , ,`. c,. '/0 '/ - -,/(6}.  `)i1}0m0.` ,..B|D0EHIJ V0wBHID0E V0W7}HP08 Ƚ08 .. .i i..@Љ L..T/( )*L9*.. Z8}, - - u, , ,L9*3}0m0Ii ..o0 n0.ʩo0` u,3.i.... .i 9}iLl+6.8).ο...8 Ll+.i.. -Ll+.80.8(Ll+X:}Y` Z, , - Z,`I `  `(`.`.XiPYi` ,`` j-;}(` j-D0( , ,+` j-!` M-. S-. S-` M-. S-. S-` M-. S-. S-` M-< S-< S-``HJJJJ<}.h).` Z,ii` j-0(` Z,|/( -/( - ,`i(i`..B=}.H.ID}`..o0`.o0o0:0o0o0o0: 0o0o0`.000ppB.BA.?}!"#$%&35  3(/7&),%).&/342)0#/-&),%02%33&/2$)2%#4/29@}4()3$)3+)3%-049||||A},/!$&),%3!6%&),%B}D?:FILENAME.EXTD?:*.*FRANKENSTEIN RULEZ(T+ X; COM TOOL V1.0$X; A UTILITY FOR ATARI COM FILES!"X; (C)1991 DONE BY FRANKENSTEIN((2LCHAN;; CHAN.1<D}SCHAN ;; CHAN.2F ICCOMBP ICBALDZ ICBAHEd ICBLLHn ICBLHIx ICAX1J CIOVVSCRN;; (ANDE} $F1)BARZP;; (AND $F3)WRITLIN;; (AND $F5)BUFFER<BUFLENMAXCH;; MENU OPTIONSX; SET MEM. F}POINT IN DLCOMTOOLQXPLH PSCRNQY PLH PSCRN#X; MAKE TABLE FOR 2 SCREEN LINES INCSCR" INCSCG}R,%>6TABSLQSCRN@ PLINELO8J QSCRNT PLINEHI8^ INCSCRh3r)>| HTABSL$X; --------- THE MENU ---------H}-- Q>DLP0 Q>DLP1MENU SHOWMENU INICH$> &CHOICEINVITQ>;; INVERT ON $CHOICE SHOI}WOPTCHECON KEYWAITSLOOP SCAN(> FSELDUS(>& HDOWNO0X; BAR DOWN:Q>;; INVERT OFFD $CHOICEN SHJ}OWOPTX #CHOICEb $CHOICEl (>MAXCHv HINVIT$>MAXCH &CHOICE !INVIT DOWNO(> HSLOOP X; BAR UPQ>K};; INVERT OFF $CHOICE SHOWOPT "CHOICE QCHOICER> HINVITQ>  PCHOICE FINVIT X; CHOICE IS SELECTL}ED*SELDUSQ>;; LOAD4 SELECT> HABRTHQ>R $>LCHAN\ OPENf DOITp PRESANY;; ANY KEY..zABRT!MENU X; TAM}BLESOPTABLO F0 F1OPTABHI F0 F1LINELO =LINEHI =X; SHOW MENUSHOWMENU CLN}SQ> PINVFLAG$> DRAWMENA5Q>;; INVERTED OFF SHOWOPT$7.>82B (>MAXCHL HDRAWMENV:`(X; SHOO}W A MENU OPTION, X = CHOICE NR.jSHOWOPTPINVFLAGt QLINELO9~ PSCRN QLINEHI9 PSCRN QOPTABLO9PSEMOCOP} QOPTABHI9PSEMOCO$>%> SEMOCOQ9 LINVFLAG P@SCRN732 (> HSEMOCO:(X; CONSOLE CHECQ}K2CONSOLQ < HCONSOLFQP:Z!X; JUMP TO THE CHOSEN PROGRAM!dDOITQCHOICEn PFLAGx$X; ---- SHOW FILE INFO, RIPR} ----- QFLAG FNORIPX; WANNA RIP!Q>;; SAVE SELECT;; SELECT DRIVE SFRES;; RESET SAVE FILENAMENORIP MS}AKTB;; TABLE LAYOUT LZP;; RESET LINE POINTER TWOGET COMCHK FSKIPPEX; DATA FILE DATLOAD:&X; FILE STT}ARTS WITH $FF,$FF -> COM!SKIPPE TWOGET;; LOAD ADR."'CONPRG0 DEFLOAD;; DEFINE LOAD ADR., TWOGET6 DEFEND;; DEFINEU} END ADR.@ DEFLEN;; DEFINE LENGTHJ SHOWLOADT SHOWEND^ SHOWLENh QLENrM>;; LEN > 32K ?| FWILLFIT ITSV}BIG !EXITNOWWILLFIT LOAD QLEN HLONGQLENR> HLONGX; CHECK RUN/INIT ADR.QLOADADRR>W} HLONG QLOADADRR>FRAR>& HLONG0RA SHOWRI: !INFONLYDLONGQFLAGN FINFONLYXX; FLAG = 1, RIP IT!bX} ASKRIPl6v CLRMSG8 HINFONLY SFINC;; FILE.001Q> $>SCHAN OPEN SAVE $>SCHAN CLOSE%>Y}! Q> ;; "*"P@WRITLIN7X; INFO ONLYINFONLY#LINE  QLINER>  HNIVOL* PRESANY4 MAKTB> LZPH !CON0Z}RNIVOLQWRITLIN\,fO>(p PWRITLINzQWRITLINO>PWRITLINX; ALWAYS SKIP $FF,$FFCON0 TWOGET QB[}UFFERR>HNOOQBUFFERR>HNOO TWOGETNOO!CONPRG0X; CHECK FOR COM FILE COMCHKQBUFFER R>\} HNOCOM$ QBUFFER. R>8 NOCOM:B X; LOAD DATA, DISPLAY LENGTHL DATLOADQ>V PLEN` PLENj LOADt QLEN~ ]}, O> PLEN QLEN O> PLEN SHOWLEN : X; DEFINE LOAD ADR. DEFLOADQBUFFER PLOADADR QBUFFE^}R PLOADADR : X; DEFINE END ADR. DEFENDQBUFFER PENDADR( QBUFFER2 PENDADR< :F X; DEFINE LENGHTP_} DEFLENQENDADRZ ;d SLOADADRn PLENx QENDADR SLOADADR PLEN #LEN HONEMORE #LEN ONEMORE:`} X; ANY KEY.. PRESANY SHOWANY KEYWAIT GETKEY CLRMSG : $X; ------- FILE SELECTOR -------- 0X; THIS PROGRAa}M WILL DISPLAY THE DIRECTORY OF 6X; A CHOOSEN DRIVE (1-8) AND LET YOU SELECT A FILE! 3X; NORMAL EXEC: FNAME CONTAINS THE SEb}LECTED FILE" X; A (ACCU) = 0, X; ABORTED : A (ACCU) = 16 X; SCREEN SETUP@ #SELECTPLSFLAG;; LOAD/SAVE FLAc}GJ NEWDRIV CLST QLSFLAG^ HSAVMh X; A = 0, LOAD!r %>'| LOACPQLOAMSG8 P@SCRN7 1 ILOACP GCSEL X; A <> d}0, SAVE! SAVM%>' SAVCPQSAVMSG8 P@SCRN7 1 ISAVCP CSEL INCSCR INCSCR %> INSCPQINSMSG8 P@SCRNe}7 3& )>(0 HINSCP: X; SELECT DRIVED SCKEY$>N NKCMPQX RKTDS9b FTOUCHEDl 2v (> HNKCMP FSCKEY TOf}UCHEDQ> P (> ;; ESC? HNESCA Q> : NESCAA M>;; 8 = RETURN , O>1 PDNAME PFNAME QLSg}FLAG FLOADFL :* LOADFL DELINE4 %X; INIT. LINE COUNTER AND ENTRIES!> Q>H PLCNTR PENTRS\ X; OPEN DIRECTORYf $>h}LCHANp Q>;;OPENz PICCOM9 Q>DNAME PICBAL9 Q>DNAME PICBAH9 Q> PICBLL9 Q> PICBLH9 Q>;i};DIR PICAX19 CIOV GCLOZ X; GET A FILENAMEGETFN$>LCHAN Q>;;GET PICCOM9$Q>. PICBLL98Q>B PICj}BLH9LQ>DIRECV PICBAL9`Q>DIRECj PICBAH9t CIOV~ GCLOZ QICBLL9R> FCLOZ X; DISPLAY FILENAME ONk} SCREEN$>%>SHOWERQDIREC9;S>  P@SCRN732(>  HSHOWERQ> P@SCRN7( SHEXT32QDIl}REC9<;FS> P P@SCRN7Z2d(> n HSHEXTx #LCNT QLCNTR> HNOPROBQ> PLCNT #SCRN HNOPROB m}#SCRNNOPROBQSCRN,O>  PSCRN QSCRNO> PSCRN #ENTRS" QENTRS,R>@6 HGETFN@CLOZ$>Ln}CHANJ CLOSET QENTRS^ HFILSELh%>rDPDMSGQEMDIS8| P@SCRN73)>( HDPDMSG PRESANY !NEWDRIVX; FIo}LE SELECTOR!FILSELQ> PCHOOS PLCNT SETMP INCSCR INCSCRWOPPA INVERTBEK KEYWAITSCKEY2 SCAp}N(>& HNONESC0 !NEWDRIV:NONESC(>;;D HDIZNOTNX; MAKE FILENAME!XOTHERQDNAME;; DRIVE NR.b PFNAq}MEl%>v$>CFNQ@SCRN7N>FNULL;; A SPACE!,O> R>.;; DOT? HNODOT &DOTHERENODOTPFNAMEr}92 NULL3)> HCFN$X; LAST CH. MAY NOT BE A DOT! "." QFNAME9R>. HZEE*04 ZEEQ>>PFNAME9s}HQ>R:\DIZNOT INVERT;;NORMALf(>p HNRIGHTz QCHOOS,O> RENTRS FWOPPA PCHOOS #LCNT QLCNTt}R> HHEBUURQ> PLCNT #SCRN HHEBUUR #SCRNHEBUURQSCRN,$O> . PSCRN8 QSCRNBO>L Pu}SCRNV !WOPPA`NRIGHT(>j HNLEFTt QCHOOS~;S>R> FWASSA PCHOOS "LCNT QLCNTR> HTORNADv}OQ> PLCNT "SCRN QSCRNR>  HTORNADO "SCRNTORNADOQSCRN(;2S> < PSCRNF QSCRNPS>Z w}PSCRNdWASSA!WOPPAn NLEFT(>x HNDOWN QCHOOS,O> RENTRSEWOP PCHOOS INCSCRWOP!WOPPAx}X; NOT RIGHT, LEFT OR DOWN??X; THIS MUST BE UP THEN!NDOWNQCHOOS;S> GWOP0 PCHOOS QSCRN";,S>(6 Py}SCRN@ QSCRNJS>T PSCRN^WOP0!WOPPAh SETMPQXr PSCRN|QY PSCRN:X; CLEAR SCREENCLS SETMz}P$>WISCR DELINE INCSCR0 HWISCR SETMP:INVERT%>BLOKIESQ@SCRN7N> P@SCRN73&)>{} 0 HBLOKIES::D PAUSEQ>NP X WEETQ b HWEETl:vDELINE%>CWISREGP@SCRN73)>( HWISREG:|}!X; SCAN UP, DOWN, LEFT, RIGHT! SCAN$>NKCMP2Q RKTFS9 FTOUCH22(> HNKCMP2  FSCANTOUCH2Q> }}P*:4X; LINE ZP!> LZPQ>H PLINERQX\,fO>Pp PWRITLINzQYO>PWRITLIN:X; KEY WAITKE~}YWAITQ>P PAUSE: X; GET KEYGETKEYQR> FGETKEY:X; CLEAR MSG.CLRMSG LASTLIN%>$Q}>.FILINVP@SCRN783B)>(L HFILINVV:`X; ASK RIP!jASKRIP LASTLINt%>~CORIPQRIPMSG8 P@SCRN73)>}( HCORIP KEYWAIT GETKEY R>+;; "Y":X; PART IS TOO BIG!ITSBIG LASTLIN%>! Q>;; "!"P@WRITLI}N7 :X; SHOW LOAD ADR.SHOWLOAD%>( STRING2QLOADADR< OUTHEXF QLOADADRP OUTHEXZ:dX; SHOW END ADR.}nSHOWEND%> x STRINGQENDADR OUTHEX QENDADR OUTHEX:X; SHOW LEN.SHOWLEN%> STRING QLE}N OUTHEXQLEN OUTHEX:X; SHOW RUN/INITSHOWRI%> STRING"QBUFFER, OUTHEX6 QBUFFER@ OU}THEXJ:TX; PUT STRING SIGN ($)^STRINGQ>hP@WRITLIN7r3|:X; HEX OUTPUT TO SCREEN OUTHEX5V?V?V?V}?> QHEXSTR9P@WRITLIN737M>;;%1111> QHEXSTR9P@WRITLIN73&:0X; PUT PTR. TO LAST LINE:LAS}TLIN SETMPD QSCRNN,XO>b PSCRNl QSCRNvO> PSCRN:X; ANY KEY..SHOWANY LASTLIN%>CAMS}GQANYMSG8 P@SCRN73)>( HCAMSG:X; MAKE TABLEMAKTB SETMP%> NURDQTABTOP8 P@SCRN7 3*)>(4} HNURD>$>HNNEE INCSCRR%>\COPLQTABLN8f P@SCRN7p3z)>( HCOPL2(> HNNEE INCSCR CLRM}SG:X; SCRN = SCRN + 40INCSCRQSCRN,O>( PSCRN QSCRNO> PSCRN:$X; GET TWO BYTES!.TW}OGETQ>8PLENBQ>L PLENVX; LOAD DATA`LOAD$>LCHANj Q>;; GETt PICCOM9~QLEN PICBLL9 QLEN PI}CBLH9Q>BUFFER PICBAL9Q>BUFFER PICBAH9 CIOV INOLER)> HERROR $>LCHAN QICBLL9 PLEN} QICBLH9 PLEN(EXITNOW$>LCHAN2 CLOSE< NOLER:FERROR$>LCHANP CLOSEZ7d7n:xX; OPEN FILEOPENPI}CAX19Q> PICCOM9Q>FNAME PICBAL9Q>FNAME PICBAH9 CIOV GERROR:X; SAVE DATASAVE$>SC}HAN Q> ;; PUT PICCOM9QLEN PICBLL9" QLEN, PICBLH96Q>BUFFER@ PICBAL9JQ>BUFFERT PICBAH9^ }CIOVh GERRORr:|X; CLOSE CHANNEL CLOSEQ>  PICCOM9 CIOV:HX; ROUTINES TO GET SAVE FILES LIKE; FILE.001, F}ILE.002, FILE.003 ETC.X; SAVE FILENAME RESET SFRES%> $DOTHEREFINFNQSFINIT8PFNAME923)> HF}INFN : X; SAVE FILENAME INCREASE& #SFINC$DOTHERE;; HERE'S THE DOT0 2: 2D 2N #FNAME9X QFNAME9b R>:;; >9 ?}l HQINCv Q>0 PFNAME9 0 #FNAME9 QFNAME9 R>: HQINC Q>0 PFNAME9 0 !#FNAME9;; NO CH}ECK IF >999 QINC: SFINIT A.000A  !X; DL ! DL p=p! B ! TOPMSG*! 4! B>! LH H! ====R! }=====\! =====f! =====p! Az! DL! LSFLAG !INVFLAG !DOTHERE ! FLAG }! LINE ! CHOICE ! LCNT ! ENTRS ! CHOOS !LOADADR =!ENDADR =! LEN =!X; HEX STRING!"}HEXSTR A0123456789ABCDEFA"!X; KEYCODE TAB. DRIVE SELECTOR"KTDS ===$" ==3=5= =." X; KEYCODE TAB. FILE S}ELECTOR8"KTFS ==== =B"6TOPMSG Aֱ̠͠é٠ΠAL"F0 ASHOW FILE INFOAV"F1 ASTRIP} COM FILEA`"6INSMSG A PRESS 1..8 FOR DIRECTORY Aj"5EMDIS A THIS DISK IS EMPTY At"6TABT}OP AĠĠȠίA~"5TABLN A | | | | A"6LOAMSG A } LOAD FILE: A"6SAVMSG A SAVE FILE: A"6ANYMSG AӠ٠٠ϠŠ}A"6RIPMSG AРӠԿٯΩA"!X; HERE WE CREATE THE FILENAME"FNAME AD?:FILENAME.EXT}A" "X; THE DIRECTORY MASK"DNAME AD?:*.*A" "X; ENTRY BUFFER"DIREC AFRANKENSTEIN RULEZA# # COMTOOLT|"X; LZW packer v1.2 source codeX; by WosFilm 1993-03-28EIX;#X; Don't forget to specify input#X; and out }put filenames at linesX; 9100 and 9105!X; TBL`;; Start of table $X; Table size shall be a multiple X; of 3  }ENDTBL- CIOV ICCOMB ICBADD ICBLNH ICAUXJ P1 P2 NEXTPRUNAD$>; }; Open inputQ>;; file PICCOM9Q>IFILE PICBAD9Q>IFILEPICBAD9 Q> PICAUX9Q>PICAU }X9 CIO$$> ;; Open output)Q>;; file. PICCOM93Q>OFILE8 PICBAD9=Q>OFILEBPICBAD9GQ>L P }ICAUX9QQ>VPICAUX9[ CIO` WRITE;; Write texte PACK;; Pack the file!j$>;; Close inputoQ> ;; filet PI }CCOM9y CIO~$> ;; Close outputQ> ;; file PICCOM9 CIO:;; Return to DOSPACK INITBL;; Init P2 GETCHA };; Get byte fromPSTRING;; input fileP10Q>;; 0=1 byte inPFLAG;; STRINGP11 GETCHA;; Get byteEP13;; End o }f file?PCHR SEARCH;; Is STRING+CHREP12;; in the table?Q>;; $80=2 or morePFLAG;; bytes in STRING QCHR; }; STRING=STRING+PSTRING;; CHR!P11P12 OUTPUT;; Output CODE  ADDTBL;; Add STRING +CHR%QCHR;; to string table }*PSTRING;; STRING=CHR+PCODE;; CODE=CHR,Q>- PCODE/!P100P13 OUTPUT;; Output CODE1QBITCT2;; Output all2 }V?;; bits left3EP154P14 PUTCHA5DP149P15:;; Finished!INCP1QP1;; Increase P1,;; to point toO>;; nex }t linkDI10 #P1 I10PP1#LINK;; Increase LINKHI11 #LINKI11:` ADDTBL%>e QCODE;; Write a lin }kj P@P27;; to STRINGo 3t QCODEy P@P27~ 3 QCHR;; Append CHR to P@P27;; STRING QNEXT;; Last available  }RBITCT3;; table entry? DA11 QNEXT R> HA11 UBITCT3;; Increase CODE TBITMSK;; length A11#NEXT;; Increas }e NEXT HA12;; pointer #NEXT A12QP2;; Increase P2 ,;; pointer to O>;; point to next DA13;; entry #P2 } A13PP2 QP2;; Is end of R>END;; string table HA14;; reached? QP2 R>END DA14  INITBL;; Re }init NEXT ;P2 and CODE A14:;; length INITBLQ>TBL PP2 Q>TBL PP2 $> &BITMSK &BITCT3 & }NEXT 0 &NEXT : GETCHA$>;; Get byte from Q>;; input file PICCOM9 Q> PICBLN9 Q> PICBLN9 } Q>BYTE PICBAD9 Q>BYTE PICBAD9  CIO GG11;; End of file? #IN HG10 #IN G10%>.;; Writ }e how many QIN;; bytes has been  WRTHEX;; input %>, QIN WRTHEX QBYTE ,! :& G11;;; End of file+ :l } OUTPUTQCODEq PTMPv QCODE{ PTMP Q> PCNT O10TTMP;; Output all 8  PUTCHA;; bits of CODE "CNT;; }LSB HO10 O11QTMP;; Output needed MBITMSK;; MSB bits , FO12 ; O12 PUTCHA QBITCT1 MBITMSK HO13 } TTMP TBITCT1 !O11 O13Q>;; Reset BITCT1 PBITCT1 : PUTCHAUOBYTE;; Output OBYTE TBITCT2;; when it' }s DO14;; filled with 8 UBITCT2;; bits  PUT ; O14: PUT$> ;; Write OBYTE Q> ;; to output PICCOM9;; file } Q>OBYTE PICBAD9% Q>OBYTE* PICBAD9/ Q>4 PICBLN99 Q>> PICBLN9C  CIOH #OUTM HO15R #OUT }W O15%>6\ QOUT;; Write currenta  WRTHEX;; length off %>4;; output filek QOUTp WRTHEXu : SEARCH*FLAG; }; Is CODE a GS10;; character? $>;; Yes... &CODE &LINK 2 &LINK QSTRING PCODE Q>TBL PP1 } Q>TBL PP1S10QP1;; Is last tableRP2;; entry reached? HS11QP1RP2DS11;Carry set = }$:;; not found)S11%>;; Check entry. QCODE3 R@P178HS12=3B QCODEG R@P17LHS12Q3VQCHR[ R@P17`H }S12eQLINK;; Match found!jPCODE;; CODE = LINKo QLINKt PCODEy INCP1~,;; Carry clear =:;; match found }S12 INCP1;; Next entry!S10WRITEQ>;; Write TEXTPCNTWRT01$CNT QTEXT9R> FWRT02 WRTCHA#C }NT !WRT01 WRT02:WRTCHAPTMP;; WriteQ;; character to 5;; E:Q5QTMP:WRTHEX5;; Write hex }M>;; digits> QHEX9 P@X717V? V?%V?*V?/>4 QHEX99P@X7>:(# CODE -# LINK 2# FLAG 7# }STRING <# CHR A# BYTE F# OBYTE K# TMP =P# CNT U# BITCT1 V# BITCT2 W# BITCT3 X# BITMSK Z#0TEXT }A}Input OutputA=A$0000 $0000A=_# IN d# OUT i#7HEX ==========!="=#=$=%=&#$X;IFILE }.CBYTE "Dn:filename.ext"#$X;OFILE .CBYTE "Dn:filename.LZW"&& RUNAD=======!="=#=$=%=&#$X;IFILE N$X; LZW unpacker v1.2 source codeX; by WosFilm 1993-03-28EIX;#X; Don't forget to specify input#X; and o}utput filenames at linesX; 9100 and 9105!X; TBL` $X; Table size must be of the same !X; size as the table used }when X; packing the file! ENDTBL- CIOV ICCOMB ICBADD ICBLNH ICAUXJ P1 P2} NEXTX; Start of STRING buffer%X; Max length of STRING=256 bytes! STRINGPRUNAD$>;; Open input}Q>;; file PICCOM9Q>IFILE PICBAD9Q>IFILEPICBAD9 Q> PICAUX9Q>PICAUX9 CIO}$$> ;; Open output)Q>;; file. PICCOM93Q>OFILE8 PICBAD9=Q>OFILEBPICBAD9GQ>L PICAUX9QQ>}VPICAUX9[ CIO` WRITE;; Write TEXTe UNPACK;; Unpack file!j$>;; Close inputoQ> ;; filet PICCOM9y CIO}~$> ;; Close outputQ> ;; file PICCOM9 CIO:;; Return to DOSUNPACK INITBL;; Init table GETC;; Get COD}EQCODE;; OLD=CODE POLD QCODEPOLDPCHR;; CHR=CODE$>;; Output firstPSTRING9;; byte &STROFS} OUTPUTU10 GETC;; Get CODEEU14;; End of file?$>QCODE;; Is CODE aFU13;; character? RNEXT;; Ha}s CODE beenDU11;; defined yet? QCODE RNEXT DU11%QOLD;; CODE=OLD* PCODE/ QOLD4 PCODE9QCHR;; App}end CHR>!U12CU11 DECODE;; Get characterHU120;; appended to CODEMPSTRING9;; Build STRINGRQCODE;; End of str}ing?WHU11\ U13QCODE]PCHRa0f PSTRING9k&STROFS;; Save offsetp OUTPUT;; Output STRINGu ADDTBL;; Add OLD+CH}RzQNEW;; to tablePOLD;; OLD=NEW QNEW POLD!U10U14:;; Finished!DECODE"CODEQCODE;; P1=}CODE*3+TBL PP1 QCODEPP1TP1 UP1,OP1PP1 QCODE OP1 PP1QP1, O>TBL}PP1 QP1 O>TBL PP1%> Q@P17;; Get link to PCODE;; next CODE 3 Q@P17 PCODE 3 Q}@P17;; Get character$ :e ADDTBL%>j QOLD;; Write linko P@P27t 3y QOLD~ P@P27 3 QCHR P@P27;; Append C}HR QNEXT;; Last available RBITCT3;; table entry? DA11 QNEXT R> HA11 UBITCT3;; Increase CODE TBITM}SK;; length A11#NEXT;; Increase NEXT HA12;; pointer #NEXT A12QP2;; Increase P2 ,;; pointer O> DA13} #P2 A13PP2 QP2;; Reached end R>END;; of table? HA14 QP2 R>END DA14  INITBL;; Re-init} NEXT ;P2 and CODE A14:;; length( INITBLQ>TBL- PP22 Q>TBL7 PP2< $>A &BITMSKF &BITCT3K &NEXT}P 0U &NEXTZ : GETCQ> PCNT G10 GETBIT;; Get all 8 LSB GG13;; bits UCODE "CNT HG10 Q> PCO}DE G11 GETBIT;; Get needed MSB GG13;; bits UCODE QBITCT1 MBITMSK HG12 TBITCT1 !G11 G12Q>} PBITCT1 QCODE;; NEW = CODE PNEW QCODE PNEW , : G13;;; End of file :T GETBITTBITCT2Y DG14^ } UBITCT2c  GETh EG15m G14TIBYTEr Q>w :| G15Q>;; End of file : GET CHECK;; Sync possible ;table re-in}it ;with packing ;routine $>;; Get byte from Q>;; input file PICCOM9 Q>IBYTE PICBAD9 Q>IBYTE} PICBAD9 Q> PICBLN9 Q> PICBLN9  CIO GG21;; End of file? #IN HG20 #IN G20%>. Q}IN;; Write how many  WRTHEX;; bytes has been %>,;; input QIN! WRTHEX& ,+ :0 G21;;; End of file5 : OUTP}UT$> ;; Write byte Q> ;; to output PICCOM9;; file Q>STRING PICBAD9 QSTROFS PICBAD9 Q> PICBLN}9 ; SSTROFS PICBLN9 HP10 #ICBLN9 P10 CIO $> QOUT , OICBLN9 POUT QOUT OICBLN}9 POUT %>6 QOUT;; Write current  WRTHEX;; output file %>4;; length QOUT WRTHEX :WRITEQ>;}; Write TEXTPCNT WRT1$CNT QTEXT9R> FWRT2 WRTCHA#CNT !WRT1 WRT2:WRTCHAPTMP;; WriteQ};; character to 5;; E:Q5QTMP:WRTHEX5;; Write hexM>;; digits> QHEX9 P@X717V? V}?%V?*V?/>4 QHEX99P@X7>:p CHECKuQP2;; If end ofz,;; table isO>;; reached, CODE>;; length must be}QP2;; reset to 9O>;; one characterR>END;; before theHC10;; table is(>END;; resetDC10Q>} PBITMSK PBITCT3C10:(# CODE -# NEW 2# OLD <# CHR A# IBYTE F# OBYTE K# TMP =P# CNT U# BITM}SK V# BITCT1 W# BITCT2 X# BITCT3 Z# STROFS _#0TEXTA}Input OutputA=A$0000 $0000A=d#7HEX ====}======!="=#=$=%=&i# IN n# OUT #$X;IFILE .CBYTE "Dn:filename.LZW"#$X;OFILE .CBYTE "Dn:filename.ext}"&& RUNAD!="=#=$=%=&i# IN n# OUT #$X;IFILE .CBYTE "Dn:filename.LZW"#$X;OFILE .CBYTE "Dn:filename.extB-COMTOOL1DOCB1COMTOOL1COMBZCCOMTOOL M65B%LZW M65B'ULZW M65/