IMD 1.16: 2/09/2008 13:07:36 84-93708-02 c2 (f70802) rtx4-scout 1/15/80    @0|)v1uo)  " }jA c MIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIOS4 MD7760301013839D2760301013839 760301013839F70802 VOLRTX4-SCOUT   IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII M@jjggg@ o G`k򞽢_C# b# }B u[ ]e JRiCp@=<; G9P@ G=0 #(1,2,N:::) N2::: SET #(2)-1 DUP #(1),N2::: ENDC * ENDM TITL * EXCHANGE MEMORY TO MEMORY MACRO - EXCH:M * CALLING SEQUENCE * EXCH:M MEM1,MEM2 * * THE CONTENTS OF MEM1 & MEM2 ARE EXCHANGED MACRO EXCH:M EXCH #1,A EXCH A,#2 EXCH  A,#1 ENDM TITL * RETURN WITH A VALUE IN THE A-REGISTER MACRO RET: COPY =#1,A RSK ENDM TITL * COPY MEMORY TO MEMORY, SECOND PARAMETER IS THE REGISTER USED MACRO COPY:M COPY #1,#2 COPY #2,#3 ENDM TITL * THE FOLLOWING SYMBOLS WORK WITH SYMATT * ABSBT: EQU :8000 ABSOLUTE RELBT: EQU :4000 RELATIVE SRLBT: EQU :2000 SCRATCH PAD EXT: EQU :1000 INDBT: EQU :800 INDIRECT LITBT: EQU :400  LITERAL NXBT: EQU :200 POST INDEXED PNXBT: EQU :100 PRE INDEXED UNDBT: SET :80 UNDEFINED NULL: EQU :40 NULL SYMER: EQU :20 AN ERROR OCC TITL * SR: -- SYSTEM REQUEST TO DOOR * * SR * SR FIELD * SR M4D12 * * WHERE FIELD IS A DIRECT OR INDIRECT REFERENCE TO * ANY LOCATION IN MEMORY. M4D12F IS ANY VALID M4D12 * ADDRESS EXPRESSION. * SR: MACRO R:DBUG MACENT :8000 R:SIG MACENT 1 R:WAIT MACENT 2 R:BGIN MACENT 3 R:END MACENT 4+:8000 R:SPRI MACENT 5 R:GPRI MACENT 6+:8000 I:IO MACENT 7 R:CINT MACENT 8+:8000 R:SEND MACENT 9 R:RECV  MACENT 10 R:ITIC MACENT 11 R:PAUS MACENT 12 R:ABUF MACENT 13 R:RBUF MACENT 14 R:STOD MACENT 15+:8000 R:GTOD MACENT 16+:8000 R:AWAL MACENT 17 R:IWAL MACENT 18 R:CTIC MACENT 19 R:MTIC MACENT 20 R:CWAL MACENT 21 F:CREA MACENT 22 F:DELE MACENT 23 F:CONN MACENT 24 F:MONT MACENT 25 F:CFNO MACENT 26 R:GATD MACENT 27 R:SATD MACENT 28 F:DMNT MACENT 29 STVAL: SET #(0)&:FF TWOOP: SET 1 IFT #(0)&:8000 TWOOP: SET 0 ENDC ADMOD: SET 1 IFF #?=0 ADMOD: SET  0 S: SYMATT #(1) IFF NXBT:;PNXBT:&S: ADMOD: SET 1 IFT #(1,'*')=1 ADMOD: SET 2 ENDC  ENDC ENDC WORD ADMOD:%13;:1A00;STVAL: IFT TWOOP: IFF ADMOD: M4D12 #(1) ENDC  IFT ADMOD: WORD #(1) ENDC ENDC IFF TWOOP: WORD 0 ENDC IFF TWOOP:=#(?) NOTE E,'WRONG NUMBER OF OPERANDS' ENDC ENDM TITL * CONSOLE DEVICE ADDRESS AND FUNCTION CODES * CONDA: EQU 0%3  CONSOLE DEVICE ADDRESS. CSSFC: EQU 0 CONSOLE SENSE SWITCH FUNCTION CODE. CIRFC: EQU 1 CONSOLE INTERRUPT RESET FUNCTION CODE. CDR: EQU 4 CONSOLE DATA REGISTER FUNCTION CODE * * DIO INTERUPT VECTOR EQUATES * IV:AIO EQU 0 AUTO I/O IV:CNT EQU 1 BYTE COUNT IV:BUF EQU 2 BUFFER ADDR IV:JSK EQU 4  JSK $+1 IV:EOB EQU 5 EOB ADDR * * NON-PRINTING ASCII CHARACTER VALUES * PARTY: EQU 0  BIT 7 OFF NU: SET :0;PARTY: NULL LF: SET :A;PARTY: LINE FEED FF: SET :C;PARTY: FORM FEED CR: SET :D;PARTY: CARRIAGE RETURN RO: SET :7F;PARTY: RUBOUT TITL * FIXED MEMORY ADDRESS ASSIGNMENTS * PUPA: EQU :80  POWER UP ADDRESS UITA: EQU :84 UNIMPLEMENTED INSTRUCTION TRAP ADDRESS UMTA: EQU :88 UNINSTALLED MEMORY TRAP ADDRESS PFTA: EQU :8C POWER FAILURE TRAP ADDRESS EACA: EQU :90 EFFECTIVE ADDRESS CALCULATION ADDRESS RTCNC: EQU :91 REAL TIME CLOCK INCREMENT ADDRESS RTCIA: EQU :92 READ TIME CLOCK INTERRUPT ADDRESS CONIA: EQU :94 CONSOLE INTERRUPT ADDRESS CNTA: EQU :98 CHARACTER/NUMERIC EXCEPTION TRAP ADDRESS SOTA: EQU :9C  STACK OVERFLOW TRAP ADDRESS SETA: EQU :9C STACK EXCEPTION TRAP ADDRESS USTA: EQU :A0 USER TRAP ADDRESS SYTA: EQU :A4 SYSTEM TRAP ADDRESS AETA: EQU :A8 ARITHMETIC EXCEPTION TRAP ADDRESS SPACE 3 SAVE END  CONSOLE DEVICE ADDRESS. CSSFC: EQU 0 CONSOLE SENSE SWITCH FUNCTION CODE. CIRFC: EQU 1 CONSOLE INTERRUPT RESET FUNCTION CODE. CDR: EQU 4 CONSOLE DATA REGISTER FUNCTION CODE * * DIO INTERUPT VECTOR EQUATES * IV:AIO EQU 0 AUTO I/O IV:CNT EQU 1 BYTE COUNT IV:BUF EQU 2 BUFFER ADDR IV:JSK EQU 4 TITL R T X . M A C - RTX GENERAL EQUATES & MACROS (93420-11-C1) * INIT:A AR,QR,XR,YR,ECB,TDB,PRI * INIT:A AR,QR,XR,YR,ECB,TDB,PRI,AMTFREE * INIT:A AR,QR,XR,YR,ECB,TDB,PRI,AMTFREE,ADRFREE * INIT:A AR,QR,XR,YR,ECB,TDB,PRI,AMTFREE,ADRFREE,ADRERROR * INIT:A AR,QR,XR,YR,ECB,TDB,PRI,,,ADRERROR * INIT:A AR,QR,XR,YR,ECB,TDB,PRI,AMTFREE,,ADRERROR * *  AR INITIAL CONTENTS OF A REGISTER. * QR INITIAL CONTENTS OF Q REGISTER. * XR INITIAL CONTENTS OF X REGISTER. * YR INITIAL CONTENTS OF Y REGISTER. * ECB ADDRESS OF ENVIRONMENT CONTROL BLOCK. * TDB ADDRESS OF TASK DESCRIPTOR BLOCLK. * PRI PRIORITY OF ACTIVITY OF TASK. * AMTFREE AMOUNT OF FREEPOOL SPACE (WORDS) * ADRFREE ADDRESS OF FREEPOOL. * ADRERROR ADDRESS OF ERROR ROUTINE * BLKSZ: EQU 12 MACRO INIT:A LOAD RTX: LOAD R:LOW R:INIT WORD #1,#2,#3,#4,#5,#6,#7&:7FFF WORD IN:CHK S: SET 0 SV: SYMATT #8 IFF NULL:&SV: SV: SYMATT #9 IFF NULL:&SV: WORD #8 WORD #9 ENDC IFT NULL:&SV: S: SET #8 ENDC ENDC SV: SYMATT #8 IFT NULL:&SV: S: SET 2*BLKSZ: ENDC IFT S: WORD S: WORD $+2 ENDC SV: SYMATT #10  IFF NULL:&SV: WORD #10 ENDC IFT NULL:&SV: WORD 0 ENDC IFT S: RES S:,:8080  ENDC ENDM TITL * SINGL: START,STACK * SINGL: START,STACK,FLAGS * * START START ADDRESS OF TASK * STACK AMOUNT OF STACK SPASE REQUIRED * FLAGS NONXA: - BEGIN WITHOUT EXTENDED ADDRESSI NG * BM:V - BEGIN WITH BYTE MODE * OV:V - BEGIN WITH OVERFLOW SET *  CY:V - BEGIN WITH CARRY SET * MACRO SINGL: EXTR R:ECB1 INIT:A 0,0,0,0,R:ECB1,R:TSK1,100,4*BLKSZ: TDB:A R:TSK1,#1,0,R:STK1,#2,#3 R:STK1 RES #2,0 LOAD UAT:S ENDM TITL * TDB:A LABEL,START,YSCRATCH,STACKAD,STACKAMT * TDB:A LABEL,START,YSCRATCH,STACKAD,STACKAMT,FLAGS * TDB:A LABEL,START,YSCRATCH,STACKAD,STACKAMT,FLAGS,USAGE * TDB:A LABEL,START,YSCRATCH,STACKAD,STACKAMT,FLAGS,USAGE,SEMA4 * * LABEL LABEL TO BE ASSIGNED TO START OF TDB. * START START ADDRESS OF TASK. * YSCRATCH AMOUNT OF Y-SCRATCHPAD USED BY TASK. * STACKAD ADDRESS OF PREALLOCATED STACK, OR ZERO. * STACKAMT AMOUNT OF STACK SPACE USED BY TASK. * FLAGS OPTIONAL FLAGS. * BM:V =BM: ON IN INITIAL STATUS * OV:V  =OV: ON IN INITIAL CONTEXT * CY:V =CY: ON IN INITIAL STATUS * USAGE NUMBER OF CONCURRENT ACTIVITIES OF THIS TASK. * SEMA4 OPTIONAL ADDRESS OF CONCURRENCY SEMAPHORE. * (WHICH MUST BE SET TO 1 OR USAGE BY USER) * MACRO TDB:A #1 CHAN R:TDBL TD:PER S: SET 0 SV: SYMATT #6 IFF NULL:&SV: IFT XA:V COMPLEMENT XA BIT IN TD:FLG WORD \XA:V ENDC IFF XA:V WORD XA:V;#6 ENDC S: SET 1 ENDC IFF S: WORD 0 TD:FLG ENDC D: SET 1 DV: SYMATT #7 IFF NULL:&DV: D: SET #7 ENDC DV: SYMATT #8 IFT NULL:&DV: WORD $+6 TD:SEM  ENDC IFF NULL:&DV: WORD #8 TD:SEM ENDC WORD D: TD:NOX WORD #3 TD:Y WORD #4  TD:AD WORD #5 TD:AMT WORD #2 TD:P IFT NULL:&DV: WORD D: CONCURRENCY SEMAPHORE  ENDC RES 2,0 WORD TD:CHK TD:CKW ENDM TITL * ECB:A LABEL,UAT * ECB:A LABEL,UAT,ENDMEM * * LABEL LABEL TO BE ASSIGNED TO START OF ECB. * UAT ADDRESS OF UNIT ASSIGNMENT TABLE. *  ENDMEM ADDRESS OF LOCATION FOLLOWING LAST WORD * OF USER'S PROGRAM. (OPTIONAL). *  MACRO ECB:A #1 CHAN R:ECBL ED:PER WORD 0 EC:FLG WORD #1 EC:EDB WORD 1  EC:LUS ALIAS EC:PRV RES 2,0 WORDS 4-5 RESERVRVED WORD 0 EC:CNT WORD 0  EC:ALH WORD 0 EC:SUB WORD 0 EC:MST WORD 0 EC:NEC WORD EC:CHK EC:CKW * REST OF ENVIRNMENT DESCRIPTOR BLOCK WORD 16 ED:EVO WORD 48 ED:MRO RES 2,0 14-15 RESERVED FOR FUTUTE USE RES 16,0 ED:EVT WORD #2 ED:UAT WORD 0 ED:LMA SV: SYMATT #3 IFF NULL:&SV: WORD #3 ED:MPA ENDC IFT NULL:&SV: WORD 0 ED:MPA ENDC WORD 0 ED:HMA WORD 0 ED:EUS WORD   :7FFF ED:PRI CHAN R:TDBL ED:TLH CHAN R:SL ED:SLH CHAN R:MBXL  ED:MLH RES 8,0 41-48 RESERVED FOR FUTURE USE * 41-43 EMPTY *  44 NUMBER OF ACTIVITY * 45 TDB OF INITIAL TASK * 46 PRIORITY OF INITIAL ACTIVITY * 47 ID OF INITIAL ACTIVITY * 48 MAP OF REGISTER TABLE ENDM TITL * BGIN:A LABEL,TASK,PRI * * LABEL ADDRESS OF ARGUMENT LIST WHICH FOLLOWS * TASK ADDRESS OF TCB AS GIVEN IN THE TDB:A MACRO * PRI PRIORITY OF THE TASK *  MACRO BGIN:A S: SET #?=3 IFF S: NOTE 'THIS MACRO CALL HAS'..#?..'PARAMETERS' ENDC  IFT S: #1 EQU $ WORD #2 WORD #3 ENDC ENDM TITL * TICK:A LABEL,TID,SEMA,TCOUNT(,EID) * *  LABEL ADDRESS OF ARGUMENT LIST WHICH FOLLOWS * TID TIMER ID TO CANCEL OR MODIFY THE REQUEST * SEMA ADDRESS OF SEMAPHORE TO BE SIGNALLED * TCOUNT NUMBER OF TICKS ELLAPSED *  EID MASTER ENVIRONMENT ID (OPTIONAL) * MACRO TICK:A S: SET 3<#?<6 IFF S:  NOTE 'THIS MACRO CALL HAS'..#?..'PARAMETERS' ENDC IFT S: V: SET 0 IFT #?=5 V: SET #5 ENDC #1 EQU $ WORD V: WORD #2 WORD #3 WORD #4 ENDC ENDM TITL * WALL:A LABEL,TID,SEMA,UPPER,LOWER(,EID) * * LABEL ADDRESS OF ARGUMENT LIST WHICH FOLLOWS * TID TIMER ID TO CANCEL OR MODIFY THE REQUEST * SEMA ADDRESS OF SEMAPHORE TO BE SIGNALLED * UPPER  TIME OF DAY UPPER * LOWER TIME OF DAY LOWER * EID MASTER ENVIRONMENT ID (OPTIONAL) * MACRO WALL:A S: SET 4<#?<7 IFF S: NOTE 'THIS MACRO CALL HAS'..#?..'PARAMETERS'  ENDC IFT S: V: SET 0 IFT #?=6 V: SET #6 ENDC #1 EQU $ WORD V: WORD #2 WORD #3 WORD #4 WORD #5 ENDC ENDM TITL * MAIL:A LABEL,IDENT(,ENVIRONMENT) * * LABEL  ADDRESS OF ARGUMENT LIST WHICH FOLLOWS * IDENT MAILBOX ID * ENVIRONMENT ENVIRONMENT ID * MACRO MAIL:A IFF 1<#?<4 NOTE 'THIS MACRO CALL HAS'..#?..'PARAMETERS' ENDC IFT 1<#?<4 V: SET 0 IFT #?=3 V: SET #3 ENDC #1 WORD V: WORD #2 ENDC ENDM TITL *  SDB:A LABEL,VALUE * * WHERE LABEL IS THE LABEL TO BE APPLIED TO THE SEMAPHORE. * VALUE IS THE INITIAL VALUE OF THE SEMAPHORE. * MACRO SDB:A IFF 0<#?<4 NOTE 'ERROR,THIS MACRO CALL HAS'...#?...'PARAMETERS'  ENDC IFT 0<#?<4 CHAN R:SL IFT #?=1 ONLY ONE ARGUMENT WORD 0 SEMAPHORE INITIALZED TO 0 #1 WORD 0 ENDC IFT #?=2 TWO ARGUMENTS WORD #2 FLAGS SET TO 0 #1  WORD #2 SEMAPHORE INITIALIZED TO #2 ENDC IFT #?=3 3 ARGUMENTS WORD #3%8;#2  FLAGS AND INITIAL VALUE #1 WORD #2 SEMAPHORE INITIALIZED TO #2 ENDC WORD SD:CHK ENDC ENDM TITL * MDB:A IDENT(,EID) * * IDENT MAILBOX ID * EID ENVIRONMENT ID, OPTIONAL * * MACRO MDB:A IFF 0<#?<3 NOTE 'ERROR, THIS MACRO CALL HAS'...#?...'PARAMETERS' ENDC  IFT 0<#?<3 V: SET 0 IFT #?=2 V: SET #2 ENDC CHAN R:MBXL PEER POINTER WORD 0 FLAGS WORD 1 MAILBOX USAGE SEMAPHORE WORD 0 MESSAGE SIGNALLING SEAPHORE  WORD 0 A-REGISTER OF MESSAGE WORD 0 Q-REGISTER OF MESSAGE RES 3,0 RESERVED WORD V: MASTER ENVIRONMENT ID WORD #1 MAILBOX IDENTIFIER WORD MD:CHK CHECKWORD  ENDC ENDM TITL * INTERNAL BLOCK CHECK VALUE EQUATES * IN:CHK EQU :F00E TD:CHK EQU :F01E TDB CHECK VALUE (IN TD:CKW) AC:CHK EQU :F02E ACB CHECK VALUE (IN AC:CKW) SD:CHK EQU :F03E SDB CHECK VALUE (IN SD:CKW) CC:CHK EQU :F04E CCB CHECK VALUE (IN CC:CKW) EC:CHK EQU :F06E ECB CHECK VALUE ( IN EC:CKW ) MD:CHK EQU :F07E MDB CHECK VALUE (IN MD:CKW) UA:CHK EQU :F09E TITL EDB EXCEPTION VECTOR EQUATES * * EDB EXCEPTION VECTOR EQUATES * * THE FOLLOWING XV:XXXXX SYMBOLS SPECIFY LOCATIONS IN THE EXCEPTION * VECTOR LOCATIONS OF THE ENVIRONMENT DESCRIPTOR TABLE (EDB). * XV:UINTP EQU :0 UNIMPLEMENTED INSTRUCTION TRAP XV:MEMTP EQU :1 MEMORY EXCEPTION TRAP XV:CNMTP EQU :2 CHARACTER/NUMERIC EXCEPTION TRAP XV:USRTP EQU :3 USER TRAP XV:AERTP EQU :4 ARITHMETIC EXCEPTION TRAP XV:STKTP EQU :5 STACK EXCEPTION TRAP XV:STKSV EQU :6 STACK EXCEPTION REGISTER SAVE AREA XV:USTEX EQU :8 UNIMPLEMENTED STRAP EXCEPTION XV:ST0EX EQU :9 STRAP 0 EXCEPTION XV:DOREX EQU :A DOOR SERVICE EXCEPTION XV:RTXEX EQU :B RTX SYSTEM ERROR SPACE 3 * * STACK EXCEPTION REGISTER SAVE AREA EQUATES * STKSV:A EQU 0 A REGISTER SAVE AREA STKSV:Q EQU 1 Q REGISTER SAVE AREA STKSV:X EQU 2 X REGISTER SAVE AREA STKSV:Y EQU 3 Y REGISTER SAVE AREA TITL ** MACRO: EDXVT:A * * GENERATE ENTRIES IN THE EXCEPTION VECTOR TABLE OF THE EDB. * THE EXCEPTION ADDRESS SPECIFIED WILL BE JUMPED TO IF THE * SPECIFIED EXCEPTION OCCURS. * * USAGE: * EDXVT:A ECB,EXCEPTION,ADDRESS * ECB = MUST MATCH FIRST PARAMETER OF ECB MACRO * EXCEPTION = EXCEPTION VECTOR OFFSET * ADDRESS = ADDRESS OF USER SUPPLIED EXCEPTION PROCESSOR * * NOTE: * IF ENVIRONMENT EXCEPTION PROCESSING IS TO BE SPECIFIED, THE * EDXVT:A MACRO MUST FOLLOW THE ECB:A MACRO. * ** SPACE 1 MACRO EDXVT:A !LOC::: SET $ SAVE LOCATION COUNTER ORG #1+ED:EVT+#2 ORG INTO EDB WORD #3 INSERT EXCEPTION PROCESSOR ADDRESS ORG !LOC::: ORG BACK TO WHERE WE WERE ENDM SPACE 3 SAVE END EXCEPTION VECTOR EQUATES * * EDB EXCEPTION VECTOR EQUATES * * THE FOLLOWING XV:XXXXX SYMBOLS SPECIFY LOCATIONS IN THE EXCEPTION * VECTOR LOCATIONS OF THE ENVIRONMENT DESCRIPTOR TABLE (EDB). * XV:UINTP EQU :0 UNIMPLEMENTED INSTRUCTION TRAP XV:MEMTP EQU :1 MEMORY EXCEPTION TRAP XV:CNMTP EQU :2   TITL R T X D . M A C - RTX DEVELOPMENT EQUATES & MACROS (93420-12-C1) * TASK DESCRIPTOR BLOCK EQUATES * TD:PER EQU 0 PEER LINK TD:FLG EQU 1 FLAGS TD:USA EQU 2 USAGE SEMAPHORE ADDRESS TD:NOX EQU 3 NUMBER OF CONCURRENT EXECUTIONS ALLOWED TD:Y EQU 4 Y-SCRATCHPAD SPECIFICATION TD:AD EQU 5 STACK LENGTH OR ADDRESS TD:AMT EQU 6 STACK LIMIT TD:P EQU 7 ADDRESS OF START OF TASK TD:CKW EQU 11  CHECK WORD (CONTAINS TD:CHK) * * ACTIVITY CONTROL BLOCK EQUATES * AC:PER EQU 0 PEER LINK AC:FLG EQU 1 FLAFS AC:PRI EQU 2 PRIORITY AC:K EQU 3 K-REGISTER AC:Y EQU  4 Y-REGISTER AC:L EQU 5 L-REGISTER AC:LST EQU 7 ENVIRONMENT ACTIVITY LIST PEER LINK AC:TDB EQU 8 TASK DESCRIPTOR BLOCK AC:ECB EQU 9 ENVIRONMENT CONTROL BLOCK AC:ID EQU  10 IDENTIFIER AC:CKW EQU 11 CHECK WORD (CONTAINS AC:CHK) * * ACB FLAGS * ACF:OD EQU 4  INDICATES EXECUTION OUTSIDE THE DOOR. TITL * ENVIRONMENT CONTROL BLOCK EQUATES * EC:PER EQU 0  PEER LINK EC:FLG EQU 1 FLAGS EC:EDB EQU 2 ENVIRONMENT DESCRIPTOR BLOCK POINTER EC:LUS EQU  3 LOGICAL UNIT SEMAPHORE EC:CNT EQU 6 # OF ACTIVITIES EC:ALH EQU 7 ACTIVITY LIST HEAD EC:SUB EQU 8 SUBORDINATE LIST HEAD EC:MST EQU 9 MASTER ENVIRONMENT EC:NEC EQU 10  NECESSARY ENVIRONMENT EC:CKW EQU 11 CHECK WORD (CONAINS EC:CHK) * * ENVIRONMENT DESCRIPTOR BLOCK EQUATES * ED:ECB EQU 0 ECB ADDRESS *WORDS 1-11 ARE A COPY OF ECB WORDS 1-11 IN THE ECB ED:EVO EQU 12  EXCEPTION VECTOR OFFSET (16) ED:MRO EQU 13 MAP REGISTER OFFSET (48) ED:EVT EQU 16 EXCEPTION VECTOR TABLE ED:UAT EQU 32 UNIT ASSIGNMENT TABLE ADDRESS ED:LMA EQU 33 LOW MEMORY ADDRESS ED:MPA  EQU 34 MEMORY POOL ADDRESS ED:HMA EQU 35 HIGH MEMORY ADDRESS ED:EUS EQU 36 ENVIRONMENT USAGE SEMAPHORE ED:PRI EQU 37 MAXIMUM PRIORITY ED:TLH EQU 38 TASK LIST HEAD ED:SLH EQU  39 SEMAPHORE LIST HEAD ED:MLH EQU 40 MAILBOX LIST HEAD * * ECB FLAGS * ECF:ND EQU 15  THIS ECB NOT DISPATCHABLE ECF:DA EQU 12 ECB WAS DYNAMICALLY ALLOCATED TITL * RTX EXCEPTION VALUES * ER:RTX EQU 2 RTX ERRORS, CLASS 2 EX:RTX EQU ER:RTX%8 EX:SEM EQU 1+EX:RTX SEMAPHORE EXCEPTION EX:STP EQU  2+EX:RTX STRAP OUT OF RANGE EX:STK EQU 3+EX:RTX INSUFFICIENT STACK SPECIFICATION EXCEPTION EX:EMP EQU 4+EX:RTX  UNABLE TO FILL E.M.P. REQUEST EX:SFP EQU 5+EX:RTX UNABLE TO FILL SYSTEM FREEPOOL REQUEST EX:PRI EQU 6+EX:RTX NEGATIVE ACTIVITY PRIORITY EX:CCB EQU 7+EX:RTX CCB EXCEPTION EX:TRP EQU 8+EX:RTX HARDWARE TRAP EXCEPTION EX:TBL EQU 9+EX:RTX DEBUG VERSION TABLE ID CHECK FAILURE EXCPT EX:SYS EQU 10+EX:RTX DEBUG VERSION, SYSTE M ACTIVITY VIOLATION EX:WCB EQU 11+EX:RTX CCB EXCEPTION, WALL CLOCK EX:MBX EQU 12+EX:RTX MAILBOX ID CHECK (INVALID ID) EX:ISS EQU :800 UNIMPLEMENTED SYSTEM SERVICE. EX:DBG EQU :900 STRAP 0 (REALTIME DEBUG BREAKPOINT) EX:UMT EQU :A00 UNINSTALLED MEMORY TRAP EX:SOT EQU :B00 STACK OVERFLOW TRAP EX:CNT EQU :C00 CHARACTER/NUMERIC TRAP EX:UIT EQU :D00 UNIMPLEMENTED INSTRUCTION TRAP EX:AET EQU :E00 ARITHMETIC ERROR TRAP EX:UST EQU :F00 USER TRAP TITL * MISCELLANEOUS EQUATES * R:CHEK SET 0  SELECT NON-DEBUGGING VERSION CHKOT: SET 1 TRUE FOR INHOUSE CHECK OUT. CHKOT: SET 0 FALSE FOR RELEASE STKMN: EQU 20 MINIMUM STACK TO BEGIN A TASK. SEMAX: EQU :100 SEMAPHORE MAXIMUM VALUE TCPRI: EQU :7000  TICK CLOCK PRIORITY WCPRI: EQU :6B00 WALL CLOCK ACTIVITY PRIORITY MAXIN: EQU :7FFF MAXIMUM TIC CLOCK INTERVAL SKAMT: EQU 23 STACK AMOUNT FOR CANNED ACTIVITY WALCP: EQU 30 WALL CLOCK PERIOD (MULTIPLES OF 8.33 MS) NDWCP: EQU 25 WALL CLOCK PERIOD FOR 50HZ LF RTC * * GENERAL CONTEXT BLOCK EQUATES * PEER: EQU 0 PEER LINK FLAGS: EQU 1 FLAGS MASTR: EQU 9 MASTER IDENT: EQU 10 IDENTIFIER CHECK: EQU 11 REDUNDANCY CHECK * * BEGIN CONTEXT BLOCK EQUATES * BEG:A EQU 1 A REGISTER BEG:Q EQU  2 Q REGISTER BEG:X EQU 3 X REGISTER BEG:Y EQU 4 Y REGISTER BEG:EC EQU 5 ECB ADDRESS BEG:TD EQU 6 TDB ADDRESS BEG:PR EQU 7 PRIORITY TITL * R:INIT BLOCK EQUATES * IN:A EQU 0  INITIAL A VALUE IN:Q EQU 1 INITIAL Q VALUE IN:X EQU 2 INITIAL X VALUE IN:Y EQU 3 INITIAL Y VALUE IN:ECB EQU 4 ECB ADDRESS FOR INITIAL ACTIVITY IN:TDB EQU 5  INITIAL TASK TO BE STARTED IN:PRI EQU 6 PRIORITY TO START INITIAL TASK AT IN:AID EQU 7 INITIALIZATION BLOCK ID IN:FPL EQU 8 FREEPOOL LENGTH (WORDS) IN:FPA EQU 9 FREEPOOL ADDRESS IN:EOM EQU 10 END-OF-MEMORY ADDRESS * * ENVIRONMENT MEMORY POOL EQUATES * EM:LEN EQU 0 IFT R:CHEK EM:XTR EQU 2 LEAVE TWO WORDS FOR DEBUG INFO ENDC IFF R:CHEK EM:XTR EQU 0 NOT DEBUG VERSION, NO EXTRAS NEEDED ENDC EM:PTR EQU EM:XTR+1 POINTER TO NEXT BLOCK TITL * CLOCK CONTROL BLOCK EQUATES * CC:PER EQU 0 PEER LINK CC:FLG EQU 1 FLAGS CC:TU EQU 2 WALL CLOCK EXPIRATION -- UPPER CC:TIC EQU CC:TU TICK CLOCK EXPIRATION CC:TL EQU 3 WALL CLOCK EXPIRATION -- LOWER CC:STS EQU 4 SEMAPHORE OR ADDRESS OF SEMAPHORE CC:BBA EQU CC:STS BEGIN BLOCK ADDRESS CC:ECB EQU 9  MASTER ENVIRONMENT CC:ID EQU 10 IDENTIFIER CC:CKW EQU 11 CHECK WORD (CONTAINS CC:CHK) TITL * SEMAPHORE DEFINITION BLOCK (SDB) EQUATES * SD:PER EQU 0 PEER LINK SD:FLG EQU 1   FLAGS SD:SEM EQU 2 SEMAPHORE SD:CKW EQU 3 CHECK WORD (CONTAINS SD:CHK) * * SEMAPHORE CONTROL EQUATES * SC:SEM EQU 0 SEMAPHORE WORD SC:CKW EQU 1 CHECKWORD * * MAILBOX DEFINITION BLOCK (MDB) EQUATES * MD:PER EQU 0 PEER POINTER MD:FLG EQU 1 FLAGS MD:MBX EQU 2  MAILBOX USAGE SEMAPHORE (IV=1) MD:MSG EQU 3 MESSAGE SIGNALLING SEMAPHORE (IV=0) MD:A EQU 4  A-REGISTER OF MESSAGE MD:Q EQU 5 Q-REGISTER OF MESSAGE MD:ECB EQU 9 MASTER ENVIRONMENT MD:ID EQU 10 IDENTIFIER MD:CKW EQU 11 CHECK WORD (CONTAINS MD:CHK) TITL * DEFBP: LABEL DEFINE LOCATION IN RTX BASE PAGE, * DEFBP: LABEL,N DEFINE N LOCATIONS IN RTX BASE PAGE, * * WHERE LABEL IS LABEL TO BE APPLIED TO LOCATION, * N IS OPTIONAL NUMBER OF CELLS. * MACRO DEFBP: #1 EQU BPLC: IFT #?=1 BPLC: SET BPLC:+1 ENDC IFF #?=1 BPLC: SET BPLC:+#2 ENDC ENDM * * * * CHKBP: LABEL CHECKS THAT THE LABEL CORRESPONDS TO * ITS ALLOCATION IN RTX BASE PAGE, * * WHERE LABEL IS THE LABEL ASSIGNED TO THE CURRENT * LOCATION COUNTER VALUE IN RTX BASE PAGE. * MACRO CHKBP: IFT #1-$ NOTE B,'ERROR IN BASE PAGE ALLOCATION' ENDC ENDM TITL * RTX BASE PAGE DEFINITIONS * R:SCRA EQU :20 START OF RTX SCRATCH PAD USAGE BPLC: SET R:SCRA DEFBP: R:ECBH DEFBP: R:ACT CURRENT ACTIVITY POINTER DEFBP: R:RDY READY LIST HEAD DEFBP: R:INTQ INTERRUPT QUEUE LIST HEAD  DEFBP: R:EMEM END OF REAL MEMORY DEFBP: R:FPH FREEPOOL LIST HEAD DEFBP: R:FPT FREEPOOL LIST TAIL DEFBP: R:NSRT R:WAIT DEFBP: R:SEMX RM:SEM X TEMPCELL DEFBP: R:SEMY RM:SEM Y TEMPCELL DEFBP: R:SVA STACK EXCEPTION, HOLDS A DEFBP: R:CCBH CCB LIST HEAD FOR TICK CLOCK REQUESTS DEFBP: R:WCBH  CCB LIST HEAD FOR WALL CLOCK REQUESTS DEFBP: R:INVL CURRENT TIC CLOCK INTERVAL DEFBP: R:CLKS TICK CLOCK WAIT SEMAPHORE DEFBP: R:NUIN TIC CLOCK INTERVAL TEMP CELL DEFBP: R:TODU TIME OF DAY UPPER DEFBP: R:TODL TIME OF DAY LOWER DEFBP: R:CHKQ CHK: MACRO TEMP CELL BPLC: SET :39 DEFBP: R:SAVE,6 CONTEXT SAVE ROUTINE DEFBP: R:SA12 INTERRUPT CONTEXT SAVE ROUTINE * * SYSTEM FREEPOOL BLOCK SIZE * BLKSZ: EQU 12 TITL * PUSH: -- PUSH REGISTER(S) ON STACK. * * PUSH: 4REG SIZE=5 * PUSH:  4REG,4REG =7,9 * PUSH: 4REG,4REG,4REG =9,11 * PUSH: 4REG,4REG,4REG,4REG  =13 * * WHERE 4REG IS ANY OF (A,Q,X,Y). NO REGISTER VALUES * EXCEPT K WILL CHANGE. STACK EXCEPTION MAY OCCUR. *  SIN WILL COVER NEXT INSTRUCTION. USES MACRO PUSH:1. * SECOND SIZE IS IF BOTH X AND Y ARE PUSHED. * MACRO PUSH:  PUSH:C #?,#1,#2,#3,#4 DETERMINE X AND Y USAGE. DUP ' JSK $+1',#? GET STACK SPACE SIN PUSH:X&PUSH:Y  %1+#?+2 PROTECT THE SEQUENCE. PUSH:E EXCHANGE K AND INDEX REGISTER. PUSH:R #1,#?-1 PUSH FIRST. IFT #?>1 PUSH:R #2,#?-2 PUSH SECOND. ENDC IFT #?>2 PUSH:R #3,#?-3 PUSH THIRD. ENDC  IFT #?>3 PUSH:R #4,#?-4 PUSH FOURTH. ENDC PUSH:E RESTORE K AND INDEX REGISTER.  ENDM TITL * POP: -- POP REGISTER(S) FROM STACK. * * POP: 4REG SIZE=5 * POP: 4REG,4REG  =6,8 * POP: 4REG,4REG,4REG =7,9 * POP: 4REG,4REG,4REG,4REG =10 * * WHERE 4REG IS ANY OF (A,Q,X,Y). NO REGISTER VALUES * EXCEPT K WILL CHANGE. REGISTERS ARE POP:ED IN * REVERSE ORDER FROM LIST SO CORRESPONDING PUSH: AND * POP: CAN HAVE SAME ARGUMENT LIST. * SECOND SIZE IS IF BOTH X AND Y ARE PUSHED. *  MACRO POP: PUSH:C #?,#1,#2,#3,#4 DETERMINE X AND Y USAGE. SIN PUSH:X&PUSH:Y%1+#?+3 PROTECT THE SEQUENCE PUSH:E POP:R #1,#?-1 IFT #?>1 POP:R #2,#?-2 ENDC IFT #?>2 POP:R #3,#?-3 ENDC IFT #?=4 POP:R #4,#?-4 ENDC IFT PUSH:Y ADD =#?,X ENDC IFF PUSH:Y ADD =#?,Y ENDC PUSH:E ENDM TITL * COPY: -- COPY WITH K-RELATIVE ADDRESSING. * *  COPY: OFFSET(K),4REG * COPY: 4REG,OFFSET(K) * * WHERE OFFSET IS AN EXPRESSION FOR THE RELATIVE * LOCATION ON THE STACK. FOR EXAMPLE, OFFSET=0 IS * THE TOP OF THE STACK. (K) MEANS INDEXED BY K. * 4REG IS ANY OF (A,Q,X,Y). *  MACRO COPY: COPY:B COPY,#1,#2 ENDM TITL * EXCH: -- EXCH WITH K-RELATIVE ADDRESSING. * * EXCH: OFFSET(K),4REG * EXCH: 4REG,OFFSET(K) * * SEE DESCRIPTION OF COPY: * MACRO EXCH: COPY:B EXCH,#1,#2 ENDM TITL * ASTAK: -- ALLOCATE TEMP CELLS ON STACK. * * ASTAK: 4REG * ASTAK: NUMBER * WHERE NUMBER IS THE NUMBER OF TEMP CELLS DESIRED. * 4REG IS ANY OF (A,Q,X,Y) WHICH CONTAINS NUMBER. * IF 4REG IS GIVEN, IT WILL BE USED AS WORKING CELL. * IF NUMBER IS GIVEN, INTERRUPTS WILL BE DISABLED. * AFTER ASTAK:, K POINTS TO BLOCK OF TEMP CELLS. *  MACRO ASTAK: R:4REG #1 FIND OUT IF ARG IS NUMBER OR 4REG. IFT R:REG JSK $+1 4REG.  SUB =1,#1 JNE #1,$-2 ENDC IFF R:REG ASTA:N SET #1/6*6 DIVIDE BY 6 LOCATIONS PER PUSH. ASTA:N SET #1-ASTA:N REMAINDER IS NUMBER OF JSK'S. IFT #1/6 IF MORE THAN 6 LOCATIONS, DUP ' PUSH :40',#1/6 ENDC IFT ASTA:N PERFORM REQUIRED NUMBER OF JSK'S. DUP ' JSK $+1',ASTA:N ENDC ENDC ENDM TITL * RSTAK: -- RELEASE TEMP CELLS TO STACK. * * RSTAK: 4REG * RSTAK: NUMBER * * WHERE NUMBER IS THE NUMBER OF TEMP CELLS TO BE RELEASED. * 4REG IS ANY OF (A,Q,X,Y) WHICH CONTAINS NUMBER. * MACRO RSTAK: R:4REG #1 FIND OUT IF ARG IS NUMBER OR 4REG. IFT R:REG ADD #1,K 4REG. ENDC IFF R:REG SIN 3 NUMBER. EXCH A,K ADD =#1,A EXCH A,K ENDC ENDM TITL * PU  SH:R -- STORE A REGISTER IN THE STACK. * * PUSH:R 4REG,RELK * * WHERE 4REG IS ANY OF (A,Q,X,Y). RELK IS RELATIVE *  POSITION IN STACK WHERE REGISTER IS STORED (0-3). * MACRO PUSH:R IFT PUSH:Y IS X REGISTER BEING USED AS INDEX? IFT #(1,'X')>0 EXCH A,K YES, K CONTAINS USER'S X. COPY A,#2(X) EXCH A,K  ENDC IFT #(1,'X')=0 COPY #1,#2(X) NO, PUSH SPECIFIED REGISTER. ENDC ENDC IFF PUSH:Y IS Y REGISTER BEING USED AS INDEX? IFT #(1,'Y')>0 EXCH A,K YES, K CONTAINS USER'S Y. COPY A,#2(Y) EXCH A,K ENDC IFT #(1,'Y')=0 COPY #1,#2(Y) NO, COPY SPECIFIED REGISTER. ENDC ENDC ENDM TITL * POP:R -- REMOVE A REGISTER FROM THE STACK. * * POP:R 4REG,RELK * * WHERE 4REG IS ANY OF (A,Q,X,Y). RELK IS RELATIVE * POSITION IN STACK. * MACRO POP:R IFT PUSH:Y IS X BEING USED AS INDEX? IFT #(1,'X')>0 COPY A,K YES, POP INTO K INSTEAD. COPY #2(X),A EXCH A,K  ENDC IFT #(1,'X')=0 COPY #2(X),#1 ENDC ENDC IFF PUSH:Y IS Y BEING USED AS INDEX? IFT #(1,'Y')>0 COPY A,K YES, POP INTO K INSTEAD. COPY #2(Y),A EXCH A,K ENDC IFT #(1,'Y')=0 COPY #2(Y),#1 ENDC ENDC ENDM TITL * PUSH:E -- EXCHANGE STACK POINTER AND INDEX REGISTER. * * PUSH:E * * PUSH:Y INDICATES WHETHER Y IS BEING PUSHED. * MACRO PUSH:E IFT PUSH:Y IS Y BEING PUSHED? EXCH X,K YES, USE X FOR PUSHING. ENDC IFF PUSH:Y NO, USE Y FOR PUSHING. EXCH Y,K ENDC ENDM TITL * PUSH:C -- CHECK FOR INDEX REGISTER USAGE * * PUSH:C #?,#1,#2,#3,#4 * * DETERMINES IF ARGUMENTS TO PUSH: OR POP: INCLUDE X OR Y. * PUSH:X=0 IFF NO REFERENCE TO X. * PUSH:Y=0 IFF NO REFERENCE TO Y. MACRO PUSH:C PUSH:X SET 0 RESET BOTH FLAGS. PUSH:Y SET 0 IFT #(2,'X')>0 PUSH:X SET 1 ENDC IFT #(2,'Y')>0 PUSH:Y SET 1 ENDC IFT #1=2 IS THERE A SECOND?  IFT #(3,'X')>0 PUSH:X SET 1 ENDC IFT #(3,'Y')>0 PUSH:Y SET 1 ENDC ENDC IFT #1=3 IS THERE A THIRD? IFT #(4,'X')>0 PUSH:X SET 1 ENDC IFT #(4,'Y')>0 PUSH:Y SET  1 ENDC ENDC IFT #1=4 IS THERE A FOURTH? PUSH:X SET 1 YES, UNLESS REGISTERS ARE DUPLICATED, PUSH:Y SET 1 THEN BOTH X AND Y MUST BE PRESENT. ENDC ENDM TITL MACRO COPY:B SIN  3 COPY:L SET #(2,'(K)')-1 IFT COPY:L>0 IFT #(3,'Y')>0 EXCH K,X #(1) #(2,1,COPY:L)(X),Y EXCH K,X ENDC IFF #(3,'Y')>0 EXCH K,Y #(1) #(2,1,COPY:L)(Y),#(3)  EXCH K,Y ENDC ENDC IFF COPY:L>0 COPY:L SET #(3,'(K)')-1 IFT #(2,'Y')  EXCH K,X #(1) #(3,1,COPY:L)(X),Y EXCH K,X ENDC IFF #(2,'Y') EXCH K  ,Y #(1) #(3,1,COPY:L)(Y),#(3) EXCH K,Y ENDC ENDC ENDM TITL * R:4REG -- DETERMINE IF AN ARGUMENT IS A 4REG. * * R:4REG #N * * WHERE #N IS THE ARGUMENT TO BE TESTED. * R:REG=1 IFF ARGUMENT IS ANY OF (A,Q,X,Y). * MACRO R:4REG R:REG SET 0 IFT #(1,?)=1 TEST FOR ONLY ONE CHARACTER IFT #(1,'A')+#(1,'Q')+#(1,'X')+#(1,'Y')>0 R:REG SET 1 ENDC ENDC ENDM TITL * CHK: -- MAKE SURE A BLOCK IS OF THE CORRECT TYPE. * * CHK: 4REG,CKW,(OFFSET) * * WHERE 4REG IS ANY OF (A,Q,X,Y), WHICH CONTAINS THE ADDRESS OF * A BLOCK WHICH IS TO BE VERIFIED. OFFSET IS OPTIONAL. IT * SPECIFIES THE DISPLACEMENT OF THE CHECKWORD FROM THE BEGINNING *  OF THE BLOCK, THE DEFAULT VALUE IS CHECK:. CHW MAY BE EITHER * THE LABEL OF A LOCATION CONTAINING THE CHECK VALUE, OR A LITERAL * PRECEDED BY AN EQUAL SIGN. * MACRO CHK: IFT R:CHEK CS: SET CHECK: IFT #?=3 CS: SET #3 ENDC * IFT #(1,'X');#(1,'Y') SIN 3 COPY Q,R:CHKQ COPY #2,Q  CSK Q,CS:(#1) SIN 1 JST R:TABL COPY R:CHKQ,Q ENDC * IFF #(1,'X');#(1,'Y') EXCH #1,X SIN 3 COPY Q,R:CHKQ COPY #2,Q CSK Q,CS:(X) SIN  1 JST R:TABL COPY R:CHKQ,Q EXCH #1,X ENDC ENDC ENDM TITL * SYS:A -- GENERATE CANNED ACTIVITY ACB AND STACK * * SYS:A ACB,PRI,START,R:L,R:K * * WHERE ACB IS ADDRESS OF THE ACTIVITY ACB *  PRI IS THE PRIORITY OF THE ACTIVITY * START IS THE BEGIN EXECUTION ADDRESS * R:L IS THE ACTIVITY STACK LIMIT *  R:K IS THE INITIAL K REGISTER VALUE * * NOTE: * SKAMT: IS THE STACK AMOUNT ALLOCATED TO A * CANNED SYSTEM ACTIVITY * MACRO SYS:A * ACTIVITY STACK #4 EQU $ STACK LIMIT RES SKAMT:-CBL: RESERVED FOR STACK EXPANSION * INITIAL CONTEXT #5 WORD #4 L-REGISTER WORD XA:V STATUS RES 4,0  ALL REGISTER 0 WORD #3 P-REGISTER * * ACTIVITY ACB * #1 EQU $ ACB LABEL  RES 2,0 DUMMY PEER POINTER,FLAGS WORD #2 PRIORITY WORD #5 K OF INITIAL CONTEXT RES 1,0 NO Y-SCRACH PAD WORD #4 STACK LIMIT RES 5,0 DUMMY ECB,TCB,.... WORD AC:CHK DEBUG TABLE ID ENDM SPACE 3 SAVE END COPY Q,R:CHKQ COPY #2,Q  CSK Q,CS:(#1) SIN 1 JST R:TABL COPY R:CHKQ,Q ENDC * IFF #(1,'X'); TITL I O S . M A C - IOS GENERAL EQUATES & MACROS (93420-13-C1) UA:CHK EQU :F09E * UAT:AA LABEL START UNIT ASSIGNMENT TABLE * * UAT:EE LUN,ADDRESS UAT ENTRY * * UAT:ZZ END OF UAT * *  LABEL LABEL TO ASSOCIATED WITH UAT * LUN LOGICAL UNIT NAME * ADDRESS ADDRESS OF DIB OR FCB * * MACRO UAT:AA LOAD I:IO WORD UA:CHK #1 WORD UAT:ND-$-4%-1 RES 3,0 UAT:NV SET 0 ENDM *   MACRO UAT:EE WORD #1 S: SYMATT #2 IFT S:&UNDBT: EXTR #2 ENDC WORD #2 UAT:NV SET UAT:NV+1 ENDM * MACRO UAT:ZZ S: SYMATT #1 IFF S:&NULL: IFT #(1,'FORTRAN')>0 SNAM  UAT:ND ENDC ENDC UAT:ND EQU $ IFF S:&NULL: IFT #(1,'FORTRAN')>0 RES UAT:NV*2,0 ENDC ENDC ENDM ************************************************************ * BUFFER POOL GENERATION MACROS * * * * CALLING SEQUENCE * * BUF:R #1,#2 * *  * * #1 - NUMBER OF BUFFERS * ************************************************************ * BUF:LN EQU 512 * * BUF:R - GENERATE BUFFER POOL * MACRO BUF:R LOAD FM:SFM NAM BUF:N BUF:N EQU #1 DUP ' BUF:R1',#1 ENDM * * BUF:R1 - GENERATES BUFFERS, CALLED ONLY BY BUF:R MACRO * MACRO BUF:R1 CHAN BUF: CHAIN LINK CHAN BUF:: STATIC LINK RES  4,0 WORD BUF:LN LENGTH RES 2,0 SECTOR RES 7,0 SPARES RES BUF:LN/2,0 ENDM * IOB:A IOB,LUN,OPC,OPM,BCT,BUF,CGI,OPO * * * IOB LABEL TO BE ASSIGNED TO START OF IOB * LUN LOGICAL UNIT NAME OR NUMBER * OPC OPERATION CODE * RE: EQU 0 READ * AR: EQU 1 WRITE *  PO: EQU 2 POSITION * FU: EQU 3 FUNCTION * OPM OPERATION MODIFIER * UF: EQU 0 UNFORMATTED * FA: EQU 1 FORMATTED ALPHANUMERIC * FB: EQU 2 FORMATTED BINARY * DA: EQU 3 DIRECT FORMATTED ALPHA * DB: EQU 4 DIRECT FORMATTED BINARY * WP: EQU 5 WRITE PROMPT * * BCT REQUESTED BYTE COUNT * BUF I/O BUFFER ADDRESS * CGI ADDRESS OF CURRENT GRANULE INDEX OR ZERO * OPO OPTIONAL MODE OF OPERATION * SB: EQU 11 START IN SECOND BYTE OF BUFFER * * MACRO IOB:A IFT #?<7  NOTE 5,'NOT ENOUGH PARAMETERS' ENDC #1 WORD #2 LOGICAL UNIT NAME /NUMBER WORD 0 DEVICE DEDICATION NUMBER WORD #7 OPTIONAL ADDRESS OF CGI S: SYMVAL #8 IFF S:=0 IFT #8>15 S: SET #8 VALUE, NOT BIT EQUATE ENDC IFF #8>15 S: SET 1%#8 ENDC ENDC WORD #3%4+#4+S: WORD #5  BYTE COUNT WORD #6 I/O BUFFER ADDRESS WORD 0 ACTUAL COUNT PROCESSED WORD 0 SOFTWARE STATUS ENDM TITL * INPUT/OUTPUT BLOCK (IOB) * IO:LUN EQU 0 LOGICAL UNIT NAME/NUMBER IO:DDN EQU 1 DEVICE DEDICATION NUMBER IO:CRI EQU 2 ADDRESS OF CURRENT RECORD INDEX IO:CFI EQU IO:CRI CURRENT FILE INDEX POINTER IO:FC EQU 3 FUNCTION CODE IO:BCT EQU 4 BYTE COUNT REQUESTED IO:BUF EQU 5 I/O BUFFER ADDRESS IO:ACT EQU 6 ACTUAL COUNT PROCESSED IO:ST EQU 7 SOFTWARE STATUS * * FUNCTION CODE BITS * * BITS 15-6 MODE OF OPERATION ER: EQU 12 DO  N'T CALL DOIO ERROR ROUTINE,GO TO USER SB: EQU 11 START ON SECOND BYTE OF BUFFER HA: EQU 10 USED BY HALT I/O FUNCTION. UD: EQU 9 UN-DEDICATE DEVICE AFTER PERFORMING I/O * ER:V EQU 1%ER: SB:V EQU 1%SB: * * RE: EQU 0 READ WR: EQU 1 WRITE PO: EQU 2 POSITION FU: EQU  3 FUNCTION OPEN: EQU 4 OPEN CLOSE: EQU 5 CLOSE * * * BITS 3-0 OPERATION MODIFIER * READ & WRITE UF: EQU 0 UNFORMATTED FA: EQU :B FORMATTED ALPHANUMERIC FB: EQU :A FORMATTED BINARY FS: EQU :8 FORMATTED STREAM WP: EQU 1 WRITE PROMPT DA: EQU :F  DIRECT ALPHANUMERIC DB: EQU 6 DIRECT BINARY DS: EQU :C DIRECT STREAM BS: EQU FS:  SEQUENTIAL STREAM BINARY SA: EQU :9 SEQUENTIAL STREAM ALPHA RB: EQU FB: SEQUENTIAL RECORD BINARY RA: EQU FA: SEQUENTIAL RECORD ALPHA DSB: EQU DS: DIRECT STREAM BINARY DSA:  EQU :D DIRECT STREAM ALPHA DRB: EQU :E DIRECT RECORD BINARY DRA: EQU DA: DIRECT RECORD ALPHA * * FOR POSITION * * FOR POSITION (PO:) * FAB: EQU 0 FILE POINTER ABSOLUTE BYTES FRB: EQU 1 FILE POINTER RELATIVE BYTES WAB: EQU 2 WRITE POINTER ABSOLUTE BYTES WRB: EQU 3  WRITE POINTER RELATIVE BYTES AR: EQU 4 ABSOLUTE RECORDS RR: EQU 5 RELATIVE RECORDS RFP: EQU 6 READ FILE POINTER RWP: EQU 7 READ WRITE POINTER * * FOR FUNCTION OP: EQU 0 OPEN CL: EQU 1 CLOSE PL: EQU 2 PUNCH LEADER WF: EQU 3 WRITE FILE MARK DF: EQU 4 DEVICE DEPENDENT FUNCTION SS: EQU 5 SELECT HARDWARE STATUS TF: EQU 6 TOP OF FORM SC: EQU 7 SOFTWARE CONTROL * * FOR OPEN BL: EQU 1 BLOCK I/O * * SOFTWARE STATUS * IOERR: EQU 15  ERROR CAUSED I/O TERMINATION * BITS 13-12 DESCRIBE CONCURRENT CONDITIONS TFORM: EQU 1%12 TOP OF FORM BFORM: EQU 2%12 BOTTOM OF FORM * RETRY: EQU 11 A RETRY WAS REQUIRED TO PERFORM THE OPERAT EOM:  EQU 10 END OF MEDIUM ENCOUNTERED DURING OPERATION DELDA: EQU 9 DELETED DATA READ FROM FLOPPY DISK * *  IOS4 ERROR CODES * BITS 0-5 OF STATUS WORD CONTAIN LOWER BYTE OF ORROR CODE * BIT 6 SET FOR UNRECOVERABLE *  ERROR CLASSES ER:IOR EQU 0 I/O RECOVERABLE ER:IOU EQU 1 I/O UNRECOVERABLE SPACE 3 *  NORMAL RETURN CODES NORML: EQU 0 NORMAL I/O COMPLETION EOF: EQU 1 END OF FILE (GOING FORWARD) BOF: SET 3 SPACE 3 * MACROS FOR IOS4 ERROR CODES * IOU: FOR UNRECOVERABLE, IOR: FOR RECOVERABLE MACRO IOU: #1 EQU 1%6+#2 ENDM MACRO IOR: #1 EQU #2 ENDM SPACE 3 * ERROR CODES IOR: HALTD:,1 I/O HALTED IOR: NORDY:,2 NOT READY IOR: WRT PR:,3 WRITE PROTECT IOR: TIMOT:,4 TIME OUT IOR: PWRFL:,5 POWER FAIL & UNABLE TO RECOVER  IOR: DDTNA:,6 DDT NOT AVAILABLE,CFM ONLY IOR: VOLNU:,7 VOLUME NOT ON UNIT IOR: VOLNF:,8  VOLUME NOT FOUND IOR: NOREL:,9 LOGICAL UNIT NOT RELEASED IOR: AGAIN:,10 TRY AGAIN SPACE 3 IOU: CKSUM:,1 BAD CHECK SUM IOU: UNDEV:,2 UNASSIGNED DEVICE IOU: NIUAT:,3  LUN NOT IN UAT IOU: REOM:,4 REACHED END OF MEDIA IOU: HARDW:,5 HARDWARE ERROR IOU:  ILLOP:,6 ILLEGAL OPERATION FOR THIS DEVICE IOU: NEMEM:,7 NON-EXISTANT MEMORY ADDR IOU: INRTX:,8 MEMORY ADDR IN SYSTEM ARTEA IOU: DIRFL:,9 DIRECTORY FULL IOU: NOLAB:,10 DISK NOT LABELED  IOU: FAOV:,11 FILE ADDR OVERFLOW IOU: ILLAU:,12 ILLEGAL AU IOU: AUNF:,13 AU NOT FOUND IOU: WDEOF:,14 WRITE DIRECT HIT EOF IOU: NOTXT:,15 NOT EXTENDABLE IOU: ILLFA:,16  ILLEGAL FILE ADDR IOU: ALOFU:,17 ALLOCATION TABLE FOULED UP IOU: SYSUG:,18 SYSTEM USAGE ONLY  IOU: FCBCH:,19 FCB CHAIN BAD IOU: FILEO:,20 FILE OPEN IOU: NOPEN:,21 FILE NOT OPEN  IOU: FNOP:,21 FILE NOT OPEN IOU: OONWR:,22 OLD OR NEW WRONG, CFM ONLY IOU: ILLFP:,22 ILLEGAL FILE POINTER IOU: NOUNT:,23 UNIT NOT GIVEN IOU: UNFCB:,24 UNASSIGNED FCB IOU: BUFWP:,25 BUFFER HAS WRITE PENDING IOU: NOAU:,26 NO MORE FREE AU'S IOU: BADTC:,27 BAD TYPE CODE IOU: ABORT:,28 ABORT IOU: RTXER:,63 RTX ERROR SPACE 3 * * I/O ERROR BLOCK EQUATES SPACE 3 IOE:AC EQU 0 ACB ADDR OF ERROR ACTIVITY IOE:EC EQU 1 ERROR CODE IOE:K EQU 2 K-REG OF ACTIVITY WITH ERROR IOE:DI EQU 3 DIB ADDR IOE:TI EQU 4 TIB ADDR  SPACE 3 SAVE END OPERATION FOR THIS DEVICE IOU: NEMEM:,7 NON-EXISTANT MEMORY ADDR IOU: INRTX:,8 MEMORY ADDR IN SYSTEM ARTEA IOU: DIRFL:,9 DIRECTORY FULL IOU: NOLAB:,10 DISK NOT LABELED  IOU: FAOV:,11 FILE ADDR OVERFLOW IOU: ILLAU:,12 ILLEGAL AU IOU: AUNF:,13 AU NOT FOU TITL I O S D . M A C - IOS DEVELOPMENT EQUATES & MACROS (93420-14-C1) * I/O ERROR BLOCK EQUATES * IOE:AC EQU 0  ACB ADDR OF ERROR ACTIVITY IOE:EC EQU 1 ERROR CODE IOE:K EQU 2 K-REG OF ACTIVITY WITH ERROR IOE:DI EQU 3 DIB ADDR IOE:TI EQU 4 TIB ADDR TITL * DEVICE INFORMATION BLOCK (DIB) * DI:PER EQU 0 PEER POINTER DI:FLG EQU 1 DIB FLAGWORD DI:CIB EQU 2 MASTER CIB ADDRESS DI:FCB EQU 3 FILE CONTROL BLOCK LIST HEAD DI:NAM EQU 4 DEVICE NAME (4 CHARACTERS) DI:DN EQU 6 DEDICATION NUMBER DI:DS EQU 7 DEDICATION SEMAPHORE DI:SPB EQU 8 WATCHDOG TIMER -- NUMBER OF SHIFTS PER BYT DI:W BT EQU 9 WATCHDOG TIMER -- BASE TIME DI:DSW EQU 10 DEVICE SPECIFICATION WORDS (10-13) *  14-15 RESERVED * * DIB FLAGWORD * EQU 15 ALWAYS ZERO FOR DIB DIF:ND EQU 14  NO DEDICATION ON THIS DEVICE DIF:DP EQU 13 DI:DDN IS A POINTER TO A DEDICATION NUMBER DIF:NT EQU 12  NO TIMER FOR READ DIF:RT EQU 11 RETRY ON POWER FAIL DIF:FC EQU 10 FORM CONTROL DIF:OP EQU 9 DEVICE IS OPEN. DIF:UI EQU 1 DEVICE SUPPORTS UNSOLICITED INPUT DIF:BF EQU 0 BUFFER FLAG FOR CARD READER DIF:MT EQU 0 DISK IS MOUNTED DIF:NM EQU 1 NO AUTOMATIC MOUNT ON DISK TITL * DEVICE INFORMATION BLOCK FOR CHARACTER DEVICES * DI:CPL EQU 16 CHARACTERS PER LINE DI:LPP EQU 17 BOTTOM OF FORM COUNT/LINES PER PAGE DI:BMI EQU 18 BRANCH/MODE WORD FOR INPUT DI:BMO EQU 19 BRANCH/MODE WORD FOR OUTPUT DI:EOL EQU 20 POINTER TO END OF LINE SEQUENCE DI:TOF EQU 21 POINTER TO TOP OF FORM SEQUENCE DI:ERM EQU 22 ERROR MASK FOR STATUS DI:LC EQU 23 LINE COUNTER DI:EDT EQU 24  EDIT CHARACTER DI:ELI EQU 25 END OF LINE SEQUENCE FOR INPUT DI:BUF EQU 26 POINTER TO 2 WORD INTERNAL BUFFER DI:PU EQU 27 POINTER TO POWER UP SEQUENCE * * DEVICE INFORMATION BLOCK FOR CARD READER * *I:CPL EQU 16 CHARACTERS PER CARD *I:LPP EQU 17 =0, NOPAGES ON CARD READER *I:BMI EQU 18  BRANCH/MODE WORD FOR INPUT DI:CBA EQU 19 CURRENT BUFFER ADDR DI:ABA EQU 20 ALTERNATE BUFFER ADDR, =0 FOR NO DOBLE BUF DI:TRT EQU 21 TRANSLATION TABLE ADDR *I:ERM EQU 22 ERROR MASK FOR STATSUS TITL * DEVICE INFORMATION BLOCK FOR DISKS * DI:BPS EQU 16 BYTES PER SECTOR DI:SPT EQU 17  SECTORS PER TRACK DI:TPC EQU 18 TRACKS PER CYLINDER DI:CPD EQU 19 CYLINDERS PER DISK DI:SPA EQU 20 SECTORS PER ALLOCATION UNIT DI:CYL EQU 21 CUURRENT CYLINDER FOR FLOPPY DI:TRY EQU 22  HARD/RATE ERROR RETYR COUNT DI:VTS EQU 23 VTOC SEMAPHORE DI:ATS EQU 24 ALLOCATION TABLE SEMAPHORE DI:HOS EQU 25 HEAD OFFSET DI:HSA EQU 26 HEAD SEMAPHORE ADDR DI:SCS EQU 27  SEEK COMPLETE SEMAPHORE ADDR DI:FLP EQU 28 FLIST POINTER IN AU DI:FLN EQU 29 FLIST LENGTH IN SECTORS DI:ALO EQU 30 ALLOCATION TABLE SECTOR ADDR DI:APD EQU 31 AU PER DISK DI:BPA EQU 32 BYTES PER AU DI:SBF EQU 33 SECTORS PER BUFFER DI:SAU EQU 34 DI:BIT EQU 35 BIT # DI:CUR EQU 36 CURRENT COUNT DI:REQ EQU 37 REQUESTED NUMBER OF AUS DI:FND EQU 38  NUMBER FOUND DI:FAU EQU 39 FOUND AU START TITL * CONTROLLER INFORMATION BLOCK (CIB) * CI:PER EQU 0 PEER POINTER CI:FLG EQU 1 CIB FLAGWORD CI:MST EQU 2 MASTER LINK CI:DIB EQU 3   SUBORDINATE LINK (DIB LIST HEAD) CI:PRI EQU 4 REQUEST PRIORITY CI:DA EQU 5 DEVICE ADDRESS CI:IV EQU  6 DEVICE INTERRUPT VECTOR LOCATION CI:RD EQU 8 ENTRY POINT TO READ CI:WRT EQU 9 ENTRY POINT TO WRITE CI:POS EQU 10 ENTRY POINT TO POSITION CI:FUN EQU 11 ENTRY POINT TO FUNCTION CI:EOB EQU 12 12-15 EOB SEQUENCE * JST R:SA12 USE SYSTEM STACK * COPY TIB,Y  TIB ADDR OBVIOUSLY * JMP *$+1 * DATA I:EOB EOB ADDR CI:T1 EQU 16 TEMP CI:T2 EQU  17 TEMP CI:APR EQU 18 SAVEED PRIORITY OF ACTIVITY USING CIB CI:TIB EQU 19 TIB ADDR CI:USM EQU 20 CONTROLLER USAGE SEMAPHORE CI:TIM EQU 21 WATCH DOG TIMER CALCULATED INTERVAL CI:CSM EQU 22 COMPLETION SEMAPHORE CI:CFL EQU 23 COMPLETION FLAG * * CIB FLAGWORD * CIF:PU EQU 14 POWER UP OCCURED CIF:TO EQU 13 TIME OUT CAUSED COMPLETION CIF:OO EQU 12 OVERLAPPED OPERATIONS TITL * CONTROLLER INFORMATION BLOCK FOR DISK * CI:RAT EQU 24 RATE ERROR RETRY COUNT CI:HRD EQU 25 HARD ERROR RETRY COUNTER CI:OPC EQU 27 OP CODE CI:DCB EQU CI:OPC  START OF DISK CONTROL BLOCK CI:UNT EQU 28 UNIT CI:CYL EQU 29 CYLINDER CI:SEK EQU 30  RELATIVE SEEK COUNT CI:SEC EQU 31 SECTOR CI:CNT EQU 32 WORD COUNT CI:BUF EQU 33  BUFFER ADDR CI:IEA EQU 34 INTERUPT ENABLE & ADDR * * CONTROLLER INFORMATION BLOCK FOR HIGH CAPACITY DISK * CI:IOB EQU 35 NEXT IOB ADDR CI:WP EQU 36 WORDS PROCESSED CI:CST EQU 37  CONTROLLER SATTUS CI:DST EQU 38 DRIVE STATUS CI:DIV EQU 39 INTERUPT VECTOR, JSK CI:EOB CI:SSA EQU 40 SEEK COMPLETE SEMAPHORE ADDR * * FLOPPY DISK CONTROLLER INFORMATION BLOCK * CI:FWP EQU 35  WORDS PROCESSED CI:FST EQU 36 STATUS CI:FIV EQU 37 INTERUPT VECTOR CI:FT1 EQU 38  TEMP CI:EIV EQU 39 ERROR INTERUPT VECTOR TITL * TEMPORARY INPUT BLOCK (TIB) - USER'S STACK * TI:IOB EQU 0 IOB ADDRESS TI:FCB EQU 1 FCB ADDR TI:DIB EQU 2 DIB ADDRESS TI:CIB EQU 3 CIB ADDRESS TI:BCT EQU 4 REQUESTED BYTE COUNT TI:BUF EQU 5 BUFFER ADDRESS TI:FC EQU 6 FUNCTION CODE TI:SOF EQU 7 SOFTWARE STATUS TI:PRI EQU 13 TEMPOARY SAVE FOR ACTIVITIES PRIORITY. * * TIB ON ENTRY TO HANDLERS * TI:CRI EQU 12 ADDR OF CURRENT RECORD INDEX * *  TIB FOR DIO * TI:TIM EQU 8 WATCHDOG TIMER VAQLUE TI:ACT EQU 9 ACTUAL BYTE COUNT TI:BMW EQU  10 BRANCH/MODE WORD TI:IBF EQU 11 INTERMEDIATE BUFFER ADDR * * TIB FOR DISKS * *TI:TIM EQU 8 WATCHDOG TIMER VAQLUE TI:SEC EQU 9 SECTOR NUMBER TI:TRK EQU 10 TRACK NUMBER  (HEAD NUMBER) TI:CYL EQU 11 CYLINDER NUMBER * * TIB ON RETURN FROM HANDLERS * *TI:ACT EQU 9  ACTUAL BYTE COUNT TI:HWS EQU 10 HARDWARE STATUS (TWO WORDS) TI:HW2 EQU 11 HARDWARE STATUS WORD 2 * * TIB EQUATES * TI:T1 EQU 14 TEMP CELL TI:T2 EQU 15 TEMP CELL TI:T3 EQU 16  TEMP CELL TI:T4 EQU 17 TEMP CELL TI:QUO EQU 18 RELATIVE AU TI:REM EQU 19 REMIANDER OF SECTOR OR AU CALCULATION TI:RAU EQU 20 EXTENT RELATIVE AU BASE TI:PAU EQU 21 EXTENT PHYSICAL AU BASE TI:NAU EQU 22 NUMBER OF AUS IN EXTENT TI:FP1 EQU 23 WORKING FILE POINTER TI:FP2 EQU 24 WORKING FILE POINTER TI:WRQ EQU 25 WORKING REQUEST COUNT TI:PL EQU TI:WRQ PARAMETER LIST ADDR TI:WAC EQU 26 WORKING ACTUAL COUNT TI:FNO EQU TI:WAC FNO TI:WSF EQU 27 WOKING SOFTWARE STATUS TI:UBX EQU 28 USERS BUFFER INDEX TI:CAU EQU 29 CURRENT AU TI:CNX EQU 30 CURRENT INDEX TI:T5 EQU 31 TEMP CELL TI:T6 EQU 32 TEMP CELL TI:FCS EQU 33 FUNCTION CODE SAVE TI:BCS EQU 34 BYTE COUNT SAVE TI:BUS EQU 35 BUFFER ADDR SAVE TIBLN: EQU 36 TIB LENGTH TITL * DISTRIBUTED I/O * IODAD: SET :F IOD ADDRESS (MAY ONLY BE :C,:D,:E OR :F) IODIB: SET :C0 IOD INTERRUPT ADDRESS BASE * CRCN: SET 0  CARD READER CHANNEL NUMBER CRDA: SET IODAD:%3+CRCN:%1 . DEVICE ADDRESS CRIA: SET CRCN:%3+IODIB: . INTERRUPT ADDRESS * MTCN: SET 1 MAGNETIC TAPE CONTROLLER CHANNEL NUMBER MTDA: SET IODAD:%3+MTCN:%1 . DEVICE ADDRESS MTIA: SET MTCN:%3+IODIB: . INTERRUPT ADDRESS * TVCN: SET 2 CRT CHANNEL NUMBER TVDA: SET IODAD:%3+TVCN:%1 .  DEVICE ADDRESS TVIA: SET TVCN:%3+IODIB: . INTERRUPT ADDRESS * IECN: SET 3 IEEE INTELLIGENT CABLE CHANNEL NUMBER IEDA: SET IODAD:%3+IECN:%1 . DEVICE ADDRESS IEIA: SET IECN:%3+IODIB: . INTERRUPT ADDRESS * TYCN: SET 4 TELETYPEWRITER CHANNEL NUMBER TYDA: SET IODAD:%3+TYCN:%1 . DEVICE ADDRESS TYIA: SET TYCN:%3+IODIB: . INTERRUPT ADDRESS * PRCN: SET 5 HIGH SPEED PAPER TAPE READER CHANNEL NUMBER PRDA: SET IODAD:%3+PRCN:%1 . DEVICE ADDRESS PRIA: SET PRCN:%3+IODIB: . INTERRUPT ADDRESS * PPCN: SET 6 HIGH SPEED PAPER TAPE PUNCH CHANNEL NUMBER PPDA: SET IODAD:%3+PPCN:%1 . DEVICE ADDRESS PPIA: SET PPCN:%3+IODIB: .  INTERRUPT ADDRESS * LPCN: SET 7 LINE PRINTER CHANNEL NUMBER LPDA: SET IODAD:%3+LPCN:%1 . DEVICE ADDRESS LPIA: SET LPCN:%3+IODIB: . INTERRUPT ADDRESS TITL *  NON-DIO * DFCN: SET :11 DISK, FLOPPY DFDA: SET DFCN:%3 . DEVICE ADDRESS * DMCN:  SET :14 DISK, MEDIUM CAPACITY DMDA: SET DMCN:%3 . DEVICE ADDRESS * DHCN: SET :15  DISK, HIGH CAPACITY DHDA: SET DHCN:%3 . DEVICE ADDRESS TITL * MISCELLANEOUS EQUATES * CI:EOB EQU :C R:SA12 EQU :3F LF: EQU :A FF: EQU :C CR: EQU :D * * BUILD A WORD OF BITS MACRO * BIT:WORD MACRO WORD MACLAB BIT:EQU MACENT EQU MACLAB BIT:SET MACENT SET MACLAB BIT:SET SET 0 * BIT:LOOP MACENT NULL IFT #(1,?) BIT:SET SET 1//#(1)++BIT:SET BIT:LOOP #(2),#(3),#(4),#(5),#(6),#(7),#(8) ENDC IFF '##(0,1,1)'='N' #(-1) #(0) BIT:SET ENDC ENDM TITL * MACRO FOR INTERUPT SEQUENCE * INT:SEQ MACRO EXTR I:EOB JST R:SA12  COPY =$-CI:EOB-1,X CIN ADDR JMP *$+1 WORD I:EOB ENDM * * PATCH MACRO * PATCH:  MACRO CORG: SET $ ORG #(1) WORD #(2) ORG CORG: ENDM * * STANDARD DIB MACRO * DIB:ST MACRO LOAD D:#(1) ENDM TITL * MEDIUM/HIGH CAPACITY DISK DIB MACRO * DIB:DM MACRO DM DIB:DH MACENT DH MB: SYMVAL #2 MEGABYTES IFT #(0,'DM') SPT: SET 12 SECTORS PER TRACK TPC: SET 2 TRACKS PER CYLINDER SPA: SET 1 SECTORS PER AU CPD: SET 203 CYLINDERS PER DISK, 5MB IFT MB:=10 CPD: SET 406 ENDC ENDC IFT #(0,'DH') TPC: SET 5 SPT: SET 32 CPD: SET 823 SPA: SET 8 IFT MB:=40 CPD: SET 411 SPA: SET 4 ENDC IFT MB:=150 TPC: SET 19 CPD: SET 411 ENDC IFT MB:=300 SPA: SET 16 TPC: SET 19 ENDC ENDC APD: SET SPT:*TPC:*CPD:/SPA: AU'S PEWR DISK NAM D:#(1) D:#(1) CHAN #(0):  DI:PER WORD 0 DI:FLG WORD C:#(1,1,3) DI:CIB CHAN Z:#(1) DI:FCB  BYTE '##(1)' DI:NAM RES 1,0 DI:DN WORD 0 DI:DS WORD -9  DI:SPB WORD 1*8 DI:WBT BIT:WORD FA:,FB:,DA:,DB:,UF: BIT:WORD FA:,FB:,DA:,DB:,UF: BIT:WORD  BIT:WORD OP:,CL: RES 2,0 WORD 512 DI:BPS WORD SPT: DI:SPT WORD TPC: DI:TPC WORD CPD: DI:CPD WORD SPA: DI:SPA WORD -1 DI:CYL  BYTE 3,10 DI:TRY WORD 1 DI:VTS WORD 1 DI:ATS IFT #(0,'DM')  BYTE 1,'##(1,4,4)'-'0'&1*2 DI:HOS ENDC IFT #(0,'DH') WORD 0 DI:HOS ENDC WORD 0,0 WORD APD:/2 DI:FLP WORD CPD: DI:FLN WORD APD:/2+CPD: WORD APD: DI:APD WORD 512*SPA: DI:BPA WORD 1 DI:SBF RES 6,0 ENDM TITL * MEDIUM/HIGH CAPACITY DISK CIB MACRO * CIB:DM MACRO DM CIB:DH MACENT DH DEVAD: SYMVAL #(2) IFT #(2,?)=0 DEVAD: SET #(0)DA: STANDARD DEVICE ADDR ENDC IFT DEVAD:<:20 DEVAD: SET DEVAD:%3 ENDC NAM C:#(1,1,3) EXTR DK:RD,DK:WRT,DK:FUN C:#(1,1,3) CHAN CIB: CI:PER RES 2,0 CHAN #(0): CI: DIB WORD :7600 CI:PRI WORD DEVAD: WORD 0,0 WORD DK:RD,DK:WRT,0,DK:FUN  INT:SEQ CI:EOB RES 4,0 WORD 1 CI:USM WORD 0,0,0 RES 15,0  JSK C:#(1,1,3)+CI:EOB LPOOL ENDM TITL * LINE PRINTER DIB MACRO * DIB:LP MACRO LP CPL: SET  80 CHARACTERS PER LINE LPP: SET 57 LINES PER PAGE BOF: SET 3 BOTTOM OF FORM COUNT IFF #(2,?)=0 CPL: SET #(2) ENDC IFF #(3,?)=0 LPP: SET #(3) ENDC  NAM D:#(1) D:#(1) CHAN #(1,1,3): BIT:WORD DIF:FC DI:FLG - FLAG WORD EXTR C:#(1,1,3) WORD C:#(1,1,3) WORD 0 BYTE '##(1)' RES 1,0 WORD 0 WORD -3 WORD 4*8 BIT:WORD BIT:WORD FA:,UF: BIT:WORD BIT:WORD OP:,CL:,WF:,SC:,TF: RES 2,0 WORD CPL: BYTE BOF:,LPP:  WORD 0 WORD :1210 WORD !LP:CR WORD !LP:TF WORD :3202 WORD -LPP:  WORD 0 WORD 0 WORD !LP:BF WORD !LP:PU !LP:PU WORD 3 BYTE :FF,CR:,LF:,0 !LP:CR WORD 2 IFT #(4,?)=0 BYTE ' ',CR: ENDC IFF #(4,?)=0 BYTE CR:,#4 ENDC !LP:TF WORD 2  BYTE FF:,CR: !LP:BF RES 2,0 ENDM SPACE 3 SAVE END RES 2,0 CHAN #(0): CI:DIB WORD :7600 CI:PRI WORD DEVAD: WORD 0,0 WORD DK:RD,DK:WRT,0,DK:FUN  INT:SEQ CI:EOB RES 4,0 WORD 1 CI:USM WORD 0,0,0 RES 15,0 JUAT:S O0SEGMENTBLANK oLR:LOW KD:DH00 D:DM01 D:DF01 KI:IO D:TY00 D:TR00 KD:TP00 D:TK00 D:PR00 KD:PP00 D:LP00 D:DM00 KD:DF00 D:CR00 ihg CRt LPt PPt PRtTKtTPtTRtTYtF0t F1tD0t D1tH0tJI:SLU I:RET I:STUR JI:STU0 I:POWR I:NEOB JI:FINI I:WAIT I:STUP JI:DOIO I:IO O0SEGMENTBLANK ROM o ?LR:LOW KI:ERS1 I:ERTB I:DOER KI:DOSV I:ABRT I:ECTT KR:SACT R:SPRI R:ISIG  KR:GPR R:IWAI C:HEAD KI:WDT iig h C @C @C @C @C @C @ `p҄GI@DEF LA1MH F@6EQM@IG k F@6IM IāM/p $p# J ho6Mekk@6M_@6;Zttttt tt @Р1MIAB C # ABx# g !@BJ+ B CJS8@9  @X yJK QEJN BJR # g  BCF09FXB +  N1C 6C&F09C +g HF@6Eo# g# g BKQ]6ǀF#   IDL 1 N6H 1 N Bȉ@AH# g MCMC+CM # # gC+C # g /ph@phC+C?ph@kph# ttt tt ttg C6# 6B # # g 섁@ +b @1# t JI:INIT I:WDAC I:KWDT JI:LWDT R:RTCI I:DOGY JI:WDT O0SEGMENTBLANK ROM o +KKTTLF4: R:ITIC R:ISIG KR:IWAI C:HEAD I:POWR ifxgig  Hܕ  ܄+6Ϡ j@F@ `+11Xdtdtttdtdig>gg@dg.i1g A s⑂@ @AF ## # tdddJI:ERS3 I:ERS2 I:ERS1 JI:ERTB O0SEGMENTBLANK oiggggJI:DOER I:DOSV I:ABRT O0SEGMENTBLANK ROM o iiggg# JD:TV00 O0SEGMENTBLANK oKTYTOF: TYEOL: TYBUF: KTYELI: C:TY0 NTY: igktTV00PPtt tttJD:TK00 O0SEGMENTBLANK oKTYTOF: TYEOL: TYBUF: KTYELI: C:TY0 NTY: igktTK00PHtt _tttJD:TY00 O0SEGMENTBLANK oKTYTOF: TYEOL: TYBUF: KTYELI: C:TY0 NTY: igktTY00PHtt _tttJD:TP00 O0SEGMENTBLANK oKTYEOL: TYBUF: C:TY0 NTY: igktTP00P t ttJD:TR00 O0SEGMENTBLANK oKTYBUF: C:TY0 NTY: igktTR00P   _tJTYELI: TYTOF: TYEOL: JTYBUF: C:TY0 O0SEGMENTBLANK o"KI:EOB TY:FUN TY:WRT KTY:RD NTY: CIB: igkktttt?tg g g gJD:LP00 O0SEGMENTBLANK o%KC:LP0 NLP0: igktLP00 P9!2#   JC:LP0 O0SEGMENTBLANK  oKI:EOB LP:FUN LP:WRT NLP0: CIB: igkkttt?tJD:CR00 O0SEGMENTBLANK ogKCR:TAB C:CR0 NCR: igktCR00PtPJC:CR0 O0SEGMENTBLANK oKI:EOB CR:WRT CR:FUN KCR:RD NCR:  CIB: igkktttt?tJD:PP00 O0SEGMENTBLANK o KC:PP0 NPP: igktPP00  JC:PP0 O0SEGMENTBLANK oKI:EOB PP:FUN PP:WRT NPP: CIB: igkkttt?tJD:PR00 O0SEGMENTBLANK oKC:PR0 NPR: igktPR00  _JC:PR0 O0SEGMENTBLANK oKI:EOB I:OPEN PR:RD NPR: CIB: igkktttt?tJD:DF03 O0SEGMENTBLANK o(KC:DF0 NZ:DF03 DF: igktkDF03AA M MGJD:DF02 O0SEGMENTBLANK o(KC:DF0 NZ:DF02 DF: igktkDF02AA M MG JD:DF01 O0SEGMENTBLANK o(KC:DF0 NZ:DF01 DF: igktkDF01AA M MGJD:DF00 O0SEGMENTBLANK o(KC:DF0 NZ:DF00 DF: igktkDF00AA M MGJC:DF0 O0SEGMENTBLANK o)KI:EOB DF:FUN DF:WRT KDF:RD NDF: CIB: igkktttt?tfdJD:DM01 O0SEGMENTBLANK o(KC:DM0 NZ:DM01 DM: igktkDM01AA    OJD:DM00 O0SEGMENTBLANK o(KC:DM0 NZ:DM00 DM: igktkDM00AA    OJC:DM0 O0SEGMENTBLANK o)KI:EOB DK:FUN DK:WRT KDK:RD NDM: CIB: igkkvttt?tdJD:DH00 O0SEGMENTBLANK o(KC:DH0 NZ:DH00 DH: igktkDH00AA  7  &7 @LJC:DH0 O0SEGMENTBLANK o)KI:EOB DK:FUN DK:WRT KDK:RD NDH: CIB: igkkvttt?tdJC:HEAD O0SEGMENTBLANK oNCIB: igkJPP:FUN LP:FUN TY:FUN JPP:WRT LP:WRT TY:WRT JPR:RD TY:RD O0SEGMENTBLANK ROM o |KI:OPCL I:VCNT I:SIV KFBW: FBR: I:STAT KI:ECTT I:RST I:SDIO KI:TRTB I:TRLL I:RET KI:EMEM I:FINI I:NEOB KI:WAIT I:DIO I:STUP iiggg EDπF ĠB΋QG F ʀDt TRt DׄDI3BJEK xC FqDOF B6E@6ArP + 1 0y vBC ܗD+KU PB ЄP# GGc󟊟tttttt t t  O YDFF 6EEKdddcb F@0 CXJQB1v 6ǀy C DD+ KFFBJ[D Xܗ 1VD+K B,y GG'C tt t  Ҟw@KQB@6 1R@ KCNĂ܄ 6À# @ KQQJDI@lJ HJICIIBΝQ ;ʙNyJQKQ/6/tttttttLPtgg IED'DDF  EKBF A @JF àC IHGKF@ 6y}@*  &I D `DF6BK FJQC kƀF6OKbt ttA KĀy}MKI IIMDNIttt|Dt DIIzDFXJQF KIM6A*%* '} CРB̘Q ICB1C D FFI@6 C  K% 'BK K C K@ K C%' BK+ IM1I@AIC uIMMDOD F@6 @M 6@FKK D BKFF AǠBy@QD}  M DRI IIF) 6A+%+ / * +'II 'CđB@1B ttt qttt A[ggg BJF / . ̠ K D II /* ӠB1P1{D+KB  I瞲  B K D IIF   FBRyD SBID@DĞD DDDI1kD+KG aCI I ZBBܗI I CF  - @KQB@6X tttttt  B  KB =KI D ItLPTYTKPPTPqJFBW: FBR: O0SEGMENTBLANK ROM o KI:SIV I:SDIO I:ECTT KI:RET I:STAT I:VCNT KI:RST I:NEOB I:STUP KI:FINI I:WAIT I:DIO iig DIBK̈́JSC DIFF I ED؞ҞОсKy  D5 ΠC FK ICD EKnC CFF DBK CILUCC IDGKC Ȟ{wtt t tttttt؞g DIBK̈́JFGF b0 DCIĐ IK  ֠CKD@yNq āJIpGFCDEK ?CC9`DI6 6݀FF DCB K Ā#"I! I G}wDI @lJ_6D/6Bht tt )KF@6+%'6*  6|EK+D@*l# JCR:WRT CR:FUN CR:RD O0SEGMENTBLANK ROM o KI:VCNT I:OPCL I:ECTT KI:EMEM I:RET I:NEOB KI:RST I:TRLT I:STAT KI:TRLL I:WAIT I:STUP KI:FINI I:DIO iig EDрF PDIB NCDIEKמ؞ٞ DIDBJ1B 6GBK' B /6yF  ̠BǀII  F ^D DBP KDB ā BKB6À  }J/6wurt tt tt t t"tt ttttg cg @ SjB TtJI:TRLT O0SEGMENTBLANK ROM o 3iig C )@aE+ 6֤ N 6LN 637603010146167576030101462775760301014627d) * + , - . / 0 ?. SCOUTGEN MACSCOUTRTX MACSCOUTRTXD MAC SCOUTIOS MAC SCOUTIOSD MAC SCOUTIOS LIB SCOUTRTX LIBJR:LOW O0SEGMENTBLANK oigJR:MPM2 R:MPM1 R:BTC1 JR:WLKS R:CNTK R:CDRG JR:SNSW R:SREG R:PFK  JR:PFLG R:CNSM R:FAT1 JR:FATL RTX: O0SEGMENTBLANK oKR:SETH R:UMTH R:PWRF KR:IDOR R:CNSL R:LSTK KR:1 KSTK R:AETH R:USTH KR:CNTH R:UITH R:STRT KR:TICI R:WLAC R:TKAC MDEBUG4 NR:ECBL ii kt9C @_9 C @o? P Px !@p@ *P z  9*r A|tttg>g >gt >g ggggggg}ug ~g  g  @0t t ttt tt 2tttJMDBUG4 O0SEGMENTBLANK oFKG:Z G:Y G:X  KG:W G:V G:U KG:T G:S G:R KG:Q G:P G:O KG:N G:M G:L KG:K G:J G:I  KG:H G:G G:F KG:E G:D G:C KG:B G:A G:9 KG:8 G:7 G:6 KG:5 G:4 G:3 KG:2 G:1 G:0 ig  ~ž\ EInYd  & T_w> ]?@ ( : ӂP - :ӂ"  )  F  ȦpP0 @ 0B %` h  !}cF «⫂ pP0/o  M D B U G 4 C 0 ӟi 7 }t#t"t!t ttttttttttttttttttt t t t t ttttttttt  ӂzӾ P AC Q@ X= Y:ԽѾ K3 L0 S- D* C'ԟK =ӟ{  } ӟ|"  *ٽ҆ N G؆BA& R Ɯ Ƙ™LBLCLFLL LSLJLILGLRȝ  ǞA 4}  Ğ|QEr , , `熂՟ _ٟ ` J BK eߞւ iޠ @ޞ ޜ `@E ;RA@E N@Aޏǎ Qފ ,_?(  o| xa  D `枢mX* Sb Ѐ] Ѐ āX@AĄ܃V B `ǁ D瞄*H] Q0 `Ģ.*,& $r "Bƽ ۽ֽˁCā  / XŃ ѽ i ]с߆@ڃ۽ BǢ ,ž[ + - * X /KJƎ ߞ^ߞ[{ xނ Z ,ş|˽с߆ ۽މ{ўu  ,Žֆx@ FC pqLL  (w{u dޅJQB`y ߾ˆzxo|  IƎQ ,ŽƇ , ƂpIưk ,  ,Htr Hm -ņց -ņ ߆CB\\ÂF - 0tт5ڃ3Ԟx ’@" Fz@ Ό F  ō lC#߆ .bƝޙޖJQ !’ފދJ QĽ %ӂԞu  U  B *  ӂGo h f e "cIaM K Y& V&RR `QKL$ kK N =ӂDD G A   :Ӟ ӟL  ǟ{ y9 u    :w  ® 0C C 9 6C C "0 `j  •࢒C "C tC  I6B E‚B4/BBtttt t^g @6NN @ SA# t JR:SWAI R:IWAI R:WAIT JR:SSIG R:ISIG R:SIG O0SEGMENTBLANK ROM o OKR:DA R:IACB R:SACT iigg# ttg oSJRCQM܀  Ā #Ā# # # gge## '_g )iHOr@bRCj( ""@`'`@(qMqK  `#Ā# jr) # tJR:TICP R:TICI R:TKAC JR:ITIC R:KTIC R:LTIC O0SEGMENTBLANK ROM o #KR:RTXEX R:DCHK R:GTS KR:GVSH R:RE12 R:SSIG KR:IWAI R:ISIG R:GPR KR:SPRI iig /p(p(` /ph@phG`t Ctdt @ABC` +1N)+ ڞoÅBS-Bt o-zB--B@At@`+ @Ui `?ph@kphJ`?p(+p(# tg?).ttg )+/` 1T-DŽ/F uutA@@` `i//-76).\tttigg@dXgp.JR:MTIC R:CTIC O0SEGMENTBLANK ROM o JKR:TKAC R:GPR R:SPRI KR:DCHK R:GVST R:XPTE KR:ITIC iig p # /p(p(`  /ph@phj)+ ` @@h@ih?ph @kph`?p(+p(# g /ph@phP?ph@kphA p # tttttttJNOWAL: O0SEGMENTBLANK ROM o LR:RWAL R:WLAC KSTTLF: R:WLKS iighh # tJR:RWAL TTLF4: R:WLAC O0SEGMENTBLANK ROM o '\KSTTLF: R:RTXEX R:GVST KR:IWAI R:ISIG R:ITIC KR:WLKS iig Ⓜ@ @A BCDEF 䃧# tdddi@dgk.i 01As?1 0,qgI,B0&C1& D `@/ph@ph ?ph@kphr%`H@@h@ `@@r`H@A@ d#ttttti#$tgJR:IWAL R:AWAL R:GTOD JR:STOD O3 0SEGMENTBLANK ROM o yKR:DCHK R:WLAC R:GPR KR:GVSH R:SPRI R:GTS iig pO10 # g p?10 # g /p(p(` F/ph@ phȂ@ABDCtfNg /p(p(` uF/ph@ pho@AB0 1Gă` / ph@ph),ƞ,@ ,i `?ph@kph`?p(+p(# tttttJR:CWAL O0SEGMENTBLANK ROM o 4KR:WLAC R:GPR R:SPRI KR:DCHK R:GVST iig p # /p(p(`  /ph@phj), ` @@h@ih?ph @kph`?p(+p(# tttttJCLK50: O0SEGMENTBLANK ROM o LSTTLF: KTTLF4: iigh # tJSTTLF: O0SEGMENTBLANK ROM o iig# JR:SPRI R:GPR R:GPRI O0SEGMENTBLANK ROM o KR:DISP R:SACT R:PRID iig p# g!# g@ A#  # !"Ă##tttJR:CNSL R:CINT O0SEGMENTBLANK ROM o 'KR:CNSM R:CNTK R:RE12 KR:RTXEX R:SSIG R:IWAI KR:ITIC iig A# A# ‘? FE # tdtttitigG?vtttJR:IRCV R:RECV R:ISND JR:SEND O0SEGMENTBLANK ROM o ~KR:IWAI R:ISIG iig ` 1@ ` A# `pCD# g Op(䂄Āp(` + E/p pOphA@kph DE `+?p(+p(# zkttg ` 1@ ` A# `pCD # g /p(p(` +cӠDE ?phA@ph `+WOphA @kph ?p(+p(# @``  @1GAx`@# !# JR:GIVM R:GETM O0SEGMENTBLANK ROM o ]KR:MPM2 R:MPM1 R:RTXEX iig ) ` 1Z@z J@K` `@@ A䁄A+ # |ttg | @"F&@#S @ Ȁ@RBnk` 1E { e(AH^ jA1M `@ ` TGwA@@xK # tJR:RBUF R:ABUF O0SEGMENTBLANK ROM o KR:DISP R:GETM R:GIVM KR:SACT iig # !I!CLg# !IttttJR:SACT R:RE12 R:DAQX JR:DA R:IACB R:DISP JG:Z O0SEGMENTBLANK ROM o yKR:KSTK iigg g!CDCg!CBg p c # /#qP@#I" "B1F@ y@(@ m"qI!C?#Qp c  # /P P!U { '%z |# tg 9 ܆@g ?p(Āp(`@qEB `@ Op(+p( @`@qDB{y`H@ĀOp(+p( # JR:KSTK R:LSTK O0SEGMENTBLANK o@ig@gJR:INI1 R:PWRF R:STRT O0SEGMENTBLANK ROM o NKR:RTXEX I:INIT R:SREG KR:SNSW R:CDRG R:PFK KR:PFLG R:DISP R:NOPF KR:UINI R:LSTK R:KSTK iig PÞQA@pg AA o0_t tttttt tttt tg uA qphjBCDpE F0AgcbP@ [@ !䃞V JR:GVST R:GVSH R:GTS O0SEGMENTBLANK ROM o iig O%1‚# %Q& # g /&&1%Ā# g ?%Ā%Q& # JR:PAUS O0SEGMENTBLANK ROM o KR:DISP R:SACT R:PRID iig@ A#  # )"` 1I{@#Ā#tttJR:USTREXR:SETH R:TRAPX JR:UITH R:4 UMTH R:USTH JR:CNTH R:AETH O0SEGMENTBLANK ROM o XKR:FATL R:EMUL iigC @IgC @IgC @IgC @Ig tgI`pFg !`@qC p@1 ptg  !1Eā䃀*! oqC@1gIfJR:SYSX R:TABL R:XPTE JR:RTXEX R:DOOREXR:STR0EXO0SEGMENTBLANK ROM o  KR:FATL iigI g I !`@qA@1tigg /}g ?|g ?|di ?!qB@1I pdiJR:SATD O0SEGMENTBLANK ROM o xiig iSC* bĀ+u* M] # Sm v jsCk JS검@mkb `@nbG*`@ G*g' ā  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII? IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII@ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIB IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIID IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIE IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIF IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIH IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIK IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIL IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII