IMD 1.17: 11/11/2014 10:49:08 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 5 OF 30  SR05q82VKXSVRDOS 0420¥l-ŠTTL„DARTDRV:‚VERSADOS�SCN2681�TERMINAL�DRIVER�WITH�TYPE-AHEAD ŠLLENƒ120J**************************************************************************J**************************************************************************J**************************************************************************J***************************************************************************<*‰DARTDRV:‚VERSAdos�SCN2681�terminal�driver�with�type-ahead.*8*‰Purpose:‚VERSAdos�device�driver�to�handle�asynchronous2*�terminals�(of�any�type)�over�the�SCN2681�chip�on*�the�following�boards:2*“MVME115„MVME115-A�(This�one�not�implemented�yet)**‰Revision�history:1*‘10/23/84‚All�BSR's�to�TERMLIB�now�JSR's�in�case.*›TERMLIB�is�located�more�than�32K�bytes�away.**‘10/17/84‚Initial�release�by�Julie�Hoban.*J**************************************************************************J**************************************************************************J**************************************************************************J************************************************************************** **‚XREF's�from�TERMLIB* ‰XREF†LOG_ERR‰XREF†MARK_DOWN ‰XREF†RESET‰XREF†TERM_BREAK‰XREF†TERM_COMMAND‰XREF†TERM_GOT_CHAR‰XREF†TERM_INIT‰XREF†TERM_TBE‰XREF†TERM_UNRDY **‚Equate�files�included:* *‰STR.EQ*‰TCB.EQ*‰CCB.EQ*‰IOE.EQ*‰NIO.EQ*‰LV5.EQ0*‰BAB.EQ�Background�Activation�Block�description:*‰TERMCCB.EQ‰Offsets�and�equates�for�CCBDDP�for�terminals.#*‰TERMINAL.EQˆEquates�for�terminals*‰SCN2681.EQ‰Device�description*‰UTILITY.MC‰Macros*ŠNOLISTŠINCLUDE�9995.&.STR.EQŠNOLISTŠINCLUDE�9995.&.TCB.EQŠNOLISTŠINCLUDE�9995.&.CCB.EQŠNOLISTŠINCLUDE�9995.&.IOE.EQŠNOLISTŠINCLUDE�9995.&.NIO.EQŠNOLISTŠINCLUDE�9995.&.LV5.EQŠNOLISTŠINCLUDE�9995.&.BAB.EQŠNOLISTŠINCLUDE�9995.&.UTILITY.MCŠLISTŠINCLUDE�9995.&.SCN2681.EQŠINCLUDE�9995.&.TERMINAL.EQ I(A0B88@4H<P6X8`9h3p9x>€>ˆO�?˜I >¨=°=¸>ÀAÈ& ŠINCLUDE�9995.&.TERMCCB.EQŠLIST>ŠTTL„DARTDRV:‚VERSADOS�SCN2681�TERMINAL�DRIVER�WITH�TYPE-AHEADŠPAGEŠOFFSET„TERMDDP*>*‚The�device-dependent�variables�of�the�CCB�are�defined�below.* :�RESERVE.4�SAV_SPR’Address�of�the�supervisor's�driver�CCB.%*§We�must�save�this�because�interrupt&*§processing�returns�to�the�supervisor *§driver. ;�RESERVE.4�SAV_ISR’Image�of�2681�interrupt�status�register. *§Used�to�keep�track�of�any�bits#*§(interrupts)�left�to�service�upon%*§return�to�the�supervisor.�Long�word*§not�required,�but�it�makes�it *§simple. :�RESERVE.1�SAV_CREG‘Image�of�2681�command�register,�needed#*§to�keep�track�of�the�state�of�the%*§transmitter�and‚receiver.‚To�give�a$*§command�other�than�RX/TX�On/Off�or$*§Reset,�read�the�current�state�from#*§here,�OR�in�the�bits�for�the�misc*§commands,�then�tell�the�chip. <�RESERVE.1�SAV_SREG‘Image�of�2681�status�register,�needed�to'*§keep�track�of�break�and�received�char#*§bits�in�the�status�register�while*§clearing�bits�in�SAV_ISR. 7�RESERVE.1�BRK_FLAG‘Flag�used�to�keep�track�of�when�the%*§SCN2681�is�transmitting�a�break�and%*§should�not�disable�the�transmitter. ;�RESERVE.1�TBE_FLAG‘Flag�used�to�keep�track�of�when�a�char-*§acter�has�been�output�and�the!*§transmit�buffer�empty�interrupt%*§has�not�yet�been�received�-�used�to%*§simulate�transmit�buffer�NOT�empty. ŠPAGE*L*‚The�device-dependent�Background�Activation�Blocks�(BAB)�are�defined�below.* :�RESERVE.12�IPC_BAB‘Routine�to�handle�IP2�line�transition. *@*ƒCompute�the�number�of�pages�of�memory�that�we�need�for�one�CCB>*ƒfor�the�DART�driver.‚CMR�automatically�allocates�one�page�ofA*ƒmemory�($100�bytes)�for�the�CCB,�and�our�variable�EXTCCBSZ�willB*ƒreside�in�the�CMR�parameter�table�at�the�beginning�of�the�driver8*ƒto�tell�CMR�how�many�extra�pages�of�memory�are�needed.**CCBSIZEB�EQU‡*PAGESIZE�EQU‡$100L1‡SET‡CCBSIZEB+PAGESIZE-1CCBSIZE‚EQU‡L1/PAGESIZEEXTCCBSZ�EQU‡CCBSIZE-1‰PAGEJ***************************************************************************+*‰SERVICE�VECTOR�TABLE,�REVISION�INFO,�ETC.*@*‰This�table�is�examined�by�CMR�when�the�channel�is�allocated�toC*‰determine�where�to�go�for�interrupts,�commands,�&�initialization.<*‰It�must�always�be�at�the�very�top�of�the�driver�code.‚Also>*‰included�is�a�parameter�telling�the�number�of�extra�pages�of>*‰memory�to�include�in�the�CCB,�and�information�describing�the*‰revision�of�the�driver.*L**************************************************************************** ŠSECTION‚0ŠOPT„BRS DARTDRV: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!*=ŠDC.LƒINTERRUPT-DARTDRV‚Address�of�interrupt�service�routine.9ŠDC.LƒCOMMAND-DARTDRV„Address�of�command�service�routine.5ŠDC.LƒINIT-DARTDRV‡Address�of�initialization�routine.ŠDC.Lƒ0’Reserved. **‚Other�CMR�parameters.*7ŠDC.BƒEXTCCBSZ‹#�of�extra�pages�in�the�CCB.‚The�CCB�may)*§be�any�size�from�1�to�256�pages�(a�page'*§is�256�bytes):‚if�this�field�is�0,�it*§will�be�1�page,�etc.ŠDC.Bƒ0,0,0ŽReserved.ŠDC.Lƒ0,0,0ŽReserved. **‚Revision�info:*/ŠDC.Bƒ'110784'‹Date�of�last�assembly�as�MMDDYY.1ŠDC.Bƒ'�'�Space�indicates�no�patches�to�.LO�file.)ŠDC.Bƒ'4'�Major�VERSAdos�revision�number.*‰PAGEO********************************************************************************+*ˆJump�table�for�use�by�the�generic�TERMLIB*O******************************************************************************* ‰BRA.L…PUT_CHAR ‰BRA.L…CK_TBE‰BRA.L…DDP_RESET ‰BRA.L…SETUP‰BRA.L…CLOCK_RESET‰BRA.L…GET_STAT‰BRA.L…DDP_STOP‰BRA.L…DDP_UNSTOP‰BRA.L…DDP_BEG_BREAK‰BRA.L…DDP_END_BREAK‰PAGEJ**************************************************************************J**************************************************************************J*************************************************************************** *‰INITIALIZATION�ROUTINE*>*‰This�routine�is�called�by�CMR�when�the�channel�is�allocated.9*‰Its�purpose�is�to�set�up�things�for�command�service�and7*‰interrupt�service.‚The�major�functions�performed�are:*@*‹1.�Device-Independent�initialization�in�the�call�to�TERM_INIT.3*‹2.�Device-Dependent�initialization�of�the�device.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.**‰Entry:…A5�=�address�of�CCB.*6*‰Calls:…TERM_INIT�in�generic�terminal�driver�TERMLIB.*'*‰Exits�to:‚CMR�(via�RTS)�if�all�is�OK.'*”KILLER�if�exec�won't�allocate�memory,.*•or�can't�get�background�routine�entry�point.*J**************************************************************************J**************************************************************************J**************************************************************************ŠDS…0INIT:*>*‚Perform�the�device-independent�initialization�by�calling�the'*‚generic�routine�TERM_INIT�in�TERMLIB.*.‰JSR‡TERM_INIT‹Do�the�device-independent�stuff2‰IFƒƒTHEN…Something�went�wrong�with�TERM_INIT.4‰IFƒƒTHEN„The�exec�call�failed�and�we�cannot�get!*œthe�scheduler's�entry�point�!!!ŽTR0$.KILLER‚,‰ELSE�RTS�The�channel�is�down�!!‰ENDI‰ENDI*;*‚Perform�the�minimum�device-dependent�initialization�using@*‚call�guarded�to�the�EXEC�for�a�routine�resident�in�background.*5‰LEA‡DO_INIT(PC),A0†Device-dependent�routine�address.-‰MOVE.L„#T0GUARD,D0‰Call�guarded�to�the�EXEC.‰TRAP†#0‰RTS‰PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMAND�SERVICE�ROUTINE*>*‰We�get�entered�here�when�the�attached�task�(IOS)�invokes�CMR?*‰via�a�TRAP�1�with�an�INITIATE�I/O�parameter�block�to�process.>*‰CMR�has�already�checked�the�CMR�parameter�block�to�ensure�it<*‰resides�within�the�address�space�of�the�attached�task.‚IOSA*‰has�already�validated�the�IOCB,�except�for�the�buffer�addresses *‰therein.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.*5*‰Entry:�A2�=�physical�address�of�CMR�parameter�block*�A5�=�physical�address�of�CCB*9*‰Calls:�TERM_COMMAND�in�generic�terminal�driver�TERMLIB.*3*‰Exit:‚D0�=�results�of�parameter�block�validation:3*•always�0�in�our�case,�indicating�it�was�OK,�since2*•IOS�will�not�send�us�any�request�except�HALT�I/O/*•if�we�are�already�busy,�and�CMR�makes�all�the*•other�checks.**J**************************************************************************J**************************************************************************J************************************************************************** COMMAND: *,*‚Perform�any�device-dependent�stuff�here...*9‰ST.BƒTBE_FLAG(A5)‹Set�the�flag�to�indicate�buffer�empty.*I*‚Perform�the�device-independent�command�handler�by�calling�TERM_COMMAND.* %ŠJSR…TERM_COMMAND†Perform�the�commandŠRTS—return�to�CMR.ŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INTERRUPT�HANDLING�ROUTINE*<*‰This�routine�completes�I/O�requests�started�by�the�command:*‰service�routine.‚It�is�entered�at�the�interrupt�priority;*‰level�of�interrupts�on�this�channel,�and�is�essentially�a9*‰subroutine�to�the�first�level�interrupt�handler�in�CMR.=*‰Remember,�however,�that�this�is�a�subordinate�driver--hence=*‰the�interrupt�was�fielded�first�by�the�supervisor�used�with(*‰whatever�type�of�board�we're�handling.* 5*‰Entry:�A0�=�address�of�the�supervisor�driver's�CCB.*�A5�=�address�of�our�CCB.3*�D1�=�Copy�of�Interrupt�Status�Register�from�2681.*"*�D0,A0,A1�have�been�saved�by�CMR.-*�D1‡has�been�saved�by�the�supervisor�driver.*�D0,A1„are�available�to�use.8*�A0‡must�be�returned�to�the�supervisor�with�the�address*šof�the�supervisor's�CCB.4*�D1‡must�be�returned�to�the�supervisor�with�the�bit(*špattern�of�interrupts�left�to�service.*>*‰Exit:‚always�via�RTS,�which�takes�us�back�to�the�supervisor.**‰Stack:*�(A7)+8�.�.�. *�(A7)+4�longword�return�address6*�(A7)ƒlongword�saved�contents�of�D1�(must�be�restored*—before�exit�to�CMR)*J**************************************************************************J**************************************************************************J************************************************************************** INTERRUPT: *‚NOTE:*?*‚This�driver�requires�a�supervisor�driver�since�it�handles�theA*‚SCN2681.‚The�supervisor�driver�written�for�use�with�this�one�isC*‚DARTSPR,�which�branches�to�the�appropriate�longword�in�this�tableC*‚depending�on�interrupt�type.‚The�supervisor�will�not�pass�controlA*‚to�this�driver�unless�there�is�in�fact�an�interrupt�on�my�port.**‚ENTRY�POINTS:*%ŠBRA.S‚RCA�Character�received�for�me.ŠNOP'ŠBRA.S‚TBE�My�transmit�buffer�is�ready.ŠNOP-ŠBRA.L‚BCI�Change�in�BREAK�status�on�my�port.ŠNOP&ŠBRA.L‚IP2�Input�Port�2�Status�change.ŠPAGEJ***************************************************************************)*‰TRANSMIT�BUFFER�EMPTY�INTERRUPT�HANDLER*@*‰The�SCN2681's�transmit�buffer�just�became�empty,�so�if�we�have+*‰more�characters�to�send�we�can�do�it�now.*5*‰Entry:�A0�=�address�of�the�supervisor�driver's�CCB.*�A5�=�address�of�CCB7*�D1�=�copy�of�Interrupt�Status�Register�from�the�2681.*9*‰Calls:�TERM_TBE�in�the�generic�terminal�driver�TERMLIB.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*O******************************************************************************* TBE:.ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�port.<ŠMOVE.L�A0,SAV_SPR(A5)…Save�address�of�the�supervisor's�CCB. 4ŠBCLRƒ#CLRTBE,D1‰Clear�interrupt�bit�in�copy�of�ISR.*ŠMOVE.L�D1,SAV_ISR(A5)…Save�it�in�the�CCB. ?ŠTST.B‚BRK_FLAG(A5)‡Is�this�TBE�because�we're�transmitting�brk?+ŠIF…�THENŠThe�flag�is�set�if�yes,�so...(‹MOVEQ‚#0,D0�Put�some�nulls�into�D0,�and:‹MOVE.B�D0,DREG(A1)‡Output�a�character�to�clear�interrupt.)‹BRA.L‚INT_EXITŠExit�from�this�interrupt.ŠENDI 3ŠPUT_BYTE�TXOFF,D0‰Set�disable�transmitter�command.5ŠMOVE.B�D0,SAV_CREG(A5)„Replace�current�value�in�CCB.=ŠMOVE.B�D0,CREG(A1)ˆClear�interrupt�by�disabling�transmitter.5ŠST.BƒTBE_FLAG(A5)‡Set�flag�to�indicate�buffer�empty.*D*‚Now�call�the�device-independent�routine�that�tests�for�transparent/*‚mode�and�invokes�the�XMIT�background�routine.*ŠJSR„TERM_TBE‹JSR�into�TREMLIB.(ŠBRA.L‚INT_EXIT‹Exit�from�the�interrupt.ŠPAGEJ***************************************************************************(*‰RECEIVED�CHARACTER�AVAILABLE�INTERRUPT*@*‰The�SCN2681�has�just�received�a�character,�and�it�is�available=*‰for�reading.‚We�will�do�that�now,�and�the�result�will�go�in$*‰the�receive�queue�if�there's�room.*5*‰Entry:�A0�=�address�of�the�supervisor�driver's�CCB.*�A5�=�address�of�CCB7*�D1�=�copy�of�Interrupt�Status�Register�from�the�2681.*>*‰Calls:�TERM_GOT_CHAR�in�the�generic�terminal�driver�TERMLIB.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** RCA:.ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�port.<ŠMOVE.L�A0,SAV_SPR(A5)…Save�address�of�the�supervisor's�CCB.*7*‚Get�the�character�from�the�2681�and�check�for�errors.*>ŠMOVE.B�DREG(A1),D0ˆClear�interrupt�by�getting�char�from�2681.2ŠBCLRƒ#CLRRCA,D1‰Clear�bit�in�working�copy�of�ISR. *ŠMOVE.L�D1,SAV_ISR(A5)…Save�it�in�the�CCB. 3ŠMOVE.B�SREG(A1),D1ˆGet�the�status�for�the�process./ŠAND.B‚#$70,D1ŒMask�out�all�but�the�error�bits.1ŠBNE.S‚INTERR�Branch�if�any�error�bits�turned�on.*D*‚Call�the�device�independent�routine�to�check�for�transparent�mode,D*‚and�any�special�characters�such�as�XON,�XOFF,�BREAK�EQUIVALENT,�or?*‚DISCARD�OUTPUT�and�invoke�the�appropriate�background�routine.9*‚Otherwise,�just�put�the�character�in�the�receive�queue.*"ŠJSRƒTERM_GOT_CHAR‡JSR�to�TERMLIB.(ŠBRA.L…INT_EXITˆExit�from�the�interrupt.ŠPAGEJ***************************************************************************#*‰FOUND�ERROR�ON�RECEIVED�CHARACTER*=*‰The�SCN2681�detected�an�error�in�the�process�of�receiving�a<*‰character.‚We�need�to�record�this�information�so�that�when<*‰the�corresponding�data�is�requested�from�the�receive�queue*‰we�can�report�an�error.*0*‰Entry:�D0.B�=�character�which�generated�error.0*�D1.B�=�status�register�value�(error�bits�only)*�A1ƒ=�address�of�our�port*�A5ƒ=�address�of�CCB*8*‰Calls:�LOG_ERR�in�the�generic�terminal�driver�TERMLIB.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** INTERR:ŠSWAPƒD0‘Make�room.:ŠMOVE.B�SAV_CREG(A5),D0„Current�value�of�command�register.0ŠOR.Bƒ#RSTEST,D0‰Set�the�reset�error�status�bit.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�the�chip.ŠSWAPƒD0‘Restore�character. )ŠBTSTƒ#SPARER,D1‰Was�this�a�parity�error?-ŠIF…�THENŠIf�the�parity�error�bit�is�set,8‹PUT_BYTE�PAR_FRAM,D0…Put�the�VERSAdos�error�code�in�D0,‹JSR„LOG_ERR‹Log�the�error.-‹BRA.L‚INT_EXITŠAnd�exit�from�this�interrupt.ŠENDI )ŠBTSTƒ#SDAOVR,D1‰Was�this�a�data�overrun?3ŠIF…�THENŠIf�the�data�overrun�error�bit�is�set,7‹PUT_BYTE�OVERRUN,D0†Put�the�VERSAdos�error�code�in�D0,‹JSR„LOG_ERR‹Log�the�error.-‹BRA.L‚INT_EXITŠAnd�exit�from�this�interrupt.ŠENDI *ŠBTSTƒ#SFRMER,D1‰Was�this�a�framing�error?.ŠIF…�THENŠIf�the�framing�error�bit�is�off,-‹BRA.L‚INT_EXITŠWe�shouldn't�be�here�so�exit."ŠELSE–The�framing�error�bit�is�on,3‹TST.B‚D0�So�let's�see�if�it�really�is�a�character.9‹IF…�THEN‰Character�is�real,�and�so�is�framing�error.8ŒPUT_BYTE�PAR_FRAM,D0„Put�the�VERSAdos�error�code�in�D0,ŒJSR„LOG_ERRŠLog�the�error.-ŒBRA.L‚INT_EXIT‰And�exit�from�this�interrupt.‹ENDIŠENDI‰PAGE*$*‚This�must�have�really�been�a�break*7ŠMOVE.B�SAV_CREG(A5),D0„Get�current�value�from�the�CCB.0ŠOR.Bƒ#RSTBCI,D0‰Set�the�reset�break�status�bit..ŠMOVE.B�D0,CREG(A1)ˆThis�clears�the�interrupt. *ŠMOVE.L�SAV_ISR(A5),D1…Get�value�from�CCB.4ŠBCLRƒ#CLRBCI,D1‰Clear�interrupt�bit�in�copy�of�ISR.*ŠMOVE.L�D1,SAV_ISR(A5)…Save�it�in�the�CCB. ŠBKGRND�BREAKŠBRA.L‚INT_EXITŠPAGEJ****************************************************************************‰BREAK�CHANGE�INTERRUPT*9*‰This�interrupt�from�the�2681�is�caused�when�either�port6*‰has�detected�the�beginning�or�end�of�a�break�signal.9*‰The�only�condition�we�care�about�is�when�a�break�signal:*‰starts�(detected�from�the�status�register�for�our�port),:*‰in�which�case�we�have�to�get�an�appropriate�event�to�the9*‰attached�task�(IOS).�For�both�interrupts,�we�must�issue7*‰a�'reset�break�change�interrupt'�command�to�clear�the*‰interrupt�bit�in�the�ISR.*.*‰Entry:�A0�=�address�of�the�supervisor's�CCB.*�A5�=�address�of�CCB?*�D1�=�working�copy�of�Interrupt�Status�Register�from�the�2681.*;*‰Calls:�TERM_BREAK�in�the�generic�terminal�driver�TERMLIB.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** BCI:.ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�port.<ŠMOVE.L�A0,SAV_SPR(A5)…Save�address�of�the�supervisor's�CCB. DŠMOVE.B�SREG(A1),SAV_SREG(A5)�Save�current�value�of�status�register. ,ŠMOVE.B�SAV_CREG(A5),D0„Get�current�command. 3ŠOR.Bƒ#RSTBCI,D0‰Set�the�reset�break�status�change.6ŠMOVE.B�D0,CREG(A1)ˆThis�clears�the�BCI�interrupt�bit.2ŠBCLRƒ#CLRBCI,D1‰Clear�bit�in�working�copy�of�ISR.ŠMOVE.B�D1,SAV_ISR(A5)…Save�it. **‚Clear�the�FIFO...*?CLRFIFOƒMOVE.B�6(A1),D0‹Read�the�FIFO...up�to�3�bytes�to�clear.ŠMOVE.B�6(A1),D0‹*ŠMOVE.B�6(A1),D0‹* 2ŠBCLRƒ#CLRRCA,D1‰Clear�bit�in�working�copy�of�ISR.*ŠMOVE.L�D1,SAV_ISR(A5)…Save�it�in�the�CCB. ;ŠMOVE.B�SAV_SREG(A5),D0„Get�saved�value�of�status�register.4ŠBTSTƒ#SRXBRK,D0‰This�bit�indicates�begin/end�break..ŠBEQ„INT_EXIT‹If��it�was�the�end,�so�exit. 7ŠJSR„TERM_BREAK‰JSR�to�TERMLIB�to�handle�dev-ind�break.&ŠBRA„INT_EXIT‹Exit�from�the�interrupt.ŠPAGEO*********************************************************************************‰IP2�INTERRUPT*<*‰The�Input�Port�2�has�made�a�transition�(active-to-inactive>*‰or�inactive-to-active).�The�Input�Port�2�is�jumpered�to�Port>*‰B�and�hard-wired�to�RS232�line�20.�IP2�is�monitored�from�the;*‰Input�Port�Change�Register�(IPCR)�of�the�SCN2681.�The�IP2<*‰interrupt�is�enabled�for�modem�operation�only�(the�IOAMODM<*‰bit�in�IOSATW�is�set).‚It�is�likely�that�the�user�will�fix;*‰the�MVME115�so�that�pin�8�of�the�RS232�interface�comes�in *‰on�IP2.*>*‰The�IPCR�is�read,�and�depending�on�the�current�state�of�IP2,C*‰the�appropriate�background�routine�is�activated�(IP2�active�low).*@*‰If�IP2�went�inactive-to-active,�then�a�modem�probably�answered@*‰the�phone�and�we�activate�BREAK�in�the�background.‚If�IP2�wentA*‰active-to-inactive,�then�the�modem�hung�up�or�the�terminal�wentA*‰unready,�and�we�may�have�to�queue�an�event�if�there�was�I/O.�We.*‰activate�IPC�in�the�background�to�handle�it.***‰Entry:�A0�=�address�of�supervisor's�CCB.*�A5�=�address�of�CCB?*�D1�=�working�copy�of�Interrupt�Status�Register�from�the�2681.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*O******************************************************************************* IP2:4ŠBCLRƒ#CLRIP2,D1‰Clear�interrupt�bit�in�copy�of�ISR.*ŠMOVE.L�D1,SAV_ISR(A5)…Save�it�in�the�CCB.<ŠMOVE.L�A0,SAV_SPR(A5)…Save�address�of�the�supervisor's�CCB. ŠMOVE.L�ADRSIDEA(A5),A0>ŠMOVE.B�IPCR(A0),D0ˆD0�<--�current�input�port�change�register.**£(reading�this�register�clears�interrupt) 9ŠBTSTƒ#STAIP2,D0‰Test�IP2�to�indicate�active�or�inactive.)ŠBNE.S‚IPC20ŽIP2�is�low,�device�is�ready.8ŠBKGRND�BREAKŽHandle�device�ready�with�background�BREAK.ŠBRA.S‚INT_EXIT 9IPC20…BKGRND�IPC�Handle�device�unready�in�background�IPC.8*‰BRA.L‚INT_EXIT‹Fall�through�to�interrupt�exit�routine.ŠPAGEO*********************************************************************************‰INTERRUPT�EXIT�ROUTINE*;*‰All�interrupts�return�to�the�supervisor�via�this�routine.6*‰Here�we�look�at�our�flag�SAV_ISR�in�the�CCB.‚SAV_ISR7*‰started�out�looking�exactly�like�the�Interrupt�Status;*‰Register�from�the�2681.‚As�we�cleared�interrupt�bits�fromA*‰the�various�sources�of�interrupts,�we�cleared�bits�in�our�flag.A*‰The�function�of�this�routine�is�to�let�us�set�up�for�our�return*‰to�the�supervisor.*O******************************************************************************* INT_EXIT:;‰MOVE.L�SAV_SPR(A5),A0‰Restore�address�of�supervisor's�CCB.0‰MOVE.L�SAV_ISR(A5),D1‰Restore�our�flag�into�D1.+‰RTS›And�we�must�go�back�to�the�supervisor.  SPC 15O********************************************************************************"*ˆEND�OF�INTERRUPT�SERVICE�ROUTINE*O*******************************************************************************ŠPAGEO*********************************************************************************!*�R�O�U�T�I�N�E�S„C�A�L�L�E�D„B�Y**–T�E�R�M�L�I�B**O*******************************************************************************‰PAGEL***************************************************************************** *ˆTRANSMIT�THE�CHARACTER*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedA*ˆat�the�beginning�of�the�driver.‚The�function�of�this�routine�isC*ˆwrite�the�character�contained�in�D0�to�the�transmit�data�register*ˆof�the�device.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*-*ˆEntry:�A1�=�address�of�our�side�of�the�chip*�A5�=�address�of�CCB*�D0.B�=�character�to�transmit**�Interrupt�level�on�entry�is�0**ˆExit:‚RTS�to�caller.*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*J************************************************************************** PUT_CHAR:ŠINHIBIT>ŠMOVE.B�#TXON,SAV_CREG(A5)„Save�enable�transmitter�cmd�in�CCB.2ŠMOVE.B�SAV_CREG(A5),CREG(A1)�Tell�it�to�the�chip.+ŠMOVE.B�D0,DREG(A1)‹Transmit�the�character.6ŠSF.BƒTBE_FLAG(A5)ŠClear�flag�to�indicate�buffer�full.'ŠUNMASK—Must�exit�at�interrupt�level�0.ŠRTSŠPAGEM******************************************************************************$*ˆCHECK�THE�DEVICE'S�TRANSMIT�BUFFER*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toF*ˆcheck�that�the�transmit�buffer�is�empty�before�allowing�any�transmit *ˆactivity.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*-*ˆEntry:�A1�=�address�of�our�side�of�the�chip*�A5�=�address�of�CCB**�Interrupt�level�on�entry�is�0*/*ˆExit:‚RTS�to�caller�with�Condition�codes�set:"*��=�transmit�buffer�not�empty*��=�transmit�buffer�empty*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*M***************************************************************************** CK_TBE:*E*‚Test�the�flag�to�simulate�transmit�buffer�empty�status.‚The�flag�isJ*‚set�when�a�character�is�output�and�cleared�when�the�tranmit�buffer�empty*‚interrupt�is�received.*ŠTST.B‚TBE_FLAG(A5)ŠRTSŠPAGEH************************************************************************* *ˆDEVICE�DEPENDENT�RESET�ROUTINE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toC*ˆperform�a�minimum�reset�of�the�device.�For�the�SCN2681�this�means6*ˆclearing�any�error�status�and�enabling�the�receiver.*;*ˆWe�are�running�in�background�when�this�routine�is�called.**ˆEntry:�A5�=�address�of�CCB**�Interrupt�level�on�entry�is�0**ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*E********************************************************************* DDP_RESET:6ŠMOVEM.L�D0/A1,-(A7)‹Save�used�registers�on�the�stack.1ŠMOVE.L�CCBCHB(A5),A1ŠA1�<--�address�of�our�port..ŠPUT_BYTE�RXON,D0ŽBe�sure�we�turn�receiver�on.5ŠMOVE.B�D0,SAV_CREG(A5)ˆSave�as�current�value�in�CCB.4ŠOR.Bƒ#RSTEST,D0�Set�reset�error�status�command�bit.(ŠMOVE.B�D0,CREG(A1)ŒTell�it�to�the�chip./ŠMOVEM.L�(A7)+,D0/A1‹Restore�working�registers.ŠRTSŠPAGEJ***************************************************************************@*ˆSUBROUTINE�TO�SET�UP�THE�DEVICE�ACCORDING�TO�THE�CONFIGURATION*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toE*ˆset�up�the�device�according�to�the�working�configuration�in�the�CCB3*ˆand�some�configuration-related�fields�in�the�CCB.*;*ˆWe�are�running�in�background�when�this�routine�is�called.**ˆEntry:�A5�=�address�of�CCB**�Interrupt�level�on�entry�is�0**ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*J************************************************************************** SETUP: 2ŠMOVEM.L�D0-D2/A0-A2,-(A7)„Save�working�registers.ŠPUSHƒSR **‚First�set�up�addresses.*4ŠLEA„CONFIG(A5),A0†A0�<--�addr�of�CCB�configuration..ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�port..ŠMOVE.L�ADRSIDEA(A5),A2„A2�<--�addr�of�port�A. */*‚Insure�that�RTS�if�off�(unready)�for�our�port*3‹BTST.B�#0,CCBTYPE(A5)‡If�we're�handling�the�A�port ‹IF…�THENŒ(we're�the�A-side)7ŒMOVE.B�#RTSAOFF,OPRR(A2)ƒset�the�RTS�line�HIGH�via�OP0‹ELSE˜(we're�the�B-side)7ŒMOVE.B�#RTSBOFF,OPRR(A2)ƒset�the�RTS�line�HIGH�via�OP1‹ENDI˜* **‚Perform�some�resets.*3ŠMOVE.B�SAV_CREG(A5),D0‡Get�current�value�from�CCB.,ŠOR.Bƒ#RSTEST,D0ŒSet�reset�error�status�bit.(ŠMOVE.B�D0,CREG(A1)‹Tell�it�to�the�chip. PAGE**‚Program�Mode�Register�1"*ˆstart�with:�flow�control�enabled*”interrupt�upon�FIFO�full*”character�error�mode3*ˆdetermine�other�fields�from�current�configuration*ˆworking�register�is�D0 !‰PUT_BYTE‚RXIRDY+CRXRTS+EMCHAR,D0 * Parity Mode [4:3]>ŠBTSTW‚#IOAUSEP,IOSATW(A0)ƒIf�we're�using�parity,�enable�it... ŠIF…�THEN)ŠOR.Bƒ#PAROFF,D0ŒMust�set�no�parity�bits.ŠELSE+ŠOR.Bƒ#PARENB,D0ŒOr�set�enable�parity�bits.ŠENDI* Parity Type [2]:ŠBTSTW‚#IOAPRTY,IOSATW(A0)ƒAnd�if�we're�using�even�parity,ŠIF…�THEN�set�it�up.ŠOR.Bƒ#PAREVN,D0ŠENDI * Character Length [1:0]1ŠBTSTW‚#IOABITS,IOSATW(A0)ƒAdd�in�bits/char�info. ŠIF…�THENŠOR.Bƒ#DTBPC7,D0Œ(7�bits/char)ŠELSEŠOR.Bƒ#DTBPC8,D0Œ(8�bits/char)ŠENDI *!*‚Program�Mode�Register�2�(MREG2)*ˆstart�with:‚normal�mode*•No�Tx�RTS�control*•No�Tx�CTS�control(*ˆdetermine�stop�bits�from�configuration*ˆworking�register�is�D1 ‰PUT_BYTE�CMNORM,D1 * Stop Bit Length [3:0]:ŠBTSTW‚#IOASTPB,IOSATW(A0)ƒAdd�in�the�number�of�stop�bits. ŠIF…�THENŠOR.Bƒ#SB1,D1�(1�stop�bit)ŠELSEŠOR.Bƒ#SB2,D1�(2�stop�bits)ŠENDI PAGE$‰INHIBIT—Inhibit�interrupts�while...3‰MOVE.B�SAV_CREG(A5),D2ˆGet�current�value�from�CCB.1‰OR.Bƒ#RSTMRP,D2�Set�reset�mode�register�pointer.(‰MOVE.B�D2,CREG(A1)ŒTell�it�to�the�chip./‰MOVE.B„D0,MREG1(A1)ˆProgram�mode�register�1...)‰MOVE.B„D1,MREG2(A1)ˆand�mode�register�2.‰ENABLE *C*‚Clock�Select�Register�(CSEL)�and�Auxiliary�Control�Register�(ACR)6*‡sets�the�baud�rate�for�the�receiver�and�transmitter.*‡working�register�D0�and�D1 *‰MOVEQ.L�#0,D0‘Clear�the�working�register.6‰MOVE.B‚IOSBRT(A0),D0‰Get�the�VERSAdos�baud�rate�CODE.,‰LSL.Lƒ#1,D0‘Double�it�to�use�in�BAUD_TABLE.<‰MOVE.W‚BAUD_TABLE(PC,D0.W),D1�Get�the�Rx/Tx�baud�rate�codes%*§and�baud�rate�set�bit�from�the�Baud(*§Rate�Conversion�Table�for�this�device. *3*‚Now�write�to�the�Auxiliary�Control�Register�(ACR)(*‚(Accessed�from�channel�A�address�only)*?‰BTSTW‚#IOAMODM,IOSATW(A0)‚If�this�is�a�modem�we're�talking�to,‰IF…�THEN�*7ŠOR.B„#INTIP2,D1‰Allow�interrupts�through�Input�Port�2.‰ENDI<‰MOVE.B‚D1,ACR(A2)ŠTell�the�chip�which�baud�rate�set�to�use. <*‚Now�write�to�the�Clock�Select�Register�for�the�baud�rates. .‰ROR.Wƒ#8,D1‘Put�the�baud�rate�codes�into‚LSB.9‰MOVE.B‚D1,CSEL(A1)‹Move�LSB�(baud�rate�codes)�into�CSEL. *+*‚Program�the�Interrupt�Mask�Register�(IMR)=*ˆThe�driver�selected�which�ISR�bits�will�cause�an�interrupt.-*ˆThese�are:�change�in�break,�channel�A�and�B*“RxRDY,�channel�A�and�B*“TxRDY,�channel�A�and�B*“Input�Port�Change�on�IP21*ˆThe�counter/timer�interrupt�bit�is�turned�'off' 3ŠBTST.B�#0,CCBTYPE(A5)ˆIf�we're�handling�the�A�port ŠIF…�THEN�(we're�the�A-side)0‹MOVE.B�#$07,D0Žallow�interrupts�on�A-side�only.ŠELSE™(we're�the�B-side)2‹MOVE.B�#$F7,D0Žallow�interrupts�on�A�and�B�sides.ŠENDI™*'ŠMOVE.B�D0,IMR(A2)ŒTell�it�to�the�chip. ŠBRA.S‚SET10 PAGEO********************************************************************************"*‰TABLE�FOR�TRANSLATING�BAUD�RATES*O******************************************************************************* **�-----------------�Defines�Set�1�or�Set�2*�|&*�|�---------------�Baud�rate�set�code*�|�|*�V�V BAUD_TABLEŠDC.Bƒ$00,0‡50 ŠDC.Bƒ$00,1‡75ŠDC.Bƒ$11,0†110ŠDC.Bƒ$22,0†134.5ŠDC.Bƒ$33,1†150ŠDC.Bƒ$44,0†300ŠDC.Bƒ$55,0†600ŠDC.Bƒ$66,0…1200ŠDC.Bƒ$AA,1…1800ŠDC.Bƒ$77,1…2000ŠDC.Bƒ$88,0…24000ŠDC.Bƒ$88,0…3600…We�don't�have�it�so�we�use�2400ŠDC.Bƒ$99,0…4800ŠDC.Bƒ$AA,0…7200ŠDC.Bƒ$BB,0…9600ŠDC.Bƒ$CC,1„19200 SET10…DS.Wƒ0 PAGE*!*‚Program�Command�Register�(CREG)+*ˆcurrent�state�is:�RTS�line�high�(unready)#*šreceiver�and�transmitter�disabled5*ˆWe�must�make�us�ready�and�enable�the�Receiver�only.  "* Make us ready by setting RTS low 3ŠBTST.B�#0,CCBTYPE(A5)‡If�we're�handling�the�A�port ŠIF��THEN�(we're�the�A-side)5‹MOVE.B�#RTSAON,OPSR(A2)„set�the�RTS�line�LOW�via�OP0ŠELSE˜(we're�the�B-side)5‹MOVE.B�#RTSBON,OPSR(A2)„set�the�RTS�line�LOW�via�OP1ŠENDI˜* %* See if the user wants us offhook...7‰BTSTW‚#IOAOFFH,IOSATW(A0)ƒIf�the�guy�wants�it�offhook,&‰IF…�THEN�Make�our�port�'unready'.3‰BTST.B�#0,CCBTYPE(A5)ˆIf�we're�handling�the�A�port ‰IF…�THEN�(we're�the�A-side)7ŠMOVE.B�#RTSAOFF,OPRR(A2)„set�the�RTS�line�HIGH�via�OP0‰ELSE™(we're�the�B-side)7ŠMOVE.B�#RTSBOFF,OPRR(A2)„set�the�RTS�line�HIGH�via�OP1‰ENDI™*‰ENDI )* Now enable the receiver and we're done..ŠPUT_BYTE�RXON,D0ŠSet�enable�receiver�command.5ŠMOVE.B�D0,SAV_CREG(A5)„Replace�current�value�in�CCB.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�the�chip. **‚Restore�registers�and�return.*ŠPOP…SR8ŠMOVEM.L�(A7)+,D0-D2/A0-A2�Restore�registers�from�stack.ŠRTSŠPAGEO*********************************************************************************ˆRESET�THE�CLOCK*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�to3*ˆchange�the�clock�speed�back�to�its�default�value.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*.*ˆEntry:�A1�=�address�of�our�side�of�the�chip.*�A5�=�address�of�our�CCB.**�Interrupt�level�on�entry�is�0**ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*O******************************************************************************* CLOCK_RESET:*C*ƒThis�functionality�is�not�supported�by�the�SCN2681�on�the�VME115.*ŠRTSŠPAGEJ****************************************************************************ˆGET�DEVICE�STATUS�BYTE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toA*ˆprepares�the�DEVICE�STATUS�byte�which�contains�the�condition�of6*ˆthe�IP2�line�(which�indicates�device�ready/unready).*;*ˆWe�are�running�in�background�when�this�routine�is�called.*8*ˆNote:‚This�routine�does�not�set�the�break�indicator�in*�the�device�status�byte.**ˆEntry:�A5�=�address�of�CCB**�Interrupt�level�on�entry�is�0*!*ˆExit:‚D0.B�=�Device�Status�byte*�RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*J************************************************************************** GET_STAT: ,ŠCLR.B‚D0�Device�status�byte�to�be�returned.,ŠMOVEM.L�D1/A0,-(A7)†Save�working�registers.*C*‚On�the�2681�as�implemented�on�the�MVME115,�IP2�cannot�be�detectedC*‚on�channel�A.‚If�we�are�channel�A,�we�assume�we�are�always�ready.B*‚IP2�can�be�detected�on�channel�B�via�Input�Port�2�which�has�been*‚jumpered�to�the�RS232�pin�20.*6ŠMOVE.L�ADRSIDEA(A5),A0ƒA0�<--�addr�of�A-side�of�chip.4ŠBTST.B�#0,CCBTYPE(A5)„Test�for�A�or�B�side�of�chip.8‹IF…�THENˆIf�we're�the�B-side�then�determine�status.8ŒMOVE.B�IPCR(A0),D1…Read�the�input�port�status�register.8ŒBTSTƒ#STAIP2,D1†Input�port�2�jumpered�for�RS232�pin�20.7�IF…�THEN†Signal�active�low;�if��then�its�high.:ŽBSETƒ#XDSNRB,D0„Set�the�unready�bit�in�the�device�status.�ENDI‹ENDI /ŠMOVEM.L�(A7)+,D1/A0†Restore�working�registers.ŠRTSŠPAGE M*******************************************************************************ˆSTOP�THE�TRANSMITTING�DEVICE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toA*ˆchange�a�hardware�output�line�to�make�our�device�look�'unready''*ˆso�the�transmitting�device�will�stop.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*,*ˆEntry:�A1�=�address�of�our�side�of�device.*�A5�=�address�of�CCB*5*�Interrupt�level�on�entry�is�INHIBITED�at�our�level.**ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*K*************************************************************************** DDP_STOP:ŠSAVEƒA0”Save�working�register.?ŠMOVE.L�ADRSIDEA(A5),A0‡Get�the�2681's�address�of�the�A-side...*ŠBTST.B�#0,CCBTYPE(A5)ˆIf�we're�the�A-side ‹IF…�THENŒ(we're�the�A-side):ŒMOVE.B�#RTSAOFF,OPRR(A0)ƒset�RTS�line�HIGH�on�the�A-side.‹ELSE˜(we're�the�B-side)>ŒMOVE.B�#RTSBOFF,OPRR(A0)ƒset�the�RTS�line�HIGH�on�the�B-side.‹ENDI%ŠRESTORE�A0“Restore�working�register.ŠRTSŠPAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�UNSTOP�THE�DEVICE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�toC*ˆunstop�the�transmitting�device�by�changing�a�hardware�output�line"*ˆto�make�our�device�look�'ready'.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*,*ˆEntry:�A1�=�address�of�our�side�of�device.*�A5�=�address�of�the�CCB*5*�Interrupt�level�on�entry�is�INHIBITED�at�our�level.**ˆExit:‚RTS�to�caller.*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*J************************************************************************** DDP_UNSTOP:ŠSAVEƒA0”Save�working�register.?ŠMOVE.L�ADRSIDEA(A5),A0‡Get�the�2681's�address�of�the�A-side...3ŠBTST.B�#0,CCBTYPE(A5)ˆIf�we're�handling�the�A�port ‹IF…�THENŒ(we're�the�A-side)5ŒMOVE.B�#RTSAON,OPSR(A0)„set�the�RTS�line�LOW�via�OP0‹ELSE˜(we're�the�B-side)5ŒMOVE.B�#RTSBON,OPSR(A0)„set�the�RTS�line�LOW�via�OP1‹ENDI%ŠRESTORE�A0“Restore�working�register.ŠRTSŠPAGEK****************************************************************************&*ˆDEVICE�DEPENDENT�BEGIN�BREAK�ROUTINE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�to@*ˆgive�a�command�to�start�sending�break�condition�to�our�device.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*,*ˆEntry:�A1�=�address�of�our�side�of�device.*�A5�=�address�of�CCB*5*�Interrupt�level�on�entry�is�INHIBITED�at�our�level.**ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*E*********************************************************************  DDP_BEG_BREAK:ŠSAVEƒD01ŠPUT_BYTE�TXON,D0ŠSet�enable�transmitter�command.+ŠMOVE.B�D0,SAV_CREG(A5)„Save�current�value.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�our�port.-ŠOR.Bƒ#BRKBEG,D0‰Set�begin�break�command�bit.9ŠST…BRK_FLAG(A5)‡Set�flag�to�indicate�transmitting�break.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�our�port. ŠRESTORE�D0ŠRTSŠPAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�END�BREAK�ROUTINE*C*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installedD*ˆat�the�beginning�of�the�driver.�The�function�of�this�routine�is�to?*ˆgive�a�command�to�stop�sending�break�condition�to�our�device.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*,*ˆEntry:�A1�=�address�of�our�side�of�device.*�A5�=�address�of�CCB*5*�Interrupt�level�on�entry�is�INHIBITED�at�our�level.* *ˆExit:‚RTS�to�caller*0*ˆThis�routine�must�preserve�all�registers�used.0*ˆThe�interrupt�level�upon�exit�must�be�the�same*ˆas�it�was�upon�entry.*L**************************************************************************** DDP_END_BREAK:ŠSAVEƒD03ŠPUT_BYTE�TXOFF,D0‰Set�disable�transmitter�command.+ŠMOVE.B�D0,SAV_CREG(A5)„Save�current�value.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�our�port.+ŠOR.Bƒ#BRKEND,D0‰Set�end�break�command�bit.5ŠSF…BRK_FLAG(A5)‡Clear�flag�to�indicate�end�of�break.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�our�port. ŠRESTORE�D0ŠRTS SPC 15O******************************************************************************** *‰END�ROUTINES�CALLED�BY�TERMLIB*O*******************************************************************************ŠPAGEO*********************************************************************************“B�A�C�K�G�R�O�U�N�D**šAND**‘C�A�L�L�__�G�U�A�R�D�E�D**–R�O�U�T�I�N�E�S**•(DEVICE-DEPENDENT)*O*******************************************************************************ŠPAGEO*********************************************************************************‰FINISH�OFF�THE�INITIALIZATION*A*‰The�initialization�routine�has�gone�around�resetting�everythingD*‰it�can,�but�the�routines�RESET�and�DDP_RESET�should�only�be�called>*‰from�within�the�background.‚So�he�invoked�this�routine�to�do *‰it�for�him.*?*‰In�addition,�these�other�device-dependent�things�MUST�be�done>*‰before�we�can�handle�commands.‚They�probably�could�have�been?*‰done�in�INIT�at�the�start�of�the�driver�but�are�handled�here.*5*‰1.‚Put�the�start�address�of�the�driver�into�the�CCB*�variable�DRV_ADDR.>*‰2.‚Set�up�the�device-dependent�BABs�using�the�macro�SET_BAB.;*‰3.‚Put�the�address�of�the�A-side�of�a�dual�channel�device6*�into�the�CCB�variable�ADRSIDEA.‚If�not�dual�channel,**�put�the�address�of�Port�1�into�ADRSIDEA.**‰Entry:�A5�=�address�of�CCB.*6*‰Calls:�RESET�in�the�generic�terminal�driver�TERMLIB.*�DDP_RESET�in�this�driver.6*�MARK_DOWN�in�the�generic�terminal�driver�if�failure.*O******************************************************************************* DO_INIT:**‚Inhibit�interrupts*‰PUSH†SR‰INHIBIT*)*‚Get�address�of�start�of�driver�into�CCB*ŠLEA‡DARTDRV(PC),A4ŠMOVE.L„A4,DRV_ADDR(A5)*"*‚Set�up�the�device�dependent�BABs*ŠSET_BABƒIPC0,IPC*6*‚Set�up�the�address�of�the�A�side�of�the�Serial�port.*@ŠMOVE.L�CCBCHB(A5),ADRSIDEA(A5)‚Move�device�address�into�A-side.8ŠBTST.B�#0,CCBTYPE(A5)‹Test�the�channel�type�-�odd�is�B.)ŠIF…�THEN�If�its�set,�its�the�B-side.9‹SUB.L�#16,ADRSIDEA(A5)‰Subtract�the�offset�to�make�it�A.ŠENDI PAGE*3*‚Put�the�receiver�and�transmitter�into�known�state**ŠMOVE.L�CCBCHB(A5),A1†Address�of�our�port..ŠMOVE.B�#RSTTX,CREG(A1)„Reset�the�transmitter.+ŠMOVE.B�#RSTRX,CREG(A1)„Reset�the�receiver.>ŠPUT_BYTE�TXRXOFF,D0‡Set�disable�transmitter/receiver�command.5ŠMOVE.B�D0,SAV_CREG(A5)„Copy�as�current�value�to�CCB.(ŠMOVE.B�D0,CREG(A1)ˆTell�it�to�the�chip. ŠJSR„RESETŽReset�everything.ŠBSR.L‚DDP_RESETŠPOP‡SRŠRTS 7FAIL†JSR‡MARK_DOWN‡Mark�the�channel�down�using�TERMLIB.ŠPOP‡SRŠRTSŠPAGEO*********************************************************************************‰IPC�TRANSITION�HANDLER*A*‰This�part�of�the�background�runs�when�the�chip�senses�a�active-A*‰to-inactive�change�on�the�IP2�line,�which�is�wired�to�RS232�pin@*‰20�on�the�MVME115�and�jumpered�for�port�B.‚This�means�that�the<*‰terminal�or�modem�has�gone�unready.‚We�call�the�TERM_UNRDYC*‰routine�in�TERMLIB�to�queue�an�event�for�us�if�we�were�doing�I/O,B*‰otherwise�we�do�nothing.‚The�only�reason�this�background�routine=*‰exists�is�because�we�do�not�want�to�queue�an�event�while�at*‰our�interrupt�level.*B*‰This�routine�is�called�using�BACKGROUND�so�we�enter�at�interrupt@*‰level�0,�and�we�must�exit�at�interrupt�level�0.‚We�are�free�to5*‰return�whatever�we�like�in�all�registers�except�A7.* *‰IPC0�Entry:�(background)*�A5�=�address�of�CCB.* *‰IPC‚Entry:*�A1�=�address�of�our�port.&*�A4�=�address�of�start�of�our�driver.*�A5�=�address�of�our�CCB.*;*‰Calls:�TERM_UNRDY�in�the�generic�terminal�driver�TERMLIB.**‰Exit:‚A0�=�garbage*O******************************************************************************* IPC0:**‚Set�up�A5�and�A1;*‚When�the�exec�calls�this�routine,�A1�=�address�of�the�BAB*'ŠLEA„-IPC_BAB(A1),A5„A5�<--�CCB�address0ŠMOVE.L�CCBCHB(A5),A1†A1�<--�address�of�our�port4ŠMOVE.L�DRV_ADDR(A5),A4„A4�<--�address�of�our�driver IPC:*6*‚IP2�is�UNREADY.�If�we�were�doing�I/O,�send�an�event.*:ŠJSR„TERM_UNRDY‰Test�for�I/O�and�send�event�using�TERMLIB.3ŠIF��THENŽ�for�good�return�from�subroutine.ŽTR0$.KILLER‚,ŠENDIŠRTSŠPAGE************************„PATCH�SPACE†************************ŠDS.Wƒ30ŠENDéééé=/*=/*†DARTSPR.AF=/*H=/* Chain file to assemble SCN2681 SUPERVISOR serial port driver for the$=/* local port on the MVME115 board.=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to DARTSPR.LS=/*=/IFC \1ƒ=ARG�DARTSPR.LS=/ENDIF=/*$=ASM DARTSPR.SA,DARTSPR.RO,\1;RZ=100=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.SCN2681.EQ=/*ƒ9999.M68230.M68230.EQ=/*}=/*=ENDéééééé Ð*‚The�CTM�or�Counter/Timer�Interrupt�has�not�been�implemented.*C*‚The�variable�OFFSET�is�the�offset�into�the�LONG�WORD�branch�tableJ*‚at�the�start�of�the�interrupt�service�routine�in�the�subordinate�driver.$*‚The�OFFSETs�are�set�up�as�follows:**„-4�=�NO�interrupt**¨--‚For�these�four�interrupts,<*…0�=�RCA�A-side‡1�=�RCA�B-side�|‚it�is�important�that�Bit�0?*…4�=�TBE�A-side‡5�=�TBE�B-side�|‚is�set�so�that�the�supervisorC*…8�=�BCI�A-side‡9�=�BCI�B-side�|‚driver�knows�which�channel�(side)**™13�=�IP2�B-side�|‚the�interrupt�is�from.*¨--*4*„-4�=�CTM‚This�interrupt�source�should�never�occur.8*ŽIt�is�masked�in�the�surbordinate�driver�SETUP�routine.* PAGE GENOFFSET MACROOFFSET�SET�-4�No�interrupts ! IFEQ (%10000000&VALUE)-%10000000OFFSET�SET�13�IP2 ENDC ! IFEQ (%00010000&VALUE)-%00010000OFFSET�SET�5‘TBE�on�B-side ENDC ! IFEQ (%00000001&VALUE)-%00000001OFFSET�SET�4‘TBE�on�A-side ENDC ! IFEQ (%00100000&VALUE)-%00100000OFFSET�SET�1‘RCA�on�B-side ENDC ! IFEQ (%00000010&VALUE)-%00000010OFFSET�SET�0‘RCA�on�A-side ENDC ! IFEQ (%01000000&VALUE)-%01000000OFFSET�SET�9‘BCI�on�B-side ENDC ! IFEQ (%00000100&VALUE)-%00000100OFFSET�SET�8‘BCI�on�A-side ENDC  LIST VALUE SET VALUE Control register DC.B OFFSET ... and offset.VALUE SET VALUE+1 ENDM PAGEO*********************************************************************************ˆDEVICE�DEPENDENT�CCB*O******************************************************************************* ‰OFFSET�CCBDDP0AB_FLAG‚DS.Wƒ1–This�flag�is�used�to�determine�if *¦we�just�serviced�the�A-side�or!*¦B-side�upon�our�return�from�the *¦subordinate�interrupt�handler. *******************‚MISC�EQUATES‚******************* 3CLR_H3ƒEQU�2™Bit�used�to�clear�interrupt�from�PI/T.2LVL_H3ƒEQU�6™Bit�defining�level�of�interrupt�line.ŠPAGEJ***************************************************************************+*‰SERVICE�VECTOR�TABLE,�REVISION�INFO,�ETC.*@*‰This�table�is�examined�by�CMR�when�the�channel�is�allocated�toC*‰determine�where�to�go�for�interrupts,�commands,�&�initialization.<*‰It�must�always�be�at�the�very�top�of�the�driver�code.‚Also>*‰included�is�a�parameter�telling�the�number�of�extra�pages�of>*‰memory�to�include�in�the�CCB,�and�information�describing�the*‰revision�of�the�driver.*L**************************************************************************** ŠSECTION‚0ŠOPT„BRS DARTSPR: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!*=ŠDC.LƒINTERRUPT-DARTSPR‚Address�of�interrupt�service�routine.9ŠDC.LƒCOMMAND-DARTSPR„Address�of�command�service�routine.5ŠDC.LƒINIT-DARTSPR‡Address�of�initialization�routine.ŠDC.Lƒ0’Reserved. **‚Other�CMR�parameters.*0ŠDC.Bƒ0’#�of�extra�pages�in�the�CCB.‚The�CCB�may)*§be�any�size�from�1�to�256�pages�(a�page'*§is�256�bytes):‚if�this�field�is�0,�it*§will�be�1�page,�etc.ŠDC.Bƒ0,0,0ŽReserved.ŠDC.Lƒ0,0,0ŽReserved. **‚Revision�info:*/ŠDC.Bƒ'110184'‹Date�of�last�assembly�as�MMDDYY.1ŠDC.Bƒ'�'�Space�indicates�no�patches�to�.LO�file.)ŠDC.Bƒ'4'�Major�VERSAdos�revision�number.ŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INITIALIZATION�ROUTINE*'*‰Entry:�All�registers�have�been�saved.*�A5�=�address�of�CCB.**‰Exits�to�CMR�(via�RTS).*J**************************************************************************J**************************************************************************J********************** ****************************************************  INIT: *1*‚We�don't�have�anything�to�do�in�initialization.*ŠRTSŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMAND�SERVICE�ROUTINE*J**************************************************************************J**************************************************************************J************************************************************************** COMMAND: *D*‚We�should�never�be�called�for�command�service!‚Since�we�have�been,*‚crash�the�system.* ŠTR0$.KILLERŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INTERRUPT�HANDLING�ROUTINE*;*‰This�routine�gets�control�whenever�an�interrupt�occurs�on;*‰this�vector�(unless�another�handler,�earlier�on�the�chain*‰for�this�vector,�claimed�it).*+*‰It�is�the�task�of�the�supervisor�(me)�to:7*�--�determine�whether�the�interrupt�is�from�my�devices*“(channel�A�or�B�of�the�2681).2*�--�clear�the�interrupt�source�at�the�PI/T�on�the5*”VME115�(the�PI/T�is�responsible�for�the�vectoring).7*�--�if�not�mine,�return�to�CMR�with�the�carry�bit�0�to**“indicate�that�the�interrupt�wasn't�mine.9*�--�if�mine,�set�up�the�environment�for�and�pass�control3*“to�the�appropriate�subordinate�handler,�depending,*“upon�the�source�and�side�of�the�interrupt.*?*‰This�supervisor�driver�is�unlike�the�one�for�the�7201�in�that:*‰it�is�returned�to�from�the�subordinate�driver�due�to�theC*‰possibility�of�having�mulitple�bits�set�in�the�ISR�of�the�SCN2681"*‰for�one�interrupt�from�the�PI/T.*=*‰Exit�to�CMR�ia�always�via�RTS.‚We�set�the�carry�bit�in�this>*‰driver�to�tell�CMR�whether�we�handled�it.‚We�clear�the�carry>*‰bit�to�tell�CMR�we�didn't�handle�it,�and�CMR�should�pass�the;*‰interrupt�on�to�the�next�guy�in�the�chain�on�that�vector.*>*‰This�device�runs�on�the�MVME115�which�does�not�support�SDLC.*J**************************************************************************J**************************************************************************J************************************************************************** INTERRUPT:ŠMOVEQ.L�#0,D04ŠMOVE.L�CCBCHB(A5),A0†A0�<--�addr�of�A�side�of�2681.)ŠMOVE.L�#PIT_BASE,A1‡Address�of�the�PI/T.7ŠMOVE.B�#1<�we�don't�handle�it.*A*‚Set�up�CCB�address�for�our�port�and�jump�corresponding�handler.*BINT_RTNƒMOVE.L�CCBSUB(A0),A5†A5�<--�addr�of�CCB�of�A-side�handler..ŠMOVE.W�#0,AB_FLAG(A0)…Clear�the�AB-side�flag.2ŠBCLRƒ#0,D0ŽTest/clear�the�A-side/B-side�flag�bit.%ŠIF…�THENŠIf�it�was�set�(B-side),6ŠTST.L‚CCBSUB(A5)‰Make�sure�Port�B�has�been�allocated.5ŠIF…�THENŠThe�subordinate's�CCB�must�be�non-zero.;ŠMOVE.L�CCBSUB(A5),A5†A5�<--�addr�of�CCB�of�B-side�handler./ŠROR.B‚#4,D1ŽPut�working�ISR�into�lower�nibble..ŠMOVE.W�#$FF,AB_FLAG(A0)ƒSet�the�AB-side�flag.+ŠELSE–Port�B�has�not�been�allocated,�so....,ŠBRA.S‚NO_SUPPORT‰Exit,�no�interrupt�for�us.ŠENDIŠENDI–* BŠMOVE.L�CCBRTNI(A5),A1…A1�<--�entry�point�for�A�or�B�side�handler.6ŠJSR„(A1,D0.W)ŠJump�to�subroutine�in�the�branch�table.*.*¡<---‚When�we�return�here,�D1�has�bee n�set�up'*§with�bits�left�to�process�in�the�ISR,%*§and�A0�has�been�maintained�with�the(*§address�of�the�CCB�for�the�supervisor. PAGE*'*‚We've�returned�from�the�subordinate..=*‚If�there�are�any�bits�still�set�in�D1�we�must�process�them.*,ŠTST.L‚D1‘Is�there�any�work�left�to�process?9ŠBNE.S‚INT_TEST‹Branch�if�yes�to�process�more�interrupts.*4*‚It�appears�that�all�interrupts�have�been�serviced.?*‚However,�the�way�in�which�the�serial�port�interrupt�lines�areH*‚input�to�the�PI/T,�some�more�interrupts�may�have�come�in�while�we�wereG*‚servicing�those�which�were�set�at�the�time�we�entered�this�supervisorI*‚driver.‚Just�to�be�sure,�we�must�check�the�status�of�the�interrupt�lineF*‚at�the�PI/T.‚If�the�line�is�low�(active)�we�must�read�once�again�theC*‚interrupt�status�register�of�the�SCN2681,�and�service�those�bits.F*‚Otherwise,�we'll�be�left�with�interrupts�pending�and�its�possible�to*‚hang�up�the�port.*)ŠMOVE.L�#PIT_BASE,A1‡Address�of�the�PI/T.CŠBTST.B�#LVL_H3,PSR(A1)„LVL_H3�will�be�high�if�no�pending�interrupt+ŠBNE.S‚INT_EXIT‹Exit�since�no�bits�pending.*C*‚If�we've�reached�this�point,�there�are�new�interrupts�to�service.*$ŠMOVEQ‚#0,D1ŽA0�<--�addr�of�our�CCB.4ŠMOVE.L�CCBCHB(A0),A5†A5�<--�addr�of�A�side�of�2681.4ŠMOVE.B�ISR(A5),D1‰D1�<--�Interrupt�Status�Register.ŠBRA.S‚INT_MORE*I*‚If�we've�reached�this�point,�there�are�interrupts�left�over�to�service.*AINT_TEST‚TST.W‚AB_FLAG(A0)ˆYes,�so�let's�see�if�we�should�rotate.#ŠBEQ„INT_MORE‹More�work�for�A-side.*ŠROL.B‚#4,D1ŽPosition�ISR�bits�for�B-side.INT_MORE‚MOVEQ.L�#0,D0@ŠMOVE.B�OFFSET_TABLE(PC,D1.W),D0‚D0�<--�offset�into�int�routine.3ŠBPL„INT_RTNŒBranch�to�determine�which�subordinate.*G*‚If�we've�reached�this�point,�there�are�no�more�interrupts�to�service.*INT_EXIT‚POP.L‚D1‘Restore�D1,7ŠMOVEQ‚#0,D0Žset�carry�bit�to�tell�CMR�'we�handled�it'. ŠSUBQƒ#1,D0Ž*ŠRTS—and�return.*1*‚The�interrupt�was�not�for�me,�so�return�to�CMR.*NO_SUPPORT POP.L D1>NOT_FOR_ME�MOVEQ�#0,D0Žclear�carry�bit�to�tell�CMR�'not�ours'. ‹ADDQ‚#1,D0Ž*‹RTS–and�return. PAGEO********************************************************************************5*ˆNOTES�ABOUT�THE�INTERFACE�TO�THE�SUBORDINATE�DRIVER*A*ˆThe�subordinate�channel's�interrupt�entry�point�must�begin�with*ˆcode�like�the�following:* *ˆINTERRUPT:4*ˆ*‚Interrupts�received�from�the�2681�on�the�MVME115 *’BRA.L‚RCA *’BRA.L‚TBE *’BRA.L‚BCI *’BRA.L‚IPC*9*ˆThe�subordinate�driver�may�use�freely�(without�PUSHing)0*ˆany�of�the�following�registers:ƒD0,D1,A0,A1,A5*C*ˆUpon�leaving�this�supervisor�driver�and�entering�the�subordinate,#*ˆthe�registers�are�set�as�follows:)*ŒA0�<--�address�of�the�supervisor's�CCB.@*ŒA1�<--�entry�point�for�subordinate�driver's�interrupt�routine.**ŒA5�<--�address�of�the�subordinate's�CCB.7*ŒD0�<--�offset�to�first�subordinate�routine�to�handle.<*ŒD1�<--�current�Interrupt�Status�register�value�to�work�on.*A*ˆD1�must�be�set�up�with�the�bits�left�to�process�in�the�ISR,�and@*ˆA0�must�be�set�up�with�the�supervisor's�CCB�address�before�the=*ˆsubordinate�exits�from�its�interrupt�tour�to�return�to�this*ˆsupervisor�driver.*O*******************************************************************************ŠPAGEO*******************************************************************************O********************************************************************************2*‰OFFSET�TABLE�FOR�INTERUPT�STATUS�REGISTER�VALUES*>*‰The�following�steps�are�used�to�determine�source�and�side�of*‰a�2681�interrupt:*=*‰1.�The�8-bit�value�of�the�Interrupt�Status�Register�is�read"*Œand�eventually�gets�put�into�D1.>*‰2.�The�corresponding�offset�is�read�from�this�table�and�gets<*Œout�into�D0.�Bit�0�of�the�offset�is�used�as�a�flag�for�the7*Œsupervisor�driver�to�indicate�channel�A�or�channel�B.1*ŒBit�0�=�0�means�A-side;‚Bit�0�=�1�means�B-side.?*‰3.�If�corresponding�offset�comes�out�negative,�(-4=$FC),�then9*Œth  e�interrupt�is�not�for�us.‚Otherwise,�the�offsets�are *Œas�follows:*Ž0�=�RCA�interrupt�A-side*Ž1�=�RCA�interrupt�B-side*Ž4�=�TBE�interrupt�A-side*Ž5�=�TBE�interrupt�B-side*Ž8�=�BCI�interrupt�A-side*Ž9�=�BCI�interrupt�B-side*�13�=�IP2�interrupt�B-side**O*******************************************************************************O******************************************************************************* OFFSET_TABLE: ŠNOLIST VALUE…SET„0 ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLE ŠGENTABLEŠLIST ŠENDééééééé=/* =/*†DRVLIB.LF=/*'=/* Link chain file to create DRVLIB.RO.=/* Input modules should all be in SECTION 15.=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to DRVLIB.LL=/*=/IFC \1ƒ=ARG�DRVLIB.LL=/ENDIF=/*=LINK„,DRVLIB.RO,\1;HMIXRINPUT DRVLIB.QEVENT.ROIN„DRVLIB.LOGPHY.ROINPUT DRVLIB.SETTIME.ROEND=/*=ENDéééé  éé"=/*=/*†EPCIDRV.AF=/**=/* Chain file to assemble SIG 2661 driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to EPCIDRV.LS=/*=/IFC \1ƒ=ARG�EPCIDRV.LS=/ENDIF=/*$=ASM EPCIDRV.SA,EPCIDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.SIG2661.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDééééé+>EPCIDRVƒIDNTƒ4,1‡VERSADOS�2661�TERMINAL�DRIVER�WITH�TYPE-AHEAD;ŠTTL„EPCIDRV:‚VERSADOS�2661�TERMINAL�DRIVER�WITH�TYPE-AHEAD ŠLLENƒ120J**************************************************************************J**************************************************************************J**************************************************************************J***************************************************************************9*‰EPCIDRV:‚VERSAdos�2661�terminal�driver�with�type-ahead.*8*‰Purpose:‚VERSAdos�device�driver�to�handle�asynchronous3*�terminals�(of�any�type)�over�the�SIG�2661�chip�on*�the�following�boards:*’VM01ˆMVME�101**‰Revision�history:*7*�02/14/85‚Modified�INITERR�routine�to�clear�the�status5*šregister�flags;�old�instrucion�did�not�clear�flags./*šModified�PUT_CHAR�to�disable�interrupts�until,*šcharacter�is�transmitted;�old�instructions *šallowed�characters�to�be�lost.  éééé 4=ETMFU:]4e<m6u}>…>�•N�L¥K­Nµ;1*�10/23/84‚All�BSR's�to�TERMLIB�now�JSR's�in�case.*šTERMLIB�is�located�more�than�32K�bytes�away.:*�10/01/84‚Changed�PASS19.MPSCDRV.SA�to�drive�the�SIG2661,+*šalso�deleted�XREF's�to�BREAK�and�GET_LEN.3*‘8/30/84‚Fixed�SPR�concerning�SETUP.‚Commented�out(*šthe�code�that�tests�the�modem�bit.‚Now**šif�the�off�hook�bit�is�set,�the�DTR�line&*šis�set�low,‚whether�or�not�the�modem *šbit�is�set.*6*‘10/3/83‚Changes�to�let�interrupts�work�correctly�for**š2661�chip.�Also�allowes�DATA�I/O�to�work0*švia�RTS�line�(not�DTR).�DTR�is�always�enabled.*š(2661�chip�only).,*šChanged�by:�Marco�Schmidt�Motorola�Munich.2*‘8/19/83‚Added�conditional�assembly�stuff�to�make-*šthis�driver�assemble�for�the�7201�chip�(the4*šoriginal�driver)�and�for�the�Signetics�2661�(EPCI),*šchip.‚The�2661�is�on�both�the�VM01�and�the*šMVME101�board.8*‘4/�7/83‚Changed�UNSTOP�routine�to�fix�bug�where�a�char(*šis�destroyed�in�the�USE�XOFF/XON�mode.*7*�10/19/82‚Major�repairs�so�that�interrupts�will�not�be3*šdisabled�so�long�as�to�screw�up�SDLC.‚Revision�1.**‘9/16/82‚Initial�release�by�Steve�Franck.*J**************************************************************************J**************************************************************************J**************************************************************************ééJ**************************************************************************‰PAGE***‚XREF's�from�TERMLIB* ‰XREF†LOG_ERR ‰XREF†RESET‰XREF†TERM_INIT‰XREF†TERM_COMMAND‰XREF†TERM_TBE‰XREF†TERM_BREAK‰XREF†TERM_GOT_CHAR%***†XREF†TERM_UNRDYŠNot�used�by�EPCI.$***†XREF†MARK_DOWN‹Not�used�by�EPCI. *?*‚Masks�delineating�all�recognized�(REC)�and�unrecognized�(UNR)(*‚attributes�(ATT)�and�parameters�(PAR).*C*REC_ATTƒEQU„%1000111111111111‚1�bits�represent�defined�attributes.D*UNR_ATTƒEQU„$FFFF-REC_ATT†The�1's�complement�of�that�are�undefined. C*REC_PARƒEQU„%0111111111111111‚1�bits�represent�defined�parameters.D*UNR_PARƒEQU„$FFFF-REC_PAR†The�1's�complement�of�that�are�undefined.***‚Equate�files�included:**‰  9995..SIG2661.EQ*‰STR*‰TCB*‰CCB*‰9995..BAB.EQ*‰IOE*‰NIO*‰LV5#*‰TERMINAL.EQˆEquates�for�terminals *‰UTILITY.MC:*‰TERMCCB.EQ‰Offsets�and�equates�for�CCBDDP�for�terminals.*ŠPAGEŠINCLUDE�9995.&.SIG2661.EQŠNOLIST ŠTTL…STR.EQŠINCLUDE�9995.&.STR.EQŠNOLISTŠINCLUDE�9995.&.TCB.EQŠNOLISTŠINCLUDE�9995.&.CCB.EQŠNOLISTŠINCLUDE�9995.&.IOE.EQ‰NOLISTŠINCLUDE�9995.&.NIO.EQŠNOLISTŠINCLUDE�9995.&.LV5.EQ‰NOLIST‰INCLUDEƒ9995.&.BAB.EQŠLISTŠINCLUDE�9995.&.TERMINAL.EQ‰PAGEŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.TERMCCB.EQŠLIST‰OFFSET„TERMDDP*0*‚Device�dependent�Background�activation�blocks:$*„None�required�for�the�EPCI�driver.**@*ƒCompute�the�number�of�pages�of�memory�that�we�need�for�one�CCB>*ƒfor�the�MPSC�driver.‚CMR�automatically�allocates�one�page�ofA*ƒmemory�($100�bytes)�for�the�CCB,�and�our�variable�EXTCCBSZ�willB*ƒreside�in�the�CMR�parameter�table�at�the�beginning�of�the�driver8*ƒto�tell�CMR�how�many�extra�pages�of�memory�are�needed.**CCBSIZEB�EQU‡*PAGESIZE�EQU‡$100L1‡SET‡CCBSIZEB+PAGESIZE-1CCBSIZE‚EQU‡L1/PAGESIZEEXTCCBSZ�EQU‡CCBSIZE-1;ŠTTL„EPCIDRV:‚VERSADOS�2661�TERMINAL�DRIVER�WITH�TYPE-AHEADŠPAGEJ***************************************************************************+*‰SERVICE�VECTOR�TABLE,�REVISION�INFO,�ETC.*@*‰This�table�is�examined�by�CMR�when�the�channel�is�allocated�toC*‰determine�where�to�go�for�interrupts,�commands,�&�initialization.<*‰It�must�always�be�at�the�very�top�of�the�driver�code.‚Also>*‰included�is�a�parameter�telling�the�number�of�extra�pages�of>*‰memory�to�include�in�the�CCB,�and�information�describing�the*‰revision�of�the�driver.*L**************************************************************************** ŠSECTION‚0ŠOPT„BRS EPCIDRV: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!*=ŠDC.LƒINTERRUPT-EPCIDRV‚Address�of�interrupt�service�routine.9ŠDC.LƒCOMMAND-EPCIDRV„Address�of�command�service�routine.5ŠDC.LƒINIT-EPCIDRV‡Address�of�initialization�routine.ŠDC.Lƒ0’Reserved. **‚Other�CMR�parameters.*7ŠDC.BƒEXTCCBSZ‹#�of�extra�pages�in�the�CCB.‚The�CCB�may)*§be�any�size�from�1�to�256�pages�(a�page'*§is�256�bytes):‚if�this�field�is�0,�it*§will�be�1�page,�etc.ŠDC.Bƒ0,0,0ŽReserved.ŠDC.Lƒ0,0,0ŽReserved. **‚Revision�info:*/ŠDC.Bƒ'021485'‹Date�of�last�assembly�as�MMDDYY.1ŠDC.Bƒ'�'�Space�indicates�no�patches�to�.LO�file.)ŠDC.Bƒ'4'�Major�VERSAdos�revision�number.*‰PAGE*+*‚Jump�table�for�use�by�the�generic�TERMLIB*‰BRA.L…PUT_CHAR ‰BRA.L…CK_TBE‰BRA.L…DDP_RESET ‰BRA.L…SETUP‰BRA.L…CLOCK_RESET‰BRA.L…GET_STAT‰BRA.L…DDP_STOP‰BRA.L…DDP_UNSTOP‰BRA.L…DDP_BEG_BREAK‰BRA.L…DDP_END_BREAK **‰PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INITIALIZATION�ROUTINE*>*‰This�routine�is�called�by�CMR�when�the�channel�is�allocated.9*‰Its�purpose�is�to�set�up�things�for�command�service�and7*‰interrupt�service.‚The�major�functions�performed�are:"*�Validate�the�channel�type�field.+*�Get�memory�for�transmit�&�receive�queues..*�Initialize�flags,�pointers,�etc.�in�the�CCB.*�Initialize�the�2661.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.**‰Entry:�A5�=�address�of�CCB.*'*‰Exits�to:‚CMR�(via�RTS)�if�all�is�OK.'*”KILLER�if�exec�won't�allocate�memory.*J**************************************************************************J**************************************************************************J**************************************************************************   ŠDS…0 INIT:.‰JSR‡TERM_INIT‹Do�the�device-independent�stuff*%%%%%%%%%%%%%%ƒbwn‚8/13/842‰IFƒƒTHEN…Something�went�wrong�with�TERM_INIT.4‰IFƒƒTHEN„The�exec�call�failed�and�we�cannot�get!*œthe�scheduler's�entry�point�!!!ŽTR0$.KILLER‚,‰ELSE�RTS�The�channel�is�down�!!‰ENDI‰ENDI*?*‚Call�guarded�for�the�device�dependent�initialization�routine.**‰LEA‡DO_INIT(PC),A0‰MOVE.L„#T0GUARD,D0‰TRAP†#0‰RTSŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMAND�SERVICE�ROUTINE*>*‰We�get�entered�here�when�the�attached�task�(IOS)�invokes�CMR?*‰via�a�TRAP�1�with�an�INITIATE�I/O�parameter�block�to�process.>*‰CMR�has�already�checked�the�CMR�parameter�block�to�ensure�it<*‰resides�within�the�address�space�of�the�attached�task.‚IOSA*‰has�already�validated�the�IOCB,�except�for�the�buffer�addresses *‰therein.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.*5*‰Entry:�A2�=�physical�address�of�CMR�parameter�block*�A5�=�physical�address�of�CCB*3*‰Exit:‚D0�=�results�of�parameter�block�validation:3*•always�0�in�our�case,�indicating�it�was�OK,�since2*•IOS�will�not�send�us�any�request�except�HALT�I/O/*•if�we�are�already�busy,�and�CMR�makes�all�the*•other�checks.*A*‰Note:‚TERMLIB�does�not�recognize�CMR�commands�for�HALT�&�RESET.B*‰HALT�can�still�be�accomplished�through�use�of�the�HALT�I/O�IOCB.*J**************************************************************************J**************************************************************************J************************************************************************** COMMAND:‹JSR…TERM_COMMAND‹RTS—return�to�CMR.‹PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INTERRUPT�HANDLING�ROUTINE*<*‰This�routine�completes�I/O�requests�started�by�the�command:*‰service�routine.‚It�is�entered�at�the�interrupt�priority;*‰level�of�interrupts�on�this�channel,�and�is�essentially�a9*‰subroutine�to�the�first�level�interrupt�handler�in�CMR.*:*‰Entry:�D0,A0,A1�have�been�saved�by�CMR�and�are�available*�A5�=�address�of�CCB*9*‰Exit�is�always�via�RTS,�which�takes�us�back�to�CMR.‚The3*�carry�bit�is�examined�by�CMR�to�determine�whether7*�the�driver�handled�the�interrupt�or�whether�it�should4*�pass�the�interrupt�on�to�the�next�guy�in�the�chain*�on�that�vector:*��=�'I�handled�it'**‰Stack:*�(A7)+4�.�.�.*�(A7)ƒlongword�return�address*J**************************************************************************J**************************************************************************J************************************************************************** INTERRUPT:ŠPUSH.L�D1‘save�D1*ŠMOVE.L�CCBCHB(A5),A1†get�address�of�2661.8ŠMOVE.B�CREG(A1),D1ˆget�contents�of�the�control�register7ŠMOVE.B�SREG(A1),D0ˆget�contents�of�the�status�register*-*‰do�we�have�anything�enabled�on�this�device?**ŠBTSTƒ#TXEN,D1‹is�the�transmitter�enabled?3ŠBNE.S‚INT010�branch�if�it�is�-�we'e�getting�closer'ŠBTSTƒ#RXEN,D1‹is�the�receiver�enabled?1ŠBNE.S‚INT010�branch�if�it�is�-�we're�even�closer*3*‰this�interrupt�must�not�be�for�us�-�return�to�CMR*5INTNOP„POP.L‚D1‘restore�D1�so�CMR�will�work�correctly$ŠAND.W‚#$FFFE,SRŠclear�the�carry�bitŠRTS—and�go�away*8*ˆis�probably�some�interrupt�for�us�-�find�out�what�kind*$INT010ƒPUSH.L„D2ˆnow�we�need�D2�also6‰MOVE.B„D0,D2…need�another�copy�of�the�status�register!‰AND.B…#$38,D2ƒget�any�error�bits*‰BNE.S…SRC‡branch�if�any�error�b  its�are�on‰POP.L…D2ˆrestore�it.‰BTST†#RXRDY,D0�is�there�a�receiver�interrupt?'‰BNE.S…RCA‡branch�if�yes�-�go�handle�it1‰BTST†#TXRDY,D0�is�there�a�transmitter�interrupt?'‰BNE.S…TBE‡branch�if�yes�-�go�handle�it8‰BTST†#DNR,D0ƒis�there�a�change�in�the�DSR�or�DCD�lines?‰BNE.S…DSRTN…branch�if�there�is,‰BTST†#FB,D1„are�we�in�the�force�break�mode?+‰BNE.S…FBMODE„branch�if�forcing�a�break�now*B*ˆif�we�got�here�there�really�wasn't�on�interrupt�for�us�after�all*‰BRA.S…INTNOP„and�return‰PAGEJ***************************************************************************)*‰TRANSMIT�BUFFER�EMPTY�INTERRUPT�HANDLER*=*‰The�2661's�transmit�buffer�just�became�empty,�so�if�we�have+*‰more�characters�to�send�we�can�do�it�now.**‰Entry:�A0�=�NOT�USED*�A1�=�address�of�2661*�A5�=�address�of�CCB*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** TBE:(ŠMOVE.B„CREG(A1),D1‰get�control�register%ŠBCLR†#TXEN,D1Œswitch�off�the�Xmitter!ŠMOVE.B„D1,CREG(A1)‰load�the�chip *%%%%%%%%%%ƒBWN‚9/17/84*F*‚Call�the�device-independent�routine�that�deals�with�transparent�mode)*‚or�invokes�the�XMIT�background�routine.* ‰JSR‡TERM_TBE‰BRA.S…INT_EXIT‰PAGEJ***************************************************************************(*‰RECEIVED�CHARACTER�AVAILABLE�INTERRUPT*=*‰The�2661�has�just�received�a�character,�and�it�is�available=*‰for�reading.‚We�will�do�that�now,�and�the�result�will�go�in$*‰the�receive�queue�if�there's�room.**‰Entry:�A0�=�NOT�USED*�A1�=�address�of�2661*�A5�=�address�of�CCB*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** RCA:/‰MOVE.B„DREG(A1),D0‰Get�the�char�from�the�chip.*C*‚Call�the�device�independent�routine�to�check�for�transparent�modeG*‚and�do�the�stuff�for�transparent�mode�or�if�not�in�tranparent�mode�toG*‚check�for�any�special�characters�such�as�XON,�XOFF,�BREAK�EQUIVALENT,G*‚or�DISCARD�OUTPUT.�Otherwise,�put�the�character�in�the�receive�queue.*‰JSR‡TERM_GOT_CHAR‰BRA.S…INT_EXIT‰PAGEN*******************************************************************************%*ˆSPECIAL�RECEIVE�CONDITION�INTERRUPT,*‘An�error�bit�is�on�in�the�status�register.*‘Determine�actual�cause.*‘bit�3�=�parity�error*‘bit�4�=�dada�overrun8*‘bit�5�=�framing�error�or�break�(break�if�data�reg�=�0)**ˆEntry:ƒA0�=�NOT�USED*‘A1�=�address�of�2661*‘A5�=�CCB�adddress*‘D0�=�status�register�value*‘D1�=�control�register�value$*‘D2�=�error�bits�of�status�register)*–D2�MUST�be�pulled�off�the�stack�in�here*O******************************************************************************* SRC:+‰POP.L„D2“restore�D2�to�make�the�rest�happyé6‰BSET…#ERRSET,D1‹clear�status�reg�error�flags„02/14/85%‰MOVE.BƒD1,CREG(A1)Šdo�it�to�the�chip‰BTST…#PE,D0�a�parity�error?,‰BEQ.S„INTERR10�branch�if�not�a�parity�error;INTERR05�PUT_BYTE�PAR_FRAM,D0Šset�parity/framing�error�code ‰JSR†LOG_ERRŽand�go�tell�someone‰BRA.S„INT_EXIT$INTERR10�BTST…#DOVR,D0�data�overrun?é  ééééé*‰BEQ.S„INTERR20�branch�if�not�data�overrun0‰PUT_BYTE�OVERRUN,D0‹set�data�overrun�error�code ‰JSR†LOG_ERRŽand�go�tell�someone‰BRA.S„INT_EXIT%INTERR20�BTST…#FE,D0�a�framing�error?3‰BEQ.S„INT_EXIT�branch�if�no�-�we�shouldn't�be�here;‰MOVE.BƒDREG(A1),D0Šsee�if�a�break�instead�of�framing�error0‰BNE.S„INTERR05�branch�if�really�a�framing�error**ˆa�break�was�received*(‰MOVE.B„CREG(A1),D1‰get�control�register"‰BCLR†#RXEN,D1Œswitch�off�reciever)‰MOVE.B„D1,CREG(A1)‰tell�control�register*3‰JSR†TERM_BREAK‹Call�the�device�independent�routine*¦to�take�care�of�a�break.‰BRA.S„INT_EXIT‰PAGEO*********************************************************************************ˆFBMODE„FORCE�BREAK�INTERRUPT/*‘We�are�in�a�force�break�mode.‚We�want�to�stay3*‘in�this�mode�until�the�timer�we�previously�set-up *‘expires.**ˆEntry:‚A0�=�NOT�USED*�A1�=�address�of�2661*�A5�=�CCB�address*O******************************************************************************* FBMODE:+‰BRA.S„INT_EXIT�just�exit�interrupt�service‰PAGEO******************************************************************************** *ˆDSRTN…DATA�SET�READY�INTERRUPT4*’There�was�a�change�in�the�DSR�line�or�the‚DCD�line3*’or�the�transmitter�went�empty.‚We�only�care�about*’the�transmitter�going�empty.**ˆEntry:‚A0�=�NOT�USED*�A1�=�address�of�2661*�A5�=�CCB�address*�D0�=�status�register�value*�D1�=�control�register�value*O******************************************************************************* DSRTN:/‰MOVE.BƒSREG(A1),D1Šre-read�the�status�register,‰BTST…#DNR,D1Žis�the�interrupt�bit�still�on?3‰BEQ.S„INT_EXIT�branch�if�no,�ignore�this�interrupt,‰CMP.B„D0,D1�see�if�DSR�and�DCD�have�changed/‰BNE†TBE’this�is�really�a�transmitter�interrupt2‰BRA.S„INT_EXIT�we�don't�care�about�this�interrupt‰NOP‰PAGE*E*‚Now�exit�as�from�an�interrupt.‚We�may�in�fact�have�been�called�fromF*‚command�service�or�initialization,�but�they�had�to�set�it�up�to�look*‚like�an�interrupt,�too.*INT_EXIT:�POP.L‚D1‘Restore�D1,7ŠMOVEQ‚#1,D0Žset�carry�bit�to�tell�CMR�'we�handled�it,' ŠSUBQƒ#2,D0Ž*ŠRTS—and�return.ŠPAGEO********************************************************************************2*‰ROUTINES�TO�SET�THE�CLOCK�DIVISOR�TO�x16�AND�x64*7*‰No�work�here�since�2661�cannot�set�the�clock�divisor.*=*‰We�must�have�a�CLOCKRESET�entry�point�for�TERMLIB,�however.**‰Entry:*‹A5ƒ=�addr�of�our�CCB.**‰Exit:*O******************************************************************************* CLOCK_RESET:ŠRTSŠPAGEK*****************************************************************************!*�R�O�U�T�I�N�E�S„C�A�L�L�E�D„B�Y**–T�E�R�M�L�I�B**F**********  ************************************************************‰PAGEL******************************************************************************ˆTRANSMIT�THE�CHARACTER*?*ˆThis�is�the�device�dependent�routine�that�actually�writes�the*ˆcharacter�to�the�device.*F*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning�of�the *ˆdriver.**ˆEntry:„A1�=�address�of�2661*’A5�=�address�of�CCB*’D0.B�=�character�to�transmit*ˆInterrupt�level�on�entry:�0*C*ˆExit:…All�registers�are�preserved,�including�the�status�register.<*’It�is�important�to�keep�the�interrupt�level�the�same�as�it*’was�upon�entry.*J************************************************************************** PUT_CHAR:ŠSAVE„D1ŠPUSH„SR D***�The�following�code�was�commented�out�and�re-arranged�toŠ02/14/85#*** prevent the loss of characters:é)***‡MOVE.B‚D0,DREG(A1)ˆtransmit�the�char.0***‡MOVE.B‚CREG(A1),D1ˆswitch�on�the�transmitter***‡BSET„#TXEN,D1‹set�the�bit$***‡MOVE.B‚D1,CREG(A1)ˆtell�the�chip ŠINHIBIT/ŠMOVE.B‚CREG(A1),D1ˆread�current�register�value-ŠBSET„#TXEN,D1‹set�the�transmitter�enable�bit7ŠMOVE.B‚D1,CREG(A1)ˆtell�the�chip�to�enable�transmitter*ŠMOVE.B‚D0,DREG(A1)ˆtransmit�the�character ŠPOP…SR ŠRESTORE�D1ŠRTS‰PAGEM******************************************************************************$*ˆCHECK�THE�DEVICE'S�TRANSMIT�BUFFER*F*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installed�at*ˆthe�beginning�of�the�driver.**ˆEntry:�A1�=�address�of�2661*�A5�=�address�of�CCB*ˆInterrupt�level�on�entry:�0ééééé**ˆExit:‚Condition�codes:"*��=�transmit�buffer�not�empty*��=�transmit�buffer�empty<*ˆIt�is�important�to�keep�the�interrupt�level�the�same�as�it*ˆwas�upon�entry.*M*****************************************************************************CK_TBE:ŠMOVEM.L�D0-D1,-(A7)ŠPUSHƒSRŠINHIBIT ŠMOVE.B�CREG(A1),D1 ŠMOVE.B�D1,D0ŠBSETƒ#TXEN,D1ŠMOVE.B�D1,CREG(A1)5ŠBTST.B�#0,SREG(A1)ˆTest�if�transmit�buffer�is�empty. ŠIF��THEN$ŒMOVE.B�D0,CREG(A1)†BUFFER�IS�EMPTY.ŒPOP„SR4ŒAND.W‚#$FFFB,SRˆset�condition�code�for�return�.ŒMOVEM.L�(A7)+,D0-D1ŒRTS ŠENDI **‚Transmitter�is�not�empty:*(ŠMOVE.B�D0,CREG(A1)ˆBUFFER�IS�NOT�EMPTY.ŠPOP„SR3ŠOR.Wƒ#$0004,SRŠset�condition�code�for�return�.ŠMOVEM.L  �(A7)+,D0-D1ŠRTS‰PAGEH************************************************************************* *ˆDEVICE�DEPENDENT�RESET�ROUTINE*9*ˆThis�is�the�device-dependent�part�of�the�reset�routine.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:�A5�=�addr�of�CCB*ˆInterrupt�level�on�entry:�0*$*ˆExit:‚All�registers�are�preserved.<*ˆIt�is�important�to�keep�the�interrupt�level�the�same�as�it*ˆwas�upon�entry.*E********************************************************************* DDP_RESET:6ŠMOVEM.L‚A1/D0,-(A7)†save�used�registers�on�the�stack.ŠPUSH…SRŠINHIBIT )ŠMOVE.LƒCCBCHB(A5),A1„get�address�of�26615ŠMOVE.Bƒ#$37,CREG(A1)„turn�the�tranmitter�on,�rec.�on'ŠMOVE.BƒDREG(A1),D0†clear�any�interrupt ŠPOP†SR0ŠMOVEM.L‚(A7)+,A1/D0†Restore�saved�registers�and ŠRTS—exit.ŠPAGEJ***************************************************************************@*‰SUBROUTINE�TO�SET�UP�THE�DEVICE�ACCORDING�TO�THE�CONFIGURATION*;*‰Uses�the�working�configuration�(in�the�CCB)�to�set�up�the;*‰device,�and�some�configuration-related�fields�in�the�CCB.*?*‰The�offset�to�this�routine�must�be�installed�at�the�beginning*‰of�the�driver.**‰Entry:�A5�=�address�of�CCB*‰Interrupt�level�on�entry:�0*$*‰Exit:‚All�registers�are�preserved.<*‰It�is�important�to�keep�the�interrupt�level�the�same�as�it*‰was�upon�entry.*J************************************************************************** SETUP:<ŠMOVEM.L�D0-D1/A0-A3,-(A7)�Save�some�registers�on�the�stack.ŠPUSHƒSR**‚First�set�up�addresses:4ŠLEA„CONFIG(A5),A0†A0�<--�addr�of�CCB�configuration.3ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�2661�port. -ŠPUT_BYTE‚ASY16X,D0…Start�with�x16�clock�rate:ŠBTSTW‚#IOASTPB,IOSATW(A0)�Add�in�the�number�of�stop�bits. ŠIF…�THENŠOR.B…#SB1,D0�1�stop�bitŠELSEŠOR.B…#SB2,D0�2�stop�bitsŠENDI >ŠBTSTW‚#IOAUSEP,IOSATW(A0)�If�we're�using�parity,�enable�it... ŠIF…�THENŠOR.B…#PENBL,D0:ŠBTSTW‚#IOAPRTY,IOSATW(A0)�and�if�we're�using�even�parity,ŠIF…�THENŠset�it�up.ŠOR.B…#PTYPE,D0ŠENDIŠENDI 1ŠBTSTW‚#IOABITS,IOSATW(A0)�Add�in�bits/char�info. ŠIF…�THENŠOR.Bƒ#BIT7,D0ˆ(7�bits/char)ŠELSEŠOR.Bƒ#BIT8,D0ˆ(8�bits/char)ŠENDI ŠINHIBIT2ŠMOVE.BƒD0,MREG1(A1)…set�mode�reg�1�for�above�info2ŠMOVE.BƒIOSBRT(A0),D0„get�user�specified�baud�rate#ŠOR.B…#ITCX16,D0‡set�16x�clock�rate=ŠMOVE.BƒD0,MREG2(A1)…set�mode�reg�2�for�16x�clock�rate�&�baud ŠMOVE…(A7),SRŠPAGE*/*‚[5]„RTS�&�DTR�lines�low,�transmitter�enabled,*‰bits/char�from�configuration.*2ŠMOVE.Bƒ#$37,D0Žset�for�norm,�RTS�low,�reset�error"*ªflags,no�break,disable�transmit,*ªenable�receiver,�DTR�low***5***‚Remove�the�modem�test,�as�per�the�MPSCDRV�driver:***C****†BTSTW‚#IOAMODM,IOSATW(A0)„If�this�is�a�modem�we're�talking�to,****†IF…�THENŽ*8ŠBTSTW‚#IOAOFFH,IOSATW(A0)„and�the�guy�wants�it�offhook,ŠIF…�THENŽ*ŠAND.B‚#$FF-DTR,D0 ***‡ENDIš*ŠENDIš* ŠINHIBIT,ŠMOVE.B‚D0,CREG(A0)ˆset�the�control�register0ŠMOVE.B‚SREG(A0),D0ˆclear�any�pending�interruptsŠPOP„SR **‚Restore�registers�and�return.*8ŠMOVEM.L�(A7)+,D0-D1/A0-A3�Restore�registers�from�stack.ŠRTSŠPAGEJ****************************************************************************‰GET�DEVICE�STATUS�BYTE*"*‰Prepares�the�DEVICE�STATUS�byte.*8*‰Note:‚this�routine�does�not�set�the�break�indicator�in*�the�device�status�byte.*?*‰The�offset�to�this�routine�must�be�installed�at�the�beginning*‰of�the�driver.**‰Entry:�A5�=�address�of�CCB*‰Interrupt�level�on�entry:�0*&*‰Exit:‚D0.B�=�the�device�status�byte.<*‰It�is�important�to�keep�the�interrupt�level�the�same�as�it*‰was�upon�entry.*J************************************************************************** GET_STAT:*4* Let's see if the device status bit 'DSR' is ready.* ‰CLR.B…D0‰MOVEM.LƒD1/A0,-(A7) 2‰MOVE.L„CCBCHB(A5),A0‡get�the�address�of�the�2661.5‰M  OVE.B„SREG(A0),D1‰get�the�DSR�bit�of�the�status�reg ‰TST.B…D1/‰IFˆ�THEN‹bit�7�is�the�DSR�bit�in�2661�chip5‰BSET†#XDSNRB,D0Šset�the�unready�bit�in�the�dev.state‰ENDI ‰MOVEM.Lƒ(A7)+,D1/A0‰RTS‰PAGEM******************************************************************************5*ˆDEVICE�DEPENDENT�STUFF�FOR�LOWERING�A�HARDWARE�LINE*ˆTO�STOP�THE�TRANSMITTER.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�address�of�2661*�A5�=�address�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*K*************************************************************************** DDP_STOP:*0*ˆThe�VME101�board�needs�RTS�for�the�hand�shake!*ŠSAVE…D0 ,ŠMOVE.BƒCREG(A1),D0‰get�the�control�register%ŠBCLR…#RTS,D0�disable�request�to�send%ŠMOVE.BƒD0,CREG(A1)‰do�it�to�the�chip ŠRESTORE‚D0ŠRTSŠPAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�UNSTOP�THE�DEVICE*=*ˆWhen�we�are�not�using�XOFF/XON,�we�unstop�the�device�in�our*ˆown�device�dependent�way.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�address�of�2661*�A5�=�address�of�the�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*J************************************************************************** DDP_UNSTOP:*2*‰for�the�VME101�we�need�RTS�to�do�the�hand�shake.*ŠSAVE…D0 ,ŠMOVE.BƒCREG(A1),D0‰get�the�control�register$ŠBSET…#RTS,D0�enable�request�to�send)ŠMOVE.BƒD0,CREG(A1)‰and�do�it�to�the�chip ŠRESTORE‚D0ŠRTSŠPAGEK****************************************************************************&*ˆDEVICE�DEPENDENT�BEGIN�BREAK�ROUTINE*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�addr�of�2661*�A5�=�addr�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*E********************************************************************* DDP_BEG_BREAK:*)*‚start�the�2661�sending�the�break�signal*‰SAVE„D0 9‰MOVE.B‚CREG(A1),D0†get�current�state�of�control�register)‰OR.B„#FB,D0‹turn�on�the�force�brack�line+‰OR.B„#TXEN,D0‰turn�on�the�transmitter�also-‰MOVE.B‚D0,CREG(A1)†and�write�it�all�back�out ‰RESTORE�D0‰RTS‰PAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�END�BREAK�ROUTINE*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�addr�of�2661*�A5�=�addr�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*L**************************************************************************** DDP_END_BREAK:ŠSAVE„D0 9ŠMOVE.B‚CREG(A1),D0Šget�current�state�of�control�registerŠBCLR„#3,D0�turn�off�the�break,ŠBCLR„#TXEN,D0�turn�off�the�transmitter�also)ŠMOVE.B‚D0,CREG(A1)Šand�write�it�back�out0ŠMOVE.B‚SREG(A1),D0Šclear�any�pending�interrupts ŠRESTORE�D0ŠRTSŠPAGEI***************************************************************************“B�A�C�K�G�R�O�U�N�D**šAND**‘C�A�L�L�__�G�U�A�R�D�E�D**–R�O�U�T�I�N�E�S**•(DEVICE-DEPENDENT)*E*********************************************************************ŠPAGEO*********************************************************************************‰FINISH�OFF�THE�INITIALIZATION*A*‰The�initialization�routine�has�gone�around�resetting�everything@*‰it�can,�but�the�routines�RESET�and�SETUP�should�only�be�called>*‰from�within�the�background.‚So�he�invoked�this�routine�to�do *‰it�for�him.**‰Entry:*�A1�=�address�of�2661.*�A5�=�address�of�CCB.*O**************************************************************** *************** DO_INIT:**‚Inhibit�interrupts*‰PUSH†SR‰INHIBIT*)*‚Get�address�of�start�of�driver�into�CCB*‰LEA‡EPCIDRV(PC),A4‰MOVE.L„A4,DRV_ADDR(A5) ‰JSR„RESETŽReset�everything.‰BSR.L‚DDP_RESET5‰BSR.L‚SETUPŽSet�up�the�2661�according�to�the�config.**‚Enable�interrupts�now.*‰POP‡SR‰RTS‰PAGE*********************** *‚PATCH�SPACE***********************ŠDS.Wƒ30ŠEND  ééé=/* =/*†IPCDRV.AF=/*)=/* Chain file to assemble the IPC driver=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to IPCDRV.LS=/*=/IFC \1ƒ=ARG�IPCDRV.LS=/ENDIF=/*#=ASM IPCDRV.SA,IPCDRV.RO,\1;MRZ=160=/*{ Included files are:=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.UTILITY.MC=/*}=/*=ENDéééééé½DIPCDRV„IDNTƒ4,4�VERSAdos�IPC�I/O�Handler�Process�Ver.�4.4�-�11/28/84AŠTTL„VERSADOS�IPC�CHANNEL�I/O�HANDLER�PROCESS�VER.�4.4�-�11/28/84 ŠNOFORMATŠPAGE ŠLLENƒ120J***************************************************************************,* IPC -- REV. 1.05 02JUN80 (TB59) STEVE BALL4*�2.00�02NOV81�(TL09)�JIM�SMITH…-�SPLIT�IPC�FROM�CMR.*�2.01�01FEB82�(TL09)�JIM�SMITH…-�VECTOR�CHAIN**�2.02�23FEB82�(TL09)�JIM�SMITH…-�IOCB�USE4*�4.00�01SEP82ˆMARC�BRIEL„-�CONFIGURE�CLASS�REQUESTS4*�4.30�14SEP83 �(TB59)�STEVE�BALL„-�FIX�HALT�I/O�BUGS6*�4.xx�23APR84ˆFRED�MATHESON�-�UPDATE�PER�NEW�FIRMWARE3*�4.40�28NOV84ˆPHIL�DUCLOSƒ-�ADD�CONFIG�AREA�IN�CCB:*�4.41�27DEC84ˆDICK�VANDERLIN�-�BUG�FIX�FOR�DCT�TABLE�SIZE0*�4.42�08JAN85ˆPHIL�DUCLOSƒ-�EXPAND�DCT�TO�LUMAXB*******************************************************************+*�Changes�to�IPCDRV�for�version�4.3ƒ8/28/84*?*‚1.�The�IPC�driver�has�been�modified�to�take�advantages�of�the;*…increased�functionality�provided�by�recent�changes�to�the*…MCCM�firmware.*+*�Changes�to�IPCDRV�for�version�4.3ƒ9/25/84*<*‚1.�The�IPC�driver�was�modified�to�delete�refenences�to�the*…Seconday�Map�bit.*?*‚2.�The�IPC�driver�was�modified�to�include�changes�required�by*…4.4�enhancements.* *�Changes�to�IPCDRVƒ11/26/84ƒPJD*G* 1. The device area was moved from an allocated segment to the CCB andF*„current�configuration�information�was�added�to�the�CCB.‚2�additional@*„segments�are�now�required�for�the�CCB.‚The�getseg�call�for�the*„device�area�was�deleted.*C********************************************************************.* USER REQUEST SIDE FOR IPC COMMAND PROCESSING*9*ƒPURPOSE:‚VALIDATE�AND�PASS�IPC�COMMAND�INFORMATION�FROM#*�USER�TO�IPC,�68000�SHARED�MEMORY.**ƒENTRY:‚JSR�FROM�CMR�HANDLER*‹JSR�FROM�INTERRUPT�HANDLER*5*ƒEXIT:‚RTS�-�PARAMETER�BLOCK�VALIDATION�STATUS�IN�D0***ƒSYSGEN�OPTIONS:�DCB�CONFIGURE�PARAMETERS**ƒEXEC�ROUTINES�CALLED:‚QEVENTT**ƒCODE�IS�RE-ENTRANT*¿Æ:ÏV×Iß;ç=ï=÷Eÿ9GHIH':/77K?XGLOJW;_6g<oAwE<‡9�I—HŸ?§B¯AH*-----------------------------------------------------------------------**ŠPAGE **‚Included�equate�files:*ˆ9995.&.TRACE.EQ*ˆ9995.&.STR.EQ*ˆ9995.&.TCB.EQ*ˆ9995.&.CCB.EQ*ˆ9995.&.IOE.EQ*ˆ9995.&.NIO.EQ*ˆ9995.&.LV5.EQ*ŠNOLISTŠINCLUDE�9995.&.TRACE.EQŠINCLUDE�9995.&.STR.EQŠINCLUDE�9995.&.TCB.EQŠINCLUDE�9995.&.CCB.EQŠINCLUDE�9995.&.IOE.EQŠINCLUDE�9995.&.NIO.EQŠINCLUDE�9995.&.LV5.EQN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<ŠINCLUDE�9995.&.DUALPORT.MCŠINCLUDE�9995.&.UTILITY.MCN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>ŠLISTŠPAGE* ŠSECTION�0‰PAGEO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83**ˆBIT�TEST�MACRO* BTSTM„MACRO „IFGE†\1-16‰OPT‡MEX‰BTSTW…#\1-16,\2(\3) ‰OPT‡NOMEX„ENDC* „IFLT†\1-16‰OPT‡MEX‰BTSTW…#\1,\2+2(\3) ‰OPT‡NOMEX„ENDC‰ENDM *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<‰PAGE**$*…EQUATES�FOR�TESTING�VECTOR�NUMBERS*#AVECTLOƒEQU„25‘LOWEST�AUTO�VECTOR�#$AVECTHIƒEQU„31‘HIGHEST�AUTO�VECTOR�##UVECTLOƒEQU„64‘LOWEST�USER�VECTOR�# IPCORG„EQU„*ŠPAGE*6* IPC COMMAND PACKET FORMAT (AS SEEN IN SHARED MEMORY)* ŠOFFSET�0IPCSTX„DS.Bƒ1*2�START�OF�TEXTIPCPID„DS.Bƒ1*2�PACKET�IDN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<*£$40�=�2nd�Configure�Packet*£0ƒ=�all�othersN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>IPCPKSZƒDS.Bƒ1*2�PACKET�SIZE IPCPHDVƒDS.Bƒ1*2�PHYSICAL�DEVICE%IPCCHCMƒDS.Bƒ1*2�CHANNEL�COMMAND�TYPEIPCDVCMƒDS.Bƒ1*2�DEVICE�COMMAND$IPCNBKSƒDS.Bƒ2*2�#BLOCKS�TO�TRANSFERIPCBKSZƒDS.Bƒ2*2�BLOCKSIZE*IPCBUFAD‚DS.Bƒ4*2�68000�ADDRESS�(PHYSICAL)IPCCKSMƒDS.Bƒ2*2�CHECKSUM$IPCCMPRM‚DS.Bƒ4*2�COMMAND�PARAMETERSIPCETX„DS.Bƒ1*2�ETX�LOCATION** OUTPUT WITH INPUT EXTENSIONŠOFFSET�IPCCMPRM!IPCSWCFƒDS.Bƒ4*2�SOFTWARE�OPTIONS-IPCNBKS2‚DS.Bƒ2*2�#BLOCKS�(OUTPUT�WITH�INPUT)/IPCBKSZ2‚DS.Bƒ2*2�BLOCKSIZE�(OUTPUT�WITH�INPUT)3IPCBUFA2‚DS.Bƒ4*2�68000�ADDRESS�(OUTPUT�WITH�INPUT)IPCETX2ƒDS.Bƒ1*2�ETX�LOCATION** CONFIGURE PACKET (1st)*ŠOFFSET�IPCNBKS)IPCHWC1ƒDS.Bƒ1*2�H /W�CONFIGURATION�BYTE�1)IPCHWC2ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�2)IPCHWC3ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�3)IPCHWC4ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�4)IPCSWC1ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�1)IPCSWC2ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�2)IPCSWC3ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�3)IPCSWC4ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�4IPCCETXƒDS.Bƒ1*2�ETX�LOCATIONN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<** CONFIGURE PACKET (2nd)*ŠOFFSET�IPCNBKS$IPCPMSKƒDS.Bƒ2*2�IOCB�PARAMETER�MASKIPCXOF„DS.Bƒ1*2�XOFF�CHARACTERIPCXON„DS.Bƒ1*2�XON�CHARACTER%IPCBRK„DS.Bƒ1*2�BREAK�EQUIVALENT�CHARŠDS.Bƒ1*2�UNUSED"IPCRPRTƒDS.Bƒ1*2�REPRINT�LINE�CHAR!IPCCNCLƒDS.Bƒ1*2�CANCEL�LINE�CHAR,IPCRTRMƒDS.Bƒ4*2�READ�TERMINATING�CHAR'S�(4)&IPCEOL„DS.Bƒ2*2�END�OF�LINE�STRING�(2)IPC2ETXƒDS.Bƒ1*2�ETX*N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>** FORMAT TRACK PACKETŠOFFSET�IPCBUFAD'IPCFPSNƒDS.Bƒ4*2�PHYSICAL�SECTOR�NUMBERIPCFETXƒDS.Bƒ1*2�ETX�LOCATION** FORMAT DISK PACKETŠOFFSET�IPCNBKSIPCDETXƒDS.Bƒ1*2�ETX�LOCATION** REQUEST STATUS PACKETŠOFFSET�IPCNBKSIPCRETXƒDS.Bƒ1*2�ETX�LOCATION* * IPC RETURN (COMPLETION) PACKET* ŠOFFSET�0RTNSTX„DS.Bƒ1*2�START�OF�TEXTRTNPID„DS.Bƒ1*2�PACKET�I.D.RTNPKSZƒDS.Bƒ1*2�PACKET�SIZE RTNPHDVƒDS.Bƒ1*2�PHYSICAL�DEVICE RTNCHCMƒDS.Bƒ1*2�CHANNEL�COMMANDRTNSTCMƒDS.Bƒ1*2�STATUS�COMMANDRTNSTVLƒDS.Bƒ2*2�STATUS�VALUERTNSTPRƒEQU„*’STATUS�PARAMETERS** IPC NORMAL COMPLETION EVENT*ŠOFFSET�RTNSTPRRTNBLKSƒDS.Bƒ2*2�NO.�OF�BLOCKSRTNBKSZƒDS.Bƒ2*2�BLOCK�SIZE#RTNDADRƒDS.Bƒ4*2�68K�MEMORY�ADDRESS** DISK ERROR COMPLETION EVENT*ŠOFFSET�RTNSTPR%RTNSECNƒDS.Bƒ4*2�ENDING�SECTOR�NUMBER** DISK STATUS RETURN*ŠOFFSET�RTNSTPRRTNDSTAƒDS.Bƒ2*2�DEVICE�STATUS RTNLSECƒDS.Bƒ4*2�LOGICAL�SECTORS* * PRINTER/TERMINAL STATUS RETURN*ŠOFFSET�RTNSTPRRTNSTADƒDS.Bƒ4*2�DEVICE�STATUS)RTNHWS1ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�1)RTNHWS2ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�2)RTNHWS3ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�3)RTNHWS4ƒDS.Bƒ1*2�H/W�CONFIGURATION�BYTE�4)RTNSWS1ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�1)RTNSWS2ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�2)RTNSWS3ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�3)RTNSWS4ƒDS.Bƒ1*2�S/W�CONFIGURATION�BYTE�4** IPC MEM MAPPED EQUATES*,IPCINT„EQU„$0D�68000�TO�IPC�INTERRUPT�OFFSET*IPCRESET‚EQU„$0F�68000�TO�IPC�RESET�OFFSET'IPCIMB1ƒEQU„$101�68000�TO�IPC�WRITE�BOX%IPCIAB1ƒEQU„$103�68000�TO�IPC�ACK�BOX#IPCIM1„EQU„$105�68000�COMMAND�WRITE'IPCIMB2ƒEQU„$181�IPC�TO�68000�WRITE�BOX%IPCIAB2ƒEQU„$183�IPC�TO�68000�ACK�BOX!IPCIM2„EQU„$185�IPC�COMMAND�WRITE*IPCLST„EQU„$1FF�LAST�BYTE�OF�SHARED�MEMORY** MISCELLANEOUS EQUATES* STX‡EQU„$02 ETX‡EQU„$03 RSˆEQU„$1E ACK‡EQU„$06 NAK‡EQU„$151LUMAX…EQU„8’MAXIMUM�DEVICE�NO.�VALUE�FOR�DISK�IPC(*£MCCM�MAX�IS�5�BUT�THEIR�IS�TABLE�SPACE*£ENOUGH�FOR�8.(IPCRDCDƒEQU„$10�CHANNEL�COMMAND�FOR�READ)IPCWRCDƒEQU„$20�CHANNEL�COMMAND�FOR�WRITE(RTNGDC„EQU„$70�NORMAL�STATUS�PACKET�CODE,RTNHLT„EQU„$71�HALT/ABORT�STATUS�PACKET�CODE+RTNSTA„EQU„$72�SOLICITED�STATUS�PACKET�CODE&RTNUNS„EQU„$80�UNSOLICITED�PACKET�CODE"RTNGDS„EQU„$0000ŽGOOD�STATUS�VALUE,SPKT†EQU„$0200ŽFIRST�2�BYTES�OF�EVERY�PACKET+SECSIZƒEQU„$100“SYSTEM�REQUIRED�SECTOR�SIZE'IOPKSZ„EQU„21”READ�OR�WRITE�PACKET�SIZE,OWIPKSZƒEQU„29”OUTPUT�WITH�INPUT�PACKET�SIZE'STPKSZ„EQU„7•STATUS�REQUEST�PACKET�SIZE#CNPKSZ„EQU„15”CONFIGURE�PACKET�SIZEN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<'C2PKSZ„EQU„21”CONFIGURE�2nd�PACKET�SIZE(TBKPKSZƒEQU„7•TRANSMIT�BREAK�PACKET�SIZEN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>$FDPKSZ„EQU„7•FORMAT�DISK�PACKET�SIZE&FTPKSZ„EQU„15”FORMAT�TRACK�PACKET�SIZEHLTPKSZƒEQU„7•HALT�PACKET�SIZEIOEVCD„EQU„1•I/O�EVENT�CODE$SMMBIT„EQU„24”SECONDARY�MEM.�MAP�BIT3PRTPRM„EQU„$0023‘PRINTER�CONFIG�PARAMETER�EDIT�MASK4PRTATM„EQU„$0003‘PRINTER�CONFIG�ATTRIBUTES�EDIT�MASK4TERPRM„EQU„$5FB3‘TERMINAL�CONFIG�PARAMETER�EDI T�MASK5TERATM„EQU„$06FE‘TERMINAL�CONFIG�ATTRIBUTES�EDIT�MASK** OPTION EQUATES*$XPKCECH‚EQU„$C0000000ŽNO�ECHO�OPTIONN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<-XPKCTAB‚EQU„$88000000ŽFLUSH�TYPE�AHEAD�BUFFERN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<+XSWFF„EQU„$82000000ŽTOP�OF�PAGE�(FORM�FEED)** CONFIGURATION EQUATES*XHWBITƒEQU„2–8�BIT�PARITYXHWPRTY‚EQU„4–PARITYXHWEVNƒEQU„5–EVEN�PARITYXHWSTPƒEQU„6–2�STOP�BITSXHWMDMƒEQU„4–MODEM*N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<XSWXONƒEQU„2–XON/XOFF�OR�CTS)XSWFLSH‚EQU„3–FLUSH�THE�TYPE�AHEAD�BUFFER'XSWTAHD‚EQU„4–ACCEPT/INHIBIT�TYPE�AHEAD!XSWNULƒEQU„5–DISCARD/ACCEPT�NULLSN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>XSWHDXƒEQU„6–HALF�DUPLEXXSWALFƒEQU„0–AUTO�LINE�FEED%XSWTOFƒEQU„1–TOP�OF�FORM�BEFORE�PRINT‰PAGE*%*ˆEQUATES�FOR�CHANNEL/DEVICE�COMMANDS*XREAD„EQU…$1001�READ!XWRITCƒEQU…$2001�WRITE�WITH�CHECK$XWRITNƒEQU…$2002�WRITE�WITHOUT�CHECKXRCRC„EQU…$3001�READ�CRCXREADYƒEQU…$3002�READY"XRDHP„EQU…$3003�READ�HEAD�POSITIONXFTRAKƒEQU…$4001�FORMAT�TRACKXFDISKƒEQU…$4002�FORMAT�DISK'XWDDM„EQU…$4003�WRITE�DELETED�DATA�MARKXRESTOR‚EQU…$4004�RESTOREXSEEK„EQU…$4005�SEEKXHALT„EQU…$5001�HALTXBOOT„EQU…$6000�BOOTSTRAP�LOAD*6*ˆADDITIONAL�EQUATES�FOR�COMM.�CHANNEL/DEVICE�COMMANDS*XINF…EQU…$1001�READ�FORMATTEDXINI…EQU…$1002�READ�IMAGE XOUTF„EQU…$2001�OUTPUT�FORMATTEDXOUTI„EQU…$2002�OUTPUT�IMAGE0XOFIF„EQU…$2801�OUTPUT�FORMATTED�INPUT�FORMATTED,XOFIM„EQU…$2802�OUTPUT�FORMATTED�INPUT�IMAGE(XOIIM„EQU…$2803�OUTPUT�IMAGE�INPUT�IMAGE,XOIIF„EQU…$2804�OUTPUT�IMAGE�INPUT�FORMATTED"XBCASTƒEQU…$2007�BROADCAST�MESSAGE XCONH„EQU…$4001�CONFIGURE�DEVICEN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<.XCON2PƒEQU…$4002�CONFIGURE�DEVICE�(2ND�PACKET)&XCNF2PK‚EQU…$40‘PACKET�ID�(2ND�PACKET)(XTRNSBK‚EQU…$4003�TRANSMIT�BREAK�REQUESTN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>**ˆSTATUS�VALUE*XPSOK„EQU…0“SUCCESSFULXPSCRCƒEQU…1“DATA�CRC�ERROR!XPSDWPƒEQU…2“DISK�WRITE�PROTECTEDXPSDNRƒEQU…3“DISK�NOT�READY#XPSRDMƒEQU…4“READ�DELETED�DATA�MARK"XPSDEVƒEQU…5“INVALID�DEVICE�ADDRES!XPSIDAƒEQU…6“INVALID�DISK�ADDRESSXPSSEKƒEQU…7“RESTORE�ERRORXPSDMEƒEQU…8“RECORD�NOT�FOUND#XPSMRKƒEQU…9“ADDRESS�MARK�CRC�ERRORXPSCDMA‚EQU…$A’DMA�ERRORXPSCSMƒEQU…$B’CHECKSUM�ERRORXPSBSYƒEQU…$C’DEVICE�BUSY(XPSCBSY‚EQU…$D’CHANNEL�BUSY�(FORMATTING)XPSINDƒEQU…$E’INDETERMINATEXPSCNTL‚EQU…$F’CONTROLLER�ERRORXPSDVCƒEQU…$10‘DEVICE�ERRORXPSSEEK‚EQU…$11‘SEEK�ERROR#XPSNODR‚EQU…$12‘NO�DEVICE�CONNECTED&XPXCFGƒEQU…$13‘DEVICE�CONNECT�CONFLICTXPSCMPƒEQU…$14‘COMPARE�ERROR%XPSSWPƒEQU…$15‘SECTOR�WRITE�PROTECTEDXPSBADƒEQU…$16‘BAD�SECTORXPSTOTƒEQU…$17‘TIMEOUTXPSCMDƒEQU…$18‘INVALID�COMMAND!XPSICMƒEQU…1“INVALID�HALT�COMMANDXPSDMAƒEQU…1“DMA�CHANNEL�ERROR'XPSCSTA‚EQU…1“PERSONALITY�STATUS�RETURNO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<<&*ˆIPC�Completion�Packet�Flag�Positions*'PIDPKTF‚EQU…6“PACKET�ID�2nd�PACKET�FLAGO*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>>* *ˆADDITIONAL�COMM.�STATUS�VALUES*XPSPARƒEQU…1“PARITY�ERRORXPSBRKƒEQU…2“BREAK�CONDITIONXPSFRMƒEQU…4“FRAMMING�ERRORXPSOVRƒEQU…6“DATA�OVERUN!XPSOUTƒEQU…7“PRINTER�OUT�OF�PAPER**ƒMiscellaneous�equates*5CCBEXTRA‚EQU„2”This�parameter�specifies�the�number�of+*£extra�pages�to�be�allocated�by�CMR�to�the**£CCB�when�the�channel�is�allocated.�Up�to"*£255�extra�pages�may�be�specifiedŠPAGE*** MACRO FOR PUTTING THE H/W PRIORITY LEVEL'* TO THE PRIORITY INDICATED BY THE CCB.* INHIB„MACRO,‰MOVE.W„CCBISR(A5),SR‡SET�PROCESSOR�PRIORITY‰ENDM*+* MACRO FOR DROPPING THE H/W PRIORITY LEVEL* TO AN INTERRUPTABLE STATE.* ENABL„MACRO3‰MOVE.W„CCBSR(A5),SRˆDROP�PROCESSOR�PRIORI TY�BY�ONE‰ENDM‰PAGE* * STRUCTURE FOR DEVICE NO. TABLE* ‰OFFSET�0LUFLG„DS.Bƒ2–ENTRY�FLAGLUDCB„DS.Bƒ4–DCB�ADDRESSLUIOCBƒDS.Bƒ4–IOCB�ADDRESSLUTCB„DS.Bƒ4–TCB�ADDRESSLUBADRƒDS.Bƒ4–BUFFER�ADDRESS>CNFG…DS.BƒIOSDDC-IOSATWŠspace�for�device�#�independent�portion*¦of�configuration.5LUENTRY‚EQU„*–length�of�common�part�of�device�#�entry**ˆAPPROXIMATELY�225�INSTRUCTIONS�EXECUTED�TO�GET�TO�THIS�POINT *ˆ(600�us).*J***************************************************************************IOHUSER:** CHECK FOR RESET*ƒIF�RESET,�DO�IT�AND�GET�OUT*)ŠCMP.B‚#XDREST,XIOSCD(A2)�TEST�RESET�BYTE#ŠBNE.S‚IOH01000‹BRANCH�IF�NOT�RESETŠBSR „CMRRESTŒCALL�RESET�ROUTINEŠBRA„IPCUSRTN‹RETURN*$* RETURN IF CHANNEL IS IN ERROR MODE*!IOH01000‚BTSTW‚#CCBFGER,CCBFG(A5)2ŠBEQ.S‚IOH01010‹BRANCH�IF�NOT�MARKED�IN�ERROR�MODE)ŠMOVE.B�#ISTACDN,D1ˆSET�UP�IOS�ERROR�CODE ŠBRA„ABORT*D* IF WE ARE WAITING FOR ACK/NAK THEN WE CANNOT HONOR THE REQUEST AND2*ƒMUST�SIGNAL�THE�CALLER�THAT�THE�CHANNEL�IS�BUSY.*IOH01010‚EQU„* ŠCLR.L‚D7'ŠBTSTW‚#CCBFGWAK,CCBFG(A5)�WAITING�ACK?)ŠBEQ.S‚IOH01020‹BRANCH�IF�NOT�WAITING�ACK*F* REQUEST CAME THRU WHILE WAITING FOR ACK - GIVE USER BACK BUSY STATUS*$ŠMOVE.B�#XSTBSY,D0‡ERROR�RETURN�CODE ŠBRA„IPCUSRTN*(* CONVERT LOGICAL PB ADDRESS TO PHYSICAL*IOH01020‚CLR.L‚D5,ŠMOVE.L�XIOCPK(A2),D6†ADDR�OF�COMMAND�PACKET+ŠMOVE.W�XIOPLN(A2),D5†LENGTH�OF�COMMAND�PKT"ŠMOVE.L�CCBTASKA(A5),A1„SET�UP�TCB ŠBSR„IOHADRCKŠBRA.S‚IOH01060‹GOOD�RETURNŠNOP—BAD�LENGTH�RETURN(ŠMOVE.B�#ISTAIP,D1‰SET�UP�IOS�ERROR�CODE ŠBRA„ABORT5IOH01060‚MOVE.L�D6,A3ŽCOMMAND�PACKET�PHYSICAL�ADDRESS*3* DETERMINE IF SHARED MEMORY IS FREE (IT SHOULD BE)*.ŠMOVE.L�CCBCHB(A5),A4†MEMORY�MAPPED�BASE�TO�A4ŠMOVE.B�IPCIMB1(A4),D00ŠBEQ.S‚IOH02060‹BRANCH�IF�NO�ERROR�(MEMORY�FREE)*:* SHARED MEMORY IS NOT FREE AND WE ARE NOT WAITING ON ACK.*ƒERROR�CONDITION.*)ŠBSETW‚#CCBFGER,CCBFG(A5)�MARK�CCB�AS�BAD)ŠMOVE.B�#ISTACDN,D1ˆSET�UP�IOS�ERROR�CODE ŠBRA„ABORT *K****************************************************************************(*‚FIND�THE�COMMAND�IN�THE�COMMAND�TABLE.* IOH02060‚EQU„*)ŠMOVE.L�XIOUID(A2),A4†PICK�UP�DCB�POINTER8ŠMOVE.L�CCBTASKA(A5),CCBTASKB(A5)�SET�UP�BUFFER�TASK�TCB-ŠMOVEQ‚#NUMCMDS-1,D0†Set�up�the�loop�counter./ŠLEA„CMDTBL,A0ŠA0�<--�address�of�command�table./ŠMOVE.W�IOSFCT(A3),D6†Set�up�user�command�code. 8CMDSRCHƒCMP.W‚(A0)+,D6‹Search�the�table�for�the�command.ŠDBEQƒD0,CMDSRCH‰* 3ŠBNE.S‚CMDERR�If�we�found�the�command�in�the�table,8ŠADD.L‚#JMPOFF-2,A0‡get�the�corresponding�entry�from�the5ŠMOVE.W�(A0),D0Œjump�table�and�jump�to�the�routine�to"ŠJMP„(A0,D0.W)Šhandle�the�command.ŠSPC„2>CMDERR„MOVE.B�#ISTAIF,D1ŠThe�command�wasn't�found�in�the�table2ŠBRA„ABORTŽso�exit�with�an�invalid�function�error.ŠPAGEM*******************************************************************************‰REQUEST�STATUS*(*‰Entry:�A2�=�address�of�CMR�param�block*�A3�=�address�of�user's�IOCB*�A4�=�address�of�DCB*�A5�=�address�of�my�CCB*�A6�=�address�of�user's�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*M******************************************************************************REQSTAT:&ŠBSR†CNFGLEN�SET�UP�DATA�BUFFER�LENGTH0ŠMOVE.LƒIOSDBP(A3),D6‡SET�UP�DATA�BUFFER�ADDRESS ŠBSR†BUFADDR*¦Physical�Addr�returned�in�D62ŠMOVE.LƒD6,CCBPTR(A5)‡SAVE�BUFFER�PHYSICAL�ADDRESSŠSPC†2*?*‰Retrieve�the�masks�of�supported�attributes�and�parameters�for@*‰the�requested�device�and�store�them�in�the�users�configuration*‰status�block.* ŠMOVE.L�D6,A0 ŠBSR„VALATPRM$ŠMOVE.W�D0,IOSATM(A0)‰Attribute�mask$ŠMOVE.W�D1,IOSPRM(A0)‰Parameter�maskŠSPC„2 ŠCLR.L„D6-ŠBSET…#LUFACT,D6ŠSET�ACTIVE�DEVICE�TABLE�FLAG%ŠBSR†DEVTBLŽSET�UP�DEVICE�TABLE�ENTRY /ŠBSR†SETPKTŽSET�UP�PACKET�HEADER�IN�SHARED�MEM. ŠMOVE.Wƒ#XREADY,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDS#ŠMOVE.Bƒ#ETX,IPCRETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#STPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE ŠBRA†NRMEXIT      ŠPAGEM****************************************************************************** *‰CONFIGURE*@*‰This�command�changes�the�CCB�configuration,�the�one�from�which<*‰the�driver�sets�up�the�device�and�under�which�it�performs.*(*‰Entry:�A2�=�address�of�CMR�param�block*�A3�=�address�of�user's�IOCB*�A4�=�address�of�DCB*�A5�=�address�of�my�CCB*�A6�=�address�of�user's�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*M****************************************************************************** CONFIGUR:%ŠCMP.B„#XTDIPC,CCBTYPE(A5)�DISK�IPC‚?/ŠBEQ†REQSTAT�YES,� MUST�LOOK�LIKE�STATUS�REQUEST &ŠBSR†CNFGLEN�SET�UP�DATA�BUFFER�LENGTH0ŠMOVE.LƒIOSDBP(A3),D6‡SET�UP�DATA�BUFFER�ADDRESS ŠBSR†BUFADDR2ŠMOVE.LƒD6,CCBPTR(A5)‡SAVE�BUFFER�PHYSICAL�ADDRESS#ŠMOVE.LƒD6,A0�SET�UP�BUFFER�POINTERŠSPC„2-ŠBSR†VALATPRMŒRetrieve�the�masks�of�supported6ŠMOVEM.W‚D0-D1,-(A7)‰attributes�and�parameters�for�the(*¦requested�device�and�save�the�masks�on *¦the�stack.ŠSPC„29ŠMOVE.Bƒ#CECUAP,D2ŠIf�unsupported�attributes�or�parameter2ŠNOT.W„D0’are�specified�in�the�users�attributes�or<ŠAND.W„IOSATM(A0),D0‡parameters�mask,�return�a�configuration*ŠNOT.W„D1’error.�Restore�the�stacked�masks1ŠAND.W„IOSPRM(A0),D1‡before�processing�the�error. ŠOR.W…D0,D1ŠMOVEM.W‚(A7)+,D0-D1ŠBNE.S„IPCR220AŠSPC„26ŠMOVE.Bƒ#CECCDO,D2ŠIf�the�user�is�trying�to�change�the1ŠMOVE.Wƒ#%1100,D3‹read�or�write�timeout,�return�a)ŠAND.W„IOSPRM(A0),D3‡configuration�error.ŠBNE.S„IPCR220AŠBRA.S„IPCR220BŠPAGEŠSPC†2BIPCR220A‚MOVE.BƒD2,IOSCEC(A0)‡Save�the�configuration�error�code�in:ŠMOVE.Bƒ#ISTACNF,D1‰the�users�configuration�data�block�and/ŠBRA†ABORT�return�a�configuration�error�to�IOS.ŠSPC†2IPCR220B‚CLR.L„D6-ŠBSET…#LUFACT,D6ŠSET�ACTIVE�DEVICE�TABLE�FLAG%ŠBSR†DEVTBLŽSET�UP�DEVICE�TABLE�ENTRY*/ŠBSR†SETPKTŽSET�UP�PACKET�HEADER�IN�SHARED�MEM.ŠMOVE.Wƒ#XCONH,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDSŠSPC†23ŠMOVE.LƒCCBPTR(A5),A0‡Load�the�address�of�the�users*¦configure�parameter�block.N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PJD 11/26/843‰MOVEM.LƒA5,-(A7)ŒSave�the�CCB�address�on�the�stack:‰MOVE.L„CCBDTBL(A5),A5†Get�the�start�address�of�the�device*¦tables‰CLR.L…D0’Need�the�whole�reg!4‰MOVE.B„DCBCDV(A4),D0‡Get�the�device�number�from�DCB6‰MULU†#LUDSZE,D0ŠMUL�size�of�an�entry�by�device�number&*¦to�get�distance�from�start�of�table./‰ADD.L…D0,A5�Add�to�base�to�get�start�of�device*¦table�for�this�device.4‰LEA‡CONFIG(A5),A5‡Use�offset�from�base�of�CONFIG�so!*¦we�can�use�the�IOE�equates�into*¦the�configuration�data.N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< PJD 11/26/84ŠSPC†2O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83A*‰BTSTW‚#DATPRT,DCBATT(A4)ƒIf�the�requested�device�is�a�terminal,>ŠBTSTM‚DATPRT,DCBATT,A4…If�the�requested�device�is�a�terminal, *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<:ŠBEQ.S‚IPCR222Œbranch�to�generate�a�terminal�configuration *£packet.‰PAGE*)*ˆSet�up�the�printer�configuration�packet**'*ˆStart�of�Hardware�Confoguration�bytes0ŠMOVE.Lƒ#$80000000,D0‡SET�UP�H/W�CONFIGURE�BYTES*&*ˆCheck�for�line�length�change�request*B‰BTSTW…#IOSRECB,IOSPRM(A0)�Does�he�want�to�change�the�line�length?#‰BEQ.S…IPCR221AŒNo,�use�the�current=ŠMOVE.BƒIOSREC+1(A0),D0…Yes,�pick�up�the�line�length�he�wants‰BRA.S…IPCR221B**ˆUse�the�current�line�length*;IPCR221A�MOVE.B„IOSREC+1(A5),D0…Use�the�current�line�lengthCIPCR221B‚MOVEP.L‚D0,IPCHWC1(A1)†PUT�H/W�CONFIGURATION�IN�SHARED�MEM%*ˆEnd�of�Hardware�Configuration�bytes'*ˆStart�of�Software�Configuration�bytes‰MOVE.L„#$00000080,D0*+*ˆCheck�for�Top�of�Form�before�print�option*A‰BTSTW…#IOASNFF,IOSATM(A0)�Does�he�want�to�change�the�Top�of�Form *¦option?#‰BEQ.S…IPCR221DŒNo,�use�the�current8‰BTSTW…#IOASNFF,IOSATW(A0)�Yes,�does�he�want�the�option? ‰BEQ.S…IPCR221EŒNo,�don't�set�it-IPCR221C�BSET†#XSWTOF,D0ŠYes,�set�the�option!‰BRA.S…IPCR221EDIPCR221D�BTSTW…#IOASNFF,IOSATW(A5)�Is�the�option�set�in�the�current? ‰BNE.S…IPCR221CŒYes,�keep�it�set:IPCR221E�ROL.L…#8,D0�Rotate�the�first�byte�out�of�the�way.*!*ˆCheck�for�Auto�Line�feed�option*C‰BTSTW…#IOALNFD,IOSATM(A0)�Does�he�want�to�change�the�AUTO�LINEFEED *¦option?#‰BEQ.S…IPCR221GŒNo,�use�the�current<ŠBTSTW„#IOALNFD,IOSATW(A0)�Yes,�does�he�want�AUTO�LINE�FEED?.ŠBEQ.S„IPCR221HŒNo,�NO�AUTO�LINE�FEED�desired.;IPCR221F‚BSET…#XSWALF,D0 ŠYes,�set�the�AUTO�LINE�FEED�option‰BRA.S…IPCR221H6IPCR221G�BTSTW…#IOALNFD,IOSATW(A5)�Use�AUTO�LINE�FEED?3‰BNE.S…IPCR221FŒYes,�set�the�AUTO�LINE�FEED�option.;IPCR221H�ROL.L…#8,D0�Rotate�the�second�byte�out�of�the�way.*'*ˆCheck�the�end�of�line/print�character*C‰BTSTW…#IOSELCB,IOSPRM(A0)�Does�he�want�to�change�the�end-print�ch?#‰BEQ.S…IPCR221IŒNo,�use�the�current7‰MOVE.B„IOSELC(A0),D0‡Yes,�get�the�char�he�wants�to�use‰BRA.S…IPCR221J3IPCR221I�MOVE.B„IOSELC(A5),D0‡Use�the�current�value6IPCR221J�ROL.L…#8,D0�Move�the�3rd�byte�out�of�the�way.*4*ˆAll�choices�made,�send�the�lword�to�the�shared�ram*?‰MOVEP.LƒD0,IPCSWC1(A1)†Send�the�Software�Config�to�shared�mem.*)*ˆEnd�of�the�Software�Configuration�bytes"*ˆEnd�of�the�Printer�Configuration* ŠBRA†IPCR249ŠPAGE*!*ˆStart�of�Terminal�Configuration* IPCR222ƒEQU†*ŠMOVE.Lƒ#$80,D0*"*‰CHECK�ATTRIBUTE�MASK�-�STOP�BITS*ŠBTSTW„#IOASTPB,IOSATM(A0)ŠBEQ.S„IPCR223ŽUSE�DEFAULT*%*‰SETUP�STOP�BITS�FROM�ATTRIBUTE�WORD*(ŠBTSTW„#IOASTPB,IOSATW(A0)‚2�STOP�BITS�?ŠBEQ.S„IPCR225ŽBRANCH�IF�NO&ŠBRA.S„IPCR224ŽYES�-�GO�SET�OPTION�BIT*1*‰SETUP�STOP�BITS�FROM�CURRENT�CONFIGURATION�AREA* IPCR223ƒEQU†*(ŠBTSTW„#IOASTPB,IOSATW(A5)‚2�STOP�BITS�?ŠBEQ.S„IPCR225ŽBRANCH�IF�NO**‰SET�THE�OPTION�BIT* IPCR224ƒEQU†*ŠBSET…#XHWSTP,D0*%*‰CHECK�ATTRIBUTE�MASK�-�7/8�BIT�MASK* IPCR225ƒEQU†*ŠBTSTW„#IOABITS,IOSATM(A0)ŠBEQ.S„IPCR226�USE�DEFAULT***‰SETUP�NUMBER�OF�BITS�FROM�ATTRIBUTE�WORD*"ŠBTSTW„#IOABITS,IOSATW(A0)‚8�BIT�?ŠBNE.S„IPCR228ŽBRANCH�IF�NOŠBRA.S„IPCR227ŽYES*6*‰SETUP�NUMBER�OF�BITS�FROM�CURRENT�CONFIGURATION�AREA* IPCR226ƒEQU†*"ŠBTSTW„#IOABITS,IOSATW(A5)‚8�BIT�?ŠBNE.S„IPCR228ŽBRANCH�IF�NO**‰SET�THE�8�BIT�OPTION�BIT* IPCR227ƒEQU†*$ŠBSET…#XHWBIT,D0‹YES,�SET�OPTION�BIT**‰CHECK�ATTRIBUTE�MASK�-�PARITY* IPCR228ƒEQU†*ŠBTSTW„#IOAUSEP,IOSATM(A0)ŠBEQ.S„IPCR229�USE�DEFAULT*&*‰SETUP�PARITY�USE�FROM�ATTRIBUTE�WORD*%ŠBTSTW„#IOAUSEP,IOSATW(A0)‚USE�PARITYŠBEQ.S„IPCR231ŽBRANCH�IF�NOŠBRA.S„IPCR230ŽYES*2*‰SETUP�PARITY�USE�FROM�CURRENT�CONFIGURATION�AREA* IPCR229ƒEQU†*$ŠBTSTW„#IOAUSEP,IOSATW(A5)‚USE�PARIYŠBEQ.S„IPCR231ŽBRANCH�IF�NO**‰SET�THE�PARITY�USE�OPTION�BIT* IPCR230ƒEQU†*%ŠBSET…#XHWPRTY,D0ŠYES,�SET�OPTION�BIT*(*‰CHECK�ATTRIBUTE�MASK�-�ODD/EVEN�PARITY* IPCR231ƒEQU†*ŠBTSTW„#IOAPRTY,IOSATM(A0)ŠBEQ.S„IPCR232�USE�DEFAULT*+*‰SETUP�EVEN/ODD�PARITY�FROM�ATTRIBUTE�WORD*&ŠBTSTW„#IOAPRTY,IOSATW(A0)‚EVEN�PARITYŠBEQ.S„IPCR234ŽBRANCH�IF�NOŠBRA.S„IPCR233ŽYES*7*‰SETUP�EVEN/ODD�PARITY�FROM�CURRENT�CONFIGURATION�AREA* IPCR232ƒEQU†*(ŠBTSTW„#IOAPRTY,IOSATW(A5)‚EVEN�PARITY�?ŠBEQ.S„IPCR234ŽBRANCH�IF�NO* *‰SET�THE�PARITY�EVEN�OPTION�BIT* IPCR233ƒEQU†*$ŠBSET…#XHWEVN,D0‹YES,�SET�OPTION�BIT*%*‰PUT�BYTE�1�H/W�CONFIG�IN�SHARED�MEM* IPCR234ƒEQU†*ŠMOVE.BƒD0,IPCHWC1(A1)*(*ˆCheck�the�parameters�mask�for�baudrate*<‰BTSTW…#IOSBRTB,IOSPRM(A0)�Should�we�configure�the�baudrate?'‰BEQ.S…IPCR234AŒNo,�use�the�current�one.ŠMOVE.BƒIOSBRT(A0),D0‡Yes,�pick�up�the�new�one‰BRA.S…IPCR234B*(*ˆUse�the�current�configuration‚baudrate*=IPCR234A�MOVE.B„IOSBRT(A5),D0‡Use�the�current�config�baudrate>‰MOVE.B„D0,IOSBRT(A0)‡Update�the�user's�IOCB�to�show�new�bdrte**‰CHECK�ATTRIBUTE�MASK�-�MODEM*"IPCR234B‚BTSTW„#IOAMODM,IOSATM(A0)ŠBEQ.S„IPCR235�USE�DEFAULT*!*‰SETUP�MODEM�FROM�ATTRIBUTE�WORD*!ŠBTSTW„#IOAMODM,IOSATW(A0)‚MODEM?ŠBEQ.S„IPCR237ŽBRANCH�IF�NOŠBRA.S„IPCR236ŽYES*-*‰SETUP�MODEM�FROM�CURRENT�CONFIGURATION�AREA* IPCR235ƒEQU†*"ŠBTSTW„#IOAMODM,IOSATW(A5)‚MODEM�?ŠBEQ.S„IPCR237ŽBRANCH�IF�NO**‰SET�THE�MODEM�OPTION�BIT* IPCR236ƒEQU†**ŠBSET…#XHWMDM,D0‹YES,�SET�MODEM�OPTION�BIT*(*‰PUT�BYTE�2�H/W�CONFIG�IN�SHARED�MEMORY* IPCR237ƒEQU†*ŠMOVE.BƒD0,IPCHWC2(A1)*'*ˆCheck�the�parameters�mask�-�Null�Pads*3‰BTSTW…#IOSNLSB,IOSPRM(A0)‹Configure�the�null�pads?*‰BEQ.S…IPCR237A– No,�use�the�current�config:ŠMOVE.BƒIOSNLS(A0),IPCHWC3(A1)ˆYes,�move�user's�value�into *°shared�ram.‰BRA.S…IPCR237B*CIPCR237A‚MOVE.BƒIOSNLS(A5),IPCHWC3(A1)ˆUse�the�current�config�value.ŠMOVE.BƒIOSNLS(A5),IOSNLS(A0)‰Update�user�IOCB*#*ˆCheck�the�record�length�parameter*?IPCR237B�BTSTW…#IOSRECB,IOSPRM(A0)‹Configure�the�record�length?‰BEQ.S…IPCR237C>ŠMOVE.BƒIOSREC+1(A0),IPCHWC4(A1)‚PUT�LINE�LENGTH�IN�SHARED�MEM‰BRA.S…IPCR237D(IPCR237C�MOVE.B„IOSREC+1(A5),IPCHWC4(A1)!‰MOVE.B„IOSREC+1(A5),IOSREC+1(A0)IPCR237D‚CLR.L„D02ŠMOVEP.L‚D0,IPCSWC1(A1)‡SET�UP�S/W�CONFIGURE�BYTES*ŠOR.B…#$80,D0ŽSET�THE�CONFIGURE�OPTION�BIT*$*‰CHECK�ATTRIBUTE�MASK�-�HALF�DUPLEX*ŠBTSTW„#IOAECHO,IOSATM(A0)ŠBEQ.S„IPCR238�USE�DEFAULT*'*‰SETUP�HALF�DUPLEX�FROM�ATTRIBUTE�WORD*'ŠBTSTW„#IOAECHO,IOSATW(A0)‚HALF�DUPLEX?ŠBEQ.S„IPCR240ŽBRANCH�IF�NOŠBRA.S„IPCR239ŽYES*3*‰SETUP�HALF�DUPLEX�FROM�CURRENT�CONFIGURATION�AREA* IPCR238ƒEQU†*(ŠBTSTW„#IOAECHO,IOSATW(A5)‚HALF�DUPLEX�?ŠBEQ.S„IPCR240ŽBRANCH�IF�NO* *‰SET�THE�HALF�DUPLEX�OPTION�BIT* IPCR239ƒEQU†*1ŠBSET…#XSWHDX,D0‹YES�-�SET�HALF�DUPLEX�OPTION�BITN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<*%*‰CHECK�ATTRIBUTE�MASK�-�ACCEPT�NULLS* IPCR240ƒEQU†*ŠBTSTW„#IOAPNUL,IOSATM(A0)ŠBEQ.S„IPCR241�USE�DEFAULT*(*‰SETUP�ACCEPT�NULLS�FROM�ATTRIBUTE�WORD*)ŠBTSTW„#IOAPNUL,IOSATW(A0)‚ACCEPT�NULLS�?ŠBEQ.S„IPCR243ŽBRANCH�IF�NOŠBRA.S„IPCR242ŽYES*4*‰SETUP�ACCEPT�NULLS�FROM�CURRENT�CONFIGURATION�AREA* IPCR241ƒEQU†*)ŠBTSTW„#IOAPNUL,IOSATW(A5)‚ACCEPT�NULLS�?ŠBEQ.S„IPCR243ŽBRANCH�IF�NO*!*‰SET�THE�ACCEPT�NULLS�OPTION�BIT* IPCR242ƒEQU†*%ŠBSET…#XSWNUL,D0ŠYES�-�SET�OPTION�BIT***‰CHECK�ATTRIBUTE�MASK�-�ACCEPT�TYPE�AHEAD* IPCR243ƒEQU†*ŠBTSTW„#IOATAHD,IOSATM(A0)ŠBEQ.S„IPCR244�USE�DEFAULT*-*‰SETUP�ACCEPT�TYPE�AHEAD�FROM�ATTRIBUTE�WORD*,ŠBTSTW„#IOATAHD,IOSATW(A0)‚ACCEPT�TYPE�AHEAD+ŠBEQ.S„IPCR246ŽBRANCH�IF�TYPE�AHEAD�ALLOWED#ŠBRA.S„IPCR245ŽTYPE�AHEAD�INHIBITED*9*‰SETUP�ACCEPT�TYPE�AHEAD�FROM�CURRENT�CONFIGURATION�AREA* IPCR244ƒEQU†*.ŠBTSTW„#IOATAHD,IOSATW(A5)‚ACCEPT�TYPE�AHEAD�?+ŠBEQ.S„IPCR246ŽBRANCH�IF�TYPE�AHEAD�ALLOWED*0*‰SET�THE�ACCEPT�TYPE�AHEAD�INHIBITED�OPTION�BIT* IPCR245ƒEQU†*/ŠBSET…#XSWTAHD,D0‰NO�-�SET�TYPE�AHEAD�INHIBITED*(*‰CHECK�ATTRIBUTE�MASK�-�XON/XOFF�OR�CTS* IPCR246ƒEQU†*ŠBTSTW„#IOAXCTL,IOSATM(A0)ŠBEQ.S„IPCR247�USE�DEFAULT*+*‰SETUP�XON/XOFF�OR�CTS�FROM�ATTRIBUTE�WORD*'ŠBTSTW„#IOAXCTL,IOSATW(A0)�USE�XON/XOFFŠBEQ.S„IPCR249ŽNO�-�USE�CTSŠBRA.S„IPCR248ŽYES*7*‰SETUP�XON/XOFF�OR�CTS�FROM�CURRENT�CONFIGURATION�AREA* IPCR247ƒEQU†*'ŠBTSTW„#IOAXCTL,IOSATW(A0)�USE�XON/XOFFŠBEQ.S„IPCR249�NO�-�USE�CTS**‰SET�THE�USE�XON/XOFF�OPTION* IPCR248ƒEQU†*ŠBSET…#XSWXON,D0 IPCR249ƒEQU†*ŠMOVE.Lƒ(A7)+,A5ŒRESTORE�A5 IPCR250ƒEQU†*2ŠMOVE.BƒD0,IPCSWC1(A1)†SET�UP�S/W�CONFIGURE�BYTE�1N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>*#ŠMOVE.Bƒ#ETX,IPCCETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#CNPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE9ŠMOVE.Bƒ#1,DCBCCF(A4)‡SET�CONFIGURATION�COORDINATION�FLAG ŠBRA†NRMEXITŠPAGEM*******************************************************************************‰CHANGE�DEFAULT�CONFIGURATION*6*‰This�command�changes�the�DCB�configuration,�to�which4*‰IOS�will�restore�us�(via�a�CONFIGURE�command)�when/*‰FHS�closes�the�last�allocation�of�the�device.*(*‰Entry:�A2�=�address�of�CMR�param�block*�A3�=�address�of�user's�IOCB*�A4�=�address�of�DCB*�A5�=�address�of�my�CCB*�A6�=�address�of�user's�TCB*M******************************************************************************CHNGDEF:%ŠCMP.B‚#XTDIPC,CCBTYPE(A5)ƒDISK�IPC‚?2ŠBEQ„REQSTAT�If�so,�perform�a�configuration/status *§request.&ŠBSR„CNFGLEN�SET�UP�DATA�BUFFER�LENGTH0ŠMOVE.LƒIOSDBP(A3),D6‡SET�UP�DATA�BUFFER�ADDRESS ŠBSR†BUFADDR2ŠMOVE.LƒD6,CCBPTR(A5)‡SAVE�BUFFER�PHYSICAL�ADDRESS 7ŠLEA†DCBDEV(A4),A0„A0�<--�addr ess�of�DCB�configuration. *G************************************************************************)* Printer/Terminal change default command** CCHGD020ƒMOVE.L�CCBPTR(A5),A1†A1�<--�physical�address�of�data�block.ŠSPC„23ŠMOVE.B�#CECUAP,D2‹If�any�unsupported�attributes�or3ŠBSR„VALATPRM‹parameters�are�specified�in�the�users1ŠNOT.W‚D0‘attributes�or�parameters�mask,�return�a)ŠAND.W‚IOSATM(A1),D0†configuration�error. ŠNOT.W‚D1ŠAND.W‚IOSPRM(A1),D1 ŠOR.WƒD0,D1 ŠBNE„BADCNFGŠSPC„2*F*‚First�we�need�to�see�what�his�proposed�configuration�will�look�like.D*‚Plug�into�his�data�block�the�current�values�for�those�attributes�&?*‚parameters�he�doesn't�want�to�change.‚The�appropriate�current(*‚configuration�is�at�A0�and�he's�at�A1.*4ŠMOVE.W�IOSATM(A1),D0†Pick�up�users�attributes�mask.;ŠAND.W‚D0,IOSATW(A1)†Zero�out�the�attributes�of�his�that�he.ŠNOT.W‚D0‘doesn't�want�to�change,�zero�out�the<ŠAND.W‚IOSATW(A0),D0†attributes�of�mine�that�he�does�want�to:ŠOR.WƒD0,IOSATW(A1)†change,�and�combine�them�in�his�space. @ŠMOVE.W�IOSPRM(A1),D0†Get�mask�of�parameters�he�wants�to�change. 1ŠLSR.W‚#1,D0ŽIf�he's�not�changing�the�LINE�WIDTH,ŠBCS.S‚CHGD022Œgive�him�ours.ŠMOVE.W�IOSREC(A0),IOSREC(A1) 8CHGD022ƒLSR.W‚#1,D0ŽIf�he's�not�changing�the�LINES/PAGE,ŠBCS.S‚CHGD024Œgive�him�ours.ŠMOVE.L�IOSRSZ(A0),IOSRSZ(A1) :CHGD024ƒLSR.W‚#1,D0ŽIf�he's�not�changing�the�WRITE�TIMEOUT$ŠBCS.S‚CHGD026Œvalue,�give�him�ours.ŠMOVE.L�IOSWTO(A0),IOSWTO(A1) 9CHGD026ƒLSR.W‚#1,D0ŽIf�he's�not�changing�the�READ�TIMEOUT$ŠBCS.S‚CHGD028Œvalue,�give�him�ours.ŠMOVE.L�IOSRTO(A0),IOSRTO(A1) O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83F*CHGD028ƒBTSTW‚#DATPRT,DCBATT(A4)ƒIf�the�device�is�a�terminal,�processCCHGD028„BTSTM‚DATPRT,DCBATT,A4‚If�the�device�is�a�terminal,�process *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<2ŠBEQ.S‚CHGD031Œthe�terminal�specific�configuration *£parameters.ŠSPC„24ŠLSR.W‚#1,D0�If�the�user�is�not�changing�the�Logical7ŠBCS.S‚CHGD029ŽRecord�length,�copy�the�current�default.ŠMOVE.W�IOSLRL(A0),IOSLRL(A1) 7CHGD029ƒLSR.W‚#1,D0�If�the�user�is�not�changing�the�EOL3ŠBCS.S‚CHGD030ŒCHARACTER,�copy�the�current�default.ŠMOVE.B�IOSELC(A0),IOSELC(A1)CHGD030ƒBRA.S‚OKCNFGŠSPC„2I*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FAM 11/07/846CHGD031ƒLSR.W‚#1,D0Žif�he's�changing�the�XOFF/XON�charŠBCS.S‚CHGD031A‹give�him�oursŠMOVE.B�IOSXOF(A0),IOSXOF(A1)ŠMOVE.B�IOSXON(A0),IOSXON(A1)?CHGD031A‚LSR.W‚#1,D0Žif�he's�changing�the�BREAK�EQUIVALENT�charŠBCS.S‚CHGD031B‹give�him�oursŠMOVE.B�IOSBRC(A0),IOSBRC(A1)=CHGD031B‚LSR.W‚#1,D0Žif�he's�changing�the�DISCARD�OUTPUT�charŠBCS.S‚CHGD031C‹give�him�oursŠMOVE.B�IOSDOP(A0),IOSDOP(A1)*;CHGD031C‚LSR.W‚#1,D0Žif�he's�changing�the�REPRINT�LINE�charŠBCS.S‚CHGD031D‹give�him�oursŠMOVE.B�IOSRLN(A0),IOSRLN(A1)*:CHGD031D‚LSR.W‚#1,D0Žif�he's�changing�the�CANCEL�LINE�charŠBCS.S‚CHGD031E‹give�him�oursŠMOVE.B�IOSCLC(A0),IOSCLC(A1)*:CHGD031E‚LSR.W‚#1,D0Žif�he's�changing�the�READ�TERMINATORSŠBCS.S‚CHGD031F‹give�him�oursŠMOVE.L�IOSRTV(A0),IOSRTV(A1)*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>FAM 11/07/84*7CHGD032ƒLSR.W‚#1,D0ŽIf�he's�not�changing�the�BAUD�RATE,ŠBCS.S‚CHGD034Œgive�him�ours.ŠMOVE.B�IOSBRT(A0),IOSBRT(A1) 9CHGD034ƒLSR.W‚#1,D0ŽIf�he's�not�changing�the�NUL�PADDING,ŠBCS.S‚CHGD036Œgive�him�ours.ŠMOVE.B�IOSNLS(A0),IOSNLS(A1) 7CHGD036ƒLSR.W‚#2,D0Žthe�TERMINATOR-CLASS�doesn't�apply.6ŠBCS.S‚OKCNFG�If�the�user�is�not�changing�the�TERMINAL<ŠMOVE.B�IOSTCD(A0),IOSTCD(A1)�CODE,�copy�the�current�default )*£Currently�there�are�no�error�checks�for)*§MCCM�serial�parallel�ports,�so�go�ahead"*§with�the�proposed�configuration. * OKCNFG:*J*‚It�passed�all�the�tests,�so�move�it�to�the�real�thing�(either�the�DCB�orH*‚or�the�CCB).‚Don't�move�the�masks,�though;�start�with�ATTRIBUTES�WORD.*ŠSPC„2BŠMOVE.L�IOSDST(A0),IOSDST(A1)‚Copy�the�device,�driver,�and�channel3ŠCLR.B‚IOSDST(A1)‹codes�from�the�DCB�into�the�users'*¥configuration�block.�Clear�the�status(*¥field�for�lack�of�current�information.ŠSPC„22ŠBSR.S‚CNFGLEN�Load�D5�with�the�number�of�bytes�to<ŠSUB.W‚#IOSATW+1,D5ˆtransfer-1�and�load�the�addresses�of�the8ŠADD.L‚#IOSATW,A0ŠATTRIBUTES�WORD�in�A0�for�the�CCB/DCB,:ŠADD.L‚#IOSATW,A1Šand�in�A1�for�the�users�configure�block.ŠSPC„2FCNFGLOOP‚MOVE.B�(A1)+,(A0)+‰Copy�the�users�coniguration�block�into�theŠDBRAƒD5,CNFGLOOPˆCCB/DCB. :ŠMOVE.B�#1,DCBCCF(A4)†Set�configuration�coordination�flag. ŠCLR.L‚D1‘*1ŠBRA„ABORT�good�status�but�use�the�ABORT�routine. *0*‚Configuration�error!‚Set�D1�to�indicate�error.*BADCNFG: :ŠMOVE.B‚#ISTACNF,D1‰Return�the�configuration�error�code�in?ŠMOVE.B�D2,IOSCEC(A1)†the�users�configure�data�block�and�return(ŠBRA…ABORTŒa�configuration�error�to�IOS.ŠPAGEL*****************************************************************************%*‰GET�CONFIGURATION�DATA�BLOCK�LENGTH**‚Entry�:�A4�=�Address�of�DCB*ŠA5�=�Address�of�CCB*B*‚Exit�:‚D5�=�Configuration�data�block�length�for�requested�device*L**************************************************************************** CNFGLEN:8ŠMOVE.L�#IOSDLN,D5ŒLoad�D5.L�with�the�configuration�dataAŠCMP.B‚#XTDIPC,CCBTYPE(A5)�block�length�for�the�disk,�printer,�or2ŠBEQ.S‚CNFGLENRŒterminal�based�on�the�device�type.ŠSPC„2ŠMOVE.L�#IOSPLN,D5O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83*‰BTSTW‚#DATPRT,DCBATT(A4)ŠBTSTM‚DATPRT,DCBATT,A4 *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ŠBNE.S‚CNFGLENRŠSPC„2ŠMOVE.L�#IOSTLN,D5ŠSPC„2 CNFGLENR‚RTSŠPAGEL*****************************************************************************2*‰GET�MASKS�OF�SUPPORTED�ATTRIBUTES�AND�PARAMETERS**†Entry�:�A4�=�Address�of�DCB*ŽA5�=�Address�of�CCB*>*†Exit‚:�D0.W�=�Supported�attributes�mask�for�requested�device7*ŽD1.W�=�Supported�parameters�mask�for�requested�device*L**************************************************************************** VALATPRM:.ŠMOVE.W�#0,D0‘If�the�device�is�a�disk�IPC,�the7ŠMOVE.W�#0,D1�supported�attributes�and�parameters�masksAŠCMP.B‚#XTDIPC,CCBTYPE(A5)�are�both�zero�because�configuration�is,ŠBEQ.S‚VALATRTNŒnot�supported�on�the�device.ŠSPC„2<ŠMOVE.W�#PRTATM,D0‹If�the�device�is�a�printer�or�a�terminal,<ŠMOVE.W�#PRTPRM,D1‰load�the�appropriate�supported�attributesO*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83?*‰BTSTW‚#DATPRT,DCBATT(A4)�and�parameters�masks�for�the�device.<ŠBTSTM‚DATPRT,DCBATT,A4�and�parameters�masks�for�the�device. *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ŠBNE.S‚VALATRTNŠSPC„2ŠMOVE.W�#TERATM,D0ŠMOVE.W�#TERPRM,D1ŠSPC„2 VALATRTN‚RTSŠPAGEL******************************************************************************‰READ�COMMAND*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*L*****************************************************************************READ:5ŠBSR„IOSCOMNŒDo�the�stuff�common�to�all�I/O�commands,7ŠMOVE.L�D6,CCBPTR(A5)†save�the�buffer�physical�address. ŠCLR.L‚D6&ŠBSETƒ#LUFXFR,D6ŒSET�DATA�TRANSFER�BITŠBSETƒ#LUFACT,D6ŒSET�ACTIVE�BIT%ŠCMP.B‚#XTDIPC,CCBTYPE(A5)ƒDISK�IPC�?ŠBNE.S‚READ10�BRANCH�IF�NO$ŠBSR„DSKPRM�YES,�VALIDATE�PARAMETERS+READ10„BSR„DEVTBL�SET�UP�DEVICE�TABLE�ENTRY /ŠBSR„SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM. %ŠCMP.B„#XTDIPC,CCBTYPE(A5)�DISK�IPC�?ŠBNE.S„READ20ŽBRANCH�IF�NO ŠMOVE.Wƒ#XRE AD,D1&ŠBSR†DSKCMDŽYES,�SET�UP�COMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UP 1READ20„BTSTW„#IOPFORB,IOSOPT(A3)�FORMATTED�MODE�?ŠBNE.S„READ30ŽNO4ŠMOVE.Wƒ#XINF,D1ŒYES,�SET�UP�READ�FORMATTED�COMMANDS ŠBRA.S„READ401READ30„MOVE.Wƒ#XINI,D1ŒSET�UP�READ�IMAGE�COMMANDSREAD40„CLR.L„D0+ŠBTSTW„#IOPECHB,IOSOPT(A3)�ECHO�SPECIFIED�?ŠBEQ.S„READ50ŽYES+ŠOR.L…#XPKCECH,D0‰NO,�SET�UP�NO�ECHO�OPTIONN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<< READ50„EQU†*2ŠBTSTW„#IOPCTAB,IOSOPT(A3)�FLUSH�TYPE�AHEAD�BUFFERŠBEQ.S„READ60ŽNO0ŠOR.L…#XPKCTAB,D0‰NO,�SET�UP�FLUSH�BUFFER�OPTION READ60„EQU†* *ºFAM�7/04/84N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>"ŠBSR†MCCMCMD�SET�UP�COMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEL******************************************************************************‰WRITE**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory**L*****************************************************************************WRITE:5ŠBSR„IOSCOMNŒDo�the�stuff�common�to�all�I/O�commands,7ŠMOVE.L�D6,CCBPTR(A5)†save�the�buffer�physical�address. ŠCLR.L‚D6&ŠBSETƒ#LUFXFR,D6ŒSET�DATA�TRANSFER�BITŠBSETƒ#LUFACT,D6ŒSET�ACTIVE�BIT%ŠCMP.B‚#XTDIPC,CCBTYPE(A5)ƒDISK�IPC�?ŠBNE.S‚WRIT10�BRANCH�IF�NO$ŠBSR„DSKPRM�YES,�VALIDATE�PARAMETERS+WRIT10„BSR„DEVTBL�SET�UP�DEVICE�TABLE�ENTRY /ŠBSR„SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM. %ŠCMP.B„#XTDIPC,CCBTYPE(A5)�DISK�IPC�?ŠBNE.S„WRIT50ŽBRANCH�IF�NO O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83A*WRIT20„BTSTW„#DATWRC,DCBATT(A0)‚WRITE�WITH�VERIFY�FOR�THIS�DCB�?>WRIT20…BTSTM„DATWRC,DCBATT,A0‚WRITE�WITH�VERIFY�FOR�THIS�DCB�? *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ŠBEQ.S„WRIT30ŽNO4ŠMOVE.Wƒ#XWRITC,D1ŠYES,�SET�UP�WRITE/VERIFY�COMMANDS ŠBRA.S„WRIT408WRIT30„MOVE.Wƒ#XWRITN,D1ŠSET�UP�WRITE/NO�VERIFY�COMMANDS 'WRIT40„BSR†DSKCMDŽSET�UP�COMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UP 1WRIT50„BTSTW„#IOPFORB,IOSOPT(A3)�FORMATTED�MODE�?ŠBNE.S„WRIT60ŽNO6ŠMOVE.Wƒ#XOUTF,D1‹YES,�SET�UP�WRITE�FORMATTED�COMMANDS ŠBRA.S„WRIT703WRIT60„MOVE.Wƒ#XOUTI,D1‹SET�UP�WRITE�IMAGE�COMMANDSWRIT70„CLR.L„D0O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/832*‰BTSTW„#DATPRT,DCBATT(A0)‚THIS�A�PRINTER�DEVICE�?/ŠBTSTM„DATPRT,DCBATT,A0‚THIS�A�PRINTER�DEVICE�? *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ŠBEQ.S„WRIT80ŽNO3ŠTST.B„DCBBCT(A0)ŠFIRST�WRITE�FOR�THIS�ASSIGNMENT�?$ŠBNE.S„WRIT80ŽNO,�NO�NEED�TO�DO�A�FF.ŠOR.L…#XSWFF,D0‹YES,�SET�UP�TOP�OF�PAGE�OPTION-ŠADD.B„#1,DCBBCT(A0)‡NOW�SET�TOP�OF�PAGE�FLAG)WRIT80„BSR†MCCMCMD�SET�UP�COMMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEL*****************************************************************************%*‰OUTPUT�W/�INPUT‚(MCCM�COMMAND�ONLY)**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory**L*****************************************************************************OUTWINP:*'*‚First�take�care�of�the�WRITE�portion.*5ŠBSR„IOSCOMNŒDo�the�stuff�common�to�all�I/O�commands,8ŠMOVE.L�D6,CCBPTR(A5)†store�the�buffer�physical�address.*$*‚Now�take�care�of�the�READ�portion.*?ŠMOVE.L�IOSRRN(A3),D6†D6�<--�logical�start�addr�of�read�buffer.<ŠMOVE.L�IOSLEN(A3),D5†D5�<--�length�of�read�buffer�in�bytes./ŠMOVE.L�D5,CCBLEN1(A5)…Save�the�buffer�length�&&ŠBSR„BUFADDRŒget�the�physical�address,8ŠMOVE.L�D6,CCBPTR1(A5)…save�the�buffer�physical�address. ŠCLR.L‚D6&ŠBSETƒ#LUFXFR,D6ŒSET�DATA�TRANSFER�BITŠBSETƒ#LUFACT,D6ŒSET�ACTIVE�BIT%ŠBSR„DEVTBL�SET� UP�DEVICE�TABLE�ENTRY /ŠBSR„SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM. 3OUTW10„BTSTW„#IOPFORB,IOSOPT(A3)‚OUTPUT�FORMATTED�?ŠBNE.S„OUTW30ŽNO,ŠBTSTW„#IOPINFB,IOSOPT(A3)�INPUT�FORMATTED�?ŠBNE.S„OUTW20ŽNO8ŠMOVE.Wƒ#XOFIF,D1‹SET�UP�OUTPUT�FRMT/INPUT�FRMT�COMMANDS ŠBRA.S„OUTW50?OUTW20„MOVE.Wƒ#XOFIM,D1‹SET�UP�OUTPUT�FRMT/INPUT�IMAGE�COMMANDS ŠBRA.S„OUTW502OUTW30„BTSTW„#IOPINFB,IOSOPT(A3)‚INPUT�FORMATTED�?ŠBNE.S„OUTW40ŽNO5ŠMOVE.Wƒ#XOIIF,D1‹SET�UP�OUTPUT�IMAGE/INPUT�FRMT�CMDS ŠBRA.S„OUTW50>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<< OUTW60„EQU†*4ŠBTSTW„#IOPCTAB,IOSOPT(A3)�FLUSH�TYPE�AHEAD�BUFFER�?ŠBEQ.S„OUTW70ŽNO,ŠOR.L…#XPKCTAB,D0‰SET�UP�FLUSH�BUFFER�OPTIONN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>> OUTW70„EQU†*-ŠMOVEP.L‚D0,IPCSWCF(A1)†SET�UP�PACKET�OPTIONS ŠMOVE.Lƒ#1,D11ŠMOVEP.W‚D1,IPCNBKS(A1)†SET�UP�BLOCKS�TO�TRANSFERŠMOVE.LƒCCBLEN(A5),D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZEŠMOVE.LƒCCBPTR(A5),D1.ŠMOVEP.L‚D1,IPCBUFAD(A1)…SET�UP�BUFFER�ADDRESS ŠCLR.L„D1'ŠMOVEP.W‚D1,IPCCKSM(A1)†SET�UP�CHECKSUM ŠMOVE.Lƒ#1,D1,ŠMOVEP.W‚D1,IPCNBKS2(A1)…SET�UP�INPUT�BLOCKSŠMOVE.LƒCCBLEN1(A5),D10ŠMOVEP.W‚D1,IPCBKSZ2(A1)…SET�UP�INPUT�BLOCK�SIZEŠMOVE.LƒCCBPTR1(A5),D14ŠMOVEP.L‚D1,IPCBUFA2(A1)…SET�UP�INPUT�BUFFER�ADDRESS#ŠMOVE.Bƒ#ETX,IPCETX2(A1)„SET�UP�ETX/ŠMOVE.Bƒ#OWIPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE ŠBRA†NRMEXITŠPAGEH*************************************************************************)*ˆFORMAT�DISK�COMMAND‚(DISK�COMMAND�ONLY)*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory**I**************************************************************************FORMAT: )‰BTSTWƒ#IOPFTRK,IOSOPT(A3)‚FORMAT�TRACK�?‰BEQ.SƒFORMT20ŽBRANCH�IF�NO !‰MOVE.L‚IOSRRN(A3),D1‰PICK�UP�RRN$‰BMI.SƒFORMT10�ERROR,�NEGATIVE�VALUE%‰CMP.LƒDCBSEC(A4),D1‰IS�RRN�TOO�BIG�?&‰BLT.SƒFORMT20�NO,�VALIDATION�COMPLETE/FORMT10‚MOVE.B‚#ISTARR,D1ŒSET�UP�IOS�ERROR�CODE ‰BRA…ABORT FORMT20‚CLR.LƒD6‰BSET„#LUFACT,D6ŒSET�ACTIVE�BIT%‰BSR…DEVTBL�SET�UP�DEVICE�TABLE�ENTRY /‰BSR…SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM. 0FORMT30ƒBTSTW„#IOPFTRK,IOSOPT(A3)‚FORMAT�TRACK�?ŠBNE.S„FORMT40�YESŠMOVE.Wƒ#XFDISK,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDS#ŠMOVE.Bƒ#ETX,IPCDETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#FDPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZEŠBRA†NRMEXIT�GO�FINISH�UP FORMT40ƒMOVE.Wƒ#XFTRAK,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDSŠMOVE.Wƒ#SECSIZ,D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZE ŠCLR.L„D1*ŠMOVEP.W‚D1,IPCNBKS(A1)†ZERO�NO.�OF�BLOCKSŠMOVE.LƒIOSRRN(A3),D1"ŠMOVEP.L‚D1,IPCFPSN(A1)†SET�UP�PSN#ŠMOVE.Bƒ#ETX,IPCFETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#FTPKSZ,IPCPKSZ(A1)…SET�UP�PACKET�SIZEŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEH**************************************************************************‰HALT�I/O‚(MCCM�COMMAND�ONLY)*3*‰This�command�stops�the�I/O�currently�in�progress.**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**J***************************************************************************HALT: ŠCLR.L„D0+ŠMOVE.BƒDCBCDV(A4),D0‡PICK�UP�DEVICE�NUMBER&ŠCMP.B„#LUMAX,D0‹VALID�DEVICE�NUMBER�?'ŠBSRGT„KILR�NO,�BRING�DOWN�THE�SYSTEM�!,ŠMULU…#LUDSZE,D0ŠCALCULATE�POSITION�IN�TABLE2ŠMOVE.LƒCCBDTBL(A5),A1†SET�UP�DEVICE�TABLE�POINTERŠINHIBŠTST.W„LUFLG(A1,D0.L)ˆACTIVE�?ŠBEQ†HALTERŽNO,�ERROR3ŠBSETW„#LUFHLT,LUFLG(A1,D0.L)�SET�HALT�PENDING�FLAGŠENABL /ŠBSR†SETPKTŽSET�UP�PACKET� HEADER�IN�SHARED�MEM. ŠMOVE.Wƒ#XHALT,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDS#ŠMOVE.Bƒ#ETX,IPCRETX(A1)„SET�UP�ETX/ŠMOVE.Bƒ#HLTPKSZ,IPCPKSZ(A1)†SET�UP�PACKET�SIZE ŠBRA†NRMEXITŠPAGEH**************************************************************************‰TRANSMIT�BREAK�REQUEST*<*‰This�command�sends�the�break�request�to�the�LUN�specified.**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**J***************************************************************************TBREAK: ŠCLR.L„D6-ŠBSET…#LUFACT,D6ŒSET�ACTIVE�DEVICE�TABLE�FLAG%ŠBSR†DEVTBL�SET�UP�DEVICE�TABLE�ENTRY*,ŠBSR†SETPKT�SET�UP�PACKET�HDR�IN�SHARED�MEM.ŠMOVE.Wƒ#XTRNSBK,D16ŠMOVEP.W‚D1,IPCCHCM(A1)ˆSET�UP�CHANNEL/DEVICE�COMMANDS#ŠMOVE.Bƒ#ETX,IPCRETX(A1)†SET�UP�ETX/ŠMOVE.Bƒ#TBKPKSZ,IPCPKSZ(A1)‚SET�UP�PACKET�SIZE ŠBRA†NRMEXITŠPAGEL*****************************************************************************C*‰ROUTINE�COMMON�TO�ALL�I/O�COMMANDS�(READ,�WRITE,�OUTPUT�W/�INPUT)**‚Entry:�A3�=�address�of�IOCB*‰A5�=�address�of�CCB**‚Exit:‚(normal)*‰D6�=�physical�addr�of�buffer**‚Exit:‚(abort)*‰D1�=�error�status**L*****************************************************************************IOSCOMN:?ŠBTSTW‚#IOPTSKB,IOSOPT(A3)�If�the�buffers�reside�in�a�different"ŠBEQ.S‚IOSC005Œtask�from�the�IOCB, 9ŠLEA„IOSTSK(A3),A0†Point�to�the�taskname�&�session�of�the7ŠTR0$.GETTCB‚,Œbuffer�owner�&�call�exec�to�get�address."ŠBRA.S‚OKTCBŽIf�it's�good,�branch.ŠNOP—If�it's�bad,7ŠMOVE.B�#ISTAADD,D1ˆset�status�in�IOCB�to�address�errorŠTST.L‚(A7)+Žadjust�stackŠBRA„ABORT�and�exit�to�CMR. :OKTCB…MOVE.L�A0,CCBTASKB(A5)„Save�physical�address�of�TCB. *<*‚Validate�the�info�in�the�IOCB�about�the�primary�buffer�and *‚convert�to�physical�addresses.*BIOSC005ƒMOVE.L�IOSSAD(A3),D6†D6�<--�buffer�physical�start�address.+ŠMOVE.L�IOSEAD(A3),D5†D5�<--�buffer�length.ŠSUB.L‚D6,D5Ž*ŠADDQ.L�#1,D5Ž*)ŠMOVE.L�D5,CCBLEN(A5)†Save�length�in�CCB. >ŠMOVE.L�CCBTASKB(A5),A1„A1�<--�address�of�TCB�of�buffer�owner. ŠBSR„IOHADRCK‹Check�the�address.$ŠBRA.S‚IOSC010ŒIf�it's�good,�branch.ŠNOP—If�it's�a�bad�base�addrŠTST.L‚(A7)+Žadjust�stack4ŠMOVE.B�#ISTAADD,D1ˆSet�IOCB�status�to�ADDRESS�ERROR2ŠBRA„ABORT�and�exit�with�appropriate�error�status. IOSC010ƒEQU„*N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<< ŠGO_OFF_BD�D6N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>ŠRTSŠPAGEK****************************************************************************/*‰VALIDATE�BUFFER�ADDRESS�&�CONVERT�TO�PHYSICAL*$*‰Entry:�D5�=�buffer�length�in�bytes-*�D6�=�buffer�logical�start�addr�(to�convert)*�A3�=�address�of�IOCB*�A5�=�address�of�CCB***‰Exit:‚D6ƒ=�buffer�physical�start�address*�D5ƒ=�buffer�length*K****************************************************************************BUFADDR:>ŠMOVE.L�CCBTASKB(A5),A1„A1�<--�address�of�TCB�of�buffer�owner. ŠBSR„IOHADRCK‹Check�the�address.$ŠBRA.S‚OKADDR2ŒIf�it's�good,�branch.ŠNOP—If�it's�a�bad�base�addrŠTST.L‚(A7)+Žadjust�stack4ŠMOVE.B�#ISTAADD,D1ˆSet�IOCB�status�to�ADDRESS�ERROR2ŠBRA„ABORT�and�exit�with�appropriate�error�status.OKADDR2ƒEQU„*’Return.*N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<< ŠGO_OFF_BD‚D6N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>ŠRTSŠPAGEO*********************************************************************************ˆCHECK�DISK�PARAMETERS**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**O********************************************************************************DSKPRM:%‰MOVE.W‚IOSOPT(A3),D1‰PICK�UP�OPTIONS+‰AND.Wƒ#IOPRAN,D1ŒRANDOM�OPTION�SPECIFIED�?‰BNE.SƒDSK PR10�YES(‰MOVE.B‚#ISTATM,D1ŒSET�UP�IOS�ERROR�CODE‰BRA.SƒDSKPR25�ERROR�EXIT(DSKPR10‚MOVE.L‚IOSRRN(A3),D1‰PICK�UP�RRN‰BPL.SƒDSKPR30�GOOD�RRN/DSKPR20‚MOVE.B‚#ISTARR,D1ŒSET�UP�IOS�ERROR�CODE DSKPR25‚TST.Lƒ(A7)+‘ADJUST�STACK‰BRA…ABORT�ERROR�EXITŠSPC„2ADSKPR30ƒCMP.LƒDCBSEC(A4),D1‡If�the�random�record�number�specified7ŠBLT.SƒDSKPR35‹in�the�IOCB�is�past�the�end�of�the�disk,1ŠMOVE.B�#ISTARR,D1‰return�an�end-of-volume�error.ŠBRA.S‚DSKPR25ŠSPC„22DSKPR35‚MOVE.L‚CCBLEN(A5),D1‰PICK�UP�BUFFER�LENGTH"‰DIVS„#256,D1�CALC.�NO.�OF�SECTORS ‰MOVE.L‚D1,D2*‰AND.Lƒ#$FFFF0000,D2‰MUST�BE�WHOLE�SECTORS‰BEQ.SƒDSKPR40�ITS�OK5‰MOVE.B‚#ISTAADD,D1‹ERROR,�PARTIAL�SECTOR�NOT�ALLOWED‰BRA…DSKPR25�ERROR�EXIT1DSKPR40‚MOVE.W‚D1,CCBBLKS(A5)ˆSAVE�NO.�OF�SECTORS2‰ADD.LƒIOSRRN(A3),D1‰CALC.�LAST�SECTOR�TO�TRANSFER‰CMP.LƒDCBSEC(A4),D1‰RANGE�OK�?‰BLE.SƒDSKPR50�YES4‰MOVE.L‚DCBSEC(A4),D1‰NO,�CALC.�MAX�SECTORS�CAN�READ‰SUB.LƒIOSRRN(A3),D1/‰MOVE.W‚D1,CCBBLKS(A5)ˆSAVE�SECTORS�TO�TRANSFER ‰BSET„#LUFEOF,D6ŒSET�EOF�PENDINGDSKPR50‚RTS›RETURN‰PAGEO********************************************************************************** SET UP DEVICE TABLE ENTRY**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D6�=�device�table�flag*N*******************************************************************************DEVTBL: ŠCLR.L‚D0(ŠMOVE.B�DCBCDV(A4),D0‰PICK�UP�DEVICE�NO. ŠCMP.B‚#LUMAX,D0�DEVICE�NO.�OK�?'ŠBSRGT‚KILR’NO,�BRING�THE�SYSTEM�DOWN�!ŠMULUƒ#LUDSZE,D0ŒCALC.�POSITION3ŠMOVE.L�CCBDTBL(A5),A0ˆPICK�UP�DEVICE�TABLE�POINTER(ŠTST.W‚LUFLG(A0,D0.L)ŠTHIS�DEVICE�FREE�?ŠBEQ.S‚DEVT010�YESŠTST.L‚(A7)+‘ADJUST�STACK+ŠMOVE.B�#ISTADB,D1ŒRETURN�DEVICE�BUSY�ERRORŠBRA„ABORT�ERROR�EXIT2DEVT010ƒMOVE.W�D6,LUFLG(A0,D0.L)‡UPDATE�TABLE�FLAG,ŠMOVE.L�A4,LUDCB(A0,D0.L)‡SET�UP�DCB�ADDRESS.ŠMOVE.L�A3,LUIOCB(A0,D0.L)†SET�UP�IOCB�ADDRESS6ŠMOVE.L�CCBTASKB(A5),LUTCB(A0,D0.L)�SET�UP�TCB�ADDRESS8ŠMOVE.L�CCBPTR(A5),LUBADR(A0,D0.L)�SET�UP�BUFFER�ADDRESS ŠRTSšRETURNŠPAGEJ***************************************************************************%*ˆSET�UP�PACKET�HEADER�IN�SHARED�MEM.**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB*,*‰Return�:�A1�=�address�of�IPC�shared�memory**I**************************************************************************SETPKT:%ŠMOVE.LƒCCBCHB(A5),A1‡MEM�MAPPED�ADDR)ŠLEA†IPCIM1(A1),A1‡SET�UP�MESSAGE�ADDRESSŠMOVE.Wƒ#SPKT,D1/ŠMOVEP.W‚D1,IPCSTX(A1)‡SET�UP�STX�AND�PACKET�ID%ŠMOVE.LƒXIOUID(A2),A0‡GET�DCB�ADDRESS0ŠMOVE.BƒDCBCDV(A0),IPCPHDV(A1)‚SET�UP�DEVICE�NO. ŠRTSšRETURNŠPAGEJ***************************************************************************)*‰SET�UP�DISK�PARAMETERS�IN�SHARED�MEMORY*&*‚Entry:�A1�=�address�of�SHARED�MEMORY%*‰A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D1�=�CHANNEL/DEVICE�commands*K****************************************************************************DSKCMD:6ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDSŠMOVE.WƒCCBBLKS(A5),D18ŠMOVEP.W‚D1,IPCNBKS(A1)†SET�UP�NO.�OF�BLOCKS�TO�TRANSFERŠMOVE.Wƒ#SECSIZ,D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZEŠMOVE.LƒCCBPTR(A5),D1.ŠMOVEP.L‚D1,IPCBUFAD(A1)…SET�UP�BUFFER�ADDRESS ŠCLR.L„D1'ŠMOVEP.W‚D1,IPCCKSM(A1)†SET�UP�CHECKSUMŠMOVE.LƒIOSRRN(A3),D1#ŠMOVEP.L‚D1,IPCCMPRM(A1)…SET�UP�PSN"ŠMOVE.Bƒ#ETX,IPCETX(A1)…SET�UP�ETX.ŠMOVE.Bƒ#IOPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE ŠRTSšRETURNŠPAGEJ***************************************************************************)*ˆSET�UP�MCCM�PARAMETERS�IN�SHARED�MEMORY**&*‚Entry:�A1�=�address�of�SHARED�MEMORY%*‰A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of� DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D0�=�options*‰D1�=�channel/device�commands**L*****************************************************************************MCCMCMD:6ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDS&ŠMOVEP.L‚D0,IPCSWCF(A1)†SET�UP�OPTIONS ŠMOVE.Lƒ#1,D18ŠMOVEP.W‚D1,IPCNBKS(A1)†SET�UP�NO.�OF�BLOCKS�TO�TRANSFERŠMOVE.LƒCCBLEN(A5),D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZEŠMOVE.LƒCCBPTR(A5),D1.ŠMOVEP.L‚D1,IPCBUFAD(A1)…SET�UP�BUFFER�ADDRESS ŠCLR.L„D1'ŠMOVEP.W‚D1,IPCCKSM(A1)†SET�UP�CHECKSUM"ŠMOVE.Bƒ#ETX,IPCETX(A1)…SET�UP�ETX.ŠMOVE.Bƒ#IOPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE ŠRTSšRETURNŠPAGEO******************************************************************************** *ˆNORMAL�EXIT*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB*I**************************************************************************NRMEXIT:*/* INDICATE AWAITING ACK, BUMP I/O PENDING COUNT*'ŠBSETW‚#CCBFGWAK,CCBFG(A5)ƒSET�CCB�FLAGŠMOVE.L�CCBTASKB(A5),A0-ŠADD.B‚#1,TCBIOCNT(A0)„BUMP�I/O�PENDING�COUNT** INTERRUPT THE IPC*0ŠMOVE.L�CCBCHB(A5),A1†SET�UP�SHARED�MEM.�POINTER(ŠMOVE.B�#$80,IPCIMB1(A1)ƒMESSAGE�WAITING0ŠADD.B‚#2,CCBICNT(A5)…BUMP�OUTSTANDING�INT�COUNT%ŠMOVE.B�#$80,IPCINT(A1)„INTERRUPT�IPC#ŠCLR.L‚D0‘SET�UP�GOOD�RETURN�TO�CMR*7* USER REQUEST SIDE OF IPC ALWAYS EXITS FROM THIS POINT*IPCUSRTN‚EQU„*ŠRTS—RETURN�TO�MAINLINEŠPAGEJ****************************************************************************ˆKILR�(KILLER)*3*“ROUTINE�CALLED�TO�HANDLE�UNRECOVERAVLE�CONDITIONS**Î ·IÀPÈJÐ5ØHàAè@ðJø:<;@8 :(N0H8@@CH;PBXH`'K****************************************************************************KILR: ‰TR0$.KILLER     J*****************************************************************************‚NOTHING�TO�HALT�ERROR�ROUTINE*%*’ENTRY:�A2�=�PARAMETER�BLOCK�ADDRESS*™A3�=�IOCB�PACKET�ADDRESS*™A4�=�ADDRESS�OF�DCB*™A5�=�ADDRESS�OF�CCB*™A6�=�ADDRESS�OF�CALLERS�TCB*H************************************************************************* HALTER:‚ENABL)‰LEA‡CCBPKT(A5),A4‡SET�UP�QUEUE�WORK�AREA ‰MOVE.L„#6,D0�SET�UP�PACKET�SIZE$‰MOVE.B„#XPSHLT,D1ŠSET�UP�EVENT�TYPE"‰MOVE.L„XIOUID(A2),D2‡SET�UP�PB�ID'‰MOVE.W„#XSTVABT,D3ŠSET�UP�STATUS�VALUE‰BSR‡QEVNT�GO�QUEUE�EVENT ‰CLR.L…D0‰BRA‡IPCUSRTNŒRETURN‰PAGEJ*****************************************************************************ˆABORT�COMMAND�ROUTINE*%*’ENTRY:�A2�=�PARAMETER�BLOCK�ADDRESS*™A3�=�IOCB�PACKET�ADDRESS*™A4�=�ADDRESS�OF�DCB*™A5�=�ADDRESS�OF�CCB*™A6�=�ADDRESS�OF�CALLERS�TCB*™D1�=�IOS�ERROR�CODE*H*************************************************************************ABORT:)‰LEA‡CCBPKT(A5),A4‡SET�UP�QUEUE�WORK�AREA ‰MOVE.L„#6,D0�SET�UP�PACKET�SIZE"‰MOVE.L„XIOUID(A2),D2‡SET�UP�PB�ID‰AND.W…#$FF,D1!‰MOVE.W„D1,D3�SET�UP�STATUS�VALUE!‰MOVE.B„D1,IOSSTA(A3)‡UPDATE�IOCB$‰MOVE.B„#XPSNRM,D1ŠSET�UP�EVENT�TYPE‰BSR‡QEVNT�GO�QUEUE�EVENT ‰CLR.L…D0‰BRA‡IPCUSRTNŒRETURNŠPAGEF***********************************************************************B* SUBROUTINE TO CHECK ADDRESS BOUNDARIES TO SEE IF ENTIRELY WITHIN*ƒCALLING�TASKS�ADDRESS�SPACE.*#*�ENTRY:ƒD5‚-�NO.�OF�BYTES�TO�CHECK*ŠD6‚-�68000�ADDRESS�(LOGICAL)*ŠA1‚-�TCB�ADDRESS** EXEC ROUTINE#* REGISTERS USED: D0-D1,D3,D6/A0-A1**7*�EXIT:„D6�-�PHYSICAL�ADDRESS�OF�BUFFER�BASE�(IF�LEGAL)*ŠRETURN�TO�PC„FOR�GOOD�ADDRESS*”PC+2‚FOR�BAD�LENGTH*”PC+4‚FOR�BAD�ADDRESS*F*********************************************************************** IOHADRCK:$ŠBTSTƒ#0,D6ŽMUST�BE�ON�WORD�BOUNDARY (ŠBNE.S‚IOHADR6ŒBRANCH�IF�BAD�BUFFER�BASE ŠTST.L‚D5.ŠBEQ.S‚IOHADR8ŒDON'T�GO�TO�LOGPHY�WITH�0�COUNT IOHADR2ƒEQU„*/ŠMOVE.L�TCBTST(A1),A0†ADDRESS�OF�TASK�SEG�TABLE ŠTR0$.LOGPHY&ŠBRA.S‚IOHADR8ŒBRANCH�FOR�GOOD�ADDRESSŠNOP—FOR�PART�IN/PART�OUT�ERROR-IOHADR6ƒADD.L‚#2,(A7)ŒADJUST�FOR�ERROR�RETURN IOHADR8ƒRTSŠPAGEI***************************************************************************ˆGET�TCB�ROUTINE*)*’ENTRY:�A0�=�POINTER�TO�TASK�AND�SESSION***’EXEC�ROUTINE*’REGISTERS�USED:�D0-D1/A0-A1***’EXIT:�A0�=�TCB�ADRESS**˜RETURN�TO�PC„FOR�GOOD�TASK�SPECIFICATION!*¢PC+2‚FOR�BAD�TASK�SPECIFICATION**J***************************************************************************GETTCB: ŠTR0$.GETTCB%ŠBRA.S„GETT10ŽGOOD�TASK�SPECIFICATION%ŠADD.L„#2,(A7)�BAD�TASK�SPECIFICATION GETT10„RTSŠPAGEJ**************************************************************************** * SUBROUTINE TO COMPUTE CHECKSUM*&*‡ENTRY:�A1�=�PHYS�ADDR�OF�BLOCK�BEGIN,*ŽD5�=�ONE�RELATIVE�COUNT�OF�NUMBER�OF�BYTES*C*‡EXIT:‚D1�=�CHECKSUM�(SUM�OF�BYTES�WITH�WORD(16�BIT)�SIGNIFICANCE)** REGISTERS D0,D5 DESTROYED*M****************************************************************************** IPCCKSUM:!‰TR0$.KILLER‰GO�CRASH�THE�SYSTEM?*‰CLR.LƒD1‹ACCUMULATOR)*‰MOVE.L‚A1,D0ˆADDRESS�OF�BLOCK�BEGINNING'*‰BTSTW‚#24,D0ˆIS�IT�FOR�2NDARY�MEMORY?*‰BNE.SƒCKSUM2‡BRANCH�IF�YES+* CHECKSUM CALCULATION IF IN PRIMARY MEMORY*‰CLR.LƒD0‹BYTE�HOLDER*IPCCK30ƒEQU…*'*‰SUB.Lƒ#1,D5ˆBEGIN�WITH�ZERO�REL�INDEX*‰BLT.SƒIPCCK50†BRANCH�IF�DONE*‰MOVE.B‚0(A1,D5.L),D0 *‰NOT.BƒD0/*‰ADD.WƒD0,D1ˆCONTRIBUTE�THIS�BYTE�TO�CHECKSUUM*‰BRA…IPCCK30†GO�FOR�ANOTHER IPCCK50ƒEQU„**‰RTS…0ŒBACK�TO�MAINLINE** CHECKSUM CALCULATION IF IN 2NDARY MEMORY CKSUM2„EQU„*!*‰TR0$.KILLERˆGO�CRASH�THE�SYSTEM"*‰AND.Lƒ#$00FFFFFF,D0‡CLEAR�BIT�24*‰MOVE.L‚D0,A1ˆFOR�INDEXING*‰CLR.LƒD0‹BYTE�HOLDER+*‰MOVE.W‚SR,-(A7)…SAVE�FOR�INTERRUPT�UNMASK*IPCCK80ƒEQU…*ŒLOOP�TOP,*‰SUB.Lƒ#1,D5ˆBEGIN�WITH�ZERO�RELATIVE�INDEX/*‰BLT.SƒIPCCK90†BRANCH�IF�DONE�WITH�CALCULATION"*‰MOVE.W‚#$2700,SR„MASK�INTERRUPTS!*‰MOVE.W‚#0,$FE0006ƒTOGGLE�2NDARY+*‰MOVE.B‚0(A1,D5.L),D0‡PICK�UP�NEXT�FOR�SUM*‰MOVE.W‚(A7),SR†UNMASK *‰NOT.BƒD0.*‰ADD.WƒD0,D1ˆCONTRIBUTE�THIS�BYTE�TO�CHECKSUM *‰BRA…IPCCK80(*IPCCK90‚ADD.Lƒ#2,A7‰BYPASS�SAVED�STATUS*‰BRA.SƒIPCCK50‡BACK�TO�CALLERŠPAGEI****************************************************************************‚CMR�RESET�ROUTINE*%*ˆENTRY:�A2�=�PARAMETER�BLOCK�ADDRESS*�A3�=�PACKET�ADDRESS*�A5�=�CCB�ADDRESS*�A6�=�CALLERS�TCB�ADDRESS*I**************************************************************************5* Just a note for future maintainers of this code ---*G*�The�following�reset�routine�has�never�been�invoked.‚In�practice�thereH*ƒis�no�way�for�us�to�reach�this�code�even�though�BSR�CMRREST�is�presentF*ƒin�the�code.‚If�this�code�were�ever�executed,�the�most�likely�resultC*ƒwould�be�to�lose�the�IPC�until�a�reboot�takes�place.‚When�a�resetH*ƒis�issued,�the�IPC�goes�into�a�self�test�mode�and�there�is�no�good�way@*ƒto�tell�when�it�is�done.‚The�amount�of�time�spent�in�self�testG*ƒmode�may�be�considerable.‚To�handle�the�reset�logic�in�an�intelligentD*ƒway�would�involve�significant�changes�to�the�driver�and�to�IOS.‚As6*ƒof�01/18/84,�no�such�changes�have�been�contemplated.*CMRREST:*/ŠMOVE.L�CCBCHB(A5),A4†SET�UP�SHARED�MEM�POINTER*5*‰SET�LAST�BYTE�OF�SHARED�MEMORY�AS�AN�INDICATOR�THAT*‰RESET�IS�NOT�COMPLETE*ŠMOVE.B�#$FF,IPCLST(A4)=* CLEAR ERROR MODE,WAITING FOR ACK, DEALT WITH ACK, EXIT FLAG%ŠCLR.L‚CCBNAKAD(A5)‡CLEAR�NAK�ADDRESS'ŠCLR.L‚CCBERAD1(A5)‡CLEAR�ERROR�ADDRESSŠINHIB•INHIBIT�INTERRUPTSEŠAND.W�#-1-(1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<*&*‰Check�for�Configuration�(2nd�Packet)*"ŠBTST.B�#PIDPKTF,RTNPID+IPCIM2(A4)ŠBEQ.S‚PKTC010�NO,�IPC�ERRORŠBRA„INEXIT�YES�2nd�Packet*N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<*.PKTC030ƒMOVE.L‚LUDCB(A2),A0‰SET�UP�DCB�POINTER ŠCLR.LƒD1%ŠCMP.Bƒ#XTDIPC,CCBTYPE(A5)‚DISK�IPC�? ŠBNE…MCCMPKTŽNO,�MUST�BE�AN�MCCM*‰BRA…DSKPKT�YESŠPAGEL*****************************************************************************,* HANDLE DISK NORMAL COMPLETION PACKETS HERE*+*ˆENTRY:�A2�=�address�of�device�table�entry*�A3�=�address�of�IOCB(*�A4�=�address�of�IPC�shared�memory�base*�A5�=�address�of�CCB*�D0�=�packet�status�value*O********************************************************************************DSKPKT:/ŠLEA…DERXREF(PC),A1‡SET�STATUS�CROSS�REF.�TABLE*ŠCMP.Wƒ#DERXL,D0ŒERROR�CODE�IN�THE�TABLE�?ŠBLE.SƒDSKPK10ŽBRANCH�IF�YES'ŠBSR…IPCUNSER�NO,�IPC�ERROR�-�RESET�IPCŠBRA…IPCINRTN�RETURN'DSKPK10ƒCMP.Wƒ#XPSCSM,D0‹CHECKSUM�ERRORŠBNE.SƒDSKPK20ŽBRANCH�IF�NOŠCLR.LƒD0“YES,�IGNORE�IT1DSKPK20ƒLSL.Wƒ#1,D0�TIMES�2�FOR�POSITION�IN�TABLE+ŠMOVE.B‚(A1,D0.W),D1‰PICK�UP�IOS�ERROR�CODE!ŠBNE.SƒDSKPK30ŽBRANCH�IF�AN�ERROR&ŠBTSTWƒ#LUFEOF,LUFLG(A2)„EOF�PENDING�?ŠBEQ.SƒDSKPK30ŽBRANCH�IF�NO)ŠMOVE.B‚#ISTAEOV,D1ŠSET�UP�IOS�ERROR�CODEŠBRA.SƒDSKPK505DSKPK30ƒBTST„#1,1(A1,D0.W)ˆNEED�TO�UPDATE�PSN�FIELD�?ŠBEQ.SƒDSKPK40ŽBRANCH�IF�NO:ŠMOVEP.L�RTNSTPR+IPCIM2(A4),D2‚PICK�UP�PSN�FROM�SHARED�MEM+ŠMOVE.L‚D2,IOSRRN(A3)ˆUPDATE�IOCB�RRN�FIELDDSKPK40ƒCLR.LƒD41ŠBTST„#0,1(A1,D0.W)ˆNEED�TO�UPDATE�LENGTH�FIELD�?ŠBEQ.SƒDSKPK60ŽBRANCH�IF�NODSKPK50ƒCLR.LƒD35ŠMOVEP.W�RTNBLKS+IPCIM2(A4),D3‚PICK�UP�NO.�OF�SECTORS2ŠMOVEP.W�RTNBKSZ+IPCIM2(A4),D4‚PICK�UP�SECTOR�SIZEŠMULU„D3,D4�CALC.�NO.�OF�BYTES5DSKPK60ƒMOVE.L‚D4,IOSLEN(A3)ˆUPDATE�IOCB�LENGTH�FIELD.ŠMOVE.B‚D1,IOSSTA(A3)ˆUPDATE�IOCB�STATUS�FIELD ŠBRA…INEXITŠPAGEK****************************************************************************!* HANDLE UNSOLICITED PACKETS HERE*+*ˆENTRY:�A2�=�address�of�device�table�entry*�A3�=�address�of�IOCB(*�A4�=�address�of�IPC�shared�memory�base*�A5�=�address�of�CCB*L*****************************************************************************UNSPKT:.ŠCMP.B‚#RTNUNS,RTNSTCM+IPCIM2(A4)�RIGHT�CODE�?ŠBEQ.S‚UNSP010�BRANCH�IF�YES 'ŠBSR„IPCUNSERŽNO,�IPC�ERROR�-�RESET�IPCŠBRA„IPCINRTNŽRETURN0UNSP010ƒMOVE.L�LUDCB(A2),D2ŠPICK�UP�LAST�CMD�DCB$ŠBEQ.S‚UNSP030�FIRST�ONE,�USE�CCB�ID ŠMOVE.L�D2,A0‘SET�UP�DCB�POINTER'ŠMOVE.W�#XSTVDST,D3‹SET�UP�STATUS�VALUE%ŠCMP.B‚#XTDIPC,CCBTYPE(A5)ƒDISK�IPC�?ŠBNE.S‚UNSP020�NO;ŠMOVE.B�RTNSTAD+IPCIM2(A4),D0‚GET�STATUS�FROM�SHARED�MEMORYŠMOVE.L�D0,D4‘MAKE�ANOTHER�COPY"ŠAND.W‚#$0F,D4�ISOLATE�DEVICE�BITS"ŠAND.W‚#$F0,D0�ISOLATE�STATUS�BITS$ŠLSL.W‚#8,D0‘SET�UP�BYTE�1�OF�STATUSŠOR.WƒD0,D4‘MERGE�BYTE�1�AND�2:ŠMOVEP.L�RTNLSEC+IPCIM2(A4),D0‚GET�SECTORS�FROM�SHARED�MEM-ŠMOVE.L�D0,DCBSEC(A0)‰UPDATE�DCB�WITH�SECTORS&ŠMOVE.L�#8,D0‘SET�UP�EVENT�INFO�LENGTHŠBRA.S‚UNSP040BUNSP020ƒMOVE.B�RTNSTAD+IPCIM2(A4),D0‚GET�STATUS�FROM�SHARED�MEMORYŠMOVE.L�D0,D4‘MAKE�ANOTHER�COPY"ŠAND.W‚#$0F,D4�ISOLATE�DEVICE�BITS"ŠAND.W‚#$F0,D0�ISOLATE�STATUS�BITSŠBSETƒ#XDSBRK,D0ŒSET�BREAK�BIT$ŠLSL.W‚#8,D0‘SET�UP�BYTE�1�OF�STATUSŠOR.WƒD0,D4‘MERGE�BYTE�1�AND�2&ŠMOVE.L�#8,D0‘SET�UP�EVENT�INFO�LENGTHŠBRA.S‚UNSP040  5UNSP030ƒMOVE.L�CCBMNEM(A5),D2ˆSET�UP�CHANNEL�MNEMONIC'ŠMOVE.W�#XSTVNID,D3‹SET�UP�STATUS�VALUE0ŠMOVE.B�RTNSTPR+IPCIM2(A4),D0‚PICK�UP�IPC�STATUSŠMOVE.L�D0,D4‘MAKE�ANOTHER�COPY"ŠAND.W‚#$0F,D4�ISOLATE�DEVICE�BITS"ŠAND.W‚#$F0,D0�ISOLATE�STATUS�BITS$ŠLSL.W‚#8,D0‘SET�UP�BYTE�1�OF�STATUSŠOR.WƒD0,D4‘MERGE�BYTE�1�AND�2/ŠMOVE.B�RTNPHDV+IPCIM2(A4),D5�SET�UP�DEVICE�NO.'ŠMOVE.L�#10,D0�SET�UP�EVENT�INFO�LENGTH+UNSP040ƒMOVE.B�#XPSUNS,D1ŒSET�UP�EVENT�TYPE+ŠLEA„CCBCPKT(A5),A4ˆSET�UP�EVENT�BUILD�AREA#ŠBSR„QEVNT‘QUEUE�NOTIFICATION�EVENT ŠBRA„INEX010ŠPAGEJ*************************************************************************** * HANDLE HALT/ABORT PACKET ($71)*+*ˆENTRY:�A2�=�address�of�device�table�entry*�A3�=�address�of�IOCB(*�A4�=�address�of�IPC�shared�memory�base*�A5�=�address�of�CCB*�D0�=�packet�status�value*K****************************************************************************HLTPKT:#ŠCMP.W‚#XPSICM,D0ŒINVALID�COMMAND�?ŠBNE.S‚HLTP010�BRANCH�IF�NON*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<*#*‰Configure�Command�-�second�packet*"ŠBTST.B�#PIDPKTF,RTNPID+IPCIM2(A4)ŠBNE.S‚HLTP030�YES�-�2nd�packet*N*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>0ŠBCLRW‚#LUFHLT,LUFLG(A2)…Clear�halt�pending�flag&ŠBRA„INEX020�Go�acknowledge�and�return:HLTP010ƒMOVE.B�#ISTATO,IOSSTA(A3)„UPDATE�IOCB�STATUS�FIELD*ŠCLR.L‚IOSLEN(A3)ŒUPDATE�IOCB�LENGTH�FIELD&ŠMOVE.W�#ISTATO,D3ŒSET�UP�STATUS�VALUE$ŠMOVE.B�#XPSHLT,D1ŒSET�UP�EVENT�TYPE-HLTP020ƒMOVE.L�#6,D0‘SET�UP�EVENT�INFO�LENGTH)ŠMOVE.L�LUDCB(A2),D2ŠSET�UP�DCB�FOR�EVENT+ŠLEA„CCBCPKT(A5),A4ˆSET�UP�EVENT�BUILD�AREAŠBSR„QEVNT‘QUEUE�HALT�EVENT)ŠCLR.W‚LUFLG(A2)�CLEAR�DEVICE�TABLE�ENTRY ŠBRA„INEX010* *‰2nd�Packet* HLTP030ƒEQU„*+ŠMOVE.L�LUBADR(A2),A1‰SET�UP�BUFFER�POINTER=ŠAND.L‚#$F84F,IOSPRM(A1)…SET�UNCONFIGURABLE�BITS�(2nd)�PACKET ŠBRA„STAP030ŠPAGEL*****************************************************************************0* HANDLE SOLICITED DEVICE/CONFIGURE PACKET ($72)*+*ˆENTRY:�A2�=�address�of�device�table�entry*�A3�=�address�of�IOCB(*�A4�=�address�of�IPC�shared�memory�base*�A5�=�address�of�CCB*�D0�=�packet�status�value*L*****************************************************************************STAPKT:+ŠMOVE.L�LUBADR(A2),A1‰SET�UP�BUFFER�POINTER(ŠMOVE.L�LUDCB(A2),A0ŠPICK�UP�DCB�ADDRESS<ŠMOVE.B�RTNDSTA+IPCIM2(A4),D1‚PICK�UP�STATUS�FROM�SHARED�MEM ŠMOVE.L�D1,D2"ŠAND.B‚#$0F,D2�ISOLATE�DEVICE�TYPE-ŠMOVE.B�D2,IOSDTP(A1)‰UPDATE�CONFIGURE�BUFFER"ŠAND.B‚#$F0,D1�ISOLATE�STATUS�BITS-ŠMOVE.B�D1,IOSDST(A1)‰UPDATE�DEV�STATUS�FIELD%ŠCMP.B‚#XTDIPC,CCBTYPE(A5)ƒDISK�IPC�?ŠBNE.S‚STAP020�NO&ŠCMP.W‚#3,D0‘DEVICE�NOT�READY�STATUS�?%ŠBEQ.S‚STAP010�BRANCH�IF�YES,�IT'S�OKŠCMP.W‚#$05,D0ŠBEQ.S‚STAP010$*¦JMP�IF�INVALID�LOGICAL�UNIT�NUMBERŠCMP.W‚#$12,D0ŠBEQ.S‚STAP010*¦JMP�IF�DEVICE�NOT�THEREŠCMP.W‚#$10,D0ŠBEQ.S‚STAP010*¦JMP�IF�DEVICE�ERROR�RETURNEDŠCMP.W‚#$13,D0ŠBEQ.S‚STAP010 *¦JMP�IF�DEVICE�CONFLICT�ERRORŠTST.W‚D0”RIGHT�STATUS�VALUE�?ŠBEQ.S‚STAP010�BRANCH�IF�YES‰CMP.W…#$0E,D0‰BNE.S…STAP010!*¦JMP�IF�OTHER�THAN�INDETERMINATE*¦CHANNEL�ERROR'ŠBSR†IPCUNSERŒNO,�IPC�ERROR�-�RESET�IPCŠBRA†IPCINRTNŒRETURN1STAP010ƒCLR.B„IOSSTA(A3)ŠUPDATE�IOCB�STATUS�FIELD>ŠMOVEP.L‚RTNLSEC+IPCIM2(A4),D1�PICK�UP�SECTORS�FROM�SHARED�MEM*ŠMOVE.LƒD1,IOSRSZ(A1)‡UPDATE�SECTORS�FIELD'ŠCLR.W„IOSATW(A1)ŠCLEAR�ATTRIBUTES�WORDŠBRA.S„STAP030* STAP020ƒEQU„*N*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 6/04/84 <<<<<<<ŠTST†D0’REQUEST�STATUS�COMMANDŠBEQ†STAP300�YES*&*‰Check�for�Configuration�(1st�Packet)*"ŠBTST.B�#PIDPKTF,RTNPID+IPCIM2(A4)ŠBNE.S‚STAP035�Not�1st�PacketN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>*ŠCLR.B‚IOSSTA(A3)ŒUPDATE�IOCB�STATUS�FIELD*O*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *ºBKM�7/14/83$*‰BTSTWƒ#DATPRT,DCBATT(A0)ƒPRINTER�?!ŠBTSTMƒDATPRT,DCBATT,A0ƒPRINTER�? *ºBKM�7/14/83O*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ŠBEQ…STAP040ŽBRANCH�IF�NO*>*ˆPrinter�configuration�complete.‚Update�current�configuration*ˆand�return�the�results.*&‰MOVEM.LƒA5,-(A7)ŒSave�the�CCB�address6‰LEA‡CONFIG(A2),A5‡Use�the�CONFIG�offset�so�we�can�use*¦the�IOE�equates.BŠMOVE.B‚RTNHWS4+IPCIM2(A4),IOSREC+1(A1)�UPDATE�RECORD�LENGTH�FIELD?ŠMOVE.B‚RTNHWS4+IPCIM2(A4),IOSREC+1(A5)�Update�the�current�line*±length�config�value..:ŠMOVE.B‚RTNSWS2+IPCIM2(A4),D3‚PICK�UP�S/W�CONFIGURE�BYTE�2-‰CLR.W…IOSATW(A5)ŠWipe�the�old�attributes�out!ŠBTST„#XSWALF,D3‹AUTO�LINE�FEED�?ŠBEQ.SƒSTAP025ŽBRANCH�IF�NOC‰BSETW…#IOALNFD,IOSATW(A5)�Yes,�set�the�attribute�in�current�config0ŠBSETWƒ#IOALNFD,IOSATW(A1)‚YES,�SET�UP�ATTRIBUTE‰MOVE.B„RTNSWS3+IPCIM2(A4),IOSELC(A5)�Set�up�end/print�char�in*°current�configuration�area.*‰MOVEM.Lƒ(A7)+,A5ŒRestore�the�CCB�address.* STAP030ƒEQU…* ŠCLR.LƒD1FŠMOVE.B�CCBTYPE(A5),IOSCTP(A1)�Return�the�channel�type�and�driver�code<ŠMOVE.B�#IODIPC,IOSDRC(A1)ƒin�the�users�configuration�block.ŠBRA…INEXIT�GO�QUEUE�EVENT*B*ˆEnd�of�second�packet�from�MCCM.‚Update�the�current�config�values* STAP035‚EQU‡*&‰MOVEM.LƒA5,-(A7)ŒSave�the�CCB�address:‰LEA‡CONFIG(A2),A5‡Use�the�CONFIG�offset�so�we�can�use�the*¦IOE�equates.‰MOVE.W„IOSREC(A1),IOSREC(A5)‰MOVE.L„IOSRSZ(A1),IOSRSZ(A5)<‰MOVE.B„IOSXOF(A1),IOSXOF(A5)�Update�the�current�config�area<‰MOVE.B„IOSXON(A1),IOSXON(A5)�Update�the�current�config�area<‰MOVE.B„IOSBRC(A1),IOSBRC(A5)�Update�the�current�config�area0‰CLR.B…IOSDOP(A5)ŒUpdate�the�current�config�area<‰MOVE.B„IOSRLN(A1),IOSRLN(A5)�Update�the�current�config�area<‰MOVE.B„IOSCLC(A1),IOSCLC(A5)�Update�the�current�config�area<‰MOVE.L„IOSRTV(A1),IOSRTV(A5)�Update�the�current�config�area<‰MOVE.L„IOSEOL(A1),IOSEOL(A5)�Update�the�current�config�area<‰MOVE.B„IOSBRT(A1),IOSBRT(A5)�Update�the�current�config�area<‰MOVE.B„IOSNLS(A1),IOSNLS(A5)�Update�the�current�config�area‰MOVEM.Lƒ(A7)+,A5‰BRA.S…STAP030ŠPAGE* STAP040ƒEQU…*0ŠBSR…BLDATRMŽCALL�THE�BUILD�ATTRIBUTE�SUBROUTINE1ŠMOVE.W‚D1,IOSATW(A1)ˆUPDATE�USER�ATTRIBUTE�FIELD* *‰CONFIGURE�COMMAND�(2nd�Packet)* STAP150ƒEQU…***‰NOW�LETS�INTERRUPT�IPC�FOR*‰EVENT�COMPLETION.*1ŠMOVE.LƒCCBCHB(A5),A4‡SETUP�SHARED�MEMORY�POINTER5ŠMOVE.Bƒ#ACK,IPCIAB1(A4)„PLACE�ACK�INTO�SHARED�MEMORY)ŠMOVE.Bƒ#$80,IPCINT(A4)…INTERRUPT�THE�IPC.ŠCLR.W„CCBRCNT(A5)‰JUST�IN�CASE�A�RESET�WORKED**‰BUILD�SECOND�PACKET*(ŠLEA†IPCIM1(A4),A4‡SETUP�MESSAGE�ADDRESSŠMOVE.Wƒ#SPKT,D1/ŠMOVEP.W‚D1,IPCSTX(A4)‡SET�UP�STX�AND�PACKET�ID+ŠBSET…#PIDPKTF,IPCPID(A4)�SET�2nd�PACKET�ID0ŠMOVE.BƒDCBCDV(A0),IPCPHDV(A4)‚SET�UP�DEVICE�NO.* *ˆSet�up�pointer�to�device�table* ‰CLR.L…D1+‰MOVE.B„DCBCDV(A0),D1‡Get�the�device�number)‰MULU†#LUDSZE,D1ŠMul�by�size�of�one�table2‰MOVE.L„CCBDTBL(A5),A0†Get�start�address�of�tables4‰ADD.L…D1,A0�Add�to�get�start�of�this�device's�table :‰LEA‡CONFIG(A0),A0‡Use�the�CONFIG�offset�so�we�can�use�IOE *¦equates.ŠMOVE.Wƒ#XCON2P,D16ŠMOVEP.W‚D1,IPCCHCM(A4)†SET�UP�CHANNEL/DEVICE�COMMANDS*?*‰Using�the�Parameter�Mask�determine�which�parameters�come�from4*‰the�Parameter�Block�and�which�ones�use�the�default*,ŠMOVE.W‚IOSPRM(A1),D0ˆGET�MASK�OF�PARAMETERSŠMOVE.W‚#$5FB3,D10ŠMOVEP.W�D1,IPCPMSK(A4)‡PARAMETER�MASK�TO�PACKETŠLSR.Wƒ#2,D0�LINES�PER�PAGEŠBCS.SƒSTAP155�YESŠMOVE.LƒIOSRSZ(A0),IOSRSZ(A1) STAP155ƒLSR.Wƒ#3,D0�XON/XOF�CharŠBCS.SƒSTAP170�YES*2*‰Move�current�config�XON/XOF�char's�to�2nd�packet*ŠMOVE.B‚IOSXOF(A0),IPCXOF(A4)3ŠMOVE.B‚IOSXOF(A0),IOSXOF(A1)ŠUpdate�the�users�IOCBŠMOVE.B‚IOSXON(A0),IPCXON(A4)3ŠMOVE.B‚IOSXON(A0),IOSXON(A1)ŠUpdate�the�users�IOCBŠBRA.SƒSTAP175*'*‰Move�new�XON/XOF�char's�to�2nd�packet* STAP170ƒEQU…*ŠMOVE.B‚IOSXOF(A1),IPCXOF(A4)ŠMOVE.B‚IOSXON(A1),IPCXON(A4) STAP175ƒEQU…*!ŠLSR.Wƒ#1,D0�BRK�equivalent�char.ŠBCS.SƒSTAP180�YES*,*‰Move�current�config�BRK�char�to�2nd�packet*ŠMOVE.B‚IOSBRC(A0),IPCBRK(A4)3ŠMOVE.B‚IOSBRC(A0),IOSBRC(A1)ŠUpdate�the�users�IOCBŠBRA.SƒSTAP185*!*‰Move�new�BRK�char�to�2nd�packet* STAP180ƒEQU…*ŠMOVE.B‚IOSBRC(A1),IPCBRK(A4) STAP185ƒEQU…*ŠLSR.Wƒ#2,D0�REPRINT�LINE�charŠBCS.SƒSTAP190�YES*5*‰Move�current�config�REPRINT�LINE�char�to�2nd�packet*ŠMOVE.B‚IOSRLN(A0),IPCRPRT(A4)/ŠMOVE.B‚IOSRLN(A0),IOSRLN(A1)ŠUpdate�users�IOCBŠBRA.SƒSTAP195***‰Move�new�REPRINT�LINE�char�to�2nd�packet* STAP190ƒEQU…*ŠMOVE.B‚IOSRLN(A1),IPCRPRT(A4) STAP195ƒEQU…*ŠLSR.Wƒ#1,D0�CANCEL�LINE�charŠBCS.SƒSTAP200�YES*4*‰Move�current�config�CANCEL�LINE�char�to�2nd�packet*ŠMOVE.B‚IOSCLC(A0),IPCCNCL(A4)/ŠMOVE.B‚IOSCLC(A0),IOSCLC(A1)‰Update�users�IOCBŠBRA.SƒSTAP205*)*‰Move�new�CANCEL�LINE‚char�to�2nd�packet* STAP200ƒEQU…*ŠMOVE.B‚IOSCLC(A1),IPCCNCL(A4) STAP205ƒEQU…*$ŠLSR.Wƒ#1,D0�READ�TERMINATING�char'sŠBCS.SƒSTAP210�YES*;*‰Move�current�config�READ�TERMINATING�char's�to�2nd�packet*ŠMOVE.L‚IOSRTV(A0),D1ŠMOVEP.L�D1,IPCRTRM(A4)'‰MOVE.L„D1,IOSRTV(A1)‡Update�users�IOCBŠBRA.SƒSTAP215*0*‰Move�new�READ�TERMINATING�char's�to�2nd�packet* STAP210ƒEQU…*ŠMOVE.L‚IOSRTV(A1),D1ŠMOVEP.L�D1,IPCRTRM(A4) STAP215ƒEQU…*ŠLSR.Wƒ#1,D0�EOD-OF-LINE�stringŠBCS.SƒSTAP220�YES*6*‰Move�current�config�END-OF-LINE�string�to�2nd�packet*ŠMOVE.W‚IOSEOL(A0),D1ŠMOVEP.W�D1,IPCEOL(A4)'‰MOVE.W„D1,IOSEOL(A1)‡Update�users�IOCBŠBRA.SƒSTAP225*+*‰Move�new�END-OF-LINE�string�to�2nd�packet* STAP220ƒEQU…*ŠMOVE.W‚IOSEOL(A1),D1ŠMOVEP.W�D1,IPCEOL(A4)*** STAP225ƒEQU…*#ŠMOVE.B‚#ETX,IPC2ETX(A4)†SET�UP�ETX.ŠMOVE.B‚#C2PKSZ,IPCPKSZ(A4)ƒSET�UP�PACKET�SIZE**‰INDICATE�AWAITING�ACK*'ŠBSETWƒ#CCBFGWAK,CCBFG(A5)ƒSET�CCB�FLAG**‰INTERRUPT�THE�IPC* NRXINP„EQU„*0ŠMOVE.L�CCBCHB(A5),A1†SET�UP�SHARED�MEM.�POINTER(ŠMOVE.B�#$80,IPCIMB1(A1)ƒMESSAGE�WAITING0ŠADD.B‚#2,CCBICNT(A5)…BUMP�OUTSTANDING�INT�COUNT%ŠMOVE.B�#$80,IPCINT(A1)„INTERRUPT�IPC#ŠCLR.L‚D0‘SET�UP�GOOD�RETURN�TO�CMR ŠBRA„IPCINRTNŠPAGEK*****************************************************************************†REQUEST�STATUS�HANDLING**ˆENTRY:�A0�=�address�of�DCB!*�A1�=�address�of�user�data�block$*�A2�=�address�of�device�table�entry(*�A4�=�address�of�IPC�shared�memory�base*K*************************************************************************** STAP300ƒEQU…*,ŠLEA…DCBDEV(A0),A3ˆADDR�OF�DCB�CONFIGURATION0ŠBSR…BLDATRMŽcall�the�build�attribute�subroutine1ŠMOVE.W‚D1,IOSATW(A1)ˆupdate�user�attribute�field,‰MOVE.L„DCBATT(A0),D1‡Get�the�DCB�attributes**@*‰Move�configuration�info�from�CURRENT�CONFIG�to�user�data�block*8‰LEA‡CONFIG(A2),A3‡Use�the�CONFIG�offset�into�the�device%*¦table�so�we�an�use�the�IOE�equates.;‰LEA‡DCBDEV(A0),A0‡Get�the�DCB�device�dependent�area�offset*>ŠMOVE.W‚IOSREC(A3),IOSREC(A1)�Move�Current�values�to�user�IOCB@ŠMOVE.L‚IOSRSZ(A3),IOSRSZ(A1)�Except�that�some�values�(those�not AŠMOVE.L‚IOSWTO(A0),IOSWTO(A1)�configurable�anyway)�will�come�from *§the�DCB.4ŠBTST…#DATPRT,D1ŠCheck�the�DCB�attributes-�is�this�a *¦printer?5ŠBNE.SƒSTAP330ŽYes,�skip�the�update�of�the�term�stuff**ˆTerminal�status�request*ŠMOVE.L‚IOSRTO(A0),IOSRTO(A1)ŠMOVE.B‚IOSXOF(A3),IOSXOF(A1)ŠMOVE.B‚IOSXON(A3),IOSXON(A1)ŠMOVE.B‚IOSBRC(A3),IOSBRC(A1)ŠMOVE.B‚IOSDOP(A3),IOSDOP(A1)ŠMOVE.B‚IOSRLN(A3),IOSRLN(A1)ŠMOVE.B‚IOSCLC(A3),IOSCLC(A1)ŠMOVE.L‚IOSRTV(A3),IOSRTV(A1)ŠMOVE.L‚IOSEOL(A3),IOSEOL(A1)ŠMOVE.B‚IOSBRT(A3),IOSBRT(A1)ŠMOVE.B‚IOSNLS(A3),IOSNLS(A1)ŠMOVE.B‚IOSTCD(A0),IOSTCD(A1) STAP320ƒEQU…* ŠCLR.LƒD1 ŠBRA.SƒINEXITN*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< FAM 6/04/84 >>>>>>>*%*ˆRemainder�of�printer�status�request*$STAP330‚MOVE.W„IOSREC(A0),IOSLRL(A1)‰MOVE.B„IOSELC(A0),IOSELC(A1)‰BRA.S…STAP320*ŠPAGEK****************************************************************************,*‰HANDLE�MCCM�NORMAL�COMPLETION�PACKETS�HERE*+*‹ENTRY:�A2�=�address�of�device�table�entry*’A3�=�address�of�IOCB(*’A4�=�address�of�IPC�shared�memory�base*’A5�=�address�of�CCB*’D0�=�packet�status�value*K****************************************************************************MCCMPKT:2ŠLEA…MERXREF(PC),A1‡SET�UP�STATUS�CROSS�REF.�TABLE*ŠCMP.Wƒ#MERXL,D0ŒERROR�CODE�IN�THE�TABLE�?ŠBLE.SƒMCCMP10ŽBRANCH�IF�YES)ŠBSR.SƒIPCUNSER�NO,�IPC�ERROR�-�RESET�IPCŠBRA.SƒIPCINRTN�RETURN)MCCMP10ƒCMP.Wƒ#XPSCSM,D0‹CHECKSUM�ERROR�?ŠBNE.SƒMCCMP20ŽBRANCH�IF�NOŠCLR.LƒD0“YES,�IGNORE�ERROR1MCCMP20ƒLSL.Wƒ#1,D0�TIMES�2�FOR�POSITION�IN�TABLE,ŠMOVE.B‚(A1,D0.W),D1‰PICK�UP�IOCB�ERROR�CODE ŠCLR.L…D41ŠBTST„#0,1(A1,D0.W)ˆNEED�TO�UPDATE�LENGTH�FIELD�?ŠBEQ.SƒMCCMP30ŽBRANCH�IF�NO5ŠMOVEP.W�RTNBKSZ+IPCIM2(A4),D4‚PICK�UP�TRANSFER�BYTES5MCCMP30ƒMOVE.L‚D4,IOSLEN(A3)ˆUPDATE�IOCB�LENGTH�FIELD.ŠMOVE.B‚D1,IOSSTA(A3)ˆUPDATE�IOCB�STATUS�FIELD*¦FALL�THRU�TO�"INEXIT"ŠPAGEK****************************************************************************!*‚NORMAL�EXIT�FROM�INTERRUPT�TOUR*+*ˆENTRY:�A2�=�address�of�device�table�entry*�A3�=�address�of�IOCB(*�A4�=�address�of�IPC�shared�memory�base*�A5�=�address�of�CCB*K****************************************************************************INEXIT:&ŠMOVE.L‚#6,D0�SET�UP�EVENT�INFO�LENGTH)ŠMOVE.L‚LUDCB(A2),D2‰SET�UP�DCB�FOR�EVENT+ŠMOVE.W‚D1,D3�SET�UP�STATUS�VALUE�FOR�EVENT$ŠMOVE.B‚#XPSNRM,D1‹SET�UP�EVENT�TYPE+ŠLEA…CCBCPKT(A5),A4‡SET�UP�EVENT�BUILD�AREA!ŠBSR…QEVNT�QUEUE�COMPLETION�EVENT)ŠCLR.WƒLUFLG(A2)ŒCLEAR�DEVICE�TABLE�ENTRY*5* DECREMENT I/O PENDING COUNT IF SOLICITED TYPE EVENT*7INEX010ƒMOVE.L�CCBCHB(A5),A4†RESTORE�SHARED�MEM�POINTER.ŠBTSTƒ#7,RTNSTCM+IPCIM2(A4)‚IS�THIS�SOLICITED?ŠBNE.S‚INEX020ŒBRANCH�IF�NO ŠMOVE.L�LUTCB(A2),A0‡TCB�ADDRESS2ŠSUB.B‚#1,TCBIOCNT(A0)„DECREMENT�I/O�PENDING�COUNT**‰NOW�LETS�INTERRUPT�IPC�FOR*‰EVENT�COMPLETION.*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 11/07/84 <<<<<<C*********************************************************************‰BUILD�ATTRIBUTES�MASK*!*‹ENTRY:�A1�=�user�buffer�pointer(*’A4�=�address�of�IPC�shared�memory�base**‹EXIT:‚D1�=�attribute�mask*C******************************************************************* BLDATRMƒEQU…* ŠCLR.LƒD1:ŠMOVE.B‚RTNHWS1+IPCIM2(A4),D2�PICK�UP�H/W�CONFIGURE�BYTE�1ŠBTST„#XHWBIT,D2‹8�BIT�?ŠBNE.SƒBLDA010ŽBRANCH�IF�YES&ŠBSET„#IOABITS,D1ŠNO,�SET�UP�ATTRIBUTE%BLDA010ƒBTST„#XHWSTP,D2‹2�STOP�BITS�?ŠBEQ.SƒBLDA020ŽBRANCH�IF�NO'ŠBSET„#IOASTPB,D1ŠYES,�SET�UP�ATTRIBUTE!BLDA020ƒBTST„#XHWPRTY,D2ŠPARITY�?ŠBEQ.SƒBLDA030ŽBRANCH�IF�NO'ŠBSET„#IOAUSEP,D1ŠYES,�SET�UP�ATTRIBUTEŠBTST„#XHWEVN,D2‹EVEN�PARITY�?ŠBEQ.SƒBLDA030ŽBRANCH�IF�NO'ŠBSET„#IOAPRTY,D1ŠYES,�SET�UP�ATTRIBUTEABLDA030ƒMOVE.B‚RTNHWS2+IPCIM2(A4),D2‚PICK�UP�H/W�CONFIGURE�BYTE�2ŠBTST„#XHWMDM,D2‹MODEM�?ŠBEQ.SƒBLDA040ŽBRANCH�IF�NO'ŠBSET„#IOAMODM,D1ŠYES,�SET�UP�ATTRIBUTE,BLDA040ƒAND.Bƒ#$0F,D2ŽISOLATE�BAUD�RATE�BITS,ŠMOVE.B‚D2,IOSBRT(A1)ˆUPDATE�BAUD�RATE�FIELD6ŠMOVE.B‚RTNHWS3+IPCIM2(A4),IOSNLS(A1)�UPDATE�NULL�PADS<ŠMOVE.B‚RTNHWS4+IPCIM2(A4),IOSREC+1(A1)�UPDATE�RECORD�LENGTHŠCLR.BƒIOSREC(A1):ŠMOVE.B‚RTNSWS1+IPCIM2(A4),D3‚PICK�UP�S/W�CONFIGURE�BYTE�1ŠBTST„#XSWHDX,D3‹HALF�DUPLEXŠBEQ.SƒBLDA050ŽBRANCH�IF�NO'ŠBSET„#IOAECHO,D1ŠYES,�SET�UP�ATTRIBUTE BLDA050ƒEQU…*ŠBTST„#XSWNUL,D3‹ACCEPT�NULLSŠBEQ.SƒBLDA060ŽBRANCH�IF�NO'ŠBSET„#IOAPNUL,D1ŠYES,�SET�UP�ATTRIBUTE BLDA060ƒEQU…*#ŠBTST„#XSWTAHD,D3ŠACCEPT�TYPE�AHEADŠBEQ.SƒBLDA070ŽBRANCH�IF�NO'ŠBSET„#IOATAHD,D1ŠYES,�SET�UP�ATTRIBUTE BLDA070ƒEQU…* ŠBTST„#XSWXON,D3‹ACCEPT�XON/XOFFŠBEQ.SƒBLDA080ŽBRANCH�IF�NO'ŠBSET„#IOAXCTL,D1ŠYES,�SET�UP�ATTRIBUTE BLDA080ƒEQU…*ŠRTSN*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FAM 11/07/84 <<<<<<ŠPAGEJ**************************************************************************** QEVNT**„PLACE�MSG�ON�USER'S�ASQ* *ˆA4�=�COMPLETION�PACKET�POINTER*ˆA5�=�CCB�ADDRESS'*ˆD0�=�PACKET�LENGTH(MINUS�HEADER�INFO)*ˆD1�=�EVENT�TYPE*ˆD2�=�ID�(4�BYTES)*ˆD3�=�STATUS�VALUE�(2�BYTES) *‡[D4�=�DEVICE�STATUS�(2�BYTES)]*‡[D5�=�DEVICE�NUMBER�(1�BYTE)]*J***************************************************************************QEVNT:ŠMOVE.L�D0,D6ŽSAVE�LENGTH-ŠMOVE.L�#2,D7ŽOFFSET�FOR�STAGING�(NO�SVC�VCT)'ŠMOVE.B�#IOEVCD,1(A4)†CODE�(NO�SVC�VCT)(ŠMOVE.L�CCBSVVC(A5),2(A4)‚SERVICE�VECTOR*ŠBEQ.S‚QEVNT10ŒBRANCH�IF�NO�SERVICE�VECTOR'ŠADD.L‚#4,D0ŽCORRECT�LENGTH�FOR�SVC�VCT/ŠADD.L‚#4,D7ŽCORRECT�OFFSET�STAGING�FOR�SVC�VCT*ŠADD.L‚#$00800000,(A4)„CORRECT�FOR�SVC�VCT QEVNT10ƒEQU„*$ŠMOVE.B�D1,0(A4,D7)ˆCMPL.�EVENT�TYPE)ŠMOVE.B�CCBKEY(A5),1(A4,D7)�USER'S�ID�KEY*ŠADD.L‚#4,D0ŽCOMPLETE�LENGTH�OF�RETURN�MSG1ŠCMP.B‚CCBASQL(A5),D0…USER'S�MAX�ASQ�ENTRY�LENGTH"ŠBLS.S‚QEVNT20ŒBRANCH�IF�LENGTH�OK/ŠMOVE.B�CCBASQL(A5),D0…USER'S�LENGTH�IS�SMALLER QEVNT20ƒEQU„*ŠMOVE.B�D0,(A4)ŒCORRRECT�LENGTH QEVNT40ƒEQU„*ŠMOVE.L�D2,2(A4,D7)ˆSET�UP�ID'ŠMOVE.W�D3,6(A4,D7)ˆSET�UP�STATUS�VALUEŠCMP.B‚#6,D6Ž6�BYTE�INFO�?ŠBEQ.S‚QEVNT50ŒBRANCH�IF�YES(ŠMOVE.W�D4,8(A4,D7)ˆSET�UP�DEVICE�STATUSŠCMP.B‚#8,D6Ž8�BYTE�INFO�?ŠBEQ.S‚QEVNT50ŒBRANCH�IF�YES)ŠMOVE.B�D5,10(A4,D7)‡SET�UP�DEVICE�NUMBER%ŠCLR.B‚11(A4,D7)ŠCLEAR�RESERVED�FIELD*@* NOW LET'S PUT THE COMPLETION INTO REGISTERS, INTERRUPT IOH FOR&*ƒEVENT�COMPLETION,�SEND�EVENT�TO�TASK** QEVNT50ƒEQU„*ŠMOVEM.L�(A4),D2-D7 ŠBSR.S‚IPCQEVNTŠRTSŠPAGEK*****************************************************************************9* ROUTINE TO QUEUE EVENT (ALREADY STAGED IN REGISTERS) TO*ƒ-�DRIVING�TASK. *ƒ-�EVENT�BEGINS�IN�REGISTER�D2.***ˆEXEC�ROUTINE/*ˆREGISTERS�USED:�D0-D1/A0,A3-A6‚WORK�REGISTERS*˜D2-D7‹STAGING�REGISTERS**K**************************************************************************** IPCQEVNT:#ŠMOVEM.L�A3-A5,-(A7)‡SAVE�REGISTERS)ŠMOVE.L�CCBRQSTA(A5),A0„CALLER'S�TCB�ADDRŠSPC„2<ŠMOVE.L�#T0QEVNTI,D0‡WHEN�ONE�OR�MORE�INTERRUPTS�ARE�PENDING:ŠTST.B‚CCBINL(A5)‰USE�THE�QEVNTI�ENTRY�POINT.�ELSE�USE�THE ŠBNE.S‚IOHQ4ŽQUEVNTT�ENTRY�POINTŠMOVE.L�#T0QEVNTT,D0 IOHQ4…TRAPƒ#0ŠSPC„2"ŠBRA.S‚IOHQ5ŽBRANCH�IF�QUEUEING�OK&ŠMOVEM.L�(A7)+,A3-A5‡RESTORE�REGISTERS7ŠMOVE.L�(A7),CCBQVER1(A5)‚SAVE�CALLERS�ADDRESS�FOR�DBUGŠBRA.S‚IOHQRTN IOHQ5…EQU„*&ŠMOVEM.L�(A7)+,A3-A5‡RESTORE�REGISTERS)ŠCLR.L‚CCBQVER1(A5)‡CLEAR�Q�ERROR�ADDRESS IOHQRTNƒEQU„*ŠRTS‰PAGE***"* DISK ERROR CROSS-REFERENCE TABLE**ˆSTRUCTURE:�-�POSITION*“-�IOCB�ERROR�CODE*“-�UPDATE�FLAG*%*ˆUPDATE�FLAG:‚BIT�0�-�LENGTH�OF�XFER*–BIT�1�-�PSN�PROVIDED**DERXREF‚DC.B„0,1‘(0)�NO�ERROR"‰DC.B„ISTACRC,2‹(1)�DATA�CRC�ERROR)‰DC.B„ISTAWP,0Œ(2)�DEVICE�WRITE�PROTECTED#‰DC.B„ISTANR,0Œ(3)�DEVICE�NOT�READY*‰DC.B„ISTADDM,2‹(4)�READ�DELETED�DATA�MARK'‰DC.B„ISTAIE,0Œ(5)�LOGICAL�UNTT�#�ERROR'‰DC.B„ISTAIE,0Œ(6)�INVALID�DISK�ADDRESS!‰DC.B„ISTARES,0‹(7)�RESTORE�ERROR$‰DC.B„ISTADME,2‹(8)�RECORD�NOT�FOUND&‰DC.B„ISTAMRK,2‹(9)�ADDRESS�MARK�ERROR&‰DC.B„ISTADMA,0‹($A)�DMA�CHANNEL�ERROR#‰DC.B„ISTACSM,0‹($B)�CHECKSUM�ERROR‰DC.B„ISTADB,0Œ($C)�DEVICE�BUSY!‰DC.B„ISTACHN,0‹($D)�CHANNEL�BUSY!‰DC.B„ISTAIE,0Œ($E)�INDETERMINATE%‰DC.B„ISTACNT,0‹($F)�CONTROLLER�ERROR"‰DC.B„ISTAUNR,0‹($10)�DEVICE�ERROR ‰DC.B„ISTASEK,0‹($11)�SEEK�ERROR‰DC.B„ISTANR,0Œ($12)�NO�DEVICE-‰DC.B„ISTACFG,0‹($13)�DEVICE�CONNECT�CONFLICT$‰DC.B„ISTACMP,2‹($14)�DCOMPARE�ERROR,‰DC.B„ISTASPE,2‹($15)�SECTOR�WRITE�PROTECTED!‰DC.B„ISTABDS,2‹($16)�BBAD�SECTOR‰DC.B„ISTATO,0Œ($17)�TIMEOUT$‰DC.B„ISTAIE,0Œ($18)�INVALID�COMMAND#‰DC.B„ISTABUS,0‹($19)�DMA�BUS�ERROR'‰DC.B„ISTAMAP,0‹($1A)�DMA�MAPPING�ERROR*‰DC.B„ISTADMC,0‹($1B)�DMA�CONTROLLER�ERROR)DERXL„EQU…(*-DERXREF)/2-1…MAX�ERROR�VALUE‰PAGE***"* MCCM ERROR CROSS-REFERENCE TABLE**ˆSTRUCTURE:�-�POSITION*“-�IOCB�ERROR�CODE*“-�UPDATE�FLAG*%*ˆUPDATE�FLAG:‚BIT�0�-�LENGTH�OF�XFER**MERXREF‚DC.B„0,1‘(0)�NO�ERROR ‰DC.B„ISTACSM,1‹(1)�PARITY�ERROR‰DC.B„ISTABRK,1‹(2)�BREAK#‰DC.B„ISTANR,0Œ(3)�DEVICE�NOT�READY"‰DC.B„ISTACSM,1‹(4)�FRAMMING�ERROR'‰DC.B„ISTAIE,0Œ(5)�LOGICAL�UNTT�#�ERROR"‰DC.B„ISTADO,1Œ(6)�RECIEVE�OVERRUN'‰DC.B„ISTANR,1Œ(7)�PRINTER�OUT�OF�PAPER‰DC.B„ISTAIE,0Œ(8)�UNUSED‰DC.B„ISTAIE,0Œ(9)�UNUSED&‰DC.B„ISTADMA,1‹($A)�DMA�CHANNEL�ERROR‰DC.B„ISTACSM,0‹($B)�UNUSED‰DC.B„ISTAIE,0Œ($C)�DEVICE�BUSY‰DC.B„ISTAIE,0Œ($D)�UNUSED!‰DC.B„ISTAIE,0Œ($E)�INDETERMINATE)MERXL„EQU…(*-MERXREF)/2-1…MAX�ERROR�VALUE ‰ENDééé 0 TTL GPIB DRIVER - COMMAND PROCESSING - MAINLINE PAGE;*************************************************************’GPIB�COMMAND�PROCESSOR*8*ƒThe�function�of�the�command�processor�is�to�coordinate7*ƒand�set�up�all�commands�and�activity�on�the�BUS.�Upon9*ƒreception�of�a�command,�the�processor�will�perform�what8*ƒbasic�validations�of�parameter�blocks�and�command�type7*ƒit�can.�Within�the�CCB�for�this�channel�is�a�circular8*ƒqueue�area�which�will�control�the�dispatch�of�commands7*ƒto�the�BUS.�When�the�command�can�be�executed,�further6*ƒcommand�mode�validations�are�made�at�run�time�and�if;*ƒsuccessful,�control�will�be�passed�to�the�menu�processor.*7*ƒEach�command�is�made�up�of�a�group�of�sub-commands�or6*ƒmenu�items�and�these�menu�items�will�be�executed�one;*ƒat�a�time�until�the�command�menu�is�completely�processed.5*ƒAfter�the�first�menu�item�is�initiated,�the�rest�of:*ƒthe�menu�flow�will�be�handled�by�the�interrupt�processor*ƒportion�of�the�GPIB�driver.**‰ENTRY:�JSR�FROM�CMR�HANDLER=*�A2�-�Phsical�Address�of�Initiate�I/O�Parameter�Block�(IIPB)9*�A5�-�Phsical�Address�of�the�CCB�of�the�requested�device1*�A6�-�Phsical�Address�of�the�attached�task's�TCB*?*‰EXIT:�RTS�-�Command�validation�return�code�in�D0�(always�=�0)*K****************************************************************************/*ƒPerform�some�of�the�basic�checks�of�the�IOSPB* CMNDGPIB: MOVEQ #0,D5:�MOVE.L�XIOCPK(A2),D6‡set�up�addr�of�command�packet�(IOCB)5�MOVE.W�XIOPLN(A2),D5†set�up�length�of�command�packet3�MOVE.L�CCBTASKA(A5),A1„set�up�caller's�TCB�address3�BSR�IOADRCHKŽconvert�logical�to�physical�addresses�BEQ.S�CMNDG010Œgood�return*5�MOVEQ‚#ISTAIP,D1‰set�invalid�parm�block�error�to�IOS�BRA�CMNDEX1�exit�processor*"CMNDG010�MOVE.L�D6,A3†A3�<==�IOSPB �MOVE.L�XIOUID(A2),A4†A4�<==�DCB3 BTSTW #GPIBDOWN,BUSACTIV(A5) is this channel down?�BEQ.S�CMNDG015Žbr�=�no=�MOVEQ�#ISTACDN,D1‹return�error�=�unrecoverable�channel�error BRA CMNDEXIT*h4q:y<�A‰;‘;>CMNDG015�CMP.W�#IOHALT,IOSFCT(A3)‚is�this�an�I/O�HALT�command?�BEQ�HALTIO�branch�if�yes**‚Go�lookup�(validate)�command*?�BSR�GETCMDPŽD2�=�Relative�index�of�GPIB�function�from�IOSCMDTB:�BNE.S�CMNDEXIT‹br�=�command�not�found,�return�error�in�D1*8*‚Validate�any�buffer�addresses�if�this�command�requiresJ*‚data�buffers�(D6�=�Sec./Config.�buffer�addr.�or�0,�&�D7�=�Primary�buffer*‚address�or�0)*;�BSR�VALIDATE�validate�any�buffer�addresses�&�command�info.@�BNE.S�CMNDEXIT‹br�=�error�during�validation,�return�error�in�D1*A*‚The�command�is�validated,�perform�final�checks�and�either�queue*ˆor�execute�the�command.* INHIB MOVEQ #0,D3'�MOVE.B�DCBCDV(A4),D3Œget�device�number>�MOVE.W�DEVQBSY(A5),D0ŠD0�<==�current�bit�map�of�busy�dev�#'s.�BTST�D3,D0”is�device�busy?6�BNE.S�CMNDG120’branch�=�yes,�return�device�busy�error*9*‚Check�to�see�if�there�is�any�I/O�in�progress�on�the�BUS*'�MOVE.L�QHEAD(A5),D1Šis�the�queue�busy? CMP.L QTAIL(A5),D1�BEQ.S�CMNDG100�branch�if�no*=*‚The�GPIB�is�busy�so�queue�this�command�for�future�execution*!�BSR�PSHGPIBQ‘push�entry�on�queue>�BEQ.S�CMNDG120�ERROR,�queue�is�full,�return�device�busy�error4�MOVE.W�DEVQBSY(A5),D0‡mark�the�device�as�being�busy BSET D3,D0.�MOVE.W�D0,DEVQBSY(A5)‡restore�busy�map�to�CCB�BRA.S�CMNDOK‘exit*A*‚Since�the�queue�is�not�busy�the�command�may�be�executed�at�thisG*‚time�so�validate�that�the�bus�is�in�the�proper�mode�for�this�command.*MCMNDG100�MOVEM.L�D3-D7,-(A7)ƒSave�primary�and�secondary�buf�addr's�and�length1�BSR�VALOPER‹check�mode�and�operational�abilities/�MOVEM.L�(A7)+,D3-D7‚restore�addr's�and�lengths�TST.B�D1�any�errors?�BNE.S�CMNDEXIT†branch�if�error*/�BSR�PSHGPIBQ’push�current�command�on�the�queue!�BEQ.S�CMNDG 120�error,�queue�full%�BSR�BUILDMENU‘build�menu�for�command�BEQ.S�CMNDG110�BR‚=�continue*&�BSR�POPGPIBQ“else�remove�queue�entry,5�MOVEQ�#ISTADRVE,D1Œset�driver�run-time�error�status,#�BRA.S�CMNDEXIT�and�exit�with�error*=CMNDG110�MOVE.W�DEVQBSY(A5),D0Šget�busy�device�number�bit�map"�BSET�D3,D0”set�device�number�busy%�MOVE.W�D0,DEVQBSY(A5)‰update�bit�map*B*‚Start�execution�of�the�current�command�since�the�BUS�is�not�busy*9�MOVE.L�CCBCHB(A5),A1‰set�base�address�of�GPIBC�registers"�BSR�PROCMENU‘initiate�I/O�on�menu�BRA.S�CMNDOK�just�exit*4CMNDG120�MOVEQ�#ISTADB,D1…set�device�busy�error�code*CCMNDEXIT MOVE.B D1,IOSSTA(A3) save error code in IOSPB status field2CMNDEX1‚MOVE.B�#XPSNRM,D4„set�event�type�to�normal"�BSR�QEVENT“queue�the�event�to�IOS*=*‚Use�this�entry�point�when�no�event�is�to�be�sent.�The�event*‚will�be�sent�at�a�later�time.*(CMNDOK�UNMASK‚set�interrupt�mask�to�zero�MOVEQ�#0,D0ƒset�return�O.K. RTS  PAGE**’HALT�I/O�TO�A�DEVICE*?*ˆThe�Halt�I/O�processor�will�halt�I/O�to�the�specified�device.&*ˆThere�are�several�cases�to�consider:3*’1.�A�halt�directed�to�the�BUS�while�a�controller,8*’2.�A�halt�directed�to�the�BUS�while�a�Talker/Listener,!*’3.�A�halt�directed�to�a�device.*?*ˆIn�the�first�case,�any�operation�in�progress,�all�queued�I/O,5*ˆand�any�SRQ�polling�in�progress�will�be�terminated!*;*ˆIn�the�second�case,�the�halt�is�(implied)�directed�to�the@*ˆcurrent�I/O�in�progress.‚That�operation�will�be�aborted�immed- *ˆiately.*<*ˆIn�the�third�case,�the�queue�is�searched�for�the�specified;*ˆI/O�command.‚If�found,�the�command�is�marked�'halted'�and:*ˆwill�be�removed�from�the�queue�when�its�turn�comes,�else#*ˆan�error�will�be�returned�to�IOS.**HALTIO:1�INHIB—don't�allow�this�process�to�be�interrupted+�MOVE.B�DCBCDV(A4),D0ˆget�the�device�number)�BNE.S�HALT50�br�=�halt�a�bussable�device*<�BTSTW�#CAC_S,BUSACTIV(A5)ƒtest�if�we�are�in�controller�mode>�BEQ.S�HALT50�br�=�no,�treat�halt�to�BUS�in�T/L�mode�as�device*:*ˆHalt�command�is�to�the�BUS�and�it�is�in�Controller�mode.9*ˆTerminate�any�SRQ�polling,�current�I/O,�and�queued�I/O.* BSR HLTALL'�BNE.S�HALT40�br�=�invalid�halt�command*.HALT30�MOVE.W�#XSTVABT,D1„set�O.K.�halt�status*&HALT35�MOVEQ�#XPSHLT,D4†set�event�type4�BSR�QEVENT’send�halt�command�acknowledgement�to�IOS BRA CMNDOK*7HALT40�MOVE.W�#$FFFF,D1†set�invalid�halt�command�status BRA.S HALT35*6*ˆHalt�I/O�to�a�specific�device�or�the�BUS�in�T/L�mode*=HALT50�BSR�HLTCMDŒhalt�current�command�on�queue�(if�possible)�BNE.S�HALT40�br�=�error BRA.S HALT30 2‰TTL�GPIB�DRIVER�-�COMMAND�PROCESSING�(VALIDATION)‰PAGEB********************************************************************–VALIDATE�GPIB�COMMAND*<*ˆThis�section�will�validate�the�required�buffer�address�and4*ˆcommand�parameters.�If�the�addresses�are�valid�the<*ˆlogical�addresses�will�be�converted�to�physical�addresses.*)*“ENTER:ƒD2.W�-�relative�index�of�Command*œA1�-�TCB�address*œA2�-�IIPB�pointer*œA3�-�IOS�paramter�block*œA4�-�address�of�DCB*œA6�-�address�of�TCB**“EXIT:„IFƒD1�=�0ƒTHEN *¦Command�has�been�validated�and*¡D4�=�primary�buffer�length*¡D5�=�secondary�buffer�length-*¡D6�=�physical�secondary/config.�buffer�addr&*¡D7�=�physical�primary�buffer�address*¦or)*¡D4�=�primary�buffer�length�not�required+*¡D5�=�secondary�buffer�length�not�required,*¡D6�=�0�if�sec./config.�buffer�not�required'*¡D7�=�0�if�primary�buffer�not�required*œELSE�D1�=�error�code*!*ŽRegister�Usage:„0�1�2�3�4�5�6�7*žD‚*�R�PƒR�R�R�R *žA‚*�*ƒP�PƒP*E********************************************************************** VALIDATE:B�LEA.L�VALPARTB(PC),A0ƒget�base�addr�of�validation�parameter�table@�MOVE.W�0(A0,D2.W),D0„get�validation�parameters�for�this�command MOVEQ #0,D63�MOVE.L�D6,D7Œclear�buffer�address�return�registers)�MOVE.L�D6,D4‹clear�buffer�length�primary+�MOVE.L�D6,D5‹clear�buffer�length�seco ndary4�MOVEQ�#ISTAADD,D1ˆpreset�invalid�address�error�code5�BTST.L�#BVALPBUF,D0…validate�primary�buffer�address?�BEQ.S�VALID010‰branch�if�no*#*ƒValidate�Primary�buffer�addresses*.�MOVE.L�IOSSAD(A3),D6…get�buffer�start�address,�MOVE.L�IOSEAD(A3),D5„get�buffer�end�address+�SUB.L�D6,D5�is�end�address�<�start�address�BLT.S�VALIDRT‹yes,�error#�ADDQ�#1,D5Žaccount�for�true�length*-*‚Convert�primary�logical�address�to�physical*�BSR.S�IOADRCHK�convert�address�BNE.S�VALIDRT�branch�if�error4�MOVE.L�D6,D7�D7�<==�physical�addr�of�primary�buffer*�MOVE.L�D5,D4�D4�<==�Primary�buffer�length7�MOVEQ�#0,D6ŽClear�sec./config.�buffer�address�register*�MOVEQ�#0,D5ŽClear�secondary�buffer�length*VALID020�BTST�#BVALCBUF,D0‚validate�configuration�buffer�addr?�BEQ.S�VALID030�branch�if�no*'*‚Validate�configuration�buffer�address*;�MOVE.L�IOSDBP(A3),D6ˆget�logical�configuration�buffer�addr MOVEQ #0,D5F�MOVE.W�IOSVARL+DCBDEV(A4),D5„include�length�of�variable�area�(if�any)4�ADD.L�#IOSILN,D5Œadd�in�rest�of�configuration�block*3*‚Convert�configuration�logical�address�to�physical*9�BSR.S�IOADRCHK�convert�addr,�D6�=�Config.�buffer�address�BNE.S�VALIDRT�branch�if�error**ƒBuffer�validation�complete**ˆValidate�Command�Requirements* VALID030::�BTST�#BVALBDEV,D0�command�valid�only�for�bussable�device?,�BEQ.S�VALID125�br�=�no,�continue�validation< CMP.B #XDSGDEV,IOSDTP+DCBDEV(A4) is this a bussable device?�BEQ.S�VALID125�br�=�O.K.!?�MOVEQ‚#ISTAIVCB,D1‹else�set�invalid�command�for�BUS�error�code BRA.S VALIDRT*IVALID125�BTST�#BVALSCTL,D0‚does�command�require�system�controller�capab.?�BEQ.S�VALID130�branch�if�no?�MOVEQ‚#ISTAIVCB,D1ˆpre-load�invalid�command�for�BUS�error�code9�LEA.L�CONFINFO(A5),A0†get�pointer�to�device�config.�area7�MOVE.L�CNFIGPTR(A0),A0…get�pointer�to�BUS�config.�areaJ�BTSTW�#IOASCTC,IOSATW(A0)‚is�BUS�configured�for�system�controller�capab.?;�BEQ.S�VALIDRTŽbranch�=�no,�error�=�invalid�command�for�BUS*9VALID130�BTST�#BVALBUS,D0ƒcommand�valid�only�for�the�BUS?�BEQ.S�VALID175�branch�if�no@ CMP.B #XDSGBUS,IOSDTP+DCBDEV(A4) yes, check if this is the BUS!�BEQ.S�VALID175�br�=�o.k MOVEQ #ISTAIVBD,D1?�BRA.S�VALIDRTŽelse�exit�for�invalid�command�to�bussable�device*0VALID175�MOVEQ‚#ISTAOK,D1ƒset�return�code�=�O.K.*'VALIDRT�TST.B�D1�set�return�status�code RTS  PAGE* *ƒIOADRCHK*:*ˆThis�subroutine�will�check�the�address�boundaries�to�see1*…if�entirely�within�calling�tasks�address�space.*&*ˆENTER:‚D5�=�number�of�bytes�to�check%*�D6�=�68000�buffer�address�(logical)*�A1�=�TCB�address*8*ˆEXIT:ƒD6�=�physical�address�of�buffer�space�(if�legal)*�D1�=�0ƒno�error *•ElseƒError**ˆRMS68K�ROUTINES:�TR0$.LOGPHY*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�P�R�P�P�P�P�R�P*›A�P�P�P�P�P�P�P�P* IOADRCHK:< MOVEM.L A0-A6/D0/D2-D5/D7,-(A7) save all regs for EXEC call'�BTST�#0,D6‘is�buffer�on�word�boundary?#�BNE.S�IOHADR6Žbranch�on�no�(error)�TST.L�D5“is�length�zero?$�BEQ.S�IOHADR6Žbranch�if�yes�(error)*:�MOVE.L�TCBTST(A1),A0‡A0�<==�address�of�task�segment�table �TR0$.LOGPHY�,Žcall�exec‚routine!�BRA.S�IOHADR8Žgood�buffer�return7�NOP˜block�partially�in�task�space�(not�valid�for�GPIB)EIOHADR6�MOVEQ‚#ISTAADD,D1‚block�is�in�MMIO�space�(not�valid�for�GPIB) BRA.S IOHADR9*&IOHADR8�MOVEQ�#ISTAOK,D1…set�return�OK'IOHADR9 MOVEM.L (A7)+,A0-A6/D0/D2-D5/D7 RTS      é=/*=/*†M300DRV.AF=/*.=/* Chain file to assemble the IEEE-488 driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M300DRV.LS=/*=/IFC \1ƒ=ARG�M300DRV.LS=/ENDIF=/*&=ASM M300DRV.SA,M300DRV.RO,\1;-WRZ=160=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.M300DRV.EQ=/*ƒM300TABL.AI=/*ƒM300INIT.AI=/*ƒM300INTR.AI=/*ƒM300CMND.AI=/*}=/*=ENDééééé™&M300DR�IDNT�4,1ŠMVME-300�(GPIB)�DRIVER TTL M300DRV (GPIB) DRIVERD*********************************************************************&*’GENERAL�PURPOSE�INTERFACE�BUS�DRIVER*D********************************************************************'*…5/31/84†BWNŽFive�bugs�found�and�fixed(*£1)�Typo�error�in�code�at�SP_TO.�Caused'*¦system�to�crash�while�serial�polling.&*¦Change�instruction�MOVEM�A3-A3,-(A7)*¦to�MOVEM.L�A3-A5,-(A7).(*£2)�IOSPB�and�DCB�pointers�not�setup�at *¦PROCM100�after�Serial�Polling.(*¦Moved�instructions�containing�pointers*¦up�two�instructions.(*£3)�The�fifth�instruction�of�HLTCMD�was'*¦changed�to�read�LEA.L�GPIBQEND(A5),A0(*£4)�Problem:�crashing�GPIB�driver�while!*¦waiting�for�a�DMA�read�to�start(*¦Diagnosis:�An�SRQ�interrupt�was�occur-(*¦ing�while�the�MVME300�was�in�DMA�mode.'*¦The�TMS9914A�interrupt�regs�were�tri-&*¦stated�at�this�point�and�thus�cannot *¦be�read.'*¦Solution:�To�disable�TMS9914a�intrpts%*¦prior�to�any�DMA�and�re-enable�when%*¦DMA�was�complete.‚Also�to�re-enable"*¦if�HaltIO�or�Bus�Error�occurred.*)*£5)�Fixed�length�buffer�transfers�of�DMA&*¦read�were�not�being�properly�set�up.&*¦The�IOS�buffer�length�was�being�used&*¦instead�of�the�sysgened�fixed�buffer!*¦length.�A�label�and�branch�were*¦modified�in�READDATA.*#*ˆ5/31/84ƒBWNŽVME/10�problem�fixed:'*¦The�driver�did�not�work�on�thw�VME/10&*¦because�the�off-board�RAM�is�seen�at"*¦different�addresses�by�the�68010*¦and�the�GPIB�device.&*¦Two�macros�were�created�to�c orrectly*¦translate�addresses.)*¦Near�label�INTR115�plus�7�instructions:**¦MOVE.B‚MARLSB(A1),D0*¦MOVE.L‚MENUCPOS(A5),A0* *¦changed�to:**¦MOVE.B‚MARLSB(A1),D0*¦GET_ON_BD‚D0*¦MOVE.L‚MENUCPOS(A5),A0*)*¦Near�label‚SETUPDMA�plus�5�instructions**¦MOVE.L„A0,D0*¦MOVE.B„D0,MARLSB(A1)* *¦changed�to:**¦MOVE.L„A0,D0*¦GO_OFF_BD‚D0*¦MOVE.B„D0,MARLSB(A1)*(*œThe�GET_ON_BD�and�GO_OFF_BDƒmacros�are*œdefined�in�9995..DUALPORT.MC.¢D«J³-*œThese�macros�require�substitutions�based�on*œthe�target�system.2*œThis�is�done�at�SYSgen�time,�with�equates�in�the**œSYSCMD.CD�file�and�DEF�statements�in�the*œM300DRV.LG�file.*9*ˆ10/16/84ŒSerial�Poll�processing�altered.‚Due�to�devices1*œthat�have�the�capability�to�toggle�the�SRQ�line**œSRQ's�were�being�missed�if�the�following1*œcircumstance�occurred.�A�device�toggled�the�SRQ/*œline,�we�started�to�poll,�another�device�(one0*œalready�polled)�generated�TRUE�SRQ,�we�reached0*œend�of�SRQ�polling�list�(once�around�the�BUS)..*œTo�remedy�this�problem,�code�was�inserted�at/*œPROCMSRQ�to�'loop'�the�BUS�twice�to�catch�any *œTRUE�SRQ's.*8*ˆ10/16/84ŒRemove�pending�SRQ's�at�power-on/bootup�time.* SECTION 0 OPT BRL M300DRV:>�DC.L�INTRGPIB-M300DRV‡self�relative�interrupt�service�address<�DC.L�CMNDGPIB-M300DRV‡self�relative�command�service�addressC�DC.L�INITGPIB-M300DRV‡self�relative�initialization�service�address�DC.L�0–reserved*)*ƒreserve�space�for�CMR�allocation�of�CCB* XREF GPIBXP*�DC.W�GPIBXP‚#�of�extra�pages�for�this�CCB*@*…NOTE:�In�the�above�location�CMR�uses�the�first�byte�for�numberA*ƒof�extra�pages�needed,�but�since�only�a�word�may�XREF'ed�a�word>*ƒwas�reserved.�So�only�the�upper�byte�is�significant,�and�the*ƒnext�byte�will�be�0.*5�DC.B�0,0…next�14�bytes�reserved�for�later�use�by�CMR DC.L 0,0,0*5�DC.B�'102284'‚date�of�last�assembly�in�MMDDYY�format*�DC.B�'�'ƒreserved�for�patches*4�DC.B�'4'‚minimum�major�VERSAdos�revision�level�that*¦driver�is�compatible�with.**‚INCLUDE�FILES�(FOR�NOW)�ARE:**ˆNOLIST*ˆ9995.&.STR.SA*ˆ9995.&.CCB.EQ*ˆ9995.&.TCB.EQ*ˆ9995.&.LV5.EQ*ˆ9995.&.IOE.EQ*ˆ9995.&.NIO.EQ*ˆ9995.&.DUALPORT.MC*ˆLIST*ˆ9995.&.M300DRV.EQ *ˆM300TABL.AI *ˆM300INIT.AI *ˆM300INTR.AI *ˆM300CMND.AI* NOLIST�INCLUDEˆ9995.&.STR.EQ�INCLUDEˆ9995.&.CCB.EQ�INCLUDEˆ9995.&.TCB.EQ�INCLUDEˆ9995.&.DUALPORT.MC LIST TTL GPIB DRIVER - (LV5)�INCLUDEˆ9995.&.LV5.EQ LIST TTL GPIB DRIVER - (IOE)�INCLUDEˆ9995.&.IOE.EQ LIST TTL GPIB DRIVER - (NIO)�INCLUDEˆ9995.&.NIO.EQ LIST�INCLUDEˆ9995.&.M300DRV.EQ�INCLUDEˆM300TABL.AI�INCLUDEˆM300INIT.AI�INCLUDEˆM300INTR.AI�INCLUDEˆM300CMND.AI**‚GPIB�PATCH�AREA* DS.B 256 END ééé ééé! TTL GPIB DRIVER - INITIALIZATION PAGE**„GPIB�Initialization*7*ˆThe�initialization�processor�will�perform�three�major7*ˆfunctions:�(1)�initialize�the�MVME300�card,�(2)�reset9*ˆthe�TMS9914A�chip�and�(3)�reset�all�software�parameters5*ˆassociated�with�this�channel.�Additionally,�a�short=*ˆfunctionality�go/no�go�test�will�be�performed�to�determined%*ˆif�the�channel�is�properly�working.*"*’ENTER:�A5�=�CCB�pointer�for�GPIB* INITGPIB:2�INHIB‰set�processor�priority�(inhibit�interrupts)*�CMP.B�#XTGBUS,CCBTYPE(A5)ƒvalid�GPIB�CCB?�BNE.S�INITG010‚no<�MOVE.L�CCBCHB(A5),A1‚A1�<==�base�address�of�GPIBC�registers1 BSR.S SETGPIBC perform first time initialization6�BSR�RESETIO‚reset�all�run-time�parameters�&�registers+ BNE.S INITG010 branch if error from MTFIFO#�BSR�BDGONOGO‚go/no�go�MVME300�test�BEQ.S�INITG20‚OK*:* Error - the channel is inoperable or invalid so mark the*‰down.:INITG010�BSETW�#GPIBDOWN,BUSACTIV(A5)‚mark�channel�'down'.*$*ƒTurn�on�the�front�panel�fail�light*G�MOVE.B�#1<* caused the interrupt. Also, the hardware configured priority(* level for each level will be the same.*3�MOVE.B�CCBVECT(A5),D1‡get�configured�vector�number.�MOVE.B�D1,VECTREG0(A1)†TMS9914A�vector�number2�MOVE.B�D1,VECTREG1(A1)†I/O�complete�vector�number/�MOVE.B�D1,VECTREG2(A1)†Bus�error�vector�number �MOVE.B�D1,VECTREG3(A1)†Not�used*?*‚Set�up�the�configured�hardware�priority�level�and�enable�them*>�MOVE.B�CCBPPRIO(A5),D1†get�configured�hardware�priority�level �AND.B�#7,D1‘mask�priority�level�OR.B�#$18,D1�enable�interrupt/�MOVE.B�D1,CONTREG0(A1)†TMS9914A�priority�level3�MOVE.B�D1,CONTREG1(A1)†I/O�complete�priority�level0�MOVE.B�D1,CONTREG2(A1)†Bus�error�priority�level*)*ƒDisable�vector�3�because�it�is�not�used *�AND.B�#$0F,D1�clear�enable�bit/�MOVE.B�D1,CONTREG3(A1)†disable�not�used�vector*<�MOVE.B�D0,RELCNT(A1)ˆenable�the�byte�count�release�registerC�MOVE.B�#$3D,ADDRMOD(A1)…set�address�modifier�reg�to�superv.,�short*%�MOVE.B�#SWRST1,AUXCMD(A1)ƒreset�9914(�MOVE.B�#VSTD1,AUXCMD(A1)„set�high�speed MOVE.B #SWRST0,AUXCMD(A1)*"*ˆSoftware�one-time�initialization* MOVEQ #0,D0.�MOVE.B�D0,IOPEND(A5)ˆclear�I/O�pending�status3�MOVE.B�D0,BINTCNT(A5)‡reset�interrupt�nesting�flag,�MOVE.W�D0,BUSACTIV(A5)†put�BUS�in�idle�mode+�MOVE.W�D0,DEVQBSY(A5)‡mark�no�devices�busy*6�LEA.L�GPIBQ(A5),A0ŠA0�<==�start�of�command�queue�area+�MOVE.L�A0,QHEAD(A5)‰init�queue�to�be�empty MOVE.L A0,QTAIL(A5)*5�MOVE.W�#$37EB,TMSMASK(A5)ƒinit�9914�intrp�mask�(CCB)***‚Initialize�the�configuration�block�areas*1�LEA.L�CONFINFO(A5),A0‡set�all�30�entries�to�zero MOVEQ #29,D0SETG10 CLR.L (A0)+ DBRA D0,SETG10*9�LEA.L�CNFGAREA(A5),A0‡set�next�available�config�area�ptr7�MOVE.L�A0,NEXTCNFG(A5)†to�start�of�configuration�areas RTS  PAGE*<*ƒRESETIO�-�This�routine�will�implement�a�soft�reset�for�the*�MVME-300�and�the�driver.*$*ŽENTRY:�A5�=�address�of�CCB�pointer**ŽEXITƒD1�=�0‚No�errors-*—ELSE�D1�=�error�code�(hardware�malfunction)RESETIO:2�MOVE.L�CCBCHB(A5),A1ˆget�VME-300�I/O�base�addressE MOVE.B #1<*„in�the�GPIBC�FIFO.�It�is�meant�to�be�used�at�initialization,9*„HALT�I/O�sequences,�or�any�time�there�is�undesired�data*„left�in�the�FIFO.*-*‡ENTER:�A1�=�BASE�ADDRESS�OF�GPIBC�REGISTERS*!*‡EXIT:ƒD1�=�0ƒTHEN�FIFO�IS�EMPTY*‘ELSE�D1�=�ERROR�CODE* *ˆRegister�Usage†0�1�2�3�4�5�6�7*™D‚*�R*™A*MTFIFO:+�MOVE.W�#MAXFIFO+1,D1‚D1�<==�max�loop�count*6MTFIFO10 BTST.B #FIEMP,CNTRSTAT(A1) is the FIFO empty?"�BNE.S�MTFIFO20ƒyes,�task�complete?�MOVE.B�FIFODAT(A1),D0‚read�a�byte�from�the�FIFO�and�throw�away+�DBRA�D1,MTFIFO10‚continue�until�FIFO�empty<�MOVEQ�#ISTAHWMF,D1ƒD1�<==�return�hardware�malfunction�error�RTS’Exit�with�error�code*#MTFIFO20�MOVEQ�#ISTAOK,D1‚return�OK �RTSƒexit PAGE* *ƒBDGONOGO*<*ˆThis�routine�will�perform�a�short�functional�go/no�go�test<*ˆof�the�MVME300�card.‚It's�purpose�is�to�determine�the�size=*ˆof�the�DMA�FIFO�buffer�and�see�that�all�of�its�RAM�is�good.*(*’Enter:„A1�=�Base�address�of�GPIBC�regs*œA5�=�address�of�CCB*'*’Exit:…If�‚the�board�is�functional*œElseƒFIFO�buffer�error.**!*’Register�Usage:…0�1�2�3�4�5�6�7*£D‚*�**£A*H************************************************************************ BDGONOGO:$�MOVEQ�#0,D0‘initialize�counter/data*7BDG010 MOVE.B D0,FIFODAT(A1) store next pattern in FIFO$�ADD.W‚#1,D0�increment�pattern/count.�CMP.W�#MAXFIFO+1,D0‰Maxim um�FIFO�size�reached0�BEQ.S�BDRTN1�Yes,�FIFO�is�not�going�full,�Error1�BTST.B�#FIFUL,CNTRSTAT(A1)‚is�the�FIFO�full�yet?$�BEQ.S�BDG010�no,continue�until�full*;*‚At�this�point,�the�FIFO�is�full�and�the�size�is�contained8*‚in�D0.W.‚Empty�the�FIFO�and�check�the�contents�against*‚the�data�that�was�input.*4�MOVE.W�D0,FIFOSIZ(A5)‡save�the�FIFO�size�in�the�CCB�MOVEQ�#0,D0‘reset�pattern�reg*4BDG020‚MOVE.B�FIFODAT(A1),D1ƒget�next�char�from�FIFO�CMP.B‚D0,D1“same�as�input�was?�BNE.S�BDRTN1“branch�if�error�ADD.W�#1,D0”increment�pattern.�BTST.B�#FIEMP,CNTRSTAT(A1)…is�the�FIFO�empty?(�BEQ.S�BDG020“branch�until�FIFO�is�empty+�MOVEQ�#ISTAOK,D1�indicate�everything�is�OK RTS*$BDRTN1�MOVEQ�#ISTAHWMF,D1‡FIFO�error �RTSœexit   é. TTL GPIB DRIVER - INTERRUPT PROCESSING (MAIN) PAGEG*************************************************************************ƒGPIB�INTERRUPT�PROCESSOR*<*†The�following�interrupt�code�is�re-entrant�and�is�designed<*†to�handle�all�interrupts�that�may�occur�on�a�GPIB�channel.*:*†To�detect�all�GPIB�interrupts,�the�MVME300�card�uses�the;*†VERSAbus�Interruptor�Module�(VBIM)�chip�located�on�board.B*†The�VBIM�is�capable�of�handling�upto�four�sources�of�interrupts.<*†Currently�only�three�sources�of�interrupts�are�enabled�and;*†they�are:�Bus�Error�Interrupt,�I/O�Complete�Interrupt�andB*†TMS9914A�Interrupt.�Since�each�channel�can�only�have�one�vector,;*†these�three�sources�generate�the�same�vector�and�it�is�up8*†to�the�interrupt�processor�to�determine�the�reason�for*†interrupt�from�the�VBIM.*9*†NOTE:‚Upon�entry�CMR�has�saved�registers�A0,A1,�and�D0.*$*ˆENTER:�A5�=�address�of�CCB�pointer* INTRGPIB:+�MOVE.L�CCBCHB(A5),A1‚get�ptr�to�GPIBC�regs1�MOVEP.L�CONTREG0(A1),D0…read�all�vector�status's>�AND.L�#1<�MOVE.L�QTAIL(A5),A0„get�current�queue�pointer�(even�if�empty)(�CMPA.L�QHEAD(A5),A0„is�the�queue�empty?�BNE.S‚INTROK3‰br�=�no.�LEA.L‚CONFINFO(A5),A4ƒyes,�the�queue�is�empty,�MOVE.L�DVDCBPTR(A4),A4ƒso�set�A4�<=�BUS�DCB'�SUB.L‚A3,A3�set�up�dummy�IOSPB�address BRA.S INTROK4*4INTROK3�MOVE.L�DCBQOFST(A0),A4ƒA4�<==�address�of�DCB7�MOVE.L�IPBQOFST(A0),A3ƒA3�<==�address�of�current�IOSPB*.*ˆGive�DMA�complete�interrupt�highest�priority*DINTROK4�BTST.L�#IOCINT,D0‚did�an�I/O �complete�(DMA)�interrupt�occur?�BEQ.S�INTR100‚yes*, BTST #TMSINT,D0 was it a TMS9914 interrupt? BEQ INTR500 br = yes*'*ˆElse�it�must�be�a�BUS�ERROR�interrupt*E********************************************************************** *ƒBUS�ERROR*:*ˆThe�Bus�error�interrupt�is�generated�by�the�MVME300�cardB*ˆwhenever�a�DMA�bus�error�condition�occurs�during�a�transmission.8*ˆIf�there�was�no�I/O�in�progress,�the�interrupt�will�be>*ˆconsidered�spurious�and�will�generate�an�unsolicited�channel?*ˆinterrupt�to�IOS.‚If�I/O�was�in�progress,�the�current�command=*ˆwill�be�aborted�and�a�hardware�malfunction�error�event�sent *ˆto�IOS.*6�BSET.B�#VBIMENAB,CONTREG2(A1)‚enable�Bus�error�vector(�MOVE.L�QTAIL(A5),A0‚is�I/O�in�progress? CMPA.L QHEAD(A5),A0�BEQ�INTREXIT‰branch�if�no*@*ƒIf�an�SRQ�was�in�progress,�abort�all�SRQ�processing�and�send�a$*ƒHardware�Malfunction�error�to�IOS.*B*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *ˆ4/24/84ƒbwn*9*ˆMust�inhibit�TMS9914A‚interrupts‚during�DMA�operations.*ˆMust�re-enable�here.*4�BSET.B�#VBIMENAB,CONTREG0(A1)‚re-enable�9914�intrps*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. MOVEQ #ISTABUS,D1 indicate hardware bus error�BSR�PROCMERR‚process�error�BRA�INTREXIT‚normal�exit6 TTL GPIB DRIVER - INTERRUPT PROCESSING (DMA COMPLETE) PAGEG*************************************************************************ƒI/O�COMPLETE*:*ˆThis�interrupt�is�generated�by�the�MVME300�card�whenever>*ˆa�DMA�WRITE�or�DMA�READ�has�completed.�Three�major�functions<*ˆare�accomplished�in�this�sectionand�they�are:�(1)�I/O�post6*ˆformatting�(if�specified)�after�a�DMA�WRITE/READ�has;*ˆcompleted,�(2)�menu�processing�and�initiation�and�(3)�SRQ *ˆprocessing.*8*ˆFor�post�I/O�formatting,�the�user�may�specify�a�formatD*ˆroutines�to�be�executed�upon�completing�the�desired�DMA�operation.<*ˆThese�routines�must�be�specified�at�sysgen�time�and�should*ˆreport�errors.*<*ˆThe�menu�processing�section�is�designed�to�either�initiate;*ˆthe�next�menu�item�or,�if�at�end�of�menu,�to�queue�an�I/O:*ˆcompletion�event�back�to�IOS�and�initiate�an�new�menu�if7*ˆthere�are�other�operations�waiting�on�the�GPIB�queue.*;*ˆThe�last�major�section�of�the�I/O�complete�portion�of�the8*ˆinterrupt�handler�is�to�handle�program�flow�of�service;*ˆrequest�functions�(SRQ)�when�received�in�controller�mode.?*ˆThe�processor�will�run�status�menues�to�each�device�connected;*ˆto�the�GPIB�until�the�device�requesting�service�is�found.;*ˆOnce�found,�an�SRQ�ASQ�event�will�be�sent�back�to�IOS�for*ˆexamination.*INTR100:5 MOVE.B #1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>/�MOVE.L�QTAIL(A5),A0‚current�menu�queue�pointer)�CMPA.L�QHEAD(A5),A0‚is�I/O�in�progress�?�BEQ�INTREXIT‰br�=�no*5�BTSTW�#CAC_S,BUSACTIV(A5)ƒare�we�in�controller�mode?�BEQ.S�INTR115�br�=�no*4�BTST�#LADS_B,ADDRSTAT(A1)ƒis�9914�in�listener�mode?�BEQ.S�INTR110�br�=�no7�MOVE.B�#TCS,AUXCMD(A1)†so�take�control�(synchronously)2�MOVE.B�DATAIO(A1),D0ˆread�reg�to�get�things�going BRA.S INTR115**ƒAll�data�DMA�sequences�require�the�length�of�the�transfer�toD*ƒbe�reported�back�in�the�IOS�parameter�block�originating�this�call.*<�MOVEQ�#0,D0ƒread�the�current�memory�location�in�the�MAR�reg/ MOVE.B MARMSB(A1),D0 get most significant byte ASL.L #8,D0+ MOVE.B MARISB(A1),D0 get intermediate byte ASL.L #8,D00�MOVE.B�MARLSB(A1),D0‚get�least�significant�byteB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*8*ˆThe�address�we�get�in�D0�is�the�address�as�seen�by�the*ˆMVME300�board.4*ˆIf�we�are�using�dual�ported�ram‚on�the�VME/10,�and5*ˆif�this�address�is�in�on-board�ram,�then�it�must�be:*ˆtranslated�to�an�on-board�address�as�the�driver�sees�it.8*ˆWe�do�this�by�subtracting�the�RAM_SKEW�offset�from�the%*ˆaddress,�using�the�GET_ON_BD�macro.* ‰GET_ON_BD�D0*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>**<*‚Check�to�see�if�this�was�the�IN�or�OUT�processor.�If�it�is8*‚calculate�the�length�of�the�last�transfer�based�on�the=*‚contents�of�the�GPIBC�memory�address�register�(MAR)�and�theC*‚type�of�I/O�operation�performed,�else�no�length�calcs.�are�req'd.*?�MOVE.L�MENUCPOS(A5),A0‚get�address�of�menu�item�just�completed1�CMPI.B�#OUT,(A0)„was�the�OUT�processor�executed?�BEQ.S�INTR150…br�=�yes*/�CMPI.B�#IN,(A0)„was�the�IN�processor�executed?1�BNE.S�INTR200„br�=�TERM�or�SEOI�process�finished*I* Check for the one command that uses the secondary buffer instead of the* primary buffer for data xfer.*GINTR130�CMPI.W�#IOOWIN,IOSFCT(A3)ƒis�this�an�outout�with�input�command?�BNE.S�INTR150ƒbr�=�noG�SUB.L�D6,D0‚D0�=�current�M.A.R.�minus�(secondary)�buffer�start�address BRA.S INTR160*LINTR150 SUB.L D7,D0 D0 = current M.A.R. minus (primary) buffer start address*;INTR160 MOVE.L D0,IOSLEN(A3) store I/O xfer length in IOSPB*C*ƒCheck�to�see�if�there�is�a�special�post�formatters�to�be�executed*C�MOVE.L�IOSFMTA+DCBDEV(A4),D1‚get�pointer�to�user�defined�formatter1 BEQ.S INTR200 br = no user defined I/O formatter*B*‚Check�to�see�whether�input�or�output�menu�processor�was�executedA*‚and�then�see�if�there�is�a�user�defined�post�processor�for�this *‚device.*@�MOVE.W�#PST_OFMT,D0ƒD0�<==�preload�post�output�formatter�offset5�CMPI.B�#OUT,(A0)…are�we�doing�"OUT"�menu�processing?�BEQ.S�INTR180„branch�if�yes7�MOVE.W�#PST_IFMT,D0ƒD0�<==�post�input�formatter�offset*:INTR180�MOVE.L�D1,A0†A0�<==�base�address�of�all�formatters8�TST.L�0(A0,D0.W)ƒdid�user�define�a�post�data�formatter?�BEQ.S�INTR200ƒbranch�=�no*+�MOVEM.L�D1-D7/A0-A6,-(A7)‚save�environment.�JSR�0(A0,D0.W)‚execute�user�defined�formatter MOVEM.L (A7)+,D1-D7/A0-A6,�TST.B�D0ƒcheck�error�code�from�user�routine!�BEQ.S�INTR200‚branch�if�no�error*B*‚An�error�has�been�detected�in�the�user's�input�formatter�routine*-�MOVEQ‚#ISTAINFE,D1‚set�input�formatter�error�BSR�PROCMERR‚process�error+ BRA.S INTR250 exit DMA interrupt processor*INTR200:'�BSR�PROCMENU„process�next�menu�item(s)*INTR250:6 MOVE.W (A7)+,D5 retrieve previous TMS9914 status regs(�TST.W�D5ˆwas�there�a�pending�interrupt? BEQ INTREXIT br = no �BRA.S�INTR510‚else�go�handle�it  ; TTL GPIB DRIVER - INTERRUPT PROCESSING (TMS9914 INTERRUPT) PAGEE***********************************************************************ƒTMS9914A�INTERRUPT�SECTION*<*„Entering�this�section�of�the�interrupt�processor�indicates8*„that�one�or�more�interrupt�conditions�enabled�has�been;*„received.�Reading�the�interrupt�mask�regsiters�(INTR0�and9*„INTR1)�of�the�TMS9914A�will�indicate�which�condition(s) *„occurred.*;*„The�GPIB�can�be�in�one�and�only�one�of�the�four�following<*„states:�(1)�controller�mode,�(2)�talker�mode,�(3)�listener%*„mode,�or�(4)�idle�mode.‚These�modes@*„are�stored�in�'BUSACTIV'�and�may�change�depending�on  �what�type=*„of�interrupt�occurred.‚Also,�different�actions�may�be�taken?*„depending�on�the�current�state�of�the�BUS.‚All�interrupt�bits8*„will�be�checked�each�time�a�TMS9914A�interrupt�occurs.* INTR500:5�MOVEP.W�INTR0(A1),D5ƒread�interrupt�status�registers6�AND.W‚TMSMASK(A5),D5ƒD5�=�valid�interrupt�status�bitsINTR510:B BSET.B #VBIMENAB,CONTREG0(A1) reset interrupt enable for TMS9914A***0***†My�Address�Change�(MAC)�check�and�processing***$�BTST�#MACBIT,D5†is�the�MAC�bit�set?�BEQ.S�INTR600ƒbr�=�no*I AND.W #$FFFF-(1< BTSTW #SRQPROG,BUSACTIV(A5) USER I/O or SRQ polling sequence?(�BNE.S�INTR605�br�=�SRQ�polling�sequenceJ MOVE.B SRQBYTE(A5),IOSSAD-1(A3) else move serial poll byte to user's IOPB-INTR605�BSR�PROCMENU‰continue�processing�menu BRA INTR700*+*ˆCheck�if�we�have�any�Task�I/O�ready�to�go*8INTR610�MOVE.L�#READPEND,D3‚set�up�for�I/O�pending�check0�BSR�CHECKIOP�go�look�for�task�level�I/O�pending***0***„Byte�Out�(BO)�interrupt�check�and�processing***)INTR700�BTST�#BOBIT,D5„is�the�BO�bit�set? BEQ.S INTR800*9�BTSTW�#CAC_S,BUSACTIV(A5)ƒis�the�BUS�in�controller�mode?�BEQ.S�INTR750�br�=�no*5*‚A�command�string�might�be�in�progress.‚Send�out�the"*‚next�command�byte�with�ATN�true.*/�TST.L�CMDCOUNT(A5)‰false�or�last�BO�interrupt?(�BEQ.S�INTR800Žbranch�if�yes�(ignore�it)*5�SUB.L�#1,CMDCOUNT(A5)†decrement�command�string�count5�BEQ.S�INTR730Žbranch�if�finished�with�command�string4�MOVE.L�CMDBFPTR(A5),A0…get�ptr�to�next�command�byte&�MOVE.B�(A0)+,D1Œget�next�command�byte5�MOVE.L�A0,CMDBFPTR(A5)…update�command�buffer�pointer%�BSR�COMCMD‘output�command�on�the�BUS�BRA.S�INTR800Žcontinue*@*ƒCommand�processing�is�complete�for�now.�Continue�with�the�next=*ƒmenu�item�after�the�command�out�menu�item�processor�for�the*ƒcurrent�command.*1INTR730�BSR�PROCMENUˆcontinue�with�next�menu�item�BRA.S�INTR800Žcontinue*!* We are not the active cntroller*8INTR750�MOVE.L�#WRITPEND,D3‚set�up�for�pending�I/O�check.�BSR�CHECKIOP�check�for�pending�task�level�I/O***8***†Service�Request�(SRQ)�interrupt�check�and�processing***BINTR800�BTST�#SRQBIT,D5ƒis�a�device�on�our�BUS�requesting�service?�BEQ.S�INTR900„br�=�no*: BSETW #SRQWAIT,BUSACTIV(A5) indicate SRQ intrp processing3�MOVE.L�QHEAD(A5),D1‡yes,�get�current�queue�pointer'�CMP.L�QTAIL(A5),D1ˆis�the�queue�empty?(�BNE.S�INTR900Žbranch�if�no,�bus�is�busy*A*‚Since�the�GPIB�is�idle,�initiate�the�service�request�processing2*‚to�determine�which�device�is�requesting�service.*9*ˆFirst�build�a�dummy�queue�entry�for�standard�processing** MOVEM.L A3-A4/D4-D7,-(A7) save intrp regs SUB.L A3,A3 dummy IOSPB address LEA.L CONFINFO(A5),A4L MOVE.L DVDCBPTR(A4),A4 A4 <= to BUS DCB (serial polling is a BUS operation)* LEA.L SRQBYTE(A5),A0 input buffer p! ointer,�MOVEQ�#1,D4‚Status�byte�response�length�=�1/ MOVE.L A3,D5 dummy length for secondary buffer2 MOVE.L A0,D6 dummy primary buffer address pointer4 MOVE.L A3,D7 dummy secondary buffer address pointer' BSR PSHGPIBQ go put entry on the queue- MOVEM.L (A7)+,A3-A4/D4-D7 restore intrp regs1 BEQ.S INTR900 br = queue full, process SRQ later&�BSR�PROCMSRQ‚start�up�the�SRQ�process***<***ƒRemote/Local�Change�(RLC)�interrupt�check�and�processing***6INTR900�BTST�#RLCBIT,D5ƒremote/local�change�interrupt?�BEQ.S�INTR1000ƒbranch�if�no*@�MOVE.B�ADDRSTAT(A1),D1‡D1�<==‚current�address�state�of�TMS9914A6�AND.W�#1<*‚bit�mask�and�check�to�see�if�we�even�need�to�respond�to�this*‚secondary�address.*8�LEA.L�CONFINFO(A5),A0„A0�<==�ptr�to�configuration�areas?�MOVE.L�CNFIGPTR(A0),A0ƒA0�<==�ptr�to�configuration�area�of�BUS*=*‚Read�the�command�pass�thru�register�to�obtain�the�secondary*‚address�that�is�required.*D�MOVE.B�CMDPTHRU(A1),D2†D2�=�secondary�addr�controller�is�requesting$�AND.L�#SECMASK,D2‹mask�address�bitsA�MOVE.L�IOSSAMW(A0),D1‡D1�<==�mask�of�valid�secondary�write�addrsD�BTST�#TADS_B,ADDRSTAT(A1)ƒAre�we�in�primary�tal! ker�addressed�state?�BEQ.S�INTR1140ŽBranch�if�no*@�MOVE.L�IOSSAMR(A0),D1‡D1�<==�mask�of�valid�secondary�read�addrs*.INTR1140�BTST.L�D2,D1ˆvalid�secondary�address?�BNE.S�INTR1150�branch�if�yes*(*‚This�is�not�a�valid�secondary�address.*?�MOVE.B�#DACR0,AUXCMD(A1)‚release�hdshk�&�don't�enter�LADS/TADS�BRA.S�INTR1200ƒcontinue*AINTR1150 MOVE.B #DACR1,AUXCMD(A1) release hdshk & enter TADS/LADS4�OR.B�#1<�BRA.S�CKIO040�go�send�event�to�user�about�type�of�pending�I/O*&*ˆTask�I/O�is�pending,�check�for�match.*’on�operation�type�&�secondary�addr.�if�req'd*8CKIO010 BTST.B D3,IOPEND(A5) Is it a a matching request?.�BEQ.S�CKIO030�Br�=�no,�abort�Task�I/O�request*C BTST.B #SECONDAR,IOPEND(A5) Is there a secondary address involved?)�BEQ.S�CKIO050�Br�=�no,�go�start�the�menu5�MOVE.L�QTAIL(A5),A0‰get�pointer�to�current�operation2�MOVE.L�IPBQOFST(A0),A0†AO�<==�I/O�parameter�block9�CMP.W�#IORSEC,IOSFCT(A0)„Is�it�a�secondary�read�command?�BEQ.S�CKIO015�br�=�yes:�CMP.W�#IOWSEC,IOSFCT(A0)„Is�it�s�secondary�write�command?.�BNE.S�CKIO030�br�=�no,�abort�pending�task�I/O*CKIO015 MOVEQ #SECMASK,D1@�AND.B�IOPEND(A5),D1‰D1�=�active�controller�requested�sec.�addr.H�CMP.B�IOSSAD-1(A0),D1‡is�it�the�same�as�rhe�Task's�requested�sec�addr.?'�BEQ.S�CKIO050�br�=�yes,�start�the�menu*.CKIO030�BSR�HLTCMD‹kill�the�task�requested�I/O CKIO050�BSETW�#BUSIOP,BUSACTIV(A5)ƒset�INTRP�level�I/O�pending&�BSR�PROCMENU‘Initiate�I/O�on�the�menu* CKIO060 RTS PAGEH**************************************************************************—CANCEL�PENDING�I/O*;*ˆAn�event�has�occurred�on�the�BUS�that�forces�us�to�cancel9*ˆany�pending�I/O�regardless�of�source.‚The�cause�of�this&*ˆevent�will�also�be�sent�to�the�user.**/*ˆENTER:„A1�<==‚base�address�of�GPIBC�registers*’A3�<==‚address�of�IOSPB*’A4�<==‚address�of�DCB*’A5�<==‚address�of�CCB*.*’D5.W�<==�current�9914�intrp�reg�(INTR�LEVEL)**’D3.B�<==�I/O�operation�type�(READ/WRITE)* CANCLIOP:#�BSR�HLTALL’Halt�all�I/O�on�the�BUS, MOVE.B #0,IOPEND(A5) cancel any pending I/OH�AND.W‚#$FFFF-(1<PROCMENA�MOVE.L�QTAIL(A5),A6‰A6�<==�ptr�to�current�queue�entry1�BTSTW�#HALTED,CSTQOFST(A6)‚was�this�menu�Halted?�BNE�PROCM020�br�=�yesK MOVE.L MENUNPOS(A5),MENUCPOS(A5) update: next item is now the current item6�MOVE.L�MENUNPOS(A5),A0ƒget�next�menu�position�pointer#�MOVE.B�(A0)+,D0ƒget�next�menu�item5�MOVE.L�A0,MENUNPOS(A5)ƒupdate�next�menu�item�pointer* *ƒcheck�to�see�if�at�end�of�menu*�CMP.B�#END,D0Œend�of�menu?�BEQ.S�PROCM020‹yes* * Initiate I/O on next menu item*;�LEA.L�MENUCTBL(PC),A0ƒA0�<--�menu�function�code�jump�table(�CMP.B�#" MENUCLEN,D0‚valid�function�code?�BGT�PROCMERB‚branch�if�no*/�AND.W�#$FF,D0ƒmask�the�offset�of�routine�index"�ASL.W�#1,D0…make�table�compatibleA�MOVE.W�0(A0,D0.W),D0‚relative�distance�between�table�and�routineA�MOVEM.L�D0/D2-D7/A0-A6,-(A7)‚save�everything�except�D1�for�error,�MOVE.L�CCBCHB(A5),A1‚get�base�addr�of�GPIBC)�JSR�0(A0,D0.W)‚initiate�I/O�on�menu�item3�MOVEM.L�(A7)+,D0/D2-D7/A0-A6‚restore�all�registers �TST.B�D1‚set�conditional�return2�BNE‚PROCMERA‚go�to�processor�menu�error�processor*C*…These�previous�menu�item�was�successfully�initiated/completed.�If;*…the�menu�item�was�a�Class�II�or�Class�III�type�(auxiliary5*…command�or�special�function�type)�no�interrupt�will9*…be�generated�so�check�that�here�to�keep�things�rolling.*5�MOVE.L�MENUCPOS(A5),A0ƒget�current�menu�item�pointer/�CMPI.B�#AUXTYPE,(A0)‚was�it�an�auxiliary�type?,�BGE.S�PROCMENA‚yes,�continue�with�next�item*:*‚The�following�is�a�special�case�check�for�the�menu�items9*„DATAXFR�TERM/SEOI.�If�either�processor�was�performed�in7*„the�image�mode�or�performed�in�formatted�mode�with�no>*„EOR�characters�enabled,�then�no�interrupt�will�be�generated.*;�BCLRW�#TERMINT,CSTQOFST(A6)ˆare�we�expecting�an�interrupt?-�BNE.S�PROCMENA•br�=�no,�go�to�next�menu�item*6PROCMRTN�MOVEM.L�(A7)+,D2-D7/A1-A6‚restore�environment RTS  PAGE*>*‚It�has�been�determined�that�we�are�at�the�end�of�the�currentB*‚operation�menu�item�table�or�this�I/O�operation�has�been�HALTED.*8PROCM020�BTSTW�#SRQPROG,BUSACTIV(A5)‚is�SRQ�in�progress?�BNE�PROCM200•yes7�MOVEQ‚#ISTAOK,D1�set�operation�completion�status�to�ok PROCM050 MOVEQ #0,D0+�MOVE.B�DCBCDV(A4),D0‚get�the�device�number1�MOVE.W�D1,-(A7)ˆsave�operation�completion�status9�MOVE.W�DEVQBSY(A5),D1‚D1�<==�current�device�busy�bit�map(�BCLR�D0,D1�clear�that�device's�busy�bit%�MOVE.W�D1,DEVQBSY(A5)‚update�bit�map�MOVE.W�(A7)+,D1ˆrestore�status: BTSTW #HALTED,CSTQOFST(A6) was this operation terminated?�BNE.S�PROCM055Žbr�=�yesH BTSTW #SRQFAIL,CSTQOFST(A6) if an SRQ poll, did the device not respond?�BEQ.S�PROCM060‰br�=�O.K.*5PROCM055�MOVEQ�#ISTATO,D1„else�set�timeout�error�code*2PROCM060 MOVE.B D1,IOSSTA(A3) save status in IOSPB2�MOVE.B�#XPSNRM,D4ƒD4�<==�set�event�type�to�normal�BSR�QEVENT‚send�event�to�IOS/�BTSTW�#SRQWAIT,BUSACTIV(A5)†is�an�SRQ�waiting?�BEQ.S�PROCM100”no*7*‚Overlay�the�current�completed�queue�entry�(operation)1*‚with�dummy�SRQ�processing�information�pointers.* LEA.L CONFINFO(A5),A1J MOVE.L DVDCBPTR(A1),DCBQOFST(A6) set to DCB of the BUS for SRQ processing'�CLR.W�CSTQOFST(A6)ŠInit�command�status-�CLR.L�IPBQOFST(A6)Šclear�dummy�IOSPB�pointer LEA.L SRQBYTE(A5),A16�MOVE.L�A1,PBPAOFST(A6)†set�dummy�input�buffer�address5�MOVE.B�#1,PBLNOFST(A6)†set�dummy�input�buffer�length(�CLR.L�SBPAOFST(A6)Šno�secondary�buffer!'�CLR.W�SBLNOFST(A6)Šand�its�length�is�0 BRA.S PROCSRQA  PAGE*3*ˆENTRY�POINT�FOR�SRQ�PROCESSING�AT�INTERRUPT�LEVEL*?*‚There�is�an�SRQ�request�waiting�to�be�handled�so�initiate�the@*‚status�menu�for�the�first�device�number�connected�to�this�CCB.=*‚Also,�send�an�I/O�complete�event�back�for�previous�function%*‚since�we�got�other�things�to�do�now* PROCMSRQ:+�MOVEM.L�D2-D7/A1-A6,-(A7)…save�environment*>PROCSRQA�MOVE.L�QTAIL(A5),A6ŠA6�<==�ptr�to�current�queue�entry2�BCLRW�#SRQWAIT,BUSACTIV(A5)„take�out�of�wait�mode8�BSETW�#SRQPROG,BUSACTIV(A5)„put�in�SRQ�in�progress�mode3�LEA.L�COND_SP(PC),A0‹A0�<==�serial�poll�menu�table+�MOVE.L�A0,MENU(A5)�set�top�of�menu�pointer=�MOVE.B�CSPDEVNM(A5),D0‰get�device�number�of�last�serial�poll<�MOVE.B�D0,FSPDEVNM(A5)‰set�first�serial�poll�device�#�indexD*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+*�USED�TO�BE�BRA.S�PROCM240ŒS.J.F.�10/10/84D*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(�BRA.S�PROCM227‘initiate�I/O�on�SRQ�menu* PAGE$PROCM100�BSR�POPGPIBQƒpop�GPIB�queue;�BEQ�PROCMRTN‚branch�if�queue�is�empty# �(nothing�else�to�do)*:*‚Set�up�the�necessary�pointers�from�the�queue�information-*‚and�then�build�the�menu�for�the�new�command**�MOVE.L�QTAIL(A5),A6‚get�new�queue�pointer3*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn#*ˆSet�up�registers�before�branching?�MOVE.L�IPBQOFST(A6),A3‚A3�<==�address�of�IOSPB�for�new�command=�MOVE.L�DCBQOFST(A6),A4‚A4�<==�address�of�DCB�for�new�command*6*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>E�BTSTW�#HALTED,CSTQOFST(A6)‚was�this�command�entry�previously�halted?�BNE�PROCM020ƒbranch�if�yes2*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn**ƒThese�moves�done�above�now.*?*MOVE.L�IPBQOFST(A6),A3‚A3�<==�address�of�IOSPB�for�new�command=*MOVE.L�DCBQOFST(A6),A4‚A4�<==�address�of�DCB�for�new�command*8*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*(�BSR�GETCMDP…get�pointer�to�next�command+�BNE�PROCM020„BR�=�invalid�command,�discard4�BSR�VALOPER…validate�operational�mode�and�abilities)�BNE�PROCM020„Error,�invalid�cmd,�discard(�BSR�BUILDMEN„build�menu�for�new�command�BNE�PROCM020„Branch�if�error&�BRA�PROCMENA„initiate�I/O�on�new�menu**‚SRQ�Processing�and�Detection*7PROCM200 BTSTW #HALTED,CSTQOFST(A6) SRQ polling halted?&�BNE.S�PROCM300„br�=�yes,�term�polling+�MOVE.B�SRQBYTE(A5),D1ƒread�the�status�byte*.�BTST�#6,D1ƒis�this�device�requesting�service? BNE.S PROCM400 branch if yes*A*‚Get�next�index�device�number�of�the�next�device�to�serial�poll.?*‚The�technique�used�allows�wraparound�so�that�no�device�on�the:*‚BUS�will�have�a�greater�priority�of�being�serial�polled.*1PROCM220�MOVE.B�CSPDEVNM(A5),D0‚get�current�index2�ADD.B�#1,D0ƒbump�by�one�to�get�next�device�number+�CMPI.B�#MAXDEVNM+1,D0ƒend�of�device�chain?�BNE.S�PROCM225‚not�yet �MOVEQ�#1,D0‚reset�to�device�#�1*I*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *‡10/9/84…SJF*A*‡We�will�insert�code�in�here�to�implement�the�concept�of�looping?*‡twice�through�all�devices�on�a�bus�to�locate�the�source�of�an=*‡SRQ.‚This�was�necessary�due�to�devices�pulsing�the�SRQ�line1*‡and�then�missing�true�SRQ's�from�other�devices.*J*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>EPROCM225�MOVE.B‚FSPDEVNM(A5),D2…D2�<--�device�#�we�started�SRQ's�with(�AND.Bƒ#$0F,D2�Mask�out�the�loop�counter5�CMP.BƒD0,D2�Have�we�reached�the�starting�SRQ�device?�BNE.SƒPROCM227ŒNot�yet7�BSET.B‚#7,FSPDEVNM(A5)…Set�the�potemtial�lap�indicator.�BNE.SƒPROCM300ŒBranch�if�we�have�lapped�twice*?PROCM227�MOVE.L�CCBCHB(A5),A1‚A1�<--�base�GPIB�address�of�board.�BTST.B‚#BUSSRQ,BUSSTAT(A1)ƒis�SRQ�still�true?1�BEQ.SƒPROCM300Žbranch�if�not,�exit�SRQ�processes =*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *�10/9/84…sjf*+*ˆThis�code�was�replaced�by�the�above�logic*L*PROCM225�CMP.B�FSPDEVNM(A5),D0‚have�we�done�a�complete�turn�around�the�BUS?**�BEQ.S�PROCM300ƒyes,�we�may�have�problems*@*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *-*‚Check�to�see�if�this�device�number�is�valid**PROCM240�ANDI.L�#$FF,D0ƒget�rid�of�garbage4�MOVE.B�D0,CSPDEVNM(A5)ƒupdate�current�device�number/�ASL.L�#3,D0ƒcalc�offset�into�config�info�table5�LEA.L�CONFINFO(A5),A0ƒbase�addr�of�config�info�table6�MOVE.L�DVDCBPTR(A0,D0.L),A4ƒget�pointer�to�device�DCBJ�MOVE.L�CNFIGPTR(A0,D0.L),A0ƒget�ptr�to�current�device�configuration�block MOVE.L A0,D0 set cond codes:�BEQ.S�PROCM220ƒbranch�if�device�not�present�or�configuredF MOVE.L A4,DCBQOFST(A6) save new DCB pointer at current queue locationC�BTSTW�#IOASPOC,IOSATW(A0)‚does�device�have�serial�poll�capability?�BEQ.S�PROCM220ƒbranch�if�no*>�MOVE.L�MENU(A5),MENUNPOS(A5)‚reset�status�menu�pointer�to�top�BRA�PROCMENAƒinitiate�I/O*>PROCM300 BCLRW #SRQPROG,BUSACTIV(A5) clear SRQ in progress bit(�BRA�PROCM100„continue�normal�processing*.*ƒFound�a�device�on�the�bus�requesting�service*5PROC# M400�MOVEQ‚#SRQTYPE,D0‚set�event�type�to�SRQ�type�BSR�SENDUEVS‚send�event>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>* *’10/9/84„sjf*5*ˆThis�logic�is�now�performed�above�after�each�device *ˆis�queried.*-*�MOVE.L�CCBCHB(A5),A1‚get�base�addr�of�GPIBC/*�BTST.B�#BUSSRQ,BUSSTAT(A1)ƒis�SRQ�still�TRUE?7*�BEQ.S�PROCM300‚no,�clean�up�and�continue�normal�oper.*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *5*ˆReset�the�lap�indicator�and�the�first�device�polled5*ˆfor�this�next�SRQ�series.�Each�time�an�SRQ�is�found4*ˆwe�must�lap�at�least�twice�to�catch�devices�missed*ˆby�toggling�SRQ's.***<�MOVE.B�CSPDEVNM(A5),D0‚last�device�#�that�was�serial�polled �ADD.B�#1,D0‚start�with�next�one2 CMPI.B #MAXDEVNM+1,D0 should we wraparound first? BNE.S PROCM520 branch if no> MOVEQ #1,D0 set to first device index of configuration blocks*DPROCM520 MOVE.B D0,FSPDEVNM(A5) set start of serial poll index chainA�BRA.S�PROCM227‚start�over�again…***�10/9/84�sjf‚WAS�PROCM240�*****5*‚Process�Menu�entry�point�when�an�error�has�occurred#*‚with�the�reason�fro�error�in�D1.B* PROCMERR:+�MOVEM.L�D2-D7/A1-A6,-(A7)…save�environment*>PROCMERA�MOVE.L�QTAIL(A5),A6ƒA6�<==�ptr�to�current�queue�entry1 BCLRW #SRQPROG,BUSACTIV(A5) was SRQ in progress?4�BEQ�PROCM050ƒbr�=�NO,�terminate�USER�I/O�processing-�BRA�PROCM100ƒelse�pop�SRQ�menu�and�terminate*:PROCMERB�MOVEQ�#ISTADRVE,D1‚set�driver�run-time�error�code% BRA.S PROCMERA go to error processor 8 TTL GPIB DRIVER - INTERRUPT PROCESSOR (MENU PROCESSORS) PAGEE***********************************************************************’MENU�ITEM�COMMAND�PROCESSES*>*ˆThe�following�routines�are�the�individual�menu�item�routinesA*…that�when�combined�make�up�a�menu�for�each�GPIB�function.�TheseE*…menu�items�are�dispatched�by�the�menu�processor�at�either�interrupt;*…level�or�command�level.�All�registers�have�been�preserved?*…before�entering�except�for�D0�and�A0�which�may�always�be�used@*…as�work�registers.�The�following�register�description�entry�is$*…true�for�all�menu�item�processors:*-*’ENTER:‚A1�=�Base�Address�of�GPIBC�registers%*šA3�=�Address�of�IOS�Parameter�Block,*šA4�=�Address�of�Device�Control�Block�(DCB)-*šA5�=�Address�of�Channel�Control�Block�(CCB)1*šA6�=�Address�of�User's�Task�Control�Block�(TCB)* *’EXIT:ƒIf�D1�=�0…THENƒNo�errors*œELSE�D1�=�error�code9*�Note:�The�INITIO�processor�has�saved�all�registers�upon)*”entry�so�all�registers�are�free�to�use.*G*********************************************************************** ! TTL CLASS I MENU ITEM PROCESSORS PAGEF************************************************************************ˆCLASS�I�MENU�ITEM�PROCESSORS*1*’This�class�of�menu�items�initiate�various�types>*ˆof�I/O�in�both�DMA�and�non-DMA�modes.�All�class�I�menu�items-*ˆwill�generate�an�interrupt�after�execution.*F********************************************************************** **ˆPROCESSOR:�Write�Data*:*ˆPURPOSE:�To�setup�the�write�request�according�to�the�IOS0*‘options,�set�up�the�DMA�registers,�and�then�to*‘initiate�the�I/O.* WRITDATA:9 MOVEQ #1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>& MOVE.B D2,UNICMD(A1) initiate the I/O*3WRITD025�MOVEQ‚#ISTAOK,D1�set�return�status�to�O.K.*WRITDRTN�RTS…exit�write�data*<*ˆSpecial�processing�for�DMA�transfer�of�only�1�byte�(either&*ˆdata�or�termination�char.�sequence).*HWRITD030 BSETW #TERMINT,CSTQOFST(A6) let PROCMENU know no intrp expected‰BRA.S�WRITD025Žtake�good�exit**‚Write�Formatted�Mode;*ˆSince�DMA�write�requests�are�transfered�directly�from�the;*ˆusers�buffer,�and�Write�Formatted�EOR�characteristics�(if8*ˆenabled)�will�be�sent�out�by�the�termination�processor'*ˆupon�completion�of�this�DMA�transfer.*>WRITDFMT�MOVE.B�WEORFMT(A2),D1‚get�EOR�req�for�Write�Formatted2�BTST.L�#FIXTERM,D1‚fixed�length�transfer�enabled?�BEQ.S�WRITD060„branch�if�noF MOVE.W IOSFBWF(A2),D0 yes change transfer length to fixed requirement*G*ƒIf�any�of�the�CR,�LF,�or�EOS�characters�are�enabled,�EOI�(if�enabled);*ƒmust�be�held�off�for�this�transfer�and�transmitted�by�the*ƒtermination�processor.*WRITD060 MOVE.B D1,D37 AND.B #1<*„terminate�on�the�highest�priority�terminator�with�EOS�having:*„the�highest�priority�followed�by�LF�and�CR�respectively.*0READ115�MOVEQ�#0,D2Šclear�DMA�operation�register#�BTST.L�#EOSTERM,D1Šis�EOS�enabled?�BEQ.S�READD060�branch�if�no; MOVE.B IOSEOSR(A2),EOSCOMP(A1) yes, set EOS read character+�BRA.S�READD080�and�bypass�CR/LF�EOS�checks)READD060�BTST.L�#LFTERM,D1‚is�LF�enabled?�BEQ.S�READD070�branch�if�no1�MOVE.B�#LF,EOSCOMP(A1)…yes,�set�LF�as�terminator'�BRA.S�READD080�and�bypass�CR�EOS�check)READD070�BTST.L�#CRTERM,D1ƒis�CR�enabled?6*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*=*ˆFix�so�that�read�will�terminate�on�fixed�length�data�input. *ˆInserted�READD090�label�below.**BEQ.S�READD020�branch�if�no BEQ.S READD090*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>1�MOVE.B�#CR,EOSCOMP(A1)…yes,�set�CR�as�terminator@READD080�BSET.L�#EOSBIT,D2‚enable�EOS�detection�for�DMA�transfer2READD090�BTST.L�#FIXTERM,D1‰fixed�length�transfer?�BEQ.S�READD020�branch�if�no1�TST.W�D3“did�user�really�specify�a�fixed�length?3�BEQ.S�READD020�br�=�no,�use�IOSPB�specified�length;�CMP.W�D0,D3‘compare�user's�real�buffer�length�to�DEVICE'S!8�BGE.S�READD011Žbr�=�user's�buffer�size�.GE.�to�device's4�MOVEQ‚#ISTAADD,D1Šbr�=�his�buffer�is�not�big�enough�BRA.S�READDRTNŽabort*BREADD011�MOVE.W�D3,D0ˆset�up�DMA�for�device's�fixed�length�record!4READD020:�BSR�SETUPDMA†set�up�DMA�byte�count�and�MAR+�MOVE.B�#LON1,AUXCMD(A1)…set�up�Listen�mode.�BSET.L�#DMAWRITE,D2ˆenable�DMA�write�commmand6�BCLRW�#BIBIT,TMSMASK(A5)ƒdisable�BI�interrupts�on�DMA7�MOVE.W�TMSMASK(A5),D1†reset�interrupt�mask�on�TMS9914A MOVEP.W D1,INTR0(A1)*�MOVE.B�#GTS,AUXCMD(A1)…lower�the�ATN�lineB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *ˆ4/24/84ƒbwn*9*ˆMust�inhibit�TMS9914A‚interrupts‚during�DMA�operations.*2�BCLR.B�#VBIMENAB,CONTREG0(A1)‚disable�9914�intrps*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&�MOVE.B�D2,UNICMD(A1)‡initiate�the�I/O+�MOVEQ‚#ISTAOK,D1Šset�return�status�to�O.K.READDRTN�RTS�exit�read�data PAGE(*ˆPROCESSOR:�Send�Termination�Characters*6*ˆPURPOSE:�This�processor�will�send�the�EOR�characters,*‘in�DMA�mode�to�complete�the�pr% evious�write*‘formatted�transfer.* SENDTERM:%�MOVE.W�IOSOPT(A3),D1‚get�IOS�options.�AND.W�#IOPIMG,D1‚data�transfer�in�image�mode?>�BNE.S�SENDTRM9ƒbranch�if�yes�(no�EOS�characters�in�this�mode)*3�BSR�GETCNFIGƒget�ptr�to�current�configuration�dataB MOVE.B WEORFMT(A0),D1 get EOR characteristics for Write Formatted$ MOVE.B IOSEOSW(A0),D2 get EOS char.7�LEA.L�TERMBUF(A5),A0‚A0�<==�termination�buffer�pointer*?*ƒOnce�again,�just�as�in�the�read�processor,�the�EOR�characters8*ƒmay�be�multiply�set�and�are�software�priority�encoded.>*ƒIf�enabled,�the�CR�character�will�be�sent�out�first�followed1*ƒby�the�LF�character�and�then�the�EOS�character.** MOVEQ #0,D0 reset EOS string byte counter+�BTST.L�#CRTERM,D1ƒis�CR�character�enabled?�BEQ.S�SENDTRM2„branch�if�no0�MOVE.B�#CR,(A0)+‚store�CR�in�termination�buffer�ADDQ.L�#1,D0ˆbump�byte�count*3SENDTRM2�BTST.L�#LFTERM,D1ƒis�LF�character�enabled?�BEQ.S�SENDTRM4„branch�if�no?�MOVE.B�#LF,(A0)+‚yes,�store�LF�character�in�termination�buffer�ADDQ.L�#1,D0ˆbump�byte�count*;SENDTRM4�BTST.L�#EOSTERM,D1‚is�write�EOS�character�enabled?�BEQ.S�SENDTRM8„branch�if�no:�MOVE.B�D2,(A0)+ƒstore�EOS�character�in�termination�buffer�ADDQ.L�#1,D0ˆbump�count*1SENDTRM5 MOVEQ #0,D2 initialize DMA transfer type �SUB.L�D0,A0‡set�start�of�buffer*0*ˆSet�up�for�data�xfer:‰A0�<--�terminator�string*¦D0�=ƒstring�length*¦D1�=ƒEOR�options*¦D2�=ƒDMA�command*,�BRA�WRITD010†do�the�terminator�string�write*(SENDTRM8�TST.L�D0‚any�EOS�char.�to�send? BNE.S SENDTRM5*?SENDTRM9 BSETW #TERMINT,CSTQOFST(A6) set no interrupt expected!+�MOVEQ‚#ISTAOK,D1�set�return�status�to�O.K.)�RTS„exit�termination�character�processor  PAGE***ˆPROCESSOR:�Send�EOI*<*ˆPURPOSE:ƒSends�the�last�character�of�a�data�(OUT)�transfer3*“with�the�EOI�line�True�(uses�TMS9914�EOI�control)**SENDEOI:)�BSR�GETCNFIG�get�pointer�to�config.�data2�MOVE.B�WEORFMT(A0),D1‡get�Write�Formatted�options MOVE.W IOSOPT(A3),D0.�AND.W�#IOPIMG,D0Œwas�data�xfer�in�Image�mode?.�BEQ.S�SENDEOI2Žbr�=�NO,�use�Formatted�options*.�MOVE.B�WEORIMG(A0),D1‡get�Write�Image�options*ASENDEOI2�BTST�#EOITERM,D1„do�we�need�to�send�last�char.�with�EOI?�BEQ.S�SENDEOI4Žbr�=�no,�exit*-*ƒSend�the�last�data�byte�of�the�string�(DMA)*B�MOVE.B�#FEOI,AUXCMD(A1)…set�TMS9914�to�send�EOI�coincident�w/data;�MOVE.B�#$FE,BCNTLSB(A1)…set�up�BCR�to�1's�compl.�of�1�byteF�MOVE.B�#$FF,BCNTMSB(A1)…THE�MAR�IS�STILL�SET�FROM�PREVIOUS�XFER!!!!!!#�MOVEQ�#0,D2‘set�up�for�data�output(�BRA�WRITD022�go�do�the�output�operation*LSENDEOI4 BSETW #TERMINT,CSTQOFST(A6) set no intrp expected flag for PROCMENU>�BTSTW�#CAC_S,BUSACTIV(A5)ƒNo�more�output�is�to�take�place,�so?�BEQ.S�SENDEOI5Žif�we�are�a�Controller,�take�control�of�the�BUSH�MOVE.B�#TCA,AUXCMD(A1)†NOW!�cause�it�won't�be�done�at�normal�intrp�time*SENDEOI5 MOVEQ #ISTAOK,D1 RTS ‰PAGE*ˆPROCESSOR:�Untalk‚(UNT)*:*ˆPURPOSE:�To�send�the�universal�UNTALK�command�out�on�the*‘BUS�with�the�ATN�line�true.*SENDUNT:&�MOVE.B�#UNT_CMD,D1‚set�Untalk�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Unlisten‚(UNL)*<*ˆPURPOSE:�To�send�the�universal�UNLISTEN�command�out�on�the*‘BUS�with�the�ATN�line�true.*SENDUNL:(�MOVE.B�#UNL_CMD,D1‚set�Unlisten�command!�BRA�COMOUT…send�out�command�byte *'*ˆPROCESSOR:�Listen�Address�Group�(LAG)*;*ˆPURPOSE:�To�send�the�primary�listen�address�of�the�device1*‘specified�in�the�LUN�parameter�of�the�IOSPB�out#*‘on�the�BUS�with�the�ATN�line�true*SENDLAG:3�BSR�GETPADDR‚get�the�primary�address�of�the�device/�OR.B�#$20,D1ˆconvert�to�primary�listen�address!�BRA�COMOUT…send�out�command�byte *%*ˆPROCESSOR:�Other�Talk�Address�(OTA)*9*ˆPURPOSE:�To�send�the�primary�talk�address�of�the�device1*‘specified�in�the�LUN�parameter�of�the�IOSPB�out#*‘on�the�BUS�with�the�ATN�line�true*SENDOTA:K MOVE.B #TON0,AUXCMD(A1) UNTALK the GPIB, send aux command talk on% ly (cs=0)3�BSR�GETPADDR‚get�the�primary�address�of�the�device-�OR.B�#$40,D1ƒconvert�to�primary�talk�address!�BRA�COMOUT…send�out�command�byte ***ˆPROCESSOR:�Other�Secondary�Address�(OSA)*9*ˆPURPOSE:�To�send�the�secondary�address�specified�in�the.*‘secondary�address�parameter�of�the�IOSPB�out$*‘on�the�BUS�with�the�ATN�line�true.*SENDOSA:5�MOVE.B�IOSSAD-1(A3),D1‚get�desired�secondary�address �AND.B�#$1F,D1ƒmask�address�bits8 OR.B #PPE_CMD,D1 set into secondary address group range!�BRA�COMOUT…send�out�command�byte *,*ˆPROCESSOR:�Parallel�Poll�Unconfigure�(PPU)*:*ˆPURPOSE:�To�send�the�universal�parallel�poll�unconfigure1*‘command�out�on�the�BUS�with�the�ATN�line�true.t*SENDPPU:I�LEA.L�CONFINFO(A5),A0‚A0�<==�start�of�configuration�area�for�all�devices*;*‚Reset�the�current�parallel�poll�configuration�of�the�BUS.*0�MOVE.L�CNFIGPTR(A0),A2‚A2�<==�cnfig�ptr�for�BUS6�BSET.B�#PPIS,IOSPOLC(A2)‚set�Parallel�Poll�Idle�State> MOVE.B #0,PARLPOLL(A1) clear the GPIBC parallel poll register#�MOVE.B�#PPU_CMD,D1‚set�PPU�command+�BRA�COMOUTƒsend�the�command�out�on�the�BUS *'*ˆPROCESSOR:�Parallel�Poll�Enable�(PPE)*:*ˆPURPOSE:�To�send�parallel�poll�configuration�information3*‘(PPP�and�S�bits�set�up�in�PPE�parameter�of�IOSPB)*‘out�on�the�BUS.*SENDPPE:1�MOVE.B�IOSSAD-1(A3),D1‚get�PP�configuration�info"�AND.B�#$0F,D1†mask�PPP�and�S�bits*8*‚Set�the�parallel�poll�configuration�register�to�active *ˆand�set�the�new�configuration.*9�BSR�GETCNFIGƒA0�<==�ptr�to�configuration�area�for�device8�MOVE.B�D1,IOSPOLC(A0)‚save�in�device�configuration�area*3�OR.B�#PPE_CMD,D1„encode�bits�to�make�a�PPE�command+�BRA�COMOUT…send�out�command�byte�to�device ***ˆPROCESSOR:�Parallel�Poll�Configure�(PPC)*8*ˆPURPOSE:�To�send�the�universal�parallel�poll�configure0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDPPC:*�MOVE.B�#PPC_CMD,D1‚set�up�the�PPC�command!�BRA�COMOUT…send�out�command�byte *(*ˆPROCESSOR:�Parallel�Poll�Disable�(PPD)*6*ˆPURPOSE:�To�send�the�universal�parallel�poll�disable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDPPD:*�MOVE.B�#PPD_CMD,D1‚set�up�the�PPD�command!�BRA�COMOUT…send�out�command�byte *%*ˆPROCESSOR:�Serial�Poll�Enable�(SPE)*3*ˆPURPOSE:�To�send�the�universal�serial�poll�enable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDSPE:*�MOVE.B�#SPE_CMD,D1‚set�up�the�SPE�command!�BRA�COMOUT…send�out�command�byte *&*ˆPROCESSOR:�Serial�Poll�Disable�(SPD)*4*ˆPURPOSE:�To�send�the�universal�serial�poll�disable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDSPD:*�MOVE.B�#SPD_CMD,D1‚set�up�the�SPD�command!�BRA�COMOUT…send�out�command�byte *$*ˆPROCESSOR:�Clear�All�Devices�(DCL)*5*ˆPURPOSE:�To�send�the�universal�device�clear�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDDCL:*�MOVE.B�#DCL_CMD,D1‚set�up�the�DCL�command!�BRA�COMOUT…send�out�command�byte * *ˆPROCESSOR:�Local�Lockout�(LLO)*6*ˆPURPOSE:�To�send�the�universal�local�lockout�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDLLO:*�MOVE.B�#LLO_CMD,D1‚set�up�the�LLO�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Take�Control�(TCT)*5*ˆPURPOSE:�To�send�the�addressed�take�control�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDTCT:*�MOVE.B�#TCT_CMD,D1‚set�up�the�TCT�command!�BRA�COMOUT…send�out�command�byte *)*ˆPROCESSOR:�Selective�Device�Clear�(SDC)*7*ˆPURPOSE:�To�send�the�addressed�selective�device�clear/*‘command�out�on�the�BUS�with�the�ATN�line�true*‘to�all�current�listeners.*SENDSDC:*�MOVE.B�#SDC_CMD,D1‚set�up�the�SDC�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Go�To�Local�(GTL)*4*ˆPURPOSE:�To�send�the�universal�go�to�local�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDGTL:*�MOVE.B�#GTL_CMD,D1‚set�up�the�GTL�command!�BRA�COMOUT…send�out�command�byte *(*ˆPROCESSOR:�Group�Execute�Trigger�(GET)*& 6*ˆPURPOSE:�To�send�the�universal�group�execute�trigger0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDGET:*�MOVE.B�#GET_CMD,D1‚set�up�the�GET�command!�BRA�COMOUT…send�out�command�byte *)*ˆPROCESSOR:�Read�Serial�Poll�status�byte*0*ˆPURPOSE:�This�processor�is�part�of�the�COND_SP)*‘(Conduct�Serial�Poll)�menu.�Its�purpose+*‘is�to�set�up�for�Byte-In�interrupt‚to�get!*‘the�status�byte�desired�device.*READSP:)�BSR�MTFIFO’clear�the�FIFO�(VME-300�bug!)3�MOVEM.L�D0-D7/A0-A6,-(A7)ƒsave�regs�on�Trap�0�call1�LEA�SP_TO(PC),A0Œset�PAT�for�serial�poll�timeout"�MOVE.L�#1000,A1�wait�for�1�second MOVEQ #0,D1E�MOVE.B�CCBISR(A5),D1ˆget�intrp�level�from�high�byte�of�CCB�S.R.�word�AND.B�#$0F,D1�mask�off�garbage)�MOVE.L�A5,D2�set�CCB�address�as�PAT�I.D.�TR0$.RQPA�,‘start�timer�BRA.S�READSP1�br�=�timer�going*#�TR0$.KILLER�,�else�bomb�the�system !READSP1 MOVEM.L (A7)+,D0-D7/A0-A6/ BSETW #SPTIMER,BUSACTIV(A5) mark timer running4�MOVE.B�#LON1,AUXCMD(A1)…set�up�to�read�SP�data�byte3�MOVE.B�#GTS,AUXCMD(A1)†Drop�ATN�to�let�him�send�it#�MOVEQ�#ISTAOK,D1Œset�return�status RTS  PAGE .*ˆSerial�Poll�Read�Status�Byte�Timeout�Routine*=*ˆIf�a�user�has�requested�the�serial�poll�function,�a�timeout=*ˆerror�status�will�be�returned.‚Else�if�the�timeout�occurred;*ˆas�a�result�of�the�driver�polling�a�device�in�response�to<*ˆan�SRQ�interrupt,�the�Serial�Poll�status�byte�(in�the�CCB)<*ˆwill�be�set�to�zero�and�the�current�device�will�be�skipped*ˆin�the�polling�sequence.*+SP_TO:ƒMOVEM.L�A3-A5,-(A7)‹save�immed.�regs‰MOVE.L�D1,A5’set�CCB�pointer‰MOVE.L�QTAIL(A5),A07‰CMPA.L�QHEAD(A5),A0‹is�there�an�operation�in�progress?/‰BEQ.S�SP_TO2’br�=�no,�must�have�been�cancelled9‰BCLRW�#SPTIMER,BUSACTIV(A5)ƒwas�timer�already�cancelled?‰BEQ.S�SP_TO2’br�=�yes,�ignore*1*ˆSet�up�registers�to�look�like�VME-300�interrupt*"‰MOVE.L�DCBQOFST(A0),A4ˆA4�<--�DCB#‰MOVE.L�IPBQOFST(A0),A3ˆA3�<--�IOPB+‰MOVE.L�CCBCHB(A5),A1ŠA1�=�hardware�address<‰MOVE.B�#TCS,AUXCMD(A1)ˆtake�control�of�BUS�now,�since�there)‰MOVE.B�DATAIO(A1),D1Šis�no�intrp�coming!)‰BTSTW�#SRQPROG,BUSACTIV(A5)ƒSRQ�polling?‰BNE.S�SP_TO1’br�=�no,�user�I/O;‰BSETW�#SRQFAIL,CSTQOFST(A0)ƒmark�SRQ�poll�response�failure*SP_TO1ƒCLR.B�SRQBYTE(A5)�reset�status�byte3‰BSR�PROCMENU’and�process�as�normal�status�response'SP_TO2ƒMOVEM.L�(A7)+,A3-A5‹restore�regs‰RTE*?*ˆRoutine�to�cancel‚the�currently�running�Serial�Poll�I/O�timer* KILLSPTO:5‰BCLRW�#SPTIMER,BUSACTIV(A5)ƒclear�timer�running�flag3‰MOVEM.L�D0-D7/A0-A6,-(A7)…save�regs�on�Trap�0�call.‰LEA�SP_TO(PC),A0Žset�up�parms�to�cancel�timer‰SUBA.L�A1,A1’interval‰MOVE.L�A5,D2’set�CCB�I.D.1‰MOVE.B�CCBISR(A5),D1Šget�intrp�level�for�request#‰AND.L�#$0F,D1‘clear�excess�garbage(‰OR.L�#$8000,D1�options�=�cancel�request‰TR0$.RQPA�,“go�cancel$‰BRA.S�KILLSP1‘br�=�request�accepted$‰TR0$.KILLER�,‘else�crash�the�system*.KILLSP1‚MOVEM.L�(A7)+,D0-D7/A0-A6…restore�regs‰RTS  PAGE*1*ˆPROCESSOR:�Send�Auxiliary�Command�Buffer�String*4*ˆPURPOSE:�This�general�processor�will�simply�output-*‘what�ever�is�in�the�users�auxiliary�command+*‘string�buffer�out�on�the�BUS�with�the�ATN *‘line�true.* SENDAUXS:8�BSR�GETXFRAD‹get�physical�I/O�address�for�this�function,�MOVE.L�D6,A0‹A0�<==�starting�buffer�address1 MOVE.L D5,CMDCOUNT(A5) set command string length+�MOVE.B�(A0)+,D1Špreload�first�command�byte?�MOVE.L�A0,CMDBFPTR(A5)‚set�command�buffer�pointer�to�next�byte�BRA�COMCMD�send�command  " TTL CLASS I MENU ITEM SUBROUTINES PAGE**‚TLPROC*&*ˆTALKER/LISTENER�WRITE/READ�PROCESSOR*6*ˆThe�purpose�of�this�routine�is�to�determine�if�it�is9*ˆO.K.�to�initiate�the�current�Read/Write�command�at�this1*ˆtime.‚If�not,�the�current�operation�will�set�up%*ˆa�Task�level�I/O�operation�pending.*.*’ENTER:‚D0.B�=‚type�of�operation�-�Read/Write#*šA1�=�base�addr�of�GPIBC�registers'*šA3�=�address�of�IOCB�for�this�request*šA5�=�address�of�CCB*:*’EXIT:‚IF�CC�then�O.K.�to�initiate�I/O�(D0.b�=�& don'�care)*™ELSE�(IF�CS�AND�D1�=�0)2*œTHEN‚task�waiting�for�controller�to�make�request$*™ELSE�(IF�CS�AND�D1.B�=�error�code)*œTHEN�command�is�aborted* *’Register�Usageƒ0�1�2�3�4�5�6�7 *¡D�*�R�*�**¡A*TLPROC:5�BTSTW�#CAC_S,BUSACTIV(A5)„is�BUS�in�controller�mode?+�BNE.S�TLP20‘br�=�yes,�O.K.�to�initiate�I/O*=�BTSTW�#BUSIOP,BUSACTIV(A5)ƒis�there�INTRP�level�I/O�pending?6�BNE.S�TLP10‘br�=�yes,�go�check�for�matching�operation*6�MOVE.B�D0,IOPEND(A5)ˆelse�mark�Task�level�I/O�pendingD�MOVE.L�MENUCPOS(A5),MENUNPOS(A5)‚back�up�menu�pointer�to�re-execute(�MOVEQ�#ISTAOK,D1Œset�return�code�=�O.K. �BRA.S�TLP40‘and�exit�with�C�=�1*>TLP10�MOVE.B�IOPEND(A5),D2ƒD2�=�INTRP�level�I/O�pending�status MOVE.B D0,D11�AND.B�D2,D1‘D1�=�INTRP�^�TASK�I/O�pending�status1�BEQ.S�TLP30‘br�=�operation�type�mismatch�-�error*/�BTST�#SECONDAR,D2‹secondary�address�operation?*�BEQ.S�TLP20‘br�=�no,�O.K.�to�initiate�I/O* MOVEQ #SECMASK,D3 MOVE.B IOSSAD-1(A3),D1-�AND.B�D3,D1‘D1�=�task�requested�sec.�address0�AND.B�D2,D3‘D3�=�INTRP�level�pending�sec.�addr.�CMP.B�D1,D3‘are�they�the�same?4�BNE.S�TLP30‘br�=�no,�go�kill�task�requested�command*,TLP20�BSR�MTFIFO�O.K.�to�init.�I/O!�LET'S�GO'�BNE.S�TLP40‘oops,�hardware�malfunction*6�CLR.B�IOPEND(A5)Œclear�INTRP�level�I/O�pending�status/�BCLRW�#BUSIOP,BUSACTIV(A5)ƒand�associated�flag&�MOVEQ�#ISTAOK,D1Œset�return�code�O.K.�ANDI�#$FE,CCR�clear�Carry�bit RTS*'TLP30�MOVEQ�#ISTAIRPI,D1…set�error�code* TLP40�ORI�#$01,CCR‹set�Carry�bit RTS  PAGE* *ƒSETUPDMA*>*‡This�routine�is�used�by�the�READDATA,�WRITDATA,�and�SENDTERM<*„processors�to�set�up�the�memory�address�register�(MAR)�andA*„the�byte�count�register�(BCR)�on�the�MVME300�card.�These�simply8*„set�up�the�DMA�transfer�registers�but�initiate�no�I/O.*-*ˆENTER:‚A1�=�base�address�of�GPIBC�registers,*�A0�=�buffer�address�to�read/write�to/from."*�D0�=�number�of�bytes�to�transfer*!*ˆRegister�Usage:†0�1�2�3�4�5�6�7*šD‚P*šA‚P* SETUPDMA: MOVE.L D0,-(A7).�NOT.W�D0…convert�byte�count�to�1's�compliment-�MOVE.B�D0,BCNTLSB(A1)‚save�LSB�of�byte�count �LSR.W�#8,D0‡get�next�eigth�bits-�MOVE.B�D0,BCNTMSB(A1)‚save�MSB�of�byte�count*#�MOVE.L�A0,D0†D0�<==�buffer�addressB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*8*ˆThe�address�we�get�in�D0�is�the�address�as�seen�by�the *ˆdriver.4*ˆIf�we�are�using�dual�ported�ram‚on�the�VME/10,�and5*ˆif�this�address�is�in�on-board�ram,�then�it�must�be;*ˆtranslated�to�an�on-board�address�as�the�MVME300�sees�it.1*ˆWe�do�this�by�adding�the�RAM_SKEW�offset�to�the%*ˆaddress,�using�the�GO_OFF_BD�macro.* ‰GO_OFF_BD�D0*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>%�MOVE.B�D0,MARLSB(A1)‚save�LSB�of�MAR �LSR.L�#8,D0„get�next�eight�bits%�MOVE.B�D0,MARISB(A1)‚save�ISB�of�MAR �LSR.L�#8,D0„get�next�eight�bits%�MOVE.B�D0,MARMSB(A1)‚save�MSB�of�MAR MOVE.L (A7)+,D0 �RTS…exit PAGE**‚COMOUT*7*ˆSince�commands�bytes�(ATN�=�true)�can�not�be�sent�out=*„in�DMA�mode,�this�processor�will�send�out�a�byte�at�a�time.'*„It�assumes�that�the�ATN�line�is�true.*-*ˆENTER:„A1�=�base�address�of�GPIBC�registers*’A5�=�address�of�CCB *’D1.B�=�command�byte�to�be�sent*ä ÍEÖDÞ<æ:î8ö:þ-54.1&J.M6?>:F/N2V:^=f>n6vD~7† !*ˆRegister�Usage:„0�1�2�3�4�5�6�7*˜D„P‡P*˜A„P*COMOUT:F�MOVE.L�#1,CMDCOUNT(A5)ƒset�command�count�to�1�for�interrupt�processor*C*‚Entry�Point�used�by�the�Command�Out/Data�Out�and�the�Command�Out/*‚Data�In�processors**ƒspace�in�the�CCB�for�new�block�and�storing�new�configuration=*ƒinformation.‚In�actuality,�the�space�for�all�configurations<*ƒattached�to�this�CCB�have�already�been�allocated�and�it�is+*ƒjust�a�matter�of�adjusting�some�pointers.=*‡Since�IOI�is�initiating�this�call,�A1�looks�like�the�user's?*ƒbuffer�but�is�really�apointer�to�the�default�configuration�of *ƒthe�DCB.;*‡The�BUS�activity�flag�(BUSACTV)�is�set�up�at�this�time�to$*ƒindicate�its�initial�startup�mode.*+�MOVE.L�A2,-(A7)‚save�address�of�GPIBC�regs6�LEA.L�CONFINFO(A5),A2‚configuration/DCB�pointer�table MOVEQ #0,D0'�MOVE.B�DCBCDV(A4),D0‚get�device�number"�ASL.L�#3,D0‡calculate�table�index@�MOVE.L�NEXTCNFG(A5),A0‚A0�<==�next�available�configuration�area=�MOVE.L�A0,CNFIGPTR(A2,D0.L)‚set�configuration�ptr�for�device3�MOVE.L�A4,DVDCBPTR(A2,D0.L)„set�DCB�ptr�for�device*I*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*8*ˆ10/16/84‚SET�SERVICE�REQUEST�WAITING�FLAG�TO�CATCH�ANY2*’SRQ'S�PENDING�ON�THE�BUS�AT�TIME�OF�BOOT/STARTUP6*’SINCE�THAT�SRQ�INTERRUPT�WILL�BE�LOST�IN�THE�TMS9914$*’AT�TIME�OF�CHANNEL�INITIALIZATION.*‰BSETW…#SRQWAIT,BUSACTIV(A5)*I*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>J�MOVE.W�IOSVARL+DCBDEV(A4),D0„D0�<==�length�of�variable�configuration�area �BTST�#0,D0…odd�number�of�bytes?�BEQ.S�CDEVA„branch�if�noB�ADDQ�#1,D0…allocate�in�even�by�amounts�for�addressing�consistency*KCDEVA�LEA.L�IOSILN(A0,D0.W),A2‚calculate�total�length�of�configuration�areaD�MOVE.L�A2,NEXTCNFG(A5)ƒupdate�next�available�configuration�area�ptr.�MOVE.L�(A7)+,A2‚restore�address�of�GPIBC�regs*?*ƒThe�next�check�will�determine�if�the�GPIB�is�being�configured4*ƒwith�system�controller�capabilities.‚If�this�is�so=*ƒthen�the�bus�interface�will�take�control�of�the�BUS�at�this?*ƒpoint.‚Otherwise�its�mode�will�be�set�according�to�the�deviceB*ƒattributes�word�(IOSATW)�passed�in�the�configuration�data�block.E*ƒIf�the�BUS�is�configured�for�Talker/Listener�only,�NO�OTHER�DEVICESI*ƒWILL�BE�ALLOWED�TO�BE�CONFIGURED�AT�SYSTEM�INTIALIZATION�TIME.‚Att( emptsG*ƒto�access�these�devices�at�a�later�time�will�cause�a�DEVICE�NOT�READY(*ƒerror�condition�to�be�returned�by�IOS.*&�TST.B�DCBCDV(A4)”configuring�the�BUS?�BNE.S�COMNCNFG”branch�if�no MOVE.L A1,-(A7)9�BSR�RESETIO—correct�for�intrps�to�an�un-attached�channel MOVE.L (A7)+,A1A�BTSTW�#IOASCTC,IOSATW(A1)‰is�BUS�being�config.�with�S.C.�capab�?�BEQ.S�COMNCNFG•branch�if�no*2*ˆElse�test�interface�for�compatible�configuration*:*ˆNOTE!!!‚The�device�will�be�stripped�of�system�controller8*ˆcapabilities�without�notifying�the�caller�on�the�first9*ˆtime�configuration�only.�This�allows�a�successful�first:*ˆtime�configuration�and�will�not�mark�this�device�OFFLINE*ˆupon�return.*.�TST.B�ADDRREG(A2)‘is�MVME300�card�in�SC�mode?�BPL.S�CDEVB—branch�if�yes9�BCLRW�#IOASCTC,IOSATW(A1)‰do�not�allow�S.C.�capabilities BRA.S COMNCNFG*>*ˆSoftware�&�hardware�S.C.�configurations�agree,�TAKE�CONTROL!*CDEVB MOVE.L A1,-(A7)#�MOVE.L�A2,A1•set�up�A1�for�SENDIFC&�BSR�SENDIFC–Take�control�of�BUS,�NOW! MOVE.L (A7)+,A1*/*‚Continue�with�normal�configuration�processing*"*ˆCheck�for�unsupported�attributes*MCOMNCNFG�MOVE.W�#CECUAP,D2ƒpreload�unsupported�attribute/parameter�error�code*3�MOVE.W�#NVALBATM,D0ƒget�mask�of�invalid�attributes8�AND.W�IOSATM(A1),D0ƒtrying�to�change�invalid�attribute?"�BNE�CNFGERR†branch�if�yes�(error)*1�MOVE.W�#NVALBPRM,D0‚get�mask�of�valid�parameters8�AND.W�IOSPRM(A1),D0‚trying�to�change�invalid�parameter?"�BNE�CNFGERR…branch�if�yes�(error)*9*‚Set�the�attributes�into�the�user's�configuration�buffer"*‚that�he�does�not�want�to�change.*0�MOVE.W�IOSATM(A1),D0‚D0�<==�his�attributes�mask;�AND.W�D0,IOSATW(A1)ƒZero�out�the�attributes�of�his�that�he9�NOT.W�D0Ždoesn't�want�to�change,�zero�out�the�attributes=�AND.W�IOSATW(A0),D0ƒof�mine�that�he�does�want�to�change,�and.�OR.W�D0,IOSATW(A1)„combine�them�in�his�space.* *‚Do�the�same�for�the�parameters*3COMN010�MOVEQ�#0,D0ƒbe�sure�upper�16�bits�are�clearK�MOVE.W�IOSPRM(A1),D0‚D0�<==�mask�of�parameters�that�he�does�want�to�change7�MOVEM.L�A0-A2,-(A7)„save�configuration�block�addresses4�LEA.L�IOSREC(A0),A0„A0�<==�addr�of�1st�param�in�CCB@�LEA.L�IOSREC(A1),A1„A1�<==�addr�of�1st�param�in�user�data�block2�LEA.L�PAR_SIZ,A2…A2�<==�addr�of�table�param�sizes*NXTPARM MOVEQ #0,D11�MOVE.B�(A2)+,D1‚get�#�of�bytes�in�next�parameter%�BEQ.S�CHKPARM„branch�if�end�of�table*+�LSR.W�#1,D0…want�to�change�next�parameter?�BCS.S�INCPARMƒbranch�if�yesA�SUBQ�#1,D1†does�not�want�to�change�it�so�move�parameter�from�CCB2*�to�the�user's�buffer�so�that�he�will�have�a�copy)MOVPARM�MOVE.B�(A0)+,(A1)+‚move�next�byte)�DBRA�D1,MOVPARMƒuntil�byte�count�expires'�BRA.S�NXTPARMƒcheck�the�next�parameter*?INCPARM�ADD.L�D1,A0‚he�does�want�to�change�it�so�leave�his�copy4�ADD.L�D1,A1‰alone�and�just�go�to�the�next�parameter BRA NXTPARM*>*ƒCheck�to�see�if�he's�doing�any�configuration�that�is�illegal*:CHKPARM�MOVEM.L�(A7)+,A0-A2‚restore�configuration�pointers=�MOVE.W�#CECIPA,D2‚preload�invalid�primary�address�error�code*2�MOVE.B�IOSPRMA(A1),D0‚get�current�primary�address0�CMP.B�#$1E,D0…valid?�(MUST�BE�0<=�ADDR.�<=�$1E)�BHI�CNFGERR…branch�=‚error*"�TST.B�DCBCDV(A4)‚is�this�the�bus?�BNE.S�CHKPRM2…branch�if�no*=*‚Check�to�see�if�the�primary�address�configured�matches�what-*‚is�set�on�the�switches�of�the�MVME300�card.*C�MOVE.B�ADDRREG(A2),D1ƒD1�<==�primary�addr�read�from�board�switches+�NOT.B�D1‰use�complement�of�switch�register �AND.B�#$1F,D1„mask�primary�addr?�CMP.B�#$1F,D1„is�switch�register�=�$1F�(INVALID�GPIB�ADDRESS!)C�BNE.S�CHKPRM1„BR�=�no,�use�hardware�switch�register�as�BUS�address)�MOVE.B�D0,D1…else�use�SYSGEN�BUS�address*@CHKPRM1�MOVE.B�D1,ADDRREG(A2)‚set�TMS9914A�primary�addr�register, MOVE.B D1,IOSPRMA(A1) update config. buffer9�BTSTW�#IOSPOLCB,IOSPRM(A1)‚local�pp�configuring�the�bus?�BEQ.S�CHKPRM2ƒbranch�if�no*=�MOVE.B�IOSPOLC(A1),D0‚D0�<==�new�parallel�poll�configuration/�BMI.S�CHKPRM2ƒbr�=�no) �configuration�set�for�PP;�AND.B�#$1F,D0ƒmask�PPP,�S�and�I�bits,�BUS�is�in�PPSS�state+�MOVE.B�D0,IOSPOLC(A1)‚save�in�users�buffer+�BSR�SETPPREG‚set�up�parallel�poll�register*JCHKPRM2�ANDI.L�#$7FFFFFFF,IOSSAMR(A1)ƒmask�out�bit�31�of�both�the�Read�and<�ANDI.L�#$7FFFFFFF,IOSSAMW(A1)ƒWrite�Secondary�Address�masks*<*‚If�we�make�it�to�here�everything�has�been�validated�and�is:*‚OK�with�the�fixed�portion�of�the�configuration�block.�If<*‚the�user�has�defined�a�variable�configuration�area,�do�the*‚necessary�sequences�for�that.*C�TST.W�IOSVARL+DCBDEV(A4)‚is�there�any�variable�configuration�info?�BEQ.S�OKCNFG†branch�if�no*<�MOVE.W�#CECVARL,D2ƒpreload�variable�config�param�error�code?�MOVE.L�IOSFMTA+DCBDEV(A4),D0ƒget�pointer�to�user�I/O�formatter4�BEQ.S�OKCNFG�branch�=�no�user�defined�I/O�formatter MOVE.L D0,A2A�TST.L�USER_CNF(A2)†is�a�variable�config�parameter�routine�given?�BEQ.S�OKCNFGŽbranch�if�noF MOVEM.L D1-D7/A0-A6,-(A7) save everything except user's return status<�JSR�USER_CNF(A2)‹execute�user�defined�configuration�routine. MOVEM.L (A7)+,D1-D7/A0-A6 restore environment�TST.B�D0�Any�errors?�BNE.S�CNFGERR…branch�if�error*>*‚The�only�thing�that�remains�now�is�sec.�addr.�validation�andD*‚to�update�the�TMS9914A�interrupt�mask�register�to�enable�secondaryI*‚addressing�if�valid�secondary�addresses�were�newly�defined�for�the�BUS.*8OKCNFG�TST.L�IOSSAMR(A1)‚any�sec.�Read�addr's�specified?�SNE�D0“D0�=�Yes/No3�TST.L�IOSSAMW(A1)ˆany�sec.�Write�addr's�specified?�SNE�D1“D1�=�Yes/No$�MOVEQ�#CECSADR,D2ˆpreset�error�code$�EOR.B�D0,D1ŽBoth�must�be�specified! �BNE�CNFGERRŽelse�it�is�an�error*" TST.B DCBCDV(A4) is this the BUS? BNE.S OKCNFG3 br = noB�MOVE.W�TMSMASK(A5),D0‚set�the�current�state�of�the�9914A�mask�reg5 BSET #APTBIT,D0 set up to enable secondary adressing0 TST.L IOSSAMR(A1) any sec read addresses valid?�BNE.S�OKCNFG2ƒbranch�if�yes:�BCLR�#APTBIT,D0ƒelse�disable�secondary�address�interrupts5OKCNFG2�MOVE.W�D0,TMSMASK(A5)‚save�in�mask�status�reg8 MOVEP.W D0,INTR0(A2) update TMS9914A interrupt mask reg*OKCNFG3 MOVEQ #0,D0F�MOVE.W�IOSVARL+DCBDEV(A4),D0„D0�<==�length�of�variable�parameter�area@�ADD.L�#(IOSILN-IOSATW)/2-1,D0ƒadd�in�rest�of�configuration�area*�MOVEM.L�A0/A1,-(A7)ƒsave�start�of�buffers5�LEA.L�IOSATW(A0),A0‚set�pointers�to�start�of�buffers LEA.L IOSATW(A1),A1*?OKCNFG5�MOVE.W�(A1)+,(A0)+‚copy�his�validated�buffer�to�the�CCB#�DBRA�D0,OKCNFG5„configuration�area*5�MOVEM.L�(A7)+,A0/A1ƒrestore�start�of�buffer�pointers.�EXG�A0,A1‰set�A0�=�his�buffer,�A1�=CCB�buffer5�BSR.S�STATYP1…set�up�status�and�configuration�headerF�MOVE.B�#1,DCBCCF(A4)ƒset�flag�indicating�that�a�CONFIGURE�or�a�CHANGE *®DEFAULT�CONFIGURATION�was�done*A*ˆThis�test�is�performed�at�this�time�so�an�initial�configurationC*ˆwill�occur�even�if�there�is�a�S.C.�switch/sysgen�incompatibility.*-�TST.B�DCBCDV(A4)‚are�we�configuring�the�BUS?#�BNE.S�OKCNFG7‚branch�=�not�the�bus*2�EXG�A0,A1ƒset�A0�=�CCB�buffer�and�A1�=�his�buffer4�MOVEQ‚#CECSCE,D2ƒpreload�invalid�S.C.�configurationB�BTSTW�#IOASCTC,IOSATW(A0)‚are�we�configuring�for�S.C.�capability?6 BEQ.S OKCNFG7 branch = no, else test hardware config.9 TST.B ADDRREG(A2) is the MVME300 card switch in SC mode?'�BMI.S�CNFGERR‚branch�=�no,�go�to�error*0OKCNFG7�MOVEQ‚#ISTAOK,D1‚set�return�status�to�OK �RTSƒexit*CCNFGERR MOVE.B D2,IOSCEC(A1) save specific configuration error codeB�MOVEQ‚#ISTACNF,D1‚set�invalid�configuration�for�device�error�code(�RTSƒexit�common�configuration�processor  TTL COMMON SUBROUTINES PAGE**‚STATYP*A*ˆThis�routine�is�used�by�CONFIGURE,�CHANGE�DEFAULT�CONFIGURATION;*…and�REQUEST�STATUS�processors�to�store�the�current�status8*…information�in�the�standard�configuration�area�header.*,*ˆENTER:‚A2�=�base�address�of�GPIB�registers*�A4�=�address�of�DCB*�A5�=�address�of�CCB*5*ˆEXIT:ƒA0�=�address�of�configuration�area�for�device*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�* *›A�R‡P�P*ST) ATYP:0�BSR.S�GETCNFIGƒA0�<==�current�configuration�ptr*STATYP1: MOVEQ #0,D0"�TST.B�DCBCDV(A4)‰is�this�the�BUS?�BNE.S�STATYP2Œbr�=�no'�MOVE.B�ADDRSTAT(A2),D0ƒget�GPIB�status�AND.B�#$FE,D0Œmask�out�garbage*6STATYP2 MOVE.B D0,IOSDST(A0) put dev. status in buffer9 MOVE.B DCBDEV+IOSCTP(A4),IOSCTP(A0) set the channel type8 MOVE.B DCBDEV+IOSDTP(A4),IOSDTP(A0) set the device type/ MOVE.B #IODGPIB,IOSDRC(A0) set the driver code �RTSƒexit  PAGE* *„SETPPREG*:*ˆThis�subroutine�will�set�or�clear�the�desired�bit�of�the?*…parallel�poll�register�for�when�a�parallel�poll�is�performed.A*…If�both�the�Individual�Status�bit�and�the�Sense�bits�are�equal,>*…the�bit�specified�will�be�set�in�the�parallel�poll�register.8*…otherwise�the�parallel�poll�register�would�be�cleared.*;*ˆThe�PPreg�will�not�be�set�if�the�system�is�in�PPIS�state.**,*ˆENTER:‚A0�=�pointer�to�configuration�table*�A5�=�address�of�CCB**ˆEXIT:ƒno�errors�return*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�*ƒ**›AƒP* SETPPREG:!�MOVE.L�A1,-(A7)‚Save�environment MOVEQ #0,D23 MOVE.B IOSPOLC(A0),D0 get current PP configuration3�BMI.S�SETPR025ˆbr�=�In�PPIS�state,�don't�set�PPreg'�BTST�#PPSENSE,D0‚is�the�sense�bit�set?�BNE.S�SETPR020‚branch�if�yes*:*‚The�sense�bit�is�equal�to�zero,�so�the�individual�status8*‚must�also�be�zero�to�set�the�parallel�poll�status�to�1*2�BTST�#INDIVST,D0‚is�the�individual�status�bit�set�BNE.S�SETPR015ƒno*$SETPR010�AND.L�#7,D0‚mask�bit�number'�BSET�D0,D2‚set�to�parallel�poll�status*6SETPR015�MOVE.L�CCBCHB(A5),A1‚A1�<==�ptr�to�GPIBC�regs:�MOVE.B�D2,PARLPOLL(A1)‚store�results�in�Parallel�poll�reg$�MOVE.L�(A7)+,A1ƒrestore�environment SETPR025 RTS*:*‚The�sense�bit�has�been�determine�that�it�is�equal�to�one*7SETPR020�BTST�#INDIVST,D0‚is�individual�status�bit�set?�BNE.S�SETPR010„branch�if�yes�BRA.S�SETPR015„no,�exit PAGE* *ƒGETCNFIG*5*ˆGet�a�pointer�to�the�current�configuration�area�for*…the�desired�device.**ˆENTER:‚A4�=�address�of�DCB*�A5�=�address�of�CCB*5*ˆEXIT:ƒA0�=�address�of�configuration�area�for�device*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�* *›A�R‡P�P* GETCNFIG: MOVEQ #0,D0<�MOVE.B�DCBCDV(A4),D0ƒD0�<==�device�number�of�desired�deviceC�LEA.L�CONFINFO(A5),A0ƒA0�<==�base�addr�of�configuration�table�ptrs!�ASL.L�#3,D0‡Two�long�words/entryB�MOVE.L�CNFIGPTR(A0,D0.L),A0‚A0�<==�base�addr�of�config�for�device �RTSƒexit * *ƒGETXFRAD*7*‰This�routine�will�simply�pull�off�the�physical�buffer *‡addresses�from�the�GPIB�queue.**�ENTER:‚A5�=�address�of�CCB*"*�EXIT:‚D4�=�primary�buffer�length*–D5�=�secondary�buffer�length/*–D6�=�physical�addr�of�secondary/config�buffer&*–D7�=�physical�addr�of�primary�buffer*!*‘Register�Usage:„0�1�2�3�4�5�6�7 *¡DŠR�R�R�R*¡A‚** GETXFRAD:.�MOVE.L�QTAIL(A5),A0…get�current�queue�pointer;�MOVE.L�PBPAOFST(A0),D7‚D7�<==�physical�primary�buffer�addrD�MOVE.L�SBPAOFST(A0),D6‚D6�<==�physical�secondary/config�buffer�addr MOVEQ #0,D54�MOVE.W�SBLNOFST(A0),D5‚D5�=�secondary�buffer�length MOVEQ #0,D42�MOVE.W�PBLNOFST(A0),D4‚D4�=�primary�buffer�length �RTS‚exit PAGE****ˆSET�UP�INDEX�(POINTER)�TO�FUNCTION�TABLE*ˆBASED�UPON�IOSPB�FUNCTION**ˆON�ENTRY:�A3�=>�IOCB*'*ˆON�EXIT:‚D2.W�IS�TABLE�OFFSET�(INDEX)+*’D1.B�&��=�OPERATION�STATUS�(�0�=�O.K)*8*‚Find�the�function�in�the�table�of�valid�GPIB�functions*GETCMDP:!ˆMOVEM.L�A0/D0/D6,-(A7)�save�regs5�MOVE.W�#NUMCMDS-1,D0ƒnumber�of�valid�GPIB�commands-14�LEA.L�IOSCMDTB(PC),A0ƒset�ptr�to�GPIB�command�table1�MOVE.W�IOSFCT(A3),D6ƒpick�up�function�from�IOSPB8�MOVEQ‚#ISTAIF,D1ƒset�invalid�command�error�just�in�case*&GETCMD50�CMP.W�(A0)+,D6ƒfound�command?.�DBEQ�D0,GETCMD50ƒbranch�if�no,�look�some�more*,�BNE.S�GETCMDX„exit�with�error,�end�of�table4�MOVE.W�#NUMCMDS-1,D2ƒcalculate�relative�table�index�SUB.W�D0,D2‚D2�<==�table�index"�ASL.W�#1,D2‚Calculate�word�offset*0�MOVEQ‚#ISTAOK,D1�se* t�process�O.K.�return�status*GETCMDX TST.B D1 set return condition code$ MOVEM.L (A7)+,A0/D0/D6 restore regs RTS* 6 TTL GPIB DRIVER - COMMON SUBROUTINES (QUEUE HANDLING) PAGE**‚POP�GPIB�QUEUE�ENTRY*6*ˆIf�I/O�is�aborted�or�an�operation�is�completed,�this9*…routine�will�pop�that�operation�from�the�GPIB�queue�and9*…update�the�necessary�queue�pointers.�It�is�assumed�that:*…the�caller�has�previously�inhibited�all�interrupts�since*…this�is�critical�processing.**’ENTER:ƒA5�-�address�of�CCB*#*’EXIT:ƒIF�„THEN‚queue�is�empty)*œELSE‚queue�still�has�at�least�one�entry*!*ŽRegister�Usage:ƒ0�1�2�3�4�5�6�7*žD *žA�*�*‡P* POPGPIBQ:1�LEA.L�GPIBQEND(A5),A0‚A0�<==�ptr�to�end�of�queue.�MOVE.L�QTAIL(A5),A1„get�current�queue�pointer2�CMPA.L�QHEAD(A5),A1„is�there�an�entry�to�POP�off?,�BEQ.S�POPG15ŒBR�=�no,�exit�with�proper�?�ADDA.L�#GPIBQLEN,A1„advance�pointer�by�length�of�a�queue�entry�CMPA.L�A0,A1…at�end�of�queue?�BNE.S�POPG10ƒno*%* time to wrap around to top of queue*5�LEA.L�GPIBQ(A5),A1…set�queue�pointer�to�top�of�queue*APOPG10�MOVE.L�A1,QTAIL(A5)ƒupdate�current�operation�queue�pointer<�CMPA.L�QHEAD(A5),A1ƒset�condition�for�empty/not�empty�queue POPG15 RTS‰PAGE* *ƒPSHGPIBQ*9*ˆThis�routine�is�used�regardless�of�whether�the�queue�is?*…busy�or�not.�It�will�place�in�the�GPIB�queue�all�the�pointers=*…necessary�to�execute�this�command�when�its�time�comes.�LikeD*…the�POPGPIBQ�routine�it�also�assumes�that�the�caller�has�inhibited*…interrupts�before�entering.**’ENTER:‚A3�-�address�of�IOSPB*šA4�-�address�of�DCB*šA5�-�address�of�CCB*šD4�-�primary�buffer�length*šD5�-�secondary�buffer�length&*šD6�-�physical�addr�of�primary�buffer/*šD7�-�physical�addr�of�secondary/config�buffer**’IF�„THENƒno�errors*•ELSE„queue�is�full*!*�Register�Usage:ƒ0�1�2�3�4�5�6�7 * D�*‡P�P�P�P* A�*�PƒP�P�P�P* PSHGPIBQ:!�MOVE.L�A1,-(A7)ƒsave�environment4�LEA.L�GPIBQEND(A5),A1„A1�<==�end�of�GPIB�queue�area4�MOVE.L�QHEAD(A5),A0†A0�<==�next�available�queue�ptr*�CLR.W‚CSTQOFST(A0)†set�entry�status�to�OK+�MOVE.L�A4,DCBQOFST(A0)ƒsave�address�of�DCB6�MOVE.L�A3,IPBQOFST(A0)ƒsave�physical�address�of�IOSPB?�MOVE.L�D7,PBPAOFST(A0)ƒsave�physical�address�of�primary�bufferI�MOVE.L�D6,SBPAOFST(A0)ƒsave�physical�address�of�secondary/config.�buffer2�MOVE.W�D4,PBLNOFST(A0)ƒsave�primary�buffer�length4�MOVE.W�D5,SBLNOFST(A0)ƒsave�secondary�buffer�length;�ADDA.L�#GPIBQLEN,A0„increment�by�length�of�one�queue�entry"�CMPA.L�A1,A0…time�to�wrap�around?�BNE.S�PSHQ010„branch�if�no*0�LEA.L�GPIBQ(A5),A0‚set�ptr�to�top�of�queue�area**PSHQ010�CMPA.L�QTAIL(A5),A0‚is�queue�full?5�BEQ.S�PSHQRTN‚yes,�but�this�should�not�have�happened4 MOVE.L A0,QHEAD(A5) update next available queue ptr4�MOVEQ�#1,D0‚set�condition�code��for�O.K.�return*PSHQRTN�MOVE.L�(A7)+,A1ƒrestore RTSA TTL GPIB DRIVER - COMMON SUBROUTINES (VALIDATE OPERATIONAL MODE) PAGE**‚VALIDATE�OPERATIONAL�MODE*9*ˆThis�routine�will�be�called�at�the�point�when�a�command:*ˆis�about�to�be�scheduled�for�I/O�initiation.�The�purpose;*ˆis�to�determine�if�the�BUS�is�in�the�proper�mode�for�this:*ˆcommand�and�to�determine�if�the�BUS�or�device�(depending:*ˆon�who�this�command�is�directed�to)�has�the�capabilities3*ˆ(if�any�are�necessary)�to�perform�this�operation.*3*’ENTER:‚A3�=�address�of�IOSPB�for�current�function*šA4�=�address�of�the�DCB*šA5�=�address�of�the�CCB%*šD2.W�=�index�of�command�in�VALPARTB*'*’EXIT„D1�=�error�code�(0�if�no�errors)* *�Register�Usage…0�1�2�3�4�5�6�7 *¡D�*�R�*�*�**¡A�**VALOPER:F�LEA.L�VALPARTB(PC),A0ƒA0�<==�base�address�of�command�validation�tableD�MOVE.W�0(A0,D2.W),D4‚D4�<==�bit�map�of�necessary�command�parameters*?�CMP.B�#XDSGDEV,IOSDTP+DCBDEV(A4)‚is�this�command�for�a�device?�BNE.S�VALOP050ƒbranch�if�no*@*‚Since�this�command�is�directed�towards�a�device�and�the�valuesB*‚in�VALPARTB�are�relative�to�the�BUS,�the�READ/WRITE�bits�take�onA*‚the�opposi* te�meaning�than�they�did�for�the�BUS.‚For�example,�ifB*‚there�is�a�write�command�to�a�device,�the�value�in�VALPARTB�willB*‚indicate�that�the�talker�ability�(VALTALK)�will�be�necessary�forA*‚this�command.‚However,�this�bit�was�set�relative�to�the�BUS.�SoA*‚if�the�write�command�is�directed�to�a�device,�this�requires�theC*‚BUS�to�be�in�the�talker�mode�and�the�device�to�be�in�the�listenerB*‚mode.‚It�is�for�these�reasons�that�the�TALK�and�LISTEN�abilitiesA*‚(VALTALK�and�VALLIST�respectively)�are�exclusive�or'd�with�'11' *‚so�as�to�invert�their�meaning.*B�MOVEQ�#VALTALK+VALLIST,D0‚set�up�specific�capabilities�to�look�at MOVE.B D0,D39�AND.B�D4,D3�D3�=�Talker/Listener�capability�requirements#�BEQ.S�VALOP050�br�=�none,�continue�CMP.B�D0,D3�are�both�required?-�BEQ.S�VALOP050�br�=�yes,�so�no�need�to�alter6�EOR.W�D0,D4�else,�change�meaning�relative�to�a�device*C*ƒNow�that�we�have�the�meaning�of�the�ability�bits�correct�relative;*ƒto�the�command,�check�the�current�attributes�word�for�theB*ƒspecified�device�to�see�if�the�device�or�BUS�is�capable�of�doing*ƒthat�command.*,VALOP050�MOVE.W�D4,D2‡D2�<==�Working�bit�mapH�AND.W�#VALTALK+VALLIST+VALCTL+VALSCTL+VALSRQ,D2‚any�abilities�required?�BEQ.S�VALOP100�branch�if�no8�BSR�GETCNFIG�get�a�pointer�to�user's�configuration�area-�MOVE.W�D2,D3�D3�<==�current�device�abilities5�AND.W�IOSATW(A0),D3ˆmask�abilities�that�are�required;�CMP.B�D2,D3�does�this�device/BUS�have�the�right�abilities.�BNE.S�VALOP250�branch�if�no*C*‚Now�that�the�ability�has�been�verified,�check�to�see�that�the�BUS,*‚is�in�the�necessary�mode�for�this�command.**VALOP100�MOVE.W�D4,D2…save�current�bit�map?�AND.W�#VALTMOD+VALLMOD+VALCMOD+VALBTLM,D2‚any�modes�necessary?�BEQ.S�VALOP500ƒbranch�if�no*3�MOVE.W�BUSACTIV(A5),D0‚D0�<==�current�bus�activity3�CMP.B�#XDSGDEV,IOSDTP+DCBDEV(A4)‚is�this�a�device?�BEQ.S�VALOP200‚branch�if�yes8�BTST�#BVALBTLM,D4‚do�we�need�to�be�in�T/L�mode�for�BUS?�BNE.S�VALOP300‚branch�if�yes*5VALOP200�BTST�#CAC_S,D0ƒis�the�BUS�in�controller�mode/�BNE.S�VALOP500‚branch�if�yes,�everything�is�OK*"*‚ERROR:�A�mode�error�has�occurred*?VALOP250�MOVEQ�#ISTAIVCM,D1ƒset�invalid�command�mode�error�code�BRA.S�VALOPRTNƒexit�with�error*6VALOP300�BTST�#CAC_S,D0‚is�the�BUS�in�controller�mode?F�BNE.S�VALOP250‚branch�if�yes�-�error�-�can(t�be�in�controller�for�cmd*?*‚Since�this�command�is�directed�to�the�BUS,�it�may�require�the>*‚BUS�to�be�either�in�Talker�or�Listener�mode.‚Check�to�see�if>*‚those�modes�are�required�for�this�command�and�if�so�check�to=*‚see�that�the�BUS�is�in�the�appropriate�mode.‚The�proper�T/L>*‚mode�check�is�skipped�if�the�BUS�is�IDLE.‚The�operation�will#*‚subsequently�be�queued�in�TLPROC.*4 AND.W #1<*‚This�check�will�see�if�a�secondary�address�is�to�be�verified<*‚for�this�command�and�check�against�valid�device�addresses.*?VALOP500�BTST�#BVALSADR,D4ƒcheck�GPIB�device�secondary�address?�BEQ.S�VALOP600ƒbranch�if�no*3 CMP.B #XDSGDEV,IOSDTP+DCBDEV(A4) Is this a device? BEQ.S VALOP520*?�BTSTW�#APTBIT,TMSMASK(A5)‚operating�in�secondary�address�mode?$�BEQ.S�VALOP250‚branch�if�no�(error)*5VALOP520�BSR�GETCNFIG‰get�configuration�ptr�of�deviceD�MOVE.L�IOSSAMR(A0),D2„D2�<==�bit�mask�of�configured�valid�read�S.A./�BTST‚#BVALLIST,D4‚is�this�a�sec�read�function?�BNE.S�VALOP540‚branch�if�yesE�MOVE.L�IOSSAMW(A0),D2ƒD2�<==�bit�mask�of�configured�valid�write�S.A.*DVALOP540‚MOVE.B�IOSSAD-1(A3),D0‚get�S.A.�f+ rom�IOSPB�for�this�request@�MOVEQ�#ISTAIVSA,D1‚preload�invalid/unconfigured�S.A.�error�code?�BTST.L�D0,D2„is�this�addr�configured�to�be�valid�in�this�mode?'�BEQ.S�VALOPRTN‚exit�with�error�in�D1.B*NVALOP600 BTST #BVALBCHG,D4 does commmand reequire user to be in charge of BUS?, BEQ.S VALOP700 br = no, all checks complete% MOVEQ #ISTAIVBD,D1 preset error code LEA.L CONFINFO(A5),A0*�MOVE.L�DVDCBPTR(A0),A0‚A0�<---�DCb�of�BUS" TST.L DCBWNT(A0) is the BUS open?/�BEQ.S�VALOPRTNƒbr�=�no,�return�with�error�code*;*‚The�mode�and�device�is�now�capable�of�completing�the�task*/VALOP700�MOVEQ�#ISTAOK,D1„set�return�code�to�OKVALOPRTN�RTS„exit @ TTL GPIB DRIVER - COMMON SUBROUTINES (HALT ALL I/O IN PROGRESS) PAGE*%*•HALT�I/O�TO�BUS�OR�SPECIFIED�DEVICE*>*ˆThis�routine�is�designed�to�halt�all�I/O�that�is�in�progress?*ˆand�any�I/O�that�is�waiting�to�be�executed�on�the�GPIB�queue.=*ˆThis�routine�may�be�envoked�at�interrupt�or�command�levels.>*ˆIf�at�command�level,�a�HALT�command�was�received�directed�to;*ˆthe�BUS.�At�interrupt�level,�a�IFC,�DCL,�or�TCT�interrupt<*ˆwas�encountered.‚These�interrupts�cause�all�pending�I/O�to *ˆbe�aborted.*2*’ENTER:„A4�=�address�of�DCB�for�current�operation*œA5�=�address�of�CCB*)*’EXIT:…If�D1.B�=�0ƒThen�all�entries�were%*œmarked�'Halted'�and�the�appropriate+*œevents�were�sent�for�the�waiting�commands*œon�the�queue.*˜ELSE*œthere�was�no�I/O�to�halt.*!*ŽRegister�Usage:†0�1�2�3�4�5�6�7*ŸDƒ*�R*ŸA‹P�P*HLTALL:+�MOVEM.L�D2-D7/A1-A6,-(A7)ƒsave�environment6�MOVE.L�QTAIL(A5),A6‰A6�<==�ptr�to�current�queue�entry(�CMPA.L�QHEAD(A5),A6‰is�the�queue�empty?+�BEQ�HLTERR’branch�if�yes�(nothing�to�halt)*�BSR�RESETIO‘do�a�soft�reset1�BSR�KILLSPTO�cancel�Serial�Poll�timer�if�running>�LEA.L�GPIBQEND(A5),A0‡A0�<==�address�of�physical�end�of�queue*CHLTALL10�BSETW�#HALTED,CSTQOFST(A6)‚set�this�entry�status�to�halted5�ADDA.L�#GPIBQLEN,A6‰bump�pointer�to�next�queue�entry&�CMPA.L�A6,A0�at�the�end�of�the�queue?�BNE.S�HLTALL20Žbr�=�no6�LEA.L�GPIBQ(A5),A6Šelse�wrap�around�to�start�of�queue*>HLTALL20 CMPA.L QHEAD(A5),A6 at the end of all queued entries?'�BNE.S�HLTALL10Žbranch�if�no�-�continue*< BCLRW #SRQWAIT,BUSACTIV(A5) clear any potential SRQ waiting=�BTSTW�#BUSIOP,BUSACTIV(A5)‚is�the�pending�I/O�interrupt�set?�BNE.S�HLTALL30Žbranch�if�yes-�CLR.B�IOPEND(A5)Œreset�pending�task�I/O�flag*>HLTALL30 MOVE.L QTAIL(A5),A6 A6 <== current operation on queue�MOVE.L�DCBQOFST(A6),A4†get�DCB!�MOVE.L�IPBQOFST(A6),A3†get�IOSPB8�BSR�PROCMENU�clean�up�and�send�halts�to�queued�commands BRA.S HLTOK 4 TTL GPIB DRIVER - COMMON SUBROUTINES (HALT COMMAND) PAGE*6*ˆHalt�I/O�to�a�specific�device�or�the�BUS�in�T/L�mode*HLTCMD:1�MOVE.L�QTAIL(A5),A6ƒget�pointer�to�current�entry(�CMPA.L�QHEAD(A5),A6‰is�the�queue�empty?(�BEQ.S�HLTXIT�br�=�yes�(nothing�to�halt)*+�MOVEM.L�D2-D7/A1-A6,-(A7)ƒsave�environment9*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn**ˆFix�an�OOPS�!#*LEA.L�GPIBQEND,A0‹set�end-of-queue LEA.L GPIBQEND(A5),A0*>*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<**ˆLocate�the�command*1HLTC60 CMPA.L DCBQOFST(A6),A4 is this the device?�BEQ.S�HLTC80�br�=�yes*'�ADDA.L�#GPIBQLEN,A6‰bump�to�next�entry�CMPA.L�A6,A0�end�of�queue?�BNE.S�HLTC70�br�=�no*0�LEA.L�GPIBQ(A5),A6Šelse�reset�to�start�of�queue*HLTC70�CMPA.L�QHEAD(A5),A6ƒend�of�entries?(�BNE.S�HLTC60�br�=�no,�continue�checking:�BRA.S�HLTERR�entry�not�found,�return�error�to�IOS�request*5HLTC80 BSETW #HALTED,CSTQOFST(A6) mark command halted+�CMPA.L�QTAIL(A5),A6‰is�it�the�current�I/O?�BNE.S�HLTOK‘br�=�no**�BSR�RESETIO‘terminate�any�I/O�in�progress3�MOVE.L�IPBQOFST(A6),A3†set�pointer�to�user's�IOSPB�BSR�PROCMENU�cancel�command0�BTSTW�#BUSIOP,BUSACTIV(A5)‚any�BUS�I/O�pending?�BNE.S�HLTOK‘br�=�yes8�AND.B�#$3F,IOPEND(A5)‡else�clear�pending�task�I/O�FLAGS*3HLTOK�MOVEM.L�(A7)+,D2-D7/A1-A6ƒrestore�environment2+ HLTXIT�MOVEQ�#ISTAOK,D1†set�good�error�return�code RTS*+HLTERR�MOVE.B�#$FF,D1ˆset�error�return�code.�MOVEM.L�(A7)+,D2-D7/A1-A6ƒrestore�environment RTS 7 TTL GPIB DRIVER - COMMON SUBROUTINES (BUILD NEXT MENU) PAGE**ƒBUILD�NEW�MENU�ITEM*:*ˆThis�routine�will�set�up�all�the�menu�pointers�necessary<*ˆto�execute�the�next�command.�Since�the�command�has�already9*ˆbeen�validated,�if�it�is�not�now�found�in�the�IOSCMDTB,;*ˆthis�routine�will�return�a�run�time�error�code�to�IOS�and*ˆthe�command�will�be�aborted.*3*�ENTER:‚A3�=�address�of�IOSPB�for�current�function*—A5�=�address�of�CCB*!*�Register�Usage:…0�1�2�3�4�5�6�7*žD‚*�* *žA‚*…PƒP* BUILDMEN:6�MOVE.W�IOSFCT(A3),D0ˆextract�current�function�command4�LEA.L�IOSCMDTB(PC),A0‡table�of�valid�GPIB�functions;�MOVE.L�#NUMCMDS-1,D1ˆD1�=�number�of�commands�in�GPIB�table*<*‚Find�the�function�in�the�table�of�available�GPIB�functions*9BUILDM10�CMP.W�(A0)+,D0…compare�to�next�function�in�table�BEQ.S�BUILDM20�found�function?%�DBRA�D1,BUILDM10‹no,�continue�search*=*‚ERROR:�This�is�an�irrecoverable�error�because�this�function9*‰was�validated�previously�and�now�a�match�did�not�occur.(*‰Somebody�overran�the�parameter�buffer.*:BUILDM15�MOVEQ‚#ISTADRVE,D1‚set�driver�run�time�error�code�RTSšexit�with�error*.*‚Match�has�been�found�so�set�up�menu�pointers*JBUILDM20 MOVE.L #NUMCMDS-1,D0 subtract index from total number of commands SUB.L D1,D0�ASL.L�#1,D0�get�word�offset9�LEA.L�CTLCFTBL(PC),A0…table�of�controller�menu�functions3�BTSTW�#CAC_S,BUSACTIV(A5)‚GPIB�in�controller�mode?�BNE.S�BUILDM30Œbranch�if�yesE�LEA.L�TLCFTBL(PC),A0†no,�set�table�of�talker/listener�menu�functions*;BUILDM30�MOVE.W�0(A0,D0.W),D1ƒget�relative�distance�of�menu?�BEQ.S�BUILDM15Šthis�should�never�happen�but�do�this�if�it�doesI�LEA.L�0(A0,D1.W),A0…get�absolute�pointer�to�menu�table�for�this�function+�MOVE.L�A0,MENU(A5)†set�top�of�menu�pointer2�MOVE.L�A0,MENUNPOS(A5)‚set�next�menu�item�pointer�MOVEQ‚#ISTAOK,D1‡good�return �RTS•exit3 TTL GPIB DRIVER - COMMON SUBROUTINES (QUEUE EVENT) PAGED*********************************************************************5*‰QUEUE�A�COMPLETION�EVENT�TO�THE�ATTACHED�TASK�(IOS)*;*‰This�routine�calls�the�exec�to�send�a�small�event�to�IOS.9*‰Uses�QEVNTI�if�we're�processing�an�interrupt�and�QEVNTT*‰if�we're�not.*8*‰NOTE:‚This�routine�is�completely�re-entrant�and�may�be2*�run�at�any�time.‚All�work�is�completely�register3*�oriented.‚All�messages�are�assumed�to�be�10�bytes*�in�length�!!!!!!**‰Entry:�D1.W�=�event�status*�D4.B�=�event�type*�A4�=�address�of�DCB.*�A5�=�address�of�CCB.**‰Exit:‚D0�=�garbage.*�D1�=�garbage.*;*‰The�structure�of�the�event�you�must�supply�is�as�follows:*‹BYTES‚MEANING@*‰*ƒ1„event�length�assuming�no�service�address�(always�10�bytes)4*‰*ƒ1„event�code�(1�if�no�service�address,�else�$81)*�1„event�type*‰*ƒ1„channel�key<*‰*ƒ4„ID�(DCB�address�for�us�since�we're�a�standard�channel)*�2„status�value*@*‰Fields�marked�by�*�are�placed�in�the�event�by�this�routine�and%*‰need�not�be�prepared�by�the�caller.@*‰If�a�service�address�was�specified�for�the�I/O,�it�is�insertedD*‰before�the�event�type�field,�and�event�length�is�update�by�4�bytes>*‰and�the�event�code�will�be�modified�to�indicate�a�completion:*‰service�address�is�present�(MSB�of�event�code�is�a�"1").*J************************************************************************** QEVENT:>ŠMOVEM.L�D2-D7/A0-A6,-(A7)�Save�the�registers�we'll�blow�away.*0*‚Start�setting�those�values�which�never�change.*!ŠMOVE.W�D1,D6’D6�<==�event�statusBŠMOVE.W�#(10*256)+IOEVCD,D2„D2�<==�prepare�event�length/event�code#ŠMOVE.L�A4,D5’D5�<==�address�of�DCB3ŠASL.W�#8,D4“shift�event�type�to�upper�byte�of�word7ŠMOVE.B�CCBKEY(A5),D4ŠSet�the�channel�key�in�lower�byte0ŠAND.L�#$FF,D6‘clear�upper�bytes�of�event�status*C*‚If�there�was�a�service�address�specified,�go�back�and�fix�things.*AŠMOVE., L�CCBSVVC(A5),D3…is�a�completion�service�address�specified?ŠBEQ.S�QEVT010�branch�if�no*-ŠADDI.W�#4*256,D2Šadjust�event�length�for�CSA7ŠMOVE.B�#$80+IOEVCD,D2…adjust�event�code�to�set�CSA�bit***ˆStage�all�registers�for�event�processing*-QEVT010ƒSWAP�D2“stage�event�length/event�codeŠTST.L�D3’any�CSA�specified?ŠBEQ.S�QEVT020�branch�if�no*,*ˆStage�registers�for�event�with�CSA�address*ŠSWAP�D3 ŠMOVE.W�D3,D2 ŠMOVE.W�D4,D3 ŠMOVE.L�D5,D4 ŠMOVE.L�D6,D5ŠSWAP�D5ŠBRA.S�QEVT030*3*ˆStage�all�registers�for�event�with�no�CSA�address*QEVT020ƒMOVE.W�D4,D2 ŠMOVE.L�D5,D3 ŠMOVE.L�D6,D4ŠSWAP�D4 ŠCLR.L�D5*&*‚Do�the�exec�call�to�queue�the�event.*FQEVT030ƒMOVE.L�CCBRQSTA(A5),A0„A0�<--�address�of�TCB�of�attached�task.0ŠMOVEQ‚#T0QEVNTI,D0‡D0�<--�the�QEVNTI�directive.7ŠTST.B‚BINTCNT(A5)ˆIf�we're�not�queueing�the�event�from(ŠIF…�THENŠwithin�the�interrupt�tour,0ŠMOVEQ‚#T0QEVNTT,D0‡D0�<--�the�QEVNTT�directive.ŠENDI–* *ŠTRAPƒ#0‘Call�the�exec�to�queue�the�event. ŠBRA„OKEVENTŒIf�good,�go�return.(ŠTR0$.KILLER�,�If�bad,�crash�the�system. COKEVENTƒMOVEM.L�(A7)+,D2-D7/A0-A6�Restore�the�registers�and�return.ŠRTS—* 4 TTL GPIB DRIVER - INTERRUPT PROCESSING (SEND EVENT) PAGEF*********************************************************************** *‚SENDUEVT*5*ˆThe�purpose�of�this�task‚is�to�send�an�event�to�the9*„user�task�from�the�device�I/O�driver.‚This�task�must�be7*„run�at�interrupt�level�or�else�the�system�will�crash.:*„Currently�there�are�7�reasons�for�this�event�on�the�GPIB>*„and�they�are:�SRQ,�RLC,�DCL,�TCT,�GET,�IFC,�and�I/O�pending.**ˆENTER:‚D0.B�=�event�type*�D1.B�=�event�status3*�A4.L�=�address�of�DCB�of�device�assoc.�with�event*�A5.L�=�address�of�CCB*.*ˆEXIT:ƒevent�was�sent�or�else�system�crashed.* *’Register�Usage‚0�1�2�3�4�5�6�7* D�*�* * A�*‡P�P*9*ˆNOTE:ƒThe�entry�point�SENDUEVS:�is�used�when�a�non-zero6*�event�status�(passed�in�D1.B)�will�be�sent�in�event.%*�Otherwise�use�SENDUEVT�entry�point.*6*ˆNOTE:‚This�routine�will�check�to�see�that�the�device-*�specified�by�the�DCB�pointer�is�open�before0*�trying�to�send�the�event.‚If�the�device�is�not1*�open,�an�attempt�will�be�made�to�send�the�event.*�to�the�BUS.‚If�the�BUS�is�not�open�the�event*�will�be�discarded.*C******************************************************************* SENDUEVT:&�MOVEQ�#0,D1‰preload�zero�event�status*DSENDUEVS: MOVEM.L D2-D7/A0-A6,-(A7) save regs that may get destroyed6�TST.B‚BINTCNT(A5)ƒmake�sure�we�are�at�interrupt�levelB�BEQ.S‚SENDUEOK†br�=�no,�fatal�error!�BUT�DON'T�CRASH,�just�ignore; MOVE.L DCBAID(A4),A2 A2 = DCB I.D. of event causing device*9SENDUE05 TST.L DCBTSK(A4) is this device claiming Events?/�BNE.S�SENDUE07‹branch�=�yes,�go�send�the�event1�TST.B�DCBCDV(A4)‰is�this�device�already�the�BUS?3�BEQ.S�SENDUEOK�br�=�yes,�then�throw�the�event�away)�MOVE.L�DCBSUP(A4),A4‡else�go�try�the�BUS�BRA.S�SENDUE05Žgo�try�again!*7SENDUE07�ASL.W�#8,D0‡put�Async�event�type�in�high�byte,&�MOVE.B�D1,D0†add�in�event�status�byte�MOVE.W�D0,-(A7)ƒsave�on�stack/�MOVE.L�A2,-(A7)ƒsave�device�I.D.�data�on�stackK MOVE.W #(AILNG*256)+AIEVCD,-(A7) PUSH event length + Async event type code*.�MOVE.L�DCBSES(A4),D1‚D1�=�task�session�number$�MOVE.L�DCBTSK(A4),A0‚A0�=�task�name.�MOVEQ�#13,D0†Call�'GTXTCB'�for�the�right�info TRAP #0) BRA.S SENDUE10 good, A0 = address of TCB'�MOVEM.L�(A7)+,D2-D3‚Clean�up�the�stack( BRA.S SENDUEOK bad, go throw away event*BSENDUE10�MOVEM.L�(A7)+,D2-D3ƒstage�the�registers�for�RMS68K�QEVENT.�MOVEQ�#T0QEVNTI,D0‚initiate�QEVENTI�directive TRAP #0�NOPŒgood�event*5*ƒIf�we�return�here�directly�the�event�wasn't�queued!!*ˆIgnore�the�error�and�keep�going*6SENDUEOK MOVEM.L (A7)+,D2-D7/A0-A6 restore environment RTS , éééééé' TTL GPIB MENU ITEM TABLE - GPIB TABLES PAGEE********************************************************************** *�COMMAND�I/O�MENU�DRIVER�TABLES*E**********************************************************************=*…THE�FOLLOWING�COMMAND�I/O�MENUS�ARE�USED�TO�COORDINATE�GPIB<*…TRANSMISSION�PROTOCOL�ON�THE�BUS.�MENUS�ARE�GENERATED�EACH:*…TIME�A�REQUEST�FROM�IOS�IS�MADE�TO�THE�DRIVER.�EACH�MENU=*…CONSISTS�OF�SEVERAL�MENU�ITEMS�EACH�OF�WHICH�HAS�A�SPECIFIC?*…TASK�TO�ACCOMPLISH�OR�INITIATE.�ONLY�ONE�MENU�MAY�BE�EXECUTED?*…AT�A�TIME�AND�ANY�REQUESTS�FOR�I/O�THAT�OCCUR�WHILE�EXECUTINGA*…A�MENU�ARE�QUEUED�UP�AND�WILL�BE�PROCESSED�WHEN�ITS�TURN�COMES.9*…MENU�ITEMS�CONSIST�OF�ESSENTIALLY�FOUR�DIFFERENT�TYPES:**…1.�COMMAND�ITEMS�(BUSCMD)*?*ˆTHESE�WILL�SEND�IEEE-488�COMMANDS�TO�THE�GPIBC�INTERFACE�WITH@*ˆTHE�ATN�LINE�TRUE.�ALL�THESE�TYPES�ARE�DESIGNATED�BY�THE�MACRO*ˆBUSCMD�.*&*…2.�AUXILLIARY�COMMAND�ITEMS�(AUXCMD)*5*ˆAUXILLIARY�COMMANDS�ARE�MENU�ITEMS�THAT�ARE�WRITTEN<*ˆDIRECTLY�TO�THE�AUXILIARY�COMMAND�REGISTER�OF�THE�TMS9914A?*ˆREGARDLESS�OF�THE�THE�STATE�OF�THE�ATN�LINE�AND�ARE�GENERATED*ˆBY�AUXCMD��MACRO�CALL.*,*…3.�DATA�INPUT/OUTPUT�MENU�ITEMS�(DATAXFER)*@*ˆTHESE�INITIATE�THE�ACTUAL�DATA�DMA�TRANSFER.�THE�COMPLETION�OF@*ˆTHESE�COMMANDS�IS�PROMPTED�BY�AN�I/O�COMPLETE�INTERRUPT�BY�THE3*ˆGPIBC.�THESE�TYPES�ARE�CALLED�WITH�DATAXFR�.*#*…4.�FUNCTION�MENU�ITEMS�(FUNCTION)*7*ˆTHESE�CAUSE�SOME�SORT�OF�MENU�FUNCTION�TO�TAKE�PLACE.>*ˆFOR�EXAMPLE,�THE�FUNCTION��MENU�ITEM�SIGNIFIES�THE�THIS>*ˆMENU�PACKET�IS�COMPLETE�AND�THAT�THE�MENU�PROCESSOR�IS�READY?*ˆFOR�A�NEW�MENU.�ALL�THESE�TYPES�OF�COMMANDS�ARE�PREFIXED�WITH *ˆTHE�MACRO�CALL�FUNCTION�.*D******************************************************************** SECTION 0 DS 0*D**********************************************************************ˆFUNCTION:�INPUT�DATA*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOREAD‚(CONTROLLER�MODE�ONLY)* Ž6—BŸ?§A¯@·B¿@ÇDÏC×Fß?ç0ï+÷0ÿ<5(/<*ˆPURPOSE:�TO�INITIATE�DMA�WRITE�(WRITE�INTO�MEMORY)�OF�DATA*C********************************************************************INP_DATA�BUSCMD�UNT„UNTALKˆBUSCMD�UNL„UNLISTEN%ˆBUSCMD�OTA„SEND�PRIMARY�TALK�ADDRESSˆDATAXFR�IN„DMA�WRITE�(I- NPUT)ˆBUSCMD�UNT„UNTALKˆFUNCTION�END„END�OF�MENUˆDS.W�0ŠASSURE�WORD�ALIGNMENT*C*********************************************************************ˆFUNCTION:�OUTPUT�DATA*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOWRIT�(CONTROLLER�MODE�ONLY)*:*ˆPURPOSE:�TO�INITIATE�DMA�READ�(READ�FROM�MEMORY)�OF�DATA*D*********************************************************************OUT_DATA�BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN'‰BUSCMD�LAGˆSEND�PRIMARY�LISTEN�ADDRESS‰DATAXFR�OUT‡DMA�READ�(OUTPUT)#‰DATAXFR�TERM†SEND�TERMINATING�CHAR'‰DATAXFR�SEOI†SEND�'EOI'�WITH�LAST�BYTE‰BUSCMD�UNLˆUNLISTEN‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*D**********************************************************************ˆFUNCTION:�OUTPUT�WITH�INPUT*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOOWIN‚(CONTROLLER�MODE�ONLY)*8*ˆPURPOSE:�TO�PERFORM�AND�OUTPUT�FUNCTION�FOLLOWED�BY�AN'*‘INPUT�FUNCTION�WITH�ONE�MENU�REQUEST.*D*********************************************************************OWI_DATA�BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN'‰BUSCMD�LAGˆSEND�PRIMARY�LISTEN�ADDRESS'‰DATAXFR�OUT‡INITIATE�DMA�READ�(OUTPUT)&‰DATAXFR�TERM†SEND�TERMINATING�CHAR(S)'‰DATAXFR�SEOI†SEND�'EOI'�WITH�LAST�BYTE‰BUSCMD�UNLˆUNLISTEN%‰BUSCMD�OTAˆSEND�PRIMARY�TALK�ADDRESS&‰DATAXFR�INˆINITIATE�DMA�WRITE�(INPUT)‰BUSCMD�UNTˆUNTALK‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E***********************************************************************ˆFUNCTION:�REQUEST�STATUS*3*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSTATƒ(ANY�MODE)*7*ˆPURPOSE:‚STANDARD�IOS�REQUEST�STATUS�FUNCTION�COMMAND*E**********************************************************************)REQ_STAT�FUNCTION�FREQSTATƒREQUEST�STATUS‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E********************************************************************** *ˆFUNCTION:�CHANGE�CONFIGURATION*3*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCNFGƒ(ANY�MODE)*=*ˆPURPOSE:‚STANDARD�IOS�CHANGE�CONFIGURATION�FUNCTION�COMMAND*E**********************************************************************6CNFG_DEV�FUNCTION�FCNFGDEVƒCHANGE�DEVICE�CONFIGURATION‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E**********************************************************************(*ˆFUNCTION:�CHANGE�DEFAULT�CONFIGURATION*3*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCHDC‚(ANY�MODE)*7*ˆPURPOSE:‚STANDARD�IOS�CHANGE�DEFAULT�FUNCTION�COMMAND*E**********************************************************************7CH_DEFLT�FUNCTION�FCHDEFLTƒCHANGE�DEFAULT�CONFIGURATION‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*D*********************************************************************"*ˆFUNCTION:�COMMAND�OUT�/�DATA�OUT*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCODO‚(CONTROLLER�MODE�ONLY)*9*ˆPURPOSE:�TO�ALLOW�THE�USER�TO�SEND�NON-STANDARD�COMMAND1*‘SEQUENCES�(ATN�TRUE)�FOLLOWED�BY�A�DATA�STRING.*D*********************************************************************7CDAT_OUT�BUSCMD�AUXˆSEND�COMMAND�STRING�FROM�AUX�BUFFER‰BUSCMD�UNTˆUNTALK'‰DATAXFR�OUT‡INITIATE�DMA�READ�(OUTPUT)#‰DATAXFR�TERM†SEND�TERMINATING�CHAR'‰DATAXFR�SEOI†SEND�'EOI'�WITH�LAST�BYTE‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E**********************************************************************!*ˆFUNCTION:�COMMAND�OUT�/�DATA�IN*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCODI‚(CONTROLLER�MODE�ONLY)*;*ˆPURPOSE:�TO�ALLOW�THE�USER�TO�SEND�A�NON-STANDARD�COMMAND-*‘SEQUENCE�(ATN�TRUE)�FOLLOWED�BY�AN�INPUT�OF*‘DATA�COMMAND.*E**********************************************************************6CDAT_IN‚BUSCMD�AUXˆSEND�COMMAND�STRING�FROM�AUX�BUFFER%‰DATAXFR�INˆINTIATE�DMA�WRITE�(INPUT)‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E***********************************************************************ˆFUNCTION:�COMMAN- D�OUT*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCMDO‚(CONTROLLER�MODE�ONLY)*;*ˆPURPOSE:�TO�ALLOW�THE�USER�TO�SEND�A�NON-STANDARD�COMMAND*‘SEQUENCE�(ATN�TRUE).*E**********************************************************************6CMD_OUT‚BUSCMD�AUXˆSEND�COMMAND�STRING�FROM�AUX�BUFFER‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E**********************************************************************"*ˆFUNCTION:�READ�SECONDARY�ADDRESS*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IORSEC‚(CONTROLLER�MODE�ONLY)*8*ˆPURPOSE:�SIMILAR�TO�INPUT�DATA�EXCEPT�THAT�A�SECONDARY*‘ADDRESS�MUST�BE�SPECIFIED.*E**********************************************************************READ_SEC�BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN ‰BUSCMD�OTAˆPRIMARY�TALK�ADDRESS‰BUSCMD�OSAˆSECONDARY�ADDRESS&‰DATAXFR�INˆINITIATE�DMA�WRITE�(INPUT)‰BUSCMD�UNTˆUNTALK‰FUNCTION�END…END�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENTE**********************************************************************#*ˆFUNCTION:�WRITE�SECONDARY�ADDRESS*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOWSEC‚(CONTROLLER�MODE�ONLY)*9*ˆPURPOSE:�SIMILAR�TO�OUTPUT�DATA�EXCEPT�THAT�A�SECONDARY*‘ADDRESS�MUST�BE�SPECIFIED*D*********************************************************************WRITE_SEC�BUSCMD�UNT‡UNTALK‰BUSCMD�UNLˆUNLISTEN"‰BUSCMD�LAGˆPRIMARY�LISTEN�ADDRESS‰BUSCMD�OSAˆSECONDARY�ADDRESS'‰DATAXFR�OUT‡INITIATE�DMA�READ�(OUTPUT)2‰DATAXFR�TERM†SEND�TERMINATION�CHAR�(IF�NECESSARY)'‰DATAXFR�SEOI†SEND�'EOI'�WITH�LAST�BYTE‰BUSCMD�UNLˆUNLISTEN‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*C********************************************************************%*ˆFUNCTION:�UNCONFIGURE�PARALLEL�POLL*>*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOPPU‚(CONTROLLER�MODE�ONLY)*1*ˆPURPOSE:�TO�RESET�ALL�DEVICES�OF�THEIR�PARALLEL*‘POLL�CONFIGURATION�STATE.*C********************************************************************5PP_UNCFG�BUSCMD�PPUˆPARALLEL�POLL�UNCONFIGURE�COMMAND‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*B*******************************************************************#*ˆFUNCTION:�CONFIGURE�PARALLEL�POLL*>*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOPPC‚(CONTROLLER�MODE�ONLY)*6*ˆPURPOSE:�TO�CONFIGURE�WHICH�OF�8�PARALLEL�POLL�LINES+*‘THE�SPECIFIED�DEVICE�IS�TO�RESPONDON�WHEN*‘PARALLEL�POLLED.*A******************************************************************PP_CNFIG�BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN"‰BUSCMD�LAGˆPRIMARY�LISTEN�ADDRESS+‰BUSCMD�PPCˆPARALLEL�POLL�CONFIGURE�COMMAND(‰BUSCMD�PPEˆSEND�POLL�AND�SENSE�BIT�INFO‰BUSCMD�UNLˆUNLISTEN‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*@*****************************************************************!*ˆFUNCTION:�CONDUCT�PARALLEL�POLL*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOPPOL�(CONTROLLER�MODE�ONLY)*=*ˆPURPOSE:�ALLOW�ACTIVE�CONTROLLER�TO�PARALLEL�ALL�CONFIGURED-*‘DEVICES�(I.E.�DEVICES�WHO�ARE�PARALLEL�POLL'*‘CONFIGURED)�AND�RECEIVE�THEIR�STATUS.*B*******************************************************************-COND_PP‚AUXCMD�TCSŠTAKE�CONTROL�SYNCHRONOUSLY,‰FUNCTION�FRPP‡REQUEST�PARALLEL�POLL�ROUTINE‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E**********************************************************************$*ˆFUNCTION:�SET�PARALLEL�POLL�STATUS*8*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSPPS‚(T/L�MODE�ONLY)*:*ˆPURPOSE:‚SET�UP�THE�PARALLEL�POLL�RESPONSE�BIT�(PPR)�AND*’THE�SENSE�BIT�(S).*E**********************************************************************/SET_PPƒFUNCTION�FSETPP…SET�PARALLEL�POLL�STATUS‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*E**********************************************************************"*ˆFUNCTION:�SET�SERIAL�POLL�STATUS*8*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSSPS�(T/L�MODE�ONLY)*5*ˆPURPOSE:‚SET�THE�VALUE�TO�BE�RETURNED�TO�THE�ACTIVE'*’CONTROLLER�WHEN�WE. �ARE�SERIAL�POLLED.*E**********************************************************************-SET_SPƒFUNCTION�FSETSP…SET�SERIAL�POLL�STATUS‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*C********************************************************************'*ˆFUNCTION:�DEVICE�STATUS�(SERIAL�POLL)*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSPOL�(CONTROLLER�MODE�ONLY)*2*ˆPURPOSE:�CONDUCT�SERIAL�POLL�OF�SPECIFIED�DEVICE*B*******************************************************************COND_SP‚BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN#‰BUSCMD�SPEˆSEND�SERIAL�POLL�ENABLE%‰BUSCMD�OTAˆSEND�PRIMARY�TALK�ADDRESS%‰DATAXFR�SPB‡RECEIVE�SERIAL�POLL�BYTE"‰BUSCMD�SPDˆLEAVE�SERIAL�POLL�MODE‰BUSCMD�UNTˆUNTALK‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*C********************************************************************!*ˆFUNCTION:�PARALLEL�POLL�DISABLE*>*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOPPD‚(CONTROLLER�MODE�ONLY)*@*ˆPURPOSE:�TO�DISABLE�A�DEVICE�FROM�SENDING�A�STATUS�BIT�MESSAGE!*‘IN�RESPONSE�TO�A�PARALLEL�POLL.*C********************************************************************PP_DISAB�BUSCMD�UNTˆUNTALK‰BUSCMD�UNLˆUNLISTEN ‰BUSCMD�LAGˆLISTEN�ADDRESS�GROUP#‰BUSCMD�PPCˆPARALLEL�POLL�CONFIGURE)‰BUSCMD�PPDˆPARALLEL�POLL�DISABLE�COMMAND‰BUSCMD�UNLˆUNLISTEN‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*C*********************************************************************ˆFUNCTION:�INTERFACE�CLEAR*C*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSIFC�(SYS�CONTROLLER�MODE�ONLY)*1*ˆPURPOSE:�TO�ALLOW�THE�SYSTEM�CONTROLLER�TO�SEND**‘THE�INTERFACE�CLEAR�COMMAND�TO�THE�GPIBC*C********************************************************************'INTF_CLR�FUNCTION�FSIC…SEND�IFC�COMMAND‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*C*********************************************************************ˆFUNCTION:�REMOTE�ENABLE*C*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSREN�(SYS�CONTROLLER�MODE�ONLY)*1*ˆPURPOSE:�TO�ALLOW�THE�SYSTEM�TO�SEND�THE�REMOTE*‘ENABLE�MESSAGE�TO�THE�GPIBC.*C********************************************************************.REM_ENAB�AUXCMD�SRE1ˆSEND�REMOTE�ENABLE�(CS=1)‰FUNCTION�END‰END�OF�MENU‰DS.W�0�ASSURE�WORD�ALIGNMENT*C*********************************************************************ˆFUNCTION:�REMOTE�DISABLE*C*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOCREN�(SYS�CONTROLLER�MODE�ONLY)*1*ˆPURPOSE:�TO�ALLOW�THE�SYSTEM�TO�SEND�THE�REMOTE*‘DISABLE�MESSAGE�TO�THE�GPIBC.*C********************************************************************/REM_DNAB�AUXCMD�SRE0ˆSEND�REMOTE�DISABLE�(CS=0)‰FUNCTION�END‰END�OF�MENU‰DS.W�0�ASSURE�WORD�ALIGNMENT*C********************************************************************2*ˆFUNCTION:�ENTRY�I:�ABORT�BUS�AND�DEVICE�MESSAGES*’ENTRY�II:‚CLEAR�ALL�DEVICES*F*ˆFUNCTION�CODE�TO�INITIATE�MENU:�I.�IOABT1�(SYS�CONTROLLER�MODE�ONLY)#*¨II.�IOSDCL�(CONTROLLER�MODE�ONLY)*7*ˆPURPOSE:�TO�HALT�ALL�ACTIVITY�ON�THE�GPIBC�BY�SENDING/*‘THE�INTERFACE�CLEAR�AND�DEVICE�CLEAR�MESSAGES*C********************************************************************2S_IFCDCL�FUNCTION�FSIC‡SEND�INTEFACE�CLEAR�COMMAND*S_DCL„BUSCMD�DCLŠSEND�DEVICE�CLEAR�COMMAND‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*C********************************************************************%*ˆFUNCTION:�LOCAL�LOCKOUT�ALL�DEVICES*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSLLO‚(CONTROLLER�MODE�ONLY)*-*ˆPURPOSE:�ALLOW�USER�TO�SEND�OUT�LLO�COMMAND*C********************************************************************$S_LOCLOK�BUSCMD�LLOŠSEND�LLO�COMMAND‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*C********************************************************************!*ˆFUNCTION:�ABORT�DEVICE�MESSAGES*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOABT2�(CONTROLLER�MODE�ONLY)*0*ˆPURPOSE:�TO�HALT�ANY�I/O�TO�DEVI. CES‚BY�SENDING"*‘THE�UNTALK�AND�UNLISTEN�COMMANDS*B*******************************************************************S_UNTUNL�BUSCMD�UNTŠSEND�UNTALK‰BUSCMD�UNLŠSEND�UNLISTEN‰FUNCTION�ENDŠEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*A*******************************************************************ˆFUNCTION:�TAKE�CONTROL*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOTCTL�(CONTROLLER�MODE�ONLY)*1*ˆPURPOSE:�TO�ALLOW�USER�TO�REGAIN�CONTROL�OF�THE)*‘BUS�AT�ANY�TIME�PROVIDED�HE�HAS�CONTROL-*‘OF�THE�BUS�AND�HAS�CONTROLLER�CAPABILITIES.*A******************************************************************/TAKE_CTL�FUNCTION�FTAKCTL‚TAKE�CONTROL�FUNCTION‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*A*******************************************************************ˆFUNCTION:�GO�TO�STANDBY*>*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOGTS�(CONTROLLER�MODE�ONLY)*2*ˆPURPOSE:�TO�ALLOW�USER�TO�RELEASE�CONTROL�OF�THE)*‘BUS�AT�ANY�TIME�PROVIDED�HE�HAS�CONTROL-*‘OF�THE�BUS�AND�HAS�CONTROLLER�CAPABILITIES.*A******************************************************************,GO_STBY‚FUNCTION�FGTS…GO�TO�STANDBY�FUNCTION‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT    A*******************************************************************ˆFUNCTION:�REQUEST�CONTROL*(*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IORQCL*5*ˆPURPOSE:�TO�ALLOW�USER�TO�INITIALLY�TAKE�CONTROL�OF-*‘THE�BUS�AFTER�THE�SYSTEM�IS�INITIALIZED�AND'*‘THE�MVME-300�HAS�COME�UP�IN�T/L�MODE./*‘THIS�COMMAND�WILL�PUT�THE�TMS9914�INTO�'CACS'.*‘AND�ALLOW�NORMAL�CONTROLLER�FUCTIONS�WITHOUT!*‘HAVE�TO�BE�A�SYSTEM�CONTROLLER.*A******************************************************************1REQ_CTL‚FUNCTION�FREQCTL‚REQUEST�CONTROL�FUNCTION‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*A*******************************************************************ˆFUNCTION:�RELEASE�CONTROL*(*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IORLCL*2*ˆPURPOSE:�TO�ALLOW�USER�TO�GIVE�UP�CONTROL�OF�THE)*‘BUS�AT�ANY�TIME�PROVIDED�HE�HAS�CONTROL+*‘OF�THE�BUS.‚THIS�COMMAND�SIMPLY�DROPS�THE+*‘ATN�LINE�ON�THE�BUS�AND�SWITCHES�THE�GPIB%*‘DRIVER�FROM�CONTROLLER�TO�T/L�MODE.#*‘(THE�9914�GOES�INTO�'CIDS'�STATE)*A******************************************************************1REL_CTL‚FUNCTION�FRELCTL‚RELEASE�CONTROL�FUNCTION‰FUNCTION�END†END�OF�MENU‰DS.W�0ŒASSURE�WORD�ALIGNMENT*A*******************************************************************ˆFUNCTION:�PASS�CONTROL*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOPCTL�(CONTROLLER�MODE�ONLY)*3*ˆPURPOSE:�TO�ALLOW�USER�TO�PASS�CONTROL�TO�ANOTHER)*‘DEVICE�ON�THE�BUS�CAPABLE�OF�CONTROLLER*‘RESPONSIBILITIES.*B*******************************************************************PASS_CTL�BUSCMD�UNTŠSEND�UNTALK‰BUSCMD�UNLŠSEND�UNLISTEN%‰BUSCMD�OTAŠSEND�PRIMARY�TALK�ADDRESS‰BUSCMD�TCTŠSEND�TAKE�CONTROL/‰FUNCTION�FRELCTL„ISSUE�RELEASE�CONTROL�COMMAND‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*A******************************************************************"*ˆFUNCTION:�CLEAR�SPECIFIED�DEVICE*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSSDC‚(CONTROLLER�MODE�ONLY)*$*ˆPURPOSE:�TO�CLEAR�SPECIFIED�DEVICE*B*******************************************************************SPEC_CLR�BUSCMD�UNTŠUNTALK‰BUSCMD�UNLŠUNLISTEN"‰BUSCMD�LAGŠPRIMARY�LISTEN�ADDRESS"‰BUSCMD�SDCŠSELECTIVE�DEVICE�CLEAR‰BUSCMD�UNLŠUNTALK‰FUNCTION�ENDŠEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMNET*A******************************************************************%*ˆFUNCTION:�CLEAR�ADDRESSED�LISTENERS*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IODSDC‚(CONTROLLER�MODE�ONLY)*!*ˆPURPOSE:�TO�CLEAR�ALL�LISTENERS*B********************************************************************ADDR_CLR�BUSCMD�SDCŠSELECTIVE�DEVICE�CLEAR‰FUNCTION�ENDŠEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMNET*A**********************************/ ********************************!*ˆFUNCTION:�SPECIFIED�GO�TO�LOCAL*A*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSGTL‚(CONTROLLER�&�T/L�MODES)*2*ˆPURPOSE:�TO�PUT�SPECIFIED�LISTENER�IN�LOCAL�MODE*B*******************************************************************SPEC_GTL�BUSCMD�UNTŠUNTALK‰BUSCMD�UNLŠUNLISTEN"‰BUSCMD�LAGŠPRIMARY�LISTEN�ADDRESS‰BUSCMD�GTLŠGO�TO�LOCAL�COMMAND‰BUSCMD�UNLŠUNLISTEN‰FUNCTION�ENDŠEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*A******************************************************************+*ˆFUNCTION:�ADDRESSED�LISTENERS�GO�TO�LOCAL*A*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IODGTL‚(CONTROLLER�&�T/L�MODES)*3*ˆPURPOSE:�TO�PUT�ADDRESSED�LISTENERS�IN�LOCAL�MODE*B*******************************************************************'ADDR_GTL�BUSCMD�GTLŠGO�TO�LOCAL�COMMAND‰FUNCTION�ENDŠEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*B*********************************************************************ˆFUNCTION:�REMOTE�ENABLE�SPECIFIED�DEVICE*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IODREM‚(CONTROLLER�MODE�ONLY)*5*ˆPURPOSE:�TO�PLACE�A�SPECIFIED�DEVICE�IN�REMOTE�MODE*B*******************************************************************'SPEC_REM�AUXCMD�SRE1‰SEND�REMOTE�ENABLE‰BUSCMD�UNTŠUNTALK‰BUSCMD�UNLŠUNLISTEN"‰BUSCMD�LAGŠPRIMARY�LISTEN�ADDRESS‰BUSCMD�UNLŠUNLISTEN‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*A******************************************************************$*ˆFUNCTION:�TRIGGER�SPECIFIED�DEVICE*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOSGET‚(CONTROLLER�MODE�ONLY)*(*ˆPURPOSE:�TO�TRIGGER�A�SPECIFIED�DEVICE*>***************************************************************SPEC_GET�BUSCMD�UNTŠUNTALK‰BUSCMD�UNLŠUNLISTEN"‰BUSCMD�LAGŠPRIMARY�LISTEN�ADDRESS&‰BUSCMD�GETŠSEND�GROUP�EXECUTE�TRIGGER‰BUSCMD�UNLŠUNLISTEN‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*A******************************************************************'*ˆFUNCTION:�TRIGGER�ADDRESSED�LISTENERS*?*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IODGET‚(CONTROLLER�MODE�ONLY)*-*ˆPURPOSE:�TO�TRIGGER�ALL�ADDRESSED�LISTENERS*>***************************************************************.ADDR_GET�BUSCMD�GETŠSEND�GROUP�EXECUTE�TRIGGER‰FUNCTION�ENDˆEND�OF�MENU‰DS.W�0ŽASSURE�WORD�ALIGNMENT*B*******************************************************************-*ˆFUNCTION:�PRIMARY�AND�SECONDARY�READ�TO�BUS*’ENTRY�POINT�I:‚SECONDARY�READ*’ENTRY�POINT�II:�PRIMARY�READ*;*ˆFUNCTION�CODE�TO�INITIATE�MENU:�I:�IORSEC‚(T/L�MODE�ONLY)*§II:�IOREAD‚(T/L�MODE�ONLY)*1*ˆPURPOSE:‚ALLOW�OWNER�OF�BUS�TO�MAKE�PRIMARY�AND-*’SECONDARY�READ�REQUESTS�FROM�THE�CONTROLLER *’IN�CHARGE.B*******************************************************************$RSEC_TL�EQU�*�READ�SECONDARY�ADDRESS8INTL_DAT�DATAXFR�INŠREAD�DATA‚(WHEN�CONTROLLER�REQUESTS)�FUNCTION�END�END�OF�MENU�DS.W�0–ASSURE�WORD�ALLIGNMENT*E**********************************************************************0*ˆFUNCTION:�PRIMARY�AND�SECONDARY�WRITE�FROM�BUS *’ENTRY�POINT�I:‚SECONDARY�WRITE*’ENTRY�POINT�II:�PRIMARY�WRITE*;*ˆFUNCTION�CODE�TO�INITIATE�MENU:�I:�IOWSEC‚(T/L�MODE�ONLY)*§II:�IOWRIT‚(T/L�MODE�ONLY)*1*ˆPURPOSE:‚ALLOW�OWNER�OF�THE�BUS�TO�MAKE�PRIMARY0*’AND�SECONDARY�WRITE�REQUESTS�TO�THE�CONTROLLER *’IN�CHARGE.*D*********************************************************************%WSEC_TL�EQU�*�WRITE�SECONDARY�ADDRESS:OUTL_DAT�DATAXFR�OUT‰WRITE�DATA‚(WHEN�CONTROLLER�REQUESTS)8�DATAXFR�TERM�SEND�TERMINATION�CHARACTERS�(IF�NECESSARY)'�DATAXFR�SEOI�SEND�'EOI'�WITH�LAST�BYTE�FUNCTION�END�END�OF�MENU�DS.W�0–ASSURE�WORD�ALLIGNMENT*B*******************************************************************1*ˆFUNCTION:�OUTPUT�WITH�INPUT�COMMAND�IN�T/L�MODE*8*ˆFUNCTION�CODE�TO�INITIATE�MENU:�IOOWIN‚(T/L�MODE�ONLY)*7*ˆPURPOSE:‚COMBINATION�OF�THE�PRIMARY�WRITE�FOLLOWED�BY%*’PRIMARY�READ�OPERATION�IN�T/L�MODE.*B**********************************/ *********************************:OITL_DAT�DATAXFR�OUTƒWRITE�DATA�(WHEN�CONTROLLER�REQUESTS)&�DATAXFR�TERMŠSEND�MESSAGE�TERMINATORS'�DATAXFR�SEOIŠSEND�'EOI'�WITH�LAST�BYTE0�DATAXFR�INŒREAD�DATA�(WHEN�CONTROLLER�REQUESTS)�FUNCTION�ENDŠEND�OF�MENU�DS.W�0�ASSURE�WORD�ALLIGNMENT TTL GPIB DRIVER - DRIVER TABLES PAGEB*************************************************************************´********’MENU�ITEM�CODE�JUMP�TABLE•**À*/*†THIS�TABLE�IS�INDEXED�BY�THE�MENU�ELEMENTS.�*7*†THE�ORDER�OF�THIS�TABLE�MUST�REMAIN�CONSISTENT�WITH‡*%*†THE�VALUES�ASSIGNED�TO�EACH�ITEM.™********´*******B****************************************************************** MENUCTBL:�DC.W�0‘END�OF�MENU�INDICATOR*�DC.W�SENDUNT-MENUCTBL‚UNTALK�ROUTINE�ADDR,�DC.W�SENDUNL-MENUCTBL‚UNLISTEN�ROUTINE�ADDR:�DC.W�SENDLAG-MENUCTBL‚PRIMARY�LISTEN�ADDR�ROUTINE�ADDRESS8�DC.W�SENDOTA-MENUCTBL‚PRIMARY�TALK�ADDR�ROUTINE�ADDRESS6�DC.W�SENDOSA-MENUCTBL‚SECONDARY�R/W�ADDR�ROUTINE�ADDR=�DC.W�SENDPPU-MENUCTBL‚PARALLEL�POLL�UNCONFIGURE�ROUTINE�ADDR;�DC.W�SENDPPC-MENUCTBL‚PARALLEL�POLL�CONFIGURE�ROUTINE�ADDR8�DC.W�SENDPPE-MENUCTBL‚PARALLEL�POLL�ENABLE�ROUTINE�ADDR9�DC.W�SENDPPD-MENUCTBL‚PARALLEL�POLL�DISABLE�ROUTINE�ADDR6�DC.W�SENDSPE-MENUCTBL‚SERIAL�POLL�ENABLE�ROUTINE�ADDR7�DC.W�SENDSPD-MENUCTBL‚SERIAL�POLL�DISABLE�ROUTINE�ADDR0�DC.W�SENDDCL-MENUCTBL‚DEVICE�CLEAR�ROUTINE�ADDR1�DC.W�SENDLLO-MENUCTBL‚LOCAL�LOCKOUT�ROUTINE�ADDR0�DC.W�SENDTCT-MENUCTBL‚PASS�CONTROL�ROUTINE�ADDR:�DC.W�SENDSDC-MENUCTBL‚SELECTIVE�DEVICE�CLEAR�ROUTINE�ADDR/�DC.W�SENDGTL-MENUCTBL‚GO�TO�LOCAL�ROUTINE�ADDR9�DC.W�SENDGET-MENUCTBL‚GROUP�EXECUTE�TRIGGER�ROUTINE�ADDR5 DC.W SENDAUXS-MENUCTBL SEND AUXILIARY COMMAND STRINGC DC.W READDATA-MENUCTBL INITIATE DMA WRITE ROUTINE ADDR (READ DATA)C DC.W WRITDATA-MENUCTBL INITIATE DMA READ ROUTINE ADDR (WRITE DATA)B DC.W SENDTERM-MENUCTBL SEND TERMINATION CHARACTER(S) ROUTINE ADDR+�DC.W�READSP-MENUCTBLƒREAD�SERIAL�POLL�BYTE5�DC.W�SENDEOI-MENUCTBL‚SEND�'EOI'�WITH�LAST�DATA�BYTE=�DC.W�AUXPROC-MENUCTBL‚GENERAL�AUXILIARY�COMMAND�ROUTINE�ADDR=�DC.W�SENDIFC-MENUCTBL‚SEND�IFC�COMMAND�ROUTINE�FUNCTION�ADDRG�DC.W�SENDRPP-MENUCTBL‚SEND�REQUEST�PARALLEL�POLL�ROUTINE�FUNCTION�ADDRD�DC.W�SENDRLC-MENUCTBLƒPERFORM�RELEASE�CONTROL�ROUTINE�FUNCTION�ADDRA�DC.W�SENDTCA-MENUCTBLƒPERFORM�TAKE�CONTROL�ROUTINE�FUNCTION�ADDRD�DC.W�SENDRQC-MENUCTBLƒPERFORM�REQUEST�CONTROL�ROUTINE�FUNCTION�ADDR2�DC.W�REQSTAT-MENUCTBL‚REQUEST�STATUS�ROUTINE�ADDR4�DC.W�CNFGDEV-MENUCTBL‚CONFIGURE�DEVICE�ROUTINE�ADDR@�DC.W�CHDEFLT-MENUCTBL‚CHANGE�DEFAULT�CONFIGURATION�ROUTINE�ADDR:�DC.W�SETPP-MENUCTBL„SET�PARALLEL�POLL�STATUS�ROUTINE�ADDR8�DC.W�SETSP-MENUCTBL„SET�SERIAL�POLL�STATUS�ROUTINE�ADDR5�DC.W�SENDGTS-MENUCTBL‚GO�TO�STANDBY�FUNCTION�ROUTINE*6MENUCLEN EQU (*-MENUCTBL)/2 NUMBER OF ENTRIES IN TABLE  PAGEC**************************************************************************µ********˜CONTROLLERŸ*'*ŒCODE/FUNCTION�MENU�TABLE�JUMP�TABLE’**Á*1*†THIS�TABLE�CONTAINS�THE�ADDRESSES�OF�THE�MENUŽ*7*†TABLES�FOR�EACH�OF�THE�GPIBC�IOS�FUNCTIONS�THAT�AREˆ*8*†VALID�IN�CONTROLLER�ONLY�MODE.�THIS�TABLE�IS�INDEXED‡*8*†BY�A�MATCH�IN�'IOSCMDTB'.�IF�THE�ENTRY�IS�ZERO,�THIS‡*'*†MENU�IS�INVALID�IN�CONTROLLER�MODE.˜**Á********µ*******C*******************************************************************%CTLCFTBL�DC.W�INP_DATA-CTLCFTBL‚INPUT�DC.W�OUT_DATA-CTLCFTBLƒOUTPUT)�DC.W�OWI_DATA-CTLCFTBLƒOUTPUT�WITH�INPUT&�DC.W�REQ_STAT-CTLCFTBLƒREQUEST�STATUS,�DC.W�CNFG_DEV-CTLCFTBLƒCHANGE�CONFIGURATION4�DC.W�CH_DEFLT-CTLCFTBLƒCHANGE�DEFAULT�CONFIGURATION,�DC.W�CDAT_OUT-CTLCFTBLƒCOMMAND�OUT/DATA�OUT*�DC.W�CDAT_IN-CTLCFTBL„COMMAND�OUT/DATA�IN"�DC.W�CMD_OUT-CTLCFTBL„COMMAND�OUT&�DC.W�READ_SEC-CTLCFTBLƒREAD�SECONDARY(�DC.W�WRITE_SEC-CTLCFTBLƒWRITE�SECONDARY1�DC.W�PP_UNCFG-CTLCFTBLƒPARALLEL�POLL�UNCONFIGURE/�DC.W�PP_CNFIG-CTLCFTBLƒPARALLEL�POLL�CONFIGURE,�DC.W�COND_PP-CTLCFTBL„CONDUCT�PARALLEL�POLL.�DC.W�SET_PP-CTLCFTBL…SE0 T�PARALLEL�POLL�STATUS,�DC.W�SET_SP-CTLCFTBL…SET�SERIAL�POLL�STATUS*�DC.W�COND_SP-CTLCFTBL„CONDUCT�SERIAL�POLL-�DC.W�PP_DISAB-CTLCFTBLƒPARALLEL�POLL�DISABLE'�DC.W�INTF_CLR-CTLCFTBLƒINTERFACE�CLEAR%�DC.W�REM_ENAB-CTLCFTBLƒREMOTE�ENABLE&�DC.W�REM_DNAB-CTLCFTBLƒREMOTE�DISABLE&�DC.W�S_DCL-CTLCFTBL†CLEAR�ALL�DEVICES3�DC.W�ADDR_CLR-CTLCFTBLƒCLEAR�ALL�LISTENING�DEVICES%�DC.W�S_LOCLOK-CTLCFTBLƒLOCAL�LOCKOUT$�DC.W�PASS_CTL-CTLCFTBLƒPASS�CONTROL-�DC.W�ADDR_GTL-CTLCFTBLƒLISTENERS�GO�TO�LOCAL)�DC.W�ADDR_GET-CTLCFTBLƒLISTENERS�TRIGGER2�DC.W�S_IFCDCL-CTLCFTBLƒINTERFACE�AND�DEVICE�CLEAR+�DC.W�S_UNTUNL-CTLCFTBLƒUNTALK�AND�UNLISTEN$�DC.W�TAKE_CTL-CTLCFTBLƒTAKE�CONTROL�DC.W�0“REQUEST�CONTROL&�DC.W�REL_CTL-CTLCFTBL„RELEASE�CONTROL$�DC.W�GO_STBY-CTLCFTBL„GO�TO�STANDBY.�DC.W�SPEC_CLR-CTLCFTBLƒSPECIFIED�CLEAR�DEVICE/�DC.W�SPEC_REM-CTLCFTBLƒSPECIFIED�REMOTE�DEVICE0�DC.W�SPEC_GET-CTLCFTBLƒSPECIFIED�TRIGGER�DEVICE-�DC.W�SPEC_GTL-CTLCFTBLƒSPECIFIED�GO�TO�LOCAL  PAGEC**************************************************************************�TALKER/LISTENER–*******'*ŒCODE/FUNCTION�MENU�TABLE�JUMP�TABLE’**Á*6*†THIS�TABLE�CONTAINS�THE�ADDRESSES�OF�THE�MENU�ITEM‰*6*†TABLE�FOR�EACH�OF�THE�GPIBC�IOS�FUNCTIONS�THAT�ARE‰*8*†VALID�IN�TALKER/LISTENER�MODE.�THIS�TABLE�IS�INDEXED‡*7*†BY�A�MATCH�IN�'IOSCMDTB'.�IF�AN�ENTRY�IS�ZERO,�THENˆ*/*†THAT�MENU�IS�INVALID�IN�TALK/LISTENER�MODE.�**Á********µ*******C*******************************************************************#TLCFTBL�DC.W�INTL_DAT-TLCFTBL‚INPUT�DC.W�OUTL_DAT-TLCFTBLƒOUTPUT(�DC.W�OITL_DAT-TLCFTBLƒOUTPUT�WITH�INPUT%�DC.W�REQ_STAT-TLCFTBLƒREQUEST�STATUS+�DC.W�CNFG_DEV-TLCFTBLƒCHANGE�CONFIGURATION3�DC.W�CH_DEFLT-TLCFTBLƒCHANGE�DEFAULT�CONFIGURATION�DC.W�0’COMMAND�OUT/DATA�OUT�DC.W�0’COMMAND�OUT/DATA�IN�DC.W�0’COMMAND�OUT$�DC.W�RSEC_TL-TLCFTBL„READ�SECONDARY%�DC.W�WSEC_TL-TLCFTBL„WRITE�SECONDARY!�DC.W�0’PARALLEL�POLL�UNCONFIGURE�DC.W�0’PARALLEL�POLL�CONFIGURE�DC.W�0’CONDUCT�PARALLEL�POLL-�DC.W�SET_PP-TLCFTBL…SET�PARALLEL�POLL�STATUS+�DC.W�SET_SP-TLCFTBL…SET�SERIAL�POLL�STATUS�DC.W�0’CONDUCT�SERIAL�POLL�DC.W�0’PARALLEL�POLL�DISABLE&�DC.W�INTF_CLR-TLCFTBLƒINTERFACE�CLEAR�DC.W�0’REMOTE�ENABLE�DC.W�0’REMOTE�DISABLE�DC.W�0’CLEAR�ALL�DEVICES#�DC.W�0’CLEAR�ALL�LISTENING�DEVICES�DC.W�0’LOCAL�LOCKOUT�DC.W�0’PASS�CONTROL�DC.W�0’LISTENERS�GO�TO�LOCAL�DC.W�0’LISTENERS�TRIGGER"�DC.W�0’INTERFACE�AND�DEVICE�CLEAR�DC.W�0’UNTALK�AND�UNLISTEN�DC.W�0’TAKE�CONTROL%�DC.W�REQ_CTL-TLCFTBL„REQUEST�CONTROL�DC.W�0’RELEASE�CONTROL�DC.W�0’GO�TO�STANDBY�DC.W�0’SPECIFIED�CLEAR�DEVICE�DC.W�0’SPECIFIED�REMOTE�DEVICE �DC.W�0’SPECIFIED�TRIGGER�DEVICE�DC.W�0’SPECIFIED�GO�TO�LOCAL  PAGEC**************************************************************************µ*******!*’CODE/FUNCTION�IOS�MATCH�TABLE’**Á*6*†THIS�TABLE�CONTAINS�THE�COMBINED�CODE�AND�FUNCTION‰*;*†FOR�EACH�COMMAND�AVAILABLE�IN�IOS�TO�A�BUSSABLE�DEVICE.„*7*†WHEN�AN�IOS�PARAMETER�BLOCK�IS�RECEIVED,�THIS�TABLEˆ*8*†WILL�BE�SCANNED�FOR�A�MATCH.�WHEN�FOUND�THE�RELATIVE‡*5*†OFFSET�IN�THE�TABLE�WILL�INDEX�INTO�'CFMENUTB'�TOŠ*:*†POINT�TO�THE�APPRIORIATE�MENU�DRIVER�FOR�THAT�FUNCTION…*1*†THESE�COMMANDS�ARE�PASSED�IN�THE�IOSPB�IN�THEŽ**†PARAMETER�'IOSFCT'.¨**Á********µ*******C*******************************************************************IOSCMDTB�DC.W�IOREAD„INPUT�DC.W�IOWRIT‡OUTPUT�DC.W�IOOWIN‡OUTPUT�WITH�INPUT�DC.W�IOSTAT‡REQUEST�STATUS!�DC.W�IOCNFG‡CHANGE�CONFIGURATION)�DC.W�IOCHDC‡CHANGE�DEFAULT�CONFIGURATION!�DC.W�IOCODO‡COMMAND�OUT/DATA�OUT �DC.W�IOCODI‡COMMAND�OUT/DATA�IN�DC.W�IOCMDO‡COMMAND�OUT�DC.W�IORSEC‡READ�SECONDARY�DC.W�IOWSEC‡WRITE�SECONDARY%�DC.W�IOPPUˆPARALLEL�POLL�UNCONFIGURE#�DC.W�IOPPCˆPARALLEL�POLL�CONFIGURE"�DC.W�IOPPOL‡CONDUCT�PARALLEL�POLL%�DC.W�IOSPPS‡SET�PARALLEL�POLL�STATUS#�DC.W�IOSSPS‡SET�SERIAL�POLL�STATUS �DC.W�IOSPOL‡CONDUCT�SERIAL�POLL!�DC.W�IOPPDˆPARALLEL�POLL�DISABLE�DC.W�IOSIFC‡INTERFACE�CLEAR�D0 C.W�IOSREN‡REMOTE�ENABLE�DC.W�IOCREN‡REMOTE�DISABLE�DC.W�IOSDCL‡CLEAR�ALL�DEVICES(�DC.W�IOSSDC‡CLEAR�ALL�LISTENING�DEVICES�DC.W�IOSLLO‡LOCAL�LOCKOUT�DC.W�IOPCTL‡PASS�CONTROL"�DC.W�IOSGTL‡LISTENERS�GO�TO�LOCAL�DC.W�IOSGET‡LISTENERS�TRIGGER'�DC.W�IOABT1‡INTERFACE�AND�DEVICE�CLEAR �DC.W�IOABT2‡UNTALK�AND�UNLISTEN�DC.W�IOTCTL‡TAKE�CONTROL�DC.W�IORQCL‡REQUEST�CONTROL�DC.W�IORLCL‡RELEASE�CONTROL�DC.W�IOGTSˆGO�TO�STANDBY#�DC.W�IODSDC‡SPECIFIED�CLEAR�DEVICE$�DC.W�IODREM‡SPECIFIED�REMOTE�DEVICE%�DC.W�IODGET‡SPECIFIED�TRIGGER�DEVICE"�DC.W�IODGTL‡SPECIFIED�GO�TO�LOCAL*6NUMCMDS�EQU�(*-IOSCMDTB)/2‚NUMBER�OF�COMMANDS�IN�TABLE  PAGEF***********************************************************************.*ŽCOMMAND�BUFFER/MODE/ABILITY�VALIDATION�TABLE*:*ˆThis�table�is�used�by�VALIDATES�and�VALOPER�to�determine4*ˆwhether�certain�parameters/modes�need�be�validated:*ˆfor�the�desired�command.�This�table�is�indexed�according9*ˆto�the�index�for�IOSCMDTB.�The�structure�is�as�follows:**ˆ|--|--|--|--|--|--|--|--|*ˆ|�7|�6|�5|�4|�3|�2|�1|�0|*ˆ|--|--|--|--|--|--|--|--|:*‰|‚|‚|‚|‚|‚|‚|‚|___�must�have�talker�ability�(VALTALK)�**=*‰|‚|‚|‚|‚|‚|‚|______�must�have�listener�ability�(VALLIST)�**<*‰|‚|‚|‚|‚|‚|_________�must�have�controller�ability�(VALCTL)C*‰|‚|‚|‚|‚|____________�must�have�sys.�controller�ability�(VALSCTL)7*‰|‚|‚|‚|_______________�must�have�SRQ�ability�(VALSRQ)@*‰|‚|‚|__________________�validate�primary�buffer�addr.(VALPBUF)C*‰|‚|_____________________�validate�secondary�buffer�addr.(VALSBUF)G*‰|________________________�validate�configuration�buf.�addr.�(VALCBUF)**ˆ|--|--|--|--|--|--|--|--|*ˆ|15|14|13|12|11|10|�9|�8|*ˆ|--|--|--|--|--|--|--|--|2*‰|‚|‚|‚|‚|‚|‚|‚|___�valid�in�talker�mode(VALTMOD)5*‰|‚|‚|‚|‚|‚|‚|______�valid�in�listener�mode(VALLMOD):*‰|‚|‚|‚|‚|‚|_________�must�be�in�controller�mode(VALCMOD)?*‰|‚|‚|‚|‚|____________�valid�only�for�BUS�in�T/L�mode(VALBTLM) *‰|‚|‚|‚|Ÿor�device�on�CTL�mode.@*‰|‚|‚|‚|_______________�valid�only�for�bussable�device(VALBDEV)C*‰|‚|‚|__________________�command�valid�only�for�BUS�itself(VALBUS)?*‰|‚|_____________________�validate�secondary�address�(VALSADR)>*‰|________________________�must�be�in�charge�(control)�of�BUS*A*ˆNOTE:‚DO�NOT�CHANGE�THE�ORDER�OF�BITS�0-4�BECAUSE�THEY�DIRECTLY8*�CORRESPOND�TO�THE�ATTRIBUTES�WORD�IN�THE�CONFIGURATION*�BLOCK�FOR�EACH�DEVICE.*@*…**�NOTE:‚THESE�CAPABILITIES�WHEN�DESIGNATED�IN�THE�TABLE�BELOW9*�ARE�WITH�RESPECT�TO�THE�BUS.‚IF�THAT�PARTICULAR�COMMAND9*�IS�USED�AND�IT�IS�DIRECTED�TOWARDS�A�DEVICE�RATHER�THAN6*�THE�BUS,�THE�BIT�BEING�SET�WILL�TAKE�ON�ITS�OPPOSITE3*�MEANING.‚THAT�IS,�IF�'VALTALK'�IS�SPECIFIED�FOR�A:*�COMMAND,�IF�THE�COMMAND�IS�DIRECTED�TOWARDS�THE�BUS�THAT8*�IMPLIES�THAT�THE�BUS�HAS�TALKER�ABILITIES.�HOWEVER,�IF?*�THAT�SAME�COMMAND�WAS�DIRECTED�TOWARS�A�DEVICE,�THE�'VALTALK'=*�BIT�IMPLIES�THAT�THE�DEVICE�MUST�HAVE�LISTENER�CAPABILITIES<*�BECAUSE�THE�BUS�WILL�BE�TRYING�TO�TALK�TO�IT.�THE�OPPOSITE**�IS�ALSO�TRUE�FOR�THE�'VALLIST'�BIT�ALSO.* 3VALPARTB�DC.W�VALLIST+VALPBUF+VALBTLM+VALLMOD‡INPUT,�DC.W�VALTMOD+VALTALK+VALPBUF+VALBTLM�OUTPUTG�DC.W�VALTALK+VALLIST+VALPBUF+VALSBUF+VALBTLM+VALTMOD‚OUTPUT�WITH�INPUT�DC.W�VALCBUF§REQUEST�STATUS"�DC.W�VALCBUF§CHANGE�CONFIGURATION'�DC.W�VALCBUF§CHANGE�DEF.�CONFIGURATION@�DC.W�VALCTL+VALBUS+VALPBUF+VALSBUF+VALCMOD‰COMMAND�OUT/DATA�OUT?�DC.W�VALCTL+VALBUS+VALPBUF+VALSBUF+VALCMOD‰COMMAND�OUT/DATA�IN/�DC.W�VALCTL+VALBUS+VALSBUF+VALCMOD‘COMMAND�OUT<�DC.W�VALLMOD+VALLIST+VALPBUF+VALBTLM+VALSADR‡READ�SECONDARY=�DC.W�VALTMOD+VALTALK+VALPBUF+VALBTLM+VALSADR‡WRITE�SECONDARY5�DC.W�VALCTL+VALBUS+VALCMOD™PARALLEL�POLL�UNCONFIGURE-�DC.W�VALBDEV+VALCMODŸPARALLEL�POLL�CONFIGURE1�DC.W�VALCTL+VALBUS+VALCMOD™CONDUCT�PARALLEL�POLL-�DC.W�VALBTLM+VALBUS SET�PARALLEL�POLL�STATUS+�DC.W�VALBTLM+VALBUS SET�SERIAL�POLL�STATUS0�DC.W�VALBDEV+VALSRQ+VALCMOD˜CONDUCT�SERIAL�POLL+�DC.W�VALBDEV+VALCMODŸPARALLEL�POLL�DISABLE$�DC.W�VALSCT1 L+VALBUS INTERFACE�CLEAR*�DC.W�VALSCTL+VALBUS+VALCMOD˜REMOTE�ENABLE+�DC.W�VALSCTL+VALBUS+VALCMOD˜REMOTE�DISABLE-�DC.W�VALCTL+VALBUS+VALCMOD™CLEAR�ALL�DEVICES7�DC.W�VALCTL+VALBUS+VALCMOD™CLEAR�ALL�LISTENING�DEVICES)�DC.W�VALCTL+VALBUS+VALCMOD™LOCAL�LOCKOUT1�DC.W�VALCTL+VALBDEV+VALCMOD+VALBCHG‘PASS�CONTROL1�DC.W�VALCTL+VALBUS+VALCMOD™LISTENERS�GO�TO�LOCAL-�DC.W�VALCTL+VALBUS+VALCMOD™LISTENERS�TRIGGER/�DC.W�VALSCTL+VALBUS INTERFACE�AND�DEVICE�CLEAR/�DC.W�VALCTL+VALBUS+VALCMOD™UNTALK�AND�UNLISTEN!�DC.W�VALBUS+VALCMOD TAKE�CONTROL$�DC.W�VALBUS+VALBTLM REQUEST�CONTROL+�DC.W�VALCTL+VALBUS+VALCMOD™RELEASE�CONTROL)�DC.W�VALCTL+VALBUS+VALCMOD™GO�TO�STANDBY,�DC.W�VALBDEV+VALCMODŸSPECIFIED�CLEAR�DEVICE-�DC.W�VALBDEV+VALCMODŸSPECIFIED�REMOTE�DEVICE.�DC.W�VALBDEV+VALCMODŸSPECIFIED�TRIGGER�DEVICE+�DC.W�VALBDEV+VALCMODŸSPECIFIED�GO�TO�LOCAL  PAGE@*****************************************************************>*‚PARAMETER�BLOCK�ELEMENT�SIZE�TABLE�FOR�CONFIGURATION�REQUEST*@****************************************************************PAR_SIZ�DC.B�2…RECORD�LENGTH�DC.B�4ŒDEVICE�SIZE�DC.B�4ŒWRITE�TIMEOUT�VALUE�DC.B�4ŒREAD�TIMEOUT�VALUE�DC.B�4ŒEOR�REQUIREMENTS�DC.B�2ŒEOS�WRITE/READ�CHAR#�DC.B�1ŒPARALLEL�POLL�CONFIGURATION�DC.B�1ŒPRIMARY�ADDRESS3�DC.B�4Œ#�OF�BYTES�IN�FIXED�WRITE�-�FORMATTED/IMAGE2�DC.B�4Œ#�OF�BYTES�IN�FIXED�READ�-�FORMATTED/IMAGE#�DC.B�4ŒREAD�SECONDARY�ADDRESS�MASK$�DC.B�4ŒWRITE�SECONDARY�ADDRESS�MASK(�DC.B�8ŒRESERVED�FOR�LATER�USE/EXPANSION�DC.B�0ŒEND�OF�CONFIGURATION* DS 0=/*=/*†M315DRV.AF=/*==/* Chain file to assemble the MVME315 disk controller driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M315DRV.LS=/*=/IFC \1ƒ=ARG�M315DRV.LS=/ENDIF=/*$=ASM M315DRV.SA,M315DRV.RO,\1;RZ=180=/*{ Included files are:=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*}=/*=ENDéééééé1 9M315DRV„IDNTƒ5,0�VERSAdos�M315�Disk�Driver�3.2�-�11/26/842ŠTTL„VERSADOS�M315�DISK�DRIVER�VER.�3.2�-�11/26/84J***************************************************************************,* IPC -- REV. 1.05 02JUN80 (TB59) STEVE BALL8*�IPC‰2.00�02NOV81�(TL09)�JIM�SMITH�-�SPLIT�IPC�FROM�CMR2*�IPC‰2.01�01FEB82�(TL09)�JIM�SMITH�-�VECTOR�CHAIN.*�IPC‰2.02�23FEB82�(TL09)�JIM�SMITH�-�IOCB�USE7*�IPC‰4.00�01SEP82ˆMARC�BRIEL-�CONFIGURE�CLASS�REQUESTS7*�M315DRV…5.00�19MAY83ˆRONI�WOOD�-�CHANGED�FOR�M315�IPC>*�M315DRV…5.01�7JULY83ˆMARCO�SCHMIDT�-�PATCHES�TO�5.00�CHANGES*¡DISK�CONTROLLER�BOARD. *¡USED�IPCDRV�AS�A�BASE.‚DELETED*¡ALL�REFERENCE�TO�MCCM�STUFF.*¡ALL�OTHER�CHANGES�ARE�MARKED.?*�M315DRV…5.01�06DEC83ˆJULIE�HOBAN�-�CHANGES�MARKED�BY�11/17/83=*�M315DRV…5.01�24JAN84ˆJULIE�HOBAN�-�BUG�FIXES�EFFECTING�INIT*¯CHANGES�MARKED�BY�01/24/848*�M315DRV…5.01�27JAN84ˆJUTTA�KINDERMANN�-�CHANGES�TO�THE*´PARAMETER�DEF.�PART�AND*´THE�CONFIGURE�DISK�PART*´ALL�CHANGES�ARE�MARKED�BY*¸'�01/27/84�'.>*�M315DRV…5.10�23MAR84ˆFRANZ�MARSCHNER‚-�CHANGE�TO�THE�COMMAND*´SERVICE�PART�TO�ENABLE*´USE�IN�THE�VME/10�SYSTEM*´ADDED�TWO�XREF'S�TO*´SATISFY�VME/10�HARDWARE*´DEPENDENCIES*´ALL�CHANGES�ARE�MARKED�BY*¸'�03/28/84�'.<*�M315DRV…5.20�09MAY84ˆJULIE�HOBAN†-�FIX�TO�CONFIGURE�LENGTH*´TABLE:�CHANGES�MARKED�BY*¸'�05/09/84�'.:*�M315DRV…5.30�27AUG84ˆJULIE�HOBAN†-�MODIFIED�TO�USE�MACRO*´DUALPORT.MC�TO�ACCESS*´OFF�BOARD�RAM�ADDRESSES.8*�M315DRV…5.31�17OCT84ˆDICK�VANDERLINƒ-�CONFIGBLK�OFFSET*´DEFINATION(SYMBUG�PROBLEM)<*�M315DRV…5.32�26NOV84ˆJULIE�HOBAN†-�CONFIGURATION�CHECK�$47*´ADDED�-�SAME�AS�VME320.**;*‰NOTE�-----�Many�comments�in�this�driver�refer�to�the�time0*”'currently'.‚This�refers�to�the�time�frame�May.*”and�June�1983.‚It�also�refers�to�this�driver3*”only�in�association�with�the�M315�disk�controller6*”board�and�all�changes/additions�for�that�board�only.*.* USER REQUEST SIDE FOR IPC COMMAND PROCESSING*!(31S90A6I7QDY6a7iCqIy?�F‰5‘D™?¡5©7±1¹:Á@É4Ñ-Ù4á2é3ñ<ùG> AC9*ƒPURPOSE:‚VALIDATE�AND�PASS�IPC�COMMAND�INFORMATION�FROM#*�USER�TO�IPC,�68000�SHARED�MEMORY.**ƒENTRY:‚JSR�FROM�CMR�HANDLER*‹JSR�FROM�INTERRUPT�HANDLER*5*ƒEXIT:‚RTS�-�PARAMETER�BLOCK�VALIDATION�STATUS�IN�D0**ƒEXEC�ROUTINES�CALLED:‚QEVENTT**ƒCODE�IS�RE-ENTRANT*H*-----------------------------------------------------------------------**ŠPAGE *‚Included�Macro�file**ˆ9995.&.DUALPORT.MC**‚Included�equate�files:*ˆ9995.&.TRACE.EQ*ˆ9995.&.STR.EQ*ˆ9995.&.TCB.EQ*ˆ9995.&.CCB.EQ*ˆ9995.&.IOE.EQ*ˆ9995.&.NIO.EQ*ˆ9995.&.LV5.EQ*ŠINCLUDE�9995.&.DUALPORT.MCŠNOLIST ŠTTL�TRACE.SAŠINCLUDE�9995.&.TRACE.EQŠNOLISTŠTTL…9995.&.STR.EQŠINCLUDE�9995.&.STR.EQŠNOLISTŠTTL…9995.&.TCB.EQŠINCLUDE�9995.&.TCB.EQŠNOLISTŠTTL…9995.&.CCB.EQŠINCLUDE�9995.&.CCB.EQŠNOLISTŠTTL…9995.&.IOE.EQŠINCLUDE�9995.&.IOE.EQŠNOLISTŠTTL…9995.&.NIO.EQŠINCLUDE�9995.&.NIO.EQŠNOLISTŠTTL…9995.&.LV5.EQŠINCLUDE�9995.&.LV5.EQŠLISTŠPAGE6ŠTTL„VERSADOS�M315�DISK�DRIVER�VERSION�5.32�-�11/26/84* ŠSECTION�0**$*…EQUATES�FOR�TESTING�VECTOR�NUMBERS*#AVECTLOƒEQU„25‘LOWEST�AUTO�VECTOR�#$AVECTHIƒEQU„31‘HIGHEST�AUTO�VECTOR�##UVECTLOƒEQU„64‘LOWEST�USER�VECTOR�# IPCORG„EQU„*ŠPAGE*6* IPC COMMAND PACKET FORMAT (AS SEEN IN SHARED MEMORY)*4*ˆNOTE:‚The�IPC�driver�never�used�the�packet�ID�byte0*�for�anything�-�the�value�was�always�zero.‚This0*�driver�currently�does�the�same�thing�-�however3*�the�packet�ID�now�is�the�address�modifier�for�the.*�read/write�buffer�addresses.‚If�the�value�is2*�zero�the�MVME315�firmware�uses�a�default�address2*�modifier�-�regular�global�memory.‚Otherwise,�the2*�value�in�packet�ID�is�used�by�the�MVME315�as�the1*�address�modifier�to�use.‚This�is�set-u2 p�for�the4*�future�when�several�processor�boards�are�using�one0*�MVME315�disk�controller�board.‚This�supplies�a0*�way�for�the�disk�controller�to�use�the�correct*�memory�locations. ŠOFFSET�0IPCSTX„DS.Bƒ1*2�START�OF�TEXTIPCPID„DS.Bƒ1*2�PACKET�IDIPCPKSZƒDS.Bƒ1*2�PACKET�SIZE IPCPHDVƒDS.Bƒ1*2�PHYSICAL�DEVICE%IPCCHCMƒDS.Bƒ1*2�CHANNEL�COMMAND�TYPEIPCDVCMƒDS.Bƒ1*2�DEVICE�COMMAND$IPCNBKSƒDS.Bƒ2*2�#BLOCKS�TO�TRANSFERIPCBKSZƒDS.Bƒ2*2�BLOCKSIZE*IPCBUFAD‚DS.Bƒ4*2�68000�ADDRESS�(PHYSICAL)IPCCKSMƒDS.Bƒ2*2�CHECKSUM$IPCCMPRM‚DS.Bƒ4*2�COMMAND�PARAMETERSIPCETX„DS.Bƒ1*2�ETX�LOCATION*9*ˆUIPC�CONFIGURATION�PACKET�-�BOARD�LEVEL�-�COMMAND�$5000*2*ˆThis�is�a�new�packet�set�up�for�the�MVME310�UIPC4*ˆconcept.‚It�passes�basic�information�to�the�board.4*ˆThe�current�impemetation�in�this�driver�is�to�pass4*ˆthe�interrupt�vector�number�to�the�disk�controller3*ˆboard.‚If�this�packet�is�not�sent,�the�board�uses4*ˆa�default�value�of�vector�number�64.�Only�one�byte5*ˆcurrently�contains�a�value,�the�rest�are�zeroed�out6*ˆand�reserved�for�future�use.‚The�command�code�is�$505*ˆand�currently�implemented�function�code�is�00�-�for1*ˆUIPC�configuration�and�control.‚This�command�is3*ˆcompletely�unrelated�to�the�configure�command�the0*ˆdriver�receives�from�VERSAdos.‚This�command�is7*ˆsent�by�the�driver�to�the�board�in�the�initialization7*ˆportion.‚Interrupts�are�inhibited�during�execution�of5*ˆthis�command.‚The�initializer�polls�til�the�command8*ˆis�complete.�If�the�command�fails,�the�board�is�marked*ˆdown�in�the�CCB.*‰OFFSET�IPCNBKSIPCVECT‚DS.Bƒ1*2�vector�number(IPCRESV‚DS.Bƒ1*2�reserved�for�future�use)IPCRESV1�DS.Bƒ4*2�reserved�for�future�use)IPCRESV2�DS.Bƒ4*2�reserved�for�future�use)IPCRESV3�DS.Bƒ4*2�reserved�for�future�use)IPCRESV4�DS.Bƒ4*2�reserved�for�future�use)IPCRESV5�DS.Bƒ4*2�reserved�for�future�useIPCVETX‚DS.Bƒ1*2�ETX�location*<*‰UIPC�Drive/Media�configuration�packet�-�command�code�$4008*9*‰This�command�is�used�to�tell�the�board�how�the�floppies<*‰and�hard�disks�are�configured.‚It�is�sent�on�behalf�of�the6*‰driver�receiving�either�a�configuration�command�or�a?*‰default�configuration�command�from�VERSAdos.‚This�is�normally:*‰done�during�boot�time�by�IOI,�once�for�each�drive.‚Mount;*‰and�Init�also�issue�these�commands.‚If�these�commands�are:*‰not�sent�to�the�board�the�board�assumes�several�defaults<*‰depending�on�the�disk�size.‚The�M315�disk�controller�knows?*‰if�the�floppy�is�single�or�double�track�density�by�the�number*‰of�sectors�per�track.*+*‰The�defaults�assumed�for�8"�floppies�are:B*‰MOTOROLA�format,�double�sided,�single�density,�128�byte�sectors,=*‰77�cylinders,�no�interleaving,�no�spiral�offset,�26�sectors *‰per�track./*‰The�defaults�assumed�for�5�1/4"�floppies�are:D*‰IBM�format,�double�sided,�double�density,�96TPI,�256�byte�sectors,=*‰80�cylinders,�no�interleaving,�no�spiral�offset,�16�sectors *‰per�track.*B*‰The�physical�device�numbers�for�floppies�are�04,�05,�06,�and�07.**‰FLOPPY�DISK�CONFIGURE�PACKET*ŠOFFSET�IPCNBKS$IPCFATR0‚DS.Bƒ1*2�attributes�byte�#0*(*‰bit�definitions�of�attributes�byte�#0:*G*‚bit�0�=�0�=�if�a�compensation�value�is�specified�it�is�write�pre-comp?*Š1�=�if�a�compensation�value�is�specified�it�is�read�post-comp=*‚bit�1�=�0�=�compensation�value�is�specified‚(byte�$F�value))*Š1�=�compensation�value�is�not�specified*‚bit�2�=�0�=�5�1/4"�diskette=*Š1�=�8"�diskette‚(�if�26�or�52�sectors/track�diskette�is�8")*‚bit�3�=�not�defined#*‚bit�4�=�0�=�single�sided�diskette*Š1�=�double�sided�diskette**‚bit�5�=�0�=�single�density�(FM�encoding)#*Š1�=�double�density�(MFM�encoding)*‚bit�6�=�0�=�no�spiral�offset*Š1�=�spiral�offset*‚bit�7�=�0�=�IBM�formatting*Š1�=�MOTOROLA�formatting$IPCFATR1‚DS.Bƒ1*2�attributes�byte�#1(*‰bit�definitions�of�attributes�byte�#1:B*‚bits�0,1,2�=�stepping�rate.�If�zero�the�M315�uses�6�milliseconds.*�for�8"�and�12�milliseconds�for�5�1/4"�disks.* *ž8"‘5�1/4"2 *!*�=�001‡3�millisecs.‰6�millisecs."*�=�010‡6�millisecs.ˆ12�millisecs.#*�=�011†10�millisecs.ˆ20�millisecs.#*�=�100†15�millisecs.ˆ30�millisecs.*"IPCFSPTƒDS.Bƒ1*2�sectors�per�track6IPCFSIDƒDS.Bƒ1*2�#�of�sides�-�either�01�or�02�is�valid5IPCFSLGƒDS.Bƒ2*2�sector�length�in�bytes�-�either�128,"*§256,�512�or�1024.‚Currently�only'*§128�and�256�are�being�used.‚The�board)*§does�double�reads�for�sector�length�128IPCFNC„DS.Bƒ2*2�#�of�cylinders8IPCFPCNƒDS.Bƒ1*2�1st�cylinder�with�compensationƒ01/27/84*-IPCFNU0ƒDS.Bƒ1*2�not�used�by�MVME315Ž01/27/84*#IPCFNU„DS.Bƒ4*2�not�used�-�reserved!IPCFIF„DS.Bƒ1*2�interleave�factor$IPCFNU1ƒDS.Bƒ1*2�not�used�-�reserved$IPCFNU2ƒDS.Bƒ4*2�not�used�-�reserved$IPCFNU3ƒDS.Bƒ2*2�not�used�-�reservedIPCHFETX‚DS.Bƒ1*2�ETX�location**9*‰The�layout�and�associated�values�are�different�for�hard:*‰disks�from�the�floppy�disks.‚If�this�command�is�not�sent;*‰to�the�controller�or�if�the�values�in�the�packet�are�zero"*‰the�following�defaults�are�used:@*‰4�heads,�256�byte�sectors,�256�cylinders,�128�pre-compensationA*‰value,�128�reduced�write�current,�and�7�bits�of�ECC�data�burst.7*‰This�actually�defines�an�8"�10�megabyte�(unformatted)*‰Winchester�disk.*D*‰The�physical�device�numbers�for�hard�disks�are�00,�01,�02,�and�03.**‰HARD�DISK�CONFIGURE�PACKET*ŠOFFSET�IPCFSPT,IPCHSPTƒDS.Bƒ1*2�#�of�sectors/track…01/27/84IPCHNOHƒDS.Bƒ1*2�#�of�heads'IPCHSLGƒDS.Bƒ2*2�sector�length�in�bytesIPCHNC„DS.Bƒ2*2�#�of�cylinders1IPCHPC„DS.Bƒ2*2�write�pre-compensation�cylinder�#2IPCHRWCƒDS.Bƒ2*2�reduced�write�current�cylinder�#.&IPCHECCƒDS.Bƒ1*2�ECC�data�burst�length,IPCHSCAƒDS.Bƒ1*2�SASI�controller�ID�01/27/84,*£The�actual�version�of�the�MVME315�01/27/84,*£firmware�expects�the�sasi�contrl.�01/27/84+*£ID�at�this�location�for�the�con-‚01/27/84+*£figure�command�and�in�the�device‚01/27/84)*£#�byte�for�the�other�commands.„01/27/84**£In�a�later�revision�it�might�beƒ01/27/84**£changed,�to�only�use�the�deviceƒ01/27/84(*£number�byte�for�all�commands.…01/27/84(*£For�further�info�refer�to�the…01/27/84*£MVME315�manual.“01/27/84!IPCHIF„DS.Bƒ1*2�interleave�factor#*§The�remaining�fields�are�the�same!*§as�the�floppy�configure�packet.** FORMAT TRACK PACKETŠOFFSET�IPCBUFAD'IPCFPSNƒDS.Bƒ4*2�PHYSICAL�SECTOR�NUMBERIPCFETXƒDS.Bƒ1*2�ETX�LOCATION** FORMAT DISK PACKETŠOFFSET�IPCNBKSIPCDETXƒDS.Bƒ1*2�ETX�LOCATION** REQUEST STATUS PACKETŠOFFSET�IPCNBKSIPCRETXƒDS.Bƒ1*2�ETX�LOCATION* * IPC RETURN (COMPLETION) PACKET* ŠOFFSET�0RTNSTX„DS.Bƒ1*2�START�OF�TEXTRTNPID„DS.Bƒ1*2�PACKET�I.D.RTNPKSZƒDS.Bƒ1*2�PACKET�SIZE RTNPHDVƒDS.Bƒ1*2�PHYSICAL�DEVICE RTNCHCMƒDS.Bƒ1*2�CHANNEL�COMMANDRTNSTCMƒDS.Bƒ1*2�STATUS�COMMANDRTNSTVLƒDS.Bƒ2*2�STATUS�VALUERTNSTPRƒEQU„*’STATUS�PARAMETERS** IPC NORMAL COMPLETION EVENT*ŠOFFSET�RTNSTPRRTNBLKSƒDS.Bƒ2*2�NO.�OF�BLOCKSRTNBKSZƒDS.Bƒ2*2�BLOCK�SIZE#RTNDADRƒDS.Bƒ4*2�68K�MEMORY�ADDRESS** DISK ERROR COMPLETION EVENT*ŠOFFSET�RTNSTPR%RTNSECNƒDS.Bƒ4*2�ENDING�SECTOR�NUMBER** DISK STATUS RETURN*ŠOFFSET�RTNSTPRRTNDSTAƒDS.Bƒ2*2�DEVICE�STATUS RTNLSECƒDS.Bƒ4*2�LOGICAL�SECTORS*‰OFFSET�RTNSTPRRTNSTAD‚DS.B…4*2’DEVICE�STATUS** IPC MEM MAPPED EQUATES*;*‚The�MVME315�does�not�have�an�IPC�interrupt�byte,�nor�does;*‚it�have�a�reset�interrupt�byte.�Every�byte�written�to�the=*‚command�channel�interrupts�the�board.‚All�references�to�the=*‚software�interrupt�are�deleted�in�the�driver.‚If�the�driver>*‚determines�a�need�for�a�reset,�the�board�is�marked�in�error.=*‚The�driver�used�to�try�to�issue�a�reset�if�it�found�a�fatal@*‚error�-�such�as�the�command�packet�from�the�IPC�was�clobbered.*-*IPCINT„EQU„$0D�68000�TO�IPC�INTERRUPT�OFFSET+*IPCRESET‚EQU„$0F�68000�TO�IPC�RESET�OFFSET'IPCIMB1ƒEQU„$101�68000�TO�IPC�WRITE�BOX%IPCIAB1ƒEQU„$103�68000�TO�IPC�ACK�BOX#IPCIM1„EQU„$105�68000�COMMAND�WRITE'IPCIMB2ƒEQU„$181�IPC�TO�68000�WRITE�BOX%IPCIAB2ƒEQU„$183�IPC�TO�68000�ACK�BOX!IPCIM2„EQU„$185�IPC�COMMAND�WRITE* * 3 STRUCTURE FOR DEVICE NO. TABLE*9*�The�address�of�this�table�is�in�the�CCB.‚The�memory�for<* this table gets allocated in the initialization section of>*�the�driver.‚The�length�is�dependent�on�#�of�devices�and�each<*�entry�length.‚The�number�of�devices�is�now�set�to�12.‚Each>* entry pertains to a disk - the disk device number is used to?* determine where in the table the entry is; ie, drive 0 is theF*�1st�entry,�drive�1�the�2nd,�etc.‚The�complete�IOCB�for�configurationF* is saved in this table - it is defined as the current configuration.>* The default configuration is save in the DCB for each drive.* ‰OFFSET�0LUFLG„DS.Bƒ2–ENTRY�FLAGLUDCB„DS.Bƒ4–DCB�ADDRESSLUIOCBƒDS.Bƒ4–IOCB�ADDRESSLUTCB„DS.Bƒ4–TCB�ADDRESSLUBADRƒDS.Bƒ4–BUFFER�ADDRESS.ACTIVEƒDS.Bƒ1–ACTIVE�FLAG�-�USED�FOR�CONFIGURE$MOUNTED‚DS.Bƒ1–MOUNTED/DISMOUNT�FLAG,CONFGBLK�EQU„*-IOSATW�OFFSET�TO�CONFIG�BLOCK3LUCONFƒDS.BƒIOSDLN-IOSATWŠconfigure�parameter�block(LUENTRY‚EQU„*–LENGTH�OF�DEVICE�NO.�ENTRY** EQUATES FOR 'LUFLG'*LUFEOFƒEQU„0–EOF�PENDINGLUFHLTƒEQU„1–HALT�PENDING"LUFXFRƒEQU„2–DATA�TRANSFER�REQUESTLUFACTƒEQU„15•ACTIVE�DEVICE** MISCELLANEOUS EQUATES*STX‡EQU„$02�start�packet�codeETX‡EQU„$03�end�packet�codeACK‡EQU„$06�ack�codeNAK‡EQU„$15�nak�code%LUMAX…EQU„12‘MAXIMUM�DEVICE�NO.�VALUE3SECOFF„EQU„4’OFFSET�TO�NO.�OF�SECTORS�IN�CONFIG�TBL(RTNGDC„EQU„$70�NORMAL�STATUS�PACKET�CODE,RTNHLT„EQU„$71�HALT/ABORT�STATUS�PACKET�CODE+RTNSTA„EQU„$72�SOLICITED�STATUS�PACKET�CODE&RTNUNS„EQU„$80�UNSOLICITED�PACKET�CODE"RTNGDS„EQU„$0000ŽGOOD�STATUS�VALUE,SPKT†EQU„$0200ŽFIRST�2�BYTES�OF�EVERY�PACKETDLUPAGE„EQU„(LUMAX*LUENTRY+256)/256�NO.�OF�PAGES�FOR�DEVICE�NO.�TABLE+SECSIZƒEQU„$100“SYSTEM�REQUIRED�SECTOR�SIZE'IOPKSZ„EQU„21”READ�OR�WRITE�PACKET�SIZE'STPKSZ„EQU„7•STATUS�REQUEST�PACKET�SIZE#CNPKSZ„EQU„29”CONFIGURE�PACKET�SIZE$FDPKSZ„EQU„7•FORMAT�DISK�PACKET�SIZE&FTPKSZ„EQU„15”FORMAT�TRACK�PACKET�SIZEHLTPKSZƒEQU„7•HALT�PACKET�SIZEIOEVCD„EQU„1•I/O�EVENT�CODE*DSKATM„EQUƒ$031F�supported�attributes�mask)IOATM…EQUƒ$031F�supported�attributes�mask/NVALATMƒEQUƒ$FFFF-DSKATMˆunsupported�attributes+DSKPRMM„EQUƒ$DBF3�supported�parameters�mask)IOPRM†EQUƒ$DBF3�supported�parameters�mask0NVALPRMƒEQU„$FFFF-DSKPRMM‡unsupported�parameters$VDOSRSZ‚EQU‡256‘VERSAdos�sector�sizeLCDSCTBT�EQU‡7@LCDSCTSZ�EQU‡1<*ˆAPPROXIMATELY�225�INSTRUCTIONS�EXECUTED�TO�GET�TO�THIS�POINT *ˆ(600�us).*J******************************************5 *********************************IOHUSER:** CHECK FOR RESET*ƒIF�RESET,�DO�IT�AND�GET�OUT*)ŠCMP.B‚#XDREST,XIOSCD(A2)�TEST�RESET�BYTE#ŠBNE.S‚IOH01000‹BRANCH�IF�NOT�RESETŠBSR„CMRRESTŒCALL�RESET�ROUTINEŠBRA„IPCUSRTN‹RETURN*$* RETURN IF CHANNEL IS IN ERROR MODE*!IOH01000‚BTSTW‚#CCBFGER,CCBFG(A5)2ŠBEQ.S‚IOH01010‹BRANCH�IF�NOT�MARKED�IN�ERROR�MODE)ŠMOVE.B�#ISTACDN,D1ˆSET�UP�IOS�ERROR�CODE ŠBRA„ABORT*D* IF WE ARE WAITING FOR ACK/NAK THEN WE CANNOT HONOR THE REQUEST AND2*ƒMUST�SIGNAL�THE�CALLER�THAT�THE�CHANNEL�IS�BUSY.*IOH01010‚EQU„* ŠCLR.L‚D7<*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>)*ˆN�O�T�E�!�!�!�!�!�!œNOT:Is�deleted�(MS)1*ˆWhen�the�M315�board�has�queuing�delete�the�line *ˆBRA.S�TEMP3*ˆThis�is�only�for�testing�and�must�be�deleted�from.*ˆthe�released�version�of�the�driver�!�!�!�!�!=*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+TEMP†BTSTW‚#CCBFGWAK,CCBFG(A5)�WAITING�ACK?)ŠBEQ.S‚IOH01020‹BRANCH�IF�NOT�WAITING�ACK$ŠBRA.S‚TEMP�loop�til�channel�is�free*F* REQUEST CAME THRU WHILE WAITING FOR ACK - GIVE USER BACK BUSY STATUS*$ŠMOVE.B�#XSTBSY,D0‡ERROR�RETURN�CODE ŠBRA„IPCUSRTN*(* CONVERT LOGICAL PB ADDRESS TO PHYSICAL*IOH01020‚CLR.L‚D5,ŠMOVE.L�XIOCPK(A2),D6†ADDR�OF�COMMAND�PACKET+ŠMOVE.W�XIOPLN(A2),D5†LENGTH�OF�COMMAND�PKT"ŠMOVE.L�CCBTASKA(A5),A1„SET�UP�TCB ŠBSR„IOHADRCKŠBRA.S‚IOH01060‹GOOD�RETURNŠNOP—BAD�LENGTH�RETURN(ŠMOVE.B�#ISTAIP,D1‰SET�UP�IOS�ERROR�CODE ŠBRA„ABORT5IOH01060‚MOVE.L�D6,A3ŽCOMMAND�PACKET�PHYSICAL�ADDRESS*3* DETERMINE IF SHARED MEMORY IS FREE (IT SHOULD BE)*.ŠMOVE.L�CCBCHB(A5),A4†MEMORY�MAPPED�BASE�TO�A4ŠMOVE.B�IPCIMB1(A4),D00ŠBEQ.S‚IOH02060‹BRANCH�IF�NO�ERROR�(MEMORY�FREE)*:* SHARED MEMORY IS NOT FREE AND WE ARE NOT WAITING ON ACK.*ƒERROR�CONDITION.*)ŠBSETW‚#CCBFGER,CCBFG(A5)�MARK�CCB�AS�BAD)ŠMOVE.B�#ISTACDN,D1ˆSET�UP�IOS�ERROR�CODE ŠBRA„ABORTŠPAGEK****************************************************************************(*‚FIND�THE�COMMAND�IN�THE�COMMAND�TABLE.* IOH02060‚EQU„*)ŠMOVE.L�XIOUID(A2),A4†PICK�UP�DCB�POINTER8ŠMOVE.L�CCBTASKA(A5),CCBTASKB(A5)�SET�UP�BUFFER�TASK�TCB-ŠMOVEQ‚#NUMCMDS-1,D0†Set�up�the�loop�counter./ŠLEA„CMDTBL,A0ŠA0�<--�address�of�command�table./ŠMOVE.W�IOSFCT(A3),D6†Set�up�user�command�code. 8CMDSRCHƒCMP.W‚(A0)+,D6‹Search�the�table�for�the�command.ŠDBEQƒD0,CMDSRCH‰* 3ŠBNE.S‚CMDERR�If�we�found�the�command�in�the�table,8ŠADD.L‚#JMPOFF-2,A0‡get�the�corresponding�entry�from�the5ŠMOVE.W�(A0),D0Œjump�table�and�jump�to�the�routine�to"ŠJMP„(A0,D0.W)Šhandle�the�command.ŠSPC„2>CMDERR„MOVE.B�#ISTAIF,D1ŠThe�command�wasn't�found�in�the�table2ŠBRA„ABORTŽso�exit�with�an�invalid�function�error.ŠPAGEM*******************************************************************************‰REQUEST�STATUS2*‰This�command�is�a�request�status�to�the�MVME315.:*‰It�is�to�return�the�current�configuration�to�the�caller.6*‰It�first�issues�a�request�status�call�to�the�driver.8*‰In�the�interrupt�service�routine�the�CCB�configuration;*‰information�is�returned�to�the�user�along�with�the�status*‰from�the�board..*(*‰Entry:�A2�=�address�of�CMR�param�block*�A3�=�address�of�user's�IOCB*�A4�=�address�of�DCB*�A5�=�address�of�my�CCB*�A6�=�address�of�user's�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*™and�address�of�device�tableM******************************************************************************REQSTAT:6ŠMOVE.Lƒ#IOSDLN,D5Šlength�of�configure�parameter�block<ŠMOVE.LƒIOSDBP(A3),D6‡logical�address�of�configure�para.�blk+ŠBSR†BUFADDR�get�the�physical�address�of�it<ŠMOVE.LƒD6,CCBPTR(A5)‡save�phys.�addr�of�configure�para.�blk ŠCLR.L„D6,ŠBSR„DEVTBL�get�get�device�table�entry�stuff%ŠMOVE.L‚A0,A1�address�of�top�of�table"ŠADD.LƒD0,A1�address�of�this�entry/ŠLEA…LUCONF(A1),A2ˆaddress�of�this�config�blockŠCLR.L‚D5‘clear�for�later�use/ŠBSR.S‚STATCONF‹STATCONF�sets�up�A0�to�point�to&*£the�IOSATM�fie5 ld�of�the�users�status%*£parameter�block.‚It�also�determines&*£the�drives�device�status�and�sets�up(*£the�first�group�of�fields�in�the�users*£status�parameter�block.9L0110…EQU„IOATM<<16ŠSet�IOSATM�field�and�the�IOSPRM�field?ŠMOVE.L�#L0110+IOPRM,(A0)+�in�the�users�status�para.�block.‚The%*£values�we�return�are�significant�to*£this�driver.L0120…EQU„IOSDLN-IOSATWL0121…EQU„L0120/2L0122…EQU„L0121*2*ŠMOVEQ‚#L0121-1,D0ˆnumber�of�words�to�move;L0130…MOVE.W�(A2)+,(A0)+ˆcopy�current�configuration�to�userŠDBRAƒD0,L0130ŠCLR.L„D1’set�for�good�return0ŠLEA†-$48(A2),A2‰*MS�adjust�A2�for�ABORT�routine.ŠBRA†ABORT�use�abort�to�queue�event�and�returnŠPAGEL***************************************************************************** *‰STATUS/CONFIGURE�COMMON�CHORES*6*‰This�subroutine�performs�functions�common�to�status,,*‰configure,�and�default�configure�commands.*+*‰entry:‚A1�=�pointer�to�device�table�entry!*‘A2�=�IOSATW�field�in�CCB�or�DCB*‘A3�=�physical�address�of�IOCB*‘A5�=�physical�address�of�CCB*M***************************************************************************** STATCONF:7ŠMOVE.L�IOSDBP(A3),D6†get�physical�address�of�the�first!*§location�of�the�users�configure*§parameter�block)ŠMOVE.L�#IOSDLN,D5‰parameter�block�length0ŠMOVE.L�A1,-(A7)‹save�device�table�entry�pointer0ŠBSR„BUFADDRŒconvert�logical�to�physical�address3ŠMOVE.L�(A7)+,A1‹restore�device�table�entry�pointerSTATCON1‚MOVE.L�D6,A0Žsave�it&ŠMOVE.L�D6,CCBPTR(A5)†save�in�CCB�also1ŠTST.B‚MOUNTED(A1)ˆif�the�disk�is�not�mounted�set'ŠSEQ.B‚(A0)�XDSNRB�BIT�of�device�status-ŠAND.B‚#1<*‰updated�in�the�interrupt�service�routine�after�the�configure>*‰call�to�the�board�is�complete.‚The�mounted/dismounted�optionB*‰is�checked�to�see�if�the�DCB�must�be�changed�for�mount/dismount.*(*‰Entry:�A2�=�address�of�CMR�param�block*�A3�=�address�of�user's�IOCB*�A4�=�address�of�DCB*�A5�=�address�of�my�CCB*�A6�=�address�of�user's�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*™and�device�tableM****************************************************************************** CONFIGUR: 3ŠMOVE.L�#IOSDLN,D5‰configure�parameter�block�length<ŠMOVE.LƒIOSDBP(A3),D6„logical�address�of�configure�para.�blk(ŠBSR†BUFADDRŠconvert�to�physical�address?ŠMOVE.LƒD6,CCBPTR(A5)„save�the�phy.�addr�of�configure�para.�blk ŠCLR.L„D6&ŠBSET„#LUFACT,D6ˆset�for�active�device%ŠBSR†DEVTBL‹set�up�device�table�entry!ŠMOVE.LƒA0,A1Œtop�of�device�tableŠADD.L„D0,A1Œtop�of�this�entry9ŠMOVE.LƒA2,D7Œmust�save�the�parameter�block�addr�11/17/83/ŠLEA…LUCONF(A1),A2…sart�of�this�configure�block2L0220…EQU„DCBDKC+IOSWTO†write-timeout�field�in�DBC>2,D1†get�VERSAdos�sector�size‰ASL.L…#2,D1�make�it�real3L0326„EQU‡IOSREC-IOSDRSV†point�to�record�size�field ‰MOVE.W„D1,L0326(A0)ˆand�save�it*‰DIVU†D0,D1�see�if�record�size�makes�sense‰SWAP†D1*‰AND.W…#(1<�error�01/27/84%CONERR46�EQU‡$46‘disk�size�error�code'‰MOVEQ…#CONERR46,D3ˆset�up�just�in�case‰MOVEQ.Lƒ#0,D5�clear�for�use*8*ˆCompute�the�number�of�sides�on�a�floppy�disk�to�use�in6*ˆcalculation�of�logical�sectors.‚Determine�rigid�disk9*ˆor�floppy�from�the�#IOARDISC�bit�o�the�attributes�word.6*ˆIf�a�floppy,�set�D5�=�1�for�a�single-sided�diskette.9*ˆDetermine�the�actual�number�of�sides�from�#IOADSIDE�bit6*ˆof�the�attributes�word.‚If�double-sided,�set�D5�=�2.*2LC000„EQU‡IOSATW-IOSDRSV†offset�to�attributes�word0‰BTSTW…#IOARDISC,LC000(A0)�see�if�floppy�or�hard"‰BNE.S…LC010�branch�if�a�hard�diskM********* Configuration check for floppies only ***************** JH 11/26/845CONERR47�EQU†$47”Get�the�error�code�that�we'll�use�to6‰MOVEQ„#CONERR47,D3‰indicate�that�we�don't�support�the)*¦proposed�configuration.�We'll�keep�this(*¦error�code�in�D3.B�as�we�make�computa-$*¦tions�regarding�the�configuration. 9‰BTSTWƒ#IOADDEN,LC000(A0)„Single-�or�double-data�density? ‰BEQ.SƒCNF172?EQ375„EQU…IOSPSM-IOSDRSVŠAt�this�time,�Versados�and�this�driver5‰CMP.Wƒ#256,EQ375(A0)ˆsupport�the�double�data-density5‰BNE…CONERRORŽconfiguration�with�256�bytes�per�sector.‰BRA.SƒCNF175�ONLY�and�the�single�data-densityCCNF172ƒCMP.Wƒ#128,EQ375(A0)ˆconfiguration�with�128�bytes�per�sector‰BNE…CONERRORŽONLY.6CNF175ƒMOVEQƒ#CONERR46,D3ŠRestore�disk�size�error�codeN********************************************************************* 11/26/84‰ADDQ.L„#1,D5�set�for�floppy8‰BTSTW…#IOADSIDE,LC000(A0)�see�if�single�or�double�sided#‰BEQ.S…L0845�branch�if�single�sided"‰ADDQ.L„#1,D5�set�for�double�sided‰BRA.S…L0845�and�go�continueLC010>L0840„EQU‡IOSHDS-IOSDRSV†offset�to�number�of�heads�-�hard�disk(‰MOVE.B„L0840(A0),D5ˆget�number�of�heads‰PAGE*<*ˆCompute�the�total�numberr�of�logical�sectors�for�an�entireC*ˆhard�disk�as�IOSSPT*IOSHDS*IOSTRK,�and�IOSSPT*�#�of�heads�*IOSTRK?*ˆfor�a�floppy.‚The�order�of�multiplication�is�important�as�theB*ˆfirst�2�factors�are�both�one-byte�values,�thus�assuring�that�the.*ˆintermediate�product�doesn't�exceed�16�bits.*0L0845„MULU†D5,D2�#�of�heads�by�sectors�per�track7L0850„EQU‡IOSTRK-IOSDRSV†offset�the�number�of�cylinders.‰MULU.W„L0850(A0),D2ˆtimes�number�of�cylinders?CNERROR2�BEQ‡CONERROR‹cannot�be�zero�-�some�value�must�be�wrong6‰CMP.L…#LSNMASK,D2‰see�if�bigger�than�largest�possible1‰BHI‡CONERRORŒbranch�if�to7 o�big�-�error�somewhere*@*ˆIf�the�disk�is�a�double�density�floppy�disk,�subtract�IOSSPT/2=*ˆfrom�the�total�number�of�logical�sectors�to�account�for�the<*ˆfact�that�the�sectors�in�track�zero�are�single�density�and*ˆhalf�the�size�of�the�rest.*2L0860„EQU‡IOSATW-IOSDRSV†offset�to�attributes�word/‰BTSTW…#IOADDEN,L0860(A0)‚see�if�double�density$‰BEQ.S…L0870�branch�if�single�desity)‰LSR‡#1,D0�get�(sectors/track)/2‰01/27/846‰BHI.S…SUBSETR�if�even,�use�(sectors/track)/2‚01/27/843‰ADDQ†#1,D0�if�odd,�incr.(sectors/track)/2‚01/27/843SUBSETR‚SUB.L…D0,D2�get�rid�of�1/2�track�of�sectors3CNERROR3�BLS‡CONERRORŒbranch�if�less�than�0�-�error*>*ˆNow�lets�see�have�many�VERSAdos�sized�sectors�we�really�have*L0870„MOVE.L„D2,D0�sector�count‰CLR.W…D2’clear�for�use‰SWAP†D2$‰DIVU†D1,D2�divide�by�VDOSRSZ/IOSPSM5L0880„EQU‡IOSRSZ-IOSDRSV†offset�to�total�sector�count"‰MOVE.W„D2,L0880(A0)ˆand�save�half‰MOVE.W„D0,D2�do�for�the�rest ‰DIVU†D1,D2$‰MOVE.W„D2,L0880+2(A0)†save�the�rest‰PAGE*4*ˆNow�copy�the�proposed�configuration�from�the�users6*ˆconfiguration�parameter�block�into�the�configuration<*ˆparameter�block�being�updated�(either�the�CCB�or�the�DCB).*3‰MOVEQ…#IOSDRSV-IOSATW-1,D0Šnumber�of�bytes�to�move8L0330„MOVE.B„-(A0),-(A2)‰do�the�move-start�at�the�bottom-‰DBRA†D0,L0330ŒA2�points�to�IOSATW�at�the�end;‰BTSTW…#CCBFCF,CCBFG(A5)ƒsee�if�this�is�a�default�configure2‰BNE.S…L0830�branch�if�a�default�configure�command*8*ˆThis�section�of�code�is�only�for�the�configure�command*6*ˆSee�if�this�is�a�mount,�dismount,�or�configure�only.:*ˆIf�IOSOPT�field�is�zero�this�is�a�mount�command.�Set�the:*ˆmounted�flag�to�indicate�this.‚If�the�IOPDMNT�bit�is�set;*ˆthis�is�a�dismount�and�we�have�to�tell�ourselves�that�and2*ˆVERSAdos�also.‚VERSAdos�will�then�know�to�change;*ˆback�to�default�configuration�and�the�volume�is�no�longer*ˆthere.*7‰MOVE.W„IOSOPT(A3),D0‡get�the�options�field�of�the�IOCB'‰BNE.S…L0820�branch�if�dismount�command#‰ST.B†MOUNTED(A1)‰set�mounted�field,L0820„ROL.W…#15-IOPDMNTB,D0…get�dismount�bit‰BPL.S…L0830�branch�if�mount$‰CLR.B…MOUNTED(A1)‰set�to�dismounted)‰ST.B†DCBCCF(A4)Šset�dismount�in�DCB�also3L0830„BSR‡STATCON1Œgo�update�device�status�and�type‰PAGE*@*ˆNow�build�the�packet�information�for�the�disk�controller�board*%‰BSR‡SETPKTŽset�initial�packet�header%‰MOVE.W„#XCONFIG,D1‰configure�command!‰MOVEP.WƒD1,IPCCHCM(A1)†to�packet8‰MOVE.L„CCBPTR(A5),A0‡get�user's�parameter�block�address1‰MOVE.B„#CNPKSZ,IPCPKSZ(A1)�29�byte�packet�length6‰BTSTW…#IOARDISC,IOSATW(A0)Šsee�if�floppy�or�hard�disk#‰BNE‡CONFH010Œbranch�if�a�hard�disk*(*ˆbuild�floppy�disk�configuration�packet*ˆdo�attributes�byte�0�first%*ˆA0�=�user's�parameter�block�address!*ˆA1�=�M315�shared�memory�address*!‰CLR.L…D1ˆbuild�attributes�byte�0'‰BTSTW…#IOASIZE,IOSATW(A0)�8"�or�5.25"?4‰BEQ.S…CONFF010‚branch�if�5.25�-�is�also�the�default‰BSET†#2,D1…set�for�8"�disketteA‰BRA.S…CONFF020‚leave�compensation�attrib.�bit�unchanged�01/27/84;CONFF010�BSET†#1,D1…set�no�compensation�for�5�1/4"‹01/27/84CONFF020�CLR.L…D2-‰MOVE.W„IOSPCOM(A0),D2…get�the�pre-comp�value.‰MOVEP.WƒD2,IPCFPCN(A1)�set�the�pre-comp�value2‰BTSTW…#IOADPCOM,IOSATW(A0)‚pre-comp�or�post-comp?8‰BEQ.S…CONFF030Œbranch�if�pre-�also�the�default�01/27/84%‰BSET†#0,D1�set�for�post-compensation1CONFF030�BTSTW…#IOADSIDE,IOSATW(A0)†single�sided?(‰BEQ.S…CONFF040Œbranch�if�single�sided�- ‰BSET†#4,D1�set�for�double�sided/CONFF040�BTSTW…#IOADDEN,IOSATW(A0)�FM�encoding?‰BEQ.S…CONFF050Œbranch�if�FM ‰BSET†#5,D1…set�for�MFM�encoding0CONFF050�TST.B…IOSSOF(A0)Šspiral�offset?�11/7/83*‰BEQ.S…CONFF060Œbranch�if�no�spiral�offset!‰BSET†#6,D1�set�for�spiral�offset.CONFF060�BTSTW…#IOAFRMT,IOSATW(A0)�IBM�format?‰BNE.S…CONFF070‚branch�if�IBM#‰BSET†#7,D1…set�for�Motorola�format5CONFF070�MOVE.B„D1,IPCFATR0(A1)…set�attributes�byte�0**ˆattributes�byte�1*‰CLR.L…D1ˆclear�for�use*‰MOVE.B„IOSSR(A0),D1ˆget�the�stepping�rate!‰CMP.B…#0,D1�is�it�zero?“01/27/8407 ‰BNE.S…CONFF080Œno�-�save�stepping�rate‡01/27/847‰BTSTW…#IOASIZE,IOSATW(A0)�yes�-�5�1/4"�or�8"?‹01/27/844‰BEQ.S…CONFF075Œ5�1/4",�use�stepping�code�1ƒ01/27/84-‰ADD.B…#1,D1�8",�use�stepping�code�2‡01/27/842CONFF075�ADD.B…#1,D1�stepping�code�1�or�2Š01/27/845CONFF080�MOVE.B„D1,IPCFATR1(A1)…set�the�stepping�rate**ˆrest�of�the�packet*0‰MOVE.B„IOSSPT(A0),IPCFSPT(A1)ˆsectors�per�track"‰MOVE.B„#1,D1™set�for�single�sided/‰BTSTW…#IOADSIDE,IOSATW(A0)�is�it�single�sided?&‰BEQ.S…CONFF090‚branch�if�single�sided"‰MOVE.B„#2,D1…set�for�double�sided-CONFF090�MOVE.B„D1,IPCFSID(A1)†set�#�of�sides%‰MOVE.W„IOSPSM(A0),D1‡get�sector�size'‰MOVEP.WƒD1,IPCFSLG(A1)†set�sector�size(‰MOVE.W„IOSTRK(A0),D1‡get�#�of�cylinders‰MOVEP.WƒD1,IPCFNC(A1)‡set�it ‰CLR.L…D1)‰MOVEP.LƒD1,IPCFNU(A1)‡clear�unused�bytes3‰MOVE.B„IOSILV(A0),IPCFIF(A1)…set�interleave�factor‰BRA.S…CONFH050“and�continue*&*ˆbuild�packet�for�hard�disk�configure*CONFH010�CLR.L…D1&‰MOVEP.WƒD1,IPCFATR0(A1)…no�attributes9‰MOVE.B„IOSSPT(A0),IPCHSPT(A1)ˆset�sectors/trackƒ01/27/84-‰MOVE.B„IOSHDS(A0),IPCHNOH(A1)ˆset�#�of�heads%‰MOVE.W„IOSPSM(A0),D0‡get�sector�size'‰MOVEP.WƒD0,IPCHSLG(A1)†set�sector�size/*ˆMOVE.W„#$8000,D0‹set�for�defaults�on�pre-comp0*ˆBTSTW…#IOSPCOMB,IOSPRM(A0)Špre-comp�specified?(*ˆBEQ.S…CONFH020Œbranch�if�not�specified)‰MOVE.W„IOSPCOM(A0),D0†get�pre-comp�value%CONFH020�MOVEP.WƒD0,IPCHPC(A1)‡set�it(‰MOVE.W„IOSTRK(A0),D0‡get�#�of�cylinders‰MOVEP.WƒD0,IPCHNC(A1)‡SET�IT8*ˆMOVE.L„#$8000,D0‹set�for�reduced�write�current�default=*ˆBTSTW…#IOSRWCCB,IOSPRM(A0)‚reduced�write�current�specified?(*ˆBEQ.S…CONFH030Œbranch�if�not�specified:‰MOVE.W„IOSRWCC(A0),D0†get�specified�reduced�write�current(‰MOVE.W„IOSECC(A0),D1‡get�ECC�value�also?CONFH030�MOVEP.WƒD0,IPCHRWC(A1)†set�reduced�write�current�value‰MOVE.B„D1,IPCHECC(A1)†set�ECC6‰MOVE.B„#1,IPCHSCA(A1)†set�sasi�controller�IDˆ01/27/84 *ˆCLR.L…D08*ˆBTSTW…#IOSILVB,IOSPRM(A0)�interleave�factor�specified?(*ˆBEQ.S…CONFH040Œbranch�if�not�specified+‰MOVE.B„IOSILV(A0),D0‡get�interleave�factor3CONFH040�MOVE.B„D0,IPCHIF(A1)‡set�interleave�factor,CONFH050�CLR.L…D0’use�to�clear�unused�fields‰MOVE.B„D0,IPCFNU1(A1)†not�used ‰MOVEP.LƒD0,IPCFNU2(A1)†not�used ‰MOVEP.WƒD0,IPCFNU3(A1)†not�used!‰MOVE.B„#ETX,IPCHFETX(A1)ƒset�ETX!‰CLR.L…D1’set�for�no�errors�found3‰MOVE.L„D7,A2�restore�CMR�para�blk�addrƒJH�01/24/84*‰BRA‡NRMEXIT�go�send�the�packet�and�return‰PAGEL******************************************************************************ˆCONFIGURATION�ERROR�ROUTINE*8*ˆControl�comes�here�is�there�is�a�detected�error�in�the*ˆconfiguration�command.*ˆentry:ƒD3�=�error�code0*‘D6�=�physical�address�of�users�parameter�block7*‘D7�=�physical�address�of�CMR�parameter�block‡11/17/83.*ˆNote:„Must�restore‚D6�and�D5�before�exiting.*L**************************************************************************** CONERROR:4‰MOVE.L„CCBDTBL(A5),A0†device�table�address‚01/27/84‰MOVEQ.Lƒ#0,D0¥01/27/84,‰MOVE.B„DCBCDV(A4),D0‡device�number‰01/27/84-‰MULU†#LUENTRY,D0‰calculate�position„01/27/84/‰CLR.W…LUFLG(A0,D0.L)†unset�active�bit†01/27/84)‰MOVE.L„D6,A0…get�users�parameter�address%‰MOVE.B„D3,IOSDST(A0)‡save�error�code1‰MOVEQ…#ISTACNF+$FFFFFF00,D1‰set�major�error�code>*ˆMOVEM.Lƒ(A7)+,D5/D6‰restore�regs�-�not�used�for�315�01/27/842‰MOVE.L„D7,A2�including�CMR�para�blk�addrƒ11/17/83‰BRA‡ABORT�and�return‰PAGEL******************************************************************************‰READ�COMMAND*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory*L*****************************************************************************READ:5ŠBSR„IOSCOMNŒDo�the�stuff�common�to�all�I/O�commands,7ŠMOVE.L�D6,CCBPTR(A5)†save�the�buffer�physical�address. ŠCLR.L‚D6&ŠBSETƒ#LUFXFR,D6ŒSET�DATA�TRANSFER�BITŠBSETƒ#LUFAC8 T,D6ŒSET�ACTIVE�BIT%ŠBSR„DEVTBL�SET�UP�DEVICE�TABLE�ENTRYŠBSR„DSKPRM�VALIDATE�PARAMETERS/ŠBSR„SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM.ŠMOVE.Wƒ#XREAD,D1&ŠBSR†DSKCMDŽYES,�SET�UP�COMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEL******************************************************************************‰WRITE**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory**L*****************************************************************************WRITE:5ŠBSR„IOSCOMNŒDo�the�stuff�common�to�all�I/O�commands,7ŠMOVE.L�D6,CCBPTR(A5)†save�the�buffer�physical�address. ŠCLR.L‚D6&ŠBSETƒ#LUFXFR,D6ŒSET�DATA�TRANSFER�BITŠBSETƒ#LUFACT,D6ŒSET�ACTIVE�BIT%ŠBSR„DEVTBL�SET�UP�DEVICE�TABLE�ENTRYŠBSR„DSKPRM�VALIDATE�PARAMETERS/ŠBSR„SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM.:ŠBTSTW„#DATWRC,DCBATT(A0)‚WRITE�WITH�VERIFY�FOR�THIS�DCB�?ŠBEQ.S„WRIT30ŽNO4ŠMOVE.Wƒ#XWRITC,D1ŠYES,�SET�UP�WRITE/VERIFY�COMMANDS ŠBRA.S„WRIT408WRIT30„MOVE.Wƒ#XWRITN,D1ŠSET�UP�WRITE/NO�VERIFY�COMMANDS 'WRIT40„BSR†DSKCMDŽSET�UP�COMMAND�PACKETŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEH**************************************************************************ˆFORMAT�DISK�COMMAND*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB* *‰Additional-*‰Registers‚A1�=�address�of�IPC�shared�memory**I**************************************************************************FORMAT: )‰BTSTWƒ#IOPFTRK,IOSOPT(A3)‚FORMAT�TRACK�?‰BEQ.SƒFORMT20ŽBRANCH�IF�NO !‰MOVE.L‚IOSRRN(A3),D1‰PICK�UP�RRN%‰BPL.SƒFORMT20�GOOD�ID�POSITIVE�VALUE/FORMT10‚MOVE.B‚#ISTARR,D1ŒSET�UP�IOS�ERROR�CODE ‰BRA…ABORT FORMT20‚CLR.LƒD6‰BSET„#LUFACT,D6ŒSET�ACTIVE�BIT%‰BSR…DEVTBL�SET�UP�DEVICE�TABLE�ENTRY5‰LEA‡LUCONF(A0,D0.L),A1‚GET�ADDRESS�OF�CONFIURE�BLOCK(‰BTSTW…#IOPFTRK,IOSOPT(A3)‚FORMAT�TRACK?‰BEQ.S…FORMT25ŽBRANCH�IF�NO3‰CMP.LƒSECOFF(A1),D1ŠSEE�IF�THIS�IS�BEYOND�THE�DISK*‰BLT.SƒFORMT25�BRANCH�IF�STILL�ON�THE�DISK*‰CLR.WƒLUFLG(A0,D0.L)ˆUNSET�THE�ACTIVE�BIT‰BRA‡FORMT10�AND�RETURN6FORMT25‚BSR…SETPKT�SET�UP�PACKET�HEADER�IN�SHARED�MEM. 0FORMT30ƒBTSTW„#IOPFTRK,IOSOPT(A3)‚FORMAT�TRACK�?ŠBNE.S„FORMT40�YESŠMOVE.Wƒ#XFDISK,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDS#ŠMOVE.Bƒ#ETX,IPCDETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#FDPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZEŠBRA†NRMEXIT�GO�FINISH�UP FORMT40ƒMOVE.Wƒ#XFTRAK,D16ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDSŠMOVE.Wƒ#SECSIZ,D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZE ŠCLR.L„D1*ŠMOVEP.W‚D1,IPCNBKS(A1)†ZERO�NO.�OF�BLOCKSŠMOVE.LƒIOSRRN(A3),D1"ŠMOVEP.L‚D1,IPCFPSN(A1)†SET�UP�PSN#ŠMOVE.Bƒ#ETX,IPCFETX(A1)„SET�UP�ETX.ŠMOVE.Bƒ#FTPKSZ,IPCPKSZ(A1)…SET�UP�PACKET�SIZEŠBRA†NRMEXIT�GO�FINISH�UPŠPAGEL*****************************************************************************C*‰ROUTINE�COMMON�TO�ALL�I/O�COMMANDS�(READ,�WRITE,�OUTPUT�W/�INPUT)**‚Entry:�A3�=�address�of�IOCB*‰A5�=�address�of�CCB**L*****************************************************************************IOSCOMN:?ŠBTSTW‚#IOPTSKB,IOSOPT(A3)�If�the�buffers�reside�in�a�different"ŠBEQ.S‚IOSC005Œtask�from�the�IOCB, 9ŠLEA„IOSTSK(A3),A0†Point�to�the�taskname�&�session�of�the7ŠTR0$.GETTCB‚,Œbuffer�owner�&�call�exec�to�get�address."ŠBRA.S‚OKTCBŽIf�it's�good,�branch.ŠNOP—If�it's�bad,7ŠMOVE.B�#ISTAADD,D1ˆset�status�in�IOCB�to�address�errorŠTST.L‚(A7)+Žadjust�stackŠBRA„ABORT�and�exit�to�CMR. :OKTCB…MOVE.L�A0,CCBTASKB(A5)„Save�physical�address�of�TCB. *<*‚Validate�the�info�in�the�IOCB�about�the�primary�buffer�and *‚convert�to�physical�addresses.*BIOSC005ƒMOVE.L�IOSSAD(A3),D6†D6�<--�buffer�physical�start�address.+ŠMOVE.L�IOSEAD(A3),D5†D5�<--�buffer�length.ŠSUB.L‚D6,D5Ž* ŠADDQƒ#1,D5Ž*)ŠMOVE.L�D5,CCBLEN(A5)†Save�l8 ength�in�CCB. >ŠMOVE.L�CCBTASKB(A5),A1„A1�<--�address�of�TCB�of�buffer�owner. ŠBSR„IOHADRCK‹Check�the�address.$ŠBRA.S‚IOSC010ŒIf�it's�good,�branch.ŠNOP—If�it's�a�bad�base�addrŠTST.L‚(A7)+Žadjust�stack4ŠMOVE.B�#ISTAADD,D1ˆSet�IOCB�status�to�ADDRESS�ERROR2ŠBRA„ABORT�and�exit�with�appropriate�error�status. IOSC010ƒRTSŠPAGEK****************************************************************************/*‰VALIDATE�BUFFER�ADDRESS�&�CONVERT�TO�PHYSICAL*$*‰Entry:�D5�=�buffer�length�in�bytes-*�D6�=�buffer�logical�start�addr�(to�convert)*�A3�=�address�of�IOCB*�A5�=�address�of�CCB***‰Exit:‚D6ƒ=�buffer�physical�start�address*�D5ƒ=�buffer�length*K****************************************************************************BUFADDR:>ŠMOVE.L�CCBTASKB(A5),A1„A1�<--�address�of�TCB�of�buffer�owner. ŠBSR„IOHADRCK‹Check�the�address.$ŠBRA.S‚OKADDR2ŒIf�it's�good,�branch.ŠNOP—If�it's�a�bad�base�addrŠTST.L‚(A7)+Žadjust�stack4ŠMOVE.B�#ISTAADD,D1ˆSet�IOCB�status�to�ADDRESS�ERROR2ŠBRA„ABORT�and�exit�with�appropriate�error�status.OKADDR2ƒRTS—Return.ŠPAGEO*********************************************************************************ˆCHECK�DISK�PARAMETERS**%*‚Entry:�A0�=�address�of�device�table%*‰A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB,*‰D0=‚offset�in�device�table�for�this�device**O********************************************************************************DSKPRM:3‰LEA…LUCONF(A0,D0.L),A1„GET�ADDRESS�OF�CONFIGURE�PB%‰MOVE.W‚IOSOPT(A3),D1‰PICK�UP�OPTIONS+‰AND.Wƒ#IOPRAN,D1ŒRANDOM�OPTION�SPECIFIED�?‰BNE.SƒDSKPR10�YES(‰MOVE.B‚#ISTATM,D1ŒSET�UP�IOS�ERROR�CODE‰TST.Lƒ(A7)+‘ADJUST�STACK‰BRA…ABORT�ERROR�EXIT(DSKPR10‚MOVE.L‚IOSRRN(A3),D1‰PICK�UP�RRN‰BPL.SƒDSKPR30�GOOD�RRN/DSKPR20‚MOVE.B‚#ISTARR,D1ŒSET�UP�IOS�ERROR�CODE DSKPR25‚TST.Lƒ(A7)+‘ADJUST�STACK*‰CLR.WƒLUFLG(A0,D0.L)‡SET�TO�DOING�NOTHING‰BRA…ABORT�ERROR�EXITŠSPC„2ADSKPR30ƒCMP.LƒSECOFF(A1),D1‡If�the�random�record�number�specified7ŠBLT.SƒDSKPR35‹in�the�IOCB�is�past�the�end�of�the�disk,2ŠMOVE.B�#ISTAEOV,D1ˆreturn�an�end-of-volume�error.ŠBRA.S‚DSKPR25ŠSPC„22DSKPR35‚MOVE.L‚CCBLEN(A5),D1‰PICK�UP�BUFFER�LENGTH"‰DIVS„#256,D1�CALC.�NO.�OF�SECTORS ‰MOVE.L‚D1,D2*‰AND.Lƒ#$FFFF0000,D2‰MUST�BE�WHOLE�SECTORS‰BEQ.SƒDSKPR40�ITS�OK5‰MOVE.B‚#ISTAADD,D1‹ERROR,�PARTIAL�SECTOR�NOT�ALLOWED‰BRA…DSKPR25�RETURN1DSKPR40‚MOVE.W‚D1,CCBBLKS(A5)ˆSAVE�NO.�OF�SECTORS2‰ADD.LƒIOSRRN(A3),D1‰CALC.�LAST�SECTOR�TO�TRANSFER‰CMP.LƒSECOFF(A1),D1‰RANGE�OK�?‰BLE.SƒDSKPR50�YES4‰MOVE.L‚SECOFF(A1),D1‰NO,�CALC.�MAX�SECTORS�CAN�READ‰SUB.LƒIOSRRN(A3),D1/‰MOVE.W‚D1,CCBBLKS(A5)ˆSAVE�SECTORS�TO�TRANSFER ‰BSET„#LUFEOF,D6ŒSET�EOF�PENDING-‰MOVE.WƒD6,LUFLG(A0,D0.L)„SET�IN�DEVICE�TABLEDSKPR50‚RTS›RETURN‰PAGEO********************************************************************************** SET UP DEVICE TABLE ENTRY**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D6�=�device�table�flag*N*******************************************************************************DEVTBL: ŠCLR.L‚D0(ŠMOVE.B�DCBCDV(A4),D0‰PICK�UP�DEVICE�NO. ŠCMP.B‚#LUMAX,D0�DEVICE�NO.�OK�?%ŠBGT„KILR’NO,�BRING�THE�SYSTEM�DOWN�! ŠMULUƒ#LUENTRY,D0‹CALC.�POSITION3ŠMOVE.L�CCBDTBL(A5),A0ˆPICK�UP�DEVICE�TABLE�POINTER(ŠTST.W‚LUFLG(A0,D0.L)ŠTHIS�DEVICE�FREE�?ŠBEQ.S‚DEVT010�YESŠTST.L‚(A7)+‘ADJUST�STACK+ŠMOVE.B�#ISTADB,D1ŒRETURN�DEVICE�BUSY�ERRORŠBRA„ABORT�ERROR�EXIT2DEVT010ƒMOVE.W�D6,LUFLG(A0,D0.L)‡UPDATE�TABLE�FLAG,ŠMOVE.L�A4,LUDCB(A0,D0.L)‡SET�UP�DCB�ADDRESS.ŠMOVE.L�A3,LUIOCB(A0,D0.L)†SET�UP�IOCB�ADDRESS6ŠMOVE.L�CCBTASKB(A5),LUTCB(A0,D0.L)�SET�UP�TCB�ADDRESS8ŠMOVE.L�CCBPTR(A5),LUBADR(A0,D0.L)�SET�UP�BUFFER�ADDRESS ŠRTSšRETURNŠPAGEJ***************************************************************************%*ˆSE9 T�UP�PACKET�HEADER�IN�SHARED�MEM.**,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB*,*‰Return�:�A1�=�address�of�IPC�shared�memory**I**************************************************************************SETPKT:%ŠMOVE.LƒCCBCHB(A5),A1‡MEM�MAPPED�ADDR)ŠLEA†IPCIM1(A1),A1‡SET�UP�MESSAGE�ADDRESSŠMOVE.Wƒ#SPKT,D1/ŠMOVEP.W‚D1,IPCSTX(A1)‡SET�UP�STX�AND�PACKET�ID0ŠMOVE.BƒDCBCDV(A4),IPCPHDV(A1)‚SET�DEVICE�NUMBER ŠRTSšRETURNŠPAGEJ***************************************************************************)*‰SET�UP�DISK�PARAMETERS�IN�SHARED�MEMORY*&*‚Entry:�A1�=�address�of�SHARED�MEMORY%*‰A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D1�=�CHANNEL/DEVICE�commands*K****************************************************************************DSKCMD:6ŠMOVEP.W‚D1,IPCCHCM(A1)†SET�UP�CHANNEL/DEVICE�COMMANDSŠMOVE.WƒCCBBLKS(A5),D18ŠMOVEP.W‚D1,IPCNBKS(A1)†SET�UP�NO.�OF�BLOCKS�TO�TRANSFERŠMOVE.Wƒ#SECSIZ,D1)ŠMOVEP.W‚D1,IPCBKSZ(A1)†SET�UP�BLOCK�SIZEŠMOVE.LƒCCBPTR(A5),D1*A*ˆAdjust�the�address�if�an�offboard�offset�applies.…(JH*08/27/84)* ŠGO_OFF_BD�D16*‰CMPI.Lƒ#MEMTOP,D1ŠONBOARD�MEMORY�(VME/10)�?ƒ03/28/84*‰BGT.S„GOGON1ŽNOš03/28/845*‰ADDI.Lƒ#OFFST,D1‹YES�ADJUST�BUFFER�ADDRESSƒ03/28/84*¦FOR�VME/10’03/28/84=GOGON1„MOVEP.L‚D1,IPCBUFAD(A1)…SET�UP�BUFFER�ADDRESS‡03/28/84 ŠCLR.L„D1'ŠMOVEP.W‚D1,IPCCKSM(A1)†SET�UP�CHECKSUMŠMOVE.LƒIOSRRN(A3),D1#ŠMOVEP.L‚D1,IPCCMPRM(A1)…SET�UP�PSN"ŠMOVE.Bƒ#ETX,IPCETX(A1)…SET�UP�ETX.ŠMOVE.Bƒ#IOPKSZ,IPCPKSZ(A1)�SET�UP�PACKET�SIZE ŠRTSšRETURNŠPAGEO******************************************************************************** *ˆNORMAL�EXIT*,*‚Entry:�A2�=�address�of�CMR�parameter�block*‰A3�=�address�of�IOCB*‰A4�=�address�of�DCB*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB*I**************************************************************************NRMEXIT:*/* INDICATE AWAITING ACK, BUMP I/O PENDING COUNT*'ŠBSETW‚#CCBFGWAK,CCBFG(A5)ƒSET�CCB�FLAGŠMOVE.L�CCBTASKB(A5),A0-ŠADD.B‚#1,TCBIOCNT(A0)„BUMP�I/O�PENDING�COUNT0D"N*92F:7B:JBR=Z8b<j9r:zF‚>** INTERRUPT THE IPC*0ŠMOVE.L�CCBCHB(A5),A1†SET�UP�SHARED�MEM.�POINTER (ŠMOVE.B�#$80,IPCIMB1(A1)ƒMESSAGE�WAITING0ŠADD.B‚#2,CCBICNT(A5)…BUMP�OUTSTANDING�INT�COUNT:*ˆThe�MVME315�does�not�have�an�interrupt�byte.‚It�actually<*ˆgets�interrupted�with�every�byute�written�to�it.�This�line/*ˆis�left�here�for�documentation�purposes�only.&*‰MOVE.B�#$80,IPCINT(A1)„INTERRUPT�IPC#ŠCLR.L‚D0‘SET�UP�GOOD�RETURN�TO�CMR*7* USER REQUEST SIDE OF IPC ALWAYS EXITS FROM THIS POINT*IPCUSRTN‚EQU„*ŠRTS—RETURN�TO�MAINLINEŠPAGEJ****************************************************************************ˆKILR�(KILLER)*3*“ROUTINE�CALLED�TO�HANDLE�UNRECOVERAVLE�CONDITIONS**K****************************************************************************KILR: ‰TR0$.KILLER    J*****************************************************************************ˆABORT�COMMAND�ROUTINE*%*’ENTRY:�A2�=�PARAMETER�BLOCK�ADDRESS*™A3�=�IOCB�PACKET�ADDRESS*™A4�=�ADDRESS�OF�DCB*™A5�=�ADDRESS�OF�CCB*™A6�=�ADDRESS�OF�CALLERS�TCB*™D1�=�IOS�ERROR�CODE*H*************************************************************************ABORT:)‰LEA‡CCBPKT(A5),A4‡SET�UP�QUEUE�WORK�AREA ‰MOVE.L„#6,D0�SET�UP�PACKET�SIZE"‰MOVE.L„XIOUID(A2),D2‡SET�UP�PB�ID‰AND.W…#$FF,D1!‰MOVE.W„D1,D3�SET�UP�STATUS�VALUE!‰MOVE.B„D1,IOSSTA(A3)‡UPDATE�IOCB$‰MOVE.B„#XPSNRM,D1ŠSET�UP�EVENT�TYPE‰BSR‡QEVNT�GO�QUEUE�EVENT5‰MOVE.L„XIOUID(A2),A4‡RESTORE�DCB�ADDRESSˆJH�01/24/84 ‰CLR.L…D9 0‰BRA‡IPCUSRTNŒRETURNŠPAGEF***********************************************************************B* SUBROUTINE TO CHECK ADDRESS BOUNDARIES TO SEE IF ENTIRELY WITHIN*ƒCALLING�TASKS�ADDRESS�SPACE.*#*�ENTRY:ƒD5‚-�NO.�OF�BYTES�TO�CHECK*ŠD6‚-�68000�ADDRESS�(LOGICAL)*ŠA1‚-�TCB�ADDRESS** EXEC ROUTINE#* REGISTERS USED: D0-D1,D3,D6/A0-A1**7*�EXIT:„D6�-�PHYSICAL�ADDRESS�OF�BUFFER�BASE�(IF�LEGAL)*ŠRETURN�TO�PC„FOR�GOOD�ADDRESS*”PC+2‚FOR�BAD�LENGTH*”PC+4‚FOR�BAD�ADDRESS*F*********************************************************************** IOHADRCK:$ŠBTSTƒ#0,D6ŽMUST�BE�ON�WORD�BOUNDARY(ŠBNE.S‚IOHADR6ŒBRANCH�IF�BAD�BUFFER�BASE ŠTST.L‚D5.ŠBEQ.S‚IOHADR8ŒDON'T�GO�TO�LOGPHY�WITH�0�COUNT/ŠMOVE.L�TCBTST(A1),A0†ADDRESS�OF�TASK�SEG�TABLE ŠTR0$.LOGPHY&ŠBRA.S‚IOHADR8ŒBRANCH�FOR�GOOD�ADDRESS-IOHADR6ƒADD.L‚#2,(A7)ŒADJUST�FOR�ERROR�RETURN IOHADR8ƒRTSŠPAGEI****************************************************************************‚CMR�RESET�ROUTINE8*ˆThe�MVME315�does�not�support�the�reset.�If�the�command8*ˆchannel�memory�is�incorrect�the�channel�is�marked�down9*ˆand�the�user�is�notified.‚All�the�code�to�actually�send;*ˆa�reset�to�the�board�is�commented�out.‚The�reset�was�used@*ˆby�the�UDC�and�FDC�to�try�to�recover�from�a�bad�shared�memory.*%*ˆENTRY:�A2�=�PARAMETER�BLOCK�ADDRESS*�A3�=�PACKET�ADDRESS*�A5�=�CCB�ADDRESS*�A6�=�CALLERS�TCB�ADDRESS*I**************************************************************************CMRREST:*/ŠMOVE.L�CCBCHB(A5),A4†SET�UP�SHARED�MEM�POINTER=* CLEAR ERROR MODE,WAITING FOR ACK, DEALT WITH ACK, EXIT FLAG&*‰CLR.L‚CCBNAKAD(A5)‡CLEAR�NAK�ADDRESS(*‰CLR.L‚CCBERAD1(A5)‡CLEAR�ERROR�ADDRESS*‰INHIB•INHIBIT�INTERRUPTSEŠAND.W�#-1-(1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>1*ˆN�: O�T�E�!!!!!!!!!!!!!!!!!!”NOT:Is�restored�(MS)/*ˆRESTORE�THIS�LINE�WHEN�THE�BOARD�HAS�QUEUEING*:*‰AND.W‚#$FFFF-(1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>2*‚RESTORE�THIS�LINE�ALSOšNOT:Is�restored�also�(MS)*IPC15000‚EQU„***%* SEE IF I/O COMPLETION HAS OCCURRED.,*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*‚RESTORE�THESE�TWO�LINES*²NOT:Are�restored�(MS)*‰BCLRW‚#CCBIPCW,CCBFG(A5)0*‰BEQ.S‚IPCNRTN1‹BRANCH�IF�NO�I/O�COMPLETION�SET*A*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;*ˆDELETE�THE�NEXT�3�LINES�WHEN�QUEUEING�WORKDS�ON�THE�BOARD*°NOT:Have�been�deleted�(MS)!IPC15000‚BCLRW�#CCBIPCW,CCBFG(A5)‰BEQ.S…IPCNRTN1%‰AND.W…#$FFFF-(1<*ˆThese�variables�are�XREFed�in�the�link�chain�file�M320DRV.LG=*ˆand�allow�the�user�to�modify�certain�media/drive�parameters>*ˆwithout�having�to�re-assemble�the�driver.‚See�the�link�chain+*ˆfile�for�a�description�of�the�parameters.* ‰XREF�FRMT_SD ‰XREF�FRMT_DD ‰XREF�FRMT_HD ‰XREF�SETTM_5 ‰XREF�SETTM_8‰XREF�SETTM_HD ‰XREF�LDTM_5 ‰XREF�LDTM_8 ‰XREF�LDTM_HD **‰MISC�EQUATES*5DRIVESƒEQU‡4“Maximum�number�of�drives�(LUN)�per�boardEXEC…EQU‡0“RMS68K�trap�# PAGE**ˆMACROS�USED�BY�THIS�DRIVER* (* Macro file to use with VMEbus drivers:*ˆINCLUDE�9995.&.DUALPORT.MC‰INCLUDE�9995.&.DUALPORT.MC *ˆLONGWORD�MACROK* This macro skips zero or more bytes in memory (if necessary) to align theM*�assembler's�location�counter�to�a�long-word�boundary.‚We�define�a�long-wordC* boundary to be a location whose address is evenly divisible by 4.F* If the location counter isn't on a long-word boundary, advance it by-* one word to put it on a long-word boundary. LONGWORD MACRO‰DS.W…0 ‰IFNE…*/4*4-*‰DS.W…1‰ENDC‰ENDM *ˆMOVEIA�MACROJ*‚This�macro�is�useful�when�we�want�to�put�an�immediate�value�into�an�1*�register,�i.e.‚[