CPDEVIL - an HP-41 program for printing mass storage text (AS) files, using only the HP-IL Development (DEVIL) ROM & the HP-IL module. By Michael Markov This program was written in support of the SWAPDISK program. Speciffically, the intent behind this version of the CP program was to overcome the 7 byte filename limitation of earlier CP programs, which (as far as HP-41 mass storage functions are concerned) meant that some text files could not be readily accessed. CPDEVIL, unlike earlier versions, supports the maximum length (10 bytes) mass storage file names. In addition, CPDEVIL eliminates the need for other ROMs, such as the Extended I/O & Extended Function ROMs, at least insofar as printing documentation files is concerned. Also, the techniques here used could be easily adapted to Mitch Hoselton's MCPY41 (Mass storage media duplication) program. This program could easily be shortened by taking advantage of the Auto Address Unconfigure (AAU) mode. However, this would preclude use with either the CMT RAMDISKs, or with HP-IL video interfaces. This program can undoubtedly be optimized in various ways, as I have not been able to spend time on that part of the job.. The operating instructions for CPDEVIL are the same as the ones for CPMM2 or CP21, with one notable exception: BE SURE TO UNPLUG UNNECESSARY ROMS, OR PLUG-IN THE DEVIL INTO A LOWER NUMBERED PORT. Otherwise, these ROMs may interfere with the proper operation of the I/O buffer. After unplugging the ROMs, toggle the HP-41 ON, then OFF, to allow the operating system to blow away existing buffers. THEN, plug-in the DEVIL. The question is which ROMs cause problems... I had some difficulties that seemed associated with the CCD module. Other modules could also cause problems. LBL "CPDEVIL" in honor of the HP-IL DEVelopment module . clear regs. 00-02 STO 00 storage for address of mass storage device STO 01 storage for address of printer device STO 02 storage for address of display device MANIO selected device is assumed to be the desired peripheral CF33 enable normal loop operations such as INSTAT E the following code determines the number of loop peripherals AAU AAD E now, we build a loop counter to determine the type of devices - on the loop. E3 / SIGN and save it in LASTX ST+ L LASTX now has a # => 1.0nn00, beg.endin(crement) LBL 00 now, to find the first drive, display & printer: LASTX make each device on the loop (in turn) UNT the talker, and ask it to tell you its TAD AID, making sure previous talkers stop talking. SAI what are you? UNT thanks. Now hush-up. 64 AID for interface & other types of devices are ignored X<=Y? controller, mass storage, printer or display? GTO 01 no, try the next device RDN 48 lowest AID for displays X<=Y? are you a display GTO 02 yes, go save the address (if first display on loop) RDN 32 lowest AID for printers X<=Y? GTO 03 go save the address of the printer RDN 16 AID for mass storage X=Y? GTO 04 go save address of drive, if first on loop LBL 01 increment loop counter & go process next device, until done. ISG L GTO 00 GTO 05 we have proccessed the last device, skip routines below LBL 02 save display address, if first. R02 is initially 0. LASTX the loop address to be saved X<> 02 save it in R02 X0? if X not equal to zero, it is not the first X<> 02 oops - not the first, restore first to storage GTO 01 go process next device LBL 03 same as LBL 02 above, but for printers LASTX X<> 01 X0? X<> 01 GTO 01 LBL 04 same as LBL 02 & LBL 03 above, but for mass storage LASTX X<> 00 X0? X<> 00 GTO 01 LBL 99 error exit when ouput device is missing "NO OUT. DEV" here, we really should exit via LBL 15 BEEP in order to restore "normal" system operation PROMPT should be AVIEW, GTO 15 LBL 05 test for output device availability RCL 02 FS? 21 according to the type selected (Flag 21 set for printers, clear RCL 01 for displays) X=0? is it missing? GTO 99 sorry, it's missing RCL 00 do we have a mass storage device? X=0? AUTOIO no, force error message X=0? DIR HP-IL now tells us "No Drive", if applicable SELECT it is all there, let's do something with it! LAD SDC clear the drive UNL TAD and tell it to be ready to talk 2 set continuous talk mode DDT DDT and move pointers to the start of directory 256 create a buffer of suitable size BSIZEX MIPT Manual Increment PoinTer mode. In this application, the buffer is a temporary storage area for variable length strings. This allows us to avoid reseting the pointer after every read " " append 9 spaces. Provides spaces so that first 10 characters LBL 09 in ALPHA are equal to the filename on the mass storage mmedium 0 PT= LBL 10 read each directory entry to the buffer 32 each is 32 bytes long... INBUFX the actual "get-it" 10 and compare the file name in ALPHA with the directory entry A=BUFX? using the maximum length mass storage file name GTO 11 Found it!, exit loop GTO 10 sorry, try next file LBL 11 now, we make sure the target file is not purged 10 PT= move the pointer to file type 2 get the file type (2 bytes) into X BUF-XB X=0? are you purged? GTO 09 yes, continue the search 14 Found it! so, we move the pointer to the start of file pointers PT= UNT tell the drive to stop talking RCL 00 so it can be told where to stick its head... LAD drive listen 4 DDL DDT4 - SEEK sector, to start of file 2 OUTBUFX using the two byte address just sent LBL 08 now, we wait until it gets there INSTAT drive status? FS? 05 are you still busy? GTO 08 wait some more UNL ok, we are finally there, now we tell the drive to stop listen RCL 00 and to stay in continuous talk mode until we are done TAD 2 DDT 0 reset buffer pointer to start of buffer (not really required, PT= but good practise. Sooner or later I forget where I end-up.) 10 now, get rid of excess trailing blanks in alpha CLA the easy way - using the data in the buffer. Another reason for BUF-AX resetting the pointer. LBL 06 now, we implement direct drive to output device transfer. UNL unlisten, so output device does not print length of record bytes RCL 00 re-enable drive talker mode with TAD 0 DDT DDT0 - pointer / read mode does not change SF33 prevent interference from automatic loop operations, in case we 0 stop (R/S) the program. Set CA bit in HP-IL control register ENTER^ to enable NRD handshake when we use INBUFX. We also set-up other 193 flags, the why would take a couple pages, and put me to sleep! WREG Store flags into reg. 0 CF33 should probably be moved to end of LBL 06 loop 2 INBUFX read 2 byte length of record header 2 BUF-XB and put it in X as a decimal value 65535 End-Of-File test value X=Y? are we done? GTO 15 yes, clean-up & END RDN no, transfer bytes specified by LOR X=0? unless it is a null record.. GTO 06 in which case, we go process the next record header FS? 21 choose output device according to flag 21 RCL 01 use the printer FC? 21 RCL 02 or the display (could be both) LAD and have it listen while you read the text of the record RDN LOR in X INBUFX read bytes as specified by LOR 2 determine whether the record length is even MOD UNL prevent output device from receiving the "PAD" byte X0? is LOR odd? (is there a pad byte?) INBUFX yes, skip past to next header FS? 21 re-enable output device listener status RCL 01 FC? 21 RCL 02 UNT untalk the drive -- we cannot have both the HP-41 and the drive talk at the same time LAD output device, listen 3338 so you can send carriage return & linefeed OUTBIN to any listeners on the loop (as many as we want, an advantage GTO 06 over XFER functions in the IO ROM. Go process next header. LBL 15 restore system flags for normal operation UNL prevent accidental trash from being sent to output device UNT untalk drive. Probably should rewind it as well. 0 BSIZEX recover memory used by I/O buffer AUTOIO CF33 END done, at last. NOTE: you should always exit via LBL 15, otherwise it may appear that your HP-41 / HP-IL system is malfunctioning... The amount of code required to replace FINDAID is rather staggering. The following version show a more compact approach that takes full advantage of the AAU (Auto Address Unconfigure) mode. In this mode, existing mass storage devices have a loop address of 2, most 80 column printers have address 5, and displays have address 31. This last is a real disapointment, since 31 LAD is equivalent to UNL, meaning you use your display in this mode, unless you modify the operating system EPROM. The obvious advantage of AAU mode is that you can hook-up hundreds of printers all at once, and have all of them produce copies of documentation. The problem associated with this mode is that if you have several drives on the loop, all of them would try to become talkers at the same time. This means that it is up to the user to insure that this never happens. One thing you may NEVER do, is check the printer(s) status if there are multiple printers, all of them sharing loop address #5. You have been warned! Results that could follow include some nasty crashes.. Last, the CMT RAMDISK responds to AAU by UNListening and UNTalking itself. This is reasonable considering that the multiple drive mode would have difficulties handling multiple talkers, or storing information into up to four addresses at once. (A better implementation would allow you to specify the virtual drive to be used in AAU mode, possibly by enabling the drive which was last accessed) Documentation notes here included document difference from CPDEVIL LBL "CPDEV2" MANIO CF33 AAU here, we invoke AAU mode without following with AAD 4 HP-IL register 4 holds the selected device address 2 the AAU mode address for mass storage WREG select the mass storage as the primary device LAD drive listen SDC clear the drive - selected device clear. Could time out UNL if rewinding a cassette. TAD Drive Talk mode DDT DDT move to start of directory 256 BSIZEX MIPT " " LBL 09 0 PT= LBL 10 the directory search is the same 32 INBUFX 10 A=BUFX? GTO 11 GTO 10 LBL 11 10 PT= 2 BUF-XB X=0? GTO 09 14 PT= UNT 2 LAD 4 DDL 2 OUTBUFX go to start of file UNL TAD now, a new approach to getting device status, using SST 32 INSTAT unfortunately disturbes AAU mode LBL 14 SST X<>Y X<=Y? are you still busy? GTO 14 yes, wait some more 2 there at last TAD the 2, TAD should be probably be deleted -- the drive is already 2 the talker. DDT sets continuous talk, as before 0 PT= 10 CLA BUF-AX LBL 06 UNL 2 TAD 2, TAD replaces RCL 00, TAD 0 DDT SF33 0 193 WREG 2 INBUFX BUF-XB 65535 X=Y? GTO 15 RDN X=0? GTO 06 5 AAU mode address for 80 column printers. Thermal printer's is 1 LAD much simpler! and nothing stops you form RDN 4 making the HP82166 converter listen also! (My own set-up). LAD RDN INBUFX so we have now implemented a multiple direct transfer & done it 2 MOD UNL X0? INBUFX skip "pad" byte, if any UNT 5 again, make 80 col. printers and HP82166 listeners LAD probably could be omitted if we skipped the pad byte after 4 sending CR, LF, but then we need make the drive talk again LAD should be room for saving many bytes 3338 OUTBIN so we can send carriage return& line feed GTO 06 LBL 15 UNL UNT E here, we restore normal loop addressing AAU AAD 0 BSIZEX AUTOIO CF33 END