; ; 22/11/95 - Add second port alias for digipeating (for APRS) ; - Add PORTMAXDIGIS config ; PAGE 56,132 ; .LALL .LFCOND ; INCLUDE DVAPI.INC DEBUG EQU 0 CR EQU 0DH LF EQU 0AH POPFF MACRO ; MACRO TO AVIOD BUG IN POPF ON 286 JMP $+3 ; SKIP OVER IRET IRET ; POP CS IP FLAGS PUSH CS CALL $-2 ENDM STACK SEGMENT STACK 'STACK' DW 8 DUP (0) STACK ENDS ; ; DEFINE SEGS HERE TO FORCE LINK ORDER ; INITSEG SEGMENT PUBLIC 'INITSEG' INITSEG ENDS CODE SEGMENT PUBLIC 'CODE' CODE ENDS TERMDATA SEGMENT PUBLIC 'TERMDATA' TERMDATA ENDS IPDATA SEGMENT PUBLIC 'DATA' IPDATA ENDS ; ; FAR PROC EXTRNS ARE OUTSIDE SEGMENT DEFINITIONS ; EXTRN DECODECALLSTRINGF:FAR,FINDNEIGHBOURF:FAR,FINDDESTINATIONF:FAR EXTRN GETVALUEF:FAR,PROCROUTESF:FAR,CLEARINTS:FAR ; INCLUDE ENVIRON.ASM INCLUDE STRUCS.ASM IF DEBUG INCLUDELIB NETLIB ENDIF DATA SEGMENT PUBLIC 'DATA' ; ; POINTERS TO TABLES ARE AT START TO SIMPLIFY DIAGNOSTIC ; DUMP ANALYSIS, AND NODES SAVE ROUTINES ; FILLER DB 14 DUP (0) ; PROTECTION AGENST BUFFER PROBLEMS! DB MAJORVERSION,MINORVERSION NEIGHBOURS DW 0 DW TYPE NEIGHBOUR_LIST MAXNEIGHBOURS DW 20 ; MAX ADJACENT NODES DESTS DW 0 ; NODE LIST DW TYPE DEST_LIST MAXDESTS DW 100 ; MAX NODES IN SYSTEM LINKS DW 0 ; L2 LINK TABLE MAXLINKS DW 30 ; MAX LEVEL 2 LINKS (UP,DOWN AND INTERNODE) L4TABLE DW 0 MAXCIRCUITS DW 50 ; NUMBER OF L4 CIRCUITS PORTTABLE DW 0 NUMBEROFPORTS DW 0 TNCTABLE DW 0 NUMBEROFSTREAMS DW 0 ENDDESTLIST DW 0 ; NODE LIST+1 ; FREE_Q DW 0 ; FREE BUFFER CHAIN BUFFERPOOL DW 0 ; START OF BUFFER POOL OBSINIT DW 5 ; INITIAL OBSOLESCENCE VALUE OBSMIN DW 4 ; MINIMUM TO BROADCAST L3INTERVAL DW 60 ; 'NODES' INTERVAL IN MINS IDINTERVAL DW 20 ; 'ID' BROADCAST INTERVAL BTINTERVAL DW 20 ; 'BT' BROADCAST INTERVAL MINQUAL DW 10 ; MIN QUALITY FOR AUTOUPDATES HIDENODES DB 0 ; N * COMMAND SWITCH BBSQUAL DB 255 ; QUALITY OF BBS RELATIVE TO NODE ; NUMBEROFBUFFERS DW 50 ; PACKET BUFFERS PACLEN DW 100 ; MAX PACKET SIZE TRANSDELAY DW 3 ; TRANSPARENT MODE SEND DELAY - 1 SEC ; ; L2 SYSTEM TIMER RUNS AT 3 HZ ; T3 DW 3*61*3 ; LINK VALIDATION TIMER (3 MINS) (+ a bit to reduce RR collisions) L2KILLTIME DW 16*60*3 ; IDLE LINK TIMER (16 MINS) L3LIVES DW 15 ; MAX L3 HOPS L4N2 DW 3 ; LEVEL 4 RETRY COUNT L4T1 DW 60 ; LEVEL 4 TIMEOUT L4LIMIT DW 60*15 ; IDLE SESSION LIMIT - 15 MINS L4DELAY DW 5 ; L4 DELAYED ACK TIMER L4DEFAULTWINDOW DB 4 ; DEFAULT WINDOW BBS DB 0 ; INCLUDE BBS SUPPORT NODE DB 1 ; INCLUDE SWITCH SUPPORT ; LINKEDFLAG DB 0 SIGNONMSG LABEL BYTE DB NAMESTRING,' AX25 Packet Switch System ',CR,LF DB 'Version ' DB VERSIONSTRING,' - ',DATESTRING,CR,LF DB 'Copyright (c) 1988-94 John Wiseman.' DB CR,LF IF DEBUG db 'WARNING - AUTOMATIC DIAGNOSTIC DUMP ACTIVE - ENSURE' DB 0DH,0AH,'THAT DISK IN DRIVE B IS NOT IMPORTANT!' DB 0DH,0AH ENDIF DB '$' PASSERR DB 'Password file is invalid', 0dh,0ah DB 'Type CTRL/C to exit, any other key to continue' db 0dh,0ah,'$' PWFILE DB 'PASSWORD.BPQ' EVEN DW 64 DUP (0) ; INIT STACK - DOESNT NEED MUCH STACKTOP LABEL WORD DW 64 DUP (0) ; CAN ALSO USE INT STACK IF IN NEEDS IT INTSTACKTOP LABEL WORD ; AND ALSO THE CONFIG MESSAGE UNPROTOCALL DB 80 DUP (0) ; STATION INFORMATION ; MYCALL DB 7 DUP (0) ; NODE CALLSIGN (BIT SHIFTED) DB ' ' ; NODE ALIAS (KEEP TOGETHER) BBSCALL DB 7 DUP (0) ; BBS ADDR IN AX25 DB ' ' ; BBS ALIAS DB 20H ; FOR ATTACH COMMAND MYNODECALL DB 10 DUP (20H) ; NODE CALLSIGN (ASCII) MYLINKCALL DB 10 DUP (20H) ; BBS CALLSIGN ; ; ; 'ID' MESSAGE - SENT EVERY 10 MINS ; IDHDDR DB 0,0,0 DW 21 ; HEADER LENGTH IDDEST DB 'I'+'I','D'+'D',40h,40h,40h,40h,11100000B ; ID IN AX25 FORM IDORIGIN DB 7 DUP (0) DB 03H,0F0H ; UI, PID ; IDMSG DW 0 ; INFOMSG DW 0 INFOLEN DW 0 ; CTEXTMSG DW 0 CTEXTLEN DW 0 ; FULL_CTEXT DB 1 ; CTEXT ON ALL CONNECTS IF NZ MYALIAS DB 7 DUP (0) ; ALIAS IN AX25 FORM BBSALIAS DB 7 DUP (0) AX25CALL DB 7 DUP (0) ; WORK AREA FOR AX25 <> NORMAL CALL CONVERSION NORMCALL DB 10 DUP (0) ; CALLSIGN IN NORMAL FORMAT NORMLEN DW 0 ; LENGTH OF CALL IN NORMCALL NEXTFREEDATA DW 0 ; OFFSET OF NEXT FREE BYTE CURRENTPORT DB 0 ; PORT FOR CURRENT MESSAGE CURRENTPORTPTR DW 0 ; PORT CONTROL TABLE ENTRY FOR CURRENT PORT SDCBYTE DB 0 ; CONTROL BYTE FOR CURRENT FRAME SDRBYTE DB 0 ; SAVED CONTROL BYTE FOR FRMR BUFFER DW 0 ; GENERAL SAVE AREA FOR BUFFER ADDR ADJBUFFER DW 0 ; BASE ADJUSED FOR DIGIS TEMPFIELD DB 7 DUP (0) ; ADDRESS WORK FILED BUFFLEN EQU 340 ; ?? TRACE_Q DW 0 ; TRANSMITTED FRAMES TO BE TRACED RANDOM DB 0 ; 'RANDOM' NUMBER FOR PERSISTENCE CALCS L2TIMERFLAG DB 0 ; INCREMENTED AT 18HZ BY TIMER INTERRUPT L3TIMERFLAG DW 0 ; DITTO L4TIMERFLAG DB 10 ; DITTO TNCTIMERFLAG DB 3 ; DITTO PORTTIMERFLAG DB 0 HEADERCHAR DB '}' ; CHAR FOR NODE HEADER MSGS LASTPOINTER DW 0 ; PERVIOUS NODE DURING CHAINING DESQVIEW DB 0 ; SET NZ IF DV PRESENT VECTORLENGTH EQU 7 BPQHOSTSTREAMS EQU 64 BPQVECLENGTH DW VECTORLENGTH ; LENGTH OF VECTOR ENTRIES BPQHOSTVECTOR DB VECTORLENGTH*BPQHOSTSTREAMS DUP (0) IPHOSTVECTOR DB 7 DUP (0) ; ; VECTOR FORMAT IS: ; ; 0-1 2 BYTES - ADDRESS OF SESSION ENTRY ; 2 1 BYTE - STATE CHANGE FLAGS ; 3 1 BYTE - APPLICATION MASK ; 4 1 BYTE - APPLICATION FLAGS ; 5-6 2 BYTES - RAW FRAME QUEUE ; IF DEBUG BUFFERCOUNT DW 0 ; NUMBER OF BUFFERS BUFFERLIST DW 200 DUP (0) ; BUFFER ADDRESSES ENDIF REALTIMETICKS DW 0 SAVEPIC0 DB 1 SAVEPIC1 DB 1 HOSTINTERRUPT DB 0 NEEDKISS DB 0 ; SET IF KISS USED ; HH DB 0 MM DB 0 SSECS DB 0 B19 DB 19 D1093 DW 1093 PUBLIC HH,MM,SSECS PUBLIC MYCALL,MYALIAS,BBSALIAS,NORMCALL,AX25CALL,DESTS,TRACE_Q PUBLIC FREE_Q,CURRENTPORT,CURRENTPORTPTR,NEIGHBOURS,MYLINKCALL PUBLIC LINKS,PORTTABLE,NUMBEROFPORTS,BUFFER,ADJBUFFER,BUFFLEN PUBLIC SDCBYTE,SDRBYTE,L4TABLE,BUFFER,BBSCALL,NORMLEN,LINKEDFLAG PUBLIC IDMSG,INFOMSG,INFOLEN,RANDOM,BBS,NODE,DESQVIEW,IPHOSTVECTOR PUBLIC TNCTABLE,NUMBEROFSTREAMS,ENDDESTLIST,UNPROTOCALL,REALTIMETICKS PUBLIC MAXLINKS,MAXDESTS,MAXNEIGHBOURS,MAXCIRCUITS,HEADERCHAR PUBLIC BBS,T3,PACLEN,TRANSDELAY,L2KILLTIME,IDINTERVAL,BTINTERVAL PUBLIC OBSINIT,OBSMIN,NODE,L3INTERVAL,L4T1,L4N2,L3LIVES,L4LIMIT,L4DELAY PUBLIC MINQUAL,HIDENODES,L4DEFAULTWINDOW PUBLIC CTEXTMSG,CTEXTLEN,FULL_CTEXT PUBLIC BPQHOSTVECTOR,BPQVECLENGTH,BPQHOSTSTREAMS,VECTORLENGTH EXTRN TIMOVERRUNS:WORD,MINBUFFCOUNT:BYTE,NOBUFFCOUNT:WORD EXTRN IDTIMER:WORD,QCOUNT:BYTE,ROUTEQUAL:BYTE,APPLS:BYTE EXTRN DESTHEADER:WORD,BTTIMER:WORD,NUMBEROFNODES:WORD EXTRN MAXBUFFS:WORD,NEEDMH:BYTE EXTRN SAVEPORT:BYTE,PWTEXT:BYTE,PWLEN:BYTE EXTRN RAN1:BYTE,RAN2:BYTE,RAN3:BYTE,RAN4:BYTE,RAN5:BYTE EXTRN CMDALIAS:BYTE,ALIASPTR:WORD DATA ENDS ; INITIALISATION CODE - REMOVED ON EXIT ; PADSEG SEGMENT PUBLIC 'PADSEG' ; ; SPACE TO BE USED FOR DATA AREAS ; PADSEG ENDS INITSEG SEGMENT PUBLIC 'INITSEG' ASSUME CS:INITSEG,DS:DATA,ES:DATA,SS:DATA ; EXTRN INSTALLINT14:NEAR EXTRN KISSINIT:NEAR,PC120INIT:NEAR,DRSIINIT:NEAR,TOSHINIT:NEAR EXTRN QUADINIT:NEAR,RLC100INIT:NEAR,BAYCOMINIT:NEAR,PA0INIT:NEAR EXTRN CHECKQUAD:NEAR PUBLIC NEEDKISS,HOSTINTERRUPT 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 C_LINKEDFLAG DB 0 ; OFFSET = 67 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_FULLCTEXT DW 0 ; 98 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 ; ; C_APPLICATIONS DB 128 DUP (0) ; 16 BYTES FOR EACH OF 8 SERVICES C_TNCPORTLIST DB 128 DUP (0) ; 8 BYTES FOR EACH OF 16 PORTS C_IDMSG EQU 512 C_INFOMSG EQU 1024 C_ROUTES EQU 1536 C_CTEXT EQU 2048 C_PORTS EQU 2560 ; ; VECTORS TO HARDWARE DEPENDENT ROUTINES ; INITCODE DW KISSINIT ; 0 DW PC120INIT ; 2 DW DRSIINIT ; 4 DW TOSHINIT ; 6 DW QUADINIT ; 8 DW RLC100INIT ; 0A DW RLC100INIT ; 0C RLC400 DW LINKINIT ; 0E INTERNAL DW EXTINIT ; 10 EXTERNAL DRIVER DW BAYCOMINIT ; 12 DW PA0INIT ; 14 PA0HZP OPTO-SCC ; TXCODE DW KISSTX DW HDLCTX DW HDLCTX DW HDLCTX DW KISSTX ; QUADPORT DW HDLCTX ; RLC100 DW HDLCTX ; RLC400 DW LINKTX ; INTERNAL LINK DW EXTTX ; EXTERNAL DRIVER DW HDLCTX DW HDLCTX ; RXCODE DW KISSRX DW HDLCRX DW HDLCRX DW HDLCRX DW KISSRX ; QUADPORT DW HDLCRX DW HDLCRX DW LINKRX ; INTERNAL LINK DW EXTRX ; EXTERNAL DRIVER DW HDLCRX DW HDLCRX ; TIMERCODE DW KISSTIMER DW HDLCTIMER DW HDLCTIMER DW HDLCTIMER DW KISSTIMER ; QUADPORT DW HDLCTIMER DW HDLCTIMER DW LINKTIMER ; INTERNAL LINK DW EXTTIMER ; EXTERNAL DRIVER DW HDLCTIMER DW HDLCTIMER ; ; CONFIGFILENAME DB CONFIGNAME,0 NODESFILENAME DB NODESNAME,0 NOCONFIGMSG DB 'Configuration file ',CONFIGNAME,' not found',0DH,0AH,'$' NONODESMSG DB 0DH,0AH,'Route/Node recovery file ',NODESNAME,' not found',0DH,0AH DB 'Continuing without it',0dh,0ah,'$' BADVERSION DB 'Configuration file built with wrong version of ',CONFIGPROG,0dh,0ah,'$' ALREADYLOADED DB 'Switch Code is already loaded',cr,lf,'$' CONFIGHANDLE DW 0 BADCONFIGMSG DB 'Configuration file read error',0DH,0AH,'$' BADNODEMSG DB 'Invalid Record in recovery file',0dh,0ah,'$' ROUTEADD DB 'ROUTE ADD ' NODEADD DB 'NODE ADD ' INITPTR DW 0 ; POINTER SAVE AREA EMSFLAG DB 0 NOTENUFMSG DB 'Insufficient RAM available$' loadedmsg DB cr,lf,lf,'Switch loaded and initialised OK' CRLF DB cr,lf,'$' EVEN BUFFERLEN DW BUFFLEN TOPOFDATA DW 0 READCOUNT DW 128 ; CHARS USED IN THIS SEGMENT READPOINTER DW 0 ; NEXT ADDRESS IN DISK BUFFER ; TICKSPERMINUTE DW 18*60 INITMSG DB CR,LF,'Initialising Port ' INITPORT DW 'XX' DB ' $' B10 DB 10 BADEXTMSG DB 7,'No Driver installed!!',7,0dh,0ah,'$' START: MOV AX,DATA MOV SS,AX MOV SP,OFFSET STACKTOP ; IN AL,21H MOV SS:SAVEPIC0,AL IN AL,0A1H MOV SS:SAVEPIC1,AL PUSH DS ; SAVE PSP ADDRESS MOV AX,DS:2 ; TOP SEGMENT AVAILABLE SUB AX,DATA CMP AX,1000H JAE PLENTY ; ; NO ROOM FOR FULL DATA SEGMENT - SET TOP ADDRESS ; MOV CL,4 SHL AX,CL MOV TOPOFDATA,AX CMP AX,30000 JA PLENTY ; ; INSUFFICIENT RAM ; PUSH CS POP DS MOV DX,OFFSET NOTENUFMSG MOV AH,9 INT 21H MOV AX,4C01H INT 21H PLENTY: MOV AX,CODE MOV DS,AX ; ASSUME DS:CODE MOV AL,ES:5DH MOV BWFLAG,AL ; M FOR MONO MOV AX,DATA MOV DS,AX MOV ES,AX ; ASSUME DS:DATA ; CALCULATE ADDRESS OF NEXT FREE BYTE IN DATA SEG (= START OF PADSEG) ; MOV AX,PADSEG SUB AX,DATA ; LENGTH OF DATA SEG (PARAS) MOV CL,4 SHL AX,CL ; CONVERT TO BYTES MOV NEXTFREEDATA,AX ; SAVE ; ; CLEAR REST OF DATA SEG ; MOV DI,AX MOV CX,TOPOFDATA SUB CX,DI MOV AL,0 REP STOSB MOV DX,OFFSET SIGNONMSG MOV AH,9 INT 21H ; ; READ PASSWORD FILE ; MOV DX,OFFSET PWFILE MOV AH,3DH MOV AL,0 ; READ ONLY INT 21H ; OPEN IT JC NOPASSFILE MOV BX,AX MOV DX,OFFSET PWTEXT MOV CX,78 MOV AH,3FH INT 21H MOV AH,3EH INT 21H ; CLOSE MOV PWLEN,0 MOV SI,OFFSET PWTEXT PWSETUP: CMP BYTE PTR [SI],20H JB FILEOK INC SI INC PWLEN JMP SHORT PWSETUP NOPASSFILE: MOV DX,OFFSET PASSERR MOV AH,9 INT 21H MOV AH,1 INT 21H FILEOK: ; ; READ CONFIG FILE, AND EXTRACT DATA ; MOV AX,INITSEG MOV DS,AX ASSUME DS:INITSEG 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,512 MOV AH,3FH INT 21H ; READ CMP AX,CX JNE SHORTCONFIG JMP SHORT PROCESSCONFIG NOCONFIGFILE: MOV DX,OFFSET NOCONFIGMSG JMP SHORT CONFIGERR SHORTCONFIG: MOV DX,OFFSET BADCONFIGMSG CONFIGERR: MOV AH,9 INT 21H MOV AX,4C01H INT 21H ; EXIT PROCESSCONFIG: CMP C_VERSION,CONFIGVERSION JE VERSION_OK MOV DX,OFFSET BADVERSION JMP CONFIGERR VERSION_OK: MOV AX,DATA MOV ES,AX MOV AL,C_EMSFLAG MOV EMSFLAG,AL ; SAVE EMS FLAG MOV AL,C_HOSTINTERRUPT OR AL,AL JNZ INT_OK MOV AL, 127 ; DEFAULT INT_OK: MOV HOSTINTERRUPT,AL MOV SI,OFFSET C_NODECALL CMP C_NODE,0 JNE GOTNODE ; ; USE BBS CALL FOR NODE AS WELL ; MOV SI,OFFSET C_BBSCALL GOTNODE: MOV DI,OFFSET MYNODECALL MOV CX,10 REP MOVSB ; COPY NODE CALL MOV DI,OFFSET MYCALL+7 MOV CX,6 REP MOVSB ; COPY NODE ALIAS ; ; IF NO BBS, SET BOTH TO NODE CALLSIGN ; MOV SI,OFFSET C_BBSCALL CMP C_BBS,0 JNE GOTBBS MOV SI,OFFSET C_NODECALL GOTBBS: MOV DI,OFFSET MYLINKCALL MOV CX,10 REP MOVSB ; COPY BBS CALL MOV DI,OFFSET BBSCALL+7 MOV CX,6 REP MOVSB ; COPY BBS ALIAS 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 MOV AX,C_OBSINIT MOV OBSINIT,AX MOV AX,C_OBSMIN MOV OBSMIN,AX MOV AX,C_NODESINTERVAL MOV L3INTERVAL,AX MOV AX,C_IDINTERVAL MOV IDINTERVAL,AX OR AX,AX JZ NO_ID MOV IDTIMER,2 NO_ID: MOV AX,C_BTINTERVAL MOV BTINTERVAL,AX OR AX,AX JZ NO_BT MOV BTTIMER,2 NO_BT: MOV AX,C_MINQUAL MOV MINQUAL,AX MOV AX,C_FULLCTEXT MOV FULL_CTEXT,AL MOV AX,C_BBSQUAL MOV BBSQUAL,AL MOV AX,C_L3TIMETOLIVE MOV L3LIVES,AX MOV AX,C_L4RETRIES MOV L4N2,AX MOV AX,C_L4WINDOW MOV L4DEFAULTWINDOW,AL MOV AX,C_L4TIMEOUT MOV L4T1,AX MOV AX,C_BUFFERS MOV NUMBEROFBUFFERS,AX MOV AX,C_PACLEN MOV PACLEN,AX MOV AX,C_TRANSDELAY MOV TRANSDELAY,AX ADD TRANSDELAY,AX ADD TRANSDELAY,AX ; X 3 MOV AX,C_T3 MOV T3,AX ADD T3,AX ADD T3,AX ; X 3 MOV AX,C_IDLETIME MOV L4LIMIT,AX MOV L2KILLTIME,AX ADD L2KILLTIME,AX ADD L2KILLTIME,AX ; X 3 MOV AX,C_L4DELAY MOV L4DELAY,AX ; MOV AL,C_BBS ; MOV BBS,AL ; ; MOV AL,C_NODE ; MOV NODE,AL MOV AL,C_DESQVIEW MOV DESQVIEW,AL MOV AL,C_LINKEDFLAG MOV LINKEDFLAG,AL MOV AX,C_MAXLINKS MOV MAXLINKS,AX MOV AX,C_MAXDESTS MOV MAXDESTS,AX MOV AX,C_MAXNEIGHBOURS MOV MAXNEIGHBOURS,AX MOV AX,C_MAXCIRCUITS MOV MAXCIRCUITS,AX MOV AL,C_HIDENODES MOV HIDENODES,AL ; SET UP APPLICATION LIST ; MOV CX,8 MOV SI,OFFSET C_APPLICATIONS MOV DI,OFFSET APPLS MOV ES:ALIASPTR,OFFSET CMDALIAS APPLLOOP: CMP BYTE PTR [SI],20H ; UNUSED - LEAVE ALONE JE NXTAPPL PUSH SI PUSH DI PUSH CX MOV CX,12 APPLCOPY: LODSB CMP AL,'/' JE GOTALIAS STOSB LOOP APPLCOPY JMP SHORT APPLDONE GOTALIAS: PUSH CX PUSH DI MOV DI,ES:ALIASPTR ADD CX,3 REP MOVSB POP DI POP CX ; ; CLEAR REST OF COMMAND ; MOV AL,20H REP STOSB APPLDONE: POP CX POP DI ; ; SET LENGTH FIELD ; MOV BYTE PTR ES:12[DI],0 ; LENGTH MOV SI,DI LENLOOP: INC BYTE PTR ES:12[DI] INC SI CMP BYTE PTR ES:[SI],20H JA LENLOOP POP SI NXTAPPL: ADD SI,16 ADD DI,17 ; LONGER DOR SYSTEMS WITH SYSOP!! ADD ES:ALIASPTR,16 LOOP APPLLOOP ; ; ; SET UP PORT TABLE ; MOV AX,C_PORTS CALL POSITIONCONFIG MOV BX,NEXTFREEDATA MOV PORTTABLE,BX PORTLOOP: MOV CX,512 CALL READCONFIGRECORD CMP AX,512 JNE BADPORTREAD CMP CONFIGTABLE,0 JNE PORTREADOK ; ; END OF LIST ; BADPORTREAD: JMP ENDPORTLOOP PORTREADOK: MOV SI,OFFSET CONFIGTABLE LODSW MOV ES:PORTNUMBER[BX],AL LEA DI,PORTDESCRIPTION[BX] MOV CX,30 REP MOVSB ; LODSW ; H/W TYPE MOV ES:PORTTYPE[BX],AL MOV DI,OFFSET INITCODE ADD DI,AX MOV CX,[DI] MOV ES:PORTINITCODE[BX],CX ; ADDR OF INIT ROUTINE MOV DI,OFFSET TXCODE ADD DI,AX MOV CX,[DI] MOV ES:PORTTXROUTINE[BX],CX MOV DI,OFFSET RXCODE ADD DI,AX MOV CX,[DI] MOV ES:PORTRXROUTINE[BX],CX MOV DI,OFFSET TIMERCODE ADD DI,AX MOV CX,[DI] MOV ES:PORTTIMERCODE[BX],CX LODSW MOV ES:PROTOCOL[BX],AL LODSW MOV ES:IOBASE[BX],AX LODSW MOV ES:INTLEVEL[BX],AL LODSW MOV ES:BAUDRATE[BX],AX LODSW MOV ES:CHANNELNUM[BX],AL LODSW MOV ES:BBSBANNED[BX],AL LODSW MOV ES:PORTQUALITY[BX],AL LODSW MOV ES:PORTWINDOW[BX],AL LODSW CALL CONVTIME ; CONVERT TO TIMER TICKS MOV ES:PORTTXDELAY[BX],AL LODSW CALL CONVTIME ; CONVERT TO TIMER TICKS MOV ES:PORTSLOTTIME[BX],AL LODSW MOV ES:PORTPERSISTANCE[BX],AL LODSW MOV ES:FULLDUPLEX[BX],AL LODSW MOV ES:SOFTDCDFLAG[BX],AL LODSW CALL CONV3SECS ; CONVERT MSECS TO 1/3 SECS MOV ES:PORTT1[BX],AL LODSW CALL CONV3SECS ; CONVERT MSECS TO 1/3 SECS MOV ES:PORTT2[BX],AL LODSW MOV ES:PORTN2[BX],AL LODSW MOV ES:PORTPACLEN[BX],AL ; LODSW MOV ES:QUAL_ADJUST[BX],AL ; 'SAME PORT' QUALITY FACTOR ; LODSW MOV ES:DIGIFLAG[BX],AL ; DIGI CONTROL FLAG ; LODSW MOV ES:DIGIPORT[BX],AL ; PORT FOR CROSS BAND DIGI ; LODSW MOV ES:USERS[BX],AL ; NUMBER OF L2 SESSIONS ; LODSW ; TAIL ; ; IF USING KISS, SET A DEFAULT IF ZERO SPECIFIED ; CMP ES:PORTTYPE[BX],0 ; ASYNC JE TAILKISS CMP ES:PORTTYPE[BX],8 ; QUAD JE TAILKISS ; ; ON HDLC, TAIL TIMER IS USED TO HOLD RTS FOR 'CONTROLLED FULL DUP' ; MODE. VALUE IS IN SECONDS, NOT MS ; JMP SHORT SETTAIL TAILKISS: OR AX,AX JNZ GOTTAIL MOV AX,30 ; DEFAULT GOTTAIL: CALL CONVTIME ; CONVERT TO TIMER TICKS SETTAIL: MOV ES:PORTTAILTIME[BX],AL LODSW MOV ES:PORTBBSFLAG[BX],AL ; PORT CALL/ALIAS IS BBS FLAG MOV SI,OFFSET CONFIGTABLE+110 ; LODSW MOV ES:PORTL3FLAG[BX],AL ; L3 ONLY FLAG ; LODSW MOV ES:KISSFLAGS[BX],AL ; KISS MODE OPTION BITS ; LODSW MOV ES:PORTINTERLOCK[BX],AL ; PORT INTERLOCK MASK ; LODSW MOV ES:NODESPACLEN[BX],AL ; LENGTH OF NODES PACKET LODSW MOV ES:TXPORT[BX],AL ; IF SHARED TX SYSTEM MOV AL,CONFIGTABLE+122 ; MINQUAL MOV ES:PORTMINQUAL[BX],AL ; MOV AL,CONFIGTABLE+123 ; MAXDIGIS OR AL,AL JNZ @F ; DEFINED MOV AL,8 @@: MOV ES:PORTMAXDIGIS[BX],AL ; SET UP CWID ; MOV AL,CONFIGTABLE+121 ; FLAG FOR ONOFF KEYING CMP AL,'o' JNE SETTYPE MOV AL,'O' SETTYPE: MOV ES:CWTYPE[BX],AL MOV SI,OFFSET CONFIGTABLE+80; TO CWID FIELD MOV CX,8 ; MAX ID LENGTH LEA DI,CWID[BX] MOV ES:CWPOINTER[BX],DI MOV AX,29 ; ALLOW A MINUTE FOR CHANNEL TO GO QUIET SUB AL,ES:PORTNUMBER[BX] ; SPREAD THEM OUT A BIT MUL TICKSPERMINUTE MOV ES:CWIDTIMER[BX],AX CWIDLOOP: LODSB CMP AL,20H JBE CWIDEND CMP AL,'Z' JA CWIDBAD SUB AL,2FH JC CWIDBAD ; DUFF CHAR CBW PUSH SI MOV SI,OFFSET CWTABLE ADD SI,AX ADD SI,AX LODSW ; PATTERN STOSW POP SI CWIDBAD: LOOP CWIDLOOP CWIDEND: ; ; SEE IF LINK CALLSIGN/ALIAS SPECIFIED ; MOV SI,OFFSET CONFIGTABLE+90; TO LINK CALL CMP BYTE PTR [SI],20H JBE NOLINKCALL MOV DI,OFFSET NORMCALL MOV CX,10 REP MOVSB PUSH DS PUSH ES POP DS ; SET DS TO DATA MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL LEA DI,PORTCALL[BX] MOV CX,7 REP MOVSB POP DS NOLINKCALL: MOV SI,OFFSET CONFIGTABLE+100; TO LINK ALIAS CMP BYTE PTR [SI],20H JBE NOLINKALIAS MOV DI,OFFSET NORMCALL MOV CX,10 REP MOVSB PUSH DS PUSH ES POP DS ; SET DS TO DATA MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL LEA DI,PORTALIAS[BX] MOV CX,7 REP MOVSB POP DS NOLINKALIAS: MOV SI,OFFSET CONFIGTABLE+200; TO 2ND LINK ALIAS CMP BYTE PTR [SI],20H JBE NOLINKALIAS2 MOV DI,OFFSET NORMCALL MOV CX,10 REP MOVSB PUSH DS PUSH ES POP DS ; SET DS TO DATA MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL LEA DI,PORTALIAS2[BX] MOV CX,7 REP MOVSB POP DS NOLINKALIAS2: ; ; SET UP NEXT PORT PTR ; MOV AX,BX ADD AX,TYPE PORTCONTROL MOV ES:PORTPOINTER[BX],AX ; ; SEE IF PERMITTED LINK CALLSIGNS SPECIFIED ; MOV SI,OFFSET CONFIGTABLE+256 ; TO PERMITTED CALLS CMP BYTE PTR [SI],20H JBE NOPERMITTEDCALLS ; NONE SPECIFIED MOV ES:PERMITTEDCALLS[BX],AX; START OF STRING NEXTPERMCALL: CMP BYTE PTR [SI],20H JBE NOMOREPERMITTEDCALLS ; NO MORE LEFT MOV DI,OFFSET NORMCALL MOV CX,10 GETPERMCALLLOOP: LODSB STOSB CMP AL,' ' JE ENDPERMCALL CMP AL,',' JE ENDPERMCALL LOOP GETPERMCALLLOOP ENDPERMCALL: PUSH SI PUSH DS PUSH ES POP DS ; SET DS TO DATA MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,ES:PORTPOINTER[BX] MOV CX,7 REP MOVSB ADD ES:PORTPOINTER[BX],7 POP DS POP SI CMP SI,OFFSET CONFIGTABLE+502; WITHIN 10 OF END? JBE NEXTPERMCALL ; OK NOMOREPERMITTEDCALLS: INC ES:PORTPOINTER[BX] ; ADD NULL TO END OF STRING NOPERMITTEDCALLS: ; ; SEE IF PORT UNPROTO ADDR SPECIFIED ; MOV SI,OFFSET CONFIGTABLE+128; TO PORT UNPROTO CMP BYTE PTR [SI],20H JBE NOPORTUNPROTO ; NONE SPECIFIED MOV AX,ES:PORTPOINTER[BX] MOV ES:PORTUNPROTO[BX],AX ; START OF STRING NEXTUNPROTO: CMP BYTE PTR [SI],20H JBE NOMOREUNPROTO ; NO MORE LEFT MOV DI,OFFSET NORMCALL MOV CX,10 GETUNPROTOLOOP: LODSB STOSB CMP AL,' ' JE ENDUNPROTO CMP AL,',' JE ENDUNPROTO LOOP GETUNPROTOLOOP ENDUNPROTO: PUSH SI PUSH DS PUSH ES POP DS ; SET DS TO DATA MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,ES:PORTPOINTER[BX] MOV CX,7 REP MOVSB ADD ES:PORTPOINTER[BX],7 POP DS POP SI CMP SI,OFFSET CONFIGTABLE+242; WITHIN 10 OF END? JBE NEXTUNPROTO ; OK NOMOREUNPROTO: INC ES:PORTPOINTER[BX] ; ADD NULL TO END OF STRING NOPORTUNPROTO: ; ; ADD MH AREA IF NEEDED ; CMP CONFIGTABLE+120,'N' JE NO_MH MOV ES:NEEDMH,1 MOV AX,ES:PORTPOINTER[BX] MOV ES:PORTMHEARD[BX],AX ; START OF AREA ADD ES:PORTPOINTER[BX],20*(TYPE MHSTRUC) NO_MH: MOV BX,ES:PORTPOINTER[BX] INC NUMBEROFPORTS JMP PORTLOOP ENDPORTLOOP: MOV NEXTFREEDATA,BX MOV AX,DATA MOV DS,AX ASSUME DS:DATA ; ; SET UP VARIOUS CONTROL TABLES ; MOV AX,TYPE LINKTABLE MUL MAXLINKS MOV BX,NEXTFREEDATA MOV LINKS,BX ADD NEXTFREEDATA,AX ; MOV AX,TYPE DEST_LIST MUL MAXDESTS MOV BX,NEXTFREEDATA MOV DESTS,BX ADD BX,AX MOV NEXTFREEDATA,BX MOV ENDDESTLIST,BX ; MOV AX,TYPE NEIGHBOUR_LIST MUL MAXNEIGHBOURS MOV BX,NEXTFREEDATA MOV NEIGHBOURS,BX ADD NEXTFREEDATA,AX ; MOV AX,TYPE TRANSPORTENTRY MUL MAXCIRCUITS MOV BX,NEXTFREEDATA MOV L4TABLE,BX ADD NEXTFREEDATA,AX ; ; SET UP DEFAULT ROUTES LIST ; MOV AX,C_ROUTES CALL READCONFIG MOV BX,NEIGHBOURS MOV SI,OFFSET CONFIGTABLE ROUTELOOP: CMP BYTE PTR CS:[SI],0 JE ROUTEEND PUSH SI MOV DI,OFFSET NORMCALL MOV CX,10 CLI REP MOVS NORMCALL,CONFIGTABLE ; COPY INTO OUR SEG STI MOV SI,OFFSET NORMCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,BX MOV CX,7 REP MOVSB POP SI ADD SI,10 LODS CONFIGTABLE MOV ES:NEIGHBOUR_QUAL[BX],AL ; SET QUALITY LODS CONFIGTABLE MOV ES:NEIGHBOUR_PORT[BX],AL ; SET PORT LODS CONFIGTABLE MOV ES:NBOUR_MAXFRAME[BX],AL ; SET WINDOW LODS WORD PTR CONFIGTABLE OR AX,AX JZ NORFRACK CALL CONV3SECS NORFRACK: MOV ES:NBOUR_FRACK[BX],AL ; SET FRACK LODS CONFIGTABLE MOV ES:NBOUR_PACLEN[BX],AL MOV ES:NEIGHBOUR_FLAG[BX],1 ; LOCKED ROUTE ADD BX,TYPE NEIGHBOUR_LIST JMP ROUTELOOP ROUTEEND: ; ; SET UP INFO MESSAGE ; MOV DI,NEXTFREEDATA MOV BX,DI MOV INFOMSG,DI MOV AX,C_INFOMSG CALL READCONFIG MOV SI,OFFSET CONFIGTABLE SETUPINFO: LODS CONFIGTABLE STOSB OR AL,AL JNZ SETUPINFO DEC DI ; DONT WANT THE NULL MOV NEXTFREEDATA,DI SUB DI,BX MOV INFOLEN,DI ; ; SET UP CTEXT MESSAGE ; MOV AX,C_CTEXT CALL READCONFIG MOV DI,NEXTFREEDATA MOV BX,DI MOV CTEXTMSG,DI MOV SI,OFFSET CONFIGTABLE SETUPCTEXT: LODS CONFIGTABLE STOSB OR AL,AL JNZ SETUPCTEXT DEC DI ; DONT WANT THE NULL MOV NEXTFREEDATA,DI SUB DI,BX MOV CTEXTLEN,DI ; ; SET UP ID MESSAGE ; MOV DI,NEXTFREEDATA MOV BX,DI ; SAVE MOV IDMSG,DI MOV SI,OFFSET IDHDDR MOV CX,21 REP MOVSB ; COPY HEADER MOV AX,C_IDMSG CALL READCONFIG MOV SI,OFFSET CONFIGTABLE SETUPID: LODS CONFIGTABLE STOSB OR AL,AL JNZ SETUPID DEC DI ; REMOVE TRAILING NULL MOV NEXTFREEDATA,DI SUB DI,BX MOV BX,IDMSG MOV 3[BX],DI ; PUT LENGTH INTO MESSAGE ; ; FINISHED WITH CONFIG FILE - CLOSE IT ; MOV BX,CONFIGHANDLE MOV AH,3EH INT 21H ; CLOSE ; ; SET UP FREE BUFFER POOL - MUST BE DONE LAST ; MOV DI,NEXTFREEDATA ; FREE SPACE MOV BUFFERPOOL,DI ; ; CALCULATE MAX SPACE AVAILABLE FOR BUFFERS ; MOV AX,TOPOFDATA SUB AX,NEXTFREEDATA MOV DX,0 DIV BUFFERLEN MOV CX,AX MOV NUMBEROFBUFFERS,0 IF DEBUG MOV BX,OFFSET BUFFERLIST ENDIF BUFF000: MOV SI,OFFSET FREE_Q PUSH DI CALL Q_ADD_INIT POP DI INC NUMBEROFBUFFERS INC MAXBUFFS ADD DI,BUFFLEN LOOP BUFF000 BUFF001: ; MOV NEXTFREEDATA,DI ; ; SET UP OUR CALLIGN(S) ; MOV SI,OFFSET MYNODECALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,OFFSET MYCALL MOV CX,7 REP MOVSB MOV SI,OFFSET AX25CALL MOV DI,IDMSG LEA DI,12[DI] ; COPY TO ID MESSAGE MOV CX,7 REP MOVSB OR BYTE PTR -1[DI],01100001B ; SET CMD END AND RESERVED BITS MOV SI,OFFSET MYCALL+7 ; ALIAS CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,OFFSET MYALIAS MOV CX,7 REP MOVSB MOV SI,OFFSET MYLINKCALL CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL ; CONSOLE CALLSIGN MOV DI,OFFSET BBSCALL MOV CX,7 REP MOVSB MOV SI,OFFSET BBSCALL+7 ; ALIAS CALL FAR PTR CONVTOAX25F MOV SI,OFFSET AX25CALL MOV DI,OFFSET BBSALIAS MOV CX,7 REP MOVSB ; ; SET UP INITIAL DEST ENTRY FOR BBS (IF BOTH NODE AND BBS NEEDED) ; MOV AL,0 CMP AL,NODE JE NOBBSDEST CMP AL,BBS JE NOBBSDEST MOV BX,DESTS MOV SI,OFFSET BBSCALL LEA DI,DEST_CALL[BX] MOV CX,13 REP MOVSB MOV DEST_STATE[BX],80H ; SPECIAL ENTRY MOV AL,BBSQUAL MOV ROUT1_QUALITY[BX],AL MOV ROUT1_OBSCOUNT[BX],255 MOV DESTHEADER,BX ; FISRT IN ALPHABETIC CHAIN INC NUMBEROFNODES NOBBSDEST: ; ; CALL PORT INITIALISATION ROUTINES ; CLI MOV BX,PORTTABLE MOV CX,NUMBEROFPORTS INITL00: ; MOV AL,PORTNUMBER[BX] MOV AH,0 DIV B10 ADD AX,3030H MOV INITPORT,AX PUSH DS PUSH CS POP DS MOV DX,OFFSET INITMSG MOV AH,9 INT 21H POP DS PUSH BX PUSH CX CALL PORTINITCODE[BX] POP CX POP BX MOV BX,PORTPOINTER[BX] LOOP INITL00 ; CALL CHECKQUAD ; SET UP QUADPORT INTS IF NECESSARY CALL CLEARINTS STI ; MOV AL,0DH CALL PRINTIT MOV AL,0AH CALL PRINTIT ; READ ROUTE/NODE RECOVERY FILE (IF PRESENT) ; ; MOV AX,INITSEG MOV DS,AX MOV ES,AX ASSUME DS:INITSEG,ES:INITSEG MOV DX,OFFSET NODESFILENAME MOV AH,3DH MOV AL,0 ; READ ONLY INT 21H ; OPEN IT JC NONODESCONFIGFILE JMP SHORT PROCESSNODESFILE NONODESCONFIGFILE: MOV DX,OFFSET NONODESMSG MOV AH,9 INT 21H JMP NONODESFILE PROCESSNODESFILE: MOV CONFIGHANDLE,AX INITNODESLOOP: CALL GETRECORD ; EXTRACT NEXT RECORD (INTO UNPROTOCALL) ASSUME DS:INITSEG,ES:DATA MOV DI,OFFSET UNPROTOCALL MOV AL,ES:[DI] CMP AL,1AH ; EOF? JE ENDNODESLOOP CMP AL,';' ; COMMENT? JE INITNODESLOOP ; YES MOV SI,OFFSET ROUTEADD MOV CX,10 REP CMPSB JE PROCROUTEJMP MOV DI,OFFSET UNPROTOCALL MOV SI,OFFSET NODEADD MOV CX,9 REP CMPSB JE PROCNODE BADNODELINE: MOV DX,OFFSET BADNODEMSG MOV AH,9 INT 21H ; ; DISPLAY BAD LINE ; PRINTTOEND: PUSH ES POP DS ; DS=DATA MOV SI,OFFSET UNPROTOCALL PRINTTOEND1: LODSB CMP AL,1AH ; EOF? JE ENDNODESLOOP CALL PRINTIT CMP SI,OFFSET UNPROTOCALL+79 JNE PRINTTOEND1 MOV AL,CR CALL PRINTIT MOV AL,LF CALL PRINTIT JMP INITNODESLOOP PRINTIT: MOV DL,AL MOV AH,6 INT 21H RET PROCNODE: JMP PROCESSNODEADD PROCROUTEJMP: JMP PROCROUTE ENDNODESLOOP: PUSH CS POP DS MOV BX,CONFIGHANDLE MOV AH,3EH INT 21H ; CLOSE ; NONODESFILE: CALL INSTALLTIMER ; START SYSTEM TIMER ; push ds push cs pop ds mov dx,offset loadedmsg mov ah,9 int 21h pop ds ; ; WAIT FOR A COUPLE OF SECS SO USER CAN READ ANY MESSAGES ; WAITABIT: CMP REALTIMETICKS,50 JB WAITABIT JMP FAR PTR MAINCODE BADRETURN: MOV AX,CS MOV DS,AX MOV ES,AX JMP BADNODELINE PROCROUTE: ; ; FORMAT IS ROUTE ADD CALLSIGN PORT QUAL (VIA .... ; PROCESSLINE: MOV AX,DATA MOV DS,AX ASSUME DS:DATA,ES:DATA MOV SI,OFFSET UNPROTOCALL+10 CALL FAR PTR CONVTOAX25F JNZ BADCALL_JMP CALL GETVALUEF MOV SAVEPORT,AL ; SET PORT FOR FINDNEIGHBOUR CALL GETVALUEF MOV ROUTEQUAL,AL ; MOV INITPTR,SI ; SAVE ; ; SEE IF ALREADY IN LIST ; MOV SI,OFFSET AX25CALL CALL FINDNEIGHBOURF JZ INITRETURN ; IGNORE IF ALREADY THERE (PROBABLY FROM CONFIG FILE CMP BX,0 JE NOROOM MOV DI,BX MOV CX,7 REP MOVSB MOV AL,SAVEPORT MOV NEIGHBOUR_PORT[BX],AL ; SET PORT MOV AL,ROUTEQUAL MOV NEIGHBOUR_QUAL[BX],AL ; SET QUALITY MOV SI,INITPTR LODSB CMP AL,'!' JNE NOTLOCKED MOV NEIGHBOUR_FLAG[BX],1 ; LOCKED ROUTE NOTLOCKED: ; ; SEE IF ANY DIGIS ; INC SI LODSW CMP AL,'V' JNE INITRETURN ADD SI,2 CALL FAR PTR CONVTOAX25F JNZ BADCALL PUSH SI MOV SI,OFFSET AX25CALL LEA DI,7[BX] MOV CX,7 REP MOVSB POP SI CMP BYTE PTR [SI],20H JE INITRETURN CALL FAR PTR CONVTOAX25F BADCALL_JMP: JNZ BADCALL MOV SI,OFFSET AX25CALL LEA DI,14[BX] MOV CX,7 REP MOVSB NOROOM: INITRETURN: MOV AX,CS MOV DS,AX MOV ES,AX JMP INITNODESLOOP BADCALL: JMP BADRETURN PROCESSNODEADD: ; ; FORMAT IS NODE ADD ALIAS:CALL ROUTE QUAL ; ; FIND CALL (AFTER ':') ; MOV AX,DATA MOV DS,AX MOV SI,OFFSET UNPROTOCALL+9 MOV DI,OFFSET TEMPFIELD MOV CX,7 ; MAX ALIAS PNODE30: LODSB CMP AL,':' JE PNODE40 STOSB LOOP PNODE30 PNODE35: JMP BADRETURN PNODE40: DEC CX JCXZ PNODE45 ; 6 CHAR ALIAS MOV AL,20H REP STOSB ; CLEAR REST OF ALIAS PNODE45: CALL FAR PTR CONVTOAX25F JNZ PNODE35 ; DUFF ; MOV INITPTR,SI ; SAVE POINTER MOV SI,OFFSET AX25CALL CALL FINDDESTINATIONF JNZ PNODE47 JMP BADRETURN ; SHOULD ONLY BE IN ONCE PNODE47: CMP BX,0 JNE PNODE48 JMP NOROOMFORNODE PNODE48: LEA DI,DEST_CALL[BX] MOV CX,7 REP MOVSB MOV CX,6 ; ADD ALIAS MOV SI,OFFSET TEMPFIELD REP MOVSB INC NUMBEROFNODES ; ; PUT ON SORTED NODES CHAIN ; MOV SI,DESTHEADER CMP SI,0 JNE NOTEMPTY ; ; LIST IS EMPTY - THIS MUST BE FIRST ; MOV DESTHEADER,BX JMP SHORT NODEROUTELOOP NOTEMPTY: MOV LASTPOINTER,OFFSET DESTHEADER SCANLOOP: PUSH SI LEA SI,DEST_ALIAS[SI] LEA DI,DEST_ALIAS[BX] MOV CX,6 REP CMPSB POP SI JB CARRYON ; ; ADD IT HERE ; MOV SI,LASTPOINTER MOV AX,DEST_CHAIN[SI] ; NEXT MOV DEST_CHAIN[SI],BX MOV DEST_CHAIN[BX],AX JMP SHORT NODEROUTELOOP CARRYON: CMP DEST_CHAIN[SI],0 JE SCANEND MOV LASTPOINTER,SI MOV SI,DEST_CHAIN[SI] JMP SCANLOOP SCANEND: MOV DEST_CHAIN[SI],BX MOV DEST_CHAIN[BX],0 ; END NODEROUTELOOP: ; MOV SI,INITPTR ; ; GET NEIGHBOURS FOR THIS DESTINATION ; CALL FAR PTR CONVTOAX25F JNZ BADROUTE ; CALL GETVALUEF MOV SAVEPORT,AL ; SET PORT FOR FINDNEIGHBOUR CALL GETVALUEF MOV ROUTEQUAL,AL ; MOV INITPTR,SI ; SAVE AGAIN PUSH OBSINIT ; SAVE CMP BYTE PTR [SI],'!' JNE NOTLOCKEDNODE ADD INITPTR,2 MOV OBSINIT,255 ; SPECIAL FOR LOCKED NOTLOCKEDNODE: MOV SI,OFFSET AX25CALL PUSH BX ; SAVE DEST CALL FINDNEIGHBOURF MOV AX,BX ; ROUTE TO AX POP BX JZ NOTBADROUTE ADD SP,2 JMP BADROUTE NOTBADROUTE: ; ; UPDATE ROUTE LIST FOR THIS DEST ; CALL PROCROUTESF ; POP OBSINIT JMP NODEROUTELOOP BADROUTE: NOROOMFORNODE: JMP INITRETURN ; FINISHED PUBLIC GETRECORD ; ; READ A RECORD FROM INPUT FILE ; GETRECORD: PUSH CS POP DS MOV AX,DATA MOV ES,AX ASSUME DS:INITSEG,ES:DATA MOV DI,OFFSET UNPROTOCALL PUSH DI MOV CX,40 MOV AX,2020H REP STOSW MOV CX,79 ; MAX SIZE POP DI GETRECORDLOOP: CALL GETDISK CMP AL,0AH JE ENDRECORD ; CMP AL,1AH JNE NOTENDOFFILE STOSB RET NOTENDOFFILE: CMP AL,0DH JE GETRECORDLOOP ; STOSB LOOP GETRECORDLOOP ; ENDRECORD: RET ; ; GETDISK: ; GET A BYTE FROM DISK BUFFER CMP READCOUNT,128 JE READIT ; GET NEW BLOCK ; MOV SI,READPOINTER ; GET NEXT CHAR POINTER READNEXT: LODSB MOV READPOINTER,SI INC READCOUNT ; CHARS USED (AND SETS NONZERO FLAG) ; RET ; WITH ZERO FLAG NOT SET ; READIT: MOV READCOUNT,0 ; MOV DX,OFFSET CONFIGTABLE MOV READPOINTER,DX MOV AH,3FH MOV BX,CONFIGHANDLE MOV CX,128 INT 21H ; READ CMP CX,AX JE READOK MOV SI,OFFSET CONFIGTABLE ADD SI,AX MOV BYTE PTR [SI],1AH ; ENSURE EOF DETECTED READOK: MOV SI,OFFSET CONFIGTABLE JMP READNEXT PUBLIC READCONFIG, READCONFIGRECORD, POSITIONCONFIG READCONFIG: PUSH DS PUSH BX PUSH CS POP DS CALL POSITIONCONFIG MOV CX,512 CALL READCONFIGRECORD POP BX POP DS RET POSITIONCONFIG: MOV CX,0 MOV DX,AX MOV BX,CONFIGHANDLE MOV AX,4200H INT 21H ; POSITION ABSOLUTE RET READCONFIGRECORD: PUSH BX MOV BX,CONFIGHANDLE MOV AH,3FH MOV DX,OFFSET CONFIGTABLE INT 21H ; READ POP BX RET INSTALLTIMER: PUSH DS PUSH ES MOV AX,0 MOV DS,AX MOV AX,CODE MOV ES,AX ASSUME DS:NOTHING,ES:CODE ; MOV SI,20H ; ADDR OF H/W TIMER INTERRUPT (INT 8) ; MOV AX,[SI] ; SYSTEM TIMER ROUTINE OFFSET MOV WORD PTR ES:HWTIMERLINK,AX MOV AX,2[SI] MOV WORD PTR ES:HWTIMERLINK+2,AX ; MOV AX,ES MOV [SI+2],AX MOV AX,OFFSET HWTIMERINT MOV [SI],AX ; POP ES POP DS RET ; Q_ADD_INIT: IF DEBUG MOV [BX],DI ; INTO BUFFER LIST ADD BX,2 INC BUFFERCOUNT ENDIF Q_ADDI05: CMP WORD PTR [SI],0 ; END OF CHAIN JE Q_ADDI10 MOV SI,[SI] ; NEXT IN CHAIN JMP Q_ADDI05 Q_ADDI10: MOV WORD PTR [DI],0 ; CLEAR CHAIN ON NEW BUFFER MOV [SI],DI ; CHAIN ON NEW BUFFER INC QCOUNT RET D10 DW 10 D50 DW 1000/18 D300 DW 1000/3 CONVTIME: ; ; CONVERT AX (MS INTERVALS) TO CLOCK TICKS IF HDLC OR 10MS IF KISS ; MOV DX,0 CMP ES:PORTTYPE[BX],0 ; ASYNC JE CONVKISS CMP ES:PORTTYPE[BX],8 ; QUAD JE CONVKISS DIV D50 ; APPROX 50 MS - 18.2 HZ INC AL ; ROUND UP RET CONVKISS: DIV D10 RET CONV3SECS: ; ; CONVERT AX (MS) TO L2 TICKS (APPROX 3 PER SEC) ; MOV DX,0 DIV CS:D300 ; APPROX 50 MS - 18.2 HZ OR AL,AL JNZ CONV3X INC AL ; ENSURE NZ CONV3X: RET LINKINIT: ; ; CANT THINK OF ANYTHING FOR NOW ; RET EXTINIT: ; ; FOR RESIDENT DRIVER - MAY BE A GOOD PLACE TO GET ROUTINE ADDR ; FROM VECTOR NUMBER, AND MAKE SURE IT IS INSTALLED ; MOV AL,INTLEVEL[BX] MOV AH,0 ADD AX,AX ADD AX,AX MOV SI,AX MOV AX,0 MOV DS,AX CMP WORD PTR [SI],0 JNE EXTOK ; ; NO ROUTINE ; MOV AX,CODE MOV DS,AX MOV SI,OFFSET RETADDR EXTOK: LEA DI,PORT_EXT_ADDR[BX] MOVSW MOVSW ; COPY ADDR TO CONTROL TABLE LDS SI,ES:PORT_EXT_ADDR[BX] CMP BYTE PTR [SI],0CFH ; IRET JNE EXTOK2 PUSH CS POP DS MOV DX,OFFSET BADEXTMSG MOV AH,9 INT 21H EXTOK2: MOV AX,DATA MOV DS,AX ; ; ALSO CALL THE ROUTINE TO START IT UP, ESPECIALLY IF A L2 ROUTINE ; PUSHF MOV AH,0 ; INIT MOV AL,CHANNELNUM[BX] CALL PORT_EXT_ADDR[BX] RET ; CW LOOKUP TABLE - TWO BITS PER ELEMENT ; ; 00 = END ; 01 = DIT ; 11 = DASH ; ; ; BASED ON DESIGN BY MIKE TUBBY, G8TIC, 1985 ; CWTABLE DW 1101011101B ; / -..-. DW 1111111111B ; 0 ----- DW 1111111101B ; 1 .---- DW 1111110101B ; 2 ..--- DW 1111010101B ; 3 ...-- DW 1101010101B ; 4 ....- DW 0101010101B ; 5 ..... DW 0101010111B ; 6 -.... DW 0101011111B ; 7 --... DW 0101111111B ; 8 ---.. DW 0111111111B ; 9 ----. DW 7 DUP (0) ; ASCII 3A-40 DW 0000001101B ; A .- DW 0001010111B ; B -... DW 0001110111B ; C -.-. DW 0000010111B ; D -.. DW 0000000001B ; E . DW 0001110101B ; F ..-. DW 0000011111B ; G --. DW 0001010101B ; H .... DW 0000000101B ; I .. DW 0011111101B ; J .--- DW 0000110111B ; K -.- DW 0001011101B ; L .-.. DW 0000001111B ; M -- DW 0000000111B ; N -. DW 0000111111B ; O --- DW 0001111101B ; P .--. DW 0011011111B ; Q --.- DW 0000011101B ; R .-. DW 0000010101B ; S ... DW 0000000011B ; T - DW 0000110101B ; U ..- DW 0011010101B ; V ...- DW 0000111101B ; W .-- DW 0011010111B ; X -..- DW 0011110111B ; Y -.-- DW 0001011111B ; Z --.. INITSEG ENDS CODE SEGMENT PUBLIC 'CODE' ASSUME CS:CODE,DS:DATA,ES:DATA,SS:DATA ; PUBLIC Q_REM,Q_ADD,Q_ADDF,RELBUFF,CONVFROMAX25,CONVTOAX25 PUBLIC GETPORTTABLEENTRY,GETBUFF,TRACEFRAME PUBLIC GETPORTQUALITY,DATASEG,NOBUFFERCHECK PUBLIC SYSTEM,REFRESH,BWFLAG EXTRN L2TIMERPROC:NEAR,L2ROUTINE:NEAR,SDETX:NEAR EXTRN PROCESSIFRAME:NEAR,PROCESSNODEMESSAGE:NEAR EXTRN L4BG:NEAR EXTRN L4TIMERPROC:NEAR EXTRN CLEARSESSIONENTRY:NEAR,L3FASTTIMER:NEAR EXTRN L3TIMERPROC:NEAR,L3BG:NEAR EXTRN TNCTIMERPROC:NEAR,FINDDESTINATION:NEAR EXTRN STATSTIMER:NEAR,HDLCEND:NEAR EXTRN KISSTX:NEAR,HDLCTX:NEAR EXTRN KISSRX:NEAR,HDLCRX:NEAR EXTRN KISSTIMER:NEAR,HDLCTIMER:NEAR EXTRN TERMINAL:NEAR,TERMTRACE:NEAR,TERMINIT:NEAR EXTRN IPGATEBG:NEAR,IPGATEINIT:NEAR PUBLIC STOPNODE DUMMYCODE: RET ; DUMMY FOR MISSING ROUTINES DB 'BPQ' ; FOR DUMP SYSTEM DATASEG DW DATA ; FOR DUMP SYSTEM DW QCOUNT ; ADDR OF QCOUNT FOR DUMP SYSTEM STACKINUSE DB 0 ; SO DUMPNODES CAN FIND IT HWTIMERLINK DD 0 ; LINK TO OLD H/W TIMER ROUTINE SYSTEM DB 0 ; SUBSYSTEM OWNING DISPLAY - TERM OR IPGATE REFRESH DB 0 BWFLAG DB 0 MAINCODE: MOV AX,DATA MOV ES,AX MOV DS,AX MOV SI,OFFSET MYCALL CALL IPGATEINIT MOV AX,DATA MOV ES,AX MOV DS,AX CALL TERMINIT MOV AX,DATA MOV ES,AX MOV DS,AX MAINLOOP: MOV AX,1000H INT 15H ; FOR DESQVIEW STI ; FOR IBM XT BIOS BUG CALL BACKGROUND CALL TERMINAL CALL IPGATEBG MOV AX,DATA MOV ES,AX MOV DS,AX JMP MAINLOOP BACKGROUND: ; ; CONVERT TICKS TO MM SS ; MOV AX,40H MOV ES,AX MOV AX,ES:6CH MOV DX,0 DIV WORD PTR D1093 ; MINS TO AL MOV MM,AL MOV AX,DX ; TICKS DIV B19 ; SECS MOV SSECS,AL MOV AL,ES:6EH ; HOURS TO AH MOV HH,AL PUSH DS POP ES INC RAN1 INC RANDOM ; ; CHECK FOR TIMER ACTIVITY ; CMP PORTTIMERFLAG,0 ; 18HZ JE NOTPORTTIMER DEC PORTTIMERFLAG ; ; CALL PORT TIMER ROUTINES ; INC RAN2 MOV BX,PORTTABLE MOV CX,NUMBEROFPORTS TIMERINT00: PUSH BX PUSH CX CALL PORTTIMERCODE[BX] POP CX POP BX MOV BX,PORTPOINTER[BX] LOOP TIMERINT00 ; NOTPORTTIMER: ; CMP L2TIMERFLAG,6 ; 3 PER SEC JB NOTL2TIMER SUB L2TIMERFLAG,6 CALL L2TIMERPROC NOTL2TIMER: CMP L3TIMERFLAG,18*60 ; 1 PER MIN JB NOTL3TIMER SUB L3TIMERFLAG,18*60 CALL L3TIMERPROC CALL STATSTIMER NOTL3TIMER: CMP L4TIMERFLAG,18 ; 1 PER SEC JB NOTL4TIMER SUB L4TIMERFLAG,18 CALL L3FASTTIMER CALL L4TIMERPROC NOTL4TIMER: CMP TNCTIMERFLAG,6 ; 3 PER SEC JB NOTTNCTIMER SUB TNCTIMERFLAG,6 CALL TNCTIMERPROC NOTTNCTIMER: ; ; SEE IF ANY FRAMES TO TRACE ; MOV SI,OFFSET TRACE_Q CLI CALL Q_REM STI JZ NOTRACERET ; ; IF BUFFER HAS A LINK TABLE ENTRY ON END, RESET TIMEOUT ; MOV BX,BUFFLEN-2[DI] OR BX,BX JZ NOTIMER CMP L2TIMER[BX],0 JE NOTIMER ; ALREADY EXPIRED MOV AL,L2TIME[BX] XOR AH,AH MOV L2TIMER[BX],AX MOV WORD PTR BUFFLEN-2[DI],0 ; CLEAR FLAG FROM BUFFER NOTIMER: OR MSGPORT[DI],80H PUSH DI CALL BPQTRACE POP DI CALL RELBUFF NOTRACERET: ; ; CHECK FOR MESSAGES RECEIVED FROM COMMS LINKS ; MOV BX,PORTTABLE MOV CX,NUMBEROFPORTS MAINL00: MOV AL,PORTNUMBER[BX] MOV CURRENTPORT,AL ; PORT NUMBER MOV CURRENTPORTPTR,BX LEA SI,PORTRX_Q[BX] CLI CALL Q_REM ; SEE IF ANYTHING THERE STI JZ MAINL10 ; INC RAN3 ; ; TIME STAMP IT ; IFDEF PCSWITCH PUSH DS MOV AX,40H MOV DS,AX MOV AX,DS:6CH POP DS MOV BUFFLEN-4[DI],AX ENDIF PUSH BX PUSH CX MOV AL,CURRENTPORT MOV MSGPORT[DI],AL ; PUT PORT INTO MSG BUFFER ; CALL L2ROUTINE ; LEVEL 2 PROCESS POP CX POP BX MAINL00_J: JMP MAINL00 ; DO ANY MORE MAINL10: CMP PORTTX_Q[BX],0 JE MAINL15 ; NO FRAMES ; ; SEE IF PORT IS BUSY ; CMP PORTTYPE[BX],10H ; EXTERNAL? JNE MAINL12 ; NO PUSH CX PUSH BX CALL EXTTEST POP BX POP CX JNZ MAINL15 ; BUSY MAINL12: LEA SI,PORTTX_Q[BX] CLI CALL Q_REM ; SEE IF ANYTHING THERE STI JZ MAINL15 ; ; MESSAGE TO SEND - SEND IT ; INC RAN4 CMP PORTDISABLED[BX],0 JE PORTACTIVE ; ; PORT HAS BEEN DISABLED ; CALL RELBUFF JMP SHORT MAINL10 ; SEE IF ANY MORE PORTACTIVE: ; PUSH BX PUSH CX ADD L2FRAMESSENT[BX],1 ADC L2FRAMESSENT+2[BX],0 CALL PORTTXROUTINE[BX] ; LEVEL 2 PROCESS POP CX POP BX JMP MAINL10 ; SEE IF MORE MAINL15: PUSH BX PUSH CX CALL PORTRXROUTINE[BX] ; SEE IF MESSAGE RECEIVED POP CX POP BX MOV BX,PORTPOINTER[BX] LOOP MAINL00_J ; ; CHECK FOR INCOMING MESSAGES ON LINK CONTROL TABLE - ; BY NOW ONLY 'I' FRAMES WILL BE PRESENT - ; LEVEL 2 PROTOCOL HANDLING IS DONE IN MESSAGE RECEIVE CODE ; AND LINK HANDLING INTERRUPT ROUTINES ; MOV BX,LINKS MOV CX,MAXLINKS MAINL20: LEA SI,RX_Q[BX] CLI CALL Q_REM ; SEE IF ANYTHING THERE STI JZ MAINL30 ; INC RAN5 PUSH CX PUSH BX CALL PROCESSIFRAME POP BX POP CX MAINL30: ; ; CHECK FOR OUTGOING MSGS ; CMP L2STATE[BX],5 JB MAINL40 ; CANT SEND TEXT TILL CONNECTED ; CMP VER1FLAG[BX],1 ; JE MAINL35 ; NEED TO RETRY WITH I FRAMES IF VER 1 ; CMP L2RETRIES[BX],0 ; JNE MAINL40 ; CANT SEND TEXT IF RETRYING MAINL35: TEST L2FLAGS[BX],RNRSET JNZ MAINL40 ; CANT SEND TEXT IF RNR PUSH BX PUSH CX CALL SDETX POP CX POP BX MAINL40: ADD BX,TYPE LINKTABLE LOOP MAINL20 ; CALL L4BG ; DO LEVEL 4 PROCESSING CALL L3BG RET TRACEFRAME: PUSH BX CALL BPQTRACE POP BX RET BPQTRACE: ; MOV AX,BUFFLEN-4[DI] ; TIMESTAMP CALL TERMTRACE MOV AX,DATA MOV ES,AX MOV DS,AX RET RELBUFF: MOV SI,OFFSET FREE_Q CLI CALL Q_ADDF ; RETURN BUFFER TO FREE QUEUE STI RET FINDLINK: ; ; FIND LINK FOR AN INCOMING MESSAGE ; ; MESSAGE ADDR IN DI MOV BX,0 MOV SI,LINKS MOV CX,MAXLINKS FINDLK00: CMP BYTE PTR [SI],0 JNE FINDLK05 ; NOT A SPARE ENTRY CMP BX,0 JNE FINDLK10 ; ALREADY FOUND A SPARE MOV BX,SI ; POINTER TO FIRST FREE JMP SHORT FINDLK10 ; TRY NEXT ENTRY FINDLK05: PUSH SI PUSH DI PUSH CX LEA DI,MSGORIGIN[DI] ; ORIGIN FROM MESSAGE CALL COMPARECALLS ; COMPARE WITH LINKCALL POP CX POP DI POP SI JNE FINDLK10 PUSH SI PUSH DI PUSH CX LEA DI,MSGDEST[DI] ADD SI,7 ; OURCALL IN TABLE CALL COMPARECALLS ; COMPARE WITH DESTINATON IN MSG POP CX POP DI POP SI JE FINDLKRET ; YES FINDLK10: ADD SI,TYPE LINKTABLE LOOP FINDLK00 ; ; ENTRY NOT FOUND - BX HAS FIRST FREE ENTRY, OR ZERO IF TABLE FULL ; OR AL,1 RET FINDLKRET: MOV BX,SI XOR AL,AL RET COMPARECALLS: ; ; COMPARE AX25 CALLSIGNS IN SI, DI IGNORING EXTRA BITS IN SSID ; MOV CX,6 REP CMPSB ; COMPARE WITH LINKCALL JNE COMPCALLRET ; DONT MATCH LODSB MOV AH,[DI] AND AX,0001111000011110B ; MASK NON-SSID BITS CMP AL,AH COMPCALLRET: RET GETPORTQUALITY: PUSH BX CALL GETPORTTABLEENTRY MOV AL,PORTQUALITY[BX] POP BX RET GETPORTTABLEENTRY: PUSH CX MOV BX,PORTTABLE MOV CX,NUMBEROFPORTS GETPORT10: CMP AL,PORTNUMBER[BX] JE GETPORT20 MOV BX,PORTPOINTER[BX] LOOP GETPORT10 MOV BX,PORTTABLE ; TO FIRST IF NOT DEFINED GETPORT20: POP CX RET CONVTOAX25F: CALL CONVTOAX25 RETF 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 Q_REM: MOV DI,[SI] ; GET ADDR OF FIRST BUFFER CMP DI,0 JE Q_RET ; EMPTY MOV AX,[DI] ; CHAIN FROM BUFFER MOV [SI],AX ; STORE IN HEADER POP [DI] ; CALLERS ADDR PUSH [DI] Q_RET: RET ; Q_ADD: CMP DI,0 JNE BUFOK POP DS:8 ; RETURN ADDR PUSH DS:8 RET BUFOK: IF DEBUG CALL CHECKBUFFER ENDIF PUSHF ; SAVE INT STATE CLI Q_ADD05: CMP WORD PTR [SI],0 ; END OF CHAIN JE Q_ADD10 MOV SI,[SI] ; NEXT IN CHAIN JMP Q_ADD05 Q_ADD10: MOV WORD PTR [DI],0 ; CLEAR CHAIN ON NEW BUFFER MOV [SI],DI ; CHAIN ON NEW BUFFER POPFF ; RECOVER INT STATE RET ; ; ADD TO FRONT OF QUEUE - MUST ONLY BE USED FOR FREE QUEUE ; Q_ADDF: CMP DI,0 JNE BUFOK1 POP DS:10 ; RETURN ADDR FOR DEBUGGING PUSH DS:10 RET BUFOK1: IF DEBUG CALL CHECKBUFFER ENDIF MOV AX,[SI] ; OLD FIRST IN CHAIN MOV [DI],AX MOV [SI],DI ; PUT NEW ON FRONT INC QCOUNT RET GETBUFF_FAR: CALL GETBUFF RETF GETBUFF: MOV SI,OFFSET FREE_Q CLI CALL Q_REM STI ; JZ NOBUFFS DEC QCOUNT MOV AL,QCOUNT CMP AL,MINBUFFCOUNT JA GETBUFFRET MOV MINBUFFCOUNT,AL GETBUFFRET: OR AL,1 ; SET NZ ; ; FLAG BUFFER WITH ADDR OF CALLING ROUTINE (TRYING TO TRACK DOWN LOST BUFFERS!) ; POP [DI] PUSH [DI] RET NOBUFFS: NOBUFFERCHECK: INC NOBUFFCOUNT XOR AL,AL RET ; CHECKBUFFER: ; IF DEBUG EXTRN INVOKEDUMP:NEAR ; ; ; ENSURE BUFFER IN DI IS VALID - IF NOT, INVOKE DIAGNOSTIC DUMP ; PUSH CX PUSH DI MOV AX,DI MOV DI,OFFSET BUFFERLIST MOV CX,BUFFERCOUNT REPNE SCASW JCXZ DUFFBUFFER POP DI POP CX RET DUFFBUFFER: POP DI POP CX PUSH SI MOV SI,OFFSET DUFFADDRMSG MOV DX,0920H JMP INVOKEDUMP DUFFADDRMSG DB 'DUFF BUFFER ADDRESS DETECTED$' ELSE RET ENDIF SAVESTACKSEG DW 0 SAVESTACKPTR DW 0 TIMERUNHOOKED DB 0 PUBLIC TIMERUNHOOKED HWTIMERINT: ; ; ENTERED FROM 8253 TIMER 0 INTERRUPT (LEVEL 0 - INT 8) ; ; CALL SYSTEM TIMER CODE, AND INCREMENT VARIOUS TIMER FLAGS ; INT2: ; ENTERED FROM HARDWARE INTERRUPT ; ; save stack ; PUSHF ; RETURN IS VIA IRET CALL HWTIMERLINK ; ; BY NOW INT CONTROLLER HAS BEEN RESET, SO OTHER INTERRUPTS MAY OCCUR - ; INTS ARE DISABLED ; PUSH DS PUSH AX MOV AX,CS:DATASEG MOV DS,AX ; TO OUR DATA SEGMENT ; INC REALTIMETICKS INC L2TIMERFLAG ; INCREMENT FLAG FOR BG INC L3TIMERFLAG ; INCREMENT FLAG FOR BG INC L4TIMERFLAG ; INCREMENT FLAG FOR BG INC PORTTIMERFLAG ; PORT TIMER NEEDED CALL CLEARINTS ; SWEEP FOR LOST INTERRUPTS POP AX POP DS ; IRET ; LOOPBACK PORT ROUTINES ; LINKTX: ; ; LOOP BACK TO SWITCH ; PUSH BX ; ; RESET TIMER ; MOV BX,BUFFLEN-2[DI] OR BX,BX JZ LNOTIMER CMP L2TIMER[BX],0 JE LNOTIMER ; ALREADY EXPIRED MOV AL,L2TIME[BX] XOR AH,AH MOV L2TIMER[BX],AX MOV WORD PTR BUFFLEN-2[DI],0 ; CLEAR FLAG FROM BUFFER LNOTIMER: POP BX LEA SI,PORTRX_Q[BX] CALL Q_ADD RET LINKRX: ; ; PACKETS ARE TRANSFERED DIRECT FROM TX ROUTINE TO RX QUEUES, SO ; THIS ROUTINE IS NOT NEEDED ; LINKTIMER: ; ; ANOTHER DUMMY ; RET ; ; ; EXTERNAL DRIVER INTERFACE ROUTRINES ; ; THE SWITCH CAN INTERFACE TO A PRE-LOADED TSR DRIVER ROUTINE. ; ; THE DRIVER MAY BE EITHER A LEVEL 1 ROUTINE - EFFECTIVELY ; A KISS MODE INTERFACE, OR MAY PROVIDE THE LEVEL 2 FEATURES, ; WITH THE SWITCH HANDLING L3 AND ABOVE. THE LATTER MODE IS MORE ; APPROPRIATE FOR INTELLIGENT INTERFACE CARDS, SUCH AS THE VNA ; ; ; THE ROUTINE IS CALLED VIA A SIMULATED INT, SO SHOULD RETURN ; WITH AN IRET. THE DRIVER MAY SUPPORT MULTIPLE LOGICAL CHANNELS - ; THE CHANNEL NUMBER IS PASSED IN AL ; ; THE ROUTINE MUST PROVIDE THE FOLLOWING FUNCTIONS: ; ; ; AH=0 INITIALISE. CALLED ONCE ON LOAD ; ; AH=1 RETURNS POINTER TO RECEIVED FRAME IN DS:SI, LENGTH IN CX ; RETURNS CX IF NO FRAME READY ; ; AH=2 SEND FRAME IN BUFFER IN DS:DI - LENGTH IS IN WORD AT 3[DI] ; DATA FOLLOWS LENGTH ; AH=3 STATUS. RETURNS AX=0 IF TX NOT BUSY. CX=0 IF RX NOT READY ; ; ; DUMMY ROUTINE IN CASE INT ROUTINE NOT LOADED RETADDR DD RETINS RETINS: IRET EXTTX: ; ; PROBABLY USED ONLY FOR L1 INTERFACE - WILL SORT OUT L2 LATER ; PUSH BX ; ; RESET TIMER ; MOV BX,BUFFLEN-2[DI] OR BX,BX JZ XNOTIMER ; CMP L2TIMER[BX],0 JE XNOTIMER ; ALREADY EXPIRED ; MOV AL,L2TIME[BX] XOR AH,AH MOV L2TIMER[BX],AX ; MOV WORD PTR BUFFLEN-2[DI],0 ; CLEAR FLAG FROM BUFFER ; XNOTIMER: ; POP BX MOV AH,2 ; SEND FRAME MOV AL,CHANNELNUM[BX] ; PUSH DI PUSHF ; SIMULATE INT NN CALL PORT_EXT_ADDR[BX] POP DI MOV SI,OFFSET TRACE_Q CALL Q_ADD RET EXTRX: ; ; POLL FOR PACKETS FROM INTERFACE ; ; RETURNS PACKET LENGTH IN CX (ZERO IF NONE) ; ; DATA POINTER IN DS:SI ; CMP QCOUNT,10 JB EXTEXIT ; DONT POLL ; MOV AH,1 ; GET FRAME MOV AL,CHANNELNUM[BX] MOV CX,0 PUSHF CALL PORT_EXT_ADDR[BX] ; CMP CX,0 JE EXTEXIT ; ; HAVE A MESSAGE ; MOV DX,DS ; SAVE MOV DS,CS:DATASEG PUSH SI CALL GETBUFF POP SI JZ EXTEXIT ; SHOULDNT HAPPEN MOV DS,DX PUSH DI REP MOVSB POP DI MOV DS,CS:DATASEG LEA SI,PORTRX_Q[BX] CALL Q_ADD EXTEXIT: RET ; EXTTIMER: ; ; PROBABLY NOT NEEDED ; RET ; EXTTEST: MOV AH,3 ; GET STATUS MOV AL,CHANNELNUM[BX] MOV CX,0 PUSHF CALL PORT_EXT_ADDR[BX] ; OR AX,AX ; RETURN ZERO IF OK TO SEND RET STOPNODE: MOV AX,DATA MOV ES,AX MOV DS,AX CLI ; RESTORE INTERRUPT MASKS MOV AL,SAVEPIC0 OUT (21H),AL MOV AL,SAVEPIC1 OUT (0A1H),AL ; ; UNHOOK TIMER ; MOV AX,0 MOV DS,AX MOV SI,20H ; ADDR OF H/W TIMER INTERRUPT (INT 8) ; MOV AX,WORD PTR CS:HWTIMERLINK MOV [SI],AX ; SYSTEM TIMER ROUTINE OFFSET MOV AX,WORD PTR CS:HWTIMERLINK+2 MOV 2[SI],AX ; SYSTEM TIMER ROUTINE OFFSET STI MOV AX,4C00H INT 21H ; EXIT PUBLIC HEXOUT HEXOUT: RET CODE ENDS END START