Several years ago, Anthony Trice was kind enough to send me a copy of the ZIP utility which was originally ported to QDOS by Erik Slagter & Kai Uwe Rommel. Unfortunately, need is a strong motivator, and it wasn’t until this Summer that I finally sat down to figure out how to implement the utility in its QDOS incarnation. ZuipaDee (1.105) is the long over due front end for the ZIP utility that is meant to complement the earlier DooDah_bas front end for UNZIP.
While more than one compression algorithm exists, the use of the earlier ‘LZ77’ algorithm allows a QDOS ZIPped file to be universally expanded by almost all versions of UNZIP. The most recent port of ZIP that I have (v3.0) was executed by Marco Holmer.
Using Zip
There are many reasons for ZIPping a file — the two reasons that come to mind are for archiving (storage) and transmission (distribution). Of course, the file or program cannot be used until it has been UNZIPped back to its natural form.
ZIPping a file results in a new, smaller file which is suffixed with ‘_zip’. For example, the TurboQuill version of Quill (60614 bytes) would become Quill_zip (39833 bytes). The command line syntax for using the QDOS version of ZIP is:
EXEC_W win1_ZIP;"zipname win1_fileone"
where ‘win1_’ is where the ZIP program is located (the location is optional), ‘zipname’ is the name that you want for the ZIPped file, and ‘win1_fileone’ is the location and actual name of the file you want to ZIP.
You should note that, as with UNZIP, the command and argument(s) are separated by a semi-colon; and, the arguments are enclosed within quote marks.
It has been said that sometimes a little knowledge is a dangerous thing; and, this was the case with my attempts to implement ZIP and write the ZipaDee_bas program.
Being familiar with the DOS versions of the ZIP program I observed that the QDOS version lacked the ‘-a’ switch for amending existing ZIP files.
This seemed like a great omission that would require including all the filenames to be incorporated into a ZIP file at the time of the creation of the ZIP file. The command line syntax would be:
EXEC_W win1_ZIP;"zipname win1_fileone flp2_filetwo"
where ‘flp2_filetwo’ might be the device and location of the second file, and so on.
Subsequent to writing the current version of the program I belatedly ascertained that the ‘-a’ switch has been renamed ‘-u’ (i.e., update); and, the command line syntax is:
EXEC_W win1_ZIP;"-u zipname win1_fileone"
My ignorance prevented the program from resulting in a more cumbersome implementation for the user; so, all’s well that ends well.
Select Device
There are several device options. Pressing ‘W’ will select ‘win1_’; pressing ‘X’ will select ‘win2_’; pressing ‘F’ will select ‘flp1’; pressing ‘G’ will select ‘flp2_’; and, so on. Use the ‘other’ option if you want to key in a device name (e.g., ‘rom1_’).
If you are looking at the menu of filenames and want to return to the SELECT_DEVICE option, press ‘0’ (zero); however, you should note that all pre-selected filenames will be lost.
Change Device
To expedite multi-source ZIPping, you can change to different devices by using a “CONTROL SHIFT single_letter” key combination. The following are supported (you can modify the LISTing if you choose).
CTRL SHIFT F == flp1_ CTRL SHIFT M == mdv1_ CTRL SHIFT N == ndk1_ CTRL SHIFT O == rom1_ CTRL SHIFT R == ram1_ CTRL SHIFT W == win1_
To move from flp1_ to flp2_ (for example), simply use the right_arrow key.
CONTROL LEFT key to move to the device designated near the right_arrow near the bottom of the screen if the device type differs from the currently accessed device.
Press ‘0’ (zero) to access the SELECT_DEVICE menu if you want to start over.
Zipping A File
Presuming that the program has been properly typed in, if you want to ZIP a program, you simply have to press the key which corresponds to the alphanumeric character in the brackets ‘{ }’ to the left of the filename. The file will be ZIPped and stored on your default DATA_USE device (usually FLP2_).
If you have more than 1 Meg of memory then you can employ “DATA_USE RAM2_”, but, don’t forget to move the(se) ZIPped file(s) to a disk before quitting!
ABOUT THE LLISTing
ZipaDee is a modification of the DooDah_bas program LLISTing, and some meaningless statements may still be included.
You should note the REMarked statements (Line 140 & 150). You can UN-REMark these if you have more than 1 Meg of memory.
If you do not have a hard drive, then substitute “win1_” with “flp1_” or any other appropriate device in Line 150 & Line 160 and (especially) Line 1010.
There are some changes to the general program, but if you already have a functional copy of DooDah_bas, then you can just change the “Main” DEFine(d) PROCedure to the following (your line numbers may differ):
8nn LET Zipfile$=Z$(k+1)
8nn filename$=t$&W$&"_"&Z$(k+1)
8nn DoWhat$=Zipfile$&" "&filename$
8nn CLS#2
8nn IF k<c THEN EXEC_W win1_zip;DoWhat$
As you can see, this will only provide limited functionality by allowing only one file to be ZIPped at a time.
If you want the capability to ZIP more than one file, then you will probably want to input the LISTing below (also based originally on the DooDah_bas program, so you can save some keyboard entry).
Originally, a more complex structure for multiple ZIPs was being written, but in a moment of inspiration, I realized that it might be possible to simply extend the DoWhat$ string; and, that is the method used.
The files to be included can be verified prior to ZIPping by pressing the ‘/’ key. The files you have selected will appear in the upper part of the screen.
You will be asked for a ZIP file name after you have selected all the files you want to ZIP.
The following listing provides an active menu of 57 filenames (three columns x 19 files). If the files which you want to ZIP are not visible in the menu or contained within a sub-directory, then you will want to transfer the files to another source medium (e.g., ram1_, if you have “extra” memory); or, modify the QLUTter_bas program to contain the MANE & MAIN procedures instead of one of QLUTter’s current utility PROCedures.
Happy Trails,
And Computing, To You …
40 REMark ***************************************
50 REMark * ZIP-A-DEE 1.105b *
60 REMark * by Al Feng *
70 REMark * A ZIP FRONT END *
80 REMark DATA_USE RAM1_: ******** SAVE as ZipaDee_bas *******
90 REMark COPY win1_zip TO ram8_zip
100 F$="_FLIST_imp": t$="win": S$="win": W$="1": Do$=" "
110 pn=0: POKE 163890,0: MODE 0
120 WINDOW#2,512,256,0,0: PAPER#2,7: BORDER#2,1,7: INK#2,0:CLS#2: WINDOW#0,413,10,50,241: PAPER#0,0: INK#0,7: WINDOW462,250,25,3: OPEN#3,scr_458x200a27x48: u$=" ZipaDee 1.105 ": AT#2,21,4:
130 PRINT#2,u$;" by Al Feng "TO 4;" @ 1998 PLATYPUS Software ": PAUSE 30
140 PAPER 7: BORDER 1,7: CLS: CL: lne: AT 0,7: PAPER 2: INK 7: PRINT" SELECT_DEVICE ": cj
150 DEFine PROCedure CLSc: BLOCK 458,225,0,10,0: END DEFine
160 DEFine PROCedure CLSd: BLOCK#2,330,10,83,240,0: END DEFine
170 DEFine PROCedure CLSe: BLOCK 458,190,0,45,pn: END DEFine
180 DEFine PROCedure CLSf: BLOCK 458,30,0,10,0: END DEFine
190 DEFine PROCedure Press: CLS#0: INK#2,5: AT#2,24,30: PRINT#2,"Press Any_Key to Continue":END DEFine
200 DEFine PROCedure sx: DIM Z$(60,32): DELETE t$&W$&F$
210 OPEN_NEW#6,t$&W$&F$
220 DIR#6,t$&W$&"_": CLOSE#6
230 OPEN_IN#7,t$&W$&F$: FOR c=0 TO 60
240 IF EOF(#7) THEN EXIT c
250 INPUT#7,Z$(c): END FOR c: CLOSE#7: c=c-1: END DEFine
260 DEFine PROCedure sw: IF W$<=8 THEN g$=W$-1: IF W$>=1 THEN h$=g$+2
270 IF g$=0 AND t$="flp" THEN LET t1$="ram": ELSE t1$="flp": END IF : g1$=1
280 IF g$>0 THEN t1$=t$: g1$=W$-1: END IF
290 END DEFine
300 DEFine PROCedure Rx: CLSf: INK#3,7: PAPER#3,0: AT 2,3: PRINT t$;W$;"_";: INK 7: PRINT Z$(0):Rx1:END DEFine
310 DEFine PROCedure Rx1:FOR a=0 TO 18
320 IF a<1 THEN a=a+a
330 FOR n=1+a+a: AT#3,a,0: PRINT#3,"{",CHR$(n+a+48);"} ";Z$(n+a+1)
340 FOR n=2+a+a: AT#3,a,26: PRINT#3,"{";CHR$(n+a+48);"} ";Z$(n+a+1)
350 FOR n=3+a+a: AT#3,a,52: PRINT#3,"{";CHR$(n+a+48);"} ";Z$(n+a+1)
360 NEXT a: END FOR a: rx2: END DEFine
370 DEFine PROCedure rx2
380 STRIP#2,0: INK#2,7
390 BLOCK 2,13,18,235,2: BLOCK 2,12,436,236,2: BLOCK 458,1,0,235,2
400 BLOCK 18,12,0,236,0
410 BLOCK 20,12,438,236,0
420 BLOCK 416,12,20,236,0
430 AT#2,24,5: INK#2,7: PRINT#2,CHR$(188);" ": AT#2,24,78: PRINT#2,CHR$(189);" "
440 AT#2,24,8: INK#2,5: PRINT#2,t1$&g1$;"_"TO 71;t$&h$;"_"
450 END DEFine
460 DEFine PROCedure Uu: sx: pn=0: CLSe: Uv: END DEFine
470 DEFine PROCedure Uv: sw: Rx: k3: pk: END DEFine
480 DEFine PROCedure Uw: wx: k3: pk: END DEFine
490 DEFine PROCedure pk: k=k-48
500 IF k=-21 THEN CLS#2: nd
510 IF k<-1 AND k<>-14 THEN Uw
520 IF k=-14 THEN Uw
530 IF k=68 THEN Uv
540 IF k=144 THEN IF W$>1 THEN W$=W$-1: Uu: ELSE : iX: Uw
550 IF k=118 THEN t$="flp": a$=1: sx: MAIN
560 IF k=125 THEN t$="mdv": a$=1: sx: MAIN
570 IF k=126 THEN t$="ndk": a$=1: sx: MAIN
580 IF k=127 THEN t$="rom": a$=1: sx: MAIN
590 IF k=130 THEN t$="ram": a$=1: sx: MAIN
600 IF k=135 THEN t$="win": a$=1: sx: MAIN
610 IF k=146 AND t$="ram" THEN t$="flp": LET a$=1: Uu
620 IF k=146 AND t$="win" THEN t$="flp": LET a$=1: Uu
630 IF k=146 AND t$="flp" THEN t$="ram": LET a$=1: Uu
640 IF k=152 THEN IF W$<2 THEN W$=W$+1: Uu: ELSE : iX: Uw
650 IF k=156 THEN W$=W$+1: Uu
660 IF k=79 THEN CLS#2: lne: tre=3: WCh
670 IF k=0 THEN GO TO 140
680 IF k>=58 THEN Uw
690 END DEFine
700 DEFine PROCedure wx: STRIP#2,2: INK#2,7: AT#2,24,29: PRINT#2," ERROR" TO 49;"ERROR ": AT#2,24,36: STRIP#2,0:PRINT#2," WRONG KEY";: INK#2,5: PRINT#2,"!": STRIP#2,7:INK#2,0: B5: CLSd: B5: END DEFine
710 DEFine PROCedure iX: AT#2,24,35: PRINT#2,"invalid drive": B5:PAUSE 10: END DEFine
720 DEFine PROCedure k3: REPeat key
730 k=CODE(INKEY$): IF k>8 THEN EXIT key
740 END REPeat key: END DEFine
750 DEFine PROCedure yeano
760 REPeat ysn
770 c$=INKEY$
780 IF c$=CHR$(27) OR c$=="n" THEN ok=0:EXIT ysn
790 IF c$=CHR$(10) OR c$=="y" THEN ok=1:EXIT ysn
800 END REPeat ysn:END DEFine
810 :
820 DEFine PROCedure MANE
830 Do$=" "
840 MAIN
850 END DEFine
860 DEFine PROCedure MAIN
870 BORDER 1,2:BLOCK 458,12,0,0,2: STRIP 2: AT 0,37: INK 7: PRINT "zip"
880 CLSc: STRIP 0: INK 2: AT 2,5: PRINT"ZIP ": sw: cr=0: Rx
890 k3: pk
900 IF k=-1 THEN CLSf: INK 5: AT 1,0: PRINT Do$: Press: PAUSE: Rx: GO TO 950
910 LET Zipfile$=Z$(k+1)
920 filename$=t$&W$&"_"&Z$(k+1)
930 AT 2,3:INK 7:PRINT" ZIP ";:INK 5:PRINT filename$ ;: INK 2: PRINT " (y/n)"
940 yeano:IF ok THEN Do$=Do$&" "&filename$:ELSE GO TO 950
950 CLSf:AT 2,3: INK 7: PRINT" ZIP ";: INK 5: PRINT "another" ;: INK 2: PRINT " (y/n)"
960 yeano: INK 2: IF ok THEN B1: Rx: STRIP#2,7: CLSd: rx2: GO TO 890: ELSE GO TO 970: END IF
970 CLSf: AT 2,3: INK 5: INPUT "ZIP file name: ";name$
980 IF name$="" THEN GO TO 970
990 CLS#2
1000 DoWhat$=name$&" "&Do$
1010 EXEC_W win1_zip;DoWhat$
1020 CLS#2: BORDER#2,1,7: wx: MAIN: END DEFine
1030 :
1040 DEFine PROCedure B1: BEEP 100,10: END DEFine
1050 DEFine PROCedure B2: BEEP 200,20: END DEFine
1060 DEFine PROCedure B3: BEEP 900,20: END DEFine
1070 DEFine PROCedure B4: BEEP 900,40: END DEFine
1080 DEFine PROCedure B5: B3: PAUSE 5: B4: END DEFine
1090 DEFine PROCedure lne: BLOCK#2,458,1,24,2,0: BLOCK 458,1,0,10,0: END DEFine
1100 DEFine PROCedure nd: PAPER 7: lne: B2: tre=1: WCh: END DEFine
1110 DEFine PROCedure CL: BLOCK 450,220,0,11,7: PAPER 7: INK 2: AT 0,64: PRINT CHR$(188)&' shift TAB ': AT 0,0: PRINT" TAB "&CHR$(189): INK 0:AT 0,7: PRINT " SELECT_DEVICE ZIP "TO 57;" EXIT ": PAPER 2: INK 7:END DEFine
1120 DEFine PROCedure K4: PAPER 7: REPeat key
1130 ike=CODE(INKEY$)
1140 IF ike=9 OR ike=32 OR ike=252 OR ike=253 OR ike>47 AND ike<58 THEN B3: EXIT key
1150 IF ike>=58 AND ike<252 THEN B4: K4
1160 END REPeat key: END DEFine
1170 DEFine PROCedure Pick
1180 IF ike=253 THEN B4: PrvW
1190 IF ike=9 THEN B3: NxtW
1200 IF ike=252 THEN B4: B5: GO TO 1530
1210 END DEFine
1220 DEFine PROCedure NxtW
1230 tre=tre+1: IF tre=3 THEN tre=0
1240 WCh: END DEFine
1250 DEFine PROCedure PrvW
1260 tre=tre-1: IF tre<0 THEN tre=2
1270 WCh: END DEFine
1280 DEFine PROCedure WCh: lne: CL
1290 IF tre=0 THEN AT 0,7: PRINT" SELECT_DEVICE ": K4: Pick: cj
1300 IF tre=1 THEN AT 0,22: PRINT" ZIP ": K4: Pick: CLS: MAIN
1310 IF tre=2 THEN AT 0,57: PRINT" EXIT ": K4: Pick: GO TO 1530
1320 END DEFine
1330 DEFine PROCedure cj: pn=7: CLSe: BLOCK 90,100,42,11,0: BLOCK 88,99,43,11,7
1340 PAPER 0: INK 7: AT 10,7: S$=t$: PRINT" [ ";: INK 5: PRINT S$&W$;: INK 7: PRINT"_mode ] ": AT 11,7: PAPER 2: PRINT u$: PAPER 7
1350 INK 0: BEEP 100,29: AT 2,9: PRINT'"W" = win1_': AT 4,9: PRINT'"F" = flp1_': AT 6,9: PRINT'"R" = ram1_': AT 8,9: PRINT'"O" = other'
1360 s=CODE(INKEY$(-1))
1370 IF s=9 THEN B3: BLOCK 90,112,42,11,7: tre=1: WCh
1380 IF s=253 THEN B4: BLOCK 90,112,42,11,7: tre=3: WCh
1390 IF s=77 OR s=109 THEN t$="mdv": W$="1" : GO TO 1480
1400 IF s=78 OR s=110 THEN t$="mdv": W$="2" : GO TO 1480
1410 IF s=70 OR s=102 THEN t$="flp": W$="1" : GO TO 1480
1420 IF s=71 OR s=103 THEN t$="flp": W$="2" : GO TO 1480
1430 IF s=82 OR s=114 THEN t$="ram": W$="1" : GO TO 1480
1440 IF s=84 OR s=116 THEN t$="ram": W$="2" : GO TO 1480
1450 IF s=87 OR s=119 THEN t$="win": W$="1" : GO TO 1480
1460 IF s=88 OR s=120 THEN t$="win": W$="2" : GO TO 1480
1470 IF s=79 OR s=111 THEN WINDOW#0,90,30,69,84: PAPER#0,7:INK#0,2: other
1480 sx: B5: MANE: END DEFine
1490 DEFine PROCedure other:INK#0,0: AT#0,0,7: PRINT#0," "&CHR$(188)&"_";: INK#0,2: AT#0,0,8: INPUT#0,t$;: IF LEN(t$)<>3 THEN GO TO 1480: END IF
1500 INK#0,5: AT#0,0,11: PRINT#0,"_": INK#0,2: AT#0,0,11: INPUT#0,W$: IF CODE(W$)>56 OR CODE(W$)<49 THEN GO TO 1510: WINDOW#0,413,10,50,241:END IF
1510 END DEFine
1520 CLS#2: PAPER#2,7: INK#2,2: AT#2,24,32: PRINT#2,"@ PLATYPUS Software"