IMD 1.17: 11/11/2014 15:02:21 82VKXBVERDOS C* VERSADOS/RMS68K OBJECT 4.4 SN=48634 18 OF 22  BT18b82VKXBVERDOS 0420¿ -Š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éééé*‚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�c hannel�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�been�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*Œthe�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éééééé  é>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.éééé "*T2F::B4J<R6Zb>j>rzN‚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_R  ESET‰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*�pa  ss�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�bits�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�dr  iver:***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‰MOVE.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  ééé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�are  a�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Û9ãGëHóIûH: 7KX#L+J3;;6C<KASE[<c9kIsH{?ƒ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�EDIT�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�RE AD!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�PRIORITY�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ƒ#ISTAC NF,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„IPC R240Ž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�<--�address�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�us ers�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ƒ#XREAD,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�=�a ddress�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ƒDSKPR10�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**************************************************************************NRME XIT:*/* 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ü:N H@C$;,B4H<'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ƒPRINTE R�? *º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�pa cket*Š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�notAŠ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�?ŠB NE.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***"* DI SK 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ééé&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�wa s�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�correctly*¦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.DDMJU-*œ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 é ééééé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*V]3fSn0v6~7†DŽ6–7žC¦I®?¶F¾5ÆDÎ?Ö5Þ7æ1î:ö@þ4-423&<.G6>>AFC9*ƒ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.&.T CB.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-up�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�se ctors *‰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"*!*�=�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�VALUE RTNSTPRƒ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* * 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***************************************************************************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�erro r.Š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�field�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�=�a ddress�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-de  nsity5‰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�too�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/840‰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�addr! ess�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ƒ#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.Š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�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ƒ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)ˆSAV" E�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***************************************************************************%*ˆ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�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�COUNTeNDWN_9gFo7w:B‡=�8—<Ÿ9§:¯F·>** 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…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/Š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.‚[