home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / amiga / unt64.lha / UnT.e < prev   
Text File  |  1995-02-16  |  7KB  |  250 lines

  1. /*  This program should take a .t64 file and pull it apart into */
  2. /*  the original, separate CBM files. */
  3. /*  Version 1.2 */
  4.  
  5. /*  Written by pbhoeffl@undergrad.math.uwaterloo.ca */
  6. /*  on March 26-7, 1994 */
  7.  
  8. /*  Modified by pbhoeff@io.org */
  9. /*  February 16, 1995 */
  10.  
  11. /*  - Wouldn't you know it that the .t64's I tested all had one thing in */
  12. /*    common... the filesizes given in the header were correct.  The day */
  13. /*    after I put this up on Watson, I found out that there were lots of */
  14. /*    files for which this was *not* true.  Hopefully, this version does */
  15. /*    not invite the guru like the old version did. */
  16.  
  17. /*  - A KingCON user pointed this out to me:  UnT didn't strip off trailing */
  18. /*    spaces from the archive name specified on the command line.  This */
  19. /*    meant that if you typed "UnT WickedGame.T64 " it would look for (and */
  20. /*    not find) "WickedGame.T64 " with that trailing space in the name. */
  21.  
  22. /*  I received only a very small number of email's concerning UnT (true, I */
  23. /*  solicited none), so either: */
  24. /*    a)  nobody used it, */
  25. /*    b)  people used it, ran into all the above bugs, and tossed it, */
  26. /*    c)  people used it, luckily missed all the bugs, and are happy. */
  27. /*  I wrote UnT primarily for myself so, lack of demand aside, it is for my */
  28. /*  own peace of mind that I am implementing these fixes. */
  29.  
  30. /*  Development Suite:  */
  31. /*  Hardware:  A500 KS1.3 OCS */
  32. /*  Software:  WB 1.3, Amiga E v2.1b, Vim 2.0 & 3.0 */
  33.  
  34. /*  I maintain no copyright on this program, and hereby release */
  35. /*  it into the public domain.  If I am violating someone elses */
  36. /*  copyright by releasing this as such... well, I guess that's */
  37. /*  my tough luck. */
  38.  
  39.  
  40.  
  41. ENUM NOARG, NOARCHIVE, EMPTYARCHIVE, NOMEMORY, READERROR
  42. ENUM CANTCREATE, WRITEERROR
  43.  
  44.  
  45. DEF flen, handle=NIL, mem
  46.  
  47. PROC main ()  HANDLE
  48.     DEF i, j, numFiles, numUsed, prompt[16]:STRING, archname[127]:STRING
  49.  
  50.     WriteF (' \e[3mUnT Version 1.2 \e[0m\n')
  51.  
  52.     StrCopy (archname, TrimStr (arg), ALL)
  53.     j := StrLen (archname)
  54.     WHILE (archname[j-1] = " ") AND (j > 0)
  55.     j := j-1
  56.     ENDWHILE
  57.     SetStr (archname, j)
  58.     
  59.     IF StrLen (archname) = 0 THEN Raise (NOARG)
  60.     /* WriteF ('Archive is:  \s\n', archname) */
  61.  
  62.     handle := Open (archname, OLDFILE)
  63.     IF handle = NIL THEN Raise (NOARCHIVE)
  64.     flen := FileLength (archname)
  65.     IF flen < 1 THEN Raise (EMPTYARCHIVE)
  66.     /* WriteF ('Located \s.  Size=\d\n', archname, flen) */
  67.  
  68.     mem := New (flen)
  69.     IF mem = NIL THEN Raise (NOMEMORY)
  70.     /* WriteF ('Memory successfully allocated.\n') */
  71.  
  72.     IF Read (handle, mem, flen) <> flen THEN Raise (READERROR)
  73.     /* WriteF ('Read archive successfully.\n', archname) */
  74.  
  75.     /*  We're done with the archive file */
  76.     Close (handle);  handle := NIL
  77.  
  78.     WriteF ('User Description :  ')
  79.     print_text (40, 24);  WriteF ('\n')
  80.  
  81. /*
  82.     WriteF ('DOS Description  :\n')
  83.     print_text (0, 32);  WriteF ('\n')
  84. */
  85.  
  86.     numFiles := make_int16 (34)
  87.     WriteF ('Number of Entries:  \d\n', numFiles)
  88.     numUsed := make_int16 (36)
  89.     WriteF ('Number Used      :  \d\n', numUsed)
  90.  
  91.     WriteF ('\nScanning Tape-Archive...\n')
  92.     FOR i := 0 TO numFiles-1
  93.     IF mem[64+(i*32)] = 1
  94.         WriteF ('#\d  ', i)
  95.         print_entry (64+(i*32))
  96.     ENDIF
  97.     ENDFOR
  98.     WriteF ('Done\n\n')
  99.  
  100.     IF numUsed = 0
  101.     WriteF ('According to the header info, there are no files in this archive.\n')
  102.     WriteF ('This is probably bogus.  The first entry is likely the converted file.\n\n')
  103.  
  104.     print_entry (64)
  105.  
  106.     WriteF ('Do you wish to extract this file (Y/N)?  ')
  107.     ReadStr (stdout, prompt);  UpperStr (prompt)
  108.  
  109.     IF prompt[0] = "Y"
  110.         WriteF ('Type the name you wish to give to this file:\n')
  111.         ReadStr (stdout, prompt)
  112.  
  113.         IF StrLen (prompt) > 0
  114.         extract_file (64, prompt)
  115.         ENDIF
  116.     ENDIF
  117.     ELSE
  118.     FOR i := 0 TO numFiles-1
  119.         IF mem[64+(i*32)] = 1
  120.         /* Pull & trim the filename from the directory entry */
  121.         j := 16
  122.         WHILE (mem[(64+(i*32)) + 16 + j - 1] = " ") AND (j >= 0)
  123.             j := j-1
  124.         ENDWHILE
  125.         SetStr (prompt, j)
  126.         StrCopy (prompt, mem + (64+(i*32)) + 16, j)
  127.     
  128.         extract_file (64+(i*32), prompt)
  129.         ENDIF
  130.     ENDFOR
  131.     ENDIF
  132.  
  133.  
  134.     CleanUp(0)
  135.  
  136.  
  137. /* Error conditions */
  138.  
  139. EXCEPT
  140.     SELECT exception
  141.     CASE NOARG
  142.         WriteF ('Usage:  UnT <archive.t64>\n')
  143.     CASE NOARCHIVE
  144.         WriteF ('Unable to open \s!\n', archname)
  145.     CASE EMPTYARCHIVE
  146.         WriteF ('Archive \s is EMPTY!\n', archname)
  147.     CASE NOMEMORY
  148.         WriteF ('Could not allocate enough memory.\n')
  149.     CASE READERROR
  150.         WriteF ('Read Error on \s.\n', archname)
  151.     DEFAULT
  152.         WriteF ('BAD SCENE, MAN!!!\n')
  153.     ENDSELECT
  154.     Close (handle)
  155.     CleanUp (-1)
  156. ENDPROC
  157.  
  158.  
  159.  
  160. PROC print_text (start, length)
  161.     DEF s[80]:STRING
  162.  
  163.     SetStr (s, length)
  164.     StrCopy (s, mem+start, length)
  165.     WriteF ('\e[40;33m\s\e[40;31m', s)
  166.  
  167. ENDPROC
  168.  
  169.  
  170.  
  171. PROC print_entry (rec_base)
  172.     DEF fileType, fileStart, fileEnd
  173.  
  174.     fileType := mem[rec_base + 1]
  175.     SELECT fileType
  176.     CASE 1
  177.         WriteF ('PRG  "')
  178.     CASE 68
  179.         WriteF ('PRG  "')
  180.     /* RE: other CASEs would be implemented if I had my 1541 manual here. */
  181.         /* I have now been re-united with my 1541 manual, only to realize */
  182.         /* that these .t64 filetypes don't correspond to the CBM filetypes. */
  183.         /* Oh, well.  It was only cosmetic anyways. */
  184.     DEFAULT
  185.         WriteF ('???  "')
  186.     ENDSELECT
  187.  
  188.     print_text (rec_base + 16, 16)
  189.  
  190.     fileStart := make_int16 (rec_base + 2)
  191.     fileEnd := make_int16 (rec_base + 4)
  192.  
  193.     WriteF ('"  Start=$\z\h[4]  ', fileStart)
  194.     WriteF ('End=$\z\h[4]\n', fileEnd)
  195.  
  196.     /* Note:  make_int16(rec_base+8) may cause problems with tapes
  197.               larger than 64K... it's really supposed to be an int32.
  198.     */
  199.     IF (fileEnd - fileStart) > (flen - make_int16 (rec_base + 8))
  200.     WriteF ('    WARNING!!  Reported file length is greater than archive length!\n')
  201.     ENDIF
  202. ENDPROC
  203.  
  204.  
  205.  
  206. PROC extract_file (rec_base, name)  HANDLE
  207.     DEF length, i, fileStart, fileEnd
  208.  
  209.     WriteF ('Extracting "\s"', name)
  210.     fileStart := make_int16 (rec_base + 2)
  211.     fileEnd := make_int16 (rec_base + 4)
  212.     length := fileEnd - fileStart
  213.     
  214.     IF length > (flen - make_int16 (rec_base + 8))
  215.     length := (flen - make_int16 (rec_base + 8))
  216.     WriteF (' (End=$\z\h[4])', fileStart + length)
  217.     ENDIF
  218.  
  219.     WriteF ('...')
  220.  
  221.     handle := Open (name, NEWFILE)
  222.     IF handle = NIL THEN Raise (CANTCREATE)
  223.  
  224.     i := Write (handle, (mem + rec_base + 2), 2)
  225.     IF i <> 2 THEN Raise (WRITEERROR)
  226.     i := Write (handle, (mem + make_int16 (rec_base + 8)), length)
  227.     IF i <> length THEN Raise (WRITEERROR)
  228.  
  229.     Close (handle)
  230.     WriteF ('  OK\n')
  231.  
  232. EXCEPT
  233.     SELECT exception
  234.     CASE CANTCREATE
  235.         WriteF ('Unable to create file!\n')
  236.     CASE WRITEERROR
  237.         WriteF ('Write Error!\n')
  238.     DEFAULT
  239.         WriteF ('BAD SCENE, MAN!!!\n')
  240.     ENDSELECT
  241.     Close (handle)
  242.     CleanUp (-1)
  243. ENDPROC
  244.  
  245.  
  246.  
  247. PROC make_int16 (address)
  248.     RETURN ( mem[address] + (256 * mem[address+1]) )
  249. ENDPROC
  250.