+-------------------------+ ! APOLOGY TO CHRIS BUNSEN ! +-------------------------+ This Titan File must start with an apology to Chris Bunsen, an HP employee who has written some wonderful software for the HP-71. (I mentioned his GRAPH71 in HPX Exchange V1 N1 P25, Q26). It seems that I obtained a copy of SPLEX from an imprudent source, and believed it to be "freeware ". With this in mind, I ran the LEXSPLIT program on it, to remove the LIST$ and MODIFY keywords , and thus created the lexfile known as BASICLEX. This has been proliferating among the HP-71 c ommunity for almost two years now, and only last Saturday did I learn from Brian that it is in f act "pirated" software. So besides publicly apologizing to Chris Bunsen, who wrote SPLEX for his HP-71 spreadsheet progr am, I must also ask all of you kind folks who have a copy of BASICLEX to immediately PURGE it fr om memory, disk, tape and cards! It does not have the support of the author, to put it mildly. I just finished chatting with him on the phone, and he was relieved to hear that I had not copi ed it from a purchased copy of his spreadsheet, but still wants the record set straight. PURGE BASICLEX!!! It's not on the official swapdiscs, but it may be on one of your copies, so p lease check. One reason for killing BASICLEX is that it reportedly contains bugs that SPLEX does not contain. I have not verified this, but no sense tempting fate, so use SPLEX instead of BASICLEX. This is possible because Chris kindly donated SPLEX to the Markov Swapdisc program. You can find it on SWAP07, along with source code listings disassembled and commented by Mike Markov. Final note: until this morning's chat with Chris, he was not aware of the LIST$ bug mentioned in the CHHU Chronicle and in the BUFSTO10 documentation on SWAP07. The bug works like this. Type 10 DIM A(MEM/16). Then type A$=LIST$(10). You will immediately see Memory Lost! The problem i s the MEM in the DIMension. In general, any lexfile function (including LEX 01, the built-in lex file) used in a DIM statement of any kind (like INTEGER, COMPLEX, etc.) when pulled out by the L IST$ function during an assignment to a string variable, causes Memory Lost. So anything like A $=LIST$(10,F$) when F$'s line 10 is INTEGER M(MAXRC) will always wipe out. Perhaps Chris will t rack this bug down and give us a debugged version of SPLEX. If so, it'll be on the next swapdis c! +--------------+ ! THEOLOGY ROM ! +--------------+ As the astute noticed, the Quick Reference Guide in "HP-71 BASIC Made Easy" (pg. 147) refers to the CREATE ALL statement in the THEOLOGY ROM. This is just one of the many keywords to be found in this huge lexfile. It is based on a higher source code, which unfortunately this magazine i s too small to contain. But I just have to tell you about CREATE ALL; you are sure to get a big bang out of it! CREATE ALL, as the name implies, creates everything. Since this is such an immense task, it tak es about six DAYS (!) to finish, after which the configuration code works for another 24 hours m aking sure that what was CREATEd is indeed good, during which time the HP-71 will appear to have gone into deep sleep. Of course, CREATE ALL only works if ALL does not already exist. If ALL already exists, CREATE ALL gives the "File already exists" error. If this occurs, it isn't enou gh to PURGE ALL or even DESTROY ALL. The THEOLOGY ROM has an expanded version of END ALL that d oes the trick. Proper use of END ALL is vital, since further action by users who have ENDed is impossible. The following is suggested: "END ALL @ CREATE ALL" on one line! If interested in CREATE ALL and END ALL, please look for a subset lexfile called GENESIS on a fu ture swapdisc! But PLEASE use it carefully! +-----------------------+ ! HARD DISK IN A MODULE ! +-----------------------+ Looking for the perfect Christmas Stocking-stuffer gift for a loved one who already has an HP-71 ? Here it is! Diebstahl Electro-Acoustical Products, Inc (DEAP) has designed the most amazing HP-71 peripheral ever. Thanks to a new, esoteric and mendacious technology, DEAP has managed to fit a complete hard-disk Winchester drive and controller board INSIDE one (1) HP-71 module package! DEAP, formed in the early 70's by several Triangle Fraternity EE's at Illinois Institute of Tech nology (IIT), has often been showered with adumbration, but has remained unknown to most OEM's. Now, their new product may obviate facing the problems related to sudden fortune and fame. Although not yet officially announced, an interview between your Titan File editor and DEAP's ho t-line modem and ALPO bulletin board system revealed the following incredible details regarding the new disk module: The device plugs directly into any HP-71 port and addresses the data in file format just like th e 9114 disk drive from HP. Approximately 3142 megabytes (that's over 3KKK) are on-line. Specia l commands allow storing/recalling files, buffers, alternate operating systems, and digitized im ages. Rumors that disk access is so fast that files can be run without copying them back into R AM are tantalizing. The drive was actually a design mistake. DEAP had programmed the IIT computer to generate any c onceivable device when given the electronic and packaging parameters. One day they tried to des ign a large-memory, low-power 3.5-inch Winchester drive, but somebody typed .5 by mistake. To t heir amazement, the program found a solution and designed the new HP-71 disk drive. The module is designed with a piggy-back bus. If one is not enough, you can just plug another o ne into the one already there. Due to the daisy-chain logic, however, access time rapidly degen erates after more than one terabyte is on-line. Also, the battery drain becomes considerable. One design oddity is that data is not erasable once it has been written to disk. There are two heads: a write head, and a read head. Since they cannot move over each other, the write head i s always ahead of the read head, and writes sequentially only. Updating files is done by copyin g it with the desired revisions to a whole new file. This is not a design mistake; DEAP points out that with over a gigabyte of storage, you could fill 100K a day and still not fill the disk in 83 years. Besides, you can specify which version of a file you wish to access, in case your updating takes a wrong turn. The storage is so mind-bogglingly capacious that DEAP includes as a free demo file on disk of al l the U.S. census data from 1890 to date, and a digitized image of Warnock & Geschke printing ou t a digitized image of themselves on an HP LaserJet from an HP Vectra, via Postscript. Although it is not mentioned in the manual, prototypes have also been found to contain every HP-65 progr am in the Users' Library, plus an HP-67 program that translates them into HP-67 code so that HP- 71 Translator Pac owners can run them. The technical-minded reader may be interested to know th at the pack is formatted into 10,606 cylinders of 296,209 bytes each. The secret to the bit density and miniature package is the low flying height of the disk head, w hich is measured in thousandths of an angstrom. Since this would cause problems with large air molecules (carbon monoxide is okay, but carbon dioxide is too big and can cause misreads), the m odule is permanently sealed in an almost perfect vacuum. This design, called Micro-Angstrom-Gap Go-One-Time technology, or MAGGOT for short, is smaller and more expandable than WORM drives. Functions that allow the 9114 disk drive to interface directly with the MAGGOT have been provide d for making backups. Although a full MAGGOT would fill more 3.5-inch floppies (sometimes calle d "stiffies") than HP could ship in a century, this says less about the MAGGOT's or 9114's capac ity than it does about HP's famous shipping schedule. DEAP is currently designing an add-on that allows disk dumps at 18,000 baud to videocassette sys tems. Under consideration is an interface to a print-image microfilmer, for those who would lik e their HP-71 to run one of these $75,000 devices. Only one problem prevents the MAGGOT from being released to the market. Relativity Theory states that rotation and acceleration are non-uniform motions. DEAP sidestepped this problem by unifo rmly accelerating the rotation. Eventually the near-light-speed velocity of the disk pack create s a strong gyroscopic effect, so much so that any motion of the HP-71 with any angular different ial to the plane of rotation (such as lifting the HP-71 from the desk, or bumping the desk, or e ven pressing any HP-71 key) instantly results in a head crash, which in turn emits an intense st ream of sub-atomic particles from friction fission. DEAP does not like to study this phenomenon , however, because every HP-71 that has run afoul this way was instantly reduced to plasma, rend ering the date code unreadable and thus voiding the warranty. As soon as this minor bug is exorcised, DEAP promises to announce the MAGGOT hard disk module to the press, at a price based on the 9114's list price times the storage capacity difference. At that price, I hope it comes with a copy of the THEOLOGY ROM! +------------------+ ! USES OF PEEKUTIL ! +------------------+ If you'd like to go spelunking through HP-71 files, but aren't sure what's where, here's everyth ing you need to know, all in one handy place. Keep this page marked for future reference, or ma ke a photocopy of it. You'll need a copy of PEEKUTIL, written by Flavio Casetta. You can find it on Markov's swapdisc s (CHHU02 and CHHU06) or you can get it by sending me one blank mag card and a self-addressed st amped envelope. If you write PEEKUTIL on the card, no further note will be necessary. If you d on't mind typing the whole lexfile into the MAKELEX program, you can find PEEKUTIL listed in the CHHU Chronicle, V2 N7 P13. First, assuming the file we wish to explore is called FRED, then do this: +----------------------+ ! A=HTD(ADDR$("FRED")) ! +----------------------+ This puts FRED's address into A. If you change memory in any way that might move FRED, be sure to recalculate A in the way shown above. Now, for any filetype at all: TEXT$(A,8) = "FRED " (full 8-character file name) RPEEK$(A+16,4) = FRED's filetype in hex RED(PEEK(A+16,4),2^15) = FRED's filetype in signed decimal PEEK(A+20) = FRED's file protection as follows: 0 = no protection 1 = SECURE only 2 = PRIVATE only 3 = EXECUTE ONLY (both SECURE and PRIVATE) RPEEK$(A+22,4) = FRED's creation time in HHMM format RPEEK$(A+26,6) = FRED's creation date in YYMMDD format PEEK(A+32,5)+32 = FRED's total length in nibbles ADPEEK$(A+32,5) = Hex address of file after FRED in CATalog ADPEEK(A+32,5) = Decimal address of file after FRED in CATalog +--------------------------+ ! If FRED is an SDATA file ! +--------------------------+ PEEK(A+32,5) DIV 16 = number of records in FRED RPEEK$(A+37+16*N,16) = Contents of Nth record (record 0 is first) +------------------------+ ! If FRED is a DATA file ! +------------------------+ PEEK(A+37,4) = Number of records in FRED PEEK(A+41,4) = Number of bytes in each record in FRED +-----------------------+ ! If FRED is a LEX file ! +-----------------------+ PEEK(a+37,2) = FRED's lex ID in decimal RPEEK$(A+37,2) = FRED's lex ID in hex PEEK(A+39,2) = FRED's lowest token number in decimal RPEEK$(A+39,2) = FRED's lowest token number in hex PEEK(A+41,2) = FRED's highest token number in decimal RPEEK$(A+41,2) = FRED's highest token number in hex PEEK(A+43,5) = Distance to next linked lex table (0 if none) If that's not 0, then: ADPEEK(A+43,5) = decimal address of next linked lex table ADPEEK$(A+43,5) = hex address of next linked lex table (NB: Linked lex tables are all within one lexfile) PEEK(A+48) = Speed Table existence flag (15 if none) If that's 0, then LET A=A+79 to skip over speed table PEEK(A+49,4) = Distance to Text Table (0 if none) If that's not 0, then: ADPEEK(A+49,4,-1) = decimal address of text table ADPEEK$(A+49,4,-1) = hex address of text table PEEK(A+53,4) = Distance to Message Table (0 if none) If that's not 0, then: ADPEEK(A+53,4) = decimal addresss of message table ADPEEK$(A+53,4) = hex addresss of message table PEEK(A+57,5) = Distance to Poll Handler (0 if none) If that's not 0, then: ADPEEK(A+57,5) = decimal address of poll handler ADPEEK$(A+57,5) = hex address of poll handler A+62 = decimal address of Main Table +-------------------------+ ! If FRED is a BASIC file ! +-------------------------+ RPEEK$(A+37,5) = Hex distance to the first SUB or END SUB If 00000, then RUN or RENUMBER and try again If FFFFF, then there are no SUBs nor END SUBs RPEEK$(A+42,5) = Hex distance to first label or DEF FN If 00000, then RUN or RENUMBER and try again If FFFFF, then there are no labels nor DEF FNs RPEEK$(A+47,2) = "F0", the End-Of-Line (EOL) marker VAL(RPEEK$(A+49,4)) = first line number PEEK(A+53,2)-2 = length of first statement in nibbles If you LET L=PEEK(A+53,2)-2, then: PEEK$(A+55,L) = hex contents of first statement RPEEK$(A+55+L,2) = EOL or @ If F0, it's an EOL followed by another line number If F4, it's an @ followed by another length byte and so on, until the end of the file is reached. With these tools, you can explore any type of file. Here are a few ideas that came from this: +---------------------------+ ! TOKENIZE in one keystroke ! +---------------------------+ In the CHHU Chronicle, V1 N3 P29, a program called TOKENIZE was listed, which enabled you to see how BASIC changes keywords into hex tokens internally. Here is the same idea, but on a simple key definition instead of a whole program: KEY 'f4','J=PEEK(193885,5)@I=PEEK(J+53,2)-2@PEEK$(J+55,I);" (";STR$(I);")"': After making this key assignment, merely pressing [f][4] (the SIN key) will show the tokenized v ersion of the first statement of the current BASIC file, no matter what it is. This is followed by a nibble count, in parentheses. This is useful in comparing the byte length of different app roaches to the same task. +---------------------------+ ! LEXCAT lexfile catalogger ! +---------------------------+ Run LEXCAT (or CALL LEXCAT(F$) with a filename in F$), and see the hex address of the specified lexfile, the address of its poll handler(s), the address of the next file, and all the keywords in the lexfile with their execution code address (entry point), lex ID and token number, and fun ction syntax. This is an invaluable program for those of us who use lexfiles a lot. It is base d on a program by HP, with a few more bells and whistles, cleaner output, and much faster thanks to PEEKUTIL. 5 ! Requires PEEKUTIL & HPILROM 10 INPUT 'LEX File: ';F$ @ CALL LEXCAT(F$) 20 SUB LEXCAT(F$) @ ON ERROR GOTO 290 @ A1=HTD(ADDR$(F$)) 30 IF PEEK(A1+16,2)#8 THEN DISP "ERR:Not LEX file" @ END 40 S=A1+37 @ F$=UPRC$(F$) 50 C=S+25+NOT PEEK(S+11)*79 @ T$=DTH$(C)&RPEEK$(S,6) 80 IF LEN(F$) THEN PRINT @ PRINT "*** ";F$;" ***" @ PRINT "(";DTH$(A1);") File Header" 90 M=HTD(T$[8,9]) @ B=ADPEEK(C-13,4) 100 IF PEEK(C-5,5) THEN PRINT "(";ADPEEK$(C-5,5);") Poll Handler" 120 IF PEEK(B,2)=255 THEN 300 130 L=PEEK(B-1)+1 @ W$=TEXT$(B,L/2) @ S$=RPEEK$(B+L,2) @ D=C+(HTD(S$)-M)*9 140 PRINT "(";ADPEEK$(D+3,5);") ";T$[10];"/"; @ B=B+L+3 150 IF NOT HTD(S$) THEN PRINT "-- ";W$;" ffn" @ GOTO 110 160 PRINT S$;" ";W$; @ E=PEEK(D+8) @ IF NOT E THEN PRINT " postfix" @ GOTO 110 170 IF E#15 THEN 250 180 E=RMD(ADPEEK(D+3,5,-2),1048576) @ P=PEEK(E) @ Q=PEEK(E+1) 190 IF Q THEN PRINT "("; ELSE PRINT " fn" @ GOTO 110 200 FOR I=1 TO Q @ IF I#1 THEN PRINT ","; 210 E=E-1 @ X=PEEK(E) @ IF I>P THEN PRINT "?"; 220 IF X>11 THEN PRINT "#/$"; ELSE IF X>7 THEN PRINT "#"; ELSE PRINT "$"; 230 IF RMD(X,4) THEN PRINT "()"; 240 NEXT I @ PRINT ")" @ GOTO 110 250 IF NOT BIT(E,3) THEN PRINT " *P"; 260 IF NOT BIT(E,2) THEN PRINT " *I"; 270 IF NOT BIT(E,0) THEN PRINT " *K"; 280 PRINT @ GOTO 110 290 DISP "ERR:";ERRM$ @ BEEP @ END 300 IF KEY$="#38" THEN END 310 IF NOT HTD(T$[10]) THEN END 330 IF PEEK(S+6,5) THEN S=ADPEEK(S+6,5) @ F$="" @ GOTO 50 340 DISP "(";ADPEEK$(A1+32,5);") Next File Header" 350 END SUB If run on SPLEX, you'll see (with varying addresses): *** SPLEX *** (80008) File Header (80077) Poll Handler (800D5) 52/24 LIST$(#,?$) (80281) 52/23 MODIFY (808C4) Poll Handler (80900) 53/55 MAXRC fn (809F1) Next File Header which means SPLEX's file header begins at hex address 80008; its first poll handler begins execu tion at hex 80077; the LIST$ function starts execution at hex address 800D5, it has lex ID 52 (h ex), token 24 (hex), and takes one numeric argument, followed by an optional string argument; th e MODIFY keyword is a statement (no clue to its syntax!); there's another poll handler at 808C4; MAXRC is a function with no arguments; and the file ends at 809F0. Next Titan File: Self-modifying BASIC programs! Joseph K. Horn 1042 Star Route Orange, CA 92667