aglover@acorn.co.uk (Alan Glover) (04/20/91)
Posting-number: Volume 01, Info 02 Submitted-by: Alan Glover <aglover@acorn.co.uk> Archive-name: bootstrap/part02 This is the first of five postings which will culminate with you having a usable copy of !Extract (a tool to extract multi part postings) and !SubExtWrk (a working directory for !Extract and it's counterpart !Submit). Save the data below under the name "Bark". When the need arises to run it (as detailed in subsequent articles), the command to do so is *BASIC Bark 10REM>Bark 20REM This program will unpack Spark or arc style archives on the BBC 30REM and Archimedes. To produce an archive that can be unpacked using it 40REM you must set arc or Spark to not use squashing. 50REM Although you can use this on the Archie, a much better solution, 60REM is to use !SparkPlug. If you have an Archie, and would like to make 70REM your own archives and manipulate them in style from the desktop, 80REM you need a copy of Spark. This is obtainable for M-#5.99 from: 90REM David Pilling, 100REM P.O. Box 22, 110REM Thornton Cleveleys, 120REM Blackpool. 130REM FY5 1LR. 140REM 150REM You are encouraged to add your own bits to this program and pass it on. 160REM If you do modify it, add your name and details below. 170REM 180REM V0.00 20th September 1989 -- David Pilling 190REM V0.01 25th September 1989 -- Philip Colmer 200REM Changed BASIC V usage to BASIC II 210REM V0.02 21st February 1990 -- Philip Colmer 220REM Improved support for DFS 230REM 240REM 250REM 260REM 270: 280ON ERROR GOTO 310 290*CLOSE 300: 310PRINT"Bark V0.02 February 1990" 320INPUT"Enter name of file to decode:"N$ 330: 340Y%=0:X%=OPENIN(N$) 350IFX%=0 PROCABEND("Can't open input file") 360: 370DIM FIX 4 380DIM suffix 4096 390DIM prefix1 4096 400DIM prefix2 4096 410DIM stack 4096 420DIM buf 128 430DIM stamp 18 440DIM name 256 450: 460DIM rmask 9 470rmask?0=0 480rmask?1=1 490rmask?2=3 500rmask?3=7 510rmask?4=15 520rmask?5=31 530rmask?6=63 540rmask?7=127 550rmask?8=255 560: 570R$="" 580level%=0 590DIM L%(32) 600L%(level%)=0 610over%=FALSE 620REPEAT 630PROCRDHDR 640IF earc% AND level%=0 CLOSE#X%:END 650IF over% CLOSE#X%:END 660IF isdir PROCDIR ELSEIF earc% PROCENDDIR ELSE PROCUNPACK 670UNTIL EOF#X% OR over% 680END 690: 700DEFPROCABEND(E$) 710PRINT"Bark has abended because:",E$ 720IFX%<>0 CLOSE#X% 730IFY%<>0 CLOSE#Y% 740END 750ENDPROC 760: 770DEFFNword 780FIX?0=BGET#X% 790FIX?1=BGET#X% 800FIX?2=BGET#X% 810FIX?3=BGET#X% 820:=!FIX 830: 840DEFFNdble 850I%=BGET#X% 860I%=I%+&100*BGET#X% 870:=I% 880: 890DEFPROCRDHDR 900I%=BGET#X% 910IF I%<>26 PRINT"Bad Header in:"N$:REPEAT I%=BGET#X%:UNTIL I%=26 OR EOF#X%:IF EOF#X%:over%=TRUE:ENDPROC 920type%=BGET#X% AND &7F 930IF type%=0 earc%=TRUE:ENDPROC ELSE earc%=FALSE 940F$="":T%=TRUE 950FOR I%=1 TO 13 960J%=BGET#X% 970IF J%>32 AND T%:F$=F$+CHR$J% ELSE T%=FALSE 980NEXT 990clen%=FNword 1000date%=FNdble 1010time%=FNdble 1020crc%=FNdble 1030IF type%>1 olen%=FNword ELSE olen%=clen% 1040load%=FNword 1050exec%=FNword 1060attr%=FNword 1070IF type%=2 AND FNTYPE=&DDC isdir=TRUE ELSE isdir=FALSE 1080ENDPROC 1090: 1100DEFFNTYPE 1110IF((load% AND &FFF00000)=&FFF00000) :=(load% AND &FFF00)/256 ELSE :=-1 1120: 1130DEFPROCDIR 1140L%(level%)=LENR$ 1150IF LENR$>0 R$=R$+F$ ELSE R$=F$ 1160level%=level%+1 1170S$="CDIR "+R$ 1180R$=R$+"." 1190PRINT"Creating directory",R$ 1200REM filing systems which allow directories are ADFS (8) and Econet (5) 1210IFFNfs=8 ORFNfs=5 OSCLI(S$) 1220ENDPROC 1230: 1240DEFPROCENDDIR 1250level%=level%-1 1260R$=LEFT$(R$,L%(level%)) 1270PRINT"Directory:",R$ 1280ENDPROC 1290: 1300DEFPROCUNPACK 1310PRINT"Restoring file:",R$+F$ 1320Y%=OPENOUT(R$+F$) 1330IF type%=1 OR type%=2 PROCUNSTORE ELSE IF type%=8 PROCUNCRUNCH ELSE IF type%=3 PROCUNPCK ELSE PROCABEND("Can't unpack "+F$) 1340CLOSE#Y%:Y%=0 1350PROCSTAMP 1360ENDPROC 1370: 1380DEFPROCUNSTORE 1390PRINT"Unstoring" 1400FOR I%=1 TO clen% 1410BPUT#Y%,BGET#X% 1420NEXT 1430ENDPROC 1440: 1450DEFPROCUNPCK 1460PRINT"Unpacking" 1470L%=0:C%=0 1480FOR I%=1 TO clen% 1490PROCputc_ncr(BGET#X%) 1500NEXT 1510ENDPROC 1520: 1530DEFFNMAXCODE(n)=2^n-1 1540: 1550DEFPROCputc_ncr(B%) 1560IF C%=1 ELSE 1580 1570IF B%=0:BPUT#Y%,&90:C%=0:ENDPROC ELSE FOR K%=2 TO B%:BPUT#Y%,L%:NEXT:C%=0:ENDPROC 1580IFB%=&90 C%=1:ENDPROC 1590L%=B%:BPUT#Y%,L% 1600ENDPROC 1610: 1620DEFPROCUNCRUNCH 1630PRINT"Uncrunching" 1640C%=0 1650offset=0:size=0:R%=clen% 1660code=FNGETC 1670IF code<>12 PROCABEND("File packed with illegal number of bits") 1680n_bits=9 1690clear_flg=0 1700maxcode=FNMAXCODE(n_bits) 1710FOR I%=0 TO 256:prefix1?I%=0:prefix2?I%=0:NEXT 1720FOR code=0 TO 255:suffix?code=code:NEXT 1730free_ent=257 1740oldcode=FNgetcode:finchar=oldcode 1750IF oldcode=-1 ENDPROC 1760PROCputc_ncr(finchar) 1770stackp=stack 1780code=FNgetcode 1790IF code<0 ENDPROC 1800IF code=256:FOR I%=0 TO 256:prefix1?I%=0:prefix2?I%=0:NEXT:clear_flg=1:free_ent=256:code=FNgetcode:IF code=-1 ENDPROC 1810incode = code 1820IF code>=free_ent ?stackp=finchar:stackp=stackp+1:code=oldcode 1830IF code>=256 ELSE 1870 1840?stackp=suffix?code:stackp=stackp+1 1850code=prefix1?code+256*prefix2?code 1860GOTO 1830 1870finchar=suffix?code:?stackp=finchar:stackp=stackp+1 1880REPEAT 1890stackp=stackp-1:PROCputc_ncr(?stackp) 1900UNTIL stackp=stack 1910code=free_ent 1920IF code < 4096 ELSE 1970 1930prefix1?code=oldcode 1940prefix2?code=oldcode/256 1950suffix?code=finchar 1960free_ent=code+1 1970oldcode=incode 1980GOTO 1780 1990ENDPROC 2000: 2010DEFFNGETC 2020IF R%>0 R%=R%-1:=BGET#X% ELSE :=-1 2030: 2040DEFFNgetcode 2050LOCAL code 2060bp=buf 2070IF clear_flg>0 OR offset>=size OR free_ent>maxcode ELSE 2180 2080IF free_ent > maxcode ELSE 2110 2090n_bits=n_bits+1 2100IF n_bits=12 maxcode = 4096 ELSE maxcode=FNMAXCODE(n_bits) 2110IF clear_flg>0 n_bits=9:maxcode=FNMAXCODE(n_bits):clear_flg=0 2120FOR size=0 TO n_bits-1 2130code=FNGETC 2140IF code=-1 temp=size:size=n_bits:NEXT ELSE buf?size=code:NEXT 2150IF size=n_bits+1:size=temp:IF size<=0:=-1 2160offset=0 2170size=(size*8)-(n_bits-1) 2180r_off=offset 2190bits=n_bits 2200bp=bp+r_off/8 2210r_off=r_off AND 7 2220code=(?bp/(2^r_off)):bp=bp+1 2230bits=bits-(8-r_off) 2240r_off=8-r_off 2250IF bits>=8 ELSE 2290 2260code=code OR (?bp*(2^r_off)):bp=bp+1 2270r_off=r_off+8 2280bits=bits-8 2290code=code OR ((?bp AND rmask?bits)*(2^r_off)) 2300offset=offset+n_bits 2310:=code AND 4095 2320: 2330DEFPROCSTAMP 2340REM modified by Philip Colmer so that it doesn't try to do 2350REM SYS"OS_File" 2360LOCAL A%,X%,Y% 2370!stamp=name 2380stamp!2=load% 2390stamp!6=exec% 2400stamp!14=attr% 2410$name=R$+F$ 2420A%=1:X%=stamp MOD256:Y%=stamp DIV256:CALL &FFDD 2430ENDPROC 2440: 2450DEFFNfs 2460A%=0:Y%=0 2470=USR&FFDA AND &FF
aglover@acorn.co.uk (Alan Glover) (04/22/91)
Posting-number: Volume 01, Info 02 Submitted-by: Alan Glover <aglover@acorn.co.uk> Archive-name: bootstrap/part02 ** This is a reposting of this article due to bugs found - please discard the earlier one (which has now been cancelled) and use this instead. This is the second of five postings which will culminate with you having a usable copy of !Extract (a tool to extract multi part postings) and !SubExtWrk (a working directory for !Extract and it's counterpart !Submit). Save the data below under the name "Bark". When the need arises to run it (as detailed in subsequent articles), the command to do so is *BASIC Bark --- CUT --- 10REM>Bark 20REM This program will unpack Spark or arc style archives on the BBC 30REM and Archimedes. To produce an archive that can be unpacked using it 40REM you must set arc or Spark to not use squashing. 50REM Although you can use this on the Archie, a much better solution, 60REM is to use !SparkPlug. If you have an Archie, and would like to make 70REM your own archives and manipulate them in style from the desktop, 80REM you need a copy of Spark. This is obtainable for M-#5.99 from: 90REM David Pilling, 100REM P.O. Box 22, 110REM Thornton Cleveleys, 120REM Blackpool. 130REM FY5 1LR. 140REM 150REM You are encouraged to add your own bits to this program and pass it on. 160REM If you do modify it, add your name and details below. 170REM 180REM V0.00 20th September 1989 -- David Pilling 190REM V0.01 25th September 1989 -- Philip Colmer 200REM Changed BASIC V usage to BASIC II 210REM V0.02 21st February 1990 -- Philip Colmer 220REM Improved support for DFS 230REM V0.03 22nd April 1991 -- Philip Colmer 240REM Fixed bugs in directory handling 250REM 260REM 270: 290*CLOSE 300: 310PRINT"Bark V0.03 April 1991" 320INPUT"Enter name of file to decode:"N$:IFN$="" END 330: 340Y%=0:X%=OPENIN(N$) 350IFX%=0 PROCABEND("Can't open input file") 360: 370DIM FIX 4 380DIM suffix 4096 390DIM prefix1 4096 400DIM prefix2 4096 410DIM stack 4096 420DIM buf 128 430DIM stamp 18 440DIM name 256 450: 460DIM rmask 9 470rmask?0=0 480rmask?1=1 490rmask?2=3 500rmask?3=7 510rmask?4=15 520rmask?5=31 530rmask?6=63 540rmask?7=127 550rmask?8=255 560: 570R$="" 580level%=0 590DIM L%(32) 600L%(level%)=0 610over%=FALSE 620REPEAT 630PROCRDHDR 640IF earc% AND level%=0 CLOSE#X%:END 650IF over% CLOSE#X%:END 660IF isdir PROCDIR ELSEIFearc% PROCENDDIR ELSE PROCUNPACK 670UNTIL EOF#X% OR over% 680END 690: 700DEFPROCABEND(E$) 710PRINT"Bark has abended because:",E$ 720IFX%<>0 CLOSE#X% 730IFY%<>0 CLOSE#Y% 740END 750ENDPROC 760: 770DEFFNword 780FIX?0=BGET#X% 790FIX?1=BGET#X% 800FIX?2=BGET#X% 810FIX?3=BGET#X% 820:=!FIX 830: 840DEFFNdble 850I%=BGET#X% 860I%=I%+&100*BGET#X% 870:=I% 880: 890DEFPROCRDHDR 900I%=BGET#X% 910IF I%<>26 PRINT"Bad Header in:"N$:REPEAT I%=BGET#X%:UNTIL I%=26 OR EOF#X%:IF EOF#X%:over%=TRUE:ENDPROC 920type%=BGET#X% AND &7F 930IF type%=0 earc%=TRUE:isdir=FALSE:ENDPROC ELSE earc%=FALSE 940F$="":T%=TRUE 950FOR I%=1 TO 13 960J%=BGET#X% 970IF J%>32 AND T%:F$=F$+CHR$J% ELSE T%=FALSE 980NEXT 990clen%=FNword 1000date%=FNdble 1010time%=FNdble 1020crc%=FNdble 1030IF type%>1 olen%=FNword ELSE olen%=clen% 1040load%=FNword 1050exec%=FNword 1060attr%=FNword 1070IF type%=2 AND FNTYPE=&DDC isdir=TRUE ELSE isdir=FALSE 1080ENDPROC 1090: 1100DEFFNTYPE 1110IF((load% AND &FFF00000)=&FFF00000) :=(load% AND &FFF00)/256 ELSE :=-1 1120: 1130DEFPROCDIR 1140L%(level%)=LENR$ 1150IF LENR$>0 R$=R$+F$ ELSE R$=F$ 1160level%=level%+1 1170S$="CDIR "+R$ 1180R$=R$+"." 1190PRINT"Creating directory",R$ 1200REM filing systems which allow directories are 1201REM ADFS (8) 1202REM Econet (5) 1203REM SCSI (26) 1210IFFNfs=8 ORFNfs=5 OR FNfs=26 OSCLI(S$) 1220ENDPROC 1230: 1240DEFPROCENDDIR 1250level%=level%-1 1260R$=LEFT$(R$,L%(level%)) 1270IFR$<>"" PRINT"Directory: ",R$ 1280ENDPROC 1290: 1300DEFPROCUNPACK 1310PRINT"Restoring file:",R$+F$ 1320Y%=OPENOUT(R$+F$) 1330IF type%=1 OR type%=2 PROCUNSTORE ELSE IF type%=8 PROCUNCRUNCH ELSE IF type%=3 PROCUNPCK ELSE PROCABEND("Can't unpack "+F$) 1340CLOSE#Y%:Y%=0 1350PROCSTAMP 1360ENDPROC 1370: 1380DEFPROCUNSTORE 1390PRINT"Unstoring" 1400FOR I%=1 TO clen% 1410BPUT#Y%,BGET#X% 1420NEXT 1430ENDPROC 1440: 1450DEFPROCUNPCK 1460PRINT"Unpacking" 1470L%=0:C%=0 1480FOR I%=1 TO clen% 1490PROCputc_ncr(BGET#X%) 1500NEXT 1510ENDPROC 1520: 1530DEFFNMAXCODE(n)=2^n-1 1540: 1550DEFPROCputc_ncr(B%) 1560IF C%=1 ELSE 1580 1570IF B%=0:BPUT#Y%,&90:C%=0:ENDPROC ELSE FOR K%=2 TO B%:BPUT#Y%,L%:NEXT:C%=0:ENDPROC 1580IFB%=&90 C%=1:ENDPROC 1590L%=B%:BPUT#Y%,L% 1600ENDPROC 1610: 1620DEFPROCUNCRUNCH 1630PRINT"Uncrunching" 1640C%=0 1650offset=0:size=0:R%=clen% 1660code=FNGETC 1670IF code<>12 PROCABEND("File packed with illegal number of bits") 1680n_bits=9 1690clear_flg=0 1700maxcode=FNMAXCODE(n_bits) 1710FOR I%=0 TO 256:prefix1?I%=0:prefix2?I%=0:NEXT 1720FOR code=0 TO 255:suffix?code=code:NEXT 1730free_ent=257 1740oldcode=FNgetcode:finchar=oldcode 1750IF oldcode=-1 ENDPROC 1760PROCputc_ncr(finchar) 1770stackp=stack 1780code=FNgetcode 1790IF code<0 ENDPROC 1800IF code=256:FOR I%=0 TO 256:prefix1?I%=0:prefix2?I%=0:NEXT:clear_flg=1:free_ent=256:code=FNgetcode:IF code=-1 ENDPROC 1810incode = code 1820IF code>=free_ent ?stackp=finchar:stackp=stackp+1:code=oldcode 1830IF code>=256 ELSE 1870 1840?stackp=suffix?code:stackp=stackp+1 1850code=prefix1?code+256*prefix2?code 1860GOTO 1830 1870finchar=suffix?code:?stackp=finchar:stackp=stackp+1 1880REPEAT 1890stackp=stackp-1:PROCputc_ncr(?stackp) 1900UNTIL stackp=stack 1910code=free_ent 1920IF code < 4096 ELSE 1970 1930prefix1?code=oldcode 1940prefix2?code=oldcode/256 1950suffix?code=finchar 1960free_ent=code+1 1970oldcode=incode 1980GOTO 1780 1990ENDPROC 2000: 2010DEFFNGETC 2020IF R%>0 R%=R%-1:=BGET#X% ELSE :=-1 2030: 2040DEFFNgetcode 2050LOCAL code 2060bp=buf 2070IF clear_flg>0 OR offset>=size OR free_ent>maxcode ELSE 2180 2080IF free_ent > maxcode ELSE 2110 2090n_bits=n_bits+1 2100IF n_bits=12 maxcode = 4096 ELSE maxcode=FNMAXCODE(n_bits) 2110IF clear_flg>0 n_bits=9:maxcode=FNMAXCODE(n_bits):clear_flg=0 2120FOR size=0 TO n_bits-1 2130code=FNGETC 2140IF code=-1 temp=size:size=n_bits:NEXT ELSE buf?size=code:NEXT 2150IF size=n_bits+1:size=temp:IF size<=0:=-1 2160offset=0 2170size=(size*8)-(n_bits-1) 2180r_off=offset 2190bits=n_bits 2200bp=bp+r_off/8 2210r_off=r_off AND 7 2220code=(?bp/(2^r_off)):bp=bp+1 2230bits=bits-(8-r_off) 2240r_off=8-r_off 2250IF bits>=8 ELSE 2290 2260code=code OR (?bp*(2^r_off)):bp=bp+1 2270r_off=r_off+8 2280bits=bits-8 2290code=code OR ((?bp AND rmask?bits)*(2^r_off)) 2300offset=offset+n_bits 2310:=code AND 4095 2320: 2330DEFPROCSTAMP 2340REM modified by Philip Colmer so that it doesn't try to do 2350REM SYS"OS_File" 2360LOCAL A%,X%,Y% 2370!stamp=name 2380stamp!2=load% 2390stamp!6=exec% 2400stamp!14=attr% 2410$name=R$+F$ 2420A%=1:X%=stamp MOD256:Y%=stamp DIV256:CALL &FFDD 2430ENDPROC 2440: 2450DEFFNfs 2460A%=0:Y%=0 2470=USR&FFDA AND &FF