IMD 1.17: 11/11/2014 10:46:15 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 4 OF 30  SR04q82VKXSVRDOS 0420¥m-)žF3 Hç€pab$¼B€0*å€\€2€ Kp,, (-"¸´pg \GSfô0<ýNuB4pNuHçþ/>,, F3 (-"¸´pg \GSfô0<ý`B† ôp.LßNuHçþ/>,, "-"²´pg \GF3 Sfô0<ý`BBBA tp4pÂBƒ.LßNurB‚½ñf 01a3¼ÿÿ\�R‚ ‚F3 fâB€`þ m"�NuHçþBƒrB‚B€0+6+g½ñfƒJCfa`R‚\�F3 ‚fà0<ò`B€Lß`²/ $m"�$_Nu/ $m"±$_Nu/ $m"0+@ÿgF3 Ê$_NuHçþBƒrB‚B€0+6g½ñf¤ƒJCfa¸`R‚\� ‚fà`ŒLßF3 B€`DHçþB…BƒrB‚B€0+6@ÿg½ñfÿbƒJCfa€`\�R‚`ä7E`ÿPF3 0<ô``ø6€NuŸü /KB†BƒB‚B€0+J@gpB…:3`/E. ߯.aÌÎüF3 XG½ñpf2&3`g4\FAúTB�-)$/Hçÿþ"Cp"N@`` aþèLßÿS@`¨B€0<öF3 `B€0<ø`LßÿB€0<ñ`&oB€ßü `ÿdHçÿþ*A…ÿ($< F3 aB aþœÈüD XD$y(,mPB‡* ,-&* ¼ƒg Ôü4Sk`î02@a$LßF3 ÿNsQ�B¯RoJEgçïSE`ô:/P�Nu02@ff(-"a ` NpN@F3 NuHçÿþ NpN@``LßÿNu`øfJ…g i6pN@`` J…gJ0PfT—T—NuHçF3 þŸü $y(B‡* -&* °ƒg Ôü4Sk`î/J$< /BB„pÞü 3 Lßþ|ÿþNu4é(;1FTACO ASREL' M615LIB SA$S(…ACO subroutines`2IACOPEN IACOOFF RIACOCLS .IACOPLS nIACOSTA `IACOOUT @)¾F3 Hç€pa‚$¼B€0*å€\€2€ Kp:ÄüX‚Jq jBR‡63/C&/a^ @ýg03ƒ #Ž XAS@nÄF3 a| @ýgB€`40<ö`.0<÷`(0<ý`"0<þJGg6<ÿÿB�43ÄüX‚3ƒ XASGnìF3 P�Lß`øHçþ/>,, (-"¸´pg \GSfô0<ý`B† ôp.LßNuHçF3 þ/>,, "-"²´pg \GSfô0<ý`BBBA tp4pÂBƒ.LßNu>,F3 , (-"¸´pg \GSfô0<ýNuB4pNurB‚½ñf 01a3¼ÿÿ\�R‚ ‚F3 fâB€`: m"�NuHçþBƒrB‚B€0+6+g½ñfƒJCfa`R‚\� ‚F3 fà0<ò`B€Lß`î/ $m"�$_NuHçþBƒrB‚B€0+6g½ñfȃJCF3 fa`R‚\� ‚fà`°LßB€`¤/ $m"±$_NuHçþB…BƒrB‚B€0+6@F3 ÿg½ñfÿxƒJCfa`\�R‚`ä7E`ÿf/ $m"0+@ÿgÊ$_Nu0,, (-"¸´pgG Sfò0<ý`(B† oQF3 f ´p` ôp` g ôp.LßNu ´pa`îýþÿþ ï÷ÿ÷F3 HçÿþB€Jk4g gpgP@B�2;Æ €x騃ÿá‹‚ƒ‚€F3 aLßÿNuB€âÞ;ªPÃ4pà‰ƒ4pà‰ƒ4pÿ≀ƒ4pNuHçþ/>,, F3 "-"²´pgG Sfò0<ý`Ð@Æ|BBBA tpÐFD¨ÈBFB4pF3 ÂB€4p€èƒFDÉBBBAè(FD¨ (ÈBFB4pÂB(€4F3 p@è ƒ(FDÉ(J(J(JJ((ä€4p@( ä€4p F3 @ ( ä€4p @ (ä€4p @B€FÆ.LßNu>,, (-"¸´pF3 gG Sfò0<ýNuB´pB´pNurB‚½ñf01a3¼ÿÿ\�R‚ ‚fàB€F3 `À m" lV¨�è�f ff<`< nF3 ¨ Nu n¨`ò n¨`æ¨ `à Q€¨ ¨è ¨NuHçF3 þBƒrB‚B€0+6+g½ñf"81gƒJCfa&`R‚\� ‚fÔ0,f2`2)aü0aüTNuÿÿHçþrB‚B€0+ @ÿn®g0½ñF3 fþ:81fþ4fþ,Ä3„HçÿþaLßÿR‚\� ‚fÀ`ÿrCúF3 aÿ~Nuþ÷Ÿü /KB†BƒB‚B€0+J@gŠB…:3`/E. ߯.a¦ÎüF3 XG½ñpfB61pg@&+gBAúdB�-)$/"CHçÿþp"N@``.LßÿHçÿþ F3 aý’LßÿS@`–B€<ö`"B€<ù`B€<ø`LßÿB€8ñ`&oB€ßü `DF3 Hçÿþ*A…ÿa aý˜LßÿNsQ�B¯RoJEg çïSE`ò:/P�F3 Nu6€Nup N@fJ…g i6pN@`` J…gJ0PfT—T—NupN@`NqT—NuHçþF3 ŸüB¯ $y(B‡* -&* °ƒg ÔøSk”`ì/J$< aÆ/BB„F3  gtR¯ ÈüD XD$y(,r@02@@gJ. Þ$Aú8B�-)àHÀüF3 "|2@NVÿ¸H×ÿp"N@``L×ÿ(nBÿaþL×ÿN^` $/a" / ÞüF3 LßþJ€g |`|ÿþNu02@f(-"aVNu` NpN@Nu m"F3 ( g ( f„RB( g( fpRB(g(fdRB(gF3 (fRRB(g(fFRB(g(f4RB( g( f&RBF3 ( g( fRBNuJ(NuJ(NuJNuJ(NuHçÿþ$< BƒB„B†F3 ÈüDAÿ*A"m"$y(B‡ -* ** °…g ÔøSFgJ`î,r@2@gF3 )gHçÿþaþÊLßÿ`)fHçÿþaþ²Lßÿ‚ÿ(JB�aûúLßÿNs3 Hçÿþ NpN@``LßÿNu`ø4éé;1FTRIO ASREL' RIOLIB SA2W(…RIO subroutines~2IRIOPEN IRIOOFF RIRIOCLS .IRIOPLS ŠIRIOENB nIRIODSB |IRIOSTA `IRIOOUT @)ÜF3 Hç€pa $¼B€0*å€\€2€ Kp*‚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�to–BŸ:§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_D A�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„PROGSTRTééééé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;*�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)‚> 6A:";*L2C:TBFJDREZ^=*�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�Progra  m**&*Œ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�r  elatively*£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�use  d�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�tel  ls�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(A0)Š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„PROGSTRTTESTƒˆÿÿÿÿÿ€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=�'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�nu m�:=�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�>=�10k h,Œ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. =/*=/*†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=/*}=/*=ENDééé ééé*‰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�=�physical�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„2H%I-95B=B=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�S egment�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„28INT020„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ŠEND=/*=/*†M610DRV.TEST610.AF=/*,=/*†TEST610�test�program�assembly�chain�file=/*6=/*†The�command�line�will�accept�arguments�as�follows:=/*;=/*‹Argument�01…\1�=�Output�file�assembly�listing�or�device=/*=/*H=/*†The�following�shows�the�assembly�chain�sequence.‚In�this�example�theH=/*†NULL�device�was�chosen�as�Argument�01,�however,�the�user�could�if�he5=/*†so�desired�have�requested�an�output�listing�file.=/*#=/*�=CHAIN�M610DRV.TEST610.AF�#NULL=/*-=/*†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�--=/*}=/*=END éééééE=/*=/*†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=/*=ENDéééééNN*******************************************************************************Ì**Ì*#*—MVME610�or�MVME620‚Test�Program•**Ì**Ì*N********************************************************************************6* This program was writt en 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�ASCIIW>`:hDpBxG€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ŠNEXTWBMESS6…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„PROGSTRTé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 4 gˆ`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*NuHçùÀ./ 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(NNNu pþ`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Š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ŠNEXTWB 1MESS11„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)ŠMOVE.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„PROGSTRTééééééé=/*=/*†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�--=/*}=/*=ENDéééééé P=/*=/*†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=/*=ENDééééééYB*„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. b/kPsP{PƒV‹\“\›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‰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‡O FFCMD(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‰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�SIMULTANEOUSL Y*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‡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„#OPNLN GS,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‰B RA‡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* STATCM D‚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�PROGRAM�******�'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Š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�(D# ynamic)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�B# RA.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‚I$ NPUTBUF,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„PROGSTRT=/*=/*†M625DRV.TESTDC.AF=/*;=/* Chain file to assemble DCO driver test routine 'TESTDC'=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M625DRV.TESTDC.LS=/*=/IFC \1ƒ=ARG�M625DRV.TESTDC.LS=/ENDIF=/*2=ASM M625DRV.TESTDC.SA,M625DRV.TESTDC.RO,\1;MRZ=70=/*{ Included files are:=/*ƒ--�none�--=/*}=/*=ENDéééééé$ =/*=/*†M625DRV.TESTDC.LF=/*/=/* Link chain file to create M625DRV.TESTDC.LO=/*:=/* If no output argument is specified for the listing the0=/* chain file will default to M625DRV.TESTDC.LL=/*=/IFC \1ƒ=ARG�M625DRV.TESTDC.LL=/ENDIF=/* =LINK ,M625DRV.TESTDC.LO,\1;HMIX SEG SEG0:0INPUT M625DRV.TESTDC.ROEND=/*=ENDééééééˆB*„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�numb% ers�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ÚPâYêZòYúRR Wb=*ˆ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‡S% TATCMD(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‰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‡OPNCM& D(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,D' 0Ž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�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„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 ‰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„#'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‡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†'**********�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„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)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)+q4c<(†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�WIT* H�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,OFF)†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†ENDééééC:C ********************************************************C†SUBROUTINE�DELAY C–DELAY�APPROXIMATELY�ONE�SECOND†DO�30�J�=�1,100†DO�20�K�=�1,350 20„CONTINUE 30„CONTINUE†RETURN†ENDééé* ééééD C:C ********************************************************C†SUBROUTINE�ERRPR1(I)†WRITE�(6,10)�I#10„FORMAT�('�STATUS�ERROR-BIT�',I1)†RETURN†ENDéééééééM=/*=/*†M625DRV.TSTDCO.FF=/*7=FORTRAN M625DRV.TSTDCO.SA,M625DRV.TSTDCO.RO,;A,S,H=1207=FORTRAN M625DRV.TSTPR1.SA,M625DRV.TSTPR1.RO,;A,S,H=1207=FORTRAN M625DRV.TSTDLY.SA,M625DRV.TSTDLY.RO,;A,S,H=120=/*=ENDé+ ééééééVTEST8ÿÿÿÿÿ€SEG0 ÿÿÿÿ ÿÿDCO1€ MVME625 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| 1IpH{ˆB§B§rHÁ/HxN« OïN«v=|ÿÚ=|ÿÜBnÿÞ=| ÿàHnÿvHnÿÖAùN»ˆP�2.ÿÖJAk g0`B§AùIôH{ˆB§B§rHÁ/HxN« OïN«v`(B§AùIòH{ˆB§B§rHÁ/HxN« OïN«v=|ÿ´=|ÿ¶=nÿ¢ÿ¸HnÿvHnÿ°AùN»ˆP�B§AùI¾H{ˆB§B§rHÁ/HxN« OïN«v=|ÿ´=|ÿ¶=nÿ¢ÿ¸HnÿvHnÿ°AùÆN»ˆP�2.ÿ°JAk g0`B§AùI†H{ˆB§B§rHÁ/HxN« OïN«v`(B§AùI„H{ˆB§B§rHÁ/HxN« OïN«vB§AùFŠH{ˆB§B§rHÁ/HxN« OïN«vB§AùINH{ˆB§B§rHÁ/HxN« OïN«vB§AùF>H{ˆB§B§rHÁ/HxN« OïN«vAùI,EûˆAîÿv <N«<¬gAùIEîÿvAûˆü <N«<Œ`õJB§N«\X�LßþN^Nu/,OŸüHçB§AùHÜH{ˆB§B§rHÁ/HxN« Oï n/HxHx!B§N«zOïN«vLßþN^Nu/,OŸü Hçp-@ÿü=|cÿúJnÿúm*p-@ÿö=|]ÿôJnÿôm SnÿôR®ÿö`îSnÿúR®ÿü`ÐLßþN^NuHç€pa‚$¼B€0*å€\€2€ KpJAf Cðh.IŸÇGÔ*‹'I8AìÿÄ'H`«ƒ++g, (=f$Tˆ&ˆ ,gJgJƒf ;gRˆ`èB`pRˆNu ,fRˆ`öNuHç0øNVÿ¬$U(jd Ef #gZ&O"KvSüQËÿú7|,E1"Aë,NC A|,|@-7|.|0E1aœJ@f€B� (f (WfPk. ()g``"Aë,NCg fkÿþ.NCf J�f0`H f$J�g^ A (Dfk.k.7|P` (Ff ((fþCèah :g )fè �ÿþbÞR�Aÿþ7AN" |€-|0Aë,NCf¬|@-|0NCfšJ�g° A :f¦CèaJAg˜||7|+.g7|d‰- |k1'|B€0+NAïÿÿ'H ŸÀ'OB—SAAëSAR«R—NBfQÉÿô7|NBg,pB�+N^Lß NupB�+0N^Lß NupB�N^Lß NuB€N^Lß Nu #faÊNu)| 2"j<'i27i6'i8'i<'| @'| D7|FTH :gL 0m 9oJ"Hp :g*QÈÿøB€"H .fR€` 0m ZnR‰`æ @oL`.pCë2avJ@fnÐü .g"Ha¶ A'bX I7A6 .fL .gpCë8aBJ@f: .f4ÐüpCë@a,J@f$ .fÐüpCëHaJ@fJg (fB€NupNu @b2¼ `"¼ @c#|  Am$ ZbØ 0m 9c Am ZbQÈÿäpNuB€NuB€B� 0m 9bÃü Ò@`æNu&LaRJ@fþVEE19|,Aì,NC|@-9|.NCg&L`þ,|l1l.9lL9lN `þ& < '@2'@8'@<'@@'@D7@HRˆJf "j<'i$2`" Ef)| 2Cë2rJg ØQÉÿøpNuB€NuHçÿþ?oL@/oHJ?oBD?oNBAïD*UEí@$�|Œ *ÿ†f5|ex|zNº|ÿ†5PÐü*g5P%h Cúð%IlÐü ``*f"25A Ao Aco$5|fx|zNº®5|*g5|ÐüCú Æ*g Cú %hÿòÐü%IlCúà*gCú%P<Ðü%IhCú" *f@Cú,f%|*g%PÐü%|*g%PÐü*g%P%Ipr"jlN‘J@gT f*g"j`Nºè*g"j`NºÖ*g j0€*f €5|†.R/Ia²%L0pNuB‚‚"jb*f ü QÊÿú&+$"jba€%L0pNu‘ê,5Hv&*,–Œgad"j(*g.&*,–ª(C3C2¼4*t Bÿf(5|ux|zNº°4 Bg5|tx|zNº˜4*tB5Bt0<Nuƒ*fÉIÙQËÿü*fÉINu *ÿ[f|[ *ðUg`Æ *ŒgN *[fl *ÿUg*Ua¤ @gT|ðUNu&j@ )f5|hx|zNº|U0<Nu&j@S‹Öü (g  gð`Öü%KD%K@`H"jpN‘B�2*\ÒŒ²ª,bz(A%L02*P Ab^|[%|\|X|W|Y|VBƒ&j@CúšB��BB1ÄüCú(Nñ *WfÖü%K@`Ì2*PA5APB€Nu`Þ`Ö`¶` `†``F``z`"`P`z`Ò``0`f`~``’`ª`Â`Þ`ö `ÿ5|ix|z|{%K~Nº @5|gx|zNº 05|mx|zNº "aÔ&5|P2*LJAf05|L5|Ž Cg5CL5CŽª�Öü%KD%K@`þV2*NJAf 5|N Cg5CNÖü%KH%K@`þ.5|jx|zNº ¢aX2*NJAgA5ANJAgþ.&jH%K@`ýø2*LJAgA5ALJAgþ &jD%K@`ýÖ|ÿU *Œgþ*�f5|hx|zNº 0%jD@5jŽLB@Nu&j<×ü%K@B@NuaÄ|ðV`ý®a¶|ÿV`ý a¨Öü%K@0<|ÿ[NuÖü%K@aˆ`ýFS‹%K@`þhÆü ÖA Cmý\5|kx|zNº ž *Vfþf *[g * [g *[g *[fþJCgþ *ÿXgþ *[gþ|ÿX5C\BC`üö *VfþJCg~ *[f5CPBƒNu *ÿYgR *Xg5C^`5C\Bƒ2*\4*^ *[g$ * [g *[gJAg6JBf` *[g`6JAg"´Al.` C5C`BƒÞü`ü€ *[fŒNu5|kx|zNº ¢5|lx|zNº ’ê� +,g( +)g +/gaÿ* *Vfý8|[`ü aÿBƒ*f5C\|$[ *ŒfJfv`ûä *[gaþä *Vfüò CfüÀÖü Nf|ÿT` Zfü¦|TÖü%K@`ûhê�aþœ|[Öü%K@`ûLê� *[faþx| [Öü%K@`û(5C^|ÿYÖü%K@`ûê�aþF|[Öü%K@`úöê�aþ*|[Öü%K@`úÚê�aþ|[Öü%K@`ú¾ê�aýò|[Öü%K@`ú¢JCg *ÿVfDC5CRBCÖü%K@`ú‚ *VfûÎJCf6<(j0ØÃ¹ê,nû¨%L0Öü%K@`úR *VfûžJCf5|kx|zNº¸(j0"LØÃ¹ê,nûjÖü*fÇICÛQËÿü*fÇI%L0%K@`ùö *[gaý( *Vfû6JCfû(j0Öü"KBƒ 'g ÖüC`ð LÐñê,búø*fÉIJCg CÙQËÿü*fÉIÖü 'f*g¤“Øü%L0`˜%K- @%L0`ùfê�aüš| [Öü%K@`ùJHçÿþCúNñ` `(`.Nºô« @g|Nº¾NºÚë +f5|‚x|zNºz +(g +)g +2g +3g +4f5|x|zNºB*g+ f.5|zx`+ f5|yx| z||Cë%I‚Nº+ gë « « « « « *g« 7| +fª7|I`~ +g( +#g +Zg +[g +_g +df5|€x|zNºrë 7|  +f k f«««`0 +f7|I+ f«+ f ««B@@*fë |` ë ||*gV < *fB€&*,(j(–Œ Cm (ÀCg`ð Cm 8ÀCg`ð8€Lßÿ(j(B@Nu&j« &j*g*(j0 +Zg$ +[g +_g +g, +#g$`äaÊ�ª( €„o"5|gx|zNº,BkNa¦/+ "k`h/+ ë"k 1fAú”'HRH'H `( 0fAú‚'HRH'H ` +g(Aúj'H'H AëNBJkNf¹Éf 'IOï`®'I �«f¼ `JkNgSŒ IS@RHØQÈÿü"_¼ 'I ` JkNfS€'@ Nu kNf °«gSŒ'L AëNBgF*g +Êf||NBg *f +Âgˆ5|„x|z`t|(k%L(%L0*fþ kNf"LÓë$%I,S‰'I `þ6"k Òü%I, +$"�k lþD@HÀ j(ÐÁ< *fBAÁQÈÿü`ýúp`5|†x|zpÞüLßþNuHçÿþCúNñ` `þ`úNº¢ @g5|�x|zNºJ +f5|ƒx|zNº2*g+ f05|zx`+ f 5|yx| z||Cë%I‚Nºò*g> +(g6 +)g. +2g& +3g +4g7|` +fR7|dI`7|d  +f7|dIë*fë+ f«+ f ««|*g$| +g +g +g|| *n5|Šx| z||Cê%I‚Nº'@(j((€*gˆ < *fB€&*,(j(–Œ Cm (ÀCg`ð Cm 8ÀCg`ð8€ Af*g (j( *(€(j( AfØü%L0Lßÿ(j(B@NupÞüLßþ(j(%L0Nu&jAë*ga$J€fNBg5|…x|z`Â*fÿH`€0¼NBJf0¼B€` Ég Âf0¼B€Nu o /Hçÿþ*UEí@$�&j +gfÀ7|,NC7|@,7|.NC|7|(k"LÒü…%I,(ü** F(üORTR8üANü Bƒ:�CúŽ f:�Cú„ÙQËÿü&ƒÿÿÿg"*,’Œ¶Ao6 o CØQËÿüSŒ'L |AëNBg5|Œx|zNº< g|NBfÞLßÿNuNº pAúNAPAUSE STOP Hçÿþ` Hçÿþ*UEí@5@x|zfêzNVÿê.ª0/j(/j,/jb jfjgj[?j\"j$&j ")2²«2g ©PR 2f&I +g *zfè7|,NC7|@,7|.NC(k%L(%L0"LÒü…%I,"L"<„ü QÉÿú(ü** E(üRRORØü%L0|[5|\Cêx%Ib|f|gHçNº øLß4*x”y-ìCú ÌBƒÄü61 Cú¤81 CúÖÒÄ(j0Øüa®Øü*zgBƒ*{"j~a”%L0*zgB|[5|\0* @co5|\Cê%Ib|fHçNº jLߨê\Øü%L0*zg2| [5|\"jCé%Ib|fHçNºªLߨü%L0*zg*| [*|CfÆü5C\"j‚%IbHçNºpLß||7|·ê$fAúÔ'HTH'H AëNB'j(SŒ'L AëNB·ê$f &j +g°7|@,7|.Aë,NCgœ*zgB5|x|z%W0%o(%o,%o bofogo[5o\N^LßÿNuNº :B€B�0*x�üd2áIB@H@�ü éH‚@H@‚@p ANAJCgC¹ê0gÙQËÿöNu d RECURSIVE CALL UNIT NO. OUT OF RANGE END OF RECORD FORMAT CODE MISSING INVALID CHARACTER IN FORMAT NEST OUT OF RANGE IN FORMAT NUMBER OUT OF RANGE IN FORMAT ILLEGAL DESCRIPTORS IN FORMAT ILLEGAL SIGN WITHOUT SCALE FACTOR INVALID DECIMAL CHARACTER INVALID CHARACTER INVALID HEXADECIMAL CHARACTER FIXED OVERFLOW FLOATING OVERFLOW FLOATING UNDERFLOW NOT ENOUGH RECORDS UNFORMATED READ TOO MANY RECORDS UNFORMATED WRITE ASSIGN MISSING INSUFFICIENT MEMORY FOR BUFFER ERROR RETURN ON FHS READ NOT SUPORTED DEVICE WRITE NOT SUPORTED DEVICE BACKSPACE NOT SUPORTED DEVICE REWIND NOT SUPORTED DEVICE ENDFILE NOT SUPORTED DEVICE DIRECT ACCESS NOT SUPORTED SEQUENTIAL ACCESS NOT SUPORTED UNFORMATED NOT SUPORTED ILLEGAL DIRECT WITHOUT OPEN STMT. ALREADY ACCESSED DIRECT ALREADY ACCESSED SEQUENTIAL I/O ERROR AT SEQUENTIAL ACCESS I/O ERROR AT DIRECT ACCESS END OF FILE ALREADY OPENED ILLEGAL RECORD FORMAT RECORD LENGTH OF OPEN STMT GT OF FILE RECORD NUMBER LE 0 NO FORMATTING FILE I/O ERROR AT PAUSE OR STOP ERROR OCCURED AT CLOSE OUT OF RANGE OF ARRAY ELEMENT INSUFFICIENT MEMORY ZERO DIVIDE SOURCE ERROR ILLEGAL LABEL ASSIGNED TO VARIABLE IN ASSIGNED GOTO REAL ZERO DIVIDE DOUBLE PRECISION ZERO DIVIDE INTEGER ZERO DIVIDE REAL POWER BASE=0,EXP=<0 DOUBLE PRECISION POWER BASE=0,EXP=<0 INTEGER POWER BASE. =0,EXP=<0 SQRT ARG.<0 DSQRT ARG.<0 EXP ARG.>=127LOG(2) DEXP ARG.>=1023LOG(2) ALOG ARG.=<0 DLOG ARG.=<0 ALOG10 ARG.=<0 DLOG10 ARG.=<0 SIN ARG.>=10**6 DSIN ARG.>=10**14 COS ARG.>=10**6 DCOS ARG.>=10**14 TAN ARG. TOO LARGE DTAN ARG. TOO LARGE ARSIN ABS ARG.>1 DARSIN ABS ARG.>1 ATAN ABS ARG. TOO LARGE DATAN ABS ARG. TOO LARGE ATAN2(X/Y) ARG.X=Y=0 DATAN2(X/Y) ARG.X=Y=0 ATAN2(X/Y) ARG. Y TOO LARGE DATAN2(X/Y) ARG. Y TOO LARGE &4Hd€ž¼Þø (7I\¡°Ïãü4Ok†¥½ß÷2MYh~¤·Êåü.:G{|}~�­ÁÚÿ'4H^kx‡–¦¸ÈÚí$<Uj€œ¹º»¼½¾¿ÀÁÂÃÄ"#"" & 4%  Hçÿþ&j·üg8|,|-Aë,NCg @gk05|�x|†zNºóÎ&S·êfÀLßÿNu/&j·üf&j8 Ъˆ°ª4nj`€0*°+fDB@ +g0<"j8%I(%I0'I"j4 kNg"j8ÒëN%I,S‰'I %K"Nu&S·êfª"j8 Ъˆ°ª4o5|wx|zNºó("“&‰&I`&‹(KØü"*ˆAüQÉÿú%K%@8jj1|,|€-0<`ÿ\Aë,NCg jxgNuk05|vx|zNºò¸ j (1g Aè1Cë1³gÒ+Lg7|„N|k1k.7kL7kN kNg"kÒëNS‰'I Nu"j4S‰'I NuHçÿþBA*[Cú$1N» LßÿNu0f$Rp®pNVÿð(j0"L-LÿüÒê\-Iÿø-jbÿôB@*f=@ÿò=|ÿð*NNº N^NuNVÿè|ÿè&jb g|ÿÿè(j0-Lÿì:*\=Eÿê*NNº²(j0&LÖê\B@0*^ÖÀÖÇÐGg~ÖêR¹ËbtÐjRJ@lD  gdB€S‹ :m8 @¹Ëb €`âBƒ6*\C&LÖÃCcQËÿú¼1RG`†6*^ÖG&LÖê\ÖÃDƒCü QËÿú0*^ÐGÐjRD@J@oÈ2*^4*\”@n"LÒê\Bƒ6Ckh<0QËÿú`^&LÖÂ"LÒê\Bƒ6´Ao6Ck + ÿÿg#` <0—üQËÿè´Amg$<.6–AC#QËÿü`6–BC<0QËÿú<.&I³Ìc<0&I³Ìc< `ö .ÿÿèf·Ìc<-` 0f ,.f¼-N^Nu6*\Cü*QËÿú`êNVÿä|ÿè&jb g|ÿÿèB�2*`Aÿé *fg|ÿé(j00*\�j^BA.ÿé�A @m¨ØÀ-Lÿì0*^@=@ÿê*NNºÊ(mÿìØíÿê , ÿÿg>$"L :m.$ :m$¹íÿìg¼0`ê(mÿìØíÿê"LSŒRG$¹íÿìfø`¶¼ *[f„JGl~B€0-ÿêD€¾@opBA-ÿéDAÒj\’j^(j0"nÿì6-ÿê¼ 0ÿ�GD€S‰J@g³Ìmô&ƒéQËÿú¼. ) ÿÿf|0ÿÿ .ÿÿèfÄ“ÀS‰³Ìm¾¼-`²0-ÿê�jRÐG;@ÿäCíÿä+Iÿô;|ÿò;|ÿð(j0Øê\+LÿøB€-ÿé™ÀØü+LÿüNºf0-ÿð(mÿüJ@g8B�2A¼+ 4-f¼-¼ @AJAm¼0ÿ@QÉÿð|Dÿÿ *fg|EÿÿBA-ÿéDAÒj\’j^ÒjR(j0 j^g4*RJBnmv¼.ÿ`Ž´j^b"&mÿì·ÌgÔBƒ6C"KS‰ÛQËÿü¼.`r6–j^C8˜jR¸Cm¦&mÿì"K“ÃB…:*^EÛQÍÿü:Eü0QÍÿú¼.`0 Acr¼.ÿCô6DCCü0QËÿú Ac¼0þ .ÿÿèf< Bb Am4gA¼-þ`"´j^b Dm¼-@þ`C¸Cm ¼-@úN^Nu(j06*\Cü*QËÿú`æ*ggNºûNugNºüÜNugNº NuNº"Nu(j0Øê\<F"jbJ‘g<TAÿÿNuB�*[ $f*f5A\(j0&jb2*\Bƒ*f’CgmØÁ`ÖACÛQËÿüNu(j0&jbØê\BC*fÖÃÆü¶j\c6*\JCg CB�# m0QËNuQÉÿàèH`ÜNVÿþ&mÿô6-ÿò| ÿÿ(mÿø Cb&gB�2JAlDA|-ÿÿ`"J�lD�|-ÿÿB€` "+B„B…B†B‡:H@8>HA<" Db Eb Fb* ‡'mB`0ˆü' "a’(*Šü' "a‚*,Œü' "ar,.Žü' B�ab.HA`B‡vJAg‚ü HA0BAHA¹íÿügb0QËÿâJDfBJEf>JFf:JGf6¹íÿøf<0 .-ÿÿf ¹íÿüg0<-™íÿü;LÿðN^Nu$BBH@B@H@Ò‚NuJCkÿ4<0QËÿô`ÿ((mÿüü*¹íÿøföN^NuNVÿÈ"jb € €f4 *fg ") �f "mÿìBƒ6-ÿêCü0QËÿú>-ÿêDGN^Nu *fgH"€ÿÿ�€HAîI4 f4<Bãˆgô€B�vâˆâ‘QËÿúB€éJHBBB€‚`")Cú úB‡$‚ðfAúL/ / //N‘ "><ÿà$‚ðHB€ÿÿ€C0-@ÿè-AÿìB@(HBBƒ-Bÿð-CÿôD?ð:<ÑÉÅHD DnDÞDDDHĉü :HDçDçEAú ~ 0@"0@ Eg Aú ÔÐÅ Dg/ / //N‘ "`" Юÿð€?ðJEgm€`€ €?ðlGAúŠ/ / //N‘ "`( €@$m n �mGAúh/ / //N‘ "Aîÿð/ / //N‘ "$€ÿÿÀ-@ÿø-AÿüBBHBèJB3oB&.ÿüã‹-Cÿü&.ÿøã“-CÿøQÊÿêCîÿø+Iÿô;|ÿòCîÿÈ+IÿüÒü +Iÿø;|ÿð/NºüŽ.G žmÿðžmÿê"mÿüÒíÿð&IB€*fÁü@°mÿêo0-ÿêÖÀZ@S‹ :m2 @³ËbR@€`äBƒ6-ÿêC&IÖÃcQËÿú|1RG&mÿìBƒ6-ÿêB€*fÁü@¶@o60CÙQËÿü°mÿêg$ * [g6-ÿê–@0ÖG¶@bCkü0QËÿúN^NuF“¸µµn@$. ?¹™™™™™šHçÿþBA*[Cú$1N» LßÿNu0üüüN|Ò$ÒNVÿð=|ÿð=|ÿò=|ÿô=|ÿöjfÿ÷-jbÿø&nÿø6¼ .ÿ÷g7| .ÿ÷g'|(j0"LÒê\-Iÿü*NNºb¹íÿüg5|nx|zNºç, mÿôg&5|qx|€zNºç"mÿø2¼ÿ -ÿ÷g"¼ÿÿÿ -ÿÿðf"mÿø -ÿ÷g2DA2�`"D�"�N^NuNVÿè=|ÿè=|ÿê=|ÿî=|ÿð=|ÿò=|ÿô|ÿöjfÿ÷-jbÿø(j0"LÒê\-Iÿü*NNºêN^Nu*ggNºþÖNugNºÿ–NugNº NuNºZNuNVÿü(j0"LÒê\-Iÿü¹îÿüg2  gô ,.ÿÿg ,Tÿÿfr`¹îÿüg  gô ,Tÿÿfr`B�"jb"�N^NuB�*[ $f*f5A\(j0&jb2*\Bƒ*f’CgmØÁ`ÖADAÖÃAü QÉÿú&jbCÜQËÿüNu(j0Øê\&jbB€*fJ@gb@üQÈÿúBƒ6*\B@*fÀü¶@m6JCg<C$ f *ÿTfQËÿîNu 0mT 9c FbH @ÿÿQËNu$ f *ÿTfQËÿîNu 0m 9c Fb éÑ#QËÿ”Nu5|px|z|{Cìÿÿ%I~NºäâB€¹íÿüfNu mÿòf +fSŒNu -fSŒNuSŒ` gÎ +g -f|ÿÿð`SŒ¹íÿüfNu 1m 9b2-ÿòA;Aÿò`( 0g gSŒNu2-ÿòJAgÀ 0gÐ *ÿTg²`Æ4-ÿô Bg B;Bÿô`œ"mÿø6-ÿö Cmb4(ã„ir*å…ilØ…ihØ€id"„`ÿt8ãDiX:åEiRØEiNØ@iJ2„`ÿZ(*)B‚ã�Õ‚ã„i4Ø‚i0,.B‚ã�Õ‚ãJBƒã�Õƒå„iØ‚iÚ‡Ù†iÚ€Ùƒi "„#E`ÿ;|ÿô`ÿ NVÿò=mÿöÿú-mÿøÿüCîÿò+Iÿø;|ÿö-|ÿò-|ÿöNºþ�;mÿôÿê¹íÿüf2-ÿê’j^;Aÿê`: Eg4 Dg. +g( -g" .g� +g¶ -f|ÿÿî`¦2-ÿê’j^;Aÿê`Ð Eg( Dg"5|ox|zNVÿþ@ÿþ|{%O~Nºâܹíÿügº  fØü`ì +gL -f|ÿÿî`> 0m® 9b¨SŒ`.;|ÿòNºý¸2-ÿòA mÿêf’mÿô“mÿê¹íÿüg^`ÿFCíÿè+Iÿø;|ÿö;|ÿè;|ÿò;|ÿôNºýp¹íÿüg5|ox|z|{%L~Nºâ02-ÿè -ÿÿîfDAÓmÿê` 2-ÿê’jR;AÿêCîÿò"<B‚&f6QÉÿø"<$< &)fQÉÿöB€"nÿü"€ nÿúgò#@`ê”�‚ <3�BéHH@ Bg6nD‚B&â‹"ƒ&)â“#CQÊÿî`B&)ã‹#C&ã“"ƒQÊÿî&ƒ€ƒ")B‚4-ÿêH ‚gÀ…ü 6HB BlB C C"nb CÿÞmxÅüÇüCúÐ BgAúÈÐÂ///(/N‘ "JCglAúÐÃ///(/N‘ "$BBHBèJ8< é¨è¨JCmB€ Bÿlø`DB€ BÿËoJBl4ÀDBB„â‰dxâˆdÁQÊÿîB‚Ò„Ñ‚B‚`$BBHBèJ8< é¨è¨ nÿúftBÿB Bÿlš Bÿèo°À8HDHA8HAçˆç‰çŒJBnBDBB„8B‚è¨e`"HA2HAHD0g€gâˆR‚eî€(<骀‚`€(<骀‚"nÿü"€ nÿúg#A -ÿÿðf"nÿüÑN^Nu5|rx <€ nÿúg <ðB�` 5|sxB€B�|€zNºßª`¦=Û|ßÙ×½»>. è&Ö•>EyŽâ0Œ:>z×òš¼¯I>°Æ÷ µí�>äøµˆãhñ?6âëC-?PbMÒñ©ü?„záG®{?¹™™™™™š?ð@$@Y@�@@È@øjA.„€AcÐA—ׄAÍÍeWUÜ/ôGÜk*} IpË èðX’h‹pæ+ ¥nÂøóa ¸ò°a® | Í ¤‘ë’àçÉî¼DSó®5‘õ´âé?]¢‚S¬ ù¹æh/ 䃑˜äBÝMç U aÖ©Áh~’N÷³ |ƒç­No"�™›úXÏ$£R›§Ñžº&¶~œ{n}(Ê/çj?”}*Þ|_{Ø„,ñ¾½õx²ù/¨rŸÃݼ1 �?syö3+ÿ.äŽ45@KÙ„™r7Rø¬Ma$9fé�5ž;y¶ª¬¦&=�îzJÔ¸?¡l&'wWœA´HKþëŸCÇœ¡ ’B#EÛ|ßÙ×½»7ð: _ <¯xµŒ@>)>Y9 Œê@=c)ñÃ\¦BQÅ~dšDcéääÂóDFw.ºÖÝÇ=HŠüïQðû_JŸk )YÇL²I­%”Ã|NÅJ0GÆ”ýPØÈÚÆ 4)RìÚb[-�UËpÒKsxW�5.P–®Y&ÂÔ%oüÁ[:REå¢Î]NØÓNTs_aôޝ#JÓatç××bYcˆU12k»eœT»’ãåg°}Eq$:iÃ24Þz×àkÖXã«yRmêýâÊéoþI@4çžTr üfЬjt$…ΞzWv7ä<ˆu‘xKÐ<�@inz`0…å>Y’|rØÜV¡4~…ðàGs~/2H@S@ØSAgQÈÿøSAü QÉÿú"NuHç@ 2H@€°AlÅHÁAÀSAS@± VÉÿúggÅH °"LßNuS@k"  VÈÿúgLßf Nu< ° NuLßDüNuHçÿNVLî(J€fJ�gÂJ‚fJƒg’(µ„/*.…ÿÿ‡ÿÿB@BBH@HB<<ðÀFÄF°Fgl´FgfJ@fB„Dfã�ã‰dÅD`ê�DÅJBfBDDfã�ã‹dÇD`ê”DÇÔ@/8<ã�ã‰dÅã�ã‹dÇQÌÿê8<HAHC $H@HBÌÀÈÂBFBDHFHDÜ„8ÈÅBDHDÜ„8ÈÇBDHDÜ„B„ÆÀÂÂÖ�dx"ÂÇÖ�d„܃d„ÎÀÊÂÞ…d(<*BEHEHGBGÞ†d„ÀÂЅЄ"� d€BC8<gD6<JDgâ‰âˆdÁSD`î$(/ÔCB?ðc B¿Ðb Bðj,`4DBBèŠ B5jJBg"â‰âˆdÁB`ìB€B�` Y�B� <ð` €HBBB€‚gÀ €€fJ�fB€Hî0N^LßÿP�NÐDCO1(' ***** DC OUTPUT MODULE TEST PROGRAM ****** ',A4)(' ')(' NON-EXISTANT TASK - ',A4)(' OPEN & OUTPUT TO EACH CHANNEL INDIVIDUALLY')(' CALL OPEN - ERROR')(' CALL OUT - ERROR')(' OPEN & OUTPUT TO EACH CHANNEL UNTIL ALL ARE ON')(' CLOSE CHANNELS, OUTPUTS SHOULD TURN OFF')(' TURN ON ALL OUTPUTS, THEN TURN OFF')(' PULSE EACH OUTPUT IN TURN')(' TRY COMMANDS WITH CHANNELS CLOSED')(' CALL CLOSE AND CHANNELS CLOSED--OK')(' CALL CLOSE - ERROR')(' CALL OUT AND CHANNELS CLOSED--OK')(' CALL OUT - ERROR')(' CALL OFF AND CHANNELS CLOSED--OK')(' CALL OFF - ERROR')(' CALL STATUS AND CHANNELS CLOSED-OK')(' CALL ST/ ATUS - ERROR')(' CALL PULSE AND CHANNELS CLOSED--OK')(' CALL PULSE - ERROR')(' TRY CALL OPEN AND ALREADY OPENED')(' CALL OPEN AND CHANNELS ARE OPEN-OK')(' CALL OPEN - ERROR')('********* TEST COMPLETED **********')DCO2DCO2(' STATUS ERROR-BIT ',I1)(ÿÿÿÿZIO 'RIODRV TESTE AFééqqTESTE LFòò qqTESTE SAûûqqTESTRIO AF$$qqTESTRIO LF--qqTESTRIO SA66WqqTESTE LO‡qqTESTRIO LO� qq=/*=/*†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�--=/*}=/*=ENDééééé/ éá=/*=/*†RIODRV.TESTE.LF=/*=/*=/IFC \1ƒ=ARG�RIODRV.TESTE.LL=/ENDIF=/*=LINK ,RIODRV.TESTE.LO,\1;MIXHS SEG SEG0:0 $0INPUT RIODRV.TESTE.ROEND=/*=ENDéééééééêŠOPT„EQU5*This is TESTE the version that tests wait for event. ŠSECTION�0 PBA‡EQU„*TEST†LEA„PBA(PC),A6ŠLEA„STACK-PBA(A6),A7+ŠCLR.L‚EVENTCNT-PBA(A6)ƒclear�event�counter* *‚GET�A.S.Q.1ŠLEA„ASQBLOCK-PBA(A6),A0�stage�command�parametersŠLEA„TESTIRQ-PBA(A6),A1ŠMOVE.L�A1,ASQBLOCK+14-PBA(A6)!ŠMOVE.L�#31,D0‚stage�command�codeŠTRAPƒ#1 ŠBNE„FAULT2*‚OPEN�THE�CHANNELS 3ŠLEA„INITIO-PBA(A6),A0‚point�to�CMR�parameter�blockŠLEA„OPNCMD-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#OPNLNG,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE„FAULT1**** WAIT EQU **‚REQUEST�WAIT�FOR�EVENTŠMOVE.L�#36,D0ŠTRAPƒ#1 ŠBNE„FAULT3**RUNTEST*‚read�status�of�channel‚10**‚stage�code�for�read�commandŠLEA„STATCMD-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)-ŠMOVE.W�#6,CMDL-PBA(A6)„set�up�command�lengthŠMOVE.L�#60,D0�set�up�CMR�callŠTRAPƒ#1 ŠBNE„FAULT7ŠSPC„2*Pulse channel 7ŠLEA„PLS7-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#12,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE„FAULT10ŠSPC�2*Pulse channel 8ŠLEA„PLS8-PBA(A6),A10 éééó7üF  MFŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#12,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE„FAULT11*Pulse channel 9ŠLEA„PLS9-PBA(A6),A1ŠMOVE.L�A1,CMDA-PBA(A6)ŠMOVE.W�#12,CMDL-PBA(A6)ŠMOVE.L�#60,D0ŠTRAPƒ#1 ŠBNE„FAULT12* *Inc EVENTCNTŠADD.L‚#1,EVENTCNT-PBA(A6)**If EVENTCNT = 10 THENŠCMP.L‚#10,EVENTCNT-PBA(A6) ŠBEQ.S‚TEST1*DO*‚disable�channel�1�interupts*‚wait�for�event*END*IF EVENTCNT >= 20 THENŠCMP.L‚#20,EVENTCNT-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Š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éé0 éééé#Š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�INPUTéOPNLNG„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�block�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.1 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�TESTé=/*=/*†RIODRV.TESTRIO.AF=/*,=/*†TESTRIO�test�program�assembly�chain�file=/*6=/*†The�command�line�will�accept�arguments�as�follows:=/*;=/*‹Argument�01…\1�=�Output�file�assembly�listing�or�device=/*H=/*†The�following�shows�the�assembly�chain�sequence.‚In�this�example�theH=/*†NULL�device�was�chosen�as�Argument�01,�however,�the�user�could�if�he5=/*†so�desired�have�requested�an�output�listing�file.=/*"=/*�=CHAIN�RIODRV.TESTRIO.AF�#NULL=/*,=/*†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�--=/*}=/*=ENDééééé=/*=/*†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=/*=END1 ééééé%N*******************************************************************************Ì**Ì**™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'*£UTILIB.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.B7;??GGOIW7_OgCoWwXB"*«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�expresse2 d)*£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Š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ƒ'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_RIO3 ‚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ƒEQU„*-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�n3 umber�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)�Store�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�*4 **Œ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*-----------------------------------------------------------------------------**‚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„PROGSTRTTESTÿÿÿÿÿ€SEG0ÿÿÿÿÿÿ4 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|pACIADRVƒIDNTƒ4,1‡VERSADOS�ACIA�TERMINAL�DRIVER�WITH�TYPE-AHEAD;ŠTTL„ACIADRV:‚VERSADOS�ACIA�TERMINAL�DRIVER�WITH�TYPE-AHEAD ŠLLENƒ120J**************************************************************************J***************************************************************************9*‰ACIADRV:‚VERSAdos�ACIA�terminal�driver�with�type-ahead.*8*‰Purpose:‚VERSAdos�device�driver�to�handle�asynchronous/*�terminals�(of�any�type)�over�the�ACIA�chip�on*�the�following�boards:*’DEBUG�(EXORmacs),…MVME110**‰Revision�history:*8*�12/17/84‚Interrupt�routine�and�RCA�routine�modified�to1*šprevent�the�EDITOR�from�hanging.‚We�must�detect5*šend-of-break�before�checking�the�received�character4*šfor�bit�7�set�(garbage�character�at�end-of-break).6*�11/21/84‚Modified�the�interrupt�routine.‚The�Special0*šReceive�Condition�routine�is�executed�now�only1*šwhen�there�has�been�a�receive�interrupt�and�SRC2*šbits�are�pending.‚This�will�prevent�the�terminal/*šfrom�hanging�when�BREAK�is�pressed�to�log�on.1*�10/23/84‚All�BSR's�to�TERMLIB�now�JSR's�in�case.*šTERMLIB�is�located�more�than�32K�bytes�away.3*‘9/27/84‚Adding�documentation,�INCLUDE�9995�files,"*šusing�TERM_BREAK�in�SRC�routine.,*‘9/25/84‚Removed�XREF�to�BREAK�and�GET_LEN.5*‘9/21/84‚Changed�PASS19.MPSCDRV.SA�to�drive�an�ACIA.3*‘8/30/84‚Fixed�SPR�concerning�SETUP.‚Commented�out(*šthe�code�that�tests�the�modem�bit.‚Now**šif�the�off�hook�bit�is�set,�the�DTR�line&*šis�set�low,‚whether�or�not�the�modem *šbit�is�set.*9*�05/23/84‚Changed�code�that�referenced�the�baud�rate�PIA1*šon�the�EXORmacs�to�be�executed�conditionally�if/*šthe�channel�type�is�a�$66�or�a�$67.‚This�will(*šallow�the�ACIADRV�to�work�on�a�VME110.1*šChanged�the�code�that�reset�the�ACIA�to�get�the!*švalue�for�reset�out�of�the�CDB.0*šChanged�UNSTOP�routine�to�fix�bug�where�a�char(*šis�destroyed�in�the�USE�XOFF/XON�mode.2*šChanged�GET_STAT�routine�to�test�CTS�bit�instead *šof�DCD�bit.*»KEG�05/23/84ª/³X»?ÃFË6Ó>ÛBãNëGóKûJH <7*�08/05/83‚Changed�To�Drive�An�ACIA�instead�of�NEC�7201*šBy�Tom�Angert*7*�10/19/82‚Major�repairs�so�that�interrupts�will�not�be3*šdisabled�so�long�as�to�screw�up�SDLC.‚Revision�1.**‘9/16/82‚Initial�release�by�Steve�Franck.*J**************************************************************************J**************************************************************************‰PAGE****‚XREF's�from�TERMLIB* ‰XREF†LOG_ERR ‰XREF†RESET‰XREF†TERM_INIT‰XREF†TERM_COMMAND‰XREF†TERM_TBE‰XREF†TERM_BREAK‰XREF†TERM_GOT_CHAR%***†XREF†TERM_UNRDYŠNot�used�by�ACIA.$***†XREF†MARK_DOWN‹Not�used�by�ACIA. *?*‚Masks�delineating�all�recognized�(REC)�and�unrecognized�(UNR)(*‚attributes�(ATT)�and�parameters�(PAR).*C*REC_ATTƒEQU„%1000111111111111‚1�bits�represent�defined�attributes.D*UNR_ATTƒEQU„$FFFF-REC_ATT†The�1's�complement�of�that�are�undefined. C*REC_PARƒEQU„%0111111111111111‚1�bits�represent�defined�parameters.D*UNR_PARƒEQU„$FFFF-REC_PAR†The�1's�complement�of�that�are�undefined.***‚Equate�files�included:**‰STR*‰TCB*‰CCB*ˆ9995..BAB.EQ*‰IOE*‰NIO*‰LV5#*‰TERMINAL.EQˆEquates�for�terminals *‰UTILITY.MC:*‰TERMCCB.EQ‰Offsets�and�equates�for�CCBDDP�for�terminals.*ŠPAGE**‚6 ACIA�equates:* CREG†EQU„0 SREG†EQU„CREG DREG†EQU„2,RDRFBITƒEQU„0’Receive�data�register�full�bit.TDREBITƒEQU„1’Transmit�data�register�empty�bit$DCDBIT„EQU„2’Data�Carrier�Detect�bitCTSBIT„EQU„3’Clear�To�Send�bit'OVRNBITƒEQU„5’Received�data�overrun�bit**%*‰SPECIAL�EQUATE�FOR�THE�EXORMACS�PIA*0BAUDPIAƒEQU„$FEE001ŒBaud�rate�PIA�device�address(*£Address�of�PIA�on�EXORmacs�Debug�board#*£to�set�the�baud�rate�for�the�ACIA****‡PAGEŠNOLIST ŠTTL…STR.EQŠINCLUDE�9995.&.STR.EQŠNOLISTŠINCLUDE�9995.&.TCB.EQŠNOLISTŠINCLUDE�9995.&.CCB.EQŠNOLISTŠINCLUDE�9995.&.IOE.EQ‰NOLISTŠINCLUDE�9995.&.NIO.EQŠNOLISTŠINCLUDE�9995.&.LV5.EQ‰NOLIST‰INCLUDEƒ9995.&.BAB.EQŠLISTŠINCLUDE�9995.&.TERMINAL.EQ‰PAGEŠINCLUDE�9995.&.UTILITY.MCŠINCLUDE�9995.&.TERMCCB.EQŠLIST‰OFFSET„TERMDDP */*‚Device�dependent�Background�activation�blocks$*‚None�required�for�the�ACIA�driver.**7�RESERVE.1�XINTENAB‘Value�to�put�in�control�register�to*§enable�transmit�interrupts. 7�RESERVE.1�XINTDISA‘Value�to�put�in�control�register�to*§disable�transmit�interrupts. 0�RESERVE.1�XRTSHI“Value�to�make�RTS�line�go�HIGH <�RESERVE.1�GOTBREAK‘Indicates�that�a�break�has�been�recieved*§and�that�all�errors�shall�be%*§ignored�untill�after�the�next�valid *§character *@*ƒCompute�the�number�of�pages�of�memory�that�we�need�for�one�CCB>*ƒfor�the�MPSC�driver.‚CMR�automatically�allocates�one�page�ofA*ƒmemory�($100�bytes)�for�the�CCB,�and�our�variable�EXTCCBSZ�willB*ƒreside�in�the�CMR�parameter�table�at�the�beginning�of�the�driver8*ƒto�tell�CMR�how�many�extra�pages�of�memory�are�needed.**CCBSIZEB�EQU‡*PAGESIZE�EQU‡$100L1‡SET‡CCBSIZEB+PAGESIZE-1CCBSIZE‚EQU‡L1/PAGESIZEEXTCCBSZ�EQU‡CCBSIZE-1;ŠTTL„ACIADRV:‚VERSADOS�ACIA�TERMINAL�DRIVER�WITH�TYPE-AHEADŠPAGEJ***************************************************************************+*‰SERVICE�VECTOR�TABLE,�REVISION�INFO,�ETC.*@*‰This�table�is�examined�by�CMR�when�the�channel�is�allocated�toC*‰determine�where�to�go�for�interrupts,�commands,�&�initialization.<*‰It�must�always�be�at�the�very�top�of�the�driver�code.‚Also>*‰included�is�a�parameter�telling�the�number�of�extra�pages�of>*‰memory�to�include�in�the�CCB,�and�information�describing�the*‰revision�of�the�driver.*L**************************************************************************** ŠSECTION‚0ŠOPT„BRS ACIADRV: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!*=ŠDC.LƒINTERRUPT-ACIADRV‚Address�of�interrupt�service�routine.9ŠDC.LƒCOMMAND-ACIADRV„Address�of�command�service�routine.5ŠDC.LƒINIT-ACIADRV‡Address�of�initialization�routine.ŠDC.Lƒ0’Reserved. **‚Other�CMR�parameters.*7ŠDC.BƒEXTCCBSZ‹#�of�extra�pages�in�the�CCB.‚The�CCB�may)*§be�any�size�from�1�to�256�pages�(a�page'*§is�256�bytes):‚if�this�field�is�0,�it*§will�be�1�page,�etc.ŠDC.Bƒ0,0,0ŽReserved.ŠDC.Lƒ0,0,0ŽReserved. **‚Revision�info:*/ŠDC.Bƒ'121784'‹Date�of�last�assembly�as�MMDDYY.1ŠDC.Bƒ'�'�Space�indicates�no�patches�to�.LO�file.)ŠDC.Bƒ'4'�Major�VERSAdos�revision�number.*‰PAGE*+*‚Jump�table�for�use�by�the�generic�TERMLIB*‰BRA.L…PUT_CHAR ‰BRA.L…CK_TBE‰BRA.L…DDP_RESET ‰BRA.L…SETUP‰BRA.L…CLOCK_RESET‰BRA.L…GET_STAT‰BRA.L…DDP_STOP‰BRA.L…DDP_UNSTOP‰BRA.L…DDP_BEG_BREAK‰BRA.L…DDP_END_BREAK **‰PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INITIALIZATION�ROUTINE*>*‰This�routine�is�called�by�CMR�when�the�channel�is�allocated.9*‰Its�purpose�is�to�set�up�things�for�command�service�and7*‰interrupt�service.‚The�major�functions�performed�are:"*�Validate�the�channel�type�field.+*�Get�memory�for�transmit�&�receive�queues..*�Initialize�flags,�pointers,�6 etc.�in�the�CCB.*�Initialize�the�ACIA.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.**‰Entry:�A5�=�address�of�CCB.*'*‰Exits�to:‚CMR�(via�RTS)�if�all�is�OK.'*”KILLER�if�exec�won't�allocate�memory.*J**************************************************************************J**************************************************************************J************************************************************************** ŠDS…0 INIT:.‰JSR‡TERM_INIT‹Do�the�device-independent�stuff*%%%%%%%%%%%%%%ƒbwn‚8/13/842‰IFƒƒTHEN…Something�went�wrong�with�TERM_INIT.4‰IFƒƒTHEN„The�exec�call�failed�and�we�cannot�get!*œthe�scheduler's�entry�point�!!!ŽTR0$.KILLER‚,‰ELSE�RTS�The�channel�is�down�!!‰ENDI‰ENDI*?*‚Call�guarded�for�the�device�dependent�initialization�routine.*‰LEA‡DO_INIT(PC),A0‰MOVE.L„#T0GUARD,D0‰TRAP†#0‰RTSŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMAND�SERVICE�ROUTINE*>*‰We�get�entered�here�when�the�attached�task�(IOS)�invokes�CMR?*‰via�a�TRAP�1�with�an�INITIATE�I/O�parameter�block�to�process.>*‰CMR�has�already�checked�the�CMR�parameter�block�to�ensure�it<*‰resides�within�the�address�space�of�the�attached�task.‚IOSA*‰has�already�validated�the�IOCB,�except�for�the�buffer�addresses *‰therein.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.*5*‰Entry:�A2�=�physical�address�of�CMR�parameter�block*�A5�=�physical�address�of�CCB*3*‰Exit:‚D0�=�results�of�parameter�block�validation:3*•always�0�in�our�case,�indicating�it�was�OK,�since2*•IOS�will�not�send�us�any�request�except�HALT�I/O/*•if�we�are�already�busy,�and�CMR�makes�all�the*•other�checks.*A*‰Note:‚TERMLIB�does�not�recognize�CMR�commands�for�HALT�&�RESET.B*‰HALT�can�still�be�accomplished�through�use�of�the�HALT�I/O�IOCB.*J**************************************************************************J**************************************************************************J************************************************************************** COMMAND:‹JSR…TERM_COMMAND‹RTS—return�to�CMR.‹PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INTERRUPT�HANDLING�ROUTINE*<*‰This�routine�completes�I/O�requests�started�by�the�command:*‰service�routine.‚It�is�entered�at�the�interrupt�priority;*‰level�of�interrupts�on�this�channel,�and�is�essentially�a9*‰subroutine�to�the�first�level�interrupt�handler�in�CMR.*:*‰Entry:�D0,A0,A1�have�been�saved�by�CMR�and�are�available*�A5�=�address�of�CCB*9*‰Exit�is�always�via�RTS,�which�takes�us�back�to�CMR.‚The3*�carry�bit�is�examined�by�CMR�to�determine�whether7*�the�driver�handled�the�interrupt�or�whether�it�should4*�pass�the�interrupt�on�to�the�next�guy�in�the�chain*�on�that�vector:*��=�'I�handled�it'**‰Stack:*�(A7)+4�.�.�.*�(A7)ƒlongword�return�address*J**************************************************************************J**************************************************************************J************************************************************************** INTERRUPT:0‰MOVE.L„CCBCHB(A5),A1‡STATUS/CONTROL�REG�ADDRESS$‰MOVE.B„SREG(A1),D0‰GET�COPY�OF�SREG‰IF��THEN.S�IF�NO�INTERRUPT‹AND…#$FFFE,SR‹CLEAR�CARRY‹RTS‰ENDI ‰PUSH.L„D1’SAVE�D1 (‰BTST†#RDRFBIT,D0‰Test�Receive�reg�full.*‰BNE.S…RCA‘Branc7 h�if�received�a�character. +‰BTST†#OVRNBIT,D0‰Test�for�receive�overrun.‰BNE.S…SRC‘Branch�if�overrun. )‰BTST†#DCDBIT,D0ŠTest�for�DCD�transition.&‰BNE.S…SRC‘Branch�if�DCD�(don't�care). -‰BTST†#TDREBIT,D0‰Test�transmit�buffer�empty.%‰BNE.S…TBE‘Branch�if�buffer�is�empty. +‰BRA.S…INT_EXITŒShould�not�get�here�anyway.ŠPAGEJ***************************************************************************)*‰TRANSMIT�BUFFER�EMPTY�INTERRUPT�HANDLER*=*‰The�ACIA's�transmit�buffer�just�became�empty,�so�if�we�have+*‰more�characters�to�send�we�can�do�it�now.**‰Entry:�A0�=�NOT�USED*�A1�=�address�of�ACIA*�A5�=�address�of�CCB*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** TBE:5ŠMOVE.B�XINTDISA(A5),CREG(A1)ƒDISABLE�XMIT�INTERRUPTS *%%%%%%%%%%ƒBWN‚9/17/84*F*‚Call�the�device-independent�routine�that�deals�with�transparent�mode)*‚or�invokes�the�XMIT�background�routine.* ‰JSR‡TERM_TBE ‰BRA‡INT_EXITŠPAGEJ***************************************************************************(*‰RECEIVED�CHARACTER�AVAILABLE�INTERRUPT*=*‰The�ACIA�has�just�received�a�character,�and�it�is�available=*‰for�reading.‚We�will�do�that�now,�and�the�result�will�go�in$*‰the�receive�queue�if�there's�room.**‰Entry:�A0�=�NOT�USED*�A1�=�address�of�ACIA*�A5�=�address�of�CCB*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** RCA:.‰MOVEQ…#$74,D1‰Test�PARITY,FRAMING,OVERRUN�and‰AND.B…D0,D1‹DCD�errors.&‰BNE.S…SRC�Branch�if�one�of�the�above. 8‰MOVE.B�DREG(A1),D0ˆGet�the�char�from�the�ACIA�and�reset ‰TST.B…GOTBREAK(A5) ‰IF��THEN/‹SFˆGOTBREAK(A5)„Clear�error�on�last�char�flag./‹TST.B…D0ŽIs�this�garbage�char�at�end-of-break? ‹BLT‡INT_EXIT‰ENDI *%%%%%%%%%%%%‚BWN�9/17/84*C*‚Call�the�device�independent�routine�to�check�for�transparent�modeG*‚and�do�the�stuff�for�transparent�mode�or�if�not�in�tranparent�mode�toG*‚check�for�any�special�characters�such�as�XON,�XOFF,�BREAK�EQUIVALENT,G*‚or�DISCARD�OUTPUT.�Otherwise,�put�the�character�in�the�receive�queue.*‰JSR‡TERM_GOT_CHAR ‰BRA‡INT_EXITŠPAGEJ***************************************************************************%*‰SPECIAL�RECEIVE�CONDITION�INTERRUPT*:*‰The�ACIA�detected�an�error�in�the�process�of�receiving�a<*‰character.‚We�need�to�record�this�information�so�that�when<*‰the�corresponding�data�is�requested�from�the�receive�queue*‰we�can�report�an�error.**‰Entry:�A0�=�NOT�USED*�A1�=�address�of�ACIA*�A5�=�address�of�CCB*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*J************************************************************************** #SRC:†EQU„*’A1�<--�addr�of�our�ACIA."*£D0�<--�our�ACIA�status�register.'‰MOVE.B‚DREG(A1),D1ˆD1�CONTENTS�OF�DREG0‰TST.BƒGOTBREAK(A5)‡TEST�ERROR�ON�LAST�CHAR�FLAG ‰BNE…INT_EXIT ‰BTST†#4,D0"‰IF��THEN.S�TEST�FRAMING�ERROR‹ST…GOTBREAK(A5)†SET�ERROR�FLAG3‹JSR„TERM_BREAKˆCall�the�device�independent�routine*£to�take�care�of�a�break. ‹BRA„INT_EXIT‰ENDI—* ‰BTSTƒ#6,D0ŽTEST�PARITY�ERROR‰IF��THEN.S1‹PUT_BYTE�PAR_FRAM,D0„Log�a�parity/framing�error;‹JSR„LOG_ERRŠ* ‹BRA„INT_EXIT*¢else�(not�parity�or�framing)‰ELSE.S‰BTST†#5,D0‹TEST�OVERRUN�ERROR‰IF��THEN.S*‹PUT_BYTE�OVERRUN,D0…Log�an�overrun�error.‹JSR„LOG_ERRŠ* ‹BRA„INT_EXIT‰ENDI–*‰ENDI2‰BRA„INT_EXIT‹Exit.�MUST�HAVE�BEEN�DCD.�DONT�CARE.‰NOP‰PAGE*E*‚Now�exit�as�from�an�interrupt.‚We�may�in�fact�have�been�called�fromF*‚command�service�or�initialization,�but�they�had�to�set�it�up�to�look*‚like�an�interrupt,�too.*INT_EXIT:�POP.L‚D1‘Restore�D1,7ŠMOVEQ‚#1,D0Žset�carry�bit�to�tell�CMR�'we�handled�i7 t,' ŠSUBQƒ#2,D0Ž*ŠRTS—and�return.ŠPAGEO********************************************************************************2*‰ROUTINES�TO�SET�THE�CLOCK�DIVISOR�TO�x16�AND�x64*7*‰No�work�here�since�ACIA�cannot�set�the�clock�divisor.*=*‰We�must�have�a�CLOCKRESET�entry�point�for�TERMLIB,�however.**‰Entry:*‹A1ƒ=*‹A5ƒ=�addr�of�our�CCB.**‰Exit:*O******************************************************************************* CLOCK_RESET:ŠRTSŠPAGEK*****************************************************************************!*�R�O�U�T�I�N�E�S„C�A�L�L�E�D„B�Y**–T�E�R�M�L�I�B**F**********************************************************************‰PAGEL******************************************************************************ˆTRANSMIT�THE�CHARACTER*?*ˆThis�is�the�device�dependent�routine�that�actually�writes�the*ˆcharacter�to�the�device.*F*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning�of�the *ˆdriver.**ˆEntry:„A1�=�address�of�ACIA*’A5�=�address�of�CCB*’D0.B�=�character�to�transmit*ˆInterrupt�level�on�entry:�0*C*ˆExit:…All�registers�are�preserved,�including�the�status�register.<*’It�is�important�to�keep�the�interrupt�level�the�same�as�it*’was�upon�entry.*J************************************************************************** PUT_CHAR:‰PUSHƒSR‰INHIBIT1‰MOVE.B�D0,DREG(A1)ˆOtherwise,�transmit�the�char./‰MOVE.B�XINTENAB(A5),CREG(A1)‚ENABLE�XMIT�INTS.‰POP„SR‰RTS‰PAGEM******************************************************************************$*ˆCHECK�THE�DEVICE'S�TRANSMIT�BUFFER*F*ˆThis�is�a�device�dependent�routine�whose�offset�must�be�installed�at*ˆthe�beginning�of�the�driver.**ˆEntry:�A1�=�address�of�ACIA*�A5�=�address�of�CCB*ˆInterrupt�level�on�entry:�0**ˆExit:‚Condition�codes:"*��=�transmit�buffer�not�empty*��=�transmit�buffer�empty<*ˆIt�is�important�to�keep�the�interrupt�level�the�same�as�it*ˆwas�upon�entry.*M*****************************************************************************CK_TBE:A‰BTST.B�#TDREBIT,SREG(A1)‚If�ACIA's�transmit�buffer�is�not�empty,‰RTS‰PAGEH************************************************************************* *ˆDEVICE�DEPENDENT�RESET�ROUTINE*9*ˆThis�is�the�device-dependent�part�of�the�reset�routine.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:�A5�=�addr�of�CCB*ˆInterrupt�level�on�entry:�0*$*ˆExit:‚All�registers�are�preserved.<*ˆIt�is�important�to�keep�the�interrupt�level�the�same�as�it*ˆwas�upon�entry.*E********************************************************************* DDP_RESET:*A*‚ACIA�did�not�have�any�device�dependent�reset�stuff�in�the�RESET:*‚routine,�which�is�where�this�stuff�would�have�come�from.* ŠRTS—exit.ŠPAGEJ***************************************************************************@*‰SUBROUTINE�TO�SET�UP�THE�DEVICE�ACCORDING�TO�THE�CONFIGURATION*;*‰Uses�the�working�configuration�(in�the�CCB)�to�set�up�the;*‰device,�and�some�configuration-related�fields�in�the�CCB.*?*‰The�offset�to�this�routine�must�be�installed�at�the�beginning*‰of�the�driver.**‰Entry:�A5�=�address�of�CCB*‰Interrupt�level�on�entry:�0*$*‰Exit:‚All�registers�are�preserved.<*‰It�is�important�to�keep�the�interrupt�level�the�same�as�it*‰was�upon�entry.*J************************************************************************** SETUP:<ŠMOVEM.L�D0-D1/A0-A3,-(A7)�Save�some�registers�on�the�stack. ŠPUSHƒSR **‚First�set�up�addresses.*4ŠLEA„CONFIG(A5),A0†A0�<--�addr�of�CCB�configuration.3ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�ACIA�port.**‚[4]„x16�clock�rate,(*‰stop�bits�&�parity�from�configuration.*)ŠMOVE.Bƒ#1,D0ŒStart�with�x16�clock�in�D0. )‰BTSTWƒ#IOABITS,IOSATW(A0)ƒTEST�BITS/CHAR‰IF��THEN.S�IF�8�THEN‹OR.Bƒ#$10,D0Œ(8�bits/char)>‹BTSTW‚#IOAUSEP,IOSATW(A0)�If�we'r8 e�using�parity,�enable�it... ‹IF…�THEN �OR.Bƒ#$08,D09�BTSTW‚#IOAPRTY,IOSATW(A0)�and�if�we're�using�odd�parity,�IF…�THENŠset�it�up. �OR.Bƒ#$04,D0�ENDI‹ELSE.S•8�BITS�NO�PARITY)�BTSTW‚#IOASTPB,IOSATW(A0)ƒTEST�STOP�BITS�IF��THEN.S�IF�1�THEN �OR.Wƒ#$04,D0�ENDI‹ENDI‰ELSE.S˜ELSE�7�THEN)‹BTSTW„#IOASTPB,IOSATW(A0)„TEST�STOP�BITS‹IF��THEN.S�OR.Wƒ#$08,D0�IF�1‹ENDI&‹BTSTW„#IOAPRTY,IOSATW(A0)ƒTEST�PARITY‹IF��THEN.S‘IF�ODD�THEN �OR.W„#$04,D0‹ENDI‰ENDI "*§Transmitter�int�disabled�DTR�low /ŠOR.B…#$80,D0ŽRecieve,Overrun,DCD‚Int's�Enabled‰INHIBITŠMOVE.BƒD0,(A1)‰POP‡SR9ŠMOVE.BƒD0,XINTDISA(A5)†SAVE�CONT�REG�(XMIT�INT�DISABLED) ŠOR.B…#$20,D08ŠMOVE.BƒD0,XINTENAB(A5)…SAVE�CONT�REG�(XMIT�INT�ENABLED):ŠAND.B„#%10011111,D0„Clear�bits�5�and�6�for�setting�up�RTS*ŠOR.B…#%01000000,D0„Set�RTS�bit�for�a�HIGHŠMOVE.BƒD0,XRTSHI(A5)**‚Set�up�baud�rate*G‰IF.B�CCBTYPE(A5)��#$66�OR.B�CCBTYPE(A5)��#$67�THEN.S�KG�052384.‹MOVE.B„IOSBRT(A0),D0‡The�configured�baud�rate‹PUT_BYTE‚$F0,D1ŽMask!‹BTST†#0,CCBTYPE(A5)†A�side�port?‹IF��THEN.S �LSL.B…#4,D0�PUT_BYTE‚$0F,D1‹ENDI2‹AND.B…D1,BAUDPIA…Clear�old�baud�rate…KEG�05/23/842‹OR.B†D0,BAUDPIA…Insert�new�baud�rate„KEG�05/23/84‰ENDI **‚Restore�registers�and�return.*8ŠMOVEM.L�(A7)+,D0-D1/A0-A3�Restore�registers�from�stack.ŠRTSŠPAGEJ****************************************************************************‰GET�DEVICE�STATUS�BYTE*"*‰Prepares�the�DEVICE�STATUS�byte.*8*‰Note:‚this�routine�does�not�set�the�break�indicator�in*�the�device�status�byte.*?*‰The�offset�to�this�routine�must�be�installed�at�the�beginning*‰of�the�driver.**‰Entry:�A5�=�address�of�CCB*‰Interrupt�level�on�entry:�0*&*‰Exit:‚D0.B�=�the�device�status�byte.<*‰It�is�important�to�keep�the�interrupt�level�the�same�as�it*‰was�upon�entry.*J************************************************************************** GET_STAT: ŠCLR.B‚D0 ŠPUSH.L�A0ŠMOVE.LƒCCBCHB(A5),A00ŠBTST…#CTSBIT,SREG(A0)„TEST�CTS�BITŒKEG�05/23/84ŠIF��THEN.S'ŒBSETƒ#XDSNRB,D0ŠDATA�SET�NOT�READY�BITŠENDI ŠPOP.L‚A0 ŠRTS—Return.ŠPAGEM******************************************************************************5*ˆDEVICE�DEPENDENT�STUFF�FOR�LOWERING�A�HARDWARE�LINE*ˆTO�STOP�THE�TRANSMITTER.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�address�of�ACIA*�A5�=�address�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*K*************************************************************************** DDP_STOP:DŠMOVE.B�XRTSHI(A5),CREG(A1)�Make�RTS�go�HIGH�to�stop�the�transmitter*¤KEG�05/23/84ŠRTS‰PAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�UNSTOP�THE�DEVICE*=*ˆWhen�we�are�not�using�XOFF/XON,�we�unstop�the�device�in�our*ˆown�device�dependent�way.*;*ˆWe�are�running�in�background�when�this�routine�is�called.*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�address�of�ACIA*�A5�=�address�of�the�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*J************************************************************************** DDP_UNSTOP:CŠMOVE.B�XINTENAB(A5),CREG(A1)�Make�RTS�go�LOW�to�enable�transmitter*¦KEG�05/23/84ŠRTSŠPAGEK****************************************************************************&*ˆDEVICE�DEPENDENT�BEGIN�BREAK�ROUTINE*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�addr�of�ACIA*�A5�=�addr�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*E********************************************************************* DDP_BEG_BR8 EAK:‰SAVEƒD08‰MOVE.B�XINTDISA(A5),D0„D0�<--�image�of�ACIA�CONTROL�REG,‰OR.Bƒ#$60,D0ŒAdd�bits�to�send�break�signal.‰MOVE.B�D0,CREG(A1)ˆ* ‰RESTORE�D0‰RTS‰PAGEK****************************************************************************$*ˆDEVICE�DEPENDENT�END�BREAK�ROUTINE*?*ˆThe�offset�to�this�routine�must�be�installed�at�the�beginning*ˆof�the�driver.**ˆEntry:‚A1�=�addr�of�ACIA*�A5�=�addr�of�CCB3*ˆInterrupt�level�on�entry:�INHIBITED�at�our�level.*$*ˆExit:ƒAll�registers�are�preserved.*L**************************************************************************** DDP_END_BREAK:.‰MOVE.B‚XINTENAB(A5),CREG(A1)ƒENABLE�XMIT�INT.‰RTS‰PAGEI***************************************************************************“B�A�C�K�G�R�O�U�N�D**šAND**‘C�A�L�L�__�G�U�A�R�D�E�D**–R�O�U�T�I�N�E�S**•(DEVICE-DEPENDENT)*E*********************************************************************ŠPAGEO*********************************************************************************‰FINISH�OFF�THE�INITIALIZATION*A*‰The�initialization�routine�has�gone�around�resetting�everything@*‰it�can,�but�the�routines�RESET�and�SETUP�should�only�be�called>*‰from�within�the�background.‚So�he�invoked�this�routine�to�do *‰it�for�him.**‰Entry:*�A5�=�address�of�CCB.*O******************************************************************************* DO_INIT:**‚Inhibit�interrupts*‰PUSH†SR‰INHIBIT*)*‚Get�address�of�start�of�driver�into�CCB*‰LEA‡ACIADRV(PC),A4‰MOVE.L„A4,DRV_ADDR(A5)*0*‚Now�actually�do�the�minimum�setup�on�the�ACIA.*.ŠMOVE.L�CCBCHB(A5),A1†A1�<--�addr�of�our�ACIA.4ŠMOVE.B�CCBRESV(A5),CREG(A1)�Reset�our�ACIA�channel. ŠJSR„RESETŽReset�everything.ŠBSR.L‚DDP_RESET5ŠBSR.L‚SETUPŽSet�up�the�ACIA�according�to�the�config.**‚Enable�interrupts�now.*‰POP‡SR‰RTS‰PAGE*********************** *‚PATCH�SPACE***********************ŠDS.Wƒ30ŠEND  ééé-‰PAGEš#######################################‰TTL‡COMMAND�HANDLER *ƒFor�changes�see: *ˆRESETCNT:*ˆL0650*œK.�E.ROEHRMAN„10/20/83*œRWMŽ11/17/83 *œPJDŽ9/18/84*C*ˆ11/7/84‚Added�a�subroutine�CHK_FLOPPY�and�some�code�to�check�that7*‘sectors�per�track,�bytes�per�sector,�and�data�density8*‘values�were�consistent�for�either�a�5�1/4"�floppy�or�a+*‘8"�floppy.‚If�not,�return�error�code�$47.*<*ˆ2/18/85‚Added�code�to�limit�precompensation�value�for�RWIN**‘disk�controller�to�$FF.‚See�label�CD030.*=*ˆ2/25/85‚Added�code�to�use�cylinders-media�for�all�hard�diskéé9 ééé -$7,94:<3D<L6T4\=d1l6t:|<„9Œ5”2œ;¤:¬2´6¼6Ä1Ì3Ô0Ü5ä3ì.ô6ü"*‘configurations.‚See�label�CD010.*O*******************************************************************************O********************************************************************************1*ˆSERVICE�VECTOR�TABLE,�PARAMETERS,�REVISION�INFO*@*ˆThe�first‚several‚locations�of�every‚I/O�driver�must�contain�aB*ˆservice�vector�table�to�contain�the‚long-word�relative�addressesB*ˆof�the�three�driver�subroutines�that�CMR�uses.‚The�CMR�parameterC*ˆtable�immediately�follows�the�service�vector�table�and�includes�aA*ˆfield�telling‚CMR‚how�many�extra�pages‚to�allocate�for�the�CCB.E*ˆThe�revision�table�immediately�follows�the�the�CMR�parameter�table.*O*******************************************************************************O******************************************************************************* '‰SECTION‚8–Section�8�is�is�a�relatively)*¦arbitrary�section�to�use,�but�it�is�the&*¦section�where�the�system�expects�(by%*¦default)�to�see�code�for�a�program. * SERVICE VECTOR TABLE * >SERVECT‚DC.L…INTERUPT-SERVECT‡This�entry�in�the�service�vector(*¦table�contains�the�relative�address�of&*¦the�SASI�driver's�interrupt�handler.(*¦The�interrupt�handler�receives�control&*¦from�CMR�when�CMR�wishes�to�poll�the'*¦SASI�driver�to�see�if�the�SASI�driver(*¦wants�to�handle�the�current�interrupt.'*¦Please�notice�that�the�label�INTERUPT&*¦is�intentionally�misspelled�to�limit*¦the�length�of�the�label. 7‰DC.L…COMMANDS-SERVECT‡This�entry�in�the�service�vector(*¦table�contains�the�relative�address�of&*¦the�SASI�driver's�command�processor.&*¦CMR�calls�the�command�processor�when&*¦CMR�has�a�command�to�initiate�an�I/O *¦transaction�on�a�SASI�channel. 6‰DC.L…INITIAL-SERVECTˆThis�entry�in�the�service�vector(*¦table�contains�the�relative�address�of'*¦the�SASI�driver's�initialization�sub-'*¦routine.‚CMR�calls�the�initialization'*¦subroutine�at�channel�allocation�time)*¦to�give�the�driver�a�chance�to�allocate(*¦memory�for�variables�and/or�to�do�any-'*¦thing�that�is�necessary�to�initialize(*¦the�channel�and�the�channel�device(s). 7‰DC.L…RESERVED-SERVECT‡This�entry�in�the�service�vector:RESERVED�EQU†SERVECTŽtable�is�not�used,�but�it�is�reserved'*¦for�future�expansion.‚Any�future�code(*¦that�is�created�to�use�this�entry�will(*¦recognize�zero�as�value�that�indicates)*¦that�the�entry�is�empty,�so�we�code�the*¦value�zero�here�for�now.-‰PAGEš####################################### * CMR PARAMETER TABLE * 2‰DC.B…EXTCCBSZ�This�field�tells�CMR�how�many�extra&*¦page(s),�if�any,�to�allocate�for�the%*¦CCB�for�this�I/O�driver.‚CMR�always(*¦allocates�one�more�than�this�number�of'*¦page(s)�because�one�page�of�memory�is&*¦required�for�the�universally-defined'*¦CCB�variables.‚The�additional�page(s)&*¦that�are�specified�by�this�field�are'*¦used�exclusively�for�devic9 e-dependent$*¦variables�that�are�required�by�the*¦device�driver. 0‰DC.B…0,0,0’These�fields�are�reserved�for�future.‰DC.L…0,0,0�extensions.‚We�provide�zero�values%*¦here�because�any�extensions�that�we(*¦implement�in�the�future�will�interpret%*¦zero�as�an�innocuous�default�value. * REVISION TABLE * 0‰DC.B…'02'�MM„This�portion�of�the�revision�table3‰DC.B…'25'�DD‚contains�the�date�on�which�the�driver3‰DC.B…'85'�YY‚was�assembled�for�a�release.‚The�data)*¦is�given�as�MMDDYY�with�two�digits�each'*¦for�the�month,�the�day,�and�the�year. .‰DC.B…'�'”This�byte�contains�an�ASCII�blank�to%*¦indicate�that�the�driver's�.LO�file*¦doesn't�contain�any�patches. .‰DC.B…'4'”This�byte�contains�an�ASCII�digit�to&*¦indicate�the�major�VERSAdos�revision(*¦number�under�which�this�version�of�the*¦driver�was�first�released. -‰PAGEš#######################################O*******************************************************************************O*********************************************************************************ˆINITIALIZATION�ROUTINE*B*ˆThis‚subroutine�is�called�from�CMR‚when�CMR�is�invoked�by�a�taskB*ˆ(normally�IOI)�to‚allocate�a�channel.‚Its�purpose�is�to�give�theD*ˆdriver�a�chance�to�set�up�things�for�command�service�and�interrupt-*ˆservice.‚The�basic�functions�performed�are:* *’Initialize�internal�variables.-*’Reset�and�test�SASI�controller�(SASI�only).-*’Read�status�of�self-test�(WINCHESTER�only).!*’Test�of�FIFO�(WINCHESTER�only).*B*ˆThis�subroutine�is�entered�through�a�JSR�from�CMR,�and�will�exit7*ˆwith�an�RTS.‚The�processor�is�in�the�supervisor�mode.*%*ˆEntry:„A6�=�physical�address�of�TCB*’A5�=�physical�address�of�CCB*!*ˆRegister�usage:ˆ0�1�2�3�4�5�6�7 *œD‚*�*�* *œA‚*…*�*�P�P**ˆExits�to:�CMR�via�RTS*O*******************************************************************************O******************************************************************************* INITIAL: 7‰LEA†SASIIDLE(PC),A0ˆInitialize�the�interrupt�handler's?‰MOVE.LƒA0,INTSWTCH(A5)†co-routine�switch�to�point�to�the�SASI-'*¦IDLE�routine�so�we'll�be�protected�in&*¦case�the�SASI�controller�erroneously'*¦generates�a�spurious�interrupt�before%*¦we've�ever�given�the�controller�any"*¦commands.‚This�step�isn't�really'*¦necessary,�but�it�gives�us�some�extra)*¦protection�against�an�error�that�should*¦never�occur. ‰NOLIST*‰IFNE…0–Omit�the�following�code.‚It�is�now"*¦obsolete�but�is�worth�saving�for*¦reference�purposes. 7‰MOVE.Wƒ#EXTCCBSZ,A0‹Ask�the�executive�to�allocate�some6‰MOVE.Lƒ#T0PAGAL,D0Šmemory�that�we�can�use�for�device--‰BSR.S„EXECREQŽrelated�variables.‚We�must�use)*¦dynamically-allocated�memory�for�all�of'*¦our�variables�so�we�can�code�the�SASI#*¦driver�as�a�re-entrant,�position-#*¦independent�routine.‚A0�tells�the$*¦executive�how�many�pages�(with�256(*¦bytes�per�page)�we�want,�and�A6�points)*¦to�the�TCB�for�the�task�that's�allocat-"*¦ing�the�channel.‚Notice�that�the(*¦MOVE.W�instruction�here�clears�the�top'*¦half�of�A0,�so�the�MOVE.W�instruction&*¦effectively�does�the�job�of�a�longer *¦and�slower�MOVE.L�instruction. '*¨The�executive�returns�control�with�A0(*¦containing�the�physical�address�of�the'*¦newly-allocated�memory,�and�registers"*¦D0,�D1,�D2,�and�A2�have�all�been *¦destroyed. 6‰MOVE.LƒA0,EXTCCB(A5)ŠSave�the�physical�address�of�the&*¦newly-allocated�memory�by�putting�it#*¦into�the�CCB.‚The�newly-allocated *¦memory�is�effectively�a�linked)*¦extension�of�the�CCB,�so�we�refer�to�it*¦as�the�extended�CCB�area. ‰ENDC‰LIST-‰PAGEš####################################### #‰IFNE…DTYPE�Assemble�if�Winchester.WINCHECK8‰MOVE.LƒCCBCHB(A5),A0ˆA0�<=�channel's�memory�mapped�I/O.;‰BTST…#BITCB,FLAGS(A0)…Test�the�read�register�for�not�busy.5‰BEQ.S„FIPASS�Don't�reset�or�test�buffer�if�not�busy.+‰MOVE.Bƒ#0,WDCRST(A0)ˆReset�the�controller.CWINI10ƒBTST…#BITCB,FLAGS(A0)…Poll�the�read�register�for�not�: busy...,‰BNE†WINI10�...to�indicate�end�of�self-test.1‰BTST…#BITFAULT,FLAGS(A0)‚Test�the�pass/fail�bit.!‰BEQ.S„WINI20�Continue�if�passed..‰SNE.B„SASIDOWN(A5)‰Set�the�channel�down�flag.‰RTS›Return�to�CMR.WINI20 ‰MOVE.W„#4095,D1Œ4K�buffer.AFIWRITE‚MOVE.B„D1,DATA0(A0)ˆMove�data�byte�by�byte�to�the�buffer.‰DBRA†D1,FIWRITEŠ*‰MOVE.W„#4095,D1ŒRestart.BFIREADƒCMP.B…DATA0(A0),D1ˆCompare�data�byte�by�byte�in�the�buffer.&‰BNE.S…FIERROR�Branch�upon�error�only.‰DBRA†D1,FIREAD‹*‰BRA.S…FIPASSŽDone�if�passed.5FIERROR‚SNE.B…SASIDOWN(A5)ˆSet�the�channel�down�flag.‰RTS›Return�to�CMRFIPASS‰ENDC -‰PAGEš#######################################9‰LEA†CCBZERO(A5),A0‰Clear�all�of�the�device-dependent�CCB=‰MOVEQWƒ(CCBZSIZE/4)-1,D0„variables�that�must�be�backgrounded(*¦with�zeros�at�channel-allocation�time.4L0100„CLR.L„(A0)+�We�clear�two�words�at�a�time�until/‰DBRA…D0,L0100�we've�cleared�all�of�the�device-&*¦dependent�variables�that�lie�between$*¦CCBZERO�and�the�end�of�the�CCB.‚We)*¦improve�our�execution�speed�somewhat�by)*¦clearing�two�words�at�a�time�instead�of&*¦clearing�one�word�at�a�time.‚We�take)*¦steps�elsewhere�to�ensure�that�CCBZSIZE(*¦is�a�multiple�of�4�and�that�CCBZERO�is*¦on�a�long-word�boundary. &*¨Control�now�falls�directly�into�sub-)*¦routine�RESETCNT,�which�resets�both�the)*¦SA1403D�SASI�controller�and�the�MVME420%*¦SASI�Peripheral�Adapter.‚Subroutine(*¦RESETCNT�also�tests�the�MVME420�to�see%*¦if�it�is�functional.‚If�the�MVME420$*¦isn't�fully�functional,�subroutine)*¦RESETCNT�illuminates�the�MVME420's�fail)*¦LED�and�sets�the�variable�SASIDOWN�non-(*¦zero�to�indicate�that�the�SASI�channel *¦is�down. %*¨Subroutine�RESETCNT�assumes�that�A5'*¦points�to�the�CCB,�and�the�subroutine*¦destroys�A3,�A4,�and�D0. !*¨Control�returns�from�subroutine'*¦RESETCNT�directly�to�the�routine�that'*¦called�subroutine�INITIAL,�so�subrou-'*¦tine�RESETCNT�is�effectively�just�the*¦tail�of�subroutine�INITIAL.‹{/‰NOLIST˜#######################################*‰IFNE…0–Omit�the�following�code.‚It�is�now"*¦obsolete�but�is�worth�saving�for*¦reference�purposes.-‰PAGEš#######################################:‰LEA†POLLSTAT(PC),A0ˆAsk�the�executive�to�start�activating9POLLTIME�EQU†1500‘the�POLLSTAT�routine�on�a�regular�basis6‰MOVEIAƒPOLLTIME,A1Šat�intervals�of�1,500�milliseconds8ACTIVATE�EQU†0<<15�starting�1,500�milliseconds�from�now.6REPEATƒEQU†1<<14�The�REPEAT�flag�says�that�we�want�the7LEVEL1ƒEQU†1<<0‘activation�to�be�repeated�over�and�over?L0010„EQU†REPEAT+LEVEL1ˆinstead�of�occurring�just�once,�and�the@‰MOVEQWƒACTIVATE+L0010,D1„LEVEL1�parameter�says�that�the�routine5‰MOVE.LƒA5,D2�should�always�be�activated�by�an�inter-8‰MOVE.Lƒ#T0RQPA,D0‹rupt�that�occurs�at�priority�level�1.%*¦The�CCB�address�that�we�put�into�D2'*¦here�will�appear�in�D1�every�time�the'*¦POLLSTAT�routine�is�activated,�so�the&*¦POLLSTAT�routine�will�have�a�link�to%*¦the�critical�data�structure�that�it*¦needs. #*¨The�MOVEIA�macro�that�we�use�here)*¦generates�the�shortest�instruction�that'*¦will�put�the�immediate�value�POLLTIME%*¦into�A1.‚Since�POLLTIME�fits�into�a#*¦single�word�as�a�two's-complement)*¦value,�the�MOVEIA�macro�will�generate�a%*¦MOVE.W�instruction�knowing�that�the'*¦sign�extension�at�execution�time�will&*¦set�the�top�half�of�A1�properly.‚The&*¦MOVEIA�macro�is�general,�and�it�will(*¦work�correctly�for�any�immediate�value*¦that�we�happen�to�use. $*¨The�POLLSTAT�routine�will�poll�the&*¦on-line/off-line�status�of�each�disc$*¦drive�that�has�been�activated,�and(*¦we'll�send�an�unsolicited�device�event%*¦to�the�attached�task�if�we�detect�a$*¦change�in�the�status�of�a�drive.‚A%*¦drive�is�considered�to�be�activated'*¦when�the�SASI�driver�has�received�any%*¦valid�command�for�the�drive,�and�we%*¦can't�receive�a�command�for�a�drive"*¦until�after�the�channel�has�been(*¦attached�by�a�task.‚Therefore,�we�know)*¦there'll�be�an�attached�task�to�receive%*¦any�event�message�that�the�POLLSTAT*¦routine�queues.:  $*¨Notice�that�control�now�falls�into'*¦subroutine�EXECREQ�to�make�the�actual(*¦executive�request�that�we�just�set�up,#*¦and�control�normally�returns�from$*¦subroutine�EXECREQ�directly�to�the)*¦routine�that�called�subroutine�INITIAL.-‰ENDCš#######################################-‰LISTš####################################### -‰PAGEš#######################################O******************************************************************************** *ˆRESET�and�TEST�SASI�CONTROLLER*A*ˆThis�subroutine�resets�both�the�SA1403D�SASI�controller�and�the?*ˆMVME420�SASI�Peripheral�Adapter,�and�tests�the�MVME420�to�see*ˆif�it�is�functional.*%*ˆEntry:„A5�=�physical�address�of�CCB*!*ˆRegister�usage:‰0�1�2�3�4�5�6�7*œDƒ* *œA‰*�*�P**ˆExits�to:�CMR�via�RTS*O******************************************************************************* RESETCNT: ‰IFEQ…DTYPE�Assemble�if�SASI.5‰MOVE.LƒCCBCHB(A5),A4ŠGet�the�physical�address�of�the:‰LEA†DIAGNOST(A4),A3†channel's�memory-mapped�I/O�area�into"*¦A4,�and�set�up�A3�to�address�the$*¦MVME420's�DIAGNOST�register.‚We'll&*¦access�the�DIAGNOST�register�several'*¦times,�so�it's�worthwhile�to�dedicate%*¦an�address�register�to�point�to�it. H*‚The�SASI�controller�for�the�DTC�520A�board�does�not�want�a�reset�sinceD*‚a�reset�will�cause�it�to�revert�back�to�the�default�configuration. #*********************************** *‚FOLLOWING�LINE�COMMENTED�OUTƒ* *ˆ11/4/83’**›KERƒ**�PUT�BACK�IN•* *ˆ12/16/83‘**›BWNƒ*#*********************************** ?‰MOVE.Bƒ#RESET,CONTROL(A4)…Reset�the�MVME420�and�the�SA1403D�by(*¦setting�the�RESET�bit�in�the�MVME420's#*¦CONTROL�register.‚In�one�case�the'*¦MVME420�and�the�SA1403D�may�have�just&*¦been�reset�by�the�automatic�power-up)*¦reset,�but�resetting�them�again�in�that&*¦one�case�does�no�harm.‚Resetting�the&*¦MVME420�illuminates�its�fail�LED�and$*¦also�disables�its�interrupt.‚We'll&*¦extinguish�the�fail�LED�later�if�the)*¦MVME420�passes�the�tests�we're�about�to(*¦perform,�but�we'll�leave�the�interrupt&*¦disabled�until�we�want�an�interrupt. 3‰MOVEQBƒ$55,D0‘Write�a�distinctive�bit�pattern�into4‰MOVE.BƒD0,(A3)Žthe�MVME420's�DIAGNOST�register,�and5‰CMP.B„(A3),D0Žset�the�SASIDOWN�flag�if�we�can't�read5‰SNE.B„SASIDOWN(A5)‰back�the�same�bit�pattern�that�we%*¦wrote.‚If�we�read�back�the�same�bit$*¦pattern�that�we�wrote,�however,�we%*¦clear�the�SASIDOWN�flag�to�indicate"*¦that�(so�far,�at�least)�the�SASI*¦channel�is�not�down. -‰PAGEš#######################################.‰NOT.B„D0•Invert�the�bit�pattern�that�we�wrote1‰NOT.B„(A3)‘to�the�DIAGNOST�register�earlier,�and.‰SUB.B„(A3),D0Žcheck�to�see�if�the�pattern�was:‰OR.B…D0,SASIDOWN(A5)†inverted�properly.‚If�it�wasn't,�set(*¦the�SASIDOWN�flag�to�indicate�that�the"*¦SASI�channel�is�definitely�down. 0‰BNE.S„L0020’If�the�MVME420�failed�either�of�the$*¦tests�above,�return�to�the�calling&*¦routine�and�leave�the�MVME420's�fail$*¦LED�illuminated.‚The�tests�that�we(*¦perform�on�the�MVME420�certainly�don't&*¦comprise�a�comprehensive�checkout�by)*¦any�means,�but�they'll�probably�catch�a'*¦surprising�number�of�problems.‚In�any(*¦case,�the�checks�that�we�make�are�con-)*¦siderably�better�than�no�checks�at�all. ?L0460„EQU†LEDOFF+DSABLINTˆThe�MVME420�passed�our�cursory�tests,?‰MOVE.Bƒ#L0460,CONTROL(A4)ƒso�extinguish�its�fail�LED,�but�keep&*¦its�interrupt�disabled.‚The�fail�LED'*¦was�automatically�illuminated�when�we%*¦reset�the�MVME420,�and�the�fail�LED'*¦remained�lit�until�now.‚The�MVME420's&*¦interrupt�was�automatically�disabled&*¦by�our�earlier�reset�command,�and�we%*¦want�to�keep�the�interrupt�disabled$*¦until�we�have�a�specific�reason�to *¦enable�it.‰ENDC/L0020„RTS›The�RTS�is�used�by�both�SASI�and�WIN. .‰PAGEš########################################O*******************************************************************************O******************************************************************; ***************ˆCOMMAND�SERVICE�ROUTINE*C*ˆThis�subroutine�is�called�from�CMR�when�CMR�receives�a�command�toA*ˆinitiate�an‚I/O�transaction‚with�a�device�that�is�controlled�byB*ˆthis�driver.‚The�purpose�is�to�perform�the�common�tasks�that�areB*ˆnecessary�for�all�command�routines,�and�to‚direct�control�to�theA*ˆindividual�routine�that�processes�the‚given�command‚through�the*ˆcommand�switching�table.*5*ˆEntry:„A2�=�physical�address�of�CMR�parameter�block*’A5�=�physical�address�of�CCB/*’A6�=�physical�address�of�TCB�of�attached�task*"*ˆRegisters�usage:„0�1�2�3�4�5�6�7 *™D‚*�*�*…R�R*™A‚*�R�P�R�R�P�P*5*ˆExit:…A1�=�pointer�to�drive's�variable�block�in�CCB*’A3�=�physical�address�of�DCB*’A4�=�physical�address�of�IOCB*’D5�=�0*’D6�=�Channel�device�#*9*ˆExits�to:�The�routine�that�processes�the�given�command.*O*******************************************************************************O******************************************************************************* CMDSWIT: 1‰DC.W…READCMD-*-4ŒThe�read�command�tells�the�SASI1‰DC.W…IOREAD�driver�to�read�data�from�a�disc�into *¦memory. 3‰DC.W…WRITECMD-*-4‹The�write�command�tells�the�SASI2‰DC.W…IOWRIT�driver�to�write�data�from�memory�to�a*¦disc. 3‰DC.W…STATCMD-*-4ŒThe�status�command�tells�the�SASI4‰DC.W…IOSTAT�driver�to�return�the�current�status�and *¦configuration�of�a�disc�drive. 5‰DC.W…CONFIG-*-4�The�configure�command�tells�the�SASI4‰DC.W…IOCNFG�driver�to�change�the�current�configura-*¦tion�of�a�disc�drive. 3‰DC.W…DFCONFIG-*-4‹The�change�default�configuration4‰DC.W…IOCHDC�command�tells�the�SASI�driver�to�change%*¦the�default�configuration�of�a�disc*¦drive.-‰PAGEš####################################### 2‰DC.W…FORMAT-*-4�The�format�command�tells�the�SASI1‰DC.W…IOFRMT�driver�to�format�an�entire�disc�or�a*¦particular�track�of�a�disc. &‰DC.W…0–This�zero�sentinel�word�in�the'*¦position�of�an�offset�value�marks�the*¦end�of�the�switching�table. COMMANDS: 6‰MOVE.LƒSP,SAVESP(A5)ŠSave�the�stack�pointer�so�we�can$*¦later�abort�at�any�level�of�nested$*¦subroutines�and�easily�restore�the%*¦stack�environment�that�existed�when*¦this�routine�began�execution.‰NOLIST*‰IFNE…0–Omit�the�following�code.‚It�is�now *¦obsolete. 6‰TST.B„SASIDOWN(A5)‹If�the�SASI�channel�is�down�(i.e.,/‰BEQ.S„L0620�out�of�service),�try�resetting�the7‰BSR.S„RESETCNT�SA1403D�SASI�controller�and�the�MVME420(*¦SASI�Peripheral�Adapter�to�see�if�they'*¦will�function�properly�after�a�reset.(*¦Subroutine�RESETCNT�resets�the�devices)*¦and�then�tests�the�MVME420�to�see�if�it"*¦is�functional.‚If�the�MVME420�is(*¦functional,�subroutine�RESETCNT�clears(*¦the�SASIDOWN�flag.‚Subroutine�RESETCNT%*¦assumes�that�A5�=�LOC(CCB),�and�the%*¦subroutine�destroys�A3,�A4,�and�D0. ‰ENDC‰LIST?L0620„MOVE.LƒXIOCPK(A2),D6ŠGet�the�physical�address�of�the�IOCB2‰MOVEQ.L‚#0,D5�for�the�command�into�A4.‚Subroutine7‰MOVE.WƒXIOPLN(A2),D5ˆLOGPHY1�converts�the�logical�IOCB4‰BSR†LOGPHY1Žaddress�(in�D6)�into�a�physical�address-‰MOVE.LƒD6,A4�for�us.‚We�must�call�subroutine)*¦LOGPHY1�with�A5�containing�the�physical(*¦address�of�the�CCB,�and�we�must�set�up(*¦D5�to�specify�the�length�(in�bytes)�of%*¦the�IOCB.‚The�CCBTASKA�field�of�the'*¦CCB�must�contain�the�physical�address(*¦of�the�TCB�that�controls�the�task�that#*¦owns�the�IOCB.‚Subroutine�LOGPHY1%*¦returns�the�physical�address�of�the *¦IOCB�in�D6. &*¨Subroutine�LOGPHY1�aborts�processing$*¦if�the�IOCB�that�we�specify�is�not'*¦entirely�within�a�memory�segment�that)*¦belongs�to�the�task�that�owns�the�IOCB.&*¦This�error�can�never�occur�in�actual%*¦practice,�though,�because�a�higher-)*¦level�routine�has�already�verified�that(*¦the�IOCB�lies�entirely�within�a�memory'*¦segment�that�belongs�to�the�task�that*¦owns�the�IOCB. -‰PAGEš#######################################9‰MOVE.LƒXIOUID(A2); ,A3ŠGet�the�physical�address�of�the�DCB2‰MOVEQ.L‚#0,D6�into�A3,�and�get�the�channel�device;‰MOVE.BƒDCBCDV(A3),D6ˆnumber�into�D6.‚These�values�indicate&*¦the�particular�device�that�should�be*¦accessed�by�the�command. 8‰MOVEQBƒISTACDN,D1�If�the�SASI�channel�is�down,�go�queue:‰TST.B„SASIDOWN(A5)‰an�event�to�the�attached�task�to�indi-7‰BNE.S„CMDEXIT2�cate�that�the�channel�is�out�of�service(*¦for�now.‚We�can't�process�any�commands'*¦for�any�SASI�devices�when�the�channel(*¦is�down�because�the�channel�being�down$*¦indicates�that�the�SASI�Peripheral*¦Adapter�is�not�functional. 5‰LEA†DRVBLK(A5),A1ŠSet�up�A1�to�point�to�the�variable:‰MOVEQWƒDRVBLKSZ,D0Šblock�for�the�disc�drive�that�is�to�be-‰MULU…D6,D0�accessed�by�the�command.‚The�disc4‰ADD.L„D0,A1�drive's�variable�block�is�in�the�drive-(*¦associated�portion�of�the�CCB,�and�the)*¦particular�variable�block�in�the�drive-)*¦associated�area�of�the�CCB�is�indicated'*¦by�the�drive's�channel�device�number.(*¦The�code�here�depends�on�the�fact�that)*¦the�drive-associated�portion�of�the�CCB%*¦is�organized�into�parallel�variable)*¦blocks�with�one�variable�block�for�each*¦drive�on�the�channel.  7‰MOVE.WƒIOSFCT(A4),D0ŠNow�prepare�to�search�the�command;‰LEA†CMDSWIT(PC),A0‡switching�table�for�the�command�that�is6‰MOVEQBƒISTAIF,D1Œspecified�by�the�IOSFCT�field�of�the$*¦IOCB.‚We�put�the�IOSFCT�value�into%*¦D0.W,�and�we�put�the�address�of�the(*¦switching�table�into�A0.‚We�also�put�a$*¦status�code�into�D1.B.‚This�status'*¦code�will�be�used�if�the�given�IOSFCT%*¦value�doesn't�correspond�to�a�valid*¦command�code.  4L0030„MOVE.Wƒ(A0)+,D2�This�loop�searches�the�command7‰BEQ.S„CMDEXIT2�switching�table�to�see�if�we�can�find�a6‰CMP.W„(A0)+,D0�match�for�the�IOSFCT�value�in�D0.W.‚If4‰BNE.S„L0030�we�reach�the�end-of-table�sentinel�word)*¦without�finding�a�match,�we�go�queue�an&*¦event�to�tell�the�attached�task�that)*¦we've�received�an�invalid�command�code.&*¦Otherwise,�we�set�up�D2.W�to�contain&*¦the�switching�offset�for�the�routine!*¦that�handles�the�given�command.  /‰MOVEQ.L‚#0,D5’Clear�D5�to�provide�a�convenient$*¦initial�value�for�the�routine�that#*¦processes�the�given�command.‚Some)*¦command-processing�routines�make�use�of*¦this�initial�value�of�D5. 4‰JMP†0(A0,D2.W)�Transfer�control�to�the�routine�that%*¦processes�the�given�command.‚Please&*¦refer�to�the�command�switching�table(*¦and�to�the�searching�loop�above�to�see'*¦how�the�offset�value�here�is�derived. -‰PAGEš#######################################O*********************************************************************************ˆSTATUS�COMMAND�ROUTINE*G*ˆThe�command�service�processor�invokes�the�STATCMD�routine�in�responseE*ˆto�a�status�command.‚Its�purpose‚is�to�set�up�the�user�task's�para-F*ˆmeter�block�to�reflect�the‚drive's�current�status�and�configuration.*6*ˆEntry:„A1�=�pointer�to�drive's�variable�block�in�CCB*’A3�=�physical�address�of�DCB*’A4�=�physical�address�of�IOCB*’A5�=�physical�address�of�CCB/*’A6�=�physical�address�of�TCB�of�attached�task**’D5�=�03*’D6�=�Channel�device�#�for�the�disc�drive�(DCBCDV)*!*ˆRegister�usage:…0�1�2�3�4�5�6�7 *™D‚*‰*�**™A‚*�P�*�P�P�P�P*7*ˆExit:…Falls�through�to�common�exit�routine�(CNDEXIT).*O******************************************************************************* STATCMD: :L0170„EQU†CONFGBLK+IOSATWˆSet�up�A2�to�point�to�the�IOSATW5‰LEA†L0170(A1),A2‰field�of�the�configure�block�in�the%*¦drive's�variable�area�in�the�drive-%*¦associated�portion�of�the�CCB.‚That&*¦configure�block�contains�the�drive's'*¦current�configuration,�and�that's�the)*¦configuration�that�we�want�to�return�to*¦the�user�task. 1‰BSR.S„STATCONF�Subroutine�STATCONF�sets�up�A0�to'*¦point�to�the�IOSATM�field�of�the�user%*¦task's�status�parameter�block.‚Sub-&*¦routine�STATCONF�also�determines�the$*¦drive's�device�status�and�sets�the#*¦first�group�of�fields�in�the�user *¦task< 's�status�parameter�block. "*¨Subroutine�STATCONF�destroys�the'*¦values�of�registers�D6�and�D5,�and�it(*¦uses�the�input�values�of�registers�A1,*¦A2,�A4,�A5,�and�A6. -‰PAGEš#######################################7L0110„EQU†IOATM<<16ŽSet�the�IOSATM�field�and�the�IOSPRM:‰MOVE.Lƒ#L0110+IOPRM,(A0)+ƒfield�in�the�user�task's�status%*¦parameter�block.‚The�values�that�we(*¦return�to�the�user�task�for�these�mask%*¦fields�contain�all�of�the�mask�bits"*¦that�are�significant�to�the�SASI&*¦driver.‚Notice�that�we�advance�A0�to'*¦point�to�the�IOSATW�field�of�the�user *¦task's�status�parameter�block.  7L0120„EQU†IOSDLN-IOSATWŠThe�code�below�assumes�that�the6L0121„EQU†L0120/2Žconfigure�block�contains�an�integral8L0122„EQU†L0121*2Žnumber�of�words�(as�it�always�should).9‰IFNE…L0120-L0122ŠIf�this�assumption�is�not�true,�we�want/‰FAIL…0”[****�ERROR�****�ERROR�****�ERROR�****],‰ENDCšto�generate�an�assembly�error�to�alert'*¦the�current�maintenance�programmer�to&*¦the�problem.‚The�instruction�that�is$*¦normally�skipped�here�generates�an*¦assembly�error. 7‰MOVEQWƒL0121-1,D0�This�loop�copies�the�drive's�current)*¦configuration�values�from�the�configure@L0130„MOVE.Wƒ(A2)+,(A0)+Šblock�in�the�drive's�area�of�the�drive-3‰DBRA…D0,L0130�associated�portion�of�the�CCB�to�the(*¦user�task's�status�parameter�block�one)*¦word�at�a�time�instead�of�one�byte�at�a*¦time�for�improved�speed. "*¨Control�falls�from�here�into�the!*¦command�processor's�common�exit *¦routine. -‰PAGEš#######################################O*********************************************************************************ˆCOMMON�EXIT�ROUTINE*B*ˆThe�CMDEXIT‚routine�is�a‚common�exit�routine�that�is�used�by�theC*ˆmany�different�paths�through�the�command�service�routine.‚ControlC*ˆcomes�to�one�of�three�entry�points�below�to�terminate�processing.*%*ˆEntry:„A3�=�physical�address�of�DCB*’A4�=�physical�address�of�IOCB*’A5�=�physical�address�of�CCB3*’A6�=�physical�address�of�TCB�of�the�attached�task**�D1.B�=�IOSSTA�status�value*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚R�* *™AˆP�P�P�P**ˆExit:…Return�to�CMR�via�RTS*O******************************************************************************* CMDEXIT: ;CMDEXIT1�MOVEQBƒISTAOK,D1ŽControl�reaches�this�point�in�the'*¦command�processor�when�we've�finished)*¦processing�a�command�with�no�errors�and$*¦we�want�to�queue�an�I/O�completion(*¦event�to�notify�the�attached�task�that)*¦the�processing�for�the�command�has�been&*¦completed�with�no�errors.‚The�status&*¦value�that�we�pick�up�here�indicates$*¦that�no�errors�have�been�detected. -‰PAGEš#######################################6CMDEXIT2�BSR†QEVENTT�Control�reaches�this�point�in�the'*¦command�processor�when�we've�finished%*¦processing�a�command�and�we�want�to)*¦queue�an�I/O�completion�event�to�notify'*¦the�attached�task�that�the�processing%*¦for�the�command�has�been�completed.$*¦The�status�value�for�the�completed'*¦command�is�in�D1.B�when�control�comes*¦here. #*¨This�routine�cannot�be�used�for�a'*¦command�whose�processing�is�completed(*¦under�interrupt�control�because�events&*¦must�be�queued�dirrerently�when�they'*¦are�queued�from�an�interrupt�handler.(*¦This�routine�is�used�only�when�we�want$*¦to�queue�an�event�from�the�command'*¦service�routine,�which�is�not�invoked*¦under�interrupt�control. BCMDEXIT3�MOVE.LƒSAVESP(A5),SPŠRestore�the�stack�pointer,�and�clear4‰MOVEQ„#0,D0�D0�to�indicate�that�the�command�service(‰RTS›routine�has�operated�properly.‚Then$*¦return�control�to�the�routine�that$*¦called�subroutine�COMMANDS.‚Notice(*¦that�we�can�use�this�return�routine�to(*¦abort�processing�from�any�level�within(*¦the�command�service�routine�because�we(*¦restore�the�stack�pointer�to�the�value'*¦it�had�when�subroutine�COMMANDS�began*¦execution�at�its�main�level. #*¨Our�handling�of�the�stack�pointer'*¦appears�to�eliminate�re-entrancy,�but(*¦the�SASI�driver�is�still�re-entrant�in'< *¦the�necessary�context�because�subrou-%*¦tine�COMMANDS�can�never�be�called�a'*¦second�time�for�the�same�SASI�channel(*¦until�we�return�control�from�the�first'*¦call�to�the�attached�task.‚Subroutine)*¦COMMANDS�can�be�called�re-entrantly�for#*¦another�SASI�channel�because�each$*¦channel�has�its�own�CCB.‚Also,�the'*¦SASI�interrupt�handler�can�be�invoked%*¦while�subroutine�COMMANDS�is�in�the*¦middle�of�its�execution. -‰PAGEš#######################################O******************************************************************************** *ˆSTATUS/CONFIGURE�COMMON�CHORES*F*ˆThe�subroutine�STATCONF�performs�functions�that�are�common�to�status?*ˆcommands,�configure�commands,�and�default�configure�commands.*6*ˆEntry:„A1�=�pointer�to�drive's�variable�block�in�CCB<*’A2�=�IOSATW�field�in�drive's�configure�block�of�CCB�or�DCB*’A4�=�physical�address�of�IOCB*’A5�=�physical�address�of�CCB*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™DŒ*�* *™A‚*�P…P�P*&*ˆExit:…Return�to�the�calling�routine.*O******************************************************************************* STATCONF: ;‰MOVE.LƒIOSDBP(A4),D6ŠGet�the�physical�address�of�the�first9‰MOVE.Lƒ#IOSDLN,D5‹location�of�the�user�task's�configure/4‰BSR†LOGPHY1Žstatus�parameter�block�into�both�D6�and9STATCON1�MOVE.LƒD6,A0�A0.‚Subroutine�LOGPHY1�converts�the'*¦logical�address�(passed�in�D6)�of�the(*¦user's�parameter�block�into�a�physical"*¦address.‚We�must�call�subroutine)*¦LOGPHY1�with�A5�containing�the�physical(*¦address�of�the�CCB,�and�we�must�set�up(*¦D5�to�specify�the�length�(in�bytes)�of'*¦the�configure/status�parameter�block.$*¦The�CCBTASKA�field�of�the�CCB�must)*¦contain�the�physical�address�of�the�TCB&*¦that�controls�the�task�that�owns�the#*¦configure/status�parameter�block.)*¦Subroutine�LOGPHY1�returns�the�physical'*¦address�of�the�parameter�block�in�D6. &*¨Subroutine�LOGPHY1�aborts�processing(*¦and�reports�an�error�if�the�configure/(*¦status�parameter�block�that�we�specify)*¦is�not�entirely�within�a�memory�segment)*¦that�belongs�to�the�task�that�allegedly*¦owns�the�parameter�block. *Â(Continued)-‰PAGEš#######################################%*¨The�STATCON1�entry�point�to�subrou-(*¦tine�STATCONF�is�a�special�entry�point'*¦that�can�be�used�to�save�time�when�D6#*¦already�points�to�the�user�task's#*¦configure/status�parameter�block. 8‰TST.B„MOUNTED(A1)ŒIf�the�disc�is�not�currently�mounted,/‰SEQ.B„(A0)‘we�set�the�XDSNRB�bit�of�the�IOSDST9‰AND.B„#1<L0250„EQU†CONFGBLK+IOSRTO†block.‚The�user�isn't�allowed�to�setC‰MOVE.LƒL0240(A3),L0250(A1)‚or�change�these�values�with�a�configure'*¦command,�so�we�always�use�the�default%*¦values.‚We�need�to�put�these�values&*¦into�the�current�configuration�block$*¦now�so�we'll�have�the�right�values)*¦there�when�we�copy�them�into�the�user's'*¦configure�parameter�block.‚Also,�this%*¦code�sets�these�fields�properly�for*¦subsequent�status�commands. -‰PAGEš#######################################6L0260„EQU†1< s�used�by�the‚configure�(CONFIG)�and�defaultF*ˆconfigure�(DFCONFIG)�routines.‚Its�purpose�is�to�do�most�of�the�work*ˆfor�both�of�them.*B*ˆEntry:„A0�=�pointer�to�current�field�of�user�task's�configure�pb;*’A1�=�pointer�to�drive's�configuration�block�in�CCB�or�DCB5*’A2�=�physical�address�of�IOSATW�field�in�CCB�or�DCB*’A3�=�physical�address�of�DCB*’A4�=�physical�address�of�IOCB*’A5�=�physical�address�of�CCB/*’A6�=�physical�address�of�TCB�of�attached�task*.*�D1.W�=�Mask�of�bits�not�recognized�in�IOSPRM *�D5.L�=�05*�D6.L�=�Channel�device�#�for�the�disc�drive�(DCBCDV)*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚*�*�*�*�*�P�P*™A‚*�*�*�P�P�P�P*6*ˆExit:…Branches�to�common�exit�for�default�configure.:*’Branches�to�common�exit�for�configure-rigid�(SASI�only).4*’Branches�to�CNFGFLOP�routine�for�configure-floppy.9*’Branches�to�CNFGFLOP�routine�for�configure-drive�and/or$*”configure-media�(WINCHESTER�only).*O******************************************************************************* CONFGCOM: 7‰MOVEM.L‚D6/D5,-(SP)ŒSave�D6�and�D5�so�we�can�use�those%*¦registers�as�working�registers.‚The&*¦saved�value�of�D6�equals�DCBCDV,�the&*¦channel�device�number,�and�the�saved#*¦value�of�D5�is�a�flag�to�indicate&*¦whether�we're�processing�a�configure)*¦command�or�a�default�configure�command. &*¨Notice�that�the�original�value�of�D5'*¦is�now�the�top�value�on�the�stack,�so*¦we�can�easily�access�it. -‰PAGEš#######################################1‰BSR.S„STATCONF�Subroutine�STATCONF�sets�up�D6�to$*¦point�to�the�first�location�of�the(*¦user�task's�configure�parameter�block,(*¦and�it�also�sets�up�A0�to�point�to�the&*¦IOSATM�field�of�the�user�task's�con-'*¦figure�parameter�block.‚Additionally,$*¦subroutine�STATCONF�determines�the$*¦drive's�device�status�and�sets�the#*¦first�group�of�fields�in�the�user#*¦task's�configure�parameter�block. '*¨Subroutine�STATCONF�destroys�register%*¦D5,�and�it�uses�the�input�values�of*¦registers�A1,�A2,�A4,�and�A5. ,‰MOVE.Wƒ(A0)+,D0�Copy�the�user�task's�IOSATM6‰MOVE.Wƒ(A0)+,D2�(attribute-mask)�field�into�D0.W,�and4L1‡SET†IOSATM�get�the�user�task's�IOSPRM�(parameter-0L1‡SET†IOSPRM�mask)�field�into�D2.W.‚These�masks%*¦indicate�which�attributes�and�which#*¦parameter�fields�the�user�task�is'*¦specifying�in�the�configure�parameter"*¦block.‚Notice�the�use�of�the�SET&*¦instructions�to�generate�concordance'*¦entries�for�the�fields�that�we�access*¦here.-‰PAGEš####################################### 0CONERR40�EQU†$40”If�the�user�task's�IOSPRM�field:‰MOVEQBƒCONERR40,D3Šcontains�any�bits�that�are�not�allowed0‰AND.W„D2,D1�for�the�IOSPRM�field,�abort�with�an3‰BNE.S„CNERROR1�error�report.‚If�we�abort�here,�the(*¦error�code�in�D3.B�will�be�returned�to&*¦the�user�task�in�the�IOSDST�field�of *¦the�configure�parameter�block. 0CONERR41�EQU†$41”If�the�user�task's�IOSATM�field:‰MOVEQBƒCONERR41,D3Šcontains�any�bits�that�are�not�allowed7‰MOVEQWƒIOATMNOT,D1Šfor�the�IOSATM�field,�abort�with�an0‰AND.W„D0,D1�error�report.‚If�we�abort�here,�the6‰BNE.S„CNERROR1�error�code�in�D3.B�will�be�returned�to&*¦the�user�task�in�the�IOSDST�field�of *¦the�configure�parameter�block. #*¨If�we�don't�abort�here,�we�end�up(*¦with�D1.W�=�0.‚We'll�take�advantage�of'*¦that�initial�D1.W�value�later�when�we *¦use�D1.W�as�an�index�register. #*¨Notice�that�we�use�a�MOVEQW�macro%*¦here.‚This�MOVEQW�macro�generates�a(*¦one-word�MOVEQ�instruction�because�the)*¦current�value�of�IOATMNOT�fits�within�a&*¦single�byte.‚However,�IOATMNOT�could&*¦expand�to�require�a�full�word�in�the%*¦future.‚If�that�happens,�the�MOVEQW%*¦macro�will�automatically�generate�a&*¦two-word�MOVE.W�instruction,�and�the!*¦code�here�will�continue�to�work *¦properly.-‰PAGEš#######################################6‰TAS.B„ACTIVE(A1)�If�the�command�that�we're�processing.‰BNE.S„L0810�is�the�first�configure�or�def> ault:‰MOVEQ.L‚#$FFFFFFFF,D0ˆconfigure�command�received�for�this<‰MOVEQ.L‚#$FFFFFFFF,D2ˆdisc�since�system�initialization,�set'*¦all�bits�of�D0�and�D2.‚These�settings)*¦for�D0�and�D2�will�cause�us�to�copy�all)*¦attribute�and�parameter�fields�from�the'*¦user�task's�configure�parameter�block(*¦into�the�disc's�current�configuration.(*¦This�special�case�allows�IOS�to�set�up%*¦the�disc's�initial�configuration�to%*¦include�even�the�disc-configuration'*¦fields�that�are�not�recognized�by�the*¦SASI�driver. 4L0810„AND.W„D0,(A0)�Set�the�IOSATW�field�in�the�user/‰NOT.W„D0“task's�configure�block�to�reflect�the7‰AND.W„(A2)+,D0�final�attributes�that�will�be�in�effect1‰OR.W…D0,(A0)Žwith�the�proposed�configuration.‚We3L1‡SET†IOSATW�compute�this�final�attribute�value�by'*¦combining�the�attribute�bits�that�the)*¦user�task�is�specifying�with�the�values&*¦of�the�remaining�attribute�bits�from(*¦the�existing�configuration.‚The�IOSATM&*¦value�from�the�user�task's�configure'*¦parameter�block�tells�which�attribute'*¦bits�the�user�task�is�specifying,�and(*¦the�other�attribute�bits�come�from�the*¦existing�configuration. "*¨Notice�the�use�of�the�SET�pseudo'*¦instruction�to�generate�a�concordance)*¦entry�for�the�IOSATW�field�that�is�used*¦and�modified�here.-‰PAGEš#######################################O*********************************************************************************ˆCommented�out�12/16/83ˆBWN2*ˆThis�test�on�the�attributes�word�is�unnecessary.:*ˆIf�the�configuration�is�for�a�rigid�disk,�then�we�do�not0*ˆlook�at�the�floppy�disk�attribute�bits�anyway.A*ˆAlso,�the�rigid�bit�attribute�is�no�longer�the�most�significant6*ˆbit�for�the�SASI�driver.�(Bit�9�is�now�significant.)*7**�CONERR42�EQU†$42”If�(1)�the�final�attributes�indicat;**‡MOVEQBƒCONERR42,D3Šthat�the�disc�is�a�rigid�disc�and�(2):**‡MOVEQWƒIOATM,D0�they�also�specify�any�attribute(s)�that8**‡AND.W„(A0)+,D0�apply�only�to�floppy�discs,�abort�with?**‡CMP.W„#1<*‚will�reflect�the�total�configuration�that�is�being�proposed. F*ˆRecall�that�D1.W�=�0�from�above.? ‚We�also�have�D2.W�=�IOSPRM�from�theH*‚user�task's�configure�parameter‚block,‚or�else�we‚have‚D2.W�=�$FFFF‚ifK*‚we're�processing‚the�first‚configure�command�or�default�configure�commandI*‚that�has‚been‚processed�for�this‚disc�since�system-initialization‚time.L*‚Additionally,�we�have‚A0�=�LOC(IOSREC)�in�the�user�task's�configure�param-I*‚eter�block,‚and�we‚have‚A2�=�LOC(IOSREC)‚in�the�configure�block�that�is*‚being�updated. 1‰BRA.S„L0310’Branch�into�the�loop�that�merges�the#*¦parameter�values.‚We'll�use�D1.W,%*¦which�equals�zero�from�above,�as�an$*¦index�into�the�CONFGLEN�table.‚The$*¦CONFGLEN�table�contains�a�one-byte'*¦entry�for�each�parameter�value�in�the&*¦configure�block,�and�the�value�of�an(*¦entry�is�N-1�where�N�is�the�length�(in'*¦bytes)�of�the�corresponding�parameter'*¦field.‚The�end�of�the�table�is�marked*¦by�a�-1�sentinel�value. %*¨We�could�easily�rearrange�some�code%*¦to�eliminate�the�branch�instruction&*¦that�is�used�here,�but�the�resulting*¦code�would�lose�some�clarity. -‰PAGEš#######################################O*********************************************************************************ˆCONFIGURATION-LENGTH�TABLE*F*ˆThis‚table�defines�the�length�of�each�parameter�field�in�a�configureF*ˆblock�for�a�disc�drive.‚There�is�one�entry�in�the�CONFGLEN�table�forE*ˆeach‚parameter�field�in�a‚configure�block,�and�the�value�of�a�tableD*ˆentry�is‚N-1�where�N�is‚the�length�(in�bytes)‚of�the�corresponding*ˆparameter�field.*O******************************************************************************* CONFGLEN: +‰DC.B…IOSRSZ-IOSREC-1†Length(IOSREC)�-�1.“{+‰DC.B…IOSWTO-IOSRSZ-1†Length(IOSRSZ)�-�1.“{+‰DC.B…IOSRTO-IOSWTO-1†Length(IOSWTO)�-�1.“{+‰DC.B…IOSSPT-IOSRTO-1†Length(IOSRTO)�-�1.“{+‰DC.B…IOSHDS-IOSSPT-1†Length(IOSSPT)�-�1.“{+‰DC.B…IOSTRK-IOSHDS-1†Length(IOSHDS)�-�1.“{+‰DC.B…IOSILV-IOSTRK-1†Length(IOSTRK)�-�1.“{+‰DC.B…IOSSOF-IOSILV-1†Length(IOSILV)�-�1.“{+‰DC.B…IOSPSM-IOSSOF-1†Length(IOSSOF)�-�1.“{+‰DC.B…IOSSHD-IOSPSM-1†Length(IOSPSM)�-�1.“{,‰DC.B…IOSTRKD-IOSSHD-1…Length(IOSPSD)�-�1.“{.‰DC.B…IOSPCOM-IOSTRKD-1„Length(IOSTRKD)�-�1.’{.‰DC.B…IOSSPTD-IOSPCOM-1„Length(IOSPCOM)�-�1.’{.‰DC.B…IOSSRTD-IOSSPTD-1„Length(IOSSPTD)�-�1.’{,‰DC.B…IOSEWCC-IOSSRTD-1„Length(IOSSRTD)�-�1.+‰DC.B…IOSECC-IOSEWCC-1…Length(IOSEWCC)�-�1.*‰DC.B…IOSDRSV-IOSECC-1…Length(IOSECC)�-�1.&‰DC.B…-1“End-of-table�sentinel�byte.‹{ '‰DS.W†0•This�statement�ensures�that�the'*¦location�counter�is�aligned�to�a�word%*¦boundary�even�if�the�CONFGLEN�table%*¦happens�to�contain�an�odd�number�of*¦bytes.-‰PAGEš#######################################*G*ˆThis�loop,�which�is�entered�at�L0310,�processes�the�parameter�fields.* 2L0280„ROR.W„#1,D2’Bring�the�next�bit�of�the�IOSPRM&*¦field�into�bit�15�of�D2�where�we�can*¦easily�test�it. 0L0290„TST.W„D2•If�the�parameter-mask�bit�is�set,2‰BMI.S„L0300�the�user�is�specifying�this�parameter3‰MOVE.Bƒ(A2),(A0)Œvalue.‚Otherwise,�the�user�is�not>L0300„CMP.B„(A2)+,(A0)+Šspecifying�this�parameter�value,�so�we3‰DBRA…D0,L0290�copy�the�parameter�from�the�existing$*¦configuration�into�the�user�task's&*¦configure�parameter�block.‚This�loop$*¦processes�one�byte�at�a�time�until$*¦we've�processed�all�byte(s)�of�the%*¦current�parameter�field.‚Notice�the)*¦use�of�the�CMP.B�instruction�to�advance*¦both�address�registers. /‰ADDQ.Wƒ#1,D1’Advance�D1.W�to�index�to�the�next$*¦byte�of�the�CONFGLEN�table.‚Recall)*¦that�we�had�D1.W�=�0�when�control�first*¦entered�this�loop. DL0310„MOVE.BƒCONFGLEN(PC,D1.W),D0ƒGet�the�next�entry�of�the�CONFGLEN,‰EXT.W„D0“table�into�D0.W.‚This�value�is�N-14‰BGE.S„L0280�where�N�is�the�number�of�byte(s)�in�the%*¦next�parameter�field.‚If�we�haven't#*¦reached�the�negative�end-of-table&*¦sentinel�entry,�loop�back�to�process*¦the�next�parameter�field. &*¨Notice�that�A0�points�to�the�IOSDRSV$*¦field�of�the�user�task's�configure(*¦parameter�block�when�control�falls�out'*¦of�this�loop.‚Similarly,�A2�poin? ts�to$*¦the�IOSDRSV�field�of�the�configure%*¦block�for�the�configuration�that�is*¦being�updated.-‰PAGEš#######################################G*ˆNow�we�want�to�check�the�proposed�configuration�to�see�if�it�containsK*‚any�invalid‚or�inconsistent�configuration�values.‚If�it�does,�we'll�abort#*‚with�an�appropriate�error�report. 6CONERR43�EQU†$43”The�interleave�factor�for�a�SASI�disc9‰MOVEQBƒCONERR43,D3Šmust�be�in�the�range�1�through�16.‚If;L0320„EQU†IOSILV-IOSDRSV‡the�IOSILV�parameter�isn't�in�this:‰MOVE.BƒL0320(A0),D0‰range,�abort�with�an�error�report.‚If2‰SUB.B„#1,D0�we�abort�here,�the�error�code�in�D3.B1‰LSR.B„#4,D0�will�be�returned�to�the�user�task�in7CNERROR1�BNE†CONERROR�the�IOSDST�field�of�the�configure*¦parameter�block. !*¨The�instruction�that�is�labeled%*¦CNERROR1�is�used�by�other�code�as�a&*¦stepping�stone�so�the�other�code�can&*¦get�to�CONERROR�without�the�use�of�a&*¦BNE.L�instruction�in�the�other�code. 3CONERR44�EQU†$44”The�SASI�driver�contains�code�that;‰MOVEQBƒCONERR44,D3Šassumes�that�the�logical�sector�size�is&*¦a�nonzero�multiple�of�LCDSCTSZ�where>L0325„EQU†IOSPSM-IOSDRSV‡LCDSCTSZ�is�defined�to�be�the�largest9‰MOVE.WƒL0325(A0),D0‰common�divisor�of�all�possible�valid5‰BEQ.S„CNERROR2�sector�sizes.‚Here�we�check�to�verify'*¦that�the�logical�sector�size�(IOSPSM)#*¦is�nonzero.‚If�we�abort�here,�the(*¦error�code�in�D3.B�will�be�returned�to&*¦the�user�task�in�the�IOSDST�field�of *¦the�configure�parameter�block. ;‰MOVEQ.L‚#VDOSRSZ>>2,D1‰Now�we�get�the�Versados�record�size3‰ASL.L„#2,D1�into�D1.L,�and�we�set�the�IOSREC�field?L0326„EQU†IOSREC-IOSDRSV‡of�the�configure�parameter�block�equal;‰MOVE.WƒD1,L0326(A0)‰to�the�Versados�record�size.‚We�save�a)*¦word�of�memory�here�by�taking�advantage&*¦of�the�fact�that�the�Versados�record *¦size�is�evenly�divisible�by�4. 8L0327„EQU†VDOSRSZ>>2�If�the�Versados�record�size�is�ever9L0328„EQU†L0327<<2�changed�so�that�it�isn't�a�multiple�of6‰IFNE…VDOSRSZ-L0328ˆ4,�we�want�to�generate�an�assembly/‰FAIL…0”[****�ERROR�****�ERROR�****�ERROR�****]-‰ENDCšerror�to�alert�the�confused�maintenance'*¦programmer�to�the�problem�that�arises(*¦here.‚The�instruction�that�is�normally$*¦skipped�here�generates�an�assembly)*¦error�if�the�Versados�record�size�isn't*¦a�multiple�of�4.-‰PAGEš#######################################.‰DIVU…D0,D1’We�require�that�the�logical�sector*‰SWAP…D1“size�(in�D0.W)�evenly�divides�the(*¦Versados�record�size�(in�D1)�so�we�can)*¦translate�an�integral�number�of�logical(*¦sector(s)�into�a�Versados�record.‚Here(*¦we�get�the�remainder�from�the�division(*¦into�D1.W,�and�we�save�the�quotient�in*¦the�top�half�of�D1. >‰AND.W„#(1<‰BTSTW„#IOARDISC,LC000(A0)‚logical�sectors.�Determine�rigid�or1‰BNE.S„LC010�floppy�from�the�#IOARDISC�bit�of�the *%%%%%%%%%%%%%%%%%%%ƒ11/7/84‚BWN*B*„Check�to�make�sure�that�the�bytes�per�sector,�sectors�per�track,:*„and�data�density�values�are�consistent�for�5�1/4"�and�8":*„diskettes.‚If�not,�go�to�CONERROR�with�a�error�code�$47.**CONERR47�EQU‡$47‰MOVEQB„CONERR47,D3‰BSR‡CHK_FLOPPY ‰BNE‡CONERROR‰MOVEQB„CONERR46,D3*L*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ééééé4‰ADDQ.Lƒ#1,D5�attributes�word.‚If�floppy,�set�D5�=�1=‰BTSTW„#IOADSIDE,LC000(A0)‚for�a�single-sided�disc.‚Determine0‰BEQ.S„L0845�the�actual�number�of�sides�from�the1‰ADDQ…#1,D5�#IOADSIDE�bit�of�the�attributes�word.)‰BRA.S„L0845�If�double-sided,�set�D5�=�2.LC010;L0840„EQU†IOSHDS-IOSDRSV‰We�have�a�rigid�disc,�so�calculate)‰MOVE.BƒL0840(A0),D5‰the�number�of�heads. 4L0845„MULU…D5,D2’Compute�the�total�number�of�logicalí24‰BEQ.S„L0870�subtract�IOSSPT/2�from�the�total�number2‰SUB.L„D0,D2�of�logical�sectors�to�account�for�the>CNERROR3�BLS.L„CONERROR�fact�that�the�sectors�in�track�zero�of'*¦a�double-density�floppy�disc�are�only%*¦half�as�large�as�normal�sectors.‚We)*¦now�have�the�total�capacity�of�the�disc)*¦in�terms�of�full-sized�logical�sectors.&*¦If�the�total�capacity�of�the�disc�in(*¦terms�of�full-sized�logical�sectors�is#*¦zero�or�less,�we�report�an�error. !*¨The�instruction�that�is�labeled%*¦CNERROR3�is�used�by�other�code�as�a&*¦stepping�stone�so�the�other�code�can&*¦get�to�CONERROR�without�the�use�of�a&*¦BLS.L�instruction�in�the�other�code. 5L0870„MOVE.LƒD2,D0’We�want�to�divide�the�disc's�total0‰CLR.W„D2“sector�count�(in�D2)�by�VDOSRSZ/IOSPSM)‰SWAP…D2“(in�D1)�to�obtain�the�total�disc/‰DIVU…D1,D2�capacity�terms�of�Versados�records.>L0880„EQU†IOSRSZ-IOSDRSV‡Unfortunately,�the�resulting�quotient:‰MOVE.WƒD2,L0880(A0)‰can�be�a�32-bit�number,�and�the�680002‰MOVE.WƒD0,D2�is�limited�to�16-bit�quotients.‚This1‰DIVU…D1,D2�code�performs�the�division�to�yield�a8‰MOVE.WƒD2,L0880+2(A0)‡32-bit�quotient,�and�we�store�the%*¦result�into�the�IOSRSZ�field�of�the(*¦user�task's�configure�parameter�block.%*¦We�simply�discard�the�remainder�(if$*¦any),�so�the�user�can't�access�any$*¦partial�Versados�record�that�might*¦exist�at�the�end�of�the�disc. *Â(Continued)-‰PAGEš#######################################%*¨We�perform�the�division�analogously)*¦to�the�way�a�person�does�long�division.)*¦The�difference�is�that�we�use�a�base�of#*¦65,536�instead�of�base�10.‚Divide)*¦fault�can't�occur�on�the�first�division)*¦because�we�reduce�the�dividend�to�a�16-&*¦bit�number.‚Divide�fault�can't�occur$*¦on�the�second�division�because�the)*¦remainder�in�the�top�half�of�D2�must�be*¦less�than�the�divisor. 1‰IFEQ…VDOSRSZ�To�guarantee�that�divide�fault�does/‰FAIL…0”[****�ERROR�****�ERROR�****�ERROR�****],‰ENDCšnot�occur,�we�must�assure�that�VDOSRSZ"*¦is�nonzero.‚A�zero�value�for�the'*¦Versados�record�size�is�preposterous,'*¦but�we�include�this�test�for�absolute!*¦safety.‚The�instruction�that�is(*¦normally�omitted�here�will�generate�an$*¦assembly�error�if�someone�tries�to'*¦define�the�Versados�record�size�to�be*¦zero.-‰PAGEš#######################################G*ˆFinally,�we're�ready�to�copy�the�proposed�configuration�from�the�userI*‚task's‚configure‚parameter�block�into�the�configure�block�that�is�being *‚updated.  @‰MOVEQWƒIOSDRSV-IOSATW-1,D0„All�parameters�and�attributes�in�the=L0330„MOVE.Bƒ-(A0),-(A2)Šproposed�configuration�are�valid,�so3‰DBRA…D0,L0330�copy�the�proposed�configuration�into#*¦the�configure�block�that�is�being#*¦updated.‚For�a�configure�command,&*¦we're�updating�the�current�configuA re'*¦block�in�the�drive's�area�of�the�CCB,%*¦and�for�a�default�configure�command&*¦we're�updating�the�default�configure'*¦block�in�the�drive's�DCB.‚Notice�that)*¦we�copy�the�IOSATW�field�and�all�of�the)*¦parameter�fields,�but�we�don't�copy�the%*¦mask�fields�because�the�mask�fields(*¦aren't�really�part�of�the�total�device*¦configuration. $*¨At�the�conclusion�of�this�step,�A2#*¦points�to�the�IOSATW�field�of�the'*¦configure�block�that's�being�updated,&*¦so�A2�is�set�properly�for�us�to�call*¦subroutine�STATCON1. /‰TST.L„(SP)“Recall�that�the�value�on�top�of�the0‰BEQ.S„L0830�stack�is�zero�if�we're�performing�a(*¦default�configure�command.‚We�skip�the$*¦next�section�of�code�for�a�default&*¦configure�command,�and�we�execute�it)*¦only�for�an�ordinary�configure�command.-‰PAGEš#######################################D*ˆThis‚section‚of�code‚is�executed�only�for�a�configure�command,�not"*‚for�a�default�configure�command.  :‰MOVE.WƒD1,SCTPVREC(A1)ˆSet�SCTPVREC�<--�VDOSRSZ/IOSPSM�to(*¦indicate�the�number�of�logical�sectors'*¦in�a�Versados�record.‚Recall�that�the(*¦desired�value�was�computed�earlier�and%*¦was�kept�in�D1.‚We�need�to�know�how'*¦many�logical�sector(s)�there�are�in�a)*¦Versados�record�so�we�can�make�the�disc(*¦appear�to�contain�Versados�records.‚We"*¦don't�want�to�set�SCTPVREC�for�a#*¦default�configure�command�because%*¦SCTPVREC�is�effectively�part�of�the)*¦drive's�current�configuration,�not�part'*¦of�the�drive's�default�configuration. 7‰MOVE.WƒIOSOPT(A4),D0ŠIf�the�entire�IOSOPT�field�of�the2‰BNE.S„L0820�IOCB�is�zero,�set�the�MOUNTED�flag�to8‰ST.B…MOUNTED(A1)Šindicate�that�the�disc�is�now�mounted.(*¦A�configure�command�with�a�zero�IOSOPT(*¦field�is�defined�to�be�a�configure�and*¦mount�command. =L0820„ROL.W„#15-IOPDMNTB,D0ˆIf�the�IOPDMNTB�bit�of�the�IOSOPT0‰BPL.S„L0830�field�of�the�IOCB�is�set,�clear�the9‰CLR.B„MOUNTED(A1)ŠMOUNTED�flag�to�indicate�that�the�disc(*¦is�now�dismounted.‚A�configure�command(*¦with�this�option�bit�set�is�defined�to&*¦be�a�configure�and�dismount�command. 5‰ST.B…DCBCCF(A3)�In�the�case�of�a�dismount�command�we(*¦set�the�DCBCCF�flag�in�the�drive's�DCB'*¦to�indicate�that�the�operating�system(*¦should�return�the�drive�to�its�default*¦configuration.-‰PAGEš#######################################@*ˆControl‚converges‚here‚for‚both‚configure‚commands‚and�default*‚configure�commands.  6L0830„BSR†STATCON1�We�call�subroutine�STATCON1�here�to)*¦update�the�IOSDST�(device-status)�field'*¦and�the�IOSDTP�(device-type)�field�in%*¦the�user�task's�configure�parameter'*¦block.‚The�device-status�field�should'*¦reflect�the�disc's�mounted/dismounted&*¦status,�which�may�have�just�changed,"*¦and�the�device-type�field�should(*¦reflect�the�device�type�that�is�speci-#*¦fied�by�the�attribute�word�in�the%*¦configuration�that�we�just�changed. '*¨Notice�that�we�still�have�D6�pointing(*¦to�the�user�task's�configure�parameter)*¦block�when�we�call�subroutine�STATCON1,'*¦and�also�notice�that�we�have�register(*¦A2�pointing�to�the�IOSATW�field�of�the'*¦configure�block�that's�being�updated.!*¦Recall�that�subroutine�STATCON1(*¦destroys�D5,�but�the�original�value�of*¦D5�is�still�on�the�stack. #‰IFNE…DTYPE�Assemble�if�Winchester."‰MOVEM.L‚(SP)+,D5/D6ŠRestore�Regs.1‰TST.L„D5“Does�D5�contain�a�0�for�a�def-donf�cmd?/‰BEQ†CMDEXIT1�Done�if�it�does...branch�to�exit.‰ENDC ‰IFEQ…DTYPE�Assemble�if�SASI.8‰MOVEM.L‚(SP)+,D5/D6ŒRestore�D5�and�D6,�which�were�saved&*¦at�the�beginning�of�this�routine.‚We'*¦now�have�D5�=�0�if�we're�processing�a)*¦default�configure�command,�or�D5�=�1�if'*¦we're�processing�a�configure�command.'*¦We�also�have�D6�=�DCBCDV,�the�channel%*¦device�number�of�the�device�that�is*¦being�configured. (*****************************************¦**ˆTHE�FOLLOWING�COMMENTED�OUTƒ**¡KER‚*(**************************************** 2*ˆAND.B„D5,D4’D5�=�0�if�we're�processing�a�default1*ˆBEQ†CMDEXIT1�configuA re�command,�and�D4.B�=�0�if$*¦we're�configuring�a�rigid�disc.‚In)*¦either�case,�we're�finished�and�we�need(*¦to�go�queue�an�I/O�completion�event�to*¦the�attached�task. !*¨If�we're�processing�a�configure(*¦command�that�configures�a�floppy�disc,(*¦we�have�D5�=�1�and�D4.B�=�$FF.‚In�this$*¦case,�we�want�to�set�up�a�variable#*¦block�to�describe�a�define-format&*¦command�sequence�that�can�be�sent�to%*¦the�SASI�controller�under�interrupt"*¦control.‚We�must�inform�the�SASI(*¦controller�if�we�change�the�density�or'*¦the�number�of�sides�on�a�floppy�disc. .**********************************************-*�MOD�FOR�DTC�520A�SASI�CONTROLLER‚11/16/83�**(*�Modified�for�both�controllers…12/12/83*(*�Type�of�disk…D4.B†Bit�IOASIZE�of�IOATW)*�------------…-----…--------------------**�Hardƒ8"Š0Šset*�Floppy�8"‰$FF‰set*�Hardƒ5�1/4"†0Šclear*�Floppy�5�1/4"…$FF‰clear*.**********************************************  ‰TST.B…D5’TEST�FOR�DEFAULT‰BEQ‡CMDEXIT1ŒDONE�IF�DEFAULTF***********************************************************************Ä*3*ˆModified�for�both�types�of�controllers�12/12/83�**Ä*F***********************************************************************=* If bit IOASIZE (9) of the attribute word (pointed to by A2)@* is 0, then we are dealing with a 5 1/4" disk and the following* code will be executed.6* Otherwise we are dealing with an 8" disk, so we will * go to MOD3*%‰BTSTW…#IOASIZE,(A2)‡IOASIZE�bit�set?'‰BNE‡MOD3�If�yes,�go�to�MOD3�--�it's�8"*F********************************************************************** *‰LEA‡DTCCMD(A5),A0‡POINT�TO�COMMAND�PACKET#‰CLR.B…DTCFLAG(A5)‰ARM�LOOP�COUNTER"‰TST.B…D4’TEST�FOR�RIGID�OR�FLOPPY‰BNE.S…L0650AŽBRA�FOR�FLOPPY;‰MOVE.L„#$C2000000,(A0)+„INIT�TO�A�CLASS�6,OPCODE�2�COMMAND(‰MOVE.W„#0,(A0)+ŒFOR�DTC�520A�CONTROLLER STVALUE‚EQU‡$0B3C0000 3‰MOVE.L„#STVALUE,D3‰GET�STEP�VALUE�DEFAULTS�INTO�D3 EQHEADS‚EQU‡IOSHDS+CONFGBLK -‰ADD.B…EQHEADS(A1),D3†SET�#�OF�HEADS�(BYTE�4)‰SUBQ†#$1,D3Ž#�OF�HEADS�-�1**ˆB15•B0*ˆ-------------------------*‚D3„!…!…!…!…!*ˆ------------------------- *‹^…^…^…^*‹!…!…!…!---------(#�HEADS)�-�1"*‹!…!…!---------------$0„STEP�MODE)*‹!…!---------------------$3CƒSTEP�PERIOD2*‹!---------------------------$0BƒSTEP�PULSE�WIDTH*0*ˆTHIS�TAKES�CARE�OF�#�HEADS�AND�THE�STEP�VALUES*1‰MOVE.L„D3,(A0)+ŒMOVE�DATA�TO�RAM�(1ST�LONG�WORD)*EQTRK„EQU‡IOSTRK+CONFGBLK *‰MOVE.W„EQTRK(A1),D3ˆGET�TOTAL�#�CYLINDERS#‰MOVE.W„D3,D2�SAVE�LOWER�WORD�IN�D2$‰AND.L…#$0000FFFF,D3‡MASK�UPPER�WORD(‰SWAP†D3’TOTAL�#�CYLINDERS�IN�UPPER�WORD,‰LSL.W…#7,D2�DIVIDE�BY�2�AND�PLACE�IN�BYTE�2‰ADD.W…D2,D3�MOVE�IT�INTO�D3%‰AND.B…#0,D3�MAKE�SURE�LAST�BYTE�IS�0**ˆB15•B0*ˆ-------------------------*‚D3„!…!…!…!…!*ˆ------------------------- *‹^…^…^…^&*‹!…!…!…!---------SET�TO�0ˆ(TYPE/SEEK)0*‹!…!…!---------------(#�CYLINDERS)/2�(PRE-COMP)/*‹!…!---------------------#�CYLINDERS…(LO�BYTE)3*‹!---------------------------#�CYLINDERS…(HI�BYTE)*0*ˆTHIS�TAKES�CARE�OF�#�CYLINDERS�&�PRECOMP�VALUE*‰MOVE.L„D3,(A0)+ŒSAVE�IN�MEMORY ‰MOVE.W„#0,D3�GET�0,‰MOVE.W„D3,(A0)+ŒCLEAR�LAST�2�BYTES�OF�BLOCK 1‰LEA‡DTCCMD(A5),A0‡GET�POINTER�TO�PARAMETER�BLOCK‰MOVE.B„D6,D3�GET�LUN�FIELD‰LSL.B…#5,D3�SHIFT�LUN�FIELD-‰MOVE.B„D3,1(A0)ŒPLACE�LUN�IN�PARAMETER�BLOCK  ‰MOVEQ.Lƒ#0,D3�CLEAR�D3‰MOVEQ.Lƒ#0,D4�CLEAR�D4 ‰BRA‡CNFGFLOP-‰PAGEš#######################################7L0650AƒMOVE.L„#$C0000000,(A0)+„CLASS�6,OPCODE�0�COMMAND‰MOVE.W„#0,(A0)+ŒINTO�DTCCMD 0STVAL1ƒEQU‡$17060015‹FOR�MICROPOLIS�1115-6�DRIVE !‰MOVE.L„#STVAL1,D0ŠSET�UP�DTCDATA **ˆB15•B0*ˆ-------------------------*‚D0„!…!…!…!…!*ˆ------------------------- *‹^…^…^…^'*‹!…!…!…!---------HEAD�SETTLE�TIME�15mS8*‹!…!…!---------------MAX�CYLINDER�ADDRESS�SET�TO�0�HERE,*‹!…!---------------------STEP�INTERVAL„6�mS4*‹!---------------------------STEP�PULSE�WIDTH�1B 7�uS*4*ˆTHIS�TAKES�CARE�OF�#�CYLINDERS�&�TIMING�PARAMETERS* '‰MOVE.W„EQTRK(A1),D3ˆGET�#�OF�CYLINDERS-‰AND.L…#$FFFF00FF,D0‡MAKE�SURE�FIELD�IS�CLEAR-‰AND.L…#$0000FFFF,D3‡MAKE�SURE�FIELD�IS�CLEAR‰LSL.W…#8,D3�PUT�#�IN�BYTE�1(‰ADD.L…D3,D0�PUT�IN�MAX�CYLINDER�ADDRESS‰MOVE.L„D0,(A0)+ŒPUT�IN�DTCDATA 0STVAL2ƒEQU‡$CD000B80‹FOR�MICROPOLIS�1115-6�DRIVE -‰MOVE.L„#STVAL2,(A0)+‡NO�MODIFICATIONS�PASSED **ˆB15•B0*ˆ-------------------------*‚D0„!…!…!…!…!*ˆ------------------------- *‹^…^…^…^(*‹!…!…!…!---------DRIVE�IDENTIFIER�-�$803*‹!…!…!---------------DELAY�AFTER�WRITE�DE-ASSERTED7*‹!…!---------------------VALID�DATA�AFTER�DRIVE�SELECT:*‹!---------------------------VALID�DATA�AFTER�HEAD�SELECT*0*ˆTHIS�TAKES�CARE�OF�ADDTIONAL�TIMING�PARAMETERS* -‰MOVE.W„#0,(A0)+ŒLAST�2�BYTES�0�BY�DEFINITION 6‰LEA‡DTCCMD(A5),A0‡NOW�GO�BACK�AND�FIX�DENSITY�&�SIDES BYTE5„EQU‡5“LAST�BYTE�IN�DTCCMD!EQCNFGƒEQU‡IOSATW+CONFGBLK…IOSATW *‰MOVE.B„BYTE5(A0),D0ˆGET�FIELD�IN�QUESTION ‰MOVE.W„EQCNFG(A1),D3‡GET�IOSATW+‰BTST†#IOATDEN,D3‰SINGLE�OR�DOUBLE�DENSITY?‰BEQ.S…MOD1�BRA�IF�SINGLE%‰OR.B†#6,D0�THESE�BITS�ARE�SET�FOR�2D-MOD1…BTST†#IOADSIDE,D3ˆSINGLE�OR�DOUBLE�SIDED‰BEQ.S…MOD2�BRA�IF�SINGLE‰OR.B†#1,D0�THIS�BIT�SET�FOR�2S&MOD2…MOVE.B„D0,BYTE5(A0)ˆREPLACE�FIELD ‰MOVE.B„D6,D3�GET�LUN�FIELD‰LSL.B…#5,D3�SHIFT�LUN�FIELD(‰MOVE.B„D3,1(A0)ŒPLACE�LUN�IN�DATA�FIELD ‰MOVEQ.Lƒ#0,D3�CLEAR�D3‰MOVEQ.Lƒ#0,D4�CLEAR�D4‰BRA.S…CNFGFLOP 2* THE FOLLOWING CODE IS NOT NOW USED. RWM 11/17/83*E* The following code will be used for the 8" SASI drive. BWN 12/12/83*'* We get to MOD3 if we have an 8" SASI.=* If D4.B = 0 then it's a hard disk, so we can go to CMDEXIT1B* If D4.B = $FF then it's a floppy so we have a little work to do.* MOD3…EQU‡* ‰TST.B…D4 ‰BEQ‡CMDEXIT1K****************************************************************************0*ƒModified�for�the�1403ES�controller�1/10/84ƒBWN**ƒTrack�format�byte:*!*ˆ00ˆSingle�density,�single�sided *ˆ01ˆSingle�density,double�sided *ˆ06ˆDouble�density,single�sided *ˆ07ˆDouble�density,double�sided** ‰CLR.L…D4 L1‡SET‡IOSATW/‰MOVE.W„(A2),D0�Get�the�attributes�word�into�D0"‰BTST†#IOADDEN,D0‰Double�density�?‰IF‚‚THEN.S˜If�so,"“BSET†#CMDDDEN,D4‰set�bits�1�and�2“BSET†#CMDDDEN2,D4‰ENDI ‰BTST†#IOADSIDE,D0ˆDouble�sided?‰IFƒƒTHEN.S#“BSET†#CMDDSIDE,D4ˆIf�so,�set�bit�0‰ENDI4‰MOVEQ.Lƒ#0,D3�Clear�D3�for�configure�floppy�routine7‰BRA.S…CNFGFLOPŒBranch�to�the�configure�floppy�routine.*M******************************************************************************'*‚The�following�code�is�no�longer�used.*<‰MOVEQ.L‚#1<‰ADDQ.Wƒ#1<*’D2�=�Desired�CTRLCODE�value�(for�SASI�configure-floppy�only)+*’D5�=�0�for�read,�write�or�format�command;*•=�1�for�a�configure�command3*’D6�=�Channel�device�#�for�the�disc�drive�(DCBCDV)*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚*�*�*�*�*�*�**™A‚*�*�*�*�*�*�P*2*ˆExit:…Branches�to�common�exit�routine�(CMDEXIT).*O******************************************************************************* READCMD: @‰MOVEQ.L‚#READFUNC-WRTFUNC,D5ƒControl�enters�at�this�entry�point(*¦when�we've�received�a�read�command.‚We$*¦set�up�D5.L�so�it�will�contain�the#*¦value�+2�when�control�reaches�the(*¦common�command-processing�routine�that&*¦is�used�for�read,�write,�format,�and&*¦configure-floppy�commands.‚The�value'*¦+2�means�that�a�read�command�is�being *¦processed. >WRITECMD�SUB.L„#-WRTFUNC,D5‹Control�enters�at�this�entry�point&*¦when�we've�received�a�write�command.$*¦We�set�D5.L�so�it�will�contain�the&*¦value�-1�when�control�falls�into�the(*¦common�command-processing�routine�that&*¦is�used�for�read,�write,�format,�and&*¦configure-floppy�commands.‚The�value&*¦-1�indicates�that�a�write�command�is*¦being�processed. -‰PAGEš#######################################.FORMATƒEQU†*–Control�comes�to�this�entry�point'*¦when�we've�received�a�format�command.(*¦We�leave�D5.L�alone�because�it�already&*¦contains�the�value�zero,�which�indi-&*¦cates�that�a�format�command�is�being *¦processed. D*ˆThe�first�part‚of�this�routine�is�used�for�read,‚write,‚and�format6*‚commands,�but�it�is�not�used�for�configure�commands.  4‰MOVEQBƒCTRLDFLT,D4ŒSet�D4.B�to�provide�the�standard$*¦default�CTRLCODE�value�for�a�read,(*¦write,�or�format�command.‚The�stanC dard'*¦default�CTRLCODE�value�tells�the�SASI)*¦controller�to�perform�automatic�retries&*¦and�automatic�data�error�correction. 7‰MOVE.LƒIOSRRN(A4),D3ŠGet�the�specified�Versados�record'*¦number�from�the�user�task's�IOCB�into(*¦D3.‚Notice�that�the�number�we�get�here(*¦is�a�Versados�record�number,�and�we'll%*¦later�need�to�translate�that�number(*¦into�a�logical�sector�number.‚Versados)*¦records�don't�necessarily�correspond�to(*¦logical�sectors�on�a�one-to-one�basis. 8‰MOVEQBƒISTADNM,D1�If�the�disc�that�is�being�accessed�is6‰TST.B„MOUNTED(A1)Šnot�mounted,�reject�the�command�and3‰BEQ†CMDEXIT2�return�an�error�code�to�indicate�that#*¦the�disc�is�not�mounted.‚We�don't&*¦allow�the�user�to�access�the�disc�if"*¦the�disc�isn't�mounted.‚If�we're"*¦performing�a�configure�and�mount$*¦command,�the�disc�has�already�been%*¦mounted�by�the�time�control�reaches(*¦this�point.‚If�the�disc�isn't�mounted,(*¦the�user�can�employ�the�Versados�mount*¦command�to�mount�it. 3CNFGFLOP�EQU†*–Control�comes�to�this�entry�point�to)*¦complete�the�processing�for�a�configure'*¦command�that�configures�a�floppy-disc'*¦drive.‚We�leave�D5.L�alone�because�it&*¦already�contains�the�value�+1,�which%*¦indicates�that�the�processing�for�a#*¦configure-floppy�command�is�being%*¦completed.‚We�also�have�the�desired)*¦CTRLCODE�value�in�D4�when�control�comes)*¦to�this�entry�point,�and�we�have�D3�=�0#*¦upon�entry�to�this�entry�point�to(*¦provide�a�dummy�Versados�record�number%*¦that�will�pass�all�validity�checks. "*¨Control�falls�from�here�into�the(*¦common�command-processing�routine�that&*¦is�used�for�read,�write,�format,�and*¦configure-floppy�commands. )‰IFNE…DTYPE�Assemble�if�Winchester�driver-‰PAGEš#######################################,‰MOVEQ„#0,D4�Use�D4�to�hold�the�control�code5L0652„EQU†CONFGBLK+IOSATW†Read�option�field�in�IOSATW‰MOVE.WƒL0652(A1),D0‰Get�it ‰BTST…#IOATDEN,D0ŠTrack�density?&‰BEQ.S„STAG10�Leave�as�zero�for�single%‰BSET…#CTD,D4ŽSet�that�bit�for�double $STAG10ƒBTST…#IOAFRMT,D0ŠFormat�type?(‰BNE.S„STAG20�Leave�as�zero�for�IBM-type,‰BSET…#CSN,D4ŽSet�that�bit�for�Motorola�type *STAG20ƒBTST…#IOADDEN,D0ŠRecording�density?+‰BEQ.S„STAG30�Leave�as�zero�for�single�(FM)+‰BSET…#CMF,D4ŽSet�that�bit�for�double�(MFM) STAG30ƒBTST…#IOADSIDE,D0‰Sides?&‰BEQ.S„STAG35�Leave�as�zero�for�single%‰BSET…#CDS,D4ŽSet�that�bit�for�double STAG35ƒEQU†*”Label�for�branch3STAG40ƒEQU†CONFGBLK+IOSPSM†Read�current�record�size‰MOVE.WƒSTAG40(A1),D0ˆGet�it#‰MOVEQ„#0,D1�Clear�working�register2STAG45ƒSUB.W„#128,D0ŽSubtract�out�min.�record�size,‰BEQ.S„STAG50�Size�found�when�D0�equals�zero‰ADD.B„#1,D1�Increment�counter‰BRA†STAG45�And�try�again,STAG50ƒLSL.B„#3,D1�Position�sector�size�code‰OR.B…D1,D4�Set�those�bits %‰BCLR…#CDM,D4ŽClear�no-DMA�bit�always*‰BSET…#CIE,D4ŽSet�command�interrupt�enable‰ENDC -‰PAGEš#######################################F*ˆThis�point�marks�the�beginning�of‚the�common�command-processing�rou-K*‚tine�that�is�used�for�read,‚write,‚format,�and�configure-floppy�commands.M*‚Control�falls�into�this�routine�from�above�with�D5�set�to�indicate�the�typeK*‚of�command�that�is�being�processed.ƒWe�have�D5.L�=�+2�for�a�read�command,J*‚D5.L�=�+1‚for�a�configure-floppy�command,‚D5.L�=�0‚for�a�format�command,$*‚and�D5.L�=�-1�for�a�write�command. A*ˆWe‚also�have‚D4.B‚containing�the‚desired‚CTRLCODE‚value�for�theL*‚command�that�is�being�processed,‚and�we�have�D3�containing�the�appropriate)*‚Versados�record�number�for�the�command. 5‰LEA†IOPKTEND(A1),A2ˆPoint�A2�to�the�word�immediately$*¦following�the�last�word�of�the�I/O#*¦packet�in�the�drive's�area�of�the&*¦drive-associated�portion�of�the�CCB."*¦We'll�use�A2�with�auto-decrement&*¦addressing�to�fill�in�the�I/O�packet%*¦values�that�describe�the�I/O�trans-!*¦action�that�is�being�requested. &*¨[******�Warning�******]‚We�use�auto-&*¦decrement�addressing�in�this�routine'*¦instead�of�referring�to�fields�in�the)*¦I/C O�packet�by�their�names,�so�the�order(*¦in�which�the�fields�of�the�drive's�I/O(*¦packet�are�defined�must�not�be�altered)*¦without�first�considering�this�routine. =‰MOVE.LƒCCBTASKA(A5),A0ˆPoint�A0�to�the�TCB�that�controls�the%*¦task�that�owns�the�IOCB�for�the�I/O%*¦command�that�is�being�processed.‚If(*¦the�command�that�is�being�processed�is&*¦an�ordinary�command�that�requires�an)*¦I/O�buffer,�the�task�that�owns�the�IOCB*¦also�owns�the�I/O�buffer.-‰PAGEš#######################################<‰MOVE.WƒIOSOPT(A4),-(A2)‡Copy�the�I/O�options�field�from�the3L1‡SET†IOOPTS�IOCB�into�the�I/O�packet.‚If�the�sign0‰BPL.S„L0360�bit�of�the�IOSOPT�field�is�set,�the&*¦IOCB�includes�an�IOSTSK�field�and�an(*¦IOSSES�field.‚These�fields�can�be�used&*¦by�a�system�task�to�specify�the�task)*¦that�owns�the�I/O�buffer�when�that�task)*¦isn't�the�same�task�that�owns�the�IOCB.'*¦The�IOSTSK�field�and�the�IOSSES�field(*¦should�never�be�included�with�a�format'*¦command�or�a�configure-floppy�command(*¦because�neither�a�format�command�nor�a%*¦configure-floppy�command�has�an�I/O *¦buffer. '*¨Notice�the�use�of�the�SET�instruction)*¦to�generate�a�concordance�entry�for�the *¦IOOPTS�field�that�is�set�here. '*¨We�copy�fields�from�the�IOCB�into�the'*¦I/O�packet�for�two�important�reasons.&*¦(1)‚We�want�the�fields�to�be�quickly&*¦accessible�to�the�interrupt�handler.'*¦(2)‚The�task�that�owns�the�IOCB�might)*¦continue�execution�while�the�I/O�trans-&*¦action�is�being�done�under�interrupt)*¦control,�and�the�task�might�change�some%*¦of�the�values�in�the�IOCB.‚Since�we)*¦can't�trust�the�integrity�of�the�fields(*¦in�the�IOCB,�we�make�our�own�copies�of&*¦the�ones�we�need.‚Thus�the�interrupt&*¦handler�won't�run�amok�by�using�IOCB'*¦values�that�could�capriciously�change*¦at�random�times.-‰PAGEš#######################################H*************************************************************************/*ˆBWN�2/28/84‰Code�added�for�alternate�sectors. *ˆPJD�9/19/847*ˆHere�we�check�the�options�field�for�a�format�command.>*ˆIf�the�options�field�is�not�correct,�we�abort�with�a�ISTAIOP*ˆerror�message.*3**‡TST.B…D5ˆAt�this�time,�D5�holds�the�I/O�function+*œcode.‚If�non-zero,�we�don't�have�a�format$*œcommand,�so�we�can�skip�this�test.**‡BNE.S…L03655**‡MOVE.W„IOOPTS(A1),D0‡Get�the�options�field�into�D0!**‡CMP.W…#IOPDSK,D0ŠFormat�disk�? **‡BEQ.S…L0365�Yes,�passes�test."**‡CMP.W…#IOPTRK,D0ŠFormat�track�? **‡BEQ.S…L0365�Yes,�passes�test.&**‡CMP.W…#IOPBAD,D0ŠFormat�track�bad�? **‡BEQ.S…L0365�Yes,�passes�test.**ˆWe�have�a�bad�options�field.*-**‡MOVE.B„#ISTAIOP,D1‰Put�error�code�into�D1,**‡BRA‡CMDEXIT2Œand�abort.*L0365*A*ˆDecided�to�comment�this�out.�If�neither�format�track�nor�format<*ˆtrack�bad�are�chosen,�the�command�defaults�to�format�disk.*O******************************************************************************* -‰PAGEš#######################################B*ˆThis‚section�of‚code‚is�executed�only‚when‚the�IOCB�includes�theI*‚optional�IOSTSK�and�IOSSES�fields.„These�fields�designate�the‚task�thatL*‚owns‚the�I/O�buffer�when�the�task�that�owns�the�IOCB�is�a�system�task�that*‚doesn't�own�the�I/O�buffer.  6‰LEA†IOSTSK(A4),A0ŠWe�need�to�get�a�pointer�to�the�TCB5‰MOVE.LƒA1,-(SP)�that�controls�the�task�that�owns�the7‰MOVE.Lƒ#T0GETTCB,D0‰I/O�buffer.‚The�T0GETTCB�executive/‰TRAP…#EXEC�request�uses�A0�as�a�pointer�to�the4‰BRA.S„L0350�IOSTSK/IOSSES�packet,�and�it�returns�A0)*¦with�a�pointer�to�the�TCB�that�controls"*¦the�specified�task.‚The�T0GETTCB(*¦executive�request�destroys�A1,�D0,�D1,)*¦and�D2,�but�we�preserve�the�value�of�A1$*¦by�saving�it�on�the�stack.‚Control%*¦returns�from�the�T0GETTCB�executive(*¦request�to�the�instruction�immediately&*¦following�the�TRAP�instruction�if�no*¦errors�are�detected. 4L0340„BRA†BADBUFAD�Control�returns�from�the�T0GETTCB(*¦executive�request�to�this�point�if�the'*¦specified�task�doesn't�exist.‚In�this%D *¦case,�we�report�an�error�indicating$*¦that�the�specification�for�the�I/O%*¦buffer�is�bad.‚Notice�that�we�don't(*¦need�to�clean�up�the�stack�because�the*¦error�routine�cleans�it�up. '*¨Control�may�branch�to�this�point�from(*¦below�in�one�or�more�cases�to�make�the*¦same�kind�of�error�report. 8L0350„MOVE.Lƒ(SP)+,A1�Restore�A1�to�point�to�the�drive's)*¦area�of�the�drive-associated�portion�of *¦the�CCB.-‰PAGEš#######################################D*ˆWhen�control�reaches�this�point,�the�registers�are�set�as�follows: #*‚A6ƒ=�LOC(TCB�of�attached�task).©{*‚A5ƒ=�LOC(CCB).º{*‚A4ƒ=�LOC(IOCB).¹{*‚A3ƒ=�LOC(DCB).º{)*‚A2ƒ=�LOC(IOOPTS�field�of�I/O�Packet).£{J*‚A1ƒ=�LOC(Disc�Drive's�variable�block�in�drive-associated�area�of�CCB).‚{K*‚A0ƒ=�LOC(TCB�of�task�that�owns�the�I/O�buffer)�if�there�is�an�I/O�buffer.D*‡=�LOC(TCB�of�task�that�owns�the�IOCB)�if�there�is�no�I/O�buffer.…{ <*‚D6.B�=�DCBCDV,�Channel�Device�Number�for�the�disc�drive.’{A*‚D5.L�=�IOFUNCT,�I/O�function�code.‚+2�=�read,�+1�=�configure,Œ{*¦0�=�format,�-1�=�write.�{8*‚D4.B�=�CTRLCODE,�control-code�value�for�the�command.–{;*‚D3.L�=�IOSRRN�(or�zero�for�a�configure-floppy�command).“{*‚D2ƒ=�Scratch.»{*‚D1ƒ=�Scratch.»{*‚D0ƒ=�Scratch.  :L0360„MOVE.BƒD6,-(A2)�Copy�the�drive�number�from�D6.B�into6‰MOVE.BƒD5,-(A2)�the�DRIVENUM�field�of�the�I/O�packet,6‰MOVE.BƒD4,-(A2)�copy�the�function�flag�from�D5.B�into4L1‡SET†DRIVENUM�the�IOFUNCT�field�of�the�I/O�packet,2L1‡SET†IOFUNCTŽand�copy�the�control�code�from�D4.B2L1‡SET†CTRLCODE�into�the�CTRLCODE�field�of�the�I/O#*¦packet.‚Notice�the�use�of�the�SET&*¦instructions�to�generate�concordance'*¦entries�for�the�fields�that�we�modify*¦here. $*¨The�interrupt�handler�could�easily(*¦determine�the�drive�number�for�itself,$*¦but�we�improve�speed�by�making�the(*¦drive�number�directly�available�in�the(*¦I/O�packet.‚The�IOFUNCT�field�contains!*¦+2�for�a�read�command,�+1�for�a#*¦configure-floppy�command,�0�for�a#*¦format�command,�or�-1�for�a�write&*¦command.‚Finally,�the�CTRLCODE�field'*¦contains�the�standard�default�control#*¦code�for�a�read,�write,�or�format(*¦command,�and�it�contains�the�specified%*¦control�code�for�a�configure-floppy *¦command.-‰PAGEš#######################################M*******************************************************************************ˆBWN�2/13/84‰PJD‚9/19/84***ˆFor�alternate�sectors�command�for�RWIN1:B*ˆOffset�IOSALT�=�IOSSAD�holds�the�sector�number�for�the‚alternateC*ˆsector,�and�we�want�to�save�it�in�IOBUFLOC�=�IOALTSEC,�so�we�will@*ˆput�IOSSAD�into�D6�a�little�earlier,�then�skip�over�the�LOGPHY *ˆroutine.*‰MOVE.L„IOSSAD(A4),D6**K*************************************************************************** 1‰ASR.L„#1,D5’If�we're�processing�a�format�command4‰BEQ.S„L0370�or�a�configure-floppy�command,�clear�D5&*¦and�skip�the�section�that�determines'*¦the�address�and�the�length�of�the�I/O&*¦buffer.‚There�is�no�I/O�buffer�for�a&*¦format�command�or�a�configure-floppy'*¦command.‚The�zero�that�we�get�into�D5%*¦here�will�be�used�later�to�indicate(*¦that�the�buffer�length�for�a�format�or#*¦configure-floppy�command�is�zero. %*¨Control�falls�through�here�if�we're&*¦processing�a�read�command�or�a�write *¦command. O*********************************************************************************ˆBWN‚2/13/84ˆPJD‚9/19/84*A*ˆJust�commenting�out�that�IOSSAD�move�into�D6�that�we�did�above.*<***†MOVE.LƒIOSSAD(A4),D6ŠGet�the�physical�address�of�the�I/O*L****************************************************************************<‰MOVE.LƒIOSEAD(A4),D5ˆbuffer�into�D6,�and�get�the�length�(in.‰SUB.L„D6,D5�bytes)�of�the�I/O�buffer�into�D5.4‰ADD.L„#1,D5�Subroutine�LOGPHY�requires�the�buffer's0‰BSR†LOGPHY�logical�address�and�its�length�in�D6&*¦and�D5�as�inputs,�and�the�subroutine(*¦also�assumes�that�A0�points�to�the�TCB&*¦that�controls�the�task�that�owns�the#*¦I/O�buffer.‚Recall�that�we�set�A0(*¦earlier.‚Subroutine�LOGPHY�returns�the)D *¦buffer's�physical�address�in�D6,�and�it *¦preserves�the�other�registers. %*¨If�the�specified�I/O�buffer�doesn't$*¦reside�within�the�specified�task's'*¦memory�area,�subroutine�LOGPHY�aborts"*¦with�an�error�report.‚Subroutine)*¦LOGPHY�also�aborts�with�an�error�report(*¦if�the�buffer�length�is�zero�or�an�odd *¦number.-‰PAGEš#######################################>*ˆControl‚converges‚at‚this‚point‚for‚read,‚write,‚format,‚andB*‚configure-floppy�commands.‚The�registers�are�now�set�as�follows: #*‚A6ƒ=�LOC(TCB�of�attached�task).©{*‚A5ƒ=�LOC(CCB).º{*‚A4ƒ=�LOC(IOCB).¹{*‚A3ƒ=�LOC(DCB).º{+*‚A2ƒ=�LOC(CTRLCODE�field�of�I/O�Packet).¡{J*‚A1ƒ=�LOC(Disc�Drive's�variable�block�in�drive-associated�area�of�CCB).‚{K*‚A0ƒ=�LOC(TCB�of�task�that�owns�the�I/O�buffer)�if�there�is�an�I/O�buffer.D*‡=�LOC(TCB�of�task�that�owns�the�IOCB)�if�there�is�no�I/O�buffer.…{ 5*‚D6.L�=�LOC(I/O�Buffer)�if�there�is�an�I/O�buffer.™{<*‰Alternate�sector�number�if�this�is�a�"format�track�as�bad"*‰command.�Otherwise,�garbage.J*‚D5.L�=�Length(I/O�Buffer)�in�terms�of�bytes�if�there�is�an�I/O�buffer.„{J*‚D4ƒ=�Scratch.‚To�be�used�to�compute�IOSECTOR,�the�logical�sector�number.;*‚D3.L�=�IOSRRN�(or�zero�for�a�configure-floppy�command).“{G*‚D2ƒ=�Scratch.‚To�be�used�to�compute�IOSCTCNT,�the�count�of�sectors.„{*‚D1ƒ=�Scratch.»{*‚D0ƒ=�Scratch.  1L0370„EQU†*–Divide�the�buffer�size�(in�D5)�by�theM*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>* *ˆBWN‡3/2/84*"‰IFNE†DTYPE�Assemble�if�Winchester**<*ˆWe�want�to�find�the�address�of�the�last�byte�in�the�user's!*ˆbuffer�and�save�it�in�IOBUFEND.6*ˆThis�will�enable�us�to�double�check�that�we�will�not8*ˆread‚past�the�end�of�the�buffer,�which�could�be�nasty.***‰MOVE.L„D5,D4�D4�<---�Length�of�I/O�buffer.‰ADD.L…D6,D4�D4�<---�Starting�address�+�length!‰SUBQ.L„#1,D4—-1�=�ending�address‰MOVE.L„D4,IOBUFEND(A1)***‰ENDCC*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?L0380„EQU†CONFGBLK+IOSREC†Versados�record�size.‚The�quotient�in<‰DIVU.WƒL0380(A1),D5‰D5.W�tells�us�how�many�Versados�records'*¦we�need�to�process,�and�the�remainder&*¦in�the�top�half�of�D5�should�be�zero)*¦because�we�don't�allow�any�I/O�transfer"*¦that�involves�a�partial�Versados *¦record. '*¨We�don't�need�to�worry�about�dividing#*¦by�zero�here�because�the�Versados$*¦record�size�is�a�nonzero�constant.(*¦Furthermore,�we�know�that�the�Versados)*¦record�size�in�the�disc's�configuration&*¦block�is�valid�because�we've�already"*¦checked�to�make�sure�the�disc�is$*¦mounted,�and�the�disc�is�marked�as)*¦being�mounted�only�at�the�completion�of)*¦a�successful�configure/mount�operation. &*¨If�an�outrageously�large�buffer�size)*¦causes�divide�fault,�the�top�half�of�D5'*¦will�end�up�with�a�nonzero�value;�and)*¦we'll�check�for�that�error�momentarily. &*¨For�a�format�command�or�a�configure-&*¦floppy�command�we�have�D5�=�0,�so�we&*¦get�a�zero�quotient�to�indicate�that(*¦there�is�no�data�transfer�for�a�format(*¦command�or�a�configure-floppy�command.-‰PAGEš#######################################1‰MOVEQ.L‚#0,D2’Move�the�count�of�Versados�records2‰MOVE.WƒD5,D2�into�D2,�and�report�a�buffer-address4‰CMP.L„D5,D2�error�if�the�top�half�of�D5�is�nonzero.1‰BNE.S„L0340�The�top�half�of�D5�can�be�nonzero�in$*¦one�of�two�ways.‚Either�the�buffer(*¦size�isn't�an�integral�multiple�of�the#*¦Versados�record�size,�or�else�the)*¦buffer�size�is�so�large�that�it�exceeds)*¦the�capacity�of�65,535�Versados�records$*¦(i.e.,�16,776,960�bytes).‚With�the)*¦present�level�of�technology�there�is�no'*¦need�to�allow�a�single�I/O�command�to(*¦specify�a�transfer�of�more�than�65,535*¦Versados�records. '*¨D2�now�contains�a�count�of�the�number&*¦of�Versados�records�to�be�processed.)*¦We'll�later�need�to�convert�that�number"*¦into�a�count�of�logical�sectors. ;L0890„EQU†CONFGBLK+IOSRSZˆNow�check�to�see�if�the�specified6‰MOVE.LƒL0890(A1),D0‰Versados�recoE rd�number�(in�D3)�is2‰SUB.L„D3,D0�beyond�the�end�of�the�disc,�and�abort/‰BLS.S„L0730�with�an�error�report�if�it�is.‚The#*¦user�has�a�serious�problem�if�the)*¦specified�starting�record�is�beyond�the%*¦end�of�the�disc.‚Recall�that�IOSRSZ(*¦specifies�the�total�number�of�Versados'*¦records�available�on�the�entire�disc.&*¦Since�the�record�number�of�the�first&*¦record�is�zero,�the�record�number�of)*¦the�last�Versados�record�on�the�disc�is *¦IOSRSZ-1. #*¨For�a�configure-floppy�command�we)*¦have�D3�=�0,�so�the�error�check�that�we(*¦make�here�degenerates�into�a�NOP�for�a*¦configure-floppy�command. '*¨Notice�that�we�now�have�D0.L�equal�to)*¦the�number�of�Versados�records�that�are$*¦available�from�the�starting�record*¦through�the�end�of�the�disc.-‰PAGEš#######################################7‰MOVEQBƒISTAOK,D1ŽInitialize�D1.B�to�contain�the�status1‰CMP.L„D0,D2�code�that�is�used�when�everything�is4‰BLS.S„L0900�OK,�and�then�check�to�see�if�the�record&*¦count�exceeds�the�number�of�Versados(*¦records�that�are�available�between�the$*¦starting�record�and�the�end�of�the#*¦disc.‚Recall�that�D2�contains�the)*¦specified�count�of�Versados�records�for'*¦the�I/O�transfer�and�that�D0�contains&*¦a�count�of�the�Versados�records�that(*¦are�available�from�the�starting�record%*¦through�the�end�of�the�disc.‚D2�=�0&*¦for�a�format�command�or�a�configure-*¦floppy�command. 8‰MOVEQBƒISTAEOV,D1�The�proposed�I/O�transfer�goes�beyond)*¦the�end�of�the�disc,�so�get�the�end-of-(*¦volume�error�code�into�D1.B.‚We'll�use'*¦that�error�code�as�the�status�that�we)*¦return�to�the�user�if�we�don't�run�into%*¦another�error�that�is�more�serious. %*¨There�are�routines�in�Versados�that(*¦depend�on�us�to�return�this�particular(*¦error�code�when�an�I/O�transfer�starts'*¦at�a�legal�Versados�record�number�but%*¦extends�beyond�the�end�of�the�disc.'*¦For�example,�the�utility�program�that)*¦initializes�a�disc�keeps�writing�to�the)*¦disc�until�it�receives�this�error�code. .‰MOVE.WƒD0,D2’Change�the�record�count�in�D2�to$*¦equal�the�total�number�of�Versados%*¦records�that�are�available�from�the(*¦starting�record�through�the�end�of�the(*¦disc.‚We'll�do�as�much�of�the�transfer)*¦as�possible,�and�we'll�truncate�it�when*¦we�reach�the�end�of�the�disc. '*¨We�know�that�the�value�in�D0�will�fit&*¦into�a�16-bit�field�because�we�found'*¦above�that�D0�was�less�than�D2�and�we&*¦already�knew�that�the�top�half�of�D2 *¦was�zero.-‰PAGEš#######################################6L0900„MOVE.BƒD1,-(A2)�Set�the�EOVFLAG�field�of�the�I/O(*¦packet.‚The�value�that�we�put�into�the$*¦EOVFLAG�field�is�either�the�ISTAOK)*¦status�code�or�the�ISTAEOV�status�code.'*¦We�use�the�ISTAEOV�status�code�if�the(*¦I/O�transfer�as�it�was�specified�would'*¦have�gone�beyond�the�end�of�the�disc.%*¦Otherwise,�we�use�the�ISTAOK�status!*¦code.‚If�we�don't�encounter�any)*¦serious�errors�during�the�I/O�transfer,)*¦we'll�return�the�value�from�the�EOVFLAG'*¦field�of�the�I/O�packet�as�the�status*¦code�for�the�transaction. 7‰MOVE.WƒSCTPVREC(A1),D0ˆGet�the�number�of�sector(s)�per2‰MULU.WƒD0,D2�Versados�record�into�D0,�and�convert'*¦the�count�of�Versados�records�(in�D2)%*¦into�a�count�of�logical�sectors.‚D2'*¦now�tells�us�how�many�logical�sectors%*¦to�process.‚The�use�of�the�multiply)*¦instruction�here�is�correct�because�the'*¦count�of�Versados�records�in�D2�was�a%*¦16-bit�number,�not�a�32-bit�number.(*¦The�resulting�count�of�logical�sectors*¦in�D2�is�a�32-bit�number. 0‰MOVEQ.L‚#0,D4’Here�we�set�D4�<--�D3*SCTPVREC�to'*¦start�the�conversion�of�the�specified7L0680„ADD.L„D3,D4�Versados�record�number�into�a�logical-‰BCS.S„L0730�sector�number.‚We're�effectively3‰SUB.W„#1,D0�multiplying�the�Versados�record�number4‰BHI.S„L0680�by�the�number�of�logical�sector(s)�in�a&*¦single�Versados�record,�but�we�can't(*¦use�a�multiply�instruction�because�the$*¦Versados�record�number�is�a�32-bit'*¦unsigned�number,�not�a�16-bit�number.)*¦If�the�resulE ting�value�in�D3�exceeds�32&*¦bits,�we�abort�with�an�error�because *¦the�IOSRRN�value�is�too�large. '*¨Recall�that�D3�contains�the�specified$*¦Versados�record�number�for�a�read,(*¦write,�or�format�command.‚D3�=�0�for�a*¦configure-floppy�command.-‰PAGEš#######################################?L0690„EQU†CONFGBLK+IOSATWˆIf�the�disc�that�is�being�accessed�is9‰MOVE.WƒL0690(A1),D0‰not�a�double-density�floppy�disc,�D4;‰ROR.W„#IOADDEN+1,D0ˆnow�contains�the�logical�sector�number.‰BCC.S„L0750�that�corresponds�to�the�specified%*¦Versados�record�number.‚If�the�disc)*¦isn't�a�double-density�disc,�therefore,(*¦we�can�skip�the�rest�of�the�conversion *¦routine. @L0700„EQU†IOARDISC-IOADDEN‡If�the�disc�that�is�being�accessed�is6‰ROR.W„#L0700,D0Œa�rigid�disc,�we�can�skip�the�rest�of1‰BCS.S„L0750�the�conversion�routine.‚A�rigid�disc(*¦is�always�recorded�at�the�same�density*¦throughout�the�disc. "*¨Actually,�this�test�is�redundant#*¦because�we�only�presently�support&*¦double-density�rigid�SASI�discs,�but'*¦this�test�may�become�important�in�the *¦future. 2‰MOVEQ.L‚#0,D0’We're�dealing�with�a�double-density:L0710„EQU†CONFGBLK+IOSSPT†floppy�disc,�and�track�zero�of�a9‰MOVE.BƒL0710(A1),D0‰double-density�floppy�disc�is�always3‰LSR.B„#1,D0�recorded�with�single�density.‚Register)*¦D4.L�contains�the�logical�sector�number%*¦that�would�be�correct�if�track�zero(*¦were�recorded�with�double�density�like&*¦all�of�the�other�tracks,�but�we�must)*¦apply�a�correction�to�D4�to�account�for(*¦the�fact�that�track�zero�is�different.#*¦We�start�by�getting�the�number�of'*¦sectors�per�track�into�D0.L,�and�then)*¦we�divide�that�number�by�two�to�account(*¦for�the�fact�that�two�sectors�in�track%*¦zero�are�equal�to�one�sector�in�any*¦other�track. 2‰CMP.L„D0,D4’If�the�starting�logical�sector�number4‰BHS.S„L0740�is�beyond�the�end�of�track�zero,�go�add(*¦IOSSPT/2�to�it�to�correct�for�the�fact)*¦that�the�sectors�in�track�zero�are�only%*¦half�sectors.‚All�of�the�sectors�in)*¦track�zero�were�counted�as�full�sectors$*¦in�the�original�computation�of�the*¦logical�sector�number.-‰PAGEš#######################################2‰SUB.L„D4,D0’The�starting�logical�sector�number�is/‰ASL.W„#1,D4�somewhere�within�track�zero,�so�we'*¦multiply�D4�by�two�to�account�for�the)*¦fact�that�the�sectors�in�track�zero�are%*¦only�half�sectors.‚The�sectors�that%*¦precede�the�starting�logical�sector(*¦number�were�originally�counted�as�full)*¦sectors,�but�they're�only�half�sectors.'*¦Overflow�is�not�possible�here�because(*¦the�value�of�D4�has�already�been�found#*¦to�be�less�than�a�one-byte�value. $*¨Besides�adjusting�D4�here,�we�also)*¦set�D0�equal�to�the�number�of�full�(not(*¦half)�sectors�in�track�zero�beyond�the*¦specified�starting�sector. 0‰CMP.L„D0,D2’Recall�that�D2.L�contains�the�count/‰BHI.S„L0720�of�full�sectors�for�the�entire�I/O2‰MOVE.LƒD2,D0�transfer.‚If�the�entire�I/O�transfer'*¦will�be�within�track�zero,�we�need�to5L0720„ADD.L„D0,D2�double�the�sector�count.‚If�the�I/O3‰BCC.S„L0755�transfer�will�extend�beyond�the�end�of'*¦track�zero,�however,�we�must�increase(*¦the�sector�count�by�the�number�of�full(*¦sectors�that�will�be�accessed�in�track(*¦zero.‚In�either�case,�we�check�to�make'*¦sure�that�overflow�doesn't�occur�when*¦we�adjust�the�sector�count. '*¨Notice�that�D0.L�now�contains�a�count)*¦of�the�number�of�full�sectors�that�will(*¦be�accessed�in�track�zero.‚This�number(*¦is�equal�to�half�of�the�number�of�half(*¦sectors�that�will�be�accessed�in�track*¦zero. L0756„CMP.B„#CNFGFUNC,IOFUNCT(A1)�Is�this�a�configure�command?&‰BNE.S„L0757�Branch�around�if�it�isn't#‰MOVEQ.L‚#0,D2�Clear�save�registers‰MOVEQ.L‚#0,D4�* =CD010„EQU†CONFGBLK+IOSTRKD…Read�the�no.�of�cylinders�on�drive éé=‰BTSTW„#IOARDISC,CONFGBLK+IOSATW(A1)‚Determine�the�disk�type:‰IF‡�THENŒIf�floppy,7‰MOVE.WƒCD010(A1),D4‰Use�the�no.�of�cylinders�on�drive.‰ELSEšIf�hard,A‰MOVE.WƒCONFGBLK+IOSTRK(A1),D4‚Use�the�no.�of�cylinders�on�media.‰ENDI $‰SUBQ…#1,D4�Max�cyl�=�no.�of�cyl�-�1 8CD020„EQU†CONFGBLK+IOSHDS†Read�the�no.�of�heads�on�drive‰MOVE.BƒCD020(A1),D2‰*(‰SUBQ…#1,D2�Max�heads�=�no.�of�heads�-�1#‰LSL.W„#8,D2�Position�in�bits�13-15‰LSL.W„#5,D2�* ‰OR.W…D2,D4�Add�to�save�register 9CD030„EQU†CONFGBLK+IOSPCOM…Read�the�precompensation�value‰MOVE.WƒCD030(A1),D2‰*I* Limit precompensation to max allowed by RWIN disk controller - 02/18/851‰CMP.W„#$FF,D2ŽThere�is�only�one-byte�to�hold�theF ééééé.‰IF��THEN’precompensation�cylinder�number!5ŠMOVE.W‚#$FF,D2ŽIf�the�user�has�asked�for�more,�limit‰ENDIšit�to�one-byte�anyway.L0757‰ENDC -‰PAGEš#######################################?L0390„REG†A4/A3/A0/D6/D5/D4/D2ƒNow�we�make�excellent�use�of�the<‰MOVEM.L‚L0390,-(A2)ŠMOVEM�instruction�to�set�several�fields$*¦of�the�I/O�packet�at�one�time.‚Theéééééé'*¦registers�have�been�set�up�to�provide*¦the�following�correspondence. ,L1‡SET†IOCBPTR‡.†A4�=�IOCBPTR‚=�LOC(IOCB).Œ{+L1‡SET†DCBPNTR‡.†A3�=�DCBPNTR‚=�LOC(DCB).�{9L1‡SET†IOBUFTCB†.†A0�=�IOBUFTCB�=�LOC(TCB�of�I/O�Buffer).9L1‡SET†IOBUFPTR†(c)(1)�D6�=�IOBUFPTR�=�LOC(I/O�Buffer).†{9L1‡SET†IOBUFLOC†(c)(1)�D5�=�IOBUFLOC�=�LOC(I/O�Buffer).†{>L1‡SET†IOSECTOR†(a)(2)�D4�=�IOSECTOR�=�Logical�Sector�Number.{:L1‡SET†IOSCTCNT†(b)(3)�D2�=�IOSCTCNT�=�Count�of�Sectors.…{ #*¨Notes:‚(1)�D6�and�D5�both�contain#*¦garbage�for�a�format�command�or�a$*¦configure-floppy�command,�but�both$*¦registers�contain�the�same�garbage(*¦value.‚(2)�D4�=�0�for�configure-floppy'*¦command�to�provide�a�harmless�logical(*¦sector�number�that�passes�all�legality!*¦checksG .‚(3)�D2�=�0�for�a�format'*¦command�or�a�configure-floppy�command'*¦to�indicate�that�no�data�sectors�will*¦be�transferred.#*¨For�the�WINCHESTER�driver:‚(a)�D4(*¦contains�the�MAX�HD�and�MAX�CYL�values *¦for�a�configure-drive�command.%*¦(b)‚D2�contains�the�precompensation&*¦value�for�a�configure-drive�command.  '*¦(c)�IOBUFLOC�(=IOALTSEC)�and�IOBUFPTR**¦both�contain�the�alternate�sector�number%*¦if�this�is�a�"format�sector�as�bad" *¦command.*"*¨Notice�the�use�of�the�SET�pseudo%*¦insructions�to�generate�concordance'*¦entries�for�the�fields�that�we�modify*¦here.-‰PAGEš#######################################2‰MOVE.WƒD0,-(A2)�Set�the�HALFSCTS�field�of�the�I/O4L1‡SET†HALFSCTS�packet,�and�simultaneously�clear�the5L1‡SET†NOFINISH�NOFINISH�flag.‚Recall�that�D0�was�set(*¦up�to�contain�a�count�of�the�number�of'*¦half�sectors�that�will�be�accessed�in&*¦the�I/O�transfer.‚HALFSCTS�is�always'*¦zero�unless�the�I/O�transfer�involves'*¦track�zero�of�a�double-density�floppy(*¦disc.‚The�upper�bytes�of�D0�are�always)*¦zero,�and�we�use�that�fact�to�clear�the'*¦NOFINISH�flag�while�we're�storing�the*¦HALFSCTS�value. "*¨Notice�the�use�of�the�SET�pseudo&*¦instructions�to�generate�concordance'*¦entries�for�the�fields�that�we�modify*¦here.-‰PAGEš#######################################M*******************************************************************************#‰IFNE†DTYPE�Assemble�if�Winchester.***ˆBWN�2/13/84‰PJD‚9/19/84*;*ˆHere�we�find�the�code�for�implementing�alternate�sectors.B*ˆNotice�that�we�are�putting�it�after�the�"excellent�use�of�MOVEM"4*ˆto�fill�the�drive's�variable�block,�because�we�are*ˆgoing�to�blow�away�D0�and�D1.*.*ˆAnother�note�for�the�maintenance�programmer:A*ˆWatch�out�for�the�use�of�A2�above�and�be�very�careful�where�you0*ˆadd�any�fields�to�the�drive's�variable�packet.*D*ˆIf�we�have�a�"format�this�sector�bad"�command�then�D6�contains�the7*ˆsector�number�for�the�track�of�the�alternate�sectors.H*ˆAt�this�point�we�will�convert�that�number�into�a�logical�sector�number$*ˆjust�as�was�done�above‚for�IOSRRN.**+‰CMP.B…#FMTFUNC,IOFUNCT(A1)ŠFormat�command?$‰BNE.S…NOT_ALT—Branch�around�if�not.-‰CMP.W…#IOPBAD,IOOPTS(A1)ŒFormat�bad�command?$‰BNE.S…NOT_ALT—Branch�around�if�not.*?*ˆThe�alternate�sectors�command�only�works�for�the�rigid�disks,>*ˆso�we�will�check�here�if�we�have�a�rigid�disk�and�abort�with*ˆan�error�message�if�not.*"‰MOVEQB„ISTAIF,D1•If�this�is�not�a/‰MOVE.W„CONFGBLK+IOSATW(A1),D0ˆrigid�disk,�then'‰BTSTW…#IOARDISC,D0’abort�with�an�error‰BEQ.L…CMDEXIT2–message. **3*ˆRecall�that�the�alternate�sector�number�is�in�D6.***°If�this�sector�number5‰MOVE.L„CONFGBLK+IOSRSZ(A1),D0ˆgoes�beyond�the�end�of&‰MOVEQB„ISTARR,D1•the�disk,�then�abort#‰SUB.L…D6,D0™with�an�error�message.‰BLS.L…CMDEXIT2**@*ˆConvert�the�Versados�record�number‚in�D6�into�a�logical�sector5*ˆnumber�in�D3,�then�move�into�IOALTSEC�and�IOBUFPTR.**/‰MOVE.W„SCTPVREC(A1),D0…Set�D3�<---�D6*SCTPVREC/‰MOVEQ.Lƒ#0,D3�by�successive�adds,�since�IOSALT‰MOVEQB„ISTARR,D1#‰REPEAT˜is�maybe�more�than�16�bits.-�ADD.LƒD6,D3�Abort�if�result�exceeds�32�bits.�BCS.LƒCMDEXIT2 �SUBQ.W‚#1,D0 ‰UNTIL.S‚,‰MOVE.L„D3,IOALTSEC(A1)…Get�it�into�IOALTSEC>‰MOVE.L„D3,IOBUFPTR(A1)…Also�get�it�into�IOBUFPTR�so�they�will*¦be�the�same.*>*ˆWe�are�going�to�check�that�the�track�of�the�alternate�sector;*ˆis�not�the�same�as�the�track�of�the�bad�sector.‚If�it�is,7*ˆthe�controller�would�make�the�bad�track�inaccessible,$*ˆand�we�certainly�don't�want�that�!*B*ˆWhile�we�are�doing�this�error�checking,�we�will�store�the�values)*ˆfor�later�use�in�the�interruptƒroutine.*A*ˆThe�subroutine�LSN2CHS�takes�a�logical�sector�number�in�D0,�and?*ˆreturns�the�cylinder�number�in�D0.W,�the�head�number�in�D1.B,1*ˆand�the�sector�number�within�the�track�in�D2.B.* ‰MOVE.L„D6,D0 ‰BSR‡LSN2CHS‰MOVE.W„D0,ALTCYL(A1)‰MOVE.B„D1,ALTHEAD(A1)*2*ˆRecall�that�the�sectG or�to�be�marked�bad�is�in�D4+*ˆLet's�convert�it�to�cylinder,head,sector.* ‰MOVE.L„D4,D0 ‰BSR‡LSN2CHS<‰MOVE.B„D2,BADSEC(A1)‡It�is�the�sector�number�within�the�bad*¦track�that�we�need�to�save.*1‰CLR.L…D2’We�don't�need�to�compare�sector�numbers**¦within�the�track,�and�we�need�to�restore"*¦D2�to�0�because�it�is�going�into *¦IOSCTCNT$‰CMP.W…ALTCYL(A1),D0‡Same�cylinder�?!‰BNE.S…NOT_ALT�If�not,�no�problem7‰CMP.B…ALTHEAD(A1),D1†Same�cylinder�and�same�head�means#*¦same�track,�and�this�is�an�error.‰IFƒƒTHEN.S“MOVE.B„#ISTAIF,D1 “BRA‡CMDEXIT2‰ENDI*?*ˆNote:�I�expect�that�most�commands�will�try�to�map�a�bad�track'*ˆto�another�track�on�the�same�surface.?*ˆSo�cylinder�numbers�will�differ,�but�head�numbers�will�be�the*ˆsame.*  NOT_ALT ‰ENDCM*****************************************************************************:‰ADD.B„#1,TCBIOCNT(A0)ˆIncrement�the�TCBIOCNT�field�of�the&*¦TCB�that�controls�the�task�that�owns)*¦the�I/O�buffer�(or�the�IOCB�in�the�case%*¦of�a�format�command�or�a�configure-(*¦floppy�command).‚The�TCBIOCNT�field�of%*¦a�task's�TCB�indicates�how�many�I/O!*¦request(s)�the�task�has�pending%*¦completion�under�interrupt�control. 3‰MOVE.WƒSR,-(SP)�Save�the�value�of�the�SR,�and�then4‰MOVE.WƒCCBISR(A5),SRˆinhibit�interrupts�at�the�SASI"*¦channel's�interrupt�level.‚We're$*¦about�to�alter�the�IOQUEUE,�and�we%*¦don't�want�the�interrupt�handler�to(*¦access�the�queue�while�we're�trying�to *¦change�it. 6‰LEA†IOQCNT(A5),A0ŠPut�the�pointer�to�the�drive's�area2‰MOVE.Wƒ(A0),D0Žof�the�CCB�into�the�next�available;L0670„EQU†IOQUEUE-IOQCNT‡queue�entry,�and�advance�the�queue=‰MOVE.LƒA1,L0670(A0,D0.W)„pointer.‚We�don't�need�to�check�for2‰ADD.W„#4,(A0)Žqueue�overflow�because�we�can�never&*¦accumulate�more�than�one�queue�entry'*¦for�each�drive.‚We�also�don't�need�to(*¦check�for�queue�wrap-around�because�we'*¦physically�move�queue�entries�instead&*¦of�using�wrap-around�queue�pointers.-‰PAGEš####################################### -‰TST.W„D0•If�the�queue�wasn't�empty�before�we1‰BNE.S„L0410�made�the�latest�entry,�the�interrupt$*¦handler�is�already�active�and�will)*¦eventually�complete�the�I/O�transaction'*¦that�we've�just�specified.‚Otherwise,#*¦we�need�to�activate�the�interrupt *¦handler. 8‰LEA†PROCQUE(PC),A0‰Set�up�the�co-routine�switch�pointer>‰MOVE.LƒA0,INTSWTCH(A5)†to�tell�the�interrupt�handler�to�start<‰MOVE.LƒCCBCHB(A5),A0ˆprocessing�a�new�I/O�queue�entry.‚Then4‰BSR†SASIINTŽpoint�A0�to�the�MVME420's�memory-mapped"*¦I/O�area,�and�activate�interrupt%*¦processing�by�calling�the�interrupt#*¦handler�once�as�a�subroutine.‚The%*¦machine's�interrupt�level�is�at�the)*¦same�level�that�would�be�present�during#*¦an�actual�interrupt�from�the�SASI(*¦channel,�so�the�interrupt�handler�will(*¦perform�correctly.‚We�need�to�call�the(*¦interrupt�handler�once�as�a�subroutine%*¦to�activate�interrupt�processing�if&*¦interrupt�processing�isn't�currently *¦active. :L0410„MOVE.Wƒ(SP)+,SR�Restore�the�SR,�and�transfer�control4‰BRA†CMDEXIT3�to�the�command�processor's�common�exit *¦routine.‚We�don't�queue�an�I/O&*¦completion�event�yet�because�the�I/O%*¦transaction�will�be�completed�later*¦under�interrupt�control. -‰PAGEš#######################################O********************************************************************************(*ˆLOGICAL-TO-PHYSICAL�ADDRESS�CONVERSION*F*ˆGiven�a�physical�TCB�address�and�the�logical�address�and�length�of�aE*ˆmemory�area,�subroutine‚LOGPHY�computes�the�physical�address�of�theE*ˆmemory�area.‚It�also�checks�to�make�sure�that�the�given�memory�areaE*ˆreally�belongs�to�the�task‚that�is�controlled�by�the�specified�TCB.*@*ˆThe�subroutine‚has‚two�entry�points:‚LOGPHY‚is�used‚when‚we'reF*ˆdealing�with�a�task�that�owns�the�TCB�and�LOGPHY1�is�used�when�we're)*ˆdealing�with�a�task�that�owns�the�IOCB.*<*ˆEntry:„A5�=�physical�address�of�CCB�(entry�@�LOGPHY1�only);*’D6�=�logicalH �address�of�the�first�word�of�the�memory�area)*’D5�=�length�in�bytes�of�the�memory�area*!*ˆRegister�usage:…0�1�2�3�4�5�6�7 *™D‚P�P‡P�R *™A‚*�P‡P*B*ˆExit:…D6�=�physical�address�of�the�first�word�of�the�memory�area *’Return�to�the�calling�routine.*O******************************************************************************* =LOGPHY1‚MOVE.LƒCCBTASKA(A5),A0ˆSet�A0�to�contain�the�physical&*¦address�of�the�TCB�that�controls�the)*¦task�that�owns�the�IOCB�for�the�command(*¦that�is�currently�being�processed.‚The'*¦memory�area�we�seek�allegedly�belongs!*¦to�the�task�that�owns�the�IOCB. FLOGPHYƒMOVEM.L‚D0-D5/D7/A0,-(SP)†Save�the�working�registers�by�pushing'*¦them�onto�the�stack.‚We�don't�use�all&*¦of�these�registers�directly,�but�the)*¦T0LOGPHY�executive�routine�destroys�the*¦ones�that�we�don't�use. 3‰MOVE.WƒD6,CCR‘Check�to�see�if�the�specified�memory/‰BCS.S„L0040�area�begins�at�an�odd�address,�and&*¦abort�if�it�does.‚We�want�the�memory#*¦area�to�start�on�a�word�boundary.)*¦Notice�that�we�check�for�an�odd�address'*¦by�copying�bit�0�of�the�address�value*¦into�the�C�bit�of�the�CCR. /‰TST.L„D5•Abort�processing�if�the�length�of�the3‰BEQ.S„L0040�specified�memory�area�is�zero.‚A�zero- õ4þ7 5 ? 6 8 &5 .= 6A >$*¦length�memory�area�is�meaningless. :‰MOVE.LƒTCBTST(A0),A0ŠGet�the�physical�address�of�the�Task:‰MOVE.Lƒ#T0LOGPHY,D0‰Segment�Table�for�the�given�task�into/‰TRAP…#EXEC�A0,�and�use�an�executive�request�to'*¦perform�the�conversion�from�a�logical *¦address�to�a�physical�address. -‰PAGEš#######################################2‰BRA.S„L0050’Control�returns�from�the�executive�to'*¦this�point�if�the�conversion�was�good'*¦and�the�specified�memory�area�resides'*¦entirely�within�a�memory�segment�that$*¦belongs�to�the�specified�task.‚The(*¦physical�address�of�the�memory�area�is(*¦in�D6,�so�we're�almost�ready�to�return$*¦control�to�the�routine�that�called*¦subroutine�LOGPHY. *‰NOP�Control�returns�from�the�executive�to)*¦this�point�if�the�specified�memory�area#*¦is�partially�inside�and�partially'*¦outside�a�memory�segment�that�belongs(*¦to�the�specified�task.‚In�this�case�we*¦want�to�report�an�error. =L0040„MOVEQBƒISTAADD,D1�Control�returns�from�the�executive�to4‰BRA†CMDEXIT2�this�point�if�(1)�the�specified�memory'*¦area�is�completely�outside�any�memory'*¦segment�that�belongs�to�the�specified'*¦task�or�(2)�the�specified�memory�area!*¦is�in�a�memory-mapped�I/O�area. 8BADBUFAD�EQU†L0040’Control�also�comes�to�this�point�from(*¦several�other�places,�including�places(*¦outside�subroutine�LOGPHY.‚We�use�this$*¦code�to�report�any�kind�of�buffer-#*¦address�error�that�we�can�detect. #*¨We�queue�an�event�to�the�attached(*¦task�to�indicate�that�we�have�received$*¦a�bad�logical�address,�and�then�we'*¦abort�processing�for�the�command�that*¦is�currently�being�processed. EL0050„MOVEM.L‚(SP)+,D0-D5/D7/A0†Control�reaches�this�point�when�we've*‰RTS›made�a�successful�address�conversion.&*¦We�restore�the�working�registers�and(*¦return�control�to�the�calling�routine. -‰PAGEš#######################################O*********************************************************************************ˆQUEUE�AN�EVENT*H*ˆSubroutine�QEVENT�queues�an�event�message�to�the�task�that�is�attachedC*ˆto�the‚channel.‚There�are‚two�entry�points‚to�the�subroutine.‚TheC*ˆQEVENT‚entry�point‚can�be�used‚to�queue‚an�event‚from�the�commandD*ˆprocessor‚to�the‚attached�task,‚and�the‚QEVENTI�entry�point�can�beC*ˆused�to‚queue‚an�event‚from�the‚interrupt�handler‚to�the�attached@*ˆtask.ƒIn�either‚case,�it‚queues‚an‚I/O�completion‚event‚to�the*ˆattached�task.*%*ˆEntry:„A3�=�physical�address�of�DCB*’A4�=�physical�address�of�IH OCB*’A5�=�physical�address�of�CCB*$*�D1.B�=�event�status�and�I/O�status*!*ˆRegister�usage:…0�1�2�3�4�5�6�7*™D‚*�P�P�P�P�P *™A‚P�PƒP�P�P*C*ˆExit:…Returns�control�to�the�calling�routine�for�good�completion.&*’Invokes�T0KILLER�for�bad�completion.*O*******************************************************************************   @QEVENTI‚MOVE.Lƒ#T0QEVNTI,D0‹This�entry�point�is�used�to�queue�an0‰BRA.S„QEVENT�I/O�completion�event�from�the�SASI)*¦interrupt�handler�to�the�attached�task.$*¦There�is�one�executive�request�for$*¦queuing�an�event�from�an�interrupt)*¦handler,�and�there�is�another�executive%*¦request�for�queuing�an�event�from�a"*¦routine�that�is�not�an�interrupt'*¦handler.‚Here�we�get�the�request�code'*¦for�the�executive�request�that�queues%*¦an�event�from�an�interrupt�handler. -‰PAGEš#######################################@QEVENTT‚MOVE.Lƒ#T0QEVNTT,D0‹This�entry�point�is�used�to�queue�an$*¦I/O�completion�event�from�the�SASI)*¦command�processor�to�the�attached�task.$*¦There�is�one�executive�request�for$*¦queuing�an�event�from�an�interrupt)*¦handler,�and�there�is�another�executive%*¦request�for�queuing�an�event�from�a"*¦routine�that�is�not�an�interrupt'*¦handler.‚Here�we�get�the�request�code'*¦for�the�executive�request�that�queues(*¦an�event�from�a�routine�that�is�not�an*¦interrupt�handler. FQEVENTƒMOVEM.L‚D1-D7/A0-A5,-(SP)†Save�the�working�registers�by�pushing'*¦them�onto�the�stack.‚We�don't�use�all&*¦of�these�registers�directly,�but�the&*¦executive�routine�that�queues�events*¦uses�some�of�them. 9‰MOVE.BƒD1,IOSSTA(A4)ŠStore�the�status�code�into�the�IOCB&*¦where�it�can�be�examined�by�the�task#*¦that�originally�requested�the�I/O#*¦transaction�we've�just�completed. 6‰MOVEQBƒEVNTCOMP,D2ŒGet�the�type�code�for�a�normal�I/O;‰MOVEQBƒEVNTCMSZ,D3Šcompletion�event�into�D2.B,�and�get�the#*¦length�(in�bytes)�of�a�normal�I/O*¦completion�event�into�D3.B. 5‰MOVEQBƒEVNTIO,D4ŽGet�the�event�code�for�an�I/O�event *¦into�D4.B.-‰PAGEš#######################################8‰LINK…A0,#-EVNTMXSZŠReserve�enough�room�on�the�stack�for5‰MOVE.LƒA0,A1�the�largest�possible�event�message,�and(*¦set�up�A1�as�a�temporary�stack�pointer'*¦for�pointing�into�the�event�area�that#*¦we've�just�reserved�on�the�stack.)*¦We'll�use�A1�as�a�working�register,�and(*¦we'll�preserve�A0.‚We�need�to�preserve(*¦A0�so�we�can�restore�the�stack�pointer%*¦after�we're�finished�with�the�event%*¦area.‚The�stack�is�now�organized�as *¦follows. *²|‚Available�Stack„|ƒ{*²|---------------------|ƒ{*¦SP�------->�|‚Event�Area‰|ƒ{ *²|Š.Š|ƒ{ *²|Š.Š|ƒ{ *²|Š.Š|ƒ{*²|---------------------|ƒ{ *¦A0,�A1�--->�|‚Old�A0�Value‡|ƒ{*²|---------------------|ƒ{*²|‚Working�Registers‚|ƒ{ *²|Š.Š|ƒ{ *²|Š.Š|ƒ{ *²|Š.Š|ƒ{*²|---------------------|ƒ{ *¨We're�going�to�build�the�event(*¦message�in�the�event�area�that�we�just&*¦created�on�the�stack,�and�then�we'll!*¦copy�the�event�message�into�the'*¦registers�for�queuing�to�the�attached%*¦task.‚By�using�the�stack�as�an�area$*¦for�building�the�event�message,�we&*¦assure�that�this�subroutine�is�fully%*¦re-entrant.‚This�subroutine�must�be$*¦fully�re-entrant�because�it�can�be(*¦executed�from�both�the�command�service$*¦routine�and�the�interrupt�handler. '*¨Notice�that�the�approach�we�take�here)*¦will�work�properly�for�an�event�message*¦of�any�possible�length. &*¨Now�we�must�start�building�the�event(*¦message�(from�end�to�beginning)�in�the*¦event�area�of�the�stack.-‰PAGEš#######################################5‰MOVE.BƒD1,-(A1)�Store�the�status�byte�into�the�event1‰CLR.B„-(A1)�area,�and�clear�the�next�byte.‚There'*¦are�two�bytes�for�the�event�status�in%*¦the�event�message,�but�one�of�those'*¦bytes�must�always�be�zero.‚We've�just(*¦filled�the�EVNTSTAT�field�of�the�event *¦message. 6‰MOVE.LƒA3,-(A1)�Store�the�physical�address�of�the�DCB%*¦into�the�EVNTDCB�field�of�the�event*¦area. =‰MOVE.BƒCCBKEY(A5),-(A1)‡Copy�the�I key�value�that�was�supplied'*¦by�the�attached�task�into�the�EVNTKEY*¦field�of�the�event�area. 6‰MOVE.BƒD2,-(A1)�Store�the�type�code�into�the�EVNTTYPE*¦field�of�the�event�area. ;‰MOVE.LƒCCBSVVC(A5),D5‰If�the�attached�task�hasn't�supplied4‰BEQ.S„L0060�an�event�service�address�for�I/O�events&*¦from�this�channel,�omit�the�EVNTSVAD*¦field�of�the�event. 1‰ADD.B„#EVNTSVSZ,D3‹Otherwise,�adjust�D3.B,�which6‰MOVE.LƒD5,-(A1)�contains�the�event�length,�to�account8‰MOVEQBƒEVNTIOSA,D4Šfor�the�added�length�of�the�EVNTSVAD)*¦field,�and�put�the�service�address�into'*¦the�EVNTSVAD�field�of�the�event�area.(*¦Also,�change�the�event�code�in�D4.B�to)*¦indicate�that�we�have�an�I/O�event�with*¦a�service�address�included. 3L0060„MOVE.BƒD4,-(A1)�Store�the�event�code�into�the#*¦EVNTCODE�field�of�the�event�area. 5‰CMP.B„CCBASQL(A5),D3‰If�the�event�message�we've�just4‰BLS.S„L0070�constructed�in�the�event�area�is�larger:‰MOVE.BƒCCBASQL(A5),D3‡than�the�largest�event�the�attached)*¦task�is�prepared�to�receive,�change�the&*¦event�length�in�D3.B�to�truncate�the%*¦event�message�to�the�maximum�length#*¦that�the�task�can�accommodate.‚In&*¦actual�practice�we'll�never�truncate&*¦any�events�here�because�the�attached&*¦task�will�be�IOS,�which�is�set�up�to(*¦receive�the�longest�event�message�that*¦we�could�ever�send. 5L0070„MOVE.BƒD3,-(A1)�Store�the�event�length�into�the$*¦EVNTLEN�field�of�the�event�area�to*¦complete�the�event�message.-‰PAGEš#######################################9‰MOVEM.L‚(A1),D2-D6�Now�get�the�event�from�the�event�area'*¦into�the�registers.‚We�pick�up�enough)*¦register�values�here�to�accommodate�the'*¦longest�possible�event�because�that's'*¦easier�than�it�would�be�to�try�to�get)*¦the�right�number�of�register�values�for#*¦the�event�that�we�happen�to�have.$*¦We're�safe�in�accessing�beyond�the(*¦actual�event�area�in�the�stack�because(*¦we�know�there�is�memory�where�we�saved*¦the�working�registers. .‰UNLK…A0•Restore�the�stack�pointer�since�we're)*¦now�finished�with�the�event�area�of�the*¦stack. ;‰MOVE.LƒCCBRQSTA(A5),A0ˆGet�the�physical�address�of�the�TCB1‰BSR.S„EXECREQŽfor�the�attached�task�into�A0,�and$*¦perform�the�executive�request�that#*¦queues�the�event�message�from�the(*¦registers�to�the�attached�task.‚Recall(*¦that�D0�contains�the�executive�request%*¦code�for�the�executive�request�that'*¦queues�the�event�message�properly�for%*¦the�current�environment.‚Subroutine'*¦EXECREQ�kills�the�operating�system�if)*¦the�system�is�unable�to�queue�the�event*¦for�some�unexpected�reason. =‰MOVEM.L‚(SP)+,D1-D7/A0-A5†Restore�the�working�registers,�and+‰RTS›return�control�to�the�calling�routine. -‰PAGEš#######################################O*********************************************************************************ˆEXECUTIVE-REQUEST�SUBROUTINE*E*ˆThe�subroutine�EXECREQ�performs�a�Trap-0�Executive�Request�and�thenB*ˆkills�the�system�if�the�executive�does�not�successfully�respond.*O******************************************************************************* EXECREQ: 0‰TRAP…#EXEC’Perform�the�actual�executive�request(*¦that�was�set�up�before�this�subroutine *¦was�called. *‰RTS�Control�returns�from�the�executive�to&*¦this�point�if�the�executive�success-)*¦fully�performed�the�requested�function.'*¦In�this�case�we�return�control�to�the#*¦routine�that�asked�us�to�make�the*¦executive�request. :‰MOVE.Lƒ#T0KILLER,D0‹Control�returns�from�the�executive�to2‰TRAP…#EXEC�this�point�if�the�executive�was�unable#*¦to�perform�the�requested�function%*¦successfully.‚This�situation�should'*¦never�arise�for�any�executive�request)*¦that�the�SASI�driver�makes�through�this$*¦subroutine.‚If�this�situation�does(*¦arise,�we�kill�the�system�to�bring�the"*¦unexpected�problem�forcefully�to&*¦someone's�attention�for�analysis�and *¦resolution.‰PAGEO******************************************************I *************************O*********************************************************************************ˆCHK_FLOPPY�ROUTINE*&*ˆEntered�as�a�subroutine�of�COMMANDS.B*ˆCheck�that�bytes�per�sector,�sectors�per�track,�and�data�density*ˆhave�consistent�values.*G*ˆWe�call�this�routine�after�we�have�filled�in�the�user's�configurationF*ˆblock�with�the�proposed�configuration.‚That�is�why�A0�is�pointing�to,*ˆthe�end�of�the�user's�configuration�block.*B*ˆWhen�this�routine�is�called,�we�have�already�determined�that�the"*ˆlogical�sector�size�is�non-zero.**ˆEntry:(*’A0�=�end�of�user's�configuration�block*!*ˆRegister�usage:…0�1�2�3�4�5�6�7 *™D†*�*�*ƒ*�**™A‚Pƒ***’P‚=‚parameter�registers*’R‚=‚return�registers"*’*‚=‚saved�and�restored�registers*$*ˆExit:…RTS�back�to�calling�routine.7*’CONDITION�CODES:��no�errors�in�this�config.�check*£�an�error�was�found*O*******************************************************************************O********************************************************************************/*‚Tables�used�to�check�the�floppy�configurationJ*‚The�RWIN�and�SASI�controllers�agree�on�their�values�for�128�byte�sectorsN*‚and�256�byte�sector.�However�there�is�a�difference�on�the�1024�byte�sectors,E*‚and�a�difference�in�what�is�supported�by�the�different�controllers.J*‚For�now,�with�only�128�or�256�bytes�sectors,�there�is�no�difference,�and*‚we�can�use�the�same�tables.*G************************************************************************$*ƒBYTES�PER�SECTOR�--�SINGLE�DENSITY*G***********************************************************************-BPS_S„DC.W†128Š128�bytes,�single�data�density,‰DC.W†0Œwe�do�not�support�256�single�density,‰DC.W†0Œwe�do�not�support�512�single�density-‰DC.W†0Œwe�do�not�support�1024�single�densityG************************************************************************$*ƒBYTES�PER�SECTOR�--�DOUBLE�DENSITY*G***********************************************************************5BPS_D„DC.W†0ŒRWIN�does�not�support�128�double�density(‰DC.W†256Š256�bytes,�double�data�density,‰DC.W†0Œwe�do�not�support�512�double�density-‰DC.W†0Œwe�do�not�support�1024�double�density ƒTHENŽIf�double�density,�move�pntr�to*ŽADDQ.Lƒ#BPS_DENS,A2„double�density�table.‰ENDI***6‰MOVE.W„IOSPSM-IOSDRSV(A0),D6‰D6�<---�bytes�per�sector 0‰MOVE.W�#C_TBL_SZ-1,D7�Search�for�match�in�bytes)BPS_LOOP�CMP.Wƒ(A2)+,D6’per�sector�table.‰DBEQ„D7,BPS_LOOP,‰BNE…RET“If�no�match,�return�with�CCR�=�*'*‚We�are�here�because�we�found�a�match.* BPS_FOUND4‰LEA‡SPT5_S(PC),A2‡A2�<---‚pntr�to�sector�per�track,#*¦5",�single�density�table.(SPT5_S)1‰BTSTW…#IOADDEN,D4‰If�double�density,�point�A2�to+‰IFƒƒTHENŽsectors�per�track,�5",�double,ŽADDQ.Lƒ#SPT_DDEN,A2„density�table.�(SPT5_D)‰ENDI.‰BTSTW…#IOASIZE,D4‰If�8"�diskette,�point�A2�to.‰IFƒƒTHENŽthe�sectors�per�track,�8"�table,4ŽADDQ.Lƒ#SPT_SIZE,A2„either�single�or�double�density*‰ENDIšas�fixed�up�above.(SPT8_D�or�SPT8_S)*D*ƒNow�that�A2�is�pointing�to�the�proper�table�for�sectors�per�track,G*ƒset�up�D4�to‚point„to�the�byte�offset�of�our�entry�from�the�beginning=*ƒof�the�proper�table,�and�let's�check�the�sectors�per�track.*‰MOVE.W„#C_TBL_SZ-1,D3 ‰SUB.W…D7,D37‰MOVE.B„IOSSPT-IOSDRSV(A0),D2‰D2�<---�sectors�per�track‰CMP.B…0(A2,D3.W),D2FRET†MOVEM.Lƒ(A7)+,D2/D3/D4/D6/D7/A2ƒReturn�with�CCR=�if�match�foun‰RTS›and��otherwise O*******************************************************************************   -‰PAGEš####################################### ééééééé=/*=/*†DARTDRV.AF=/*I=/* Chain file to assemble SCN2681 SUBORDINATE serial port driver for the$=/* local port on the MVME115 board.=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to DARTDRV.LS=/*=/IFC \1ƒ=ARG�DARTDRV.LS=/ENDIF=/*$=ASM DARTDRV.SA,DARTDRV.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=/*ƒJ 9995.&.UTILITY.MC=/*ƒ9995.&.SCN2681.EQ=/*ƒ9995.&.TERMINAL.EQ=/*ƒ9995.&.TERMCCB.EQ=/*}=/*=ENDééééé F*J*=========================================================================*?*‚Code�added�to�allocate�memory�for�tables�used�by�RAD1�driver.*K*==========================================================================7‰XREF†RAD1TBLƒSYSPAR�loc�containing�addr�of�RAD�tables. ‰XREF†KILLER *ˆBRA‡RADMEM*ˆINCLUDEƒ&.RADDRV.EQ‰INCLUDEƒ&.RADDRV.EQ ‰SECTIONƒ8*ƒfor�the�DART�driver.‚CMR�automatically�allocates�one�page�ofA*ƒmemory�($100�bytes)�for�the�CCB,�and�our�variable�EXTCCBSZ�willB*ƒreside�in�the�CMR�parameter�table�at�the�beginning�of�the�driver8*ƒto�tell�CMR�how�many�extra�pages�of�memory�are�needed.**CCBSIZEB�EQU‡*PAGESIZE�EQU‡$100L1‡SET‡CCBSIZEB+PAGESIZE-1CCBSIZE‚EQU‡L1/PAGESIZEEXTCCBSZ�EQU‡CCBSIZE-1‰PAGEJ***************************************************************************+*‰SERVICE�VECTOR�TABLE,�REVISION�INFO,�ETC.*@*‰This�table�is�examined�by�CMR�when�the�channel�is�allocated�toC*‰determine�where�to�go�for�interrupts,�commands,�&�initialization.<*‰It�must�always�be�at�the�very�top�of�the�driver�code.‚Also>*‰included�is�a�parameter�telling�the�number�of�extra�pages�of>*‰memory�to�include�in�the�CCB,�and�information�describing�the*‰revision�of�the�driver.*L**************************************************************************** ŠSECTION‚0ŠOPT„BRS DARTDRV: *D*‚Service�vector�table.‚Notice�that�these�values�are�relative�to�theC*‚beginning�of�the�driver�so�the�mechanism�is�position-independent!*=ŠDC.LƒINTERRUPT-DARTDRV‚Address�of�interrupt�service�routine.9ŠDC.LƒCOMMAND-DARTDRV„Address�of�command�service�routine.5ŠDC.LƒINIT-DARTDRV‡Address�of�initialization�routine.ŠDC.Lƒ0’Reserved. **‚Other�CMR�parameters.*7ŠDC.BƒEXTCCBSZ‹#�of�extra�pages�in�the�CCB.‚The�CCB�may)*§be�any�size�from�1�to�256�pages�(a�page'*§is�256�bytes):‚if�this�field�is�0,�it*§will�be�1�page,�etc.ŠDC.Bƒ0,0,0ŽReserved.ŠDC.Lƒ0,0,0ŽReserved. **‚Revision�info:*/ŠDC.Bƒ'110784'‹Date�of�last�assembly�as�MMDDYY.1ŠDC.Bƒ'�'�Space�indicates�no�patches�to�.LO�file.)ŠDC.Bƒ'4'�Major�VERSAdos�revision�number.*‰PAGEO********************************************************************************+*ˆJump�table�for�use�by�the�generic�TERMLIB*O******************************************************************************* ‰BRA.L…PUT_CHAR ‰BRA.L…CK_TBE‰BRA.L…DDP_RESET ‰BRA.L…SETUP‰BRA.L…CLOCK_RESET‰BRA.L…GET_STAT‰BRA.L…DDP_STOP‰BRA.L…DDP_UNSTOP‰BRA.L…DDP_BEG_BREAK‰BRA.L…DDP_END_BREAK‰PAGEJ**************************************************************************J**************************************************************************J***************************************************************************K *‰INITIALIZATION�ROUTINE*>*‰This�routine�is�called�by�CMR�when�the�channel�is�allocated.9*‰Its�purpose�is�to�set�up�things�for�command�service�and7*‰interrupt�service.‚The�major�functions�performed�are:*@*‹1.�Device-Independent�initialization�in�the�call�to�TERM_INIT.3*‹2.�Device-Dependent�initialization�of�the�device.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.**‰Entry:…A5�=�address�of�CCB.*6*‰Calls:…TERM_INIT�in�generic�terminal�driver�TERMLIB.*'*‰Exits�to:‚CMR�(via�RTS)�if�all�is�OK.'*”KILLER�if�exec�won't�allocate�memory,.*•or�can't�get�background�routine�entry�point.*J**************************************************************************J**************************************************************************J**************************************************************************ŠDS…0INIT:*>*‚Perform�the�device-independent�initialization�by�calling�the'*‚generic�routine�TERM_INIT�in�TERMLIB.*.‰JSR‡TERM_INIT‹Do�the�device-independent�stuff2‰IFƒƒTHEN…Something�went�wrong�with�TERM_INIT.4‰IFƒƒTHEN„The�exec�call�failed�and�we�cannot�get!*œthe�scheduler's�entry�point�!!!ŽTR0$.KILLER‚,‰ELSE�RTS�The�channel�is�down�!!‰ENDI‰ENDI*;*‚Perform�the�minimum�device-dependent�initialization�using@*‚call�guarded�to�the�EXEC�for�a�routine�resident�in�background.*5‰LEA‡DO_INIT(PC),A0†Device-dependent�routine�address.-‰MOVE.L„#T0GUARD,D0‰Call�guarded�to�the�EXEC.‰TRAP†#0‰RTS‰PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMAND�SERVICE�ROUTINE*>*‰We�get�entered�here�when�the�attached�task�(IOS)�invokes�CMR?*‰via�a�TRAP�1�with�an�INITIATE�I/O�parameter�block�to�process.>*‰CMR�has�already�checked�the�CMR�parameter�block�to�ensure�it<*‰resides�within�the�address�space�of�the�attached�task.‚IOSA*‰has�already�validated�the�IOCB,�except�for�the�buffer�addresses *‰therein.*@*‰We�got�here�through�a�JSR�from�CMR,�and�will�exit�with�an�RTS.>*‰All�registers�have�been�saved�by�CMR�and�may�be�used�freely.?*‰Entry�is�at�interrupt�level�0,�and�we�are�in�supervisor�mode.*5*‰Entry:�A2�=�physical�address�of�CMR�parameter�block*�A5�=�physical�address�of�CCB*9*‰Calls:�TERM_COMMAND�in�generic�terminal�driver�TERMLIB.*3*‰Exit:‚D0�=�results�of�parameter�block�validation:3*•always�0�in�our�case,�indicating�it�was�OK,�since2*•IOS�will�not�send�us�any�request�except�HALT�I/O/*•if�we�are�already�busy,�and�CMR�makes�all�the*•other�checks.**J**************************************************************************J**************************************************************************J************************************************************************** COMMAND: *,*‚Perform�any�device-dependent�stuff�here...*9‰ST.BƒTBE_FLAG(A5)‹Set�the�flag�to�indicate�buffer�empty.*I*‚Perform�the�device-independent�command�handler�by�calling�TERM_COMMAND.* %ŠJSR…TERM_COMMAND†Perform�the�commandŠRTS—return�to�CMR.ŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INTERRUPT�HANDLING�ROUTINE*<*‰This�routine�completes�I/O�requests�started�by�the�command:*‰service�routine.‚It�is�entered�at�the�interrupt�priority;*‰level�of�interrupts�on�this�channel,�and�is�essentially�a9*‰subroutine�to�the�first�level�interrupt�handler�in�CMR.=*‰Remember,�however,�that�this�is�a�subordinate�driver--hence=*‰the�interrupt�was�fielded�first�by�the�supervisor�used�with(*‰whatever�type�of�board�we're�handling.*L 5*‰Entry:�A0�=�address�of�the�supervisor�driver's�CCB.*�A5�=�address�of�our�CCB.3*�D1�=�Copy�of�Interrupt�Status�Register�from�2681.*"*�D0,A0,A1�have�been�saved�by�CMR.-*�D1‡has�been�saved�by�the�supervisor�driver.*�D0,A1„are�available�to�use.8*�A0‡must�be�returned�to�the�supervisor�with�the�address*šof�the�supervisor's�CCB.4*�D1‡must�be�returned�to�the�supervisor�with�the�bit(*špattern�of�interrupts�left�to�service.*>*‰Exit:‚always�via�RTS,�which�takes�us�back�to�the�supervisor.**‰Stack:*�(A7)+8�.�.�. *�(A7)+4�longword�return�address6*�(A7)ƒlongword�saved�contents�of�D1�(must�be�restored*—before�exit�to�CMR)*J**************************************************************************J**************************************************************************J************************************************************************** INTERRUPT: *‚NOTE:*?*‚This�driver�requires�a�supervisor�driver�since�it�handles�theA*‚SCN2681.‚The�supervisor�driver�written�for�use�with�this�one�isC*‚DARTSPR,�which�branches�to�the�appropriate�longword�in�this�tableC*‚depending�on�interrupt�type.‚The�supervisor�will�not�pass�controlA*‚to�this�driver�unless�there�is�in�fact�an�interrupt�on�my�port.**‚ENTRY�POINTS:*%ŠBRA.S‚RCA�Character�received�for�me.ŠNOP'ŠBRA.S‚TBE�My�transmit�buffer�is�ready.ŠNOP-ŠBRA.L‚BCI�Change�in�BREAK�status�on�my�port.ŠNOP&ŠBRA.L‚IP2�Input�Port�2�Status�change.ŠPAGEJ***************************************************************************)*‰TRANSMIT�BUFFER�EMPTY�INTERRUPT�HANDLER*@*‰The�SCN2681's�transmit�buffer�just�became�empty,�so�if�we�have+*‰more�characters�to�send�we�can�do�it�now.*5*‰Entry:�A0�=�address�of�the�supervisor�driver's�CCB.*�A5�=�address�of�CCB7*�D1�=�copy�of�Interrupt�Status�Register�from�the�2681.*9*‰Calls:�TERM_TBE�in�the�generic�terminal�driver�TERMLIB.*<*‰Since�this�is�not�a�subroutine,�registers�at�exit�are�just-*‰the�entry�requirements�of�the�next�routine.*ééééééééL ééééééééééééééééM ééééééééééééééééM ééééééééééééééééN ééééééééééééééééN ééééééééééééééééO ééééééééééééééééO éééééééééééééééé