"Loading XDOS Utilities v1.26" $PRINT CRLF ;created 4/23/05 last mod 1/1/12 ;XDOS must be loaded first. Additional utilities... ;MS2F copies MS input to a file (not redirection) ;F2MS copies a file to MS output (not redirection) ;ABS2F loads ABS from MS input, patches, writes to file ;VRECOVER adds volume entries if deleted but point to directory ;XRECOVER adds file entries if deleted but point to non-zero data ;XINIT general purpose SFS/XDOS "formatter", prompts for info ;--------------------------------------------------- "Loading MS2F" $PRINT CRLF ;"file" bytes MS2F - copies bytes from MS input to file DEFINE MS2F ChkSFS IFNZ ;if SFS is running $DROP DROP ;don't create files ELSE "Copying " $PRINT ZAM DUP PNUM "bytes from MS to " $PRINT $DUP $PRINT " " $PRINT MS_SAVE ;save MS input and output vectors 350 DUP GET ;save MS input vector to restore (leave adr) 2 MSUSER ;redirect ms in/out to alt PUT ;restore MS input vector #0 OVER +DO ;copy bytes to alt MSBIN MSBOUT ;in and out +LOOP #0 MSBOUT ;write one more byte (0) to make sure flushed MS_RESTORE ;restore MS in/out vectors ;length in bytes on stack, filename on X CRLF AM2F ;save alt mem to file ENDIF END ;--------------------------- "Loading F2MS" $PRINT CRLF ;"file" F2MS - copies file to MS output DEFINE F2MS F2AM ;copy file to alt mem CRLF "Writing " $PRINT MS_SAVE 351 DUP GET ;save MS out vect to restore 2 MSUSER ;redirect MS to alt PUT ;restore normal MS out #0 ;push a zero DirInfo 3 ADD GET ;push byte size DUP IFZ "nothing." $PRINT DROP ELSE DUP PNUM "bytes to MS out... " $PRINT DEC ;make byte size - 1 +DO ;loop thru all bytes in file MSBIN MSBOUT ;copy alt to MS out +LOOP "Done" $PRINT ENDIF MS_RESTORE END ;--------------------------- "Loading ABS2F" $PRINT CRLF ;"file" ABS2F - copies ABS binary to file ;if location 2 is 0/unused then prompts for ;run address and exit address ;note... uses location 157 (changed from 100, 1/1/12) DEFINE ABS2F ChkSFS IFNZ ;if SFS is running $DROP DROP ;don't create files ELSE "Clearing alt.." $PRINT ZAM CRLF ABSLOAD CRLF ;load abs file into alt mem 2 157 1 A>CCOPY ;get loc 2 from alt mem 157 GET IFZ ;if loc 2 = 0 "Run Address : " $PRINT $IN $VAL DUP IFZ DROP ELSE ;if run addr <> 0 157 124003 PUT 157 2 1 C>ACOPY ;add jmp *+1,i 157 SWAP PUT 157 3 1 C>ACOPY ;add run address ENDIF "Add 77 exit for BASIC? (Y/N) " $PRINT CHRIN 131 SUB IFZ ;if Y "es" $PRINT CRLF 157 77000 PUT 157 76 1 C>ACOPY ;put 77000 in alt loc 76 157 124076 PUT 157 77 1 C>ACOPY ;put jmp 76,i in alt loc 77 ELSE CRLF ENDIF ENDIF ; 174000 AM2F ;write alt to file, length = 62KB ; simple but AM2F fails to recognize raw binaries that start at 2 ; (that's ok, it was designed for "normal" binaries and text) ; must do manually to make sure it's recorded as a binary... "Saving alt " $PRINT DirInfo DUP 2 PUT ;load adr = 2 INC DUP 2 PUT ;run adr = 2 INC DUP #0 PUT ;last access = 0 INC DUP 174000 PUT ;length = 62KB INC #0 PUT ;control = 0 PutFile 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 2 ;mem ptr #0 37 +DO ;loop for up to 31 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 Z ;put #entries in last dir on Z to make programming easier WKBUF DUP 1777 ADD +DO INDEX #0 PUT +LOOP ;clear work buffer DEC ;decrement #vols to get the number of last entry DUP #0 SWAP +DO ;loop thru all volume index entries WKBUF INDEX 20 MUL ADD ;push entry start address #0 7 +DO DUP INDEX ADD 20040 PUT +LOOP ;make name = spaces 13 ADD ;point to dir size entry OVER INDEX SUB IFZ ;if this is the last volume then Z>S ;get size of last dir from Z, removing from Z ELSE 100 ;otherwise full size ENDIF OVER SWAP PUT ;write dir size, leaving mem ptr on stack INC ;point to dir block ptr low INDEX IFZ ;if this is the first entry DUP 7 PUT ;dir is in block 7 INC INC ;leave dir block high zero 47 PUT ;file space begins in block 47 ELSE S>Z ;temporarily stash mem ptr on Z ;dir block = volume number * 4001 + 46 ;file space begins in next block INDEX 4001 EMUL #0 46 DADD DUP ;dup the low word of the result Z>S DUP S>Z ;get mem ptr, leave on Z SWAP PUT ;write dir block low OVER ;push the high word of the result Z>S INC DUP S>Z ;get mem ptr, inc, return to Z SWAP PUT ;write dir block high #0 1 DADD ;increment result to get start of filespace Z>S INC DUP S>Z ;get mem ptr, inc, return to Z SWAP PUT ;write file space low Z>S INC PUT ;write file space high ENDIF +LOOP DROP ;last vol number "Writing new volume index... " $PRINT #0 6 SBLA ;seek to block 6 WKBUF W-1K ;write work buffer