; ; 13/9/99 ; ; Prevent overrun if more than 8 digis specified on connect cmd ; PAGE 56,132 ; DATA SEGMENT PUBLIC 'DATA' INCLUDE ENVIRON.ASM INCLUDE STRUCS.ASM IFDEF KANT INCLUDE KANTEQU.ASM SYSOP EQU 1 ENDIF IFDEF MSC ; INCLUDE KANTEQU.ASM SYSOP EQU 1 ENDIF IFDEF SWITCH SYSOP EQU 1 ENDIF IFDEF OS2 SYSOP EQU 1 ENDIF EXTRN SAVEPORT:BYTE PUBLIC APPLMASK,SAVEDAPPLFLAGS,D10,SESSIONHDDR,SESSHDDRLEN PUBLIC CMDALIAS,ALIASPTR,COMMANDLIST EXTRN BBS:BYTE,NODE:BYTE,LINKEDFLAG:BYTE EXTRN L3INTERVAL:BYTE,L4T1:WORD,L4N2:BYTE,L3LIVES:BYTE,L4LIMIT:WORD EXTRN L2KILLTIME:WORD,MYLINKCALL:BYTE EXTRN L4DEFAULTWINDOW:BYTE,HEADERCHAR:BYTE EXTRN PORTTABLE:WORD,NUMBEROFPORTS:BYTE,COMPAREPORT:BYTE EXTRN LINKS:WORD,MAXLINKS:WORD EXTRN DESTS:WORD,MAXDESTS:WORD,ENDDESTLIST:WORD EXTRN NEIGHBOURS:WORD,MAXNEIGHBOURS:WORD EXTRN L4TABLE:WORD,MAXCIRCUITS:WORD,ROUTEQUAL:BYTE IFDEF PCSWITCH EXTRN BPQHOSTVECTOR:BYTE,BPQVECLENGTH:BYTE ENDIF PUBLIC APPLS IF TNC2 EXTRN TNCTABLE:WORD,NUMBEROFSTREAMS:WORD ENDIF EXTRN INFOMSG:WORD,INFOLEN:WORD,DESTHEADER:WORD EXTRN BBS:BYTE,PACLEN:WORD EXTRN OBSINIT:BYTE,OBSMIN:BYTE,L4N2:BYTE EXTRN T3:BYTE,LINKEDFLAG:BYTE,IDINTERVAL:BYTE,MINQUAL:BYTE EXTRN FULL_CTEXT:BYTE,HIDENODES:BYTE,L4DELAY:BYTE EXTRN BTINTERVAL:BYTE IFDEF MSC EXTRN HOURS:BYTE,MINS:BYTE,SECS:BYTE ENDIF D1093 DW 1093 CR EQU 0DH LF EQU 0AH CMDX STRUC DB ' ' ; COMMAND STRING CMDLEN DB ? ; SIGNIFICANT LENGTH CMDPROC DW ? ; COMMAND PROCESSOR IFDEF SYSOP CMDFLAG DW ? ; FLAG/VALUE ADDRESS ENDIF CMDX ENDS COMMANDLIST LABEL BYTE IFDEF SYSOP ; ; SYSOP COMMANDS ; IFDEF SWITCH CMDX <'SAVENODES',8,SAVENODES> ENDIF CMDX <'SENDNODES',8,SENDNODES> CMDX <'TXDELAY',3,PORTVAL,PORTTXDELAY> CMDX <'MAXFRAME',3,PORTVAL,PORTWINDOW> CMDX <'RETRIES',3,PORTVAL,PORTN2> CMDX <'FRACK',3,PORTVAL,PORTT1> CMDX <'RESPTIME',3,PORTVAL,PORTT2> CMDX <'PPACLEN',3,PORTVAL,PORTPACLEN> CMDX <'QUALITY',3,PORTVAL,PORTQUALITY> CMDX <'PMINQUAL',3,PORTVAL,PORTMINQUAL> CMDX <'PERSIST',2,PORTVAL,PORTPERSISTANCE> CMDX <'TXTAIL',3,PORTVAL,PORTTAILTIME> CMDX <'XMITOFF',7,PORTVAL,PORTDISABLED> CMDX <'DIGIFLAG',5,PORTVAL,DIGIFLAG> CMDX <'DIGIPORT',5,PORTVAL,DIGIPORT> CMDX <'MAXUSERS',4,PORTVAL,USERS> CMDX <'L3ONLY',6,PORTVAL,PORTL3FLAG> CMDX <'BBSALIAS',4,PORTVAL,PORTBBSFLAG> CMDX <'VALIDCALL',5,VALNODES> IF BLACKBITS CMDX <'EXCLUDE',5,DISPBLACKLIST> ENDIF CMDX <'CLOCK',5,DISPCLOCK> CMDX <'COLDSTART',9,COLDSTART> CMDX <'WARMSTART',9,WARMSTART> CMDX <'FULLDUP',4,PORTVAL,FULLDUPLEX> CMDX <'SOFTDCD',4,PORTVAL,SOFTDCDFLAG> CMDX <'REMDUMP',7,REMDUMP> ; CMDX <'OBSINIT',7,SWITCHVAL,OBSINIT> CMDX <'OBSMIN',6,SWITCHVAL,OBSMIN> CMDX <'NODESINT',8,SWITCHVAL,L3INTERVAL> CMDX <'L3TTL',5,SWITCHVAL,L3LIVES> CMDX <'L4RETRIES',5,SWITCHVAL,L4N2> CMDX <'L4TIMEOUT',5,SWITCHVALW,L4T1> CMDX <'T3',2,SWITCHVAL,T3> CMDX <'IDLETIME',8,SWITCHVALW,L4LIMIT> CMDX <'LINKEDFLAG',10,SWITCHVAL,LINKEDFLAG> CMDX <'IDINTERVAL',5,SWITCHVAL,IDINTERVAL> CMDX <'MINQUAL',7,SWITCHVAL,MINQUAL> CMDX <'FULLCTEXT',6,SWITCHVAL,FULL_CTEXT> CMDX <'HIDENODES',8,SWITCHVAL,HIDENODES> CMDX <'L4DELAY',7,SWITCHVAL,L4DELAY> CMDX <'L4WINDOW',6,SWITCHVAL,L4DEFAULTWINDOW> CMDX <'BTINTERVAL',5,SWITCHVAL,BTINTERVAL> ; PASSWORD MUST BE LAST ; PASSCMD CMDX <'PASSWORD',8,PWDCMD> ENDIF APPL1 LABEL BYTE APPLS CMDX <'***********',12,APPLCMD> HOSTCMD CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'***********',12,APPLCMD> CMDX <'*** LINKED',10,LINKCMD> CQCALL CMDX <'CQ ',2,CQCMD> CMDX <'CONNECT',1,CMDC00> CMDX <'BYE',1,BYECMD> CMDX <'INFO',1,CMDI00> CMDX <'LINKS',1,CMDL00> CMDX <'L4T1',2,CMDT00> CMDX <'NODES',1,CMDN00> CMDX <'PORTS',1,CMDP00> CMDX <'PACLEN',3,CMDPAC> CMDX <'ROUTES',1,CMDR00> CMDX <'STATS',1,CMDSTATS> CMDX <'USERS',1,CMDS00> CMDX <'?',1,CMD?00> CMDX <'DUMP',4,DUMPCMD> CMDX <'MHEARD',1,MHCMD> NUMBEROFCOMMANDS EQU ($-COMMANDLIST)/TYPE CMDX CMDERRMSG DB 'Invalid command - Enter ? for command list',0dh CMDERRLEN EQU $-CMDERRMSG NEEDMH DB 0 CMDLIST DB 'CONNECT BYE INFO NODES PORTS ROUTES USERS MHEARD' CMDLISTLEN EQU $-CMDLIST CMDALIAS DB 8 * 16 DUP (0) ; ALIASES FOR ALLP COMMANDS ALIASPTR DW OFFSET CMDALIAS TABLESFULL DB 'Sorry - System Tables Full!',0dh TABLESFULLLEN EQU $-TABLESFULL INVALIDCALL DB 'Invalid callsign',0dh INVCALLLEN EQU $-INVALIDCALL INVALIDWIND DB 'Invalid window',0dh INVWINDLEN EQU $-INVALIDWIND INVALIDPORT DB 'Invalid port',0dh INVPORTLEN EQU $-INVALIDPORT L3INVALIDPORT DB 'Sorry, port is for internode traffic only',0dh L3INVPORTLEN EQU $-L3INVALIDPORT T4MSG DB 'L4 timeout - ' T4MSGLEN EQU $-T4MSG PACMSG DB 'PACLEN - ' PACMSGLEN EQU $-PACMSG OKMSG DB 'Ok',0DH BADVALUEMSG DB 'Invalid parameter',0DH BADVALLEN EQU $-BADVALUEMSG IFDEF SYSOP PASSWORDMSG DB 'Command requires SYSOP status - enter password',0DH LPASSMSG EQU $-PASSWORDMSG ENDIF PORTHDDR DB 'Ports:',0dh NODEHDDR DB 'Nodes:',0dh ROUTEHDDR DB 'Routes:',0dh NOTFOUNDMSG DB 'Not found',0DH NODEROUTEHDDR DB 'Routes to: ' USERHDDR DB 'Links:',0DH MHHDDR DB 'Heard List for Port ' MHERRMSG DB 'Error - format is MH portnum',0dh MHERRLEN EQU $-MHERRMSG MHDISMSG DB 'MHEARD not enabled on that port',0dh MHDISLEN EQU $-MHDISMSG SESSIONHDDR DB NAMESTRING IFDEF OS2 DB ' Packet Switch for OS/2 V' ELSE IFDEF SYSOP ; SWITCH OR KANT DB ' Packet Switch V' ELSE DB ' Network System V' ENDIF ENDIF DB VERSIONSTRING,' (' SESSHDDRLEN EQU $-SESSIONHDDR UPLNKMSG DB 'Uplink' DOWNLNKMSG DB 'Downlink' CROSSLNKMSG DB 'Circuit' HOSTLNKMSG DB 'Host' CLOSINGMSG DB '(Closing) ' CONNECTEDMSG DB 'Connected to ' LCONNECTEDMSG EQU $-CONNECTEDMSG DISCONNMSG DB '*** DISCONNECTED',0DH LDISCONNMSG EQU $-DISCONNMSG NOFREEPORTS DB 'Sorry, All ' DB 'Ports are in use - Please try later',CR NOFREEPORTSLEN EQU $-NOFREEPORTS HOSTBUSYMSG DB 'HOST ' IF TNC2 DB 'not available',cr HOSTBUSYMSGLEN EQU $-hostbusymsg ENDIF NOPORTMSG DB 'Downlink connect needs port number - C P CALLSIGN ',cr LNOPORTMSG EQU $-NOPORTMSG CQFLAG DB 0 STAYSWITCH DB 0 ; CONNECT STRING INCLUDED S(TAY) SPYSWITCH DB 0 COMMANDBUFFER DB 80 DUP (0) ; COMMAND HANDLER INPUT BUFFER USERSBUFFER DB 40 DUP (0) ; BUFFER FOR USERS COMMAND CONNECTCALL DB 10 DUP (0) ; CALLSIGN IN CONNECT MESSAGE DIGICALL DB 10 DUP (0) ; DIGI IN CONNECT COMMAND AX25STRING DB 64 DUP (0) ; DIGI STRING IN AX25 FORMAT DIGIPTR DW 0 ; POINTER TO CURRENT DIGI IN STRING CONNECTREPLYPTR DW 0 ; BUFFER ADDR FOR CONNECT REJECT MSGS CONNECTSESSION DW 0 ; L4TABLE ENTRY FOR CONNECT COMMAND TARGETDEST DW 0 ; DESTINATION IF CROSS CONNECT CMDTAIL DW 0 ; POINTER TO REST OF BUFFER CONNECTPORT DB 0 ; PORT FOR CONNECT COMMAND APPLMASK DB 0 ; APPLICATION MASK SAVEDAPPLFLAGS DB 0 CMDPTR DW 0 ; NAME OF COMMAND NSTAR DB 0 ; SET IF NODES * INPUT RPORT DB 0 ; PONT NUM FOR SELCTIVE ROUTES REPLYBUFFER DW 0 ; ADDRESS OF COMMAND HANDLER REPLY BUFFER SAVELINK DW 0 ; CURRENT LINK ; CMDPACLEN DW 0 ; CURRENT PACLEN TEMPFIELD DB 7 DUP (0) ; TEMP STORAGE FOR CALL VALUE DW 0 ; PARAM VALUE DECODEDNAME DB 20 DUP ('*') ; CALL IN ALIAS:CALL FORMAT STATS DB 'Time active (mins) ' db 1 STATSTIME DD 0 IFDEF PCSWITCH db 'Timer Overruns ' db 1 TIMOVERRUNS DD 0 ELSE db 'Warm Restarts ' db 1 RESTARTS DD 0 ENDIF db 'Buffers: Max/Cur/Min/Out ' DB 4 MAXBUFFS DD 0 QCOUNT DB 0,0,0,0 MINBUFFCOUNT DB 255,0,0,0 NOBUFFCOUNT DD 0 DB 'Known Nodes ' DB 1 NUMBEROFNODES DW 0,0 db 'L4 Connects Sent/Rxed ' db 2 L4CONNECTSOUT DD 0 L4CONNECTSIN DD 0 DB 'L4 Frames TX/RX/Resent/Reseq' DB 4 L4FRAMESTX DD 0 L4FRAMESRX DD 0 L4FRAMESRETRIED DD 0 OLDFRAMES DD 0 db 'L3 Frames Relayed ' db 1 L3FRAMES DD 0 DB 0 STATSLEN EQU 28 L2STATS db 'L2 Frames Digied' DW L2DIGIED db 'L2 Frames Heard ' DW L2FRAMES db 'L2 Frames Rxed ' DW L2FRAMESFORUS db 'L2 Frames Sent ' DW L2FRAMESSENT db 'L2 Timeouts ' DW L2TIMEOUTS db 'REJ Frames Rxed ' DW L2REJCOUNT db 'RX out of Seq ' DW L2OUTOFSEQ db 'L2 Resequenced ' DW L2RESEQ db 'Undrun/Poll T-O ' DW L2URUNC db 'RX Overruns ' DW L2ORUNC db 'RX CRC Errors ' DW RXERRORS DB 'FRMRs Sent ' DW L2FRMRTX DB 'FRMRs Received ' DW L2FRMRRX DB 'Frames abandoned' DW L1DISCARD DB 'Link Active % ' DW AVSENDING L2STATSLEN EQU 16 PORTSTATS EQU 15 PORT DB ' Port' STATCMDCOUNT DW 0 STATCMDPTR DW 0 CMDSTACKP DW 0 ; STACK POINTER ON ENTRY - USED TO ABORT ; COMMAND IF NO BUFFERS LEFT D10 DB 10 D100 DB 100 W10 DW 10 IFDEF DOS TICKDIV DW 11 ENDIF IFDEF OS2 TICKDIV DW 20 ENDIF D60 DW 60 W18 DW 18 W16 DW 16 B19 DB 19 W32 DW 32 ; ; POWERS OF 10 - 8 4-BYTE NUMBERS FROM 100,000,000 TO 10 ; POWERS DD 100000000 DD 10000000 DD 1000000 DD 100000 TENK DD 10000 DD 1000 WORD100 DD 100 DWORD10 DD 10 ; ACCUM DB 4 DUP (0) CONVFLAG DB 0 SUPPRESS DB 0 ; ZERO SUPPRESS FLAG IF BLACKBITS PUBLIC BLACKLIST BLACKLIST DB 71 DUP (0) ; 10 ENTRIES, 7 BYTES EACH BLACKEND DW BLACKLIST ; KEEP JUST AFTER LIST ENDIF PUBLIC L4FRAMESTX,L4FRAMESRX,MINBUFFCOUNT,NOBUFFCOUNT,MAXBUFFS PUBLIC L4FRAMESRETRIED,L4CONNECTSIN,L4CONNECTSOUT,STATSTIME,NEEDMH PUBLIC L3FRAMES,QCOUNT,STATSTIMER,NUMBEROFNODES EXTRN MYCALL:BYTE,AX25CALL:BYTE,NORMCALL:BYTE,NEXTID:BYTE EXTRN BUFFER:WORD,BBSCALL:BYTE,HEXOUT:NEAR PUBLIC OLDFRAMES IFNDEF PCSWITCH PUBLIC RESTARTS ELSE PUBLIC TIMOVERRUNS ENDIF DATA ENDS CODE SEGMENT PUBLIC 'CODE' ASSUME CS:CODE,DS:DATA,ES:DATA ; PUBLIC COMMANDHANDLER,CONVBIGNUMBER,COUNTNODES PUBLIC CONVTODIGITS,SETUPNODEHEADER,DECODENODENAME,CONV_DIGITS EXTRN FINDDESTINATION:NEAR,FINDDESTALIAS:NEAR,SENDSABM:NEAR EXTRN Q_ADD:NEAR,GETBUFF:NEAR,RELBUFF:NEAR,COMPARECALLS:NEAR EXTRN GETPORTQUALITY:NEAR,RESET2:NEAR,FINDLINK:NEAR,B2HEX:NEAR EXTRN CONVFROMAX25:NEAR,CONVTOAX25:NEAR,SENDL4CONNECT:NEAR EXTRN Q_REM:NEAR,GETFREECIRCUIT:NEAR,GETPORTTABLEENTRY:NEAR,SCAN:NEAR EXTRN GETPORTWINDOW:NEAR,CLOSECURRENTSESSION:NEAR,INC_ID:NEAR EXTRN SENDNODESMSG:NEAR PUBLIC DECODECALLSTRINGF IF TNC2 EXTRN SETUPCONSOLESESSION:NEAR ENDIF EXTRN ATTACHTOBBS:NEAR EXTRN FINDNEIGHBOUR:NEAR,CHAINNODE:NEAR,UNCHAINNODE:NEAR EXTRN COUNT_Q:NEAR,COUNT_AT_L2:NEAR PUBLIC DECODECALLSTRING STATSTIMER: ADD WORD PTR STATSTIME,1 ADC WORD PTR STATSTIME+2,0 ; ONCE PER MINUTE MOV SI,PORTTABLE MOV CH,0 MOV CL,NUMBEROFPORTS STATST10: MOV AX,SENDING[SI] MOV DX,0 ; PROTECT AGAINST OVERFLOW IN OS/2 IFDEF PCSWITCH DIV TICKDIV ELSE DIV D60 ENDIF MOV AVSENDING[SI],AL MOV AX,SENDING[SI] ADD AX,ACTIVE[SI] MOV DX,0 IFDEF PCSWITCH DIV TICKDIV ELSE DIV D60 ENDIF MOV AVACTIVE[SI],AL MOV SENDING[SI],0 MOV ACTIVE[SI],0 MOV SI,PORTPOINTER[SI] LOOP STATST10 RET COMMANDHANDLER: ; MOV CMDSTACKP,SP ; SAVE STACK FOR NO BUFFER RECOVERY ; ; GET PACLEN FOR THIS CONNECTION ; MOV AH,0 MOV AL,SESSPACLEN[BX] OR AX,AX JNZ PACLENOK MOV AX,PACLEN ; DONT ALLOW ZERO! PACLENOK: MOV CMDPACLEN,AX PUSH DI ; ; TRANSPORT TABLE ENTRY IN BX, MESSAGE IN DI ; LEA SI,6[DI] ; TO DATA MOV DI,OFFSET COMMANDBUFFER MOV CX,40 MOV AX,2020H REP STOSW MOV DI,OFFSET COMMANDBUFFER MOV CX,80 COMMANDDECODE00: LODSB AND AL,7FH ; MASK PARITY CMP AL,0DH JE COMMANDDECODE10 CMP AL,61H JB COMMANDDECODE05 CMP AL,7AH JA COMMANDDECODE05 SUB AL,20H COMMANDDECODE05: STOSB LOOP COMMANDDECODE00 COMMANDDECODE10: ; ; USE INPUT MESSAGE BUFFER FOR REPLY ; POP DI MOV REPLYBUFFER,DI ; ; SET UP HEADER ; MOV AL,LINKPORT[BX] ; FROM LINK TABLE MOV MSGPORT[DI],AL LEA DI,5[DI] ; SKIP HEADER MOV AL,0F0H STOSB ; PID CALL SETUPNODEHEADER PUSH DI ; SAVE REPLY BUFFER REDOCOMMAND: MOV SI,OFFSET COMMANDBUFFER ; MESSAGE ADDR CALL SCAN ; STRIP LEADING SPACES ; CMP BYTE PTR [SI],20H JE NULLCMD ; IGNORE NULL COMMAND MOV DI,OFFSET COMMANDLIST MOV CX,NUMBEROFCOMMANDS COMMANDLOOP: CMP DI,OFFSET APPL1 JNE NOTAPP1 MOV APPLMASK,1 ; FOR APPLICATION ATTACH REQUESTS MOV ALIASPTR,OFFSET CMDALIAS NOTAPP1: MOV CMDPTR,DI ; POINTER TO COMMAND NAME PUSH SI PUSH DI PUSH CX MOV CL,CMDLEN[DI] ; MIN LENGTH REP CMPSB JE COMMANDFOUND POP CX POP DI POP SI TRYNEXT: SHL APPLMASK,1 ADD ALIASPTR,16 ADD DI,TYPE CMDX LOOP COMMANDLOOP POP DI INVALIDCMD: INC BADCOMMANDS[BX] CMP BADCOMMANDS[BX],6 JE FORCEDISC ; TOO MANY ERRORS MOV SI,OFFSET CMDERRMSG MOV CX,CMDERRLEN REP MOVSB JMP SENDCOMMANDREPLY NULLCMD: POP DI NOREPLY: MOV DI,REPLYBUFFER CALL RELBUFF RET BYECMD: FORCEDISC: MOV DI,REPLYBUFFER CALL RELBUFF MOV STAYFLAG[BX],0 CALL CLOSECURRENTSESSION RET COMMANDFOUND: CMP BYTE PTR [SI],' ' JE ENDOFCOMMAND CMPSB JE COMMANDFOUND ; LOOP TILL ALL COMPARED OR END ; ; END OF STRING WRONG ; POP CX POP DI POP SI JMP TRYNEXT ENDOFCOMMAND: MOV BADCOMMANDS[BX],0 ; RESET ERROR COUNT POP CX POP DI POP AX ; TO CLEAR STACK IFDEF SYSOP ; ; SEE IF SYSOP COMMAND, AND IF SO IF PASSWORD HAS BEEN ENTERED ; CMP DI,OFFSET PASSCMD JAE COMM_OK ; ; NEEDS PASSWORD FOR SYSOP COMMANDS ; CMP PASSWORD[BX],0FFFFH JNE NEEDPASS COMM_OK: MOV VALNODESFLAG,0 ; NOT VALID NODES COMMAND ENDIF MOV AX,CMDPROC[DI] ; COMMAND PROCESSOR POP DI ; COMMAND REPLY BUFFER PUSH AX RET ; ENTER COMMAND PROCESSOR - ; SI POINTS TO CHAR FOLLOWING COMMAND ; IFDEF SYSOP NEEDPASS: POP DI PASSERROR: MOV SI,OFFSET PASSWORDMSG MOV CX,LPASSMSG REP MOVSB JMP SENDCOMMANDREPLY ENDIF CMDI00: MOV SI,INFOMSG MOV CX,INFOLEN CALL MOVEANDCHECK ; CHECK FOR PACLEN JMP SENDCOMMANDREPLY BADLINK: JMP INVALIDCMD LINKCMD: ; ; PROCESS *** LINKED to CALLSIGN ; CMP LINKEDFLAG,'Y' ; UNCONDITIONAL? JE LINKOK CMP LINKEDFLAG,'A' ; APPL ONLY? JNE BADLINK ; NOT ALLOWED ; ; SEE IF HOST SESSION OR PASSWORD GIVEN ; IF TNC2 TEST L4CIRCUITTYPE[BX],HOST+BPQHOST ELSE TEST L4CIRCUITTYPE[BX],BPQHOST ENDIF JNZ LINKOK ; LET HOST DO ANYTHING IFDEF SYSOP ; CMP PASSWORD[BX],0FFFFH JE LINKOK JMP PASSERROR ; SAY NEEDS PASSWORD ELSE JMP BADLINK ENDIF LINKOK: MOV CONNECTREPLYPTR,DI ; SAVE POINTER MOV CONNECTSESSION,BX ADD SI,3 ; SKIP ' to ' CALL SCAN CMP BYTE PTR [SI],20H JE LINKC00 ; NO CALLSIGN CALL DECODECALLSTRING JZ LINKC10 ; OK LINKC00: JMP CMDC98 ; SEND 'INVALID CALL' LINKC10: LEA DI,L4USER[BX] MOV CX,7 REP MOVSB MOV SI,OFFSET OKMSG MOV DI,CONNECTREPLYPTR MOV CX,3 REP MOVSB JMP SENDCOMMANDREPLY ; CMD?00: ; ; DISPLAY AVAILABLE COMMANDS ; MOV CX,8 MOV SI,OFFSET APPLS ADDAPPLS: CMP BYTE PTR [SI],'*' JE NEXTAPPL PUSH SI CALL COPYTOSPACE MOV AL,20H STOSB POP SI NEXTAPPL: ADD SI,TYPE CMDX LOOP ADDAPPLS MOV SI,OFFSET CMDLIST MOV CX,CMDLISTLEN CMP NEEDMH,1 JE LEAVECX SUB CX,7 ; REMOVE MHEARD LEAVECX: REP MOVSB MOV AL,0DH STOSB JMP SENDCOMMANDREPLY MOVEANDCHECK: CALL CHECKBUFFER ; ALLOW BIG I MESSAGES MOVSB LOOP MOVEANDCHECK RET CMDN00: ; ; PROCESS 'NODES' MESSAGE ; MOV NSTAR,0 ; NOT N * CALL SCAN CMP BYTE PTR [SI],' ' JE CMDN01 ; ALL NODES ; IFDEF SYSOP CMP WORD PTR [SI],'DA' ; 'ADD ' JNE NOTNADD CMP WORD PTR 2[SI],' D' ; 'ADD ' JNE NOTNADD JMP NODE_ADD NOTNADD: CMP WORD PTR [SI],'ED' ; 'DEL ' JNE NOTNDEL CMP WORD PTR 2[SI],' L' ; 'ADD ' JNE NOTNDEL JMP NODE_DEL NOTNDEL: ENDIF CMP BYTE PTR [SI],'*' ; Hidden Nodes ? JE CMDN00H ; YES ; CMP WORD PTR [SI],' T' ; RTT Info ? JE CMDN00A ; YES ; JMP CMDN100 ; PROCESS ONE NODE CMDN00A: MOV NSTAR,1 CMDN00H: INC NSTAR CMDN01: MOV SI,OFFSET NODEHDDR MOV CX,7 REP MOVSB MOV SI,DESTHEADER MOV CX,0 CMDN10: CMP SI,0 JNE CMDN10A ; MORE TO GO ; ; END OF LIST ; TEST CL,3 JZ CMDN99A ; ALREADY AT END OF LINE MOV AL,0DH ; PUT N/L ON END STOSB CMDN99A: JMP SENDCOMMANDREPLY CMDN10A: CALL CHECKBUFFER CMP DEST_CALL[SI],0 JE CMDN20 ; SPARE ; PUSH SI PUSH CX PUSH BX MOV BX,SI ; SAVE LEA SI,DEST_CALL[SI] CALL DECODENODENAME ; CONVERT TO ALIAS:CALL CMP BYTE PTR [SI],'#' ; HIDDEN? JNE CMDN12 ; NO CMP NSTAR,0 JNE CMDN12 ; OK TO DISPLAY CMP HIDENODES,0 ; HIDE NODES ENABLED? JE CMDN12 ; NO ; ; HIDDEN NODE - IGNORE IT ; CMDN11: POP BX POP CX POP SI JMP SHORT CMDN20 CMDN12: ; ; SEE IF RTT DISPLAY ; CMP NSTAR,2 JNE CMDN13 ; NORMAL ; ; ONLY DISPLAY IF COUNT NZ, AND ALSO DISPLAY RTT ; CMP DEST_COUNT[BX],0 JE CMDN11 ; IGNORE CMDN13: POP BX MOV CX,19 CALL MOVEANDCHECK ; CHECK FOR PACLEN POP CX POP SI CMP NSTAR,2 JNE CMDN14 ; NORMAL PUSH BX MOV BX,SI CALL DORTT ; NEEDS BX = DEST POP BX JMP SHORT CMDN15 CMDN14: INC CX TEST CL,3 JNZ CMDN20 CMDN15: MOV AL,0DH STOSB CMDN20: MOV SI,DEST_CHAIN[SI] JMP CMDN10 DORTT: ; ; USES BX=DEST ENTRY ; MOV AX,'TR' STOSW MOV AX,'=T' STOSW ; RTT= MOV AX,DEST_RTT[BX] MOV DX,0 IFDEF OS2 DIV W32 ELSE IFDEF PCSWITCH DIV W18 ; CONVERT TO SECS ELSE DIV W10 ENDIF ENDIF CALL CONV_5DIGITS MOV AX,4620H ; F STOSW MOV AX,'=R' ; R= STOSW MOV AX,DEST_COUNT[BX] CALL CONV_5DIGITS TEST DEST_STATE[BX],40H JZ RTTRET ; NOT BPQ NODE MOV AX,'B ' STOSB ; SPACE STOSW ; DISPLAY ' B' FLAG STOSB ; SPACE MOV AL,DEST_STATE[BX] ; HOPS TO DEST + CONTROL BITS_ AND AL,3FH ; MASK CONTROL BITS JZ RTTRET CALL CONV_DIGITS RTTRET: RET CMDP00: ; ; PROCESS 'PORTS' MESSAGE ; MOV SI,OFFSET PORTHDDR MOV CX,7 REP MOVSB CMDP05: MOV SI,PORTTABLE MOV CH,0 MOV CL,NUMBEROFPORTS CMDP10: CALL CHECKBUFFER PUSH SI PUSH CX MOV AL,PORTNUMBER[SI] CALL CONVTODIGITS ; CONVERT AL TO DECIMAL DIGITS MOV AL,20H STOSB LEA SI,PORTDESCRIPTION[SI] MOV CX,30 CALL MOVEANDCHECK ; CHECK FOR PACLEN POP CX POP SI MOV AL,0DH STOSB MOV SI,PORTPOINTER[SI] LOOP CMDP10 JMP SENDCOMMANDREPLY CMDR00: ; ; PROCESS 'ROUTES' MESSAGE ; MOV RPORT,0 ; NOT SELECTIVE MOV NSTAR,0 ; SYSOP OPTION CALL SCAN CMP BYTE PTR [SI],' ' JE CMDR01 ; NORMAL ; MOV NSTAR,1 IFDEF SYSOP CMP BYTE PTR 3[SI],20H JE CMDR01A ; NO CALLSIGN JMP ROUTEUPDATE ENDIF CMDR01A: ; ; IF SECOND PARAM, ITS A PORT NUMBER ; ADD SI,2 CALL SCAN CMP BYTE PTR [SI],' ' JE CMDR01 ; NORMAL ; CALL GETVALUE ; EXTRACT NUMBER ; JC CMDR01 ; DUFF PARAM MOV RPORT,AL CMDR01: MOV SI,OFFSET ROUTEHDDR MOV CX,8 REP MOVSB MOV SI,NEIGHBOURS MOV CX,MAXNEIGHBOURS CMDR10: MOV AL,RPORT OR AL,AL JZ CMDR11 ; NOT SELECTIVE CMP AL,NEIGHBOUR_PORT[SI] JNE CMDR12 ; WRONG PORT - IGNORE CMDR11: PUSH CX CALL DISPLAYROUTE POP CX CMDR12: ADD SI,TYPE NEIGHBOUR_LIST LOOP CMDR10 JMP SENDCOMMANDREPLY DISPLAYROUTE: CALL CHECKBUFFER CMP NEIGHBOUR_CALL[SI],0 JNE CMDR20 RET ; CMDR20: MOV AX,2020H CMP NEIGHBOUR_LINK[SI],0 JE IDLEROUTE ; ; ACTIVE LINK ; MOV AL,'>' IDLEROUTE: STOSW MOV AL,NEIGHBOUR_PORT[SI] CALL CONV_DIGITS MOV AL,20H STOSB MOV AX,0 CALL CMDR95 ; DISPLAY CALL ; ; CHECK FOR DIGIS ; CMP NEIGHBOUR_DIGI[SI],0 JE CMDR50 MOV AX,'IV' STOSW MOV AX,' A' STOSW ; PUT IN VIA MOV AX,7 CALL CMDR95 ; DISPLAY DIGI CALL CMP NEIGHBOUR_DIGI+7[SI],0 JE CMDR50 MOV AX,14 CALL CMDR95 ; DISPLAY 2ND DIGI CALL CMDR50: MOV AL,NEIGHBOUR_QUAL[SI] CALL CONV_DIGITS MOV AL,20H STOSB CALL COUNTNODES ; NODES USING THIS DESTINATION PUSH AX ; SAVE NODES CALL CONV_DIGITS POP AX TEST NEIGHBOUR_FLAG[SI],1 JZ NOTLOCKED MOV AL,'!' STOSB NOTLOCKED: CMP NSTAR,0 JNE CMDR55 JMP CMDR89 ; SKIP EXTRA BITS CMDR55: ; ; DISPLAY FRAME COUNTS, ETC ; MOV AX,2020H STOSW MOV AX,WORD PTR NBOUR_IFRAMES[SI] MOV DX,WORD PTR NBOUR_IFRAMES+2[SI] CALL CONVBIGNUMBER MOV AX,2020H STOSW MOV AX,WORD PTR NBOUR_RETRIES[SI] MOV DX,WORD PTR NBOUR_RETRIES+2[SI] CALL CONVBIGNUMBER MOV AX,2020H STOSW ; ; CALCULATE % RETRY RATE ; MOV AX,WORD PTR NBOUR_IFRAMES[SI] MOV DX,WORD PTR NBOUR_IFRAMES+2[SI] CMP DX,0 JNE BIGNUMBERS ; NEED TO SCALE CMP AX,0 JE CANTDOIT ; DONT TRY TO DIVIDE BY ZERO! ; ; IF RETRIES ARE LESS THAT 655, CAN CALCULATE DIRECTLY ; CMP WORD PTR NBOUR_RETRIES+2[SI],0 JNE BIGNUMBERS CMP WORD PTR NBOUR_RETRIES[SI],655 JA BIGNUMBERS ; ; CALCULATE AS (RETRIES*100)/FRAMES ; MOV CX,AX ; SAVE FRAMES MOV AX,WORD PTR NBOUR_RETRIES[SI] MUL WORD PTR WORD100 DIV CX JMP SHORT DISPIT BIGNUMBERS: ; ; CALCULATE AS RETRIES/(FRAMES/100) ; CMP DX,100 ; TOO BIG JAE CANTDOIT DIV WORD PTR WORD100 CMP AX,0 JE CANTDOIT ; ZERO DIVISOR! MOV CX,AX ; SAVE FRAMES/100 MOV AX,WORD PTR NBOUR_RETRIES[SI] MOV DX,WORD PTR NBOUR_RETRIES+2[SI] DIV CX ; RETRIES/(FRAMES/100); DISPIT: CALL CONV_5DIGITS MOV AL,'%' STOSB JMP SHORT DONEIT CANTDOIT: MOV AL,'*' STOSB DONEIT: MOV AX,2020H STOSW MOV AL,NBOUR_MAXFRAME[SI] CALL CONV_DIGITS MOV AX,2020H STOSW MOV AL,NBOUR_FRACK[SI] CALL CONV_DIGITS MOV AX,2020H STOSW ; ; DO TIME ; MOV AL,BYTE PTR NEIGHBOUR_TIME+1[SI] CALL PRINTNUM MOV AL,':' STOSB MOV AL,BYTE PTR NEIGHBOUR_TIME[SI] CALL PRINTNUM ; ; DISPLAY L2 QUEUE ; CMP NEIGHBOUR_LINK[SI],0 JE CMDR89 ; IDLE ROUTE PUSH BX MOV AX,2020H STOSW MOV BX,NEIGHBOUR_LINK[SI] ; TO LINK ENTRY ; MOV AH,0 CALL COUNT_AT_L2 ; SEE HOW MANY QUEUED MOV AL,AH CALL CONV_DIGITS POP BX CMDR89: MOV AL,0DH STOSB CMDR90: RET CMDR95: ; ; DO A CALLSIGN ; PUSH SI PUSH DI ADD SI,AX CALL CONVFROMAX25 ; CONVERT TO CALL INC CX POP DI MOV SI,OFFSET NORMCALL CALL MOVEANDCHECK ; CHECK FOR PACLEN POP SI RET COUNTNODES: ; ; COUNT NODES WITH ROUTE VIA NEIGHBOUR IN SI ; PUSH DI MOV DI,DESTS MOV AL,0 COUNTN10: CMP ROUT1_NEIGHBOUR[DI],SI JNE COUNTN12 INC AL JMP SHORT COUNTN50 COUNTN12: CMP ROUT2_NEIGHBOUR[DI],SI JNE COUNTN14 INC AL JMP SHORT COUNTN50 COUNTN14: CMP ROUT3_NEIGHBOUR[DI],SI JNE COUNTN50 INC AL COUNTN50: ADD DI,TYPE DEST_LIST CMP DI,ENDDESTLIST JNE COUNTN10 POP DI RET CMDN100: ; ; SELECTIVE NODES DISPLAY ; PUSH BX PUSH DI PUSH SI CALL FINDDESTALIAS POP SI POP DI JZ CMDN105 ; FOUND PUSH DI CALL CONVTOAX25 ; CONVERT PARAM TO AX25 FORMAT MOV SI,OFFSET AX25CALL CALL FINDDESTINATION POP DI JZ CMDN105 ; FOUND POP BX MOV SI,OFFSET NOTFOUNDMSG MOV CX,10 REP MOVSB JMP SENDCOMMANDREPLY CMDN105: MOV SI,OFFSET NODEROUTEHDDR MOV CX,11 REP MOVSB LEA SI,DEST_CALL[BX] CALL DECODENODENAME ; CONVERT TO ALIAS:CALL REP MOVSB CMP DEST_RTT[BX],0 JE NO_RTT ; TIMER NOT SET - DEST PROBABLY NOT USED MOVSB ; ADD SPACE CALL DORTT NO_RTT: MOV AL,CR STOSB MOV CX,3 MOV DH,DEST_ROUTE[BX] ; CURRENT ACTIVE ROUTE MOV DL,1 CMDN110: MOV SI,ROUT1_NEIGHBOUR[BX] CMP SI,0 JE CMDN199 MOV AX,' ' CMP DH,DL JNE CMDN112 ; NOT CURRENT DEST MOV AX,' >' CMDN112: STOSW PUSH CX MOV AL,ROUT1_QUALITY[BX] CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS mov AL,' ' stosb MOV AL,ROUT1_OBSCOUNT[BX] CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS mov AL,' ' stosb MOV AL,NEIGHBOUR_PORT[SI] ; GET PORT CALL CONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS mov AL,' ' stosb PUSH DI CALL CONVFROMAX25 ; CONVERT TO CALL POP DI MOV SI,OFFSET NORMCALL REP MOVSB MOV AL,CR STOSB ADD BX,4 INC DL ; ROUTE NUMBER POP CX LOOP CMDN110 CMDN199: POP BX JMP SENDCOMMANDREPLY CMDL00: ; ; PROCESS 'LINKS' MESSAGE ; MOV SI,OFFSET USERHDDR MOV CX,7 REP MOVSB MOV SI,LINKS MOV CX,MAXLINKS ; MAX LINES IN ONE MESSAGE CMDL10: CALL CHECKBUFFER ; MAKE SURE ROOM LEFT PUSH CX CMP BYTE PTR[SI],0 JE CMDL50 ; UNUSED ENTRY ; PUSH SI CALL CMDUXX ADD SI,7 MOV AL,20H STOSB CALL CMDUXX ; DISPLAY BOTH CALLS POP SI MOV AL,20H STOSB MOV AX,'=S' STOSW MOV AL,L2STATE[SI] ADD AL,30H STOSB ; PUT IN STATE MOV AL,20H STOSB MOV AX,'=P' STOSW MOV AL,LINKPORT[SI] CALL CONV_DIGITS ; PUT IN PORT MOV AL,20H STOSB MOV AX,'=T' STOSW MOV AL,LINKTYPE[SI] ADD AL,30H STOSB ; PUT IN TYPE MOV AL,20H STOSB MOV AX,'=V' STOSW MOV AL,'2' SUB AL,VER1FLAG[SI] STOSB ; PUT IN VERSION MOV AL,0DH STOSB CMDL50: ADD SI,TYPE LINKTABLE POP CX LOOP CMDL10 CMDL99: JMP SENDCOMMANDREPLY ; ; PROCESS 'USERS' ; CMDS00: mov SI,OFFSET SESSIONHDDR mov CX,SESSHDDRLEN rep movsb mov AL,QCOUNT ; Get number of free buffers CALL CONV_DIGITS mov AL,')' stosb mov AL,CR stosb mov SI,L4TABLE mov CX,MAXCIRCUITS CMDS10: call CHECKBUFFER ; ENSURE ROOM push CX cmp L4USER[SI],0 je CMDS60 ; SPARE ENTRY test L4CIRCUITTYPE[SI],UPLINK jnz CMDS10A ; YES ; IF DOWNLINK, ONLY DISPLAY IF NO CROSSLINK cmp L4CROSSLINK[SI],0 jne CMDS60 ; WILL PROCESS FROM OTHER END ; ; ITS A DOWNLINK WITH NO PARTNER - MUST BE A CLOSING SESSION ; DISPLAY TO THE RIGHT FOR NOW ; PUSH SI MOV SI,OFFSET CLOSINGMSG MOV CX,10 REP MOVSB POP SI CMDS10A: cmp L4CROSSLINK[SI],0 jne TWO_ENTRIES push SI call DISPLAYCIRCUIT pop SI jmp SHORT CMDS20 TWO_ENTRIES: push DI mov DI,OFFSET USERSBUFFER mov CX,17 mov AX,' ' rep stosw mov DI,OFFSET USERSBUFFER push SI call DISPLAYCIRCUIT pop SI pop DI push SI mov SI,OFFSET USERSBUFFER mov CX,17 rep movsw pop SI push SI mov SI,L4CROSSLINK[SI] CMP L4STATE[SI],5 JE CMDS19A mov AX,'~<' stosw mov AX,'>~' stosw JMP SHORT CMDS19B CMDS19A: mov AX,'-<' stosw mov AX,'>-' stosw CMDS19B: mov AX,' ' stosw call DISPLAYCIRCUIT pop SI CMDS20: mov AL,CR stosb CMDS60: pop CX add SI,TYPE TRANSPORTENTRY loop CMDS10 jmp SENDCOMMANDREPLY CMDUXX_1: push BX push SI push CX push DI call FINDDESTINATION pop DI jz NODE_FOUND push DI ; NET/ROM not found call CONVFROMAX25 ; CONVERT TO CALL pop DI mov SI,OFFSET NORMCALL rep movsb jmp SHORT END_CMDUXX NODE_FOUND: lea SI,DEST_CALL[BX] call DECODENODENAME REP MOVSB END_CMDUXX: pop CX pop SI pop BX ret DISPLAYCIRCUIT: MOV AH,L4CIRCUITTYPE[SI] PUSH SI CMP AH,L2LINK+UPLINK JNE CMDS11 mov SI,OFFSET UPLNKMSG mov CX,6 rep movsb POP SI PUSH SI PUSH AX MOV AL,20H STOSB MOV SI,L4TARGET[SI] ; NODE MOV AL,LINKPORT[SI] CALL CONV_DIGITS POP AX jmp SHORT CMDS17 CMDS11: CMP AH,L2LINK+DOWNLINK JE CMDS30 ; DISPLAY L2 DOWNLINK CMDS13: IF TNC2 TEST AH,HOST+BPQHOST ELSE TEST AH,BPQHOST ENDIF JZ CMDS14 ; ; MAY BE TNC2 OR BPQ MODE ; MOV SI,OFFSET HOSTLNKMSG MOV CX,4 REP MOVSB POP SI PUSH SI IF TNC2 TEST AH,BPQHOST JNZ CMDS13A ; ; TNC2 MODE ; MOV SI,L4TARGET[SI] ; TO TNC DATA MOV AL,BIOSPORT[SI] ; INT 14 PORT NUMBER ADD AL,31H STOSB JMP SHORT CMDS17 ENDIF CMDS13A: IFDEF PCSWITCH ; NO BPQHOST MODE IN DATA ENGINE MOV DL,AH ; SAVE MOV AX,L4TARGET[SI] ; BPQ HOST VECTOR SUB AX,OFFSET BPQHOSTVECTOR DIV BPQVECLENGTH INC AL ; WANT 1-64 CBW DIV D10 OR AX,3030H STOSW ; PUT IN HOSTMODE SUBPORT NUMBER MOV AH,DL ENDIF JMP SHORT CMDS17 CMDS14: mov SI,OFFSET CROSSLNKMSG mov CX,7 rep movsb CMDS17: POP SI MOV AL,'(' STOSB IF TNC2 TEST AH,HOST+BPQHOST ELSE TEST AH,BPQHOST ENDIF JNZ HOST_ENTRY CMP AH,L2LINK+UPLINK JE ONECALL PUSH SI MOV SI,L4TARGET[SI] ; NODE LEA SI,DEST_CALL[SI] CALL CMDUXX_1 POP SI MOV AL,' ' STOSB ONECALL: PUSH SI LEA SI,L4USER[SI] CALL CMDUXX ; DISPLAY USER ; POP SI MOV AL,')' STOSB RET HOST_ENTRY: push SI LEA SI,L4USER[SI] call CMDUXX_1 pop SI mov AL,')' stosb ret CMDS30: MOV SI,OFFSET DOWNLNKMSG MOV CX,8 REP MOVSB POP SI PUSH SI MOV SI,L4TARGET[SI] ; L2 SESSION MOV AL,20H STOSB MOV AL,LINKPORT[SI] CALL CONV_DIGITS MOV AL,'(' STOSB PUSH SI LEA SI,OURCALL[SI] CALL CMDUXX POP SI MOV AL,' ' STOSB LEA SI,LINKCALL[SI] CALL CMDUXX ; REMOTE USER POP SI MOV AL,')' STOSB RET CMDUXX: push SI push CX push DI call CONVFROMAX25 ; CONVERT TO CALL pop DI mov SI,OFFSET NORMCALL rep movsb pop CX pop SI ret CQCMD: MOV CQFLAG,1 MOV CONNECTREPLYPTR,DI ; SAVE POINTER MOV CONNECTSESSION,BX MOV SI,OFFSET CQCALL MOV CONNECTPORT,1 ; MAYBE NEED TO CHANGE JMP GOTPORT ; ISSUE DUMMY 'CONNECT' TO CQ CMDC00: ; ; PROCESS CONNECT COMMAND ; MOV CQFLAG,0 ; NOT CQ CALL MOV CONNECTREPLYPTR,DI ; SAVE POINTER MOV CONNECTSESSION,BX IF BLACKBITS PUSH SI LEA SI,L4USER[BX] CALL CHECKBLACKLIST POP SI JNZ ALLOWED ; ; CONNECTS FROM THIS STATION ARE NOT ALLOWED ; MOV DI,REPLYBUFFER CALL RELBUFF RET ALLOWED: ENDIF MOV CONNECTPORT,0 ; NO PORT SPECIFIED CALL SCAN CMP BYTE PTR [SI],' ' JE HOSTCONNECT JMP CMDC01X ; ; C WITH NO PARAMS - LOOK FOR AN APPL 2 PORT WITH CONOK ON ; HOSTCONNECT: ; ; HOST MODE ; MOV CMDPTR,OFFSET HOSTCMD MOV APPLMASK,2 ; BBS JMP APPLCMD1 CMDC01J: JMP CMDC01 ; INVALID CALL CMDC98AJ: JMP CMDC98A ; INVALID PORT CMDC01X: ; ; SEE IF PORT SPECIFIED ; PUSH SI ; SAVE IN CASE NOT PORT CALL GETVALUE JC NOPORT ; POINT TO FIRST CHAR OF CALL ; ; IF THERE IS NOTHING FOLLOWING THE NUMBER, ASSUME IT IS A ; NUMERIC ALIAS INSTEAD OF A PORT ; CALL SCAN CMP BYTE PTR[SI+1],20H ; COULD JUSY BE S OR Z JBE NOPORT ADD SP,2 ; DISCARD SAVED SI PUSH BX PUSH AX CALL GETPORTTABLEENTRY ; SEE IF PORT IS DEFINED POP AX CMP AL,PORTNUMBER[BX] POP BX JNE CMDC98AJ ; ILLEGAL MOV CONNECTPORT,AL JMP SHORT GOTPORT NOPORT: POP SI GOTPORT: CALL SCAN CALL DECODECALLSTRING JNZ CMDC01J ; INVALID ; ; SEE IF CALL TO HOST TNC (BBS) - UNLESS DIGIS SPECIFIED ; MOV SI,CONNECTSESSION ; INCOMING CIRCUIT MOV AL,STAYSWITCH MOV STAYFLAG[SI],AL ; SET STAY VALUE CMP AX25STRING+7,0 JNE CMDC02 ; FORCE L2 CONNECT IF DIGIS SPECIFIED ; MOV SI,OFFSET CONNECTCALL MOV DI,OFFSET BBSCALL+7 ; BBS ALIAS MOV CX,6 REP CMPSB JE BBSCONNECT_J ; MOV SI,OFFSET CONNECTCALL MOV DI,OFFSET MYLINKCALL ; BBS CALLSIGN MOV CX,10 REP CMPSB JNE NOTBBSC BBSCONNECT_J: JMP BBSCONNECT NOTBBSC: ; CMP AX25STRING+7,0 JNE CMDC02 ; FORCE L2 CONNECT IF DIGIS SPECIFIED ; ; SEE IF CALL TO ANOTHER NODE ; CMP BYTE PTR CONNECTCALL+6,'-' ; SSID? JE NOTALIASC MOV SI,OFFSET CONNECTCALL CALL FINDDESTALIAS JZ L4CONNECT ; FOUND ; NOTALIASC: MOV SI,OFFSET AX25STRING CALL FINDDESTINATION JNZ CMDC02 ; NOT NETROM CONNECT L4CONNECT: MOV TARGETDEST,BX ; SAVE POINTER JMP SHORT CMDC06 CMDC01: JMP CMDC98 ; INVALID CMDC02: MOV TARGETDEST,0 ; INDICATE L2 DOWNLINK REQUIRED CMP CONNECTPORT,0 JNE CMDC05 ; L2 NEEDS PORT NUMBER MOV AL,NUMBEROFPORTS ; IF ONLY ONE PORT, DONT NEED NUMBER CMP AL,1 JNE MULTIPORT MOV CONNECTPORT,1 JMP SHORT CMDC05 MULTIPORT: MOV SI,OFFSET NOPORTMSG MOV CX,LNOPORTMSG MOV DI,CONNECTREPLYPTR MOV BX,CONNECTSESSION ; REP MOVSB JMP CMDP00 ; LIST AVAILABLE PORTS CMDC05: ; ; ENSURE PORT IS AVAILABLE FOR L2 USE ; MOV SI,CONNECTSESSION IF TNC2 TEST L4CIRCUITTYPE[SI],HOST+BPQHOST ELSE TEST L4CIRCUITTYPE[SI],BPQHOST ENDIF JNZ CMDC06 ; LET HOST DO ANYTHING MOV AL,CONNECTPORT CALL GETPORTTABLEENTRY CMP PORTL3FLAG[BX],0 JE CMDC06 ; OK ; ; PORT NOT ALLOWED ; MOV SI,OFFSET L3INVALIDPORT MOV CX,L3INVPORTLEN JMP CMDC99 CMDC06: ; ; GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK ; CALL GETFREECIRCUIT ; GET AN ENTRY JZ CMDC07 JMP CMDC97 ; TABLES FULL CMDC07: MOV SI,CONNECTSESSION ; INCOMING CIRCUIT MOV L4CROSSLINK[BX],SI ; POINTER FROM NEW TO OLD MOV L4CROSSLINK[SI],BX ; POINTER FROM OLD TO NEW LEA SI,L4USER[SI] LEA DI,L4USER[BX] MOV CX,7 REP MOVSB ; PUT IN CALL ; MOV SI,CONNECTSESSION ; INCOMING CIRCUIT LEA SI,L4MYCALL[SI] LEA DI,L4MYCALL[BX] MOV CX,7 REP MOVSB ; PUT IN CALL ; MOV CIRCUITINDEX[BX],DL ; OUR INDEX MOV AL,NEXTID MOV CIRCUITID[BX],AL ; OUR ID CALL INC_ID MOV SI,CONNECTSESSION MOV AX,SESSIONT1[SI] ; CALLERS TIMEOUT MOV SESSIONT1[BX],AX ; NET SESSION TIMEOUT MOV AL,L4DEFAULTWINDOW MOV L4WINDOW[BX],AL CMP TARGETDEST,0 JE CMDC09 ; L2 CONNECT REQUIRED ; ; SET UP CROSSLINK ; MOV L4CIRCUITTYPE[BX],SESSION+DOWNLINK ; CROSS MOV AX,TARGETDEST MOV L4TARGET[BX],AX ; SET POINTER TO DEST ; MOV L4STATE[BX],2 ; CONNECTING MOV AL,SPYSWITCH MOV SPYFLAG[BX],AL MOV DI,REPLYBUFFER CALL RELBUFF CALL SENDL4CONNECT INC WORD PTR L4CONNECTSOUT JNZ INC000 INC WORD PTR L4CONNECTSOUT+2 INC000: RET CMDC09: MOV L4CIRCUITTYPE[BX],L2LINK+DOWNLINK ; DOWNLINK ; ; FORMAT LINK TABLE ENTRY FOR THIS CONNECTION ; MOV AL,CONNECTPORT MOV COMPAREPORT,AL CALL GETPORTTABLEENTRY MOV BP,BX MOV DI,REPLYBUFFER CALL FINDLINK ; GET LINK FOR THIS ADDRESS PAIR (IN BX) ; ; SET UP NEW SESSION (OR RESET EXISTING ONE) ; CMP BX,0 JNE CMDC09A JMP CMDC97 ; TABLES FULL CMDC09A: ; ; COPY ADDRESS INFO TO LINK TABLE ; LEA SI,AX25STRING LEA DI,LINKCALL[BX] MOV CX,7 REP MOVSB MOV SI,CONNECTSESSION MOV AL,L4CIRCUITTYPE[SI] ; FOR SSID SWAP TEST LEA SI,L4USER[SI] LEA DI,OURCALL[BX] MOV CX,7 REP MOVSB ; IF TNC2 TEST AL,HOST+BPQHOST ELSE TEST AL,BPQHOST ENDIF JNZ DONTFLIP ; LEAVE ALONE FOR HOST XOR BYTE PTR -1[DI],00011110B ; FLIP SSID DONTFLIP: MOV AL,CONNECTPORT MOV LINKPORT[BX],AL ; PUT IN PORT MOV AL,DS:PORTT1[BP] MOV L2TIME[BX],AL ; SET STANDARD TIMER VALUE ADD AL,AL ; *2 FOR DIGIS ; MOV SI,OFFSET AX25STRING+7 CMDC019: CMP BYTE PTR [SI],0 JE CMDC020 ; END OF DIGI STRING MOV CX,7 REP MOVSB ADD L2TIME[BX],AL ; ADJUST TIMER VALUE FOR 1 DIGI JMP CMDC019 ; COPY OTHERS CMDC020: MOV AL,CONNECTPORT MOV LINKPORT[BX],AL ; PUT IN MOV LINKTYPE[BX],2 ; DOWNLINK CALL GETPORTWINDOW MOV LINKWINDOW[BX],AL CALL RESET2 ; RESET ALL FLAGS MOV L2STATE[BX],2 ; CONNECTING PUSH BX LEA DI,CIRCUITPOINTER[BX] MOV AX,BX MOV BX,CONNECTSESSION MOV BX,L4CROSSLINK[BX] ; TO 'DOWN' SESSION MOV [DI],BX ; POINTER TO CIRCUIT MOV L4TARGET[BX],AX ; SET UP CROSS LINKS MOV AL,DS:PORTPACLEN[BP] OR AL,AL JZ LEAVEPACLEN ; ; SET SESSION PACLEN TO PORT VALUE ; MOV BX,CONNECTSESSION MOV SESSPACLEN[BX],AL LEAVEPACLEN: POP BX ; LINK ; CMP CQFLAG,1 JE DUMMYCALL ; A CQ CALL - DONT SEND SABM! CALL SENDSABM ; KICK IT OFF DUMMYCALL: ; ; DISCARD BUFFER ; MOV DI,REPLYBUFFER CALL RELBUFF RET CMDC96: MOV SI,OFFSET INVALIDWIND MOV CX,INVWINDLEN JMP SHORT CMDC99 CMDC97: MOV SI,OFFSET TABLESFULL MOV CX,TABLESFULLLEN JMP SHORT CMDC99 CMDC98: MOV SI,OFFSET INVALIDCALL MOV CX,INVCALLLEN JMP SHORT CMDC99 CMDC98A: MOV SI,OFFSET INVALIDPORT MOV CX,INVPORTLEN CMDC99: MOV DI,CONNECTREPLYPTR MOV BX,CONNECTSESSION ; REP MOVSB JMP SENDCOMMANDREPLY DECODECALLSTRINGF: CALL DECODECALLSTRING RETF DECODECALLSTRING: ; ; CONVERT CALL + OPTIONAL DIGI STRING AT [SI] TO AX25, RETURN ADDRESS ; OF CONVERTED STRING IN [SI], WITH NZ SET IF INVALID ; ; ALSO RETURN END OF INPUT STRING IN AX MOV STAYSWITCH,0 MOV SPYSWITCH,0 MOV DI,OFFSET AX25STRING MOV CX,64 MOV AL,0 REP STOSB ; CLEAR STRING MOV DI,OFFSET CONNECTCALL MOV AX,2020H MOV CX,5 REP STOSW MOV DI,OFFSET CONNECTCALL MOV CX,10 EXTRACTCALL: LODSB CMP AL,20H JE EXTR10 ; END STOSB LOOP EXTRACTCALL DECODECALL99_J: JMP DECODECALL99 ; DUFF EXTR10: PUSH SI MOV SI,OFFSET CONNECTCALL CALL CONVTOAX25 ; CONVERT PARAM TO AX25 FORMAT MOV SI,OFFSET AX25CALL MOV DI,OFFSET AX25STRING MOV CX,7 REP MOVSB POP SI JNZ DECODECALL99_J ; INVALID ; ; GET NEXT FIELD = COULD BE CALLSIGN, VIA, OR S (FOR SAVE) ; MOV DIGIPTR,OFFSET AX25STRING+7 DIGILOOP: MOV DI,OFFSET DIGICALL MOV AX,2020H MOV CX,5 REP STOSW MOV DI,OFFSET DIGICALL MOV CX,10 CMP BYTE PTR [SI],20H JE NOTDIGI ; END OF DIGI STRING EXTRACTDCALL: LODSB CMP AL,20H JE EXTRD10 ; END CMP AL,',' JE EXTRD10 ; END STOSB LOOP EXTRACTDCALL JMP SHORT DECODECALL99 ; DUFF EXTRD10: ; ; CHECK FOR VIA, ETC ; CMP DIGICALL,'V' JNE NOTVIA MOV AL,DIGICALL+1 CMP AL,20H JE DIGILOOP ; V CMP AL,'I' JNE NOTVIA MOV AL,DIGICALL+2 CMP AL,20H JE DIGILOOP ; VI CMP AL,'A' JNE NOTVIA CMP DIGICALL+3,' ' JE DIGILOOP ; VIA NOTVIA: CMP WORD PTR DIGICALL,' S' ; S SPACE = STAY JNE NOTSTAY MOV STAYSWITCH,'S' JMP DIGILOOP NOTSTAY: CMP WORD PTR DIGICALL,' Z' ; Z SPACE = 'SPY' JNE NOTSPY MOV SPYSWITCH,'Z' JMP DIGILOOP NOTSPY: CMP DIGIPTR,OFFSET AX25STRING+63 ; GOT 8 DIGIS? JE DECODECALL99 PUSH SI ; SAVE COMMAND POINTER MOV SI,OFFSET DIGICALL CALL CONVTOAX25 ; CONVERT PARAM TO AX25 FORMAT MOV SI,OFFSET AX25CALL MOV DI,DIGIPTR MOV CX,7 REP MOVSB POP SI JNZ DECODECALL99 ; INVALID MOV DIGIPTR,DI ; SAVE JMP DIGILOOP NOTDIGI: XOR AL,AL ; RETURN ZERO MOV AX,SI ; NEXT CHAR IN INPUT STRING MOV SI,OFFSET AX25STRING RET DECODECALL99: OR AL,1 RET ; NZ SET APPLCMD: ; ; SEE IF THERE IS AN ALIAS DEFINDED FOR THIS COMMAND ; ; MOV SI,ALIASPTR CMP BYTE PTR [SI],20H JBE APPLCMD1 ; NO ALIAS ; ; COPY ALIAS TO COMMAND BUFFER, THEN REENTER COMMAND HANDLER ; PUSH DI ; REPLY BUFFER PTR MOV DI,OFFSET COMMANDBUFFER MOV CX,16 REP MOVSB JMP REDOCOMMAND APPLCMD1: MOV CONNECTREPLYPTR,DI ; SAVE POINTER MOV CONNECTSESSION,BX JMP SHORT SKIPBBS BBSCONNECT: ; ; LOOK FOR A FREE BBS HOST SESSION ; MOV CMDPTR,OFFSET APPL1 MOV APPLMASK,1 ; BBS SKIPBBS: MOV AX,CMDPACLEN CALL ATTACHTOBBS JZ BBSCOK ; SESSION FOUND ; ; NO PORTS AVAILABLE ; MOV SI,OFFSET NOFREEPORTS MOV DI,CONNECTREPLYPTR MOV CX,11 REP MOVSB ; ; ADD APPL NAME ; PUSH SI MOV SI,CMDPTR CMP WORD PTR [SI],'**' JNE BUSYLOOP ; ; MUST BE HOST PORT ; MOV SI,OFFSET HOSTBUSYMSG BUSYLOOP: LODSB STOSB CMP AL,' ' JNE BUSYLOOP POP SI MOV CX,NOFREEPORTSLEN-11 REP MOVSB MSGDONE: MOV BX,CONNECTSESSION ; JMP SENDCOMMANDREPLY ; BBSCOK: ; ; IF CMD_TO_APPL SET IN APPLFLAGS, SEND INPUT MSG TO APPL ; TEST SAVEDAPPLFLAGS,CMD_TO_APPL JZ DONTSENDCMD CALL GETBUFF JZ DONTSENDCMD ; CANT DO MUCH ELSE PUSH DI ADD DI,6 ; SKIP DATA MOV SI,OFFSET COMMANDBUFFER MOV CX,72 REP MOVSB MOV AL,0DH STOSB POP DI MOV MSGLENGTH[DI],79 PUSH BX MOV BX,L4CROSSLINK[BX] ; TO HOST SESSION LEA SI,L4TX_Q[BX] CALL Q_ADD POP BX DONTSENDCMD: ; ; IF MSG_TO_USER SET, SEND 'CONNECTED' MESSAGE TO USER ; MOV AL,SAVEDAPPLFLAGS MOV SESS_APPLFLAGS[BX],AL ; SAVE IN SESSION ENTRY TEST AL,MSG_TO_USER JNZ SENDCMDMSG ; ; DONT NEED BUFFER ANY MORE ; MOV DI,REPLYBUFFER CALL RELBUFF RET SENDCMDMSG: MOV SI,OFFSET CONNECTEDMSG MOV CX,LCONNECTEDMSG MOV DI,CONNECTREPLYPTR REP MOVSB ; ; ADD BBS CALL, OR APPL ; TEST APPLMASK,1 JNZ BBSCOK01 MOV SI,OFFSET APPLS MOV AL,1 MOV CX,8 GETAPPL: TEST APPLMASK,AL JNZ GOTAPPL ADD SI,TYPE CMDX SHL AL,1 LOOP GETAPPL BBSCOK01: MOV SI,OFFSET BBSCALL+7 GOTAPPL: CMP WORD PTR [SI],'**' JNE NOTHOST ; ; MUST BE HOST PORT ; MOV SI,OFFSET HOSTBUSYMSG NOTHOST: CALL COPYTOSPACE MOV AL,0DH STOSB JMP SENDCOMMANDREPLY COPYTOSPACE: LODSB CMP AL,20H JBE BBSCOK03 STOSB JMP COPYTOSPACE BBSCOK03: RET CMDSTATS: MOV AL,0DH STOSB ; ; SEE IF ANY PARAM ; CALL SCAN LODSB MOV NSTAR,AL ; ; IF ASKING FOR PORT STATS, DONT DO SYSTEM ONES ; CMP AL,' ' JE DOSYSSTATS CMP AL,'S' JE DOSYSSTATS MOV SI,OFFSET L2STATS JMP DOREST DOSYSSTATS: MOV SI,OFFSET STATS CMDST00: CMP BYTE PTR [SI],0 JE CMDST15 ; DO PORT STATS CALL CHECKBUFFER MOV CX,STATSLEN REP MOVSB LODSB ; COUNT OF NUMBERS TO PROCESS CBW MOV CX,AX CMDST05: LODSW MOV DX,AX LODSW XCHG DX,AX ; LOW ORDER TO AX, HI TO DX CALL CONVTO10DIGITS ; DISPLAY COUNTERS LOOP CMDST05 MOV AL,0DH STOSB JMP CMDST00 ; ; DO ONES STORED BY PORT ; CMDST15: INC SI CMP NSTAR,'S' ; SYSTEM STATS ONLY JNE DOREST JMP SENDCOMMANDREPLY DOREST: ; ; PORT NUMBERS ; PUSH BX MOV BX,PORTTABLE MOV CH,0 MOV CL,NUMBEROFPORTS CMP NSTAR,' ' JE CMDST17 ; ; POSITION TO REQUESTED PORT ; MOV AL,NSTAR AND AL,0FH GETFIRSTPORT: CMP AL,PORTNUMBER[BX] JE GOTFIRSTPORT MOV BX,PORTPOINTER[BX] LOOP GETFIRSTPORT ; ; REQUESTED PORT NOT FOUND ; POP BX JMP SENDCOMMANDREPLY GOTFIRSTPORT: CMP CL,7 JBE CMDST17 MOV CL,7 ; LIMIT TO 7 ENTRIES CMDST17: MOV STATCMDCOUNT,CX MOV STATCMDPTR,BX PUSH CX MOV AL,20H MOV CX,16 REP STOSB POP CX PUSH SI CMDST17A: PUSH CX MOV SI,OFFSET PORT MOV CX,6 REP MOVSB POP CX MOV AL,PORTNUMBER[BX] CALL CONVTODIGITS ; CONVERT AL TO DECIMAL DIGITS MOV BX,PORTPOINTER[BX] LOOP CMDST17A MOV AL,0DH STOSB POP SI POP BX MOV CX,PORTSTATS-1 CMDST20: CALL CHECKBUFFER PUSH BX PUSH CX MOV CX,L2STATSLEN REP MOVSB MOV BX,STATCMDPTR MOV CX,STATCMDCOUNT CMDST30: PUSH BX ADD BX,[SI] ; TO COUNTER MOV AX,[BX] MOV DX,2[BX] POP BX CALL CONVTO10DIGITS ; DISPLAY COUNTERS MOV BX,PORTPOINTER[BX] LOOP CMDST30 ADD SI,2 POP CX POP BX MOV AL,0DH STOSB LOOP CMDST20 ; DO LINK LOADS ; CALL CHECKBUFFER PUSH BX MOV CX,L2STATSLEN REP MOVSB MOV BX,STATCMDPTR MOV CX,STATCMDCOUNT CMDST80: PUSH BX ADD BX,[SI] ; TO COUNTER MOV AX,2020H STOSW MOV AL,[BX] CALL CONVTODIGITS ; DISPLAY COUNTERS MOV AL,20H STOSB MOV AL,1[BX] CALL CONVTODIGITS ; DISPLAY COUNTERS POP BX MOV BX,PORTPOINTER[BX] LOOP CMDST80 POP BX MOV AL,0DH STOSB SKIPREST: JMP SENDCOMMANDREPLY SENDCOMMANDREPLY: MOV CX,DI MOV DI,REPLYBUFFER SUB CX,DI CMP CX,6 ; NULL PACKET JE RELEASE MOV MSGLENGTH[DI],CX ; LEA SI,L4TX_Q[BX] ; LINK TX QUEUE CALL Q_ADD RET RELEASE: CALL RELBUFF RET CHECKBUFFER: ; ; MAKE SURE THERE IS ROOM IN CURRENT BUFFER ; MOV AX,DI SUB AX,REPLYBUFFER CMP AX,CMDPACLEN JAE NEWBUFFER CMP AX,156 JB CHECKBUFFRET ; ENOUGH LEFT ; NEWBUFFER: ; ; END OF BUFFER - QUEUE IT AND GET ANOTHER ; PUSH SI PUSH CX CALL SENDCOMMANDREPLY ; ; GET BUFFER ; CALL GETBUFF JNZ CHECKBUFFER10 ; OK ; ; NO BUFFERS - ABORT ; MOV SP,CMDSTACKP ; RESET STACK TO ENTRY VALUE RET CHECKBUFFER10: MOV REPLYBUFFER,DI ; ; SET UP HEADER ; LEA DI,5[DI] ; SKIP HEADER MOV AL,0F0H STOSB ; PID POP CX POP SI CHECKBUFFRET: RET CMDT00: ; ; SET L4 TIMEOUT FOR CONNECTS ON THIS SESSION ; CALL GETVALUE ; EXTRACT NUMBER ; JC CMDT99 ; DUFF PARAM OR AX,AX JZ CMDT50 ; DISPLAY VALUE MOV SESSIONT1[BX],AX ; SAVE ; ; DISPLAY VALUE ; CMDT50: MOV SI,OFFSET T4MSG MOV CX,T4MSGLEN REP MOVSB MOV AX,SESSIONT1[BX] MOV DX,0 CALL CONVBIGNUMBER MOV AL,0DH STOSB JMP SENDCOMMANDREPLY CMDT99: ; MOV SI,OFFSET BADVALUEMSG MOV CX,BADVALLEN REP MOVSB JMP SENDCOMMANDREPLY CMDPAC: ; ; SET PACLEN FOR THIS SESSION ; CALL GETVALUE ; EXTRACT NUMBER ; JC CMDPAC99 ; DUFF PARAM OR AX,AX JZ CMDPAC50 ; DISPLAY VALUE CMP AL,30 JB CMDPAC99 MOV SESSPACLEN[BX],AL ; SAVE ; ; DISPLAY VALUE ; CMDPAC50: MOV SI,OFFSET PACMSG MOV CX,PACMSGLEN REP MOVSB MOV AL,SESSPACLEN[BX] MOV AH,0 MOV DX,0 CALL CONVBIGNUMBER MOV AL,0DH STOSB JMP SENDCOMMANDREPLY CMDPAC99: ; MOV SI,OFFSET BADVALUEMSG MOV CX,BADVALLEN JMP SHORT DOERR MHDISABLE: MOV SI,OFFSET MHDISMSG MOV CX,MHDISLEN JMP SHORT DOERR MHERR: MOV SI,OFFSET MHERRMSG MOV CX,MHERRLEN DOERR: REP MOVSB JMP SENDCOMMANDREPLY MHCMD: ; ; DISPLAY HEARD LIST ; CALL GETVALUE ; EXTRACT NUMBER ; JC MHERR ; DUFF PARAM OR AL,AL JE MHERR ; PORT ZERO PUSH AX PUSH BX CALL GETPORTTABLEENTRY MOV SI,BX POP BX POP AX CMP AL,PORTNUMBER[SI] JNE MHERR ; INVALID PUSH SI MOV SI,OFFSET MHHDDR MOV CX,20 REP MOVSB POP SI CALL CONV_DIGITS ; PORT NUM MOV AL,0DH STOSB MOV SI,PORTMHEARD[SI] CMP SI,0 JE MHDISABLE ; NOT ON THIS PORT MOV CX,20 MHLOOP: CMP BYTE PTR [SI],0 JE MHEND CALL CHECKBUFFER PUSH CX PUSH SI PUSH DI CALL CONVFROMAX25 ; CONVERT CALL TO NORMAL POP DI MOV SI,OFFSET NORMCALL MOV DX,CX ; SAVE LEN REP MOVSB POP SI MOV AL,MHDIGI[SI] STOSB MHPAD: CMP DX,10 JAE DOTIME MOV AL,20H STOSB INC DX JMP SHORT MHPAD DOTIME: ; ; DO TIME ; IFDEF KANT ; ; REAL TIME CLOCK VALUES ARE IN BCD ; MOV AL,BYTE PTR MHTIME[SI] ; HOURS CALL B2HEX MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+1[SI] ; MINS CALL B2HEX ; MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+2[SI] ; SECS CALL B2HEX ENDIF IFDEF MSC ; ; REAL TIME CLOCK VALUES ARE IN BINARY ; MOV AL,BYTE PTR MHTIME[SI] ; HOURS CALL PRINTNUM MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+1[SI] ; MINS CALL PRINTNUM ; MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+2[SI] ; SECS CALL PRINTNUM ENDIF IFDEF PCSWITCH ; ; REAL TIME CLOCK VALUES ARE IN BINARY ; MOV AL,BYTE PTR MHTIME[SI] ; HOURS CALL PRINTNUM MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+1[SI] ; MINS CALL PRINTNUM ; MOV AL,':' STOSB MOV AL,BYTE PTR MHTIME+2[SI] ; SECS CALL PRINTNUM ENDIF MOV AL,0DH STOSB POP CX ADD SI,TYPE MHSTRUC LOOP MHLOOP MHEND: JMP SENDCOMMANDREPLY GETVALUE: ; ; EXTRACT DECIMAL VALUE FROM COMMAND ; PUSH BX MOV VALUE,0 CALL SCAN JE ENDVALUE ; NO NUMBER ; ; PROCESS NEXT DIGIT ; VALLOOP: LODSB CMP AL,' ' JE ENDVALUE CMP AL,0DH JE ENDVALUE ; ; ANOTHER DIGIT - MULTIPLY BY 10 ; MOV BL,AL MOV AX,VALUE MUL W10 MOV VALUE,AX SUB BL,'0' JC BADVALUE CMP BL,10 JNC BADVALUE MOV BH,0 ADD VALUE,BX JMP VALLOOP ENDVALUE: POP BX MOV AX,VALUE CLC RET BADVALUE: POP BX STC RET ; CARRY=DUFF GETVALUEHEX: ; ; EXTRACT NUMBER (HEX OR DECIMAL) FROM INPUT STRING ; PUSH BX MOV VALUE,0 CALL SCAN JE ENDVALUE ; NO NUMBER ; HEXLOOP: LODSB CMP AL,' ' JE ENDVALUE ; ; ANOTHER DIGIT - MULTIPLY BY 16 ; MOV AX,VALUE MUL W16 MOV VALUE,AX MOV AL,ES:-1[SI] SUB al,'0' JC BADVALUE CMP AL,10 JC HEXOK SUB AL,7 CMP AL,10 JC BADVALUE CMP AL,16 JNC BADVALUE HEXOK: MOV AH,0 ADD VALUE,AX JMP HEXLOOP ;-----------------------------------------------------------------------------; ; Convert byte in AL to nnn, nn or n format ; ;-----------------------------------------------------------------------------; CONV_DIGITS: MOV AH,0 CONV_5DIGITS: PUSH DX PUSH BX MOV BX,OFFSET TENK ; 10000 CMP AX,10 JB UNITS ; SHORT CUT AND TO STOP LOOP START_LOOP: cmp AX,WORD PTR [BX] JAE STARTCONV ADD BX,4 ; DWORD ENTRIES JMP SHORT START_LOOP ; STARTCONV: MOV DX,0 DIV WORD PTR [BX] ; ADD AL,30H ; MUST BE LESS THAN 10 STOSB ; MOV AX,DX ; REMAINDER ADD BX,4 CMP BX,OFFSET DWORD10+4 ; JUST DIVIDED BY 10? JNE STARTCONV ; NO, SO ANOTHER TO DO ; ; RESET MUST BE UNITS ; UNITS: add AL,30H stosb POP BX POP DX ret CONVTODIGITS: ; ; CONVERT AL TO 3 DECIMAL DIGITS AT [DI] ; MOV AH,0 DIV D10 ADD AH,30H MOV 2[DI],AH MOV AH,0 DIV D10 ADD AH,30H MOV 1[DI],AH ADD AL,30H MOV [DI],AL CMP WORD PTR [DI],'00' JNE CONVTOD00 MOV WORD PTR [DI],' ' ; CONVERT LEADING ZEROS TO SPACES JMP SHORT CONVTOD20 CONVTOD00: CMP BYTE PTR [DI],'0' JNE CONVTOD20 MOV BYTE PTR [DI],' ' ; CONVERT LEADING ZEROS TO SPACES CONVTOD20: ADD DI,3 RET CONVBIGNUMBER: MOV SUPPRESS,1 ; ZERO SUPRESS; JMP SHORT DEC000 ; ; THIS ROUTINE CONVERTS A 32 BIT BINARY NUMBER IN DX,AX ; TO PRINTABLE DECIMAL CHARS ; CONVTO10DIGITS: MOV SUPPRESS,0 DEC000: PUSH BX PUSH SI PUSH CX MOV CONVFLAG,0 MOV CX,8 MOV WORD PTR ACCUM,AX MOV WORD PTR ACCUM+2,DX MOV SI,OFFSET POWERS ; LOW ORDER OF FIRST DEC010: MOV BL,0 ; LOOP COUNT FOR SUBTRACT DEC020: CALL SUB4 JC DEC030 ; TOO SMALL INC BL ; NUMBER OF SUBTRACTS JMP DEC020 ; DEC030: CALL ADD4 ; PUT BACK MOV AL,BL ADD AL,'0' ; TO CHARACTER FORM TEST CONVFLAG,1 JNZ DEC040 ; ALREADY HAVE A SIGNIFICANT CHAR CMP AL,'0' ; IS IT A ZERO JE DEC036 ; YES, SO CHANGE TO SPACE OR CONVFLAG,1 ; SET NON-ZERO CHAR FOUND JMP SHORT DEC040 ; AND PRINT IT ; DEC036: CMP SUPPRESS,1 JE DEC044 ; SUPPRESS LEADING SPACES MOV AL,' ' DEC040: STOSB DEC044: ADD SI,4 LOOP DEC010 MOV AL,ACCUM ; REMAINDER ADD AL,'0' STOSB ; PRINT IT ; POP CX POP SI POP BX RET ; ; ROUTINE TO ADD TWO 4 BYTE NUMBERS ; ; ADD4: MOV AL,[SI] ADD ACCUM,AL MOV AL,[SI+1] ADC ACCUM+1,AL MOV AL,[SI+2] ADC ACCUM+2,AL MOV AL,[SI+3] ADC ACCUM+3,AL RET ; ; ROUTINE TO SUBTRACT TWO 4 BYTE NUMBERS ; ; SUB4: MOV AL,[SI] SUB ACCUM,AL MOV AL,[SI+1] SBB ACCUM+1,AL MOV AL,[SI+2] SBB ACCUM+2,AL MOV AL,[SI+3] SBB ACCUM+3,AL RET SETUPNODEHEADER: MOV SI,OFFSET MYCALL CALL DECODENODENAME ; REP MOVSB MOV AL,HEADERCHAR STOSB MOV AL,20H STOSB RET DECODENODENAME: ; ; SI = TABLE ENTRY WITH AX25 CALL AND ALIAS ; ; RETURNS SI = 20 BYTE DECODED NAME IN FORM ALIAS:CALL ; CX = LENGTH OF STRING ; PUSH DI MOV DI,OFFSET DECODEDNAME MOV CX,10 MOV AX,' ' REP STOSW ; CLEAR IT CALL CONVFROMAX25 CMP CX,10 JBE CXOK MOV CX,10 CXOK: PUSH CX ; SAVE CALL LENGTH MOV DI,OFFSET DECODEDNAME cmp BYTE PTR [SI],20H ; Does it start with a null or a space ? jbe NO_MNEMONIC MOV CX,6 ; MAX LENGTH DECODEN10: LODSB CMP AL,' ' JE DECODEN20 STOSB LOOP DECODEN10 DECODEN20: MOV AL,':' STOSB NO_MNEMONIC: POP CX MOV SI,OFFSET NORMCALL REP MOVSB MOV CX,DI POP DI MOV SI,OFFSET DECODEDNAME SUB CX,SI RET PRINTNUM: MOV AH,0 DIV D10 OR AX,3030H STOSW RET IF BLACKBITS PUBLIC CHECKBLACKLIST CHECKBLACKLIST: PUSH DI MOV DI,OFFSET BLACKLIST BCHECKLOOP: CMP BYTE PTR [DI],0 JE NOTBLACKED ; END OF LIST PUSH CX PUSH SI PUSH DI MOV CX,6 REP CMPSB POP DI POP SI POP CX JZ BLACKED ADD DI,7 ; TO NEXT ENTRY JMP BCHECKLOOP NOTBLACKED: OR AL,1 BLACKED: POP DI RET ENDIF IFDEF SYSOP ; ; SYSOP STUFF ; DATA SEGMENT PUBLIC 'DATA' WHATMSG DB 'Invalid Command',0dh WAS DB ' was ',0 BADMSG DB 'Bad Parameter',0dh BADPORT DB 'Invalid Port Number',0dh NOVALCALLS DB 'No Valid Calls defined on this port',0dh PWTEXT DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' DB 'AAAAAAAAAAAAAAAAAAAAAAAAAA' DB 'AAAAAAAAAAAAAAAAAAAAAAAAAA' PWLEN DB 26 VALNODESFLAG DB 0 PWCHARS DB 5 DUP (0) ; PROMPT SENT PWFLAG DB 0 ; SET WHEN RESPONSE NEEDED NUMBER DB 5 DUP (0) HEXFLAG DB 0 PORTNO DB 0 ; PORT NO FROM COMMAND NEWVALUE DB 0 ZAPFLAG DB 0 ; CLEAR ROUTE STATS FLAG ROUTEPORT DB 0 ; PORT FOR ROUTE UPDATE NEWROUTEVAL DB 0 ROUTEDISP DB 0 ; DISPLAY/UPDATE FLAG PUBLIC RAN1,RAN2,RAN3,RAN4,RAN5,PWTEXT,PWLEN RAN1 DB 2 RAN2 DB 3 RAN3 DB 4 RAN4 DB 5 RAN5 DB 6 B10 DB 10 IFDEF SWITCH FILENAME DB 'BPQNODES',0 HANDLE DW 0 LINE DB 80 DUP (0) ROUTEADD DB 'ROUTE ADD ' NODEADD DB 'NODE ADD ' ENDIF DATA ENDS PUBLIC WARMSTART,COLDSTART SENDNODES: PUSH BX PUSH DI ; CALL SENDNODESMSG POP DI POP BX JMP SENDOK COLDSTART: ; ; CLEAR RAM AND FORCE A RESTART ; CLI MOV DI,0 MOV CX,8000H MOV AX,0 REP STOSW WARMSTART: CLI IFDEF KANT ; ; FORCE A RESTART - USE WATCHDOG ; JMP WARMSTART ; WAIT FOR WATCHDOG TO RESET US ENDIF IFDEF MSC ; DB 0EAH,0,0,0FFH,0FFH ; JMP FFFF:0 DB 0EAH,0,0,0H,10H ; JMP 1000:0 ENDIF PWDCMD: ; ; REQUEST PASSWORD OR SYSOP AUTHORITY ; CALL SCAN IF TNC2 TEST L4CIRCUITTYPE[BX],HOST+BPQHOST ELSE TEST L4CIRCUITTYPE[BX],BPQHOST ENDIF JNZ PASSOK ; HOST - SET AUTHORISED REGARDLESS CMP BYTE PTR [SI],20H JNE CHECKPASS ; PASSWORD SUPPLIED ; ; SEND PASSWORD PROMPT ; MOV DX,0 ; CHECKSUM OF VALUE SENT MOV SI,OFFSET RAN1 MOV CX,5 RANLOOP: LODSB PUSH CX CALL PWCHR POP CX PUSH BX MOV BX,OFFSET PWTEXT-1 MOV AH,0 ADD BX,AX MOV AL,[BX] ; CHARACTER EQUIVALENT POP BX ADD DL,AL ADC DH,0 MOV AL,20H STOSB LOOP RANLOOP MOV AL,0DH STOSB MOV PASSWORD[BX],DX JMP SENDCOMMANDREPLY PWCHR: ; ; LIMIT NUMBER IN A TO RANGE 1 - PW LENGTH ; CMP PWLEN,0 JE NOPW ; PASSWORD NOT SET PWL000: OR AL,AL JZ TOOLOW SUB AL,PWLEN JZ TOOLOW JNC PWL000 ; LOOP TILL -VE OR ZERO TOOLOW: ADD AL,PWLEN NOPW1: PUSH AX MOV AH,0 DIV D10 ADD AX,3030H STOSW POP AX ; RETURN NUMBER ; RET NOPW: MOV AL,1 JMP SHORT NOPW1 CHECKPASS: MOV DX,0 MOV CX,5 CHECKLOOP: LODSB ADD DL,AL ADC DH,0 LOOP CHECKLOOP CMP PASSWORD[BX],DX JNE DUFFPW PASSOK: MOV PASSWORD[BX],0FFFFH ; SET AUTHORISED SENDOK: MOV SI,OFFSET OKMSG MOVSW MOVSB JMP SENDCOMMANDREPLY DUFFPW: JMP NOREPLY DISPCLOCK: ; ; DISPLAY OR SET RTC ; IFDEF KANT CALL SCAN CMP BYTE PTR [SI],20H JNE SETCLOCK DISPLAYTIME: MOV AL,1 OUT CLOCK_D,AL GETTIMELOOP: IN AL,CLOCK_D ; WAIT FOR NOT BUSY TEST AL,2 JZ OKTOREAD MOV AL,0 OUT CLOCK_D,AL MOV AL,1 OUT CLOCK_D,AL JMP GETTIMELOOP OKTOREAD: IN AX,CLOCK_HOUR AND AX,0F0FH ADD AX,3030H PUSH AX MOV AL,AH STOSB POP AX STOSB MOV AL,':' STOSB IN AX,CLOCK_MINUTE AND AX,0F0FH ADD AX,3030H PUSH AX MOV AL,AH STOSB POP AX STOSB MOV AL,0DH STOSB MOV AL,0 OUT CLOCK_D,AL JMP SENDCOMMANDREPLY SETCLOCK: CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH PUSH AX ; SAVE HOURS CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH PUSH AX ; SAVE MINUTES ; ; start real time clock ; mov al,3 out CLOCK_F,al mov al,7 out CLOCK_F,al mov al,1 out CLOCK_E,al out CLOCK_D,al xor ax,ax out CLOCK_SECOND,ax POP AX ; MINS XOR AH,AH DIV D10 XCHG AH,AL OUT CLOCK_MINUTE,ax POP AX ; HOURS XOR AH,AH DIV D10 XCHG AH,AL out CLOCK_HOUR,ax mov al,1 out CLOCK_DAY,ax out CLOCK_MONTH,ax mov ax,900h out CLOCK_YEAR,ax mov al,4 out CLOCK_F,al xor ax,ax out CLOCK_D,al JMP DISPLAYTIME ENDIF IFDEF MSC CALL SCAN CMP BYTE PTR [SI],20H JNE SETCLOCK DISPLAYTIME: MOV AL,HOURS CALL PRINTNUM MOV AL,':' STOSB MOV AL,MINS CALL PRINTNUM MOV AL,':' STOSB MOV AL,SECS CALL PRINTNUM MOV AL,0DH STOSB JMP SENDCOMMANDREPLY SETCLOCK: CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH MOV HOURS,AL CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH MOV MINS,AL CALL GETVALUE MOV SECS,AL JMP DISPLAYTIME ENDIF IFDEF SWITCH MOV AX,40H MOV ES,AX MOV AX,ES:6CH MOV DX,0 DIV WORD PTR D1093 ; MINS TO AL MOV DL,AL ; SAVE MOV AL,ES:6EH ; HOURS PUSH DS POP ES CALL PRINTNUM MOV AL,':' STOSB MOV AL,DL CALL PRINTNUM ; JMP SENDCOMMANDREPLY ENDIF VALNODES: MOV VALNODESFLAG,1 PORTVAL: ; ; PROCESS PORT VALUE COMMANDS ; ; SI = COMMAND STRING ; DI = REPLY BUFFER ; BX = SESSION ; PUSH BX ; SAVE SESSION CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC PBADVALUE ; INVALID DIGITS MOV PORTNO,AL ; SAVE PORT NUMBER MOV BX,PORTTABLE MOV CH,0 MOV CL,NUMBEROFPORTS FINDPORT: CMP AL,PORTNUMBER[BX] JE PORTOK MOV BX,PORTPOINTER[BX] LOOP FINDPORT MOV SI,OFFSET BADPORT JMP ERRCOM PORTOK: CMP VALNODESFLAG,1 JE DISPVALNODES CALL SCAN CMP BYTE PTR [SI],20H JBE DISPVAL ; DISPLAY ONLY CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC PBADVALUE ; INVALID DIGITS MOV CL,0 CALL KEYDISP ; DISPLAY KEYWORD WAS MOV SI,CMDPTR ; ADDR OF CMDX ENTRY MOV SI,CMDFLAG[SI] ; ADDR OF FLAG MOV AH,[SI][BX] ; GET OLD VALUE MOV AL,BYTE PTR VALUE MOV [SI][BX],AL ; SET FLAG MOV AL,AH ; DISPLAY OLD MOV AH,0 JMP VALDISP PBADVALUE: MOV SI,OFFSET BADMSG ERRCOM: CALL SENDSTRING POP BX JMP SENDCOMMANDREPLY DISPVALNODES: CMP PERMITTEDCALLS[BX],0 JNE VALN00 MOV SI,OFFSET NOVALCALLS JMP ERRCOM ; NONE TO DISPLAY VALN00: MOV SI,PERMITTEDCALLS[BX] VALN10: CMP BYTE PTR [SI],0 JE VALNRET ; FINISHED MOV AX,0 CALL CMDR95 ADD SI,7 JMP VALN10 VALNRET: MOV AL,CR CALL SENDCHAR JMP SENDCOMMANDREPLY DISPVALW: MOV CX,1 CALL KEYDISP MOV SI,CMDPTR MOV SI,CMDFLAG[SI] ; ADDR OF FLAG MOV AX,[SI][BX] ; GET VALUE JMP SHORT VALDISP DISPVAL: MOV CX,1 CALL KEYDISP MOV SI,CMDPTR MOV SI,CMDFLAG[SI] ; ADDR OF FLAG MOV AL,[SI][BX] ; GET VALUE MOV AH,0 VALDISP: CALL CONV_5DIGITS MOV AL,0DH CALL SENDCHAR POP BX JMP SENDCOMMANDREPLY KEYDISP: PUSH CX MOV SI,CMDPTR MOV CX,12 ; MAX LENGTH CALL PUTSTRING MOV AL,20H CALL SENDCHAR ; ; IF A PORT PARAM, DISPLAY PORT NO ; CMP BX,0 JE NOPORTDISP MOV AL,PORTNO CALL CONV_DIGITS MOV AL,20H CALL SENDCHAR NOPORTDISP: MOV SI,OFFSET WAS ; DISPLAY 'was' POP CX OR CL,CL MOV CX,5 JZ KEYDISP12 ; NO MOV CX,1 ; LEAVE OUT 'WAS' KEYDISP12: CALL PUTSTRING RET SWITCHVAL: ; ; PROCESS OTHER VALUE COMMANDS ; ; SI = COMMAND STRING ; DI = REPLY BUFFER ; BX = SESSION ; PUSH BX ; SAVE SESSION MOV BX,0 ; NO PORT CALL SCAN CMP BYTE PTR [SI],20H JBE DISPVAL ; DISPLAY ONLY CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JNC VAL_OK JMP PBADVALUE ; INVALID DIGITS VAL_OK: MOV CL,0 CALL KEYDISP ; DISPLAY KEYWORD WAS MOV SI,CMDPTR ; ADDR OF CMDX ENTRY MOV SI,CMDFLAG[SI] ; ADDR OF FLAG MOV AH,[SI] ; GET OLD VALUE MOV AL,BYTE PTR VALUE MOV [SI],AL ; SET FLAG MOV AL,AH ; DISPLAY OLD MOV AH,0 JMP VALDISP SWITCHVALW: ; ; PROCESS 16 BIT VALUE COMMANDS ; ; SI = COMMAND STRING ; DI = REPLY BUFFER ; BX = SESSION ; PUSH BX ; SAVE SESSION MOV BX,0 ; NO PORT CALL SCAN CMP BYTE PTR [SI],20H JA NOTJUSTDISP JMP DISPVALW ; DISPLAY ONLY NOTJUSTDISP: CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JNC VAL_OKW JMP PBADVALUE ; INVALID DIGITS VAL_OKW: MOV CL,0 CALL KEYDISP ; DISPLAY KEYWORD WAS MOV SI,CMDPTR ; ADDR OF CMDX ENTRY MOV SI,CMDFLAG[SI] ; ADDR OF FLAG PUSH [SI] ; GET OLD VALUE MOV AX,VALUE MOV [SI],AX ; SET FLAG POP AX JMP VALDISP IFDEF BLACKLIST DISPBLACKLIST: BLIST00: CALL SCAN CMP BYTE PTR [SI],20H JBE DISPLIST ; DISPLAY ONLY PUSH DI CMP WORD PTR [SI],' Z' JNE UPLIST ; ; CLEAR LIST ; MOV DI,OFFSET BLACKLIST MOV BLACKEND,DI MOV CX,70 MOV AL,0 REP STOSB BDISPIT: POP DI JMP SHORT DISPLIST UPLIST: CALL CONVTOAX25 MOV DI,BLACKEND CMP DI,OFFSET BLACKLIST+70 JE BDISPIT MOV SI,OFFSET AX25CALL MOV CX,6 REP MOVSB ADD BLACKEND,7 JMP BDISPIT DISPLIST: MOV SI,OFFSET BLACKLIST BLIST10: CMP BYTE PTR [SI],0 JE BLISTRET ; FINISHED MOV AX,0 CALL CMDR95 ADD SI,7 JMP BLIST10 BLISTRET: MOV AL,CR CALL SENDCHAR JMP SENDCOMMANDREPLY ENDIF PUTSTRING: ; ; SEND STRING LENGTH CX TO NODE ; LODSB CALL SENDCHAR LOOP PUTSTRING RET SENDCHAR: ; STOSB RET ; ; SENDSTRING: ; ; SEND STRING TO NODE ; LODSB PUSH AX CALL SENDCHAR POP AX CMP AL,0DH JNE SENDSTRING RET ROUTEUPDATE: CMP PASSWORD[BX],0FFFFH JE GOTPASS JMP PASSERROR GOTPASS: PUSH BX ; SAVE SESSION PUSH DI ; SAVE BUFFER CALL CONVTOAX25 CALL SCAN CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC BADROUTECMD ; INVALID DIGITS MOV SAVEPORT,AL CALL SCAN MOV ROUTEDISP,1 CMP BYTE PTR [SI],20H JE JUSTDISPLAY MOV ZAPFLAG,0 CMP BYTE PTR [SI],'Z' JNE NOTZAP MOV ZAPFLAG,1 JMP SHORT JUSTDISPLAY NOTZAP: MOV ROUTEDISP,2 ; LOCK UPDATE CMP BYTE PTR [SI],'!' JE JUSTDISPLAY ; ; LOOK FOR V FOR ADDING A DIGI ; CMP WORD PTR [SI],' V' ; V [SPACE] JE ADDDIGI CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC BADROUTECMD ; INVALID DIGITS MOV NEWROUTEVAL,AL MOV ROUTEDISP,0 CALL SCAN ; SEE IF ! MOV AH,[SI] JUSTDISPLAY: MOV SI,OFFSET AX25CALL CALL FINDNEIGHBOUR JZ FOUNDROUTE ; IN LIST - OK CMP BX,0 JE BADROUTECMD ; TABLE FULL?? MOV CX,7 MOV DI,BX REP MOVSB ; PUT IN CALL MOV AL,SAVEPORT MOV NEIGHBOUR_PORT[BX],AL JMP FOUNDROUTE BADROUTECMD: POP DI JMP PBADVALUE FOUNDROUTE: CMP ZAPFLAG,1 JNE NOTCLEARCOUNTS XOR AX,AX MOV ES:WORD PTR NBOUR_IFRAMES[DI],AX MOV ES:WORD PTR NBOUR_IFRAMES+2[DI],AX MOV ES:WORD PTR NBOUR_RETRIES[DI],AX MOV ES:WORD PTR NBOUR_RETRIES+2[DI],AX JMP SHORT NOUPDATE NOTCLEARCOUNTS: CMP ROUTEDISP,1 JE NOUPDATE CMP ROUTEDISP,2 JE LOCKUPDATE MOV AL,NEWROUTEVAL MOV NEIGHBOUR_QUAL[BX],AL CMP AH,'!' JNE NOUPDATE LOCKUPDATE: XOR NEIGHBOUR_FLAG[BX],1 ; FLIP LOCKED BIT NOUPDATE: MOV SI,BX POP DI POP BX CALL DISPLAYROUTE JMP SENDCOMMANDREPLY ADDDIGI: ADD SI,2 PUSH SI ; SAVE INPUT BUFFER MOV SI,OFFSET AX25CALL CALL FINDNEIGHBOUR POP SI JZ ADD_FOUND ; IN LIST - OK JMP BADROUTECMD ADD_FOUND: CALL CONVTOAX25 ; GET DIGI CALLSIGN PUSH SI MOV SI,OFFSET AX25CALL LEA DI,NEIGHBOUR_DIGI[BX] MOV CX,7 REP MOVSB POP SI ; MSG BUFFER ; ; SEE IF ANOTHER DIGI ; CMP BYTE PTR [SI],20H JE NOMORE CALL CONVTOAX25 ; GET DIGI CALLSIGN MOV SI,OFFSET AX25CALL LEA DI,NEIGHBOUR_DIGI+7[BX] MOV CX,7 REP MOVSB NOMORE: JMP NOUPDATE NODE_ADD: CMP PASSWORD[BX],0FFFFH JE GOTPASS1 JMP PASSERROR GOTPASS1: ; ; FORMAT IS NODE ADD ALIAS:CALL ROUTE QUAL ; ; FIND CALL (AFTER ':') ; PUSH BX ; SAVE SESSION PUSH DI ; REPLY BUFFER ADD SI,4 MOV DI,OFFSET TEMPFIELD MOV CX,7 ; MAX ALIAS PNODE30: LODSB CMP AL,':' JE PNODE40 STOSB LOOP PNODE30 PNODE35: JMP BADROUTECMD PNODE40: DEC CX JCXZ PNODE45 ; 6 CHAR ALIAS MOV AL,20H REP STOSB ; CLEAR REST OF ALIAS PNODE45: CALL CONVTOAX25 JNZ PNODE35 ; DUFF ; PUSH SI ; SAVE POINTER MOV SI,OFFSET AX25CALL CALL FINDDESTINATION JZ PNODE47 ; ALREADY THERE CMP BX,0 JNE PNODE48 PNODE47: POP SI JMP PNODE35 ; NOROOMFORNODE PNODE48: LEA DI,DEST_CALL[BX] MOV CX,7 REP MOVSB MOV CX,6 ; ADD ALIAS MOV SI,OFFSET TEMPFIELD REP MOVSB POP SI ; ; GET NEIGHBOURS FOR THIS DESTINATION ; CALL CONVTOAX25 JNZ BADROUTE ; CALL GETVALUE MOV SAVEPORT,AL ; SET PORT FOR FINDNEIGHBOUR CALL GETVALUE MOV ROUTEQUAL,AL ; MOV SI,OFFSET AX25CALL PUSH BX ; SAVE DEST CALL FINDNEIGHBOUR MOV AX,BX ; ROUTE TO AX POP BX JZ NOTBADROUTE JMP BADROUTE NOTBADROUTE: ; ; UPDATE ROUTE LIST FOR THIS DEST ; MOV ROUT1_NEIGHBOUR[BX],AX MOV AL,ROUTEQUAL MOV ROUT1_QUALITY[BX],AL MOV ROUT1_OBSCOUNT[BX],255 ; LOCKED ; CALL CHAINNODE POP DI POP BX JMP SENDOK BADROUTE: ; ; KILL IT ; MOV CX,TYPE DEST_LIST MOV DI,BX MOV AL,0 REP STOSB JMP BADROUTECMD NODE_DEL: CMP PASSWORD[BX],0FFFFH JE GOTPASS2 JMP PASSERROR GOTPASS2: ; ; FORMAT IS NODE DEL ALL ; ; PUSH BX ; SAVE SESSION PUSH DI ; REPLY BUFFER ADD SI,4 CALL CONVTOAX25 JNZ DNODE45 ; DUFF ; MOV SI,OFFSET AX25CALL CALL FINDDESTINATION JZ DNODE48 ; FOUND DNODE45: JMP PNODE35 DNODE48: CALL UNCHAINNODE ; ; KILL IT ; MOV CX,TYPE DEST_LIST MOV DI,BX MOV AL,0 REP STOSB POP DI POP BX JMP SENDOK ; ENDIF REMDUMP: ; CALL SCAN CALL GETVALUEHEX ; GET NUMBER, UP TO SPACE , CR OR OFFH MOV DUMPPTR[BX],AX MOV SI,OFFSET OKMSG MOVSW MOVSB JMP SENDCOMMANDREPLY PUBLIC BUILD_DUMP_FRAME BUILD_DUMP_FRAME: ; ; GET BUFFER ; CMP QCOUNT,20 JB DUMPRET CALL GETBUFF JNZ B_DUMP10 ; OK ; ; NO BUFFERS (!!) - ABORT ; DUMPRET: RET B_DUMP10: MOV REPLYBUFFER,DI ; ; SET UP HEADER ; LEA DI,5[DI] ; SKIP HEADER MOV AL,0F0H STOSB ; PID MOV AX,0AAAAH STOSW ; FLAG MOV AX,DUMPPTR[BX] STOSW ; ADDR MOV SI,AX MOV CX,192 ; ; FIND FIRST NZ BYTE ; FINDNZ: LODSB CMP AL,0 JNE DOCOPY INC WORD PTR -2[DI] ; START INC DUMPPTR[BX] JZ B_DUMP20 ; FINISHED CMP SI,0 JNE FINDNZ ; ; NO MORE ; JMP B_DUMP20 DOCOPY: DEC SI REP MOVSB ADD DUMPPTR[BX],192 JNC B_DUMP20 ; ; END ; B_DUMP15: MOV DUMPPTR[BX],0 B_DUMP20: ; ; SCAN BACK TO FIRST NZ ; DEC DI CMP BYTE PTR [DI],0 JE B_DUMP20 INC DI JMP SENDCOMMANDREPLY ENDIF DUMPCMD: ; CALL SCAN CALL GETVALUEHEX ; GET NUMBER, UP TO SPACE , CR OR OFFH MOV SI,AX MOV AL,0DH STOSB CALL DOLINE CALL DOLINE JMP SENDCOMMANDREPLY DOLINE: MOV DX,SI MOV AL,DH ; DISPLAY ADDR CALL B2HEX MOV AL,20H STOSB MOV AL,DL CALL B2HEX MOV AX,20H STOSB STOSB MOV CX,16 DUMP00: LODSB CALL B2HEX MOV AL,20H STOSB LOOP DUMP00 MOV AL,0DH STOSB RET ; IFDEF SWITCH SAVENODES: PUSH BX PUSH DI ; ; OPEN FILE ; MOV DX,OFFSET FILENAME MOV CX,0 MOV AH,3CH INT 21H MOV HANDLE,AX CALL DOROUTES CALL DONODES MOV BX,HANDLE MOV AH,3EH INT 21H ; CLOSE FILE ; POP DI POP BX JMP SENDOK DONODES: MOV SI,OFFSET NODEADD MOV DI,OFFSET LINE MOV CX,9 CLI REP MOVS LINE, NORMCALL STI MOV BX,DESTS MOV CX,MAXDESTS XCMDN10: PUSH CX MOV DI,OFFSET LINE+9 CMP DEST_CALL[BX],0 JE XCMDN20 ; SPARE ; TEST DEST_STATE[BX],80H JNZ XCMDN20 ; SPECIAL (BBS) NODE LEA SI,DEST_CALL[BX] CALL DECODENODENAME ; CONVERT TO ALIAS:CALL MOV CX,18 XCMDN15: LODS NORMCALL STOSB CMP AL,' ' JE XCMDN16 LOOP XCMDN15 XCMDN16: PUSH BX MOV CX,3 XCMDN110: MOV SI,ROUT1_NEIGHBOUR[BX] CMP SI,0 JE XCMDN199 PUSH CX PUSH SI ; SAVE NEIGHBOUR PUSH DI CALL CONVFROMAX25 ; CONVERT TO CALL POP DI MOV SI,OFFSET NORMCALL NCOPY: LODS NORMCALL STOSB CMP AL,' ' JNE NCOPY ; ; GET PORT FROM ROUTES ENTRY ; POP SI MOV AL,NEIGHBOUR_PORT[SI] CALL XCONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS mov AL,' ' stosb MOV AL,ROUT1_QUALITY[BX] CALL XCONV_DIGITS ; CONVERT AL TO DECIMAL DIGITS mov AL,' ' stosb TEST ROUT1_OBSCOUNT[BX],80H JZ NOTLOCKEDDEST MOV AX,' !' STOSW NOTLOCKEDDEST: ADD BX,4 POP CX LOOP XCMDN110 XCMDN199: MOV AX,0A0DH STOSW MOV DX,OFFSET LINE MOV CX,DI SUB CX,DX ; GET LENGTH MOV BX,HANDLE MOV AH,40H INT 21H POP BX XCMDN20: POP CX ADD BX,TYPE DEST_LIST LOOP XCMDN10_JMP ; TOO FAR! XCMDN99A: RET XCMDN10_JMP: JMP XCMDN10 DOROUTES: ; MOV SI,OFFSET ROUTEADD MOV DI,OFFSET LINE MOV CX,10 CLI REP MOVS LINE, NORMCALL STI MOV SI,DS:NEIGHBOURS MOV CX,DS:MAXNEIGHBOURS XCMDR10: PUSH CX MOV DI,OFFSET LINE+10 CMP NEIGHBOUR_CALL[SI],0 JE XCMDR92 ; SPARE ; MOV AX,0 CALL XCMDR95 ; DISPLAY CALL MOV AL,NEIGHBOUR_PORT[SI] CALL XCONV_DIGITS MOV AL,20H STOSB MOV AL,NEIGHBOUR_QUAL[SI] CALL XCONV_DIGITS MOV AL,20H STOSB TEST NEIGHBOUR_FLAG[SI],1 JZ XNOTLOCKED MOV AL,'!' STOSB XNOTLOCKED: ; ; CHECK FOR DIGIS ; CMP NEIGHBOUR_DIGI[SI],0 JE XCMDR50 MOV AL,20H STOSB MOV AX,'IV' STOSW MOV AX,' A' STOSW ; PUT IN VIA MOV AX,7 CALL XCMDR95 ; DISPLAY DIGI CALL CMP NEIGHBOUR_DIGI+7[SI],0 JE XCMDR50 MOV AX,14 CALL XCMDR95 ; DISPLAY 2ND DIGI CALL XCMDR50: MOV AL,20H STOSB MOV AL,NBOUR_MAXFRAME[SI] CALL XCONV_DIGITS MOV AL,20H STOSB MOV AL,NBOUR_FRACK[SI] CALL XCONV_DIGITS MOV AL,20H STOSB MOV AL,NBOUR_PACLEN[SI] CALL XCONV_DIGITS XCMDR90: MOV AX,0A0DH STOSW MOV DX,OFFSET LINE MOV CX,DI SUB CX,DX ; GET LENGTH MOV BX,HANDLE MOV AH,40H INT 21H XCMDR92: POP CX ADD SI,TYPE NEIGHBOUR_LIST LOOP XCMDR10_JMP RET XCMDR10_JMP: JMP XCMDR10 XCMDR95: PUSH SI PUSH DI ADD SI,AX CALL CONVFROMAX25 INC CX MOV SI,OFFSET NORMCALL POP DI CLI REP MOVS LINE, NORMCALL STI POP SI RET XCONV_DIGITS: CMP AL,10 JB XUNITS cmp AL,100 jb XTENS MOV AH,0 DIV D100 OR AL,30H STOSB mov AL,AH XTENS: CBW DIV D10 OR AL,30H STOSB MOV AL,AH ; REMAINDER = UNITS XUNITS: add AL,30H STOSB ret ENDIF CODE ENDS END