Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!UCONNVM.BITNET!SEWALL From: SEWALL@UCONNVM.BITNET Newsgroups: comp.sys.apple Subject: IIgs software for the spoiled Apple II Binary files Message-ID: <8704082212.aa13014@SPARK.BRL.ARPA> Date: Wed, 8-Apr-87 22:11:00 EST Article-I.D.: SPARK.8704082212.aa13014 Posted: Wed Apr 8 22:11:00 1987 Date-Received: Mon, 13-Apr-87 05:36:09 EST Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 439 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