IMD 1.17: 11/11/2014 11:02:11 82VKXSVRDOS B* VERSADOS/RMS68K SRC/OBJ 4.4 (NOT BOOTABLE) SN=49367 8 OF 30  SR08q82VKXSVRDOS 0420„a-°=ø=Ą<Č=ŠAŲKąAč@šFųEKL .*‘8/6/84‚Implementedexecbackgroundroutines1*šUsejumptableatbeginningofdevicedependent+*šmoduletocallnecessarydevice-dependent *šroutines.*;*‘6/6/84‚ExtractedfromVERSAdos4.3releaseofMPSCDRV.SA**‰RMS68Kroutinesused: *TR0$.RQPA*TR0$.QEVENTI *TR0$.LOGPHY *TR0$.KILLER *TR0$.GETTCB**‰Othernotes:0*ThiscodeisROMableandposition-independent.*J**************************************************************************J**************************************************************************J**************************************************************************  * *‚INCLUDES***ˆ9995.&.IOE.EQ*ˆ9995.&.STR.EQ*ˆ9995.&.TCB.EQ*ˆ9995.&.NIO.EQ*ˆ9995.&.LV5.EQ*ˆ9995.&.CCB.EQ*ˆ9995.&.TERMINAL.EQ*ˆ9995.&.UTILITY.MC*ˆ9995.&.TERMCCB.EQ*ˆ9995.&.BAB.EQ*‰NOLIST‰INCLUDEƒ9995.&.IOE.EQ‰NOLIST‰INCLUDEƒ9995.&.STR.EQ‰NOLIST‰INCLUDEƒ9995.&.TCB.EQ‰NOLIST‰INCLUDEƒ9995.&.NIO.EQ‰NOLIST‰INCLUDEƒ9995.&.LV5.EQ‰NOLIST‰INCLUDEƒ9995.&.CCB.EQ‰NOLIST‰INCLUDEƒ9995.&.TERMINAL.EQ‰NOLIST‰INCLUDEƒ9995.&.UTILITY.MC‰NOLIST‰INCLUDEƒ9995.&.TERMCCB.EQ‰NOLIST‰INCLUDEƒ9995.&.BAB.EQ‰LIST‰PAGED*********************************************************************5*ƒEQUATESANDMACROSFORTHEGENERICTERMINALLIBRARY*D**********************************************************************@*ƒOFFSETTOMARKTHEENDOFTHESERVICEVECTORTABLEINADRIVER*SERVECT‚EQU‡$28*=*‚ADRIVERTHATWISHESTOUSETERMLIBMUSTHAVETHEFOLLOWING>*‚BRANCHTABLEIMMEDIATELYFOLLOWINGTHESERVICEVECTORTABLE:**†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**‰OFFSET„SERVECTT_PUT_CHAR‰DS.L†1T_CK_TBE‹DS.L†1T_DDP_RESETˆDS.L†1T_SETUPŒDS.L†1T_CLOCK_RESET†DS.L†1T_GET_STAT‰DS.L†1T_DDP_STOP‰DS.L†1T_DDP_UNSTOP‡DS.L†1T_DDP_BEG_BREAK„DS.L†1T_DDP_END_BREAK„DS.L†1***‰PAGEG************************************************************************>*ƒMACROTOPERFORMTHEJUMPTOthedeviceDEPENDENTSUBROUTINE*3*ƒAssumption:A4=addrofbeginningofthedriver.**ƒCalledby:ƒT_JSR‚ROUTINE*2*‰where‚T_ROUTINEisanoffsetintheabovetable.*H************************************************************************* T_JSR„MACRO ‰IFC'\1','' ŒFAIL‚400ŒMEXIT‰ENDC ‰JSR„T_\1(A4)‰ENDM‰PAGEC********************************************************************2*ƒDescriptionsoftheroutinesrequiredbyTERMLIB*C*******************************************************************D********************************************************************* *ˆPUT_CHAR**ˆEntry:‚A5=addrofCCB*A4=addrofdriver#*A1=addrofoursideofthechip*D0.B=charactertotransmit**ˆExit:*A5=addrofCCB*A4=don'tcare*A1=don'tcare'*D0.B=characterthatwastransmitted4*Allotherregistersmustbeastheywereonentry.***?*ˆPUT_CHARactuallywritesthecharacterinD0.Btothedevice.6*ˆPUT_CHARiscalledbyXMIT_D0(FORCE_D0)inTERMLIB.-*ˆPUT_CHARiscalledbyTM_OUTPUTinTERMLIB.*H**************************************************************************ˆCK_TBE*ˆEntry:‚A5=addrofCCB*A4=addrofthedriver#*A1=addrofoursideofthechip*ˆExit:*A5=addrofCCB*A4=addrofthedriver#*A1=addrofoursideofthechip*A2-A3,A6=don'tcare!*A7mustbethesameasonentry*D0-D7=don'tcare**9*ˆCK_TBEteststoseeifthetransmitbufferisemptyand)*ˆreturnstheconditioncodesasfollows:*’=transmitbufferempty"*’=transmitbuffernotempty&*ˆCK_TBEiscalledbyXMITinTERMLIB.*H************************************************************************* *ˆDDP_RESET**ˆEntry:‚A5=addrofCCB *A4=addressofdriver&*A1=addressofoursideofthechip&*A0=addressofeventinsomecases.**ˆExit:ƒA5=addressofCCB*A4=addressofdriver&*A1=addressofoursideofthechip*A0mustbepreserved1*AllotherregistersexceptA7canbedestroyed.*,*ˆDDP_RESETdoesthedevicedependentreset.8*ˆTheTERMLIBRESETclearsthequeues,clearsflags,and"*ˆotherdevice-independentthings.%*ˆDDP_RESETiscalledbyDO_CONFIGUR, *ŸDO_HALT,*ŸRECV,*ŸBREAKinTERMLIB.*G*************************************************************************ˆSETUP**ˆEntry:‚A5=addrofCCB*A4=addrofdriver**ˆExit:ƒA5=addrofCCB*A0-A4=don'tcare*D0-D7=don'tcare**;*ˆSETUPusestheworkingconfigurationin‚theCCBtosetup *ˆthedevice."*ˆSETUPiscalledbyDO_CONFIGURE.*B******************************************************************* *ˆCLOCK_RESET**ˆEntry:‚A5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice%*A0=addrofConfigureStatusBlock**ˆExit:ƒA5=addrofCCB*A4=addrofdriver*A0-A3=don'tcare*D0-D7=don'tcare*<*ˆCLOCK_RESETresetstheon-boardclock,ifthereisone,to4*ˆitsdefaultvalue.‚Ifthereisnoclock,justRTS.4*ˆTheCLOCK_RESETroutineiscalledbyDO_CONFIGURE.8*ˆThedevicedependentroutinemayuseCLOCK_RESETwhile*ˆinDETECT_BAUDmode.*G************************************************************************ *ˆGET_STAT**ˆEntry:‚A5=addrofCCB*A4=addrofdriver*A3=addrofIOCB(IO_COMN)+*A1=addrofuser'sdatablock(REQ_STAT)*A1=addrofevent(BREAK)0*A1=addrofstufftocopyintoDCB(CHNG_DEF)5*A0=addrofuser'sCSB(CHNG_DEFandDO_CONFIGURE)!*A0=addrofeventarea(BREAK)*'*ˆExit:ƒA0-A1,A3-A7mustbeasonentry*A2=don'tcare*D2-D7=don'tcare*D0.B=thedevicestatusbyte*D1=garbage*A*ˆGET_STATpreparesthedevicestatusbytewhichcontains,ifthe?*ˆboardiscapableofsensingit,theconditionoftheDSRline)*ˆ(whichindicatesdeviceready/unready)..*ˆItsetssuchbitsasXDSDCD,XDSABR,XDSNRB.D*ˆThisroutinedoesnotsetthebreakindicatorinthedevicestatus*ˆbyte.**ˆGET_STATiscalledby*1*ˆ(1)‡REQ_STAT,ahandlerfortheIOSTATcommand.3*’UponreturnfromGET_STAT,D0.Bismovedintothe"*’IOSDSTfieldoftheuser'sIOCB.*3*ˆ(2)‡CHNG_DEF,thehandlerfortheIOCHDCcommand.3*’UponreturnfromGET_STAT,D0.Bismovedintothe!*’IOSDSTfieldoftheuser'sCSB.*3*ˆ(3)‡IO_COMN,thehandlerfortheREAD,WRITE,and*’OUTPUTw/INPUTcommands.3*’UponreturnfromGET_STAT,theXDSNRB(notready)1*’bitischecked,andifthedeviceisnotready,8*’thentheISTANR(notready)errormessageisreturned.*:*ˆ(4)‡BREAK,abackgroundroutine.‚Ifwegetabreakwhile4*’doingI/O,thyenwesendbackanunsolicitedevent *’toIOS.6*’UponreturnfromGET_STAT,wesettheXDSBRK(break)2*’bit,andreturnthecontentsofD0intheXRPDST%*’(devicestatus)fieldoftheevent.*:*ˆ(5)‡DO_CONFIGURE,toputthelateststatusintheuser's*’CSB.*H************************************************************************* *ˆDDP_STOP**ˆEntry:‚A5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice**ˆExit:ƒA5=addrofCCB*A0-A4=don'tcare*D0-D7=don'tcare.*ˆDDP_STOPstopsthedevicefromtransmitting.8*ˆDDP_STOPiscalledbySTOP_IT,abackgroundroutinein6*ˆTERMLIB.‚IfwearenotconfiguredforXON_XOFF,then/*ˆTERMLIBcallsuponDDP_STOPtopulltheline.*K**************************************************************************** *ˆDDP_UNSTOP**ˆEntry:‚A5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice***ˆExit:ƒA5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice*A0,A2-A3=don'tcare*D0-D7=don'tcare*?*ˆDDP_UNSTOPisthedevicedependentpartoftheUNSTOProutine ;*ˆinTERMLIB.‚WhenwearenotusingXOFF/XON,weunstoptheF*ˆdeviceinourowndevice-dependentway.‚Whenthisroutineiscalled,5*ˆwearerunninginbackground,atinterruptlevel0.*,*ˆDDP_UNSTOPiscalledbyUNSTOPinTERMLIB.*H**************************************************************************ˆDDP_BEG_BREAK**ˆEntry:‚A5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice**ˆExit:ƒA5=addrofCCB*A0-A4=don'tcare*D0-D7=don'tcare*&*ˆInterruptsareinhibiteduponentry.*6*ˆDDP_BEG_BREAKwriteswhateveritmusttothechipto*ˆtransmitabreak.*?*ˆDDP_BEG_BREAKiscalledbyBEG_BREAK,abackgroundroutinein *ˆTERMLIB.1*ˆDDP_BEG_BREAKiscalledbyTM_BREAKinTERMLIB.*G*************************************************************************ˆDDP_END_BREAK**ˆEntry:‚A5=addrofCCB*A4=addrofdriver!*A1=addrofoursideofdevice**ˆExit:ƒA5=addrofCCB*D0,A0,A1,A4‚=don'tcare(*Allotherregistersmustbepreserved.*&*ˆInterruptsareinhibiteduponentry.*6*ˆDDP_END_BREAKwriteswhateveritmusttothechipto*ˆstoptransmittingabreak.*<*ˆDDP_END_BREAKiscalledbySTOP_BREAK,aspecialinterrupt5*ˆserviceroutineforthetimerinterrupttostopthe.*ˆbreaksignal,ifweareintransparentmode.<*ˆDDP_END_BREAK‚iscalledbyEND_BREAK,abackgroundroutine *ˆinTERMLIB.*‰PAGEC********************************************************************;*ƒDEVICE-DEPENDENTROUTINES‚THATARENOTCALLEDBYTERMLIB,9*ƒBUTNEVERTHELESSNEEDTODOCERTAINTHINGSFORTERMLIB.*C******************************************************************** *DO_INIT:<*‰Thisisthedevicedependentportionoftheinitialization *‰routine. *‰DO_INITmustdothefollowing:*5*ŽPutthestartingaddressofthedriverintotheCCB**ŽLEA…MY_DRVR(PC),A0*ŽMOVE.L‚A0,DRV_ADDR(A5)*A*‚Ifyouareusinganydevice-dependentbackgroundroutines,this#*‚isalsotheplacetosetthemup.*;*ŽSetupanydevicedependentBackgroundActivationBlocks:*)*ŽSET_BAB‚,*5*ŽTogoalongwiththis,thedevicedependentroutine7*Žmusthavesetupanareainthedevice-dependentpart *ŽoftheCCBlikethefollowing:*2*ŽRESERVE.12„DCD_BABƒ(macrodefinedinUTILITY.MC)**!*ŽTheninDO_INITyouwouldhave:*0*ŽSET_BABƒDCD0,DCD‚(macrodefinedinUTILITY.MC)*2*ŽToinvokethebackgroundroutineyouwouldhave:***ŽBKGRND„DCD‡(macrodefinedinUTILITY.MC)*0*ŽAndthestartofyourroutinewouldlooklike:**DCD0:*&*LEA…-DCD_BAB(A1),A5„A5<---CCBaddr2*MOVE.L‚CCBCHB(A5),A1†A1<---addrofoursideof*³device/*MOVE.LƒDRV_ADDR(A5),A4„A4<---addrofdriver$**3*DO_DCD:‚***‘....**“RTSI*************************************************************************‰PAGE** *‚XREF's.**C*‚ThisXREFisfromthedriverlibraryDRVLIB.ROwhichislinkedin*‚atSYSgentime.*0‰XREF†LOGPHYŽConvertlogicaladdresstophysical6‰XREF†I_NRM_QEVENTˆQueueanormalI/Ocompletionevent*¦frominterrupthandler6‰XREF†N_NRM_QEVENTˆQueueanormalI/Ocompletionevent*¦fromcommandlevel.*‰XREF†I_HLT_QEVENTˆQueueanI/Ohaltevent*¦frominterrupthandler*‰XREF†N_HLT_QEVENTˆQueueanI/Ohaltevent*¦fromcommandlevel.4‰XREF†I_UNS_QEVENTˆQueueanunsoliciteddeviceevent*¦frominterrupthandler4‰XREF†N_UNS_QEVENTˆQueueanunsoliciteddeviceevent*¦fromcommandlevel.**A*‚TheseXREF'sarefromtheTCHTYPEmodule,tableofvalidserial*‚portchannels.*/‰XREF†CH_TYPESŒChanneltypesforserialdrivers *¦(table)0‰XREF†NUMTYPESŒNumberofsupportedchanneltypes5‰XREF†NUMBYTESŒNumberofbytesberentryinthetable *(*‚XDEF'Sforthedevice-dependentmodule* ‰XDEF†LOG_ERR ‰XDEF†RESET‰XDEF†TERM_INIT ‰XDEF†TERM_COMMAND‰XDEF†TERM_TBE‰XDEF†TERM_BREAK‰XDEF†TERM_GOT_CHAR‰XDEF†TERM_UNRDY‰XDEF†MARK_DOWN  ‰SECTION14TERMLIB: **‚Identificationmnemonic*‰DC.B†'!TERMLIB'**‚Revisioninfo:*/ŠDC.Bƒ'012185'‹DateoflastassemblyasMMDDYY.1ŠDC.Bƒ''Spaceindicatesnopatchesto.LOfile.)ŠDC.Bƒ'4'MajorVERSAdosrevisionnumber.**%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠPAGEO*********************************************************************************‰NOTESONCODINGSTANDARDS*O******************************************************************************* G*‚BecausethisisanI/Odriver,speedisoftheutmostimportance,andG*‚asaresulttradeoffsweremadedecreasingthestraightforwardnessofL*‚thecodeinfavoroflesstimespentprocessinginterrupts.‚Inparticular,F*‚theinterruptserviceportionofthisdriverisnotatallmodular--H*‚some'routines'havemultipleentryandexitpoints,andreturnisnot*‚alwaystothecaller.*G*‚OnevisualaidusedwhichmaysaveyousomeworkistheuseoflabelsD*‚inexecutablecode.‚Considerthefollowingsampleprogramsegment:*.*‰LABEL1:˜labelaloneonline,followedby':'*‘MOVE.B......7*‰LABEL2:ADD.B‚......Šlabelnotalone,followedby':'-*‰LABEL3‚CMP.B‚......Šlabelnotalone,no':'*F*‚Eachwayofwritingthelabelhasitsownsignificance.‚LABEL1marksC*‚thebeginningofalogicalmodule,andnothingfallsintoLABEL1.G*‚LABEL2isalabelbranchedtofromoutsidethelogicalmodule.‚LABEL3F*‚isa'local'label,branchedtoonlyfromwithinthelogicalmodule.  >*‚Foreachsubroutine,registerusageisspecifiedasfollows:**‰Entry:A5=addressofCCB**‰Exit:‚A0=garbage(*A1=addressofoursideofthedevice*G*‚TheentryconditionsspecifyonlytheREQUIREMENTSoftheroutine.‚InI*‚otherwords,aregistermaybeknowntocontainaparticularvalue,butI*‚ifitisnotusedbyaroutine,itisnotlistedasanentrycondition.J*‚TheexitconditionslistonlythoseregisterswhichCHANGE.‚IntheaboveH*‚example,thefactthatA5isnotlistedasanexitconditionindicates"*‚thatitstillpointstotheCCB.*J*‚Ifamoduledoesnotrepresentasubroutine(thatis,willnotreturntoK*‚thecodeitwasenteredfrom),theexitconditionsfortheregisterswill*‚notbespecified.ŠPAGEO********************************************************************************,*‰TABLEOFSIZESOFCONFIGURATIONPARAMETERS*<*‰UsedbyCMN_CNFGroutinetoisolatethoseparameterswhich9*‰theuserdoesnotwanttochangethroughaCONFIGUREor<*‰CHANGEDEFAULTCONFIGURATIONcommand.‚Eachbyterepresents?*‰thesizeofaconfigurationparameter,andtheyappearinthe.*‰orderinwhichtheyarelaidoutintheCSB.*O******************************************************************************* 8PAR_SIZE:DC.Bƒ2’#ofbytesintheLINEWIDTHparameter.ŠDC.Bƒ4’.‘LINES/PAGEŠDC.Bƒ4’.‘WRITETIMEOUTŠDC.Bƒ4’.‘READ‚TIMEOUTŠDC.Bƒ2’.‘XON/XOFFŠDC.Bƒ1’.‘BREAKEQUIVALENTŠDC.Bƒ1’.‘DISCARDOUTPUTŠDC.Bƒ1’.‘REPRINTLINEŠDC.Bƒ1’.‘CANCELLINEŠDC.Bƒ4’.‘READTERMINATORSŠDC.Bƒ4’.‘END-OF-LINESTRINGŠDC.Bƒ1’.‘BAUDRATEŠDC.Bƒ1’.‘NULPADDINGŠDC.Bƒ1’.‘TERMINATORCLASSŠDC.Bƒ1’.‘TERMINALTYPE%ŠDC.Bƒ0’0Markstheendofthetable.ŠPAGEJ****************************************************************************‰COMMANDTABLE&JUMPTABLE*:*‰Theseareusedbythecommandserviceroutinetojumpto<*‰theappropriateroutinetohandleacommandwhenwe'renot*‰intransparentmode.*8*‰NotethatIOHALT(haltI/O)isnotinthetable--itis*‰checkedforseparately.*J**************************************************************************  ŠDS…0 #CMD_TBL:‚DC.WƒIOWRITWRITEcommand.%ŠDC.WƒIOOWINOUTPUTW/INPUTcommand.ŠDC.WƒIOREADREADcommand.$ŠDC.WƒIOTBRKTRANSMITBREAKcommand.$ŠDC.WƒIOSTATREQUESTSTATUScommand.ŠDC.WƒIOCNFGCONFIGUREcommand. 2ŠDC.WƒIOCHDCCHANGEDEFAULTCONFIGURATIONcommand. ?NUM_CMDS‚EQU„(*-CMD_TBL)/2†Thenumberofcommandsinthetable.    ;JMP_TBL:‚DC.WƒWRITE-*ŒBiasestothecorrespondingroutines.ŠDC.WƒOUTWINP-* ŠDC.WƒREAD-*ŠDC.WƒXMIT_BRK-*ŠDC.WƒREQ_STAT-*ŠDC.WƒCONFIGUR-*ŠDC.WƒCHNG_DEF-*  :JMP_OFFƒEQU„JMP_TBL-CMD_TBL„Offsetbetweenthetwotables.'*§Havingfoundthecommandinthefirst&*§table,thisoffsetisusedtogetto(*§thecorrespondingvalueinthesecond.ŠPAGEJ***************************************************************************1*‰COMMANDTABLE&JUMPTABLEFORTRANSPARENTMODE*:*‰Theseareusedbythecommandserviceroutinetojumpto<*‰theappropriateroutinetohandleacommandwhenwearein*‰transparentmode.*J**************************************************************************  ŠDS…0 TM_CMD_TBL:$ŠDC.WƒIOSTATREQUESTSTATUScommand.2ŠDC.WƒIOCHDCCHANGEDEFAULTCONFIGURATIONcommand. ETM_NUM_CMDSEQU‚(*-TM_CMD_TBL)/2†Thenumberofcommandsinthetable.    TM_JMP_TBL:ŠDC.WƒREQ_STAT-*ŠDC.WƒCHNG_DEF-*   CTM_JMP_OFFEQUƒTM_JMP_TBL-TM_CMD_TBL„Offsetbetweenthetwotables.'*§Havingfoundthecommandinthefirst&*§table,thisoffsetisusedtogetto(*§thecorrespondingvalueinthesecond.ŠPAGEM******************************************************************************"*‰TRANSPARENTMODEINTERFACETABLE*A*‰Whentransparentmodeisselected,theaddressofthistableisA*‰passesbacktotheselectingtask.‚Whenthetask(whichmustbe@*‰quitecareful)wantsustodosomethingforhim,hesetsupA5A*‰andtheSRandthenjumpstotheappropriateBRAnchinstruction*‰inthistable.*M***************************************************************************** TM_TABLE: :ŠBRA.L‚TM_OUTPUTŠBranchtotheroutinewhichoutputsacha9ŠBRA.L‚TM_BREAK‹Branchtotheroutinewhichsendsabreak‰PAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰INITIALIZATIONROUTINE*=*‰Thisroutineiscalledbythedevicedependentmoduleafter.*‰itreceivesaninitializationcallfromCMR.9*‰Itspurposeistosetupthingsforcommandserviceand7*‰interruptservice.‚Themajorfunctionsperformedare:"*Validatethechanneltypefield.1*Fillinthedrivercode,recognizedatrributes,2*“recognizedparameters,andrecognizedbaudrates*“fieldsoftheCCB.7*Getthescheduler'saddressintheCCBforlateruse.+*Getmemoryfortransmit&receivequeues..*Initializeflags,pointers,etc.intheCCB.**Setupthebackgroundactivationblocks.*?*‰Entryisatinterruptlevel0,andweareinsupervisormode.**‰Entry:A5=addressofCCB.*9*‰Exitsto:‚devicedependentmodulewithconditioncodes:"*”and--->ƒbadexeccall*”ƒchannelisdown/*”ƒallwentwell,OKtoproceedwithdevice*›dependentI/O*J**************************************************************************J**************************************************************************J************************************************************************** ‰SECTIONƒ14 ŠDS…0 TERM_INIT:*%%%%%%%%%%%%‚BWNƒ8/3/84*0*‚INHIBITINTERRUPTSUNTILWEAREREADYFORTHEM*‰PUSH†SR‰INHIBIT*%%%%%%%%%%%%%%%%%%%%%%*%%%%%%%%‚BWN8/16/84.ŠCLR.B‚ES_ST(A5)ŠSetESprocessstatetoIDLE. <**ˆMOVE.LA7,STAK_PTR(A5)„SavethestackpointerintheCCB.**F*‚Checkthechanneltypefieldwearesupposedtobetomakesureit's*‚atypethisdriverhandles.*/ŠMOVE.BCCBTYPE(A5),D0…D0<--ourchanneltype.7ŠLEA„CH_TYPES,A0ˆA0<--addroftableofchanneltypes.*%%%%%%%%%%%‚BWN‚7/16/84@**ˆMOVE.W#NUMTYPES-1,D1…D1<--loopcontrolfortableoftypes.  @**CHK_TYPE‚CMP.B‚(A0)+,D0‹Checkwhetherourtypeisinthelist.**ˆDBEQƒD1,CHK_TYPEˆ*‰FOR.W…D1=#1‚TO‚#NUMTYPESƒDO“CMP.Bƒ(A0)+,D0 “BEQ‡CH_FOUND“ADD.L…#NUMBYTES-1,A0‰ENDFG*************************************************************************„BADCHANNELTYPE!!!*F**********************************************************************(*£Ifit'snot(badchanneltype),setupCŠMOVE.B#ISTAICE,DOWN_ERR(A5)‚toreturnIndeterminateChannelError@ŠMOVE.B#M_DOWN,MENU(A5)ƒforallrequests,markthechanneldown*%%%%bwn8/13/84“inthemenu,‰POP‡SR)‰MOVE.B„#-1,D0‹Setconditioncodeto#ŠRTS—andreturntocallingroutine.*£*@******************************************************************…GOODCHANNELTYPE!!!*9*********************************************************CH_FOUND*=*‚Wegotherebecausewefoundthechanneltypeinthetable.:*‚A0isnowpointingtotheDrivecodeentryinthetable.**’Channeltypeˆ(byte)*ˆA0---->‚DriveCodeŠ(byte)*’Recognizedattributesƒ(word)*’Recognizedparametersƒ(word)"*’Recognizedbaudrate„(longword)*‰MOVE.B„(A0)+,DRV_CODE(A5)‰MOVE.W„(A0)+,REC_ATT(A5)‰MOVE.W„(A0)+,REC_PAR(A5)‰MOVE.L„(A0)+,REC_BAUD(A5)**+*‚Getthescheduler'saddressintoSCHED_EP*;‰MOVE.L„#T0SCHED,D1‰D1<---directivewhoseaddresswewant+‰MOVE.L„#T0ENTRY,D0‰D0<---ENTRYdirective‰TRAP†#0 ‰BRA.S…EXISTS*=***************************************************************‚BADEXECCALL,SENDBACK*9**********************************************************‚Enableinterrupts*‰POPˆSR ‰MOVE.B…#1,D0‰RTS 9***********************************************************‚GOODEXECCALL*8********************************************************EXISTS,‰MOVE.L„A0,SCHED_EP(A5)…A0hasentryaddress '*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   **‚Dosomeotherinitialization.*7ŠCLR.L‚MENU(A5)‹Clearoutthemenu(notdoinganyI/O).*%%%%%%%%%%%% BWN 7/9/84;**ˆSF…BKG_ACTV(A5)‡Markthatthebackgroundisnotrunning.*%%%%%%%%%%%%%%%M******************************************************************************@*ˆFillinthebackgroundactivationblockswiththeiraddresses.*ˆ(DEVICEINDEPENDENT)*M*****************************************************************************‰SET_BABƒRECV0,RECV‰SET_BABƒBREAK0,BREAK‰SET_BABƒBLOCK0,BLOCK‰SET_BABƒUNBLOCK0,UNBLK‰SET_BABƒXMIT0,XMIT‰SET_BABƒSTOP_IT0,STOP‰SET_BABƒB_BRK0,B_BRK‰SET_BABƒE_BRK0,E_BRK*%%%%%%%%%%%%%%%%%%%%**‚Determinetheboardtype.,*‚WehavetogetthechanneltypebackinD0**7***‡MOVEQ‚#$06,D0ŒD0<--bits1and2oftheporttype.***‡AND.B‚CCBTYPE(A5),D0…* ŠMOVE.B‚CCBTYPE(A5),D0ŠLSR.B‚#1,D0Ž*(ŠMOVE.BD0,BOARD(A5)‡SaveitintheCCB.**‚Setconditioncodes** Enable interrupts*‰POP‡SR ‰MOVE.B„#0,D0 ‰RTS ŠPAGEJ**************************************************************************J**************************************************************************J****************************************************************************‰COMMANDSERVICEROUTINE*=*‰WegotherethroughaBSRfromthedevicedependentmodule,*‰andwillexitwithanRTS.?*‰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/*A6=physicaladdressofTCBofattachedtask*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************************************************************************** TERM_COMMAND:  :ŠMOVE.LA7,STAK_PTR(A5)„SavethestackpointerintheCCB. 5*%%%%%%%%%%%‚BWN8/16/84‚MOVEDTHISHEREFROMMPSCDRV*C*‚Nowthatwehavereceivedacommand,weknowthereissomeoneoutI*‚theretotalkto.‚Iftheguywhoreportsbreaksisasleep,wakehimup.*DŠMOVE.B#S_REPORT,ES_ST(A5)Reportincomingbreakstoattachedtask.**%%%%%%%%%%%%%%%%%%%%%%  FŠMOVE.LXIOUID(A2),DCB_ADDR(A5)SaveCMRPARAMBLOCKID(sincewe'rea)*§standardchannel,that'stheDCBaddr). *:*‚GetphysicaladdressofIOCB(nopossibilityoferroron(*‚this--IOShasvalidatedIOCBaddress).*5ŠMOVE.LXIOCPK(A2),D6†D6<--logicaladdressofIOCB. ŠCLR.L‚D5‘D5<--length‚ofIOCB.ŠMOVE.WXIOPLN(A2),D5†*5ŠMOVE.LCCBTASKA(A5),A1„A1<--addressoftask'sTCB.5ŠBSR.L‚BUF_ADDR‹Callexecroutinetoconvertaddress..ŠMOVE.LD6,A3ŽA3<--physicaladdressofIOCB. *0*‚Ifthechannelisdown,exitwithdownstatus.*+ŠMOVE.BDOWN_ERR(A5),D1„D1<--downstatus.ŠIF…THENŠIfwearedown,CŠMOVE.LA3,IOCB_ADR(A5)„savetheIOCBaddressandexitimmediately,6ŠBRA„NRM_EXIT‹queuingacompletioneventwiththedown ŠENDI–status. *G*‚Searchforthecommand.‚Weuseadifferenttabledependingonwhether$*‚ornotweareintransparentmode.*.ŠMOVE.WIOSFCT(A3),D6†D6<--functionofIOCB.0ŠTST.B‚TR_MODE(A5)ˆIfwe'reintransparentmode,ŠIF…THENŠ* 1ŠMOVEQ‚#TM_NUM_CMDS-1,D0‚Setuptheloopcounter.?ŠMOVEQ‚#TM_JMP_OFF,D1…D1<--offsetbetweencmdandJMPtables.:ŠLEA„TM_CMD_TBL,A0†A0<--addressofcommandtableforTM. +ŠELSE–Else(we'renotintransparentmode), *;*…CheckfortheonecommandwhichcanarriveevenwhileI/O:*…isinprogress:‚HALTI/O.‚Ifit'snotHALTI/O,savethe;*…TCBaddresssowe'llhaveitevenifaHALTI/Ocomesin.*8ŠCMP.W‚#IOHALT,D6‰IfthisisaHALTI/Ocommand,gohalt/ŠBEQ.L‚HALTtheI/OwithoutlosingTCBaddress. =ŠMOVE.LA3,IOCB_ADR(A5)„SaveaddressofIOCBandowner'sTCB.!ŠMOVE.LCCBTASKA(A5),TCB_ADDR(A5) .ŠMOVEQ‚#NUM_CMDS-1,D0…Setuptheloopcounter.<ŠMOVEQ‚#JMP_OFF,D1ˆD1<--offsetbetweencmdandJMPtables.0ŠLEA„CMD_TBL,A0‰A0<--addressofcommandtable. ŠENDI 9CMD_SRCH‚CMP.W‚(A0)+,D6‹Searchthetableforthecommand.ŠDBEQƒD0,CMD_SRCHˆ* 3ŠIFTHENŽIfwefoundthecommandinthetable,8ŠADD.W‚-2(A0,D1),D1‡getthecorrespondingentryfromthe4ŠJMP„-2(A0,D1)ŠjumptableandjumptotheroutinetoŠENDI–handlethecommand. 3ŠPUT_BYTEISTAIF,D1ˆWedidn'tfindit,soexitwith *§INVALIDFUNCTIONstatus.‚(Just'*§fallthroughtoNORMALEXITroutine.)ŠPAGEJ***************************************************************************µ**‰NORMALEXIT”*ƒNOTE:‚the*µ*ƒCOMMANDcode7*‰Youcomehereifyouhavecompleteda‡*ƒfallsthrough7*‰commandwithoutdoingI/O.‚Thiscode‡*ƒintothiscode:*‰preparesacompletioneventandinvokes…*ƒifthecommand-*‰thebackgroundtosendit.’*ƒintheIOCBis*µ*ƒnotvalid!'*‰Entry:D1.W=statusvalueforIOCB‰**A5ƒ=addressofCCB**µ*J**************************************************************************  **‚UpdateIOCBstatus.*8NRM_EXIT:MOVE.LIOCB_ADR(A5),A4„A4<--addressofIOCB..ŠMOVE.BD1,IOSSTA(A4)†Statusfield<--status. **‚Preparecompletionevent.*4ŠLEA„EVENT(A5),A0‡PrepareaNORMALcompletionevent:"ŠMOVE.B#10,(A0)‹sizeis10bytes;0ŠMOVE.B#XPSNRM,XRPSTA(A0)eventtypeisNORMAL;+ŠMOVE.WD1,XRPSTV(A0)†setthestatusvalue; *%*‚Usecall-guardedtosendtheevent.*‰LEA‡DO_EVENT(PC),A0‰MOVE.L„#T0GUARD,D0‰TRAP†#0‰BRA.L…CMD_EXIT  ŠPAGEM*******************************************************************************‰TRANSMITBREAKSIGNAL*=*‰ThisistheroutinethathandlesanIOTBRKcommand.‚Itjust<*‰callsthebackgroundroutineBEG_BREAK(beginbreak)todo ;*‰allthework.‚Thebreakisstoppedwhenatimerinterrupt%*‰passescontroltoroutineSTOP_BRK.**‰Entry:*A5=addressofmyCCB*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*M***************************************************************************** XMIT_BRK: *%%%%%%%%%%%% BWN 7/9/84*B**ˆBSETW‚#W_BEG_BREAK,WORK(A5)‚Markworkfortheguywhostartsus*§transmittingabreaksignal.+**ˆINHIBIT“Inhibitinterruptsatthislevel,**ˆBRA.L‚CALL_BKG‹andinvokethebackground.**‚Usecallguarded**?‰MOVE.L„CCBCHB(A5),A1„A1<---addressofoursideofthedevice=‰MOVE.L‚DRV_ADDR(A5),A4„A4<--driveraddressforT_JSRmacro‰LEA‡BEG_BREAK(PC),A0‰MOVE.L„#T0GUARD,D0‰TRAP†#0‰BRA.L…CMD_EXIT ŠPAGEM*******************************************************************************‰REQUESTSTATUS*-*‰ThisisthehandlerfortheIOSTATcommand.@*‰Wejustcopythecurrentconfiguration(inCCB)tohisCSBand*‰providestatusinfo.*$*‰Entry:A3=addressofuser'sIOCB*A5=addressofmyCCB**‰ExitstoNRM_EXIT<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*M***************************************************************************** REQ_STAT: *E*‚Gettheaddressofhisdatablockandmoveourconfigurationthere.*?ŠMOVE.LIOSDBP(A3),D6†D6<--logicaladdrofuser'sdatablock./ŠMOVE.L#IOSTLN,D5‰D5<--lengthofdatablock.2ŠMOVE.LTCB_ADDR(A5),A1„A1<--addressofhisTCB.2ŠBSR.L‚BUF_ADDR‹ConvertittophysicalandputtheŠMOVE.LD6,A1ŽresultinA1. *8*‚Thefirst8bytesoftheCSBarenotmaintainedinthe3*‚CCB,sowemanufacturethatparthereonthefly.*=‰MOVE.L‚DRV_ADDR(A5),A4„A4<--driveraddressforT_JSRmacro‰T_JSRƒGET_STAT(ŠMOVE.BD0,IOSDST(A1)†SetDEVICESTATUS.0ŠMOVE.BCCBTYPE(A5),IOSCTP(A1)‚SetCHANNELTYPE.9ŠMOVE.B#XDSACIA,IOSDTP(A1)SetDEVICETYPEtoACIA-like.6‰MOVE.B‚DRV_CODE(A5),IOSDRC(A1)SetupthedrivercodeAŠMOVE.WREC_ATT(A5),IOSATM(A1)Setmaskofrecognizedattributes.<ŠMOVE.WREC_PAR(A5),D0‰D0<--maskofrecognizedparameters.8ŠMOVE.WD0,IOSPRM(A1)†Setmaskofrecognizedparameters. *B*‚TherestisjusttheconfigurationinfokeptintheCCB,soloopA*‚tofillintherestoftheblockstartingwithATTRIBUTESWORD.*5ŠLEA„CNFG(A5),A0ˆA0<--addressofCCBconfiguration.7ŠLEA„IOSATW(A1),A1†A1<--addressofhisconfiguration. >ŠMOVE.L#(IOSTLN-IOSATW)/2-1,D0ƒD0<--#ofwords-1tomove.(REQ_LOOP‚MOVE.W(A0)+,(A1)+ˆMoveaword.6ŠDBRAƒD0,REQ_LOOPˆKeepmovinguntilwholeblockmoved. (ŠPUT_BYTEISTAOK,D1ˆExitwithOKstatus.ŠBRA.L‚NRM_EXIT‹*ŠPAGEM****************************************************************************** *‰CONFIGURE*:*‰ThisisthehandlerfortheIOCNFGcommand.‚Thisroutine>*‰changestheCCBconfiguration,theonefromwhichthedriver9*‰setsupthedeviceandunderwhichitperforms.‚Thenew!*‰infocomesfromtheuser'sCSB.*$*‰Entry:A3=addressofuser'sIOCB%*A2=addressofCMRparameterblock*A5=addressofmyCCB*M***************************************************************************** CONFIGUR: <ŠLEA„CONFIG(A5),A0†A0<--addrtouseforCCBconfiguration.1ŠMOVE.LXIOUID(A2),A4†A4<--baseaddressofDCB. *G*‚Putthetimeoutvalues(locatedintheDCB)intheconfigurationareaD*‚oftheCCBsothatwecanjustcopythewholeconfigurationtohis.*‚CSB.‚Thendothecommonconfigurationstuff.*DŠMOVE.LDCBDEV+IOSWTO(A4),IOSWTO(A0)TransferwriteandreadtimeoutDŠMOVE.LDCBDEV+IOSRTO(A4),IOSRTO(A0)valuesfromtheDCBtotheCCB. ?ŠMOVE.W#1<THENŠfortransparentmode, ?ŠBTSTW‚#IOATRM,IOSATW(A0)Seewhetherwe'reintransparentmode.ŠSNE„TR_MODE(A5)ˆandsettheflagaccordingly.ŠIF…THENŠIfweare, *F*‚ValidateandconverttophysicaltheaddressofhisTMbranchtable.*9ŠMOVE.LIOSTMU(A0),D6†D6<--addrofhisTMbranchtable.1ŠMOVEQ‚#HIS_TM_LEN,D5…D5<--lengthofthetable./ŠMOVE.LTCB_ADDR(A5),A1„A1<--addrofhisTCB.CŠBSR.L‚GET_PHYSICAL_ADDRESS‚Calltheexectovalidate&convertit.$ŠIF…THENŠIftheaddressisbad,:ŠMOVEQ‚#CECTMA,D7‰ExitwithTRANSPARENTMODEADDRESSerrorŠBRA.L‚BAD_CNFG‹intheCSB.ŠENDI–*EŠMOVE.LD6,HIS_BRA_TBL(A5)Savethelogicaladdrofhisbranchtable. 6ŠPEA„TM_TABLE(PC)‡GivehimbacktheaddrofourbranchŠPOP.L‚IOSTMD(A0)‰table,ŠMOVE.LA5,IOSTMA(A0)†ourA5,DŠMOVE.WCCBISR(A5),IOSTMS(A0)‚andtheSRwewanttobeenteredwith. ŠENDI ŠENDI *2*‚CopythenewdefaultconfigurationintotheDCB.*?ŠMOVE.LCSB_ADDR(A5),A0„A0<--addressofstufftocopyinCSB.'**ˆBSR.L‚GET_STAT‹D0<--devicestatus. ‰PUSH.L‚A4=‰MOVE.L‚DRV_ADDR(A5),A4„A4<--driveraddressforT_JSRmacro‰T_JSRƒGET_STAT ‰POP.LƒA4(ŠMOVE.BD0,IOSDST(A0)†SetDEVICESTATUS.ŠLEA„IOSATW(A0),A0†*AŠLEA„DCBDEV+IOSATW(A4),A1‚A1<--addrofstufftocopytoinDCB.>ŠMOVE.L#(IOSTLN-IOSATW)/2-1,D0‚D0<--#ofwordstomove-1. -CDEFLOOP‚MOVE.W(A0)+,(A1)+ˆKeepmovingwords1ŠDBRAƒD0,CDEFLOOPˆuntilthewholeblockismoved. *B*‚NowjustletNRM_EXITtakecareofsendingthecompletionevent.*.ŠPUT_BYTEISTAOK,D1ˆSetgoodcompletionstatusŠBRA„NRM_EXIT‹andexit.ŠPAGEM******************************************************************************,*‰SUBROUTINETODOCOMMONCONFIGURATIONWORK*7*‰Thisroutinedoestheworkcommontothetwocommands-*‰CONFIGUREandCHANGEDEFAULTCONFIGURATION.**‰Entry:3*D0.W=maskofrecognizedattributeswhichcannot*—bechangedwiththiscommand.3*D1.W=maskofrecognizedparameterswhichcannot*—bechangedwiththiscommand.'*A0ƒ=addressofcurrentconfiguration*A3ƒ=addressofuser'sIOCB*A4ƒ=baseaddressofDCB*A5ƒ=addressofCCB**‰Exitifnoerror:**D1=ISTAOK(statusindicatingnoerror)  *D0,D5,D6,D7,A0,A1,A2=garbage**‰Exitifanyerror:*D1=errorcodeforIOCB *D0,D5,D6,D7,A0,A1,A2=garbage4*branchestoNRM_EXIT;stackwillberestoredthere*M***************************************************************************** CMN_CNFG: *J*‚Firstgetthephysicaladdressoftheuser'sConfiguration/StatusBlock.*4ŠMOVE.LIOSDBP(A3),D6†D6<--logicaladdressofCSB.,ŠMOVE.L#IOSTLN,D5‰D5<--datablocklength.2ŠMOVE.LTCB_ADDR(A5),A1„A1<--addressofhisTCB.7ŠBSR.L‚BUF_ADDR‹Verify&converttophysicaladdresses.-ŠMOVE.LD6,A1ŽA1<--physicaladdressofCSB.+ŠMOVE.LA1,CSB_ADDR(A5)„SaveitintheCCB. *H*‚Firstcheckwhetherhe'stryingtochangeanyparametersorattributesK*‚whichareillegalbecauseit'saCONFIGUREcommand.‚TheappropriatemasksJ*‚forthechecksareinD0.W(attributes)andD1.W(parameters)--a1bitG*‚inthemaskindicatesthatthecorrespondingitemmayNOTbechanged.*-ŠMOVEQ‚#CECCDO,D7‰PreloadD7witherrorcode. 9ŠAND.W‚IOSATM(A1),D0†Ifhe'schangingattributeshe'snot-ŠBNE.L‚BAD_CNFG‹supposedto,that'sanerror. 9ŠAND.W‚IOSPRM(A1),D1†Ifhe'schangingparametershe'snot-ŠBNE.L‚BAD_CNFG‹supposedto,that'sanerror. *F*‚Nowcheckthathe'snottryingtochangeanyUNRECOGNIZEDattributesF*‚orparameters.‚Notethatthiscanvarydependingontheboardtype--6*‚baudratemaynotbechangedviasoftwareonaVM02.*-ŠMOVEQ‚#CECUAP,D7‰PreloadD7witherrorcode. *%%%%%%%%%ŠMOVE.W#$FFFF,D0ŠSUB.W‚REC_ATT(A5),D0 *%%%%%%%%%% >***‡MOVE.W#UNR_ATT,D0ˆD0<--maskofunrecognizedattributes.9ŠAND.W‚IOSATM(A1),D0†Ifhespecifiedanyofthese,that'sŠBNE.L‚BAD_CNFG‹anerror. *%%%%%%%%%ŠMOVE.W‚#$FFFF,D0ŠSUB.WƒREC_PAR(A5),D0<*‰MOVE.W#UNR_PAR,D0ˆD0<--maskofunrecognizedparameters. *%%%%%%%%%%9ŠAND.W‚IOSPRM(A1),D0†Ifhespecifiedanyofthese,that'sŠBNE.L‚BAD_CNFG‹anerror. *F*‚Firstweneedtoseewhathisproposedconfigurationwilllooklike.D*‚Plugintohisdatablockthecurrentvaluesforthoseattributes&?*‚parametershedoesn'twanttochange.‚Theappropriatecurrent>*‚configurationisatA0andhe'satA1.‚Firsttheattributes.*1ŠMOVE.WIOSATM(A1),D0†D0<--hisattributesmask.;ŠAND.W‚D0,IOSATW(A1)†Zeroouttheattributesofhisthathe.ŠNOT.W‚D0‘doesn'twanttochange,zerooutthe<ŠAND.W‚IOSATW(A0),D0†attributesofminethathedoeswantto:ŠOR.WƒD0,IOSATW(A1)†change,andcombinetheminhisspace. **‚Nowtheparameters.*?ŠMOVE.WIOSPRM(A1),D0†D0<--maskofparamshewantstochange.2ŠPUSH.LA0‘Savetheconfigurationblockaddresses. ŠPUSH.LA1‘*3ŠLEA„IOSREC(A0),A0†A0<--addrof1stparaminCCB.?ŠLEA„IOSREC(A1),A1…A1<--addrof1stparaminuserdatablock.5ŠLEA„PAR_SIZE,A2ˆA2<--addroftableofparamsizes. .NXT_PARM‚CLR.L‚D1‘ClearD1toholdwordvalue.1ŠMOVE.B(A2)+,D1‹D1<--#ofbytesinnextparam./ŠBEQ„CHK_PARM‹Endofparametersismarkedby0. 5ŠLSR.W‚#1,D0ŽCheckthenextbitintheparammask.‚If:ŠIF…THEN‰it'snotset(hedoesn'twanttochangeit),5ŠSUBQƒ#1,D1ŽthenmovetheparamfromtheCCBintohisŠAND.W‚IOSATW(A1),D0†ushe'susingamodembutdoesn'twantus>ŠCMP.W‚#1<#$0FTHEN‚Ifhedidn'tspecifyone, >ŠBTSTW‚#IOATFUL,IOSATW(A1)‚andwearen'tsupposedtoterminateŠIF…THENŠonbufferfull,0ŠTST.L‚IOSRTV(A1)‰andhedidn'tspecifyanyREAD2ŠBEQ„BAD_CNFG‹TERMINATORS,that'sanerror(nowayŠENDI–toterminatearead). .ŠELSE–Else(hedidspecifyaTERMINATOR-CLASS) 8ŠPUT_BYTE$F0,D1‹Isamatchpossibleusingthesevalues?ŠAND.B‚D0,D1ŽD1<--maskvalue. ŠLSL.B‚#4,D0ŽD0<--matchvalue.$ŠAND.B‚D0,D1ŽD1<--mask.AND.match.ŠCMP.B‚D0,D1Ž(ifmask.and.match<>match,go4ŠBNE„BAD_CNFG‹signalerrorsincematchnotpossible) ŠENDI–* ***** (*§Iftherewillonlybe7bits/char,butEŠBTSTW‚#IOABITS,IOSATW(A1)theonlypossibleterminationisonachar7ŠIFTHENŽwiththehighbitset,that'sanerror...*DŠIF.BIOSTRC(A1)#$0FTHEN‚IfaTERMINATOR-CLASSwasspecified,=ŠBTST.B#3,IOSTRC(A1)†checkwhetherthehighbitofthematch0ŠBEQ„OK_CNFGŒvalueisa0.‚Ifso,terminationis'ŠENDI–possible,soconfigurationisOK. :ŠMOVE.LIOSRTV(A1),D0†Ifthatdidn'tsaveus,wemustlook=CHK_NEXT‚ROL.L‚#8,D0ŽthroughtheREADTERMINATORSforavalue5ŠBEQ„BAD_CNFG‹withthehighbita0.‚Remembertostop-ŠBPL„OK_CNFGŒlookingwhenweencountera$00. ŠCLR.B‚D0‘*ŠBRA„CHK_NEXT‹* ŠENDI *D*‚Looksgood;fillinsomefieldsattheverytopofhisCSB&exit.*OK_CNFG0ŠMOVE.BCCBTYPE(A5),IOSCTP(A1)‚SetCHANNELTYPE.9ŠMOVE.B#XDSACIA,IOSDTP(A1)SetDEVICETYPEtoACIA-like.*%%%%BWN‚6/25/84ŠMOVE.WDRV_CODE(A5),D0 *%%%%%%%%%ŠMOVE.BD0,IOSDRC(A1)‡SetDRIVERCODE 6ŠST…DCBCCF(A4)‰FlagtheDCBthataCONFIGUREorCHANGE+ŠRTS—DEFAULTCONFIGURATIONwasdone&exit.   *C*‚Configurationerror!‚D7hasspecificerrorcode,sostickthatin4*‚hisCSB.‚ThenexitwithCONFIGURATIONERRORinD1.*;BAD_CNFG:MOVE.BD7,IOSCEC(A1)†Setthespecificerrorcode. 8ŠPUT_BYTEISTACNF,D1‡SetstatustoINVALIDCONFIGURATION2ŠBRA.L‚NRM_EXIT‹FORDEVICEandexittosendevent.ŠPAGEL******************************************************************************‰READCOMMAND*=*‰ThisisthehandlerfortheIOREADcommand.‚Convertsbuffer?*‰addressesandsetsupmenuandpointerstodoreadoperation.9*‰ThenstartstheI/Oincasethere'salreadydatainthe*‰receivequeue.**‰Entry:A3=addressofIOCB*A5=addressofCCB*:*‰ExitstoNRM_EXITifthere'sanerror,elsetoSTART_IO.<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*L**************************************************************************** READ: 7ŠBSR.L‚IO_COMNŒDothestuffcommontoallI/Ocommands.CŠMOVEM.LD4-D6,READ_BUF(A5)‚Savetheaddressesforthereadbuffer. 3ŠBSR„RD_COMNŒDothestuffcommontoREADandOUTPUT*§W/INPUTcommands. *+*‚Setupthemenuandstartthingsrolling.* *ŠINHIBIT“Inhibitinterruptsatthislevel. >ŠBTSTW‚#IOPFORB,IOSOPT(A3)‚Setupmenuwith2nditem=ENDand3ŠIF…THENŠ1stitem=(dependingonoptionsset)-ŠMOVE.W#M_IMGRD<<8+M_END,MENU(A5)ƒIMAGEREADŠELSE–or1ŠMOVE.W#M_FRMRD<<8+M_END,MENU(A5)ƒFORMATTEDREADŠENDI (ŠBRA„START_IO‹GostarttheI/Oandexit.ŠPAGEL*****************************************************************************/*‰SUBROUTINETODOWORKCOMMONTOREADCOMMANDS*?*‰ThissubroutineiscalledbythehandlersforREADandOUTPUT@*‰W/INPUTcommands,anddoestheworkcommontothembothwhich#*‰isassociatedwiththereadpart.**‰Entry:A3=addressofIOCB*A5=addressofCCB **‰Exit:*L**************************************************************************** RD_COMN: *ŠST…INPUT(A5)ŠFlagthatwe'redoingINPUT.6ŠST…INHIB_DO(A5)‡FlagthatDISCARDOUTPUTnotallowed.5ŠSF…DISCARD(A5)ˆClearthe'discardoutput'condition.;ŠCLR.L‚CHAR_CNT(A5)‡Setthecountofchar'sonscreento0. **‚Shouldweecho?*.ŠSF…ECHO(A5)‹Fornow,flagthatwewon'techo. @ŠBTSTW‚#IOPECHB,IOSOPT(A3)‚IftheoptiontosuppressechoisnotŠIF…THENŠset, ?ŠBTSTW‚#IOAECHO,CONFIG+IOSATW(A5)‚Ifweareconfiguredtoecho,%ŠSEQ„ECHO(A5)‹flagthatwewillecho. ŠENDI–* ŠRTS—Return.ŠPAGEL******************************************************************************‰WRITE*?*‰ThisisthehandlerfortheIOWRITcommand.‚Itsetsupbuffer>*‰addresses,menu,etc.todothewrite,andstartstheI/Oby#*‰transmittingthefirstcharacter.**‰Entry:A3=addressofIOCB*A5=addressofCCB**‰Exit:+*goestoNRM_EXITiferror,elseSTART_IO.<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*L**************************************************************************** WRITE: 5ŠBSR„IO_COMNŒDothestuffcommontoallI/Ocommands.@ŠMOVEM.LD4-D6,WRIT_BUF(A5)‚Savethebufferaddressesforwrite. *'*‚Clearthe'discardoutput'condition?**ŠINHIBIT“Inhibitinterruptsatthislevel. :ŠBTSTW‚#IOPCDOB,IOSOPT(A3)‚Iftheoptionssaytoclearthe0ŠIF…THENŠcondition,thenresettheflagand4ŠSF…DISCARD(A5)ˆmarkthatthefunctionisinhibited.ŠST…INHIB_DO(A5)‡*ŠENDI–* **‚Setupthemenu.*>ŠBTSTW‚#IOPFORB,IOSOPT(A3)‚Setthe2ndmenuitem=ENDandthe4ŠIF…THENŠ1stmenuitem=(dependingonoptions)/ŠMOVE.W#M_IMGWRT<<8+M_END,MENU(A5)‚IMAGEWRITEŠELSE–or3ŠMOVE.W#M_FRMWRT<<8+M_END,MENU(A5)‚FORMATTEDWRITEŠENDI–* */*‚FallthroughtotheroutinetostarttheI/O.*ŠPAGEK****************************************************************************®*!*‰STARTTHEI/O˜*ƒNOTE:‚theWRITE*®*ƒroutinefallsthrough5*‰Startupthedatatransfer.‚Marksƒ*ƒintothiscode.&*‰theI/Ointheguy'sTCB,preparesƒ*&*‰theenvironmentforthebackgroundƒ*'*‰partoftheinterruptservicetour,‚**‰andcallsit.˜**®**‰Entry:A5=addressofCCB‹**®* *‰Exit: **D0,A0,A1aregarbageˆ**BranchestoCMD_EXITŠ**®*J************************************************************************** *+*‚MarkthistaskashavingoutstandingI/O!*DSTART_IO:MOVE.LTCB_ADDR(A5),A1„IncrementtheoutstandingI/Ocount)ŠADD.B‚#1,TCBIOCNT(A1)„intheuser'sTCB.*%%%%%%%%%%%%%%% BWN 7/9/84?**ˆBSETW‚#W_XMIT,WORK(A5)ƒMarkworkforthetransmitroutineso*G*‚Beforewegothere,weinhibitedinterruptstomessaroundwithmenu./*‚Nowwemustunmaskbeforewedocall-guarded.*‰UNMASK‰LEA‡CALL_XMIT(PC),A0‰MOVE.L#T0GUARD,D0‰TRAP†#0*C*ƒNowwehavestartedofftheI/OandarereadytoreturntoCMRto(*ƒbeawakenedwhenaninterruptarrives.**E*‚NowreturntoCMRwithD0indicatingthatthecommandwasaccepted.*:CMD_EXIT:MOVEQ‚#0,D0ŽD0<--codetellingCMR'itwasOK.'5ŠMOVE.LSTAK_PTR(A5),A7„Restorethestackpointerand*%%%%%‚BWN‚8/13/84ŠRTS—returntoCMR.ŠPAGEL*****************************************************************************3*‰SUBROUTINETODOWORKCOMMONTOALLI/OCOMMANDS.*=*‰ThisroutineiscalledbythehandlersforREAD,WRITE,and9*‰OUTPUTW/INPUTcommands.‚Itensuresthatthedeviceis<*‰readyforI/O,getstheaddressofthebufferowner'sTCB,-*‰andgetstheaddressoftheprimarybuffer.**‰Entry:A3=addressofIOCB*A5=addressofCCB**‰ExitifallwentOK:*A0=garbage*=*‰Exitiferrorencounteredonexeccallordevicenotready:**branchtoNRM_EXITwitherrorcodeinD1*L****************************************************************************  IO_COMN: *+*‚Checktomakesuretheterminalisready.*=‰MOVE.L‚DRV_ADDR(A5),A4„A4<--driveraddressforT_JSRmacro‰T_JSRƒGET_STAT:ŠBTSTƒ#XDSNRB,D0‰Ifthedeviceisnotready(eitherDSRisDŠIFOR.BAUTO_BAUD(A5)#0THEN‚loworwe'rebusydetecting*§thebaudrate),5ŠPUT_BYTEISTANR,D1ˆsetthecompletioncodeandexit.ŠBRA„NRM_EXIT‹*ŠENDI–* *2*‚TakeoptionsandbufferaddressesfromhisIOCB.*?ŠMOVE.WIOSOPT(A3),OPTIONS(A5)‚Getacopyofhisoptionsfield. ?ŠBTSTW‚#IOPTSKB,IOSOPT(A3)Ifthebuffersresideinadifferent!ŠIF…THENŠtaskfromtheIOCB, 9ŠLEA„IOSTSK(A3),A0†Pointtothetaskname&sessionofthe7ŠTR0$.GETTCB‚,Œbufferowner&callexectogetaddress.!ŠBRA„OK_TCBIfit'sgood,branch.7ŠPUT_BYTEISTAADD,D1‡Ifit'sbad,setstatusinIOCBto.ŠBRA.L‚NRM_EXIT‹ADDRESSERRORandexittoCMR. ;OK_TCB„MOVE.LA0,TCB_ADDR(A5)„SavephysicaladdressofTCB. ŠENDI  <ŠCLR.L‚XFER_LEN(A5)‡Initializethe'#ofbytestransferred'. *<*‚ValidatetheinfointheIOCBabouttheprimarybufferand *‚converttophysicaladdresses.*;ŠMOVE.LIOSSAD(A3),D6†D6<--bufferphysicalstartaddress.+ŠMOVE.LIOSEAD(A3),D5†D5<--bufferlength.ŠSUB.L‚D6,D5Ž* ŠADDQƒ#1,D5Ž*2ŠMOVE.LTCB_ADDR(A5),A1„A1<--addressofhisTCB..ŠBSR„BUF_ADDR‹Callroutinetoconvertaddress.ŠRTSŠPAGEK****************************************************************************/*‰VALIDATEBUFFERADDRESS&CONVERTTOPHYSICAL*9*‰Convertsalogicaladdressforataskintoitsphysical2*‰addressandhandleserrors.‚Becausethisroutine7*‰exitsdirectlytoNRM_EXIT(whereIOCBstatusisset)6*‰ifanerroroccursontheexeccall,itassumesthat3*‰theIOCBexistsattheaddressinIOCB_ADRifthe!*‰addressisfoundtobeinvalid.*$*‰Entry:D5=bufferlengthinbytes-*D6=bufferlogicalstartaddr(toconvert)/*A1=addressofTCBoftaskcontainingbuffer*A5=addressofCCB**‰Exitifaddressisgood:$*D4ƒ=bufferphysicalstartaddress"*D5ƒ=bufferphysicalendƒaddress$*D6ƒ=bufferphysicalstartaddress*RTStocallingtask**‰Exitifaddressisbad:/*ExitstoNRM_EXITw/ISTAADDerrorcodeinD1*K*************************************************************************** BUF_ADDR: *0*‚Calltheroutinethatactuallycallstheexec.*<ŠBSR„GET_PHYSICAL_ADDR‚Convertthelogicaladdrtophysical.#ŠIF…THENŠIfthereisanerror, 7ŠPUT_BYTEISTAADD,D1‡SetstatustoADDRESSERRORandgo3ŠBRA.L„NRM_EXIT‰tothenormalcommandexitroutine. ŠENDI *L*‚ThebufferisOK;itsphysicaladdrisinD6.‚SetupaddressesinD4/D5/D6?*‚sothecallercanusethemtoinitializepointersintheCCB.*3ŠMOVE.LD6,D4ŽD4<--bufferphysicalstartaddress./ŠADD.L‚D6,D5ŽD5<--bufferphysicalendƒaddress*ŠSUBQ.L#1,D5Ž*ƒ=startaddr+length-1. ŠRTS—Return.ŠPAGEK****************************************************************************=*‰GET_PHYSICAL_ADDRESS--DOLOGICALTOPHYSICALCALLTOEXEC*6*‰DoesanexecLOGPHYcalltocheckouttheaddressof*‰abufferorparameterblock.*$*‰Entry:D5=bufferlengthinbytes-*D6=bufferlogicalstartaddr(toconvert)/*A1=addressofTCBoftaskcontainingbuffer*A5=addressofCCB*0*‰Exit:‚CCR:=physicaladdressisinD6.L.**•=addressisinvalidforthistask.**K*************************************************************************** GET_PHYSICAL_ADDRESS:+*%%%%%%%%%%%BWN‚8/14/84‚USEDRVLIBROUTINE‰MOVEM.L‚A0/A1,-(SP) ‰MOVE.L‚A1,A0 ‰BSR…LOGPHY‰MOVEM.L(SP)+,A0/A1‰RTS*%%%%%%%%%%%%%%%%%%%%%%% ŠPAGEL******************************************************************************‰OUTPUTW/INPUT*<*‰ThisisthehandlerforIOOWINcommands.‚Bufferaddresses,:*‰menu,etc.aresetuptohandlethecommand.‚START_IOis8*‰thencalledtotransmitthefirstcharacterofoutput.**‰Entry:A3=addressofIOCB *A5=addressofCCB*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*L**************************************************************************** OUTWINP: *A*‚Firstcheckoutwrite&readbuffersanddoothercommonstuff.*5ŠBSR„IO_COMNŒDothestuffcommontoallI/Ocommands,AŠMOVEM.LD4-D6,WRIT_BUF(A5)&storethephysicaladdressesofthe*§writebufferintheCCB. ?ŠMOVE.LIOSRRN(A3),D6†D6<--logicalstartaddrofreadbuffer.<ŠMOVE.LIOSLEN(A3),D5†D5<--lengthofreadbufferinbytes.2ŠMOVE.LTCB_ADDR(A5),A1„A1<--addressofhisTCB.5ŠBSR„BUF_ADDR‹Getthephysicaladdressesandputthem'ŠMOVEM.LD4-D6,READ_BUF(A5)intheCCB. /ŠBSR„RD_COMNŒDothestuffcommontoallREAD's. *&*‚Setupthemenu,oneitematatime.**ŠINHIBIT“Inhibitinterruptsatthislevel. ?ŠBTSTW‚#IOPFORB,IOSOPT(A3)Checkwhetherthewriteshouldbein2ŠIF…THENŠimagemodeorformatted,andaddthe8ŠMOVE.B#M_IMGWRT,MENU(A5)appropriateitemtothemenu.ŠELSE–*ŠMOVE.B#M_FRMWRT,MENU(A5)*ŠENDI–* >ŠBTSTW‚#IOPINFB,IOSOPT(A3)Checkwhetherthereadshouldbein2ŠIF…THENŠimagemodeorformatted,andaddthe9ŠMOVE.B#M_IMGRD,MENU+1(A5)appropriateitemtothemenu.ŠELSE–*ŠMOVE.B#M_FRMRD,MENU+1(A5)*ŠENDI–* ;ŠMOVE.B#M_END,MENU+2(A5)‚AddanENDmenuitemtothemenu. **‚Nowstartthingsgoing.*(ŠBRA„START_IO‹GostarttheI/Oandexit.ŠPAGEH************************************************************************* *‰HALTI/O*=*‰ThisisthehandlerfortheIOHALTcommand.‚Itjustinvokes**‰abackgroundroutinetodoallthework.**‰Entry:A3=addressofIOCB*A5=addressofCCB**‰Exit:‚D0,A0,A1,A3aregarbage*J************************************************************************** HALT: *%%%%%%%%%%%%%%% BWN 7/9/848**ˆBSETƒ#W_HALT,WORK(A5)ƒMarkworkforthehaltroutine.,**ˆINHIBIT“Inhibitinterruptsatthislevel.'**ˆBRA„CALL_BKG‹Gocallthebackground.*%%%%%%%%%%%‚BWN8/13/84‰LEA‡DO_HALT(PC),A0‰MOVE.L„#T0GUARD,D0‰TRAP†#0‰BRA.L…CMD_EXIT ‰PAGEJ****************************************************************************•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INDEPENDENT)*J**************************************************************************   ŠPAGEO*********************************************************************************‰DOACONFIGURE*B*‰ACONFIGUREcommandwasstartedbythecommandservicecode,butE*‰hecan'tfinishitbecauseitinvolvesdoingaRESET,whichchanges9*‰states,etc.‚Sohecalleduponustofinishitforhim.*D*‰ThisroutineiscalledusingCALL_GUARDEDsoweenteratinterrupt6*‰level0,andwemustmustexitatinterruptlevel0.6*‰WemustalsorestoreregisterA7ifwemesswithit.@*‰Otherthanthat,wearefreetoreturnwhateverwelikeinthe *‰registers.**‰Entry:*A5=addressofCCB*O******************************************************************************* DO_CONFIGURE: ŠPUSH.LA1‘SaveA1. ;‰MOVE.L‚CCBCHB(A5),A1†A1<---addressofoursideofdeviceŠBSR.L‚RESETŽReseteverybody.=‰MOVE.L‚DRV_ADDR(A5),A4„A4<--driveraddressforT_JSRmacro‰T_JSRƒDDP_RESET *B*‚Ifappropriate,settheclockdivisorbacktoitsinitialstate.*.ŠMOVE.LCSB_ADDR(A5),A0„A0<--addressofCSB. ?ŠBTSTW‚#IOAAUTO,IOSATM(A0)‚IfhedinkedwiththeAUTOBAUDRATE*¦DETECTattribute,‰BNE‡SET_CLOCK =ŠBTSTW‚#IOSBRTB,IOSPRM(A0)‚OrifhedinkedwiththeBAUDRATE *£parameter,‰BNE‡SET_CLOCK 7ŠTST.B‚AUTO_BAUD(A5)†Orifwewereinthemiddleofthe8ŠIF…THENŠdetectionprocesswhentheCONFIGUREcame, THENŠIfthemaskis0,noTERMINATOR-CLASSwas:ŠMOVEQ‚#$0F,D0Œspecified--makethematchvalue$0FsothatŠENDI–wenevergetamatch. 0ŠLSL.B‚#4,D0ŽThelow4bitsarethematchvalue.ŠMOVE.BD0,TC_VALUE(A5)„* *?*‚Setupthemaskforstrippingparityoffincomingcharacters.*1ŠPUT_BYTE$FF,D0‹D0<--masktoleaveall8bits. >ŠMOVEƒIOSATW(A0),D1†Ifwe'vebeenaskedtostripbit8without>ŠAND„#1<THENŠ* =SET_MASK‚MOVEQ‚#$7F,D0ŒD0<--masktostripoffthehighbit. ŠENDI–* 1ŠMOVE.BD0,CHAR_MSK(A5)„SavethemaskintheCCB. **‚Restoreregisters*‰MOVEM.Lƒ(SP)+,A0/D0/D1‰RTS ‰PAGED********************************************************************* *ˆCALL_XMIT*/*ˆCallXMITbutfirstsettheNONINTERRUPTflag*ˆwhileinCALL_GUARDEDmode.-*ˆThencleartheNONINTERRUPTflagonreturn.*E********************************************************************* CALL_XMIT:‰MOVE.L„CCBCHB(A5),A1‰MOVE.L„DRV_ADDR(A5),A4‰STˆNONINTERRUPT(A5) ‰BSR.L…XMIT‰SFˆNONINTERRUPT(A5)‰RTSŠPAGEO********************************************************************************&*‰HALTOUTSTANDINGI/OIFTHEREISANY*B*‰AcommandtoHALTI/Owasreceived,butthatkindofstuffcan'tA*‰bedoneoutsidethebackground,sothisguywasinvoked.‚ThingsB*‰areresetandaneventissent.‚ThetypeofeventthatgetssentC*‰dependsonwhetherornottherewasactuallyanyI/Oinprogress.**‰Entry:*A5=addressofCCB.*O******************************************************************************* DO_HALT:  ;‰MOVE.L„CCBCHB(A5),A1„A1<---AddressofoursideofdeviceA‰MOVE.L„DRV_ADDR(A5),A4‚A4<---AddressofdriverforT_JSRmacro5ŠLEA„EVENT(A5),A0‡A0<--addresstoprepareeventin. /ŠTST.BMENU(A5)ŒIfthereisnoI/Oinprogress,ŠIF…THENŠ**********************H*‚Iftheconditionexists,someonesentusaHaltI/OrequestforanI/OG*‚theythoughtwasinprogressBUTbythetimetheHaltcommandreachedH*‚uswehavealreadycompletedtheI/Oandsentacompletioneventback.*CŠMOVE.B#ISTAIF,IOSSTA(A3)ƒupdatetheusershaltI/Oparameterblock+*„withthecodethatsaysInvalidFunction.*DŠMOVE.W#ISTAIF,XRPSTV(A0)‚eventstatusisABORT(badhaltcommand);'*¤putsamecodeintheeventwesendto*¤theI/Osystem.   'CH!C)O1G9IABI=QFYAaJiNqDyLB‰N‘F™D”A©6±A¹>Į:ÉBŃBŁEįDéGńMłE *******************Ød.v.1/11/85"ŠELSE–Otherwise(I/Oinprogress),@ŠMOVE.B#ISTAOK,IOSSTA(A3)UpdatetheusersHaltI/Ostatuswith,*£goodstatussayingwearehaltingtheI/O.*AŠMOVE.LIOCB_ADR(A5),A3„SetthestatusfieldoftheoriginalIOCBCŠMOVE.B#ISTATO,IOSSTA(A3)(theonefortheI/O)toTIMEOUTandput:ŠBSR.L‚GET_LENŒinthe#ofbytessuccessfullytransferred.ŠMOVE.LD0,IOSLEN(A3)†* ŠBSR.L‚RESETŽReseteverything.‰T_JSRƒDDP_RESET ;ŠMOVE.W#ISTATO,XRPSTV(A0)SettheeventstatustoTIMEOUT. ŠENDI–*   *-*‚Preparetherestoftheeventandqueueit.*8ŠMOVE.B#10,(A0)‹Putintheeventlengthandeventtype,5ŠMOVE.B#XPSHLT,XRPSTA(A0)queuetheevent,andexit.‰STˆNONINTERRUPT(A5)ŠBSR.L‚Q_EVENTŒ*‰SFˆNONINTERRUPT(A5) ŠIF‚‚THEN(ŒTR0$.KILLER,Ifbad,crashthesystem.ŠENDI ‰RTS‰PAGEJ*************************************************************************** *‰RECEIVE*>*‰Thissection'comestolife'whentheredataisrequestedby<*‰aREADorOUTPUTW/INPUTcommandandthereisdatainthe9*‰receivequeue.‚Otherwiseitjustidles.‚Itsfunctionis?*‰totakecharactersfromthereceivequeueandfilltheuser's;*‰bufferwiththem.‚Whenthebufferisfull,itsetsupfor.*‰adispatchtobedoneofthenextmenuitem.**‰RECV0backgroundentrypoint:.*A1=addressofBackgroundactivationblock.**‰RECVentrypoint:/*‰Entry:A1=addressofoursideofthedevice*A4=addressofdriver*A5=addressofCCB**‰ExitbyRTS.*J************************************************************************** *%%%%%%%%%%%%%%%%%bwn‚7/9/84RECV0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.*)‰LEA‡-RECV_BAB(A1),A5„A5<---CCBaddress;‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofdevice1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%RECV: *+*‚Seeifthere'sreallyanyworktodonow.*:ŠTST.W‚RECV_ST(A5)ˆIfwe'renotdoingaREADatthemoment ŠIFƒ‚THENRTSŠENDI8ŠTST.W‚RQ_CNT(A5)‰orthere'snothingleftinthereceive0ŠIF‚‚THENŒqueuetoread,we'redonefornow.RTSŠENDI *C*‚There'ssomethingtodo.‚Checkwhetherthere'senoughroominthe!*‚transmitqueueforustodoit.*@ŠIF.WTQ_CNT(A5)#TQ_MAX-7THENƒIfthetransmitqueuecan't3ŠST…WAIT_TQ(A5)ˆhold7morechar's,markthatwe're,ŠRTS—waitingforthetransmitqueuetoemptyŠENDI–andgetout. *%%%%%%%%%‚BWN‚10/9/84*=*‚SincetheTQ_CNTisnowlowenough,cleartheWAIT_TQflag.*‰SF„WAIT_TQ(A5)"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*?*‚It'sOKtoreceivesomething.‚Isthereanerroronthischar?*9ŠMOVE.WRQ_GET(A5),D1†D1<--pointertonextbytetoget.8ŠCMP.W‚ERR_PTR(A5),D1…Iftheerrorpointermatchesthis,ŠIF…THENŠ* /ŠMOVE.LIOCB_ADR(A5),A0„A0<--addressofIOCB.>ŠMOVE.LRBUF_PTR(A5),D1„Computethe#ofbytesreadbeforethe6ŠSUB.L‚RBUF_SAD(A5),D1„errorandputthisintheIOCB.ŠMOVE.LD1,IOSLEN(A0)†*CŠMOVE.BERR_CODE(A5),IOSSTA(A0)‚Setthestatusfromtheerrorcode. 5ŠLEA„EVENT(A5),A0‡A0<--addresstoprepareeventat. ŠMOVE.B#10,(A0)‹Seteventsize.*ŠMOVE.B#XPSNRM,XRPSTA(A0)Seteventtype.6ŠCLR.B‚XRPSTV(A0)‰Seteventstatus(highbyte=0,low6ŠMOVE.BERR_CODE(A5),XRPSTV+1(A0)‚byte=IOCBstatus).$ŠBSR.L‚RESETŽDothelow-levelreset.ŠT_JSR‚DDP_RESETŠBSR.L‚Q_EVENTŒQueuetheevent. ŠIF‚‚THEN(ŒTR0$.KILLER,Ifbad,crashthesystem.ŠENDI  !**ˆBRA„CHECK_WORK‰Andwe'redone.ŠRTSŠENDI *&*‚Getthecharfromthereceivequeue.*;ŠMOVE.BRQ(A5,D1.W),D1…D1<--nextcharfromreceivequeue.:ŠSUBQ.W#1,RQ_GET(A5)†UpdatethereceivequeuegetpointerŠI  F…THENŠ(circularqueue).ŠMOVE.W#RQ_MAX,RQ_GET(A5)*ŠENDI–*ŠSUBQ.W#1,RQ_CNT(A5)†* *H*‚IfwehadsuspendedtransmissionfromtheterminalbecausethereceiveE*‚queuewasnearfull,andremovingthischargivesusenoughroomto$*‚continue,thenreleasethedevice.*3ŠTST.B‚STOPPED(A5)ˆIfwe'vegotthedevicestopped,ŠIF…THENŠ* BŠIF.WRQ_CNT(A5)#NUF_ROOMTHENƒIfwe'vegotenoughroomnow,,ŠBSR.L‚UNSTOPLetthedevicetransmitagain.ŠENDI–* ŠENDI–* *,*‚Doaccordingtothereceiveprocessstate.*>ŠMOVE.WRECV_ST(A5),D0…Getthereceivestateandjumpintothe,ŠJMP„RECV_TBL(PC,D0.W)‚receivebranchtable.   ***‚Branchtableforreceiveprocessstates.* RECV_TBL:5**ˆBRA.L‚CHECK_WORK‰IfreceiveprocessstateisIDLE.ŠRTSŠNOPŠBRA.S‚R_IMAGEŒIfit'sIMAGE.ŠNOPŠBRA.L‚R_FORMAT‹Ifit'sFORMAT.ŠPAGEJ****************************************************************************‰RECEIVE--IMAGEREADSTATE*1*‰RECVbrancheshereifreceivestateisS_IMAGE.<*‰Thefunctionofthisroutineistoreceivecharactersinto"*‰theuser'sbufferinIMAGEMODE.**‰Entry:D1.B=charreceived(*A1ƒ=addressofoursideofthedevice*A5ƒ=addressofCCB*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** R_IMAGE: ***‚Isthereroomintheuser'sreadbuffer?*?ŠMOVE.LRBUF_PTR(A5),A0„A0<--pointerintouser'sreadbuffer.DŠIF.LA0RBUF_EAD(A5)THENƒIfwe'repasttheendofthebuffer, 3ŠBSR„TERM_TST‹Checktoseeifthisisaterminator.ŠIF…THENŠIfnot,ŠMOVEQ‚#BEL,D0ŒechoaBELchar.ŠBSR.L‚Q_XMIT*ŠENDI–* 1ŠELSE–else(we'renotpasttheendofthebuffer) *8*‚There'sroominthebuffer,soputthecharoutthere.*6ŠMOVE.BD1,(A0)+‹Putcharatnextlocationinbuffer&+ŠMOVE.LA0,RBUF_PTR(A5)„updatethepointer. *@*‚Ifwe'resupposedtobeechoing,putitinthetransmitqueue.*$ŠTST.B‚ECHO(A5)‹Ifechoflagisset,ŠIF…THENŠ*1ŠMOVE.BD1,D0ŽPutthecharinthetransmitqueue.ŠBSR.L‚Q_XMIT*'ŠMOVE.BD0,D1ŽRestorethecharintoD1.ŠENDI–* **‚Testfortermination.*BŠMOVE.LRBUF_PTR(A5),D0„Ifwe'reconfiguredtoterminateonbuffer>ŠBTSTW‚#IOATFUL,CONFIG+IOSATW(A5)‚fullandthebufferisfull,(ŠIFAND.LD0RBUF_EAD(A5)THEN 6ŠSUB.L‚RBUF_SAD(A5),D0„setthe#ofbytestransferred,ŠMOVE.LD0,XFER_LEN(A5)„*,ŠBRA.L‚RECV_ZAP‹andgetthisreadoverwith; *ŠELSE–else(thatdidn'tcausetermination) 2ŠBSR„TERM_TST‹checkifthisisaterminationchar. ŠENDI–* ŠENDI  ŠBRA„RECVExit.ŠPAGEJ***************************************************************************(*‰SUBROUTINETOTESTFORREADTERMINATOR**‰Checksachartoseeifit)*--isoneofthereadterminatorvalues%*--fallsintotheterminatorclass.<*‰Ifeitheroftheaboveistrue,the#ofbytestransferred3*‰iscomputedandthereceivestateissettoIDLE.**‰Entry:D1.B=charreceived*A5ƒ=addressofCCB(*A1ƒ=addressofoursideofthedevice**‰Exit:‚CC=resultsoftest:*•=charisaterminator!*•=charisnotaterminator*D0=garbage*J************************************************************************** TERM_TST: *-*‚Firstcheckthe0-4readterminatorvalues.*7ŠMOVE.LCONFIG+IOSRTV(A5),D0ƒGettheterminatorvalues. (terminator).2ŠCLR.B‚D0‘Otherwiseclearthatbyteandtryagain.ŠBRA„TERM_NXT‹* *>*‚Wasn'toneofthose--doesitfallintotheterminatorclass?*KTERM_CLS‚MOVE.BTC_MASK(A5),D0„IfafterANDingthecharwiththedon't-care8ŠAND.B‚D1,D0Žmaskitmatchesthematchvalue,we'llhave@ŠC  MP.B‚TC_VALUE(A5),D0„setthecond.codesto(terminator). 4ŠBNE„TERMEXIT‹Ifitwasn'tone,justexitwith.  **‚It'saterminator!*ETERM_YES‚MOVE.LRBUF_PTR(A5),D0„It'saterminator--setthe#ofbytesAŠSUB.L‚RBUF_SAD(A5),D0„transferred(soitcanlaterbeputintheBŠMOVE.LD0,XFER_LEN(A5)„IOCB).‚Finally,setreceivestatetoIDLE,*%%%%%%%%%%%%%%%% BWN 7/9/84D**ˆBSETW‚#W_XMIT,WORK(A5)ƒmarkworkforxmitter(sohe'lldispatch), ŠBKGRNDƒXMIT*%%%%%%%%%%%%%%%%%%%%%%%%%%%%6ŠCLR.W‚RECV_ST(A5)ˆandSETCONDITIONCODESTO!!!  TERMEXIT‚RTS—Exit.ŠPAGEJ***************************************************************************!*‰RECEIVE--FORMATTEDREADSTATE*2*‰RECVbrancheshereifreceivestateisS_FORMAT.<*‰Thefunctionofthissectionistoreceivecharactersinto&*‰theuser'sbufferinFORMATTEDMODE.*;*‰Note:‚thespecialcharactersREPRINTLINEandCANCELLINE=*‰mustbe<=$7F.‚Iftheyarenot,thecheckforinvalidASCII>*‰(whichcomesbeforethechecksforthosetwo)willcausethe-*‰chartoberejectedwhenitisencountered.**‰Entry:D1.B=charreceived*A5ƒ=addressofCCB(*A1ƒ=addressofoursideofthedevice*J************************************************************************** R_FORMAT: ?ŠMOVE.LRBUF_PTR(A5),A0„A0<--pointerintouser'sreadbuffer. *B*‚Checkwhetherthisisaterminatorcharacter.‚Ifso,putCRintoD*‚buffer(ifthere'sroom)andgodothefinishforformattedreads.*&ŠBSR„TERM_TST‹Ifthisisaterminator,ŠIF…THENŠ* AŠIF.LA0RBUF_EAD(A5)THEN‚Ifthebufferisn'talreadyfull,1ŠMOVE.BD1,(A0)Œputtheterminatorinthebuffer.ŠENDI–* ŠBRA.L‚R_F_TERM‹Gofinishup. ŠENDI *&*‚Itwasn'taterminator--isitaNUL?*ŠTST.B‚D1‘IfcharisaNUL,ŠBEQ„RECVjustexit. ***‚Wasn'taNUL--isitnon-ASCII($80-$FF)?*)ŠIF.BƒD1#$7FTHEN‚Ifcharis>$7F, 4ŠMOVEQ‚#BEL,D0ŒPutaBELcharinthetransmitqueue,ŠBSR.L‚Q_XMIT*ŠBRA„RECVandexit. ŠENDI *'*‚Itwasn'tnon-ASCII--isitDELorBS?*4ŠIFOR.BD1#BSTHENƒIfcharisDELorBS, BŠIF.LA0RBUF_SAD(A5)THENƒIfuser'sreadbufferisn'tempty, /ŠMOVE.B-(A0),D1‹D1<--thecharbeingdeleted.8ŠMOVE.LA0,RBUF_PTR(A5)„Correctthereadbufferpointer.<ŠSUBQ.L#1,CHAR_CNT(A5)„Decrementthe#ofchar'sonscreen. 0ŠTST.B‚ECHO(A5)‹Ifwe'resupposedtobeechoing,ŠIF…THENŠ* 7ŠBTSTW‚#IOAHCPY,CONFIG+IOSATW(A5)ƒIfwe'retalkingtoaŠIF…THENŠhardcopydevice, ŠPUSH.BD1‘Savethechar.6ŠTAS„LAST_BS(A5)ˆIfthelastcharwasnotaBSorDEL,ŠIF…THENŠ*:ŠPUT_BYTEL_ARROW,D0‡setuptotransmitaleftarrowchar.ŠBSR.L‚Q_XMIT*ŠENDI–*;ŠIF.B(A7)#HI_CTLTHEN‚Ifthecharisacontrolchar,-ŠPUT_BYTECARET,D0‰setuptotransmitacaretŠBSR.L‚Q_XMIT*4ŠADD.B‚#$40,(A7)ŠandconvertthecontrolchartoitsŠENDI–printableequivalent.&ŠPOP.B‚D0‘Setuptotransmitthechar.ŠBSR.L‚Q_XMIT* $ŠELSE–else(we'retalkingtoaVDT), @ŠIF.BD1#HI_CTLTHENIfit'sacontrolchar,put(another):ŠMOVE.L#BS_SP_BS,D0‡BS,SPACE,BSintothetransmitqueue/ŠBSR.L‚Q4_XMITŒanddecrementthe#ofchar'son'ŠSUBQ.L#1,CHAR_CNT(A5)„screen(again).ŠENDI–*9ŠMOVE.L#BS_SP_BS,D0‡putaBS,aSPACE,andaBSintotheŠBSR.L‚Q4_XMITŒtransmitqueue. ŠENDI ŠENDI ŠENDI .ŠBRA.L‚RECVThat'sallforBS,DEL.‚Justexit. ŠENDI *B*‚Wasn'tBSorDEL--atthispointweknowwearegoingtogenerateG*‚somethingthatrequiresustocloseoutanytextdeletedbyBSorDEL8*‚inhardcopymode.‚Sosendarightarrowifweneedto.*8ŠTST.B‚LAST_BS(A5)ˆIfthelastcharreceivedwasaBSor#ŠIF…THENŠDELinhardcopymode, ŠPUSH.BD1‘Savethechar.6ŠSF…LAST_BS(A5)ˆCleartheflag(thisisnotBSorDEL):ŠPUT_BYTER_ARROW,D0‡andsetuptotransmitarightarrow.ŠBSR.L‚Q_XMIT*ŠPOP.B‚D1‘Restorethechar. ŠENDI–* *  B*‚IsthechartheREPRINTLINEchar?‚Ifso,setuptotransmittheF*‚end-of-linestring,andchangethemenutodoreprintandthenread.*BŠIF.BD1CONFIG+IOSRLN(A5)THENƒIfcharisREPRINTLINEchar, :ŠMOVE.LCONFIG+IOSEOL(A5),D0„Putend-of-linestringintheŠBSR.L‚Q4_XMITŒtransmitqueue.DŠMOVE.LRBUF_SAD(A5),WBUF_PTR(A5)‚Initializepointerforreprintand6ŠCLR.L‚CHAR_CNT(A5)‡setcountofcharsonscreento0.DŠMOVE.L#M_REPRNT<<24+M_FRMRD<<16+M_END<<8,MENU(A5)‚Changethemenu.,ŠBRA.L‚RECV_ZAP‹Gozapthereadwe'redoing. ŠENDI *F*‚Wasn'tREPRINTLINEchar--isitCANCELLINEchar?‚Ifso,changemenu8*‚andhandleaccordingtodevicetype(hardcopyorVDT).*AŠIF.BƒD1CONFIG+IOSCLC(A5)THEN„IfcharisCANCELLINEchar, CŠMOVE.LRBUF_SAD(A5),RBUF_PTR(A5)ƒResetpointerforformattedread. 7ŠTST.B‚ECHO(A5)‹Ifechoisnotonorthisisahardcopy3ŠBEQ„NEW_LINE‹device,wecan'terasecharacters,so#ŠBTSTW‚#IOAHCPY,CONFIG+IOSATW(A5)*ŠIF…THENŠ* ;NEW_LINE‚PUT_BYTEBKSLASH,D0‡SetuptotransmitabackslashŠBSR.L‚Q_XMIT*8ŠMOVE.LCONFIG+IOSEOL(A5),D0ƒandtheend-of-linestring,ŠBSR.L‚Q4_XMITŒ*ŠBRA„RECVandexit. -ŠENDI–otherwise(canerasechar's),setuptoDŠMOVE.L#M_CANCEL<<24+M_FRMRD<<16+M_END<<8,MENU(A5)canceltheline,.ŠBRA„RECV_ZAP‹andgozapthereadwe'redoing. ŠENDI *6*‚Charisjustordinarydata.‚Trytoputitinbuffer.*9ŠIF.LA0RBUF_EAD(A5)THENƒIfuser'sbufferisfull, 4ŠMOVEQ‚#BEL,D0ŒPutaBELcharinthetransmitqueue.ŠBSR.L‚Q_XMIT* #ŠELSE–else(user'sbuffernotfull) 5ŠMOVE.BD1,(A0)+‹Putcharinuser'sbufferandupdate@ŠMOVE.LA0,RBUF_PTR(A5)„bufferpointerand#ofbytesonscreen.ŠADDQ.L#1,CHAR_CNT(A5)„* 7ŠTST.B‚ECHO(A5)‹Ifwe'resupposedtobeechoingchar's,ŠIF…THENŠ* 5ŠIF.BD1#HI_CTLTHENIfthisisacontrolchar,ŠPUSH.BD1‘Savethechar.<ŠPUT_BYTECARET,D0‰Putanuparrow(^)inthetransmitqueue,5ŠBSR.L‚Q_XMITincrementthe#ofbytesonscreen,and?ŠADDQ.L#1,CHAR_CNT(A5)„changethecontrolchartoitsreadable&ŠMOVEQ‚#$40,D1Œequivalentandrestore.ŠADD.B‚(A7)+,D1‹*ŠENDI–* 3ŠMOVE.BD1,D0ŽPutthecharintothetransmitqueue.ŠBSR.L‚Q_XMIT* ŠENDI AŠBTSTW‚#IOATFUL,CONFIG+IOSATW(A5)‚Finally,ifwe'reconfiguredtoAŠIFAND.LA0RBUF_EAD(A5)THENƒterminateonbufferfull?ŠSUB.L‚RBUF_SAD(A5),A0„andthebufferisnowfull,setthe#of;ŠMOVE.LA0,XFER_LEN(A5)„bytestransferredandgofinishup.ŠBRA„R_F_TERM‹*ŠENDI–* ŠENDI  0ŠBRA„RECVKeepdoingthisuntilwehavetostop!ŠPAGEK*****************************************************************************‰FINISHUPAFORMATTEDREAD*<*‰Aformattedreadhasbeenterminated.‚Finishupbysetting<*‰the#ofbytestransferredandarrangingforaclosing'>'7*‰andtheend-of-linestringtobesentasappropriate.**‰Entry:%*A1=addrofoursideofthedevice*A5=addressofCCB*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*K*************************************************************************** R_F_TERM: *J*‚Ifweneedtooutputa'>'tocloseoffabackspacedsectioninhardcopy-*‚mode,doitnow--butonlyifwe'reechoing!*0ŠTST.B‚ECHO(A5)‹Ifwe'resupposedtobeechoing,ŠIF…THENŠ* :ŠTST.B‚LAST_BS(A5)ˆCheckwhetherthelastcharwasaBSor*ŠIF…THENŠDELinhardcopymode.‚Ifso,1ŠPUT_BYTER_ARROW,D0‡transmitarightarrowchar.ŠBSR.L‚Q_XMIT*ŠENDI–* ŠENDI *>*‚Whetherwe'reechoingornot,outputtheend-of-linestring.*@ŠMOVE.LCONFIG+IOSEOL(A5),D0‚Puttheend-of-linestringintotheŠBSR.L‚Q4_XMITŒtransmitqueue. *A*‚Zapthereadwe'redoingsowecangoontothenextmenuitem.*DRECV_ZAP:CLR.W‚RECV_ST(A5)ˆSetreceivestatetoIDLE,markworkfor*%%%%%%%%%%%%%%%% BWN 7/9/84;**ˆBSETW‚#W_XMIT,WORK(A5)ƒthetransmitte  r(hehastodothe ‰BKGRND„XMIT,**ˆBRA„CHECK_WORK‰dispatch),andwe'redone.‰RTS‰PAGEN********************************************************************************‰DISPATCHMENUITEM*:*‰SincereceiveandtransmitprocessesarebothIDLE,it's:*‰timetomoveontothenextiteminthemenu.‚Whenwe've:*‰finishedallthemenuitems(ENDmenuitemencountered),<*‰we'llqueueacompletioneventtotheattachedtask(IOS).*;*‰NOTE:‚Becauseofthewaythisroutinedealswithtransmit=*‰processstates,itmayonlybecalledbytheXMITroutines.**‰Entry:A5=addressofCCB**‰Exit:*J************************************************************************** DISPATCH: 8ŠMOVEM.LD0/A0,-(A7)‡Savetheregisterswe'llblowaway.6ŠMOVE.LMENU(A5),D0ˆGettheoldmenu;ifwe'redownor'ŠBLS.L‚DISPEXIT‹inactive,justgetout. #ŠROL.L‚#8,D0ŽGetnextmenuitemand,ŠMOVE.LD0,MENU(A5)ˆsavetheremainingmenu. *"*‚Somekindoftransmitmenuitem?*BŠIF.BD0#MHI_XMITTHEN‚Ifthisisatransmit-typemenuitem, 'ŠCLR.L‚COLUMN(A5)‰Startusatcolumn0. ;ŠMOVE.BD0,XMIT_ST+1(A5)ƒSettransmitstatefrommenuitem,*%%%%%%%%%%%%%%%%%bwn‚7/9/848**ˆBSETW‚#W_XMIT,WORK(A5)ƒmarkworkforthetransmitter, ‰BKGRND„XMIT!*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠBRA„DISPEXIT‹andexit. ŠENDI–* *!*‚Somekindofreceivemenuitem?*AŠIF.BD0#MHI_RECVTHEN‚Ifthisisareceive-typemenuitem, 8ŠSF…LAST_BS(A5)ˆclearthe'lastcharwasbackspace'flag9ŠSUB.B‚#MLO_RECV,D0‡andsetreceivestatefrommenuitem.ŠMOVE.BD0,RECV_ST+1(A5)ƒ* *D*‚Shouldweclearthetype-aheadbuffer?‚Yesifwe'renotconfigured:*‚fortypeaheadortheoptiontoclearthebufferisset.*AŠBTSTW‚#IOPCTAB,OPTIONS(A5)‚Iftheoptiontoclearthetype-ahead'ŠBNE„CLR_BUFF‹bufferisset,doitnow. @ŠBTSTW‚#IOATAHD,CONFIG+IOSATW(A5)‚Ifwe'renotconfiguredtouseŠIF…THENŠtype-ahead,then;CLR_BUFF‚BSR„EMPTY_RQ‹emptythereceivequeue(whichistheŠENDI–type-aheadbuffer). *%%%%%%%%%%%%%%%%%bwn‚7/9/844**ˆBSETW‚#W_RECV,WORK(A5)ƒMarkworkforthereceiver ‰BKGRND„RECV"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠBRA„DISPEXIT‹andexit.ŠENDI–* *B*‚ItmustbeanENDmenuitem.‚Setmenuinactive,updatetheIOCB,9*‚andqueueacompletioneventbacktotheattachedtask.*&ŠCLR.L‚MENU(A5)‹Setthemenuinactive. /ŠMOVE.LIOCB_ADR(A5),A0„A0<--addressofIOCB.1ŠMOVE.B#ISTAOK,IOSSTA(A0)SetIOCBstatustoOK.?ŠMOVE.LXFER_LEN(A5),IOSLEN(A0)‚SettheIOCB'stransferlength. 2ŠSF…INPUT(A5)ŠFlagthatwe'renotdoinganyinput.5ŠSF…INHIB_DO(A5)‡FlagthatDISCARDOUTPUTisallowed.=ŠMOVE.LTCB_ADDR(A5),A0„Decrementthe'outstandingI/O'count(ŠSUB.B‚#1,TCBIOCNT(A0)„intheguy'sTCB. 4ŠLEA„EVENT(A5),A0‡A0<--addresstocreateeventat."ŠMOVE.B#10,(A0)‹Seteventlength,?ŠMOVE.B#XPSNRM,XRPSTA(A0)seteventtypetoNORMALCOMPLETION,6ŠMOVE.W#ISTAOK,XRPSTV(A0)seteventstatustoISTAOK,#ŠBSR.L‚Q_EVENTŒandqueuetheevent. ŠIF‚‚THEN(ŒTR0$.KILLER,Ifbad,crashthesystem.ŠENDI **‚Returntothecaller.*@DISPEXIT‚MOVEM.L(A7)+,D0/A0‡Restoresavedregistersandreturn.ŠRTS—*ŠPAGEJ***************************************************************************'*‰SUBROUTINETOEMPTYTHERECEIVEQUEUE*=*‰Eliminatescharacterstypedaheadandanyerrorsassociated;*‰withthem,andenablesthedevicetotransmitagainifit*‰wasstopped.**‰Entry:%*A1=addrofoursideofthedevice*A5=addrofCCB**‰Exit:*J************************************************************************** EMPTY_RQ: *C*‚Setthepointerstothesameplaceandzerothecount.‚ThereasonD*‚wearedoingthiswithinterruptsINHIBITedisthatcharactersare1*‚addedtothequeuefromoutsidethebackground.*‰PUSHƒSRŠINHIBIT3ŠMOVE.W#RQ_MAX,RQ_GET(A5)Emptythereceivequeue.ŠMOVE.W#RQ_MAX,RQ_PUT(A5)*ŠCLR.W‚RQ_  CNT(A5)‰* +ŠCLR.W‚ERR_PTR(A5)ˆClearanyreceiveerror.ŠPOP‚SR *'*‚Ifwestoppedthedevice,unstophim.*0ŠTST.B‚STOPPED(A5)ˆIfwehadstoppedthedevice,ŠIF…THENŠ* %ŠBSR.L‚UNSTOPLethimtransmitagain. ŠENDI–* ŠRTS—*‰PAGEJ***************************************************************************.*‰SUBROUTINETOSETCOUNTOFBYTESTRANSFERRED*<*‰Thisroutineiscalledfromthetransmitprocesstosetup<*‰thetransferlengthfieldintheCCB--BUTONLYIFTHISWAS=*‰AWRITECOMMAND.‚Thatis,ifweweredoingOUTPUTW/INPUT,?*‰theinputpartiswhatgetsreflectedinthetransferlength.**‰Entry:A5=addressofCCB**‰Exit:‚D0=garbage*J************************************************************************** SET_CNT: 0ŠTST.B‚INPUT(A5)ŠIfwe'redoingaWRITEcommand,ŠIF…THENŠ* BŠMOVE.LWBUF_PTR(A5),D0„Savethe#ofbytestransferredforlater.ŠSUB.L‚WBUF_SAD(A5),D0„*ŠMOVE.LD0,XFER_LEN(A5)„* ŠENDI  ŠRTS—Exit.‰PAGEJ****************************************************************************‰HANDLEABREAK*:*‰EithertheBREAKkeywaspressedortheBREAKEQUIVALENT7*‰charwasreceived.‚Eitherway,wesendanappropriate9*‰eventtotheattachedtask(IOS)dependinguponwhether*‰ornotwearedoingI/O.**"*‰BREAK0(background)entrypoint:-*A1=addressofbackgroundactivationblock**‰BREAKentrypoint:*‰Entry:(*A1=addressofoursideofthedevice*A4=addressofdriver*A5=addressofCCB*J************************************************************************** *%%%%%%%%%%%%%%%%%bwn‚7/9/84BREAK0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.**‰LEA‡-BREAK_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BREAK: *%%%%%%%‚BWN‚9/17/84*J*‚Ifwearesupposedtobereportingbreaks,andwearenotintransparent*‚mode,*ŠIF.BƒES_ST(A5)‚‚#0ƒAND.B‘TR_MODE(A5)ƒƒ#0ƒTHEN  +ŠTST.B‚MENU(A5)‹Ifthechannelisnotdown,ŠIF…THENŠ* *ŠIF…THENŠIfweweren'tdoinganyI/O, 7ŠLEA„UNS_EVNT(A5),A0„A0<--addresstocreateeventat.4ŠMOVE.B#12,(A0)‹Settheeventlength(alongone!).9ŠMOVE.B#XPSUNS,XRPSTA(A0)EventtypeisUNSOLICITED,and:ŠMOVE.W#XSTVDST,XRPSTV(A0)eventstatusisDEVICESTATUS.4ŠT_JSRƒGET_STAT‹Getthedevicestatus,setthebreak.ŠBSETƒ#XDSBRK,D0‰bit,andputitintheevent.ŠMOVE.BD0,XRPDST(A0)†*=ŠMOVE.B#XDSACIA,XRPDTP(A0)‚Setthedevicetypeintheevent. ŠELSE–else(weweredoingI/O) ?ŠMOVE.LIOCB_ADR(A5),A0„A0<--addressoftheIOCBfortheI/O.9ŠBSR.L‚GET_LENŒD0<--lengthofsuccessfuldatatransfer.7ŠMOVE.LD0,IOSLEN(A0)†SetthelengthfieldintheIOCB.?ŠPUT_BYTEISTABRK,D0‡SetthestatusfieldintheIOCBtoBREAK.ŠMOVE.BD0,IOSSTA(A0)†* 4ŠLEA„EVENT(A5),A0‡A0<--addresstocreateeventat.$ŠMOVE.B#10,(A0)‹Settheeventsize,.ŠMOVE.B#XPSNRM,XRPSTA(A0)settheeventtype,5ŠMOVE.WD0,XRPSTV(A0)†settheeventstatus(ISTABRK). ŠENDI $ŠBSR.L‚RESETŽDothelesserresetand‰T_JSRƒDDP_RESETŠBSR.L‚Q_EVENTŒqueuetheevent. ŠIF‚‚THEN(ŒTR0$.KILLER,Ifbad,crashthesystem.ŠENDI ŠENDI ŠENDI  ‰RTSŠPAGEJ************************************************************************** *‰TRANSMIT*A*‰ThisisthestartofthecodethatsendscharactersoutthroughD*‰thedevice.‚Ifthedeviceisready,we'regoingtosendoutachar>*‰andreturn.‚Thesourceofthecharacterdependsonthestate*‰we'recurrentlyin.*!*‰XMIT0entrypoint(background):-*A1=addressofbackgroundactivationblock**‰XMITentrypoint:,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addrofdriver**‰Exit:*D0,D1,A0=garbage*J******************************************************************  ******** XMIT0:**ƒSetupA5andA1. *ƒSetupA4<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.*)‰LEA‡-XMIT_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC5‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofthedriver* XMIT: * *‚Seeifwecandoanyworknow.**;*‚Checkingtoseeifthedevice'stransmitbufferisempty.* ‰T_JSR…CK_TBE>‰IF‚‚THEN†Ifthetransmitbufferisnotempty,wearedone ŒRTSŽfornow.‰ENDI *5*‚Jumptotheroutinedictatedbythetransmitstate.*DXMIT_JMP:MOVE.WXMIT_ST(A5),D0…Getthetransmitstateandjumpinto1ŠJMP„XMIT_TBL(PC,D0.W)‚thetransmitbranchtable.  *+*‚Branchtablefortransmitprocessstates.* XMIT_TBL:0ŠBRA.S‚X_IDLEIftransmitprocessstateisIDLE.ŠNOPŠBRA.L‚X_IMAGEŒIfit'sIMAGE.ŠBRA.L‚X_FORMAT‹Ifit'sFORMAT.ŠBRA.L‚X_CANCEL‹Ifit'sCANCEL.ŠBRA.L‚X_REPRNT‹Ifit'sREPRNT.!ŠBRA.L‚X_SPECIALŠIfit'sSPECIAL.ŠPAGEO*********************************************************************************‰TRANSMITTHECHARIND0*@*‰ThisistheONLYplaceacharissenttothedevice.‚BasicallyB*‰wejustchecktoseeifwe'resupposedtobethrowingawaywrite@*‰requests(DISCARDOUTPUT)andsendthecharacterifwe'renot.**‰Entry:*D0.B=chartotransmit%*A1=addrofoursideofthedevice*A5=addrofCCB*A4=addrofdriver**‰Exit:*D0=garbage*O******************************************************************************* XMIT_D0: *B*‚Ifwe'rediscardingoutput,justsetupfortheI/Ototerminate1*‚withoutdoinganyI/O.‚Otherwisesendthechar.*5ŠTST.B‚DISCARD(A5)ˆIftheDISCARDOUTPUTconditionis/ŠIF…THENŠset(thecharhasbeenreceived), 0ŠCLR.B‚NUL_CNT(A5)ˆStopsendingNUL'sifweare, 3ŠMOVE.W#TQ_MAX,TQ_GET(A5)emptythetransmitqueueŠMOVE.W#TQ_MAX,TQ_PUT(A5)*ŠCLR.W‚TQ_CNT(A5)‰* >ŠMOVE.LWBUF_EAD(A5),D0„movethewritebufferpointerpastthe&ŠADDQ.L#1,D0Žendofthewritebuffer,ŠMOVE.LD0,WBUF_PTR(A5)„* )*§arrangeforthetransmittertogoidle,1ŠTST.B‚SPECIAL(A5)ˆ(ifwe'reinSPECIALmodethenŠIF…THENŠ*4ŠCLR.B‚OLD_XMIT_ST(A5)„changetheoldstatetoidle,&ŠELSE–else(we'renotinSPECIALmode)3ŠCLR.B‚XMIT_ST+1(A5)†changethenewstatetoidle).ŠENDI–* *ŠBRA„XMITandstartoverwiththetranmit. ŠENDI *@*‚Here'swherewetransmitthechar.‚BranchdirectlyhereifyouA*‚absolutelyhavetogetthischarout,asinthecaseofsending/*‚anXOFFtostopthedevicefromtransmitting.*FORCE_D0:EQU„***‚Transmitthecharacter*‰T_JSR…PUT_CHAR *H*‚IfthecharwejusttransmittedisaCRorLFandwe'reconfiguredfor8*‚NULpadding,setuptoprinttheconfigured#ofNULs.*9ŠIF.BD0#CROR.BD0#LFTHEN‚Ifit'sCRorLF,9ŠMOVE.BCONFIG+IOSNLS(A5),NUL_CNT(A5)„setthe#ofNUL's.0ŠIF…THENŠIftherearesometosend,putthe<ŠBSR.L‚SET_SPECIALˆtransmitterinSPECIALmodetosendNULs.ŠBSETƒ#SPEC_NUL,SPECIAL(A5)ŠENDIŠENDI ‰RTS˜Andwe'redone.‰PAGEJ**************************************************************************ŠPAGEJ****************************************************************************‰TRANSMIT--IDLESTATE*7*‰XMITbrancheshereiftransmitstateisS_IDLE.‚Other;*‰X_??????routinesbranchheredirectlywhentheygoIDLE.9*‰Whenwegethere,thetransmitprocesshasnothingleft8*‰todo.‚Whatwedofromheredependsonwhat'sgoingon7*‰inthereceiveprocess'smind.‚Ifhe'sidletoo,then+*‰it'stimetodispatchthenextmenuitem.*/*‰Entry:A1=addressofoursideofthedevice*A5=addressofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** X_IDLE:   *B*‚Checkwhetherthereceiverwaswaitingforthetransmitqueueto!*‚becomeempty(whichitisnow).*6ŠTST.B‚WAIT_TQ(A5)ˆIfthereceiveprocesswaswaiting,ŠIF…THENŠ* 4ŠSF…WAIT_TQ(A5)ˆresettheflagandmarkworkforthe*%%%%%%%%%%%%%%%%% BWN 7/13/84#**ˆBSETW‚#W_RECV,WORK(A5)ƒreceiver. ‰BKGRND„RECV*%%%%%%%%%%%%%%%%%%%%%%%%%%% ŠELSE–* *7*‚Receivewasn'twaitingontransmitqueue;isheIDLE?=*‚Ifso,webothare,whichmeansit'stimetodoadispatch.*2ŠTST.W‚RECV_ST(A5)ˆIfthereceiveprocessisIDLE,ŠIF…THENŠ**ŠBSR„DISPATCH‹dispatchthenextmenuitem.ŠENDI–* ŠENDI ‰RTS˜Andwe'redone.ŠPAGEJ****************************************************************************‰UNSTOPthedevice*?*‰Thereceivequeuegotprettyfull,sowedidsomethingtotry>*‰tostopthedevicefromtransmittingmorecharacters.‚Nowwe=*‰haveroominthereceivequeueagain,sowewanttolethim *‰continue.*,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addrofdriver**‰Exit:*J************************************************************************** UNSTOP: $ŠMOVEM.LD0/D1,-(SP)‡Saveregisters. :ŠSF…STOPPED(A5)ˆClearflagthatsayswe'vegotitstopped.  ?ŠBTSTW‚#IOAXCTL,CONFIG+IOSATW(A5)…Ifwe'resupposedtobeusing8ŠIF…THENŠXONandXOFFchar'sforreadflowcontrol, =ŠBSR.L‚SET_SPECIALˆSetupforthespecialtransmitroutineto@ŠBSETƒ#SPEC_XON,SPECIAL(A5)‚runwhichputsoutanXONcharacter,*%%%%%%%%%%%%%%%%%bwn‚7/9/84<**ˆBSETW‚#W_XMIT,WORK(A5)ƒandmarkworkforthetransmitter. ‰BKGRND„XMIT*%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ŠELSE–else(notusingXON/XOFF) *9*ˆCall‚thedevice-dependentroutinetounstopthedevice.*F*%%%%%%%%%%‚BWN‚9/24/84‚INHIBIT/UNMASKAROUNDDEVICE-DEPENDENTROUTINE‰INHIBIT‰T_JSR…DDP_UNSTOP‰UNMASK *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*ŠENDI–*  2ŠMOVEM.L(SP)+,D0/D1‡Restoreregistersandreturn.ŠRTS—* ŠPAGEJ****************************************************************************‰TRANSMIT--IMAGEWRITESTATE*2*‰XMITbrancheshereiftransmitstateisS_IMAGE.<*‰Thisroutine'sjobistooutputcharactersfromtheuser's*‰bufferinIMAGEMODE.*,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** X_IMAGE: <ŠMOVE.LWBUF_PTR(A5),A0„A0<--writebufferpointer.‚Ifit'sAŠIF.LA0WBUF_EAD(A5)THEN‚pasttheendofthewritebuffer, ,ŠBSR„SET_CNTŒSetcountifwe'resupposedto,2ŠCLR.W‚XMIT_ST(A5)ˆsettransmitstatetoIDLE,andŠBRA„X_IDLEexit. #ŠELSE–Else(stillmoretotransmit) .ŠMOVE.B(A0)+,D0‹D0<--nextchartotransmit.8ŠMOVE.LA0,WBUF_PTR(A5)„Updatethewritebufferpointer. ŠENDI  -ŠBRA„XMIT_D0ŒExittotransmitthecharinD0.ŠPAGEJ***************************************************************************#*‰TRANSMIT--FORMATTEDWRITESTATE*3*‰XMITbrancheshereiftransmitstateisS_FORMAT.>*‰Theideahereistooutputcharactersfromtheuser'sbuffer*‰inFORMATTEDMODE.**‰Entry:A5=addressofCCB(*A1=addressofoursideofthedevice*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** X_FORMAT: *0*‚Havewealreadytransmittedtheentirebuffer?*4ŠMOVE.LWBUF_PTR(A5),A0„A0<--writebufferpointer.:ŠCMP.L‚WBUF_EAD(A5),A0„Ifit'spasttheendofthebuffer,ŠBHI„X_F_TERM‹gofinishup. *;*‚There'smoretotransmit.‚GetnextcharandcheckforCR.*+ŠMOVE.B(A0)+,D0‹Getnextcharfrombuffer.ŠCMP.B‚#CR,D0Ifit'saCR,ŠBEQ„X_F_TERM‹gofinishup. *E*‚Nota  CR,soupdatethepointer,incrementtheCOLUMNcountifit's#*‚aprintablechar,andgosendit.*4ŠMOVE.LA0,WBUF_PTR(A5)„Updatewritebufferpointer. @ŠIF.BD0#HI_CTLTHEN„Ifit'saprintablechar(between$20;ŠADD.L‚#1,COLUMN(A5)†and$FF,inclusive),updatethecolumn ŠENDI–count. !ŠBRA.L‚XMIT_D0ŒExittosendchar.ŠPAGEJ*****************************************************************************‰FINISHUPAFORMATTEDMODEWRITEREQUEST*7*‰DoesthewrapupforX_FORMATwheneverythingissent.9*‰The#ofbytestransferredisrecordedifnecessaryand;*‰theend-of-linestringisqueuedfortransmit(unlessthe8*‰#ofprintablechar'ssentisanexactmultipleofthe*‰configuredlinelength).*/*‰Entry:A1=addressofoursideofthedevice*A5=addressofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** X_F_TERM: .ŠCLR.W‚XMIT_ST(A5)ˆSettransmitstatetoIDLE. )ŠBSR„SET_CNTŒSetbytecountifnecessary. 8ŠMOVE.LCOLUMN(A5),D0†D0<--#ofprintablechar'ssent.(ŠCLR.L‚D1‘D1<--configuredlinelength.ŠMOVE.WCONFIG+IOSREC(A5),D1-ŠBEQ„X_F_EOLŒIfthat's0,gosendEOLstring. .ŠREPEAT”Seeif#ofprintablecharssentisan2ŠSUB.L‚D1,D0ŽexactmultipleoftheconfiguredlineŠUNTIL‚length. ŠIF…THENŠIfnot,GX_F_EOLƒMOVE.LCONFIG+IOSEOL(A5),D0ƒPuttheend-of-linestringintotheŠBSR.L‚Q4_XMITŒtransmitqueue.*%%%%%%%%%‚BWN‚10/9/84*<*‰AbackgroundXMITroutineisnowscheduledtorun,sojust*‰return*ŠRTS*,*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠENDI–*  ŠBRA„XMITNowtryitagain.ŠPAGEJ****************************************************************************‰TRANSMIT--CANCELSTATE*3*‰XMITbrancheshereiftransmitstateisS_CANCEL.5*‰Outputsuntilallchar'stypedin5*‰areerased.‚Usedonlyforformattedmodereadswhen(*‰theHARDCOPYattributeisNOTset(0).*/*‰Entry:A1=addressofoursideofthedevice*A5=addressofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.:*‰RTSoutofbackgroundtoEXECifthereissomethingleft *‰tocancel,*‰elsetoX_IDLE.*J************************************************************************** X_CANCEL: ;ŠTST.L‚CHAR_CNT(A5)‡Iftherearemorechar'slefttoerase,ŠIF…THENŠ* <ŠSUBQ.L#1,CHAR_CNT(A5)„Decrement#ofchar'slefttoerase.*%%%%%%%%%ƒBWN9/24/84ŠMOVE.L#BS_SP_BS,D0D**ˆMOVE.L#SPACE<<24+BS<<16,D0‚Putspaceandbackspaceintothexmit6ŠBSR.L‚Q4_XMITŒqueueandexittotransmitabackspace.ŠRTS*%%%%%%%%%%%%%%%%%%%%%**ˆMOVEQ‚#BS,D0***ˆBRA„XMIT_D0Œ* ŠENDI  >ŠCLR.W‚XMIT_ST(A5)ˆOtherwise(everythingerased),settransmit%ŠBRA.L‚X_IDLEstatetoIDLEandexit.ŠPAGEJ****************************************************************************‰TRANSMIT--REPRINTSTATE*3*‰XMITbrancheshereiftransmitstateisS_REPRNT.=*‰UsedwhentheREPRINTLINEchariskeyedduringaformatted=*‰moderead.‚Takescharactersfromtheuser'sreadbufferand>*‰echoesthemtotheterminal,expandingcontrolcharactersto*‰their2-charequivalents.*,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.=*‰BranchestoXMIT_D0(withcharinD0)ifsomethingwasleft*‰toreprint,elsetoX_IDLE.*J************************************************************************** X_REPRNT: 4ŠMOVE.LWBUF_PTR(A5),A0„A0<--writebufferpointer.@ŠIF.LA0RBUF_PTR(A5)THENƒIfwehavereprintedeverything, 7ŠCLR.W‚XMIT_ST(A5)ˆSettransmitstatetoIDLEan  dexit. ŠBRA„X_IDLE* ŠENDI  9ŠMOVE.B(A0)+,D0‹Otherwise(moretoreprint)getthenext?ŠMOVE.LA0,WBUF_PTR(A5)„char,updatethepointer,andincrement6ŠADDQ.L#1,CHAR_CNT(A5)„the#ofchar'sonthescreen. 2ŠIF.BD0#HI_CTLTHENIfit'sacontrolchar, >ŠADDQ.L#1,CHAR_CNT(A5)„Increment#ofchar'sonscreenagain,6ŠADD.B‚#$40,D0Œputthecharacter'svisiblecounterpart*%%%%%%%%%%%%%‚BWN‚10/1/84,*…ThissequencedoesnotworkontheMVME115*4**ˆBSR.L‚Q_XMITinthetransmitqueue,andsetupto)**ˆMOVE.B#CARET,D0Štransmitacaret(^).*B*„Putallthecharacterswewanttotransmitintothequeuefirst.*2*‰AND.L‚#$FF,D0ŒClearoutallbutlowerbyteinD0-ŠSWAPƒD0‘Getcharacterinsecondhighestbyte/ŠOR.Lƒ#CARET<<24,D0†Putacaretintoupperbyte/ŠBSR.L‚Q4_XMITŒGetintotransmitqueueandcall*£backgroundXMIT.ŠRTS*D*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ŠENDI %ŠBRA.L‚XMIT_D0ŒExittotransmitchar.ŠPAGEO********************************************************************************$*‰SPECIALTRANSMITROUTINESEXECUTOR*A*‰Normaltransmitprocessinghasbeensuspendedduetoanoddball=*‰requirement,orperhapsseveraloddballrequirements.‚ItisD*‰thisguy'sjobtogetcontroltotheguyswhohandletheseoddballF*‰things,andwhenthey'refinallydone,returntothenormaltransmit-*‰processingweweredoingorshoulddonext.**‰Entry:%*A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver**‰Exit:*O********************************************************************************=*‰ThecalledroutinecancountonA1andA5beingastheyare?*‰definedaboveandshouldleavethemthatway,ofcourse.‚NoteB*‰thatunliketheWORKbyteexecutor,whichmaylooksimilar,thisE*‰executordoesnotloopuntilthemagicfield(inthiscaseSPECIAL)A*‰isclear;thatis,onlyoneroutinegetscalled,andonlyonce,@*‰bythisexecutoruntilsomethinghappenstocauseX_SPECIALtoE*‰runagain.‚ThatmeansthereisaninherentpriorityintheorderingA*‰ofthetestsbelow.‚Forexample,theXOFFcharwillnotbesent**‰untilabreakbeingtransmittedexpires.*O******************************************************************************* X_SPECIAL: EŠBTST#SPEC_BREAK,SPECIAL(A5)‚Ifwe'reintheprocessoftransmitting#ŠBNE„X_BREAKŒabreak,gohandleit. >ŠBTST#SPEC_XOFF,SPECIAL(A5)‚IfanXOFFcharneedstobesent,ŠBNE„X_XOFFgohandleit. <ŠBTST#SPEC_XON,SPECIAL(A5)‚IfanXONcharneedstobesent,ŠBNE„X_XONŽgohandleit. :ŠBTST#SPEC_BLOCK,SPECIAL(A5)‚Ifwe'reblockedbyanXOFF,ŠBNE„X_BLOCKŒgohandleit. DŠBTST#SPEC_NUL,SPECIAL(A5)‚Ifwe'resendingNULchar'sforpadding,ŠBNE„X_NULŽgohandleit. DŠBTST#SPEC_QUEUE,SPECIAL(A5)‚Ifthere'sstuffinthequeuetosend,ŠBNE„X_QUEUEŒgohandleit.  *F*‚Apparentlythere'snothingspeciallefttodo,sowecanrestorethe@*‚oldtransmitstateandseeifthere'sanything'normal'todo.*%ŠMOVE.BOLD_XMIT_ST(A5),XMIT_ST+1(A5) ŠBRA„XMIT_JMPŠPAGEO*********************************************************************************‰TRANSMITTINGABREAK*A*‰Thisisthespecialhandlerinforcewhilewe'retransmittinga?*‰breaksignal.‚There'sreallynothingtodobutwaituntilthe*‰breakisover.**‰Entry: *A1=addressofourthedevice*A5=addressofCCB*A4=addressofdriver*O******************************************************************************* X_BREAK: -‰RTS˜Justlookforother,non-transmit,work. ŠPAGEO********************************************************************************;*‰TRANSMITANXOFFCHARACTERRIGHTNOW(TOSTOPthedevice)*>*‰Becausethereceivequeuegotprettyfull,transmissionfrom>*‰thedeviceneededtobesuspended.‚Becauseweareconfigured>*‰touseXONandXOFFincontrollingthedevice'stransmitter,C*‰wec amehere(justputtinganXOFFinthetransmitqueuewouldn'tD*‰haveworked,sincetheremayhavebeenalotofstuffinthequeue*‰aheadofit).**‰Entry:%*A1=addrofoursideofthedevice*A5=addrofCCB*)*§startingwiththecheckformorechars. O******************************************************************************* X_XOFF: =ŠBCLR#SPEC_XOFF,SPECIAL(A5)‚Cleartheflagthatgotushere. 2ŠMOVE.BCONFIG+IOSXOF(A5),D0‚D0<--theXOFFchar.ŠBRA„FORCE_D0‹Gotransmitit.ŠPAGEO********************************************************************************<*‰TRANSMITANXONCHARACTERRIGHTNOW(TOUNSTOPthedevice)*@*‰Sometimeearlierthereceivequeuegotprettyfullandwesent>*‰anXOFFcharactertothedevicetostopitfromsendingmore?*‰characters.‚Sincethenwehavemaderoominthequeue,sonowB*‰wewanttoletthedevicecontinuetransmittingtousbysending@*‰himanXONcharacter.‚JustputtinganXONcharinthetransmit8*‰queuewouldn'tworksincehemayhavesentusanXOFF.**‰Entry:%*A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver*O******************************************************************************* X_XON: <ŠBCLR#SPEC_XON,SPECIAL(A5)‚Cleartheflagthatgotushere. 1ŠMOVE.BCONFIG+IOSXON(A5),D0‚D0<--theXONchar.ŠBRA„FORCE_D0‹Gotransmitit.ŠPAGEO********************************************************************************.*‰BLOCKEDBYANXOFFCHARACTERFROMthedevice*?*‰Thisisthespecialhandlerinforcewhilewe'reblockedfrom@*‰transmittingbyanXOFFcharreceivedfromthedevice.‚There's;*‰reallynothingtodobutwaituntiltheXONchararrives.**‰Entry: *A1=addressofourthedevice*A4=addressofCCB*O******************************************************************************* X_BLOCK: -‰RTS˜Justlookforother,non-transmit,work.ŠPAGEO*********************************************************************************‰TRANSMITNULCHARACTERS*0*‰XMITbrancheshereiftransmitstateisS_NUL.:*‰UsedtooutputtheconfigurednumberofASCIINULchar's *‰wheneveraCRorLFisoutput.*,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver*<*‰Sincethisisnotasubroutine,registersatexitarejust-*‰theentryrequirementsofthenextroutine.*J************************************************************************** X_NUL: 5ŠTST.B‚NUL_CNT(A5)ˆIftherearenomoreNULstosend,ŠIF…THENŠ*@ŠBCLR#SPEC_NUL,SPECIAL(A5)‚clearthespecialflagwhichgetsus,ŠBRA„X_SPECIALŠhereandseewhattodonext.ŠENDI–* $ŠMOVEQ‚#NUL,D0ŒPutaNULcharinD0,7ŠSUBQ.B#1,NUL_CNT(A5)…decrementthe#ofNULstosend,ŠBRA„XMIT_D0Œandgosendit.ŠPAGEO*********************************************************************************‰TRANSMIT--QUEUESTATE*@*‰XMITbrancheshereiftransmitstateisS_QUEUE.‚TheideahereA*‰istotakecharactersoutofthetransmitqueue,oneatatime,8*‰andfeetthemtothedevice,untilthequeueisempty.*,*‰Entry:A1=addrofoursideofthedevice*A5=addrofCCB*A4=addressofdriver*O******************************************************************************* 9X_QUEUE:‚TST.W‚TQ_CNT(A5)‰Ifthetransmitqueueisempty,ŠIF…THENŠ*DŠBCLR#SPEC_QUEUE,SPECIAL(A5)‚Cleartheflagcorrespondingtooutput9ŠBRA„X_SPECIALŠfromthetransmitqueueandgoseewhattoŠENDI–donext. 9ŠMOVE.WTQ_GET(A5),D1†D1<--pointertonextbytetoget.<ŠMOVE.BTQ(A5,D1.W),D0…D0<--nextbytefromtransmitqueue.?ŠSUBQ.W#1,TQ_GET(A5)†Advancethegetpointer(circularqueue).ŠIF…THENŠ*ŠMOVE.W#TQ_MAX,TQ_GET(A5)*ŠENDI–*>ŠSUBQ.W#1,TQ_CNT(A5)†Decrementthetransmitqueuecharcount. ŠBRA„XMIT_D0ŒGosendit.ŠPAGEJ***************************************************************************8*‰ SUBROUTINETOPUTUPTO4CHARACTERSINTRANSMITQUEUE*9*‰Takescharactersleft-to-rightfromD0andputsthemin;*‰thetransmitqueue.‚TrailingNULcharactersarenotsent.=*‰Theroutinestopsqueueingwhenall4charactersarequeued:*‰ortheremainingcharactersareall$00.‚Forexample,if8*‰D0=$0D0A0000,first$0Dwillbequeued,then$0A.*?*‰Note:‚thisroutineassumesthereisroominthequeuetohold*thecharacters!!!*;*‰Entry:D0=0-4char's,left-justified,toputinqueue*A5=addressofCCB*A4=addressofdriver**‰Exit:‚D0=garbage*D1=garbage*J************************************************************************** Q4_XMIT: 3ŠROL.L‚#8,D0ŽGetleftmostbyteintopositioninD0.1ŠIF…THENŠIfthere'sanythingatalltosend, 7**ˆBSR„Q_XMITSendthefirstcharusingthefullQ_XMIT7**ˆBRA„Q4_XMIT1‹routinewhichsetsupaddressesandthe(*§transmitstate,andjumpintotheloop)*§startingwiththecheckformorechars. !ŠREPEAT”Foreachadditionalbyte,1ŠBSR„Q_IT.QueuethebyteinD0usingthesecond;Q4_XMIT1‚CLR.B‚D0‘.entrypoint(wesetaddressesthefirst7ŠROL.L‚#8,D0Ž.time),clearthatbyteandgetthenext.(ŠUNTIL‚Stopwhenonly0'sareleft.  ***%%%%%%% BWN 7/27/84* *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%**;*‚SetupforthespecialguyX_QUEUEtodequeuethisstuff.*4ŠBSR„SET_SPECIALˆPutusinSPECIALmodesuchthatwe;ŠBSET#SPEC_QUEUE,SPECIAL(A5)‚willtransmitfromthequeue.*%%%%%%%%%%%%%%%%%bwn‚7/9/847**ˆBSET#W_XMIT,WORK(A5)…Markworkforthetransmitter. ‰BKGRND„XMIT2*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠENDI ŠRTS—Exit.ŠPAGEJ****************************************************************************‰PUTCHARINTRANSMITQUEUE*>*‰PutsthecharinD0.Bintothetransmitqueue.‚IfQ_XMIThas=*‰justbeencalledandmorechar'sneedtobequeued,youmay,*‰callQ_ITinsteadofQ_XMITandsavetime.*A*‰BWNrevised7/27/84:‚can'tcallXMITuntiltherearecharacters*‰inthebuffer.*@*‰Note:‚thisroutineassumesthereisroominthetransmitqueue*forthechar!!!*$*‰Entry:D0.B=chartoputinqueue*A5ƒ=addressofCCB*A4=addressofdriver**‰Exit:‚D1=garbage*J************************************************************************** Q_XMIT: *%%%%%%%%%%%ƒBWN‚7/27/84*$*‚PutthebyteinD0intothequeue.* ‰BSR‡Q_IT *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%**;*‚SetupforthespecialguyX_QUEUEtodequeuethisstuff.*4ŠBSR„SET_SPECIALˆPutusinSPECIALmodesuchthatwe;ŠBSET#SPEC_QUEUE,SPECIAL(A5)‚willtransmitfromthequeue.*%%%%%%%%%%%%%%%%%bwn‚7/9/847**ˆBSET#W_XMIT,WORK(A5)…Markworkforthetransmitter. ‰BKGRND„XMIT‰RTS*%%%%%%%%%%%%%%%%%%%%%%%%%%%%‰PAGEL*****************************************************************************J*‚PutthebyteinD0intothequeue.‚Thisroutinecanbecalledseparately;*‚ifQ_XMITwasjustcalled(toqueuemultiplecharacters).**ˆEntry:A5=addrofCCB$*D0.B=charactertoputintoqueue*I*************************************************************************=Q_IT:…MOVE.WTQ_PUT(A5),D1†D1<--transmitqueueputpointer.=ŠMOVE.BD0,TQ(A5,D1.W)…Movethecharintothetransmitqueue.7ŠSUB.W‚#1,TQ_PUT(A5)†BacktheputpointeruponeintheŠIF…THENŠcircularqueue.ŠMOVE.W#TQ_MAX,TQ_PUT(A5)*ŠENDI–*=ŠADD.W‚#1,TQ_CNT(A5)†Incrementthetransmitqueuebytecount. ŠRTS—Return.ŠPAGEO********************************************************************************$*‰CHANGETRANSMITTERTOSPECIALMODE*?*‰WhenyouwantoneofthespecialtransmitguystotemporarilyB*‰takecontrol,youcallthisroutineandthensettheappropriate>*‰entryinthespecialbyte.‚Thisroutinetakescareofsaving?*‰theoldtransmitstateifweweren'tinSPECIALmodealready.%*‰Thatcallingsequenceisimportant:*BSR„SET_SPECIAL*BSETƒ#SPEC_xxxx,SPECIAL(A5)7*‰Theorde risimportant,too--don'tdotheBSETfirst!**‰Entry:*A5=addressofCCB*A4=addressofdriver**‰Exit:*O******************************************************************************* SET_SPECIAL: 7ŠTST.B‚SPECIAL(A5)ˆIfwe'renotalreadydoingsomethingŠIF…THENŠinSPECIALmode, AŠMOVE.BXMIT_ST+1(A5),OLD_XMIT_ST(A5)‚savetheoldtransmitstate:ŠMOVE.B#S_SPECIAL,XMIT_ST+1(A5)‚andchangeittoSPECIAL. ŠENDI–*  ŠRTS—Andreturn.ŠPAGEO********************************************************************************5*‰BLOCKUSFROMTRANSMITTING(BECAUSEWEGOTANXOFF)*?*‰WereceivedanXOFFcharfromtheuser,whichmeansweshould?*‰stoptransmittinguntilwegetanXON.‚Thisguy'sjobisjust=*‰togetthetransmitterintothespecialmodewherehewaits*‰fortheXON.*"*ˆBLOCK0(backgroundentrypoint):-*A1=addressofbackgroundactivationblock**ˆBLOCKentrypoint:*‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*A4=addressofdriver*O******************************************************************************* *%%%%%%%%%%%%%%%%%bwn‚7/9/84BLOCK0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.**‰LEA‡-BLOCK_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%BLOCK: =ŠTST.B‚BLOCKED(A5)ˆIfwe'restillblocked(wemightnotbeif6ŠIF…THENŠaRESETwasdonerightafterRCAsawthe *§XOFFchar), (ŠBSR„SET_SPECIALˆPutusinSPECIALmode.DŠBSET#SPEC_BLOCK,SPECIAL(A5)‚Inparticular,weareblockedbyXOFF. ŠENDI–*  ‰RTSŠPAGEO********************************************************************************1*‰UNBLOCKOURTRANSMITTER(BECAUSEWEGOTANXON)*?*‰WehadbeenblockedbyanXOFFcharreceivedfromthedevice.@*‰WegottheXONnow,though,soit'stimetocontinue.‚Thisguy7*‰allowsthetransmittertocontinuewhereheleftoff.*$*ˆUNBLOCK0(background)entrypoint:-*A1=addressofbackgroundactivationblock**ˆUNBLOCKentrypoint:*‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*A4=addressofdriver*O******************************************************************************* *%%%%%%%%%%%%%%%%%bwn‚7/9/84 UNBLOCK0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.**‰LEA‡-UNBLK_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%UNBLOCK: )ŠSF…BLOCKED(A5)ˆWeain'tblockednomore.@ŠBCLR#SPEC_BLOCK,SPECIAL(A5)‚Takeoutthespecialflagtowait. *%%%%%%%%%%%%%%%%%bwn‚7/9/848**ˆBSETW‚#W_XMIT,WORK(A5)ƒMarkworkforthetransmitter. ‰BKGRND„XMIT **ˆBRA„CHECK_WORK‰Andexit.‰RTS1*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠPAGEO********************************************************************************(*‰STOPIT(thedevice)FROMTRANSMITTING*?*‰Ourreceivequeuegottoofull,sothisguygotinvoked.‚It's@*‰hisjobtostopthedevicefromtransmitting.‚DependingonhowA*‰we'reconfigured,thateitherinvolvesloweringahardwareline3*‰orarrangingforthetransmittertosendanXOFF.*$*ˆSTOP_IT0(background)entrypoint:-*A1=addressofbackgroundactivationblock**ˆSTOP_ITentrypoint:*‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*A4=addrofdriver*O******************************************************************************* *%%%%%%%%%%%%%%%%%bwn‚7/9/84 STOP_IT0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.*)‰LEA‡-STOP_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC 1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%STOP_IT: )ŠST…STOPPED(A5)ˆFlagthatwestoppedhim. <ŠBTSTW‚#IOAXCTL,CONFIG+IOSATW(A5)‚Ifwe'reconfiguredtouse ŠIF…THENŠXON_XOFFforthis, 5ŠBSR„SET_SPECIALˆPutthetransmitterinSPECIALmode.DŠBSET#SPEC_XOFF,SPECIAL(A5)‚Inparticular,wewanttosendanXOFF.*%%%%%%%%%%%%%% BWN 7/9/848**ˆBSETW‚#W_XMIT,WORK(A5)ƒMarkworkforthetransmitter. ‰BKGRND„XMIT *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% )ŠELSE–else(we'reconfiguredtouseDTR),(*%%%%%%%%‚BWN9/24/84‚INHIBITINTERRUPTSŠINHIBIT2ŠT_JSR…DDP_STOPˆCallthedevice-dependentroutine.ŠUNMASK'*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ŠENDI  **ˆBRA„CHECK_WORK‰Andexit.‰RTSŠPAGEJ***************************************************************************%*‰LOGERRORONRECEIVEDCHARANDEXIT*;*‰Somesortoferrorhashappenedassociatedwithreceiving<*‰acharacter.‚Rememberthiserrorbyrecordingtheposition0*‰ofthenastycharacter,andthetypeoferror.**‰Entry:D0.B=errorcode*A5ƒ=addressofCCB**J************************************************************************** LOG_ERR: 3ŠTST.W‚ERR_PTR(A5)ˆIfthereisn'talreadyanerror, ŠIF…THEN =ŠMOVE.BD0,ERR_CODE(A5)„Savetheerrorcode&thelocationof0ŠMOVE.WRQ_PUT(A5),ERR_PTR(A5)ƒtheproblemchar. *J*‚OrdinarilyjustcopyingRQ_PUTatthetimetheerroroccurredisenough,J*‚butifthereceivequeueisfulltheerrorpointerisaimedatthefirstE*‚charinthequeue,sowehavetobackitupone.‚Sincethecircular7*‚queuefillsandemptiesbackwards,thismeansweadd.*:ŠIF.WƒRQ_CNT(A5)#RQ_MAXTHENƒIfthereceivequeueis9ŠADD.W‚#1,ERR_PTR(A5)…full,backtheerrorpointerupone:ŠIF.WERR_PTR(A5)#RQ_MAXTHENƒbyte(circularqueue).ŠCLR.W‚ERR_PTR(A5)ˆ*ŠENDI–*ŠENDI–* ŠENDI ‰RTS ŠPAGEJ***************************************************************************(*‰GETLENGTHOFSUCCESSFULDATATRANSFER*<*‰Usedduringabortiveprocessing(HALTI/OcommandorBREAK:*‰signalreceived)todeterminethe#ofbytestransferred*‰beforetheabort.**‰Entry:*A5=addressofCCB*(*‰Exit:‚D0=the#ofbytestransferred.*J************************************************************************** GET_LEN: @ŠMOVE.LXFER_LEN(A5),D0„D0<--lengthofdatatransferasstored2ŠIF…THENŠinCCB.‚Ifthat's0(wasneverset), :ŠTST.B‚INPUT(A5)ŠIfweweredoingREADorOUTPUTW/INPUT,ŠIF…THENŠ*BŠMOVE.LRBUF_PTR(A5),D0„D0<--theamountofthereadbuffersent;ŠSUB.L‚RBUF_SAD(A5),D0„* ŠELSE–else(weweredoingWRITE)CŠMOVE.LWBUF_PTR(A5),D0„D0<--theamountofthewritebuffersent;ŠSUB.L‚WBUF_SAD(A5),D0„*ŠENDI–* ŠENDI  ŠRTS—Exit.ŠPAGEJ****************************************************************************‰RESET*?*‰ThisisthebackgroundRESEThandler.‚Itisinvokedprimarily?*‰whensomeoneincommandservicewantstodoareset.‚Itcan't>*‰bedonefromthere,ofcourse,sotheworkflagforRESETis!*‰setandthebackgroundinvoked.*>*‰Thisroutinemainlyjustsetsalotofflagsandpointersin*‰theCCBtoknownstates.**‰Entry:A5=addrofCCB**‰Exit:*J************************************************************************** RESET: 3ŠMOVEM.LA1,-(A7)‡saveusedregistersonthestack. **‚Firstemptythequeues.*(ŠBSR.L‚EMPTY_RQ‹Emptythereceivequeue. 4ŠMOVE.W#TQ_MAX,TQ_GET(A5)Emptythetransmitqueue.ŠMOVE.W#TQ_MAX,TQ_PUT(A5)*ŠCLR.W‚TQ_CNT(A5)‰* **‚SetsomestatestoIDLE.*.ŠCLR.W‚XMIT_ST(A5)ˆMaketransmitprocessIDLE.;ŠCLR.B‚SPECIAL(A5)ˆNospecialthingsforthexmittertodo.-ŠCLR.W‚RECV_ST(A5)ˆMakereceive‚processIDLE. *=*‚IfweweredoingI/O,zapthemenuanddecrementthetask's*‚outstandingI/Ocount.*%ŠTST.B‚MENU(A5)‹IfweweredoingI/O,ŠIF…THENŠ*%ŠCLR.L‚M ENU(A5)‹SetmenuINACTIVEand,ŠMOVE.LTCB_ADDR(A5),A1„decrementI/Ocount.ŠSUB.B‚#1,TCBIOCNT(A1)„*ŠENDI–* *5*‚Setabunchofflagstoreasonablestartingvalues.*5ŠSF…DISCARD(A5)ˆForgetaboutanyDISCARDOUTPUTchar. 7ŠSF…INPUT(A5)ŠWe'renotdoingaREADorOUTPUTw/INPUT8ŠSF…INHIB_DO(A5)‡TheDISCARDOUTPUTfunctionisallowed. 6ŠSF…WAIT_TQ(A5)ˆReceiveprocessisnotwaitingforthe*§transmitqueuetoempty. 5ŠSF…BLOCKED(A5)ˆWe'renotwaitingforanXONanymore. (ŠCLR.B‚NUL_CNT(A5)ˆNonullstotransmit.  ‰MOVEM.Lƒ(A7)+,A1‰RTSŠPAGEO********************************************************************************!*‰BEGINTRANSMITTINGBREAKSIGNAL*:*‰ThisroutineispartoftheTRANSMITBREAKcommand.‚When=*‰thecommandisreceived,thisroutinegetsinvokedtostart=*‰thedevicesendingthebreaksignal.‚Wesetatimerhereto?*‰interrupt(andgotoroutineSTOP_BRK)whentheproperlength!*‰forabreaksignalhasexpired.*B*‰ThisroutineiscalledusingBACKGROUNDsoweenteratinterrupt6*‰level0,andwemustmustexitatinterruptlevel0.6*‰WemustalsorestoreregisterA7ifwemesswithit.@*‰Otherthanthat,wearefreetoreturnwhateverwelikeinthe *‰registers.**"*ˆB_BRK0(background)entrypoint:.*A1=addressofbackgroundactivationblock.**ˆBEG_BREAKentrypoint:*‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*A4=addrofdriver*O********************************************************************************%%%%%%%%%%%%%%%%%bwn‚7/9/84B_BRK0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.**‰LEA‡-B_BRK_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% BEG_BREAK: :ŠMOVEM.LD2-D7/A1-A5,-(SP)‚Saveregisterswe'llblowaway. *(*‚Startthedevicesendingbreaksignal.**ŠINHIBIT‰T_JSR…DDP_BEG_BREAK‰UNMASK *9*‚Setupthetransmittertowaituntilthebreakisover.*5ŠBSR„SET_SPECIALˆPutthetransmitterinSPECIALmode.BŠBSET#SPEC_BREAK,SPECIAL(A5)‚Specifically,waitforbreaktoend. *<*‚Callexectosettimerforhoweverlongbreakshouldlast.*=ŠLEA„STOP_BRK(PC),A0„A0<--addrtogotowhentimerexpires.<ŠMOVE.L#BRK_LEN,A1ˆA1<--#ofmillisectomaintainsignal.*ŠMOVE.L#1,D1ŽInterruptlevelshouldbe1.%ŠMOVE.LA5,D2ŽIDwillbeCCBaddress.'ŠTR0$.RQPA,Askexectosetthetimer.5ŠBRA„OK_TIMER‹Ifalliswell,gosetuptostartI/O.9ŠTR0$.KILLER,Ifsomethingwentwrong,crashthesystem. COK_TIMER‚MOVEM.L(SP)+,D2-D7/A1-A5All'swell,sorestoreregisters‰RTSŠPAGEH*************************************************************************7*‰SPECIALINTERRUPTSERVICEROUTINEFORTIMERINTERRUPT*˜TOSTOPBREAKSIGNAL*8*‰WhenthetimersetbytheBEG_BRKroutineexpires,the5*‰exectransferscontroltothisroutine.‚Wemakethe>*‰environmentlooklikeitdoesforathedeviceinterruptand5*‰invokebackgroundroutineEND_BREAKtoturnitoff.*;*‰Entry:D0,A0,A1havebeensavedbyexecandareavailable9*D1=addressofCCB(becausewemadethatthetimerID)**‰Exit:*D0,A0,A1=garbage.*I************************************************************************* STOP_BRK: *G*‚Maketheenvironmentlooklikewhatthebackgroundexpects.‚NotethatH*‚sincewearenotbeingcalledfromCMR,A5doesnotinitiallypointto4*‚theCCB.‚Hencethat'sourfirstorderofbusiness.* ŠPUSH.LA5‘SaveA5onthestack.$ŠMOVE.LD1,A5ŽA5<--addressofCCB.*A*‚Ifwe'reintransparentmode,callthetaskwe'reconnectedto.*0ŠTST.B‚TR_MODE(A5)ˆIfwe'reintransparentmode,ŠIF…THENŠ* **‚Disableinterrupts.*0ŠPUSHƒSR‘SavetheexistingSRandmakesurethat2ŠMOVEƒSR,D0Žinterr uptsaredisabledbyraisingthe&ŠADD„#$0100,D0Šinterruptlevelbyone. ŠMOVEƒD0,SRŽ* *)*‚Stopthedevicefromsendingthebreak.*‰MOVE.L„CCBCHB(A5),A1*5*‚TouseT_JSR,wemusthavethedriveraddressinA4* ‰PUSH.L‚A4A DFF"N*H2L:>BWJCR ‰MOVE.L‚DRV_ADDR(A5),A4‰T_JSR…DDP_END_BREAK ‰POP.LƒA4 7ŠPOP„SRRestoretheinterruptlevelwewereenteredat. *8*‚CalltheTMtasktolethimknowhecantransmitmore.*EŠMOVE.LHIS_BRA_TBL(A5),A0A0<--addrofthetask'sinterfacetable.@ŠJSR„TM_BRK_OVER(A0)„JSRtotheentrythatsays'breakisover.' +ŠELSE–else(we'renotintransparentmode), *#*‚We'reNOTintransparentmode....=*‚InvokethebackgroundroutineEND_BREAKtostopthesignal.* ‰BKGRND„E_BRKD**ˆBSETW‚#W_END_BREAK,WORK(A5)‚Markworkforthebackgroundhandler.*%%%%%%%%%%%%%%%% ŠENDI *&*‚Nowreturnfromthetimerinterrupt.*.ŠPOP.L‚A5‘RestoreA5andreturnfromthetimerŠRTE—interrupt.ŠPAGEO*********************************************************************************‰ENDBREAKTRANSMISSION*=*‰ThisisfortheTRANSMITBREAKcommand.‚Whenthetimergoes>*‰off,sayingwe'vebeensendingthebreaksignallongenough,;*‰theinterruptserviceroutineforthetimergetsthisguy<*‰running.‚Thisiswherewestopthedevicefromsendingthe7*‰breaksignalandsetupforthecommandtoterminate.*B*‰ThisroutineiscalledusingBACKGROUNDsoweenteratinterrupt6*‰level0,andwemustmustexitatinterruptlevel0.6*‰WemustalsorestoreregisterA7ifwemesswithit.@*‰Otherthanthat,wearefreetoreturnwhateverwelikeinthe *‰registers."*‰E_BRK0(background)entrypoint:-*A1=addressofbackgroundactivationblock**‰END_BREAKentrypoint:*‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*A4=addressofdriver**O*******************************************************************************  *%%%%%%%%%%%%%%%%%bwn‚7/9/84E_BRK0:**ƒSetupA5andA1.<*ƒWhentheexeccallsthisroutine,A1=addressoftheBAB.**‰LEA‡-E_BRK_BAB(A1),A5„A5<---CCBaddress>‰MOVE.L„CCBCHB(A5),A1‡A1<---addressofoursideofTHEDEVIC1‰MOVE.L„DRV_ADDR(A5),A4…A4<---addressofdriver*"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% END_BREAK: *E*‚IfHALTI/Ohasn'tcomeinandabreakhasn'tbeenreceived(eitherE*‚ofwhichwouldcancelthebreak),stopsendingthebreaksignaland**‚releasethetransmitprocess.*5ŠBCLR#SPEC_BREAK,SPECIAL(A5)‚Clearthespecialflag.0ŠIF…THENŠIfithadn'talreadybeencleared, ŠINHIBIT7‰T_JSR…DDP_END_BREAK‡CalllthedevicedependentroutineŠUNMASK >ŠMOVE.B#M_END,MENU(A5)„Setupthemenusothedispatcherwill(*§sendacompletionevent,andmarkwork*%%%%%%%%%%%% BWN 7/16/84 ‰BKGRND„XMIT@**ˆBSETW‚#W_XMIT,WORK(A5)ƒforthetransmittersohe'lldispatch.*%%%%%%%%%%%%%%%%%%%%% ŠENDI **ˆBRA„CHECK_WORK‰Andexit.‰RTSŠPAGEO********************************************************************************'*‰SENDTHEEVENTPRELOADEDATEVENT(A5)*>*‰SomebodyincommandserviceloadedaneventupatEVENT(A5),=*‰butofcoursehecouldn'tsenditsincetheQ_EVENTroutine;*‰canonlybecalledfromthebackground.‚Soheaskedmeto)*‰doitforhim.‚I'msuchaniceroutine.**‰Entry:)*A1=addressofoursideofthedevice.*A5=addressofCCB.*O******************************************************************************* DO_EVENT: *%%%%%%‚BWN‚8/3/84‰ST†NONINTERRUPT(A5)1ŠLEA„EVENT(A5),A0‡A0<--addressofstoredevent.)ŠBSR„Q_EVENTŒCalltheroutinetosendit.‰SF†NONINTERRUPT(A5) ‰IF‚‚THEN ŽTR0$.KILLER‰ENDI ‰RTSŠPAGEJ******************************** *******************************************5*‰QUEUEACOMPLETIONEVENTTOTHEATTACHEDTASK(IOS)*;*‰ThisroutinecallstheexectosendasmalleventtoIOS.9*‰UsesQEVNTIifwe'reprocessinganinterruptandQEVNTT*‰ifwe'renot.*7*‰NOTE:thisroutinemayonlybecalledfromwithinthe*background!!!!!*>*‰NOTE:theNONINTERRUPTflagmustbesetifyouarenotgoing8*toexitthroughthecommoninterrupthandler(CMRgoes6*totheCIH)sowe'lluseQEVENTTinsteadofQEVENTI.*4*‰NOTE:themaximumsizeofacompletioneventwhich-*thisroutinecansendisONLY12BYTESifa7*completionaddressisspecified(16bytesotherwise).*2*‰Entry:A0=addressofcompletioneventtosend.*A5=addressofCCB.**‰Exit:‚D0=garbage.*D1=garbage.7*A0=finaladdressofstartofevent(eitheroriginal*•A0valueor4less).**Conditioncodes:* *•=successfulTRAP#0call"*•=unsuccessfulTRAP#0call*;*‰Thestructureoftheeventyoumustsupplyisasfollows:*‹BYTES‚MEANING,*1„eventlengthassumingnoserviceaddress4*‰*ƒ1„eventcode(1ifnoserviceaddress,else$81)*1„eventtype*‰*ƒ1„channelkey<*‰*ƒ4„ID(DCBaddressforussincewe'reastandardchannel)*2„statusvalue%*?„otherinfo(asforabreakevent)*@*‰Fieldsmarkedby*areplacedintheeventbythisroutineand%*‰neednotbepreparedbythecaller.@*‰IfaserviceaddresswasspecifiedfortheI/O,itisinserted>*‰beforetheeventtypefield,andeventlengthandeventcode*‰aremovedback4bytes.*J************************************************************************** Q_EVENT: *%%%%%%%%‚BWN‚8/21/84*'*ƒUSETHENEWQEVENTMODULEFROMDRVLIB*=‰MOVEM.LƒD1/D3/D4,-(A7)„Savetheregisterswewillblowaway.7‰MOVE.W„XRPSTV(A0),D1‡D1.B„<---errorcode/statusvalue+‰MOVE.L„DCB_ADDR(A5),D3…D3<---DCBaddress‰MOVE.B„XRPSTA(A0),D4‰IF.B†D4‚‚#XPSNRMƒTHEN=***************************************************************ˆNORMALEVENT*=*************************************************************#“IF.BƒNONINTERRUPT(A5)‚‚#0ƒTHENBSR.LƒI_NRM_QEVENT“ELSEBSR.LƒN_NRM_QEVENT“ENDI‰ELSE“IF.BƒD4ƒ‚#XPSHLTƒTHENC*********************************************************************ˆHALTI/OEVENT*A*****************************************************************#IF.BƒNONINTERRUPT(A5)‚#0ƒTHEN§BSR.LƒI_HLT_QEVENTELSE§BSR.LƒN_HLT_QEVENTENDI“ELSEIF.BƒD4‚‚#XPSUNS‚THENF************************************************************************ˆUNSOLICITEDDEVICEEVENT*E*********************************************************************§MOVE.W‚XRPDST(A0),D4#§IF.BƒNONINTERRUPT(A5)‚‚#0THEN±BSR.LƒI_UNS_QEVENT§ELSE±BSR.LƒN_UNS_QEVENT§ENDIELSEE***********************************************************************ˆUNKNOWNTYPEOFEVENT!!!!*ˆSHOULDNEVERHAPPEN*D******************************************************************** LOOP£BRA†LOOPENDI“ENDI‰ENDI-‰MOVEM.Lƒ(A7)+,D1/D3/D4„Restoretheregisters‰RTSE*********************************************************************‰PAGEL*****************************************************************************/*ˆROUTINES„FOR„THE…INTERRUPT*'*ˆHANDLER…FOR„THE…DEVICE**ˆDEPENDENT…MODULE*L****************************************************************************‰PAGEO******************************************************************************** *‰MARK_DOWN*A*‰Thisroutineiscalledwhenthedevicedependentmoduledetects3*‰thatthechannelisdownbecauseitisnotready.**‰Entry:*A5ƒ=addrofourCCB.**‰Exit:*RTStocallingroutine.*O******************************************************************************* MARK_DOWN:‡MOVE.B„#M_DOWN,MENU(A5)‡MOVE.B„#ISTAUNR,DOWN_ERR(A5)‡RTS ‰PAGEO************************** ****************************************************** *‰TERM_UNRDY*<*‰Thisroutineiscalledbythedevicedependentmodulewhen4*‰itdiscoversthattheterminalhasbecomeunready.0*‰IfweweredoingI/Owewanttosendanevent.*‰Wealsoresetthechannel.**‰Entry:*A5ƒ=addrofourCCB.**‰Registers:‰0„1…2…3…4…5…6…7*“AŸ*…P*“D**’P=parameterregister*’R=resultregister!*’*=savedandrestoredregister*‰Exit:=*CCR=ifallwentwell,andtheeventwassuccessfully *›queued.:*–iftherewasanerrorreturnedontheTRAP#0call.**O******************************************************************************* TERM_UNRDY:%ŠTST.B‚MENU(A5)‹IfweweredoingI/O,ŠIF…THENŠ* 4ŠLEA„EVENT(A5),A0‡A0<--addresstocreateeventat.?ŠMOVE.LIOCB_ADR(A5),A1„A1<--addressoftheIOCBfortheI/O.7ŠBSR„GET_LENŒD0<--lengthofsuccessfuldatatransfer.7ŠMOVE.LD0,IOSLEN(A1)†SetthelengthfieldintheIOCB.;ŠPUT_BYTEISTANR,D0ˆSetthestatusfieldintheIOCBtoNOTŠMOVE.BD0,IOSSTA(A1)†READY. $ŠMOVE.B#10,(A0)‹Settheeventsize,.ŠMOVE.B#XPSNRM,XRPSTA(A0)settheeventtype,4ŠMOVE.WD0,XRPSTV(A0)†settheeventstatus(ISTANR). $ŠBSR.L‚RESETŽDothelesserresetand ŠPUSH.LƒA4ŠMOVE.LƒDRV_ADDR(A5),A4ŠT_JSR„DDP_RESET ŠPOP.L„A4ŠBSR.L‚Q_EVENTŒqueuetheevent.ŠENDI‰RTS ‰PAGEO******************************************************************************** *‰TERM_TBE*<*‰Thisroutineiscalledbythedevice-dependentmodulewhen6*‰atransmitbufferemptyinetrrupthasbeenreceived.8*‰Wedodifferentstuuffdependingonwhethyerwearein*‰transparentmodeornot.**‰Entry:*A5ƒ=addrofourCCB.**‰Exit:*RTStocallingroutine.*O******************************************************************************* TERM_TBE:*A*‚Ifwe'reintransparentmode,callthetaskwe'reconnectedto.*0ŠTST.B‚TR_MODE(A5)ˆIfwe'reintransparentmode,ŠIF…THENŠ* EŠMOVE.LHIS_BRA_TBL(A5),A0A0<--addrofthetask'sinterfacetable.7ŠJSR„TM_TBE(A0)‰JSRtotheentrywhichtellshimhecan)ŠRTS—transmitmore,andreturntocaller.  ŠENDI *G*‚We'renotintransparentmode,soinvokethebackgroundfortransmit.**%%%%%%%%%%%%%%%% BWN 7/9/84 ‰BKGRND„XMIT‰RTS;**ˆBSETW‚#W_XMIT,WORK(A5)ƒMarkworkforthetransmitterand(**ˆBRA.L‚BKG_EXEC‹invokethebackground.*%%%%%%%%%%%%%%%%%%%%%%%%‰PAGEO*********************************************************************************‰TERM_GOT_CHAR*<*‰Thisroutineiscalledbythedevicedependentmodulewhen*‰itreceivesacharacter.*F*‰Thisroutineshouldnotbecalledifweareinautobaudratedetect*‰mode.*A*‰Ifweareintransparentmode,dothetransparentmodereceive.5*‰Otherwise,lokkforXON,XOFF,BREAKEQUIVALENT,or*‰DISCARDOUTPUTcharacters.*?*‰Ifthecharacterisnotspecial,putitinthereceivequeue.**‰Entry:*D0.B‚=thecharacterreceived*A5ƒ=addrofourCCB.**‰Registers:‰0„1…2…3…4…5…6…7*“Aˆ*œP*“DˆP„***’P=parameterregister*’R=resultregister*’*=destroyedregister**‰Exit:*’RTStocallingroutine**O******************************************************************************* TERM_GOT_CHAR:*1*‚Wereceivedachar;areweintransparentmode?*0ŠTST.B‚TR_MODE(A5)ˆIfwe'reintransparentmode,ŠIF…THENŠ*6‰AND.BƒCHAR_MSK(A5),D0„Stripoffparityif7bits/char>ŠMOVE.LHIS_BRA_TBL(A5),A0A0<--addrofuser'sbranchtable.8ŠJSR„TM_RCA(A0)‰CallhisRECEIVEDCHARAVAILABLEroutineŠRTS—andexit.ŠENDI **H*‚Nope.‚LookforXON,XOFF,BREAKEQUIVALENT,andDISCARDOUTPUTchar's.*ŠAND.B‚CHAR_MSK(A5),D0#ŠIF…THENŠIfthecharisaNUL, 5ŠTST.B‚BLOCKED(A5)ˆIfwe'reblockedbyXOFFandwe're.ŠIF…THENŠconfiguredthatanycharisXON,1ŠTST.B‚CONFIG+IOSXON(A5)‚gotreatthisasanXON.ŠBEQ.L‚RCA_XON Œ*ŠENDI–* ?ŠBTSTW‚#IOAPNUL,CONFIG+IOSATW(A5)‚Ifwe'renotpassingnullsas2ŠIF‚‚THENŒdatainimagemode,ignorethechar.ŒRTSŠENDI "ŠELSE–else(thecharisnotaNUL) AŠIF.BD0CONFIG+IOSBRC(A5)THEN‚Ifit'sthebreakequivalent*%%%%%%%%%%%%%%%% BWN 7/9/84 ŽBKGRND„BREAKŽRTS=**ˆBSETW‚#W_BREAK,WORK(A5)‚char,markworkforthebreakrout,**ˆBRA.L‚BKG_EXEC‹andinvokethebackground.**%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠENDI–* AŠMOVE.BCONFIG+IOSXON(A5),D1„Ifwe'reconfiguredthatanycharisŠIF…THENŠXON,and)ŠTST.B‚BLOCKED(A5)ˆwe'reblockedbyXOFF,-ŠBNE.L‚RCA_XONŒgohandlethisasanXONchar.ŠENDI–* .ŠIF.BD0D1THEN†IfthisistheXONchar,/ŠTST.B‚BLOCKED(A5)ˆIfwe'reblockedbyanXOFF,+ŠBNE.L‚RCA_XONŒgohandleitasanXONchar./ŠRTS—Ifwe'renotblocked,justignoretheXON.ŠENDI–* >ŠIF.BƒD0CONFIG+IOSXOF(A5)THEN„IfthisistheXOFFchar,.ŠST…BLOCKED(A5)ˆFlagthatwe'rebeingblocked,"*%%%%%%%%%%%%%%%%%%%%%% BWN 7/9/84 ‰BKGRND„BLOCK‰RTSB**ˆBSETW‚#W_BLOCK,WORK(A5)‚markworkfortheguywhostopsusfrom9**ˆBRA.L‚BKG_EXEC‹sendingoutputandcallthebackground.*%%%%%%%%%%%%%%%%%%%%%%%%%%%%ŠENDI–* BŠIF.BD0CONFIG+IOSDOP(A5)THENƒIfthisistheDISCARDOUTPUT:ŠTST.B‚INHIB_DO(A5)‡charandthefunctionisnotcurrentlyŠIF…THENŠinhibited,4ŠNOT.B‚DISCARD(A5)ˆinverttheDISCARDflagandexit.ŠENDI–*&ŠRTS—(Ifitwasinhibited,justexit.)ŠENDI–* ŠENDI *E*‚Thecharisn'tspecial(tome).‚Trytoputitinthereceivequeue.*@ŠIF.WRQ_CNT(A5)#RQ_MAXTHEN‚Ifthereceivequeueisfull,-ŠPUT_BYTEOVERRUN,D0‡gologanoverrunerror.ŠBSR.L‚LOG_ERRŠRTSŠENDI–* 7ŠMOVE.WRQ_PUT(A5),D1†D1<--receivequeueputpointer.:ŠMOVE.BD0,RQ(A5,D1.W)…Movecharintonextspaceinqueue.,ŠSUBQ.W#1,RQ_PUT(A5)†Decrementputpointer."ŠIF…THENŠIfithasreached0,=ŠMOVE.W#RQ_MAX,RQ_PUT(A5)setittothemax(it'scircular).ŠENDI–*9ŠADDQ.W#1,RQ_CNT(A5)†Incrementreceivequeuecharcount. *D*‚Thecharisnowinthereceivequeue.‚IfitisgettingdangerouslyE*‚closetobeingfull,wehavetogetthebackgroundroutinestostop*‚thedevicefromtransmitting.*AŠIFRQ_CNT(A5)#NEAR_FULTHEN‚Ifreceivequeueisnearfull,*%%%%%%%%%%%%%%%% BWN 7/9/84 ‰BKGRND„STOP@**ˆBSETW‚#W_STOP_IT,WORK(A5)‚markworkfortheguywhostopsthe*%%%%%%%%%%%%%%%%%%%%%%%%% ŠENDI–device. *0*‚Invokethebackgroundtoletthereceiverrun.**%%%%%%%%%%%%%% BWN 7/9/84RCA_EXITBKGRND„RECV‰RTSI**RCA_EXIT‚BSETW‚#W_RECV,WORK(A5)ƒMarkthatthere'sworkforthereceiver,**ˆBRA.L‚BKG_EXEC‹andinvokethebackground.*%%%%%%%%%%%%%%%%%%%%%%%%  *C*‚WegotanXONchar!‚Letthebackgrounddecidewhattodowithit.**%%%%%%%%%%%%%% BWN 7/9/84RCA_XONƒBKGRNDƒUNBLK‰RTS#**RCA_XONƒBSETW‚#W_UNBLOCK,WORK(A5)**ˆBRA.L‚BKG_EXEC"*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%‰PAGEO******************************************************************************** *‰TERM_BREAK*<*‰Thisroutineiscalledbythedevicedependentmodulewhen*‰itreceivesabreak.:*‰Wedodifferentstuffdependingonwhetherornotweare*‰intransparentmode.**‰Entry:*A5ƒ=addrofourCCB.**‰Registers:‰0„1…2…3…4…5…6…7*“Aˆ*œP*“D**’P=parameterregister*’R=resultregister*’*=destroyedregister*‰Exit:*’RTStocallingroutine**O******************************************************************************* TERM_BREAK:  *>*‚Ifwe'reintransparentmode,dothetransparentmodebreak.*0ŠTST.B‚TR_MODE(A5)ˆIfwe'reintransparentmode,ŠIF…THENŠ*  EŠMOVE.LHIS_BRA_TBL(A5),A0A0<--addrofthetask'sinterfacetable.=ŠJSR„TM_BRK_RECV(A0)„JSRtotheentrywhichtellshimwehave*§detectedabreak.  ŠRTS—Exit ŠENDI *C*‚We'renotintransparentmode;callthebackgroundbreakroutine.* ŠBKGRND„BREAK F**ˆBSETW‚#W_BREAK,WORK(A5)‚Markworkforthebackgroundbreakhandler.*%%%%%%%%%%%%%%%%%  ‰RTS ‰PAGEL******************************************************************************’TRANSPARENT„MODE**™ROUTINES*N******************************************************************************ŠPAGEO********************************************************************************!*‰TRANSPARENTMODEOUTPUTROUTINE*D*‰Thisroutineiscalleddirectlybyatask,atsupervisorlevelandG*‰atourinterruptlevel-1(atleast),tooutputachartothedevice2*‰withoutgoingthroughallthenormalprocessing.**‰Entry:*D0.B=thechartooutput.*A5ƒ=addrofourCCB.**‰Exit:<*CCR=ifthecallermustwaittobeenteredatTM_TBE/*›(viahisinterfacetable)beforecallingthis*›routineagain.5*–ifthecallermaycallthisroutineagainnow.*D0,A0aregarbage.*O******************************************************************************* TM_OUTPUT: *%%%%%%%%%%%%%% BWN 7/17/84‰MOVEM.L„A1/A4,-(SP)‰MOVE.L„CCBCHB(A5),A1;‰MOVE.L„DRV_ADDR(A5),A4†A4<---addressoddriverforT_JSR‰T_JSR…PUT_CHAR‰MOVEM.L„(SP)+,A1/A4 8ŠMOVEQ‚#0,D0ŽSetCCR:tosay'wait;I'llcallyou.' ŠRTS—Returntocallingroutine.ŠPAGEO**********************************************************************************‰TRANSPARENTMODEROUTINETOSENDABREAK*D*‰Thisroutineiscalleddirectlybyatask,atsupervisorlevelandC*‰atourinterruptlevel-1(atleast),tobegintransmissionofa?*‰breaksignalwithoutgoingthroughallthenormalprocessing.**‰Entry:*A5ƒ=addrofourCCB.**‰Exit:4*CCR=ifthecallermustwaittobecalledat**›TM_BRK_OVER(viahisinterfacetable)in3*›ordertoknowthebreakhasbeencompletelysent.8*–ifitisimpossibletosendabreaktothedevice**›orthebreakhasalreadybeencompleted.*D0,A0aregarbage.*O******************************************************************************* TM_BREAK: :ŠMOVEM.LD1-D7/A1-A6,-(SP)Saveregisterswe'llblowaway. **‚Disableinterrupts.*0ŠPUSHƒSR‘SavetheexistingSRandmakesurethat2ŠMOVEƒSR,D0Žinterruptsaredisabledbyraisingthe&ŠADD„#$0100,D0Šinterruptlevelbyone. ŠMOVEƒD0,SRŽ* *#*‚Startthedevicesendingabreak.*>**ˆMOVE.LCCBCHB(A5),A0†A0<--addrofoursideofthedevice.<ŠMOVE.LCCBCHB(A5),A1†A1<--addrofoursideofthedevice.**‡BSR‡DDP_BEG_BREAK;‰MOVE.L„DRV_ADDR(A5),A4†A4<---addressofdriverforT_JSR‰T_JSR…DDP_BEG_BREAK<**ˆMOVEQ‚#NCW5BRK,D0ˆCreateanimageofthedevice'scontrolB**ˆOR.BƒR5_thedevice(A5),D0…withtheTRANSMITBREAKbitsetandwF**ˆMOVE.B#NCW0RG5,CREG(A0)‚thatouttocontrolregister5ofourside$**ˆMOVE.BD0,CREG(A0)ˆofthedevice./*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7ŠPOP„SRRestoretheinterruptlevelwewereenteredat. *N*‚ArrangeforatimertocausetheSTOP_BRKroutinetorunwhenbreakisdone.*=ŠLEA„STOP_BRK(PC),A0„A0<--addrtogotowhentimerexpires.<ŠMOVE.L#BRK_LEN,A1ˆA1<--#ofmillisectomaintainsignal.*ŠMOVE.L#1,D1ŽInterruptlevelshouldbe1.-ŠMOVE.LA5,D2ŽTheIDwillbeourCCBaddress.'ŠTR0$.RQPA,Askexectosetthetimer.+ŠBRA„TM_OK_TIMERˆIfalliswell,justexit.9ŠTR0$.KILLER,Ifsomethingwentwrong,crashthesystem. TM_OK_TIMER-ŠMOVEM.L(SP)+,D1-D7/A1-A6Restoreregisters.5ŠMOVEQ‚#0,D0ŽSetCCR:toindicatethattaskmust*§waitforcallatTM_BRK_OVER. ŠRTS—Returntothecallingtask. ‰END é éé=/* =/*†TNTDRV.AF=/*B=/* Chain file to assemble the Transparent Network Terminal driver=/*:=/* If no output argument is specified for the listing the(=/* chain file will default to TNTDRV.LS=/*=/IFC \1ƒ=ARGTNTDRV.LS=/ENDIF=/*"=ASM TNTDRV.SA,TNTDRV.RO,\1;RZ=110=/*{ Included files are:=/*ƒ9995.&.TR1.EQ=/*ƒ9995.&.TR1RTCD.EQ=/*ƒ9995.&.EXE.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*ƒ9995.NTS.TR1X.EQ=/*ƒ9995.NTS.NTS.EQ =/*ƒTNTMF.AI=/*}=/*=ENDééééééZBTNTDRV„IDNT…1,1…TRANSPARENTNETWORKTERMINALDRIVER‚07/25/84%%1,1ŠTTL„VERSADOS‹I/OMODULE=** INCLUDED FILES FOLLOW:TR1,EXE,IOE,NIO,EQUTR1X,EQUNTS,TNTMF‰OPT‡CRE,MEX,NOCL*‰INCLUDE9995.&.TR1.EQ*‰INCLUDE9995.&.TR1RTCD.EQ*‰INCLUDE9995.&.EXE.EQ*‰INCLUDE9995.&.IOE.EQ*‰INCLUDE9995.&.NIO.EQ ŠNOLISTŠINCLUDE9995.&.TR1.EQŠINCLUDE9995.&.TR1RTCD.EQŠINCLUDE9995.&.EXE.EQŠINCLUDE9995.&.IOE.EQŠINCLUDE9995.&.NIO.EQŠLISTŠINCLUDE9995.NTS.TR1X.EQŠINCLUDE9995.NTS.NTS.EQ9NTSRNOBƒEQU†$FF‡returncodefromNTSfor'outofbuffers'ŠINCLUDE‚TNTMF.AI-‰TTL‡ExtendedDCB'sforeachnetworkterminal ‰OFFSET„0&NDXSTAƒDS.W†1‰ConnectionstatusofLCC7NDXSBSY‚EQU‡0‰=1ifNDXblockisassignedtoaterminal4NDXSHIOPEQU‡1‰=1ifneedtosendHIOrequesttoHDS%****ŸNDXSPBisactivewhenHIOissuedNDXIOIP‚EQU‡2‰I/Oinprogress:NDXDCBƒDS.L†1‰DCBaddresswhichpointstonetworkterminalNDXTSKƒDS.L†1‰tosavetaskname$NDXSESƒDS.L†1‰tosavesessionnumber;NDXSPBƒDS.B†NTSPBSZƒroomforNTSSEND/WRITEparameterblockNDXBUFƒDS.B†300‡buffer"NDXBUFL‚EQU‡*-NDXBUF‚bufferlength(NDXLENƒEQU‡*-NDXSTA‚lengthofthisblock***** ŠPAGE‰TTL‡NETWORK-CRTI/ODRIVERN******************************************************** ************************‘VERSADOSOPERATINGSYSTEM* *—I/OMODULE**TASKLEVELDRIVERMODULE*%*‹COPYRIGHT1984,1980MOTOROLA,INC.*N*******************************************************************************:*REV.‚1,1‚07/25/84ƒPSGŒ(changesmarkedby"%%1,1"string)G*ƒ1.FixedforDLCmulti-dropproblemofcreationof"orphansessions".*N*-----------------------------------------------------------------------------**PROGRAMNAME:‚.TNTDRV*$*REV.‚1.00‚9/10/82ˆ(OriginalEntry)*-*FUNCTION:‚VERSAdostaskleveldrivermodule*&*CALLINGSEQUENCE:‚eventnotification***SUPPORTTABLES:‚logicalunittable(LUT)*’devicecontrolblocks(DCB)*’deviceconnectionqueue(DCQ)** cElOt=|?„<Œ?”7œG¤H¬;“H¼=ÄCĢaŌ(6*ENTRY:‚ThismoduleassumesithasbeenSYSGENEDinto*‰VERSAdosina'READY'state.2*„****DuringSYSGEN,DCBSTAmustbesetto0‚****A*„DuringSYSGEN,aDCBissetupforeachHDS-CRTtosaveinfoon *„LCC,status,DCBpointer,etc.F********************************************************************** ‰XREF„NTSSERV**ˆGENERALEQUATES*#*TNTIDƒEQU‡'.TNT'ŒDEFINEDINNIO.SA‰SPC3 NTSCALL‚MACRO‰JSR.LƒNTSSERVcallNTS‰CONT…EQ‰ENDM‰SPC1NTSCHECK MACRO‰CMP.Bƒ#-1,NTSSTA(A0)†idle?‰BEQ…\1’branchyes%‰BTST.B‚#NTSSTC,NTSSTA(A0)‚completed?‰BEQ…\1’branchno'‰CMP.Bƒ#NTSROK,NTSRCOD(A0)completeok?‰CONT…EQ3‰MOVE.B‚#-1,NTSSTA(A0)†markparameterblockasidle‰ENDM CONT…MACRO ‰B\1.SƒOK\@continueifnoerror ‰LEA…*,A2 ‰BRA…KILIT OK\@…EQU…*‰ENDM‰PAGE ‰SECTION‚0I***************************************************************************ˆTIOINITIALIZATIONROUTINE*0*ŒTHISROUTINEPERFORMSTHEFOLLOWINGFUNCTIONS:**-setuserstackpointer1*-allocatedataareaforDCBextensions(NDX's)9*-establishnetworkconnectionwithTNTRtaskinHDS400*+*ˆENTRY:A0=addressofcommonI/Osegment****J***************************************************************************&TNTENTƒBRA.SƒINTL“Initialjumpvector."TNTASRƒBRA…ASRBEG‘ASRjumpvector.  2INTL:„LEA…IOSTAK(PC),A7ŠSetupuserstackpointer. 3‰MOVE.L‚A0,IOCOMSŽsaveaddressofIOcommonsegment )‰XREF„NNTDCBS#ofnetworkterminalDCB's6‰MOVE.L‚#NNTDCBS,D0ŒgetspaceforDCBextension(NDX's)‰MULU„#NDXLEN,D0+‰ADD.Lƒ#2,D0’addspacefortableterminator‰MOVE.L‚D0,GTSPB+SEGLEN‰ERQ.GTSEGGTSPBgetspace‰CONT„EQ 2‰MOVE.L‚A0,SEGADRŽSaveaddressofourdatasegment  *'*ˆWalkDCBlistandfindtheoneswe're*ˆinterestedin.*)‰MOVE.L‚IOCOMS,A1PickuppointertoSVT.1‰MOVE.L‚SVTDST(A1),A1‰SetuppointertoDCBlist.‰MOVE.L‚SEGADR,A49INTL30ƒCMP.Lƒ#TNTID,DCBDID(A1)…DCBpointtothisdriver?‰BNE.SƒINTL40Branchifno.4‰LEA…NDXBUF(A4),A0‰putsendbufferaddrinsendp.b.‰MOVE.L‚A0,NDXSPB+NTSSAD(A4)D‰MOVE.B‚#NTSCSEND,NDXSPB+NTSCMD(A4)putNTSsendcommandinNTSp.b.+‰CLR.WƒNDXSPB+NTSOPT(A4)…returnimmediately‰CLR.WƒNDXSTA(A4)ŒmarkNDXidle<‰MOVE.B‚#-1,NDXSPB+NTSSTA(A4)indicateNTSsend'notactive';‰MOVE.L‚A1,NDXDCB(A4)‰saveDCBaddressfornetworkterminal(‰LEA…NDXLEN(A4),A4‰A4pointstonextDCB(INTL40ƒMOVE.L‚DCBPTR(A1),A1‰getnextDCB‰MOVE.L‚A1,D0‘finished? ‰BNE.SƒINTL30****‚MarktheendofNDXtable‰MOVE.W‚#-1,(A4)*‰CLR.BƒDISCFLAGŽINITIALIZEDISCONNECTFLAG***<*ˆ***********************************************************ˆ*ø*5*ˆ*IdentifymyselfasTNTD„toNTS(networkservice)…**ˆ*ø*<*ˆ****************************************************************‚getstationIDfromNTS GTID…EQU…*‰LEA…NDXLPB,A0:‰MOVE.B‚#NTSCSID,NTSCMD(A0)‡returnstationIDcommandcode+‰CLR.WƒNTSOPT(A0)optionfieldmustbezero‰JSR.LƒNTSSERV$‰CMP.Bƒ#NTSRICMD,D0Žinvalidcommand? ‰BNE.SƒTEST1  >***‚waitforNTStogetready,sowedelay5seconds…*********I* NTS is invoked by a command after system initialization. Someone has toF* type this command. TNTD is part of system initialization. Therefore,/* TNTD run long before that command gets typed. ,‰MOVE.L‚#5000,A0’setdelay5000milliseconds ‰ERQ.DELAY‰BRA.SƒGTID–gotryagain!!TEST1„TST.BƒD0‰CONT„EQ 4‰MOVE.L‚#'TNTD',NTSNAME(A0)move4charintoNTSNAME?‰MOVE.W‚D1,NTSNAME+4(A0)„putASCIIIDin5th&6thcharsofNAU .‰MOVE.B‚#NTSCIDNT,NTSCMD(A0)‡IDENcommandcode<‰MOVE.W‚#1<*ˆaMESSAGEcommand.‚TheMESSAGEcommandattemptstobroadcast(*ˆtoallterminalDCB's,includingours. BASR40„MOVE.B„#ISTANR,DCBIOS+IOSSTA(A6)‚Setdevice-not-readystatus ‰BSR‡IOEXIT‰BRA‡RTNVTforgetit ‰PAGE I***************************************************************************ˆINITIATEI/OROUTINE*!*ˆENTRY:A3=ASQmessagepointer*A7=stackpointer**F*ƒ*****ThisroutinereceivedIOCBfromIOS,sendsCOMMANDof"initiate*ˆI/O"toNTS.L*****************************************************************************STRIO:;‰MOVE.L‚DCBLUT(A6),A0‰pickaddroflogicalunittableentry‰CLR.BƒDCBBCT(A6)8‰MOVE.L‚LUTTID(A0),NDXTSK(A4)saverequester'staskname0‰MOVE.L‚LUTSES(A0),NDXSES(A4)‚andsessionnumber‰LEA…NDXSPB(A4),A13‰CMP.Bƒ#-1,NTSSTA(A1)ˆisthereanoutstandingsend?‰CONT„EQ 5‰MOVE.B‚#TNMIOR,NDXBUF+TNMSGT(A4)‚messagetype-IOreq**copyIOSblockinto‚NDXBUF0‰LEA…NDXBUF+TNIOS(A4),A0„addrofIOSslotinmsg%‰LEA…DCBIOS(A6),A1ŠaddrofIOSinDCB‰MOVE.L‚#IOSBLN,D0IOSlength'STR20„MOVE.B„(A1)+,(A0)+ŠmoveIOSblock‰DBRA†D0,STR20/‰MOVE.L„#TNWDATA,D4Šbasicmsglengthifnodata‰CMP.W…#IOWRIT,IOSFCT(A5)‰BEQ.S…STR30branchifoutput‰CMP.W…#IOOWIN,IOSFCT(A5)*‰BNE.S…STR40branchifnotoutputw/input *¦somekindofoutput-getdataD** calculate length of data to be copied into NDXBUF after IOS blockSTR30„MOVE.L‚IOSEAD(A5),D1‰SUB.LƒIOSSAD(A5),D1!‰ADD.Lƒ#1,D1’lengthofdatainD1:‰CMP.Lƒ#NDXBUFL-TNWDATA,D1„checklengthofdatatobesent+‰BLE.SƒSTR35’itissmallerthanbuffersize<‰MOVE.B‚#ISTABO,IOSSTA(A5)…putbufferoverflowinIOSstatus$‰BSR…IOEXIT‘notifyIOSthesituation‰BRA…RTNVT’return+STR35„LEA…MUTNT,A0pickaddrofMOVELLp.b.‰MOVE.L‚D1,MVLENG(A0)-‰ADD‡D1,D4bumpNTSmsglengthbydatalength=‰MOVE.L„NDXTSK(A4),MVSTSK(A0)setsourcetasknameforMOVELL%‰MOVE.L„NDXSES(A4),MVSSES(A0)session4‰MOVE.L„IOSSAD(A5),MVSADD(A0)sourcelogicaladdress8*******‚temporaryfixforoddsourceaddress„*********** ‰AND.B…#$FE,MVSADD+3(A0) '‰LEA‡NDXBUF+TNWDATA(A4),A1destaddress‰MOVE.L„A1,MVDADD(A0)$****** move write data to our buffer ‰ERQ.MOVELL ‰BEQ.S…STR40*‰CMP.W…#RTCDTASK,D0‰sourcetasknotexist? ‰BEQ.S…RTNVT ‰LEA‡*,A2 ‰BRA‡KILIT8STR40„BSET.B„#NDXIOIP,NDXSTA(A4)‚setI/Oinprogressbit,‰LEA‡NDXSPB(A4),A0ˆpicksendparameterblock-‰MOVE.L„D4,NTSLEN(A0)ˆsetcomputedmsglength&‰JSR.L…NTSSERVŽsendI/OrequesttoHDS‰BRA.S…RTNVT’return  ‰PAGEH**************************************************************************"*ˆUNSOLICITEDSTATUS(BREAKevent)***F********************** *************************************************SIGBRK:‰MOVEM.LD0-D7/A0-A6,-(A7)$‰BSR…DCBWAITGetaccesstoDCBlist.+‰ADD.Bƒ#1,DCBBCT(A6)‡IncrementBREAKcount.‰BSR…DCBSIGŽReleaseDCBlist.‰BSR…BRAKERŽCallBREAKhandler.‰MOVEM.L(A7)+,D0-D7/A0-A6 ‰RTS™Return‰PAGEM*******************************************************************************ˆHALTI/OROUTINE**!*ˆENTRY:A4=ASQmessagepointer*A7=stackpointer*L*****************************************************************************HALTIO:,‰LEA‡NDXSPB(A4),A0‡picksendparameterblock#‰CMP.B…#-1,NTSSTA(A0)†Isthisidle?.‰BEQ.S…H10‘branchifnosendgoing-oktouse9‰BSET†#NDXSHIOP,NDXSTA(A4)‚blockinuse-setHIOpending+‰BRA.S…RTNVTthat'salltillsendconpletes *¦oktousesendblock-H10†BSR.S…SENDHIOsendHIOrequesttoHDSnow‰BRA.S…RTNVTalldonehere   *¦sendanHIOrequesttoHDS2SENDHIO‚MOVE.L„NTSSAD(A0),A1‡picksendbufferaddr+‰MOVE.B„#TNMHIO,TNMSGT(A1)‚setmessagetype$‰MOVE.L„#1,NTSLEN(A0)‡setmsglength‰JSR.L…NTSSERVsendthemessage ‰RTS›doneŠPAGEH***************************************************************************ˆRETURNFROMEVENT**K****************************************************************************RTNVT:-‰MOVEM.Lƒ(A7)+,D0-D7/A0-A6ƒRestoreregisters. ‰RTR›Return. O********************************************************************************8*ˆTERMINATEEVERYTHINGINSESSIONSOWECANDOARESTART*O******************************************************************************* RESTART‚EQU‡*0‰CLR.B…DISCFLAGŒCLEARDISCONNECTFLAGFORRE-USE1‰CLR.B…DISCCLEARLOOPDISCONNECTFLAGFORRE-USE2‰LEA‡SESSTBL,A3ŠADDRESSWHEREWESAVEDSESSION#'S3REST010‚MOVE.L„(A3)+,TRMPSES‡MOVESESS#TOTERMPB*‰BEQ.S…REST020DONEWITHLOOPIFIT'SZERO4‰BMI.S…REST010CONTINUELOOPIFTHISISUNUSEDENTRY/‰ERQ.TERMTTRMPBLKTERMINATETHISSESSIONS&SCT*‰MOVE.L„#-1,-(A3)‹RESETTHISSESSIONENTRY%‰BRA.S…REST010LOOKFORANOTHERENTRYREST020‚EQU‡*“FINISHED‰RTS›KEEPLOOKING*O********************************************************************************,*ˆSAVESESSIONNUMBERSOFDISCONNECTEDLINKS* *’BSRƒSAVSESS*œA4--->NDXENTRY%*œSESSTBLUNUSEDENTRIESARENEGATIVEO*******************************************************************************SAVSESS‚MOVE.L„A3,-(A7)ŒSAVEA3-‰LEA‡SESSTBL,A3ŠGETADDRESSOFSTORAGEBUFFER1SAVS010‚MOVE.L„(A3),D0VALIDSESSIONNUMBERHERE?)‰BEQ.S…SAVS030NOROOMIFTHISISAZERO!%‰BMI.S…SAVS020BRANCHIFUNUSEDENTRY8‰CMP.L…NDXSES(A4),D0‡HAVEWEALREADYLOGGEDTHISSESSION‰BEQ.S…SAVS030IFYES-EXIT*‰TST.L…(A3)+IFNO-INCREMENTTONEXTENTRY‰BRA.S…SAVS010ŽTHENCHECKIT&SAVS020‚MOVE.L„NDXSES(A4),(A3)…SAVEIT"SAVS030‚MOVE.L„(A7)+,A3ŒRESTOREA3‰RTS‰PAGEJ****************************************************************************ˆTHISISTHEI/ODONEROUTINE**†ENTRY:‚A6=DCBpointer*ŽA7=stackpointer***L*****************************************************************************IOEXIT:.‰MOVE.W‚#-1,DCBTMO(A6)†SetterminationinDCB.7‰MOVE.L‚A6,DCBADDRŠSetupDCBaddressforIODONEevent. ‰ERQ.QEVNTQEVDRVŒNotifyIODONE.‰CONT„EQ‰RTS‰PAGEK*****************************************************************************‚BRAKER*$*ˆNotifyBREAKclaimer,ifheexists**L*****************************************************************************BRAKER:.‰LEA…QEVATN(PC),A1‡Setupparamblockpointer.‰CLR.LƒD0’Clearstatus.#‰TST.LƒDCBWNT(A6)ŠDeviceassigned?‰BEQ.SƒBRAK2Branchifno.*‰BSETƒ#EVATNAS,D0ŠYes,setstatuscodeup.BRAK2„MOVE.W‚D0,ATTN+EVASTA-‰MOVE.L‚DCBAID(A6),ATTN+EVADEV‚Setupdevice.(‰CLR.WƒQEVOPT(A1)ŠClearserviceaddress.-‰TST.LƒDCBBRK(A6)Šlocalbreakclaimerexists?‰BNE.SƒBRAK20ŽBranchifyes(‰MOVE.L‚IOCOMS,A0‹SetuppointertoSVT.2‰TST.LƒSVTBRK(A0)ŠAnyonewantBREAKnotification?‰BEQ.SƒBRAK30ŽBranchi fno.-‰MOVE.L‚SVTBRK(A0),QEVTSK(A1)‚Setuptaskid./‰MOVE.L‚SVTBRK+4(A0),QEVSES(A1)‚Setupsession.5‰MOVE.L‚SVTBSA(A0),QEVIAD(A1)‚Setupserviceaddress.+‰BMI.SƒBRAK10ŽNoserviceaddressrequested.9‰MOVE.W‚#QVOPAS,QEVOPT(A1)‚Setupserviceaddressoption..BRAK10ƒERQ.QEVNT‚QEVATN‹NotifyBREAKSclaimer. ‰RTS™Return /BRAK20ƒMOVE.L‚DCBBRK(A6),A2‡SetupLUTpointer.-‰MOVE.L‚LUTTID(A2),QEVTSK(A1)Setuptaskid.-‰MOVE.L‚LUTSES(A2),QEVSES(A1)Setupsession.5‰MOVE.L‚DCBSRV(A6),QEVIAD(A1)Setupserviceaddress.!‰BMI.SƒBRAK25ŽNoserviceaddress.6‰MOVE.W‚#QVOPAS,QEVOPT(A1)‚Setserviceaddressoption.***ƒQueueevent!BRAK25ƒERQ.QEVNT‚QEVATNBRAK30ƒRTS™Return.‰PAGEI****************************************************************************SEMAPHOREROUTINES**I**************************************************************************,DCBWAIT‚MOVE.L#SVTSDCB,D0ŠGetDCBsemaphor.‰MOVE.LIOCOMS,A0 ‰ADD.LD0,A0DCBW00ƒTAS(A0)‰BEQ.SƒDCBW10ŽOK,wegotit.‰MOVE.LA0,-(A7)***‚Can'tgetitnow! ‰ERQ.RELINQ‰MOVE.L(A7)+,A0‰BRA.SƒDCBW00ŽTryagain.DCBW10ƒRTS™Return.**.DCBSIGƒMOVE.LIOCOMS,A0ŒReleaseDCBsemaphore.‰CLR.BSVTSDCB(A0) ‰RTS™Return.‰PAGEL******************************************************************************PARAMETERBLOCKS***L**************************************************************************** *#*ˆqueueeventtoIODONE(task.IOS)*QEVDRVƒDC.L…IOSIDŽTaskid‰DC.L…IOSESSSession‰DC.W„0“Options‰DC.L„EVTDRVŽPointertoevent‰DC.L„0“Vectoraddress**ˆqueueattentionevent*QEVATNƒDC.L„0“Taskid‰DC.L„0“Session‰DC.W„0“Options‰DC.L„ATTNPointer‰DC.L„0“Vectoraddress**ˆMOVE‚fromusertoTNT* MUTNT„DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0****MOVE‚fromTNTtouser MTNTU„DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0‰DC.L…0**.MYBUF„DS.B…256ˆBUFTORECEIVEORSTOREMESSAGE)BUFLENƒEQU†*-MYBUF„BUFFERLENGTHINBYTESLSTNBUF‚DS.B…16‰listenbuffer)LSTNBLƒEQU†*-LSTNBUF‚listenbufferlength*)CONNDXƒDS.L…1ŠaddrofNDXbeingconnected*‰PAGE*œTERMTTRMPBLK‚DC.L…'&SCT'†TASKNAME.TRMPSES‚DC.L…0ŠSESSIONNUMBER.SETATRUNTIME‰DC.W…$8888†ABORTCODE?*ˆROOMTOSAVE8SESSIONSPLUS1TERMINATOR.‚ONEFOREACHDROP.&SESSTBL‚DC.L†-1,-1,-1,-1,-1,-1,-1,-1,0*œGTSEG GTSPB„DC.L…0,0ˆtaskname,session$‰DC.W…SGOPPA…OPT-returnlogicaladdr‰DC.W…SGATRW…ATTR-R/W ‰DC.L…0Šname ‰DC.L…0ŠLAD‰DC.L…0Šlength‰PAGEJ*************************************************************************** *ˆWORKAREAS***L*****************************************************************************‰DS.W„07NDXLPBƒDS.B„NTSPBSZ…roomforNTSLISTENparameterblock!NDXCPBƒDC.B„NTSCCONN„commandcode ‰DC.B„0‹LCC‰DC.W„0‹OPT:immediatereturn*‰DC.B„-1,0ˆSTA,RCOD.-1isnon-activeflag‰DC.L„0,0,0‡RESV,TASK,SESS‰DC.L„0,0,0‡SADD,LEN,RCSZ‰SPC‚2!NDXRPBƒDC.B„NTSCRECV„commandcode ‰DC.B„0‹LCC"‰DC.W„NTSMANY…OPT:immediatereturn0‰DC.B„-1,0ˆSTA,RCOD.-1meansreceivenotactive‰DC.L„0,0,0‡RESV,TASK,SESS"‰DC.L„MYBUF,BUFLEN,0‚SADD,LEN,RCSZ‰SPC‚2$NDXCCPB‚DC.B„NTSCCONC„cancelconnect ‰DC.B„0‹LCC ‰DC.W„0‹OPT‰DC.B„-1,0ˆSTA,RCOD‰DC.L„0,0,0‡RESV,TASK,SESS‰DC.L„0,0,0‡SADD,LEN,RCSZ‰SPC‚2*ARQUE„DS.B„$20‰Eventqueue*!EVTDRVƒDC.B…EVTLNG-8‹Eventlength‰DC.B…EVCQUEEventcode!EVTQSUB‚DC.B…TRMEVTEventsubcode‰DC.B„0“ReservedDCBADDR‚DC.L„0“DCBaddress**ATTN…DC.B…EVALEN ‰DC.B…EVCATN‰DC.L„0‰DC.W„0CHARS„DC.L„0“Buffer*‰DS.B„$80‘Stackarea IOSTAKƒEQU…** IOCOMSƒDS.L„1“I/Ocommonaddress*"SEGADRƒDC.L„0“DATASEGMENTADDRESS*,ACTIVCƒDC.B„1“COUNTOFACTIVENDXPARABLOCK*&DISC…DC.B„0“USEDWITHINMAINLOOPONLYDISCFLAGDC.B„0“DISCONNECTFLAG ‰END…TNTENT éééé-‰TTL‡ExtendedDCB'sforeachnetworkterminal‰PAGE ‰OFFSET0 TNMSGTƒDS.B†1TNMIORƒEQU‰1ˆI/OrequestTNMIOCƒEQU‰2‡I/OcompleteTNMUB„EQU‰3‡unsolicitedbreakTNMHIOƒEQU‰4‡haltIOrequest/‰DS.Bˆ1‡unused-neededtoword-alignIOSblock-TNIOS„DS.B†IOSBLN„messagetype1--I/OrequestTNWDATA‚DS.B†0‰writedatastart )‰OFFSET„TNIOS…messagetype-2I/OcompleteTNSTATƒDS.B†1‰status#‰DS.B†1‰alignmentforevenboundary(TNDLENƒDS.L†1‰lengthofdata(forreads)TNRDATA‚DS.B†0‰data(forreads)                  éééééÜ#=/*=/*†VM22DRV.AF=/**=/* Chain file to assemble the VM22 driver=/*:=/* If no output argument is specified for the listing the)=/* chain file will default to VM22DRV.LS=/*=/IFC \1ƒ=ARGVM22DRV.LS=/ENDIF=/*$=ASM VM22DRV.SA,VM22DRV.RO,\1;RZ=130=/*{ Included files are:=/*ƒ9995.&.STR.EQ=/*ƒ9995.&.TCB.EQ=/*ƒ9995.&.CCB.EQ=/*ƒ9995.&.LV5.EQ=/*ƒ9995.&.IOE.EQ=/*ƒ9995.&.NIO.EQ=/*}=/*=ENDé éééééå‰TTL‡VM22DRIVEREQUATES ŠOPTCRE,PCS **‰MISCEQUATES*.DRIVESƒEQU‡12’Numberofdrives(LUN)perboardEXEC…EQU‡0“RMS68Ktrap# **ˆMACROSUSEDBYTHISDRIVER* *ˆLONGWORDMACROK* This macro skips zero or more bytes in memory (if necessary) to align theM*assembler'slocationcountertoalong-wordboundary.‚Wedefinealong-wordC* boundary to be a location whose address is evenly divisible by 4.F* If the location counter isn't on a long-word boundary, advance it by-* one word to put it on a long-word boundary. LONGWORD MACRO‰DS.W…0 ‰IFNE…*/4*4-*‰DS.W…1‰ENDC‰ENDM *ˆMOVEIAMACROJ*‚Thismacroisusefulwhenwewanttoputanimmediatevalueintoan1*register,i.e.‚[