"Loading XDOS Version 1.27" $PRINT CRLF ;created 4/23/05 last mod 9/29/07 ;requires dms.ipl, disk.ipl, [driver].ipl ;requires PRESET, added to HP-IPL/OS' 1.11 create.ipl ; ;Volume functions... ;WKBUF constant defining work buffer ;XCV variable defining current volume number for XDOS ;$VOL pushes string containing current volume name ;MKVOL makes a new volume.. "vol" MKVOL ;FindEntry subroutine that finds an entry in vol/dir table ;16Pad subroutine that pads string to 16 characters ;ChkSFS subroutine that detects buffered SFS dirs or modified files ;DELVOL deletes a volume.. "vol" DELVOL (confirms) ;RENVOL renames a volume.. "vol" "newname" RENVOL ;CHVOL changes XCV to new current volume.. "vol" CHVOL ;LSVOL lists volume index ;File functions... (operate on current volume defined by XCV) ;VolInfo 5 word array containing current volume specs (after GetVol) ;DirInfo 6 word array containing directory specs (after GetFile) ;GetVol reads volume index and updates VolInfo ;GetFile finds existing file and updates DirInfo, returns start block ;PutFile creates new dir entry from DirInfo, returns start block ;ZAM zero alternate memory, useful for importing/creating files ;AM2F copy alt memory to a new file.. "file" bytes AM2F ;F2AM copy file to alt memory.. "file" F2AM ;XSAVE save current system to a new file (size 62KB).. "file" XSAVE ;XLOAD load an ipl or system binary file.. "file" XLOAD ;XSHOW show file on screen, if LA is not 0 (text) then hexdumps file ;XDIR lists current volume name and the files it contains ;XREN renames a file.. "file" "newname" XREN ;XDEL deletes a file.. "file" XDEL (confirms) ; ;Disk layout specs... (octal numbers, blocks are 1KW) ;Blocks 0 to 5 bootext code for 7900 etc drives ;Block 6 volume index ;Block 7 directory for volume 0 ;Blocks 10-46 31K system binary for booting ;Blocks 47-106 vol 0 file 0 ;.... ;Blocks 4007-4046 vol 0 file 63 dec ;Block 4047 directory for volume 1 ;Blocks 4050-10047 next 64 dec files ;Block 10050 directory for volume 2 ;Blocks 10051-14050 next 64 dec files ;.... etc ;The only fixed locations are the volume index in block 6 ;and the boot binary in blocks 10-46, everything else is ;defined by the numbers in block 6 as initialized. The above ;layout is recommended for large disks and created by XINIT. ;Smaller disks can be formatted for less files per directory ;to permit use of volumes, XI79 formats a 7900 like... ;Blocks 0-46 same as above ;Blocks 47-106 vol 0 file 0 ;... ;Blocks 607-646 vol 0 file 11 dec ;Blocks 647-1446 vol 1 file space ;Blocks 1447-2246 vol 2 file space ;Block 2247 vol 1 directory ;Block 2250 vol 2 directory ; ;The volume index table contains 64 entries of 16 words each... ;word offset 0-7 contain a 16-character space-padded volume name ;word offset 13 octal contains Size of Directory Block (how many files max) ;word offset 14 octal contains Directory Block Pointer Low ;word offset 15 octal contains Directory Block Pointer High ;word offset 16 octal contains File Space Pointer Low ;word offset 17 octal contains File Space Pointer High ; ;A volume entry name that begins with 0 marks the end of useable ;disk space. Unused or deleted entries have spaces in at least ;the first two characters of the volume name. ; ;Each directory block has 64 entries of 16 words each... ;word offset 0-7 contain a 16-character space-padded file name ;word offset 13 octal contains the binary file load address ;word offset 14 octal contains the binary file run address ;word offset 15 octal contains the Last Access Pointer ;word offset 16 octal contains the File Length in bytes ;word offset 17 octal contains the File Control Word (not specified yet) ; ;Unused or deleted directory entries can be zero or spaces, ;to permit starting with an all-zero directory block. ; ;--------------------------------------- "Constant WKBUF, Variable XCV" $PRINT CRLF OCTAL CONSTANT WKBUF 66000 VARIABLE XCV XCV #0 PUT ;start in volume 0 ;--------------------------------------- "Loading 16Pad" $PRINT CRLF DEFINE 16Pad 20 40 $CREATE $CAT #0 17 $SLICE $SWAP $DROP ;space-pad string END ;--------------------------------------- "Loading ChkSFS" $PRINT CRLF ; pushes 1 if SFS is buffering directories or modified files ; else pushes 0 if safe to do direct manipulations ; (except to the open file of course, just don't do it) DEFINE ChkSFS #0 ;push a 0 200 203 +DO #1 INDEX GET SUB IF<0 ;if any CWA numbers are >=2 DROP #1 ;make the 0 a 1 ENDIF +LOOP DUP IFNZ "SFS running" $PRINT ENDIF END ;--------------------------------------- "Loading MKVOL" $PRINT CRLF ; MKVOL - finds the first vol index entry that begins ; with spaces, then names it and creates an empty directory ; usage: "name" MKVOL DEFINE MKVOL ChkSFS IFNZ ;if SFS running $DROP ;don't run ELSE 16Pad ;space-pad string #0 6 SBLA WKBUF R-1K ;read in volume index table Z ;put last valid address onto Z stack 16Pad ;space-pad string $ADR ;push address of string SWAP ;swap with address ptr DO ;until match is found or no more entries to look at DUP ;pointer for test Z>S DUP S>Z SWAP SUB IF<0 ;if past the end DROP ;mem ptr DROP ;address of string $DROP ;name string #0 ;return 0 for failure #1 ;terminate loop ELSE ;see if first two chars match.. (str adr, mem ptr on stack) OVER GET ;push 1st word of string OVER GET ;push 1st word of mem entry SUB IFNZ ;if they don't match 20 ADD ;next entry #0 ;keep looking ELSE ;check the remaining 7 words.. #1 S>Y ;flag on Y, any mismatch clears #1 7 +DO ;loop 7 times OVER INDEX ADD GET ;push word from string OVER INDEX ADD GET ;push word from mem SUB IFNZ Y>S DROP #0 S>Y ENDIF ;clear flag if not equal +LOOP Y>S ;get flag IFZ ;if no match.. 20 ADD #0 ;next entry ELSE ;found it! SWAP DROP ;string address $DROP ;string #1 ;stop looping ;leaving entry address on stack ENDIF ENDIF ENDIF UNTIL Z>S DROP ;clean up Z stack END ;--------------------------------------- "Loading DELVOL" $PRINT CRLF ; "name" DELVOL - removes volume entry DEFINE DELVOL ChkSFS IFNZ ;if SFS running $DROP ;don't run ELSE "Delete volume " $PRINT $DUP $PRINT "? (Y/N) " $PRINT CHRIN "Y" $HEAD $DROP SUB CRLF IFNZ $DROP ELSE #0 6 SBLA WKBUF R-1K ;read volume index X ;push to X stack +LOOP DROP ;mem ptr 20 S>X ;string is 16 bytes long 11 S>X ;9 words including byte count END ;--------------------------------------- "Loading ZAM" $PRINT CRLF ;ZAM - Zero Alternate Memory DEFINE ZAM WKBUF DUP 1777 ADD +DO INDEX #0 PUT +LOOP ;clear work buffer #0 37 +DO ;32 blocks WKBUF ;source INDEX 2000 MUL ;dest DUP IFZ DROP 2 ENDIF ;if block 0 start at loc 2 2000 C>ACOPY ;copy 2000 octal words to alt +LOOP END ;--------------------------------------- "Loading AM2F" $PRINT CRLF ;"filename" bytes AM2F - save alt mem to file DEFINE AM2F ChkSFS IFNZ ;if SFS running $DROP DROP ;don't run ELSE "Saving alt " $PRINT ;determine type by context, if loc 2 contains 124003 ;then assume alt contains a system binary, otherwise ;set load/run addresses to zero, file length on stack 2 DirInfo 1 A>CCOPY ;get location 2 from alt mem DirInfo GET 124003 SUB IFZ 2 ELSE #0 ENDIF DirInfo OVER PUT ;load address = 2 if bin, or 0 DirInfo INC SWAP PUT ;run address = 2 if bin, or 0 DirInfo INC INC #0 PUT ;last access = 0 DirInfo 3 ADD OVER PUT ;length = specified DirInfo 4 ADD #0 PUT ;control = 0 PutFile ;attempt to make new dir entry IFZ "error" $PRINT DROP ELSE ;bytelen, high/low block start of file on stack "to " $PRINT OVER PNUM DUP PNUM SBLA ;set block address to start of file ;bytelen on stack INC ;in case odd 4000 DIV ;turn into #blocks 2 ;mem ptr OVER #0 SWAP +DO ;loop for up to 32 dec 1KW blocks DUP ;push alt mem loc source WKBUF ;push destination 2000 ;size of first 31 blocks INDEX 37 SUB IFZ DROP 1777 ENDIF ;size of last block A>CCOPY ;copy 1K to work buffer WKBUF W-1K ;write to disk 2000 ADD ;increment mem ptr to next block "*" $PRINT +LOOP DROP ;mem ptr DROP ;block length ACOPY ;copy 1K to alt mem 2000 ADD ;inc ptr to next block "*" $PRINT +LOOP DROP ;alt mem ptr DROP ;#blocks =end UNTIL MS_RESTORE DROP ELSE DirInfo GET 177777 SUB IFNZ ;if not because of error ;dump alt mem as hex... (fixed 2/21/07) #0 ;alt mem ptr DO ;until quit DUP WKBUF 200 A>CCOPY ;copy 128 alt words to work buf WKBUF ;work buffer ptr #0 17 +DO ;do 16 dec lines at a time OVER $STR $HEAD DROP $PRINT ":" $PRINT #0 7 +DO ;do 8 words per line DUP INDEX ADD GET PNUM +LOOP SWAP 10 ADD SWAP ;inc alt-mem ptr 10 ADD ;inc wkbuf ptr CRLF +LOOP DROP ;wkbuf ptr $DUP $PRINT ;print prompt CHRIN CASE = 102 DROP #0 #0 ;move to begining = 106 2000 ADD #0 ;move forward = 121 #1 ;quit DEFAULT #0 42 +DO 4010 PWRD 40 PCHR +LOOP 10 PCHR ;erase prompt #0 ;keep going ENDCASE UNTIL DROP ;alt mem pointer ENDIF ;DirInfo error ENDIF ;txt/bin test $DROP ;prompt string END ;--------------------------------------- "Loading XDIR" $PRINT CRLF ;XDIR - lists files in current directory block DEFINE XDIR $VOL ;read volume index and set VolInfo to current dir, push cv name "Drive: " $PRINT DRV GET PNUM " Volume: " $PRINT VolInfo GET IFZ ;if something went wrong " invalid" $PRINT $DROP ELSE $PRINT ;print drive and volume VolInfo INC INC GET ;push dirblock high VolInfo INC GET ;push dirblock low SBLA WKBUF R-1K ;read dirblock Y ;push printed-legend flag #0 VolInfo GET DEC +DO ;loop thru all dir entries DUP GET IFNZ ;if not zero DUP GET 20040 SUB IFNZ ;if not spaces Y>S DUP S>Y IFZ ;if not printed yet CRLF ;print legend... "Filename " $PRINT "LA RA LAP BSIZ CW BLKL BLKH Slot" $PRINT Y>S DROP #1 S>Y ;flip flag to print only once ENDIF CRLF #0 7 +DO DUP INDEX ADD GET PWRD +LOOP ;print filename " " $PRINT 13 17 +DO DUP INDEX ADD GET PNUM +LOOP ;print numbers #0 INDEX 40 MUL ;push 32 bit file offset VolInfo 4 ADD GET ;push filespace high VolInfo 3 ADD GET ;push filespace low DADD ;make 32 bit starting block of file PNUM PNUM ;print BLKH BLKL INDEX PNUM ;print slot# ENDIF ENDIF 20 ADD ;increment ptr +LOOP DROP ;ptr Y>S IFZ CRLF "No files" $PRINT ENDIF ENDIF ;read error ENDIF ;volume error END ;--------------------------------------- "Loading XREN" $PRINT CRLF ;"filename" "newname" XREN - renames file DEFINE XREN ChkSFS IFNZ ;if SFS running $DROP $DROP ;don't run ELSE $SWAP $DUP ;swap strings, save filename ;newname oldname oldname on X GetFile ;look up dir/vol stats IFZ ;if error $PRINT " not found" $PRINT $DROP ELSE ;VolInfo/DirInfo valid (as disk is), loc hi/lo on stack DROP DROP ;don't need to know DirInfo 5 ADD GET ;push entry# 20 MUL WKBUF ADD ;turn into address ;sanity check... DUP WKBUF SUB IF<0 #1 ELSE #0 ENDIF DUP WKBUF 1777 ADD SWAP SUB IF<0 DROP #1 ENDIF IFNZ "Bad error! check file " $PRINT $PRINT $DROP DROP ELSE ;newname oldname on X, mem ptr on stack "Renaming " $PRINT $PRINT " to " $PRINT $DUP $PRINT "... " $PRINT 16Pad ;space-pad string $ADR ;push address of new name string #0 7 +DO ;loop for 8 words OVER INDEX ADD ;push address in dir entry OVER INDEX ADD GET ;push string word PUT ;copy string to mem +LOOP DROP DROP $DROP ;string adr, mem ptr, new name string VolInfo INC INC GET ;push dirblock high VolInfo INC GET ;push dirblock low SBLA WKBUF W-1K ;update dir block