.TITLE PHOCOM - PHONE COMMUNICATIONS .IDENT /1.1/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: PHOCOM.MAC ; Author: Robin Miller ; Date: August 17, 1982 ; ; Description: ; ; This module does the communications between the PHONE programs. ; ; Modification History: ; ; Version 1.1 November 18, 1982 by Gary Larsen ; Modified startup and receive ast routines to clean out the ; receive queue so the next AST would be posted. ; ;- .ENABL AMA .NLIST BEX .MCALL ASTX$S, RCVD$S, SDAT$S, SRDA$S, USTP$S ; Local buffers: R.NAME = 0 ; OFFSET TO TASK NAME R.CODE = 4 ; OFFSET TO COMMAND CODE R.TNUM = 6 ; OFFSET TO TERMINAL NUMBER S.CODE = 0 ; OFFSET FOR COMMAND CODE S.TNUM = 2 ; OFFSET FOR TERMINAL NUMBER RECBUF::.BLKW 15. ; STORAGE FOR RECEIVE DATA SNDBUF::.BLKW 13. ; BUFFER TO SEND MESSAGE CMDCOD = SNDBUF+S.CODE ; ADDRESS TO STORE COMMAND CODE ; Command codes: C.ANS = 1 ; ANSWER COMMAND CODE C.GO = 2 ; GO COMMAND CODE C.HANG = 3 ; HANGUP MESSAGE CODE C.REJ = 4 ; REJECT MESSAGE CODE C.WAIT = 5 ; WAITING MESSAGE CODE C.BUSY = 6 ; BUSY MESSAGE CODE C.ABO = 7 ; ABORT MESSAGE CODE ENDCMD = 7 ; LAST COMMAND CODE ; Dispatch table for received commands. RECTBL: .WORD 0 ; SHOULD NEVER GET HERE .WORD RECANS ; PHONE ANSWERED MESSAGE .WORD RECGO ; GO AHEAD MESSAGE .WORD RECHNG ; HANGUP PHONE MESSAGE .WORD RECREJ ; PHONE CALL REJECTED .WORD RECWAT ; SOMEONE IS WAITING .WORD RECBSY ; PHONED TERMINAL IS BUSY .WORD RECABO ; DIALING TERMINAL ABORTED .SBTTL ARMREC - ARM THE RECEIVE DATA AST ;+ ; ; ARMAST - Specify the receive data AST. ; ; This routine simply arms the receive data AST. ; ; Inputs: ; None ; ; Outputs: ; C bit clear/set = directive success/failure. ; ;- ARMREC:: SRDA$S #RECAST ; SPECIFY THE AST ADDRESS CALL DOCMD ; SEE IF THERE ARE ANY COMMANDS (01) RETURN .SBTTL RECAST - PROCESS A RECEIVE DATA AST ;+ ; ; RECAST - Process a receive data AST. ; ; This routine is called by the Executive when data has been sent to us. ; We in turn will receive the data, parse the command, and process it. ; ;- RECAST::CALL DOCMD ; PROCESS THE RECEIVED COMMAND ASTX$S ; EXIT THE AST ROUTINE DOCMD:: CALL $SAVAL ; SAVE ALL REGISTERS 10$: RCVD$S ,#RECBUF ; RECEIVE A DATA BLOCK BCC 20$ ; IF CC, WE GOT SOMETHING (01) CMP $DSW,#IE.ITS ; IS THE ERROR "QUEUE EMTPY" ? (01) BEQ 100$ ; IF EQ, YES (EXPECT THIS) (01) SEC ; SHOW THERE WAS AN ERROR (01) CALL CHKDIR ; REPORT THE DIRECTIVE ERROR BR 100$ ; AND RETURN ... (01) ; Check for the correct task name. 20$: MOV #RECBUF,R0 ; ADDRESS OF RECEIVED DATA ; Dispatch on the command code. ; R0 = address of the receive buffer. MOV R.CODE(R0),R1 ; COPY THE COMMAND CODE BEQ 100$ ; IF EQ, INVALID COMMAND CODE CMP R1,#ENDCMD ; IS THE CODE IN RANGE ? BHI 100$ ; IF HI, NO (IGNORE IT) ASL R1 ; MAKE R0 A WORD INDEX CALL @RECTBL(R1) ; CALL APPROPRIATE ROUTINE BR 10$ ; SEE IF THE QUEUE IS EMPTY (01) 100$: RETURN .SBTTL RECMSG - PROCESS RECEIVE MESSAGES ;+ ; ; RECABO - Process an abort message. ; ; Inputs: ; R0 = address of the received buffer. ; ;- RECABO::BIC #B.WAIT,STATUS ; NO ONE IS WAITING NOW MOV R.TNUM(R0),R1 ; COPY THE BINARY UNIT NUMBER MOV #NWAITM,R0 ; ADDRESS TO STORE TTY NAME CALL MAKTTY ; GO MAKE THE ASCII NAME ERRMSG NWAITM, RETURN ;+ ; ; RECANS - Process an answer message. ; ;- RECANS::BIS #B.ANS,STATUS ; SHOW PHONE WAS ANSWERED BIC #B.WAIT,STATUS ; WE ARE NO LONGER WAITING CALL CANMRK ; CANCEL THE MARK TIME CALL WRITTO ; WRITE THE PHONED TERMINAL ERRMSG ANSM, RETURN ;+ ; ; RECBSY - Process a BUSY message (sent back from WAIT message). ; ;- RECBSY::CALL CANMRK ; CANCEL THE MARK TIME BIC #B.DIAL,STATUS ; SHOW WE'VE BEEN REJECTED ERRMSG RBSYM, RETURN ;+ ; ; RECGO - Process a GO command (response to ANSWER message). ; ;- RECGO:: BIS #B.ANS,STATUS ; SHOW OUR ANSWER WAS RECEIVED CALL WRITTO ; WRITE THE TERMINAL NAME ERRMSG GOOM, USTP$S #TNAME ; UNSTOP OUR TASK NAME RETURN ;+ ; ; RECHNG - Process a HANGUP command. ; ; This routine is entered when ever the phone is hung up. If we are ; not hungup, then we send a hangup message to let the other phoner ; know we have received the hangup message. Otherwise, if we sent ; the hangup message, we are already hungup, we don't send another ; hangup message as that would cause us to loop forever. ; ;- .ENABL LSB RECHNG::BIT #B.HANG,STATUS ; DID WE SEND THE HANGUP MSG ? BEQ 10$ ; IF EQ, NO CALL CLRBOT ; CLEAR BOTTOM OF SCREEN ERRMSG HUNGM, BR 20$ ; AND CONTINUE ... 10$: CALL SNDHNG ; TELL THEM WE'RE HUNGUP BIC #B.ANS!B.WAIT,STATUS ; ALLOWED TO ANSWER PHONE BIS #B.HANG,TOTBL ; SHOW WHICH TERMINAL HUNGUP BIS #B.HANG,STATUS ; SHOW SOMEONE HUNGUP CALL CLRBOT ; CLEAR BOTTOM OF SCREEN ERRMSG RHUNGM, 20$: USTP$S #TNAME ; UNSTOP OUR TASK RETURN .DSABL LSB ;+ ; ; RECREJ - Process a REJECT command. ; ;- .ENABL LSB RECREJ::BIT #B.DIAL,STATUS ; ARE WE DIALING ANYONE ? BEQ 10$ ; IF EQ, NO (IGNORE REQUEST) BIC #B.DIAL!B.ONL,STATUS ; SHOW WE'VE BEEN REJECTED ERRMSG REJM, CALL CANMRK ; CANCEL THE MARK TIME 10$: RETURN .DSABL LSB ;+ ; ; RECWAT - Process a WAITing message. ; ; Inputs: ; R0 = the address of the received buffer. ; ;- RECWAT::BIT #B.ANS,STATUS ; ARE WE ALREADY TALKING ? BNE SNDBSY ; IF NE, YES (SEND BUSY MESSAGE) MOV #TOTBL,R3 ; ADDRESS OF PHONED ENTRY MOV R.NAME(R0),O.TASK(R3) ; SAVE FIRST PART OF TASK NAME MOV R.NAME+2(R0),O.TASK+2(R3) ; NOW THE SECOND PART MOV R.TNUM(R0),O.TNUM(R3) ; SAVE THE TERMINAL NUMBER BIS #B.WAIT,STATUS ; SHOW SOMEONE IS WAITING MOV #WAITM,R0 ; ADDRESS TO STORE TTY NAME MOV O.TNUM(R3),R1 ; COPY THE BINARY UNIT NUMBER CALL MAKTTY ; GO MAKE THE ASCII NAME ERRMSG WAITM, CALL CANMRK ; CANCEL THE MARK TIME RETURN ; Send the phoning terminal a BUSY message. The received buffer ; has the senders task name in the first two words. SNDBSY::JSR R2,$SAVVR ; SAVE R0 - R2 MOV #RECBUF,R2 ; POINT TO DATA PORTION MOV #C.BUSY,R.CODE(R2) ; SETUP THE COMMAND CODE MOV #SBSYM,R0 ; ADDRESS TO STORE TTY NAME MOV R.TNUM(R2),R1 ; COPY THE TERMINAL NUMBER CALL MAKTTY ; MAKE THE ASCII TERMINAL NAME ERRMSG SBSYM, BIC #B.MSG,STATUS ; ENSURE MESSAGE IS LEFT ON SCREEN MOV TITBL+O.TNUM,R.TNUM(R2) ; COPY OUR TERMINAL NUMBER SDAT$S #RECBUF,#RECBUF+R.CODE ; SEND THE REJECT MESSAGE RETURN .SBTTL SNDMSG - SEND PHONE MESSAGES ;+ ; ; SNDABO - Send the ABORT message. ; ; This message is sent from the DIALing terminal when aborting because the ; phoned terminal (which is ONLINE) is not ANSWERing. ; ;- SNDABO::BIT #B.ONL,STATUS ; IS THE PHONED TERMINAL ONLINE ? BEQ 10$ ; IF EQ, NO (IGNORE REQUEST) MOV #C.ABO,CMDCOD ; SETUP THE COMMAND CODE BIC #B.ONL,STATUS ; CLEAR THE ONLINE BIT JMP SENDIT ; AND SEND THE ABORT MESSAGE 10$: RETURN ;+ ; ; SNDANS - Send the ANSWER message. ; ; This message is sent by the ANSWERing terminal in response to a DIAL. ; ;- SNDANS::MOV #C.ANS,CMDCOD ; SETUP THE COMMAND CODE BIC #B.WAIT,STATUS ; NO LONGER IN WAIT STATE JMP SENDIT ; AND GO SEND IT ;+ ; ; SNDGO - Send the GO message. ; ; This message is sent by the DIALer to let the phoned terminal know ; that the ANSWER message was received and we are ready to talk. ; ;- SNDGO:: MOV #C.GO,CMDCOD ; SETUP THE COMMAND CODE JMP SENDIT ; AND GO SEND IT ;+ ; ; SNDHNG - Send the HANGUP message. ; ; This message is send to the other phoner when we hangup the phone. ; ;- SNDHNG::BIT #B.ANS,STATUS ; DO WE NEED TO HANGUP ? BEQ 10$ ; IF EQ, NO BIC #B.ANS!B.WAIT,STATUS ; SHOW WE ARE HUNGUP NOW MOV #C.HANG,CMDCOD ; SETUP THE COMMAND CODE JMP SENDIT ; AND GO SEND IT 10$: RETURN ;+ ; ; SNDREJ - Send the REJECT message. ; ; This message is sent to tell the dialer you don't wish to talk right now. ; ;- SNDREJ::JSR R2,$SAVVR ; SAVE R0 - R2 ERRMSG SREJM, BIC #B.WAIT,STATUS ; NOBODY IS WAITING FOR US MOV #C.REJ,CMDCOD ; SETUP THE COMMAND CODE JMP SENDIT ; AND GO SEND IT ;+ ; ; SNDWAT - Send the WAITing mesage. ; ; This message is sent from DIAL to determine it the phoned terminal ; already has PHONE active. This will prevent us from doing a broadcast ; to that terminal if it is active which screws up the phone screen. ; ;- SNDWAT::CLC ; RETURN SUCCESS FOR "BIT" BIT #B.ANS,STATUS ; HAVE WE ALREADY BE ANSWERED ? BNE 10$ ; IF NE, YES (GO TALK) BIT #B.ONL,STATUS ; HAVE WE ALREADY SENT WAIT MSG ? BNE 10$ ; IF NE, YES (DON'T DOIT AGAIN) MOV #C.WAIT,CMDCOD ; SETUP THE COMMAND CODE MOV TITBL+O.TNUM,SNDBUF+S.TNUM ; COPY OUR TERMINAL NUMBER SDAT$S #TOTBL+O.TASK,#SNDBUF ; SEND THE COMMAND CODE BCS 10$ ; IF CS, PRESUME NOT THERE BIS #B.ONL,STATUS ; ELSE, SHOW THEY'RE ONLINE 10$: RETURN ;+ ; ; SENDIT - Send the command code the the other PHONE program. ; ; The PHONE program must be run under the task name PHOTnn (where 'nn' ; is the terminal name) for the send data directive to work. The task ; name is constructed when either a DIAL or ANSWER command is processed ; using this convention so we know where to send the data. Unfortunatly, ; the first copy of the installed PHONE task (...PHO) gets starts with ; the prototype task name (...PHO). Subsequent PHONEs are started with ; the above naming convention (PHOTnn). Ideally, you want to start PHONE ; using the RPOI$ directive from a CLI and specify the above task name. ; Unfortunatly, only a CLI task can specify a different task name. ; ; Inputs: ; CMDCOD = setup with the command code to send. ; ; Outputs: ; All registers are preserved. ; ;- SENDIT::MOV TITBL+O.TNUM,SNDBUF+S.TNUM ; COPY OUR TERMINAL NUMBER SDAT$S #TOTBL+O.TASK,#SNDBUF ; SEND THE COMMAND CODE CALL CHKDIR ; CHECK/REPORT DIRECIVE ERRORS RETURN .END