| 1 | / OS/8 TSAR/TSARINA\r |
| 2 | /\r |
| 3 | / ADBUFF.RA\r |
| 4 | /\r |
| 5 | / DEC-S8-STSAA-A-LA25\r |
| 6 | /\r |
| 7 | / K. ELLSON AND L. PEARSON\r |
| 8 | /\r |
| 9 | /\r |
| 10 | / TSAR SUBROUTINE - BUFFERED A/D\r |
| 11 | / COPYRIGHT 1973\r |
| 12 | / DIGITAL EQUIPMENT CORPORATION\r |
| 13 | / MAYNARD, MASSACHUSETTS 01754\r |
| 14 | /\r |
| 15 | / THIS PACKAGE PROVIDES A FUNCTIONAL REPLACEMENT FOR\r |
| 16 | / THE FOLLOWING FORTRAN IV LIBRARY SUBROUTINES: REALTM\r |
| 17 | / AND ADB. REALTM AND ADB ARE REPLACED BY THE SUBROUTINE\r |
| 18 | / THRUPT. A THRUPT CALL IS ILLUSTRATED BY THE FOLLOWING\r |
| 19 | / FORTRAN PROGRAM.\r |
| 20 | /\r |
| 21 | /*************************************************************\r |
| 22 | /\r |
| 23 | / EXTERNAL STAT1,STAT2\r |
| 24 | / INTEGER BUFF1(85),BUFF2(85),IPARMS(3),HASH(# OF CHANNELS)\r |
| 25 | / CALL THRUPT(BUFF1,BUFF2,IPARMS,HASH,NTRIG)\r |
| 26 | / CALL CLOCK(8,IRATE) @ IF NO /1 SWITCH AT ASSEMBLY TIME \r |
| 27 | / @ FOR A/D CONVERSION TIMED WITH FIRST DK8-EP\r |
| 28 | / CALL CLOCK1(8,IRATE) @ IF /1 SWITCH SET AT ASSEMBLY TIME\r |
| 29 | / @ THIS IS FOR A/D CONVERSION TIMED WITH 2ND DK8-EP\r |
| 30 | / IF YOU USE BOTH CLOCKS ON ONE SYSTEM, THEN YOU\r |
| 31 | / MAY SWITCH ON ONLY ONE CLOCK-TIMED A/D CONVERSION.\r |
| 32 | / THIS MEANS: ONLY ONE CLOCK MAY BE STARTED WITH FUNCTION=8 (BIT 9 SET)\r |
| 33 | / ...\r |
| 34 | / 100 IF (STAT1-0.5) 100, 110, 999\r |
| 35 | / 110 WRITE (5) BUFF1\r |
| 36 | / CALL RELEAS (1)\r |
| 37 | / ...\r |
| 38 | / 999 WRITE (4,1000)\r |
| 39 | / 1000 FORMAT (' SAMPLING TOO FAST')\r |
| 40 | / CALL CLOCK (0,0)\r |
| 41 | / ...\r |
| 42 | /\r |
| 43 | /************************************************************\r |
| 44 | /\r |
| 45 | / BUFF1 - ONE OF 2 BUFFERS FOR THE ANALOG DATA, 255 12 BIT\r |
| 46 | / WORDS ARE STORED IN EACH BUFFER\r |
| 47 | /\r |
| 48 | / STAT1 - DYNAMIC STATUS WORD OF BUFF1. THE VALUES 0.25,\r |
| 49 | / 0.5, AND +1. INDICATE THAT THE BUFFER IS NOT FILLED,\r |
| 50 | / BUFFER IS FILLED, AND BUFFER OVERFLOW.\r |
| 51 | /\r |
| 52 | / BUFF2 - THE SECOND BUFFER.\r |
| 53 | /\r |
| 54 | / STAT2 - THE DYNAMIC STATUS WORD OF BUFF2, VALUES ARE THE\r |
| 55 | / SAME AS FOR STAT1.\r |
| 56 | \f/\r |
| 57 | / IPARMS - THE PARAMETER VECTOR WHICH CONTAINS IN ORDER THE\r |
| 58 | / STARTING CHANNEL, THE NUMBER OF CHANNELS, AND THE NUMBER\r |
| 59 | / OF SAMPLES. \r |
| 60 | / HASH - OPTIONAL: A TABLE CONTAINING THE READ VALID INFORMATION FOR A/D CHANNELS AND STRIGG INPUTS\r |
| 61 | / NTRIG - OPTIONAL BUT HASH MUST BE SPECIFIED:\r |
| 62 | / THE NUMBER OF SCHMITT TRIGGER CHANNELS TO SAMPLE\r |
| 63 | / CONFIGURATION REQUIRED FOR A/D AND STRIGG SAMPLING:\r |
| 64 | / FIRST DK8-EP: FREE RUNNING TIMER (10 KHZ OR 100 KHZ) FOR TRIGGER INPUT.\r |
| 65 | / CALL CLOCK4 (1 TO 7,3) FOR 10 KHZ\r |
| 66 | / CALL CLOCK4 (1 TO 7,30) FOR 100 KHZ \r |
| 67 | / SECOND DK8-EP STARTS THE A/D VIA EXTERNAL EVENT: CALL CLOCK1(8,RATE)\r |
| 68 | / TIME WORD: THE INTERVALL BETWEEN TWO A/D CYCLES IS DIVIDED INTO\r |
| 69 | / 12 SLICES CALLED S0 TO S11.\r |
| 70 | / AN EXTERNAL EVENT BETWEEN 0 AND S0 (SAMRAT/12) SETS THE LEFTMOST BIT 0.\r |
| 71 | / ' '' '' '' S11 AND SAMRAT SETS THE RIGHTMOST BIT 11.\r |
| 72 | /\r |
| 73 | / UPDATES:\r |
| 74 | /\r |
| 75 | / WGET: THE THIRD PARAMETER (RESULT) IS OPTIONAL\r |
| 76 | / VALID CALLS:\r |
| 77 | / I=WGET(BUFF,PNTR,RESULT)\r |
| 78 | / I=WGET(BUFF,PNTR)\r |
| 79 | / CALL WGET (BUFF,PNTR,RESULT)\r |
| 80 | /\r |
| 81 | / 11-SEP-80 HA\r |
| 82 | /\r |
| 83 | / INTERRUPT SERVICE ROUTINE FSMPLE:\r |
| 84 | / BEFORE THE READ ADRB WAIT FOR ADSE TO AVOID A NON VALID READ\r |
| 85 | / IF CLOCK DID'NT START THE AD CONVERTER.\r |
| 86 | / THEREFORE IN ANY CASE (ONE OR MORE CHANNELS) THE \r |
| 87 | / CLOCK MUST BE STARTED WITH CALL CLOCK(8,FREQU).\r |
| 88 | / FIRST PARAMETER OF CLOCK MUST BE 8 !\r |
| 89 | / 29-SEP-80 HA\r |
| 90 | / 1-OCT-82 HA REV 2.0 PACKS THE SAMPLE\r |
| 91 | / 15-JUL-83 HA REV 2.1 REARANGES CODE FOR PDP12 LINC OPTION\r |
| 92 | / 18-MAR-85 HA REV 3.0 ALLOWS TWO DK8-EP MODULES\r |
| 93 | / FOR A/D TRIGGED WITH DEV. CODE 13 CLOCK: /8 SWITCH\r |
| 94 | / FOR A/D TRIGG'D WITH DEV. CODE 17 CLOCK: /1 /8 SWITCH\r |
| 95 | / FOR A/D ON PDP-12 : NO SWITCH\r |
| 96 | /\r |
| 97 | / 26-JUL-85 HA REV 3.1 ALLOWS SCMITT TRIGGER INPUT WITH DK8-EP DEV 13 AND CLOCKED A/D WITH DK8-EP DEV 17\r |
| 98 | /\r |
| 99 | \f/\r |
| 100 | CL1DEV=13&10 / FIRST DK8-EP\r |
| 101 | CL2DEV=17&10 / SECOND DK8-EP\r |
| 102 | /\r |
| 103 | MQL=7421\r |
| 104 | MQA=7501 / WE USE EAE MODE B\r |
| 105 | CAM=7621\r |
| 106 | DAD=7443\r |
| 107 | DST=7445\r |
| 108 | DLD=DAD!CAM\r |
| 109 | DDZ=DST!CAM\r |
| 110 | DVI=7407\r |
| 111 | DPIC=7573\r |
| 112 | DPSZ=7451\r |
| 113 | IFNSW 1 <\r |
| 114 | EXTERN #CLINT\r |
| 115 | CLINT= #CLINT\r |
| 116 | IFSW 4 < EXTERN #CLIN1 >\r |
| 117 | >\r |
| 118 | IFSW 1 <\r |
| 119 | EXTERN #CLIN1\r |
| 120 | CLINT= #CLIN1\r |
| 121 | IFSW 4 < BAD SWITCH /1 /4; END >\r |
| 122 | >\r |
| 123 | CSTAT=157 /CLOCK ROUTINE PUTS CLSA BITS IN HERE\r |
| 124 | ENTRY STAT1 /ALLOW FORTRAN ACCESS TO THES\r |
| 125 | ENTRY STAT2 /LOCATIONS\r |
| 126 | COMMZ #PAGE0\r |
| 127 | ORG 2\r |
| 128 | PBUFF, 0 /PNTR TO CURRENT BUFFER\r |
| 129 | CURSTT, 0 /PNTR TO CURRENT STATUS WORD\r |
| 130 | NXTSTT, 0 /PNTR TO NEXT STATUS WORD\r |
| 131 | CURBUF, 0;0 /START OF CURRENT BUFFER PNTR\r |
| 132 | NXTBUF, 0;0 /START OF NEXT BUFFER PNTR\r |
| 133 | /STATUS WORDS, VALUES\r |
| 134 | STAT1, F 0.25 /0.25, 0.5, & 1.0 INDICATE\r |
| 135 | STAT2, F 0.25 /STATUS WORD IS NOT FILLED,\r |
| 136 | /FILLED, AND OVERFLOWED\r |
| 137 | \r |
| 138 | \r |
| 139 | \r |
| 140 | IFSW 8 <\r |
| 141 | ADSK=6534\r |
| 142 | ADRB=6533\r |
| 143 | ADST=6532\r |
| 144 | ADLM=6531\r |
| 145 | ADLE=6536\r |
| 146 | ADCL=6530\r |
| 147 | ADRS=6537\r |
| 148 | ADSE=6535\r |
| 149 | CLED=6134\r |
| 150 | MQL=7421\r |
| 151 | ACL=7701\r |
| 152 | CLBA=6006 / DO NOT FORGET TO INSERT THE DEVICE CODE\r |
| 153 | CLZE=6000\r |
| 154 | >\r |
| 155 | IFNSW 8 <\r |
| 156 | ESF=4\r |
| 157 | LINC=6141\r |
| 158 | PDP=2\r |
| 159 | SAM=100\r |
| 160 | CLEN=6134\r |
| 161 | >\r |
| 162 | \r |
| 163 | \r |
| 164 | \f FIELD1 FSMPLE\r |
| 165 | 0 /INTERRUPT TIME A/D SAMPLER\r |
| 166 | DST; ACMQ /SAVE AC AND MQ --> ACMQ\r |
| 167 | JMS% ITSTVL+1 /TEST VALID FOR THE FIRST SAMPLE\r |
| 168 | JMS INVALID /AND DECLARE NOT VALID\r |
| 169 | WAITSP,\r |
| 170 | IFNSW 8<\r |
| 171 | JMS LNCSAM /INITIATE SAMPLE\r |
| 172 | NEXTCH, ISZ SAMINS /UPDATE SAM INST FOR NXT CHAN\r |
| 173 | JMS LNCSAM\r |
| 174 | TAD SAMTMP\r |
| 175 | >\r |
| 176 | IFSW 8 <\r |
| 177 | ADSK / WAIT FOR COMPLETION OF CONVERSION\r |
| 178 | JMP .-1\r |
| 179 | ADRB /READ SAMPLE\r |
| 180 | JMS PUTSAM / INSERT INTO THE OUTPUT BUFFER AND TEST IF WORK DONE\r |
| 181 | MORESM,/\r |
| 182 | ISZ NCHANL+1 / ANY MORE CHANNELS TO SAMPLE?\r |
| 183 | SKP / START THE NEXT CONVERSION IF THERE IS ANY REMAINING\r |
| 184 | JMP NOTMOR / NOTHING MORE TO A/D SAMPLE\r |
| 185 | JMS% ITSTVL+1 /HERE ONLY IF SOME MORE A/D TO SAMPLE!\r |
| 186 | JMP SKIPSM / SKIP THE NEXT SAMPLE, RETURNS TO MORESM !!\r |
| 187 | ADST / AND START THE NEXT CONVERSION - AUTO INCREMENT MODE!\r |
| 188 | >\r |
| 189 | JMS% IINCPT+1 / INCREMENT BUFFER POINTER\r |
| 190 | JMP WAITSP / AND TAKE THE NEXT SAMPLE\r |
| 191 | NOTMOR,/\r |
| 192 | TAD CSTART+2 /STARTING CHANNEL\r |
| 193 | IFSW 8 <\r |
| 194 | ADLM / ELSE RESET MUX REGISTER\r |
| 195 | >\r |
| 196 | IFNSW 8 <\r |
| 197 | DCA SAMINS\r |
| 198 | JMS LNCSAM /SET CHANNEL TO START IN CASE\r |
| 199 | /CLOCK INITIATED\r |
| 200 | >\r |
| 201 | TAD NCHANL+2 /NUMBER OF CHANNELS\r |
| 202 | DCA NCHANL+1 /INTO COUNTER\r |
| 203 | /\r |
| 204 | / HERE WE INSERT THE STRIGG TIME WORDS\r |
| 205 | /\r |
| 206 | IWLOP1,\r |
| 207 | ISZ IWSTRC / IF ANY MORE TRIGG INPUTS\r |
| 208 | JMP .+2 / THEN SKIP TO INCPTR\r |
| 209 | JMP IWLOP2 / ELSE RESET ALL POINTERS AT IWLOP2\r |
| 210 | TAD% IWSTRI / TRIGG TIME WORD --> AC\r |
| 211 | JMS PUTSAM /INSERT TIME WORD INTO THE OUTPUT BUFFER\r |
| 212 | JMS% ITSTVL+1 /TEST FOR VALID SAMPLE (SKIP MEANS CRAZY PROGRAMMER!)\r |
| 213 | JMP .+2 / SKIP HERE MEANS BAD STRIGG TIME WORDS!\r |
| 214 | JMS INCPTR / INCREMENT OUTPUT BUFFER POINTER\r |
| 215 | ISZ IWSTRI / INCREMENT POINTER TO THE TIME WORDS\r |
| 216 | JMP IWLOP1 / AND LOOK FOR THE NEXT TRIGG WORDS TO PROCESS\r |
| 217 | IWLOP2, CLA\r |
| 218 | TAD% IWSTRI+1 /HOLDS ADDR \r |
| 219 | DCA IWSTRI / HOLDS POINTER TO THE TIME WORD\r |
| 220 | TAD% IWSTRC+1 /HOLDS NEGATIVE NUMBER OF TRIGG INPUTS\r |
| 221 | DCA IWSTRC / HOLDS THE COUNTER\r |
| 222 | DLD; ACMQ /RESTORE AC AND MQ\r |
| 223 | JMP% FSMPLE /DONE FOR THIS TIC\r |
| 224 | /\r |
| 225 | / SAMPLING FINISHED\r |
| 226 | /\r |
| 227 | SAMDON,/\r |
| 228 | ISZ PUTFLG / IF WE FOREGET TO INCREMNT BUFFER POINTER \r |
| 229 | JMS% IINCPT+1 / THEN WE DO IT NOW\r |
| 230 | / $$$$$$ STATUS WORT LADEN!\r |
| 231 | DCAZ% CURSTT /SET STATUS OF CURRENT FULL\r |
| 232 | SAMXIT, DCA% XCLINT+1 /STOP SAMPLING\r |
| 233 | IFSW 4 <\r |
| 234 | DCA% YCLINT > / STOP STRIGG INPUT\r |
| 235 | DLD; ACMQ /RESTORE AC AND MQ\r |
| 236 | JMP% FSMPLE\r |
| 237 | /\r |
| 238 | SKIPSM,/ SKIP ONE A/D SAMPLE\r |
| 239 | ISZ NCHANL+1 / NEVER SKIPS - SINCE ALREADY BEEING TESTED\r |
| 240 | DLD; NPOINT / THIS CODE HERE SAVES SOME INDIRECT REFS\r |
| 241 | DPIC / INCREMENT DOUBLE PREC. COUNTER TO TEST FOR MORE SAMPLES\r |
| 242 | DST; NPOINT / BUMP INTO COUNTER\r |
| 243 | DPSZ / SKIP IF WORK DONE\r |
| 244 | JMP MORESM /GO FETCH THE NEXT SAMPLE\r |
| 245 | JMP SAMDON / SET STATUS OF CURRENT BUFFER FULL: SAMPLE DONE\r |
| 246 | /\r |
| 247 | /\r |
| 248 | PUTSAM, 0 / INSERTS AC INTO OUTPUT BUFFER\r |
| 249 | ISZ AVALID / VALID INPUT?\r |
| 250 | JMP PUTSA1 / NON VALID, RETURN WITHOUT ACTION\r |
| 251 | BUFCDF, HLT /REPLACED BY CDF TO BUFFER\r |
| 252 | DCAZ% PBUFF\r |
| 253 | CDF 10 / USED FOR POINTER PVALID!\r |
| 254 | DCA AVALID / CLEAR VALID FLAG FOR NEXT CALL\r |
| 255 | DCA PUTFLG / DON'T FORGET TO INCREMENT THE BUFFER POINTER 0 --> PUTFLG\r |
| 256 | JMP% PUTSAM / ON RETURN AC = 0\r |
| 257 | PUTSA1, CLA / CLEAR AC FOR RETURN\r |
| 258 | JMP% PUTSAM\r |
| 259 | /\r |
| 260 | /\r |
| 261 | INVALID,0 / SET THE ACTUAL SAMPLE INVALID\r |
| 262 | CLA CMA / -1 --> AC\r |
| 263 | DCA AVALID\r |
| 264 | JMP% INVALID / ON RETURN AC=0\r |
| 265 | PUTFLG,\r |
| 266 | IINCPT, ADDR INCPTR / ADDRESS OF ROUTINE TO INCREMENT BUFFER POINTER\r |
| 267 | AVALID, / / ACTUAL VALID FLAG\r |
| 268 | ITSTVL, ADDR TSTVLD / TEST FOR VALID READ \r |
| 269 | TMP,\r |
| 270 | IWSTRC, ADDR WSTRC / POINTER TO THE NUMBER OF STRIGS CHANNELS TO SAMPLE\r |
| 271 | IWSTRI, ADDR TIMWRD / POINTER TO THESE TIME WORDS\r |
| 272 | XCLINT, ADDR CLINT / POINTER TO ENTRY OF CLOCK I/R SERVICE ROUTINE\r |
| 273 | IFSW 4 <\r |
| 274 | YCLINT, ADDR #CLINT / /4 ENABLES STRIGG INPUT FROM FIRST DK8-EP\r |
| 275 | NCHANL, 0;0;0\r |
| 276 | SAMCNT,\r |
| 277 | CSTART, 0;0;0\r |
| 278 | \f/\r |
| 279 | IPUTFL, ADDR PUTFLG / SET TO -1 IF BUFFER POINTER INCREMENTED, RESET BY PUTSAM\r |
| 280 | L10, 10\r |
| 281 | /\r |
| 282 | INCPTR, 0\r |
| 283 | CLA CMA / -1 --> AC\r |
| 284 | DCA% IPUTFL / -1 --> PUTFLG\r |
| 285 | ISZZ PBUFF /ELSE INCR PNTR & SKIP IF WE\r |
| 286 | JMP FLDOK /CROSSED A FIELD BOUNDARY\r |
| 287 | TAD BUFCDF /UPDATE FIELD\r |
| 288 | TAD L10\r |
| 289 | DCA BUFCDF\r |
| 290 | FLDOK,\r |
| 291 | ISZ SAMCNT /INCR BUFFER CNTR & SKIP IF\r |
| 292 | JMP% INCPTR /FILLED. BUFFER OK\r |
| 293 | DCAZ% CURSTT /SET STATUS WORD TO 0.5\r |
| 294 | /FOR BUFFER FILLED\r |
| 295 | TADZ NXTSTT /SWAP STATUS WORD PNTRS\r |
| 296 | DCA TMP / NXTSTT<=> CURSTT\r |
| 297 | TADZ CURSTT\r |
| 298 | DCAZ NXTSTT\r |
| 299 | TAD TMP\r |
| 300 | DCAZ CURSTT\r |
| 301 | TADZ% CURSTT /HAS USER RELEASED THIS BUFFER\r |
| 302 | SMA CLA\r |
| 303 | JMP% ITOOFST+1 /NO, SAMPLING TOO FAST!\r |
| 304 | JMS% ISWPBFR+1 / SWAP BUFFER\r |
| 305 | JMP% INCPTR / BUFFER POINTER UPDATED\r |
| 306 | ISWPBF, ADDR SWPBFR\r |
| 307 | /\r |
| 308 | /\r |
| 309 | ITOOFS, ADDR TOOFST\r |
| 310 | /\r |
| 311 | TAD CSTART+2 /STARTING CHANNEL\r |
| 312 | IFSW 8 <\r |
| 313 | ADLM / ELSE RESET MUX REGISTER\r |
| 314 | >\r |
| 315 | IFNSW 8 <\r |
| 316 | DCA SAMINS\r |
| 317 | JMS LNCSAM /SET CHANNEL TO START IN CASE\r |
| 318 | /CLOCK INITIATED\r |
| 319 | >\r |
| 320 | TAD NCHANL+2 /NUMBER OF CHANNELS\r |
| 321 | DCA NCHANL+1 /INTO COUNTER\r |
| 322 | \f ORG FSMPLE+200\r |
| 323 | /\r |
| 324 | / HERE WE SWAP THE INPUT BUFFERS POINTERS\r |
| 325 | /\r |
| 326 | SWPBFR, 0\r |
| 327 | /\r |
| 328 | / SWAP BUFFER POINTERS\r |
| 329 | /\r |
| 330 | TADZ NXTBUF / NXTBUF <=> CURBUF\r |
| 331 | DCA BUFCDF / BUFCDF, PBUFF = NXTBUF\r |
| 332 | TADZ NXTBUF+1\r |
| 333 | DCAZ PBUFF\r |
| 334 | TADZ CURBUF\r |
| 335 | DCAZ NXTBUF\r |
| 336 | TADZ CURBUF+1\r |
| 337 | DCAZ NXTBUF+1\r |
| 338 | TAD% IBUFCDF\r |
| 339 | DCAZ CURBUF\r |
| 340 | TADZ PBUFF\r |
| 341 | DCAZ CURBUF+1\r |
| 342 | TAD% IBUFSIZ /RESET BUFFER COUNTER\r |
| 343 | DCA% ISAMCNT\r |
| 344 | JMP% SWPBFR\r |
| 345 | IBUFCDF=.+1\r |
| 346 | ADDR BUFCDF\r |
| 347 | IBUFSIZ=.+1\r |
| 348 | ADDR BUFSIZ\r |
| 349 | ISAMCNT=.+1\r |
| 350 | ADDR SAMCNT\r |
| 351 | /\r |
| 352 | / SAMPLING RATE TOO FAST\r |
| 353 | /\r |
| 354 | TOOFST,/\r |
| 355 | CLA IAC /SET STATUS WORD TO 1.0\r |
| 356 | DCAZ% CURSTT\r |
| 357 | IAC\r |
| 358 | DCAZ% NXTSTT\r |
| 359 | JMP% ISAMXIT\r |
| 360 | ISAMXIT=.+1\r |
| 361 | ADDR SAMXIT\r |
| 362 | IFNSW 8 <\r |
| 363 | LNCSAM, 0 /LINC SAM SUBROUTINE\r |
| 364 | LINC\r |
| 365 | SAMINS, SAM 0 /SAMPLE AND SELECT NEXT CHANNEL\r |
| 366 | PDP\r |
| 367 | DCA SAMTMP /SAVE IT\r |
| 368 | JMP% LNCSAM\r |
| 369 | >\r |
| 370 | -2LT\f ORG FSMPLE+400\r |
| 371 | /\r |
| 372 | / INTERRUPT TIME SCHMITT TRIGGER INPUT HANDLER\r |
| 373 | /\r |
| 374 | IFSW 4 <\r |
| 375 | ENRTY FIREED\r |
| 376 | >\r |
| 377 | FIREED, 0 / ON ENTRY AC IS CLEARED BY CLOCK RTN\r |
| 378 | CLA CLL CMA RTL / -3 --> AC\r |
| 379 | DST; MQSAVE / FIRST: STRIG COUNTER, SECOND SAVES MQ\r |
| 380 | CAM / MQ HOLDS # OF STRIGG FIRED, FIRST IS #0\r |
| 381 | TAD CSTAT / CLSA BITS OF FIRST CLOCK --> AC\r |
| 382 | TRILOP, RAL / STRIG BITS --> LINK\r |
| 383 | SWP / NOW AC HOLDS # OF STRIGG \r |
| 384 | SZL / SKIP IF STRIGG DID NOT FIRE\r |
| 385 | JMS TRIGGED / ELSE SET THE TRIGGER TIME WORD\r |
| 386 | IAC / INCREMENT FOR NEXT STRIGG\r |
| 387 | SWP / # OF STRIGG --> MQ, CLSA BIT MASK --> AC\r |
| 388 | ISZ MQSAVE / SOME MORE STRIGS?\r |
| 389 | JMP TRILOP / YES, FETCH THE NEXT EVENT\r |
| 390 | CAM / STRIGS DONE, TEST FOR CLOCK OVERFLOW\r |
| 391 | TAD CTSTAT / CLSA BITS --> AC\r |
| 392 | RAR / LINK GOES ON IF CLOCK OVERFLOWED\r |
| 393 | DLD; MQSAVE / RESTORE MQ, CLEAR AC! TRICKSY!\r |
| 394 | SNL / IF NO CLOCK OVERFLOW THEN\r |
| 395 | JMP% FIREED / RETURN TO CLOCK ROUTINE\r |
| 396 | ISZ CLKOVR / ELSE INCREMENT CLOCK OVERFLOW COUNTER\r |
| 397 | NOP / PROTECT ISZ\r |
| 398 | JMP% FIREED / AND RETURN TO CLOCK IR SERVICE ROUTINE\r |
| 399 | /\r |
| 400 | MQSAVE, 0;0 / FIRST WORD IS USED FOR STRIGG COUNTER, SECOND SAVES MQ ON ENTRY\r |
| 401 | CLKOVR, 0;0 / HERE IS THE CLOCK OVERFLOW COUNTER, (SINGLE PRECISION, SECOND WORD HOLDS CLOCK COUNTER)\r |
| 402 | /\r |
| 403 | ACMQ, 0;0 / HERE FSMPLE AND TRIGGED ROUTINE SAVE AC&MQ ON ENTRY\r |
| 404 | ITIMWR, ADDR TIMWR / POINTER TO STRIGG TIME WORDS\r |
| 405 | TIMWRD, 0;0;0 / TIME WORDS FOR 3 SCHMITT TRIGGER CHANNELS\r |
| 406 | TIMBIT, 0;0 / THRUPT INSERTS RATE*12/SAMRAT\r |
| 407 | M13, -13 / CONSTANT USED TO TEST TIME SLICE OVERFLOW\r |
| 408 | IBITWR, TAD BITWRD / POINTER TO LOAD THE CORRECT BIT MASK FOR EACH TIME SLICE\r |
| 409 | BITWRD, 4000\r |
| 410 | 2000\r |
| 411 | 1000\r |
| 412 | 0400\r |
| 413 | 0200\r |
| 414 | 0100\r |
| 415 | 0040\r |
| 416 | 0020\r |
| 417 | 0010\r |
| 418 | 0004\r |
| 419 | 0002\r |
| 420 | 0001\r |
| 421 | /\r |
| 422 | / HERE WE COMPUTE THE STRIGG TIME WORD\r |
| 423 | /\r |
| 424 | TRIGGD, 0 / ON ENTRY AC HOLDS NUMBER OF SCHMITT TRIGGER FIRED\r |
| 425 | DST; ACMQ / SAVE AC AND MQ\r |
| 426 | TAD ITIMWR+1 / COMPUTE CORRECT ADDRESS OF TIME WORD\r |
| 427 | DCA ITIMWR\r |
| 428 | CLBA!CL1DEV / LOAD CLOCK BUFFER --> AC\r |
| 429 | MQL / AND INTO MQ, CLEAR AC\r |
| 430 | DAD; CLKOVR /AND ADD THE CLOCK OVERFLOW COUNTER\r |
| 431 | DST; CLKOVR / AND SAVE THE ACTUAL TIME OF THE EVENT\r |
| 432 | DVI; TIMBIT / TIMBIT= RATE*12/SAMRAT HERE WE COMPUTE THE TIME SLICES\r |
| 433 | MQL\r |
| 434 | MQA / SLICE --> AC AND MQ\r |
| 435 | TAD M13 / IF THERE ARE ALLREADY 12 SLICES PASSED \r |
| 436 | SMA SZA CLA / THEN STOP, ELSE GOON\r |
| 437 | HLT\r |
| 438 | MQA / TIME SLICE --> AC\r |
| 439 | TAD IBITWR / HERE WE DO SOME COMPUTATIONS \r |
| 440 | DCA .+3 / IN ORDER TO FETCH THE \r |
| 441 | TAD% ITIMWR / CORRECT BIT AND TIMEWORD.\r |
| 442 | MQL / PREP FOR .OR. TIMEWORD AND SLICE BIT\r |
| 443 | TAD BITWRD / IS REPLACED BY CORRECT TAD BITWRD+SLICE\r |
| 444 | MQA / OR THE TIMEWORD AND THE BIT\r |
| 445 | DCA% ITIMWR / AND PUSH BACK\r |
| 446 | DLD; ACMQ / RESET AC AND MQ\r |
| 447 | JMP% TRIGGD / AND RETURN!\r |
| 448 | \r |
| 449 | \fADSETU, 0 /SET UP ROUTINE\r |
| 450 | TADZ CURBUF /GET FIELD OF BUFFER\r |
| 451 | JMS MAKCDF /MAKE 3 BITS FLD INTO CDF\r |
| 452 | DCAZ CURBUF\r |
| 453 | TADZ CURBUF\r |
| 454 | DCA% IBUFCDF+1 /SAVE IN SAMPLER CODE\r |
| 455 | TADZ CURBUF+1 /SET SAMPLER BUFFER POINTER\r |
| 456 | DCAZ PBUFF\r |
| 457 | TADZ NXTBUF /GET FIELD OF ALTERNATE BUFFER\r |
| 458 | JMS MAKCDF\r |
| 459 | DCAZ NXTBUF\r |
| 460 | TAD BUFSIZ /SET INITIAL COUNT\r |
| 461 | DCA% ISAMCNT+1\r |
| 462 | TAD% JNCHANL+1 /SET CHANNEL COUNT\r |
| 463 | DCA% INCHANL+1\r |
| 464 | IFSW 8 <\r |
| 465 | CLA CMA /STOP THE CLOCK\r |
| 466 | CLZE\r |
| 467 | CLA\r |
| 468 | ADCL /CLEAR AD LOGIC JUST IN CASE\r |
| 469 | TAD L300 /SET AD ENABLE BITS, EXT START, AUTO INCREMENT\r |
| 470 | ADLE\r |
| 471 | TAD% JCSTART+1 /STARTING CHANNEL NUMBER\r |
| 472 | ADLM\r |
| 473 | >\r |
| 474 | IFNSW 8 <\r |
| 475 | CLEN /STOP THE CLOCK\r |
| 476 | TAD% JCSTART+1 /SET UP INITIAL SAM INSTRUCTION\r |
| 477 | TAD L100\r |
| 478 | DCA% JCSTART+1\r |
| 479 | TAD% JCSTART+1\r |
| 480 | DCA SAMINS\r |
| 481 | TAD L100 /SET FAST SAM BIT\r |
| 482 | IOF /TURN OFF INTERRUPTS IN LINC MODE\r |
| 483 | LINC /ENTER LINC MODE\r |
| 484 | ESF\r |
| 485 | PDP\r |
| 486 | JMS LNCSAM\r |
| 487 | ION\r |
| 488 | DST; ACMQ / SAVE MQ\r |
| 489 | DDZ; TIMWRD\r |
| 490 | DCA TIMWRD+1 / CLEAR STRIGG TIME WORDS\r |
| 491 | DDZ; CLKOVR / AND CLEAR CLOCK OVERFLOW COUNTER\r |
| 492 | >\r |
| 493 | CIF CDF\r |
| 494 | JMP% ADSETU\r |
| 495 | /\r |
| 496 | JNCHAN, ADDR NCHANL+2\r |
| 497 | INCHAN, ADDR NCHANL+1\r |
| 498 | JCSTAR, ADDR CSTART+2\r |
| 499 | ISAMCN, ADDR SAMCNT\r |
| 500 | IBUFCD, ADDR BUFCDF\r |
| 501 | \f/\r |
| 502 | / MAKE THREE BITS OF AC9-11 INTO CDF\r |
| 503 | /\r |
| 504 | MAKCDF, 0\r |
| 505 | AND L7\r |
| 506 | CLL RTL\r |
| 507 | BASEX, RAL\r |
| 508 | TAD CDF0\r |
| 509 | JMP% MAKCDF\r |
| 510 | /\r |
| 511 | NPOINT, 0;0;0\r |
| 512 | CDF0, CDF\r |
| 513 | 0;0\r |
| 514 | L7, 7\r |
| 515 | BUFSIZ, -377\r |
| 516 | IFSW 8 <\r |
| 517 | L300, 300\r |
| 518 | >\r |
| 519 | IFNSW 8 <\r |
| 520 | L100, 100\r |
| 521 | >\r |
| 522 | TEMP, 0;0;0\r |
| 523 | ORG 10*3+BASEX\r |
| 524 | 0\r |
| 525 | JA NAME+3\r |
| 526 | 0\r |
| 527 | SAMRTN, JA .\r |
| 528 | FP25, F 0.25\r |
| 529 | XVALID, F 56. / LENGTH OF READ VALID VECTOR\r |
| 530 | VALID, ORG .+70 / AND HERE IS THE BUFFER SPACE\r |
| 531 | /\r |
| 532 | / ROUTINE TO TEST FOR VALID SAMPLE ( PACKED DATA)\r |
| 533 | /\r |
| 534 | PVALID, ORG .+2\r |
| 535 | MVALID, ORG .+2\r |
| 536 | NVALID, ADDR VALID-1\r |
| 537 | /\r |
| 538 | TSTVLD, ORG .+1 / JMS TSTVLD\r |
| 539 | / SAMPLE NON VALID RETURN\r |
| 540 | / SAMPLE VALID RETURN\r |
| 541 | / ON RETURN AC=0\r |
| 542 | ISZ PVALID+1 / GET THE NEXT LOC. OF VALID VECTOR\r |
| 543 | CLA\r |
| 544 | TAD PVALID+1\r |
| 545 | TAD MVALID+1 / IF WE REACHED THE END OF THE VECTOR THEN\r |
| 546 | SPA CLA / WE RESET TO THE START ELSE\r |
| 547 | JMP L1 / CONTINUE AT L1\r |
| 548 | TAD NVALID+1\r |
| 549 | IAC\r |
| 550 | DCA PVALID+1\r |
| 551 | L1, TAD% PVALID+1 / READ VALID FLAG --> AC\r |
| 552 | SNA CLA / IF THIS READ WAS VALID THEN WE INCREMENT THE BUFFER POINTER ELSE\r |
| 553 | JMP% TSTVLD / WE TAKE THE NEXT SAMPLE INTO THIS LOCATION\r |
| 554 | ISZ TSTVLD / TAKE THE NORMAL RETURN FOR VALID SAMPLE \r |
| 555 | JMP% TSTVLD\r |
| 556 | \f EXTERN #ARGER\r |
| 557 | SECT THRUPT\r |
| 558 | BASE 0\r |
| 559 | STARTD\r |
| 560 | FLDA 30 /GET RETURN ADDR\r |
| 561 | FSTA SAMRTN\r |
| 562 | STARTF\r |
| 563 | FLDA 0\r |
| 564 | FSTA# TRETU\r |
| 565 | STARTD\r |
| 566 | FLDA% 0 / COMPUTE THE NUMBER OF PARAMETERS\r |
| 567 | FSUB 0\r |
| 568 | FSUB# TWO\r |
| 569 | SETX XR0\r |
| 570 | LDX 1,X1\r |
| 571 | ALN X1 / DIVIDE BY TWO\r |
| 572 | FNEG\r |
| 573 | ATX X2 / NEGATIVE NUMBER OF ARGUMENTS --> X2\r |
| 574 | FLDA 0 /GET ARG POINTER\r |
| 575 | BASE BASEX\r |
| 576 | SETB BASEX\r |
| 577 | FSTA TEMP /SAVE ARG POINTER\r |
| 578 | FCLA\r |
| 579 | FSTA CLINT /STOP ANY SAMPLING NOW!\r |
| 580 | FLDA% TEMP,1 /GET BUFF1 ADDRESS\r |
| 581 | FSTA CURBUF\r |
| 582 | LDX 1,X0\r |
| 583 | JXN TH0,X2+\r |
| 584 | TRAP4 #ARGER\r |
| 585 | TH0,\r |
| 586 | FLDA% TEMP,1+ /GET BUFF2 ADDR\r |
| 587 | FSTA NXTBUF\r |
| 588 | LDX 2,X0\r |
| 589 | JXN TH1,X2+\r |
| 590 | TRAP4 #ARGER\r |
| 591 | TH1,\r |
| 592 | FLDA% TEMP,1+ /ADDR OF PARAMETERS\r |
| 593 | FSTA PARAM / SAVE ADDR. OF PARAMETERS\r |
| 594 | FCLA\r |
| 595 | JXN TH2,X2+ / IF THERE ARE 4 OR MORE PARAMETERS THEN FETCH THE LAST BUT ONE\r |
| 596 | JA TH3 / ELSE THERE ARE 3 ARGUMENTS \r |
| 597 | TH2, FLDA% TEMP,X1+\r |
| 598 | TH3, FSTA PACK\r |
| 599 | FLDA PARAM / RESTORE ADR. OF THIRD ARGUMENT\r |
| 600 | FSTA TEMP\r |
| 601 | STARTF\r |
| 602 | LDX 0,1\r |
| 603 | FLDA% TEMP,1 /STARTING CHANNEL\r |
| 604 | ALN 0\r |
| 605 | FSTA CSTART\r |
| 606 | FLDA% TEMP,1+ /# CHANNELS\r |
| 607 | FSTA CHNLS\r |
| 608 | FNEG\r |
| 609 | ALN 0\r |
| 610 | FSTA NCHANL\r |
| 611 | FLDA% TEMP,1+ /NUMBER OF POINTS\r |
| 612 | FNEG\r |
| 613 | ALN 0\r |
| 614 | FSTA NPOINT\r |
| 615 | FLDA PACK\r |
| 616 | JEQ TH4 / ONLY THREE PARAMETERS\r |
| 617 | FLDA% TEMP,1+\r |
| 618 | FNEG\r |
| 619 | FSUB FL1\r |
| 620 | ALN 0\r |
| 621 | TH4, FSTA PCKSIG\r |
| 622 | ATX X2\r |
| 623 | /\r |
| 624 | TBIN0, SETX VALID\r |
| 625 | LDX 1,X0\r |
| 626 | SETX XR0\r |
| 627 | STARTD\r |
| 628 | FLDA NVALID\r |
| 629 | FSTA PVALID\r |
| 630 | FNEG\r |
| 631 | FADD PCKSIG+1\r |
| 632 | FSTA MVALID\r |
| 633 | /\r |
| 634 | FLDA PACK\r |
| 635 | JEQ TH5\r |
| 636 | FSTA TEMP\r |
| 637 | LDX -1,X1 / X2 HOLDS PCKSIG !\r |
| 638 | \r |
| 639 | FLDA TBIN0\r |
| 640 | FSTA TBIN1\r |
| 641 | STARTF\r |
| 642 | THL0, FLDA% TEMP,1+\r |
| 643 | TBIN1, SETX VALID / XR POINTER ONTO VALID VECTOR\r |
| 644 | ATX X0 / INSERT V. VALUE INTO THE VECTOR (WORD BY WORD)\r |
| 645 | SETX TBIN1 / NOW WE INCREMENT THE POINTER ABOVE\r |
| 646 | JXN .+2,X1+ / WITH THE X INCREMENT CMD AND\r |
| 647 | SETX XR0 / RESET TO THE INDEX REGISTER SET\r |
| 648 | JXN THL0,X2+ / AND NOW WE TEST IF THE WORK IS DONE\r |
| 649 | \r |
| 650 | TH5, STARTF\r |
| 651 | /\r |
| 652 | / INDEX REGISTERS (PBUFF) 1&2 ARE STATUS WORD PNTRS!\r |
| 653 | /\r |
| 654 | SETX PBUFF\r |
| 655 | LDX 11,1 /INITIALIZE STATUS WORD PNTRS\r |
| 656 | LDX 14,2\r |
| 657 | FLDA FP25 /INITIALIZE STATUS WORDS\r |
| 658 | FSTA STAT1 /TO INDICATE BUFFERS\r |
| 659 | FSTA STAT2 /NOT FILLED\r |
| 660 | TRAP4 ADSETU /SET UP AD STUFF\r |
| 661 | STARTD\r |
| 662 | FLDA SAMADR /SET UP SAMPLER INTRPT HNDLR\r |
| 663 | FSTA CLINT\r |
| 664 | STARTF\r |
| 665 | JA SAMRTN /RETURN\r |
| 666 | NAME, TEXT +THRUPT+\r |
| 667 | SETX XR0\r |
| 668 | SETB BASEX\r |
| 669 | TRETU, F 0.\r |
| 670 | SAMADR, ADDR FSMPLE\r |
| 671 | /\r |
| 672 | XR0, 0\r |
| 673 | XR1, 0 / HOLDS NUMBER OF ARGUMENTS\r |
| 674 | XR2, 0\r |
| 675 | XR3, 0\r |
| 676 | X0= 0\r |
| 677 | X1= X0+1\r |
| 678 | X2= X1+1\r |
| 679 | X3= X2+1\r |
| 680 | ONE, 0;1;0\r |
| 681 | TWO, 0;2;0\r |
| 682 | FL1, F 1.\r |
| 683 | PARAM,\r |
| 684 | CHNLS, F 0.\r |
| 685 | PCKSIG, F 0.\r |
| 686 | PACK, F 0. / HOLDS ADR. OF FOURTH ARGUMENT\r |
| 687 | NTRIG, F 0. / HOLDS ADDR. OF FIFTH ARGUMENT\r |
| 688 | \f/**** WORD SUBROUTINES ****\r |
| 689 | /\r |
| 690 | WPCNT, 0;0\r |
| 691 | WC1, 0;6\r |
| 692 | BASE WDBASE\r |
| 693 | WDBASE, F 0. /PNTR TO ARGS\r |
| 694 | WDINDX, F 0. /INDEX TO WORD IN ARRAY\r |
| 695 | WDOPER, F 0. /TARGET OR SOURCE ADDR\r |
| 696 | F1, F 1.\r |
| 697 | STXMJA, 0;1100-1030;0 /STX - JA\r |
| 698 | WORDOP, TEXT +WORDOP+\r |
| 699 | 0\r |
| 700 | WDRTN, JA .\r |
| 701 | WINDEX, F 0. /INDEX REGS 0-2\r |
| 702 | /\r |
| 703 | ORG 10*3+WDBASE\r |
| 704 | 0\r |
| 705 | JA WORDOP+3\r |
| 706 | /\r |
| 707 | /**** WGET - WORD GET ****\r |
| 708 | /\r |
| 709 | / CALL WGET(BUFF1,NWORD,Y)\r |
| 710 | /\r |
| 711 | ENTRY WGET\r |
| 712 | WGET, JSA WDSET /INIT REGISTERS\r |
| 713 | FLDA WPCNT / LOOK IF CALLED WITH TWO PARAMETERS\r |
| 714 | JEQ W2PAR / TWO PARAMETERS ONLY, OUPUT VIA FAC\r |
| 715 | XTA 0 /GET WORD FROM BUFF1\r |
| 716 | FSTA% WDOPER /STICK IT IN X\r |
| 717 | JA WDRTN\r |
| 718 | W2PAR, XTA 0\r |
| 719 | JA WDRTN\r |
| 720 | /\r |
| 721 | /**** WPUT - WORD PUT ****\r |
| 722 | /\r |
| 723 | / CALL WPUT(BUFF1,NWORD,Y)\r |
| 724 | /\r |
| 725 | ENTRY WPUT\r |
| 726 | WPUT, JSA WDSET /INIT REGISTERS\r |
| 727 | FLDA% WDOPER /GET Y\r |
| 728 | ATX 0 /FIX AND STORE IN BUFF1\r |
| 729 | JA WDRTN\r |
| 730 | /\r |
| 731 | / WGET & WPUT INITIALISATION\r |
| 732 | /\r |
| 733 | BASE 0\r |
| 734 | WDSET, 0;0\r |
| 735 | STARTD\r |
| 736 | FLDA 30 /GET RTN ADDR\r |
| 737 | FSTA WDRTN\r |
| 738 | FLDA 0 /PNTR TO ARGS\r |
| 739 | SETB WDBASE\r |
| 740 | BASE WDBASE\r |
| 741 | SETX WINDEX\r |
| 742 | FSTA WDBASE\r |
| 743 | LDX 0,1 / COMPUTE NUMBER OF PARAMETERS\r |
| 744 | FLDA% WDBASE,1 / ADR. FOLLOWING THE PARAMETER LIST --> FAC\r |
| 745 | FSUB WDBASE / SUBTRACT THE START ADR. OF PARAMETER LIST\r |
| 746 | FSUB WC1 / FAC-5 --> FAC\r |
| 747 | FSTA WPCNT / WPCNT=0 <==> TWO PARAMETERS, =2 <==> THREE PARAMETERS\r |
| 748 | FLDA% WDBASE,1+ /BUFFER ADDR\r |
| 749 | FADD STXMJA /MAKE SETX INST\r |
| 750 | FSTA WDSETX\r |
| 751 | FLDA% WDBASE,1+ /WORD INDEX ADDR\r |
| 752 | FSTA WDINDX\r |
| 753 | FLDA WPCNT / TEST IF THERE ARE MORE THAN 2 PARAMETERS\r |
| 754 | JEQ WCONT / \r |
| 755 | FLDA% WDBASE,1+ /RESULT OR VALUE ADDR\r |
| 756 | FSTA WDOPER\r |
| 757 | WCONT,\r |
| 758 | STARTF\r |
| 759 | FLDA% WDINDX /WORD INDEX\r |
| 760 | FSUB F1 /COMPUT ADDR OF WORD\r |
| 761 | ALN 0\r |
| 762 | STARTD\r |
| 763 | FADDM WDSETX\r |
| 764 | WDSETX, SETX 0 /MODIFIED DURING EXEC\r |
| 765 | STARTF\r |
| 766 | JA WDSET\r |
| 767 | / SUBROUTINE TO RELEASE A BUFFER BY RESETTING\r |
| 768 | / THE STATUS REGISTER\r |
| 769 | /\r |
| 770 | / CALL RELEAS(N)\r |
| 771 | /\r |
| 772 | / N DESIGNATES THE STATUS REGISTER, N SHOULD BE 1\r |
| 773 | / OR 2. IF N .NE. 1, 2 IS ASSUMED.\r |
| 774 | /\r |
| 775 | ENTRY RELEAS\r |
| 776 | BASE 0\r |
| 777 | RELEAS, STARTD\r |
| 778 | FLDA 30 /GET RTN ADDR\r |
| 779 | FSTA WDRTN\r |
| 780 | FLDA 0 /GET ARG PNTR\r |
| 781 | BASE WDBASE\r |
| 782 | SETB WDBASE\r |
| 783 | SETX WINDEX\r |
| 784 | FSTA WDBASE\r |
| 785 | LDX 1,1\r |
| 786 | FLDA% WDBASE,1 /N ADDR\r |
| 787 | FSTA WDBASE\r |
| 788 | SETX STAT1 /MODIFY STATUS VIA INDEX\r |
| 789 | STARTF\r |
| 790 | FLDA% WDBASE /N\r |
| 791 | FSUB F1 /TEST FOR NOT 1\r |
| 792 | JNE CLR2 /ASSUME STAT2\r |
| 793 | LDX -1,0 /CHANGE EXPONENT\r |
| 794 | /TO -7 TO MAKE 0.25\r |
| 795 | JA WDRTN\r |
| 796 | CLR2, LDX -1,3 /STAT2 EXP TO -1\r |
| 797 | JA WDRTN\r |
| 798 | \f\1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 |