// CHAT.BCPL - Bob Sproull - Pup User Telnet - BCPL // Copyright Xerox Corporation 1979, 1980 // modified: September 26, 1980 5:21 PM (E. Taft) get "Chat.d" get "ChatBSP.d" get "SysDefs.d" get "BcplFiles.d" //outgoing procedures: external [ Sti SendMarkData BigStack SmallStack CheckShiftSwat SendScreenParams ] //incoming procedures external [ ChatReadParams ChatComInit ChatTTY ChatDIS ChatDISInit //BSP BSPPutMark //OS Puts CallersFrame GotoLabel EnableInterrupts DisableInterrupts Junta MyFrame InitializeZone MoveBlock //ALTOTIME SetTimer TimerHasExpired //CONTEXT CallContextList //EtherBoot EtherBoot ] //global statics external [ //Chat state Parm //vector of structure PARM ctxQ //List of processes Running //0 => stopped; 1 => running; 2=> please quit makeBootFile //Connections: TTYSoc //Telnet Socket TTYStr // (stream version) DISSoc //Display protocol socket DISStr //Screen ScreenBuffer //Buffer to use. ScreenBufferLength // and its length YMax //Free storage stuff ChatZone //Normal zone ChatZoneSize ComZone //For communications stuff (below code!) ComZoneLeft ] static [ Parm ctxQ Running = 0 savedUFP makeBootFile TTYSoc TTYStr DISSoc DISStr ScreenBuffer ScreenBufferLength YMax=YMaxDefault ChatZone ChatZoneSize ComZone ComZoneLeft ] //incoming statics external [ OsBuffer UserName UserPassword lvUserFinishProc lvAbortFlag ] // local statics static [ bigStack saved335 savedFrame ] manifest kbdAd = #177034 let CHAT(blv) be [CHAT //First, set up parm vector and read parameters in: Parm=#1000 bigStack=#1000+lPARM ChatReadParams(Parm) //Now start up communications stuff: savedUFP = @lvUserFinishProc @lvUserFinishProc = ChatHandleFinish let zoneFirst=#1000+lPARM+bigStackSize ChatComInit(zoneFirst, blv>>BLV.startOfStatics-zoneFirst-1) //Now decide which of the two "programs" we are running! if Parm>>PARM.DisplayProtocol then [ //Display -- move display code down over TTY and Init code: let len=@#335-ChatDIS+2 MoveBlock(ChatTTY, ChatDIS, len) let dif=ChatDIS-ChatTTY let p=blv>>BLV.relPairTable for i=1 to p!0 do [ @(p!1)=@(p!1)-dif //Relocate statics p=p+2 ] Junta(levKeyboard, ChatDISInit) ] //Must be simple TTY if we ever get here!! ChatTTY() //Go do the work! ]CHAT and ChatHandleFinish() be if makeBootFile then EtherBoot(10B) // NetExec and CheckShiftSwat() be // Note: do not simply "abort" here, because when the OS "finish" code // re-enables shift-swat aborts, the abort will take a second time // and may cause the OS initialization to malfunction. if kbdAd!2 eq #177677 & (kbdAd!3 & #177577) eq #177573 then [ if makeBootFile then abort // do not want OS to see this @lvAbortFlag = @lvAbortFlag-1 for i = 1 to 10000 do loop @lvAbortFlag = @lvAbortFlag+1 ] //SendMarkData(soc, markbyte, databyte) // Sends a mark of type "markbyte", optionally followed by a single // data byte "databyte" and SendMarkData(S, markbyte, data; numargs n) be [ BSPPutMark(S, markbyte) if n gr 2 then Puts(lv S>>BSPSoc.bspStr, data) ] and SendScreenParams(Soc) be [SSP SendMarkData(Soc, MarkPageLength, Parm>>PARM.ScreenLines) //Page length SendMarkData(Soc, MarkTerminalType, #12) //Terminal type scope SendMarkData(Soc, MarkLineWidth, Parm>>PARM.ScreenChars) //Line width ]SSP // Sti(byte1) -- stuff the character in the type-in buffer! and Sti(c) be [STI DisableInterrupts() let oldIn=OsBuffer>>OsBUF.In let newIn=oldIn+1 if newIn eq OsBuffer>>OsBUF.Last then newIn=OsBuffer>>OsBUF.First if newIn ne OsBuffer>>OsBUF.Out then [ @oldIn=c OsBuffer>>OsBUF.In=newIn ] EnableInterrupts() ]STI // Routines for letting procedures run in a bigger-than-usual // stack. Users must beware that no Blocks() are done within // the big stack, because another process may use the same stack. // Note: local variables are not the same (accessible) after a call // on BigStack. // Both BigStack and SmallStack return their arguments. and BigStack(val) be [BS savedFrame=CallersFrame() //Including return address let cfsize=(savedFrame!0)-savedFrame saved335=@#335 @#335=bigStack GotoLabel(bigStack+bigStackSize-cfsize, savedFrame!1+1, val) ]BS and SmallStack(val) be [SS let l=CallersFrame() @#335=saved335 GotoLabel(savedFrame, l!1+1, val) ]SS