CP : HP-41 PROGRAMS FOR PRINTING OR DISPLAYING TEXT FILES, by M.Markov These programs allow HP-41 users to output any text (AS) file to a suitable printer or display, irregardless of the lenght of the file or the amount of available memory. Required : HP-41 Extended IO ROM, CPMM2 also uses Extended Functions ROM Select a printer device by setting flag 21. Clearing flag 21 cause the output to be sent to a display instead. To use this utility, enter the mass storage filename into the ALPHA register, and run the CP program. You should set perforation skip mode / reset the output device to avoid trouble. Turning the device off, then back on after several seconds is usually the easiest way. This is not done by the program, as we have no easy way to know the control codes for all the possible choices. REMEMBER - THE HP-41 only uses 7 byte file names. KEY-IN ONLY THE FIRST SEVEN CHARACTERS OF THE FILE NAME. Does not work if you enter more! (a special version of CP that uses the DEVIL ROM, now in the debuging stages, will be able to handle 10 character file names.) CPMM2 -- This version uses the extended function module function GETAS to keep the byte count to a minimum. This version of CPMM has an improved output algorithm that does a better job of handling text files from strange controllers. Briefly, text files consist of a set of records, each of which is preceeded by a two byte "Length Of Record" (LOR) header. Thus, each record could be 65534 bytes long.. While such files can be easily created with the HP-71, they are not typical. Typical files have record lenghts under 256 bytes. Also, each record MUST be an even number of bytes long, for upward compatibility with other HP machines. This is done by adding a "pad" byte to the end of odd-length records. With the HP-41 & HP-75, this was nearly always a byte whose numerical value was zero... Well, the golden days are over, and we must cope with non-zero pad bytes. The main disadvantage of CPMM & CPMM2 is that they cannot handle HP-71 secured text files -- GETAS errors out before it should, on invalid file type instead of "invalid destination file spec". Hence, if we want to print-out HP-71 secured files, we must go back in time and borrow code from earlier versions of CP, in this case, CP7 or CP8 (Published once upon a time in the Melbourne Technical Notes). This code is incorporated in CP21 below. I have tested these versions of CP on the HP82161A cassette drive, the HP9114A and the CMT RAMDISK drives. I have tried to solve a variety of problems that I could reproduce. The simple road to successful use of CP programs seems to be KEEP THINGS SIMPLE! I strongly recommend working with only one mass storage unit and one output device (either a video interface, or a printer) on the loop. This is especially important with HP9114 drives, where the HP-41 barely finishes reading a sector (256 bytes) to find that the drive has powered-down. In this respect, the HP9114 and the HP-41 (even at 2X speed-up and with battery eliminators) are poorly matched. It does not take long before you start getting error messages and poor performance. Some functions like INSTAT seem to be particularily sensitive. Generally - trouble occurs when a command is sent while the drive is "busy" powering-up, or moving the head to some distant location. This does not seem to be a problem with RAMDISK, where power-up and SEEK are nearly instantaneous, or with the cassette drive, probably because the HP-41 HP-IL was specifically designed to work with the cassette drive & thermal printer. Speeded-up HP-41 (above 1.7X) may run into TIME-OUT errors when used with the cassette drive. All comments that apply to CPMM2 also apply to CP21, although CPMM2 does a better job of handling HP-9114 drives. LBL "CPMM2" ADRON make sure of status, important. 16 AID for mass storage AUTOIO in case of trace, output is not sent to the drive! FINDAID find mass storage device SELECT make it primary device FLLENG this traps "file not found". You still can run afoul file type. "," force a specific GETAS error -- invalid destination specifier SF 25 do not stop on forced error GETAS if filetype is valid (AS), positions drive to "start-of-file" ATOXR get rid of appended comma 48 AID for displays FS? 21 do you want to select a printer? 32 yes, use printer AID (displays otherwise) CHS we want a class of device, not any particular model FINDAID find the output device SIGN save this address in LASTX register LBL 05 the output loop UNL make sure listeners dont catch trash 255 "End Of File" (EOF) test value INXB get first "length of record" byte (LOR) X=Y? is it EOF? GTO 00 yes, exit X=0? no, is LOR zero? GTO 05 ok, null record, loop for next record LASTX address of output device in X XFERN now, transfer the junk! LASTX save output device address X<>Y while you find out if there is a "pad" byte 2 MOD X<>Y SIGN restore output device address to LASTX X<>Y UNL make sure output device does not catch the "pad" byte X0? X not 0? (is there a "pad" byte?) INXB skip over pad LASTX now make output device listen while we send an "End-Of-Line" ADROFF prevent automatic UNListen frames LAD 13 carriage return. OUTXB send it! 10 linefeed OUTXB send it! ADRON restore automatic housekeeping for next XFERN GTO 05 go process next record LBL 00 housekeeping, to avoid future trouble ADRON END CP21 - THIS VERSION, WHILE LONGER, HAS THE DISTINCT ADVANTAGE OF BEING ABLE TO OUTPUT ==>ANY<== FILETYPE. You could send an HP-41 program file to a modem, produce hex listing, or anything you desire. All you have to do is write your own LBL 05 loop. This allows outputing HP-71 secured files - and other non-text files if you miskey the filename, or if another file has the same 7 leading characters in the file name. Since the CPMM2 listing (above) is partially duplicated in CP21, comments are provided only for portions of code that diverge from the above listing. LBL "CP21" ADRON AUTOIO 16 FINDAID SELECT FLLENG this load the directory entry for the desired file in drive ASTO 00 buffer #1. Save the object file name. ASHF now filename characters 7 to 10 (if any) ASTO 01 3 after FLLENG, the drive pointer is at start of next entry. DEVT set DDT3 mode, and get the pointers. INAN 3 bytes into ALPHA DEVL now set-up to reset the byte pointer ATOXR byte pointer value in X 18 decrement to "start-of-file" of desired file - 256 making allowances for possible wrap-around MOD OUTXB reset byte pointer! SIGN fastest way to load a 1 into X DEVT and prepare for reading buffer #1 at start-of-file 2 INAN get a two byte start of file address. Actually, the LIF standard X^2 provides a 4 byte address field, but 2 bytes is enough for media DEVL with 16 million byte capacity... Now, send DDT4 to reset the SQRT drive to start of file and send the two address bytes out. OUTAN send it! X<>FIO now, we wait while the drive is busy getting there LBL 03 INSTAT get drive status (does not always work with HP9114, if so, SST RDN past. RDN for stack managment, previous versions saved filename on stack. OK if 7 bytes or less. FS? 05 still busy? GTO 03 waste more time X<>FIO restore flags 0-7 2 DEVT set continuous talker mode -- we are ready to output 48 as soon as we take care of finding output device FS? 21 32 CHS FINDAID STO ] use status register O to save address of output device LBL 05 ADRON UNL 255 INXB X=Y? GTO 00 X=0? GTO 05 RCL ] XFERN 2 MOD UNL X0? INXB RCL ] ADROFF LAD 13 OUTXB 10 OUTXB ADRON GTO 05 note output loop is essentially identical - as it should be! LBL 00 again, housekeeping, just more of it. CLA ARCL 00 ARCL 01 ADRON END