todd@CINCOM.UMD.EDU ("TODD AVEN") (12/17/86)
Following the -*- cut here -*- is the VAX/MACRO program OBSERVE.MAR. I didn't write it, so I can't answer any questions about it (gasp! I haven't even looked at the code). Use in good taste, please. -? send(message(following),from(todd),to(Netlandiers)). -*- cut here -*- .TITLE OBSERVE .LIBRARY /SYS$LIBRARY:LIB.MLB/ .PAGE .SUBTITLE DEFINITIONS $CRBDEF GLOBAL $DDBDEF GLOBAL $DVIDEF GLOBAL $IDBDEF GLOBAL $IODEF GLOBAL $IPLDEF GLOBAL $IRPDEF GLOBAL $PRDEF GLOBAL $PRIDEF GLOBAL $RSNDEF GLOBAL $SSDEF GLOBAL $TTYDEF GLOBAL $TTDEF GLOBAL $TT2DEF GLOBAL $UBADEF GLOBAL $UCBDEF GLOBAL $VECDEF GLOBAL $TTYMACS $TTYDEFS GLOBAL .PAGE .SUBTITLE PARAMETERS TERM_LENGTH = 64 RESPONSE_LENGTH = 1 HEADER = 12 DYN_C_CODE = 120 GREATER_THAN_ZERO = ^B1100 NEGATIVE = ^B1000 ZERO = ^B0100 .PAGE .SUBTITLE BUFFERS CHANNEL: .BLKW 1 SYS_INPUT: .ASCII /SYS$INPUT/ SYS_INPUT_LENGTH = .- SYS_INPUT TERM_PROMPT: .ASCII /enter target terminal / TERM_PROMPT_LENGTH = .- TERM_PROMPT PROMPT_BUFFER: .BLKB TERM_LENGTH TARGET_TERMINAL: .BLKB TERM_LENGTH MY_TERMINAL: .BLKB TERM_LENGTH ;I need to substitute tests for 'X' in the terminal name with a test of ;this byte (MY_TERM_TYPE). I should also validate the target terminal ;type (DT$_DZ11 or DT$_DMF32). TARGET_TERM_TYPE: .BYTE 0 MY_TERM_TYPE: .BYTE 0 TARGET_PID: .BLKL 1 TARGET_CLASS: .BLKL 1 TARGET_UCB_ADDRESS: .BLKL 1 TARGET_UCB_PRTCTL: .BLKW 1 NPP_ADDRESS: .BLKL 1 ALLOCATED_SIZE: .BLKL 1 RESPONSE_BUFFER: .BLKB RESPONSE_LENGTH EXIT_MESSAGE_BUFFER: .BYTE 27 .BYTE 91 .BYTE 72 .BYTE 27 .BYTE 91 .BYTE 74 .ASCII ?enter CTRL/Y to exit? .BYTE 13 .BYTE 10 EXIT_MESSAGE_LENGTH = .- EXIT_MESSAGE_BUFFER ROW: .LONG 24 COLUMN: .LONG 1 MY_UCB_ADDRESS: .LONG 0 PUTNXT_ADDRESS: .LONG 0 GETNXT_ADDRESS: .LONG 0 PORT_ADDRESS: .LONG 0 NEW_PUTNXT_ADDRESS: .BLKL 1 NEW_GETNXT_ADDRESS: .BLKL 1 NEW_PORT_ADDRESS: .BLKL 1 USER_RUNDOWN_ADDRESS: .BLKL 1 CONTROL_Y_MASK: .LONG ^X02000000 QIO_IOSB: .BLKQ 1 TERMINAL_CHAR: .BLKQ 1 .PAGE .SUBTITLE GETDVI ITEM LIST GETDVI_ITEM_LIST: .WORD TERM_LENGTH .WORD DVI$_TT_PHYDEVNAM DVI_TERM_ADDR: .ADDRESS TARGET_TERMINAL .LONG 0 .WORD 4 .WORD DVI$_PID .ADDRESS TARGET_PID .LONG 0 .WORD 4 .WORD DVI$_DEVCLASS .ADDRESS TARGET_CLASS .LONG 0 .LONG 0 .PAGE .SUBTITLE DESCRIPTORS SYS_INPUT_DESCR: .WORD SYS_INPUT_LENGTH .BLKW 1 .ADDRESS SYS_INPUT TERM_PROMPT_DESCR: .WORD TERM_PROMPT_LENGTH .BLKW 1 .ADDRESS TERM_PROMPT TARGET_TERM_DESCR: .WORD TERM_LENGTH .BLKW 1 .ADDRESS TARGET_TERMINAL .PAGE .SUBTITLE OBSERVE .ENTRY OBSERVE, ^M<> BSBW INITIAL CMPL #SS$_NORMAL, R0 BEQLU 10$ BRW EXIT 10$: $CMKRNL_S ROUTIN = INITIALIZE_UCBS BLBS R0, 20$ BRW EXIT 20$: ;disable CTRL/Y PUSHAL CONTROL_Y_MASK CALLS #1, G^LIB$DISABLE_CTRL BLBS R0, 30$ BRW EXIT 30$: ;clear screen with write $QIOW_S FUNC = #IO$_WRITEVBLK,- CHAN = CHANNEL,- IOSB = QIO_IOSB,- P1 = EXIT_MESSAGE_BUFFER,- P2 = #EXIT_MESSAGE_LENGTH BLBC R0, EXIT BLBC QIO_IOSB, EXIT ;modify target UCB $CMKRNL_S ROUTIN = MODIFY_TARGET_UCB BLBC R0, EXIT ;establish CTRL/Y AST to execute termination routine $QIOW_S FUNC = #IO$_SETMODE!IO$M_CTRLYAST,- CHAN = CHANNEL,- IOSB = QIO_IOSB,- P1 = TERMINATION BLBC R0, EXIT BLBC QIO_IOSB, EXIT $HIBER_S EXIT: PUSHL R0 PUSHAL CONTROL_Y_MASK CALLS #1, G^LIB$ENABLE_CTRL BBS #TT$V_NOBRDCST, TERMINAL_CHAR, 10$ $QIOW_S FUNC = #IO$_SETMODE,- CHAN = CHANNEL,- P1 = TERMINAL_CHAR 10$: $DASSGN_S CHAN = CHANNEL $EXIT_S (SP)+ .PAGE .SUBTITLE INITIAL INITIAL: PUSHL #0 ;prompt only if string absent PUSHAL TARGET_TERM_DESCR ;don't need out length PUSHAQ TERM_PROMPT_DESCR PUSHAQ TARGET_TERM_DESCR ;obtain target terminal name CALLS #4, G^LIB$GET_FOREIGN BLBS R0, 10$ BRW INITIAL_EXIT 10$: ;make sure it's a valid device $GETDVIW_S DEVNAM = TARGET_TERM_DESCR,- ITMLST = GETDVI_ITEM_LIST BLBS R0, 12$ 11$: BRW INITIAL_EXIT 12$: CMPL #SS$_NOSUCHDEV, R0 BEQL 11$ ;make sure the device is being used 15$: TSTB TARGET_PID BNEQU 20$ MOVL #SS$_NONEXPR, R0 BRW INITIAL_EXIT 20$: ;assign a channel to my terminal $ASSIGN_S DEVNAM = SYS_INPUT_DESCR,- CHAN = CHANNEL BLBS R0, 25$ BRW INITIAL_EXIT ;get my terminal name 25$: MOVAL MY_TERMINAL, DVI_TERM_ADDR MOVL #0, DVI_TERM_ADDR + 4 $GETDVIW_S CHAN = CHANNEL,- ITMLST = GETDVI_ITEM_LIST BLBC R0, INITIAL_EXIT MOVL TARGET_TERMINAL + 1, TARGET_TERMINAL MOVL MY_TERMINAL + 1, MY_TERMINAL ;make sure I'm not observing my terminal CMPL MY_TERMINAL, TARGET_TERMINAL BNEQU 30$ MOVL #SS$_NONEXPR, R0 BRB INITIAL_EXIT ;set my terminal to no-broadcast 30$: $QIOW_S FUNC = #IO$_SENSEMODE,- CHAN = CHANNEL,- P1 = TERMINAL_CHAR BLBC R0, INITIAL_EXIT BBS #TT$V_NOBRDCST, TERMINAL_CHAR, INITIAL_EXIT MOVQ TERMINAL_CHAR, QIO_IOSB BISL2 #TT$M_NOBRDCST, QIO_IOSB + 4 $QIOW_S FUNC = #IO$_SETMODE,- CHAN = CHANNEL,- P1 = QIO_IOSB INITIAL_EXIT: RSB .PAGE .SUBTITLE INITIALIZE UCBS .ENTRY INITIALIZE_UCBS, ^M<R2, R3, R4, R5, R6, R7, R8, R9> BSBW FIND_UCBS ;check to see if this terminal is already OBSERVEd MOVL MY_UCB_ADDRESS, R1 CMPL UCB$L_TT_PUTNXT(R1), PUTNXT_ADDRESS BEQLU 10$ 5$: MOVL #SS$_ILLIOFUNC, R0 BRB 20$ 10$: MOVL TARGET_UCB_ADDRESS, R0 CMPB UCB$W_TT_SPEED(R1), UCB$W_TT_SPEED(R0) BLSSU 5$ 15$: BSBW PUT_ROUTINE_IN_NPP 20$: RET .PAGE .SUBTITLE FIND_UCBS FIND_UCBS: MOVL G^IOC$GL_DEVLIST, R6 10$: CMPC3 #3, DDB$T_NAME+1(R6), TARGET_TERMINAL BNEQU 30$ CLRL R7 CLRL R8 SUBB3 #48, TARGET_TERMINAL + 3, R7 MOVL DDB$L_UCB(R6), R9 BRB 25$ 20$: MOVL UCB$L_LINK(R9), R9 25$: AOBLEQ R7, R8, 20$ ; MOVL UCB$L_CRB(R9), R10 ; MOVB CRB$B_TT_TYPE(R10), TARGET_TERM_TYPE MOVL UCB$L_TT_PUTNXT(R9), PUTNXT_ADDRESS MOVL UCB$L_TT_GETNXT(R9), GETNXT_ADDRESS MOVL UCB$L_TT_PORT(R9), PORT_ADDRESS MOVW UCB$W_TT_PRTCTL(R9), TARGET_UCB_PRTCTL MOVL R9, TARGET_UCB_ADDRESS TSTL MY_UCB_ADDRESS BNEQU FIND_EXIT 30$: CMPC3 #3, DDB$T_NAME+1(R6), MY_TERMINAL BNEQU 60$ CLRL R7 CLRL R8 SUBB3 #48, MY_TERMINAL + 3, R7 MOVL DDB$L_UCB(R6), R9 BRB 45$ 40$: MOVL UCB$L_LINK(R9), R9 45$: AOBLEQ R7, R8, 40$ MOVL R9, MY_UCB_ADDRESS ; MOVL UCB$L_CRB(R9), R10 ; MOVB CRB$B_TT_TYPE(R10), MY_TERM_TYPE TSTL TARGET_UCB_ADDRESS BNEQU FIND_EXIT 60$: MOVL DDB$L_LINK(R6), R6 BEQLU FIND_EXIT BRW 10$ FIND_EXIT: RSB .PAGE .SUBTITLE PUT_ROUTINE_IN_NPP PUT_ROUTINE_IN_NPP: CMPB #^A/X/, MY_TERMINAL + 1 BNEQU 10$ MOVL #DMF_ROUTINE_LENGTH, R1 BRB 20$ 10$: MOVL #DZ_ROUTINE_LENGTH, R1 20$: MTPR IPL_TWO, S^#PR$_IPL JSB G^EXE$ALONONPAGED MTPR #0, S^#PR$_IPL ;establish image rundown routine MOVL G^CTL$GL_USRUNDWN, USER_RUNDOWN_ADDRESS MOVAL RESET_UCBS, G^CTL$GL_USRUNDWN BRB AROUND IPL_TWO: .BYTE 2 AROUND: BLBS R0, 2$ BRW PUT_EXIT 2$: MOVL R2, NPP_ADDRESS MOVL PUTNXT_ADDRESS, (R2)+ MOVL MY_UCB_ADDRESS, (R2)+ ;mark block for easy deallocation MOVW R1, (R2)+ MOVW #DYN_C_CODE, (R2)+ ;move GETNXT address and port address MOVL GETNXT_ADDRESS, (R2)+ MOVL @PORT_ADDRESS, (R2)+ ;save start of vector table in R8 for modifying UCB MOVL R2, NEW_PORT_ADDRESS ;calculate address of PORT_STARTIO vector and move into vector table CMPB #^A/X/, MY_TERMINAL + 1 BNEQU 3$ ADDL3 NPP_ADDRESS, #DMF_STARTIO_DISPLACEMENT, (R2)+ BRB 4$ 3$: ADDL3 NPP_ADDRESS, #DZ_STARTIO_DISPLACEMENT, (R2)+ 4$: ;loop to move the other port vectors MOVL #1, R0 5$: MOVL @PORT_ADDRESS[R0], (R2)+ AOBLSS #14, R0, 5$ ;move address of PUTNXT code into R6 for modifying UCB MOVL R2, NEW_PUTNXT_ADDRESS ;move code into system buffer, calculate GETNXT address (in R7) CMPB #^A/X/, MY_TERMINAL + 1 BNEQU 10$ MOVC3 #DMF_CODE_LENGTH, DMF_PUTNXT_ROUTINE, (R2) ADDL3 #DMF_GETNXT_DISPLACEMENT, NEW_PUTNXT_ADDRESS,- NEW_GETNXT_ADDRESS BRB 20$ 10$: MOVC3 #DZ_CODE_LENGTH, DZ_PUTNXT_ROUTINE, (R2) ADDL3 #DZ_GETNXT_DISPLACEMENT, NEW_PUTNXT_ADDRESS,- NEW_GETNXT_ADDRESS 20$: MOVL #SS$_NORMAL, R0 PUT_EXIT: RSB .PAGE .SUBTITLE MODIFY TARGET UCB .ENTRY MODIFY_TARGET_UCB, ^M<> MOVL TARGET_UCB_ADDRESS, R2 MTPR IPL_21, S^#PR$_IPL MOVL NEW_PUTNXT_ADDRESS, UCB$L_TT_PUTNXT(R2) MOVL NEW_GETNXT_ADDRESS, UCB$L_TT_GETNXT(R2) MOVL NEW_PORT_ADDRESS, UCB$L_TT_PORT(R2) ;clear DMA bit to force single character and burst output BICW2 #TTY$M_PC_DMAENA, UCB$W_TT_PRTCTL(R2) MTPR #0, S^#PR$_IPL MOVL #SS$_NORMAL, R0 RET IPL_21: .BYTE 21 .PAGE .SUBTITLE START OF DMF ROUTINE START_OF_DMF_ROUTINE: DMF_PUTNXT_ADDRESS: .BLKL 1 DMF_MY_UCB_ADDRESS: .BLKL 1 .BLKL 1 ;holds position of 3rd longword of header DMF_GETNXT_ADDRESS: .BLKL 1 ;moved to system buffer via MOVL DMF_PORT_VECTOR: .BLKL 1 DMF_PORT_VECTOR_TABLE: .BLKL 14 ;new vector table DMF_PUTNXT_ROUTINE: PUSHR #^M<R6, R7, R8, R9, R10> MOVL DMF_MY_UCB_ADDRESS, R6 MOVL UCB$L_CRB(R6), R7 MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 PUSHAL DMF_START_IO ;return to output rtn JMP @DMF_PUTNXT_ADDRESS ;perform code DMF_GETNXT_ROUTINE: DMF_GETNXT_DISPLACEMENT = .-DMF_PUTNXT_ROUTINE PUSHR #^M<R6, R7, R8, R9, R10> MOVL DMF_MY_UCB_ADDRESS, R6 MOVL UCB$L_CRB(R6), R7 MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 JSB @DMF_GETNXT_ADDRESS ;perform routine DMF_START_IO: BLEQ 10$ ;none or string output BISW3 #^X4040, UCB$W_UNIT(R6), (R7) ;select silo transmit MOVB R3, 6(R7) ;output character BICPSW #GREATER_THAN_ZERO ;reset CC BRB 91$ 10$: BEQL 91$ ;no output MOVW UCB$W_TT_OUTLEN(R5), UCB$W_TT_OUTLEN(R6) MOVL UCB$L_TT_OUTADR(R5), UCB$L_TT_OUTADR(R6) BISW3 #^X4040, UCB$W_UNIT(R6), (R7) MOVZBL 6(R7), R8 ;get silo depth SUBL3 R8, #32, R8 ;convert to # of slots MOVZWL UCB$W_TT_OUTLEN(R6), R9 ;get length of transfer CMPW R9, R8 ;compare slots and size BLEQU 50$ MOVZBL R8, R9 ;maximize with slots 50$: MOVL UCB$L_TT_OUTADR(R6), R10 ;autoincrement R10 ADDL R9, UCB$L_TT_OUTADR(R6) ;update pointer SUBW R9, UCB$W_TT_OUTLEN(R6) ;and count BEQL 60$ BISW #TTY$M_TANK_BURST,- UCB$W_TT_HOLD(R6) 60$: BLBC R9, 70$ ;branch if even MOVB (R10)+, 6(R7) ;output single byte DECL R9 BEQL 90$ 70$: ASHL #-1, R9, R9 ;convert to word count 75$: MOVW (R10)+, 6(R7) NOP NOP NOP SOBGTR R9, 75$ 90$: TSTL DMF_MY_UCB_ADDRESS ;reset CC negative 91$: POPR #^M<R6, R7, R8, R9, R10> RSB DMF_STARTIO_ROUTINE: DMF_STARTIO_DISPLACEMENT = .-START_OF_DMF_ROUTINE BEQL 90$ ;save PSL on stack MOVPSL -28(SP) ;load return address for RSB in above routine PUSHL DMF_PORT_VECTOR PUSHR #^M<R6, R7, R8, R9, R10> ;save condition codes and set branch address to above routine (REI) TSTL -(SP) PUSHAL DMF_START_IO MOVL DMF_MY_UCB_ADDRESS, R6 MOVL UCB$L_CRB(R6), R7 MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 ;restore condition codes and branch REI 90$: JMP @DMF_PORT_VECTOR DMF_CODE_LENGTH = .-DMF_PUTNXT_ROUTINE DMF_ROUTINE_LENGTH = .- START_OF_DMF_ROUTINE .PAGE .SUBTITLE START OF DZ ROUTINE START_OF_DZ_ROUTINE: DZ_PUTNXT_ADDRESS: .BLKL 1 DZ_MY_UCB_ADDRESS: .BLKL 1 .BLKL 1 ;holds position of 3rd longword of header DZ_GETNXT_ADDRESS: .BLKL 1 ;moved to system buffer via MOVL DMF_GETNXT... DZ_PORT_VECTOR: .BLKL 1 DZ_PORT_VECTOR_TABLE: .BLKL 14 DZ_PUTNXT_ROUTINE: PUSHR #^M<R6, R7, R8> MOVL DZ_MY_UCB_ADDRESS, R6 MOVL UCB$L_CRB(R6), R7 MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 PUSHAL DZ_START_IO ;return to output rtn JMP @DZ_PUTNXT_ADDRESS ;perform routine DZ_GETNXT_ROUTINE: DZ_GETNXT_DISPLACEMENT = .-DZ_PUTNXT_ROUTINE PUSHR #^M<R6, R7, R8> MOVL DZ_MY_UCB_ADDRESS, R6 MOVL UCB$L_CRB(R6), R7 MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 JSB @DZ_GETNXT_ADDRESS ;perform routine TSTB UCB$B_TT_OUTYPE(R5) ;anything to output?? DZ_START_IO: BLEQ 10$ ;none or string output MOVB R3, UCB$W_TT_HOLD(R6) ;save character in tank BISW #TTY$M_TANK_HOLD,- UCB$W_TT_HOLD(R6) ;signal char in tank BISW UCB$W_TT_UNITBIT(R6), 4(R7) ;enable line BICPSW #GREATER_THAN_ZERO ;reset CC positive BRW 90$ ;exit 10$: BEQL 90$ ;no character - exit MOVL UCB$L_TT_OUTADR(R5), UCB$L_TT_OUTADR(R6) ;addr MOVW UCB$W_TT_OUTLEN(R5), UCB$W_TT_OUTLEN(R6) ;len BISW #TTY$M_TANK_BURST,- UCB$W_TT_HOLD(R6) ;signal burst BISW UCB$W_TT_UNITBIT(R6), 4(R7) ;enable line TSTL DZ_MY_UCB_ADDRESS ;reset CC negative 90$: POPR #^M<R6, R7, R8> RSB DZ_STARTIO_ROUTINE: DZ_STARTIO_DISPLACEMENT = .-START_OF_DZ_ROUTINE ;save PSL on stack MOVPSL -20(SP) ;push return address of above routine PUSHL DZ_PORT_VECTOR PUSHR #^M<R6, R7, R8> ;save condition codes and set branch address to above routine (REI) TSTL -(SP) PUSHAL DZ_START_IO MOVL DZ_MY_UCB_ADDRESS, R6 ;get my UCB MOVL UCB$L_CRB(R6), R7 ;find my MOVL @CRB$L_INTD + VEC$L_IDB(R7), R7 ;CSR ;restore condition codes and branch REI DZ_CODE_LENGTH = .-DZ_PUTNXT_ROUTINE DZ_ROUTINE_LENGTH = .- START_OF_DZ_ROUTINE .PAGE .SUBTITLE TERMINATION ROUTINE .ENTRY TERMINATION, ^M<> PUSHAL CONTROL_Y_MASK CALLS #1, G^LIB$ENABLE_CTRL pushal column pushal row calls #2, G^lib$set_cursor BBS #TT$V_NOBRDCST, TERMINAL_CHAR, 10$ $QIOW_S FUNC = #IO$_SETMODE,- CHAN = CHANNEL,- P1 = TERMINAL_CHAR 10$: $DASSGN_S CHAN = CHANNEL ;force immediate image rundown $EXIT_S R0 RET .PAGE .SUBTITLE RESET UCBS RESET_UCBS: MOVL TARGET_UCB_ADDRESS, R2 MOVL NPP_ADDRESS, R0 MTPR IPL_TWENTY_ONE, S^#PR$_IPL MOVL PUTNXT_ADDRESS, UCB$L_TT_PUTNXT(R2) MOVL GETNXT_ADDRESS, UCB$L_TT_GETNXT(R2) MOVL PORT_ADDRESS, UCB$L_TT_PORT(R2) MOVW TARGET_UCB_PRTCTL, UCB$W_TT_PRTCTL(R2) MTPR #2, S^#PR$_IPL JSB G^EXE$DEANONPAGED MTPR #0, S^#PR$_IPL ;clear specified rundown routine MOVL USER_RUNDOWN_ADDRESS, G^CTL$GL_USRUNDWN BRB AROUND_1 IPL_TWENTY_ONE: .BYTE 21 AROUND_1: RSB .END OBSERVE ------
LEICHTER-JERRY@YALE.ARPA.UUCP (12/18/86)
WARNING!!! This program can crash your system! OBSERVE is a clever little piece of code that interposes itself between the port and class drivers of a target terminal and copies all outgoing characters directly to the terminal it was run on. For OBSERVE to work, it must under- stand the kind of port driver being used, and further the same port driver must be used on both the target and observing terminals. In practice, the program understands the DZ11 and DMF32 port drivers. Unfortunately, it makes a rather simple test to determine which of the two it is dealing with: It looks at the second byte of the terminal's device name. If that byte is "X", the DMF32 code is used; otherwise, the DZ11 code is used. For example, if you try it out using a VAXStation emulated window - device name WTAn: - you'll get a quick crash. (At least I did.) I'm willing to bet that the same thing will happen with LAT terminals (LTAn) or a DECnet remote terminal (RTAn). I don't know what will happen with other terminal hardware, such as the DZ32, though I think the port drivers for the DZ32 and DZ11 are the same, so that particular one should work. It's also not obvious that the code will work if virtual terminals are enabled. Since it WON'T run on my VAXStation - which has no "real" terminals - I can't test any of this out; I'm not willing to crash our 8600 just for the heck of it. So, I can only guess based on a quick reading of sparsely-commented code. Other things to know about OBSERVE: - I suspect that typing CTRL/S while observing a terminal that's producing a lot of output can cause a crash as various buffers overflow. - It is hard-wired to assume VT100-compatible terminals, only, though nothing really terrible will happen on others. - It has hard-coded in a variety of assumptions about the inards of the terminal driver. Hence, it stands a good chance of dying as new versions of VMS come out. Further, given its nature, any time OBSERVE dies, it is almost certain to take the system with it. - Some of the coding isn't quite as defensive as it might be; there are some timing windows during initialization that could leave the system in a strange state. Don't type CTRL/Y while the program is starting up! - The program never bothers to lock down the kernel-mode, elevated-IPL code it runs during initialization; a page fault in this code will cause a crash. This is quite unlikely, but possible. - If you start it via a foreign command, it will take a single argu- ment, the name of the target terminal. Otherwise, it will prompt you. - Don't bother thinking about using OBSERVE to RECORD what a terminal is doing, rather than just displaying it - that would involve a whole new approach. Take all this as a warning to be careful. Given its simplicity, it's probably the case that if OBSERVE works on a particular configuration at all, it will continue to work - i.e., if you can run it for a couple of minutes without crashing the system you should be safe. But don't make your test run during production! BTW, OBSERVE needs CMKRNL - which it will NOT enable - and must be linked against the system symbol table. (I'm being brief deliberately: If you don't know what this means, you have no business playing with this program.) -- Jerry -------
CP.PAVER@MCC.COM.UUCP (12/18/86)
Yup. It doesn't like LAT's either. Fortunately it was late at night... -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Bob Paver (512) 338-3316 Microelectronics and Computer Technology Corp. (MCC) 3500 West Balcones Center Drive Austin, TX 78759 ARPA: paver@mcc.com UUCP: {ihnp4,seismo,harvard,gatech}!ut-sally!im4u!milano!paver -------