THE TITAN FILE Joseph K. Horn Welcome to "The Titan File"! This column is by and for HP-71 ("Titan") users. Anything and everything you or I can dream of that makes the HP-71 earn its keep belongs here!And if you remember the Titan File from the CHHU Chronicle, then welcome back! We’ll just continue here with HPX (thanx, Brian!) where we left off in CHHU. That makes this Titan File #10. If you don’t have any of the earlier columns, contact me for photocopies.This one will continue what column #7 began: Members’ questions and the HP-71 Answer Man’s answers. Since that column had 21 questions & answers in it, here we go with Q22: -------------------------------------------------- Q22. Paul Silberg of Salem, Oregon, and Lee Kenderdine of Antioch, Tennessee, want to know why COPY A$:TAPE doesn’t work, even if A$ contains the name of a file that is on tape or disc. A22. Syntax error! BASIC, like all languages, has strict rules of syntax. You can: COPY A$&":TAPE" or COPY :TAPE TO A$but you can’t COPY A$:TAPE because that’s mixing variables (A$) and unquoted string literals (:TAPE) in an illegal way. The first option, COPY A$&":TAPE" uses the string concatenator (&) to join A$ with a quoted string literal (":TAPE") which is legal. The second option, which I prefer by far, uses no quotes, no concatenator, no monkey business; it’s great in programs. -------------------------------------------------- Q23. Fred Farr, of Minneapolis, Minnesota, and practically everybody else, asks if there is an up-to-date lexfile list. A23. No. As soon as I update mine, rumors drift in about a whole diskfull of hot new lexfiles from some desert island. But if you’re interested in what I have at the moment, send a self-addressed stamped envelope (NO MONEY!!!) and ask for my current lexfile list (that’s ALL lexfiles known to me, not just the ones I wrote). -------------------------------------------------- Q24. Andre Cote of Ste-Foy, Quebec (Canada) asks why they didn’t put MAT READ in the HP-71 Math ROM. After all, they did put it in the HP-75 Math ROM; why did we get short-changed? A24. Because the bare-bones HP-71 has it! BUT it isn’t called MAT READ, it’s just plain old READ. If you use a variable that has been DIM’ed, then READ will automatically fill the array or matrix with DATA. For example, 10 DIM M(5) 20 READ M 30 DATA 123,234,345,456,567 will nicely fill all 5 elements of array M with the DATA values. No need for MAT READ; just use READ. It’s the HP-75 owners who got short-changed! -------------------------------------------------- Q25. Andre also asks whether keywords in lexfiles can be isolated into their own, smaller lexfiles, and whether or not linked lexfiles can be unlinked into their original lexfiles. A25. Yes, and yes! Although there is no easy way to surgically remove (lextract?) a single keyword (or specific set of keywords) from a lexfile, it can be done IF you have a disassembler, an understanding of the HP-71 IDS that’s good enough to cope with your disassembler’s deficiencies, enough time to wade through the disassembly listing to find what you’re looking for and to retype it as a new source code file, and an assembler. It’s not as mind-boggling as writing original code, but it’s time consuming. I’ve gotten pretty good at hacking up lexfiles and making new ones with the keywords I want. If you need any help, let me know.Regarding unlinking lexfiles, there is a beautiful program called LEXSPLIT that asks for the name of the lexfile you’re going to split up, tells you how many lexfiles it originally was before they were linked, asks for names for each of them, and makes NEW unlinked lexfiles, leaving the original linked lexfile intact! I wish my copy of LEXSPLIT had an author’s name in it, because I’ve plumb forgotten who wrote it. Send SASE for a copy. -------------------------------------------------- Q26. Bill Collins of Boulder, Colorado, asks what lexfiles exist that would help with HP-71 ThinkJet graphics. A26. If the GRAPH71 package (available from EduCalc) doesn't do what you need, then these LEX files might help: BITBYTLX - BITBYTE$($,#) turns bits into bytes. D2DLEX - DOT2DOT$($,#,#) "widens" bits any specified width. FLIPLEX - FLIP$($) flips the order of the bits in each byte. HIGHLEX - HIGH$($) sets the high bit of every byte. MAPLEX - MAP$($,$,$) replaces any byte(s) with any other. MAP file,$,$ does the same on an entire TEXT file. PATTERN - PATTERN$($) converts text to a GDISP pattern. PRNLEX - BEGINGR$, ENDGR$, HIGHGR$, LOWGR$, RASTER$(#), and tons of non-graphics ThinkJet keywords. RGCMDS - CPRSRG$($) compresses graphics into fewer bytes. EXPDRG$($) expands compressed data back to normal. ROWCOL - ROWCOL$($) transposes row-graphics to column. SBITLEX - SBIT$($,#,?#,?#) sets or clears any bit. SBIT($,#,#) tests any bit in a string. SHRINKLX - SHRINK file; shrinks space at end of TEXT files. SPCKLX71 - SPACK$($) packs text strings into fewer bytes. SUNPACK$($) unpacks packed strings back to normal. STRBOOL - AND$($,$) bitwise boolean AND on two strings. OR$($,$) bitwise boolean OR on two strings. EXOR$($,$) exclusive-OR on two strings. COMP$($) bitwise boolean NOT on a string. REVBIT$($) flips the order of the bytes’ bits. Also available in many lexfiles are these four useful functions: REV$($) reverses the order of the bytes in a string. RPT$($,#) repeats a string any number of times. STRSUM($) adds the ASCII values of all the bytes. CNTBITS($) counts bitwise how many 1’s are in the string. -------------------------------------------------- Q27. Eric Larkin of Union City, California wants to know how to recall the dimensions of a variable after dimensioning it. A27. If you have the Math ROM, use UBND and LBND. For example, DIM M(3,4). Then UBND(M,1) gives 3, and UBND(M,2) gives 4. LBND(M,1) gives either 0 or 1, depending on whether you had OPTION BASE 0 or OPTION BASE 1 active when you DIMensioned M.If you don’t have a Math ROM, you should go buy one. If you can’t, then you should weep and gnash your teeth. If that doesn’t help, you can always PEEK at a variable’s dimensions, as in the program LISTVARS on the French swapdisk. A full discussion of that is beyond the scope of this Q&A column. -------------------------------------------------- Q28. Keith Gordon of Munsonville, New Hampshire, asks how to get Greek letters on the ThinkJet. A28. You can’t. Of course, you can create them using ThinkJet graphics, and if you really need them, go ahead, but it’ll take a bit of doing to design them all, dot by dot. The ThinkJet does not have a Greek font, or Greek mode, or Greek character set, or anything like that. Sorry. -------------------------------------------------- Q29. Keith also asks how to list a STAT array’s contents and edit the individual entries in it. A29. Sorry again! If you mean that you want to list the individual data that you ADDed into the STAT array, forget it! It cannot be done, because they don’t exist. When you ADD data, the STAT array is modified to reflect that addition, but the data itself is thrown away and is not stored anywhere. In effect, just the running average and a number related to the standard deviation are stored in the STAT array, not the individual data. But if you mean that you want to access the values that ARE in the STAT array (even though they are NOT the data you ADDed), that is very easy, and is done as for any array, e.g. DISP A(3), or A(3)=153, etc. -------------------------------------------------- Q30. Dr. Martin Koenig of Cincinnati, Ohio, points out that the "TIMEFMT" subprogram in the HP-71 Utilities Book gives results like "05:14:04. AM" and wonders how to get rid of that extraneous dot.A30. Excellent question! BASIC is supposed to be easy, but look how messy getting rid of one lousy dot can be! Solution 1: Change HP’s subprogram like this. Change line 290 to: S=IP(FP(T*100)*100), and delete line 340. That seems to work. Solution 2: Don’t just CALL TIMEFMT(T,T$,12). Instead, use this in your calling program: STD @ CALL TIMEFMT(T-RED(T,1E-4), T$,12). That seems to work too. Solution 3: Leave the subprogram alone, and call it normally, but then don’t use T$ as is; use T$[1,8]&T$[10]. That leaves out the dot! (This is the most trivial solution). Solution 4: Don’t even use that subprogram. There are lexfiles that do it faster, with no dots. For example, the TCNV$(#) function in the TCONV lexfile takes a decimal number of seconds and converts to HH:MM:SS format. The HMS$(#) function in the TIMELEX file takes a decimal number of hours and does the same. -------------------------------------------------- Q31. James Cave of Princeton, Texas, wants a complete bug list for the HP-71. A31. So do I! The one I have is huge, but it’s still growing! If you’d like a photocopy of what I’ve got, just send an SASE and a request for the HP-71 buglist. -------------------------------------------------- Q32. James also asks what is the shortest and fastest way to toggle a flag. A32. If the flag number is F and X is a scratch variable, then a short & very fast way is: X=FLAG(F,NOT FLAG(F)). Notice that this suggests a short & fast way to SWAP two flags’ values. If the flags are F and G, and X is scratch, then X=FLAG(F,FLAG(G,FLAG(F))) swaps ‘em quick as a wink! -------------------------------------------------- Q33. Dr. August Nechi of Stone Mountain, Georgia, notices that nothing happens when he tries to turn on "blink mode" by POKE "2E3FF","3". What’s wrong? A33. Nothing’s wrong. Blink mode is disabled by ANY display change, and pressing ENDLINE after a command (such as POKE "2E3FF","3") clears the display, thereby terminating blink mode (which was enabled for one zillionth of a second). To see blink mode in action, POKE "2E3FF","3" @ WAIT 5. The display blinks for 5 seconds (5 blinks) and then clears. Or try this: "Blink Mode!" @ POKE "2E3FF","3". Since there is something to display, blink mode won’t stop until you interrupt it. Try it again after setting DELAY 3. The POKE doesn’t take effect until the 3-second DELAY is past. -------------------------------------------------- Q34. Richard de Queiroz of Palos Verdes Estates, California, asks if there is a way to change the beep-margin from 96 to 80. A34. Yes and no. Yes, you can get any of various lexfiles that add the MARGIN command, and use it to set MARGIN 80 (as the HP-75 does). No, you can’t move the "hard margin" over; you’ll always be able to type 96 characters, even if the "beep margin" is at the 80th column. A method of programming limited-length inputs using non-readable display characters is described in the HP-71 Software Developers’ Handbook, page 9-6. -------------------------------------------------- Q35. Howard Snapp of Waukesha, Wisconsin, notices that the GEDIT program (in the HP- 71 Software Developers’ Handbook) doesn’t Print correctly, and asks if it can be fixed. A35. You’re right; it doesn’t work! Whoever wrote it did NOT have the HP-71 or the ThinkJet in mind. Yes, it can be fixed; you need a copy of D2DLEX in memory though. Just add these lines to the program: 280 PRINT CHR$(27);"*rA"; @ FOR J=0 TO 7 @ FOR K=1 TO 4 282 PRINT CHR$(@&);"*b66W";DOT2DOT$(A$,J,4) @ NEXT K 284 NEXT J @ PRINT CHR$(27);"*rB"; @ GOTO 50 Try values other than 4 in lines 280 and 282 for different sized printouts. In case your version of the Software Developers’ Handbook doesn’t have the other bugs out, also be sure to make these changes to GEDIT too: Line 20 should end with: @ PWIDTH INF Delete line 60 and replace with: 60 SFLAG 5 Delete line 90 and replace with: 90 GOSUB 290 Line 100 should be only: 100 K$=KEY$ Line 200 should have: @ GDISP A$ @ A$=GDISP$ inserted between the READ and GOTO statements Lines 210,220 and 230 should end with: @ GOTO 50 Line 260 should be: 260 INPUT "X,Y:",STR$(X)&","$STR$(Y+1);X,Y -------------------------------------------------- Q36. Ed Winfield of Hollis, New York asks how to interrupt a program that has a lot of inputs in it, take a break for lunch, then come back and resume where you left off without starting all the inputs all over again. A36. Simple: just press the [OFF] key at an input prompt, and the HP-71 will immediately turn off. Enjoy lunch. When you return, press [ON], and you will see the "SUSP" annunciator telling you that the program was suspended. Press the [CONT] key, and you will be whisked immediately back into action, precisely at the same input that was running when you pressed [OFF]!There is only one exception that I can think of. If you press [OFF] during a MAT INPUT (a Math ROM specialty), you will have to begin all over again with array element 1 when you CONTinue. Since the Math ROM displays the element number expected, and since the partially typed array is still available in the command stack, this should not be a problem at all. If it is, plug in your HP-71 to AC, set flag -3 (the continuous ON flag), and just leave the ’71 turned on, right through lunch! -------------------------------------------------- Q37. Jim Bell of Honolulu, Hawaii, asks for the memory address of the display. A37. Unfortunately, the display is NOT mapped into a single chunk of memory, but three chunks, and they’re not even the same size. To satisfy your curiosity, here are the addresses. The leftmost 46 display dot columns (numbered 0 thru 45) reside at hex 2E104 thru 2E15F. The middle 48 columns (numbered 46 thru 93) reside at hex 2E200 thru 2E25F. The rightmost 38 columns (numbered 94 thru 131) reside at hex 2E300 thru 2E34B. The even-numbered addresses are the top four dots of each column, and the odd-numbered addresses are the bottom four dots. So try this: "FA" @ POKE "2E10C","F7". See what happened? The "FA" was displayed, then the POKE drew a line on top of the "F" making it look like a squarish "A". -------------------------------------------------- Q38. Donald Humbert of New York City wants to know my definition of prime numbers. A38. MY definition? As opposed to THE definition? Okay; my definition: A Prime Number is a natural number with exactly two natural number factors. ("Natural number" = integer greater than 0; also called the "counting numbers".) Notice that this definition doesn’t fit 1, which has only one natural number factor (itself). 2 is the first prime number, its factors being 1 and 2. This agrees with THE definition, but I like mine better because it’s easier to understand. "Do two and only two numbers go into it? Then it’s prime." -------------------------------------------------- Q39. Bill Figueroa of Richardson, Texas, has the Variable Cross Reference program from the HP-71 Utilities Book, but can’t use it because it bombs out if there are more than 63 variables for it to handle. Is there a better one? A39. Yes. Just send an SASE and request "VARXREF", an improved version of the Variable Cross Reference program. This one has NO limits. If you want it on card or disc, send 2 cards (it’s 1933 bytes long) or a disc, and enough postage on the SASE. -------------------------------------------------- Q40. Hans Decarli of Pine Grove, California, doesn’t have a printer, so he programs his HP-71 to stop at every display so that he can write down the output, and then makes the program resume. The problem he notices with this approach is that the HP- 71 is doing nothing when he’s writing down each output, and he’s doing nothing when the HP-71 is running; what a waste of time! He wonders if there is some way to have the HP-71 running while he’s writing down the answer. A40. YES!!! This will sound odd, but think about it. All you have to do is pause BEFORE each DISP, instead of after. You can’t use DELAY for this. A simple keystroke-seeking line is:30 IF NOT LEN(KEY$) THEN 30If you have the KEYWAIT$ or KEYSLP$ function or one like them, then you can simply say A$=KEYWAIT$, with A$ being any scratch variable.Notice what happens when you do this? When you press a key, the next output is immediately displayed (because we paused right before the DISP), and then the program goes running full steam in search of the next output, WHILE YOU ARE WRITING DOWN THE LAST OUTPUT. No time wasted; you are working, and the HP-71 is working.No solution’s perfect, however. Notice that this method prevents us from ever getting the very FIRST output; the program will pause itself right before the first output! My solution to this is silly, but it works: I start the program with PUT "X". (You can PUT any character you like.) This makes the first pause get skipped, because it thinks that a key was pressed! 10 PUT "X" 20 GOSUB ‘SEARCH’ @ BEEP 1400,.07 30 IF NOT LEN(KEY$) THEN 30 40 DISP whatever the output is 50 GOTO 20 60 ‘SEARCH’ @ etc. The BEEP in line 20 is a bonus: the HP-71 chirps when it finds the next output, so that you know, but it doesn’t change the display, in case you’re still writing down the previous one. -------------------------------------------------- Q41. Harold F. Byrd of Chula Vista, California, asks if there is any way that the "LOCKOFF" lexfile can be used to unlock somebody else’s HP-71. A41. Harold, really now. Many people rely on the LOCK feature of their HP-71’s to prevent unauthorized access to their machines. Why? Perhaps they have data in there that should not fall into the wrong hands. Perhaps they are developing brilliant new software and they don’t want their ideas stolen. Perhaps they simply have stuff in there that they don’t want messed up by some knucklehead with hyperactive fingers. They have a right to believe that LOCK is what HP said it is: a security device. So how could I in good conscience publish the method (quite simple, really) of using "LOCKOFF" or "NOSTRTUP" to unlock somebody else’s HP-71? No, no, I can’t... -------------------------------------------------- Q42. Evan Magnuson of Hammond, Louisiana, asks if there is any way to print out the command stack. A42. It’s easy if you have the PEEKUTIL lexfile (also called UTILLEX); all it takes is this little routine: 10 A=PEEK("2F576",5) 20 FOR X=PEEK("2F976")+1 TO 1 STEP -1 30 L=PEEK(A,3) 40 IF NOT L THEN 60 50 PRINT STR$(X)&": "&TEXT$(A+3,L/2-1) 60 A=A+L+670 NEXT X If you don’t have PEEKUTIL, it would take less effort to send me an SASE (with mag card or disk if you want it recorded) than it would take to rewrite this to just use PEEK$. -------------------------------------------------- Q43. Evan also asks if the alarm annunciator is ever used in the HP-71. A43. Not really. The Debugger that HP sells uses it as a "Debugger Active" annunciator, but the Debugger manual tells how to change the software so that any other annunciator can be used instead. SUPERLEX, sold by Titan Software, contains keywords for turning the alarm annunciator on and off. Nothing uses it seriously.However, I just got a letter in the mail today (dated 24 June 1987) from a young lexfile expert who says he’s thinking about writing "an alarm lexfile which is similar in operation to the HP-41 XYZALM function." That’s good news! And who knows; he might give the alarm annunciator some real use, after all these years! -------------------------------------------------- Q44. Vern C. Hunt of Orange, California, is looking for a better way of printing a line of dashes than the obvious and explicit PRINT "------------------------". A44. Use USING! PRINT USING "60'-’" will nicely print 60 dashes, as you see above. If you are a total speed demon, PRINT RPT$("-",80) is a tad faster, but you need a lexfile that contains RPT$. -------------------------------------------------- Q45. Lotsa folks from all over have asked if there is a short routine that converts from decimal degrees or hours (HR) to hours-minutes-seconds format (HMS), like the HP-41 has. A45. Just add these two UDF’s (user-defined functions) to your program that needs the conversions: 10 DEF FND(X)=X+FP(X)/1.5+FP(X*100)/90 ! FND(x)=HR(x) 20 DEF FNT(X)=X-.4*FP(X)-.004*FP(X*60) ! FNT(x)=HMS(x) Then, whenever you need to convert decimal hours (or degrees) to H.MMSS format, just use FNT(x) as if it were a built-in function. (The "T" in FNT stands for "Time format"). To convert H.MMSS back to decimal hours, use FND(x). (The "D" stands for "Decimal format"). The comments at the end of each line are just in case you forget which is which. The line numbers can be anything at all, but the DEF’s MUST reside within the main program or subprogram that uses them. You needn’t have both if you only need to convert one way. You’ll love how FAST these are! -------------------------------------------------- Q46. Tim Eide of Ventura, California, bought the Debugger but were upset to find that it contains the software on disc, not on cards. Since he owns only a card reader, he asks if the Debugger is available on cards. A46. Send me 11 mag cards, an SASE with enough postage on it, and a request for DBGLEX1A, DBGLEX2A, DBGLEX3A and DBGMAINA. -------------------------------------------------- Q47. Horst Debushman of Frankfurt, West Germany, wants to know if there is a lexfile that can put the HP-71 into gradian mode. A47. No, and for good reason. To convert from degrees to gradians, all you have to do is divide by .9; no lexfile required for that! Multiply by .9 to go from gradians back to degrees. Anyway, what’s a German using Japanese angles for? It reminds me of the time a fellow walked into the HP booth at the Consumer Electronics Show, and hassled a poor HP employee about a calculator on display because it didn’t have hyperbolics. The HP rep in all sincerity asked him, "But what are hyperbolics used for?" It deflated the guy completely, because he had no idea what hyperbolics are used for! He probably saw it on other calculators, and missed it on the HP, and thought it "should" be there. Gradian mode? Gimme a break. -------------------------------------------------- Q48. Michael Scano of Palo Alto, California, likes the way PRINT USING can format things, but he wonders if there is some way of getting it to output to a string variable instead of just to a printer or display. A48. Yes! There is a lexfile called FMTLEX that adds two keywords to BASIC, one of which is PRINT TO. This new version of PRINT uses USING like normal, but dumps the output into a string variable! For example,PRINT USING "’Total:’,’$’3dc3d.2d" TO A$;12345.67;would place "Total: $12,345.67" into A$. Of course, now that it’s in a string, you can put it in a file or whatever you want with it. For a copy of FMTLEX, send SASE, 1 mag card if you want it recorded, and a request for FMTLEX. It also contains IMAGE$, a way of pre-processing IMAGEs before USING them. -------------------------------------------------- Q49. Michael Markov of Lockwood, New York, was somewhat put out by the way I seemed to give my blessings to software piracy in Titan File #7, Questions 2 and 3. Isn’t this wrong? A49. Software piracy is illegal, bad, and stupid. Illegal because enough citizens demanded it. Bad because benefitting from the work of another without giving them just remuneration for their labor is immoral. And stupid because it ultimately has two horrendous effects: software is sold with awful copy protection schemes that make everybody (especially hard-disk users) very upset, and the authors of the really good software (the stuff that gets pirated the most) quickly get discouraged and stop writing code, and our sources of elegant programming disappear. Mike, I couldn’t agree with you more about software piracy: it is indeed A BAD THING.In Titan File #7, I did not recommend or advocate software piracy. I suggested that if a user wants a MINOR PART OF A WHOLE, when that part is only available by purchasing the whole, then go ahead and copy it from a friend or dealer or whatever. It’s like reading a friend’s Calvin and Hobbes comic book, and finding one strip in it that really makes you howl, so you borrow the book and photocopy that one page. Is that breach of copyright? Of course not. Photocopying half the book is another story entirely! If somebody wants the HP-71 Software Developers’ Handbook, I tell them to go buy it. But if they want just the STRINGLX lexfile, which amazingly is not available through the Users’ Library, then I just give them a copy. This is not software piracy. Of course, this is my opinion. Not everybody agrees with me. Not everybody is right. Joseph K. Horn 1042 Star Route Orange, CA 92667