; Trivial HP-IPL/OS "dos" for 7900-size drives ; orig 1/6/04 WTN last mod 9/3/04 ; Req. DMS, R-1K W-1K SBLA LDFB disk drivers ; 21MX only with at least 128MB memory ; Uses 2 blocks for disk, normal allocation is 4 blocks ; Implementation... ; +DB -DB ZAM F2AM AM2F MS2F F2MS ; TGEN TLOAD TSHOW TDIR TDELETE TFORMAT TDSAVE TABS ; Supports 32 files beginning at block offset 47 octal ; File types... ; If 1st word = 0 then empty ; If 1st word = 124003 then system file ; Anything else is a general-purpose file, 31KW long generally ; No directory, system files identified by string at 2001 oct or ; the run address if not 2000 oct, general files are ID'd by the ; first few characters. No filenames, just file number 0-37 octal. ; TLOAD loads and runs if system, anything ; else is redirected ; into HP-IPL/OS. Binary overlays must be encoded to IPL first... ; ; ZAM MS_SAVE 2 MSUSER ; fromadr toadr MKLDR ; file# AM2F ; MS_RESTORE ...then overlay can be TLOAD'd. ; ;----------------- "Loading +DB -DB" $PRINT CRLF ; ; +DB - sets allocation to 2 blocks ; OCTAL DEFINE +DB 2 ALLOCATE ;use top-most 2 blocks for dos stuff END ; ; -DB - sets allocation to 4 blocks ; OCTAL DEFINE -DB 4 ALLOCATE ;two lower blocks that disk won't overwrite END ;----------------- "Loading ZAM" $PRINT CRLF ; ; ZAM - zero alt map - copy 32KW of zeros to alt starting at 0 ; this overwrites the A and B registers ; OCTAL DEFINE ZAM #0 ZEROBLOCK #0 37 +DO ;32 blocks @BLK GET ;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 F2AM" $PRINT CRLF ; ; filenumber F2AM - copies 31KW of file to alt map, offset by 2 ; This is designed to be used by other dos stuff, doesn't change alloc ; OCTAL DEFINE F2AM DUP 40 SUB IF<0 ;if valid filenumber 40 MUL 47 ADD #0 SWAP SBLA ;seek to file 2 ;address to copy to #0 36 +DO ;loop thru all blocks @BLK GET DUP R-1K ;read block, save addr OVER 2000 C>ACOPY ;copy current to alt map 2000 ADD ;point to next block in alt map +LOOP ELSE "Bad file#" $PRINT ENDIF DROP ;pointer or filenumber END ;----------------- "Loading AM2F" $PRINT CRLF ; ; filenumber AM2F - copies 31KW of alt map starting at 2 to file ; This is designed to be used by other dos stuff, doesn't change alloc ; OCTAL DEFINE AM2F DUP 40 SUB IF<0 ;if valid filenumber 40 MUL 47 ADD #0 SWAP SBLA ;seek to file 2 ;address to copy from #0 36 +DO ;loop thru all blocks DUP @BLK GET 2000 A>CCOPY ;copy alt block to block 0 @BLK GET W-1K ;write to file 2000 ADD ;point to next block in alt map +LOOP ELSE "Bad file#" $PRINT ENDIF DROP ;pointer or filenumber END ;----------------- "Loading TGEN" $PRINT CRLF ; ; filenumber TGEN - write system to file ; OCTAL DEFINE TGEN DUP 40 SUB IF<0 ;if valid filenumber "Saving..." $PRINT 40 MUL 47 ADD ;multiply by filesize and add offset #0 SWAP SBLA ;seek to file slot 2 ;start at address 2 #0 36 +DO ;loop 31 times DUP W-1K ;write block 2000 ADD ;add 1024 to pointer +LOOP ELSE "Bad file#" $PRINT ENDIF DROP END ;----------------- "Loading TLOAD" $PRINT CRLF ; ; filenumber TLOAD - load/run system from file ; OCTAL DEFINE TLOAD DUP 40 SUB IF<0 ;if valid filenumber +DB ;use top blocks DUP ;save filenumber 40 MUL 47 ADD ;multiply by filesize and add offset DUP #0 SWAP SBLA @BLK GET R-1K ;load first block @BLK GET GET ;get 1st word of file CASE = 0 "Nothing there." $PRINT DROP DROP = 124003 -DB ;restore normal allocation ALTSAVE ;save system to alt mem and put restore code in himem "Loading system..." $PRINT CRLF -IRQ -DMS ;no interrupts or dms #0 SWAP SBLA ;seek to start of file LDFB ;load and run system file DEFAULT ;load an IPL file into alt map and redirect into console DROP F2AM ;copy file to alt map (and clean up stack) 2 MSUSER ;point MS to alt map starting at 2 =end UNTIL MS_RESTORE DROP -DB ;normal allocation ELSE DROP "Bad file#" $PRINT ENDIF END ;----------------- "Loading TDIR" $PRINT CRLF ; ; TDIR - lists files ; OCTAL DEFINE TDIR +DB ;determine how many files to display, count backwards from last 37 ;last file DO DUP 40 MUL 47 ADD #0 SWAP SBLA @BLK GET R-1K ;load 1st block of file @BLK GET GET IFZ ;if 1st word is 0 DEC DUP ;decrement stack, dup for test IF<0 "No files." $PRINT #1 ELSE #0 ENDIF ;terminate if no more ELSE #1 ;keep looking for non-empty fileslot ENDIF UNTIL ;if no files stack = -1 otherwise ;last non-empty filenumber on stack DUP IF<0 DROP ELSE #0 SWAP +DO "File " $PRINT INDEX PNUM 40 PCHR INDEX 40 MUL 47 ADD #0 SWAP SBLA @BLK GET R-1K ;get 1st block of file @BLK GET GET ;get 1st word CASE = 124003 @BLK GET INC GET 2000 SUB IFZ ;if startadr = 2000 then ;assume it's a hpiplos binary, print version @BLK GET DUP R-1K ;get next block, keep address INC DUP 11 ADD +DO ;loop thru address+1 to address+10 INDEX GET ; PWRD ;print HP-IPL/OS version ; 8/30/03 avoid problems with strange binaries... DUP 177 AND ;push low byte OVER 77400 AND 377 DIV ;push high bype #0 #1 +DO ;loop twice DUP CASE < 40 DROP 56 ENDCASE PCHR +LOOP DROP +LOOP ELSE ;if starting address <> 2000 then "System binary, runadr = " $PRINT @BLK GET INC GET PNUM ENDIF <> 0 MS_SAVE #0 INBLOCK #0 57 +DO ;print 48 characters MSBIN DUP CASE < 40 56 PCHR ;reject return and control chars > 177 56 PCHR ;reject binary DEFAULT DUP PCHR ;print first few characters ENDCASE DROP +LOOP MS_RESTORE ENDCASE CRLF +LOOP ENDIF -DB END ;----------------- "Loading TDELETE" $PRINT CRLF ; ; filenumber TDELETE - delete file ; OCTAL DEFINE TDELETE DUP 40 SUB IF<0 ;if valid filenumber +DB "Deleting file " $PRINT DUP PNUM 40 MUL 47 ADD ;multiply by filesize and add offset #0 SWAP SBLA ;seek #0 ZEROBLOCK ;clear block #0 37 +DO ;do 32 times @BLK GET W-1K ;write 0's to 32 blocks +LOOP -DB ELSE DROP "Bad file#" $PRINT ENDIF END ;----------------- "Loading TFORMAT" $PRINT CRLF ; ; TFORMAT ; OCTAL DEFINE TFORMAT "Erase all files? (Y/N) " $PRINT CHRIN 131 SUB IFZ CRLF #0 37 +DO INDEX TDELETE CRLF +LOOP ENDIF END ;----------------- "Loading TDSAVE" $PRINT CRLF ; ; "DefName" filenumber TDSAVE - save definition to file ; Uses 4 blocks, expanded definition cannot exceed 4KW ; OCTAL DEFINE TDSAVE DUP 40 SUB IF<0 ;if valid filenumber -DB ;use 4 blocks DUP TDELETE CRLF ;overwrite previous file with 0 "Saving " $PRINT $DUP $PRINT #0 3 +DO INDEX ZEROBLOCK +LOOP #0 STASH ;write definition to block 0+ 40 MUL 47 ADD #0 SWAP SBLA ;seek to file #0 3 +DO INDEX 2000 MUL @BLK GET ADD W-1K +LOOP ;write blocks 0-3 to file ELSE DROP "Bad file#" $PRINT ENDIF END ;----------------- "Loading MS2F" $PRINT CRLF ; ; #bytes filenumber MS2F - copy MS input to file ; OCTAL DEFINE MS2F DUP 40 SUB IF<0 ;if valid filenumber MS_SAVE +DB SWAP ;will need #bytes first "Clearing buffer..." $PRINT ZAM CRLF "Copying " $PRINT DUP PNUM "bytes from MS input..." $PRINT 350 DUP GET ;push current MS input vector 2 MSUSER ;redirect MS in/out to alt map loc. 2 PUT ;restore MS input to previous value, leaving out >alt map DUP IFZ DROP ELSE #0 SWAP DEC +DO ;loop thru all bytes MSBIN MSBOUT ;straight copy +LOOP 40 MSBOUT ;pad with a space incase odd #bytes ;(MSUSER writes only when 2nd byte received) ENDIF CRLF "Saving to file " $PRINT DUP PNUM AM2F ;copy alternate map to file -DB MS_RESTORE ;restore config ELSE DROP DROP "Bad file#" $PRINT ENDIF END ;----------------- "Loading F2MS" $PRINT CRLF ; ; filenumber F2MS - copies file to MS output ; OCTAL DEFINE F2MS DUP 40 SUB IF<0 ;if valid filenumber MS_SAVE +DB "Copying file " $PRINT DUP PNUM "to buffer..." $PRINT F2AM CRLF ;copy file to alt map "Transfering 31KW to MS output..." $PRINT 351 DUP GET ;save MS output value 2 MSUSER ;redirect MS in/out from/to alt map loc 2 PUT ;restore original MS output #0 75777 +DO ;output exactly 31KW MSWIN MSWOUT ;word copy, bit faster +LOOP -DB MS_RESTORE ELSE DROP "Bad file#" $PRINT ENDIF END ;--------------------- "Loading TABS" $PRINT CRLF ; ; TABS - loads an abs file into alt memory, patches it so ; TDOS can load it as a system binary and writes to disk. ; ABS file must be loaded into PTR (or whatever MS stream set to) ; Note: uses zp locations 176 and 177 ; Usage: file# TABS ; Prompts for run address, if 100 then adds exit code to locs 77/76 ; so that basic1.abs' BYE command exits back to hpiplos ; OCTAL DEFINE TABS ZAM ABSLOAD CRLF ;load the abs into alt mem 176 124003 PUT ;put jmp 3,i in loc 176 177 "Run address: " $PRINT $IN $VAL PUT ;save runadr to loc 177 176 2 2 C>ACOPY ;copy 176/177 to alt mem 2/3 "Add 77 exit? (Y/N) " $PRINT CHRIN 131 SUB IFZ "es" $PRINT ;indicate action ;put 77000 in alt mem 76 and jmp 76,i in 77 ;so executing 77 causes hpiplos to be restored 176 77000 PUT 177 124076 PUT 176 76 2 C>ACOPY ENDIF CRLF "Saving to file " $PRINT DUP PNUM AM2F ;copy alt mem to TDOS file END ;----------------- "Loading TPRA" $PRINT CRLF OCTAL DEFINE TPRA ; runadr TPRA - patches run address of system in alt mem ; primary use is to save HPBASIC system/program to disk ; for HPBASIC 100 inits, 2050 reenters, 5137 runs ; (prob. not the right vectors but seem to work) ; for ex. to make a hpbasic program autostart use: ; 5137 TPRA file# AM2F ; uses zp location 176 176 SWAP PUT 176 3 #1 C>ACOPY END ;----------------- "Loading THELP" $PRINT CRLF OCTAL DEFINE THELP "=== Trivial DOS === 9/3/04" $PRINT CRLF "Supports 32 files of 31KW each, accessed via filenumber" $PRINT CRLF "TDIR - displays version or 1st line of each file" $PRINT CRLF "file# TGEN - write system to file" $PRINT CRLF "file# TLOAD - load system or IPL file" $PRINT CRLF "file# TSHOW - display contents of file" $PRINT CRLF "file# TDELETE - overwrite file with 0's" $PRINT CRLF "TFORMAT - overwrite all files with 0's" $PRINT CRLF 42 PCHR "DefName" $PRINT 42 PCHR " file# TDSAVE" $PRINT " - save def to file (4 blocks max)" $PRINT CRLF "ZAM - zero alt mem" $PRINT CRLF "file# F2AM - copy file to alt mem" $PRINT CRLF "file# AM2F - copy alt mem to file" $PRINT CRLF "file# F2MS - copy file to MS output device" $PRINT CRLF "#bytes file# MS2F - copy bytes from MS input to file" $PRINT CRLF "file# TABS - load ABS from MS input and save to file" $PRINT CRLF "runadr TPRA - patch run address of system in alt mem" $PRINT END ;----------------- CONSOLE