IMD 1.17: 11/11/2014 12:16:05 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 30 OF 30  SR30q82VKXSVRDOS 0420¦i-‰TTL‡BUFFER�MGT�SUBROUTINES�(Copyright�1982�by�Motorola,�Inc.)‰NOLIST‰INCLUDEƒ9995.&.CRASH.MC‰INCLUDEƒ9995.NTS.NAT.EQ‰INCLUDEƒ9995.&.STR.EQ ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰LIST ‰SECTIONƒ94‰XREF.S„NATBEG,SYSPOFF,MEMOFF,FREEQHD,FREEQND,MEMOFF5‰XREF.S„FQLWM,FQBCNT,USERQHD,USERQND,SDLCPCB,SDLCQUSB‰XREF†SDLCQXMT   H*************************************************************************Æ**Æ**šBUFFER�MANAGEMENT›**Æ**Æ* *•NETWORK�SERVICES�/�SDLC�ONLY•**Æ**Æ**˜SHARED�RAM/BUFFER�POOL˜**Æ**Æ*H************************************************************************   H*************************************************************************Æ*E*�WARNING:�"PTXMQ"�CONTAINS�AN�IMPLEMENTATION�RESTRICTION�WHICH�HAS„*F*�NOT�BEEN�RESOLVED�YET.‚"PTXMQ"�ASSUMES�THAT�IF�MEMOFF�IS�ZERO�THEN‚*C*�THE�SDLC�DRIVER�IS�PRESENT�IN�THE�SAME�MPU.‚IN�EXISTING�USES�OF…*D*�THIS�MODULE,�THAT�IS�TRUE.‚HOWEVER�IT�MAY�NOT�ALWAYS�BE�TRUE.‚ATƒ*D*�SOME�FUTURE�TIME,�"PTXMQ"�SHOULD�BE�CHANGED�TO�DETERMINE�IF�SDLC…*E*�EXISTS�IN�THE�SAME�MPU�IN�A�MORE�DIRECT�FASHION,�AND�THEREBY�LIFT„*E*�THIS�RESTRICTION.‚A�WARNING�IS�GENERATED�WITHIN�"PTXMQ"�TO�ACT�ASƒ*#*�A�REMINDER�OF�THIS�RESTRICTION.¦**Æ*H************************************************************************ ‰PAGE H*************************************************************************Æ*E*ƒTHIS�MODULE�IS�USED�IN�ALL�PROCESSORS�WHICH�ACCESS�THE�SHARED�RAM‚*D*�AREA�CONTAINING�THE�SHARED�BUFFERS.‚TWO�SYSGEN�DEFINED�CONSTANTS„*D*�WHICH�ARE�UNIQUE�TO�THE�PROCESSOR�USING�THIS�CODE�ARE�IMPORTANT.…*A*„"SYSPOFF"�IS�A�LONG�WORD�CONTAINING�THE�OFFSET�THIS�PROCESSOR…*9*‡MUST�USE�IN�ACCESSING�THE�FREE�POOL�CONTROL�AREA,�ANDŠ*E*„"MEMOFF"�IS�A�LONG�WORD�CONTAINING�THE�OFFSET�THIS�PROCESSOR�MUST�*(*‡USE�IN�ACCESSING�INDIVIDUAL�BUFFERS.›**Æ**„-„-„-„-„-„-„-„-„-„-„-„-„-…**Æ*A*„<-------�MPU�A's�View�------->�<-------�MPU�B's�View�------->…**Æ* <(*0&8?@0H9P/X6`4h<p*x0€1ˆ7�  *’+-------------+¥*1*„$00000000�-->�!�!ƒ(MPU�B�Cannot�"see"�MPU�A's‡*)*’!ƒPrivateƒ!…private�RAM�area�at�all.)‡* *’!…RAM…!¥**„$00FBFFFF�-->�!�!¥**’+-------------+¥**š+-------------+�*5*„$00FC0000�---------->�!�!�<------------�$00000000…**š!ƒShared„!�* *š!…RAM…!�*5*„$00FFFFFF�---------->�!�!�<------------�$0003FFFF…**š+-------------+�**Æ*+*„SYSPOFF�=�$00FC0C00—SYSPOFF�=�$00000000…*)*„MEMOFF‚=�$00FC0000—MEMOFF‚=�$00000000…**Æ**„-„-„-„-„-„-„-„-„-„-„-„-„-…**Æ*D*„THIS�DIAGRAM�REPRESENTS�THE�EXORMACS/VM02�CONFIGURATION�USED�FOR‚*G*�NETWORK�SERVICES�QUITE�OFTEN.‚THE�VM02'S�ONBOARD�MEMORY�IS�"SHARED"�*G*�BETWEEN�THE�PROCESSORS.‚THE�VM02�"SEES"�THIS�AREA�BEGINNING�AT�ZERO,*8*�WHILE�THE�EXORMACS�"SEES"�IT�BEGINNING�AT�$00FC0000.‘*D*„MEMOFF�IS�THE�OFFSET�TO�THE�SHARED�RAM�AREA.‚IN�THE�VM02,�MEMOFF�*<*�WILL�BE�ZERO.‚IN�THE�EXORMACS,�MEMOFF�WILL�BE�$00FC0000.Œ*B*„SYSPOFF�IS�THE�OFFSET�TO�THE�SYSPAR�AREA.‚IN�THE�VM02,�SYSPOFFƒ*=*�WILL�BE�ZERO.‚IN�THE�EXORMACS,�SYSPOFF�WILL�BE�$00FC0C00.‹*B*„IN�BOTH�PROCESSORS�THEN,�THE�BUFFER�POOL�QUEUE�CONTROL�AREA�(A„*F*�VM02�SYSPAR�CONSTRUCT)�IS�ACCESSED�AT�"FREQHD+SYSPOFF".‚SIMILARLY,‚*E*�A�GIVEN�BUFFER�MAY�BE�ACCESSED�IN�EITHER�MPU�AS�"BUFADDR+MEMOFF",„*:*�AND�THE�USER�QUEUE�MAY�BE�FOUND�AT�"USERQUEUE+MEMOFF".�*E*„HOWEVER,�SINCE�BUFFERS�IN�THE�FREE�POOL�AND�USER�QUEUE�ARE�LINKED�*E*�AND�MANIPULATED�BY�EITHER�PROCESSOR,�WHO'S�"VIEW"�OF�ADDRESSES�IS„* *�USED?À*C*„BY�CONVENTION,�BUFFERS�IN�THESE�AREAS�ARE�LINKED�TOGETHER�USINGƒ*C*�NO�OFFSET�WHATSOEVER.‚ANY�PROCESSOR�ACCESSING�THEM�WILL�HAVE�TO…*G*�INCLUDE�ITS�OWN�MEMOFF�IN�ACCESSING�THE�BUFFERS,�OR�ITS�OWN�SYSPOFF‚*G*�IN�ACCESSING�THE�CONTROL�AREA.‚(BECAUSE�SYSPOFF�AND�MEMOFF�ARE�BOTH�*C*�ZERO�IN�THE�VM02,�IT�WOULD�APPEAR�THAT�THE�POOL�USES�THE�VM02'S†*D*�OFFSETS.‚THIS�WILL�NOT�BE�THE�CASE�HOWEVER�WHERE�BOTH�PROCESSORS„*B*�ARE,�FOR�EXAMPLE,�VM02'S.‚ONE�WILL�HAVE�ZERO�OFFSETS�WHILE�THE†* *�WILL�HAVE�NON-ZERO�OFFSETS.)©**Æ*H************************************************************************‰PAGEH*************************************************************************Æ*C*„THESE�ROUTINES�IMPLEMENT�A�BUFFER�MANAGEMENT�SYSTEM�UTILIZING�Aƒ*E*�QUEUE�OF�SHARED�"FREE�BUFFERS".‚THE�BUFFERS�EXIST�IN�A�SHARED�RAMƒ*E*�AREA�OF�MEMORY,�AND�A�"LOCK"�IS�USED�ON�THE�QUEUE�HEAD�POINTER�TO„*D*�INSURE�EXCLUSIVE�ACCESS�TO�THE�POOL�CONTROL�AREA�DURING�UPDATES.…*F*�THESE�ROUTINES�SHOULD�BE�USED�IN�***ALL***�PROCESSORS�WHICH�ACCESSƒ*F*�AND/OR�MANIPULATE�THE�QUEUE�CONTROL�AREA.‚A�"LOW�WATER�MARK"�LEVEL‚*H* IS DEFINED WHICH PREVENTS APPLICATIONS (OR FUNCTIONS ON THEIR BEHALF)*-*�FROM�COMPLETELY�DRAINING�THE�BUFFER�POOL.œ**Æ*A*„"SBGTFRIR"�(AND�"GTFRIR")�IGNORE�THE�LOW�WATER�MARK,�AND�WILL…*E*�SUPPLY�ONE�BUFFER�FROM�THE�POOL.‚AN�INDICATION�IS�RETURNED�IF�THEƒ*E*�POOL�HAS�JUST�BECOME�EMPTY.‚THIS�MODULE�SHOULD�NOT�BE�USED�BY,�ORƒ*F*�ON�BEHALF�OF�APPLICATIONS.‚IT�IS�INTENDED�FOR�LOW�LEVEL,�HIGH�PER-‚*G*�FORMANCE�ROUTINES�ONLY�WHICH�MAY�USE�THE�LAST�BUFFER�FROM�THE�POOL.‚**Æ*D*„"SBGTFRBF"�(AND�"GTFRBF")�RETURN�ONE�BUFFER�IF�THE�POOL�IS�ABOVE‚*H* THE LOW WATER MARK, OTHERWISE A "NOT AVAILABLE" INDICATION IS GIVEN. **Æ*E*„"SBGTFRML"�(AND�"GTFRML")�RETURN�MANY�BUFFERS�FROM�THE�POOL�UP�TO�*H* A REQUESTED NUMBER, OR UNTIL THE LOW WATER MARK IS REACHED, WHICHEVER*G*�OCCURS�FIRST.‚THE�RETURNED�BUFFERS�ARE�LINKED�TOGETHER�AND�THE�FIRST*F*�BUFFERS�ADDRESS,�THE�NUMBER�OF�BUFFERS�RETURNED,�AND�A�RETURN�CODEƒ*#*�OF�ALL,�SOME,�OR�NONE�IS�GIVEN.¦**Æ*B*„"SBPTFRBF"�(AND�"PTFRBF")�RETURN�A�SINGLE�BUFFER�BACK�INTO�THE„* *�POOL.À**Æ*A*„"SBPTFRML"�(AND�"PTFRML")�RETURN�"MANY"�BUFFERS�BACK�INTO�THE…* *�POOL.À**Æ*E*„"SBPTXMQ"�(AND�"PTXMQ")�PUT�A�SINGLE�BUFFER�ON�THE�TRANSMIT�QUEUE�*G*�OF�THE�APPROPRIATE�SECONDARY�STATION'S�CONTROL�BLOCK.‚IF�THE�PASSED�*D*�SECONDARY�STATION�NUMBER�IS�INVALID�(I.E.,�THE�SECONDARY�STATION…*F*�CONTROL�BLOCK�CANNOT�BE�FOUND),�AN�ERROR�INDICATION�IS�RETURNED�ASƒ* E*�WELL�AS�THE�BUFFER.‚IF�THE�STATION�NUMBER�IS�VALID,�THE�BUFFER�ISƒ*D*�ENQUEUED�TO�THE�APPROPRIATE�SECONDARY�STATION�CONTROL�BLOCK,�THE…*G*�SDLC�DRIVER�IS�NOTIFIED�OF�THE�TRAFFIC'S�ARRIVAL,�AND�A�GOOD�RETURN‚*4*�CODE�(AND�NO�BUFFER)�ARE�RETURNED�TO�THE�CALLER.•**Æ*D*„"SBPTUSQ"�(AND�"PTUSQ")�PUT�A�SINGLE�BUFFER�ON�THE�"USER�QUEUE".‚*F*�WHERE�THE�HOSTING�SYSTEM�CONTAINS�NETWORK�SERVICES,�IT�IS�NOTIFIEDƒ**�OF�THE�BUFFER'S�ARRIVAL.­**Æ*E*„"SBGTUSQ"�(AND�"GTUSQ")�GET�A�SINGLE�BUFFER�FROM�THE�"USER�QUEUE",*G*�RETURNING�AN�INDICATION�OF�WHETHER�OR�NOT�A�BUFFER�WAS�OBTAINED.‚IF�*H* NO BUFFER IS AVAILABLE, A "BAD" POINTER IS RETURNED FACILITATING THE **�FINDING�OF�BUGS.µ**Æ*H************************************************************************‰PAGEH*************************************************************************Æ*0*ˆSYMBOL�DEFINITIONS�USED�WITHIN�THESE�MODULES’**Æ*H************************************************************************ )* CONDITION CODE REGISTER BIT DEFINITIONS $N.SET„EQU‡%00001000�NEGATIVE�BIT�SET Z.SET„EQU‡%00000100�ZERO�BIT�SET$V.SET„EQU‡%00000010�OVERFLOW�BIT�SET!C.SET„EQU‡%00000001�CARRY�BIT�SET &N.CLR„EQU‡%00000000�NEGATIVE�BIT�CLEAR"Z.CLR„EQU‡%00000000�ZERO�BIT�CLEAR&V.CLR„EQU‡%00000000�OVERFLOW�BIT�CLEAR#C.CLR„EQU‡%00000000�CARRY�BIT�CLEAR   (* INTERRUPT LEVEL WITHIN STATUS REGISTER 'LEVEL7ƒEQU‡$0700…LEVEL�7�INTERRUPT�MASK   * LOCK BIT WITHIN AN ADDRESS *LOCKBIT‚EQU‡$80000000�MOST�SIGNIFICANT�BIT   )* AN ADDRESS VALUE WHICH HELPS CATCH BUGS AFLYPAPER�EQU‡$FFFFFFFF�(IT'S�AN�ODD�NUMBER,�MOVE.W/.L�WILL�FAIL!) ‰PAGEH*************************************************************************Æ*=*ˆSUBROUTINE:‚"SBGTFRIR"‚GET�ONE�BUFFER�FROM�THE�FREE�QUEUEƒ**ˆTRAP:ˆ"GTFRIR"©**ˆENTER:�NO�ARGUMENTS.ª*(*ˆRETURN:‚A3.L�=�POINTER�TO�THE�BUFFER™**’CCR±*/*‘Z�set‚BUFFER�WAS�SUPPLIED�(NOT�LAST�BUFFER)‰*"*‘N�set‚LAST�BUFFER�WAS�SUPPLIED–**‘neither‚NO�BUFFER�AVAILABLE™*:*ˆNOTE:‚THIS�ROUTINE�IS�TO�BE�USED�ONLY�BY�THE�DLC�LEVEL‡*/*�BECAUSE�IT�WILL�SUPPLY�THE�VERY�LAST�BUFFERŒ*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D­* *˜A‡R‡S�** |‡|_�stack–** |_________�returned“**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†GTFRIR,SBGTFRIR9GTFRIRƒBSR.S…SBGTFRIR‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE /SBGTFRIR�MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT‰MOVE.L„A1,-(A7)A‰MOVE.B„#Z.SET+N.CLR,5(A7)�ASSUME�"BUFFER�WAS�SUPPLIED,�NOT�LAST";‰MOVE.L„SYSPOFF,A1�GET�THE�LOCAL�OFFSET�TO�THE�CONTROL�AREA H* THE FOLLOWING TST OF MEMOFF AND BNE INSTRUCTIONS ARE FOR TEMPORARY USEH*�ONLY.‚I�WANT�TO�SEE�IF�ANYONE�IS�USING�THIS�SUBROUTINE�IN�THE�EXORMACSA*�MPU�-�WHICH�SHOULD�NOT�BE�HAPPENING.†ED�SKINNER,�MARCH�9,�1983. ‰TST.L…MEMOFF6‰CRASH.NE‚*-1‡DIE�IF�NOT�RUNNING�IN�THE�VM02�WITH�SDLC 7* OBTAIN EXCLUSIVE ACCESS TO THE FREE POOL CONTROL AREA6GTFRIRLK�MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL!‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS(‰TAS‡FREEQHD(A1)�ATTEMPT�TO�SET�THE�LOCK3‰BMI.S…GTFRIRLK‚LOOP�IF�FAILED�(ANOTHER�MPU�HAS�IT),‰CRASH.NE‚*-1‡CRASH�IF�LOCK�BYTE�IS�CORRUPT! .* FREEQHD IS LOCKED AND INTERRUPTS ARE MASKED!/‰SUB.W…#1,FQBCNT(A1)�DECREMENT�COUNT�OF�BUFFERS;‰BGT.S…GTFRIR1ƒOUT�IF�AT�LEAST�ONE�REMAINS�AFTER�WE�GET�ONE)‰BMI.S…GTFRIR0ƒOUT�IF�NOT�EVEN�ONE�FOR�US=* EXACTLY ONE LEFT, WE WILL NOW GET IT LEAVING THE POOL EMPTY<‰MOVE.B„#N.SET+Z.CLR,5(A7)�ASSERT�"LAST�BUFFER�WAS�SUPPLIED"0‰CLR.L…FREEQND(A1)�AND�CLEAR�POOL'S�TAIL�POINTEREGTFRIR1‚MOVE.L„FREEQHD(A1),A3�HEAD�BUFFER�ADDR�->�A3�(NO�OFFSET�YET!))‰SUBA.L„#LOCKBIT,A3�TURN�OFF�THE�LOCK�BIT8‰ADD.L…MEMOFF,A3�COMPUTE�WHERE�WE�"SEE"�THE�BUFFER�TO�BE9‰BSET†#7,SDDLNK(A3)‚SET�LOCK�BIT�IN�NEXT�BUFFER'S�ADDRESS3‰CRASH.NE‚*-1‡COMMIT�HARI-KARI�IF�IT'S�ALREADY�SET!B‰MOVE.L„SDDLNK(A3),FREEQHD(A1)�STORE�NEW�HEAD�PTR,�ALREADY�LOCKED! )‰BCLR†#7,FREEQHD(A1)�AND�RELEASE�THE�LOCK7‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.,‰CLR.L…0(A3)…CLEAR�THE�BUFFER'S�FORWARD�LINK‰CLR.L…4(A3)…CLEAR‰CLR.L…8(A3)ŠOTHER�PARTS#‰CLR.L…12(A3)”OF�THE�BUFFER�AS�WELL‰MOVE.L„(A7)+,A1#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN 1* NO BUFFERS LEFT AT ALL, NOT EVEN ONE FOR CALLER6GTFRIR0‚ADD.W…#1,FQBCNT(A1)�PUT�COUNT�BACK�LIKE�IT�WAS4‰CRASH.NE‚*-1‡SHOULD�BECOME�ZERO!�DIE�IF�IT�DOESN'T!)‰BCLR†#7,FREEQHD(A1)�AND�RELEASE�THE�LOCK7‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.)‰CLR.B…5(A7)…ASSERT�"NO�BUFFER�AVAILABLE"1‰MOVE.L„#FLYPAPER,A3�BUFFER�POINTER�=�"BAD"�VALUE‰MOVE.L„(A7)+,A1#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN‰PAGEH*************************************************************************Æ*=*ˆSUBROUTINE:‚"SBGTFRBF"‚GET�ONE�BUFFER�FROM�THE�FREE�QUEUEƒ**ˆTRAP:ˆ"GTFRBF"©**ˆENTER:�NO�ARGUMENTS.ª*-*ˆRETURN:‚A0.L�=�ADDRESS�OF�BUFFER�SUPPLIED”**’CCR±**“Z�set�BUFFER�WAS�SUPPLIEDš**’not�set‚NO�BUFFER�AVAILABLE˜*A*ˆNOTE:‚THIS�ROUTINE�WILL�NOT�DEPLETE�THE�FREE�QUEUE�COMPLETELY�*5*�IT�WILL�SUPPLY�BUFFERS�DOWN�TO�THE�LOW�WATER�MARK†*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�U«* *˜A�R�S�**š|�|_�stack–**š|_______________�returned“**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†GTFRBF,SBGTFRBF9GTFRBFƒBSR.S…SBGTFRBF�TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE /SBGTFRBF�MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT3‰MOVE.B„#Z.SET,1(A7)�ASSUME�BUFFER�WILL�BE�SUPPLIED‰MOVE.L„A1,-(A7);‰MOVE.L„SYSPOFF,A1�GET�THE�LOCAL�OFFSET�TO�THE�CONTROL�AREA 7* OBTAIN EXCLUSIVE ACCESS TO THE FREE POOL CONTROL AREA6GTFRBFLK�MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL!‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS(‰TAS‡FREEQHD(A1)�ATTEMPT�TO�SET�THE�LOCK3‰BMI.S…GTFRBFLK‚LOOP�IF�FAILED�(ANOTHER�MPU�HAS�IT),‰CRASH.NE‚*-1‡CRASH�IF�LOCK�BYTE�IS�CORRUPT! .* FREEQHD IS LOCKED AND INTERRUPTS ARE MASKED!‰MOVE.W„FQBCNT(A1),D0-‰CMP.W…FQLWM(A1),D0�ABOVE�THE�LOW�WATER�MARK?+‰BLE.S…GTFRBFLW‚NO,�CAN'T�GET�A�BUFFER,�OUT*‰SUB.W…#1,FQBCNT(A1)�YES,�WE�WILL�TAKE�ONE;‰BGT.S…GTFRBF1ƒOUT�IF�AT�LEAST�ONE�REMAINS�AFTER�WE�GET�ONE7‰BMI.S…GTFRBF0ƒOUT�IF�NOT�EVEN�ONE�FOR�US�(L.W.M.�<=�0)=* EXACTLY ONE LEFT, WE WILL NOW GET IT LEAVING THE POOL EMPTY,‰CLR.L…FREEQND(A1)�CLEAR�POOL'S�TAIL�POINTEREGTFRBF1‚MOVE.L„FREEQHD(A1),A0�HEAD�BUFFER�ADDR�->�A0�(NO�OFFSET�YET!)%‰SUBA.L„#LOCKBIT,A0�TURN�OFF�LOCK�BIT8‰ADD.L…MEMOFF,A0�COMPUTE�WHERE�WE�"SEE"�THE�BUFFER�TO�BE9‰BSET†#7,SDDLNK(A0)�SET�LOCK�BIT�IN�NEXT�BUFFER'S�ADDRESS3‰CRASH.NE‚*-1‡COMMIT�HARI-KARI�IF�IT'S�ALREADY�SET!B‰MOVE.L„SDDLNK(A0),FREEQHD(A1)�STORE�NEW�HEAD�PTR,�ALREADY�LOCKED!)‰BCLR†#7,FREEQHD(A1)�AND�RELEASE�THE�LOCK7‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.,‰CLR.L…0(A0)…CLEAR�THE�BUFFER'S�FORWARD�LINK‰CLR.L…4(A0)…CLEAR‰CLR.L…8(A0)ŠOTHER�PARTS#‰CLR.L…12(A0)”OF�THE�BUFFER�AS�WELL‰MOVE.L„(A7)+,A1#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN 1* NO BUFFERS LEFT AT ALL, NOT EVEN ONE FOR CALLER6GTFRBF0‚ADD.W…#1,FQBCNT(A1)�PUT�COUNT�BACK�LIKE�IT�WAS4‰CRASH.NE‚*-1‡SHOULD�BECOME�ZERO!�DIE�IF�IT�DOESN'T!1GTFRBFLW�BCLR†#7,FREEQHD(A1)�AND�RELEASE�THE�LOCK7‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.)‰CLR.B…5(A7)…ASSERT�"NO�BUFFER�AVAILABLE"1‰MOVE.L„#FLYPAPER,A0�BUFFER�POINTER�=�"BAD"�VALUE‰MOVE.L„(A7)+,A1#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN‰PAGEH*************************************************************************Æ*>*ˆSUBROUTINE:‚"SBGTFRML"‚GET�MANY�BUFFERS�FROM�THE�FREE�POOL‚**ˆTRAP:ˆ"GTFRML"©*-*ˆENTER:‚D1.W�=�NUMBER�OF�BUFFERS�REQUESTED”* /*ˆRETURN:‚A0.L�=�ADDR�OF�1ST�BUFFER�IN�STRING’*%*‘D1.W�=�NUMBER�OF�BUFFERS�SUPPLIED”**’CCR±*#*“Z�set�ALL�BUFFERS�WERE�SUPPLIED”*$*“N�set�SOME�BUFFERS�WERE�SUPPLIED“* *’neither‚NO�BUFFERS�AVAILABLE—*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�* *˜D�U�R©* *˜A�R�S�**œ|‹|_�stack–**œ|_____________�returned“**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†GTFRML,SBGTFRML9GTFRMLƒBSR.S…SBGTFRML‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE /SBGTFRML�MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT$‰CLR.B…1(A7)…ASSUME�WE�WILL�GET�NONE0‰CLR.W…-(A7)…INIT�COUNT�OF�HOW�MANY�WE'VE�GOTTEN-‰CLR.L…-(A7)…INIT�A(LAST�BUFFER�WE'VE�GOTTEN).* STACK: 0(A7).L = A(LAST BUFFER WE'VE GOTTEN)**ˆ4(A7).W�=�COUNT�OF�HOW�MANY�WE'VE�GOTTEN!*ˆ6(A7).W�=�RETURN�CONDITION�CODE9‰TST.W…D1ˆCALLER�WANT�LESS�THAN�OR�EQUAL�TO�ZERO�BUFFERS?$‰CRASH.LE‚*-1‡YES,�COMMIT�HARI-KARI!'‰BRA.S…GTFRMLGB‚NO,�GO�TRY�AND�GET�THEM CGTFRMLGA�BSR.L…SBGTFRBF‚GET�ONE�BUFFER,�CHECKING�THE�LOW�WATER�MARK'‰BNE.S…GTFRMLGS‚OUT�IF�COULDN'T�GET�ONE1‰MOVE.B„#N.SET+Z.CLR,7(A7)�RETURN�CODE�=�GOT�SOME@‰MOVE.L„0(A7),SDDLNK(A0)�NEW�BFR�POINTS�TO�LAST�BFR�WE'VE�GOTTEN=‰MOVE.L„A0,0(A7)‚AND�NEW�BUFFER�BECOMES�THE�LAST�WE'VE�GOTTEN*‰ADDQ.W„#1,4(A7)‚AND�COUNT�HOW�MANY�WE�GET3GTFRMLGB�DBRA†D1,GTFRMLGA�LOOP�TILL�WE�GET�THEM�ALL KGTFRMLGD�MOVE.B„#Z.SET+N.CLR,7(A7)�GOT�ALL�THE�USER�WANTED,�SET�RETURN�CODE9GTFRMLGS�MOVE.L„(A7)+,A0‚A0�=�A(FIRST�BUFFER�IN�THE�LIST)%‰MOVE.W„(A7)+,D1‚D1�=�HOW�MANY�WE�GOT*‰BGT.S…GTFRMLEX‚OUT�IF�WE�GOT�AT�LEAST�ONE3‰MOVE.L„#FLYPAPER,A0�GOT�NONE,�SET�A0�=�BAD�POINTER+GTFRMLEX�MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN‰PAGEH*************************************************************************Æ*9*ˆSUBROUTINE:‚"SBPTFRBF"‚PUT�A�BUFFER�ON�THE�FREE�QUEUE‡**ˆTRAP:ˆ"PTFRBF"©*'*ˆENTER:‚A0.L�=�ADDRESS�OF�THE�BUFFERš**ˆRETURN:�NO�ARGUMENTS.©*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D­* *˜A�P�S�**š|�|_�stack–**š|_______________�preserved’**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†PTFRBF,SBPTFRBF9PTFRBFƒBSR.S…SBPTFRBF‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE /SBPTFRBF�MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT‰MOVE.L„A1,-(A7)/‰CMPA.L„#0,A0…DID�CALLER�PASS�US�A�NIL�POINTER?$‰CRASH.EQ‚*-1‡YES,�COMMIT�HARI-KARI!‰MOVE.L„SYSPOFF,A16‰CLR.L…SDDLNK(A0)�CLEAR�RETURNING�BUFFERS�FORWARD�LINK 7* OBTAIN EXCLUSIVE ACCESS TO THE FREE POOL CONTROL AREA6PTFRBFLK�MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL!‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS(‰TAS‡FREEQHD(A1)�ATTEMPT�TO�SET�THE�LOCK3‰BMI.S…PTFRBFLK‚LOOP�IF�FAILED�(ANOTHER�MPU�HAS�IT),‰CRASH.NE‚*-1‡CRASH�IF�LOCK�BYTE�IS�CORRUPT! .* FREEQHD IS LOCKED AND INTERRUPTS ARE MASKED!?‰MOVE.L„FREEQHD(A1),SDDLNK(A0)�LINK�FREE�QUEUE�AFTER�RETURN�BFRA‰BCLR†#7,SDDLNK(A0)�CLEAR�EXTRANEOUS�LOCK�BIT�IN�OUR�FORWARD�LINK7‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�BIT�WAS�ALREADY�CLEAR?‰SUBA.L„MEMOFF,A0�REMOVE�OUR�LOCAL�OFFSET�FROM�BUFFER'S�ADDRESS/‰ADDA.L„#LOCKBIT,A0�(ASSERT�POOL�STILL�LOCKED!)A‰MOVE.L„A0,FREEQHD(A1)�STORE�NEW�HEAD�POINTER,�LOCK�BIT�STILL�SET'‰TST.L…FREEQND(A1)�WAS�THE�QUEUE�EMPTY?1‰BNE.S…PTFRBFNE‚NO,�TAIL�POINTER�IS�VALID�ALREADY7‰TST.W…FQBCNT(A1)�YES,�COUNT�OUGHT�TO�BE�ZERO�RIGHT�NOW‰CRASH.NE‚*-1‡DIE�IF�IT�ISN'T@‰SUBA.L„#LOCKBIT,A0�(LOCK�BIT�DOESN'T�APPLY�TO�THE�TAIL�POINTER);‰MOVE.L„A0,FREEQND(A1)�RETURNING�BUFFER�IS�TAIL�BUFFER�ALSO4PTFRBFNE�ADDQ.W„#1,FQBCNT(A1)�INCREMENT�BUFFER�COUNT3‰CRASH.LE‚*-1‡DIE�IF�THE�COUNT�IS�ZERO�OR�NEGATIVE!)‰BCLR†#7,FREEQHD(A1)�AND�RELEASE�THE�POOL-‰CRASH.EQ‚*-1‡DIE�IF�IT�WAS�ALREADY�UNLOCKED!7‰MOVE.W„4(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.‰MOVE.L„(A7)+,A1)‰MOVE.L„#FLYPAPER,A0�SET�A0�=�BAD�POINTER‰MOVE.W„(A7)+,SR ‰RTS‘RETURN‰PAGE H*************************************************************************Æ*8*ˆSUBROUTINE:‚"SBPTFRML"‚PUT�A�LINKED�CHAIN�OF�BUFFERSˆ**¡ON�THE�FREE�QUEUE”**ˆTRAP:ˆ"PTFRML"©*:*ˆENTER:‚A0.L�=�ADDRESS�OF�THE�FIRST�BUFFER�IN�THE�CHAIN‡**—OR�NIL�($00000000)�**ˆRETURN:�NO�ARGUMENTS.©*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�U«* *˜A�U�S�**š|�|_�stack–**š|_______________�used—**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†PTFRML,SBPTFRML9PTFRMLƒBSR.S…SBPTFRML‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE *SBPTFRML�MOVE.L„A0,D0…SAVE�A(FIRST�BUFFER) !* D0.L = A(NEXT BUFFER TO RETURN)5PTFRMLNX�MOVE.L„D0,A0…GET�ADDRESS�OF�BUFFER�TO�RETURN ‰TST.L…D05‰BEQ.S…PTFRMLEX‚OUT�IF�ALL�BUFFERS�HAVE�BEEN�RETURNED1‰MOVE.L„SDDLNK(A0),D0�SAVE�ADDRESS�OF�NEXT�BUFFER'‰BSR.L…SBPTFRBF‚RETURN�THE�BUFFER�IN�A04‰BRA.S…PTFRMLNX‚AND�LOOP�TILL�ALL�HAVE�BEEN�RETURNED 1PTFRMLEX�MOVE.L„#FLYPAPER,A0�SET�A0�=�BAD�POINTER‰RTS‰PAGEH*************************************************************************Æ*:*ˆSUBROUTINE:‚"SBPTXMQ"‚PUT�A�BUFFER�ON�A�TRANSMIT�QUEUE†**ˆTRAP:ˆ"PTXMQ"ª*'*ˆENTER:‚A0.L�=�ADDRESS�OF�THE�BUFFERš**ˆRETURN:�CCR³*-*‘Z�set�BUFFER�WAS�LINKED�TO�TRANSMIT�QUEUEŒ*%*‘N�set�ILLEGAL�SDLC�STATION�NUMBER”*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�U«* *˜A�U�U�U‰S�**ž|‰|_�stack–**ž|___________�used—**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ H*************************************************************************Æ*E*�WARNING:�"PTXMQ"�CONTAINS�AN�IMPLEMENTATION�RESTRICTION�WHICH�HAS„*F*�NOT�BEEN�RESOLVED�YET.‚"PTXMQ"�ASSUMES�THAT�IF�MEMOFF�IS�ZERO�THEN‚*C*�THE�SDLC�DRIVER�IS�PRESENT�IN�THE�SAME�MPU.‚IN�EXISTING�USES�OF…*D*�THIS�MODULE,�THAT�IS�TRUE.‚HOWEVER�IT�MAY�NOT�ALWAYS�BE�TRUE.‚ATƒ*D*�SOME�FUTURE�TIME,�"PTXMQ"�SHOULD�BE�CHANGED�TO�DETERMINE�IF�SDLC…*E*�EXISTS�IN�THE�SAME�MPU�IN�A�MORE�DIRECT�FASHION,�AND�THEREBY�LIFT„*E*�THIS�RESTRICTION.‚A�WARNING�IS�GENERATED�WITHIN�"PTXMQ"�TO�ACT�ASƒ*#*�A�REMINDER�OF�THIS�RESTRICTION.¦**Æ*H************************************************************************ ‰XDEF†PTXMQ,SBPTXMQ7PTXMQ„BSR.S…SBPTXMQƒTRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE .SBPTXMQ‚MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT ‰CMPA.L„#0,A0=‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�CALLER�PASSED�A�NIL�POINTER ‰FAIL†501‡SEE�THE�ABOVE�WARNINGC*�TEST�MEMOFF�FOR�ZERO.‚IN�AN�EXORMACS/VM02�CONFIGURATION,�THE�SDLCH*�DRIVER�EXECUTES�IN�THE�VM02.‚MEMOFF�IS�ZERO�FOR�THE�VM02,�AND�NON-ZEROI*�FOR�THE�EXORMACS.‚BY�TESTING�MEMOFF�WE�DETERMINE�THAT�(IN�THIS�ONE�TYPEI* OF SYSTEM CONFIGURATION) WE ARE RUNNING IN THE PROCESSOR WHICH CONTAINS* THE SDLC DRIVER.‰TST.L…MEMOFF„IS�MEMOFF�ZERO?3‰BEQ.S…PTXMQSDL‚YES,�ENQUEUE�TO�SCB�AND�AWAKEN�SDLC<‰BSR‡SDLCQXMT‚NO,�PASS�THE�BUFFER�TO�PROPER�MPU�FOR�QUEUEING7‰MOVE.B„#Z.SET,1(A7)�RETURN�CODE�=�BUFFER�WAS�PASSED�OK#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE ‰RTS‘RETURN G* FOR THE REMAINDER OF THIS ROUTINE WE KNOW THAT WE ARE IN THE SAME MPUJ* AS THE SDLC DRIVER, AND THEREFORE THAT OUR "MEMOFF" AND "SYSPOFF" AS THEH*�SAME�AS�HIS.‚FOR�THIS�REASON�WE�DISPENSE�WITH�CORRECTION�FACTORS�USING3* THESE VARIABLES IN THE REMAINDER OF THIS ROUTINE.?PTXMQSDL�CLR.L…D0ˆHERE�ONLY�WHEN�IN�SAME�MPU�AS�THE�SDLC�DRIVER8‰MOVE.B„SDDSEC(A0),D0�GET�STATION�NUMBER�FROM�THE�BUFFER<‰MOVE.L„SDLCPCB,A1�GET�POINTER�TO�PRIMARY�CONTROL�BLOCK,�AND?‰MOVE.L„SDPFSEC(A1),A1�THEREFROM�THE�1ST�SECONDARY�CB'S�ADDRESS,‰CMP.B…#$FF,D0ƒBUFFER�GOING�TO�ALL�STATIONS?;‰BEQ.S…PTXMQFDƒYES,�PUT�THE�MESSAGE�ON�FIRST�SCB�REGARDLESS O* SCAN THRU THE SECONDARY CONTROL BLOCKS LOOKING FOR A MATCHING STATION ADDRESSBPTXMQSC‚CMP.B…SDSSEC(A1),D0�IS�THIS�THE�DESTINATION�STATION'S�SCB? ;‰BEQ.S…PTXMQFDƒYES,�WE'VE�FOUND�THE�CORRECT�SCB�(SEE�BELOW):‰ADD.L…#SDSLNG,A1�NO,�FETCH�NEXT�(CONSECUTIVE)�SCB�ADDRESS-‰TST.B…SDSSEC(A1)�IS�THERE�ANOTHER�ONE�THERE?@‰BNE.S…PTXMQSCƒYES,�LOOP�TILL�WE�FIND�CORRECT�ONE�(OR�REACH�END)6‰MOVE.B„#N.SET+Z.CLR,1(A7)�NO,�ILLEGAL�STATION�NUMBER!0‰MOVE.W„(A7)+,SR‚ASSERT�RETURNING�CONDITION�CODE‰RTS‘AND�RETURN D* TARGET SCB FOUND, PREPARE THE BUFFER FOR TRANSMISSION AND QUEUE IT3PTXMQFD‚CLR.W…SDDSTS(A0)�ASSERT�NO�REPORTED�ERRORS,,‰CLR.B…SDDERR(A0)�AND�NO�ERRORS�OF�ANY�KIND,(‰CLR.B…SDDRSP(A0)�AND�NO�RESPONSE�(YET),0‰CLR.L…SDDLNK(A0)�AND�NO�BUFFERS�AFTER�THIS�ONE,?‰MOVE.B„SDSSRT(A1),SDDRTC(A0)�AND�FINALLY,�A�FRESH�RETRY�COUNT."‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS!4‰MOVE.L„SDSTND(A1),A2�LINK�BCB�TO�END�OF�TXMIT�QUEUE*‰TST.L…SDSTHD(A1)�IS�TRANSMIT�QUEUE�EMPTY?1‰BNE.S…PTXMQTAL‚NO,�LINK�TO�TAIL�OF�CURRENT�QUEUE<‰LEA‡SDSTHD-SDDLNK(A1),A2�YES,�NEW�BUFFER�IS�QUEUE�HEAD�ALSODPTXMQTAL�MOVE.L„A0,SDSTND(A1)�TAIL�OF�QUEUE�POINTS�TO�THE�NEW�BUFFER7‰MOVE.L„A0,SDDLNK(A2)�WHICH�GLUES�ONTO�TAIL�OF�LAST�ONE;* ZERO THIS STATIONS TIMER SO WE WILL SEND TRAFFIC A.S.A.P.?‰CLR.W…SDSCTD(A1)�********�TEMPORARY�UNTIL�EXPEDITED�TXMIT�DONE6‰MOVE.W„(A7),SRƒRESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.(* TELL SDLC THERE IS NEW TRAFFIC TO SEND=‰BSR.L…SDLCQUSB‚********�TEMPORARY�UNTIL�EXPEDITED�TXMIT�DONE5‰MOVE.B„#Z.SET,1(A7)�RETURN�CC�=�BUFFER�WAS�LINKED�OK)‰MOVE.L„#FLYPAPER,A0�SET�A0�=�BAD�POINTER0‰MOVE.W„(A7)+,SR‚ASSERT�RETURNING�CONDITION�CODE‰RTS‘AND�RETURN‰PAGEH*************************************************************************Æ*8*ˆSUBROUTINE:‚"SBPTUSQ"‚PUT�A�BUFFER�ON�THE�USER�QUEUEˆ**ˆTRAP:ˆ"PTUSQ"ª*'*ˆENTER:‚A0.L�=�ADDRESS�OF�THE�BUFFERš**ˆRETURN:�NO�ARGUMENTS.©*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�U«* *˜A�U�U�U‰S�**ž|‰|_�stack–**ž|___________�used—**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†PTUSQ,SBPTUSQ7PTUSQ„BSR.S…SBPTUSQƒTRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE .SBPTUSQ‚MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT(‰MOVE.L„A0,D0…CALLER�PASS�A�NIL�POINTER?)‰CRASH.EQ‚*-1‡COMMIT�HARI-KARI�IF�HE�DID!‰MOVE.L„SYSPOFF,A10‰CLR.L…SDDLNK(A0)�CLEAR�BUFFER'S�FORWARD�POINTER 8* OBTAIN EXCLUSIVE ACCESS TO THE USER QUEUE CONTROL AREA5PTUSQLK‚MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL!‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS(‰TAS‡USERQHD(A1)�ATTEMPT�TO�SET�THE�LOCK2‰BMI.S…PTUSQLKƒLOOP�IF�FAILED�(ANOTHER�MPU�HAS�IT),‰CRASH.NE‚*-1‡CRASH�IF�LOCK�BYTE�IS�CORRUPT! .* USERQHD IS LOCKED AND INTERRUPTS ARE MASKED!<‰MOVE.L„USERQND(A1),D0�GET�ADDR�OF�LAST�BUFFER�IN�USER�QUEUE>‰BEQ.S…PTUSQHED‚NEW�BUFFER�TO�HEAD�AND�TAIL�IF�CURRENTLY�EMPTY*‰MOVE.L„D0,A2…OTHERWISE,�LINK�TO�TAIL�ONLY>‰ADDA.L„MEMOFF,A2�DEVELOP�PERCEIVED�ADDRESS�OF�THE�TAIL�BUFFER2‰SUBA.L„MEMOFF,A0�AND�ACTUAL�ADDRESS�OF�NEW�BUFFER=‰MOVE.L„A0,SDDLNK(A2)�TIE�NEW�BUFFER�ONTO�CURRENT�TAIL�BUFFER;‰MOVE.L„A0,USERQND(A1)�AND�MAKE�NEW�BUFFER�THE�CURRENT�TAIL)‰BCLR†#7,USERQHD(A1)�RELEASE�THE�LOCK�BIT)‰CRASH.EQ‚*-1‡DIE�IF�IT�WAS�ALREADY�CLEAR7‰MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P. APTUSQWKU�MOVE.L„NATBEG,D0�NETWORK�SERVICES�RUN�IN�THIS�PROCESSOR?-‰BEQ.S…PTUSQEXT‚NO,�JUST�RETURN�TO�CALLER�NOW‰MOVE.L„D0,A0…YES,‰MOVE.L„#SSCNAU-1,D0‚DEVELOP‰MULU†#NATESIZ,D0�SSCT�TASK'S#‰LEA‡NATENTRY(A0,D0),A0�TCB�ADDRESS%‰MOVE.L„NATTCB(A0),A0�AND�WAKE�HIM�UP ‰TR0$.WAKEUP 1PTUSQEXT�MOVE.L„#FLYPAPER,A0�SET�A0�=�BAD�POINTER‰MOVE.W„(A7)+,SR ‰RTS‘RETURN K* USER QUEUE IS CURRENTLY EMPTY, STORE NEW BUFFER TO HEAD AND TAIL POINTERS>PTUSQHED�SUBA.L„MEMOFF,A0�DEVELOP�ACTUAL�ADDRESS�OF�NEW�BUFFERC‰MOVE.L„A0,USERQND(A1)�STORE�AS�END�BUFFER�(LOCK�BIT�DOESN'T�APPLY)‰ADDA.L„#LOCKBIT,A0>‰MOVE.L„A0,USERQHD(A1)�AND�AS�HEAD�BUFFER�(LOCK�BIT�STILL�ON!))‰BCLR†#7,USERQHD(A1)�RELEASE�THE�LOCK�BIT)‰CRASH.EQ‚*-1‡DIE�IF�IT�WAS�ALREADY�CLEAR 7‰MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.-‰BRA.S…PTUSQWKU‚GO�SEE�ABOUT�NETWORK�SERVICES‰PAGEH*************************************************************************Æ*<*ˆSUBROUTINE:‚"SBGTUSQ"‚GET�ONE�BUFFER�FROM�THE�USER�QUEUE„**ˆTRAP:ˆ"GTUSQ"ª**ˆENTER:�NO�ARGUMENTS.ª*-*ˆRETURN:‚A0.L�=�ADDRESS�OF�BUFFER�SUPPLIED”**’CCR±**“Z�set�BUFFER�WAS�SUPPLIEDš**’not�set‚NO�BUFFER�AVAILABLE˜*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�U«* *˜A�R�S�**š|�|_�stack–**š|_______________�returned“**Æ*#*�REPLACED�ON�3/8/83,�ED�SKINNER.¦**Æ*H************************************************************************ ‰XDEF†GTUSQ,SBGTUSQ7GTUSQ„BSR.S…SBGTUSQƒTRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE .SBGTUSQ‚MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINTB‰MOVE.B„#Z.SET,1(A7)�ASSUME�WE'LL�USE�THE�"BUFFER�SUPPLIED"�RETURN‰MOVE.L„SYSPOFF,A1 8* OBTAIN EXCLUSIVE ACCESS TO THE USER QUEUE CONTROL AREA5GTUSQLK‚MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL!‰ORI.W…#LEVEL7,SR�MASK�INTERRUPTS(‰TAS‡USERQHD(A1)�ATTEMPT�TO�SET�THE�LOCK2‰BMI.S…GTUSQLKƒLOOP�IF�FAILED�(ANOTHER�MPU�HAS�IT),‰CRASH.NE‚*-1‡CRASH�IF�LOCK�BYTE�IS�CORRUPT! .* USERQHD IS LOCKED AND INTERRUPTS ARE MASKED!4‰MOVE.L„USERQHD(A1),D0�GET�FIRST�BUFFER�IN�THE�QUEUE ‰BCLR†#31,D0‰TST.L…D0ˆIS�THE�QUEUE�EMPTY?‰BEQ.S…GTUSQEMP‚YES,�OUT‰MOVE.L„D0,A0…NO,:‰ADDA.L„MEMOFF,A0�DEVELOP�PERCEIVED�ADDRESS�OF�HEAD�BUFFER/‰TST.L…SDDLNK(A0)�ANY�BUFFER�AFTER�HEAD�BUFFER?‰BNE.S…GTUSQMOR-‰CLR.L…USERQND(A1)�NO,�CLEAR�THE�TAIL�POINTERCGTUSQMOR�BSET†#7,SDDLNK(A0)�ASSERT�LOCK�BIT�IN�NEXT�BUFFERS�ADDRESS(‰CRASH.NE‚*-1‡DIE�IF�IT�WAS�ALREADY�SET!D‰MOVE.L„SDDLNK(A0),USERQHD(A1)�AND�STORE�NEW�HEAD�PTR�(LOCK�BIT�ON!))‰BCLR†#7,USERQHD(A1)�AND�RELEASE�THE�LOCK*‰CRASH.EQ‚*-1‡DIE�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.4‰CLR.L…SDDLNK(A0)�CLEAR�GOTTEN�BUFFER'S�FORWARD�LINK#‰MOVE.W„(A7)+,SR‚ASSERT�RETURN�CODE‰RTS‘AND�RETURN -GTUSQEMP�BCLR†#7,USERQHD(A1)�RELEASE�THE�LOCK*‰CRASH.EQ‚*-1‡DIE�IF�IT�WAS�ALREADY�CLEAR!7‰MOVE.W„0(A7),SR‚RESTORE�PRIOR�INTERRUPT�LEVEL�A.S.A.P.)‰MOVE.L„#FLYPAPER,A0�SET�A0�=�BAD�POINTER0‰CLR.B…1(A7)…ASSERT�"NO�BUFFER�AVAILABLE"�RETURN‰MOVE.W„(A7)+,SR‰RTS‘AND�RETURN‰ENDéééééé =/*=/*†SDLC.DLTRACE.AF=/*1=/* Chain file to assemble module SDLC.DLTRACE.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to SDLC.DLTRACE.LS=/*=/IFC \1ƒ=ARG�SDLC.DLTRACE.LS=/ENDIF=/*-=ASM SDLC.DLTRACE.SA,SDLC.DLTRACE.RO,\1;RZ=40=/*{ Included files are:=/*ƒ9995.&.NEC7201.EQ=/*}=/*=ENDéééééé˜.DLTRACE‚IDNT†1,0ƒTRACE�INTERRUPTS�ON�DATA�LINK‰INCLUDEƒ9995.&.NEC7201.EQ‰PAGE*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.*F***********************************************************************Ä*&*†Trace�every�interrupt�from�NEC7201œ**Ä*F*************************************************************************1*ˆON�ENTRY:�A1,A2�and�D0�have�been�saved�on�stack'*’A1�=�Pointer�to�Primary�Control�Block*’D0�=�INTERRUPT�NUMBER* *ˆON�RETURN:*’A1�and�A2�destroyed* ‰SECTIONƒ9‰OPT‡PCS‰XREF†SDLCPCB,TRACEBEG‰XREF†NECCTL_A,NECCTL_B* ‰XDEF†DLTRACE**/DLTRACE‚MOVE.L„TRACEBEG,A2‰Start�of�trace�table%‰MOVE.L„(A2),A2�ADDRESS�of�next�entry4‰MOVE.W„16(A7),(A2)+ˆSave�SR�when�interrupt�occurred4‰MOVE.L„18(A7),(A2)+ˆSave�PC�when�interrupt�occurred'‰MOVE.W„D0,(A2)+ŒSave�type�of�interrupt/‰MOVE.L„0(A1,D0),(A2)+†Save�SDLC�vector�address)‰MOVE.B„NECCTL_A,(A2)+‡Save�Port�A�status)‰MOVE.B„NECCTL_B,(A2)+‡Save�Port�B�status#‰LEA‡2(A2),A2ŒIncrement�to�16�bytes(‰MOVE.L„TRACEBEG,A1‰Start�of�trace�table)‰CMP.L…4(A1),A2ŒIs�this�the�end�of�table?‰BLT.S…DLTRAC4�Branch�if�NO+‰LEA‡16(A1),A2‹Restart�with�1st�trace�entry1DLTRAC4‚MOVE.L„A2,(A1)�Save�address�of�Next�entry)‰MOVE.L„SDLCPCB,A1ŠRestore�address�of�PCB ‰RTS›Return‰END é é¡/=/*=/*†SDLC.EXORDLC.AF=/*1=/* Chain file to assemble module SDLC.EXORDLC.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to SDLC.EXORDLC.LS=/*=/IFC \1ƒ=ARG�SDLC.EXORDLC.LS=/ENDIF=/*-=ASM SDLC.EXORDLC.SA,SDLC.EXORDLC.RO,\1;RZ=60=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.SDLCPRI.TEMPLTS.EQ=/*ƒ9995.NTS.SMSG.EQ=/*ƒ9995.NTS.NTW.EQ=/*}=/*=ENDééééééª-‰TTL‡EXORDLC.SAŠDLC�routines�called�by�NWCREQ9* Modified 4/6/83 by Ed Skinner for MC68010 compatability**ˆSubroutines�called�by�NWCREQ*:*ˆThese�are�substitutes�for�the�real�SDLC�routines�running *ˆon�a�VM02�in�EXORmacs�chassis.*/*ˆMust�send�a�message�to�V2REQ�handler�in�VM02.5*ˆThe�V2REQ�handler�will�call�the�real�SDLC�routines.***ˆINCLUDEƒ9995.&.STR.EQ!*ˆINCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ*ˆINCLUDEƒ9995.NTS.SMSG.EQ*ˆINCLUDEƒ9995.NTS.NTW.EQ*‰NOLIST‰INCLUDEƒ9995.&.STR.EQ ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰INCLUDEƒ9995.NTS.SMSG.EQ‰INCLUDEƒ9995.NTS.NTW.EQ‰LIST‰PAGE ‰SECTIONƒ10‰XDEF†SBUSRACK* SBUSRACK�MOVE.L„D0,D7�STATION�ID‰MOVE.L„#NTWCACKR,D6ˆCommandUSRCMDƒTR0.GTFRBF‰IFˆ�THEN.S,‹MOVE.L„#NTSRNOB,D0‰ERROR�CODE�for�no�buffer.‹ADD.L…#2,0(A7)ŒChange�PC�for�no�buffer�return‰ELSE.S/‹MOVE.W„D7,V2STA(A0)ˆSave�Station�ID�in�message,‹MOVE.B„D6,V2CMD(A0)ˆSave�COMMAND�in�message+‹BSR.S…SBPTV2RQŒPut�buffer�in�request�QUEUE‰ENDI‰RTS**‰XDEF†SBSDLCFL* SBSDLCFL�MOVE.L„D1,D7�STATION�ID‰MOVE.L„#NTWFLUSH,D6ˆCommand&‰BRA‡USRCMDŽContinue�with�prev�routine*:*…Get�here�from�call�to�SBPTXMQ„(Put�buffer�on�Xmit�Queue)*‰XDEF†SDLCQXMT*9SDLCQXMT�MOVE.B„#DLCQXM,V2CMD(A0)ƒSave�COM MAND�in�message+‰BSR.S…SBPTV2RQŒPut�buffer�in�request�QUEUE‰RTS**‰XDEF†SBSDLCKL*SBSDLCKL�CLR.L…D7’STATION�ID‰MOVE.L„#DLCSTOP,D6‰Command&‰BRA‡USRCMDŽContinue�with�prev�routine‰PAGE*0*ƒSubroutine�to�put�message�in�V2�Request�buffer*‰XREF†SYSPOFF,MEMOFF,V2RQHD*.SBPTV2RQ�MOVE.L„A1,-(A7)ŒSave�A1�-�will�use�it&‰MOVE.L„SYSPOFF,A1ŠSYSPAR�offset�in�V2+‰CLR.L…(A0)�Be�sure�link�in�buffer�is�clear&‰SUB.L…MEMOFF,A0‹Adjust�buffer�address‰REPEAT%‹TAS‡V2RQHD(A1)ŠBlock�other�processor ‰UNTIL…(‰LEA‡V2RQHD(A1),A1‡Start�of�buffer�chain$‰MOVE.L„(A1),D0�First�buffer�address‰BCLR†#31,D0ŽClear�TAS�bit‰TST.L…D0’Does�buffer�exist?‰IFˆ�THEN.S‹REPEAT!�MOVE.L„D0,A1�Next�buffer�address�ADD.L…MEMOFF,A1‹Add�offset³R¼*�MOVE.L„(A1),D0�Find�last�buffer's�address ‹UNTIL…$‹MOVE.L„A0,(A1)�Put�new�one�in�chain ‹MOVE.L„SYSPOFF,A1ŠSYSPAR�offset!‹BCLR†#7,V2RQHD(A1)‡Clear�TAS�bit‰ELSE.S‹MOVE.L„A0,-(A7)¡*�1/25/83�SCB.)‹BSET†#31,(A7)ŒSet�TAS�bit‹*�1/25/83�SCB.7‹MOVE.L„(A7)+,(A1)ŠPut�this�one�in�chain�*�1/25/83�SCB.+‹BCLR†#31,(A1)ŒClear�TAS�bit‰*�1/25/83�SCB.‰ENDI‰MOVE.L„(A7)+,A1ŒRestore�A1‰RTS*:*„The�following�entry�is�here�to�satisfy�an�XREF�in�BUFMGT*‰XDEF†SDLCQUSB SDLCQUSB RTS‰ENDéééééé=/*=/*†SDLC.IBFMGT.AF=/*0=/* Chain file to assemble module SDLC.IBFMGT.SA=/*:=/* If no output argument is specified for the listing the-=/* chain file will default to SDLC.IBFMGT.LS=/*=/IFC \1ƒ=ARG�SDLC.IBFMGT.LS=/ENDIF=/*'=ASM SDLC.IBFMGT.SA,SDLC.IBFMGT.RO,\1;R=/*{ Included files are:=/*ƒ9995.SDLCPRI.TEMPLTS.EQ=/*}=/*=ENDéé ééééÄ2IBUFMGT‚IDNT†1,0‡BUFFER�MANAGEMENT�INIT�SUBROUTINE7‰TTL‡BUFFER�MGT�INITˆ(Copyright�1982�by�Motorola,�Inc.)‰PAGE‰NOLIST ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰LIST ‰SECTIONƒ8 ‰XREF†SZDBUF‰XDEF†SBINFRBFH*************************************************************************Æ*5*ˆSUBROUTINE:‚"SBINFRBF"‚INITIALIZE�THE�BUFFER�POOL‹**Æ*4*ˆENTER:‚A0.L�=�ADDRESS�OF�START�OF�MEMORY�SEGMENT�*+*�A1.L�=�ADDRESS�OF�END�OF�MEMORY�SEGMENT�**Æ*0*ˆRETURN:‚D1.W�=�NUMBER�OF�BUFFERS�INITIALIZED‘**Æ*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�* *˜D�U�R©* *˜A�U�U�U‰S�**ž|‰|_�stack–**ž|___________�used—**Æ*H************************************************************************+SBINFRBF�CLR.L…D1’INITIALIZE�NUM�OF�BUFFERS‰CLR.L…D0’FETCH�BUFFER�LENGTH‰MOVE.W„SZDBUF(PC),D0‡*‰ADD.W…#SDDLNG,D0Š*4INFRBF1‚MOVE.L„A0,A2…CALCULATE�NEXT�BUFFER'S�ADDRESS‰ADD.L…D0,A0…*!‰CMP.L…A0,A1…PAST�END�OF�SEGMENT?‰BLT.S…INFRBF2ƒ*,‰MOVE.L„A0,(A2)ƒNO,�PUT�LINK�INTO�1ST�BUFFER%‰ADD.W…#1,D1…INCREMENT�NUM�OF�BUFFERS‰BRA.S…INFRBF1ƒ*#INFRBF2‚SUB.L…D0,A2…CLEAR�LAST�LINK ‰CLR.L…(A2)†* ‰RTS‡RETURN‰ENDéééÍ(=/*=/*†SDLC.PORTAIO.AF=/**=/* Chain file to assemble SDLC.PORTAIO.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to SDLC.PORTAIO.LS=/*=/IFC \1ƒ=ARG�SDLC.PORTAIO.LS=/ENDIF=/*-=ASM SDLC.PORTAIO.SA,SDLC.PORTAIO.RO,\1;RZ=46=/*{ Included files are:=/*ƒ9995.&.NEC7201.EQ=/*ƒ9995.SDLCPRI.TEMPLTS.EQ=/*}=/*=END ééééééÖ)PORTAIO‚IDNT†1,0ƒPASS�INERRUPT�ON�TO�HDIO*ˆINCLUDEƒ9995.&.NEC7201.EQ!*ˆINCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰NOLIST‰INCLUDEƒ9995.&.NEC7201.EQ ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰LIST‰PAGE ‰SECTIONƒ9*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.*F***********************************************************************Ä*>*„PORTAIO�will�save�the�contents�of�the�7201�status�register†***„for�HDIO�and�then�give�control�to�HDIOš**Ä*.*ˆOn�entry:�D0�=�CONTENTS�OF�STATUS�REGISTER’*.*’A1�=�ADDRESS�OF�SDLC�PRIMARY�CONTROL�BLOCKˆ**Ä*'*’D0,A1�and�A2�are�saved�on�the�stack�*F***********************************************************************‰XREF†NECCTL_A ‰XDEF†PORTAIO*.PORTAIO‚BTST†#1,NECCTL_AŠIs�interrupt�pending?‰BNE.S…PORTAI1�Branch�if�YES/‰CMP.B…#SDPBTX,SDPBSY(A1)‚Is�SDLC�transmitting?‰BNE.S…PORTAI1�Branch�if�NO2‰MOVE.L„#4,D0�Set�interrupt�to�external�status�chg5‰MOVE.L„SDPVCT(A1,D0.W),A2‚SET�A2�to�vectored�routine‰JMP‡(A2)�Go�there+PORTAI1‚MOVE.L„8(A7),A2ŒRestore�original�A2:‰MOVE.L„SDPVECT(A1),8(A7)ƒOriginal�vector�content�to�stack:‰MOVE.L„SDPCCBA(A1),A1†Address�of�where�to�save�status�reg!‰BTST†#0,-1(A1)‹Is�this�for�HDIO?‰BEQ.S…PORTAI2�Branch�if�NO,‰LSR.W…#2,D0�Adjust�status�register�for�HDIO+PORTAI2‚MOVE.B„D0,(A1)�Save�status�register&‰MOVEM.Lƒ(A7)+,D0/A1‰Restore�registers‰RTS›Go�to�HDIO‰ENDééß+ =/*=/*†SDLC.PORTAV4.AF=/*1=/* Chain file to assemble module SDLC.PORTAV4.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to SDLC.PORTAV4.LS=/*=/IFC \1ƒ=ARG�SDLC.PORTAV4.LS=/ENDIF=/*.=ASM SDLC.PORTAV4.SA,SDLC.PORTAV4.RO,\1;RZ=120=/*{ Included files are:=/*ƒ9995.&.NEC7201.EQ=/*ƒ9995.SDLCPRI.TEMPLTS.EQ=/*}=/*=ENDééééééè3PORTAV4‚IDNT†1,0ƒMVME400,�PASS�INTERRUPT�ON�TO�HDIO*ˆINCLUDEƒ9995.&.NEC7201.EQ!*ˆINCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰NOLIST‰INCLUDEƒ9995.&.NEC7201.EQ ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰LIST‰PAGE ‰SECTIONƒ9*$*ˆCOPYRIGHTED�1983�BY�MOTOROLA,�INC.*F***********************************************************************Ä*>*„PORTAV4�will�save�the�contents�of�the�7201�status�register†*+*„for�HDIO�and�then�give�control�to�HDIO.™**Ä*C*„NOTE:�This�version�of�PORTAIO�is�specific�for�the�VME/10�system�*?*„using�an�MVME400�I/O�board�(containing�the�NEC7201�device).…**Ä*.*ˆOn�entry:�D0�=�CONTENTS�OF�STATUS�REGISTER’*.*’A1�=�ADDRESS�OF�SDLC�PRIMARY�CONTROL�BLOCKˆ**Ä*'*’D0,A1�and�A2�are�saved�on�the�stack�*F***********************************************************************J* We come here from INT7201 via the vector table found in the SDLC primaryK*�control�block.‚This�happens�when�the�NEC7201�presents�an�interrupt�vectorF*�of�4,�5,�6,�or�7�(all�of�which�are�A-side�interrupts).‚In�the�VME/10L* system (where an MVME400 board contains the 7201 device of interest), whenH* an interrupt occurs which uses the 7201's vector, we go to the INT7201J*�routine�(in�the�SDLC�code).‚There,�the�interrupt�vector�is�read�from�theI*�NEC7201�which�may�or�may�not�be�the�cause�of�the�interrupt.‚This�vectorL* will be from 0 to 7 (it is shifted left two places actually, but that factK*�is�only�"noise"�as�far�as�this�discussion�is�concerned).‚Vectors�0..3�areJ*�for�B-side�interrupts,�and�vectors�4..7�are�for�A-side�interrupts.‚Also,.* vector 7 is used for "no interrupt" as well.*K* INT7201 uses the vector number to compute which vector to use in its PCB.L* In practice, vectors 0..3 (B-side interrupts) will take us to some routine L* within the SDLC implementation, and vectors 4..7 will either bring us hereI* (when an A-side handler exists), or to INT7201A (when an A-side handler* does not exist).*I* When we come here, the 7201's vector is stored in "somebody's" CCB, andñ-ú"9* we vector off to an address that was placed in our PCB.*I* The MVME400 board contains two PIA devices (6821s) as well as the 7201.L* Because the handler we go to processes interrupts from these other devicesM* as well as the 7201, 1) we can't be sure that a given interrupt is actuallyK* from the 7201, and 2) we can't know if more than one device is in need ofI* service at this time (both PIAs and the 7201 could be interrupting - or%* needing to interrupt at this time).*K* So, when the routine we jumped to (via the vector in the PCB) is done, weL*�check�the�interrupt�pending�flag�in�the�NEC7201.‚If�the�flag�is�true,�thenL* the routine which just finished did not service the interrupt in the 7201.L* If the flag is clear, then either the routine did service the 7201, or the)* 7201 did not have an interrupt pending.*@* The rule for checking the interrupt pending bit is as follows;*G*„1)�Read�the�Interrupt�Vector�Register�(the�interrupt�pending�bit�will?*‡not�be�valid�until�this�is�done)�from�the�7201�(register�2B),E*„Then,�check�the�Interrupt�Pending�Bit�(register�2A).‚If�set�(1),�anA*Šinterrupt�is�pending,�and�the�vector�read�in�step�one�is�valid.@*ŠIf�clear�(0),�an�interrupt�is�not�pending,�and�the�vector�read*Šin�step�1�is�meaningless.E*„Note,�until�a�pending�interrupt�is�serviced�and�an�End�Of�Interrupt=*Šcommand�is�issued�(0A),�the�pending�bit�will�remain�set(1).G*„Note,�when�no�interrupt�was�pending,�the�pending�flag�will�not�becomeA*Šset�until�the�Interrupt�Vector�is�read.‚If�an�interrupt�was�notB*Špending�when�the�vector�was�read,�then�the�pending�flag�will�notE*Šbecome�set�until�the�vector�is�read�again,�no�matter�how�many�times-*Šthe�pending�flag�is�checked�in�the�interim.*I* What we do here is to read the interrupt vector register (see INT7201),D* vector to here when interrupt vectors 4, 5, 6, or 7 are presented,L* jump to the indicated address (he has to figure out if the 7201 is in needN* of service or not), and upon his completion, look to see if the 7201 pendingM*�flag�is�still�set.‚If�it�is,�then�the�routine�did�not�service�the�7201�yet,H*�and�we�need�to�give�him�another�chance.‚If�the�pending�bit�is�not�set,M* then either he did service the 7201 thereby clearing the pending condition,L* or there was no 7201 interrupt pending in the first place, and he probably* serviced one of the PIAs.*L* Note that we could have checked the pending flag immediately after readingJ*�out�the�vector�register.‚However,�knowing�whether�or�not�the�7201�is�theJ* cause of the interrupt is of no use to us once we get to PORTAIO anyway,K*�so�the�check�is�not�performed�at�first.‚Only�after�the�"somebody"�routineN* has run do we look to see if the interrupt is still pending, and then vector* to "somebody" again if it is. ‰XREF†NECCTL_A ‰XDEF†PORTAIO*6PORTAIO‚MOVE.L„SDPCCBA(A1),A2†A2�=�A("somebody's"�CCB)6‰MOVE.B„D0,(A2)�Store�7201's�vector�(%000xxx00)�to�CCB<‰MOVE.L„SDPVECT(A1),A2†A2�=�A("who"�we're�supposed�to�go�to)‰REPEAT0‹CLR.W…-(A7)�(VOR)�Build�an�interrupt-like�stack0‹PEA‡TSTINTP(PC)‰(PC)�which�will�come�back�to�us.‹MOVE.W„SR,-(A7)Œ(SR)�when�"they"�are�all�done‹JMP‡(A2)�Go�to�"them"8TSTINTP„BTST.B„#1,NECCTL_A‰7201�Interrupt�still�pending?4‰UNTIL…�if�so,�repeat�above�until�it's�satisfied9‰MOVEM.Lƒ(A7)+,D0/A1-A2†Recover�regs�which�INT7201�pushed‰RTE›and�exit�the�interrupt ‰END éé**ˆSDLC.ROOT.AG*!‰TTL‡SDLC�DRIVER,�GENERIC�SECTION'* Arguments substituted via SYSGEN are;**„VERSION�-�Version�number*„REVISIO�-�Revision�number#*„REVDATE�-�Date�of�latest�revision%*„CHIPTYP�-�MPU�type�-�68000�or�680107*„STATION�-�Station�type�-�1�(Primary)�or�2�(Secondary)<*„IFRMBCT�-�I_frame�byte�counts�included�-�1�(Yes)�or�0�(No)E*„RES7201�-�Board�containing�the�NEC7201�-�02�(VM02)�or�400�(MVME400)* ‰OPT‡MEX,CRE VER†EQU‡\VERSIONŒVERSION�NUMBER/REV†EQU‡\REVISIOŒREVISION�NUMBER�WITHIN�VERSION /CHIPTYPE�EQU‡\CHIPTYPŒMPU�TYPE�(68000�OR�68010) 8STATION‚EQU‡\STATIONŒSTATION�TYPE�(PRIMARY�OR�SECONDARY)#PRIMARY‚EQU‡1“PRIMARY�STATION�VALUE&SECONDAR�EQU‡2“SECONDARY�STATION�VALUE 4IFRMBCT‚EQU‡\IFRMBCTŒSEND/RCV�BYTE�COUNT�ON�I_FRAMES YES†EQU‡1NO‡EQU‡0 0RES7201‚EQU‡\RES7201ŒNEC7201�RESIDENT�BOARD�TYPE* 02 = VM02, or 400 = MVME400 ‰IFEQ†CHIPTYPE-68000 ‹OPT‡P=68000‹IFEQ†STATION-PRIMARY/SDLCPRI†IDNT†VER,REVƒ68000�SDLC�PRIMARY�STATION:�TTL‡68000�PRIMARY�STATION�(Copyright�1982/3�Motorola�Inc)‹ENDC‹IFEQ†STATION-SECONDAR1SDLCSEC†IDNT†VER,REVƒ68000�SDLC�SECONDARY�STATION<�TTL‡68000�SECONDARY�STATION�(Copyright�1982/3�Motorola�Inc)‹ENDC‰ENDC‰IFEQ†CHIPTYPE-68010 ‹OPT‡P=68010‹IFEQ†STATION-PRIMARY/SDLCPRI†IDNT†VER,REVƒ68010�SDLC�PRIMARY�STATION:�TTL‡68010�PRIMARY�STATION�(Copyright�1982/3�Motorola�Inc)‹ENDC‹IFEQ†STATION-SECONDAR1SDLCSEC†IDNT†VER,REVƒ68010�SDLC�SECONDARY�STATION<�TTL‡68010�SECONDARY�STATION�(Copyright�1982/3�Motorola�Inc)‹ENDC‰ENDC‰IFNE†CHIPTYPE-68000‹IFNE†CHIPTYPE-680100�FAIL†1�INVALID�CHIPTYPE,�MUST�BE�68000�OR�68010‹ENDC‰ENDC‰IFNE†STATION-PRIMARY‹IFNE†STATION-SECONDAR5�FAIL†1�INVALID�STATION,�MUST�BE�PRIMARY�OR�SECONDARY‹ENDC‰ENDC‰IFNE†IFRMBCT-YES‹IFNE†IFRMBCT-NO8�FAIL†1�INVALID�IFRMBCT�VALUE,�MUST�BE�1�(YES)�OR�0�(NO)‹ENDC‰ENDC‰IFNE†RES7201-02‹IFNE†RES7201-400;�FAIL†1�INVALID�RES7201,�MUST�BE�02�(VM02)�OR�400�(MVME400)‹ENDC‰ENDC‰IFEQ†RES7201-400 KL$‹XREF†MVME400ƒMVME400's�Base�Address‰ENDC‰PAGE‰INCLUDEƒSDLC.OVERVIEW.SI‰PAGE‰INCLUDEƒSDLC.MACROS.SI‰PAGE‰INCLUDEƒ9995.&.CRASH.MC‰INCLUDEƒ9995.&.NEC7201.EQ ‰INCLUDEƒ9995.SDLCPRI.TEMPLTS.EQ‰PAGE‰IFEQ†RES7201-400‹INCLUDEƒ9995.&.MVME400.EQ‹PAGE‰ENDC‰INCLUDEƒ9995.&.STR.EQ‰PAGE** NEC7201 Device Addresses*;‰XREF†NECCTL_A,NECCTL_B,NECDAT_A,NECDAT_B�NEC7201�Addresses ‰SECTIONƒ9 L*****************************************************************************‰DC.B†'**SDLC**'‰IFEQ†STATION-PRIMARY)‹DC.B†'PRIMARY�'ŠEYE-CATCHER�STATION�TYPE‰ENDC‰IFEQ†STATION-SECONDARY)‹DC.B†'SECONDAR'ŠEYE-CATCHER�STATION�TYPE‰ENDC‰IFEQ†CHIPTYPE-68000‹DC.B†'68000ƒ'ŠMPU�TYPE‰ENDC‰IFEQ†CHIPTYPE-68010‹DC.B†'68010ƒ'ŠMPU�TYPE‰ENDC‰IFEQ†RES7201-02‹DC.B†'VM02„'ŠBOARD�TYPE‰ENDC‰IFEQ†RES7201-400‹DC.B†'MVME400�'ŠBOARD�TYPE‰ENDC(‰DC.B†'\REVDATE'ŠDATE�OF�LATEST�REVISION*L*****************************************************************************;‰XDEF†PWRUP,SBSDLCRCST,SBUSRACK,SDLCQUSB,SDLCTMOUT,SDLCPRSB>‰XDEF†SDLCRCST,USRACK,SDLCQU,SDLCTTMOUT,SDLCPR,SBSDLCFL,SDLCFL*‰XDEF†INT7201,INT7201A,PWR,SDLCKL,SBSDLCKL*0‰XREF†SBGTFRIR,SBPTFRBF,SBPTFRML,SBPTUSQ,SDLCPCB‰IFEQ†CHIPTYPE-6  8000 ‹XREF†SBRQPA‰ENDC‰XREF†TRACFLAG,DLTRACE*‰IFEQ†STATION-PRIMARY‹INCLUDEƒSDLCPRI.POLLQ.SI‰ENDC‰IFEQ†STATION-SECONDARY‹INCLUDEƒSDLCSEC.PWRUP.SI‰ENDC‰INCLUDEƒSDLCPRI.INT7201.SI‰INCLUDEƒSDLCPRI.TRANSMIT.SI‰INCLUDEƒSDLCPRI.RECEIVE.SI‰IFEQ†STATION-PRIMARY‹INCLUDEƒSDLCPRI.FRMCNT.SI‰ENDC‰IFEQ†STATION-SECONDARY‹INCLUDEƒSDLCSEC.FRMCNT.SI‰ENDC‰INCLUDEƒSDLCPRI.SUBRTN.SI‰ENDéC‚******************************************************************‚*�SDLC.SYSCMD.CD1‚*„SYSGEN�Command�File�for�SDLC�driver�generation‚*4‚*„Create�an�SDLC�driver�for�a�specific�environment.‚*‚*„Arguments�are:*‚*‡Arg�1�=�Mnemonic�-�legal�mnemonics�are:‚* ‚*‘"GMADPRI"�-�GM�primary�system"‚*‘"GMADSEC"�-�GM�secondary�system$‚*‘"HDS4PRI"�-�HDS400�primary�system&‚*‘"HDS4SEC"�-�HDS400�secondary�system$‚*‘"VME10PRI"-�VME/10�primary�system‚*:‚*‡Arg�2�=�Overall�listing�file/device.‚Listing�is�handled‚*‘by�driver�chain�file.‚*K‚*�Each�time�maintenance�is�performed,�the�following�three�arguments�should1‚*�be�updated:�REVDATE�-�Date�of�latest�revision, ‚*�VERSION�-�Version�number,�and‚*�REVISIO�-�Revision�number.‚*/‚REVDATEƒ=�"09/07/83"ƒ*�Date�of�latest�revision‚VERSIONƒ=�3Œ*�Version�number‚REVISIOƒ=�7Œ*�Revision�number ‚*‚&LF‡=�0ŒLegal�mnemonic�flag ‚IFEQˆ"\1"‰,"GMADPRI"…&LF‡=�1…STATIONƒ=�1‰Primary�station…CHIPTYPƒ=�"68000"…RES7201ƒ=�02ˆVM02…SUBSˆSDLC.ROOT.AG3…ASM‰SDLC.ROOT.AG,SDLC.GMADPRI.RO,&.SYSGEN.TF;Z=100 …=COPY‡&.SYSGEN.TF,&.SYSASM.LS;A$…=COPY‡&.SYSGEN.TF,SDLC.GMADPRI.LS;Y‚ENDC‚IFEQˆ"\1"‰,"GMADSEC"…&LF‡=�1…STATIONƒ=�2‰Secondary�station…CHIPTYPƒ=�"68000"…RES7201ƒ=�02ˆVM02…SUBSˆSDLC.ROOT.AG3…ASM‰SDLC.ROOT.AG,SDLC.GMADSEC.RO,&.SYSGEN.TF;Z=100 …=COPY‡&.SYSGEN.TF,&.SYSASM.LS;A$…=COPY‡&.SYSGEN.TF,SDLC.GMADSEC.LS;Y‚ENDC‚IFEQˆ"\1"‰,"HDS4PRI"…&LF‡=�1…STATIONƒ=�1‰Primary�station…CHIPTYPƒ=�"68000"…RES7201ƒ=�02ˆVM02…SUBSˆSDLC.ROOT.AG3…ASM‰SDLC.ROOT.AG,SDLC.HDS4PRI.RO,&.SYSGEN.TF;Z=100 …=COPY‡&.SYSGEN.TF,&.SYSASM.LS;A$…=COPY‡&.SYSGEN.TF,SDLC.HDS4PRI.LS;Y‚ENDC‚IFEQˆ"\1"‰,"HDS4SEC"…&LF‡=�1…STATIONƒ=�2‰Secondary�station…CHIPTYPƒ=�"68000"…RES7201ƒ=�02ˆVM02…SUBSˆSDLC.ROOT.AG3…ASM‰SDLC.ROOT.AG,SDLC.HDS4SEC.RO,&.SYSGEN.TF;Z=100 …=COPY‡&.SYSGEN.TF,&.SYSASM.LS;A$…=COPY‡&.SYSGEN.TF,SDLC.HDS4SEC.LS;Y‚ENDC‚IFEQˆ"\1"‰,"VME10PRI"…&LF‡=�1…STATIONƒ=�1‰Primary�station…CHIPTYPƒ=�"68010"J$…RES7201ƒ=�400‡MVME400…SUBSˆSDLC.ROOT.AG1…ASM‰SDLC.ROOT.AG,SDLC.VME10.RO,&.SYSGEN.TF;Z=100 …=COPY‡&.SYSGEN.TF,&.SYSASM.LS;A"…=COPY‡&.SYSGEN.TF,SDLC.VME10.LS;Y‚ENDC ‚IFEQˆ\&LF6…MSG‰"\1"�is�an�invalid�mnemonic.�Legal�mnemonics�are:;…MSG‰"GMADPRI","GMADSEC","HDS4PRI","HDS4SEC",�or�"VME10PRI".…MSG‰Please�rerun�sysgen�with�proper�mnemonic.…ABORT‡‚ENDC 3‚IFRMBCTƒ=�1Œ*�Send�and�Receive�I_Frame�Byte�Counts ‚*�END�OF�SDLC.SYSCMD.CDC‚******************************************************************‚END‰é  éééé******************************** BEGINNING OF SDLC.MACROS.AI ******************************** RTS2RTE‚MACRO‰IFEQ†CHIPTYPE-680101‹MOVE.W„(A7),-(A7)ˆCREATE:�0(A7)�=�PC�(High�Word)1‹MOVE.W„4(A7),2(A7)‡.......�2(A7)�=�PC�(Low�Word).‹CLR.W…4(A7)�.......�4(A7)�=�VOR�(Short�Stack)‰ENDC6‰MOVE.W„SR,-(A7)ŒPush�SR�so�we�can�RTE�rather�than�RTS‰ENDM ************************** END OF SDLC.MACROS.AI **************************éééééé,6* ****************************************************6* * BEGINNING OF FILE 'FIX:48.SDLC.OVERVIEW.AI' *1*�*�Date�Revised:�September�7,�1983,�Ed�Skinner†**�*²*2*�*�Note:�This�is�a�"generated"�file.‚Updates�to„*3*�*�these�introductory�notes�should�be�applied�to„*2*�*�SDLC.OVERVIEW.PR�-�See�a�description�of�this…**�*�contained�herein. **�*²*6* ******************************************************** 1 Introduction*C*†The�Motorola�Synchronous�Data�Link�Control�(referred�to‚simply‚asG*�SDLC)‚is‚a‚component�of�the�Network�Services�facility�available�under * VERSAdos.B*†The�SDLC�implementation�provides�a‚communications‚circuit‚driverI*�using�the�NEC7201�device�in�the�bit-oriented�protocol�mode.‚Frame�levelI*�commands  �are�highly�similar�to�those�in�IBM's�SDLC.‚Support�is�providedG*�for‚the‚remote‚loading�and�dumping�of�stations,�multi-drop�as�well�asJ* point to point configurations, with circuit speeds of up to 57,600 baud. 5:>BFJNR&VZ^bfjnrvz~‚†Š E*†Because�of�the�many�configurations�within�which�this�implementationI*�must�function,�operation�is�limited�to�half-duplex�only�(at�the‚present* time).***"* 2 Overview of System Preparation*D*†The‚SDLC�implementation�exists�as�a�permanently�resident�extensionF*�of�the�system's�executive�(RMS68K).‚As�such,�it�is‚"link"ed‚with‚theE*�executive‚such‚that‚a‚single‚load�module�exists�containing�both�theE*�executive�and�the�SDLC�driver.‚Additionally,‚in‚those‚systems‚whereD*�Network‚Services‚(NTS)‚executes‚on‚the‚same�processor,�it�(NetworkE* Services) will be similarly "link"ed and loaded with the executive.D*†Generally�speaking,�a�version�of�the�SDLC�driver�is�first‚producedH*�which‚is�"customized"�for�the�target�system.‚The�parameters�which�makeG*�a�given�implementation�unique�include�the�type�of‚processor‚(68000‚orH*�68010),‚the‚residence�of�Network�Services�(on-board�or�off-board),�theD*�type�of�board�upon�which‚the‚communications‚device‚(an‚NEC7201)‚isG*�located,‚and‚the‚address�of�the�various�registers�of�that�device,�andC* whether the implementation is for a primary or secondary station.C*†Generation�of�the�SDLC�driver�is�facilitated�by�chain‚files‚which?*�"customize"ƒtheƒgeneric‚driver‚for‚one‚of‚the‚specific‚targetB*�environments.‚This‚"customized"‚version‚(an‚object‚file)‚is‚thenA*�combined‚with‚other‚modules‚(such‚as‚the‚RMS68K‚kernel,‚NetworkA*�Services,�and�so�on)‚to‚create‚a‚single‚load‚module.ƒThis‚final4* preparation is outside the scope of this document.B*†For‚the‚GMAD‚system,�the�primary�station�software�runs�on�a�VM02J* board, with Network Services executing on a tightly coupled Exormacs MPUH*�board.ƒA�shared�memory�facility�is�used�for�the�communications�between* Network Services and SDLC.D*†Similarly,�the�secondary�GMAD�station�software�also�runs�on�a‚VM02I*�board,‚except�that�its�Network�Services�is�on-board,�and�a�considerably=* simpler shared memory area is used for inter-communication.>*†Preparation�of‚the‚HDS-400‚Primary‚and‚Secondary‚stations‚is* similar to the GMAD stations.C*†The‚VME/10‚Primary�station�for�an�HDS-400�runs�on�a�VME/10�systemD*�using�an�MC68010�MPU�and‚MVME400‚board‚(which‚contains‚the‚NEC7201 * device).**** 3 SDLC Driver Preparation*@*†The‚first‚step,‚is‚to‚prepare�a�copy�of�the�informational�fileJ* (what you are currently reading) for inclusion into the assembly stream.F*�Note‚that‚this‚preparation‚need�be�done�only�if�the�SDLC.OVERVIEW.PRH*�input�file�has�been�updated.‚When�several�versions�of�SDLC�drivers‚areB*�to‚be‚generated,‚the‚OVERVIEW.CF‚(SDLC.OVERVIEW.CF)‚need‚only‚beH*�executed�before�generating�the�first�version.‚Once�this�has�been‚done,J* several different versions of the SDLC driver may be generated, re-using* the overview file./*†An�example�of�creating�this�overview�file�is;*†=USE�48.SDLC*†=OVERVIEW.CF)*‹=/*�CREATE�OVERVIEW.AI�FROM�OVERVIEW.PR1*‹=101.USERLIB.PROSE�OVERVIEW.PR,OVERVIEW.LS;Z=64*‹Version:�dd-mmmm-yy*‹No�errors�detected.*‹=DEL�OVERVIEW.AI#*‹DELETED�FIX:0048.SDLC.OVERVIEW.AI*‹=E�OVERVIEW.LS,OVERVIEW.AI;L*‹VERSAdos�EDITOR‚RELEASE‚x.y*‹COPYRIGHT�BY�MOTOROLA�19zz&*Ž(Example�output�deleted�for�brevity) *‹EDIT�DONE*‹=ENDE*†The�next�one�or�more�steps�consist�of�generating�version(s)�of�SDLCG*�as‚required‚for�the�target�system.‚SDLC�may�be�generated�as�a�primaryE*�or�secondary�station,�and�for�the�MC68000‚or‚MC68010‚processor.ƒTheE*�chain‚file‚which‚performs‚th  is�is�&.CONFIG.CF.‚It�is�always�invokedI*�with�two�arguments.‚The�first�argument�specifies�the�configuration,�theI*�second�argument�specifies�the�overall�listing�file�or�device.‚The�firstE*�argument�names�for�various‚SDLC‚configurations‚are:‚HDS-400‚PrimaryF*�Station‚("HDS4PRI"),‚HDS-400‚Secondary‚Station�("HDS4SEC"),�GMAD�DMSJ* (Primary) Station ("GMADPRI"), GMAD PMS (Secondary) Station ("GMADSEC"),/* and VME/10 HDS-400 Primary Station ("VME10").B*†The‚chain‚file‚produces�object�and�listing�files�appropriate�for"* the specified system as follows;*0* +--------------+--------------+--------------+!*�!‚Argument„!„Object„!ƒListing„!0* +--------------+--------------+--------------+)*�!‚"HDS4PRI"ƒ!‚HDS4PRI.RO‚!‚HDS4PRI.LS‚!)*�!‚"HDS4SEC"ƒ!‚HDS4SEC.RO‚!‚HDS4SEC.LS‚!)*�!‚"GMADPRI"ƒ!‚GMADPRI.RO‚!‚GMADPRI.LS‚!)*�!‚"GMADSEC"ƒ!‚GMADSEC.RO‚!‚GMADSEC.LS‚!&*�!‚"VME10PRI"‚!‚VME10.RO„!‚VME10.LS„!0* +--------------+--------------+--------------+** 4 Required Files*B*†The�following�files�are�the�minimum�set�required‚to‚generate‚all* versions of the SDLC driver;F*�&.SYSGEN.CF‚-‚The‚user‚invoked�chain�file�producing�SDLC�for�the�all*†SDLC�implementations.G*�SDLC.SYSCMD.CD�-�The�SYSGEN�command�file�used�in�the‚preparation‚of‚a*†version�of�the�SDLC�driver,F*�SDLC.ROOT.AG‚-‚The‚file‚"assembled"�to�produce�a�version�of�the�SDLCE*†driver,�as�directed�by�parameters�specified�by�the�user,�and�by�the*†SYSCMD.CD�command�file,G*�SDLC.OVERVIEW.CF‚-‚The‚chain�file�which�causes�SDLC.OVERVIEW.AI�to�be7*†created�from�SDLC.OVERVIEW.PR�via�the�PROSE�facility,9*�SDLC.OVERVIEW.PRƒ-ƒTheƒ"prose"ƒinput„file,„processed„by3*†SDLC.OVERVIEW.CF,�which�creates�SDLC.OVERVIEW.AI,G*�SDLC.OVERVIEW.AI‚-‚Created‚from�SDLC.OVERVIEW.PR�by�SDLC.OVERVIEW.CF,B*†this�file�presents�a�gross�overview�of�the‚implementation,‚and‚a'*†list�of�known�problems�and/or�errors,0* 9995.&.NEC7201.EQ - Defines NEC7201 Symbolics,2* 9995.&.STR.EQ - Defines RMS68K Kernel Symbolics,3* SDLCPRI.TEMPLTS.EQ - Defines SDLC Control Blocks,;* MVME400.EQUATES.AI - Defines the MVME400 board Symbolics,A* SDLC.MACROS.AI - Defines miscellaneous macros required by SDLC,F*�SDLCPRI.POLLQ.AI‚-‚Primary‚Station,‚External�(User)�Interfaces,�SDLC(*†Start�Up�Logic,�and�Polling�Algorithm,D*�SDLCPRI.INT7201.AI�-‚Primary‚Station,‚Transmitter‚Flush‚Logic,‚and*†NEC7201�Interrupt�Dispatcher,;* SDLCPRI.TRANSMIT.AI - Primary Station Transmitter Driver,7* SDLCPRI.RECEIVE.AI - Primary Station Receiver Driver,4* SDLCPRI.FRMCNT.AI - Primary Station Frame Handler,)* SDLCPRI.SUBRTN.AI - Common Subroutines,H*�SDLCSEC.PWRUP.AI‚-‚Secondary�Station,�External�(User)�Interfaces,�SDLC5*†Start�Up�Logic,�and�Polling�Response�Algorithm,�andD*�SDLCSEC.FRMCNT.AI�-�Secondary‚Station‚Frame‚Handler,‚and‚Link‚Mode*†Finite�State�Machine.**** 5 Primary Station Files*@*†The�following�files�comprise�the�primary�station's�generation;* SLDC.ROOT.AG,* SDLC.OVERVIEW.AI,* 9995.&.NEC7201.EQ,* 9995.&.STR.EQ,* SDLCPRI.TEMPLTS.EQ,* SDLC.MACROS.AI,* MVME400.EQUATES.AI,* SDLCPRI.POLLQ.AI,* SDLCPRI.INT7201.AI,* SDLCPRI.TRANSMIT.AI,* SDLCPRI.RECEIVE.AI,* SDLCPRI.FRMCNT.AI, and* SDLCPRI.SUBRTN.AI.**** 6 Secondary Station Files*B*†The�following�files�comprise�the�secondary�station's�generation;* SLDC.ROOT.AG* SDLC.OVERVIEW.AI,* 9995.&.NEC7201.EQ,* 9995.&.STR.EQ,* SDLCPRI.TEMPLTS.EQ,* SDLC.MACROS.AI,* MVME400.EQUATES.AI,* SDLCSEC.PWRUP.AI,* SDLCPRI.INT7201.AI,* SDLCPRI.RECEIVE.AI,* SDLCSEC.FRMCNT.AI,* SDLCPRI.TRANSMIT.AI, and* SDLCPRI.SUBRTN.AI.**** 7 ROM-based Version Files*9*†The�files�which�comprise�SDLCROM�are�currently�unknown.**** 8 Primary Data Flows*>*†The‚primary‚data‚flow‚into‚SDLC‚is‚via�the�SBPTXMQ�and�PTXMQI*�functions�which�are�located�in�the�buffer�management�module�(BUFMGT‚andH*�BUFMGTX).ƒThese�functions�enqueue�a�transmit�buffer�to�t  he�appropriateI*�Secondary�Control�Block�(SCB)�where�the�SDLC�driver�will�find�it�at‚theF*�proper‚time.ƒIn‚the�primary�station,�the�SBPTXMQ�and�PTXMQ�functionsH*�"awaken"�SDLC�each�time�a�buffer�is�enqueued�by�calling�the‚SDLC‚entryF*�point‚SDLCQUSB‚or‚SDLCQU�function.‚In�the�secondary�station,�SDLC�is?*�not‚"awakened"‚when‚a‚buffer‚is‚enqueued.ƒIn‚anƒEXORMACS/VM02J* configuration, buffers are passed from the EXORMACS to the VM02 thru the* VM02 request queue.>*†The�primary�data�flow�from‚SDLC‚is‚via‚the‚SBPTUSQ‚and‚PTUSQI*�functions‚which�are�located�in�the�buffer�management�module�(BUFMGT�andG*�BUFMGTX).‚When�SDLC�has�received�an�error�free�transmission‚(which‚isB*�not‚an‚internally‚used‚SDLC‚control‚frame),‚the‚SBPTUSQ�or�PTUSQD*�function�is�called�and�the�received‚buffer‚is‚enqueued‚to‚the‚userI*�queue.‚In�an�EXORMACS/VM02�configuration,�the�user�queue�passes�buffers * from the VM02 to the EXORMACS.C*†In�general,�all�information�frames�(I_frames)‚contain‚applicationH*�program‚data,‚supervisory�frames�(S_frames)�are�used�internally�by�theI*�various�SDLC�stations�on�a�link,�and�un-numbered�(U_frames)�are�used‚to* control the mode of the link.C*†It‚is‚very�important�to�note�that�U_frames�are�never�"created"�orI*�"consumed"�by�the�SDLC�module:‚They�are�always�initiated�and�terminatedE*�outside‚of‚SDLC.ƒ"Hand-shake"‚procedures�exist�between�SDLC�and�theH*�U_frame�creator�and�consumer�to�assist�in�the�synchronization‚of‚these* two processes.**** 9 Entry Points*C*†External‚entry‚points�are�provided�within�the�SDLC�implementation* for the following conditions;*@* +----------+------+------------------------+-----+-----+-----+8*�!�Entry„!�Type�!�Input�Description†!�Pri�!�Sec�!�ROM�!@* +----------+------+------------------------+-----+-----+-----+;*�!�PWRUP„!�Subr�!�Start�SDLC�Operationƒ!�Yes�!�Yes�!�Yes�!2*�!�PWR†!�Intr�!�NEC7201�A-Side�Intr„!‚?‚!‚?‚!‚?‚!<*�!�INT7201‚!�Intr�!�NEC7201�B-Side�Intr„!�Yes�!�Yes�!�Yes�!=*�!�INT7201A�!�Intr�!�NEC7201�A-Side�Intr„!�Yes�!�Yes�!�Yes�!+*�!�SDLCQXMT�!�Subr�!�Unknown�!‚?‚!‚?‚!‚?‚!>*�!�SDLCQUSB�!�Subr�!�Send�Traffic�Enqueued‚!�Yes�!�No‚!�Yes�!<*�!�SDLCQUƒ!�Trap�!�Send�Traffic�Enqueued‚!�Yes�!�No‚!�Yes�!?*�!�SBUSRACK�!�Subr�!�Ack�SIM,�DISC,�or�SNRM�!�No‚!�Yes�!�Yes�!=*�!�USRACKƒ!�Trap�!�Ack�SIM,�DISC,�or�SNRM�!�No‚!�Yes�!�Yes�!>*�!�SDLCTMOU�!�Subr�!�Receive�Timer�Expired‚!�Yes�!�Yes�!�No‚!>*�!�SDLCTTMO�!�Trap�!�Receive�Timer�Expired‚!�Yes�!�Yes�!�No‚!:*�!�SDLCKLƒ!�Trap�!�Terminate�Operation„!�Yes�!�Yes�!�No‚!<*�!�SBSDLCKL�!�Subr�!�Terminate�Operation„!�Yes�!�Yes�!�No‚!9*�!�SDLCPRSB�!�Subr�!�50�mSecond�Tickˆ!�Yes�!�Yes�!�***�!7*�!�SDLCPRƒ!�Trap�!�50�mSecond�Tickˆ!�Yes�!�Yes�!�***�!=*�!�SDLCFLƒ!�Trap�!�Flush�All�Send�Traffic�!�Yes�!�Yes�!�No‚!?*�!�SBSDLCFL�!�Subr�!�Flush�All�Send�Traffic�!�Yes�!�Yes�!�No‚!<*�!�SDLCRCST�!�Trap�!�Buffer(s)�Now�Exist„!�No‚!�Yes�!�Yes�!<*�!�SBSDLCRC�!�Subr�!�Buffer(s)�Now�Exist„!�No‚!�Yes�!�Yes�!@* +----------+------+------------------------+-----+-----+-----+*F*�***�SDLCROM�executes�without�the�aid�of�"timers",‚and‚so‚these‚entry,* points are never used in actual operation.***'* 10 Support Functions and/or Variables*C*†Externally‚defined‚routines�which�are�used�by�this�implementation* are;I*�SBGTFRIR�-�FOREGROUND�(interrupt�handler)�USE�ONLY,�get�one�buffer‚fromE*†the�free�pool�regardless�of�the�low�water�mark�and�how�many�buffers *†remain,1* DLTRACE - add an entry to the SDLC trace table,.* SBPTFRBF - return a buffer to the free pool,2* SBPTFRML - return many buffers to the free pool,1* SBPTUSQ - put a buffer into the user queue, andF*�SBRQPA�-�(RMS68K�kernel�entry�point)�request‚a‚periodic‚activation‚-B*†Note‚that‚the�use�of�this�function�is�being�phased�out.‚ExistingD*†versions�(based�on�the�MC68000�MPU)�continue�to�use�this‚function,;*†andƒthereforeƒrequireƒLINK'ing‚with‚the‚associated‚RMS68KC*†functions.‚Newer�versions�(based  �on�the�MC68010�MPU)�will�use‚theE*†TRAP�#0�instruction�to�access�the�same�function,�and�so�do�not�need'*†to�be�LINK'ed�with�the�RMS68K�Kernel.:* Additionally, various RMS68K functions are used by SDLC.*C*†Externally�defined�symbolic�variables�used�by‚this‚implementation* are;D* NECCTL_A - address of the NEC7201 device control register, Port A,D* NTCCTL_B - address of the NEC7201 device control register, Port B,A* NECDAT_A - address of the NEC7201 device data register, Port A,A* NECDAT_B - address of the NEC7201 device data register, Port B,5* SDLCPCB - pointer to the Primary Control Block, and2* TRACFLAG - trace wanted (least significant bit).**** 11 Known Problems*@*†The‚following‚paragraphs‚detail‚the‚"known"�problems�which�areD*�either�thought�to�be�within‚this‚SDLC‚implementation,‚or‚that‚haveI*�significant�bearing�on�SDLC's�performance.‚The�order�of�presentation�of'* these problems is of no significance.*G*�Thruput�Improvement�-�The�overall�system�thruput�could‚be‚improved‚byE*†adding�a�transmission�to�a�secondary�system�after�receiving�traffic@*†from�it.‚Presently,�when�a‚secondary‚station‚transmits‚inboundC*†traffic,‚it‚must�wait�for�the�next�poll�before�it�"finds�out"�howA*†many�frames�the�primary�station�received.‚During‚this‚period‚of6*†time,ƒseveralƒbuffersƒmayƒbeƒtiedƒup‚waiting‚for‚theC*†acknowledgement.‚If�the�primary�station�were�to�transmit�an�RR‚orA*†RNR‚(without‚the‚poll‚bit)�after�receiving�the�final�bit�from�a<*†secondary‚(assuming‚that‚informationƒframesƒwereƒreceived,E*†otherwise�the�extra�transmission�is�extraneous),�then�the�secondary<*†station‚would‚immediately‚know‚how‚many‚of‚its‚frames‚wereA*†successfully‚received‚by‚the�primary�station.‚This�change�would?*†have�a�significant�impact‚during‚the‚upload‚process‚where‚the7*†secondaryƒstationƒonlyƒhasƒfourƒbuffersƒto‚play‚with.A*†Unfortunately,�Network�Services�appears�to�be‚unable‚to‚keep‚up>*†with‚the‚current‚upload‚rate,‚and‚this‚proposed�change�would?*†significantly�accelerate‚the‚upload‚thruput‚thereby‚causing‚a+*†resource�shortage�in�the�primary�station.J* Architectural Problem - Use of the Low Water Mark facility of the buffer?*†pool�is�incorrect.ƒGenerally‚speaking,‚routines‚which‚consumeE*†system�buffers�should�be�subject�to�the�Low�Water�Mark,�while�those@*†which�return�buffers�to�the�pool,‚or‚that‚initiate‚some‚actionC*†which‚will‚cause�buffers�to�be�returned�to�the�pool�should�not�beA*†subject�to�the�Low�Water�Mark.‚Presently,�there�are‚a‚couple‚of@*†exceptions‚to‚these‚guidelines.ƒSpecifically,�the�SDLC�traffic>*†receive�routines�are�not�subject‚to‚the‚Low‚Water‚Mark:ƒThey;*†shouldƒbe.ƒThe‚NTS‚functions‚which‚perform‚the‚connectionE*†tear-down�(disconnect,�etc)�are�subject�to�the�Low�Water�Mark:�They>*†should‚not‚be.ƒBecause‚of‚these‚"mis-architected"�functions,C*†dead-lock�situations�occur�when�a�node�receives�to�a‚traffic‚loadB*†which‚exceeds‚its�thruput.‚All�buffers�are�consumed�with�receive@*†traffic,�and�no�buffers�are‚left‚to‚send‚application-level,‚orE*†definite�response�traffic�which�would�uncommit�some�of�the�received *†buffers.C*�Performance�Problem�-‚The‚primary‚station‚is‚not‚re-enabling‚it'sE*†receiver�soon�enough�between�successive�receptions�when�the�sendingC*†secondary�station�is�running�in�its�ROM�version�and�is‚sending‚an>*†upload.ƒThe‚primary‚receives‚the‚first‚and�third�information>*†frames,�but�misses�the‚second‚one.ƒThis‚results‚in‚excessive*†upload�durations.G*�Unknown‚Cause‚-‚A�"Receive�buffer�overrun"�error�occurs�approximatelyE*†every�four�frames�when�receiving�an�upload�from�a�secondary�stationB*†running‚in‚it's�ROM�version.‚This�problem�is�most�likely�relatedA*†to�the�preceeding�problem.‚However,�the�sequence‚of‚events‚that=*†lead‚to‚the‚receive‚buffer‚overrun‚error‚are�a�mystery:‚TheC*†secondary�station�should�not�be�sending�over-length‚messages,‚and@*†error‚recovery‚in‚the‚primary‚should�prevent�other�errors�from*†"tur  ning�into"�this�error.F*�Unknown�Cause�-�A�secondary�station�is�apparently‚getting‚stuck‚in‚a@*†Frame‚Reject‚state‚thereby‚preventing‚that�station�(only)�from*†completing�a�restart.I*�Unknown�Cause�-�Cessation�of�down-load�during�stress�periods�requires‚a?*†reboot‚of‚the‚entire‚system.ƒThis�situation�is�rare,�and�onlyE*†occurs�when�one�or�more�uploads�are�in�progress�at�the�same�time�as@*†downloads.ƒA‚"dead-lock"‚situation‚occurs�where�all�the�systemA*†buffers�are�in�use,�and�another�buffer�is�needed‚to‚free‚up‚anyB*†buffers.ƒThere‚may�be�other�problems�which�appear�to�be�the�sameA*†as�the�dead-lock�situation.‚This�may�be�an‚overall‚buffer‚usageB*†problem,‚or‚an‚NTS�problem�rather�than�a�specific�problem�in�the*†SDLC�implementation.E*�Architectural�Problem�-�If�a�secondary‚fails‚(or‚is‚manually‚reset)A*†while‚a‚download‚is‚in�progress�to�that�secondary,�the�state�ofC*†that�station�as�recorded�in�the�primary�occasionally‚prevents‚theC*†flushing‚of�traffic.‚This�causes�a�large�number�of�system�buffers>*†to�be�tied�up�for�an�extended�period�(conceivably,�forever).H*�Architectural�Problem�-�The�download�(and�upload)�processes‚contain‚noE*†data�rate�regulating�mechanisms�and�tend,�therefore,�to�drive�otherA*†parts�of�the�system�into�error�recovery‚situations‚by‚placing‚aB*†severe‚load‚on�the�system�unnecessarily.‚Due�to�the�difficultiesD*†in�correcting�this�problem,�no�practical�solution�appears�to‚existA*†at‚this‚time.ƒ(These�"difficulties"�include�the�need�to�totallyD*†revamp�how�uploads�and�downloads�are�performed�across�all‚products-*†currently�using�Network�Services�and�SDLC.)D*�Unknown‚Cause‚-‚An‚excessive‚retransmission‚error�is�occuring�on�a8*†download‚information‚block.„Theƒblockƒshouldƒhaveƒbeen>*†acknowledged‚by‚the‚loaded‚secondary,‚or‚it‚should�have�been@*†flushed�upon�download�completion.‚Either‚of‚these‚events‚would?*†prevent‚the‚excessive‚retransmission‚error‚which‚is�occuring.?*†There�is,�ostensibly,�no�problem�with‚this.ƒBut‚the‚system‚is'*†indicating�some�error,�none�the�less.F*�Unknown‚Cause‚-‚Apparently‚a�message�is�occasionally�being�discarded>*†erroneously�during‚the‚download‚and/or‚restart‚process.ƒThisD*†causes‚the�affected�secondary�station�to�be�unable�to�complete�itsA*†restart�and�requires�the�manual�resetting�of‚that‚station.ƒThis<*†problemƒmayƒbe‚related‚to‚the‚aforementioned‚architectural%*†difficulties�concerning�link�reset.@*�Architectural‚Problem‚-‚The‚"cooperation"‚between‚SDLCƒandƒNTSC*†concerning‚link‚reset�and/or�restart�is�faulty�due�to�a�number�ofC*†problems�in�the�architecture�of�this�area.‚The�"problems"�lead‚to1*†dead-lock�and/or�poor�performance�fairly�often.D*�Architectual‚Difficulty‚-‚RMS68K‚handling‚of‚set�date�and�time�may>*†result�in‚several‚seconds‚of‚computation‚with‚all‚interruptsC*†masked.ƒNTS/SDLC�"feels"�this�by�missing�transmission(s)�from�theC*†primary�station,�and�loosing�contact�for�several�seconds.‚As‚thisE*†only�occurs�when�a�secondary�station�is�re-starting,�the�problem�isD*†minor�the�problem�is�considered�to�be�an�"annoyance"�rather�than‚a=*†"problem".ƒCorrection‚of‚this‚problem‚may‚be‚implemented�byE*†changing�the�algorithm�within�RMS68K�and/or�by�revamping�the�"powerD*†on"�/�"power�off"�decision�criteria�within�SDLC.‚Regardless�of�theC*†RMS68K�changes,�the�SDLC's�up/down�criteria�should�be‚revamped‚as@*†the‚present‚implementation‚is‚crude‚and�"over-reacts"�to�minor*†transgressions.G*�Hardware�Problem�-�If�a�secondary�(or�the�primary)‚station‚fails‚suchC*†that‚it‚is�unable�to�perform�a�reset�of�the�communications�deviceD*†(NEC�7201),�and�the�failure�occurs�at�a�time�when�that�station‚hasA*†its‚transmitter‚enabled,‚the‚communications�circuit�will�be�"in?*†use"�for�an�indefinate�period�and‚no‚stations‚will‚be‚able‚to=*†communicate.ƒThis‚situation‚will‚continue‚until‚the‚failingC*†station�is�identified�and�disconnected�from�the�circuit.‚The‚mostD*†expedi  tious‚method�for�resolving�this�problem�is�to�1)�verify�thatE*†it�is�occuring�-�a�line�monitor�will�display�a�continuous�stream�ofC*†data‚on‚the�circuit�-�normally�the�same�byte�over�and�over�again,E*†and�then�to�2)�begin�disconnecting�secondary�stations�one�at�a�timeC*†until‚the�line�monitor�indicates�a�cessation�of�this�pattern.‚TheB*†continuous�transmission�will�cease�when�the‚offending‚station‚isD*†disconnected.‚Alternatively,�secondary�stations�may�be�powered�off@*†rather�than�being�disconnected.‚This‚condition‚(of‚a‚secondaryE*†"hogging"�the�circuit)�is�very�difficult�to�identify�in�the�primaryD*†station's�software,�and�it�is�uncertain�if�any�automatic‚procedureC*†can‚be‚initiated�by�the�primary�to�resolve�this�situation�even�if%*†it�could�determine�that�it�existed.*0* **********************************************0* * END OF FILE 'FIX:48.SDLC.OVERVIEW.AI' *0* **********************************************ééE1BEGSDLC ASREL' SDLC BEGSDLC SAQ(…Beginning of SDLC segment2IBEGSDLC )3 `þ4éééééééŽI1BUFMGT ASREL' SDLC BUFMGT SAQ(…BUFFER MANAGEMENT SUBROUTINESó2pUSERQHD pUSERQND pSDLCPCB ISBPTFRML ISBGTUSQ pSDLCQUSB ISBPTUSQ ¼ISBPTXMQ 6IGTFRBF LpFQBCNT IGTFRIR IPTFRBF âIGTFRML žpFQLW  M IPTFRML pNATBEG IGTUSQ IPTUSQ ¶\2IPTXMQ 0pFREEQHD ISBGTFRBF RISBGTFRIR ISBPTFRBF èISBGTFRML ¤)JF3 P@ a@×Ns@ç||Sy(nk|&y(#Ó(F×B“FßNuRy(F×B/&|ÿÿÿÿF3 J FßNua@×Ns@ç||09(°y(o"Sy(k y(#Ð(F×B�FßNuRy(F×B/F3 |ÿÿÿÿFßNua@×Ns@çB/BgB§JAoÿý`ašf| —.ˆRoQÉÿì| _F3 2n |ÿÿÿÿFßNua@×Ns@ç±ügÿý| ¹(#È(Ry(Fß |ÿÿÿÿNua@×NsF3€  @J€g aÂ`ô |ÿÿÿÿNua@×Ns@çB€±ügÿý( "y("iD ÿg°gF3 ÓüXJfò|FßNuBhB( B( B�i|$iJ©fEé#H$ˆI3Š BiF×aB þ\| |ÿÿÿÿFßNua@×Ns@ç gÿýB�|$y( fEù(#È($ˆF3  Fß 9(g @pÀü&Að hpN@ |ÿÿÿÿNua@×Ns@ç|| 9(g @#Ð&3� (fB¹(F×B�FßNuF×B/ |ÿÿÿÿFßNu4ééé—I1BUFMGTX ASREL' SDLC BUFMGTX SAR (…BUFFER MANAGEMENT SUBROUTINESö2pUSERQHD pUSERQND pSDLCPCB ISBPTFRML  pSYSPOFF pSDLCQXMT ISBGTUSQ LpSDLCQUSB ISBPTUSQ ÂISBPTXMQ *IGTFRBF ¢pFQBCNT IGTFRIR IPTFRBF †IGTFRML @pFQLWM pMEMOFF IPTFRML pNATBEG …2IGTUSQ FIPTUSQ ¼IPTXMQ $pFREEQHD pFREEQND ISBGTFRBF ¨ISBGTFRIR ISBPTFRBF ŒISBGTFRML F)ºF3P� a@×Ns@ç/ |"x J¸ fÿýFï|Jé kòfÿýSi n kF|B© F3B  &i —ü€×ø Ófÿý#S © gÿýFïB“B«B«B« "_FßNuRi F3 fÿý© gÿýFïB/&|ÿÿÿÿ"_FßNua@×Ns@ç|/ "x Fï|JéF3…"„ kòfÿý0) °i oPSi nk@B©  i ‘ü€Ñø Ðfÿý#P © gF3 ÿýFïB�B¨B¨B¨ "_FßNuRi fÿý© gÿýFïB/ |ÿÿÿÿ"_FßNuF3 a@×Ns@çB/BgB§JAoÿý`aÿNf| —.ˆRoQÉÿê| _2n |ÿÿF3 ÿÿFßNua@×Ns@ç/ ±ügÿý"x B�Fï|Jé kòfÿý © �gÿý‘øF3… P€ Ñü€#H J© fJi fÿý‘ü€#H Ri oÿý© gÿýFï"_ |ÿÿI3 ÿÿFßNua@×Ns  @J€g aÿt`ò |ÿÿÿÿNua@×Ns@ç±ügÿýJ¸ gaB ýÂF3@ |FßNuB€( "x "iD ÿg°gÓüXJfò|FßNuBhB( B(I3 B�i|$iJ©fEé#H$ˆBiF×aB ýV| |ÿÿÿÿFßNua@×F3E$ Ns@ç gÿý"x B�F×|Jé kôfÿý ) g@$@Õø ‘ø $ˆ#H © gÿýF3  F× 8 g @pÀü&Að hpN@ |ÿÿÿÿFßNu‘ø #H Ñü€#H © gF3„ ÿýF×`¼a@×Ns@ç|"x F×|Jé kôfÿý ) €J€g, @Ñø J�fB©@3‚@ Ðfÿý#P © gÿýF×B�FßNu© gÿýF× |ÿÿÿÿB/FßNu4éé   I1DLTRACE ASREL' SDLC DLTRACE SAS#(…TRACE INTERRUPTS ON DATA LINKA2pSDLCPCB pNECCTL_A pNECCTL_B IDLTRACE pTRACEBEG )@<3@@@ $y($R4ï$ï4À$ñù(ù(Eê"y(µémEé"Š"y(Nu4ééééééé©,1EXORDLC ASREL' SDLC EXORDLC SAS5(…}2JSBSDLCFL $pSYSPOFF JSBSDLCKL 8JSBUSRACK JSDLCQXMT .JSDLCQUSB ’pMEMOFF pV2RQHD pSBGTFRBF *”H3 .,<¡aA ög <ÿT—` 1GFa Nu.,<¢`Ú|a NuB‡,<£F3�� `Æ/ "y(B�‘ù(Jé kúCé  €J€g"@Óù( fô"ˆ"y(© ` /×3 "Ÿ‘"_NuNu4éééé éé²' SDLC IBFMGT ROÇÇrrPORTAIO ROÐÐrrPORTAV4 ROÙÙrrM1IBUFMGT ASREL' SDLC IBFMGT SAT(…BUFFER MANAGEMENT INIT SUBROUTINE 2pSZDBUF HSBINFRBF ( (3 B�B€0:A ú@$HÑÀ³Èm$ˆRA`ò•ÀB’Nu4ééééééé¿ D1PORTAIO ASREL' SDLC PORTAIO SAT4(…PASS INERRUPT ON TO HDIO 2IPORTAIO pNECCTL_A ):>3 9(f )Ofp$qNÒ$o/iT"iX)ÿÿgäH€LßNu4éééééééÈN1PORTAV4 ASREL' SDLC PORTAV4 SATW(…MVME400, PASS INTERRUPT ON TO HDIO 2IPORTAIO pNECCTL_A )$(3 $iX€$iTBgHz@çNÒ9(fìLßNs4éééééé éÑ' TEST OUTTERM AFæærrOUTTERM SAïïrrOUTTERM ROøørr=/*=/*†TEST.OUTTERM.AF=/*1=/* Chain file to assemble module TEST.OUTTERM.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to TEST.OUTTERM.LS=/*=/IFC \1ƒ=ARG�TEST.OUTTERM.LS=/ENDIF=/*)=ASM TEST.OUTTERM.SA,TEST.OUTTERM.RO,\1;R=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDééééééÞ,OUTTERMƒIDNTƒ1,0�Put�Message�out�to�terminal**ˆPUT�MESSAGE�OUT�TO�TERMINAL* ‰OFFSET„0OUTPB„DS.W†1ˆ2=�WRITE�COMMAND‰DS.W†1ˆ8=�IMAGE�MODE ‰DS.W†1ˆ6=�LU‰DS.W†3OUTPBSA‚DS.L†1‰START�ADDRESSOUTPBEA‚DS.L†1‰END�ADDRESS‰DS.L†2 ‰SECTI ONƒ14**„ON�ENTRY:‚A1=START�ADDRESS*�A2=END�ADDRESS* ‰XDEF†OUTTERMOUTTERM‚LEA‡OUTPB(A6),A0‰MOVE.L„A1,OUTPBSA(A0)‰MOVE.L„A2,OUTPBEA(A0)‰MOVE.W„#2,(A0)…COMMAND‰MOVE.W„#8,2(A0)„OPTIONS‰MOVE.W„#6,4(A0)„LU ‰CLR.L…6(A0) ‰CLR.W…10(A0) ‰CLR.L…20(A0)‰TRAP†#2‰RTS‰ENDéééééçG1OUTTERM ASREL' TEST OUTTERM SAU!(…Put Message out to terminal2NOUTTERM .*03AÖ!I !J0¼1|1|B¨Bh B¨NBNu4ééééééé ð' VM02 STRSDLC AFrrSTRSDLC SArrVEC7201 AGrrSTRSDLC RO  rr=/*=/*†VM02.STRSDLC.AF=/**=/* Chain file to assemble VM02.STRSDLC.SA=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to VM02.STRSDLC.LS=/*=/IFC \1ƒ=ARG�VM02.STRSDLC.LS=/ENDIF=/*;=ASM VM02.STRSDLC.SA/&.STRSDLC.SA,VM02.STRSDLC.RO,\1;RZ=100=/*{ Included files are:=/*ƒ9995.SDLCPRI.TEMPLTS.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.TST.EQ=/*ƒ9995.HDIO.HDIO.EQ=/*ƒ9995.INET.INET.EQ=/*}=/*=ENDééééééý#************************************�File�VM02.STRSDLC.SAŒ*#************************************TYPEBD„EQU„02‡*�VM02�BoardŠPAGEé éééééé**ˆVM02.VEC7201.AG* ŠSECTION�8 ŠXDEFƒVEC7201=VEC7201ƒEQU„\V2G1IR6‹*�NEC7201�uses�the�Group�1,�IRQ�6�vector%ŠNOP—Must�have�code�to�satisfy�linkerŠENDééééééé 91STRSDLC ASREL' STRSDLC SAU%(…Start up SDLCx2pPORTAIO pSYSTYPE pVEC7201 pINT7201 pINT7201A pBEGSDLC pPWRUP pTRACFLAG pTRACEBEG HSTRSDLC (8H3@ :A þgNu&lAú pN@` `ÔHDIO*H0<"m6Eé "FIX:48.SDLCSEC.FRMCNT.AI' *5***************************************************** I* NOTE: I THINK THIS PROCEDURE (TRANSEQ) IS ALWAYS THE WRONG THING TO DO!@*‡WE�WILL�RE-USE�THE�FIRST�BUFFER�IN�THE�RECEIVE�QUEUE.‚IS�THEREE*‡ALWAYS�ONE�THERE?‚IS�IT�OK�TO�RE-INITIALIZE�ITS�BYTE�COUNT,�STATUS,3*‡ERROR,�RETRY�COUNT,�AND�SECONDARY�STATION�NUMBER?L* This situation (reaching the end of the transmit queue without sending the;*‡final�bit�should�occur�only�as�a�result�of�a�FLUSH�order.* ED SKINNER, MARCH 3, 1983 &‰FAIL†501‡TRANSEQ�IS�VERY,�VERY�WRONG! *TRANSEQ‚EQU‡*‰TRANSMIT�(END�OF�QUEUE)�EXIT/‰MOVE.L„SDPRCV(A5),A2�TRANSMIT�AN�"RR"�RESPONSE ‰CMPA.L„#0,A2‰CRASH.EQ‚*+1‡DIE�IF�NO�BUFFER! ‰MOVE.B„#SDDRRR+$10,SDDCMD(A2)�*‰BRA.L…VCTINIT6‚* &TRANSPB‚EQU‡*‰TRANSMIT�(POLL�BIT)�EXIT@‰MOVE.L„SDPRCV(A5),A3�TxMITTED�A�POLL�BIT,�GET�INTO�RECEIVE�MODE‰BRA.L…SDLCRC02‚* ‰PAGE%TRANSUF‚EQU‡*‰TRANSMIT�UNDERFLOW�EXIT‰MOVE.B„#NCW0RG1,NECCTL_B„*#‰MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B�*9‰MOVE.B„#SDPBFC,SDPBSY(A5)�SET�SDLC�BUSY�IN�FRAME�CONTROL‰ADD.W…#1,SDSHCTOF(A4)…3/2/83'‰BTST.B„#0,SDDCMD(A3)�I�FIELD�TxMITTED?‰IFˆ�THEN.S)‹SUB.B…#2,SDSVSC(A4)�YES,�FIX�UP�Vs�COUNT‹AND.B…#$0E,SDSVSC(A4)6‹SUB.B…#1,SDSUKT(A4)�And�number�of�un-ack'd�frames�out‰ENDI/‰TST.L…SDSTHD(A4)�DID�AN�SDLC�FLUSH�JUST�OCCUR?‰IFˆ�THEN.S/‹MOVE.L„SDPRCV(A5),A2�Yes,�send�an�"RR"�command‹MOVE.B„#SDDRRR+$10,SDDCMD(A2)3‹MOVE.B„#SDPTRQ,SDPTXF(A5)�(sending�from�rcv�queue)‹BRA.L…VCTINIT6‰ENDI1‰TST.B…SDDRTC(A3)�No,�shall�we�try�sending�again?<‰BEQ.S…TRANSPBƒCount�is�zero,�so�we'll�try�again�when�polled@‰SUB.B…#1,SDDRTC(A3)�Count�isn't�zero�yet,�decrement�one�attempt=‰BNE.S…TRANSPBƒand�resend�(when�polled)�if�count�not�zero�yet?* Fall-thru to next page when the retransmission count expires.‰PAGE4* Note: We fall-thru to here from the previous page. M5V3^<f=n<vK~B†QŽM–?ž4* The retry count has expired for a transmit buffer.=* Return it to the originator after marking it as unsendable.F* Then, fix up the transmit queue by linking the buffer just after the.*‡unsendable�one�to�the�buffer�just�before�it.?* For example, if the transmit queue currently looks like this;'*†A�-->�B�-->�C,�where�B�is�unsendable.:* Then we fix up the transmit queue so it looks like this;*†A�-------->�C.K* The fix-up is accomplished by looking for a buffer that points to the oneO* we jus t got rid of, and then storing the "next" buffer's address (as returned3* to us by SOMESEND) into its forward link pointer.3‰MOVE.B„#SDDSSTE,SDDSTS+1(A3)�Mark�it�as�unsendable6‰MOVE.L„A3,A1…A1�=�A(Unsendable�buffer�-�for�SOMESEND)>‰MOVE.L„A3,A2…A2�=�A(Unsendable�buffer�-�for�WHILE�clause�use)6‰BSR.L…SOMESEND‚Pass�the�Unsendable�buffer�to�the�user7‰MOVE.L„A1,A3…A3�=�A(Next�buffer�in�the�transmit�queue)?‰LEA‡SDSTHD-SDDLNK(A4),A1�Find�buffer�before�the�unsendable�one?‰WHILE.LƒSDDLNK(A1)��A2�DO.S�Pointing�to�unsendable�buffer?/‹MOVE.L„SDDLNK(A1),A1‡No,�on�to�the�next�buffer‰ENDW@‰MOVE.L„A3,SDDLNK(A1)�yes,�store�"next"�into�"before�unsendable"<‰BRA.S…TRANSPBƒAll�done�with�clean-up,�go�see�what�to�do�now ‰PAGE'RECEITO‚EQU‡*‰RECEIVE�TIME�OUT�OCCURRED‰MOVE.B„#SDDSSRT,SDDSTS+1(A3)‰ADD.W…#1,SDSHCRTP(A4)…3/2/83 ‰BRA.S…HSKP0 /RECEIEE‚EQU‡*‰RECEIVE�EXCESSIVE�ERRORS�OCCURRED‰MOVE.B„#SDDSSRE,SDDSTS+1(A3)‰ADD.W…#1,SDSHCREX(A4)…3/2/83 *ˆBRA.S…HSKP0 &RECEILB‚EQU‡*‰RECEIVE,�NO�BUFFERS�LEFT +RECEIFB‚EQU‡*‰RECEIVED�A�FINAL�BIT�RESPONSE ***ˆEND�OF�A�RCV�SEQUENCE,�SHUT�RECEIVER�OFF* HSKP0„MOVE.B„#NCW0RG1,NECCTL_B„*#‰MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B�*‰MOVE.B„#NCW0RG3,NECCTL_B„*#‰MOVE.B„#NCW3BT8+NCW3AUE,NECCTL_B„*‰ADD.W…#1,SDSHCROF(A4)…3/2/83&‰BSR.L…SOMETOCLR�CLEAR�RECEIVE�TIMEOUT&* A5 = PRIMARY CONTROL BLOCK'S ADDRESS(* A4 = SECONDARY CONTROL BLOCK'S ADDRESS‰MOVE.L„SDPRCV(A5),A2#* A2 = CURRENT RCV BUFFER'S ADDRESS9‰MOVE.B„#SDPBFC,SDPBSY(A5)�SET�SDLC�BUSY�IN�FRAME�CONTROL,‰MOVE.W„#$2500,SR�LOWER�68000�INTERRUPT�MASK,‰BSR.L…SBXIDQ„CHECK�FOR�"XID"�ON�TxMIT�QUEUE* Fall-thru to the next page‰PAGE7* NOTE: WE MAY FALL-THRU TO HERE FROM THE PREVIOUS PAGE **ˆSDLC�FRAME�CONTROL�PROCEDURES*9HSKP1„MOVE.L„A2,SDPRCV(A5)�SAVE�NEW�HEAD�OF�RECEIVE�QUEUE!‰IF.B†SDDSTS+1(A2)��#0�THEN.S‹CLR.L…D0ˆNo�RCV�errors,‹MOVE.B„SDSCST(A4),D0 ‹SUB.B…#1,D0 ‹ASL.L…#2,D08‹JMP.S…RCVVCT(PC,D0.W)�To�current�state�if�no�RCV�errors,RCVVCT…BRA.L…VCTINITƒTo�INITIALIZATION�STATE+‹BRA.L…VCTINIBƒTo�INITIALIZATION�BUSY�STATE$‹BRA.L…VCTDISCƒTo�DISCONNECTED�STATE&‹BRA.L…VCTNRM„To�NORMAL�RESPONSE�STATE‹BRA.L…VCTBSY„To�BUSY�STATE$‹BRA.L…VCTFRMRƒTo�FRAME�REJECT�STATE‰ENDI‰MOVE.L„A2,A1…Rcv�Errors,5‰BSR.L…SOMESEND‚Tell�the�Application�Program�about�it ‰MOVE.L„A1,A20‰BSR.L…SOMEFREE‚*�FREE�ANY�OTHER�RECEIVE�BUFFERS+‰BRA.L…SDLCRC01‚*�GO�BACK�INTO�RECEIVE�MODE‰PAGE *$*ˆINITIALIZATION�STATE�FRAME�CONTROL*2VCTINIT‚MOVE.B„#SDSCIBSY,SDSCST(A4)�"SIM"�COMMAND?‰CMP.B…#SDDCSIM,SDDRSP(A2)‰BEQ.S…VCTINIT3,‰MOVE.B„#SDSCIM,SDSCST(A4)�NO,�POLL�BIT�SET?‰BTST.B„#$4,SDDRSP(A2)‰IFˆ�THEN.S5‹MOVE.B„#SDSCIM,SDSCST(A4)�Yes,�Send�a�"RIM"�Response‹MOVE.B„#SDDRRIM,SDDCMD(A2))VCTINIT6ƒCLR.W…SDDBCT(A2)�INIT�BYTE�COUNT%VCTINIT7ƒCLR.W…SDDSTS(A2)�INIT�STATUS"‹CLR.B…SDDRTC(A2)�INIT�RETRY�COUNT!‹CLR.B…SDDERR(A2)�INIT�SDLC�ERROR,‹MOVE.B„SDSSEC(A4),SDDSEC(A2)�INIT�STATION�#4‹MOVE.L„A2,SDPRCV(A5)�SAVE�NEW�HEAD�OF�RECEIVE�QUEUE ‹MOVE.L„A2,A3$‹BRA.L…TRANSMTƒTRANSMIT�THE�RESPONSE‰ENDI�FREE�QUEUE‰BSR.L…SOMEDISPOSE ‰MOVE.L„A1,A26‰MOVE.L„A1,D0…Any�more�receive�buffers�after�that�one?;‰BNE.L…HSKP1…Yes,�loop�back�up�and�see�what�the�next�one�is;‰BRA.L…SDLCRC01‚No,�just�go�turn�the�receiver�back�on�again :VCTINIT2�MOVE.B„#SDSCRDM,SDSCST(A4)�SET�DISCONNECTED�STATEGVCTINIT3�TST.W…SDDBCT(A2)�DATA�FIELD�ON�"SIM"�"SNRM"�OR�"DISC"�COMMAND?=‰BNE.L…FRMRPI„Yes,�he�shouldn't�have�done�that!�(Go�FRMR�him)<‰BSR.L…SBGTFRIR‚NO,�Get�a�buffer�for�sending�a�"UA"�response‰IFˆ�THEN.S2‹BSR.L…SOMEFREE‚NO�BUFFERS,�So�don't�send�anything@‹BRA.L…SDLCRC01‚(Make�like�we�didn't�receive�his�command�at�all)‰ENDI6‰CLR.B…SDSVRC(A4)�No�data�field,�it's�a�valid�command,-‰CLR.B…SDSVSC(A4)�reset�our�Vr�and�Vs�counts,1‰MOVE.L„A2,A1…and�tell�the�user�what�has�happened‰BSR.L…SOMESEND'‰MOVE.L„A3,A2…then�send�a�"UA"�response‰MOVE.B„#SDDRUA,SDDCMD(A 2)�*@‰MOVE.B„#SDPTRN,SDPTXF(A5)�*�SET�TxMIT�FLAG�AS�IF�"RNR"�TxMITTEDJ* NOTE: THIS WILL CAUSE RECEIVED I-FRAMES TO BE IGNORED UNTIL AN "RNR" CAN?* BE TRANSMITTED BECAUSE WE ARE IN THE BUSY OR INIT BUSY STATE.M* WE HAVE PASSED A RECEIVED SNRM ON TO THE "USER" IN OUR MACHINE, AND HE MUST(* ACKNOWLEDGE IT BEFORE WE CAN CONTINUE.‰BRA.S…VCTINIT6‚* ‰PAGE *)*ˆINITIALIZATION�BUSY�STATE�FRAME�CONTROL*+VCTINIB‚BTST.B„#$4,SDDRSP(A2)�POLL�BIT�SET?2‰BEQ.S…VCTINIT1‚*�NO,�FREE�BUFFER,�GO�INTO�RECEIVEF‰MOVE.B‚#SDDRRNR+$10,SDDCMD(A2)�YES,�BUILD�&�TRANSMIT�A�"RNR"�RESPONSE‰BRA.S…VCTINIT6‚* ‰PAGE **ˆBUSY�STATE�FRAME�CONTROL**VCTBSYƒBTST.B„#$4,SDDRSP(A2)�POLL�BIT�SET?2‰BEQ.L…VCTINIT1‚*�NO,�FREE�BUFFER,�GO�INTO�RECEIVEF‰MOVE.B‚#SDDRRNR+$10,SDDCMD(A2)�YES,�BUILD�&�TRANSMIT�A�"RNR"�RESPONSE‰BRA.L…VCTINIT6ƒ* ‰PAGE *"*ˆFRAME�REJECT�STATE�FRAME�CONTROL*+VCTFRMR‚BTST.B„#$4,SDDRSP(A2)�POLL�BIT�SET?2‰BEQ.L…VCTINIT1‚*�NO,�FREE�BUFFER,�GO�INTO�RECEIVEC‰MOVE.B„#SDSCIBSY,SDSCST(A4)�YES,�"SIM",�"DISC",�OR�"SNRM"�COMMAND?‰CMP.B…#SDDCSIM,SDDRSP(A2)�*‰BEQ.L…VCTINIT3‚*‰CMP.B…#SDDCDISC,SDDRSP(A2)�*‰BEQ.L…VCTINIT2‚*‰MOVE.B„#SDSCBSY,SDSCST(A4)�*‰CMP.B…#SDDCSNRM,SDDRSP(A2)�*‰BEQ.L…VCTINIT3‚*4‰BRA.S…FRMRSP„NO,�BUILD�&�TRANSMIT�A�"FRMR"�RESPONSE ‰PAGE E* FRAME REJECTS WILL BE TRANSMITTED BY A SECONDARY STATION FOR ANY OF* THE FOLLOWING REASONS;K* 1) INVALID COMMAND - IN DISC OR NRM STATE, RECEIVE AN XID, AND HAVE NEVER*–TRANSMITTED�AN�XID,�OR2*–IN�NRM�AND�RECEIVE�AN�"UNKNOWN"�SDLC�COMMAND,�OR2*–IN�FRAME�REJECT�STATE�AND�RECEIVE�ANY�OTHER�THAN*–A�SIM,�DISC,�OR�SNRM�COMMAND.J* 2) PROHIBITED I-FIELD - RECEIVED AN I-FIELD ON A COMMAND WHICH IS A SIM,*–SNRM,�DISC,�RR,�RNR,�OR�REJ.G* 3) BUFFER OVERRUN - RECEIVE AN OTHERWISE "GOOD" FRAME WHICH IS LONGER*–THAN�A�BUFFER.H* 4) INVALID Nr COUNT - RECEIVED AN Nr VALUE (IN EITHER A SUPERVISORY OR2*–AN�INFORMATION�FRAME)�WHICH�ACKNOWLEDGES�A�FRAME*–WE�HAVE�NOT�TRANSMITTED. **ˆCREATE�"FRaMe�Reject"�DATA*4FRMRICƒMOVE.B„#$01,SDPFRB+2(A5)‚INVALID�COMMAND�FRMR)‰CMP.B…#SDSCRDM,SDSCST(A4)�IN�DISC�STATE?,‰BEQ.L…VCTDISC1‚*�IF�YES,�SEND�"DM"�RESPONSE‰BRA.S…FRMRGN„NO,�SEND�"FRMR" 7FRMRPIƒMOVE.B„#$03,SDPFRB+2(A5)ƒPROHIBITED�I�FIELD�FRMR‰BRA.S…FRMRGN„* 3FRMRBOƒMOVE.B„#$04,SDPFRB+2(A5)ƒBUFFER�OVERRUN�FRMR‰BRA.S…FRMRGN„* 5FRMRNRƒMOVE.B„#$08,SDPFRB+2(A5)ƒINVALID�NR�COUNT�FRMR*BFRMRGNƒMOVE.B„SDDRSP(A2),SDPFRB(A5)�OFFENDING�COMMAND�->�FRMR�DATA=‰MOVE.B„SDSVSC(A4),D0�CURRENT�"NR"�&�"NS"�COUNTS�->�FRMR�DATA‰OR.B†SDSVRC(A4),D0‡*‰AND.B…#$EE,D0ƒ*‰MOVE.B„D0,SDPFRB+1(A5)(‰BSR.L…SOMEFREE‚FREE�ALL�RECEIVE�BUFFERS"‰BSR.L…SBGTFRIR‚FETCH�A�NEW�BUFFER6‰BGT.L…SDLCRC01‚OUT�IF�THERE�ARE�ABSOLUTELY�NO�BUFFERS2* GOT ONE, DON'T CARE IF IT'S THE LAST ONE OR NOT.‰MOVE.L„A3,A2…*DFRMRSPƒMOVE.B„#SDSCRFR,SDSCST(A4)�BUILD�&�TRANSMIT�A�"FRMR"�RESPONSE‰MOVE.B„#SDDRFRMR,SDDCMD(A2)�*'‰MOVE.W„#3,SDDBCT(A2)�*�INIT�BYTE�COUNT)‰MOVE.L„SDPFRB(A5),SDDDAT(A2)�*�INIT�DATA‰BRA.L…VCTINIT7‚* ‰PAGE * *ˆDISCONNECT�STATE�FRAME�CONTROL*+VCTDISC‚BTST.B„#$4,SDDRSP(A2)�POLL�BIT�SET?2‰BEQ.L…VCTINIT1‚*�NO,�FREE�BUFFER,�GO�INTO�RECEIVEC‰MOVE.B„#SDSCIBSY,SDSCST(A4)�YES,�"SIM",�"DISC",�OR�"SNRM"�COMMAND?‰CMP.B…#SDDCSIM,SDDRSP(A2)�*‰BEQ.L…VCTINIT3‚*‰CMP.B…#SDDCDISC,SDDRSP(A2)�*‰BEQ.L…VCTINIT2‚*‰MOVE.B„#SDSCBSY,SDSCST(A4)�*‰CMP.B…#SDDCSNRM,SDDRSP(A2)�*‰BEQ.L…VCTINIT3‚*.‰MOVE.B„#SDSCRDM,SDSCST(A4)�NO,�"XID"�COMMAND?‰CMP.B…#SDDCXID,SDDRSP(A2)�*‰BEQ.S…XIDRSP„*/‰CMP.B…#SDDCTEST,SDDRSP(A2)�NO,�"TEST"�COMMAND?‰BEQ.S…TESTRSP‚*GVCTDISC1�MOVE.B„#SDDRDM,SDDCMD(A2)‚NO,�BUILD�&�TRANSMIT�A�"DM"�RESPONSE‰BRA.L…VCTINIT6‚* ‰PAGE **ˆTRANSMIT�A�"TEST"�RESPONSE*%TESTRSP‚MOVE.B„#SDDCTEST,SDDCMD(A2)�*‰BRA.L…VCTINIT7‚* ‰PAGE J***************************************************************************<*‚SUBROUTINE:‚"SBXIDQ"�CHECK�FOR�AN�"XID"�ON�THE�TxMIT�QUEUE*2*‚ENTER:ŠA4.L�=�ADDRESS� OF�SECONDARY�CONTROL�BLOCK)*’A5.L�=�ADDRESS�OF�PRIMARY�CONTROL�BLOCK*!*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7*’D�U*’A�U�UƒU�P�PƒS *¢|_�stack*K*************************************************************************** 9SBXIDQƒMOVE.L„SDSTHD(A4),A3�"XID"�REPONSE�ON�TxMIT�QUEUE?6‰IF.L†A3��#0�AND.B�SDDCMD(A3)��#SDDCXID�THEN.S8‹MOVE.L„SDDLNK(A3),SDSTHD(A4)�TAKE�"XID"�OFF�TxMIT�QUEUE‹IF.L†SDPXID(A5)��#0�THEN.S5�MOVE.L„SDPXID(A5),A1…DISPOSE�OF�THE�OLD�"XID"�BUFFER�BSR.L…SOMEDISPOSE‹ENDI/‹MOVE.L„A3,SDPXID(A5)�NEW�"XID"�RESPONSE�BUFFER‰ENDI‰RTS ‰PAGE *&*ˆTRANSMIT�AN�"XID"�OR�"FRMR"�RESPONSE*2XIDRSPƒBSR.S…SBXIDQ„CHECK�FOR�"XID"�ON�TxMIT�QUEUE,‰MOVE.L„SDPXID(A5),D0�"XID"�RESPONSE�BUFFER?&‰BEQ.L…FRMRIC„*�IF�NO,�INVALID�COMMAND,‰BSR.L…SBGTFRIR‚FETCH�A�RCV�BUFFER�FOR�LATER‰IFˆ�THEN.S1‹BSR.L…SOMEFREE‚NO�BUFFERS,�JUST�STAY�IN�RCV�MODE‹BRA.L…SDLCRC01‰ENDI‰MOVE.L„A3,SDPRCV(A5)�*0‰MOVE.L„A2,A1…SEND�THE�"XID"�COMMAND�TO�THE�USER‰BSR.L…SOMESEND‚*,‰MOVE.L„SDPXID(A5),A3�PREPARE�"XID"�RESPONSE‰CLR.W…SDDSTS(A3)�*�STATUS!‰CLR.B…SDDRTC(A3)�*�RETRY�COUNTER‰CLR.B…SDDERR(A3)�*�ERROR)‰MOVE.B„SDSSEC(A4),SDDSEC(A3)�*�STATION�#%‰MOVE.B„#SDDCXID,SDDCMD(A3)�*�COMMAND1‰BRA.L…TRANSMTƒTRANSMIT�THE�"XID"�&�GO�TO�RECEIVE ‰PAGE *%*ˆNORMAL�RESPONSE‚STATE�FRAME�CONTROL*/VCTNRMƒMOVE.L„SDSTHD(A4),A3‡HEAD�OF�TxMIT�QUEUE*VCTNRM02�CLR.L…D0ˆIS�COMMAND�AN�"I"�FIELD?‰MOVE.B„SDDRSP(A2),D0 ‰BTST.L„#0,D0#‰BEQ.L…DSPNR1„YES,�OUT�IF�"I"�FRAME0‰BTST.L„#1,D0…NO,�"RR",�"RNR",�OR�"REJ"�COMMAND?0‰BEQ.S…DSPNR…YES,�OUT�IF�RR,�RNR,�OR�REJ�COMMAND‰BTST.L„#4,D0…NO,�POLL�BIT�SET?‰BEQ.S…VCTNRM06C‰MOVE.B„#SDSCIBSY,SDSCST(A4)�YES,�"SIM",�"DISC",�OR�"SNRM"�COMMAND?‰CMP.B…#SDDCSIM,D0‰BEQ.L…VCTINIT3‰CMP.B…#SDDCDISC,D0‰IF.B†D0��#SDDCDISC�THEN.S<‹CMP.B…#SDPTXQ,SDPTXF(A5)�"DISC",�TxMITTED�FROM�TxMIT�QUEUE?‹BNE.L…VCTINIT26‹CMP.B…#SDDRRD,SDDCMD(A3)�YES,�WAS�"RD"�LAST�RESPONSE?‹BNE.L…VCTINIT2K* NOTE: THE "RD" RESPONSE WILL BE LEFT ON THE TRANSMIT QUEUE UNTIL A "DISC"F*�COMMAND�IS�RECEIVED.‚THE�"RD"�CAME�FROM�A�"USER"�WITHIN�OUR�MACHINE.&‹MOVE.L„A3,A1…YES,�DISPOSE�OF�THE�"RD"‹BSR.L…SOMEDISPOSE-‹MOVE.L„A1,SDSTHD(A4)�NEW�HEAD�OF�TxMIT�QUEUE‹BRA.L…VCTINIT2‰ENDI‰MOVE.B„#SDSCBSY,SDSCST(A4)�*‰CMP.B…#SDDCSNRM,D0�*‰BEQ.L…VCTINIT3‚*.‰MOVE.B„#SDSCNRM,SDSCST(A4)�NO,�"XID"�COMMAND?‰CMP.B…#SDDCXID,D0�*‰BEQ.L…XIDRSP„*'‰CMP.B…#SDDCTEST,D0�NO,�"TEST"�COMMAND?‰BEQ.L…TESTRSP‚*!‰AND.B…#$EF,D0‚NO,�CLEAR�POLL�BIT)VCTNRM06�CMP.B…#SDDCUI,D0�IS�COMMAND�"UI"‰BEQ.L…RSPUI…*%‰BRA.L…FRMRIC„*�I�GIVE�UP�IF�IT�ISN'T ‰PAGE ADSPNR„TST.W…SDDBCT(A2)�DATA�FIELD�ON�"RR"�"RNR"�OR�"REJ"�COMMAND?$‰BNE.L…FRMRPI„*�IF�YES,�FRAME�REJECT**ˆTEST�FOR�A�VALID�Nr�COUNT*DSPNR1ƒCLR.L…D0 ‰CLR.L…D1 ‰CLR.L…D2$‰MOVE.B„SDDRSP(A2),D0�FETCH�Nr�COUNT‰LSR.B…#5,D0…*$‰MOVE.B„SDSVSC(A4),D1�FETCH�Vs�COUNT‰LSR.B…#1,D1…*-‰MOVE.B„SDSUKT(A4),D2�FETCH�#�TxMITTED�FRAMES ‰BEQ.S…DSPNR2„*�FRAMES�TxMITTED?>‰CMP.L…#0,A3…ALL�XMIT�FRAMES�GONE�(RESULT�OF�A�FLUSH)?�3/21/831‰BEQ.S…DSPNR2„YES,�SAME�AS�IF�NO�I_FRAMES�3/21/833‰BTST.B„#0,SDDCMD(A3)�NO,�"I"�FRAME�ON�TxMIT�QUEUE?‰BNE.S…DSPNR2„*�*1‰MOVE.B„SDDCMD(A3),D1�*�YES,�GET�Ns�COUNT�FROM�IT‰LSR.B…#1,D1…*�*‰ADD.B…D2,D1…*�*‰AND.B…#7,D1…*�*DSPNR2ƒWHILE.BƒD0��D1�DO.S‹SUB.B…#1,D1…NEXT�Vs�COUNT ‹AND.B…#7,D1#‹SUB.B…#1,D2…ALL�Vs�COUNTS�CHECKED?#‹BMI.L…FRMRNR„YES,�INVALID�Nr�COUNT‰ENDW* Fall-thru to the next page‰PAGE3* NOTE: WE FALL-THRU TO HERE FROM THE PREVIOUS PAGE *"*ˆDISPOSE�OF�TXMIT�BUFFERS�TO�NR-1*%‰CLR.L…D1ˆFETCH�Nr�COUNT�FROM�COMMAND‰MOVE.B„SDDRSP(A2),D1�*‰LSR.B„#4,D1…*‰AND.B…#$0E,D1ƒ*‰MOVE.B„D1,SDSVSC(A4)�*�Vs�=�Nr ‰MOVE.L„A3,D0…TxMIT�QUEUE�EMPTY?‰BEQ.L…DSPRC1„YES,�OUT>DSPNR4ƒCMP.B…#SDPTXQ,SDPTXF(A5)�NO,�TxMITTED�FROM�TxMIT�QUEUE?‰BNE.L…DSPRC1„*&‰CLR.L…D0ˆYES,�TXMITTED�A�UI�RESPONSE?‰MOVE.B„SDDCMD(A3),D0�*‰AND.B…#$EF,D0ƒ*‰IF.B†D0��#SDDCUI�THEN.S‹BTST.L„#0,D0…I�FIEL D? ‹BNE.L…DCRTX8‹TST.B…SDSUKT(A4)�YES,�UNACKNOWLEDGED�I�FRAMES�TxMITTED? ‹BEQ.L…DSPRC1‹AND.B…#$0E,D0ƒYES,�Nr�=�Ns?‹IF.B†D1��D0�THEN.S4�MOVE.B„SDDRSP(A2),D0�YES,�is�response�RR,�RNR,�REJ?�AND.B…#$03,D0ƒ*�CMP.B…#1,D0…*�BNE.S…DSPUI…*-�BTST.B„#4,SDDRSP(A2)�and�poll/final�bit�set?�BNE.S…DSPUI…*+�MOVE.L„A2,A1…NO,�DISPOSE�OF�RECEIVE�BUFFER�BSR.L…SOMEDISPOSE�*%�MOVE.L„A1,A2…END�OF�RECEIVE�BUFFERS?�MOVE.L„A1,D0…*�BEQ.S…DSPUI…**�BRA.L…VCTNRM02‚NO,�TEST�BUFFER'S�RESPONSE‹ENDI‰ENDI)‰MOVE.L„A3,A1…NO,�DISPOSE�OF�TxMIT�BUFFER!‰BTST.B„#4,SDDCMD(A3)�POLL/FINAL?‰IFˆ�THEN.S‹BSR.L…SOMEDISPOSE�NO ‹MOVE.L„A1,A3‹SUB.B…#1,SDSUKT(A4) ‹BRA.S…DSPNR4‰ELSE.S7‹BSR.L…SOMEDISPOSE�YES,�ALSO�DISPOSE�OF�RECEIVE�BUFFERS ‹MOVE.L„A1,A34‹CLR.B…SDSUKT(A4)�CLEAR�UNACKNOWLEDGED�I�FRAME�COUNT ‹BRA.L…DSPRC1‰ENDI ‰PAGE *,*ˆA�UI�(UNNUMBERED�I�FIELD)�COMMAND�OCCURRED*=RSPUI„MOVE.L„A2,A1…SEND�RECEIVE�BUFFER�TO�APPLICATION�PROGRAM‰BSR.L…SOMESEND%‰MOVE.L„A1,A2…END�OF�RECEIVE�BUFFERS? ‰MOVE.L„A1,D0 ‰BEQ.S…DSPUI*‰BRA.L…VCTNRM02‚NO,�TEST�BUFFER'S�RESPONSE ‰PAGE **ˆDISPOSE�OF�UI�TXMIT�BUFFERS*9DSPUI„CMP.B…#SDPTXQ,SDPTXF(A5)�TxMITTED�FROM�TxMIT�QUEUE?‰BNE.L…DSPRC1„*&‰MOVE.L„A3,D0…YES,�END�OF�TxMIT�QUEUE?‰BEQ.L…DSPRC1„*%‰CLR.L…D1ˆNO,�TXMITTED�A�UI�RESPONSE?‰MOVE.B„SDDCMD(A3),D1�*‰AND.B…#$EF,D1ƒ*‰CMP.B…#SDDCUI,D1�*‰BNE.S…DCRTX…**‰MOVE.L„A3,A1…YES,�DISPOSE�OF�TXMIT�BUFFER‰BTST.B„#4,SDDCMD(A3)�*‰IFˆ�THEN.S>‹BSR.L…SOMEDISPOSE�POLL/FINAL�SET,�ALSO�DISPOSE�OF�RCV�BUFFERS ‹MOVE.L„A1,A3 ‹BRA.S…DSPRC1‰ENDI#‰BSR.L…SOMEDISPOSE�POLL/FINAL�CLEAR ‰MOVE.L„A1,A3 ‰BRA.S…DSPUI ‰PAGE **ˆDECREMENT�TxMIT�RETRY�COUNTS*DCRTX„MOVE.L„A3,A1…*‰MOVE.B„SDSUKT(A4),D1+DCRTX2ƒMOVE.L„A3,D0…ALL�TxMIT�BUFFERS�GONE?‰BEQ.S…DCRTX5„*"‰BTST.B„#0,SDDCMD(A3)�NO,�I�FIELD?‰IFˆ�THEN.S*‹TST.B…D1ˆYES,�UNACKNOWLEDGED�COUNT�CLEAR?‹BEQ.S…DCRTX5„YES,�OUT ‹SUB.B…#1,D1‰ENDI7‰TST.B…SDDRTC(A3)�NO,�DECREMENT�RETRY�COUNT�IF�NON-ZERO ‰BEQ.S…DCRTX4*‰SUB.B…#1,SDDRTC(A3)�DECREMENT�RETRY�COUNT‰BNE.S…DCRTX4„EXPIRED??‰MOVE.L„A3,A1…YES,�SEND�THIS�TxMIT�BUFFER�TO�APPL�PGM�AS�UNSENT>‰MOVE.B„#SDDSSTE,SDDSTS+1(A3)�SET�RETRY�COUNTER�EXPIRED�STATUS$‰BTST.B„#$4,SDDCMD(A3)�POLL�BIT�SET?‰IFˆ�THEN.S&‹BSR.L…SOMESEND‚YES,�LAST�TXMIT�BUFFER4‹CLR.B…SDSUKT(A4)�CLEAR�UNACKNOWLEDGED�I�FRAME�COUNT ‹BRA.S…DCRTX5‰ENDI"‰BTST.B„#0,SDDCMD(A3)�NO,�I�FIELD?‰IFˆ�THEN.S#‹SUB.B…#1,SDSUKT(A4)�YES,�FIX�COUNT‰ENDI‰BSR.L…SOMESEND%‰MOVE.L„A1,A3…FETCH�NEXT�TxMIT�BUFFER ‰BRA.S…DCRTX2 .DCRTX4ƒCLR.B…SDDERR(A3)�CLEAR�SDLC�ERROR�FIELD$‰BTST.B„#$4,SDDCMD(A3)�POLL�BIT�SET?‰IFˆ�THEN.S1‹MOVE.L„SDDLNK(A3),A3�No,�FETCH�NEXT�TxMIT�BUFFER ‹BRA.S…DCRTX2‰ENDI!* Fall-Thru if poll/final bit set ‰PAGE +DCRTX5ƒMOVE.L„A1,A3ƒNEW�HEAD�OF�TxMIT�QUEUE**ˆDISPOSE�OF�RCV�BUFFERS*3DSPRC1ƒMOVE.L„A3,SDSTHD(A4)�NEW�HEAD�OF�TxMIT�QUEUE.‰MOVE.L„A2,D0…ALL�RECEIVE�BUFFERS�DISPOSED�OF? ‰BEQ.S…SELTX4‰CMP.B…#SDDERBO,SDDERR(A2)�NO,�BUFFER�OVERRUN�ERROR? ‰BEQ.L…FRMRBO0‰TST.B…SDDERR(A2)�NO,�SOME�OTHER�SDLC�RCV�ERROR? ‰BNE.S…SELTX2/‰MOVE.B„SDDRSP(A2),D0�IS�COMMAND‚UI�OR�I�FIELD?‰AND.B…#$EF,D0‰IF.B†D0��#SDDCUI�THEN.S ‹BTST.L„#0,D0 ‹BNE.S…SELTX2„OUT�IF�NOT�I-FRAME‰ENDI;‰MOVE.L„A2,A1…UI�OR�I-FRAME,�SEND�IT�TO�APPLICATION�PROGRAM‰BTST.B„#4,SDDRSP(A2)‰IFˆ�THEN.S!‹BSR.L…SOMESEND‚FINAL�BIT�NOT�SET ‹MOVE.L„A1,A2 ‹BRA.S…DSPRC1‰ELSE.S5‹BSR.L…SOMESEND‚*�YES,�ALSO�FREE�ALL�RCV�BUFFERS�LEFT$‹MOVE.L„A1,A2…FALL-THRU�TO�NEXT�PAGE‰ENDI ‰PAGE :* WARNING: WE MAY FALL-THRU TO HERE FROM THE PREVIOUS PAGE*%*ˆFETCH�A�BUFFER�&�TRANSMIT�SOMETHING*)SELTX„BSR.L…SOMEFREE‚FREE�ANY�OLD�BUFFERS"‰BSR.L…SBGTFRIR‚FETCH�A�NEW�BUFFER3‰BGT.L…SDLCRC01‚OUT�IF�ABSOLUTELY�NO�BUFFERS�AT�ALL‰IFˆ�THEN.S* GOT THE VERY LAST BUFFER/‹MOVE.L„A3,SDPRCV(A5)�NEW�HEAD�OF�RECEIVE�QUEUE ‹MOVE.L„A3,A21‹MOVE.B„#SDDRRNR+$10,SDDCMD(A2)�TRANSM IT�AN�"RNR"3‹MOVE.B„#SDPTRQ,SDPTXF(A5)�TxMITTING�FROM�RCV�QUEUE‹BRA.L…VCTINIT6‰ENDI3‰MOVE.L„A3,SDPRCV(A5)�NO,�NEW�HEAD�OF�RECEIVE�QUEUE-‰MOVE.L„A3,A2…USE�NEW�BUFFER�TO�TRANSMIT�FROM‰MOVE.B„#$10,SDDRSP(A2)**ˆSELECT�A�RESPONSE�TO�TRANSMIT*+SELTX2ƒBTST.B„#$4,SDDRSP(A2)�FINAL�BIT�SET?‰IFˆ�THEN.S(‹MOVE.L„A2,A1…NO,�DISPOSE�OF�THIS�BUFFER‹BSR.L…SOMEDISPOSE ‹MOVE.L„A1,A2 ‹BRA.L…DSPRC1‰ENDI5‰MOVE.L„A2,SDPRCV(A5)�ONLY�1�BUFFER�LEFT�IN�RCV�QUEUE‰MOVE.B„SDDRSP(A2),D0?‰AND.B…#$1F,D0ƒWere�we�sent�an�RNR�command?�or�have�no�traffic?9‰IF.B†D0��#SDDRRNR+$10�OR.L�SDSTHD(A4)��#0�THEN.S9‹MOVE.B„#SDDRRR+$10,SDDCMD(A2)�Yes,�send�an�"RR"�response3‹MOVE.B„#SDPTRQ,SDPTXF(A5)�(sending�from�rcv�queue)‹BRA.L…VCTINIT6‰ENDI‰MOVE.L„SDSTHD(A4),A3‰MOVE.B„#SDPTXQ,SDPTXF(A5)#‰BTST.B„#0,SDDCMD(A0)�YES,�I�FIELD?‰IFˆ�THEN.S:‹CLR.B…SDSUKT(A4)�YES,�CLEAR�UNACKNOWLEDGED�TRANSMIT�COUNT‰ENDI‰BRA.L…TRANSMT ‰PAGEG* When a "flush" occurs, after all transmit frames have been discarded,H* and when, at the moment of the flush, we are transmitting one of theseH* frames, an abort is transmitted and the transmitter turned off (by theE*�flush�procedure).‚Immediately�after�doing�that,�we�branch�to�SDLCRQ* to decide what to do next.I* In a secondary station, we simply exit because we will wait to see whatK* the primary wants us to do next (presumably he will poll us fairly soon). SDLCRQƒSDLRSRG‰RTE /***********************************************/* END OF FILE 'FIX:48.SDLCSEC.FRMCNT.AI' */***********************************************ééééééé4****************************************************4* BEGINNING OF FILE 'FIX:48.SDLCSEC.PWRUP.AI' *4**************************************************** M*�NOTE:�AT�STARTUP,�OUR�CURRENT�STATE�IS�"DISCONNECT�MODE".‚THE�STARTER-UPPERE*‡(WHO?)�STORES�#SDSCRDM�INTO�SDSCST�THEREBY�ASSERTING�THIS�STATE.‚WEE*‡ARE�IN�THIS�STATE�WHEN�THE�PWRUP�SUBROUTINE�IS�CALLED,�WHICH�IS�THE&*‡FIRST�CALL�TO�THE�SDLC�DRIVER�LOGIC. SDLRSRG‚MACRO2‰MOVEM.Lƒ(A7)+,A0-A6/D0-D2�RESTORE�SAVED�REGISTERS‰ENDM  SDLSVRG‚MACRO‰MOVEM.LƒA0-A6/D0-D2,-(A7)‰ENDM‰PAGE H*************************************************************************Æ*D*�SUBROUTINE:‚"PWRUP"�INITIALIZE�THE�NEC7201�CHIP�AT�POWER�UP�TIME„*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤* *‘D�U�U�U®**‘A�U�U�UƒP…S¤**Æ*H************************************************************************ ‰NEXTWB,PWRUP„MOVE.B„#NCW0RCN,NECCTL_B„CHANNEL�RESET‰MOVE.B„#NCW0RG2,NECCTL_A)‰MOVE.B„#NCW2RTS+NCW2PRI+NCW2BIN,NECCTL_A*‰MOVE.B„#NCW0RG2,NECCTL_B„INTERRUPT�VECTOR‰MOVE.B„#0,NECCTL_B‰MOVE.B„#NCW0RG4,NECCTL_B„MODE)‰MOVE.B„#NCW4C01+NCW4SDL+NCW4SME,NECCTL_B#‰MOVE.B„#NCW0RG7,NECCTL_B„SDLC�FLAG‰MOVE.B„#SDLCFLAG,NECCTL_B3‰MOVE.B„#NCW0RG3,NECCTL_B„ENABLE�AUTO�ENABLE�OF�CTS!‰MOVE.B„#NCW3BT8+NCW3AUE,NECCTL_B‰IFEQ†RES7201-400‹MOVE.W„SR,-(A7)!‹ORI.W…#$0700,SRŠMask�Interrupts!5‹MOVE.L„#MVME400,A0ˆA0�=�Address�of�the�MVME400�board'‹BCLR.B„#REGSELEC,CTLPIA_A(A0)�Set�DDRAA‹MOVE.B„#WRT_LED+WRT_SEL,DATPIA_A(A0)�to�output�mid-two�bits�only:‹BSET.B„#REGSELEC,CTLPIA_A(A0)�Switch�now�to�Data�Reg�on�A=‹BSET.B„#WRT_SEL,DATPIA_A(A0)�Select�baud�rate�jumpers�Port�2(‹MOVE.B„DATPIA_A(A0),D0�and�read�them�in6‹ANDI.W„#$07,D0‹AND'ing�off�all�but�the�baud�rate�bitsB‹MOVE.B„V400BAUD(PC,D0.W),D0�and�get�the�4-bit�corresponding�value3‹MOVE.B„D0,-(A7)Šsaving�it�on�the�stack�temporarily,‹BCLR.B„#REGSELEC,CTLPIA_B(A0)�Now,�set�DDRB2‹MOVE.B„#%11111111,DATPIA_B(A0)�to�all�bits�output:‹BSET.B„#REGSELEC,CTLPIA_B(A0)�Switch�now�to�Data�Reg�on�B¦5¯L·K¿IÇ;‹MOVE.B„DATPIA_B(A0),D0�and�read�the�current�4-bit�settings.‹ANDI.B„#RATE1MSK,D0�drop�out�Port�2's�setting;‹OR.B†(A7)+,D0�and�OR�in�the�new�value�we�figured�out�aboveB‹MOVE.B„D0,DATPIA_B(A0)�and�output�the�new�rate�(Port�1�unchanged)#‹MOVE.W„(A7)+,SRŠUnmask�Interrupts!‰ENDC,‰LEA‡SDLCPR(PC),A0‡Address�of�"SDLCPR"�->�A0‰MOVE.L„#TIMCNST,A1‰MOVE.W„#$4005,D19‰MOVE.L„#DLC1,D2ŒRequest�a�Periodic,�Recurring�Activation‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC3‰BRA.S…HOPOVER�(MUST�BE�2�BYTE�INSTRUCTION)‚2/24/831‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR!ˆ2/24/83 5HOPOVER‚BRA.L…SBSDLCRCSTŠGo�turn�on�the�receiver�now! ‰IFEQ†RES7201-400"V400BAUDƒDC.B†15,14,13,12,10,7,5,2‰ENDC *3*„This�is�a�dummy�routine�to�satisfy�XREF�in�BUFMGT*‰XDEF†SDLCQXMT )SDLCQXMT�ILLEGAL�Die,�should�not�be�used! ‰PAGE ‰SECTIONƒ9H*************************************************************************Æ*0*ˆTRAP:‚"SDLCQU"‚TRAP�SERVICE�ROUTINE�FOR�SDLC�*0*™A�BUFFER�HAS�BEEN�ENQUEUED�FOR�TRANSMISSION.�*,*™IN�THE�SECONDARY�STATION,�WE�DON'T�CARE.…**ˆSUBROUTINE:‚"SDLCQUSB"§**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ 'SDLCQUƒBSR.S…SDLCQUSB‚DO�THE�SUBROUTINE=‰MOVE.W„SR,0(A7)‚REPLACE�SR�ON�STACK�TO�GIVE�PROPER�CC�RETURN‰RTE‘AND�RETURN 2SDLCQUSB�RTS‘Just�Return,�We�don't�care�about�this ‰PAGE H*************************************************************************Æ*4*ˆTRAP:‚"SDLCTTMOUT"‚TRAP�SERVICE�ROUTINE�FOR�SDLCŒ*,*�THIS�ROUTINE�IS�ENTERED�WHEN�THE�RECEIVE�**�TIMEOUT�EXPIRESš**ˆSUBROUTINE:‚"SDLCTMOUT"¦**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ SDLCTMOUT‚RTS2RTE%SDLCTTMOUT�SDLSVRG�SAVE�ALL�USER�REGS‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A6‰ADD.W…#1,SDSHCRTO(A4)…3/2/83‰BRA.L…RECEITOƒRECEIVE�TIMEOUT ‰PAGE H*************************************************************************Æ*8*ˆTRAP:‚"SDLCPR"‚TRAP�SERVICE�ROUTINE�WHICH�IS�ENTEREDˆ*%*™WHEN�THE�PERIODIC�TIMER�RUNS�DOWNŒ **ˆSUBROUTINE:‚"SDLCPRSB"§**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤*H************************************************************************ SDLCPRSB RTS2RTE!SDLCPRƒSDLSVRGŽSAVE�ALL�REGISTERS2‰MOVE.L„SDLCPCB,A5�ARE�WE�BUSY�WAITING�FOR�BUFERS?$‰IF.B†SDPBSY(A5)��#SDPBWB�THEN.S‹SDLRSRGŽNO,�RETURN‹RTE‰ENDI8‰BRA.S…SDLCRC01‚YES,�GO�GET�ONE�AND�TURN�ON�THE�RECEIVER‰PAGE H*************************************************************************Æ*0*ˆTRAP:‚"SDLCKL"ƒTRAP�SERVICE�ROUTINE�FOR�SDLC�*&*šTHIS�ROUTINE�EFFECTIVELY�KILLS�THEŠ*.*šSDLC�LINK�AND�CANCELS�PERIODIC�ACTIVATIONS‚**ˆSUBROUTINE:‚"SBSDLCKL"§**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤* *‘DƒU�U®**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ 9SDLCKLƒBSR.S…SBSDLCKL‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE9‰MOVE.W„SR,0(A7)‚REPLACE�SR�ON�STACK�SO�WE�GIVE�PROPER�CC‰RTE‘AND�RETURN /SBSDLCKL�MOVE.W„SR,-(A7)‚SUBROUTINE�ENTRY�POINT!‰ORI.W…#$0700,SR�MASK�TO�LEVEL�7!1‰MOVE.B„#NCW0RCN,NECCTL_B�CHANNEL�RESET�7201�CHIP'‰BSR.L…SOMETOCLR�TURN�OFF�RECEIVE�TIMER‰MOVE.W„#$8005,D1;‰MOVE.L„#DLC1,D2‚Discontinue�Recurring�Periodic�Activations‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC‰BRA.S…SDLCKLEX)‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR! 6SDLCKLEX�MOVE.W„(A7)+,SR‚RESTORE�PRIOR�INTERRUPT�LEVEL‰RTS‘AND�RETURN ‰PAGE H*************************************************************************Æ*<*ˆSUBROUTINE:‚"SBUSRACK"‚USER�ACKNOWLEDGES�RECEIPT�OF�SDLC„*!*¡"SIM"�"DISC"�OR�"SNRM"�FRAMESˆ**ˆTRAP:ˆ"USRACK"©**Æ*&*ˆENTER:‚D0.B�=�"SDDCSIM"�=>�ACK�SIM›**•=�"SDDCDISC"�=>�ACK�DISC™**•=�"SDDCSNRM"�=>�ACK�SNRM™**Æ**Æ*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜D�P«* *˜A�U�S�**š|‚|Š|_�stack–**š|‚|____________�preserved’**š|_______________�used—**Æ**Æ*H************************************************************************ 9USRACKƒBSR.S…SBUSRACK‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE5‰MOVE.W„SR,0(A7)‚REPLACE�SR�ON�STACK�GIVING�PROPER�CC‰RTE‘AND�RETURN @SBUSRACK�MOVE.L„SDLCPCB,A0�FETCH�SECONDARY�CONTROL�BLOCK�ADDRESS‰MOVE.L„SDPFSEC(A0),A0‰IF.B†D0��#SDDCSIM�THEN.S2‹MOVE.B„#SDSCRDM,SDSCST(A0)�IF�SIM,�SET�DISC�STATE‰ELSE.S‹IF.B†D0��#SDDCDISC�THEN.S3�MOVE.B„#SDSCRDM,SDSCST(A0)�IF�DISC,�SET�DISC�STATE‹ELSE.S�IF.B†D0��#SDDCSNRM�THEN.S2�MOVE.B„#SDSCNRM,SDSCST(A0)�IF�SNRM,�SET�NRM�STATE�ELSE.S%‘ILLEGAL�OTHERWISE,�ILLEGAL�ACK,�DIE!�ENDI‹ENDI‰ENDI‰RTS ‰PAGE H*************************************************************************Æ*2*ˆTRAP:‚"SDLCRCST"‚TRAP�SERVICE�ROUTINE�FOR�SDLCŽ*)*™THIS�ROUTINE�FETCHES�A�RECEIVE�BUFFERˆ**™AND�STARTS�UP�THE�RECEIVER“**ˆSUBROUTINE:‚"SBSDLCRCST"¥**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ SBSDLCRCST RTS2RTE#SDLCRCST�SDLSVRG�SAVE�ALL�USER�REGS>SDLCRC01�MOVE.L„SDLCPCB,A5�PRIMARY�CONTROL�BLOCK�ADDRESS�->�A5<‰MOVE.L„SDPFSEC(A5),A4�SECONDARY�CONTROL�BLOCK�ADDRESS�->�A4)‰CLR.L…SDPRCV(A5)�CLEAR�HEAD�OF�RCV�QUEUE ‰MOVE.W„SR,D0‰AND.W…#$0700,D0%‰CMP.W…#$0500,D0�AT�LEAST�LEVEL�FIVE?‰IF.W†#$0500��D0�THEN.S‹MOVE.W„SR,D0…NO,‹AND.W…#$F8FF,D0.‹OR.W†#$0500,D0�RAISE�TO�INTERRUPT�LEVEL�FIVE!-‹MOVE.W„D0,SR…(OLD�SR�AND�LEVEL�ARE�ON�STACK)‰ENDI-‰MOVE.B„#SDPBNB,SDPBSY(A5)�SET�SSDLC�NOT�BUSY$‰BSR.L…SBGTFRIR‚GET�A�RECEIVE�BUFFER‰IFˆ�THEN.S8‹MOVE.B„#SDPBWB,SDPBSY(A5)�NONE�AVAILABLE,�SLEEP�A�WHILE‹SDLRSRG‹RTE‰ENDIBSDLCRC02�MOVE.L„A3,SDPRCV(A5)�LINK�RCV�BUFFER�TO�HEAD�OF�RCV�QUEUE-‰MOVE.W„SDPRLG(A5),SDDBCT(A3)�INIT�BYTE�COUNT‰CLR.W…SDDSTS(A3)�INIT�STATUS!‰CLR.B…SDDERR(A3)�INIT�SDLC�ERROR,‰MOVE.B„SDSSEC(A4),SDDSEC(A3)�STATION�NUMBER#‰BRA.L…RECEIVEƒGO�INTO�RECEIVE�MODE .**********************************************.* END OF FILE 'FIX:48.SDLCSEC.PWRUP.AI' *.********************************** ************éééééé' GEN IBUFQ AGÛÛrrIDLCP AGääLrrILOADP AGíírrINETP AGöörrINET LGÿÿ+rrINETNOL LG4rrINETV2 LG1rrLOADV2 LGrr**ˆGEN.IBUFQ.AG*0IBUFQ„IDNT†1,0ƒINIT�PARAMS�FOR�BUFFER�MANAGEMENT ‰SECTIONƒ8*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.*F***********************************************************************Ä*3*„Initialization�Parameters�for�Buffer�Management‘**Ä*F*********************************************************************** ‰XDEF†NUMBUF5NUMBUFƒDC.W†\NUMBUFƒNunber�of�buffers�in�Buffer�Queue ‰XDEF†SZDBUF4SZDBUFƒDC.W†\SZDBUFƒSize�of�data�area�in�each�buffer ‰XDEF†FQULWM4FQULWMƒDC.W†\FQULWMƒFree�Queue�User's�Low�Water�Mark‰ENDéé éééÓ**ˆGEN.IDLCP.AG*1IDLCP…IDNTƒ1,0�Initialization�parameters�for�SDLC*‰NOLIST*‰INCLUDE�9995.INET.INET.EQ*‰LISTŠNOLISTŠINCLUDE�9995.INET.INET.EQŠLIST ŠSECTION�8*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.*F***********************************************************************Ä*?*„Initialization�Parameters�for�Synchronous�Data�Link�Control…**Ä*F*********************************************************************** STAFLG„SET„0 ŠXDEFƒSTATION STATIONƒEQU„*ŠIFC„'\STATION','PRIMARY'&�DC.B‚0�Station�ID�flag,�0�for�primary STAFLG‡SETƒ1ŠENDCŠIFC„'\STATION','SECONDARY'*�DC.B‚1�Station�ID�flag,�<>0�for�secondary STAFLG‡SETƒ2ŠENDC ŠIFEQƒSTAFLG5�FAIL‚100ƒSTATION�must�equal�'PRIMARY'�or�'SECONDARY'ŠENDC ŠIFNEƒSTAFLG*STAFLG‡SET‚STAFLG-1…0=PRIMARY,�1=SECONDARYŠENDC* ŠXDEFƒSYSTYPE7SYSTYPEƒDC.Bƒ\SYSTYPE‹System�type�(NOLINK,LINKMAIN,...)* ŠXDEFƒMAXSEC ŠIFEQƒSTAFLGBMAXSEC‡DC.Wƒ\MAXSEC…Max�#�secondary�stations�(if�local�is�primary) �XDEFƒFSSTN0FSSTNˆDC.Bƒ\FSSTN�First�Secondary�Station�Number �XDEFƒSSINC-SSINCˆDC.Bƒ\SSINC�Secondary�Station�INCrementŠENDC ŠIFNEƒSTAFLG5MAXSEC‡DC.Wƒ1’If�local�station�is�secondary,�MAXSEC=1 �XDEFƒFSSTN FSSTNˆDC.Bƒ0 �XDEFƒSSINC SSINCˆDC.Bƒ0ŠENDC ŠXDEFƒDLBR%DLBR†DC.Wƒ\DLBRŽData�Link's�Baud�Rate ŠXDEFƒTXRTRY(TXRTRY„DC.Bƒ\TXRTRYŒTransmit�Retry�Count ŠXDEFƒRCRTRY'RCRTRY„DC.Bƒ\RCRTRYŒReceive�Retry�Count ŠXDEFƒMXOBF3MXOBF…DC.Bƒ\MXOBF�Maximum�Number�of�Outbound�Frames ŠXDEFƒRCTOV3RCTOV…DC.Wƒ\RCTOV�Receive�Timeout�Value�(1=50�Msec) ŠXDEFƒRTRDLY+RTRDLY„DC.Wƒ\RTRDLYŒRetry�Delay�(1=50�Msec) ŠXDEFƒTXDLY,TXDLY…DC.Wƒ\TXDLY�Transmit�Delay�(1=50�Msec) ŠXDEFƒPFDLY4PFDLY…DC.Wƒ\PFDLY�Poll�Powered�Off�Delay�(1=50�Msec) ŠXDEFƒPNDLY3PNDLY…DC.Wƒ\PNDLY�Poll�Powered�On�Delay�(1=50�Msec) ŠXDEFƒTXPDS$TXPDS…DC.Bƒ\TXPDS�#�of�Transmit�PadsŠENDÜM**ˆGEN.ILOADP.AG*(ILOADP„IDNTƒ1,0�Init.�equates�for�LOADV2 ŠSECTION�8*$* COPYRIGHTED 1982 BY MOTOROLA, INC.*#* Initialization equates for LOADV2* ŠXDEFƒV2OFF'V2OFF…EQU„\V2OFF�Offset�for�VM02�memory ŠXDEFƒV2SYSP0V2SYSP„EQU„\V2SYSPŒAddress�for�VM02�SYSPAR�area.ŠENDé éééééå**ˆGEN.INETP.AG*/INETP„IDNT†1,0ƒINIT�PARAMS�FOR�NETWORK�SERVICES ‰SECTIONƒ8*$*ˆCOPYRIGHTED�1982�BY�MOTOROLA,�INC.*F***********************************************************************Ä*0*„Initialization�Parameters�for�Network�Services*Ä*F*********************************************************************** ‰XDEF†MAXLNAUFMAXLNAU‚DC.W†\MAXLNAU‚Max�#�Network�Addressable�Units�at�local�station ‰XDEF†MAXNAMEGMAXNAME‚DC.W†\MAXNAME‚Max�#�Network�Names�(if�primary�-�max�in�network) ‰XDEF†MAXCONN/MAXCONN‚DC.W†\MAXCONN‚Max�#�Logical�Connections ‰XDEF†OPERDEVOPERDEV‚DC.L†0‰ENDéééééî=/*=/*†GEN.INET.LG=/*.=/* Link chain file run at sysgen time to link=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*"=LINK ,&.INET.LO,&.SYSGEN.TF;HMIXS TASK INET,$AATTR SDPSEG SDLC(R ):9,10,2 $0000 SEG SSCT:14,0 SEG INET(R):8DEF DLCBLDCB,$0000DEF SBINFRBF,$0000DEF STRSDLC,$0000INPUT…SDLC.BEGSDLC.ROINˆSDLC.BUFMGTX.ROINˆSDLC.EXORDLC.ROINˆNTS.NTSREQ.ROINˆNTS.NTCREQP.ROINˆNTS.NWCREQ.ROINˆNTS.TRANSSUB.ROINˆNTS.TRANSSCN.ROINˆNTS.SSCT.ROINˆNTS.NWCTPRI.ROIN‡TEST.OUTTERM.ROINˆNTS.NTSSERV.ROINŠ&.SYSPAR.ROIN…M68000.INET.ROINˆGEN.INETP.ROINˆGEN.IDLCP.ROINˆGEN.IBUFQ.ROINˆGEN.ILOADP.ROIN‡INET.NTBLDTB.ROIN…M68000.SRSN.ROIN‡INET.NWTEST.ROIN‡INET.GETSTA.ROINPUT„INET.OUTTERMS.ROLIB 0.&.UTILIB.ROEND=/*=ENDéééé÷,=/*=/*†GEN.INETNOL.LG=/*.=/* Link chain file run at sysgen time to link=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*$=LINK ,&.INETNOL.LO,&.SYSGEN.TF;HMIX TASK INET,$AATTR SDPSEG SDLC:9,10,2 SEG SSCT:14,0 SEG &INT:8DEF PORTAIO,$0000DEF NECDAT_A,$F70011DEF NECDAT_B,$F70013DEF NECCTL_A,$F70015DEF NECCTL_B,$F70017INPUT…SDLC.BEGSDLC.ROINˆSDLC.BUFMGTX.ROINˆSDLC.SDLCPRI.ROINˆSDLC.DLTRACE.ROIN 9999.M68XXX.EXRQPA.ROIN‚9999.M6840.RDTIMER.ROIN‰NTS.NTSREQ.ROIN‰NTS.NTCREQP.ROIN‰NTS.NWCREQ.ROIN‰NTS.TRANSSUB.ROIN‰NTS.TRANSSCN.ROIN‰NTS.SSCT.ROIN‰NTS.NWCTPRI.ROINˆTEST.OUTTERM.ROIN‰NTS.NTSSERV.ROIN‹&.SYSPAR.ROIN†M68000.INET.ROIN‰GEN.IDLCP.ROIN‰GEN.INETP.ROIN‰GEN.IBUFQ.ROIN‰GEN.ILOADP.ROINˆINET.IPSDLC.ROINˆINET.GETSTA.ROINˆSDLC.IBFMGT.ROINˆINET.NTBLDTB.ROIN†M68000.SRSN.ROINˆINET.NWTEST.ROINˆVM02.STRSDLC.ROINˆVM02.VEC7201.ROINPUT…INET.OUTTERMS.ROLIB 0.&.UTILIB.ROEND=/*=ENDééé 5=/*=/*†GEN.INETV2.LG=/*.=/* Link chain file run at sysgen time to link=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*%=LINK ,VM02.INET.LO,&.SYSGEN.TF;SHMIX TASK INET,$AATTR SDPSEG SDLC:9,10,2 \V2BSTR SEG SSCT:14,0 SEG &INT:8DEFƒNECDAT_A,$F70011DEFƒNECDAT_B,$F70013DEFƒNECCTL_A,$F70015DEFƒNECCTL_B,$F70017DEFƒMAXCONN,$8000DEFƒMAXLNAU,$8000DEFƒMAXNAME,$8000DEFƒNTBLDTB,$8000DEFƒNTSREQ,$0000DEFƒNWCT,$0000DEFƒOUTTERMS,$0000DEFƒSSCT,$0000DEFƒTRASCAN,$0000INPUT‡9999.M68XXX.EXRQPA.ROINPUT‡9999.M6840.RDTIMER.ROINPUT‡SDLC.BEGSDLC.ROINPUT‡SDLC.BUFMGTX.ROINPUT‡SDLC.PORTAIO.ROINPUT‡SDLC.SDLCPRI.ROINPUT‡SDLC.DLTRACE.ROINPUT„&.SYSPAR.ROINPUT„M68000.INET.ROINPUT„GEN.IDLCP.ROINPUT„GEN.IBUFQ.ROINPUT„GEN.ILOADP.ROINPUT„INET.IPSDLC.ROINPUT„SDLC.IBFMGT.ROINPUT„M68000.SRSN.ROINPUT„INET.NWTEST.ROINPUT„VM02.STRSDLC.ROINPUT„VM02.VEC7201.ROINPUT„INET.GETSTA.ROLIB 0.&.UTILIB.ROEND=/*=ENDééé 2=/*=/*†GEN.LOADV2.LG=/*.=/* Link chain file run at sysgen time to link=/*D=/* Sysgen parameter LINKLS = \LINKLS = file/device to which to send=/* the linker listing=/*%=LINK ,&.LOADV2.LO,&.SYSGEN.TF;HAMIXSSEG SEG0:0,8,14INPUT &.SYSPAR.ROINPUT INET.LOADV2.ROINPUT GEN.ILOADP.ROLIB 0.&.UTILIB.ROEND=/*=ENDéééé éé' NETVM02 INT LG'' rr=/*=/*†&..SYSINIT.LG=/*=/*=LINK ,INIT.LO,SYSGEN.TF;HAMIXSSEG .INT:8 \PCINPUT ROGEN.ROINPUT &.INITDAT.ROINPUT 9999.C13O15.SYSPAR.ROEND=/*=ENDééééééé  ' SDLCPRI FRMCNT SI445ÊrrINT7201 SImm+rrPOLLQ SIžž.crrRECEIVE SIÏÏ5žrrSUBRTN SI rrTRANSMITSI))Lrr‰PAGE4****************************************************5* BEGINNING OF FILE 'FIX:48.SDLCPRI.FRMCNT.AI' *4**************************************************** 9TRANSEQ‚EQU‡*‰End�of�Xmt�Queue�reached,�P/F�bit�NOT�sent!‰MOVE.B„#NCW0EOI,NECCTL_A8‰MOVE.B„#NCW0RG1,NECCTL_B„Disable�Transmitter�Interrupts!‰MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B9‰MOVE.B„#SDPBFC,SDPBSY(A5)�SET�SDLC�BUSY�IN�FRAME�CONTROL‰ADD.W…#1,SDSHCTOF(A4)…3/2/83‰MOVE.L„SDSTHD(A4),A3‰MOVE.L„SDPRCV(A5),A2 ‰BSR.L…SOMEFREE�FREE�RCV�BUFFERS ‰LEA‡0,A2�*-‰CLR.B…SDSPWR(A4)�ASSUME�DEVICE�IS�POWERED�UP0‰BRA.L…DSPUI…DISPOSE�OF�ANY�TxMITTED�"UI"�FRAMES .TRANSPB‚BRA.L…RECEIVEƒTRANSMIT�(POLL�BIT)�EXIT ‰PAGE %TRANSUF‚EQU‡*‰TRANSMIT�UNDERFLOW�EXIT8‰MOVE.B„#NCW0RG1,NECCTL_B„Disable�Transmitter�Interrupts!‰MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B9‰MOVE.B„#SDPBFC,SDPBSY(A5)�SET�SDLC�BUSY�IN�FRAME�CONTROL'‰BTST.B„#0,SDDCMD(A3)�I�FIELD�TxMITTED?‰IFˆ�THEN.S*‹SUB.B…#2,SDSVSC(A4)�YES,�FIX�UP�Vs�COUNTS‹AND.B…#$0E,SDSVSC(A4)‹SUB.B…#1,SDSUKT(A4)‰ENDI)‰TST.L…SDSTHD(A4)�Did�a�flush�just�occur?(‰BEQ.S…TRANSUF3‚Yes,�go�send�an�"RR"�now&‰TST.B…SDDRTC(A3)�No,�any�retry�count?2‰BEQ.L…TRANSMTƒNo,�retry�sending�forever�and�ever!>‰SUB.B…#1,SDDRTC(A3)�Yes,�count�one�attempt�to�send�the�buffer7‰BNE.L…TRANSMTƒand�go�re-send�it�if�count�not�exhausted4* The retry count has expired for a transmit buffer.=* Return it to the originator after marking it as unsendable.F* Then, fix up the transmit queue by linking the buffer just after the.*‡unsendable�one�to�the�buffer�just�before�it.?* For example, if the transmit queue currently looks like this;'*†A�-->�B�-->�C,�where�B�is�unsendable.:* Then we fix up the transmit queue so it looks like this;*†A�-------->�C.K* The fix-up is accomplished by looking for a buffer that points to the oneO* we just got rid of, and then storing the "next" buffer's address (as returned3* to us by SOMESEND) into its forward link pointer.,15@=@ENMOUJ]33‰MOVE.B„#SDDSSTE,SDDSTS+1(A3)�Mark�it�as�unsendable6‰MOVE.L„A3,A1…A1�=�A(Unsendable�buffer�-�for�SOMESEND)>‰MOVE.L„A3,A2…A2�=�A(Unsendable�buffer�-�for�WHILE�clause�use)6‰BSR.L…SOMESEND‚Pass�the�Unsendable�buffer�to�the�user7‰MOVE.L„A1,A3…A3�=�A(Next�buffer�in�the�transmit�queue)?‰LEA‡SDSTHD-SDDLNK(A4),A1�Find�buffer�before�the�unsendable�one?‰WHILE.LƒSDDLNK(A1)��A2�DO.S�Pointing�to�unsendable�buffer?/‹MOVE.L„SDDLNK(A1),A1‡No,�on�to�the�next�buffer‰ENDW@‰MOVE.L„A3,SDDLNK(A1)�yes,�store�"next"�into�"before�unsendable"8‰BNE.L…TRANSMTƒGo�send�the�next�one�if�something's�thereETRANSUF3�MOVE.L„SDPRCV(A5),A3�Otherwise,�send�an�"RR"�command�instead‰BRA.L…SDLCPR5B ‰PAGE /RECEIEE‚EQU‡*‰RECEIVE�EXCESSIVE�ERRORS�OCCURRED‰MOVE.B„ #SDDSSRE,SDDSTS+1(A3)‰ADD.W…#1,SDSHCREX(A4) ‰BRA.S…HSKP2 ‰PAGE 'RECEITO‚EQU‡*‰RECEIVE�TIME�OUT�OCCURRED‰MOVE.B„#SDDERTO,SDDERR(A3)‰ADD.W…#1,SDSHCRTP(A4) +RECEIFB‚EQU‡*‰RECEIVED�A�FINAL�BIT�RESPONSE *RECEILB‚EQU‡*‰RECEIVE�DEPLETED�BUFFER�POOL ***ˆEND�OF�A�RCV�SEQUENCE,�SHUT�RECEIVER�OFF*HSKP2„MOVE.B„#NCW0RG1,NECCTL_B!‰MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B‰MOVE.B„#NCW0RG3,NECCTL_B!‰MOVE.B„#NCW3BT8+NCW3AUE,NECCTL_B‰ADD.W…#1,SDSHCROF(A4)…3/2/83&‰BSR.L…SOMETOCLR�CLEAR�RECEIVE�TIMEOUT‰MOVE.L„SDSTHD(A4),A3‰MOVE.L„SDPRCV(A5),A2&* A5 = PRIMARY CONTROL BLOCK'S ADDRESS(* A4 = SECONDARY CONTROL BLOCK'S ADDRESS%* A3 = CURRENT TXMIT BUFFER'S ADDRESS#* A2 = CURRENT RCV BUFFER'S ADDRESS * Fall-thru to the next page‰PAGE3* NOTE: WE FALL-THRU TO HERE FROM THE PREVIOUS PAGE **ˆSDLC�FRAME�CONTROL�PROCEDURES*9‰MOVE.B„#SDPBFC,SDPBSY(A5)�SET�SDLC�BUSY�IN�FRAME�CONTROL,‰MOVE.W„#$2500,SR�LOWER�68000�INTERRUPT�MASK@‰CLR.B…SDSTXF(A4)�ASSUME�NOT�(RNR�SENT�&�GOOD�RSP�RCV'D)�2/24/83 %‰IF.B†SDDRSP(A2)��#SDDRRIM�THEN.S5‹OR.B†#SDDSRIM,SDDSTS(A2)�IF�RIM,�THEN�SET�RIM�STATUS‰ELSE.S$‹IF.B…SDDRSP(A2)��#SDDRDM�THEN.S5�OR.B†#SDDSRDM,SDDSTS(A2)�IF�RDM,�THEN�SET�RDM�STATUS‹ELSE.S$�IF.B†SDDRSP(A2)��#SDDRRD�THEN.S3�OR.B†#SDDSRRD,SDDSTS(A2)�IF�RD,�THEN�SET�RD�STATUS�ENDI‹ENDI‰ENDI.‰MOVE.B„SDDERR(A2),D0�Very�bad�error�received?‰IFˆ�THEN.S4‹IF.B†D0��#SDDENNR�AND.B�D0��#SDDEIFU�THEN.S-�BRA.L…INVRSP„Yes,�can't�tell�what�it�is,�out‹ENDI‰ENDI7‰CLR.B…SDSPWR(A4)�No,�It's�either�OK,�or�just�sorta�bad‰MOVE.B„#SDSCNRM,SDSCST(A4)$‰IF.B†SDPTXF(A5)��#SDPTRN�THEN.S<‹MOVE.B„#SDSTRN,SDSTXF(A4)�Sent�RNR�or�RR,�assert�good�reply‰ENDI ‰PAGE+HSKP9„IF.B†SDDRSP(A2)��#SDDRFRMR�THEN.SA*ŠSecondaries�send�Frame�Reject�for�any�of�the�following�reasons;*Œ1�-�Invalid�command,?*�In�DISC�or�NRM�state,�and�Rcv�XID�but�don't�have�one�to�send,/*�In�NRM�state�and�Rcv�an�"unknown"�command,�or6*�In�FRMR�state�and�Rcv�other�than�SIM,�DISC,�or�SNRM,*Œ2�-�Prohibited�I_field,7*�Rcv�an�I_field�on�a�SIM,�SNRM,�DISC,�RR,�RNR,�or�REJ,*Œ3�-�Buffer�Overrun,<*�Rcv�an�otherwise�good�frame�which�is�longer�than�a�buffer,*Œ4�-�Invalid�Nr�Count,>*�Rcv�an�Nr�count�which�acknowledges�an�frame�he's�never�sent.2‹OR.B†#SDDSFRM,SDDSTS(A2)�SET�FRMR�OCCURRED�STATUS.‹MOVE.L„A2,A1�SEND�FRMR�TO�APPLICATION�PROGRAM‹BSR.L…SOMESEND ‹MOVE.L„A1,A2$‹BSR.L…SOMEFREE�FREE�ALL�RCV�BUFFERS)‹BRA.L…DCRTX�DECREMENT�TxMIT�RETRY�COUNTS‰ENDI‰CLR.L…D0ˆNO,�IS�RESPONSE�UI?‰MOVE.B„SDDRSP(A2),D0‰AND.B…#$EF,D0‰IF.B†D0��#SDDCUI�THEN.S8‹MOVE.L„A2,A1…SEND�RECEIVE�BUFFER�TO�APPLICATION�PROGRAM‹BSR.L…SOMESEND%‹MOVE.L„A1,A2…END�OF�RECEIVE�BUFFERS? ‹MOVE.L„A1,D0 ‹BEQ.L…DSPUI'‹BRA.L…HSKP9…NO,�TEST�BUFFER'S�RESPONSE‰ENDI!‰AND‡#$0F,D0ƒNO,�IS�RESPONSE�RNR?‰IF.B†D0��#SDDRRNR�THEN.S6‹MOVE.B„#SDSCBSY,SDSCST(A4)�YES,�SET�REMOTE�BUSY�STATE ‹BRA.L…DSPNR‰ENDI!‰CMP.B…#SDDRRR,D0�IS�RESPONSE�RR?‰BEQ.L…DSPNR…* '‰CMP.B…#SDDRREJ,D0�NO,�IS�RESPONSE�REJ?‰BEQ.L…DSPNR…* $‰BTST.L„#$0,D0„NO,�IS�IT�AN�I�FIELD?!‰BEQ.L…DSPNR1„YES,�CHECK�Nr�COUNT *‰MOVE.L„A3,D0…NO,�ANYTHING�IN�TxMIT�QUEUE?‰BEQ.L…DSPRC1„*<‰CMP.B…#SDPTXQ,SDPTXF(A5)�DID�WE�TxMIT�FROM�THE�TxMIT�QUEUE?‰BNE.L…DSPRC1„* ‰PAGE%‰IF.B†SDDCMD(A3)��#SDDCSIM�THEN.S$‹IF.B†SDDRSP(A2)��#SDDRUA�THEN.S)�MOVE.B„#SDSCRDM,SDSCST(A4)�RDM�-->�STATE�CLR.B…SDSVRC(A4)�0�-->�Vr�CLR.B…SDSVSC(A4)�0�-->�Vs �BRA.L…OKRSP‹ELSE.S �BRA.L…INVRSP‹ENDI‰ENDI&‰IF.B†SDDCMD(A3)��#SDDCSNRM�THEN.S$‹IF.B†SDDRSP(A2)��#SDDRUA�THEN.S)�MOVE.B„#SDSCNRM,SDSCST(A4)�NRM�-->�STATE�CLR.B…SDSVRC(A4)�0�-->�Vr�CLR.B…SDSVSC(A4)�0�-->�Vs �BRA.L…OKRSP‹ELSE.S �BRA.L…INVRSP‹ENDI‰ENDI&‰IF.B†SDDCMD(A3)��#SDDCDISC�THEN.S$‹IF.B†SDDRSP(A2)��#SDDRUA�THEN.S)�MOVE.B„#SDSCRDM,SDSCST(A4)�RDM�-->�STATE �BRA.L…OKRSP‹ELSE.S �BRA.L…INVRSP‹ENDI‰ENDI#‰IF.B†SDDCMD(A3)��#SDDCX ID�OR.B!“SDDCMD(A3)��#SDDCTEST�THEN.S‹MOVE.B„SDDCMD(A3),D0‹IF.B†D0��SDDRSP(A2)�THEN.S9�MOVE.L„A3,A1…If�response�=�command,�discard�xmit�buffer,�BSR.L…SOMEDISPOSE�MOVE.L„A1,SDSTHD(A4).�MOVE.L„A2,A1…Pass�the�response�to�application�BSR.L…SOMESEND �MOVE.L„A1,A2�BSR.L…SOMEFREE2�BRA.L…SDLCRQ„and�select�next�station�to�talk�with‹ELSE.S �BRA.L…INVRSP‹ENDI‰ENDI0‰BRA.L…DSPUI…All�others�go�to�DSPUI�for�handling‰PAGE /* May fall-thru to here from the previous page! ADSPNR„TST.W…SDDBCT(A2)�DATA�FIELD�ON�"RR"�"RNR"�OR�"REJ"�COMMAND?(‰BNE.L…INVRSP„*�IF�YES,�INVALID�RESPONSE**ˆTEST�FOR�A�VALID�Nr�COUNT*DSPNR1ƒCLR.L…D0 ‰CLR.L…D1 ‰CLR.L…D2$‰MOVE.B„SDDRSP(A2),D0�FETCH�Nr�COUNT‰LSR.B…#5,D0…*$‰MOVE.B„SDSVSC(A4),D1�FETCH�Vs�COUNT‰LSR.B…#1,D1…*-‰MOVE.B„SDSUKT(A4),D2�FETCH�#�TxMITTED�FRAMES ‰BEQ.S…DSPNR2„*�FRAMES�TxMITTED?9‰CMP.L…#0,A3…XMIT�I_FRMS�GONE�JUST�AFTER�A�PURGE?�3/21/836‰BEQ.S…DSPNR2„YES,�SAME�AS�IF�NO�I_FRAMES�SENT�3/21/833‰BTST.B„#0,SDDCMD(A3)�NO,�"I"�FRAME�ON�TxMIT�QUEUE? ‰BNE.S…DSPNR2/‰MOVE.B„SDDCMD(A3),D1�YES,�GET�Ns�COUNT�FROM�IT ‰LSR.B…#1,D1 ‰ADD.B…D2,D1 ‰AND.B…#7,D1DSPNR2ƒWHILE.BƒD0��D1�DO.S‹SUB.B…#1,D1…NEXT�Vs�COUNT ‹AND.B…#7,D1#‹SUB.B…#1,D2…ALL�Vs�COUNTS�CHECKED?#‹BMI.L…INVRSP„YES,�INVALID�Nr�COUNT‰ENDW* Fall-thru to the next page‰PAGE3* NOTE: WE FALL-THRU TO HERE FROM THE PREVIOUS PAGE *"*ˆDISPOSE�OF�TXMIT�BUFFERS�TO�NR-1*&‰CLR.L…D1‰FETCH�Nr�COUNT�FROM�RESPONSE‰MOVE.B„SDDRSP(A2),D1 ‰LSR.B…#4,D1‰AND.B…#$0E,D1‰MOVE.B„D1,SDSVSC(A4)�Vs�=�Nr&‰MOVE.L„A3,D0…ANYTHING�IN�TxMIT�QUEUE? ‰BEQ.L…DSPRC1'DSPNR3A‚CLR.L…D0ˆTXMITTED�A�UI�COMMAND?‰MOVE.B„SDDCMD(A3),D0‰AND.B…#$EF,D0‰IF.B†D0��#SDDCUI�THEN.S‹BTST.L„#0,D0…I�FIELD? ‹BNE.L…DCRTX8‹TST.B…SDSUKT(A4)�YES,�UNACKNOWLEDGED�I�FRAMES�TxMITTED? ‹BEQ.L…DSPRC1‹AND.B…#$0E,D0ƒYES,�Nr�=�Ns? ‹CMP.B…D1,D0‹IF.B†D1��D0�THEN.S8�MOVE.B„SDDRSP(A2),D0�Nr�=�Ns,�IS�RESPONSE�RR,�RNR,�REJ?�AND.B…#$03,D0 �CMP.B…#1,D0 �BNE.S…DSPUI,�MOVE.L„A2,A1…YES,�DISPOSE�OF�RECEIVE�BUFFER�BSR.L…SOMEDISPOSE%�MOVE.L„A1,A2…END�OF�RECEIVE�BUFFERS? �MOVE.L„A1,D0,�BNE.L…HSKP9…No,�go�see�what�the�next�one�is>�CMP.B…#SDPTXQ,SDPTXF(A5)�Yes,�did�we�send�from�the�xmt�queue?'�BNE.L…DSPRC1„No,�go�finish�cleaning�up6�BRA.S…DSPUI…Yes,�discard�any�transmitted�"UI"�buffers‹ENDI‰ENDI/‰MOVE.L„A3,A1…Nr�<>�Ns,�DISPOSE�OF�TxMIT�BUFFER‰BTST.B„#4,SDDCMD(A3)‰IFˆ�THEN.S.‹BSR.L…SOMEDISPOSE�YES,�DISPOSE�OF�RCV�BUFFERS ‹MOVE.L„A1,A34‹CLR.B…SDSUKT(A4)�CLEAR�UNACKNOWLEDGED�I�FRAME�COUNT ‹BRA.L…DSPRC1‰ELSE.S‹BSR.L…SOMEDISPOSE ‹MOVE.L„A1,A3‹SUB.B…#1,SDSUKT(A4)‹BRA.S…DSPNR3A‰ENDI ‰PAGE*"*ˆAN�INVALID�RESPONSE�WAS�RECEIVED*DINVRSPƒMOVE.B„#$FF,SDSPWR(A4)„LET'S�ASSUME�THE�DEVICE�IS�POWERED�OFF**ˆDISPOSE�OF�UI�TXMIT�BUFFERS*&DSPUI„MOVE.L„A3,D0…END�OF�TxMIT�QUEUE?‰BEQ.L…DSPRC1„Yes,�out ‰CLR.L…D1ˆNo,‰MOVE.B„SDDCMD(A3),D1‰AND.B…#$EF,D1+‰CMP.B…#SDDCUI,D1�Did�we�send�a�UI�command? ‰BNE.S…DCRTX*‰MOVE.L„A3,A1…YES,�DISPOSE�OF�TXMIT�BUFFER)‰BTST.B„#4,SDDCMD(A3)�Poll/final�bit�set?‰IFˆ�THEN.S‹BSR.L…SOMEDISPOSE�No ‹MOVE.L„A1,A3 ‹BRA.S…DSPUI‰ENDI7‰BSR.L…SOMEDISPOSE�Yes,�also�dispose�of�receive�buffers ‰MOVE.L„A1,A3 ‰BRA.S…DSPRC1 ‰PAGE**ˆDECREMENT�TxMIT�RETRY�COUNTS*DCRTX„MOVE.L„A3,A1…*‰MOVE.B„SDSUKT(A4),D1�**DCRTX2ƒCMP.L…#0,A3…ALL�TxMIT�BUFFERS�GONE? ‰BEQ.S…DCRTX5"‰BTST.B„#0,SDDCMD(A3)�NO,�I�FIELD?‰IFˆ�THEN.S*‹TST.B…D1ˆYES,�UNACKNOWLEDGED�COUNT�CLEAR? ‹BEQ.S…DCRTX5‹SUB.B…#1,D1…YES,�DECREMENT�IT‰ENDI7‰TST.B…SDDRTC(A3)�NO,�DECREMENT�RETRY�COUNT�IF�NON-ZERO ‰BEQ.S…DCRTX4*‰SUB.B…#1,SDDRTC(A3)�DECREMENT�RETRY�COUNT‰BNE.S…DCRTX4„EXPIRED??‰MOVE.L„A3,A1…YES,�SEND�THIS�TxMIT�BUFFER�TO�APPL�PGM�AS�UNSENT>‰MOVE.B„#SDDSSTE,SDDSTS+1(A3)‚SET�RETRY�COUNTER�EXPIRED�STATUS$‰BTST.B„#$4,SDDCMD(A3)‚POLL�BIT�SET?‰IFˆ�THEN.S&‹BSR.L…SOMESEND�YES,�LAST�TXMIT�BUFFER4‹CLR.B…SDSUKT(A4)�CLEAR�UNACKNOWLEDGED�I�FRAME�COUNT  ‹BRA.S…DCRTX5‰ENDI"‰BTST.B„#0,SDDCMD(A3)�NO,�I�FIELD?‰IFˆ�THEN.S2‹SUB.B…#1,SDSUKT(A4)�YES,�FIX�UNACKNOWLEDGED�COUNT‰ENDI‰BSR.L…SOMESEND%‰MOVE.L„A1,A3�FETCH�NEXT�TxMIT�BUFFER ‰BRA.S…DCRTX2 )DCRTX4ƒCLR.B…SDDERR(A3)�CLEAR�ERROR�FIELD$‰BTST.B„#$4,SDDCMD(A3)�POLL�BIT�SET? ‰BNE.S…DCRTX5-‰MOVE.L„SDDLNK(A3),A3�FETCH�NEXT�TxMIT�BUFFER ‰BRA.S…DCRTX2 +DCRTX5ƒMOVE.L„A1,A3ƒNEW�HEAD�OF�TxMIT�QUEUE*ˆBRA.S…DSPRC1„FALL-THRU ‰PAGE:* WARNING: WE MAY FALL-THRU TO HERE FROM THE PREVIOUS PAGE**ˆDISPOSE�OF�RCV�BUFFERS*3DSPRC1ƒMOVE.L„A3,SDSTHD(A4)�NEW�HEAD�OF�TxMIT�QUEUE.‰MOVE.L„A2,D0…ALL�RECEIVE�BUFFERS�DISPOSED�OF?‰BEQ.L…SDLCRQ„*‰MOVE.B„SDDERR(A2),D0‰IFˆ�THEN.S4‹IF.B†D0��#SDDENNR�AND.B�D0��#SDDEIFU�THEN.S?�MOVE.B„#$FF,SDSPWR(A4)�Bad�error,�assume�station�is�turned�off‹ENDI)‹TST.B…SDDSTS+1(A2)�REPORT�ERROR�TO�USER?‹BNE.S…DSPRC3„Yes,�go�tell�him+‹BRA.S…DSPRC5„NO,�JUST�FREE�THE�RCV�BUFFERS‰ENDIC‰MOVE.B„SDDRSP(A2),D0�IS�RESPONSE�FRMR,�RD,�DM,�RIM,�UI�OR�I�FIELD?‰AND.B…#$EF,D0ƒ*‰CMP.B…#SDDCUI,D0�*‰BEQ.S…DSPRC3„*‰CMP.B…#SDDRRD,SDDRSP(A2)�*‰BEQ.S…DSPRC3„*‰CMP.B…#SDDRDM,SDDRSP(A2)�*‰BEQ.S…DSPRC3„*‰CMP.B…#SDDRRIM,SDDRSP(A2) ‰BEQ.S…DSPRC3‰CMP.B…#SDDRFRMR,SDDRSP(A2) ‰BEQ.S…DSPRC3 ‰BTST.L„#0,D0 ‰BNE.S…DSPRC5CDSPRC3ƒMOVE.L„A2,A1…YES,�SEND�RECEIVE�BUFFER�TO�APPLICATION�PROGRAM$‰BTST.B„#4,SDDRSP(A2)‚Final�bit�set?‰IFˆ�THEN.S‹BSR.L…SOMESEND‚NO ‹MOVE.L„A1,A2 ‹BRA.S…DSPRC1‰ENDI3‰BSR.L…SOMESEND‚YES,�ALSO�FREE�ALL�RCV�BUFFERS�LEFT ‰MOVE.L„A1,A2*DSPRC5ƒBSR.L…SOMEFREE‚FREE�ALL�RCV�BUFFERS0‰BRA.S…SDLCRQ„SELECT�NEXT�SDLC�SECONDARY�STATION ‰PAGE*(*ˆTHE�RESPONSE�WAS�VALID�FOR�THE�COMMAND**OKRSP„MOVE.L„A3,A1…DISPOSE�OF�TXMIT�BUFFER‰BSR.L…SOMEDISPOSE�*‰MOVE.L„A1,SDSTHD(A4)�*‰BSR.L…SOMEFREE�*=*ˆBRA.S…SDLCRQ„Fall�thru�and�select�next�station�to�talk�with ‰PAGE8* Warning: May fall-thru to here from the previous page!*#*ˆSET�THE�STATION'S�POLL�DELAY�TIME*%SDLCRQƒIF.B†SDSPWR(A4)��#0�THEN.S‹IF.L‡SDSTHD(A4)��#0�THEN.S<�MOVE.W…SDSTPN(A4),SDSCTD(A4)�Up,�no�tfc,�use�Power�On�Delay‹ELSE.S8�MOVE.W…SDSTTX(A4),SDSCTD(A4)�Up,�tfr,�use�Traffic�Delay‹ENDI‰ELSE.S3‹FAIL†501�Is�this�next�MOVE.B�correct�at�this�time?9‹MOVE.B„#SDSCBSY,SDSCST(A4)�Set�busy�state�to�poll�device‹IF.L†SDSTHD(A4)��#0�THEN.S?�MOVE.W„SDSTPF(A4),SDSCTD(A4)�Down,�no�tfc,�use�Power�Off�Delay‹ELSE.S:�MOVE.W„SDSTRT(A4),SDSCTD(A4)�Down,�tfc,�use�Re-Xmit�Delay‹ENDI‰ENDI+‰MOVE.L„A4,A0…SELECT�NEXT�SECONDARY�STATION‰BRA.L…SDLCSN1 .**********************************************/* END OF FILE 'FIX:48.SDLCPRI.FRMCNT.AI' *.**********************************************éé‰PAGE6******************************************************6* BEGINNING OF FILE 'FIX:48.SDLCPRI.INT7201.AI' *6****************************************************** INTRSRG‚MACROD‰MOVEM.Lƒ(A7)+,A1-A2/D0�Restore�Registers�Used�by�Interrupt�Handlers‰ENDM INTSVRG‚MACROA‰MOVEM.LƒA1-A2/D0,-(A7)�Save�Registers�Used�by�Interrupt�Handlers‰ENDM H*************************************************************************Æ*9*ˆSUBROUTINE:‚"SBSDLCFL"‚FLUSH�(PURGE)�A�TRANSMIT�QUEUE‡**ˆTRAP:ˆ"SDLCFL"©*.*ˆENTER:‚D1.B�=�SDLC�STATION�NUMBER�TO�FLUSH“**ˆRETURN:�CCR³**‘Z�set�BUFFERS�WERE�FLUSHED›*%*‘N�set�ILLEGAL�SDLC�STATION�NUMBER”*#*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7�**˜DƒP©* *˜A�U�U‹S�**œ|‹|_�stack–**œ|_____________�use d—**Æ*H************************************************************************ SBSDLCFL RTS2RTE5SDLCFLƒBSR.L…FINDSCBƒFind�the�Secondary�Control�Block‰IFˆ�THEN.L?‹ANDI.B„#$F7,1(A7)�Return�Negative�Clear�(Legal�station�number)0‹ORI.B…#$04,1(A7)�And�Zero�Set�(Buffers�Flushed)+‹ORI.W…#$700,SR�SCB�Found,�MASK�INTERRUPTS!(‹ADD.W…#1,SDSHCFLS(A1)�Count�the�flushes/‹MOVE.L„SDSTHD(A1),A0�Find�his�transmit�buffers)‹MOVE.L„A2,-(A7)�Protect�A2�while�tracing‹BSR.L…GETRACE�Get�a�trace�row‹IFˆ�THEN.SE**********************************************************************�Trace�Entry�Format°*E**********************************************************************Ã*#*‚+0Ž+4Ž+8‚+9‚+10…+12�+13�+14�+15‚*E* +---------------+---------------+---+---+-------+---+---+---+---+ *6*�!†PC‡!�A(1st�Buffer)�!�#�!�S�!ƒ0ƒ!�C�!�R�!�D0!�D1!�*E* +---------------+---------------+---+---+-------+---+---+---+---+ **Ã**�PC�=�Program�Counter,­*A*�A(1st�Buffer)�=�Address�of�the�first�buffer�being�flushed,�or…*1*‘Zero�when�no�buffer(s)�is(are)�being�flushed,…**�#�=�Station's�Number,­* *�S�=�Station's�Current�State,¦**�0�=�Unused,·*7*�C�=�When�A(1st�Buffer)�<>�0,�Buffer's�Command�Byte,�*e7n8v ~0†1Ž8*�R�=�When�A(1st�Buffer)�<>�0,�Buffer's�Response�Byte,Ž*9*�D0�=�When�A(1st�Buffer)�<>�0,�Buffer's�1st�Data�Byte,�*9*�D1�=�When�A(1st�Buffer)�<>�0,�Buffer's�2nd�Data�Byte.�**Ã*E*********************************************************************�PEA‡*(PC)�If�we�get�one,�then)�MOVE.L„(A7)+,0(A2)�trace�our�PC�address,�MOVE.L„A0,4(A2)�A(1st�Buffer),)�MOVE.B„SDSSEC(A1),8(A2)�Station�address,9�MOVE.B„SDSCST(A1),9(A2)�His�current�state�(as�in�IOWA?),&�CLR.W…10(A2)�(Zero�fill�unused�bytes)�IF.L†#0��A0�THEN.S/�MOVE.B„SDDCMD(A0),12(A2)�1st�Buffer's�Command,#�MOVE.B„SDDRSP(A0),13(A2)�Response,#�MOVE.B„SDDDAT+0(A0),14(A2)�and�two.�MOVE.B„SDDDAT+1(A0),15(A2)�...�...�data�bytes�ELSE.S-�CLR.L…12(A2)�But�if�no�buffers,�store�zeroes�ENDI‹ENDI)‹MOVE.L„(A7)+,A2�Recover�A2�after�tracing‹IF.L†#0��A0�THEN.S-�CLR.L…SDSTHD(A1)�Make�all�buffers�disappear,.�BSR.L…SBPTFRML‚(return�them�to�the�free�pool)‹ENDI'‹MOVE.L„A1,A0…A0�=�A(SCB�being�flushed)‹MOVE.L„SDLCPCB,A1�A1�=�A(PCB)?‹IF.B†#SDPBTX��SDPBSY(A1)�AND.L�A0��SDPRRTA4(A1)�THEN.S$�IF.B†#SDPTXQ��SDPTXF(A1)�THEN.S;�MOVE.B„#NCW0SAB,NECCTL_B�Xmt'g�one�of�the�flushed�buffers,'�MOVE.B„#NCW0RG1,NECCTL_B�Abort�it,�and6�MOVE.B„#NCW1IRD+NCW1STV,NECCTL_B�turn�off�everything!�MOVEM.LƒA0-A6/D0-D2,-(A7)�MOVE.L„SDLCPCB,A64�MOVEM.LƒSDPRRTA0(A6),A0-A6�Restore�driver's�context�ADD.W…#1,SDSHCTOF(A4)�MOVE.L„SDPRCV(A5),A2,�BSR.L…SOMEFREE†Release�Rcv�Bfr�to�free�pool�LEA‡0,A2ŠNo�Rcv"�MOVE.L„A2,A3‰......�or�Xmt�Buffer0�MOVE.B„#$FF,SDSPWR(A4)�and�mark�station�as�DOWN$�BRA.L…SDLCRQˆNow�go�reset�its�timer�ENDI‹ENDI‰ELSE.S?‹ANDI.B„#$FB,1(A7)�Return�Zero�Clear�(Buffers�were�not�flushed);‹ORI.B…#$08,1(A7)�And�Negative�Set�(Illegal�station�number)‰ENDI‰RTE‘(UN-MASKS�INTERRUPTS) ‰PAGE!* OVERVIEW OF INTERRUPT VECTORING -* SIGNIFICANT CONTROL BLOCK AND AREA SETTINGS M* 1) The low-memory (0..3FF) interrupt vector which the NEC7201 uses contains)*„the�address�of�the�INT7201�routine,�andO* 2) The SDLC Primary Control Block (PCB) contains eight vectors, four for eachI*„side�of�the�NEC7201.‚B-side�vectors�(0..3)�in�the�PCB�are�maintained�byI*„the�SDLC�driver.‚A-side�vectors�(4..7)�are�all�the�same�however,�eitherE*„pointing�to�INT7201A�or�to�PORTAIO.‚INT7201A�is�used�when�no�A-sideB*„driver�exists,�PORTAIO�is�used�when�an�A-side�driver�is�present. * NEC7201 INTERRUPT VECTOR NOTES J* When no interrupt is pending in the NEC7201, the  interrupt vector numberM*�register�(2B)�"rests"�at�vector�7.‚Note�that�vector�7�is�for�A-side�SpecialM*�Receive�Condition�Interrupts.‚The�difference�between�a�"resting"�and�"real"L* interrupt vector in register 2B is indicated in the A-side register 0, bitJ*�number�1:‚Where�this�bit�is�set�(1),�an�interrupt�is�pending.‚Where�thisO* bit is clear (0), no interrupt was pending, and the interrupt vector "rests".H* (Note that register 2B must be read before the pending bit is tested.) * INTERRUPT PROCESSING SEQUENCE L* When something interrupts using the low-memory interrupt vector designatedL*�as�the�NEC7201s�vector,�the�MPU�vectors�to�the�INT7201�routine.‚There,�theO* 7201's internal interrupt vector number is read from register 2B, and controlM* is passed via the corresponding vector in the SDLC PCB (note that vector #7@* will be used when the 7201 does not have a pending interrupt).O* Where a B-side interrupt was present (vector 0..3), we go to an SDLC routine.K* Where an A-side vector (4..7) was presented, we go to INT7201 or PORTAIO.J* For A-side interrupts, if no A-side driver has overwritten vectors 4..7,G* we go to INT7201A and acknowledge the interrupt, making it "go away".L* If an A-side driver exists, we go to PORTAIO which checks the pending flagL* in the 7201's A-side register 0, and thereby determines whether or not the* 7201 has a pending interrupt.N* Where a pending interrupt exists (must be an A-side interrupt), PORTAIO usesM* two SDLC PCB pointers to store the interrupt vector number as read from theN* 7201 (PORTAIO will right justify the vector in some cases), and then to jumpL*�to�some�other�address.‚(The�A-side�driver�has�stored�these�two�addresses.)O* Where no pending interrupt exists (i.e., the interrupt vector number read wasO* 4..7 [should have been #7, by the way], and the interrupt pending flag in theN* 7201's register 0 on the A-side was clear), the PORTAIO routine "assumes" anO* External Status change interrupt for the B-side (SDLC), and forces processing?* to the current SDLC External Status interrupt handling state.L*�This�"assumed"�External�Status�interrupt�is�questionable.‚As�we�don't�knowM* who interrupted (it is not the NEC7201), it is unclear what to do about it.‰PAGEH*************************************************************************Æ*9*ˆI.�S.�R.:‚"INT7201"‚NEC7201�Interrupt�Service�Routine‡**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*<*ˆVectors�through�Primary�Control�Block's�Indirect�Vectors†*6*ˆOffset�by�NEC7201's�Status�Affects�Vector�RegisterŒ**Æ*3*ˆSaves�Registers�D0.L,�A1.L,�&�A2.L�on�the�Stack�*+*˜A1.L�=�Address�of�Primary�Control�Block‡**Æ*H************************************************************************ "INT7201‚INTSVRG—SAVE�REGS�ON�STACK,‰CLR.W…D0’Read�the�NEC7201's�Vector�Register‰MOVE.B„#NCW0RG2,NECCTL_B‰MOVE.B„NECCTL_B,D01‰MOVE.L„SDLCPCB,A1Š(A1�=�A(Primary�Control�Block)0*ˆBTST†#0,TRACFLAG+1‡Should�interrupt�be�traced?*ˆIFˆ�THEN.S!*ŠBSR‡DLTRACE�Trace�the�interrupt*ˆENDIB‰MOVE.L„SDPVCT(A1,D0.W),A2‚Find�out�Where�To�Go�for�this�Interrupt‰JMP‡(A2)�And�Go�There! ‰PAGE I**************************************************************************Ç*'*ˆINT7201A�-�A-Side�Interrupt�Handlerœ**Ç*H*�An�A-Side�Interrupt�has�occurred,�or�something�other�than�an�NEC7201‚*I* interrupt has brought us here (in which case the NEC7201 has given us *F*�vector�#7).‚Either�way,�we�don't�want�the�nasty�little�sucker.‚So,‚*H*�if�the�NEC7201�really�did�cause�the�interrupt,�we�acknowledge�it�and‚*H*�thereby�make�the�interrupt�go�away.‚Otherwise,�we�simply�exit�in�the�*G*�hope�that�whatever�brought�us�here�won't�do�it�again�(as�we�have�noƒ*F*�idea�what�we�should�do�about�it�since�we�don't�know�what�"it"�is)!„**Ç*I************************************************************************* @INT7201A�BTST.B„#1,NECCTL_A‰Is�an�interrupt�pending�in�the �7201?1‰IFˆ�THEN.S‰Yes,�see�what�flavor�of�interrupt9‹IF.W†D0��#16�THEN.S�On�Transmitter�Empty�Interrupts,;�MOVE.B„#NCW0RTI,NECCTL_AƒReset�Transmitter�Empty�Interrupt‹ELSE.S7�IF.W†D0��#20�THEN.S�On�External�Status�Interrupts,9�MOVE.B„#NCW0REX,NECCTL_AƒReset�External�Status�Interrupt�ELSE.S8�IF.W†D0��#24�THEN.S�On�Receive�Character�Interrupts/‘TST.B…NECDAT_AŒRead�the�Char�(Clears�the�Intr)�ELSE.S5*�Otherwise,�on�Special�Receive�Condition�Interrupts,7‘MOVE.B„#NCW0ERR,NECCTL_AƒReset�Error�(Clears�the�Intr)�ENDI�ENDI‹ENDI?‹MOVE.B„#NCW0EOI,NECCTL_AƒWhatever,�make�the�interrupt�go�away!‰ENDI4*ˆBRA.S…INTEXIT�And�go�exit�from�handling�interrupts)* Fall-thru to the Interrupt Exit Routine APWR†EQU‡INT7201A‚On�Power�Up,�Reset�Any�Pending�A-Side�Interrupts ‰PAGE H*************************************************************************Æ*.*ˆ"INTEXIT"�-�NEC7201�Interrupt�Exit�Routine”**Æ*:*ˆNOTE:�All�interrupt�handling�procedures�must�come�hereˆ**ˆupon�completion.®**Æ*:*ˆChecks�for�"another"�pending�interrupt�in�the�NEC7201.ˆ*:*ˆIf�present,�we�vector�thru�the�Primary�Control�Block'sˆ*?*ˆIndirect�Vector�as�indicated�by�the�7201's�Vector�Register.ƒ*>*ˆIf�no�"other"�interrupt�is�pending,�registers�are�restored„*?*ˆfrom�the�stack,�and�an�RTE�is�executed�thereby�returning�toƒ**ˆthe�interrupted�process.¦**Æ*;*ˆAssumes�Registers�D0.L,�A1.L,�&�A2.L�still�on�the�Stack‡**Æ*H************************************************************************ ?* Warning: We may "fall-thru" to here from the preceeding page. INTEXIT‚CLR.W…D0‰MOVE.B„#NCW0RG2,NECCTL_B9‰MOVE.B„NECCTL_B,D0‰Read�the�7201's�Vector�Register,�then9‰BTST.B„#1,NECCTL_A‰If�Interrupt�Pending�Flag�Is�Now�Set,4‰IFˆ�THEN.S‰Then�"another"�Interrupt�is�Present.8‹MOVE.L„SDLCPCB,A1ŠSo,�Set�A1�=�A(Primary�Control�Block)0*ŠBTST†#0,TRACFLAG+1‡Should�interrupt�be�traced?*ŠIFˆ�THEN.S!*ŒBSR‡DLTRACE�Trace�the�interrupt*ŠENDI:‹MOVE.L„SDPVCT(A1,D0.W),A2‚Regardless,�Fetch�"Where�To�Go")‹JMP‡(A2)�And�Go�Handle�the�new�Interrupt-‰ENDIšBut�if�no�"other"�Interrupt�is�present,#‰INTRSRG—Then�Restore�the�Registers'‰RTE›And�Resume�the�Interrupted�Process 0************************************************0* END OF FILE 'FIX:48.SDLCPRI.INT7201.AI' *0************************************************éééé4****************************************************4* BEGINNING OF FILE 'FIX:48.SDLCPRI.POLLQ.AI' *4**************************************************** SDLRSRG‚MACRO2‰MOVEM.Lƒ(A7)+,A0-A6/D0-D2�RESTORE�SAVED�REGISTERS‰ENDM SDLSVRG‚MACRO‰MOVEM.LƒA0-A6/D0-D2,-(A7)�*‰ENDM ‰SECTIONƒ9‰PAGEH*************************************************************************Æ*D*�SUBROUTINE:‚"PWRUP"�INITIALIZE�THE�NEC7201�CHIP�AT�POWER�UP�TIME„**Æ*+*�ENTER:‚A4.L�=�ADDRESS�OF�SDLC'S� SEGMENT�**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤* *‘D�U�U°**‘A�U�U�UƒP…S¤* *¡|__�stackœ**Æ*H************************************************************************ ‰NEXTWB,PWRUP„MOVE.B„#NCW0RCN,NECCTL_BƒCHANNEL�RESET‰MOVE.B„#NCW0RG2,NECCTL_A)‰MOVE.B„#NCW2RTS+NCW2PRI+NCW2BIN,NECCTL_A*‰MOVE.B„#NCW0RG2,NECCTL_BƒINTERRUPT�VECTOR‰MOVE.B„#0,NECCTL_B‰MOVE.B„#NCW0RG4,NECCTL_BƒMODE)‰MOVE.B„#NCW4C01+NCW4SDL+NCW4SME,NECCTL_B#‰MOVE.B„#NCW0RG7,NECCTL_BƒSDLC�FLAG‰MOVE.B„#SDLCFLAG,NECCTL_B3‰MOVE.B„#NCW0RG3,NECCTL_BƒENABLE�AUTO�ENABLE�OF�CTS!‰MOVE.B„#NCW3BT8+NCW3AUE,NECCTL_B‰IFEQ†RES7201-400‹MOVE.W„SR,-(A7)!‹ORI.W…#$0700,SRŠMask�Interrupts!5‹MOVE.L„#MVME400,A0ˆA0�=�Address�of�the�MVME400�board'‹BCLR.B„#REGSELEC,CTLPIA_A(A0)�Set�DDRAA‹MOVE.B„#WRT_LED+WRT_SEL,DATPIA_A(A0)�to�output�mid-two�bits�only:‹BSET.B„#REGSELEC,CTLPIA_A(A0)�Switch�now�to�Data�Reg�on�A=‹BSET.B„#WRT_SEL,DATPIA_A(A0)�Select�baud�rate�jumpers�Port�2(‹MOVE.B„DATPIA_A(A0),D0�and�read�them�in6‹ANDI.W„#$07,D0‹AND'ing�off�all�but�the�baud�rate�bitsB‹MOVE.B„V400BAUD(PC,D0.W),D0�and�get�the�4-bit�corresponding�value3‹MOVE.B„D0,-(A7)Šsaving�it�on�the�stack�temporarily,‹BCLR.B„#REGSELEC,CTLPIA_B(A0)�Now,�set�DDRB2‹MOVE.B„#%11111111,DATPIA_B(A0)�to�all�bits�output:‹BSET.B„#REGSELEC,CTLPIA_B(A0)�Switch�now�to�Data�Reg�on�B;‹MOVE.B„DATPIA_B(A0),D0�and�read�the�current�4-bit�settings.‹ANDI.B„#RATE1MSK,D0�drop�out�Port�2's�setting;‹OR.B†(A7)+,D0�and�OR�in�the�new�value�we�figured�out�above–8ŸK§I¯0·;¿-B‹MOVE.B„D0,DATPIA_B(A0)�and�output�the�new�rate�(Port�1�unchanged)#‹MOVE.W„(A7)+,SRŠUnmask�Interrupts!‰ENDC,‰LEA‡SDLCPR(PC),A0†FETCH�ADDRESS�OF�"SDLCPR"‰MOVE.L„#TIMCNST,A1'‰MOVE.W„#$4005,D1�INTERRUPT�LEVEL�->�D1‰MOVE.L„#DLC1,D2ŒI.D.�#�->�D2‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC3‰RTS‘RETURN�(MUST�BE�A�2�BYTE�INSTRUCTION!)‚2/24/831‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR!ˆ2/24/83 ‰IFEQ†RES7201-400"V400BAUDƒDC.B†15,14,13,12,10,7,5,2‰ENDC *3*„This�is�a�dummy�routine�to�satisfy�XREF�in�BUFMGT*‰XDEF†SDLCQXMT SDLCQXMT RTS‰PAGEH*************************************************************************Æ*9*ˆTRAP:‚"SDLCRCST"�THIS�ROUTINE�IS�A�"DUMMY"�TO�PROVIDEˆ*'*šCOMPATABILITY�FOR�BUFFER�MANAGEMENT‰**ˆSUBROUTINE:‚"SBSDLCRCST"¥**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ =SDLCRCST�BSR.S…SBSDLCRCST�TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE +SBSDLCRCST�ILLEGAL‹Die,�should�not�be�used!‰PAGEH*************************************************************************Æ*0*ˆTRAP:‚"USRACK"ƒTRAP�SERVICE�ROUTINE�FOR�SDLC�**ˆSUBROUTINE:‚"SBUSRACK"§**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ 9USRACKƒBSR.S…SBUSRACK‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE"‰RTE‘SO�WE�GIVE�PROPER�RETURN�CODE )SBUSRACK�ILLEGAL�Die,�should�not�be�used!‰PAGEH*************************************************************************Æ*0*ˆTRAP:‚"SDLCKL"ƒTRAP�SERVICE�ROUTINE�FOR�SDLC�*&*šTHIS�ROUTINE�EFFECTIVELY�KILLS�THEŠ*.*šSDLC�LINK�AND�CANCELS�PERIODIC�ACTIVATIONS‚**ˆSUBROUTINE:‚"SBSDLCKL"§**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤* *‘DƒU�U®**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ 9SDLCKLƒBSR.S…SBSDLCKL‚TRAP�ENTRY�POINT,�DO�THE�SUBROUTINE+‰MOVE.W„SR,0(A7)‚REPLACE�THE�CONDITION�CODE&‰RTE‘SO�WE�GIVE�THE�PROPER�RETURN�CODE @SBSDLCKL�MOVE.B„#NCW0RCN,N ECCTL_B�CHANNEL�RESET�THE�NEC7201�CHIP2‰MOVE.W„#$8005,D1�DISCONTINUE�PERIODIC�ACTIVATIONS‰MOVE.L„#DLC1,D2‚*‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC.‰RTS‘OK,�RETURN�(MUST�BE�A�2�BYTE�INSTRUCTION)1‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR!ˆ2/24/83‰PAGEH*************************************************************************Æ*0*ˆTRAP:‚"SDLCQU"‚TRAP�SERVICE�ROUTINE�FOR�SDLC�*+*™THIS�ROUTINE�CHECKS�TRANSMIT�QUEUES�FOR†*0*™DATA�TO�TRANSMIT�BETWEEN�PERIODIC�ACTIVATIONS**ˆSUBROUTINE:‚"SDLCQUSB"§**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ SDLCQUSB RTS2RTESDLCQUƒSDLSVRG‰MOVE.L„SDLCPCB,A5‰ADD.W…#1,SDPHCQUS(A5) ‰MOVE.W„SR,D0%‰AND.W…#$0700,D0‹AT�LEAST�AT�LEVEL�5?‰IF.W†D0��#$0500�THEN.S ‹MOVE.W„SR,D0‹AND.W…#$F8FF,D0‹No,-‹OR.W†#$0500,D0‹assert�we�are�now�at�level�5!.‹MOVE.W„D0,SR�(old�SR�and�intr�level�on�stack)‰ENDI‰BRA.S…SDLCPR3‰PAGEH*************************************************************************Æ*4*ˆTRAP:‚"SDLCTTMOUT"‚TRAP�SERVICE�ROUTINE�FOR�SDLCŒ*,*�THIS�ROUTINE�IS�ENTERED�WHEN�THE�RECEIVE�**�TIMEOUT�EXPIRESš**ˆSUBROUTINE:‚"SDLCTMOUT"¦**Æ**Æ*#*�REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¤**‘D´**‘A�S¤* *¡|__�stackœ**Æ*H************************************************************************ SDLCTMOUT‚RTS2RTE%SDLCTTMOUT�SDLSVRG�SAVE�ALL�USER�REGS+‰MOVE.L„SDLCPCB,A6�RESTORE�REGS�FROM�P.C.B.‰MOVEM.LƒSDPRRTA0(A6),A0-A6‰ADD.W…#1,SDSHCRTO(A4)…3/2/83‰BRA.L…RECEITOƒRECEIVE�TIMEOUT ‰PAGE H*************************************************************************Æ*>*ˆTRAP:‚"SDLCPR"‚TRAP�ROUTINE�WHICH�IS�ENTERED�WHEN�PERIODIC‚**™TIMER�RUNS�DOWNž**ˆSUBROUTINE:‚"SDLCPRSB"§**Æ*0*ˆENTER:‚D0.L�=�#�INTERVALS�WHICH�HAVE�ELAPSED‘**�D1.L�=�ACTIVATION�I.D. **Æ*C*�WARNING:‚THIS�SECTION�OF�CODE�RUNS�AT�INTERRUPT�LEVEL�FIVE�(5).…*C*�HOWEVER,�WHEN�WE�ENTER�HERE�AFTER�COMPLETING�A�TRANSACTION�WITH†*F*�A�SECONDARY�STATION,�WE�ARE�AT�"FUNNY�LEVEL�5"�-�I.E.,�WE�SUFFEREDƒ*E*�A�LEVEL�SIX�(6)�INTERRUPT,�HANDLED�IT,�AND�THEN�LOWERED�THE�LEVEL„*E*�TO�FIVE.‚AS�A�RESULT,�WE�MAY�HAVE�INTERRUPTED�OURSELVES.‚FOR�THIS‚*G*�REASON,�THE�VARIABLE�"SDPBSY"�IS�USED�TO�ALLOW�ACCESS�TO�THE�"START‚*D*�NEW�WORK"�PORTIONS�OF�THIS�IMPLEMENTATION.‚WHEN�THIS�VARIABLE�IS„*E*�SET�TO�"NOT�BUSY",�THEN�AND�ONLY�THEN�CAN�WE�LOOK�FOR�NEW�WORK�TO„*G*�BE�INITIATED.‚WHEN�WE�ARE�NOT�"NOT�BUSY"�(I.E.,�WE�ARE�BUSY�SENDING�*E*�OR�RECEIVING,�OR�WHATEVER)�WE�CAN�ONLY�DECREMENT�THE�TIMER�VALUES„*F*�IN�THE�SECONDARY�CONTROL�BLOCKS,�AND�NO�MORE.‚LASTLY,�BECAUSE�EVEN‚*D*�THIS�COULD�BE�"INTERRUPTED"�BY�OURSELVES,�WE�MUST�HANDLE�A�TIMER…*G*�VALUE�WHICH�GOES�TO�LESS�THAN�ZERO�(I.E.,�WE�COMMITTED�TO�DECREMENT‚*H* A TIMER, WERE INTERRUPTED AND ZEROED THAT COUNTER, AND THEN RETURNED *2*�TO�SUBTRACT�ONE,�LEAVING�THAT�COUNT�NEGATIVE).—**Æ**�ED�SKINNER,�MARCH�2,�1983¬**Æ*H************************************************************************ SDLCPRSB RTS2RTESDLCPRƒSDLSVRG‰MOVE.L„#0,A1…SET�UP�REGISTERS‰MOVE.L„SDLCPCB,A5�*‰MOVE.L„SDPFSEC(A5),A0†**<*ˆDECREMENT�THE�CURRENT�TIME�DELAY�OF�ALL�SECONDARY�STATIONS$*‰AND�SELECT�THE�1ST�ONE�THAT'S�ZERO* ‰WHILE.BƒSDSSEC(A0)��#0�DO.S‹IF.W†SDSCTD(A0)��#0�THEN.S2�SUB.W…D0,SDSCTD(A0)�Timer�:=�Timer�-�Elapsed_Time‹ENDI<‹ADD.L…#SDSLNG,A0�Thusly�update�ALL�Secondary�Control�Blocks‰ENDW* Fall-thru to the next page‰PAGE:* NOTE: MAY BE FALLING-THRU TO HERE FROM THE PREVIOUS PAGE F* NOTE: ENTER HERE FROM SDLCQUSB - SOMEONE HAS ENQUEUED AN XMIT BUFFER FSDLCPR3‚MOVE.L„SDPFSEC(A5),A0�Are�we�NOT�"NOT�BUSY"�(ie,�are�we�busy?)$‰IF.B†SDPBSY(A5)��#SDPBNB�THEN.S‹SDLRSRG�Yes,�exit‹RTE‰ENDI‰PAGE*1*ˆSELECT�THE�1ST�SCB�WHOSE�TIME�DELAY�IS�NOW�ZERO*?SDLCSLƒWHILE.BƒSDSSEC(A0)��#0�AND.W�SD SCTD(A0)��#0�DO.S,SDLCSN1„ADD.L…#SDSLNG,A0�Advance�to�next�SCB‰ENDW‰IF.B†SDSSEC(A0)��#0�THEN.S<‹MOVE.B„#SDPBNB,SDPBSY(A5)�End�of�list,�set�SDLC�to�NOT�BUSY‹SDLRSRG�And�exit‹RTE‰ENDI‰MOVE.L„A0,A4…A4�=�A(SCB)(‰MOVE.B„#SDPBFC,SDPBSY(A5)�set�SDLC�BUSY* Fall-Thru to next page‰PAGE7* WARNING: MAY FALL-THRU TO HERE FROM THE PREVIOUS PAGE*0* A4 = CURRENT SECONDARY'S CONTROL BLOCK ADDRESS.* A5 = CURRENT PRIMARY'S CONTROL BLOCK ADDRESS*.*ˆA�SECONDARY�CONTROL�BLOCK�HAS�BEEN�SELECTED,*ˆDetermine�what�to�send.*3‰CMP.B…#SDSCBSY,SDSCST(A4)�SECONDARY�IN�BUSY�STATE?‰BEQ.S…SDLCPR5ƒ*)‰TST.L…SDSTHD(A4)�NO,�SOMETHING�TO�TXMIT?‰BNE.S…SDLCPR6ƒ*=SDLCPR5‚BSR.L…SBGTFRIR‚NO,�FETCH�A�RCV�BUFFER�&�TXMIT�AN�"RR"-‰BEQ.S…SDLCPR5B‚GOT�ONE�AND�IT'S�NOT�THE�LAST‰IFˆ�THEN.S6‹MOVE.B„#SDPBNB,SDPBSY(A5)�Didn't�get�one,�go�NOT�BUSY‹SDLRSRG�And�exit‹RTE‰ENDI!* GOT ONE, BUT IT'S THE VERY LASTASDLCPR5A�MOVE.B„#SDDRRNR+$10,SDDCMD(A3)�YES,�SET�AN�"RNR"�COMMAND‰BRA.S…SDLCPR5C #*ˆA3�=�BUFFER�CONTROL�BLOCK�ADDRESS;SDLCPR5B�MOVE.B„#SDDRRR+$10,SDDCMD(A3)�SEND�AN�"RR"�COMMAND?SDLCPR5C�MOVE.L„A3,SDPRCV(A5)‚*�(TxMIT�FROM�THE�RECEIVE�BUFFER)‰MOVE.B„#SDPTRQ,SDPTXF(A5)�*�**‰MOVE.W„SDPRLG(A5),SDDBCT(A3)�*�BYTE�COUNT‰CLR.W…SDDSTS(A3)�*�STATUS‰CLR.B…SDDERR(A3)�*�SDLC�ERROR$‰CLR.B…SDDRTC(A3)�*�SDLC�RETRY�COUNT.‰MOVE.B„SDSSEC(A4),SDDSEC(A3)�*�STATION�NUMBER‰BRA.L…TRANSMTƒ*�*‰PAGEH* NOTE: ED SKINNER, 2/24/83 - WHEN WE HAVE A "SNRM" TO SEND, WE ACTUALLYI*�PERFORM�THE�FOLLOWING:‚1)�TRANSMIT�A�"RNR"�COMMAND�AND�RECEIVE�A�"GOOD"H*�RESPONSE.‚THIS�IS�DONE�SO�THE�REMOTE�STATION�WILL�KNOW�HOW�MANY�OF�HISH* INFORMATION FRAMES THAT WE HAVE RECEIVED, THEREBY AVOIDING DUPLICATIONH*�OF�FRAMES.‚WE�MUST�GET�A�"GOOD"�RESPONSE�TO�THE�RNR�BEFORE�SENDING�THEH* SNRM SO THAT WE KNOW HE GOT THE RNR OK, AND THEREFORE NOW KNOWS OUR NrI*�VALUE.‚(BY�A�"GOOD"�RESPONSE,�I�MEAN�A�RECEIVED�REPLY�OF�ANY�KIND�WHICHJ* WAS RECEIVED WITHOUT ANY ERRORS - DOES AN Ns ERROR COUNT? I DON'T KNOW!)D* ONCE WE'VE RECEIVED A "GOOD" REPLY, WE CAN THEN TRANSMIT THE SNRM. 6SDLCPR6‚MOVE.L„SDSTHD(A4),A3�WE�HAVE�SOMETHING�TO�TXMT3‰CMP.B…#SDDCSNRM,SDDCMD(A3)�"SNRM"�COMMAND?Ž9/14/82&‰BNE.S…SDLCPR6C‚*�BRANCH�IF�NOš9/14/829‰CMP.B…#SDSTRN,SDSTXF(A4)�YES,�TXMITTED�AN�"RNR"?ˆ2/23/83'‰BEQ.S…SDLCPR6C‚*�BRANCH�IF�YES™9/14/82?‰BSR.L…SBGTFRIR‚NO,�FETCH�A�RCV�BUFFER�&�TXMIT�AN�"RNR"�9/14/825‰BEQ.S…SDLCPR5A‚GOT�ONE�AND�IT'S�NOT�THE�LAST‹9/14/82‰IFˆ�THEN.S6‹MOVE.B„#SDPBNB,SDPBSY(A5)�Didn't�get�one,�go�NOT�BUSY‹SDLRSRG�And�exit‹RTE‰ENDI"* WE JUST GOT THE VERY LAST BUFFER)‰BRA.S…SDLCPR5A‚TRANSMIT�AN�"RNR"—9/14/82 "SDLCPR6C�MOVE.B„#SDPTXQ,SDPTXF(A5)‰MOVE.L„A3,-(A7),‰BSR.L…SBGTFRIR‚Get�a�buffer�to�receive�into‰IFˆ�THEN.S:‹MOVE.W„SDPRLG(A5),SDDBCT(A3)�Ok,�Prepare�it�for�later�use‹CLR.W…SDDSTS(A3)�STATUS‹CLR.B…SDDERR(A3)�SDLC�ERROR‹MOVE.L„A3,SDPRCV(A5)‹MOVE.L„(A7)+,A3)‹BTST.B„#0,SDDCMD(A3)�I�Frame�to�be�sent?‹IFˆ�THEN.S4�CLR.B…SDSUKT(A4)�Yes,�zero�the�number�of�frames�out‹ENDI‰ELSE.S.‹MOVE.L„(A7)+,A0�Absolutely�no�buffers�at�all,-‹MOVE.B„#SDPBNB,SDPBSY(A5)�Set�SDLC�not�busy,‹SDLRSRG�And�exit‹RTE‰ENDI$‰BRA.L…TRANSMTƒGo�start�transmitting .**********************************************.* END OF FILE 'FIX:48.SDLCPRI.POLLQ.AI' *.**********************************************é‰PAGE6******************************************************6* BEGINNING OF FILE 'FIX:48.SDLCPRI.RECEIVE.AI' *6****************************************************** H************************************************************************ *'*ˆMODULE:‚"RECEIVE"�RECEIVE�SDLC�FRAMES*-*ˆENTER:‚A5.L�=�PRIMARY�CONTROL�BLOCK�ADDRESS(*�A4.L�=�SECONDARY�CONTROL�BLOCK�ADDRESS*9*ˆENTRY�ASSUMES�A0-A6/D0-D7�HAVE�BEEN�PUSHED�ON�THE�STACK5*–AND�ENTRY�WAS�THROUGH�EXCEPTION�(TRAP�OR�INTERRUPT)*>*ˆEXIT:‚"RECEIFB"‚SDLC�RESPONSE�WITH�FINAL�BIT�SET�CAUSED�EXIT'*�"RECEITO"‚RECEIVE�TIMEOUT�CAUSED�EXIT3*�"RECEILB"‚THE�FREE�QUEUE�HAS�ONLY�ONE�BUFFER�LEFT9*�"RECEIEE"‚AN�EXCESSIVE�NUMBER�OF�RCV�ERRORS�CAUSED�EXIT*!*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7*˜D�U*˜A�U�U�U�U�P�PƒS* |ƒ|ƒ|__�stack* |ƒ|______�preserved* |__________�used*#*ˆEXITS�TO�EXTERNALLY�DEFINED�LABEL&*ŽWITH�A0-A6/D0-D7�PUSHED�ON�THE�STACK&*ŽAND�ASSUMES�FINAL�EXIT�WILL�BE�"RTE"*H************************************************************************ ?RECEIVE‚MOVE.B„#SDPBRC,SDPBSY(A5)‚Mark�us�as�busy�receiving�now ‰ADD.W…#1,SDSHCRCV(A4)…3/2/83 <‰LEA‡RCVSTSEI(PC),A0…and�set�interrupt�vectors�for�receiving‰MOVE.L„A0,SDPVCT2(A5)‰LEA‡RCVST1(PC),A0‰MOVE.L„A0,SDPVCT3(A5)‰LEA‡RCVSTS(PC),A0‰MOVE.L„A0,SDPVCT4(A5) 5‰MOVE.L„SDPRCV(A5),A3‡Find�the�buffer�to�receive�into6‰LEA‡SDDDAT(A3),A2‡A2�=�A(data�area�within�the�buffer)(‰MOVE.L„#0,A1�(Zero�the�high�word�of�A1)‰MOVE.W„SDPRLG(A5),A1‡and6‰MOVE.W„A1,SDDBCT(A3)‹store�maximum�byte�count‚2/24/83:‰MOVE.B„SDSRRT(A4),SDSCSE(A4)�Initialize�the�error�counter.‰CLR.B…SDDERR(A3)ŠClear�the�error�flagŠ2/24/83B‰MOVEM.LƒA0-A6,SDPRRTA0(A5)‚Save�regs�for�interrupt�handlers�usage9‰MOVE.W„#-1,SDPRBCT(A5)…make�the�count�field�"bad"„3/8/83 ‰OR.W†#$700,SRŒMask�interrupts2‰MOVE.B„#NCW0RG6,NECCTL_B„Load�the�station�address0‰MOVE.B„SDSSEC(A4),NECCTL_B‚We�are�interested�in;‰MOVE.B„#NCW0REX+NCW0RG1,NECCTL_B�EXT�&�RCV�CHAR�INT�ENABLEÇ:ÐBØKàGè4ð:ø#)‰MOVE.B„#NCW1IRX+NCW1EXI+NCW1STV,NECCTL_B$‰MOVE.B„#NCW0RG3,NECCTL_B„RCV�ENABLE;W3TOTAL‚EQU‡NCW3BT8+NCW3AUE+NCW3EHU+NCW3CRC+NCW3ADS+NCW3RXE‰MOVE.B„#W3TOTAL,NECCTL_B!‰MOVE.B„#NCW0RG5,NECCTL_B„SET�DTR‰MOVE.B„#NCW5DTR,NECCTL_B5‰MOVE.B„#NCW0RTX,NECCTL_B„ENABLE�INT�ON�NEXT�RCV�CHAR!‰MOVE.B„#NCW0RTC+NCW0REX,NECCTL_B '‰BSR.L…SOMETOUT‚TRIGGER�RECEIVE�TIMEOUT ‰SDLRSRG—Restore�all�registers,‰INTSVRG—Then�save�only�the�"interrupt"�ones‰BRA.L…INTEXIT ‰PAGE*#* External Status Interrupt Handler*I*�NOTE:‚THIS�STATE�IS�USED�WHEN�AN�EXTERNAL�STATUS�INTERRUPT�OCCURS�PRIORB*ˆTO�RECEIVING�THE�FIRST�CHARACTER�OF�A�RECEIVE�FRAME.‚DURING�THISF*ˆPERIOD�(BEFORE�WE�BEGIN�RECEIVING�A�FRAME)�WE�IGNORE�EXTERNAL�STATUSE*ˆINTERRUPTS.‚WE�DON'T�CARE�ABOUT�RECEIVE�ABORTS�AND/OR�CLEAR�TO�SENDC*ˆAND/OR�DATA�CARRIER�DETECT�STATE�CHANGES�WHEN�WE�ARE�NOT�ACTUALLY*ˆRECEIVING�A�FRAME. 1RCVSTSEI�MOVE.B„NECCTL_B,D0ŠGET�THE�CHIP'S�STATUS*œIGNORE�RECEIVE�ABORT,*œHUNT�MODE�CHANGES,*œCLEAR�TO�SEND�CHANGES,�AND*œDATA�CARRIER�DETECT�CHANGES./‰MOVE.B„#NCW0REX,NECCTL_B�RESET�EXTERNAL�STATUS.‰MOVE.B„#NCW0EOI,NECCTL_A�AND�END�OF�INTERRUPT‰BRA.L…INTEXIT‰PAGE*#* External Status Interrupt Handler**1*ˆVECTORED�STATE�TO�PROCESS�EXT/STATUS�INTERRUPTS*%RCVSTEƒMOVE.B„NECCTL_B,D0�SDLC�ABORT?‰BTST.L„#7,D0…*‰BNE.S…RCVSTE1ƒ*,‰BTST.L„#3,D0…NO,�DataCarrierDetect�DROPPED?‰BEQ.S…RCVSTE2ƒ*4‰MOVE.B„#NCW0REX,NECCTL_B�NO,�RESET�INTERRUPT�&�EXIT‰MOVE.B„#NCW0EOI,NECCTL_A�*‰BRA.L…INTEXIT‡* 7RCVSTE1‚MOVE.B„#NCW0REX,NECCTL_B„RESET�INTERRUPT�&�EXIT‰MOVE.B„#NCW0EOI,NECCTL_A�*3RCVSTE1A�INTRSRG“LET'S�SAVE�ALL�THE�USERS'�REGS�NOW ‰SDLSVRG“*‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A6�*3‰MOVE.B„#SDDEABT,SDDERR(A3)„SET�SDLC�ABORT�OCCURRED‰ADD.W…#1,SDSHCRAB(A4)…3/2/83‰BRA.L…RCVSTSF�*   7RCVSTE2‚MOVE.B„#NCW0REX,NECCTL_B„RESET�INTERRUPT�&�EXIT‰MOVE.B„#NCW0EOI,NECCTL_A�*+‰INTRSRG“LET'S�SAVE�ALL�THE�USERS'�REGS�NOW ‰SDLSVRG“* ‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A6�*<‰MOVE.B„#SDDEABT,SDDERR(A3)„ASSUME�AN�ABORT�OCCURREDƒ2/24/83‰ADD.W…#1,SDSHCRDD(A4)…3/2/83‰BRA.L…RCVSTSE�* ‰PAGE *%* Receive Character Interrupt Handler**2*ˆVECTORED�STATE�TO�PROCESS�1ST�RCV�CHAR�AVAILABLE*�THEN.S0‹MOVE.L„SDPRRTA2(A1),A2…More�may�be�received�OK,5‹MOVE.B„NECDAT_B,(A2)+‡Store�received�byte�into�buffe2‹MOVE.L„A2,SDPRRTA2(A1)…Save�updated�data�address.‰ELSE.S9‹LEA‡RCVST4(PC),A2‡Buffer�is�full,�better�by�1st�FCS�byte<‹MOVE.L„A2,SDPVCT3(A1)†Use�BUFFER�OVERRUN�vector�if�rcv�more2‹MOVE.B„NECDAT_B,D0Šand�discard�1st�FCS�byte�(hope‰ENDI‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE *%* Receive Character Interrupt Handler**+*ˆVECTORED�STATE�TO�PROCESS�OVERRUN�BUFFERS*2RCVST4ƒMOVE.L„SDPRRTA3(A1),A2�BUFFER�OVERRUN�ERROR‰MOVE.B„#SDDERBO,SDDERR(A2)1‰MOVE.B„NECDAT_B,D0�REMOVE�CHARACTER�FROM�NEC7201‰MOVE.L„SDPRRTA4(A1),A2…3/2/83‰ADD.W…#1,SDSHCROB(A2)…3/2/83‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE *-* Special Receive Condition Interrupt Handler**2*ˆVECTORED�STATE�TO�PROCESS�SPECIAL�RCV�CONDITIONS*?RCVSTSƒMOVE.B„NECDAT_B,D0‚REMOVE�2ND�CRC�CHARACTER�FROM�NEC7201+‰INTRSRG“LET'S�SAVE�ALL�THE�USERS'�REGS�NOW‰SDLSVRG‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A64‰MOVE.B„#NCW0RG1,NECCTL_B�Get�Register�1�Information‰MOVE.B„NECCTL_B,D03‰MOVE.B„#NCW0ERR,NECCTL_B�(reset�special�interrupt)!‰MOVE.B„#NCW0RTC+NCW0RTX,NECCTL_B‰MOVE.B„#NCW0EOI,NECCTL_A )‰MOVE.L„A2,-(A7)ŒProtect�A2�while�tracing‰BSR.L…GETRACE�Get�a�trace�row‰IFˆ�THEN.SE**********************************************************************�Trace�Entry�Format°*E**********************************************************************Ã*'*‚+0Ž+4Ž+8‚+9‚+10�+11�+12�+13�+14�+15‚*E* +---------------+---------------+---+---+---+---+---+---+---+---+ *:*�!†PC‡!�A(Rcv�Buffer)�!�#�!�S�!�C�!�R�!�D0!�D1!�E�!�R1!�* E* +---------------+---------------+---+---+---+---+---+---+---+---+ **Ã**�PC�=�Program�Counter,­*8*�A(Rcv�Buffer)�=�Address�of�the�buffer�just�received,Ž**�#�=�Station's�Number,­* *�S�=�Station's�Current�State,¦**�C�=�Buffer's�Command�Byte,¨**�R�=�Buffer's�Response�Byte,§* *�D0�=�Buffer's�1st�Data�Byte,¦* *�D1�=�Buffer's�2nd�Data�Byte,¦*!*�E�=�Buffer's�Error�Code�Byte,¥*(*�R1�=�NEC7201�Read�Register�One�Byte.ž**Ã*E*********************************************************************,‹PEA‡*(PC)�If�we�get�a�trace�row,�then�trace#‹MOVE.L„(A7)+,0(A2)‰our�PC�address,‹MOVE.L„A3,4(A2)ŒA(Rcv�Buffer),)‹MOVE.B„SDSSEC(A4),8(A2)„Station�address,+‹MOVE.B„SDSCST(A4),9(A2)„His�current�state,0‹MOVE.B„SDDCMD(A3),10(A2)ƒCommand�Byte�(if�any),(‹MOVE.B„SDDRSP(A3),11(A2)ƒResponse�Byte,%‹MOVE.B„SDDDAT+0(A3),12(A2)�First�and.‹MOVE.B„SDDDAT+1(A3),13(A2)�Second�data�bytes,.‹MOVE.B„SDDERR(A3),14(A2)ƒError�code�byte,�and-‹MOVE.B„D0,15(A2)‹Register�1�from�the�NEC7201‰ENDI)‰MOVE.L„(A7)+,A2ŒRecover�A2�after�tracing $‰BTST.L„#7,D0…End�of�Frame�detected?‰BEQ.S…RCVSTSA‰BTST.L„#6,D0…Yes,�FCS�error?‰IFˆ�THEN.S=‹MOVE.B„#SDDECRC,SDDERR(A3)�Yes,�post�the�error�in�the�buffer‹ADD.W…#1,SDSHCRCR(A4)…3/2/83‰ENDI&RCVSTSA‚BTST.L„#5,D0…receiver�overrun?‰IFˆ�THEN.S6‹MOVE.B„#SDDERCU,SDDERR(A3)�Yes,�post�it�in�the�buffer‹ADD.W…#1,SDSHCROR(A4)…3/2/83‰ENDI,‰CMP.B…#SDDERTO,SDDERR(A3)�Receive�time-out?0‰BEQ.L…RECEITO�Yes,�depart�from�here�completely!,‰TST.B…SDDERR(A3)ŠAny�error�detected�so�far?‰IFˆ�THEN.S/‹CMP.B…#SDDERBO,SDDERR(A3)�Yes,�frame�too�long?1‹BNE.L…RCVSTSE�No,�just�ignore�the�received�frame(‹TST.B…SDSCSE(A4)ŠYes,�any�retries�left?-‹BNE.L…RCVSTSE’Yes,�ignore�the�received�frame7* When a Buffer Overrun occurs and no retries are left,J* the overlength frame is passed to the application with the error posted.L* This allows someone to complain about these "big" frames we are receiving.‰ENDI9‰MOVE.W„A1,D0…Calculate�how�many�bytes�are�in�the�buffer,5‰ADD.W…#1,D0…Adding�one�for�1st�FCS�character�overrun‰SUB.W…D0,SDDBCT(A3)C‰CMP.W…#-1,SDDBCT(A3)�Is�the�frame�too�short?�(LT�32�bits?)�8/27/82‰IFˆ�THEN.S8‹MOVE.B„#SDDEIFU,SDDERR(A3)�Yes,�post�the�error‰10/13/82‹ADD.W…#1,SDSHCR32(A4)…3/2/83‹BRA.L…RCVSTSF©10/13/82‰ENDI,‰BTST.B„#0,SDDRSP(A3)‚No,�was�it�an�I�frame?$‰BNE.S…RCVSTSDƒOut�if�not�an�I�frame‰IFEQ†IFRMBCT-YES3‹MOVE.W„SDPRBCT(A5),D0‚I�Frame's�Length�as�Claimed?‹CMP.W…SDDBCT(A3),D0‹BNE.S…RCVSTSB6ˆNo,�branch‰ENDC=‰CMP.B…#SDPTRN,SDPTXF(A5)‚Yes,�did�we�just�send�an�RNR�frame?0‰BNE.S…RCVSTSB3ŒNo,�it's�OK�to�rcv�I�frames�thenHRCVSTSB6�MOVE.B„#SDDEIFU,SDDERR(A3)�Yes,�station�shouldn't�have�sent�it!‰ADD.W…#1,SDSHCRLN(A4)…3/2/83‰BRA.S…RCVSTSB4 ARCVSTSB3�MOVE.B„SDDRSP(A3),D0‡NO,�DOES�Vr�=�Ns�in�received�frame? ‰ASL.B…#4,D0‰AND.B…#$E0,D0‰CMP.B…SDSVRC(A4),D0‰BEQ.S…RCVSTSC:RCVSTSB5�MOVE.B„#SDDENNR,SDDERR(A3)�NO,�SET�Vr�<>�Ns�ERROR‰ADD.W…#1,SDSHCRNR(A4)…3/2/83ARCVSTSB4�BTST.B„#4,SDDRSP(A3)‡Is�the�received�poll/final�bit�set?‰BEQ.S…RCVSTSE-‰BRA.L…RECEIFB�YES,�EXIT�(RECEIVED�FINAL�BIT) 5RCVSTSC‚ADD.B…#$20,SDSVRC(A4)…Vr�=�Ns,�so�Vr�=�Vr�+�1‰AND.B…#$E0,SDSVRC(A4)@RCVSTSD‚BTST.B„#4,SDDRSP(A3)‡Is�the�received�poll/final�bit�set?‰BEQ.S…RCVSTSD1-‰BRA.L…RECEIFB�YES,�EXIT�(RECEIVED�FINAL�BIT) �A2 ‰ADD.L…A3,A2#‰MOVE.L„#0,A1…BUFFER'S�LENGTH�->�A1‰MOVE.W„SDPRLG(A5),A1 ‰MOVE.W„A1,SDDBCT(A3)�BYTE�COUNT"‰CLR.B…SDDERR(A3)„CLEAR�SDLC�ERROR%‰MOVEM.LƒA0-A6,SDPRRTA0(A5)�SAVE�REGS2‰LEA‡RCVST1(PC),A0‡VECTORED�STATE�FOR�1ST�RCV�CHAR‰MOVE.L„A0,SDPVCT3(A5)*‰LEA‡RCVSTSEI(PC),A0…AND�IGNORE�EXT�STATUS‰MOVE.L„A0,SDPVCT2(A5)7‰MOVE.W„#-1,SDPRBCT(A5)…MAKE�COUNT�FIELD�INVALID†3/8/83‰ADD.W…#1,SDSHCRRS(A4)…3/2/835‰MOVE.B„#NCW0RG3,NECCTL_BƒRe-enable�hunt�mode�2/10/83H MOVE.B #NCW3BT8+NCW3AUE+NCW3EHU+NCW3CRC+NCW3ADS+NCW3RXE,NECCTL_B 2/10/8'‰BSR.L…SOMETOUT‚TRIGGER�RECEIVE�TIMEOUT$‰SDLRSRG—Restore�all�registers,�then'‰INTSVRG—Save�only�the�"interrupt"�ones‰BRA.L…INTEXIT 0************************************************0* END OF FILE 'FIX:48.SDLCPRI.RECEIVE.AI' *0************************************************éé‰PAGE5*****************************************************5* BEGINNING OF FILE 'FIX:48.SDLCPRI.SUBRTN.AI' *5*****************************************************   J***************************************************************************È*6*‚SUBROUTINE:‚"SOMETOUT"‚TRIGGER�THE�RECEIVE�TIMEOUT’**È*1*‚ENTER:�A4.L�=�SECONDARY�CONTROL�BLOCK�ADDRESS™**È**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥* *’D�U�U�U¯* *’A�U�U…P…S¥**”|‡|…|_�stackž**”|‡|_______�preservedš**”|_______________�usedŸ**È*J************************************************************************** 7SOMETOUT�LEA‡SDLCTTMOUT(PC),A0ƒACTIVATION�ADDRESS�->�A0'‰CLR.L…D0’TIME�INTERVAL�(IN�MSEC)�->�A1‰MOVE.W„SDSTOC(A4),D0‡*‰BEQ.S…SOMETOU1Œ*‰MULU.W„#TIMCNST,D0‰*‰MOVE.W„D0,A1�*'‰MOVE.W„#$0006,D1‹INTERRUPT�LEVEL�->�D1‰MOVE.L„#DLC2,D2ŒI.D.�#�->�D2‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC3SOMETOU1�RTS›(MUST�BE�A�2�BYTE�INSTRUCTION)�2/24/831‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR!ˆ2/24/83 ‰PAGE J***************************************************************************È*5*‚SUBROUTINE:‚"SOMETOCLR"‚CLEAR�THE�RECEIVE�TIMEOUT“**È**È**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥* *’D�U�U�U¯* *’A�U�U‹S¥**”|�|_�stackž**”|_______________�usedŸ**È*J************************************************************************** 8SOMETOCLR�LEA†SDLCTTMOUT(PC),A0ƒACTIVATION�ADDRESS�->�A0'‰CLR.L…D0’TIME�INTERVAL�(IN�MSEC)�->�D1‰MOVE.W„SDSTOC(A4),D0‡*‰BEQ.S…SOMECLR1Œ*‰MULU.W„#TIMCNST,D0‰*‰MOVE.W„D0,A1�*'‰MOVE.W„#$8006,D1‹INTERRUPT�LEVEL�->�D1‰MOVE.L„#DLC2,D2‹I.D.�#�->�D2‰IFEQ†CHIPTYPE-68000 ‹TR0.RQPA‰ENDC‰IFNE†CHIPTYPE-68000 ‹TR0$.RQPA‰ENDC3SOMECLR1�RTS›(MUST�BE�A�2�BYTE�INSTRUCTION)�2/24/831‰ILLEGAL�DIE�IF�SBRQPA�RETURNS�ANY�ERROR!ˆ2/24/83 ‰PAGE J***************************************************************************È*1*‚SUBROUTINE:‚"SOMEDISPOSE"�DISPOSE�OF�A�BUFFER˜*  N QA+*È*.*‚ENTER:�A1.L�=�ADDRESS�OF�BUFFER�TO�DISPOSEœ*(*‰A5.L�=�PRIMARY�CONTROL�BLOCK�ADDRESS›**È*;*‚RETURN:�A1.L�=�ADDRESS�OF�LINK�FIELD�OF�DISPOSED�BUFFER�**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥**’Dµ* *’A�U�R‡PƒS¥**”|�|‡|ƒ|_�stackž**”|�|‡|_____�preservedš**”|�|_____________�returned›**”|_______________�usedŸ**È*J************************************************************************** #SOMEDISPOSE MOVE.L SDDLNK(A1),-(A7) ‰MOVE.L„A1,A0‰BSR.L…SBPTFRBF‰MOVE.L„(A7)+,A1‰RTS ‰PAGE J***************************************************************************È*?*‚SUBROUTINE:‚"SOMESEND"‚SEND�A�BUFFER�TO�APPLICATION�PROGRAM‰**È*+*‚ENTER:�A1.L�=�ADDRESS�OF�BUFFER�TO�SENDŸ*(*‰A5.L�=�PRIMARY�CONTROL�BLOCK�ADDRESS›**È*7*‚RETURN:�A1.L�=�ADDRESS�OF�LINK�FIELD�OF�SENT�BUFFER“**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥**’D�U³* *’A�U�R‡PƒS¥* *–|‡|ƒ|¥**–|‡|ƒ|_�stackž**–|‡|_____�preservedš**–|_____________�returned›**È*J************************************************************************** SOMESEND�MOVE.L„SDDLNK(A1),-(A7) ‰MOVE.L„A1,A0‰MOVE.L„A2,-(A7)‰BSR.L…SBPTUSQ‰MOVE.L„(A7)+,A2‰MOVE.L„(A7)+,A1‰RTS ‰PAGE J***************************************************************************È*F*‚SUBROUTINE:‚"SOMEFREE"�FREE�THE�LINK�OF�RCV�BUFFERS�TO�BUFFER�POOLƒ**È*5*‚ENTER:�A2.L�=�ADDRESS�OF�FIRST�RCV�BUFFER�TO�FREE•*(*‰A5.L�=�PRIMARY�CONTROL�BLOCK�ADDRESS›**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥**’D�U³* *’A�UƒP…PƒS¥**”|‰|ƒ|_�stackž**”|‰|_____�preservedš**”|_______________�usedŸ**È*J************************************************************************** SOMEFREE�MOVE.L„A2,A0‰BSR.L…SBPTFRML‰RTS ‰PAGE J***************************************************************************È*8*‚SUBROUTINE:‚"FINDSCB"�Find�a�Secondary�Control�Block‘**È*D*‚ENTER:�D1.B�=�Secondary�Station�Address,�or�$FF�(Global�Address)†*7*�Note:�Where�the�Global�Address�is�used,�the�address…*3*–of�the�1st�Secondary�Control�Block�is�returned.ƒ**È*4*‚RETURN:�Negative�=�0�(Plus)�-�SCB�Found,�see�A1,–*** A1�=�A(SCB�-�Secondary�Control�Block),‚*>*ŠNegative�=�1�(Minus)�-�SCB�Not�Found,�A1�is�indeterminite.„**È*#*‚REGISTERS�USED:ƒ0�1�2�3�4�5�6�7¥**’D�P³* *’A�|�R‹S¥**”|�|‹|_�stackž**”|�|_____________�returned›**”|_______________�preservedš**È*J************************************************************************** ‰XDEF†FINDSCB >FLYPAPER�EQU‡$FFFFFFFF‹Fly-Paper,�causes�Address�Error�if�used 8FINDSCB‚MOVE.L„SDLCPCB,A1ŠVia�the�Primary�Control�Block,8‰MOVE.L„SDPFSEC(A1),A1†Find�the�address�of�the�first�SCB‰IF.B†D1��#$FF�THEN.S9‹WHILE.BƒSDSSEC(A1)��#0�AND.B�SDSSEC(A1)��D1�DO.S&�ADDA.L„#SDSLNG,A1ŠAdvance�to�next�SCB‹ENDW‰ENDI‰IF.B†SDSSEC(A1)��#0�THEN.S0‹MOVE.L„#FLYPAPER,A1ˆNot�Found,�A1�=�Bug�Catcher ‹ORI.B…#$08,CCRŒAnd�Negative�=�1‰ELSE.S1‹ANDI.B„#$F7,CCRŒFound,�Negative�=�0,�A1�=�A(SCB)‰ENDI‰RTS ‰PAGE J***************************************************************************È*1*‚SUBROUTINE:‚"GETRACE"�Get�a�Trace�Row�Address˜**È**‚ENTER:�No�Arguments³**È*A*‚RETURN:�Carry�=�0�(Carry�Clear)�-�Trace�Row�Address�Returned,‰**¤A2�=�A(Trace�Row),’*%*¤(The�trace�flag�is�on�and�a�traceƒ**¥area�exists),–*3*ŠCarry�=�1�(Carry�Set)�-ƒNo�Trace�Row�Available,�**¤A2�=�#$FFFFFFFF,”*%*¤(Either�the�trace�flag�is�off,�orƒ**¥no�trace�area�exists).�**È*H*‚Note:�The�sixteen�bytes�from�0(A2)�thru�15(A2)�are�available�for�any‚*B*ˆtrace�information�(when�the�"Not�Equal"�return�occurs).‚Common�*B*ˆusage�is�to�store�the�current�PC�value�at�0(A2).L,�identifying‚*B*ˆthe�procedure�which�is�tracing,�followed�by�procedure�specific‚**ˆtrace�information.®*! *È**‚Example�Usage:¸*+*ŠMOVE.L„A2,-(A7)ŒProtect�A2�if�necessary‰*!*ŠBSR.L…GETRACE�Get�a�trace�row‘*)*ŠIFˆ�THEN.S‰If�a�row�is�available,Š* *ŒPEA‡*(PC)­***ŒMOVE.L„(A7)+,0(A2)‰Store�my�PC�address‹**ŒMOVE.B„x,4(A2)«**ŒMOVE.B„y,5(A2)«*)*ŒMOVE.L„z,6(A2)�Store�some�informationˆ**ŒMOVE.L„a,10(A2)ª*.*ŒMOVE.W„b,14(A2)Œ-�Do�Not�Exceed�15(A2).B�-„**ŠENDIº*0*ŠMOVE.L„(A7)+,A2Œand�recover�A2�(if�"pushed")„**È*J************************************************************************** ‰XREF†TRACEBEG GETRACE‚MOVE.L„TRACEBEG,A2‰BTST.B„#0,TRACFLAG+1 ‰IFˆ�AND.L�A2��#0�THEN.S‹MOVEM.LƒA3-A4,-(A7)0‹MOVE.L„A2,A3�A3�=�A(Trace�control�&�trace�area)‹MOVE.W„SR,-(A7) ‹ORI.W…#$0700,SR‹MASK�INTERRUPTS ‹MOVE.L„0(A3),A2ŒGet�A(Next�Row)%‹LEA‡16(A2),A4‹Figure�A(New�Next�Row)‹IF.L†A4��4(A3)�THEN.S.�LEA‡8(A3),A4ŠReset�to�beginning�when�past�end �MOVE.L„A4,A2�LEA‡16(A2),A4‹ENDI4‹MOVE.L„A4,0(A3)ŒStore�new�A(Next�Row)�for�next�time"‹MOVE.W„(A7)+,SRŒUNMASK�INTERRUPTS)‹LEA‡15(A2),A4‹See�if�a�"Full�Row"�exists‹IF.L†A4��4(A3)�THEN.S,�ANDI.Bƒ#$FE,CCR�and�assert�Row�Exists�if�OK‹ELSE.S3�MOVE.Lƒ#FLYPAPER,A2‰otherwise,�A2�=�#$FFFFFFFF�and�ORI.B„#$01,CCR˜No�Row�Exists‹ENDI‹MOVEM.Lƒ(A7)+,A3-A4‰ELSE.S.‹MOVE.L„#FLYPAPER,A2ˆelse,�A2�=�#$FFFFFFFF�and‹ORI.B…#$01,CCR’No�Row�Exists‰ENDI‰RTS /***********************************************/* END OF FILE 'FIX:48.SDLCPRI.SUBRTN.AI' */***********************************************ééé‰PAGE7*******************************************************7* BEGINNING OF FILE 'FIX:48.SDLCPRI.TRANSMIT.AI' *7******************************************************* H*************************************************************************(*ˆMODULE:‚"TRANSMT"�TRANSMIT�SDLC�FRAMES*-*ˆENTER:‚A5.L�=�PRIMARY�CONTROL�BLOCK�ADDRESS(*�A4.L�=�SECONDARY�CONTROL�BLOCK�ADDRESS%*�A3.L�=�BUFFER�CONTROL�BLOCK�ADDRESS9*ˆENTRY�ASSUMES�A0-A6/D0-D7�HAVE�BEEN�PUSHED�ON�THE�STACK5*–AND�ENTRY�WAS�THROUGH�EXCEPTION�(TRAP�OR�INTERRUPT)2*ˆEXIT:‚"TRANSUF"‚A�TRANSMIT�UNDERFLOW�CAUSED�EXIT-*�"TRANSEQ"‚END�OF�TRANSMIT�QUEUE�CAUSED�EXIT6*�"TRANSPB"‚SDLC�COMMAND�WITH�POLL�BIT�SET�CAUSED�EXIT!*ˆREGISTERS�USED:ƒ0�1�2�3�4�5�6�7*˜D�U*˜A�U�U�U�U�P�PƒS* |ƒ|ƒ|_�stack* |ƒ|_____�preserved* |_________�used#*ˆEXITS�TO�EXTERNALLY�DEFINED�LABEL&*ŽWITH�A0-A6/D0-D7�PUSHED�ON�THE�STACK&*ŽAND�ASSUMES�FINAL�EXIT�WILL�BE�"RTE"*H************************************************************************E* NOTE: ALL INFORMATION FRAMES HAVE THEIR LENGTHS TRANSMITTED AS WELLA*�AS�THEIR�DATA.‚THE�LENGTH�IS�SENT�AS�THE�FIRST�TWO�BYTES�OF�THE* INFORMATION FIELD AS FOLLOWS;N*
H*�THE�RECEIVING�STATION�MUST,�OF�COURSE,�EXPECT�THIS.‚THE�LENGTH�IS�SENTM* AS THE NEC7201 HAS THE NASTY TENDENCY TO SEND THE FRAME CHECK SEQUENCE WHENN*�A�TRANSMITTER�UNDERRUN�OCCURS.‚IF�WE�DO�THIS�BY�ACCIDENT,�THEN�WE�MUST�BEGINL* SENDING AN ABORT WITHIN THREE CHARACTER TIMES (TWO FCS CHARACTERS PLUS THEL*�ENDING�FLAG)�FOR�THE�RECEIVING�STATION�TO�KNOW�THAT�WE�GOOFED.‚IF�FOR�SOMEH* REASON WE DON'T INITIATE THE ABORT IN TIME, WITHOUT THE DATA COUNT THEK* RECEIVING STATION WOULD HAVE NO WAY OF K! NOWING THAT THE FRAME HE HAS JUSTM*�RECEIVED�IS�NO�GOOD.‚THE�RECEIVER�HANDLES�THIS�"BAD�LENGTH"�FRAME�JUST�LIKE>* ANY OTHER ERRONEOUS FRAME - HE IGNORES THE FRAME COMPLETELY. :TRANSMT‚MOVE.B„#SDPBTX,SDPBSY(A5)‚Set�us�busy�transmitting!+*92:8B>J6RJZEb>j‰ADD.W…#1,SDSHCTXM(A4)…3/2/83‰OR.W†#$700,SRŒMask�Interrupts!<‰MOVE.B„#NCW0REX+NCW0RG1,NECCTL_B�Reset�any�pending�ExternalB‰MOVE.B„#NCW1EXI+NCW1STV,NECCTL_B�Enable�only�ExtStatus�(not�Xmtr)‰MOVE.B„#NCW0RG5,NECCTL_B9‰MOVE.B„#NCW5DTR+NCW5TX8+NCW5TXE+NCW5RTS+NCW5TCE,NECCTL_B ‰PAGE C* DTR and RTS are now active, wait for CTS to become active as well ‰MOVE.B„NECCTL_B,D0.‰BTST.L„#5,D0�Is�Clear�to�Send�already�active?‰IFˆ�THEN.S)‹LEA‡TXMSTCTS(PC),A0…No,�Must�wait�for�it7‹MOVE.L„A0,SDPVCT2(A5)†ExtStatus�to�TXMSTCTS�(CTS�Wait)‹LEA‡TXMSTOFF(PC),A0;‹MOVE.L„A0,SDPVCT1(A5)†and�XmtrEmpty�to�TXMSTOFF�(Xmtr�Off)‹MOVEM.LƒA0-A6,SDPRRTA0(A5)‹SDLRSRG‹INTSVRG'‹BRA.L…INTEXIT�Exit�till�CTS�comes�true *#* External Status Interrupt Handler*0TXMSTCTSƒMOVE.B„NECCTL_B,D0‰ExtStatus�Interrupt,‹MOVE.B„#NCW0REX,NECCTL_B+‹MOVE.B„#NCW0EOI,NECCTL_AƒAck�the�interrupt*‹BTST.L„#5,D0�Is�Clear�to�Send�now�active?‹IFˆ�THEN.S!�BRA.L…INTEXIT‹No,�wait�some�more‹ENDI‹INTRSRG‹SDLSVRG)‹MOVE.L„SDLCPCB,A6ŠYes,�Now�we�can�begin!0‹MOVEM.LƒSDPRRTA0(A6),A0-A6‚Restore�BG�Registers‰ENDI * Fall-thru to the next page‰PAGE7* NOTE: WE MAY FALL-THRU TO HERE FROM THE PREVIOUS PAGE ‰MOVE.B„#NCW0RG1,NECCTL_B@‰MOVE.B„#NCW1TXI+NCW1EXI+NCW1STV,NECCTL_B�Enable�Xmtr�Interrupts )* Pre-frame transmission delay algorithm.+* Replaced on August 23, 1983 by Ed Skinner*D*†Where�a�pre-frame�transmission�delay�is�required,�we�send�a�"null"L*�frame�consisting�of�the�specified�number�of�bytes.‚This�frame�is�addressedH* to station $00 (there ain't no such station), and is not sent with anyJ*�FCS.‚These�two�conditions�(station�$00�and�no�FCS)�should�guarantee�that3* no station receives this as a valid transmission.E*†A�pre-frame�transmission�delay�is�needed�for�either�of�two�reasons.J* First, where Mancester encoding is used (such as in the Exormacs/HDS-400G* and GMAD Weld Monitor configurations), the Mancester chip will supplyM* Transmit Clock to the NEC7201 sometime after RTS is output (from the 7201).K* The single leading flag sent by the NEC7201 is not always received intactL*�by�the�target�station.‚This�may�be�due�to�some�difficulty�in�the�MancesterJ*�receiver�and/or�NEC7201.‚Regardless,�it�remains�that�the�first�characterM* transmitted by the NEC7201 (an SDLC Flag) is not always received correctly.C*†Secondly,�a�pre-frame�transmission�delay�may�be�used�to�allow�theM* receiving software (in the target node) additional time in which to prepare* for receiving a frame.D*†To�effect�the�pre-frame�transmission�delay,�a�frame�containing�$00I*�bytes�in�all�fields�is�transmitted.‚As�the�station�address�$00�is�not�aI* valid station address according to the SDLC protocol, no station should.* begin active reception of this "null" frame.F*†Once�the�specified�number�of�"null"�bytes�have�been�transmitted,�theI* transmitter is allowed to revert to the "flagging" condition (no FCS isG*�sent).‚Since�any�receiver�of�this�frame�will�think�the�last�two�bytesH* are the FCS, and as these bytes do not contain the computed FCS, it isI* unlikely (1 chance in 65535) that it will appear to be the correct FCS.I* Additionally, since the odds of a transmission error which would changeG* the address field to some "real" station address are much more remoteF* (although no information is available in this regard, the error rateF* should be similar to that of a satellite link (1 in 10**9) or betterJ* considering the "protected" " environment and circuit length), the overallF* probability of some station receiving this leading transmission as aE*�valid�frame�are�comfortably�remote.‚(Besides�that,�the�reason�we'reE* sending this little sucker is because the first frame usually isn'tJ*�received�as�the�leading�flag�is�missed.‚This�makes�it�even�more�unlikelyB* that this leading pad frame might be received as a valid frame.)D*†Note�that�when�a�frame�transmission�completes,�we�do�not�send�thisK* "leading pad" frame when more than one frame is sent in quick succession. 2TXMSTPAD�TST.W…SDSTPD(A4)ŠAny�leading�frame�delay?‰IFˆ�THEN.S1‹MOVE.W„SDSTPD(A4),A1‡Yes,�A1.W�=�Character�Count‹LEA‡TXMSTPNX(PC),A08‹MOVE.L„A0,SDPVCT1(A5)†Xmtr�Intr�-->�TXMSTPNX�(Next�Pad)‹LEA‡TXMSTEI(PC),A07‹MOVE.L„A0,SDPVCT2(A5)†ExtSta�Intr�-->�TXMSTEI�(Ignore)‹MOVEM.LƒA0-A6,SDPRRTA0(A5)‹SDLRSRG‹INTSVRG9‹MOVE.B„#$00,NECDAT_B‡Send�Station�Address�=�$00�(Nobody)#‹BRA.L…INTEXIT�Exit�till�Xmtr�Empty ‰PAGE*%* Transmitter Empty Interrupt Handler*B* Enter here upon Transmitter Empty interrupts where the last byteE*�output�is�now�being�transmitted�by�the�NEC7201.‚Because�the�NEC7201J* gives us the Transmitter Empty interrupt up to one character time beforeF* the character is actually needed, there is a one character "latency"E*�between�what�we�output,�and�what�the�NEC7201�is�sending.‚Therefore,H* we actually output one more than the specified number of leading pads,H* and terminate this operation when we get the interrupt indicating thatG* the last byte output (the "extra" byte) is now being transmitted, andI* therefore, that the specified number of leading pads have, in fact, now* all been transmitted. 5TXMSTPNXƒSUB.W…#1,SDPRRTA1+2(A1)ƒSent�one�delay�byte,‹IFˆ�THEN.S7�MOVE.B„#$00,NECDAT_B‡Send�another�till�count�exhausted*�MOVE.B„#NCW0EOI,NECCTL_AƒEnd�of�Interrupt.�BRA.L…INTEXIT�And�exit�till�another�Xmtr�Intr‹ENDI1‹MOVE.B„#NCW0EOI,NECCTL_AƒEnd�of�Interrupt�(Xmtr)‹INTRSRG‹SDLSVRG‹MOVE.L„SDLCPCB,A60‹MOVEM.LƒSDPRRTA0(A6),A0-A6‚Restore�BG�Registers‰ENDI%* And begin sending the "real" frame. %TXMSTNXT�ADD.W…#1,SDSHCTXS(A4)‡3/2/83* Fall-thru to the next page‰PAGE8* NOTE: WE WILL FALL-THRU TO HERE FROM THE PREVIOUS PAGE 7* "EMBELLISH" SDLC COMMAND WITH Nr/Ns COUNTS & POLL BIT ‰MOVE.B„SDDCMD(A3),D0‰AND.B…#$03,D0‰IF.B†D0��#3�THEN.S#‹MOVE.B„SDDCMD(A3),D0ƒS�or�I�frame,‹AND.B…#$1F,D0/‹OR.B†SDSVRC(A4),D0ƒOR�in�the�current�Vr�count. ‹BTST.L„#0,D0‹IFˆ�THEN.S�AND.B…#$F1,D0‰I�frame,4�OR.B†SDSVSC(A4),D0ƒOR�in�the�current�Vs�count�also,(�OR.B†#$10,D0‰assert�the�poll/final�bit,/�ADD.B…#2,SDSVSC(A4)ƒ(Advance�Vs�for�next�time):�AND.B…#$0E,SDSVSC(A4)ƒ(making�sure�it's�only�3�bits�wide)3�ADD.B…#1,SDSUKT(A4)ƒbump�the�number�of�frames�out,�MOVE.B„SDSUKT(A4),D11�TST.L…SDDLNK(A3)†any�more�frames�after�this�one?(�IFˆ�AND.B�D1��SDSMXF(A4)�THEN.S9�MOVE.L„SDDLNK(A3),A0ƒyes,�and�haven't�reached�max�limit,�BTST.B„#0,SDDCMD(A0)�IFˆ�THEN.S2‘AND.B…#$EF,D0‰don't�poll/final�if�next�is�I�frame�ENDI�ENDI‹ELSE.S�MOVE.B„D0,D1ŽIf�we�are�sending*�AND.B…#$1F,D1Œa�Receiver�Not�Ready�frame,!�IF.B†D1��#SDDRRNR+$10�THEN.S/�MOVE.B„#SDPTRN,SDPTXF(A5)�Then�assert�RNR�Sent�ENDI‹ENDI7‹MOVE.B„D0,SDDCMD(A3)‡Store�the�command�byte�to�be�sent‰ENDI* Fall-thru to the next page‰PAGE8* NOTE: WE WILL FALL-THRU TO HERE FROM THE PREVIOUS PAGE 8‰LEA‡TXMST0(PC),A0‡Prepare�interrupt�vectors�for�sending‰MOVE.L„A0,SDPVCT1(A5)<‰LEA‡TXMSTEI(PC),A0†For�1st�Char�Out,�we�ignore�ExtSta�Intrs‰MOVE.L„A0,SDPVCT2(A5) .‰LEA‡SDDDAT(A3),A2‡A2�=�A(data�area�of�buffer) +‰MOVE.B„SDDCMD(A3),D0‡Figure�I�field�length)‰AND.B…#$03,D0�according�to�type�of�frame‰IF.B†D0��#$01�THEN.S<‹MOVE.W„SDDBCT(A3),A1‡I�and�U�frames�specify�I�field�lengths‰ELSE.S2‹MOVE.W„#0,A1�While�S�frames�never�have�an�I�field‰ENDI C‰MOVEM.LƒA0-A6,SDPRRTA0(A5)‚Save�regs�for�" interrupt�handlers�to�use* A5 = SDPRRTA5 = A(PCB)* A4 = SDPRRTA4 = A(SCB)* A3 = SDPRRTA3 = A(Buffer)(* A2 = SDPRRTA2 = A(Data within I field)#* A1 = SDPRRTA1 = Length of I fieldG* A0 = SDPRRTA0 = Not used for anything special - just leftover garbage ‰ADD.W…#1,SDSHCTXA(A4)…3/2/83 ‰MOVE.B„SDSSEC(A4),D0‡3/3/832‰IF.B†D0��SDDSEC(A3)�AND.B�D0��#$FF�THEN.S$‹ILLEGAL—Die�if�bad�station�address!‰ENDI* Fall-thru to the next page‰PAGE8* NOTE: WE WILL FALL-THRU TO HERE FROM THE PREVIOUS PAGE )‰MOVE.L„A2,-(A7)ŒProtect�A2�while�tracing‰BSR.L…GETRACE�Get�a�trace�row‰IFˆ�THEN.SE**********************************************************************�Trace�Entry�Format°*E**********************************************************************Ã*'*‚+0Ž+4Ž+8‚+9‚+10�+11�+12�+13�+14�+15‚*E* +---------------+---------------+---+---+---+---+---+---+---+---+ *:*�!†PC‡!�A(Xmt�Buffer)�!�#�!�S�!�U�!�C�!�RC!�D0!�D1!�0�!�*E* +---------------+---------------+---+---+---+---+---+---+---+---+ **Ã**�PC�=�Program�Counter,­*<*�A(Xmt�Buffer)�=�Address�of�the�buffer�to�be�transmitted,Š**�#�=�Station's�Number,­* *�S�=�Station's�Current�State,¦*/*�U�=�Station's�Current�Unacknowledged�Count,—**�C�=�Buffer's�Command�Byte,¨**�RC�=�Buffer's�Retry�Count,¨* *�D0�=�Buffer's�1st�Data�Byte,¦* *�D0�=�Buffer's�2nd�Data�Byte,¦**�0�=�Unused.·**Ã*E*********************************************************************,‹PEA‡*(PC)�If�we�get�a�trace�row,�then�trace#‹MOVE.L„(A7)+,0(A2)‰our�PC�address, ‹MOVE.L„A3,4(A2)ŒA(Xmit�buffer),)‹MOVE.B„SDSSEC(A4),8(A2)„Station�Address,+‹MOVE.B„SDSCST(A4),9(A2)„His�current�state,7‹MOVE.B„SDSUKT(A4),10(A2)ƒCurrent�unacknowledged�count,'‹MOVE.B„SDDCMD(A3),11(A2)ƒCommand�byte,&‹MOVE.B„SDDRTC(A3),12(A2)ƒRetry�Count,%‹MOVE.B„SDDDAT+0(A3),13(A2)�and�first4‹MOVE.B„SDDDAT+1(A3),14(A2)�...�.....�two�data�bytes$‹CLR.B…15(A2)Ž(Zero�the�unused�byte)‰ENDI)‰MOVE.L„(A7)+,A2ŒRecover�A2�after�tracing ?‰MOVE.B„#NCW0RTG,NECCTL_B„Reset�the�transmitter's�FCS�generatorB‰MOVE.B„SDDSEC(A3),NECDAT_B‚Output�the�secondary�station's�address=‰MOVE.B„#NCW0RTU,NECCTL_B„Enable�FCS�transmission�on�Underrun ‰SDLRSRG—Recover�all�registers,,‰INTSVRG—Make�stack�look�like�interrupt�regs4‰BRA.L…INTEXIT�And�go�see�if�an�interrupt�is�pending‰PAGE *%* Transmitter Empty Interrupt Handler*,*ˆVECTORED�STATE�TO�TxMIT�SDLC�COMMAND�FIELD*ATXMST0ƒMOVE.B„NECCTL_B,D0‰Since�we've�been�ignoring�ExtSta�Intrs,2‰BTST.L„#6,D0�We�now�check�for�an�earlier�underrun,‰BNE.L…TXMSTE1�If�true,�go�send�an�Abort�now"‰MOVE.L„SDPRRTA3(A1),A2…Otherwise,2‰MOVE.B„SDDCMD(A2),NECDAT_B�Send�the�command�field‰IFEQ†IFRMBCT-YES6‹BTST.B„#0,SDDCMD(A2)‡Where�we�are�sending�an�I�frame,‹BNE.S…TXMST012‹LEA‡TXMSTL1(PC),A2†We�Send�a�"Length"�Field�first‹BRA.S…TXMST02‰ENDCATXMST01‚LEA‡TXMST1(PC),A2‡Set�Up�the�Next�Xmtr�Empty�Intr�HandlerTXMST02‚MOVE.L„A2,SDPVCT1(A1)1‰LEA‡TXMSTE(PC),A2‡And�from�now�on,�we�care�about1‰MOVE.L„A2,SDPVCT2(A1)†External�Status�Interrupts‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE ‰IFEQ†IFRMBCT-YES*%* Transmitter Empty Interrupt Handler**/*ˆVECTORED�STATE�TO�TxMIT�SDLC�LENGTH�FIELD�#�1*7TXMSTL1‚MOVE.L„SDPRRTA3(A1),A2�OUTPUT�SDLC�LENGTH�FIELD‰MOVE.B„SDDBCT(A2),NECDAT_B‚*+‰LEA‡TXMSTL2(PC),A2†SET�NEXT�VECTORED�STATE‰MOVE.L„A2,SDPVCT1(A1)†*‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE *%* Transmitter Empty Interrupt Handler**/*ˆVECTORED�STATE�TO�TxMIT�SDLC�LENGTH�FIELD�#�2*7TXMSTL2‚MOVE.L„SDPRRTA3(A1),A2�OUTPUT�SDLC�LENGTH�FIELD"‰MOVE.B„SDDBCT+1(A2),NECDAT_B�*œ10*‰LEA‡TXMST1(PC),A2‡SET�NEXT�VECTORED�STATE‰MOVE.L„A2,SDPVCT1(A1)†*‰MOVE.B„#NCW0EOI,NECCTL_A„*�10‰BRA.L…INTEXIT‡*‚ENDC ‰PAGE *#* External Status Interrupt Handler**4*ˆVECTORED�STATE�TO�PROCESS�STATUS�CHANGE�INTERRUPTS*!TXMSTEƒMOVE.B„NECCTL_B,D0‰GET�RR0‰BTST.L„#6,D# 0�UNDERRUN?(‰BNE.S…TXMSTE1�YES,�HURRY�AND�SEND�ABORTTXMSTE0‚BTST.L„#5,D0�CTS�DROP?%‰BEQ.S…TXMSTE1�YES,�XMTR�DYING,�ABORT'‰BRA.S…TXMSTE2�NO,�IGNORE�THE�INTERRUPT 3TXMSTE1‚MOVE.B„#NCW0SAB,NECCTL_BƒSEND�AN�SDLC�ABORT‰MOVE.L„SDPRRTA4(A1),A2‰ADD.W…#1,SDSHCTUN(A2)4‰MOVE.L„SDPRRTA3(A1),A2…RESTORE�BUFFER�CONTROL�BLOCK0‰MOVE.B„#SDDETXU,SDDERR(A2)�TxMIT�UNDERRUN�ERROR*‰MOVE.B„#NCW0REX,NECCTL_BƒRESET�INTERRUPTS‰MOVE.B„#NCW0EOI,NECCTL_A‰INTRSRG—SAVE�ALL�USER'S�REGS‰SDLSVRG‰MOVE.L„SDLCPCB,A5ŠRESTORE�REGS‰MOVEM.LƒSDPRRTA3(A5),A3-A5(‰BRA.L…TRANSUF�EXIT�(TRANSMIT�UNDERFLOW) ETXMSTE2‚MOVE.B„#NCW0REX,NECCTL_BƒIgnore�the�External�Status�Interrupt‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE *%* Transmitter Empty Interrupt Handler**0*ˆVECTORED�STATE�TO�TxMIT�SDLC�INFORMATION�FIELD*>TXMST1ƒSUB.W…#1,SDPRRTA1+2(A1)ƒDecrement�number�of�bytes�to�go‰IFˆ�THEN.S/‹MOVE.L„SDPRRTA2(A1),A2…If�"more"�bytes�remain,5‹MOVE.B„(A2)+,NECDAT_B‡Output�the�next�data�byte,�and7‹MOVE.L„A2,SDPRRTA2(A1)…Save�data�pointer�for�next�time‰ELSE.S9‹LEA‡TXMSTOFF(PC),A2…When�done,�prepare�to�send�FCS�bytes/‹MOVE.L„A2,SDPVCT1(A1)†(Xmtr�Intr�not�expected)0‹LEA‡TXMST2(PC),A2‡and�Expect�an�External�Status&‹MOVE.L„A2,SDPVCT2(A1)†interrupt�next,9‹MOVE.B„#NCW0RTI,NECCTL_BƒAnd�make�the�Xmtr�Empty�go�away‰ENDI6‰MOVE.B„#NCW0EOI,NECCTL_AƒEither�way,�End�of�Interrupt‰BRA.L…INTEXIT ‰PAGE *#* External Status Interrupt Handler* *ˆVECTORED�STATE�TO�TRANSMIT�CRC*0TXMST2ƒMOVE.B„NECCTL_B,D0‰Get�the�Chip's�Status,(‰BTST.L„#6,D0�Is�it�sending�the�FCS�now?$‰BEQ.L…TXMSTE0�No,�go�check�CTS�fall5‰LEA‡TXMSTEI(PC),A2†Yes,�Chip�is�now�sending�the�FCS.3‰MOVE.L„A2,SDPVCT2(A1)†Ignore�Underruns�from�now�on‰MOVE.B„#NCW0REX,NECCTL_B‰MOVE.B„#NCW0EOI,NECCTL_AƒAnd2‰LEA‡TXMST3(PC),A2‡Set�up�for�Xmtr�Empty�Interrupt,‰MOVE.L„A2,SDPVCT1(A1)†To�take�us�to�TXMST3.4‰BRA.L…INTEXIT�(Occurs�when�FCS�sending�is�complete) ‰PAGE *%* Transmitter Empty Interrupt Handler*(*ˆVECTORED�STATE�AFTER�CRC�HAS�BEEN�SENT* TXMST3ƒINTRSRG—SAVE�ALL�REGS�NOW‰SDLSVRG‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A6.‰BTST.B„#4,SDDCMD(A3)‡POLL�BIT�SET�IN�COMMAND?‰BNE.S…TXMST3A�Yes,�See�below‰MOVE.B„#NCW0EOI,NECCTL_AƒNo,6‰MOVE.L„SDDLNK(A3),A3‡Is�there�something�else�to�send? ‰MOVE.L„A3,D04‰BNE.L…TXMSTPADŽYup,�go�send�it�(with�leading�delay)'‰ADD.W…#1,SDSHCTNP(A4)…No,�done�sending+‰BRA.L…TRANSEQ�Go�figure�out�what�to�do�now ‰PAGE J* WHEN WE ARE READY TO SHUT DOWN THE TRANSMITTER, WE MUST DELAY FOR 11 BITJ* TIMES TO ALLOW THE ENDING FLAG TO LEAVE THE SHIFT REGISTER (8 BIT TIMES)L* AND TO PASS THRU OTHER HARDWARE (SUCH AS THE MANCESTER ENCODER WHICH NEEDSJ*�3�MORE�BIT�TIMES).‚SINCE�WE�CANNOT�MEASURE�INDIVIDUAL�BIT�TIMES,�WE�WAITL* A TOTAL OF 16 BIT TIMES BY SENDING TWO "PAD" CHARACTERS CONSISTING OF $00.M* THIS VALUE IS USED AS NO SECONDARIES HAVE THIS ADDRESS AND, THEREFORE, NONEK*�OF�THEM�WILL�START�TO�RECEIVE�THIS�INFORMATION.‚ADDITIONALLY,�WE�TURN�THEM* TRANSMITTER OFF AFTER THE LAST ONE IS OUT WITHOUT SENDING ANY FCS SEQUENCE.K* TURNING THE TRANSMITTER OFF, IF SOMEONE IS RECEIVING AT THAT TIME, CAUSESI* THE LINE TO GO TO A MARKING STATE WHICH WILL CAUSE THEM TO DETECT FIRSTI*�A�RECEIVE�ABORT,�AND�THEN�A�MARKING�(IDLE)�LINE.‚FROM�THESE�INDICATIONSF* WE ARE ASSURED THAT NO STATION WILL RECEIVE THESE TRAILING PADS AS A+*�VALID�FRAME.ƒED�SKINNER,�MARCH�2,�1983... /TXMST3A‚MOVE.B„#$00,NECDAT_B�OUTPUT�A�NULL�CHAR*‰LEA‡TXMST4(PC),A0‡SET�NEXT�VECTORED�STATE‰MOVE.L„A0,SDPVCT1(A5)‰MOVE.B„#NCW0EOI,NECCTL_A&‰SDLRSRG—Restore�full�set�of�registers$‰INTSVRG—And�stack�the�interrupt�set4‰BRA.L…INTEXIT�And�go�see�if�another�interrupt�pends ‰PAGE *%* Transmitter Empty Interrupt Handler***ˆOUTPUT�2ND�NULL�CHAR*-TXMST4ƒMOVE.B„#$00,NECDAT_B�OUTPUT�A�PAD�NULL*‰LEA‡TXMST5(PC),A2‡SET�NEXT�VECTORED�STATE‰MOVE.L„A2,SDPVCT1(A1)‰MOVE.B„#NCW0EOI,NECCTL_A‰BRA.L…INTEXIT ‰PAGE # *%* Transmitter Empty Interrupt Handler**E*ˆTxMIT�SHUTDOWN�WITH�POLL�BIT�SET�IN�COMMAND�(NOT�NECESSARILY!�E.S.)*=TXMST5ƒMOVE.B„#NCW0EOI,NECCTL_A�LETS�SAVE�ALL�THE�USER'S�REGSTXMENDƒINTRSRG‰SDLSVRG‰MOVE.L„SDLCPCB,A6�RESTORE�REGS‰MOVEM.LƒSDPRRTA0(A6),A0-A6‰ADD.W…#1,SDSHCTEN(A4)…3/2/83"‰BRA.L…TRANSPBƒEXIT�(POLL�BIT�SET) ‰PAGE *#* External Status Interrupt Handler**8*ˆEXTERNAL�STATUS�INTERRUPT�HANDLER�WHICH�IS�USED�DURING*’1)�LEADING�PAD�TRANSMISSION,+*’2)�TRANSMISSION�OF�THE�ADDRESS�FIELD,�AND*’3)�TRAILING�PAD�TRANSMISSION.@*ˆIN�ALL�THREE�CASES,�"UNDERRUN"�INDICATIONS�ARE�IGNORED�AS�WELL=*ˆAS�ALL�OTHER�CONDITIONS�EXCEPT�FOR�A�FALL�OF�CLEAR�TO�SEND.*0TXMSTEI‚MOVE.B„NECCTL_B,D0‰GET�THE�CHIP'S�STATUS/‰MOVE.B„#NCW0REX,NECCTL_BƒRESET�EXTERNAL�STATUS.‰MOVE.B„#NCW0EOI,NECCTL_AƒAND�END�OF�INTERRUPT‰MOVE.L„SDPRRTA4(A1),A2…3/2/83‰ADD.W…#1,SDSHCEXA(A2)…3/2/83?‰BTST.L„#5,D0…CTS�fall?‚If�yes,�then�must�assume�frame�sent�OK,=‰BEQ.S…TXMEND„We�"assume"�poll�bit�sent,�and�go�into�rcv�now.I* CTS did not drop, so we ignore the External Status Interrupt completely‰BRA.L…INTEXIT ‰PAGE *%* Transmitter Empty Interrupt Handler*F* This state is to be used when transmitter interrupts are supposed toE*�be�off,�or�are�otherwise�not�expected.‚If�one�happens�while�in�this-* state, the system is intentionally crashed.* 2TXMSTOFF�CRASH.Tƒ*+1‘Fail�with�an�Addressing�Error 1*************************************************1* END OF FILE 'FIX:48.SDLCPRI.TRANSMIT.AI' *1*************************************************ééééééééé$ éééééééééééééééé$ éééééééééééééééé% éééééééééééééééé% éééééééééééééééé& éééééééééééééééé& éééééééééééééééé' éééééééééééééééé' éééééééééééééééé( éééééééééééééééé( éééééééééééééééé) éééééééééééééééé) éééééééééééééééé* éééééééééééééééé* éééééééééééééééé+ éééééééééééééééé+ éééééééééééééééé, éééééééééééééééé, éééééééééééééééé- éééééééééééééééé- éééééééééééééééé. éééééééééééééééé. éééééééééééééééé/ éééééééééééééééé/ éééééééééééééééé0 éééééééééééééééé0 éééééééééééééééé1 éééééééééééééééé1 éééééééééééééééé2 éééééééééééééééé2 éééééééééééééééé3 éééééééééééééééé3 éééééééééééééééé4 éééééééééééééééé4 éééééééééééééééé5 éééééééééééééééé5 éééééééééééééééé6 éééééééééééééééé6 éééééééééééééééé7 éééééééééééééééé7 éééééééééééééééé8 éééééééééééééééé8 éééééééééééééééé9 éééééééééééééééé9 éééééééééééééééé: éééééééééééééééé: éééééééééééééééé; éééééééééééééééé; éééééééééééééééé< éééééééééééééééé< éééééééééééééééé= éééééééééééééééé= éééééééééééééééé> éééééééééééééééé> éééééééééééééééé? éééééééééééééééé? éééééééééééééééé@ éééééééééééééééé@ ééééééééééééééééA ééééééééééééééééA ééééééééééééééééB ééééééééééééééééB ééééééééééééééééC ééééééééééééééééC ééééééééééééééééD ééééééééééééééééD ééééééééééééééééE ééééééééééééééééE ééééééééééééééééF ééééééééééééééééF ééééééééééééééééG ééééééééééééééééG ééééééééééééééééH ééééééééééééééééH ééééééééééééééééI ééééééééééééééééI ééééééééééééééééJ ééééééééééééééééJ ééééééééééééééééK ééééééééééééééééK ééééééééééééééééL ééééééééééééééééL ééééééééééééééééM ééééééééééééééééM ééééééééééééééééN ééééééééééééééééN ééééééééééééééééO ééééééééééééééééO éééééééééééééééé