[comp.sys.apple] IIgs software for the spoiled Apple II Binary files

SEWALL@UCONNVM.BITNET (04/09/87)

Unless the copy protection scheme causes trouble, Terrapin Logo ought to
work fine on a IIgs.  The latest version of the Bank Street Writer also
is quite serviceable, and while a mouse isn't necessary, it is menu
driven; I recommend it over AppleWorks or AppleWriter for children
(and anyone with a Mac who doesn't need all the bells and whistles on an
Apple //; besides the Bank Street Writer isn't nearly as expensive).
The Bank Street Writer also is copy protected, but Broderbund already
produces some IIgs software (you might call and ask if they are sure the
program runs on the GS, but I'd be surprised if it doesn't).

One program I know exists in a IIgs version that is REALLY a hoot is
Fantavision.  I've got it for my //c, and it's possible to use it
without a mouse only in theory.  You may let the kids use the Mac while
you play with their copy of Fantavision.

Multiscribe's "cute."  It's sort of a MacWrite imitator for the Apple
//; document size it limited.  Save your $$$.  Get a catalog from
Broderbund, they are busy putting out IIgs stuff.  I have a friend who
beta tests who tells me that Broderbund is on the verge of releasing a
desktop publishing program for the Apple // that may put Newroom
completely out of business.

*******

The request for the Apple II Binary files seems a good idea; and here
they are:

                           AppBinary
                            ---------
              Apple II Binary File Transfer Format

                               by

                         Gary B. Little

Version History
---------------
November 6, 1986 :  Initial specification.

November 10, 1986:  Modified to add a version number byte and to
                    permit partial pathnames.

Background
----------
Transferring Apple ProDOS files in binary form to commercial
information services like CompuServe, Delphi, Genie, and The
Source is, to put it mildly, a frustrating exercise. (For
convenience, I'll refer to such services, and any other non-
binary transfer protocol, for example), they don't receive the
file's all-important directory attributes. The attributes are
stored in the ProDOS disk directory, not in the file itself.

These attributes are the access code, file type code, auxiliary
type code, storage type code, date of creation and last
modification, time of creation and last modification, the file
size, and the name of the file itself. (All these terms are
defined in Apple's "ProDOS Technical Reference Manual" or in the
book "Apple ProDOS: Advanced Features for Programmers" by Gary
Little.) It is usually not possible to use the file's data
without knowing what the file's attributes are (particularly the
file type code, auxiliary type code, and size), unless it is
known to be a standard ASCII text file. This means ProDOS files
uploaded in binary form to a host are useless to those who
download them.

Most Apple II communications programs use special protocols for
transferring ProDOS file attributes during a binary file
transfer, but none of these protocols have been implemented by
hosts. These programs are only useful for exchanging files with
another Apple II running the same program.

At present, the only acceptable way to transfer a ProDOS file to
a host is to convert it into lines of text and send it as a text
file. Such a text file would contain a listing of an Applesoft
program, or a series of Apple system monitor "enter" commands
(e.g., 0300:A4 32 43). Someone downloading such a file can
convert the file to binary form using the Applesoft EXEC
command.

The main disadvantage of this technique is that the text version
of the file is over three times the size of the original binary
file, making it expensive (in terms of time and $$$) to upload
and download. It is also awkward, and sometimes impossible, to
perform the binary-to-text or text-to-binary conversion.

The solution to the problem is to upload an encoded binary file
which contains not just the file's data, but the file's
attributes as well. Someone downloading such a file, say using
standard Xmodem, can then use a conversion program to strip the
attributes from the file and create a ProDOS file with the
required attributes.

To make this technique truly useful, however, the Apple II
community must agree on a format for this encoded binary file.
We cannot allow a variety of incompatible formats, all achieving
the same general result, to appear.

It is proposed that the AppBinary format described in this
document be adopted. What follows is a description of the
AppBinary format in sufficient detail to allow software
developers to implement it in Apple II communications programs.

The AppBinary File Format
-------------------------
The AppBinary form of a ProDOS file consists of a 128-byte file
information header followed by the file's data. The data portion
of the file is padded with nulls ($00 bytes), if necessary, to
ensure the data length is an even multiple of 128. As a result,
the AppBinary form of a file is never more than 255 bytes longer
than the original file.

The file information header contains four ID bytes, the
attributes of the ProDOS file, and some control information.
Here is the structure of the header:

         Offset  Length              Contents
         ------  ------   -----------------------------------
          +0       1      ID byte: always $0A
          +1       1      ID byte: always $47
          +2       1      ID byte: always $4C
          +3       1      access code
          +4       1      file type code
          +5       2      auxiliary type code
          +7       1      storage type code
          +8       2      size of file in blocks
          +10      2      date of modification
          +12      2      time of modification
          +14      2      date of creation
          +16      2      time of creation
          +18      1      ID byte: always $02
          +19      1      [not used]
          +20      3      end-of-file (EOF) position
          +23      1      length of filename/partial pathname
          +24      64     ASCII filename or partial pathname
          +88      37     [reserved, must be zero]
          +125     1      version number
          +126     1      operating system type
          +127     1      number of files to follow

Multi-byte numeric quantities are stored with their low-order
bytes first, the same order used by ProDOS. All reserved bytes
must be set to zero; they may be used in future versions of the
protocol.

To determine the values of the attributes to be put into a file
information header, you can use the ProDOS GET_FILE_INFO and
GET_EOF MLI commands. The "operating system type" byte is $00
for ProDOS 8 or ProDOS 16. The current implementation of
AppBinary has a "version number" of $00.

   Note: Some file attributes returned by ProDOS 16 commands are
         one byte longer than the attributes returned by the
         corresponding ProDOS 8 commands. Do not put this extra
         byte (it is always the high-order byte and it is always
         zero) in the file information header.

Filenames and Partial Pathnames
-------------------------------
Notice that you can put a standard ProDOS filename or a partial
pathname in the file information header (but never a complete
pathname). Beware! Don't use a partial pathname unless you've
included, earlier on in the AppBinary file, file information
headers for each of the directories referred to in the partial
pathname (see below for how multiple files can be sent in one
AppBinary file). Such headers must have their "end of file
position" bytes set to zero, and no data blocks for the
subdirectory file must follow it.

For example, if you want to send a file whose partial pathname
is HELP/GS/READ.ME, first send a file information header
defining the HELP/ subdirectory, then one defining the HELP/GS/
subdirectory. If you don't, someone downloading the AppBinary
file won't be able to convert it because the necessary
subdirectories will not exist.

Handling Multiple Files
-----------------------
An appealing feature of AppBinary is that a single AppBinary
file can hold multiple ProDOS files, making it easy to keep a
group of related files "glued" together when they're sent to a
host.

The structure of an AppBinary file containing multiple ProDOS
files is what you might expect: it is a series of images of
individual AppBinary files. For example, here is the general
structure of an AppBinary file containing two files:

  start                                                    end
  ------------------------------------------------------------
  | Header #1 | [file #1 data ] | Header #2 | [file #2 data] |
  ------------------------------------------------------------
    +127 = 1                      +127 = 0

The data areas following each header end on a 128-byte boundary.

The last byte (at offset 127) in the file information header for
each ProDOS file contains the number of ProDOS files that follow
it in the AppBinary file. It will be zero in the header for the
last ProDOS file in the group.

Identifying AppBinary Files
---------------------------
You can determine if a file is in AppBinary form by examining
the ID bytes at offsets +0, +1, +2, and +18 from the beginning
of the file. They must be $0A, $47, $4C, and $02, respectively.

If it is an AppBinary file, you can use the data in the file
information header to create and open a file with the correct
name and attributes (using the ProDOS CREATE, OPEN and
SET_FILE_INFO commands), transfer the file data in the AppBinary
file to the ProDOS file, set the ProDOS file size (with
SET_EOF), then close the ProDOS file. You would repeat this for
each ProDOS file contained inside the AppBinary file.

   Note: The number of 128-byte data blocks following the header
         block must be derived from the "end-of-file position"
         attribute (EOF) not the "size of file in blocks"
         attribute. Calculate the number by dividing EOF by 128
         and adding one to the result if EOF is not 0 or an
         exact multiple of 128.

Exception: If the file information header defines a subdirectory
(the file type code is 15), simply CREATE the subdirectory file.
Do not OPEN it and do not set its size with SET_EOF.

Ideally, all this conversion work will be done automatically by
your communications program during an Xmodem (or other binary
protocol) download. If not, you will have to run a separate
conversion program after the AppBinary file has been received.

Feedback
--------
Send any comments on the AppBinary standard to:

Gary B. Little
#210 - 131 Water Street
Vancouver, British Columbia
Canada  V6B 4M3
(604) 681-3371

CompuServe : 70135,1007
Delphi     : GBL
MCI Mail   : 658L6

**** Split off the following with your editor and download it as a
ProDOS .TXT file (or a Text file in DOS 3.3 then use CONVERT, the ProDOS
Utilities, or Copy 2 Plus to transfer to ProDOS) then execute
BASIC.SYSTEM and EXEC this file (under ProDOS mind you) - you'll get the
2 Apple II binary programs.  I've used these extensively to transfer
files to and from a Commodore based BBS, and these DO perform as
advertised.  Not to worry that AE ProDOS, Apple ACCESS II, and so forth
XModems download the files as .TXT, as long as they contain all 8 bits,
the FROM.BINARY program WILL recover.  I've also transferred files from
DOS 3.3 to ProDOS encoded them, transferred them, downloaded them and
transferred back to DOS 3.3 -- works fine.  I haven't had any trouble
transferring A2B encoded files to DOS 3.3 to upload and transferring
downloaded files from DOS 3.3 to ProDOS for decoding, but you can have
problems moving encoded files back and forth with some software (I use
Copy 2 Plus and haven't lost a byte yet). -- SEWALL@UCONNVM

*********

NEW
 1  REM  APPBIN.TO
 10  NORMAL : TEXT : NOTRACE : HOME
 15 D$ =  CHR$ (4)
 18 CD = 8192: REM  CODE START
 20 EC = CD + 18: REM  ERROR CODE LOCATION
 25 PN = CD + 19: REM  PATHNAME LOCATION
 30 DT = 10752: REM  BLOCK BUFFER ADDRESS ($2A00)
 32  DIM F$(255): REM  FILENAMES
 33  FOR I = CD TO CD + 296: READ X: POKE I,X: NEXT
 35  PRINT "PRODOS TO APPBINARY FILE CONVERTER"
 37  PRINT "(VERSION 1.00 --- NOVEMBER 10, 1986)"
 40  PRINT "BY GARY B. LITTLE"
 42  PRINT : PRINT "THIS IS A PUBLIC DOMAIN PROGRAM.": PRINT
 45  PRINT "THIS PROGRAM CREATES AN APPBINARY"
 46  PRINT "FILE FROM A GROUP OF PRODOS FILES."
 50  PRINT : PRINT "ENTER THE NAME OF THE DIRECTORY IN"
 60  PRINT "WHICH THE PRODOS FILES ARE STORED"
 70  PRINT "( E.G. /MYDISK/MYFILES/ ):": PRINT
 80  INPUT "";PF$: IF PF$ = "" THEN  HOME : END
 90  ONERR  GOTO 110
 100  PRINT D$;"PREFIX";PF$: POKE 216,0: GOTO 190
 110  PRINT : PRINT "THAT DIRECTORY DOES NOT EXIST."
 120  PRINT "PRESS ANY KEY TO CONTINUE:";: GET A$: PRINT A$: PRINT : GOTO 50
 190  HOME : PRINT "ENTER THE NAMES OF THE PRODOS FILES"
 192  PRINT "(PRESS [RETURN] WHEN DONE):"
 195 NF = 1
 200  PRINT : PRINT "ENTER THE NAME OF PRODOS FILE #";NF;": ";
 210  INPUT "";F$(NF)
 215  IF  LEN (F$(NF)) > 15 THEN  PRINT "ERROR: ILLEGAL FILENAME.": GOTO 200
 220  IF F$(NF) <  > "" THEN NF = NF + 1: GOTO 200
 230 NF = NF - 1: IF NF = 0 THEN  HOME : END
 232  PRINT : PRINT "ENTER A NAME FOR THE APPBINARY FILE: ";: INPUT "";AB$
 234  IF AB$ = "" THEN  HOME : END
 236 L =  LEN (AB$): IF L > 15 THEN 232
 238  ONERR  GOTO 242
 240  PRINT D$;"CREATE";AB$;",TBIN": POKE 216,0: GOTO 245
 242  IF  PEEK (222) = 19 THEN  PRINT D$;"DELETE";AB$: GOTO 240
 243  GOTO 600
 245  POKE PN,L: FOR I = 1 TO L: POKE PN + I, ASC ( MID$ (AB$,I,1)): NEXT
 250  CALL CD + 0: GOSUB 5000: REM  OPEN APPBINARY FILE
 260  HOME
 270  FOR J = 1 TO NF
 280 L =  LEN (F$(J))
 290  POKE PN,L: FOR I = 1 TO L: POKE PN + I, ASC ( MID$ (F$(J),I,1)): NEXT
 300  PRINT "STORING... ";
 310  FOR I = 1 TO L
 320 CH =  ASC ( MID$ (F$(J),I,1)): IF CH < 128 THEN CH = CH + 128
 330  PRINT  CHR$ (CH);: NEXT : PRINT
 340  REM  CREATE THE HEADER
 350  CALL CD + 3: GOSUB 5000: REM  OPEN/FORM HEADER
 360  POKE DT + 127,NF - J: REM  FILES TO FOLLOW
 370  REM  WRITE THE HEADER
 380  CALL CD + 9: GOSUB 5000
 390 EF =  PEEK (DT + 20) + 256 *  PEEK (DT + 21) + 65536 *  PEEK (DT + 22)
 400  IF EF = 0 THEN 460
 420  CALL CD + 6: REM  READ 128 BYTES
 425  IF  PEEK (EC) = 76 THEN 460: REM  BRANCH IF EOF
 430  GOSUB 5000
 440  CALL CD + 9: GOSUB 5000: REM  WRITE 128 BYTES
 450  GOTO 420
 460  CALL CD + 15: GOSUB 5000: REM  CLOSE PRODOS FILE
 470  NEXT J
 480  CALL CD + 12: REM  CLOSE APPBINARY FILE
 500  PRINT : PRINT "THE APPBINARY FILE, ";AB$;","
 510  PRINT "HAS HOW BEEN CREATED.": END
 600  PRINT : PRINT "ERROR: CAN'T CREATE ";AB$
 610  PRINT "APPLESOFT ERROR #"; PEEK (222): END
 5000 EN =  PEEK (EC): REM  GET ERROR CODE
 5010  IF EN = 0 THEN  RETURN
 5015  IF EN = 70 OR EN = 64 THEN  PRINT : PRINT "ERROR: FILE NOT FOUND": END
 5020  POP : PRINT : PRINT "ERROR: MLI CODE #";EN: END
 6000  DATA  76,84,32,76,100,32,76,203,32,76,223,32,76,233,32,76,239
 6001  DATA  32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6002  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6003  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6004  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32
 6005  DATA  0,191,200,13,33,32,251,32,173,18,33,141,34,33,96,32,192
 6006  DATA  32,169,10,141,0,42,169,2,141,18,42,169,23,141,1,42,169
 6007  DATA  42,141,2,42,174,19,32,189,19,32,157,23,42,202,16,247,32
 6008  DATA  0,191,196,0,42,32,251,32,169,71,141,1,42,169,76,141,2
 6009  DATA  42,173,4,42,201,15,240,30,32,0,191,200,19,33,32,251,32
 6010  DATA  173,24,33,141,26,33,141,12,33,141,19,42,32,0,191,209,18
 6011  DATA  42,32,251,32,96,162,127,169,0,157,0,42,202,16,250,96,32
 6012  DATA  192,32,32,0,191,202,25,33,144,5,201,76,208,1,24,32,251
 6013  DATA  32,96,32,0,191,203,33,33,32,251,32,96,169,0,56,32,251
 6014  DATA  32,169,0,141,18,32,32,0,191,204,11,33,96,141,18,32,144
 6015  DATA  8,104,104,32,0,191,204,9,33,96,1,0,1,0,3,19,32
 6016  DATA  0,34,0,3,19,32,0,38,0,4,0,0,42,128,0,0,0
 6017  DATA  4,0,0,42,128,0,0,0
SAVE TO.BINARY
NEW
 1  REM  APPBIN.FRM
 10  NORMAL : TEXT : NOTRACE : HOME
 15 D$ =  CHR$ (4)
 18 CD = 8192: REM  CODE START
 20 EC = CD + 21: REM  ERROR CODE LOCATION
 25 PN = CD + 22: REM  PATHNAME LOCATION
 30 DT = 10752: REM  BLOCK BUFFER ADDRESS ($2A00)
 32 LL = DT + 20: REM  EOF LOCATION
 35  PRINT "APPBINARY TO PRODOS FILE CONVERTER"
 37  PRINT "(VERSION 1.10 --- NOVEMBER 10, 1986)"
 40  PRINT "BY GARY B. LITTLE": PRINT
 45  PRINT "THIS PROGRAM EXTRACTS PRODOS FILES"
 46  PRINT "FROM A FILE IN APPBINARY FORM."
 48  PRINT : PRINT "THIS PROGRAM IS IN THE PUBLIC DOMAIN."
 50  PRINT : PRINT "ENTER THE NAME OF THE DIRECTORY IN"
 60  PRINT "WHICH THE APPBINARY FILE IS STORED"
 70  PRINT "(E.G., /MYDISK/MYFILES/ ):": PRINT
 80  INPUT "";PF$: IF PF$ = "" THEN  HOME : END
 90  ONERR  GOTO 5100
 100  PRINT D$;"PREFIX";PF$: POKE 216,0
 150  FOR I = 0 TO 297: READ X: POKE CD + I,X: NEXT
 200  PRINT : PRINT "ENTER THE NAME OF THE APPBINARY FILE"
 210  PRINT "YOU WANT TO CONVERT:";: INPUT "";F$
 220  IF F$ = "" THEN  HOME : END
 230 L =  LEN (F$): IF L > 15 THEN 5200
 235  POKE PN,L
 240  FOR I = 1 TO L: POKE PN + I, ASC ( MID$ (F$,I,1)): NEXT
 250  HOME
 300  CALL CD + 0: GOSUB 5000: REM  OPEN APPBINARY FILE
 305  PRINT "SCANNING THE APPBINARY FILE:": PRINT
 310  REM  READ HEADER AND CHECK ID BYTES
 320  CALL CD + 6: GOSUB 5000: REM  READ 128 BYTES
 330 I1 =  PEEK (DT + 0):I2 =  PEEK (DT + 1)
 335 I3 =  PEEK (DT + 2):I4 =  PEEK (DT + 18)
 340  IF I1 <  > 10 OR I2 <  > 71 OR I3 <  > 76 OR I4 <  > 2 THEN 1000
 345  IF  PEEK (DT + 126) <  > 0 THEN 1000: REM  NOT PRODOS
 350  REM  CALCULATE NUMBER OF BLOCKS TO READ
 360 EF =  PEEK (LL) + 256 *  PEEK (LL + 1) + 65536 *  PEEK (LL + 2)
 370 NB =  INT (EF / 128) + ((EF - 128 *  INT (EF / 128)) <  > 0)
 380  REM  DISPLAY NAME OF FILE
 382  PRINT "CREATING... ";
 384 L =  PEEK (DT + 23): FOR I = 1 TO L
 386 CH =  PEEK (DT + 23 + I): IF CH < 128 THEN CH = CH + 128
 388  PRINT  CHR$ (CH);: NEXT : PRINT
 390 TF =  PEEK (DT + 127): REM  NUMBER OF FILES TO FOLLOW
 400  CALL CD + 3: GOSUB 5000: REM  OPEN PRODOS FILE
 405  IF NB = 0 THEN 460
 410  FOR I = 1 TO NB
 420  CALL CD + 6: GOSUB 5000: REM  READ 128 BYTES
 430  CALL CD + 9: GOSUB 5000: REM  WRITE 128 BYTES
 440  NEXT I
 450  CALL CD + 18: GOSUB 5000: REM  SET EXACT EOF
 460  CALL CD + 15: GOSUB 5000: REM  CLOSE PRODOS FILE
 470  IF TF <  > 0 THEN 320
 480  CALL CD + 12: REM  CLOSE APPBINARY FILE
 500  PRINT : PRINT "CONVERSION COMPLETED.": END
 1000  CALL CD + 12: REM  CLOSE APPBINARY FILE
 1010  HOME : PRINT "ERROR: ";F$;" IS NOT AN APPBINARY FILE": END
 5000 EN =  PEEK (EC): REM  GET ERROR CODE
 5010  IF EN = 0 THEN  RETURN
 5020  POP : PRINT : PRINT "ERROR: MLI CODE #";EN
 5030  IF EN = 70 THEN  PRINT "FILE NOT FOUND"
 5040  IF EN = 71 THEN  PRINT "DUPLICATE FILENAME"
 5050  END
 5100  HOME : PRINT "ERROR: DIRECTORY NOT FOUND.": POKE 216,0: END
 5200  HOME : PRINT "ERROR: ILLEGAL FILE NAME.": POKE 216,0: END
 6000  DATA  76,87,32,76,103,32,76,199,32,76,209,32,76,219,32,76,225
 6001  DATA  32,76,237,32,0,0,0,0,0,0,0,0,0,0,0,0,0
 6002  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6003  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6004  DATA  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 6005  DATA  0,0,32,0,191,200,9,33,32,247,32,173,14,33,141,22,33
 6006  DATA  96,169,7,141,0,42,169,23,141,1,42,169,42,141,2,42,173
 6007  DATA  3,42,9,2,141,3,42,162,2,189,20,42,157,39,33,202,16
 6008  DATA  247,48,23,162,3,189,14,42,157,8,42,202,16,247,32,0,191
 6009  DATA  192,0,42,32,247,32,76,170,32,32,0,191,195,0,42,176,21
 6010  DATA  32,0,191,200,15,33,176,13,173,20,33,141,30,33,141,38,33
 6011  DATA  141,8,33,96,201,70,240,200,56,32,247,32,32,0,191,202,21
 6012  DATA  33,32,247,32,96,32,0,191,203,29,33,32,247,32,96,169,0
 6013  DATA  56,32,247,32,169,0,141,21,32,32,0,191,204,7,33,96,32
 6014  DATA  0,191,208,37,33,32,247,32,96,141,21,32,144,8,104,104,32
 6015  DATA  0,191,204,5,33,96,1,0,1,0,3,22,32,0,34,0,3
 6016  DATA  23,42,0,38,0,4,0,0,42,128,0,0,0,4,0,0,42
 6017  DATA  128,0,0,0,2,0,0,0,0
SAVE FROM.BINARY