PAGE 56,132 ; ; TNC2 INFERFACE MODULE FOR G8BPQ SWITCH ; LF EQU 0AH CR EQU 0DH ; ; JULY 92 FIX BUGS ; ; AH=1F,AL=2 WAS RETURNING BUFFER COUNT IN AX INSTEAD OF AH ; ; NDREAD (INT14 FN8) DIDNT LOOK FOR DATA FROM NODE ; ; PACLEN BEING OVERWRITTEN BY VALUE FROM NODE ; ; DEC 94 ; ; USE NEW AH=0 CALL TO CHECK IF SWITCH IS LOADED ; CODE SEGMENT ASSUME DS:CODE, CS:CODE ORG 0100H INCLUDE ENVIRON.ASM GO: JMP INIT TNCBUFFLEN EQU 1024 TNCDATA STRUC RXBUFFER DB TNCBUFFLEN DUP (?) ; BUFFER TO USER TXBUFFER DB 260 DUP (?) ; BUFFER TO NODE BIOSPORT DB ? ; INT 14 PORT NUMBER NODEPORT DB ? ; BPQHOST PORT NUMBER ; VMSR DB ? ; VIRTUAL MSR RTSFLAG DB ? ; BIT 0 SET IF RTS/DTR UP VLSR DB ? ; LAST RECEIVED LSR VALUE RXCOUNT DW ? ; BYTES IN RX BUFFER PUTPTR DW ? ; POINTER FOR LOADING BUFFER GETPTR DW ? ; POINTER FOR UNLOADING BUFFER CURSOR DW ? ; POSTION IN KEYBOARD BUFFER ;KBSESSION DW ? ; POINTER TO L4 SESSION ENTRY FOR CONSOLE ; DW 14 DUP (?) ; 14 MORE SESSIONS FOR HOST MODE PORT MSGLEN DW ? TRANSTIMER DB ? ; TRANPARENT MODE SEND TIMOUT AUTOSENDFLAG DB ? ; SET WHEN TRANSMODE TIME EXPIRES TRACEFLAG DB ? ; MONITOR ON/OFF ECHOFLAG DB ? ; ECHO ON/OFF FLOWFLAG DB ? ; FLOW OFF/ON CONOK DB ? CBELL DB ? NOMODE DB ? ; MODE CHANGE FLAGS NEWMODE DB ? CONMODEFLAG DB ? ; CONNECT MODE - CONV OR TRANS LFIGNORE DB ? MCON DB ? ; TRACE MODE FLAGS MCOM DB ? MALL DB ? BBSMON DB ? ; SPECIAL SHORT MONITOR FOR BBS MTX DB ? ; MONITOR TRANSMITTED FRAMES MTXFORCE DB ? ; MONITOR TRANSMITTED FRAMES EVEN IF M OFF MMASK DW ? ; MONITOR PORT MASK HEADERLN DB ? ; PUT MONITORED DATA ON NEW LINE FLAG MODEFLAG DB ? ; COMMAND/DATA MODE APPLICATION DB ? ; BIT SIGNIFICANT FIELD TO DEFINE ; WHICH APPLICATION PORT SUPPORTS ; BIT 0 = BBS FOR BACKWARD COMPATIBILITY ; BIT 1 = HOST (BY CONVENTION) ; BIT 2 = SYSOP (DITTO) ; BITS 3 - 7 - USER DEFINABLE ; APPLFLAGS DB ? ; FLAGS TO CONTROL APPL SYSTEM HOSTFLAG DB ? ; SET WHEN RUNNING HOST MODE ;MAXHOSTSESSIONS DB ? ; MAX SESSIONS ON HOST MODE PORT ;HOSTREPLYCURSOR DW 0 ;HOSTREPLYBUFFER DW 0 SENDPAC DB ? ; SEND PACKET CHAR CPACTIME DB ? ; USE PACTIME IN CONV MODE CRFLAG DB ? ; APPEND SENDPAC FLAG TPACLEN DB ? ; MAX PACKET SIZE FOR TNC GENERATED PACKETS UNPROTO DB 64 DUP (?) ; UNPROTO DEST AND DIGI STRING TNCDATA ENDS ; ; MODEFLAG DEFINITIONS ; COMMAND EQU 1B TRANS EQU 10B CONV EQU 100B ; ; APPL DEFINITIONS ; BBSAPPL EQU 1B HOSTAPPL EQU 10B SYSOPAPPL EQU 100B ; ; HOSTFLAG DEFINITIONS ; ;HOSTMODE EQU 1B ; PK232 HOSTMODE ENABLED ;HOSTESCBIT EQU 10B ; IN ESCAPE SEQUENCE ;UFQ EQU 100B ; UFQ MODE (IE NOT AA4RE) ;POLLED EQU 1000B ; POLL RECEIVED ; ; APPLFLAGS BITS ; CMD_TO_APPL EQU 1B ; PASS COMMAND TO APPLICATION MSG_TO_USER EQU 10B ; SEND 'CONNECTED' TO USER MSG_TO_APPL EQU 100B ; SEND 'CONECTED' TO APPL ; LASTTIME DW 0 ; LAST VALUE OF TICKS COUNTER MONITORDATA DB 350 DUP (0) ; RAW FRAME FROM NODE D10 DW 10 ; ; BASIC LINK LEVEL MESSAGE BUFFER LAYOUT ; MESSAGE STRUC MSGCHAIN DW ? ; CHAIN WORD MSGPORT DB ? ; PORT MSGLENGTH DW ? ; LENGTH MSGDEST DB 7 DUP (?) ; DESTINATION MSGORIGIN DB 7 DUP (?) ; ORIGIN ; ; MAY BE UP TO 56 BYTES OF DIGIS ; MSGCONTROL DB ? ; CONTROL BYTE MSGPID DB ? ; PROTOCOL IDENTIFIER MSGDATA DB ? ; START OF LEVEL 2 MESSAGE ; MESSAGE ENDS ; TABLELEN DW TYPE TNCDATA ; LNKSTATEMSG DB 'Link state is: ' CONNECTEDMSG DB 'CONNECTED to ' WHATMSG DB 'Eh?',0DH CMDMSG DB 'cmd:' DISCONNMSG DB CR,'*** DISCONNECTED',CR CONMSG1 DB CR,'*** CONNECTED to ' CONCALL DB 10 DUP (0),CR CONMSG DB CR,'*** CONNECTED to ' SWITCH DB 'SWITCH',CR SWITCHSP DB 'SWITCH ' WAS DB ' was ' VIA DB ' via ' OFF DB 'OFF',0DH ON DB 'ON ',0DH CMDX STRUC DB ' ' ; COMMAND STRING CMDLEN DB ? ; SIGNIFICANT LENGTH CMDPROC DW ? ; COMMAND PROCESSOR CMDFLAG DW ? ; FLAG/VALUE ADDRESS CMDX ENDS COMMANDLIST LABEL BYTE CMDX <'BBSMON',6,ONOFF,BBSMON> ; BBS (SHORT FORM ) MONITOR BTCMD CMDX <'BTEXT',2,BTEXT> CMDX <'CONOK',4,ONOFF_CONOK,CONOK> CMDX <'C SWITCH',8,CSWITCH> CMDX <'CBELL',2,ONOFF,CBELL> CMDX <'CONMODE',4,CONMODE> CMDX <'CPACTIME',2,ONOFF,CPACTIME> CMDX <'CR',2,ONOFF,CRFLAG> CMDX <'APPLFLAG',5,APPL_VALHEX,APPLFLAGS> CMDX <'APPL',4,APPL_VALHEX,APPLICATION> CMDX <'CONVERS',4,TNCCONV> CMDX <'CONNECT',1,TNCCONNECT> CMDX <'DISCONNE',1,TNCDISC> CMDX <'ECHO',1,ONOFF,ECHOFLAG> CMDX <'FLOW',4,ONOFF,FLOWFLAG> CMDX <'HEADERLN',2,ONOFF,HEADERLN> CMDX <'K',1,TNCNODE> ; CONNECT TO NODE CMDX <'MTXFORCE',4,ONOFF,MTXFORCE> ; MONITOR TXED FRAMES WHEN M OFF CMDX <'LFIGNORE',3,ONOFF,LFIGNORE> ; IGNORE LF IN DATA FROM USER CMDX <'MTX',3,ONOFF,MTX> ; MONITOR TRANSMITTED FRAMES CMDX <'MALL',2,ONOFF,MALL> CMDX <'MCOM',4,ONOFF,MCOM> CMDX <'MCON',2,ONOFF,MCON> CMDX <'MMASK',2,VALWHEX,MMASK> ; MONITOR PORT MASK CMDX <'MONITOR',1,ONOFF,TRACEFLAG> CMDX <'NEWMODE',2,ONOFF,NEWMODE> CMDX <'NODE',3,TNCNODE> ; CONNECT TO NODE CMDX <'NOMODE',2,ONOFF,NOMODE> CMDX <'SENDPAC',2,VALHEX,SENDPAC> CMDX <'PACLEN',1,VALUE,TPACLEN> CMDX <'RELEASE',3,TNCRELEASE> CMDX <'TRANS',1,TNCTRANS> UNPROT CMDX <'UNPROTO',1,UNPROTOCMD> NUMBEROFCOMMANDS EQU ($-COMMANDLIST)/TYPE CMDX DISCFLAG DB 0 ; HOST MODE DISCONNECT PARAM (FOR STAY CHECK) LASTCH DB 0 ; ESC FLAG FOR HOST READ BUFFER NEWVALUE DW 0 HEXFLAG DB 0 D16 DB 16 NUMBER DB 4 DUP (0),CR NUMBERH DB '$0000',CR BADMSG DB '?bad parameter',CR,0 BTHDDR DW 0 ; CHAIN DB 0 ; PORT DW 7 ; LENGTH DB 0F0H ; PID BTEXTFLD DB 0DH,256 DUP (0) CMDENDADDR DW 0 ; POINTER TO END OF COMMAND MBOPTIONBYTE DB 0 NORMCALL DB 10 DUP (0) AX25CALL DB 7 DUP (0) 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 NORMLEN DW 0 EVEN TNCTABLE DW TABLE NUMBEROFSTREAMS DW 0 SAVEBX DW 0 TRANSDELAY DB 3 ; 1 SEC CR EQU 0DH LF EQU 0AH StartedFlag DB 0 TESTTIMER: ; ; SEE IF TIME TO CALL TIMER CODE ; PUSH AX TIMLOOP: MOV AH,15 CALL NODE SUB AX,CS:LASTTIME CMP AX,6 ; 1/3RD SEC JB LEAVETIMER ADD CS:LASTTIME,6 PUSH ES PUSH CS POP ES PUSH BX PUSH CX PUSH DX PUSH DI CALL TNCTIMERPROC POP DI POP DX POP CX POP BX POP ES JMP TIMLOOP LEAVETIMER: POP AX RET TNCTIMERPROC: ; ; CALLED AT 3HZ ; ; CHECK FOR TRANSPARENT MODE SEND TIMOUT ; cmp StartedFlag,0 je TIMRET MOV BX,TNCTABLE MOV CX,NUMBEROFSTREAMS JCXZ TIMRET MOV AH,0 TIM000: OR AH,TRACEFLAG[BX] ; SEE IF ANY PORTS ARE MONITORING CMP TRANSTIMER[BX],0 JE TIM100 ; NOTHING DOING DEC TRANSTIMER[BX] JNZ TIM100 ; STILL OK ; MOV AUTOSENDFLAG[BX],1 ; CANT DO IT HERE - WAIT TILL NEXT INT 14 TIM100: ; ADD BX,TYPE TNCDATA LOOP TIM000 ; ; IF ANY PORTS HAVE MONITOR ENABLED, SET MONITOR BIT ON FIRST PORT ; MOV CL,0 OR AH,AH JZ NO_MON MOV CL,80H ; TOP BIT CONTROLS MONITOR NO_MON: ; MOV BX,TNCTABLE MOV DL,APPLICATION[BX] OR CL,APPLFLAGS[BX] CMP CONOK[BX],0 JNE SETAPPLM MOV DL,0 ; STOP CONNECTS SETAPPLM: MOV AH,1 MOV AL,NODEPORT[BX] CALL NODE ; ; DO ANY MONITORING ; MOV BX,TNCTABLE MOV AL,NODEPORT[BX] MOV AH,11 MOV DI,OFFSET MONITORDATA CALL NODE CMP CX,0 JE TRACEEND MOV DI,OFFSET MONITORDATA MOV CX,NUMBEROFSTREAMS JCXZ TRACEEND ; TRACELOOP: PUSH BX PUSH CX PUSH DI CALL DISPLAYFRAME POP DI POP CX POP BX ADD BX,TYPE TNCDATA LOOP TRACELOOP TRACEEND: TIMRET: RET KEYSUPPORT: TEST MODEFLAG[BX],COMMAND JNZ KEYB06C ; COMMAND MODE - SKIP TRANS TEST TEST MODEFLAG[BX],TRANS JNZ KEYB06T ; TRANS MODE ; ; CONV MODE - SEE IF CPACTIME ON ; CMP CPACTIME[BX],0 JE KEYB06 ; NOT CPACTIME MOV AH,TRANSDELAY MOV TRANSTIMER[BX],AH ; REPRIME SEND TIMER JMP SHORT KEYB06 ; PROCESS CHAR KEYB06T: MOV AH,TRANSDELAY MOV TRANSTIMER[BX],AH JMP SHORT KBNORM ; TRANSPARENT MODE KEYB06: ; ; STILL JUST CONV MODE ; CMP AL,SENDPAC[BX] JNE NOTSENDPAC ; ; SEND PACKET CHAR - SHOUD WE SEND IT? ; MOV TRANSTIMER[BX],0 CMP CRFLAG[BX],1 JE KBCR_JMP ; SEND IT JMP SENDPACKET KBCR_JMP: JMP KBCR NOTSENDPAC: KEYB06C: ; ; COMMAND OR CONV MODE ; CMP AL,20H JB KBCTRL KBNORM: CMP MSGLEN[BX],256 JA TOOLONG ; PROTECT BUFFER ; INC MSGLEN[BX] MOV DI,CURSOR[BX] STOSB MOV CURSOR[BX],DI TOOLONG: TEST ECHOFLAG[BX],0FFH JZ NOECHO CALL KBECHO NOECHO: MOV AL,TPACLEN[BX] CMP BYTE PTR MSGLEN[BX],AL JB NOSEND ; ; DONT APPLY PACLEN IN COMMAND MODE ; TEST MODEFLAG[BX],COMMAND JNZ NOSEND JMP SENDPACKET NOSEND: RET KBCTRL: CMP LFIGNORE[BX],0 JE KBCTRL00 ; ; IF LF, IGNORE IT ; CMP AL,0AH JE NOSEND ; IGNORE RET KBCTRL00: CMP AL,8 JE KBBSPACE CMP AL,1AH ; CTRL/Z JE KBNORM ; FOR MBX TERMINATOR TEST MODEFLAG[BX],CONV JNZ CTRLREST ; CMP AL,0DH JE KBCR JMP SHORT CTRLREST ; ; CONV MODE ; CTRLREST: CMP AL,3 JE KBESCAPE ; RETURN TO COMMAND MODE ; CMP AL,14H ; CTRL/T JNE IGNORECTRL XOR TRACEFLAG[BX],1 RET IGNORECTRL: JMP KBNORM KBESCAPE: CALL SETCOMMANDMODE JMP KBRET ; EXIT SETCOMMANDMODE: CMP MSGLEN[BX],0 JE SETCOMM00 CALL SENDPACKET ; PROCESS WAITING DATA SETCOMM00: OR MODEFLAG[BX],COMMAND ; BACK TO COMMAND MODE AND MODEFLAG[BX],NOT (CONV+TRANS) MOV TRANSTIMER[BX],0 ; CANCEL TRANS MODE SEND TIMER MOV AUTOSENDFLAG[BX],0 ; IN CASE ALREADY SET MOV SI,OFFSET CMDMSG MOV CX,4 CALL SENDREPLY CALL KBRET RET KBBSPACE: CMP MSGLEN[BX],0 JE KBBS00 DEC MSGLEN[BX] DEC CURSOR[BX] TEST ECHOFLAG[BX],0FFH JZ KBBS00 CALL KBECHO KBBS00: RET KBCR: CALL KBNORM ; PUT CR IN BUFFER SENDPACKET: ; ; SEE IF COMMAND STATE ; TEST MODEFLAG[BX],COMMAND JZ NOTCOMMAND JMP TNCCOMMAND ; COMMAND TO TNC NOTCOMMAND: ; ; IF CONNECTED, SEND TO L4 (COMMAND HANDLER OR DATA), ; OTHERWISE SEND AS AN UNPROTO FRAME (TO ALL PORTS) ; TEST VMSR[BX],80H ; CONNECTED? JNZ SENDTOL4 ; ; SEND BUFFER AS AN UNPROTO FRAME ; MOV AL,0 ; UNPROTO STREAM JMP SHORT SENDTONODE SENDTOL4: TESTFORBUSY: ; TEST VMSR[BX],00010000B ; CHECK CTS JNZ NOTBUSY CALL RELEASE_TIMESLICE CALL CHECKCTS JMP TESTFORBUSY NOTBUSY: MOV AL,NODEPORT[BX] SENDTONODE: MOV CX,MSGLEN[BX] LEA SI,TXBUFFER[BX] MOV CURSOR[BX],SI ; RESET POINTER MOV AH,2 CALL NODE ; SEND FRAME MOV MSGLEN[BX],0 ; CALL CHECKCTS ; SEE IF NOW BUSY RET KBECHO: CALL PUTCHARINBUFFER ; RET TNCCOMMAND: ; ; PROCESS COMMAND TO TNC CODE ; LEA SI,TXBUFFER[BX] MOV DI,SI PUSH SI ; ; CONVERT TO UPPER CASE ; MOV CX,200 ; IN CASE GARBAGE!! TNCUCLOOP: LODSB CMP AL,0DH JE TNCUCEND CMP AL,61H JB TNCUCOK CMP AL,7AH JA TNCUCOK SUB AL,20H TNCUCOK: STOSB LOOP TNCUCLOOP ; TNCUCEND: MOV CMDENDADDR,SI ; SAVE REAL END OF COMMAND MOV AL,20H MOV CX,40 REP STOSB ; PUT A FEW SPACES ON END FOR DECODE ROUTINES POP SI CALL SCAN CMP BYTE PTR [SI],20H JE NULLCMD ; BLANK LINE MOV DI,OFFSET COMMANDLIST MOV CX,NUMBEROFCOMMANDS COMMANDLOOP: PUSH SI PUSH DI PUSH CX MOV CL,8[DI] ; MIN LENGTH REP CMPSB JE COMMANDFOUND POP CX POP DI POP SI ADD DI,TYPE CMDX LOOP COMMANDLOOP TNCDUFF: MOV SI,OFFSET WHATMSG MOV CX,4 CALL SENDREPLY NULLCMD: JMP SENDOK COMMANDFOUND: CMP BYTE PTR [SI],0DH JE ENDOFCOMMAND 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 TNCDUFF ENDOFCOMMAND: POP CX POP DI POP AX ; TO CLEAR STACK CALL SCAN JMP WORD PTR 9[DI] ; ENTER COMMAND PROCESSOR - ; SI POINTS TO CHAR FOLLOWING COMMAND SCAN: MOV CX,10 ; DONT LOOK TOO FAR! SCAN1: CMP BYTE PTR [SI],20H JNE SCANRET INC SI LOOP SCAN1 XOR AL,AL ; RETURN Z SCANRET: RET ; UNPROTOCMD: ; ; EXTRACT CALLSIGN STRING ; CMP BYTE PTR [SI],20H JE UNPROTODIS CMP BYTE PTR [SI],'*' JE CLEARUNPROTO CALL DECODECALLSTRING ; CONVERT TO AX25 FORMAT JZ UNPROTOOK JMP TNCDUFF CLEARUNPROTO: LEA DI,UNPROTO[BX] MOV AL,0 MOV CX,63 REP STOSB ; COPY IN UNPROTODIS: MOV AL,1 CALL DISPLAYUNPROTO ; DISPLAY CURRENT SETTING JMP SENDOK UNPROTOOK: PUSH SI MOV AL,0 CALL DISPLAYUNPROTO ; DISPLAY OLD STRRING POP SI LEA DI,UNPROTO[BX] MOV CX,63 REP MOVSB ; COPY IN JMP SENDOK CONMODE: JMP KBRET DISPLAYUNPROTO: ; PUSH AX MOV SI,OFFSET UNPROT MOV CX,8 CALL PUTSTRINGINBUFFER MOV SI,OFFSET WAS ; DISPLAY 'was' MOV CX,5 POP AX OR AL,AL JZ DISPU00 ; NO MOV CX,1 ; LEAVE OUT 'WAS' DISPU00: CALL PUTSTRINGINBUFFER LEA SI,UNPROTO[BX] CMP BYTE PTR [SI],40H JBE DISPUPRET CALL CONVFROMAX25 PUSH SI MOV SI,OFFSET NORMCALL CALL PUTSTRINGINBUFFER POP SI CMP BYTE PTR [SI],0 JE DISPUPRET PUSH SI MOV SI,OFFSET VIA MOV CX,5 CALL PUTSTRINGINBUFFER POP SI DISPUPLOOP: CALL CONVFROMAX25 PUSH SI MOV SI,OFFSET NORMCALL INC CX CALL PUTSTRINGINBUFFER POP SI CMP BYTE PTR [SI],0 JNE DISPUPLOOP DISPUPRET: MOV AL,0DH CALL PUTCHARINBUFFER RET TNCCONV: OR MODEFLAG[BX],CONV AND MODEFLAG[BX],NOT (COMMAND+TRANS) JMP KBRET TNCTRANS: ; ; MAKE PRETTY SURE THIS ISNT A BIT OF STRAY DATA ; CALL SCAN JZ TRANSOK JMP TNCDUFF TRANSOK: OR MODEFLAG[BX],TRANS AND MODEFLAG[BX],NOT (COMMAND+CONV) JMP KBRET TNCNODE: ; ; CONNECT TO NODE ; OR MODEFLAG[BX],CONV ; INTO CONVERSE MODE AND MODEFLAG[BX],NOT (COMMAND+TRANS) CALL CONNECTTONODE OR VMSR[BX],88H ; SET CONNECTED CALL READCHANGE ; CLEAR STATUS CHANGE (TO AVOID ; SUPURIOUS 'CONNECTED TO' JMP KBRET READCHANGE: MOV AH,4 MOV AL,NODEPORT[BX] CALL NODE ; MOV AH,5 MOV AL,NODEPORT[BX] CALL NODE ; ACK THE STATUS CHANGE RET BTEXT: ; CMP BYTE PTR [SI],20H JE BTDIS ; PUSH SI MOV AL,0 CALL DISPLAYBT ; DISPLAY OLD STRING POP SI MOV DI,OFFSET BTEXTFLD MOV CX,255 BTLOOP: LODSB STOSB CMP SI,CMDENDADDR ; END? JE BTEND LOOP BTLOOP BTEND: XOR AL,AL STOSB ; NULL ON END ; ; SET UP TO SEND IT AS A UI ; MOV CX,DI MOV SI,OFFSET BTHDDR SUB CX,SI MOV MSGLENGTH[SI],CX ; ; PASS TO SWITCH ; MOV SI,OFFSET BTEXTFLD SUB CX,6 ; DONT NEED HEADER MOV AH,12 ; UPDATE FUNCTIONS MOV DX,1 ; UPDATE BT CALL NODE ; PASS TO NODE JMP SENDOK BTDIS: MOV AL,1 CALL DISPLAYBT ; DISPLAY CURRENT SETTING JMP SENDOK DISPLAYBT: ; PUSH AX MOV SI,OFFSET BTCMD MOV CX,8 CALL PUTSTRINGINBUFFER MOV SI,OFFSET WAS ; DISPLAY 'was' MOV CX,5 POP AX OR AL,AL JZ DISPBT00 ; NO MOV CX,1 ; LEAVE OUT 'WAS' DISPBT00: CALL PUTSTRINGINBUFFER MOV SI,OFFSET BTEXTFLD DISPBT10: LODSB OR AL,AL JZ DISPBT20 CALL PUTCHARINBUFFER JMP DISPBT10 DISPBT20: MOV AL,0DH CALL PUTCHARINBUFFER RET CONVHEX: MOV BYTE PTR NUMBER,'$' INC DI B2HEX: PUSH AX SHR AL,1 SHR AL,1 SHR AL,1 SHR AL,1 CALL B1HEX POP AX B1HEX: AND AL,0FH CMP AL,10 JB B1HEX2 ADD AL,7 B1HEX2: ADD AL,30H STOSB RET UC: RET VALWHEX: ; ; WORD PARAM - SO FAR ONLY FOR MMASK ; CMP BYTE PTR [SI],20H JBE DISPWVAL ; DISPLAY ONLY CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC BADVALUE ; INVALID DIGITS MOV CL,0 CALL KEYDISP ; DISPLAY KEYWORD WAS MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV CX,[SI][BX] ; GET OLD VALUE MOV AX,NEWVALUE MOV [SI][BX],AX ; SET FLAG MOV AX,CX ; DISPLAY OLD JMP VALWDISP JMP SENDOK DISPWVAL: MOV CX,1 CALL KEYDISP MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV AX,[SI][BX] ; GET VALUE VALWDISP: MOV DI,OFFSET NUMBERH+1 PUSH AX MOV AL,AH CALL B2HEX POP AX CALL B2HEX MOV SI,OFFSET NUMBERH MOV CX,6 CALL PUTSTRINGINBUFFER JMP SENDOK VALHEX: MOV HEXFLAG,1 ; DISPLAY IN HEX VALUE: ; ; PROCESS COMMANDS WITH VALUE PARAMS ; CMP BYTE PTR [SI],20H JBE DISPVAL ; DISPLAY ONLY CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH JC BADVALUE ; INVALID DIGITS VALOK: MOV CL,0 CALL KEYDISP ; DISPLAY KEYWORD WAS MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV AH,[SI][BX] ; GET OLD VALUE MOV AL,BYTE PTR NEWVALUE MOV [SI][BX],AL ; SET FLAG MOV AL,AH ; DISPLAY OLD JMP VALDISP BADVALUE: MOV SI,OFFSET BADMSG ERRCOM: CALL NORMSTR JMP SENDOK DISPVAL: MOV CX,1 CALL KEYDISP DISPV00: MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV AL,[SI][BX] ; GET VALUE VALDISP: MOV WORD PTR NUMBER+1,2020H ; CLEAR OUT IN CASE LESS THAN 3 DIGITS MOV NUMBER+3,20H MOV DI,OFFSET NUMBER CMP HEXFLAG,1 JE DISPHEX CALL CONV_DIGITS JMP SHORT DISPCOM DISPHEX: CALL CONVHEX DISPCOM: MOV SI,OFFSET NUMBER MOV CX,5 CALL PUTSTRINGINBUFFER JMP SENDOK KEYDISP: PUSH CX MOV SI,DI MOV CX,8 ; MAX LENGTH CALL PUTSTRINGINBUFFER 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 PUTSTRINGINBUFFER RET PUBLIC GETVALUEF GETVALUEF: CALL SCAN CALL GETVALUE MOV AL,BYTE PTR NEWVALUE RETF GETVALUE: ; ; EXTRACT NUMBER (HEX OR DECIMAL) FROM INPUT STRING ; MOV NEWVALUE,0 LODSB CMP AL,'$' ; HEX? JE DECODEHEX DEC SI VALLOOP: LODSB CMP AL,' ' JE ENDVALUE CMP AL,0DH JE ENDVALUE CMP AL,',' JE ENDVALUE ; ; ANOTHER DIGIT - MULTIPLY BY 10 ; MOV AX,NEWVALUE MUL D10 MOV NEWVALUE,AX MOV AL,-1[SI] CALL UC SUB al,'0' JC DUFFVALUE CMP AL,10 JNC DUFFVALUE MOV AH,0 ADD NEWVALUE,AX JC DUFFVALUE JMP VALLOOP DECODEHEX: HEXLOOP: LODSB CMP AL,' ' JE ENDVALUE CMP AL,0FFH JE ENDVALUE CMP AL,',' JE ENDVALUE ; ; ANOTHER DIGIT - MULTIPLY BY 16 ; MOV AX,NEWVALUE MUL D16 MOV NEWVALUE,AX MOV AL,-1[SI] CALL UC SUB al,'0' JC DUFFVALUE CMP AL,10 JC HEXOK SUB AL,7 CMP AL,10 JC DUFFVALUE CMP AL,16 JNC DUFFVALUE HEXOK: MOV AH,0 ADD NEWVALUE,AX JMP HEXLOOP ENDVALUE: CLC RET DUFFVALUE: STC RET APPL_VALHEX: CALL VALHEX JMP SHORT SETAPPLV ONOFF_CONOK: ; CALL ONOFF ; ; UPDATE APPL FLAGS ON NODE PORT ; SETAPPLV: MOV DL,APPLICATION[BX] MOV CL,APPLFLAGS[BX] CMP CONOK[BX],0 JNE SETAPPL MOV DL,0 ; STOP CONNECTS SETAPPL: MOV AH,1 MOV AL,NODEPORT[BX] CALL NODE RET ONOFF: ; ; PROCESS COMMANDS WITH ON/OFF PARAM ; CMP BYTE PTR [SI],20H JBE CMDDISP LODSB CMP AL,'Y' JE CMDON CMP AL,'N' JE CMDOFF ; TO HANDLE YES/NO LODSB CMP AL,'N' JE CMDON CMP AL,'F' JE CMDOFF CMP AL,' ' JE CMDDISP ; DISPLAY CURRENT VALUE JMP TNCDUFF CMDON: MOV AL,1 JMP SHORT ONOFF00 CMDOFF: MOV AL,0 ONOFF00: MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV AH,[SI][BX] ; GET OLD VALUE MOV [SI][BX],AL ; SET FLAG MOV AL,0 JMP CMDDISP00 ; DISPLAY CMDDISP: MOV SI,CMDFLAG[DI] ; ADDR OF FLAG MOV AH,[SI][BX] ; GET OLD VALUE MOV AL,1 ; DISPLAY FLAG CMDDISP00: PUSH AX MOV SI,DI MOV CX,8 ; MAX LENGTH CALL PUTSTRINGINBUFFER MOV SI,OFFSET WAS ; DISPLAY 'was' MOV CX,5 POP AX PUSH AX ; DISPLAY ONLY? OR AL,AL JZ CMDDISP12 ; NO MOV CX,1 ; LEAVE OUT 'WAS' CMDDISP12: CALL PUTSTRINGINBUFFER POP AX MOV SI,OFFSET OFF CMP AH,0 JE WASOFF MOV SI,OFFSET ON WASOFF: MOV CX,4 CALL PUTSTRINGINBUFFER JMP SENDOK TNCCONNECT: CMP BYTE PTR [SI],20H ; ANY PARAM? JBE TNCCSTATE ; NO, SO REQUEST FOR CURRENT STATE ; ; CONNECT, BUT NOT TO SWITCH - CONNECT TO NODE, THEN PASS TO IT FOR ; PROCESSING ; OR MODEFLAG[BX],CONV ; INTO CONVERSE MODE AND MODEFLAG[BX],NOT (COMMAND+TRANS) OR VMSR[BX],88H ; SET CONNECTED CALL CONNECTTONODE CALL READCHANGE ; CLEAR PENDING STATUS CHANGE ADD MSGLEN[BX],20 ; PUT SPACES ON END JMP SENDPACKET ; LOOP BACK - WILL NOW GO TO NODE TNCCSTATE: MOV SI,OFFSET LNKSTATEMSG ; LINK STATE IS MOV CX,15 CALL SENDREPLY ; ; GET FROM NODE ; TEST VMSR[BX],80H JZ TNCST10 ; NOT CONNECTED MOV SI,OFFSET CONNECTEDMSG MOV CX,13 CALL SENDREPLY MOV DI,OFFSET NORMCALL MOV AH,8 MOV AL,NODEPORT[BX] CALL NODE ; GET CALLSIGN MOV SI,OFFSET NORMCALL MOV CX,8 CALL SENDREPLY MOV AL,0DH CALL PUTCHARINBUFFER JMP KBRET TNCST10: MOV SI,OFFSET DISCONNMSG+5 MOV CX,13 CALL SENDREPLY JMP KBRET CSWITCH: ; ; CONNECT TO NODE (SPECIAL FOR BBS FORWARDING SYSTEM) ; MOV SI,OFFSET CMDMSG MOV CX,4 CALL SENDREPLY CALL CONNECTTONODE JMP KBRET DOCONMODECHANGE: OR VMSR[BX],88H ; SET CONNECTED ; ; IF NOMODE IS ON LEAVE IN TNC COMMAND MODE, ELSE PUT INTO CONV MODE ; (MAY NEED TO IMPLEMENT CONMODE SOMETIME) ; CMP NOMODE[BX],0 JNE CSWITCH00 ; OR MODEFLAG[BX],CONV ; INTO CONVERSE MODE AND MODEFLAG[BX],NOT (COMMAND+TRANS) CSWITCH00: RET TNCDISC: MOV AH,6 MOV CX,2 ; DISCONNECT MOV AL,NODEPORT[BX] CALL NODE AND VMSR[BX],7FH ; DROP DCD OR VMSR[BX],08H ; DELTA DCD CALL SENDOK ; SEND CMD: RET SENDSTARDISC: MOV SI,OFFSET DISCONNMSG MOV CX,18 CALL SENDREPLY RET SENDOK: MOV SI,OFFSET CMDMSG MOV CX,4 CALL SENDREPLY KBRET: LEA DI,TXBUFFER[BX] MOV CURSOR[BX],DI ; RESET MESSAGE START MOV MSGLEN[BX],0 RET SENDREPLY: LODSB CALL PUTCHARINBUFFER LOOP SENDREPLY RET TNCRELEASE: ; ; DISCONNECT TNC, BUT LEAVE SESSION WITH NODE ; CALL DORELEASE CALL SENDOK RET DORELEASE: MOV AH,6 MOV CX,3 MOV AL,NODEPORT[BX] CALL NODE ; RETURN TO NODE AND VMSR[BX],7FH ; DROP DCD OR VMSR[BX],08H ; DELTA DCD RET PUTSTRINGINBUFFER: LODSB CALL PUTCHARINBUFFER LOOP PUTSTRINGINBUFFER RET SEND_CONNECTED: ; ; SEND TAPR-STYLE *** CONNECTED TO CURRENT PORT ; TEST MODEFLAG[BX],TRANS JNZ SENDCON10 ; NOT IF TRANSPARENT MOV SI,OFFSET CONMSG MOV CX,18 CALL PUTSTRINGINBUFFER MOV DI,OFFSET NORMCALL MOV AH,8 MOV AL,NODEPORT[BX] CALL NODE ; ; GET PACLEN FROM INCOMMING SESSION ; MOV AX,SAVEBX ; PACLEN CMP AL,0 JE NOPACLENX MOV TPACLEN[BX],AL NOPACLENX: MOV SI,OFFSET NORMCALL MOV CX,10 CALL PUTSTRINGINBUFFER MOV AL,0DH CALL PUTCHARINBUFFER SENDCON10: RET ; DONT BOTHER! RELEASE_TIMESLICE: ; ; CALLED WHEN WAITING FOR SOMETHING TO HAPPEN - RELEASE REST OF ; TIME SLICE ; MOV AX,1000H ; DV RELEASE TIMESLOT INT 15H STI ; XT BIOS BUG RET ; ; ; COMBIOS EMULATION CODE ; ; THE SYSTEM MAINTAINS VIRTUAL MSR AND LSR REGS FOR EACH PORT ; ; THE MSR BITS SUPPORTED ARE DCD=CONNECTED ; CTS=NOT BUSY ; ; AN ATTEMPT IS ALSO MADE TO MAINTAIN DELTA BITS ; ; BIT 7 - Receive Line Signal Detect (DCD) ; 6 - Ring Indicator ; 5 - Data Set Ready ; 4 - Clear To Send ; 3 - Delta RLSD ( ie state has changed since last ; access) ; 2 - Trailing Edge Ring Detect ; 1 - Delta DSR ; 0 - Delta CTS EVEN ; GETPACLENFROMNODE: PUSH CX PUSH DX PUSH SI PUSH DI MOV AH,8 ; PARAMS MOV AL,NODEPORT[BX] MOV DI,OFFSET NORMCALL CALL NODE ; GET CALL ; MOV CX,SAVEBX CMP CL,0 JE NOPACLEN MOV TPACLEN[BX],CL NOPACLEN: POP DI POP SI POP DX POP CX JMP NODERET GETUNACKED: PUSH CX PUSH DX PUSH SI PUSH DI MOV AH,7 ; BUFFER STATUS MOV AL,NODEPORT[BX] CALL NODE ; GET CALL ; MOV AH,CL ; UNACKED PACKETS MOV AL,CL ; FOR COMPATIBILITY POP DI POP SI POP DX POP CX JMP NODERET DATASEG DW 0 OLDINT14 DD 0 INT14: CLI ; DESQVIEW BUG PUSH DS PUSH BX PUSH CX MOV DS,CS:DATASEG MOV BX,TNCTABLE MOV CX,NUMBEROFSTREAMS INT14LP1: CMP DL,BIOSPORT[BX] JE PORTFOUND ADD BX,TYPE TNCDATA LOOP INT14LP1 POP CX POP BX POP DS JMP DWORD PTR CS:OLDINT14 NODECOMMANDS: ; ; INT 14 WITH AH = 1F ; ; NODE-SPECIFIC COMBIOS EXTENTIONS ; ; AL = 0 - RETURN VERSION AND NODE DS ; AL = 1 - RETURN ES:SI = CONNECTED CALL (IN AX25 FORM), OR SI=0 ZERO ; IF NOT CONNECTED. ALSO PORT IN AL IF L2 ; ; AL = 2 = RETURN UNACKED PACKETS ON CONNECTION (IN AH) ; ; AL = 10H RECONNECT USER TO NODE (SAME AS TNC RELEASE) ; ; ONLY DS,BX SAVED AT THIS POINT ; ; BX = TNC DATA ; CMP AL,0 JE GETVERSION CMP AL,1 JE GETCONNECTEDCALL CMP AL,2 JE GETUNACKED CMP AL,3 JE GETPACLENFROMNODE CMP AL,10H JE RELUSER JMP SHORT NODERET RELUSER: PUSH ES PUSH DS POP ES CALL DORELEASE POP ES JMP SHORT NODERET GETVERSION: MOV DH,MAJORVERSION MOV DL,MINORVERSION MOV AX,DS JMP SHORT NODERET GETCONNECTEDCALL: PUSH DS POP ES PUSH DI PUSH CX MOV AH,4 MOV AL,NODEPORT[BX] CALL NODE ; GET CALL MOV SI,0 MOV AX,0 JCXZ NOT_CONN ; NOT CONNECTED ; ; CONNECTED - GET CALLSIGN ; MOV AH,8 MOV DI,OFFSET NORMCALL MOV AL,NODEPORT[BX] CALL NODE ; GET CALL ; PUSH AX MOV SI,OFFSET NORMCALL CALL CONVTOAX25 MOV SI,OFFSET AX25CALL ; IT EXPECTS AX.25 FORMAT POP AX NOT_CONN: POP CX POP DI NODERET: POP BX POP DS ; CLEAR STACK IRET RETURNLOADEDFLAG: ; ; RETURN 'LOADED' FLAG ; POP BX POP DS ; CLEAR STACK MOV AX,0AA55H MOV BX,AX ; FOR YFB IRET PORTFOUND: ; STI CLD POP CX AND AH,7FH ; MASK TO ALLOW TOP BIT TO BE SET CMP AH,1FH JE NODECOMMANDS ; CMP AH,4 JE RETURNLOADEDFLAG ; ; BX POINTS TO TNC DATA AREA DS TO DATA, DS, BX ON STACK ; PUSH CX PUSH SI PUSH DI PUSH BP PUSH DX PUSH ES ; SAVE LAST IN CASE WE NEED TO RETURN NEW VALUE PUSH AX ; MOV ES,CS:DATASEG ; ; IF A TIMER SEND IS REQUIRED, DO IT HERE ; MOV StartedFlag,1 ; Allow timer code to run CMP AUTOSENDFLAG[BX],1 JNE INT14_00 MOV AUTOSENDFLAG[BX],0 CMP MSGLEN[BX],0 JE INT14_00 ; MESSAGE ALREADY SENT PUSH BX PUSH CX PUSH DI CALL SENDPACKET POP DI POP CX POP BX INT14_00: ; ; IF MORE THAN 6 TICKS HAVE PASSED, CALL TIMER CODE ; CALL TESTTIMER POP AX OR AH,AH JNZ NOTINIT JMP RETURNSTATUS ; INIT NOTINIT: DEC AH JNZ NOTSEND JMP SENDCHAR ; SEND NOTSEND: DEC AH JZ GETCHAR ; RECEIVE DEC AH JZ L14A3 ; STATUS DEC AH ; INSTALLED CHECK TRAPPED ABOVE DEC AH JZ L14A9 ; DROP RTS DEC AH JZ L14AC ; RAISE RTS DEC AH JZ L14AF ; SEND BREAK DEC AH JZ NDREAD DEC AH JZ MBOPTIONS ; GET/SET OPTIONS DEC AH JNZ NOTWRITEBUFFER JMP WRITEBUFFER NOTWRITEBUFFER: DEC AH JZ READBUFFER_JMP JMP INT14EXIT READBUFFER_JMP: JMP READBUFFER GETCHAR: JMP GETCHARSUPPORT NDREAD: ; ; NON - DESTRUCTIVE READ ; CMP RXCOUNT[BX],0 JNE GOTSOMEDATEND CALL GETDATA GOTSOMEDATEND: MOV SI,GETPTR[BX] MOV AL,[SI] MOV AH,VLSR[BX] AND AH,0FEH ; MASK DAV BIT CMP RXCOUNT[BX],0 JZ NDNODATA OR AH,1 ; SET DAV IF BUFFER NOT EMPTY NDNODATA: JMP INT14EXIT MBOPTIONS: MOV AH,MBOPTIONBYTE MOV MBOPTIONBYTE,AL MOV AL,AH JMP INT14EXIT L14A3: ; ; GET STUFF FROM NODE IF BUFFER EMPTY ; CMP RXCOUNT[BX],0 JNE GOTSOMEDATE CALL GETDATA GOTSOMEDATE: JMP RETURNSTATUS JMP RETURNSTATUS L14A9: JMP DROPRTS L14AC: JMP RAISERTS L14AF: JMP SENDBREAK INT14EXIT: POP ES POP DX POP BP POP DI POP SI POP CX POP BX POP DS IRET ; SENDCHAR: CALL SENDCHARSUPPORT JMP SHORT RETURNSTATUS SENDCHARSUPPORT: ; ; CALLED FROM SEND CHAR OR SEND BLOCK ; CALL KEYSUPPORT ; CHAR KEYED - BX IS SESSION RET WAITFORCHAR: CALL RELEASE_TIMESLICE CALL DONODEPOLL ; SEE IF ANY MORE CALL TESTTIMER GETCHARSUPPORT: CMP RXCOUNT[BX],0 JE WAITFORCHAR ; WAIT FOR CHAR CALL GETONECHAR GETAH: MOV AH,VLSR[BX] AND AH,0FEH ; MASK DAV BIT CMP RXCOUNT[BX],0 JZ L1579 OR AH,1 ; SET DAV IF BUFFER NOT EMPTY L1579: JMP INT14EXIT GETONECHAR: MOV SI,GETPTR[BX] LODSB ; GET CHAR DEC RXCOUNT[BX] MOV DX,TNCBUFFLEN ADD DX,BX CMP SI,DX ; BUFFER WRAP? JB L153C ; NO MOV SI,BX ; RESET TO START L153C: CMP RXCOUNT[BX],128 ; GETTING LOW? JNB L1560 ; NO TEST RTSFLAG[BX],1 ; RTS UP? JZ L1560 ; YES ; ; RTS HAD BEEN DROPPED TO STOP OTHER END SENDING - RAISE IT AGAIN ; AND RTSFLAG[BX],0FEH L1560: MOV GETPTR[BX],SI RET RETURNSTATUS: ; ; GET STATUS - AH = LSR, AL = MODEM STATUS ; ; IF CTS IS LOW (MEANING CROSS SESSION IS BUSY) ; CHECK IF STILL BUSY ; TEST VMSR[BX],10H JNZ CTSOK CALL CHECKCTS CTSOK: CALL GETSTATUS JMP INT14EXIT GETSTATUS: ; ; GET STATUS - AH = LSR, AL = MODEM STATUS ; MOV AL,VLSR[BX] AND AL,0FEH CMP RXCOUNT[BX],0 JZ L1599 ; ; IF FLOW ON, AND CHARS IN KB BUFFER, DONT REPORT DATA AVAIL ; TEST FLOWFLAG[BX],1 JZ DATAAVAIL ; FLOW OFF CMP MSGLEN[BX],0 JNE L1599 ; SOMETHING KEYED DATAAVAIL: OR AL,1 ; SET DATA AVAIL L1599: MOV AH,AL MOV AL,VMSR[BX] AND VMSR[BX],0F0H ; CLEAR DELTA BITS RET DROPRTS: ; ; DROP DTR/RTS ; OR RTSFLAG[BX],1 JMP INT14EXIT RAISERTS: ; ; RAISE DTR/RTS ; AND RTSFLAG[BX],0FEH JMP INT14EXIT SENDBREAK: ; ; SET COMMAND MODE FLAG TO TNC CODE ; CALL SETCOMMANDMODE JMP INT14EXIT PUTCHARINBUFFER: ; ; CALLED BY L4 CODE TO PASS DATA TO VIRTUAL TNC ; CMP RXCOUNT[BX],TNCBUFFLEN JB STILLOK ; ; OVERRUN - LOSE IT ; OR VLSR[BX],2 ; SET OVERRUN ERROR RET STILLOK: PUSH DI AND VLSR[BX],NOT 2 ; CLEAR OVERRRUN CLI MOV DI,PUTPTR[BX] MOV [DI],AL INC DI INC WORD PTR RXCOUNT[BX] MOV AX,TNCBUFFLEN ; BUFFER LENGTH ADD AX,BX ; END ADDR CMP DI,AX ; END OF BUFFER ADDR JB L1648 ; OK ; ; BUFFER WRAPAROUND ; MOV DI,BX ; POINT BACK TO START L1648: MOV PUTPTR[BX],DI STI CMP RXCOUNT[BX],TNCBUFFLEN-300 ; ALLOW FOR FULL PACKET JB L1667 ; ; BUFFER GETTING FULL - DROP RTS/DTR ; OR RTSFLAG[BX],1 ; SET BUSY L1667: POP DI RET CHECKCTS: ; ; SEE IF CROSS-SESION STILL BUSY ; MOV AH,7 MOV AL,NODEPORT[BX] CALL NODE ; ; CX = FRAMES QUEUED ; CMP CX,4 ; SHOULD BE WINDOW?? JB CLEARCTS TEST VMSR[BX],00010000B ; ALREADY OFF? JZ CTSNOCHANGE AND VMSR[BX],11101111B ; DROP CTS? OR VMSR[BX],00000001B ; DELTA BIT CTSNOCHANGE: RET CLEARCTS: OR VMSR[BX],11H ; CTS AND DELTA CTS RET READBUFFER: MOV DX,0 ; CHARS RETURNED POP ES ; USERS SEG MOV AH,0DH ; END CHAR GETBLOOP: CMP RXCOUNT[BX],0 JE GETBEND ; NOTHING DOING PUSH DX CALL GETONECHAR POP DX STOSB INC DX ; CHARS RETURNED CMP AL,AH ; TERMINATOR JE GETBRET SKIPXX: MOV LASTCH,AL ; PREVIOUS LOOP GETBLOOP ; SEE IF MORE ; ; COUNT EXCEEDED ; GETBRET: GETBEND: MOV CX,DX ; CHARS RETURNED CALL GETSTATUS ; POP DX POP BP ADD SP,2 ; LEAVE DI POP SI ADD SP,2 ; LEAVE CX ; POP BX POP DS IRET ; WRITEBUFFER: POP ES PUSH ES WBLOOP: MOV AL,ES:[DI] INC DI PUSH ES PUSH DI PUSH CX MOV ES,CS:DATASEG CALL SENDCHARSUPPORT POP CX POP DI POP ES LOOP WBLOOP MOV DX,0 ; CHARS NOT SENT POP ES JMP GETBEND CONNECTTONODE: MOV AL,NODEPORT[BX] MOV AH,6 ; CONNECT/DISCONNECT MOV CX,0 ; CONNECT USING APPL IN DL MOV DL,APPLICATION[BX] CALL NODE RET GETDATA: ; ; LOOK FOR STATUS CHANGE ; MOV AH,4 MOV AL,NODEPORT[BX] CALL NODE ; CMP DX,0 JE NOSTATECHANGE ; ; PORT HAS CONNECTED OR DISCONNECTED - SEND STATUS CHANGE TO PC ; PUSH CX ; SAVE MOV AH,5 MOV AL,NODEPORT[BX] CALL NODE ; ACK THE STATUS CHANGE POP CX CMP CX,0 JNE SENDHOSTCON ; ; DISCONNECTED ; FORCEOFF: OR MODEFLAG[BX],COMMAND AND MODEFLAG[BX],NOT (CONV+TRANS) AND VMSR[BX],7FH ; DROP DCD OR VMSR[BX],08H ; DELTA DCD CALL SENDSTARDISC JMP SHORT STATUSPOLLEND SENDHOSTCON: ; ; GET CALLSIGN ; CALL SEND_CONNECTED CALL DOCONMODECHANGE ; SET CONNECTED AND CHANGE MODE IF NEEDED JMP SHORT STATUSPOLLEND NOSTATECHANGE: ; ; VERIFY CURRENT STATE ; CMP CX,0 JNE SHOULDBECONN ; ; SWITCH THINKS WE ARE DISCONNECTED ; TEST VMSR[BX],80H JZ STATUSPOLLEND ; SO DOES TNC ; JMP FORCEOFF ; DISCONNECT TNC SHOULDBECONN: ; ; SWITCH THINKS WE ARE CONNECTED ; TEST VMSR[BX],80H JNZ STATUSPOLLEND ; SO DOES TNC ; JMP SENDHOSTCON ; CONNECT TNC STATUSPOLLEND: DONODEPOLL: ; ; SEE IF ANYTHING QUEUED ; MOV AL,NODEPORT[BX] MOV AH,3 MOV DI,OFFSET MONITORDATA CALL NODE CMP CX,0 JE DATAPOLLRET MOV SI,OFFSET MONITORDATA GETD00: ; LODSB CALL PUTCHARINBUFFER LOOP GETD00 DATAPOLLRET: RET NODE: PUSH BX INTVAL: INT 7FH MOV SAVEBX,BX ; FOR FUNCTION 8 POP BX RET CONSOLESEND: MOV SI,DI SENDCONS00: LODSB CALL PUTCHARINBUFFER LOOP SENDCONS00 SENDCONSEND: RET IF 0 HEXOUT: PUSH AX PUSH AX sar al,1 sar al,1 sar al,1 sar al,1 call hexout1 pop ax call hexout1 mov al,20h call printit POP AX ret hexout1: and al,0fh cmp al,10 jl hexout5 add al,7 hexout5: add al,30h call printit ; ret ; printit: PUSH AX PUSH BX mov AH,14 int 10h POP BX POP AX ret ; ENDIF NORMSTR: lodsb OR AL,AL ; End of String ? je NORMSTR_RET ; Yes call PUTCHARINBUFFER jmp SHORT NORMSTR NORMSTR_RET: ret TENK DD 10000 DD 1000 DD 100 DWORD10 DD 10 ; ; Convert byte in AL to nnn, nn or n format ; CONV_DIGITS: ; CONVERT AL TO N\MAX 3 DIGITS MOV AH,0 CONV_5DIGITS: ; CONVERT AX TO 5 DIGITS 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 CONVTOAX25: ; ; CONVERT CALLSIGN IN [SI] TO AX25 FORMAT IN AX25CALL ; RETURN NZ IF CALLSIGN INVALID ; MOV DI,OFFSET AX25CALL MOV CX,6 ; MAX ALPHANUMERICS MOV AL,40H REP STOSB ; CLEAR IN CASE SHORT CALL MOV AL,01100000B ; DEFAULT SSID STOSB MOV DI,OFFSET AX25CALL MOV CL,7 CONVAX00: LODSB CMP AL,'-' JE CONVAX20 ; SSID FOLLOWS CMP AL,' ' JE CONVAX40 ; END OF NAME ; CMP AL,'#' JNE NOTHASH CMP CL,7 JE CONVAX10 ; OK AS FIRST CHAR NOTHASH: CMP AL,'/' ; ALLOW / AND DIGITS (FOR W0RLI!) JB CONVAX49 ; INVALID CMP AL,'9' JBE CONVAX10 ; OK CMP AL,'A' JB CONVAX49 ; INVALID CMP AL,'Z' JBE CONVAX10 ; OK CMP AL,'a' JB CONVAX10 ; OK CMP AL,'z' JA CONVAX49 ; INVALID AND AL,NOT 20H ; CONVERT TO UPPER CASE CONVAX10: SAL AL,1 ; SHIFT UP STOSB LOOP CONVAX00 ; ; HAVE PROCESSED 7 CHARS - NAME IS INVALID ; JMP SHORT CONVAX49 CONVAX20: LODSB ; FIRST CHAR IF SSID CMP AL,'0' JB CONVAX49 ; INVALID CMP AL,'9' JA CONVAX49 ; OK ; MOV AH,AL ; SAVE LODSB CMP AL,' ' JE CONVAX30 ; END OF SSID INC SI ; OTHER CODE EXPECTS SI TO POINT TO NEXT FIELD CMP AL,'0' JB CONVAX49 ; INVALID CMP AL,'5' ; LIMIT 10 - 15 JA CONVAX49 ; OK ; SUB AL,30H CMP AH,'1' JNE CONVAX49 ; IF 2 DIGITS, FIRST MUST BE 1 ADD AL,10 MOV AH,AL CONVAX30: SAL AH,1 ; UP 1 BIT OR AH,01100000B ; DEFAULT RR BITS MOV AX25CALL+6,AH CONVAX40: ; ; NO SSID SUPPLIED ; XOR AL,AL ; SET ZERO RET CONVAX49: OR AL,1 ; SET NZ RET CONVFROMAX25: ; ; CONVERT AX25 FORMAT CALL IN [SI] TO NORMAL FORMAT IN NORMCALL ; RETURNS LENGTH IN CX AND NZ IF LAST ADDRESS BIT IS SET ; PUSH SI ; SAVE MOV DI,OFFSET NORMCALL MOV CX,10 ; MAX ALPHANUMERICS MOV AL,20H REP STOSB ; CLEAR IN CASE SHORT CALL MOV DI,OFFSET NORMCALL MOV CL,6 CONVAX50: LODSB CMP AL,40H JE CONVAX60 ; END IF CALL - DO SSID SHR AL,1 STOSB LOOP CONVAX50 CONVAX60: POP SI ADD SI,6 ; TO SSID LODSB MOV AH,AL ; SAVE FOR LAST BIT TEST SHR AL,1 AND AL,0FH JZ CONVAX90 ; NO SSID - FINISHED ; MOV BYTE PTR [DI],'-' INC DI CMP AL,10 JB CONVAX70 SUB AL,10 MOV BYTE PTR [DI],'1' INC DI CONVAX70: ADD AL,30H ; CONVERT TO DIGIT STOSB CONVAX90: MOV CX,DI SUB CX,OFFSET NORMCALL MOV NORMLEN,CX ; SIGNIFICANT LENGTH TEST AH,1 ; LAST BIT SET? RET STAYSWITCH DB 0 SPYSWITCH DB 0 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: 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 ; ; MONITORING STUFF ; NULL EQU 00H CR EQU 0DH LF EQU 0AH NETROM_PID EQU 0CFH NODES_SIG EQU 0FFH ; PORT_MSG DB ' Port=',NULL NODES_MSG DB ' NODES broadcast from ',NULL NETROM_MSG DB ' NET/ROM',CR,' ',NULL TO_MSG DB ' to ',NULL TTL_MSG DB ' ttl=',NULL AT_MSG DB ' at ',NULL VIA_MSG DB ' via ',NULL QUALITY_MSG DB ' qlty=',NULL MYCCT_MSG DB ' my' CCT_MSG DB ' cct=',0 TIM_MSG DB ' t/o=',0 WINDOW DB ' w=',0 CONN_REQ_MSG DB ' ',NULL CONN_ACK_MSG DB ' ',NULL CONN_NAK_MSG DB ' - BUSY',NULL DISC_REQ_MSG DB ' ',NULL DISC_ACK_MSG DB ' ',NULL INFO_MSG DB ' ',NULL IP_MSG DB ' ',NULL UA_MSG DB 'UA',NULL DM_MSG DB 'DM',NULL RR_MSG DB 'RR',NULL RNR_MSG DB 'RNR',NULL UI_MSG DB 'UI',NULL FRMR_MSG DB 'FRMR',NULL REJ_MSG DB 'REJ',NULL ; ; HDLC COMMANDS (WITHOUT P/F) ; UI EQU 3 SABM EQU 2FH DISC EQU 43H DM EQU 0FH UA EQU 63H FRMR EQU 87H RR EQU 1 RNR EQU 5 REJ EQU 9 ; PFBIT EQU 10H ; POLL/FINAL BIT IN CONTROL BYTE ; ; L4FLAGS DEFINITION ; L4BUSY EQU 80H ; BNA - DONT SEND ANY MORE L4NAK EQU 40H ; NEGATIVE RESPONSE FLAG L4MORE EQU 20H ; MORE DATA FOLLOWS - FRAGMENTATION FLAG L4CREQ EQU 1 ; CONNECT REQUEST L4CACK EQU 2 ; CONNECT ACK L4DREQ EQU 3 ; DISCONNECT REQUEST L4DACK EQU 4 ; DISCONNECT ACK L4INFO EQU 5 ; INFORMATION L4IACK EQU 6 ; INFORMATION ACK ; ;-----------------------------------------------------------------------------; ; Parameter area for received frame ; ;-----------------------------------------------------------------------------; PORT_NO DB 0 ; Received port number 0 - 256 VERSION_NO DB 0 ; Version 1 or 2 1,2 POLL_FINAL DB 0 ; Poll or Final ? P,F COMM_RESP DB 0 ; Command or Response C,R FRAME_TYPE DB 0 ; Frame Type UI etc in Hex PID DB 0 ; Protocol ID FRAME_LENGTH DW 0 ; Length of frame 0 - 65... NR DB 0 ; N(R) Flag NS DB 0 ; N(S) Flag INFO_FLAG DB 0 ; Information Packet ? 0 No, 1 Yes OPCODE DB 0 ; L4 FRAME TYPE FRMRFLAG DB 0 DISPLAYFRAME: TEST MSGPORT[DI],80H JZ RXMON ; ; TX FRAME ; CMP MTX[BX],0 JNE DISPLAYFRAMETX RET DISPLAYFRAMETX: CMP MTXFORCE[BX],0 JNE TRACEANYWAY RXMON: cmp TRACEFLAG[BX],0 jne TRACEOK TRACERET: ret TRACEOK: ; ; CHECK FOR PORT SELECTIVE MONITORING ; MOV CL,MSGPORT[DI] AND CL,7FH ; DROP TX BIT DEC CL MOV AX,1 SHL AX,CL ; SHIFT BIT UP TEST MMASK[BX],AX JZ TRACERET ;-----------------------------------------------------------------------------; ; See if connected and MCON set ; ;-----------------------------------------------------------------------------; cmp MCON[BX],0 jne TRACEANYWAY test VMSR[BX],80H jz TRACEANYWAY ; NOT CONNECTED ret TRACEANYWAY: ; ; GET THE CONTROL BYTE, TO SEE IF THIS FRAME IS TO BE DISPLAYED ; PUSH DI MOV CX,8 ; MAX DIGIS CTRLLOOP: TEST BYTE PTR MSGCONTROL-1[DI],1 JNZ CTRLFOUND ADD DI,7 LOOP CTRLLOOP ; ; INVALID FRAME ; POP DI RET CTRLFOUND: MOV AL,MSGCONTROL[DI] POP DI ; TEST AL,1 ; I FRAME JZ IFRAME AND AL,NOT PFBIT ; CLEAR P/F CMP AL,3 ; UI JE OKTOTRACE ; ALWAYS DO UI CMP AL,FRMR JE OKTOTRACE ; ALWAYS DO FRMR ; ; USEQ/CONTROL - TRACE IF MCOM ON ; CMP MCOM[BX],0 JNE OKTOTRACE RET ;-----------------------------------------------------------------------------; ; Check for MALL ; ;-----------------------------------------------------------------------------; IFRAME: cmp MALL[BX],0 jne OKTOTRACE ret OKTOTRACE: ; ;-----------------------------------------------------------------------------; ; Get the port number of the received frame ; ;-----------------------------------------------------------------------------; mov AL,MSGPORT[DI] mov PORT_NO,AL MOV FRMRFLAG,0 push DI mov AH,MSGDEST+6[DI] mov AL,MSGORIGIN+6[DI] mov COMM_RESP,0 ; Clear Command/Response Flag ;-----------------------------------------------------------------------------; ; Is it a Poll/Final or Command/Response ; ;-----------------------------------------------------------------------------; test AH,80H mov COMM_RESP,'C' jnz NOT_RESPONSE mov COMM_RESP,'R' NOT_RESPONSE: ;-----------------------------------------------------------------------------; ; Is this version 1 or 2 of AX25 ? ; ;-----------------------------------------------------------------------------; xor AH,AL test AH,80H mov VERSION_NO,1 je VERSION_1 mov VERSION_NO,2 VERSION_1: ;-----------------------------------------------------------------------------; ; Display Origin Callsign ; ;-----------------------------------------------------------------------------; lea SI,MSGORIGIN[DI] call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR pop DI push DI mov AL,'>' call PUTCHARINBUFFER ;-----------------------------------------------------------------------------; ; Display Destination Callsign ; ;-----------------------------------------------------------------------------; lea SI,MSGDEST[DI] call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR pop DI push DI mov AX,MSGLENGTH[DI] mov FRAME_LENGTH,AX mov CX,8 ; Max number of digi-peaters ;-----------------------------------------------------------------------------; ; Display any Digi-Peaters ; ;-----------------------------------------------------------------------------; NEXT_DIGI: test MSGORIGIN+6[DI],1 jnz NO_MORE_DIGIS add DI,7 sub FRAME_LENGTH,7 ; Reduce length push DI push CX lea SI,MSGORIGIN[DI] call CONVFROMAX25 ; Convert to call push AX ; Last byte is in AH mov AL,',' call PUTCHARINBUFFER mov SI,OFFSET NORMCALL call DISPADDR pop AX test AH,80H jz NOT_REPEATED mov AL,'*' call PUTCHARINBUFFER NOT_REPEATED: pop CX pop DI loop NEXT_DIGI NO_MORE_DIGIS: ;----------------------------------------------------------------------------; ; Display the Port No of the frame ; ;----------------------------------------------------------------------------; mov SI,OFFSET PORT_MSG call NORMSTR mov AL,PORT_NO AND AL,7FH ; MASK TX BIT add AL,30H call PUTCHARINBUFFER ; ; IF BBS MONITOR MODE, STOP HERE - IT HAS ENOUGH FOR THE J LIST ; CMP BBSMON[BX],0 JE NORMAL_MON mov AL,CR call PUTCHARINBUFFER POP DI RET NORMAL_MON: mov AL,' ' call PUTCHARINBUFFER ;-----------------------------------------------------------------------------; ; If this is Version 2 get the Poll/Final Bit ; ;-----------------------------------------------------------------------------; mov POLL_FINAL,0 ; Clear Poll/Final Flag mov AL,MSGCONTROL[DI] ; Get control byte cmp COMM_RESP,'C' jne NOT_COMM test AL,PFBIT je NOT_POLL mov POLL_FINAL,'P' NOT_POLL: NOT_COMM: cmp COMM_RESP,'R' jne NOT_RESP test AL,PFBIT je NOT_FINAL mov POLL_FINAL,'F' NOT_FINAL: NOT_RESP: ;-----------------------------------------------------------------------------; ; Start displaying the frame information ; ;-----------------------------------------------------------------------------; and AL,NOT PFBIT ; Remove P/F bit mov FRAME_TYPE,AL mov AL,'<' ; Print "<" call PUTCHARINBUFFER mov NR,0 ; Reset all the flags mov NS,0 mov INFO_FLAG,0 mov AL,FRAME_TYPE test AL,1 jne NOT_I_FRAME ;-----------------------------------------------------------------------------; ; Information frame ; ;-----------------------------------------------------------------------------; mov AL,'I' call PUTCHARINBUFFER mov INFO_FLAG,1 mov NR,1 mov NS,1 jmp END_OF_TYPE NOT_I_FRAME: ;-----------------------------------------------------------------------------; ; Un-numbered Information Frame ; ;-----------------------------------------------------------------------------; cmp AL,UI jne NOT_UI_FRAME mov SI,OFFSET UI_MSG call NORMSTR mov INFO_FLAG,1 jmp SHORT END_OF_TYPE NOT_UI_FRAME: test AL,10B jne NOT_R_FRAME ;-----------------------------------------------------------------------------; ; Process supervisory frames ; ;-----------------------------------------------------------------------------; mov NR,1 ; All supervisory frames have N(R) and AL,0FH ; Mask the interesting bits cmp AL,RR jne NOT_RR_FRAME mov SI,OFFSET RR_MSG call NORMSTR jmp SHORT END_OF_TYPE NOT_RR_FRAME: cmp AL,RNR jne NOT_RNR_FRAME mov SI,OFFSET RNR_MSG call NORMSTR jmp SHORT END_OF_TYPE NOT_RNR_FRAME: cmp AL,REJ jne NOT_REJ_FRAME mov SI,OFFSET REJ_MSG call NORMSTR jmp SHORT END_OF_TYPE NOT_REJ_FRAME: mov NR,0 ; Don't display sequence number mov AL,'?' ; Print "?" call PUTCHARINBUFFER jmp SHORT END_OF_TYPE ;-----------------------------------------------------------------------------; ; Process all other frame types ; ;-----------------------------------------------------------------------------; NOT_R_FRAME: cmp AL,UA jne NOT_UA_FRAME mov SI,OFFSET UA_MSG call NORMSTR jmp SHORT END_OF_TYPE NOT_UA_FRAME: cmp AL,DM jne NOT_DM_FRAME mov SI,OFFSET DM_MSG call NORMSTR jmp SHORT END_OF_TYPE NOT_DM_FRAME: cmp AL,SABM jne NOT_SABM_FRAME mov AL,'C' call PUTCHARINBUFFER jmp SHORT END_OF_TYPE NOT_SABM_FRAME: cmp AL,DISC jne NOT_DISC_FRAME mov AL,'D' call PUTCHARINBUFFER jmp SHORT END_OF_TYPE NOT_DISC_FRAME: cmp AL,FRMR jne NOT_FRMR_FRAME mov SI,OFFSET FRMR_MSG call NORMSTR MOV FRMRFLAG,1 jmp SHORT END_OF_TYPE NOT_FRMR_FRAME: mov AL,'?' call PUTCHARINBUFFER END_OF_TYPE: ;----------------------------------------------------------------------------; ; If Version 2 Then display P/F C/R Information ; ;----------------------------------------------------------------------------; cmp VERSION_NO,2 jne NOT_VERSION_2 mov AL,' ' call PUTCHARINBUFFER mov AL,COMM_RESP ; Print Command/Response Flag call PUTCHARINBUFFER cmp POLL_FINAL,0 je NO_POLL_FINAL mov AL,' ' call PUTCHARINBUFFER mov AL,POLL_FINAL ; Print Poll/Final Flag if Set call PUTCHARINBUFFER NO_POLL_FINAL: NOT_VERSION_2: ;----------------------------------------------------------------------------; ; Display sequence numbers if applicable ; ;----------------------------------------------------------------------------; cmp NS,1 jne NOT_NS_DATA mov AL,' ' call PUTCHARINBUFFER mov AL,'S' call PUTCHARINBUFFER mov AL,FRAME_TYPE ror AL,1 call DISPLAYSEQ NOT_NS_DATA: cmp NR,1 jne NOT_NR_DATA mov AL,' ' call PUTCHARINBUFFER mov AL,'R' call PUTCHARINBUFFER mov AL,FRAME_TYPE rol AL,1 rol AL,1 rol AL,1 call DISPLAYSEQ NOT_NR_DATA: mov AL,'>' call PUTCHARINBUFFER CMP FRMRFLAG,0 JE NOTFRMR ; ; DISPLAY FRMR BYTES ; lea SI,MSGPID[DI] MOV CX,3 ; TESTING FRMRLOOP: lodsb CALL BYTE_TO_HEX LOOP FRMRLOOP JMP NO_INFO NOTFRMR: ;----------------------------------------------------------------------------; ; Find the PID if an information frame ; ;----------------------------------------------------------------------------; mov AL,0 cmp INFO_FLAG,1 jne NO_PID lea SI,MSGPID[DI] lodsb NO_PID: mov PID,AL ;----------------------------------------------------------------------------; ; Is this a NET/ROM message of any sort ? ; ;----------------------------------------------------------------------------; MOV CX,FRAME_LENGTH cmp PID,NETROM_PID je DISPLAY_NETROM ;----------------------------------------------------------------------------; ; Display the rest of the frame (If Any) ; ;----------------------------------------------------------------------------; DISPLAY_INFO: cmp INFO_FLAG,1 ; Is it an information packet ? jne NO_INFO mov AL,':' call PUTCHARINBUFFER XOR AL,AL ; IN CASE EMPTY sub CX,21 JCXZ NO_INFO ; EMPTY I FRAME TEST HEADERLN[BX],1 JZ SAMELN ; ; PUT TEXT ON A NEW LINE ; MOV AL,0DH CALL PUTCHARINBUFFER SAMELN: cmp CX,257 jb LENGTH_OK mov CX,256 LENGTH_OK: push CX lodsb cmp AL,0AH JE MONOK CMP AL,0DH JE MONOK CMP AL,20H JB SKIP_MON ; IGNORE OTHER CONTROLS MONOK: PUSH AX call PUTCHARINBUFFER POP AX SKIP_MON: pop CX loop LENGTH_OK NO_INFO: ; ; ADD CR UNLESS DATA ALREADY HAS ONE ; CMP AL,CR JE NOTANOTHER ADD_CR: mov AL,CR call PUTCHARINBUFFER NOTANOTHER: ; pop DI ret ;----------------------------------------------------------------------------; ; Display NET/ROM data ; ;----------------------------------------------------------------------------; DISPLAY_NETROM: lodsb cmp AL,NODES_SIG ; Check NODES message je DISPLAY_NODES jmp DISPLAY_NETROM_DATA DISPLAY_NODES: ;----------------------------------------------------------------------------; ; Display NODES broadcast ; ;----------------------------------------------------------------------------; push CX push SI mov SI,OFFSET NODES_MSG call NORMSTR pop SI push SI mov CX,6 call DISPADDR mov AL,CR call PUTCHARINBUFFER pop SI pop CX add SI,6 ; Point to first destination sub CX,28 ; Header, mnemonic and signature length NODES_LOOP: cmp CX,0 jbe NO_INFO push CX push SI ; Global push for each node push SI ; Local push mov AL,' ' call PUTCHARINBUFFER mov AL,' ' call PUTCHARINBUFFER pop SI push SI add SI,7 ; Display destination mnemonic cmp BYTE PTR [SI],' ' je NO_MNEMONIC mov CX,6 ; Max length MNEMONIC_LOOP: lodsb ; Get character cmp AL,' ' ; Short mnemonic ? je END_MNEMONIC call PUTCHARINBUFFER loop MNEMONIC_LOOP END_MNEMONIC: mov AL,':' call PUTCHARINBUFFER NO_MNEMONIC: pop SI push SI call CONVFROMAX25 ; Display dest callsign mov SI,OFFSET NORMCALL call DISPADDR mov SI,OFFSET VIA_MSG call NORMSTR pop SI add SI,13 ; Point to neighbour callsign push SI call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR mov SI,OFFSET QUALITY_MSG call NORMSTR pop SI add SI,7 ; Point to quality byte mov AL,[SI] call DISPLAY_BYTE_1 mov AL,CR call PUTCHARINBUFFER pop SI pop CX add SI,21 ; Point to next destination sub CX,21 ; Remove length of each jmp SHORT NODES_LOOP ;----------------------------------------------------------------------------; ; Display normal NET/ROM transmissions ; ;----------------------------------------------------------------------------; DISPLAY_NETROM_DATA: DEC SI ; BACK TO DATA PUSH SI mov SI,OFFSET NETROM_MSG call NORMSTR pop SI PUSH SI call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR mov SI,OFFSET TO_MSG call NORMSTR pop SI add SI,7 push SI call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR ; ; Display Time To Live number ; mov SI,OFFSET TTL_MSG call NORMSTR pop SI add SI,7 ; Point to TTL counter lodsb call DISPLAY_BYTE_1 ; ; DISPLAY CIRCUIT ID ; PUSH SI MOV SI,OFFSET CCT_MSG CALL NORMSTR POP SI LODSB CALL BYTE_TO_HEX LODSB CALL BYTE_TO_HEX INC SI INC SI ; TO OPCODE ;-----------------------------------------------------------------------------; ; Determine type of Level 4 frame ; ;-----------------------------------------------------------------------------; mov AL,[SI] MOV OPCODE,AL ; SAVE AND AL,0FH ; Strip off flags cmp AL,L4CREQ jne NOT_L4CREQ PUSH SI mov SI,OFFSET CONN_REQ_MSG call NORMSTR MOV SI,OFFSET WINDOW CALL NORMSTR POP SI INC SI LODSB ; WINDOW SIZE CALL DISPLAY_BYTE_1 mov AL,' ' call PUTCHARINBUFFER PUSH SI call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR mov SI,OFFSET AT_MSG call NORMSTR pop SI add SI,7 PUSH SI call CONVFROMAX25 mov SI,OFFSET NORMCALL call DISPADDR POP SI CMP FRAME_LENGTH,56 JE NOT_BPQ ; ; BPQ EXTENDED CON REQ - DISPLAY TIMEOUT ; PUSH SI MOV SI,OFFSET TIM_MSG CALL NORMSTR POP SI MOV AX,7[SI] ; TIMEOUT CALL DISPLAY_BYTE_1 ; NOT_BPQ: JMP ADD_CR NOT_L4CREQ: cmp AL,L4CACK jne NOT_L4CACK TEST OPCODE,L4BUSY JZ L4CRQ00 ; ; BUSY RETURNED ; MOV SI,OFFSET CONN_NAK_MSG CALL NORMSTR JMP END_NETROM L4CRQ00: PUSH SI MOV SI,OFFSET CONN_ACK_MSG CALL NORMSTR MOV SI,OFFSET WINDOW CALL NORMSTR POP SI MOV AL,1[SI] ; WINDOW SIZE CALL DISPLAY_BYTE_1 PUSH SI MOV SI,OFFSET MYCCT_MSG CALL NORMSTR POP SI MOV AL,-2[SI] CALL BYTE_TO_HEX MOV AL,-1[SI] CALL BYTE_TO_HEX JMP ADD_CR NOT_L4CACK: cmp AL,L4DREQ jne NOT_L4DREQ mov SI,OFFSET DISC_REQ_MSG call NORMSTR JMP ADD_CR NOT_L4DREQ: cmp AL,L4DACK jne NOT_L4DACK mov SI,OFFSET DISC_ACK_MSG call NORMSTR jmp add_cr NOT_L4DACK: cmp AL,L4INFO jne NOT_L4INFO push SI mov SI,OFFSET INFO_MSG call NORMSTR pop SI mov AL,-2[SI] ; Get send sequence number call DISPLAY_BYTE_1 mov AL,' ' call PUTCHARINBUFFER mov AL,'R' call PUTCHARINBUFFER mov AL,-1[SI] ; Get receive sequence number call DISPLAY_BYTE_1 mov AL,'>' call PUTCHARINBUFFER INC SI ; TO DATA MOV CX,FRAME_LENGTH sub CX,20 CALL DOL4FLAGS jmp DISPLAY_INFO NOT_L4INFO: cmp AL,L4IACK jne NOT_L4IACK push SI mov SI,OFFSET INFO_ACK_MSG call NORMSTR pop SI mov AL,-1[SI] ; Get receive sequence number call DISPLAY_BYTE_1 mov AL,'>' call PUTCHARINBUFFER CALL DOL4FLAGS JMP SHORT END_NETROM NOT_L4IACK: OR AL,AL JNZ NOTIP ; ; TCP/IP DATAGRAM ; mov SI,OFFSET IP_MSG call NORMSTR ; ; MAY DECODE IT LATER ; JMP ADD_CR NOTIP: mov SI,OFFSET DUFF_NET_MSG call NORMSTR END_NETROM: jmp add_cr DOL4FLAGS: ; ; DISPLAY BUSY/NAK/MORE FLAGS ; TEST OPCODE,L4BUSY JZ L4F010 MOV AL,'B' CALL PUTCHARINBUFFER L4F010: TEST OPCODE,L4NAK JZ L4F020 MOV AL,'N' CALL PUTCHARINBUFFER L4F020: TEST OPCODE,L4MORE JZ L4F030 MOV AL,'M' CALL PUTCHARINBUFFER L4F030: RET ;-----------------------------------------------------------------------------; ; Display sequence numbers ; ;-----------------------------------------------------------------------------; DISPLAYSEQ: and AL,7 add AL,30H call PUTCHARINBUFFER ret ;-----------------------------------------------------------------------------; ; Display Callsign pointed to by SI ; ;-----------------------------------------------------------------------------; DISPADDR: jcxz DISPADDR_RET lodsb call PUTCHARINBUFFER loop DISPADDR DISPADDR_RET: ret ;-----------------------------------------------------------------------------; ; Convert byte in AL to nnn, nn or n format ; ;-----------------------------------------------------------------------------; DISPLAY_BYTE_1: cmp AL,100 jb TENS_1 mov AH,0 HUNDREDS_LOOP_1: cmp AL,100 jb HUNDREDS_LOOP_END_1 sub AL,100 inc AH jmp SHORT HUNDREDS_LOOP_1 HUNDREDS_LOOP_END_1: push AX mov AL,AH add AL,30H call PUTCHARINBUFFER pop AX jmp SHORT TENS_PRINT_1 TENS_1: cmp AL,10 jb UNITS_1 TENS_PRINT_1: mov AH,0 TENS_LOOP_1: cmp AL,10 jb TENS_LOOP_END_1 sub AL,10 inc AH jmp SHORT TENS_LOOP_1 TENS_LOOP_END_1: push AX mov AL,AH add AL,30H call PUTCHARINBUFFER pop AX UNITS_1: add AL,30H call PUTCHARINBUFFER ret ;-----------------------------------------------------------------------------; ; Convert byte in AL to nn format ; ;-----------------------------------------------------------------------------; DISPLAY_BYTE_2: cmp AL,100 jb TENS_2 sub AL,100 jmp SHORT DISPLAY_BYTE_2 TENS_2: mov AH,0 TENS_LOOP_2: cmp AL,10 jb TENS_LOOP_END_2 sub AL,10 inc AH jmp SHORT TENS_LOOP_2 TENS_LOOP_END_2: push AX mov AL,AH add AL,30H call PUTCHARINBUFFER pop AX UNITS_2: add AL,30H call PUTCHARINBUFFER ret ;-----------------------------------------------------------------------------; ; Convert byte in AL to Hex display ; ;-----------------------------------------------------------------------------; BYTE_TO_HEX: push AX shr AL,1 shr AL,1 shr AL,1 shr AL,1 call NIBBLE_TO_HEX pop AX call NIBBLE_TO_HEX ret NIBBLE_TO_HEX: and AL,0FH cmp AL,10 jb LESS_THAN_10 add AL,7 LESS_THAN_10: add AL,30H call PUTCHARINBUFFER ret TABLE DB 32 * TYPE TNCDATA DUP (0) ; ; STUFF FOLLOWIN IS DELETED FOLLOWING INSTALLATION ; ; ; BPQCFG FIRST 256 BYTES ; CONFIGTABLE LABEL BYTE ; ; CONFIGURATION DATA STRUCTURE ; ; DEFINES LAYOUT OF CONFIG RECORD PRODUCED BY CONFIGURATION PROG ; ; LAYOUT MUST MATCH THAT IN CONFIG.C SOURCE ; C_NODECALL DB 10 DUP (0) ; OFFSET = 0 C_NODEALIAS DB 10 DUP (0) ; OFFSET = 10 C_BBSCALL DB 10 DUP (0) ; OFFSET = 20 C_BBSALIAS DB 10 DUP (0) ; OFFSET = 30 ; C_OBSINIT DW 0 ; OFFSET = 40 C_OBSMIN DW 0 ; OFFSET = 42 C_NODESINTERVAL DW 0 ; OFFSET = 44 C_L3TIMETOLIVE DW 0 ; OFFSET = 46 C_L4RETRIES DW 0 ; OFFSET = 48 C_L4TIMEOUT DW 0 ; OFFSET = 50 C_BUFFERS DW 0 ; OFFSET = 52 C_PACLEN DW 0 ; OFFSET = 54 C_TRANSDELAY DW 0 ; OFFSET = 56 C_T3 DW 0 ; OFFSET = 58 DW 0 ; OFFSET = 60 DW 0 ; OFFSET = 62 C_IDLETIME DW 0 ; OFFSET = 64 C_EMSFLAG DB 0 ; OFFSET = 66 DB 0 C_BBS DB 0 ; OFFSET = 68 C_NODE DB 0 ; OFFSET = 69 C_HOSTINTERRUPT DB 0 ; OFFSET = 70 C_DESQVIEW DB 0 ; OFFSET = 71 C_MAXLINKS DW 0 ; OFFSET = 72 C_MAXDESTS DW 0 C_MAXNEIGHBOURS DW 0 C_MAXCIRCUITS DW 0 ; 78 C_TNCPORTLISTO DB 16 DUP (0) ; OFFSET = 80 C_IDINTERVAL DW 0 ; 96 C_XXXXXXXX DW 0 ; 98 ; SPARE (WAS DIGIFLAG) C_MINQUAL DW 0 ; 100 C_HIDENODES DB 0 ; 102 C_L4DELAY DW 0 ; 103 C_L4WINDOW DW 0 ; 105 C_BTINTERVAL DW 0 ; 106 X_UNPROTO DB 9 DUP (0) ; 108 ; NOW SPARE C_BBSQUAL DW 0 ; 117 C_UNPROTO DB 80 DUP (0) ; 119 DB (CONFIGTABLE+255-$) DUP (0) C_VERSION DB 0 ; CONFIG PROG VERSION ; UNPROTOCALL DB 80 DUP (0) STREAMBASE DB 33 ; FIRST BPQ HOST PORT PORT DB 0 ; FIRST COMBIOS PORT SAVEPACLEN DB 0 CONFIGHANDLE DW 0 INIT: MOV DATASEG,DS MOV DX,OFFSET MSG MOV AH,9 INT 21H ; ; GET NODE INTERRUPT NUMBER FROM CONFIG FILE ; MOV DX,OFFSET CONFIGFILENAME MOV AH,3DH MOV AL,0 ; READ ONLY INT 21H ; OPEN IT JC NOCONFIGFILE MOV CONFIGHANDLE,AX MOV BX,AX MOV DX,OFFSET CONFIGTABLE MOV CX,256 MOV AH,3FH INT 21H ; READ CMP AX,CX JNE SHORTCONFIG JMP SHORT PROCESSCONFIG NOCONFIGFILE: MOV DX,OFFSET NOCONFIGMSG DISPERR: MOV AH,9 INT 21H MOV AX,4C01H INT 21H SHORTCONFIG: MOV DX,OFFSET BADCONFIGMSG JMP SHORT DISPERR PROCESSCONFIG: MOV AL,BYTE PTR C_PACLEN MOV SAVEPACLEN,AL MOV SI,OFFSET C_UNPROTO MOV DI,OFFSET UNPROTOCALL ; UNPROTO DEST MOV CX,80 UNPLOOP: ; ; CONVERT TO UPPER CASE ; LODSB CMP AL,'a' JB UNPOK CMP AL,'z' JA UNPOK SUB AL,20H UNPOK: STOSB LOOP UNPLOOP ; ; CHECK SWITCH IS LOADED ; PUSH DS MOV AL,C_HOSTINTERRUPT ; INTERRUPT MOV BYTE PTR INTVAL+1,AL ; PATCH NODE CALL INSTRUCTION MOV AH,0 ADD AX,AX ADD AX,AX MOV SI,AX XOR AX,AX MOV DS,AX ; ; DS:SI POINTS TO VECTOR ; CMP WORD PTR DS:2[SI],0 POP DS JNE SWITCHINTOK NOSWITCH: MOV DX,OFFSET NOTBPQERROR JMP SHORT DISPERR SWITCHINTOK: MOV AH,0 CALL NODE ; CHECK IF LOADED AND GET VERSIONS CMP AX,'PB' ; NOT BPQ JE SWITCHOK MOV DX,OFFSET NOTBPQERROR JMP SHORT DISPERR SWITCHOK: CMP DH,MAJORVERSION JNE BADVERSION CMP DL,MINORVERSION JE VERSIONOK BADVERSION: MOV DX,OFFSET VERSERROR JMP SHORT DISPERR VERSIONOK: ; ; READ TNCPORTS FROM CONFIG FILE ; MOV BX,CONFIGHANDLE MOV DX,OFFSET CONFIGTABLE MOV CX,256 MOV AH,3FH INT 21H ; READ CMP AX,CX JNE SHORTCONFIG ; ; SEE IF DEFAULT PARAMS ; CMP WORD PTR DS:5DH,' ' ; SPACES? JNE USEPARAMS ; ; INITIALISE FROM INFO IN TNCPORTS IN CONFIG FILE ; MOV BX,TNCTABLE ; MOV SI,OFFSET CONFIGTABLE+128 MOV CX,16 ; MAX TNCLOOP: LODSB ; PORT NUMBER OR AL,AL ; END OF LIST? JE NOMORETNCS DEC AL ; COMBIOS NUMBERS START FROM 1, INT 14 PORTS FROM 0 MOV BIOSPORT[BX],AL INC NUMBEROFSTREAMS PUSH SI CALL INITIALISETNCPORT POP SI LODSB ; ; SET APPL CONTROL BITS ; MOV AL,3[SI] MOV APPLFLAGS[BX],AL ; FLAGS ; ; SET APPL IF SPECIFIED ; MOV AL,[SI] OR AL,AL JZ NOAPPL ; NOT SUPPLIED MOV APPLICATION[BX],AL NOAPPL: ADD SI,6 ; TO NEXT ENTRY ADD BX,TYPE TNCDATA LOOP TNCLOOP NOMORETNCS: CMP BX,TNCTABLE JNE GOTSOME ; ; NO PORTS DEFINED - EXIT ; MOV DX,OFFSET NOPORTSMSG JMP DISPERR GOTSOME: JMP INSTALLINTS BADPORTVAL: MOV AH,9 MOV DX,OFFSET ERRORMSG INT 21H RET USEPARAMS: MOV SI,82H ; PARAM STRING CALL GETVALUE ; NUMBER OF PORTS JC BADPORTVAL MOV AL,BYTE PTR NEWVALUE OR AL,AL JZ BADPORTVAL CMP AL,32 JA BADPORTVAL MOV AL,BYTE PTR NEWVALUE CBW MOV NUMBEROFSTREAMS,AX CALL GETVALUE ; BIOS PORT JC BADPORTVAL MOV AL,BYTE PTR NEWVALUE OR AL,AL JZ BADPORTVAL DEC AL MOV PORT,AL ; CALL GETVALUE ; NODE PORT JC BADPORTVAL MOV AL,BYTE PTR NEWVALUE OR AL,AL JZ BADPORTVAL ADD AL,BYTE PTR NUMBEROFSTREAMS CMP AL,65 JA BADPORTVAL MOV AL,BYTE PTR NEWVALUE MOV STREAMBASE,AL ; ; INITIALISE PORTS ; MOV CX,NUMBEROFSTREAMS MOV BX,TNCTABLE ; ; BX = PORT ENTRY, AL = INT14 PORT NUMBER ; INITPORT: MOV AL,PORT MOV BIOSPORT[BX],AL CALL INITIALISETNCPORT ADD BX,TYPE TNCDATA INC PORT LOOP INITPORT INSTALLINTS: PUSH BX ; ; INSTALL INTERRUPTS ; MOV AL,14H MOV AH,35H INT 21H ; GET VECTOR MOV WORD PTR OLDINT14,BX MOV WORD PTR OLDINT14+2,ES ; SAVE MOV DX,OFFSET INT14 MOV AL,14H MOV AH,25H ; SET NEW VECTOR INT 21H ; PUSH CS POP ES ; MOV BX,CONFIGHANDLE MOV AH,3EH INT 21H ; CLOSE CONFIG POP DX ; END ADDR INT 27H ; EXIT INITIALISETNCPORT: MOV AL,STREAMBASE MOV NODEPORT[BX],AL MOV AX,0 ; START OF BUFFER ADD AX,BX MOV PUTPTR[BX],AX MOV GETPTR[BX],AX MOV VLSR[BX],20H MOV VMSR[BX],30H OR MODEFLAG[BX],COMMAND MOV SENDPAC[BX],0DH MOV CRFLAG[BX],1 MOV MALL[BX],1 MOV MMASK[BX],0FFFFH ; MONITOR MASK FOR PORTS MOV AL,BYTE PTR SAVEPACLEN MOV TPACLEN[BX],AL ; TNC PACLEN MOV APPLICATION[BX],BBSAPPL ; FOR COMPATIBILITY MOV APPLFLAGS[BX],6 ; DEFAULT LEA DI,TXBUFFER[BX] MOV CURSOR[BX],DI ; RESET MESSAGE START PUSH CX MOV SI,OFFSET UNPROTOCALL CALL DECODECALLSTRING LEA DI,UNPROTO[BX] MOV CX,56 REP MOVSB ; UNPROTO ADDR POP CX INC STREAMBASE RET MSG DB 'TNC2 Interface for ' DB NAMESTRING DB ' switch version ' db VERSIONSTRING,' ',DATESTRING db 0dh,0ah,'$' ERRORMSG DB 0AH,'Parameter error:',0dh,0ah,0ah db 'Format is BPQHTNC2 Numberofports BIOSPort BPQHOSTPort' db 0dh,0AH,0ah,'Program NOT installed' DB 0dh,0ah,0AH,'$' NOTBPQERROR DB 'Switch not found$' VERSERROR DB 'Version not compatible with Node Software$' G8BPQ DB 'G8BPQ' BADCONFIGMSG DB 'Configuration file read error',0DH,0AH,'$' CONFIGFILENAME DB CONFIGNAME,0 NOCONFIGMSG DB 'Configuration file ',CONFIGNAME,' not found',0DH,0AH,'$' NOPORTSMSG DB 'No TNCPORTS defined in BPQCFG.TXT. Program not loaded',0dh,0ah,'$' CODE ENDS END GO