1! MESMAN EDIT 6B-1 MARCH, 1977 ! PETER MULLEN 20! MESMAN is the program which handles all notices that are sent to users To send a notice the user runs MESSAG. 21! MESMAN distinguishes between three types of notices; SYSTEM- the system notice. When there is a new system notice MESMAN will insure that every account will receive the notice at least once. 22! GROUP- The instructor of a project is able to send a notice to every programmer in his project. Each programmer will receive the notice once, when log into the system. INDIVIDUAL- The notice the one user con send to another. 23! The account to which the notice is directed will receive the prompt RUN $RECEIVE, when someone first signs on. 400 DIM I%(30%), L4%(1024%), Q%(20%,2%), B%(15%) ! ! IN CORE ARRAYS ! 401 ! USED AS FOLLOWS ! I%()- USED TO GET MESSAGES IN ! L4%()- KEEPS LIST OF USERS WHO HAVE INDIVIDUAL MESSAGES WAITING ! Q%(,)- QUE THAT MESSAGES WAITING TO BE PROCESSED ARE KEPT ON 402 ! B%()- HOLDS BIT PATTERNS ! 410 DIM #1%, L1%(1023%), L2%(1023%) ! ! IN FILE A9$+'MESMAN.PT1' ! L1%()- HOLDS INFORMATION ON WHICH USER NEEDS SYSTEM NOTICE SENT ! L2%()- HOLDS INFORMATION ON WHICH USER HAS A GROUP NOTICE WAITING ! 420 DIM #2%, L3%(2047%) ! ! IN FILE A9$+'MESMAN.PT2' ! L3%()- HOLDS LINKED LIST AND POINTERS FOR INDIVIDUAL MESSAGES ! 430 DIM #3%, M$(2500%)=32% ! ! IN FILE A9$+'MESMAN.STR' ! M$()- STORES MESSAGES ! 440 DIM #5%, C5$(254%)=32% ! ! TEMP FILE TEMPLATE. ! C5$()- HOLDS MESSAGE THAT ONE USER SENDS TO AN OTHER ! 450 DIM #6%, L5%(2047%) ! ! USED FOR GARBAGE COLLECTION ! L5%()- SAME AS L3%() AFTER GARBAGE COLECTION ! 460 DIM #7%, M9$(2047%)=32% ! ! USED FOR GARBAGE COLLECTION ! M9$()- SAME AS M$() AFTER GARBAGE COLLECTION ! 1000 ! ! I N I T I A L I Z A T I O N 1005 I$=FNM9$('PUT ON LINE AT '+TIME$(0%)) \ A9$='(1,3)' \ A8$='(1,4)' \ INPUT 'SHOULD FILES BE INITIALIZED';I$ \ GOTO 1030 IF CVT$$(I$,255%)='YES' ! CHECK TO SEE IF FILES SHOULD BE CLEANED ! A9$- ACCOUNT THAT MASTER FILES ARE STORED ON ! A8$- ACCOUNT THAT TEMP. MESSAGE FILES ARE OPENED ON 1010 ON ERROR GOTO 1020 \ OPEN A9$+'MESMAN.PT1' FOR INPUT AS FILE 1% \ OPEN A9$+'MESMAN.PT2' FOR INPUT AS FILE 2% \ OPEN A9$+'MESMAN.STR' FOR INPUT AS FILE 3% \ GOTO 1050 1020 IF ERR=5% THEN RESUME 1030 ELSE ON ERROR GOTO 0 1030 GOSUB 14000 ! INITIALIZE FILES IF THEY DO NOT EXIST 1050 B%(I%)=2%^I% FOR I%=0% TO 15% \ D%=PEEK(SWAP%(CVT$%(RIGHT(SYS(CHR$(6%)+CHR$(-3%)),7%)))+ ASCII(RIGHT(SYS(CHR$(6%)+CHR$(-12%)),9%))) ! BIT PATERNS FOR TESTING PROGRAMMERS BITS ! BASE OF TERMINAL DDB POINTER TABLE 1060 Q1%=-1% \ Q2%=0% ! QUEUE FOR NOTICES TO ADD TO PROGRAM STORAGE 1070 P1%=L2%(111%) \ T%=L3%(1%) \ L4%(0%)=0% ! P1%- FREE STRING POINTER L4%()- KEEP INDIVIDUAL NOTICE PPNS IN CORE FOR QUICK ACCESS 1080 WHILE T%<>-1% \ L4%(0%)=L4%(0%)+1% \ L4%(L4%(0%))=L3%(T%+1%) \ T%=L3%(T%) \ NEXT ! GO THROUGH LINKED LIST RECORDING PPN THAT HAVE MESSAGES 1090 B1%=8% \ P%=1% ! B1%- NUMBER OF PSEUDO KEYBOURDS *2 (MUST BE CHANGED IF DIFFERENT) P%- JOB PROCESSING POINTER 1100 A1$=CHR$(6%)+CHR$(18%) \ A2$=CHR$(30%)+MID(SYS(CHR$(6%)+CHR$(-10%)+'MESMAN'),7%,4%) ! PREPARE RECEIVE STRINGS 1990 PRINT 'DETACHING.. .' \ PRINT\ PRINT\ PRINT \ I$=SYS(CHR$(6%)+CHR$(7%)) ! DETACH 1995 Z9%=0% \ IF P1%>950% OR L3%(0%)>1900% THEN GOSUB 6040 ! CHECK FOR GARBAG AT BEGINING 2000 ! ! M A I N P R O G R A M 2010 W%=2% \ON ERROR GOTO 19000 ! SLEEP UNTIL FIRST MESSAGE SET ERROR TRAP 2020 ON FNM%(W%)+1% GOSUB 5000,3000,3500 ,4000, 2050, 32760, 3600 \ GOTO 2020 ! VALUE FNM% RETURNS DEPENDS ON WHAT PROGRAM SENT MESSAGE 2030 ! 0% - NO MESSAGE (PROCESS UNFINISHED WORK) 1% - LOGIN SENT (CHECK FOR MESSAGES TO SEND) 2% - RECEIV SENT (DELETE USER FROM LIST) 3%- MESSAGE SENT (PLACE ON QUE, NEW MESSAGE) 2040 ! 4%- DUMMY MESSAGE (DO NOTHING) 5%- SHUTUP SENT (CLOSE FILES AND KILL YOURSELF) 6%- MESSAG SENT (INDIVIDUAL MESSAGE DELETEION) 2050 RETURN ! DUMMY MESSAG, USED TO TEST IF MESMAN IS RUNNING 3000 ! CHECK TO SEE IF THIS NEW USER SHOULD BE SENT ANY NOTICES K%- FALSE IF NOTICE POINTERS SHOULD BE RESET 3010 IF I%(10%)<=B1% AND I%(10%)>0% THEN RETURN ELSE K%=0% ! DO NOT SEND NOTICES TO BATCH JOBS 3020 IF FNL1% THEN GOSUB 7000 IF I%(11%) !CHECK TO SEE IF USER NEEDS SYSTEM NOTICE SENT BUT ONLY SEND IF LOG IN DID NOT 3030 IF FNL2% THEN GOSUB 7000 ! IS THERE A GROUP NOTICE PENDING? 3040 IF FNL3% THEN GOSUB 7000 ! ANY INDIVIDUAL COMMUNICATIONS? 3045 M1%=2% \ GOSUB 7000 IF K% ! SEND Ready MESSAGE TO ALL USERS 3050 T%=L1%(0%) \ RETURN ! SHIFT BUFFERS TO KEEP FILES CURRENT 3500 ! DELETE USER PPN FROM LISTS 3510 T%=I%(8%)+SWAP%(I%(7%)) \ T1%=1% ! PREPARE FOR LIST SEARCH 3520 T2%=T1% \ T1%=L3%(T1%) \ IF T1%<>-1% THEN IF L3%(T1%+1%)<>T% THEN 3520 ELSE L3%(T2%)=L3%(T1%) \ IF T2%>255% THEN T1%=L3%(0%) ELSE T1%=L3%(256%) 3530 GOTO 3540 IF T%=L4%(I%) FOR I%=1% TO L4%(0%) \ RETURN ! SEARCH IN CORE STORAGE FOR PPN 3540 L4%(I%)=L4%(L4%(0%)) \ L4%(0%)=L4%(0%)-1% \ RETURN ! RESET POINTERS IN INCORE ARRAY 3600 ! ! D E L E T E I N D I V I D U A L M E S S A G E S ! ! 3610 ON I%(12%) GOTO 3620, 3630, 3650 ! BRANCH TO ROUTINES 3620 L1%(0%)=-1% \ RETURN ! DELETE SYSTEM NOTICE 3630 GOTO 3640 IF I%(11%)=L2%(I%) FOR I%=1% TO L2%(0%) \ RETURN ! DELETE GROUP NOTICE, RETURN IF NONE EXISTES 3640 L2%(I%)=L2%(L2%(0%)) \ L2%(I%+55%)=L2%(L2%(0%)+55%) \ L2%(I%*16%+96%+J%)=L2%(L2%(0%)*16%+96%+J%) FOR J%=0% TO 15% \ L2%(0%)=L2%(0%)-1% \ RETURN 3650 RETURN ! NOT AVAILABLE NOW 4000 ! NEW NOTICE, PLACE ON QUE Q%(,)- QUE Q%(,0%)- PPN Q%(,1%)- TYPE,EXTENSION 4010 IF Q1%=Q2% THEN I$=FNM9$('QUE OVERFLOW') \ RETURN ! QUE OVERFLOW SEND OPERATOR MESSAGE Q1%- TOP OF QUE Q2%- BOTTOM OF QUE 4020 Q1%=Q2% IF Q1%=-1% \ Q%(Q2%,0%)=I%(11%)+SWAP%(I%(10%)) \ Q%(Q2%,1%)=I%(13%)+SWAP%(I%(12%)) \ Q%(Q2%,2%)=I%(8%)+SWAP%(I%(7%)) ! PLACE NOTICE ON QUEUE 4030 IF Q2%>=20% THEN Q2%=0% ELSE Q2%=Q2%+1% ! UPDATE NEXT FREE PLACE IN QUE 4040 W%=1% \ RETURN ! THERE IS WORK TO BE DONE SO DO NOT SLEEP IF NO NEW MESSAGE 5000 ! NO MESSAGE FINISH PROCESSING ANOTHER JOB P%- STATUS OF PROCESSING ON THIS JOB Q1%- POINTER TO INFOMATION ON THIS JOB. 5010 ON P% GOSUB 5100,5200,5300,6040 \ RETURN ! WORK ON STEP THAT IS NEXT 5100 ! OPEN TEMPFILE THAT NOTICE IS STORED IN 5110 IF Q1%<>-1% THEN ON ERROR GOTO 5140 ELSE W%=2%\ RETURN ! IF NO JOB WAITING RETURN AND SLEEP 5115 F1%=(Q%(Q1%,0%) AND 255%) + 200% \ F2%=Q%(Q1%,0%)/256% + 200% ! DETERMINE WHO NOTICE IS FOR 5117 I$=A8$+NUM$(F1%)+NUM$(F2%)+'.'+NUM$((Q%(Q1%,1%) AND 255%)+200%) \ OPEN I$ FOR INPUT AS FILE 5% \ KILL I$ \ P%=2% ! OPEN TEMP FILE 5120 IF Z9% THEN CLOSE 5% ELSE ON ERROR GOTO 0 \ RETURN ! IF Z9% IS SET THEN KILL FILE BY CLOSING IT 5130 ON ERROR GOTO 19000 \ Q1%=Q1%+1% \ Q1%=0% IF Q1%>=21% \ Q1%=-1% IF Q1%=Q2% \ P%=1% \ RETURN ! UPDATE QUEUE TO NEXT JOB 5140 IF ERR=5% THEN RESUME 5130 ELSE ON ERROR GOTO 0 5200 ! TRANSFER NOTICE FROM TEMPFILE TO NOTICE STORAGE P1%- FREE STRING POINTER IN M$() M$()- 32 BYTE VIRTUAL STRING ARRAY (NOTICE STORAGE) L2%(111%)- WHERE P1% IS STORED ON THE DISK 5210 P2%=P1% \ T%=ASCII(C5$(0%))-1% \ M$(P1%+I%)=C5$(I%) FOR I%=0% TO T% ! SAVE HEAD OF THIS NOTICE, DO TRANSFER 5220 L2%(111%),P1%=P1%+T%+1% \ P%=3% \ CLOSE 5% \ M$(P1%+17%)=' ' \ RETURN ! RESET FREE STRING POINTER MOVE BUFFER TO KEEP FILE CURRENT 5300 ! RESET POINTERS Q%(Q1%,1%)/256%- TYPE OF NOTICE BEING PROCESSED I%- SYSTEM 2%- GROUP 3%- INDIVIDUAL 5310 ON Q%(Q1%,1%)/256% GOSUB 5400,5450,5500 \ IF Q1%>=20% THEN Q1%=0% ELSE Q1%=Q1%+1% ! SET POINTERS ACCORDING TO TYPE OF MESSAGE RESET TOP OF QUE 5320 Q1%=-1% IF Q1%=Q2% \ P%=1% \ P%=4% IF L3%(0%)>2000% OR P1%>1000 \ RETURN ! CHECK IF GARBAGE COLLECTION NEEDS DOING 5400 L1%(0%)=P2% \ L1%(1%)=1% \ RETURN ! RESET POINTERS FOR NEW SYSTEM NOTICE 5450 ! RESET POINTERS FOR NEW GROUP MESSAGE 5460 T%=Q%(Q1%,0%) AND 255% \ GOTO 5470 IF T%=L2%(I%) FOR I%=1% TO L2%(O%) \ I%,L2%(0%)=L2%(0%)+1% \ L2%(I%)=T% ! BRANCH IF PROJECT # ALREADY EXISTS, OTHERWIZE CREATE IT 5470 L2%(I%+55%)=P2% \ I%=I%*16%+96% \ L2%(I%+J%)=-1% FOR J%=0% TO 15% \ RETURN ! SET BITS FOR EACH PROGRAMMER IN PROJECT 5500 ! RESET POINTERS FOR INDIVIDUAL NOTICES P2%- POINTER TO NOTICE STORAGE L3%(0%)- START OF FREE SPACE 5510 T%=1% \ T1%=L3%(0%) ! PREPARE FOR LINKED LIST SEARCH 5520 IF Q%(Q1%,0%)=L3%(T%+1%) THEN 5540 ELSE IF L3%(T%)=-1% THEN 5530 ELSE T%=L3%(T%)\ GOTO 5520 ! SEARCH THROUGH LIST FOR MATCH OR END OF LIST 5530 L3%(T%)=T1% \ L3%(T1%)=-1% \ L3%(T1%+1%)=Q%(Q1%,0%) \ L3%(T1%+2%)=-1% \ L3%(T1%+3%)=P2% 5535 L3%(T1%+4%)=Q%(Q1%,2%) \ L3%(0%)=T1%+5% \ GOTO 5550 ! THIS PPN NOT ON LIST, MAKE NEW NODE WITH IDENTIFICATION INFORMATION AND POINTER TO NOTICE 5540 T%=T%+2% \ T%=L3%(T%) WHILE L3%(T%)<>-1% \ L3%(T%)=T1% \ L3%(T1%)=-1% \ L3%(T1%+1%)=P2% 5545 L3%(T1%+2%)=Q%(Q1%,2%) \ L3%(0%)=T1%+3% ! THIS USER ALREADY ON LIST, PUT NOTICE AT END OF EXISTING NOTICES 5550 GOTO 5560 IF L4%(I%)=Q%(Q1%,0%) FOR I%=1% TO L4%(0%) \ L4%(0%)=L4%(0%)+1% \ L4%(L4%(0%))=Q%(Q1%,0%) ! ADD PPN TO IN CORE STORAGE SHIFT BUFFERS SO FILES ARE CURRENT 5560 T%=L3%(256%) \ RETURN 6000 ! ! G A R B A G E C O L L E C T I O N ! ! 6010 ! VARIABLES USED IN GARBAGE COLLECTION: ! M$()- OLD VIRTUAL STRING STORAGE ! M9$()- NEW VIRTUAL STRING STORAGE ! L3%()- OLD VIRTUAL POINTER STORAGE ! L5%()- NEW VIRTUAL POINTER STORAGE 6020 ! GARBAGE COLLECTION WILL TRANSFER ALL STRINGS AND POINTERS ! THAT ARE STILL IN USE FROM THE OLD STORAGE TO THE NEW STORAGE. 6030 ! P1%- NEXT FREE STRING IN M9$() ! M1%- POINTS TO A MESSAGE IN M$() THAT SHOULD BE TRANSFERED TO ! M9$() AT P1% BY SUBROUTINE 6600 ! P2%- NEXT FREE POINTER IN L5%() 6040 I$=SYS(CHR$(6%)+CHR$(18%)+CHR$(0%)+CHR$(0%)) \ I$=FNM9$('STARTING GARBAGE COLLECTION AT '+TIME$(0%)) \ I$=FNM9$(NUM$(P1%)+'USED STRINGS') \ I$=FNM9$(NUM$(L3%(0%))+'USED INTEGERS') ! SEND OPERATOR MESSAGE FOR GARBAGE COLLECTION 6050 OPEN A9$+'MES01.TMP' FOR OUTPUT AS FILE 6%, CLUSTERSIZE 8%, FILESIZE 8% \ OPEN A9$+'MES02.TMP' FOR OUTPUT AS FILE 7%, CLUSTERSIZE 8%, FILESIZE 64% ! OPEN TEMP FILES, TO BE RENAMED LATER 6060 P1%=0% \ M1%=0% \ GOSUB 6600 \ M1%=2% \ GOSUB 6600 \ T%=L2%(0%) + 55% ! TRANSFER PERMANENT NOTICES 6070 IF L1%(0%)<>-1% THEN M1%=L1%(0%) \ L1%(0%)=P1% \ GOSUB 6600 ! TRANSFER SYSTEM NOTICE IF THERE IS ONE 6080 FOR J4%=56% TO T% \ M1%=L2%(J4%) \ L2%(J4%)=P1% \ GOSUB 6600 \ NEXT J4% ! TRANSFER GROUP NOTICES 6090 P2%=3% \ L5%(2%)=0% \ G%=1% \ T%=L3%(1%) ! INITIALIZE FOR TRANSFER OF INDIVIDUAL MESSAGES 6100 WHILE T%<>-1% \ L5%(G%)=P2% \ G%=P2% \ L5%(P2%+1%)=L3%(T%+1%) \ P2%=P2%+2% \ T1%=T%+2% ! START OUTER LOOP THROUGH PPNS 6110 G1%=P2% \ L5%(P2%+1%)=P1% \ M1%=L3%(T1%+1%) \ GOSUB 6600 \ L5%(P2%+2%)=L3%(T1%+2%) \ T1%=L3%(T1%) \ P2%=P2%+3% ! FIRST MESSAGE IS SPECIAL BECAUSE IT HAS NO PREVIOUS LINK 6120 WHILE T1%<>-1% \ L5%(G1%)=P2% \ G1%=P2% \ L5%(P2%+1%)=P1% \ M1%=L3%(T1%+1%) \ GOSUB 6600 \ L5%(P2%+2%)=L3%(T1%+2%) ! TRANSFER INFORMATION FOR MESSAGES 6130 P2%=P2%+3% \ T1%=L3%(T1%) ! MOVE TO NEXT MESSAGE 6140 NEXT \ L5%(G1%)=-1% \ T%=L3%(T%) ! FINISHED WITH THIS MESSAGE LIST, MOVE TO NEXT PPN 6150 NEXT \ L5%(G%)=-1% \ L5%(0%)=P2% \ L2%(111%)=P1% ! FINISH TRANSFER, STORE FREE SPACE POINTERS 6160 CLOSE 2,3,6,7\ I%=L1%(0%) \ KILL A9$+'MESMAN.PT2' \ KILL A9$+'MESMAN.STR' \ NAME A9$+'MES01.TMP' AS A9$+'MESMAN.PT2<40>' \ NAME A9$+'MES02.TMP' AS A9$+'MESMAN.STR<40>' ! RENAME FILES 6170 OPEN A9$+'MESMAN.PT2' FOR INPUT AS FILE 2% \ OPEN A9$+'MESMAN.STR' FOR INPUT AS FILE 3% \ I$=FNM9$('GARBAGE COLLECTION COMPLETED AT '+TIME$(0%)) \ I$=FNM9$(NUM$(P1%)+'USED STRINGS') 6180 I$=FNM9$(NUM$(P2%)+'USED INTEGERS') \ P%=1% \ IF P1%<950% AND L3%(0%)<=1900% THEN RETURN ! RETURN UNLESS GARBAG COLLECTION DID NOT SHRINK STORAGE 6190 I$=FNM9$('STORAGE FULL WILL NOT PROCESS NEW MESSAGES') \ Z9%=-1% \ RETURN 6600 J1%=ASCII(M$(M1%))-1% \ M9$(P1%+J%)=M$(M1%+J%) FOR J%=0% TO J1% \ P1%=P1%+J1%+1% \ RETURN ! TRANSFER STRINGS 6700 DEF FNM9$(A$)=SYS(CHR$(6%)+CHR$(-5%)+CHR$(0%)+"'MESMAN' MESSAGE: "+ A$+CHR$(13%)+CHR$(10%)) ! FUNCTION TO COMUNICATE WITH THE OPERATOR 7000 ! SEND NOTICE M1%- POINTER TO HEAD OF NOTICE I%(10%)- KEYBOARD # *2 7010 RETURN IF M1%=-1% \ K%=-1% \ T1%=I%(10%) \ T%=ASCII(M$(M1%))-1% \ T2%=PEEK(D%+T1%) \ T1%=T1%/2% \ I$=SYS(CHR$(6%)+CHR$(-5%)+CHR$(T1%)+RIGHT(M$(M1%),2%)) ! GET TERMINAL NUMBER ! GET LENGTH OF MESSAGE ! GET BASE OF TERMINAL DDB ! SEND FIRST LINE OF MESSAGE 7020 FOR I%=1% TO T% \ T%=T% WHILE PEEK(T2%+10%)<>PEEK(T2%+12%) \ I$=SYS(CHR$(6%)+CHR$(-5%)+CHR$(T1%)+M$(M1%+I%)) ! SLEEP UNTIL OUTPUT IS FINISHED ! SEND NEXT PART OF MESSAGE 7030 NEXT I% \ RETURN 14000 OPEN A9$+'MESMAN.PT1' FOR OUTPUT AS FILE 1%,CLUSTERSIZE 8% FILESIZE 8% \ OPEN A9$+'MESMAN.PT2<40>' FOR OUTPUT AS FILE 2%,CLUSTERSIZE 8% ,FILESIZE 8% 14005 OPEN A9$+'MESMAN.STR<40>' FOR OUTPUT AS FILE 3%, CLUSTERSIZE 8% FILESIZE 64% ! OPEN FILES 14010 L1%(1%)=1% \ L1%(0%)=-1% \ L2%(0%)=0% \ L2%(111%)=3% \ L3%(0%)=3% \ L3%(1%)=-1% \ L3%(2%)=0%\ T%=L3%(256%) ! DEFINE END OF LIST, ETC. POINTERS 14015 I$=FNM9$('FILES INITIALIZED AT '+TIME$(0%)) ! SEND OPERATOR MESSAGE 14020 M$(0%)=CHR$(2%)+"Message Waiting type 'RUN $RECE" \ M$(1%)="IVE'"+CHR$(13%)+CHR$(10%)+CHR$(10%) \ M$(2%)=CHR$(1%)+CHR$(10%)+'Ready'+CHR$(10%)+CHR$(13%)+CHR$(10%) \ RETURN ! ONE MESSAG IN STORAGE 15000 ! ! F U N C T I O N S 15005 ! FUNCTION TO GET MESSAGES 15010 DEF FNM%(W%) \ ON ERROR GOTO 15090 ! SET UP SPECIAL ERROR TRAP 15020 I$=SYS(A1$+CHR$(W%)+A2$) ! CALL FIP TO RECIEVE MESSAGE W%=1% IMEDIATE ERROR IF NO MESSAGE W%=2% SLEEP IF NO MESSAGE 15030 CHANGE I$ TO I% \ FNM%=I%(9%) ! IF MESSAGE RECIEVED PUT INFORMATION IN I%() I%(5%)=SENDERS JOB I%(8%)= " PROJECT # I%(7%)= " PROGRAMMER # I%(9%)=PROGRAM THAT SENT MESSAGE 15040 ON ERROR GOTO 19000 ! RESET ERROR TRAP 15050 FNEND ! EACH SUBROUTINE WILL PICK THE INFORMATION OUT OF I%() THAT IT NEEDS, WHICH SHOULD BE THERE. 15090 IF ERR<>5% THEN ON ERROR GOTO 0 ELSE IF W%=2% THEN RESUME 15020 ELSE FNM%=0%\ RESUME 15040 ! ERROR HANDLING FOR FNM%() 15100 !FUNCTION THAT WILL TEST TRUE IF THE SYSTEM NOTICE SHOULD BE SENT TO THIS USER L1%(0%)- POINTER TO SYSTEM NOTICE L1%(1%)- END OF PROJECT # LIST L1%(2%-63%)- PROJECT # 15110 DEF FNL1% \ T%=-1% \ GOTO 15120 IF I%(8%)=L1%(I%) FOR I%=2% TO L1%(1%) \ T%=0% ! T% IS FALSE IF THE PROJECT NUMBER DID NOT EXIST IN TABLE 15120 IF T% THEN I%=I%*16%+32% ELSE I%,L1%(1%)=L1%(1%)+1% \ L1%(I%)=I%(8%) \ I%=I%*16%+32% \ L1%(I%+J%)=-1% FOR J%=0% TO 15% ! CREATE RECORD IF PROJECT WAS NOT ON LIST 15130 T%=I%(7%)/16% \ T1%=I%(7%)-T%*16% \ I%=I%+T% \ T2%=L1%(I%) AND B%(T1%) \ IF T2% THEN L1%(I%)=L1%(I%) AND NOT B%(T1%) ! TEST PROGRAMMER'S BIT, IF TRUE SEND SYSTEM NOTICE 15140 M1%=L1%(0%) \ FNL1%=T2% ! M1% POINTER TO SYSTEM NOTICE 15150 FNEND 15200 ! FUNCTION THAT WILL TEST TRUE IF THERE IS A GROUP NOTICE WAITING FOR THIS USER. L1%(0%)- END OF PROJECT # LIST L2%(1%-55%)- PROJECT #'S L2%(56%-110%)- POINTERS TO NOTICES L2%(112%-127%)- BITS FOR PROGRAMMERS OF FIRST PROJECT 15210 DEF FNL2% \ GOTO 15230 IF I%(8%)=L2%(I%) FOR I%=1% TO L2%(0%) \ FNL2%=0% \ GOTO 15260 ! BRANCH IF NOTICE WAITING SET FNL2% AND RETURN IF NOT. 15230 M1%=L2%(I%+55%) ! ASSIGN NOTICE POINTER TO SEND POINTER NOW TO MINIMUMIZE DISK ACTION. 15240 T%=I%(7%)/16% \ T1%=I%(7%) AND 15% \ I%=I%*16%+96%+T% \ T2%=L2%(I%) AND B%(T1%) \ IF T2% THEN L2%(I%)=L2%(I%) AND NOT B%(T1%) ! TEST PROGRAMMER'S BIT, IF TRUE SEND MESSAGE 15250 FNL2%=T2% ! SET FNL2%, TRRUE IF NOTICE SHOULD BE SENT 15260 FNEND 15300 ! FUNCTION THAT WILL TEST TRUE IF THERE IS AN INDIVIDUAL NOTICE WAITING FOR THIS USER. L3%(0%)- END OF LIST L3%(2%)- FIRST PPN L3%(3%)- POINTER TO NOTICE L4%- INCORE ARRAY THAT HOLDS A LIST OF PPN'S THAT HAVE NOTICES 15310 DEF FNL3% \ T%=I%(8%)+SWAP%(I%(7%)) \ GOTO 15320 IF T%=L4%(I%) FOR I%=1% TO L4%(0%) \ FNL3%=0% \ GOTO 15340 ! NO NESSAGE WAITING SO RETURN. 15320 M1%=0% \ FNL3%=-1% \ L4%(I%)=L4%(L4%(0%)) \ L4%(0%)=L4%(0%)-1% ! ASSIGN SEND POINTER, RESET ARRAY 15340 FNEND 19000 ON ERROR GOTO 0 32760 RETURN UNLESS I%(8%)=1% \ I$=FNM9$('SHUTING DOWN AT '+TIME$(0%)) \ CLOSE 1%,2%,3% \ I$=SYS(CHR$(6%)+CHR$(8%)+CHR$(PEEK(518%)/2%)+ STRING$(24%,0%)+CHR$(255%)) ! KILL YOURSELF 32767 END