How to patch binaries using HP-IPL/OS ===================================== Sometimes the binary code of existing programs needs to be changed, for reasons including but not limited to... Changing device I/O slot addresses Changing constants or text strings Disabling the running of subroutines or other code Adding new code then modifying something to call it Overlaying additional code (such as combining SIO and EXTASMB) Adding or modifying a run jump in locations 2/3 Most of these things require exact knowledge of the binary being patched, such as a source listing (or at least a good idea where things are), and obviously exact knowledge of what to add or change. I can only explain how to use the tools and utilities, the rest is up to you. When a utility is needed that are not part of the system, it has to be loaded into the system to make available. If the utility IPL file is on disk (XDIR) use "FILE.IPL" XLOAD to load the utility to make the command(s) available. If not on disk, obtain the IPL file, halt and attach ptr to the file, continue and enter LOAD to load it. Note.. IPL files must be in CRLF (dos) format, Linux's LF-only format won't work, convert the file using unix2dos (from the sysutils or tofrodos package) or use some other method to make sure each line ends with CRLF. The referenced utility IPL files are included in this file. Generally these require altutil.ipl and fcam.ipl, already loaded in the default boot system of the 7906 disk sim and in the "utility" build provided with the 31KW MSU BASIC package, but included here anyway for reference. Binary-related HP-IPL/OS commands --------------------------------- HP-IPL/OS uses a 31KW buffer called "alternate memory" (alt mem), any binary being patched must fit within locations 2 to 75777. Alt mem locations 0 and 1 are the same as the A and B registers. HP-IPL/OS can access alt mem locations above 75777 but that's the limit of the alt mem punch tool, and the "swapper" program (swaps main and alt mem then runs from 2) is programmed to swap 31KW from 2 to 76001, same range for all disk binaries, so practically addresses are limited to 2-75777, above that and the output ABS will have to manually be formed by doing PTHEADER from to AAOUT [from to AAOUT [etc]] PTZERO, and HP-IPL/OS cannot be used to directly execute the program. Here's some of the binary-related commands from a HP-IPL/OS DMS system with altutil.ipl, fcam.ipl and sham.ipl loaded... ZAM - clears alt memory ALTSAVE - copies HP-IPL/OS to alt mem and puts a swapper at 77000 in main mem ALTSAVE ZAM - clears alt mem with a swapper at 77000 in main mem ALTRUN - swaps and runs whatever is in halt, if nothing at 2/3 prompts for run 77000 RUN - blindly runs the swapper, there needs to be a jump at 2/3 HLT - just halts, useful for attaching detaching etc ABSLOAD - loads an ABS file from PTR into alt mem, attach first HLT ABSLOAD - halt to attach then loads ABS file (repeat for overlays) RUNABS - clears alt w/swapper, loads and runs ABS from PTR (prompts to halt) FCAM - finds code in alt mem and displays detected ranges location AGET PNUM - print the contents of a location in alt mem location value APUT - sets an alt mem location to specified value For example to add a startup jump in locs 2/3... 2 124003 APUT a JMP 3,I instruction 3 startadr APUT startadr=location to jump to when run from 2 from to ALTDUMP - displays a range of alt mem locations SHAM - prompts for alt mem address and displays a page of octal and ascii. enter ALL to dump all of alt mem, just enter to exit. Nice for finding text. UNSHAM - decodes a SHAM dump from PTR (attach first) back into alt mem, add a line containing just ~TERMINATE~ to the end of the file for automatic termination (or ignore the X overflow error). SHAM and UNSHAM can be used to store binary data in text form to restore or copy into other binaries. AM2ABS - scans alt memory and punches what it finds to PTP (prompts to halt) in ABS format. This provides padding (see fcam.ipl). To manually punch specific ranges, halt and attach PTP to a file, continue and do... PTHEADER - writes 8 zeroes to PTP for a header from to AAOUT - writes specified alt mem range to ABS attached to PTP repeat for all ranges to save, then do... PTZERO - writes 20 zeroes to PTP for a trailer Useful disk commands... XDIR - display disk directory "FILENAME" F2AM - copies a file to alt mem (binaries overwrite all 31KW) "FILENAME" 174000 AM2F - save 31KW binary from alt mem to a file "FILENAME" XLOAD - if text, loads (IPL file) into console, if binary saves HP-IPL/OS with a swapper at 77000 then loads and runs the binary from 2. "FILENAME" XSAVE - saves the current HP-IPL/OS system in memory to a file "FILENAME" XDEL - deletes a file, use before XSAVE or AM2F to existing file "FILENAME" "NEWNAME" XREN - renames a file "FILENAME" XSHOW - displays a file "FILENAME" ABS2F - copy an ABS file from PTR (attach first) to a disk file "FILENAME" F2ABS - copy a binary file from disk to PTP in ABS format, works the same as AM2ABS except copies file to alt mem first. "FILENAME" DECIMAL numberofbytes OCTAL MS2F - copy bytes as-is from PTR (attach first) to a disk file (numberofbytes=size shown by dir or ls -la) "FILENAME" F2MS - copy a file as-is to PTP (attach first) Note... XLOAD, XSHOW, ABS2F, F2ABS, F2AM, MS2F and F2MS overwrite any binary that might be in alt mem, don't use unless that's what you want to do. DBOOT - reboots disk - does NOT clear alt mem Remember to specify "@ FILE" when referring to binaries on the menu, as in "@ CHESS" F2AM to copy the chess binary on disk to alt mem. A simple example - add a SIO driver to EXTASMB and add a jump to locs 2/3 to location 100 to permit running the assembler from a HP-IPL/OS disk file or just make it easier to use by not having to separately load the driver. ZAM control-E to halt and attach ptr to a configured SIO.ABS (see SIOUTIL.IPL) c to continue ABSLOAD wnen done loading halt and attach ptr to extasmb.abs and continue ABSLOAD when done loading... 2 124003 APUT 3 100 APUT To punch to an ABS file enter: AM2ABS press Y to save, Y to halt, attach ptp outputfile.abs, continue when done saving continue again To save to a disk file enter: "EXTASMB" 174000 AM2F before using from disk, halt and attach ptr to source file, attach ptp to the output file, continue and "EXTASMB" XLOAD When it halts, attach ptr to the same source file again and continue. At the final halt, either attach ptr/ptp to more files and run 2 or 100 or run 77000 to return to HP-IPL/OS. The assembler is fairly easy to operate from a disk file and makes a good example of how to combine multiple ABS files, patch as needed and save to a single binary. It is possible to operate all of the BCS tools from disk files (see siobcs.ipl in hpiplos_main.zip) but the MKBCS utility (mkbcs.ipl) is much easier to use for complex multi-part EXTASMB/ALGOL/FORTRAN projects and requires no importing, combining or modification of the tools other than configuring them to the desired I/O slot configuration. A similar technique can be used with the ABS output of BCS tools to reduce the file size and in the case of CHESS, save enough pad zeroes to permit loading and running without having to clear memory first. Do... ZAM halt, attach ptr to raw BCS ABS file, continue ABSLOAD when done loading... AM2ABS and do Y Y attach ptp newfile.abs, c then when done saving c again. Changing I/O Device Assignments ------------------------------- How to reassign I/O slots for HP-IPL/OS itself is explained elsewhere. In a nutshell enter CONFIG from the prompt, change to what's needed, and save (DGEN for the bootsystem) ["FILE" XDEL] "FILE" XSAVE for a build on disk, or attach ptp to ABS file and SYSALL to punch. Upon the next boot of the system the new configuration will be enacted. CONFIG can't change magtape slots, to do that magtape.ipl has to be edited and the build using it rebuilt. Officially anyway.. the BINPATCH utility described later may be of use for changing HP-IPL/OS slots not supported by CONFIG, haven't tried. Slot-patching MSU BASIC programs... To change I/O slots in 31KW MSU BASIC (with or without an embedded program), use the MSUPATCH utility, which is built into the 7906 disk sim's boot system. The boot system's menu could do it by running the program, BYE, select 7 to save, Y to run MSUPATCH, change slots, if saving back to disk give it a name or to punch it, just enter for the name prompt then press 9 to punch the file, pressing Y, Y, attach ptp outputfile.abs, c, c again at the next halt. MSUPATCH is probably already loaded in systems designed to support it such as the 7906 disk sim and the hposutil.abs utility build from msubasic.zip. The following is how to patch TREK and punch using prompt commands... "@ TREK" F2AM loads into alt mem MSUPATCH press 4 to configure slots enter the new CLK address enter the new TTY address just enter to exit the utility AM2ABS Y Y attach ptp file.abs c c Pretty easy.. but don't directly swap CLK and TTY (default 10 and 11) in one pass or the vectors get messed up. To make CLK=11 and TTY=10 do... MSUPATCH press 4 to configure slots enter (say) 12 for new CLK address enter 10 for new TTY address press 4 again enter 11 for new CLK address just enter to keep TTY address just enter to exit utility Similar procedures can be used with the hposutil.abs utility build included in the msubasic.zip package, essentially doing ZAM and ABSLOAD to load an ABS from PTR instead of loading a binary file from disk. Slot-patching a 16KW SIO driver... If a 16K SIO system, specifically the sio16k11.abs file, needs to be patched for different slots (not necessary but saves extra reconfig steps if the SIO tools have the same assignments as the BCS linker) then use the SIOPATCH command in the SIOUTIL.IPL file. "SIOUTIL.IPL" XLOAD to load it if already on disk, otherwise get and attach ptr sioutil.ipl then LOAD it. SIOPATCH reads a 16KW SIO ABS file from PTR and punches a reconfigured 16KW SIO ABS file to PTP, both files must be attached before running but it pauses at an entry prompt to provide an opportunity to halt and attach. If the input file isn't valid an error message is displayed otherwise it prompts for the TTY, PTR and PTP slot addresses. To use... control-E to halt attach ptr sio16k11.abs attach ptp newsio.abs c SIOPATCH press enter enter TTY slot enter PTR slot enter PTP slot [runs then says Done] control-E to halt detach ptp Slot-patching BCS binaries... The BCS games on the 7906 sim's disk only use TTY, but changing it isn't exactly easy. This "normally" requires preparing a new BCS linker/system, recompiling the sources and relinking the REL files to make a new ABS. The other option is to directly edit the binary. All I/O instructions and control words refering to slot 11 need to be changed to the new slot, while avoiding words that just happen to match the control word mask. The 31KW BCS driver used in the games resides from 74070 to 75777, two control words near the beginning of the range (equal to the TTY slot 11) have to change, plus all I/O instructions for slot 11. REVERSIX has a asm sub that directly accesses TTY slot 11, those instructions have to change too. Tricky stuff so I wrote a BINPATCH utility to assist. Manual input is still required to tell it what to do but it makes the process much easier than using SHAM APUT etc to manually patch the binary. To use BINPATCH copy the IPL code from the code section in this file into a text file and make sure it's in CRLF format (it's brand new and at the time of this writing isn't anywhere else but will probably end up in the 7906 disk sim, XDIR to see, if there "BINPATCH.IPL" XLOAD to load it otherwise...), halt and attach ptr binpatch.ipl (or name of the IPL), continue and LOAD. The utility requires that SHAM from sham.ipl already be loaded, provided on its menu for poking around to try to guess what ranges to patch and what should and should not be changed. The utility operates on whatever is in alt mem, so whatever needs to be slot-patched has to be loaded, for example "@ CHESS" F2AM to patch the CHESS game on the 7906 sim's disk, or attach an ABS file to PTR and use ZAM ABSLOAD to put it into alt mem. With the binary to patch in alt mem enter BINPATCH to run the utility, which displays a menu with options to run FCAM to display code extents (BCS driver code is in the highest extent but other code may also need patching), run SHAM to dump the binary and try to figure out what does what, and an option to patch I/O slot addresses. Press a key for the desired option, any other keypress exits the utility. The slot-patch option prompts for the existing slot (11 in the case of the games included with the 7906 disk sim), prompts for the new slot (whatever TTY etc needs to be changed to - note there is no error-checking for the device addresses, and if changing multiple devices the new slot must not be the same as any existing slot, make multiple passes if necessary), then enter the from and to addresses to patch. For simple things, just the extent containing the drivers, for things like CHESS or other things that might contain hard-coded device addresses in subroutines the entire binary can be specified by entering 2 for the from address and 75777 for the to address. Next it prompts if control words should be patched, for BCS press Y as there are two locations near the beginning of the driver extent containing the TTY slot, which must be changed to the new slot (no idea for PTR/PTP etc, only tested for patching the BCS games which only use TTY). Control words are data used for self-patching or DMA control words which may have bit 13 or 15 set. Next it asks to prompt for changes, generally press Y unless sure all matching values need changing. In the case of changing the TTY slot of BCS programs, only change the 2 control words that appear right after the start of the driver extent in high memory, do not change other control word matches that have nothing to do with I/O devices. Some experimentation may be necessary. Once patched, exit the utility and use AM2ABS to punch a new ABS file, for XDEL/AM2F to save the binary to a disk file (as in reconfiguring the entire simulation to use different slots). The following edited sim log shows using BINPATCH (loaded from disk where I made it using the FED editor) to change the TTY slot of the BCS games from 11 to 17, then punching the altered binaries to ABS files which were tested under sim and function properly. Sidetracks and mistakes have been removed. ----- begin sim session -------------------------------------------------- ? "BINPATCH.IPL" XLOAD Loading alt mem: **** ? "@ CHESS" F2AM Loading alt mem: ******************************** ? BINPATCH BINARY PATCH UTILITY 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): 1 FROM 000002 TO 024431 FROM 074070 TO 075777 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): 3 EXISTING I/O SLOT: 11 NEW I/O SLOT: 17 FROM ADDRESS: 74070 TO ADDRESS: 75777 PATCH CONTROL WORDS? (Y/N) Y PROMPT BEFORE CHANGING? (Y/N) Y MOVING IRQ VECTOR 074106 000011 CHANGE? (Y/N) Y --> 000017 074112 000011 CHANGE? (Y/N) Y --> 000017 075236 106711 CHANGE? (Y/N) Y --> 106717 075237 102111 CHANGE? (Y/N) Y --> 102117 075304 102311 CHANGE? (Y/N) Y --> 102317 075407 106611 CHANGE? (Y/N) Y --> 106617 075410 103711 CHANGE? (Y/N) Y --> 103717 075434 102511 CHANGE? (Y/N) Y --> 102517 075531 106611 CHANGE? (Y/N) Y --> 106617 075533 103711 CHANGE? (Y/N) Y --> 103717 075616 106711 CHANGE? (Y/N) Y --> 106717 075623 106711 CHANGE? (Y/N) Y --> 106717 075672 106611 CHANGE? (Y/N) Y --> 106617 075673 102611 CHANGE? (Y/N) Y --> 102617 075675 103711 CHANGE? (Y/N) Y --> 103717 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): ? AM2ABS Scanning alt mem... Detected extents: From 000002 to 024531 From 074000 to 075777 Save as ABS? Y Halt for attaching/detaching files? Y Attach PTP file.abs then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> attach ptp chess17.abs PTP: creating new file sim> c Saving... Done. Detach PTP then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> detach ptp sim> c ? "@ REVERSIX" F2AM Loading alt mem: ******************************** ? BINPATCH BINARY PATCH UTILITY 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): 3 EXISTING I/O SLOT: 11 NEW I/O SLOT: 17 FROM ADDRESS: 2 TO ADDRESS: 75777 PATCH CONTROL WORDS? (Y/N) Y PROMPT BEFORE CHANGING? (Y/N) Y MOVING IRQ VECTOR 000342 000011 CHANGE? (Y/N) N 012443 000011 CHANGE? (Y/N) N 012536 106711 CHANGE? (Y/N) Y --> 106717 012537 102111 CHANGE? (Y/N) Y --> 102117 012564 106611 CHANGE? (Y/N) Y --> 106617 012566 102611 CHANGE? (Y/N) Y --> 102617 012567 103711 CHANGE? (Y/N) Y --> 103717 012570 102311 CHANGE? (Y/N) Y --> 102317 074106 000011 CHANGE? (Y/N) Y --> 000017 074112 000011 CHANGE? (Y/N) Y --> 000017 075236 106711 CHANGE? (Y/N) Y --> 106717 075237 102111 CHANGE? (Y/N) Y --> 102117 075304 102311 CHANGE? (Y/N) Y --> 102317 075407 106611 CHANGE? (Y/N) Y --> 106617 075410 103711 CHANGE? (Y/N) Y --> 103717 075434 102511 CHANGE? (Y/N) Y --> 102517 075531 106611 CHANGE? (Y/N) Y --> 106617 075533 103711 CHANGE? (Y/N) Y --> 103717 075616 106711 CHANGE? (Y/N) Y --> 106717 075623 106711 CHANGE? (Y/N) Y --> 106717 075672 106611 CHANGE? (Y/N) Y --> 106617 075673 102611 CHANGE? (Y/N) Y --> 102617 075675 103711 CHANGE? (Y/N) Y --> 103717 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): ? AM2ABS Scanning alt mem... Detected extents: From 000002 to 002077 From 004000 to 016022 From 074000 to 075777 Save as ABS? Y Halt for attaching/detaching files? Y Attach PTP file.abs then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> attach ptp reversix17.abs PTP: creating new file sim> c Saving... Done. Detach PTP then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> detach ptp sim> c ? "@ 31-ODD" F2AM Loading alt mem: ******************************** ? BINPATCH BINARY PATCH UTILITY 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): 1 FROM 000002 TO 003646 FROM 074070 TO 075777 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): 3 EXISTING I/O SLOT: 11 NEW I/O SLOT: 17 FROM ADDRESS: 74070 TO ADDRESS: 75777 PATCH CONTROL WORDS? (Y/N) Y PROMPT BEFORE CHANGING? (Y/N) N MOVING IRQ VECTOR 074106 000011 --> 000017 074112 000011 --> 000017 075236 106711 --> 106717 075237 102111 --> 102117 075304 102311 --> 102317 075407 106611 --> 106617 075410 103711 --> 103717 075434 102511 --> 102517 075531 106611 --> 106617 075533 103711 --> 103717 075616 106711 --> 106717 075623 106711 --> 106717 075672 106611 --> 106617 075673 102611 --> 102617 075675 103711 --> 103717 1) RUN FCAM TO FIND CODE 2) RUN SHAM TO DUMP CODE 3) CHANGE DEVICE I/O SLOT PRESS 1-3 (ANY OTHER EXITS): ? AM2ABS Scanning alt mem... Detected extents: From 000002 to 003746 From 074000 to 075777 Save as ABS? Y Halt for attaching/detaching files? Y Attach PTP file.abs then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> attach ptp 31odd17.abs PTP: creating new file sim> c Saving... Done. Detach PTP then continue HALT instruction 102007, P: 42410 (JMP 321,I) sim> detach ptp sim> c ? ----- end sim session ---------------------------------------------------- IPL files for the utilities and (some of the) dependencies ========================================================== The following IPL files are provided in this section... altutil.ipl - various alt mem utilities, including loading/running ABS files fcam.ipl - more alt mem utilities for examining/modifying and punching ABS sham.ipl - SHAM (show alt mem) dumper and UNSHAM for restoring sioutil.ipl - contains SIOPATCH for changing the slots of sio16k11.abs msupatch.ipl - contains MSUPATCH for patching 31KW MSU BASIC binpatch.ipl - contains BINPATCH for slot-patching BCS and other binaries In addition to these, the following IPL files must already be loaded... extra.ipl - standard HP-IPL/OS extras dms.ipl - alt mem support for MX machines double.ipl - required by XDOS and possibly other things disk.ipl - low-level disk support 7900.ipl, 7906.ipl or ide.ipl - disk driver for disk being used xdos.ipl - XDOS, recommend 9/1/07 version or later with fixed XDEL command The disk-related files are optional, PTR/PTP work fine for loading and saving binaries to patch (the disk-related F2ABS in fcam.ipl won't load if no disk). ----- begin altutil.ipl -------------------------------------------------- ; alt mem utility words... 8/26/07 10/5/07 12/13/07 ; requires PRESET (v1.11 create.ipl) and dms.ipl ; ; ZAM - Zero Alternate Memory ; HLT - halts the computer for attaching, swapping, etc ; ALTRUN - Swaps and executes altmem from loc 2 ; RUNABS - Load and run an ABS attached to MS input (PTR) ; PTHEADER - Writes 8 zeros to MS output (PTP) (used by ALTABS) ; from to AAOUT - Writes alt mem to MS out in ABS format ; ALTABS - Saves alt mem to ABS file attached to MS out ; ALTDUMP - Dumps alt mem to terminal ; CLRHALT - Saves system to alt mem, halts with empty system ; ALTHALT - Swaps system with system in alt mem then halts ; ;----------------------------------------------------------------------- ; ; ZAM - zero alt mem, similar to the TDOS word but this ; version saves and restores MS vectors for usage from the prompt ; 10/5/07 added load code to delete if exists ; If using w/TDOS (unlikely..) rename its ZAM first ; "ZAM" $DEFADR ;push non-zero if exists ; OCTAL DEFINE ZAM MS_SAVE ;added because ZEROBLOCK redirects MS #0 ZEROBLOCK #0 37 +DO @BLK GET INDEX 2000 MUL DUP IFZ DROP 2 ENDIF 2000 C>ACOPY +LOOP MS_RESTORE ;added END ; DEFINE TEMP ;if dup detected prompt to delete IFZ ;if no dup "TEMP" $DEFADR 4 SUB #0 PUT ;delete self ELSE ;dup detected "Forgetting dup ZAM" $PRINT CRLF "ZAM" $DEFADR 4 SUB #0 PUT ;delete new dup ZAM ENDIF END TEMP ;do it, will delete self ; ;----------------------------------------------------------------------- ; ; HLT - halts with code 7 ; 10/5/07 - added load code to delete if exists ; "HLT" $DEFADR ;push non-zero if exists ; OCTAL CREATE HLT HLT 7 END ; DEFINE TEMP ;if dup detected prompt to delete IFZ ;if no dup "TEMP" $DEFADR 4 SUB #0 PUT ;delete self ELSE ;dup detected "Forgetting dup HLT" $PRINT CRLF "HLT" $DEFADR 4 SUB #0 PUT ;delete new dup HLT ENDIF END TEMP ;do it, will delete self ;----------------------------------------------------------------------- ; ; ALTRUN - execute program in alt memory 10/4/07 ; This code was in RUNABS but handy as a separate word ; ; If location 2 is defined, just runs it from 2. ; If papertape basic detected (loc 100/105=124201/002200), ; then adds a jump to 100 at 2/3 and a jump to 77000 at 76/77 ; to permit returning to HP-IPL/OS upon entering "BYE". ; Otherwise if not papertape basic and loc 2 undefined, prompts for RA. ; Uses locations 150/151 octal for temp use. ; OCTAL DEFINE ALTRUN 77000 GET 105734 SUB IFNZ "ALTSAVE not run " $PRINT ELSE PRESET ;disable TBG and interrupts 2 150 #1 A>CCOPY ;copy alt loc 2 to loc 150 150 GET IFZ ;if loc 2 not defined then... 100 150 6 A>CCOPY ;get locs 100-105 2 ;#matches needed 150 GET 124201 SUB IFZ DEC ENDIF 155 GET 002200 SUB IFZ DEC ENDIF IFZ ;if (unpatched) HP BASIC detected... "Patching HP BASIC RA/BYE" $PRINT CRLF 150 124003 PUT 151 100 PUT 150 2 2 C>ACOPY ;patch run address 150 77000 PUT 151 124076 PUT 150 76 2 C>ACOPY ;patch BYE exit to hpiplos 77000 RUN ;save HP-IPL/OS and execute basic ELSE ;prompt for run address... "Enter Run Address (0 to halt): " $PRINT $IN 40 $APPEND $VAL CRLF DUP IFNZ ;if not zero then... 150 124003 PUT 151 SWAP PUT 150 2 2 C>ACOPY ;set run address to whatever entered 77000 RUN ;execute it ELSE ;DROP ;save a word don't worry about dropping 0 150 102003 PUT ;a halt with code 3 150 2 #1 C>ACOPY ;copy to alt loc 2 77000 RUN ;execute halt ENDIF ENDIF ELSE ;loc 2 is already defined 77000 RUN ;just do it ENDIF ENDIF END ;----------------------------------------------------------------------- ; ; RUNABS - saves current system along with program at 77000 that ; swaps it back, loads and runs ABS file attached to PTR. ; Uses RUNALT to execute, see above. ; Uses loc 150 for temp use. ; Started 7/6/07 last mod 9/29/07 OCTAL DEFINE RUNABS ALTSAVE ;saves system (redundant), puts swap code at 77000 ZAM ;wipe out saved hpiplos copy, makes debugging easier.. "Halt for cable swap? " $PRINT CHRIN CRLF 131 SUB IFZ #1 ELSE #0 ENDIF 150 SWAP PUT ;set halt flag 150 GET IFNZ HLT ENDIF ABSLOAD ;loads ABS file into alt 150 GET IFNZ HLT ENDIF CRLF CRLF ;space past load indicator dots ALTRUN ;execute it END ;----------------------------------------------------------------------- ; ; ALTABS - copies alt mem to ABS file attached to PTP ; Presents a menu with save options, attach to PTP first. ; Uses locations 150-155. 9/29/07 ; from to AAOUT - modified version of ABSOUT that takes ; input from alt mem instead. Uses locations 152/153. 7/6/07 ; from to ALTDUMP - lists alt mem to terminal. 7/10/07 ; PTHEADER - writes 8 zero's to MS out (def.PTP). 7/11/07 ; OCTAL DEFINE PTHEADER #0 7 +DO #0 MSBOUT +LOOP END ; OCTAL DEFINE AAOUT #0 S>Z ;record counter on Z DUP S>Y ;copy end address to Y to check for last block #0 S>X ;checksum on X MS_SAVE ;added - save current MS pointers 152 351 GET PUT ;added - save current MS out pointer OVER MSUSER ;added - set MS to alt, starting from from 351 152 GET PUT ;added - put MS out back to ptr or whatever +DO ;for index = start address to end address Z>S DUP S>Z ;copy record counter to stack IFZ ;if zero then start of new block... Y>S DUP S>Y ;get end address INDEX ;get current address X>S DROP ;discard prev checksum DUP S>X ;copy address to checksum SUB INC ;sub/inc to get # words left DUP ;save to use in a bit 33 SUB ;subtract 33 oct to see if incomplete IF<0 ;if incomplete block leave #left on stack ELSE ;else DROP ; don't need #words left 33 ; instead do 33 octal words ENDIF Z>S DROP DUP S>Z ;copy record count to Z MSBOUT ;output record count to mass storage #0 MSBOUT ;write 0 pad byte INDEX MSWOUT ;write two byte starting address ENDIF MSWIN ;get word from MS in (from alt) DUP MSWOUT ;write to mass storage X>S ADD DUP S>X ;add data to checksum and duplicate Z>S DEC DUP S>Z ;decrement record counter IFZ ;if last word... MSWOUT ; write checksum ELSE DROP ;else discard it ENDIF +LOOP X>S DROP ;discard checksum Y>S DROP ;discard last address Z>S DROP ;discard record counter MS_RESTORE ;added - restore MS pointers END ; OCTAL DEFINE ALTABS CRLF "1) Save 31K ABS dump" $PRINT CRLF "2) Save HP BASIC to re-enter/run" $PRINT CRLF "3) Manually save range(s)" $PRINT CRLF "Attach PTP to file and enter selection: " $PRINT $IN 40 $APPEND $VAL CASE = 1 ;straight save "Saving alt mem from 2 to 75777..." $PRINT PTHEADER 2 75777 AAOUT PTZERO CRLF "Done" $PRINT CRLF = 2 ;save HPBASIC 100 150 6 A>CCOPY ;get a little to verify 2 ;#matches needed 150 GET 124201 SUB IFZ DEC ENDIF 155 GET 002200 SUB IFZ DEC ENDIF IFNZ "HP BASIC not detected" $PRINT CRLF ELSE 77 150 #1 A>CCOPY ;get loc 77 150 GET IFZ ;if BYE not patched "Patch BYE? " $PRINT $IN 40 $APPEND #0 $GET 131 SUB IFNZ $DROP ELSE "Address? (77000 for swap/exit, 0 to halt) " $PRINT $IN 40 $APPEND $VAL DUP IFZ ;if zero for halt 150 #0 PUT 151 102077 PUT ;halt for loc 77 ELSE 150 SWAP PUT 151 124076 PUT ;jump for 77/76 ENDIF 150 76 2 C>ACOPY ;patch BYE ENDIF ENDIF "Select..." $PRINT CRLF "1) Save just basic and drivers" $PRINT CRLF "2)" $PRINT "Save basic and program to " $DUP $PRINT "re-enter" $PRINT CRLF "3)" $PRINT $PRINT "auto-run" $PRINT CRLF "? " $PRINT $IN 40 $APPEND $VAL DUP CASE = 1 100 = 2 2050 = 3 5137 DEFAULT #0 ENDCASE DUP IFZ ;if invalid choice DROP DROP ;address and selection ELSE ;do it, stack=selection, address on top PTHEADER ;write leader 151 SWAP PUT 150 124003 PUT 150 2 2 C>ACOPY ;patch run address 2 ;first location SWAP ;get selection CASE = 1 110 DEFAULT 113 ENDCASE ;if just bas use 110 else 113 150 #1 A>CCOPY 150 GET ;get alt loc 110 or 113 "Saving " $PRINT OVER PNUM "to " $PRINT DUP PNUM AAOUT CRLF 111 150 #1 A>CCOPY 150 GET ;push 1st loc of drivers 154 GET 777 OR ;calculate last location (loc 104) "Saving " $PRINT OVER PNUM "to " $PRINT DUP PNUM AAOUT PTZERO CRLF "Done" $PRINT ENDIF ENDIF = 3 ;specified save "Run address (enter for no change): " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP ELSE 150 124003 PUT 151 SWAP PUT 150 2 2 C>ACOPY "(range must includes 2/3)" $PRINT CRLF ENDIF PTHEADER ;write leader zeros "Enter ranges, just enter when done..." $PRINT CRLF DO ;while ranges entered "Starting address: " $PRINT $IN 40 $APPEND $VAL DUP IFNZ "Ending address : " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP DROP #0 ELSE OVER OVER SUB IF<0 "Saving..." $PRINT AAOUT #1 CRLF ELSE "Invalid" $PRINT CRLF DROP DROP #1 ENDIF ENDIF ENDIF WHILE ;non-zero address entered PTZERO "Done" $PRINT ENDCASE END ; OCTAL DEFINE ALTDUMP 151 #1 PUT ;a flag to indicate 1st word +DO INDEX 7 AND IFZ CRLF INDEX PNUM ": " $PRINT 151 #0 PUT ELSE 151 GET IFNZ INDEX PNUM ": " $PRINT 151 #0 PUT ENDIF ENDIF INDEX 150 #1 A>CCOPY 150 GET PNUM +LOOP END ;----------------------------------------------------------------------- ; ; CLRHALT - saves HP-IPL/OS to alt mem, clears main mem and halts, ; useful for operating BCS utilities, asm/compilers etc, ; presents an (almost) empty machine to build in. ; ALTHALT - swaps alt mem and HP-IPL/OS and halts, useful for running ; binaries (loaded via ABSLOAD) from an address besides 2. ; ALTSAVE must have been previously run to place the swapper ; code into memory. ; Run from location 77000 to return to previous system. ; Note.. both of these overwrite location 2, make note of contents if ; necessary to restore (often 124003 to run from address in 3). ; New for ALTHALT - preserves original run link at 2/3 so pressing ; the run button executes. ; 8/25/07 9/30/07 OCTAL DEFINE CLRHALT "Run 77000 to return" $PRINT ALTSAVE ZAM 150 102003 PUT 150 2 #1 C>ACOPY PRESET 77000 RUN END ; OCTAL DEFINE ALTHALT 77000 GET 105734 SUB IFNZ "ALTSAVE not run " $PRINT ELSE 2 150 2 A>CCOPY 150 GET 124003 SUB IFZ ;if run address present 77075 102007 PUT ;a halt in loc 77075 77076 127077 PUT ;a jmp 77077,i in loc 77076 (fixed 12/13/07) 77077 151 GET PUT ;original run address in loc 77077 "Press Run to execute " $PRINT 151 GET PNUM CRLF 151 77075 PUT 151 3 #1 C>ACOPY ;patch run address to halt ELSE ;not a standard run address or zero "Loc.2/3 was " $PRINT 150 GET PNUM 151 GET PNUM CRLF 150 3 #1 C>ACOPY ;move loc 2 to loc 3 150 102003 PUT 150 2 #1 C>ACOPY ;halt in loc 2 ENDIF PRESET 77000 RUN ENDIF END ;----------------------------------------------------------------------- ; CONSOLE ----- end altutil.ipl ---------------------------------------------------- ----- begin fcam.ipl ----------------------------------------------------- ; ; More AltMem utilities... 9/15/07 9/29/07 ; _FLG _XFR _LNZ _CNT - variables used by these words ; _MCZ - variable containing max consecutive zeros for FCAM ; FCAM - find Code in Alt Mem ; address value APUT - puts value into altmem ; address AGET - pushes value from altmem ; ?MSOUT - prints current MS out redirection - default MS out = PTP ; _PAD - variable containing # of pad words for AM2ABS ; _CBD - variable containing code boundary for AM2ABS ; _TRA - variable containing transition address between pad/boundary ; AM2ABS - saves contents of altmem to ABS file attached to MS out ; F2ABS - wrapper for AM2ABS that loads file into altmem then runs AM2ABS ; ; AM2ABS/F2ABS requires AAOUT HLT from altutil.ipl ; ; ; FCAM - find code in alt mem (from 2 to 75777) ; this word outputs FROM xxxxxx TO yyyyyy [crlf] ; for every non-zero extent it finds with up to ; 1024 dec embedded consecutive zeros. The addresses ; of the first and last non-zero values are listed. ; Change contents of _MCZ to change max# consec.zeros. ; VARIABLE _FLG VARIABLE _XFR VARIABLE _LNZ VARIABLE _CNT VARIABLE _MCZ OCTAL _MCZ 2000 PUT ;set max # imbedded zeros to 1024 dec DEFINE FCAM 2 ;starting location _FLG #0 PUT ;flag, zero for in-between non-zero values ;_XFR used for transfer ;_LNZ used for last non-zero loc (to) ;_CNT used for count of consecutive zeros DO DUP _XFR #1 A>CCOPY ;get word _XFR GET IFNZ ;if word not zero _LNZ OVER PUT ;save address _CNT #0 PUT ;clear count _FLG GET IFZ ;if flag zero "FROM " $PRINT DUP PNUM _FLG #1 PUT ;set flag ENDIF ELSE ;word is zero _CNT GET _MCZ GET SUB IF<0 ;if less than max zeros _CNT DUP GET INC PUT ;increment count ELSE _FLG GET IFNZ ;if flag set "TO " $PRINT _LNZ GET PNUM CRLF _FLG #0 PUT ;reset flag ENDIF ENDIF ENDIF INC ;address DUP 76000 SUB IF<0 #0 ELSE #1 ENDIF UNTIL ;address reaches 76000 DROP ;address _FLG GET IFNZ ;if flag still set "TO 075777" $PRINT CRLF ENDIF END ; ; ?MSOUT - prints "PTP " if loc [351] = [345] ; otherwise prints "MS out [contents of 351] " ; OCTAL DEFINE ?MSOUT 351 GET 345 GET SUB IFZ "PTP " $PRINT ELSE "MS out " $PRINT 351 GET PNUM ENDIF END ; ; AM2ABS - saves alt mem to an ABS file attached to MS output ; using information returned by FCAM plus a little extra ; smarts to save some of the surrounding zeros in case ; they are necessary for proper operation. The rules are.. ; End addresses below 67000 increased by 100 octal ; End addresses >=67000 increased to nearest 100 octal boundary minus 1 ; Beginning addresses above 100 lowered to nearest 100 octal boundary ; ; Requires HLT FCAM, plus words from altutil.ipl ; Uses _XFR var, AAOUT uses locations 152/153 for temps ; _PAD var contains TO address pad amount (100 octal) ; _CBD var contains code boundary (power of 2 - 1 inverted, 177700 octal) ; _TRA var contains transition address between pad/boundary behavior ; ; Note... this amounts to guessing where the programmer stored variables, ; and is designed to work only with the cases I have encountered. This ; word is an attempt to automate the process to simplify documenting ; "how to save a HP-IPL/OS disk binary to an ABS file" without having ; to write page after page explaining the guesswork involved, but there ; may come a time where it's required to manually determine the save ; ranges and use tools like ALTABS or PTHEADER/AAOUT/PTZERO. On disk ; HP-IPL/OS avoids all this mess by clearing memory before loading or ; importing ABS files, and saves all 31KW to disk, zeros and all. ; VARIABLE _PAD VARIABLE _CBD VARIABLE _TRA OCTAL _PAD 100 PUT _CBD 177700 PUT _TRA 67000 PUT DEFINE AM2ABS MS_SAVE ;save current MS redirection CRLF "Scanning alt mem..." $PRINT #0 OUTBLOCK >MS FCAM CRLF ;run FCAM output to block 0, extra crlf <>CON ;restore normal console output CRLF "Detected extents:" $PRINT #0 INBLOCK ;redirect MS in to read back data 177777 ;push terminate value to stack DO ;loop through entries MS$IN ;get line $LEN IFZ ;if empty $DROP ;line #1 ;terminate loop ELSE ;line in the form of "FROM xxxxxx TO xxxxxx " 5 12 $SLICE $VAL ;push from address DUP _CBD GET NOT INC SUB IF<0 ELSE ;if >= code boundary _CBD GET AND ;lower to nearest boundary ENDIF 17 24 $SLICE $VAL ;push to address DUP _TRA GET SUB IF<0 ELSE ;if >= transition address _CBD GET AND _CBD GET NOT ADD ;raise to boundary minus 1 ELSE _PAD GET ADD ;just add pad amount ENDIF $DROP ;FROM/TO line CRLF "From " $PRINT OVER PNUM "to " $PRINT DUP PNUM #0 ;keep looping ENDIF UNTIL ;all extends found and processed MS_RESTORE ;restore previous MS redirections DUP 177777 SUB IFZ ;if nothing... CRLF "Nothing in alt to save. " $PRINT ELSE ;do it... CRLF "Save as ABS? " $PRINT CHRIN CRLF 131 SUB IFNZ ;if not confirmed... ;clean up stack... DO DROP DROP DUP 177777 SUB WHILE ELSE ;prompt to attach and save... "Halt for attaching/detaching files? " $PRINT CHRIN CRLF 131 SUB _FLG SWAP PUT ;if _FLG = 0 then halt _FLG GET IFZ "Attach " $PRINT ?MSOUT "file.abs then continue" $PRINT CRLF HLT ENDIF "Saving... " $PRINT PTHEADER ;write header DO AAOUT ;write segment DUP 177777 SUB WHILE ;still more segments PTZERO ;write trailer CRLF "Done. " $PRINT _FLG GET IFZ "Detach " $PRINT ?MSOUT "then continue" $PRINT CRLF HLT ENDIF ENDIF ENDIF DROP ;terminator END ; ; address value APUT - puts value into alt mem ; uses _XFR var ; OCTAL DEFINE APUT _XFR SWAP PUT _XFR SWAP #1 C>ACOPY END ; ; address AGET - gets value from alt mem and pushes to stack ; uses _XFR var ; OCTAL DEFINE AGET _XFR #1 A>CCOPY _XFR GET END ; ; "FILE" F2ABS - file wrapper for AM2ABS ; OCTAL DEFINE F2ABS F2AM ;load file into alt mem DirInfo GET 177777 SUB IFNZ ;if file loaded... 2 AGET 124003 SUB IFZ AM2ABS ;save it ELSE "Not a system binary" $PRINT ENDIF ENDIF END ; CONSOLE ----- end fcam.ipl ------------------------------------------------------- ----- begin sham.ipl ----------------------------------------------------- ; SHAM - SHOW ALTERNATE MEMORY 3/4/08 ; PROMPTS FOR ADDRESS, DUMPS 20 LINES IN OCTAL AND TEXT ; ENTER ALL TO DUMP EVERYTHING IN ALTERNATE MEMORY ; JUST ENTER TO EXIT ; USES LOCS 150,151 FOR TEMPS ; OCTAL DEFINE SHAM MS_SAVE ;SAVE MS VECTORS TO RESTORE ON EXIT 150 #0 PUT ;INTERACTIVE MODE, IF ALL ENTERED SET TO 1 ;151 USED FOR OFFSET IN ALL MODE DO 150 GET IFZ ;IF INTERACTIVE MODE CRLF "ADR: " $PRINT $IN $TRIM "ALL" $EQUAL IFNZ ;IF ALL ENTERED $DROP "0" ;START WITH ADDRESS 0 151 #0 PUT ;INIT OFFSET COUNTER 150 #1 PUT ;SET ALL FLAG ENDIF ELSE 151 GET 240 ADD ;PUSH NEXT ADDRESS TO DUMP 151 OVER PUT ;WRITE BACK TO COUNTER DUP CASE < 76000 ;"IF" LESS THAN MAX $STR ;TURN ADDRESS INTO STRING DEFAULT ;"ELSE" DROP "" ;DROP ADDRESS AND PUSH EMPTY STRING TO TERMINATE ENDCASE ;"ENDIF" ENDIF $LEN IFZ ;IF NOTHING ENTERED $DROP #1 ;DROP STRING, SAY EXIT ELSE #0 ;SAY DON'T EXIT $VAL DUP ;GET VALUE OF STRING, DUP FOR LATER @BLK GET 240 A>CCOPY ;COPY WORDS FROM ALT TO BLOCK 0 #1 OUTBLOCK >MS ;REDIRECT TEXT OUTPUT TO BLOCK 1 @BLK GET DUP 237 ADD DUMP ;DUMP 20 LINES OF MEMORY TO BLOCK 1 #0 23 +DO ;LOOP THROUGH 20 LINES INDEX 120 MUL INC INC SETOP ;SET OUTPUT PTR TO ADDRESS FIELD DUP $STR $HEAD DROP $PRINT ;OVERWRITE WITH REAL ADDRESS 10 ADD ;NEXT LINE TO CHANGE +LOOP DROP ;NEXT, DROP PTR WHEN DONE <>CON ;RESTORE CONSOLE TEXT ;DUMP BLOCK 1 TO AND INCLUDING OFFSET 1440 TO SCREEN 150 GET IFZ CRLF ENDIF ;CRLF IF INTERACTIVE MODE ;SKIP 1ST WORD, A CRLF ADDED BY DUMP @BLK GET 2001 ADD DUP 1437 ADD +DO INDEX GET PWRD +LOOP ENDIF UNTIL ;USER PRESSES JUST ENTER MS_RESTORE ;RESTORE MS VECTORS END ; ; UNSHAM - DECODES A SHAM DUMP 3/6/08 ; READS A SHAM DUMP FILE ATTACHED TO MS IN (PTR) AND PUTS IN ALT MEM ; ADD ~TERMINATE~ ON A LINE BY ITSELF AT THE END OF THE DUMP TO STOP, ; OR HALT, RUN 2 WHEN IT HANGS. NOT FOR ALTDUMP OUTPUT. ; OCTAL DEFINE UNSHAM ALTSAVE ZAM DO MS$IN $LEN 13 SUB IF<0 $DROP #1 ELSE "~TERMINATE~" $EQUAL IFNZ $DROP #0 ELSE 5 $GET 72 SUB IFNZ $DROP #1 ELSE ;IT'S A LINE TO DECODE 6 ;START PARSING STRING AT OFFSET 6 #0 4 $SLICE $VAL DUP PNUM 15 PCHR DUP 7 ADD +DO ;LOOP THROUGH ADDRESSES #1 INDEX SUB IF<0 ;IF NOT LOC 0 OR 1 (THEY'RE A AND B REG) DUP DUP 5 ADD $SLICE INDEX $VAL APUT ;WRITE TO ALT MEM ENDIF 7 ADD ;NEXT OCTAL DATA DUP DEC 40 SUB IFNZ INC ENDIF ;SKIP PDF JUNK (THOSE AREN'T SPACES!) +LOOP $DROP ;LEAVE STRING PTR ON STACK FOR WHILE ENDIF ENDIF ENDIF WHILE END ; CONSOLE ----- end sham.ipl ------------------------------------------------------- ----- begin sioutil.ipl -------------------------------------------------- ; This utility patches a prepared 16K SIO driver ; to use other slots, tested with sio16k11.abs ; last code change 7/10/07 OCTAL DEFINE SIOPATCH "Attach sio to PTR, new sio to PTP" $PRINT CRLF "Press enter when ready..." $PRINT $IN $DROP ZAM ABSLOAD CRLF 37135 150 #1 A>CCOPY 150 GET 35104 SUB IFNZ "Not an sio binary" $PRINT ELSE "TTY? " $PRINT $IN $VAL 151 SWAP PUT "PTR? " $PRINT $IN $VAL 152 SWAP PUT "PTP? " $PRINT $IN $VAL 153 SWAP PUT "Patching..." $PRINT 37440 37441 37442 37444 37553 37626 37633 37637 37640 37641 #1 12 +DO DUP 150 #1 A>CCOPY 150 GET 177700 AND 151 GET OR 150 SWAP PUT 150 SWAP #1 C>ACOPY +LOOP 37255 37256 37260 37365 #1 4 +DO DUP 150 #1 A>CCOPY 150 GET 177700 AND 152 GET OR 150 SWAP PUT 150 SWAP #1 C>ACOPY +LOOP 37177 37215 37220 37221 37222 #1 5 +DO DUP 150 #1 A>CCOPY 150 GET 177700 AND 153 GET OR 150 SWAP PUT 150 SWAP #1 C>ACOPY +LOOP CRLF "Writing new sio binary..." $PRINT PTZERO 4 5 AAOUT 101 106 AAOUT 37134 37677 AAOUT PTZERO CRLF "Done" $PRINT ENDIF END CONSOLE ----- end sioutil.ipl ---------------------------------------------------- ----- begin msupatch.ipl ------------------------------------------------- ; MSUPATCH - PATCHER FOR SINGLE-USER 31KW MSU BASIC ; CREATED 3/2/08 LAST MOD 3/13/08 ; BUGS... CAN ONLY EDIT INFO LINE(S) IF NEW TEXT IS SHORTER OR ; NOT MUCH LONGER, OTHERWISE MAYHEM RESULTS. WHEN RUNNING PREP ; SPACE-PAD INITIAL INFO LINE(S) TO END OF TERMINAL LINE, AND ; DON'T ENTER A LINE LONGER THAN THE INITIAL PADDING. ; ; NOTE! BEFORE PATCHING ANYTHING THE STOCK SYSTEM MUST ; HAVE BEEN LOGGED ONTO AT LEAST ONCE TO INITIALIZE ITSELF, ; THE PATCHES BYPASS THIS SO THOSE DATA STRUCTURES MUST ALREADY ; BE IN PLACE. SET T/D, LOG ON, BREAK SIM AT THE READY PROMPT ; RUN 77000 TO GO BACK TO HP-IPL/OS THEN RUN THIS UTILITY. ; ; THE PATCHES MAKE IT BOOT STRAIGHT TO THE READY PROMPT WITHOUT ; CLEARING MEMORY, AND CAUSE BYE TO RETURN TO HP-IPL/OS IF PRESENT ; OR RUN THE STOCK LOGOUT IF NOT. ; ; ALSO PERMITS FLIPPING THE BACKSPACE CHAR BETWEEN _ AND ASCII-8 ; CHANGING THE INFORMATION LINES (BUT NOT THE NUMBER OF LINES) ; AND RECONFIGURING THE CLK AND TTY SLOTS. CARD/TAPE NOT SUPPORTED. ; ; THIS IS ONLY FOR A 31KW SYSTEM (PREP ABS VERSION 3/1/08) SET UP FOR ; A SINGLE-USER, LOGGING DISABLED, NO CARD/TAPE SUPPORT. THE FOLLOWING ; LOCATIONS MUST BE TRUE: 2012=60114 73662=10443 67337=60373 75632=63647 ; ; INSTRUCTIONS... ASSUMING "UTIL" BUILD (DISK INSTR. IN PAR) ; BOOT THE UTIL BUILD, HALT, ATTACH THIS FILE TO PTR, CONTINUE ; THEN ENTER LOAD TO LOAD IT. ; IF PATCHING THE RAW OUTPUT FROM THE CONFIGURATOR... ; ENTER RUNABS, PRESS Y TO HALT, ATTACH PTR TO RAW ABS, CONTINUE ; SET DATE/TIME, LOG ON, AT READY PROMPT HALT, RUN 77000 ; IF REPATCHING AN ALREADY-PATCHED VERSION... ; ENTER HLT, ATTACH PTR TO EXISTING PATCHED ABS, CONTINUE, ENTER ABSLOAD ; (TO REPATCH DISK VERSION ENTER "FILENAME" F2AM) ; WITH LOGGED-ON 31KW CMU BASIC IN ALT-MEM VIA ONE OF THE ABOVE, ; ENTER CMUPATCH TO RUN THE PATCH UTILITY. ; WHEN DONE PATCHING, ENTER AM2ABS, PRESS Y TO SAVE, Y TO HALT, ; ATTACH PTP TO NEW OUTPUT ABS, CONTINUE, WHEN IT HALTS DETACH PTP ; AND CONTINUE. SHOULD BE DONE, TEST THE RESULTS. ; (TO SAVE PATCHED BASIC TO DISK ENTER "NEWNAME" 174000 AM2F) ; OCTAL DEFINE MSUPATCH #1 ;VALID 2012 AGET 60114 SUB IFNZ DROP #0 ENDIF 73662 AGET 10443 SUB IFNZ DROP #0 ENDIF 67337 AGET 60373 SUB IFNZ DROP #0 ENDIF 75632 AGET 63647 SUB IFNZ DROP #0 ENDIF IFZ "INCORRECT VERSION" $PRINT ELSE "SINGLE USER 31KW MSU BASIC PATCH UTILITY" $PRINT CRLF DO #0 ;EXIT FLAG "[1] APPLY PATCHES" $PRINT CRLF "[2] CHANGE BACKSPACE" $PRINT CRLF "[3] CHANGE INFO LINES" $PRINT CRLF "[4] CONFIGURE SLOTS" $PRINT CRLF "PRESS KEY OR ANY OTHER TO EXIT: " $PRINT CHRIN CRLF CASE = 61 ;1 - APPLY PATCHES "APPLYING PATCHES..." $PRINT CRLF 67562 73205 APUT ;BYPASS LOG-ON PROMPTS 100 2021 APUT ;BYBASS BASIC INIT ; PATCH TO MAKE BYE EXIT TO HP-IPL/OS OR LOGOUT... 75700 163705 APUT ;LDA 75705,I GET 1ST SWAPPER INSTRUCTION 75701 53706 APUT ;CPA 75706 IS IT HP-IPL/OS? 75702 127705 APUT ;JMP 75705,I YES - RUN THE SWAPPER 75703 127704 APUT ;JMP 75704,I NO - RUN THE STOCK LOGOUT 75704 73313 APUT ;73313 - ADDRESS OF LOGOUT CODE 75705 77000 APUT ;LOCATION OF SWAPPER = 77000 75706 105734 APUT ;1ST SWAPPER INSTRUCTION = 105734 101 75700 APUT ;SET BYE VECTOR TO NEW CODE ; NEW STARTUP PATCH (WAS JUST 3=67314 BUT THAT DIDN'T CLC 0) 75720 106700 APUT ;CLC 0 75721 127722 APUT ;JMP 75722,I 75722 67314 APUT ;67314 - START PAST TASK INIT 3 75720 APUT ;SET START TO NEW STARTUP CODE = 62 ;2 - CHANGE BACKSPACE 75530 AGET 137 SUB IFZ ;IF STOCK "CHANGING TO ASCII-8 BACKSPACE" $PRINT CRLF 75530 10 APUT ELSE ;IF NOT STOCK "CHANGING TO UNDERLINE BACKSPACE" $PRINT CRLF 75530 137 APUT ENDIF = 63 ;3 - CHANGE INFO LINE(S) #0 73070 AGET 2CPL DEC +DO ;LOOP THRU INFO LINES 73071 AGET INDEX ADD AGET ;PUSH START OF TEXT #0 73072 AGET INDEX ADD AGET DEC +DO ;LOOP FOR ALL CHARS DUP INDEX 2 DIV ADD AGET ;GET WORD INDEX #1 AND IFZ ;IF CHAR COUNT EVEN 400 DIV PCHR ;PRINT HIGH CHAR ELSE ;IF ODD 377 AND PCHR ;PRINT LOW CHAR ENDIF +LOOP CRLF ;FINISH PRINTING LINE DROP ;MEM POINTER +LOOP ;PRINT ALL LINES "CHANGE? [Y/ANY] " $PRINT CHRIN CRLF 131 SUB IFZ ;IF Y PRESSED "ENTER NEW LINE" $PRINT 73070 AGET 2CPL DEC IFNZ "S" $PRINT ENDIF "..." $PRINT CRLF #0 73070 AGET 2CPL DEC +DO ;LOOP THRU INFO LINES $IN $LEN IFZ $DROP " " ENDIF ;INPUT LINE, AT LEAST ONE SPACE DO ;trim too-long lines 3/13/08 $LEN CASE > 110 $TAIL DROP #0 DEFAULT #1 ENDCASE UNTIL ;72 chars or less 73072 AGET INDEX ADD $LEN APUT ;UPDATE LENGTH 73071 AGET INDEX ADD AGET ;PUSH START OF LINE #0 $LEN INC 2 DIV DEC +DO ;LOOP FOR EACH WORD DUP INDEX ADD $ADR INDEX ADD GET APUT ;WRITE WORD +LOOP ;NEXT WORD DROP $DROP ;MEM PTR AND STRING +LOOP ;NEXT LINE ENDIF = 64 ;4 - CHANGE SLOTS ;USES LOC 150 TO STORE PATCH # 67340 AGET $STR $TAIL $TAIL $DROP ;PUSH CLK SLOT DIGITS "CLK SLOT (" $PRINT PCHR PCHR "): " $PRINT $IN 40 $APPEND $VAL DUP CASE < 10 DROP > 25 DROP DEFAULT ;IF BETWEEN 10 AND 25 150 SWAP PUT ;SAVE SLOT# "PATCHING CLK TO SLOT " $PRINT 150 GET PNUM CRLF 67340 AGET 77 AND #0 APUT ;ZERO EXISTING CLK VECTOR 150 GET 114030 APUT ;SET NEW INT VECTOR #0 ;TERMINATE VALUE, PATCH LIST... 67340 67342 75643 75631 73547 DO DUP IFNZ ;IF NOT THE TERMINATOR DUP AGET 170000 AND 100000 SUB IFZ ;IF IT LOOKS LIKE I/O DUP DUP AGET 177700 AND 150 GET OR APUT ;PATCH IT ENDIF ENDIF WHILE ;NON-ZERO ADDRESS ENDCASE 73661 AGET $STR $TAIL $TAIL $DROP ;PUSH TTY SLOT DIGITS "TTY SLOT (" $PRINT PCHR PCHR "): " $PRINT $IN 40 $APPEND $VAL DUP CASE < 10 DROP > 25 DROP DEFAULT 150 SWAP PUT "PATCHING TTY TO SLOT " $PRINT 150 GET PNUM CRLF 73661 AGET 77 AND #0 APUT ;ZERO EXISTING TTY VECTOR 150 GET 114031 APUT ;SET NEW INT VECTOR #0 ;TERMINATE VALUE, TTY PATCH LIST... 73661 73665 73666 73671 73672 73673 74647 67316 67317 67332 67333 75612 75635 67351 67457 67460 67461 67466 67467 67470 67472 67314 DO DUP IFNZ DUP AGET 170000 AND 100000 SUB IFZ DUP DUP AGET 177700 AND 150 GET OR APUT ENDIF ENDIF WHILE ENDCASE DEFAULT DROP #1 ;EXIT IF ANY OTHER KEY PRESSED ENDCASE UNTIL ;EXIT ENDIF END ; CONSOLE ----- end msupatch.ipl --------------------------------------------------- ----- begin binpatch.ipl ------------------------------------------------- ; BINPATCH - ASSISTS IN ALTERING DEVICE I/O ASSIGNMENTS 3/23/08 ; REQUIRES ALTUTIL.IPL FCAM.IPL SHAM OCTAL DEFINE BINPATCH "BINARY PATCH UTILITY" $PRINT CRLF DO ;UNTIL QUIT #0 ;EXIT FLAG, CHANGES TO NON-ZERO TO EXIT CRLF "1) RUN FCAM TO FIND CODE" $PRINT CRLF "2) RUN SHAM TO DUMP CODE" $PRINT CRLF "3) CHANGE DEVICE I/O SLOT" $PRINT CRLF "PRESS 1-3 (ANY OTHER EXITS): " $PRINT CHRIN CRLF CASE = 61 FCAM = 62 SHAM = 63 ;CHANGE I/O SLOT... ;USES ZP MEM 150 TO 155 "EXISTING I/O SLOT: " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP ELSE 150 SWAP PUT ;STORE OLD SLOT IN LOC 150 "NEW I/O SLOT: " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP ELSE 151 SWAP PUT ;STORE NEW SLOT IN LOC 151 "FROM ADDRESS: " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP ELSE 152 SWAP PUT ;STORE FROM IN 152 "TO ADDRESS: " $PRINT $IN 40 $APPEND $VAL DUP IFZ DROP ELSE 153 SWAP PUT ;STORE TO IN 153 ;MAKE SURE TO >= FROM 153 GET 152 GET SUB IF<0 "INVALID RANGE" $PRINT CRLF ELSE "PATCH CONTROL WORDS? (Y/N) " $PRINT CHRIN CRLF 131 SUB 154 SWAP PUT ;154=0 TO PATCH CW "PROMPT BEFORE CHANGING? (Y/N) " $PRINT CHRIN CRLF 131 SUB 155 SWAP PUT ;155=0 TO PROMPT 150 GET AGET DUP IFZ DROP ELSE "MOVING IRQ VECTOR" $PRINT CRLF 150 GET #0 APUT 151 GET SWAP APUT ENDIF 152 GET 153 GET +DO ;LOOP THRU SPECIFIED RANGE ;INSTRUCTION MUST MATCH 1000X1XYYYZZZZZZ WHERE ;X=DON'T CARE Y=ANYTHING BUT 0 Z=OLDSLOT INDEX AGET 172000 AND 102000 SUB IFZ ;=1000X1 INDEX AGET 700 AND IFNZ ;YYY NOT 0 INDEX AGET 77 AND 150 GET SUB IFZ ;ZZZZZZ=OLDSLOT INDEX PNUM INDEX AGET PNUM 155 GET IFZ " CHANGE? (Y/N) " $PRINT CHRIN ELSE 131 ENDIF 131 SUB IFZ " --> " $PRINT INDEX AGET 177700 AND 151 GET OR DUP PNUM INDEX SWAP APUT ENDIF CRLF ENDIF ENDIF ENDIF 154 GET IFZ ;IF PATCH CONTROL SELECTED ;INSTR MUST BE X0X0000000ZZZZZZ INDEX AGET 57700 AND IFZ ;CONTROL WORD MATCH INDEX AGET 77 AND 150 GET SUB IFZ ;=OLDSLOT INDEX PNUM INDEX AGET PNUM 155 GET IFZ " CHANGE? (Y/N) " $PRINT CHRIN ELSE 131 ENDIF 131 SUB IFZ " --> " $PRINT INDEX AGET 177700 AND 151 GET OR DUP PNUM INDEX SWAP APUT ENDIF CRLF ENDIF ENDIF ENDIF +LOOP ENDIF ENDIF ENDIF ENDIF ENDIF DEFAULT DROP #1 ENDCASE UNTIL END CONSOLE ----- end binpatch.ipl --------------------------------------------------- Whew! lot of code, but whatever it takes. All those "whatevers" were done at different times to solve whatever problems ranging from being able to load and run an ABS on a real HP mini without having to reload HP-IPL/OS afterwards (the cable swap prompts were literally so I could swap a single serial cable between a PTR emulator and the console), to using under simulation to take apart and put together ABS binaries produced by other systems (the focus of this doc). Only recently did I start programming things to ask to halt, mainly as a convenience under sim. The older things like LOAD ABSLOAD etc do not bother real hardware users who either don't need to halt, or if a halt is needed can do as I do... HLT LOAD. So there's great varience in the user interface of different things. For occasional use utilities such as BINPATCH or SIOPATCH can be loaded as needed, then DBOOT used to return to the boot system (or otherwise restart or use FORGET to remove what was loaded). To avoid having to find and load various patch tools, make a custom build and save it to disk then load it when needed for binary manipulations. Assuming the 7906 disk sim's boot system, enter FORGET _DM to remove the menu, but keep altutil, fcam, msupatch and sham packages. Or enter RENAME !DMI .DMI to disable autostarting of the menu but keep it in memory to run by entering DMENU. The starting build can be trimmed back as far as needed, FORGET MSUPATCH, FORGET SHAM etc. FORGET HLT will remove all of the altmem utilities (FORGET the 1st word or variable in the package's IPL file to completely remove it). Next load in the packages that are needed, if on disk "FILENAME.IPL" XLOAD, or halt, attach ptr to the IPL file, continue and LOAD. Do WORDS after each load and make sure the load didn't overflow the dictionary (lists [addresses] rather than names), and there's enough memory left for further loads. Do 2 ALLOCATE to gain more memory if needed unless an app actually needs more than 2 blocks. When all the utilities that might be needed have been loaded and WORDS looks OK then the system can be saved to disk, enter: "@ UTILITIES" XSAVE or something similar, adjust the name as needed. If that name, then the boot menu will list as UTILITIES, run when needed, DBOOT when done. Many of the functions that have accumulated probably aren't useful for others doing specific things, so it's perfectly OK to copy out only the individual words (and words and variables used by those words) into a single custom IPL file, put a CONSOLE at the end of it and load only what's needed, freeing up memory that can be used for loading other things. It takes a bit of practice but compared to say C this is easy stuff.. to see what a program depends on, read it. Everything that's not a number or a string has to be a word already in the dictionary. That's why they're called words. Variables and constants are words to, and often variables are set using immediate commands in the IPL (words numbers and strings not between DEFINE/END pairs). When copying code to a new IPL, all that has to go too if it affects something being used. Some words (like HLT and ZAM) appear in multiple packages so to automatically delete dups before the word is a "NAME" $DEFADR to push the word's address to the stack if it exists, or 0 if it doesn't. Then it defines/creates the word, and afterwards defines a TEMP word and runs it, the code in the temp word checks the stack and if it was already defined, deletes the word that was defined. This is necessary because IPL files have to load as a stream, there can be no branching while loading so tricks have to be used. Best to keep these self-deleting words as one chunk of code, but other than wasting memory there is no problem with having duplicate words.. old code continues to use the old version, new code uses the new version. Sometimes words are duplicated intentionally to add additional functionality to an existing word. Actually writing IPL code to do new things is probably a steep hill to climb if you've never programmed using stacks before, but provides new abilities I can't imagine (literally... I have only a foggy idea what sorts of things an HP mini hacker might need to hack, and only provide code for the kinds of things I do or consider a likely need). Writing IPL can be an exercise in frustration (one stack value out of place and it all comes tumbling down) and the simplicity of HP-IPL/OS doesn't help... the threaded interpreter simply fetches addresses from whatever's running, looks there to get an address of some machine code, saves where its at and runs the code, repeating forever. There is no easy way for code to know if there's not enough ENDIF's etc, those are just words like all the other ones. This effectively means if you mismatch IFx/ENDIF CASE/ENDCASE DO/UNTIL or WHILE, +DO/+LOOP etc the results are unpredictable and unintended code execution may occur (if OCTAPUS pops up you probably forgot an ENDIF). It's not like it scans a text file and counts pairs like a compiler, and if I tried to check for every error a programmer might make there'd be no memory left for disk operating systems and ABS patching utilities. HP-IPL/OS code must be correct or it'll crash, simple as that. But it can do stuff no other HP21xx programming system can, with the exception of assembler (which also has to be correct or it crashes). Of course there's a lot of stuff it can't do, but it can run binaries so it doesn't have to. While floating-point can be done in HP-IPL/OS, if you need matrixes and trig functions, use MSU BASIC to write the app. This doc created 3/24/08, last modified 3/25/08 Terry Newton (wtnewton@infionline.net)