IMD 1.16: 1/09/2008 12:19:36 84-93438-01 a030 f43801 synchronous communications handler product diskette 8feb83    @0{)vvЀЀsQpk)p " }fA __M@IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIOS4 MA283011015534040830110155340 830110155340IF43801 VOLSYNCHRONOUS COMMUNICATIONS HANDLER PRODUCT DISKETTE (A030)   IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII_M@qGyy GGG`HX@ b G`^Y e GQ @@p@987 85P@ G:پN 8)0. * C'xC# b# }B* @0DAJL w+™ЀЀΖQA1"   i  ž} š} @EEFF)DEۄF8 џ} ԟ} ̟} * `jUBBI,v BI, # @ G7H@pܾrCHC C GTq` Lg gEXC P+s=胾P+c fQN p $Rxnj  ޔniZ ތ⊞ } }HGž Ÿ@ALS)"$ C k20j.h( +$`%ꂜ\1 !M' y %'+os慾)sY ed|{ @8 o O m J K i gN )V% t%sLn`"E F. F„ D>) =`;nrgy w"G,{Kq1 A&}E*`(t@% ;c  765y342(.OS:: SYSG @ @G6BDāCGDĀ# BC @E OBJSC:FUN SC:WRT SC:RD O0SEGMENTBLANK IOS: o KPUT:CREQPUT:DREQR:WAIT KR:SPRI R:GPR I:RET KI:ECTT I:EMEM im MACRO (F370) @i ؄MC STU@`KV W@`KXYEDBƠB 6 # EZD[C \ # # T VYY  #  Mg >Y` B+]\Ipg 2M` B+Q\Idtttttttg V@KUQFXKQ ZB [` C5ĠB@āE F   9 7 ZB[` C B@ā([. 1*CKR 5 CKR )5 tJPUT:CREQGET:DREQPUT:DREQO0SEGMENTBLANK SYNC: o EKR:BGIN B:LINEC R:SPRI KR:GPR R:SIG im MACRO (F370) @ig C @`I@qB@1Ac # g C @` O@1D@A`pBc # g C @` p``pDB I@@`qB@Ę1A`pD@6D@|ě:t c # tttJC:LINEC B:LINEC O0SEGMENTBLANK SYNC: OTABLE: o  KR:END R:RBUF R:BGIN KR:ABUF B:RECVC B:XMITC KB:DEVCC CND:EVNTCHK:WAITKMODE:SETREQ:EXU CHK:QUE KTMR:ENDUTMR:BGNUTERM:ACTKRELS:LCBRELS:EPTALOC:EPTKRET:REQQRET:REQ PUT:REQ KGET:REQ RLS:EVNTR:SPRI KR:WAIT NR:TDBL im MACRO (F370) @i  FF #igk0di gd  ~@ ABICEFGH  # @NȻ ĹK ĸ Gn @ 1R @ J U@  p܀# @ # DL @`K̞L `+ ܀D ٠E@Ĭ # @`KL ` +# I# C @ I @ 1 N 6 p9 p܆c #  ^yu1#-IPW t tt t DCքC# D@:t# D@:t# D@:t # D# D `+#  y D@Y @6X LJQL@6N)XLL   `+#  D@# D@# D@# ttt @̄C̄CD 5# @ ̈́CCD 2# C C6ARC܄C6F 6CCD   # 1ML L  Ȟ# 9# #  # # #  # # # @  @@+I + @ # C݄CCC 6CCD # t ttt Ġ@1yA @  iA1GA v@+BzD ÀE PD Ƞ@ŀEÀG A+[@ @  A@}: tt+t }ttQtt tJCND:EVNTCHK:WAITMODE:SETJREQ:EXU CHK:QUE O0SEGMENTBLANK SYNC: o  KR:BGIN B:PROTO RELS:LCBKALOC:LCBRET:REQ DEL:REQ KPRO:EVNTim MACRO (F370) @i 1j@  @6@6@6@O6G X Q@XQUœXQ™@XQ•Đ@:t p܀# I# I# t ` @tg C @@6AN)XLLL   p܆c # g C @ X?QI  @̻S @ ܼN)XLLXL L@L L L JQ 6 / p܆c # I  I II păc # t 1J 1C{z# g C @ H j1PIf 1L@ p HI I păc # p܆c # g C @@6@6@N!G ֗!֔֒@Đ@ 6@6N!ؐX8Q p܆c # ttg C @@ `+'1a@ pĄH ,I,I,I+1 pL @`K_I^ p؃Q@` KUIT pIĄc # JC:PROTO B:PROTO O0SEGMENTBLANK SYNC: OTABLE: o  KR:END STRT:RSPCHK:TERMKSET:CURSSET:REQSABRT:ALLKREQ:XMITREQ:RECVXMIT:RELKRECV:RELREL:XMITREL:RECVKPRO:RPRTPRC:WRITXMIT:CPLKPROC:RFEGEN:XMITTERM:TMRKCNCL:TMRSTRT:TMRINIT:TMRKRELS:EPTALOC:EPTRLS:EVNTKR:WAIT NR:TDBL im MACRO (F370) @iigk!@d$igd D@AI@C 1DXQADXQADX QEĄF GHBIJ KLNOPQMRSTUV WXYZ[\]^# 1dB DI@EBK1V] D I@EBK1G^ BA p܀# ]1AB# @tttt E6ĀD6ـFE@6 ̄FTT@G6eHH E@R # E6e[ Z1RP)Z@ [ \ @ZQY# Ā# # 6A GF@R ( #  F6AFG6FF 6CHHE6ĀD6# t tt_ttt I@  BǠ1# t   # E|EǀE6ĀD 6# ElE# #  # Hl6H# Hm6A H# 3# 0# -#  (*# tttt t ͞ ˀD6BqB 1AAABC  ]1EC ^1EC  E AFo6HE ŀE) B+OI ^1B]1BA B ::t tt gt t tttttJPROC:RFEO0SEGMENTBLANK SYNC: o KR:SIG FRC:CURSSET:CURSKCHK:MODEEND:POLLEND:FINLKRECV:RELRS T:RECVRET:REQ KRESC:ALLRESC:ONEPROC:ACKKPUT:REQ ACPT:SEQACPT:SELim MACRO (F370) @i E@6ENIKXNKX PKCAH# N E 6CJXJX MJEC FIH# @ @JM#  EXL`_`FF 6ÀGG# C @I CCd@6ŀC\ *RDQDV7SϠ1M JXĆC p c # t tt   C @@ @@(   N 6C+MQ RGQGb^]H XLHL L c # C  @AQàQK p F Ic # Fo6DlGF# t t t EN)XWQ@D@QG@ 6G@GNA@@6G@6V@ GG֗GI6@A@ EGE IG# IB# t oC @@6  `8 .' p N 6C1 XLL BH I+LCL LLL/LςLOLo JI ;Ic # 0t E  %# 6G@ 6턁@ְGDŀG~ G6ȀD/66ÀGnG#  G6T6U6Հ6ҀGE ֒6@o6@E # <# # ott C @@6 `8  .' p N 6C XLL BE  ΞLcLLWCQ΀G ĄG*FFGGc # g 6 6B 6B @6B. L@ A +A܅1A @@ 6΀ @6EFF# F݄F# tCvt tttJGEN:XMITO0SEGMENTBLANK SYNC: o tKSTRT:RSPSET:CURSCHK:TERMKWRT:ACK SND:EVNTGEN:EVNTim MACRO (F370) @i `( H%'@( h܄# # C  @I p%C @'DD% ' pKqc #  C @ A pą IĆĀE   F@DLF섁L Մc # C @ AˀE  J`pC6ą A@ą`pDc # C @ AE J`pD B@6RLFXNą FX1@Ną  B`pDDK)BEc # t  66PRD@6܄ PS@ Aπ6Aq @ @A܈66 FF# FF# tt (F6@66G@6 Bo# @6xH@6C@6 E@6F[QH@6jIPK XQF@6PH@6C@ 6E@6E[QH@6Q@ 6CH@HE@6D@Lą @Ć# F66h I E @`KP E@ 6J1`@6JXG J`@`yFF# #  F@o6@mFX?NY rF? @ AY HKff # @6@}F/# EI  CIC6F QR # KLGG# ttt E)EF@6K@6C@ 6FG܄G IE)  GnYE@G@ ‘ GGGi ICG G # O/o! Ho6U6WIQXJQBI  IMJXQKC@6I ܄H HIIH̄H݀E  # E6ˀH6FF 6EC@6K# H6[1v 6dLXNLC  NN PLCNP KLCƀ[\ZH @H[\C a E # HŀF66 p܀# /?N`tjg E@o6@6^AIZF G66LʀE6ŀF 6DjhE b# xRJSTRT:RSPFRC:CURSSET:CURSJSET:REQSCHK:MODEPRO:RPRTJXMIT:RELRECV:RELCHK:TERMJREQ:XMITREQ:RECVRST:XMITJRST:RECVREL:XMITREL:RECVJEND:FINLEND:POLLRESC:ALLJRESC:ONEPRC:WRITXMIT:CPLJACPT:SEQACPT:SELPROC:ACKJWRT:ACK PUT:RORDABRT:ALLO0SEGMENTBLANK SYNC: o )KR:SIG CNCL:TMRSTRT:TMRKRET:REQQRET:REQ PUT:REQ KGET:REQ INI:EVNTim MACRO (F370) @ig `+ `+ `+ `+A+# g C @C  @ȄC @C A p # `pBX @BC G@1CEDD@1B@ CŅDEkp``# g ą@ @ @L I LLU1A#  # UVpLI2# ttg C @ TY1NKCI YZL`pCEp RK CE@K R SKC E@K SNKCD@KNKXKc # g C @J@ @ @I7 QJWH `+ I,HHJQAQ QHWQDQJXC c  # pQ X1B WH@H @ p܆c # g C @JԀ@ @  @IJQ JHH p܆c # g A+ ] 6VLK LX@RnNLX@LRC IeIbI_# tt=g Y1LKɀYZ[@[\K RS# g KN7KNY3[Z\ YZjg F@6@FGGF RK Aa]1DFF# g E6OGG SKAN]1DFF# g E6K6EA@# g  E6Ko6EA@# `ttg  GGFFH6 H J QMW1TWX A܅+E66/@+j# g  FFH6|H K LNO PRSYKIYZ [1D[ HĀ[\[1J 6EO O1# :ttg  EۀEEAĄ   @ĄE6@ĄE A@# g  EʀEEA@# g @QE@I6I~OL CtA+t Iֹ ĂN)XJRI`@6MO ĆKXOIĀ\1BR[ [\E6D@66B Bo61>A # B # `t ?@t8tg BԀE) EXJQ Fo6C# # # # g C @EE6D@6ɀ^ G6DYU[CQc # g C @EE6D@6CBc # sg E.NGA@)# g E@X)@ JQ# G6jF6gJQɀD6 E6à^1AŀGG# G D@6|XQAlG TD 6ȀE6=^1B# g EX8@ # L(# E@E;gEX@ # g E֛@E ' +gF6DF]# t?tJC:RECVC B:RECVC O0SEGMENTBLANK SYNC: OTABLE: o ` KR:END R:BGIN TERM:ACTKWAIT:FLGB:RECVD RELS:EPTKALOC:EPTPRO:EVNTRLS:EVNTKINI:EVNTR:WAIT R:SIG NR:TDBL im MACRO (F370) @iigk 0digd D@DC6ĠB  CŠB+# @IC ABD1rA @:t ` A I@A ҀD6K1I AF AoA+kBBDA +z@ A I@:tt ttt tt ttJC:RECVD B:RECVD O0SEGMENTBLANK SYNC: OTABLE: o  KR:END TERM:RCVABRT:RCVKSTRT:RCVTERM:TMRCNCL:TMRKSTRT:TMRINIT:TMRRELS:EPTKALOC:EPTGET:REQ PUT:REQ KPRO:EVNTSND:EVNTRLS:EVNTKDIS:EVNTGEN:EVNTR:WAIT KR:SIG NR:TDBL im MACRO (F370) @iigk0digd D6OB1Q ʀ CǀDDB# B} # EFC+C܅E# tt t C6/ Ą+ C+CD6P@6Z ܄DCB GF FLD݄DC@Ą  @ IB+IC @6@Ą C @  C p܀D 6݄DFA# Eă+H QJ @) C@6  IE1FDKJ JK@ G# tt tt 8t @@BEI IĄ# C K@ EI@SBBIQȐC +C܅# ą֞@Ă YE Ĉ#  qNyGEqNyG# t  CED̈́D@  ` @WD6P C6ʀàED̄D @ݠB+e@QĀDD XQW@_6L)@/6G) @?6D) @o6A)ŠC6= # @ pE C؂֮QJ؂ Ny؂L؂ L^E@6@6임 @O6@IKRE p܀# # t,ttt 1I @ KߤFJ1 @۠A B@ıKĂA+ D6FB+ȞwǞE D6K@6@6ˠ@6 DDE@ā@B: dECD6 C DDC CA+D F B@ @A+:t ttttt t ?tJC:XMITC B:XMITC O0SEGMENTBLANK SYNC: OTABLE: o Q KR:END R:BGIN TERM:ACTKWAIT:FLGB:XMITD RELS:EPTKALOC:EPTPRO:EVNTINI:EVNTKRLS:EVNTR:WAIT NR:TDBL im MACRO (F370) @iigk 0digd @ ABCD1xA @:t ` A I@A րD6O1M C DD AA+g@ BBDA+z@  A @I:ttttt t ttJC:XMITD B:XMITD O0SEGMENTBLANK SYNC: OTABLE: o  KR:END TERM:XMTSTRT:XMTKRELS:EPTALOC:EPTPUT:REQ KPRO:EVNTRLS:EVNTR:WAIT KR:SIG NR:TDBL im MACRO (F370) @iigk0d\igd E GH1IJ IJE@N K 6Ā6A@\F` @ DB+x@@?6à@ܠ @@# D@D C CA+# E  JĈC+ @QDC+# tt tttt 1ĠAB @  A+jBD6ߠ1]   ԤECQBE BE6ȀD6CQ +B[B+AW@  BBA+6:tttJC:DEVCC B:DEVCC O0SEGMENTBLANK SYNC: OTABLE: o  KR:END TERM:OPRABRT:RCVKSTRT:OPRSTRT:XMTSTRT:RCVKTERM:TMRCNCL:TMRSTRT:TMRKINIT:TMRRELS:EPTALOC:EPTKINI:EVNTR:WAIT R:SIG NR:TDBL im MACRO (F370) @iigk0d@igd AEILNQ` V@ q~XR@ J# @ N G@6A\@6ĠX QlU KI` @ INOΠTEK Kn R+p p܀@# @1Q OMKRTR +TlM@ C  5LRπO͐LCb 6C+sQQ p܀# t tttt @6Y T pL TڀO֐LFb6CTd R+^o ͞ p܀O ĄM# TS# bH@I O 6AIC ܀QbֵNiGQ b@66IQ݄QAR1 QQ6̀C # C@Q@ 6BDENQ1QQ 6ǀG # G@H p܀# ?`ttt @1IOEO N K@C  PP ( TP@C T R+tTP EK  KZ p܀ MON# Q 6ƀADABQ6ƀEDEF# t ttt 1HR @ K1àR T@ I I @RO LQ @6Te@QNQQN QXQ[Q@6ŀK K@ Q K@ UI` @R++IQ QT&u I@ R+zT R @ I@:t t t t F t}tJTERM:OPRTERM:XMTTERM:RCVJABRT:RCVSTRT:OPRSTRT:XMTJSTRT:RCVO0SEGMENTBLANK SYNC: o fKCNCL:TMRSTRT:TMRim MACRO (F370) @ig IăHā@6@đIā# g IćHą@6@đIą# g ?C C @6D@đ# g 6̄y bIā# g 6I# g 6 I# g ŀ턑# ttJSC:EOBS SC:EOBT SC:EOBR O0SEGMENTBLANK SYNC: o %KR:RE12 R:SSIG im MACRO (F370) @ig  ܁g  ܅g  ܌6܉ttJTERM:ACTWAIT:FLGRET:REQQJRET:REQ FND:REQ DEL:REQ JPUT:REQ GET:REQ RELS:LCBJALOC:LCBRELS:EPTALOC:EPTJDIS:EVNTRLS:EVNTPRO:EVNTJINI:EVNTSND:EVNTGEN:EVNTO0SEGMENTBLANK SYNC: o KR:RBUF R:ABUF R:WAIT KR:SIG im MACRO (F370) @i x1L*xv1wvĂ  # ?w1„v x# # `@ @qă+ # @# OqD@ `# tgC @@J`pDc # gC @@^c # g C @@<1E@ `pDERc # g C @@01E@(`pEFc # g  C @@L1C`pE0c # g C @@*c # g  C @: 1F `pDc # g C @ c # g  C @: 1PI㥹Ćć ĈĉĊĀ( Ă`pDc # g C @ Iē  c # g C @` O@1E @A`pBc # g C @`I@qC@c # c # g C @`@Ő@ȄAIЀ ĀQAc # g C @`p*1E@ @1 B)Dc # g NQGQA܄ 1EB1A# g C @`pD1JDDA`pCEbsc # g C @`pBƠD+wFc # g C @+c # ?ttJTMR:ENDUTMR:BGNUTERM:TMRJCNCL:TMRSTRT:TMRINIT:TMRO0SEGMENTBLANK SYNC: o KR:BGIN R:RBUF R:ABUF KDEL:REQ FND:REQ CT:BEGINKCT:USAGECT:PRIORCT:TAIL KCT:HEAD R:SPRI R:GPR im MACRO (F370) @ig C @: `pD1IąIĀāĂĄIĆc # g C @ z  ` p1ĉR 1 pĂIĀ  B@AĂ@ pĀ@( ā@(C( p  Ă `c # c # t t tt tg C @y`xx p ސ IЁN ā Q‡d @ `bc # QB_w pW utTWq0. * fgC @ c # g C @?`>>ߑ:t `8c # gC @ c # tttJTDB:TMR CT:SEM CT:BEGINJCT:PRIORCT:TAIL CT:HEAD JCT:USAGEO0SEGMENTBLANK TABLE: OSYNC: o 2KR:END R:ITIC PUT:DREQKR:WAIT R:SIG NR:TDBL R:SL im MACRO (F370) @igggg~ iikg>ii gkdigd ~ߨ: d q[B BFEDE` @@ @G`IAB -猞:ddttdd tIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII TITL SYNCHRONOUS HANDLER USER DEFINITIONS (93438-90/A030) TITL EQUATES FOR VALUES OF FIELDS * * EQUATES FOR REQUEST TERMINATION CODES * TRM:NORM EQU 0 NORMAL COMPLETION OF REQUEST TRM:LINE EQU 1 LINE INOPERATIVE TERMINATION TRM:INOP EQU 2 PROTOCOL LINK INOPERATIVE TERMINATION TRM:REST EQU 3 PROTOCOL LINK RESET TERMINATION TRM:RETH EQU 4 RETRY THRESHOLD EXCEEDED TERMINATION TRM:INVF EQU 5 INVALID FRAME TERMINATION TRM:INVR EQU 6 INVALID REQUEST TERMINATION TRM:CONF EQU 7 CONFLICTING CONTROL REQUEST T ERMINATION TRM:MEMO EQU 8 MEMORY UNAVAILABLE TERMINATION TRM:MANY EQU 9 TOO MANY PROTOCOL LINKS ACTIVE TERMINATION TRM:ABRT EQU 10 REQUEST ABORTED TERMINATION TRM:TEMP EQU 11 TEMPORARILY INVALID REQUEST TERMINATION SPACE 2 * * EQUATES FOR CONTROL REQUEST CODES * CRC:DISC EQU 0 PROTOCOL TO DISCONNECTED STATE REQUEST CRC:INP EQU 1 PROTOCOL TO INITIALIZATION PRIMARY STATE REQUEST CRC:INF EQU 2 PROTOCOL TO INFORMATION TRANSFER STATE REQUEST CRC:TERM EQU 3 TERMINATE PROTOCOL OPERATION REQUEST CRC:ABRT EQU 4 ABORT PRIOR CONTROL REQUEST REQUEST SPACE 2 * * EQUATES FOR PROTOCOL STATION STATES * PST:IDLE EQU 0 PROTOCOL PROCESSING IDLE STATE ** MUST BE ZERO ** PST:INIT EQU 1 PROTOCOL PROCESSING INITIALIZATION STATE PST:DISC EQU 2 PROTOCOL IN DISCONNECTED STATE PST:INP EQU 3 PROTOCOL IN INITIALIZATION PRIMARY STATE PST:INF EQU 4 PROTOCOL IN INFORMATION TRANSFER STATE PST:TERM EQU 5 PROTOCOL PROCESSING TERMINATION STATE SPACE 2 * * ERROR CODE DEFINITIONS * IOR: RESET:,12 PROTOCOL LINK RESET IOR: RTYTH:,13 RETRY THRESHOLD EXCEEDED IOU: NOMEM:,46 MEMORY UNAVAILABLE IOU: NOLIN:,47 LINE INOPERATIVE IOU: TMANY:,48 TOO MANY PROTOCOL LINKS ACTIVE SPACE 2 * * FUNCTION MODIFIER DEFINITIONS * ET: EQU :4 STATISTICS TABLE READ EC: EQU :7 STATISTICS TABLE CLEAR TITL FLAG AND FIELD DEFINITION MACROS * * MACROS USED FOR DEFINING BIT AND FIELD LABELS WITHIN A WORD * SPACE 1 WORD:BGN MACRO BEGINNING OF WORD DEFINITION MACRO H: SET 15 L: SET 0 ENDM SPACE 1 WORD:END MACRO END OF WORD DEFINITION MACRO X: SET H:-L:+1 ENDM SPACE 1 FLAG: MACRO FLAG DEFINITION WITHIN WORD MACLAB #(-1) EQU H: H: SET H:-1  ENDM SPACE 1 FIELD: MACRO FIELD DEFINITION WITHIN WORD MACLAB #(-1)B EQU L: #(-1)M EQU 1%#(1)-1 L: SET L:+#(1) ENDM TITL CONTROLLER INFORMATION BLOCK OFFSET DEFINITIONS * * CIB OFFSET EQUATES * CI:CRH EQU 24 CONTROL REQUEST QUEUE HEAD CI:CRT EQU CI:CRH+1 CONTROL REQUEST QUEUE TAIL CI:LMS EQU CI:CRT+1 LINE MASTER ACTIVITY SEMAPHORE ADDRESS CI:DLS EQU CI:LMS+1 DEVICE AND LINE STATE FLAGS CI:FCS EQU CI:DLS+1 FRAME CHECK SEQUENCE ERROR COUNT CI:RXM EQU CI:FCS+1 RETRANSMISSION COUNT CI:OVR EQU CI:RXM+1 RECEIVE OVERRUN ERROR COUNT CI:MCS EQU CI:OVR+1 MODEM CONTROL SIGNAL ERROR COUNT CI:HDW EQU CI:MCS+1 CONTROLLER ERROR COUNT CI:AFR EQU CI:HDW+1 RECEIVE SIDE TOTAL UTILIZATION CI:AFT EQU CI:AFR+1 TRANSMIT SIDE TOTAL UTILIZATION CI:UFR EQU CI:AFT+1 RECEIVE SIDE DATA UTILIZATION CI:UFT EQU CI:UFR+1 TRANSMIT SIDE DATA UTILIZATION CI:PCC EQU CI:UFT+1 PAIRED CHANNEL CIB ADDRESS CI:LBR EQU CI:PCC+1 LINE BIT RATE CI:AAR EQU CI:LBR+1 RECEIVE SIDE TOTAL CHARACTERS CI:AAT EQU CI:AAR+1 TRANSMIT SIDE TOTAL CHARACTERS CI:URR EQU CI:AAT+1 RECEIVE SIDE DATA CHARACTERS CI:URT EQU CI:URR+1 TRANSMIT SIDE DATA CHARACTERS CI:BPL EQU CI:URT+1 BASE PRIORITY LEVEL CI:PIB EQU CI:BPL+1 ACTIVE PIB ADDRESS CI:ADR EQU CI:PIB+1 ACTIVE STATION ADDRESS CI:LCP EQU CI:ADR+1 LINE CONTROL EPT ADDRESS CI:DCP EQU CI:LCP+1 DEVICE CONTROL EPT ADDRESS CI:RCP EQU CI:DCP+1 RECEIVE CONTROL EPT ADDRESS CI:RDP EQU CI:RCP+1 RECEIVE DRIVER EPT ADDRESS CI:TCP EQU CI:RDP+1 TRANSMIT CONTROL EPT ADDRESS CI:TDP EQU CI:TCP+1 TRANSMIT DRIVER EPT ADDRESS * UNUSED WORD CI:DCT EQU CI:TDP+2 DEVICE CONTROL TABLE ADDRESS CI:ALH EQU CI:DCT+1 AVAILABLE EVENT INFORMATION BLOCK LIST HEAD  CI:ALT EQU CI:ALH+1 AVAILABLE EVENT INFORMATION BLOCK LIST TAIL CI:AEC EQU CI:ALT+1 AVAILABLE EVENT INFORMATION BLOCK COUNT CI:AET EQU CI:AEC+1 AVAILABLE EVENT INFORMATION BLOCK THRESHOLD CI:ESB EQU CI:AET+1 EVENT SPACE BASE CI:MLA EQU CI:ESB+1 MAXIMUM PROTOCOL LINKS ACTIVE CI:LCA EQU CI:MLA+1 PROTOCOL LINKS CURRENTLY ACTIVE CI:APL EQU CI:LCA+1 ACTIVE PROTOCOL LINK LIST CI:AEP EQU CI:APL+1 ACTIVE EVENT PROCESSOR LIST SIZE:CIB EQU CI:AEP+1 SIZE OF CONTROLLER INFORMATION BLOCK TITL DEVICE INFORMATION BLOCK OFFSET DEFINITIONS * * DIB OFFSET EQUATES * DI:PLS EQU 16 PROTOCOL LINK STATUS DI:ADR EQU DI:PLS+1 PROTOCOL LINK ADDRESSES DI:PIB EQU DI:ADR+1 PROTOCOL INFORMATION BLOCK ADDRESS DI:LCB EQU DI:PIB+1 LINK CONTROL BLOCK ADDRESS DI:BTI EQU DI:LCB+1 BUFFER AVAILABLE TIMEOUT INTERVAL DI:RQH EQU DI:BTI+1 READ LIST HEAD POINTER DI:RQT EQU DI:RQH+1 READ LIST TAIL POINTER DI:RQS EQU DI:RQT+1 READ LIST SEMAPHORE ADDRESS DI:WQH EQU DI:RQS+1 WRITE LIST HEAD POINTER DI:WQT EQU DI:WQH+1 WRITE LIST TAIL POINTER DI:WQS EQU DI:WQT+1 WRITE LIST SEMAPHORE ADDRESS DI:NTF EQU DI:WQS+1 MAXIMUM NUMBER OF TRANSMIT FRAME OUTSTANDING DI:IDS EQU DI:NTF+1 STATION IDENTIFICATION SIZE:DIB EQU DI:IDS+4 SIZE OF DEVICE INFORMATION BLOCK TITL PROTOCOL INFORMATION BLOCK OFFSET DEFINITIONS * * PIB OFFSET EQUATES * PI:LOF EQU 0 LINK OPTIONS FLAGS PI:POF EQU PI:LOF+1 PROTOCOL OPTIONS FLAGS PI:RFI EQU PI:POF+1 RESPONSE INTERVAL PI:PSI EQU PI:RFI+1 POLLING INTERVAL PI:CRT EQU PI:PSI+1 CONTROL RETRY THRESHOLD PI:IFT EQU PI:CRT+1 INFORMATION RETRY THRESHOLD PI:WDW EQU PI:IFT+1 WINDOW SIZE PI:VSC EQU PI:WDW+1 VALID SUPERVISORY CODES PI:VUC EQU PI:VSC+1 VALID UNNUMBERED COMMAND/RESPONSE CODES SIZE:PIB EQU PI:VUC+4 SIZE OF PROTOCOL INFORMATION BLOCK TITL BUFFER INFORMATION / CONTROL REQUEST BLOCK OFFSET DEFINITIONS * * BIB OFFSET EQUATES * BI:NXT EQU 0 NEXT POINTER BI:QPB EQU BI:NXT+1 COMPLETION QUEUE POINTER BLOCK BI:ORF EQU BI:QPB+1 OPERATION FLAGS BI:BUF EQU BI:ORF+1 BUFFER ADDRESS BI:BCT EQU BI:BUF+1 REQUEST COUNT BI:ACT EQU BI:BCT+1 ACTUAL COUNT BI:SEQ EQU BI:ACT+1 SEQUENCE NUMBER BI:HDR EQU BI:SEQ+1 HEADER DATA SIZE:BIB EQU BI:HDR+2 BUFFER INFORMATION / CONTROL REQUEST BLOCK SIZE SPACE 2 * * CRB OFFSET EQUATES * CR:NXT EQU 0 NEXT POINTER CR:QPB EQU CR:NXT+1 COMPLETION QUEUE POINTER BLOCK CR:ORF EQU CR:QPB+1 OPERATION REQUEST FLAGS CR:CRC EQU CR:ORF+1 CONTROL REQUEST CODE CR:DIB EQU CR:CRC+1 BASE ADDRESS OF ASSOCIATED DIB SIZE:CRB EQU SIZE:BIB TITL FLAG WORD BIT AND FIELD DEFINITIONS * * DEVICE AND LINE STATE FLAGS (CIB) * WORD:BGN DLS:OPR FLAG: DEVICE OPERATIVE FLAG DLS:ACT FLAG: LINE ACTIVE FLAG DLS:DED FLAG: DEDICATED LINE FLAG DLS:CON FLAG: CONNECTED LINE FLAG DLS:MTP FLAG: MULTIPOINT LINE FLAG DLS:AAE FLAG: AUTOANSWER ENABLED FLAG DLS:TWS FLAG: TWO-WAY SIMULTANEOUS FLAG DLS:CHN FLAG: CHANNEL SELECTION FLAG DLS:LCA FLAG: LINE CONTROL ACTIVITY PRESENT FLAG WORD:END SPACE 2 * * PROTOCOL LINK STATUS (DIB) * WORD:BGN PLS:IDP FLAG: IDENTIFICATION SEQUENCE PRESENT FLAG PLS:PSF FLAG: PRIMARY STATION FUNCTION OPERATING FLAG PLS:SSF FLAG: SECONDARY STATION FUNCTION OPERATING FLAG PLS:SYM FLAG: SYMMETRIC PROTOCOL LINK FLAG PLS:PSS FIELD: 3 PRIMARY STATION STATE PLS: SSS FIELD: 3 SECONDARY STATION STATE PLS:IDL FIELD: 3 LENGTH OF IDENTIFICATION SEQUENCE WORD:END * * LINK OPTIONS FLAGS (PIB, PST) * WORD:BGN LOF:TWS FLAG: TWO-WAY SIMULTANEOUS FLAG LOF:DED FLAG: DEDICATED LINE FLAG LOF:MTP FLAG:  MULTIPOINT LINE FLAG LOF:ESN FLAG: EXTENDED SEQUENCE NUMBERING ENABLED FLAG LOF:NSN FLAG: NORMAL SEQUENCE NUMBERING ENABLED FLAG LOF:PMM FIELD: 5 SET OF ENABLED LOCAL STATION TYPES * LOF:NS EQU LOF:PMMB+0 NORMAL SECONDARY STATION ENABLE LOF:AS EQU LOF:PMMB+1 ASYNCHRONOUS SECONDARY STATION ENABLE LOF:NP EQU LOF:PMMB+2 NORMAL PRIMARY STATION ENABLE LOF:AP EQU LOF:PMMB+3 ASYNCHRONOUS PRIMARY STATION ENABLE LOF:AC EQU LOF:PMMB+4 ASYNCHRONOUS COMBINED STATION ENABLE * WORD:END SPACE 2 * * PROTOCOL OPTIONS FLAGS (PIB, PST) * WORD:BGN POF:RD FLAG: REQUEST DISCONNECT ENABLED POF:XID FLAG: EXCHANGE IDENTIFICATION ENABLED POF:REJ FLAG: REJECT ENABLED POF:SREJ FLAG: SELECTIVE REJECT ENABLED POF:UI FLAG: UNNUMBERED INFORMATION ENABLED POF:SIM FLAG: INITIALIZATION MODE ENABLED POF:UP FLAG: UNNUMBERED POLL ENABLED POF:MRO FLAG: MODE RESET ONLY POF:ICO FLAG: INFORMATION TRANSFER BY COMMANDS ONLY POF:IRO FLAG:  INFORMATION TRANSFER BY RESPONSES ONLY POF:SYM FLAG: SYMMETRIC PROTOCOL LINK WORD:END SPACE 2 * * OPERATION REQUEST FLAGS (BIB, CRB) * WORD:BGN ORF:NSI FLAG: NON-SEQUENTIAL INFORMATION FLAG ORF:BRD FLAG: BROADCAST ADDRESSING FLAG ORF:ERR FLAG: ERROR TERMINATION FLAG ORF:AHL FIELD: 3 ACTUAL USER HEADER LENGTH ORF:EHL FIELD: 3 EXPECTED USER HEADER LENGTH ORF:TRM FIELD: 4 TERMINATION CODE WORD:END SPACE 2 END D D D D D D D D D D D D D D D D D D D D D D D D D IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII TITL SYNCHRONOUS HANDLER USER MACROS (93438-91/A030) TITL CONTROLLER INFORMATION BLOCK GENERATION MACRO * * CIB:SC * *  MACRO GENERATES A SYNCHRONOUS COMMUNICATIONS CONTROLLER * INFORMATION BLOCK. * * PARAMETERS ARE: * SCnn - THE NAME OF ANY ASSOCIATED DEVICE INFORMATION BLOCK * addr - THE DEVICE ADDRESS OF THE SYNCHRONOUS COMMUNICATIONS *  CONTROLLER * chan - THE CHANNEL NUMBER ON THE CONTROLLER (0 OR 1) * nnn - THE BIT RATE OF THE LINE IN 100 BIT/SECOND UNITS * pcn - THE NAME OF THE CIB FOR THE PAIRED CONTROLLER CHANNEL * * THESE REQUIRED PARAMETERS MAY BE FOLLOWED BY A VARIETY OF OPTIONAL * PARAMETERS. THE MAXIMUM TOTAL NUMBER OF PARAMETERS IS THIRTEEN. * CIB:SC MACRO IFF #?>=4 NOTE W,INSUFFICIENT.PARAMETERS.FOR.CALL ENDC IFF #?<15 NOTE E,TOO.MANY.PARAMETERS.FOR.CALL ENDC IFT #?>=4 IFT #?<14 LPOOL O: SET $ TABLE: REL SHARABLE TABLE: SYSTEM C:#(1,1,3) NAM C:#(1,1,3) I: SET 0 INTERNAL INTERFACE FLAG M: SET -1 MAXIMUM NUMBER OF PROTOCOL LINKS ACTIVE P: SET -1 BASE PRIORITY LEVEL T: SET -1 IDLE DISCONNECT TIMEOUT F: SET 1%DLS:DED DEVICE AND LINE STATE FLAGS ACCUMULATION F: SET 1%DLS:TWS;F: D: SET 0 DEFINED FLAGS MASK IFT #?>5 SC:CIBOP #(6),6 OPTIONAL PARAMETER AS ARGUMENT 6   IFT #?>6 SC:CIBOP #(7),7 OPTIONAL PARAMETER AS ARGUMENT 7 IFT #?>7 SC:CIBOP #(8),8 OPTIONAL PARAMETER AS ARGUMENT 8 IFT #?>8 SC:CIBOP #(9),9 OPTIONAL PARAMETER AS ARGUMENT 9 IFT #?>9 SC:CIBOP #(10),10 OPTIONAL PARAMETER AS ARGUMENT 10 IFT #?>10 SC:CIBOP #(11),11 OPTIONAL PARAMETER AS ARGUMENT 11 IFT #?>11 SC:CIBOP #(12),12 OPTIONAL PARAMETER AS ARGUMENT 12 IFT #?>12 SC:CIBOP #(13),13 OPTIONAL PARAMETER AS ARGUMENT 13 ENDC ENDC ENDC ENDC ENDC ENDC ENDC ENDC IFF I: EXTR SC:RD,SC:WRT,SC:FUN ENDC CHAN CIB: CI:PER RES 2,0 HEAD SC:#(1,3,3) CI:DIB WORD :7600 CI:PRI WORD #(2) CI:DA WORD 0 CI:IV WORD 0 CI:UNI  IFT I: WORD 0 CI:RD WORD 0 CI:WRT WORD 0 CI:POS WORD 0 CI:FUN ENDC IFF I: WORD SC:RD CI:RD WORD SC:WRT CI:WRT WORD 0 CI:POS WORD SC:FUN CI:FUN ENDC RES 4,0 INTERRUPT SEQUENCE (UNUSED) WORD 0 CI:T1 WORD 0 CI:T2 WORD 0 CI:APR WORD 0 CI:TIB WORD :7FFF CI:USM WORD 0 CI:TIM WORD 0 CI:CSM WORD 0 CI:CFL WORD 0 CI:LMS WORD 0 CI:CRH WORD 0 CI:CRT WORD #(3)%DLS:CHN;F: CI:DLS * LINE STATISTICS TABLE WORD 0 CI:FCS WORD 0 CI:RXM WORD 0 CI:OVR WORD 0 CI:MCS WORD 0 CI:HDW WORD 0 CI:AFR WORD 0 CI:AFT WORD 0 CI:UFR WORD 0 CI:UFT IFT #(5,?) WORD #(5) CI:PCC ENDC IFF #(5,?) WORD 0 CI:PCC ENDC WORD #(4) CI:LBR WORD 0 CI:AAR WORD 0 CI:AAT WORD 0 CI:URR WORD 0 CI:URT IFT P:<0 P: SET :7A00 SET DEFAULT BASE PRIORITY LEVEL ENDC WORD P: CI:BPL WORD 0 CI:PIB WORD 0 CI:ADR WORD 0 CI:LCP WORD 0 CI:DCP WORD 0 CI:RCP WORD 0 CI:RDP WORD 0 CI:TCP WORD 0 CI:TDP WORD 0 CI:TPP WORD DCT:#(1,3,3) CI:DCT WORD 0 CI:ALH WORD 0 CI:ALT WORD 0 CI:AEC WORD 0 CI:AET WORD 0 CI:ESB IFT M:<0 M: SET 1 ENDC WORD M: CI:MLA WORD 0 CI:LCA WORD 0 CI:APL WORD 0 CI:AEP DCT:#(1,3,3) WORD C:#(1,1,3) DC:CIB WORD 0 DC:RIP WORD 0 DC:RSA WORD 0 DC:RRC WORD 0 DC:RCB WORD 0 DC:TIP WORD 0 DC:TSA WORD 0 DC:TRC WORD 0 DC:TCB WORD 0 DC:CIP WORD 0 DC:CSA WORD 0 DC:CRC WORD 0 DC:SIC WORD 0 DC:ACT WORD 0 DC:WRC WORD 0 DC:RDR WORD 0 DC:INT WORD 0 DC:DCF WORD 0 DC:EPT  IFT T:<0 T: SET 0 ENDC WORD T: DC:IDT WORD 0 DC:WDT WORD 0 DC:SCS WORD 0 DC:TRM WORD 0 WORD 0 DC:REG WORD 0 EXTR SC:EOBR,SC:EOBT,SC:EOBS WORD 0 DC:RCS WORD 0 DC:RBC JSK DCT:#(1,3,3)R DC:RCI WORD 0 WORD 0 DC:TCS WORD 0 DC:TBC JSK DCT:#(1,3,3)T DC:TCI WORD 0 WORD 0 DC:CCS WORD 0 JSK DCT:#(1,3,3)S DC:SCI WORD 0 DCT:#(1,3,3)R JST R:SA12 INTERRUPT SEQUENCE COPY DCT:#(1,3,3)BA,X JMP *$+1 WORD SC:EOBR DCT:#(1,3,3)T JST R:SA12 TRANSMIT END OF BLOCK INTERRUPT SEQUENCE COPY DCT:#(1,3,3)BA,X  JMP *$+1 WORD SC:EOBT DCT:#(1,3,3)S JST R:SA12 STATUS INTERRUPT SEQUENCE COPY DCT:#(1,3,3)BA,X JMP *$+1 WORD SC:EOBS DCT:#(1,3,3)BA WORD DCT:#(1,3,3) BASE ADDRESS ORG O: ENDC ENDC ENDM SPACE 2 * * SC:CIBOP * * MACRO PROCESSES OPTIONAL PARAMETERS FOR CONTROLLER INFORMATION * BLOCK GENERATION. * * PARAMETERS ARE: * xxx - THE OPTIONAL PARAMETER FROM THE ORIGINAL MACRO CALL * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * SC:CIBOP MACRO R:: SET 0 PARAMETER RECOGNIZED FLAG IFT #(1,?)=3 IFT #(1,'INT') I: SET 1 R:: SET 1 ENDC ENDC IFT #(1,?)=2 IFT #(1,'SL') SC:SETOF DLS:DED,#(2),#(1) ENDC IFT #(1,'DL') SC:SETON DLS:DED,#(2),#(1) ENDC IFT #(1,'AA') SC:SETON DLS:AAE,#(2),#(1) ENDC IFT #(1,'MA')   SC:SETOF DLS:AAE,#(2),#(1) ENDC IFT #(1,'PP') SC:SETOF DLS:MTP,#(2),#(1) ENDC IFT #(1,'MP') SC:SETON DLS:MTP,#(2),#(1) ENDC IFT #(1,'TA') SC:SETOF DLS:TWS,#(2),#(1) ENDC IFT #(1,'TS') SC:SETON DLS:TWS,#(2),#(1) ENDC ENDC IFT #(1,?)>3 IFT #(1,'BP=')=1 SC:SETEQ P:,#(2),#(1),:7DFF,:4000 ENDC IFT #(1,'ML=')=1 SC:SETEQ M:,#(2),#(1),253,1 ENDC IFT #(1,'DI=')=1 SC:SETEQ T:,#(2),#(1),1200,1 ENDC ENDC IFF R:: NOTE W,UNRECOGNIZED.PARAMETER.NUMBER.#(2).#(1) ENDC ENDM TITL DEVICE INFORMATION BLOCK GENERATION MACRO * * DIB:SC * * MACRO GENERATES A SYNCHRONOUS COMMUNICATIONS CONTROLLER DEVICE * INFORMATION BLOCK, CORRESPONDING TO A PROTOCOL LINK. * * PARAMETERS ARE: * SCnn - THE NAME OF THE PROTOCOL LINK * pib - THE NAME OF THE PROTOCOL INFORMATION BLOCK TO BE USED * * THESE REQUIRED PARAMETERS MAY BE FOLLOWED BY A VARIETY OF OPTIONAL * PARAMETERS. THE MAXIMUM TOTAL NUMBER OF PARAMETERS IS EIGHT. * DIB:SC MACRO IFF #?>=2 NOTE E,INSUFFICIENT.PARAMETERS.FOR.CALL ENDC IFF #?<8 NOTE E,TOO.MANY.PARAMETERS.FOR.CALL ENDC IFT #?>=2 IFT #?<9 I: SET 0 INTERNAL INTERFACE FLAG S: SET -1 LOCAL STATION ADDRESS D: SET -1 DESTINATION STATION ADDRESS N: SET -1 PARAMETER NUMBER OF QUOTED STATION IDENTIFIER B: SET -1 BUFFER AVAILABLE TIMEOUT VALUE T: SET -1 MAXIMUM NUMBER OF TRANSMIT FRAMES OUTSTANDING IFT #?>2 SC:DIBOP #(3),3 OPTIONAL PARAMETER AS ARGUMENT 3 IFT #?>3 SC:DIBOP #(4),4 OPTIONAL PARAMETER AS ARGUMENT 4 IFT #?>4 SC:DIBOP #(5),5 OPTIONAL PARAMETER AS ARGUMENT 5 IFT #?>5 SC:DIBOP #(6),6 OPTIONAL PARAMETER AS ARGUMENT 6 IFT #?>6 SC:DIBOP #(7),7 OPTIONAL PARAMETER AS ARGUMENT 7 IFT #?>7 SC:DIBOP #(8),8 OPTIONAL PARAMETER AS ARGUMENT 8 ENDC ENDC ENDC ENDC ENDC ENDC U: SET S:<0 U: SET D:<0;U: IFT U: NOTE W,STATION.ADDRESSES.NOT.DEFINED ENDC IFF U: IFT S:=D: NOTE W,DUPLICATE.STATION.ADDRESSES ENDC ENDC LPOOL O: SET $ TABLE: REL SHARABLE TABLE: SYSTEM D:#(1) NAM D:#(1) CHAN SC:#(1,3,3) DI:PER WORD 0 DI:FLG WORD C:SC#(1,3,3) DI:CIB WORD 0 DI:FCB BYTE '##(1)' DI:NAM WORD 0 DI:DN WORD 0 DI:DS WORD 0 DI:SPB WORD 0 DI:WBT IFT I: WORD 0 DI:DSW WORD 0 . WORD 0 . WORD 0 . ENDC IFF I: WORD :0D01 DI:DSW WORD :0D01 . WORD 0 . WORD :0093 . ENDC WORD 0 RESERVED WORD 0 . IFT N:>0 V: SET C:%PLS:IDLB WORD 1%PLS:IDP;V: DI:PLS ENDC IFF N:>0 WORD 0 DI:PLS ENDC WORD D:%8;S: DI:ADR WORD P:#(2) DI:PIB WORD 0 DI:LCB IFT B:<0 B: SET 0 ENDC WORD B: DI:BTI WORD 0 DI:RQH WORD 0 DI:RQT WORD 0 DI:RQS WORD 0 DI:WQH WORD 0 DI:WQT WORD 0 DI:WQS IFT T:<0 T: SET 1 ENDC WORD T: DI:NTF IFT N:>0 V: SET #(N:,?) BYTE #(N:,4,V:) DI:IDS ENDC ORG O: ENDC ENDC ENDM SPACE 2 * * SC:DIBOP * * MACRO PROCESSES OPTIONAL PARAMETERS FOR DEVICE INFORMATION BLOCK * GENERATION. * * PARAMETERS ARE: * xxx - THE OPTIONAL PARAMETER FROM THE ORIGINAL MACRO CALL * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * SC:DIBOP MACRO R:: SET 0 PARAMETER RECOGNIZED FLAG IFT #(1,?)=3 IFT #(1,'INT') I: SET 1 R:: SET 1 ENDC ENDC IFT #(1,?)>3 IFT #(1,'BT=')=1 SC:SETEQ B:,#(2),#(1),200,1 ENDC IFT #(1,'SA=')=1 SC:SETEQ S:,#(2),#(1),254,1 ENDC IFT #(1,'DA=')=1 SC:SETEQ D:,#(2),#(1),254,1 ENDC IFT #(1,'TF=')=1 SC:SETEQ T:,#(2),#(1),10,1 ENDC IFT  #(1,'ID=')=1 R:: SET 1 IFF N:<0 NOTE W,DUPLICATE.PARAMETER.SPECIFICATION.NUMBER.#(2).#(1) ENDC IFT N:<0 C: SET #(1,?)-5 IFT C:<1 NOTE W,INVALID.STATION.IDENTIFICATION.NUMBER.#(2).#(1) ENDC IFF C:<1 N: SET #(2) IFT C:>8 C: SET 8 NOTE W,STATION.IDENTIFICATION.TOO.LONG.NUMBER.#(2).#(1) ENDC ENDC ENDC ENDC ENDC IFF R:: NOTE W,UNRECOGNIZED.PARAMETER.NUMBER.#(2).#(1) ENDC ENDM TITL PROTOCOL INFORMATION BLOCK GENERATION MACROS * * PIB:SCO * * MACRO GENERATES A SET OF PROTOCOL OPTIONS FLAGS USED IN THE * GENERATION OF THE PROTOCOL INFORMATION BLOCK. * * A VARIETY OF OPTIONAL PARAMETERS MAY BE SPECIFIED FOR THIS MACRO. * THE MAXIMUM NUMBER OF PARAMETERS IS TEN. * POF::VAL SET 0 INITIAL STATE FOR PROTOCOL OPTIONS FLAGS * PIB:SCO MACRO IFT #?>10 NOTE E,TOO.MANY.ARGUMENTS.FOR.CALL ENDC IFF #?>10 F: SET 0 INITIALIZE PROTOCOL OPTIONS FLAGS ACCUMULATION D: SET 0 DEFINED FLAGS MASK IFT #?>0 SC:PIBOO #(1),1 OPTIONAL PARAMETER AS ARGUMENT 1 IFT #?>1 SC:PIBOO #(2),2 OPTIONAL PARAMETER AS ARGUMENT 2 IFT #?>2 SC:PIBOO #(3),3 OPTIONAL PARAMETER AS ARGUMENT 3 IFT #?>3 SC:PIBOO #(4),4 OPTIONAL PARAMETER AS ARGUMENT 4 IFT #?>4 SC:PIBOO #(5),5 OPTIONAL PARAMETER AS ARGUMENT 5 IFT #?>5 SC:PIBOO #(6),6 OPTIONAL PARAMETER AS ARGUMENT 6 IFT #?>6 SC:PIBOO #(7),7 OPTIONAL PARAMETER AS ARGUMENT 7 IFT #?>7 SC:PIBOO #(8),8 OPTIONAL PARAMETER AS ARGUMENT 8 IFT #?>8 SC:PIBOO #(9),9 OPTIONAL PARAMETER AS ARGUMENT 9 IFT #?>9 SC:PIBOO #(10),10 OPTIONAL PARAMETER AS ARGUMENT 10 ENDC  ENDC ENDC ENDC ENDC ENDC ENDC ENDC ENDC ENDC POF::VAL SET F: SET VALUE TO BE USED FOR PIB GENERATION ENDC ENDM SPACE 2 * * PIB:SC * * MACRO GENERATES A SYNCHRONOUS COMMUNICATIONS CONTROLLER PROTOCOL * INFORMATION BLOCK. * * PARAMETERS ARE: * pib - THE NAME OF THE GENERATED PROTOCOL INFORMATION BLOCK * * THIS REQUIRED PARAMETER MAY BE FOLLOWED BY A VARIETY OF OPTIONAL * PARAMETERS. THE MAXIMUM TOTAL NUMBER OF PARAMETERS IS TEN. * PIB:SC MACRO IFF #?>0 NOTE E,REQUIRED.PARAMETER.MISSING.FROM.CALL ENDC IFF #?<11 NOTE E,TOO.MANY.PARAMETERS.FOR.CALL ENDC IFT #?>0 IFT #?<11 F: SET 0 LINK OPTIONS FLAGS ACCUMULATION D: SET 0 DEFINED FLAGS MASK R: SET -1 RESPONSE TIMEOUT INTERVAL P: SET -1 POLL TIMEOUT INTERVAL I: SET -1 INFORMATION FRAME RETRY THRESHOLD C: SET -1 CONTROL FRAME RETRY THRESHOLD W: SET -1 WINDOW SIZE IFT #?>1 SC:PIBOP #(2),2 OPTIONAL PARAMETER AS ARGUMENT 2 IFT #?>2 SC:PIBOP #(3),3 OPTIONAL PARAMETER AS ARGUMENT 3 IFT #?>3 SC:PIBOP #(4),4 OPTIONAL PARAMETER AS ARGUMENT 4 IFT #?>4 SC:PIBOP #(5),5 OPTIONAL PARAMETER AS ARGUMENT 5 IFT #?>5 SC:PIBOP #(6),6 OPTIONAL PARAMETER AS ARGUMENT 6 IFT #?>6 SC:PIBOP #(7),7 OPTIONAL PARAMETER AS ARGUMENT 7 IFT #?>7 SC:PIBOP #(8),8 OPTIONAL PARAMETER AS ARGUMENT 8 IFT #?>8 SC:PIBOP #(9),9 OPTIONAL PARAMETER AS ARGUMENT 9 IFT #?>9 SC:PIBOP #(10),10 OPTIONAL PARAMETER AS ARGUMENT 10 ENDC ENDC ENDC ENDC ENDC ENDC ENDC ENDC ENDC LPOOL O: SET $ TABLE: REL SHARABLE TABLE: SYSTEM P:#(1) NAM P:#(1) IFF LOF:PMMM%LOF:PMMB&F: F: SET 1%LOF:NS;F: ENDC V: SET 1%LOF:ESN V: SET 1%LOF:NSN;V: IFF V:&F: F: SET 1%LOF:NSN;F: ENDC WORD F: PI:LOF WORD POF::VAL PI:POF IFT R:<0 R: SET 120 ENDC WORD R: PI:RFI IFT P:<0 P: SET 0 ENDC WORD P: PI:PSI IFT  C:<0 C: SET 0 ENDC WORD C: PI:CRT IFT I:<0 I: SET 4 ENDC WORD I: PI:IFT IFT W:<0 W: SET 0 ENDC WORD W: PI:WDW M: SET 3 IFT 1%POF:REJ&POF::VAL M: SET 1%2;M: ENDC IFT 1%POF:SREJ&POF::VAL M: SET 1%3;M: ENDC WORD M: PI:VSC M: SET :8988 IFT 1%POF:SIM&POF::VAL M: SET 1%1;M: ENDC IFT 1%POF:UI&POF::VAL M: SET 1%0;M: ENDC IFT 1%POF:UP&POF::VAL M: SET 1%4;M: ENDC WORD M: PI:VUC (COMMANDS 0 - 15) M: SET :0801 IFT 1%LOF:AC&F: IFF 1%POF:MRO&POF::VAL M: SET 1%3;M: ENDC ENDC IFT 1%POF:XID&POF::VAL M: SET 1%7;M: ENDC WORD M: PI:VUC (COMMANDS 16 - 31) M: SET :1008 IFT 1%POF:SIM&POF::VAL M: SET 1%1;M: ENDC IFT 1%POF:UI&POF::VAL M: SET 1%0;M: ENDC IFT 1%POF:RD&POF::VAL M: SET 1%8;M: ENDC WORD M: PI:VUC (RESPONSES 0 - 15) M: SET :0002 IFT 1%POF:XID&POF::VAL M: SET 1%7;M: ENDC WORD M: PI:VUC (RESPONSES 16 - 31) ORG O: ENDC ENDC ENDM SPACE 2 * * SC:PIBOO * *  MACRO PROCESSES OPTIONAL PARAMETERS FOR THE PROTOCOL INFORMATION * BLOCK GENERATION PROTOCOL OPTIONS MACRO. * * PARAMETERS ARE: * xxx - THE OPTIONAL PARAMETER FROM THE ORIGINAL MACRO CALL * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * SC:PIBOO MACRO R:: SET 0 PARAMETER RECOGNIZED FLAG IFT #(1,?)=4 IFT #(1,'SREJ') SC:SETON POF:SREJ,#(2),#(1) ENDC ENDC IFT #(1,?)=3 IFT #(1,'XID') SC:SETON POF:XID,#(2),#(1) ENDC IFT #(1,'REJ') SC:SETON POF:REJ,#(2),#(1)  ENDC IFT #(1,'SIM') SC:SETON POF:SIM,#(2),#(1) ENDC IFT #(1,'MRO') SC:SETON POF:MRO,#(2),#(1) ENDC IFT #(1,'ICO') IFT 1%POF:IRO&F: R:: SET 1 NOTE W,CONFLICTING.SPECIFICATION.ON.PARAMETER.#(2).#(1) ENDC IFF 1%POF:IRO&F: SC:SETON POF:ICO,#(2),#(1) ENDC ENDC IFT #(1,'IRO') IFT 1%POF:ICO&F: R:: SET 1 NOTE W,CONFLICTING.SPECIFICATION.ON.PARAMETER.#(2).#(1) ENDC IFF 1%POF:ICO&F: SC:SETON POF:IRO,#(2),#(1) ENDC ENDC IFT #(1,'SYM') SC:SETON POF:SYM,#(2),#(1) ENDC ENDC IFT #?=2 IFT #(1,'RD') SC:SETON POF:RD,#(2),#(1) ENDC IFT #(1,'UI') SC:SETON POF:UI,#(2),#(1) ENDC IFT #(1,'UP') SC:SETON POF:UP,#(2),#(1)  ENDC ENDC IFF R:: NOTE W,UNRECOGNIZED.PARAMETER.NUMBER.#(2).#(1) ENDC ENDM SPACE 2 * * SC:PIBOP * * MACRO PROCESSES OPTIONAL PARAMETERS FOR THE PROTOCOL INFORMATION * BLOCK GENERATION MACRO. * * PARAMETERS ARE: * xxx - THE OPTIONAL PARAMETER FROM THE ORIGINAL MACRO CALL * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * SC:PIBOP MACRO R:: SET 0 PARAMETER RECOGNIZED FLAG IFT #(1,?)=2 IFT #(1,'NS') SC:SETON LOF:NS,#(2),#(1) ENDC IFT #(1,'AS') SC:SETON LOF:AS,#(2),#(1) ENDC IFT #(1,'NP') SC:SETON LOF:NP,#(2),#(1) ENDC IFT #(1,'AP') SC:SETON LOF:AP,#(2),#(1) ENDC IFT #(1,'AC') SC:SETON LOF:AC,#(2),#(1) ENDC IFT #(1,'EN') SC:SETON LOF:ESN,#(2),#(1) ENDC IFT #(1,'NN') SC:SETON LOF:NSN,#(2),#(1) ENDC ENDC IFT #(1,?)>3 IFT #(1,'RI=')=1 SC:SETEQ R:,#(2),#(1),,1 ENDC IFT #(1,'PI=')=1 SC:SETEQ P:,#(2),#(1),,1 ENDC IFT #(1,'IR=')=1 SC:SETEQ I:,#(2),#(1),,1 ENDC IFT #(1,'CR=')=1 SC:SETEQ C:,#(2),#(1),,1 ENDC IFT #(1,'WD=')=1 SC:SETEQ W:,#(2),#(1),254,0 ENDC ENDC IFF R: NOTE W,UNRECOGNIZED.PARAMETER.NUMBER.#(2).#(1) ENDC ENDM TITL SET AND RESET FLAGS MACROS DEFINITION * * SC:SETON, SC:SETOF * * MACROS RESPECTIVELY SET AND RESET THE SPECIFIED FLAG IN THE FLAG * AC  CUMULATION VARIABLE 'F:'. THE CORRESPONDING FLAG IN THE DEFINED * FLAG ACCUMULATION VARIABLE 'D:' IS TESTED, AND IF SET A WARNING * MESSAGE IS GENERATED FOR THE DUPLICATE AND/OR CONTRADICTORY * SPECIFICATION OF FLAG STATE. IN ANY CASE, THE CORRESPONDING FLAG * IN 'D:' IS SET, AS IS THE PARAMETER RECOGNIZED FLAG 'R::'. * * PARAMETERS ARE: * XXX:XXX - THE BIT NUMBER FOR THE FLAG TO BE SET OR RESET * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * xxx - THE ACTUAL PARAMETER * SC:SETON MACRO 0 SC:SETOF MACENT 1 R:: SET 1 IFT 1%#(1)&D: NOTE W,DUPLICATE/CONFLICTING.SPECIFICATION.ON.PARAMETER.#(2).#(3) ENDC D: SET 1%#(1);D: F: SET 1%#(1);F: IFT #(0) F: SET 1%#(1)--F: ENDC ENDM TITL EXTRACT AND VALIDATE EQUATE VALUE MACRO DEFINITION * * SC:SETEQ * * MACRO EXTRACTS THE VALUE TO THE RIGHT OF THE '=' IN A PARAMETER *  STRING. A CHECK IS FIRST MADE TO DETERMINE IF THE VALUE HAS BEEN * SET PREVIOUSLY, AND IF SO A WARNING MESSAGE IS GENERATED. THE * VALUE IS THEN EXTRACTED, AND LIMIT CHECKS PERFORMED, WHICH CAN * GENERATE OTHER WARNING MESSAGES. * *  PARAMETERS ARE: * X: - SYMBOL TO BE USED FOR THE EXTRACTED VALUE * n - THE NUMBER OF THE PARAMETER WITHIN THE ORIGINAL MACRO CALL * xxx - THE ACTUAL PARAMETER FROM THE ORIGINAL MACRO CALL * max - THE MAXIMUM VALUE FOR THE PARAMETER (OPTIONAL) * min - THE MINIMUM VALUE FOR THE PARAMETER (OPTIONAL) * SC:SETEQ MACRO R:: SET 1 IFT #(1)>=0 NOTE W,DUPLICATE.PARAMETER.SPECIFICATION.NUMBER.#(2).#(3) ENDC IFF #(1)>=0 L::: SET #(3,?) F::: SET #(3,'=')+1 #(1) SET #(3,F:::,L:::) IFT #(5,?) IFT #(1)<#(5) #(1) SET #(5) NOTE W,VALUE.LESS.THAN.MINIMUM.FOR.PARAMETER.#(2).#(3) ENDC ENDC IFT #(4,?) IFT #(1)>#(4) #(1) SET #(4) NOTE W,VALUE.GREATER.THAN.MAXIMUM.FOR.PARAMETER.#(2).#(3) ENDC ENDC ENDC ENDM SPACE 2 END A A A A A AIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII TITL SYNCHRONOUS COMMUNICATIONS HANDLER SAMPLE PROGRAM (93438-1B/A030) TITL INPUT/OUTPUT CONTROL BLOCK DEFINITIONS * * TABLES ARE SET UP FOR 9600 BITS PER SECOND OPERATION OF THE * SYNCHRONOUS COMMUNICATIONS CONTROLLER, WITH THE STANDARD DEVICE * ADDRESS OF :D. PROTOCOL OPERATION IS ASYNCHRONOUS BALANCED MODE * WITH EXTENDED SEQUENCE NUMBERING (NORMAL NUMBERING IS ALSO * ENABLED, BUT EXTENDED IS THE PREFERRED MODE AND WILL BE USED IN * THIS CASE). * CIB:SC SC00,:68,0,96,C:SC1,DL,MA,PP,TS,BP=:7A00,ML=1 DIB:SC SC00,COM,SA=1,DA=2,BT=25 CIB:SC SC10,:68,1,96,C:SC0,DL,MA,PP,TS,BP=:7A00,ML=1 DIB:SC SC10,COM,SA=2,DA=1,BT=25 PIB:SC COM,AC,EN,NN,RI=20,PI=40,IR=4,CR=4 * * THIS HAS BEEN EDITED TO ELIMINATE THE LISTING OF CODE GENERATED * BY THE ABOVE MACRO CALLS, IN ORDER TO CONSERVE SPACE USED IN THE * MANUAL. * END D D D D D D D D D D D D D D D D D FOR BACK-TO-BACK CONNECTION IS * DESCRIBED IN THE SYNCHRONOUS COMMUNICATIONS CONTROLLER MANUAL, OR * CAN BE ORDERED FROM  COMPUTER AUTOMATION (FOR RS-232 BOARD, 53870, * USE 81-21550-01, PRODUCT NUMBER 63-21550-01; FOR RS-449 BOARD, * 53874, USE 81-21553-01, PRODUCT NUMBER 63-21553-01). * * THE CONSOLE DATA REGISTER DISPLAYS THE NUMBER OF THE MOST-RECENTLY * RECEIVED BLOCK OF DATA DURING EXECUTION OF THE SAMPLE PROGRAM. THE * NUMBER OF BLOCKS TRANSMITTED IN AN EXECUTION IS DETERMINED BY AN * ASSEMBLY PARAMETER (NUMPASS). THE NUMBER OF BYTES IN EACH BLOCK OF * DATA, AND THE DATA PATTERN USED FOR THE BLOCK, ARE BOTH EQUAL TO * THE NUMBER OF THE BLOCK, MOD 256 (EXCEPT FOR MULTIPLES OF 256, WHEN * A LENGTH OF 256 IS USED). ALL ERRORS EXIT DIRECTLY TO DEBUG. * LOAD DEBUG4 EXTR D:SC00,D:SC10 TASK REL SHARABLE TASK G:0 NAM G:0 SPACE 2 * *  OPERATIONAL PARAMETER EQUATES * NUMPASS EQU :200 NUMBER OF FRAMES TO BE TRANSFERRED MAXBUFF EQU NUMPASS-1&:FF+1/2 MAXIMUM WORDS IN BLOCK OF DATA NUMOPER EQU 2 NUMBER OF OPERATION ACTIVITIES TO BE USED TITL TEST TASK SCRATCHPAD DEFINITIONS * * TEST TASK SCRATCHPAD * * TEST TASK SCRATCHPAD AREA USED TO KEEP TRACK OF THE STATUS OF * THE TEST SEQUENCE CONSISTS OF: *  1) INTERNAL CONTROL INFORMATION FOR THE TEST PROGRAM ACTIVITY. * 2) SHARED DATA AREAS FOR THE READ AND WRITE OPERATION ACTIVITIES * (HEAD AND TAIL POINTERS FOR LINKED LISTS OF COMPLETED * OPERATIONS, COUNTS OF ACTIVITIES OF EACH TYPE RUNNING, AND * THE ADDRESS OF THE SEMAPHORE TO BE SIGNALLED WHEN AN * OPERATION IS COMPLETED) *  3) ONE-WORD SEMAPHORE WHICH THE TEST PROGRAM ACTIVITY WAITS ON * WHEN NOT PROCESSING A COMPLETED OPERATION. *  4) STANDARD IOS4 INPUT/OUTPUT BLOCK. * THE TEST TASK SCRATCHPAD IS ALLOCATED AT THE TIME A TEST TASK * ACTIVITY IS STARTED. * TPSCWN EQU 0 CURRENT WRITE OPERATION NUMBER TPSCRN EQU TPSCWN+1 CURRENT READ OPERATION NUMBER TPSNUM EQU TPSCRN+1 ACTIVITY LOOP COUNTER TPSCNT EQU TPSNUM+1 BUFFER LOOP COUNTER TPSBUF EQU TPSCNT+1 POINTER FOR BUFFER OPERATIONS TPSWCH EQU TPSBUF+1 COMPLETED WRITE OPERATION QUEUE TPSWCT EQU TPSWCH+1 COMPLETED WRITE OPERATION QUEUE TAIL TPSNWA EQU TPSWCT+1 NUMBER OF WRITE OPERATION ACTIVITIES TPSWSA EQU TPSNWA+1 WRITE COMPLETION SEMAPHORE ADDRESS TPSRCH EQU TPSWSA+1 COMPLETED READ OPERATION QUEUE HEAD TPSRCT EQU TPSRCH+1 COMPLETED READ OPERATION QUEUE TAIL TPSNRA EQU TPSRCT+1 NUMBER OF READ OPERATION ACTIVITIES TPSRSA EQU TPSNRA+1 READ COMPLETION SEMAPHORE ADDRESS TPSSEM EQU TPSRSA+1 SEMAPHORE WORD FOR ACTIVITY TPSLUN EQU TPSSEM+1 LOGICAL UNIT NAME FOR INPUT/OUTPUT BLOCK TPSUNA EQU TPSLUN+1 FIRST UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUNB EQU TPSUNA+1 SECOND UNUSED WORD IN INPUT/OUTPUT BLOCK TPSFC EQU TPSUNB+1 FUNCTION CODE FOR INPUT/OUTPUT BLOCK TPSUNC EQU TPSFC+1 THIRD UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUND EQU TPSUNC+1 FOURTH UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUNE EQU TPSUND+1 FIFTH UNUSED WORD IN INPUT/OUTPUT BLOCK TPSST EQU TPSUNE+1 SOFTWARE STATUS RETURNED FOR INPUT/OUTPUT BLOCK SIZETSP EQU TPSST+1 SIZE OF TEST PROGRAM SCRATCHPAD AREA TITL OPERATION TASK SCRATCHPAD DEFINITIONS * * EXTENDED INPUT/OUTPUT BLOCK * * EXTENDED INPUT/OUTPUT BLOCKS USED BY THE PROGRAM FOR READ AND * WRITE OPERATIONS CONSIST OF: * 1) LINKAGE WORD FOR USE WHEN THE OPERATION IS COMPLETED AND *   THE ACTIVITY PERFORMING THE OPERATION ADDS IT TO THE LIST * OF COMPLETED READ OR WRITE OPERATIONS. * 2) ONE-WORD SEMAPHORE WHICH THE ACTIVITY PERFORMING THE * OPERATION WAITS ON WHEN THE OPERATION IS COMPLETED. * 3) INTERNAL CONTROL INFORMATION FOR THE ACTIVITY PERFORMING THE * OPERATION. * 4) STANDARD IOS4 INPUT/OUTPUT BLOCK. * 5) BUFFER AREA FOR THE READ OR WRITE OPERATION. * THE EXTENDED INPUT/OUTPUT BLOCK IS ALLOCATED AT THE TIME THE *  CORRESPONDING OPERATION ACTIVITY IS STARTED, AS A SCRATCHPAD AREA. * EIONXT EQU 0 NEXT POINTER FOR COMPLETED LIST EIOSEM EQU EIONXT+1 SEMAPHORE WORD FOR ACTIVITY EIOTRM EQU EIOSEM+1 TERMINATION FLAG WORD EIOSHR EQU EIOTRM+1 ADDRESS OF SHARED INFORMATION AREA EIOLUN EQU EIOSHR+1 LOGICAL UNIT NAME FOR IOB EIOUNA EQU EIOLUN+1 FIRST UNUSED INPUT/OUTPUT BLOCK WORD EIOUNB EQU EIOUNA+1 SECOND UNUSED INPUT/OUTPUT BLOCK WORD EIOFC EQU EIOUNB+1 FUNCTION CODE FOR INPUT/OUTPUT BLOCK EIOBCT EQU EIOFC+1 INPUT/OUTPUT BLOCK REQUESTED COUNT EIOBUF EQU EIOBCT+1 INPUT/OUTPUT BLOCK BUFFER ADDRESS EIOACT EQU EIOBUF+1 ACTUAL COUNT FOR INPUT/OUTPUT BLOCK EIOST EQU EIOACT+1 SOFTWARE STATUS RETURNED FOR INPUT/OUTPUT BLOCK EIODATA EQU EIOST+1 READ/WRITE BUFFER AREA SIZEEIO EQU EIODATA+MAXBUFF SIZE OF EXTENDED INPUT/OUTPUT BLOCK TITL SYSTEM SERVICE PARAMETER BLOCKS AND TABLES * * INITIALIZATION BLOCK DEFINITION * INIT:A 0,0,0,0,ECB,TDBI,:2000,1024 * * INITIALIZATION TASK DEFINITION BLOCK * TDB:A TDBI,INIT,0,0,:20 * * TEST TASK DEFINITION BLOCK * TDB:A TDBT,TESTSTRT,SIZETSP,0,:50,0,16 * * TEST TASK ACTIVITY BEGIN BLOCK * BGIN:A BEGINTST,TDBT,:2000 * * OPERATION TASK DEFINITION BLOCK * TDB:A TDBO,OPERSTRT,SIZEEIO,0,:50,0,16 * * OPERATION TASK BEGIN BLOCK * BGIN:A BEGINOPR,TDBO,:2100 * * UNIT ASSIGNMENT TABLE DEFINITION * UAT:AA UAT UAT:EE 'L0',D:SC00 SYNCHRONOUS CONTROLLER LINE ZERO UAT:EE 'L1',D:SC10 SYNCHRONOUS CONTROLLER LINE ONE UAT:ZZ * * ENVIRONMENT CONTROL BLOCK DEFINITION * ECB:A ECB,UAT TITL SAMPLE PROGRAM INITIALIZATION TASK * * INITIALIZATION TASK STARTS TWO ACTIVITIES OF THE TEST TASK, ONE * FOR EACH OF THE TWO SYNCHRONOUS COMMUNICATIONS CONTROLLER CHANNELS. * THE INITIALIZATION TASK TERMINATES AFTER THE TWO TEST TASK * ACTIVITIES HAVE BEEN STARTED. * INIT EQU $ COPY ='L0',A SET LOGICAL UNIT NAME R:BGIN BEGINTST START FIRST ACTIVITY OF TEST TASK COPY ='L1',A SET LOGICAL UNIT NAME R:BGIN BEGINTST START SECOND ACTIVITY OF TEST TASK R:END TERMINATE INITIALIZATION TASK * LPOOL TITL SAMPLE PROGRAM TEST TASK * * TEST TASK PERFORMS THE FOLLOWING SEQUENCE OF OPERATIONS: * 1)  START THE REQUIRED NUMBER OF OPERATION TASK ACTIVITIES (AS * SPECIFIED BY THE NUMOPER EQUATE) FOR RECEIVE AND TRANSMIT * OPERATIONS. * 2) OPEN THE COMMUNICATIONS LINE PROTOCOL LINK. * 3) GENERATE DATA FOR TRANSMIT (WRITE) OPERATIONS, AND CHECK DATA * FROM RECEIVE (READ) OPERATIONS, USING THE OPERATION ACTIVITIES * TO PERFORM THE ACTUAL I/O OPERATIONS. * 4) TERMINATE THE OPERATION TASK ACTIVITIES. * 5) CLOSE THE COMMUNICATIONS LINE PROTOCOL LINK. * IF ERRORS ARE FOUND AT ANY POINT IN THE SEQUENCE, AN EXIT DIRECT TO * DEBUG IS TAKEN. * * START-UP PARAMETERS: *   A - LOGICAL UNIT NAME TO BE USED BY TEST TASK ACTIVITY * Y - ADDRESS OF SCRATCHPAD ALLOCATED FOR THIS ACTIVITY * TESTSTRT EQU $ JSK INITTEST INITIALIZE SCRATCHPAD AREA COPY =FU:%4+OP:,A SET OPERATION CODE FOR OPEN FUNCTION COPY A,TPSFC(Y) I:IO TPSLUN(Y) PERFORM THE OPEN OPERATION JST *0 ABNORMAL RETURN ENTERS DEBUG COPY TPSST(Y),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 JSK STRTOPER START THE OPERATION TASK ACTIVITIES COPY TPSNWA(Y),A NUMBER OF WRITE OPERATION ACTIVITIES NEG A SET NEGATIVE OF VALUE AS LOOP COUNT COPY A,TPSNUM(Y) TS01 EQU $ INITIALIZE WRITE OPERATION ACTIVITIES COPY Y,A SET ADDRESS OF WRITE COMPLETION QUEUE ADD =TPSWCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE COPY A,X SET UP INDEX REGISTER WITH ADDRESS JSK SETWRITE SET UP FOR WRITE OPERATION R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO DO IT IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP TS01 LOOP FOR ALL WRITE OPERATION ACTIVITIES TS02 EQU $ CHECK FOR WRITE OPERATION COMPLETIONS COPY Y,A SET ADDRESS OF WRITE COMPLETION QUEUE ADD =TPSWCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE JEQ A,TS05 JUMP IF QUEUE WAS EMPTY COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX COPY EIOST(X),A SOFTWARE STATUS RETURNED BY OPERATION CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 COPY TPSCWN(Y),A CURRENT WRITE OPERATION NUMBER SUB MAXPASS,A COMPARE WITH NUMBER TO BE DONE JNE A,TS03 JUMP UNLESS ALL OPERATIONS COMPLETED COPY =-1,A SET FLAG FOR TERMINATION REQUIRED COPY A,EIOTRM(X) JMP TS04 GO TO SIGNAL OPERATION ACTIVITY TS03 EQU $ CONTINUE WITH NEXT WRITE OPERATION JSK SETWRITE SET UP FOR NEXT WRITE OPERATION TS04 EQU $ SIGNAL OPERATION ACTIVITY R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME JMP TS02 LOOP TO CHECK IF MORE ON QUEUE TS05 EQU $ CHECK FOR READ OPERATION COMPLETIONS COPY Y,A SET ADDRESS OF READ COMPLETION QUEUE ADD =TPSRCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE JEQ A,TS06 JUMP IF QUEUE WAS EMPTY COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX JSK VALREAD VALIDATE COMPLETION OF READ OPERATION R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME JMP TS05 LOOP TO CHECK IF MORE ON QUEUE TS06 EQU $ OUTPUT READ OPERATION NUMBER IF DISPLAYED COPY TPSLUN(Y),A LOGICAL UNIT NAME SST 0 CHECK SENSE SWITCH SETTING XOR =1,A REVERSE SETTING OF LOW-ORDER BIT TBIT 0,A CHECK IF THIS LINE SELECTED FOR DISPLAY COPY TPSCRN(Y),A CURRENT READ OPERATION NUMBER JF OV,$+2 JUMP IF PAIRED LINE SELECTED SELP A,4 OUTPUT RECEIVE PASS NUMBER TO DATA REGISTER SUB MAXPASS,A CHECK FOR ALL READS COMPLETED JNE A,$+3 JUMP IF MORE READS TO BE DONE COPY TPSNWA(Y),A NUMBER OF WRITE OPERATION ACTIVITIES JEQ A,TS07 OUT OF LOOP IF WRITE OPERATIONS COMPLETED R:WAIT TPSSEM(Y) WAIT FOR A SIGNAL BEFORE RESUMING JMP TS02 LOOP TO CHECK COMPLETIONS TS07 EQU $ CLOSE LINK WHEN TESTING COMPLETED COPY =FU:%4+CL:,A SET OPERATION CODE FOR CLOSE FUNCTION COPY A,TPSFC(Y) I:IO TPSLUN(Y) PERFORM THE CLOSE OPERATION JST *0 ABNORMAL RETURN ENTERS DEBUG COPY TPSST(Y),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 TS08 EQU $ CHECK READS AND SIGNAL TO TERMINATE COPY Y,A SET ADDRESS OF READ COMPLETION QUEUE  ADD =TPSRCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX COPY EIOST(X),A SOFTWARE STATUS RETURNED BY OPERATION CSK A,=NORDY: CHECK FOR NOT READY TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 COPY =-1,A SET FLAG FOR TERMINATION REQUIRED COPY A,EIOTRM(X) R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME COPY TPSNRA(Y),A NUMBER OF READ OPERATION ACTIVITIES RUNNING JNE A,TS08 LOOP UNLESS ALL TERMINATED R:END TERMINATE TEST TASK ACTIVITY * MAXPASS WORD NUMPASS MAXIMUM DATA BLOCK NUMBER TITL INITTEST - INITIALIZE TEST ACTIVITY SCRATCHPAD * * INITTEST * * PROCEDURE INITIALIZES THE SCRATCHPAD AREA FOR A NEW TEST TASK * ACTIVITY. * * CALL PARAMETERS: * A - LOGICAL UNIT NAME TO BE USED BY TEST TASK ACTIVITY * * RETURN PARAMETERS: * A - DESTROYED * Q,X - UNCHANGED * INITTEST EQU $ COPY A,TPSLUN(Y) SAVE LOGICAL UNIT NAME FOR I/O COPY =0,A COPY A,TPSCWN(Y) INITIALIZE WRITE OPERATION NUMBER COPY A,TPSCRN(Y) INITIALIZE READ OPERATION NUMBER COPY A,TPSWCH(Y) INITIALIZE WRITE OPERATION QUEUE COPY A,TPSWCT(Y) COPY A,TPSNWA(Y) INITIALIZE NUMBER OF WRITE ACTIVITIES COPY A,TPSRCH(Y) INITIALIZE READ OPERATION QUEUE COPY A,TPSRCT(Y) COPY A,TPSNRA(Y) INITIALIZE NUMBER OF READ ACTIVITIES COPY A,TPSSEM(Y) INITIALIZE ACTIVITY SEMAPHORE WORD COPY A,TPSUNA(Y) INITIALIZE UNUSED WORDS OF IOB COPY A,TPSUNB(Y) COPY A,TPSUNC(Y) COPY A,TPSUND(Y) COPY A,TPSUNE(Y) COPY Y,A SET ADDRESS OF SEMAPHORE FOR COMPLETIONS ADD =TPSSEM,A COPY A,TPSWSA(Y) COPY A,TPSRSA(Y) RSK RETURN TO CALLER TITL STRTOPER - START OPERATION TASK ACTIVITIES * * STRTOPER * * PROCEDURE STARTS THE SPECIFIED NUMBER (NUMOPER EQUATE VALUE) OF * OPERATION TASK ACTIVITIES RUNNING FOR RECEIVE AND TRANSMIT * * CALL PARAMETERS: * NONE * * RETURN PARAMETERS: * A,Q,X - DESTROYED * STRTOPER EQU $ COPY =-NUMOPER,A SET UP LOOP CONTROL FOR READ ACTIVITIES COPY A,TPSNUM(Y) COPY =RE:%4+UF:,A SET OPERATION CODE FOR READS COPY TPSLUN(Y),Q SET LOGICAL UNIT NAME COPY Y,X SET ADDRESS OF SHARED READ ACTIVITY INFORMATION ADD =TPSRCH,X SO01 EQU $ LOOP FOR STARTING READ OPERATION ACTIVITIES R:BGIN BEGINOPR START AN OPERATION TASK ACTIVITY IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP SO01 LOOP FOR SPECIFIED NUMBER OF ACTIVITIES COPY =-NUMOPER,A SET UP LOOP CONTROL FOR WRITE ACTIVITIES COPY A,TPSNUM(Y) COPY =WR:%4+UF:,A SET OPERATION CODE FOR WRITES COPY Y,X SET ADDRESS OF SHARED WRITE ACTIVITY INFORMATION ADD =TPSWCH,X SO02 EQU $ LOOP FOR STARTING WRITE OPERATION ACTIVITIES R:BGIN BEGINOPR START AN OPERATION TASK ACTIVITY IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP SO02 LOOP FOR SPECIFIED NUMBER OF ACTIVITES RSK RETURN TO CALLER TITL REMQUEUE - REMOVE FIRST BLOCK FROM QUEUE * * REMQUEUE * * PROCEDURE REMOVES THE FIRST OPERATION TASK ACTIVITY SCRATCHPAD * BLOCK FROM A COMPLETION QUEUE. * * CALL PARAMETERS: * A - ADDRESS OF HEAD POINTER FOR COMPLETION QUEUE * *  RETURN PARAMETERS: * A - ZERO IF QUEUE EMPTY, ADDRESS OF OPERATION TASK ACTIVITY * SCRATCHPAD OTHERWISE *  Q,X - DESTROYED * REMQUEUE EQU $ COPY A,X COPY ADDRESS OF QUEUE HEAD POINTER SIN 6 PROTECT FROM INTERRUPTION BY OPERATION  ACTIVITIES COPY 0(X),X ADDRESS OF FIRST BLOCK ON QUEUE JEQ X,RQ01 JUMP IF QUEUE ALREADY EMPTY COPY EIONXT(X),Q GET ADDRESS OF NEXT ON QUEUE EXCH A,X SWAP BLOCK ADDRESS AND HEAD POINTER ADDRESS COPY Q,0(X) SET NEW HEAD OF QUEUE JNE Q,$+2 JUMP UNLESS QUEUE NOW EMPTY COPY Q,1(X) SET NULL TAIL POINTER FOR QUEUE RSK RETURN WITH ADDRESS OF BLOCK REMOVED RQ01 EQU $ QUEUE ALREADY EMPTY COPY =0,A SET NULL ADDRESS FOR BLOCK REMOVED RSK TITL SETWRITE - SET UP FOR NEXT WRITE OPERATION * * SETWRITE * * PROCEDURE INITIALIZES THE BYTE COUNT AND BUFFER CONTENTS FOR THE * NEXT WRITE OPERATION TO BE PERFORMED. * *  CALL PARAMETERS: * X - ADDRESS OF OPERATION ACTIVITY SCRATCHPAD * * RETURN PARAMETERS: * A,Q - DESTROYED *  X - UNCHANGED * SETWRITE EQU $ IMS TPSCWN(Y) INCREMENT CURRENT WRITE OPERATION NUMBER COPY TPSCWN(Y),A GET NUMBER OF OPERATION AND =:FF,A MASK LOW-ORDER BYTE OF NUMBER COPY A,EIOBCT(X) USE AS BYTE COUNT FOR WRITE JNE A,$+3 JUMP UNLESS ZERO MOD 256 COPY =:100,Q SET MAXIMUM LENGTH WRITE OPERATION COPY Q,EIOBCT(X) COPY A,Q FORM WORD BY DUPLICATING BYTE SHIFT A,LO,8 OR A,Q COPY EIOBUF(X),A BUFFER ADDRESS FOR OPERATION COPY A,TPSBUF(Y) SAVE IN SCRATCHPAD FOR FILLING COPY EIOBCT(X),A BYTE COUNT FOR OPERATION SUB =1,A CORRECT FOR LOOP COUNTER BIAS SHIFT A,RO,1 CONVERT TO WORD LOOP COUNTER SW01 EQU $ STORE A WORD OF DATA IN BUFFER COPY Q,*TPSBUF(Y) STORE WORD INTO BUFFER IMS TPSBUF(Y) INCREMENT FOR NEXT WORD OF BUFFER NOP JNED A,SW01 LOOP FOR ALL WORDS OF BUFFER RSK RETURN WITH OPERATION SET UP TITL VALREAD - VALIDATE READ OPERATION COMPLETION * * VALREAD * * PROCEDURE VALIDATES THE SOFTWARE STATUS AND DATA RETURNED BY A * COMPLETED READ OPERATION. * * CALL PARAMETERS: * X - ADDRESS OF OPERATION ACTIVITY SCRATCHPAD * * RETURN PARAMETERS: * A,Q - DESTROYED * X - UNCHANGED * VALREAD EQU $ COPY TPSCRN(Y),Q NUMBER OF LAST READ AND =:FF,Q TAKE MODULO 256 ADD =1,Q GET COUNT OF BYTES FOR OPERATION IMS TPSCRN(Y) INCREMENT CURRENT READ NUMBER COPY EIOST(X),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 CSK Q,EIOACT(X) CHECK FOR CORRECT READ LENGTH JST *0 ENTER DEBUG IF INCORRECT LENGTH JST *0 COPY EIOBUF(X),A ADDRESS OF BUFFER USED COPY A,TPSBUF(Y) SAVE IN SCRATCHPAD AREA FOR LOOP COPY =0,A INITIALIZE COUNT OF BYTES CHECKED VR01 EQU $ CHECK A WORD OF DATA READ COPY *TPSBUF(Y),Q LOAD WORD FROM BUFFER SHIFT Q,RO,8 POSITION HIGH-ORDER BYTE OF WORD XOR TPSCRN(Y),Q COMPARE WITH CURRENT READ NUMBER AND =:FF,Q CHECKING ONLY ONE BYTE OF VALUE JEQ Q,$+2 JUMP IF CORRECT DATA READ JST *0 ENTER DEBUG IF BAD DATA ADD =1,A INCREMENT COUNT OF BYTES CHECKED COPY EIOACT(X),Q LENGTH OF READ OPERATION CSN A,Q CHECK IF ALL BYTES CHECKED JMP VR02 EXIT LOOP IF DONE XOR *TPSBUF(Y),Q CHECK LENGTH AGAINST DATA  AND =:FF,Q MASK LOW-ORDER BYTE OF DIFFERENCE JEQ Q,$+2 JUMP IF CORRECT DATA READ JST *0 ENTER DEBUG IF BAD DATA IMS TPSBUF(Y) INCREMENT BUFFER POINTER FOR NEXT WORD NOP ADD =1,A INCREMENT COUNT OF BYTES CHECKED CSK A,EIOACT(X) CHECK IF DONE CHECKING DATA JMP VR01 LOOP TO CHECK ANOTHER WORD NOP VR02 EQU $ RESET IOB AND RETURN COPY =0,A RESET ACTUAL COUNT IN IOB COPY A,EIO ACT(X) RSK RETURN TO CALLER TITL SAMPLE PROGRAM OPERATION TASK * * OPERATION TASK PERFORMS THE FOLLOWING SEQUENCE OF OPERATIONS: * 1) IF THIS OPERATION TASK ACTIVITY IS TO PERFORM WRITE * OPERATIONS, THEN ENQUEUE SCRATCHPAD (EXTENDED INPUT/OUTPUT * BLOCK) ON THE WRITE COMPLETION QUEUE, AND WAIT FOR A SIGNAL * BEFORE CONTINUING. *  2) PERFORM THE SPECIFIED OPERATION (READ OR WRITE). * 3) ENQUEUE SCRATCHPAD ON THE APPROPRIATE COMPLETION QUEUE AND *  WAIT FOR A SIGNAL BEFORE CONTINUING. * 4) IF TERMINATION FLAG IS NOT SET, REPEAT BEGINNING AT STEP 2. * ERRORS ARE NOT PROCESSED BY THE OPERATION TASK. * * START-UP PARAMETERS: * A - FUNCTION CODE FOR OPERATION TO BE PERFORMED *  Q - LOGICAL UNIT NAME * X - SHARED INFORMATION ADDRESS: * WORD 0: HEAD POINTER FOR COMPLETION QUEUE *  WORD 1: TAIL POINTER FOR COMPLETION QUEUE * WORD 2: COUNT OF OPERATION ACTIVITIES RUNNING * WORD 3: ADDRESS OF SEMAPHORE TO BE SIGNALLED FOR QUEUE * Y - ADDRESS OF SCRATCHPAD (EXTENDED INPUT/OUTPUT BLOCK) ALLOCATED * FOR THIS ACTIVITY * OPERSTRT EQU $ COPY A,EIOFC(Y) SAVE FUNCTION CODE WORD COPY Q,EIOLUN(Y) SAVE LOGICAL UNIT NAME COPY X,EIOSHR(Y) SAVE ADDRESS OF SHARED INFORMATION COPY =0,Q COPY Q,EIONXT(Y) INITIALIZE NEXT LINKAGE COPY Q,EIOSEM(Y) INITIALIZE ACTIVITY SEMAPHORE COPY Q,EIOTRM(Y) INITIALIZE TERMINATION FLAG WORD COPY Q,EIOUNA(Y) INITIALIZE UNUSED WORDS OF IOB COPY Q,EIOUNB(Y) COPY =NUMPASS-1&:FF+1,Q SET MAXIMUM BUFFER LENGTH COPY Q,EIOBCT(Y) COPY Y,Q SET ADDRESS OF BUFFER ADD =EIODATA,Q COPY Q,EIOBUF(Y) IMS 2(X) COUNT ACTIVITY PRESENT SHIFT A,RO,4 GET BASIC FUNCTION CODE FOR OPERATION CLSN A,=RE: CHECK FOR READ OPERATION JMP OP01 DIRECTLY INTO LOOP IF SO JSK ADDQUEUE ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE R:WAIT EIOSEM(Y) WAIT FOR SIGNAL BEFORE CONTINUING OP01 EQU $ PERFORM SPECIFIED OPERATION I:IO EIOLUN(Y) EXECUTE THE READ OR WRITE OPERATION NOP IGNORE ABNORMAL RETURN FROM CALL JSK ADDQUEUE ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE R:WAIT EIOSEM(Y) WAIT FOR SIGNAL BEFORE CONTINUING COPY EIOTRM(Y),A TERMINATION FLAG JEQ A,OP01 LOOP UNTIL TERMINATION REQUESTED COPY EIOSHR(Y),X BASE ADDRESS OF SHARED INFORMATION COPY 2(X),A DECREMENT COUNT OF OPERATION ACTIVITIES RUNNING SUB =1,A COPY A,2(X) R:END TERMINATE ACTIVITY  TITL ADDQUEUE - ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE * * ADDQUEUE * * PROCEDURE ADDS THE ACTIVITY'S SCRATCHPAD AREA BLOCK TO THE * LINKED LIST ON THE COMPLETION QUEUE IN THE SHARED INFORMATION * AREA, AND SIGNALS THE TEST ACTIVITY IF THE QUEUE WAS PREVIOUSLY * EMPTY. * * CALL PARAMETERS: * NONE * * RETURN PARAMETERS: * A,Q,X - DESTROYED * ADDQUEUE EQU $ COPY =0,A SET NULL LINKAGE FROM THIS SCRATCHPAD BLOCK COPY A,EIONXT(Y) COPY EIOSHR(Y),X ADDRESS OF SHARED INFORMATION AREA COPY 0(X),A ADDRESS OF FIRST BLOCK ON QUEUE JNE A,AQ01 JUMP UNLESS QUEUE WAS EMPTY COPY Y,0(X) SET THIS SCRATCHPAD AS HEAD AND TAIL COPY Y,1(X) COPY 3(X),X LOAD ADDRESS OF SEMAPHORE TO BE SIGNALLED R:SIG 0(X) SIGNAL TEST ACTIVITY FOR INITIAL ADDITION TO QUEUE RSK RETURN TO CALLER AQ01 EQU $ ADDING TO NON-EMPTY QUEUE COPY 1(X),X ADDRESS OF FORME R LAST BLOCK ON QUEUE COPY Y,EIONXT(X) SET LINKAGE TO THIS BLOCK COPY EIOSHR(Y),X ADDRESS OF SHARED INFORMATION AREA COPY Y,1(X) SET THIS SCRATCHPAD BLOCK AS NEW LAST RSK RETURN TO CALLER END D D D D D D D D D D D D D D D D D D D D D D D D D IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII TITL SYNCHRONOUS COMMUNICATIONS HANDLER SAMPLE PROGRAM (93438-95/A030) TITL INPUT/OUTPUT CONTROL BLOCK DEFINITIONS * * TABLES ARE SET UP FOR 9600 BITS PER SECOND OPERATION OF THE * SYNCHRONOUS COMMUNICATIONS CONTROLLER, WITH THE STANDARD DEVICE * ADDRESS OF :D. PROTOCOL OPERATION IS ASYNCHRONOUS BALANCED MODE * WITH EXTENDED SEQUENCE NUMBERING (NORMAL NUMBERING IS ALSO * ENABLED, BUT EXTENDED IS THE PREFERRED MODE AND WILL BE USED IN * THIS CASE). * CIB:SC SC00,:68,0,96,C:SC1,DL,MA,PP,TS,BP=:7A00,ML=1 DIB:SC SC00,COM,SA=1,DA=2,BT=25 CIB:SC SC10,:68,1,96,C:SC0,DL,MA,PP,TS,BP=:7A00,ML=1 DIB:SC SC10,COM,SA=2,DA=1,BT=25 PIB:SC COM,AC,EN,NN,RI=20,PI=40,IR=4,CR=4 * * THIS HAS BEEN EDITED TO ELIMINATE THE LISTING OF CODE GENERATED * BY THE ABOVE MACRO CALLS, IN ORDER TO CONSERVE SPACE USED IN THE * MANUAL. * END D D D D D D D D D D D D D D D D D IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII TITL SYNCHRONOUS COMMUNICATIONS HANDLER SAMPLE PROGRAM (93438-1A/A030) * * SAMPLE PROGRAM TO DEMONSTRATE THE USAGE OF THE IOS4 INTERFACE FOR * FULL DUPLEX, MULTIPLY-BUFFERED OPERATION. THREE DIFFERENT TASKS * ARE INCLUDED IN THIS PROGRAM: * * 1) INITIALIZATION TASK - * STARTS TWO ACTIVITIES OF THE TEST TASK. * 2) TEST TASK - * PERFORMS A SEQUENCE OF FULL DUPLEX READS AND WRITES, USING * ACTIVITIES OF THE OPERATION TASK TO ACTUALLY PERFORM THE I/O *  OPERATIONS. RECEIVED DATA IS VERIFIED AND SOFTWARE STATUS * VALUES RETURNED FOR BOTH READ AND WRITE OPERATIONS CHECKED. * 3) OPERATION TASK - * PERFORMS ACTUAL I/O OPERATIONS. * * THE PROGRAM IS SET UP TO RUN WITH SYNCHRONOUS COMMUNICATIONS * CONTROLLER CHANNELS A AND B CONNECTED BACK-TO-BACK, USING A NULL * MODEM CABLE. THE CABLE NECESSARY FOR BACK-TO-BACK CONNECTION IS * DESCRIBED IN THE SYNCHRONOUS COMMUNICATIONS CONTROLLER MANUAL, OR * CAN BE ORDERED FROM COMPUTER AUTOMATION (FOR RS-232 BOARD, 53870, * USE 81-21550-01, PRODUCT NUMBER 63-21550-01; FOR RS-449 BOARD, * 53874, USE 81-21553-01, PRODUCT NUMBER 63-21553-01). * * THE CONSOLE DATA REGISTER DISPLAYS THE NUMBER OF THE MOST-RECENTLY * RECEIVED BLOCK OF DATA DURING EXECUTION OF THE SAMPLE PROGRAM. THE * NUMBER OF BLOCKS TRANSMITTED IN AN EXECUTION IS DETERMINED BY AN * ASSEMBLY PARAMETER (NUMPASS). THE NUMBER OF BYTES IN EACH BLOCK OF * DATA, AND THE DATA PATTERN USED FOR THE BLOCK, ARE BOTH EQUAL TO * THE NUMBER OF THE BLOCK, MOD 256 (EXCEPT FOR MULTIPLES OF 256, WHEN * A LENGTH OF 256 IS USED). ALL ERRORS EXIT DIRECTLY TO DEBUG. * LOAD DEBUG4 EXTR D:SC00,D:SC10 TASK REL SHARABLE TASK G:0 NAM G:0 SPACE 2 * *   OPERATIONAL PARAMETER EQUATES * NUMPASS EQU :200 NUMBER OF FRAMES TO BE TRANSFERRED MAXBUFF EQU NUMPASS-1&:FF+1/2 MAXIMUM WORDS IN BLOCK OF DATA NUMOPER EQU 2 NUMBER OF OPERATION ACTIVITIES TO BE USED TITL TEST TASK SCRATCHPAD DEFINITIONS * * TEST TASK SCRATCHPAD * * TEST TASK SCRATCHPAD AREA USED TO KEEP TRACK OF THE STATUS OF * THE TEST SEQUENCE CONSISTS OF: *  1) INTERNAL CONTROL INFORMATION FOR THE TEST PROGRAM ACTIVITY. * 2) SHARED DATA AREAS FOR THE READ AND WRITE OPERATION ACTIVITIES * (HEAD AND TAIL POINTERS FOR LINKED LISTS OF COMPLETED * OPERATIONS, COUNTS OF ACTIVITIES OF EACH TYPE RUNNING, AND * THE ADDRESS OF THE SEMAPHORE TO BE SIGNALLED WHEN AN * OPERATION IS COMPLETED) *  3) ONE-WORD SEMAPHORE WHICH THE TEST PROGRAM ACTIVITY WAITS ON * WHEN NOT PROCESSING A COMPLETED OPERATION. *  4) STANDARD IOS4 INPUT/OUTPUT BLOCK. * THE TEST TASK SCRATCHPAD IS ALLOCATED AT THE TIME A TEST TASK * ACTIVITY IS STARTED. * TPSCWN EQU 0 CURRENT WRITE OPERATION NUMBER TPSCRN EQU TPSCWN+1 CURRENT READ OPERATION NUMBER TPSNUM EQU TPSCRN+1 ACTIVITY LOOP COUNTER TPSCNT EQU TPSNUM+1 BUFFER LOOP COUNTER TPSBUF EQU TPSCNT+1 POINTER FOR BUFFER OPERATIONS TPSWCH EQU TPSBUF+1 COMPLETED WRITE OPERATION QUEUE TPSWCT EQU TPSWCH+1 COMPLETED WRITE OPERATION QUEUE TAIL TPSNWA EQU TPSWCT+1 NUMBER OF WRITE OPERATION ACTIVITIES TPSWSA EQU TPSNWA+1 WRITE COMPLETION SEMAPHORE ADDRESS TPSRCH EQU TPSWSA+1 COMPLETED READ OPERATION QUEUE HEAD TPSRCT EQU TPSRCH+1 COMPLETED READ OPERATION QUEUE TAIL TPSNRA EQU TPSRCT+1 NUMBER OF READ OPERATION ACTIVITIES TPSRSA EQU TPSNRA+1 READ COMPLETION SEMAPHORE ADDRESS TPSSEM EQU TPSRSA+1 SEMAPHORE WORD FOR ACTIVITY TPSLUN EQU TPSSEM+1 LOGICAL UNIT NAME FOR INPUT/OUTPUT BLOCK TPSUNA EQU TPSLUN+1 FIRST UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUNB EQU TPSUNA+1 SECOND UNUSED WORD IN INPUT/OUTPUT BLOCK TPSFC EQU TPSUNB+1 FUNCTION CODE FOR INPUT/OUTPUT BLOCK TPSUNC EQU TPSFC+1 THIRD UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUND EQU TPSUNC+1 FOURTH UNUSED WORD IN INPUT/OUTPUT BLOCK TPSUNE EQU TPSUND+1 FIFTH UNUSED WORD IN INPUT/OUTPUT BLOCK TPSST EQU TPSUNE+1 SOFTWARE STATUS RETURNED FOR INPUT/OUTPUT BLOCK SIZETSP EQU TPSST+1 SIZE OF TEST PROGRAM SCRATCHPAD AREA TITL OPERATION TASK SCRATCHPAD DEFINITIONS * * EXTENDED INPUT/OUTPUT BLOCK * * EXTENDED INPUT/OUTPUT BLOCKS USED BY THE PROGRAM FOR READ AND * WRITE OPERATIONS CONSIST OF: * 1) LINKAGE WORD FOR USE WHEN THE OPERATION IS COMPLETED AND *  THE ACTIVITY PERFORMING THE OPERATION ADDS IT TO THE LIST * OF COMPLETED READ OR WRITE OPERATIONS. * 2) ONE-WORD SEMAPHORE WHICH THE ACTIVITY PERFORMING THE * OPERATION WAITS ON WHEN THE OPERATION IS COMPLETED. * 3) INTERNAL CONTROL INFORMATION FOR THE ACTIVITY PERFORMING THE * OPERATION. * 4) STANDARD IOS4 INPUT/OUTPUT BLOCK. * 5) BUFFER AREA FOR THE READ OR WRITE OPERATION. * THE EXTENDED INPUT/OUTPUT BLOCK IS ALLOCATED AT THE TIME THE *  CORRESPONDING OPERATION ACTIVITY IS STARTED, AS A SCRATCHPAD AREA. * EIONXT EQU 0 NEXT POINTER FOR COMPLETED LIST EIOSEM EQU EIONXT+1 SEMAPHORE WORD FOR ACTIVITY EIOTRM EQU EIOSEM+1 TERMINATION FLAG WORD EIOSHR EQU EIOTRM+1 ADDRESS OF SHARED INFORMATION  AREA EIOLUN EQU EIOSHR+1 LOGICAL UNIT NAME FOR IOB EIOUNA EQU EIOLUN+1 FIRST UNUSED INPUT/OUTPUT BLOCK WORD EIOUNB EQU EIOUNA+1 SECOND UNUSED INPUT/OUTPUT BLOCK WORD EIOFC EQU EIOUNB+1 FUNCTION CODE FOR INPUT/OUTPUT BLOCK EIOBCT EQU EIOFC+1 INPUT/OUTPUT BLOCK REQUESTED COUNT EIOBUF EQU EIOBCT+1 INPUT/OUTPUT BLOCK BUFFER ADDRESS EIOACT EQU EIOBUF+1 ACTUAL COUNT FOR INPUT/OUTPUT BLOCK EIOST EQU EIOACT+1 SOFTWARE STATUS RETURNED FOR INPUT/OUTPUT BLOCK EIODATA EQU EIOST+1 READ/WRITE BUFFER AREA SIZEEIO EQU EIODATA+MAXBUFF SIZE OF EXTENDED INPUT/OUTPUT BLOCK TITL SYSTEM SERVICE PARAMETER BLOCKS AND TABLES * * INITIALIZATION BLOCK DEFINITION * INIT:A 0,0,0,0,ECB,TDBI,:2000,1024 * * INITIALIZATION TASK DEFINITION BLOCK * TDB:A TDBI,INIT,0,0,:20 * * TEST TASK DEFINITION BLOCK * TDB:A TDBT,TESTSTRT,SIZETSP,0,:50,0,16 * * TEST TASK ACTIVITY BEGIN BLOCK * BGIN:A BEGINTST,TDBT,:2000 * * OPERATION TASK DEFINITION BLOCK * TDB:A TDBO,OPERSTRT,SIZEEIO,0,:50,0,16 * * OPERATION TASK BEGIN BLOCK * BGIN:A BEGINOPR,TDBO,:2100 * * UNIT ASSIGNMENT TABLE DEFINITION * UAT:AA UAT UAT:EE 'L0',D:SC00 SYNCHRONOUS CONTROLLER LINE ZERO UAT:EE 'L1',D:SC10 SYNCHRONOUS CONTROLLER LINE ONE UAT:ZZ * * ENVIRONMENT CONTROL BLOCK DEFINITION * ECB:A ECB,UAT TITL SAMPLE PROGRAM INITIALIZATION TASK * * INITIALIZATION TASK STARTS TWO ACTIVITIES OF THE TEST TASK, ONE * FOR EACH OF THE TWO SYNCHRONOUS COMMUNICATIONS CONTROLLER CHANNELS. * THE INITIALIZATION TASK TERMINATES AFTER THE TWO TEST TASK * ACTIVITIES HAVE BEEN STARTED. * INIT EQU $ COPY ='L0',A SET LOGICAL UNIT NAME R:BGIN BEGINTST START FIRST ACTIVITY OF TEST TASK COPY ='L1',A SET LOGICAL UNIT NAME R:BGIN BEGINTST START SECOND ACTIVITY OF TEST TASK R:END TERMINATE INITIALIZATION TASK * LPOOL TITL SAMPLE PROGRAM TEST TASK * * TEST TASK PERFORMS THE FOLLOWING SEQUENCE OF OPERATIONS: * 1)  START THE REQUIRED NUMBER OF OPERATION TASK ACTIVITIES (AS * SPECIFIED BY THE NUMOPER EQUATE) FOR RECEIVE AND TRANSMIT * OPERATIONS. * 2) OPEN THE COMMUNICATIONS LINE PROTOCOL LINK. * 3) GENERATE DATA FOR TRANSMIT (WRITE) OPERATIONS, AND CHECK DATA * FROM RECEIVE (READ) OPERATIONS, USING THE OPERATION ACTIVITIES * TO PERFORM THE ACTUAL I/O OPERATIONS. * 4) TERMINATE THE OPERATION TASK ACTIVITIES. * 5) CLOSE THE COMMUNICATIONS LINE PROTOCOL LINK. * IF ERRORS ARE FOUND AT ANY POINT IN THE SEQUENCE, AN EXIT DIRECT TO * DEBUG IS TAKEN. * * START-UP PARAMETERS: *  A - LOGICAL UNIT NAME TO BE USED BY TEST TASK ACTIVITY * Y - ADDRESS OF SCRATCHPAD ALLOCATED FOR THIS ACTIVITY * TESTSTRT EQU $ JSK INITTEST INITIALIZE SCRATCHPAD AREA COPY =FU:%4+OP:,A SET OPERATION CODE FOR OPEN FUNCTION COPY A,TPSFC(Y) I:IO TPSLUN(Y) PERFORM THE OPEN OPERATION JST *0 ABNORMAL RETURN ENTERS DEBUG COPY TPSST(Y),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 JSK STRTOPER START THE OPERATION TASK ACTIVITIES COPY TPSNWA(Y),A NUMBER OF WRITE OPERATION ACTIVITIES NEG A SET NEGATIVE OF VALUE AS LOOP COUNT COPY A,TPSNUM(Y) TS01 EQU $ INITIALIZE WRITE OPERATION ACTIVITIES COPY Y,A SET ADDRESS OF WRITE COMPLETION QUEUE ADD =TPSWCH,A JSK REMQUEUE GET FIRST BL OCK FROM QUEUE COPY A,X SET UP INDEX REGISTER WITH ADDRESS JSK SETWRITE SET UP FOR WRITE OPERATION R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO DO IT IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP TS01 LOOP FOR ALL WRITE OPERATION ACTIVITIES TS02 EQU $ CHECK FOR WRITE OPERATION COMPLETIONS COPY Y,A SET ADDRESS OF WRITE COMPLETION QUEUE ADD =TPSWCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE JEQ A,TS05 JUMP IF QUEUE WAS EMPTY COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX COPY EIOST(X),A SOFTWARE STATUS RETURNED BY OPERATION CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 COPY TPSCWN(Y),A CURRENT WRITE OPERATION NUMBER SUB MAXPASS,A COMPARE WITH NUMBER TO BE DONE JNE A,TS03 JUMP UNLESS ALL OPERATIONS COMPLETED COPY =-1,A SET FLAG FOR TERMINATION REQUIRED COPY A,EIOTRM(X) JMP TS04 GO TO SIGNAL OPERATION ACTIVITY TS03 EQU $ CONTINUE WITH NEXT WRITE OPERATION JSK SETWRITE SET UP FOR NEXT WRITE OPERATION TS04 EQU $ SIGNAL OPERATION ACTIVITY R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME JMP TS02 LOOP TO CHECK IF MORE ON QUEUE TS05 EQU $ CHECK FOR READ OPERATION COMPLETIONS COPY Y,A SET ADDRESS OF READ COMPLETION QUEUE ADD =TPSRCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE JEQ A,TS06 JUMP IF QUEUE WAS EMPTY COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX JSK VALREAD VALIDATE COMPLETION OF READ OPERATION R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME JMP TS05 LOOP TO CHECK IF MORE ON QUEUE TS06 EQU $ OUTPUT READ OPERATION NUMBER IF DISPLAYED COPY TPSLUN(Y),A LOGICAL UNIT NAME SST 0 CHECK SENSE SWITCH SETTING XOR =1,A REVERSE SETTING OF LOW-ORDER BIT TBIT 0,A CHECK IF THIS LINE SELECTED FOR DISPLAY COPY TPSCRN(Y),A CURRENT READ OPERATION NUMBER JF OV,$+2 JUMP IF PAIRED LINE SELECTED SELP A,4 OUTPUT RECEIVE PASS NUMBER TO DATA REGISTER SUB MAXPASS,A CHECK FOR ALL READS COMPLETED JNE A,$+3 JUMP IF MORE READS TO BE DONE COPY TPSNWA(Y),A NUMBER OF WRITE OPERATION ACTIVITIES JEQ A,TS07 OUT OF LOOP IF WRITE OPERATIONS COMPLETED R:WAIT TPSSEM(Y) WAIT FOR A SIGNAL BEFORE RESUMING JMP TS02 LOOP TO CHECK COMPLETIONS TS07 EQU $ CLOSE LINK WHEN TESTING COMPLETED COPY =FU:%4+CL:,A SET OPERATION CODE FOR CLOSE FUNCTION COPY A,TPSFC(Y) I:IO TPSLUN(Y) PERFORM THE CLOSE OPERATION JST *0 ABNORMAL RETURN ENTERS DEBUG COPY TPSST(Y),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 TS08 EQU $ CHECK READS AND SIGNAL TO TERMINATE COPY Y,A SET ADDRESS OF READ COMPLETION QUEUE ADD =TPSRCH,A JSK REMQUEUE GET FIRST BLOCK FROM QUEUE COPY A,X OPERATION ACTIVITY SCRATCH BASE TO INDEX COPY EIOST(X),A SOFTWARE STATUS RETURNED BY OPERATION CSK A,=NORDY: CHECK FOR NOT READY TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 COPY =-1,A SET FLAG FOR TERMINATION REQUIRED COPY A,EIOTRM(X) R:SIG EIOSEM(X) SIGNAL OPERATION ACTIVITY TO RESUME COPY TPSNRA(Y),A NUMBER OF READ OPERATION ACTIVITIES RUNNING JNE A,TS08 LOOP UNLESS ALL TERMINATED R:END TERMINATE TEST TASK ACTIVITY * MAXPASS WORD NUMPASS MAXIMUM DATA BLOCK NUMBER TITL INITTEST - INITIALIZE TEST ACTIVITY SCRATCHPAD * * INITTEST * * PROCEDURE INITIALIZES THE SCRATCHPAD AREA FOR A NEW TEST TASK * ACTIVITY. * * CALL PARAMETERS: * A - LO GICAL UNIT NAME TO BE USED BY TEST TASK ACTIVITY * * RETURN PARAMETERS: * A - DESTROYED * Q,X - UNCHANGED * INITTEST EQU $ COPY A,TPSLUN(Y) SAVE LOGICAL UNIT NAME FOR I/O COPY =0,A COPY A,TPSCWN(Y) INITIALIZE WRITE OPERATION NUMBER COPY A,TPSCRN(Y) INITIALIZE READ OPERATION NUMBER COPY A,TPSWCH(Y) INITIALIZE WRITE OPERATION QUEUE COPY A,TPSWCT(Y) COPY A,TPSNWA(Y) INITIALIZE NUMBER OF WRITE ACTIVITIES COPY A,TPSRCH(Y) INITIALIZE READ OPERATION QUEUE COPY A,TPSRCT(Y) COPY A,TPSNRA(Y) INITIALIZE NUMBER OF READ ACTIVITIES COPY A,TPSSEM(Y) INITIALIZE ACTIVITY SEMAPHORE WORD COPY A,TPSUNA(Y) INITIALIZE UNUSED WORDS OF IOB COPY A,TPSUNB(Y) COPY A,TPSUNC(Y) COPY A,TPSUND(Y) COPY A,TPSUNE(Y) COPY Y,A SET ADDRESS OF SEMAPHORE FOR COMPLETIONS ADD =TPSSEM,A COPY A,TPSWSA(Y) COPY A,TPSRSA(Y) RSK RETURN TO CALLER TITL STRTOPER - START OPERATION TASK ACTIVITIES * * STRTOPER * * PROCEDURE STARTS THE SPECIFIED NUMBER (NUMOPER EQUATE VALUE) OF * OPERATION TASK ACTIVITIES RUNNING FOR RECEIVE AND TRANSMIT * * CALL PARAMETERS: * NONE * * RETURN PARAMETERS: * A,Q,X - DESTROYED * STRTOPER EQU $ COPY =-NUMOPER,A SET UP LOOP CONTROL FOR READ ACTIVITIES COPY A,TPSNUM(Y) COPY =RE:%4+UF:,A SET OPERATION CODE FOR READS COPY TPSLUN(Y),Q SET LOGICAL UNIT NAME COPY Y,X SET ADDRESS OF SHARED READ ACTIVITY INFORMATION ADD =TPSRCH,X SO01 EQU $ LOOP FOR STARTING READ OPERATION ACTIVITIES R:BGIN BEGINOPR START AN OPERATION TASK ACTIVITY IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP SO01 LOOP FOR SPECIFIED NUMBER OF ACTIVITIES COPY =-NUMOPER,A SET UP LOOP CONTROL FOR WRITE ACTIVITIES COPY A,TPSNUM(Y) COPY =WR:%4+UF:,A SET OPERATION CODE FOR WRITES COPY Y,X SET ADDRESS OF SHARED WRITE ACTIVITY INFORMATION ADD =TPSWCH,X SO02 EQU $ LOOP FOR STARTING WRITE OPERATION ACTIVITIES R:BGIN BEGINOPR START AN OPERATION TASK ACTIVITY IMS TPSNUM(Y) INCREMENT LOOP CONTROL COUNTER JMP SO02 LOOP FOR SPECIFIED NUMBER OF ACTIVITES RSK RETURN TO CALLER TITL REMQUEUE - REMOVE FIRST BLOCK FROM QUEUE * * REMQUEUE * * PROCEDURE REMOVES THE FIRST OPERATION TASK ACTIVITY SCRATCHPAD * BLOCK FROM A COMPLETION QUEUE. * * CALL PARAMETERS: * A - ADDRESS OF HEAD POINTER FOR COMPLETION QUEUE * *  RETURN PARAMETERS: * A - ZERO IF QUEUE EMPTY, ADDRESS OF OPERATION TASK ACTIVITY * SCRATCHPAD OTHERWISE *  Q,X - DESTROYED * REMQUEUE EQU $ COPY A,X COPY ADDRESS OF QUEUE HEAD POINTER SIN 6 PROTECT FROM INTERRUPTION BY OPERATION ACTIVITIES COPY 0(X),X ADDRESS OF FIRST BLOCK ON QUEUE JEQ X,RQ01 JUMP IF QUEUE ALREADY EMPTY COPY EIONXT(X),Q GET ADDRESS OF NEXT ON QUEUE EXCH A,X SWAP BLOCK ADDRESS AND HEAD POINTER ADDRESS COPY Q,0(X) SET NEW HEAD OF QUEUE JNE Q,$+2 JUMP UNLESS QUEUE NOW EMPTY COPY Q,1(X) SET NULL TAIL POINTER FOR QUEUE RSK RETURN WITH ADDRESS OF BLOCK REMOVED RQ01 EQU $ QUEUE ALREADY EMPTY COPY =0,A SET NULL ADDRESS FOR BLOCK REMOVED RSK TITL SETWRITE - SET UP FOR NEXT WRITE OPERATION * * SETWRITE * * PROCEDURE INITIALIZES THE BYTE COUNT AND BUFFER CONTENTS FOR THE * NEXT WRITE OPERATION TO BE PERFORMED. * *  CALL PARAMETERS: * X - ADDRESS OF OPERATION ACTIVITY SCRATCHPAD * * RETURN PARAMETERS: * A,Q - DESTROYED *   X - UNCHANGED * SETWRITE EQU $ IMS TPSCWN(Y) INCREMENT CURRENT WRITE OPERATION NUMBER COPY TPSCWN(Y),A GET NUMBER OF OPERATION AND =:FF,A MASK LOW-ORDER BYTE OF NUMBER COPY A,EIOBCT(X) USE AS BYTE COUNT FOR WRITE JNE A,$+3 JUMP UNLESS ZERO MOD 256 COPY =:100,Q SET MAXIMUM LENGTH WRITE OPERATION COPY Q,EIOBCT(X) COPY A,Q FORM WORD BY DUPLICATING BYTE SHIFT A,LO,8 OR A,Q COPY EIOBUF(X),A BUFFER ADDRESS FOR OPERATION COPY A,TPSBUF(Y) SAVE IN SCRATCHPAD FOR FILLING COPY EIOBCT(X),A BYTE COUNT FOR OPERATION SUB =1,A CORRECT FOR LOOP COUNTER BIAS SHIFT A,RO,1 CONVERT TO WORD LOOP COUNTER SW01 EQU $ STORE A WORD OF DATA IN BUFFER COPY Q,*TPSBUF(Y) STORE WORD INTO BUFFER IMS TPSBUF(Y) INCREMENT FOR NEXT WORD OF BUFFER NOP JNED A,SW01 LOOP FOR ALL WORDS OF BUFFER RSK RETURN WITH OPERATION SET UP TITL VALREAD - VALIDATE READ OPERATION COMPLETION * * VALREAD * * PROCEDURE VALIDATES THE SOFTWARE STATUS AND DATA RETURNED BY A * COMPLETED READ OPERATION. * * CALL PARAMETERS: * X - ADDRESS OF OPERATION ACTIVITY SCRATCHPAD * * RETURN PARAMETERS: * A,Q - DESTROYED * X - UNCHANGED * VALREAD EQU $ COPY TPSCRN(Y),Q NUMBER OF LAST READ AND =:FF,Q TAKE MODULO 256 ADD =1,Q GET COUNT OF BYTES FOR OPERATION IMS TPSCRN(Y) INCREMENT CURRENT READ NUMBER COPY EIOST(X),A SOFTWARE STATUS RETURNED CSK A,=NORML: CHECK FOR NORMAL TERMINATION JST *0 ENTER DEBUG IF ANY OTHER STATUS JST *0 CSK Q,EIOACT(X) CHECK FOR CORRECT READ LENGTH JST *0 ENTER DEBUG IF INCORRECT LENGTH JST *0 COPY EIOBUF(X),A ADDRESS OF BUFFER USED COPY A,TPSBUF(Y) SAVE IN SCRATCHPAD AREA FOR LOOP COPY =0,A INITIALIZE COUNT OF BYTES CHECKED VR01 EQU $ CHECK A WORD OF DATA READ COPY *TPSBUF(Y),Q LOAD WORD FROM BUFFER SHIFT Q,RO,8 POSITION HIGH-ORDER BYTE OF WORD XOR TPSCRN(Y),Q COMPARE WITH CURRENT READ NUMBER AND =:FF,Q CHECKING ONLY ONE BYTE OF VALUE JEQ Q,$+2 JUMP IF CORRECT DATA READ JST *0 ENTER DEBUG IF BAD DATA ADD =1,A INCREMENT COUNT OF BYTES CHECKED COPY EIOACT(X),Q LENGTH OF READ OPERATION CSN A,Q CHECK IF ALL BYTES CHECKED JMP VR02 EXIT LOOP IF DONE XOR *TPSBUF(Y),Q CHECK LENGTH AGAINST DATA  AND =:FF,Q MASK LOW-ORDER BYTE OF DIFFERENCE JEQ Q,$+2 JUMP IF CORRECT DATA READ JST *0 ENTER DEBUG IF BAD DATA IMS TPSBUF(Y) INCREMENT BUFFER POINTER FOR NEXT WORD NOP ADD =1,A INCREMENT COUNT OF BYTES CHECKED CSK A,EIOACT(X) CHECK IF DONE CHECKING DATA JMP VR01 LOOP TO CHECK ANOTHER WORD NOP VR02 EQU $ RESET IOB AND RETURN COPY =0,A RESET ACTUAL COUNT IN IOB COPY A,EIOACT(X) RSK RETURN TO CALLER TITL SAMPLE PROGRAM OPERATION TASK * * OPERATION TASK PERFORMS THE FOLLOWING SEQUENCE OF OPERATIONS: * 1) IF THIS OPERATION TASK ACTIVITY IS TO PERFORM WRITE * OPERATIONS, THEN ENQUEUE SCRATCHPAD (EXTENDED INPUT/OUTPUT * BLOCK) ON THE WRITE COMPLETION QUEUE, AND WAIT FOR A SIGNAL * BEFORE CONTINUING. *  2) PERFORM THE SPECIFIED OPERATION (READ OR WRITE). * 3) ENQUEUE SCRATCHPAD ON THE APPROPRIATE COMPLETION QUEUE AND *  WAIT FOR A SIGNAL BEFORE CONTINUING. * 4) IF TERMINATION FLAG IS NOT SET, REPEAT BEGINNING AT STEP 2. * ERRORS ARE NOT PROCESSED BY THE OPERATION TASK. * * START-UP PARAMETERS: * A - FUNCTION CODE FOR OPERATION TO BE PERFORMED *   Q - LOGICAL UNIT NAME * X - SHARED INFORMATION ADDRESS: * WORD 0: HEAD POINTER FOR COMPLETION QUEUE *  WORD 1: TAIL POINTER FOR COMPLETION QUEUE * WORD 2: COUNT OF OPERATION ACTIVITIES RUNNING * WORD 3: ADDRESS OF SEMAPHORE TO BE SIGNALLED FOR QUEUE * Y - ADDRESS OF SCRATCHPAD (EXTENDED INPUT/OUTPUT BLOCK) ALLOCATED * FOR THIS ACTIVITY * OPERSTRT EQU $ COPY A,EIOFC(Y) SAVE FUNCTION CODE WORD COPY Q,EIOLUN(Y) SAVE LOGICAL UNIT NAME COPY X,EIOSHR(Y) SAVE ADDRESS OF SHARED INFORMATION COPY =0,Q COPY Q,EIONXT(Y) INITIALIZE NEXT LINKAGE COPY Q,EIOSEM(Y) INITIALIZE ACTIVITY SEMAPHORE COPY Q,EIOTRM(Y) INITIALIZE TERMINATION FLAG WORD COPY Q,EIOUNA(Y) INITIALIZE UNUSED WORDS OF IOB COPY Q,EIOUNB(Y) COPY =NUMPASS-1&:FF+1,Q SET MAXIMUM BUFFER LENGTH COPY Q,EIOBCT(Y) COPY Y,Q SET ADDRESS OF BUFFER ADD =EIODATA,Q COPY Q,EIOBUF(Y) IMS 2(X) COUNT ACTIVITY PRESENT SHIFT A,RO,4 GET BASIC FUNCTION CODE FOR OPERATION CLSN A,=RE: CHECK FOR READ OPERATION JMP OP01 DIRECTLY INTO LOOP IF SO JSK ADDQUEUE ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE R:WAIT EIOSEM(Y) WAIT FOR SIGNAL BEFORE CONTINUING OP01 EQU $ PERFORM SPECIFIED OPERATION I:IO EIOLUN(Y) EXECUTE THE READ OR WRITE OPERATION NOP IGNORE ABNORMAL RETURN FROM CALL JSK ADDQUEUE ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE R:WAIT EIOSEM(Y) WAIT FOR SIGNAL BEFORE CONTINUING COPY EIOTRM(Y),A TERMINATION FLAG JEQ A,OP01 LOOP UNTIL TERMINATION REQUESTED COPY EIOSHR(Y),X BASE ADDRESS OF SHARED INFORMATION COPY 2(X),A DECREMENT COUNT OF OPERATION ACTIVITIES RUNNING SUB =1,A COPY A,2(X) R:END TERMINATE ACTIVITY  TITL ADDQUEUE - ADD SCRATCHPAD BLOCK TO COMPLETION QUEUE * * ADDQUEUE * * PROCEDURE ADDS THE ACTIVITY'S SCRATCHPAD AREA BLOCK TO THE * LINKED LIST ON THE COMPLETION QUEUE IN THE SHARED INFORMATION * AREA, AND SIGNALS THE TEST ACTIVITY IF THE QUEUE WAS PREVIOUSLY * EMPTY. * * CALL PARAMETERS: * NONE * * RETURN PARAMETERS: * A,Q,X - DESTROYED * ADDQUEUE EQU $ COPY =0,A SET NULL LINKAGE FROM THIS SCRATCHPAD BLOCK COPY A,EIONXT(Y) COPY EIOSHR(Y),X ADDRESS OF SHARED INFORMATION AREA COPY 0(X),A ADDRESS OF FIRST BLOCK ON QUEUE JNE A,AQ01 JUMP UNLESS QUEUE WAS EMPTY COPY Y,0(X) SET THIS SCRATCHPAD AS HEAD AND TAIL COPY Y,1(X) COPY 3(X),X LOAD ADDRESS OF SEMAPHORE TO BE SIGNALLED R:SIG 0(X) SIGNAL TEST ACTIVITY FOR INITIAL ADDITION TO QUEUE RSK RETURN TO CALLER AQ01 EQU $ ADDING TO NON-EMPTY QUEUE COPY 1(X),X ADDRESS OF FORMER LAST BLOCK ON QUEUE COPY Y,EIONXT(X) SET LINKAGE TO THIS BLOCK COPY EIOSHR(Y),X ADDRESS OF SHARED INFORMATION AREA COPY Y,1(X) SET THIS SCRATCHPAD BLOCK AS NEW LAST RSK RETURN TO CALLER END D D D D D D D D D D D D D D D D D D D D D D D D D IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII! IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII# IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII/e830110155340830110155340830111103724e&L830110155340830110155340830110155340$ e 830110155340830110155340830110155340e830110155340830110155340830110155340830110155340830110155340830110155340e"B)830110162619830110162627830110162704e&"830110162628830110162633830110162709e8!@u830110162634830110162642830110162718 eY% ^830111103705830111103706830111103719 e^830110162654830110162655830110162730 e*R830111103625830111103645830111103703& ' ( ) . SYNC LIBSYNC MACSYNCM MAC SAMPLE ASM SAMPTBL ASMIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII* IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII, IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII- IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII. IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII/ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII0 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII1 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII2 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII3 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII4 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII5 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII6 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII7 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII8 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII9 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII; IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII< IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII= IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII> IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII? IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII@ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIB IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIID IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIE IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIF IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIH IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIK IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIL IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIOS4 MA283011015534040830110155340 830110155340IF43801 VOLSYNCHRONOUS COMMUNICATIONS HANDLER PRODUCT DISKETTE (A030)