1 EXTEND 2 ! PRESET == Preset system characteristics to current values & ! & ! This program creates a command file for use with ONLPAT which & ! presets the terminal characteristics of all terminals on the system & ! plus the date and time formats and the magtape labeling and density & ! settings to their current settings. Once preset in this way, & ! terminal characteristics, except multiple private dilimiters, date & ! and time formats, and magtape label and density settings do not need & ! to be set in the system startup procedure. & ! & ! This program is provided by Cluster Technology Corp. as a service to & ! the RSTS community. It is provided "AS IS" with no warranties, & ! expressed or implied. & ! & ! Author: & ! Michael Mayfield & ! & ! Edit History: & ! 00 4-Apr-86 MEM Original version. & ! 01 21-Apr-86 MEM Added support for date and time formats and & ! magtape label and density defaults. Verified & ! operation on V9.1-05. & ! & ! RSTS Version: & ! V9.0, V9.1 & ! & ! Variable Usage: & ! BC% Offset from TTINPT to buffer count & ! CMDFIL.CHN% Channel number for command file & ! CMDFIL.NAME$ Name of command file & ! CNT.KB% Number of keyboards on system & ! CR$ Carriage return & Line feed & ! DATCNV% ->DATCNV (TIMCNV, MAGLBL, & MAGDEN follow) & ! DDHORC.M1% DDB offset-1 to characters per line +1 (DDHORC) & ! DDHORC.VAL% Value of DDHORC & ! KBDDB% ->DDB for current terminal & ! DDIDX% DDB offset to driver index (DDIDX) & ! DDUNT.M1% DDB offset-1 to unit number & ! DEV0KB% Offset from DEVPTR to KB entry & ! DEVPTR% ->DEVPTR & ! DEVTBL% ->DEVPTR at KB0 entry & ! EP% Offset from TTINPT to empty pointer & ! FP% Offset from TTINPT to fill pointer & ! HDR1$ First part of patch line header & ! HDR3$ Second part of header for byte patch & ! HDR6$ Second part of header for word patch & ! HT$ Horizontal tab & ! KB.NUM.2% Keyboard number *2 for terminal & ! M1$ String constant of CVT%$(-1%) & ! OFFSET$ Header for offset prompt & ! SILNAM$ Name of SIL to patch & ! SYMTBL$(0..n) List of symbols and resolved values & ! TTCAPB% DDB offset to terminal capabilities (TTCAPB) & ! TTCAPB.VAL% Value of TTCAPB & ! TTCHAR% DDB offset to terminal characteristics (TTCHAR) & ! TTCHAR.VAL% Value of TTCHAR & ! TTCTRL% DDB offset to control chars & funcs (TTCTRL) & ! TTCTRL.VAL% Value of TTCTRL and TTTYPE & ! TTFCNT% DDB offset to TTFCNT (or 0) & ! TTINPT% DDB offset to TTINPT & ! TTINPT.BC.VAL% Value of TTINPT+BC & ! TTINTF% DDB offset to interface type (TTINTF) & ! TTINTF.VAL% Value of TTINTF & ! TTPARM% DDB offset to TTPARM (or 0) & ! TTPDLM.M1% DDB offset-1 to private delimeters (TTPDLM) & ! TTPDLM.VAL% Value of TTPDLM & ! TTRING% DDB offset to TTRING (or 0) & ! & ! Function Usage: & ! FNC.OCT$ Convert integer to octal string & ! FNC.FIND.SIL$ Find current SIL name & ! FNC.GBLRES% Resolve global symbols from SIL & 100 DIM Z%(32), SYMTBL$(7) & \ DDIDX%=0% & \ DDUNT.M1%=2% & \ DDHORC.M1%=16% & \ TTINPT%=18% & \ EP%=0% & \ FP%=2% & \ BC%=4% & \ TTPDLM.M1%=26% & \ TTCHAR%=28% & \ TTINTF%=30% & \ TTCAPB%=34% & \ TTCTRL%=36% & \ CR$=CHR$(13%)+CHR$(10%) & \ HT$=CHR$(9%) & \ M1$=CVT%$(-1%) & \ HDR3$=HT$+" ???"+HT$+"? " & \ HDR6$=HT$+"??????"+HT$+"? " & \ OFFSET$="Offset address? " & \ CMDFIL.CHN%=1% & \ SYMTBL$(1%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"TTPARM"),7%,4%) & \ SYMTBL$(2%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"TTRING"),7%,4%) & \ SYMTBL$(3%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"TTFCNT"),7%,4%) & \ SYMTBL$(4%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"DATCNV"),7%,4%) & \ SYMTBL$(5%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"TIMCNV"),7%,4%) & \ SYMTBL$(6%)=MID(SYS(CHR$(6%)+CHR$(-10%)+"MAGLBL"),7%,4%) & \ SYMTBL$(0%)=CVT%$(6%) & ! Initialize constants & 1000 PRINT "PRESET V1.1 == Preset system characteristics in SIL" & \ PRINT & \ ON ERROR GOTO 30000 & \ CHANGE SYS(CHR$(6%)+CHR$(-3%)) TO Z% & \ CNT.KB%=Z%(3%) & \ DEVPTR%=Z%(7%) OR SWAP%(Z%(8%)) & \ CHANGE SYS(CHR$(6%)+CHR$(-12%)) TO Z% & \ DEV0KB%=Z%(9%) OR SWAP%(Z%(10%)) & \ DEVTBL%=PEEK(DEVPTR%+DEV0KB%) & ! Announce ourselves. Get number of keyboards on system. Get & ! pointers to the tables we will need. Set up our symbolic offsets & ! within the DDB. & 1010 PRINT "Output command file name "; & \ INPUT LINE CMDFIL.NAME$ & \ CMDFIL.NAME$=CVT$$(CMDFIL.NAME$,-1%) & \ CMDFIL.NAME$="SY:PRESET.CMD" IF CMDFIL.NAME$="" & \ OPEN CMDFIL.NAME$ FOR INPUT AS FILE CMDFIL.CHN% & \ PRINT "%That file already exists. Delete it "; & \ INPUT LINE Z$ & \ Z$=LEFT(CVT$$(Z$,-1%),1%) & \ GOTO 1010 UNLESS Z$="Y" & ! Get our command file name. Make sure the file does not already & ! exist (non-existant goes to 1020). Allow them to replace the & ! file if desired. & 1020 PRINT "Ensure that the system is idle. Press RETURN to continue"; & \ INPUT LINE Z$ & \ SILNAM$=FNC.FIND.SIL$(12%) & \ PRINT "Creating patch control file for "; SILNAM$; CR$; & "Please wait..."; & \ Z%=FNC.GBLRES%(SILNAM$,12%) & \ TTPARM%,TTRING%,TTFCNT%=0% & \ TTPARM%=CVT$%(SYMTBL$(1%)) IF RIGHT(SYMTBL$(1%),3%)=M1$ & \ TTRING%=CVT$%(SYMTBL$(2%)) IF RIGHT(SYMTBL$(2%),3%)=M1$ & \ TTFCNT%=CVT$%(SYMTBL$(3%)) IF RIGHT(SYMTBL$(3%),3%)=M1$ & \ DATCNV%=CVT$%(SYMTBL$(4%)) & \ FOR Z%=4% TO CVT$%(SYMTBL$(0%)) & \ IF RIGHT(SYMTBL$(Z%),3%)<>M1$ OR & CVT$%(SYMTBL$(Z%))<>DATCNV%+(Z%-4%)*2% THEN & PRINT CR$; "?Symbol "; RAD$(CVT$%(SYMTBL$(Z%))); & RAD$(CVT$%(RIGHT(SYMTBL$(Z%),3%))); & " not resolved properly."; CR$; & "?PRESET will not work with this version of RSTS." & \ GOTO 32767 1030 NEXT Z% & \ OPEN CMDFIL.NAME$ FOR OUTPUT AS FILE CMDFIL.CHN%, RECORDSIZE 4%*512% & \ PRINT #CMDFIL.CHN%, "File to patch? "; SILNAM$; & TAB(40%);";PRESET command file created "; DATE$(0%); CR$; & "Module name? RSTS" & ! Ensure that the system is idle (no terminals are in special modes) & ! Find the name of the currently installed SIL. Tell them what SIL & ! we are using. Resolve our global symbols. Check that the required & ! symbols are resolved properly. Create the ONLPAT command file. & ! Get resolved variables for optional portion of DDB, if any. & ! Setup the patch file header. & 1040 FOR KB.NUM.2%=0% TO (CNT.KB%-1%)*2% STEP 2% & \ KBDDB%=PEEK(DEVTBL%+KB.NUM.2%) & \ IF (PEEK(KBDDB%+DDIDX%) AND 255%) <> 2% OR & (SWAP%(PEEK(KBDDB%+DDUNT.M1%)) AND 255%) <> KB.NUM.2%/2% THEN & PRINT CR$; "?PROGRAM BUG: Attempted to change non-KB DDB" & \ GOTO 32767 1050 !ELSE & HDR1$=FNC.OCT$(KBDDB%,6%)+HT$ & \ DDHORC.VAL%=SWAP%(PEEK(KBDDB%+DDHORC.M1%)) AND 255% & \ TTPDLM.VAL%=SWAP%(PEEK(KBDDB%+TTPDLM.M1%)) AND 255% & \ TTINPT.BC.VAL%=PEEK(KBDDB%+TTINPT%+BC%) & \ TTINPT.BC.VAL%=0% & IF PEEK(KBDDB%+TTINPT%+EP%)<>PEEK(KBDDB%+TTINPT%+FP%) & \ TTCHAR.VAL%=PEEK(KBDDB%+TTCHAR%) & \ TTINTF.VAL%=PEEK(KBDDB%+TTINTF%) & \ TTCAPB.VAL%=PEEK(KBDDB%+TTCAPB%) & \ TTCTRL.VAL%=PEEK(KBDDB%+TTCTRL%) & \ PRINT #CMDFIL.CHN%, & "Base address? "; FNC.OCT$(KBDDB%,6%); & TAB(40%); ";Settings for KB"; NUM1$(KB.NUM.2%/2%); ":"; CR$; & OFFSET$; FNC.OCT$(DDHORC.M1%+1%,2%); CR$; & " Base Offset Old New?"; CR$; & HDR1$; FNC.OCT$(DDHORC.M1%+1%,6%); HDR3$; & FNC.OCT$(DDHORC.VAL%,3%); TAB(40%); ";DDHORC"; CR$; & HDR1$; FNC.OCT$(DDHORC.M1%+2%,6%); HDR3$; "^Z"; CR$; & OFFSET$; FNC.OCT$(TTPDLM.M1%+1%,2%); CR$; & \ PRINT #CMDFIL.CHN%, & HDR1$; FNC.OCT$(TTPDLM.M1%+1%,6%); HDR3$; & FNC.OCT$(TTPDLM.VAL%,3%); TAB(40%); ";TTPDLM"; CR$; & HDR1$; FNC.OCT$(TTPDLM.M1%+2%,6%); HDR3$; "^Z"; CR$; & OFFSET$; FNC.OCT$(TTINPT%+BC%,2%); CR$; & HDR1$; FNC.OCT$(TTINPT%+BC%,6%); HDR6$; & \ IF TTINPT.BC.VAL% THEN & PRINT #CMDFIL.CHN%, FNC.OCT$(TTINPT.BC.VAL%,6%); & TAB(40%); ";TTINPT+BC"; CR$; & ELSE & PRINT #CMDFIL.CHN%, ""; & TAB(40%); ";TTINPT+BC was unstable and was not used"; CR$; 1055 PRINT #CMDFIL.CHN%, & HDR1$; FNC.OCT$(TTINPT%+BC%+2%,6%); HDR6$; "^Z"; CR$; & OFFSET$; FNC.OCT$(TTCHAR%,2%); CR$; & HDR1$; FNC.OCT$(TTCHAR%,6%); HDR6$; & FNC.OCT$(TTCHAR.VAL%,6%); TAB(40%); ";TTCHAR"; CR$; & HDR1$; FNC.OCT$(TTINTF%,6%); HDR6$; & FNC.OCT$(TTINTF.VAL%,6%); TAB(40%); ";TTINTF"; CR$; & HDR1$; FNC.OCT$(TTINTF%+2%,6%); HDR6$; ""; CR$; & \ PRINT #CMDFIL.CHN%, & HDR1$; FNC.OCT$(TTCAPB%,6%); HDR6$; & FNC.OCT$(TTCAPB.VAL%,6%); TAB(40%); ";TTCAPB"; CR$; & HDR1$; FNC.OCT$(TTCTRL%,6%); HDR6$; & FNC.OCT$(TTCTRL.VAL%,6%); TAB(40%); ";TTCTRL & TTTYPE"; CR$; & HDR1$; FNC.OCT$(TTCTRL%+2%,6%); HDR6$; "^Z" 1060 IF TTPARM% THEN & PRINT #CMDFIL.CHN%, & OFFSET$; FNC.OCT$(TTPARM%,6%); CR$; & HDR1$; FNC.OCT$(TTPARM%,6%); HDR6$; & FNC.OCT$(PEEK(KBDDB%+TTPARM%),6%); & TAB(40%); ";TTPARM"; CR$; & HDR1$; FNC.OCT$(TTPARM%+2%,6%); HDR6$; "^Z" 1070 IF TTRING% THEN & PRINT #CMDFIL.CHN%, & OFFSET$; FNC.OCT$(TTRING%,6%) & \ PRINT #CMDFIL.CHN%, & HDR1$; FNC.OCT$(TTRING%+LOOP%,6%); HDR6$; & FNC.OCT$(PEEK(KBDDB%+TTRING%+LOOP%),6%); & TAB(40%); ";TTRING+"; FNC.OCT$(LOOP%,2%); CR$; & FOR LOOP%=0% TO 8% STEP 2% & \ PRINT #CMDFIL.CHN%, & HDR1$; FNC.OCT$(TTRING%+10%,6%); HDR6$; "^Z" 1080 IF TTFCNT% THEN & PRINT #CMDFIL.CHN%, & OFFSET$; FNC.OCT$(TTFCNT%,6%); CR$; & HDR1$; FNC.OCT$(TTFCNT%,6%); HDR6$; & FNC.OCT$(PEEK(KBDDB%+TTFCNT%) AND 255%,6%); & TAB(40%); ";TTFCNT"; CR$; & HDR1$; FNC.OCT$(TTFCNT%+2%,6%); HDR6$; "^Z" 1090 PRINT #CMDFIL.CHN%, & OFFSET$; "^Z" & \ NEXT KB.NUM.2% & ! For each keyboard on the system: Get ->DDB. Ensure that we are & ! (probably) pointing to the write keyboard DDB. Peek value of & ! current DDB contents. Don't use TTINPT+BC if invalid because input & ! is pending. Write command file contents to patch value of DDHORC, & ! TTPDLM, TTINPT, TTCHAR, TTINTF, TTCAPB, TTCTRL, TTTYPE (combined & ! with TTCTRL), and, optionally, TTPARM, TTRING+0..10, TTFCNT. & 1100 HDR1$=FNC.OCT$(DATCNV%,6%)+HT$ & \ PRINT #CMDFIL.CHN%, & "Base address? "; FNC.OCT$(DATCNV%,6%); & TAB(40%); ";Settings for date, time, and magtape:"; CR$; & OFFSET$; "0"; CR$; & HDR1$; "000000"; HDR6$; & FNC.OCT$(PEEK(DATCNV%),6%); & TAB(40%); ";DATCNV"; CR$; & HDR1$; "000002"; HDR6$; & FNC.OCT$(PEEK(DATCNV%+2%),6%); & TAB(40%); ";TIMCNV"; CR$; & HDR1$; "000004"; HDR6$; & FNC.OCT$(PEEK(DATCNV%+4%),6%); & TAB(40%); ";MAGLBL"; CR$; & HDR1$; "000006"; HDR6$; & FNC.OCT$(PEEK(DATCNV%+6%),6%); & TAB(40%); ";MAGDEN"; CR$; & HDR1$; "000010"; HDR6$; "^C" & \ CLOSE #CMDFIL.CHN% & \ PRINT CR$; CR$; & "Finished. Now run ONLPAT and use the "; CMDFIL.NAME$; CR$; & "command file to patch the necessary values into the "; CR$; & SILNAM$; " monitor SIL file." & \ GOTO 32767 & ! Write command file for DATCNV, TIMCNV, MAGLBL, and MAGDEN values. & ! Close out command file. Tell them we are done. That's all folks. & 20000 ! FNC.OCT$ == Integer to Octal String & ! & ! Converts an integer to the equivalent octal string. The number of & ! digits can be specified. Leading zeroes are provided. & ! & ! Input: & ! INTVAL% Integer value to convert & ! SIZ% Number of digits in octal string (6 max) & ! & ! Output: & ! FNC.OCT$ Octal string & ! & ! Local Variables: & ! OCT.STR%(0..6) Working values of string to be built & ! Z% Loop counter & ! Z1% Unsigned value for integer sign bit div. by 8 & & DEF* FNC.OCT$(INTVAL%,SIZ%) & \ OCT.STR%(0%)=SIZ% & \ OCT.STR%(Z%)=48% FOR Z%=1% TO SIZ% & \ IF INTVAL%>=0% THEN & Z1%=0% & ELSE & Z1%=4096% & \ INTVAL%=INTVAL% AND 32767% 20010 FOR Z%=1% TO SIZ% & \ OCT.STR%(SIZ%+1%-Z%)=(INTVAL% AND 7%)+48% & \ INTVAL%=INTVAL%/8%+Z1% & \ Z1%=0% & \ NEXT Z% & \ OCT.STR%(1%)=37% IF INTVAL%<>0% & \ CHANGE OCT.STR% TO FNC.OCT$ & \ FNEND & \ DIM OCT.STR%(6%) & ! Initialize string to all zeros. Put each octal digit in string & ! working from right to left. Replace first character with % if & ! number too large to fit in specified string size. Change to a & ! string and return. & 20100 ! FNC.FIND.SIL$ == Find the name of the currently installed SIL & ! & ! Returns the name of the currently installed SIL. & ! & ! Input: & ! TMPCHN% Channel number to use for disk I/O & ! & ! Output: & ! Name of current SIL as a string & ! & ! Local Variables: & ! None & & DEF* FNC.FIND.SIL$(TMPCHN%) & \ OPEN "_SY0:[0,1]INIT.SYS" FOR INPUT AS FILE TMPCHN%, MODE 8192% & \ GET #TMPCHN%, RECORD 1% & \ FIELD #TMPCHN%, 58% AS Z$, 2% AS Z$ & \ Z%=SWAP%(CVT$%(Z$)) & \ GET #TMPCHN%, RECORD Z%/512%+1% & \ FIELD #TMPCHN%, Z%-(Z%/512%*512%) AS Z$, 2% AS Z$, 2% AS Z1$ & \ FNC.FIND.SIL$="_SY0:[0,1]"+CVT$$(RAD$(SWAP%(CVT$%(Z$)))+ & RAD$(SWAP%(CVT$%(Z1$))),2%)+".SIL" & \ CLOSE #TMPCHN% & \ FNEND & ! Open the [0,1]INIT.SYS we booted from. Get byte offset to config & ! info from bytes 72-73(8) of block 1 of INIT. Get configuration & ! info. Extract installed SIL name and convert to a string. & 20200 ! FNC.GBLRES% == Resolve global symbols from a SILUS format file & ! & ! Resolves a list of symbol names from the symbol table(s) in a SILUS & ! format file. & ! & ! Input: & ! SILNAM$ Name of SILUS file to use & ! TMPCHN% Channel number to use for SIL I/O & ! SYMTBL$(0..n) Symbol names RAD50 2-word format & ! SYMTBL$(0) CVT%$() of count of symbols in SYMTBL$(1..n) & ! & ! Output: & ! FNC.GBLRES% Number of unresolved symbols & ! SYMTBL$(1..n) Symbol value in CVT%$() format & ! & ! Local Variables: & ! GBLRES.BUFOFF% Offset within the SIL buffer to current symbol & ! GBLRES.BUFSIZ% Size of SIL disk buffer, in bytes & ! GBLRES.MODCNT% Number of modules in SIL & ! GBLRES.MODNUM% Module number within SIL (loop counter) & ! GBLRES.RESCNT% Number of symbols in symbol table & ! GBLRES.RESLFT% Number of symbols left to resolve & ! & ! Note: & ! SYMTBL$() must be demensioned in the main program. & & DEF* FNC.GBLRES%(SILNAM$,TMPCHN%) & \ OPEN SILNAM$ FOR INPUT AS FILE TMPCHN%, & RECORDSIZE 512%*16%, MODE 8192% & \ GBLRES.BUFSIZ%=BUFSIZ(TMPCHN%) & \ GBLRES.RESCNT%,GBLRES.RESLFT%=CVT$%(SYMTBL$(0%)) & \ GET #TMPCHN%, RECORD 1% & \ FIELD #TMPCHN%, 2% AS Z$ & \ GBLRES.MODCNT%=SWAP%(CVT$%(Z$)) & \ FOR GBLRES.MODNUM%=1% TO GBLRES.MODCNT% & \ FIELD #TMPCHN%, 2%+(GBLRES.MODNUM%-1%)*32%+10% AS Z$, & 2% AS Z$, 2% AS Z1$ & \ GBLRES.SYMCNT%=SWAP%(CVT$%(Z1$)) & \ GET #TMPCHN%, RECORD SWAP%(CVT$%(Z$))+1% & \ GBLRES.BUFOFF%=0% & \ FOR GBLRES.DSKSYM%=1% TO GBLRES.SYMCNT% & \ IF GBLRES.BUFOFF%>=GBLRES.BUFSIZ% THEN & GET #TMPCHN% & \ GBLRES.BUFOFF%=0% 20210 FIELD #TMPCHN%, GBLRES.BUFOFF% AS Z$, 4% AS Z$ & \ FOR GBLRES.TBLSYM%=1% TO GBLRES.RESCNT% & \ IF SYMTBL$(GBLRES.TBLSYM%)=Z$ THEN & FIELD #TMPCHN%, GBLRES.BUFOFF%+6% AS Z$, 2% AS Z$ & \ SYMTBL$(GBLRES.TBLSYM%)=CVT%$(SWAP%(CVT$%(Z$)))+CVT%$(-1%) & \ GBLRES.RESLFT%=GBLRES.RESLFT%-1% & \ GOTO 20220 20220 NEXT GBLRES.TBLSYM% 20230 GOTO 20240 IF GBLRES.RESLFT%=0% & \ GBLRES.BUFOFF%=GBLRES.BUFOFF%+8% & \ NEXT GBLRES.DSKSYM% & \ GET #TMPCHN%, RECORD 1% & \ NEXT GBLRES.MODNUM% 20240 FNC.GBLRES%=GBLRES.RESLFT% & \ CLOSE #TMPCHN% & \ FNEND & ! Open specified SILUS file. Get module count from SIL header. For & ! each module in the SIL: For each symbol in the module: For each & ! symbol in the symbol table (SYMTBL$): If the symbols match, replace & ! symbol table entry with symbol value and count one less symbol to & ! find. Read new buffers as necessary to keep searching the symbol & ! table. Return the remaining unresolved symbol count as our result. & 30000 IF ERR=5% AND ERL=1010% THEN & RESUME 1020 & ! Can't find the output file. OK to create it. & 30999 PRINT IF CCPOS(0%)<>0 & \ PRINT "??Unexpected error"; ERR; "at line"; ERL & \ ON ERROR GOTO 0 & ! All other errors are fatal & 32767 END