IMD 1.16: 2/09/2008 10:23:00 f81003 (rev b0) s81021.asm nm4 source/object floppy o81031.obj mini flex disk pico diagnostic minflpyhelp.hlp 00-93810-03b0    @0|)v1uo)  " }jA cMIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIOS4 MC9790405142912A0790405142912 790405142912(F81003 VOLLSI-4 SOURCE/OBJECT FLOPPY   IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIM@jjggg@ o G`k򞽢_C# b# }B u[ ]e JRiCp@=<; G9P@ G=y;<": 06OS:: SYS " NEITHER UNIT OR VOLUME SPECIFIED CLOSING  VOLUME NOT GIVEN( CORRECT VOLUME NAME IS  PARAMETERS IGNORED & FILE IS SYSTEM FILE BAD AU  UNITS N TITL 'MINI-FLEX DISK PICO DIAGNOSTIC 00-93810-00B0' * * MINI-FLOPPY PICO DIAGNOSTIC * * THIS PROGRAM CONSISTS OF A MINI-FLOPPY * PICO DIAGNOSTIC AND A DISKETTE FORMATTER * UTILITY. * * THE MINI-FLOPPY PICO DIAGNOSTIC TESTS ARE: * * TEST A - TESTS BASIC CONTROLLER FUNCTIONS * TEST B - TESTS SEEK FUNCTIONS * TEST C - TESTS SEEK AND READ ADDRESS FUNCTIONS * TEST D - TESTS READ AND WRITE DATA FUNCTIONS * TEST E - TESTS READ AND WRITE (UNIQUE PATTERN) DATA FU(CTIONS * TEST F - TESTS VERIFY DATA FUNCTIONS * TEST G - TESTS PROPER FUNCTION OF INTERRUPT * FEATURE READ ADDRESS/READ DATA/WRITE DATA. * TEST H - TESTS MULTI-SECTOR AUTO I/O FUNCTIONS * TEST T - TECH TESTS. * * UP EQU :5E UP ARROW BACK EQU :5F BACK ARROW CR EQU :0D CARRIAGE RETURN LF EQU :0A LINE FEED DTTYDA EQU :7C DIO STSHFT EQU 9 TTY CRLF EQU :8D8A CARRIAGE RETURN/LINE FEED MFADR EQU :FC MINI-FLEX DEVICE ADDRESS SEEKOP EQU 9  SEEK OPERATION RDADOP EQU 5 READ ADDRESS OPERATION WRITOP EQU 3 WRITE DATA OPERATION REDOP  EQU 7 READ DATA OPERATION DELAY EQU 1 DELAY FLAG WRTAU EQU :4 WRITE AUTOI/O RRTAU EQU :8 READ AUTO I/O VRYFOP EQU :B VERIFY OPERATION CMPERR EQU :F COMPARE ERROR MISCMP EQU :F MIS COMPARE CNSINT EQU :94 CONSOLE INTERRUPT * * MAIN LINE * NAM POWRUP,POWRDN,SAVEP REL 0 MFPD EQU $ ENTRY POINT RBIT 12,S ENABLE EOB INTERRUPTS RBIT 13,S ENABLE DATA SERVICE INTERRUPTS UIS UPDATE INTERRUPT STATUS RBIT 6,S TURN ON XA BIT IN STATUS WORD JMP MFP10 MFP10 EQU  $ JST ASCOUT PRINT SIGN-ON WORD SIGNOL+SIGNOL WORD SIGNON COPY =1,A INITIALIZE PASS COUNT COPY A,PASSNO TO ONE COPY =0,A COPY A,ENTFLG SBIT 8,S ENABLE COMPUTER INTERRUPTS SBIT 4,S ENABLE CONSOLE INTGERRUPTS JST INITLZ JMP QUERY ASK QUESTIONS MFP20 EQU $ COPY TSINAD,A TEST TABLE PTR-1 COPY A,TPTR MFP25 IMS TPTR INCREMENT POINTER COPY *TPTR,A  GET TEST NO JLT A,PASEND END OF TABLE IS FFFF(-1) JEQ A,MFP25 SKIP ZERO COPY A,X JST  0(X) EXECUTE THE TEST JST TSTEND JUMP TO TEST END JMP MFP25 PASEND EQU $ COPY CNTRL,A  GET CONTROL WORD ROTATE A,RO,4 JT OV,PAS10 JMP MFPD HALT AFTER ONE PASS PAS10 EQU $  JST PRTPAS IMS PASSNO JMP MFP20 * PRINT PASS AT END OF EACH PASS PRTPAS ENT JST ASCOUT PRINT PASS WORD 9 # WORD ERRH1 COPY PASSNO,A AFTER EACH PASS JST DECOUT JMP *PRTPAS * LPOOL * * MASTER DATA WORDS * * * CONTROL BLOCK CONFIGURATION * (DO NOT CHANGE ORDER) * OPCODE WORD 0 OPERATION CODE UNIT WORD 0 UNIT TRACK WORD 0 TRACK HEAD WORD 0 HEAD SCTR WORD 0 SECTOR DED WORD 0 DELAY FLAG * TECHNO WORD 0  TECH NUMBER RESET WORD :100 RESET PICO RETRYC WORD 0 ENTFLG WORD 0 INTERRUPT FLAG TPTR WORD  0 TABLE PTR DEVAD WORD 0 DEVICE ADDRESS CNTRL WORD 0 CONTROL DEFLT WORD 0  DEFAULT FLAG TEMP1 WORD 0 TEMP CELLS TEMP2 WORD 0 TEMP4 WORD 0 TESTNO WORD 0 TEST NUMBER COUNT WORD 0 COUNT CNTCNT WORD 0 CONTROL COUNTER FINIFG WORD 0 FI/NISHG FLAG COMAND WORD :200 COMMAND WORD WCPAT WORD 0 PATTERN WCPAT1 WORD 0 PASSNO WORD 0  PASS NUMBER* FMFLG WORD 0 FORMAT FLAG ERRWRD WORD 0 ERROR WORD TEMPU WORD 0  TEMPARILY UNIT HRDSFT WORD 0 HARD/SOFT ERROR FMAT WORD 0 FORMAT TYPE * * SSCTR WORD 1  START SECTOR ESCTR WORD 16 ENDING SECTOR * SHEAD WORD 0 START HEAD EHEAD WORD 1  ENDING HEAD * STRK WORD 0 STARTING TRACK ETRK WORD 35 ENDING TRACK * SUNIT WOR D 0 START UNIT EUNIT WORD 4 ENDING UNIT INTS WORD 0 UPATRN WORD 0 UNIQUE PATTERN TSINAD WORD TESTS-1 REEDBF RES 128,0 PTNBUF RES 128,0 * FRSTWT WORD 0 SIGNON WORD CRLF WORD CRLF  BYTE 'MINI-FLEXIBLE DISK PICO DIAGNOSTIC' SIGNOL EQU $-SIGNON * QUERYA WORD CRLF BYTE 'FORMAT/DIAG (D) = '  WORD -1 QUERYB WORD CRLF BYTE 'TSTS (A,B,C,D,E,F,G,H) = ' WORD -1 QUERYC WORD CRLF BYTE 'UNITS (0) = ' WORD -1 QUERYD WORD CRLF BYTE 'TRACKS (0,3) = ' WORD -1 QUERYE WORD CRLF BYTE  'SCTRS (1,2) =' WORD -1 QUERYF WORD CRLF BYTE 'HEAD (0) = ' WORD -1 QUERYG WORD CRLF BYTE 'INTS (Y) = ' WORD -1 QUERYH WORD CRLF BYTE 'PATN (5B) = :' WORD -1 QUERYI WORD CRLF BYTE 'DEV AD (:FC)=:' WORD -1 QUERYJ WORD CRLF BYTE 'CONTROL INFO (C) = :' WORD -1 QUERYK WORD CRLF BYTE 'INT ADR (:F0) = :' WORD -1 QUERYL WORD CRLF BYTE 'MULTI-SECTOR I/O (2) = ' WORD -1 * * QUERIES - ASK QUESTIONS AND VERIFY THE ANSWER. * ALSO ESTABLISH DEFAULT VALUE. * * QUERY EQU $ QUERY1 EQU $ JST MSGA WORD QUERYA FOR MAT ERROR QURY1B JST IDEC JNE X,QUERY1 NUMERIS INPUT ERROR.  JST CHRIN JMP QURY1E C/R JMP QUERND # JMP QUERY1 BACK ARROW JMP QUERY1 UP ARROW JMP QUERY1 COMMA NOP COPY =0,X CLSN ='D',A CHECK IF DIAGNOSTIC JMP QURY1C CSK A,='F' CHECK IF FORMAT NOP JMP QUERY1 COPY =1,X SET X=+1 QURY1C COPY  X,FMFLG JMP QURY1B QURY1E EQU $ COPY FMFLG,A CHECK FOR FORMAT? JEQ A,QURY2A JMP FORMAT LPOOL * * ASK FOR TESTS * * QURY2A EQU $ ASK FOR TESTS JST MSGA WORD QUERYB COPY =0,A COPY A,TEMP4 QURY2C EQU $ JST *IDECP JNE X,QURY2E ANY DECIMAL INPUT JST *CHRINP JMP QURY3A C/R JMP QUERND # QURY2E JMP QURY2A BACK ARFROW JMP QUERY1  UP ARROW JMP QURY2C COMMA NOP NOP SUB =:40,A JLE A,QURY2E CLSN =:14,A  CHECK FOR JMP TECHT TECH TEST SUB =:10,A JGT A,QURY2E ADD =:10,A COPY A,X COPY TEMP4,A CHECK INPUTS OF 10 TESTS CLSN =10,A JMP QURY2A YES ERROR * * THE FOLLOWING CODE BUILDS A JSTG TABLE FOR * ALL TESTS THAT WERE INSERTED BY OPERATOR) * COPY X,QRYZ1 COPY QRYX1,A GET ADDRESS OF PARAM TABLE ADD QRYZ1,A ADD OFFSET COPY A,QRYZ2 COPY *QRYZ2,A COPY A,QRYZ1 SAVE TGEST ADDRESS COPY QRYX2,A ADD TEMP4,A COPY A,QRYZ2 COPY QRYZ1,A GET TEST ADDRESS  COPY A,*QRYZ2 SAVE IN WORKING TABLE COPY QRYZ2,A GET WORK TABLE ADDRESS ADD QRYX3,A INCR ADDRESS  COPY A,QRYZ2 COPY =-1,A GET DELIMITER COPY A,*QRYZ2 IMS TEMP4 BUMP COUNT JMP  QURY2C GET NEXT INPUT QRYX1 WORD PRAMSX-1 QRYZ1 WORD 0 QRYZ2 WORD 0 QRYX2 WORD PRAMS QRYX3 WORD 1 LPOOL * * ASK FOR UNIT NUMBERS * QURY3A EQU $ JST MSGA ASK UNIT NOS WORD QUERYC UNIT COPY =0,A COPY A,TEMP4 QURY3C JST *IDECP GET INPUT JEQ X,QURY3J COPY X,A DO RANGE CHECK CSK A,H3 MUST BE BETWEEN 0-3 JMP $+2 JMP QURY3A RANGE ERROR QURY3E EQU $ COPY  TEMP4,A GETR ADDRESS IN UNIT CLSN =0,A CHECK IF ZERO COPY X,SUNIT SAVE STARTING UNIT ADD =1,X INCREMENT COUNT COPY X,EUNIT SET ENDING UNIT IMS TEMP4 COPY SUNIT,A MAKE SURE ENDING  CSK A,EUNIT UNIT IS ASCENDING ORDER JMP QURY3F IF LESS THAN OK NOP > IF GREATER ERROR JMP QURY3A = IF EQUAL ERROR QURY3F JST *CHRINP CHECK TERMINATOR JMP QURY4A C/R JMP  QUERND # JMP QURY3A BACK ARROW JMP QURY2A UP ARROW JMP QURY3C COMMA JMP QURY3A NOP JMP QURY3A QURY3J COPY IDCTM3,A JEQ A,QURY3F IF ZERO CONTINUE COPY =0,X JMP QURY3E IF ACTUAL ZERO LOOP BACK LPOOL CHRINP WORD CHRIN PTR TO CHAR IN IDECP WORD IDEC PTR TO IDEC H3 WORD 3 * * ASK FOR CYLINDER (TRACKS) * QURY4A EQU $ JST MSGA ASK FOR CYLINDER WORD QUERYD COPY =0,A COPY A,TEMP4 QURY4C JST *IDECP GET INPUT JEQ X,QURY4K COPY X,A DO RANGE CHECK CSK A,H40 MUST BE 0-40 JMP QURY4E < JMP QURY4A > RANGE ERROR QURY4E COPY  TEMP4,A = CLSN =2,A TWO INPUT JMP QURY4A YES, ERROR CLSN =0,A FIRST PARAM COPY X,STRK SAVE IN STGART TRACK ADD =1,X FOR ENDING TRACK COPY X,ETRK THE END+1 IMS TEMP4 INCREMENT OFFSET COPY A,X COPY STRK,A GET START TRACK CSK A,ETRK CHECK FOR ASCENDING ORDER JMP QURY4G NOP JMP QURY4A QURY4G JST *CHRINP CHECK TGERMINATOR JMP QURY5A C/R  JMP QUERND # JMP QURY4A BACK ARROW JMP QURY3A UP ARROW JMP QURY4C COMMA  NOP ':' NOP JMP QURY4A QURY4K COPY IDCTM3,A LOOK AT ACTUAL INPUT COUNT JEQ A,QURY4G COPY =0,X JMP QURY4E ACTUAL INPUT A ZERO * H40 WORD 40 * * ASK FOR SECTORS ( 1 - 16) * QURY5A EQU $ JST MSGA ASK FOR SECTOR WORD QUERYE COPY =0,A COPY A,TEMP4 QURY5C JST *IDECP GET INPUT  JEQ X,QURY5K COPY X,A DO RANGE CHECK CSK A,H17 1-16 JMP QURY5E < JMP  QURY5A > RANGE ERROR JMP QURY5A = QURY5E COPY TEMP4,A CLSN =0,A COPY X,SSCTR SAVE IN START SECTOR ADD =1,X AND STORE +1 COPY X,ESCTR END +1 IMS TEMP4 INCREMENT OFFSET COPY SSCTR,A GET START TRACK CSK A,ESCTR CHECK FOR ASCENDING ORDER JMP QURY5G NOP JMP QU RY5A QURY5G JST *CHRINP CHECK TGERMINATOR JMP QURYBA C/R JMP QUERND # JMP QURY5A BACK ARROW  JMP QURY4A UP ARROW JMP QURY5C NOP ':' NOP JMP QURY5A QURY5K COPY IDCTM3,A CHECK VALUE JEQ A,QURY5G  COPY =0,X JMP QURY5E * H17 WORD 17 * * ASK FOR HEAD ( 0 OR 1) * QURY6A EQU $ JST MSGA  ASK FOR HEAD WORD QUERYF COPY =0,A COPY A,TEMP4 QURY6C JST *IDECP GET INPUT JEQ X,QURY6K COPY X,A CSK A,H1 MUST BE 0, OR 1 JMP QURY6E < JMP QURY6A > RANGE ERROR QURY6E COPY TEMP4,A CLSN =0,A COPY X,SHEAD CLSN =1,A COPY X,EHEAD IMS TEMP4 QURY6G JST *CHRINP CHECK TERMINATOR QURY6H JMP QURY7A C/R JMP QUERND # JMP QURY6A BACK ARROW JMP QURYBA UP ARROW JMP QURY6C COMMA NOP ':' NOP JMP QURY6A QURY6K COPY IDCTM3,A  JEQ A,QURY6G COPY =0,X JMP QURY6E * H1 WORD 1 * * INTERRUPT QUERY * QURY7A EQU $ JST MSGA WORD QUERYG ASK FOR INTERRUPT JST *IDECP GET RESPONSE JNE X,QURY7A ANY NUMERIC INPUT IS ERROR CLSN ='Y',A ISIT Y JMP QURY7F CLSN ='N',A IS IT N JMP QURY7H QURY7C JST *CHRINP CHECK OTHER TERMINATOR JMP QURY8A C/R JMP QUERND # JMP QURY7A BACK ARROW JMP QURY6A UP ARROW JMP QURY7A JMP QURY7A JMP QURY7A NOP JMP QURY7A QURY7F COPY =0,A SET INTERRUP ON = ZERO QURY7H COPY A,INTS N=NON-ZERO JST *IDECP GET TERMINATOR  JMP QURY7C CHECK IT LPOOL * * ASK FOR DATA PATTERN / ONE WORD HEX * QURY8A EQU $ JST MSGA PRINT MESSAGE WORD QUERYH PATN = JST IHEX GET INPUT JEQ X,QURY8F IF ZERO SEE WHY QURY8C COPY X,WCPAT STORE PATTERN QURY8E JST CHRIN CHECK TERMINATOR JMP QURY9A C/R JMP QUERND  # JMP QURY8A BACK ARROW JMP QURY7A UP ARROW JMP QURY8A ANYTHING ELSE JMP QURY8A ':' NOP JMP QURY8A QURY8F COPY IDCTM3,X LOOK AT ACTUAL INPUT COUNT JEQ X,QURY8E DEFAULT COPY =0,X  JMP QURY8C STTORE IT LPOOL * * ASK FOR DEVICE ADDRESS * QURY9A EQU $ JST MSGA ASK ASK DEVICE ADDRESS WORD QUERYI JST IHEX GET INPUT JEQ X,QURY9F IF ZERO, SEE WHY COPY X,A  SHIFT A,RO,8 JNE A,QURY9A ILLEGAL INPUT COPY X,DEVAD STORE INPUT QURY9C JST CHRIN CHECK TERMINATOR JMP QURY9K C/R JMP QUERND # JMP QURY9A BACK ARROW JMP QURY8A UP ARROW  JMP QURY9A NOP NOP JMP QURY9A QURY9F COPY IDCTM3,A GET ACTUJAL INPUT COUNT JEQ A,QURY9C IF ZERO DEFAULT JMP QURY9A ELSE INPUT ERROR LPOOL * * ASK FOR INTERRUPT ADDRESS * QURY9K EQU $ JST MSGA ASK FOR INTERRUPT ADDRESS WORD QUERYK JST IHEX GET INPUT JEQ X,QURY9P COP Y X,A SHIFT A,RO,8 JNE A,QURY9K ILLEGAL INPUT COPY X,INTADR STORE INPUT QURY9M JST CHRIN CHECK TERMINATOR JMP QURYAA C/R JMP QUERND # JMP QURY9K BACK ARROW JMP QURY9A UJP ARROW JMP QURY9K NOP NOP JMP QURY9K QURY9P COPY IDCTM3,A GET ACTUAL INPUT COUNT JEQ A,QURY9M IF ZERO DEFAULT JMP QURY9K ELSE INPUT ERRROR LPOOL * * ASK FOR CONTROL INFORMATION * QURYAA EQU $  JST MSGA WORD QUERYJ CONTROL INFO JST IHEX GET INPUT JEQ X,QURYAF IF ZERO, SEE WHY COPY X,CNTRL STORE INPUT QURYAC JST CHRIN CHECK TERMINATOR JMP QUER10 C/R JMP QUERND # JMP QURYAA BACK ARROW JMP QURY9K UP ARROW NOP NOP JMP QURYAA JMP QURYAA QURYAF COPY IDCTM3,A GET ACTUAL INPUT COUNT JEQ A,QURYAC IF ZERO DEFAULT JMP QURYAC LPOOL * * *  ASK FOR SECTOR COUNT TO BE USED WITH MULTI-SECTOR AUTO * I/O INSTRUCTIONS * * QURYBA EQU $ COPY =17,A SUB SSCTR,A COPY A,ROOM JST MSGA ASK WORD QUERYL JST IDEC GET INPUT JEQ X,QURYBB INPUT ZERO OR CARRIAGE RETURN: SET UP FOR DEFAULT CLSN =1,A JMP QURYBB COPY X,A CSK A,ROOM ENOUGH SECTORS AFTER STARTING SECTOR TO TEST? JMP $+2 < YES JMP QURYBA > NO COPY A,SCTCNT SAVE SECTOR COUNT FOR MULTI SECTOR I/O NEG A,A COPY A,MSCNT COPY =0,A ADD =:80,A ADD UP BYTE TRANSFER COUNT (128/SECTOR) IMS MSCNT JMP $-2 COPY A,TSTH16 STORE FOR MULTI-SECTOR WRITE (BYTE COUNT) COPY A,TSTH17 STORE FOR MULTI SECTOR READ (BYTE COUNT) SHIFT A,RO,1 MAKE BYTE COUNT INTO WORD COUNT COPY A,TSTH18 STORE FO JMP QURYBD SKIP DEFAULT SETUP FOR MULTI-SECTOR I/O QURYBB COPY =256,A SET UP COPY A,TSTH16 DEFAULT COPY A,TSTH17 VALUES SHIFT A,RO,1 COPY A,TSTH18 COPY =2,A SET UP DEFAULT COPY A,SCTCNT SECTOR COUNT QURYBD JST CHRIN CHECK TERMINATOR JMP QURY6A C/R JMP QUERND # JMP QURYBA BACK ARROW JMP QURY5A UP ARROW NOP NOP NOP JMP QURYBA ROOM WORD 0 MSCNT WORD 0 SCTCNT WORD 0 * * SET UP DEVICE ADDRESS * QUERND EQU $ QUER10 EQU $ JST SETADR JST SEKZ JEQ A,QUER17 IF NO ERROR JST ERRCON  PRINT ERROR JMP MFPD START OVER QUER17 EQU $ COPY SHEAD,A GET STARTING HEAD SHIFT A,LO,7 COPY A,HEAD COPY SUNIT,A GET STARTING UNIT COPY A,UNIT COPY STRK,A GET STARTING TRACK COPY A,TRACK COPY SSCTR,A GET STARTING SECTOR SUB =1,A COPY A,SCTR DECREMENT SECTOR COUNT  JMP MFP20 MASKD WORD :FFF1 DEVICE ADDRESS MASK LPOOL * TEST A - TEST A TEST THE PROPER OPERATION OF * BASIC CONTROLLER. A 128-BYTE OUTPUT * IS ISSUED TO THE CONTROLLER. TRHE * EXPECTED TRANSFER OF 128-BYTE SHOULD BE * INVERTED. THE TEST VERIFIES THE TURN AROUND * OF DATA VIA THE CONTROLLERS FIFO BUFFER. * TESTA ENT COPY ='A',A SET TEST NUMBER SELP A,4 COPY A,TESTNO COPY =-128,A SET BYTE COUNT  COPY A,COUNT COPY =0,X SET X TO ZERO DA10 OUT X,MFADR+0 DEVADDRESS WILL BE OR'ED IN ADD =1,X   INCREMENT VALUE IMS COUNT INCRFEMENT COUNT JMP DA10 FINISHED - NO COPY =-128,A YES  COPY A,COUNT COPY =:FF,A COPY A,TEMP1 DA12 IN MFADR+0,A INPUT VALUE CSK A,TEMP1 NOP JMP TSTA10 > ERROR TSTA5 COPY TEMP1,A = OK SUB =1,A DECRFEMENT A-REG COPY A,TEMP1 IMS COUNT INCREMENT COUNT JMP DA12 LOOP UNTIL FINISHED JMP *TESTA RETURN TO CALLER TSTA10 EQU $ COPY A,MSCMPA ACTUAL COPY TEMP1,A COPY A,MSCMPE EXPECTED COPY =MISCMP,A GET MISCOMPARE ERROR  COPY A,ERRWRD SAVE IN ERROR WORD JST ERRCON JMP TSTA5 LPOOL * * TEST B VERIFIES THE OPERATION OF THE SEEK * FUNCTION. TRACKS 0 TO 35 MAY BE CHECKED * DEPENDING ON OPERATOR SELECTION * STATUS IS CHECKED UPON COMPLETION. * TESTB ENT COPY ='B',A SET TEST NUMBER SELP A,4 COPY A,TESTNO COPY  =SEEKOP,A SET UP OP-CODE COPY A,OPCODE COPY TRACK,A GET TRACK SUB =1,A DECREMENT BY ONE  COPY A,TRACK TSTB5 JST SETUP SET UP CONTROL BLOCK JLT A,TSTB50 TSTB10 JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP BUSY LOOP JST ERRCON EDRROR CONDITION JLT A,TSTB10 RETRY FUNCTGION JMP TSTB5 TSTB50 EQU $ JMP *TESTB RETURN TO CALLER * LPOOL * * TEST C PERFORMS BOTH SEEK AND READ * ADDRESS FUNCTIONS. AFTER EACH SEEK TO THE INDICATED TRACK * IS PERFORMED A READ ADDRESS IS INITIATED. THE *  THE SEEK AND READ ADDRESS ARE BOTH CHECK AND VERIFIED * TESTC ENT COPY ='C',A SET TEST NUMBER SELP A,4  COPY A,TESTNO COPY TRACK,A GET TRACK SUB =1,A DECREMTN BY ONE COPY A,TRACK TSTC10 COPY =SEEKOP,A GET OP-CODE COPY A,OPCODE JST SETUP SET UP CONTROL BLOCK JLT A,TSTC50 FINISHED TSTC15 JST OCBLK OUTPUT BLOCK JST BSYLP BUSY LOOP JST ERRCON IF ERROR CONDITION JLT A,TSTC15 RETRY JNE A,TSTC10 ERROR TSTC20 COPY =RDADOP,A GET READY FOR READ ADDRESS COPY A,OPCODE JST OCBLK SET UP CONTRO BLOCK JST BSYLP SET UP BUSYLOOP JST ERRCON ERROR CONDITION JLT  A,TSTC20 RETRY JNE A,TSTC10 ERROR TSTC30 JST READAD READ 6 BYTES JST ERRCON ERROR CONDITION TSTC35 JMP TSTC10 TSTC50 EQU $ JMP *TESTC RETURN TO CALLER LPOOL * * TEST D CHECK THE PROPER OPERATION OF THE * WRITE DATA, AND READ DATA COMMANDS. * TESTD ENT COPY ='D',A LOAD TEST NUMBER SELP A,4  COPY A,TESTNO COPY SSCTR,A GET STARTING SECTOR SUB =1,A COPY A,SCTR DECREMENT SCTR COUNT TSTD10 COPY =WRITOP,A GET WRITEE OPCODE COPY A,OPCODE JST SETUP SET UP CONTROL BLOCK JLT A,TSTD60 TSTD15 JST OCBLK OUTPUT CONTROL BLOCK COPY =1,A COPY A,FRSTWT JST BSYLP JST ERRCON ERROR CONDITION JLT A,TSTD15 RETRY JNE A,TSTD10 ERROR TSTD20 JST WRTBUF WRITE PATTERN   COPY =0,A COPY A,FRSTWT SET FLAG TO ZERO JST BSYLP JST ERRCON ERROR CONDITION JLT  A,TSTD15 RETRY JNE A,TSTD10 ERROR TSTD30 COPY =REDOP,A GET READ OPERATION COPY A,OPCODE JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP WAIT FOR FINISHED JST ERRCON ERROR CONDITION JLT A,TSTD30 RETRY JNE A,TSTD10 ERROR TSTD40 JST READBF READ BUFFER JST COMPTN COMPARE PATTERN TSTD50 JMP TSTD10 TSTD60 EQU $ COPY =0,A COPY A,FRSTWT JMP *TESTD RETURN TO CALLER LPOOL * * TEST E - CHECKS THE OPERATION OF THE WRITE * DATA AND READ DATA COMMANDS UTILIZING * A UNIQUE PATTERN SELECTED FOR EACH DRIVE HEAD.L * TESTE ENT COPY ='E',A GET TEST NUMBER SELP A,4 COPY A,TESTNO COPY SSCTR,A GET STARTING SECTOR SUB =1,A COPY A,SCTR TSTE10 COPY =WRITOP,A GET WRITE OPERATION CODE  COPY A,OPCODE JST SETUP SET UP CONTROL BLOCK JLT A,TSTE50 IF FINISHED TSTE15 JST OCBLK OUTPUT CONTROL BLOCK COPY =1,A COPY A,FRSTWT JST BSYLP WAIT FOR FINISH JST ERRCON ERROR CONDITION JLT A,TSTE15 RETRY JNE A,TSTE10 TSTE20 JST WRTUPN WRITE UNIQUE PATTERN COPY =0,A COPY A,FRSTWT JST BSYLP BUSY WAIT JST ERRCON ERROR CONDITION JLT A,TSTE15 RETRY JNE A,TSTE10 ERROR TSTE25 COPY =REDOP,A SET UP OPCODE COPY A,OPCODE JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP WAIT FOR FINISHED JST ERRCON ERROR CONDITION JLT A,TSTE25 RETRY JNE A,TSTE10 ERROR TSTE30 JST RDUPTN READ BUFFER JST CMPUPN COMPARE BUFFER JEQ A,TSTE40 JST ERRCON ERROR CONDITION TSTE40 JMP TSTE10 TSTE50 EQU $ COPY =0,A COPY A,FRSTWT JMP *TESTE RETURN TO CALLER LPOOL * * TEST F - CHECKS THE VERIFY FUNCTION * PERFORFMS THE SAME AS READ COMMAND EXCEPT * NO DATA TRANSFER TAKES PLACE * TESTF ENT COPY ='F',A GET TEST NUMB ER SELP A,4 COPY A,TESTNO COPY SSCTR,A GET STARTING SECTOR SUB =1,A DECREMENT SECTOR COPY A,SCTR COPY =VRYFOP,A GET VERIFY OPERATION COPY A,OPCODE TSTF10 JST SETUP SET UP CONTROL OPERATION JLT A,TSTF50 IF FINISHED TSTF15 JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP BUSY LOOP JST ERRCON ERROR CONDITION JLT A,TSTF15 TSTF20 JMP TSTF10 TSTF50 EQU $ JMP *TESTF RETURN TO CALLER * * TEST G CHECKS PROPER EXECUTION OF THE * INTERRUPT FEATURES FOR WRITE DATA, READ DATA * AND READ ADDRESS. * TESTG ENT COPY ='G',A GET TEST NUMBER SELP A,4 COPY A,TESTNO COPY SSCTR,A GET STARTING OPERATION SUB =1,A DECREMENT SECTOR COPY A,SCTR TSTG10 COPY =WRTAU,A SET UP WRITE AUTO I/O COPY A,OPCODE  JST SETUP SET UP CONTROL BLOCK JLT A,TSTG40 TSTG15 JST WAUTO JST OCBLK OUTPUT CONTROL BLOCK  JMP $ * ENTRY POINT FROM EOB WRITE EOBEW EQU $ JST ERRCON ERROR CONDITGION JLT A,TSTG15 RETRY JNE A,TSTG10 ERROR TSTG20 COPY =RRTAU,A GET READ OPERATION AUTO I/O COPY A,OPCODE TSTG25 JST  RAUTO READ AUTO I/OP JST OCBLK JMP $ * ENTRY POINT FROM EOB READ EOBER EQU $ JST ERRCON ERROR CONDITION JLT A,TSTG25 RETRY JNE A,TSTG10 TSTG30 JST COMPBF JST ERRCON ERROR CONDITION JMP TSTG10 TSTG40 EQU $ JMP *TESTG * * TESTH * TESTH ENT COPY ='H',A GET TEST NUMBER SELP A,4 COPY A,TESTNO COPY SSCTR,A GET STARTING SECTOR SUB =1,A DECREMENT COPY A,SCTR AND STORE IN CONTROL BLOCK TSTH10 COPY =WRTAU,A GET WRITE AUTO I/O OPCODE COPY A,OPCODE AND STORE IT JST SETUP SET UP CONTROL BLOCK JLT A,TSTH90 COPY SCTR,A  IS THERE ENOUGH ROOM ADD SCTCNT,A BETWEEN THE CURRENT SECTOR AND THE CLSN =18,A END OF TRACK TO MAKE TEST JMP *TESTH NO,  EXIT TEST WITH NO ERROR COPY =RBUFFR,X GET READ BUFFER ADDRESS COPY ZROBUF,A AND SIZE NEG A,A COPY A,ZROCNT SET UP COUNTER COPY =0,A COPY A,0(X) AND ZERO THE READ BUFFER ADD =1,X IMS ZROCNT JMP $-3 COPY SCTCNT,A SUB =1,A DECREMENT SECTOR COUNT FOR INSERTION OR HEAD,A WITH HEAD BIT AND THEN COPY A,HEAD INSERTIOHN INTO THE CONTROL BLOCK TSTH15 JST MSAUTO SET UP MULTI-SECTOR AUTO OUTPUT TSTH16 WORD 0 BYTE TRANSFER COUNT (STUFFED IN DURING INITIALIZATION) JST OCBLK OUTPUT CONTROL BLOCK  JMP $ WAIT FOR EOB EOBATW EQU $ JST ERRCON ERROR CONDITION? JLT A,TSTH15 RETRY WRITE OPERATION JNE A,TSTH10 ERROR, RETRY ENTIRE TEST TSTH25 COPY =RRTAU,A GET READ AUTO I/O OPCODE COPY A,OPCODE AND STORE IT JST MSAUTI SET UP MULTI-SECTOR AUTO INPUT TSTH17 WORD 0 BYTE TRANSFER COUNT (STUFFED DURING INITIALIZATION) JST OCBLK OUTPUT CONTROL BLOCK JMP $ WAIT FOR EOB EOBATR EQU $ JST ERRCON ERROR CONDITION? JLT A,TSTH25 YES RETRY READ JNE A,TSTH10 ERROR RETRY ENTIRE TEST FOR NEXT SECTOR JST COMPAR COMPARE READ AND WRITE BUFFERS TSTH18 WORD 0 WORDS TO BE COMPARED (STUFFED DURING INITIALIZATION) JST ERRCON ERROR? JMP TSTH10 RETRY TSTH90 EQU $ JMP *TESTH ZROBUF WORD ENDPT-RBUFFR ZROCNT WORD 0 JMP *TESTH * * TGESTI * TESTI ENT JMP *TESTI * * TESTJ * TESTJ ENT JMP *TESTJ * LPOOL * * SAVEP HANDLES CONSOLE INTERRUPT * SAVEP EQU $ * * ENT COPY RESET,A GET RESET COMMAND DA44 OUT A,MFADR+1 RBIT 4,S  OUT A,1 JMP MFPD * * * SETUP * SET UP CONTRO BYTES * * EXIT CONDITION - A-REG MINUS WHEN FINISHED WITH PARAMETE^ *% LIST. * SETUP ENT COPY =0,A INITIALIZE FINISH FLAG COPY A,FINIFG COPY TESTNO,A CLSN ='B',A JMP STUP70 CLSN ='C',A JMP STUP70 IMS SCTR INCREMENT COPY SCTR,A GET CURRENT SECTOR CSK A,ESCTR COMPARE WITH ENTRERED SECTOR JMP STUP50 < NOP  > STUP10 COPY SSCTR,A = RFESTORE BEGINNING COPY A,SCTR SECTOR IMS TRACK COPY  TRACK,A GET CURRENT TRACK STUP12 CSK A,ETRK COMPARE WITH ENDING TRACK JMP STUP50 < NOP   > STUP15 COPY STRK,A = RESTORE TRACK COPY A,TRACK COPY HEAD,A GET CURRENT HEAD ADD =:80,A INCREMENT COPY A,HEAD SHIFT A,RO,7 CSK A,EHEAD COMPARE ENDING HEAD JMP STUP50 < NOP > STUP20 COPY SHEAD,A = RESTOE HEAD SHIFT A,LO,7 COPY A,HEAD IMS UNIT COPY UNIT,A GET UNIT CSK A,EUNIT COMPARE WITH ENDING UNIT JMP STUP50 < NOP > COPY SUNIT,A = RESTORE UNIT  COPY A,UNIT COPY =-1,A SET DONE FLAG COPY A,FINIFG STUP50 COPY =DELAY,A INITIALIZE DELAY COPY A,DED COPY FINIFG,A GET FINISHED FLAG JMP *SETUP RETURN TO CALLER STUP70 IMS TRACK INCREMENT TRACK NOP COPY TRACK,A JMP STUP12 LPOOL * * INIT INITIALIZE ALL PARAMETER TO DEFAULT VALUE * * INITLZ ENT COPY =0,A SET FOR COPY A,FMFLG DIAGNOSTIC * * BUILD DEFAULT WORK TABLE COPY =DTABL,A GET DEFAULT TABLE COPY A,TMPADR SAVE COPY =TESTS,X GET WORK TABLE ADDRESS INIT5 COPY *TMPADR,A COPY A,0(X) SAVE VALUE IMS TMPADR INCREMENT ADDRESS ADD =1,X INCREMENT X-REG JGE A,INIT5 COPY =DSUNT,A SET UP UNIT COPY A,SUNIT DEFAULT COPY A,UNIT COPY =DSCTCN,A SET UP MULTI-SECTOR DEFAULT COUNT COPY A,SCTCNT COPY =DBTRCN,A SET UP MULTI-SECTOR BYTE TRANSFER COUNT ADD =1,A COPY A,TSTH17 COPY A,TSTH16 SHIFT A,RO,1 SET UP COMPARISON WORD TRANSFER COUNT COPY A,TSTH18 COPY =DEUNT,A COPY A,EUNIT  COPY =DSHED,A SET UP HEAD COPY A,SHEAD DEFAULT COPY =DEHED,A COPY A,EHEAD COPY =DSTRK,A SET UP TRACK COPY A,STRK DEFAULT COPY =DETRK,A COPY A,ETRK COPY =DSSCTR,A SET UP SECTOR COPY A,SSCTR DEFAULT COPY =DESCTR,A COPY A,ESCTR COPY =DUPTRN,A GET DEFAULT PATTERN  COPY A,UPATRN COPY =DCNTRL,A COPY A,CNTRL COPY =DNTADR,A COPY A,INTADR SET UP INTERRUP ADDRESS COPY =DDVAD,A GET DEFAULT ADDRESS COPY A,DEVAD COPY =0,A INITIALIZE A-REG COPY A,RETRYC COPY =1,A COPY A,FMAT DEFAULT TO FORMAT ONE COPY =0,A COPY =0,X SET X TO ZERO COPY =SOFT0,Y INIT20 COPY A,0(Y,X) CLSN =7,X JMP INIT25 ADD =1,X JMP INIT20 INIT25 COPY A,HRDSFT COPY RESET,A GET RESET FLAG DA42 OUT A,MFADR+1 JMP *INITLZ RETURN TO CALLER * * DEFAULT TABLE DTABL WORD TESTA DEFAULT TEST TABLE WORD TESTB WORD TESTC WORD TESTD WORD TESTE WORD TESTF WORD TESTG WORD TESTH WORD -1 END OF TABLE * DDVAD  EQU :FC TMPADR WORD 0 * DSCTCN EQU 2 MULTI-SECTOR I/O DEFAULT DBTRCN EQU :FF BYTE TRANSFER COUNT (-1) DEFAULT DSUNT EQU 0 DEFAULT START DEUNT EQU 1 STOP FOR UNIT * DSHED EQU 0 START FOR HEAD DEHED EQU 1 END * DSTRK EQU 0 DEFAULT FOR START TRK DETRK EQU 4 * DSSCTR EQU 1   DEFAULT FOR START SECTOR DESCTR EQU 3 END * DUPTRN EQU :DB DEFAULT PATTERN * DNTADR EQU  :F0 DCNTRL EQU :C INTADR WORD 0 INTERRUPT ADDRESS * * * TSTEND - PERFORMED AT ENBD OF EACH TEST * TSTEND ENT JT SS,END10 IF SENSE ON NO PRINTOUT COPY CNTRL,A ROTATE A,RO,3 JF OV,END10 CVHECK IF TALLIE ON/OFF COPY HRDSFT,A CHECK IF ANYERRORS JEQ A,END20 JST TLYRPT END10 COPY =0,X  COPY =0,A COPY =SOFT0,Y END15 COPY A,0(Y,X) CLSN =7,X JMP END20 ADD =1,X JMP END15 END20 COPY A,HRDSFT SOFT TO NO JMP *TSTEND LPOOL * * READBF - READBF ROUTINE READS 128 BYTES * READBF ENT COPY =-128,A SET UP COUNT COPY A,CNTCNT COPY =REEDB,X GET READ BUF ADDRESS DA26  IN MFADR+0,A INPUT VALUE COPY A,0(X) SAVE IN BUFFER ADD =1,X INCREMENT COUNTYER IMS CNTCNT INCREMENT COUNTER JMP DA26 JMP *READBF LPOOL REEDB RES 128 * * * READAD - READ ADDRESS ROUTINE CHECKS THE * 6 BYTES OF THE READ ADDRESS COMMAND. * AND VERIFIES THE TRACK READAD ENT COPY =-6,A SET CONTROL COUNTER COPY A,CNTCNT COPY =READAB,X SET S-REG TO BUFFER DA18 IN MFADR+0,A GET VALUE COPY A,0(X) ADD =1,X INCREMENT X-REG IMS CNTCNT INCREMENT COUNT JMP DA18 IF NOT DONE LOOP BACK COPY READAB,A CSK A,TRACK CHECK IF TRACK THE SAME JMP RAD10 < IF LESS - ERROR JMP RAD10 > IF GREATER - ERROR COPY READAB+1,A GET ZEROES JNE A,RAD10 IF NOT ZERO - ERROR COPY READAB+3,A GET ZEROES JNE A,RAD10 IF NOT ZEROES ERROR COPY A,ERRWRD RAD5 JMP *READAD  RETURN TO CALLER RAD10 COPY A,MSCMPA ACTUAL COPY TRACK,A COPY A,MSCMPE EXPECTED COPY =MISCMP,A COPY A,ERRWRD  JMP RAD5 LPOOL READAB RES 12,0 LPOOL * * OCTBLK - OUTPUT CONTROL BLOCK * OCBLK ENT COPY =-6,A SET CONTROL COUNT COPY A,CNTCNT COPY =OPCODE,X GET ADDRES OF CONTROL BLOCK OCT10 COPY 0(X),A GET VALUES DA14 OUT A,MFADR+0 OUTPUT VALUE ADD =1,X INCREMENT PINTGER IMS CNTCNT INCREMENT CONTROL COUNTER JMP OCT10 COPY COMAND,A OUTPUT COMMAND DA15 OUT A,MFADR+1 OUTPUT COMMAND JMP *OCBLK  RETURN TO CALLER * * BSYLP BSYLP ROUTINE WAITS FOR * MINI-FLOPPY TO FINISH WITH CONTROL BLOCK * BSYLP ENT DA16  IN MFADR+1,A INPUT STATUS (BUSY CHECK) ROTATE A,RO,2 CHECK BUSY BIT JT OV,DA16 CHECK IF BUSY JLT A,BSY20 COPY =0,A COPY A,ERRWRD BSY15 JMP *BSYLP RETURN TO CALLER BSY20 AND MASK3F,A MASK OFF MOST SIGN. BITS COPY A,ERRWRD JMP BSY15 * MASK3F WORD :3F * * TABLE OF I/O INSTRUCTIONS WHICH REQUEIRE * MODIFICATION WHEN DEVICE ADDRESS IS CHANGED * TABL EQU $ DAFRST EQU $ START OF DA TABLE WORD DA10 USED IN TESTA WORD DA12 USED IN TESTA WORD DA14 USED IN OCTBLK   WORD DA15 WORD DA16 USED IN BSYLP WORD DA18 USED IN READOP WORD DA20  USED IN WRTBUF WORD DA22 USED IN WRTBUF WORD DA24 USED IN WRTBUF WORD DA26 USED IN READBUF WORD DA28 USED IN WRTUPN WORD DA30 USED IN RDUPTN WORD DA32 USED IN EOBW WORD DA34 USED IN EOBR WORD DA36 USED IN SEKZ WORD DA38 USED IN SEKZ WORD DA40 USED IN SEKZ WORD DA42 USED IN INITIALIZE ROUTINE WORD DA44 WORD DA46 WORD DA48 WORD DA50 DALAST EQU $ * * * CMPUPN - CMPUPN ROUTINE COMPARE UNIQUE *  PATTERN TO B UFFER JUST READ IN * CMPUPN ENT COPY UNIT,A GET UNIT COPY A,UPATRN SAVE UNIT STARTING  COPY =-128,A GET COUNTER COPY A,CNTCNT COPY =PTNBUF,X GET BUFFER POINTER CMPU5 COPY 0(X),A CSK A,UPATRN NOP < IF LESS - ERROR JMP CMPU10 > IF GRFEATER - ERROR ADD =1,X = OK IF EQUAL/INCREMENT COUNT IMS UPATRN IMS CNTCNT JMP CMPU5 IF NOT DONE LOOP BACK COPY =0,A JMP *CMPUPN RETURN TO CALLER CMPU10 COPY A,MSCMPA ACTUAL COPY UPATRN,A COPY A,MSCMPE EXPECTED COPY =MISCMP,A COPY A,ERRWRD JMP *CMPUPN RETURN TO CALLER LPOOL * * WRTBUF - WRTBUF ROUTINE WRITES * 128 BYTE PATTERN * WRTBUF ENT COPY WCPAT,A GET PATTERN SHIFT A,RO,8 SHIFT TO LEFT BYTE JNE A,WRT10  IF A NON-ZERO COPY WCPAT,A ELSE SAVE LEFT BYTE WRT10 COPY A,WCPAT1 COPY =-64,A COPY A,CNTCNT WRT15 COPY WCPAT,A GET PATTERN DA20 OUT A,MFADR+0 OULTPUT VALUE COPY WCPAT1,A DA22 OUT A,MFADR+0 OUTPUT VBALUE IMS CNTCNT INCRFEMENT COUNT JMP WRT15 COPY COMAND,A OUTPUT COMMAND DA24 OUT A,MFADR+1 OUTPUT COMMAND JMP *WRTBUF RETURN TO CALLER LPOOL * * COMPTN ROUTINE COMPARE BUFFER * RERAD IN WITH PATTERN SELECTED BY USER * COMPTN ENT COPY =REEDB,X COPY =-64,A COPY A,CNTCNT SET WORD CUNTER COPY 0(X),A GET VALUE COMP10 CSK A,WCPAT CHECK AGAINST PATTERN JMP COMP20 < IF LESS - ERROR  JMP COMP20 > IF GREATER - ERROR COMP12 COPY 1(X),A = CSK A,WCPAT1 JMP COMP30 JMP COMP30 > IF GFREATER ERROR COMP14 ADD =1,X = INCREMENT X-REG IMS CNTCNT INCREMENT CONTROL COUNTER  JMP COMP10 JMP *COMPTN RETURN TO CALLER COMP20 COPY A,MSCMPA ACTUAL COPY WCPAT,A COPY A,MSCMPE EXPECTED  COPY =CMPERR,A COPY A,ERRWRD JST ERRCON ERROR CONDITION JMP COMP12 COMP30 COPY A,MSCMPA ACTUAL COPY WCPAT1,A COPY A,MSCMPE EXPECTED COPY =CMPERR,A COPY A,ERRWRD JST ERRCON ERROR CONDITION JMP COMP14 LPOOL * * SETADR - SET UP DEVICE ADDRESS * SETADR ENT COPY DEVAD,A SET DEVICE ADDRESS  COPY A,TEMP1 COPY =DAFRST-DALAST,A IF END OF TABLEW COPY A,TEMP2 COPY =TABL,A GET TABLE   COPY A,TEMP3 SET15 COPY *TEMP3,X GET ADDRESS COPY 0(X),A AND MASKD,A OR TEMP1,A COPY A,0(X) IMS TEMP3 IMS TEMP2 JMP SET15 JMP *SETADR RETURN TO CALLER TEMP3 WORD 0  LPOOL * * SEKZ - SEEK TO ZERO ROUTINE * INITIALIZE DISK * SEKZ ENT COPY SUNIT,A GET STARTING UNIT COPY A,TUNIT SAVE IN TEMP UNIT SEK5 COPY TUNIT,A IMS TUNIT COPY A,SEKTBL+1 SAVE IN TABLE COPY =-6,A SET BLOCK COUNTY COPY A,CNTCNT COPY =SEKTBL,X GET TABLE ADDRESS SEK10 COPY 0(X),A DA36 OUT A,MFADR+0 OUTPUT VALUE ADD =1,X INCREMENT REG IMS CNTCNT INCREMENT COUNT JMP  SEK10 LOOP UNTIL FINISHED COPY 0(X),A GET COMMAND WORD DA38 OUT A,MFADR+1 OUTPUT COMMAND DA40 IN MFADR+1,A ROTATE A,RO,2 SHIFT TO CHECK BUSY BIT JT OV,DA40 IF BUSY LOOP BACK JLT A,SEK50 IF ERROR COPY TUNIT,A GET TEMP UNIT CSK A,EUNIT COMPARE WITH ENDING UNIT JMP SEK5 IF LESS KEEP GOING NOP COPY =0,A ZERO ERROR FLAG JMP *SEKZ RETURN TO CALLER SEK50 AND MASK3F,A MASK OFF MSB COPY A,ERRWRD COPY ='S',A COPY A,TESTNO COPY ERRWRD,A GET ERROR WORD JMP *SEKZ RETURN TO CALLER * SEKTBL WORD 9 OPCODE WORD 0 UNIT WORD 0 TRACK WORD 0 WORD 0 SECTOR WORD 1 DELAY WORD :200 COMMAND TUNIT WORD 0 TEMP UNIT LPOOL * * FORMAT * FORMAT EQU $ JMP FQURY QUERY SECTION FMT1  COPY SUNIT,A GET STARTING UNIT COPY A,UNIT COPY SHEAD,A GET STARTING HEAD SHIFT A,LO,7 SHIFT TO BIT 7 COPY A,HEAD COPY FMAT,A GET FORMAT OPCODE COPY A,OPCODE COPY =1,A SET DELAY INDICATOR COPY A,DED SET UP DELAY COPY =0,A COPY A,RETRYC JST SETADR SET UP DEVICE ADDRESS FMT5 JST OCBLK OUTPUT BLOCK JST BSYLP BUSY LOOP COPY ERRWRD,A GET ERROR WORD JEQ A,FMT10 IF NO ERROR CLSN =:E,A IF CONTROLLER JMP FMT20 ERROR RETRY FMT7 COPY =1,A COPY A,PASSNO COPY A,TESTNO JST ERROR PRITN ERROR MESSAGE JMP MFP10 FMT10 COPY HEAD,A INCREMENT HEAD  ADD =:80,A COPY A,HEAD SHIFT A,RO,7 CSK A,EHEAD CHECK FOR ENDING HEAD JMP FMT5 NOP > IF GREATER COPY SHEAD,A = IF EQUAL SHIFT A,LO,7 COPY A,HEAD IMS UNIT INCREMENT UNIT  COPY UNIT,A CSK A,EUNIT CHECK FOR ENDING UNIT JMP FMT5 < NOP > COPY SUNIT,A COPY A,UNIT * VERIFY ALL FORMATS JST FMT50 JST MSGA PRINT MESSAGE WORD COMPLT JMP MFP10 FMT20 EQU $ IMS RETRYC INCREMENT RETRY FLAG COPY RETRYC,A GET RETRY FLAG CLSN =5,A CHECK IF FIVE RETRIES JMP FMT7 JMP FMT5 * VERIFY ALL FORMATS FMT50 ENT COPY SUNI  T,A GET STARTING UNIT COPY A,UNIT FMT51 COPY SHEAD,A GET STARTING HEAD SHIFT A,LO,7 ADD =15,A SET UP SECTOR COUNT TO VERIFY A FULL TRACK COPY A,HEAD COPY =VRYFOP,A GET VERIFY OPERATION CODE COPY A,OPCODE FMT52  COPY =0,A COPY A,TRACK INITIALIZE TGRACK FMT53 COPY =1,A GET DELAY INDICATOR COPY A,DED COPY A,SCTR FMT55 JST OCBLK OUTPUT BLOCK JST BSYLP BUSY LOOP COPY ERRWRD,A GET ERROR WORD  JEQ A,FMT70 IF NO ERROR JMP FMT7 FMT70 IMS TRACK COPY TRACK,A SELP A,4 CSK A,LSTTRK  COMPARE WITH LAST TRACK JMP FMT53 < IF LESS NOP > IF GREATER COPY HEAD,A ADD =:80,A INCREMENT HEAD COPY A,HEAD SHIFT A,RO,7 CSK A,EHEAD CHECK FOR LAST HEAD JMP FMT52 < IF LESS NOP  > IF GREATER IMS UNIT COPY UNIT,A GET UNIT CSK A,EUNIT COMPARE WITH ENDING UNIT  JMP FMT51 < IF LESS NOP > IF GREATER NOP = IF EQUAL JMP *FMT50 * LSTSCT WORD 17 LAST SECTOR LSTTRK WORD 35 LAST TRACK * * COMPLT WORD :8D8A CRLF BYTE  'FORMAT COMPLETE ' WORD -1 LPOOL * * FQURY - FORMAT QUERY * FQURY EQU $ JST MSGA ASK FOR FORMAT WORD FQURYA COPY =0,A COPY A,TEMP4 SET TEMP4 TO ZERO JST IDEC JEQ X,FQRY1K COPY X,A CSK A,H2 CHECK IF OVER TWO JMP $+2 JMP FQURY COPY X,FMAT FQRY1C JST CHRIN CHECK TERMINATOR JMP FQRY2A C/R JMP FMT1 # JMP FQURY BACK ARROW  JMP QUERY UP ARROW JMP FQURY JMP FQURY NOP JMP FQURY FQRY1K COPY IDCTM3,A JEQ A,FQRY1C IF ZERO CONTINUE COPY =0,X JMP FQRY1C LPOOL LPOOL * * ASK FOR UNITS * FQRY2A EQU $ JST MSGA WORD FQURYB ASK FOR UNIT COPY =0,A COPY A,TEMP4 FQRY2C JST IDEC GET INPUT JEQ X,FQRY2J COPY X,A CSK A,H3 MUST BE IN RANGE /-3 JMP $+2 JMP FQRY2A RANGE ERROR FQRY2E EQU $ COPY TEMP4,A CLSN =0,A COPY X,SUNIT SAVE STARTING UNIT  ADD =1,X COPY X,EUNIT IMS TEMP4 COPY SUNIT,A MAKE SUJRE ENDING CSK A,EUNIT UNIT IS ASCENDING ORDER JMP FQRY2F IF LESS - OK NOP JMP FQRY2A FQRY2F JST CHRIN CHECK TGERMINATOR JMP FQRY3A C/R JMP FMT1 # JMP FQRY2A BACK ARROW JMP FQURY UP ARROW  JMP FQRY2C COMMA JMP FQRY2A NOP JMP FQRY2A FQRY2J COPY IDCTM3,A JEQ A,FQRY2F COPY =0,X JMP FQRY2E LPOOL * * ASK FOR HEAD * FQRY3A EQU $ JST MSGA ASK FOR HEAD  WORD FQURYC COPY =0,A COPY A,TEMP4 FQRY3C JST IDEC GET INPUT JEQ X,FQRY3K COPY X,A CSK A,H1 MUST BE /, OR 1 JMP FQRY3E < JMP FQRY3A > FQRY3E COPY TEMP4,A = C LSN =0,A COPY X,SHEAD CLSN =1,A COPY X,EHEAD IMS TEMP4 FQRY3F JST CHRIN CHECK TERMINAOT JMP FQRY4A C/R JMP FMT1 # JMP FQRY3A BACK ARROW JMP FQRY2A UP ARROW  JMP FQRY3A COMMA NOP NOP JMP FQRY3A FQRY3K COPY IDCTM3,A JEQ A,FQRY3F CHECK IF ZERO OR NO COPY =0,X JMP FQRY3E LPOOL * * DEVICE ADDRESS * FQRY4A EQU $ JST MSGA ASK FOR DEVICE ADDRESS WORD FQURYD JST IHEX GET INPUT JEQ X,FQRY4K IF ZERO SEE WHY COPY X,A SHIFT A,RO,8 JNE A,FQRY4A ILLEGAL INPUT COPY X,DEVAD FQRY4C JST CHRIN JMP FMT1 C/R JMP FMT1 # JMP FQRY4A JMP FQRY3A UP ARROW NOP NOP NOP JMP FQRY4A FQRY4K COPY IDCTM3,A GET ACTUAL INPUT COUNT JEQ A,FQRY4C JMP FQRY4A LPOOL * FQURYA WORD :8D8A BYTE ' FORMAT (35T=1 OR 40T =2) - (1) = ' WORD -1 * FQURYB WORD :8D8A BYTE ' UNIT (0) = ' WORD -1 * FQURYC WORD :8D8A BYTE ' HEAD (0) = ' WORD -1 * FQURYD WORD :8D8A BYTE ' DEV ADR (:FC) = '  WORD -1 LPOOL * * ERRCON - ERROR CONDITION ROUTINE * 1). CHECKS IF PRINT SELECTION IS ON * 2). TALLIES SOFT/HARD ERRORS * 3). RETRIES IF NECESSARY * EXIT * A-REG - MINUS - RETRY * ZERO - GOOD * NON-ZERO - ERROR * ERRCON ENT CLSN =:F,A MISCOMPARE ERROR? JMP $+4 YES, GO SET MISCOMPARE FLAG COPY =0,A NO, RESET MISCOMPARE FLAG COPY A,MSCMPF JMP $+3 COPY =1,A COPY A,MSCMPF COPY ERRWRD,A GET ERROR FLAG JNE A,ERR10 COPY RETRYF,A GET RETRY FLAG JNE A,ERR50 CHECK IF RETRY FLAG ON JMP ERR90 DONE ERR10 EQU $  COPY =:8000,A TURN ON OR TESTNO,A SELP A,4 TO CONSOLE JT SS,ERR20 IF SENSE SWITCH ON NO PRINT OUT COPY CNTRL,A CHECK CONTROL WORD ROTATE A,RO,1 CHECK BIT ONE JF OV,ERR12 IF RESET SKIP JMP ERR20 ERR12 ROTATE A,RO,1 CHECK IF REPORT TO PRINTED JT OV,ERR20 JST ERROR ERROR SUBROUTINE ERR20 EQU $ CHECK COPY ERRWRD,A FOR POTENTIAL CLSN =3,A SOFT WARE JMP  ERR25 ERROR CLSN =5,A JMP ERR25 CLSN =6,A JMP ERR25 ERR22 EQU $ COPY *UNITPT,X GET UNIT COPY =HARD0,Y IMS 0(Y,X) INCREMENT HARD ERROR COPY =1,A COPY A,HRDSFT SET HRD SFT ERROR JMP ERR95 ERR25 JST SEKZ JEQ A,ERR27 SHIFT A,LO,8 SHIFT A,LO,4 OR TESTNO,A OR IN TEST NUMBER SELP A,4 JMP MFPD ERR27 IMS SFTCNT COPY SFTCNT,A CLSN =3,A CHECK FOR THREE ERROR JMP ERR29 JMP ERR30 ERR29 EQU $ COPY =0,A RESET ERROR COUTN COPY A,SFTCNT COPY A,RETRYF RESET RETRY FLAG JMP ERR22 ERR30 COPY =-1,A SET RETRY FLAG  COPY A,RETRYF JMP ERR95 ERR50 EQU $ COPY FRSTWT,A CHECK IF JNE A,ERR90 FIRST WORD COP Y *UNITPT,X COPY =SOFT0,Y IMS 0(Y,X) INCREMENT SOFT ERROR COPY =1,A COPY A,HRDSFT SET FLAG COPY =0,A COPY A,RETRYF INITIALIZE RETRY FLAG COPY A,SFTCNT AND SOFT COUNT ERR90 COPY =0,A SET A-REG TO ZERO * ERR95 JMP *ERRCON RETURN TO CALLER UNITPT WORD UNIT LPOOL * * ERRPT PRINTS DETAIL ERROR LINE * FORMAT * PASS :DDDD TEST BB ERR DD * * CALLING SEQUENCE * JST ERRPT * DATA PASS * DATA TEST * DATA ERROR * DATA TRACK * DATA SCTR * DATA HEAD * ERRPT ENT JST ASCOUT PRINT PASS WORD 7 WORD ERRH1 PASS COPY *ERRPT,X IMS ERRPT INCREMENT PARAMETER  COPY 0(X),A JST DCMLOT DDDD JST ASCOUT TEST WORD 6 WORD ERRH2 COPY *ERRPT,X IMS ERRPT INCREMENT PARAMETER COPY 0(X),A JST OTT JST ASCOUT ERR WORD 6 WORD ERRH3 COPY *ERRPT,X IMS ERRPT INCREMENT PARAMETER COPY 0(X),A JST HEXOUT JST ASCOUT PRINT UNIT WORD 6 WORD ERRH15 COPY UNITPT,X COPY 0(X),A JST DCMLOT JST ASCOUT PRINT TRACK  WORD 6 WORD ERRH8 COPY *ERRPT,X IMS ERRPT INCREMENT POINTER COPY 0(X),A  JST DCMLOT DDDD JST ASCOUT PRINT SCTERR WORD 7 WORD ERRH9 COPY *ERRPT,X IMS ERRPT COPY 0(X),A GET SECTOR JST DCMLOT PRINT HEAD JST ASCOUT WORD 7 WORD ERRH10 COPY *ERRPT,X IMS ERRPT COPY 0(X),A COPY A,SCTSAV SAVE SECTOR COUNT AND =:80,A ISOLATE HEAD BIT SHIFT A,RO,7 GET TO LOW ORDER JST DCMLOT OUTPUT HEAD JST ASCOUT PRINT SECTOR COUNT WORD 11 WORD ERRH20 COPY SCTSAV,A RESTORE SECTOR COUNT AND =:F,A ISOLATE SECTOR COUNT JST DCMLOT OUTPUT SECTOR COUNT COPY MSCMPF,A WAS THIS A MISCOMPARE ERROR? JNE A,$+2 YES JMP *ERRPT NO,RETURN JST ASCOUT PRINT ACTUAL WORD 14 WORD ERRH14 COPY MSCMPA,A GET ACTUAL WORD JST HEXOUT AND OUTPUT IT JST ASCOUT PRINT EXPECTED WORD 14 WORD ERRH13 COPY MSCMPE,A GET EXPECTED WORD JST HEXOUT AND OUTPUT IT JMP *ERRPT RETURN MSCMPF WORD 0 MSCMPA WORD 0 MSCMPE WORD 0 SCTSAV WORD 0 LPOOL * * ERROR - ERROR REPORT * ERROR ENT RBIT 8,S DISABLE INTERRUPT ERROR5 EQU $ JST ERRPT PRINT OUT REPORT WORD PASSNO WORD TESTNO WORD ERRWRD WORD TRACK WORD SCTR WORD HEAD ERROR7 EQU $ SBIT 8,S ENABLE INTERRUJPT JMP *ERROR RETURN TO CALLER * * TLYRPT - PRINTS TOTAL ERROR HARD AND SOFT * FOR EACH UNIT * TLYRPT ENT RBIT 8,S DISABLE INTERRUPTS JST ASCOUT WORD 10  WORD ERRH4 COPY TESTNO,A SET TEST NUMBER JST OTT PRINT OUT JST ASCOUT WORD 18  WORD ERRH5 COPY SUNIT,A GET UNIT COPY A,TEMPU SAVE IN TEMPARIRY TLY5 CSK A,EUNIT ECHECK FOR ENDING UNIT JMP TLY10 < IF LESS NOP > IF GREATER JMP TLY50 = TLY10 EQU $   JST ASCOUT WORD 10 WORD ERRH6 COPY *TEMPUP,A PRINT OUT UNIT JST DECOUT JST  ASCOUT WORD 3 WORD ERRH7 COPY *TEMPUP,X GET TREMPARY UNIT COPY =SOFT0,Y COPY  0(Y,X),A JST DECOUT JST ASCOUT WORD 3 WORD ERRH7 COPY *TEMPUP,X COPY =HARD0,Y COPY 0(Y,X),A JST DECOUT IMS *TEMPUP INCREMENT TEMP UNIT COPY *TEMPUP,A LOAD THE UNIT JMP TLY5 TLY50 EQU $ SBIT 8,S JMP *TLYRPT TEMPUP WORD TEMPU LPOOL * SOFT/HARD ERROR COUNT * SOFT0 WORD 0 SOFT1 WORD 0 SOFT2 WORD 0 SOFT3 WORD 0 HARD0 WORD 0 HARD1 WORD 0 HARD2 WORD 0 HARD3 WORD 0 RETRYF WORD 0 0=NO RETRY 1 = RETYRY ON SFTCNT WORD 0 * ERRH0 WORD :A0A0 BLANKS * ERRH1 WORD :8D8A CRLF BYTE 'PASS ' * ERRH2 BYTE ' TST ' * ERRH3 BYTE ' ERR ' * ERRH4 WORD :8D8A  BYTE ' TEST ' * ERRH5 BYTE ' U SOFT HARD ' * ERRH6 WORD :8D8A BYTE ' ' ERRH7 BYTE ' ' * ERRH8 BYTE ' TRK ' * ERRH9 BYTE ' SCTR ' * ERRH10 BYTE ' HEAD ' ERRH13 WORD :8D8A BYTE 'EXPECTED ' ERRH14 WORD :8D8A BYTE 'ACTUAL ' ERRH15 BYTE ' UNT ' ERRH20 BYTE ' SCTR CNT ' * * IHEX - ACCEPTS INPUT THROUGH THE TTY OF A * HEX VALUE, WHICH IT RETURN IN THE X-REG. * THE ROUTINE IS EXITED UPON INPUT OF THE * FIRST NON-HEX ASCII CHARACTER, WHICH IT * RETURN IN THE A-REG. * IHEX ENT INPUT HEX VALUE (4-DIGIT) COPY =0,A CLEAR VALUE AREA  COPY A,IDCTM1 COPY A,IDCTM3 AND COUNT IHEX3 JST IKB GET A CHAR COPY A,IDCTM2 SAVE IT  SUB HB0,A CHECK FOR HEX JLT A,IHEX4 TERMINATOR SUB H9,A JLE A,IHEX1 ITS /-9 SUB H9,A ADD =1,A JLT A,IHEX4 TERMINATE SUB H5,A JGT A,IHEX4 TERMINATOR ADD HF,A IT A-F IHEX2 COPY A,IDCTM2 SAVE HEX CHAR COPY IDCTM1,A INCLUDE IT IN VALUE SHIFT A,LO,4  OR IDCTM2,A COPY A,IDCTM1 IMS IDCTM3 BUMP COUNT JMP IHEX3 GET NEXT CHAR IHEX1 ADD  H9,A HEX 0-9 JMP IHEX2 IHEX4 COPY IDCTM2,A LOAD TERMINATOR INTO A COPY IDCTM1,X LOAD VALUE IN X  JMP *IHEX RETURN H2 WORD 2 H5 WORD 5 HEX CONSTANT H9 WORD 9 HEX CONSTANT HF WORD :F HEX CONSTANT LPOOL * * TECH TEST * * TECHT EQU $ COPY ='T',A SET T INDICATOR COPY A,TESTNO SELP A,4 OUTPUT TO CONSOLE JMP TECQER TECH QUERIES TECH01 EQU $  JST SETADR SET UP DEVICE ADDRESS JST SEKZ JEQ A,TECH03 SHIFT A,LO,8 SHIFT A,LO,4 OR TESTNO,A SELP A,4 TECH03 EQU $ COPY =SEEKOP,A GET SEEK OPCODE COPY =1,A SET DELAY COPY A,DED TECH05 COPY STRK,A GET STARTING TRACK COPY A,TRACK COPY SSCTR,A GET STARTING SECTOR COPY A,SCTR COPY TECHNO,A GET TECH TEST JNE A,TECH30 COPY =SEEKOP,A COPY A, OPCODE TECH10 JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP BUSY LOOP COPY ERRWRD,A GET ERROR WORD  JNE A,TECH20 COPY TESTNO,A GET TEST NUMBER TECH15 SELP A,4 IMS TRACK INCREMENT TRACK COPY TRACK,A GET TRACK CSK A,ETRK CHECK IF ENDING TRACK JMP TECH10 < NOP >  JMP TECH05 = TECH20 EQU $ SET ERROR FLAG ON SHIFT A,LO,8 SHIFT A,LO,4 OR TESTNO,A JMP TECH15 TECH30 EQU $ COPY TECHNO,A GET TECH TEST CLSN =2,A JMP TECH70 COPY =REDOP,A LOAD READ OPERATIN COPY A,OPCODE TECH35 JST OCBLK OUTPUT CONTROL BLOCK JST BSYLP BUSY LOOP  COPY ERRWRD,A GET ERROR WORD JNE A,TECH40 JST READBF READ BUFFER JST COMPTN COPY ERRWRD,A JNE A,TECH40 TECH38 SELP A,4 OUTPUT TO CONSOLE JST SETUP SET UP CONTROL BLOCK JLT A,TECH30 JMP TECH35 TECH40 EQU $ SET ERROR FLAG SHIFT A,LO,8 SHIFT A,LO,4 OR TESTNO,A JMP TECH38 TECH70 EQU $ COPY =WRITOP,A GET WRITE OPERATION COPY A,OPCODE TECH75 JST OCBLK OUTPUT BLOCK JST BSYLP COPY ERRWRD,A GET ERROR WORD JNE A,TECH80 JST WRTBUF WRITE BUFFER JST BSYLP BUSY LOOP COPY ERRWRD,A GET ERROR WORD JNE A,TECH80 COPY TESTNO,A GET TEST NUMBER TECH78 SELP A,4 OUTPUT CONSOLE JST SETUP JLT A,TECH30 JMP TECH75 TECH80 EQU $ SET ERROR CODE SHIFT A,LO,8 SHIFT A,LO,4 OR TESTNO,A SELP A,4 OUTPUT TO CONSOLE JMP TECH78 LPOOL * * TECQER - TEST TECH QUERIES * TECQER EQU $ JST MSGA PRINT MESSAGE WORD TECHH1 F = TQUR1A JST IDEC JEQ X,TQUR1K COPY X,A CSK A,H2 COMPARE WITH TWO JMP TQUR1C < JMP TQUR1A TQUR1C COPY X,TECHNO SAVE TECH NO JST CHRIN CHECK TERMINATOR JMP TQUR2A C/R JMP TQUR2A JMP TECQER+1 BACK ARROW JMP TECHT NOP NOP  NOP JMP TECQER+1 TQUR1K COPY IDCTM3,A CHECK FOR ACTUAL ZERO JEQ A,TECQER+1 COPY =0,X JMP TQUR1C * TQUR2A EQU $ JST MSGA PRINT MESSAGE WORD TECHH2 N= TQUR2B JST IDEC GET VALUE JEQ X,TQUR2K COPY X,A CSK A,H3 COMPARE WITH THREE JMP TQUR2C < IF LESS JMP TQUR2A > IF GREATER TQUR2C COPY X,UNIT = JST CHRIN CHECK TERMINATOR JMP TQUR3A C/R  JMP TQUR3A # JMP TQUR2A BACK ARROW JMP TECHT UP ARROW NOP NOP NOP JMP  TQUR2A TQUR2K COPY IDCTM3,A CHECK ACTUAL VALUE JEQ A,TQUR2A COPY =0,X JMP TQUR2C LPOOL * * TQUR3A * TQUR3A EQU $ JST MSGA PRINT MESSSAGE WORD TECHH3 D = JST IHEX  GET INPUT JEQ X,TQUR3K GET INPUT COPY X,A SHIFT A,RO,8 JNE A,TQUR3A ILLEGAL INPUT   COPY X,DEVAD TQUR3C JST CHRIN CHECK TERMINATOR JMP TQUR3M C/R JMP TQUR3M JMP TQUR3A  BACK ARROW JMP TQUR2A UP ARROW NOP NOP NOP JMP TQUR3A JMP TQUR2A TQUR3K COPY IDCTM3,A JEQ A,TQUR3A JMP TQUR3A TQUR3M EQU $ TQUR4A EQU $ JST MSGA PRINT MESSAGE WORD  TECHH4 PATRN JST IHEX GET HEX JEQ X,TQUR4K TQUR4C COPY X,WCPAT SAVE PATTERN JST CHRIN CHECK TERMINATOR JMP TQUR5A C/R JMP TQUR5A # JMP TQUR4A BACK ARROW JMP TECQER+1 UP ARROW NOP NOP NOP JMP TQUR4A TQUR4K COPY IDCTM3,A JEQ A,TQUR4A COPY =0,X JMP TQUR4C LPOOL * * TQUR5A * TQUR5A EQU $ JST MSGA PRINT MESSAGE WORD TECHH5 SCTR COPY =0,A COPY A,TEMP4 TQUR5C JST IDEC JEQ X,TQUR5K COPY X,A CSK A,H17 COMPARE WITH 17 JMP TQUR5E < JMP TQUR5A > JMP TQUR5A TQUR5E COPY TEMP4,A  CLSN =0,A CHECK IF ZERO COPY X,SSCTR STORE STARTING SECTOR ADD =1,X COPY X,ESCTR SAVE ENDING SECTOR IMS TEMP4 JST CHRIN TERMINATOR JMP TQUR6A C/R JMP TQUR6A @  JMP TQUR5A BACK ARROW JMP TQUR4A UP ARROW NOP NOP NOP JMP TQUR5A TQUR5K COPY IDCTM3,A CHECK VALUE JEQ A,TQUR5A COPY =0,X JMP TQUR5E LPOOL * * TQUR6A * TQUR6A EQU  $ JST MSGA PRINT MESSAGE WORD TECHH6 TRACK COPY =0,A COPY A,TEMP4 JST  IDEC JEQ X,TQUR5K COPY X,A CSK A,H40 COMPARE WITH 40 JMP TQUR6E < IF ESS  JMP TQUR6A > IF GREATER JMP TQUR6A TQUR6E COPY TEMP4,A CLSN =0,A CHECK FOR ZERO COPY X,STRK SAVE START TGRACK ADD =1,X COPY X,ETRK IMS TEMP4 INCRFEMENT JST CHRIN TERMINATOR JMP TQUR6M C/R JMP TQUR6M @ JMP TQUR6A JMP TQUR5A NOP NOP NOP JMP TQUR6A TQUR6K COPY IDCTM3,A JEQ A,TQUR6A COPY =0,X JMP TQUR6E TQUR6M JMP TECH01 RETURN TO CALLER * TECHH1 WORD :8D8A BYTE ' F = ' WORD -1 * TECHH2 WORD :8D8A BYTE ' N = '  WORD -1 * TECHH3 WORD :8D8A BYTE ' D = ' WORD -1 * TECHH4 WORD :8D8A BYTE ' PATN = '  WORD -1 * TECHH5 WORD :8D8A BYTE ' SCTR = ' WORD -1 * TECHH6 WORD :8D8A BYTE ' TRACK = ' WORD -1 * * * MSGA - OUTPUT AN ASCII MESSAGE TO THE * TELETYPE. CALLING SEQUENCE * JST MSGA (CALL ROUTINE) * DATA (ADDRESS OF ASCII MESSAGE * LAST CHAR = :FF * * MSGA ENT COPY A,MSGA4 SAVE A-REG COPY X,MSGA3 SAVE X-RFEG COPY *MSGA,X GET MSG ADDRESS SHIFT X,LO,1 IMS MSGA BUMP FOR RETURN MSGA1 SBIT 2,S COPYB 0(X),A GETG A BYTE RBIT 2,S CLSN =:FF,A IS IT END?? JMP MSGA2   YESX EXIT JST OTT ADD =1,X BUMP PTR JMP MSGA1 GET NEXT CHAR MSGA2 COPY MSGA3,X RESTORE X COPY MSGA4,A RESTORE REG A JMP *MSGA EXIT MSGA3 WORD 0 SAVE X-REG MSGA4 WORD 0 SAVE A-REG LPOOL * * IDEC - ACCEPTS INPUT FROM THE TTY OF * AN ASCII-DECIMAL VALUE, WHICH IT CONVERTS TO * BINARY AND RETURN IT IN X-REG. THE * ROUTINE IS EXITED UPON INPUT OF FIRST * NON-ASCII-DECIMAL CHARACTER, WHICH IT * RETURN IN THE A-REG. * IDEC ENT INPUT A DECIMAL VALUE IDEC4 COPY =0,A CLEAR CELL  COPY A,IDCTM1 COPY A,IDCTM3 IDEC3 JST IKB GET A CHJAR COPY A,IDCTM2 SAVE IT SUB HB0,A SEE IF ASCII 0-9 JLT A,IDEC1 TERMINATOR SUB HA,A JGE A,IDEC1 IMS IDCTM3 BUMP COUNT COPY IDCTM1,A ADD TO VALUE SHIFT A,LO,2 ADD IDCTM1,A SHIFT A,LO,1 ADD IDCTM2,A ADD NEW VALUE SUB HB0,A LESS ASCII JLT A,IDEC2 MINUS IS ERROR COPY A,IDCTM1 STORE NEW VALUE JMP IDEC3 IDEC1 COPY IDCTM2,A GET VALUE COPY IDCTM1,X GET TERMINATOR IN X JMP *IDEC EXIT IDEC2 COPY =:BF,A ERROR JST OTT OUTPUT (?) JMP IDEC4 START OVER IDCTM1 WORD 0  VALUE IDCTM2 WORD 0 ASCII CHAR ALL IDCTM3 WORD 0 COUNT HB0 WORD :30 ASCII FORMAT HA WORD :A ASCII FORMAT * * TEST ADDRESS TABLE * * (TEMP WORKING TABLE) * PRAMS EQU $ START OF TEMP PARAM TABLE TESTS WORD TESTA WORD TESTB WORD TESTC WORD TESTD  WORD TESTE WORD TESTF WORD TESTG WORD TESTH WORD TESTI WORD TESTJ WORD -1 END * * TEST (RESET PARAM TABLE) * * PRAMSX EQU $ START OF PARAM TABLE TESTSX WORD TESTA WORD TESTB WORD TESTC WORD TESTD WORD TESTE WORD TESTF WORD TESTG  WORD TESTH WORD TESTI WORD TESTJ WORD -1 END PRAMND EQU $ * * RDUPTN - RDUPTN ROUTINE READS 128 * BYTES OF UNIQUE DATA * RDUPTN ENT COPY =-128,A SET UP BYTE COUNTER COPY A,CNTCNT COPY =PTNBUF,X DA30 IN MFADR+0,A INPUT FROM FLOPPY COPY A,0(X) SAVE IN BUFFER ADD =1,X  INCREMENT BUFFER POINTER IMS CNTCNT REDUCE COUNT JMP DA30 IF NOT DONE LOOP BACK JMP *RDUPTN RETURN TO CALLER LPOOL * * WRTUPN - WRTUPN ROUTINE WRITES A * UNIQUE PATTERN TO DISK * WRTUPN ENT  COPY UNIT,A PICK UP UNIT COPY A,UPATRN SAVE IN UNIQUE PATTERN COPY =-128,A SET UP FOR 128 BYTES  COPY A,CNTCNT WRTU10 COPY UPATRN,A GBET UNIQUE PATTERN DA28 OUT A,MFADR+0 OUTPUT PATTERN IMS UPATRN INCREMENT UNIQUJE PATTERN IMS CNTCNT BYTE CONTROL LOOP JMP WRTU10 IF DONE COPY COMAND,A DA50 OUT A,MFADR+1 JMP *WRTUPN RETURN TO CALLER LPOOL * * * MSAUTO - MULTI-SECTOR AUTO I/O BLOCK FOR OUTPUT * * MSAUTO E NT COPY INTADR,A GET INTERRUPT ADDRESS COPY A,INTLOC AND SAVE COPY AOBM,A GET AUTO I/O INSTRUCTION OR DEVAD,A AND OR IN DEVICE ADDRESS COPY A,*INTLOC STORE IN INTERRUPT LOCATION COPY *MSAUTO,A LOAD BYTE COUNT NEG A,A IMS MSAUTO INCREMENT FFOR RETURN IMS INTLOC COPY A,*INTLOC SET UP BYTE COUNT COPY MSAU10,A LOAD TRANSFER START ADDRESS -1 IMS INTLOC COPY A,*INTLOC STOREW TRANSFER START ADDRESS -1 IMS INTLOC IMS INTLOC COPY JSTINS,A LOAD COPY A,*INTLOC AND STORE JST INSTRUCTION COPY MSWEOB,A LOAD EOB ADDRESS FOR MS WRITE IMS INTLOC COPY A,*INTLOC AND STORE IT SBIT 8,S TURN ON INTERRUPTS JMP *MSAUTO  AND RETURN INTLOC WORD 0 MSAU10 WORD WBUFFR*2-1 MSWEOB WORD EOBMSW LPOOL * * * MSAUTI - MULTI-SECTOR AUTO I/O BLOCK FOR INPUT * * MSAUTI ENT COPY INTADR,A GET INTERRUPT ADDRESS COPY A,INTLOC AND SAVE COPY AIBM,A GET AUTO I/O INSTRUCTION OR DEVAD,A AND OR DEVICE ADDRESS COPY A,*INTLOC STORE IN INTERRUPT LOCATION COPY *MSAUTI,A LOAD BYTE COUNT NEG A,A IMS MSAUTI INCREMENT FOR RETURN IMS INTLOC COPY A,*INTLOC AND STORE BYTE COUNT COPY MSAU20,A LOAD TRANSFER ADDRESS-1 IMS INTLOC COPY A,*INTLOC IMS INTLOC IMS INTLOC COPY JSTINS,A LOAD COPY A,*INTLOC AND STORE JST INSTRUCTION IMS INTLOC COPY MSREOB,A LOAD EOB ADRESS FOR MS READ COPY A,*INTLOC AND STORE SBIT 8,S TURN ON INTERRUPTS JMP *MSAUTI AND RETURN MSAU20 WORD RBUFFR*2-1 MSREOB WORD EOBMSR LPOOL * * * END OF BLOCK FOR MULTI-SECTOR WRITE * * EOBMSW ENT SBIT 8,S DA46 IN MFADR+1,A INPUT STATUS ROTATE A,RO,3 CHECK GLOBAL ERROR BIT JLT A,$+3 IF A MINUS ERROR EXISTS COPY =0,A CLEAR A REGISTER, NO ERROR EXISTS RBIT 1,S RESET OVERFLOW BIT IF NO ERROR EXISTS ROTATE A,LO,1 RESTORE LEAST SIGNIFICANT BIT FROM OVERFLOW AND MASK3F,A MASK OFF MOST SIGNIFICANT BITS COPY A,ERRWRD JMP EOBATW JMP TO ROUTINE WHICH WAS INTERRUPTED * * * * END OF BLOCK FOR MULTI-SECTOR READ * * * EOBMSR ENT SBIT 8,S DA48 IN MFADR+1,A INPUT STATUS ROTATE A,RO,3 CHECK GLOBAL ERROR BIT JLT A,$+3 IF A MINUS, ERROR EXISTS COPY =0,A CLEAR A REGISTER, NO ERROR EXISTS RBIT 1,S RESET OVERFLOW IF NO ERROR EXISTS ROTATE A,LO,1 RESTORE LEAST SIGNIFICANT BIT FROM OVERFLOW AND MASK3F,A MASK OFF MOST SIGNIFICANT BITS COPY A,ERRWRD JMP EOBATR JMP TO ROUTINE WHICH WAS INTERRUPTED * * * COMPAR - COMPARES THE CONTENTS OF TWO BUFFERS WHOSE LENGTH IS * SPECIFIED IN THE DATA WORD FOLLOWING THE CALLING INSTRUCTION * CALLING SEQUENCE IS: * * JST COMPAR * WORD LENGTH OF BUFFERS TO BE COMPARED (IN WORDS) * * COMPAR ENT COPY *COMPAR,A GET COUNT TO BE COMPARED (WORDS) IMS COMPAR FOR RETURN NEG A,A COPY A,CNTCNT COPY =RBUFFR,A GET READ BUFFER ADDRESS COPY A,CMPR10 AND SAVE IT COPY =WBUFFR,X GET WRITE BUFFER ADDRESS CMPR30 COPY 0(X),A GET VALUE CSK A,*CMPR10 NOP < JMP CMPR20 > ERROR ADD =1,X = OK IMS CMPR10 INCREMENT POINTER IMS CNTCNT INCREMENT COUNTER JMP CMPR30 LOOP TIL FINISHED COPY =0,A CLEAR A REGISTER COPY A,ERRWRD NO ERROR JMP *COMPAR RETURN CMPR20 COPY A,MSCMPE EXPECTED COPY *CMPR10,A COPY A,MSCMPA ACTUAL COPY =CMPERR,A COMPARISON ERROR COPY A,ERRWRD JMP *COMPAR ERROR RETURN CMPR10 WORD 0 * * WAUTO - SET UP AUTO I/O BLOCK FOR WRITE OPERATION * WAUTO ENT COPY INTADR,A GET I/NTERRUPT ADDRE SS COPY A,TEMP9 SAVE COPY AOBM,A GET MASK FOR AUTOMATIC WORD OP OR DEVAD,A OR IN DEVICE ADDRESS COPY A,*TEMP9 COPY =-128,A SET UP BYTE COUNT IMS TEMP9 COPY A,*TEMP9 COPY =WBUFR+WBUFR-1,A GET BUFFER *2-1 COUNT IMS TEMP9 INCREMENT ADDRESS COPY A,*TEMP9 IMS TEMP9 INCREMENT ADDRESS IMS TEMP9 INCREMENT ADDRESS COPY JSTINS,A GET JST INSTRUCTION COPY A,*TEMP9  IMS TEMP9 INCREMNT ADDRESS COPY WEOB,A GET EOB ADDRESS FOR WR*ITE COPY A,*TEMP9 SBIT 8,S TURN ON INTERRUPT JMP *WAUTO RETURN TO CALLER * WEOB WORD EOBW END OF BLOCK ADDRESS JSTINS JST *$+1 JST INSTRUCTIONS AOBM AOB 0*8+0 TEMP9 WORD 0 LPOOL WBUFR RES 128,:DB INITIALIZE 128 WORDS TO DB * * RAUTO - BLOCK FOR READ AUTO I/O * RAUTO ENT COPY INTADR,A GET INTERRUPT ADDRESS COPY A,TEMP5 COPY AIBM,A GET AUTO I/O INSTRUCTION OR DEVAD,A OR IN DEVICE ADDRESWS COPY A,*TEMP5 SAVE INSTRUCTION COPY =-128,A SET UP FOR 128 WORD LOOP IMS TEMP5 COPY A,*TEMP5 SAVE IN ADDRESS COPY =RBUFR+RBUFR-1,A GET READ BUFFER IMS TEMP5 INCREMENT ADDRESS COPY A,*TEMP5 IMS TEMP5  IMS TEMP5 INCRFEMENT ADDRESS COPY JSTINS,A GET JST INSTRUCTION COPY A,*TEMP5 IMS TEMP5  INCREMENT ADDRESS COPY REOB,A GET RETURN ADDRESS COPY A,*TEMP5 SBIT 8,S INTERRUPTS ADDRESS JMP *RAUTO RETURN TO CALLER REOB WORD EOBR EOB ADDRESS AIBM AIB 0*8+0 TEMP5 WORD 0 LPOOL RBUFR RES 128,0 * * END OF BLOCK WRITE AUTO I/O * EOBW ENT SBIT 8,S DA32 IN MFADR+1,A INPUT STATUS ROTATE A,RO,2 SHIFT TWO LEFT JLT A,EOBW5 IF MINUS ERROR EXISTS COPY =0,A SET NO ERROR EOBW5 AND MASK3F,A MASK OFF MSB COPY A,ERRWRD JMP EOBEW JUMP TO ROUTINE WHICH WAS INTERRU&TED * * END OF BLOCK FOR AUTO I/O * EOBR ENT SBIT 8,S DA34 IN MFADR+1,A INPUT STATUS ROTATE A,RO,2 SHIFT TWO LEF IF GREATER ERROR ADD =1,X = OK IMS TEMP8 IMS CNTCNT INCREMENT COUNTER JMP COMPB3 IF NOT DONE LOOP BACK COPY =0,A SET GOOD FLAG COPY A,ERRWRD COMPB5 JMP *COMPBF RETURN TO CALLER COMPB9 COPY A,MSCMPA ACTUAL COPY *TEMP8,A  COPY A,MSCMPE EXPECTED COPY =CMPERR,A COPY A,ERRWRD JMP COMPB5 RETURN TO CALLER TEMP8 WORD 0 * *  OUTSHT PRINTS A CARRIAGE RETURN, LINE FEED, * FOLLOWED BY A MESSAGE. * * A = BYTE LENGTH OF MESSAGE *  X = WORD ADDRESS OF MESSAGE * OUTSHT ENT COPY A,OUTSH1 SAVE A COPY X,OUTSH2 SAVE X COPY =CR,A  OUTPUT CARRIAGE JST OTT RETURN COPY =LF,A OUTPUT LINE JST OTT FEED JST ASCOUT OUTSH1 RES 1 OUTSH2 RES 1 JMP *OUTSHT RETURN TO CALLER * * * DECOUT PRINTS A 16 BIT INTEGER AS A *  4 CHARACTER UNSIGNED DECIMAL FIELD. * (0-9999 ONLY) * LDA VALUE * JST DECOUT * * DECOUT ENT COPY A,DECVAL SAVE DECIMAL VALUE COPY =DECTBL,A GET TABLE ADDRESS COPY A,DECPTR COPY =-4,A COPY A,DECCNT DECIMAL COUNT(DIGITS) DECOT1 COPY DECVAL,A COPY ='0'-1,X DECOT2 SUB *DECPTR,A ADD =1,X  JGE A,DECOT2 ADD *DECPTR,A COPY A,DECVAL COPY X,A TRANSFER X TO A JST OTT  OUTPUT VALUE IMS DECPTR IMS DECCNT JMP DECOT1 JMP *DECOUT DECVAL RES 1 DECCNT RES  1 DECPTR RES 1 DECTBL WORD 1000,100,10,1 * * * DCMLOT - PRINTS A 16 BIT INTEFER AS A * 2 CHARACTER UNSIGNED DECIMAL FIELD. (0-99 ONLY) * CALLING SEQUENCE: * * COPY VALUE,A * JST DCMLOT * * DCMLOT ENT COPY A,DECVAL SAVE DECIMAL VALUE COPY =DCMTBL,A GET TABLE ADRESS COPY A,DCMPTR COPY =-2,A COPY A,DCMCNT DCMOT1 COPY DECVAL,A COPY ='0'-1,X DCMOT2 SUB *DCMPTR,A ADD =1,X JGE A,DCMOT2 ADD *DCMPTR,A COPY A,DECVAL COPY X,A JST OTT IMS DCMPTR IMS DCMCNT JMP DCMOT1  JMP *DCMLOT DCMCNT RES 1 DCMPTR RES 1 DCMTBL WORD 10,1 LPOOL * * HEXOUT PRINTS A 16 BIT INTEGER AS A 4 CHARACTER *  HEXADECIMAL FIELD. * LDA HEXNUM LOAD INTEGER IN A REGISTER * JST HEXOUT * HEXOUT ENT COPY =4,X HEXOT1 COPY A,TEMPHE SHIFT A,RO,8 SHIFT A,RO,4 SUB =:A,A JGE A,$+3 ADD ='9'+1,A JMP $+2 ADD ='A',A JST OTT COPY TEMPHE,A SHIFT A,LO,4  SUB =1,X JNE X,HEXOT1 JMP *HEXOUT TEMPHE WORD 0 LPOOL * * * ASCOUT PRINT ASCII C HARACTERS. * JST ASCOUT * WORD LENGTH NUMBER OF BYTES TO PRINT * WORD ADDRESS WORD ADDRTESS OF ASCII STRING * ASCOUT ENT COPY *ASCOUT,A GET THE BYTE COUNT NEG A,A COPY A,TEMPAS IMS ASCOUT  COPY *ASCOUT,X IMS ASCOUT SHIFT X,LO,1 SHIFT LEFT ONE ASCOT1 SBIT 2,S SET BYTE MODE COPYB 0(X),A GET BYTE RBIT 2,S SET WORD MODE JST OTT ADD =1,X  MOVE TO NEXT BYTE IMS TEMPAS JMP ASCOT1 JMP *ASCOUT RETURN TO CALLER TEMPAS WORD 0 LPOOL LPOOL * * SAVE STATUS AND X-REGISTER * RESTORE STATUS AND X-REGISTER * SAVEX ENT  ENTRY POINT SIN 6 COPY A,SVS SAVE A-REG COPY S,A EXCH SVS,A RBIT 8,S  DISABLE INTERRUPTS COPY X,SVX JMP *SAVEX RETURN TO CALLER RSTORX ENT SIN 6  EXCH SVS,A SHIFT A,RO,STSHFT-1 SHIFT A,RO,1 SHIFT ONE RIGHT JF OV,$+2 SBIT 8,S ENABLE INTERRUPT EXCH SVS,A GET STATUS COPY SVX,X GET X-REG JMP *RSTORX RETURN TO CALLER SVS RES 1 SVX RES 1 LPOOL * * OTT - OUTPUT A CHARACTER TO THE TELETYPE * OTT  ENT JST SAVEX COPY =:8612,X START,REQUEST TO SEND,DONT INTERRUPT OUT X,DTTYDA%1;1 OUT A,DTTYDA%1 COPY =:100,X RESET CODE IN DTTYDA%1;1,A SHIFT A,RO,5 JT OV,$-2  IN DTTYDA%1;1,A SHIFT A,RO,5 JF OV,$-2 OUT X,DTTYDA%1;1 JST RSTORX JMP  *OTT RETURN TO CALLER LPOOL TYLACH WORD 0 * * IKB - INPUT A CHARACTER FROM THE TELETYPE * IKB ENT  JST SAVEX COPY =:8618,A START, ECHO NO INTERRUPT OUT A,DTTYDA%1;1 COPY =:100,X  RESET CODE IN DTTYDA%1;1,A SHIFT A,RO,4 DATA READY TO OV JF OV,$-2 IFF DATA NOT READY IN DTTYDA%1,A OUT X,DTTYDA%1;1 AND =:7F,A TURN ON PARITY BIT JST RSTORX  JMP *IKB LPOOL * * POWER RESTORE * POWRUP ENT JMP MFPD * * POWER DOWN * POWRDN ENT SIN  1 HLT * LPOOL WBUFFR RES 1030,:A5A5 RBUFFR RES 1030,0 ENDPT END MFPD TITL STANDARD INTERRUPT LOCATIONS EXTR  POWRUP,POWRDN,SAVEP * POWER UP ABS :80 JST *$+1 WORD POWRUP * POWER DOWN ABS  :8C WORD 0 WORD 0 JST *$+1 WORD POWRDN ABS :94 JST *$+1 WORD SAVEP END LPOOL * * POWER RESTORE * POWRUP ENT JMP MFPD * * POWER DOWN * POWRDN ENT SIN  1 HLT * LPOOL WBUFFR RES 1030,:A5A5 RBUFFR RES 1030,0 ENDPT END MFPD TITL STANDARD INTERRUPT LOCATIONS EXTR  POWRUP,POWRDN,SAVEP * POWER UP ABS :80 JST *$+1 WORD POWRUP * POWER DOWN ABS  :8C WORD 0 WORD 0 JST *$+1 WORD POWRDN ABS :94 JST *$+1 WORD  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII! IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII# IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII$ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII% IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII& IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII?e; 790405142912790405142912800313115536e@790405142912790405142912790405142912e:' 790405142912790405142912790405142912e790405142912790405142912790405142912790405142912790405142912790405142912edh4.7904051432542579040514341025800313114233de@7904051434577580031311423400800313115828deN7904051437235079040514372825d eO+'8003131158522580031311594300800313115943( ) * + , - . / 0 . S81021 ASMO81031 OBJMINFPYHELP HLP B81041 BIN1 JSAVEP POWRDN POWRUP O0SEGMENTBLANK oi g&]  Eʆު < x;6Abޫo y 9J     #  MINI-FLEXIBLE DISK PICO DIAGNOSTICFORMAT /DIAG (D) = TSTS (A, B,C,D,E,F,G,H) = UN ITS (0) = TRACKS (0, 3) = SCTRS (1,2) =  HEAD (0) = INTS (Y) = PATN (5B) =  : DEV AD (:FC)=: CONTROL INFO (C) = : INT ADR (:F0) = : MU LTI-SECTOR I/O (2) = p 1xwv) D Fo)nG t Ly{ 1ÿ՞rvXx   5  g ߆Y  Cfe fD w1X vp + kk.g1idb5)h WX  My1[ vF s  +? 힂hd d9f_V5)e( 'S1Y vu  +ǻʞj@Ɵf ?ha25)h /1S v  ߫"lng5)m 1 Y N tUrqpn r QtUVRHCSTYs 1JwTutr15)r A I\ x1M yst\rok5l>F b1M y]ʞt]roU5lI0 L1JJw`srB5t?  1R  s  ޗ}   \W Ba 5Q7  S6W4U  A)"+ߗ|  ߊwg MsDEAM  Bv @ >ſ8yo3/;  Ca- + ssϿr r# jkkme  DE  WWؿV T M  EFFd Z\xv  E ,,ڿ+ m)l f"e  ^AXb TXQ7 ]  Fv u ſ ޿Ayo Gуe d ϾѿϿ/  ȿĞ'ÿ#kc H H G B  q +ޛ|    WOL ~ ~ Ds63/; ^    Dg  G g B Cߴ߮ V Ti aMߗ Sߐ` :RQVUTS4XWG758  ւֆՃ2 +;  mj   a ] Z W T Q N ۇ  )⯄,+{7DHYv  F+6ÃI) ␄,+{n L? Z?>;PO   +߂{vF  +ߑ{ Çm yFM#5   i+d{t  6= ZxW|? 49<z  = 0 ;   9+ߍ 1x p/. *jH34Z  yzloIJ   xu +vpl qf nM  ꇎރ߅xp>ABG  ޢ+ ߞ{6=Ƃl fI SF` WXDFF wa߇   .&G  ۇe ڃ iʞoaŻUgQN ߿ b[ Ea  A N߭s i jߖ%_Y# FORMAT COMPLETE  SPT 4638;/;K57Mp 1N vd qonl5)sC  ]P tt1X vm + hkdcgFidb]5)hgWX* NN1S vG   BCBlEjg<5)m   1M y,,+tTo%5l A>  FORMAT (35T=1 OR 40T =2) - (1) = UNIT (0) = HEAD (0)  = DEV ADR (:FC) =    잵G 6  6A    Eq1ߣ  j   <4DM ?O\ {zƿ ts ml 8W `_ "YX & RQi  ;C 1 *8 9 ^  ( -KDM576u n  ki `  [ ⓀT  ⍀߄fXNWNX   PASS TST ERR TE ST U SOFT HARD   TRK SC TR HEAD EXPECTED  ACTUAL UNT  SCTR CNT   ю͎ ̎J1 ߊmwd  p  T޿ͿDq1  ƃƇƃŃ ¿¿ ȃ߹vlq1 u  ȿ tq1x  ɿŃsq1w Q9D8U573/;MVvx h 1N zet o-)r m 1N xsn,)r g4 fw r 1N yqtUoPh,k w 1J_w.rW0)r A>I ~ 1T vu  +ߍ=kTf$)mCR  x12 Ϟvup  +kkHf $)m F =  N = D = PATN = SCTR =  TRACK =  |.z% ' +xo ^UV j  ̎Jޑ ņpi bg0  HYv HYv  +߂{vF p  x߆t{s4ZH  y3 wލ ފވއ퇅ރi  .I u> t  zvysywon lkjiχgfdi # 9   +   +  ~ }+ދ x m g  0/ސލ ދފއk eFM    ޏތ ފމކk EI> 7 t       |{ # yx _vu ^sr ,po : ml jih ׂ׆ +͞x Ɵo y    u )/+= ޅރtm    d  wr)/ +=l ބނtm    ^FMgo F      )y9 B : A 1*1p ~{z y.%'+ނyp  _0x _y 6v ] ^  j"I6=I6 "fq Xx96"Vsg g  O0SEGMENTBLANK oKSAVEP POWRDN POWRUP iitttPOWER UP ABS :80 JST *$+1 WORD POWRUP * POWER DOWN ABS  :8C WORD 0 WORD 0 JST *$+1 WORD POWRDN ABS :94 JST *$+1 WORD * HELP FILE * * NM4 MINI FLEXIBLE DISK PICO DIAGNOSTIC * * TO ASSEMBLE UNDER OS4 * ASSIGN USER FILE TO THE *  DISK WHICH CONTAINS THE * SOURCE OF THE DIAGNOSTIC * * /JOB * /AS UF=D. * /MACRO O81031.OBJ=S81021.ASM * . * . * /LINK B81041.BIN=O81031.OBJ(AB=100,EX=100)+D.DEBUGX.OBJ(UL) * * NOTE: ANY OS4 COMPATIBLE DEBUG MAY BE LINKED TO THIS * DIAGNOSTIC TO AID IN TROUBLE SHOOTING. * * END HELP FILE OVicEdDano  k\ g&  Eʆު< x;6Abޫo jyn WT#-&MINI-FLEXIBLE DISK PICO DIAGNOSTICFORMAT/DIAG (D) = TSTS (A,B,C,D,E,F,G,H) = UNITS (0) = TRACKS (0,3) = SCTRS (1,2) = HEAD (0) = INTS (Y) = PATN (5B) = : DEV AD (:FC)=:CONTROL INFO (C) = :INT ADR (:F0) = : MULTI-SECTOR I/O (2) = ۿ1xwv) D Fo)nG ^y 1ÿ՞rvXx   5  g߆Y8. D w1X vp +kk.g1idb5)h+  My1[ vF s +? 힂hdd9f_V5)e(  'S1Y vu +ǻʞj@Ɵf?ha25)h  /1S v ߫"lng5)m 1 Y N tUrqpn r    s 1JwTutr15)r+ \ )x1M yst\rok5l F >b1M y]ʞt]roU5l0 2L1JJw`srB5t  I1R  s ޗ}  \WBa   / k { A)"+ߗ|  ߊwg Ms   Bv @ >ſ8yo . Ca- + ssϿrr# jkkmem4  DE  WWؿV T M EFFd Z  E ,,ڿ+ m)l f"e ^AXb TX QD Fv u ſ޿޿Ayo Gуe d ϾѿϿ̞/ ſȿĞ'ÿ#kc HH G B q +ޛ|  WOL ~ ~  k1a G g B Cߴ߮V TiaMߗ Sߐ` k  ւֆՃ޼+; mj   a ] Z W T Q N ۇ   )⯄,+{7D*?[ F+6ÃI) ␄,+{n . _ 0 +߂{v m! +ߑ{Çm y   Q i+d{t 6= ZxW|? qWH 9>?*\ 9+ߍ1x p/. *j  G yzlo   xu+vpl qf n  ꇎރ߅xp  ޢ+ߞ{6=Ƃl fI SF`  Owa߇  .&G  ۇeڟڃ iʞoaƃŻUgQ߿ b[ Ea  AN߭s ijߖ%_Y#FORMAT COMPLETE   % p pP 1N vdqonl5)s _+ WPd tt1X vm +hkdcgFidb]5)h *m NN1S vG  BCBlEjg<5)m: v1M y,,+tTo%5l FORMAT (35T=1 OR 40T =2) - (1) = UNIT (0) = HEAD (0) = DEV ADR (:FC) =   Ã잵G 6 6A    Eq1ߣ  jȣ  <  g %c / kh _ j{zƿntsqmlW`_YXRQi C8n - u n tkiy` [ⓀT⍀߄fX T_cPASS TST ERR TEST U SOFT HARD TRK SCTR HEAD EXPECTED ACTUAL UNT SCTR CNT  ю͎ ̎J1ߊmwd +)*, T޿ͿDq1 ƃƃŃ ¿¿ƒȃ߹vlq1u  ȿtq1x ɿŃsq1w /  .ӿ1N zeto-)rؿ1N xsn,)r+ wݿ1N yqtUoPh,k⿏1J_w.rW0)r  1T vu +ߍ=kTf$)m   x12 Ϟvup +kkHf$)m F = N = D = PATN = SCTR = TRACK =  |.z%' +xo  ̎Jޑņpi bg0 *?[*?[ +߂{v  G x߆t{s 5   ywލފވއ퇅ރi1  zvysywonlkjiχgfdi9 +  +  ~}+ދx m g 0/ސލދފއke  - ޏތފމކkE / J     |{ #yx _vu ^sr ,po :ml jih ׂ׆ր+ދ͞x Ɵo˃ y Su )/+= ޅރtmjd  wr)/+=l ބނtmD  * j )y9 B : A1*1p ~{zy.%'+ނyp _0x _y 6v& j"I6=I6"fq Xx96"Vs   k( }؞I8{}J~vo\E{b   oIcd T ( :Ԃ9 - :Ԃ" )  k ΦpP0 @0B ¢` h }cD ¯⯂pP0Oo X D B U G 4 E 0 0 0 ԟe 3} ԂzԾ P AC Q@ X= Y:սҾ K3 L0 S- D* C'՟K =ԟ{ } ԟ|" Ž *ڽӆ Y Q A T Gӽن R Ʀ M D V Wƚ›LBLCLFLLLSLJLILGLRLZ Ȟ8 +}ӆ{ӆu Ƃt P LƂj T P BƁ P Ԃ\ W H Tƅ Ş|QEI , , ` 6 _ڞ"Y? #} ` J B YK QJfׂ ^ޡ @ޟޝ `@E ;RA@EN@Aޏǎ Qފ ,^$Ag o){ w_ D `nX*Qc Ѐ^Ѐ āY@AĄ܃S B `ȁ D*K_U2 `Ţ0*.( &r o{5 M쇅 `Xh z} T C I U N S A ›PQI哢`@"ӟƠ -LlQłބMb 5}⼢ x C “KQGa@" qQłއށj Iސސސސ޳޳ ,Ӟ  }I迋t2[Ln W¨KQGb@"ӑƒ qQł‹Ljޖj Uȝ '} AAw r} { yxwt “KQGEMNc@"JK qQłEBDAށj \ NI “KQG)56d@"23 qQł-*,)ށj @ S- “KQG e@" qQłށj $ A "Bƽ҃ܽ׽́CŁ  / Xƃ ҽܞi ]ҁ@ۃׁܽBǢ ,ž[ + - * X /KJƎ^[{ xނZ  ,Ɵ| ׽L ΁ P ҁ۽ܽ޺{ ӽҞq kɆȂGާ}ަyޠ}y E   .ԃ E   .ޣރfN ,ƽ׆s@FC kqLL (w{u ^|JQBZy L S TҞNM  Isžˆ_]]| IƎ> ,ƽƇ ,ƂpIưk , ,Htr H6 m -Ɔׁ -Ɔ('\\ÂF -t҂ۃ՞x ’@"Fz@ Ό F ƍ l h#.bƝޙޖJQ!’ފދJQŽ %Ԃ՞u U B * ԂGo h fe "cIaM K Y&V&RR `QKL$kK N =ԂDD GԂA   :Ԟ ԟL ǟ{ y9u    :w ® 0C C 96C C "0 `j •C "C tC I6DÎA6PO6P6P  k F I Dlk Ԟx @9@@? R6A W CËˋJR>JKSB|ҝ B{ ӆvtrLDLELILRLWƖd ,ka%#!ņyĆxÆwpQAlýkL=\L>L:|öbL<L=L^]\Q HǞ wqqno = < > :ba y C 1 =Ԃ C 2 =Ԃ C 3 =Ԃ M =ԃTܽҞH&ƽ׆ =FFEFCCE=:7&Ɠ5-Ɠ,&Ɠ$Q߇ƽ? mE3E1E2E1--E1E0IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII7 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII8 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII9 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII; IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII< IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII= IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII> IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII? IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII@ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIB IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIID IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIE IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIF IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIH IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIK IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIL IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII