home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
amiga
/
unt64.lha
/
UnT.e
< prev
Wrap
Text File
|
1995-02-16
|
7KB
|
250 lines
/* This program should take a .t64 file and pull it apart into */
/* the original, separate CBM files. */
/* Version 1.2 */
/* Written by pbhoeffl@undergrad.math.uwaterloo.ca */
/* on March 26-7, 1994 */
/* Modified by pbhoeff@io.org */
/* February 16, 1995 */
/* - Wouldn't you know it that the .t64's I tested all had one thing in */
/* common... the filesizes given in the header were correct. The day */
/* after I put this up on Watson, I found out that there were lots of */
/* files for which this was *not* true. Hopefully, this version does */
/* not invite the guru like the old version did. */
/* - A KingCON user pointed this out to me: UnT didn't strip off trailing */
/* spaces from the archive name specified on the command line. This */
/* meant that if you typed "UnT WickedGame.T64 " it would look for (and */
/* not find) "WickedGame.T64 " with that trailing space in the name. */
/* I received only a very small number of email's concerning UnT (true, I */
/* solicited none), so either: */
/* a) nobody used it, */
/* b) people used it, ran into all the above bugs, and tossed it, */
/* c) people used it, luckily missed all the bugs, and are happy. */
/* I wrote UnT primarily for myself so, lack of demand aside, it is for my */
/* own peace of mind that I am implementing these fixes. */
/* Development Suite: */
/* Hardware: A500 KS1.3 OCS */
/* Software: WB 1.3, Amiga E v2.1b, Vim 2.0 & 3.0 */
/* I maintain no copyright on this program, and hereby release */
/* it into the public domain. If I am violating someone elses */
/* copyright by releasing this as such... well, I guess that's */
/* my tough luck. */
ENUM NOARG, NOARCHIVE, EMPTYARCHIVE, NOMEMORY, READERROR
ENUM CANTCREATE, WRITEERROR
DEF flen, handle=NIL, mem
PROC main () HANDLE
DEF i, j, numFiles, numUsed, prompt[16]:STRING, archname[127]:STRING
WriteF (' \e[3mUnT Version 1.2 \e[0m\n')
StrCopy (archname, TrimStr (arg), ALL)
j := StrLen (archname)
WHILE (archname[j-1] = " ") AND (j > 0)
j := j-1
ENDWHILE
SetStr (archname, j)
IF StrLen (archname) = 0 THEN Raise (NOARG)
/* WriteF ('Archive is: \s\n', archname) */
handle := Open (archname, OLDFILE)
IF handle = NIL THEN Raise (NOARCHIVE)
flen := FileLength (archname)
IF flen < 1 THEN Raise (EMPTYARCHIVE)
/* WriteF ('Located \s. Size=\d\n', archname, flen) */
mem := New (flen)
IF mem = NIL THEN Raise (NOMEMORY)
/* WriteF ('Memory successfully allocated.\n') */
IF Read (handle, mem, flen) <> flen THEN Raise (READERROR)
/* WriteF ('Read archive successfully.\n', archname) */
/* We're done with the archive file */
Close (handle); handle := NIL
WriteF ('User Description : ')
print_text (40, 24); WriteF ('\n')
/*
WriteF ('DOS Description :\n')
print_text (0, 32); WriteF ('\n')
*/
numFiles := make_int16 (34)
WriteF ('Number of Entries: \d\n', numFiles)
numUsed := make_int16 (36)
WriteF ('Number Used : \d\n', numUsed)
WriteF ('\nScanning Tape-Archive...\n')
FOR i := 0 TO numFiles-1
IF mem[64+(i*32)] = 1
WriteF ('#\d ', i)
print_entry (64+(i*32))
ENDIF
ENDFOR
WriteF ('Done\n\n')
IF numUsed = 0
WriteF ('According to the header info, there are no files in this archive.\n')
WriteF ('This is probably bogus. The first entry is likely the converted file.\n\n')
print_entry (64)
WriteF ('Do you wish to extract this file (Y/N)? ')
ReadStr (stdout, prompt); UpperStr (prompt)
IF prompt[0] = "Y"
WriteF ('Type the name you wish to give to this file:\n')
ReadStr (stdout, prompt)
IF StrLen (prompt) > 0
extract_file (64, prompt)
ENDIF
ENDIF
ELSE
FOR i := 0 TO numFiles-1
IF mem[64+(i*32)] = 1
/* Pull & trim the filename from the directory entry */
j := 16
WHILE (mem[(64+(i*32)) + 16 + j - 1] = " ") AND (j >= 0)
j := j-1
ENDWHILE
SetStr (prompt, j)
StrCopy (prompt, mem + (64+(i*32)) + 16, j)
extract_file (64+(i*32), prompt)
ENDIF
ENDFOR
ENDIF
CleanUp(0)
/* Error conditions */
EXCEPT
SELECT exception
CASE NOARG
WriteF ('Usage: UnT <archive.t64>\n')
CASE NOARCHIVE
WriteF ('Unable to open \s!\n', archname)
CASE EMPTYARCHIVE
WriteF ('Archive \s is EMPTY!\n', archname)
CASE NOMEMORY
WriteF ('Could not allocate enough memory.\n')
CASE READERROR
WriteF ('Read Error on \s.\n', archname)
DEFAULT
WriteF ('BAD SCENE, MAN!!!\n')
ENDSELECT
Close (handle)
CleanUp (-1)
ENDPROC
PROC print_text (start, length)
DEF s[80]:STRING
SetStr (s, length)
StrCopy (s, mem+start, length)
WriteF ('\e[40;33m\s\e[40;31m', s)
ENDPROC
PROC print_entry (rec_base)
DEF fileType, fileStart, fileEnd
fileType := mem[rec_base + 1]
SELECT fileType
CASE 1
WriteF ('PRG "')
CASE 68
WriteF ('PRG "')
/* RE: other CASEs would be implemented if I had my 1541 manual here. */
/* I have now been re-united with my 1541 manual, only to realize */
/* that these .t64 filetypes don't correspond to the CBM filetypes. */
/* Oh, well. It was only cosmetic anyways. */
DEFAULT
WriteF ('??? "')
ENDSELECT
print_text (rec_base + 16, 16)
fileStart := make_int16 (rec_base + 2)
fileEnd := make_int16 (rec_base + 4)
WriteF ('" Start=$\z\h[4] ', fileStart)
WriteF ('End=$\z\h[4]\n', fileEnd)
/* Note: make_int16(rec_base+8) may cause problems with tapes
larger than 64K... it's really supposed to be an int32.
*/
IF (fileEnd - fileStart) > (flen - make_int16 (rec_base + 8))
WriteF (' WARNING!! Reported file length is greater than archive length!\n')
ENDIF
ENDPROC
PROC extract_file (rec_base, name) HANDLE
DEF length, i, fileStart, fileEnd
WriteF ('Extracting "\s"', name)
fileStart := make_int16 (rec_base + 2)
fileEnd := make_int16 (rec_base + 4)
length := fileEnd - fileStart
IF length > (flen - make_int16 (rec_base + 8))
length := (flen - make_int16 (rec_base + 8))
WriteF (' (End=$\z\h[4])', fileStart + length)
ENDIF
WriteF ('...')
handle := Open (name, NEWFILE)
IF handle = NIL THEN Raise (CANTCREATE)
i := Write (handle, (mem + rec_base + 2), 2)
IF i <> 2 THEN Raise (WRITEERROR)
i := Write (handle, (mem + make_int16 (rec_base + 8)), length)
IF i <> length THEN Raise (WRITEERROR)
Close (handle)
WriteF (' OK\n')
EXCEPT
SELECT exception
CASE CANTCREATE
WriteF ('Unable to create file!\n')
CASE WRITEERROR
WriteF ('Write Error!\n')
DEFAULT
WriteF ('BAD SCENE, MAN!!!\n')
ENDSELECT
Close (handle)
CleanUp (-1)
ENDPROC
PROC make_int16 (address)
RETURN ( mem[address] + (256 * mem[address+1]) )
ENDPROC