IMD 1.16: 2/09/2008 14:19:20 84-93727-06 a200 f72706 scout macro file for cpu test program    @0|)wwЀЀtQql)  " }gA `MIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIOS4 ME581100512570600811009100301 811009100301=F72706 VOLMACRO & DOCUMENTATION FILE FOR CPU TEST PROGRAM   IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIM@jjggg@ o G`k_C# b# }B u[ ]e JRiCCp@<;: F8P@ G;NPCHC C GTqE'ɞ * Cϟx @0DAJL )‘ЀЀΎQBx"  i+ fEB)3 `jmBBI,v  BI,m  @EEFF)D^EF% jH@pOğv g7g4]X] PhV+s=胾c_N GF֞ؾ “@ALS)"$ C k1/j-h p vRw ppwp ki 15 !^\d X %'+Ns愾Q)s ED|{ @$ o O m J K i g. V tsFn`"FED) E`Cnrgy w"N{Rq1H }L2`0tG- Bc (>== HIGH LIMIT * THEN ERROR HALT * ELSE * IF SOFTWARE COUNT < LOW LIMIT * THEN ERROR HALT * ELSE * IF LOOP COUNTER < 0 * THEN JUMP N31033 * ELSE * END REAL-TIME CLOCK TEST SPACE 1 * BEGIN I/O TEST * COPY 0 IN Q * OUTPUT Q TO CDR * INPUT CDR INTO A * IF Q AND A ARE NOT EQUAL * THEN ERROR HALT * COPY :AAAA INTO X * OUTPUT X INTO CDR * INPUT CDR INTO Q * IF Q AND X ARE NOT EQUAL * THEN ERROR HALT * COPY :5555 INTO Y * OUTPUT Y INTO CDR * INPUT CDR INTO X * IF X AND Y NOT EQUAL *  THEN ERROR HALT * COPY :FFFF INTO A * OUPUT A TO CDR * INPUT CDR INTO Y * IF A AND Y ARE NOT EQUAL * THEN ERROR HALT * ELSE * INTERRUPT INSTRUCTIONS * (JST AS AN INTERRUPT INSTRUCTION) * RESET BIT 8 IN STATUS REGISTER * SET UP INTERRUPT VECTOR * OUTPUT :6F0 TO LOCATION :F9 (TO CAUSE INTERRUPT) * SIN 2 * SET BIT 8 IN STATUS REGISTER * IF INTERRUPT DID NOT OCCUR * THEN ERROR HALT * ELSE * IF MORE THAN 2 INSTRUCTIONS EXECUTED BEFORE INTERRUPT * THEN ERROR HALT * ELSE * (JSK AS INTERRUPT INSTRUCTION) * SET STATUS REGISTER TO :150 * SET UP INTERRUPT VECTOR * * * * * MORE * (AUTO I/0 OUTPUT) * RESET THE CRT * SET UP INTERRUPT VECTOR (BEGINNING AT :E0) * OUTPUT :612 TO LOCATION :F9 (TO START AUTO I/O) * SET BIT 8 IN STATUS REGISTER * WAIT A WHILE * IF E-O-B INTERRUPT DID NOT OCCUR * THEN ERROR HALT * ELSE * (AUTO I/O INPUT) * RESET BIT 8 IN STATUS REGISTER * SET UP INTERRUPT VECTOR (BEGINNING AT :E0) * OUTPUT :610 TO LOCATION :F9 (TO START AUTO I/O) * SET BIT 8 IN STATUS REGISTER * WAIT A WHILE * IF E-O-B INTERRUPT DID NOT OCCUR * THEN ERROR HALT * ELSE * NON-INTERRUPTABLE INSTRUCTIONS * (JST) * SET STATUS REGISTER TO :150 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CREATE INTERRUPT) * IF JST INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER JST *  THEN ERROR HALT * ELSE * (JSK) * SET STATUS REGISTER TO :150 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOC ATION :F9 (TO CAUSE INTERRUPT) * IF JSK INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER JSK INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * (JSKE) * SET STATUS REGISTER TO :150 *  SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF JSKE INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER JSKE INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * (PUSH) * SET STATUS REGISTER TO :150 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF PUSH INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER PUSH INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * (POP) * SET STATUS REGISTER TO :150 * SET UP INTERRUPT VECTOR *  OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF POP INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE *  IF INTERRUPT DID NOT OCCUR AFTER POP INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * (SBIT 8,S) * SET STATUS REGISTER TO :0 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF SBIT 8,S INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER SBIT 8,S INSTRUCTION EXECUTED *  THEN ERROR HALT * ELSE * (CBIT 8,S) * SET STATUS REGISTER TO :0 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT * IF CBIT 8,S INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER CBIT 8,S INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * (XNX) * SET STATUS REGISTER TO :0 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF XNX INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER XNX INSTRUCTION EXECUTED * THEN ERROR HALT *  ELSE * (UIS) * SET STATUS REGISTER TO :0 * SET UP INTERRUPT VECTOR * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) * IF UIS INSTRUCTION INTERRUPTED * THEN ERROR HALT * ELSE * IF INTERRUPT DID NOT OCCUR AFTER UIS INSTRUCTION EXECUTED * THEN ERROR HALT * ELSE * END INPUT OUTPUT TEST * SPACE 1 * BEGIN FLOATING POINT TEST * IF CPU BEING TESTED IS AN 4/04-01 * THEN JUMP END:1 * ELSE * TEST FIX INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALT * TEST FLOAT INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALT * ELSE * TEST CSKF INSTRUCTION IN ALL ADDRESSSING MODES * IF ERROR OCCURS * THEN ERROR HALTS * ELSE * TEST ADDF INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALTS * ELSE * TEST SUBF INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALT * ELSE * TEST MULF INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALT * ELSE * TEST DIVF INSTRUCTION * IF ERROR OCCURS * THEN ERROR HALT * ELSE * END:1 * END FLOATING POINT INSTRUCTION TEST SPACE 1 * BEGIN MEMORY TEST *  SET UP UNIMPLIMINTED MEMORY TRAP * GET LOCATION OF PROGRAM END * USE LOCATION AS REFERENCE TO MEMORY ADDRESS * COP  Y :5000 INTO MEMORY LOCATION :5000 * LOOP:9 * ADD 1 TO NUMBER AND ADDRESS * COPY NUMBER INTO ADDRESS * IF NOT TO LOCATION :FFFF * THEN JUMP LOOP:9 * ELSE * COPY CONTENTS OF MEMORY LOCATION :5000 IN X * LOOP12 * COMPARE X TO EXPECTED DATA * IF X IS NOT EQUAL TO EXPECTED DATA * THEN ERROR HALT * ELSE * ADD 1 TO MEMORY ADDRESS * IF NOT TO LOCATION :FFFF * THEN JUMP LOOP12 * ELSE * SET MEMORY ADDRESS AT :FFFF * LOOP14 * READ MEMORY ADDRESS * IF MEMORY ADDRESS NOT EQUAL TO EXPECTED VALUE * THEN ERROR HALT * ELSE * IF NOT TO MEMORY LOCATION :5000 * THEN JUMP TO LOOP14 * ELSE * BYTE TEST * SET MEMORY ADDRESS TO :5000 * SET BYTE MODE * LOOP22 * COPY :55 IN LOWER BYTE * COPY :AA IN UPPER BYTE * INCREMENT MEMORY ADDRESS * IF NOT TO MEMORY LOCATION :FFFF * THEN JUMP LOOP22 * ELSE * SET MEMORY ADDRESS AT :5000 * SET BYTE MODE * LOOP33 * READ UPPER BYTE * IF UPPER BYTE NOT EQUAL TO EXPECTED DATA * THEN ERROR HALT * ELSE * READ LOWER BYTE * IF LOWER BYTE NOT EQUAL TO EXPECTED DATA * THEN ERROR HALT * ELSE * IF NOT TO LOCATION :FFFF * THEN JUMP LOOP33 * ELSE * END MEMORY TEST SPACE 1 * 8.0 OPERATION SUMMARY SPACE 1 * 8.1 DEFAULT MODE SPACE 1 * 1) LOAD AND EXECUTE THE PAT404 PROGRAM AT ADDRESS :100. * BIDP, UIT, RTC, IO, FLPT, AND MEM:TST ARE EXECUTED * CONTINUOUSLY. (PRESS RUN AFTER EACH OF THE THREE HALTS * DURING BIDP. * 2) PRESS STOP TO TERMINATE EXECUTION. PRESS RUN TO CONTINUE * AFTER ANY ERROR HALT. SPACE 1 * 8.2 DEMAND MODE SPACE 1 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :101 INTO * THE P REGISTER. * 2) ENTER RUN OPTIONS IN THE A REGISTER AS FOLLOWS: SPACE 1 * BIT 0 NOT USED * BIT 1 0=> HALT IF PDNCT AND PUPCT ARE NOT EQUAL * 1 => DO NOT HALT IF PDNCT AND PUPCT ARE NOT EQUAL * BITS 2-15 NOT USED * 3) SET THE CONSOLE DATA REGISTER BITS CORRESPONDINS TO THE * DESIRED TESTS, AS FOLLOWS: SPACE 1 * BIT 0  RUN BASIC INSTRUCTION TEST * BIT 1 RUN UNIMPLIMINTES INSTRUCTION TEST * BIT 3 RUN REAL-TIME CLOCK TEST *  BIT 4 RUN INPUT OUTPUT TEST * BIT 5 RUN FLOATING POINT TEST * BIT 6 RUN MEMORY TEST SPACE 1 * 4) PRESS RUN. THE SELECTED TESTS ARE RUN CONTINUOUSLY. * (PRESS RUN AFTER EACH OF THE THREE HALTS DURING THE * BASIC INSTRUCTION TEST) SPACE 1 * 8.3 RESTART MODE SPACE 1 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :102 INTO THE *  P REGISTER * 2) FOLLOW STEPS 2 THRU 5 AS DESCRIBED IN DEMAND MODE. PASS * COUNTERS AND POWER FAIL COUNTERS REMAIN ACCUMULATIVE AT * THIS ADDRESS. * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :102 INTO THE * P REGISTER. * 2) FOLLOW STEPS 2 THROUGH 5 AS DESCRIBED IN DEMAND MODE. * PASS COUNTERS AND POWER FAIL COUNTERS REMAIN * ACCUMULATIVE AT THIS ADDRESS. END 1 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :102 INTO THE *  P REGISTER * 2) FOLLOW STEPS 2 THRU 5 AS DESCRIBED IN DEMAND MODE. PASS * COUNTERS AND POWER FAIL COUNTERS REMAIN  1PAGE 0001 MACRO (F100) 1981/11/30 09:05:37.75 SI = DH00.PAT404:DOC.ASM LO = DH00.PAT404:DOC.LST 0001 * TABLE OF CONTENTS PAGE 0003 * 1.0 INTRODUCTION  3 0005 * 2.0 FUNCTIONAL DESCRIPTION 3 0007 * 2.1  HARDWARE REQUIRED 3 0008 * 2.2 ADDITIONAL HARDWARE SUPPORTED 3  0010 * 3.0 REFERENCE DOCUMENTATION 3 0012 * 4.0 GENERAL DESCRIPTION 3 0014 * 4.0 PROGRAM OPERATION 4  0016 * 4.1 LOADING AND START UP 4 0017 * 5.1.1 DEFAULT MODE  4 0018 * 5.1.2 DEMAND MODE 4 0019 * 5.1.3 RESTSRT MODE 5 0021 * 5.2 RUN INDICATION  5 0023 * 5.3 TERMINATION 5 0024 * 5.3.1  NORMAL TERMINATION 5 0025 * 5.3.2 ERROR TERMINATION 5  0026 * 5.4 CONSOLE INTERRUPT TESTING 5 0027 * 5.5 POWER FAIL/POWER UP TESTING 5 0028 * 5.6 UNEXPECTED TRAPS 6 0030 * 6.0 TEST DESCRIPTIONS 6 0032 * 6.1 BASIC INSTRUCTION TEST  6 0033 * 6.1.1 BASIC INSTRUCTION TESTING 6 0034 * 6.1.2  SINGLE WORD MEM. REF. TESTING 6 0035 * 6.1.3 REGISTER TO REGISTER TESTING 6  0036 * 6.1.4 SHIFT/ROTATE & BIT MANIPULATION 6 0037 * 6.1.5 IMMEDIATE LITERAL TESTING 7 0038 * 6.1.6 CONDITIONAL JUMP TESTING 7  0039 * 6.1.7 MULTIPLE WORD MEM. REF. TESTING 7 0040 * 6.1.8 STACK TESTING  7 0041 * 6.1.9 TRAP EMULATION TESTING 7 0042 * 6.1.10 SOFTWARE AUTOLOAD TESTING 7 1PAGE 0002 MACRO (F100) 1981/11/30 09:05:39.00 0043 * 6.2 UNIMPLIMINTED INSTRUCTION TESTING 7 0044 * 6.3 REAL-TIME CLOCK TESTING  7 0045 * 6.4 INPUT/OUTPUT TEST 8 0046 * 6.5 FLOATING POINT TEST 8 0047 * 6.6 MEMORY TEST 9  0049 * 7.0 PROGRAM FLOW 9 0051 * 7.1 HIGH LEVEL  9 0052 * 7.2 LOW LEVEL 10 005  4 * 8.0 OPERATION SUMMARY 15 0056 * 8.1 DEFAULT MODE  15 0057 * 8.2 DEMAND MODE 15 0058 * 8.3  RESTART MODE 16 1PAGE 0003 MACRO (F100) 1981/11/30 09:05:39.50 0060 *  1.0 INTRODUCTION 0062 * THE SCOUT 4/04 PROCESSOR ACCEPTANCE TEST VERIFIES THE 0063 * OPERATIONAL CAPABILITY OF THE SCOUT 4/04 -01, -02 CPU 0064 * BY MEANS OF TESTS THAT CHECK FOR:  0066 * 1. COMPLETE INSTRUCTION REPERTOIRE 0067 * 2. MEMORY INTEGITY 0068 * 3. PROCESSOR FEATURES (POWER FAIL,REAL-TIME CLOCK, 0069 * CONSOLE INTERRUPT, TRAPS)  0071 * 2.0 ENVIRONMENT 0073 * THE MINIMUM HARDWARE AND SOFTWARE REQUIREMENTS TO RUNTHIS  0074 * PROGRAM ARE LISTED IN THIS SUBSECTION. 0076 * 2.1 HARDWARE REQUIRED 0078 * THE FOLLOWING HARDWARE IS REQUIRED: 0079 * 1) SCOUT 4/04 CENTRAL PROCESSOR UNIT WITH PROGRAMMERS CONSOLE 0080 * 2) I/O TEST MODULE (REQUIRED ONLY FOR TEST 4) 0081 * 3) MEMORY (MUST BE 64K ) 0083 * 2.3 ADDITIONAL HARDWARE SUPPORTED 0085 * THE FOLLOWING HARDWARE IS OPTIONAL. 0086 * ASR-33 TTY OR EQUIVALENT (TO USE DEBUG4) 0088 * 3.0 REFERENCE DOCUMENTATION 0090 * REFER TO THE FOLLOWING DOCUMENTS FOR SUPPLEMENTARY INFORMATION. 0091 * NAKED MINI 4 ASSEMBLERS USERS MANUAL 90-93500-01 0092 * ENGINEERING SPEC, PI SERIES CPU, 76-20797-00  0094 * 4.0 GENERAL DESCRIPTION 0096 * PAT404 IS COMPRISED LOGICALLY OF SIX PARTS WRITTEN AS ONE PROGRAM 0097 * (THIS ELIMINATES THE NEED TO USE A LINK MAP TO DETERMINE LABEL 0098  * LOCATIONS IN MEMORY FOR PARTS TWO THRU SIX). 0100 * PART NAME ON LINK MAP CONTENTS  0101 * ------------------------------------------------------------- 0102 * A01000  TEST 1 BASIC INSTRUCTION DIAGNOSTIC (BIDP) 1PAGE 0004 MACRO (F100) 1981/11/30 09:05:40.75 0103 * UIT TEST 2 UNIMPLEMENTED INSTRUCTION TEST (UIT) 0104 * RTC TEST 3 REAL-TIME CLOCK TEST (RTC) 0105 * IOT TEST 4 INPUT/OUTPUT TEST (IOT) 0106 * FLPT TEST 5 FLOATING POINT INSTRUCTION TEST (FLPT) 0107 * MEM:TST TEST 6 MEMORY TEST (MEM:TST) 0109 * 5.0 PROGRAM OPERATION 0111 * 5.1 LOADING AND START UP 0113 * PAT404 LOADS AND HALTS AT LOCATION :100. HERE, THE A REGISTER 0114 * MUST BE LOADED FOR DEFAULT MODE; THE A REGISTER, DATA 0115 * REGISTER AND P REGISTER MUST BE LOADED, FOR BOTH  DEMAND 0116 * AND RESTART MODES. THREE NORMALL HALTS WILL FOLLOW. 0118 * 5.1.1 DEFAULT MODE -- ADDRESS :100 0120 * THE PAT404 PROGRAM IS SUPPLIED AS AN AUTOLOADABLE FLOPPY DISK.  0121 * PAT404 CAN BE STARTED AT LOCATION :100. AT THIS LOCATION, TESTS 0122 * 1,2,3,5, & 6 ARE EXECUTED CONTINUOUSLY. REFER TO 5.1.2 0123 * FOR A REGISTER RUN OPTIONS (THESE MUST BE SPECIFIED). 0124 * TEST 4 (IOT) EXECUTES IF THE I/O TEST CARD IS PRESENT. 0126 * 5.1.2 DEMAND MODE -- ADDRESS :101  0128 * THE PROGRAM CAN BE STARTED AT LOCATION :101 IF SPECIFIC TESTS OR RUN 0129 * OPTIONS ARE DESIRED. ENTER THE FOLLOWING INFORMATION IN THE CONSOLE 0130 * DATA REGISTER AT THIS ADDRESS.  0132 * CONSOLE DATA REG. BIT HEX 0133 * * ----------------------- ----- ----------- 0134 * 0 :0001 RUN TEST 1 (BIDP) 0135 * 1 :0002 RUN TEST 2 (UIT) 0136 * 3 :0008 RUN TEST 3 (RTC)  0137 * 4 :0010 RUN TEST 4 (IOT) 0138 * 5  :0020 RUN TEST 5 (FLPT) 0139 * 6 :0040 RUN TEST 6 (MEM:TST)  0140 * 7-15 NOT USED 0142 * TEST 1, BIDP, IS ALWAYS RUN, REGARDLESS OF TEST SELECTION. 0143 * ENTER THE FOLLOWING RUN OPTIONS IN THE A REGISTER AT ADDRESS :101  0145 * A REGISTER BIT RUN OPTION 1PAGE 0005 MACRO (F100) 1981/11/30 09:05:42.25 0146 * ---------------- ----------------------------------------- 0147 * 0148 *  0 NOT USED 0149 * 1 1= DO NOT HALT THE PROGRAM IF POWER UP AND 0150 * DOWN COUNTERS ARE UNEQUAL. (SEC. 5.5) 0151 * 0=HALT IF COUNTERS ARE UNEQUAL. 0152 * 2-15 NOT USED, ENTER ZERO 0154 * PRESS RUN AFTER ENTERING A REGISTER AND DATA REGISTER INFORMATION. 0155 *  PAT404 EXECUTES BIDP AND SELECTED TESTS CONTINUOUSLY. 0157 * 5.1.3 RESTART MODE -- ADDRESS :102  0159 * PAT404 CAN BE RESTARTED AT LOCATION :102. PASS COUNTERS AND POWER 0160 * FAIL COUNTERS REMAIN ACCUMULATIVE AT THIS ADDRESS. ENTER A REGISTER 0161 * RUN OPTIONS AND DATA REGISTER TEST SELECTIONS BEFORE RESTARTING 0162 * THE PROGRAM AT THIS ADDRESS. 0164 * 5.2 RUN INDICATION  0166 * DURING EXECUTION, THE LOWER NIBBLE (BITS 0-3) OF THE CONSOLE DATA 0167 * REGISTER NORMALLY DISPLAY THE TEST NUMBER. REFER TO THE SPECIFIC 0168 * TEST DESCRIPTION FOR DETAILED RUN INDICATION DESCR  IPTIONS. 0170 * 5.3 TERMINATION 0172 * 5.3.1 NORMAL TERMINATION  0174 * PRESS STOP TO TERMINATE PAT404. 0175 * THE PROGRAM CAN BE SUBSEQUENTLY 0176 * RESTARTED AT LOCATION :102. 0178 * 5.3.2 ERROR TERMINATION 0180 * PAT404 HALTS ON ANY ERROR CONDITION. EXAMINE THE P REGISTER AND 0181 * REFER TO THE PROGRAM LISTING TO DETERMINE THE CAUSE OF THE ERROR. 0183 * 5.4 CONSOLE INTERRUPT TESTING 0185 * PRESS INT DURING PAT404 EXECUTION TO TEST CONSOLE INTERRUPT 0186 * RECOGNITION. THE CONSOLE DATA REGISTER FLASHES AN ALTERNATING  0187 * :AAAA/:5555 PATTERN AND THE OV INDICATOR REMAINS ON FOR 0188 * APPROXIMATELY THREE SECONDS. IF INT IS PRESSED WHEN INTERRUPTS 1PAGE 0006 MACRO (F100) 1981/11/30 09:05:43.50 0189 * ARE DISABLED, THE INT INDICATOR REMAINS LIT UNTIL INTERRUPTS 0190 * ARE ENABLED. THE ALTERNATING PATTERN IS DISPLAYED WHEN 0191 * THE INTERRUPT IS SERVICED. 0193 * 5.5 POWER FAIL/POWER UP TESTING  0195 * ALL VOLATILE REGISTERS AND SIN STATE ARE SAVED AND THE POWER 0196 * DOWN COUNT (PDNCT) IS INCREMENTED IF A POWER FAILURE OCCURS. 0197 * WHEN POWER IS RESTORED, THE POWER UP COUNT (PUPCT) IS INCREMENTED, 0198 * THE CONTENTS OF VOLATILE REGISTERS ARE RESTORED, AND IF TESTS 1,2, 0199 * A, OR B WERE EXECUTING, PROGRAM EXECUTION IS RESUMED AT THE LOCATION 0200 * WHERE THE POWER FAILURE OCCURRED. IF TESTS 3,4,5, OR 6 0201 * WERE EXECUTING, PAT404 IS RESUMED AT THE BEGINNING OF BIDP. 0202 * AN ERROR HALT OCCURS IF PDNCTAND PUPCT ARE NOT EQUAL UNLESS THIS 0203 * HALT WAS SUPPRESSED (A-REGISTER RUN OPTION BIT 1=1) PRIOR TO PAT495 0204 * EXECUTION. PRESS RUN FOLLOWING THIS ERROR HALT TO RESUMEEXECUTION AT 0205 * THE BEGINNING OF BIDP.THE THREE HALTS (SEE SEC. 6.1) ARE BYPASSED. 0207 * 5.6 UNEXPECTED TRAPS 0209 * PAT404 HALTS IMMEDIATELY IF UNEXPECTED MEMORY EXCEPTION, 0210 * UNIMPLEMENTED INSTRUCTION, ARITHMETIC ERROR, OR SYSTEM/USER STACK 0211 * EXCEPTION TRAPS OCCUR. CONSOLE DATA REGISTER BITS 8-15 DISPLAY 0212 * :AA; BITS 0-7 REMAIN UNCHANGED. PRESS RUN TO RESTART PAT495.  0213 * BIDP BEGINS EXECUTION, ALTHOUGH THE THREE INITIAL HALTS ARE BYPASSED. 0215 * 6.0 TEST DESCRIPTIONS 0217 * 6.1 TEST 1, BASIC INSTRUCTION DIAGNOSTIC (BIDP) 0219 * BIDP EXERCISED ALL BASIC SCOUT NON-I/O INSTRUCTIONS IN THE NAKED MINI 0220 * 4 INSTRUCTION REPERTOIRE AND DETERMINES WHETHER EACH INSTRUCTION 0221 * PERFORMS AS EXPECTED, ALTHOUGH IT DOES NOT CHECK THE EFFECTS OF  0222 * INSTRUCTION EXECUTION ON UNINVOLVED REGISTERS OR MEMORY CELLS. 0223 * DURING BIDP, BITS 0-3 OF T HE CONSOLE DATA REGISTER DISPLAY :1. 0224 * THE TESTING IS CONDUCTED IN THE FOLLOWING ORDER.  0226 * 6.1.1 BASIC INSTRUCTION TESTING 0228 * THIS PART OF BIDP VERIFIES BASIC INSTRUCTIONS WHICH ARE REQUIRED 0229 * TO EXTENSIVELY TEST REMAINING INSTRUCTIONS. TESTING IS PERFORMED 0230 * USING ABSOLUTE DIRECT ADDRESSING, WORD MODE ONLY. 0231 * THREE HALTS OCCUR AT THE BEGINNING OF THIS TEST, DURING THE FIRST 1PAGE 0007 MACRO (F100) 1981/11/30 09:05:44.75 0232 * PASS OF BIDP. PRESS RUN AFTER EACH HALT TO CONTINUE PROGRAM 0233 * EXECUTION AFTER VERIFYING THE CONSOLE DATA REGISTER CONTENTS.  0234 * ALL HALTS AFTER HALT 3 ARE ERROR HALTS. 0236 * HALT ACTION 0237 * ---- ------ 0238 * HALT 1 CONSOLE DATA REGISTER SHOULD DISPLAY :B200  0239 * HALT 2 CONSOLE DATA REGISTER SHOULD DISPLAY :0117 0240 * HALT 3  CONSOLE DATA REGISTER SHOULD DISPLAY MACHINE TYPE 0242 * 6.1.2 SINGLE WORD MEMORY REFERENCE TESTING  0244 * SINGLE WORD MEMORY REFERENCE INSTRUCTION TESTING IS PERFORMED 0245 * AFTER BASIC INSTRUCTION TESTING. EXTENSIVE TESTING IS PERFORMED 0246 * ON COPY AND EXCH IN ALL MEMORY REFERENCE MODES; OTHER INSTRUCTIONS 0247 * ARE TESTED LESS EXTENSIVELY. 0249 * 6.1.3 REGISTER TO REGISTER TESTING 0251 * THE COPY INSTRUCTION IS TESTED WITH ALL REGISTER PAIR COMBINATIONS; 0252 * OTHER INSTRUCTIONS ARE TESTED WITH ONE REGISTER PAIR. THE OV BIT 0253 * IS CHECKED FOLLOWING THE EXECUTION OF NEG, ADD, OR SUB INSTRUCTION. 0255 * 6.1.4 SHIFT/ROTATE AND BIT MANIPULATION TEST  0257 * SINGLE REGISTER SHIFT/ROTATES ARE TESTED WITH ALL REGISTERS. ALL 0258 * SHIFT COUNTS (1-16) ARE TESTED WITH THE AREG. 0259 * BIT MANIPULATION INSTRUCTION SBIT IS TESTED ON REGISTERBITS 0-15;  0260 * ALL OTHER BIT MANIPULATION INSTRUCTIONS ARE TESTED ON ONE BIT ONLY. 0262 * 6.1.5 IMMEDIATE LITERAL TESTING 0264 * EACH INSTRUCTION IS TESTED WITH ONE REGISTER. THE OV BIT IS CHECKED 0265 * FOLLOWING THE EXECUTION OF AN ADD OR SUB INSTRUCTION. 0267 * 6.1.6 CONDITIONAL JUMP TESTING  0269 * EACH CONDITION WHICH CAUSES OR DOES NOT CAUSE A JUMP IS VERIFIED. 0271 * 6.1.7 MULTIPLE WORD MEMORY REFERENCE TESTING 0273 * ALL MEMORY REFERENCE MODES ARE CHECKED ON THE ADDC INSTRUCTION; 0274 * OTHER INSTRUCTIONS ARE TESTED LESS EXTENSIVELY. 1PAGE 0008 MACRO (F100) 1981/11/30 09:05:46.25  0275 * THE OV AND CY BITS ARE CHECKED FOLLOWING EXECUTION 0276 * OF AN ADDCOF SUBC INSTRUCTION. MUL AND DIV ARE TESTED FOR THE 0277 * FOUR COMBINATIONS OF POSITIVE AND NEGATIVE ARGUMENTS. ARITHMEI C 0278 * EXCEPTION TRAPS AND STACKEXCEPTION TRAPS (JSKE) ARE ALSO TESTED. 0280 * 6.1.8 STACK TESTING 0282 * INSTRUCTIONS ARE TESTED ON ALL ASPECTS OF CORRECT OPERATION. 0283 * STACK OVERFLOW TRAP OPERATION IS VERIFIED FOR JSK AND PUSH. 0284 * REGISTER EFFECTS ARE CHECKED FOR PUSH AND POP. 0286 * 6.1.9 TRAP EMULATION TESTING 0288 * STRAP AND UTRAP INSTRUCTIONS ARE VERIFIED FOR PROPER OPERATION. 0289 * EACH PASS OF BIDP TESTSEACH OF THE ABOVE GROUPS 64 TIMES.  0291 * 6.1.10 SOFTWARE AUTOLOAD TESTING (SAL INSTRUCTION) 0293 * THE SAL INSTRUCTION IS TESTED FOR THE FOLLOWING CONDITIONS: 0295 * 1) NO-CHAIN NO EXECUTE 0296 * 2) NO-CHAIN AND EXECUTE 0297 * 3) CHAIN NO EXECUTE 0298 * 4) CHAIN AND EXECUTE  0299 * 5) LOADING A NON-EXISTENCE FILE 0301 * 6.2 TEST 2, UNIMPLEMENTED INSTRUCTION TEST (UIT)  0303 * IN THIS TEST, ALL UNIMPLEMENTED INSTRUCTIONS ARE EXECUTED TO VERIFY 0304 * THE OPERATION OF THE UNIMPLEMENTED INSTRUCTION TRAP. 0305 * DURING UIT, BITS 0-3 OF THE CONSOLE DATA REGISTER DISPLAY :2 AND 0306 * BITS 8-15 DISPLAY THE UPPER 8 BITS OF THE UNIMPLEMENTED INSTRUCTION 0307 * CURRENTLY BEING TESTED. 0309 * 6.3 TEST 3, REAL-TIME CLOCK TEST (RTC) 0311 * RTC VERIFIES THAT THE REAL-TIME CLOCK CAN GENERATE TIMING ('TICK') 0312 * INTERRUPTS AND CHECKS THAT RTC INTERRUPTS OCCUR WHEN THE INCREMENT 0313 * LOCATION COUNT REACHES ZERO. RTC MONITORS LOCATION IS :91. 0314 * AN ERROR HALT OCCURS UNDER ANY OF THE FOLLOWING CONDITIONS: 0316 * 1. THE TIMING LOOP EXPIRES BEFORE A TIMING INTERRUPT ('TICK') 0317 * OCCURS. 1PAGE 0009 MACRO (F100) 1981/11/30 09:05:47.50 0318 * 2. INCREMENT LOCATION :91 IS INCREMENTED BY A VALUE OTHER 0319 *  THAN 1. 0320 * 3. A RTC INTERRUPT IS NOT TAKEN WHEN LOCATION :91 IS ZERO. 0321 * 4. A RTC INTERRUPT IS TAKEN WHEN LOCATION :91 IS NOT ZERO. 0322 * 5. INCREMENT LOCATION :91 IS NOT -1 IMMEDIATELY PRIOR TO THE 0323 * RTC INTERRUPT. 0325 * RTC ALSO PERFORMS A REAL-TIME CLOCK CONSISTANCY TEST. THE RTC IS 0326 * RUN FOR ABOUT .25 SECOND AND AN AVERAGE 2-TICK SOFTWARE COUNT IS 0327 * TAKEN. A +/-6% WINDOW IS CALCULATED ON THIS SOFTWARE COUNT, AND  0328 * USED TO DETERMINE THE CONSISTENCY OF THE RTC OVER A 4-SECOND SPAN. 0329 * DURING RTC, BITS 0-3 OF THE CONSOLE DATA REGISTER DISPLAY :3. 0330 * DURING THE FIRST PART OF RTC, THE OV INDICATOR BLINKS (ABOUT 2 SEC.), 0331 * DURING THE SECOND PART OF RTC, BITS 12-15 OF THE CONSOLE DATA 0332 * REGIST ER DISPLAY A COUNTER INCREMENTING FROM 0 TO F (ABOUT 4 SEC.). 0334 * 6.4 TEST 4, I/O TEST (IOT)  0336 * IOT TESTS ALL INPUT/OUTPUT FUNCTIONS OF THE PROCESSOR. IN ADDITION 0337 * IT VERIFIES ALL MOTHERBOARD SIGNALS AND FEATURES OF PROCESSOR 0338 * OPERATION ASSOCIATED WITH INTERRUPTS.  0340 * * * NOTE * * * AN I/O TEST MODULE IS REQUIRED FOR THIS TEST. 0342 * THE INDIVIDUAL TESTS IN IOT ARE: 0344 * 1. PROGRAMMED I/O INSTRUCTION TESTING 0345 * 2. I/O CLOCKS TESTING 0346 * 3. INTERRUPT INSTRUCTION TESTING 0347 * 4. AUTO I/O INSTRUCTION TESTING 0348 * 5. INSTRUCTION NON-INTERRUPTABILITY TESTING 0349 * 6. DMA TESTING (WILL BE ADDED AT A LATER DATE) 0350 * 7. POWER-FAIL TESTING 0352 *  DURING IOT, BITS 0-3 OF THE CONSOLE DATA REGISTER DISPLAY :4. 0353 * BITS 8-15 DISPLAY :0F FOR ABOUT .25 SECOND, AND THEN :FF FOR ABOUT 0354 * 3.0 SECONDS. (THE TEST LASTS ABOUT 4.0 SECONDS.) 0356  * 6.5 TEST 5, FLOATING POINT INSTRUCTION TEST (FLPT) 0358 * THIS TEST VERIFIES THE CORRECT OPERATION OF THE FLOATING POINT CLASS 0359 * OF INSTRUCTIONS, PLUS FIX AND FLOAT (CONSOLE AND CONTROL CLASS).  0360 * THE TEST CHECKS FOR CORRECT RESULTS WITH A WIDE RANGE OF OPERANDS 1PAGE 0010 MACRO (F100) 1981/11/30 09:05:49.00 0361 * FOR EACH INSTRUCTION TESTED. THE ADDRESSED MEMORY LOCATIONS AND 0362 * THE X AND Y REGISTERS ARE TESTED FOR SIDE EFFECTS. ARITHMETIC 0363 * ERROR TRAP OPERATION IS CHECKED. ONLY RELATIVE ADDRESSING MODE 0364 * IS TESTED. 0365 * DURING FLPT, BITS 0-3 OF THE CONSOLE DATA REGISTER DISPLAY :5. 0367 * 6.6 TEST 5, MEMORY TEST (MEM:TST) 0369 * THIS TEST VERIFIES ALL INSTALLED MEMORY TO BE FUNCTIONAL. 0370 * THE MEMORY IS TESTED FROM LOW MEMORY TO HIGH MEMORY,FROM HIGH 0371 * MEMORY TO LOW MEMORY,AND IN BYTE MODE FROM LOW MEMORY TO HIGH 0372 * MEMORY.IF AN UNIMPLIMINTED MEMORY TRAP OCCURS THE REST OF THE 0373 * TEST WILL BE SKIPPED AND THE X REGISTER WILL CONTAIN THE SIZE 0374 * OF THE INSTALLED MEMORY. DURING MEM:TST, BITS 0-3 OF THE CONSOLE 0375 * DATA REGISTER DISPLAY :6 0377 * 7.0 PROGRAM FLOW (HIGH LEVEL) 0379 * BEGIN BASIC INSTRUCTION TEST 0380 * EXECUTE BASIC INSTRUCTION TEST 0381 * IF ERROR OCCURS  0382 * THEN ERROR HALT 0383 * ELSE 0384 * EXECUTE UNIMPLIMINTED INSTRUCTION TEST 0385 * IF ERROR OCCURS 0386 * THEN ERROR HALT 0387 * ELSE 0388 * EXECUTE REAL-TIME CLOCK TEST 0389 * IF ERROR OCCURS   0390 * THEN ERROR HALT 0391 * ELSE 0392 * EXECUTE I/O TEST  0393 * IF ERROR OCCURS 0394 * THEN ERROR HALT 0395 * ELSE  0396 * EXECUTE FLOATING POINT INSTRUCTION TEST 0397 * IF ERROR OCCURS 0398 *  THEN ERROR HALT 0399 * ELSE 0400 * EXECUTE MEMORY TEST 0401  * IF ERROR OCCURS 0402 * THEN ERROR HALT 0403 * ELSE 1PAGE 0011 MACRO (F100) 1981/11/30 09:05:50.00 0404 * END PAT404 0406 * 7.1 PROGRAM FLOW (LOW LEVEL) 0408 * BEGIN BASIC INSTRUCTION TEST 0409 * COPY P REGISTER TO A REGISTER  0410 * SEND A REG. TO CDR 0411 * HALT 0412 * P REGISTER SHOULD BE :B200  0413 * (PRESS RUN TO CONTINUE PROGRAM) 0414 * COPY P REGISTER TO A REGISTER  0415 * SEND A REG. TO CDR 0416 * HALT 0417 * P REGISTER SHOULD BE :0117 0418 * (PRESS RUN TO CONTINUE PROGRAM) 0419 * FETCH MACHINE TYPE 0420 * SEND MACHINE TYPE TO CDR 0421 * HALT 0422 * (PRESS RUN TO CONTINUE PROGRAM) 0423 * SET STATUS REG TO :150 0424 * SHOULD REST OF THE TEST BE EXECUTED  0425 * IF NOT 0426 * THEN JUMP BIDP 0427 * ELSE 0428 * (FROM THIS POINT ON IF AN ERROR OCCURS THE 0429 * PROGRAM WILL HALT) 0430 *  TEST COPY AND CSK INSTRUCTIONS 0431 * TEST JUMP INSTRUCTIONS 0432 * TEST OVERFLOW BIT MANIPILIATION INSTRUCTIONS 0433 * TEST IMS INSTRUCTION 0434 * TEST STANDARD SHIFT INSTRUCTION(IN BOTH THE 01 AND 02) 0435 * TEST FMT AND XNX INSTRUCTIONS 0436 * TEST IN INSTRUCTION 0437 * TEST UIS AND SST INSTRUCTIONS 0438 * TEST COPY INSTRUCTION IN ALL ADDRESSING MODES 0439 * TEST ADD AND SUB INSTRUCTIONS 0440 * TEST EXCH INSTRUCTION IN ALL ADDRESSING MODES 0441 * TEST JST INSTRUCTION 0442 * TEST NEG, AND, OR, AND XOR INSTRUCTIONS 0443 * TEST SHIFT AND ROTATE INSTRUCTIONS 0444 * TEST CSM AND CSN INSTRUCTIONS 0445 * TEST SBIT, RBIT, CBIT, TBIT INSTRUCTIONS 0446 * TEST IJEQ AND IJNE INSTRUCTIONS 1PAGE 0012 MACRO (F100) 1981/11/30 09:05:51.00 0447 * TEST JEQD AND JNED INSTRUCTIONS 0448 * TEST JT AND JF INSTRUCTIONS 0449 * TEST ADDC INSTRUCTION IN ALL ADDRESSING MODES 0450 * TEST JSKE INSTRCUTION 0451 * TEST CEA AND CSME INSTRUCTIONS   0452 * TEST SUBC INSTRUCTION 0453 * TEST MUL AND DIV INSTRUCTIONS 0454 *  TEST JSK AND RSK INSTRUCTION 0455 * TEST PUSH AND POP INSTRUCTIONS 0456 * TEST STRAP AND UTRAP INSTRUCTIONS 0457 * TEST SAL INSTRUCTION 0458 * END BASIC INSTRUCTION TEST 0460 * BEGIN UNIMPLIMINTED INSTRUCTION TEST 0461 * SET STATUS REGISTER TO :150  0462 * FILL IN TEMPORARY UNIMPLIMINTED INSTRUCTION TRAP 0463 * GET FIRST UNIMPLIMINTED INSTRUCTION FROM TABLE 0464 * EXEC: 0465 * EXECUTE UNIMPLIMINTED INSTRUCTION  0466 * IF TRAP DOES NOT OCCUR 0467 * THEN ERROR HALT 0468 * ELSE  0469 * PUT INSTRUCTION WHICH CAUSED TRAP IN Q 0470 * MASK OFF DONT CARE BITS  0471 * IF Q NOT EQUAL :700 0472 * THEN CHECK FIRST WORD OF TRAP 0473 *  IF FIRST WORD OF TRAP NOT EQUAL TO P+2 0474 * THEN ERROR HALT 0475 * ELSE 0476 * JUMP TO INST: 0477 * ELSE 0478 * CHECK FIRST WORD OF TRAP 0479 * IF FIRST WORD OF TRAP NOT EQUAL TO P+1 0480 * THEN ERROR HALT  0481 * ELSE 0482 * INST: 0483 * CHECK SECOND WORD OF TRAP  0484 * IF SECOND WORD OF TRAP NOT EQUAL TO THE 0485 * INSTRUCTION WHICH CAUSED THE TRAP  0486 * THEN ERROR HALT 0487 * ELSE 0488 * INCREMENT TABLE  0489 * IF MORE INSTRUCTIONS LEFT IN TABLE 1PAGE 0013 MACRO (F100) 1981/11/30 09:05:52.00 0490 * THEN JUMP TO EXEC: 0491 * ELSE 0492 * END UNIMPLIMINTED INSTRUCTION TEST 0494 * BEGIN REAL-TIME CLOCK TEST 0495 * SET STATUS REGISTER TO :140  0496 * SELP TEST CODE TO CDR 0497 * SET UP REAL-TIME CLOCK INTERRUPT VECTOR 0498 * SET INCREMENT COUNTER TO :FF10 (-240) 0499 * N31011: 0500 * COPY ZERO INTO Q  0501 * INCREMENT COUNTER 0502 * N31012: 0503 * INCREMENT Q, AND JUMP TO N31013 IF Q=0 0504 * IF INCREMENT CELL NOT EQUAL TO COUNTER 0505 * THEN JUMP TO N31012 0506 * ELSE 0507 * IF INCREMENT CELL = ZERO 0508 *  THEN ERROR HALT (INTERRUPT SHOULD OCCUR WHEN 0509 * INTERRUPT CELL GOES TO ZERO) 0510 * ELSE 0511 * JUMP N31011 0512 * (INTERRUPT SHOULD OCCUR DURING THOSE LOOPS  0513 * AND IT SHOULD VECTOR TO INT:VEC) 0514 * INT:VEC: 0515 * P UT INCREMENT CELL IN A 0516 * IF A NOT EQUAL 0 0517 * THEN ERROR HALT  0518 * ELSE 0519 * RESET BIT 5 IN S 0520 * SET STATUS REGISTER TO :40  0521 * GET INCREMENT CELL (LOCATION :91) 0522 * IF INCREMENT CELL NOT EQUAL 0  0523 * THEN ERROR HALT 0524 * ELSE 0525 * IF COUNTER NOT EQUAL ZERO  0526 * THEN ERROR HALT 0527 * ELSE 0528 * RTC CONTISTENCY TEST: 0529 * SET STATUS REGISTER TO :40 0530 * SET LOOP COUNTER TO -9 0531 * SET SOFTWARE COUNT TO 0 0532 * N31031: 1PAGE 0014 MACRO (F100) 1981/11/30 09:05:53.00  0533 * SET SOFTWARE TIC COUNT TO 0 (LOCATION :91) 0534 * SET UP INTERRUPT VECTOR  0535 * SET STATUS REGISTER TO :160 0536 * INCREMENT COUNTER 0537 * JUMP $-1 (INTERRUPT SHOULD OCCUR) 0538 * IF INTERRUPT DID NOT OCCUR 0539 * THEN ERROR HALT 0540 * INT:ROU: 0541 * RESET BIT 5 IN STATUS REGISTER 0542 *  IF TIC COUNT (LOCATION :91) NOT EQUAL 0 0543 * THEN ERROR HALT 0544 * ELSE  0545 * IF LOOP COUNTER = -9 0546 * THEN SET SOFTWARE COUNT TO 0 0547 * JUMP N31031 0548 * ELSE 0549 * IF COUNTER < 0 0550 *  THEN JUMP N31031 0551 * ELSE 0552 * DIVIDE SOFTWARE COUNT BY 8  0553 * SAVE IN MEMORY WORD LOW 0554 * DIVIDE SOFTWARE COUNT BY 32 0555 * SAVE IN Q 0556 * ADD LOW TO Q 0557 * SAVE IN MEMORY LOCATION HIGH (HIGH COUNT LIMIT)  0558 * SUB Q FROM LOW 0559 * SAVE IN MEMORY LOCATION LOW (LOW COUNT LIMIT)  0560 * SET LOOP COUNTER TO :FF10 0561 * N31033: 0562 * SET SOFTWARE COUNT TO 0 0563 * SET TIC COUNT TO -2 (LOCATION :91) 0564 * SET UP INTERRUPT ROUTINE  0565 * SET STATUS REGISTER TO :160 0566 * HERE: 0567 * INCREMENT SOFTWARE COUNT 0568 * IF SOFTWARE COUNT NOT EQUAL 0 0569 * THEN JUMP HERE  0570 * ELSE ERROR HALT 0571 * (THE REAL TIME CLOCK INTERRUPT SHOULD OCCUR 0572 *  BEFORE THE COUNT =0 AND WILL VECTOR TO INT:VEC3) 0573 * INT:VEC3 0574 * RESET BIT 5 IN STATUS REGISTER 0575 * IF TIC COUNT (LOCATION :91) NOT EQUAL 0 1PAGE 0015 MACRO (F100) 1981/11/30  09:05:54.00 0576 * THEN ERROR HALT 0577 * ELSE 0578 * IF  LOOP COUNTER =:FF10 0579 * THEN INCREMENT LOOP COUNTER 0580 * JUMP N31033  0581 * ELSE 0582 * IF SOFTWARE COUNT >= HIGH LIMIT 0583 * THEN ERROR HALT 0584 * ELSE 0585 * IF SOFTWARE COUNT < LOW LIMIT 0586 * THEN ERROR HALT 0587 * ELSE 0588 * IF LOOP COUNTER < 0 0589 * THEN JUMP N31033 0590 * ELSE 0591 * END REAL-TIME CLOCK TEST  0593 * BEGIN I/O TEST 0594 * COPY 0 IN Q 0595 * OUTPUT Q TO CDR  0596 * INPUT CDR INTO A 0597 * IF Q AND A ARE NOT EQUAL 0598 * THEN ERROR HALT 0599 * COPY :AAAA INTO X 0600 * OUTPUT X INTO CDR 0601 *  INPUT CDR INTO Q 0602 * IF Q AND X ARE NOT EQUAL 0603 * THEN ERROR HALT  0604 * COPY :5555 INTO Y 0605 * OUTPUT Y INTO CDR 0606 * INPUT CDR INTO X 0607 * IF X AND Y NOT EQUAL 0608 * THEN ERROR HALT 0609 *  COPY :FFFF INTO A 0610 * OUPUT A TO CDR 0611 * INPUT CDR INTO Y  0612 * IF A AND Y ARE NOT EQUAL 0613 * THEN ERROR HALT 0614 * ELSE  0615 * INTERRUPT INSTRUCTIONS 0616 * (JST AS AN INTERRUPT INSTRUCTION) 0617 * RESET BIT 8 IN STATUS REGISTER 0618 * SET UP INTERRUPT VECTOR 1PAGE 0016 MACRO (F100) 1981/11/30 09:05:55.00 0619 * OUTPUT :6F0 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0620 * SIN 2  0621 * SET BIT 8 IN STATUS REGISTER 0622 * IF INTERRUPT DID NOT OCCUR  0623 * THEN ERROR HALT 0624 * ELSE 0625 * IF MORE THAN 2 INSTRUCTIONS EXECUTED BEFORE INTERRUPT 0626 * THEN ERROR HALT 0627 * ELSE 0628 * (JSK AS INTERRUPT INSTRUCTION) 0629 * SET STATUS REGISTER TO :150 0630 * SET UP INTERRUPT VECTOR 0631 * * * * * MORE 0632 * (AUTO I/0 OUTPUT) 0633 * RESET THE CRT 0634 * SET UP INTERRUPT VECTOR (BEGINNING AT :E0) 0635 * OUTPUT :612 TO LOCATION :F9 (TO START AUTO I/O) 0636 * SET BIT 8 IN STATUS REGISTER 0637 * WAIT A WHILE 0638 * IF E-O-B INTERRUPT DID NOT OCCUR 0639 * THEN ERROR HALT 0640 * ELSE 0641 * (AUTO I/O INPUT) 0642 * RESET BIT 8 IN STATUS REGISTER 0643 * SET UP INTERRUPT VECTOR (BEGINNING AT :E0) 0644 * OUTPUT :610 TO  LOCATION :F9 (TO START AUTO I/O) 0645 * SET BIT 8 IN STATUS REGISTER 0646 * WAIT A WHILE 0647 * IF E-O-B INTERRUPT DID NOT OCCUR 0648 * THEN ERROR HALT  0649 * ELSE 0650 * NON-INTERRUPTABLE INSTRUCTIONS 0651 * (JST)  0652 * SET STATUS REGISTER TO :150 0653 * SET UP INTERRUPT VECTOR 0654 * OUTPUT :6F2 TO LOCATION :F9 (TO CREATE INTERRUPT) 0655 * IF JST INSTRUCTION INTERRUPTED 0656 * THEN ERROR HALT 0657 * ELSE 0658 * IF INTERRUPT DID NOT OCCUR AFTER JST  0659 * THEN ERROR HALT 0660 * ELSE 0661 * (JSK) 1PAGE 0017  MACRO (F100) 1981/11/30 09:05:56.00 0662 * SET STATUS REGISTER TO :150 0663 * SET UP INTERRUPT VECTOR 0664 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0665 *  IF JSK INSTRUCTION INTERRUPTED 0666 * THEN ERROR HALT 0667 * ELSE  0668 * IF INTERRUPT DID NOT OCCUR AFTER JSK INSTRUCTION EXECUTED 0669 * THEN ERROR HALT  0670 * ELSE 0671 * (JSKE) 0672 * SET STATUS REGISTER TO :150  0673 * SET UP INTERRUPT VECTOR 0674 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT)  0675 * IF JSKE INSTRUCTION INTERRUPTED 0676 * THEN ERROR HALT 0677 * ELSE 0678 * IF INTERRUPT DID NOT OCCUR AFTER JSKE INSTRUCTION EXECUTED 0679 *  THEN ERROR HALT 0680 * ELSE 0681 * (PUSH) 0682 * SET STATUS REGISTER TO :150 0683 * SET UP INTERRUPT VECTOR 0684 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0685 * IF PUSH INSTRUCTION INTERRUPTED 0686 * THEN ERROR HALT 0687 * ELSE 0688 * IF INTERRUPT DID NOT OCCUR AFTER PUSH INSTRUCTION EXECUTED  0689 * THEN ERROR HALT 0690 * ELSE 0691 * (POP)  0692 * SET STATUS REGISTER TO :150 0693 * SET UP INTERRUPT VECTOR 0694 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0695 * IF POP INSTRUCTION INTERRUPTED 0696 * THEN ERROR HALT 0697 * ELSE 0698 * IF INTERRUPT DID NOT OCCUR AFTER POP INSTRUCTION EXECUTED 0699 * THEN ERROR HALT 0700 * ELSE 0701 *  (SBIT 8,S) 0702 * SET STATUS REGISTER TO :0 0703 * SET UP INTERRUPT VECTOR  0704 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 1PAGE 0018 MACRO (F100) 1981/11/30 09:05:57.00   0705 * IF SBIT 8,S INSTRUCTION INTERRUPTED 0706 * THEN ERROR HALT 0707 * ELSE 0708 * IF INTERRUPT DID NOT OCCUR AFTER SBIT 8,S INSTRUCTION EXECUTED 0709  * THEN ERROR HALT 0710 * ELSE 0711 * (CBIT 8,S) 0712 *  SET STATUS REGISTER TO :0 0713 * SET UP INTERRUPT VECTOR 0714 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT 0715 * IF CBIT 8,S INSTRUCTION INTERRUPTED 0716 * THEN ERROR HALT 0717 * ELSE 0718 * IF INTERRUPT DID NOT OCCUR AFTER CBIT 8,S INSTRUCTION EXECUTED 0719 * THEN ERROR HALT 0720 * ELSE 0721 * (XNX) 0722 * SET STATUS REGISTER TO :0 0723 * SET UP INTERRUPT VECTOR 0724 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0725 * IF XNX INSTRUCTION INTERRUPTED  0726 * THEN ERROR HALT 0727 * ELSE 0728 * IF INTERRUPT DID NOT OCCUR AFTER XNX INSTRUCTION EXECUTED 0729 * THEN ERROR HALT 0730 * ELSE  0731 * (UIS) 0732 * SET STATUS REGISTER TO :0 0733 * SET UP INTERRUPT VECTOR 0734 * OUTPUT :6F2 TO LOCATION :F9 (TO CAUSE INTERRUPT) 0735 * IF UIS INSTRUCTION INTERRUPTED 0736 * THEN ERROR HALT 0737 * ELSE 0738 * IF INTERRUPT DID NOT OCCUR AFTER UIS INSTRUCTION EXECUTED 0739 * THEN ERROR HALT 0740 *  ELSE 0741 * END INPUT OUTPUT TEST 0742 * 0744 * BEGIN FLOATING POINT TEST 0745 * IF CPU BEING TESTED IS AN 4/04-01 0746 * THEN JUMP END:1  0747 * ELSE 1PAGE 0019 MACRO (F100) 1981/11/30 09:05:58.00 0748 * TEST FIX INSTRUCTION  0749 * IF ERROR OCCURS 0750 * THEN ERROR HALT 0751 * TEST FLOAT INSTRUCTION 0752 * IF ERROR OCCURS 0753 * THEN ERROR HALT 0754 * ELSE 0755 * TEST CSKF INSTRUCTION IN ALL ADDRESSSING MODES 0756 * IF ERROR OCCURS 0757 * THEN ERROR HALTS 0758 * ELSE 0759 * TEST ADDF INSTRUCTION 0760 * IF ERROR OCCURS 0761 * THEN ERROR HALTS 0762  * ELSE 0763 * TEST SUBF INSTRUCTION 0764 * IF ERROR OCCURS 0765 * THEN ERROR HALT 0766 * ELSE 0767 * TEST MULF INSTRUCTION  0768 * IF ERROR OCCURS 0769 * THEN ERROR HALT 0770 * ELSE   0771 * TEST DIVF INSTRUCTION 0772 * IF ERROR OCCURS 0773 * THEN ERROR HALT  0774 * ELSE 0775 * END:1 0776 * END FLOATING POINT INSTRUCTION TEST  0778 * BEGIN MEMORY TEST 0779 * SET UP UNIMPLIMINTED MEMORY TRAP 0780 * GET LOCATION OF PROGRAM END 0781 * USE LOCATION AS REFERENCE TO MEMORY ADDRESS 0782 * COPY :5000 INTO MEMORY LOCATION :5000 0783 * LOOP:9 0784 * ADD 1 TO NUMBER AND ADDRESS 0785 * COPY NUMBER INTO ADDRESS 0786 * IF NOT TO LOCATION :FFFF  0787 * THEN JUMP LOOP:9 0788 * ELSE 0789 * COPY CONTENTS OF MEMORY LOCATION :5000 IN X 0790 * LOOP12 1PAGE 0020 MACRO (F100) 1981/11/30 09:05:59.00 0791 * COMPARE X TO EXPECTED DATA 0792 * IF X IS NOT EQUAL TO EXPECTED DATA 0793 *  THEN ERROR HALT 0794 * ELSE 0795 * ADD 1 TO MEMORY ADDRESS 0796 * IF NOT TO LOCATION :FFFF 0797 * THEN JUMP LOOP12 0798 * ELSE  0799 * SET MEMORY ADDRESS AT :FFFF 0800 * LOOP14 0801 * READ MEMORY ADDRESS  0802 * IF MEMORY ADDRESS NOT EQUAL TO EXPECTED VALUE 0803 * THEN ERROR HALT  0804 * ELSE 0805 * IF NOT TO MEMORY LOCATION :5000 0806 * THEN JUMP TO LOOP14 0807 * ELSE 0808 * BYTE TEST 0809 * SET MEMORY ADDRESS TO :5000 0810 * SET BYTE MODE 0811 * LOOP22 0812 * COPY :55 IN LOWER BYTE 0813 * COPY :AA IN UPPER BYTE 0814 * INCREMENT MEMORY ADDRESS  0815 * IF NOT TO MEMORY LOCATION :FFFF 0816 * THEN JUMP LOOP22 0817 * ELSE 0818 * SET MEMORY ADDRESS AT :5000 0819 * SET BYTE MODE 0820 *  LOOP33 0821 * READ UPPER BYTE 0822 * IF UPPER BYTE NOT EQUAL TO EXPECTED DATA  0823 * THEN ERROR HALT 0824 * ELSE 0825 * READ LOWER BYTE  0826 * IF LOWER BYTE NOT EQUAL TO EXPECTED DATA 0827 * THEN ERROR HALT  0828 * ELSE 0829 * IF NOT TO LOCATION :FFFF 0830 * THEN JUMP LOOP33  0831 * ELSE 0832 * END MEMORY TEST 1PAGE 0021 MACRO (F100) 1981/11/30 09:06:00.00  0834 * 8.0 OPERATION SUMMARY 0836 * 8.1 DEFAULT MODE 0838 * 1) LOAD AND EXECUTE THE PAT404 PROGRAM AT ADDRESS :100. 0839 * BIDP, UIT, RTC, IO, FLPT, AND MEM:TST AR E EXECUTED 0840 * CONTINUOUSLY. (PRESS RUN AFTER EACH OF THE THREE HALTS 0841 *  DURING BIDP. 0842 * 2) PRESS STOP TO TERMINATE EXECUTION. PRESS RUN TO CONTINUE 0843 * AFTER ANY ERROR HALT. 0845 * 8.2 DEMAND MODE 0847 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :101 INTO 0848 * THE P REGISTER. 0849 * 2) ENTER RUN OPTIONS IN THE A REGISTER AS FOLLOWS: 0851 * BIT 0 NOT USED 0852 * BIT 1  0=> HALT IF PDNCT AND PUPCT ARE NOT EQUAL 0853 * 1 => DO NOT HALT IF PDNCT AND PUPCT ARE NOT EQUAL 0854 * BITS 2-15 NOT USED 0855 * 3) SET THE CONSOLE DATA REGISTER BITS CORRESPONDINS TO THE 0856 * DESIRED TESTS, AS FOLLOWS: 0858 * BIT 0 RUN BASIC INSTRUCTION TEST 0859 * BIT 1 RUN UNIMPLIMINTES INSTRUCTION TEST 0860 *  BIT 3 RUN REAL-TIME CLOCK TEST 0861 * BIT 4 RUN INPUT OUTPUT TEST 0862 *  BIT 5 RUN FLOATING POINT TEST 0863 * BIT 6 RUN MEMORY TEST 0865 * 4) PRESS RUN. THE SELECTED TESTS ARE RUN CONTINUOUSLY. 0866 * (PRESS RUN AFTER EACH OF THE THREE HALTS DURING THE 0867 * BASIC INSTRUCTION TEST) 0869 * 8.3 RESTART MODE 0871 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :102 INTO THE 0872 * P REGISTER  0873 * 2) FOLLOW STEPS 2 THRU 5 AS DESCRIBED IN DEMAND MODE. PASS 0874 * COUNTERS AND POWER FAIL COUNTERS REMAIN ACCUMULATIVE AT 0875 * THIS ADDRESS. 0876 * 1) LOAD THE PAT404 PROGRAM AND ENTER ADDRESS :102 INTO THE 1PAGE 0022 MACRO (F100) 1981/11/30 09:06:01.25 0877 *  P REGISTER. 0878 * 2) FOLLOW STEPS 2 THROUGH 5 AS DESCRIBED IN DEMAND MODE. 0879 * PASS COUNTERS AND POWER FAIL COUNTERS REMAIN 0880 * ACCUMULATIVE AT THIS ADDRESS. 0881 END 0000 ERRORS (0000/0000) 0000 WARNINGS (0000/0000) 76 * 1) LOAD THE PATIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII! IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIe811130160816811130160816811130160816e@811130160816811130160816811201105659" e811130160816811130160816811130160816e811130160816811130160816811130160816811130160816811130160816811130160816# $ % & e811005125706811005125706811201105841e 81100512570681113009172925811201105840e' 811005125706811005125706811201105828e811005125706811005125706811005125706811005125706811005125706811005125706eK8111251448307581112514484025811130091535e=y88111300904030081113009041025811130091625eA`8110090816080081113009060175811130091724( . PAT404 MACPAT404:DOC ASMPAT404:DOC LST TITL PAT405 DIAGNOSTIC MACROS (PAT405.MAC) TITL MACRO TABLE OF CONTENTS *  PAGE * **** ERROR: --ERROR INDICATION TO USER...........8 * **** PATCHX --LOOP PATCHING MACRO (SHORT FORM)...8 * **** TRLD: --LOAD AND TEST REGISTERS............9 * **** GLPOL: --GENERATE LPOOL MACRO..............10 * **** CKSTD: --TEST REGS FOR STANDARD VALUES.....11 * **** LDSTD: --LOAD REGS WITH STANDARD VALUES....11 * **** LDREG: --LOAD REGISTERS....................12 * **** LODREG --LOAD SINGLE REGISTER..............13 * **** TREGS: --TEST REGISTERS....................14 * **** TSTREG --TEST SINGLE REG. AGAINST VALUE....14 * **** TMEM: --TEST MEMORY AGAINST VALUES........45 * **** LDMEM: --LOAD MEMORY WITH SPECIFIED VALUES.15 * **** OPTEST --FLOATING POINT INSTR TEST MACRO...16 * **** FLTEST --FLOATING POINT PRETEST MACRO......20 * **** FPADDR --FL. PT ADDRESS MODES TEST.........21 * TITL TABLE OF CONTENTS--INSTRUCTION TEST MACROS ****  DLOAD: --TEST DLOADS INSTRUCTION...........22 * **** DSTOR: --TEST DSTORS INSTRUCTION...........23 * **** DPREC --TEST DBLADD & DBLSUB INSTRUCTIONS.24 * **** CVDP: --TEST CVTDBL INSTRUCTION...........25 * **** SGWT: --TEST SIGNAL & WAIT INSTRUCTIONS...26 * **** SPUSH: --TEST SINGLE REGISTER PUSH INSTR...27 * **** SPOP: --TEST SINGLE REGISTER POP INSTR....28 * **** XTR: --TEST XTR & XTRS INSTRUCTIONS......29 * **** INSR: --TEST INSR INSTRUCTION.............30 * **** PROC: --TEST ENTER & RETURN INSTRUCTIONS..31 * **** ENQUE: --TEST ENQUEB INSTRUCTION...........32 * **** DEQUE: --TEST DEQUEN INSTRUCTION...........33 * **** DELQ: --TEST DELQUE INSTRUCTION...........34 * **** NEXTQ: --TEST NEXTQUE INSTRUCTION..........35 * **** ENQA: --TEST ENQUEA INSTRUCTION...........36 * **** BLKMOV --TEST MOVE INSTRUCTION.............37 * **** COPYU --TEST LODU & STRU INSTRUCTIONS.....38 * **** CSKS: --TEST CSKS INSTRUCTION.............39 * **** S:ECC --TEST STRECC INSTRUCTION...........40 * **** L:ECC --TEST LODECC INSTRUCTION...........41 * **** G:ECC --TEST GENECC INSTRUCTION...........42 * **** STOR:K --TEST K-RELATIVE STORE INSTRUCTION.43 * **** LOAD:K --TEST K-RELATIVE LOAD INSTRUCTION..44 * TITL MACRO DEFINITIONS * * U S E R D E F I N E D O P---C O D E S * BITS MACRO S1 SYMATT #(1) IFT S1&:800 S1  SET S1++:400 ENDC S1 SET S1&:700%-4 R1 SET R1++S1 WORD R1 S1 SYMVAL #(1) WORD S1 ENDM TITL STRU MACRO :5C15 STORE AREG IN USER SPACE LODU MACENT :5C25 LOAD AREG FROM USER SPACE LCNTX MACENT :5C45 LOAD CONTEXT CVTDBL MACENT :260D CONVERT TO DOUBLE PRECISION WAIT MACENT :262D WAIT ON SEMAPHORE SIGNAL MACENT :26) 1D SIGNAL SEMAPHORE DEQUEN MACENT :264D REMOVE QUEUE ELEMENT FOLLOWING REFERENCE ELEMENT ENQUEB MACENT :263D INSERT QUEUE ELEMENT BEFORE REFERENCE ELEMENT MOVE MACENT :267D BLOCK MOVE WORD RETURN MACENT :266D RETURN FROM PROCEDURE STRECC MACENT :26AD STORE ERROR CORRECTION CODE LODECC MACENT :26BD LOAD ERROR CORRECTION CODE GENECC MACENT :26CD GENERATE ERROR CORRECTION CODE ENQUEA MACENT :26DD INSERT QUEUE ELEMENT AFTER REFERENCE ELEMENT DELQUE MACENT :26ED DELETE QUEUE ELEMENT REFERENCED NEXTQUE MACENT :26FD POINT TO NEXT QUEUE ELEMENT WORD #(0) ENDM SPACE 1 PUSH: MACRO :0F05 PUSH SINGLE REGISTER ONTO STACK POP: MACENT :0F07 POP SINGLE REGISTER FROM STACK R1 SYMVAL #(1) R1 SET R1&6%12++#(0) WORD R1 ENDM ENTER MACRO :265D ENTER PROCEDURE SCNTX MACENT :5C35 SAVE CONTEXT WORD #(0) S1 SYMVAL #(1) WORD #(1) ENDM TITL MULS MACRO :1F80 MULTIPLY -- STACK RELATIVE DIVS MACENT :1F81 DIVIDE -- STACK RELATIVE CEAS MACENT :1F84 COMPUTE EFFECTIVE ADDRESS -- STACK RELATIVE DLOADS MACENT :1F86 LOAD DOUBLE REGISTER -- STACK RELATIVE LOADS MACENT :1F88 LOAD SINGLE REGISTER -- STACK RELATIVE ADDS MACENT :1F8A ADD TO REGISTER -- STACK RELATIVE SUBS MACENT :1F8B SUBTRACT FROM REGISTER -- STACK RELATIVE EXCHS MACENT :1F8C EXCHANGE WITH REGISTER -- STACK RELATIVE R1 SYMVAL #(2) R1 SET R1&6%12++#(0) BITS #(1) ENDM SPACE 2  SPACE 2 CSMS MACRO :1F85 COMPARE MAG. & SKIP 3 WAY -- STACK RELATIVE DSTORS MACENT :1F87 STORE DOUBLE REGISTERS -- STACK RELATIVE STORS MACENT :1F89 STORE SINGLE REGISTER -- STACK RELATIVE R1 SYMVAL #(1) R1 SET R1&6%12++#(0) BITS #(2) ENDM SPACE 2 SPACE 2 ADDCS MACRO :1F82 ADD WITH CARRY -- STACK RELATIVE SUBCS MACENT :3F82 SUBTRACT WITH CARRY -- STACK RELATIVE ANDS MACENT :1F8E 'AND' TO REGISTER -- STACK RELATIVE ORS MACENT :3F8E 'OR' TO REGISTER -- STACK RELATIVE XORS MACENT :1F8F 'EXCLUSIVE OR' TO REGISTER -- STACK RELATIVE R1 SYMVAL #(2) R1 SET R1&4%12++#(0) BITS #(1) ENDM TITL CSKS MACRO :3F8F COMPARE & SKIP 3 WAY -- STACK RELATIVE R1  SYMVAL #(1) R1 SET R1&4%12++#(0) BITS #(2) ENDM SPACE 2 JSKS MACRO :1F83 JUMP & STACK -- STACK RELATIVE JMPS MACENT :1F8D JUMP -- STACK RELATIVE JSTS MACENT :3F8D JUMP & STORE -- STACK RELATIVE IMSS MACENT :5F8D INCREMENT & SKIP IF ZERO -- STACK RELATIVE DMSS MACENT :7F8D DECREMENT & SKIP IF ZERO -- STACK RELATIVE DBLADDS MACENT :268B ADD TO DOUBLE REGISTER -- STAK RELATIVE DBLSUBS MACENT :268A SUBTRACT FROM DOUBLE REGISTERS -- STACK RELATIVE R1 SET #(0) BITS #(1) ENDM SPACE 2 INSR MACRO :030B INSERT BIT FIELD TO MEMORY XTR MACENT :030E EXTRACT BIT FIELD FROM MEMORY XTRS MACENT :030F EXTRACT BIT FIELD AND EXTEND SIGN R1 SYMVAL #(1) R1 SET R1&6%12++#(0) S1 SYMVAL #(2) S1 SET S1-1&15%4++R1 WORD S1 ENDM TITL STORK MACRO :1E80 STORE REGISTER -- STACK RELATIVE R1 SYMVAL #(1) GET REGISTER R1 SET R1&6%12++#(0) OR IN SKELETON AFTER SHIFTING S1 SYMATT #(2) GET ATTRIBUTES IFT S1&:800 ONLY INDIRECT OR NONE ALLOWED R1 SET R1++:40 S* ET INDIRECT BIT ENDC S1 SYMVAL #(2) GET D6 FIELD R1 SET R1++S1 OR D6 FIELD IN WORD R1 ENDM SPACE 2 LOADK MACRO :1E00 LOAD REGISTER -- STACK RELATIVE R1 SYMVAL #(2) R1 SET R1&6%12++#(0) S1 SYMATT #(1) IFT S1&:800 R1 SET R1++:40 ENDC S1 SYMVAL #(1) R1 SET R1++S1 WORD R1 ENDM TITL TEST MACRO DEFINITIONS * BREAK EQU 1 ****** * E R R O R M A C R O * * THIS MACRO IS USED TO INDICATE AN ERROR ****** XMACRO ERROR: HLT #(1) #(2) #(3) #(4) #(5) #(6) #(7) #(8) #(9) #(10) #(11) #(12)  ENDM SPACE 10 ****** * * P A T C H X M A C R O * ****** XMACRO PATCHX JMP #(1) PATCH FOR LOOPING ORG $-1 NOP OVERLAY WITH NOP ENDM TITL ****** * T E S T L O A D R E G M A C R O * * THIS MACRO COPIES THE REGISTER SPECIFIED * BY PARAMETER #(1) TO THE REGISTER SPECIFIED * BY PARAMETER #(3). IT THEN CHECKS THAT * THE VALUE MOVED TO THE REGISTER SPECIFIED * BY PARAMETER #(3) CONTAINS THE EXPECTED * VALUE BY MOVING THAT VALUE TO EITHER A OR Q * THEN COMPARING IT TO THE VALUE SPECIFIED * BY PARAMETER #(4) (MUST BE LABEL-CANNOT BE * A VALUE). * * A SAMPLE CALL FORMAT FOLLOWS: * * TRLD: REG,A OR Q,REG,LABEL NAME OF VALUE * * PARAMETER #(2) MUST BE EITHER A OR Q * PARAMETERS #(1) AND #(3) CAN BE ANY * REGISTER. VALUE MUST BE A BINARY * NUMBER (0-:FFFF) ****** XMACRO TRLD: SPACE BREAK * TRLD: #(1),#(2),#(3),#(4) COPY #(1),#(3) COPY #(3),#(2)  CSK #(2),#(4) TEST THAT #(3) = EXPECTED VALUE NOP ERROR: COPY,-#(1)-,TO,-#(3)-,FAILED COPY =0,#(2) CLEAR -#(2)- ENDM TITL ****** * G E N E R A T E L P O O L M A C R O * * THIS MACRO EXECUTES A JUMP AROUND AN LPOOL. * * SAMPLE CALL: * * GLPOL: ****** XMACRO GLPOL: LP::L SET $ SET UP LABEL TO REPLACE NOP WITH JMP INST. NOP RESERVE SPACE FOR JMP INSTRUCTION LPOOL LP::L1 SET $ SET UP LABEL AT END OF LPOOL ORG LP::L GO BACK TO OVERLAY NOP WITH JMP INST. JMP LP::L1 JUMP TO LABEL AT END OF LPOOL ORG LP::L1 CONTINUE AT END OF LPOOL ENDM TITL ****** * CKSTD: -- CHECK REGISTERS FOR STANDARD VALUES ****** * THIS MACRO TESTS 'A', 'Q', 'X', 'Y', 'K', AND 'L' WITH * :FFFF, :F0F0, 00FF, :5555, :6666 AND 0 RESPECTIVELY. * ****** XMACRO CKSTD: TREGS: A,:FFFF,Q,:F0F0,X,:00FF,Y,:5555 TREGS: K,:6666,L,0 ENDM SPACE 10 ****** * LDSTD: -- LOAD REGISTERS WITH STANDARD VALUES * * THIS MACRO LOADS 'A', 'Q', 'X', 'Y', 'K', AND 'L' BY * :FFFF, :F0F0, :00FF, :5555, :6666, AND 0 RESPECTIVELY. * ****** XMACRO LDSTD: LDREG: A,:FFFF,Q,:F0F0,X,:00FF,Y,:5555,K,:6666,L,0  ENDM TITL ****** * L O A D R E G I S T E R M A C R O * * THIS MACRO IS USED TO SET VALUES INTO * ANY OF 7 REGISTERS. THE MACRO WILL * LOAD THE REGISTER SPECIFIED BY PARAMETER #(1) * WITH THE VALUE SPECIFIED BY PARAMETER #(2) * REGISTER (PARAMETER #(3)) LOADED WITH VALUE * (PARAMETER #(4)) AND SO ON. SEVEN OF THE * EIGHT REGISTERS MAY BE LOADED. THE P REG * IS NOT ALLOWED TO BE LOADED. * * A SAMPLE CALL FOLLOWS: * * LDREG: A,AVAL,X,XVAL,Y,YV+ AL,Q,QVAL,ETC * * IF THE -A- REGISTER IS USED IN THE CALL IT * MUST BE THE FIRST PARAMETER, THERE IS NOT * ANY RESTRICTIONS ON THE OTHER REGISTERS * ****** LDREG: XMACRO IFT #?>=2 IFF #(1,'A') LODREG #(1),#(2) ENDC ENDC IFT #?>=4 LODREG #(3),#(4) ENDC IFT #?>=6 LODREG #(5),#(6) ENDC  IFT #?>=8 LODREG #(7),#(8) ENDC IFT #?>=10 LODREG #(9),#(10) ENDC IFT #?>=12 LODREG #(11),#(12) ENDC IFT #?>=14 LODREG #(13),#(14) ENDC IFT #(1,'A') COPY =#(2),A ENDC IFT #?>=10 ENDC ENDM TITL LODREG XMACRO IFF #(1,'S') IFF #(1,'K') IFF #(1,'L') COPY =#(2),#(1) ENDC ENDC ENDC IFF #(1,'Q') IFF #(1,'X') IFF #(1,'Y')  COPY =#(2),A COPY A,#(1) ENDC ENDC ENDC ENDM TITL ****** * T E S T R E G I S T E R S M A C R O * * THE PURPOSE FOR THIS MACRO IS TO ALLOW * THE ABILITY TO TEST SPECIFIED REGISTERS * FOR SPECIFIED VALUES. UP TO 4 REGISTERS * MAY BE SPECIFIED, ALONG WITH THE VALUES THE * REGISTERS ARE EXPECTED TO CONTAIN, IN ANY * ONE MACRO CALL. IF THE REGISTER DOES NOT * CONTAIN THE EXPECTED VALUE, THE ERROR * MACRO WILL BE INVOKED. ALL REGISTERS WILL *  REMAIN UNCHANGED. * * A SAMPLE FORMAT OF A MACRO CALL FOLLOWS: * * TREGS: REG,VALUE,REG,VALUE,(ETC UP TO 4) * * WHERE: REG=REGISTER DESIGNATION * (A,Q,X,Y,P,L,S,K) * VALUE= LITERAL VALUE (0-:FFFF) ****** XMACRO TREGS: COPY A,ATEMP SAVE A DURING THE NEXT REGISTER TESTS. IFT #?>=2 TSTREG #(1),#(2) ENDC  IFT #?>=4 TSTREG #(3),#(4) ENDC IFT #?>=6 TSTREG #(5),#(6) ENDC IFT #?>=8 TSTREG #(7),#(8) ENDC COPY ATEMP,A RESTORE A REGISTER TO ORIGINAL VALUE. GLPOL: ENDM TSTREG XMACRO IFF #(1,'A') COPY #(1),A ENDC CSK A,=#(2) NOP ERROR: -#(1)-,SHOULD,BE,=#(2) ENDM TITL TITL * * LDMEM: MACRO * * THIS MACRO LOADS FOUR CONSECUTIVE MEMORY LOCATIONS * WITH THE VALUES SPECIFIED..... * THE PARAMETERS ARE: * #(1) - ADDRESS OF THE FIRST LOCATION *  #(2) THRU #(5) - VALUES TO BE LOADED. * LDMEM: XMACRO COPY =#(1),Y COPY =#(2),A COPY A,0(Y) COPY =#(3),A COPY A,1(Y) COPY =#(4),A COPY A,2(Y) COPY =#(5),A  COPY A,3(Y) GLPOL: ENDM TITL * #(1),#(2) = AQ REGISTER PAIR * #(3) = OPERATION * #(4),#(5) = OPERAND * #(6) = STATUS * OK = NORMAL * OV = OVERFLOW * UF = UNDERFLOW * DP = DOUBLE PRECISION RESULT (FIX) * SP = SINGLE PRECISION RESULT (FIX) * LT = LESS THAN (CSKF) *  GT = GREATER THAN (CSKF) * EQ = EQUAL (CSKF) * DZ = DIVIDE BY ZERO (DIVF) * #(7),#(8) = EXPECTED RESULT * #(9) = CARRY FLAG * #(10) = OVERFLOW FLAG * #(11) = X REGISTER * #(12) = Y REGISTER * #(13) = BYTE MODE ,  B=BYTE W=WORD OPTEST XMACRO * CY=#(9) OV=#(10) A=#(1) Q=#(2) #(3) #(4) #(5)=#(7) #(8) #(6) FLOAT1 SET $ JST INITRP  INITIALIZE TRAP LOCATIONS COPY =#(1),A #(1) ==> 'A' COPY =#(2),Q #(2) ==> 'Q' COPY =#(11),X  #(11) ==> 'X' COPY =#(12),Y #(12) ==> 'Y' #(9)BIT CY,S #(9) ==> CARRY FLAG #(10)BIT OV,S  #(10) ==> OVERFLOW FLAG IFT #(13,'B') SBIT BY,S CHECK FOR BYTE MODE INDEPENDENCE ENDC IFT #(3,'ADDF');#(3,'SUBF');#(3,'MULF');#(3,'DIVF');#(3,'CSKF') JMP $+3 JUMP AROUND WORD FLOAT2 SET $ WORD #(4) INSTRUCTION OPERAND WORD #(5) FLOAT3 SET $ IFT #(6,'OK');#(3,'CSKF') #(3) FLOAT2 DO THE OPERATION ENDC IFT #(6,'OV') IFF #(3,'FIX') #(3) FLOAT2 SHOULD OVERFLOW AND T R A P ENDC ENDC IFT #(6,'UF') #(3) FLOAT2 SHOULD UNDERFLOW ENDC IFT #(6,'DZ') #(3) FLOAT2 SHOULD TRAP ON DIVIDE BY ZERO ENDC ENDC IFT #(3,'FIX');#(3,'FLOAT') FLOAT3 SET $ IFT #(3,'FLOAT') #(3) -- DO THE OPERATION ENDC IFT #(6,'OV') #(3)  -- SHOULD OVERFLOW ENDC IFT #(6,'DP') #(3) -- EXPECT DOUBLE PRECISION RESULT  ENDC IFT #(6,'SP') #(3) -- EXPECT SINGLE PRECISION RESULT ENDC ENDC IFT #(3,'CSKF') IFT #(6,'LT') JMP $+3 OK-- AQ IS LESS THAN OPERAND NOP ERROR: INCORRECT,COMPARE ENDC IFT #(6,'GT') ERROR: INCORRECT,COMPARE JMP $+2 OK-- AQ IS GREATER THAN OPERAND ERROR: INCORRECT,COMPARE ENDC IFT #(6,'EQ') NOP ERROR: INCORRECT,COMPARE NOP  OK-- AQ IS EQUAL TO OPERAND ENDC ENDC IFT #(13,'B') RBIT BY,S ENDC IFF #(3,'CSKF') IFT #(7,?)>0 CSK A,=#(7) CHECK -A- NOP ERROR: -A-,SHOULD,CONTAIN,#(7)  CSK Q,=#(8) CHECK -Q- NOP ERROR: -Q-,SHOULD,CONTAIN,#(8) ENDC ENDC IFT #(3,'CSKF') CSK A,=#(1) CHECK -A- NOP ERROR: #(3),MODIFIED,-A- CSK Q,=#(2) CHECK -Q- NOP ERROR: #(3),MODIFIED,-Q- ENDC COPY X,A FOR TESTING CSK A,=#(11) CHECK -X- NOP  ERROR: #(3),MODIFIED,-X- COPY Y,A FOR TESTING CSK A,=#(12) CHECK -Y- NOP ERROR: #(3),MODIFIED,-Y- IFT #(3,'ADDF');#(3,'SUBF');#(3,'MULF');#(3,'DIVF');#(3,'CSKF') COPY FLOAT2,A CSK A,=#(4) CHECK OPERAND WORD 1 NOP ERROR: #(3),MODIFIED,OPERAND COPY FLOAT2+1,A CSK A,=#(5)  CHECK OPERAND WORD 2 NOP ERROR: #(3),MODIFIED,OPERAND ENDC IFT #(6,'OK');#(3,'CSKF');#(6,'DZ')  IFT #(10,'R') JF OV,$+2 OVERFLOW STILL RESET? ERROR: NO--,#(3),CHANGED,OVERFLOW ENDC  IFT #(10,'S') JT OV,$+2 OVERFLOW STILL SET? ERROR: NO--,#(3),CHANGED,OVERFLOW ENDC IFT -  #(9,'R') JF CY,$+2 CARRY STILL RESET? ERROR: NO--,#(3),CHANGED,CARRY ENDC IFT #(9,'S')  JT CY,$+2 CARRY STILL SET? ERROR: NO--,#(3),CHANGED,CARRY ENDC ENDC IFT #(6,'OV')  IFF #(3,'FIX') IFT #(9,'R') JF CY,$+2 CARRY STILL RESET? ERROR: NO--,#(3),WITH,OVERFLOW,CHANGED,CARRY ENDC IFT #(9,'S') JT CY,$+2 CARRY STILL SET? ERROR: NO--,#(3),WITH,OVERFLOW,CHANGED,CARRY ENDC ENDC IFT #(3,'FIX') JT CY,$+2 CARRY SET? ERROR: NO--,EXPECTED,OVERFLOW,WITH,CY,SET ENDC JT OV,$+2 OVERFLOW SET? ERROR: NO--,EXPECTED,OVERFLOW,WITH,OV,SET ENDC IFT #(6,'UF') JT CY,$+2 CARRY SET? ERROR: NO--,EXPECTED,UNDERFLOW,WITH,CY,SET JT OV,$+2 OVERFLOW SET? ERROR: NO--,EXPECTED,UNDERFLOW,WITH,OV,SET ENDC IFT #(6,'DP') JT CY,$+2  CARRY SET? ERROR: NO--,SHOULD,BE,SET,WHEN,DOUBLE,PRECISION JF OV,$+2 OVERFLOW RESET? ERROR: NO--,SHOULD,BE,RESET,WHEN,DOUBLE,PRECISION ENDC IFT #(6,'SP') JF CY,$+2 CARRY RESET? ERROR: NO--,SHOULD,BE,RESET,WHEN,SINGLE,PRECISION JF OV,$+2 OVERFLOW RESET? ERROR: NO--,SHOULD,BE,RESET,WHEN,SINGLE,PRECISION ENDC IFT #(3,'CSKF') COPY ATRAP,A 1ST WORD OF TRAP VECTOR JEQ A,$+2 STILL ZERO? ERROR: NO--,#(3),ALTERED,TRAP,VECTOR COPY ATRAP+1,A 2ND WORD OF TRAP VECTOR JEQ A,$+2 STILL ZERO? ERROR: NO--,#(3),ALTERED,TRAP,VECTOR IFT #(6,'OK');#(6,'UF');#(3,'CSKF');#(3,'FIX');#(3,'FLOAT') COPY QTEMP,A CHECK TRAP FLAG TO SEE IF TRAP WAS TAKEN JEQ A,$+2 STILL ZERO? ERROR: NO--,#(3),EXECUTED,TRAP ENDC ENDC IFT #(6,'OV');#(6,'DZ') IFF #(3,'FIX') COPY QTEMP,A CHECK TRAP FLAG TO SEE IF TRAP WAS TAKEN CSK A,=1 NOP ERROR: #(3),DID,NOT,EXECUTE,TRAP COPY ATRAP,A  1ST WORD OF TRAP VECTOR CSK A,=FLOAT3+2 CHECK 'P' NOP ERROR: #(3),TRAP,STORED,WRONG,'P' COPY ATRAP+1,A 2ND WORD OF TRAP VECTOR CSK A,FLOAT3 CHECK 'I' NOP ERROR: #(3),TRAP,STORED,WRONG,'I' ENDC ENDC JMP FLOAT1 PATCH FOR LOOPING ORG $-1 NOP GLPOL: ENDM TITL SPACE 5 ****** * * #(1),#(2) = AQ REGISTER PAIR * #(3) = OPERATION * #(4),#(5) = OPERAND * #(6) = STATUS * #(7),#(8) = EXPECTED RESULT * #(9) = CY AND OV INITIAL VALUE * ****** FLTEST XMACRO IFF #(3,'CSKF') OPTEST #(1),#(2),#(3),#(4),#(5),#(6),#(7),#(8),#(9),#(9),:3333,:0F0F,W ENDC IFT #(3,'CSKF') OPTEST #(1),#(2),#(3),#(4),#(5),#(6),#(1),#(2),#(9),#(9),:FF00,:5555,W ENDC ENDM TITL * * FLOATING POINT ADDRESSING MODES TEST MACRO * FPADDR XMACRO FLOATX SET $ JST INITRP INITIALIZE TRAP LOCATIONS SBIT XA,S FORCE WORD MODE  JMP $+7 * FLOAT4 SET $ WORD #(1) WORD #(2) FLOAT5 SET $ WORD #(7) FLOAT6 SET .  $ WORD #(8) FLOAT7 SET $ WORD #(9) FLOAT8 SET $ WORD FLOAT4 * COPY FLOAT4,A #(1) -> A COPY FLOAT4+1,Q #(2) -> Q COPY FLOAT5,X (FLOAT5) -> X COPY FLOAT6,Y (FLOAT6) -> Y * IFT #(3,'$-10') * CSKF $-10 P-RELATIVE WORD :5C84  WORD :FFF4 ENDC IFF #(3,'$-10') CSKF #(3) #(4) #(5) #(6) ENDC ERROR: ADDRESSING,MODE,FAILED ERROR: ADDRESSING,MODE,FAILED * PATCHX FLOATX ENDM TITL * * DOUBLE LOAD MACRO * * THE DOUBLE LOAD MACRO ALLOWS A DOUBLE PRECISION NUMBER TO * BE LOADED INTO THE REGISTER PAIR SPECIFIED (AQ,AX,AY). * THE PARAMETERS ARE: * #(1) - ADDRESS TO BE LOADED FROM (STACK RELATIVE) * #(2) - LOW ORDER REGISTER (Q, X OR Y) * DLOAD: XMACRO * DLOAD: #(1),#(2) DLOADS #(1),A#(2) IFF #(2,'X') LOADS #(1),X CSK A,X NOP ERROR: AREG,DID,NOT,LOAD,CORRECTLY LOADS #(1)+1,X CSK #(2),X NOP ERROR: #(2)REG,DID,NOT,LOAD,CORRECTLY ENDC IFT #(2,'X') LOADS #(1),Q LOADS #(1)+1,Y CSK A,Q NOP ERROR: AREG,DID,NOT,LOAD,CORRECTLY CSK X,Y NOP ERROR: XREG,DID,NOT,LOAD,CORRECTLY ENDC ENDM TITL * * DOUBLE STORE MACRO * * THE DOUBLE STORE MACRO ALLOWS THE REGISTER PAIR SPECIFIED * (AQ,AX,AY) TO BE STORED AS A DOUBLE PRECISION NUMBER. * THE PARAMETERS ARE: * #(1) - LOW ORDER REGISTER (Q, X OR Y) * #(2) - ADDRESS TO BE STORED TO (STACK RELATIVE) * DSTOR: XMACRO * DSTOR: #(1),#(2) DSTORS A#(1),#(2) COPY #(1),Q CSKS A,#(2) NOP ERROR: AREG,DID,NOT,STORE,CORRECTLY CSKS Q,#(2)+1 NOP ERROR: #(1)REG,DID,NOT,STORE,CORRECTLY ENDM TITL * * DOUBLE PRECISION ARITHMETIC MACRO * * THE DOUBLE PRECISION ARITHMETIC MACRO ALLOWS A DOUBLE PRECISION * ADD OR SUBTRACT OF A STACK RELATIVE MEMORY LOCATION WITH THE * AQ REGISTER PAIR. * THE PARAMETERS ARE: * #(1) - ADD OR SUBTRACT (ADD OR SUB) * #(2) - AREG VALUE * #(3) - QREG VALUE * #(4) - ADDRESS OF DOUBLE PRECISION WORD (STACK RELAT * #(5) - HIGH ORDER WORD VALUE * #(6) - LOW ORDER WORD VALUE * #(7) - HIGH ORDER (AREG) RESULT * #(8) - LOW ORDER (QREG) RESULT * #(9) - 'OV' IF OVERFLOW EXPECTED; ELSE '' * DPREC XMACRO TITL * DPREC #(1),#(2),#(3),#(4),#(5),#(6),#(7),#(8),#(9),#(10) COPY =#(6),Q COPY =#(5),A DSTOR: Q,#(4) COPY =#(2),A COPY =#(3),Q DBL#(1) #(4) CSK A,=#(7) NOP ERROR: AREG,RESULT,IN,ERROR CSK Q,=#(8) NOP ERROR: QREG,RESULT,IN,ERROR IFT '##(9,1,2)'='OV' JT OV,$+2 ENDC IFF '##(9,1,2)'='OV' JF OV,$+2 ENDC ERROR: OVERFLOW,BIT,SET,INCORRECTLY JMP !OVPOL LPOOL !OVPOL EQU $ ENDM TITL * * CONVERT TO DOUBLE PRECISION MACRO * * THE CONVERT TO DOUBLE PRECISION MACRO ALLOWS THE VALUE * IN THE QREG TO BE CONVERTED TO A 32 BIT PRECISION VALUE * BY EXTENDING THE SIGN BIT(15) THROUGH THE AREG. * THE PARAMETERS ARE: * #(1) - ORIGINAL VALUE IN AREG * #(2) - VALUE IN QREG TO BE EXTENDED *  #(3) - NEW VALUE IN AREG (:0000 OR :FFFF) * CVDP: XMACRO * CVDP: #(1),#(2),#(3) LDREG: A,#(1),Q,#(2) CVTDBL /  TREGS: A,#(3),Q,#(2) ENDM TITL * * SIGNAL AND WAIT MACRO * * THE SIGNAL AND WAIT MACRO CHECKS FOR PROPER INCREMENT/ * DECREMENT OF THE SEMAPHORE AND CHECKS THE COUNT FOR * THE NUMBER OF TIMES THE MACRO HAS PREVIOUSLY CAUSED *  A SEMAPHORE TRAP. * THE PARAMETERS ARE: * #(1) - SIGNAL OR WAIT (SIGNAL OR WAIT) * #(2) - SEMAPHORE COUNT * #(3) - TRAP COUNT (NUMBER OF TRAPS WHICH HAVE OCCURED) * SGWT: XMACRO TITL * SGWT: #(1),#(2),#(3) #(1) COPY 0(X),A TREGS: A,#(2) TMEM: TRAPFLG,#(3) ENDM TITL * * SINGLE REGISTER PUSH MACRO * * THE PARAMETER IS: * #(1) - THE REGISTER TO BE PUSHED (Q, X OR Y) * WILL NOT TEST AREG CORRECTLY * SPUSH: XMACRO  PUSH: #(1) LOADS 0,A CSK #(1),A NOP ERROR: #(1)REG,SHOULD,BE,SAME,AS,AREG ENDM TITL * * SINGLE REGISTER POP MACRO * * THE PARAMETER IS: * #(1) - THE REGISTER TO BE POPPED (Q, X OR Y) * THE AREG WILL NOT TEST CORRECTLY * SPOP: XMACRO LOADS 0,A POP: #(1) CSK #(1),A NOP ERROR: #(1)REG,SHOULD,BE,SAME,AS,AREG ENDM TITL * * EXTRACT BIT FIELD FROM MEMORY MACRO * * THE EXTRACT MACRO ALLOWS A SELECTED BIT FIELD TO BE * EXTRACTED FROM MEMORY AND PUT INTO A, Q, X OR YREGS. * THE HIGH ORDER BIT MAY BE EXTENDED AS A SIGN BIT. * THE PARAMETERS ARE: * #(1) - INSTRUCTION WITH OR WITHOUT SIGN EXTEND * (XTR OR XTRS) * #(2) - DISPLACEMENT FROM BASE ADDRESS IN BITS * #(3) - BASE ADDRESS IN WORDS * #(4) - LENGTH OF FIELD TO BE EXTRACTED * #(5) - REG TO BE USED FOR RESULT (A, Q, X OR Y) * #(6) - REG VALUE AFTER EXTRACT * XTR: XMACRO TITL * XTR:  #(1),#(2),#(3),#(4),#(5),#(6) LDMEM: #(3),:5555,:AAAA,:6666,:9999 COPY =#(2),X COPY =#(3),Y #(1) #(5),#(4) TREGS: #(5),#(6) ENDM TITL * * INSERT BIT FIELD TO MEMORY MACRO * * THE INSERT MACRO ALLOWS A SELECTED BIT FIELD TO BE * INSERTED INTO MEMORY FROM THE A OR QREG. * THE PARAMETERS ARE: * #(1) - VALUE IN REGISTER TO BE INSERTED FROM * #(2) - DISPLACEMENT FROM BASE ADDRESS IN BITS * #(3) - BASE ADDRESS IN WORDS * #(4) - LENGTH OF BIT FIELD TO BE INSERTED * #(5) - REGISTER FOR INSERT (A OR Q) * #(6) THRU #(9) VALUES EXPECTED IN MEMORY * INSR: XMACRO TITL * INSR: #(1),#(2),#(3),#(4),#(5),#(6),#(7),#(8),#(9) COPY =#(2),X COPY =#(3),Y COPY =#(1),#(5) INSR #(5),#(4) TMEM: #(3),#(6),#(3)+1,#(7),#(3)+2,#(8),#(3)+3,#(9) JMP !INSR LPOOL !INSR EQU $ ENDM TITL * PROCEDURE ENTER AND RETURN MACRO * * THE PROCEDURE ENTER AND RETURN MACRO ALLOWS TESTING OF * THE INSTRUCTIONS ENTER AND RETURN. IT CHECKS THAT THE * STACK IS UPDATED CORRECTLY AND THAT THE RSK IS PERFORMED * BY THE RETURN INSTRUCTION. * THE PARAMETER IS: * #(1) - THE NUMBER OF SCRATCH ELEMENTS TO BE ALLOCATED * ON THE STACK PROC: XMACRO TITL * PROC: #(1) JSK !PROC1 !PROC0 JMP !PROC2 !PROC1 ENTER #(1) COPY K,A ADD =#(1)+2,A CSKS A,0 NOP ERROR: KREG,DOES,NOT,POINT,AT,OLD,K COPY =!PROC0,A0  CSKS A,*0 NOP ERROR: OLD,K,DOES,NOT,CONTAIN,OLD,P COPY Y,A CSKS A,1 NOP ERROR: YREG,DID,NOT,GET,SAVED,CORRECTLY RETURN  ERROR: RETURN,DID,NOT,DO,RSK !PROC2 EQU $ ENDM TITL * * ENQUE MACRO * * THE ENQUE MACRO ALLOWS AN ELEMENT TO BE INSERTED * BEFORE THE REFERENCED ELEMENT. * THE PARAMETERS ARE: * #(1) - THE ADDRESS OF THE ELEMENT TO BE ENQUED * #(2) - THE ADDRESS OF THE REFERENCE ELEMENT * ENQUE: XMACRO TITL * ENQUE: #(1),#(2) COPY #(1),Q GET ADDRESS OF ELEMENT TO BE ENQUED COPY =#(2),X GET ADDRESS OF REFERENCE ELEMENT COPY Q,Y COPY 1(X),A GET OLD BACK POINTER ENQUEB CSK A,1(Y) NOP ERROR: BACK,POINTER,IN,NEW,ELEMENT,INCORRECT COPY *1(Y),A GET FORWARD POINTER TO NEW ELEMENT CSK A,Q NOP ERROR: FORWARD,POINTER,TO,NEW,ELEMENT,INCORRECT COPY 0(Y),A GET FORWARD POINTER IN NEW ELEMENT CSK A,X NOP ERROR: FORWARD,POINTER,IN,NEW,ELEMENT,INCORRECT COPY 1(X),A GET BACK POINTER TO NEW ELEMENT CSK A,Q NOP ERROR: BACK,POINTER,TO,NEW,ELEMENT,INCORRECT ENDM TITL * * DEQUE: MACRO * * THE DEQUE MACRO ALLOWS THE ELEMENT FOLLOWING * THE REFERENCE ELEMENT TO BE DELETED. * THE PARAMETER IS: * #(1) - ADDRESS OF REFERENCE ELEMENT * DEQUE: XMACRO TITL * DEQUE: #(1) COPY =#(1),X GET ADDRESS OF REFERENCE ELEMENT COPY X,Y COPY 0(Y),A GET FORWARD POINTER CSK A,Y IS QUEUE EMPTY? NOP JMP !DQ0 NO DEQUEN YES CSK X,=0 NOP ERROR: XREG,SHOULD,BE,ZERO CSK A,Y NOP ERROR: FORWARD,POINTER,CHANGED,-,SHOULD,NOT,HAVE,BEEN COPY 1(Y),A GET BACK POINTER CSK A,Y NOP ERROR: BACK,POINTER,CHANGED,-,SHOULD,NOT,HAVE,BEEN JMP !DQ1 TITL !DQ0 EQU $ COPY A,YTEMP SAVE OLD FORWARD POINTER COPY *0(Y),A GET NEW FORWARD POINTER DEQUEN CSK A,0(Y) NOP ERROR: NEW,FORWARD,POINTER,NOT,SET,CORRECTLY COPY YTEMP,A GET OLD FORWARD POINTER CSK A,X NOP ERROR: XREG,NOT,SET,TO,ELEMENT,REMOVED COPY =1,X COPY *0(X,Y),A GET BACK POINTER CSK A,Y NOP ERROR: BACK,POINTER,SET,INCORRECTLY !DQ1 EQU $ ENDM TITL * *  DELQ: MACRO * * THE DELQ: MACRO ALLOWS THE REFERENCED * ELEMENT TO BE DELETED. * THE PARAMETER IS: *  #(1) - ADDRESS OF REFERENCED ELEMENT. * DELQ: XMACRO TITL * DELQ: #(1) COPY =#(1),X GET ADDRESS OF REFERENCED ELEMENT COPY X,Y DELQUE CSK X,Y NOP ERROR: XREG,SHOULD,NOT,HAVE,BEEN,CHANGED COPY 0(Y),A CSK X,A NOP JMP !DQE COPY =1,X  COPY 0(Y),A COPY 1(Y),Q CSK A,*1(Y) NOP ERROR: FORWARD,POINTER,UPDATED,INCORRECTLY CSK Q,*0(X,Y) NOP ERROR: BACKWARD,POINTER,UPDATED,INCORRECTLY !DQE EQU  $ ENDM TITL * * NEXTQ: MACRO * * THE NEXTQ: MACRO POINTS TO THE NEXT QUEUE ELEMENT * IF THE QUEUE IS NOT EMPTY, OR TO ZERO IF THE * QUEUE IS EMPTY. * * THE PARAMETER IS: * #(1) - THE REFERENCED QUEUE ELEMENT * NEXTQ: XMACRO TITL * NEXTQ: #(1) COPY =#(1),X GET ADDRESS OF REFERENCED ELEMENT  COPY X,Y COPY 0(Y),A CSK X,A NOP JMP !NXQ0 NEXTQUE 1  JNE X,!NXQ2 JMP !NXQ1 !NXQ2 ERROR: QUEUE,EMPTY,-,XREG,NOT,ZERO JMP !NXQ1 !NXQ0 NEXTQUE COPY 0(Y),A CSK X,A NOP ERROR: XREG,DID,NOT,MOVE,TO,NEXT,QUEUE,ELEMENT !NXQ1 EQU $ ENDM TITL * * ENQA: MACRO * * THE ENQA: MACRO TESTS THE FUNCTION OF THE * ENQUEA INSTRUCTION (INSERT AFTER QUEUE ELEMENT). * THE PARAMETERS ARE: * #(1) - ADDRESS OF ELEMENT TO BE INSERTED. * #(2) - ADDRESS OF REFERENCED QUEUE ELEMENT. * ENQA: XMACRO TITL * ENQA: #(1),#(2) COPY #(1),Q GET ADDRESS OF ELEMENT TO BE INSERTED COPY =#(2),X GET ADDRESS OF REFERENCED ELEMENT COPY Q,Y COPY 0(X),A ENQUEA CSK Q,0(X) NOP ERROR: OLD,FORWARD,POINTER,UPDATED,INCORRECTLY CSK A,0(Y) NOP ERROR: NEW,FORWARD,POINTER,INCORRECT COPY A,Y  CSK Q,1(Y) NOP ERROR: OLD,BACKWARD,POINTER,UPDATED,INCORRECTLY COPY Q,Y COPY X,A CSK A,1(Y) NOP ERROR: NEW,BACKWARD,POINTER,INCORRECT ENDM TITL * * BLOCK MOVE WORD MACRO * * THE BLOCK MOVE WORD MACRO ALLOWS BLOCKS * COPIED TO A NEW LOCATION. * THE PARAMETERS ARE: * #(1) - NUMBER OF WORDS TO BE MOVED * #(2) - ADDRESS OF FIRST WORD OF SOURCE * #(3) - ADDRESS OF FIRST WORD OF DESTINATION * BLKMOV XMACRO * * BLKMOV #(1),#(2),#(3) * LDREG: A,#(1),Q,#(2),X,#(3) MOVE TREGS: A,0,Q,#(2)+#(1),X,#(3)+#(1) LDREG: A,#(1),Y,#(2),X,#(3) JEQD A,$+8 COPY 0(X),Q CSK Q,0(Y) NOP ERROR: BUFFERS,DO,NOT,COMPARE,CORRECTLY ADD =1,X ADD =1,Y JMP $-7 ENDM TITL * * COPY TO/FROM USER SPACE MACRO * * THE COPY TO/FROM USER SPACE ALLOWS A SINGLE WORD TO * BE COPIED FROM THE AREG TO THE USER ADDRESS IN THE * XREG AND VICE VERSA. IT ASSUMES THAT THE USER ADDRESS * BLOCK WILL CORRESPOND TO THE SYSTEM ADDRESS BLOCK * OFFSET 1K WORD * USER NUMBER. *  THE PARAMETERS ARE: * #(1) - INSTRUCTION TO BE EXECUTED (LODU OR STRU) * #(2) - VALUE TO BE COPIED *  #(3) - USER ADDRESS FOR XREG * #(4) - USER NUMBER * COPYU XMACRO TITL * COPYU #(1),#(2),#(3),#(4) LDREG: A,#(2),X,#(3),Q,#(4) OUT Q,6 SET USER NUMBER SHIFT Q,L,10 SET USER * 1000 #(1) ADD Q,X GET OFFSET FOR USER MAP CSK A,0(X) NOP ERROR: #(1),DID,NOT,WORK,CORRECTLY ENDM TITL * * CSKS: MACRO * * THIS MACRO TESTS THE INTEGRITY OF THE CSKS INSTRUCTION. * * THE PARAMETERS ARE: * #(1) - ADDRESS OF THE STACK POINTER * #(2) - COMPARISON VALUE * #(3) - REGISTER FOR COMPARISON (A OR Q) * #(4) - POSITION IN STACK * CSKS: XMACRO TITL ***** CSKS: #(1),#(2),#(3),#(4) COPY =#(1),Y LOAD STACK LOCATION WITH #(1) COPY =#(2),Q  COPY Q,#(4)(Y) COPY =#(1),A SET UP STACK POINTER COPY A,K COPY =#(2),#(3) LOAD TEST REGISTER CSKS #(3),#(4) NOP ERROR: CSKS,FAILED,ON,EQUALITY ADD =10,#(3) 2  CSKS #(3),#(4) JMP $+2 JMP $+2 ERROR: CSKS,FAILED,ON,GREATER,THAN SUB  =20,#(3) CSKS #(3),#(4) JMP $+3 NOP ERROR: CSKS,FAILED,ON,LESS,THAN GLPOL: ENDM TITL * * S:ECC MACRO * * THE S:ECC MACRO IS USED TO TEST THE STRECC * (STORE ERROR CORRECTION CODE) INSTRUCTION. * * THE PARAMETERS ARE: * #(1) - ADDRESS OF REFERENCED LOCATION *  #(2) - CONTENTS OF REFERENCED LOCATION * #(3) - ECC FOR CONTENTS DISPLACED BY ONE BIT * #(4) - DISPLACED CONTENTS (OFF BY ONE BIT) * S:ECC XMACRO ***** S:ECC #(1),#(2),#(3),#(4) COPY =#(1),X LOAD ADDRESS COPY =#(2),Q LOAD CONTENTS COPY =#(3),A LOAD ECC FOR #(4) COPY Q,#(1) STORE CONTENTS,MEMORY PRODUCES ECC SPACE 1 STRECC SPACE 1 COPY #(1),A CSK A,=#(4) CHECK AREG AGAINST VALUE NOP ERROR: STRECC,INSTRUCTION,DID,NOT,WORK ENDM TITL * * L:ECC MACRO * * THE L:ECC MACRO IS USED TO TEST THE LODECC * (LOAD ERROR CORECTION CODE) INSTRUCTION... * * THE PARAMETERS ARE: * #(1) - ADDRESS OF REFERENCED LOCATION * #(2) - CONTENTS OF REFERENCED LOCATION * #(3) - EXPECTED ECC VALUE AFTER LOAD * L:ECC XMACRO ***** L:ECC #(1),#(2),#(3) COPY =#(1),X LOAD ADDRESS COPY =#(2),A LOAD CONTENTS COPY =#(3),Q LOAD CHECKING ECC COPY  A,#(1) STORE CONTENTS,MEMORY PRODUCES ECC SPACE 1 LODECC SPACE 1 CSK A,Q CHECK THE LOAD NOP ERROR: LODECC,INSTRUCTION,DID,NOT,WORK ENDM TITL * * G:ECC MACRO * * THE G:ECC MACRO IS USED TO TEST THE GENECC * (GENERATE ERROR CORRECTION CODE) INSTRUCTION. * * THE PARAMETERS ARE: * #(1) - ADDRESS OF REFERINCED LOCATION * #(2) - CONTENTS OF REFERENCED LOCATION * #(3) - EXPECTED ECC VALUE AFTER GENERATION * G:ECC XMACRO ***** G:ECC #(1),#(2),#(3) COPY =#(1),X LOAD ADDRESS COPY =#(2),Q LOAD CONTENTS COPY Q,#(1) STORE CONTENTS COPY =0,A CLEAR AREG SPACE 1 GENECC SPACE 1 CSK A,=#(3) CHECK GENERATION NOP ERROR:  GENECC,INSTRUCTION,DID,NOT,WORK ENDM TITL * * STOR:K MACRO * * THE STOR:K MACRO IS USED TO TEST THE STORK * (STORE K-RELATIVE) INSTRUCTION. * * THE PARAMETERS ARE: * #(1) - REGISTER USED * #(2) - D6 FIELD USED *  #(3) - DATA STORED (AN INDIRECT ADDRESS) * STOR:K XMACRO COPY =#(3),#(1) STORK #(1),#(2) TRY DIRECT ADDRESSING, K-RELATIVE IFF #(1,'A') COPY #(1),A ENDC CSK A,KSTK+#(2) NOP ERROR: STORK,DIRECT,ERROR,--,#(1)REG,SHOULD,=#(3) COPY =#(3),#(1) STORK #(1),*#(2) TEST INDIRECT, K-RELATIVE COPY #(3),#(1) IFF #(1,'A') COPY #(1),A ENDC CSK A,=#(3) NOP ERROR: STORK,INDIRECT,ERROR,--,#(1)REG,SHOULD,=#(3) ENDM TITL * * LOAD:K MACRO * * THE LOAD:K MACRO IS USED TO TEST THE LOADK * (LOAD K-RELATIVE) INSTRUCTION. * * THE PARAMETERS ARE: * #(1) - REGISTER USED * #(2) - D6 FIELD USED *  #(3) - DATA READ (INDIRECT ADDRESS) * LOAD:K XMACRO COPY =#(3),#(1) COPY #(1),KSTK+#(2) COPY =0,#(1) LOADK #(2),#(1) 3  COPY #(1),A CSK A,=#(3) NOP ERROR: LOADK,DIRECT,ERROR,--,#(1)REG,SHOULD,=#(3) COPY =#(3),#(1) COPY #(1),#(3) COPY =0,#(1) LOADK *#(2),#(1) COPY #(1),A CSK A,=#(3) NOP ERROR: LOADK,INDIRECT,ERROR,--,#(1)REG,SHOULD,=#(3) ENDM TITL ************************************************************************ *  * * TMEM: MACRO * * THIS MACRO WILL TEST FOUR MEMORY LOCATIONS FOR THEIR * * SPECIFIED VALUES. IT HALTS WHEN AN INEQUALITY IS FOUND * * CALLING THE ERROR: MACRO. * * * * EXAMPLE OF A CALL IS: TMEM: MEM1,VAL1,MEM2,VAL2,,,, * * UP TO FOUR MEMORY LOCATIONS CAN BE SPECIFIED EACH WITH  * * AN ASSOCIATED VALUE. THE A REG IS USED FOR THE COMPARE * * AND RESTORED TO ORIGINAL VALUE ON EXIT FROM ROUTINE. * * * ************************************************************************ XMACRO TMEM: COPY A,ATEMP SAVE A REG IFT #?>=2 AT LEAST 2 PARAM. COPY #(1),A CSK A,=#(2) TEST MEM1 NOP ERROR: -#(1)-,SHOULD,BE,=#(2)  IFT #?>=4 AT LEAST 4 PARAM. COPY #(3),A CSK A,=#(4) TEST MEM2 NOP ERROR:  -#(3)-,SHOULD,BE,=#(4) ENDC IFT #?>=6 AT LEAST 6 PARAM. COPY #(5),A CSK A,=#(6) TEST MEM3 NOP ERROR: -#(5)-,SHOULD,BE,=#(6) ENDC IFT #?>=8 AT LEAST 8 PARAM. COPY #(7),A CSK A,=#(8) TEST MEM4 NOP ERROR: -#(7)-,SHOULD,BE,=#(8) ENDC ENDC COPY ATEMP,A RESTORE A REG VALUE. ENDM SAVE END TEST MEM2 NOP ERROR:  -#(3)-,SHOULD,BE,=#(4) ENDC IFT #?>=6 AT LEAST 6 PARAM. COPY #(5),A CSK A,=#(6) TEST MEM3 NOP ERROR: -#(5)-,SHOULD,BE,=#(6) ENDC IFT #?>=8 AT LEAST 8 PARAMIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII4 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII5 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII6 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII7 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII8 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII9 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII; IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII< IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII= IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII> IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII? IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII@ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIA IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIB IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIC IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIID IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIE IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIF IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIG IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIH IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIK IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIL IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII