IMD 1.17: 25/11/2014 13:02:15 82VKXBVERDOS D* BT19:0 68K VERSADOS/RMS68K OBJECT 4.5 (DS,DD 96 tpi 5.1/4" DISK) REVISED: 04/22/86 DISK 19 OF 24  BT19 82VKXBVERDOS 0420±j-ˆ/�@˜8 <¨5°=¸8À3È<Ð5Ø=à>èOð^øQI9 H* I/O HANDLER DATA AREA *************************************************CCBFLG„DS.B„2ŒFlags(CCBERAD1‚DS.B„4ŒError�debug�save�address2CCBQVER1‚DS.B„4ŒEvent�queueing�error�debug�address7CCBCCB„DS.B„4ŒPhysical�address�of�command�packet�(IOCB)CCBTASKB‚DS.B„4ŒBuffer�task�TCB-CCBPKT„DS.B„18‹Event�work�area�(command�tour)0CCBCPKTƒDS.B„18‹Event�work�area�(interrupt�tour)(CCBPTR„DS.B„4ŒPhysical�address�of�bufferCCBLEN„DS.B„4ŒLength�of�buffer0CCBPTR1ƒDS.B„4ŒPhysical�address�of�2ndary�buffer&CCBLEN1ƒDS.B„4ŒLength�of�2ndary�buffer*CCBCID„DS.B„4ŒCMR�parameter�block�id�(DCB)CCBCOPTƒDS.B„2ŒIOCB�options#CCBCFIGƒDS.B„$26ŠConfiguration�data**‰56�bytes�remain*9*‰CCBFLG�DEFINITIONS:�if‚CCBFLG.B�if�not�0�the�RIO�module$*�for�the�CCB�cannot�be�used�for�the*�following�reasons:*9*‰CCBFLG.B�=�$FA�=�CCB�allocation�exceeded�#�of�specified/*šdevices�-�no�room�in�RIO�table�for�the�module!*’=�$FC�=�no�RIOTBL�was�allocated/*’=�$F5�=�no�room�in�RIOTBL�for�this�RIO�module*™(incorrect�table�allocation)**‰PAGE ‰SECTION�8 ‰XREF�RIOTBLJ******************************************************************************‚RIO�SERVICE�VECTOR�TABLE***L*****************************************************************************RIODVR:#*ˆDC.L†RIOINTŽinterrupt�svc�address!*ˆDC.L†RIOCMDŽcommand�svc�address)*ˆDC.L†RIOINIT�initialization�svc�address**?*Below are the new offset form of service pointers, for new CMR**(‰DC.L†RIOINT-RIODVR†interrupt�svc�offset*‰DC.L†RIOCMD-RIODVR†command�service�offset.‰DC.L†RIOINIT-RIODVR…initialization�svc�offset‰DC.L†0‰Reserved‰DC.B†0“number�of�extra�pages‰DC.B†0,0,0�reserved‰DC.L†0,0,0�reserved 3*ƒ---ƒ---…CONFIGURATION�CONTROL�INFORMATION…---ƒ---ŠSPC�1$‰DC.B…'032983'ƒdate�of�last�assembly'‰DC.B†'�'‡space�means�no�patches�in�.LO#‰DC.B†'4'‡major�Versados�revision�#‰PAGEJ****************************************************************************‰COMMAND�TABLE�&�JUMP�TABLE*:*‰These�are�used�by�the�command�service�routine�to�jump�to.*‰the�appropriate�routine�to�handle�a�command.*J***************************************************************************CMDTBL:ŠDC.WƒROPENŽOPEN�command.ŠDC.WƒRCLOSE�CLOSE�command.ŠDC.WƒROUTON�RELAY�ON�command. ŠDC.WƒROUTOFFŒRELAY�OFF�command.ŠDC.WƒRSTATŽSTATUS�command.'ŠDC.WƒRENABL�ENABLE�INTERRUPTS�command.(ŠDC.WƒRDSABL�DISABLE�INTERRUPTS�command."ŠDC.WƒRPLSOŽPULSED�OUTPUT�command.=NUMCMDSƒEQU„(*-CMDTBL)/2‡The�number�of�commands�in�the�table.*9JMPTBL:ƒDC.WƒOPEN-*�Biases�to�the�corresponding�routines. ŠDC.WƒCLOSE-* ŠDC.WƒOUTON-*ŠDC.WƒOUTOFF-* ŠDC.WƒSTAT-*ŠDC.WƒENABLE-*ŠDC.WƒDSABLE-* ŠDC.WƒPLSO-**7JMPOFF„EQU„JMPTBL-CMDTBL†Offset�between�the�two�tables.ŠPAGEJ****************************************************************************+*ˆRIO�DRIVER�INITIALIZATION�SERVICE�ROUTINE*>*ˆThe�driver�is�entered�here�for�each�CCB�allocated.‚More�than:*ˆone�CCB�may�be�allocated�for�each�RIO�module.‚One�CCB�is>*ˆallocated�for�each�interrupt�level�the�board�is�jumpered�to.?*ˆThis�routine�checks�to�see�if�there�is�room�in�the�RIOTBL�for=*ˆthe�device�ID.‚It�saves�the�device�ID�and�the�memory�mapped>*ˆI/O�address�of�the�device�the�the�RIOTBL.‚It�initializes�the5*ˆinput�PIA�of�the�device�if�not�already�initialized.B*ˆThis�routine�also�checks�to�see�if�the�RIO�LED�is�on,�indicating<*ˆan�I/O�channel�reset�was�issued�or�a�power-up.�If�on,�thisA*ˆroutine�turns�it�off.�The�on/off�indicator�is�bit�#7�of�TSTREG.*:*ˆAn�error�code�is�saved�in�the�CCB�if�this�CCB�allocation=*ˆexceeds�the�maximum�number�of�CCB's�specified�during�SYSGEN9*ˆ(SYSGEN�parameter�NRIO),�if�no�RIOTBL�exists�or�no�room*ˆin�the�table�for�this�module.*$*ˆEntry:‚all�registers�are�available*�A5�=�CCB�address*I**************************************************************************RIOINIT:ŠPUSHPOINT‘save�pointers3ŠMOVE.LƒCCBCHB(A5),A0„get�memory�mapped�I/O�address$ŠMOVE.L�RIOTBL,A1Šget�RIOTBL�address ŠCMP.L‚#0,A1Žis�there�one?&ŠBNE.S‚RIOINIT1‹branch�if�have�a�table8ŠMOVE.B�#RIONTBL,CCBFLG(A5)�set�no�table�error�conditionŠBRA�RIOINEX1�goto�error�returnRIOINIT5‚TST.L‚(A1,D3)Œlook�for�an�entry�slot�to�save�this�guy5ŠBMI.S‚RIOINIT6‹branch�if�this�slot�is�empty�-�use�it/ŠADD.W‚#PIALNG,D3‰not�empty,�bump�to�next�entry"ŠSUB.B‚#1,D4Ždecrement�the�counter(ŠBNE.S‚RIOINIT5‹branch�if�more�to�search4ŠBRA„RIOEXTER‹error�if�got�here-�no�room�for�the�map>RIOINIT6‚MOVE.L�D2,(A1,D3)‰save�this�memory�mapped�I/O�address*E*The input pia ios used exclusively for all input, and is initialized1* to all inputs and muist remain so for all time.*N*The output pia (PIA 2) is used exclusively for all output, and is initializedL*to�all�inputs.‚On�any�channel�which�is�allocted�for�output,�only�the�outputD*�Pia�will�be�set�for�output.‚When�this�channel�is�de-allocated,�theH*�corresponding�output�PIA�bit�must�be�re-initialized�for�input.‚FailureM* to follow this policy will result in impropper operation of input channels.*.ŠMOVE.L‚#0,D0�write�0�to�all�pia�control�reg'sŠBSR.SƒRIO.WCR‹do�itBŠMOVE.B‚#0,PIA1ADR(A0)„clear�all�data�direction�regs�(set�for�inpu!ŠMOVE.B‚#0,PIA1BDR(A0)„clear�next!ŠMOVE.B‚#0,PIA2ADR(A0)„clear�next!ŠMOVE.B‚#0,PIA2BDR(A0)„clear�last2ŠMOVE.B‚#4,D0�set�control�regs�for�data�reg�access ,ŠBSR.SƒRIO.WCR‹writes�are�done�by�subroutine&ŠBSR.SƒRIO.CLR‹go�clear�all�interrupts **‰turn�off�the�LED*1RIOEXIT1‚CLR.B‚CCBFLG(A5)‰set�for�good�allocation3ŠMOVE.L�CCBCHB(A5),A1†get�memory�mapped�I/O�address,ŠMOVE.B�TSTREG(A1),D1†read�the�test�register$ŠBPL.S‚RIOINEX1‹return�if�LED�is�off%ŠBCLRƒ#LEDSTA,D1‰clear�the�LED�on�bit&ŠMOVE.B�D1,TSTREG(A1)†turn�the�LED�off'RIOINEX1:�POP_POINT‘recall�all�pointersŠRTS**‚Subroutines�used�by�RIOINIT:*DRIO.WCR‚EQU�*ƒwrites�data�in�ls�byte�of�D0�to�all�pia�control�reg`s.‰MOVE.B‚D0,PIA1ACR(A0)‰MOVE.B‚D0,PIA1BCR(A0)‰MOVE.B‚D0,PIA2ACR(A0)‰MOVE.B‚D0,PIA2BCR(A0)‰RTS›end�RIOWCR**RIO.CLRƒEQU�*ƒclear�any�pending�interrupts*‰MOVE.B‚PIA1ADR(A0),D0‰MOVE.B‚PIA1BDR(A0),D0‰MOVE.B‚PIA2ADR(A0),D0‰MOVE.B‚PIA2BDR(A0),D0‰RTS›end�RIOCLRŠPAGEJ***************************************************************************$*‰RIO�DRIVER�COMMAND�SERVICE�ROUTINE*6*‹PARAMETER�ADDRESS�AND�BOUNDARY�CHECKS�HAVE�BEEN�MADE**ƒEntry:‚JSR�FROM�CMR�HANDLER.*‹A2�-�PHYSICAL�ADDRESS�OF�CMR�PARAMETER�BLOCK*‹A5�-�PHYSICAL�ADDRESS�OF�CCB*5*ƒExit:‚RTS�-�PARAMETER�BLOCK�VALIDATION�STATUS�IN�D0**ƒREGISTERS�USED:ƒ01234567 *”D******** *”A**P**PP*"*”A3�=�RIO�PARAMETER�BLOCK�ADDRESS*”A6�=�REQUESTOR�TCB�ADDRESS**ƒEXEC�ROUTINES�CALLED:‚QEVENTI**ƒCODE�IS�RE-ENTRANT***** J***************************************************************************RIOCMD:*)*‰Convert�logical�PB�address�to�physical.* ŠCLR.L‚D5;ŠMOVE.L�XIOCPK(A2),D6†Set�up�address�of�RIO�parameter�block:ŠMOVE.W�XIOPLN(A2),D5†Set�up�length�of�RIO�parameter�block+ŠMOVE.L�CCBTASKA(A5),A1„Set�up�TCB�pointer.&ŠBSR„IOHADRCK‹Call�conversion�routine.ŠBRA.S‚CMD010�Good�return.ŠNOP—Bad�length�return. ŠCLR.L‚D0;ŠMOVE.B�#RTCDPBLK,D0‡Set�up�invalid�parameter�block�addressŠBRA�RIOCEX2�goto�error�exit*!*‰see�if�passed�the�initialize�ok*CMD010„CLR.L‚D02ŠMOVE.LƒD6,A3ŒStage�phys.�addr.�opf�RIO�para.�blk.4ŠTST.B‚CCBFLG(A5)‰error�code�set�in�CCB�during�INIT?/ŠBEQ.S‚CMD020�branch�if�no�error�code,�continue$ŠMOVE.B�CCBFLG(A5),D0†set�error�code%CMDSRTRƒBRA.S‚RIOCEX2Œgoto�error�exit CMD020„EQU�**,*‰get�RIOTBL�address�into�A4�for�command�use* ŠMOVE.L�RIOTBL,A4ŠRIOTBL�address)ŠCMP.L‚#'!RIO',(A4)‡really�is�the�RIOTBL?,ŠBEQ.S‚CMD030�branch�if�really�is�the�RIOTBL4ŠMOVE.B�#RIONTBL,D0ˆset�error�return�code�-�no�tableŠBRA.S‚CMDSRTRŒand�return**‰find�RIO-ID�in�RIOTBL*‰A1�=�entry�address*0CMD030„MOVE.L�XIOCID(A2),D0†get�specified�RIO-ID(ŠMOVE.B�RIONMAX(A4),D1…max�#�of�RIO-ID's$ŠMOVE.L�#RIONTRY,D2ˆbump�past�header"FNDRIO10‚CMP.L‚(A4,D2),D0‰a�match?!ŠBEQ.S‚FNDRIO20‹branch�if�a�match&ŠADD.W‚#RIOIDLNG,D2‡bump�to�next�entry1ŠSUB.L‚#1,D1Ždecrement�number�of�entries�to�check&ŠBNE.S‚FNDRIO10‹branch�if�more�entries.ŠMOVE.W�#RIONID,D0‰error�-�RIO-ID�not�in�table3ŠBRA„CMDSRTRŒreturn�to�CMR�with�error�condition�set+FNDRIO20‚MOVE.L�A4,A1Žbass�address�of�tableŠADD.L‚D2,A1Žaddress�of�entry*(*‰Find�the�command�in�the�command�table.*-ŠMOVEQ‚#NUMCMDS-1,D0†Set�up�the�loop�counter./ŠLEA„CMDTBL,A0ŠA0�<--�address�of�command�table.+ŠMOVE.W�CMDCOD(A3),D6†get�RIO�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.DCMDERR„MOVE.B�#RIOINVD,D1ˆdidn't�find�command�code�-�exit�with�errorŠSPC�1RIOCEX2:;ŠMOVE.WƒD0,CMDSTA(A3)‡write�error�code�to�users�RIO�para�blRIOCEX1:ŠRTSŠPAGEL*****************************************************************************‰OPEN�COMMANDA*‰This�command�assigns�the�logical�connection�between�a�user�task:*‰and�specified�channels�within�an�RIO�module.�16�channels?*‰maximum�may�be�specified�in�one�open�command.�Interrupt�levelB*‰of�the�channels�are�taken�from�the�CCB.�The�interrupts�levels�of4*‰input�channels�0-7�must�match�the�following�order:-*‰channels�0-1�must�have�same�interrupt�level-*‰channels�2-3�must�have�same�interrupt�level-*‰channels�4-5�must�have�same�interrupt�level-*‰channels�6-7�must�have�same�interrupt�levelD*‰It�is�ok�for�all�these�channels�to�have�the�same�interrupt�levels.*#*‰RIO�OPEN�command‚parameter�block: *�DS.W‚1„returned�command�status*�DS.W‚1„command�code�(01)*�DS.W‚1„#�of�channels�to�open*�DS.W‚1„1st�channel�number*�DS.W‚1„channel�configuration*’.*�DS.W‚1„nth�channel�number*�DS.W‚1„channel�configuration**‰configuration�byte:*�bit�0=1�output�channel*•=0�input�channel*�bit�1=1�disable�interrupt*•=0�enable�interrupt"*�bit�2=1�interrupt�on�rising�edge*•=0�interrupt�on�falling�edge)*�bit�3=1�wake-up�task�on�input�interrupt,*•=0�queue�event�to�task�on�intput�interrupt8*Œbits�8-14=‚debounce�interval.‚0=no�debounce,�otherwise-*˜debounce�time�is�value�times�4�milliseconds$*�bit�15=1�use�default�configuration *•=0�use�specified�configuration**‰Default�configuration:*�channels�0-7’channels�8-15*�------------’-------------*�input�channel‘output�channel*�interrupt�enabled*�interrupt�on�falling�edge*�queue�event�on�interruptB*‰When�default�configuration�is�specified,�the�actual�configuation9*‰is�saved�in�RIOTBL.�The�task�TCB�address�is�also�saved.*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL %*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�CLRPIAM,�SETPIA,�DOPIA*L**************************************************************************** PAGE*OPEN:*‰see�if�channel�already�opened* ŠPUSHPOINT‘save�all�address�regsŠALLOCATEƒCHCONFIG4ŠBSR�CLRPIAM�clear�(to�$FF)�the�PIA�map�for�this�RIOŠCLR.L‚D7‘channel�counter:ŠCMP.W‚#RIONID,D0‰an�error�returned�from�clearing�the�map?'ŠBEQ„OPNOID�branch�if�an�error�returned$ŠCLR.L‚D2‘channel�offset�into�RIOTBL)ŠCLR.L‚D1‘offset�into�RIO�parameter�block1ŠMOVE.W�CMDCHN(A3),D0†get�#�of�channels�specified-ŠBLE„OPNINC�branch�if�negative�or�zero,�error2ŠCMP.W‚#16,D0�cannot�specify�more�than�16�channels,ŠBGT„OPNINC�branch�if�greater�than�16,�errorGOPEN10„MOVE.W�NUMCHAN(A3,D1),D2‚get�channel�number�from�RIO�param.�blk.ŠMOVE.W�D2,D5Žsave�it0ŠMULUƒ#CHANLNG,D2ˆget�channel�offset�into�RIOTBLŠADD.L‚#4,D2Žbump�past�RIO-ID+ŠTST.W‚(A1,D2)Œthis�channel�already�opened?+ŠBPL„OPNOPN�branch�if�already�opened,�errorŠADD.L‚#1,D7Žcount�this�channel@ŠMOVE.W�CHNCNFG(A3,D1),D3‚get�configuration�from�RIO�param.�blk.-ŠSTORE„D3,CHCONFIG†save�channel�configuration*ŠBMI.S‚OPEN60�branch�if�defaults�specifiedŠBTSTƒ#0,D3Žoutput�channel?&ŠBNE.S‚OPEN70�branch�if�output�channel**‰set�this�channel�for�input* ŠMOVE.W�D3,D4Žsave�configuration"ŠCMP.B‚#8,D5Žsee�if�channel�#�8-153ŠBGE.S‚OPEN50�branch�if�channel�8-15,�no�interrupts3ŠMOVE.B�CCBPPRIO(A5),D4„get�intrrupt�level�from�CCBŠASL.L‚#4,D4Žget�into�bits�4-6$ŠOR.WƒD4,D3Žsave�the�interrupt�level*6*‰check�to�see�that�interrupt�levels�of�channels�match*,OPEN20„MOVE.B�D5,D6Žsave�this�channel�numberŠBTSTƒ#0,D5Žodd�channel?*ŠBNE.S‚OPEN30�branch�if�odd�channel�number*ŠADD.B‚#1,D6Ževen�-�get�channel�number�+�1ŠBRA.S‚OPEN40�and�continue/OPEN30„SUB.B‚#1,D6Žodd�-�get�channel�number�-�15OPEN40„MULUƒ#CHANLNG,D6ˆget�channel�offset�into�tableŠADD.L‚#4,D6Žbump�past�RIO-ID#ŠTST.W‚(A1,D6)Œthis�channel�opened?"ŠBMI.S‚OPEN50�branch�if�not�opened9ŠMOVE.W�RIOCNIF(A1,D6),D6‚get�other�channel�configurationŠSPC�2ŠBTSTƒ#0,D6Žan�input�channel?,ŠBNE.S‚OPEN50�branch�if�not�an�input�channel$ŠASR.L‚#4,D6Žget�into�low�order�bits**‰good�configuration0*‰save�TCB�address�and�configuration�information* OPEN50„EQU†*.ŠLOAD…D3,CHCONFIG†recall�channel�configuration+ŠBSR„SETPIA�go�set�PIA�map�for�this�channel5ŠCMP.W‚#RIONID,D0‰an�error�found�during�the�save�map?*ŠBEQ.S‚OPNERR�branch�if�an�error�was�found6ŠMOVE.W�D3,RIOCNIF(A1,D2)‚save�configuration�in�RIOTBL)ŠMOVE.L�A6,RIOTCB(A1,D2)ƒsave�TCB�address4ŠADD.W‚#OPNTRY,D1‰bump�to�next�RIO�param.�blk.�entry3ŠSUB.W‚#1,D0Ždecrement�number�of�channels�specified)ŠBGT„OPEN10�branch�if�more�channels�to�do,ŠBSR„DOPIAŽgo�set�the�PIA�hardware�registers!ŠCMP.W‚#RIONID,D0‰an�error�found?7ŠBEQ.S‚OPNERR�branch�if�an�error�was�found�-�don't�openŠCLR.L‚D0‘set�for�good�returnŠBRA.S‚OPNXIT�go�return�to�CMR**‰default�configuration�set*%OPEN60„CMP.W‚#7,D5Žsee�if�channel�0-7!ŠBLE.S‚OPEN80�branch�if�maybe�0-7!ŠCMP.W‚#16,D5�see�if�channel�8-16-ŠBGT.S‚OPNCNŽbranch�if�greater�than�16,�error**‰output�channel*,OPEN70„MOVE.W�#1,D3Žset�output�configurationŠBRA.S‚OPEN50�go�save�it**‰input�configuration�specified*-OPEN80„TST.W‚D5‘must�be�channel�#0�or�greater)ŠBLT.S‚OPNCNŽbranch�if�less�than�0,�errorŠCLR.W‚D3‘set�for�defaults/ŠMOVE.B�CCBPPRIO(A5),D3„get�CCB�interrupt�levelŠASL.L‚#4,D3Žput�into�bits�4-6ŠBRA.S‚OPEN20�go�save�it**‰open�errors�here*;OPNINT„MOVE.W�#RIOIINT,D0ˆset�invalid�interrupt�level�error.ŠBRA.S‚OPNERR�go�'de-open'�any�opened�channels>OPNCN…MOVE.W�#RIOICNS,D0ˆset�illegal�channel�#�specified�error.ŠBRA.S‚OPNERR�go�'de-open'�any�opened�channels8OPNINC„MOVE.W�#RIOINC,D0‰set�invalid�#�of�channels�errorŠBRA.S„OPNXIT‹exit;OPNOID„MOVE.W�#RIONID,D0‰set�RIO�module�not�allocated�errorŠBRA.S‚OPNXIT�go�return�to�CMR 9OPNOPN„MOVE.W�#RIOPND,D0‰set�channel�already�opened�error*)*‰reset�any�opened�channels�to�not�opened*%OPNERR„TST.W‚D7‘any�channels�to�undo?3ŠBEQ.S‚OPNXIT�branch�if�none�to�undo,�return�to�CMR&ŠMOVE.W�#$FFFF,D3Šset�'un-opened'�codeŠCLR.L‚D1‘clear�for�use6OPNERR10‚MOVE.W�NUMCHAN(A3,D1),D2‚get�a�channel�number$ŠMULUƒ#CHANLNG,D2ˆget�channel�offsetŠADD.L‚#4,D2Žbump�past�headers*ŠMOVE.W�D3,(A1,D2)‰set�this�entry�unopened-ŠADD.W‚#OPNTRY,D1‰bump�to�next�channel�numberŠSUB.W‚#1,D7Ždecrement�counter&ŠBGT.S‚OPNERR10‹branch�if�more�to�undo** Fall into exit* OPNXIT EQU * ŠADD.L„#8,A7Œdeallocate�CHCONFIGŠPOP_POINT‘restore�all�pointers ŠBRA�NRMEXITŠPAGEK*****************************************************************************‰SETPIA*7*‰Build�the�PIA�map�entries�for�the�specified�channels.*‰Builds�1�entry�per�call*‰Map�is�in�RIOTBL.**‰Entry:�A4ƒ=�RIOTBL�address*�D3.W�=�channel�configuration*�D5.B�=�channel�number*7*‰Exit:‚D0.W�=�RIONID�if�map�entry�not�found,�otherwise*—D0�unchanged *‰Uses:�D4,D6*‰Entry�point�=�SETPIA*‰Exit�point‚=�SETPIART**L******************************************************************************‰find�map�entry* SETPIA EQU *ŠPUSHPOINT‘save�all�pointersŠMOVE.L�D7,-(A7)‹save�D75ŠMOVE.W�RIOPIA(A4),D7†get�offset�to�start�of�PIA�maps.ŠMOVE.B�RIONAL(A4),D6†get�#�of�RIO'S�allocated3ŠMOVE.L�CCBCHB(A5),D4†get�memory�mapped�I/O�address=SETPIAFD‚CMP.L‚PIADDR(A4,D7),D4ƒfind�the�matching�I/O�addressŠBEQ.S‚SETPIA00‹branch�if�found$ŠADD.W‚#PIALNG,D7‰bump�to�next�entryŠSUB.B‚#1,D6Ždecrement�counter0ŠBNE.S‚SETPIAFD‹branch�if�more�entries�to�search>ŠMOVE.W�#RIONID,D0‰set�for�fatal�error�-�this�shouldn't�happen ŠBRA.S„SETPIART‰return�to�caller**‰determine�channel�number*SETPIA00‚CLR.L‚D6‘clear�for�use/ŠMOVE.B�D5,D6Žcopy�channel�number�to�work�spaceŠCMP.B‚#7,D5Žchannel�0-7?ŠBLE.S‚SETPIA20‹branch�if�0-7**‰channel�8-15*/ŠSUB.B‚#8,D6Žget�bit�#�offset�of�channel�numberŠBTSTƒ#0,D3Žan�output�channel?0ŠBNE.S‚SETPIA10‹branch�if�yes,�an�output�channel**‰channel�8-15�as�input�channel*%ŠBCLRƒD6,DODR815(A4,D7)‚set�for�input ŠBRA.S‚SETPIART‹return�to�caller* *‰channel�8-15�as�output�channel*SETPIA10 EQU *0ŠBSET…D6,DODR815(A4,D7)ƒset�ddr�image�for�output ŠBRA.S‚SETPIART‹return�to�caller* *‰channel�0-7*%SETPIA20‚BTSTƒ#0,D3Žan�input�channel?,ŠBEQ.S‚SETPIA30‹branch�if�yes,�input�channel**‰CHANNEL�0-7�as�output�channel*/ŠBSETƒD5,DODR07(A4,D7)ƒset�ddr�image�for�output#SETPIART‚MOVE.L�(A7)+,D7‹restore�D7ŠPOP_POINT‘restore�all�pointersŠRTS—return�to�caller**‰channel�0-7�as�input�channel*SETPIA30‚EQU�*$ŠBCLRƒD5,DODR07(A4,D7)ƒset�for�input1ŠBSR„NEWSETPŒinit�PIA�control�regs�for�interrupts ŠBRA†SETPIARTŠPAGED********************************************************************&*ˆNEWSETP�is�interrupt�setup�for�PIA's&*ˆNEWSETP�initializes�one�PIA�per�call** Private subroutine for SETPIA** Table driven pia setup::*‚PIAICMSK‚is�a�table�of�PIA�interrupt�control�mask�words.N*‚The�LS�byte�is�AND'ed�with�map�entry,�and�the�MS�byte�is�OR'd�with�map�entry‰SPC�3PIAICMSK EQU *-‰DC.W†$05FD…enable�falling�irq�on�even�port�#‰DC.W†$04FE…disable�even‰DC.W†$07FF…enable�rising‰even‰DC.W†$04FE…disable�evenA*----------------------------------------------------------------‰DC.W†$0CEF…enable�fallingˆodd‰DC.W†$04F7…disable�odd‰DC.W†$1CFF…enable�rising‰odd‰DC.W†$04F7…disable�oddŠSPC�3)PIAMGOFF�EQU�*‚IRQ�control�image�offsets:‰DC.B†2‰DC.B†3‰DC.B†0‰DC.B†1‰SPC�3NEWSETP:ŠSPC�1L*Generate index into table of interrupt control masks based on configuration * and even / odd channel number:(*Configurations are between 00X and 11X.**On entry (data input:)%*ˆD3.W‚contains�channel�configuration*ˆD5.B‚contains�channel�number%*ˆD7„contains�offset�to�PIA�map�start**‰PUSHALL–save�all ‰CLR.L…D0/‰MOVE.B„D3,D0…get�IRQ�config.�to�working�reg�D0 +‰AND.B…#$0004,D0‚select�IRQ�config�data�bit‰TST.B…D0ˆsetup�for�branches7‰BMI.S…SETPIA33‚branch�on�default�configuration�request8‰BEQ.S…SETPIA32‚branch�on�falling�edge�irq�configuration‰CMP.B…#4,D0…rising�edge�irq�?7‰BEQ.S…SETPIA32‚branch�on�rising�edge�irq�configuration1‰MOVE.L„#2,D0…on�all�other�config.'s,�disable�irq6SETPIA32ƒEQU‚*ƒnow�determine�even�/�odd�channel�number"‰BTST†#0,D5…even�or�odd�channel�#?(‰BEQ.S…SETPIA31‚branch�on�even�channel�#"‰ADD‡#8,D0…add�8�for�odd�channel�##SETPIA31ŠEQU�*…rejoin�main�sequence ‰CLR.L…D18‰MOVE.W„PIAICMSK(PC,D0),D1‚fetch�control�word�from�table)‰MOVE.L„D3,D0…get�new�copy�of�config�data5‰AND.L…#$00000008,D0‚select�wakeup/que�event�data�bit ‰MOVE.L„#21,D4„setup�shift�count2‰LSL.L…D4,D0„position�wakeup/quevent�bit�in�bit�24‰SPC�1)‰AND.L…#$0000FF00,D3‡select�debounce�data1‰LSL.L…#8,D3…position�debounce�data�in�bits�16-23‰OR.L†D3,D1…add�debounce�data-‰OR.L†D0,D1…add�wakeup/quevent�data�at�bit�248‰BSR‡WRITMAPƒwrite�the�interrupt�control�data�to�PIA�map7SETPIA33‚EQU‚*‚branch�here�for�no�change�in�irq�setting‰POPALL˜restore�register�values‰RTS‰PAGEWRITMAP:#*ˆWrites�interrupt�data�to�PIA�map.*ˆInput�parameters�to�WRITMAP:*ˆD5ƒchannel�# *ˆD7ƒoffset�to�start�of�PIA�maps$*ˆA4ƒRIOTBL�address�for�current�user;*ˆD1.L�PIA�control�mask�word�(bits�16-23�are�debounce�data)!*¤(bit�24�is�wakeup/quevent�bit).*>*ˆTranslates�channel�number�to�PIA�register�image�map�address,4*ˆthen�modifys�the�map�image�based�on�data�in�D1�.L.2*ˆNow�translate�channel�number�into�PIA�map�offset* ‰CLR.L…D0/‰MOVE.B„D5,D0…put�channel�#�into�working�reg�D0"‰LSR.B…#1,D0…divide�channel�#�by�2*;*‡PIA�channel�index�now�in�D0;�now�add�offset�from�PIAMGOFF*‡(pia�image�offset�table)*;‰ADD.B…PIAMGOFF(PC,D0),D7‚add�offset�to�channel�IRQ�control$‰ADD.B…#8,D7…bump�to�register�images**ˆD7�contains�offset�to�PIA�map*.‰AND.B…D1,(A4,D7)‚modify�PIA�control�reg�image0‰LSR.L…#8,D1…bring�OR�byte�into�working�position-‰OR.B†D1,(A4,D7)‚modify�PIA�control�reg�image.‰LSR.L…#8,D1…bring�debounce�data�into�position/‰OR.B†D1,-1(A4,D7)‚add�debounce�data�to�PIA�map*‰LSR.L…#1,D1‡bring�wakeup/que�bit�to�bit�7(‰AND.B…#$80,D1Šselect�wakeup/quevent�bit.‰OR.B†D1,(A4,D7)„add�wakeup/que�bit�to�PIA�map‰RTS‰PAGED*********************************************************************:*‰DOPIA‚Copy�the�interrupt�control�data�and�data�direction3*�information�from�the�PIA�register�images�(in�map)*�to�the�PIA�registers.*A*‚The�PIA�must�not�be�allowed�to�generate�an�interrupt�during�theE*‚initialization�process�because�the�CMR�and�RIO�tables�have�not�been@*‚set�up.‚To�enforce�this,�all�interupts�are�disabled�during�the@*‚code�section�where�the�PIA�control�reg.'s�are�set,�and�the�PIA*‚interrupt�flags�are�cleared.**ˆENTRY�PARAMETERS:*�A4�=�address�of�RIOTBL*�A5�=�address�of�CCB***‰Exit:‚D0.W�=�RIONID�if�PIA�map�not�found*�D0.W�=�0�if�no�errors�found**‰Uses:�A0,D1,D6,D7**D*********************************************************************;*‚CLRIRQ�is�an�AND�mask�used�to�clear�PIA�IRQ�control�bits.*"CLRIRQƒEQU‡$E4‡clears�bits�0,1,3,4*** DOPIA EQU *ŠPUSHPOINT’save�all�pointers!ŠMOVE.L�D7,-(A7)‹save�register�D7,ŠMOVE.W�RIOPIA(A4),D7†get�offset�to�PIA�maps$ŠMOVE.B�RIONAL(A4),D6†get�#�of�RIO'S3ŠMOVE.L�CCBCHB(A5),D1†get�memory�mapped�I/O�address>DOPIA10ƒCMP.L‚PIADDR(A4,D7),D1ƒlook�for�a�matching‚I/O�address(ŠBEQ.S‚DOPIA20Œbranch�if�found�the�entry(ŠADD.W‚#PIALNG,D7‰bump�to�next�map�entry"ŠSUB.B‚#1,D6Ždecrement�the�counter/ŠBNE.S‚DOPIA10Œbranch�if�more�entries�to�search9ŠMOVE.W�#RIONID,D0‰set�for�fatal�error�(shouldn't�happen) ŠBRA�DOPIAX�branch�to�exit�point**‰D7�contains�offset�to�PIA�map(*‰set�direction�register�of�channels�0-7**ˆMASK�ALL�INTERRUPTS* DOPIA20 EQU *0ŠMOVE.WƒSR,D6Œsave�present�interrupt�mask�status!ŠOR‡#$0700,SRˆmask�all�interrupts***‰Set�direction�register�for�channel�0�-�7 3*‰Newly�created�OUTPUT�channels�must�be�set�to�OFF.4*‰To�do�this,�OR�new�channels�bit�map�with�data�reg.<*‰(there�is�logical�inversion)�between�PIA�and�final�output.*ŠCLR†D2�for�useŠCLR†D1�for�use6ŠMOVE.L�PIADDR(A4,D7),A0ƒget�memory�mapped�I/O�address,ŠBSET…#2,PIA2ADR(A0)ƒset�for�data�reg�access-ŠMOVE.BƒPIA2ADR(A0),D4ƒget�old�data�reg�value+ŠNOT†D4�convert�data�format�to�conventional'ŠBCLR…#2,PIA2ACR(A0)ƒset�for�DDR�access;ŠMOVE.BƒPIA2ADR(A0),D2ƒget�a�copy�of�old�data�direction�reg-ŠAND†D2,D4Œselect�on�channels�that�are�outputŠNOT†D24ŠMOVE.BƒDODR07(A4,D7),D1„get�the�new�output�channelsŠAND†D2,D1Œfind�new�channels:ŠMOVE.B�PIA2ADR(A0),D0…read�channel�0-7�direction�register9ŠOR.BƒDODR07(A4,D7),D0ƒadd�in�the�new�setting�information8ŠMOVE.B�D0,PIA2ADR(A0)…store�into�the�direction�register,ŠBSETƒ#2,PIA2ACR(A0)…set�for�output�function4ŠOR.B„D1,PIA2ADR(A0)„set�new�OUTPUT�channels�for�OFF'ŠNOT…D4�convert�to�inverted�data�format/ŠAND.B„D4,PIA2ADR(A0)ƒadd�in�old�data�reg�value*-*‰Set�direction�register�for�channels�8�-�16.*>*‰Newly�created�OUTPUT�channels�must�be�set�OFF.‚To�do�this,OR>*‰new�channels�bit�mask�with�data�register�(there�is�a�logical3*‰inversion�between�PIA�outputs�and�final�outputs).*ŠCLR†D2�for�useŠCLR†D1�for�use,ŠBSET…#2,PIA2BDR(A0)ƒset�for�data�reg�access-ŠMOVE.BƒPIA2BDR(A0),D4†get�old�data�reg�value+ŠNOT†D4�convert�data�to�conventional�format'ŠBCLR…#2,PIA2BCR(A0)†set�for�DDR�access7ŠMOVE.BƒPIA2BDR(A0),D2†get�a�copy�of�old�direction�reg.-ŠAND†D2,D4Œselect�on�channels�that�are�outputŠNOT†D20ŠMOVE.BƒDODR815(A4,D7),D1ƒget�new�direction�reg.%ŠAND†D2,D1Œselect�new�output�channels;ŠMOVE.B�PIA2BDR(A0),D0…read�channel�8-15�direction�register:ŠOR.BƒDODR815(A4,D7),D0‚add�in�the�new�setting�information8ŠMOVE.B�D0,PIA2BDR(A0)…store�into�the�direction�register,ŠBSETƒ#2,PIA2BCR(A0)…set�for�output�function0ŠOR.BƒD1,PIA2BDR(A0)…set�new�output�channels�off'ŠNOT†D4�convert�data�to�inverted�format1ŠAND.B„D4,PIA2BDR(A0)ƒreplace�old�data�reg�values **ˆClear�all�PIA�interrupts*‰TST.B…PIA1ADR(A0)‰clear�PIA�1A‰TST.B…PIA1BDR(A0)‰clear�PIA�1B‰TST.B…PIA2ADR(A0)‰clear�PIA�2A‰TST.B…PIA2BDR(A0)‰clear�PIA�2B*#* Set channels 4-5 IRQ control bits*6ŠMOVE.B�PIA2ACR(A0),D0…get�0-7�output�control�register)ŠAND.B„#CLRIRQ,D0‡negate�IRQ�control�bits;ŠOR.BƒOCR07(A4,D7),D0„add�channel�4-5�interrupt�information*ŠMOVE.B�D0,PIA2ACR(A0)…write�the�new�stuff*,*‰set�interrupt�information�for�channels�6-7*<ŠMOVE.B�PIA2BCR(A0),D0…get�chan�8-15�output�control�register(ŠAND.B„#CLRIRQ,D0‡clear�IRQ�control�bits<ŠOR.BƒOCR815(A4,D7),D0ƒset�channel�6-7�interrupt�information*ŠMOVE.B�D0,PIA2BCR(A0)…write�the�new�stuff*,*‰set�interrupt�information�for�channels�0-1*:ŠMOVE.B�PIA1ACR(A0),D0…get�chan�0-7�input�control�register(ŠAND.B„#CLRIRQ,D0‡clear�IRQ�control�bits;ŠOR.BƒICR07(A4,D7),D0„set�channel�0-1�interrupt�information*ŠMOVE.B�D0,PIA1ACR(A0)…write�the�new�stuff*,*‰set�interrupt�information�for�channels�2-3*>ŠMOVE.B�PIA1BCR(A0),D0…get�channel�8-15�input�control�register(ŠAND.B„#CLRIRQ,D0‡clear�IRQ�control�bits<ŠOR.BƒICR815(A4,D7),D0ƒset�channel�2-3�interrupt�information*ŠMOVE.B�D0,PIA1BCR(A0)…write�the�new�stuffŠCLR.L‚D0‘set�for�good�return**ˆrestore�interrupt�level*6ŠMOVE.WƒD6,SRŒreturn�interrupt�masks�to�previous�valueDOPIAX�EQU�*˜exit�sequenceŠMOVE.Lƒ(A7)+,D7‰restore�D7ŠPOP_POINT‘recall�all�pointersŠRTS—return�to�callerŠPAGEL*****************************************************************************6*‰CLRPIAMƒClear�out�the�PIA�map�for�this�memory�mapped*“I/O�address.*&*‰Entry:�A1�=�RIO-ID�address�in�RIOTBL%*�A2�=�address�of�CMR�parameter�block%*�A3�=�address�of�RIO�parameter�block*�A4�=�address�of�RIOTBL*�A5�=�address�of�CCB*�A6�=�address�of�users�TCB**‰Uses:‚D4,D6,D7*%*‰Exit:‚D0�=�RIONID�if�an�error�found**�D0�=�contents�on�entry�if�no�error�found* L*****************************************************************************3CLRPIAMƒMOVE.W�RIOPIA(A4),D7†get�offset�to�PIA�maps.ŠMOVE.B�RIONAL(A4),D6†get�#�of�RIO'S�allocated3ŠMOVE.L�CCBCHB(A5),D4†get�memory�mapped�I/O�addressDCLRPIAM1‚CMP.L‚PIADDR(A4,D7),D4ƒlook�for�matching�mem.�map.�I/O�addrŠBEQ.S‚CLRPIAM2‹branch�if�found$ŠADD.W‚#PIALNG,D7‰bump�to�next�entryŠSUB.B‚#1,D6Ždecrement�counter0ŠBNE.S‚CLRPIAM1‹branch�if�more�entries�to�search#ŠMOVE.W�#RIONID,D0‰set�error�returnŠRTS—return�to�caller*CLRPIAM2‚CLR.L‚DODR07(A4,D7)†clear�the�map ŠCLR.L‚OCR07(A4,D7)‡and�the�restŠRTS—return�to�callerŠPAGEL******************************************************************************‚CLOSE�COMMAND*A*‚Close�all�connections�with�this�user�task�and�his�open�channelsB*‚for�this�RIO�module.�The�channels�are�put�back�to�the�pre-opened4*‚state.�All�I/O�on�this�user's�channels�is�stopped.*$*‚RIO�CLOSE�COMMAND�parameter�block: *‰DS.Wƒ1ƒreturned�command�status*‰DS.Wƒ1ƒcommand�code�02*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�STOPPIA*L*****************************************************************************CLOSE:+ŠMOVE.L�#4,D1Žbump�past�RIO-ID�in�the�table!ŠCLR.L‚D2‘use�for�channel�counter5CLOSE10ƒCMP.L‚RIOTCB(A1,D1),A6ƒchannel�for�this�user?*ŠBNE.S‚CLOSE20Œbranch�if�not�for�this�user3ŠMOVE.W�RIOCNIF(A1,D1),D0‚get�channel�configuration4ŠBSR„STOPPIAŒgo�stop�I/O�on�this�channel�D2�=�chan�#?ŠMOVE.W�#$FFFF,RIOTCB(A1,D1)�set�this�channel�entry�to�not�used5CLOSE20ƒADD.L‚#CHANLNG,D1ˆpoint�to�next�channel�entryŠADD.L‚#1,D2Žcount�this�channel$ŠCMP.L‚#16,D2�searched�all�channels?&ŠBNE.S‚CLOSE10Œbranch�if�more�channelsŠCLR.L‚D0‘set�for�no�errorsŠBRA„NRMEXITŒand�return�to�CMRŠPAGED*********************************************************************4*‚STOPPIAƒdeactivate�I/O�on�specified�channel�number*&*‚Entry:�A1�=�RIO-ID�address�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‰D0.W�=�channel�configuration%*‰D2.L�=�channel�number�to�deactivate* *‚Uses:‚D0,A0*L*****************************************************************************:STOPPIAƒMOVE.L�CCBCHB(A5),A0†get�memory�mapped�I/O�addressŠCMP.B‚#8,D2Žchannel�8-15?&ŠBGE.S‚STOPIA60‹branch�if�channel�8-15* *‰channel�0-7*5ŠBCLRƒ#2,PIA2ACR(A0)…select�output�direction�register/ŠBCLRƒD2,PIA2ADR(A0)…set�this�channel�for�input0ŠBSETƒ#2,PIA2ACR(A0)…select�output�data�register,ŠBCLRƒD2,PIA2ADR(A0)…deactivate�this�channelŠBTSTƒ#0,D0Žinput�channel?,ŠBNE.S‚STOPIART‹branch�if�no,�output�channel*/*‰input�channel�-�determine�if�using�interrupts* ŠBTSTƒ#1,D0Žinterrupts�disabled?"ŠBNE.S‚STOPIART‹branch�if�disabled-ŠBTSTƒ#0,D2Žsee�if�odd�or�even�channel�number,ŠBNE.S‚STOPIA10‹branch�if�odd�channel�number7ŠMOVE.B�#1,D0Ževen�chan�-�disable�interrupts�bit�#�is�0ŠBRA.S‚STOPIA20‹and�continue>STOPIA10�MOVE.B�#4,D0�odd�chan�-�disable�interrupts�bit�#�is�3.STOPIA20�CMP.B‚#1,D2�get�actual�channel�number)ŠBGT.S‚STOPIA30‹branch�if�not�channel�0-15ŠBCLRƒD0,PIA1ACR(A0)…disable�interrupts�-�channel�0-1STOPIART‚RTS—return�to�caller.STOPIA30‚CMP.B‚#3,D2Žsee�if�channel�number�2-3!ŠBGT.S‚STOPIA40‹branch�if�not�2-33ŠBCLRƒD0,PIA1BCR(A0)…disable�interrupts�channel�2-3ŠBRA.S‚STOPIART‹and�return.STOPIA40‚CMP.B‚#5,D2Žsee�if�channel�number�4-5!ŠBGT.S‚STOPIA50‹branch�if�not�4-53ŠBCLRƒD0,PIA2ACR(A0)…disable�interrupts�channel�4-5ŠBRA.S‚STOPIART‹and�return;STOPIA50‚BCLRƒD0,PIA2BCR(A0)…disable�interrupts�channel�6-7ŠBRA.S‚STOPIART‹and�returnŠPAGE**‰channel�8-15*(STOPIA60‚MOVE.L�D2,D0Žget�channel�number!ŠSUB.L‚#8,D0Žmake�0-7�type�number5ŠBCLRƒ#2,PIA2BCR(A0)…select�output�direction�register"ŠBCLRƒD0,PIA2BDR(A0)…set�for�input 0ŠBSETƒ#2,PIA2BCR(A0)…select�output�data�register,ŠBCLRƒD0,PIA2BDR(A0)…deactivate�this�channelŠRTS—return�to�callerŠPAGEF************************************************************************‰OUTON�-�TURN�ON�RELAY�COMMAND;*‰This�command�activates�relays�for�specified�channels�that9*‰have�previously�been�opened�for�output�by�the�same�task<*‰requesting�this�activation.‚The�parameter�block�is�checked9*‰for�errors�before�any�relay�is�activated.‚No�channel�is!*‰activated�if�an�error�is�found.9*‰All�channels�within�a�PIA�are�activated�sumultaneously.>*‰Outon�reads�the�pia�data�register�to�find�the�current�state.*%*‰RIO�OUTPUT�command�parameter�block: *‰DS.Wƒ1ƒreturned�command�status*‰DS.Wƒ1ƒcommand�code�034*‰DS.Wƒ1ƒbit�mask�containing�channel�#'s�to�activate*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�DOOUT**L*****************************************************************************OUTON:ŠPUSHPOINT‘save�all�pointers3ŠCLR.L‚D3‘flag�to�ck�para.�blk.�before�doing�output.OUTON10ƒMOVE.L�#4,D1Žbump�past�RIO-ID�in�table!ŠCLR.L‚D2‘use�for�channel�counterŠCLR.L‚D0‘clear�for�use+ŠMOVE.W�CMDCHN(A3),D0†get�channels�to�start8ŠMOVE.WƒCMDCHN(A3),D3„copy�ON�request�to�check�register.)OUTON20ƒBTSTƒD2,D0Žactivate�this�channel?0ŠBEQ.S‚OUTON30Œbranch�if�no�-�check�next�channel5ŠCMP.L‚RIOTCB(A1,D1),A6ƒchannel�belonge�to�this�user?"ŠBNE.S‚OUTONERŒbranch�if�no,�error3ŠMOVE.W�RIOCNIF(A1,D1),D4‚get�channel�configurationŠBTST‚#0,D4�an�output�channel?+ŠBEQ.S‚OUTONER1‹branch�if�not�output,�error.ŠBCLRƒD2,D3Žnegate�check�flag�for�this�channel$ŠTST„D3‘is�all�of�parameter�checked?(ŠBNE.S‚OUTON30Œbranch�if�not�all�checked5ŠBSR„DOOUTŽgood�parameter�block�-�go�activate�channelŠBRA.S‚OUTONEXŒnormal�exit/OUTON30ƒADD.L‚#1,D2Žbump�to�next�channel�number-ŠADD.L‚#CHANLNG,D1ˆbump�to�next�channel�entry'ŠCMP.L‚#16,D2�checked�all�the�channels?/ŠBNE.S‚OUTON20Œbranch�if�more�channels�to�check*<*Fall into invalid command for error return (error in OUTON)*AOUTONERƒMOVE.W�#RIOICU,D0‰set�invalid�command�for�this�user�errorŠBRA.S‚OUTONRTŒand�return?OUTONER1‚MOVE.W�#RIOICC,D0‰set�invalid�command�for�this�channelŠBRA.S‚OUTONRTŒand�return$OUTONEXƒCLR.L‚D0‘set�for�good�return%OUTONRTƒPOP_POINT‘recall�all�pointersŠBRA„NRMEXITŒgo�return�to�CMR‰PAGE** DOOUT…EQU„***A*DOOUT talks directly to the PIA data reg.s and turns on outputs.**‰On�entry�to�DOOUT:8*‰D0�contains�(16�bit)�bit�mask�for�desired�ON�channels.<*‰A5�contains�address�of�CCB�from�which�I/O�base�addr�is�ob.*-“MOVE.L„A2,-(A7)Œsave�address�of�CMR�para�blk*“MOVE.L„CCBCHB(A5),A2‡get�I/O�base�address#“NOT‡D0’logic�inversion�in�RIO�ckts*“AND.B…D0,PIA2ADR(A2)†turn�on�channels�0-7%“LSR.W…#8,D0�select�data�for�ch.�8-15+“AND.B…D0,PIA2BDR(A2)†turn�on�channels�8-15-“MOVE.L„(A7)+,A2Œrestore�addr�of�CMR�para�blk“RTS‰PAGEM******************************************************************************"*‰OUTOFF�-�TURN�OFF�RELAYS�COMMAND=*‰This�command�deactivates�relays�for�specified�channels�that9*‰have�previously�been�opened�for�output�by�the�same�task<*‰requesting�this�activation.‚The�parameter�block�is�checked;*‰for�errors�before�any�relay�is�deactivated.‚No�channel�is#*‰deactivated�if�an�error�is�found.*)*‰RIO�OUTPUT�OFF�command�parameter�block: *‰DS.Wƒ1ƒreturned�command�status*‰DS.Wƒ1ƒcommand�code�044*‰DS.Wƒ1ƒbit�mask�containing�channel�#'s�to�activate*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�DOOFF*L*****************************************************************************OUTOFF:ŠPUSHPOINT‘save�all�pointers 2ŠCLR.L‚D3‘flag�to�ck�para.�blk.�before�stop�output.OUTOF10ƒMOVE.L�#4,D1Žbump�past�RIO-ID�in�table!ŠCLR.L‚D2‘use�for�channel�counterŠCLR.L‚D0‘clear�for�use+ŠMOVE.W�CMDCHN(A3),D0†get�channels�to�start0ŠMOVE.WƒD0,D3Œcopy�chan.�to�turn�off�to�work�reg+OUTOF20ƒBTSTƒD2,D0Ždeactivate�this�channel?0ŠBEQ.S‚OUTOF30Œbranch�if�no�-�check�next�channel5ŠCMP.L‚RIOTCB(A1,D1),A6ƒchannel�belongs�to�this�user? ŠBNE„OUTONERŒbranch�if�no,�error3ŠMOVE.W�RIOCNIF(A1,D1),D4‚get�channel�configurationŠBTST‚#0,D4�an�output�channel?)ŠBEQ„OUTONER1‹branch�if�not�output,�error.ŠBCLR…D2,D3Œnegate�check�flag�for�this�channel$ŠTST„D3‘is�all�of�parameter�checked?(ŠBNE.S‚OUTOF30Œbranch�if�not�all�checked3ŠBSR„DOOFFŽgood�para.�block�-�go�deactivate�channelŠBRA.S„OUTOFFXŠnormal�exit/OUTOF30ƒADD.L‚#1,D2Žbump�to�next�channel�number-ŠADD.L‚#CHANLNG,D1ˆbump�to�next�channel�entry'ŠCMP.L‚#16,D2�checked�all�the�channels?/ŠBNE.S‚OUTOF20Œbranch�if�more�channels�to�check ŠBRA†OUTONEROUTOFFX�EQU�*šnormal�exitŠPOP_POINT‘recall�all�pointersŠCLR.L„D0�signal�no�errorsŠBRA�NRMEXIT�normal�exit‰PAGE*** DOOFF…EQU�**B*DOOFF‚talks�directly�to�the�PIA�output�regs�and�turns�off�outputs*G* On entry: D0 has bit map of channels to turn off (a 1 means turn off)*‹A5�has�address�of�user�CCB*:*‰DOOFF�is�called�by�OUTOFF�and�pulsed�output�deactivation*/ŠMOVE.LƒA2,-(A7)Œsave�address�of�CMR�para�block3ŠMOVE.LƒCCBCHB(A5),A2‡get�memory�mapped�I/O�address*D*‚There�is�a�logical�inversion�between�PIA�outputs�and�final�outputs**ŠOR.B…D0,PIA2ADR(A2)†turn�off�selected�0-71ŠLSR.W„#8,D0�select�information�for�channels�8-15+ŠOR.B…D0,PIA2BDR(A2)†turn�off�selected�8-152ŠMOVE.Lƒ(A7)+,A2Œrestore�address�of�CMR�para�blockŠRTSŠPAGEM******************************************************************************!*‰STAT�-�GET�INPUT�STATUS�COMMAND;*‰This�command�reads�the�status�of�specified�input�channels=*‰that�do�not�have�interrupts�enabled.‚The�channels�must�have>*‰previously�been�opened�for�input�by�this�user.‚The�parameter>*‰block�is�checked�for�errors�before�any�input�status�is�read.A*‰The�users�parameter�block�is�modified�to�signal�active�channels<*‰by�setting�the�corresponding�bit�in�the�bit-mask�word.�The;*‰corresponding�bit�number�of�inactive�channels�is�cleared.**.*‰All�channels�in�a�PIA�side�are�read�at�once.*+*‰RIO�INPUT�STATUS�command�parameter�block: *‰DS.Wƒ1ƒreturned�command�status*‰DS.Wƒ1ƒcommand�code�05<*‰DS.Wƒ1ƒbit�mask�containing�channels�numbers�to�read�status$*”(�this�is�also�the�returned�field)*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�GTSTAT*M******************************************************************************STAT:ŠPUSHPOINT‘save�all�pointers(ŠCLR.L‚D5‘use�for�returned�status�values2ŠCLR.L‚D3‘flag�to�ck�para.�blk.�before�read�status.STAT10„MOVE.L�#4,D1Žbump�past�RIO-ID�in�RIOTBLŠCLR.L‚D2‘channel�counterŠCLR.L‚D0‘clear�for�use;ŠMOVE.W�CMDCHN(A3),D0†get�channel�numbers�to�read�status�on3ŠMOVE.W�D0,D3Žcopy�chan�activation�req.�bit�pattern/STAT20„BTSTƒD2,D0Žread�status�for�this�channel?ŠBEQ.S‚STAT40�branch�if�no5ŠCMP.L‚RIOTCB(A1,D1),A6ƒchannel�belongs�to�this�user?1ŠBNE„OUTONERŒbranch�if�no�-�return�with�error�set3ŠMOVE.W�RIOCNIF(A1,D1),D4‚get�channel�configurationŠBTSTƒ#0,D4Žan�input�channel?9ŠBNE„OUTONER1‹branch�if�not�input�-�return�with�error�set'ŠCMP.B‚#8,D2Žsee�if�channel�number�8-156ŠBGE.S‚STAT30�branch�if�8-15�-�do�not�check�interrupts,ŠBTSTƒ#1,D4Žis�chan�1-7,�set�for�interrupts?2ŠBEQ„OUTONER1‹branch�if�set�for�interrupts�-�error6STAT30„BCLRƒD2,D3Žclr�activation�flag�for�this�channel*ŠTST„D3‘finished�checking�parameter�block?1ŠBNE.S‚STAT40�branch�if�not�finished�checking�yet.ŠBSR„GTSTAT�go�read�status�and�save�in�REG.�D5!ŠBRA.S‚STAT50�goto�procedure�exit 3STAT40„ADD.L‚#CHANLNG,D1ˆbump�to�next�channel�entry(ŠADD.L‚#1,D2Žbump�to�next�channel�number#ŠCMP.L‚#16,D2�checked�all�channels?,ŠBRA„STAT20�branch�to�channel�check�sequence�X�X‚(stamp�coupling)?*‚Return�parameters:‚none�(side�effects;�writes�to�PIA�ctl�reg)* DOENBL EQU *3‰LEA‡ENBLIRQ(PC),A1†get�address�of�enable_irq�table 3‰BSR‡MODIFYPIAŒmodify�PIA�control�reg�IRQ1�ctl�bits‰RTS‰PAGE *MODIFYPIA**†It's�functions�are:0*ˆa.�To�write�interrupt�control�data�to�PIA�maps=*ˆb.�To�write�interrupt�control�data�to�PIA�control�registers*>*‹It�performs�these�two�functions�be�invoking�WRITMAP�&�DOPIA.+*‹It�DOES�NOT�MODIFY�DEBOUNCE�CONTROL�DATA.***ˆInput�parameters:/*’A1„address�of�enable�/�disable�constant�table*’D2„channel�#*’A4„RIOTBL�address*’D1„X��X�X>*ˆOutput�parameters:‚none�(side�effects;�writes�PIA�registers)*MODIFYPIA EQU * ‰CLR.L…D7‰MOVE.L„D2,D5ˆsetup�channel�#2‰MOVE.W„RIOPIA(A4),D7‡get�offset�to�user's�PIA�map ‰BTST†#0,D2…even�or�odd�channel?"‰BNE.S…MODF1…branch�on�odd�channel-‰MOVE.W„(A1),D1ƒget�even�channel�control�mask ‰BRA.S…MODF2 MODF1 EQU ***ˆstage�code�for�WRITMAP*1‰MOVE.W„2(A1),D1‚get�odd�channel�IRQ�control�mask MODF2 EQU *2‰BSR‡WRITMAPƒwrite�the�new�interrupt�status�to�map,‰BSR‡DOPIA…write�the�new�control�data�to�PIA‰RTS‰SPC�10*ENBLIRQ�EQU�*†table�for�use�by�DOENBL�only@*‚MS�byte�is�OR'ed�with�control�data,�LS�byte�is�AND'ed�with�it.%‰DC.W†$01FF…enable�irq�even�channel�#$‰DC.W†$08FF…enable�IRQ�odd�channel�#;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ŠPAGEM******************************************************************************%*ˆDSABLE�-�DISABLE�INTERRUPTS�COMMAND>*‰This�command�disables�interrupts�for�the�specified�channels.<*‰The�channels�must�have�been�opened�for�input�by�this�user,?*‰must�be�channels�0-7�only,�and�must�currently�have�interrupts;*‰enabled.‚The�parameter�block�is�checked�for�errors�before>*‰any�interrupts�are�disabled.�No�channels�are�disabled�if�any*‰error�is�found.*1*‰RIO�DISABLE�INTERRUPTS�command�parameter�block: *‰DS.Wƒ1ƒreturned�command�status*‰DS.Wƒ1ƒcommand�code�07B*‰DS.Wƒ1ƒbit�mask�containing�channel�numbers�to�disable�interrupts*)*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB**‚Calls:�DODSABL*M*****************************************************************************DSABLE:ŠPUSHPOINT‘save�all�pointers7DSABL10ƒMOVE.L�#4,D1Žset�D1�to�chan�config.�entry�(row)!ŠCLR.L‚D2‘use�for�channel�counter1ŠCLR.L‚D0‘clear�for�use�as�channel�activ.�bit�map4ŠMOVE.W�CMDCHN(A3),D0†get�channel�activation�bit�map+ŠCMP.W‚#$FF,D0Œcannot�specify�channels�8-153ŠBGT„ENABLERŒbranch�if�8-15�-�return�with�error�set(DSABL20ƒBTSTƒD2,D0Ždisable�this�channel?)ŠBEQ.S‚DSABL30Œbranch�if�not�this�channel-ŠCMP.L‚RIOTCB(A1,D1),A6ƒbelongs�to�this�user?0ŠBNE„OUTONERŒbranch�if�no,�return�with�error�set3ŠMOVE.W�RIOCNIF(A1,D1),D4‚get�channel�configurationŠBTSTƒ#0,D4Žan�input�channel?8ŠBNE„OUTONER1‹branch�in�not�input,�return�with�error�setŠBTSTƒ#1,D4Žinterrupts�enabled?1ŠBNE„OUTONER1‹branch�if�no,�return�with�error�set/ŠBSET…#1,D4Œdisable�interrupts�for�this�channel>ŠMOVE.WƒD4,RIOCNIF(A1,D1)ƒstore�out�irq�data�in�config.�RIOTBLŠPUSHALL“save�all�regs!ŠBSR„DODSABLŒgo�do�actual�disableŠPOPALL”restore�all(DSABL30ƒADD.L‚#1,D2Žbump�to�next�channel-ŠADD.L‚#CHANLNG,D1ˆbump�to�next�channel�entry"ŠCMP.L‚#8,D2Žchecked�all�channels?&ŠBNE.S‚DSABL20Œbranch�if�more�channels)ŠBRA†ENABLOKŠreturn�with�status�=�no�errsŠPAGE**.*DODSABL is a local subroutine for DSABLE only**ƒInput�parameters**’D2.W‚channel�#*’A4„RIOTBL�address*?*‚Return�parameters:‚none�(side�effects;�writes�to�PIA�ctl�reg)* DODSABL EQU *3‰LEA‡DSBLIRQ(PC),A1†get�address�of�enable_irq�table3‰BSR‡MODIFYPIAŒmodify�PIA�control�reg�IRQ1�ctl�bits‰RTS*** DSBLIRQ‚EQU‡*.‰DC.W†$00FE…disable�IRQ�on�even�channel�number%‰DC.W†$00F7…disable�IRQ�odd�channel�#;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - -‰PAGEM*******************************************************************************ˆPLSO�-�PULSED�OUTPUT�COMMAND* )*‚Entry:�A1�=�address�of�RIO-ID�in�RIOTBL%*‰A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A4�=�address�of�RIOTBL*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB***‰Exits�to�NRMEXIT***Parameter block format for pulsed output:*0*RIO parameter block (pointed to by A3 on entry)* *ˆDS.W†1‰returned�command�status*ˆDS.W†1‰command�code*ˆDS.W†1‰number�of�channels<*ƒ---ƒ---ƒ---ƒparameters�for�individual�channelsƒ---ƒ---ƒ---*ˆDS.W†1‰first�channel�number,*ˆDS.L†1‰number�of�milliseconds�for�pulse�on*ˆ.*ˆ.*ˆDS.W†1‰nth�channel�number5*ˆDS.L†1‰number�of�milliseconds�for�nth�channel�pulse*7* EACH CHANNEL IS ACTIVATED IN TURN (NON-SYNCHRONOUSLY)**M***************************************************************************** PLSO:*@*ƒPulsed_Out(IN:LIST�OF�channel�activation�request,�pulse�times;*ˆOUT:error�code)>‰ALLOCATE�CHANID,RIOPARBK†allocate�channel�id�&�RIO�para�block3‰STORE…A3,RIOPARBK‰save�RIO�parameter�block�address**†Initiate�pulsed�output*!‰CLR.L…D6’clear�working�registers ‰CLR.L…D3’. ‰CLR.L…D2’. ‰CLR.L…D0’.*$*ˆget�number�of�channels�to�activate*<‰MOVE.W„CMDCHN(A3),D0‡get�number�of�chan's�from�RIO�para�blk**‡WHILE�channel�count�>�0*PLSO1:$‰TST.W…D0’loop�on�#�of�chan.'s�to�do ‰BEQ‡PLSOX**ˆDO**‡get�first�channel�number* ‰CLR.L…D5‰MOVE.W„NUMCHAN(A3,D6),D5$‰STORE…D5,CHANID‹save�channel�number*G* Channel ID will consist of user CCB address + chan number in LS byte.*+‰MOVE.L„A5,D7�copy�user's�CCB�address�to�D75‰ADD.L…D7,CHANID(A7)‡CHANID�now�has�complete�chan.�ID"‰MOVE.L„D5,D7�copy�channel�#�to�D7,‰BSR‡BIN_BIT�convert�binary�to�bit�map�in�D5*)*‚IF�channel�belongs�to�current�user�THEN*6‰MULU†#CHANLNG,D7‰compute�offset�to�nth�chan�in�RIOTBL%‰ADD‡#4,D7�bump�to�user�TCB�in�RIOTBL-‰CMP.L…RIOTCB(A1,D7),A6„compare�TCB�addresses1‰BNE.S…PLSOER1�branch�on�channel�not�current�user**ˆDO'*ˆGet�channel�configuration�from�RIOTBL*8‰MOVE.W„RIOCNIF(A1,D7),D3ƒget�channel�config�from�RIOTBL*&*‚IF�channel�is�an�output�channel�THEN* ‰BTST†#0,D3.‰BEQ.S…PLSOER2ƒbranch�on�not�an�output�channel**„DO2*…Get�pulse�time�from�RIO�commmand�parameter�block*‰MOVE.L„CHNCNFG(A3),D3*%*„IF�pulse�time�>�pulse_min_time�THEN*'‰BEQ.S…PLSOER3ƒbranch�on�pulse�time�=�0**„DO-*†request�periodic�activation(this�channel�#)*2‰LEA‡PLSOFF(PC),A0‡point�to�pulse�turn�off�routine%‰CLR.L…D1’set�request�for�1�time�only6‰MOVE.B„CCBPPRIO(A5),D1…set�act.�priority�same�as�task/‰LOAD†D2,CHANID‹setup�channel�ID�to�goto�PLSOFF'‰MOVE.L„D3,A1�setup�activation�interval‰PUSHALL"‰TR0$.RQPA˜pass�request�for�wakeup*)*‚If�no�err�in�periodic�act.�request�THEN*‰BRA.S…RQPAOKŽgood�return(‰BRA.S…PLSOER4�err�in�periodic�act.�req.**†DO*RQPAOK:‰POPALL(‰PUSHALL—a�more�elegant�way�to�do�this�?*"*ˆactivate_this_channel(channel�#)*$‰MOVE.L„D5,D0�pass�bit�mask�to�DOOUT ‰BSR‡DOOUT‰POPALL**†END*ƒEND*ƒdecrement�channel�count* ‰SUB‡#1,D0**END* ‰BRA‡PLSO1**ˆError�handling*PLSOER1‚CLR.L…D00‰MOVE.B„#RIOICNS,D0‰channel�not�for�current�user ‰BRA.S…PLSOX1PLSOER2: ‰CLR.L…D00‰MOVE.B„#RIOICC,D0Šchannel�not�an�output�channel ‰BRA.S…PLSOX1PLSOER3:"‰CLR.L…D0’requested�pulse�time�=�03‰MOVE.B„#RIOCNFG,D0‰return�'bad�configuration'�code ‰BRA.S…PLSOX1PLSOER4:‰POPALL ‰CLR.L…D0+‰MOVE.B„RIOBSY,D0‹periodic�activation�error ‰BRA.S…PLSOX1Žreturn�device�busy‰SPC�2** Pulsed output good exit point*;PLSOX„LOAD†A3,RIOPARBK‰restore�RIO�para�block�address�to�A3‰CLR.L…D0ˆset�for�normal�returnPLSOX1: ‰ADD.L…#12,A7*‰BRA†NRMEXIT„goto�normal�common�exit�point‰PAGE**‡PULSED�OUTPUT�DEACTIVATION:**ˆPulsed�output�de-activation.!*ˆEntered�by�periodic�activation. *ƒOn�entry:?*ˆD1�contains�channel�ID�composed�of�user's�CCB�address�in�M.S.8*ˆ3�bytes,�and�channel�number�(0-15)�in�least�sig.�byte.*PLSOFF:‰PUSHALL&‰MOVE.B„D1,D5�save�combined�channel�ID  ‰AND.B…#0,D1�recover�CCB�address+‰MOVE.L„D1,A5�stage�CCB�address�for�'DOOFF'+‰AND.L…#$000000FF,D5‡recover�channel�number,‰BSR‡BIN_BIT�convert�chan�#�to�bit�map�in�D5"‰MOVE.L„D5,D0�stage�data�for�DOOFF‰BSR‡DOOFF�turn�off�channel‰POPALL‰RTE‰PAGEBIN_BIT:*$* Binary to bit-map conversion in D5*J*Produces a 1 in D5 corresponding to the value in D5 (in binary) up to 15.@*ˆFor�input�>�15�binary�the�resultant�pattern�in�D5�is�undefined*‰ALLOCATE‚BITMAP‰CLR.L…BITMAP(A7)‰ADD.W…#1,BITMAP(A7) LOOP…SET‡* ‰TST.W…D5‰BEQ‡BINBITX�exit�on�bit�found‰ROL.W…BITMAP(A7) ‰SUB‡#1,D5 ‰BRA‡LOOP BINBITXŒEQU‡*‰MOVE.W„BITMAP(A7),D5‰DEALOC„BITMAP‰RTSŠPAGEO******************************************************************************** *ˆNORMAL�EXIT*,*‚Entry:�A2�=�address�of�CMR�parameter�block%*‰A3�=�address�of�RIO�parameter�block*‰A5�=�address�of�CCB*‰A6�=�address�of�users�TCB*‰D0�=�RIO�error�code*I**************************************************************************NRMEXIT:>ŠMOVE.W�D0,CMDSTA(A3)†set�return�status�in�RIO�parameter�blockŠRTS—return�to�CMRŠPAGEJ****************************************************************************ˆKILR�(KILLER)*4*“Routine�called�to�handle�unrecoverable�conditions.**K****************************************************************************KILR: ‰TR0$.KILLERŠ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�work�boundary.)ŠBNE.S‚IOHADR4�Branch�if�bad�buffer�base.ŠTST.L‚D5”Length�can't�be�zero.2ŠBEQ.S‚IOHADR8�Don't�go�to�logphy�with�zero�count. IOHADR2ƒEQU„*1ŠMOVE.L�TCBTST(A1),A0‰Address�of�task�seg.�table. ŠTR0$.LOGPHY.ŠBRA.S‚IOHADR8�Branch�for�good�address�return.0ŠBRA.S‚IOHADR6�Branch�for�bad�byte�count�return.(ŠTST.L‚D5”Was�an�entry�pointer�returned.#ŠBEQ.S‚IOHADR4�Branch�if�no�-�ERROR)ŠTST.B‚7(A0,D5)ŽIs�this�an�MMIO�segment�?ŠBNE.S‚IOHADR8�Yes,�OK.3IOHADR4ƒADD.L‚#2,(A7)�Adjust�PC�for�invalid�return.3IOHADR6ƒADD.L‚#2,(A7)�Adjust�PC�for�invalid�return.IOHADR8ƒRTSšReturn.Š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.ŠNOPšBad�task�specification.&ŠADD.L„#2,(A7)�Bad�task�specification.GETT10„RTSšReturn.ŠPAGEJ**************************************************************************** INTERRUPT SSERVICE ROUTINE*?*ƒPURPOSE:‚HANDLE�THE�RIO�INTERRUPTS�AND�NOTIFY�THE�USER�OF�THE5*�INTERRUPTS.‚OPERATES�AT�HARDWARE�INTERRUPT�PRIORITY*�LEVEL.*1*ƒENTRY:‚JSR‚FROM�INTERRUPT�HANDLER�ROUTINE�-�CMR*‹A0�-�WORK�REGISTER *‹A1�=�SELF*‹A5�=�ADDRESS�OF�CCB*‹D0�=�WORK�REGISTER*5*ƒEXIT:‚RTS�-�BACK�TO�INTERRUPT�HANDLER�ROUTINE�-�CMR*C*ŠInterrupt�handler�must�pruserve�all�data�reg.'s�&�address�reg.'s.***ƒREGISTERS�USED:ƒ01234567 *”D******** *”A*****P****ƒEXEC�ROUTINES�CALLED:‚QEVENTI**ƒCODE�IS�RE-ENTRANT**?*‚Debounce�on�interrupt�added�9/13/82.‚Debounce�is�0�to�512�ms,9*‚encoded�in�bits�8-14�of�the�channel�configuration�word.I*‚The�scale�factor�for�debounce�time�is�4�ms�per�count�in�ch.�config.�wd.* F*---------------------------------------------------------------------*RIOINT:*<* Find RIO TABLE module (board) name which matches CCB name:*-ˆMOVEM.L„A0-A6/D1-D7,-(A7)„save�all�except�D0:ˆALLOCATEƒRIOTADR,CHANUM,CLAIMCHKƒallocate�local�variables/ˆCLR.L†CLAIMCHK(A7)…clear�interrupt�claim�check-ˆMOVE.L…RIOTBL,A2‰get�address�of�RIOTBL�to�A2 ˆCLR.L…D76ˆMOVE.B„RIONMAX(A2),D7…get�max�number�of�RIOID's�to�D7#ˆMOVE.L„CCBMNEM(A5),D0…get�ccb�name2IOHI011�EQU�*‚find�matching�RIOID�loop�entry�point*ˆMOVE.L„RIOID(A2),D3‡get�RIOID�for�staging'ŠCMP.LƒD3,D0Ždoes�CCB�name�match�RIOID?#ŠBEQ.SƒIOHI020Œbranch�on�name�match,ŠADDA.W‚RIOOFST,A2‰add�offset�to�next�RIOTBL#ŠSUB.Bƒ#1,D7Žtest�for�end�of�RIOTBL*ŠBMI…IOHIPXŠbranch�to�exit�if�id�not�found ŠBRA�IOHI011 IOHI020ƒEQU�**F*‚Found�matching�names,�now�get�number�of�interrupting�channel�(to�D2)2*‚and�clear�hardware�interrupt�flag�in�PIA�device.*%‰STORE…A2,RIOTADRŠsave�RIOTBL�address,‰MOVE.L„#$0C010000,D2‡init�para�fields�in�D2)‰BSR‡IOHICLR�clr�irq�&�get�int.�channel�#+‰STORE…D2,CHANUM‹save�chan.�#�&�return�code*>* Compute address of field in RIOTBL having user's TCB address* ŠCLR.L„D4!ŠMOVE.BƒD2,D4�get�channel‚to�D4.B)ŠCMP.B„#8,D4�channel�must�be�<�8�or�error'ŠBEQ.S„IOHIPXŒexit�on�channel�not�found1ŠADD.L„#1,CLAIMCHK(A7)ƒmark�interrupt�acknowledge2ŠMULU…#6,D4�point�to�data�field�assoc�with�channel5ŠADD†#RIONTRY,D4‡add�offset�to�1st�channel�data�fieldŠADD†#4,D4�add�in�size�of�RIOID-ŠMOVE.LƒRIOTBL,A2‰get�address�of�RIOTBL�to�A26ŠMOVE.L‚RIOTCB(A2,D4),A6„A6�now�has�user's�TCB�address*"*IF channel requires debounce THEN*3ŠMOVE.WƒRIOCNIF(A2,D4),D0ƒget�channel�configuration(ŠAND†#$7F00,D0‹select�debounce�time�data…IF.L†ŠTHEN*„DO;*ˆRequest�periodic�activation(CCB_adr,chan_#,debounce_time)6*ˆGenerate�channel�ID�=�CCB�address�+�channel�#�to�D2:**‰MOVE.L„A5,D7�copy�board�CCB�address�to�D7‰ADD.B…D2,D7�add�channel�number/‰MOVE.L„D7,D2�stage�channel�ID�for�period.�act..‰LEA‡DEBOUNCE(PC),A0…point�to�debounce�routine!‰CLR.L…D1’request�1�periodic�act.1‰MOVE.B„CCBPPRIO(A5),D1…set�priority�same�as�task&‰LSR‡#8,D0�position�debounce�time�data-‰MULU†#4,D0�multiply�by�debounce�delay�factor ‰MOVE.L„#0,A1*‰MOVE.W„D0,A1�stage�time�for�periodic�act..‰LINK†A6,#-(ALLREGS+4)…add�some�extra�room�(4)*I* NOTE: LINK has reserved space on the stack for all registers + 4 words.A*‡Now�I�can�do�MOVEM.L�to�the�stack�without�auto�inc�or�auto�dec.B*‡and�as�long�as�I�get�back�A6�unchanged,�UNLINK�A6�will�take�care+*‡of�adjusting�the�stack�pointer�correctly.*.‰MOVEM.LƒA0-A6/D0-D7,(A7)„save�all�reg.�values ‰TR0$.RQPA*/*‡IF�no�error�returned�from�per.�act.�req.�THEN*,‰BRA.S…DBACTOK�good�return�from�per.act.req.+‰BRA.S…DBACTNG�bad�return�from�per.act.req.*‡DO*DBACTOK‚EQU‡*‰Debounce�act.�req.�return�ok**ŠDisable�IRQ�on�this�channel.%*ŽStage�arguments�for�call�to�DODSABL*0‰MOVEM.Lƒ(A7),A0-A6/D0-D7„recall�register�values.‰MOVE.L„RIOTADR+4(A6),A4„recall�RIOTBL�address#‰AND‡#$000000FF,D2‡select�channel�#+‰BSR‡DODSABL�disable�IRQ.�note:�ck'�9/15/82*DBACTNG„EQU…*‰debounce�act.�req.�return�NG*ˆENDƒdisable�IRQ0‰MOVEM.Lƒ(A7),A0-A6/D0-D7„recall�register�values‰UNLK„A6*…END†debounce�setup�sequence†ELSE**…here�if�no�debounce�required*.‰LOAD†D2,CHANUM‹recall�channel�#�&�return�code‰BSR‡NOTIFYUSR†ENDI$IOHIPX„EQU�*‡'RIOINT'�procedure�exit+‰LOAD‚D0,CLAIMCHKŒget�interrupt�claim�check#‰ADD‡#16,A7Žrelease�local�variables0‰MOVEM.Lƒ(A7)+,A0-A6/D1-D7ƒrestore�all�except�D0+‰TST.L…D0’does�RIODRV�claim�this�interrupt?‰IF.L‚�THEN(‰ORˆ#1,SR�signal�CMR�'interrupt�handled'‰ELSE2‰AND‡#$FFFE,SR‹signal�CMR�'interrupt�not�from�RIO'‰ENDI‹RTS…PAGE NOTIFYUSR:*A*ˆnotify�user�by�means�of�que�event�or�wakeup�as�specified�in�the*ˆchannel�configuration�word.**„INPUT�PARAMETERS:'*’A2:�Address�of�channel�name�in�RIOTBL;*’D4:�Offset�from�channel�name�to�channel�data�field�(base) *™in�RIOTBL.*’A5:�Address�of�channel�CCB.  'A;!4)L1*’A6:�User's�TCB�address#*’D2:�$0C01�**@ŠMOVE.WƒRIOCNIF(A2,D4),D0�get�channel�configuration�from�channel *¤configuration�table�in�RIOTBL.)ŠBTST…#3,D0�determine:�wake-up�or�q-event ‰IF…‰THEN**ˆDO*ˆEnqueue�event;�data�staging:*$*ƒD2�=�$0C01� *ƒD3�=�RIOID*ƒD4�=�Mem�mapped�I/O�address*ƒA6�=�User's�TCB�address*8ŒMOVE.LƒCCBCHB(A5),D4…get�mem.�mapped�I/O�address�stagedŒBSR�QUEVENT�enqueue�the�eventŒRTS˜and�return�to�caller*‰ELSE*DO%ŒMOVE.LƒA6,A0Žstage�users�TCB�address#ŒTR0$.WAKEUP�,�issue�wakeup�to�user*ENDŒENDIŒRTS™return�to�caller‰PAGE=*‚IOHICLR�determines�if�the�interrupt�is�for�this�RIO�module.E*‚If�the�interrupt�is�not�for�this�channel�D2�contains�'8'�on�return.C*‚If�the�interrupt�is�for�this�RIO�module,�the�interrupting�channelI*‚number�is�returned�in�D2‚The�interrupt�in�the�PIA�is�cleared�here�also.**‚Input�parameters:%*’A5:�Points�to�the�I/O�base�address.*‚Output�parameters:(*’D2:�Contains�interrupt�channel�number.* IOHICLR EQU *0ŠMOVE.L�CCBCHB(A5),A0ˆget�I/O�base�address�to�A08ŠBTST.Bƒ#0,PIA1ACR(A0)…is�channel�#0�set�for�interrupts?/ŠBEQ.S„IOHIO01Œbranch�if�not�set�-�check�chan�18ŠBTST.Bƒ#7,PIA1ACR(A0)…set�for�interrupt�-�is�there�one?(ŠBNE†IOHI021Œbranch�on�IRQ�found�on�ch�0$IOHIO01ƒADD�#1,D2“bump�channel�count5ŠBTST.Bƒ#3,PIA1ACR(A0)…is�chan.�1�set�for�interrupts?/ŠBEQ.S„IOHIO02Œbranch�if�not�set�-�check�chan�28ŠBTST.Bƒ#6,PIA1ACR(A0)…set�for�interrupt�-�is�there�one?*ŠBNE.S�IOHI021�branch�on�IRQ�found�on�ch�1$IOHIO02ƒADD�#1,D2“bump�channel�count4ŠBTST.B‚#0,PIA1BCR(A0)†is�chan�2�set�for�interrupts?*ŠBEQ.SƒIOHIO03�branch�if�no�-�check�chan�38ŠBTST.Bƒ#7,PIA1BCR(A0)…set�for�interrupt�-�is�there�one?*ŠBNE.S„IOHI022Œbranch�on�IRQ�found�on�ch�2$IOHIO03ƒADD‚#1,D2’bump�channel�count4ŠBTST.B‚#3,PIA1BCR(A0)†is�chan�3�set�for�interrupts?*ŠBEQ.SƒIOHIO04�branch�if�no�-�check�chan�48ŠBTST.B‚#6,PIA1BCR(A0)†set�for�interrupt�-�is�there�one?*ŠBNE.S‚IOHI022Žbranch�on�IRQ�found�on�ch�3&IOHIO04ƒADD�#1,D2“bump�channel�counter4ŠBTST.Bƒ#0,PIA2ACR(A0)…is�chan�4�set�for�interrupts?*ŠBEQ.S„IOHIO05Œbranch�if�no�-�check�chan�58ŠBTST.Bƒ#7,PIA2ACR(A0)…set�for�interrupt�-�is�there�one?*ŠBNE.S�IOHI023�branch�on�IRQ�found�on�ch�4&IOHIO05ƒADD�#1,D2“bump�channel�counter4ŠBTST.B‚#3,PIA2ACR(A0)†is�chan�5�set�for�interrupts?-ŠBEQ.SƒIOHIO06�branch�if�no�-�go�check�chan�68ŠBTST.B‚#6,PIA2ACR(A0)†set�for�interrupt�-�is�there�one?*ŠBNE.S�IOHI023�branch�on�IRQ�found‚on�ch�5&IOHIO06ƒADD�#1,D2“bump�channel�counter4ŠBTST.B‚#0,PIA2BCR(A0)†is�chan�6�set�for�interrupts?-ŠBEQ.S„IOHIO07Œbranch�if�no�-�go�check�chan�78ŠBTST.B‚#7,PIA2BCR(A0)†set�for�interrupt�-�is�there�one?*ŠBNE.S�IOHI024�branch�on�IRQ�found‚on�ch�6&IOHIO07ƒADD�#1,D2“bump�channel�counter4ŠBTST.B‚#3,PIA2BCR(A0)†is�chan�7�set�for�interrupts?2ŠBEQ.SƒIOHIONO�branch�if�no�-this�inter�not�for�me8ŠBTST.B‚#6,PIA2BCR(A0)†set�for�interrupt�-�is�there�one?*ŠBNE.S�IOHI024�branch�on�IRQ�found‚on�ch�77IOHIONOƒADD�#1,D2“set�chan�#�=�8�=�interrupt�not�for�me ŠRTS™return�to�interrupt�handler5IOHI021ƒTST.B„PIA1ADR(A0)ˆreading�data�reg�clears�IRQŠRTS™and�return-IOHI022ƒTST.BƒPIA1BDR(A0)‰clear�the�interruptŠRTS™and�return(IOHI023ƒTST.BƒPIA2ADR(A0)‰clear�IRQ�flagŠRTS™and�return(IOHI024ƒTST.BƒPIA2BDR(A0)‰clear�IRQ�flag‰RTSšand�return‹PAGE'*‹DEBOUNCE�-�interrupt�debounce�routine3*‹Control�returns�here�when�the�periodic�activation*‹request�time�expires.*ƒInput�parameters:**’D1:�CCB�address�+�channel�#�(in�ls�byte)* DEBOUNCE:‰PUSHALL�save�all�registers*F*‚IF�(((channel�config�=�rising�edge�IRQ)�AND�(channel�state�=�up))�ORH*†((channel�config�=�falling�edge�IRQ)�AND�(channel�state�=�down)))�THEN*0*…Compute�offset�for�t  his�channel�in�the�RIOTBL:*5‰MOVE.L„#$0C010000,D2‡setup�data�fileds�for�NOTIFYUSR!‰CLR.L…D3’clear�working�registers ‰CLR.L…D4’. ‰CLR.L…D6’.%‰MOVE.B„D1,D4�extract�channel�#�to�D46‰MOVE.B„D4,D2�complete�stage�of�chan�data�to�NOTIFYUSR*‰MOVE.B„D4,D3�save�copy�of�channel�#�in�D35‰MULU†#6,D4�point�to�data�field�for�channel�in�RIOTBL7‰ADD‡#RIONTRY+RIOCNIF,D4�add�offset�to�1st�channel�data*'*ˆGet�channel�I/O�address�base�from�CCB*'‰AND‡#$FFFFFF00,D1‡clear�ls�byte�in�CCB#‰MOVE.L„D1,A5�put�CCB�address�on�A5*‰MOVE.L„CCBCHB(A5),A1‡get�I/O�base�address*+*ˆFind�RIOTBL�data�section�for�this�channel*+‰MOVE.L„RIOTBL,A2‹get�address�of�the�RIOTBL ‰CLR.L…D70‰MOVE.L„CCBMNEM(A5),D0†get�channel�name�from�CCB1‰MOVE.B„RIONMAX(A2),D6†get�max�number�of�RIOTBL's LOOP…SET‡*.‰MOVE.L„RIOID(A2),D5ˆget�channel�name�from�CCB%‰CMP.L…D5,D0�channel�name�=�CCB�name? ‰BEQ.S…FOUND13‰ADD.W…RIOOFST,A2Šbump�to�next�RIOID�(channel�name)!‰SUB‡#1,D6�decrement�loop�counter*‰BEQ.S…DBERR�err�if�channel�name�not�found ‰BRA�LOOPFOUND1:/‰MOVE.L„RIOTCB(A2,D4),A6†get�user's�TCB�address3‰BTST†#2,RIOCNIF+1(A2,D4)ƒconfig�=�rising�edge�IRQ? ‰IF…‡THEN*%* DO if set for rising edge interrupt*-‰BTST†D3,PIA1ADR(A1)†channel�status�=�hi�now? �IF‚ƒTHEN*9*‰DO‚notify�user�if�still�on�rising�edge�-�good�interrupt*ŒPUSHALL”save�all�regsŒBSR„NOTIFYUSRŒPOPALL•restor�all�regs**‰END„of�interrupt�on�rising�edge�sequenceˆENDIˆELSE*?*„Else�the�channel�configuration�is�for�falling�edge�interrupt.!*†DO‚see�if�still�on�falling�edge*-‰BTST†D3,PIA1ADR(A1)†channel�status�=�lo�now? †IF‚ƒTHEN*5*†Channel�status�=�lo‚-�notify�user�of�good�interrupt*†DO‰PUSHALL‰BSR�NOTIFYUSR‰POPALL"*†END‚of�falling�edge�IRQ�sequence‡ENDI**‚ENDƒof�debounce�sequence*ƒENDI*"*ˆEnable�IRQ�on�debounced�channel:***BEGIN�stage�parameters�for�call�to�DOENBL*%‰AND.L…#$000000FF,D2‡select�channel�#&‰MOVE.L„A2,A4�get�RIOTBL�address�to�A4)‰CLR.L…D1’set�debounce�data�field�to�null.‰BSR�DOENBL”invoke�routine�to�enable�interrupt*END*/DBERR�EQU�*‚debounce�err;�riotbl�name�not�found+‰POPALLŽrestore�all�registers�before�return‰RTE›return�to�O.S.‰PAGE*H*‚QUEVENT‚enqueue's�event�to�driving�task�using�data�staged�in�registers *‹as�follows:**‹A6�=�user's�TCB�address&*‹D2�=�$0C01�*‹D3�=�RIOID‚(module�name)*‹D4�=�mem�mapped�I/O�address** QUEVENT EQU *‹PUSHALL”push�all�regs"‹MOVE.L…A6,A0Žstage�user's�address ‹TR0$.QEVNTI)‹BRA.SƒQUEVNTOKŒgood�return�for�que�event'‹BRA.SƒQUEVNTERŒbad�return�from�queventQUEVNTOK EQU *‹POPALL•restore�all�regs‹RTS QUEVNTER:(‹BRA�QUEVNTOK�put�a�break�here�for�debug*‰ENDNNNN  NFTRIO…IDNTƒ1,0�RIO�subroutines**‰FORTRAN�callable�subroutines*‰for�RIO�driver�calls*$*‰CALL�RIOCMD(rio_id,param_blk_addr)*‰where�RIOCMD�may�be:*)*‰CALL�RIOPEN(rio_id,param_blk_addr)…open**‰CALL�RIOCLS(rio_id,param_blk_addr)…close3*‰CALL�RIOOUT(rio_id,param_blk_addr)…output�latched/*‰CALL�RIOOFF(rio_id,param_blk_addr)…output�off+*‰CALL�RIOSTA(rio_id,param_blk_addr)…status6*‰CALL�RIOENB(rio_id,param_blk_addr)„enable�interrupts7*‰CALL�RIODSB(rio_id,param_blk_addr)„disable�interrupts2*‰CALL�RIOPLS(rio_id,param_blk_addr)„output�pulsed*,*‰All�arguments�for�the�calls�are�identical.7*‰The�contents�of�the�param_blk�for�each�call�is�unique*‰to�the�call.*6*‰All�the�command�subroutines�call�a�common�subroutine3*‰RIOSET�to�build�the�initiate�I/O�parameter�block.**‰STACK�FOR�ALL�CALLS:*7*‰deepest�stack:�(stack�address�stays�at�RIOSET�return)0*˜command�codeƒ2�bytes�(initiate�I/O�param.�blk) *˜n/aŒ2�bytes*˜rio_id‰4�bytes *˜n/aŒ4�bytes *˜n/aŒ4�bytes *˜n/aŒ4�bytes,*˜command�addrƒ4�bytes�(rio�command�address)**˜command�lng„2�bytes�(rio�command�length)-*˜RIOSET�return‚4�bytes�deepest�stack�address *˜A3�4�bytes *˜A2�4�bytes *˜A1�4�bytes *˜D0�4�bytes*‰entry�stack:ƒreturn‰4�bytes*˜^param_blk_adr�4�bytes*˜^rio-idˆ4�bytes* ŠSECTION�9!ŠXDEFƒRIOPEN,RIOCLS,RIOOUT,RIOOFF!ŠXDEFƒRIOSTA,RIOENB,RIODSB,RIOPLS*$*‰CALL�RIOPEN(rio_id,param_blk_addr)*‰open�and�configure�channels*1RIOPEN„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers3ŠBSR„RIOSET�set-up�the�initiate�I/O�parameter�block)ŠMOVE.L�#1,(A2)Œset�the�open�command�codeRIOPN00ƒCLR.L‚D0‘clear�for�use'ŠMOVE.W�4(A2),D0‹get�number�of�channelsŠASL.L‚#2,D0Žmultiply�by�4.RIOPN05ƒADD.L‚#6,D0Žadd�in�the�6�byte�overhead-RIOPN10ƒMOVE.W�D0,(A1)Œset�the�command�length-ŠMOVE.L�A3,A0ŽTRAP�#1�parameter�block�address#ŠMOVE.L�#60,D0�CMR�directive�numberŠTRAPƒ#1‘call�RMS68K'ŠMOVE.W�D0,(A2)Œset�the�returned�status)ŠMOVEM.L�(A7)+,D0/A1-A3„restore�registers!ŠMOVE.L�(A7)+,A0‹put�return�in�A09AB8J ŠLEA„8(A7),A7‹clean�up�the�stackŠJMP„(A0)�return�to�user*$*‰CALL�RIOCLS(rio_id,param_blk_addr)"*‰close�all�channels�for�this�user*1RIOCLS„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block*ŠMOVE.L�#2,(A2)Œset�the�close�command�code&ŠMOVE.W�#4,D0ŽRIO�close�command�lengthŠBRA„RIOPN10Œgo�do�the�CMR�call*$*‰CALL�RIOOUT(rio_id,param_blk_addr)'*‰activate�output�on�requested�channels*1RIOOUT„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block+ŠMOVE.L�#3,(A2)Œset�the�output�command�code*RIOUT10ƒMOVE.Wƒ#6,D0Œset�up�command�lengthŠBRA„RIOPN10Œgo�do�the�CMR�call*$*‰CALL�RIOOFF(rio_id,param_blk_addr))*‰deactivate�output�on�specified�channels*1RIOOFF„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block/ŠMOVE.L�#4,(A2)Œset�the�output�off�command�code4ŠBRA„RIOUT10Œgo�set�command�length�&�do�the�CMR�call*$*‰CALL�RIOSTA(rio_id,param_blk_addr))*‰read�input�status�on�specified�channels*1RIOSTA„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block+ŠMOVE.L�#5,(A2)Œset�the�status�command�code4ŠBRA„RIOUT10Œgo�set�command�length�&�do�the�CMR�call*$*‰CALL�RIOENB(rio_id,param_blk_addr).*‰enable�interrpts�on�specified�input�channels*1RIOENB„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block+ŠMOVE.L�#6,(A2)Œset�the�enable�command�code  4ŠBRA„RIOUT10Œgo�set�command�length�&�do�the�CMR�call*$*‰CALL�RIODSB(rio_id,param_blk_addr)0*‰disable�interrupts�on�specified�input�channels*1RIODSB„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block,ŠMOVE.L�#7,(A2)Œset�the�disable�command�code4ŠBRA„RIOUT10Œgo�set�command�length�&�do�the�CMR�call*$*‰CALL�RIOPLS(rio_id,param_blk_addr)>*‰activate�output�for�x#�of�milliseconds�on�specified�channels*1RIOPLS„MOVEM.L�D0/A1-A3,-(A7)„save�some�registers5ŠBSR.S‚RIOSET�set-up�the�initiate�I/O�parameter�block2ŠMOVE.L�#8,(A2)Œset�the�pulsed�output�command�codeŠCLR.L‚D0‘clear�for�use,ŠMOVE.W�4(A2),D0‹get�specified�#�of�channelsŠASL.L‚#2,D0Žmultiply�by�6ŠADD.W‚4(A2),D04ŠBRA„RIOPN05Œgo�set�command�length�&�do�the�CMR�callŠPAGE*4*‰RIOSET�set�up�the�CMR�initiate�I/O�parameter�block,*‰returns:ƒA1=address�for�RIO�command�length(*”A2=RIO�command�parameter�block�address)*”A3=initiate�I/O�parameter�block�address*(RIOSET„CLR.W‚-2(A7)�clear�command�length-ŠLEA„-2(A7),A1Šsave�address�of�command�length$ŠMOVE.L�24(A7),A0Šget�param_blk_addr%ŠMOVE.L�A0,-6(A7)Šsave�param_blk_addr,ŠMOVE.L�A0,A2Žsave�param_blk_addr�for�returnŠCLR.L‚-10(A7)Œnot�usedŠCLR.L‚-14(A7)Œnot�usedŠCLR.L‚-18(A7)Œnot�usedŠMOVE.L�28(A7),A0Šget�^rio_idŠMOVE.L�(A0),-22(A7)‡get�rio_idŠCLR.W‚-24(A7)Œnot�used0ŠMOVE.W�#$0700,-26(A7)…initiate�I/O�command�code4ŠLEA„-26(A7),A3‰initiate�I/O�parameter�block�addressŠRTS—return�to�callerŠENDNNN'M600DRV TEST600 AF^^  TEST600 LFgg  TEST600 LOh  TEST600 SA||J‚  =/*=/*†M600DRV.TEST600.AF=/*,=/*†TEST600�test�program�assembly�chain�file=/*-=/*†Default�argument�01�is�M600DRV.TEST600.LS=/*=/IFC \1ƒ=ARG�M600DRV.TEST600.LS=/ENDIF=/*4=ASM M600DRV.TEST600.SA,M600DRV.TEST600.RO,\1;RZ=100=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=END  NNNNNNV=/*=/*†M600DRV.TEST600.LF=/*G=/*†This�chain�file�will�generate�the�TEST600�test�program�load�module.=/*5=/*†The�command�line�will�accept�arguments�as�follows=/*7=/*‹Argument�01ˆ\1�=�Output�file�link�listing�or�device=/*D=/*†The�following�shows�the�link�chain�sequence.‚In�this�example�theF=/*†printer�was�chosen�as�Argument�1,�however,�the�user�could�if�he�so2=/*†desired�have�requested�an�output�listing�file.=/*!=/*�=CHAIN�M600DRV.TEST600.LF�#PR=/*-=/*†Default�argument�01�is�M600DRV.TEST600.LL=/*=/IFC \1ƒ=ARG�M600DRV.TEST600.LL=/ENDIF=/*"=LINK ,M600DRV.TEST600.LO,\1;HAMIXSEG SEG0:0,1,8,14 $000000ATTRIBUTES D PINPUT M600DRV.TEST600.ROLIB 0.&.UTILIB.ROEND=/*=ENDNNNNN_  TEST˜ÿÿÿÿÿ€SEG0 ÿÿÿÿ ÿÿÿÿÿDAC1 MVME600 & MVME605 Driver Test Program  Number of the channel to convert > Value to be converted ($000 - $FFF) > Entered value = = Result value. <<< Starting conversions >>> <<< Conversions done >>> *** OPEN ABORTED D/A *** -- *** CONVERSION ABORTED D/A *** -- *** CLOSE ABORTED D/A *** -- *** OPEN ABORTED A/D *** -- *** CONVERSION ABORTED A/D *** -- *** CLOSE ABORTED A/D *** -- Error code returned in D0 = Oúý2Iúüb :ü^D€Aô)HÌ)H¬Ñü)HÐ)HÄAúþ)HRAúþ0)HVAúýtNBAúþ$)HRAúþD)HVAúý^NBAúüæ)HnAúüæ)HrAúýdNBaNAúüÌa„ €m €o`¶9@ 9@¨9@¶9@ÀaÀ9|ª zü�2<0Á0Ã9CDAúý2CúýJ!|DAC1!I1|p*‚on�the�VME600.‚You�must�use�the�SAME�channel�on�both�boards.*ŠPAGE ,*£ASCVAL,�BHLCVT,�and�CVT2�are�commonly�used**£functions�which�are�modules�in�a�library(*£file�called�UTILIB.RO.‚A�call�to�these'*£functions�are�included�in�this�source)*£program,�which�is�provided�with�an�XREF&*£declaration.‚This�also�requires�that'*£UTILIB.RO�be�available�to�the�linkage$*£editor�during�the�linking�process.%*£See�TEST605.LF�for�link�chain�file. -ŠXREFƒASCVAL�Converts�ASCII�to�a�binary�value$*£This�routine�will�convert�an�ASCII,*£character�string�representing�a�decimal�or,*£hexidecimal�value�to�the�equivalent�binary,*£value.‚If�a�dollar�sign�($)�is�encountered&*£hexidecimal�conversion�is�performed;,*£otherwise�decimal�conversion�is�performed.+*£An�empty�character�string�field�passed�totB}:…J�>•I�A¥B­IµM½,*£this�function�in�A0�produces�a�zero�binary'*£value.‚Conversion�terminates�when�the)*£first�invalid�character�is�encountered.'*£ENTRY:‚A0�-�Starting�address�of�ASCII*°character�string�to�convert#*£EXIT�:‚D1�-�Character�that�caused *°termination%*«D2�-�Class�code�of�terminating�char"*«D3�-�Binary�result�of�conversion*«A0�-�Address�of�the�character *°following�the�terminating�char 8ŠXREFƒBHLCVT�Converts�4-byte�binary�value�to�ASCII�digit)*£This�routine�will�convert�a�long�binary-*£word�value�to�a�hexadecimal�value�expressed)*£as�an�8�character�ASCII�string.‚Leading*£zeros�are�suppressed.,*£ENTRY:‚D0.L�-�Binary�value�to�be�converted(*£EXIT�:‚D2.L�-�Four�high�order�bytes�of*²converted�value *«D3.L�-�Four�low�order�bytes�of*²converted�value 6ŠXREFƒCVT2�Converts�two�ASCII�decimal�digits�to�binary-*£This�routine�will�convert�two�ASCII�decimal(*£digits�to�the�equivalent�binary�value.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary**£value.‚Conversion�terminates�when�a�non-*£decimal�digit�is�encountered)*£ENTRY:‚A0�-�Address�of�most�significant*°ASCII�decimal�digit)*£EXIT�:‚D0�-�Binary�result�of�conversion!*«A0�-�Address�of�the�terminating *°character ŠPAGE:BUFSIZEƒEQU„$100�This�label�defines�the�value�for�the�size*£of�the�conversion�tableS. ŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N****************************************************************************** ŠSECTION�DATA =D_ABUF„DS.BƒBUFSIZEŒThis�is�the�buffer�area�that�will�contain**£the�delay�and�the�conversion�value�to�be *£converted. =A_DBUF„DS.BƒBUFSIZEŒThis�is�the�buffer�area�that�will�contain(*£the�converted�analog�to�digital�value. $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. :BUFOFSTƒDC.LƒPBA-D_ABUF‰This�is�the�offset�from�PBA�to�the'*£conversion�table�so�that�the�relative**£address�can�be�found�to�make�the�program*£relocatable. 9ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�VME605�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. 9BUFADR_DAƒDS.Lƒ1�This�is�the�storage�area�for�the�address-*£of�the�conversion�table�for�the�D/A�driver. 9BUFADR_ADƒDS.Lƒ1�This�is�the�storage�area�for�the�address-*£of�the�conversion�table�for�the�A/D�driver. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was. 6NUMBER„DS.Lƒ2’Save�area�for�the�ASCII�value�of�STATUS. 8INPUT_VALUE‚DS.W‚1�Entered�digital�value�to�be�converted**£to�analog�(D/A)�is�stored�here�in�binary**£form�for�later�comparison�with�the�value*£read�off�the�A/D.ŠPAGE N**************************  *****************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠDC.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address*#*‚CMR�Initiate�I/O�parameter�block:CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�Unused/ŠDC.Lƒ'DAC1'�Channel�name�(Dynamically�changed)ŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�blockŠPAGE*2*‚OPEN�command�parameter�block�for�the�D/A�driver:*OPEN_DAƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)4OLEN_DAƒEQU„*-OPEN_DAŠLength�of�OPEN�parameter�block*5*‚CONVERT�command�parameter�block�for�the�D/A�driver:*CONV_DAƒDC.Wƒ0’Returned�status�from�driver"ŠDC.WƒCONVERTŒConvert�command�code ŠDC.Wƒ1’#�of�channels�to�convert0ŠDC.Wƒ0’Channel�to�convert�(Dynamically�changed)ŠDC.Wƒ1’#�of�conversions%ŠDC.Lƒ0’Buffer�address�of�conversionsŠDC.Wƒ01‘Wake�up�when�done7CLEN_DAƒEQU„*-CONV_DAŠLength�of�CONVERT�parameter�block*2*‚OPEN�command�parameter�block�for�the�A/D�driver:*OPEN_ADƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�code-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)4OLEN_ADƒEQU„*-OPEN_ADŠLength�of�OPEN�parameter�block*5*‚CONVERT�command�parameter�block�for�the�A/D�driver:*CONV_ADƒDC.Wƒ0’Returned�status�from�driver"ŠDC.WƒCONVERTŒConvert�command�code ŠDC.Wƒ1’#�of�channels�to�convert )ŠDC.Wƒ0’Command�ID�(return�when�complete)0ŠDC.Wƒ0’Channel�to�convert�(Dynamically�changed) ŠDC.Wƒ00‘Channel�completion�code%ŠDC.Lƒ0’Buffer�address�of�conversionsŠDC.Wƒ2’Buffer�size�in�bytesŠDC.Wƒ0’Control�field7CLEN_ADƒEQU„*-CONV_ADŠLength�of�CONVERT�parameter�block*@*‚CLOSE�command�parameter�block�for�the�A/D�and�the�D/A�drivers:)CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLK ŠNEXTWB ŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES CHEAD†DC.BƒCR,LF,LF,'MVME600�&�MVME605�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB1MESS1…DC.Bƒ'…Number�of�the�channel�to�convert‚>�'MESS1E„EQU„*-1ŠNEXTWB4MESS5…DC.Bƒ'‚Value�to�be�converted�($000�-�$FFF)‚>�'MESS5E„EQU„*-1ŠNEXTWBMESS8…DC.Bƒ'Entered�value�=�'MESS8E„EQU„*-1ŠNEXTWB#MESS9…DC.Bƒ'�=�Result�value.',CR,LFMESS9E„EQU„*-1ŠNEXTWB6MESS10„DC.BƒCR,LF,'<<<�Starting�conversions�>>>',CR,LFMESS10EƒEQU„*-1ŠNEXTWB2MESS11„DC.BƒCR,LF,'<<<ƒConversions�doneƒ>>>',CR,LFMESS11EƒEQU„*-1ŠNEXTWB3BADOPN_DA�DC.BƒCR,LF,'***�OPEN�ABORTED�D/A�***�--�'BOPEN_DA‚EQU„*-1ŠNEXTWB9BADCNV_DA�DC.BƒCR,LF,'***�CONVERSION�ABORTED�D/A�***�--�'BCNV_DAƒEQU„*-1ŠNEXTWB4BADCLS_DA�DC.BƒCR,LF,'***�CLOSE�ABORTED�D/A�***�--�'BCLS_DAƒEQU„*-1ŠNEXTWB3BADOPN_AD�DC.BƒCR,LF,'***�OPEN�ABORTED�A/D�***�--�'BOPEN_AD‚EQU„*-1ŠNEXTWB9BADCNV_AD�DC.BƒCR,LF,'***�CONVERSION�ABORTED�A/D�***�--�'BCNV_ADƒEQU„*-1ŠNEXTWB4BADCLS_AD�DC.BƒCR,LF,'***�CLOSE�ABORTED�A/D�***�--�'BCLS_ADƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…  EQU„*-1ŠNEXTWBSPACE…DC.Bƒ'„'SPACE_END�EQU„*-1ŠNEXTWBŠPAGEN*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODE PROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA)?ŠMOVE.L�BUFOFST(PC),D0…D0�=�offset�to�find�the�conversion�tableŠNEG.L‚D0–from�PBA3ŠLEA„(A4,D0.L),A0‡Address�for�D/A�conversion�bufferFŠMOVE.L�A0,BUFADR_DA-PBA(A4)�Save�the�address�of�the�conversion�buffer@ŠMOVE.L�A0,CONV_DA+$A-PBA(A4)�the�physical�address�of�the�buffer3ŠADD.L‚#BUFSIZE,A0ˆAddress�for�A/D�conversion�buferFŠMOVE.L�A0,BUFADR_AD-PBA(A4)�Save�the�address�of�the�conversion�buffer@ŠMOVE.L�A0,CONV_AD+$C-PBA(A4)�the�physical�address�of�the�buffer &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN.ŠOUTPUT�MESS1,MESS1E‡Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.L�D0��#0�OR.L�D0��#3�THEN.S ŒBRA�GETCHANŠENDI@ŠMOVE.W�D0,OPEN_DA+6-PBA(A4)�Channel�number�for�D/A�OPEN„commandCŠMOVE.W�D0,CONV_DA+6-PBA(A4)�Channel�number�for�D/A�CONVERT�command@ŠMOVE.W�D0,OPEN_AD+4-PBA(A4)�Channel�number�for�A/D�OPEN„commandCŠMOVE.W�D0,CONV_AD+8-PBA(A4)�Channel�number�for�A/D�CONVERT�command **‰C�=�Constant�level�waveform*)ŒBSR„GETVAL‹Returns�D3�=�Value�to�convertŒMOVE.W�#1,CONV_DA+8-PBA(A4)@ŒMOVE.L�BUFADR_DA(PC),A0‚Get�the�address�of�the�conversion�tableŒMOVE.W�#0,D1ŒZero�delay%ŒMOVE.W�D1,(A0)+‰D1�=�Delay�value�=�0&ŒMOVE.W�D3,(A0)+‰D3�=�Value�to�convertBŒMOVE.W�D3,INPUT_VALUE-PBA(A4)‚Save�the�user�entered�digital�value%*¢for�later�comparison�with�A/D�valueŒPAGEN*-----------------------------------------------------------------------------**‰Start�the�conversions�here*N*-----------------------------------------------------------------------------**ƒOPEN�THE�D/A�CHANNEL*ŠLEA„CMRBLK(PC),A0ŠLEA„OPEN_DA(PC),A1ŠMOVE.L�#'DAC1',$4(A0)ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_DA,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.1ŠIF��THEN.SŒCMR�returns�a�status�code�in�D0.BŒMOVE.L�D0,STATUS-PBA(A4)/ŒOUTPUT�BADOPN_DA,BOPEN_DA‚***�OPEN�ABORTED�***ŒBRA.L‚SHOW_D0ŠENDI**ƒOPEN�THE�A/D�CHANNEL*ŠLEA„CMRBLK(PC),A0ŠLEA„OPEN_AD(PC),A1ŠMOVE.L�#'AD01',$4(A0)ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_AD,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.1ŠIF��THEN.SŒCMR�returns�a�status�code�in�D0.BŒMOVE.L�D0,STATUS-PBA(A4)/ŒOUTPUT�BADOPN_AD,BOPEN_AD‚***�OPEN�ABORTED�***ŒBRA.L‚SHOW_D0ŠENDI**ƒDO�CONVERSIONS*3ŠOUTPUT�MESS10,MESS10E…<<<ƒStarting�conversionsƒ>>> ŒLEA„CMRBLK(PC),A0ŒLEA„CONV_DA(PC),A1ŒMOVE.L�#'DAC1',$4(A0)ŒMOVE.L�A1,$14(A0)ŒMOVE.W�#CLEN_DA,$18(A0)5ŒMOVE.L�#CMR,D0ŠTell�the�driver�to�do�the�conversionsŒTRAPƒ#1*(*ƒDo�a�wait�until�the�driver�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒMOVE.W�CONV_DA(PC),D01ŒIF��THEN.SŒCMR�returns�a�status�code�in�D0.BŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADCNV_DA,BCNV_DAƒ***�CONVERSION�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI  ŒLEA„CMRBLK(PC),A0ŒLEA„CONV_AD(PC),A1ŒMOVE.L�#'AD01',$4(A0)ŒMOVE.L�A1,$14(A0)ŒMOVE.W�#CLEN_AD,$18(A0)5ŒMOVE.L�#CMR,D0ŠTell�the�driver�to�do�the�conversionsŒTRAPƒ#1*A*‚THE�A/D�DRIVER�WILL�ONLY�RETURN�WHEN�CHANNEL�HAS�BEEN�CONVERTED*ŒMOVE.W�CONV_AD(PC),D01ŒIF��THEN.SŒCMR�returns�a�status�code�in�D0.BŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADCNV_AD,BCNV_ADƒ***�CONVERSION�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 'ŒOUTPUT�MESS8,MESS8E‡'ENTERED�VALUE�=�' ŒCLR.L‚D04ŒMOVE.W�INPUT_VALUE-PBA(A4),D0‚Get�the�entered�valueŒBSR„BHLCVTŽConvert�to�ASCII ŒMOVE.L�D2,NUMBER-PBA(A4)ŒMOVE.L�D3,NUMBER+4-PBA(A4)0ŒOUTPUT�NUMBER,NUMBER+7…Output�the�entered�value0ŒOUTPUT�SPACE,SPACE_END…'„'�(output�some�spaces) 7ŒMOVE.L�BUFADR_AD(PC),A0„Point�to�result�buffer�for�A/D ŒCLR.L‚D0ŒMOVE.W�(A0),D0�Get�the�result"ŒAND.W‚#$0FFF,D0‹Result�is�12�bitsŒBSR„BHLCVTŽConvert�to�ASCIIŒMOVE.L�D2,NUMBER-PBA(A4)ŒMOVE.L�D3,NUMBER+4-PBA(A4)/ŒOUTPUT�NUMBER,NUMBER+7…Output�the�result�value'ŒOUTPUT�MESS9,MESS9Eˆ'�=�result�value.' ŒBRA.S‚EXIT :SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returned'SHOW1_D0‚BSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE ŠBRA.S‚EXIT  CHECKQ3ŠCMP.B‚#'Q',INPUTBUF-PBA(A4)�Do�they�want�to�Quit�? ŠBEQ.S‚EXIT3ŠCMP.B‚#'.',INPUTBUF-PBA(A4)�Do�they�want�to�Quit�? ŠBEQ.S‚EXITŠRTS  EXIT**‚CLOSE�THE�CHANNELS:*ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�#'DAC1',$4(A0)ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)1ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�D/A�channelŠTRAPƒ#1ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)/ŒOUTPUT�BADCLS_DA,BCLS_DAƒ***�CLOSE�ABORTED�***ŠENDI ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�#'AD01',$4(A0)ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)1ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�D/A�channelŠTRAPƒ#1ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)/ŒOUTPUT�BADCLS_AD,BCLS_ADƒ***�CLOSE�ABORTED�***ŠENDI /ŠOUTPUT�MESS11,MESS11E…<<<ƒConversions�doneƒ>>> "ŠMOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1 *=*‚Routine�to�get�the�digital�value�to�be�converted�to�analog:*GETVAL8ŠOUTPUT�MESS5,MESS5E‡Value�to�be�converted�($000�-�$FFF)ŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0!ŠBSR„ASCVAL‹D3�=�Value�to�convertŠRTS ŠEND„PROGSTRTNNNNN'M605DRV TEST605 AFÑÑ  TEST605 LFÚÚ  TEST605 LOÛ‰  TEST605 SAmmWû   =/*=/*†M605DRV.TEST605.AF=/*,=/*†TEST605�test�program�assembly�chain�file=/*-=/*†Default�argument�01�is�M605DRV.TEST605.LS=/*=/IFC \1ƒ=ARG�M605DRV.TEST605.LS=/ENDIF=/*4=ASM M605DRV.TEST605.SA,M605DRV.TEST605.RO,\1;RZ=100=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNNÉ=/*=/*†M605DRV.TEST605.LF=/*G=/*†This�chain�file�will�generate�the�TEST605�test�program�load�module.=/*5=/*†The�command�line�will�accept�arguments�as�follows=/*7=/*‹Argument�01ˆ\1�=�Output�file�link�listing�or�device=/*D=/*†The�following�shows�the�link�chain�sequence.‚In�this�example�theF=/*†printer�was�chosen�as�Argument�1,�however,�the�user�could�if�he�so2=/*†desired�have�requested�an�output�listing�file.=/*!=/*�=CHAIN�M605DRV.TEST605.LF�#PR=/*-=/*†Default�argument�01�is�M605DRV.TEST605.LL=/*=/IFC \1ƒ=ARG�M605DRV.TEST605.LL=/ENDIF=/*"=LINK ,M605DRV.TEST605.LO,\1;HAMIXSEG SEG0:0,1,8,14 $000000ATTRIBUTES D PINPUT M605DRV.TEST605.ROLIB 0.&.UTILIB.ROEND=/*=ENDNNN NNÒTESTƒˆÿÿÿÿÿ€SEG0‰ÿÿÿÿˆÿÿÿÿÿ        €DAC1 MVME605 Driver Test Program Number of the channel to convert  > Delay between conversions > (C)onstant level (S)awtooth wave > Value to be converted ($000 - $FFF) > Number of times to do conversions > Increment for conversion value > <<< Starting conversions >>> <<< Conversions done >>> *** OPEN ABORTED *** -- *** CONVERSION ABORTED *** -- *** CLOSE ABORTED *** -- Error code returned in D0 = Oúý>Iúür :ý D€Aô)HÈ)H®Aúþ)HTAúþ,)HXAúý”NBAúþ )HTAúþ@)HXAúý~NBAúüü)HpAúüü)HtAúý„NBaâAúüâaâ €m €?o`¶9@¢9@ªAúþ")HTAúþB)HXAúý,NBAúüª)HpAúüª)HtAúý2NBa�:ü� Of,$zü‚"Ja’ ƒÿÿg 2ÃaÔ2Ã`ê“Ê €ü9@¬`Ò Cf"af9C0a®9|¬ zü>2:ü¢0Á0Ã`ª Sfža<9C0Aúþ)HTAúþ")HXAúüŽNBAúü )HpAúü )HtAúü”NBaòAúûòa– �gÀ ƒm ƒÿo`®9CF0:ü0B� zûÂ"H4:ü:2À2ÁÒB Aÿoô Aÿo’B2À2Á’B Alô“È €ü9@¬``þÌAúý@)HTAúý`)HXAúûöNBAúût)HpAúût)HtAúûüNBaZAúûZaþ Ag ƒm ƒÿÿo`°)CBAúûêCúü!I1|pAúüä)HTAúü÷)HXAúú²NBAúúž)HTAúú�)HXAúúœNBAúüÔ)HTAúüÍ)HXAúú†NB` ,QÌg ,.ÌgNupNAAúû$)HTAúûD)HXAúúXNBAúùÖ)HpAúùÖ)HtAúú^NBa¼aºAúù¼a`J�gÄ ƒm ƒÿÿo`²NuAúû()HTAúûH)HXAúúNBAúù†)HpAúù†)HtAúúNBaÿlaÿhAúùha NuRˆ  gøHçIúîB„BƒÁa;*�This�question�asks�which�channel�you�would�like�to�do�the>*�conversions�on.‚The�answer�must�be�(0�-�63),�decimal,�or�the/*�test�program�will�ask�for�a�different�answer.*'*‰B.‚(C)onstant�level‚(S)awtooth�wave„>?*�This�question�asks�for�the�type�of�waveform�you�would�like�to>*�test�for.‚An�answer�of�"C"�will�then�ask�you�question�#C�and?*�then�question�#D.‚An�answer�of�"S"�will�then�ask�you�question8*�#C�and�then�question�#E.‚An�answer�of�"O"�will�ask�you?*�question�#C�and�then�question�#D�until�you�answer�question�#C>*�with�an�$FFFF�to�exit.‚The�"O"�option�is�used�to�create�your6*�own�waveform.‚This�will�enable�the�user�to�creat‚the<*�conversion�table�with�his�own�delays�and�conversion�values* *‰C.‚Delay�between�conversionsŒ>;*�This�question�asks�for�the�delay�of�the�conversion�value.?*�This�value�can�be�from�$0�to�$FFFF�with�$0�being�no�delay�and<*�$FFFF�being�the�longest�delay.‚Each�delay�is�approximately*�1�(one)�millisecond�of�delay.***‰D.‚Value�to�be�converted�($000�-�$FFF)‚>e6nAv:~;†LŽC–TžF¦D®E¶^=*�This�question�asks�for�the�value�to�be�converted.‚The�value<*�can�be�from�$000�to�$FFF�with�$000�being�the�most�negative;*�value�and�$FFF�being�the�most�positive�value.‚Question�#F*�follows�this�question.*"*�ValueŠ5�volt�scaleŠ10�volt�scale* equivalent�equivalent4*�--------------------------------------------------*�$FFFŒ+5.0�volts�+10.0�volts*�$C00Œ+2.5“+5.0*�$800�0.0”0.0*�$400Œ-2.5“-5.0*�$000Œ-5.0“-10.0*%*‰E.‚Increment�for�conversion�value‡>>*�This�question�asks�for�the�increment�value�that�will�be�used;*�to�calculate�the�sawtooth�waveform�with.‚This�is�how�much@*�the�sawtooth�waveform�will�be�incremented�for�each�conversion.<*�This�value�can�be�from�$000�to�$FFF.‚Anything�outside�this>*�range�will�not�be�accepted�and�the�test�program�will�ask�for*�a�different�answer.*(*‰F.‚Number�of�times�to�do�conversions„>?*�This�question�asks�for�the�amount�of�times�to�run�through�the*�conversion�table. ŠPAGE *‚Examples:*B*‰The�following�example�should�make�a�constant�level�at�+5.0�volts:*‰if�the�input�voltage�on�the�VME605�board�is�+10.0�volts.**‰MVME605�Driver�Test�Program**&*ŒNumber�of�the�channel�to�convert‚>�0&*‹(C)onstant�level‚(S)awtooth�wave‚>�C*“Delay�between�conversions‚>�1,*‰Value�to�be�converted�($000�-�$FFF)‚>�$C00'*‹Number�of�times�to�do�conversions‚>�1    E*‰The�following�example�will�create�a�sawtooth�wave�that�will�be�from-*‰the�minimum�voltage�to�the�maximum�voltage.**‰MVME605�Driver�Test�Program**&*ŒNumber�of�the�channel�to�convert‚>�0&*‹(C)onstant�level‚(S)awtooth�wave‚>�S*“Delay�between�conversions‚>�0'*ŽIncrement�for�conversion�value‚>�$100(*‹Number�of�times�to�do�conversions‚>�50  ŠPAGE,*£ASCVAL,�BHLCVT,�and�CVT2�are�commonly�used**£functions�which�are�modules�in�a�library(*£file�called�UTILIB.RO.‚A�call�to�these'*£functions�are�included�in�this�source)*£program,�which�is�provided�with�an�XREF&*£declaration.‚This�also�requires�that'*£UTILIB.RO�be�available�to�the�linkage$*£editor�during�the�linking�process.%*£See�TEST605.LF�for�link�chain�file. -ŠXREFƒASCVAL�Converts�ASCII�to�a�binary�value$*£This�routine�will�convert�an�ASCII,*£character�string�representing�a�decimal�or,*£hexidecimal�value�to�the�equivalent�binary,*£value.‚If�a�dollar�sign�($)�is�encountered&*£hexidecimal�conversion�is�performed;,*£otherwise�decimal�conversion�is�performed.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces �a�zero�binary'*£value.‚Conversion�terminates�when�the)*£first�invalid�character�is�encountered.'*£ENTRY:‚A0�-�Starting�address�of�ASCII*°character�string�to�convert#*£EXIT�:‚D1�-�Character�that�caused *°termination%*«D2�-�Class�code�of�terminating�char"*«D3�-�Binary�result�of�conversion*«A0�-�Address�of�the�character *°following�the�terminating�char 8ŠXREFƒBHLCVT�Converts�4-byte�binary�value�to�ASCII�digit)*£This�routine�will�convert�a�long�binary-*£word�value�to�a�hexadecimal�value�expressed)*£as�an�8�character�ASCII�string.‚Leading*£zeros�are�suppressed.,*£ENTRY:‚D0.L�-�Binary�value�to�be�converted(*£EXIT�:‚D2.L�-�Four�high�order�bytes�of*²converted�value *«D3.L�-�Four�low�order�bytes�of*²converted�value   6ŠXREFƒCVT2�Converts�two�ASCII�decimal�digits�to�binary-*£This�routine�will�convert�two�ASCII�decimal(*£digits�to�the�equivalent�binary�value.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary**£value.‚Conversion�terminates�when�a�non-*£decimal�digit�is�encountered)*£ENTRY:‚A0�-�Address�of�most�significant*°ASCII�decimal�digit)*£EXIT�:‚D0�-�Binary�result�of�conversion!*«A0�-�Address�of�the�terminating *°characterŠPAGE ;BUFSIZEƒEQU„$8000ŽThis�label�defines�the�value�for�the�size$*£of�the�delay�and�conversion�table. 6CLOSE…EQU„2’This�label�defines�the�code�value�that�the+*£D/A�driver�recognizes�as�the�command�code*£for�a�CLOSE�command. @CLSIZE„EQU„BUFSIZE/4ŠThis�label�defines�the�value�for�performing,*£a�loop�to�fill�the�conversion�table�with�a)*£certain�delay�and�conversion�value.‚The-*£size�is�BUFSIZE/4�because�there�are�2�words,*£per�entry,�1�word�for�delay�and�1�word�for-*£the�conversion�value,�and�there�are�2�bytes *£per�word. 4CMR‡EQU„60‘This�label�defines�the�code�value�that�we,*£must�use�to�tell�the�operating�system�that+*£we�want�to�invoke�CMR,�the�RMS68K�Channel*£Management�Routine. /CODE†EQU„8’This�label�defines�the�number�of�the%*£program�section�that�contains�code.-*£Section�8�is�a�relatively�arbitrary�section(*£but�it�is�the�section�where�the�system(*£expects�(by�default)�to�see�code�for�a*£program,�(read�only). 8CONVERTƒEQU„3’This�label�defines�the�code�value�that�the+*£D/A�driver�recognizes�as�the�command�code*£for�a�CONVERT�command. 5CRˆEQU„$0D�This�label�defines�the�code�for�a�carriage*£return 1CRT‡EQU„6’This�label�defines�the�value�for�the�LU*£number�for�the�CRT. 4DATA†EQU„0’This�label�defines�the�number�of�the�data**£section�that�contains�data.‚Section�0�is+*£a�relatively�arbitrary�section,�but�it�is-*£the�section�where�the�system�expects�to�see"*£code�for�data�(read/write�area). 6KEYBOARD‚EQU„5’This�label�defines�the�value�for�the�LU*£number�for�the�keyboard. 6LFˆEQU„$0A�This�label�defines�the�code�for�a�line�feed 3MESSAGES‚EQU„1’This�label�defines�the�number�of�the,*£messages�section�that�will�contain�all�the%*£messages.‚Section�1�is�a�relatively*£arbitrary�section. 5OPEN†EQU„1’This�label�defines�the�code�value�that�the+*£D/A�driver�recognizes�as�the�command�code*£for�an�OPEN�command. 3READ†EQU„1’This�label�defines�the�code�value�of�the&*£IOS�request�code�for�a�READ�command. ŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N****************************************************************************** ŠSECTION�DATA =D_ABUF„DS.BƒBUFSIZEŒThis�is�the�buffer�area�that�will�contain**£the�delay�and�the�conversion�value�to�be *£converted. $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. 9ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�VME605�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. 8BUFFADDR‚DS.Lƒ1’This�is�the�storage�area�for�the�address,*£of�the�conversion�table.‚This�address�will-*£be�figured�at�execution�time�so�the�program*£will�be�relocatable. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 6DELAYVAL‚DS.Wƒ1’This�is�the�storage�area�for�the�delay(*£that�is�entered�for�the�delay�for�each *£conversion. :BUFOFSTƒDC.LƒPBA-D_ABUF‰This�is�the�offset�from�PBA�to�the'*£conversion�table�so�that�the�relative**£address�can�be�found�to�make�the�program*£relocatable. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was.  NUMBER„DS.Lƒ2 1NUMT†DS.Lƒ1’This�is�the�storage�for�the�number�of&*£conversions�to�perform.‚This�will�be,*£changed�dynamically�after�the�question�has*£been�answered. 5INC‡DS.Wƒ1’This�is�the�storage�area�for�the�increment**£that�will�be�used�to�figure�the�sawtooth *£waveform. ŠPAGE N*******************************************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠDC.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address  CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�UnusedŠDC.Lƒ'DAC1' �Channel�nameŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�block   *OPENBLKƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)4OPENLENƒEQU„*-OPENBLKŠLength�of�OPEN�parameter�block   *CONVBLKƒDC.Wƒ0’Returned�status�from�driver"ŠDC.WƒCONVERTŒConvert�command�code ŠDC.Wƒ1’#�of�channels�to�convert0ŠDC.Wƒ0’Channel�to�convert�(Dynamically�changed).ŠDC.Wƒ0’#�of�conversions�(Dynamically�changed)%ŠDC.Lƒ0’Buffer�address�of�conversionsŠDC.Wƒ01‘Wake�up�when�done7CONVLENƒEQU„*-CONVBLKŠLength�of�CONVERT�parameter�block   )CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLK ŠNEXTWB ŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES 9HEAD†DC.BƒCR,LF,LF,'MVME605�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB1MESS1…DC.Bƒ'…Number�of�the�channel�to�convert‚>�'MESS1E„EQU„*-1ŠNEXTWB*MESS3…DC.Bƒ'ŒDelay�between�conversions‚>�'MESS3E„EQU„*-1ŠNEXTWB1MESS4…DC.Bƒ'„(C)onstant�level‚(S)awtooth�wave‚>�'MESS4E„EQU„*-1ŠNEXTWB4MESS5…DC.Bƒ'‚Value�to�be�converted�($000�-�$FFF)‚>�'MESS5E„EQU„*-1ŠNEXTWB2MESS6…DC.Bƒ'„Number�of�times�to�do�conversions‚>�'MESS6E„EQU„*-1ŠNEXTWB/MESS7…DC.Bƒ'‡Increment�for�conversion�value‚>�'MESS7E„EQU„*-1ŠNEXTWB0MESS10„DC.BƒCR,LF,'<<<�Starting�conversions�>>>'MESS10EƒEQU„*-1ŠNEXTWB2MESS11„DC.BƒCR,LF,'<<<ƒConversions�doneƒ>>>',CR,LFMESS11EƒEQU„*-1ŠNEXTWB,BADOPN„DC.BƒCR,LF,'***�OPEN�ABORTED�***�--�'BADOPNEƒEQU„*-1ŠNEXTWB2BADCNV„DC.BƒCR,LF,'***�CONVERSION�ABORTED�***�--�'BADCNVEƒEQU„*-1ŠNEXTWB-BADCLS„DC.BƒCR,LF,'***�CLOSE�ABORTED�***�--�'BADCLSEƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…EQU„*-1 ŠNEXTWB ŠPAGE N*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODE PROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA)?ŠMOVE.L�BUFOFST(PC),D0…D0�=�offset�to�find�the�conversion�tableŠNEG.L‚D0–from�PBA7ŠLEA„(A4,D0.L),A0‡Add�the�negative�offset�to�PBA�to�getEŠMOVE.L�A0,BUFFADDR-PBA(A4)�Save�the�address�of�the�conversion�buffer@ŠMOVE.L�A0,CONVBLK+$A-PBA(A4)�the�physical�address�of�the�buffer &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN.ŠOUTPUT�MESS1,MESS1E‡Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary(ŠIF.L�D0��#0�OR.L�D0��#63�THEN.S ŒBRA�GETCHANŠENDI?ŠMOVE.W�D0,OPENBLK+6-PBA(A4)�Save�the�channel�number�in�OPENBLK?ŠMOVE.W�D0,CONVBLK+6-PBA(A4)�Save�the�channel�number�in�CONVBLK N*-----------------------------------------------------------------------------*.*‰Get�(C)onstant�level‚or�(S)awtooth�wave�form*N*-----------------------------------------------------------------------------GETCLST<ŠOUTPUT�MESS4,MESS4E‡(C)onstant�level�or�(S)awtooth�waveform+ŠINPUT‚INPUTBUF,INPUTBUF+8�Get�their�choiceŠMOVE.B�INPUTBUF(PC),D0**£C�=�Constant�level*£O�=�create�your�Own�waveform*£S�=�Sawtooth�waveform* **‰O�=�Own�waveform*CŠIF.B�D0��#'O'�THEN.S‚See�if�they�want�to�do�there�own�waveformŒMOVE.L�BUFFADDR(PC),A2 ŒMOVE.L�A2,A1%OWNVAL†BSR„GETDELAY‰Get�a�delay�value<ŒIF.L�D3��#$FFFF�THEN.S�D3�=�$FFFF�means�exit�"O"�option-ŽMOVE.W�D3,(A1)+‰Store�the�delay �in�the�table/ŽBSR„GETVAL‹Go�get�the�value�for�the�conversion ŽMOVE.W�D3,(A1)+‰Save�that�value ŽBRA„OWNVALŒENDI6ŒSUB.L‚A2,A1ŠFind�the�difference�between�the�beg�&�end ŒMOVE.L�A1,D01ŒDIVU.W‚#4,D0‰Divide�by�4�because�4�bytes/commandŒMOVE.W�D0,CONVBLK+8-PBA(A4)0ŒBRA„GETNUMTˆGo�get�the�number�of�times�to�do�itŠENDI **‰C�=�Constant�level�waveform*ŠIF.B�D0��#'C'�THEN.S7ŒBSR„GETDELAY‹Go�get�the�delay�value�for�each�conversio0ŒMOVE.W�D3,DELAYVAL-PBA(A4)�Save�the�delay�value)ŒBSR„GETVAL‹Returns�D3�=�Value�to�convertŒMOVE.W�#1,CONVBLK+8-PBA(A4)?ŒMOVE.L�BUFFADDR(PC),A0‚Get�the�address�of�the�conversion�tableCŒMOVE.W�DELAYVAL(PC),D1‚Get�the�delay�value�to�put�into�buffer�tabl!ŒMOVE.W�D1,(A0)+‰D1�=�Delay�value&ŒMOVE.W�D3,(A0)+‰D3�=�Value�to�convert0ŒBRA„GETNUMTˆGo�get�the�number�of�times�to�do�itŠENDI **‰S�=�Sawtooth�waveform*ŠIF.B�D0��#'S'�THEN.L7ŒBSR„GETDELAY‹Go�get�the�delay�value�for�each�conversio0ŒMOVE.W�D3,DELAYVAL-PBA(A4)�Save�the�delay�valueGETINCŒREPEAT3ŽOUTPUT�MESS7,MESS7EƒIncrement�for�conversion�valueŽINPUT‚INPUTBUF,INPUTBUF+8ŽLEA„INPUTBUF(PC),A0 ŽBSR„ASCVALŒUNTIL.L�D1��#0+ŒIF.L�D3��#1�OR.L�D3��#$0FFF�THEN.S ŽBRA„GETINCŒENDI8ŒMOVE.W�D3,INC-PBA(A4)ƒSave�the�number�of�times�to�do�itCŒMOVE.W�DELAYVAL(PC),D0‚Get�the�delay�value�to�put�into�buffer�tabl-ŒCLR.L‚D1�Start�with�a�maximum�negative�value;ŒMOVE.L�BUFFADDR(PC),A0‚Get�the�address�of�the�buffer�table ŒMOVE.L�A0,A1ŒMOVE.W�INC(PC),D2 ŒREPEAT/ŽMOVE.W�D0,(A1)+‡Move�the�delay�into�the�buffer<ŽMOVE.W�D1,(A1)+‡Move�the�data�to�be�converted�into�the�buff ŽADD.W‚D2,D1ŒUNTIL.W�D1��#$0FFF ŒIF.W�D1��#$0FFF�THEN.S ŽSUB.W‚D2,D1ŒENDI ŒREPEAT/ŽMOVE.W�D0,(A1)+‡Move�the�delay�into�the�buffer<ŽMOVE.W�D1,(A1)+‡Move�the�data�to�be�converted�into�the�buff ŽSUB.W‚D2,D1ŒUNTIL.W�D1��#0 6ŒSUB.L‚A0,A1ŒFind�the�difference�between�the�beg�&�end ŒMOVE.L�A1,D01ŒDIVU.W‚#4,D0‹Divide�by�4�because�4�bytes/commandŒMOVE.W�D0,CONVBLK+8-PBA(A4)2ŒBRA.S‚GETNUMTˆGo�get�the�number�of�times�to�do�itŠENDI ŠBRA„GETCLSTN*-----------------------------------------------------------------------------*.*‰Get�the�number�of�time�to�do�the�conversions*N*-----------------------------------------------------------------------------GETNUMTŠREPEAT6ŒOUTPUT�MESS6,MESS6E‡Number�of�times�to�do�conversionsŒINPUT‚INPUTBUF,INPUTBUF+8ŒLEA„INPUTBUF(PC),A0 ŒBSR„ASCVALŠUNTIL�D1��#0+ŠIF.L�D3��#1�OR.L�D3��#$FFFF�THEN.S ŒBRA„GETNUMTŠENDI8ŠMOVE.L�D3,NUMT-PBA(A4)„Save�the�number�of�time�to�do�it N*-----------------------------------------------------------------------------**‰Start�the�conversions�here*N*-----------------------------------------------------------------------------**ƒOPEN�THE�D/A�CHANNEL*ŠLEA„CMRBLK(PC),A0ŠLEA„OPENBLK(PC),A1ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OPENLEN,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�to.ŠTRAPƒ#1‘invoke�CMR.‚The�value�in�D0�tells�the)*£operating�system�that�we�want�to�invoke**£CMR,�and�the�value�in�A0�tells�CMR�where&*£to�find�its�parameter�block.‚The�CMR+*£parameter�block�contains�a�pointer�to�the(*£I/O�command�block,�and�the�I/O�command"*£block�spwcifies�an�OPEN�command. 9ŠBNE.S‚BADOPENŒCMR�returns�a�status�code�in�D0.B,�and�CMR+*£returns�the�CC.Z�bit�to�reflect�the�value'*£of�the�status�code�in�D0.B.‚A�nonzero+*£status�code�indicates�that�the�driver�has*£rejected�the�OPEN�command.**ƒDO�CONVERSIONS*3ŠOUTPUT�MESS10,MESS10E…<<<ƒStarting�conversionsƒ>>>:ŠMOVE.L�NUMT(PC),D7ˆD7�=�Number�of�times�to�do�conversionsŠFOR.L�D6�=�#1�TO�D7�DO.SŒLEA„CMRBLK(PC),A0ŒLEA„CONVBLK(PC),A1ŒMOVE.L�A1,$14(A0)ŒMOVE.W�#CONVLEN,$18(A0)5ŒMOVE.L�#CMR,D0ŠTell�the�driver�to�do�the�conversionsŒTRAPƒ#1*'*ƒDo�a�wait�until�the�drive�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒMOVE.W�CONVBLK(PC),D0ŒBNE.S‚BADCONVŠENDF**‚CLOSE�THE�CHANNEL*ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�A1,$14(A 0)ŠMOVE.W�#CLOSLEN,$18(A0)1ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�D/A�channelŠTRAPƒ#1ŠBNE.S‚BADCLOSE/ŠOUTPUT�MESS11,MESS11E…<<<ƒConversions�doneƒ>>> ŠBRA„EXIT BADOPENŠMOVE.L�D0,STATUS-PBA(A4)+ŠOUTPUT�BADOPN,BADOPNE…***�OPEN�ABORTED�***ŠBRA.S‚SHOW_D0 BADCONVŠMOVE.L�D0,STATUS-PBA(A4)1ŠOUTPUT�BADCNV,BADCNVE…***�CONVERSION�ABORTED�***ŠBRA.S‚SHOW_D0 BADCLOSEŠMOVE.L�D0,STATUS-PBA(A4),ŠOUTPUT�BADCLS,BADCLSE…***�CLOSE�ABORTED�*** :SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returnedŠBSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE ŠBRA.S‚EXIT  CHECKQ3ŠCMP.B‚#'Q',INPUTBUF-PBA(A4)�Do�they�want�to�Quit�? ŠBEQ.S‚EXIT3ŠCMP.B‚#'.',INPUTBUF-PBA(A4)�Do�they�want�to�Quit�? ŠBEQ.S‚EXITŠRTS  EXIT"ŠMOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1 GETDELAY.ŠOUTPUT�MESS3,MESS3E‡Delay�between�conversionsŠINPUT‚INPUTBUF,INPUTBUF+8 ŠBSR„CHECKQŠLEA„INPUTBUF(PC),A0 ŠBSR„ASCVAL ŠTST.L‚D1 ŠBEQ„GETDELAY+ŠIF.L�D3��#0�OR.L�D3��#$FFFF�THEN.S ŒBRA„GETDELAYŠENDI ŠRTS   GETVAL8ŠOUTPUT�MESS5,MESS5E‡Value�to�be�converted�($000�-�$FFF)ŠINPUT‚INPUTBUF,INPUTBUF+8 ŠBSR„CHECKQŠLEA„INPUTBUF(PC),A0!ŠBSR„ASCVAL‹D3�=�Value�to�convertŠRTS   ŠEND„PROGSTRT'M610DRV INTSTASMAFÊÊ  TEST610 AFÓÓ  INPTST LFÜÜ  TEST610 LFåå  INPTST LOæ6  TEST610 LO  INPTST PF//  INPTST SA88Ò  INTSTASMSAII'M  TEST610 SArrF[  =/*=/*†M610DRV.INTSTASM.AF=/*5=/* Chain file to assemble portion of the MVME610/620=/* driver test program.=/*:=/* If no output argument is specified for the listing the2=/* chain file will default to M610DRV.INTSTASM.LS=/*=/IFC \1ƒ=ARG�M610DRV.INTSTASM.LS=/ENDIF=/*4=ASM M610DRV.INTSTASM.SA,M610DRV.INTSTASM.RO,\1;Z=80=/*{ Included files are:=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.EXE.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.M610CMD.EQ=/*}=/*=ENDNNNN NNÂ=/*=/*†M610DRV.TEST610.AF=/*,=/*†TEST610�test�program�assembly�chain�file=/*-=/*†Default�argument�01�is�M610DRV.TEST610.LS=/*=/IFC \1ƒ=ARG�M610DRV.TEST610.LS=/ENDIF=/*4=ASM M610DRV.TEST610.SA,M610DRV.TEST610.RO,\1;RZ=100=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNNË=/*=/*†M610DRV.INPTST.LF=/*/=/* Link chain file to create M610DRV.INPTST.LO=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M610DRV.INPTST.LL=/*=/IFC \1ƒ=ARG�M610DRV.INPTST.LL=/ENDIF=/* =LINK ,M610DRV.INPTST.LO,\1;HIMXSEG CODE(RL):0-9SEG SEG2(L):15INPUT M610DRV.INPTST.ROINPUT M610DRV.INTSTASM.ROLIBƒ0.&.PASVMDOS.ROLIBƒ0.&.PDOLRLIB.ROLIBƒ0.&.PASCALIB.RO TASK‚INP0ATTR‚P PRIO‚$7F,$7FEND=/*=ENDNN NNNNÔ=/*=/*†M610DRV.TEST610.LF=/*G=/*†This�chain�file�will�generate�the�TEST610�test�program�load�module.=/*5=/*†The�command�line�will�accept�arguments�as�follows=/*7=/*‹Argument�01ˆ\1�=�Output�file�link�listing�or�device=/*D=/*†The�following�shows�the�link�chain�sequence.‚In�this�example�theF=/*†printer�was�chosen�as�Argument�1,�however,�the�user�could�if�he�so2=/*†desired�have�requested�an�output�listing�file.=/*!=/*�=CHAIN�M610DRV.TEST610.LF�#PR=/*-=/*†Default�argument�01�is�M610DRV.TEST610.LL=/*=/IFC \1ƒ=ARG�M610DRV.TEST610.LL=/ENDIF=/*"=LINK ,M610DRV.TEST610.LO,\1;HAMIXSEG SEG0:0,1,8,14 $000000ATTRIBUTES D PINPUT M610DRV.TEST610.ROLIB 0.&.UTILIB.ROEND=/*=ENDNNNNNÝINP04ŸàCODE" SEG2"ÿÿÿÿ!ÿ"5ÿÿÿÿÿ$@&IpAú¨NAf¼.HßüB "K*O,OB•Hí(+I6Hí0@+B:;C>;FH+G0Bm4¼ `J(HÙüÿ$HGê`+Kp&üÿÿÿÿB›+K+Ll2<€0<ìBµX@YAbö&Jr`B›Y�fúAúv%H,Aú6%H0Aú„%H8Aúš%HJf @fpBNNCíK& –‰CCaZJfR@  g ;fÿz;@" ;fXa =faôg ,fò  g. Zg( Ae" [dCíK( ˜‰ -fDDH�ã‰Gíj7„aÀ  f¨JgŒáƒåƒaf() ˜©„‰ ƒŠclÖ„ƒÿBAíB¨B�B¨BhBh B¨!|SEG2 pNAfþAí!CB�B¨1| B¨!|SEG2 1| pNAfýè–„ƒŠ`BƒaÞ,iÝüˆÝÃKí¼0<¼=%U@fú.N*O$iGê`+Kp&üÿÿÿÿB›+K+i l&Jr`B›Y�fúAú´%H,Aút%H0AúÂ%H8AúØ%HHíÿÿ|+o t <+@xaÿ:`ÿ H@0-4H@,NAB€B�IúT am zn ,gè4k6 -fÀ`Ög0ƒgÁ` =fRŠa`  f@` NuBƒ:< &J $g� am zn 4gˆ`6 am zn 4k6gãƒ(åƒÖ„�Ö�SEf΂ am zn 4jè  f" am zn +ÿþNu:< am zn  am zn 4k´fgŒ_�郆�SEfÌ`ÿz€€€@@ P€@  €@HÄR„„ÿÿÿþŸÄŸü ¿íb O÷H pNNOï .·HNu.LÐ2*(-0a®a+D0Nu"_. HÂ&g&<…(„QR„Dÿþ$O•ĵíldEïµíle•ílØŠaÿz!OEïP/JEò8ÿ/JA??B$O eTgv`gvC)C BjBBjBªL@O(-0fgA@aJf<gJ-(ga Xat`aúgJ-$ga @a\`aâgaÄ`8°m"b"?S@å@@,J5LŸg ga a$` ga¤`aŠgNq5A+D0NÑHçØžMê$gpÿS@å@@,Aõ|B€(@AõJa\$€ÿ€üLßyg/p(NNg g%m6*HBB|g€BNÁ Nupa |&8%m:*NuH瀀Aê$0¼€NCgNN *&o|&BjFB*K*E f|'` f|'`|'BjDLßNu.LÐ2*aHaxB� f† fpÀj& g fa  g4/ &Ja Æ5 c ¼5‚a ˜a>H‚?a Æ2&_g*8 gAê0¼NBgNN` ap÷Áj&a AìB’5ANup`‚.LÐ ª2*a’ fFa p�j&aV*8 &g, g&Aê$0¼€NCg f0¼NCf0¼€NCgNNa –B’A€� a ¬CòO%I5ANup` f?*8 &g pøÀj&€W5@&0Nu/(-0fBg<`"g<`BR ft bfì cp@NNB B)(NuB€B�Iúûr&H6<%B„aük$ #fÀ` ff&@€€€Nu€ü`öaÊkBfôgÚ .f R nÐ`Þ :f€@`Ð (f€`Ä )fª@`¸g Jfžf˜ggŒfF*H Kf  am zn (g24f.f. gD gô .fRˆ`*Rˆ`DÀ` 6<Gîa&4<aškÌ`À`Â&<€€€ am zn 4k^f0fR *g2À  am zn 4kR .fâ`JÆü �Ö�`¤ ƒ€f4 .fÄÀ6<ÿþ` ƒ€g ƒ'cÀ` =C ` À`À4<aÚk 6< Gî aN4<aÂkô n& f| 6< Gîa(4<aœkÎ (g 6<Gîa 4<a~k° (f¨BBBC am zn 4kD )gg8 Pn2AéK†AB`ÈBÿg BnÀ BcÀ=C `JÀÀÀBÿ BcÀ`.Rˆ6<Gîap4<aæk$< Gî &Â&Â&Â&Â6ÂBn $B|gÀ4B|gÀJ€NuJCfBA`$ am zn SC /f À<€`4Nu4HB€€»ÈgF am zn 4k.f(f @À`< *fÀÁSCn¾€€`$HB´CfÀ`< (*ÿþf<*`ÂSCnúNuJ€jÀ`QBgQBÀ`ÀBgÀNug g ³êga° ‰Nu%| 8%| .f %m@0%mD4` g%m6*Nu HçùÀ./ T¯ a( ‚DÁLߟNuHçùÀ./ T¯ aãƒjD€ €DÁLߟNu G0å@A÷X@ @fB@C÷ "fpNN&âƒjD€³ƒJ�jD�tÿB²€dã‰R`ö��dÐ�ã’â‰SdòF‚"jD‚F�‚[ÁNu.LÐR’aP ‰Nu0/8/`8/0/./ Gï 2RAAÿþ sLИ@a†J@g ›aŽS@nö ‰&_$_O÷NÒHçÀ€2*fpDNN³êggS‰` g¼ `S‰`¼ %IAê0¼NBg ÆgNNa&CòO%I"jLßNuJDo ¼ aSDnôNu³êfaÿzŸRIR’Nu./ LÐ 8+ fa¸8+gp"NN„7D +�ŠR€Ñ“&_B�Nu.a2€Nu.a"€NuHçx"aõjLÐ 8+,Oa¤B +g -f -f|ÿaºa˜ am zn aÀ,OaÎJjD€ ŠÞü"LßH`Nu.HçPBYU@a"Lß 2‚Nu./ aJAgp ÀSAnú&_NuLÐ 8+24a.µëgaBJAgîÀSA`è”A ŠNua fa$`ðNu fa¨8+gp"NNB€NuR“µëf•Ê`RеëfÄ7DNuz"Bv 0m 9op1NN`@JEoJf 0g 0ÀPÁSE`RCaÿªaÿˆ am zn 0m 9oÀ #f¬ÃJEoÀSE`RCBaÿlaÿJ am zn 9o Am0 oJ@m @op1NN`TJEoJf gÀPÁSE`RCaÿaþî am zn 9o Am0 oJm o¬E"DENuB@BAt JEoNv #f(J@gpbNN` Ac AcpbNN`4B@BA`´CnpcNNÀÂÂÂÒƒHA6HAЃSE`°H@0NuHçøÐ2+$KaHÀgS€`R€@ÿþЫS€'@fpCNNAë0¼NBgz Ægt ÂgNNA€7A gXa5´5cJaÂ�7AR55H‚5 J /g RB5 J /fôRB‚aê2*aT5ALß `ÿJ•Ê`8�$k +g�J€fÁ¼ ` J€g0+HÀS€ÐŠ'@7ALß NuAê$0¼@NCgNN$-0*)Â+B0ÁNu0<…f0*NugH瀀Aê$0¼NCgNNLßNuaÞAý¿?* „6Nug0<$`g0<(`+OSH€å@@,NuAõ JHçMë$aõfLßpaù¸€ÿ€üg/p(NNNupþ`B@ _.8˜@gAðañ,"OUDg"ØYDnúm2ØNÐ$_. 0HÀ`$_. "JaNò8&RƒCÿþ(gÙS€nú`â€UÁâ€UÂg ÙS€núJg0ÙJgÙNu$_. 8TDað¾"OUDg"ØYDnúm2ØNÒ."Ga|(` ."GapB„8R„„ÿÿÿþ.‰v¸ƒl(X„"mQ‰$I&)g""C¸‘nò �„ €lX‰%Q`*"€ÓÀ"Ä`""mEñH ¿ÊbpNNEêÿØQ‰$Ñ"Ä$Ñ+J ‰NuOïÿà¿íOï bpNNNu _.02RAAÿþÞÁNÐNuNVÿîB.ÿópCîÿøAíÿøN«ŠN« ØBnÿô=|ÿö?.ÿöAîÿøN«ÒN«ˆ°_m„0.ÿö 60ùm 69ùo0.ÿö 6Aùmb 6FùnZ0.ÿö 6Aùm2.ÿôHÁé�6ùH‚HÂÒ‚�7=Aÿô` 0.ÿôHÀé€2.ÿö6ùH‚HÂЂ€0=@ÿô0.ÿöHÀR€=@ÿö`ÿj?.ÿöAîÿøN«ÒN«ˆ°_m>|ÿóHmÿðN«XInvalid hex number - reenter > BgN« /N“ÆJ.ÿófþð=nÿôN^NuNVÿîAîÿúN«‚ -|ÿò0.HÀrN« p-@ÿö4.HÂ&N« X=B € m8.ÿô€7€@û`0.ÿô".ÿö�0�ûS®ÿò ®ÿòl¤HmÿðAîÿúN«ÒBgN« N« îN^ _T�NÐNVÿò-mÿ®ÿö-ÿÂ`\ nÿöBh`~ nÿö1|`p nÿö1|`b nÿö1|`T nÿö1|`F nÿö1|`8?<NN WnòAú Vˆ°númæÐÐNÐCÿ¨DÿÀEÿ®OÿŽSÿÂWÿz nÿö0(HÀJ€gÂHmÿðN«XEnter channel mnemonic > BgN« /N“BpCíÿžAíÿøN« N« Ø nÿö0(HÀ €gNHmÿðN«XEnter channels mask in hex. > BgN« /N“è nÿöHhU�aý0 _0€`HmÿðN«X#Enter number of channels to open > BgN« /N“” nÿöCèAíÿøN«N« ØB®ÿú nÿö0(HÀS€-@ÿò`ªHmÿðN«XEnter channel number > BgN« /N“8 nÿö .ÿúå@CðAíÿøN«N« ØHmÿðN«X&Enter channel configuration in hex. > BgN« /N“à nÿö .ÿúå@HpU�aûú0 _0€R®ÿúi .ÿò°®ÿúlÿNU�Hmÿ˜Hmÿ¼N“l nÿö0Ÿ0(HÀJ€gx0(HÀ €f6HmÿðN«XChannel Status = BgN« /N“\ nÿö?(aüžHmÿðN«XCommand Status is BgN« /N“& nÿö?aüjN^NužüntrpAíÿðN«âAíÿðN«®trpAíÿøN«âAíÿøN«ü|ÿšB-ÿ›Aíÿ®N«ü&HmÿðN«XEnter number of tasks (1-26) > BgN« /N“šCíÿ´AíÿøN«N« ØAíÿ¼N«‚INPx/-ÿ´N“F+|ÿ¸+mÿ´ÿ’` -ÿ¸€@@ÿ¿HmÿðN«X** Task BgN« //-ÿ¼?<?<N« þ/?<*/< *BgN« N« îHmÿðN«X9Command (O-pen,C-lose,E-nable,D-isable,S-tatus,W-ait ) > BgN« /N“Àp CíÿÀAíÿøN«ŠN« ØAíÿÀN«ÒN«ˆHÀJ€g,-ÿ "<ˆ€8t ?c°` m`gaûTAíÿÀN«ÒN«ˆHÀJ€fþþR­ÿ¸i -ÿ’°­ÿ¸lþì`þÖAíÿðN«ÆAíÿøN«ÆBgNN(_.S‡Oïÿœ O ¼INPAB¨1|@||1| Cú>!I1|2p NAgaàR(QÉÿð ¼INPA1| 1| ""Op#|CODE INAga®p#|SEG2 INAgašR)QÉÿÒ I ¼INPA| | !| Cú>!I"pNAgabR(QÉÿð ¼INPA1|"p NAgaBR(QÉÿðOïdNÔLßOïÿœ O ’1|€Eú˜!JEè!J B\4ü$Ì9|$l jf2*Âü\�9Ap#NAgaàJ,ÿþgúOïd>’NÑ STAKpAúÿäNAga¬Oèøp$NAgúažpNAùþ`¹þ``êŸü Op"NAgav h ßü"hJigp  Enter one of the above... 0 = READ THE CURRENT INPUT STATUS. 1 = ENABLE FOR AN INTERRUPT. 2 = QUIT. STATUS OF ALL CHANNELS (ASCII) = <<< Starting command >>> <<< Command done >>> *** OPEN ABORTED *** -- *** ENABLE INTERRRUPT ABORTED *** -- *** DISABLE INTERRRUPT ABORTED *** -- *** READ STATUS ABORTED *** -- *** CLOSE ABORTED *** -- Error code returned in D0 = Oúý(Iúü\Aúþ)HDAúþ)HHAúý€NBAúþ)HDAúþ6)HHAúýjNBAúüô)H`Aúüô)HdAúýpNBAúüÞab €m €o`º9@’AúÜ09@š9@ 9@¦Aúþ)HDAúþ%)HHAúý NBAúþ)HDAúþ2)HHAúüöNBAúþ&)HDAúþ-)HHAúüàNBAúý )HDAúý¶)HHAúüÊNBAúüT)H`AúüT)HdAúüÐNBAúü>a @m @o`¾ fÈAúýú)HDAúþ )HHAúü€NBa²0< aAúü¦CúüÈ!I1|pNBB€0,ša¸)B0)C4Aúýl)HDAúý†)HHAúüNBAúü)HDAúü)HHAúüNBAúþ^)HDAúþW)HHAúûêNBAúýj)HDAúýz)HHAúûÔNB`þR f^Aúý.)HDAúýA)HHAúû´NBaæ0<aLpNAg0:ü)@,AúýP)HDAúýn)HHAúû†NBAúý)HDAúý)HHAúûpNB`ýî f`’`ýàAúû�Cúû¨9@”!I1| p=�'0'�)�and�(�num_str[i]�<=�'9'�))�or7‘((�num_str[i]�>=�'A'�)�and�(�num_str[i]�<=�'F'�))ƒ)�doŒbegin�if�num_str[i]�>=�'A'9’then�num�:=�num�*�16�+�ord�(num_str[i])�-�ord�('A')�+�105’else�num�:=�num�*�16�+�ord�(num_str[i])�-�ord�('0'); �i�:=�i�+�1Œend;‰if�i�<=�length�(num_str)�thenŒbegin�error�:=�TRUE;+�write�('Invalid�hex�number�-�reenter�>�');�p$force�(output)Œend†endƒuntil�error�=�FALSE;ƒhex_in�:=�num end;{$E} procedure hex_out ( num : word); varƒnum_str�:�string[4];ƒi,j…:�integer; begin ƒnum_str�:=�'„';ƒfor�i�:=4�downto�1�do†begin‰j�:=�num�mod�16;‰num�:=�num�div�16; ‰if�j�>=�10 0k9h,Œthen�num_str[i]�:=�chr�(j�-�10�+�ord�('A'))'Œelse�num_str[i]�:=�chr�(j�+�ord�('0'))†end;ƒwriteln�(num_str)end;{$E}procedure enter_command; varƒstatus„:�word; ƒi‰:�integer; beginƒwith�init_blk.cmd_adr^�do„begin†case�cmd_char[1]�of‰'W'�:�code�:=�WAIT;‰'O'�:�code�:=�OPEN;‰'C'�:�code�:=�CLOSE;‰'E'�:�code�:=�ENABLE;‰'D'�:�code�:=�DISABLE;‰'S'�:�code�:=�STAT†end;†if�code�<>�WAIT�thenˆbegin%Šwrite�('Enter�channel�mnemonic�>�');Šp$force�(output);Šreadln�(init_blk.mnemonic);Šif�code�<>�OPEN �then”{All�commands�except�OPEN}�begin*“write�('Enter�channels�mask�in�hex.�>�');“p$force�(output);“chan_mask�:=�hex_in�end�else”{OPEN�command}�begin /“write�('Enter�number�of�channels�to�open�>�');“p$force�(output);“readln�(chan_cnt); “for�i�:=�0�to�chan_cnt�-�1�do–begin#™write�('Enter�channel�number�>�');™p$force�(output);™readln�(cdb[i].chan_no);2™write�('Enter�channel�configuration�in�hex.�>�');™p$force�(output);™cdb[i].config�:=�hex_in–end Œend‚{else} ˆend;{if},†status�:=�send_command�(init_blk,�task_ID);†if�code�<>�WAITˆthen‰begin‹if�code�=�STATŽthen�begin’write�('Channel�Status�=�');’p$force�(output);’hex_out(chan_mask)�end;‹write�('Command�Status�is�');‹p$force�(output);‹hex_out�(status)‰end „end‚{with}end;{$E} begin‚{main} ƒwith�init_blk�do†begin ‰code�:=�7;‰sub_code�:=�0;‰new�(cmd_adr)†end; +ƒwrite�('Enter�number�of�tasks�(1-26)�>�');ƒp$force�(output);ƒreadln�(�task_cnt); ƒtask_ID�:=�'INPx'; ƒclone_tasks�(task_cnt); ƒwhile�true�do†for�i�:=�1�to�task_cnt�do‡repeat‰begin(Œtask_id[4]�:=�chr�(ord�('A')�+�i�-�1�);$Œwriteln�('**�Task�',task_ID,'�**');EŠwrite�('Command�(O-pen,C-lose,E-nable,D-isable,S-tatus,W-ait�)�>�');Œp$force�(output);Œreadln�(cmd_char); Œif�(length�(cmd_char)�<>�0)�and+�(cmd_char[1]�in�['W','O','C','E','D','S'])�then‚enter_command‰end‡until�length�(cmd_char)�=�0end. *‰INCLUDE�9995.&.TR1.EQŠINCLUDE�9995.&.TR1.EQ*‰INCLUDE�9995.&.TR1RTCD.EQŠINCLUDE�9995.&.TR1RTCD.EQ*‰INCLUDE�9995.&.EXE.EQŠINCLUDE�9995.&.EXE.EQ*‰INCLUDE�9995.&.LV5.EQŠINCLUDE�9995.&.LV5.EQ*‰INCLUDE�9995.&.M610CMD.EQŠINCLUDE�9995.&.M610CMD.EQŠPAGE*H* VME 610/620 Driver Assembly language test routines. These routines are;* called from a Pascal test task that performs terminal I/OŠSPC„2 ŠSECTION�9ŠXDEFƒCLONE_TA I*‚Create�the�specified�number�of�test�tasks�that�share�the�code�and�stackL* segments of the PASCAL program that is calling this routine. Then allocate.* an ASQ for each task and start them running. ,CLONE_TA‚MOVE.L�(A7)+,A4‹Save�return�addressŠSPC„2$ŠMOVE.L�(A7)+,D7‹Save�task�count�-�1 ŠSUB.L‚#1,D7ŠSPC„2:ŠLEA.L‚-100(A7),A7ˆAllocate�parameter�block�space�on�stackŠSPC„27ŠMOVE.L�A7,A0ŽStore�CRTCB�parameter�block�address�in�A0ŠSPC„2'*‚Initialize�Create�TCB�parameter�block @ŠMOVE.L�#'INPA',CRTTSK(A0)ƒName�tasks�alphabetically�within�sameŠCLR.L‚CRTSES(A0)‰sessionŠSPC„23ŠMOVE.W�#CTOPMP,CRTOPT(A0)�Propogate�monitor�optionŠSPC„21ŠMOVE.B�#$7F,CRTIPR(A0)„Run�task�at�max.�priorityŠMOVE.B�#$7F,CRTLPR(A0)ŠSPC„2-ŠMOVE.W�#$2000,CRTATT(A0)‚Task�dump�attributeŠSPC„2.ŠLEA.L‚TASKENT(PC),A1…Task�entry�point�addressŠMOVE.L�A1,CRTENT(A0)ŠSPC„2ŠMOVE.W�#0,CRTUID(A0)†User�0ŠSPC„2* Create TCB's %ŠMOVE.W�D7,D1ŽInitialize�loop�counterŠSPC„2)TCBLOOPƒMOVE.L�#CRTCB,D0ŠIssue�CRTCB�callŠTRAPƒ#1 ŠBEQ.S‚TCBOK ŠBSR„ERRORŠSPC„2ETCBOK…ADD.B‚#1,CRTTSK+3(A0)„Update�task�name�and�loop�until�all�tasks#ŠDBRAƒD1,TCBLOOP‰have�been�created.ŠSPC„25* Initialize Share Segment directive parameter block. #ŠMOVE.L�#'INPA',SEGTCB(A0)ƒTaskname<ŠMOVE.W�#SGOPPA,SEGOPT(A0)ƒLogical�=�phy sical�address�optionŠSPC„23ŠMOVE.W�#SGATSS,SEGATT(A0)ƒSession�sharable�segmentŠSPC„2,* Share code and data segments to each task. %ŠMOVE.L�D7,D1ŽInitialize�loop�counter ŠMOVE.L�A7,A1ŠSPC„2AHJIR9ZBbB=SEGLOOPƒMOVE.L�#SHRSEG,D0‰Share�the�code�segment�to�each�taskŠMOVE.L�#'CODE',SEGNAM(A1) ŠMOVE.L�A1,A0ŠTRAPƒ#1 ŠBEQ.S‚SEG010 ŠBSR„ERRORŠSPC„2DSEG010„MOVE.L�#SHRSEG,D0‰Share�the�PASCAL�stack�segment�to�each�taskŠMOVE.L�#'SEG2',SEGNAM(A1) ŠMOVE.L�A1,A0ŠTRAPƒ#1 ŠBEQ.S‚SEG020 ŠBSR„ERRORŠSPC„2FSEG020„ADD.B‚#1,SEGTCB+3(A1)†Loop�until�both�segments�have�been�sharedŠDBRAƒD1,SEGLOOP‰to�all�tasks.ŠSPC„2)* Initialize Allocate ASQ parameter block ŠMOVE.L�A1,A0,ŠMOVE.L�#'INPA',ASQTSK(A0)„Initial�task�nameŠSPC„2AŠMOVE.B�#AQSTQE+AQSTRE+8,ASQSTA(A0)�ASR/ASQ�enabled,�no�registersŠSPC„23ŠMOVE.B�#18,ASQMML(A0)…Max.�event�length�=�18�bytesŠSPC„2.ŠMOVE.L�#2048,ASQQLN(A0)ƒASQ�length�=�2K�bytesŠSPC„2-ŠLEA.L‚INTASR(PC),A1†Default�to�interrupt�ASRŠMOVE.L�A1,ASQASR(A0)ŠSPC„2* Allocate ASQs for each task %ŠMOVE.L�D7,D1ŽInitialize�loop�counterŠSPC„25ASQLOOPƒMOVE.L�#GTASQ,D0ƒIssue�Allocate�ASQ�directiveŠTRAPƒ#1 ŠBEQ.S‚ASQ010 ŠBSR„ERRORŠSPC„2EASQ010„ADD.B‚#1,ASQTSK+3(A0)†Loop�until�an�ASQ�has�been�allocated�forŠDBRAƒD1,ASQLOOP‰each�task.ŠSPC„2'*Initialize Start Task parameter block. :ŠMOVE.L�#'INPA',STRTSK(A0)ƒStart�tasks�without�passing�any+ŠMOVE.W�#0,STROPT(A0)†initialize�registers.ŠSPC„2* Start all tasks *ŠMOVE.L�D7,D1�Initialize�the�loop�counter.ŠSPC„2#STARTLPƒMOVE.L�#START,D0ŠStart�taskŠTRAPƒ#1ŠBEQ.S‚STRT010 ŠBSR„ERRORŠSPC„2DSTRT010ƒADD.B‚#1,STRTSK+3(A0)„Loop�until�all�tasks�have�been�startedŠDBRAƒD1,STARTLPŠSPC„2* Task startup completeŠSPC„2-ŠLEA.L‚100(A7),A7‰Restore�entry�stack�pointerŠSPC„2+ŠJMP„(A4)�Return�to�calling�PASCAL�routine.ŠSPC„2ŠPAGEŠXDEFƒSEND_COMŠSPC„2K* This routine passes the address of an Initiate I/O parameter block to oneM* of the test tasks in an event that is queued to the task. After sending theM* command event, the routine waits for the test task to set a flag indicatingM* that the command has been issued to the driver and the return status can beH* read from the command parameter block. The routine then returns to theN* calling PASCAL routine with the command status as the function return value. :SEND_COM‚MOVEM.L�(A7)+,A1/A2/A4„Pull�parameters�from�stack*¤A1�=�Return�address*¤A2�=�Task�ID�address*¤A4�=�Initiate�I/O�PB�addressŠSPC„2>ŠLEA.L‚-100(A7),A7ˆAllocate�parameter�block�space�on�the�stackŠSPC„2-* Initialize the Queue Event parameter block. 6ŠMOVE.L�A7,A0ŽSave�parameter�block�base�address�in�A0.ŠSPC„2?ŠMOVE.L�(A2),QEVTSK(A0)†Copy�the�task�ID�passed�from�the�PASCAL'*£routine�to�the�destination�task�name.ŠSPC„2@ŠMOVE.W�#QVOPAS,QEVOPT(A0)ƒSet�the�command�processing�ASR�of�the?ŠLEA.L‚CMDASR(PC),A2†tast�task�to�be�the�alternate�ASRT�serviceŠMOVE.L�A2,QEVIAD(A0)†address.ŠSPC„2?ŠLEA.L‚QEVIAD+4(A0),A2†Load�the�event�buffer�address�(following=ŠMOVE.L�A2,QEVPKT(A0)†the�parameter�block)�into�the�parameter*£block.ŠSPC„22ŠCLR.W‚(A4)+�Clear�the�command�conpletion�flag�and(*£update�the�pointer�to�the�Initiate�I/O*£parameter�block�base�address.ŠSPC„2;ŠMOVE.W�#$0603,(A2)+‰Event�length�=�6�bytes,�Event�code�=�3ŠMOVE.L�A4,(A2)+ŠSPC„2@ŠMOVE.W�#CMDLEN,XIOPLN(A4)ƒAssume�that�the�length�of�the�command'*£block�is�standard�(i.e.�not�an�OPEN�) ŠSPC„29ŠMOVE.L�XIOCPK(A4),A2‡Get�the�command�block�base�address.ŠSPC„2BŠCMP.W‚#INOPEN,CMDCOD(A2)‚If�the�command�is�not�OPEN,�the�standard/ŠBNE.S‚QUECMD�length�already�loaded�is�correct.ŠSPC„2:ŠMOVE.W�CMDNCO(A2),D1ˆCalculate�the�correct�length�for�the:ŠMULUƒ #OPNCDB,D1‰OPEN�command�parameter�block�and�store�in)ŠADD.L‚#CMDCHL,D1‰the�Initiate�I/O�block.ŠMOVE.W�D1,XIOPLN(A4)ŠSPC„2AQUECMD„MOVE.L�#QEVNT,D0‹Queue�the�command�event�to�the�test�task.ŠTRAPƒ#1ŠBEQ.S‚ACKLOOP ŠBSR„ERRORŠSPC„2;ACKLOOPƒTST.B‚-2(A4)�Loop�until�the�command�completion�flag+ŠBEQ„ACKLOOPŒhas�been�set�by�the�test�task.ŠSPC„22ŠLEA.L‚100(A7),A7‹Restore�the�entry�stack�pointer.ŠSPC„2=ŠMOVE.W�CMDSTA(A2),(A7)†Save�the�command�completion�status�in(*£the�function�return�word�on�the�stack.ŠSPC„2/ŠJMP„(A1)‘Return�to�the�calling�PASCAL�routine.ŠSPC„2ŠPAGEJ*‚This�is�the�test�task�that�issues�commands�to�the�driver�as�specified�byL* the controlling PASCAL task. The test task handles interrupt notificationsN* sent by the driver. The user is notified of the interrupt via LEDs connected:* to an MVME 625 Digital Output module on the I/O channel. 5VME625„EQU„$FE6001ŒVME�625�module�I/O�channel�address (* Allocate Stack Segment parameter block SEGBLK„DC.Lƒ0’Task�name…(self)ŠDC.Lƒ0’Session�number(self)6ŠDC.WƒSGOPPA�Logical�Address�=�Physical�address�option)ŠDC.WƒSGATRW�Read/Write�Segmant�attributeŠDC.Lƒ'STAK'�Segment�name)ŠDC.Lƒ0’Segment�address�(Returned�by�RMS)ŠDC.Lƒ$100�Segment�lengthŠSPC„2* Test task entry point* Allocate a stack segment >TASKENTƒMOVE.L�#GTSEG,D0ŠAllocate�a�stack�segment�of�256�bytesŠLEA.L‚SEGBLK(PC),A0ŠTRAPƒ#1 ŠBEQ.S‚TSK010 ŠBSR„ERRORŠSPC„2BTSK010„LEA.L‚$F8(A0),A7‰Initialize�the�stack�pointer�to�the�end�of*£the�stack�segment.ŠSPC„2CTSKWTEVT‚MOVE.L�#WTEVNT,D0‹Wait�for�a�command�event�or�an�interrupt*ŠTRAPƒ#1‘event�to�be�processed�in�the�ASR.ŠBEQ.S‚TSKWTEVT ŠBSR„ERRORŠSPC„2I*‚Control�reaches�here�when�the�user�has�issued�a�command�for�the�task�to* enter the wait state. ;TSKWAITƒMOVE.L�#WAIT,D0ŒPlace�the�task�into�a�WAIT�state�so0ŠTRAPƒ#1‘interrupts�may�be�processed�on�channels*£using�WAKEUP.ŠSPC„23ŠBSETƒ#7,VME625ŒPulse�LED�7�on�the�VME�625�board�to8ŠBCLRƒ#7,VME625Šindicate�that�a�wakeup�has�been�receivedŠSPC„26ŠBRA.S‚TSKWAITŽThis�loop�repeats�until�a�command�event*£is�queued�to�the�test�task.ŠPAGE* Command event ASR 3CMDASR„SUB.L‚#16,A7�Allocate�stack�to�receive�event ŠMOVE.L�A7,A0ŠSPC„21ŠMOVE.L�#RDEVNT,D0ŠRead�command�event�into�bufferŠTRAPƒ#1 ŠBEQ.S‚CMD020 ŠBSR.S‚ERRORŠSPC„28CMD020„MOVE.L�EVQTXT(A0),A0‡Load�event�text�base�address ŠADD.L‚#16,A7=ŠMOVE.L�XIOCPK(A0),A1ˆLoad�Input�Command�Parameter�Block�base *£addressŠSPC„27ŠTST.W‚CMDCOD(A1)ŠIf�the�command�code�is�zero,�the�test3ŠBEQ.S‚CMDWAITŒtask�is�to�be�put�into�a�WAIT�state.ŠSPC„2* Issue command to the driver. 5ŠMOVE.L�#CMR,D0ŒIssue�the�Initiate�I/O�command�to�CMRŠTRAPƒ#1 ŠBEQ.S‚CMD030ŠSPC„2=ŠMOVE.W�D0,CMDSTA(A1)ˆIf�an�error�is�returne�by�CMR,�copy�the'*£error�code�into�the�IPB�status�field.ŠSPC„24* Signal supervisor task that command was completed. FCMD030„MOVE.W�#$FFFF,-2(A0)†Set�the�command�completion�flag�and�returnŠRTR—from�the�eventŠSPC„2* Put task in WAIT state CCMDWAITƒLEA.L‚TSKWAIT(PC),A1‡Change�the�event�return�address�to�the'ŠMOVE.L�A1,2(A7)‹WAIT�loop�entry�point.ŠSPC„25ŠMOVE.W�#$FFFF,-2(A0)ˆSet�the�command�completion�flagŠSPC„2;ŠMOVE.L�#SETASQ,D0‹Enable�the�ASR�and�ASQ�so�command�events4ŠMOVE.L�#5,A0Žmay�be�processed�when�a�WAKEUP�occurs.ŠTRAPƒ#1 ŠBEQ.S‚CMD010 ŠBSR.S‚ERRORŠSPC„20CMD010„RTR˜Return�to�the�WAIT�state�loop�until�a+*£command�event�is�waiting�and�a�WAKEUP�has(*£been�issued�to�the�task�by�the�driver.ŠPAGE* Interrupt Event ASR 3INTASR„SUB.L‚#16,A7�Allocate�stack�to�receive�event ŠMOVE.L�A7,A0ŠSPC„2)ŠMOVE.L�#RDEVNT,D0‰Read�event�into�bufferŠTRAPƒ#1 ŠBEQ.S‚INT010 ŠBSR.S‚ERRORŠSPC„2;INT010„MOVE.B�3(A0),D0‹Load�the�interrupting�channal�numberŠSPC„28ŠCMP.L‚#'IN02',4(A0)ˆIf�the�first�module�is�interrupting1ŠBNE.S‚INT020�leave�the�channel�number�unchanged.ŠSPC„21ŠADD.B‚#4,D0�If�the�second�module�is�interrupting!*£add�four�to�the�channel�number.ŠSPC„28 INT020„BSETƒD0,VME625ŒPulse�the�LED�corresponding�to�the(ŠBCLRƒD0,VME625Šmodified�channel�number.ŠSPC„2ŠADD.L‚#16,A7�Restore�stackŠSPC„2ŠRTR™Return�from�eventŠSPC„2;ERROR…MOVE.L�(A7)+,A0�Abort�the�task�if�an�unexpected�error9ŠMOVE.L�#ABORT,D0Šoccurs.�The�address�of�wherer�the�error3ŠTRAPƒ#1‘occurred�is�stored�in�A0�for�the�SCT�abort *£message.ŠSPC„2ŠENDN*******************************************************************************Ì**Ì*#*—MVME610�or�MVME620‚Test�Program•**Ì**Ì*N********************************************************************************6* This program was written to test the MVME610 driver.**    *‰Modification�HistoryN*-----------------------------------------------------------------------------*�11/01/84‡DUH�Initial�writing   *�1.‚Introduction*B*‰This�program�was�written�to�test�the�MVME610�driver.‚It�can�alsoI*‚be�used�to�test�the�VME620�board.‚This�program�will�ask�for�the�channelI*‚number�to�use.‚It�will�then�ask�if�the�user�wants�to�read�the�status�ofL*‚that�channel�or�enable�and�wait�for�a�negative�going�edge�on�that�channel.K*‚To�use�this�test�program,�connect�a�square�wave�generator�to�a�channel�onD*‚the�VME620�DC�input�module�or�a�switch�connected�to�120VAC�for�the*‚VME610�AC�input�module.*8*‰This�program�assumes�the�boards�are�jumpered�as�shown:**‚VME610�or�VME620:%*„J3‚1,2‚3,4‚5,6‡address�offset�$0005*„J2‚2,4‘interrupt�INT1*ŠPAGE ,*£ASCVAL,�BHLCVT,�and�CVT2�are�commonly�used**£functions�which�are�modules�in�a�library(*£file�called�UTILIB.RO.‚A�call�to�these'*£functions�are�included�in�this�source)*£program,�which�is�provided�with�an�XREF&*£declaration.‚This�also�requires�that'*£UTILIB.RO�be�available�to�the�linkage$*£editor�during�the�linking�process.%*£See�TEST620.LF�for�link�chain�file. -ŠXREFƒASCVAL�Converts�ASCII�to�a�binary�value$*£This�routine�will�convert�an�ASCII,*£character�string�representing�a�decimal�or,*£hexidecimal�value�to�the�equivalent�binary,*£value.‚If�a�dollar�sign�($)�is�encountered&*£hexidecimal�conversion�is�performed;,*£otherwise�decimal�conversion�is�performed.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary'*£value.‚Conversion�terminates�when�the)*£first�invalid�character�is�encountered.'*£ENTRY:‚A0�-�Starting�address�of�ASCIIj>s:{DƒB‹G“F›F£S«8*°character�string�to�convert#*£EXIT�:‚D1�-�Character�that�caused *°termination%*«D2�-�Class�code�of�terminating�char"*«D3�-�Binary�result�of�conversion*«A0�-�Address�of�the�character *°following�the�terminating�char 8ŠXREFƒBHLCVT�Converts�4-byte�binary�value�to�ASCII�digit)*£This�routine�will�convert�a�long�binary-*£word�value�to�a�hexadecimal�value�expressed)*£as�an�8�character�ASCII�string.‚Leading*£zeros�are�suppressed.,*£ENTRY:‚D0.L�-�Binary�value�to�be�converted(*£EXIT�:‚D2.L�-�Four�high�order�bytes�of*²converted�value *«D3.L�-�Four�low�order�bytes�of*²converted�value 6ŠXREFƒCVT2�Converts�two�ASCII�decimal�digits�to�binary-*£This�routine�will�convert�two�ASCII�decimal(*£digits�to�the�equivalent�binary�value.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary**£value.‚Conversion�terminates�when�a�non-*£decimal�digit�is�encountered)*£ENTRY:‚A0�-�Address�of�most�significant*°ASCII�decimal�digit)*£EXIT�:‚D0�-�Binary�result�of�conversion!*«A0�-�Address�of�the�terminating *°character ŠPAGEŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N************************************************************************ ****** ŠSECTION�DATA $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. 9ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�VME620�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was. 6NUMBER„DS.Lƒ2’Save�area�for�the�ASCII�value�of�STATUS.ŠPAGE N*******************************************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠDC.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address  CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�UnusedŠDC.Lƒ'IN01'�Channel�nameŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�blockŠPAGE*7*‚OPEN�command�parameter�block�for�the�DC�INPUT�driver:+OPEN_DCI‚DC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)-ŠDC.WƒDEFAULTŒChannel�configuration�(Dynamic)6OLEN_DCI‚EQU„*-OPEN_DCI‰Length�of�OPEN�parameter�block*E*‚READ�OUTPUT�STATUS�command�parameter�block�for�the�DC�INPUT�driver:+READ_DCI‚DC.Wƒ0’Returned�status�from�driver*ŠDC.WƒREAD_STATUSˆRead�status�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*£return�holds�the�actual�channel�status=RLEN_DCI‚EQU„*-READ_DCI‰Length�of�READ�STATUS�parameter�block*D*‚ENABLE�INTERRUPTS�command�parameter�block�for�the�DC�INPUT�driver:+ENAB_DCI‚DC.Wƒ0’Returned�status�from�driver-ŠDC.WƒENAB_INT‹Enable�interrupts�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*£return�holds�the�actual�channel�statusCELEN_DCI‚EQU„*-ENAB_DCI‰Length�of�ENABLE�INTERRUPTS�parameter�block*D*‚ENABLE�INTERRUPTS�command�parameter�block�for�the�DC�INPUT�driver:+DISB_DCI‚DC.Wƒ0’Returned�status�from�driver.ŠDC.WƒDISAB_INTŠEnable�interrupts�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*£return�holds�the�actual�channel�status>DLEN_DCI‚EQU„*-DISB_DCI‰Length�of�DISABLE�INTERRUPTS�parameter*8*‚CLOSE�command�parameter�block�for�the�DC�INPUT�driver:)CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLKŠNEXTWBŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES 9HEAD†DC.BƒCR,LF,LF,'MVME620�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB1MESS1…DC.Bƒ'…Number�of�the�channel�to�convertˆ>�'MESS1E„EQU„*-1ŠNEXTWB(MESS2…DC.Bƒ'…Enter�one�of�the�above...�'MESS2E„EQU„*-1ŠNEXTWB?MESS4…DC.BƒCR,LF,LF,'…0�=�READ�THE�CURRENT�INPUT�STATUS.',CR,LFMESS4E„EQU„*-1ŠNEXTWB0MESS5…DC.Bƒ'…1�=�ENABLE�FOR�AN�INTERRUPT.',CR,LFMESS5E„EQU„*-1ŠN EXTWBMESS6…DC.Bƒ'…2�=�QUIT.',CR,LFMESS6E„EQU„*-1ŠNEXTWB4MESS9…DC.BƒCR,LF,'STATUS�OF�ALL�CHANNELS�(ASCII)�=�'MESS9E„EQU„*-1ŠNEXTWB2MESS10„DC.BƒCR,LF,'<<<�Starting�command�>>>',CR,LFMESS10EƒEQU„*-1ŠNEXTWB1MESS11„DC.BƒCR,LF,'<<<�Command�done�>>>',CR,LF,LFMESS11EƒEQU„*-1ŠNEXTWBŠPAGE,BADOPN„DC.BƒCR,LF,'***�OPEN�ABORTED�***�--�'BADOPNEƒEQU„*-1ŠNEXTWB8BADEN…DC.BƒCR,LF,'***�ENABLE�INTERRRUPT�ABORTED�***�--�'BADENE„EQU„*-1ŠNEXTWB:BADDIS„DC.BƒCR,LF,'***�DISABLE�INTERRRUPT�ABORTED�***�--�'BADDISEƒEQU„*-1ŠNEXTWB4BADREADƒDC.BƒCR,LF,'***�READ�STATUS�ABORTED�***�--�'BADREADE‚EQU„*-1ŠNEXTWB-BADCLS„DC.BƒCR,LF,'***�CLOSE�ABORTED�***�--�'BADCLSEƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…EQU„*-1ŠNEXTWBŠPAGE N*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODEPROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA) &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN.ŠOUTPUT�MESS1,MESS1E‡Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.L�D0��#0�OR.L�D0��#7�THEN.S ŒBRA�GETCHANŠENDI8ŠMOVE.W�D0,OPEN_DCI+6-PBA(A4)�Save�the�channel�number... <ŠLEA„BIT_NUMBER(PC),A0‚Convert�the�channel�number�(0-7)�into?ŠMOVE.B�(A0,D0.W),D0‡the�corresponding�bit�number�(1,2,4,8...).8ŠMOVE.W�D0,READ_DCI+4-PBA(A4)�Save�the�bit�mask�value...ŠMOVE.W�D0,ENAB_DCI+4-PBA(A4)ŠMOVE.W�D0,DISB_DCI+4-PBA(A4) N*-----------------------------------------------------------------------------*4*‰Get„0�=�READ�STATUS‚1�=�ENABLE�INTERRUPTSƒ2�=�QUIT*N*-----------------------------------------------------------------------------GETCLST'ŠOUTPUT�MESS4,MESS4E…Put�up�the�menu...ŠOUTPUT�MESS5,MESS5EŠOUTPUT�MESS6,MESS6EFGET_CHOICE‚OUTPUT�MESS2,MESS2E…Ask�the�user�to�enter�one�of�the�above. +ŠINPUT‚INPUTBUF,INPUTBUF+8�Get�their�choiceŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.W�D0��#0�OR.W�D0��#2�THEN.S�BRA.S�GET_CHOICEŠENDIŠPAGE* *‰0�=�Read�input�status�command:*ŠIF.B�D0��#0�THEN.L /ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> ŒBSR.L‚CLOSE_ALL>ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A06ŒLEA„READ_DCI(PC),A1‚Read�input�status�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#RLEN_DCI,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�READ_DCI(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADREAD,BADREADEƒ***�READ�STATUS�ABORTED�***ŒENDI ŒCLR.L‚D0<ŒMOVE.W�READ_DCI+4-PBA(A4),D0‚Get�the�status�value�returned.ŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŒOUTPUT�MESS9,MESS9EŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFE 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDIŠPAGE* *‰1�=�Enable�interrupts�command:*ŠIF.B�D0��#1�THEN.S /ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> ŒBSR.L‚CLOSE_ALL 3ŒMOVE.W�#$7F08,D0ˆEnable�interrupts,�WAKEUP�option,8*‡software�debounce�=�508mSec,�trigger�on�negative�edge.$ŒBSR.S‚OPEN_CHANˆGo�open�the�channel *(*‚Do�a�wait�until�the�driver�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒIF��THEN.SŽMOVE.W�ENAB_DCI(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)6ŽOUTPUT�BADEN,BADENE„***�ENABLE�INTERRUPTS�ABORTED�***ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start� over. ŠENDI **‰2�=�quit�command:*ŠIF.B�D0��#2�THEN.S �BRA.L�EXITŠENDI ŠBRA.L�GETCHAN�Go�start�over.ŠPAGEM*----------------------------------------------------------------------------**ƒOPEN�THE�CHANNEL*M*----------------------------------------------------------------------------OPEN_CHAN�LEA„CMRBLK(PC),A0ŠLEA„OPEN_DCI(PC),A1BŠMOVE.W�D0,OPEN_DCI+8-PBA(A4)‚Save�the�open�configuration�options.ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_DCI,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)+ŒOUTPUT�BADOPN,BADOPNE…***�OPEN�ABORTED�***ŒBRA.S‚SHOW_D0ŠENDIŠRTS M*----------------------------------------------------------------------------**ƒOUTPUT�THE�ERROR�CODE:*M*----------------------------------------------------------------------------:SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returnedŠBSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE EXIT:ŠBSR.S‚CLOSE_ALL +EXIT_OUT:�MOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1ŠPAGEN*-----------------------------------------------------------------------------**‚CLOSE�ALL�CHANNEL'S�ROUTINE:*N*-----------------------------------------------------------------------------CLOSE_ALL MOVE.W D0,-(A7) ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)6ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�DC�INPUT�channelŠTRAPƒ#1ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)ŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytes,ŒOUTPUT�BADCLS,BADCLSE…***�CLOSE�ABORTED�***ŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFEŒMOVE.W�(A7)+,D0‰Restore�stack.&ŒBRA.S‚EXIT_OUT‰Output�the�error�code.ŠENDI ŠMOVE.W�(A7)+,D0ŠRTS M*----------------------------------------------------------------------------*A*ƒTABLE�TO�CONVERT�THE�CHANNEL�NUMBER�(0-7)�TO�IT'S�CORRESPONDING**ƒBIT�MAPPED�VALUE�(1,2,4,8,16,32,64,128).*M*----------------------------------------------------------------------------$BIT_NUMBER‚DC.B‚1,2,4,8,16,32,64,128 ŠEND„PROGSTRTN'M615DRV TEST615 AF¿¿  TESTAC AFÈÈ  TEST615 LFÑÑ  TESTAC LFÚÚ  TEST615 LOÛ  TESTAC LOç  TEST615 SAP¿  TESTAC SAaa‰¨  =/*=/*†M615DRV.TEST615.AF=/*,=/*†TEST615�test�program�assembly�chain�file=/*-=/*†Default�argument�01�is�M615DRV.TEST615.LS=/*=/IFC \1ƒ=ARG�M615DRV.TEST615.LS=/ENDIF=/*4=ASM M615DRV.TEST615.SA,M615DRV.TEST615.RO,\1;RZ=100=/*{ I ncluded files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNN·=/*=/*†M615DRV.TESTAC.AF=/*;=/* Chain file to assemble ACO driver test routine 'TESTAC'=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M615DRV.TESTAC.LS=/*=/IFC \1ƒ=ARG�M615DRV.TESTAC.LS=/ENDIF=/*2=ASM M615DRV.TESTAC.SA,M615DRV.TESTAC.RO,\1;MRZ=70=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNN À=/*=/*†M615DRV.TEST615.LF=/*G=/*†This�chain�file�will�generate�the�TEST615�test�program�load�module.=/*5=/*†The�command�line�will�accept�arguments�as�follows=/*7=/*‹Argument�01ˆ\1�=�Output�file�link�listing�or�device=/*D=/*†The�following�shows�the�link�chain�sequence.‚In�this�example�theF=/*†printer�was�chosen�as�Argument�1,�however,�the�user�could�if�he�so2=/*†desired�have�requested�an�output�listing�file.=/*!=/*�=CHAIN�M615DRV.TEST615.LF�#PR=/*-=/*†Default�argument�01�is�M615DRV.TEST615.LL=/*=/IFC \1ƒ=ARG�M615DRV.TEST615.LL=/ENDIF=/*=/*"=LINK ,M615DRV.TEST615.LO,\1;HAMIXSEG SEG0:0,1,8,14 $000000ATTRIBUTES D PINPUT M615DRV.TEST615.ROLIB 0.&.UTILIB.ROEND=/*=ENDNNNNNÉ=/*=/*†M615DRV.TESTAC.LF=/*/=/* Link chain file to create M615DRV.TESTAC.LO=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M615DRV.TESTAC.LL=/*=/IFC \1ƒ=ARG�M615DRV.TESTAC.LL=/ENDIF=/* =LINK ,M615DRV.TESTAC.LO,\1;HMIX SEG SEG0:0INPUT M615DRV.TESTAC.ROEND=/*=ENDNNNN NNÒTEST8ÿÿÿÿÿ€SEG0 ÿÿÿÿ ÿÿÿÿÿACO1€ MVME615 Driver Test Program Number of the channel to convert  > Enter one of the above... Time (in milliseconds) for output pulse > 0 = OUTPUT ON. 1 = OUTPUT OFF. 2 = PULSE AN OUTPUT FOR A SPECIFIED TIME. 3 = READ THE CURRENT OUTPUT STATUS. 4 = QUIT. STATUS OF ALL CHANNELS (ASCII) = <<< Starting command >>> <<< Command done >>> *** OPEN ABORTED *** -- *** START OUTPUT ON ABORTED *** -- *** TURN OUTPUT OFF ABORTED *** -- *** START OUTPUT PULSE ABORTED *** -- *** READ STATUS ABORTED *** -- *** CLOSE ABORTED *** -- Error code returned in D0 = OúüŽIúûÂAúýv)HDAúýŽ)HHAúüæNBAúý‚)HDAúý¨)HHAúüÐNBAúüZ)H`AúüZ)HdAúüÖNBAúüDaÄ €m €o`º9@’9@¨Aú:09@š9@ 9@²Aúý )HDAúý¯)HHAúünNBAúý¢)HDAúý¯)HHAúüXNBAúý¢)HDAúýÉ)HHAúüBNBAúý¼)HDAúýÝ)HHAúü,NBAúýÐ)HDAúýØ)HHAúüNBAúüâ)HDAúüø)HHAúüNBAúûŠ)H`AúûŠ)HdAúüNBAúûtaô @m @o`¾ fva2Aúý¤)HDAúý·)HHAúû´NB0<€a0AúûÞCúü!I1|pCúÐEúÍa 2Cú ¬Eú ×a &Cú¸Eúµa Aú lCú È!I2|1Ip!I2| 1IpCúÿÔEú` >Aú ~áètáè Aú|RP0:v @kÿxAú `Cú Æ!I2|1Ip!I2| 1IpŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N****************************************************************************** ŠSECTION�DATA $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. 9ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�VME615�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was. 6NUMBER„DS.Lƒ2’Save�area�for�the�ASCII�value�of�STATUS.ŠPAGE N*******************************************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠDC.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address  CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�UnusedŠDC.Lƒ'ACO1'�Channel�nameŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�blockŠPAGE*8*‚OPEN�command�parameter�block�for�the�AC�OUTPUT�driver:+OPEN_ACO‚DC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)-ŠDC.WƒDEFAULTŒChannel�configuration�(Dynamic)6OLEN_ACO‚EQU„*-OPEN_ACO‰Length�of�OPEN�parameter�block*C*‚START�OUTPUT�ON�command�parameter�block�for�the�AC�OUTPUT�driver:)ON_ACO„DC.Wƒ0’Returned�status�from�driverŠDC.WƒON‘ON�command�code2ŠDC.Wƒ0’Bit�mask! �for�channels�to�turn�on�(Dynamic)2NLEN_ACO‚EQU„*-ON_ACO‹Length�of�ON�parameter�block*C*‚TURN�OUTPUT�OFF�command�parameter�block�for�the�AC�OUTPUT�driver:*OFF_ACOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOFF�Off�command�code3ŠDC.Wƒ0’Bit�mask�for�channels�to�turn�off�(Dynamic)4FLEN_ACO‚EQU„*-OFF_ACOŠLength�of�OFF�parameter�block*A*‚PULSED�OUTPUT�command�parameter�block�for�the�AC�OUTPUT�driver:*PON_ACOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒPULSEŽPulse�command�codeŠDC.Wƒ1’#�of�channels,ŠDC.Wƒ0’Channel�number�(Dynamically�changed)/ŠDC.Lƒ0’Time�of�pulse�in�milliseconds�(Dynamic)6PLEN_ACO‚EQU„*-PON_ACOŠLength�of�PULSE�parameter�block*F*‚READ�OUTPUT�STATUS�command�parameter�block�for�the�AC�OUTPUT�driver:+READ_ACO‚DC.Wƒ0’Returned�status�from�driver*ŠDC.WƒREAD_STATUSˆRead�status�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*£return�holds�the�actual�channel�status=RLEN_ACO‚EQU„*-READ_ACO‰Length�of�READ�STATUS�parameter�block*9*‚CLOSE�command�parameter�block�for�the�AC�OUTPUT�driver:)CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLKŠNEXTWBŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES 9HEAD†DC.BƒCR,LF,LF,'MVME615�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB1MESS1…DC.Bƒ'…Number�of�the�channel�to�convertˆ>�'MESS1E„EQU„*-1ŠNEXTWB(MESS2…DC.Bƒ'…Enter�one�of�the�above...�'MESS2E„EQU„*-1ŠNEXTWB8MESS3…DC.Bƒ'…Time�(in�milliseconds)�for�output�pulse�>�'MESS3E„EQU„*-1ŠNEXTWB+MESS4…DC.BƒCR,LF,LF,'…0�=�OUTPUT�ON.',CR,LFMESS4E„EQU„*-1ŠNEXTWB#MESS5…DC.Bƒ'…1�=�OUTPUT�OFF.',CR,LFMESS5E„EQU„*-1ŠNEXTWB=MESS6…DC.Bƒ'…2�=�PULSE�AN�OUTPUT�FOR�A�SPECIFIED�TIME.',CR,LFMESS6E„EQU„*-1ŠNEXTWB7MESS7…DC.Bƒ'…3�=�READ�THE�CURRENT�OUTPUT�STATUS.',CR,LFMESS7E„EQU„*-1ŠNEXTWB MESS8…DC.Bƒ'…4�=�QUIT.',CR,LF,LFMESS8E„EQU„*-1ŠNEXTWB4MESS9…DC.BƒCR,LF,'STATUS�OF�ALL�CHANNELS�(ASCII)�=�'MESS9E„EQU„*-1ŠNEXTWB2MESS10„DC.BƒCR,LF,'<<<�Starting�command�>>>',CR,LFMESS10EƒEQU„*-1ŠNEXTWB1MESS11„DC.BƒCR,LF,'<<<�Command�done�>>>',CR,LF,LFMESS11EƒEQU„*-1ŠNEXTWBŠPAGE,BADOPN„DC.BƒCR,LF,'***�OPEN�ABORTED�***�--�'BADOPNEƒEQU„*-1ŠNEXTWB6BADON…DC.BƒCR,LF,'***�START�OUTPUT�ON�ABORTED�***�--�'BADONE„EQU„*-1ŠNEXTWB7BADOFF„DC.BƒCR,LF,'***�TURN�OUTPUT�OFF�ABORTED�***�--�'BADOFFEƒEQU„*-1ŠNEXTWB:BADPLS„DC.BƒCR,LF,'***�START�OUTPUT�PULSE�ABORTED�***�--�'BADPLSEƒEQU„*-1ŠNEXTWB4BADREADƒDC.BƒCR,LF,'***�READ�STATUS�ABORTED�***�--�'BADREADE‚EQU„*-1ŠNEXTWB-BADCLS„DC.BƒCR,LF,'***�CLOSE�ABORTED�***�--�'BADCLSEƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…EQU„*-1ŠNEXTWBŠPAGE N*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODEPROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA) &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN.ŠOUTPUT�MESS1,MESS1E‡Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.L�D0��#0�OR.L�D0��#7�THEN.S ŒBRA�GETCHANŠENDI8ŠMOVE.W�D0,OPEN_ACO+6-PBA(A4)�Save�the�channel�number...ŠMOVE.W�D0,PON_ACO+6-PBA(A4) <ŠLEA„BIT_NUMBER(PC),A0‚Convert�the�channel�number�(0-7)�into?ŠMOVE.B�(A0,D0.W),D0‡the�corresponding�bit�number�(1,2,4,8...).6ŠMOVE.W�D0,ON_ACO+4-PBA(A4)�Save�the�bit�mask�value...ŠMOVE.W�D0,OFF_ACO+4-PBA(A4)ŠM" OVE.W�D0,READ_ACO+4-PBA(A4) N*-----------------------------------------------------------------------------*4*‰Get„0�=�OUTPUT�ON„1�=�OUTPUT�OFFƒ2�=�PULSED�OUTPUT*�3�=�READ�STATUS‚4�=�QUIT*N*-----------------------------------------------------------------------------GETCLST'ŠOUTPUT�MESS4,MESS4E…Put�up�the�menu...ŠOUTPUT�MESS5,MESS5EŠOUTPUT�MESS6,MESS6EŠOUTPUT�MESS7,MESS7EŠOUTPUT�MESS8,MESS8EFGET_CHOICE‚OUTPUT�MESS2,MESS2E…Ask�the�user�to�enter�one�of�the�above. +ŠINPUT‚INPUTBUF,INPUTBUF+8�Get�their�choiceŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.W�D0��#0�OR.W�D0��#4�THEN.S�BRA.S�GET_CHOICEŠENDIŠPAGE**‰0�=�Start�output�ON�command:*ŠIF.B�D0��#0�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A02ŒLEA„ON_ACO(PC),A1„Start�output�ON�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#NLEN_ACO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�ON_ACO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADON,BADONE…***�START�OUTPUT�ON�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰1�=�Turn�output�OFF�command:*ŠIF.B�D0��#1�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A03ŒLEA„OFF_ACO(PC),A1ƒTurn�output�OFF�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#FLEN_ACO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�OFF_ACO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)6ŽOUTPUT�BADOFF,BADOFFE„***�TURN�OUTPUT�OFF�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰2�=�PULSE�an�output�command:*ŠIF.B�D0��#2�THEN.L3ŒBSR„GET_TIME‰Get�the�pulse�duration�(milliseconds)+ŒMOVE.L�D3,PON_ACO+8-PBA(A4)�Store�the�time 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10E…<<<ƒStarting�commandƒ>>> 7ŒMOVE.W�#WAKEUP_O,D0…Use�the�WAKEUP�option�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A06ŒLEA„PON_ACO(PC),A1ƒStart�output�pulse�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#PLEN_ACO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1*(*ƒDo�a�wait�until�the�driver�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒIF��THEN.SŽMOVE.W�PON_ACO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4);ŽOUTPUT�BADREAD,BADREADEƒ***�START�OUTPUT�PULSE�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰3�=�READ�STATUS�command:*ŠIF.B�D0��#3�THEN.L /ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> ŒLEA„CMRBLK(PC),A00ŒLEA„READ_ACO(PC),A1‚Read�status�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#RLEN_ACO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�READ_ACO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADREAD,BADREADEƒ***�READ�STATUS�ABORTED�***ŒENDI ŒCLR.L‚D0;ŒMOVE.W�READ_ACO+4-PBA(A4),D0‚Get�the�status�value�returnedŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŒOUTPUT�MESS9,MESS9EŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFE 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI**‰4�=�quit�command:*ŠIF.B�D0�<EQ>�#4�THEN.S'�BSR.L‚CLOSE_ALLˆGo�close�all�channels. �BRA.L�EXITŠENDI ŠBRA.L�GETCHAN�Go�start�over.ŠPAGEM*----------------------------------------------------------------------------**ƒOPEN�THE�CHANNEL*M*-----------------------" -----------------------------------------------------OPEN_CHAN�LEA„CMRBLK(PC),A0ŠLEA„OPEN_ACO(PC),A1BŠMOVE.W�D0,OPEN_ACO+8-PBA(A4)‚Save�the�open�configuration�options.ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_ACO,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)+ŒOUTPUT�BADOPN,BADOPNE…***�OPEN�ABORTED�***ŒBRA.S‚SHOW_D0ŠENDIŠRTS M*----------------------------------------------------------------------------*+*‚GET�THE�TIME�DURATION�FOR�AN�OUTPUT�PULSE*M*----------------------------------------------------------------------------GET_TIMEŠOUTPUT�MESS3,MESS3EŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0 ŠBSR„ASCVAL ŠTST.L‚D3 ŠBEQ„GET_TIME+ŠIF.L�D3��#0�OR.L�D3��#$FFFF�THEN.S ŒBRA„GET_TIMEŠENDIŠAND.L‚#$0000FFFF,D3ŠRTS M*----------------------------------------------------------------------------**ƒOUTPUT�THE�ERROR�CODE:*M*----------------------------------------------------------------------------:SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returnedŠBSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE EXITŠBSR.S‚CLOSE_ALL"ŠMOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1ŠPAGEN*-----------------------------------------------------------------------------**‚CLOSE�ALL�CHANNEL'S�ROUTINE:*N*-----------------------------------------------------------------------------CLOSE_ALL MOVE.W D0,-(A7) ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)7ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�AC�OUTPUT�channelŠTRAPƒ#1ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4),ŒOUTPUT�BADCLS,BADCLSE…***�CLOSE�ABORTED�***ŒMOVE.W�(A7)+,D0‰Restore�stack.%ŒBRA.L‚SHOW_D0ŠOutput�the�error�code.ŠENDI ŠMOVE.W�(A7)+,D0ŠRTS M*----------------------------------------------------------------------------*A*ƒTABLE�TO�CONVERT�THE�CHANNEL�NUMBER�(0-7)�TO�IT'S�CORRESPONDING**ƒBIT�MAPPED�VALUE�(1,2,4,8,16,32,64,128).*M*----------------------------------------------------------------------------$BIT_NUMBER‚DC.B‚1,2,4,8,16,32,64,128 ŠEND„PROGSTRTNNNNNN# NB*„This�is�TESTAC,�a�relocatable�program�that�tests�the�ACO�driver.*$*„Copyrighted�1983�by�Motorola,�Inc.E**********************************************************************B*‚This�program�sets�up�for�task�ACO1�and�verifies�it�exists.�If�it;*‚does�it�proceeds�with�the�test,�if�not�it�trys�task�ACO2./*‚If�either�task�is�missing,�it�skips�the�test.*:*‚This�program�performs�the�following�tests�on�the�driver:*9*ˆTEST1‚-‚individually�opens�each�channel,�outputs�to�it,-*’checks�status,�turns�it�off,�checks�status, *’and�closes.9*ˆTEST2‚-‚individually�opens�each�channel,�outputs�to�it,1*’checks�status,�continues�until�all�are�on.�Then,*’individually�turns�off�each�channel,checks0*’status,�continues�until�all�are�off.�Turns�all%*’channels�back�on�for�the�next�test.7*ˆTEST3‚-‚closes�the�channels,�OPERATOR�must�check�they *’turned�off.4*ˆTEST4‚-‚opens�all�channels,�turns�all�channels�on,-*’delays,�turns�all�channels�off,�and�closes.9*ˆTEST5‚-‚individually�opens�each�channel,�commands�pulse*’output,�delays,�and�closes.7*ˆTEST6‚-‚opens�four�channels,�commands�pulse�output�of3*’different�lengths�to�each�simultaneously,�delays,*’closes�channels.;*ˆTEST7�-ƒopens�channel�two�with�queue�event�configuration,'*’pulses�output,�waits�for�queue�event,)*’verifies�message�sent,�closes�channels.:*ˆTEST8‚-‚opens�channel�one�with�wait�for�wake-up�config.,'*’pulses�output,�waits�for�wake-up,�and*’closes�channels.:*ˆTEST9‚-‚trys�output�ON�with�channels�closed�and�verifies*’error.3*’trys�output�OFF�with�channels�closed�and�verifies*’error./*’trys�checking�status�with�channels�closed�and*’verifies�error.,*’trys�pulse�output�with�channels�closed�and*’verifies�error.<*ˆTEST10�-‚trys�opening�invalid�channel�numbers�and�verifies3*’errors.�(ZERO�channels,�more�than�eight�channels,"*’channel�#�9,�same�two�channels).:*ˆTEST11�-‚opens�channel�and�trys�invalid�commands�(�0,�6,*’7,�>�8�)�and�verifies�errors. Y/bPjPrPzV‚\Š\’UšW¢PªY²ZºYÂRÊRÒWÚbâ=*ˆTEST12�-‚trys�opening�channels�when�they�are�already�opened*’and�verifies�error.*>*ˆIf�it�passed�these�tests�it�returns�to�the�top�to�set�up�for2*’task�ACO2.�If�this�was�for�task�ACO2,�it�sets�up$*’to�test�both�tasks�simultaneously.7*ˆIF�ALL�TESTS�ARE�SUCCESSFUL,�prints�message�attesting0*’to�that�fact.�If�any�test�fails,�ERROR�message$*’is�printed�and�test�is�terminated.*D********************************************************************‰PAGE*5IOADR0ƒEQU‡$F80000�VM02�base�mem�map�I/O�chan�address5IOADR1ƒEQU‡$FA0000�VM03�base�mem�map�I/O�chan�address7IOADR2ƒEQU‡$FE6000�VME110�base�mem�map�I/O�chan�address7IOADR3ƒEQU‡$F1C000�VME/10�base�mem�map�I/O�chan�address* ‰SECTIONƒ0*TEST…LEA‡STACK(PC),A7‰LEA‡INITIO(PC),A0.‰CLR.W…DUALFG-INITIO(A0)ƒclear�dual�test�flags‰CLR.W…DUALCK-INITIO(A0)**�SET�UP�A.S.Q.*!‰MOVE.L„#31,D0Žstage�command�code-‰LEA‡ASQBLOCK(PC),A0…stage�command�parameters.‰LEA‡TESTIRQ(PC),A1†initializes�addr.�of�async*‰MOVE.L„A1,ASQLA-ASQBLOCK(A0)‚service�rtn.‰TRAP†#1 ‰BNE‡FAULT11*‰MOVE.L„#'ACO1',D0(TNAME„LEA‡INITIO(PC),A0‡SET�UP�TASK�NAME‰MOVE.L„D0,ACOPAR-INITIO(A0)‰MOVE.L„D0,TMSG-INITIO(A0)*!TRYBTHƒLEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1†again‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*.‰LEA‡SMSG1(PC),A1ˆoutput�start�of�test�message‰LEA‡EMSG1(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*‰LEA‡INITIO(PC),A0‰LEA‡CLSCMD(PC),A1‰MOV# E.L„A1,CMDA-INITIO(A0)+‰MOVE.W„#CLSLNG,A1ŠINSURE�CHANNEL(S)�CLOSED$‰MOVE.W„A1,CMDL-INITIO(A0)‚TO�START.‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT16*‰PAGE* *…OPEN�THE�CHANNELS�INDIVIDUALLY*5TEST1„LEA‡SMSG2(PC),A1‡output�'open�&�output'�message‰LEA‡EMSG2(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A0*‰MOVE.W„#1,ONCMD1-INITIO(A0)�'ON'�bit�mask,‰MOVE.W„#1,OFFCMD1-INITIO(A0)�'OFF'�bit�mask2‰MOVE.W„#1,STATSHF-INITIO(A0)�status�req.�bit�mask;OPNLP„MOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL�(event�count�holds‰LEA‡INITIO(PC),A0‡channel�#�)+‰MOVE.W„D0,OPNCH-INITIO(A0)�channel�to�open‰LEA‡OPNCMDS(PC),A1,‰MOVE.L„A1,CMDA-INITIO(A0)‚parameters�to�CMR‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*+‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNEL�OPENED‰LEA‡ONCMD(PC),A1,‰MOVE.L„A1,CMDA-INITIO(A0)‚parameters�to�CMR ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*!‰LEA‡OPNLP(PC),A1ˆloop�back�addr.&‰LEA‡TEST1B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*%TEST1BƒLEA‡INITIO(PC),A0‡CHECK�STATUS/‰MOVE.W„STATSHF(PC),D0†move�channel�to�check�to1‰MOVE.W„D0,STAT-INITIO(A0)‚status�parameter�block‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*3‰MOVE.W„STAT(PC),D0‰does�status�check�with�bit�that"‰CMP.W…ONCMD1(PC),D0‡should�be�on? ‰BNE‡FAULT4*#‰LEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT5*‰LEA‡INITIO(PC),A0‡CHECK�STATUS/‰MOVE.W„STATSHF(PC),D0†move�channel�to�check�to1‰MOVE.W„D0,STAT-INITIO(A0)‚status�parameter�block‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*.‰MOVE.W„STAT(PC),D0‰does�status�check�show�bit#‰BNE‡FAULT4Žstill�on?�if�so,�error.*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST1B(PC),A1‡loop�back�addr.&‰LEA‡TEST1C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST1CƒLEA‡INITIO(PC),A0>‰ASL.W…ONCMD1-INITIO(A0)ƒshift�'ON'�channel�bit�mask�one�place/‰ASL.W…OFFCMD1-INITIO(A0)‚shift�'OFF'ƒ"…"ƒ"„"„"0‰ASL.W…STATSHF-INITIO(A0)‚shift�status‚"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP*‰PAGE*2*„OUTPUT�TO�CHANNELS�SEQUENTIALLY�UNTIL�ALL�ARE�ON*5TEST2„LEA‡SMSG3(PC),A1‡output�'output�to�all'�message‰LEA‡EMSG3(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A06‰MOVE.W„#1,ONCMD1-INITIO(A0)‚bit�mask�for�'ON'�channel9‰MOVE.W„#1,STATSHF-INITIO(A0)�bit�mask�for�status�channel)OPNLP2ƒMOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL‰LEA‡INITIO(PC),A0‰MOVE.W„D0,OPNCH-INITIO(A0)/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*+‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNEL�OPENED‰LEA‡ONCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP2(PC),A1‡loop�back�addr.&‰LEA‡TEST2A(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*1TEST2AƒLEA‡INITIO(PC),A0‡CHECK�STATUS�OF�CHANNELS‰MOVE.W„STATSHF(PC$ ),D0‰MOVE.W„D0,STAT-INITIO(A0)‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*&‰MOVE.W„STAT(PC),D0‰does�status�check?‰CMP.W…STATSHF(PC),D0 ‰BNE‡FAULT4*"‰LEA‡TEST2A(PC),A1‡loop�back�addr.&‰LEA‡TEST2B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST2BƒLEA‡INITIO(PC),A0>‰ASL.W…ONCMD1-INITIO(A0)ƒshift�'ON'�channel�bit�mask�one�place‰ORI‡#$10,CCRŒset�X�bit/‰ROXL.W„STATSHF-INITIO(A0)‚add�statusƒ"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP2*7TEST2CƒLEA‡SMSG39(PC),A1‡output�'turn�off�seq.'�message‰LEA‡EMSG39(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A08‰MOVE.W„#1,OFFCMD1-INITIO(A0)‚bit�mask�for�'OFF'�channel9‰MOVE.W„#1,STATSHF-INITIO(A0)�bit�mask�for�status�channel*)OPNLP3ƒLEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT5*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP3(PC),A1‡loop�back�addr.&‰LEA‡TEST2D(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*0TEST2DƒLEA‡INITIO(PC),A0‡CHECK�STATUS�OF�CHANNEL‰MOVE.W„STATSHF(PC),D0‰MOVE.W„D0,STAT-INITIO(A0)‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*&‰MOVE.W„STAT(PC),D0‰does�status�check? ‰BNE‡FAULT4*"‰LEA‡TEST2D(PC),A1‡loop�back�addr.&‰LEA‡TEST2E(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST2EƒLEA‡INITIO(PC),A0@‰ASL.W…OFFCMD1-INITIO(A0)‚shift�'OFF'�channel�bit�mask�one�place0‰ASL.W…STATSHF-INITIO(A0)‚shift�status‚"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP3*+TEST2FƒLEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNELS‰LEA‡ONCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST2F(PC),A1‡loop�back�addr.%‰LEA‡TEST3(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle**%**************************************ƒCLOSE�TEST–*%**************************************-TEST3„LEA‡SMSG4(PC),A1‡output�'close'�message‰LEA‡EMSG4(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*)TEST3AƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST3A(PC),A1‡loop�back�addr.%‰LEA‡TEST4(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE$*„TURN�ON�ALL�OUTPUTS,�THEN�TURN�OFF*9TEST4„LEA‡SMSG5(PC),A1‡output�'turn�on,�turn�off'�message‰LEA‡EMSG5(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15**TEST4AƒLEA‡INITIO(PC),A0‡OPEN�ALL�CHANNELS/‰LEA‡OPNCMD(PC),A1‡point�to�CMR�parameter�block‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*,‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNELS�OPENED‰LEA‡ONCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST4A(PC),A1‡loop�back�addr.&‰LEA‡TEST4B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle**TEST4BƒLEA‡INITIO(PC),A0‡TURN�OFF�CHANNELS‰LEA‡OFFCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰T$ RAP†#1 ‰BNE‡FAULT5*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST4B(PC),A1‡loop�back�addr.%‰LEA‡TEST5(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE*„PULSE�EACH�OUTPUT�IN�TURN*2TEST5„LEA‡SMSG6(PC),A1‡output�'pulse�each'�message‰LEA‡EMSG6(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0‰CLR.W…0(A0)�initialize�evntcnt)OPNLP4ƒMOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block+‰MOVE.W„D0,OPNCH-INITIO(A0)�channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)�channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP4(PC),A1‡loop�back�addr.&‰LEA‡TEST5A(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*)TEST5AƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST5A(PC),A1‡loop�back�addr.&‰LEA‡TEST5B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST5BƒLEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP4*‰PAGE#*„PULSE�FOUR�OUTPUTS�SIMULTANEOUSLY*6TEST6„LEA‡SMSG32(PC),A1†output�'pulse�simult.'�message‰LEA‡EMSG32(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1500,A0Œ1500�MS‰TRAP†#1 ‰BNE‡FAULT15*&TEST6AƒLEA‡INITIO(PC),A0‡OPEN�CHANNELS‰LEA‡OPNCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSTWO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#PLSTLG,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST6A(PC),A1‡loop�back�addr.&‰LEA‡TEST6B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST6BƒMOVE.L„#21,D0ŽDELAY‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*)TEST6CƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST6C(PC),A1‡loop�back�addr.%‰LEA‡TEST7(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE+*„PULSE�OUTPUT�TWO�AND�GENERATE�QUEUE�EVENT*6TEST7„LEA‡SMSG7(PC),A1‡output�'pulse�output�2'�message‰LEA‡EMSG7(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST7AƒLEA‡RCVBUF(PC),A0‡ensure�RCVBUF�zeroed�out‰MOVE.L„#0,0(A0)‰MOVE.L„#0,4(A0)‰MOVE.L„#0,8(A0)*‰LEA‡INITIO(PC),A09‰MOVE.W„#0,OPNCNF-INITIO(A0)�set�up�config.�(queue�event)‰MOVE.W„#2,D0�OPEN�CHANNEL�TWO+‰MOVE.W„D0,OPNCH-INITIO(A0)‚channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)‚channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*+WAITQ„MOVE.L„#36,D0Žrequest�wait�for�event.$‰TRAP†#1’to�be�issued�by�ACO�driver. ‰BNE‡FAULT13*4‰MOVE.L„RCVBUF(PC),D0‡verify�message�returned�by�ASQ4‰CMP.L…#$0C010002,D0‡$0C01�� ‰BNE‡FAULT6‰MOVE.L„RCVBUF+4(PC),D0‰CMP.L…ACOPAR(PC),D0‡ACO-ID ‰BNE‡FAU% LT6‰MOVE.L„RCVBUF+8(PC),D0,‰AND.L…#$FFFFFF00,D0‡mask�off�low�order�byte0‰CMP.L…#IOADR0,D0ŠVM02�memory�mapped�I/O�address ‰BEQ.S…TEST710‰CMP.L…#IOADR1,D0ŠVM03�memory�mapped�I/O�address ‰BEQ.S…TEST722‰CMP.L…#IOADR2,D0ŠVME110�memory�mapped�I/O�address ‰BEQ.S…TEST732‰CMP.L…#IOADR3,D0ŠVME/10�memory�mapped�I/O�address ‰BNE‡FAULT6*‰LEA‡SMSG43(PC),A1‰LEA‡EMSG43(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST71ƒLEA‡SMSG40(PC),A1‰LEA‡EMSG40(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST72ƒLEA‡SMSG41(PC),A1‰LEA‡EMSG41(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST73ƒLEA‡SMSG42(PC),A1‰LEA‡EMSG42(PC),A2 ‰BSR‡MSGOUT2TEST74ƒLEA‡SMSG38(PC),A1‡output�'asq�verified'�msg‰LEA‡EMSG38(PC),A2 ‰BSR‡MSGOUT*"‰LEA‡TEST7A(PC),A1‡loop�back�addr.&‰LEA‡TEST7B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*)TEST7BƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST7B(PC),A1‡loop�back�addr.&‰LEA‡TEST7C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST7CƒMOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰PAGE'*…PULSE�OUTPUT�ONE�AND�GENERATE�WAKE-UP3TEST8„LEA‡SMSG8(PC),A1‡output�'pulse�led�1'�message‰LEA‡EMSG8(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST8AƒLEA‡INITIO(PC),A0‡point�to�CMR�para.�block5‰MOVE.W„#1,OPNCNF-INITIO(A0)�set�up�config.�(wake-up)‰MOVE.W„#1,D0�OPEN�CHANNEL�ONE+‰MOVE.W„D0,OPNCH-INITIO(A0)‚channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)‚channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*-WAITW„MOVE.L„#19,D0Žrequest�wait�for�wake-up.$‰TRAP†#1’to�be�issued�by�ACO�driver. ‰BNE‡FAULT130‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST8A(PC),A1‡loop�back�addr.&‰LEA‡TEST8B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*)TEST8BƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST8B(PC),A1‡loop�back�addr.&‰LEA‡TEST8C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST8CƒLEA‡INITIO(PC),A0‡restore�default�configuration ‰MOVE.W„#$8000,OPNCNF-INITIO(A0)2‰MOVE.W„#0,OPNCH-INITIO(A0)�restore�channel�select1‰MOVE.W„#1,STAT-INITIO(A0)‚restore�status�channel3‰MOVE.W„#1,OFFCMD1-INITIO(A0)‚restore�off�cmd�chan.*‰PAGE#*„TRY�COMMANDS�WITH�CHANNELS�CLOSED7TEST9„LEA‡SMSG9(PC),A1‡output�'try�with�closed'�message‰LEA‡EMSG9(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST9AƒLEA‡INITIO(PC),A0‡OUTPUT�TO�CLOSED�CHANNEL‰LEA‡ONCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1)‰MOVE.W„ONCMD(PC),D0ˆread�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT2 ‰LEA‡SMSG12(PC),A1‡output�ok�msg‰LEA‡EMSG12(PC),A2 ‰BSR‡MSGOUT*#‰LEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„OFFCMD(PC),D0‡read�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT5‰LEA‡SMSG14(PC),A1‡off�ok�msg‰LEA‡EMSG14(PC),A2 ‰BSR‡MSGOUT*‰LEA‡INITIO(PC),A0‡CHECK�STATUS‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1+‰MOVE.W„STATCMD(PC),D0†read�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT3 ‰LEA‡SMSG16(PC),A1‡status�ok�msg‰LEA‡EMSG16(PC),A2 ‰BSR‡MSGOUT% *‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1(‰MOVE.W„PLSO(PC),D0‰read�returned�status(‰CMP.W…#$F6,D0�verify�correct�error�code ‰BNE‡FAULT10*"‰LEA‡TEST9A(PC),A1‡loop�back�addr.&‰LEA‡TEST9B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*%TEST9BƒLEA‡SMSG18(PC),A1‡pulse�ok�msg‰LEA‡EMSG18(PC),A2 ‰BSR‡MSGOUT*‰PAGE*ƒTRY�TO�OPEN�INVALID�CHANNELS6TEST10ƒLEA‡SMSG11(PC),A1‡output�'try�invalid�channels'‰LEA‡EMSG11(PC),A2 ‰BSR‡MSGOUT0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*3TEST10A‚LEA‡INITIO(PC),A0‡TRY�TO�OPEN�ZERO�CHANNELS‰LEA‡OPNCH0(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNCHL,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNCH0(PC),D0‡read�cmd�status‰CMP.W…#$F7,D0 ‰BNE‡FAULT7*3‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�MORE�THAN�8�CHANNELS‰LEA‡OPNMOR(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNML,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNMOR(PC),D0‡read�cmd�status‰CMP.W…#$F7,D0 ‰BNE‡FAULT7*,‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�CHANNEL�#�>�8‰LEA‡OPNCH9(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNC9L,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNCH9(PC),D0‡read�cmd�status‰CMP.W…#$F6,D0 ‰BNE‡FAULT7*0‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�SAME�TWO�CHANNELS‰LEA‡OPNTW(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNTL,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1$‰MOVE.W„OPNTW(PC),D0ˆread�cmd�status‰CMP.W…#$FE,D0 ‰BNE‡FAULT7*#‰LEA‡TEST10A(PC),A1†loop�back�addr.'‰LEA‡TEST10B(PC),A2†continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST10B‚LEA‡SMSG36(PC),A1‡output�'invalid�channels�ok'‰LEA‡EMSG36(PC),A2 ‰BSR‡MSGOUT*‰PAGE*„TRY�TO�USE�INVALID�COMMANDS*2TEST11ƒLEA‡SMSG25(PC),A1‡output�'try�invalid�cmds'‰LEA‡EMSG25(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*&TEST11A‚LEA‡INITIO(PC),A0‡OPEN�CHANNEL‰MOVE.W„#1,OPNCH-INITIO(A0)‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�0‰LEA‡INVCM0(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM0(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�6‰LEA‡INVCM6(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM6(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�7‰LEA‡INVCM7(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM7(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*&‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�>�8‰LEA‡INVCM9(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM9(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*#‰LEA‡TEST11A(PC),A1†loop�back�addr.'‰LEA‡TEST11B(PC),A2†continue�on�forward‰BRA‡FLOP�test�for�toggle*-TEST11B‚LEA‡SMSG26(PC),A1‡invalid�cmds�ok�msg‰LEA‡EMSG26(PC),A2 ‰BSR‡MSGOUT*‰PAGE*„TRY�OPEN�AND�ALREADY�OPENED9TEST12ƒLEA‡SMSG20(PC),A1†output�'try�with�opened'�message‰LEA‡EMSG20(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*6TEST12A‚LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block(‰MOVE.W„#0,OPNCH-INITIO(A0)�OPEN�CHANNEL‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block‰LEA‡OPNCMDS(PC)& ,A1)‰MOVE.L„A1,CMDA-INITIO(A0)‚TRY�OPEN�again‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1+‰MOVE.W„OPNCMDS(PC),D0‡read�returned�status‰CMP.W…#$FE,D0 ‰BNE.S…FAULT1*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*#‰LEA‡TEST12A(PC),A1†loop�back�addr.%‰LEA‡TESTC(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*1**************************************************„TEST�COMPLETED�*1************************************************* TESTC„LEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*1‰LEA‡SMSG23(PC),A1†output�'test�complete'�message‰LEA‡EMSG23(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1†space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*#NEXT…MOVE.W„DUALFG(PC),D0‡flag�set? ‰BNE‡TERM.NEXTA„MOVE.L„ACOPAR(PC),D0‡try�for�second�task‰CMP.L…#'ACO1',D0‰BNE‡TERMA�done‰MOVE.L„#'ACO2',D0‰BRA‡TNAME�set�up�second�task*‰PAGE*#FAULT1ƒLEA‡SMSG22(PC),A1‡open�error‰LEA‡EMSG22(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT2ƒLEA‡SMSG13(PC),A1‡output�error‰LEA‡EMSG13(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT3ƒLEA‡SMSG17(PC),A1‡status�error‰LEA‡EMSG17(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM+FAULT4ƒLEA‡SMSG28(PC),A1‡status�check�error‰LEA‡EMSG28(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM"FAULT5ƒLEA‡SMSG15(PC),A1‡off�error‰LEA‡EMSG15(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM*FAULT6ƒLEA‡SMSG10(PC),A1‡ASQ�message�error‰LEA‡EMSG10(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM.FAULT7ƒLEA‡SMSG21(PC),A1‡invalid�channel�error‰LEA‡EMSG21(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM$FAULT8ƒLEA‡SMSG33(PC),A1‡close�error‰LEA‡EMSG33(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM.FAULT9ƒLEA‡SMSG27(PC),A1‡invalid�cmd�error�msg‰LEA‡EMSG27(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT10‚LEA‡SMSG19(PC),A1‡pulse�error‰LEA‡EMSG19(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM#FAULT11‚LEA‡SMSG30(PC),A1‡ASQ�error‰LEA‡EMSG30(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TERM#FAULT12‚LEA‡SMSG29(PC),A1‡ASQ�error‰LEA‡EMSG29(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM6FAULT13‚LEA‡SMSG31(PC),A1‡WAKE-UP�or�QUEUE�EVENT�error‰LEA‡EMSG31(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM2FAULT14‚LEA‡SMSG34(PC),A1‡IOS�(trap�#2)�call�error‰LEA‡EMSG34(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM*FAULT15‚LEA‡SMSG35(PC),A1‡call�delay�error‰LEA‡EMSG35(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM/FAULT16‚LEA‡SMSG37(PC),A1‡non-existant�task�msg‰LEA‡EMSG37(PC),A2 ‰BSR.S…MSGOUT(‰LEA‡DUALFG(PC),A0‡set�flag�to�eliminate‰ADD.W…#1,(A0)�dual�test ‰BRA‡NEXTA**„DE-ACTIVATE�SELF*0TERMA„LEA‡INITIO(PC),A0‡test�for�dual�board�test‰TST.W…DUALFG-INITIO(A0) ‰BNE.S…TERM4‰MOVE.W„#1,DUALFG-INITIO(A0)‚set�up�for�dual�bd�test‰MOVE.W„#1,DUALCK-INITIO(A0)!‰MOVE.L„#'ACO1',ACOPAR-INITIO(A0)*‰MOVE.L„#'ACO1',TMSG-INITIO(A0)‚set�up�msg‰MOVE.W„#'&2',TMSG+4-INITIO(A0) ‰BRA‡TRYBTH*%TERM…MOVE.L„#32,D0ŽDE-ALLOCATE�A.S.Q.‰TRAP†#1**‰MOVE.L„#15,D0ŽNOW�DE-ACTIVATE�SELF�(EXIT)‰TRAP†#1**„MESSAGE�OUTPUT�SUBROUTINE*/MSGOUTƒLEA‡MSG(PC),A0Šoutput�message�pointed�to(‰MOVE.L„A1,X1-MSG(A0)‡by�A1,�ended�by�A2‰MOVE.L„A2,X2-MSG(A0)‰TRAP†#2 ‰BNE‡FAULT14‰RTS*1FLOP…LEA‡INITIO(PC),A0‡toggle�between�ACO1�&�ACO2‰MOVE.W„DUALCK-INITIO(A0),D0 ‰BEQ.S…FLOP2�continue�on�if�zero‰CMP.W…#1,D0�see�if�=�1 ‰BNE.S…FLOP11‰MOVE.W„#2,DUALCK-INITIO(A0)‚is�=�1,�set�up�for�2!‰MOVE.L„#'ACO2',ACOPAR-INITIO(A0)‰JMP‡(A1)�loop�back6FLOP1„MOVE.W„#1,DUALCK-INITIO(A0)‚is�=�2,�set�up�for�1!‰MOVE.L„#'ACO1',ACOPAR-INITIO(A0))FLOP2„JMP‡(A2)�continue�on�with�next�test*-*ƒMOVE�THE�ASQ�MESSAGE�FROM�THE�ASQ�TO�RCVBUF*8TESTIRQ‚EQU‡*‰entry�point�moving�data�from�ASQ�to�RCVBUF!‰MOVE.L„#34,D0„stage�command�code‰LEA‡RCVBUF(PC),A0‰TRAP†#1 ‰BNE‡FAULT12*„RETURN�FROM�EVENT!‰MOVE.L„#37,D0„stage�command�code ‰MOVE.W„#1,A0‰TRAP†#1*‰PAGE**„CMR�parameter�block*INITIOƒDC.B†7,0,0,0ACOPARƒDC.L†'ACO1'„TASK�NAME ‰DC.L†0,0,0*CMDA…DC.L†0‰address�of�ACO�parameter�blockCMDL…DC.W†0‰command�length*& *„A.S.Q.�parameter�block*ASQBLOCK�EQU‡*‰DC.L†0‰task�name‰DC.L†0‰dummy�field*‰DC.B†5‰ASQ�&�ASR�enabled�=�initial�status"‰DC.B†16ˆlength�of�message�for�ASQ‰DC.L†16ˆstorage�for�4�events?ASQLA„DC.L†TESTIRQƒlogical�address�of�target�task�async�svc�rtn‰DC.L†0‰dummy�fieldASQLNGƒEQU‡*-ASQBLOCK*0*„ACO�parameter�block�to�open�individual�channel*OPNCMDS‚DC.W†0‰returned�status‰DC.W†1‰OPEN�command�code‰DC.W†1‰open�1�channelOPNCH„DC.W†0‰channel�#/OPNCNFƒDC.W†$8000…Default�channel�configurationOPNLNGS‚EQU‡*-OPNCMDS�length***„ACO�parameter�block�to�open�ALL�channels*OPNCMDƒDC.W†0‰returned�status‰DC.W†1‰OPEN�command�code‰DC.W†8‰open�8�channels*‰DC.W†0,$8000ƒCHAN�0,default�configuration‰DC.W†1,$8000ƒCHAN�1,ƒ"‰"‰DC.W†2,$8000ƒCHAN�2,ƒ"‰"‰DC.W†3,$8000ƒCHAN�3,ƒ"‰"‰DC.W†4,$8000ƒCHAN�4,ƒ"‰"‰DC.W†5,$8000ƒCHAN�5,ƒ"‰"‰DC.W†6,$8000ƒCHAN�6,ƒ"‰"‰DC.W†7,$8000ƒCHAN�7,ƒ"‰"OPNLNGƒEQU‡*-OPNCMD‚length*#*ƒparameter�block�for�CLOSE�command*CLSCMDƒDC.W†0‰returned�status‰DC.W†2‰CLOSE�command(CLSLNGƒEQU‡*-CLSCMD‚close�command�length*$*…ACO�parameter�block�for�ON�command* ONCMD„EQU‡*‰DC.W†0‰returned�command�status‰DC.W†3‰OUTPUT�ON�command,ONCMD1ƒDC.W†1‰bit�mask�of�channel�to�turn�ON* ONCMDAƒEQU‡*‰DC.W†0‰returned�command�status‰DC.W†3‰OUTPUT�ON�command,‰DC.W†$00FF…bit�mask�to�turn�ON�all�channels*%*…ACO�parameter�block�for�OFF�command* OFFCMDƒEQU‡*&‰DC.W†0‰return�command�status�location‰DC.W†4‰OFF�command.OFFCMD1‚DC.W†1‰bit�mask�of�channel�to�turn�OFF* OFFCMDA‚EQU‡*&‰DC.W†0‰return�command�status�location‰DC.W†4‰OFF�command-‰DC.W†$00FF…bit�mask�to�turn�OFF�all�channels*$*„parameter�block�for�STATUS�command* STATCMD‚EQU‡*‰DC.W†0‰returned�command�status‰DC.W†5‰STATUS�command2STAT…DC.W†1‰bit�mask�&�read�status�of�channels�0-7*:*„ACO�parameter�block�to�do�1000�ms�PULSE�on�selected�chan*PLSO…DC.W†0‰returned�cmd�status‰DC.W†8‰PULSE�command�code‰DC.W†1‰one�channelPLSO1„DC.W†1‰pulse�channel�#‰DC.L†500‡500�ms�pulse*7*„parameter�block�to�PULSE�four�channels�simultaneously*!PLSTWOƒDC.W†0‰returned�cmd�status‰DC.W†8‰PULSE�command�code‰DC.W†4‰four�channels‰DC.W†4‰chan.�#�4‰DC.L†250‡250�ms‰DC.W†5‰chan.�#�5‰DC.L†500‡500�ms‰DC.W†6‰chan.�#�6‰DC.L†750‡750�ms‰DC.W†7‰chan.�#�7‰DC.L†1000†1000�msPLSTLGƒEQU‡*-PLSTWO*"*„INVALID�CHANNEL�parameter�blocks*!OPNCH0ƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�command�code‰DC.W†0‰open�zero�channels‰DC.W†0‰channel�0‰DC.W†$8000…config.OPNCHLƒEQU‡*-OPNCH0*!OPNCH9ƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†1‰open�one�channel‰DC.W†9‰open�channel�#�9‰DC.W†$8000…config.OPNC9LƒEQU‡*-OPNCH9* OPNTW„DC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†3‰open�three�chan.‰DC.W†1,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.OPNTL„EQU‡*-OPNTW*!OPNMORƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†9‰open�9�channels‰DC.W†0,$8000ƒchan,�config.‰DC.W†1,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.‰DC.W†3,$8000ƒchan,�config.‰DC.W†4,$8000ƒchan,�config.‰DC.W†5,$8000ƒchan,�config.‰DC.W†6,$8000ƒchan,�config.‰DC.W†7,$8000ƒchan,�config.‰DC.W†8,$8000ƒchan,�config.OPNML„EQU‡*-OPNMOR*#*…INVALID�COMMANDS�parameter�blocks*!INVCM0ƒDC.W†0‰returned�cmd�status‰DC.W†0‰invalid�command�0*!INVCM6ƒDC.W†0‰returned�cmd�status‰DC.W†6‰invalid�command�6*!INVCM7ƒDC.W†0‰returned�cmd�status‰DC.W†7‰invalid�command�7*!INVCM9ƒDC.W†0‰returned�cmd�status"‰DC.W†9‰invalid�cmd�greater�than�8**„IOS�MESSAGE�parameter�block*MSG†DC.B†0‰Data�xfer�code=0‰DC.B†2‰Write�data‰DC.W†0‰Options�-�none‰DC.B†0‰Status ‰DC.B†6‰LUN‰DC.W†0‰reserved‰DC.L†0‰random�record�countX1‡DC.L†0‰bfr�start�addr.X2‡DC.L†0‰bfr�end�addr.‰DC.L†0‰length�of�data�xfer ‰DC.L†0‰completion/service�addr.*‰PAGE *„MESSAGES*6SMSG1„DC.W†'**********�AC�OUTPUT�TEST�PROGRA' M�******�'TMSG…DC.W†'ACO1‚' EMSG1„EQU‡*-1*8SMSG2„DC.W†'‚OPEN�&�OUTPUT�TO�EACH�CHANNEL�INDIVIDUALLY' EMSG2„EQU‡*-1*9SMSG3„DC.W†'‚OPEN�&�OUTPUT�EACH�CHANNEL�UNTIL�ALL�ARE�ON' EMSG3„EQU‡*-1*5SMSG4„DC.W†'‚CLOSE�CHANNELS,�OUTPUTS�SHOULD�TURN�OFF' EMSG4„EQU‡*-1*0SMSG5„DC.W†'‚TURN�ON�ALL�OUTPUTS,�THEN�TURN�OFF' EMSG5„EQU‡*-1*'SMSG6„DC.W†'‚PULSE�EACH�OUTPUT�IN�TURN' EMSG6„EQU‡*-1*5SMSG7„DC.W†'‚PULSE�OUTPUT�2�AND�GENERATE�QUEUE�EVENT' EMSG7„EQU‡*-1*1SMSG8„DC.W†'‚PULSE�OUTPUT�1�AND�GENERATE�WAKE-UP' EMSG8„EQU‡*-1*/SMSG9„DC.W†'‚TRY�COMMANDS�WITH�CHANNELS�CLOSED' EMSG9„EQU‡*-1**SMSG10ƒDC.W†'‚INVALID�ASQ�MESSAGE�-�ERROR'EMSG10ƒEQU‡*-1*+SMSG11ƒDC.W†'‚TRY�TO�OPEN�INVALID�CHANNELS'EMSG11ƒEQU‡*-1*4SMSG12ƒDC.W†'‚CALL�OUTPUT�AND�CHANNELS�CLOSED�-�OK!'EMSG12ƒEQU‡*-1*"SMSG13ƒDC.W†'‚CALL�OUTPUT�-�ERROR'EMSG13ƒEQU‡*-1*1SMSG14ƒDC.W†'‚CALL‚OFFƒAND�CHANNELS�CLOSED�-�OK!'EMSG14ƒEQU‡*-1*SMSG15ƒDC.W†'‚CALL�OFF�-�ERROR'EMSG15ƒEQU‡*-1*4SMSG16ƒDC.W†'‚CALL�STATUS�AND�CHANNELS�CLOSED�-�OK!'EMSG16ƒEQU‡*-1*"SMSG17ƒDC.W†'‚CALL�STATUS�-�ERROR'EMSG17ƒEQU‡*-1*3SMSG18ƒDC.W†'‚CALL�PULSE‚AND�CHANNELS�CLOSED�-�OK!'EMSG18ƒEQU‡*-1*!SMSG19ƒDC.W†'‚CALL�PULSE�-�ERROR'EMSG19ƒEQU‡*-1*4SMSG20ƒDC.W†'‚TRY�CALL�OPEN�AND�ALREADY�OPENED�-OK!'EMSG20ƒEQU‡*-1*&SMSG21ƒDC.W†'‚INVALID�CHANNEL�-�ERROR'EMSG21ƒEQU‡*-1* SMSG22ƒDC.W†'‚CALL�OPEN�-�ERROR'EMSG22ƒEQU‡*-1*9SMSG23ƒDC.W†'‚******�TEST�COMPLETED�SUCCESSFULLY�*******'EMSG23ƒEQU‡*-1*SMSG24ƒDC.W†'‚'EMSG24ƒEQU‡*-1**SMSG25ƒDC.W†'‚TRY�TO�USE�INVALID�COMMANDS'EMSG25ƒEQU‡*-1**SMSG26ƒDC.W†'‚CALL„INVALID„COMMANDS„-‚OK!'EMSG26ƒEQU‡*-1*&SMSG27ƒDC.W†'‚INVALID�COMMAND�-�ERROR'EMSG27ƒEQU‡*-1*#SMSG28ƒDC.W†'‚STATUS�CHECK�-�ERROR'EMSG28ƒEQU‡*-1*"SMSG29ƒDC.W†'‚A.S.Q.�MOVE‚-�ERROR'EMSG29ƒEQU‡*-1*SMSG30ƒDC.W†'‚A.S.Q.�-�ERROR'EMSG30ƒEQU‡*-1*$SMSG31ƒDC.W†'‚WAKEUP�OR�QUEUE�ERROR'EMSG31ƒEQU‡*-1*9SMSG32ƒDC.W†'‚PULSE�CHANNELS�4,�5,�6,�&�7�SIMULTANEOUSLY'EMSG32ƒEQU‡*-1*!SMSG33ƒDC.W†'‚CALL�CLOSE�-�ERROR'EMSG33ƒEQU‡*-1*#SMSG34ƒDC.W†'‚TRAP�#�2�(IOS)�ERROR'EMSG34ƒEQU‡*-1*!SMSG35ƒDC.W†'‚CALL�DELAY�-�ERROR'EMSG35ƒEQU‡*-1**SMSG36ƒDC.W†'‚CALL„INVALID„CHANNELS„-‚OK!'EMSG36ƒEQU‡*-1*‰PAGE*:SMSG37ƒDC.W†'-�-�-�NON-EXISTANT�TASK/BOARD�-�-�-�-�-�-�-^'EMSG37ƒEQU‡*-1*&SMSG38ƒDC.W†'‚A.S.Q.�MESSAGE�VERIFIED'EMSG38ƒEQU‡*-1*-SMSG39ƒDC.W†'‚TURN�OFF�CHANNELS�SEQUENTIALLY'EMSG39ƒEQU‡*-1*SMSG40ƒDC.W†'‚VM02'EMSG40ƒEQU‡*-1*SMSG41ƒDC.W†'‚VM03'EMSG41ƒEQU‡*-1*SMSG42ƒDC.W†'‚VME110'EMSG42ƒEQU‡*-1*SMSG43ƒDC.W†'‚VME/10'EMSG43ƒEQU‡*-1*‰PAGE*EVNTCNT‚DS.W†1‰event�counter!STATSHF‚DS.W†1‰status�bit�shifter1DUALFGƒDS.W†1‰dual�board�test�flag(1=do�not�test) Enter one of the above... Time (in milliseconds) for output pulse > 0 = OUTPUT ON. 1 = OUTPUT OFF. 2 = PULSE AN OUTPUT FOR A SPECIFIED TIME. 3 = READ THE CURRENT OUTPUT STATUS. 4 = QUIT. STATUS OF ) ALL CHANNELS (ASCII) = <<< Starting command >>> <<< Command done >>> *** OPEN ABORTED *** -- *** START OUTPUT ON ABORTED *** -- *** TURN OUTPUT OFF ABORTED *** -- *** START OUTPUT PULSE ABORTED *** -- *** READ STATUS ABORTED *** -- *** CLOSE ABORTED *** -- Error code returned in D0 = OúüŽIúûÂAúýv)HDAúýŽ)HHAúüæNBAúý‚)HDAúý¨)HHAúüÐNBAúüZ)H`AúüZ)HdAúüÖNBAúüDaÄ €m €o`º9@’9@¨Aú:09@š9@ 9@²Aúý )HDAúý¯)HHAúünNBAúý¢)HDAúý¯)HHAúüXNBAúý¢)HDAúýÉ)HHAúüBNBAúý¼)HDAúýÝ)HHAúü,NBAúýÐ)HDAúýØ)HHAúüNBAúüâ)HDAúüø)HHAúüNBAúûŠ)H`AúûŠ)HdAúüNBAúûtaô @m @o`¾ fva2Aúý¤)HDAúý·)HHAúû´NB0<€a0AúûÞCúü!I1|pCúÐEúÍa 2Cú ¬Eú ×a &Cú¸Eúµa Aú lCú È!I2|1Ip!I2| 1IpCúÿÔEú` >Aú ~áètáè Aú|RP0:v @kÿxAú `Cú Æ!I2|1Ip!I2| 1Ip&OCë¶üDüCüOü1Bk07|2'|º~`(+ºØ„BsH.R«ºS‡lÿîBkV7|XBkZ7|\Bk^Bk`7|bBkdBkf7|hBkjBkl7|n'|º~`(+ºØ„BsHjR«ºS‡lÿî7|¦7|¨7|ª7|¬7|®7|?°7|²7|ÿ´7|’7|”7|–7|˜7|š7| œ7|@ž7|€ 7|ÿ¢7|€¤CèdpNB™QÈÿü1|ÊCúô!IˆPèÒzN¬ CèdpNB™QÈÿü1|ÊCúÐ!IˆPèÒzN¬ CèdpNB™QÈÿü1|ÊCú*!Iˆ/ Hk¶Hx/<PèÒzN¬ Þü *_`8&, ***** DC OUTPUT MODULE TEST PROGRAM ****** CèdpNB™QÈÿü1|ÊCú8!IˆPèÒzN¬ CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& HçœYOHk¶?|HkVp"<‡³N¬Þü Lß90+VHÀk gf`CèdpNB™QÈÿü1|ÊCú*!Iˆ/ Hk¶Hx/<PèÒzN¬ Þü *_` & NON-EXISTANT TASK - ` ÒCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `2&+ OPEN & OUTPUT TO EACH CHANNEL INDIVIDUALLY'|º~` 7|4 +ºS€7@60+¤HÀ7@8HçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß9€0+0HÀk gD`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL OPEN - ERROR(+ºØ„„�03HHÀ7@^HçœYOHk¶?|HkZp"<‡aN¬Þü Lß9€0+ZHÀk gD`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL OUT - ERRORHç˜p"<Ô (N¬L߀(+ºØ„„�03HHÀ7@jHçœYOHk¶?|Hkfp"<‡yáN¬Þü Lß9€0+jHÀ(+ºØ„„�23HHÁ��k g"`HçœUOHkºp"<""fïN¬\OLß9€(+ºØ„„�03HHÀ7@dHçœYOHk¶?|Hk`p"<‡^¶N¬Þü Lß9€HçœYOHk¶?|HkVp"<‡³N¬Þü Lß9€R«ºS‡lýÞCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `6&/ OPEN & OUTPUT TO EACH CHANNEL UNTIL ALL ARE ON'|º~` 7|4 +ºS€7@60+¤HÀ7@8HçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß9€(+ºØ„„�03HHÀ7@^HçœYOHk¶?|HkZp"<‡aN¬Þü Lß9€Hç˜p"<Ô (N¬L߀(+ºØ„„¤03HHÀ7@jHçœYOHk¶?|Hkfp"<‡yáN¬Þü Lß9€0+jHÀ(+ºØ„„¤23HHÁ��k g(`HçœUO +ºS€+/ p"<""fïN¬\OLß9€R«ºS‡lþÞCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `.&( CLOSE CHANNELS, OUTPUTS SHOULD TURN OFFHç˜p"<Ô (N¬LßHçœYOHk¶?|HkVp"<‡³N¬Þü Lß9Hç˜p"<Ô (N¬LßCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# TURN ON ALL OUTPUTS, THEN TURN OFF7|4B«¾'|º~`0(+ºØ„ +¾7€H. +ºR€(Ø„HsH.0+¤HÀ"_2€R«¾T«ºS‡lÿÎHçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß90+¢HÀ7@^HçœYOHk¶?|HkZp"<‡aN¬Þü Lß9Hç˜p"<Ô (N¬Lß0+¢HÀ7@dHçœYOHk¶?|Hk`p"<‡^¶N¬Þü Lß9HçœYOHk¶?|HkVp"<‡³N¬Þü Lß9CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ ` & PULSE EACH OUTPUT IN TURN'|º~`²7|4 +ºS€7@60+¤HÀ7@8HçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß9€7|p +ºS€7@rBkt7|ôvHçœYOHk¶?|Hklp"<‡eóN¬Þü Lß9€Hç˜p"<Ô (N¬L߀Hç˜p"<Ô (N¬L߀R«ºS‡lÿLHçœYOHk¶?|HkVp"<‡³N¬Þü Lß9CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `(&" TRY COMMANDS WITH CHANNELS CLOSEDHçœYOHk¶?|HkVp"<‡³N¬Þü Lß90+VHÀk^g`VCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL CLOSE AND CHANNELS CLOSED--OK`BCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL CLOSE - ERROR7|^HçœYOHk¶?|HkZp"<‡aN¬Þü Lß90+ZHÀk gZ`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL OUT AND CHANNELS CLOSED--OK`@CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL OUT - ERROR7|dHçœYOHk¶?|Hk`p"<‡^¶N¬Þü Lß90+`HÀk gZ`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL OFF AND CHANNELS CLOSED--OK`@CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL OFF - ERROR7|jHçœYOHk¶?|+ Hkfp"<‡yáN¬Þü Lß90+fHÀk gZ`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL STATUS AND CHANNELS CLOSED-OK`BCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL STATUS - ERROR7|p7|rBkt7| vHçœYOHk¶?|Hklp"<‡eóN¬Þü Lß90+lHÀk gZ`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL PULSE AND CHANNELS CLOSED--OK`BCèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL PULSE - ERROR7|47|60+¤HÀ7@8HçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß9CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `(&! TRY CALL OPEN AND ALREADY OPENED7|47|60+¤HÀ7@8HçœYOHk¶?|Hk0p"<‡dÖN¬Þü Lß90+0HÀk gZ`CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&# CALL OPEN AND CHANNELS ARE OPEN-OK`@CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `& CALL OPEN - ERRORCèdpNB™QÈÿü1|ÊCúò!IˆPèÒzN¬ CèdpNB™QÈÿü1|ÊCú!IˆPèÒzN¬ `*&#********* TEST COMPLETED **********CèdpNB™QÈÿü1|ÊCúñ !IˆPèÒzN¬ rzCë¶N¬aDCO2"_rN¬N¬XWÀH€HÀfCë¶üDüCüOü2`ïRNìNì"<hCûþNVCèdpNB™QÈÿü1|ÊCú,!Iˆ/ "nHQHx/<PèÒzN¬ Þü *_`& STATUS ERROR-BIT N^Nu"<BCûþNVÿè&O'|~d`"'|,<^`R«S†lÿøR«S‡lÿÜN^NuHç€pa‚$¼B€0*å€\€2€ KpŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N****************************************************************************** ŠSECTION�DATA $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. 9ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�VME625�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was. 6NUMBER„DS.Lƒ2’Save�area�for�the�ASCII�value�of�STATUS.ŠPAGE N*******************************************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠDC.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address  CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�UnusedŠDC.Lƒ'DCO1'�Channel�nameŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�blockŠPAGE*8*‚OPEN�command�parameter�block�for�the�DC�OUTPUT�driver:+OPEN_DCO‚DC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)-ŠDC.WƒDEFAULTŒChannel�configuration�(Dynamic)6OLEN_DCO‚EQU„*-OPEN_DCO‰Length�of�OPEN�parameter�block*C*‚START�OUTPUT�ON�command�parameter�block�for�the�DC�OUTPUT�driver:)ON_DCO„DC.Wƒ0’Returned�status�from�driverŠDC.WƒON‘ON�command�code2ŠDC.Wƒ0’Bit�mask�for�channels�to�turn�on�(Dynamic)2NLEN_DCO‚EQU„*-ON_DCO‹Length�of�ON�parameter�block*C*‚TURN�OUTPUT�OFF�command�parameter�block�for�the�DC�OUTPUT�driver:*OFF_DCOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOFF�Off�command�code3ŠDC.Wƒ0’Bit�mask�for�channels�to�turn�off�(Dynamic)4FLEN_DCO‚EQU„*-OFF_DCOŠLength�of�OFF�parameter�block*, A*‚PULSED�OUTPUT�command�parameter�block�for�the�DC�OUTPUT�driver:*PON_DCOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒPULSEŽPulse�command�codeŠDC.Wƒ1’#�of�channels,ŠDC.Wƒ0’Channel�number�(Dynamically�changed)/ŠDC.Lƒ0’Time�of�pulse�in�milliseconds�(Dynamic)6PLEN_DCO‚EQU„*-PON_DCOŠLength�of�PULSE�parameter�block*F*‚READ�OUTPUT�STATUS�command�parameter�block�for�the�DC�OUTPUT�driver:+READ_DCO‚DC.Wƒ0’Returned�status�from�driver*ŠDC.WƒREAD_STATUSˆRead�status�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*£return�holds�the�actual�channel�status=RLEN_DCO‚EQU„*-READ_DCO‰Length�of�READ�STATUS�parameter�block*9*‚CLOSE�command�parameter�block�for�the�DC�OUTPUT�driver:)CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLKŠNEXTWBŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES 9HEAD†DC.BƒCR,LF,LF,'MVME625�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB1MESS1…DC.Bƒ'…Number�of�the�channel�to�convertˆ>�'MESS1E„EQU„*-1ŠNEXTWB(MESS2…DC.Bƒ'…Enter�one�of�the�above...�'MESS2E„EQU„*-1ŠNEXTWB8MESS3…DC.Bƒ'…Time�(in�milliseconds)�for�output�pulse�>�'MESS3E„EQU„*-1ŠNEXTWB+MESS4…DC.BƒCR,LF,LF,'…0�=�OUTPUT�ON.',CR,LFMESS4E„EQU„*-1ŠNEXTWB#MESS5…DC.Bƒ'…1�=�OUTPUT�OFF.',CR,LFMESS5E„EQU„*-1ŠNEXTWB=MESS6…DC.Bƒ'…2�=�PULSE�AN�OUTPUT�FOR�A�SPECIFIED�TIME.',CR,LFMESS6E„EQU„*-1ŠNEXTWB7MESS7…DC.Bƒ'…3�=�READ�THE�CURRENT�OUTPUT�STATUS.',CR,LFMESS7E„EQU„*-1ŠNEXTWB MESS8…DC.Bƒ'…4�=�QUIT.',CR,LF,LFMESS8E„EQU„*-1ŠNEXTWB4MESS9…DC.BƒCR,LF,'STATUS�OF�ALL�CHANNELS�(ASCII)�=�'MESS9E„EQU„*-1ŠNEXTWB2MESS10„DC.BƒCR,LF,'<<<�Starting�command�>>>',CR,LFMESS10EƒEQU„*-1ŠNEXTWB1MESS11„DC.BƒCR,LF,'<<<�Command�done�>>>',CR,LF,LFMESS11EƒEQU„*-1ŠNEXTWBŠPAGE,BADOPN„DC.BƒCR,LF,'***�OPEN�ABORTED�***�--�'BADOPNEƒEQU„*-1ŠNEXTWB6BADON…DC.BƒCR,LF,'***�START�OUTPUT�ON�ABORTED�***�--�'BADONE„EQU„*-1ŠNEXTWB7BADOFF„DC.BƒCR,LF,'***�TURN�OUTPUT�OFF�ABORTED�***�--�'BADOFFEƒEQU„*-1ŠNEXTWB:BADPLS„DC.BƒCR,LF,'***�START�OUTPUT�PULSE�ABORTED�***�--�'BADPLSEƒEQU„*-1ŠNEXTWB4BADREADƒDC.BƒCR,LF,'***�READ�STATUS�ABORTED�***�--�'BADREADE‚EQU„*-1ŠNEXTWB-BADCLS„DC.BƒCR,LF,'***�CLOSE�ABORTED�***�--�'BADCLSEƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…EQU„*-1ŠNEXTWBŠPAGE N*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODEPROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA) &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN.ŠOUTPUT�MESS1,MESS1E‡Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.L�D0��#0�OR.L�D0��#7�THEN.S ŒBRA�GETCHANŠENDI8ŠMOVE.W�D0,OPEN_DCO+6-PBA(A4)�Save�the�channel�number...ŠMOVE.W�D0,PON_DCO+6-PBA(A4) <ŠLEA„BIT_NUMBER(PC),A0‚Convert�the�channel�number�(0-7)�into?ŠMOVE.B�(A0,D0.W),D0‡the�corresponding�bit�number�(1,2,4,8...).6ŠMOVE.W�D0,ON_DCO+4-PBA(A4)�Save�the�bit�mask�value...ŠMOVE.W�D0,OFF_DCO+4-PBA(A4)ŠMOVE.W�D0,READ_DCO+4-PBA(A4) N*-----------------------------------------------------------------------------*4*‰Get„0�=�OUTPUT�ON„1�=�OUTPUT�OFFƒ2�=�PULSED�OUTPUT*�3�=�READ�STATUS‚4�=�QUIT*N*-----------------------------------------------------------------------------GETCLST'ŠOUTPUT�MESS4,MESS4E…Put�up�the�menu...ŠOUTPUT�MESS5,MESS5EŠOUTPUT�MESS6,MESS6EŠOUTPUT�MESS7,MESS7E- ŠOUTPUT�MESS8,MESS8EFGET_CHOICE‚OUTPUT�MESS2,MESS2E…Ask�the�user�to�enter�one�of�the�above. +ŠINPUT‚INPUTBUF,INPUTBUF+8�Get�their�choiceŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.W�D0��#0�OR.W�D0��#4�THEN.S�BRA.S�GET_CHOICEŠENDIŠPAGE**‰0�=�Start�output�ON�command:*ŠIF.B�D0��#0�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A02ŒLEA„ON_DCO(PC),A1„Start�output�ON�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#NLEN_DCO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�ON_DCO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADON,BADONE…***�START�OUTPUT�ON�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰1�=�Turn�output�OFF�command:*ŠIF.B�D0��#1�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A03ŒLEA„OFF_DCO(PC),A1ƒTurn�output�OFF�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#FLEN_DCO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�OFF_DCO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)6ŽOUTPUT�BADOFF,BADOFFE„***�TURN�OUTPUT�OFF�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰2�=�PULSE�an�output�command:*ŠIF.B�D0��#2�THEN.L3ŒBSR„GET_TIME‰Get�the�pulse�duration�(milliseconds)+ŒMOVE.L�D3,PON_DCO+8-PBA(A4)�Store�the�time 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS10,MESS10E…<<<ƒStarting�commandƒ>>> 7ŒMOVE.W�#WAKEUP_O,D0…Use�the�WAKEUP�option�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A06ŒLEA„PON_DCO(PC),A1ƒStart�output�pulse�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#PLEN_DCO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1*(*ƒDo�a�wait�until�the�driver�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒIF��THEN.SŽMOVE.W�PON_DCO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4);ŽOUTPUT�BADREAD,BADREADEƒ***�START�OUTPUT�PULSE�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI **‰3�=�READ�STATUS�command:*ŠIF.B�D0��#3�THEN.L /ŒOUTPUT�MESS10,MESS10Eƒ<<<ƒStarting�commandƒ>>> ŒLEA„CMRBLK(PC),A00ŒLEA„READ_DCO(PC),A1‚Read�status�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#RLEN_DCO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�READ_DCO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADREAD,BADREADEƒ***�READ�STATUS�ABORTED�***ŒENDI ŒCLR.L‚D0;ŒMOVE.W�READ_DCO+4-PBA(A4),D0‚Get�the�status�value�returnedŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŒOUTPUT�MESS9,MESS9EŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFE 3ŒOUTPUT�MESS11,MESS11Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI**‰4�=�quit�command:*ŠIF.B�D0��#4�THEN.S'�BSR.L‚CLOSE_ALLˆGo�close�all�channels. �BRA.L�EXITŠENDI ŠBRA.L�GETCHAN�Go�start�over.ŠPAGEM*----------------------------------------------------------------------------**ƒOPEN�THE�CHANNEL*M*----------------------------------------------------------------------------OPEN_CHAN�LEA„CMRBLK(PC),A0ŠLEA„OPEN_DCO(PC),A1BŠMOVE.W�D0,OPEN_DCO+8-PBA(A4)‚Save�the�open�configuration�options.ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_DCO,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)+ŒOUTPUT�BADOPN,BADOPNE…***�OPEN�ABORTED�***ŒBRA.S‚SHOW_D0ŠENDIŠRTS - M*----------------------------------------------------------------------------*+*‚GET�THE�TIME�DURATION�FOR�AN�OUTPUT�PULSE*M*----------------------------------------------------------------------------GET_TIMEŠOUTPUT�MESS3,MESS3EŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0 ŠBSR„ASCVAL ŠTST.L‚D3 ŠBEQ„GET_TIME+ŠIF.L�D3��#0�OR.L�D3��#$FFFF�THEN.S ŒBRA„GET_TIMEŠENDIŠAND.L‚#$0000FFFF,D3ŠRTS M*----------------------------------------------------------------------------**ƒOUTPUT�THE�ERROR�CODE:*M*----------------------------------------------------------------------------:SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returnedŠBSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE EXITŠBSR.S‚CLOSE_ALL"ŠMOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1ŠPAGEN*-----------------------------------------------------------------------------**‚CLOSE�ALL�CHANNEL'S�ROUTINE:*N*-----------------------------------------------------------------------------CLOSE_ALL MOVE.W D0,-(A7) ŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)7ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�DC�OUTPUT�channelŠTRAPƒ#1ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4),ŒOUTPUT�BADCLS,BADCLSE…***�CLOSE�ABORTED�***ŒMOVE.W�(A7)+,D0‰Restore�stack.%ŒBRA.L‚SHOW_D0ŠOutput�the�error�code.ŠENDI ŠMOVE.W�(A7)+,D0ŠRTS M*----------------------------------------------------------------------------*A*ƒTABLE�TO�CONVERT�THE�CHANNEL�NUMBER�(0-7)�TO�IT'S�CORRESPONDING**ƒBIT�MAPPED�VALUE�(1,2,4,8,16,32,64,128).*M*----------------------------------------------------------------------------$BIT_NUMBER‚DC.B‚1,2,4,8,16,32,64,128 ŠEND„PROGSTRTB*„This�is�TESTDC,�a�relocatable�program�that�tests�the�DCO�driver.*$*„Copyrighted�1983�by�Motorola,�Inc.E**********************************************************************B*‚This�program�sets�up�for�task�DCO1�and�verifies�it�exists.�If�it;*‚does�it�proceeds�with�the�test,�if�not�it�trys�task�DCO2./*‚If�either�task�is�missing,�it�skips�the�test.*:*‚This�program�performs�the�following�tests�on�the�driver:*9*ˆTEST1‚-‚individually�opens�each�channel,�outputs�to�it,-*’checks�status,�turns�it�off,�checks�status, *’and�closes.9*ˆTEST2‚-‚individually�opens�each�channel,�outputs�to�it,1*’checks�status,�continues�until�all�are�on.�Then,*’individually�turns�off�each�channel,checks0*’status,�continues�until�all�are�off.�Turns�all%*’channels�back�on�for�the�next�test.7*ˆTEST3‚-‚closes�the�channels,�OPERATOR�must�check�they *’turned�off.4*ˆTEST4‚-‚opens�all�channels,�turns�all�channels�on,-*’delays,�turns�all�channels�off,�and�closes.9*ˆTEST5‚-‚individually�opens�each�channel,�commands�pulse*’output,�delays,�and�closes.7*ˆTEST6‚-‚opens�four�channels,�commands�pulse�output�of3*’different�lengths�to�each�simultaneously,�delays,*’closes�channels.;*ˆTEST7�-ƒopens�channel�two�with�queue�event�configuration,'*’pulses�output,�waits�for�queue�event,)*’verifies�message�sent,�closes�channels.:*ˆTEST8‚-‚opens�channel�one�with�wait�for�wake-up�config.,'*’pulses�output,�waits�for�wake-up,�and*’closes�channels.:*ˆTEST9‚-‚trys�output�ON�with�channels�closed�and�verifies*’error.3*’trys�output�OFF�with�channels�closed�and�verifies*’error./*’trys�checking�status�with�channels�closed�and*’verifies�error.,*’trys�pulse�output�with�channels�closed�and*’verifies�error.<*ˆTEST10�-‚trys�opening�invalid�channel�numbers�and�verifies3*’errors.�(ZERO�channels,�more�than�eight�channels,"*’channel�#�9,�same�two�channels).:*ˆTEST11�-‚opens�channel�and�trys�invalid�commands�(�0,�6,*’7,�>�8�)�and�verifies�errors..  °/¹PÁPÉPÑVÙ\á\éUñWùPY ZYR!R)W1b9=*ˆTEST12�-‚trys�opening�channels�when�they�are�already�opened*’and�verifies�error.*>*ˆIf�it�passed�these�tests�it�returns�to�the�top�to�set�up�for2*’task�DCO2.�If�this�was�for�task�DCO2,�it�sets�up$*’to�test�both�tasks�simultaneously.7*ˆIF�ALL�TESTS�ARE�SUCCESSFUL,�prints�message�attesting0*’to�that�fact.�If�any�test�fails,�ERROR�message$*’is�printed�and�test�is�terminated.*D********************************************************************‰PAGE*5IOADR0ƒEQU‡$F80000�VM02�base�mem�map�I/O�chan�address5IOADR1ƒEQU‡$FA0000�VM03�base�mem�map�I/O�chan�address7IOADR2ƒEQU‡$FE6000�VME110�base�mem�map�I/O�chan�address7IOADR3ƒEQU‡$F1C000�VME/10�base�mem�map�I/O�chan�address* ‰SECTIONƒ0*TEST…LEA‡STACK(PC),A7‰LEA‡INITIO(PC),A0.‰CLR.W…DUALFG-INITIO(A0)ƒclear�dual�test�flags‰CLR.W…DUALCK-INITIO(A0)**�SET�UP�A.S.Q.*!‰MOVE.L„#31,D0Žstage�command�code-‰LEA‡ASQBLOCK(PC),A0…stage�command�parameters.‰LEA‡TESTIRQ(PC),A1†initializes�addr.�of�async*‰MOVE.L„A1,ASQLA-ASQBLOCK(A0)‚service�rtn.‰TRAP†#1 ‰BNE‡FAULT11*‰MOVE.L„#'DCO1',D0(TNAME„LEA‡INITIO(PC),A0‡SET�UP�TASK�NAME‰MOVE.L„D0,DCOPAR-INITIO(A0)‰MOVE.L„D0,TMSG-INITIO(A0)*!TRYBTHƒLEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1†again‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*.‰LEA‡SMSG1(PC),A1ˆoutput�start�of�test�message‰LEA‡EMSG1(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*‰LEA‡INITIO(PC),A0‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)+‰MOVE.W„#CLSLNG,A1ŠINSURE�CHANNEL(S)�CLOSED$‰MOVE.W„A1,CMDL-INITIO(A0)‚TO�START.‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT16*‰PAGE* *…OPEN�THE�CHANNELS�INDIVIDUALLY*5TEST1„LEA‡SMSG2(PC),A1‡output�'open�&�output'�message‰LEA‡EMSG2(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A0*‰MOVE.W„#1,ONCMD1-INITIO(A0)�'ON'�bit�mask,‰MOVE.W„#1,OFFCMD1-INITIO(A0)�'OFF'�bit�mask2‰MOVE.W„#1,STATSHF-INITIO(A0)�status�req.�bit�mask;OPNLP„MOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL�(event�count�holds‰LEA‡INITIO(PC),A0‡channel�#�)+‰MOVE.W„D0,OPNCH-INITIO(A0)�channel�to�open‰LEA‡OPNCMDS(PC),A1,‰MOVE.L„A1,CMDA-INITIO(A0)‚parameters�to�CMR‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*+‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNEL�OPENED‰LEA‡ONCMD(PC),A1,‰MOVE.L„A1,CMDA-INITIO(A0)‚parameters�to�CMR ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*!‰LEA‡OPNLP(PC),A1ˆloop�back�addr.&‰LEA‡TEST1B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*%TEST1BƒLEA‡INITIO(PC),A0‡CHECK�STATUS/‰MOVE.W„STATSHF(PC),D0†move�channel�to�check�to1‰MOVE.W„D0,STAT-INITIO(A0)‚status�parameter�block‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*3‰MOVE.W„STAT(PC),D0‰does�status�check�with�bit�that"‰CMP.W…ONCMD1(PC),D0‡should�be�on? ‰BNE‡FAULT4*#‰LEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT5*‰LEA‡INITIO(PC),A0‡CHECK�STATUS/‰MOVE.W„STATSHF(PC),D0†move�channel�to�check�to1‰MOVE.W„D0,STAT-INITIO(A0)‚status�parameter�block‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*.‰MOVE.W„STAT(PC),D0‰does�status�check�show�bit#‰BNE‡FAULT4Žstill�on?�if�so,�error.*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(. PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST1B(PC),A1‡loop�back�addr.&‰LEA‡TEST1C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST1CƒLEA‡INITIO(PC),A0>‰ASL.W…ONCMD1-INITIO(A0)ƒshift�'ON'�channel�bit�mask�one�place/‰ASL.W…OFFCMD1-INITIO(A0)‚shift�'OFF'ƒ"…"ƒ"„"„"0‰ASL.W…STATSHF-INITIO(A0)‚shift�status‚"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP*‰PAGE*2*„OUTPUT�TO�CHANNELS�SEQUENTIALLY�UNTIL�ALL�ARE�ON*5TEST2„LEA‡SMSG3(PC),A1‡output�'output�to�all'�message‰LEA‡EMSG3(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A06‰MOVE.W„#1,ONCMD1-INITIO(A0)‚bit�mask�for�'ON'�channel9‰MOVE.W„#1,STATSHF-INITIO(A0)�bit�mask�for�status�channel)OPNLP2ƒMOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL‰LEA‡INITIO(PC),A0‰MOVE.W„D0,OPNCH-INITIO(A0)/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*+‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNEL�OPENED‰LEA‡ONCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP2(PC),A1‡loop�back�addr.&‰LEA‡TEST2A(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*1TEST2AƒLEA‡INITIO(PC),A0‡CHECK�STATUS�OF�CHANNELS‰MOVE.W„STATSHF(PC),D0‰MOVE.W„D0,STAT-INITIO(A0)‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*&‰MOVE.W„STAT(PC),D0‰does�status�check?‰CMP.W…STATSHF(PC),D0 ‰BNE‡FAULT4*"‰LEA‡TEST2A(PC),A1‡loop�back�addr.&‰LEA‡TEST2B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST2BƒLEA‡INITIO(PC),A0>‰ASL.W…ONCMD1-INITIO(A0)ƒshift�'ON'�channel�bit�mask�one�place‰ORI‡#$10,CCRŒset�X�bit/‰ROXL.W„STATSHF-INITIO(A0)‚add�statusƒ"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP2*7TEST2CƒLEA‡SMSG39(PC),A1‡output�'turn�off�seq.'�message‰LEA‡EMSG39(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0"‰CLR.W…0(A0)�initialize�parameters‰LEA‡INITIO(PC),A08‰MOVE.W„#1,OFFCMD1-INITIO(A0)‚bit�mask�for�'OFF'�channel9‰MOVE.W„#1,STATSHF-INITIO(A0)�bit�mask�for�status�channel*)OPNLP3ƒLEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT5*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP3(PC),A1‡loop�back�addr.&‰LEA‡TEST2D(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*0TEST2DƒLEA‡INITIO(PC),A0‡CHECK�STATUS�OF�CHANNEL‰MOVE.W„STATSHF(PC),D0‰MOVE.W„D0,STAT-INITIO(A0)‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT3*&‰MOVE.W„STAT(PC),D0‰does�status�check? ‰BNE‡FAULT4*"‰LEA‡TEST2D(PC),A1‡loop�back�addr.&‰LEA‡TEST2E(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST2EƒLEA‡INITIO(PC),A0@‰ASL.W…OFFCMD1-INITIO(A0)‚shift�'OFF'�channel�bit�mask�one�place0‰ASL.W…STATSHF-INITIO(A0)‚shift�status‚"…"ƒ"„"„"‰LEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP3*+TEST2FƒLEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNELS‰LEA‡ONCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�S/ O�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST2F(PC),A1‡loop�back�addr.%‰LEA‡TEST3(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle**%**************************************ƒCLOSE�TEST–*%**************************************-TEST3„LEA‡SMSG4(PC),A1‡output�'close'�message‰LEA‡EMSG4(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*)TEST3AƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST3A(PC),A1‡loop�back�addr.%‰LEA‡TEST4(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE$*„TURN�ON�ALL�OUTPUTS,�THEN�TURN�OFF*9TEST4„LEA‡SMSG5(PC),A1‡output�'turn�on,�turn�off'�message‰LEA‡EMSG5(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15**TEST4AƒLEA‡INITIO(PC),A0‡OPEN�ALL�CHANNELS/‰LEA‡OPNCMD(PC),A1‡point�to�CMR�parameter�block‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*,‰LEA‡INITIO(PC),A0‡OUTPUT�TO�CHANNELS�OPENED‰LEA‡ONCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT2*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST4A(PC),A1‡loop�back�addr.&‰LEA‡TEST4B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle**TEST4BƒLEA‡INITIO(PC),A0‡TURN�OFF�CHANNELS‰LEA‡OFFCMDA(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT5*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST4B(PC),A1‡loop�back�addr.%‰LEA‡TEST5(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE*„PULSE�EACH�OUTPUT�IN�TURN*2TEST5„LEA‡SMSG6(PC),A1‡output�'pulse�each'�message‰LEA‡EMSG6(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰LEA‡EVNTCNT(PC),A0‰CLR.W…0(A0)�initialize�evntcnt)OPNLP4ƒMOVE.W„EVNTCNT(PC),D0†OPEN�CHANNEL/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block+‰MOVE.W„D0,OPNCH-INITIO(A0)�channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)�channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡OPNLP4(PC),A1‡loop�back�addr.&‰LEA‡TEST5A(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*)TEST5AƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST5A(PC),A1‡loop�back�addr.&‰LEA‡TEST5B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST5BƒLEA‡EVNTCNT(PC),A0'‰ADD.W…#1,0(A0)Œincrement�event�counter‰MOVE.W„EVNTCNT(PC),D0‰CMPI.W„#8,D0�done? ‰BMI‡OPNLP4*‰PAGE#*„PULSE�FOUR�OUTPUTS�SIMULTANEOUSLY*6TEST6„LEA‡SMSG32(PC),A1†output�'pulse�simult.'�message‰LEA‡EMSG32(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1500,A0Œ1500�MS‰TRAP†#1 ‰BNE‡FAULT15*&TEST6AƒLEA‡INITIO(PC),A0‡OPEN�CHANNELS‰LEA‡OPNCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSTWO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#PLSTLG,CMDL-INITIO(A0)‰MOVE./ L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#500,A0�500�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST6A(PC),A1‡loop�back�addr.&‰LEA‡TEST6B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*TEST6BƒMOVE.L„#21,D0ŽDELAY‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*)TEST6CƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST6C(PC),A1‡loop�back�addr.%‰LEA‡TEST7(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*‰PAGE+*„PULSE�OUTPUT�TWO�AND�GENERATE�QUEUE�EVENT*6TEST7„LEA‡SMSG7(PC),A1‡output�'pulse�output�2'�message‰LEA‡EMSG7(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST7AƒLEA‡RCVBUF(PC),A0‡ensure�RCVBUF�zeroed�out‰MOVE.L„#0,0(A0)‰MOVE.L„#0,4(A0)‰MOVE.L„#0,8(A0)*‰LEA‡INITIO(PC),A09‰MOVE.W„#0,OPNCNF-INITIO(A0)�set�up�config.�(queue�event)‰MOVE.W„#2,D0�OPEN�CHANNEL�TWO+‰MOVE.W„D0,OPNCH-INITIO(A0)‚channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)‚channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*+WAITQ„MOVE.L„#36,D0Žrequest�wait�for�event.$‰TRAP†#1’to�be�issued�by�DCO�driver. ‰BNE‡FAULT13*4‰MOVE.L„RCVBUF(PC),D0‡verify�message�returned�by�ASQ4‰CMP.L…#$0C010002,D0‡$0C01�� ‰BNE‡FAULT6‰MOVE.L„RCVBUF+4(PC),D0‰CMP.L…DCOPAR(PC),D0‡DCO-ID ‰BNE‡FAULT6‰MOVE.L„RCVBUF+8(PC),D0,‰AND.L…#$FFFFFF00,D0‡mask�off�low�order�byte0‰CMP.L…#IOADR0,D0ŠVM02�memory�mapped�I/O�address ‰BEQ.S…TEST710‰CMP.L…#IOADR1,D0ŠVM03�memory�mapped�I/O�address ‰BEQ.S…TEST722‰CMP.L…#IOADR2,D0ŠVME110�memory�mapped�I/O�address ‰BEQ.S…TEST732‰CMP.L…#IOADR3,D0ŠVME/10�memory�mapped�I/O�address ‰BNE‡FAULT6*‰LEA‡SMSG43(PC),A1‰LEA‡EMSG43(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST71ƒLEA‡SMSG40(PC),A1‰LEA‡EMSG40(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST72ƒLEA‡SMSG41(PC),A1‰LEA‡EMSG41(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TEST74TEST73ƒLEA‡SMSG42(PC),A1‰LEA‡EMSG42(PC),A2 ‰BSR‡MSGOUT2TEST74ƒLEA‡SMSG38(PC),A1‡output�'asq�verified'�msg‰LEA‡EMSG38(PC),A2 ‰BSR‡MSGOUT*"‰LEA‡TEST7A(PC),A1‡loop�back�addr.&‰LEA‡TEST7B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*)TEST7BƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST7B(PC),A1‡loop�back�addr.&‰LEA‡TEST7C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST7CƒMOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*‰PAGE'*…PULSE�OUTPUT�ONE�AND�GENERATE�WAKE-UP3TEST8„LEA‡SMSG8(PC),A1‡output�'pulse�led�1'�message‰LEA‡EMSG8(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST8AƒLEA‡INITIO(PC),A0‡point�to�CMR�para.�block5‰MOVE.W„#1,OPNCNF-INITIO(A0)�set�up�config.�(wake-up)‰MOVE.W„#1,D0�OPEN�CHANNEL�ONE+‰MOVE.W„D0,OPNCH-INITIO(A0)‚channel�to�open,‰MOVE.W„D0,PLSO1-INITIO(A0)‚channel�to�pulse‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT10*-WAITW„MOVE.L„#19,D0Žrequest�wait�for�wake-up.$‰TRAP†#1’to�be�issued�by�DCO�driver. ‰BNE‡FAULT130‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�CHANNEL‰MOVE.L„#1000,A0Œ1000�MS‰TRAP†#1 ‰BNE‡FAULT15*"‰LEA‡TEST8A(PC),A1‡loop�back�addr.&‰LEA‡TEST8B(PC),A2‡continue�on�for0 ward‰BRA‡FLOP�test�for�toggle*)TEST8BƒLEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*"‰LEA‡TEST8B(PC),A1‡loop�back�addr.&‰LEA‡TEST8C(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST8CƒLEA‡INITIO(PC),A0‡restore�default�configuration ‰MOVE.W„#$8000,OPNCNF-INITIO(A0)2‰MOVE.W„#0,OPNCH-INITIO(A0)�restore�channel�select1‰MOVE.W„#1,STAT-INITIO(A0)‚restore�status�channel3‰MOVE.W„#1,OFFCMD1-INITIO(A0)‚restore�off�cmd�chan.*‰PAGE#*„TRY�COMMANDS�WITH�CHANNELS�CLOSED7TEST9„LEA‡SMSG9(PC),A1‡output�'try�with�closed'�message‰LEA‡EMSG9(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*1TEST9AƒLEA‡INITIO(PC),A0‡OUTPUT�TO�CLOSED�CHANNEL‰LEA‡ONCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#6,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1)‰MOVE.W„ONCMD(PC),D0ˆread�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT2 ‰LEA‡SMSG12(PC),A1‡output�ok�msg‰LEA‡EMSG12(PC),A2 ‰BSR‡MSGOUT*#‰LEA‡INITIO(PC),A0‡TURN�OFF�CHANNEL‰LEA‡OFFCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„OFFCMD(PC),D0‡read�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT5‰LEA‡SMSG14(PC),A1‡off�ok�msg‰LEA‡EMSG14(PC),A2 ‰BSR‡MSGOUT*‰LEA‡INITIO(PC),A0‡CHECK�STATUS‰LEA‡STATCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#6,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1+‰MOVE.W„STATCMD(PC),D0†read�returned�status(‰CMP.W…#$F2,D0�verify�correct�error�code ‰BNE‡FAULT3 ‰LEA‡SMSG16(PC),A1‡status�ok�msg‰LEA‡EMSG16(PC),A2 ‰BSR‡MSGOUT*‰LEA‡INITIO(PC),A0‰LEA‡PLSO(PC),A1‰PULSE�OUTPUT‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#12,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1(‰MOVE.W„PLSO(PC),D0‰read�returned�status(‰CMP.W…#$F6,D0�verify�correct�error�code ‰BNE‡FAULT10*"‰LEA‡TEST9A(PC),A1‡loop�back�addr.&‰LEA‡TEST9B(PC),A2‡continue�on�forward‰BRA‡FLOP�test�for�toggle*%TEST9BƒLEA‡SMSG18(PC),A1‡pulse�ok�msg‰LEA‡EMSG18(PC),A2 ‰BSR‡MSGOUT*‰PAGE*ƒTRY�TO�OPEN�INVALID�CHANNELS6TEST10ƒLEA‡SMSG11(PC),A1‡output�'try�invalid�channels'‰LEA‡EMSG11(PC),A2 ‰BSR‡MSGOUT0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*3TEST10A‚LEA‡INITIO(PC),A0‡TRY�TO�OPEN�ZERO�CHANNELS‰LEA‡OPNCH0(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNCHL,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNCH0(PC),D0‡read�cmd�status‰CMP.W…#$F7,D0 ‰BNE‡FAULT7*3‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�MORE�THAN�8�CHANNELS‰LEA‡OPNMOR(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNML,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNMOR(PC),D0‡read�cmd�status‰CMP.W…#$F7,D0 ‰BNE‡FAULT7*,‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�CHANNEL�#�>�8‰LEA‡OPNCH9(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNC9L,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1%‰MOVE.W„OPNCH9(PC),D0‡read�cmd�status‰CMP.W…#$F6,D0 ‰BNE‡FAULT7*0‰LEA‡INITIO(PC),A0‡TRY�TO�OPEN�SAME�TWO�CHANNELS‰LEA‡OPNTW(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNTL,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1$‰MOVE.W„OPNTW(PC),D0ˆread�cmd�status‰CMP.W…#$FE,D0 ‰BNE‡FAULT7*#‰LEA‡TEST10A(PC),A1†loop�back�addr.'‰LEA‡TEST10B(PC),A2†continue�on�forward‰BRA‡FLOP�test�for�toggle*6TEST10B‚LEA‡SMSG36(PC),A1‡output�'invalid�channels�ok'‰LEA‡EMSG36(PC),A2 ‰BSR‡MSGOUT*‰PAGE*„TRY�TO�USE�INVALID�COMMANDS*2TEST11ƒLEA‡SMSG25(PC),A1‡output�'try�invalid�cmds'‰LEA‡EMSG25(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*&TEST11A‚LEA‡INITIO(PC),A0‡OPEN�CHANNEL‰MOVE.W„#1,OPNCH-INITIO(A0)‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„0 A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�0‰LEA‡INVCM0(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM0(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�6‰LEA‡INVCM6(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM6(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*$‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�7‰LEA‡INVCM7(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM7(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*&‰LEA‡INITIO(PC),A0‡INVALID�COMMAND�>�8‰LEA‡INVCM9(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0) ‰MOVE.W„#4,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1*‰MOVE.W„INVCM9(PC),D0‡read�returned�status‰CMP.W…#$F4,D0 ‰BNE‡FAULT9*#‰LEA‡TEST11A(PC),A1†loop�back�addr.'‰LEA‡TEST11B(PC),A2†continue�on�forward‰BRA‡FLOP�test�for�toggle*-TEST11B‚LEA‡SMSG26(PC),A1‡invalid�cmds�ok�msg‰LEA‡EMSG26(PC),A2 ‰BSR‡MSGOUT*‰PAGE*„TRY�OPEN�AND�ALREADY�OPENED9TEST12ƒLEA‡SMSG20(PC),A1†output�'try�with�opened'�message‰LEA‡EMSG20(PC),A2 ‰BSR‡MSGOUT*0‰MOVE.L„#21,D0ŽDELAY�SO�OPERATOR�CAN�SEE�MESSAGE‰MOVE.L„#1200,A0Œ1200�MS‰TRAP†#1 ‰BNE‡FAULT15*6TEST12A‚LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block(‰MOVE.W„#0,OPNCH-INITIO(A0)�OPEN�CHANNEL‰LEA‡OPNCMDS(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1 ‰BNE‡FAULT1*/‰LEA‡INITIO(PC),A0‡point�to�CMR�parameter�block‰LEA‡OPNCMDS(PC),A1)‰MOVE.L„A1,CMDA-INITIO(A0)‚TRY�OPEN�again‰MOVE.W„#OPNLNGS,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0ŽCMR‰TRAP†#1+‰MOVE.W„OPNCMDS(PC),D0‡read�returned�status‰CMP.W…#$FE,D0 ‰BNE.S…FAULT1*#‰LEA‡INITIO(PC),A0‡CLOSE�CHANNEL(S)‰LEA‡CLSCMD(PC),A1‰MOVE.L„A1,CMDA-INITIO(A0)‰MOVE.W„#CLSLNG,A1‰MOVE.W„A1,CMDL-INITIO(A0)‰MOVE.L„#60,D0‰TRAP†#1 ‰BNE‡FAULT8*#‰LEA‡TEST12A(PC),A1†loop�back�addr.%‰LEA‡TESTC(PC),A2ˆcontinue�on�forward‰BRA‡FLOP�test�for�toggle*1**************************************************„TEST�COMPLETED�*1************************************************* TESTC„LEA‡SMSG24(PC),A1‡space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*1‰LEA‡SMSG23(PC),A1†output�'test�complete'�message‰LEA‡EMSG23(PC),A2 ‰BSR‡MSGOUT*‰LEA‡SMSG24(PC),A1†space�up‰LEA‡EMSG24(PC),A2 ‰BSR‡MSGOUT*#NEXT…MOVE.W„DUALFG(PC),D0‡flag�set? ‰BNE‡TERM.NEXTA„MOVE.L„DCOPAR(PC),D0‡try�for�second�task‰CMP.L…#'DCO1',D0‰BNE‡TERMA�done‰MOVE.L„#'DCO2',D0‰BRA‡TNAME�set�up�second�task*‰PAGE*#FAULT1ƒLEA‡SMSG22(PC),A1‡open�error‰LEA‡EMSG22(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT2ƒLEA‡SMSG13(PC),A1‡output�error‰LEA‡EMSG13(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT3ƒLEA‡SMSG17(PC),A1‡status�error‰LEA‡EMSG17(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM+FAULT4ƒLEA‡SMSG28(PC),A1‡status�check�error‰LEA‡EMSG28(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM"FAULT5ƒLEA‡SMSG15(PC),A1‡off�error‰LEA‡EMSG15(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM*FAULT6ƒLEA‡SMSG10(PC),A1‡ASQ�message�error‰LEA‡EMSG10(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM.FAULT7ƒLEA‡SMSG21(PC),A1‡invalid�channel�error‰LEA‡EMSG21(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM$FAULT8ƒLEA‡SMSG33(PC),A1‡close�error‰LEA‡EMSG33(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM.FAULT9ƒLEA‡SMSG27(PC),A1‡invalid�cmd�error�msg‰LEA‡EMSG27(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM%FAULT10‚LEA‡SMSG19(PC),A1‡pulse�error‰LEA‡EMSG19(PC),A2 ‰BSR‡MSGOUT ‰BRA‡TERM#FAULT11‚LEA‡SMSG30(PC),A1‡ASQ�error‰LEA‡EMSG30(PC),A2 ‰BSR‡MSGOUT ‰BRA.S…TERM#FAULT12‚LEA‡SMSG29(PC),A1‡ASQ�error‰LEA‡EMSG29(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM6FAULT13‚LEA‡SMSG31(PC),A1‡WAKE-UP�or�QUEUE�EVENT�error‰LEA‡EMSG31(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM2FAULT14‚LEA‡SMSG34(PC),A1‡IOS�(trap�#2)�call�error‰LEA‡EMSG34(PC),A2 ‰B1 SR.S…MSGOUT ‰BRA.S…TERM*FAULT15‚LEA‡SMSG35(PC),A1‡call�delay�error‰LEA‡EMSG35(PC),A2 ‰BSR.S…MSGOUT ‰BRA.S…TERM/FAULT16‚LEA‡SMSG37(PC),A1‡non-existant�task�msg‰LEA‡EMSG37(PC),A2 ‰BSR.S…MSGOUT(‰LEA‡DUALFG(PC),A0‡set�flag�to�eliminate‰ADD.W…#1,(A0)�dual�test ‰BRA‡NEXTA**„DE-ACTIVATE�SELF*0TERMA„LEA‡INITIO(PC),A0‡test�for�dual�board�test‰TST.W…DUALFG-INITIO(A0) ‰BNE.S…TERM4‰MOVE.W„#1,DUALFG-INITIO(A0)‚set�up�for�dual�bd�test‰MOVE.W„#1,DUALCK-INITIO(A0)!‰MOVE.L„#'DCO1',DCOPAR-INITIO(A0)*‰MOVE.L„#'DCO1',TMSG-INITIO(A0)‚set�up�msg‰MOVE.W„#'&2',TMSG+4-INITIO(A0) ‰BRA‡TRYBTH*%TERM…MOVE.L„#32,D0ŽDE-ALLOCATE�A.S.Q.‰TRAP†#1**‰MOVE.L„#15,D0ŽNOW�DE-ACTIVATE�SELF�(EXIT)‰TRAP†#1**„MESSAGE�OUTPUT�SUBROUTINE*/MSGOUTƒLEA‡MSG(PC),A0Šoutput�message�pointed�to(‰MOVE.L„A1,X1-MSG(A0)‡by�A1,�ended�by�A2‰MOVE.L„A2,X2-MSG(A0)‰TRAP†#2 ‰BNE‡FAULT14‰RTS*1FLOP…LEA‡INITIO(PC),A0‡toggle�between�DCO1�&�DCO2‰MOVE.W„DUALCK-INITIO(A0),D0 ‰BEQ.S…FLOP2�continue�on�if�zero‰CMP.W…#1,D0�see�if�=�1 ‰BNE.S…FLOP11‰MOVE.W„#2,DUALCK-INITIO(A0)‚is�=�1,�set�up�for�2!‰MOVE.L„#'DCO2',DCOPAR-INITIO(A0)‰JMP‡(A1)�loop�back6FLOP1„MOVE.W„#1,DUALCK-INITIO(A0)‚is�=�2,�set�up�for�1!‰MOVE.L„#'DCO1',DCOPAR-INITIO(A0))FLOP2„JMP‡(A2)�continue�on�with�next�test*-*ƒMOVE�THE�ASQ�MESSAGE�FROM�THE�ASQ�TO�RCVBUF*8TESTIRQ‚EQU‡*‰entry�point�moving�data�from�ASQ�to�RCVBUF!‰MOVE.L„#34,D0„stage�command�code‰LEA‡RCVBUF(PC),A0‰TRAP†#1 ‰BNE‡FAULT12*„RETURN�FROM�EVENT!‰MOVE.L„#37,D0„stage�command�code ‰MOVE.W„#1,A0‰TRAP†#1*‰PAGE**„CMR�parameter�block*INITIOƒDC.B†7,0,0,0DCOPARƒDC.L†'DCO1'„TASK�NAME ‰DC.L†0,0,0*CMDA…DC.L†0‰address�of�DCO�parameter�blockCMDL…DC.W†0‰command�length**„A.S.Q.�parameter�block*ASQBLOCK�EQU‡*‰DC.L†0‰task�name‰DC.L†0‰dummy�field*‰DC.B†5‰ASQ�&�ASR�enabled�=�initial�status"‰DC.B†16ˆlength�of�message�for�ASQ‰DC.L†16ˆstorage�for�4�events?ASQLA„DC.L†TESTIRQƒlogical�address�of�target�task�async�svc�rtn‰DC.L†0‰dummy�fieldASQLNGƒEQU‡*-ASQBLOCK*0*„DCO�parameter�block�to�open�individual�channel*OPNCMDS‚DC.W†0‰returned�status‰DC.W†1‰OPEN�command�code‰DC.W†1‰open�1�channelOPNCH„DC.W†0‰channel�#/OPNCNFƒDC.W†$8000…Default�channel�configurationOPNLNGS‚EQU‡*-OPNCMDS�length***„DCO�parameter�block�to�open�ALL�channels*OPNCMDƒDC.W†0‰returned�status‰DC.W†1‰OPEN�command�code‰DC.W†8‰open�8�channels*‰DC.W†0,$8000ƒCHAN�0,default�configuration‰DC.W†1,$8000ƒCHAN�1,ƒ"‰"‰DC.W†2,$8000ƒCHAN�2,ƒ"‰"‰DC.W†3,$8000ƒCHAN�3,ƒ"‰"‰DC.W†4,$8000ƒCHAN�4,ƒ"‰"‰DC.W†5,$8000ƒCHAN�5,ƒ"‰"‰DC.W†6,$8000ƒCHAN�6,ƒ"‰"‰DC.W†7,$8000ƒCHAN�7,ƒ"‰"OPNLNGƒEQU‡*-OPNCMD‚length*#*ƒparameter�block�for�CLOSE�command*CLSCMDƒDC.W†0‰returned�status‰DC.W†2‰CLOSE�command(CLSLNGƒEQU‡*-CLSCMD‚close�command�length*$*…DCO�parameter�block�for�ON�command* ONCMD„EQU‡*‰DC.W†0‰returned�command�status‰DC.W†3‰OUTPUT�ON�command,ONCMD1ƒDC.W†1‰bit�mask�of�channel�to�turn�ON* ONCMDAƒEQU‡*‰DC.W†0‰returned�command�status‰DC.W†3‰OUTPUT�ON�command,‰DC.W†$00FF…bit�mask�to�turn�ON�all�channels*%*…DCO�parameter�block�for�OFF�command* OFFCMDƒEQU‡*&‰DC.W†0‰return�command�status�location‰DC.W†4‰OFF�command.OFFCMD1‚DC.W†1‰bit�mask�of�channel�to�turn�OFF* OFFCMDA‚EQU‡*&‰DC.W†0‰return�command�status�location‰DC.W†4‰OFF�command-‰DC.W†$00FF…bit�mask�to�turn�OFF�all�channels*$*„parameter�block�for�STATUS�command* STATCMD‚EQU‡*‰DC.W†0‰returned�command�status‰DC.W†5‰STATUS�command2STAT…DC.W†1‰bit�mask�&�read�status�of�channels�0-7*:*„DCO�parameter�block�to�do�1000�ms�PULSE�on�selected�chan*PLSO…DC.W†0‰returned�cmd�status‰DC.W†8‰PULSE�command�code‰DC.W†1‰one�channelPLSO1„DC.W†1‰pulse�channel�#‰DC.L†500‡500�ms�pulse*7*„parameter�block�to�PULSE�four�channels�simultaneously*!PLSTWOƒDC.W†0‰returned�cmd�status‰DC.W†8‰PULSE�command�code‰DC.W†4‰four�channels‰DC.W†4‰chan.�#�4‰DC.L†250‡251 0�ms‰DC.W†5‰chan.�#�5‰DC.L†500‡500�ms‰DC.W†6‰chan.�#�6‰DC.L†750‡750�ms‰DC.W†7‰chan.�#�7‰DC.L†1000†1000�msPLSTLGƒEQU‡*-PLSTWO*"*„INVALID�CHANNEL�parameter�blocks*!OPNCH0ƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�command�code‰DC.W†0‰open�zero�channels‰DC.W†0‰channel�0‰DC.W†$8000…config.OPNCHLƒEQU‡*-OPNCH0*!OPNCH9ƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†1‰open�one�channel‰DC.W†9‰open�channel�#�9‰DC.W†$8000…config.OPNC9LƒEQU‡*-OPNCH9* OPNTW„DC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†3‰open�three�chan.‰DC.W†1,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.OPNTL„EQU‡*-OPNTW*!OPNMORƒDC.W†0‰returned�cmd�status‰DC.W†1‰OPEN�cmd�code‰DC.W†9‰open�9�channels‰DC.W†0,$8000ƒchan,�config.‰DC.W†1,$8000ƒchan,�config.‰DC.W†2,$8000ƒchan,�config.‰DC.W†3,$8000ƒchan,�config.‰DC.W†4,$8000ƒchan,�config.‰DC.W†5,$8000ƒchan,�config.‰DC.W†6,$8000ƒchan,�config.‰DC.W†7,$8000ƒchan,�config.‰DC.W†8,$8000ƒchan,�config.OPNML„EQU‡*-OPNMOR*#*…INVALID�COMMANDS�parameter�blocks*!INVCM0ƒDC.W†0‰returned�cmd�status‰DC.W†0‰invalid�command�0*!INVCM6ƒDC.W†0‰returned�cmd�status‰DC.W†6‰invalid�command�6*!INVCM7ƒDC.W†0‰returned�cmd�status‰DC.W†7‰invalid�command�7*!INVCM9ƒDC.W†0‰returned�cmd�status"‰DC.W†9‰invalid�cmd�greater�than�8**„IOS�MESSAGE�parameter�block*MSG†DC.B†0‰Data�xfer�code=0‰DC.B†2‰Write�data‰DC.W†0‰Options�-�none‰DC.B†0‰Status ‰DC.B†6‰LUN‰DC.W†0‰reserved‰DC.L†0‰random�record�countX1‡DC.L†0‰bfr�start�addr.X2‡DC.L†0‰bfr�end�addr.‰DC.L†0‰length�of�data�xfer ‰DC.L†0‰completion/service�addr.*‰PAGE *„MESSAGES*6SMSG1„DC.W†'**********�DC�OUTPUT�TEST�PROGRAM�******�'TMSG…DC.W†'DCO1‚' EMSG1„EQU‡*-1*8SMSG2„DC.W†'‚OPEN�&�OUTPUT�TO�EACH�CHANNEL�INDIVIDUALLY' EMSG2„EQU‡*-1*9SMSG3„DC.W†'‚OPEN�&�OUTPUT�EACH�CHANNEL�UNTIL�ALL�ARE�ON' EMSG3„EQU‡*-1*5SMSG4„DC.W†'‚CLOSE�CHANNELS,�OUTPUTS�SHOULD�TURN�OFF' EMSG4„EQU‡*-1*0SMSG5„DC.W†'‚TURN�ON�ALL�OUTPUTS,�THEN�TURN�OFF' EMSG5„EQU‡*-1*'SMSG6„DC.W†'‚PULSE�EACH�OUTPUT�IN�TURN' EMSG6„EQU‡*-1*5SMSG7„DC.W†'‚PULSE�OUTPUT�2�AND�GENERATE�QUEUE�EVENT' EMSG7„EQU‡*-1*1SMSG8„DC.W†'‚PULSE�OUTPUT�1�AND�GENERATE�WAKE-UP' EMSG8„EQU‡*-1*/SMSG9„DC.W†'‚TRY�COMMANDS�WITH�CHANNELS�CLOSED' EMSG9„EQU‡*-1**SMSG10ƒDC.W†'‚INVALID�ASQ�MESSAGE�-�ERROR'EMSG10ƒEQU‡*-1*+SMSG11ƒDC.W†'‚TRY�TO�OPEN�INVALID�CHANNELS'EMSG11ƒEQU‡*-1*4SMSG12ƒDC.W†'‚CALL�OUTPUT�AND�CHANNELS�CLOSED�-�OK!'EMSG12ƒEQU‡*-1*"SMSG13ƒDC.W†'‚CALL�OUTPUT�-�ERROR'EMSG13ƒEQU‡*-1*1SMSG14ƒDC.W†'‚CALL‚OFFƒAND�CHANNELS�CLOSED�-�OK!'EMSG14ƒEQU‡*-1*SMSG15ƒDC.W†'‚CALL�OFF�-�ERROR'EMSG15ƒEQU‡*-1*4SMSG16ƒDC.W†'‚CALL�STATUS�AND�CHANNELS�CLOSED�-�OK!'EMSG16ƒEQU‡*-1*"SMSG17ƒDC.W†'‚CALL�STATUS�-�ERROR'EMSG17ƒEQU‡*-1*3SMSG18ƒDC.W†'‚CALL�PULSE‚AND�CHANNELS�CLOSED�-�OK!'EMSG18ƒEQU‡*-1*!SMSG19ƒDC.W†'‚CALL�PULSE�-�ERROR'EMSG19ƒEQU‡*-1*4SMSG20ƒDC.W†'‚TRY�CALL�OPEN�AND�ALREADY�OPENED�-OK!'EMSG20ƒEQU‡*-1*&SMSG21ƒDC.W†'‚INVALID�CHANNEL�-�ERROR'EMSG21ƒEQU‡*-1* SMSG22ƒDC.W†'‚CALL�OPEN�-�ERROR'EMSG22ƒEQU‡*-1*9SMSG23ƒDC.W†'‚******�TEST�COMPLETED�SUCCESSFULLY�*******'EMSG23ƒEQU‡*-1*SMSG24ƒDC.W†'‚'EMSG24ƒEQU‡*-1**SMSG25ƒDC.W†'‚TRY�TO�USE�INVALID�COMMANDS'EMSG25ƒEQU‡*-1**SMSG26ƒDC.W†'‚CALL„INVALID„COMMANDS„-‚OK!'EMSG26ƒEQU‡*-1*&SMSG27ƒDC.W†'‚INVALID�COMMAND�-�ERROR'EMSG27ƒEQU‡*-1*#SMSG28ƒDC.W†'‚STATUS�CHECK�-�ERROR'EMSG28ƒEQU‡*-1*"SMSG29ƒDC.W†'‚A.S.Q.�MOVE‚-�ERROR'EMSG29ƒEQU‡*-1*SMSG30ƒDC.W†'‚A.S.Q.�-�ERROR'EMSG30ƒEQU‡*-1*$SMSG31ƒDC.W†'‚WAKEUP�OR�QUEUE�ERROR'EMSG31ƒEQU‡*-1*9SMSG32ƒDC.W†'‚PULSE�CHANNELS�4,�5,�6,�&�7�SIMULTANEOUSLY'EMSG32ƒEQU‡*-1*!SMSG33ƒDC.W†'‚CALL�CLOSE�-�ERROR'EMSG33ƒEQU‡*-1*#SMSG34ƒDC.W†'‚TRAP�#�2�(IOS)�ERROR'EMSG34ƒEQU‡*-1*!SMSG35ƒDC.W†'‚CALL�DELAY�-�ERROR'EMSG35ƒEQU‡*-1**SMSG36ƒDC.W†'‚CALL„INVALID„CHANNEL2 S„-‚OK!'EMSG36ƒEQU‡*-1*‰PAGE*:SMSG37ƒDC.W†'-�-�-�NON-EXISTANT�TASK/BOARD�-�-�-�-�-�-�-^'EMSG37ƒEQU‡*-1*&SMSG38ƒDC.W†'‚A.S.Q.�MESSAGE�VERIFIED'EMSG38ƒEQU‡*-1*-SMSG39ƒDC.W†'‚TURN�OFF�CHANNELS�SEQUENTIALLY'EMSG39ƒEQU‡*-1*SMSG40ƒDC.W†'‚VM02'EMSG40ƒEQU‡*-1*SMSG41ƒDC.W†'‚VM03'EMSG41ƒEQU‡*-1*SMSG42ƒDC.W†'‚VME110'EMSG42ƒEQU‡*-1*SMSG43ƒDC.W†'‚VME/10'EMSG43ƒEQU‡*-1*‰PAGE*EVNTCNT‚DS.W†1‰event�counter!STATSHF‚DS.W†1‰status�bit�shifter1DUALFGƒDS.W†1‰dual�board�test�flag(1=do�not�test)500ƒFORMAT�('�OPEN�&�OUTPUT�TO�EACH�CHANNEL�UNTIL�ALL�ARE�ON')C †DO�600�I=1,8 †OPN(3)�=�1 †OPN(4)�=�I-1†OPN(5)�=�IHEX(10)†CALL�DCOPEN�(ID,OPN)†OUT(3)�=�IHEX(I)†CALL�DCOOUT�(ID,OUT)C †CALL�DELAYC†STATUS(3)�=�MSK(I)†CALL�DCOSTA�(ID,STATUS)"†IF�(STATUS(3)-MSK(I))�550,600,550550ƒCALL�ERRPR1�(I-1) 600ƒCONTINUEC†WRITE�(6,620)7620ƒFORMAT�('�CLOSE�CHANNELS,�OUTPUTS�SHOULD�TURN�OFF') †CALL�DELAY†CALL�DCOCLS�(ID,CLSE) †CALL�DELAYC†WRITE�(6,750)2750ƒFORMAT�('�TURN�ON�ALL�OUTPUTS,�THEN�TURN�OFF')C †OPN(3)�=�8†K=0†DO�800�I�=�4,18,2 †OPN(I)�=�K†OPN(I+1)�=�IHEX(10)†K�=�K+1 800ƒCONTINUE†CALL�DCOPEN(ID,OPN)†OUT(3)�=�IHEX(9)†CALL�DCOOUT�(ID,OUT)C †CALL�DELAY†OFF(3)�=�IHEX(9)†CALL�DCOOFF(ID,OFF)†CALL�DCOCLS�(ID,CLSE)C†WRITE�(6,950))950ƒFORMAT�('�PULSE�EACH�OUTPUT�IN�TURN')C†DO�1000�I�=�1,8 †OPN(3)�=�1 †OPN(4)�=�I-1†OPN(5)�=�IHEX(10)†CALL�DCOPEN�(ID,OPN) †PULSE(3)�=�1†PULSE(4)�=�I-1 †PULSE(5)�=�0†PULSE(6)�=�500†CALL�DCOPLS�(ID,PULSE)C †CALL�DELAY †CALL�DELAY 1000‚CONTINUE†CALL�DCOCLS(ID,CLSE)C†WRITE�(6,1030)11030‚FORMAT('�TRY�COMMANDS�WITH�CHANNELS�CLOSED')C†CALL�DCOCLS(ID,CLSE)†IF�(CLSE(1))�1090,1070,10901070‚WRITE�(6,1080)31080‚FORMAT�('�CALL�CLOSE�AND�CHANNELS�CLOSED--OK') †GO�TO�10951090‚WRITE�(6,1093)#1093‚FORMAT�('�CALL�CLOSE�-�ERROR')C1095‚OUT(3)�=�1†CALL�DCOOUT(ID,OUT)†IF�(OUT(1))�1040,1060,10401040‚WRITE�(6,1050)01050‚FORMAT('�CALL‚OUT‚AND�CHANNELS�CLOSED--OK') †GO�TO�10651060‚WRITE�(6,1063)!1063‚FORMAT�('�CALL�OUT�-�ERROR')C1065‚OFF(3)�=�1†CALL�DCOOFF(ID,OF3 F)†IF�(OFF(1))�1100,1120,11001100‚WRITE�(6,1110)11110‚FORMAT�('�CALL‚OFF‚AND�CHANNELS�CLOSED--OK') †GO�TO�11251120‚WRITE�(6,1123)!1123‚FORMAT�('�CALL�OFF�-�ERROR')C1125‚STATUS(3)�=1†CALL�DCOSTA(ID,STATUS)†IF�(STATUS(1))�1130,1150,11301130‚WRITE�(6,1140)21140‚FORMAT('�CALL�STATUS�AND�CHANNELS�CLOSED-OK') †GO�TO�11551150‚WRITE�(6,1153)$1153‚FORMAT�('�CALL�STATUS�-�ERROR')C1155‚PULSE(3)�=�1 †PULSE(4)�=�1 †PULSE(5)�=�0†PULSE(6)�=�10†CALL�DCOPLS(ID,PULSE)†IF�(PULSE(1))�1160,1180,11601160‚WRITE�(6,1170)21170‚FORMAT('�CALL�PULSE�AND�CHANNELS�CLOSED--OK') †GO�TO�11851180‚WRITE�(6,1183)#1183‚FORMAT�('�CALL�PULSE�-�ERROR')C1185‚OPN(3)�=�1 †OPN(4)�=�1†OPN(5)�=�IHEX(10)†CALL�DCOPEN(ID,OPN)C†WRITE�(6,1190)01190‚FORMAT('�TRY�CALL�OPEN�AND�ALREADY�OPENED')C †OPN(3)�=�1 †OPN(4)�=�1†OPN(5)�=�IHEX(10)†CALL�DCOPEN(ID,OPN)†IF�(OPN(1))�1200,1220,12001200‚WRITE�(6,1210)21210‚FORMAT('�CALL�OPEN�AND�CHANNELS�ARE�OPEN-OK') †GO�TO�12251220‚WRITE�(6,1222)"1222‚FORMAT�('�CALL�OPEN�-�ERROR')C1225‚WRITE�(6,60)C†WRITE�(6,1300)31300‚FORMAT�('*********�TEST�COMPLETED�**********')C †WRITE�(6,60)CCˆSEE�IF�SECOND�BOARD�TO�TESTC#1350‚IF�(ID�.EQ.�'DCO2')�GO�TO�15001400‚ID�=�'DCO2'†GO�TO�5C 1500‚STOP†ENDNNNNC:C ********************************************************C†SUBROUTINE�DELAY C–DELAY�APPROXIMATELY�ONE�SECOND†DO�30�J�=�1,100†DO�20�K�=�1,350 20„CONTINUE 30„CONTINUE†RETURN†ENDNNNNN3 NNb C:C ********************************************************C†SUBROUTINE�ERRPR1(I)†WRITE�(6,10)�I#10„FORMAT�('�STATUS�ERROR-BIT�',I1)†RETURN†ENDNNNNNNNk'RIODRV TESTE AF€€  TESTRIO AF‰‰  TESTE LF’’   TESTRIO LF››  TESTE LOœ  TESTRIO LO¥  TESTE SAºº  TESTRIO SAÛÛW  4 =/*=/*†RIODRV.TESTE.AF=/*:=/* Chain file to assemble RIO driver test routine 'TESTE'=/*:=/* If no output argument is specified for the listing the.=/* chain file will default to RIODRV.TESTE.LS=/*=/IFC \1ƒ=ARG�RIODRV.TESTE.LS=/ENDIF=/*)=ASM RIODRV.TESTE.SA,RIODRV.TESTE.RO,\1;R=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNNNx=/*=/*†RIODRV.TESTRIO.AF=/*,=/*†TESTRIO�test�program�assembly�chain�file=/*,=/*†Default�argument�01�is�RIODRV.TESTRIO.LS=/*=/IFC \1ƒ=ARG�RIODRV.TESTRIO.LS=/ENDIF=/*2=ASM RIODRV.TESTRIO.SA,RIODRV.TESTRIO.RO,\1;RZ=100=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDNNNNN4 N�=/*=/*†RIODRV.TESTE.LF=/*=/*=/IFC \1ƒ=ARG�RIODRV.TESTE.LL=/ENDIF=/*=LINK ,RIODRV.TESTE.LO,\1;MIXHS SEG SEG0:0 $0INPUT RIODRV.TESTE.ROEND=/*=ENDNNNNNNNŠ=/*=/*†RIODRV.TESTRIO.LF=/*G=/*†This�chain�file�will�generate�the�TESTRIO�test�program�load�module.=/*5=/*†The�command�line�will�accept�arguments�as�follows=/*7=/*‹Argument�01ˆ\1�=�Output�file�link�listing�or�device=/*D=/*†The�following�shows�the�link�chain�sequence.‚In�this�example�theF=/*†printer�was�chosen�as�Argument�1,�however,�the�user�could�if�he�so2=/*†desired�have�requested�an�output�listing�file.=/* =/*�=CHAIN�RIODRV.TESTRIO.LF�#PR=/*,=/*†Default�argument�01�is�RIODRV.TESTRIO.LL=/*=/IFC \1ƒ=ARG�RIODRV.TESTRIO.LL=/ENDIF=/*!=LINK ,RIODRV.TESTRIO.LO,\1;HAMIXSEG SEG0:0,1,8,14 $000000ATTRIBUTES D PINPUT RIODRV.TESTRIO.ROLIB 0.&.UTILIB.ROEND=/*=ENDNN5 NNN“TESTÿÿÿÿÿ€SEG0ÿÿÿÿÿÿÿÿÿMúÿþOîöB®ŒAîvCîb-I„pNAf*Aî�Cîª-I¤=|*¨p Enter one of the above... Time (in milliseconds) for output pulse > <<< Starting command >>> <<< Command done >>> *** START OUTPUT ON ABORTED *** -- *** TURN OUTPUT OFF ABORTED *** -- *** START OUTPUT PULSE ABORTED *** -- *** OPEN ABORTED *** -- *** ENABLE INTERRRUPT ABORTED *** -- *** DISABLE INTERRRUPT ABORTED *** -- *** READ STATUS ABORTED *** -- *** CLOSE ABORTED *** -- Error code returned in D0 = OúüIúûHAúý)HDAúý)HHAúülNBAúýð)HDAúþ)HHAúüVNBAúûà)H`Aúûà)HdAúü\NBAúûÊaŽ €m €o`º9@’9@¨Aúìã009@²9@¸9@¾9@š9@ Aúü¤)HDAúü³)HHAúûêNBAúü¦)HDAúü³)HHAúûÔNBAúü¦)HDAúüÍ)HHAúû¾NBAúüÀ)HDAúüà)HHAúû¨NBAúüÔ)HDAúüî)HHAúû’NBAúüâ)HDAúüé)HHAúû|NBAúý0)HDAúýF)HHAúûfNBAúúð)H`Aúúð)HdAúûlNBAúúÚaž @m @o`¾ fva˜Aúý4)HDAúýG)HHAúûNB0<aèAúûDCúûf!I1|p= 20 THENŠCMP.L‚#20,EVE6 NTCNT-PBA(A6) ŠBGE.S‚TEST2*DO*‚EVENTCNT�=�0*‚enable�channel�1�interrupts*‚wait�for�event*END*ELSE*DO ŠBRA.S‚TEST3#*‚toggle�output�on�sucessive�events*END** TEST1…EQU„*!*Stage code for disable channel 1ŠLEA„INITIO-PBA(A6),A0ŠLEA„DSA1-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#6,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE„FAULT8 ŠBRA„WAIT* TEST2…EQU„*ŠCLR.L‚EVENTCNT"* Stage code for enable interruptsŠLEA„INITIO-PBA(A6),A0ŠLEA„ENA1-PBA(A6),A1²m»WÃTËŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#6,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE.S‚FAULT9 ŠBRA„WAIT* TEST3…EQU„*-*toggle EVENTCNT & output on sucessive eventsBŠBTSTƒ#0,EVENTCNT+3-PBA(A6)�Micky�Mouse�way�to�test�LS�byte�in�mem ŠBNE.S‚LAMPON*Stage code for OFF-ŠLEA„INITIO-PBA(A6),A0‚point�to�command�tableŠLEA„OFFCMD-PBA(A6),A1;ŠMOVE.L�A1,CMDA-PBA(A6)„pass�address�of�RIO�parameter�block+ŠMOVE.W�#6,CMDL-PBA(A6)„pass�command�length)ŠMOVE.L�#60,D0�set�up�trap�1�service�codeŠTRAPƒ#1‘call�for�service"ŠBNE.S‚FAULT6�branch�on�trap�error ŠBRA„WAITŠSPC„3#LAMPON�EQU�*‚turn�output�(lamp)�on.**Stage code for ON-ŠLEA„INITIO-PBA(A6),A0‚point�to�command�tableŠLEA„ONCMD-PBA(A6),A1;ŠMOVE.L�A1,CMDA-PBA(A6)„pass�address�of�RIO�parameter�block#ŠMOVE.W�#6,CMDL-PBA(A6)„pass�length/ŠMOVE.L�#60,D0�setup�trap1�service�request�codeŠTRAPƒ#1 ŠBNE.S‚FAULT5ŠBRA„WAIT�wait�for�next�eventŠSPC„8*‚CLOSE�CHANNELSŠLEA„CLSCMD-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#CLSLNG,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 FAULT1„NOP FAULT2„NOP FAULT3„NOP FAULT4„NOP FAULT5„NOP FAULT6„NOP FAULT7„NOP FAULT8„NOP FAULT9„NOP FAULT10ƒNOP FAULT11ƒNOP FAULT12ƒNOP*‚DE-ACTIVATE�SELF ŠMOVE.L�#15,D0ŠTRAPƒ#1ŠSPC„10A*ƒ---ƒ---ƒ---�MOVE�THE�ASQ�MESSAGE�FROM�THE�ASQ�TO�RCVBUF‚---‚---ŠSPC„18TESTIRQƒEQU„*‚entry�point�moving�data�from�ASQ�to�RCVBUFŠLEA„RCVBUF-PBA(A6),A0!ŠMOVE.L�#34,D0„stage�command�codeŠTRAPƒ#1 ŠBNE.S‚FAULT4*‚RETURN�FROM�EVENT ŠMOVE.W�#1,A0!ŠMOVE.L�#37,D0„stage�command�codeŠTRAPƒ#1ŠRTS  ASQBLOCK‚EQU„*ŠDC.Lƒ0‰task�nameŠDC.Lƒ0‰dummy�field1ŠDC.B†5‰initial�status�of�ASQ�=�ASQ�&�ASR�enabled"ŠDC.B†16ˆlength�of�message�for�ASQŠDC.L†64ˆstorage�for�4�events4ŠDC.L†0‰logical�address�of�target�task�async�svc�rtnŠDC.L†0‰dummy�field*%RCVBUFƒDS.L†64ˆdefine�reciever�bufferEVENTCNT�DS.L†1‰event�counter**‚CMR�PARAMETER�BLOCK*INITIO„DC.Bƒ7,0,0,0ŠDC.Lƒ'RI01'†TASK�NAME ŠDC.Lƒ0,0,0*CMDA†DC.Lƒ0‹address�of�RIO�parameter�blockCMDL†DC.Wƒ0‹command�length*&*‚RIO�PARAMETER�BLOCK�to�open�channels*OPNCMD„DC.Wƒ0,1ŠDC.Wƒ9‘open�9�channels1ŠDC.Wƒ0,$7F00‹CHAN�0�IRQ�on�fall,�512�ms�debounce1ŠDC.Wƒ1,$3F04‹CHAN�1�IRQ�on�fall,�255�ms�debounce)ŠDC.Wƒ2,4�CHAN�2�interrupt�on�rising�edge*ŠDC.Wƒ3,0�CHAN�3�interrupt�on�falling�edge&*¢CHAN�4ˆ{{‚CH�4�IS�NO�GOOD�ON�HARDWAR0ŠDC.Wƒ5,1�CHAN�5�output�{{�hardware�checked�ok}}ŠDC.Wƒ7,1�CHAN�7�outputŠDC.Wƒ8,1�CHAN�8�outputŠDC.Wƒ9,1�CHAN�9�outputŠDC.Wƒ10,0�CHAN�10�INPUTOPNLNG„EQU„*-OPNCMD„lengthCLSCMD„DC.Wƒ0,2‰close�command(CLSLNG„EQU„*-CLSCMD„close�command�length*$*ˆRIO�parameter�block�for�ON�command ONCMD EQU *ŠDC.W…0‰returned�command�statusŠDC.W…3‰OUTPUT�ON�commandŠDC.W…$0020…turn�on�channel�#5‰SPC�5%*ˆRio�parameter�block�for�OFF�command‰SPC�1 OFFCMD EQU *&ŠDC.W…0‰return�command�status�locationŠDC.W…4‰off�commandŠDC.W…$0020…turn�off�channel�5ŠSPC�5 STATCMD EQU *ŠDC.W…0‰returned�command�statusŠDC.W…5‰read�commandŠDC.W…$0400…read�channel�10*:*ƒRIO�parameter�block�for�DISABLE�INTERRUPTS�on�channel�1:* DSA1…EQU�*‰DC.W†0‰returned�status‰DC.W†7‰disable�interrupt�code$‰DC.W†2‰bit�mask�selecting�channel�1**8*‚RIO�parameter�bl6 ock�for�ENABLE�INTERRUPTS�on�channel�1* ENA1…EQU�*‰DC.W†0‰returned�status‰DC.W†6‰enable�interrupt�code$‰DC.W†2‰bit�mask�selecting�channel�1******†stack‚definition* ŠDS.Bƒ$400 STACK…EQU„**PLS7:2* RIO parameter block to do 200 ms pulse on chan 7‰DC.W†0‰returned�cmd�status‰DC.W†8‰pulse�command�code‰DC.W†1‰one�channels‰DC.W†7‰pulse�channel�7‰DC.L†200ˆ200�ms�pulse‰SPC�2PLS8:1*RIO parameter block to do 300 ms pulse on chan 8‰DC.W†0‰returned�cmd�status‰DC.W†8‰pulse�command�code‰DC.W†1‰one�channels‰DC.W†8‰pulse�channel�8‰DC.L†300ˆ300�ms�pulsePLS9:1*RIO parameter block to do 550 ms pulse on chan 9‰DC.W†0‰returned�cmd�status‰DC.W†8‰pulse�command�code‰DC.W†1‰one�channels‰DC.W†9‰pulse�channel�9‰DC.L†550‡550�ms�pulse ŠEND�TESTNNNNNNNN*******************************************************************************Ì**Ì**™RIO1…Test�Programž**Ì**Ì*N********************************************************************************2* This program was written to test the RIO driver.**    *‰Modification�HistoryN*-----------------------------------------------------------------------------*�11/02/84‡DUH�Initial�writing   *�1.‚Introduction*D*‰This�program�was�written�to�test�the�RIO�driver.‚This�program�willJ*‚ask�for�the�channel�number.‚It�will�then�put�up�a�menu�for�the�following *‚functions:*…1.‚Turn�an�output�channel�on. *…2.‚Turn�an�output�channel�off.*…3.‚Pulse�an�output�channel.)*…4.‚Read�the�status�of�an�input�channel.:*…5.‚Enable�and�wait�for�an�interrupt�on�an�input�channel.*6*‰This�program�assumes�the�board�is�jumpered�as�shown:*%*„J9‚1,2‚3,4‚7,8…address�offset�$0021=*„The�interrupt�level�for�all�4�interrupts�should�be�on�INT3.*ŠPAGE ,*£ASCVAL,�BHLCVT,�and�CVT2�are�commonly�used**£functions�which�are�modules�in�a�library(*£file�called�UTILIB.RO.‚A�call�to�these'*£functions�are�included�in�this�source)*£program,�which�is�provided�with�an�XREF&*£declaration.‚This�also�requires�that'*£UTILIB7 .RO�be�available�to�the�linkage$*£editor�during�the�linking�process.!*£See�RIO.LF�for�link�chain�file. -ŠXREFƒASCVAL�Converts�ASCII�to�a�binary�value$*£This�routine�will�convert�an�ASCII,*£character�string�representing�a�decimal�or,*£hexidecimal�value�to�the�equivalent�binary,*£value.‚If�a�dollar�sign�($)�is�encountered&*£hexidecimal�conversion�is�performed;,*£otherwise�decimal�conversion�is�performed.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary'*£value.‚Conversion�terminates�when�the)*£first�invalid�character�is�encountered.'*£ENTRY:‚A0�-�Starting�address�of�ASCII*°character�string�to�convert#*£EXIT�:‚D1�-�Character�that�caused *°termination%*«D2�-�Class�code�of�terminating�charÓBÜ;ä?ìGôIü7O CWX$B"*«D3�-�Binary�result�of�conversion*«A0�-�Address�of�the�character *°following�the�terminating�char 8ŠXREFƒBHLCVT�Converts�4-byte�binary�value�to�ASCII�digit)*£This�routine�will�convert�a�long�binary-*£word�value�to�a�hexadecimal�value�expressed)*£as�an�8�character�ASCII�string.‚Leading*£zeros�are�suppressed.,*£ENTRY:‚D0.L�-�Binary�value�to�be�converted(*£EXIT�:‚D2.L�-�Four�high�order�bytes�of*²converted�value *«D3.L�-�Four�low�order�bytes�of*²converted�value 6ŠXREFƒCVT2�Converts�two�ASCII�decimal�digits�to�binary-*£This�routine�will�convert�two�ASCII�decimal(*£digits�to�the�equivalent�binary�value.+*£An�empty�character�string�field�passed�to,*£this�function�in�A0�produces�a�zero�binary**£value.‚Conversion�terminates�when�a�non-*£decimal�digit�is�encountered)*£ENTRY:‚A0�-�Address�of�most�significant*°ASCII�decimal�digit)*£EXIT�:‚D0�-�Binary�result�of�conversion!*«A0�-�Address�of�the�terminating *°character ŠPAGEŠMOVE.L�A0,IOSOUT+16-PBA(A4)�Set�the�ending�address�of�messageŠLEA„IOSOUT(PC),A0ŠTRAPƒ#2ŠENDM ŠPAGE 2ŠOPT„PCS�We�use�a�PCS�option�so�the�assembler�will%*£force�PC�relative�addressing�within(*£SECTION.‚Forces�PC�relative�addressing-*£(whenever�such�an�addressing�mode�is�legal))*£in�an�instruction�which�occurs�within�a'*£relocatable�SECTION�and�references�an,*£operand�in�a�relocatable�SECTION�(need�not**£be�the�same�SECTION�as�the�instruction).,*£Failure�to�resolve�sucn�a�reference�into�a-*£16-bit�displacement�from�the�PC�will�result)*£in�an�error.‚This�option�may�be�used�to+*£force�position�independent�code;�however,(*£this�option�does�not�force�PC�relative,*£addressing�of�absolute�operands�or�unknown*£forward�references. ŠPAGE N*******************************************************************************Ì**™D�A�T�AƒS�E�C�T�I�O�Nœ**Ì*N****************************************************************************** ŠSECTION�DATA $PBA‡EQU„*’Program�Base�Address�(PBA)%*£This�label�is�used�to�designate�the+*£beginning�of�the�program.‚This�is�used�to'*£make�references�to�other�parts�of�the*£program,�relocatable. 6ŠDS.WƒSTACKLEN‹This�is�the�stack�area�for�the�RIO�test2STACK…EQU„*’program.‚Registers�and�other�important,*£information�will�be�stored�on�the�stack�as)*£the�program�is�executed.‚The�stack�area'*£is�dynamic�and�will�change�during�the *£execution�of�the�test�program. =INPUTBUF‚DS.WƒSTRNGLEN‹This�is�the�storage�area�for�the�input*£strings�that�are�entered. 9STATUS„DS.Lƒ1’This�will�be�the�storage�are�for�the�status,*£code�that�is�returned�from�CMR.‚This�value-*£will�be�displayed�to�show�the�user�what�the*£error�code�was. 6NUMBER„DS.Lƒ2’Save�area�for�the�ASCII�value�of�STATUS.ŠPAGE N*******************************************************************************Ì*!*–P�A�R�A�M�E�T�E�RƒB�L�O�C�K�S—**Ì*N****************************************************************************** ŠNEXTWB”Force�even�boundaryIOSOUTŠDC.Bƒ0’Request�code"ŠDC.BƒWRITEŽFunction�specificationŠDC.Wƒ8’OptionsŠDC.Bƒ0’StatusŠDC.BƒCRT�Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address   ŠNEXTWB”Force�even�boundaryIOSINŠDC.Bƒ0’Request�code!ŠDC.BƒREAD�Function�specificationŠD8 C.Wƒ0’OptionsŠDC.Bƒ0’Status"ŠDC.BƒKEYBOARD‹Logical�unit�numberŠDC.Wƒ0’ReservedŠDC.Lƒ0’Random�record�numberŠDC.Lƒ0’Start�addressŠDC.Lƒ0’End�addressŠDC.Lƒ0’Length�of�data�transferŠDC.Lƒ0’Completion�address  CMRBLK„DC.Bƒ7’Initiate�I/OŠDC.BƒUNUSED�UnusedŠDC.WƒUNUSED�UnusedŠDC.Lƒ'RI01'�Channel�nameŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�UnusedŠDC.LƒUNUSED�Unused$ŠDC.Lƒ0’Address�of�I/O�control�block#ŠDC.Lƒ0’Length�of�I/O�control�blockŠPAGE*2*‚OPEN�command�parameter�block�for�the�RIO�driver:+OPEN_RIO‚DC.Wƒ0’Returned�status�from�driverŠDC.WƒOPEN�Open�command�codeŠDC.Wƒ1’#�of�channels�to�open-ŠDC.Wƒ0’Channel�to�open�(Dynamically�changed)-ŠDC.WƒDEFAULTŒChannel�configuration�(Dynamic)6OLEN_RIO‚EQU„*-OPEN_RIO‰Length�of�OPEN�parameter�block*=*‚START�OUTPUT�ON�command�parameter�block�for�the�RIO�driver:)ON_RIO„DC.Wƒ0’Returned�status�from�driverŠDC.WƒON‘ON�command�code2ŠDC.Wƒ0’Bit�mask�for�channels�to�turn�on�(Dynamic)2NLEN_RIO‚EQU„*-ON_RIO‹Length�of�ON�parameter�block*=*‚TURN�OUTPUT�OFF�command�parameter�block�for�the�RIO�driver:*OFF_RIOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒOFF�Off�command�code3ŠDC.Wƒ0’Bit�mask�for�channels�to�turn�off�(Dynamic)4FLEN_RIO‚EQU„*-OFF_RIOŠLength�of�OFF�parameter�block*;*‚PULSED�OUTPUT�command�parameter�block�for�the�RIO�driver:*PON_RIOƒDC.Wƒ0’Returned�status�from�driverŠDC.WƒPULSEŽPulse�command�codeŠDC.Wƒ1’#�of�channels,ŠDC.Wƒ0’Channel�number�(Dynamically�changed)/ŠDC.Lƒ0’Time�of�pulse�in�milliseconds�(Dynamic)6PLEN_RIO‚EQU„*-PON_RIOŠLength�of�PULSE�parameter�block*?*‚READ�INPUT�STATUS�command�parameter�block�for�the�RIO�driver:+READ_RIO‚DC.Wƒ0’Returned�status�from�driver*ŠDC.WƒREAD_STATUSˆRead�status�command�code.ŠDC.Wƒ0’Bit�mask�for�channels�to�read�and�upon(*§return�holds�the�actual�channel�status=RLEN_RIO‚EQU„*-READ_RIO‰Length�of�READ�STATUS�parameter�block*?*‚ENABLE�INTERRUPTS�command�parameter�block�for�the�RIO�driver:+ENAB_RIO‚DC.Wƒ0’Returned�status�from�driver-ŠDC.WƒENAB_INT‹Enable�interrupts�command�code2ŠDC.Wƒ0’Bit�mask�for�channels�to�enable�interruptsCELEN_RIO‚EQU„*-ENAB_RIO‰Length�of�ENABLE�INTERRUPTS�parameter�block*?*‚ENABLE�INTERRUPTS�command�parameter�block�for�the�RIO�driver:+DISB_RIO‚DC.Wƒ0’Returned�status�from�driver.ŠDC.WƒDISAB_INTŠEnable�interrupts�command�code3ŠDC.Wƒ0’Bit�mask�for�channels�to�disable�interrupts>DLEN_RIO‚EQU„*-DISB_RIO‰Length�of�DISABLE�INTERRUPTS�parameter*3*‚CLOSE�command�parameter�block�for�the�RIO�driver:)CLSBLK„DC.Wƒ0’Returned�status�from�driverŠDC.WƒCLOSEŽClose�command�codeCLOSLENƒEQU„*-CLSBLKŠNEXTWBŠPAGE N*******************************************************************************Ì**œM�E�S�S�A�G�E�S¡**Ì*N****************************************************************************** ŠSECTION�MESSAGES 5HEAD†DC.BƒCR,LF,LF,'RIO�Driver�Test�Program',CR,LF,LF HEADE…EQU„*-1ŠNEXTWB+MESS1…DC.BƒCR,LF,LF,'…0�=�OUTPUT�ON.',CR,LFMESS1E„EQU„*-1ŠNEXTWB#MESS2…DC.Bƒ'…1�=�OUTPUT�OFF.',CR,LFMESS2E„EQU„*-1ŠNEXTWB=MESS3…DC.Bƒ'…2�=�PULSE�AN�OUTPUT�FOR�A�SPECIFIED�TIME.',CR,LFMESS3E„EQU„*-1ŠNEXTWB6MESS4…DC.Bƒ'…3�=�READ�THE�CURRENT�INPUT�STATUS.',CR,LFMESS4E„EQU„*-1ŠNEXTWB0MESS5…DC.Bƒ'…4�=�ENABLE�FOR�AN�INTERRUPT.',CR,LFMESS5E„EQU„*-1ŠNEXTWBMESS6…DC.Bƒ'…5�=�QUIT.',CR,LFMESS6E„EQU„*-1ŠNEXTWB5MESS10„DC.BƒCR,LF,'STATUS�OF�ALL�CHANNELS�(ASCII)�=�'MESS10EƒEQU„*-1ŠNEXTWB2MESS11„DC.Bƒ'…Number�of�the�channel�to�convertˆ>�'MESS11EƒEQU„*-1ŠNEXTWB)MESS12„DC.Bƒ'…Enter�one�of�the�above...�'MESS12EƒEQU„*-1ŠNEXTWB9MESS13„DC.Bƒ'…Time�(in�milliseconds)�for�output�pulse�>�'MESS13EƒEQU„*-1ŠNEXTWB2MESS14„DC.BƒCR,LF,'<<<�Starting�command�>>>',CR,LFMESS14EƒEQU„*-1ŠNEXTWB1MESS15„DC.BƒCR,LF,'<<<�Command�done�>>>',CR,LF,LFMESS15EƒEQU„*-1ŠPAGEŠNEXTWB6BADON…DC.BƒCR,LF,'***�START�OUTPUT�ON�ABORTED�***�--�'BADONE„EQU„*-1ŠNEXTWB7BADOFF„DC.BƒCR,LF,'***�TURN�OUTPUT�OFF�ABORTED�***�--�'BADOFFEƒEQ8 U„*-1ŠNEXTWB:BADPLS„DC.BƒCR,LF,'***�START�OUTPUT�PULSE�ABORTED�***�--�'BADPLSEƒEQU„*-1ŠNEXTWB,BADOPN„DC.BƒCR,LF,'***�OPEN�ABORTED�***�--�'BADOPNEƒEQU„*-1ŠNEXTWB8BADEN…DC.BƒCR,LF,'***�ENABLE�INTERRRUPT�ABORTED�***�--�'BADENE„EQU„*-1ŠNEXTWB:BADDIS„DC.BƒCR,LF,'***�DISABLE�INTERRRUPT�ABORTED�***�--�'BADDISEƒEQU„*-1ŠNEXTWB4BADREADƒDC.BƒCR,LF,'***�READ�STATUS�ABORTED�***�--�'BADREADE‚EQU„*-1ŠNEXTWB-BADCLS„DC.BƒCR,LF,'***�CLOSE�ABORTED�***�--�'BADCLSEƒEQU„*-1ŠNEXTWB+STATUSMƒDC.Bƒ'Error�code�returned�in�D0�=�'STATUSME‚EQU„*-1ŠNEXTWBCRLF†DC.BƒCR,LF CRLFE…EQU„*-1ŠNEXTWBŠPAGE N*******************************************************************************Ì**–P�R�O�G�R�A�MƒS�E�C�T�I�O�N™**Ì*N****************************************************************************** ŠSECTION�CODEPROGSTRTŠLEA„STACK(PC),A7.ŠLEA„PBA(PC),A4‰Get�Program�Base�Address�(PBA) &ŠOUTPUT�HEAD,HEADE‰Display�the�heading N*-----------------------------------------------------------------------------***‰Get�the�number�of�the�channel�to�convert*N*-----------------------------------------------------------------------------GETCHAN0ŠOUTPUT�MESS11,MESS11E…Channel�number�to�convertŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary(ŠIF.L�D0��#0�OR.L�D0��#15�THEN.S ŒBRA�GETCHANŠENDI8ŠMOVE.W�D0,OPEN_RIO+6-PBA(A4)�Save�the�channel�number...ŠMOVE.W�D0,PON_RIO+6-PBA(A4) =ŠLEA„BIT_NUMBER(PC),A0‚Convert�the�channel�number�(0-15)�into7ŠLSL.B‚#1,D0Žthe�corresponding�bit�number�(1,2,4,8...).ŠMOVE.W�(A0,D0.W),D08ŠMOVE.W�D0,READ_RIO+4-PBA(A4)�Save�the�bit�mask�value...ŠMOVE.W�D0,ENAB_RIO+4-PBA(A4)ŠMOVE.W�D0,DISB_RIO+4-PBA(A4)ŠMOVE.W�D0,ON_RIO+4-PBA(A4)ŠMOVE.W�D0,OFF_RIO+4-PBA(A4) N*-----------------------------------------------------------------------------*3*‰Get„0�=�OUTPUT�ON„1�=�OUTPUT�OFFŠ2�=�PULSE�OUTPUT0*�3�=�READ�STATUS‚4�=�ENABLE�INTERRUPTSƒ5�=�QUIT*N*-----------------------------------------------------------------------------GETCLST'ŠOUTPUT�MESS1,MESS1E…Put�up�the�menu...ŠOUTPUT�MESS2,MESS2EŠOUTPUT�MESS3,MESS3EŠOUTPUT�MESS4,MESS4EŠOUTPUT�MESS5,MESS5EŠOUTPUT�MESS6,MESS6EHGET_CHOICE‚OUTPUT�MESS12,MESS12EƒAsk�the�user�to�enter�one�of�the�above. +ŠINPUT‚INPUTBUF,INPUTBUF+8�Get�their�choiceŠLEA„INPUTBUF(PC),A0)ŠBSR„CVT2�Convert�ASCII�decimal�to�binary'ŠIF.W�D0��#0�OR.W�D0��#5�THEN.S�BRA.S�GET_CHOICEŠENDIŠPAGE**‰0�=�Start�output�ON�command:*ŠIF.B�D0��#0�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS14,MESS14Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A02ŒLEA„ON_RIO(PC),A1„Start�output�ON�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#NLEN_RIO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�ON_RIO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADON,BADONE…***�START�OUTPUT�ON�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS15,MESS15Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDIŠPAGE**‰1�=�Turn�output�OFF�command:*ŠIF.B�D0��#1�THEN.S 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS14,MESS14Eƒ<<<ƒStarting�commandƒ>>> >ŒMOVE.W�#DEFAULT,D0†Use�the�default�configuration�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A03ŒLEA„OFF_RIO(PC),A1ƒTurn�output�OFF�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#FLEN_RIO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�OFF_RIO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)6ŽOUTPUT�BADOFF,BADOFFE„***�TURN�OUTPUT�OFF�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS15,MESS15Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDIŠPAGE**‰2�=�PULSE�an�output�command:*ŠIF.B�D0��#2�THEN.L3ŒBSR„GET_TIME‰Get�the�pulse�duration�(milliseconds)+ŒMOVE.L�D3,PON_RIO+8-PBA(A4)�Sto9 re�the�time 'ŒBSR.L‚CLOSE_ALLˆGo�close�all�channels./ŒOUTPUT�MESS14,MESS14Eƒ<<<ƒStarting�commandƒ>>> 6ŒMOVE.W�#DEFAULT,D0†Use�the�WAKEUP�option�for�the�open$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A06ŒLEA„PON_RIO(PC),A1ƒStart�output�pulse�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#PLEN_RIO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1*7*ƒDRIVER�DOES�NOT�SUPPORT�WAKEUP�AFTER�AN�OUTPUT�PULSE.**‹MOVE.L�#19,D0 *‹TRAPƒ#1 ŒIF��THEN.SŽMOVE.W�PON_RIO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)9ŽOUTPUT�BADPLS,BADPLSEƒ***�START�OUTPUT�PULSE�ABORTED�***ŽBRA.L‚SHOW_D0ŒENDI 3ŒOUTPUT�MESS15,MESS15E…***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDIŠPAGE* *‰3�=�Read�input�status�command:*ŠIF.B�D0��#3�THEN.L /ŒOUTPUT�MESS14,MESS14Eƒ<<<ƒStarting�commandƒ>>> ŒBSR.L‚CLOSE_ALL'ŒMOVE.W�#$000E,D0ˆSet�for�input�channel$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel ŒLEA„CMRBLK(PC),A06ŒLEA„READ_RIO(PC),A1‚Read�input�status�parameter�blockŒMOVE.L�A1,$14(A0)ŒMOVE.W�#RLEN_RIO,$18(A0)ŒMOVE.L�#CMR,D0ŒTRAPƒ#1ŒIF��THEN.SŽMOVE.W�READ_RIO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)4ŽOUTPUT�BADREAD,BADREADEƒ***�READ�STATUS�ABORTED�***ŒENDI ŒCLR.L‚D0<ŒMOVE.W�READ_RIO+4-PBA(A4),D0‚Get�the�status�value�returned.ŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŒOUTPUT�MESS10,MESS10EŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFE 3ŒOUTPUT�MESS15,MESS15E…***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDIŠPAGE* *‰4�=�Enable�interrupts�command:*ŠIF.B�D0��#4�THEN.S /ŒOUTPUT�MESS14,MESS14Eƒ<<<ƒStarting�commandƒ>>> ŒBSR.L‚CLOSE_ALL 3ŒMOVE.W�#$7F0C,D0ˆEnable�interrupts,�WAKEUP�option,8*‡software�debounce�=�508mSec,�trigger�on�positive�edge.$ŒBSR.L‚OPEN_CHANˆGo�open�the�channel *(*‚Do�a�wait�until�the�driver�wakes�us�up*ŒMOVE.L�#19,D0ŒTRAPƒ#1 ŒIF��THEN.SŽMOVE.W�ENAB_RIO(PC),D0ŽMOVE.L�D0,STATUS-PBA(A4)6ŽOUTPUT�BADEN,BADENE„***�ENABLE�INTERRUPTS�ABORTED�***ŒENDI 3ŒOUTPUT�MESS15,MESS15Eƒ***‚<<<�Command�done�>>>‚***ŒBRA.L�GETCHAN�Go�start�over. ŠENDI    **‰5�=�quit�command:*ŠIF.B�D0��#5�THEN.S �BRA.L�EXITŠENDI ŠBRA.L�GETCHAN�Go�start�over.ŠPAGEM*----------------------------------------------------------------------------*+*‚GET�THE�TIME�DURATION�FOR�AN�OUTPUT�PULSE*M*----------------------------------------------------------------------------GET_TIMEŠOUTPUT�MESS13,MESS13EŠINPUT‚INPUTBUF,INPUTBUF+8ŠLEA„INPUTBUF(PC),A0 ŠBSR„ASCVAL+ŠIF.L�D3��#1�OR.L�D3��#$FFFF�THEN.S ŒBRA„GET_TIMEŠENDIŠAND.L‚#$0000FFFF,D3ŠRTS M*----------------------------------------------------------------------------**ƒOPEN�THE�CHANNEL*M*----------------------------------------------------------------------------OPEN_CHAN�LEA„CMRBLK(PC),A0ŠLEA„OPEN_RIO(PC),A1BŠMOVE.W�D0,OPEN_RIO+8-PBA(A4)‚Save�the�open�configuration�options.ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#OLEN_RIO,$18(A0)7ŠMOVE.L�#CMR,D0ŒHere�we�perform�an�executive�request�toŠTRAPƒ#1‘invoke�CMR.ŠIF��THEN.SŒMOVE.L�D0,STATUS-PBA(A4)+ŒOUTPUT�BADOPN,BADOPNE…***�OPEN�ABORTED�***ŒBRA.S‚SHOW_D0ŠENDIŠRTS M*----------------------------------------------------------------------------**ƒOUTPUT�THE�ERROR�CODE:*M*----------------------------------------------------------------------------:SHOW_D0ƒMOVE.L�STATUS(PC),D0†Get�the�status�value�returnedŠBSR„BHLCVT�Convert�it�to�ASCII9ŠMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŠMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytesŠOUTPUT�STATUSM,STATUSMEŠOUTPUT�NUMBER,NUMBER+7ŠOUTPUT�CRLF,CRLFE EXIT:ŠBSR.S‚CLOSE_ALL +EXIT_OUT:�MOVE.L�#15,D0�Terminate�this�taskŠTRAPƒ#1ŠPAGEN*-------------------------------------------------------------------9 ----------**‚CLOSE�ALL�CHANNEL'S�ROUTINE:*N*----------------------------------------------------------------------------- CLOSE_ALLŠLEA„CMRBLK(PC),A0ŠLEA„CLSBLK(PC),A1ŠMOVE.L�A1,$14(A0)ŠMOVE.W�#CLOSLEN,$18(A0)-ŠMOVE.L�#CMR,D0ŒTell�CMR�to�close�the�channelŠTRAPƒ#1ŠIF��THEN.SŒBSR„BHLCVT�Convert�it�to�ASCII9ŒMOVE.L�D2,NUMBER-PBA(A4)‚Save�the�upper�four�ASCII�bytes;ŒMOVE.L�D3,NUMBER+4-PBA(A4)�Save�the�lower�four�ASCII�bytes,ŒOUTPUT�BADCLS,BADCLSE…***�CLOSE�ABORTED�***ŒOUTPUT�NUMBER,NUMBER+7ŒOUTPUT�CRLF,CRLFE&ŒBRA.S‚EXIT_OUT‰Output�the�error�code.ŠENDI ŠRTS M*----------------------------------------------------------------------------*B*ƒTABLE�TO�CONVERT�THE�CHANNEL�NUMBER�(0-15)�TO�IT'S�CORRESPONDING-*ƒBIT�MAPPED�VALUE�(1,2,4,8,....$4000,$8000).*M*----------------------------------------------------------------------------'BIT_NUMBER‚DC.W‚1,2,4,8,$10,$20,$40,$805ŒDC.W‚$0100,$0200,$0400,$0800,$1000,$2000,$4000,$8000 ŠEND„PROGSTRTä' ACIADRV AF88  DISKLIB AFAA  æDRVLIB AFJJ$  EPCIDRV AFSS  IPCDRV AF\\  M300DRV AFee  M319DRV AFnn  M320DRV AFww  æM331DRV AF€€  M360DRV AF‰‰  M420DRV AF’’  M435DRV AF››  MFPDRV AF¤¤  MPCCDRV AF­­  MPSCDRV AF¶¶  MPSCSPR AF¿¿  MPSCSUP AFÈÈ  P050DRV AFÑÑ  P117DRV AFÚÚ  PIADRV AFãã  =/*=/*†ACIADRV.AF=/*-=/* Chain file to assemble ACIA serial driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to ACIADRV.LS=/*=/IFC \1ƒ=ARG�ACIADRV.LS=/ENDIF=/*$=ASM ACIADRV.SA,ACIADRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDNNNNN: 0=/*=/*†DISKLIB.AF=/*,=/* Chain file to assemble library for disks=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to DISKLIB.LS=/*=/IFC \1ƒ=ARG�DISKLIB.LS=/ENDIF=/*$=ASM DISKLIB.SA,DISKLIB.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNN9=/* =/*†DRVLIB.AF=/*<=/* Chain file to assemble DRVLIB.*.SA, driver library files=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to DRVLIB.LS=/*=/IFC \1ƒ=ARG�DRVLIB.LS=/ENDIF=/*.=ASM DRVLIB.LOGPHY.SA,DRVLIB.LOGPHY.RO,\1;Z=75=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.STR.EQ=/*}=/*=/*/=ASM DRVLIB.QEVENT.SA,DRVLIB.QEVENT.RO,\1;GZ=75=/*{ Included files are:=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.UTILITY.MC=/*}=/*=/*1=ASM DRVLIB.SETTIME.SA,DRVLIB.SETTIME.RO,\1;GZ=75=/*{ Included files are:=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*}=/*=ENDNNN: NNB%=/*=/*†EPCIDRV.AF=/**=/* Chain file to assemble SIG 2661 driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to EPCIDRV.LS=/*=/IFC \1ƒ=ARG�EPCIDRV.LS=/ENDIF=/*$=ASM EPCIDRV.SA,EPCIDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.SIG2661.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDNNNNNK=/* =/*†IPCDRV.AF=/*)=/* Chain file to assemble the IPC driver=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to IPCDRV.LS=/*=/IFC \1ƒ=ARG�IPCDRV.LS=/ENDIF=/*"=ASM IPCDRV.SA,IPCDRV.RO,\1;RZ=160=/*{ Included files are:=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.UTILITY.MC=/*}=/*=ENDN; NNNNT=/*=/*†M300DRV.AF=/*.=/* Chain file to assemble the IEEE-488 driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M300DRV.LS=/*=/IFC \1ƒ=ARG�M300DRV.LS=/ENDIF=/*&=ASM M300DRV.SA,M300DRV.RO,\1;-WRZ=180=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.M300DRV.EQ=/*ƒM300TABL.AI=/*ƒM300INIT.AI=/*ƒM300INTR.AI=/*ƒM300CMND.AI=/*}=/*=ENDNNNNN]=/*=/*†M319DRV.AF=/*J=/* Chain file to assemble the MVME319/MVME315 disk/tape controller driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M319DRV.LS=/*=/IFC \1ƒ=ARG�M319DRV.LS=/ENDIF=/*$=ASM M319DRV.SA,M319DRV.RO,\1;RZ=180=/*{ Included files are:=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.KILL.; MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNNf=/*=/*†M320DRV.AF=/*==/* Chain file to assemble the MVME320 disk controller driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M320DRV.LS=/*=/IFC \1ƒ=ARG�M320DRV.LS=/ENDIF=/*&=ASM M320DRV.SA,M320DRV.RO,\1;-WRZ=186=/*{ Included files are:=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*}=/*=ENDNNNNNo< =/*=/*†M331DRV.AF=/*F=/* Chain file to assemble the MVME331 communication controller driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M331DRV.LS=/*=/IFC \1ƒ=ARG�M331DRV.LS=/ENDIF=/*$=ASM M331DRV.SA,M331DRV.RO,\1;RZ=180=/*{ Included files are:=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.TRACE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNNx=/*=/*†M360DRV.AF=/*,=/* Chain file to assemble the VME360 DRIVER=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M360DRV.LS=/*=/IFC \1ƒ=ARG�M360DRV.LS=/ENDIF=/*$=ASM M360DRV.SA,M360DRV.RO,\1;RZ=130=/*{ Included files are:=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.DUALPORT.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995..DISK.EQ=/*ƒ9995..DISKCCB.EQ=/*ƒ9995..DISKMEM.EQ=/*}=/*=ENDNNNN< N�=/*=/*†M420DRV.AF=/*/=/* Chain file to assemble VME420 (SASI) driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M420DRV.LS=/*=/IFC \1ƒ=ARG�M420DRV.LS=/ENDIF=/*$=ASM M420DRV.SA,M420DRV.RO,\1;RZ=186=/*{ Included files are:=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*}=/*=ENDNNNNNNŠ=/*=/*†M435DRV.AF=/*.=/* Chain file to assemble the MAG tape driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to M435DRV.LS=/*=/IFC \1ƒ=ARG�M435DRV.LS=/ENDIF=/*&=ASM M435DRV.SA,M435DRV.RO,\1;-WRZ=150=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNN= NNN“=/* =/*†MFPDRV.AF=/*H=/* Chain file to assemble MK68910 serial port driver for local ports on=/* VME120 and VME133 boards.=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to MFPDRV.LS=/*=/IFC \1ƒ=ARG�MFPDRV.LS=/ENDIF=/*"=ASM MFPDRV.SA,MFPDRV.RO,\1;RZ=140=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*ƒ9999.MK68901.MK68901.EQ=/*}=/*=ENDNNNNNœ=/*=/*†MPCCDRV.AF=/*G=/* Chain file to assemble R68560 serial port driver for the local port*=/* on the VME050 system controller board.=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to MPCCDRV.LS=/*=/IFC \1ƒ=ARG�MPCCDRV.LS=/ENDIF=/*$=ASM MPCCDRV.SA,MPCCDRV.RO,\1;RZ=145=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=END= NNNNN¥=/*=/*†MPSCDRV.AF=/*6=/* Chain file to assemble NEC 7201 subordinate driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to MPSCDRV.LS=/*=/IFC \1ƒ=ARG�MPSCDRV.LS=/ENDIF=/*$=ASM MPSCDRV.SA,MPSCDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.MVME400.EQ=/*ƒ9995.&.NEC7201.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDNNNNN®=/*=/*†MPSCSPR.AF=/*K=/* Chain file to assemble NEC 7201 supervisor driver for the MVME400 board=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to MPSCSPR.LS=/*=/IFC \1ƒ=ARG�MPSCSPR.LS=/EN> DIF=/*$=ASM MPSCSPR.SA,MPSCSPR.RO,\1;RZ=106=/*{ Included files are:=/*ƒ9995.&.NEC7201.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNNN·=/*=/*†MPSCSUP.AF=/*B=/* Chain file to assemble NEC 7201 supervisor driver for the VM03=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to MPSCSUP.LS=/*=/IFC \1ƒ=ARG�MPSCSUP.LS=/ENDIF=/*$=ASM MPSCSUP.SA,MPSCSUP.RO,\1;RZ=106=/*{ Included files are:=/*ƒ9995.&.NEC7201.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNNN> À=/*=/*†P050DRV.AF=/*?=/* Chain file to assemble printer driver for the MVME050 board=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to P050DRV.LS=/*=/IFC \1ƒ=ARG�P050DRV.LS=/ENDIF=/*$=ASM P050DRV.SA,P050DRV.RO,\1;RZ=146=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.PRNT.EQ=/*ƒ9995.&.PRNTCCB.EQ=/*}=/*=ENDNNNNNÉ=/*=/*†P117DRV.AF=/*C=/* Chain file to assemble the printer driver for the MVME117 board=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to P117DRV.LS=/*=/IFC \1ƒ=ARG�P117DRV.LS=/ENDIF=/*$=ASM P117DRV.SA,P117DRV.RO,\1;RZ=146=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.PRNT.EQ=/*ƒ9995.&.PRNTCCB.EQ=/*}=/*=ENDNNN? NNÒ=/* =/*†PIADRV.AF=/*8=/* Chain file to assemble the printer driver for a PIA.=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to PIADRV.LS=/*=/IFC \1ƒ=ARG�PIADRV.LS=/ENDIF=/*"=ASM PIADRV.SA,PIADRV.RO,\1;RZ=146=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.PRNT.EQ=/*ƒ9995.&.PRNTCCB.EQ=/*}=/*=ENDNNNNNNÛ' PRNTLIB AFðð  RWINDRV AFùù  SCCDRV AF  SCSIDRV AF    SIODRV AF  TERMLIB AF  VM22DRV AF&&  M300CMNDAI//1k  M300INITAIppì  300INTRAI‘ ‚g 4  ? =/*=/*†PRNTLIB.AF=/*,=/* Chain file to assemble library for disks=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to PRNTLIB.LS=/*=/IFC \1ƒ=ARG�PRNTLIB.LS=/ENDIF=/*$=ASM PRNTLIB.SA,PRNTLIB.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.PRNT.EQ=/*ƒ9995.&.PRNTCCB.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDNNNNNè=/*=/*†RWINDRV.AF=/*&=/* Chain file to the RWIN disk driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to RWINDRV.LS=/*=/IFC \1ƒ=ARG�RWINDRV.LS=/ENDIF=/*$=ASM RWINDRV.SA,RWINDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*}=/*=ENDNNNNN@ Nñ=/* =/*†SCCDRV.AF=/*F=/* Chain file to assemble Z8530 serial port driver for the local port$=/* on the VME117 and VME133 boards.=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to SCCDRV.LS=/*=/IFC \1ƒ=ARG�SCCDRV.LS=/ENDIF=/*"=ASM SCCDRV.SA,SCCDRV.RO,\1;RZ=140=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDNNNNNú=/*=/*†SCSIDRV.AF=/*&=/* Chain file to the SCSI disk driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to SCSIDRV.LS=/*=/IFC \1ƒ=ARG�SCSIDRV.LS=/ENDIF=/*$=ASM SCSIDRV.SA,SCSIDRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*}=/*=ENDNN@ NNN=/* =/*†SIODRV.AF=/*H=/* Chain file to assemble MK68564 serial port driver for the local port=/* on the VM04 board.=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to SIODRV.LS=/*=/IFC \1ƒ=ARG�SIODRV.LS=/ENDIF=/*"=ASM SIODRV.SA,SIODRV.RO,\1;RZ=140=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDNNNNN =/*=/*†TERMLIB.AF=/*0=/* Chain file to assemble library for terminals=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to TERMLIB.LS=/*=/IFC \1ƒ=ARG�TERMLIB.LS=/ENDIF=/*$=ASM TERMLIB.SA,TERMLIB.RO,\1;RZ=155=/*{ Included files are:=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.TERMCCB.EQ=/*ƒ9995.&.BAB.EQ=/*ƒ9995.&.KILL.MC=/*ƒ9995.&.KILLDRV.EQ=/*}=/*=ENDA NNNNN=/*=/*†VM22DRV.AF=/*&=/* Chain file to the VM22 disk driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to VM22DRV.LS=/*=/IFC \1ƒ=ARG�VM22DRV.LS=/ENDIF=/*$=ASM VM22DRV.SA,VM22DRV.RO,\1;RZ=150=/*{ Included files are:=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.&.UTILITY.MC=/*ƒ9995.&.DISK.EQ=/*ƒ9995.&.DISKCCB.EQ=/*ƒ9995.&.DISKMEM.EQ=/*}=/*=ENDNNNNNN0 TTL GPIB DRIVER - COMMAND PROCESSING - MAINLINE PAGE;*************************************************************’GPIB�COMMAND�PROCESSOR*8*ƒThe�function�of�the�command�processor�is�to�coordinate7*ƒand�set�up�all�commands�and�activity�on�A the�BUS.�Upon9*ƒreception�of�a�command,�the�processor�will�perform�what8*ƒbasic�validations�of�parameter�blocks�and�command�type7*ƒit�can.�Within�the�CCB�for�this�channel�is�a�circular8*ƒqueue�area�which�will�control�the�dispatch�of�commands7*ƒto�the�BUS.�When�the�command�can�be�executed,�further6*ƒcommand�mode�validations�are�made�at�run�time�and�if;*ƒsuccessful,�control�will�be�passed�to�the�menu�processor.*7*ƒEach�command�is�made�up�of�a�group�of�sub-commands�or6*ƒmenu�items�and�these�menu�items�will�be�executed�one;*ƒat�a�time�until�the�command�menu�is�completely�processed.5*ƒAfter�the�first�menu�item�is�initiated,�the�rest�of:*ƒthe�menu�flow�will�be�handled�by�the�interrupt�processor*ƒportion�of�the�GPIB�driver.**‰ENTRY:�JSR�FROM�CMR�HANDLER=*�A2�-�Phsical�Address�of�Initiate�I/O�Parameter�Block�(IIPB)9*�A5�-�Phsical�Address�of�the�CCB�of�the�requested�device1*�A6�-�Phsical�Address�of�the�attached�task's�TCB*?*‰EXIT:�RTS�-�Command�validation�return�code�in�D0�(always�=�0)*K****************************************************************************/*ƒPerform�some�of�the�basic�checks�of�the�IOSPB* CMNDGPIB: MOVEQ #0,D5:�MOVE.L�XIOCPK(A2),D6‡set�up�addr�of�command�packet�(IOCB)5�MOVE.W�XIOPLN(A2),D5†set�up�length�of�command�packet3�MOVE.L�CCBTASKA(A5),A1„set�up�caller's�TCB�address3�BSR�IOADRCHKŽconvert�logical�to�physical�addresses�BEQ.S�CMNDG010Œgood�return*5�MOVEQ‚#ISTAIP,D1‰set�invalid�parm�block�error�to�IOS�BRA�CMNDEX1�exit�processor*"CMNDG010�MOVE.L�D6,A3†A3�<==�IOSPB �MOVE.L�XIOUID(A2),A4†A4�<==�DCB3 BTSTW #GPIBDOWN,BUSACTIV(A5) is this channel down?�BEQ.S�CMNDG015Žbr�=�no=�MOVEQ�#ISTACDN,D1‹return�error�=�unrecoverable�channel�error BRA CMNDEXIT*'40:8:@@HP-X<` >CMNDG015�CMP.W�#IOHALT,IOSFCT(A3)‚is�this�an�I/O�HALT�command?�BEQ�HALTIO�branch�if�yes**‚Go�lookup�(validate)�command*?�BSR�GETCMDPŽD2�=�Relative�index�of�GPIB�function�from�IOSCMDTB:�BNE.S�CMNDEXIT‹br�=�command�not�found,�return�error�in�D1*8*‚Validate�any�buffer�addresses�if�this�command�requiresJ*‚data�buffers�(D6�=�Sec./Config.�buffer�addr.�or�0,�&�D7�=�Primary�buffer*‚address�or�0)*;�BSR�VALIDATE�validate�any�buffer�addresses�&�command�info.@�BNE.S�CMNDEXIT‹br�=�error�during�validation,�return�error�in�D1*A*‚The�command�is�validated,�perform�final�checks�and�either�queue*ˆor�execute�the�command.* INHIB MOVEQ #0,D3'�MOVE.B�DCBCDV(A4),D3Œget�device�number>�MOVE.W�DEVQBSY(A5),D0ŠD0�<==�current�bit�map�of�busy�dev�#'s.�BTST�D3,D0”is�device�busy?6�BNE.S�CMNDG120’branch�=�yes,�return�device�busy�error*9*‚Check�to�see�if�there�is�any�I/O�in�progress�on�the�BUS*'�MOVE.L�QHEAD(A5),D1Šis�the�queue�busy? CMP.L QTAIL(A5),D1�BEQ.S�CMNDG100�branch�if�no*=*‚The�GPIB�is�busy�so�queue�this�command�for�future�execution*!�BSR�PSHGPIBQ‘push�entry�on�queue>�BEQ.S�CMNDG120�ERROR,�queue�is�full,�return�device�busy�error4�MOVE.W�DEVQBSY(A5),D0‡mark�the�device�as�being�busy BSET D3,D0.�MOVE.W�D0,DEVQBSY(A5)‡restore�busy�map�to�CCB�BRA.S�CMNDOK‘exit*A*‚Since�the�queue�is�not�busy�the�command�may�be�executed�at�thisG*‚time�so�validate�that�the�bus�is�in�the�proper�mode�for�this�command.*MCMNDG100�MOVEM.L�D3-D7,-(A7)ƒSave�primary�and�secondary�buf�addr's�and�length1�BSR�VALOPER‹check�mode�and�operational�abilities/�MOVEM.L�(A7)+,D3-D7‚restore�addr's�and�lengths�TST.B�D1�any�errors?�BNE.S�CMNDEXIT†branch�if�error*/�BSR�PSHGPIBQ’push�current�command�on�the�queue!�BEQ.S�CMNDG120�error,�queue�full%�BSR�BUILDMENU‘build�menu�for�command�BEQ.S�CMNDG110�BR‚=�continue*&�BSR�POPGPIBQ“else�remove�queue�entry,5�MOVEQ�#ISTADRVE,D1Œset�driver�run-time�error�status,#�BRA.S�CMNDEXIT�and�exit�with�error*B =CMNDG110�MOVE.W�DEVQBSY(A5),D0Šget�busy�device�number�bit�map"�BSET�D3,D0”set�device�number�busy%�MOVE.W�D0,DEVQBSY(A5)‰update�bit�map*B*‚Start�execution�of�the�current�command�since�the�BUS�is�not�busy*9�MOVE.L�CCBCHB(A5),A1‰set�base�address�of�GPIBC�registers"�BSR�PROCMENU‘initiate�I/O�on�menu�BRA.S�CMNDOK�just�exit*4CMNDG120�MOVEQ�#ISTADB,D1…set�device�busy�error�code*CCMNDEXIT MOVE.B D1,IOSSTA(A3) save error code in IOSPB status field2CMNDEX1‚MOVE.B�#XPSNRM,D4„set�event�type�to�normal"�BSR�QEVENT“queue�the�event�to�IOS*=*‚Use�this�entry�point�when�no�event�is�to�be�sent.�The�event*‚will�be�sent�at�a�later�time.*(CMNDOK�UNMASK‚set�interrupt�mask�to�zero�MOVEQ�#0,D0ƒset�return�O.K. RTS  PAGE**’HALT�I/O�TO�A�DEVICE*?*ˆThe�Halt�I/O�processor�will�halt�I/O�to�the�specified�device.&*ˆThere�are�several�cases�to�consider:3*’1.�A�halt�directed�to�the�BUS�while�a�controller,8*’2.�A�halt�directed�to�the�BUS�while�a�Talker/Listener,!*’3.�A�halt�directed�to�a�device.*?*ˆIn�the�first�case,�any�operation�in�progress,�all�queued�I/O,5*ˆand�any�SRQ�polling�in�progress�will�be�terminated!*;*ˆIn�the�second�case,�the�halt�is�(implied)�directed�to�the@*ˆcurrent�I/O�in�progress.‚That�operation�will�be�aborted�immed- *ˆiately.*<*ˆIn�the�third�case,�the�queue�is�searched�for�the�specified;*ˆI/O�command.‚If�found,�the�command�is�marked�'halted'�and:*ˆwill�be�removed�from�the�queue�when�its�turn�comes,�else#*ˆan�error�will�be�returned�to�IOS.**HALTIO:1�INHIB—don't�allow�this�process�to�be�interrupted=*>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 10/28/85 REV 4.5 >>>>>>>>>>>>>1�MOVE.L�QTAIL(A5),A6‰get�pointer�to�current�entry(�CMPA.L�QHEAD(A5),A6‰is�the�queue�empty?3�BEQ.S‚HALT40�YES,�send�back�invalid�command�status:�CLR.B‚IOSSTA(A3)‹send�good�completion�status�for�HALT�I/O=*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*+�MOVE.B�DCBCDV(A4),D0ˆget�the�device�number)�BNE.S�HALT50�br�=�halt�a�bussable�device*<�BTSTW�#CAC_S,BUSACTIV(A5)ƒtest�if�we�are�in�controller�mode>�BEQ.S�HALT50�br�=�no,�treat�halt�to�BUS�in�T/L�mode�as�device*:*ˆHalt�command�is�to�the�BUS�and�it�is�in�Controller�mode.9*ˆTerminate�any�SRQ�polling,�current�I/O,�and�queued�I/O.*  BSR HLTALL'�BNE.S�HALT40�br�=�invalid�halt�command*(HALT30�BRA.L�CMNDOKŠset�O.K.�halt�status*&HALT35�MOVEQ�#XPSHLT,D4†set�event�type4�BSR�QEVENT’send�halt�command�acknowledgement�to�IOS BRA CMNDOK*?*>>>>>>>>>>>>>>>>>>>>>>>�10/28/85‚REV�4.5�>>>>>>>>>>>>>>>>>>>>>8HALT40�MOVE.W�#ISTAIF,D1†set�invalid�halt�command�status5�MOVE.B�D1,IOSSTA(A3)†update�HALT�I/O�Parameter�blockA*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> BRA.S HALT35*6*ˆHalt�I/O�to�a�specific�device�or�the�BUS�in�T/L�mode*=HALT50�BSR�HLTCMDŒhalt�current�command�on�queue�(if�possible)�BNE.S�HALT40�br�=�error BRA.S HALT30 2‰TTL�GPIB�DRIVER�-�COMMAND�PROCESSING�(VALIDATION)‰PAGEB********************************************************************–VALIDATE�GPIB�COMMAND*<*ˆThis�section�will�validate�the�required�buffer�address�and4*ˆcommand�parameters.�If�the�addresses�are�valid�the<*ˆlogical�addresses�will�be�converted�to�physical�addresses.*)*“ENTER:ƒD2.W�-�relative�index�of�Command*œA1�-�TCB�address*œA2�-�IIPB�pointer*œA3�-�IOS�paramter�block*œA4�-�address�of�DCB*œA6�-�address�of�TCB**“EXIT:„IFƒD1�=�0ƒTHEN *¦Command�has�been�validated�and*¡D4�=�primary�buffer�length*¡D5�=�secondary�buffer�length-*¡D6�=�physical�secondary/config.�buffer�addr&*¡D7�=�physical�primary�buffer�address*¦or)*¡D4�=�primary�buffer�length�not�required+*¡D5�=�secondary�buffer�length�not�required,*¡D6�=�0�if�sec./config.�buffer�not�required'*¡D7�=�0�if�primary�buffer�not�required*œELSE�D1�=�error�code*!*ŽRegister�Usage:„0�1�2�3�4�5�6�7*žD‚*�R�PƒR�R�R�R *žA‚*�*ƒP�PƒP*E********************************************************************** VALIDATE:B B�LEA.L�VALPARTB(PC),A0ƒget�base�addr�of�validation�parameter�table@�MOVE.W�0(A0,D2.W),D0„get�validation�parameters�for�this�command MOVEQ #0,D63�MOVE.L�D6,D7Œclear�buffer�address�return�registers)�MOVE.L�D6,D4‹clear�buffer�length�primary+�MOVE.L�D6,D5‹clear�buffer�length�secondary4�MOVEQ�#ISTAADD,D1ˆpreset�invalid�address�error�code5�BTST.L�#BVALPBUF,D0…validate�primary�buffer�address?�BEQ.S�VALID010‰branch�if�no*#*ƒValidate�Primary�buffer�addresses*.�MOVE.L�IOSSAD(A3),D6…get�buffer�start�address,�MOVE.L�IOSEAD(A3),D5„get�buffer�end�address+�SUB.L�D6,D5�is�end�address�<�start�address*BLT.S�VALIDRT‹yes,�error<�BLO.S�VALIDRT‹yes,�error�*�r.e.m.�11/4/85�signed�32-bit�cmpNNNNN#�ADDQ�#1,D5Žaccount�for�true�length*-*‚Convert�primary�logical�address�to�physical*�BSR.S�IOADRCHK�convert�address�BNE.S�VALIDRT�branch�if�error4�MOVE.L�D6,D7�D7�<==�physical�addr�of�primary�buffer*�MOVE.L�D5,D4�D4�<==�Primary�buffer�length7�MOVEQ�#0,D6ŽClear�sec./config.�buffer�address�register*�MOVEQ�#0,D5ŽClear�secondary�buffer�length*VALID020�BTST�#BVALCBUF,D0‚validate�configuration�buffer�addr?�BEQ.S�VALID030�branch�if�no*'*‚Validate�configuration�buffer�address*;�MOVE.L�IOSDBP(A3),D6ˆget�logical�configuration�buffer�addr MOVEQ #0,D5F�MOVE.W�IOSVARL+DCBDEV(A4),D5„include�length�of�variable�area�(if�any)4�ADD.L�#IOSILN,D5Œadd�in�rest�of�configuration�block*3*‚Convert�configuration�logical�address�to�physical*9�BSR.S�IOADRCHK�convert�addr,�D6�=�Config.�buffer�address�BNE.S�VALIDRT�branch�if�error**ƒBuffer�validation�complete**ˆValidate�Command�Requirements* VALID030:NNC :�BTST�#BVALBDEV,D0�command�valid�only�for�bussable�device?,�BEQ.S�VALID125�br�=�no,�continue�validation< CMP.B #XDSGDEV,IOSDTP+DCBDEV(A4) is this a bussable device?�BEQ.S�VALID125�br�=�O.K.!?�MOVEQ‚#ISTAIVCB,D1‹else�set�invalid�command�for�BUS�error�code BRA.S VALIDRT*IVALID125�BTST�#BVALSCTL,D0‚does�command�require�system�controller�capab.?�BEQ.S�VALID130�branch�if�no?�MOVEQ‚#ISTAIVCB,D1ˆpre-load�invalid�command�for�BUS�error�code9�LEA.L�CONFINFO(A5),A0†get�pointer�to�device�config.�area7�MOVE.L�CNFIGPTR(A0),A0…get�pointer�to�BUS�config.�areaJ�BTSTW�#IOASCTC,IOSATW(A0)‚is�BUS�configured�for�system�controller�capab.?;�BEQ.S�VALIDRTŽbranch�=�no,�error�=�invalid�command�for�BUS*9VALID130�BTST�#BVALBUS,D0ƒcommand�valid�only�for�the�BUS?�BEQ.S�VALID175�branch�if�no@ CMP.B #XDSGBUS,IOSDTP+DCBDEV(A4) yes, check if this is the BUS!�BEQ.S�VALID175�br�=�o.k MOVEQ #ISTAIVBD,D1?�BRA.S�VALIDRTŽelse�exit�for�invalid�command�to�bussable�device*0VALID175�MOVEQ‚#ISTAOK,D1ƒset�return�code�=�O.K.*'VALIDRT�TST.B�D1�set�return�status�code RTS  PAGE* *ƒIOADRCHK*:*ˆThis�subroutine�will�check�the�address�boundaries�to�see1*…if�entirely�within�calling�tasks�address�space.*&*ˆENTER:‚D5�=�number�of�bytes�to�check%*�D6�=�68000�buffer�address�(logical)*�A1�=�TCB�address*8*ˆEXIT:ƒD6�=�physical�address�of�buffer�space�(if�legal)*�D1�=�0ƒno�error *•ElseƒError**ˆRMS68K�ROUTINES:�TR0$.LOGPHY*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�P�R�P�P�P�P�R�P*›A�P�P�P�P�P�P�P�P* IOADRCHK:< MOVEM.L A0-A6/D0/D2-D5/D7,-(A7) save all regs for EXEC call'�BTST�#0,D6‘is�buffer�on�word�boundary?#�BNE.S�IOHADR6Žbranch�on�no�(error)�TST.L�D5“is�length�zero?$�BEQ.S�IOHADR6Žbranch�if�yes�(error)*:�MOVE.L�TCBTST(A1),A0‡A0�<==�address�of�task�segment�table �TR0$.LOGPHY�,Žcall�exec‚routine!�BRA.S�IOHADR8Žgood�buffer�return7�NOP˜block�partially�in�task�space�(not�valid�for�GPIB)EIOHADR6�MOVEQ‚#ISTAADD,D1‚block�is�in�MMIO�space�(not�valid�for�GPIB) BRA.S IOHADR9*&IOHADR8�MOVEQ�#ISTAOK,D1…set�return�OK'IOHADR9 MOVEM.L (A7)+,A0-A6/D0/D2-D5/D7 RTS     NNNNNNNC ! TTL GPIB DRIVER - INITIALIZATION PAGE**„GPIB�Initialization*7*ˆThe�initialization�processor�will�perform�three�major7*ˆfunctions:�(1)�initialize�the�MVME300�card,�(2)�reset9*ˆthe�TMS9914A�chip�and�(3)�reset�all�software�parameters5*ˆassociated�with�this�channel.�Additionally,�a�short=*ˆfunctionality�go/no�go�test�will�be�performed�to�determined%*ˆif�the�channel�is�properly�working.*"*’ENTER:�A5�=�CCB�pointer�for�GPIB* INITGPIB:2�INHIB‰set�processor�priority�(inhibit�interrupts)*�CMP.B�#XTGBUS,CCBTYPE(A5)ƒvalid�GPIB�CCB?�BNE.S�INITG010‚no<�MOVE.L�CCBCHB(A5),A1‚A1�<==�base�address�of�GPIBC�registers1 BSR.S SETGPIBC perform first time initialization6�BSR�RESETIO‚reset�all�run-time�parameters�&�registers+ BNE.S INITG010 branch if error from MTFIFO#�BSR�BDGONOGO‚go/no�go�MVME300�test�BEQ.S�INITG20‚OK*:* Error - the channel is inoperable or invalid so mark the*‰down.:INITG010�BSETW�#GPIBDOWN,BUSACTIV(A5)‚mark�channel�'down'.*$*ƒTurn�on�the�front�panel�fail�light*G�MOVE.B�#1<* caused the interrupt. Also, the hardware configured priority(* level for each level will be the same.*3�MOVE.B�CCBVECT(A5),D1‡get�configured�vector�number.�MOVE.B�D1,VECTREG0(A1)†TMS9914A�vector�number2�MOVE.B�D1,VECTREG1(A1)†I/O�complete�vector�number/�MOVE.B�D1,VECTREG2(A1)†Bus�error�vector�number �MOVE.B�D1,VECTREG3(A1)†Not�used*?*‚Set�up�the�configured�hardware�priority�level�and�enable�them*>�MOVE.B�CCBPPRIO(A5),D1†get�configured�hardware�priority�level �AND.B�#7,D1‘mask�priority�level�OR.B�#$18,D1�enable�interrupt/�MOVE.B�D1,CONTREG0(A1)†TMS9914A�priority�level3�MOVE.B�D1,CONTREG1(A1)†I/O�complete�priority�level0�MOVE.B�D1,CONTREG2(A1)†Bus�error�priority�level*)*ƒDisable�vector�3�because�it�is�not�used*�AND.B�#$0F,D1�clear�enable�bit/�MOVE.B�D1,CONTREG3(A1)†disable�not�used�vector*<�MOVE.B�D0,RELCNT(A1)ˆenable�the�byte�count�release�registerC�MOVE.B�#$3D,ADDRMOD(A1)…set�address�modifier�reg�to�superv.,�short*%�MOVE.B�#SWRST1,AUXCMD(A1)ƒreset�9914(�MOVE.B�#VSTD1,AUXCMD(A1)„set�high�speed MOVE.B #SWRST0,AUXCMD(A1)*"*ˆSoftware�one-time�initialization* MOVEQ #0,D0.�MOVE.B�D0,IOPEND(A5)ˆclear�I/O�pending�status3�MOVE.B�D0,BINTCNT(A5)‡reset�interrupt�nesting�flag,�MOVE.W�D0,BUSACTIV(A5)†put�BUS�in�idle�mode+�MOVE.W�D0,DEVQBSY(A5)‡mark�no�devices�busy*6�LEA.L�GPIBQ(A5),A0ŠA0�<==�start�of�command�queue�area+�MOVE.L�A0,QHEAD(A5)‰init�queue�to�be�empty MOVE.L A0,QTAIL(A5)*5�MOVE.W�#$37EB,TMSMASK(A5)ƒinit�9914�intrp�masD k�(CCB)***‚Initialize�the�configuration�block�areas*1�LEA.L�CONFINFO(A5),A0‡set�all�30�entries�to�zero MOVEQ #29,D0SETG10 CLR.L (A0)+ DBRA D0,SETG10*9�LEA.L�CNFGAREA(A5),A0‡set�next�available�config�area�ptr7�MOVE.L�A0,NEXTCNFG(A5)†to�start�of�configuration�areas RTS  PAGE*<*ƒRESETIO�-�This�routine�will�implement�a�soft�reset�for�the*�MVME-300�and�the�driver.*$*ŽENTRY:�A5�=�address�of�CCB�pointer**ŽEXITƒD1�=�0‚No�errors-*—ELSE�D1�=�error�code�(hardware�malfunction)RESETIO:2�MOVE.L�CCBCHB(A5),A1ˆget�VME-300�I/O�base�addressE MOVE.B #1<*„in�the�GPIBC�FIFO.�It�is�meant�to�be�used�at�initialization,9*„HALT�I/O�sequences,�or�any�time�there�is�undesired�data*„left�in�the�FIFO.*-*‡ENTER:�A1�=�BASE�ADDRESS�OF�GPIBC�REGISTERS*!*‡EXIT:ƒD1�=�0ƒTHEN�FIFO�IS�EMPTY*‘ELSE�D1�=�ERROR�CODE* *ˆRegister�Usage†0�1�2�3�4�5�6�7*™D‚*�R*™A*MTFIFO:+�MOVE.W�#MAXFIFO+1,D1‚D1�<==�max�loop�count*6MTFIFO10 BTST.B #FIEMP,CNTRSTAT(A1) is the FIFO empty?"�BNE.S�MTFIFO20ƒyes,�task�complete?�MOVE.B�FIFODAT(A1),D0‚read�a�byte�from�the�FIFO�and�throw�away+�DBRA�D1,MTFIFO10‚continue�until�FIFO�empty<�MOVEQ�#ISTAHWMF,D1ƒD1�<==�return�hardware�malfunction�error�RTS’Exit�with�error�code*#MTFIFO20�MOVEQ�#ISTAOK,D1‚return�OK �RTSƒexit PAGE* *ƒBDGONOGO*<*ˆThis�routine�will�perform�a�short�functional�go/no�go�test<*ˆof�the�MVME300�card.‚It's�purpose�is�to�determine�the�size=*ˆof�the�DMA�FIFO�buffer�and�see�that�all�of�its�RAM�is�good.*(*’Enter:„A1�=�Base�address�of�GPIBC�regs*œA5�=�address�of�CCB*'*’Exit:…If�‚the�board�is�functional*œElseƒFIFO�buffer�error.**!*’Register�Usage:…0�1�2�3�4�5�6�7*£D‚*�**£A*H************************************************************************ BDGONOGO:$�MOVEQ�#0,D0‘initialize�counter/data*7BDG010 MOVE.B D0,FIFODAT(A1) store next pattern in FIFO$�ADD.W‚#1,D0�increment�pattern/count.�CMP.W�#MAXFIFO+1,D0‰Maximum�FIFO�size�reached0�BEQ.S�BDRTN1�Yes,�FIFO�is�not�going�full,�Error1�BTST.B�#FIFUL,CNTRSTAT(A1)‚is�the�FIFO�full�yet?$�BEQ.S�BDG010�no,continue�until�full*;*‚At�this�point,�the�FIFO�is�full�and�the�size�is�contained8*‚in�D0.W.‚Empty�the�FIFO�and�check�the�contents�against*‚the�data�that�was�input.*4�MOVE.W�D0,FIFOSIZ(A5)‡save�the�FIFO�size�in�the�CCB�MOVEQ�#0,D0‘reset�pattern�reg*4BDG020‚MOVE.B�FIFODAT(A1),D1ƒget�next�char�from�FIFO�CMP.B‚D0,D1“same�as�input�was?�BNE.S�BDRTN1“branch�if�error�ADD.W�#1,D0”increment�pattern.�BTST.B�#FIEMP,CNTRSTAT(A1)…is�the�FIFO�empty?(�BEQ.S�BDG020“branch�until�FIFO�is�empty+�MOVEQ�#ISTAOK,D1�indicate�everything�is�OK RTS*$BDRTN1�MOVEQ�#ISTAHWMF,D1‡FIFO�error �RTSœexit   D N. TTL GPIB DRIVER - INTERRUPT PROCESSING (MAIN) PAGEG*************************************************************************ƒGPIB�INTERRUPT�PROCESSOR*<*†The�following�interrupt�code�is�re-entrant�and�is�designed<*†to�handle�all�interrupts�that�may�occur�on�a�GPIB�channel.*:*†To�detect�all�GPIB�interrupts,�the�MVME300�card�uses�the;*†VERSAbus�Interruptor�Module�(VBIM)�chip�located�on�board.B*†The�VBIM�is�capable�of�handling�upto�four�sources�of�interrupts.<*†Currently�only�three�sources�of�interrupts�are�enabled�and;*†they�are:�Bus�Error�Interrupt,�I/O�Complete�Interrupt�andB*†TMS9914A�Interrupt.�Since�each�channel�can�only�have�one�vector,;*†these�three�sources�generate�the�same�vector�and�it�is�up8*†to�the�interrupt�processor�to�determine�the�reason�for*†interrupt�from�the�VBIM.*9*†NOTE:‚Upon�entry�CMR�has�saved�registers�A0,A1,�and�D0.*$*ˆENTER:�A5�=�address�of�CCB�pointer* INTRGPIB:+�MOVE.L�CCBCHB(A5),A1‚get�ptr�to�GPIBC�regs1�MOVEP.L�CONTREG0(A1),D0…read�all�vector�status's>�AND.L�#1<�MOVE.L�QTAIL(A5),A0„get�current�queue�pointer�(even�if�empty)(�CMPA.L�QHEAD(A5),A0„is�the�queue�empty?�BNE.S‚INTROK3‰br�=�no.�LEA.L‚CONFINFO(A5),A4ƒyes,�the�queue�is�empty,�MOVE.L�DVDCBPTR(A4),A4ƒso�set�A4�<=�BUS�DCB'�SUB.L‚A3,A3�set�up�dummy�IOSPB�address BRA.S INTROK4*4INTROK3�MOVE.L�DCBQOFST(A0),A4ƒA4�<==�address�of�DCB7�MOVE.L�IPBQOFST(A0),A3ƒA3�<==�address�of�current�IOSPB*.*ˆGive�DMA�complete�interrupt�highest�priority*DINTROK4�BTST.L�#IOCINT,D0‚did�an�I/O�complete�(DMA)�interrupt�occur?�BEQ.S�INTR100‚yes*, BTST #TMSINT,D0 was it a TMS9914 interrupt? BEQ INTR500 br = yes*'*ˆElse�it�must�be�a�BUS�ERROR�interrupt*E********************************************************************** *ƒBUS�ERROR*:*ˆThe�Bus�error�interrupt�is�generated�by�the�MVME300�cardB*ˆwhenever�a�DMA�bus�error�condition�occurs�during�a�transmission.8*ˆIf�there�was�no�I/O�in�progress,�the�interrupt�will�be>*ˆconsidered�spurious�and�will�generate�an�unsolicited�channel?*ˆinterrupt�to�IOS.‚If�I/O�was�in�progress,�the�current�command=*ˆwill�be�aborted�and�a�hardware�malfunction�error�event�sent *ˆto�IOS.*6�BSET.B�#VBIMENAB,CONTREG2(A1)‚enable�Bus�error�vector(�MOVE.L�QTAIL(A5),A0‚is�I/O�in�progress? CE MPA.L QHEAD(A5),A0�BEQ�INTREXIT‰branch�if�no*@*ƒIf�an�SRQ�was�in�progress,�abort�all�SRQ�processing�and�send�a$*ƒHardware�Malfunction�error�to�IOS.*B*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *ˆ4/24/84ƒbwn*9*ˆMust�inhibit�TMS9914A‚interrupts‚during�DMA�operations.*ˆMust�re-enable�here.*4�BSET.B�#VBIMENAB,CONTREG0(A1)‚re-enable�9914�intrps*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. MOVEQ #ISTABUS,D1 indicate hardware bus error�BSR�PROCMERR‚process�error�BRA�INTREXIT‚normal�exit6 TTL GPIB DRIVER - INTERRUPT PROCESSING (DMA COMPLETE) PAGEG*************************************************************************ƒI/O�COMPLETE*:*ˆThis�interrupt�is�generated�by�the�MVME300�card�whenever>*ˆa�DMA�WRITE�or�DMA�READ�has�completed.�Three�major�functions<*ˆare�accomplished�in�this�sectionand�they�are:�(1)�I/O�post6*ˆformatting�(if�specified)�after�a�DMA�WRITE/READ�has;*ˆcompleted,�(2)�menu�processing�and�initiation�and�(3)�SRQ *ˆprocessing.*8*ˆFor�post�I/O�formatting,�the�user�may�specify�a�formatD*ˆroutines�to�be�executed�upon�completing�the�desired�DMA�operation.<*ˆThese�routines�must�be�specified�at�sysgen�time�and�should*ˆreport�errors.*<*ˆThe�menu�processing�section�is�designed�to�either�initiate;*ˆthe�next�menu�item�or,�if�at�end�of�menu,�to�queue�an�I/O:*ˆcompletion�event�back�to�IOS�and�initiate�an�new�menu�if7*ˆthere�are�other�operations�waiting�on�the�GPIB�queue.*;*ˆThe�last�major�section�of�the�I/O�complete�portion�of�the8*ˆinterrupt�handler�is�to�handle�program�flow�of�service;*ˆrequest�functions�(SRQ)�when�received�in�controller�mode.?*ˆThe�processor�will�run�status�menues�to�each�device�connected;*ˆto�the�GPIB�until�the�device�requesting�service�is�found.;*ˆOnce�found,�an�SRQ�ASQ�event�will�be�sent�back�to�IOS�for*ˆexamination.*INTR100:5 MOVE.B #1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>/�MOVE.L�QTAIL(A5),A0‚current�menu�queue�pointer)�CMPA.L�QHEAD(A5),A0‚is�I/O�in�progress�?�BEQ�INTREXIT‰br�=�no*5�BTSTW�#CAC_S,BUSACTIV(A5)ƒare�we�in�controller�mode?�BEQ.S�INTR115�br�=�no*4�BTST�#LADS_B,ADDRSTAT(A1)ƒis�9914�in�listener�mode?�BEQ.S�INTR110�br�=�no7�MOVE.B�#TCS,AUXCMD(A1)†so�take�control�(synchronously)2�MOVE.B�DATAIO(A1),D0ˆread�reg�to�get�things�going BRA.S INTR115**ƒAll�data�DMA�sequences�require�the�length�of�the�transfer�toD*ƒbe�reported�back�in�the�IOS�parameter�block�originating�this�call.*<�MOVEQ�#0,D0ƒread�the�current�memory�location�in�the�MAR�reg/ MOVE.B MARMSB(A1),D0 get most significant byte ASL.L #8,D0+ MOVE.B MARISB(A1),D0 get intermediate byte ASL.L #8,D00�MOVE.B�MARLSB(A1),D0‚get�least�significant�byteB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*8*ˆThe�address�we�get�in�D0�is�the�address�as�seen�by�the*ˆMVME300�board.4*ˆIf�we�are�using�dual�ported�ram‚on�the�VME/10,�and5*ˆif�this�address�is�in�E on-board�ram,�then�it�must�be:*ˆtranslated�to�an�on-board�address�as�the�driver�sees�it.8*ˆWe�do�this�by�subtracting�the�RAM_SKEW�offset�from�the%*ˆaddress,�using�the�GET_ON_BD�macro.* ‰GET_ON_BD�D0*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>**<*‚Check�to�see�if�this�was�the�IN�or�OUT�processor.�If�it�is8*‚calculate�the�length�of�the�last�transfer�based�on�the=*‚contents�of�the�GPIBC�memory�address�register�(MAR)�and�theC*‚type�of�I/O�operation�performed,�else�no�length�calcs.�are�req'd.*?�MOVE.L�MENUCPOS(A5),A0‚get�address�of�menu�item�just�completed1�CMPI.B�#OUT,(A0)„was�the�OUT�processor�executed?�BEQ.S�INTR150…br�=�yes*/�CMPI.B�#IN,(A0)„was�the�IN�processor�executed?1�BNE.S�INTR200„br�=�TERM�or�SEOI�process�finished*I* Check for the one command that uses the secondary buffer instead of the* primary buffer for data xfer.*GINTR130�CMPI.W�#IOOWIN,IOSFCT(A3)ƒis�this�an�outout�with�input�command?�BNE.S�INTR150ƒbr�=�noG�SUB.L�D6,D0‚D0�=�current�M.A.R.�minus�(secondary)�buffer�start�address BRA.S INTR160*LINTR150 SUB.L D7,D0 D0 = current M.A.R. minus (primary) buffer start address*;INTR160 MOVE.L D0,IOSLEN(A3) store I/O xfer length in IOSPB*C*ƒCheck�to�see�if�there�is�a�special�post�formatters�to�be�executed*C�MOVE.L�IOSFMTA+DCBDEV(A4),D1‚get�pointer�to�user�defined�formatter1 BEQ.S INTR200 br = no user defined I/O formatter*B*‚Check�to�see�whether�input�or�output�menu�processor�was�executedA*‚and�then�see�if�there�is�a�user�defined�post�processor�for�this *‚device.*@�MOVE.W�#PST_OFMT,D0ƒD0�<==�preload�post�output�formatter�offset5�CMPI.B�#OUT,(A0)…are�we�doing�"OUT"�menu�processing?�BEQ.S�INTR180„branch�if�yes7�MOVE.W�#PST_IFMT,D0ƒD0�<==�post�input�formatter�offset*:INTR180�MOVE.L�D1,A0†A0�<==�base�address�of�all�formatters8�TST.L�0(A0,D0.W)ƒdid�user�define�a�post�data�formatter?�BEQ.S�INTR200ƒbranch�=�no*+�MOVEM.L�D1-D7/A0-A6,-(A7)‚save�environment.�JSR�0(A0,D0.W)‚execute�user�defined�formatter MOVEM.L (A7)+,D1-D7/A0-A6,�TST.B�D0ƒcheck�error�code�from�user�routine!�BEQ.S�INTR200‚branch�if�no�error*B*‚An�error�has�been�detected�in�the�user's�input�formatter�routine*-�MOVEQ‚#ISTAINFE,D1‚set�input�formatter�error�BSR�PROCMERR‚process�error+ BRA.S INTR250 exit DMA interrupt processor*INTR200:'�BSR�PROCMENU„process�next�menu�item(s)*INTR250:6 MOVE.W (A7)+,D5 retrieve previous TMS9914 status regs(�TST.W�D5ˆwas�there�a�pending�interrupt? BEQ INTREXIT br = no �BRA.S�INTR510‚else�go�handle�it  ; TTL GPIB DRIVER - INTERRUPT PROCESSING (TMS9914 INTERRUPT) PAGEE***********************************************************************ƒTMS9914A�INTERRUPT�SECTION*<*„Entering�this�section�of�the�interrupt�processor�indicates8*„that�one�or�more�interrupt�conditions�enabled�has�been;*„received.�Reading�the�interrupt�mask�regsiters�(INTR0�and9*„INTR1)�of�the�TMS9914A�will�indicate�which�condition(s) *„occurred.*;*„The�GPIB�can�be�in�one�and�only�one�of�the�four�following<*„states:�(1)�controller�mode,�(2)�talker�mode,�(3)�listener%*„mode,�or�(4)�idle�mode.‚These�modes@*„are�stored�in�'BUSACTIV'�and�may�change�depending�on�what�type=*„of�interrupt�occurred.‚Also,�different�actions�may�be�taken?*„depending�on�the�current�state�of�the�BUS.‚All�interrupt�bits8*„will�be�checked�each�time�a�TMS9914A�interrupt�occurs.* INTR500:5�MOVEP.W�INTR0(A1),D5ƒread�interrupt�status�registers6�AND.W‚TMSMASK(A5),D5ƒD5�=�valid�interrupt�status�bitsINTR510:B BSET.B #VBIMENAB,CONTREG0(A1) reset interrupt enable for TMS9914A***0***†My�Address�Change�(MAC)�check�and�processing***$�BTST�#MACBIT,D5†is�the�MAC�bit�set?�BEQ.S�INTR600ƒbr�=�no*I AND.W #$FFFF-(1< BTSTW #SRQPROG,BUSACTIV(A5) USER I/O or SRQ polling sequence?(�BNE.S�INTR605�br�=�SRQ�polling�sequenceJ MOVE.B SRQBYTE(A5),IOSSAD-1(A3) else move serial poll byte to user's IOPB-INTR605�BSR�PROCMENU‰continue�processing�menu BRA INTR700*+*ˆCheck�if�we�have�any�Task�I/O�ready�to�go*8INTR610�MOVE.L�#READPEND,D3‚set�up�for�I/O�pending�check0�BSR�CHECKIOP�go�look�for�task�level�I/O�pending***0***„Byte�Out�(BO)�interrupt�check�and�processing***)INTR700�BTST�#BOBIT,D5„is�the�BO�bit�set? BEQ.S INTR800*9�BTSTW�#CAC_S,BUSACTIV(A5)ƒis�the�BUS�in�controller�mode?�BEQ.S�INTR750�br�=�no*5*‚A�command�string�might�be�in�progress.‚Send�out�the"*‚next�command�byte�with�ATN�true.*/�TST.L�CMDCOUNT(A5)‰false�or�last�BO�interrupt?(�BEQ.S�INTR800Žbranch�if�yes�(ignore�it)*5�SUB.L�#1,CMDCOUNT(A5)†decrement�command�string�count5�BEQ.S�INTR730Žbranch�if�finished�with�command�string4�MOVE.L�CMDBFPTR(A5),A0…get�ptr�to�next�command�byte&�MOVE.B�(A0)+,D1Œget�next�command�byte5�MOVE.L�A0,CMDBFPTR(A5)…update�command�buffer�pointer%�BSR�COMCMD‘output�command�on�the�BUS�BRA.S�INTR800Žcontinue*@*ƒCommand�processing�is�complete�for�now.�Continue�with�the�next=*ƒmenu�item�after�the�command�out�menu�item�processor�for�the*ƒcurrent�command.*1INTR730�BSR�PROCMENUˆcontinue�with�next�menu�item�BRA.S�INTR800Žcontinue*!* We are not the active cntroller*8INTR750�MOVE.L�#WRITPEND,D3‚set�up�for�pending�I/O�check.�BSR�CHECKIOP�check�for�pending�task�level�I/O***8***†Service�Request�(SRQ)�interrupt�check�and�processing***BINTR800�BTST�#SRQBIT,D5ƒis�a�device�on�our�BUS�requesting�service?�BEQ.S�INTR900„br�=�no*: BSETW #SRQWAIT,BUSACTIV(A5) indicate SRQ intrp processing3�MOVE.L�QHEAD(A5),D1‡yes,�get�current�queue�pointer'�CMP.L�QTAIL(A5),D1ˆis�the�queue�empty?(�BNE.S�INTR900Žbranch�if�no,�bus�is�busy*A*‚Since�the�GPIB�is�idle,�initiate�the�service�request�processing2*‚to�determine�which�device�is�requesting�service.*9*ˆFirst�build�a�dummy�queue�entry�for�standard�processing** MOVEM.L A3-A4/D4-D7,-(A7) save intrp regs SUB.L A3,A3 dummy IOSPB address LEA.L CONFINFO(A5),A4L MOVE.L DVDCBPTR(A4),A4 A4 <= to BUS DCB (serial polling is a BUS operation)* LEA.L SRQBYTE(A5),A0 input buffer pointer,�MOVEQ�#1,D4‚Status�byte�response�length�=�1/ MOVE.L A3,D5 dummy length for secondary buffer2 MOVE.L A0,D6 dummy primary buffer address pointer4 MOVE.L A3,D7 dummy secondary buffer address pointer' BSR PSHGPIBQ go put entry on the queue- MOVEM.L (A7)+,A3-A4/D4-D7 restore intrp regs1 BEQ.S INTR900 br = queue full, process SRQ later&�BSR�PROCMSRQ‚start�up�the�SRQ�process***<***ƒRemote/Local�Change�(RLC)�interrupt�check�and�processing***6INTR900�BTST�#RLCBIT,D5ƒremote/local�change�interrupt?�BEQ.S�INTR1000ƒbranch�if�no*@�MOVE.B�ADDRSTAT(A1),D1‡D1�<==‚current�address�state�of�TMS9914A6�AND.W�#1<*‚bit�mask�and�check�to�see�if�we�even�need�to�respond�to�this*‚secondary�address.*8�LEA.L�CONFINFO(A5),A0„A0�<==�ptr�to�configuration�areas?�MOVE.L�CNFIGPTR(A0),A0ƒA0�<==�ptr�to�configuration�area�of�BUS*=*‚Read�the�command�pass�thru�register�to�obtain�the�secondary*‚address�that�is�required.*D�MOVE.B�CMDPTHRU(A1),D2†D2�=�secondary�addr�controller�is�requesting$�AND.L�#SECMASK,D2‹mask�address�bitsA�MOVE.L�IOSSAMW(A0),D1‡D1�<==�mask�of�valid�secondary�write�addrsD�BTST�#TADS_B,ADDRSTAT(A1)ƒAre�we�in�primary�talker�addressed�state?�BEQ.S�INTR1140ŽBranch�if�no*@�MOVE.L�IOSSAMR(A0),D1‡D1�<==�mask�of�valid�secondary�read�addrs*.INTR1140�BTST.L�D2,D1ˆvalid�secondary�address?�BNE.S�INTR1150�branch�if�yes*(*‚This�is�not�a�valid�secondary�address.*?�MOVE.B�#DACR0,AUXCMD(A1)‚release�hdshk�&�don't�enter�LADS/TADS�BRA.S�INTR1200ƒcontinue*AINTR1150 MOVE.B #DACR1,AUXCMD(A1) release hdshk & enter TADS/LADS4�OR.B�#1<�BRA.S�CKIO040�go�send�event�to�user�about�type�of�pending�I/O*&*ˆTask�I/O�is�pending,�check�for�match.*’on�operation�type�&�G secondary�addr.�if�req'd*8CKIO010 BTST.B D3,IOPEND(A5) Is it a a matching request?.�BEQ.S�CKIO030�Br�=�no,�abort�Task�I/O�request*C BTST.B #SECONDAR,IOPEND(A5) Is there a secondary address involved?)�BEQ.S�CKIO050�Br�=�no,�go�start�the�menu5�MOVE.L�QTAIL(A5),A0‰get�pointer�to�current�operation2�MOVE.L�IPBQOFST(A0),A0†AO�<==�I/O�parameter�block9�CMP.W�#IORSEC,IOSFCT(A0)„Is�it�a�secondary�read�command?�BEQ.S�CKIO015�br�=�yes:�CMP.W�#IOWSEC,IOSFCT(A0)„Is�it�s�secondary�write�command?.�BNE.S�CKIO030�br�=�no,�abort�pending�task�I/O*CKIO015 MOVEQ #SECMASK,D1@�AND.B�IOPEND(A5),D1‰D1�=�active�controller�requested�sec.�addr.H�CMP.B�IOSSAD-1(A0),D1‡is�it�the�same�as�rhe�Task's�requested�sec�addr.?'�BEQ.S�CKIO050�br�=�yes,�start�the�menu*.CKIO030�BSR�HLTCMD‹kill�the�task�requested�I/O CKIO050�BSETW�#BUSIOP,BUSACTIV(A5)ƒset�INTRP�level�I/O�pending&�BSR�PROCMENU‘Initiate�I/O�on�the�menu* CKIO060 RTS PAGEH**************************************************************************—CANCEL�PENDING�I/O*;*ˆAn�event�has�occurred�on�the�BUS�that�forces�us�to�cancel9*ˆany�pending�I/O�regardless�of�source.‚The�cause�of�this&*ˆevent�will�also�be�sent�to�the�user.**/*ˆENTER:„A1�<==‚base�address�of�GPIBC�registers*’A3�<==‚address�of�IOSPB*’A4�<==‚address�of�DCB*’A5�<==‚address�of�CCB*.*’D5.W�<==�current�9914�intrp�reg�(INTR�LEVEL)**’D3.B�<==�I/O�operation�type�(READ/WRITE)* CANCLIOP:#�BSR�HLTALL’Halt�all�I/O�on�the�BUS, MOVE.B #0,IOPEND(A5) cancel any pending I/OH�AND.W‚#$FFFF-(1<PROCMENA�MOVE.L�QTAIL(A5),A6‰A6�<==�ptr�to�current�queue�entry1�BTSTW�#HALTED,CSTQOFST(A6)‚was�this�menu�Halted?�BNE�PROCM020�br�=�yesK MOVE.L MENUNPOS(A5),MENUCPOS(A5) update: next item is now the current item6�MOVE.L�MENUNPOS(A5),A0ƒget�next�menu�position�pointer#�MOVE.B�(A0)+,D0ƒget�next�menu�item5�MOVE.L�A0,MENUNPOS(A5)ƒupdate�next�menu�item�pointer* *ƒcheck�to�see�if�at�end�of�menu*�CMP.B�#END,D0Œend�of�menu?�BEQ.S�PROCM020‹yes* * Initiate I/O on next menu item*;�LEA.L�MENUCTBL(PC),A0ƒA0�<--�menu�function�code�jump�table(�CMP.B�#MENUCLEN,D0‚valid�function�code?�BGT�PROCMERB‚branch�if�no*/�AND.W�#$FF,D0ƒmask�the�offset�of�routine�index"�ASL.W�#1,D0…make�table�compatibleA�MOVE.W�0(A0,D0.W),D0‚relative�distance�between�table�and�routineA�MOVEM.L�D0/D2-D7/A0-A6,-(A7)‚save�everything�except�D1�for�error,�MOVE.L�CCBCHB(A5),A1‚get�base�addr�of�GPIBC)�JSR�0(A0,D0.W)‚initiate�I/O�on�menu�item3�MOVEM.L�(A7)+,D0/D2-D7/A0-A6‚restore�all�registers �TST.B�D1‚set�conditional�return2�BNE‚PROCMERA‚go�to�processor�menu�error�processor*C*…These�previous�menu�item�was�successfully�initiated/completed.�If;*…the�menu�item�was�a�Class�II�or�Class�III�type�(auxiliary5*…command�or�special�function�type)�no�interrupt�will9*…be�generated�so�check�that�here�to�keep�things�rolling.H *5�MOVE.L�MENUCPOS(A5),A0ƒget�current�menu�item�pointer/�CMPI.B�#AUXTYPE,(A0)‚was�it�an�auxiliary�type?,�BGE.S�PROCMENA‚yes,�continue�with�next�item*:*‚The�following�is�a�special�case�check�for�the�menu�items9*„DATAXFR�TERM/SEOI.�If�either�processor�was�performed�in7*„the�image�mode�or�performed�in�formatted�mode�with�no>*„EOR�characters�enabled,�then�no�interrupt�will�be�generated.*;�BCLRW�#TERMINT,CSTQOFST(A6)ˆare�we�expecting�an�interrupt?-�BNE.S�PROCMENA•br�=�no,�go�to�next�menu�item*6PROCMRTN�MOVEM.L�(A7)+,D2-D7/A1-A6‚restore�environment RTS  PAGE*>*‚It�has�been�determined�that�we�are�at�the�end�of�the�currentB*‚operation�menu�item�table�or�this�I/O�operation�has�been�HALTED.*8PROCM020�BTSTW�#SRQPROG,BUSACTIV(A5)‚is�SRQ�in�progress?�BNE�PROCM200•yes7�MOVEQ‚#ISTAOK,D1�set�operation�completion�status�to�ok PROCM050 MOVEQ #0,D0+�MOVE.B�DCBCDV(A4),D0‚get�the�device�number1�MOVE.W�D1,-(A7)ˆsave�operation�completion�status9�MOVE.W�DEVQBSY(A5),D1‚D1�<==�current�device�busy�bit�map(�BCLR�D0,D1�clear�that�device's�busy�bit%�MOVE.W�D1,DEVQBSY(A5)‚update�bit�map�MOVE.W�(A7)+,D1ˆrestore�status: BTSTW #HALTED,CSTQOFST(A6) was this operation terminated?�BNE.S�PROCM055Žbr�=�yesH BTSTW #SRQFAIL,CSTQOFST(A6) if an SRQ poll, did the device not respond?�BEQ.S�PROCM060‰br�=�O.K.*5PROCM055�MOVEQ�#ISTATO,D1„else�set�timeout�error�code*2PROCM060 MOVE.B D1,IOSSTA(A3) save status in IOSPB2�MOVE.B�#XPSNRM,D4ƒD4�<==�set�event�type�to�normal�BSR�QEVENT‚send�event�to�IOS/�BTSTW�#SRQWAIT,BUSACTIV(A5)†is�an�SRQ�waiting?�BEQ.S�PROCM100”no*7*‚Overlay�the�current�completed�queue�entry�(operation)1*‚with�dummy�SRQ�processing�information�pointers.* LEA.L CONFINFO(A5),A1J MOVE.L DVDCBPTR(A1),DCBQOFST(A6) set to DCB of the BUS for SRQ processing'�CLR.W�CSTQOFST(A6)ŠInit�command�status-�CLR.L�IPBQOFST(A6)Šclear�dummy�IOSPB�pointer LEA.L SRQBYTE(A5),A16�MOVE.L�A1,PBPAOFST(A6)†set�dummy�input�buffer�address5�MOVE.B�#1,PBLNOFST(A6)†set�dummy�input�buffer�length(�CLR.L�SBPAOFST(A6)Šno�secondary�buffer!'�CLR.W�SBLNOFST(A6)Šand�its�length�is�0 BRA.S PROCSRQA  PAGE*3*ˆENTRY�POINT�FOR�SRQ�PROCESSING�AT�INTERRUPT�LEVEL*?*‚There�is�an�SRQ�request�waiting�to�be�handled�so�initiate�the@*‚status�menu�for�the�first�device�number�connected�to�this�CCB.=*‚Also,�send�an�I/O�complete�event�back�for�previous�function%*‚since�we�got�other�things�to�do�now* PROCMSRQ:+�MOVEM.L�D2-D7/A1-A6,-(A7)…save�environment*>PROCSRQA�MOVE.L�QTAIL(A5),A6ŠA6�<==�ptr�to�current�queue�entry2�BCLRW�#SRQWAIT,BUSACTIV(A5)„take�out�of�wait�mode8�BSETW�#SRQPROG,BUSACTIV(A5)„put�in�SRQ�in�progress�mode3�LEA.L�COND_SP(PC),A0‹A0�<==�serial�poll�menu�table+�MOVE.L�A0,MENU(A5)�set�top�of�menu�pointer=�MOVE.B�CSPDEVNM(A5),D0‰get�device�number�of�last�serial�poll<�MOVE.B�D0,FSPDEVNM(A5)‰set�first�serial�poll�device�#�indexD*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+*�USED�TO�BE�BRA.S�PROCM240ŒS.J.F.�10/10/84D*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>(�BRA.S�PROCM227‘initiate�I/O�on�SRQ�menu* PAGE$PROCM100�BSR�POPGPIBQƒpop�GPIB�queue;�BEQ�PROCMRTN‚branch�if�queue�is�empty�(nothing�else�to�do)*:*‚Set�up�the�necessary�pointers�from�the�queue�information-*‚and�then�build�the�menu�for�the�new�command**�MOVE.L�QTAIL(A5),A6‚get�new�queue�pointer3*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn#*ˆSet�up�registers�before�branching?�MOVE.L�IPBQOFST(A6),A3‚A3�<==�address�of�IOSPB�for�new�command=�MOVE.L�DCBQOFST(A6),A4‚A4�<==�address�of�DCB�for�new�command*6*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>E�BTSTW�#HALTED,CSTQOFST(A6)‚was�this�command�entry�previously�halted?�BNE�PROCM020ƒbranch�if�yes2*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn**ƒThese�moves�done�above�now.*?*MOVE.L�IPBQOFST(A6),A3‚A3�<==�address�of�IOSPB�for�new�command=*MOVE.L�DCH BQOFST(A6),A4‚A4�<==�address�of�DCB�for�new�command*8*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*(�BSR�GETCMDP…get�pointer�to�next�command+�BNE�PROCM020„BR�=�invalid�command,�discard4�BSR�VALOPER…validate�operational�mode�and�abilities)�BNE�PROCM020„Error,�invalid�cmd,�discard(�BSR�BUILDMEN„build�menu�for�new�command�BNE�PROCM020„Branch�if�error&�BRA�PROCMENA„initiate�I/O�on�new�menu**‚SRQ�Processing�and�Detection*7PROCM200 BTSTW #HALTED,CSTQOFST(A6) SRQ polling halted?&�BNE.S�PROCM300„br�=�yes,�term�polling+�MOVE.B�SRQBYTE(A5),D1ƒread�the�status�byte*.�BTST�#6,D1ƒis�this�device�requesting�service? BNE.S PROCM400 branch if yes*A*‚Get�next�index�device�number�of�the�next�device�to�serial�poll.?*‚The�technique�used�allows�wraparound�so�that�no�device�on�the:*‚BUS�will�have�a�greater�priority�of�being�serial�polled.*1PROCM220�MOVE.B�CSPDEVNM(A5),D0‚get�current�index2�ADD.B�#1,D0ƒbump�by�one�to�get�next�device�number+�CMPI.B�#MAXDEVNM+1,D0ƒend�of�device�chain?�BNE.S�PROCM225‚not�yet �MOVEQ�#1,D0‚reset�to�device�#�1*I*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *‡10/9/84…SJF*A*‡We�will�insert�code�in�here�to�implement�the�concept�of�looping?*‡twice�through�all�devices�on�a�bus�to�locate�the�source�of�an=*‡SRQ.‚This�was�necessary�due�to�devices�pulsing�the�SRQ�line1*‡and�then�missing�true�SRQ's�from�other�devices.*J*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>EPROCM225�MOVE.B‚FSPDEVNM(A5),D2…D2�<--�device�#�we�started�SRQ's�with(�AND.Bƒ#$0F,D2�Mask�out�the�loop�counter5�CMP.BƒD0,D2�Have�we�reached�the�starting�SRQ�device?�BNE.SƒPROCM227ŒNot�yet7�BSET.B‚#7,FSPDEVNM(A5)…Set�the�potemtial�lap�indicator.�BNE.SƒPROCM300ŒBranch�if�we�have�lapped�twice*?PROCM227�MOVE.L�CCBCHB(A5),A1‚A1�<--�base�GPIB�address�of�board.�BTST.B‚#BUSSRQ,BUSSTAT(A1)ƒis�SRQ�still�true?1�BEQ.SƒPROCM300Žbranch�if�not,�exit�SRQ�processes =*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *�10/9/84…sjf*+*ˆThis�code�was�replaced�by�the�above�logic*L*PROCM225�CMP.B�FSPDEVNM(A5),D0‚have�we�done�a�complete�turn�around�the�BUS?**�BEQ.S�PROCM300ƒyes,�we�may�have�problems*@*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *-*‚Check�to�see�if�this�device�number�is�valid**PROCM240�ANDI.L�#$FF,D0ƒget�rid�of�garbage4�MOVE.B�D0,CSPDEVNM(A5)ƒupdate�current�device�number/�ASL.L�#3,D0ƒcalc�offset�into�config�info�table5�LEA.L�CONFINFO(A5),A0ƒbase�addr�of�config�info�table6�MOVE.L�DVDCBPTR(A0,D0.L),A4ƒget�pointer�to�device�DCBJ�MOVE.L�CNFIGPTR(A0,D0.L),A0ƒget�ptr�to�current�device�configuration�block MOVE.L A0,D0 set cond codes:�BEQ.S�PROCM220ƒbranch�if�device�not�present�or�configuredF MOVE.L A4,DCBQOFST(A6) save new DCB pointer at current queue locationC�BTSTW�#IOASPOC,IOSATW(A0)‚does�device�have�serial�poll�capability?�BEQ.S�PROCM220ƒbranch�if�no*>�MOVE.L�MENU(A5),MENUNPOS(A5)‚reset�status�menu�pointer�to�top�BRA�PROCMENAƒinitiate�I/O*>PROCM300 BCLRW #SRQPROG,BUSACTIV(A5) clear SRQ in progress bit(�BRA�PROCM100„continue�normal�processing*.*ƒFound�a�device�on�the�bus�requesting�service*5PROCM400�MOVEQ‚#SRQTYPE,D0‚set�event�type�to�SRQ�type�BSR�SENDUEVS‚send�event>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>* *’10/9/84„sjf*5*ˆThis�logic�is�now�performed�above�after�each�device *ˆis�queried.*-*�MOVE.L�CCBCHB(A5),A1‚get�base�addr�of�GPIBC/*�BTST.B�#BUSSRQ,BUSSTAT(A1)ƒis�SRQ�still�TRUE?7*�BEQ.S�PROCM300‚no,�clean�up�and�continue�normal�oper.*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *5*ˆReset�the�lap�indicator�and�the�first�device�polled5*ˆfor�this�next�SRQ�series.�Each�time�an�SRQ�is�found4*ˆwe�must�lap�at�least�twice�to�catch�devices�missed*ˆby�toggling�SRQ's.***<�MOVE.B�CSPDEVNM(A5),D0‚last�device�#�that�was�serial�polled �ADD.B�#1,D0‚start�with�next�oneI 2 CMPI.B #MAXDEVNM+1,D0 should we wraparound first? BNE.S PROCM520 branch if no> MOVEQ #1,D0 set to first device index of configuration blocks*DPROCM520 MOVE.B D0,FSPDEVNM(A5) set start of serial poll index chainA�BRA.S�PROCM227‚start�over�again…***�10/9/84�sjf‚WAS�PROCM240�*****5*‚Process�Menu�entry�point�when�an�error�has�occurred#*‚with�the�reason�fro�error�in�D1.B* PROCMERR:+�MOVEM.L�D2-D7/A1-A6,-(A7)…save�environment*>PROCMERA�MOVE.L�QTAIL(A5),A6ƒA6�<==�ptr�to�current�queue�entry1 BCLRW #SRQPROG,BUSACTIV(A5) was SRQ in progress?4�BEQ�PROCM050ƒbr�=�NO,�terminate�USER�I/O�processing-�BRA�PROCM100ƒelse�pop�SRQ�menu�and�terminate*:PROCMERB�MOVEQ�#ISTADRVE,D1‚set�driver�run-time�error�code% BRA.S PROCMERA go to error processor 8 TTL GPIB DRIVER - INTERRUPT PROCESSOR (MENU PROCESSORS) PAGEE***********************************************************************’MENU�ITEM�COMMAND�PROCESSES*>*ˆThe�following�routines�are�the�individual�menu�item�routinesA*…that�when�combined�make�up�a�menu�for�each�GPIB�function.�TheseE*…menu�items�are�dispatched�by�the�menu�processor�at�either�interrupt;*…level�or�command�level.�All�registers�have�been�preserved?*…before�entering�except�for�D0�and�A0�which�may�always�be�used@*…as�work�registers.�The�following�register�description�entry�is$*…true�for�all�menu�item�processors:*-*’ENTER:‚A1�=�Base�Address�of�GPIBC�registers%*šA3�=�Address�of�IOS�Parameter�Block,*šA4�=�Address�of�Device�Control�Block�(DCB)-*šA5�=�Address�of�Channel�Control�Block�(CCB)1*šA6�=�Address�of�User's�Task�Control�Block�(TCB)* *’EXIT:ƒIf�D1�=�0…THENƒNo�errors*œELSE�D1�=�error�code9*�Note:�The�INITIO�processor�has�saved�all�registers�upon)*”entry�so�all�registers�are�free�to�use.*G*********************************************************************** ! TTL CLASS I MENU ITEM PROCESSORS PAGEF************************************************************************ˆCLASS�I�MENU�ITEM�PROCESSORS*1*’This�class�of�menu�items�initiate�various�types>*ˆof�I/O�in�both�DMA�and�non-DMA�modes.�All�class�I�menu�items-*ˆwill�generate�an�interrupt�after�execution.*F********************************************************************** **ˆPROCESSOR:�Write�Data*:*ˆPURPOSE:�To�setup�the�write�request�according�to�the�IOS0*‘options,�set�up�the�DMA�registers,�and�then�to*‘initiate�the�I/O.* WRITDATA:9 MOVEQ #1<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>& MOVE.B D2,UNICMD(A1) initiate the I/O*3WRITD025�MOVEQ‚#ISTAOK,D1�set�return�status�to�O.K.*WRITDRTN�RTS…exit�write�data*<*ˆSpecial�processing�for�DMA�transfer�of�only�1�byte�(either&*ˆdata�or�termination�char.�sequence).*HWRITD030 BSETW #TERMINT,CSTQOFST(A6) let PROCMENU know no intrp expected‰BRA.S�WRITD025Žtake�good�exit**‚Write�Formatted�Mode;*ˆSince�DMA�write�requests�are�transfered�directly�from�the;*ˆusers�buffer,�and�Write�Formatted�EOR�characteristics�(if8*ˆenabled)�will�be�sent�out�by�the�termination�processor'*ˆupon�completion�of�this�DMA�transfer.*>WRITDFMT�MOVE.B�WEORFMT(A2),D1‚get�EOR�req�for�Write�Formatted2�BTST.L�#FIXTERM,D1‚fixed�length�transfer�enabled?�BEQ.S�WRITD060„branch�if�noF MOVE.W IOSFBWF(A2),D0 yes change transfer length to fixed requirement*G*ƒIf�any�of�the�CR,�LF,�or�EOS�characters�are�enabled,�EOI�(if�enabled);*ƒmust�be�held�off�for�this�transfer�and�transmitted�by�the*ƒtermination�processor.*WRITD060 MOVE.B D1,D37 AND.B #1<*„terminate�on�the�highest�priority�terminator�with�EOS�having:*„the�highest�priority�followed�by�LF�and�CR�respectively.*0READ115�MOVEQ�#0,D2Šclear�DMA�operation�register#�BTST.L�#EOSTERM,D1Šis�EOS�enabled?�BEQ.S�READD060�branch�if�no; MOVE.B IOSEOSR(A2),EOSCOMP(A1) yes, set EOS read character+�BRA.S�READD080�and�bypass�CR/LF�EOS�checks)READD060�BTST.L�#LFTERM,D1‚is�LF�enabled?�BEQ.S�READD070�branch�if�no1�MOVE.B�#LF,EOSCOMP(A1)…yes,�set�LF�as�terminator'�BRA.S�READD080�and�bypass�CR�EOS�check)READD070�BTST.L�#CRTERM,D1ƒis�CR�enabled?6*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*=*ˆFix�so�that�read�will�terminate�on�fixed�length�data�input. *ˆInserted�READD090�label�below.**BEQ.S�READD020�branch�if�no BEQ.S READD090*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>1�MOVE.B�#CR,EOSCOMP(A1)…yes,�set�CR�as�terminator@READD080�BSET.L�#EOSBIT,D2‚enable�EOS�detection�for�DMA�transfer2READD090�BTST.L�#FIXTERM,D1‰fixed�length�transfer?�BEQ.S�READD020�branch�if�no1�TST.W�D3“did�user�really�specify�a�fixed�length?3�BEQ.S�READD020�br�=�no,�use�IOSPB�specified�length;�CMP.W�D0,D3‘compare�user's�real�buffer�length�to�DEVICE'S!8�BGE.S�READD011Žbr�=�user's�buffer�size�.GE.�to�device's4�MOVEQ‚#ISTAADD,D1Šbr�=�his�buffer�is�not�big�enough�BRA.S�READDRTNŽabort*BREADD011�MOVE.W�D3,D0ˆset�up�DMA�for�device's�fixed�length�record!4READD020:�BSR�SETUPDMA†set�up�DMA�byte�count�and�MAR+�MOVE.B�#LON1,AUXCMD(A1)…set�up�Listen�mode.�BSET.L�#DMAWRITE,D2ˆenable�DMA�write�commmand6�BCLRW�#BIBIT,TMSMASK(A5)ƒdisable�BI�interrupts�on�DMA7�MOVE.W�TMSMASK(A5),D1†reset�interrupt�mask�on�TMS9914A MOVEP.W D1,INTR0(A1)*�MOVE.B�#GTS,AUXCMD(A1)…lower�the�ATN�lineB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<* *ˆ4/24/84ƒbwn*9*ˆMust�inhibit�TMS9914A‚interrupts‚during�DMA�operations.*2�BCLR.B�#VBIMENAB,CONTREG0(A1)‚disable�9914�intrps*?*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&�MOVE.B�D2,UNICMD(A1)‡initiate�the�I/O+�MOVEQ‚#ISTAOK,D1Šset�return�status�to�O.K.READDRTN�RTS�exit�read�data PAGE(*ˆPROCESSOR:�Send�Termination�Characters*6*ˆPURPOSE:�This�processor�will�send�the�EOR�characters,*‘in�DMA�mode�to�complete�the�previous�write*‘formatted�transfer.* SENDTERM:%�MOVE.W�IOSOPT(A3),D1‚get�IOS�options.�AND.W�#IOPIMG,D1‚data�transfer�in�image�mode?>�BNE.S�SENDTRM9ƒbranch�if�yes�(no�EOS�characters�in�this�mode)*3�BSR�GETCNFIGƒget�ptr�to�current�configuration�dataB MOVE.B WEORFMT(A0),D1 get EOR characteristics for Write Formatted$ MOVE.B IOSEOSW(A0),D2 get EOS char.7�LEA.L�TERMBUF(A5),A0‚A0�<==�termination�buffer�pointer*?*ƒOnce�again,�just�as�in�the�read�processor,�the�EOR�characters8*ƒmay�be�multiply�set�and�are�software�priority�encoded.>*ƒIf�enabled,�the�CR�character�will�be�sent�out�first�followed1*ƒby�the�LF�character�and�then�the�EOS�character.** MOVEQ #0,D0 reset EOS string byte counter+�BTST.L�#CRTERM,D1ƒis�CR�character�enabled?�BJ EQ.S�SENDTRM2„branch�if�no0�MOVE.B�#CR,(A0)+‚store�CR�in�termination�buffer�ADDQ.L�#1,D0ˆbump�byte�count*3SENDTRM2�BTST.L�#LFTERM,D1ƒis�LF�character�enabled?�BEQ.S�SENDTRM4„branch�if�no?�MOVE.B�#LF,(A0)+‚yes,�store�LF�character�in�termination�buffer�ADDQ.L�#1,D0ˆbump�byte�count*;SENDTRM4�BTST.L�#EOSTERM,D1‚is�write�EOS�character�enabled?�BEQ.S�SENDTRM8„branch�if�no:�MOVE.B�D2,(A0)+ƒstore�EOS�character�in�termination�buffer�ADDQ.L�#1,D0ˆbump�count*1SENDTRM5 MOVEQ #0,D2 initialize DMA transfer type �SUB.L�D0,A0‡set�start�of�buffer*0*ˆSet�up�for�data�xfer:‰A0�<--�terminator�string*¦D0�=ƒstring�length*¦D1�=ƒEOR�options*¦D2�=ƒDMA�command*,�BRA�WRITD010†do�the�terminator�string�write*(SENDTRM8�TST.L�D0‚any�EOS�char.�to�send? BNE.S SENDTRM5*?SENDTRM9 BSETW #TERMINT,CSTQOFST(A6) set no interrupt expected!+�MOVEQ‚#ISTAOK,D1�set�return�status�to�O.K.)�RTS„exit�termination�character�processor  PAGE***ˆPROCESSOR:�Send�EOI*<*ˆPURPOSE:ƒSends�the�last�character�of�a�data�(OUT)�transfer3*“with�the�EOI�line�True�(uses�TMS9914�EOI�control)**SENDEOI:)�BSR�GETCNFIG�get�pointer�to�config.�data2�MOVE.B�WEORFMT(A0),D1‡get�Write�Formatted�options MOVE.W IOSOPT(A3),D0.�AND.W�#IOPIMG,D0Œwas�data�xfer�in�Image�mode?.�BEQ.S�SENDEOI2Žbr�=�NO,�use�Formatted�options*.�MOVE.B�WEORIMG(A0),D1‡get�Write�Image�options*ASENDEOI2�BTST�#EOITERM,D1„do�we�need�to�send�last�char.�with�EOI?�BEQ.S�SENDEOI4Žbr�=�no,�exit*-*ƒSend�the�last�data�byte�of�the�string�(DMA)*B�MOVE.B�#FEOI,AUXCMD(A1)…set�TMS9914�to�send�EOI�coincident�w/data;�MOVE.B�#$FE,BCNTLSB(A1)…set�up�BCR�to�1's�compl.�of�1�byteF�MOVE.B�#$FF,BCNTMSB(A1)…THE�MAR�IS�STILL�SET�FROM�PREVIOUS�XFER!!!!!!#�MOVEQ�#0,D2‘set�up�for�data�output(�BRA�WRITD022�go�do�the�output�operation*LSENDEOI4 BSETW #TERMINT,CSTQOFST(A6) set no intrp expected flag for PROCMENU>�BTSTW�#CAC_S,BUSACTIV(A5)ƒNo�more�output�is�to�take�place,�so?�BEQ.S�SENDEOI5Žif�we�are�a�Controller,�take�control�of�the�BUSH�MOVE.B�#TCA,AUXCMD(A1)†NOW!�cause�it�won't�be�done�at�normal�intrp�time*SENDEOI5 MOVEQ #ISTAOK,D1 RTS ‰PAGE*ˆPROCESSOR:�Untalk‚(UNT)*:*ˆPURPOSE:�To�send�the�universal�UNTALK�command�out�on�the*‘BUS�with�the�ATN�line�true.*SENDUNT:&�MOVE.B�#UNT_CMD,D1‚set�Untalk�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Unlisten‚(UNL)*<*ˆPURPOSE:�To�send�the�universal�UNLISTEN�command�out�on�the*‘BUS�with�the�ATN�line�true.*SENDUNL:(�MOVE.B�#UNL_CMD,D1‚set�Unlisten�command!�BRA�COMOUT…send�out�command�byte *'*ˆPROCESSOR:�Listen�Address�Group�(LAG)*;*ˆPURPOSE:�To�send�the�primary�listen�address�of�the�device1*‘specified�in�the�LUN�parameter�of�the�IOSPB�out#*‘on�the�BUS�with�the�ATN�line�true*SENDLAG:3�BSR�GETPADDR‚get�the�primary�address�of�the�device/�OR.B�#$20,D1ˆconvert�to�primary�listen�address!�BRA�COMOUT…send�out�command�byte *%*ˆPROCESSOR:�Other�Talk�Address�(OTA)*9*ˆPURPOSE:�To�send�the�primary�talk�address�of�the�device1*‘specified�in�the�LUN�parameter�of�the�IOSPB�out#*‘on�the�BUS�with�the�ATN�line�true*SENDOTA:K MOVE.B #TON0,AUXCMD(A1) UNTALK the GPIB, send aux command talk only (cs=0)3�BSR�GETPADDR‚get�the�primary�address�of�the�device-�OR.B�#$40,D1ƒconvert�to�primary�talk�address!�BRA�COMOUT…send�out�command�byte ***ˆPROCESSOR:�Other�Secondary�Address�(OSA)*9*ˆPURPOSE:�To�send�the�secondary�address�specified�in�the.*‘secondary�address�parameter�of�the�IOSPB�out$*‘on�the�BUS�with�the�ATN�line�true.*SENDOSA:5�MOVE.B�IOSSAD-1(A3),D1‚get�desired�secondary�address �AND.B�#$1F,D1ƒmask�address�bits8 OR.B #PPE_CMD,D1 set into secondary address group range!�BRA�COMOUT…send�out�command�byte *,*ˆPROCESSOR:�Parallel�Poll�Unconfigure�(PPU)*:*ˆPURPOSE:�To�send�the�universal�parallel�poll�unconfigure1*‘command�out�on�the�BUS�with�the�ATN�line�true.t*SENDPPU:I�LEA.L�CONFINFO(A5),A0‚A0�<==�starK t�of�configuration�area�for�all�devices*;*‚Reset�the�current�parallel�poll�configuration�of�the�BUS.*0�MOVE.L�CNFIGPTR(A0),A2‚A2�<==�cnfig�ptr�for�BUS6�BSET.B�#PPIS,IOSPOLC(A2)‚set�Parallel�Poll�Idle�State> MOVE.B #0,PARLPOLL(A1) clear the GPIBC parallel poll register#�MOVE.B�#PPU_CMD,D1‚set�PPU�command+�BRA�COMOUTƒsend�the�command�out�on�the�BUS *'*ˆPROCESSOR:�Parallel�Poll�Enable�(PPE)*:*ˆPURPOSE:�To�send�parallel�poll�configuration�information3*‘(PPP�and�S�bits�set�up�in�PPE�parameter�of�IOSPB)*‘out�on�the�BUS.*SENDPPE:1�MOVE.B�IOSSAD-1(A3),D1‚get�PP�configuration�info"�AND.B�#$0F,D1†mask�PPP�and�S�bits*8*‚Set�the�parallel�poll�configuration�register�to�active *ˆand�set�the�new�configuration.*9�BSR�GETCNFIGƒA0�<==�ptr�to�configuration�area�for�device8�MOVE.B�D1,IOSPOLC(A0)‚save�in�device�configuration�area*3�OR.B�#PPE_CMD,D1„encode�bits�to�make�a�PPE�command+�BRA�COMOUT…send�out�command�byte�to�device ***ˆPROCESSOR:�Parallel�Poll�Configure�(PPC)*8*ˆPURPOSE:�To�send�the�universal�parallel�poll�configure0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDPPC:*�MOVE.B�#PPC_CMD,D1‚set�up�the�PPC�command!�BRA�COMOUT…send�out�command�byte *(*ˆPROCESSOR:�Parallel�Poll�Disable�(PPD)*6*ˆPURPOSE:�To�send�the�universal�parallel�poll�disable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDPPD:*�MOVE.B�#PPD_CMD,D1‚set�up�the�PPD�command!�BRA�COMOUT…send�out�command�byte *%*ˆPROCESSOR:�Serial�Poll�Enable�(SPE)*3*ˆPURPOSE:�To�send�the�universal�serial�poll�enable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDSPE:*�MOVE.B�#SPE_CMD,D1‚set�up�the�SPE�command!�BRA�COMOUT…send�out�command�byte *&*ˆPROCESSOR:�Serial�Poll�Disable�(SPD)*4*ˆPURPOSE:�To�send�the�universal�serial�poll�disable0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDSPD:*�MOVE.B�#SPD_CMD,D1‚set�up�the�SPD�command!�BRA�COMOUT…send�out�command�byte *$*ˆPROCESSOR:�Clear�All�Devices�(DCL)*5*ˆPURPOSE:�To�send�the�universal�device�clear�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDDCL:*�MOVE.B�#DCL_CMD,D1‚set�up�the�DCL�command!�BRA�COMOUT…send�out�command�byte * *ˆPROCESSOR:�Local�Lockout�(LLO)*6*ˆPURPOSE:�To�send�the�universal�local�lockout�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDLLO:*�MOVE.B�#LLO_CMD,D1‚set�up�the�LLO�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Take�Control�(TCT)*5*ˆPURPOSE:�To�send�the�addressed�take�control�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDTCT:*�MOVE.B�#TCT_CMD,D1‚set�up�the�TCT�command!�BRA�COMOUT…send�out�command�byte *)*ˆPROCESSOR:�Selective�Device�Clear�(SDC)*7*ˆPURPOSE:�To�send�the�addressed�selective�device�clear/*‘command�out�on�the�BUS�with�the�ATN�line�true*‘to�all�current�listeners.*SENDSDC:*�MOVE.B�#SDC_CMD,D1‚set�up�the�SDC�command!�BRA�COMOUT…send�out�command�byte **ˆPROCESSOR:�Go�To�Local�(GTL)*4*ˆPURPOSE:�To�send�the�universal�go�to�local�command(*‘out�on�the�BUS�with�the�ATN�line�true.*SENDGTL:*�MOVE.B�#GTL_CMD,D1‚set�up�the�GTL�command!�BRA�COMOUT…send�out�command�byte *(*ˆPROCESSOR:�Group�Execute�Trigger�(GET)*6*ˆPURPOSE:�To�send�the�universal�group�execute�trigger0*‘command�out�on�the�BUS�with�the�ATN�line�true.*SENDGET:*�MOVE.B�#GET_CMD,D1‚set�up�the�GET�command!�BRA�COMOUT…send�out�command�byte *)*ˆPROCESSOR:�Read�Serial�Poll�status�byte*0*ˆPURPOSE:�This�processor�is�part�of�the�COND_SP)*‘(Conduct�Serial�Poll)�menu.�Its�purpose+*‘is�to�set�up�for�Byte-In�interrupt‚to�get!*‘the�status�byte�desired�device.*READSP:)�BSR�MTFIFO’clear�the�FIFO�(VME-300�bug!)3�MOVEM.L�D0-D7/A0-A6,-(A7)ƒsave�regs�on�Trap�0�call1�LEA�SP_TO(PC),A0Œset�PAT�for�serial�poll�timeout"�MOVE.L�#1000,A1�wait�for�1�second MOVEQ #0,D1E�MOVE.B�CCBISR(A5),D1ˆget�intrp�level�from�high�byte�of�CCB�S.R.�word�AND.B�#$0F,D1�mask�off�garbage)�MOVE.L�A5,D2�K set�CCB�address�as�PAT�I.D.�TR0$.RQPA�,‘start�timer�BRA.S�READSP1�br�=�timer�going*$ KILL.DRIVER M300INT_ID,T0RQPA,A5,A4 !READSP1 MOVEM.L (A7)+,D0-D7/A0-A6/ BSETW #SPTIMER,BUSACTIV(A5) mark timer running4�MOVE.B�#LON1,AUXCMD(A1)…set�up�to�read�SP�data�byte3�MOVE.B�#GTS,AUXCMD(A1)†Drop�ATN�to�let�him�send�it#�MOVEQ�#ISTAOK,D1Œset�return�status RTS  PAGE .*ˆSerial�Poll�Read�Status�Byte�Timeout�Routine*=*ˆIf�a�user�has�requested�the�serial�poll�function,�a�timeout=*ˆerror�status�will�be�returned.‚Else�if�the�timeout�occurred;*ˆas�a�result�of�the�driver�polling�a�device�in�response�to<*ˆan�SRQ�interrupt,�the�Serial�Poll�status�byte�(in�the�CCB)<*ˆwill�be�set�to�zero�and�the�current�device�will�be�skipped*ˆin�the�polling�sequence.*+SP_TO:ƒMOVEM.L�A3-A5,-(A7)‹save�immed.�regs‰MOVE.L�D1,A5’set�CCB�pointer‰MOVE.L�QTAIL(A5),A07‰CMPA.L�QHEAD(A5),A0‹is�there�an�operation�in�progress?/‰BEQ.S�SP_TO2’br�=�no,�must�have�been�cancelled9‰BCLRW�#SPTIMER,BUSACTIV(A5)ƒwas�timer�already�cancelled?‰BEQ.S�SP_TO2’br�=�yes,�ignore*1*ˆSet�up�registers�to�look�like�VME-300�interrupt*"‰MOVE.L�DCBQOFST(A0),A4ˆA4�<--�DCB#‰MOVE.L�IPBQOFST(A0),A3ˆA3�<--�IOPB+‰MOVE.L�CCBCHB(A5),A1ŠA1�=�hardware�address<‰MOVE.B�#TCS,AUXCMD(A1)ˆtake�control�of�BUS�now,�since�there)‰MOVE.B�DATAIO(A1),D1Šis�no�intrp�coming!)‰BTSTW�#SRQPROG,BUSACTIV(A5)ƒSRQ�polling?‰BNE.S�SP_TO1’br�=�no,�user�I/O;‰BSETW�#SRQFAIL,CSTQOFST(A0)ƒmark�SRQ�poll�response�failure*SP_TO1ƒCLR.B�SRQBYTE(A5)�reset�status�byte3‰BSR�PROCMENU’and�process�as�normal�status�response'SP_TO2ƒMOVEM.L�(A7)+,A3-A5‹restore�regs‰RTE*?*ˆRoutine�to�cancel‚the�currently�running�Serial�Poll�I/O�timer* KILLSPTO:5‰BCLRW�#SPTIMER,BUSACTIV(A5)ƒclear�timer�running�flag3‰MOVEM.L�D0-D7/A0-A6,-(A7)…save�regs�on�Trap�0�call.‰LEA�SP_TO(PC),A0Žset�up�parms�to�cancel�timer‰SUBA.L�A1,A1’interval‰MOVE.L�A5,D2’set�CCB�I.D.1‰MOVE.B�CCBISR(A5),D1Šget�intrp�level�for�request#‰AND.L�#$0F,D1‘clear�excess�garbage(‰OR.L�#$8000,D1�options�=�cancel�request‰TR0$.RQPA�,“go�cancel$‰BRA.S�KILLSP1‘br�=�request�accepted$‰KILL.DRIVER�M300INT_ID,T0RQPA,A5,A4*.KILLSP1‚MOVEM.L�(A7)+,D0-D7/A0-A6…restore�regs‰RTS  PAGE*1*ˆPROCESSOR:�Send�Auxiliary�Command�Buffer�String*4*ˆPURPOSE:�This�general�processor�will�simply�output-*‘what�ever�is�in�the�users�auxiliary�command+*‘string�buffer�out�on�the�BUS�with�the�ATN *‘line�true.* SENDAUXS:8�BSR�GETXFRAD‹get�physical�I/O�address�for�this�function,�MOVE.L�D6,A0‹A0�<==�starting�buffer�address1 MOVE.L D5,CMDCOUNT(A5) set command string length+�MOVE.B�(A0)+,D1Špreload�first�command�byte?�MOVE.L�A0,CMDBFPTR(A5)‚set�command�buffer�pointer�to�next�byte�BRA�COMCMD�send�command  " TTL CLASS I MENU ITEM SUBROUTINES PAGE**‚TLPROC*&*ˆTALKER/LISTENER�WRITE/READ�PROCESSOR*6*ˆThe�purpose�of�this�routine�is�to�determine�if�it�is9*ˆO.K.�to�initiate�the�current�Read/Write�command�at�this1*ˆtime.‚If�not,�the�current�operation�will�set�up%*ˆa�Task�level�I/O�operation�pending.*.*’ENTER:‚D0.B�=‚type�of�operation�-�Read/Write#*šA1�=�base�addr�of�GPIBC�registers'*šA3�=�address�of�IOCB�for�this�request*šA5�=�address�of�CCB*:*’EXIT:‚IF�CC�then�O.K.�to�initiate�I/O�(D0.b�=�don'�care)*™ELSE�(IF�CS�AND�D1�=�0)2*œTHEN‚task�waiting�for�controller�to�make�request$*™ELSE�(IF�CS�AND�D1.B�=�error�code)*œTHEN�command�is�aborted* *’Register�Usageƒ0�1�2�3�4�5�6�7 *¡D�*�R�*�**¡A*TLPROC:5�BTSTW�#CAC_S,BUSACTIV(A5)„is�BUS�in�controller�mode?+�BNE.S�TLP20‘br�=�yes,�O.K.�to�initiate�I/O*=�BTSTW�#BUSIOP,BUSACTIV(A5)ƒis�there�INTRP�level�I/O�pending?6�BNE.S�TLP10‘br�=�yes,�go�check�for�matching�operation*6�MOVE.B�D0,IOPEND(A5)ˆelse�mark�Task�level�I/O�pendingD�MOVE.L�MENUCPOS(A5),MENUNPOS(A5)‚back�up�menu�pointer�to�re-execute(�MOVEQ�#ISTAOK,D1Œset�return�code�=�O.K. �BRA.S�TLP40‘and�exit�with�C�=�1*>TLP10�MOVE.B�IOPEND(A5),D2ƒD2�=�INTRP�level�I/O�pending�status MOVE.B D0,D11�AND.B�D2,D1‘D1�=�INTRL P�^�TASK�I/O�pending�status1�BEQ.S�TLP30‘br�=�operation�type�mismatch�-�error*/�BTST�#SECONDAR,D2‹secondary�address�operation?*�BEQ.S�TLP20‘br�=�no,�O.K.�to�initiate�I/O* MOVEQ #SECMASK,D3 MOVE.B IOSSAD-1(A3),D1-�AND.B�D3,D1‘D1�=�task�requested�sec.�address0�AND.B�D2,D3‘D3�=�INTRP�level�pending�sec.�addr.�CMP.B�D1,D3‘are�they�the�same?4�BNE.S�TLP30‘br�=�no,�go�kill�task�requested�command*,TLP20�BSR�MTFIFO�O.K.�to�init.�I/O!�LET'S�GO'�BNE.S�TLP40‘oops,�hardware�malfunction*6�CLR.B�IOPEND(A5)Œclear�INTRP�level�I/O�pending�status/�BCLRW�#BUSIOP,BUSACTIV(A5)ƒand�associated�flag&�MOVEQ�#ISTAOK,D1Œset�return�code�O.K.�ANDI�#$FE,CCR�clear�Carry�bit RTS*'TLP30�MOVEQ�#ISTAIRPI,D1…set�error�code* TLP40�ORI�#$01,CCR‹set�Carry�bit RTS  PAGE* *ƒSETUPDMA*>*‡This�routine�is�used�by�the�READDATA,�WRITDATA,�and�SENDTERM<*„processors�to�set�up�the�memory�address�register�(MAR)�andA*„the�byte�count�register�(BCR)�on�the�MVME300�card.�These�simply8*„set�up�the�DMA�transfer�registers�but�initiate�no�I/O.*-*ˆENTER:‚A1�=�base�address�of�GPIBC�registers,*�A0�=�buffer�address�to�read/write�to/from."*�D0�=�number�of�bytes�to�transfer*!*ˆRegister�Usage:†0�1�2�3�4�5�6�7*šD‚P*šA‚P* SETUPDMA: MOVE.L D0,-(A7).�NOT.W�D0…convert�byte�count�to�1's�compliment-�MOVE.B�D0,BCNTLSB(A1)‚save�LSB�of�byte�count �LSR.W�#8,D0‡get�next�eigth�bits-�MOVE.B�D0,BCNTMSB(A1)‚save�MSB�of�byte�count*#�MOVE.L�A0,D0†D0�<==�buffer�addressB*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< *ˆ4/24/84ƒbwn*8*ˆThe�address�we�get�in�D0�is�the�address�as�seen�by�the *ˆdriver.4*ˆIf�we�are�using�dual�ported�ram‚on�the�VME/10,�and5*ˆif�this�address�is�in�on-board�ram,�then�it�must�be;*ˆtranslated�to�an�on-board�address�as�the�MVME300�sees�it.1*ˆWe�do�this�by�adding�the�RAM_SKEW�offset�to�the%*ˆaddress,�using�the�GO_OFF_BD�macro.* ‰GO_OFF_BD�D0*>*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>%�MOVE.B�D0,MARLSB(A1)‚save�LSB�of�MAR �LSR.L�#8,D0„get�next�eight�bits%�MOVE.B�D0,MARISB(A1)‚save�ISB�of�MAR �LSR.L�#8,D0„get�next�eight�bits%�MOVE.B�D0,MARMSB(A1)‚save�MSB�of�MAR MOVE.L (A7)+,D0 �RTS…exit PAGE**‚COMOUT*7*ˆSince�commands�bytes�(ATN�=�true)�can�not�be�sent�out=*„in�DMA�mode,�this�processor�will�send�out�a�byte�at�a�time.'*„It�assumes�that�the�ATN�line�is�true.*-*ˆENTER:„A1�=�base�address�of�GPIBC�registers*’A5�=�address�of�CCB *’D1.B�=�command�byte�to�be�sent*‘ zE ƒD ‹< “: ›8 £: «- ³5 »4 Ã. Ë1 ÓJ ÛM ã? ë:!*ˆRegister�Usage:„0�1�2�3�4�5�6�7*˜D„P‡P*˜A„P*COMOUT:F�MOVE.L�#1,CMDCOUNT(A5)ƒset�command�count�to�1�for�interrupt�processor*C*‚Entry�Point�used�by�the�Command�Out/Data�Out�and�the�Command�Out/*‚Data�In�processors**ƒspace�in�the�CCB�for�new�block�and�storing�new�configuration=*ƒinformation.‚In�actuality,�the�space�for�all�configurations<*ƒattached�to�this�CCB�have�already�been�allocated�and�it�is+*ƒjust�a�matter�of�adjusting�some�pointers.=*‡Since�IOI�is�initiating�this�call,�A1�looks�like�the�user's?*ƒbuffer�but�is�really�apointer�to�the�default�configuration�of *ƒthe�DCB.;*‡The�BUS�activity�flag�(BUSACTV)�is�set�up�at�this�time�to$*ƒindicate�its�initial�startup�mode.*+�MOVE.L�A2,-(A7)‚save�address�of�GPIBC�regs6�LEA.L�CONFINFO(A5),A2‚configuration/DCB�pointer�table MOVEQ #0,D0'�MOVE.B�DCBCDV(A4),D0‚get�device�number"�ASL.L�#3,D0‡calculate�table�index@�MOVE.L�NEXTCNFG(A5),A0‚A0�<==�next�available�configuration�area=�MOVE.L�A0,CNFIGPTR(A2,D0.L)‚set�configuration�ptr�for�device3�MOVE.L�A4,DVDCBPTR(A2,D0.L)„set�DCB�ptr�for�device*I*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*8*ˆ10/16/84‚SET�SERVICE�REQUEST�WAITING�FLAG�TO�CATCH�ANY2*’SRQ'S�PENDING�ON�THE�BUS�AT�TIME�OF�BOOT/STARTUP6*’SINCE�THAT�SRQ�INTERRUPT�WILL�BE�LOST�IN�THE�TMS9914$*’AT�TIME�OF�CHANNEL�INITIALIZATION.*‰BSETW…#SRQWAIT,BUSACTIV(A5)*I*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>J�MOVE.W�IOSVARL+DCBDEV(A4),D0„D0�<==�length�of�variable�configuration�area �BTST�#0,D0…odd�number�of�bytes?�BEQ.S�CDEVA„branch�if�noB�ADDQ�#1,D0…allocate�in�even�by�amounts�for�addressing�consistency*KCDEVA�LEA.L�IOSILN(A0,D0.W),A2‚calculate�total�length�of�configuration�areaD�MOVE.L�A2,NEXTCNFG(A5)ƒupdate�next�available�configuration�area�ptr.�MOVE.L�(A7)+,A2‚restore�address�of�GPIBC�regs*?*ƒThe�next�check�will�determine�if�the�GPIB�is�being�configured4*ƒwith�system�controller�capabilities.‚If�this�is�so=*ƒthen�the�bus�interface�will�take�control�of�the�BUS�at�this?*ƒpoint.‚Otherwise�its�mode�will�be�set�according�to�the�deviceB*ƒattributes�word�(IOSATW)�passed�in�the�configuration�data�block.E*ƒIf�the�BUS�is�configured�for�Talker/Listener�only,�NO�OTHER�DEVICESI*ƒWILL�BE�ALLOWED�TO�BE�CONFIGURED�AT�SYSTEM�INTIALIZATION�TIME.‚AttemptsG*ƒto�access�these�devices�at�a�later�time�will�cause�a�DEVICE�NOT�READY(*ƒerror�condition�to�be�returned�by�IOS.*&�TST.B�DCBCDV(A4)”configuring�the�BUS?�BNE.S�COMNCNFG”branch�if�no MOVE.L A1,-(A7)9�BSR�RESETIO—correct�for�intrps�to�an�un-attached�channel MOVE.L (A7)+,A1A�BTSTW�#IOASCTC,IOSATW(A1)‰is�BUS�being�config.�with�S.C.�capab�?�BEQ.S�COMNCNFG•branch�if�no*2*ˆElse�test�interface�for�compatible�configuration*:*ˆNOTE!!!‚The�device�will�be�stripped�of�system�controller8*ˆcapabilities�without�notifying�the�caller�on�the�first9*ˆtime�configuration�only.�This�allows�a�successful�first:*ˆtime�configuration�and�will�not�mark�this�device�OFFLINE*ˆupon�return.*.�TST.B�ADDRREG(A2)‘is�MVME300�card�in�SC�mode?�BPL.S�CDEN VB—branch�if�yes9�BCLRW�#IOASCTC,IOSATW(A1)‰do�not�allow�S.C.�capabilities BRA.S COMNCNFG*>*ˆSoftware�&�hardware�S.C.�configurations�agree,�TAKE�CONTROL!*CDEVB MOVE.L A1,-(A7)#�MOVE.L�A2,A1•set�up�A1�for�SENDIFC&�BSR�SENDIFC–Take�control�of�BUS,�NOW! MOVE.L (A7)+,A1*/*‚Continue�with�normal�configuration�processing*"*ˆCheck�for�unsupported�attributes*MCOMNCNFG�MOVE.W�#CECUAP,D2ƒpreload�unsupported�attribute/parameter�error�code*3�MOVE.W�#NVALBATM,D0ƒget�mask�of�invalid�attributes8�AND.W�IOSATM(A1),D0ƒtrying�to�change�invalid�attribute?"�BNE�CNFGERR†branch�if�yes�(error)*1�MOVE.W�#NVALBPRM,D0‚get�mask�of�valid�parameters8�AND.W�IOSPRM(A1),D0‚trying�to�change�invalid�parameter?"�BNE�CNFGERR…branch�if�yes�(error)*9*‚Set�the�attributes�into�the�user's�configuration�buffer"*‚that�he�does�not�want�to�change.*0�MOVE.W�IOSATM(A1),D0‚D0�<==�his�attributes�mask;�AND.W�D0,IOSATW(A1)ƒZero�out�the�attributes�of�his�that�he9�NOT.W�D0Ždoesn't�want�to�change,�zero�out�the�attributes=�AND.W�IOSATW(A0),D0ƒof�mine�that�he�does�want�to�change,�and.�OR.W�D0,IOSATW(A1)„combine�them�in�his�space.* *‚Do�the�same�for�the�parameters*3COMN010�MOVEQ�#0,D0ƒbe�sure�upper�16�bits�are�clearK�MOVE.W�IOSPRM(A1),D0‚D0�<==�mask�of�parameters�that�he�does�want�to�change7�MOVEM.L�A0-A2,-(A7)„save�configuration�block�addresses4�LEA.L�IOSREC(A0),A0„A0�<==�addr�of�1st�param�in�CCB@�LEA.L�IOSREC(A1),A1„A1�<==�addr�of�1st�param�in�user�data�block2�LEA.L�PAR_SIZ,A2…A2�<==�addr�of�table�param�sizes*NXTPARM MOVEQ #0,D11�MOVE.B�(A2)+,D1‚get�#�of�bytes�in�next�parameter%�BEQ.S�CHKPARM„branch�if�end�of�table*+�LSR.W�#1,D0…want�to�change�next�parameter?�BCS.S�INCPARMƒbranch�if�yesA�SUBQ�#1,D1†does�not�want�to�change�it�so�move�parameter�from�CCB2*�to�the�user's�buffer�so�that�he�will�have�a�copy)MOVPARM�MOVE.B�(A0)+,(A1)+‚move�next�byte)�DBRA�D1,MOVPARMƒuntil�byte�count�expires'�BRA.S�NXTPARMƒcheck�the�next�parameter*?INCPARM�ADD.L�D1,A0‚he�does�want�to�change�it�so�leave�his�copy4�ADD.L�D1,A1‰alone�and�just�go�to�the�next�parameter BRA NXTPARM*>*ƒCheck�to�see�if�he's�doing�any�configuration�that�is�illegal*:CHKPARM�MOVEM.L�(A7)+,A0-A2‚restore�configuration�pointers=�MOVE.W�#CECIPA,D2‚preload�invalid�primary�address�error�code*2�MOVE.B�IOSPRMA(A1),D0‚get�current�primary�address0�CMP.B�#$1E,D0…valid?�(MUST�BE�0<=�ADDR.�<=�$1E)�BHI�CNFGERR…branch�=‚error*"�TST.B�DCBCDV(A4)‚is�this�the�bus?�BNE.S�CHKPRM2…branch�if�no*=*‚Check�to�see�if�the�primary�address�configured�matches�what-*‚is�set�on�the�switches�of�the�MVME300�card.*C�MOVE.B�ADDRREG(A2),D1ƒD1�<==�primary�addr�read�from�board�switches+�NOT.B�D1‰use�complement�of�switch�register �AND.B�#$1F,D1„mask�primary�addr?�CMP.B�#$1F,D1„is�switch�register�=�$1F�(INVALID�GPIB�ADDRESS!)C�BNE.S�CHKPRM1„BR�=�no,�use�hardware�switch�register�as�BUS�address)�MOVE.B�D0,D1…else�use�SYSGEN�BUS�address*@CHKPRM1�MOVE.B�D1,ADDRREG(A2)‚set�TMS9914A�primary�addr�register, MOVE.B D1,IOSPRMA(A1) update config. buffer9�BTSTW�#IOSPOLCB,IOSPRM(A1)‚local�pp�configuring�the�bus?�BEQ.S�CHKPRM2ƒbranch�if�no*=�MOVE.B�IOSPOLC(A1),D0‚D0�<==�new�parallel�poll�configuration/�BMI.S�CHKPRM2ƒbr�=�no�configuration�set�for�PP;�AND.B�#$1F,D0ƒmask�PPP,�S�and�I�bits,�BUS�is�in�PPSS�state+�MOVE.B�D0,IOSPOLC(A1)‚save�in�users�buffer+�BSR�SETPPREG‚set�up�parallel�poll�register*JCHKPRM2�ANDI.L�#$7FFFFFFF,IOSSAMR(A1)ƒmask�out�bit�31�of�both�the�Read�and<�ANDI.L�#$7FFFFFFF,IOSSAMW(A1)ƒWrite�Secondary�Address�masks*<*‚If�we�make�it�to�here�everything�has�been�validated�and�is:*‚OK�with�the�fixed�portion�of�the�configuration�block.�If<*‚the�user�has�defined�a�variable�configuration�area,�do�the*‚necessary�sequences�for�that.*C�TST.W�IOSVARL+DCBDEV(A4)‚is�there�any�variable�configuration�info?�BEQ.S�OKCNFG†branch�if�no*<�MOVE.W�#CECVARL,D2ƒpreload�variable�config�param�error�code?�MOVE.L�IOSFMTA+DCBDEV(A4),D0ƒget�pointer�to�user�I/O�N formatter4�BEQ.S�OKCNFG�branch�=�no�user�defined�I/O�formatter MOVE.L D0,A2A�TST.L�USER_CNF(A2)†is�a�variable�config�parameter�routine�given?�BEQ.S�OKCNFGŽbranch�if�noF MOVEM.L D1-D7/A0-A6,-(A7) save everything except user's return status<�JSR�USER_CNF(A2)‹execute�user�defined�configuration�routine. MOVEM.L (A7)+,D1-D7/A0-A6 restore environment�TST.B�D0�Any�errors?�BNE.S�CNFGERR…branch�if�error*>*‚The�only�thing�that�remains�now�is�sec.�addr.�validation�andD*‚to�update�the�TMS9914A�interrupt�mask�register�to�enable�secondaryI*‚addressing�if�valid�secondary�addresses�were�newly�defined�for�the�BUS.*8OKCNFG�TST.L�IOSSAMR(A1)‚any�sec.�Read�addr's�specified?�SNE�D0“D0�=�Yes/No3�TST.L�IOSSAMW(A1)ˆany�sec.�Write�addr's�specified?�SNE�D1“D1�=�Yes/No$�MOVEQ�#CECSADR,D2ˆpreset�error�code$�EOR.B�D0,D1ŽBoth�must�be�specified! �BNE�CNFGERRŽelse�it�is�an�error*" TST.B DCBCDV(A4) is this the BUS? BNE.S OKCNFG3 br = noB�MOVE.W�TMSMASK(A5),D0‚set�the�current�state�of�the�9914A�mask�reg5 BSET #APTBIT,D0 set up to enable secondary adressing0 TST.L IOSSAMR(A1) any sec read addresses valid?�BNE.S�OKCNFG2ƒbranch�if�yes:�BCLR�#APTBIT,D0ƒelse�disable�secondary�address�interrupts5OKCNFG2�MOVE.W�D0,TMSMASK(A5)‚save�in�mask�status�reg8 MOVEP.W D0,INTR0(A2) update TMS9914A interrupt mask reg*OKCNFG3 MOVEQ #0,D0F�MOVE.W�IOSVARL+DCBDEV(A4),D0„D0�<==�length�of�variable�parameter�area@�ADD.L�#(IOSILN-IOSATW)/2-1,D0ƒadd�in�rest�of�configuration�area*�MOVEM.L�A0/A1,-(A7)ƒsave�start�of�buffers5�LEA.L�IOSATW(A0),A0‚set�pointers�to�start�of�buffers LEA.L IOSATW(A1),A1*?OKCNFG5�MOVE.W�(A1)+,(A0)+‚copy�his�validated�buffer�to�the�CCB#�DBRA�D0,OKCNFG5„configuration�area*5�MOVEM.L�(A7)+,A0/A1ƒrestore�start�of�buffer�pointers.�EXG�A0,A1‰set�A0�=�his�buffer,�A1�=CCB�buffer5�BSR.S�STATYP1…set�up�status�and�configuration�headerF�MOVE.B�#1,DCBCCF(A4)ƒset�flag�indicating�that�a�CONFIGURE�or�a�CHANGE *®DEFAULT�CONFIGURATION�was�done*A*ˆThis�test�is�performed�at�this�time�so�an�initial�configurationC*ˆwill�occur�even�if�there�is�a�S.C.�switch/sysgen�incompatibility.*-�TST.B�DCBCDV(A4)‚are�we�configuring�the�BUS?#�BNE.S�OKCNFG7‚branch�=�not�the�bus*2�EXG�A0,A1ƒset�A0�=�CCB�buffer�and�A1�=�his�buffer4�MOVEQ‚#CECSCE,D2ƒpreload�invalid�S.C.�configurationB�BTSTW�#IOASCTC,IOSATW(A0)‚are�we�configuring�for�S.C.�capability?6 BEQ.S OKCNFG7 branch = no, else test hardware config.9 TST.B ADDRREG(A2) is the MVME300 card switch in SC mode?'�BMI.S�CNFGERR‚branch�=�no,�go�to�error*0OKCNFG7�MOVEQ‚#ISTAOK,D1‚set�return�status�to�OK �RTSƒexit*CCNFGERR MOVE.B D2,IOSCEC(A1) save specific configuration error codeB�MOVEQ‚#ISTACNF,D1‚set�invalid�configuration�for�device�error�code(�RTSƒexit�common�configuration�processor  TTL COMMON SUBROUTINES PAGE**‚STATYP*A*ˆThis�routine�is�used�by�CONFIGURE,�CHANGE�DEFAULT�CONFIGURATION;*…and�REQUEST�STATUS�processors�to�store�the�current�status8*…information�in�the�standard�configuration�area�header.*,*ˆENTER:‚A2�=�base�address�of�GPIB�registers*�A4�=�address�of�DCB*�A5�=�address�of�CCB*5*ˆEXIT:ƒA0�=�address�of�configuration�area�for�device*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�* *›A�R‡P�P*STATYP:0�BSR.S�GETCNFIGƒA0�<==�current�configuration�ptr*STATYP1: MOVEQ #0,D0"�TST.B�DCBCDV(A4)‰is�this�the�BUS?�BNE.S�STATYP2Œbr�=�no'�MOVE.B�ADDRSTAT(A2),D0ƒget�GPIB�status�AND.B�#$FE,D0Œmask�out�garbage*6STATYP2 MOVE.B D0,IOSDST(A0) put dev. status in buffer9 MOVE.B DCBDEV+IOSCTP(A4),IOSCTP(A0) set the channel type8 MOVE.B DCBDEV+IOSDTP(A4),IOSDTP(A0) set the device type/ MOVE.B #IODGPIB,IOSDRC(A0) set the driver code �RTSƒexit  PAGE* *„SETPPREG*:*ˆThis�subroutine�will�set�or�clear�the�desired�bit�of�the?*…parallel�poll�register�for�when�a�parallel�poll�is�performed.A*…If�both�the�Individual�Status�bit�and�the�Sense�bits�are�equal,>*…the�bit�specified�will�be�set�in�the�parallel�poll�register.8*…otherwise�the�O parallel�poll�register�would�be�cleared.*;*ˆThe�PPreg�will�not�be�set�if�the�system�is�in�PPIS�state.**,*ˆENTER:‚A0�=�pointer�to�configuration�table*�A5�=�address�of�CCB**ˆEXIT:ƒno�errors�return*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�*ƒ**›AƒP* SETPPREG:!�MOVE.L�A1,-(A7)‚Save�environment MOVEQ #0,D23 MOVE.B IOSPOLC(A0),D0 get current PP configuration3�BMI.S�SETPR025ˆbr�=�In�PPIS�state,�don't�set�PPreg'�BTST�#PPSENSE,D0‚is�the�sense�bit�set?�BNE.S�SETPR020‚branch�if�yes*:*‚The�sense�bit�is�equal�to�zero,�so�the�individual�status8*‚must�also�be�zero�to�set�the�parallel�poll�status�to�1*2�BTST�#INDIVST,D0‚is�the�individual�status�bit�set�BNE.S�SETPR015ƒno*$SETPR010�AND.L�#7,D0‚mask�bit�number'�BSET�D0,D2‚set�to�parallel�poll�status*6SETPR015�MOVE.L�CCBCHB(A5),A1‚A1�<==�ptr�to�GPIBC�regs:�MOVE.B�D2,PARLPOLL(A1)‚store�results�in�Parallel�poll�reg,SETPR025‚MOVE.L�(A7)+,A1ƒrestore�environment RTS*:*‚The�sense�bit�has�been�determine�that�it�is�equal�to�one*7SETPR020�BTST�#INDIVST,D0‚is�individual�status�bit�set?�BNE.S�SETPR010„branch�if�yes�BRA.S�SETPR015„no,�exit PAGE* *ƒGETCNFIG*5*ˆGet�a�pointer�to�the�current�configuration�area�for*…the�desired�device.**ˆENTER:‚A4�=�address�of�DCB*�A5�=�address�of�CCB*5*ˆEXIT:ƒA0�=�address�of�configuration�area�for�device*!*‹Register�Usage:ƒ0�1�2�3�4�5�6�7*›D�* *›A�R‡P�P* GETCNFIG: MOVEQ #0,D0<�MOVE.B�DCBCDV(A4),D0ƒD0�<==�device�number�of�desired�deviceC�LEA.L�CONFINFO(A5),A0ƒA0�<==�base�addr�of�configuration�table�ptrs!�ASL.L�#3,D0‡Two�long�words/entryB�MOVE.L�CNFIGPTR(A0,D0.L),A0‚A0�<==�base�addr�of�config�for�device �RTSƒexit * *ƒGETXFRAD*7*‰This�routine�will�simply�pull�off�the�physical�buffer *‡addresses�from�the�GPIB�queue.**�ENTER:‚A5�=�address�of�CCB*"*�EXIT:‚D4�=�primary�buffer�length*–D5�=�secondary�buffer�length/*–D6�=�physical�addr�of�secondary/config�buffer&*–D7�=�physical�addr�of�primary�buffer*!*‘Register�Usage:„0�1�2�3�4�5�6�7 *¡DŠR�R�R�R*¡A‚** GETXFRAD:.�MOVE.L�QTAIL(A5),A0…get�current�queue�pointer;�MOVE.L�PBPAOFST(A0),D7‚D7�<==�physical�primary�buffer�addrD�MOVE.L�SBPAOFST(A0),D6‚D6�<==�physical�secondary/config�buffer�addr MOVEQ #0,D54�MOVE.W�SBLNOFST(A0),D5‚D5�=�secondary�buffer�length MOVEQ #0,D42�MOVE.W�PBLNOFST(A0),D4‚D4�=�primary�buffer�length �RTS‚exit PAGE****ˆSET�UP�INDEX�(POINTER)�TO�FUNCTION�TABLE*ˆBASED�UPON�IOSPB�FUNCTION**ˆON�ENTRY:�A3�=>�IOCB*'*ˆON�EXIT:‚D2.W�IS�TABLE�OFFSET�(INDEX)+*’D1.B�&��=�OPERATION�STATUS�(�0�=�O.K)*8*‚Find�the�function�in�the�table�of�valid�GPIB�functions*GETCMDP:!ˆMOVEM.L�A0/D0/D6,-(A7)�save�regs5�MOVE.W�#NUMCMDS-1,D0ƒnumber�of�valid�GPIB�commands-14�LEA.L�IOSCMDTB(PC),A0ƒset�ptr�to�GPIB�command�table1�MOVE.W�IOSFCT(A3),D6ƒpick�up�function�from�IOSPB8�MOVEQ‚#ISTAIF,D1ƒset�invalid�command�error�just�in�case*&GETCMD50�CMP.W�(A0)+,D6ƒfound�command?.�DBEQ�D0,GETCMD50ƒbranch�if�no,�look�some�more*,�BNE.S�GETCMDX„exit�with�error,�end�of�table4�MOVE.W�#NUMCMDS-1,D2ƒcalculate�relative�table�index�SUB.W�D0,D2‚D2�<==�table�index"�ASL.W�#1,D2‚Calculate�word�offset*0�MOVEQ‚#ISTAOK,D1�set�process�O.K.�return�status*GETCMDX TST.B D1 set return condition code$ MOVEM.L (A7)+,A0/D0/D6 restore regs RTS* 6 TTL GPIB DRIVER - COMMON SUBROUTINES (QUEUE HANDLING) PAGE**‚POP�GPIB�QUEUE�ENTRY*6*ˆIf�I/O�is�aborted�or�an�operation�is�completed,�this9*…routine�will�pop�that�operation�from�the�GPIB�queue�and9*…update�the�necessary�queue�pointers.�It�is�assumed�that:*…the�caller�has�previously�inhibited�all�interrupts�since*…this�is�critical�processing.**’ENTER:ƒA5�-�address�of�CCB*#*’EXIT:ƒIF�„THEN‚queue�is�empty)*œELSE‚queue�still�has�at�least�one�entry*!*ŽRegister�Usage:ƒ0�1�2�3�4�5�6�7*žD *žA�*�*‡P* POPGPIBQ:1�LEA.L�GPIBQEND(A5),A0‚A0�<==�ptr�to�end�of�queue.�MOVE.L�QTAIL(A5),A1„get�currentO �queue�pointer2�CMPA.L�QHEAD(A5),A1„is�there�an�entry�to�POP�off?,�BEQ.S�POPG15ŒBR�=�no,�exit�with�proper�?�ADDA.L�#GPIBQLEN,A1„advance�pointer�by�length�of�a�queue�entry�CMPA.L�A0,A1…at�end�of�queue?�BNE.S�POPG10ƒno*%* time to wrap around to top of queue*5�LEA.L�GPIBQ(A5),A1…set�queue�pointer�to�top�of�queue*APOPG10�MOVE.L�A1,QTAIL(A5)ƒupdate�current�operation�queue�pointer<�CMPA.L�QHEAD(A5),A1ƒset�condition�for�empty/not�empty�queue POPG15 RTS‰PAGE* *ƒPSHGPIBQ*9*ˆThis�routine�is�used�regardless�of�whether�the�queue�is?*…busy�or�not.�It�will�place�in�the�GPIB�queue�all�the�pointers=*…necessary�to�execute�this�command�when�its�time�comes.�LikeD*…the�POPGPIBQ�routine�it�also�assumes�that�the�caller�has�inhibited*…interrupts�before�entering.**’ENTER:‚A3�-�address�of�IOSPB*šA4�-�address�of�DCB*šA5�-�address�of�CCB*šD4�-�primary�buffer�length*šD5�-�secondary�buffer�length&*šD6�-�physical�addr�of�primary�buffer/*šD7�-�physical�addr�of�secondary/config�buffer**’IF�„THENƒno�errors*•ELSE„queue�is�full*!*�Register�Usage:ƒ0�1�2�3�4�5�6�7 * D�*‡P�P�P�P* A�*�PƒP�P�P�P* PSHGPIBQ:!�MOVE.L�A1,-(A7)ƒsave�environment4�LEA.L�GPIBQEND(A5),A1„A1�<==�end�of�GPIB�queue�area4�MOVE.L�QHEAD(A5),A0†A0�<==�next�available�queue�ptr*�CLR.W‚CSTQOFST(A0)†set�entry�status�to�OK+�MOVE.L�A4,DCBQOFST(A0)ƒsave�address�of�DCB6�MOVE.L�A3,IPBQOFST(A0)ƒsave�physical�address�of�IOSPB?�MOVE.L�D7,PBPAOFST(A0)ƒsave�physical�address�of�primary�bufferI�MOVE.L�D6,SBPAOFST(A0)ƒsave�physical�address�of�secondary/config.�buffer2�MOVE.W�D4,PBLNOFST(A0)ƒsave�primary�buffer�length4�MOVE.W�D5,SBLNOFST(A0)ƒsave�secondary�buffer�length;�ADDA.L�#GPIBQLEN,A0„increment�by�length�of�one�queue�entry"�CMPA.L�A1,A0…time�to�wrap�around?�BNE.S�PSHQ010„branch�if�no*0�LEA.L�GPIBQ(A5),A0‚set�ptr�to�top�of�queue�area**PSHQ010�CMPA.L�QTAIL(A5),A0‚is�queue�full?5�BEQ.S�PSHQRTN‚yes,�but�this�should�not�have�happened4 MOVE.L A0,QHEAD(A5) update next available queue ptr4�MOVEQ�#1,D0‚set�condition�code��for�O.K.�return*PSHQRTN�MOVE.L�(A7)+,A1ƒrestore RTSA TTL GPIB DRIVER - COMMON SUBROUTINES (VALIDATE OPERATIONAL MODE) PAGE**‚VALIDATE�OPERATIONAL�MODE*9*ˆThis�routine�will�be�called�at�the�point�when�a�command:*ˆis�about�to�be�scheduled�for�I/O�initiation.�The�purpose;*ˆis�to�determine�if�the�BUS�is�in�the�proper�mode�for�this:*ˆcommand�and�to�determine�if�the�BUS�or�device�(depending:*ˆon�who�this�command�is�directed�to)�has�the�capabilities3*ˆ(if�any�are�necessary)�to�perform�this�operation.*3*’ENTER:‚A3�=�address�of�IOSPB�for�current�function*šA4�=�address�of�the�DCB*šA5�=�address�of�the�CCB%*šD2.W�=�index�of�command�in�VALPARTB*NNNNN