From 309936c2eb2a69b7e6d547a889fe578b29b0f2da Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Sun, 25 Feb 2018 18:40:37 +0100 Subject: [PATCH] Files from archives. --- arc/ar1:c/BARBER ORAL | 87 ++ arc/ar1:c/DBA RECOM | 59 ++ arc/ar1:c/DOYLE AREA | 77 ++ arc/ar1:c/GLS ORAL | Bin 0 -> 3115 bytes arc/ar1:c/HOARE CSP | 70 ++ arc/ar1:c/KAHN ORAL | Bin 0 -> 4225 bytes arc/ar1:c/KAPUR AREA | Bin 0 -> 2615 bytes arc/ar1:c/KEN EECS | 73 ++ arc/ar1:c/KEN IBM2 | 88 ++ arc/ar1:c/KEN RECMND | 114 +++ arc/ar1:c/KWLSKI CONTRO | 78 ++ arc/ar1:c/LING REC | 12 + arc/ar1:c/MCDONA ORAL | Bin 0 -> 4605 bytes arc/ar1:c/REED AREA | Bin 0 -> 2340 bytes arc/ar1:c/REED ORAL | 73 ++ arc/ar1:c/RICH AREA1 | 109 +++ arc/ar1:c/RUSS ORAL | Bin 0 -> 5450 bytes arc/ar1:c/STEIGE AREA | Bin 0 -> 3790 bytes arc/ar1:c/STEVEN ORAL | Bin 0 -> 3790 bytes arc/ar1:c/VALDIS AREA | Bin 0 -> 5370 bytes arc/ar1:c/WOODAM AREA | 169 ++++ arc/ar2:c/MMR 1 | Bin 0 -> 7415 bytes arc/ar2:c/MMR2 1 | Bin 0 -> 3125 bytes arc/ar2:c/PART6 1 | 298 +++++++ arc/ar2:c/SCHED 1 | Bin 0 -> 840 bytes arc/ar2:clib/AC C | 281 +++++++ arc/ar2:clib/ALLOC CMID | 225 +++++ arc/ar2:clib/APFNAM C | 26 + arc/ar2:clib/ATOI C | 17 + arc/ar2:clib/BLT CMID | 21 + arc/ar2:clib/C DEFS | 58 ++ arc/ar2:clib/C INFO | 139 ++++ arc/ar2:clib/C10BOO CMID | 56 ++ arc/ar2:clib/C10COR CMID | 54 ++ arc/ar2:clib/C10EXC C | 119 +++ arc/ar2:clib/C10EXP C | 51 ++ arc/ar2:clib/C10FD C | 231 ++++++ arc/ar2:clib/C10FIL C | 24 + arc/ar2:clib/C10FNM C | 118 +++ arc/ar2:clib/C10FO CMID | 96 +++ arc/ar2:clib/C10INT CMID | 407 +++++++++ arc/ar2:clib/C10IO C | 849 +++++++++++++++++++ arc/ar2:clib/C10JOB C | 720 ++++++++++++++++ arc/ar2:clib/C10JOB OLD | 713 ++++++++++++++++ arc/ar2:clib/C10MAP C | 58 ++ arc/ar2:clib/C10MIO CMID | 490 +++++++++++ arc/ar2:clib/C10PAG C | 111 +++ arc/ar2:clib/C10RUN CMID | 431 ++++++++++ arc/ar2:clib/C10SAV CMID | 44 + arc/ar2:clib/C10SFD C | 25 + arc/ar2:clib/C10SRY CMID | 64 ++ arc/ar2:clib/C10STD C | 136 +++ arc/ar2:clib/C10SYS CMID | 728 ++++++++++++++++ arc/ar2:clib/C10TAP CMID | 197 +++++ arc/ar2:clib/C10TMM CMID | 111 +++ arc/ar2:clib/C10TMR CMID | 150 ++++ arc/ar2:clib/C10TPR C | 152 ++++ arc/ar2:clib/C10TTY C | 376 +++++++++ arc/ar2:clib/CFLOAT CMID | 217 +++++ arc/ar2:clib/CLIB H | 15 + arc/ar2:clib/CLIB LIST | 208 +++++ arc/ar2:clib/CLIB PRGLST | 47 ++ arc/ar2:clib/CLIB STINKR | 8 + arc/ar2:clib/CLIB TESTER | 16 + arc/ar2:clib/CLIB TIMER | 18 + arc/ar2:clib/CODE INSERT | 35 + arc/ar2:clib/CPRINT C | 177 ++++ arc/ar2:clib/CRATE 10 | 39 + arc/ar2:clib/CRATE 9 | 40 + arc/ar2:clib/CTYPE C | 17 + arc/ar2:clib/CTYPE H | 16 + arc/ar2:clib/DATE C | 155 ++++ arc/ar2:clib/FPRINT C | 90 ++ arc/ar2:clib/GETSRV C | 79 ++ arc/ar2:clib/ITS BITS | 77 ++ arc/ar2:clib/MAKLIB C | 283 +++++++ arc/ar2:clib/MAKLIB STINKR | 7 + arc/ar2:clib/MATCH C | 94 +++ arc/ar2:clib/MKCLIB STINKR | 29 + arc/ar2:clib/NC INSERT | Bin 0 -> 780 bytes arc/ar2:clib/NM INSERT | 164 ++++ arc/ar2:clib/PR60TH C | 56 ++ arc/ar2:clib/RANDOM CMID | 31 + arc/ar2:clib/STDIO H | 17 + arc/ar2:clib/STKDMP C | 249 ++++++ arc/ar2:clib/STRING CMID | 132 +++ arc/ar2:clib/TESTFD C | 19 + arc/ar2:clib/TTIME C | 123 +++ arc/ar2:clib/UUOH CMID | 157 ++++ arc/ar5:c/AC C | 281 +++++++ arc/ar5:c/ALLOC CMID | 225 +++++ arc/ar5:c/APFNAM C | 26 + arc/ar5:c/ATOI C | 17 + arc/ar5:c/BLT CMID | 21 + arc/ar5:c/C DEFS | 57 ++ arc/ar5:c/C10BOO CMID | 56 ++ arc/ar5:c/C10COR CMID | 54 ++ arc/ar5:c/C10EXC C | 120 +++ arc/ar5:c/C10EXP C | 51 ++ arc/ar5:c/C10FD C | 231 ++++++ arc/ar5:c/C10FIL C | 24 + arc/ar5:c/C10FNM C | 118 +++ arc/ar5:c/C10FO CMID | 96 +++ arc/ar5:c/C10INT CMID | 407 +++++++++ arc/ar5:c/C10IO C | 849 +++++++++++++++++++ arc/ar5:c/C10JOB C | 713 ++++++++++++++++ arc/ar5:c/C10MAP C | 58 ++ arc/ar5:c/C10MIO CMID | 490 +++++++++++ arc/ar5:c/C10PAG C | 111 +++ arc/ar5:c/C10RUN CMID | 431 ++++++++++ arc/ar5:c/C10SAV CMID | 44 + arc/ar5:c/C10SFD C | 25 + arc/ar5:c/C10SRY CMID | 64 ++ arc/ar5:c/C10STD C | 136 +++ arc/ar5:c/C10SYS CMID | 728 ++++++++++++++++ arc/ar5:c/C10TAP CMID | 197 +++++ arc/ar5:c/C10TMM CMID | 111 +++ arc/ar5:c/C10TMR CMID | 150 ++++ arc/ar5:c/C10TPR C | 152 ++++ arc/ar5:c/C10TTY C | 376 +++++++++ arc/ar5:c/CDOC 90 | 1608 ++++++++++++++++++++++++++++++++++++ arc/ar5:c/CFLOAT CMID | 217 +++++ arc/ar5:c/CLIB PRGLST | 46 ++ arc/ar5:c/CODE INSERT | 35 + arc/ar5:c/CPRINT C | 177 ++++ arc/ar5:c/CRATE 10 | 39 + arc/ar5:c/CRATE 9 | 40 + arc/ar5:c/CTYPE C | 17 + arc/ar5:c/DATE C | 155 ++++ arc/ar5:c/FPRINT C | 90 ++ arc/ar5:c/GETSRV C | 79 ++ arc/ar5:c/ITS BITS | 77 ++ arc/ar5:c/MAKLIB C | 283 +++++++ arc/ar5:c/MAKLIB STINKR | 7 + arc/ar5:c/MATCH C | 94 +++ arc/ar5:c/MKCLIB STINKR | 29 + arc/ar5:c/NC INSERT | 62 ++ arc/ar5:c/NM INSERT | 164 ++++ arc/ar5:c/PR60TH C | 56 ++ arc/ar5:c/RANDOM CMID | 31 + arc/ar5:c/STDIO H | 17 + arc/ar5:c/STKDMP C | 249 ++++++ arc/ar5:c/STRING CMID | 132 +++ arc/ar5:c/TESTFD C | 19 + arc/ar5:c/TTIME C | 123 +++ arc/ar5:c/UUOH CMID | Bin 0 -> 3570 bytes arc/ar6:c/C5 C | 481 +++++++++++ arc/ar6:c/C93 C | 44 + arc/ar6:c/CC 1 | 773 +++++++++++++++++ arc/ar6:c/CC 3 | 781 +++++++++++++++++ arc/ar6:c/CC H | 341 ++++++++ arc/ar6:c/CC11 3 | 781 +++++++++++++++++ arc/ar6:c/CNOP H | 66 ++ 153 files changed, 24732 insertions(+) create mode 100644 arc/ar1:c/BARBER ORAL create mode 100644 arc/ar1:c/DBA RECOM create mode 100644 arc/ar1:c/DOYLE AREA create mode 100644 arc/ar1:c/GLS ORAL create mode 100644 arc/ar1:c/HOARE CSP create mode 100644 arc/ar1:c/KAHN ORAL create mode 100644 arc/ar1:c/KAPUR AREA create mode 100644 arc/ar1:c/KEN EECS create mode 100644 arc/ar1:c/KEN IBM2 create mode 100644 arc/ar1:c/KEN RECMND create mode 100644 arc/ar1:c/KWLSKI CONTRO create mode 100644 arc/ar1:c/LING REC create mode 100644 arc/ar1:c/MCDONA ORAL create mode 100644 arc/ar1:c/REED AREA create mode 100644 arc/ar1:c/REED ORAL create mode 100644 arc/ar1:c/RICH AREA1 create mode 100644 arc/ar1:c/RUSS ORAL create mode 100644 arc/ar1:c/STEIGE AREA create mode 100644 arc/ar1:c/STEVEN ORAL create mode 100644 arc/ar1:c/VALDIS AREA create mode 100644 arc/ar1:c/WOODAM AREA create mode 100644 arc/ar2:c/MMR 1 create mode 100644 arc/ar2:c/MMR2 1 create mode 100644 arc/ar2:c/PART6 1 create mode 100644 arc/ar2:c/SCHED 1 create mode 100644 arc/ar2:clib/AC C create mode 100644 arc/ar2:clib/ALLOC CMID create mode 100644 arc/ar2:clib/APFNAM C create mode 100644 arc/ar2:clib/ATOI C create mode 100644 arc/ar2:clib/BLT CMID create mode 100644 arc/ar2:clib/C DEFS create mode 100644 arc/ar2:clib/C INFO create mode 100644 arc/ar2:clib/C10BOO CMID create mode 100644 arc/ar2:clib/C10COR CMID create mode 100644 arc/ar2:clib/C10EXC C create mode 100644 arc/ar2:clib/C10EXP C create mode 100644 arc/ar2:clib/C10FD C create mode 100644 arc/ar2:clib/C10FIL C create mode 100644 arc/ar2:clib/C10FNM C create mode 100644 arc/ar2:clib/C10FO CMID create mode 100644 arc/ar2:clib/C10INT CMID create mode 100644 arc/ar2:clib/C10IO C create mode 100644 arc/ar2:clib/C10JOB C create mode 100644 arc/ar2:clib/C10JOB OLD create mode 100644 arc/ar2:clib/C10MAP C create mode 100644 arc/ar2:clib/C10MIO CMID create mode 100644 arc/ar2:clib/C10PAG C create mode 100644 arc/ar2:clib/C10RUN CMID create mode 100644 arc/ar2:clib/C10SAV CMID create mode 100644 arc/ar2:clib/C10SFD C create mode 100644 arc/ar2:clib/C10SRY CMID create mode 100644 arc/ar2:clib/C10STD C create mode 100644 arc/ar2:clib/C10SYS CMID create mode 100644 arc/ar2:clib/C10TAP CMID create mode 100644 arc/ar2:clib/C10TMM CMID create mode 100644 arc/ar2:clib/C10TMR CMID create mode 100644 arc/ar2:clib/C10TPR C create mode 100644 arc/ar2:clib/C10TTY C create mode 100644 arc/ar2:clib/CFLOAT CMID create mode 100644 arc/ar2:clib/CLIB H create mode 100644 arc/ar2:clib/CLIB LIST create mode 100644 arc/ar2:clib/CLIB PRGLST create mode 100644 arc/ar2:clib/CLIB STINKR create mode 100644 arc/ar2:clib/CLIB TESTER create mode 100644 arc/ar2:clib/CLIB TIMER create mode 100644 arc/ar2:clib/CODE INSERT create mode 100644 arc/ar2:clib/CPRINT C create mode 100644 arc/ar2:clib/CRATE 10 create mode 100644 arc/ar2:clib/CRATE 9 create mode 100644 arc/ar2:clib/CTYPE C create mode 100644 arc/ar2:clib/CTYPE H create mode 100644 arc/ar2:clib/DATE C create mode 100644 arc/ar2:clib/FPRINT C create mode 100644 arc/ar2:clib/GETSRV C create mode 100644 arc/ar2:clib/ITS BITS create mode 100644 arc/ar2:clib/MAKLIB C create mode 100644 arc/ar2:clib/MAKLIB STINKR create mode 100644 arc/ar2:clib/MATCH C create mode 100644 arc/ar2:clib/MKCLIB STINKR create mode 100644 arc/ar2:clib/NC INSERT create mode 100644 arc/ar2:clib/NM INSERT create mode 100644 arc/ar2:clib/PR60TH C create mode 100644 arc/ar2:clib/RANDOM CMID create mode 100644 arc/ar2:clib/STDIO H create mode 100644 arc/ar2:clib/STKDMP C create mode 100644 arc/ar2:clib/STRING CMID create mode 100644 arc/ar2:clib/TESTFD C create mode 100644 arc/ar2:clib/TTIME C create mode 100644 arc/ar2:clib/UUOH CMID create mode 100644 arc/ar5:c/AC C create mode 100644 arc/ar5:c/ALLOC CMID create mode 100644 arc/ar5:c/APFNAM C create mode 100644 arc/ar5:c/ATOI C create mode 100644 arc/ar5:c/BLT CMID create mode 100644 arc/ar5:c/C DEFS create mode 100644 arc/ar5:c/C10BOO CMID create mode 100644 arc/ar5:c/C10COR CMID create mode 100644 arc/ar5:c/C10EXC C create mode 100644 arc/ar5:c/C10EXP C create mode 100644 arc/ar5:c/C10FD C create mode 100644 arc/ar5:c/C10FIL C create mode 100644 arc/ar5:c/C10FNM C create mode 100644 arc/ar5:c/C10FO CMID create mode 100644 arc/ar5:c/C10INT CMID create mode 100644 arc/ar5:c/C10IO C create mode 100644 arc/ar5:c/C10JOB C create mode 100644 arc/ar5:c/C10MAP C create mode 100644 arc/ar5:c/C10MIO CMID create mode 100644 arc/ar5:c/C10PAG C create mode 100644 arc/ar5:c/C10RUN CMID create mode 100644 arc/ar5:c/C10SAV CMID create mode 100644 arc/ar5:c/C10SFD C create mode 100644 arc/ar5:c/C10SRY CMID create mode 100644 arc/ar5:c/C10STD C create mode 100644 arc/ar5:c/C10SYS CMID create mode 100644 arc/ar5:c/C10TAP CMID create mode 100644 arc/ar5:c/C10TMM CMID create mode 100644 arc/ar5:c/C10TMR CMID create mode 100644 arc/ar5:c/C10TPR C create mode 100644 arc/ar5:c/C10TTY C create mode 100644 arc/ar5:c/CDOC 90 create mode 100644 arc/ar5:c/CFLOAT CMID create mode 100644 arc/ar5:c/CLIB PRGLST create mode 100644 arc/ar5:c/CODE INSERT create mode 100644 arc/ar5:c/CPRINT C create mode 100644 arc/ar5:c/CRATE 10 create mode 100644 arc/ar5:c/CRATE 9 create mode 100644 arc/ar5:c/CTYPE C create mode 100644 arc/ar5:c/DATE C create mode 100644 arc/ar5:c/FPRINT C create mode 100644 arc/ar5:c/GETSRV C create mode 100644 arc/ar5:c/ITS BITS create mode 100644 arc/ar5:c/MAKLIB C create mode 100644 arc/ar5:c/MAKLIB STINKR create mode 100644 arc/ar5:c/MATCH C create mode 100644 arc/ar5:c/MKCLIB STINKR create mode 100644 arc/ar5:c/NC INSERT create mode 100644 arc/ar5:c/NM INSERT create mode 100644 arc/ar5:c/PR60TH C create mode 100644 arc/ar5:c/RANDOM CMID create mode 100644 arc/ar5:c/STDIO H create mode 100644 arc/ar5:c/STKDMP C create mode 100644 arc/ar5:c/STRING CMID create mode 100644 arc/ar5:c/TESTFD C create mode 100644 arc/ar5:c/TTIME C create mode 100644 arc/ar5:c/UUOH CMID create mode 100644 arc/ar6:c/C5 C create mode 100644 arc/ar6:c/C93 C create mode 100644 arc/ar6:c/CC 1 create mode 100644 arc/ar6:c/CC 3 create mode 100644 arc/ar6:c/CC H create mode 100644 arc/ar6:c/CC11 3 create mode 100644 arc/ar6:c/CNOP H diff --git a/arc/ar1:c/BARBER ORAL b/arc/ar1:c/BARBER ORAL new file mode 100644 index 00000000..b2196e9b --- /dev/null +++ b/arc/ar1:c/BARBER ORAL @@ -0,0 +1,87 @@ +.device xgp; font 1 "carl;30vrs"; font 2 "carl;25vgbs"; font 3 "carl;30vrbs"; font 4 "fonts;25vri"; font 5 "carl;37vrbs"; font 6 "carl;s30grk"; +.require "CARL;PUBMAC >" sourcefile + +.!xgpcommands_";squish" + +.area text lines 3 to 45 +.page frame 45 high 85 wide +.title area heading line 1 to 2 +.tabspace +.every heading (5DRAFT*,{page},5DRAFT*) + +.tabspace + +.place text +.next page +.fill + + +.begin center +.turn on "{" +.comment "}"; +{date} +.end + +.skip 4 + +.begin nofill +TO: Area II Committee +FROM: Carl Hewitt +SUBJECT: Oral Examination for Mr. Gerald Barber +.end + +.begin para + The oral examination for Mr. Barber was held on November 23, 1977. +The committee members were Professors Gallager, Winston, and Hewitt +[Chairperson]. +On the basis of demonstrated research potential +and performance on the oral examination, the committee recommends that Mr. Barber +be deemed to have passed his +oral examination. +.end + +.begin para + The examination began with Mr. Barber presenting his masters thesis +which was done at the University of Idaho. +The topic of the research was a program to do optical character recognition. +The committee feels that Mr. Barber explained his research quite clearly. +.end + +.begin para + Mr. Barber described some research which he is currently doing +with Professor Hewitt on the development of formal techniques for the +description of office procedures in which he has made several important contributions. +Professor Hewitt is quite pleased with his progress and a doctoral thesis proposal +should be forthcoming before the end of the academic year. +.end + +.begin para + Professor Gallager asked Mr. Barber to consider the problem of synchronizing +the action of two modules which can only communicate via a noisy channel which +can drop messages. If the two modules have no prior agreement as to the time at which +they will act and neither can act alone without being certain that the other will +act at the same time then the problem is impossible to solve. +After some guidance Mr. Barber was able to give an informal proof of this +result. +Professor Hewitt asked Mr. Barber to write a recursive LISP procedure to +reverse a list at all levels. Mr. Barber was able to do this with only one minor +false start. +Professor Winston asked him how he would program a depth first tree search. +After this he was asked how he would program a breadth first tree search and +then how he would program a best first search. With some guidance Mr. Barber +realized that all of the programs are variants of one basic schema. +.end +.begin para + The committee feels that Mr. Barber should speak more forcefully and +be more dynamic and definitive in his presentations and answers to questions. Mr. Barber +seemed quite nervous at the examination which could account for some +of this difficulty. The committee feels that some teaching experience could help him overcome +some of these problems. +.end +.begin para + Mr. Barber ranked 50 out of 110 on the Preliminary Written Examination. +He did rather poorly in the topic of +discrete mathematics. The committee recommends that he work to remedy this +deficiency. +.end + \ No newline at end of file diff --git a/arc/ar1:c/DBA RECOM b/arc/ar1:c/DBA RECOM new file mode 100644 index 00000000..14ba5dc6 --- /dev/null +++ b/arc/ar1:c/DBA RECOM @@ -0,0 +1,59 @@ +.ss +.sp 4 +.center +January 7, 1974 +.sp 4 +Ms. Sylvia A. Bressey +.br +Senior Administrative Assistant +.br +School of Mathematical Studies +.br +University of Essex +.br +Wivenhoe Park +.br +Colchester CO 3SQ +.br +England +.sp +Dear Ms. Bressey: +.sp +I consider Bruce Anderson to be eminently qualified for the +post of Lecturer in the Computing Center. +Bruce has a sharp mind, knows the literature of the field, +and expresses himself well. +From my visit to Essex last summer and from your description +of the post, I believe that Bruce would fit in well +with the research and teaching interests of the Computer +Science division. +.sp +I have known Bruce for over two years. +We first met at IJCAI-71 in London. +I got to know him better when I visited Edinburgh +after the conference. +Since that time our paths have crossed regularly +and we have had extensive discussions on developments in the field. +Bruce is one of the people +whose comments and criticisms I value most highly. +.sp +In summary I consider Bruce Anderson to be extremely +well qualified for the post of Lecturer in the Computing Center +and recommend that you appoint him. +.sp +.center +Sincerely, +.sp 4 +.center +Professor Carl Hewitt +.center +M.I.T. +.center +Room 813 +.center +545 Technology Square +.center +Cambridge, Mass. 02139 + +.end +   \ No newline at end of file diff --git a/arc/ar1:c/DOYLE AREA b/arc/ar1:c/DOYLE AREA new file mode 100644 index 00000000..8b604ee5 --- /dev/null +++ b/arc/ar1:c/DOYLE AREA @@ -0,0 +1,77 @@ +.device xgp; font 1 "carl;30vrs"; font 2 "carl;25vgbs"; font 3 "carl;30vrbs"; font 4 "fonts;25vri"; font 5 "carl;37vrbs"; font 6 "carl;s30grk"; + +.require "CARL;PUBMAC >" sourcefile + +.!xgpcommands_";squish" + +.area text lines 3 to 45 +.page frame 45 high 85 wide +.title area heading line 1 to 2 +.tabspace +.every heading (5DRAFT*,{page},5DRAFT*) + +.tabspace + +.place text +.next page +.fill + + +.begin center +.turn on "{" +.comment "}"; +{date} +.end + +.skip 4 + +.begin nofill +TO: Area II Committee +FROM: Carl Hewitt +SUBJECT: Area Examination for Jon Doyle +.end + +.begin para + The area examination for Jon Doyle was held on November 30, 1977. +The committee members were Professors Goldstein, Martin, and Hewitt [Chairperson]. +The committee examined Mr Doyle in the general area of representation of knowledge. +On the basis of good oral presentation and originality in his critique of +the papers, +the committee recommends that Mr. Doyle be deemed to have passed his +area examination. +.end + + +.begin para + The papers assigned for the exam within the topic of "Languages for Knowledge +Representation" +were: +.skip +.begin narrow 12,0 +.begin para +"Experience with KRL-0, One Cycle of a Knowledge Representation Language" by +Daniel G. Bobrow, Terry Winograd, and the KRL research group. Xerox Palo Alto +Research Center Technical Report. +.end +.begin para +"An Overview of Owl, A Language for Knowledge Representation" +by Pter Szolovits, Lowell B. Hawkinson, and William A Martin. +LCS Technical Memorandum 86. June 1977. +.end +.begin para +"Nudge, A Knowledge-Based Scheduling Program" by Ira P. Goldstein and R. Bruce Roberts. +AI Memo 405. February 1977. +.end + +.end +.skip +Comparing the approaches used in the above represented a +challenging task. +Mr. Doyle demonstrated a good grasp of the of the strengths and +limitations of the various representation languages. +In fact his paper was considered sufficiently perceptive that +Professor Szolovits used it in his knowledge based engineering course. +.end + + + \ No newline at end of file diff --git a/arc/ar1:c/GLS ORAL b/arc/ar1:c/GLS ORAL new file mode 100644 index 0000000000000000000000000000000000000000..c696516d3a575dac259b6578a513f82f175c47c7 GIT binary patch literal 3115 zcmWO8hj$|eVSsTBYY*ERw)XJQwuZI0HLPh_lC`HbEy-H8ELpOakI+K<0+%+A&=A7q z(sV$MJ7@_PE;R72kV~Kq%|W?9XlRlPN!uisD<$N3$#Kme@%`TC4P~e|Wh)7_B^p5P z^IbNUMJlR|?X#YM)2EBZu0>K3QMc*1 z9mI^1DD@WeWSvl}J6N6x464yx6I#1^pfKk<9g}7IP^8y6e>5z}4qh%p!1BA{J_Yd` z*3i~8P=3p_&&aq)V`B|@63NhVFYVmNF=@D^WC(#xT#KV6?;aS2l|#i z6Utp`6lafAIZ_yX8$DvXKneuX@K)V%EW0V5W$Y5hob{QPu(4ryW8R+EPbbD2(IDZ6 zn8|3nqVo}wk?aRNd{8Ml-s_~IxpCG1a|0d923rh0@eh5dT;zMgl#2f`ywzNd<)EXg zy_?X-K6BKf#s4j~ZVUf3z*82P)$FVSB5V6O_tV3j*{fSfTca@FA|BnV?<+~o+0w%N z+oq(Ne>x9CmELNt!_aSt*HXAMg(XSpwFU4YH0>P32(8mmDh$ZdQ{a1>3CpPtii($S zsT54x2iXITyzUL}_WyQ1Pmw-FBD;j=LK9iz!*XW?dz@hj5?@N1DGN*K*}@UMDV(ML z3%d*EXXnh;O1HqI>27S12DEQ2L>9HrcunE((EY$b3S^y>8S2)9*phc4 zWXELS+mh@YY{tF0E&SN)R_%)cO91X~=Bn#MOAy0}3g)&NYhT1}jZjanVyM8BH)%wE zWgQ6JT7jtc6<7Ibz>#Wr?BBRkDTG$>cBTyXs)}2YUnTHd5|Of+cUy_G;x^qP@992} ztnnAl72w>%KtrH3jOY_q`qF+<$a*_1_L$D^)*~n6umeQ7y%4U{UbI(fhdtBE=I(uT z^?-=6mHVvPc<;nRFpQkUce_SZ%9>3VqVpzf#DBL!i)NH69b)4nj;4_6Dv~=3e~HG; zGB^6ohTJ7j)Hl6yn>_R`tf$#~K~9CE#0aLJdkhcI@@p6=H2WdD)(`fKwjSk`V_t3F z7O7j8{(b#Kpt$8(^tG#{eF6UqD4B0s5EHg3V4=Og|6+Q_uq%qqN2%X4te0)mn!7qx z+L$Zahoy!wH6)_cJ!eadeQ#PvZw=1zrkGY>j{%$eIOx&8veY@65zTh$I|h2 z70DFTnrvO&vn|j(;YQwB5`T#)3UZ#_#H5q)5mgsSX%b4lOo!hv&aM<1+dG?WI@7#% z5=?$z&4I92inAKyLt^hKaZgJCbIO3C3G6~n(CJSH@N84On_~d(smZSF-w2C^NrGnb zd7xP@D02sGXOk|A{mqKYxa%e9o&IV$>~1QzT-&A`@Y;5P75}N~nBoLO<;vivy(^W{ z9WpIOxi)7va(~~7h*)usL2Y`I$SlLDdIAaUpBWK0sx!9E3B_Bo9KY@-q{Ba;tZfc) zUOsMcVbtIXrtBgwBw6J}>1Wd&O#XKkLW}NV&8UpeVJaruY%k>vzwU~ktbQj$MF@C% z2MpCYzX~{dLgN>V1O#bo`COGvZL}TyVUE9oo;q*ftc7xUB^_fcLca72EmAPv0VV>0wvcC+-$zKQJ3ma7GoGg=usLvEV}k_xsFF64vam+6}{TU>H%234UqpR0RV}v&0|yAy@Sp?|nL&96!t4$So&54cgLmnIfZEV{G#6gc6qe1E#MactBp1mOQoLW|;!1AbOw zDx#CZAVO`g--sW|NKfc1UjJ}Lc-^;dks%1H+P z3Fz0CH8sPvj?F6hby^*^Qz!9-(3zDC16{;bSG+g3gJt%|Xhn8H=k!X|&&g07=y?+_ zgLP`#xj9pGhCJt`Y#1r}o$5ptN|w>^*N&ySQD!YUj6c3;wzB>zgs0Waz}W1DCoW%9 z{1cT$3}0cas1=t_-5P6Cwx^q}_HZt%YF;sbKHdRyHP7yZY7JgfpCf*=Z4ui)bui$J zuF4^N&SN?0e&h0-%4OWQ;5D4Y!D1n0@hOOvuZ@@OK3OE6U<>spd4&tn0w0Fv8Wf3I zMG>dqmf}IZsMK$EE|k*&&y#3S0CVOLx2?8Qs*03gW-SKv0y=smF$Cgmsi`D7;Vdz8 z7`hvGV{7*WrZw`Hml}rFgK1tX{jdfmX%7l4s_T!mZmxc5NWx8?&yb|CKLUIc(Tjl~ z0RD4}!{(@%OY(uU%8iZR!0$V)Kie;?YROW2gmzQ5h27KDlRKRU+bnaxKF0^Owl>@q z!;?*EruYbQpQ=Wz#CiE&tUS9U=89E)g13ARHZejgY z+am?RwEJy-!`BQBFpQZqC~|tBJ0`kC&mG8i%kOi#Y3N}hVKY3Q{iL_slf>NWC4+^3 z`cSZUwDOA$uSDvxu?`L{rY8JT09+l@{9$Z2Ybh(?ZO2P=entAe}prUi`H zvu~^gX3&3EWyk9uomgk)isra5ttN&@(C>qy-g?QKFLl1rX6@|!HKU_J%HTk|{>t`B z4-*NL3EB(md$FT%*d7qSkwMPn{%a!Oqq=wkgza#sVUt%3JUd3bJ?C3`TNCw>17@i_ zxT@caY(0;e8@rpBw9a>&+l%l?LlHQ0O}`_vug1AM{x4_16GPL6?-lNMvFy;B#T2ab zj@V&d)I(tGMcT=-lkkWxfz)OXqjJ#IeaV{W4rdlgj3CRaxig#`BM1=2!01uptWseWzTxP z9jV|gOL$!0JDLg(ucMSIpg%N*)MebwQ~D^r1=@cWdn+rGjai@BDg zeyAf7F!&v4xNTNEE00d*k!HkLQCkP>O55nfECbCb1%;1d{dLb{8adiTs+j}U--?t| z(EW80taf><)94R6Ld@ca!?ZAI$5KJn){>=1{u-H#pzA#8Nr$)J`D86bN}I4fXMI?sbG+z@`a`GX@R=~K^~4&Mya{(zBtfV+JEm- zh7dP4wK3THFi9`+6P183yjbnvJs(1Qn#7;P%M)I$nV&WlY5+t2Kcay+eui1m#Gf;= za+p?B7Mb&`Yd@J9Sa*{7JU}l>eXa|qfp38p5+s{&3^qm<%&VziNMk8tQVjqh9$D9f zn-7XY^U=Epr;*w%;fQ~9C+lN&9t{S&LoS>MVSO{BUXMPTAlZ4I%5nts2UTIigwl4p z#WG~jI*Plpt}?UBLi*GRnMkFVsc`-{XCVgfb5bzmS6h-($kRDG5Y6+f6K(%j?<@@8 mMDdq7u3>SlepX_~X!(i,c);console(i)!ack()] + +which inputs characters from consoles and sends back acknowledgements. +As the program stands there is nothing to prevent all of the characters +from being input from console(1). + Implementing recursive subroutines as arrays of "processes" +seems like a total KLUDGE. +The excuse given is that this method is "necessitated by the 'static' +design of the language". However, it is presumably going to be necessary +to dynamically allocate an new array for each "new" invocation +of a recursive procedure in order to implement mutually recursive routines. +This same problem shows up in recursive data representation. +It becomes even worse in section 5 on monitors and scheduling where the claim +is made using arrays of processes and guards of the appropriate kind can be used +to implement monitors. I am doubtful that monitors can be implemented +quite so easily using the constructs provided. In particular I would like +to see the implementations of the readers-writers problem for the cases +involving giving readers priority and giving writers priority. +Also I would also be interested in seeing an implementation of a disk-head scheduler. +The problem is compounded by the fact that it seems difficult to implement +fair (starvation-free) scheduling using the primitives provided. +For example the integer semaphore implementation in section 5.2 does not +guard against starvation. The problem continues to plague the paper in +the next section where it spoils some of the beauty of the sieve of +Eratosthenes where it is not immediately evident that 100 sieve processes +are sufficient to produce all primes less than 100000 (although it is +obvious that it will produce all primes less than 10000). +The iterative array example is very pretty. + I believe that the way in which arrays of processes +are treated is one of the worst defects of the paper and should be corrected +before the paper is published in the CACM. +Also some of the decisions about the language need to be better motivated. +For example the decision that an output command must wait until +some other process has input the value output seems arbitrary. +Perhaps a short section describing the hardware model that seems +to underly many of the decisions: each "process" is a hardware module +connected by physical wires to the other hardware modules with which it +communicates. + The term "process" as used in the paper differs from the meaning +which the author has previously attached to the term in his paper +on "monitors". Some comment as to this difference in terminology should +be inserted to warn readers. + In summary I believe that the paper will make an important contribution +to the state of the art when these defects are overcome. The major thrust of the +paper is in the right direction. + + Sincerely, + + Carl Hewitt + \ No newline at end of file diff --git a/arc/ar1:c/KAHN ORAL b/arc/ar1:c/KAHN ORAL new file mode 100644 index 0000000000000000000000000000000000000000..e0b7adf64397b3849fca4ec513b7aa6335fccf19 GIT binary patch literal 4225 zcmZvfZI2tb6@?4rizHb8f$*0)z}BsuI6+>JV&Ru~;ilQd3-m)#2-FNmV#OJb$(fav zU*G3m&S>Q(Ufa7nA}=q`J@=eD-yO0W%<~t`?#krnFLvp$UVWDjzBkYKVH=0mCO-Zf zzYMW|_$4$CpFCQx)~i>G&995i^Q>*TDtxiK$e+xlT}PFG*w zz5aIjlRcSdSLWF_U%!xtzw+qkWP|x-w81wg-|funkGA!l9enIe6O;KVJvHxK*STSD z-r0Ru&RMUP*PV&7*IjIgOjq;(8#CWJvyWpkwa?X#dx+K*_eoG}K z+vTH6lF^6JQ3@)uUMVIq+{k zfGWq}Yx4BL4=3YGv`ZSvsU!?LTvrP^1lmL640aG|>rB7c*u^I6U$@xQi;b3#Pd+R* zqkb3`8^72z`v1H{k`lPVWN(cfO*D=(KhWRu<43XJC~PQpGS3d$*VR<*}-qtHBZE zfb!GYOwnBp10vjNuMEAiH(cgq8h7MTCv7AIqX-Z{nnr#B@FAQGyQH{%WS!XxlL}X~ zLu;3mV+!DoB|B5cV+R#HC9@&86D-#LAjVOvRXeUp7&@MGvI}sT#T?RcbdqELfIluw zb>Gp+PJuaMIl>PYYpcvl(xH_70jr%XqbC1MdPRoCE_qan}5>( z&_sw}C#Do2^T7QJ7<5um;y-8e_$+L-Yw6V?otH^*_o%N#p1TZ$L|s6{H4Tt^#N|}( zRQsm!)kw#}grYFHDs-J%o(tWG+Ead@Uaz1AM5qQBIJgk}4n7l2k+o+$v|z*4**zpB z-&J7*hV=@%557mQlAAbdMRElGsXaLZ$<7@9CWa7?!Zw>qE!ikb*Q*1>(@nlp=+w6g zaC41oN0gEr9dlXRrSfAba($zIwT-EpUFz(U%jI(x{7d*+R()ZP&K)>4)K@&(<1|7b zs;BmXd@R3U$F=rbS!#DtmhNabOVe_TVV|NMP@CoQOF4hg1cZg=OQ1F{rbB|TUzfdL z8MYST?{52oHqWRm?C)?3ll0%aRs?wGmxtG;M z3^!o20yYCnfrIt4UABms?R>@{IC0Ey9nuN-1$%UBuYFKVL^NQ}ZR9bOIqz+}&`SPJ zbP6`@0EJ7d-ayI!!e4`GVtMfS@g2wA7Ev`fA#~EL?@xJf?bFBR%)Z>m13;91>m%Mf z`45kT(MVB`52!AmJ>sI%p*kYtQjQ%r8WIDWNKQv;xf~{P^A-iq2q88x3#QQ4ePocR zk8 z2W8l#6x?2or5EfddrQF80 zaV*nN1JzA}Lkw~jKcwU>GMG+ee%46TVH%9I@U)6nSDGT@c}E#5(wGO?^u{M5l3XRp zjs3(vY-_9z4D7ObayG7dU&u}Qh8W>0n(9R|iy`!)jcN&W0j)dtiLT>Fb+mvl*wbg`sXid z_^niMZqMfv`~^z}ucX#smY}F5bY^IgzD5wk5gUx0cBy!RvgDb0Yyn_yH;#iaxO(tP`e{7;T5?dxsrt- z|GjUxs}ILbFA{f_oSFCL&2W>9mpWy7n3rcXvnJ3XbyDSuv!jEh^PR@nYmB}Aaz5Q! zkM_3itjE+5NB#_(o!)rpZ}y%n-EQy8#_Ep_=I*|8)^4?1iQ`X|c1)e&;P&e5=I+gC zFr?o*(y3i6l*#-*oimS9KJUa=%CVxr4}l78*wYaOOUHdUFV&oB z=G21mOu3%t^r}xQoxx`kbSRkO;ha^b%{-n5Cpg}d4QlF3mC9aTvRl(;+b_@hZ*K?h zC(nNCewGklx?97qF{9l{Nuq#{m>(XDq$y{x2DU=BV>#uyHk7gn?C=;WXUH1rdDYCuW5B@P5}Op_M8n6mSTYC+hU1Y3$G@DFD}Ls)j!ZruQ8 zQE(ylIh5rQ;=1-QRbI;`np+EG;;eM+QM#H!NzyuvN~=PLwFJ&_Aay$EPZdY^l1Zr~ z`)<1>4?8Lx*FwlV@>Kx{8URzKjClc25N@uPOh1&$dpyH^yA>6_R}Cb*DIHc%idRP` zIM8zgA5wTpL_DB%Lf-HdY^hU0+j+`VyCnpE%@njOWqggOqSkG2qnxuVI_z~1wzgVL zosl&L(ty?J$uW#&nNa`u^hLjavL)paAzNshJYu9vn;SZpP%Gs!_>o|ASs9K^`3+Zt z2W=O~J{9GFo(ZS9k-Gax@l&=0)VT7>&^V#%l}_(9T)ze0L}*7VmlehZjZ@8_LGrN9 za8b~m(U?~r8iR3iODFvoz5XHAGCN|U^}mtiBtjB_v5@P7tJ2v12>6kmo@q73&>Y)Y z0Cp^59lX$jiBh1OV<#%~EGD%<$nnJ=H&=rXC;*_dZ))-?i52N#!$`R_r(W+x?|3@{ zYJE1pwN?bKa#DNAO_imyD$PM&B|>jBsiqd{ciglcUSK4pxiqXn+u^M8_kg}@{)`t9 zrV6sT?p(CBFNI=>)ck=7xCpryfbCYHF`r^r$A*`UOJrv&yx*qw-yA=`5RyDPLE2T3 zC?Hadazh#QfWs=zwOyiHNN8vio3TV8R=EawUxC2ZrKEy;qB6enC8vUJmvd~-TD?De zjM$K4UP+&W)Hw6-zngiON6pBCc{B3vOa=g(+`VXZmwbJlbWz*wkd=WSr31`!s1v|b zn`0UnTs!=LJF>ZF8oo0k8i=;CdIoz8oS+_#oJy z^$@7k>QOcKh^a?>sX~s!!nnuP2h9@ZQoQXRO^0~b?G08SGHFp|h$wS%4?Pfz`V>u_ z<{A05v1NT%v|Dlo2;Ww8jO4^#&(^xQ;*_27sPd8v3|(> +.beta _ "9b*" << lower-case greek beta >> +.gamma _ "9g*" << lower-case greek gamma >> +.delta _ "9d*" << lower-case greek delta >> +.lambda _ "6F*" << lower-case greek lambda >> +.bottom _ "6T*" << upside down capital T >> +.natural _ "3N*" +.turnstile _ "6p*" +.inclusive _ "6I*" << inclusive subset symbol >> +.union _ "6U*" << big set union symbol >> +.phi _ "9F*" + +.require "CARL;BMAC >" sourcefile + +.area text lines 4 to 42 +.page frame 44 high 85 wide +.title area heading line 1 to 2 +.title area footing line 44 + +.every heading(,,5{page}1) +.turn on "{" +.comment "}"; + +.tabspace + +.place text +.fill +\\\\{date} +.skip 3 +.begin nofill +Professor Horace Smith +Secretary of the Committee on Graduate Admissions +Graduate Office, Department of EECS 38-444 +.end +.skip +Dear Professor Smith: +.begin para + I would like to nominate Kenneth Kahn for a Junior Fellowship at the University +of Michigan. As Ken's thesis supervisor, I find that his research is very original and +creative. He has an excellent record and has published several papers in the fields +of Artificial Intelligence and Computer Graphics. +.end +.begin para + During his graduate study at MIT, he has worked with different research groups. First +he worked with the Clinical Decision Making Group and did his Master Thesis with them on the +mechanization of temporal knowledge. He then moved on the the Logo Group of the Artificial +Intelligence Laboratory where he taught elementary school children computer animation and +language processing. He developed a computer language for that purpose which he has continued +to improve. For the last two years he has been honored by holding an IBM graduate fellowship. +During this period he has been working on his doctoral thesis which is exploration of the +processes of creation as exemplified by a computer system that he created that is capable of +making animated films in response to a high level script. He is expected to finish his +thesis by August 1978. +.end +.skip 1 +.begin nofill +\\\\Sincerely, +.skip 3 +\\\\Carl Hewitt +\\\\Associate Professor of EECS +.end diff --git a/arc/ar1:c/KEN IBM2 b/arc/ar1:c/KEN IBM2 new file mode 100644 index 00000000..ccc7f21c --- /dev/null +++ b/arc/ar1:c/KEN IBM2 @@ -0,0 +1,88 @@ +.!xgpcommands_";squish;botmar 150" + +.comment "title page for working paper in ai:baker phead >"; +.device xgp; +.if xcribl then font 1 "carl;30vrs" +.if xcribl then font 2 "carl;25vgbs" +.if xcribl then font 3 "carl;30vrbs" +.if xcribl then font 4 "fonts;25vri" +.if xcribl then font 5 "carl;37vrbs" +.if xcribl then font 6 "fonts;plunk" +.if xcribl then font 7 "carl;25evnt" +.if xcribl then font 8 "fonts;30fg" +.if xcribl then font 9 "fonts;s30grk" +.alpha _ "9a*" << lower-case greek alpha >> +.beta _ "9b*" << lower-case greek beta >> +.gamma _ "9g*" << lower-case greek gamma >> +.delta _ "9d*" << lower-case greek delta >> +.lambda _ "6F*" << lower-case greek lambda >> +.bottom _ "6T*" << upside down capital T >> +.natural _ "3N*" +.turnstile _ "6p*" +.inclusive _ "6I*" << inclusive subset symbol >> +.union _ "6U*" << big set union symbol >> +.phi _ "9F*" +.require "carl;cmac >" sourcefile +.page frame 48 high 85 wide +.area text lines 3 to 45 +.title area heading line 1 to 2 +.title area footing line 47 to 48 +.place text +.at null  +.begin para; nofill +Professor Albert Meyer +Chairman +Area II Committee +.skip +Dear Sir: +.end + +.begin para + This letter is in support of the renewal of the IBM fellowship +for Kenneth Kahn. It is intended to supplement the letter which I wrote +last year when Ken was first proposed for the fellowship. +.end +.begin para + In the last year Ken has vigorously pursued his thesis research. +In the course of this research +he has developed a new approach to knowledge-based animation and a scenario +exemplifing it. He has improved the syntax, speed, and cleanliness of his actor-based +animation language and added new capabilities since last Spring. +.end +.begin para + Ken has written two publishable papers in the last year. +He attended and has a paper in the proceedings of the Siggraph/ACM +Workshop on "User-oriented design of Interactive Computer Graphics Systems". He +has nearly completed an article reviewing the field of computer animation for +Technology Review. +.end +.begin para + Last fall he participated in a graduate experimental film course, producing +several films. This school year he is taking courses and reading the +relevant literature in Aesthetics and +Art History for his thesis project. +Ken was a place winner of Byte magazine's Computer Art Contest. His entry will +appear on a cover of the magazine. +One +of his animated films is being shown in various film festivals, theatres and cable television. +.end +.begin para + Last summer he worked on the problems of representing the specifications +and commentary of simple LISP +programs for data structures. The purpose of the research was to explore how a system with +the specifications, commentary and their interconnections would be able to help a program +in modifying either the program or the specifications. +.end +.begin para + In summary, the fellowship has enabled Ken to devote his entire energy to +the pursuit of his research free of other distracting responsibilities. +This freedom has resulted in his outstanding performance during the period +which he has held the fellowship. If his fellowship is renewed, he will be able +to continue his thesis research developing a knowledge-based approach to +computer graphics. +This is an area in which we currently do not have any research contracts which +could provide him with a assistanship. Ken needs a fellowship if he is +to continue to devote his full time to making further progress in his doctoral +research. +.end + \ No newline at end of file diff --git a/arc/ar1:c/KEN RECMND b/arc/ar1:c/KEN RECMND new file mode 100644 index 00000000..98054bcf --- /dev/null +++ b/arc/ar1:c/KEN RECMND @@ -0,0 +1,114 @@ +.!xgpcommands_";squish;botmar 100" + +.device xgp; +.if xcribl then font 1 "carl;30vrs" +.if xcribl then font 2 "carl;25vgbs" +.if xcribl then font 3 "carl;30vrbs" +.if xcribl then font 4 "fonts;25vri" +.if xcribl then font 5 "carl;37vrbs" +.if xcribl then font 6 "fonts;plunk" +.if xcribl then font 7 "carl;25evnt" +.if xcribl then font 8 "fonts;30fg" +.if xcribl then font 9 "fonts;s30grk" +.alpha _ "9a*" << lower-case greek alpha >> +.beta _ "9b*" << lower-case greek beta >> +.gamma _ "9g*" << lower-case greek gamma >> +.delta _ "9d*" << lower-case greek delta >> +.lambda _ "6F*" << lower-case greek lambda >> +.bottom _ "6T*" << upside down capital T >> +.natural _ "3N*" +.turnstile _ "6p*" +.inclusive _ "6I*" << inclusive subset symbol >> +.union _ "6U*" << big set union symbol >> +.phi _ "9F*" + +.require "CARL;BMAC >" sourcefile + +.area text lines 4 to 42 +.page frame 44 high 85 wide +.title area heading line 1 to 2 +.title area footing line 44 + +.every heading(,,5{page}1) +.turn on "{" +.comment "}"; + +.tabspace + +.place text +.fill +\\\\January 6, 1978 +.skip 3 +.begin nofill +Michigan Society of Fellows +c/o Karina Niemeyer +Rackham School of Graduate Studies +The University of Michigan +Ann Arbor, Michigan 48109 +.end +.skip +Dear Ms. Niemeyer: +.begin para + I would like to strongly support +Kenneth Kahn for consideration as a Junior Fellow at the University +of Michigan. As Ken's thesis supervisor, I find that his research is very original and +creative. He has an excellent record and has published several papers in the fields +of Artificial Intelligence and Computer Graphics. +.end +.begin para + During his graduate study at MIT, he has worked with different research groups. First +he worked with the Clinical Decision Making Group and did his Master Thesis with them on the +mechanization of temporal knowledge. This research has been published in the A.I. Journal +(co-authored by his supervisor) +and is considered to be a substantial contribution to the state of the art. +.end +.begin para + He then moved on the the Logo Group of the Artificial +Intelligence Laboratory where he taught elementary school children computer animation and +language processing. He developed an actor-based +computer language called DIRECTOR which he has continued +to improve. +He attended and has a paper in the proceedings of the Siggraph/ACM Workshop +on "User-oriented Design of Interactive Computer Graphics +Systems". During this period he participated in a graduate experimental film +course, producing several films. Byte magazine sponsored a Computer Art Contest +in which Ken was a first place winner and his entry is to appear on the cover of +the magazine. +Also he did an excellent job in teaching a section of our +undergraduate course on Artificial Intelligence Problem-Solving Paradigms. +.end +.begin para + For the last two years he has been honored by holding an IBM graduate fellowship. +During this period he has been working on his doctoral thesis which is an exploration of the +processes of creativity as exemplified by a computer system that he is building +that is capable of +making animated films in response to a high level script. He is expected to finish his +thesis by August 1978. +In the course of his thesis research he has improved the syntax, speed, and +cleanliness of DIRECTOR and added new capabilities since last spring. +In addition Technology Review has published his excellent survey of the +the field of computer animation (co-authored with Henry Lieberman). +.end + +.begin para + In terms of comparison with other students, Ken is our best graduate student +in the area of computer graphics and animation since Ron Baecker graduated in 1969. +In many respects Ken is already more mature and broadly based than Ron was at a similar +stage of his career. Ron is currently a professor at the University of Toronto +directing their computer graphics research. +.end +.begin para + In summary I believe that Ken has outstanding potential as a teacher and +research worker in computer science with a particularly strong background +in the areas of computer animation, artificial intelligence, and programming +languages. +.end + +.skip 1 +.begin nofill +\\\\Sincerely, +.skip 3 +\\\\Carl Hewitt +\\\\Associate Professor of EECS +.end + \ No newline at end of file diff --git a/arc/ar1:c/KWLSKI CONTRO b/arc/ar1:c/KWLSKI CONTRO new file mode 100644 index 00000000..2e2ef5ed --- /dev/null +++ b/arc/ar1:c/KWLSKI CONTRO @@ -0,0 +1,78 @@ +Review of ALGORITHM = LOGIC + CONTROL + + My major recommendation for this paper is that it should be submitted +to the JACM instead of CACM as the subject of the paper really is theorem +proving using resolution. I shall attempt to substantiate this recommendation +in the remainder of the review. First of all the input language that is used in the +paper is very limited, being restricted to sentences of first order logic in +[slightly sugared] disjunctive normal form. + +The expressions admitted by the "programming language" are +of the form + + B1,...,Bm <- A1,...,An + +which is logically equivalent to the following clause in disjunctive normal +form: + + B1 v ... v Bm v -A1 v ... V -An + + Formulas in disjunctive normal form are too primitive and disjointed to +serve as a well structured programming language. A good example of this disjointedness +is found in the paper on the definition of the subset relation. +In first order quantificational calculus the relation can be simply expressed +by saying that "x is a subset of y if, for all z, if z belongs to x then z belongs +to y". However in clausal form the relation must be expressed by two distinct clauses +which are quite difficult to understand by themselves: + + x is a subset of y, arb(x,y) belongs to x <- + x is a subset of y <- arb(x,y) belongs to y + +Neither one of the above clauses makes much sense by itself. +Both need to be considered together as a unit. Unfortunately +this grouping is not expressible by the language considered in the paper being +reviewed. + + I find that the arguments at the beginning of the paper in favor of +separating factual considerations from control considerations in programming +to be unconvincing. A major problem in programming is to devise good ways +to combine factual and control information in order to produce good algorithms. +Simple minded schemes such as using a given clause only "top-down" or "bottom-up" +will not suffice as uniform strategies. The arrow notation used in the paper +is slightly better than this but what is needed is a full fledged control +language [which might be viewed as a generalization of one of the PLANNER-like +which uses parallelism and nondeterminancy instead of backtracking]. In such a +language control questions can be explicitly dealt with so that the section +"A Notation for Expressing Control Information" can have the following example +explicitly written out: + + | + V + Grandparent(x,y) <- Parent(x,z),Parent(z,y) + | | + V V + +The control infomation +ought to be expressed explicitly by a program of the following form: + + +top-down-grandparent-rule: + TO SHOW Grandparent(x,y) + IF given(x) + then SHOW Parent(x,z) + then SHOW Parent(z,y) + IF given(y) + then SHOW Parent(z,y) + then SHOW Parent(x,z) + +The hard part of programming is devising languages and +building up programs such as the one given immediately above +so that factual knowledge and control knowledge can be effectively COMBINED. +My principle criticism of the paper under review is that it +does not recognize that this is the essential problem to be tackled. +Instead the paper simply concedes that the above example cannot be handled by the +arrow notation. If the paper were rewritten to show how to +combine factual information and control information to produce efficient +algorithms then it would be a useful contribution to JACM. + + \ No newline at end of file diff --git a/arc/ar1:c/LING REC b/arc/ar1:c/LING REC new file mode 100644 index 00000000..a2295009 --- /dev/null +++ b/arc/ar1:c/LING REC @@ -0,0 +1,12 @@ +Dear Sirs: + +Without qualifications I would recommend Michael Freiling for a position on your +faculty. In his years at our lab, he has performed research of top quality. +His research has concentrated on developing techniques for representing general +causal structures, and in applying these techniques to problems involving simple +machines. +He has demonstrated a remarkable ability to plan and coordinate his own research +project. + He is also quite friendly, diligent, and open minded. His ability to form +freindships and get along with others would make him a great asset to your +faculty.  \ No newline at end of file diff --git a/arc/ar1:c/MCDONA ORAL b/arc/ar1:c/MCDONA ORAL new file mode 100644 index 0000000000000000000000000000000000000000..7f23bca6452075a03322b26a24c5b9d0f07401c0 GIT binary patch literal 4605 zcma)<-EZ4Q7R5LFV4%Y4J&&_`*)&kq#)+Fv4J_c=4&p^VjKoDBiefP$htgCOhn*oM zdxQM%{oNUomTd0_kRTz&nYs6zbI-jq9?f#Iv6)fVi~3jdXHOaIukDq_H@nO=v zJnUW`9&Hx$;qCLCPjBD8P!riG9P_ca{SHU{w=XyT_S^5fx8eDB3%{Bik4H0aes8Te zYI1t=@$K>DPd~mpIaU9dsNhyj zJk&aqZ_UQ|8`XdISSE@Z#$j(d|kJqGXR49}ks;DQoyYxs~!c z|DBtKtyE^J#&{l^)>q0^YVw&3XOcF*sL2;W>~pRg^M%)@%H!IwvbB1#vrXmF&Q~9P zQ0hd$xwufLY+{?naPaGoAKvlHDYUCMX3N|0=+jR>{`36w>Ie0~>r$Ox>$ReS>}@EN$qW^4qr{x zvsW*_pN&UXOB>P`{99Nb8l?$+T{l8atwT`F1Lwq*MhRRoQ?)khx$$ge5ZI-6g$cp& zd{UOCnyS|x39VdRO!<)mrUM$koG!KXHEUhD=2*?#mm!;AhZA(2zLX=c) zs?1EsBMIyFd~XtUxx}lR2;(h)bEAH1^M%RPqsNtN)bFh>ZDD!l(?%d@?AknjG#&{B z2ml4z3IODg++|I~x%O^>!1+a;mnLhx&4j=TJsIN>^>{?d2>o@7xYVc2N~|RHFo8mK zAESa=T~RO1Qt_|3&Ws?}B!+8m0uM*99y)N(cwnvxoZUtli+D?1b$8$kJdVnPgH^&DZyx;Emhu9Y%Wnj<*j5v z2Gcdx5P)esit2KHC1J*`sdK?3GAqWz>qNBxFC2+C+=)RRw`@Wtm)bYw4IdDOBrmbF zB`6hXcd0<=*)A>Nv22O{Y7%j+&7`65;m67`8A3g(vzUa zqshUGD?VE5-$1Ig)ZHKlSBijU17K+?9af#Yc2)P}& zRyn&Y2-Qc8QT_-=^hC5DHD`cY1b0gDgQ^SVdh)D!FN> z=TzNT3vgiZ=6`{3w- zwz7@I9h#-rVadu4H!)+KQGVzkEKM#dkTm5z`@mF;l;FCWhdMlP;XLQAC1}tyo|eIy zr4dHPBiIt2c~HT`V(6po{G}-Gdfw>EL}?r-$TsJH`cWQN|!oM zX%b|7Hy)X5lpFmnK@?Sj&T#GZR7z1YY^&(v0(}Rp1XbcD<557*CN|%`n1`%Iz*M@X zMa1=Tk`qBk+XlkBbaQS^(PQr_SfBiqvfgp7%%bTy~Gz4&w~r703be@+}gI!Pop^A1nt*SyV=-)$W>5Ss8% zknCA?<<}#gN24ZH-IFV>;oJ(lw;ZBX>BM_!gra~b<)~BB^qw4{6pEtr;Dd?PL9(%) zM1{F2VgWF5K+?hC$>rtw`?G_motqMbL%)e<+KXfAkS>rV2#U7KlIc7EzX-ixWGXF= z5sPvEKqdpBSO7p-nrx);Xsl;utIXx*$>d22N4>vzD}TS9Fi9E=twn%*3{JP7?tb&< z|AXpb&=Du47tVJ@xRB|1=uO1kl{+Cn=uevQ@8;h!Ktzwo8443u(${62+buFNM}Ey# z)F-?NXKj6pP!cO5M_0p?u#*r;?>XodG!8>m>NNKTtK|7{t`b`AO;sEQ{$en&3lKyo zb}y0dmet>a8k%ONbF;P?hzuqfJ%OcS6ICz8D3{nmx+1}MhjHr-Cwg7QdF0izZ(lu2 zSTUIXd@j*Q5TL}6)k;`cWAyBtYVx!#&JZss%2q}d3MN@=%%$_Dosk<1FRIurx!f@a zQs&eWHJpo{=o>8)D+BLt#&Irb^a=sQIju0;p&C*l4D0Wv2e-@{vE3w!;`~EWbWmhuXZkR$U*K?9gF>Rdv{PCGVdm=JwA2r zYAj~$xcv~bgx?R4$%4>OZsODy)8n30mfu916oc3sTl=0R_!`GeBx5_Ks}3H%msxq= zizCCS1rPolYd;QMCOBpW?3GC;aDif?iFX7>iB9j_+#S;ecqRG4H*Kc%Twy!Kr&yvS zuJ{ZJx|`o!TwqD|DOy>+uX>pT)w*S>7NEwXtfWb!8Eyg8jjURY}F5X~t-1nAUDkJHViEo8yA{22oUWLa)(#C2fV1&X35sNK;n;}y9fxsvT5 z|GjUx`tV1Bo+NU~nKy6VJa#jl>6Ga%ua0P9O`t7GQsv5{-sa5tWU;xu*xcTo<>S?E z@6plq?hYjq$RFXb)5{3E%d`74w?4bK*!8{5+}$Qe?N+owX9`Az_T;G-hYV0eO%2}SVyQk%`pI`5uT=h?{ zU;o*y?rYuD7v!u-|L9MmNXj!@>13$nZ{0wNXI>-o!dOQ8T71 zW}sMMX{xD|QwVuoEJ)_>-K4ql;I_=9!~%G-k?}rzjK3E~H^U zRLXm-3+>yjI0BEl1JKJ>;@^vAHrWXQbZ!tsR3Jbk0%j`|3krj+bSf1m|4UxGg<~(s zgZ8D-?*Ky7y~1LYb9PQ!+nvqTUL&?-bUz*25^0AsRn`roH(ok5uqNdy)ZqJyA2aS_ z0cd0npMbPb0FB@f8^g(j)8K((d{6ybZLHJumo@yL=Bk64I)mJ%mfrRbF^(skMsdnq z?yVSn!d^0B*jLc0j~coz*uqp$Ii|9zoBk(+Warj%RZzc6zuUZKgJd^@5B-iHw=U4z zy$+r7*wqU6#RtBVZ>dDOuo;&N4eK=0(v@nnB9XmzC**|U?eRT1y@kK z^{RyW&XxHFf@nxf{XD7vjnt`}bVKyA&`~WqTu3HL$SvE0eHchuD47-bBd#fbOJhzI zE(vi6qa9@$or+;q1$Zh2(#Wu6F+9hc5GPNTQIt_`GIYwN1-M%ce};Ypxr7poN2*lg9n%#!|~Qg9v9fujFj&|<%{{wWi%D#*1`($;> literal 0 HcmV?d00001 diff --git a/arc/ar1:c/REED ORAL b/arc/ar1:c/REED ORAL new file mode 100644 index 00000000..38343a72 --- /dev/null +++ b/arc/ar1:c/REED ORAL @@ -0,0 +1,73 @@ +DRAFT + + +TO: Area II Committee + +DATE: April 22, 1975 + +RE: Oral Qualifying Examination for Mr. Dave Reed + + + + An oral examination of Mr. Reed was held on Friday April 18, +by a committee consisting of Professors Mitter, Schroeder and Hewitt +(chairman). Mr. Reed spent about forty five minutes discussing his +thesis work, and after a recess spent over an hour answering questions +and solving problems on the blackboard. Dave performed exceedingly +well on the problems and his masters thesis research is first rate. +On the basis of all the evidence the committee felt that Mr. Reed +should be p_a_s_s_e_d_ and be q_u_a_l_i_f_i_e_d_ at this time in the doctoral program. + + Dave's thesis concerns simplifying and generalizing the +implementation of processes in MULTICS. Currently processes in +MULTICS provide many useful services for the user but they are +expensive to create and maintain. Dave has taken the approach of +building a small fixed number of virtual processors as a base on which +to build the general MULTICS processes. The capabilities of virtual +processors are closely matched to the capabilities of the actual +physical processors of the machine. Two very important design goals +of his thesis are to simplify and increase the security of MULTICS. +Professor Mitter asked how Dave could be sure that the security of +MULTICS had in fact been increased by these measures. Professor +Hewitt asked Dave to describe similarities and differences of his +virtual processors and the virtual machines as implemented on the +IBM-370. Professor Mitter asked Dave about the possibilities for +formally modeling his implementation with Petri Nets. Dave had tried +this but found the restriction of not being able to add new places or +transitions to a Petri to be a crucial deficiency in the model. This +limitation restricts Petri Nets to finite state control. + + Professor Schroeder then asked Dave to describe the techniques +of contiguous allocation and block allocation memory schemes. Dave +answered the question succinctly pointing out the relative advantages and +disadvantages of each scheme. Professor Schroeder then asked Dave to +give a rough calculation of the wasted space for each scheme. Dave +did the calculation assuring a uniform distribution of block sizes. +Professor Schroeder then pointed out that a uniform distribution was +not a realistic assumption. + + Professor Hewitt asked Dave to implement LISP lists in the   lambda- +calculus. Dave proceeded to do this by giving lambda-expressions for +CONS, CAR, CDR. He was asked whether his definitions would run if +translated into LISP. Dave answered that it depended on the version +of LISP and explained two common schemes for implementing LISP. +Professor Hewitt then asked if he could translate his definitions of CONS +into an ALGOL-like language with procedures as values. Dave easily did this +and explained how the usual implementation of ALGOL would have to be changed. +Dave was then asked to add operations RPLACA and RPLACD to his definition of +CONS. He did this and explained how the change further affected the +implementation of the language. + + Professor Mitter asked Dave to formally define the notion of a +finite state machine. Dave was a little rusty on his automata theory +but was able to come up with the defintion. He was then asked to +define the reduced machine after some thrashing around he hit upon the +idea of a homorphism. + + Sincerely, + + + + Carl E. Hewitt + +CEH/yw \ No newline at end of file diff --git a/arc/ar1:c/RICH AREA1 b/arc/ar1:c/RICH AREA1 new file mode 100644 index 00000000..9d990e84 --- /dev/null +++ b/arc/ar1:c/RICH AREA1 @@ -0,0 +1,109 @@ + +.device xgp; font 1 "carl;30vrs"; font 2 "carl;25vgbs"; font 3 "carl;30vrbs"; font 4 "fonts;25vri"; font 5 "carl;37vrbs"; font 6 "carl;s30grk"; + +.require "CARL;PUBMAC >" sourcefile + +.!xgpcommands_";squish" + +.area text lines 3 to 45 +.page frame 45 high 85 wide +.title area heading line 1 to 2 +.tabspace +.every heading (,{page},) + +.tabspace + +.place text +.next page +.fill + + +.begin center +.turn on "{" +.comment "}"; +July 15, 1976 +.end + +.skip 4 + +.begin nofill +TO: Area II Committee +FROM: Carl Hewitt +SUBJECT: Area Examination for Charles Rich +.end + +.begin para + The area examination for Charles Rich was held on May 24, 1976. +The committee members were Professors Szolovitz, Winston, and Hewitt [Chairperson]. +The committee examined Mr. Rich in the general area of Automating the Construction +of Reliable Software. +On the basis of disappointing performance in answering technical +questions in his proposed thesis area, +the committee recommends that Mr. Rich retake the +area examination in the fall. +.end + + +.begin para + The papers assigned for the exam within the topic of "Control Structures +in Artificial Intelligence" +were: +.skip +.begin narrow 12,0 +.begin para +"An Overview of Production Systems" +Davis and King. Stanford. AI Memo. AIM-J71. +.end +.begin para +"Micro-PLANNER Reference Manual" +Sussman, Winograd, and Charniak. MIT AI Memo. 203A. +.end +.begin para +"An Actor-Based Computer Animation Language". +Kenneth Kahn. AI Working Paper 120. +.end +.end +.skip +The committee was not very happy with the written critique produced +by Mr. Rich but felt that it was probably difficult to produce a better one. +In his oral presentation, Mr. Rich presented a quite good discussion +of the overall issues in control structure for A.I. systems. +The committee felt that Mr. Rich did a quite good job throughout the +examination in explaining top level goals and methodology. +However, his performance was disappointing on the technical questions +discussed below. +.end + +.begin para + Mr. Rich was asked to construct a LISP function which computed +the set of all subsets of its argument. Mr. Rich had considerably difficulty +with this problem. +Professor Hewitt asked Mr. Rich to provide a specification +for an integer division algorithm for positive integers. +Mr. Rich was able to come up with +the specification that the numerator should be equal to the quotient times +the divisor plus the remainder. +However, he left out the specification that the remainder should be +non-negative and less than the divisor. +He was then asked to develop a flow chart which implemented the specifications. +Unfortunately, the flow chart developed was overly complicated for the +task. Twice during the development of the implementation, +Mr. Rich completed a flow chart and thought that the program was correct. +However, both on both cases it turned out that there was a bug. +Mr. Rich had tremendous difficulty in attempting to prove that +his final flow chart was correct. +.end + +.begin para + In general, the committee found that Mr. Rich's performance on +constructing programs and proving them correct was disappointing. +The programs which he developed were overly complicated. They +were developed by a process of patching with no obvious overview +of the entire process. +Therefore the recommendation is that he retake the examination in the +fall with emphasis on technical aspects of the area. +In particular the committee recommends that the next examination concentrate +on the formal mathematical basis for program semantics and +proofs of correctness. +.end + \ No newline at end of file diff --git a/arc/ar1:c/RUSS ORAL b/arc/ar1:c/RUSS ORAL new file mode 100644 index 0000000000000000000000000000000000000000..e11c1a14993218d9c7d6b1568a6139d82158fa80 GIT binary patch literal 5450 zcma)=-*4Q;5y$gnAcx*lU;4Pcm$reT#+@G{e|WLHQ2$t{;Ci2#KNYqz^BK?m8J9Cx*Sg8We-`I~w?esyx3o7}b>^;9 zm2FH=PgLjB(`UTY>a|gY*R|nqRoZo_zI~>)Hpk{^XS>R%_;P7wTkKqZaRp@KnO)j#_*W#NOw+GatBYnmoQ6Zf&cc9++udvV8OM zd!?2F&efH=z=-WS!@)nje))ns7o=TXnk`r7vo~*l_}BA`oA1?2uPgQZPS>{4oyCX3 zdG*4ds@Hu8rmEDkyR}Vl&4CBW`&N5BpM8E)8s)@@`N+t}2GmvuAgywVblG}ask5^a z_4vDQzCNALZb}>C6CL(~$y~#851AF;MxWw)MhRdsR#lsNWjuxq6no`eVM1{Hz051) zPt=dbcdmcu!il=J;nr8_99XEfrIScQ5BD}U2xdaO^um0`E#$8=iX21$VYk|0SDi!=;Vxi$*WQ9{G6$x82U#O+ z#gb$ZjHN1$@F}T$!Dv1UqO6F8ty||~TF6fa<6>Tg1rHN??`|qwrNb@xJvs&YY6!7= z7jv<^{^!fA5`_pY=ne3t4|Mc-(@mYb`})SSGmy3+OZj3cX}T8*PxkjToy z>eP2bcdbM&C=JnN^S5c1k zp3i4v>HHpKhD1Jq%vO}fcF3d9UD73~E_EePNG2l$QvX!`qDStljRutkyt<4$YzDyP zT`iaqN7S#zq20X~Nb4wk$T5{57UGNJDgPH|iz?<8X{DgG_wXuLcrA{uO_NBI8#)dr zmu?$xBtPmNG2>@uOdiuv>RjcvC~VeO2ykngM*Pd&wwcco$vbT+WlI7H2MT63NFOQb z8%Zi$@jJLU^^;G~F-I~zast+PTxfc|R@88Gr$eE_6*suMWSyA;CkQfzcF7bv96J;A;+AFF}jAu`Au2iFeJYI={a~D&vzhffu)_ht7uBcD`G4Iu_;G<}Wc}k+R zFSLD4#e|JUH|P$@A3BsBW8!H}?>)h>fNz*g@U+ z`_(vxr728;#1~{%9)gi}6YWZG;LwQ_0v^){yFz|YiS&n~L1!rnA@rruC9&AI>uAAl zV7*wF+z4aW#Xs^D2jVm^GL5)qjsDQZ3cUd;Xdv^K@b@rO%-xh`rwUWap)qF=-}s1< zgfO5cGnnK!b`XlCGFkGn^F8TKBO-~7y05c1X0hi;_l<-*JXGq7)UjUd0NFMIn2ah= zQIJk!E3H);Dnk{yojjYwP>y2S5i;RrOwZvF^I6oBTCW>h*nKJs?4>wKS!5e+fF#H=+9nc|13DM;dgSX2d5dz>61b&{ds6f!c( z7YaX&*(2%^;;qyO=Lo&EqG)!iB9)5i6qxhWpB@-YRwfhCtR3rufEa&FReH>t1F`4H zR4t;cGF^#(8RIA;Z4@YCSh0xZv~^LH+s19F43^Vj0=W zf~;hamv%sNTsu#Xs7EGIG2;$HW2J`<)2-|Z0_DNGWUKm8=#nN0b}slR`w}xp9=|gH z+QYLcQXt2qwJvF7th}Q{-QVnn#ZLCRv=$LCn-e5qvt~sfBqWJaJixO$v11*{#HYq> z)SK>ymPo8v1}kZ&KE^fH8TfS6qco4WVaijo-Hoe4;)%|4W@fs@exp{Gtah|dZ)A*5 zJJB&QW#rGLwGLD8uWlt79k*i{gxK=OWlkhKc{i{Ub&yVp1DD)lnNw82?NB6$`M;m5 zpT9l(`*)9j5j{fEDlIFZ93kk9J!mgnN6C=RK);NWIa_MpL+6N6TkhCDxtUb@Z6ggh z$QBRqR~0;PcI?8RAAEv2_!hG7KNBYgd?W>XRZx>C#G*O$FMbCY%66zqLfe)k3KNpC zG-<_eJC}k+ZuhOREOBoFz zas`ahH5niyk>r*j!WPHsL{UohwGV9kfq63aN)8#n(Tst849_tF(nnBd(N?x<<|Z-` zJM%_1iD6+iOrY#^Fe#A`^qXiT=2h4m21kJsx-b+Ve*20I;53JVRI*#P->FPg;uGlbGZ*haDAT-sJU-c!e{kTyEXO4 zzTZ0B+ME8v*8iRI=N}}F&3SfR;-*A}FUX?gBltMixv449b_mE_mMG98s+DtgMbD$Y z69B!;*-H5Fnn`43vDgrzsETx!=_q+<4fW7fkmbU_g}^H9>FrwtG@)uVN>s)$oZKuK zWxV3s;}LlBNFw6cnaPZh?OD@M-Ug2DJ%`9YFa7U>rsQJWvd(EG6_v z&vs8u$`qMVuxVn|8G>aRP zq8jiG0ey)*i%0&XVS(Wr^nsGd6TXQ6?E89*?}K8gv+xQ|mmlEc1yM z1<8uLRkx(2@crP>u#^-UF0$6aq~k0^>~oDlWGu${5DDQlY8`L@TAl}S)X9X%+8X@| zHn#SCi%z!fc>VHvYcH0m+!10pYt$5YYUM)gtPZIJgo@JY>P!R|T$==eWs~ZStC*^F z+-Km~Tda%`nDHo4UP}7}xk}DrAq&g5BmbxDNWDY(-szxYGx@2}o&19%pC2Uz`n41vj=?BPmULySrQa-)!yS zf2iGIO@rnvK()*of*4vx5^;Lr9SWVRhUMPT#VbHu959g*%L_F(Rzp9>{h3{)78@i# z{dn)`<5%y^^y3Hm>M70SQ!lK0DZ_g$`om5H82du&&O3SX+Gm0t%B)!J#@Z?#i^FOf+Xt}$i>3KPY>)o01OUel8@uhqyPW+$)iV4@E3pn1KrH~Gynhq literal 0 HcmV?d00001 diff --git a/arc/ar1:c/STEVEN ORAL b/arc/ar1:c/STEVEN ORAL new file mode 100644 index 0000000000000000000000000000000000000000..87442ffcee02e273fffdf2d0598bf6978613ee3f GIT binary patch literal 3790 zcmWO8`FA3OfdF7axFJ9wK*Al4gm8xd;l9HW?i<2=CqTFo0wF+J>#DUn9Xqa$*VKBv zy6e-f-M6kftGjml+G^iAu2=hNyZW5x)LpGRZne&|9@{_R`|WdwGnC8goaClC7C=-7 z&=u+Y+xP+q`0S{8fJ)(+4gXJ=mKy3J7oXkyE@eofAlv8x^I;fmO41*iC1oMSN5h5S zAO%6{E)|wE0=1^Y1_g$@v77;==62-9La%2q`?^A{#_`gqxZe3y1w6a)Wn@5xzt0?* z+drepY4N;^Lw7_}6()Xw@9n5ROu|C*e<9O@dv_*x+~Nlh)8f+B=8mV-*HgD4SG1XM z{>f$ubD+#GMo?E#C(BNt9FEXkY1og}FN-ns+`@Q826`18A4N>_wt{v#(eDv-lC>~n zC)TcMybC+g>}NcDP$4<0_ENF@c-Q}?js{ttHS7A~pL&t`=nI0Ba_tLPYo8m>Lr!*W zhe>Vxrh^tWaVajdMqUf>6eY%P79$6*xBV;Mp#gfB7XhBRL@U+#hl|FZJvYoSW2K zsKpv8*yJCTP`pgLn5_kuV<1{mx`<-1nI8qGtkyOxZtZW%3xLq=V?sDkp5xN}Wc3kf zj<99qfk-JRVDl~K&`jCad6!NuKxC=*0~{WLfpBr;Gt`2GQtyx#ce&p?vPVc{HN_A5 z=PbfWxj&H+2wdY-GQju6)&+2<6rMbtpQC!3ji>-HMS7mxW9auDR zdiGx4(0h@#wH|q{J07mD?rBo(o}W9UKI|#eJ@4VFtOHQ66;nNJv4^oIwDk!J5eyz5 zsHe{3ZHUgjfPNu{$)(~)ErI9zm0l|J;IW||xGH8r%};BXgYY$W(TcmDsOu_9uD!L+ zfZ;7iJbrJ%`*&>DM&1_|p9G+F^8?0HqWUKugF+Gj%>!~W zvmPbZY_ktg#jI(a|DTu!u=~1>!)4#bu}}BE8L{(CPshU9ghs*i$MTI}t)tl?b$H+5 z8XDNJT#4k~ITqH_DG_PayvP|&cLP%@rt|MhmDS=)jAUb29?(zZg=BHL>ktbwYP_IP zoID?+7W+4+GGpF5JJSF?s>ku(r@qM|=>S3+T>?Ca!|BKu#%rq-p)zhgCdQW=Y7>N_I zW+h)!axw&~m&j7l}0L{;2}V(t@xhlb+P2?Hv7+ zIln69a2sN1Qvx$niS<#%{aF<no>(M`(+&-e3Ht=W-$RZqEFuAboN zQo=$lon!l~8w>jK^ipGinnt)4f!M`q=!n2tin*~*&4OvtrgXg_xrHtY1@9@uPwDsQ zB)&OTe5r}Jh6U*}AE5eE%=IpF-Vhm$0>&7&7Zw1COBwc)eW5V3Js?ya_mNJ0=C1_S zk@SKw?iNO|VeszD2N6;G?smPs+%0jcE02hean_HB^O5R6V-|}!rJQVZ1~{q7-=1T_ ziEo5!CgV$yeiCzEAw~+{19a1|bzqO!1)^y$Esq8lWOjTpnAUQ19J_j-uE9V01=;lYLEqF5Jq+unGi#zbR z62PR<)*WHdyjo;C%@6uizs0z!9B%(GpjA$;R?PW9vx_We{-Kre3vMiWxF>dlNZ!7o zhbwmFbewI-G7*~0R2E!L!7Ln*_@RSUiI_2L%uzHn??^o}>-3CXZw~3Id(q6i2NRxf zYG2z3K)#hOBzW0a9ff*V7rV6?ipuoHOWOpG*{#~vrU9XB!@I1ISLolOx#iX?39D=6 z8k8vly#X2P+hiN7nZBQhtao@O&W!s{lHnNh%Q`S+ILQP13)hIQ&gQGO34s1azn%ad zVVd+Adm10)UtX)j(s$XKbqql`4kgbF@@9qI7;`{J|9ctOXs{@?8bRj4zK*5Bon&uZ4EAnOfb0uB2j=XHi&foID-PR@;&eF)3&#t&4Fb==$c zFGl@ev|yW#L0sCV^#~K zc|E$w(6rKt(dv6Vy12zaVlm4z_Ek&kQd-Eb{?e=TZv5VP6hh1rAc`HXLg=x_@+vW& zORlPY`BY$N*~|;$;-4vYCbmh89fsU(K{h9!SyvAa&bx&n!7cU!OXG8;$w+tZ>YkM!^X8z6M}nI!MIb z;eSF*PY83ywdqM=m4hl57Lpm{9NBK-+_YB1NU%6K(D3~U*B<#~=-^x5g)*`HD>kA| zoj=jf1l}%Y1x>qP30V^H9DBJBR^YSA)>d|}c#D=yCVd6aFAnNpU8?>Y*BU~3g&^A3 zT}83vmg_0xSn{cnH(j*%3|jQ^2$7_x#M^4yWi867)*W{Oi2usE*pLKKfDU|2+{GQG zV0{|F*vgGd^oH#!@i>fq znTKibtLApv^LUh65Ps2TAYlHuMh#^U%W07GO=QI+wZ?Mh(6?E9ApNX?xGlU*8IA`E zqpj%iSQ{4W8}>|%c5C?LX!0CW02EAXG$r`66JgTzYz=QFU*?a|iW|+l8`27>Dkx;! zX>u7{WhQceAJ#4po>|e%`M07@Klqcs-Y4-$6JG`Cd;(emS(Y{RpLXrq#*v<)+Dv9n z`KogxJ8R`8QnN>E&8^~m;O&*!jeFZg`cSMBIDFmNnM1-o_;KR&>~NdP<(^=mk!MOY zs4Wm>@40_$*@%tZd#jNquwX?L9uv58oxjMb_P~1;4l(@u1r1};+i@?c-a81kA{A!w zwDIUch~2#!*~={Asu2s~VHVYfew|UOVJiaP5*!@U%c`$gwnt8#i~wBz5G5_;p4!}A zvCqtJB#Pp#syb`H_CWPBRyU!DkPYC<3qfJDNVM)oc{kuh^dn?CtJ>Hpafno|SIomD zxFNLUyUKnQevVqQ`3y`S-56V*A9I^r4L>#&CYjww1pWkiu@l=LziJPxk&P~}4EyR@ z86Ufe00CJK(6+Ga|A;!1+H6Do^8Z&bXu+O;!+- zk0JX`kxDerz-#s~4%OMIWbAO@dnDksZYt!tK*L4dG>cKn+65wx+h1-#1E|+{ppx}j z~83Mx%UMrTij-4Vso|>lMt!GR5j!J~@nR;+2Pbcn7>hN`AdcaTBI` za?iH{DQ~!g$K2ZD^#wXB-QAa=S2x#+X}%_2q3IDcI@fv0gyOb1@aS~jCeiEx=?kHR zGbRystnD*s|DfjV4f4f(YSTFYBkg1Sir!qsTrcS%EBs{Hy2qqco({2S;{2rl3 efxdhSs)Yj_Cn)p`DF;{oR!|^Ng;gX{6ZwC(muueu literal 0 HcmV?d00001 diff --git a/arc/ar1:c/VALDIS AREA b/arc/ar1:c/VALDIS AREA new file mode 100644 index 0000000000000000000000000000000000000000..6b1d7809b117e92047b1e7e1b0ab9b0b48612e94 GIT binary patch literal 5370 zcma)=-EZ8u6~*(kzz#Z3ed!}RPi^50^5vvm0|gv!(s=7MM&k6PC<>0mk+_ybg_LIE z4f4PDcS%Vj$4R>{hNU4d@5j049%{K*=VoU!qdpexiQ2lRQxDZD)4n=+{9xz9YIyl* zc=_mfS8S%Yk7r8{Z=a}@7z!sW_I9*zJg$AV^M|!hhqvMJgTi00PL_-1V(ra`-g=`} zXQyv3PA=a+e|>tU{<>1Z^*%Gd+uF*+b-%~y%+z&we`9-Jgd?crTX)++S?qP>&|wSQE_u=bZ(m>?k6W~e-=4m_`tDChpX7+oN7IWxMvo3V#fb_V(LWvEp&MNb_A_TQw<8y(0I3pKu0mD+m= zprPEj68$Tj%M}l#6uY2;V|5dVOwjkCH$gHUj+P5?=8yt!5(e^sm%79A$?=U*xiK~2 zfZ9^;jQVY>L*Tiz6e_}dRt~%!fx~}ysux`i3In!iupzYI@j7vLS0>Y zliLhPf~P9$t6mPp!aQ4QOcrRCD*nLHg4)T0Mtkq}>fxiK2h+QRshRx?S8yh_XLUGO zR%&yj-a3%dslU6ut~g+=WNl{fuqk3?&R?Ei-hcLR%EGM-tOR#oRD29>I{ce~yJ$sCU?;E>YOD137hz8+9)9 z(0aq)sWM+n22tPgo3y`Mt1IoBs&DeIWaX!`)ARe!jt?hCZW(GMSvf#)YpO1R5Mqg> zDS>7{-DVbYC?a0;#(~7H^u{Fk2jvZ(2VuBeK^9r5tI9Oc9y@fn#;bUc7@`qW>s{Vw ztfj2;MiuUeWSmt-dmL*zZ5ymC7rEiziYjH^&st+(Z86BFh8k^FO&qQ%tBi(#@OU1gpH|Oiz}2R<}U(p$l`#l z*>S)oGrqwlg{e2T=xukiTnt{=vCq-~#GwWt2sM8bIdh2SW=sD_av2A@(bWxeVY$G} zmi9x809k-kGBh)3<)Oxm+nxy*pV&C_c5rJeIzn)UWHZ~ong)jS5OH6QvyuN8iTHZn zL?0q1k8ZWmtQQ5?mOjKM8kA~CF(&+y@|{6w#JN+Et6U3QSs7$hfszJTDB#mqR5%9^ z;?CU)4r5_f!UH;`_X%0fLYqmY37{l3Xagn-Q;5j-nhF7}%=)aaccO@5rHAra*@rU7 zY;+?wt^7VfYOG)^^0$1vgR+B*P{k;?ZcWWY(vu#+#I=;3J`Rj^2XyCNg7hHyZKd|o z9|%KVi-?#bsC5EC^ie->t(YJ?o66K;pmpeq&c^N%GF&dkvq-+kiVoF;u;6Ia!Uz{Y zA4o5$rE<$fO;bwg3QI1>z9Cyk6*f8`U^teiVa1q1p^iibsx7^y|6^HfGfPd|DQdzI{;(3uPBP%c4GwMyWsJ78)!69*6d$Fi+J7?#sqQ>#9; zQ#|-XuXAxLQ(S9fpGjk-As=q)jjM*4NE_Onm=Md;uH{0!gGg~JPSu8*&lWa)&7-hJ zx;6ZYO5R~5Igq;E$uYAgG?@Ac zTNEY5%N;RJgaXDb_*CHPiSh%V1Fnraz4+Uk3&DcWSiPamCgE{Q((>9Da(fqN`0PNY zrr#41A_vL5%zE!(mDsULXW~i4*NoV);yLK8McfIgg-PijGCgtCp^?9(WCg0pG{uWE zab5%&<1$EM(IbcMtl3AYGR)(|8~7ww+jQ$o(jbj7=^j2K+^EpWrxsdcP-5|eMLh3v zWI^uC@x~5l&lyUi0*iP|@-1${M(kXaVNBaW=ndlx@uLEIZR}>Xap-d~Bg0D+S1uZp zQAucnhUQBSXo!H9S^Mkg?{L+b=S<)iVb?jdNWAx?Nrwj%P44>1he&FYMz{GHE{tjk z7>T1YDfEVJL-`V~yb4)~!%+jpoKIqOyimy34}twK>7%B__|`!9)KBh3@n>XZ0@9Rt z5I(X1sYzdaNWxWVpr+|M_hpR0FI~VQLuP!?Af0NXLBCwfrhCxfe{xd<{y^u%6z9{} zb`m7Kll4(J(oJd`?{6X{m|uLVp`bFuL|&3Fkre_U(LkUJ0U;<=wf-3uQMsnLFUm" sourcefile + +.!xgpcommands_";squish" + +.area text lines 3 to 45 +.page frame 45 high 85 wide +.title area heading line 1 to 2 +.tabspace +.every heading (5DRAFT*,{page},5DRAFT*) + +.tabspace + +.place text +.next page +.fill + + +.begin center +.turn on "{" +.comment "}"; +{date} +.end + +.skip 4 + +.begin nofill +TO: Area II Committee +FROM: Carl Hewitt +SUBJECT: Area Examination for Robert Woodham +.end + +.begin para + The area examination for Robert Woodham was held on February 9, 1976. +The committee members were Professors Horn, Minsky, Ward, and Hewitt [Chairperson]. +The committee examined Mr. Woodham in the general area of Artificial Intelligence +with special reference to common sense reasoning. +On the basis of a well written paper and good performance in answering questions, +the committee recommends that Mr. Woodham be deemed to have passed his +area examination. +.end +.begin para + The examination began with a request for Mr. Woodham to describe the +general area of vision research with particular emphasis on applications. +Mr. Woodham gave a coherent discussion of the field. He feels that +the main applications of vision in the next five years or so will +be in the areas of inspection and monitoring. +.end + +.begin para + The papers assigned for the exam within the topic of "Common Sense Reasoning" +were: +.skip +.begin narrow 12,0 +.begin para +"Concepts for Representing Mundane Reality in Plans" by Abelson. +Representation and Understanding edited by Bobrow and Collins. +.end +.begin para +"Organization and Inference in a Frame-like System of Common Sense Knowledge" by Charniak. Proceedings of Workshop on Theoretical Issues in Natural Language Processing. +10-13 June 1975. +.end +.begin para +"Scripts, Plans, and Knowledge" by Schank and Abelson +Proceedings of IJCAI-75. +.end +.begin para +"One System for two Tasks: A Commonsense Algorithm Memory that Solves Problem and Comprehends Language" by Reiger. +A. I. Working Paper 114. +.end +.end +.skip +The committee felt that reading and criticizing the above four papers represented a +challenging task. The critique produced by Mr. Woodham was very clear containing +detailed criticisms of some of the authors. +.end + +.begin para + The examination turned to an oral critique by Mr. Woodham of +the papers which he had been assigned to read. +Mr. Woodham began with an analysis of common sense reasoning which +is trivial and mundane knowledge about the world that people commonly +use in everyday activities. +He pointed out that all of the authors assume that they can analyze common +sense reasoning by analyzing the mechanisms needed to understand stories. +Professor Horn questioned whether this assumption was valid pointing out +that the authors had not analyzed spatial knowledge to any degree. +.end + +.begin para + Mr. Woodham then turned to the issues of representation, inference, +and control. Representation concerns the issue of the use of primitives. +Inference concerns making explicit what was previously only implicit in the +the representation. Control concerns issues of how to use available inference +mechanisms. +Professor Ward questioned whether there is any alternative to the use of +primitives. Mr. Woodham clarified his remarks by noting that it is the +number and use of primitives that is at issue with some authors (notably Schank) +favoring a very small number whereas others (such as Charniak) permitting +large numbers. +Having only a small number of primitives seems to require that English +sentences must be expanded to the level of primitives in order to +be used. Mr. Woodham gave the example of how the sentence +.begin outquote; narrow 12,12 +John killed Mary for a reason. +.end +.skip +would be represented as a conceptual dependency graph whose meaning is equivalent to: + +.begin outquote; narrow 12,12 +John though something, which caused him to do something, which caused +Mary to become in a state of worst possible health. +.end +.skip +Professor Minsky suggested that perhaps Schank had recently withdrawn somewhat +from the above position on expanding everything in terms of a very few +primitives. +.end + +.begin para + Mr. Woodham then turned to the issue of canonical forms. He maintained +that for English that it was not realistic to hope for canonical forms in a +representation in the sense that two English sentences would mean the same +if and only if they had the same representation. +Professor Ward raised the issue of canonical forms for lambda expressions +pointing out that normal forms are a canonical form in that if two forms +have the same normal form then they are equivalent. +Professor Minsky pointed out that the meaning of a sentence in English +is analogous to the function which +corresponds to a lambda expression. +There is no unique lambda expression that corresponds to a function +considered as a set of ordered pairs. +.end + +.begin para + Professor Hewitt asked the relationship between the plans +of high-level goal-oriented languages like PLANNER and the scripts +of Schank and Abelson. Mr. Woodham pointed out that the scripts were not +just plans of how to carry some activity such as how to eat in +a restaurant. Rather the scripts were directions on how to process +stories about people eating in restaurants. +.end + +.begin para + Professor Horn asked Mr. Woodham to rank the work represented +in the papers which he had read on a spectrum of development of +implementation on a scale from vague ideas to precise specified in terms +that would make implementation straight forward. Mr. Woodham was +able to construct this spectrum and argue persuasively for +his ranking. +Professor Ward asked Mr. Woodham to elaborate on his criticism of Abelson. +Professor Hewitt asked him to relate Reiger's By-Passable Networks +to production systems. +Mr. Woodham was able to make the correspondence between production systems +and Reiger's networks and show how the by-pass mechanism corresponds to adding +more productions. +.end + +.begin para + The exam finished up with Mr. Woodham presenting an overview +of his proposed thesis topic which is an investigation into the +kinds of visual processing needed to detect flaws in castings. +.end + + + + \ No newline at end of file diff --git a/arc/ar2:c/MMR 1 b/arc/ar2:c/MMR 1 new file mode 100644 index 0000000000000000000000000000000000000000..9b23be39cad6ed6f89709c1677329d9ebcaeda2f GIT binary patch literal 7415 zcmZ`;+in{<65ZDbqkrJr$bb@TGJC~7*@=w=7-tr?XJ@f*R5v9N?r!$5*_Jh5zvonu zt(M~e6O3(<#k!n2b%0Ga`FL$UUjF>^y}A7Q$vk|%Hn+ET=H{2X+vQ@pc=ND# z=GInw-|_#xORlqB<;4lYEOe4tobV)UO(c6j~Qebia>oNW&!8cD0<7+YheVcOFl{ z);_ucYD1YP*t2?ov3on1Dzts$lB=@>s13`+Z`V&Q9!-kAH=832e7G|y(9rBl-wg>? zhwUCI~XNjZsEj%EW* zi-g*&+&kztc0;vy_1Hk=_7u%Ed^uNV7Xlms71qlIOn)k-&+lBQI#9i7!a)MYKq8zK zjAqoP_|GC~wm6*4{hl_!K-2uoNDzkPdWem%r5oD~jI9w~gbCx=tUgqn-5vZk{mw{ zrn9YE8`WAJES{%7id^``BSG|2WGR3Nvp@`L7LU#h10?ttg)#!+`Th&UXo_YV8J3J;0bFQw@m>FXSOl4d;@{9N8ywFAj|=fYq)$ELL_!+^iTNzuLGUN zV`s*|n-Kiyj%)dBWK{{C>cTtr*@AaTu(psvVtU&XNX2q}C3ucQzmjM!Bd z0eLA~wOpuAz6K_RH}mSgj(#VT~>zhoZ?YP>YV znyqVKd|+gOu2(!KDKqx9B&t?}bYM||qeGYWC8U4NIG#P&kDz$Ug_AWjm5l-RHfCi3 z8OH>Qf$ZMxfSgc`tWjnkn%W6gP^%aMUp)fXh&+;w@-*5PoGuPiI{VuhdS69hwpua#QeBm-@j-baGIt=P z!R);x(Uj%s*n8X zwPA8OW3Y4DHMD*hT)kZIhNQvYzl9V_H>ug7nxnLXU2=se(Lz0!&p<LmOZ$gIxht38Y5Zr=$hEAQB9z6ww><*aSYI1t%}f+uubJ+LZg9#=9(I~ zrgwpAEjs@^>9hsyoU=l%KZO|xPtdUmc+-MQ=UiXtl}fQPBo|RNz_(iV|BPpTMXLbA zrTbF4&oxYQ172y-7D7!n1-X4Foy~Hg+6#Hm0qAGJtr}}IDrcFoHs~sSFAUNIO#wDy zVHa(`mwvMRS#nA`V`k8rJ)%QN3`gh8mrrX$vP16^{gXw@z&2Lvhc+S7*TS+-u6No6 zWg5;P|avf&G1+4z3^w$hZJ^hG)8(rzapPJ>?WFk1%cf z#HHBAN;Pf7$oqCX7wf{H2rETd!1`$F0+%bKucv=YZ5S>69gUt5(>SG z0-Q70R%~-svxx-+JqJ;Dng&>CCe3s2$zDSqMOjc!;8o>YSi$=@42LQ1xV4?#L50=L z{q2Ql38@$iN@jARL34pQ1byM;kjd`+DogkSEQFBq7=Gg^#Oz#6I+M;Q1_M6UvY@ZF*4oS@DFh&Eva9q}gNV&iZ_&fSus=(oup_ z+CD@Zk7NV1tr?(&p379C17V5Rk1YA8uFh*S#io&}!fi+})IN5I4yGYV<;F`k% zqFU+Ttog5t;h8Y$LCb0y!9k{$a)LcUZhdom&eCMDv0JRb}FnIGs@`i7LC+TtzIn_9mAj zsKG&gxp;KFAPXl^6)HQ(G|u0UQ&`=|DoM5;*<>wexwEtA!sgx)y_Sm~{v88HQbrHn z$@*;>JlJ-`U`ux2&p@bL_+}pd+!9G{6T%~|zuiDVtfh_sLMz1$zujDZeE3Dkm(J+N z*aujFclCoT2R2B*M_xKOu+)f26Wa*xg!15%Et#)FbP|PU=nL^q7HYAgs`3DqU5mNl zWOM;i=rDyreqLG8Bhi6zag`*`-_<=+LsD!-+|i3*K?H@fXmRhGYvkW?D)M)3$MEE# zf=M2z16X@>>(_TE8Kn6_3x+K{P%vb5Aiq znwN4;e-x7E`w9gy{{y>o+%ys@9h_lqz=X1BtPKNwL`{k-mZ1OO~ zz0l$DK9S+7a6V z4x*?RgR4e z6UmA7HF)hQP*_UpYvt zJonIgT9i*c50i-d4wY9HLvo3Y4T1%-fgc5bZS;{SSNNlA?0q04EAWLLx$H`2!n!60d4|&3fG^{CeKZe%MYNsCsDE z^R@52nc33xo%Tg_cdPL8vsI1?GM!g;ubRfGqjfKRMdVeX>zYbsTD5n!QQm#LyIpMv zzG8^;&e?;bzK5x^Lr?W5Sp2Z|g`GIql8xG17cv=Nsh*tCwQ7fEM>yunOnXqtLw z_U`u0si5e6NraJ4q;6TpVmVkN8EDY_OZi`A-0>q?26t&)+xWI{jBIqIpJFz_@ za-5Q5-$~L^dm1T9rW5R@)ZoILKs3O(Gkb+~P@5k)32a3MBELJZs&_RB#WUo@IU?ui z0J?#hkY{~G?r8etWDY{fCHRXW0K3zrv8s%{L2iix;jaUepr4ETg8opyoQFVfT{ClRbI6RVmuc&t#F(SJ=DFC$&wc@W44qWg0 zL`$-}Y9zvAgl2Q(|3m&_#((yn=a_`bn+cN>2Mps*4*k=A5yE&^}Dq#^o#hR0Rvd~$a$aj_FvVWnJ3kL;r%i)!FPz4Zf%&DY`HA( zu$ojN4KO6eFQl%WGp|^zXu%}P1uEjU%$MTSp}@J|&+X!rijmlSJb9c zJF8uJfpUfL_^=bP$zElToX^6_w^E7(Xu-Va*oB(0ki}1#TuSNS!+bRdFWt#NaFI%pWX^ z?1}deUYppSc5HIG|>}9F+|MC-HF_AulEmQ?`+}>C77|P@e4frj<>xIJThN)oT7;;%Hx~_s*W? LgEpxA=H})v6o}qY literal 0 HcmV?d00001 diff --git a/arc/ar2:c/PART6 1 b/arc/ar2:c/PART6 1 new file mode 100644 index 00000000..f77a54b8 --- /dev/null +++ b/arc/ar2:c/PART6 1 @@ -0,0 +1,298 @@ + SCHEDULING THE INSTALLATION OF EQUIPMENT + + It is the scheduler's job to coordinate the deliveries of +machines. Scheduling is a complex business: each order for a machine +involves a separate planning operation that starts when the order is +placed, and becomes progressively more detailed as the day of +installation approaches. Much of the subtlety of the scheduling +process lies in the careful accumulation by the scheduler of +information about each machine to be installed. + + The scheduler must take care not only of installations, but +also of upgrades and cancellations. In this section we describe only +the procedures associated with the installation of equipment, we did +not have the time to study and describe the procedures relating to +cancellations. + +S_c_h_e_d_u_l_i_n_g_ _i_n_v_o_l_v_e_s_ _t_h_e_ _f_o_l_l_o_w_i_n_g_ _s_i_x_ _s_t_e_p_s_:_ + + BATCHING. Machines are installed about one month after the +date of order. As soon as the order has been placed, and has been +through the Equipment Order Entry (EOE) process, the Order Package +containing the relevant documents is sent to the scheduler. A Strip +Board, summarizing the details of each machine installation, is +maintained for quick reference, and the first operation is to prepare +a fresh strip for the new order. Details of the supplies +to accompany the machine installation are sent to the +Regional Distribution Center (RDC), so that they can be delivered well +before the machine arrives. Then the Order Package is filed in the +Open Order file. + + ALLOCATION. Every week the scheduler receives from the Region +Headquarters a Weekly Allocation Sheet. This sheet is received two +weeks in advance of the period to which it refers, and shows how many +machines of each type will be available to the Branch for installation +during the week in question. The scheduler maintains an E_q_u_i_p_m_e_n_t_ +C_o_n_t_r_o_l_ L_o_g_ (ECL), arranged by machine type, showing each installation +and its projected date. The weekly Allocation sheet is used to add +new entries to this log. + + ROUGH SCHEDULING. Every day the scheduler plans the +deliveries of machines for the corresponding day two weeks hence. She +works through the Strip Board and the ECL, compiling a list of the +machines that can be installed that day. The list of deliveries for +each day is entered on a form called the Pick-and-Pull (P&P). This +form eventually generates the instructions to the rigger, the person +who actually delivers the machine. A fresh Strip Board is prepared +containing all the strips for the day's deliveries. + + DETAILED SCHEDULING. After making up the list of deliveries, +the scheduler goes through the Open Order file, pulling out the +relevant Order Packages, checking them and transfering them to a +separate Open Order file. + + REPORTING. After all the day's scheduling is done, various +people must be notified. Copies are made of the daily Strip Board, of +the Pick-and-Pull, and of the Work Orders that show details of each +order. These are sent to the rigger and to certain managers., and are +also posted in several places in the Branch Office. The Pick-and-Pull +is sent to the E_q_u_i_p_m_e_n_t_ _L_o_g_i_s_t_i_c_s_ _C_e_n_t_e_r_ (ELC), the warehouse from +which deliveries are made. + + AUDITING. The scheduler receives a daily report from the +rigger, indicating the machines he has installed the previous day. +She checks this against the Pick-and-Pull, and then transfers the +appropriate strips to a new Strip Board showing those machines that +are Shipped/Not Installed (SNI). Likewise, the Order Packages for +these installations are moved to a special Shipped/Not Installed Open +Order file. + + +B_A_T_C_H_I_N_G_ + + The Batching operation is the +only phase during scheduling that requires the service of a typist; +the actual typing is done by the Branch receptionist. + + 1. Order Packages are received one by one after they have +been through the EOE (Equipment Order Entry) process. These packages, +each in a manila folder, include the COED (Customer Order Entry +Document), the service agreement and the purchase order made out by +the customer. A batch of Order Packages is made up and given to the +receptionist. + + 2. The receptionist types a strip for each order and places +the strip in the folder. + + 3. The batch of Order Packages returns to the scheduler. + + 4. The strip is removed and is inserted on the Strip Board +for the appropriate machine type (SB/MT). + + 5. The Order Package is stacked on one side for later filing. + + 6. The COED includes an Initial Supply Order (ISO), a list of +supplies to be provided when the machine is installed. The +appropriate part of the COED is copies, and the copy is placed in a +batch of ISO's. The COED number, a unique number stamped on each +blank COED form, is written on the batch cover sheet. + + 7. The Order Packages are filed in the Open Order drawer, a +single file drawer. The front part of this drawer is devoted to +unscheduled orders such as this one, and is subdivided by machine +type. Behind are the Daily (OO/D) and Shipped/Not Installed (OO/SNI) +sections of the Open Order drawer. + + 8. At the end of the day, the ISO Batch is completed: the +batch size is entered on the cover sheet, and a copy of the cover +sheet is made and filed. + + 9. The ISO Batch is mailed to the Regional Distribution +Center. + +A_L_L_O_C_A_T_I_O_N_ + + Allocation is performed with the aid +of a Weekly Allocation Sheet received two weeks in advance from Region +Headquarters. A typical such sheet shows +the weekly allocations for several other branches. The scheduler uses +a felt pen to outline the column for the easier reference. + + The main purpose of Allocation is to open up fresh entries in +the E_q_u_i_p_m_e_n_t_ _C_o_n_t_r_o_l_ _L_o_g_ _(_E_C_L_)_. Each page of the ECL is devoted to a +single type of machine; each machine installation is given one line, +which will eventually show the serial number, COED number and customer +name. At the time the weekly allocations are first +made, however, the serial numbers of the machines are not known, and +at this stage no attempt is made to assign names or COED numbers +either. + + Later on, after the machines have been scheduled in detail, a +Monthly Allocation Report is received from the Region Headquarters: +this repeats the information given in the weekly allocations, and also +includes serial numbers. It is used for checking purposes. + + 10. After studying the Weekly Allocation Sheet, the scheduler +selects each machine type in turn, and consults her Equipment Control +Log. + + 11. According to the number in the allocation, the +appropriate number of lines are opened up in the log, for filling in +later when daily scheduling is done. + + 12. The Weekly Allocation Sheet is filed. + + 13. Every month the scheduler receives the Monthly Allocation +Report. The entries are compared, by serial number, with the +entries in the ECL. + + 14. The Monthly Allocation Report is filed. + +R_O_U_G_H_ _S_C_H_E_D_U_L_I_N_G_ _F_O_R_ _I_N_S_T_A_L_L_A_T_I_O_N_ _2_ _W_E_E_K_S_ _H_E_N_C_E_ + + It is during the first phase of daily scheduling +that orders are selected for installation on a day exactly +two weeks hence. This operation involves a good deal of knowledge +about the installation operation - which Technical Representative can +install which type of machine, which machines are particularly +difficult and time-consuming to install, and so forth. + + 15. A Pick-and Pull is prepared for the day's deliveries. +The scheduler fills in the control number (allocated sequentially), +the Branch number, the name of the rigger and the installation date. + + 16. Taking the Strip Board for the machine type in question, +the scheduler selects the top most strip on the board and attempts to +schedule it. Installations are never made until at least three weeks +have elapsed from placing the order; therefore strips representing +orders less than a week old are not selected. + + 17. The scheduler consults the ECL to determine whether the +machine can be installed. + + 18. If the order can be scheduled, the customer name and COED +number are entered in the ECL. + + 19. The serial number and allocation week are copied from the +ECL to start a fresh entry on the Pick-and-Pull. + + 20. The COED number and customer name are entered from the +strip onto the Pick-and-Pull. The first three digits of the serial +number are also entered, since these are invariant for any one machine +type. + + 21. The strip is transfered to a fresh Strip Board for the +day in question. + +D_E_T_A_I_L_E_D_ _S_C_H_E_D_U_L_I_N_G_ _F_O_R_ _I_N_S_T_A_L_L_A_T_I_O_N_S_ _2_ _W_E_E_K_S_ _H_E_N_C_E_ + + 22. For each entry on the Strip Board, starting at the +bottom, the corresponding Order Package is retrieved from the Open +Order drawer: the machine type identifies the folder in which to +look, and generally the package will be near the back of that section. + + 23. The Order Package is checked, and a copy is made of the +Work Order which consists of the top one-third of each side of the +COED; the COED is designed so that it can be folded to present both +sections simultaneously to the copier. + + 24. The Order Package is placed on one side. + + 25. The Work Order copies are also placed on one side. + + 26. When the day's installations have been handled, the +packages are placed in a special section of the Open Order drawer, +devoted to that day' installations. + +R_E_P_O_R_T_I_N_G_ _I_N_S_T_A_L_L_A_T_I_O_N_S_ _S_C_H_E_D_U_L_E_D_ + + The Pick-and-Pull is not used during the Detailed Scheduling +phase, but after the daily scheduling is complete it must be sent to +the Equipment Logistics Center. The rigger also needs it, together +with copies of the Work Orders to tell him exactly where to install +each copier. In addition, the scheduler posts copies of the Daily +Strip Boards for the benefit of Technical Representatives, and keeps +various members of the Branch management informed about installation +scheduling. + 27. Twelve copies are made of the daily Strip Board; eight +of these are for inclusion in sets of documents sent to Branch +managers; the remaining four are posted around the Branch Office. + + 28. The day's Work Orders are copied and made into batches +for distribution. + + 29. The Pick-and-Pull is telecopied to the ELC. + + 30. A copy is made for the rigger of the Pick-and-Pull, which +is then filed in a folder. + + 31. The copied documents are made up into batches, and +distributed. + +A_U_D_I_T_I_N_G_ + + Auditing takes place on the day +following installation, when a report is received from the rigger +listing the machines he installed the previous day. This report +provides, for the first time, the serial numbers of the machines +installed. In this final stage of scheduling, the rigger's report is +checked against the Pick-and-Pull for the day, serial numbers are +copied into the ECL, any errors detected are resolved, and the orders +are tansfered from Daily to Shipped/Not Installed (SNI) status. The +Rigger Report, includes other details besides impending deliveries, +but these do not relate to our study. + + 32. The Rigger Report, received via Telecopier, is checked +against the Pick-and-Pull folder. Entries are identified by COED +number. Generally all the entries on the Rigger Report are to be +found on a single day's P&P, but rigger delays and coordination +problems may cause discrepancies, and the scheduler may have to go +back to the folder for ohther P&P's. + + 33. The COED number is also used to find the machine's entry +in the ECL. The serial number is copied from the Rigger Report to the +ECL. + + 34. The customer name is copied from the P&P to the Rigger +Report entry. + + 35. Using the customer name as key, the scheduler finds the +corresponding strip on the Daily Strip Board and transfers it to the +SNI Strip Board. + + 36. Order Packages are Likewise located and transfered to the +SNI section of the Open Order drawer. + + 37. The scheduler goes to the terminal and enters the +`Equipment Received' data from the Rigger Report. + + 38. The Rigger Report is filed in a folder. + +C_O_N_C_L_U_S_I_O_N_ + + Installation Scheduling is carried out almost entirely by one +person. Schedulding involves both routine paper work and complex +decision-making, and exhibits an interesting interplay of logs, files +and strip boards. + +G_L_O_S_S_A_R_Y_ _O_F_ _A_C_R_O_N_Y_M_S_ + +COED Customer Order Entry Document +ECL Equipment Control Log +ELC Equipment Logistics Center +EOE Equipment Order Entry +ISO Initial Supply Order +MT Machine Type +OO Open Order file +OO/D Open Order, Daily file +OO/MT Open Order, filed by Machine Type +OO/SNI Open Order file, Shipped/Not Installed +P&P Pick-and-Pull +RDC Regional Distribution Center +SB Strip Board +SB/D Strip Board, Daily +SB/MT Strip Board, arranged by Machine Type +SB/SNI Strip Board, Shipped/Not Installed +SNI Shipped/Not Installed + + \ No newline at end of file diff --git a/arc/ar2:c/SCHED 1 b/arc/ar2:c/SCHED 1 new file mode 100644 index 0000000000000000000000000000000000000000..01794c1c36715a7bea7b566e875542390a6f6ff4 GIT binary patch literal 840 zcmbW0!ES>v42IEeL*pI%0M&NiP8)4cosi0;oii{cYDiELRQ2s=2iQtWH>uo+gZ=;C zZ?;%q>!s1s`6LEo zSNf5VUgwoM_xS9ky#C}0d62^X=8T+eabvWvr&cVs#`+8W<9Y|twAAe52nXqFaA>7a Upu6Uaeu+lVQuE5vLPb&Z4I ac create empty array + ac_alloc (size) => ac create empty array, preferred size + ac_create (string) => ac create with initial value + ac_xh (ac, c) => c extend array with character + ac_trim (ac) => ac trim excess storage + ac_fetch (ac, i) => c fetch character from array + ac_link (ac) => ac make new link to array + ac_unlink (ac) remove link to array + ac_puts (ac, f) print array + ac_cat (ac, ac) => ac concatenate arrays + ac_copy (ac) => ac copy array + ac_string (ac) => *char return string version + ac_size (ac) => size return current size of array + ac_flush (ac) make array empty + ac_n () => int return # of active arrays + +*/ + +struct rep { + int count; /* reference count */ + char *s; /* pointer to actual array */ + int csize; /* logical size of array */ + int msize; /* physical size of array (at least csize+1) */ + }; + +# define ac struct rep* /* watch usage! */ +# define ASIZE 4 /* number of words in rep */ +# define initial_size 8 /* default initial allocation */ + +char *calloc (); +int *salloc (); +ac ac_new(); +ac ac_alloc(); +ac ac_create(); +ac ac_link(); +ac ac_cat(); +ac ac_copy(); + +static int count; + +/********************************************************************** + + AC_NEW - Create empty array. + AC_ALLOC - Create empty array, preferred size given. + +**********************************************************************/ + +ac ac_new () + + {return (ac_alloc (initial_size));} + +ac ac_alloc (sz) + + {ac a; + + if (sz<0) sz=0; + a = salloc (ASIZE); + a->count = 1; + a->csize = 0; + a->msize = sz+1; + a->s = calloc (a->msize); + ++count; + return (a); + } + +/********************************************************************** + + AC_CREATE - Create array with initial value. + +**********************************************************************/ + +ac ac_create (s) char s[]; + + {register char *p; + register int sz; + register ac a; + + sz = slen (s); + a = ac_alloc (sz); + a->csize = sz; + p = a->s; + while (--sz >= 0) *p++ = *s++; + return (a); + } + +/********************************************************************** + + AC_XH - Extend Array with Character. + +**********************************************************************/ + +char ac_xh (a, c) register ac a; + + {register char *p, *q; + char *old; + int i; + + if ((i = a->csize) >= a->msize-1) + {old = p = a->s; + a->s = q = calloc (a->msize =* 2); + while (--i >= 0) *q++ = *p++; + if (old) cfree (old); + } + a->s[a->csize++] = c; + return (c); + } + +/********************************************************************** + + AC_TRIM - Discard excess storage. + +**********************************************************************/ + +ac ac_trim (a) register ac a; + + {register char *p, *q; + char *old; + int i; + + if ((i = a->csize) < a->msize-1) + {old = p = a->s; + a->s = q = calloc (a->msize = a->csize + 1); + while (--i >= 0) *q++ = *p++; + if (old) cfree (old); + } + return (a); + } + +/********************************************************************** + + AC_FETCH - Fetch Character from Array. + +**********************************************************************/ + +char ac_fetch (a, n) ac a; + + {extern int cerr; + if (n<0 || n>=a->csize) + {cprint (cerr, "Character array bounds error."); + return (0); + } + return (a->s[n]); + } + +/********************************************************************** + + AC_LINK - Create link to array. + +**********************************************************************/ + +ac ac_link (a) ac a; + + {++a->count; + return (a); + } + +/********************************************************************** + + AC_UNLINK - Remove link to array. + +**********************************************************************/ + +ac_unlink (a) ac a; + + {if (--a->count == 0) + {if (a->s) cfree (a->s); + --count; + sfree (a); + } + } + +/********************************************************************** + + AC_PUTS - Print array. + +**********************************************************************/ + +ac_puts (a, f, wid) ac a; /* 3 args for cprint usage */ + + {register char *p; + register int i; + + p = a->s; + i = a->csize; + while (--i >= 0) cputc (*p++, f); + } + +/********************************************************************** + + AC_CAT - Concatenate arrays. + +**********************************************************************/ + +ac ac_cat (a1, a2) ac a1; ac a2; + + {register ac a; + register char *p, *q; + int i; + + a = ac_alloc (i = a1->csize + a2->csize); + a->csize = i; + p = a->s; + q = a1->s; + i = a1->csize; + while (--i>=0) *p++ = *q++; + q = a2->s; + i = a2->csize; + while (--i>=0) *p++ = *q++; + return (a); + } + +/********************************************************************** + + AC_COPY - Copy array. + +**********************************************************************/ + +ac ac_copy (a1) ac a1; + + {register ac a; + register char *p, *q; + int i; + + a = ac_alloc (i = a1->csize); + a->csize = i; + p = a->s; + q = a1->s; + while (--i >= 0) *p++ = *q++; + return (a); + } + +/********************************************************************** + + AC_STRING - Return string version of array. The returned + string is valid only while the array remains linked + to and unchanged. + +**********************************************************************/ + +char *ac_string (a) ac a; + + {a->s[a->csize]=0; + return (a->s); + } + +/********************************************************************** + + AC_SIZE - Return current size of array. + +**********************************************************************/ + +int ac_size (a) ac a; + + {return (a->csize);} + +/********************************************************************** + + AC_FLUSH - Make array empty + +**********************************************************************/ + +ac_flush (a) ac a; + + {a->csize = 0;} + +/********************************************************************** + + AC_N - Return number of active arrays. + +**********************************************************************/ + +int ac_n () {return (count);} + + \ No newline at end of file diff --git a/arc/ar2:clib/ALLOC CMID b/arc/ar2:clib/ALLOC CMID new file mode 100644 index 00000000..5c2f7d7f --- /dev/null +++ b/arc/ar2:clib/ALLOC CMID @@ -0,0 +1,225 @@ +; +; ALLOC - C FREE STORAGE ROUTINES +; +; This file is PDP-10 dependent, system independent. +; +; CALLOC (SIZE) => *CHAR ; ALLOCATE ZEROED CHARACTERS +; SALLOC (SIZE) => *INT ; ALLOCATE ZEROED WORDS +; CFREE (*CHAR) ; RETURN CHARACTERS +; SFREE (*INT) ; RETURN WORDS +; +; AFREE (SIZE) => (ADDR) ; ALLOCATE GARBAGE WORDS +; AFRET (ADDR, SIZE) ; DEALLOCATE WORDS +; AFREZ (SIZE) => (ADDR) ; ALLOCATE AND ZERO WORDS +; +; ALOCSTAT (&NWALLOC, &NBFREE) => NWFREE ; COMPUTE STATS +; + +TITLE ALLOC +.INSRT NC +.INSRT NM + + +; THESE ARE STORAGE-ALLOCATION ROUTINES WITH SOME PROTECTION + +CENTRY CALLOC,[NWORDS] ; ALLOCATE CHARACTERS +XENTRY SALLOC,CALLOC ; ALLOCATE WORDS + + SKIPL A,NWORDS ; DON'T ADD TO BAD SIZE + ADDI A,2 ; FOR HEADER WORDS + CALL AFREZ,[A] + ADDI A,2 ; POINTER TO USER AREA OF BLOCK + MOVE B,NWORDS + MOVEM B,-1(A) ; STORE SIZE IN HEADER + MOVE B,A + ADD B,[147506732514] + MOVEM B,-2(A) ; MAGIC WORD IN HEADER + RETURN + +CENTRY CFREE,[PTR] ; RETURN CHARACTERS +XENTRY SFREE,CFREE ; RETURN WORDS + + MOVE A,PTR + MOVE B,-2(A) + SUB B,A + CAME B,[147506732514] + GO CF$BAD + MOVEI A,-2(A) + MOVE B,1(A) + ADDI B,2 + CALL AFRET,[A,B] + SETZ A, +CF$RET: RETURN +CF$BAD: CROAK BAD CALL TO CFREE/SFREE + SETO A, + GO CF$RET + + +.IDATA +MDATA FNWORDS ; NUMBER OF WORDS ALLOCATED + 0 +MDATA FLIST + FLIST+1 ; LIST OF FREE BLOCKS + 0 +.CODE +; +; AFREE - ALLOCATE STORAGE +; + +CENTRY AFREE,[BSIZE] +XENTRY GETVEC,AFREE + + MOVE A,BSIZE + JUMPLE A,AE$BAD ; SIZE MUST BE POSITIVE + CAIL A,400000 ; SIZE MUST BE REASONABLE + GO AE$BAD + HRLZI D,(A) ; SIZE IN LEFT HALF FOR COMPARISON + MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B + HRRZ C,(B) ; CURRENT BLOCK ADDR IN C +A1: CAMG D,(C) ; IS CURRENT BLOCK BIG ENOUGH? + GO A3 ; YES + MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN C,A1 ; BLOCK EXISTS => LOOP + HLRZ B,D ; DESIRED SIZE IN B + PPUSH B ; SAVE SIZE NEEDED + CALL GETCORE,[B] ; ALLOCATE NEW BLOCK (SIZE,,ADDR) + HLRZ B,A ; SIZE OBTAINED + HRRZ A,A ; ADDRESS OF BLOCK + PPOP D ; SIZE NEEDED + SUBI B,(D) ; HOW MUCH EXTRA OBTAINED? + JUMPE B,AE$RET ; NO EXCESS => DONE + PPUSH A ; ADDRESS OF BLOCK + ADDM B,(P) ; ADDRESS OF DESIRED PART OF BLOCK + CALL AFRET,[A,B] ; RETURN THE EXCESS + PPOP A ; ADDRESS OF DESIRED PART OF BLOCK + GO AE$RET ; DONE + +; HERE WHEN A SUFFICIENTLY LARGE BLOCK FOUND IN LIST + +A3: HLRZ D,D ; DESIRED SIZE IN D + HLRZ A,(C) ; SIZE OF BLOCK IN LIST + SUBI A,(D) ; EXCESS + JUMPE A,A4 ; NO EXCESS => DELETE BLOCK FROM LIST + HRLM A,(C) ; NEW BLOCK SIZE + ADDI A,(C) ; ADDRESS OF DESIRED PART OF BLOCK + GO AE$RET ; DONE + +; HERE WHEN ENTIRE BLOCK IS TO BE REMOVED FROM THE LIST + +A4: HRRZ A,(C) ; NEXT BLOCK IN LIST + HRRM A,(B) ; CHAIN TO PREVIOUS BLOCK + MOVEI A,(C) ; RETURN THIS BLOCK + GO AE$RET ; DONE + +AE$BAD: CROAK AFREE CALLED WITH BAD SIZE ARGUMENT + SETZ A, +AE$RET: RETURN ; DONE + +; +; AFRET - DEALLOCATE STORAGE +; + +CENTRY AFRET,[PTR,BSIZE] + + MOVE A,PTR + MOVE B,BSIZE + JUMPLE B,CODE [ ; SIZE MUST BE POSITIVE + CROAK AFRET CALLED WITH BAD SIZE ARGUMENT + GO ARRET + ] + MOVEI C,FLIST ; ADDRESS OF PREVIOUS BLOCK IN C + HRRZ D,(C) ; ADDRESS OF CURRENT BLOCK IN D +A5: CAIG A,(D) ; FIND PLACE IN LIST + GO A8 ; NEW BLOCK GOES HERE + MOVEI C,(D) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ D,(D) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN D,A5 ; BLOCK EXISTS => LOOP + +; HERE TO INSERT NEW BLOCK AFTER A GIVEN BLOCK IN LIST + +A6: HLRZ D,(C) ; SIZE OF OLD BLOCK + ADDI D,(C) ; END OF OLD BLOCK + CAIGE A,(D) ; OVERLAP WITH PREVIOUS BLOCK ? + GO CODE [ ; YES, ERROR + CROAK AFRET CALLED WITH BAD ADDRESS + GO ARRET + ] + CAIN A,(D) ; CONTIGUOUS WITH PREVIOUS BLOCK ? + GO A7 ; YES, GO MERGE THEM + HRRZ D,(C) ; ADDRESS OF NEXT BLOCK (IF ANY) + HRLI D,(B) ; SIZE OF BLOCK BEING FREED (IN LEFT HALF) + MOVEM D,(A) ; MAKE DOPE WORD OF BLOCK BEING FREED + HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK + GO ARRET ; DONE + +; HERE TO MERGE BLOCK WITH PREVIOUS BLOCK (ADDR IN C) + +A7: HLRZ D,(C) ; SIZE OF OLD BLOCK + ADDI D,(B) ; ADD SIZE OF BLOCK BEING FREED + HRLM D,(C) ; STORE NEW SIZE IN OLD BLOCK + GO ARRET ; DONE + +; HERE IN INSERT NEW BLOCK IN MIDDLE OF LIST + +A8: MOVEI 0,(A) ; ADDRESS OF NEW BLOCK + ADDI 0,(B) ; END OF NEW BLOCK + CAILE 0,(D) ; OVERLAP WITH NEXT BLOCK ? + GO CODE [ ; YES, ERROR + CROAK AFRET CALLED WITH BAD ADDRESS + GO ARRET + ] + CAIE 0,(D) ; CONTIGUOUS WITH NEXT BLOCK ? + GO A6 ; NO, APPEND TO PREVIOUS BLOCK + MOVS 0,(D) ; SWAPPED DOPE WORD OF NEXT BLOCK + ADDI 0,(B) ; SIZE OF COMBINED BLOCK + MOVSM 0,(A) ; MAKE DOPE WORD OF COMBINED BLOCK + HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK + HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK + ADDI D,(C) ; END OF PREVIOUS BLOCK + CAIE D,(A) ; CONTIGUOUS WITH PREVIOUS BLOCK ALSO ? + GO ARRET ; NO, DONE + HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK + ADDI 0,(D) ; SIZE OF COMBINED BLOCK + MOVSM 0,(C) ; MERGE AGAIN +ARRET: RETURN ; DONE + + +; +; AFREZ - ALLOCATE ZEROED BLOCK +; + +CENTRY AFREZ,[BSIZE] + + CALL AFREE,[BSIZE] ; ALLOCATE A BLOCK + SETZM (A) ; ZERO FIRST WORD + MOVE B,BSIZE ; THE SIZE + SOJE B,AZRET ; NUMBER OF WORDS REMAINING TO BE ZEROED + ADDI B,(A) ; LAST WORD OF BLOCK + HRLZI C,(A) ; FIRST WORD OF BLOCK (LEFT HALF) + HRRI C,1(A) ; SECOND WORD OF BLOCK (RIGHT HALF) + BLT C,(B) ; TRANSFER ZEROES +AZRET: RETURN ; DONE + +; +; ALOCSTAT - COMPUTE ALLOCATION STATISTICS +; + +CENTRY ALOCSTAT,[PNALOC,PNBFREE] + + MOVE A,FNWORDS ; NUMBER ALLOCATED + MOVEM A,@PNALOC + SETZ A, ; ZERO SUM OF FREE BLOCK SIZES + SETZM @PNBFREE ; ZERO COUNT OF FREE BLOCKS + MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B + HRRZ C,(B) ; CURRENT BLOCK ADDR IN C +A9: HLRZ D,(C) ; GET SIZE OF BLOCK + ADD A,D ; ADD TO SUM + AOS @PNBFREE + MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN C,A9 ; BLOCK EXISTS => LOOP + RETURN + +END + \ No newline at end of file diff --git a/arc/ar2:clib/APFNAM C b/arc/ar2:clib/APFNAM C new file mode 100644 index 00000000..b9567a3f --- /dev/null +++ b/arc/ar2:clib/APFNAM C @@ -0,0 +1,26 @@ +/********************************************************************** + + APFNAME - Append suffix to file name + +**********************************************************************/ + +char *apfname (dest, source, suffix) + char *dest, *source, *suffix; + + {fnsfd (dest, source, 0, 0, 0, suffix, "", ""); + return (dest); + } + +/********************************************************************** + + FNMKOUT - Make output file name + +**********************************************************************/ + +char *fnmkout (dest, source, suffix) + char *dest, *source, *suffix; + + {fnsfd (dest, source, "", 0, 0, suffix, "", ""); + return (dest); + } + \ No newline at end of file diff --git a/arc/ar2:clib/ATOI C b/arc/ar2:clib/ATOI C new file mode 100644 index 00000000..827ff5ae --- /dev/null +++ b/arc/ar2:clib/ATOI C @@ -0,0 +1,17 @@ +/********************************************************************** + + ATOI - Convert string to Integer + +**********************************************************************/ + +int atoi (s) char s[]; + + {int i, f, c; + + if (!s) return (0); + i = f = 0; + if (*s == '-') {++s; ++f;} + while ((c = *s++)>='0' && c<='9') i = i*10 + c-'0'; + return (f?-i:i); + } + \ No newline at end of file diff --git a/arc/ar2:clib/BLT CMID b/arc/ar2:clib/BLT CMID new file mode 100644 index 00000000..8beb4934 --- /dev/null +++ b/arc/ar2:clib/BLT CMID @@ -0,0 +1,21 @@ +; +; BLT +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE BLT +.INSRT NC +.INSRT NM + +CENTRY BLT,[FROM,TO,NUM] + + HRRZ A,TO + HRRZI B,-1(A) + ADD B,NUM + HRL A,FROM + BLT A,(B) + RETURN + +END + \ No newline at end of file diff --git a/arc/ar2:clib/C DEFS b/arc/ar2:clib/C DEFS new file mode 100644 index 00000000..f408eb25 --- /dev/null +++ b/arc/ar2:clib/C DEFS @@ -0,0 +1,58 @@ +/* + + C Standard Definitions + +*/ + +# define ITS ITS +# define AI AI + +/* data types */ + +struct _filespec {int dev, fn1, fn2, dir;}; +# define filespec struct _filespec + +# define channel int + +struct _cal {int year, month, day, hour, minute, second;}; +# define cal struct _cal + +struct _tag {int *pc, *fp, *ap, *sp;}; +# define tag struct _tag + + +/* common values */ + +# define TRUE 1 +# define FALSE 0 + +# define OPENLOSS -1 /* returned by COPEN if lose */ + +/* C interrupts */ + +# define INT_DEFAULT 0 +# define INT_IGNORE 1 + +# define mpv_interrupt 1 +# define ioc_interrupt 2 +# define ilopr_interrupt 3 +# define mar_interrupt 4 +# define utrap_interrupt 5 +# define pure_interrupt 6 +# define wiro_interrupt 7 + +# define sys_down_interrupt 8 +# define clock_interrupt 9 +# define timer_interrupt 10 +# define pdlov_interrupt 11 +# define ttyi_interrupt 12 +# define cli_interrupt 13 +# define overflow 14 +# define float_overflow 15 + +# define channel0_interrupt 16 +# define inferior0_interrupt 32 + +# define ctrls_interrupt 41 +# define ctrlg_interrupt 42 + \ No newline at end of file diff --git a/arc/ar2:clib/C INFO b/arc/ar2:clib/C INFO new file mode 100644 index 00000000..c0c1deb2 --- /dev/null +++ b/arc/ar2:clib/C INFO @@ -0,0 +1,139 @@ +C Info (30 July 1979) + +--- C --- + +C is an implementation language, similar to BCPL except with data +types. It is the primary language used in the Unix operating system. +This implementation runs on the ITS and TOPS-20 operating systems. +(The ITS implementation exists only on DM.) This implementation is +moderately compatible with the Unix C implementation. The Unix +system calls are NOT implemented. Some implemented library routines +are described below. + +Further information is available from Eliot Moss (EBM@XX). + +--- Compiling --- + +CC is the C compiler command. Usage is + + :cc file1.c file2.c ... + +where the arguments are the path names of C source files which are to +be compiled. Each file will be compiled in turn, and if the compilation +is successful, the resulting relocatable file will be placed in the file +"file*.stk". [The ITS compiler currently produces "file*.rel". This will +soon be changed.] Arguments beginning with the '-' character are taken +to be compiler options. Available options include: + + -c compile only, do not assemble + -g do not delete MIDAS file + -x syntax check only + -s produce a symbol table listing + -b compile big function (FUNCTION TOO LARGE) + +For example, the command + + :cc foo.c + +would compile the C program in the file "foo.c" ("FOO C" on ITS) in the +current directory, and place the resulting relocatable program in the file +"foo.stk" ("FOO STK" on ITS). + +--- Loading --- + +Relocatable programs produced by the C compiler are loaded together +with the C support routines using the STINKR loader. To load program +files "foo", "bar", and "bletch" and produce a runnable file "foo", +type the following to STINKR: + + (TOPS-20: (ITS: + + x clib x c/clib + l foo l foo + l bar l bar + l bletch l bletch + o foo.exe o ts.foo + ^Z ^@ + +The ^@ (ASCII NUL) or ^Z terminates the terminal input file. +The ^Z must be followed by a CR. These commands (minus the ^@) +could also be written in a file, say "foo.stinkr" ("FOO STINKR" +on ITS), in which case one could invoke STINKR with "foo" as a +JCL argument and STINKR would read the commands from the +command file. + +--- Library --- + +The above STINKR commands will load in a set of library routines +for performing I/O, etc. These routines are similar to the +Unix "Portable I/O Library". A brief description of the most useful +routines follows: + +char c; /* an ASCII character */ +int i, n, cc; /* an integer */ +int *p; /* an integer pointer */ +int b; /* a boolean */ +char *s, *s1, *s2; /* strings */ +char *fn; /* an ITS file name or a path name */ +int fd; /* a "file descriptor" */ + +fd = copen (fn, mode, options); /* open file */ + char mode; /* 'r', 'w', or 'a' (append) */ + char *options; /* 0 (char I/O), "s" (string file), "b" (binary) */ + /* for string file, pass string as fn */ + /* returns -1 if open fails */ + +extern int cin; /* standard input - pre-existing */ +extern int cout; /* standard output - pre-existing */ +extern int cerr; /* standard error ouput - pre-existing */ + +c = cgetc (fd); /* get character; returns 0 if eof */ +c = cputc (c, fd); /* put character */ +b = ceof (fd); /* test for end of file */ +cclose (fd); /* close file */ + +c = getchar (); /* equivalent to cgetc(cin) */ +putchar (c); /* equivalent to cputc(c,cout) */ + +gets (s1); /* read string (line) from cin */ +puts (s1); /* put string and newline to cout */ + +cprint (fd, format, arg...); /* formatted print routine */ + /* the format is a string which may contain format items + of the form %nf, where n is an optional decimal integer + (the minimum field width) and f is one of the following + characters: + + d - print next arg (an integer) in decimal + o - print next arg (an integer) in octal + s - print next arg (a string) + c - print next arg (a character) + + The file descriptor FD can be omitted, in which case + COUT is used. + */ + +i = cgeti (fd); /* get integer (binary input) */ +i = cputi (i, fd); /* put integer (binary output) */ + +b = istty (fd); /* test if file is a TTY */ + +c = utyi (); /* read char from TTY (unbuffered, no echo) */ +utyo (c); /* output char to TTY (unbuffered) */ +tyo_flush (); /* flush TTY output buffer */ + +cexit (cc); /* terminate job, closing all files */ + /* returning from "main" is equivalent */ + + /* STRING Routines */ + +i = slen (s); /* find string length */ +stcpy (s1, s2); /* copy string from S1 to S2 */ +b = stcmp (s1, s2); /* compare strings */ + +/* storage allocation */ + +p = salloc (n); /* allocate n words, return pointer to it */ +sfree (p); /* free storage allocated by salloc */ +s = calloc (n); /* allocate n characters, return ptr to it */ +cfree (s); /* free storage allocated by calloc */ diff --git a/arc/ar2:clib/C10BOO CMID b/arc/ar2:clib/C10BOO CMID new file mode 100644 index 00000000..9d829321 --- /dev/null +++ b/arc/ar2:clib/C10BOO CMID @@ -0,0 +1,56 @@ +; +; C10BOO - Bootstrapper Routine +; +; This file is ITS dependent. +; +TITLE BOOTSTRAP +.INSRT NC +.INSRT NM + +LSTART==6 ; WHERE BOOTSTRAP LOADER WILL BE MOVED TO +LCHN==15 ; LOAD FILE CHANNEL +TCHN==16 ; TTY CHANNEL + +CENTRY BOOTSTRAP,[FS] + + MOVE C,FS + SYSCAL OPEN,[MOVSI 6?MOVEI LCHN?(C)?1(C)?2(C)?3(C)],LOSE + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLZ A,OPTOPC+OPTINT ; TURN OFF OLD PC ON MPV, IOC AND + ; USE NEW INTERRUPT STACKING SCHEME + .SUSET [.SOPTI,,A] ; SET OPTION WORD + SETZM 42 ; DISABLE INTERRUPT HANDLING + SETZ A, + .SUSET [.SMASK,,A] + SETZM 41 + + .OPEN TCHN,[SIXBIT/ TTY/] + GO NOTTY + .CALL [SETZ ; TURN OFF ECHOING + 'TTYSET + 1000,,TCHN + [232222222222] + SETZ [230222220222] + ] + JFCL + +NOTTY: MOVE 0,[LOADER,,LSTART] + BLT 0,LSTART+LODLEN ; MOVE LOADER + JRST LSTART ; EXECUTE LOADER +LOSE: SETO A, + RETURN + +; +; THE LOADING PROGRAM +; + +LOADER: + .CALL [SETZ ? SIXBIT/LOAD/ ? MOVEI -1 ? SETZI LCHN] + .VALUE + .IOT LCHN,LSTART+5 ; READ STARTING ADDRESS + .CLOSE LCHN, + JRST @0 ; START PROGRAM + -1,,0 ; IOT POINTER +LODLEN==.-LOADER + +END diff --git a/arc/ar2:clib/C10COR CMID b/arc/ar2:clib/C10COR CMID new file mode 100644 index 00000000..5b635e71 --- /dev/null +++ b/arc/ar2:clib/C10COR CMID @@ -0,0 +1,54 @@ +; +; C10COR - Basic Storage Allocation +; +; This file is ITS dependent. +; + +TITLE CCORE +.INSRT NC +.INSRT NM + +.GLOBAL FNWORD + +; +; GETCORE - BASIC CORE ALLOCATOR +; +; GETCORE (SIZE) => SIZE,,ADDR +; + +CENTRY GETCORE,[BSIZE],[NPAGES,PTR] + + MOVE B,BSIZE + ADDI B,1777 + LSH B,-10. ; NUMBER OF PAGES NEEDED + MOVEM B,NPAGES + CALL PGJGET,[NPAGES] ; GET PAGES + MOVN B,NPAGES ; MINUS NUMBER OF PAGES + JUMPLE A,CODE [ + CROAK STORAGE EXHAUSTED + GO DOT + ] + MOVEM A,PTR + HRL A,B ; AOBJN POINTER TO NEW PAGES +TRYAGN: .CALL [SETZ + 'CORBLK + 1000,,300000 ; WANT READ AND WRITE ACCESS + 1000,,-1 ; PUT PAGE IN MY MAP + A ; WHERE TO PUT THEM + 401000,,400001 ; GET FRESH PAGES + ] + GO CODE [ + CROAK UNABLE TO GET CORE + MOVEI 0,30. + .SLEEP 0, + GO TRYAGN + ] + MOVE A,PTR + LSH A,10. ; POINTER TO FIRST PAGE + MOVE B,NPAGES + LSH B,10. ; NUMBER OF WORDS GOTTEN + ADDM B,FNWORDS ; SAVE FOR STATS + HRL A,B ; SIZE,,ADDR + RETURN + +END diff --git a/arc/ar2:clib/C10EXC C b/arc/ar2:clib/C10EXC C new file mode 100644 index 00000000..f82d59e6 --- /dev/null +++ b/arc/ar2:clib/C10EXC C @@ -0,0 +1,119 @@ +# include "clib/c.defs" + +int exctime 0; +int exccode 0; + +/********************************************************************** + + EXECS - Execute a program with a given command string + + Returns: + + -5 Job valretted something and was not continued. + -4 Internal fatal error. + -3 Unable to load program file. + -2 Unable to create job. + -1 Unable to open program file. + 0 Job terminated normally. + other Job terminated abnormally with said PIRQ + + Sets: + + exctime - job's CPU time in 1/60 sec. units + exccode - contents of job's loc 1 at termination + +**********************************************************************/ + +int execs (pname, args) char *pname, *args; + + {int i, j, ich; + char *s, buf[40]; + filespec f; + + j = j_fload (pname); + if (j<0) return (j); + + j_sjcl (j, args); + j_give_tty (j); + j_start (j); + + while (TRUE) + {i = j_wait (j); + j_take_tty (j); + switch (i) { + + case -1: return (-4); + case -2: i = 0; + break; + case -3: s = j_valret (j); + if (s) + {cprint ("Job valrets: "); + puts (s); + } + else + {puts ("Job .VALUE 0"); + } + cprint ("continue? "); + gets (buf); + if (buf[0]=='y' || buf[0]=='Y') + {j_give_tty (j); + j_start (j); + continue; + } + i = -5; + break; + case -5: wsuset (014, 02); /* simulate ^Z typed */ + sleep (15); + j_give_tty (j); + j_start (j); + continue; + default: cprint ("Unhandled interrupt, continue? "); + gets (buf); + if (buf[0]=='y' || buf[0]=='Y') + {j_give_tty (j); + j_start (j); + continue; + } + break; + } + break; + } + + exctime = ruset (j_ch(j), 024) / (16666000./4069.); + exccode = 0; + if (!j_name (j, &f) && (ich=open(&f,4))>=0) + {uiiot (ich); + exccode = uiiot (ich); + close (ich); + } + j_kill (j); + return (i); + } + +/********************************************************************** + + EXECV - Execute file given a vector of arguments + +**********************************************************************/ + +int execv (prog, argc, argv) + char *prog, *argv[]; + + {char **ap, **ep, buff[300], *p, *s; + int c; + + p = buff; + ap = argv; + ep = argv + argc - 1; + + while (ap <= ep) + {s = *ap++; + *p++ = '"'; + while (c = *s++) *p++ = c; + *p++ = '"'; + *p++ = ' '; + } + + *p++ = 0; + return (execs (prog, buff)); + } diff --git a/arc/ar2:clib/C10EXP C b/arc/ar2:clib/C10EXP C new file mode 100644 index 00000000..b8dc1604 --- /dev/null +++ b/arc/ar2:clib/C10EXP C @@ -0,0 +1,51 @@ +# include "c/c.defs" + +/********************************************************************** + + EXPAND ARGUMENT VECTOR CONTAINING FILE NAME PATTERNS + +**********************************************************************/ + +static char **next; +static char *bufp; + +int exparg (argc, argv, outv, buffer) + char *argv[], *outv[], buffer[]; + + {int i, expfs(); + char *s; + + bufp = buffer; + next = outv; + i = 0; + while (idev; + fs.dir = fp->dir; + fs.fn1 = fp->fn1; + fs.fn2 = fp->fn2; + n = rddir (fp, v, 04); + if (fp->fn1) c6tos (fp->fn1, pat1); + if (fp->fn2) c6tos (fp->fn2, pat2); + q = v + 2*n; + for (p=v; pfn1) + {c6tos (p[0], buf); + if (!smatch (pat1, buf)) continue; + } + if (fp->fn2) + {c6tos(p[1], buf); + if (!smatch (pat2, buf)) continue; + } + fs.fn1 = p[0]; + fs.fn2 = p[1]; + (*f)(&fs); + } + } + +/********************************************************************** + + RDIREC - Read A Directory + + S is a string specifying a directory. + V will be filled with pairs of SIXBIT names, one for each file. + The number of files is returned. + +**********************************************************************/ + +int rdirec (s, v, fs) + char *s; + int v[]; + filespec *fs; + + {fparse (s, fs); + if (!fs->dir) fs->dir = fs->fn1; + return (rddir (fs, v, 0)); + } + +/********************************************************************** + + RDDIR - Read Directory + + Return in V a list of names in the directory specified by FS. + OPT is used to filter out some files: + + if (opt & 01) no-links + if (opt & 02) no-backed-up-files + if (opt & 04) no-locked-files + +**********************************************************************/ + +int rddir (fp, v, opt) + filespec *fp; + int v[], opt; + + {int buf[DIRSIZ], f, n, i, *p, d, n1, n2; + filespec fs; + + fs.dev = fp->dev; + fs.dir = fp->dir; + fs.fn1 = _FILE_; + fs.fn2 = _PDIRP_; + if (!fs.dev) fs.dev = _DSK_; + if (!fs.dir) fs.dir = rsname(); + f = open (&fs, BII); + if (f<0) return (0); + sysread (f, buf, DIRSIZ); + close (f); + n = (DIRSIZ - buf[1]) / ENTSIZ; + p = buf+buf[1]; + i = 0; + while (--n >= 0) + {n1 = *p++; + n2 = *p++; + d = *p++ >> 18; /* random info */ + p =+ 2; + if (d & 060) continue; /* should ignore these */ + if (opt & d) continue; /* optionally ignore */ + *v++ = n1; + *v++ = n2; + ++i; + } + return (i); + } + +/********************************************************************** + + RMFD - Read the Master File Directory + + V will be filled with SIXBIT names, one for each directory, + sorted. + The number of directories is returned. + +**********************************************************************/ + +int rdmfd (v) + int v[]; + + {int ch, n, *e, *p, *q, i, j, x; + + ch = fopen ("m.f.d. (file)", BII); + if (ch<0) return (ch); + n = sysread (ch, v, DIRSIZ); + close (ch); + e = v+n; + p = v+v[1]; + q = v; + while (p DEFAULT, 1 => IGNORE, OTHER => ROUTINE ADDR) +; BITS 18-23 BIT NUMBER IN ITS MASK WORD +; BIT 24 ITS MASK WORD NUMBER + +.IDATA +MDATA TAB2 + 0 ; NOT USED + 15,,0 ; MPV + 10,,0 ; IOC + 5,,0 ; ILOPR + 16,,0 ; MAR + 27,,0 ; UTRAP + 30,,0 ; PURE + 31,,0 ; WIRO + + 6,,0 ; SYSDOWN + 14,,0 ; CLOCK + 41,,0 ; TIMER + 0 ; PDLOV (NOT USED) + 0,,0 ; TTYI + 21,,0 ; CLI + 3,,0 ; OVERFLOW + 32,,0 ; FLOATING OVERFLOW + + 100,,0 ; CHANNEL 0 + 101,,0 ; CHANNEL 1 + 102,,0 ; CHANNEL 2 + 103,,0 ; CHANNEL 3 + 104,,0 ; CHANNEL 4 + 105,,0 ; CHANNEL 5 + 106,,0 ; CHANNEL 6 + 107,,0 ; CHANNEL 7 + + 110,,0 ; CHANNEL 10 + 111,,0 ; CHANNEL 11 + 112,,0 ; CHANNEL 12 + 113,,0 ; CHANNEL 13 + 114,,0 ; CHANNEL 14 + 115,,0 ; CHANNEL 15 + 116,,0 ; CHANNEL 16 + 117,,0 ; CHANNEL 17 + + 122,,0 ; INFERIOR 0 + 123,,0 ; INFERIOR 1 + 124,,0 ; INFERIOR 2 + 125,,0 ; INFERIOR 3 + 126,,0 ; INFERIOR 4 + 127,,0 ; INFERIOR 5 + 130,,0 ; INFERIOR 6 + 131,,0 ; INFERIOR 7 + + 0 ; NOT USED + 0 ; CONTROL-S INTERRUPT + 0 ; CONTROL-G INTERRUPT + + +; +; ON - SPECIFY AN ACTION FOR A C INTERRUPT +; + +.CODE +CENTRY ON,[INTNO,NEWH] + + MOVE B,INTNO ; INTERRUPT # + JUMPLE B,ON2 ; BAD # + CAILE B,NINT ; NINT = HIGHEST VALID # + GO ON2 ; BAD # + HRRZ A,NEWH ; NEW HANDLER + CAIL B,CTRSI + GO ON1 ; SOFTWARE INTERRUPT + + LDB D,[220600,,TAB2(B)] ; BIT # + MOVEI C,1 + LSH C,(D) ; MASK + LDB D,[300100,,TAB2(B)] ; WORD # + + CAIN B,CTRGI + JUMPE A,TURNON + JUMPE A,TURNOF + CAIE A,1 + GO TURNON + CAIGE B,8. + GO TURNON + +TURNOF: .SUSET [.SAMASK,,C ? .SAMSK2,,C](D) + GO ON1 + +TURNON: .SUSET [.SIMASK,,C ? .SIMSK2,,C](D) +ON1: HRRZ C,TAB2(B) ; OLD HANDLER + HRRM A,TAB2(B) ; NEW HANDLER + MOVE A,C ; RETURN OLD HANDLER +ONRET: RETURN + +ON2: CROAK ON: INVALID INTERRUPT NUMBER + MOVEI A,1 + GO ONRET + + +; +; SIGNAL - SIGNAL A C INTERRUPT +; + +CENTRY SIGNAL,[SIGNO] + + MOVE A,SIGNO ; INTERRUPT # + JUMPLE A,S3 ; BAD # + CAILE A,NINT ; NINT = HIGHEST VALID # + GO S3 ; BAD # + HRRZ B,TAB2(A) ; HANDLER + CAIN B,1 + GO SIGRET ; 1 => IGNORE + JUMPN B,S1 ; SPECIFIED HANDLER + CAIN A,CTRGI + GO S4 ; HANDLE ^G INTERRUPT + GO SIGRET ; OTHERWISE IGNORE + +S1: CAIGE A,CH0I + GO S2 ; NO ARG + CAILE A,IN0I+7 + GO S2 ; NO ARG + CAIGE A,IN0I + SUBI A,CH0I ; ARG IS CHANNEL # + CAIL A,IN0I + SUBI A,IN0I ; ARG IS INFERIOR # + VCALL (B),[A] + GO SIGRET + +S2: CAIN A,CTRSI + CL CTRSIH ; SPECIAL ^S ACTION + CAIN A,CTRGI + CL CTRGIH ; SPECIAL ^G ACTION + VCALL (B) + GO SIGRET + +S3: CROAK INVALID INTERRUPT SIGNALLED + GO SIGRET + +S4: CL CTRGIH + CALL STKDMP + CROAK -- ^G -- +SIGRET: RETURN + +; SPECIAL HANDLER FOR CONTROL-S INTERRUPT + +IENTRY CTRSIH + + PPUSH A + PPUSH B +CTRS1: SETO B, + SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN" ? 2000,,B] + JUMPLE B,CTRS2 + CAIE B,^S + GO CTRS1 +CTRS2: PPOP B + PPOP A + RTN + +; SPECIAL HANDLER FOR CONTROL-G INTERRUPT + +IENTRY CTRGIH + + PPUSH A + PPUSH B +CTRG1: SETO B, + SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN ? 2000,,B] + JUMPLE B,CTRG2 + CAIE A,^G + GO CTRG1 +CTRG2: PPOP B + PPOP A + RTN + + +; +; DISMISS - DISMISS INTERRUPT AND RETURN TO CALLER +; + +MENTRY DISMISS + SYSCAL DISMIS,[5000,,T%CTL ? INTPTR ? 1000,,.+2] + RETURN + +; +; GETPC - GET INTERRUPTED PC +; + +CENTRY GETPC + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + HRRZ A,T%OPC(D) + RETURN + +; +; SETPC - SET INTERRUPTED PC +; + +CENTRY SETPC,[PC] + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,PC + HRRM A,T%OPC(D) + RETURN + +; +; INTERRUPT HANDLING SPECIFICATONS +; + +T%NRG==4 ; NUMBER OF REGISTERS PUSHED + +T%IW1==0 ; OFFSET OF 1ST INTERRUPT WORD +T%IW2==1 ; OFFSET OF 2ND INTERRUPT WORD +T%DF1==2 ; OFFSET OF 1ST OLD DEFER WORD +T%DF2==3 ; OFFSET OF 2ND OLD DEFER WORD +T%OPC==4 ; OFFSET OF OLD PC +T%REG==5 ; OFFSET OF FIRST SAVED REGISTER +T%SIZ==T%REG+T%NRG ; SIZE OF INTERRUPT FRAME +T%CTL==A*100+T%NRG ; CONTROL ARG FOR PUSHING REGS + +MDATA TSINT + T%CTL,,INTPTR ; PUSH REGISTERS ON INTERRUPT STACK + %PIPDL ? 0 ; HANDLE PDL-OVERFLOW + -1 ? -1 ; DEFER ALL INTERRUPTS + PDLOVH ; PDL-OVERFLOW HANDLER + %PIMPV ? 0 ; HANDLE MPV + #%PIPDL ? -1 ; DEFER ALL BUT PDL-OVERFLOW + MPVH ; MPV HANDLER + #<%PIMPV+%PIPDL> ? 0 ; HANDLE ALL OTHER FIRST WORDERS + #<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV + TSINT1 ; INTERRUPT HANDLER + 0 ? -1 ; HANDLE ALL SECOND WORDERS + #<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV + TSINT2 ; INTERRUPT HANDLER +TSINTL"==21. ; .-TSINT DOESN'T WORK DUE TO MIDAS BUG + +; +; INTERRUPT STACK +; + +INTPSZ==2*TSINTL ; SIZE OF INTERRUPT STACK + +.IDATA +MDATA INTPTR + -INTPSZ,,INTPDL +MDATA INTPDL + BLOCK INTPSZ-1 + -1 ; THIS PAGE MUST NOT BE DELETED! +.CODE + +; +; MPV HANDLER +; + +IENTRY MPVH + + .SUSET [.RMPVA,,B] ; GET LOSING ADDRESS + ; NOTE THAT ON KA-10 THIS ADDRESS + ; IS ROUNDED DOWN TO FIRST WORD + ; OF PAGE + TRZ B,1777 ; ROUND DOWN ANYWAY (FOR KL-10) + + CAMGE B,SEG0LO" ; MAYBE IN SEGMENT 0? + GO MPV$0 ; NO + CAMG B,SEG0HI" ; IN SEGMENT 0? + GO MPV$1 ; YES + +MPV$0: CAMGE B,SEG1LO" ; MAYBE IN SEGMENT 1? + GO TSINT1 ; NO + CAMLE B,SEG1HI" ; IN SEGMENT 1? + GO TSINT1 ; NO + + ; HERE IF ADDRESS IS IN SEGMENT 1 + + MOVE C,PDLTOP ; TOP END OF STACK + SUBI C,2000 + TRZ C,1777 ; LAST FULL PAGE OF STACK + CAME B,C ; REFERENCE TO LAST PAGE OF STACK? + GO MPV$1 ; NO + CROAK IMMINENT STACK OVERFLOW + +MPV$1: LSH B,-10. ; PAGE NUMBER + SYSCAL CORTYP,[B ? SETZM C] ; GET PAGE INFO + JUMPN C,TSINT1 ; PAGE EXISTS => MPV ON ANOTHER JOB + +MPV$2: SYSCAL CORBLK,[1000,,%CBNDW ? 1000,,-1 ? B ? 1000,,%JSNEW],MPVLOS + GO INTDIS +MPVLOS: CROAK UNABLE TO GET ZERO PAGE + GO MPV$2 + +; +; HANDLER FOR FIRST WORD INTERRUPTS +; + +IENTRY TSINT1 + + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,T%IW1(D) ; GET INTERRUPT WORD + JFFO A,.+2 ; GET FIRST BIT + GO INTDIS ; NONE (?) + MOVE A,TAB1(B) ; C INTERRUPT NUMBER + JUMPE A,IGNORE ; NOT HANDLED + HRRZ B,TAB2(A) ; HANDLER + CAIN B,1 + GO IGNORE ; 1 MEANS IGNORE + JUMPN B,TS1 ; HANDLER SPECIFIED + CAIN A,MPV + GO FATMPV + CAIN A,CTRGI + GO TS1 ; DEFAULT IS NOT TO IGNORE +IGNORE: AOS T%OPC(D) ; OTHERWISE - THE DEFAULT + GO INTDIS ; IS TO CONTINUE WITH THE + ; NEXT INSTRUCTION + +; HERE IF FATAL MPV OCCURS + +FATMPV: MOVEI A,%PIMPV + IORM A,T%DF1(D) ; MAKE MPV DEFFERED + GO INTDIS ; NOW DISMISS - WILL MAKE FATAL + +; +; SECOND WORD INTERRUPT HANDLER +; + +IENTRY TSINT2 + + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,T%IW2(D) ; GET INTERRUPT WORD + JFFO A,.+2 + GO INTDIS + CAILE B,17. + GO CHANI + CAIGE B,10. + GO INTDIS + MOVN A,B + ADDI A,17.+IN0I + GO TS1 + +CHANI: CAIGE B,19. + GO INTDIS + MOVN A,B + ADDI A,35.+CH0I + GO TS1 + + +; +; HERE TO SIGNAL SOMETHING WITH ARG IN A +; + +DEFINE PUSHL LIST +IRP X,,[LIST] + PPUSH X +TERMIN!TERMIN + +DEFINE POPL LIST +IRP X,,[LIST] + PPOP X +TERMIN!TERMIN + +TS1: ADDI P,20 ; IN CASE EPILOG INTERRUPTED + PUSHL [0,5,6,7,10,11,12,13,14,15,16] + PUSHL [40,USAVEA,USAVEB,USAVEC,USAVED,UUOH] + CALL SIGNAL,[A] + POPL [UUOH,USAVED,USAVEC,USAVEB,USAVEA,40] + POPL [16,15,14,13,12,11,10,7,6,5,0] + SUBI P,20 + +PDLOVH: +INTDIS: SYSCAL DISMIS,[5000,,T%CTL ? INTPTR] + +IENTRY ETSINT +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10IO C b/arc/ar2:clib/C10IO C new file mode 100644 index 00000000..8d65a5c8 --- /dev/null +++ b/arc/ar2:clib/C10IO C @@ -0,0 +1,849 @@ +# include "c/c.defs" +# include "c/its.bits" + +/* + * + * CIO - C I/O Routines (written in C) + * + * Routines: + * + * fd = copen (fname, mode, opt) + * c = getchar () + * gets (s) + * putchar (c) + * puts (s) + * ch = mopen (f, mode) + * rc = mclose (ch) + * rc = fparse (s, f) + * s = prfile (f, s) + * ch = fopen (fname, mode) + * ch = open (&filespec, mode) + * argc = fxarg (argc, argv) + * n = prsarg (in, out, argv, job) + * valret (s) + * c6 = ccto6 (c) + * c = c6toc (c6) + * w = csto6 (s) + * s = c6tos (w, s) + * + * Internal routines: + * + * c0init () [called by startup routine] + * fd = c0open (fname, mode) + * w = cons (lh, rh) + * s = filscan (b, s) + * s = c6q2s (w, s) + * + * Variables: + * + * cin - standard input channel + * cout - standard output channel + * cerr - standard error output channel + * + * cinfn - standard input file name (if redirected) + * coutfn - standard output file name (if redirected) + * cerrfn - standard errout file name (if redirected) + * + * + */ + +# rename c0fcbs "C0FCBS" +# rename gettab "GETTAB" +# rename puttab "PUTTAB" +# rename clotab "CLOTAB" +# rename gc_bad "GC$BAD" +# rename pc_bad "PC$BAD" +# rename cl_bad "CL$BAD" +# rename prsarg "PRSARG" +# rename fcbtab "FCBTBL" +# rename tty_input_channel "TYICHN" +# rename tty_output_channel "TYOCHN" +# rename setappend "SETAPP" + +# define _magic 37621 /* a magic number for validation */ +# define buf_siz 0200 +# define fcb_siz 7 +# define NCHANNEL 10 /* number of CHANNELs */ + +# define phyeof_flag 001 +# define open_flag 002 +# define write_flag 004 +# define tty_flag 010 +# define unset_flag 020 + +# define QUOTE 021 /* control-Q, for file names */ + +# define _DSK 0446353000000 /* sixbit for DSK */ +# define _GREATER 0360000000000 /* sixbit for > */ +# define _TTY 0646471000000 /* sixbit for TTY */ +# define _FILE 0164651544516 /* sixbit for .FILE. */ +# define _DIR 0104451621100 /* sixbit for (DIR) */ + +channel cin, /* standard input unit */ + cout, /* standard output unit */ + cerr; /* standard error output unit */ + +char *cinfn, /* standard input file name, if redirected */ + *coutfn, /* standard output file name, if redirected */ + *cerrfn; /* standard errout file name, if redirected */ + +int cerrno; /* system OPEN error codes returned here */ + +extern int c0fcbs[], fcbtab[], puttab[], gettab[], clotab[], + gc_bad[], pc_bad[], cl_bad[]; + +/********************************************************************** + + COPEN - CIO Open File + + Open a file, given a file name, an optional mode, and an + optional options string. The possible modes are + + 'r' - read + 'w' - write + 'a' - append + + The default mode is read. Normally, I/O is character oriented + and produces text files. In particular, the lines of a text + file are assumed (by the user) to be separated by newline + characters with any conversion to the system format performed + by the I/O routines. + + If an options string is given and contains the character "b", + then I/O is integer (word) - oriented and produces image files. + + I/O to and from character strings in core is accomplished by + including "s" in the options string and supplying a character + pointer to the string to be read or written into as the first + argument to COPEN. Closing a string open for write will + append a NULL character to the string and return a character + pointer to that character. + + COPEN returns a CHANNEL, which is a pointer to a control block. + The external variables CIN, COUT, and CERR contain already-open + channels for standard input, standard output, and standard + error output, respectively. + + COPEN returns OPENLOSS in case of error. The system error code is + stored in CERRNO. + +**********************************************************************/ + +channel copen (fname, mode, opt) + char *fname; + + {int *fcbp, i, fmode, bmode, its_mode, flags; + int chan, buffp, state, bcnt, device, c, sflag, *ip; + char *p, buf[5], *ep; + filespec f; + + cerrno = 0; + if (mode<'A' || mode>'z') mode = 'r'; + p = opt; + if (opt<0100 || opt>=01000000) p = ""; + else if (p[0]<'A' || p[0]>'z') p = ""; + + flags = open_flag; + fmode = 0; + switch (lower (mode)) { + case 'r': fmode = 0; break; + case 'w': fmode = 1; break; + case 'a': fmode = 2; break; + default: cerrno = 012; /* mode not available */ + return (OPENLOSS); + } + bmode = 0; + sflag = FALSE; + while (c = *p++) switch (lower (c)) { + case 'b': bmode = 4; break; + case 's': sflag = TRUE; break; + } + + if (c0fcbs[0] != _magic) c0init(); /* initialize */ + for (i=0; i=NCHANNEL) + {cerrno = 06; /* device full */ + return (OPENLOSS); + } + chan = -1; + buffp = fcbp[0] >> 18; + if (sflag) /* string I/O */ + {state = 3; + if (fmode==2) /* append */ + while (*fname) ++fname; + } + else /* file I/O */ + {state = 1; + fparse (fname, &f); /* parse file name */ + if (f.dev == _TTY /* TTY special case */ + && (f.fn1 != _FILE || f.fn2 != _DIR)) + {state = 0; + bmode = 0; + device = 0; + chan = -1; + flags =| tty_flag; + } + else /* normal case */ + {if (f.dev == 0) f.dev = _DSK; + if (f.dir == 0) f.dir = rsname(); + if (f.fn2 == 0) f.fn2 = _GREATER; + + its_mode = (fmode==2 ? 0100001 : fmode); + its_mode =| 2; /* block mode */ + its_mode =| bmode; /* image mode */ + + if (fmode==2 && !bmode) /* char append */ + {chan = setappend (&f, its_mode, buf, &ep); + if (chan == -04) /* not found */ + {chan = mopen (&f, its_mode & 077); + fmode = 1; + } + } + else chan = mopen (&f, its_mode); + if (chan<0) {cerrno = -chan; return (OPENLOSS);} + device = status (chan) & 077; /* device code */ + if (bmode && device<=2) /* TTY in IMAGE mode ?? */ + {close (chan); + bmode = 0; + its_mode =& ~4; + chan = mopen (&f, its_mode); + if (chan<0) {cerrno = -chan; return (OPENLOSS);} + device = status (chan) & 077; + } + if (state==1) + if (buffp==0) + {buffp = salloc (buf_siz); + if (buffp == -1) + {cerrno = 037; /* no core available */ + return (OPENLOSS); + } + } + else + {i = buf_siz; + ip = buffp; + while (--i >= 0) *ip++ = 0; + } + } + } + bcnt = -1; /* special initialization hack */ + if (fmode) + {bcnt = 5*buf_siz; /* char count */ + if (bmode) bcnt = buf_siz; /* word count */ + flags =| write_flag; + } + if (bmode && !sflag) state = 2; + if (chan < 0) {flags =| unset_flag; chan = 0;} + fcbp[0] = (buffp<<18) | ((chan&017)<<14) | ((device&077)<<8) | flags; + fcbp[2] = bcnt; + if (sflag) fcbp[1] = fname; + else fcbp[1] = cons (bmode ? 0 : 0440700, buffp); + if (fcbp[3]==0) fcbp[3] = salloc(20); + else fcbp[3] =& 0777777; + if (fmode) state =+ 4; + fcbp[4] = cons (clotab[state], fcbp[5]=gettab[state]); + fcbp[6] = puttab[state]; + if (fmode==2 && !sflag) /* file append */ + {i = fillen (chan); + if (bmode) access (chan, i); /* access to end of file */ + else if (i>0) + {access (chan, i-1); /* write over last word */ + p = buf; + while (p < ep) cputc (*p++ | 0400, fcbp); + } + } + return (fcbp); + } + +/********************************************************************** + + SETAPPEND - Set up for character append + +**********************************************************************/ + +int setappend (fp, mode, buf, epp) filespec *fp; char buf[], **epp; + + {int count, n, chan, wordlen, chanlen, c; + char *p; + + count = 5; /* try 5 times */ + while (--count>=0) + {p = buf; + chan = mopen (fp, UII); + if (chan < 0) return (chan); + wordlen = fillen (chan); + close (chan); + chan = mopen (fp, UAI); + if (chan < 0) return (chan); + chanlen = fillen (chan); + if (chanlen > 0) + {if (chanlen == wordlen) --chanlen; + else chanlen = ((chanlen-1)/5)*5; + access (chan, chanlen); + n = 5; + while (--n>=0 && (c = uiiot (chan)) >= 0 && c != 3) + *p++ = c; + } + close (chan); + *epp = p; + chan = mopen (fp, mode); + if (chan<0) return (chan); + if (wordlen == fillen(chan)) return (chan); + close (chan); + } + return (-012); + } + +/********************************************************************** + + GETCHAR - Read a character from the standard input unit + +**********************************************************************/ + +getchar () {return (cgetc (cin));} + +/********************************************************************** + + GETS - Read a string from the standard input unit + +**********************************************************************/ + +gets (p) + char *p; + + {int c; + + while ((c = cgetc (cin)) != '\n' && c>0) *p++ = c; + *p = 0; + } + +/********************************************************************** + + PUTCHAR - Output a character to the standard output unit + +**********************************************************************/ + +putchar (c) + int c; + + {return (cputc (c, cout));} + +/********************************************************************** + + PUTS - Output a string to the standard output unit + +**********************************************************************/ + +puts (s) + char *s; + + {int c; + + while (c = *s++) cputc (c, cout); + cputc ('\n', cout); + } + +/********************************************************************** + + MOPEN - OPEN FILE + + Open file given filespec and mode. + Return ITS channel number or -FC if unsuccessful. + Same as OPEN, except handles TTY specially + and waits if file is locked. + +**********************************************************************/ + +channel mopen (f, mode) filespec *f; int mode; + + {int ch, n; + + if (f->dev == _TTY && !(f->fn1 == _FILE && f->fn2 == _DIR)) + return (mode & 1 ? tyoopn() : tyiopn()); + + ch = open (f, mode); + n = 8; + while (ch == -023 && --n>=0) /* file locked */ + {sleep (30); + ch = open (f, mode); + } + return (ch); + } + +/********************************************************************** + + MCLOSE - Close ITS channel, unless its the TTY. + +**********************************************************************/ + +mclose (ch) channel ch; + + {extern int tty_input_channel, tty_output_channel; + if (ch == tty_input_channel) return (0); + if (ch == tty_output_channel) + {tyo_flush (); + return (0); + } + return (close (ch)); + } + +/********************************************************************** + + FPARSE - Convert an ASCIZ string representation of an ITS + file name or a path name to a FILESPEC. + + Return 0 if OK, -1 if bad path name format. + +**********************************************************************/ + +fparse (s, f) char s[]; filespec *f; + + {int i, c, fnc, n_slash, no_its_chars, n_dot; + char buf[7], *p, *filscan(); + + f->dev = f->dir = f->fn1 = f->fn2 = 0; + + /* check for path name */ + + p = s; + no_its_chars = TRUE; + n_slash = n_dot = 0; + + while (c = *p++) switch (c) { + case QUOTE: if (*p) ++p; break; + case '.': ++n_dot; break; + case '/': ++n_slash; break; + case ' ': + case ':': + case ';': no_its_chars = FALSE; break; + } + + if (no_its_chars && (n_dot>0 || n_slash>0)) + + /* here if path name */ + + {p = s; + if (*p=='/') + {--n_slash; + p = filscan (buf, ++p, &n_dot, &n_slash); + f->dev = csto6(buf); + c = *p++; + if (c!='/') return (-1); + } + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + if (c=='/') + {f->dir = csto6(buf); + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + } + if (c=='.') + {f->fn1 = csto6(buf); + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + } + if (f->fn1) f->fn2 = csto6(buf); + else f->fn1 = csto6(buf); + return (0); + } + + /* here if ITS file name */ + + p = s; + fnc = i = 0; + buf[0] = 0; + + do {c = *p++; + switch (c) { + + case ':': f->dev = csto6(buf); + i = 0; + break; + + case ';': f->dir = csto6(buf); + i = 0; + break; + + case ' ': + case 0: if (buf[0]) switch (fnc++) { + case 0: f->fn1 = csto6(buf); break; + case 1: f->fn2 = csto6(buf); break; + } + i = 0; + break; + + default: if (c==QUOTE && *p) c = *p++; + if (i<6) buf[i++] = c; + } + + buf[i] = 0; + } + while (c); + return (0); + } + +/********************************************************************** + + FILSCAN - scan for part of file name + +**********************************************************************/ + +char *filscan (b, q, andot, anslash) + char *b, *q; + int *andot, *anslash; + + {int c; + char *p; + + p = q++; + while (c = *p++) + {if (c=='/') {--*anslash; break;} + else if (c=='.') + {if (--*andot == 0 && *anslash==0 && *p && + p!=q) break;} + else if (c==QUOTE && *p) c = *p++; + *b++ = c; + } + *b = 0; + return (--p); + } + +/********************************************************************** + + PRFILE - convert FILESPEC to ITS file name + +**********************************************************************/ + +char *prfile(f,p) filespec *f; char *p; + + {char *c6q2s(); + if (f->dev) {p = c6q2s (f->dev, p); *p++ = ':';} + if (f->dir) {p = c6q2s (f->dir, p); *p++ = ';';} + if (f->fn1) {p = c6q2s (f->fn1, p); *p++ = ' ';} + if (f->fn2) {p = c6q2s (f->fn2, p);} + *p = 0; + return (p); + } + +/********************************************************************** + + FOPEN - Open file given file name + +**********************************************************************/ + +channel fopen (fname, mode) char *fname; int mode; + + {filespec f; + + fparse (fname, &f); + if (f.dev == 0) f.dev = _DSK; + if (f.dir == 0) f.dir = rsname(); + return (open (&f, mode)); + } + +/********************************************************************** + + OPEN - Open file given filespec + +**********************************************************************/ + +channel open (f, mode) filespec *f; int mode; + + {channel c; + int rc; + + c = chnloc(); + if (c<0) return (-014); /* bad channel number */ + rc = sysopen (c, f, mode); + if (rc) return (rc); + return (c); + } + +/********************************************************************** + + FXARG - Process Command Arguments to Set Up + Redirection of Standard Input and Output + + This routine is called by the C start-up routine. + +**********************************************************************/ + +int fxarg (argc, argv) int argc; char *argv[]; + + {char **p, **q, *s; + int i, append, errappend, f; + + i = argc; /* number of arguments given */ + argc = 0; /* number of arguments returned */ + p = argv; /* source pointer */ + q = argv; /* destination pointer */ + + while (--i >= 0) /* for each argument given */ + {s = *p++; /* the argument */ + switch (s[0]) { + case '<': if (s[1]) cinfn = s+1; break; + case '>': if (s[1] == '>') + {if (s[2]) {coutfn = s+2; append = TRUE;}} + else {if (s[1]) {coutfn = s+1; append = FALSE;}} + break; + case '%': if (s[1] == '%') + {if (s[2]) {cerrfn = s+2; errappend=TRUE;}} + else {if (s[1]) {cerrfn = s+1; errappend = FALSE;}} + break; + default: /* normal argument */ + ++argc; *q++ = s; + } + } + + /* now hack the standard file descriptors */ + + if (cinfn) /* input is redirected */ + {f = c0open (cinfn, 'r'); + if (f != OPENLOSS) {cclose (cin); cin = f;} + } + + if (coutfn) /* output is redirected */ + {f = c0open (coutfn, append ? 'a' : 'w'); + if (f != OPENLOSS) {cout = f;} + } + + if (cerrfn) /* errout is redirected */ + {f = c0open (cerrfn, errappend ? 'a' : 'w'); + if (f != OPENLOSS) + {if (cerr!=cout) cclose (cerr); cerr = f;} + } + return (argc); + } + +/********************************************************************** + + C0OPEN - Open with error message + +**********************************************************************/ + +channel c0open (name, mode) + + {channel f; + + f = copen (name, mode, 0); + if (f == OPENLOSS) cprint (cerr, "Unable to open '%s'\n", name); + return (f); + } + +/********************************************************************** + + C0INIT - Initialization for C I/O Routines. + This routine is normally called first by the C start-up routine. + +**********************************************************************/ + +c0init () + + {int *p, i; + + c0fcbs[0] = _magic; + p = &c0fcbs[1]; + i = NCHANNEL*fcb_siz; + while (--i >= 0) *p++ = 0; + i = NCHANNEL; + while (--i >= 0) + {p = &c0fcbs[fcb_siz*i+5]; + p[0] = cons (cl_bad, gc_bad); + p[1] = gc_bad; + p[2] = pc_bad; + } + + cin = copen ("/tty", 'r', 0); /* standard input */ + cout = cerr = copen ("/tty", 'w', 0); /* standard output */ + + /* These calls do not actually open the TTY, the TTY is + automatically opened when I/O is done to it. This is helpful + for allowing C programs to run without the TTY. */ + } + +/********************************************************************** + + VALRET - Valret a String + +**********************************************************************/ + +valret (s) char *s; + + {int len, bp1, bp2, buf, c, flag; + + flag = FALSE; + len = slen (s); + buf = salloc (len/5 + 1); + if (buf<=0) + {buf=s; /* gross hack */ + flag = TRUE; + } + bp1 = bp2 = 0440700000000 | buf; + + while (TRUE) + {c = *s++; + if (c=='\n') c='\r'; + idpb (c, &bp1); + if (!c) break; + } + + val7ret (bp2); + if (flag) cquit(1); else sfree (buf); + } + +/********************************************************************** + + PRSARG - Parse JCL Arguments (PDP-10 ITS) + + given: in - an advance byte pointer to the JCL + out - a pointer to a character buffer where the + arguments should be placed + argv - a pointer to a character pointer array + where pointers to the args should be placed + job - the sixbit XJNAME + narg - the maximum number of arguments + returns: number of arguments + +**********************************************************************/ + +int prsarg (in, out, argv, job, narg) + char *out, *argv[]; + + {int c, argc; + char *c6tos(); + + argc = 1; + argv[0] = out; + out = c6tos (job, out); + *out++ = 0; + argv[1] = out; + + while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case QUOTE: *out++ = ildb (&in); continue; + case ' ': continue; + case '"': while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case QUOTE: *out++ = ildb (&in); continue; + case '"': break; + default: *out++ = c; continue; + } + break; + } + *out++ = 0; + if (++argc < narg) argv[argc] = out; + if (c=='"') continue; + break; + default: *out++ = c; + while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case ' ': break; + case QUOTE: *out++ = ildb (&in); continue; + default: *out++ = c; continue; + } + break; + } + *out++ = 0; + if (++argc < narg) argv[argc] = out; + if (c==' ') continue; + break; + } + break; + } + return (argc>narg ? narg : argc); + } + +/********************************************************************** + + CONS - construct word from left and right halves + +**********************************************************************/ + +int cons (lh, rh) {return (((lh & 0777777) << 18) | (rh & 0777777));} + + +/********************************************************************** + + CCTO6 - convert ascii character to sixbit character + +**********************************************************************/ + +char ccto6 (c) char c; + + {return (((c>=040 && c<0140) ? c+040 : c) & 077);} + +/********************************************************************** + + C6TOC - convert sixbit character to ascii character + +**********************************************************************/ + +char c6toc (c) char c; + + {return (c+040);} + +/********************************************************************** + + CSTO6 - convert ascii string to left-justified sixbit + +**********************************************************************/ + +int csto6 (s) char *s; + + {int c,i,j; + + i=0; + j=30; + while (c = *s++) if (j>=0) + {i =| (ccto6(c)<=0 && (c = (i>>j)&077)) + {*p++ = c6toc(c); j =- 6;} + *p = 0; + return (p); + } + +/********************************************************************** + + C6Q2S - convert left-justified sixbit word to ascii string, + inserting QUOTE characters, where necessary + +**********************************************************************/ + +char *c6q2s (i, p) int i; char *p; + + {int c, j; + + j = 30; + while (j>=0) + {c = c6toc ((i>>j) & 077); + if (c==' ' || c==':' || c==';') *p++ = QUOTE; + *p++ = c; + if (! (i & ((1< # or error code + + j_load (filespec) => # or error code + j_fload (file_name) => # or error code + j_cload (channel, jname) => # or error code + j_own (uname, jname) => # or error code + + error code: + + -1 unable to open program file + -2 unable to create job + -3 unable to load job + -4 fatal error + -5 (OWN) no such job + -6 (OWN) job not yours + + j_start (#) => rc (return code: non-zero => error) + j_stop (#) => rc + j_disown (#) => rc + j_forget (#) => rc + j_kill (#) => rc + j_snarf (#, inferior_name) => rc + (disown named inferior from stopped job) + j_give_tty (#) => rc + j_take_tty (#) => rc + + j_grab_tty () (grab tty if given to some inferior + and stop job) + j_retn_tty () (return tty to inferior and restart) + + j_wait (#) => status (waits for non-zero status) + j_sts (#) => status + + j_onchange (f) (set handler for status changes) + + j_sjcl (#, s) => rc (set jcl for job) + j_jcl (#) => s (get jcl) + j_ch (#) => ch (return block image output channel to job) + j_name (#, filespec) (set filespec to job name) + + j_val (#) => s (return string valretted by job) + j_fval (#) (flush valret string; or call cfree) + + Job Status: + + -5 => stopped, ^Z typed + -4 => stopped (by superior) + -3 => stopped, valret + -2 => stopped, requested suicide + -1 => no job + 0 => running + >0 => stopped, value is job's first interrupt word + +*/ + +# define MAXJOBS 8 +# define VALBUFSIZ 200 + +/* job status values */ + +# define js_attn -5 +# define js_stopped -4 +# define js_valret -3 +# define js_suicide -2 +# define js_nojob -1 +# define js_running 0 + +/* useful SIXBIT numbers */ + +/* Fixed by BGS 9/14/79 because of MOVNI bug +# define _USR 0656362000000 +# define _TS 0646300000000 +# define _DSK 0446353000000 +# define _FOO 0465757000000 +# define _GR 0360000000000 */ /* > */ + +#define _USR csto6("USR") +#define _TS csto6("TS") +#define _DSK csto6("DSK") +#define _FOO csto6("FOO") +#define _GR csto6(">") + +/* internal tables */ + +# rename job_channels "JOBCHN" +# rename job_status "JOBSTS" +# rename job_jcl "JOBJCL" +# rename job_valret "JOBVAL" +# rename job_name "JOBNAM" +# rename job_xname "JOBXNM" +# rename job_wait "JOBWAT" + +int job_status[MAXJOBS] {js_nojob, js_nojob, js_nojob, js_nojob, + js_nojob, js_nojob, js_nojob, js_nojob}; +int job_channels[MAXJOBS] {-1, -1, -1, -1, -1, -1, -1, -1}; +char *job_jcl[MAXJOBS]; +char *job_valret[MAXJOBS]; +int job_name[MAXJOBS]; +int job_xname[MAXJOBS]; +int job_wait -1; +static int jobtty {-1}, jobotty, jobosts, (*jchandler)(); + +/* the routines */ + +int j_fload (file_name) char *file_name; + + {filespec f; + + fparse (file_name, &f); + return (j_load (&f)); + } + +int j_load (f) filespec *f; + + {int pch, xjname; + + if (f->dev == 0) f->dev = _DSK; + if (f->dir == 0) f->dir = rsname (); + pch = mopen (f, BII); + if (pch<0) return (-1); + xjname = (f->fn1 == _TS ? f->fn2 : f->fn1); + return (j_cload (pch, xjname)); + } + +int j_cload (pch, xjname) + channel pch; + + {int j, jch, start; + + j = j_create (xjname); + if (j<0) + {close (pch); + return (j); + } + jch = job_channels[j]; + + /* load program */ + + if (sysload (jch, pch)) + {uclose (jch); + close (pch); + return (-3); + } + + /* get starting address of program */ + + sysread (pch, &start, 1); + close (pch); + + /* set starting address of job */ + + wuset (jch, UPC, start & 0777777); + return (j); + } + +int j_create (xjname) + + {int jch, i, inc, count, flag; + filespec jf; + + /* set up job name */ + + jf.dev = _USR; + jf.dir = 0; + jf.fn1 = 0; + jf.fn2 = xjname; + + /* make job name unique */ + + flag = FALSE; + while ((jch = open (&jf, OLD + BII)) >= 0) + {close (jch); + if (!flag) + {flag = TRUE; + i = jf.fn2; + count = 0; + while ((i&077)==0) {i =>> 6; ++count;} + if (count>0) + {count = 6*(count-1); + jf.fn2 =| ccto6('0') << count; + inc = 1 << count; + } + else + {jf.fn2 = (jf.fn2 & ~077) | ccto6('0'); + inc = 1; + } + } + else jf.fn2 =+ inc; + } + + /* create job */ + + jch = open (&jf, BIO); + if (jch<0) return (-2); + reset (jch); + + /* set job's NAMEs */ + + wuset (jch, USNAME, rsname()); + wuset (jch, UXJNAME, xjname); + + return (j_xxx (jch, xjname)); + } + +/********************************************************************** + + J_OWN - attach job as inferior + +**********************************************************************/ + +int j_own (uname, jname) + + {filespec fs; + int jch, j, w, sts; + + fs.dev = _USR; + fs.dir = 0; + fs.fn1 = uname; + fs.fn2 = jname; + + if ((jch = open (&fs, OLD + BII)) < 0) return (-5); + close (jch); + if ((jch = open (&fs, BIO)) < 0) return (-5); + if (status (jch) != 061) + {close (jch); return (-6);} + j = j_xxx (jch, jname); + if (ruset (jch, USTOP) & BUSRC) + {w = ruset (jch, UPIRQ); + if (w & PICZ) sts = js_attn; + else if (w & PIVAL) sts = js_valret; + else if (w) sts = w; + else sts = js_stopped; + wuset (jch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + } + else sts = js_running; + job_status[j] = sts; + return (j); + } + +/********************************************************************** + + J_XXX - common processing for new inferior + +**********************************************************************/ + +int j_xxx (jch, xjname) + + {int i, inf_no, option, j_handler(); + + /* get inferior number */ + + i = ruset (jch, UINF) >> 18; + inf_no = 0; + if (i) while (!(i&1)) {i=>>1; ++inf_no;} + + /* set up interrupt handler */ + + on (inferior0_interrupt+inf_no, j_handler); + option = ruset (jch, UOPTION); + wuset (jch, UOPTION, option | OPTBRK); + + /* clean up */ + + job_channels[inf_no] = jch; + if (job_status[inf_no] == js_nojob) + {job_status[inf_no] = js_stopped; + job_jcl[inf_no] = 0; + job_valret[inf_no] = 0; + } + job_name[inf_no] = ruset (jch, UJNAME); + job_xname[inf_no] = xjname; + + return (inf_no); + } + +int j_start (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, 0); + job_status[j] = js_running; + return (0); + } + +int j_stop (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, -1); + job_status[j] = js_stopped; + return (0); + } + +int j_disown (j) + + {int ch, ec; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + ec = sysdisown (ch); + if (ec) return (ec); + j_flush (j); + return (0); + } + +int j_forget (j) + + {int ch; + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + close (ch); + j_flush (j); + return (0); + } + +int j_kill (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + uclose (ch); + j_flush (j); + return (0); + } + +static int code[] { + 0042000000013, /* .IOPUSH 0, ;(26) DON'T CLOBBER HIM */ + 0041000000034, /* .OPEN 0,34 ;(27) OPEN */ + 0043100000000, /* .LOSE ;(30) FAIL, CAUSE ERR MSG */ + 0042000000027, /* .DISOWN 0, ;(31) DISOWN */ + 0042000000014, /* .IOPOP 0, ;(32) UNCLOBBER HIM */ + 0043200000000, /* .VALUE ;(33) RETURN SUCCESS */ + 0000001656362, /* 1,,'USR ;(34) FILENAME BLOCK */ + 0, /* ;(35) WILL GET UNAME */ + 0 /* ;(36) WILL GET JNAME */ + }; + +int j_snarf (j, jname) + + {int ch, piclr, pirqc, pc, osts, sts; + + if (j<0 || j>=MAXJOBS) return (-1); + osts = job_status[j]; + if (osts == js_running) return (-1); /* must be stopped */ + ch = job_channels[j]; + if (ch<0) return (-1); + code[7] = rsuset (UUNAME); + code[8] = jname; + access (ch, 026); + syswrite (ch, code, 9); + piclr = ruset (ch, UPICLR); + wuset (ch, UPICLR, 0); + pirqc = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, pirqc); + pc = ruset (ch, UPC); + wuset (ch, UPC, 026); + j_start (j); + sts = j_wait (j); + job_status[j] = osts; + if (sts == js_valret) sts = 0; + else {wuset (ch, UAPIRQ, sts); sts = -1;} + wuset (ch, UPC, pc); + wuset (ch, UIPIRQ, pirqc); + wuset (ch, UPICLR, piclr); + return (sts); + } + +int j_flush (j) + + {char *p; + + job_channels[j] = -1; + job_status[j] = js_nojob; + job_name[j] = 0; + if (p = job_jcl[j]) + {sfree (p); + job_jcl[j] = 0; + } + if (p = job_valret[j]) + {sfree (p); + job_valret[j] = 0; + } + on (inferior0_interrupt+j, 0); + } + +int j_give_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = atty (ch); + if (rc == 0) jobtty = j; + return (rc); + } + +int j_take_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = dtty (ch); + if (rc == 0) jobtty = -1; + return (rc); + } + +int j_grab_tty () + + {if (jobtty >= 0) + {int rc; + jobotty = jobtty; + jobosts = job_status[jobtty]; + j_stop (jobtty); + rc = j_take_tty (jobtty); + if (rc && jobosts==0) j_start (jobtty); + return (rc); + } + jobotty = -1; + return (0); + } + +int j_retn_tty () + + {if (jobtty < 0 && jobotty >= 0) + {j_give_tty (jobotty); + if (jobosts == 0) j_start (jobotty); + jobotty = -1; + } + } + +int j_wait (j) + + {int sts; + + if (j<0 || j>=MAXJOBS) return (-1); + job_wait = j; + sts = wfnz (&job_status[j]); + job_wait = -1; + return (sts); + } + +int j_onchange (f) int (*f)(); + + {jchandler = f; + } + +int j_sts (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_status[j]); + } + +int j_sjcl (j, s) char *s; + + {char *buf, *p; + int ch, i; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + if (*s==0) + {if (buf = job_jcl[j]) /* flush previous */ + {i = ruset (ch, UOPTION) & ~OPTCMD; + wuset (ch, UOPTION, i); + sfree (buf); + job_jcl[j] = 0; + } + return (0); + } + i = salloc (slen (s) + 2); + if (i <= 0) return (-1); + buf = i; + stcpy (s, buf); + p = buf; + while (*p) ++p; + if (p==buf || p[-1]!='\r') + {p[0] = '\r'; + p[1] = 0; + } + job_jcl[j] = buf; + wuset (ch, UOPTION, OPTCMD); + } + +char *j_jcl (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_jcl[j]); + } + +int j_ch (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_channels[j]); + } + +int j_name (j, f) filespec *f; + + {f->dev = _USR; + f->dir = 0; + f->fn1 = runame(); + if (j>=0 && jfn2 = job_name[j]; + return (f->fn2 == 0); + } + f->fn2 = 0; + return (-1); + } + +char *j_val (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_valret[j]); + } + +j_fval (j) + + {if (j<0 || j>=MAXJOBS) return; + if (job_valret[j] == 0) return; + cfree (job_valret[j]); + job_valret[j] = 0; + } + +j_handler (j) + + {int ch, w, opt, old_status; + + if (j<0 || j>=MAXJOBS) return; + ch = job_channels[j]; + if (ch<0) return; + + old_status = job_status[j]; + w = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + opt = ruset (ch, UOPTION); + if ((opt & OPTOPC)==0 && (w & IBACKUP)) + wuset (ch, UPC, ruset (ch, UPC) - 1); + + job_status[j] = w; + if (w & PICZ) /* ^Z typed */ + {job_status[j] = js_attn; + return; + } + if (w & PIVAL) /* .VALUE */ + jdovalue (j); + else if (w & PIBRK) /* .BREAK */ + jdobrk (j); + + if (j != job_wait && job_status[j] != old_status && jchandler) + (*jchandler)(j,job_status[j]); + } + +jdovalue (j) /* handle .VALUE */ + + {int ch, ich, cmda, n; + char *p, buf[VALBUFSIZ]; + filespec f; + + ch = job_channels[j]; + job_valret[j] = 0; + job_status[j] = js_valret; + cmda = ruset (ch, USV40) & 0777777; + if (cmda == 0) return; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + access (ich, cmda); + n = VALBUFSIZ; + p = buf; + while (TRUE) + {int w, i, c; + w = uiiot (ich); + for (i=0;i<5;++i) + {c = (w>>29) & 0177; + w =<< 7; + if (c!='\n') {*p++ = c; --n;} + if (c=='\r') {*p++ = '\n'; --n;} + if (!c) break; + if (n<=2) + {*p++ = c = 0; + break; + } + } + if (!c) break; + } + close (ich); + if (stcmp (buf, ":KILL\r") || stcmp (buf, ":KILL\r\n")) + {/* if (job_wait != j) j_kill (j); + else */ job_status[j] = js_suicide; + return; + } + p = calloc (slen (buf) + 1); + stcpy (buf, p); + job_valret[j] = p; + return; + } + +jdobrk (j) /* handle .BREAK */ + /* unless there is a 'fatal error', the job status + must be changed to something reasonable */ + + {int ch, i; + ch = job_channels[j]; + wuset (ch, UAPIRQ, PIBRK); /* reset PIRQ bit */ + i = ruset (ch, USV40); /* the instruction */ + if ((i & ~000740000000) == 042000000033) + i = 045700160000; /* .LOGOUT n, */ + switch (i>>18) { /* opcode */ + +case 045700: /* .BREAK 16 */ + /* if ((i & 020000) && (job_wait != j)) j_kill (j); + else */ job_status[j] = js_suicide; + return; + +case 045500: /* .BREAK 12 */ + jdob12 (j, i); + return; + } + + j_start (j); + } + +jdob12 (j, i) /* handle .BREAK 12 */ + + {int cmda, ich, och; + filespec f; + + cmda = i & 0777777; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + if ((och = open (&f, UIO)) < 0) + {close (ich); + return; + } + access (ich, cmda); + i = uiiot (ich); + if (i & 0200000000000) /* multiple commands */ + {int n, a; + n = (i>>18) | 0777777000000; + a = i & 0777777; + while (n<0) + {access (och, cmda); + ++n; + ++a; + uoiot (och, (n<<18) | a); + access (ich, a-1); + do_brk (j, ich, och, uiiot (ich)); + } + } + else do_brk (j, ich, och, i); + close (ich); + close (och); + j_start (j); + } + +do_brk (j, ich, och, w) /* do .BREAK 12 command W */ + + {int cmd, a, f, i; + + cmd = (w>>18) & 0177777; + a = w & 0777777; + access (och, a); + if (cmd==6) /* send :PRINT defaults */ + {uoiot (och, _DSK); + uoiot (och, rsname ()); + uoiot (och, _FOO); + uoiot (och, _GR); + return; + } + if (cmd==5 && job_jcl[j]) + {f = copen (job_jcl[j], 'r', "s"); + access (ich, a+2); + while (TRUE) + {w = 0; + for (i=0;i<5;++i) w = (w<<7) | (cgetc (f) & 0177); + w =<< 1; + uoiot (och, w); + if ((w & 0377) == 0) break; + if (uiiot (ich)) + {uoiot (och, 0); + break; + } + } + cclose (f); + return; + } + if (cmd==10) /* send XJNAME */ + {uoiot (och, job_xname[j]); + return; + } + } + \ No newline at end of file diff --git a/arc/ar2:clib/C10JOB OLD b/arc/ar2:clib/C10JOB OLD new file mode 100644 index 00000000..08f10d38 --- /dev/null +++ b/arc/ar2:clib/C10JOB OLD @@ -0,0 +1,713 @@ +# include "clib/c.defs" +# include "clib/its.bits" + +/********************************************************************** + + JOBs - Inferior Process Management + ITS Version + +**********************************************************************/ + +/* + + The representation of a job is an integer with a value from + 0 to 7, indicating the inferior number. + + Routines: + + j_create (jname) => # or error code + + j_load (filespec) => # or error code + j_fload (file_name) => # or error code + j_cload (channel, jname) => # or error code + j_own (uname, jname) => # or error code + + error code: + + -1 unable to open program file + -2 unable to create job + -3 unable to load job + -4 fatal error + -5 (OWN) no such job + -6 (OWN) job not yours + + j_start (#) => rc (return code: non-zero => error) + j_stop (#) => rc + j_disown (#) => rc + j_forget (#) => rc + j_kill (#) => rc + j_snarf (#, inferior_name) => rc + (disown named inferior from stopped job) + j_give_tty (#) => rc + j_take_tty (#) => rc + + j_grab_tty () (grab tty if given to some inferior + and stop job) + j_retn_tty () (return tty to inferior and restart) + + j_wait (#) => status (waits for non-zero status) + j_sts (#) => status + + j_onchange (f) (set handler for status changes) + + j_sjcl (#, s) => rc (set jcl for job) + j_jcl (#) => s (get jcl) + j_ch (#) => ch (return block image output channel to job) + j_name (#, filespec) (set filespec to job name) + + j_val (#) => s (return string valretted by job) + j_fval (#) (flush valret string; or call cfree) + + Job Status: + + -5 => stopped, ^Z typed + -4 => stopped (by superior) + -3 => stopped, valret + -2 => stopped, requested suicide + -1 => no job + 0 => running + >0 => stopped, value is job's first interrupt word + +*/ + +# define MAXJOBS 8 +# define VALBUFSIZ 200 + +/* job status values */ + +# define js_attn -5 +# define js_stopped -4 +# define js_valret -3 +# define js_suicide -2 +# define js_nojob -1 +# define js_running 0 + +/* useful SIXBIT numbers */ + +# define _USR 0656362000000 +# define _TS 0646300000000 +# define _DSK 0446353000000 +# define _FOO 0465757000000 +# define _GR 0360000000000 /* > */ + +/* internal tables */ + +# rename job_channels "JOBCHN" +# rename job_status "JOBSTS" +# rename job_jcl "JOBJCL" +# rename job_valret "JOBVAL" +# rename job_name "JOBNAM" +# rename job_xname "JOBXNM" +# rename job_wait "JOBWAT" + +int job_status[MAXJOBS] {js_nojob, js_nojob, js_nojob, js_nojob, + js_nojob, js_nojob, js_nojob, js_nojob}; +int job_channels[MAXJOBS] {-1, -1, -1, -1, -1, -1, -1, -1}; +char *job_jcl[MAXJOBS]; +char *job_valret[MAXJOBS]; +int job_name[MAXJOBS]; +int job_xname[MAXJOBS]; +int job_wait -1; +static int jobtty {-1}, jobotty, jobosts, (*jchandler)(); + +/* the routines */ + +int j_fload (file_name) char *file_name; + + {filespec f; + + fparse (file_name, &f); + return (j_load (&f)); + } + +int j_load (f) filespec *f; + + {int pch, xjname; + + if (f->dev == 0) f->dev = _DSK; + if (f->dir == 0) f->dir = rsname (); + pch = mopen (f, BII); + if (pch<0) return (-1); + xjname = (f->fn1 == _TS ? f->fn2 : f->fn1); + return (j_cload (pch, xjname)); + } + +int j_cload (pch, xjname) + channel pch; + + {int j, jch, start; + + j = j_create (xjname); + if (j<0) + {close (pch); + return (j); + } + jch = job_channels[j]; + + /* load program */ + + if (sysload (jch, pch)) + {uclose (jch); + close (pch); + return (-3); + } + + /* get starting address of program */ + + sysread (pch, &start, 1); + close (pch); + + /* set starting address of job */ + + wuset (jch, UPC, start & 0777777); + return (j); + } + +int j_create (xjname) + + {int jch, i, inc, count, flag; + filespec jf; + + /* set up job name */ + + jf.dev = _USR; + jf.dir = 0; + jf.fn1 = 0; + jf.fn2 = xjname; + + /* make job name unique */ + + flag = FALSE; + while ((jch = open (&jf, OLD + BII)) >= 0) + {close (jch); + if (!flag) + {flag = TRUE; + i = jf.fn2; + count = 0; + while ((i&077)==0) {i =>> 6; ++count;} + if (count>0) + {count = 6*(count-1); + jf.fn2 =| ccto6('0') << count; + inc = 1 << count; + } + else + {jf.fn2 = (jf.fn2 & ~077) | ccto6('0'); + inc = 1; + } + } + else jf.fn2 =+ inc; + } + + /* create job */ + + jch = open (&jf, BIO); + if (jch<0) return (-2); + reset (jch); + + /* set job's NAMEs */ + + wuset (jch, USNAME, rsname()); + wuset (jch, UXJNAME, xjname); + + return (j_xxx (jch, xjname)); + } + +/********************************************************************** + + J_OWN - attach job as inferior + +**********************************************************************/ + +int j_own (uname, jname) + + {filespec fs; + int jch, j, w, sts; + + fs.dev = _USR; + fs.dir = 0; + fs.fn1 = uname; + fs.fn2 = jname; + + if ((jch = open (&fs, OLD + BII)) < 0) return (-5); + close (jch); + if ((jch = open (&fs, BIO)) < 0) return (-5); + if (status (jch) != 061) + {close (jch); return (-6);} + j = j_xxx (jch, jname); + if (ruset (jch, USTOP) & BUSRC) + {w = ruset (jch, UPIRQ); + if (w & PICZ) sts = js_attn; + else if (w & PIVAL) sts = js_valret; + else if (w) sts = w; + else sts = js_stopped; + wuset (jch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + } + else sts = js_running; + job_status[j] = sts; + return (j); + } + +/********************************************************************** + + J_XXX - common processing for new inferior + +**********************************************************************/ + +int j_xxx (jch, xjname) + + {int i, inf_no, option, j_handler(); + + /* get inferior number */ + + i = ruset (jch, UINF) >> 18; + inf_no = 0; + if (i) while (!(i&1)) {i=>>1; ++inf_no;} + + /* set up interrupt handler */ + + on (inferior0_interrupt+inf_no, j_handler); + option = ruset (jch, UOPTION); + wuset (jch, UOPTION, option | OPTBRK); + + /* clean up */ + + job_channels[inf_no] = jch; + if (job_status[inf_no] == js_nojob) + {job_status[inf_no] = js_stopped; + job_jcl[inf_no] = 0; + job_valret[inf_no] = 0; + } + job_name[inf_no] = ruset (jch, UJNAME); + job_xname[inf_no] = xjname; + + return (inf_no); + } + +int j_start (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, 0); + job_status[j] = js_running; + return (0); + } + +int j_stop (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, -1); + job_status[j] = js_stopped; + return (0); + } + +int j_disown (j) + + {int ch, ec; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + ec = sysdisown (ch); + if (ec) return (ec); + j_flush (j); + return (0); + } + +int j_forget (j) + + {int ch; + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + close (ch); + j_flush (j); + return (0); + } + +int j_kill (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + uclose (ch); + j_flush (j); + return (0); + } + +static int code[] { + 0042000000013, /* .IOPUSH 0, ;(26) DON'T CLOBBER HIM */ + 0041000000034, /* .OPEN 0,34 ;(27) OPEN */ + 0043100000000, /* .LOSE ;(30) FAIL, CAUSE ERR MSG */ + 0042000000027, /* .DISOWN 0, ;(31) DISOWN */ + 0042000000014, /* .IOPOP 0, ;(32) UNCLOBBER HIM */ + 0043200000000, /* .VALUE ;(33) RETURN SUCCESS */ + 0000001656362, /* 1,,'USR ;(34) FILENAME BLOCK */ + 0, /* ;(35) WILL GET UNAME */ + 0 /* ;(36) WILL GET JNAME */ + }; + +int j_snarf (j, jname) + + {int ch, piclr, pirqc, pc, osts, sts; + + if (j<0 || j>=MAXJOBS) return (-1); + osts = job_status[j]; + if (osts == js_running) return (-1); /* must be stopped */ + ch = job_channels[j]; + if (ch<0) return (-1); + code[7] = rsuset (UUNAME); + code[8] = jname; + access (ch, 026); + syswrite (ch, code, 9); + piclr = ruset (ch, UPICLR); + wuset (ch, UPICLR, 0); + pirqc = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, pirqc); + pc = ruset (ch, UPC); + wuset (ch, UPC, 026); + j_start (j); + sts = j_wait (j); + job_status[j] = osts; + if (sts == js_valret) sts = 0; + else {wuset (ch, UAPIRQ, sts); sts = -1;} + wuset (ch, UPC, pc); + wuset (ch, UIPIRQ, pirqc); + wuset (ch, UPICLR, piclr); + return (sts); + } + +int j_flush (j) + + {char *p; + + job_channels[j] = -1; + job_status[j] = js_nojob; + job_name[j] = 0; + if (p = job_jcl[j]) + {sfree (p); + job_jcl[j] = 0; + } + if (p = job_valret[j]) + {sfree (p); + job_valret[j] = 0; + } + on (inferior0_interrupt+j, 0); + } + +int j_give_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = atty (ch); + if (rc == 0) jobtty = j; + return (rc); + } + +int j_take_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = dtty (ch); + if (rc == 0) jobtty = -1; + return (rc); + } + +int j_grab_tty () + + {if (jobtty >= 0) + {int rc; + jobotty = jobtty; + jobosts = job_status[jobtty]; + j_stop (jobtty); + rc = j_take_tty (jobtty); + if (rc && jobosts==0) j_start (jobtty); + return (rc); + } + jobotty = -1; + return (0); + } + +int j_retn_tty () + + {if (jobtty < 0 && jobotty >= 0) + {j_give_tty (jobotty); + if (jobosts == 0) j_start (jobotty); + jobotty = -1; + } + } + +int j_wait (j) + + {int sts; + + if (j<0 || j>=MAXJOBS) return (-1); + job_wait = j; + sts = wfnz (&job_status[j]); + job_wait = -1; + return (sts); + } + +int j_onchange (f) int (*f)(); + + {jchandler = f; + } + +int j_sts (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_status[j]); + } + +int j_sjcl (j, s) char *s; + + {char *buf, *p; + int ch, i; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + if (*s==0) + {if (buf = job_jcl[j]) /* flush previous */ + {i = ruset (ch, UOPTION) & ~OPTCMD; + wuset (ch, UOPTION, i); + sfree (buf); + job_jcl[j] = 0; + } + return (0); + } + i = salloc (slen (s) + 2); + if (i <= 0) return (-1); + buf = i; + stcpy (s, buf); + p = buf; + while (*p) ++p; + if (p==buf || p[-1]!='\r') + {p[0] = '\r'; + p[1] = 0; + } + job_jcl[j] = buf; + wuset (ch, UOPTION, OPTCMD); + } + +char *j_jcl (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_jcl[j]); + } + +int j_ch (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_channels[j]); + } + +int j_name (j, f) filespec *f; + + {f->dev = _USR; + f->dir = 0; + f->fn1 = runame(); + if (j>=0 && jfn2 = job_name[j]; + return (f->fn2 == 0); + } + f->fn2 = 0; + return (-1); + } + +char *j_val (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_valret[j]); + } + +j_fval (j) + + {if (j<0 || j>=MAXJOBS) return; + if (job_valret[j] == 0) return; + cfree (job_valret[j]); + job_valret[j] = 0; + } + +j_handler (j) + + {int ch, w, opt, old_status; + + if (j<0 || j>=MAXJOBS) return; + ch = job_channels[j]; + if (ch<0) return; + + old_status = job_status[j]; + w = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + opt = ruset (ch, UOPTION); + if ((opt & OPTOPC)==0 && (w & IBACKUP)) + wuset (ch, UPC, ruset (ch, UPC) - 1); + + job_status[j] = w; + if (w & PICZ) /* ^Z typed */ + {job_status[j] = js_attn; + return; + } + if (w & PIVAL) /* .VALUE */ + jdovalue (j); + else if (w & PIBRK) /* .BREAK */ + jdobrk (j); + + if (j != job_wait && job_status[j] != old_status && jchandler) + (*jchandler)(j,job_status[j]); + } + +jdovalue (j) /* handle .VALUE */ + + {int ch, ich, cmda, n; + char *p, buf[VALBUFSIZ]; + filespec f; + + ch = job_channels[j]; + job_valret[j] = 0; + job_status[j] = js_valret; + cmda = ruset (ch, USV40) & 0777777; + if (cmda == 0) return; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + access (ich, cmda); + n = VALBUFSIZ; + p = buf; + while (TRUE) + {int w, i, c; + w = uiiot (ich); + for (i=0;i<5;++i) + {c = (w>>29) & 0177; + w =<< 7; + if (c!='\n') {*p++ = c; --n;} + if (c=='\r') {*p++ = '\n'; --n;} + if (!c) break; + if (n<=2) + {*p++ = c = 0; + break; + } + } + if (!c) break; + } + close (ich); + if (stcmp (buf, ":KILL\r") || stcmp (buf, ":KILL\r\n")) + {/* if (job_wait != j) j_kill (j); + else */ job_status[j] = js_suicide; + return; + } + p = calloc (slen (buf) + 1); + stcpy (buf, p); + job_valret[j] = p; + return; + } + +jdobrk (j) /* handle .BREAK */ + /* unless there is a 'fatal error', the job status + must be changed to something reasonable */ + + {int ch, i; + ch = job_channels[j]; + wuset (ch, UAPIRQ, PIBRK); /* reset PIRQ bit */ + i = ruset (ch, USV40); /* the instruction */ + if ((i & ~000740000000) == 042000000033) + i = 045700160000; /* .LOGOUT n, */ + switch (i>>18) { /* opcode */ + +case 045700: /* .BREAK 16 */ + /* if ((i & 020000) && (job_wait != j)) j_kill (j); + else */ job_status[j] = js_suicide; + return; + +case 045500: /* .BREAK 12 */ + jdob12 (j, i); + return; + } + + j_start (j); + } + +jdob12 (j, i) /* handle .BREAK 12 */ + + {int cmda, ich, och; + filespec f; + + cmda = i & 0777777; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + if ((och = open (&f, UIO)) < 0) + {close (ich); + return; + } + access (ich, cmda); + i = uiiot (ich); + if (i & 0200000000000) /* multiple commands */ + {int n, a; + n = (i>>18) | 0777777000000; + a = i & 0777777; + while (n<0) + {access (och, cmda); + ++n; + ++a; + uoiot (och, (n<<18) | a); + access (ich, a-1); + do_brk (j, ich, och, uiiot (ich)); + } + } + else do_brk (j, ich, och, i); + close (ich); + close (och); + j_start (j); + } + +do_brk (j, ich, och, w) /* do .BREAK 12 command W */ + + {int cmd, a, f, i; + + cmd = (w>>18) & 0177777; + a = w & 0777777; + access (och, a); + if (cmd==6) /* send :PRINT defaults */ + {uoiot (och, _DSK); + uoiot (och, rsname ()); + uoiot (och, _FOO); + uoiot (och, _GR); + return; + } + if (cmd==5 && job_jcl[j]) + {f = copen (job_jcl[j], 'r', "s"); + access (ich, a+2); + while (TRUE) + {w = 0; + for (i=0;i<5;++i) w = (w<<7) | (cgetc (f) & 0177); + w =<< 1; + uoiot (och, w); + if ((w & 0377) == 0) break; + if (uiiot (ich)) + {uoiot (och, 0); + break; + } + } + cclose (f); + return; + } + if (cmd==10) /* send XJNAME */ + {uoiot (och, job_xname[j]); + return; + } + } + \ No newline at end of file diff --git a/arc/ar2:clib/C10MAP C b/arc/ar2:clib/C10MAP C new file mode 100644 index 00000000..9488f97a --- /dev/null +++ b/arc/ar2:clib/C10MAP C @@ -0,0 +1,58 @@ +/* + + FILMAP - file mapping routines + + filmap (c, o, s) map in part of a file + filunmap (p, s) unmap part of a file + +*/ + +# include "c.defs" + +/********************************************************************** + + FILMAP - map in a part of a disk file + return a pointer to it + +**********************************************************************/ + +int *filmap (ch, offset, size) + + {int block_no, page_no, word_no, no_pages, i; + int *p; + + block_no = offset>>10; + word_no = offset & 01777; + no_pages = ((word_no + size - 1) >> 10) + 1; + page_no = pg_get (no_pages); + if (page_no < 0) + {puts ("FILMAP: Unable to Allocate Pages.\n"); + return (0); + } + for (i=0;i> 10; + no_pages = ((word_no + size - 1) >> 10) + 1; + pg_ret (page_no, no_pages); + } + + \ No newline at end of file diff --git a/arc/ar2:clib/C10MIO CMID b/arc/ar2:clib/C10MIO CMID new file mode 100644 index 00000000..69280cd2 --- /dev/null +++ b/arc/ar2:clib/C10MIO CMID @@ -0,0 +1,490 @@ +; +; C10MIO - C I/O ROUTINES WRITTEN IN MIDAS +; +; This file is ITS dependent. +; + +TITLE MIO +.INSRT NC +.INSRT NM + +; INCLUDES: +; +; CGETC - CIO GET CHARACTER +; CPUTC - CIO PUT CHARACTER +; CGETI - CIO GET INTEGER (IMAGE) +; CPUTI - CIO PUT INTEGER (IMAGE) +; CEOF - CIO TEST FOR END-OF-FILE +; CFLUSH - CIO FLUSH BUFFER +; REW - REWIND INPUT FILE +; CLOSALL - CIO CLOSE ALL FILES +; CCLOSE - CIO CLOSE FILE +; ISTTY - IS FILE A TTY? +; CISFD - IS PTR AN ACTUAL FILE DESCRIPTOR? +; ITSCHAN - RETURN ACTUAL ITS CHANNEL +; + +; REGISTERS + +FP==3 ; FILE CONTROL BLOCK POINTER +T1==4 ; TEMPORARY + +; VALUES + +NL==12 +CR==15 + +; FILE CONTROL BLOCK ENTRIES + +FBUFFP==0 ; (LEFT HALF) POINTER TO BUFFER (OR ZERO IF NOT BUFFERED) + FCHAN: 160400,,(FP) ; ITS CHANNEL NUMBER + FDEVIC: 100600,,(FP) ; DEVICE CODE +FFLAG==0 ; (RIGHTMOST 8 BITS) FLAGS + PHYEOF==1 ; PHYSICAL EOF REACHED (BUFFERED INPUT) + %OPEN==2 ; FILE IS OPEN + %WRITE==4 ; FILE IS OPEN FOR WRITE + %TTY==10 ; FILE IS TTY + %UNSET==20 ; DEVICE AND CHANNEL NOT SET YET +FBPTR==1 ; POINTER TO NEXT CHAR/WORD OR CHAR/WORD POSITION +FBCNT==2 ; NUMBER OF CHARS/WORDS OR AVAILABLE POSITIONS IN BUFFER +FUCNT==3 ; (LEFT HALF) NUMBER OF CHARS IN UNGETC BUFFER +FUPTR==3 ; (RIGHT HALF) POINTER TO UNGETC BUFFER +FCLSR==4 ; (LEFT HALF) ADDRESS OF CLOSE ROUTINE +FNGETR==4 ; (RIGHT HALF) ADDRESS OF NORMAL GETC ROUTINE +FGETCR==5 ; ADDRESS OF CGETC ROUTINE +FPUTCR==6 ; ADDRESS OF CPUTC ROUTINE +FCBSIZ==7 ; SIZE OF FILE CONTROL BLOCK + +; CONSTANTS + +IBFSIZ==200 +NCHAN==10. +UBFFSZ==20. + +CENTRY CGETC,[FD] +XENTRY GETC,CGETC +XENTRY CGETI,CGETC +XENTRY GETI,CGETC + + HRRZ FP,FD ; FILE DESCRIPTOR + GO @FGETCR(FP) ; JUMP TO APPROPRIATE ROUTINE + +GETBUF: SOSGE FBCNT(FP) ; HERE FOR BUFFERED CHAR INPUT + JSP B,GTBUF1 ; BUFFER EMPTY, GO FILL IT + ILDB A,FBPTR(FP) ; GET NEXT CHAR FROM BUFFER + CAIN A,CR ; IGNORE INCOMING CR + GO GETBUF + RETURN + +GETBIN: SOSGE FBCNT(FP) ; HERE FOR BINARY INPUT + GO GTBIN1 ; BUFFER EMPTY, REFILL IT + MOVE A,@FBPTR(FP) ; GET NEXT WORD FROM BUFFER + AOS FBPTR(FP) ; INCR POINTER + RETURN + +GETSTR: MOVE A,@FBPTR(FP) ; HERE FOR STRING INPUT + AOS FBPTR(FP) ; INCR POINTER + JUMPE A,NEWEOF + RETURN + +GETTTY: CALL TYI ; HERE FOR TTY INPUT + HRRZ FP,FD ; RESTORE FP + JUMPE A,NEWEOF + RETURN + +IENTRY GC$BAD + CROAK BAD CALL TO CGETC/CGETI + SETO A, + RETURN + +GETUN: HLRZ B,FUCNT(FP) ; HERE WHEN CHAR IN UNGETC BUFFER + JUMPLE B,CODE [ ; IS UNGETC BUFFER EMPTY? + HRRZ A,FNGETR(FP) ; YES + MOVEM A,FGETCR(FP) ; RESTORE CGETC ROUTINE + GO (A) ; GET NEXT CHAR + ] + HRRZ A,FUPTR(FP) + ADD A,B + HRRZ A,(A) ; GET CHAR + SUBI B,1 ; DECR COUNT + HRLM B,FUCNT(FP) + RETURN + +NEWEOF: MOVEI A,EOF ; HERE ON NEWLY DISCOVERED EOF + MOVEM A,FGETCR(FP) + HRRM A,FNGETR(FP) ; SET CGETC ROUTINE TO EOF +EOF: SETZ A, + RETURN + +; BUFFERED CHARACTER INPUT - BUFFER READ ROUTINE +; +; CONTAINS HACKERY WHICH ALLOWS DETECTION OF LAST WORD +; OF FILE. TRAILING CONTROL-C'S ARE REMOVED FROM THIS +; WORD. CALLED VIA JSP B, +; + +GTBUF1: HRRZ T1,FFLAG(FP) ; HERE TO FILL OR REFILL BUFFER + TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED? + GO NEWEOF ; YES, ANNOUNCE IT + MOVN A,FBCNT(FP) ; OLD CHARACTER COUNT (CHECKED LATER) + MOVEI T1,5* ; RESET CHARACTER COUNT + MOVEM T1,FBCNT(FP) ; (LAST WORD SAVED FOR NEXT BUFFER) + HLRZ T1,FBUFFP(FP) ; RESET CHARACTER POINTER + HRLI T1,440700 ; TO BEGINNING OF BUFFER + MOVEM T1,FBPTR(FP) + CAIE A,2 ; CHECK OLD COUNT FOR SPECIAL VALUE + GO GTBUF2 ; NORMAL (NOT INIT) CASE + HLRZ T1,FBUFFP(FP) ; FIRST TIME - FILL ENTIRE BUFFER + HRLI T1,-IBFSIZ + GO GTBUF3 + +GTBUF2: HLRZ T1,FBUFFP(FP) ; NORMAL CASE - ONE WORD SAVED FROM LAST READ + MOVE A,IBFSIZ-1(T1) ; GET LAST WORD OF BUFFER (UNREAD) + MOVEM A,(T1) ; MAKE FIRST WORD OF BUFFER + ADDI T1,1 ; ADJUST CPTR TO FILL REST OF BUFFER + HRLI T1,-IBFSIZ+1 + +GTBUF3: LDB A,FCHAN ; ITS CHANNEL NUMBER + LSH A,23. + IOR A,[.IOT T1] + XCT A ; EXECUTE .IOT + JUMPGE T1,-2(B) ; BUFFER WAS FILLED, NO MORE TO DO + HLRES T1 + ADDI T1,IBFSIZ ; NUMBER OF WORDS READ + HLRZ A,FBUFFP(FP) + ADDI A,-1(T1) ; POINTER TO WORD LAST READ + IMULI T1,5 ; NUMBER OF CHARS READ + PPUSH B + MOVEI B,5 ; CHECK FOR AT MOST 5 TRAILING ^C'S + HRLI A,010700 ; BYTE POINTER TO LAST CHAR +GTBUF4: LDB 0,A ; GRAB CHARACTER + ADD A,[070000,,0] ; DECREMENT BYTE POINTER + CAIE 0,3 ; IS IT A ^C + GO GTBUF5 ; NO + SUBI T1,1 ; DECREMENT CHARACTER COUNT + SOJG B,GTBUF4 ; KEEP LOOKING +GTBUF5: PPOP B + MOVEM T1,FBCNT(FP) ; SET CHARACTER COUNT + MOVEI T1,PHYEOF + IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG + GO -2(B) ; THAT'S IT! + +; +; GTBIN1 - INTERNAL CODE FOR BINARY BUFFER GET +; +GTBIN1: HRRZ T1,FFLAG(FP) ; HERE TO REFILL BUFFER IN BINARY MODE + TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED? + GO NEWEOF ; YES, ANNOUNCE IT + MOVEI T1,IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) ; BUFFER POINTER + MOVEM T1,FBPTR(FP) ; RESET POINTER + HRLI T1,-IBFSIZ ; COUNTING POINTER FOR IOT + LDB A,FCHAN + LSH A,23. + IOR A,[.IOT T1] ; SET UP .IOT INSTRUCTION + XCT A ; EXECUTE .IOT INSTRUCTION + JUMPGE T1,GETBIN ; BUFFER WAS FILLED, RESUME + HLRES T1 + ADDI T1,IBFSIZ ; NUMBER OF WORDS ACTUALLY READ + MOVEM T1,FBCNT(FP) ; SET COUNTER + MOVEI T1,PHYEOF + IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG + GO GETBIN ; RESUME + +CENTRY CPUTC,[CC,FD] +XENTRY PUTC,CPUTC +XENTRY CPUTI,CPUTC +XENTRY PUTI,CPUTC + + HRRZ FP,FD ; FILE DESCRIPTOR + MOVE A,CC ; CHARACTER (OR INTEGER) TO BE WRITTEN + GO @FPUTCR(FP) ; JUMP TO APPROPRIATE ROUTINE + +PUTBUF: CAIN A,NL ; HERE FOR BUFFERED CHAR OUTPUT + GO CODE [ + CALL CPUTC,[[[CR]],FP] + HRRZ FP,FD + MOVEI A,NL + GO PF$1 + ] + JUMPE A,PC$RET ; DONT WRITE NULLS +PF$1: IDPB A,FBPTR(FP) ; STORE CHAR + SOSG FBCNT(FP) ; BUFFER FULL? + GO CODE [ ; YES + MCALL FLUSHB,[FP,[[IBFSIZ]]] ; FLUSH ENTIRE BUFFER + GO PC$RET + ] +PC$RET: RETURN ; NO, RETURN + +PUTBIN: MOVEM A,@FBPTR(FP) ; HERE ON BINARY OUTPUT + AOS FBPTR(FP) + SOSLE FBCNT(FP) + GO PC$RET + HLRZ T1,FBUFFP(FP) + HRLI T1,-IBFSIZ ; SET UP COUNTING POINTER FOR .IOT + LDB A,FCHAN ; GET ITS CHANNEL NUMBER + LSH A,23. + IOR A,[.IOT T1] ; PREPARE .IOT INSTRUCTION + XCT A ; EXECUTE .IOT INSTRUCTION + MOVEI T1,IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) + MOVEM T1,FBPTR(FP) ; RESET POINTER + GO PC$RET + +PUTSTR: MOVEM A,@FBPTR(FP) ; HERE ON STRING OUTPUT + AOS FBPTR(FP) + GO PC$RET + +PUTTTY: CAIN A,NL ; HERE ON TTY OUTPUT + MOVEI A,CR ; OUTPUT NEWLINES AS CR'S + CALL TYO,[A] + GO PC$RET + +IENTRY PC$BAD + CROAK BAD CALL TO CPUTC/CPUTI + SETO A, + GO PC$RET + +CENTRY CEOF,[FD] + + HRRZ FP,FD + SETZ A, + HRRZ B,FGETCR(FP) + CAIN B,EOF + MOVEI A,1 + CAIN B,GC$BAD + SETO A, + RETURN + +CENTRY UNGETC,[CC,FD] + + HRRZ FP,FD ; FILE DESCRIPTOR + MOVE A,CC ; CHARACTER + HLRZ T1,FUCNT(FP) ; NUMBER OF CHARS IN BUFFER + ADDI T1,1 + CAIL T1,UBFFSZ ; TOO MANY? + GO CODE [ + SETO A, + GO UN$RET + ] + HRLM T1,FUCNT(FP) + HRRZ B,FUPTR(FP) + ADD T1,B + MOVEM A,(T1) ; STORE CHAR + MOVEI B,GETUN + MOVEM B,FGETCR(FP) ; SET UP GETC ROUTINE +UN$RET: RETURN + +CENTRY CFLUSH,[FD] + + MCALL FLUSHP,[FD,[[0]]] + RETURN + +MENTRY FLUSHP,[FD,PADC] + + HRRZ FP,FD + HRRZ A,FPUTCR(FP) ; OUTPUT ROUTINE + CAIE A,PUTBUF + GO FL$RET + HRRZ T1,PADC ; PAD CHARACTER + MOVEI A,5*IBFSIZ ; NUMBER OF CHAR POSITIONS + SUB A,FBCNT(FP) ; NUMBER OF ACTUAL CHARS IN BUFFER + JUMPLE A,FL$RET ; BUFFER IS EMPTY + IDIVI A,5 + JUMPE B,FL$1 ; NO PARTIALLY FILLED WORDS + MOVN B,B + ADDI B,5 + IDPB T1,FBPTR(FP) ; FILL OUT WITH ^C'S + SOJG B,.-1 + ADDI A,1 +FL$1: MCALL FLUSHB,[FP,A] +FL$RET: RETURN + +MENTRY FLUSHB,[FD,SIZE] + + MOVE FP,FD ; FILE POINTER + MOVN T1,SIZE ; SIZE OF FILLED PART OF BUFFER + HRLZ T1,T1 ; CONSTRUCT + HLR T1,FBUFFP(FP) ; .IOT POINTER + LDB B,FCHAN + LSH B,23. + IOR B,[.IOT T1] ; PREPARE .IOT INSTRUCTION + XCT B ; EXECUTE .IOT INSTRUCTION + MOVEI T1,5*IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) + HRLI T1,440700 + MOVEM T1,FBPTR(FP) ; RESET ABPTR + RETURN + +CENTRY REW,[FD] + + HRRZ FP,FD + SETOM FBCNT(FP) + HRRZ A,FFLAG(FP) + TRZ A,PHYEOF + HRRM A,FFLAG(FP) + MOVE A,GETTAB+1 + MOVEM A,FGETCR(FP) + LDB A,FCHAN + .CALL [SETZ ? 'ACCESS ? A ? 401000,,0] + CROAK REW: ACCESS FAILED + RETURN + +CENTRY CLOSALL,,[COUNTER] ; CLOSE ALL C FILES + + MOVEI A,NCHAN-1 + MOVEM A,COUNTER + MOVE A,COUNTER +CA$1: CALL CCLOSE,[FCBTBL(A)] + SOSL A,COUNTER + GO CA$1 + RETURN + +CENTRY CCLOSE,[FD] + + HRRZ FP,FD + HLRZ A,FCLSR(FP) + GO (A) ; JUMP TO APPROPRIATE ROUTINE + +CLOBUF: MCALL FLUSHP,[FP,[[3]]] + GO CLIBUF + +CLOBIN: MOVE A,FBCNT(FP) ; HERE ON BINARY OUTPUT + SUBI A,IBFSIZ + JUMPGE A,CLIBUF + HRLZ A,A + HLR A,FBUFFP(FP) + LDB B,FCHAN + LSH B,23. + IOR B,[.IOT A] + XCT B ; FLUSH BUFFER + +CLIBUF: LDB A,FCHAN ; HERE ON BUFFERED AND BINARY INPUT + ; ALSO FALL THROUGH FROM BUFFERED AND BINARY OUTPUT + CALL MCLOSE,[A] + MOVE FP,FD + +CLTTY: SETZ A, ; HERE ON TTY AND FALL THROUGH + +CLOSE2: MOVEI T1,%OPEN ; HERE TO CLEAR %OPEN BIT + ANDCAM T1,FFLAG(FP) + MOVEI T1,GC$BAD ; SET ROUTINES TO BAD + MOVEM T1,FGETCR(FP) + MOVEI T1,PC$BAD + MOVEM T1,FPUTCR(FP) + MOVE T1,[CL$BAD,,GC$BAD] + MOVEM T1,FCLSR(FP) +CL$RET: RETURN + +CLOSTR: MOVE A,FBPTR(FP) ; HERE ON STRING OUTPUT + SETZM (A) ; APPEND NULL ONTO STRING + GO CLOSE2 ; RETURN POINTER TO NULL CHAR + +IENTRY CL$BAD + SETO A, + GO CL$RET + +CENTRY ISTTY,[FD] + + HRRZ FP,FD + HRRZ A,FFLAG(FP) + TRNE A,%UNSET ; IS DEVICE CODE VALID? + GO IS$RET ; NO -- MUST BE A TTY + LDB A,FDEVICE ; GET IT + CAILE A,2 ; TEST FOR TTY DEVICES + SETZ A, +IS$RET: RETURN + +; INTERNAL ROUTINE TO SET DEVICE AND CHANNEL +; MUST BE THE TTY INPUT OR OUTPUT CHANNEL +; RETURN DEVICE CODE + +MENTRY SETDEV,[FD] + + HRRZ FP,FD + MOVE A,FFLAG(FP) + TRNE A,%WRITE + MOVEI B,ZTYOOPN" + TRNN A,%WRITE + MOVEI B,ZTYIOPN" + VCALL (B) + JUMPL A,SD$RET ; VALID CHANNEL RETURNED? + HRRZ FP,FD + DPB A,FCHAN ; YES - STORE IT + LSH A,23. + IOR A,[.STATUS A] + XCT A + ANDI A,77 ; GET DEVICE FROM CHANNEL STATUS + DPB A,FDEVIC ; STORE DEVICE + MOVEI T1,%UNSET ; CLEAR %UNSET BIT + ANDCAM T1,FFLAG(FP) +SD$RET: RETURN + +CENTRY CISFD,[FD] + + MOVE A,FD + CAIGE A,C0FCBS+1 + GO ISF$NO + CAIL A,C0FCBS+1+NCHAN*FCBSIZ + GO ISF$NO + MOVEI A,1 + RETURN +ISF$NO: SETZ A, + RETURN + +CENTRY ITSCHAN,[FD] + + HRRZ FP,FD + HRRZ A,FFLAG(FP) + TRNN A,%UNSET ; IS CHANNEL CODE VALID? + GO IC$1 ; YES - GET IT + MCALL SETDEV,[FD] ; NO -- SET IT AND RETURN IT + RETURN +IC$1: LDB A,FCHAN ; GET CHANNEL + RETURN + +.PDATA +MDATA GETTAB + GETTTY + GETBUF + GETBIN + GETSTR + GC$BAD + GC$BAD + GC$BAD + GC$BAD + +MDATA PUTTAB + PC$BAD + PC$BAD + PC$BAD + PC$BAD + PUTTTY + PUTBUF + PUTBIN + PUTSTR + +MDATA CLOTAB + CLTTY + CLIBUF + CLIBUF + CLTTY + CLTTY + CLOBUF + CLOBIN + CLOSTR + +; STATIC DATA AREAS + +.UDATA +MDATA C0FCBS + BLOCK NCHAN*FCBSIZ+1 + +MDATA FCBTBL +REPEAT NCHAN C0FCBS+1+.RPCNT*FCBSIZ + +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10PAG C b/arc/ar2:clib/C10PAG C new file mode 100644 index 00000000..512e57ea --- /dev/null +++ b/arc/ar2:clib/C10PAG C @@ -0,0 +1,111 @@ +/* + * C PAGE Handling Package + * + * routines: + * + * pg = pg_get (n) + * rc = pg_ret (pg, n) + * b = pg_exist (pg) + * i = pg_nshare (pg) + * i = pp_nshare (p) + * + */ + +# include "c.defs" + +# rename page_table "PAGTAB" +# rename first_free_page "FFPAGE" + +int first_free_page; +extern int page_table [256]; +extern int cerr; + +/********************************************************************** + + PG_GET - Page Get + + Allocate "n" contiguous unused pages in the address space. + Return the number of the lowest page allocated, or -1 + if unable to allocate pages. + +**********************************************************************/ + +int pg_get (n) + + {int page, i, top, tp, n_free; + + if (n<1 || n>254) return (-1); + page = first_free_page; /* first page we examine */ + top = 256-n; /* highest possible low page */ + n_free = 0; /* number of free pages we see */ + while (page <= top) + {for (i=0;i=n) break; /* success */ + page =+ i+1; + } + if (page > top) return (-1); + for (i=0;i256) + {cprint (cerr, "PG_RET: invalid page number %d.\n", page); + return (-1); + } + if (page < first_free_page) first_free_page = page; + while (--n >= 0) + {page_table[page] = 0; + corblk (0, -1, page, -1, page); + ++page; + } + return (0); + } + +/********************************************************************** + + PG_EXIST - Does page exist in address space? + +**********************************************************************/ + +pg_exist (page_no) + + {int blk[4]; + + cortyp (page_no, blk); + return (page_table[page_no] = (blk[0] != 0)); + } + + +/********************************************************************** + + PG_NSHARE - Return number of times page is shared + +**********************************************************************/ + +pp_nshare (p) {return (pg_nshare (p>>10));} + +pg_nshare (page_no) + + {int blk[4]; + + cortyp (page_no, blk); + return (blk[3] & 0777777); + } + + \ No newline at end of file diff --git a/arc/ar2:clib/C10RUN CMID b/arc/ar2:clib/C10RUN CMID new file mode 100644 index 00000000..a3a1ee4d --- /dev/null +++ b/arc/ar2:clib/C10RUN CMID @@ -0,0 +1,431 @@ +; +; C10RUN - BASIC C RUN-TIME SUPPORT +; +; This file is ITS dependent. +; + +TITLE CRUN +.INSRT NC +.INSRT NM + +.GLOBAL A,B,C,D,P,GO,.CCALL,.VCALL,.ACALL,.XCALL + +PDLSIZ==20000 ; DESIRED PDL SIZE +MAXARG==40. ; MAXIMUM NUMBER OF ARGUMENTS +BUFSZ==250. ; COMMAND BUFFER SIZE IN CHARACTERS +TP==16 + +; +; START-UP ROUTINE +; + +IENTRY START + + ; ENABLE INTERRUPTS + + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLO A,OPTOPC+OPTINT ; SET OLD PC ON MPV, IOC AND + ; USE NEW INTERRUPT STACKING SCHEME + .SUSET [.SOPTI,,A] ; SET OPTION WORD + + MOVE A,[-TSINTL",,TSINT"] ; SET UP INTERRUPT HANDLING + MOVEM A,42 + MOVEI A,%PIMPV+%PIPDL ; ENABLE MPV AND PDL OVERFLOW + .SUSET [.SMASK,,A] + + ;SET UP UUO HANDLER + + MOVE A,[JSR UUOH"] + MOVEM A,41 + + MOVE P,PDLBOT ; STACK + MOVE TP,TPINIT ; TIME STACK (IF IN TIMING MODE) + MCALL $SETUP +IENTRY RESTART + MOVE P,PDLBOT + VCALL @CALLER,[ARGC,[[ARGV]]] + CALL CEXIT,[[[0]]] +IENTRY .EXIT + SETZM TIMING + SKIPE EXITER + VCALL @EXITER ; CLEAN-UP TIMING + .LOGOUT ; IN CASE WE ARE AT TOP LEVEL + .BREAK 16,160000 ; COMMIT SUICIDE + +; SETUP ROUTINE + +; TURN OFF TTY ECHOING, READ AND PARSE JCL COMMAND, +; GET JOB NAME, INITIALIZE I/O, OPEN TTY + +MENTRY $SETUP + + ; TURN OFF TTY ECHOING + + .SUSET [.RTTY,,A] ; READ TTY WORD + TLNE A,400000 ; TEST %TBNOT BIT + GO SET$0 ; DONT HAVE TTY + .OPEN 17,[SIXBIT/ TTY/] + GO SET$0 ; WHO CARES IF IT FAILS + .CALL [SETZ ; TURN OFF ECHOING + 'TTYSET + 1000,,17 + [020202020202] + SETZ [030202020202] + ] + JFCL + .CLOSE 17, + +SET$0: .CLOSE 1, ; HACK FOR TOP-LEVEL BOOTSTRAP + .CLOSE 2, + .CLOSE 3, + + ; READ JCL + + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLNN A,OPTCMD ; IS THERE SOME JCL + GO SET$2 ; NOPE + + SETZM JCLBUF ; FIRST WORD -- MAKE SURE ITS THERE + SETOM JCLBUF+-1 ; LAST WORD OF JCLBUF + .BREAK 12,[..RJCL,,JCLBUF] ; READ JCL + + ; READ JOB NAME + +SET$2: .SUSET [.RXJNAME,,XJNAME] + + ; PARSE JCL + + MCALL PRSARG,[[[440700,,JCLBUF]],[[ARGBUF]],[[ARGV]],XJNAME,[[MAXARG]]] + MOVEM A,ARGC + + CALL C0INIT ; INITIALIZE C I/O ROUTINES + CALL FXARG,[ARGC,[[ARGV]]] ; DO REDIRECTION OF STANDARD I/O + MOVEM A,ARGC + + .SUSET [.RTTY,,A] ; READ TTY WORD + TLNE A,400000 ; TEST %TBNOT BIT + GO SET$R ; RETURN IF DONT HAVE TTY + CALL TYIOPN ; ENABLE INTERRUPT CHARS +SET$R: RETURN + +IENTRY STKDMP + + PUSH P,0 ; SAVE REGISTERS + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,[0] ; PLACE TO SAVE 'REAL' RETURN ADDRESS + PUSH P,[0] ; ZERO ARG TO STKDMP + .VALUE [ASCIZ\..XECP/0/1Q +P\] + MOVEM 0,-1(P) ; SAVE AWAY 'REAL' RETURN ADDRESS + PUSHJ P,ZSTKDMP" + POP P,(P) + POP P,D + POP P,C + POP P,B + POP P,A + POP P,0 + POPJ P, + +; +; EXIT ROUTINES +; + +CENTRY CEXIT,[CC] + CALL CLOSALL + MOVE A,CC + GO .EXIT + +CENTRY CQUIT,[CC] + CROAK CQUIT CALLED + CALL CEXIT,[CC] + + +; CODE TO PERFORM LOAD-TIME INITIALIZATION +; FLUSHES ZERO PAGES IN IMPURE AREAS + +.IDATA +; NO LITERALS IN THIS CODE! + +IENTRY LBINIT ; INIT FOR MAKING LIBRARY + SETZM IFLUSH ; DON'T FLUSH ZERO-PAGES BECAUSE + ; MAKLIB EXPECTS THEM TO BE THERE + MOVE A,LBD1 ; RESET FLUSH-FLAG WHEN DONE + MOVEM A,IDONE + GO LINIT +LBD1: SETOM IFLUSH + +IENTRY LINIT + + MOVEI P,ARGV ; TEMPORARY PDL + +IENTRY ISTART + + JFCL + + ; SETUP SEGMENT BOUNDARIES + + HLRZ A,20 + MOVEM A,SEG0LO + HRRZ A,20 + MOVEM A,SEG0HI + SETZM 20 + HLRZ A,21 + MOVEM A,SEG1LO + HRRZ A,21 + MOVEM A,SEG1HI + SETZM 21 + HLRZ A,22 + MOVEM A,SEG2LO + HRRZ A,22 + MOVEM A,SEG2HI + SETZM 22 + HLRZ A,23 + MOVEM A,SEG3LO + HRRZ A,23 + MOVEM A,SEG3HI + SETZM 23 + + ; INITIALIZE PAGE-TABLE + + MOVEI A,256. +I$LOOP: SOJL A,I$SMSH ; A IS PAGE NUMBER + .CALL I$CORT ; GET PAGE INFO + .VALUE I$MES1 ; SYSTEM CALL LOST + MOVEM B,PAGTAB(A) + GO I$LOOP + + ; NOW LOOK FOR .CCALLS TO SMASH + +I$SMSH: SKIPE TIMING ; DON'T SMASH IF TIMING + GO I$FLSH + SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA +I$S1: ADDI A,1 ; NEXT WORD + CAML A,SEG2HI ; AT END OF CODE AREA? + GO I$PURE ; DONE + HLRZ B,(A) ; INSTRUCTION + TRZ B,000777 ; ISOLATE OPCODE + CAIE B,(.CCALL) ; IS IT A .CCALL? + GO I$S1 ; NO, GO ON + HLRZ B,(A) ; THE INSTRUCTION AGAIN + TRNN B,000037 ; IS INDEXING OR INDIRECTION USED + GO I$S6 ; NO, IT'S A CONSTANT CALL + TRZ B,777000 ; SMASH OPCODE + IORI B,(.VCALL) ; MAKE IT A .VCALL + HRLM B,(A) ; SMASH THE .CCALL + GO I$S1 ; GO ON TO NEXT WORD + +I$S6: HRRZ C,(A) ; THE CALLED PROCEDURE + JUMPE C,I$S1 ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO I$S1 ; NO, NOT A PROCEDURE + LDB B,[270400,,(A)] ; THE NUMBER OF ACTUAL ARGS + CAIE 0,(B) ; DO THE NUMBERS MATCH? + GO I$S2 ; NO + MOVEI B,(PUSHJ P,) + HRLM B,(A) ; SMASH .CCALL TO PUSHJ + GO I$S1 + + ; HERE IF NUMBER OF ACTUALS AND FORMALS ARE DIFFERENT + +I$S2: SUBI 0,(B) ; NUMBER OF EXTRA ACTUALS NEEDED + JUMPL 0,I$S5 ; TOO MANY ACTUALS GIVEN + MOVE B,0 + ADDI B,2 + CL I$ALLC ; ALLOCATE SPACE FOR PROG + HRRZ B,D ; ADDRESS OF BLOCK + HRLI B,(JSP D,) ; CONSTRUCT CALL TO IT + MOVEM B,(A) ; SMASH ORIGINAL CALL + SUBI D,1 +I$S3: SOJL 0,I$S4 ; FOR EACH MISSING ARG + PUSH D,PZERO ; COMPILE A PUSH OF ZERO + GO I$S3 +I$S4: PUSH D,PUSHD ; COMPILE A PUSH OF D (RETURN ADDRESS) + HRLI C,(GO) ; MAKE JUMP TO CALLED PROC + PUSH D,C ; COMPILE CALL + GO I$S1 ; FINISHED WITH THIS CALL + + ; HERE IF NUMBER OF ACTUALS EXCEEDS NUMBER OF FORMALS + +I$S5: MOVEI B,3 ; GET TWO WORDS + CL I$ALLC + HRRZ B,D ; ADDRESS OF BLOCK + HRLI B,(JSP D,) ; MAKE CALL TO IT + MOVEM B,(A) ; SMASH ORIGINAL CALL + MOVN B,0 ; NUMBER OF EXTRA ARGS + HRLI B,(SUBI P,) ; CONSTRUCT INSTRUCTION + MOVEM B,(D) ; STORE IN BLOCK + MOVE B,PUSHD + MOVEM B,1(D) + HRLI C,(GO) ; MAKE JUMP TO CALLED PROC + MOVEM C,2(D) ; STORE IN BLOCK + GO I$S1 ; FINISHED WITH THIS CALL + + ; NOW PURIFY HIGH SEGMENTS + +I$PURE: MOVE A,SEG2LO + TRZ A,1777 + MOVE B,SEG2HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PBLK + .VALUE I$MES4 + MOVE A,SEG3LO + TRZ A,1777 + MOVE B,SEG3HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PBLK + .VALUE I$MES4 + + ; NOW LOOK FOR ZERO-PAGES TO FLUSH + +I$FLSH: SKIPN IFLUSH + GO I$DONE + MOVEI A,0 ; FIRST PAGE IS 1 (CAN'T FLUSH 0!) +NXTPAG: ADDI A,1 ; CURRENT PAGE NUMBER + MOVE B,A + LSH B,10. ; POINTER TO FIRST WORD IN PAGE + CAMLE B,SEG1HI ; STILL IN IMPURE AREA? + GO I$DONE ; NO, DONE + SKIPN PAGTAB(A) ; DOES PAGE EXIST? + GO NXTPAG ; NO, TRY NEXT ONE +NXTWRD: SKIPE (B) ; IS THE WORD ZERO + GO NXTPAG ; NO, CAN'T FLUSH THIS PAGE + ADDI B,1 ; NEXT WORD + TRNE B,1777 ; IN NEXT PAGE? + GO NXTWRD ; NO, KEEP GOING + .CALL I$CORB ; YES, DELETE PAGE + .VALUE I$MES2 ; SYSTEM CALL LOST + GO NXTPAG ; GO ON TO NEXT PAGE + +I$DONE: + +IENTRY IDONE + + JFCL + SETZ A, ; CLEAN UP + SETZ B, ; LIKE A GOOD BOY SHOULD + SETZ C, + SETZ D, + .BREAK 16,0 ; RETURN TO LOADER + + ; STORAGE ALLOCATOR FOR .CCALL COMPILER + ; CALL WITH SIZE IN B + ; RETURNS ADDRESS IN D + +I$ALLC: MOVE D,SEG3HI ; TOP OF PATCH SPACE + ADDI D,1 ; POINT TO NEW BLOCK + ADDB B,SEG3HI ; NEW TOP OF PATCH SPACE + LSH B,-10. ; PAGE OF TOP OF PATCH SPACE + SKIPE PAGTAB(B) ; DOES PAGE EXIST? + RTN ; YES + .CALL I$GETB ; GET PAGE + .VALUE I$MES3 ; SYSTEM CALL LOST + SETOM PAGTAB(B) ; UPDATE PAGE TABLE + RTN ; RETURN + +MDATA TIMING + 0 + +IFLUSH: -1 ; FLUSH ZERO PAGES +I$CORT: SETZ ? 'CORTYP ? A ? 402000,,B +I$CORB: SETZ ? 'CORBLK ? 1000,,0 ? 1000,,%JSELF ? SETZ A +I$PBLK: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A +I$GETB: SETZ ? 'CORBLK ? 1000,,%CBNDR+%CBNDW ? 1000,,%JSELF ? + B ? 401000,,%JSNEW +I$MES1: ASCIZ/CORTYP FAILED/ +I$MES2: ASCIZ/PAGE-DELETE FAILED/ +I$MES3: ASCIZ/PAGE-GET FAILED/ +I$MES4: ASCIZ/PURIFY FAILED/ + +.CODE + +IENTRY FIXIFY + + JUMPL A,FIXL + FADR A,[.499999] + UFA A,[233000000000'] + TLZ B,777000' + JRST @0 +FIXL: MOVN A,A + FADR A,[.499999] + UFA A,[233000000000'] + TLZ B,777000' + MOVN B,B + JRST @0 + +; IMPURE AREA + +.IDATA + -1 ; THIS STUFF MUST NOT BE FLUSHED! +MDATA PAGTAB ; PAGE TABLE + BLOCK 256. +MDATA ARGV + BLOCK MAXARG ; POINTERS TO ARGS PLACED HERE +MDATA XJNAME + BLOCK 1 ; JOB NAME +MDATA SEG0LO + 0 +MDATA SEG0HI + 0 +MDATA SEG1LO + 0 +MDATA SEG1HI + 0 +MDATA SEG2LO + 0 +MDATA SEG2HI + 0 +MDATA SEG3LO + 0 +MDATA SEG3HI + 0 + ; END OF WIRED-DOWN STUFF (PROTECTED + ; ON THIS END BY CALLER) +MDATA CALLER + ZMAIN" ; C ROUTINE CALLED AS PROGRAM +MDATA PURBOT + 0 +MDATA PURTOP + 0 + +.UDATA +MDATA EXITER + BLOCK 1 ; EXIT ROUTINE (FOR TIMING) +ARGC: BLOCK 1 ; NUMBER OF ARGUMENTS TO MAIN +JCLBUF: BLOCK BUFSZ/5 ; JCL BUFFER +ARGBUF: BLOCK BUFSZ ; MAIN ARGS BUFFER +PDL: BLOCK PDLSIZ ; THE STACK +.IDATA +MDATA PDLBOT + PDL +MDATA PDLTOP + PDL+PDLSIZ-1 +.PDATA +MDATA PZERO + PUSH P,ZERO +MDATA ZERO + 0 +MDATA PUSHD + PUSH P,D +MDATA TPINIT ; SET BY TINIT + 0 + +CONSTANTS + +MDATA PATCH + +END START + \ No newline at end of file diff --git a/arc/ar2:clib/C10SAV CMID b/arc/ar2:clib/C10SAV CMID new file mode 100644 index 00000000..ca3840d9 --- /dev/null +++ b/arc/ar2:clib/C10SAV CMID @@ -0,0 +1,44 @@ +; +; CSAVE - Routine to prepare for saving a program file +; +; This file is ITS dependent. +; This file contains the size of the shared library file. +; + +TITLE CSAVE +.INSRT NC +.INSRT NM + +.GLOBAL TYICHN,TYOCHN,PDLBOT,PDLTOP + +CENTRY CSAVE + + SETOM TYICHN + SETOM TYOCHN + MOVE A,[-10.,,246.] + .CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A] + ; DELETE SHARED LIBRARY PAGES + CROAK CORBLK FAILED + + ; DELETE STACK PAGES + + MOVE A,PDLBOT + ADDI A,1777 + TRZ A,1777 ; MOVE TO NEXT PAGE BOUNDARY + MOVE B,PDLTOP ; LAST WORD OF STACK + ADDI B,1 + TRZ B,1777 ; MOVE TO PREVIOUS PAGE BOUNDARY + LSH A,-10. + LSH B,-10. ; GET PAGE NUMBERS + SUB B,A ; NUMBER OF PAGES + MOVN B,B ; NEGATIVE NUMBER OF PAGES + HRL A,B ; MAKE COUNTING POINTER + + .CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A] + CROAK CORBLK FAILED + + .VALUE [ASCIZ/:PDUMP /] + RETURN + +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10SFD C b/arc/ar2:clib/C10SFD C new file mode 100644 index 00000000..cea578d4 --- /dev/null +++ b/arc/ar2:clib/C10SFD C @@ -0,0 +1,25 @@ +/********************************************************************** + + SETFDIR - Set File Directory (and defaults) + (obsolete) + +**********************************************************************/ + +char *setfdir (buf, name, dir) + char *buf, *name, *dir; + + {filespec fs1, fs2; + char *p; + + fparse (name, &fs1); + fparse (dir, &fs2); + if (fs2.dir==0) fs2.dir=fs2.fn1; + if (fs2.dev) fs1.dev = fs2.dev; + else if (fs1.dev==0) fs1.dev=csto6("dsk"); + if (fs2.dir) fs1.dir = fs2.dir; + else if (fs1.dir==0) fs1.dir=rsname(); + p = prfile (&fs1, buf); + *p = 0; + return (buf); + } + \ No newline at end of file diff --git a/arc/ar2:clib/C10SRY CMID b/arc/ar2:clib/C10SRY CMID new file mode 100644 index 00000000..f6d8bcbe --- /dev/null +++ b/arc/ar2:clib/C10SRY CMID @@ -0,0 +1,64 @@ +; +; C10SRY - CHANGE .VCALL'S TO PUSHJ'S +; +; This file is ITS dependent. +; This routine assumes a superior DDT. +; + +TITLE SORRY +.INSRT NC +.INSRT NM + +.GLOBAL SEG2LO,SEG2HI,SEG3LO,SEG3HI + +IENTRY SORRY + + .VALUE [ASCIZ/:UNPURE +P/] + +; MOVE A,SEG2LO +; TRZ A,1777 +; MOVE B,SEG2HI +; SUBI B,(A) +; LSH A,-10. +; ADDI B,1777 +; LSH B,-10. +; MOVN B,B +; HRL A,B +; .CALL I$IMPR +; .VALUE + + SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA +S1: ADDI A,1 ; NEXT WORD + CAML A,SEG2HI ; AT END OF CODE AREA? + GO DONE + HLRZ B,(A) ; INSTRUCTION + TRZ B,000777 ; ISOLATE OPCODE + CAIE B,(.VCALL) ; IS IT A .CCALL? + GO S1 ; NO, GO ON + HLRZ B,(A) ; THE INSTRUCTION AGAIN + TRZ B,777740 ; FLUSH OPCODE AND ACCUMULATOR + IORI B,(PUSHJ P,) ; MAKE IT A PUSHJ + HRLM B,(A) ; STORE IT + GO S1 + +DONE: MOVE A,SEG2LO + TRZ A,1777 + MOVE B,SEG3HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PURE + .VALUE + + .VALUE [ASCIZ/:PDUMP /] + .BREAK 16,0 + +.PDATA +I$PURE: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A +;I$IMPR: SETZ ? 'CORBLK ? 1000,,%CBRED+%CBWRT ? 1000,,%JSELF ? 400000,,A +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10STD C b/arc/ar2:clib/C10STD C new file mode 100644 index 00000000..29e55ae1 --- /dev/null +++ b/arc/ar2:clib/C10STD C @@ -0,0 +1,136 @@ +# include "c.defs" +# include "stdio.h" + +/********************************************************************** + + STDIO.C - 'Standard I/O' Simulator for ITS + + Must call STDIO to initialize. + +**********************************************************************/ + +int *stdin, *stdout, *stderr; +extern int cin, cout, cerr; + +stdio () + + {stdin = cin; stdout = cout; stderr = cerr; + on (ctrlg_interrupt, INT_IGNORE); + } + +flopen (name, mode) + char *name, *mode; + + {int f; + f = copen (name, mode[0]); + if (f == OPENLOSS) return (0); + return (f); + } + +int fgetc (f) + + {int c; + c = cgetc (f); + if (c < 0) return (EOF); + if (c == 0 && ceof (f)) return (EOF); + return (c); + } + +int fgeth () + + {return (fgetc (cin));} + +int peekc (f) + + {int c; + c = cgetc (f); + if (c < 0) return (EOF); + if (c == 0 && ceof (f)) return (EOF); + ungetc (c, f); + return (c); + } + +int pkchar () + + {return (peekc (cin));} + +printf (a, b, c, d, e, f, g) + {cprint (cout, a, b, c, d, e, f, g);} + +fprintf (a, b, c, d, e, f, g) + {cprint (a, b, c, d, e, f, g);} + +fclose (f) {cclose (f);} + +fread (f, buf, size, number) char buf[]; + + {int n; + n = size * number; + while (--n >= 0) *buf++ = cgetc (f); + } + +freopen (name, mode, f) char *name, *mode; + + {int i; + cclose (f); + i = copen (name, *mode); + return (i); + } + +/********************************************************************** + + STRING ROUTINES + +**********************************************************************/ + +strcmp (s1, s2) + char *s1, *s2; + + {int c1, c2; + while (TRUE) + {c1 = *s1++; + c2 = *s2++; + if (c1 < c2) return (-1); + if (c1 > c2) return (1); + if (c1 == 0) return (0); + } + } + +strcpy (dest, source) + char *dest, *source; + + {stcpy (source, dest);} + +strcat (dest, source) + char *dest, *source; + + {while (*dest) ++dest; + stcpy (source, dest); + } + +getuid () {return (rsuset (074));} + +getpw (w, buf) char *buf; + {c6tos (w, buf);} + +nowtime (tv) int tv[]; + {cal foo; + now (&foo); + tv[0] = tv[1] = cal2f (&foo); + } + +char *ctime (tv) int tv[]; + {static char buf[100]; + cal foo; + int f; + f2cal (tv[0], &foo); + f = copen (buf, 'w', "s"); + prcal (&foo, f); + cputc ('\n', f); + cclose (f); + return (buf); + } + +unlink (s) {delete (s);} +exit (cc) {cexit (cc);} + \ No newline at end of file diff --git a/arc/ar2:clib/C10SYS CMID b/arc/ar2:clib/C10SYS CMID new file mode 100644 index 00000000..688b217e --- /dev/null +++ b/arc/ar2:clib/C10SYS CMID @@ -0,0 +1,728 @@ +; +; C10SYS - C LIBRARY ROUTINES (INTERFACES TO SYSTEM CALLS) +; +; This file is ITS dependent. +; + +TITLE C10SYS +.INSRT NC +.INSRT NM + +; CONTAINS: + +; SYSOPEN ; OPEN CHANNEL +; CLOSE ; CLOSE CHANNEL +; CHNLOC ; FIND AVAILABLE CHANNEL + +; UIIOT ; PERFORM UNIT INPUT IOT +; UOIOT ; PERFORM UNIT OUTPUT IOT +; SYSREAD ; PERFORM BLOCK INPUT IOT +; SYSWRITE ; PERFORM BLOCK OUTPUT IOT +; SIOT ; STRING IOT + +; SYSFINISH ; FORCE OUTPUT AND WAIT FOR COMPLETION +; SYSFORCE ; FORCE OUTPUT TO DEVICE + +; RESET ; RESET CHANNEL +; STATUS ; GET CHANNEL STATUS +; RFPNTR ; READ FILE ACCESS POINTER +; ACCESS ; PERFORM RANDOM ACCESS ON CHANNEL +; FILLEN ; GET FILE LENGTH +; FILNAM ; GET FILE NAME FROM CHANNEL + +; RAUTH ; READ FILE AUTHOR +; SAUTH ; SET FILE AUTHOR +; RDMPBT ; READ DUMP BIT +; SDMPBT ; SET DUMP BIT +; SREAPB ; SET DO-NOT-REAP BIT +; RFDATE ; READ FILE CREATION DATE +; SFDATE ; SET FILE CREATION DATE +; SRDATE ; SET FILE REFERENCE DATE +; DSKUPD ; UPDATE FILE INFO +; RESRDT ; RESTORE FILE INFO + +; TTYGET ; GET TTY STATUS +; TTYSET ; SET TTY STATUS +; CNSGET ; GET CONSOLE PARAMETERS +; CNSSET ; SET CONSOLE PARAMETERS + +; ITYIC ; READ TTY INTERRUPT CHARACTER +; WHYINT ; WHY WAS I INTERRUPTED? +; SYSLISTEN ; LISTEN FOR TTY INPUT +; RCPOS ; READ CURSOR POSITION +; SCML ; SET # OF COMMAND LINES + +; GETCPU ; RETURN CPU TIME IN 4.069 USEC +; CPUTM ; RETURN CPU TIME IN 1/60 SECONDS +; SLEEP ; GO TO SLEEP +; ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT +; NOW ; GET CURRENT DATE AND TIME + +; CORBLK ; PERFORM PAGE HACKING +; CORTYP ; GET INFORMATION ABOUT PAGE +; PAGEID ; GET NAMED PUBLIC PAGE +; PGWRIT ; CAUSE PAGE TO BE WRITTEN ON DISK + +; RSNAME ; READ SNAME +; SSNAME ; SET SNAME +; RUNAME ; READ USER NAME +; RSUSET ; WHAT = RSUSET (WHERE) +; WSUSET ; WHAT = WSUSET (WHERE, WHAT) +; RUSET ; WHAT = RUSET (WHO, WHERE) +; WUSET ; WHAT = WUSET (WHO, WHERE, WHAT) +; WUSRVAR ; RC = WUSRVAR (JOB, SPEC, VALUE) + +; DELETE ; DELETE A FILE +; SYSDEL ; DELETE FILE +; RENMWO ; RENAME FILE OPEN FOR OUTPUT +; SYSRNM ; EC = SYSRNM (FS1, FS2) +; SYSLNK ; EC = MAKE LINK (FS1, FS2) +; DIRSIZ ; READ DIRECTORY SIZE, QUOTA INFO + +; TRANAD ; RC = TRANAD (JOB, FROM, TO, FLAGS) +; TRANCL ; RC = TRANCL (JOB, FLAGS) +; TRANDL ; RC = TRANDL (JOB, FILESPEC, FLAGS) + +; SYSLOAD ; LOAD A PROGRAM +; PDUMP ; PDUMP A PROGRAM +; UCLOSE ; DESTROY INFERIOR JOB +; SYSDISOWN ; EC = SYSDISOWN (JOBCH) +; REOWN ; EC = REOWN (JOBCH) +; SYSDTACH ; EC = SYSDTACH (JOBCH) +; SYSATACH ; EC = SYSATACH (JOBCH, TTY) + +; ATTY ; GIVE TTY TO INFERIOR +; DTTY ; TAKE TTY FROM INFERIOR + +; WFNZ ; WAIT FOR WORD TO BECOME NON-ZERO +; WFZ ; WAIT FOR WORD TO BECOME ZERO +; VAL7RET ; VALRET AN ASCIZ STRING +; DEMSIG ; SIGNAL A DEMON PROCESS +; SSTATUS ; OBTAIN SYSTEM STATUS + +; MAKTAG ; CREATE A TAG (GLOBAL LABEL) +; GOTAG ; GOTO A TAG, DISMISSING INTERRUPTS + +CENTRY SYSOPEN,[CHAN, FILSPC, MODE] ; OPEN CHANNEL + + HRLZ B,MODE + HRR B,CHAN + HRRZ C,FILSPC + SYSCAL OPEN,[B ? (C) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY CLOSE,[CHAN] ; CLOSE CHANNEL + + SYSCAL CLOSE,[CHAN] + RETURN + +CENTRY CHNLOC ; FIND AVAILABLE CHANNEL + +FIRSTC==1 ; CHANGE TO 0 IF SYSTEM FIXED SO THAT + ; CHANNEL 0 IS NOT ARBITRARILY SMASHED + ; BY .CALL MLINK, ETC. + + MOVEI B,FIRSTC +CL$1: SYSCAL RFNAME,[B ? 2000,,C] + JUMPE C,CL$2 ; CHANNEL NOT OPEN + ADDI B,1 + CAIGE B,20 + GO CL$1 + SETO A, + GO CL$RET +CL$2: MOVE A,B +CL$RET: RETURN + +CENTRY UIIOT,[CHAN] ; PERFORM UNIT INPUT IOT + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.IOT A] + XCT A + RETURN + +CENTRY UOIOT,[CHAN,DATA] ; PERFORM UNIT OUTPUT IOT + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.IOT DATA] + XCT A + MOVE A,DATA + RETURN + +CENTRY SYSREAD,[CHAN,BUFFP,NWORDS] ; PERFORM BLOCK INPUT IOT +XENTRY SYSWRITE,SYSREAD ; PERFORM BLOCK OUTPUT IOT + + MOVN A,NWORDS ; MINUS NUMBER OF WORDS + HRLZ 0,A + HRR 0,BUFFP ; SET UP CPTR + MOVE C,CHAN + ANDI C,17 + LSH C,23. + IOR C,[.IOT 0] + XCT C + HLRE C,0 ; NEW COUNTER + SUB C,A ; NUMBER OF WORDS WRITTEN/READ + MOVE A,C + RETURN + +CENTRY SIOT,[CHAN,BYTP,NBYTES] ; STRING IOT + + SYSCAL SIOT,[CHAN ? BYTP ? NBYTES],SI$LOS + MOVE A,NBYTES +SI$RET: RETURN +SI$LOS: CROAK SIOT LOST + GO SI$RET + +CENTRY SYSFINISH,[CHAN] + + SYSCAL FINISH,[CHAN] + RETURN + +CENTRY SYSFORCE,[CHAN] + + SYSCAL FORCE,[CHAN] + RETURN + +CENTRY RESET,[CHAN] ; RESET CHANNEL + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.RESET] + XCT A + SETZ A, + RETURN + +CENTRY STATUS,[CHAN] ; GET CHANNEL STATUS + + MOVE A,CHAN + LSH A,23. + IOR A,[.STATUS A] + XCT A + RETURN + +CENTRY RFPNTR,[CHAN] ; READ FILE ACCESS POINTER + + SYSCAL RFPNTR,[CHAN ? MOVEM B],RP$LOS + MOVE A,B +RP$RET: RETURN +RP$LOS: MOVN A,A + GO RP$RET + +CENTRY ACCESS,[CHAN,POS] ; PERFORM RANDOM ACCESS ON CHANNEL + + SYSCAL ACCESS,[CHAN ? POS] + RETURN + +CENTRY FILLEN,[CHAN] ; GET FILE LENGTH + + SYSCAL FILLEN,[CHAN ? 2000,,B],FL$LOS + MOVE A,B +FL$RET: RETURN +FL$LOS: MOVN A,A + GO FL$RET + +CENTRY FILNAM,[CHAN,FILSPC] ; GET FILE NAME FROM CHANNEL + + HRLZ B,CHAN ; CHANNEL + HRR B,FILSPC ; FILESPEC FOR RESULTS + MOVE C,4(B) ; SAVE 5TH WORD + .RCHST B, ; READ CHANNEL STATUS + HRLZS (B) ; LEFT ADJUST DEV + MOVEM C,4(B) ; RESTORE 5TH WORD + RETURN ; DONE + +CENTRY RAUTH,[CHAN] + + SYSCAL RAUTH,[CHAN ? MOVEM B],RA$LOS + MOVE A,B +RA$RET: RETURN +RA$LOS: MOVN A,A + GO RA$RET + +CENTRY SAUTH,[CHAN,AUTHOR] + + SYSCAL SAUTH,[CHAN ? AUTHOR] + RETURN + +CENTRY RDMPBT,[CHAN] + + SYSCAL RDMPBT,[CHAN ? MOVEM B],RD$LOS + MOVE A,B +RD$RET: RETURN +RD$LOS: MOVN A,A + GO RD$RET + +CENTRY SDMPBT,[CHAN,BIT] + + SYSCAL SDMPBT,[CHAN ? BIT] + RETURN + +CENTRY SREAPB,[CHAN,BIT] + + SYSCAL SREAPB,[CHAN ? BIT] + RETURN + +CENTRY RFDATE,[CHAN] ; READ FILE CREATION DATE + + SYSCAL RFDATE,[CHAN ? 2000,,B],RF$LOS + MOVE A,B +RF$RET: RETURN +RF$LOS: MOVN A,A + GO RF$RET + +CENTRY SFDATE,[CHAN,FDATE] ; SET FILE CREATION DATE + + SYSCAL SFDATE,[CHAN ? FDATE] + RETURN + +CENTRY SRDATE,[CHAN,FDATE] ; SET FILE REFERENCE DATE + + SYSCAL SRDATE,[CHAN ? FDATE] + RETURN + +CENTRY DSKUPD,[CHAN] + + SYSCAL DSKUPD,[CHAN] + RETURN + +CENTRY RESRDT,[CHAN] + + SYSCAL RESRDT,[CHAN] + RETURN + +CENTRY TTYGET,[CHAN,BLOCK] ; GET TTY STATUS - WRITES 3 VALUES + + HRRZ B,BLOCK + SYSCAL TTYGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B)] + RETURN + +CENTRY TTYSET,[CHAN,BLOCK] ; SET TTY STATUS - READS 3 VALUES + + HRRZ B,BLOCK + SYSCAL TTYSET,[CHAN ? (B) ? 1(B) ? 2(B)] + RETURN + +CENTRY CNSGET,[CHAN,BLOCK] ; GET CONSOLE STATUS - WRITES 5 VALUES + + HRRZ B,BLOCK + SYSCAL CNSGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B) + MOVEM 3(B) ? MOVEM 4(B)] + RETURN + +CENTRY CNSSET,[CHAN,BLOCK] ; SET CONSOLE STATUS - READS 5 VALUES + + HRRZ B,BLOCK + SYSCAL CNSSET,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)] + RETURN + +CENTRY WHYINT,[CHAN,BLOCK] + + HRRZ B,BLOCK + SYSCAL WHYINT,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)] + RETURN + +CENTRY ITYIC,[CHAN] ; READ TTY INTERRUPT CHARACTER + + MOVE A,CHAN ; CHANNEL + .ITYIC A, + SETO A, + RETURN + +CENTRY SYSLISTEN,[CHAN] ; NCHARS = SYSLISTEN(CHAN) + + SYSCAL LISTEN,[CHAN ? MOVEM B],LI$LOS + MOVE A,B +LI$RET: RETURN +LI$LOS: MOVN A,A + GO LI$RET + +CENTRY RCPOS,[CHAN] ; READ TTY CURSOR POSITION (V,,H) + + SYSCAL RCPOS,[CHAN ? 2000,,B],RC$LOS + MOVE A,B +RC$RET: RETURN +RC$LOS: MOVN A,A + GO RC$RET + +CENTRY SCML,[CHAN,NUMBER] + + SYSCAL SCML,[CHAN ? NUMBER] + RETURN + +CENTRY GETCPU ; RETURN CPU TIME IN 4.069 USEC + + .SUSET [24,,A] + RETURN + +CENTRY CPUTM ; RETURN CPU TIME IN 1/60 SECONDS + + .SUSET [24,,A] + LSH A,-12. + RETURN + +CENTRY SLEEP,[TIME] ; GO TO SLEEP + + MOVE A,TIME + .SLEEP A, + RETURN + +CENTRY ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT + + .RDTIME A, + LSH A,1 + RETURN + +CENTRY NOW,[PCAL] ; GET CURRENT DATE AND TIME + + HRRZ D,PCAL ; CAL POINTER + .RDATE C, + LDB A,[360600,,C] ; HIGH-ORDER YEAR SIXBIT + SUBI A,20 + IMULI A,10. + LDB B,[300600,,C] ; LOW-ORDER YEAR SIXBIT + SUBI B,20 + ADDI A,1900.(B) ; YEAR + MOVEM A,(D) + + LDB A,[220600,,C] ; HIGH-ORDER MONTH + SUBI A,20 + IMULI A,10. + LDB B,[140600,,C] ; LOW-ORDER MONTH + SUBI B,20 + ADDI A,(B) + MOVEM A,1(D) ; MONTH + + LDB A,[060600,,C] ; HIGH-ORDER DAY + SUBI A,20 + IMULI A,10. + LDB B,[000600,,C] ; LOW-ORDER DAY + SUBI B,20 + ADDI A,(B) + MOVEM A,2(D) ; DAY + + .RTIME C, + LDB A,[360600,,C] ; HIGH-ORDER HOUR + SUBI A,20 + IMULI A,10. + LDB B,[300600,,C] ; LOW-ORDER HOUR + SUBI B,20 + ADDI A,(B) + MOVEM A,3(D) ; HOUR + + LDB A,[220600,,C] ; HIGH-ORDER MINUTE + SUBI A,20 + IMULI A,10. + LDB B,[140600,,C] ; LOW-ORDER MINUTE + SUBI B,20 + ADDI A,(B) + MOVEM A,4(D) ; MINUTE + + LDB A,[060600,,C] ; HIGH-ORDER SECOND + SUBI A,20 + IMULI A,10. + LDB B,[000600,,C] ; LOW-ORDER SECOND + SUBI B,20 + ADDI A,(B) + MOVEM A,5(D) ; SECOND + + MOVEI A,(D) + RETURN + +CENTRY CORBLK,[A1,A2,A3,A4,A5] ; PERFORM PAGE HACKING + + SYSCAL CORBLK,[A1 ? A2 ? A3 ? A4 ? A5] + RETURN + +CENTRY CORTYP,[PAGNO,OUTPUT] ; GET INFORMATION ABOUT PAGE + + MOVE B,OUTPUT + SYSCAL CORTYP,[PAGNO ? 2000,,(B) ? 2000,,1(B) ? 2000,,2(B) + 2000,,3(B)] + RETURN + +CENTRY PAGEID,[VPN,IDN] ; GET NAMED PUBLIC PAGE + + SYSCAL PAGEID,[VPN ? IDN ? 2000,,B],PI$LOS + MOVE A,B +PI$RET: RETURN +PI$LOS: MOVN A,A + GO PI$RET + +CENTRY PGWRIT,[JOB,VPN] + + SYSCAL PGWRIT,[JOB ? VPN] + RETURN + +CENTRY RSNAME ; READ SNAME + + .SUSET [.RSNAM,,A] + RETURN + +CENTRY SSNAME,[NAME] ; SET SNAME + + MOVE A,NAME + .SUSET [.SSNAM,,A] + RETURN + +CENTRY RUNAME ; READ USER NAME + + .SUSET [.RUNAM,,A] + RETURN + +CENTRY RSUSET,[WHERE] + + HRLZ A,WHERE + TLZ A,600000 ; CLEAR DIRECTION AND BLOCK BITS + ADDI A,A ; RESULT TO A + .SUSET A ; DO IT + RETURN + +CENTRY WSUSET,[WHERE,WHAT] + + HRLZ B,WHERE + TLO B,400000 ; SET DIRECTION BIT + TLZ B,200000 ; CLEAR BLOCK BIT + ADDI B,A ; TAKE WORD FROM A + MOVE A,WHAT + .SUSET B ; DO IT + RETURN + +CENTRY RUSET,[WHO,WHERE] + + HRLZ B,WHERE + TLZ B,600000 ; CLEAR DIRECTION AND BLOCK BITS + ADDI B,A ; RESULT TO A + HRRZ A,WHO + ANDI A,17 ; CHANNEL NUMBER + LSH A,23. + IOR A,[.USET B] + XCT A ; DO IT + RETURN + +CENTRY WUSET,[WHO,WHERE,WHAT] + + HRLZ B,WHERE + TLO B,400000 ; SET DIRECTION BIT + TLZ B,200000 ; CLEAR DIRECTION BIT + ADDI B,A ; TAKE WORD FROM A + HRRZ C,WHO + ANDI C,17 ; CHANNEL NUMBER + LSH C,23. + IOR C,[.USET B] + MOVE A,WHAT + XCT C ; DO IT + RETURN + +CENTRY WUSRVAR,[JOB,SPEC,VALUE] + + SETZ A, + SYSCAL USRVAR,[JOB ? SPEC ? VALUE] + RETURN + +CENTRY DELETE,[FILNAM],[FDEV,FDIR,FFN1,FFN2] ; DELETE A FILE + + MOVEI A,FDEV ; POINTER TO FILESPEC + CALL FPARSE,[FILNAM,A] ; CONSTRUCT FILESPEC + MOVEI A,FDEV + CALL SYSDELETE,[A] ; DELETE THAT FILE + RETURN + +CENTRY SYSDELETE,[FILSPC] ; DELETE FILE + + MOVE B,FILSPC ; ADDRESS OF FILESPEC BLOCK + HRLZI C,(SIXBIT/DSK/) + SKIPN (B) + MOVEM C,(B) + .SUSET [.RSNAM,,C] + SKIPN 3(B) + MOVEM C,3(B) + SYSCAL DELETE,[(B) ? 1(B) ? 2(B) ? 3(B)] + RETURN + +CENTRY RENMWO,[CHAN,FILSPC] ; RENAME FILE OPEN FOR OUTPUT + + HRRZ B,FILSPC + SYSCAL RENMWO,[CHAN ? 1(B) ? 2(B)] + RETURN + +CENTRY SYSRNM,[FILSP1,FILSP2] + + HRRZ B,FILSP1 + HRRZ C,FILSP2 + SYSCAL RENAME,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY SYSLNK,[FILSP1,FILSP2] + + HRRZ B,FILSP1 + HRRZ C,FILSP2 + SYSCAL MLINK,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY DIRSIZ,[CHAN,BLOCK] ; WRITES 2 VALUES + + HRRZ B,BLOCK + SYSCAL DIRSIZ,[CHAN ? (B) ? 1(B)] + RETURN + +CENTRY TRANAD,[JOB,FROM,TO,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + HRRZ C,FROM ; FROM FILESPEC + HRLI C,-4 ; MAKE IT A CPTR + HRRZ D,TO ; TO FILESPEC + HRLI D,-4 ; MAKE IT A CPTR + SYSCAL TRANAD,[B ? C ? D] + RETURN + +CENTRY TRANCL,[JOB,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + SKIPN FLAGS + HRLI B,300003 ; DEFAULT FLAGS + SYSCAL TRANCL,[B] + RETURN + +CENTRY TRANDL,[JOB,FILSPC,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + HRRZ C,FILSPC + HRLI C,-4 ; MAKE IT A CPTR + SYSCAL TRANDL,[B ? C] + RETURN + +CENTRY SYSLOAD,[JOB,CHAN],[RCODE,OLDIOC] ; LOAD A PROGRAM + + SETZM RCODE + CALL ON,[[[2]],[[1]]] + MOVEM A,OLDIOC + + SYSCAL LOAD,[JOB ? CHAN],LD$LOS +LD$1: CALL ON,[[[2]],OLDIOC] + MOVE A,RCODE + RETURN +LD$LOS: SETOM RCODE + GO LD$1 + +CENTRY PDUMP,[JOBCH,DSKCH] + + SETZ B, + SYSCAL PDUMP,[JOBCH ? DSKCH ? B] + RETURN + +CENTRY UCLOSE,[JCHAN] ; DESTROY INFERIOR JOB + + MOVE A,JCHAN + ANDI A,17 + LSH A,23. + IOR A,[.UCLOSE] + XCT A + RETURN + +CENTRY SYSDISOWN,[JCHAN] + + SYSCAL DISOWN,[JCHAN] + RETURN + +CENTRY REOWN,[JCHAN] + + SYSCAL REOWN,[JCHAN] + RETURN + +CENTRY SYSDTACH,[JCHAN] + + SYSCAL DETACH,[JCHAN] + RETURN + +CENTRY SYSATACH,[JCHAN,TTY] ; TTY<0 => DEFAULT + + SKIPGE TTY + GO AT$1 + SYSCAL ATTACH,[JCHAN ? TTY] +AT$RET: RETURN +AT$1: SYSCAL ATTACH,[JCHAN] + GO AT$RET + +CENTRY ATTY,[JOB] ; GIVE TTY TO INFERIOR + + MOVE B,JOB + ANDI B,17 + LSH B,23. + IOR B,[.ATTY] + SETZ A, + XCT B + SETO A, + RETURN + +CENTRY DTTY,[JOB] ; TAKE TTY FROM INFERIOR + + MOVE B,JOB + ANDI B,17 + LSH B,23. + IOR B,[.DTTY] + SETZ A, + XCT B + SETO A, + RETURN + +CENTRY WFNZ,[PTR] ; WAIT FOR WORD TO BECOME NON-ZERO + + MOVE A,PTR + SKIPN (A) + .HANG + MOVE A,(A) + RETURN + +CENTRY WFZ,[PTR] ; WAIT FOR WORD TO BECOME ZERO + + MOVE A,PTR + SKIPE (A) + .HANG + MOVE A,(A) + RETURN + +CENTRY VAL7RET,[STR] ; VALRET AN ASCIZ STRING + + HRRZ A,STR + HRLI A,(.VALUE) + XCT A + RETURN + +CENTRY DEMSIG,[DEMON] ; SIGNAL A DEMON PROCESS + + SYSCAL DEMSIG,[DEMON] + RETURN + +CENTRY SSTATUS,[VALBLK] ; RETURNS 7 VALUES + + HRRZ B,VALBLK + SYSCAL SSTATUS,[MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B) + MOVEM 3(B) ? MOVEM 4(B) ? MOVEM 5(B) ? MOVEM 6(B)] + RETURN + +CENTRY MAKTAG,[TAGP] + + HRRZ A,TAGP ; TAG POINTER + MOVE B,(P) ; RETURN PC + MOVEM B,(A) ; SAVE RETURN PC + MOVEI B,-2(P) ; STACK POINTER BEFORE CALL + MOVEM B,1(A) ; SAVE STACK POINTER + RETURN + +CENTRY GOTAG,[TAGP] + + MCALL DISMISS + MOVE A,TAGP + MOVE P,1(A) + HRRZ D,(A) + GO (D) + +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10TAP CMID b/arc/ar2:clib/C10TAP CMID new file mode 100644 index 00000000..88b423bf --- /dev/null +++ b/arc/ar2:clib/C10TAP CMID @@ -0,0 +1,197 @@ +; +; C10TAP - MAG TAPE INTERFACE +; +; This file is ITS dependent. +; + +TITLE C10TAPE +.INSRT NC +.INSRT NM + +TAPIN==17 ; TAPE CHANNEL +TPIBSZ==200 ; SIZE OF TAPE INPUT BUFFER +TPBFSZ==2000 ; SIZE OF TAPE OUTPUT BUFFER + +CENTRY RWND8 ; REWIND TAPE, LEAVE OPEN FOR READ + + .CLOSE TAPIN, + .OPEN TAPIN,[033726,,(SIXBIT/MT0/)] + CROAK UNABLE TO OPEN TAPE FOR READING + MOVE 0,[TAPIN,,[1]] + .MTAPE 0, + JFCL + SETZM CURBLOCK + RETURN + +CENTRY OPEN8 ; OPEN TAPE FOR 8-BIT READ + + MOVE A,TAPECH + CAILE A,0 + GO OP$RTN + CALL RWND8 + SETZM TPICNT + SETZM TPIEOF + SETOM CURBLOCK + MOVEI 0,1 + MOVEM 0,TAPECH +OP$RTN: RETURN + +CENTRY OPNW8 ; OPEN TAPE FOR 8-BIT WRITE + + CALL RWND8 + .OPEN TAPIN,[033707,,(SIXBIT/MT0/)] + CROAK UNABLE TO OPEN TAPE FOR WRITING + MOVEI A,2*TPBFSZ + MOVEM A,TPICNT + MOVE A,[442000,,TPIBUF] + MOVEM A,TPIBFP + SETOM TAPECH + RETURN + +CENTRY GET16 ; READ 16-BITS + + SOSGE TPICNT + CL TPREAD + ILDB A,TPIBFP + ILDB B,TPIBFP + LSH B,10 + IOR A,B + MOVE B,A + ADD B,CHECKSUM + ANDI B,0177777 + MOVEM B,CHECKSUM + RETURN + +CENTRY PUT16,[W] ; WRITE 16 BITS + + MOVE C,W + SOSGE TPICNT ; ANY ROOM ? + CL WRTAPE ; NO, FLUSH BUFFER + MOVE B,C + ADD B,CHECKSUM + ANDI B,0177777 + MOVEM B,CHECKSUM + MOVE B,C + LSH B,-10 + ANDI B,0377 + LSH C,10 + ANDI C,177400 + IOR B,C + MOVE C,B + IDPB C,TPIBFP + RETURN + +CENTRY SEEK8,[ACC] ; RANDOM ACCESS + + SETZM CHARINBUF ; CLEAR GET8 BUFFER + MOVE A,ACC + MOVE B,A + SUB A,CURBLOCK + CAIE A,0 + GO L1 + +; HERE IF DESIRED BLOCK IS IN BUFFER + + MOVEI A,2*TPIBSZ + MOVEM A,TPICNT + MOVE A,[441000,,TPIBUF] + MOVEM A,TPIBFP +SE$RET: RETURN + +L1: SUBI A,1 ; NUMBER OF BLOCKS TO SKIP + SETZM TPICNT + CAIN A,0 + GO SE$RET ; WANT NEXT BLOCK, NOTHING TO SKIP + +; HERE IF NECESSARY TO SKIP SOME BLOCKS + + HRLZ C,A + HRLZI A,TAPIN + HRRI A,C + HRRI C,6 + .MTAPE A, + JFCL + SUBI B,1 + MOVEM B,CURBLOCK + RETURN + +CENTRY CLOS8 ; CLOSE TAPE + + SKIPGE TAPECH + CL FLUSH8 ; FLUSH BUFFER + CALL RWND8 + .CLOSE TAPIN, + SETZM TAPECH + RETURN + +CENTRY EOF8 ; TEST FOR END-OF-FILE + + MOVE A,TPIEOF + RETURN + +; *** BUFFERED I/O ROUTINES *** + +; TPICNT - NUMBER OF 16-BIT INTEGERS IN BUFFER +; TPIBFP - ABPTR TO NEXT 16-BIT INTEGER IN BUFFER +; TPIBUF - THE BUFFER +; TPIEOF - -1 IF END-OF-FILE + +TPR1: SOSL TPICNT + RTN +TPREAD: MOVEI A,2*TPIBSZ + MOVEM A,TPICNT + MOVE A,[441000,,TPIBUF] + MOVEM A,TPIBFP + MOVEI A,TPIBUF + HRLI A,-TPIBSZ + AOS CURBLOCK + .IOT TAPIN,A + JUMPGE A,TPR1 + HLRES A + ADDI A,TPIBSZ + JUMPE A,TPR2 ; END OF FILE + LSH A,1 + MOVEM A,TPICNT + GO TPR1 +TPR2: SETOM TPIEOF + SETZM TPIBUF + RTN + +FLUSH8: MOVEI A,2*TPBFSZ ; FLUSH (MAYBE UNFILLED) BUFFER + SUB A,TPICNT + ADDI A,1 + LSH A,-1 + MOVN A,A + HRLZ A,A + SKIPA + +WRTAPE: HRLZI A,-TPBFSZ ; THIS IS SKIPPED FROM FLUSH8 + HRRI A,TPIBUF + .IOT TAPIN,A ; WRITE BUFFER + MOVEI A,2*TPBFSZ-1 + MOVEM A,TPICNT + MOVE A,[442000,,TPIBUF] + MOVEM A,TPIBFP + RTN + +; *** BUFFERED I/O VARIABLES *** + +.UDATA +TAPECH: BLOCK 1 ; 0 - CLOSED + ; 1 - OPEN FOR READ + ; -1 - OPEN FOR WRITE + +TPICNT: BLOCK 1 ; TAPE I/O VARIABLES +TPIBFP: BLOCK 1 +TPIEOF: BLOCK 1 +TPIBUF: BLOCK TPBFSZ + +MDATA CURBLOCK + BLOCK 1 +MDATA CHECKSUM + BLOCK 1 +MDATA CHARINBUF + BLOCK 1 + +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10TMM CMID b/arc/ar2:clib/C10TMM CMID new file mode 100644 index 00000000..5e886a32 --- /dev/null +++ b/arc/ar2:clib/C10TMM CMID @@ -0,0 +1,111 @@ +; +; C10TMM - Program to determine the timing constants for +; the C timing package (C10TMR). The computed +; times are left in TIME1, TIME2, TIME3. Times +; are in nanoseconds. +; +; This file is ITS dependent. +; This is a stand-alone program. +; + +A==1 +B==2 +C==3 +D==4 +P==17 +CL==PUSHJ P, +RTN==POPJ P, +GO==JRST +.CCALL==1_27. + +TP"=16 ; TIME STACK POINTER +%TPROC==0 ; THE PROCEDURE POINTER +%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE) +%TNCAL==2 ; THE NUMBER OF CALLS +%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME +%TSIZE==4 ; SIZE OF TIME TABLE ENTRY +%FTABL==0 ; POINTER TO TIME TABLE ENTRY +%FTIME==1 ; ACCUMULATED OR START TIME +%FRTNA==2 ; ACTUAL RETURN ADDRESS +%FSIZE==3 ; SIZE OF STACK FRAME + +TIME1: 0 +TIME2: 0 +TIME3: 0 +TIME4: 0 + +START: MOVE P,[-2000,,PDL] + MOVE A,[JSR UUOH] + MOVEM A,41 + .SUSET [24,,TIME1] + CL TSUSET + .SUSET [24,,TIME2] + CL TUUO + .SUSET [24,,TIME3] + CL TEPILOG + .SUSET [24,,TIME4] + MOVE A,TIME2 + SUB A,TIME1 + IMULI A,4069. + IDIVI A,1000. + MOVEM A,TIME1 + MOVE A,TIME3 + SUB A,TIME2 + IMULI A,4069. + IDIVI A,1000. + MOVEM A,TIME2 + MOVE A,TIME4 + SUB A,TIME3 + IMULI A,4069. + IDIVI A,500. + MOVEM A,TIME3 + SETZM TIME4 + .VALUE + +TSUSET: REPEAT 1000.,[.SUSET [24,,C] +] + RTN + +TUUO: REPEAT 1000.,[ + .CCALL 2,0 + ] + RTN + +UUOH: 0 + GO UUO$HANDLER + +UUO$HANDLER: + + MOVEM D,USAVED + LDB D,[330500,,ZERO] + GO @UUOH(D) + +USAVED: 0 +ZERO: 0 +BAR: -1 +BAR2: 0 + 0 + 0 +BAR3: 0 + 0 + 0 + 0 + +TEPILOG: + MOVEI TP,BAR2 + MOVEI B,BAR3 + MOVEI A,0 + REPEAT 500.,[ + MOVE 0,C + SUBI C,37 + SUB C,%FTIME(TP) + MOVE C,%FTABL(TP) + ADDM C,%TTIME(B) + SUBI TP,%FSIZE + ADDI 0,37 + SUBM 0,%FTIME(TP) + GO @[.+1](A) ; TO NEXT LOCATION + ] + RTN +PDL: BLOCK 2000 +END START diff --git a/arc/ar2:clib/C10TMR CMID b/arc/ar2:clib/C10TMR CMID new file mode 100644 index 00000000..23dd9981 --- /dev/null +++ b/arc/ar2:clib/C10TMR CMID @@ -0,0 +1,150 @@ +; +; TIMER - Version of runtime to time procedure calls +; +; This file is ITS dependent. +; (Dependency is system-call to get runtime.) +; + +TITLE TIMER +.INSRT NC +.INSRT NM + +TIMSIZ==1000. +IF1,[ +KLFLAG==0 +PRINTX \KL10 (YES/NO)? \ +.TTYMAC TIMEQ +IFSE TIMEQ,YES,KLFLAG==1 +TERMIN +] + +TP"=16 ; TIME STACK POINTER + +; TIME TABLE ENTRY WORDS + +%TPROC==0 ; THE PROCEDURE POINTER +%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE) +%TNCAL==2 ; THE NUMBER OF CALLS +%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME +%TSIZE==4 ; SIZE OF TIME TABLE ENTRY + +; TIME STACK FRAME WORDS + +%FTABL==0 ; POINTER TO TIME TABLE ENTRY +%FTIME==1 ; ACCUMULATED OR START TIME +%FRTNA==2 ; ACTUAL RETURN ADDRESS +%FSIZE==3 ; SIZE OF STACK FRAME + +; TIMING CONSTANTS (IN NANOSECONDS) +; COMPUTED BY PROGRAM 'TTIMM' + +IFE KLFLAG,[ +SUSTIM==387909. ;TIME FOR .SUSET +UUOTIM==27929. ;TIME FOR UUO DISPATCH +EPITIM==30891. ;TIME FOR EPILOG +] + +IFN KLFLAG,[ +SUSTIM==71630. +UUOTIM==3373. +EPITIM==4663. +] + +; +; .CCALL HANDLER (TIMING VERSION) +; + +IENTRY UTCALL + + .SUSET [24,,C] ; JOB ACCUMULATED TIME TO C + SKIPN TIMING" ; IS TIMING ON ? + GO UT$1 ; NO, RESUME NORMAL OPERATION + SUBI C,/4069. + ; FUDGE FOR SUSET AND TIME IT TOOK + ; TO GET HERE + SUBM C,%FTIME(TP) ; DETERMINE CALLER'S ACCUMULATED TIME + ADDI TP,%FSIZE ; ALLOCATE NEW TIME FRAME + + HRRZ B,40 ; CALLED ROUTINE + HRRZ D,-1(B) ; TIMTAB POINTER OR PROC NAME + CAIGE D,TIMTAB ; IS IT A TIMTAB POINTER? + GO UT$3 ; NO + CAMGE D,TIMEP ; IS IT A TIMTAB POINTER? + GO UT$2 ; YES + +UT$3: MOVE A,D ; PROC NAME + MOVE D,TIMEP ; FIRST TIMED CALL OF ROUTINE + CAML D,ETIMEP ; IS TIME TABLE FULL? + GO UT$1 ; YES, IGNORE THIS CALL + MOVEM B,%TPROC(D) ; NO - INITIALIZE NEW TIMTAB ENTRY + MOVEM A,%TNAME(D) + SETZM %TTIME(D) + SETZM %TNCAL(D) + HRRM D,-1(B) ; PUT PTR TO TIMTAB ENTRY IN NAME WORD + MOVEI C,%TSIZE + ADDM C,TIMEP ; ADVANCE POINTER TO NEXT FREE ENTRY + +UT$2: ; HERE WITH PTR TO TIMTAB ENTRY IN D + MOVEM D,%FTABL(TP) ; STORE POINTER IN TIME STACK + AOS %TNCAL(D) ; INCREMENT USE COUNT + +UT$1: ; CONTINUE WITH CALL PROCESSING + HRRZ C,40 ; THE CALLED PROCEDURE + JUMPE C,UCBAD" ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO UCBAD ; NO, NOT A PROCEDURE + LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS + SUB 0,B ; NUMBER OF ARGS NOT GIVEN + JUMPL 0,CODE [ ; TOO MANY ARGS GIVEN + ADD P,0 ; POP OFF EXTRA ARGS + GO UTDOIT ; MAKE THE CALL + ] +UTLOOP: SOJL 0,UTDOIT ; FOR EACH ARG NEEDED + PUSH P,[0] ; PUSH ZERO ARG + GO UTLOOP ; LOOP +UTDOIT: SKIPN TIMING + GO UT$4 + MOVE B,UUOH ; RETURN ADDRESS + MOVEM B,%FRTNA(TP) ; SAVE IT + MOVEI B,%FTIME(TP) ; CONSTRUCT .SUSET + HRLI B,24 ; GET START TIME FOR CALLED PROC + .SUSET B ; AND STORE IN TIME STACK FRAME + PUSHJ P,(C) ; CALL PROCEDURE + .SUSET [24,,C] ; JOB ACCUMULATED TIME + MOVE 0,C + SUBI C,SUSTIM/4069. ; FUDGE FOR .SUSET TIME + SUB C,%FTIME(TP) ; SUBTRACT START TIME + MOVE B,%FTABL(TP) ; TIMTAB ENTRY POINTER + ADDM C,%TTIME(B) ; ADD TO ACCUMULATED TIME FOR CALLEE + SUBI TP,%FSIZE ; POP TIME STACK FRAME + ADDI 0,/4069. ; FUDGE + SUBM 0,%FTIME(TP) ; ADJUST START TIME OF CALLER + GO @%FRTNA+%FSIZE(TP) ; RETURN TO CALLER + +UT$4: PUSH P,UUOH" + GO (C) + +IENTRY TINIT + + SETOM TIMING" + MOVEI A,UTCALL + MOVEM A,UUOTAB"+1 + MOVEI TP,TIMSTK + MOVEM TP,TPINIT" + MOVEI A,TPRT" + MOVEM A,EXITER" + GO LINIT" + +.IDATA +MDATA TIMEP + TIMTAB +MDATA ETIMEP + TIMTAB+ +.UDATA +MDATA TIMTAB + BLOCK TIMSIZ*%TSIZE +MDATA TIMSTK + BLOCK TIMSIZ +END + \ No newline at end of file diff --git a/arc/ar2:clib/C10TPR C b/arc/ar2:clib/C10TPR C new file mode 100644 index 00000000..8f6fe1aa --- /dev/null +++ b/arc/ar2:clib/C10TPR C @@ -0,0 +1,152 @@ +# include "clib/c.defs" +# include "clib/its.bits" + +/********************************************************************** + + C10TPR - Printing Routine for C Timer Package + *ITS* + +**********************************************************************/ + +# rename null "$NULL$" +# rename timing "TIMING" +# rename timtab "TIMTAB" +# rename timep "TIMEP" +# rename tprt "TPRT" + +struct _tentry {int *proc, pname, count, time;}; +# define tentry struct _tentry + +extern int timing; +extern tentry timtab[], *timep; +extern int cout; + +/* All times are kept in machine-dependent Units + and converted upon output to the appropriate + units. +*/ + +tprt () + + {int fout, /* output file */ + total_time, /* total CPU time used */ + smallest, /* smallest average time */ + time, /* time used by current routine */ + average, /* average time of current routine */ + percent, /* percentage CPU time, current routine */ + cpercent, /* cumulative percentage CPU time */ + ctime, /* cumulative CPU time */ + count, /* number of calls, current routine */ + ncalls, /* total number of calls */ + namep, /* pointer to current routine name */ + nulltime, /* time to call null routine */ + t, + c; + + tentry *ip, *ip1; + + t = rsuset (URUNT); + c = 50; + timing = -1; + while (--c >= 0) + {null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + } + timing = 0; + + fout = copen ("timer.output", 'a'); + if (fout<0) fout = copen ("timout", 'w'); + if (fout<0) fout = cout; + + cprint (fout, "\n\n\n *** TIMING INFORMATION ***\n\n"); + cprint (fout, "TIME(usec) PERCENT CUM. %% NO. CALLS AVG. TIME ROUTINE NAME\n\n"); + + /* null entry should be last */ + + --timep; + nulltime = timep->time / timep->count; + + /* sort entries in order of decreasing CPU time used */ + + for (ip=timtab;iptime > ip->time) + bswap (ip, ip1, 4); + + total_time = 0; + for (ip=timtab;iptime; + + ncalls = 0; + smallest = 10000; /* big number */ + ctime = 0; + for (ip=timtab;iptime; + ctime =+ time; + percent = (time * 1000) / total_time; + cpercent = (ctime * 1000) / total_time; + count = ip->count; + ncalls =+ count; + namep = (ip->pname) | 0440700000000; + average = time/count; + if (average0) smallest=average; + cprint (fout, "%10d%8d.%1d%8d.%1d", + u2mic (time), percent/10, percent%10, + cpercent/10, cpercent%10); + cprint (fout, "%11d%12d ", count, u2mic (average)); + while (c = ildb (&namep)) cputc (c, fout); + cputc ('\n', fout); + } + + if (smallest= 0) + {t = *p; + *p++ = *q; + *q++ = t; + } + } + +null () {;} + \ No newline at end of file diff --git a/arc/ar2:clib/C10TTY C b/arc/ar2:clib/C10TTY C new file mode 100644 index 00000000..f5f45ab9 --- /dev/null +++ b/arc/ar2:clib/C10TTY C @@ -0,0 +1,376 @@ +/* + * C TTY Package + * + * routines: + * + * tyiopn - open TTY input channel + * tyi - read char from TTY (buffered) + * utyi - read char from TTY (unbuffered) + * get_buf - read string from TTY + * setprompt - set default TYI prompt string + * tyoopn - open TTY output channel + * tyo - output char to TTY (buffered) + * utyo - output char to TTY (unbuffered) + * spctty - output display code (unbuffered) + * tyos - output string to TTY (buffered) + * tyo_flush - flush TTY output buffer + * + * global variables: + * + * ttynp - ^L handler + * + * internal routines: + * + * ttyih - TTY interrupt handler + * ctrlch - return display width of char + * + */ + +# include "c.defs" + +# define tty_input_buffer_size 120 +# define tty_output_buffer_size 60 + +# rename tty_input_channel "TYICHN" +# rename tty_output_channel "TYOCHN" +# rename tty_device_code "TTYDEV" +# rename tty_input_buffer "TYIBUF" +# rename tty_input_ptr "TYIPTR" +# rename tty_input_count "TYICNT" +# rename tty_output_buffer "TYOBUF" +# rename tty_output_ptr "TYOPTR" +# rename tty_output_count "TYOCNT" +# rename tty_output_bptr "TYOBPT" +# rename tty_default_prompt "TTYDPR" + +int tty_input_channel -1; +int tty_output_channel -1; +int tty_device_code -1; +char tty_input_buffer[tty_input_buffer_size]; +char *tty_input_ptr; +int tty_input_count; +char tty_output_buffer[tty_output_buffer_size]; +char *tty_output_ptr {tty_output_buffer}; +int tty_output_count; +int tty_output_bptr; +char *tty_default_prompt; + +int ttxnp(); /* default TTY ^L handler */ +int (*ttynp)() {ttxnp}; /* called on ^L */ + +/********************************************************************** + + TYI - Read Character From TTY (buffered) + +**********************************************************************/ + +tyi () + + {while (tty_input_count <= 0) + {if (tty_input_channel < 0) tyiopn (); + tty_input_count = get_buf (tty_input_buffer, + tty_input_buffer_size, '\r', ""); + tty_input_ptr = tty_input_buffer; + if (tty_input_count == 0) return (0); + } + --tty_input_count; + return (*tty_input_ptr++); + } + +/********************************************************************** + + UTYO - output character to TTY (unbuffered) + +**********************************************************************/ + +utyo (c) + + {if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (tty_output_count > 0) tyo_flush (); + c =& 0177; + if (c != 16) uoiot (tty_output_channel, c); + else + {uoiot (tty_output_channel, '^'); + uoiot (tty_output_channel, 'P'); + } + } + } + +/********************************************************************** + + TYO - output character to TTY + +**********************************************************************/ + +tyo (c) + + {c =& 0177; + + if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (c != 16) {*tty_output_ptr++ = c; ++tty_output_count;} + else + {*tty_output_ptr++ = '^'; + *tty_output_ptr++ = 'P'; + tty_output_count =+ 2; + } + if (c=='\r' || tty_output_count >= tty_output_buffer_size-2) + tyo_flush (); + } + } + +/********************************************************************** + + TYO_FLUSH - flush TTY output buffer + +**********************************************************************/ + +tyo_flush () + + {if (tty_output_channel >= 0 && tty_output_count > 0) + {siot (tty_output_channel, tty_output_bptr, + tty_output_count); + tty_output_ptr = tty_output_buffer; + tty_output_count = 0; + } + } + +/********************************************************************** + + TYOS - Output String to TTY + +**********************************************************************/ + +tyos (s) char s[]; + + {int c; + + while (c = *s++) tyo (c=='\n' ? '\r' : c); + } + +/********************************************************************** + + SPCTTY - Send "special" display control character to TTY. + +**********************************************************************/ + +spctty (c) + + {if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (tty_output_count > 0) tyo_flush (); + uoiot (tty_output_channel, 16); + uoiot (tty_output_channel, c); + } + } + +/********************************************************************** + + UTYI - read character from TTY (unbuffered and unechoed) + +**********************************************************************/ + +int utyi () + + {if (tty_input_channel<0) tyiopn (); + if (tty_output_count > 0) tyo_flush (); + return (uiiot (tty_input_channel)); + } + +/********************************************************************** + + GET_BUF - Read characters from TTY until end-of-file + simulated or given break character seen. + Read characters into given buffer, including + the terminating break character (if any). + Return a count of the number of characters + placed in the buffer. The given prompt string + will be printed first; it will be reprinted + when ^L is typed. + +**********************************************************************/ + +int get_buf (buf, buf_size, break_ch, prompt) char buf[], prompt[]; + + {char *p, *q, pbuf[tty_output_buffer_size]; + int i, c, j; + + if (tty_input_channel<0) tyiopn (); + if (!prompt[0]) /* no explicit prompt */ + {if (tty_output_count > 0) /* use partial output line */ + {tty_output_buffer[tty_output_count] = 0; + stcpy (tty_output_buffer, pbuf); + prompt = pbuf; + } + else if (tty_default_prompt) /* use default */ + prompt = tty_default_prompt; + } + if (prompt != pbuf) tyos (prompt); + if (tty_output_count > 0) tyo_flush (); + p = buf; + i = 0; /* number of chars in buffer */ + + while (TRUE) + {c = uiiot (tty_input_channel); + if (c != break_ch) switch (c) { + +case 0177: /* rubout - delete prev char */ + + if (i>0) + {c = *--p; + --i; + if (tty_device_code==2) /* display */ + {if (c=='\r') + {spctty ('U'); + q = p; + while ((c = *--q) != '\r' && + q>=buf) + {j = ctrlch(c); + while (--j>=0) spctty ('F'); + } + if (q=prompt) + {j = ctrlch(c); + while (--j>=0) spctty ('F'); + } + } + } + else + {j = ctrlch(c); + while (--j>=0) spctty ('X'); + } + } + else utyo (c); + } + continue; + +case '\p': /* redisplay buffer */ + + *p = 0; + (*ttynp) (tty_device_code==2, prompt, buf); + continue; + +case 0: /* simulate end-of-file */ + + q = buf; + while (q < p) {if (*q == '\r') *q = '\n'; ++q;} + return (i); + +case '\n': /* ignore - dont want to echo it */ + + continue; + +default: if (i <= buf_size - 2) + {++i; + utyo (*p++ = c); + } + else utyo (07); /* beep */ + continue; + } + + break; + } + + utyo ('\r'); + *p++ = c; + q = buf; + while (q < p) {if (*q == '\r') *q = '\n'; ++q;} + return (i+1); + } + +/********************************************************************** + + TTXNP - Default TTY ^L handler + +**********************************************************************/ + +ttxnp (display, prompt, buf) + int display; + char *prompt, *buf; + + {if (display) spctty ('C'); else tyo ('\r'); + tyos (prompt); + tyos (buf); + tyo_flush (); + } + +/********************************************************************** + + TTYIH - TTY Input Interrupt Handler + +**********************************************************************/ + +ttyih () + + {int c; + + c = ityic (tty_input_channel); + if (c == 023) signal (ctrls_interrupt); + else if (c == 007) signal (ctrlg_interrupt); + } + +/********************************************************************** + + TYIOPN - Open TTY for INPUT. + +**********************************************************************/ + +channel tyiopn() + + {int block[3]; + if (tty_input_channel < 0) + tty_input_channel = fopen ("/tty", 0); + on (ttyi_interrupt, ttyih); + ttyget (tty_input_channel, block); + block[0] = 020202020202; + block[1] = 030202020202; + ttyset (tty_input_channel, block); + tty_device_code = status (tty_input_channel) & 077; + return (tty_input_channel); + } + +/********************************************************************** + + TYOOPN - Open TTY for OUTPUT. + +**********************************************************************/ + +channel tyoopn() + + {int i; + if (tty_output_channel < 0) + {tty_output_channel = fopen ("/tty", 021); + i = tty_output_buffer; + i =| 0444400000000; + tty_output_bptr = i; + } + return (tty_output_channel); + } + +/********************************************************************** + + CTRLCH - Return the number of characters a character + prints as. + +**********************************************************************/ + +int ctrlch (c) + + {if (c==0177) return (2); + if (c>=' ' || c==033 || c=='\t') return (1); + if (c=='\b' || c==07) return (0); + return (2); + } + +/********************************************************************** + + SETPROMPT - Set Default Input Prompt String + +**********************************************************************/ + +setprompt (s) + char *s; + + {tty_default_prompt = s;} + \ No newline at end of file diff --git a/arc/ar2:clib/CFLOAT CMID b/arc/ar2:clib/CFLOAT CMID new file mode 100644 index 00000000..725361cf --- /dev/null +++ b/arc/ar2:clib/CFLOAT CMID @@ -0,0 +1,217 @@ +; +; CFLOAT - FLOATING POINT STUFF +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE CFLOAT +.INSRT NC +.INSRT NM + +; CONTAINS: LOG, EXP, COS, SIN, ATAN, SQRT, DTRUNCATE, DROUND, DABS + +CENTRY LOG,[V] + + MOVE B,V + JUMPLE B,OUTRNG + LDB D,[331100,,B] ;GRAB EXPONENT + SUBI D,201 ;REMOVE BIAS + TLZ B,777000 ;SET EXPONENT + TLO B,201000 ; TO 1 + MOVE A,B + FSBR A,SQRT2 + FADR B,SQRT2 + FDVB A,B + FMPR B,B + MOVE C,[0.434259751] + FMPR C,B + FADR C,[0.576584342] + FMPR C,B + FADR C,[0.961800762] + FMPR C,B + FADR C,[2.88539007] + FMPR C,A + FADR C,[0.5] + MOVE B,D + FSC B,233 + FADR B,C + FMPR B,[0.693147180] ;LOG E OF 2 + MOVE A,B + RETURN + +CENTRY EXP,[V] + + MOVE B,V + PUSH P,B + MOVM A,B + SETZM B + FMPR A,[0.434294481] ;LOG BASE 10 OF E + MOVE D,[1.0] + CAMG A,D + GO RATEX + MULI A,400 + ASHC B,-243(A) + CAILE B,43 + GO OUTRNG + CAILE B,7 + GO EXPR2 +EXPR1: FMPR D,FLOAP1(B) + LDB A,[103300,,C] + SKIPE A + TLO A,177000 + FADR A,A +RATEX: MOVEI B,7 + SETZM C +RATEY: FADR C,COEF2-1(B) + FMPR C,A + SOJN B,RATEY + FADR C,[1.0] + FMPR C,C + FMPR D,C + MOVE B,[1.0] + SKIPL (P) ;SKIP IF INPUT NEGATIVE + SKIPN B,D + FDVR B,D + MOVE A,B + SUB P,[1,,1] + RETURN + +EXPR2: LDB D,[030300,,B] + ANDI B,7 + MOVE D,FLOAP1(D) + FMPR D,D ;TO THE 8TH POWER + FMPR D,D + FMPR D,D + GO EXPR1 + +COEF2: 1.15129278 + 0.662730884 + 0.254393575 + 0.0729517367 + 0.0174211199 + 2.55491796^-3 + 9.3264267^-4 + +FLOAP1: 1.0 + 10.0 + 100.0 + 1000.0 + 10000.0 + 100000.0 + 1000000.0 + 10000000.0 + +OUTRNG: CROAK [ARGUMENT OUT OF RANGE] + GO RTN1 + +CENTRY COS,[V] + + MOVE B,V + FADR B,[1.570796326] ;COS(X)=SIN (X+PI/2) + CALL SIN,[B] +RTN1: RETURN + +CENTRY SIN,[V] + + MOVE B,V + CL .SIN + RETURN + +.SIN: MOVM A,B + CAMG A,[.0001] + RTN ;GOSPER'S RECURSIVE SIN. + FDVR B,[-3.0] ;SIN(X)=4*SIN(X/-3)**3-3*SIN(X/-3) + CL .SIN + FSC A,1 + FMPR A,A + FADR A,[-3.0] + FMPRB A,B + RTN + +CENTRY SQRT,[V] + + MOVE B,V + MOVE A,B + ASH B,-1 + FSC B,100 +SQ2: MOVE C,B ;NEWTON'S METHOD, SPECINER'S HACK. + FDVRM A,B + FADRM C,B + FSC B,-1 + CAME C,B + GO SQ2 + MOVE A,B + RETURN + +CENTRY ATAN,[V],[TEMP] + + MOVE B,V + MOVEM B,TEMP + MOVM D,B + CAMG D,[0.4^-8] ;SMALL ENOUGH SO ATAN(X)=X? + GO ATAN3 ;YES + CAML D,[7.0^7] ;LARGE ENOUGH SO THAT ATAN(X)=PI/2? + GO ATAN1 ;YES + MOVN C,[1.0] + CAMLE D,[1.0] ;IS ABS(X)<1.0? + FDVM C,D ;NO,SCALE IT DOWN + MOVE B,D + FMPR B,B + MOVE C,[1.44863154] + FADR C,B + MOVE A,[-0.264768620] + FDVM A,C + FADR C,B + FADR C,[3.31633543] + MOVE A,[-7.10676005] + FDVM A,C + FADR C,B + FADR C,[6.76213924] + MOVE B,[3.70925626] + FDVR B,C + FADR B,[0.174655439] + FMPR B,D + JUMPG D,ATAN2 ;WAS ARG SCALED? + FADR B,PI2 ;YES, ATAN(X)=PI/2-ATAN(1/X) + GO ATAN2 +ATAN1: MOVE B,PI2 +ATAN2: SKIPGE TEMP ;WAS INPUT NEGATIVE? + MOVNS B ;YES,COMPLEMENT +ATAN3: MOVE A,B + RETURN + +SQRT2: 1.41421356 +PI2: 3.1415926535/2 + +CENTRY DROUND,[V] + + MOVE A,V + FADR A,[.499999] + JUMPL A,ROUND1 + UFA A,[233000000000] + TLZ B,777000 + GO ROUND2 +ROUND1: UFA A,[233000000000] + TLO B,777000 +ROUND2: MOVE A,B + RETURN + +CENTRY DTRUNCATE,[V] + + MOVE A,V + UFA A,[233000000000] + TLZ B,777000 + MOVE A,B + RETURN + +CENTRY DABS,[V] + + MOVE A,V + JUMPGE A,RET + MOVN A,A + JUMPGE A,RET + TLZ A,400000 +RET: RETURN + +END + \ No newline at end of file diff --git a/arc/ar2:clib/CLIB H b/arc/ar2:clib/CLIB H new file mode 100644 index 00000000..aecf7f25 --- /dev/null +++ b/arc/ar2:clib/CLIB H @@ -0,0 +1,15 @@ +/* Handy definitions */ + +#define OPENLOSS (-1) /* Returned by COPEN if open fails */ + +typedef int SIXBIT; /* Six characters packed in one word */ + +typedef struct { /* ITS filespec in sixbit */ + SIXBIT dev, /* Device */ + fn1, /* First filename */ + fn2, /* Second filename */ + dir; /* Directory */ + } FILESPEC; + +#define TRUE 1 +#define FALSE 0 diff --git a/arc/ar2:clib/CLIB LIST b/arc/ar2:clib/CLIB LIST new file mode 100644 index 00000000..96a9a931 --- /dev/null +++ b/arc/ar2:clib/CLIB LIST @@ -0,0 +1,208 @@ +/* + + CLIB LIST - List of some C routines contained in the + shared library. + + *** TYPE DEFINITIONS *** + +1. SIXBIT A word containing left-justified SIXBIT + characters. + +2. FILESPEC A block of four SIXBIT words, representing + an ITS file specification. + +*/ + +# define sixbit int + +struct _filespec {sixbit dev, fn1, fn2, dir;}; +# define filespec struct _filespec + +/********************************************************************** + + PARAMETER AND RETURNED VALUE TYPE DEFINITIONS + +*/ + +char c; /* an ASCII character */ +int i; /* an integer */ +int *p; /* an integer pointer */ +int b; /* a boolean */ +char *s, *s1, *s2; /* strings */ +int rc; /* a return code, + zero if OK, non-zero otherwise */ +char *fn; /* a string representing an ITS file + name or a path name */ +int fd; /* a "file descriptor," used by the + portable I/O stuff */ + +char c6; /* a SIXBIT character */ +sixbit w; /* a SIXBIT word */ +filespec *f; /* a pointer to a FILESPEC block */ +int ch; /* an ITS channel or (returned) negative + ITS failure code */ +int fdate; /* date as stored in ITS file dir */ +int pg; /* a page number */ +int *pbp; /* pointer to a PDP-10 byte pointer */ + +/********************************************************************** + + A LISTING OF THE ROUTINES + +*/ + + /* "Portable" I/O Routines */ + +fd = copen (fn, mode, options); /* open file */ + /* mode is either + 'r' - read + 'w' - write + 'a' - append + options is usually omitted + but "s" means I/O to string (pass string as fn) + and "b" means binary I/O + returns -1 if open fails + */ + +extern int cin; /* standard input - pre-existing */ +extern int cout; /* standard output - pre-existing */ +extern int cerr; /* standard error ouput - pre-existing */ + +c = cgetc (fd); /* get character; returns 0 if eof */ +c = cputc (c, fd); /* put character */ +b = ceof (fd); /* test for end of file */ +cclose (fd); /* close file */ + +c = getchar (); /* equivalent to cgetc(cin) */ +putchar (c); /* equivalent to cputc(c,cout) */ + +gets (s1); /* read string (line) from cin */ +puts (s1); /* put string and newline to cout */ + +cprint (fd, format, arg...); /* formatted print routine */ + /* the format is a string which may contain format items + of the form %nf, where n is an optional decimal integer + (the minimum field width) and f is one of the following + characters: + + d - print next arg (an integer) in decimal + o - print next arg (an integer) in octal + s - print next arg (a string) + c - print next arg (a character) + + The file descriptor FD can be omitted, in which case + COUT is used. + */ + +i = cgeti (fd); /* get integer (binary input) */ +i = cputi (i, fd); /* put integer (binary output) */ + +cexit (cc); /* terminate job, closing all files */ + /* returning from "main" is equivalent */ + +b = istty (fd); /* test if file is a TTY */ +ch = itschan (fd); /* return actual ITS channel */ + + /* STRING Routines */ + +i = slen (s); /* find string length */ +stcpy (s1, s2); /* copy string from S1 to S2 */ +b = stcmp (s1, s2); /* compare strings */ + + /* SIXBIT Routines */ + +c6 = ccto6 (c); /* convert ASCII char to SIXBIT char */ +c = c6toc (c6); /* convert SIXBIT char to ASCII char */ +w = csto6 (s1); /* convert ASCIZ string to SIXBIT word */ +c6tos (w, s1); /* convert SIXBIT word to ASCII string */ + + /* ITS Filename Routines */ + +fparse (s1,f); /* convert file name or path name to FILESPEC */ +prfile (f,s1); /* convert FILESPEC to file name (ASCII string) */ + + /* ITS I/O Routines */ + +ch = mopen (f, mode); /* open file, handle TTY specially */ +rc = mclose (ch); /* close channel, unless TTY */ +spctty (c); /* output ^P code to TTY */ + +ch = fopen (s1, mode); /* open channel given filename or pathname, + if error return negative ITS failure code */ +ch = open (f, mode); /* open channel given filespec + if error return negative ITS failure code */ +delete (fname); /* delete the file named FNAME */ + + /* Byte Pointer Hacking */ + +ildb (pbp); +idpb (i, pbp); + + /* Interfaces to ITS System Calls */ + +rc = sysopen (ch, f, mode); /* open specific channel, if error return + negative ITS failure code */ +sysdel (f); /* delete the file specified by F */ +ch = chnloc (); /* find an available channel */ +rc = close (ch); /* close a channel */ +uclose (ch); /* close a job */ +i = status (ch); /* return channel status */ +n = fillen (ch); /* return ITS file length */ +access (ch, i); /* set file access pointer */ +reset (ch); /* reset channel */ +i = uiiot (ch); /* unit input IOT */ +uoiot (ch, i); /* unit output IOT */ +n_read = sysread (ch, p, n_words); /* block input IOT */ +n_written = syswrite (ch, p, n_words); /* block output IOT */ +fdate = rfdate (ch); /* read file creation date */ +fdate = sfdate (ch, fdate); /* set file creation date */ + +w = rsname (); /* return SNAME */ +w = runame (); /* return UNAME */ +ssname (w); /* set SNAME */ +sleep (n); /* sleep for n 30th seconds */ +rc = sysload (job_ch, prog_ch); /* load program into job */ +rc = atty (ch); /* give TTY to inferior */ +rc = dtty (ch); /* take TTY from inferior */ +valret (s); /* .VALUE a string (or 0) */ + +t = etime(); /* return system elapsed time in 1/60 sec units*/ +t = cputm(); /* return job CPU time in 1/60 sec units */ +t = getcpu(); /* return job CPU time in 4.096 usec units */ + +rc = corblk (mode, dest, destpg, src, srcpg); +cortyp (pg, &resultblock); +rc = pageid (idn, pg); + +/* USET hacking */ + +what = rsuset (where); +what = wsuset (where, what); + +what = ruset (who, where); +what = wuset (who, where, what); + +/* TRANSL hacking */ + +rc = tranad (job, from_file_spec, to_file_spec, flags); +rc = trancl (job, flags); +rc = trandl (job, file_spec, flags); + +/* storage allocation */ + +p = salloc (n); /* allocate n words, return pointer to it */ +sfree (p); /* free storage allocated by salloc */ +s = calloc (n); /* allocate n characters, return ptr to it */ +cfree (s); /* free storage allocated by calloc */ + +/* interrupt hacking */ + +previous_handler = on (interrupt_number, new_handler); +signal (interrupt_number); + +/* miscellaneous routines */ + +i = wfnz (p); /* wait for word pointed to by P to become + non-zero; then return that value */ + + \ No newline at end of file diff --git a/arc/ar2:clib/CLIB PRGLST b/arc/ar2:clib/CLIB PRGLST new file mode 100644 index 00000000..0ffaa743 --- /dev/null +++ b/arc/ar2:clib/CLIB PRGLST @@ -0,0 +1,47 @@ +; CLIB PRGLST +; *ITS* + +; This file is a Stinkr XFILE that lists the program files that make up the +; shared C library. It is used in the construction of a new library. It +; is also used to construct test versions of programs not using the shared +; library and to construct timing versions of programs (which cannot use +; the shared library). + +; The following are ITS- dependent files from C10LIB: + +l clib;c10cor +l clib;c10exp +l clib;c10fd +l clib;c10fil +l clib;c10fnm +l clib;c10fo +l clib;c10int +l clib;c10io +l clib;c10map +l clib;c10mio +l clib;c10pag +l clib;c10sys +l clib;c10tty + +; The following are ITS-independent files from CLIB: + +l clib;ac +l clib;alloc +l clib;apfnam +l clib;atoi +l clib;blt +l clib;cfloat +l clib;cprint +l clib;date +l clib;fprint +l clib;match +l clib;pr60th +l clib;random +l clib;stkdmp +l clib;string +l clib;uuoh + +; This must be last: + +l clib;c10run + \ No newline at end of file diff --git a/arc/ar2:clib/CLIB STINKR b/arc/ar2:clib/CLIB STINKR new file mode 100644 index 00000000..b50c1ef6 --- /dev/null +++ b/arc/ar2:clib/CLIB STINKR @@ -0,0 +1,8 @@ +; xfile for loading basic C library +; this file must be loaded first +; segment 0 must start at 100 + +s 100,n,p,n +i sinit +l clib;[crel] > + \ No newline at end of file diff --git a/arc/ar2:clib/CLIB TESTER b/arc/ar2:clib/CLIB TESTER new file mode 100644 index 00000000..a87d3a75 --- /dev/null +++ b/arc/ar2:clib/CLIB TESTER @@ -0,0 +1,16 @@ +; CLIB TESTER +; *ITS* + +; This file is a Stinkr XFILE to be used to construct test versions of +; programs that do not use the shared C library. Construction of such +; programs is useful to test changes to library routines prior to the +; construction of a new version of the library. + +; This file must be XFILEd first. +; Segment 0 must start at 100. + +s 100,n,p,n +i linit + +x c;clib prglst + \ No newline at end of file diff --git a/arc/ar2:clib/CLIB TIMER b/arc/ar2:clib/CLIB TIMER new file mode 100644 index 00000000..e13e58ea --- /dev/null +++ b/arc/ar2:clib/CLIB TIMER @@ -0,0 +1,18 @@ +; CLIB TIMER +; *ITS* + +; This file is a Stinkr XFILE to be used to construct timing versions of +; programs. The only difference from normal programs is that a different +; handler is used for the procedure call UUOs. + +; This file must be XFILEd first. +; Segment 0 must start at 100. + +s 100,100000,400000,600000 +i tinit + +l clib;c10tmr +l clib;c10tpr + +x clib;clib prglst + \ No newline at end of file diff --git a/arc/ar2:clib/CODE INSERT b/arc/ar2:clib/CODE INSERT new file mode 100644 index 00000000..4968883f --- /dev/null +++ b/arc/ar2:clib/CODE INSERT @@ -0,0 +1,35 @@ +; MACROS FOR SEPARATE CODE LITERAL AREA +; THIS DOES NOT HANDLE RECURSIVE CALLS + +CD%N==0 +IF1,[CD%LOC==0] + +DEFINE CD%AS *PREFIX*,#SEGNO,*SUFFIX* + PREFIX!SEGNO!SUFFIX + TERMIN + +DEFINE CODE BODY +IF2,[ CD%AS/CD%LOC+CD%/,CD%N+1] + + CD%N==CD%N+1 + DOT==.-1 + CD%OLC==. + IF1,[ + BODY + CD%AS /CD%/,CD%N,/==CD%LOC/ + CD%LOC==CD%LOC+<.-CD%OLC> + ] + IF2,[ + CD%AS /LOC CD%LOC+CD%/,CD%N + BODY + ] + LOC CD%OLC + TERMIN + +DEFINE INSCODE + IF1,[ + CD%SIZ==CD%LOC + CD%LOC==. + BLOCK CD%SIZ + ] + TERMIN diff --git a/arc/ar2:clib/CPRINT C b/arc/ar2:clib/CPRINT C new file mode 100644 index 00000000..a70d3418 --- /dev/null +++ b/arc/ar2:clib/CPRINT C @@ -0,0 +1,177 @@ +/* + + CPRINT - C Formatted Print Routine + + Extendable Format Version: + Print Routines should expect the following + arguments (n specified when defined): + 1 to n: n data arguments + n+1: file descriptor + n+2: field width (0 if none given) + +*/ + +# define WORDMASK 077777777777 +# define SMALLEST "-34359738368" + +extern int cin, cout, cerr; +int prc(), prd(), pro(), prs(); + +static int (*format_table[26]) () { + /* a */ 0, 0, prc, prd, 0, 0, 0, 0, + /* i */ 0, 0, 0, 0, 0, 0, pro, 0, + /* q */ 0, 0, prs, 0, 0, 0, 0, 0, + /* y */ 0, 0}; + +static int format_nargs [26] { + /* a */ 0, 0, 1, 1, 0, 0, 0, 0, + /* i */ 0, 0, 0, 0, 0, 0, 1, 0, + /* q */ 0, 0, 1, 0, 0, 0, 0, 0, + /* y */ 0, 0}; + +deffmt (c, p, n) int (*p)(); + + {if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A'); + if (c >= 'a' && c <= 'z') + {if (n >= 0 && n <= 3) + {format_table [c - 'a'] = p; + format_nargs [c - 'a'] = n; + } + else cprint (cerr, "bad nargs to DEFFMT: %d\n", n); + } + else cprint (cerr, "bad character to DEFFMT: %c\n", c); + } + +cprint (a1,a2,a3,a4,a5,a6,a7,a8) + + {int *adx, c, width; + char *fmt; + int fn, (*p)(), n; + + if (cisfd(a1)) /* file descriptor */ + {fn = a1; + fmt = a2; + adx = &a3; + } + else + {fn = cout; + fmt = a1; + adx = &a2; + } + + while (c= *fmt++) + + {if (c!='%') cputc (c,fn); + else + {width = 0; + while ((c = *fmt)>='0' && c<='9') + width = (width*10) + (*fmt++ - '0'); + c = *fmt++; + if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A'); + if (c >= 'a' && c <= 'z') + {p = format_table [c - 'a']; + n = format_nargs [c - 'a']; + if (p) + {switch (n) { + case 0: (*p) (fn, width); break; + case 1: (*p) (adx[0], fn, width); break; + case 2: (*p) (adx[0], adx[1], fn, width); break; + case 3: (*p) (adx[0], adx[1], adx[2], fn, width); break; + } + adx =+ n; + continue; + } + cputc (c, fn); + } + else cputc (c, fn); + } + } + } + +/********************************************************************** + + PRO - Print Octal Integer + +**********************************************************************/ + +pro (i, f, w) + + {int b[30], *p, a; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + p = b; + while (a = ((i>>3) & WORDMASK)) + {*p++ = (i&07) + '0'; + i = a; + } + *p++ = i+'0'; + if (i) *p++ = '0'; + i = w - (p-b); + while (--i>=0) cputc (' ', f); + while (p > b) cputc (*--p, f); + } + +/********************************************************************** + + PRD - Print Decimal Integer + +**********************************************************************/ + +prd (i, f, w) + + {int b[30], *p, a, flag; + + flag = 0; + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + p = b; + if (i < 0) {i = -i; flag = 1;} + if (i < 0) {stcpy (SMALLEST, b); p = b+slen(b); flag = 0;} + else + {while (a = i/10) + {*p++ = i%10 + '0'; + i = a; + } + *p++ = i+'0'; + } + if (flag) *p++ = '-'; + i = w - (p-b); + while (--i>=0) cputc (' ', f); + while (p > b) cputc (*--p, f); + } + +/********************************************************************** + + PRS - Print String + +**********************************************************************/ + +prs (s, f, w) char *s; + + {int i; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + i = (w > 0 ? w - slen (s) : 0); + while (--i >= 0) cputc (' ', f); + while (i = *s++) cputc (i, f); + } + +/********************************************************************** + + PRC - Print Character + +**********************************************************************/ + +prc (c, f, w) + + {int i; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + i = w - 1; + while (--i >= 0) cputc (' ', f); + cputc (c, f); + } + \ No newline at end of file diff --git a/arc/ar2:clib/CRATE 10 b/arc/ar2:clib/CRATE 10 new file mode 100644 index 00000000..5c5f0345 --- /dev/null +++ b/arc/ar2:clib/CRATE 10 @@ -0,0 +1,39 @@ +TITLE CRATE C LIBRARY DESECRATOR FOR VERSION 10 +A==1 +GO==JRST + +.GLOBAL INIT,PAGENO,NPAGES,VERNAM +INIT: .VALUE [ASCIZ/: INITIALIZE IF NOT FOR VERSION 10  + /] + .CALL [SETZ + SIXBIT/OPEN/ + 1000,,1 ; CHANNEL 1 + [SIXBIT/DSK/] + [SIXBIT/[CLIB]/] + VERNAM + SETZ [SIXBIT/C/] + ] + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE  +/] + MOVN A,NPAGES + HRLZ A,A + HRR A,PAGENO + .CALL [SETZ + 'CORBLK + 1000,,600000 ; READ-WRITE ACCESS + 1000,,-1 ; PUT IN MY MAP + A ; AOBJN POINTER + 401000,,1 ; FROM FILE + ] + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE  +/] + .CLOSE 1, + .VALUE [ASCIZ/: ALL SET  +:SL /] + GO .-1 + +PAGENO: 246. ; FIRST PAGE TO SMASH +NPAGES: 10. ; NUMBER OF PAGES TO SMASH +VERNAM: SIXBIT/10/ ; VERSION NUMBER IN SIXBIT + +END INIT diff --git a/arc/ar2:clib/CRATE 9 b/arc/ar2:clib/CRATE 9 new file mode 100644 index 00000000..2a34eeb7 --- /dev/null +++ b/arc/ar2:clib/CRATE 9 @@ -0,0 +1,40 @@ +TITLE CRATE C LIBRARY DESECRATOR FOR VERSION 9 +A==1 +GO==JRST + +.GLOBAL INIT,PAGENO,NPAGES,VERNAM +INIT: .VALUE [ASCIZ/: INITIALIZE IF NOT FOR VERSION 9  + /] + .CALL [SETZ + SIXBIT/OPEN/ + 1000,,1 ; CHANNEL 1 + [SIXBIT/DSK/] + [SIXBIT/[CLIB]/] + VERNAM + SETZ [SIXBIT/C/] + ] + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE  +/] + MOVN A,NPAGES + HRLZ A,A + HRR A,PAGENO + .CALL [SETZ + 'CORBLK + 1000,,600000 ; READ-WRITE ACCESS + 1000,,-1 ; PUT IN MY MAP + A ; AOBJN POINTER + 401000,,1 ; FROM FILE + ] + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE  +/] + .CLOSE 1, + .VALUE [ASCIZ/: ALL SET  +:SL /] + GO .-1 + +PAGENO: 371 ; FIRST PAGE TO SMASH +NPAGES: 7 ; NUMBER OF PAGES TO SMASH +VERNAM: SIXBIT/9/ ; VERSION NUMBER IN SIXBIT + +END INIT + \ No newline at end of file diff --git a/arc/ar2:clib/CTYPE C b/arc/ar2:clib/CTYPE C new file mode 100644 index 00000000..bb3285b9 --- /dev/null +++ b/arc/ar2:clib/CTYPE C @@ -0,0 +1,17 @@ +# include "ctype.h" + +# define S _S +# define N _N +# define L _L +# define U _U + +char _ctype[] { + 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, + S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + N, N, N, N, N, N, N, N, N, N, 0, 0, 0, 0, 0, 0, + 0, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, 0, 0, 0, 0, 0, + 0, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, + L, L, L, L, L, L, L, L, L, L, L, 0, 0, 0, 0, 0}; + \ No newline at end of file diff --git a/arc/ar2:clib/CTYPE H b/arc/ar2:clib/CTYPE H new file mode 100644 index 00000000..893eaaa7 --- /dev/null +++ b/arc/ar2:clib/CTYPE H @@ -0,0 +1,16 @@ +#define _U 01 +#define _L 02 +#define _A 03 +#define _N 04 +#define _S 010 + +extern char _ctype[]; + +#define isalpha(c) (_ctype[c]&_A) +#define isupper(c) (_ctype[c]&_U) +#define islower(c) (_ctype[c]&_L) +#define isdigit(c) (_ctype[c]&_N) +#define isspace(c) (_ctype[c]&_S) +#define toupper(c) ((c)-'a'+'A') +#define tolower(c) ((c)-'A'+'a') + \ No newline at end of file diff --git a/arc/ar2:clib/DATE C b/arc/ar2:clib/DATE C new file mode 100644 index 00000000..b794ef94 --- /dev/null +++ b/arc/ar2:clib/DATE C @@ -0,0 +1,155 @@ +/* + +DATE - Date Hacking Routines + +These routines recognize three representations for dates: + +(1) CAL - calender date, a system-independent representation + consisting of a record containing six integers + for the year, month, day, hour, minute, and second + +(2) FDATE - the ITS date representation used in file directories + +(3) UDATE - the UNIX date representation, seconds since + Jan 1, 1970, GMT. + +(4) TDATE - the TOPS-20 date representation + +The routines: + + u2cal (udate, cd) - convert udate to cal + udate = cal2u (cd) - convert cal to udate + f2cal (fdate, cd) - convert fdate to cal + fdate = cal2f (cd) - convert cal to fdate + t2cal (tdate, cd) + tdate = cal2t (cd) + prcal (cd, fd) - print cal (CIO) + + +*/ + +# define ZONE 5 /* offset of local zone from GMT */ +struct _cal {int year, month, day, hour, minute, second;}; +# define cal struct _cal + +static int month_tab1[] {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static int month_tab2[] {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; +static int year_tab[] {0, 365, 2*365, 3*365+1}; + +# define four_years (4*365+1) + +static char *month_name[] { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + +# rename srctab "SRCTAB" + +u2cal (udate, cd) cal *cd; + + {udate =- (ZONE*60*60); + cd->second = udate%60; udate =/ 60; + cd->minute = udate%60; udate =/ 60; + cd->hour = udate%24; udate =/ 24; + cd->year = 1970 + 4*(udate/four_years); + udate =% four_years; + cd->year =+ srctab (year_tab, 4, &udate); + cd->month = srctab (cd->year%4==0 ? month_tab2 : month_tab1, + 12, &udate) + 1; + cd->day = udate + 1; + } + +int cal2u (cd) cal *cd; + + {int udate, year; + + year = cd->year; + udate = cd->second + 60*(cd->minute + 60*(cd->hour + 24*(cd->day-1))); + udate =+ (year%4==0 ? month_tab2 : month_tab1) [cd->month-1] * 60*60*24; + year =- 1970; + if (year<0) year=0; + udate =+ 60*60*24*(four_years*(year/4) + year_tab[year%4]); + udate =+ (ZONE*60*60); + return (udate); + } + +f2cal (fdate, cd) cal *cd; + + {cd->year = 1900 + ((fdate>>27) & 0177); + if ((cd->month = (fdate>>23) & 017) > 12) cd->month = 0; + cd->day = (fdate>>18) & 037; + fdate = (fdate & 0777777) >> 1; + cd->second = fdate % 60; + fdate =/ 60; + cd->minute = fdate % 60; + cd->hour = fdate / 60; + } + +int cal2f (cd) cal *cd; + + {int fdate; + + fdate = 2*(cd->second + 60*(cd->minute + 60*cd->hour)); + fdate =| cd->day << 18; + fdate =| cd->month << 23; + fdate =| (cd->year - 1900) << 27; + return (fdate); + } + +t2cal (tdate, cd) cal *cd; + + {int vec[3], udate; + SYSODCNV (tdate, 0, vec); + cd->year = vec[0] >> 18; + cd->month = (vec[0] & 0777777) + 1; + cd->day = (vec[1] >> 18) + 1; + udate = vec[2] & 0777777; + cd->second = udate%60; udate =/ 60; + cd->minute = udate%60; udate =/ 60; + cd->hour = udate%24; + } + +int cal2t (cd) cal *cd; + + {char buf[100]; + int f; + f = copen (buf, 'w', "s"); + cprint (f, "%d/%d/%d %d:%d:%d", cd->month, cd->day, cd->year, + cd->hour, cd->minute, cd->second); + cclose (f); + return (SYSIDTIM (mkbptr (buf), 0)); + } + +prcal (cd, f) cal *cd; + + {char *s; + int m; + m = cd->month-1; + if (m>=0 && m<=11) s = month_name[m]; + else s = "?"; + cprint (f, "%s%3d%5d ", s, cd->day, cd->year); + cputc (cd->hour/10+'0', f); + cputc (cd->hour%10+'0', f); + cputc (':', f); + cputc (cd->minute/10+'0', f); + cputc (cd->minute%10+'0', f); + cputc (':', f); + cputc (cd->second/10+'0', f); + cputc (cd->second%10+'0', f); + } + +int srctab (tab, sz, n) int *tab, sz, *n; + + {int *p, i; + + p = tab+sz; + i = *n; + + while (--p>=tab) + {if (*p <= i) + {*n = i - *p; + return (p-tab); + } + } + return (0); + } + \ No newline at end of file diff --git a/arc/ar2:clib/FPRINT C b/arc/ar2:clib/FPRINT C new file mode 100644 index 00000000..2ff150f2 --- /dev/null +++ b/arc/ar2:clib/FPRINT C @@ -0,0 +1,90 @@ +# + +/* + * + * FPRINT - Floating-Point Print Routine + * + * requires: + * + * i = dtruncate (d) + * i = dround (d) + * d = dabs (d) + * cputc (c, fd) + * + * internal routines and tables: + * + * fp3, fp4, fp5, fp6, ft0, ft1, ft10 + * + */ + +static double ft0[] {1e1, 1e2, 1e4, 1e8, 1e16, 1e32}; +static double ft1[] {1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32}; +static double ft10[] {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7}; +double dabs (); + +fprint (d, fd) + double d; + + {if (d<0) {cputc ('-', fd); d = dabs (d);} + if (d>0) + {if (d < 1.0) {fp4 (d, 0, fd); return;} + else if (d >= 1e8) {fp4 (d, 1, fd); return;} + } + fp3 (d, fd); + } + +fp3 (d, fd) /* print positive double */ + double d; + + {int i, n; + double fraction; + + i = dtruncate (d); + fraction = d - i; + n = fp5 (i, fd); /* return # of digits printed */ + cputc ('.', fd); + n = 8 - n; + fraction =* ft10[n]; + i = dround (fraction); + fp6 (i, n, fd); /* prints n digits */ + } + +fp4 (d, flag, fd) + double d; + + {int c, e; + + c = 6; + e = 0; + while (--c >= 0) + {e =<< 1; + if (flag ? d >= ft0[c] : d <= ft1[c]) + {++e; + d =* (flag ? ft1[c] : ft0[c]); + } + } + if (d < 1.0) {++e; d =* 10.0;} + fp3 (d, fd); + cputc ('e', fd); + cputc (flag ? '+' : '-', fd); + fp5 (e, fd); + } + +int fp5 (i, fd) /* print decimal integer, return # of digits printed */ + + {int a; + + if (a = i/10) a = fp5 (a, fd); + else a = 0; + cputc (i%10 + '0', fd); + return (a+1); + } + +int fp6 (i, n, fd) /* print decimal integer given # of digits */ + + {if (n>0) + {if (n>1) fp6 (i/10, n-1, fd); + cputc (i%10 + '0', fd); + } + } + \ No newline at end of file diff --git a/arc/ar2:clib/GETSRV C b/arc/ar2:clib/GETSRV C new file mode 100644 index 00000000..bc277d58 --- /dev/null +++ b/arc/ar2:clib/GETSRV C @@ -0,0 +1,79 @@ +# include "c.defs" + +/********************************************************************** + + GETSRV - Lookup name in table of Arpanet Servers + Currently runs only on ITS machines (needs a particular file). + Requires upper case string. + +**********************************************************************/ + +# define TABLESIZE 10000 + +int getsrv (s) char *s; /* return -1 if bad */ + + {static int *p; + int n, *nmtab; + /* first check for decimal host number */ + n = atoi (s); + if (n > 0) return (n); + /* if not a number, must search the table of host names */ + if (!p) /* host file not read in yet */ + {int f, *q, *e; + char *ss; + p = calloc (TABLESIZE); + ss = "sysbin;hosts1 >"; + f = copen (ss, 'r', "b"); + if (f == OPENLOSS) + {cprint ("Unable to find host table: %s\n", ss); + return (-1); + } + e = p + TABLESIZE; + q = p; + while (!ceof (f) && q= 0) + {int nte, nm, bp; + nte = *nmtab++; + nm = nte & 0777777; /* index of name in table */ + nm = p + nm; /* pointer to name in table */ + bp = 0440700000000 | nm; /* byte pointer to name */ + if (_gmatch (bp, s)) /* found entry */ + {int num; + num = nte >> 18; /* index of numtab entry in table */ + if (p[num+2]<0) /* it's a server */ + return (p[num]); + return (-1); + } + } + return (-1); + } + +_gmatch (bp, s) char *s; + + {int c; + while (c = ildb (&bp)) + if (c != *s++) return (FALSE); + return (*s == 0); + } + + +#ifdef testing +main () + + {char buf[100]; + int n; + + while (TRUE) + {cprint ("Enter name:"); + gets (buf); + n = getsrv (buf); + cprint ("Name=%s,Number=%d\n", buf, n); + } + } + +#endif + \ No newline at end of file diff --git a/arc/ar2:clib/ITS BITS b/arc/ar2:clib/ITS BITS new file mode 100644 index 00000000..f0a2782b --- /dev/null +++ b/arc/ar2:clib/ITS BITS @@ -0,0 +1,77 @@ +/* open modes */ + +# define UAI 0 /* unit ascii input */ +# define UAO 1 /* unit ascii output */ +# define BAI 2 /* block ascii input */ +# define BAO 3 /* block ascii output */ +# define UII 4 /* unit image input */ +# define UIO 5 /* unit image output */ +# define BII 6 /* block image input */ +# define BIO 7 /* block image output */ +# define OLD 010 /* open old job only */ + +/* user variables */ + +# define UPC 0 +# define UTTY 02 +# define UUNAME 04 +# define UJNAME 05 +# define USTOP 07 +# define UPIRQ 010 +# define UINF 011 +# define USV40 013 +# define UIPIRQ 014 +# define UAPIRQ 015 +# define USNAME 016 +# define UPICLR 017 +# define URUNT 024 +# define UHSNAME 043 +# define UOPTION 054 +# define USUPPR 065 +# define UXUNAME 074 +# define UXJNAME 075 + +/* USTOP magic bit */ + +# define BUSRC 0100000000000 + +/* .OPTION bits */ + +# define OPTBRK 020000000000 /* can handle .BREAKs */ +# define OPTCMD 040000000000 /* got command arg to give */ +# define OPTOPC 000200000000 /* always reset PC on interrupt */ + +/* first word interrupt bits */ + +# define PJRLT 0200000000000 /* Real-time timer went off [3] (A) */ +# define PJRUN 0100000000000 /* Run-time timer went off [3] (A) */ +# define PJTTY 02000000000 /* Don't have TTY [2] (S) */ +# define PJPAR 01000000000 /* Memory parity error [1] (A) */ +# define PJFOV 0400000000 /* ARFOV (Floating overflow) [3] (S) */ +# define PJWRO 0200000000 /* WIRO (Write in read-only page) [2] (S) */ +# define PJFET 0100000000 /* Fetched insn from impure page [2] (S) */ +# define PJTRP 040000000 /* SYSUUO (System uuo in trap mode) [2] (S) */ +# define PJDBG 02000000 /* System being debugged state change [3] (A) */ +# define PILOS 01000000 /* .LOSE */ +# define PICLI 0400000 /* CLI interrupt [3] (A) */ +# define PIPDL 0200000 /* PDL overflow [3] (S) */ +# define PILTP 0100000 /* 340 or E&S light pen hit [3] (A) */ +# define PIMAR 040000 /* MAR hit. [2] (S) */ +# define PIMPV 020000 /* MPV (memory protect violation) [2] (S) */ +# define PICLK 010000 /* Slow (1/2 sec) clock [3] (A) */ +# define PI1PR 04000 /* Single-instruction proceed [1] (S) */ +# define PIBRK 02000 /* .BREAK instruction executed. [1] (S) */ +# define PIOOB 01000 /* Address out of bounds [2] (S) */ +# define PIIOC 0400 /* IOCERR (I/O channel error) [2] (S) */ +# define PIVAL 0200 /* .VALUE instruction executed [1] (S) */ +# define PIDWN 0100 /* System-going-down status change [3] (A) */ +# define PIILO 040 /* ILOPR, ILUUO (illegal operation) [2] (S) */ +# define PIDIS 020 /* Display memory protect [2] (A) */ +# define PIARO 010 /* Arithmetic overflow [3] (S) */ +# define PIB42 04 /* BADPI (Bad location 42) [1] (S) */ +# define PICZ 02 /* ^Z or CALL typed on terminal [1] (A) */ +# define PITYI 01 /* TTY input (obsolete) [3] (A) */ + +# define IBACKUP (PJTTY|PJWRO|PJFET|PJTRP|PIMPV|PIOOB|PIIOC|PIILO) + /* interrupts where PC may need SOSing */ + \ No newline at end of file diff --git a/arc/ar2:clib/MAKLIB C b/arc/ar2:clib/MAKLIB C new file mode 100644 index 00000000..fd2f50a5 --- /dev/null +++ b/arc/ar2:clib/MAKLIB C @@ -0,0 +1,283 @@ +# include "c.defs" +# include "its.bits" + +/* + + MAKLIB + + *ITS* + + Shared C Library Construction Program + + Loads library stuff from TS CLIB into an inferior. Writes + pure part as a sharable file. Constructs a MIDAS program + to load the impure part and define all symbols. + + *** Instructions for constructing a new version of the + shared C library: + + 1. Edit the file MKCLIB STINKR to contain all of the + files you want to be in the library. See that file + for further instructions. + 2. Create a TS CLIB in the C directory by running Stinkr on + MKCLIB STINKR. + 3. Create a TS MAKLIB using MAKLIB STINKR. + 4. Run TS MAKLIB. + + The STINKR files are kept in C10LIB. + +*/ + +# define MAXSYMS 4000 /* maximum number of symbols */ +# define NAMMASK 0037777777777 /* name mask away flags */ +# define SYMMASK 0037777777777 /* symtab mask for name */ + +struct _syment {int sym, val;}; +typedef struct _syment syment; +syment symtab[MAXSYMS]; +syment *csymp, *esymp; + +main (argc, argv) char *argv[]; + + {int flib, fmak, version, nam, val, npage, pgno, zeroc; + int j, jch, pch, ilo, ihi, plo, phi, count; + char svers[20], buf[50], vbuf[100]; + filespec ff; + syment *p; + + /* open library program file */ + + pch = fopen ("TS CLIB", UII); + if (pch < 0) + {puts ("Unable to find TS CLIB"); + return; + } + + /* create an inferior job */ + + j = j_create (020); + if (j < 0) + {puts ("Unable to create inferior job"); + return; + } + + j_name (j, &ff); + jch = open (&ff, UII); + if (jch < 0) + {puts ("Unable to open inferior job"); + return; + } + + /* load CLIB program into inferior */ + + if (sysload (jch, pch)) + {puts ("Unable to load TS CLIB"); + return; + } + rsymtab (pch); + + flib = copen ("c/[clib].>", 'w', "b"); + if (flib < 0) + {puts ("Unable to create library file"); + return; + } + filnam (itschan (flib), &ff); + version = ff.fn2; + c6tos (version, svers); + apfname (buf, "c/[cmak].foo", svers); + fmak = copen (buf, 'w'); + if (fmak < 0) + {puts ("Unable to create maker file"); + cclose (flib); + delete ("c/clib.>"); + return; + } + cprint ("Creating C library version %s\n", svers); + cprint (fmak, ";\tSHARED C LIBRARY MAKER -- VERSION %s\n\n", svers); + cprint (fmak, ".INSRT C;NC INSERT\n"); + cprint (fmak, "TITLE CLIB C LIBRARY VERSION %s\n\n", svers); + + p = symtab; + while (p < csymp) + {nam = p->sym; + val = p->val; + ++p; + prname (nam, fmak, 0); + cprint (fmak, "\"=%o\n", val); + } + cputc ('\n', fmak); + + /* now define impure area */ + + ilo = jread (lookup (rdname ("SEG0LO")), jch); + ihi = jread (lookup (rdname ("SEG1HI")), jch); + count = ihi - ilo + 1; + + cprint (fmak, "\t.IDATA\n\n"); + zeroc = 0; + access (jch, ilo); + while (--count >= 0) + {val = uiiot (jch); + if (val) + {if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc); + zeroc = 0; + cprint (fmak, "\t%o\n", val); + } + else ++zeroc; + } + if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc); + cputc ('\n', fmak); + + plo = jread (lookup (rdname ("SEG2LO")), jch); + phi = jread (lookup (rdname ("SEG3HI")), jch); + phi =+ 0100; + plo =& ~01777; + npage = (phi - plo + 02000) >> 10; + pgno = plo >> 10; + + cprint (fmak, "IPATCH\": BLOCK 40\n\ + .CODE\n\ +INIT\": MOVEI P,ARGV\n\ + PUSHJ P,MAPIN\"\n\ + MOVEI A,ZMAIN\"\n\ + HRRM A,CALLER\"\n\ + GO START\"\n\n\ +MAPIN: .CALL [SETZ\n\ + SIXBIT/OPEN/\n\ + 1000,,1 ; CHANNEL 1\n\ + [SIXBIT/DSK/]\n\ + [SIXBIT/[CLIB]/]\n\ + [SIXBIT/%s/]\n\ + SETZ [SIXBIT/C/]\n\ + ]\n\ + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE /]\n\ + MOVE A,[-%d.,,%o]\n\ + .CALL [SETZ\n\ + 'CORBLK\n\ + 1000,,200000 ; READ-ONLY\n\ + 1000,,-1 ; PUT IN MY MAP\n\ + A ; AOBJN POINTER\n\ + 401000,,1 ; FROM FILE\n\ + ]\n\ + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE /]\n\ + .CLOSE 1,\n\ + POPJ P,\n\n\ +MAPOUT\":MOVE A,[-%d.,,%o]\n\ + .CALL [SETZ\n\ + 'CORBLK\n\ + 1000,,0 ; DELETE\n\ + 1000,,-1 ; FROM ME\n\ + 400000,,A ; AOBJN POINTER\n\ + ]\n\ + .VALUE [ASCIZ/: CAN'T MAP OUT LIBRARY PAGES /]\n\ + POPJ P,\n\n\ +SINIT\": MOVE A,[PUSHJ P,MAPIN]\n\ + MOVEM A,ISTART\"\n\ + MOVE A,[PUSHJ P,MAPOUT]\n\ + MOVEM A,IDONE\"\n\ + GO LINIT\"\n\n", svers, npage, pgno, npage, pgno); + + cprint (fmak, ".PDATA\NEND INIT\n"); + cclose (fmak); + + count = phi - plo + 1; + count = (count + 01777) & ~01777; + access (jch, plo); + while (--count >= 0) + {val = uiiot (jch); + cputi (val, flib); + } + cclose (flib); + + fmak = copen (vbuf, 'w', "s"); + cprint (fmak, ":KILL\r:MIDAS C;[CREL] %s _ C;[CMAK] %s\r", svers, svers); + cclose (fmak); + valret (vbuf); + } + +int jread (loc, jch) + + {access (jch, loc); + return (uiiot (jch)); + } + +/********************************************************************** + + SYMBOL TABLE + +**********************************************************************/ + +rsymtab (ch) + + {int count; + csymp = symtab; + esymp = symtab + MAXSYMS; + + uiiot (ch); + count = -((uiiot (ch) >> 18) | 0777777000000) / 2; + uiiot (ch); + uiiot (ch); + --count; + + while (--count >= 0) + {int n, val; + n = uiiot (ch) & SYMMASK; + val = uiiot (ch); + csymp->sym = n; + csymp->val = val; + ++csymp; + } + } + +int lookup (sym) + + {syment *p; + + for (p = symtab; p < csymp; ++p) + if (p->sym == sym) return (p->val); + puts ("symbol missing"); + return (01000000); + } + +char tab40[] {' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', '.', '$', '%'}; + +rdname (p) char *p; + + {int w, factor, c; + char *s; + s = p; + w = 0; + factor = (40*40*40*40*40); + while (c = *s++) + {int i; + if (c==' ') continue; + if (factor == 0) continue; + if (c>='a' && c<='z') c =+ ('A'-'a'); + for (i=0;i<40;++i) + if (c == tab40[i]) + {w =+ (i * factor); + factor =/ 40; + break; + } + if (i>=40) break; + } + return (w); + } + +prname (n, fn, w) + + {n =& NAMMASK; + if (n) p40 (n, fn); + } + +p40 (i, fn) + + {int a; + if (a = i/40) p40 (a, fn); + i =% 40; + if (i) cputc (tab40[i], fn); + } + \ No newline at end of file diff --git a/arc/ar2:clib/MAKLIB STINKR b/arc/ar2:clib/MAKLIB STINKR new file mode 100644 index 00000000..12b5ed90 --- /dev/null +++ b/arc/ar2:clib/MAKLIB STINKR @@ -0,0 +1,7 @@ +x clib +l maklib +l apfnam +l c10job +l c10fnm +o ts maklib + \ No newline at end of file diff --git a/arc/ar2:clib/MATCH C b/arc/ar2:clib/MATCH C new file mode 100644 index 00000000..635f65e1 --- /dev/null +++ b/arc/ar2:clib/MATCH C @@ -0,0 +1,94 @@ +# include "c.defs" + +/********************************************************************** + + SMATCH - pattern matching procedure + + The pattern P is a character string which is to be matched + with the data string S. Certain characters in P are treated + special: + + '*' match any substring + '?' match any character + '\\' quote following character + +**********************************************************************/ + +int smatch (p, s) + char *p; + char *s; + + {int c1, c2, i; + + while (TRUE) + {c1 = *p++; + c2 = *s++; + switch (c1) { + + case 0: return (!c2); + case '?': if (!c2) return (FALSE); + continue; + case '*': while (*p=='*') ++p; + if (*p==0) return (TRUE); + i = -1; + do if (smatch (p, s+i)) return (TRUE); + while (s[i++]); + return (FALSE); + case '\\': if (!(c1 = *p++)) return (FALSE); + /* fall through */ + default: if (c1 != c2) return (FALSE); + continue; + } + } + } + +/********************************************************************** + + SINDEX (P, DS) + + Return the index of the first occurrence of the string P + in the string DS. Return -1 if P does not occur in DS. + +**********************************************************************/ + +int sindex (p, ds) + char *p; + char *ds; + + {int c1, c2, start; + char *s, *t1, *t2, *tail; + + s = ds; + start = p[0]; + tail = p+1; + if (start) while (TRUE) + {while ((c2 = *s++) != start) + if (c2==0) return (-1); + t1 = tail; + t2 = s; + while ((c1 = *t1++) == (c2 = *t2++)) + if (c1==0) break; + if (c1==0) break; + } + return (s-ds-1); + } + +# ifdef test + +int main () + + {char buf1[100], buf2[100]; + + while (TRUE) + {cprint ("Pattern: "); + gets (buf1); + cprint ("Data: "); + gets (buf2); + if (smatch (buf1, buf2)) + cprint ("Matched.\n"); + else cprint ("No match.\n"); + } + } + +# endif + \ No newline at end of file diff --git a/arc/ar2:clib/MKCLIB STINKR b/arc/ar2:clib/MKCLIB STINKR new file mode 100644 index 00000000..e2ad3d5e --- /dev/null +++ b/arc/ar2:clib/MKCLIB STINKR @@ -0,0 +1,29 @@ +; Stinkr xfile for loading basic C library in preparation for construction +; of the shared library. + +; note -- it is proper for ZMAIN to be undefined +; note -- it is proper for DATE to have 3 TOPS-20-related names undefined + +; The last two addresses in the 's' command must be set so that nothing +; overlaps and there is no wraparound. You also have to leave some room +; at the end for consing done during loading. + +; The best procedure is to first use 'p' for the last two numbers, which +; tells Stinkr to allocate from the next page boundary. Then run Stinkr +; to find out how big the segments are. Then you can change the starting +; addresses to push the last to segments as close to the end as possible. +; You should leave about 400 octal words for cons space; if you have not +; left enough, stinker will die saying LBINIT failed. + +; If the library has gotten bigger (more pages), the program C10SAV must +; be changed accordingly. + +; C10SRY should not be here; you want to run it before the library is mapped +; in. +; C10SAV should not be here; it maps out the library as it runs. + +s 100,n,755400,774000 +i lbinit +o ts clib + +x c;clib prglst diff --git a/arc/ar2:clib/NC INSERT b/arc/ar2:clib/NC INSERT new file mode 100644 index 0000000000000000000000000000000000000000..3a8b38ffb74f4c290e21bb5a2f8d12d9ccb48056 GIT binary patch literal 780 zcmZuvO^@3k5bf2L_z!c5dML3r>2CL6alkNkXfUvVcN;}f|Np<};Ey!w)|Y|d&6_uG z+=6PI0^<_K%xYG*kWVH-Z!7{uhp16Q_8?Qjv7_v0v`i49AEF%RgPs&&y310Hpg{RC z5JRLY_&{q*JV~eb$``tSC^RNBIMj2!hYrDdS#TdFpNMViRrE!)Udb#;39B2@9W$g$ zLN~PIWD^eeS(>rjj!)(L%73i!b%}+_^ap+=lF?d|g*cR)ETI!eRx9zH)ml8W8pR8% zgE+i21XfB~D-OSpuXG!{_!-me8@^4_rV3q-m#P`8@1&*DHTx@Lbbr%CjJRm@IVsxvJ{osAoy_YvM@G{swp z*keSeFcmesAOy)6I|tu)zy3qoMxyBXcxYb%4+L!FYsZ*)9Deu{||ij7##13 zX)%1gEFJb_(7gkzZ!J0vw9I9vM}9Ru^@Tpo>#drzp&xK3`HuSXjw`M?^1uhr7jj~| I(I{X307THMng9R* literal 0 HcmV?d00001 diff --git a/arc/ar2:clib/NM INSERT b/arc/ar2:clib/NM INSERT new file mode 100644 index 00000000..f6e2ab30 --- /dev/null +++ b/arc/ar2:clib/NM INSERT @@ -0,0 +1,164 @@ +.INSRT C;CODE INSERT + +.OFNM2=SIXBIT/STK/ + +CL=PUSHJ P, +RTN=POPJ P, + +.VCALL=2_33 +.ACALL=3_33 +.XCALL=4_33 + +DEFINE SYSCAL NAME,ARGS,DUMMY,LABEL + SETZ A, + .CALL [SETZ + .1STWD SIXBIT /NAME/ + ARGS + 403000,,A + ] + IFSN [LABEL][]GO LABEL + IFSE [LABEL][]MOVN A,A + TERMIN + +DEFINE INFORM A,B +IF1,[PRINTX \ A = B +\] +TERMIN + +; SUPPORT ROUTINES + +DEFINE %LEN [LIST] +%COUNT==0 +IRP ELEM,,LIST + %COUNT==%COUNT+1 + TERMIN +TERMIN + +DEFINE DEFVAR NAME,#OFFSET + DEFINE NAME +&262143.(P)TERMIN +TERMIN + +; DEFINE C-CALLABLE PROCEDURE (C NAME) + +DEFINE CENTRY NAME,[ARGS],[VARS] + PROLOG Z!NAME,NAME,ARGS,VARS + TERMIN + +; DEFINE C-CALLABLE PROCEDURE (MIDAS NAME) + +DEFINE MENTRY NAME,[ARGS],[VARS] + PROLOG NAME,NAME,ARGS,VARS + TERMIN + +; DEFINE MIDAS ENTRY POINT (NOT PROCEDURE) + +DEFINE IENTRY NAME +NAME": TERMIN + +; PROLOG MACRO + +DEFINE PROLOG MNAME,PNAME,[ARGS],[VARS] + %LEN ARGS + %A==%COUNT + %LEN VARS + %V==%COUNT + %OFF== -<%A+%V> + IRP ARGNAM,,ARGS + DEFVAR ARGNAM,%OFF + %OFF==%OFF+1 + TERMIN + %OFF==%OFF+1 + IRP VARNAM,,VARS + DEFVAR VARNAM,%OFF + %OFF==%OFF+1 + TERMIN + %A,,[ASCIZ/PNAME/] +MNAME": IFN %V,[ADDI P,%V] + TERMIN + +; DEFINE SYNONYM FOR C-CALLABLE ENTRY POINT + +DEFINE XENTRY NEWNAME,OLDNAME +Z!NEWNAME"=Z!OLDNAME" +TERMIN + +; DEFINE MIDAS-ACCESSIBLE DATA + +DEFINE MDATA NAME +NAME":TERMIN + +; FATAL ERROR + +DEFINE CROAK STRING/ +.VALUE [ASCIZ \ +: STRING  +\] +TERMIN + +; RETURN STATEMENT + +DEFINE RETURN + IFE %A,[ + IFN %V,[SUBI P,%V] + POPJ P, + ] + IFN %A,[ + SUBI P,%V+%A+1 + JRST @<%A+1>(P) + ] + TERMIN + +; CALL STATEMENT + +DEFINE CALL NAME,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + ICALL NN,NAME + TERMIN + +; MIDAS-CALL STATEMENT + +DEFINE MCALL NAME,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + CCALL NN,NAME" + TERMIN + +; VARIABLE-CALL STATEMENT + +DEFINE VCALL F,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + CCALL NN,F + TERMIN + +; INTERNAL CALL + +DEFINE ICALL N,NAME + CCALL N,Z!NAME" + TERMIN + +; HACK FOR CONSTANTS + +EQUALS NM%EN END +EXPUNGE END +DEFINE END ENDLOC + .CODE + INSCODE + .PDATA + CONSTANTS + NM%EN ENDLOC + TERMIN + +.CODE + \ No newline at end of file diff --git a/arc/ar2:clib/PR60TH C b/arc/ar2:clib/PR60TH C new file mode 100644 index 00000000..2e9f453a --- /dev/null +++ b/arc/ar2:clib/PR60TH C @@ -0,0 +1,56 @@ +# include "c.defs" + +/********************************************************************** + + PR60TH - Print time in 1/60 sec. + + Print time HH:MM:SS.XX on file FILE. + TIME is in units of 1/60 sec. + +**********************************************************************/ + +pr60th (time, file) + + {int ss, sc, mn, hour, zs; + + if (time < 0) time = -time; + zs = TRUE; + ss = time%60; + time = time/60; + sc = time%60; + time = time/60; + mn = time%60; + hour = time/60; + if (hour) + {cprint (file, "%3d:", hour); + zs = FALSE; + } + else cprint (file, " "); + xput2 (mn, file, zs); + if (zs && mn==0) cputc (' ', file); + else + {cputc (':', file); + zs = FALSE; + } + if (zs && !sc) + {cputc (' ', file); + cputc ('0', file); + } + else + {xput2 (sc, file, zs); + zs = FALSE; + } + cputc ('.', file); + xput2 (ss, file, FALSE); + } + +xput2 (val, file, zs) + + {int num; + num = val/10; + if (num>0 || !zs) {cputc ('0'+num, file); zs=FALSE;} + else cputc (' ', file); + num = val%10; + if (num>0 || !zs) cputc ('0'+num, file); + else cputc (' ', file); + } diff --git a/arc/ar2:clib/RANDOM CMID b/arc/ar2:clib/RANDOM CMID new file mode 100644 index 00000000..89813a85 --- /dev/null +++ b/arc/ar2:clib/RANDOM CMID @@ -0,0 +1,31 @@ +; +; RANDOM - RANDOM NUMBER GENERATOR (STOLEN FROM MUDDLE) +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE RANDOM +.INSRT NC +.INSRT NM + +CENTRY SRAND,[SEED] + MOVE A,SEED + ROT A,-1 + MOVEM A,RLOW + RETURN + +CENTRY RAND + MOVE A,RHI + MOVE B,RLOW + MOVEM A,RLOW ;Update Low seed + LSHC A,-1 ;Shift both right one bit + XORB B,RHI ;Generate output and update High seed + MOVE A,B + RETURN + +.IDATA +RHI: 267762113337 +RLOW: 155256071112 +.PDATA + +END diff --git a/arc/ar2:clib/STDIO H b/arc/ar2:clib/STDIO H new file mode 100644 index 00000000..25bd9ca3 --- /dev/null +++ b/arc/ar2:clib/STDIO H @@ -0,0 +1,17 @@ +# define BUFSIZ 512 +# define FILE int +# define NULL 0 +# define EOF (-1) + +# define peekchar pkchar /* avoid name conflict */ +# define fopen flopen /* " */ +# define getc fgetc /* " */ +# define getchar fgeth /* " */ + +# define feof ceof /* direct translation */ +# define putc cputc /* " */ + +extern FILE *stdin, *stdout, *stderr; + +# define ITS ITS + \ No newline at end of file diff --git a/arc/ar2:clib/STKDMP C b/arc/ar2:clib/STKDMP C new file mode 100644 index 00000000..48b390d0 --- /dev/null +++ b/arc/ar2:clib/STKDMP C @@ -0,0 +1,249 @@ +# include "c.defs" + +/********************************************************************** + + STKDMP - C Stack Dumping Routine + + This file is PDP-10 dependent, but essentially system + independent. + +**********************************************************************/ + +# rename findproc "FINDPR" +# rename findframe "FINDFR" +# rename print_name "PRNAME" +# rename callok "CALLOK" + +# rename hack "STKDMP" +# rename seg2lo "SEG2LO" +# rename seg2hi "SEG2HI" +# rename seg3lo "SEG3LO" +# rename seg3hi "SEG3HI" +# rename pdlbot "PDLBOT" +# rename pdltop "PDLTOP" +# rename purbot "PURBOT" +# rename purtop "PURTOP" +# rename intptr "INTPTR" +# rename mpvh "MPVH" +# rename etsint "ETSINT" +# rename uuoh "UUOH" +# rename uuohan "UUO$HA" +# rename euuoh "EUUOH" +# rename caller "CALLER" + +# define ADDI_P 0271740 +# define SUBI_P 0275740 +# define GO_P 0254037 +# define JSP_D 0265200 +# define GO 0254000 + +# define left(x) (((x) >> 18) & 0777777) +# define right(x) ((x) & 0777777) + +extern int *seg2lo, *seg2hi, *seg3lo, *seg3hi, + *pdlbot, *pdltop, *purbot, *purtop, *caller, + mpvh[], etsint[], intptr, uuoh[], uuohan[], euuoh[], + cout, *findframe(), *findproc(), hack[]; + +/********************************************************************** + + STKDMP - Dump stack. + +**********************************************************************/ + +static int tuuoh; + +stkdmp (fd) + + {int *pc; /* procedure pointer */ + int *opc; /* previously printed-out pc */ + int *sp; /* stack pointer */ + + if (!cisfd(fd)) fd = cout; + cputc ('\n', fd); + tuuoh = uuoh[0]; + sp = &fd; /* arg is on the stack */ + pc = right(sp[1]); /* my caller's pc is on the stack */ + opc = -1; + --sp; /* top of stack when he was running */ + if (pc >= hack && pc <= hack+12) /* PUSHJ P,STKDMP$X */ + {pc = right(sp[0]); /* 'real' caller */ + sp =- 7; /* 'real' stack top */ + } + while (TRUE) + {int *proc, nargs, *npc, *namep, *ap; + proc = findproc (pc); + if (proc == 0) break; + nargs = left(proc[-1]); + namep = right(proc[-1]); + sp = findframe (sp, proc, pc); + if (sp == 0) + {if (opc != caller) + {cprint (fd, " "); + print_name (namep, fd); + cprint (fd, "\n"); + } + break; + } + npc = right(sp[0]); + sp =- nargs; + ap = sp; + --sp; + cprint (fd, "%7o ", sp); + print_name (namep, fd); + cprint (fd, " ("); + if (nargs>10) nargs = 10; + while (--nargs >= 0) + {cprint (fd, "%o", *ap++); + if (nargs) cprint (fd, ", "); + } + cprint (fd, ")\n"); + opc = proc; + pc = npc; + } + } + +/********************************************************************** + + FINDPROC - Find beginning of active procedure, given a PC. + +**********************************************************************/ + +int *findproc (pc) int *pc; + + {int *low, *high, n; + + n = 3; + while (--n>=0) + {if (pc >= mpvh && pc < etsint) + {int *p; + p = right(intptr); + pc = right(p[-4]); + continue; + } + if (pc == uuoh+1 || (pc >= uuohan && pc < euuoh)) + {pc = right(tuuoh); + if ((pc[0]>>29)==0) ++pc; /* hack */ + continue; + } + } + if (pc > seg2lo && pc <= seg2hi) + {low = seg2lo; + high = seg2hi; + } + else if (pc > purbot && pc <= purtop) + {low = purbot; + high = purtop; + } + else return (0); + + ++pc; + while (--pc > low) + {int data, c, nargs, *namep; + if ((*pc >> 27) == 0) continue; + data = pc[-1]; + nargs = left(data); + namep = right(data); + if (nargs >= 16) continue; + if (namep < seg3lo || namep > seg3hi) continue; + c = (*namep >> 29); /* left byte */ + if (c < ' ' || c > 'z') continue; + return (pc); + } + return (0); + } + +/********************************************************************** + + FINDFRAME - Find stack frame, given stack top and procedure + pointer, and PC within procedure. Returns pointer + to return address on stack. + +**********************************************************************/ + +int *findframe (sp, proc, pc) int *sp, *proc, *pc; + + {int instr, signal(); + + instr = proc[0]; + if (left(instr) == ADDI_P) /* procedure allocates a frame */ + {int bump; + bump = right(instr); /* local frame size */ + if (pc == proc); /* hasn't allocated it yet */ + else if (left(pc[0]) == GO_P); /* has popped it */ + else sp =- bump; + } + if (pc >= mpvh && pc < etsint) /* was in interrupt handler */ + sp =- 17; /* ignore stuff pushed by handler */ + /* !!! the above is wrong !!! */ + + ++sp; + while (--sp >= pdlbot) + {int data, *opc; + data = *sp; + + /* look for return address word on stack */ + /* check for reasonable status bits */ + if (!(data & 0010000000000)) continue; + /* must be in user mode */ + if (data & 0027637000000) continue; /* bad for status bits */ + + /* check for reasonable old PC (within code segment) */ + opc = right(data) - 1; + if (opc < seg2lo) continue; + if (opc > seg2hi) continue; + + /* check to see if old PC was call to current proc */ + if (callok (opc, proc)) + {if (proc == signal && opc>=mpvh && opc='A' && c<='Z' ? c+('a'-'A') : c, fd); + } + \ No newline at end of file diff --git a/arc/ar2:clib/STRING CMID b/arc/ar2:clib/STRING CMID new file mode 100644 index 00000000..3d6b68d3 --- /dev/null +++ b/arc/ar2:clib/STRING CMID @@ -0,0 +1,132 @@ +; +; STRING - C STRING, BYTE, AND BIT ROUTINES +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE STRING +.INSRT NC +.INSRT NM + +; CONTAINS: + +; SLEN ; STRING LENGTH +; STCPY ; STRING COPY +; STCMP ; STRING COMPARE +; LOWER ; CVT CHAR TO LOWER CASE +; UPPER ; CVT CHAR TO UPPER CASE + +; BGET ; BIT ARRAY BIT GET +; BSET ; BIT ARRAY BIT SET + +; ILDB ; INCREMENT AND LOAD BYTE +; IDPB ; INCREMENT AND DEPOSIT BYTE + +CENTRY SLEN,[STR] ; STRING LENGTH + + MOVE B,STR ; POINTER TO STRING + SETZ A, ; COUNTER +SL$1: MOVE C,(B) ; GET NEXT CHARACTER + SKIPN C + GO SL$RET ; RETURN ON NULL CHAR + ADDI A,1 ; INCR COUNTER + ADDI B,1 ; INCR POINTER + GO SL$1 +SL$RET: RETURN + +CENTRY STCPY,[SRC,DEST] ; STRING COPY + + ; COPY STRING FROM SRC TO DEST + ; RETURN POINTER TO NULL TERMINATING NEW COPY + + MOVE B,SRC ; SOURCE POINTER + MOVE A,DEST ; DESTINATION POINTER +SC$1: MOVE C,(B) ; GET NEXT CHAR + MOVEM C,(A) ; STORE + SKIPN C + GO SC$RET ; RETURN AFTER WRITING NULL CHAR + ADDI B,1 ; INCR SOURCE PTR + ADDI A,1 ; INCR DESTINATION PTR + GO SC$1 +SC$RET: RETURN + +CENTRY STCMP,[S1,S2] ; STRING COMPARE + + MOVE B,S1 + MOVE C,S2 +SM$1: MOVE A,(B) ; GET NEXT CHAR + CAME A,(C) + GO SM$2 ; DIFFERENCE FOUND + ADDI B,1 ; INCR PTR1 + ADDI C,1 ; INCR PTR2 + JUMPN A,SM$1 + SETO A, + GO SM$RET +SM$2: SETZ A, +SM$RET: RETURN + +CENTRY LOWER,[CH] ; CVT CHAR TO LOWER CASE + + MOVE A,CH + CAIGE A,"A + GO LW$RET + CAILE A,"Z + GO LW$RET + ADDI A,"a-"A +LW$RET: RETURN + +CENTRY UPPER,[CH] ; CVT CHAR TO UPPER CASE + + MOVE A,CH + CAIGE A,"a + GO UP$RET + CAILE A,"z + GO UP$RET + SUBI A,"a-"A +UP$RET: RETURN + +CENTRY BGET,[BARRAY,BINDEX] ; BIT ARRAY BIT GET + + HRRZ C,BINDEX + HRRZ A,BARRAY + MOVEI B,(C) ; SUBSCRIPT + + LSH C,-5 ; GET WORD OFFSET + ADDI A,(C) ; GET WORD ADDRESS + MOVE A,(A) ; GET THE WORD + ANDI B,37 ; BIT OFFSET + ROT A,1(B) ; PUT BIT IN RIGHT-MOST POSITION + ANDI A,1 ; GET THE BIT + RETURN + +CENTRY BSET,[BARRAY,BINDEX] ; BIT ARRAY BIT SET + + HRRZ C,BINDEX + HRRZ A,BARRAY + MOVEI B,(C) ; SUBSCRIPT + + LSH C,-5 ; GET WORD OFFSET + ADDI A,(C) ; GET WORD ADDRESS + ANDI B,37 ; BIT OFFSET + MOVN B,B ; NEGATIVE BIT OFFSET + MOVEI C,1 ; A BIT + ROT C,-1(B) ; PUT IN RIGHT POSITION + IORM C,(A) ; SMASH ARRAY WORD + MOVEI A,1 + RETURN + +CENTRY ILDB,[ABPTR] ; INCREMENT AND LOAD BYTE + + HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER + ILDB A,(A) + RETURN + +CENTRY IDPB,[CH,ABPTR] ; INCREMENT AND DEPOSIT BYTE + + MOVE B,CH ; THE CHARACTER + HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER + IDPB B,(A) + RETURN + +END + \ No newline at end of file diff --git a/arc/ar2:clib/TESTFD C b/arc/ar2:clib/TESTFD C new file mode 100644 index 00000000..1e000dfd --- /dev/null +++ b/arc/ar2:clib/TESTFD C @@ -0,0 +1,19 @@ +/********************************************************************** + + TSTFD + Test routine for FD + +**********************************************************************/ + +main () + + {char buf[200]; + extern int puts (); + for (;;) + {cprint ("Enter pattern: "); + gets (buf); + fdmap (buf, puts); + puts (""); + } + } + \ No newline at end of file diff --git a/arc/ar2:clib/TTIME C b/arc/ar2:clib/TTIME C new file mode 100644 index 00000000..0a9c7636 --- /dev/null +++ b/arc/ar2:clib/TTIME C @@ -0,0 +1,123 @@ +/********************************************************************** + + TTIME - Test program for Timing + +**********************************************************************/ + +# rename timing "TIMING" +extern int timing; + +main () + + {int i; + i = 10000; + if (timing) i = 1000; + while (--i >= 0) foo (); + } + +foo () /* calls null 100 times */ + + { + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + } + +null () {;} diff --git a/arc/ar2:clib/UUOH CMID b/arc/ar2:clib/UUOH CMID new file mode 100644 index 00000000..acd572f9 --- /dev/null +++ b/arc/ar2:clib/UUOH CMID @@ -0,0 +1,157 @@ +; +; UUOH - C UUO Handler +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE UUOH +.INSRT NC +.INSRT NM + +; +; UUO DISPATCH TABLE +; + +.PDATA +IENTRY UUOTAB + ILLUUO + UCCALL ;.CCALL - FIRST TIME CALL + UVCALL ;.VCALL - CALL OF VARIABLE PROC + UACALL ;.ACALL - CALL NEEDING ADDITIONAL ARGS + UXCALL ;.XCALL - CALL WITH EXTRA ARGS +REPEAT UUOTAB+40-.,[ILLUUO?] + +; +; BASIC UUO DISPATCHER +; + +.IDATA +MDATA UUOH + 0 + GO UUO$HANDLER +MDATA SMASH + -1 +.UDATA +MDATA USAVEA + BLOCK 1 +MDATA USAVEB + BLOCK 2 +MDATA USAVEC + BLOCK 3 +MDATA USAVED + BLOCK 4 +.CODE + +IENTRY UUO$HANDLER + + MOVEM D,USAVED + LDB D,[330500,,40] ; GET UUO CODE + GO @UUOTAB(D) ; DISPATCH BASED ON THE UUO + +URETA: MOVE A,USAVEA +URETB: MOVE B,USAVEB +URETC: MOVE C,USAVEC +URETD: MOVE D,USAVED + GO @UUOH + +; +; ILLEGAL UUO HANDLER +; + +IENTRY ILLUUO + + CROAK ILLEGAL UUO + GO URETD + +; +; .CCALL HANDLER +; + +IENTRY UCCALL + + MOVEM B,USAVEB ; MUST NOT CHANGE ANY REGS + MOVEM C,USAVEC ; AS CALL MIGHT BE THRU A REG + HRRZ C,40 ; THE CALLED PROCEDURE + JUMPE C,UCBAD ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO UCBAD ; NO, NOT A PROCEDURE + SKIPN SMASH ; SHOULD I SMASH THE CALL + GO UC$GO ; NO, LEAVE IT + SOS D,UUOH ; ADDRESS OF THE CALL + MOVE B,(D) ; THE .CCALL INSTRUCTION + TLZ B,777740 ; ZERO OUT ALL BUT ADDRESS PART + CAIE B,(C) ; IS IT A CONSTANT CALL? + GO UCV ; NO, CHANGE IT INTO A .VCALL + LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + SUB B,0 ; THE NUMBER OF EXTRA ACTUALS + JUMPL B,UCA ; TOO FEW ACTUALS + JUMPG B,UCX ; TOO MANY ACTUALS + MOVEI B,(PUSHJ P,) + HRLM B,(D) ; SMASH .CCALL TO PUSHJ + GO URETB ; RE-EXECUTE CALL + +UCA: MOVN B,B ; THE NUMBER OF EXTRA ARGS NEEDED + LSH B,5 ; SHIFT INTO ACCUMULATOR POSITION + IORI B,(.ACALL) + HRLM B,(D) ; SMASH .CCALL TO .ACALL + GO URETB ; RE-EXECUTE CALL +UCX: LSH B,5 ; SHIFT INTO ACCUMULATOR POSITION + IORI B,(.XCALL) + HRLM B,(D) ; SMASH .CCALL TO .ACALL + GO URETB ; RE-EXECUTE CALL +UCV: MOVE B,(D) ; THE ORIGINAL CALL + TLZ B,777000 ; MASK OUT OPCODE + TLO B,(.VCALL) ; MAKE IT A .VCALL + MOVEM B,(D) ; SMASH CALL + GO URETB ; RE-EXECUTE CALL + +IENTRY UCBAD + LDB B,[270400,,0] ; THE NUMBER OF ACTUAL ARGS +UVBAD: MOVEM B,USAVEA ; SAVE NUMBER OF ACTUAL ARGS + SETZ A, ; SET DEFAULT RETURN VALUE + MOVE D,UUOH + SUBI D,1 ; LET USER LOOK AT CALL + CROAK CALL OF UNDEFINED PROCEDURE + SUB P,USAVEA ; POP OFF ARGS + GO URETB ; RETURN TO CALLER + +IENTRY UVCALL + + HRRZ C,40 ; THE CALLED PROCEDURE + JUMPE C,UVBAD ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO UVBAD ; NO, NOT A PROCEDURE +UC$GO: LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS + SUB 0,B ; NUMBER OF ARGS NOT GIVEN + JUMPL 0,UVHACK ; TOO MANY ARGS GIVEN +UVLOOP: SOJL 0,UVDOIT ; FOR EACH ARG NEEDED + PUSH P,[0] ; PUSH ZERO ARG + GO UVLOOP ; LOOP + +UVHACK: ; TOO MANY ARGS GIVEN + ADD P,0 ; POP OFF EXTRA ARGS +UVDOIT: PUSH P,UUOH ; PUSH RETURN ADDRESS + GO (C) ; EXECUTE PROCEDURE + +IENTRY UACALL + + LDB B,[270400,,40] ; THE NUMBER OF EXTRA ARGS NEEDED + HRRZ C,40 ; THE CALLED PROCEDURE +UALOOP: SOJL B,UVDOIT ; FOR EACH ARG NEEDED + PUSH P,[0] ; PUSH ZERO ARG + GO UALOOP ; LOOP + +IENTRY UXCALL + + LDB B,[270400,,40] ; THE NUMBER OF EXTRA ARGS + HRRZ C,40 ; THE CALLED PROCEDURE + SUBI P,(B) ; POP OFF EXTRA ARGS + PUSH P,UUOH ; PUSH RETURN ADDRESS + GO (C) ; EXECUTE PROCEDURE + +IENTRY EUUOH +END + \ No newline at end of file diff --git a/arc/ar5:c/AC C b/arc/ar5:c/AC C new file mode 100644 index 00000000..49c6e50f --- /dev/null +++ b/arc/ar5:c/AC C @@ -0,0 +1,281 @@ +# +/* + + AC - Array of Characters Cluster + + operations: + + ac_new () => ac create empty array + ac_alloc (size) => ac create empty array, preferred size + ac_create (string) => ac create with initial value + ac_xh (ac, c) => c extend array with character + ac_trim (ac) => ac trim excess storage + ac_fetch (ac, i) => c fetch character from array + ac_link (ac) => ac make new link to array + ac_unlink (ac) remove link to array + ac_puts (ac, f) print array + ac_cat (ac, ac) => ac concatenate arrays + ac_copy (ac) => ac copy array + ac_string (ac) => *char return string version + ac_size (ac) => size return current size of array + ac_flush (ac) make array empty + ac_n () => int return # of active arrays + +*/ + +struct rep { + int count; /* reference count */ + char *s; /* pointer to actual array */ + int csize; /* logical size of array */ + int msize; /* physical size of array (at least csize+1) */ + }; + +# define ac struct rep* /* watch usage! */ +# define ASIZE 4 /* number of words in rep */ +# define initial_size 8 /* default initial allocation */ + +char *calloc (); +int *salloc (); +ac ac_new(); +ac ac_alloc(); +ac ac_create(); +ac ac_link(); +ac ac_cat(); +ac ac_copy(); + +static int count; + +/********************************************************************** + + AC_NEW - Create empty array. + AC_ALLOC - Create empty array, preferred size given. + +**********************************************************************/ + +ac ac_new () + + {return (ac_alloc (initial_size));} + +ac ac_alloc (sz) + + {ac a; + + if (sz<0) sz=0; + a = salloc (ASIZE); + a->count = 1; + a->csize = 0; + a->msize = sz+1; + a->s = calloc (a->msize); + ++count; + return (a); + } + +/********************************************************************** + + AC_CREATE - Create array with initial value. + +**********************************************************************/ + +ac ac_create (s) char s[]; + + {register char *p; + register int sz; + register ac a; + + sz = slen (s); + a = ac_alloc (sz); + a->csize = sz; + p = a->s; + while (--sz >= 0) *p++ = *s++; + return (a); + } + +/********************************************************************** + + AC_XH - Extend Array with Character. + +**********************************************************************/ + +char ac_xh (a, c) register ac a; + + {register char *p, *q; + char *old; + int i; + + if ((i = a->csize) >= a->msize-1) + {old = p = a->s; + a->s = q = calloc (a->msize =* 2); + while (--i >= 0) *q++ = *p++; + if (old) cfree (old); + } + a->s[a->csize++] = c; + return (c); + } + +/********************************************************************** + + AC_TRIM - Discard excess storage. + +**********************************************************************/ + +ac ac_trim (a) register ac a; + + {register char *p, *q; + char *old; + int i; + + if ((i = a->csize) < a->msize-1) + {old = p = a->s; + a->s = q = calloc (a->msize = a->csize + 1); + while (--i >= 0) *q++ = *p++; + if (old) cfree (old); + } + return (a); + } + +/********************************************************************** + + AC_FETCH - Fetch Character from Array. + +**********************************************************************/ + +char ac_fetch (a, n) ac a; + + {extern int cerr; + if (n<0 || n>=a->csize) + {cprint (cerr, "Character array bounds error."); + return (0); + } + return (a->s[n]); + } + +/********************************************************************** + + AC_LINK - Create link to array. + +**********************************************************************/ + +ac ac_link (a) ac a; + + {++a->count; + return (a); + } + +/********************************************************************** + + AC_UNLINK - Remove link to array. + +**********************************************************************/ + +ac_unlink (a) ac a; + + {if (--a->count == 0) + {if (a->s) cfree (a->s); + --count; + sfree (a); + } + } + +/********************************************************************** + + AC_PUTS - Print array. + +**********************************************************************/ + +ac_puts (a, f, wid) ac a; /* 3 args for cprint usage */ + + {register char *p; + register int i; + + p = a->s; + i = a->csize; + while (--i >= 0) cputc (*p++, f); + } + +/********************************************************************** + + AC_CAT - Concatenate arrays. + +**********************************************************************/ + +ac ac_cat (a1, a2) ac a1; ac a2; + + {register ac a; + register char *p, *q; + int i; + + a = ac_alloc (i = a1->csize + a2->csize); + a->csize = i; + p = a->s; + q = a1->s; + i = a1->csize; + while (--i>=0) *p++ = *q++; + q = a2->s; + i = a2->csize; + while (--i>=0) *p++ = *q++; + return (a); + } + +/********************************************************************** + + AC_COPY - Copy array. + +**********************************************************************/ + +ac ac_copy (a1) ac a1; + + {register ac a; + register char *p, *q; + int i; + + a = ac_alloc (i = a1->csize); + a->csize = i; + p = a->s; + q = a1->s; + while (--i >= 0) *p++ = *q++; + return (a); + } + +/********************************************************************** + + AC_STRING - Return string version of array. The returned + string is valid only while the array remains linked + to and unchanged. + +**********************************************************************/ + +char *ac_string (a) ac a; + + {a->s[a->csize]=0; + return (a->s); + } + +/********************************************************************** + + AC_SIZE - Return current size of array. + +**********************************************************************/ + +int ac_size (a) ac a; + + {return (a->csize);} + +/********************************************************************** + + AC_FLUSH - Make array empty + +**********************************************************************/ + +ac_flush (a) ac a; + + {a->csize = 0;} + +/********************************************************************** + + AC_N - Return number of active arrays. + +**********************************************************************/ + +int ac_n () {return (count);} + + \ No newline at end of file diff --git a/arc/ar5:c/ALLOC CMID b/arc/ar5:c/ALLOC CMID new file mode 100644 index 00000000..5c2f7d7f --- /dev/null +++ b/arc/ar5:c/ALLOC CMID @@ -0,0 +1,225 @@ +; +; ALLOC - C FREE STORAGE ROUTINES +; +; This file is PDP-10 dependent, system independent. +; +; CALLOC (SIZE) => *CHAR ; ALLOCATE ZEROED CHARACTERS +; SALLOC (SIZE) => *INT ; ALLOCATE ZEROED WORDS +; CFREE (*CHAR) ; RETURN CHARACTERS +; SFREE (*INT) ; RETURN WORDS +; +; AFREE (SIZE) => (ADDR) ; ALLOCATE GARBAGE WORDS +; AFRET (ADDR, SIZE) ; DEALLOCATE WORDS +; AFREZ (SIZE) => (ADDR) ; ALLOCATE AND ZERO WORDS +; +; ALOCSTAT (&NWALLOC, &NBFREE) => NWFREE ; COMPUTE STATS +; + +TITLE ALLOC +.INSRT NC +.INSRT NM + + +; THESE ARE STORAGE-ALLOCATION ROUTINES WITH SOME PROTECTION + +CENTRY CALLOC,[NWORDS] ; ALLOCATE CHARACTERS +XENTRY SALLOC,CALLOC ; ALLOCATE WORDS + + SKIPL A,NWORDS ; DON'T ADD TO BAD SIZE + ADDI A,2 ; FOR HEADER WORDS + CALL AFREZ,[A] + ADDI A,2 ; POINTER TO USER AREA OF BLOCK + MOVE B,NWORDS + MOVEM B,-1(A) ; STORE SIZE IN HEADER + MOVE B,A + ADD B,[147506732514] + MOVEM B,-2(A) ; MAGIC WORD IN HEADER + RETURN + +CENTRY CFREE,[PTR] ; RETURN CHARACTERS +XENTRY SFREE,CFREE ; RETURN WORDS + + MOVE A,PTR + MOVE B,-2(A) + SUB B,A + CAME B,[147506732514] + GO CF$BAD + MOVEI A,-2(A) + MOVE B,1(A) + ADDI B,2 + CALL AFRET,[A,B] + SETZ A, +CF$RET: RETURN +CF$BAD: CROAK BAD CALL TO CFREE/SFREE + SETO A, + GO CF$RET + + +.IDATA +MDATA FNWORDS ; NUMBER OF WORDS ALLOCATED + 0 +MDATA FLIST + FLIST+1 ; LIST OF FREE BLOCKS + 0 +.CODE +; +; AFREE - ALLOCATE STORAGE +; + +CENTRY AFREE,[BSIZE] +XENTRY GETVEC,AFREE + + MOVE A,BSIZE + JUMPLE A,AE$BAD ; SIZE MUST BE POSITIVE + CAIL A,400000 ; SIZE MUST BE REASONABLE + GO AE$BAD + HRLZI D,(A) ; SIZE IN LEFT HALF FOR COMPARISON + MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B + HRRZ C,(B) ; CURRENT BLOCK ADDR IN C +A1: CAMG D,(C) ; IS CURRENT BLOCK BIG ENOUGH? + GO A3 ; YES + MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN C,A1 ; BLOCK EXISTS => LOOP + HLRZ B,D ; DESIRED SIZE IN B + PPUSH B ; SAVE SIZE NEEDED + CALL GETCORE,[B] ; ALLOCATE NEW BLOCK (SIZE,,ADDR) + HLRZ B,A ; SIZE OBTAINED + HRRZ A,A ; ADDRESS OF BLOCK + PPOP D ; SIZE NEEDED + SUBI B,(D) ; HOW MUCH EXTRA OBTAINED? + JUMPE B,AE$RET ; NO EXCESS => DONE + PPUSH A ; ADDRESS OF BLOCK + ADDM B,(P) ; ADDRESS OF DESIRED PART OF BLOCK + CALL AFRET,[A,B] ; RETURN THE EXCESS + PPOP A ; ADDRESS OF DESIRED PART OF BLOCK + GO AE$RET ; DONE + +; HERE WHEN A SUFFICIENTLY LARGE BLOCK FOUND IN LIST + +A3: HLRZ D,D ; DESIRED SIZE IN D + HLRZ A,(C) ; SIZE OF BLOCK IN LIST + SUBI A,(D) ; EXCESS + JUMPE A,A4 ; NO EXCESS => DELETE BLOCK FROM LIST + HRLM A,(C) ; NEW BLOCK SIZE + ADDI A,(C) ; ADDRESS OF DESIRED PART OF BLOCK + GO AE$RET ; DONE + +; HERE WHEN ENTIRE BLOCK IS TO BE REMOVED FROM THE LIST + +A4: HRRZ A,(C) ; NEXT BLOCK IN LIST + HRRM A,(B) ; CHAIN TO PREVIOUS BLOCK + MOVEI A,(C) ; RETURN THIS BLOCK + GO AE$RET ; DONE + +AE$BAD: CROAK AFREE CALLED WITH BAD SIZE ARGUMENT + SETZ A, +AE$RET: RETURN ; DONE + +; +; AFRET - DEALLOCATE STORAGE +; + +CENTRY AFRET,[PTR,BSIZE] + + MOVE A,PTR + MOVE B,BSIZE + JUMPLE B,CODE [ ; SIZE MUST BE POSITIVE + CROAK AFRET CALLED WITH BAD SIZE ARGUMENT + GO ARRET + ] + MOVEI C,FLIST ; ADDRESS OF PREVIOUS BLOCK IN C + HRRZ D,(C) ; ADDRESS OF CURRENT BLOCK IN D +A5: CAIG A,(D) ; FIND PLACE IN LIST + GO A8 ; NEW BLOCK GOES HERE + MOVEI C,(D) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ D,(D) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN D,A5 ; BLOCK EXISTS => LOOP + +; HERE TO INSERT NEW BLOCK AFTER A GIVEN BLOCK IN LIST + +A6: HLRZ D,(C) ; SIZE OF OLD BLOCK + ADDI D,(C) ; END OF OLD BLOCK + CAIGE A,(D) ; OVERLAP WITH PREVIOUS BLOCK ? + GO CODE [ ; YES, ERROR + CROAK AFRET CALLED WITH BAD ADDRESS + GO ARRET + ] + CAIN A,(D) ; CONTIGUOUS WITH PREVIOUS BLOCK ? + GO A7 ; YES, GO MERGE THEM + HRRZ D,(C) ; ADDRESS OF NEXT BLOCK (IF ANY) + HRLI D,(B) ; SIZE OF BLOCK BEING FREED (IN LEFT HALF) + MOVEM D,(A) ; MAKE DOPE WORD OF BLOCK BEING FREED + HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK + GO ARRET ; DONE + +; HERE TO MERGE BLOCK WITH PREVIOUS BLOCK (ADDR IN C) + +A7: HLRZ D,(C) ; SIZE OF OLD BLOCK + ADDI D,(B) ; ADD SIZE OF BLOCK BEING FREED + HRLM D,(C) ; STORE NEW SIZE IN OLD BLOCK + GO ARRET ; DONE + +; HERE IN INSERT NEW BLOCK IN MIDDLE OF LIST + +A8: MOVEI 0,(A) ; ADDRESS OF NEW BLOCK + ADDI 0,(B) ; END OF NEW BLOCK + CAILE 0,(D) ; OVERLAP WITH NEXT BLOCK ? + GO CODE [ ; YES, ERROR + CROAK AFRET CALLED WITH BAD ADDRESS + GO ARRET + ] + CAIE 0,(D) ; CONTIGUOUS WITH NEXT BLOCK ? + GO A6 ; NO, APPEND TO PREVIOUS BLOCK + MOVS 0,(D) ; SWAPPED DOPE WORD OF NEXT BLOCK + ADDI 0,(B) ; SIZE OF COMBINED BLOCK + MOVSM 0,(A) ; MAKE DOPE WORD OF COMBINED BLOCK + HRRM A,(C) ; CHAIN IT TO PREVIOUS BLOCK + HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK + ADDI D,(C) ; END OF PREVIOUS BLOCK + CAIE D,(A) ; CONTIGUOUS WITH PREVIOUS BLOCK ALSO ? + GO ARRET ; NO, DONE + HLRZ D,(C) ; SIZE OF PREVIOUS BLOCK + ADDI 0,(D) ; SIZE OF COMBINED BLOCK + MOVSM 0,(C) ; MERGE AGAIN +ARRET: RETURN ; DONE + + +; +; AFREZ - ALLOCATE ZEROED BLOCK +; + +CENTRY AFREZ,[BSIZE] + + CALL AFREE,[BSIZE] ; ALLOCATE A BLOCK + SETZM (A) ; ZERO FIRST WORD + MOVE B,BSIZE ; THE SIZE + SOJE B,AZRET ; NUMBER OF WORDS REMAINING TO BE ZEROED + ADDI B,(A) ; LAST WORD OF BLOCK + HRLZI C,(A) ; FIRST WORD OF BLOCK (LEFT HALF) + HRRI C,1(A) ; SECOND WORD OF BLOCK (RIGHT HALF) + BLT C,(B) ; TRANSFER ZEROES +AZRET: RETURN ; DONE + +; +; ALOCSTAT - COMPUTE ALLOCATION STATISTICS +; + +CENTRY ALOCSTAT,[PNALOC,PNBFREE] + + MOVE A,FNWORDS ; NUMBER ALLOCATED + MOVEM A,@PNALOC + SETZ A, ; ZERO SUM OF FREE BLOCK SIZES + SETZM @PNBFREE ; ZERO COUNT OF FREE BLOCKS + MOVEI B,FLIST ; PREVIOUS BLOCK ADDR IN B + HRRZ C,(B) ; CURRENT BLOCK ADDR IN C +A9: HLRZ D,(C) ; GET SIZE OF BLOCK + ADD A,D ; ADD TO SUM + AOS @PNBFREE + MOVEI B,(C) ; CURRENT BLOCK -> PREVIOUS BLOCK + HRRZ C,(C) ; NEXT BLOCK -> CURRENT BLOCK + JUMPN C,A9 ; BLOCK EXISTS => LOOP + RETURN + +END + \ No newline at end of file diff --git a/arc/ar5:c/APFNAM C b/arc/ar5:c/APFNAM C new file mode 100644 index 00000000..b9567a3f --- /dev/null +++ b/arc/ar5:c/APFNAM C @@ -0,0 +1,26 @@ +/********************************************************************** + + APFNAME - Append suffix to file name + +**********************************************************************/ + +char *apfname (dest, source, suffix) + char *dest, *source, *suffix; + + {fnsfd (dest, source, 0, 0, 0, suffix, "", ""); + return (dest); + } + +/********************************************************************** + + FNMKOUT - Make output file name + +**********************************************************************/ + +char *fnmkout (dest, source, suffix) + char *dest, *source, *suffix; + + {fnsfd (dest, source, "", 0, 0, suffix, "", ""); + return (dest); + } + \ No newline at end of file diff --git a/arc/ar5:c/ATOI C b/arc/ar5:c/ATOI C new file mode 100644 index 00000000..827ff5ae --- /dev/null +++ b/arc/ar5:c/ATOI C @@ -0,0 +1,17 @@ +/********************************************************************** + + ATOI - Convert string to Integer + +**********************************************************************/ + +int atoi (s) char s[]; + + {int i, f, c; + + if (!s) return (0); + i = f = 0; + if (*s == '-') {++s; ++f;} + while ((c = *s++)>='0' && c<='9') i = i*10 + c-'0'; + return (f?-i:i); + } + \ No newline at end of file diff --git a/arc/ar5:c/BLT CMID b/arc/ar5:c/BLT CMID new file mode 100644 index 00000000..8beb4934 --- /dev/null +++ b/arc/ar5:c/BLT CMID @@ -0,0 +1,21 @@ +; +; BLT +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE BLT +.INSRT NC +.INSRT NM + +CENTRY BLT,[FROM,TO,NUM] + + HRRZ A,TO + HRRZI B,-1(A) + ADD B,NUM + HRL A,FROM + BLT A,(B) + RETURN + +END + \ No newline at end of file diff --git a/arc/ar5:c/C DEFS b/arc/ar5:c/C DEFS new file mode 100644 index 00000000..fbd3bf15 --- /dev/null +++ b/arc/ar5:c/C DEFS @@ -0,0 +1,57 @@ +/* + + C Standard Definitions + +*/ + +# define ITS ITS + +/* data types */ + +struct _filespec {int dev, fn1, fn2, dir;}; +# define filespec struct _filespec + +# define channel int + +struct _cal {int year, month, day, hour, minute, second;}; +# define cal struct _cal + +struct _tag {int *pc, *fp, *ap, *sp;}; +# define tag struct _tag + + +/* common values */ + +# define TRUE 1 +# define FALSE 0 + +# define OPENLOSS -1 /* returned by COPEN if lose */ + +/* C interrupts */ + +# define INT_DEFAULT 0 +# define INT_IGNORE 1 + +# define mpv_interrupt 1 +# define ioc_interrupt 2 +# define ilopr_interrupt 3 +# define mar_interrupt 4 +# define utrap_interrupt 5 +# define pure_interrupt 6 +# define wiro_interrupt 7 + +# define sys_down_interrupt 8 +# define clock_interrupt 9 +# define timer_interrupt 10 +# define pdlov_interrupt 11 +# define ttyi_interrupt 12 +# define cli_interrupt 13 +# define overflow 14 +# define float_overflow 15 + +# define channel0_interrupt 16 +# define inferior0_interrupt 32 + +# define ctrls_interrupt 41 +# define ctrlg_interrupt 42 + \ No newline at end of file diff --git a/arc/ar5:c/C10BOO CMID b/arc/ar5:c/C10BOO CMID new file mode 100644 index 00000000..9d829321 --- /dev/null +++ b/arc/ar5:c/C10BOO CMID @@ -0,0 +1,56 @@ +; +; C10BOO - Bootstrapper Routine +; +; This file is ITS dependent. +; +TITLE BOOTSTRAP +.INSRT NC +.INSRT NM + +LSTART==6 ; WHERE BOOTSTRAP LOADER WILL BE MOVED TO +LCHN==15 ; LOAD FILE CHANNEL +TCHN==16 ; TTY CHANNEL + +CENTRY BOOTSTRAP,[FS] + + MOVE C,FS + SYSCAL OPEN,[MOVSI 6?MOVEI LCHN?(C)?1(C)?2(C)?3(C)],LOSE + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLZ A,OPTOPC+OPTINT ; TURN OFF OLD PC ON MPV, IOC AND + ; USE NEW INTERRUPT STACKING SCHEME + .SUSET [.SOPTI,,A] ; SET OPTION WORD + SETZM 42 ; DISABLE INTERRUPT HANDLING + SETZ A, + .SUSET [.SMASK,,A] + SETZM 41 + + .OPEN TCHN,[SIXBIT/ TTY/] + GO NOTTY + .CALL [SETZ ; TURN OFF ECHOING + 'TTYSET + 1000,,TCHN + [232222222222] + SETZ [230222220222] + ] + JFCL + +NOTTY: MOVE 0,[LOADER,,LSTART] + BLT 0,LSTART+LODLEN ; MOVE LOADER + JRST LSTART ; EXECUTE LOADER +LOSE: SETO A, + RETURN + +; +; THE LOADING PROGRAM +; + +LOADER: + .CALL [SETZ ? SIXBIT/LOAD/ ? MOVEI -1 ? SETZI LCHN] + .VALUE + .IOT LCHN,LSTART+5 ; READ STARTING ADDRESS + .CLOSE LCHN, + JRST @0 ; START PROGRAM + -1,,0 ; IOT POINTER +LODLEN==.-LOADER + +END diff --git a/arc/ar5:c/C10COR CMID b/arc/ar5:c/C10COR CMID new file mode 100644 index 00000000..5b635e71 --- /dev/null +++ b/arc/ar5:c/C10COR CMID @@ -0,0 +1,54 @@ +; +; C10COR - Basic Storage Allocation +; +; This file is ITS dependent. +; + +TITLE CCORE +.INSRT NC +.INSRT NM + +.GLOBAL FNWORD + +; +; GETCORE - BASIC CORE ALLOCATOR +; +; GETCORE (SIZE) => SIZE,,ADDR +; + +CENTRY GETCORE,[BSIZE],[NPAGES,PTR] + + MOVE B,BSIZE + ADDI B,1777 + LSH B,-10. ; NUMBER OF PAGES NEEDED + MOVEM B,NPAGES + CALL PGJGET,[NPAGES] ; GET PAGES + MOVN B,NPAGES ; MINUS NUMBER OF PAGES + JUMPLE A,CODE [ + CROAK STORAGE EXHAUSTED + GO DOT + ] + MOVEM A,PTR + HRL A,B ; AOBJN POINTER TO NEW PAGES +TRYAGN: .CALL [SETZ + 'CORBLK + 1000,,300000 ; WANT READ AND WRITE ACCESS + 1000,,-1 ; PUT PAGE IN MY MAP + A ; WHERE TO PUT THEM + 401000,,400001 ; GET FRESH PAGES + ] + GO CODE [ + CROAK UNABLE TO GET CORE + MOVEI 0,30. + .SLEEP 0, + GO TRYAGN + ] + MOVE A,PTR + LSH A,10. ; POINTER TO FIRST PAGE + MOVE B,NPAGES + LSH B,10. ; NUMBER OF WORDS GOTTEN + ADDM B,FNWORDS ; SAVE FOR STATS + HRL A,B ; SIZE,,ADDR + RETURN + +END diff --git a/arc/ar5:c/C10EXC C b/arc/ar5:c/C10EXC C new file mode 100644 index 00000000..7459b8ab --- /dev/null +++ b/arc/ar5:c/C10EXC C @@ -0,0 +1,120 @@ +# include "c/c.defs" + +int exctime 0; +int exccode 0; + +/********************************************************************** + + EXECS - Execute a program with a given command string + + Returns: + + -5 Job valretted something and was not continued. + -4 Internal fatal error. + -3 Unable to load program file. + -2 Unable to create job. + -1 Unable to open program file. + 0 Job terminated normally. + other Job terminated abnormally with said PIRQ + + Sets: + + exctime - job's CPU time in 1/60 sec. units + exccode - contents of job's loc 1 at termination + +**********************************************************************/ + +int execs (pname, args) char *pname, *args; + + {int i, j, ich; + char *s, buf[40]; + filespec f; + + j = j_fload (pname); + if (j<0) return (j); + + j_sjcl (j, args); + j_give_tty (j); + j_start (j); + + while (TRUE) + {i = j_wait (j); + j_take_tty (j); + switch (i) { + + case -1: return (-4); + case -2: i = 0; + break; + case -3: s = j_valret (j); + if (s) + {cprint ("Job valrets: "); + puts (s); + } + else + {puts ("Job .VALUE 0"); + } + cprint ("continue? "); + gets (buf); + if (buf[0]=='y' || buf[0]=='Y') + {j_give_tty (j); + j_start (j); + continue; + } + i = -5; + break; + case -5: wsuset (014, 02); /* simulate ^Z typed */ + sleep (15); + j_give_tty (j); + j_start (j); + continue; + default: cprint ("Unhandled interrupt, continue? "); + gets (buf); + if (buf[0]=='y' || buf[0]=='Y') + {j_give_tty (j); + j_start (j); + continue; + } + break; + } + break; + } + + exctime = ruset (j_ch(j), 024) / (16666000./4069.); + exccode = 0; + if (!j_name (j, &f) && (ich=open(&f,4))>=0) + {uiiot (ich); + exccode = uiiot (ich); + close (ich); + } + j_kill (j); + return (i); + } + +/********************************************************************** + + EXECV - Execute file given a vector of arguments + +**********************************************************************/ + +int execv (prog, argc, argv) + char *prog, *argv[]; + + {char **ap, **ep, buff[300], *p, *s; + int c; + + p = buff; + ap = argv; + ep = argv + argc - 1; + + while (ap <= ep) + {s = *ap++; + *p++ = '"'; + while (c = *s++) *p++ = c; + *p++ = '"'; + *p++ = ' '; + } + + *p++ = 0; + return (execs (prog, buff)); + } + \ No newline at end of file diff --git a/arc/ar5:c/C10EXP C b/arc/ar5:c/C10EXP C new file mode 100644 index 00000000..b8dc1604 --- /dev/null +++ b/arc/ar5:c/C10EXP C @@ -0,0 +1,51 @@ +# include "c/c.defs" + +/********************************************************************** + + EXPAND ARGUMENT VECTOR CONTAINING FILE NAME PATTERNS + +**********************************************************************/ + +static char **next; +static char *bufp; + +int exparg (argc, argv, outv, buffer) + char *argv[], *outv[], buffer[]; + + {int i, expfs(); + char *s; + + bufp = buffer; + next = outv; + i = 0; + while (idev; + fs.dir = fp->dir; + fs.fn1 = fp->fn1; + fs.fn2 = fp->fn2; + n = rddir (fp, v, 04); + if (fp->fn1) c6tos (fp->fn1, pat1); + if (fp->fn2) c6tos (fp->fn2, pat2); + q = v + 2*n; + for (p=v; pfn1) + {c6tos (p[0], buf); + if (!smatch (pat1, buf)) continue; + } + if (fp->fn2) + {c6tos(p[1], buf); + if (!smatch (pat2, buf)) continue; + } + fs.fn1 = p[0]; + fs.fn2 = p[1]; + (*f)(&fs); + } + } + +/********************************************************************** + + RDIREC - Read A Directory + + S is a string specifying a directory. + V will be filled with pairs of SIXBIT names, one for each file. + The number of files is returned. + +**********************************************************************/ + +int rdirec (s, v, fs) + char *s; + int v[]; + filespec *fs; + + {fparse (s, fs); + if (!fs->dir) fs->dir = fs->fn1; + return (rddir (fs, v, 0)); + } + +/********************************************************************** + + RDDIR - Read Directory + + Return in V a list of names in the directory specified by FS. + OPT is used to filter out some files: + + if (opt & 01) no-links + if (opt & 02) no-backed-up-files + if (opt & 04) no-locked-files + +**********************************************************************/ + +int rddir (fp, v, opt) + filespec *fp; + int v[], opt; + + {int buf[DIRSIZ], f, n, i, *p, d, n1, n2; + filespec fs; + + fs.dev = fp->dev; + fs.dir = fp->dir; + fs.fn1 = _FILE_; + fs.fn2 = _PDIRP_; + if (!fs.dev) fs.dev = _DSK_; + if (!fs.dir) fs.dir = rsname(); + f = open (&fs, BII); + if (f<0) return (0); + sysread (f, buf, DIRSIZ); + close (f); + n = (DIRSIZ - buf[1]) / ENTSIZ; + p = buf+buf[1]; + i = 0; + while (--n >= 0) + {n1 = *p++; + n2 = *p++; + d = *p++ >> 18; /* random info */ + p =+ 2; + if (d & 060) continue; /* should ignore these */ + if (opt & d) continue; /* optionally ignore */ + *v++ = n1; + *v++ = n2; + ++i; + } + return (i); + } + +/********************************************************************** + + RMFD - Read the Master File Directory + + V will be filled with SIXBIT names, one for each directory, + sorted. + The number of directories is returned. + +**********************************************************************/ + +int rdmfd (v) + int v[]; + + {int ch, n, *e, *p, *q, i, j, x; + + ch = fopen ("m.f.d. (file)", BII); + if (ch<0) return (ch); + n = sysread (ch, v, DIRSIZ); + close (ch); + e = v+n; + p = v+v[1]; + q = v; + while (p DEFAULT, 1 => IGNORE, OTHER => ROUTINE ADDR) +; BITS 18-23 BIT NUMBER IN ITS MASK WORD +; BIT 24 ITS MASK WORD NUMBER + +.IDATA +MDATA TAB2 + 0 ; NOT USED + 15,,0 ; MPV + 10,,0 ; IOC + 5,,0 ; ILOPR + 16,,0 ; MAR + 27,,0 ; UTRAP + 30,,0 ; PURE + 31,,0 ; WIRO + + 6,,0 ; SYSDOWN + 14,,0 ; CLOCK + 41,,0 ; TIMER + 0 ; PDLOV (NOT USED) + 0,,0 ; TTYI + 21,,0 ; CLI + 3,,0 ; OVERFLOW + 32,,0 ; FLOATING OVERFLOW + + 100,,0 ; CHANNEL 0 + 101,,0 ; CHANNEL 1 + 102,,0 ; CHANNEL 2 + 103,,0 ; CHANNEL 3 + 104,,0 ; CHANNEL 4 + 105,,0 ; CHANNEL 5 + 106,,0 ; CHANNEL 6 + 107,,0 ; CHANNEL 7 + + 110,,0 ; CHANNEL 10 + 111,,0 ; CHANNEL 11 + 112,,0 ; CHANNEL 12 + 113,,0 ; CHANNEL 13 + 114,,0 ; CHANNEL 14 + 115,,0 ; CHANNEL 15 + 116,,0 ; CHANNEL 16 + 117,,0 ; CHANNEL 17 + + 122,,0 ; INFERIOR 0 + 123,,0 ; INFERIOR 1 + 124,,0 ; INFERIOR 2 + 125,,0 ; INFERIOR 3 + 126,,0 ; INFERIOR 4 + 127,,0 ; INFERIOR 5 + 130,,0 ; INFERIOR 6 + 131,,0 ; INFERIOR 7 + + 0 ; NOT USED + 0 ; CONTROL-S INTERRUPT + 0 ; CONTROL-G INTERRUPT + + +; +; ON - SPECIFY AN ACTION FOR A C INTERRUPT +; + +.CODE +CENTRY ON,[INTNO,NEWH] + + MOVE B,INTNO ; INTERRUPT # + JUMPLE B,ON2 ; BAD # + CAILE B,NINT ; NINT = HIGHEST VALID # + GO ON2 ; BAD # + HRRZ A,NEWH ; NEW HANDLER + CAIL B,CTRSI + GO ON1 ; SOFTWARE INTERRUPT + + LDB D,[220600,,TAB2(B)] ; BIT # + MOVEI C,1 + LSH C,(D) ; MASK + LDB D,[300100,,TAB2(B)] ; WORD # + + CAIN B,CTRGI + JUMPE A,TURNON + JUMPE A,TURNOF + CAIE A,1 + GO TURNON + CAIGE B,8. + GO TURNON + +TURNOF: .SUSET [.SAMASK,,C ? .SAMSK2,,C](D) + GO ON1 + +TURNON: .SUSET [.SIMASK,,C ? .SIMSK2,,C](D) +ON1: HRRZ C,TAB2(B) ; OLD HANDLER + HRRM A,TAB2(B) ; NEW HANDLER + MOVE A,C ; RETURN OLD HANDLER +ONRET: RETURN + +ON2: CROAK ON: INVALID INTERRUPT NUMBER + MOVEI A,1 + GO ONRET + + +; +; SIGNAL - SIGNAL A C INTERRUPT +; + +CENTRY SIGNAL,[SIGNO] + + MOVE A,SIGNO ; INTERRUPT # + JUMPLE A,S3 ; BAD # + CAILE A,NINT ; NINT = HIGHEST VALID # + GO S3 ; BAD # + HRRZ B,TAB2(A) ; HANDLER + CAIN B,1 + GO SIGRET ; 1 => IGNORE + JUMPN B,S1 ; SPECIFIED HANDLER + CAIN A,CTRGI + GO S4 ; HANDLE ^G INTERRUPT + GO SIGRET ; OTHERWISE IGNORE + +S1: CAIGE A,CH0I + GO S2 ; NO ARG + CAILE A,IN0I+7 + GO S2 ; NO ARG + CAIGE A,IN0I + SUBI A,CH0I ; ARG IS CHANNEL # + CAIL A,IN0I + SUBI A,IN0I ; ARG IS INFERIOR # + VCALL (B),[A] + GO SIGRET + +S2: CAIN A,CTRSI + CL CTRSIH ; SPECIAL ^S ACTION + CAIN A,CTRGI + CL CTRGIH ; SPECIAL ^G ACTION + VCALL (B) + GO SIGRET + +S3: CROAK INVALID INTERRUPT SIGNALLED + GO SIGRET + +S4: CL CTRGIH + CALL STKDMP + CROAK -- ^G -- +SIGRET: RETURN + +; SPECIAL HANDLER FOR CONTROL-S INTERRUPT + +IENTRY CTRSIH + + PPUSH A + PPUSH B +CTRS1: SETO B, + SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN" ? 2000,,B] + JUMPLE B,CTRS2 + CAIE B,^S + GO CTRS1 +CTRS2: PPOP B + PPOP A + RTN + +; SPECIAL HANDLER FOR CONTROL-G INTERRUPT + +IENTRY CTRGIH + + PPUSH A + PPUSH B +CTRG1: SETO B, + SYSCAL IOT,[5000,,%TIACT+%TIINT+%TINWT ? TYICHN ? 2000,,B] + JUMPLE B,CTRG2 + CAIE A,^G + GO CTRG1 +CTRG2: PPOP B + PPOP A + RTN + + +; +; DISMISS - DISMISS INTERRUPT AND RETURN TO CALLER +; + +MENTRY DISMISS + SYSCAL DISMIS,[5000,,T%CTL ? INTPTR ? 1000,,.+2] + RETURN + +; +; GETPC - GET INTERRUPTED PC +; + +CENTRY GETPC + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + HRRZ A,T%OPC(D) + RETURN + +; +; SETPC - SET INTERRUPTED PC +; + +CENTRY SETPC,[PC] + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,PC + HRRM A,T%OPC(D) + RETURN + +; +; INTERRUPT HANDLING SPECIFICATONS +; + +T%NRG==4 ; NUMBER OF REGISTERS PUSHED + +T%IW1==0 ; OFFSET OF 1ST INTERRUPT WORD +T%IW2==1 ; OFFSET OF 2ND INTERRUPT WORD +T%DF1==2 ; OFFSET OF 1ST OLD DEFER WORD +T%DF2==3 ; OFFSET OF 2ND OLD DEFER WORD +T%OPC==4 ; OFFSET OF OLD PC +T%REG==5 ; OFFSET OF FIRST SAVED REGISTER +T%SIZ==T%REG+T%NRG ; SIZE OF INTERRUPT FRAME +T%CTL==A*100+T%NRG ; CONTROL ARG FOR PUSHING REGS + +MDATA TSINT + T%CTL,,INTPTR ; PUSH REGISTERS ON INTERRUPT STACK + %PIPDL ? 0 ; HANDLE PDL-OVERFLOW + -1 ? -1 ; DEFER ALL INTERRUPTS + PDLOVH ; PDL-OVERFLOW HANDLER + %PIMPV ? 0 ; HANDLE MPV + #%PIPDL ? -1 ; DEFER ALL BUT PDL-OVERFLOW + MPVH ; MPV HANDLER + #<%PIMPV+%PIPDL> ? 0 ; HANDLE ALL OTHER FIRST WORDERS + #<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV + TSINT1 ; INTERRUPT HANDLER + 0 ? -1 ; HANDLE ALL SECOND WORDERS + #<%PIMPV+%PIPDL> ? -1 ; DEFER ALL BUT MPV AND PDLOV + TSINT2 ; INTERRUPT HANDLER +TSINTL"==21. ; .-TSINT DOESN'T WORK DUE TO MIDAS BUG + +; +; INTERRUPT STACK +; + +INTPSZ==2*TSINTL ; SIZE OF INTERRUPT STACK + +.IDATA +MDATA INTPTR + -INTPSZ,,INTPDL +MDATA INTPDL + BLOCK INTPSZ-1 + -1 ; THIS PAGE MUST NOT BE DELETED! +.CODE + +; +; MPV HANDLER +; + +IENTRY MPVH + + .SUSET [.RMPVA,,B] ; GET LOSING ADDRESS + ; NOTE THAT ON KA-10 THIS ADDRESS + ; IS ROUNDED DOWN TO FIRST WORD + ; OF PAGE + TRZ B,1777 ; ROUND DOWN ANYWAY (FOR KL-10) + + CAMGE B,SEG0LO" ; MAYBE IN SEGMENT 0? + GO MPV$0 ; NO + CAMG B,SEG0HI" ; IN SEGMENT 0? + GO MPV$1 ; YES + +MPV$0: CAMGE B,SEG1LO" ; MAYBE IN SEGMENT 1? + GO TSINT1 ; NO + CAMLE B,SEG1HI" ; IN SEGMENT 1? + GO TSINT1 ; NO + + ; HERE IF ADDRESS IS IN SEGMENT 1 + + MOVE C,PDLTOP ; TOP END OF STACK + SUBI C,2000 + TRZ C,1777 ; LAST FULL PAGE OF STACK + CAME B,C ; REFERENCE TO LAST PAGE OF STACK? + GO MPV$1 ; NO + CROAK IMMINENT STACK OVERFLOW + +MPV$1: LSH B,-10. ; PAGE NUMBER + SYSCAL CORTYP,[B ? SETZM C] ; GET PAGE INFO + JUMPN C,TSINT1 ; PAGE EXISTS => MPV ON ANOTHER JOB + +MPV$2: SYSCAL CORBLK,[1000,,%CBNDW ? 1000,,-1 ? B ? 1000,,%JSNEW],MPVLOS + GO INTDIS +MPVLOS: CROAK UNABLE TO GET ZERO PAGE + GO MPV$2 + +; +; HANDLER FOR FIRST WORD INTERRUPTS +; + +IENTRY TSINT1 + + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,T%IW1(D) ; GET INTERRUPT WORD + JFFO A,.+2 ; GET FIRST BIT + GO INTDIS ; NONE (?) + MOVE A,TAB1(B) ; C INTERRUPT NUMBER + JUMPE A,IGNORE ; NOT HANDLED + HRRZ B,TAB2(A) ; HANDLER + CAIN B,1 + GO IGNORE ; 1 MEANS IGNORE + JUMPN B,TS1 ; HANDLER SPECIFIED + CAIN A,MPV + GO FATMPV + CAIN A,CTRGI + GO TS1 ; DEFAULT IS NOT TO IGNORE +IGNORE: AOS T%OPC(D) ; OTHERWISE - THE DEFAULT + GO INTDIS ; IS TO CONTINUE WITH THE + ; NEXT INSTRUCTION + +; HERE IF FATAL MPV OCCURS + +FATMPV: MOVEI A,%PIMPV + IORM A,T%DF1(D) ; MAKE MPV DEFFERED + GO INTDIS ; NOW DISMISS - WILL MAKE FATAL + +; +; SECOND WORD INTERRUPT HANDLER +; + +IENTRY TSINT2 + + MOVE D,INTPTR ; TOP OF INTERRUPT STACK + MOVEI D,-T%SIZ+1(D) ; BOTTOM OF FRAME + MOVE A,T%IW2(D) ; GET INTERRUPT WORD + JFFO A,.+2 + GO INTDIS + CAILE B,17. + GO CHANI + CAIGE B,10. + GO INTDIS + MOVN A,B + ADDI A,17.+IN0I + GO TS1 + +CHANI: CAIGE B,19. + GO INTDIS + MOVN A,B + ADDI A,35.+CH0I + GO TS1 + + +; +; HERE TO SIGNAL SOMETHING WITH ARG IN A +; + +DEFINE PUSHL LIST +IRP X,,[LIST] + PPUSH X +TERMIN!TERMIN + +DEFINE POPL LIST +IRP X,,[LIST] + PPOP X +TERMIN!TERMIN + +TS1: ADDI P,20 ; IN CASE EPILOG INTERRUPTED + PUSHL [0,5,6,7,10,11,12,13,14,15,16] + PUSHL [40,USAVEA,USAVEB,USAVEC,USAVED,UUOH] + CALL SIGNAL,[A] + POPL [UUOH,USAVED,USAVEC,USAVEB,USAVEA,40] + POPL [16,15,14,13,12,11,10,7,6,5,0] + SUBI P,20 + +PDLOVH: +INTDIS: SYSCAL DISMIS,[5000,,T%CTL ? INTPTR] + +IENTRY ETSINT +END + \ No newline at end of file diff --git a/arc/ar5:c/C10IO C b/arc/ar5:c/C10IO C new file mode 100644 index 00000000..8d65a5c8 --- /dev/null +++ b/arc/ar5:c/C10IO C @@ -0,0 +1,849 @@ +# include "c/c.defs" +# include "c/its.bits" + +/* + * + * CIO - C I/O Routines (written in C) + * + * Routines: + * + * fd = copen (fname, mode, opt) + * c = getchar () + * gets (s) + * putchar (c) + * puts (s) + * ch = mopen (f, mode) + * rc = mclose (ch) + * rc = fparse (s, f) + * s = prfile (f, s) + * ch = fopen (fname, mode) + * ch = open (&filespec, mode) + * argc = fxarg (argc, argv) + * n = prsarg (in, out, argv, job) + * valret (s) + * c6 = ccto6 (c) + * c = c6toc (c6) + * w = csto6 (s) + * s = c6tos (w, s) + * + * Internal routines: + * + * c0init () [called by startup routine] + * fd = c0open (fname, mode) + * w = cons (lh, rh) + * s = filscan (b, s) + * s = c6q2s (w, s) + * + * Variables: + * + * cin - standard input channel + * cout - standard output channel + * cerr - standard error output channel + * + * cinfn - standard input file name (if redirected) + * coutfn - standard output file name (if redirected) + * cerrfn - standard errout file name (if redirected) + * + * + */ + +# rename c0fcbs "C0FCBS" +# rename gettab "GETTAB" +# rename puttab "PUTTAB" +# rename clotab "CLOTAB" +# rename gc_bad "GC$BAD" +# rename pc_bad "PC$BAD" +# rename cl_bad "CL$BAD" +# rename prsarg "PRSARG" +# rename fcbtab "FCBTBL" +# rename tty_input_channel "TYICHN" +# rename tty_output_channel "TYOCHN" +# rename setappend "SETAPP" + +# define _magic 37621 /* a magic number for validation */ +# define buf_siz 0200 +# define fcb_siz 7 +# define NCHANNEL 10 /* number of CHANNELs */ + +# define phyeof_flag 001 +# define open_flag 002 +# define write_flag 004 +# define tty_flag 010 +# define unset_flag 020 + +# define QUOTE 021 /* control-Q, for file names */ + +# define _DSK 0446353000000 /* sixbit for DSK */ +# define _GREATER 0360000000000 /* sixbit for > */ +# define _TTY 0646471000000 /* sixbit for TTY */ +# define _FILE 0164651544516 /* sixbit for .FILE. */ +# define _DIR 0104451621100 /* sixbit for (DIR) */ + +channel cin, /* standard input unit */ + cout, /* standard output unit */ + cerr; /* standard error output unit */ + +char *cinfn, /* standard input file name, if redirected */ + *coutfn, /* standard output file name, if redirected */ + *cerrfn; /* standard errout file name, if redirected */ + +int cerrno; /* system OPEN error codes returned here */ + +extern int c0fcbs[], fcbtab[], puttab[], gettab[], clotab[], + gc_bad[], pc_bad[], cl_bad[]; + +/********************************************************************** + + COPEN - CIO Open File + + Open a file, given a file name, an optional mode, and an + optional options string. The possible modes are + + 'r' - read + 'w' - write + 'a' - append + + The default mode is read. Normally, I/O is character oriented + and produces text files. In particular, the lines of a text + file are assumed (by the user) to be separated by newline + characters with any conversion to the system format performed + by the I/O routines. + + If an options string is given and contains the character "b", + then I/O is integer (word) - oriented and produces image files. + + I/O to and from character strings in core is accomplished by + including "s" in the options string and supplying a character + pointer to the string to be read or written into as the first + argument to COPEN. Closing a string open for write will + append a NULL character to the string and return a character + pointer to that character. + + COPEN returns a CHANNEL, which is a pointer to a control block. + The external variables CIN, COUT, and CERR contain already-open + channels for standard input, standard output, and standard + error output, respectively. + + COPEN returns OPENLOSS in case of error. The system error code is + stored in CERRNO. + +**********************************************************************/ + +channel copen (fname, mode, opt) + char *fname; + + {int *fcbp, i, fmode, bmode, its_mode, flags; + int chan, buffp, state, bcnt, device, c, sflag, *ip; + char *p, buf[5], *ep; + filespec f; + + cerrno = 0; + if (mode<'A' || mode>'z') mode = 'r'; + p = opt; + if (opt<0100 || opt>=01000000) p = ""; + else if (p[0]<'A' || p[0]>'z') p = ""; + + flags = open_flag; + fmode = 0; + switch (lower (mode)) { + case 'r': fmode = 0; break; + case 'w': fmode = 1; break; + case 'a': fmode = 2; break; + default: cerrno = 012; /* mode not available */ + return (OPENLOSS); + } + bmode = 0; + sflag = FALSE; + while (c = *p++) switch (lower (c)) { + case 'b': bmode = 4; break; + case 's': sflag = TRUE; break; + } + + if (c0fcbs[0] != _magic) c0init(); /* initialize */ + for (i=0; i=NCHANNEL) + {cerrno = 06; /* device full */ + return (OPENLOSS); + } + chan = -1; + buffp = fcbp[0] >> 18; + if (sflag) /* string I/O */ + {state = 3; + if (fmode==2) /* append */ + while (*fname) ++fname; + } + else /* file I/O */ + {state = 1; + fparse (fname, &f); /* parse file name */ + if (f.dev == _TTY /* TTY special case */ + && (f.fn1 != _FILE || f.fn2 != _DIR)) + {state = 0; + bmode = 0; + device = 0; + chan = -1; + flags =| tty_flag; + } + else /* normal case */ + {if (f.dev == 0) f.dev = _DSK; + if (f.dir == 0) f.dir = rsname(); + if (f.fn2 == 0) f.fn2 = _GREATER; + + its_mode = (fmode==2 ? 0100001 : fmode); + its_mode =| 2; /* block mode */ + its_mode =| bmode; /* image mode */ + + if (fmode==2 && !bmode) /* char append */ + {chan = setappend (&f, its_mode, buf, &ep); + if (chan == -04) /* not found */ + {chan = mopen (&f, its_mode & 077); + fmode = 1; + } + } + else chan = mopen (&f, its_mode); + if (chan<0) {cerrno = -chan; return (OPENLOSS);} + device = status (chan) & 077; /* device code */ + if (bmode && device<=2) /* TTY in IMAGE mode ?? */ + {close (chan); + bmode = 0; + its_mode =& ~4; + chan = mopen (&f, its_mode); + if (chan<0) {cerrno = -chan; return (OPENLOSS);} + device = status (chan) & 077; + } + if (state==1) + if (buffp==0) + {buffp = salloc (buf_siz); + if (buffp == -1) + {cerrno = 037; /* no core available */ + return (OPENLOSS); + } + } + else + {i = buf_siz; + ip = buffp; + while (--i >= 0) *ip++ = 0; + } + } + } + bcnt = -1; /* special initialization hack */ + if (fmode) + {bcnt = 5*buf_siz; /* char count */ + if (bmode) bcnt = buf_siz; /* word count */ + flags =| write_flag; + } + if (bmode && !sflag) state = 2; + if (chan < 0) {flags =| unset_flag; chan = 0;} + fcbp[0] = (buffp<<18) | ((chan&017)<<14) | ((device&077)<<8) | flags; + fcbp[2] = bcnt; + if (sflag) fcbp[1] = fname; + else fcbp[1] = cons (bmode ? 0 : 0440700, buffp); + if (fcbp[3]==0) fcbp[3] = salloc(20); + else fcbp[3] =& 0777777; + if (fmode) state =+ 4; + fcbp[4] = cons (clotab[state], fcbp[5]=gettab[state]); + fcbp[6] = puttab[state]; + if (fmode==2 && !sflag) /* file append */ + {i = fillen (chan); + if (bmode) access (chan, i); /* access to end of file */ + else if (i>0) + {access (chan, i-1); /* write over last word */ + p = buf; + while (p < ep) cputc (*p++ | 0400, fcbp); + } + } + return (fcbp); + } + +/********************************************************************** + + SETAPPEND - Set up for character append + +**********************************************************************/ + +int setappend (fp, mode, buf, epp) filespec *fp; char buf[], **epp; + + {int count, n, chan, wordlen, chanlen, c; + char *p; + + count = 5; /* try 5 times */ + while (--count>=0) + {p = buf; + chan = mopen (fp, UII); + if (chan < 0) return (chan); + wordlen = fillen (chan); + close (chan); + chan = mopen (fp, UAI); + if (chan < 0) return (chan); + chanlen = fillen (chan); + if (chanlen > 0) + {if (chanlen == wordlen) --chanlen; + else chanlen = ((chanlen-1)/5)*5; + access (chan, chanlen); + n = 5; + while (--n>=0 && (c = uiiot (chan)) >= 0 && c != 3) + *p++ = c; + } + close (chan); + *epp = p; + chan = mopen (fp, mode); + if (chan<0) return (chan); + if (wordlen == fillen(chan)) return (chan); + close (chan); + } + return (-012); + } + +/********************************************************************** + + GETCHAR - Read a character from the standard input unit + +**********************************************************************/ + +getchar () {return (cgetc (cin));} + +/********************************************************************** + + GETS - Read a string from the standard input unit + +**********************************************************************/ + +gets (p) + char *p; + + {int c; + + while ((c = cgetc (cin)) != '\n' && c>0) *p++ = c; + *p = 0; + } + +/********************************************************************** + + PUTCHAR - Output a character to the standard output unit + +**********************************************************************/ + +putchar (c) + int c; + + {return (cputc (c, cout));} + +/********************************************************************** + + PUTS - Output a string to the standard output unit + +**********************************************************************/ + +puts (s) + char *s; + + {int c; + + while (c = *s++) cputc (c, cout); + cputc ('\n', cout); + } + +/********************************************************************** + + MOPEN - OPEN FILE + + Open file given filespec and mode. + Return ITS channel number or -FC if unsuccessful. + Same as OPEN, except handles TTY specially + and waits if file is locked. + +**********************************************************************/ + +channel mopen (f, mode) filespec *f; int mode; + + {int ch, n; + + if (f->dev == _TTY && !(f->fn1 == _FILE && f->fn2 == _DIR)) + return (mode & 1 ? tyoopn() : tyiopn()); + + ch = open (f, mode); + n = 8; + while (ch == -023 && --n>=0) /* file locked */ + {sleep (30); + ch = open (f, mode); + } + return (ch); + } + +/********************************************************************** + + MCLOSE - Close ITS channel, unless its the TTY. + +**********************************************************************/ + +mclose (ch) channel ch; + + {extern int tty_input_channel, tty_output_channel; + if (ch == tty_input_channel) return (0); + if (ch == tty_output_channel) + {tyo_flush (); + return (0); + } + return (close (ch)); + } + +/********************************************************************** + + FPARSE - Convert an ASCIZ string representation of an ITS + file name or a path name to a FILESPEC. + + Return 0 if OK, -1 if bad path name format. + +**********************************************************************/ + +fparse (s, f) char s[]; filespec *f; + + {int i, c, fnc, n_slash, no_its_chars, n_dot; + char buf[7], *p, *filscan(); + + f->dev = f->dir = f->fn1 = f->fn2 = 0; + + /* check for path name */ + + p = s; + no_its_chars = TRUE; + n_slash = n_dot = 0; + + while (c = *p++) switch (c) { + case QUOTE: if (*p) ++p; break; + case '.': ++n_dot; break; + case '/': ++n_slash; break; + case ' ': + case ':': + case ';': no_its_chars = FALSE; break; + } + + if (no_its_chars && (n_dot>0 || n_slash>0)) + + /* here if path name */ + + {p = s; + if (*p=='/') + {--n_slash; + p = filscan (buf, ++p, &n_dot, &n_slash); + f->dev = csto6(buf); + c = *p++; + if (c!='/') return (-1); + } + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + if (c=='/') + {f->dir = csto6(buf); + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + } + if (c=='.') + {f->fn1 = csto6(buf); + p = filscan (buf, p, &n_dot, &n_slash); + c = *p++; + } + if (f->fn1) f->fn2 = csto6(buf); + else f->fn1 = csto6(buf); + return (0); + } + + /* here if ITS file name */ + + p = s; + fnc = i = 0; + buf[0] = 0; + + do {c = *p++; + switch (c) { + + case ':': f->dev = csto6(buf); + i = 0; + break; + + case ';': f->dir = csto6(buf); + i = 0; + break; + + case ' ': + case 0: if (buf[0]) switch (fnc++) { + case 0: f->fn1 = csto6(buf); break; + case 1: f->fn2 = csto6(buf); break; + } + i = 0; + break; + + default: if (c==QUOTE && *p) c = *p++; + if (i<6) buf[i++] = c; + } + + buf[i] = 0; + } + while (c); + return (0); + } + +/********************************************************************** + + FILSCAN - scan for part of file name + +**********************************************************************/ + +char *filscan (b, q, andot, anslash) + char *b, *q; + int *andot, *anslash; + + {int c; + char *p; + + p = q++; + while (c = *p++) + {if (c=='/') {--*anslash; break;} + else if (c=='.') + {if (--*andot == 0 && *anslash==0 && *p && + p!=q) break;} + else if (c==QUOTE && *p) c = *p++; + *b++ = c; + } + *b = 0; + return (--p); + } + +/********************************************************************** + + PRFILE - convert FILESPEC to ITS file name + +**********************************************************************/ + +char *prfile(f,p) filespec *f; char *p; + + {char *c6q2s(); + if (f->dev) {p = c6q2s (f->dev, p); *p++ = ':';} + if (f->dir) {p = c6q2s (f->dir, p); *p++ = ';';} + if (f->fn1) {p = c6q2s (f->fn1, p); *p++ = ' ';} + if (f->fn2) {p = c6q2s (f->fn2, p);} + *p = 0; + return (p); + } + +/********************************************************************** + + FOPEN - Open file given file name + +**********************************************************************/ + +channel fopen (fname, mode) char *fname; int mode; + + {filespec f; + + fparse (fname, &f); + if (f.dev == 0) f.dev = _DSK; + if (f.dir == 0) f.dir = rsname(); + return (open (&f, mode)); + } + +/********************************************************************** + + OPEN - Open file given filespec + +**********************************************************************/ + +channel open (f, mode) filespec *f; int mode; + + {channel c; + int rc; + + c = chnloc(); + if (c<0) return (-014); /* bad channel number */ + rc = sysopen (c, f, mode); + if (rc) return (rc); + return (c); + } + +/********************************************************************** + + FXARG - Process Command Arguments to Set Up + Redirection of Standard Input and Output + + This routine is called by the C start-up routine. + +**********************************************************************/ + +int fxarg (argc, argv) int argc; char *argv[]; + + {char **p, **q, *s; + int i, append, errappend, f; + + i = argc; /* number of arguments given */ + argc = 0; /* number of arguments returned */ + p = argv; /* source pointer */ + q = argv; /* destination pointer */ + + while (--i >= 0) /* for each argument given */ + {s = *p++; /* the argument */ + switch (s[0]) { + case '<': if (s[1]) cinfn = s+1; break; + case '>': if (s[1] == '>') + {if (s[2]) {coutfn = s+2; append = TRUE;}} + else {if (s[1]) {coutfn = s+1; append = FALSE;}} + break; + case '%': if (s[1] == '%') + {if (s[2]) {cerrfn = s+2; errappend=TRUE;}} + else {if (s[1]) {cerrfn = s+1; errappend = FALSE;}} + break; + default: /* normal argument */ + ++argc; *q++ = s; + } + } + + /* now hack the standard file descriptors */ + + if (cinfn) /* input is redirected */ + {f = c0open (cinfn, 'r'); + if (f != OPENLOSS) {cclose (cin); cin = f;} + } + + if (coutfn) /* output is redirected */ + {f = c0open (coutfn, append ? 'a' : 'w'); + if (f != OPENLOSS) {cout = f;} + } + + if (cerrfn) /* errout is redirected */ + {f = c0open (cerrfn, errappend ? 'a' : 'w'); + if (f != OPENLOSS) + {if (cerr!=cout) cclose (cerr); cerr = f;} + } + return (argc); + } + +/********************************************************************** + + C0OPEN - Open with error message + +**********************************************************************/ + +channel c0open (name, mode) + + {channel f; + + f = copen (name, mode, 0); + if (f == OPENLOSS) cprint (cerr, "Unable to open '%s'\n", name); + return (f); + } + +/********************************************************************** + + C0INIT - Initialization for C I/O Routines. + This routine is normally called first by the C start-up routine. + +**********************************************************************/ + +c0init () + + {int *p, i; + + c0fcbs[0] = _magic; + p = &c0fcbs[1]; + i = NCHANNEL*fcb_siz; + while (--i >= 0) *p++ = 0; + i = NCHANNEL; + while (--i >= 0) + {p = &c0fcbs[fcb_siz*i+5]; + p[0] = cons (cl_bad, gc_bad); + p[1] = gc_bad; + p[2] = pc_bad; + } + + cin = copen ("/tty", 'r', 0); /* standard input */ + cout = cerr = copen ("/tty", 'w', 0); /* standard output */ + + /* These calls do not actually open the TTY, the TTY is + automatically opened when I/O is done to it. This is helpful + for allowing C programs to run without the TTY. */ + } + +/********************************************************************** + + VALRET - Valret a String + +**********************************************************************/ + +valret (s) char *s; + + {int len, bp1, bp2, buf, c, flag; + + flag = FALSE; + len = slen (s); + buf = salloc (len/5 + 1); + if (buf<=0) + {buf=s; /* gross hack */ + flag = TRUE; + } + bp1 = bp2 = 0440700000000 | buf; + + while (TRUE) + {c = *s++; + if (c=='\n') c='\r'; + idpb (c, &bp1); + if (!c) break; + } + + val7ret (bp2); + if (flag) cquit(1); else sfree (buf); + } + +/********************************************************************** + + PRSARG - Parse JCL Arguments (PDP-10 ITS) + + given: in - an advance byte pointer to the JCL + out - a pointer to a character buffer where the + arguments should be placed + argv - a pointer to a character pointer array + where pointers to the args should be placed + job - the sixbit XJNAME + narg - the maximum number of arguments + returns: number of arguments + +**********************************************************************/ + +int prsarg (in, out, argv, job, narg) + char *out, *argv[]; + + {int c, argc; + char *c6tos(); + + argc = 1; + argv[0] = out; + out = c6tos (job, out); + *out++ = 0; + argv[1] = out; + + while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case QUOTE: *out++ = ildb (&in); continue; + case ' ': continue; + case '"': while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case QUOTE: *out++ = ildb (&in); continue; + case '"': break; + default: *out++ = c; continue; + } + break; + } + *out++ = 0; + if (++argc < narg) argv[argc] = out; + if (c=='"') continue; + break; + default: *out++ = c; + while (c = ildb (&in)) + {switch (c) { + case '\r': break; + case ' ': break; + case QUOTE: *out++ = ildb (&in); continue; + default: *out++ = c; continue; + } + break; + } + *out++ = 0; + if (++argc < narg) argv[argc] = out; + if (c==' ') continue; + break; + } + break; + } + return (argc>narg ? narg : argc); + } + +/********************************************************************** + + CONS - construct word from left and right halves + +**********************************************************************/ + +int cons (lh, rh) {return (((lh & 0777777) << 18) | (rh & 0777777));} + + +/********************************************************************** + + CCTO6 - convert ascii character to sixbit character + +**********************************************************************/ + +char ccto6 (c) char c; + + {return (((c>=040 && c<0140) ? c+040 : c) & 077);} + +/********************************************************************** + + C6TOC - convert sixbit character to ascii character + +**********************************************************************/ + +char c6toc (c) char c; + + {return (c+040);} + +/********************************************************************** + + CSTO6 - convert ascii string to left-justified sixbit + +**********************************************************************/ + +int csto6 (s) char *s; + + {int c,i,j; + + i=0; + j=30; + while (c = *s++) if (j>=0) + {i =| (ccto6(c)<=0 && (c = (i>>j)&077)) + {*p++ = c6toc(c); j =- 6;} + *p = 0; + return (p); + } + +/********************************************************************** + + C6Q2S - convert left-justified sixbit word to ascii string, + inserting QUOTE characters, where necessary + +**********************************************************************/ + +char *c6q2s (i, p) int i; char *p; + + {int c, j; + + j = 30; + while (j>=0) + {c = c6toc ((i>>j) & 077); + if (c==' ' || c==':' || c==';') *p++ = QUOTE; + *p++ = c; + if (! (i & ((1< # or error code + + j_load (filespec) => # or error code + j_fload (file_name) => # or error code + j_cload (channel, jname) => # or error code + j_own (uname, jname) => # or error code + + error code: + + -1 unable to open program file + -2 unable to create job + -3 unable to load job + -4 fatal error + -5 (OWN) no such job + -6 (OWN) job not yours + + j_start (#) => rc (return code: non-zero => error) + j_stop (#) => rc + j_disown (#) => rc + j_forget (#) => rc + j_kill (#) => rc + j_snarf (#, inferior_name) => rc + (disown named inferior from stopped job) + j_give_tty (#) => rc + j_take_tty (#) => rc + + j_grab_tty () (grab tty if given to some inferior + and stop job) + j_retn_tty () (return tty to inferior and restart) + + j_wait (#) => status (waits for non-zero status) + j_sts (#) => status + + j_onchange (f) (set handler for status changes) + + j_sjcl (#, s) => rc (set jcl for job) + j_jcl (#) => s (get jcl) + j_ch (#) => ch (return block image output channel to job) + j_name (#, filespec) (set filespec to job name) + + j_val (#) => s (return string valretted by job) + j_fval (#) (flush valret string; or call cfree) + + Job Status: + + -5 => stopped, ^Z typed + -4 => stopped (by superior) + -3 => stopped, valret + -2 => stopped, requested suicide + -1 => no job + 0 => running + >0 => stopped, value is job's first interrupt word + +*/ + +# define MAXJOBS 8 +# define VALBUFSIZ 200 + +/* job status values */ + +# define js_attn -5 +# define js_stopped -4 +# define js_valret -3 +# define js_suicide -2 +# define js_nojob -1 +# define js_running 0 + +/* useful SIXBIT numbers */ + +# define _USR 0656362000000 +# define _TS 0646300000000 +# define _DSK 0446353000000 +# define _FOO 0465757000000 +# define _GR 0360000000000 /* > */ + +/* internal tables */ + +# rename job_channels "JOBCHN" +# rename job_status "JOBSTS" +# rename job_jcl "JOBJCL" +# rename job_valret "JOBVAL" +# rename job_name "JOBNAM" +# rename job_xname "JOBXNM" +# rename job_wait "JOBWAT" + +int job_status[MAXJOBS] {js_nojob, js_nojob, js_nojob, js_nojob, + js_nojob, js_nojob, js_nojob, js_nojob}; +int job_channels[MAXJOBS] {-1, -1, -1, -1, -1, -1, -1, -1}; +char *job_jcl[MAXJOBS]; +char *job_valret[MAXJOBS]; +int job_name[MAXJOBS]; +int job_xname[MAXJOBS]; +int job_wait -1; +static int jobtty {-1}, jobotty, jobosts, (*jchandler)(); + +/* the routines */ + +int j_fload (file_name) char *file_name; + + {filespec f; + + fparse (file_name, &f); + return (j_load (&f)); + } + +int j_load (f) filespec *f; + + {int pch, xjname; + + if (f->dev == 0) f->dev = _DSK; + if (f->dir == 0) f->dir = rsname (); + pch = mopen (f, BII); + if (pch<0) return (-1); + xjname = (f->fn1 == _TS ? f->fn2 : f->fn1); + return (j_cload (pch, xjname)); + } + +int j_cload (pch, xjname) + channel pch; + + {int j, jch, start; + + j = j_create (xjname); + if (j<0) + {close (pch); + return (j); + } + jch = job_channels[j]; + + /* load program */ + + if (sysload (jch, pch)) + {uclose (jch); + close (pch); + return (-3); + } + + /* get starting address of program */ + + sysread (pch, &start, 1); + close (pch); + + /* set starting address of job */ + + wuset (jch, UPC, start & 0777777); + return (j); + } + +int j_create (xjname) + + {int jch, i, inc, count, flag; + filespec jf; + + /* set up job name */ + + jf.dev = _USR; + jf.dir = 0; + jf.fn1 = 0; + jf.fn2 = xjname; + + /* make job name unique */ + + flag = FALSE; + while ((jch = open (&jf, OLD + BII)) >= 0) + {close (jch); + if (!flag) + {flag = TRUE; + i = jf.fn2; + count = 0; + while ((i&077)==0) {i =>> 6; ++count;} + if (count>0) + {count = 6*(count-1); + jf.fn2 =| ccto6('0') << count; + inc = 1 << count; + } + else + {jf.fn2 = (jf.fn2 & ~077) | ccto6('0'); + inc = 1; + } + } + else jf.fn2 =+ inc; + } + + /* create job */ + + jch = open (&jf, BIO); + if (jch<0) return (-2); + reset (jch); + + /* set job's NAMEs */ + + wuset (jch, USNAME, rsname()); + wuset (jch, UXJNAME, xjname); + + return (j_xxx (jch, xjname)); + } + +/********************************************************************** + + J_OWN - attach job as inferior + +**********************************************************************/ + +int j_own (uname, jname) + + {filespec fs; + int jch, j, w, sts; + + fs.dev = _USR; + fs.dir = 0; + fs.fn1 = uname; + fs.fn2 = jname; + + if ((jch = open (&fs, OLD + BII)) < 0) return (-5); + close (jch); + if ((jch = open (&fs, BIO)) < 0) return (-5); + if (status (jch) != 061) + {close (jch); return (-6);} + j = j_xxx (jch, jname); + if (ruset (jch, USTOP) & BUSRC) + {w = ruset (jch, UPIRQ); + if (w & PICZ) sts = js_attn; + else if (w & PIVAL) sts = js_valret; + else if (w) sts = w; + else sts = js_stopped; + wuset (jch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + } + else sts = js_running; + job_status[j] = sts; + return (j); + } + +/********************************************************************** + + J_XXX - common processing for new inferior + +**********************************************************************/ + +int j_xxx (jch, xjname) + + {int i, inf_no, option, j_handler(); + + /* get inferior number */ + + i = ruset (jch, UINF) >> 18; + inf_no = 0; + if (i) while (!(i&1)) {i=>>1; ++inf_no;} + + /* set up interrupt handler */ + + on (inferior0_interrupt+inf_no, j_handler); + option = ruset (jch, UOPTION); + wuset (jch, UOPTION, option | OPTBRK); + + /* clean up */ + + job_channels[inf_no] = jch; + if (job_status[inf_no] == js_nojob) + {job_status[inf_no] = js_stopped; + job_jcl[inf_no] = 0; + job_valret[inf_no] = 0; + } + job_name[inf_no] = ruset (jch, UJNAME); + job_xname[inf_no] = xjname; + + return (inf_no); + } + +int j_start (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, 0); + job_status[j] = js_running; + return (0); + } + +int j_stop (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + wuset (ch, USTOP, -1); + job_status[j] = js_stopped; + return (0); + } + +int j_disown (j) + + {int ch, ec; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + ec = sysdisown (ch); + if (ec) return (ec); + j_flush (j); + return (0); + } + +int j_forget (j) + + {int ch; + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch < 0) return (-1); + close (ch); + j_flush (j); + return (0); + } + +int j_kill (j) + + {int ch; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + uclose (ch); + j_flush (j); + return (0); + } + +static int code[] { + 0042000000013, /* .IOPUSH 0, ;(26) DON'T CLOBBER HIM */ + 0041000000034, /* .OPEN 0,34 ;(27) OPEN */ + 0043100000000, /* .LOSE ;(30) FAIL, CAUSE ERR MSG */ + 0042000000027, /* .DISOWN 0, ;(31) DISOWN */ + 0042000000014, /* .IOPOP 0, ;(32) UNCLOBBER HIM */ + 0043200000000, /* .VALUE ;(33) RETURN SUCCESS */ + 0000001656362, /* 1,,'USR ;(34) FILENAME BLOCK */ + 0, /* ;(35) WILL GET UNAME */ + 0 /* ;(36) WILL GET JNAME */ + }; + +int j_snarf (j, jname) + + {int ch, piclr, pirqc, pc, osts, sts; + + if (j<0 || j>=MAXJOBS) return (-1); + osts = job_status[j]; + if (osts == js_running) return (-1); /* must be stopped */ + ch = job_channels[j]; + if (ch<0) return (-1); + code[7] = rsuset (UUNAME); + code[8] = jname; + access (ch, 026); + syswrite (ch, code, 9); + piclr = ruset (ch, UPICLR); + wuset (ch, UPICLR, 0); + pirqc = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, pirqc); + pc = ruset (ch, UPC); + wuset (ch, UPC, 026); + j_start (j); + sts = j_wait (j); + job_status[j] = osts; + if (sts == js_valret) sts = 0; + else {wuset (ch, UAPIRQ, sts); sts = -1;} + wuset (ch, UPC, pc); + wuset (ch, UIPIRQ, pirqc); + wuset (ch, UPICLR, piclr); + return (sts); + } + +int j_flush (j) + + {char *p; + + job_channels[j] = -1; + job_status[j] = js_nojob; + job_name[j] = 0; + if (p = job_jcl[j]) + {sfree (p); + job_jcl[j] = 0; + } + if (p = job_valret[j]) + {sfree (p); + job_valret[j] = 0; + } + on (inferior0_interrupt+j, 0); + } + +int j_give_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = atty (ch); + if (rc == 0) jobtty = j; + return (rc); + } + +int j_take_tty (j) + + {int ch, rc; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + rc = dtty (ch); + if (rc == 0) jobtty = -1; + return (rc); + } + +int j_grab_tty () + + {if (jobtty >= 0) + {int rc; + jobotty = jobtty; + jobosts = job_status[jobtty]; + j_stop (jobtty); + rc = j_take_tty (jobtty); + if (rc && jobosts==0) j_start (jobtty); + return (rc); + } + jobotty = -1; + return (0); + } + +int j_retn_tty () + + {if (jobtty < 0 && jobotty >= 0) + {j_give_tty (jobotty); + if (jobosts == 0) j_start (jobotty); + jobotty = -1; + } + } + +int j_wait (j) + + {int sts; + + if (j<0 || j>=MAXJOBS) return (-1); + job_wait = j; + sts = wfnz (&job_status[j]); + job_wait = -1; + return (sts); + } + +int j_onchange (f) int (*f)(); + + {jchandler = f; + } + +int j_sts (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_status[j]); + } + +int j_sjcl (j, s) char *s; + + {char *buf, *p; + int ch, i; + + if (j<0 || j>=MAXJOBS) return (-1); + ch = job_channels[j]; + if (ch<0) return (-1); + if (*s==0) + {if (buf = job_jcl[j]) /* flush previous */ + {i = ruset (ch, UOPTION) & ~OPTCMD; + wuset (ch, UOPTION, i); + sfree (buf); + job_jcl[j] = 0; + } + return (0); + } + i = salloc (slen (s) + 2); + if (i <= 0) return (-1); + buf = i; + stcpy (s, buf); + p = buf; + while (*p) ++p; + if (p==buf || p[-1]!='\r') + {p[0] = '\r'; + p[1] = 0; + } + job_jcl[j] = buf; + wuset (ch, UOPTION, OPTCMD); + } + +char *j_jcl (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_jcl[j]); + } + +int j_ch (j) + + {if (j<0 || j>=MAXJOBS) return (-1); + return (job_channels[j]); + } + +int j_name (j, f) filespec *f; + + {f->dev = _USR; + f->dir = 0; + f->fn1 = runame(); + if (j>=0 && jfn2 = job_name[j]; + return (f->fn2 == 0); + } + f->fn2 = 0; + return (-1); + } + +char *j_val (j) + + {if (j<0 || j>=MAXJOBS) return (0); + return (job_valret[j]); + } + +j_fval (j) + + {if (j<0 || j>=MAXJOBS) return; + if (job_valret[j] == 0) return; + cfree (job_valret[j]); + job_valret[j] = 0; + } + +j_handler (j) + + {int ch, w, opt, old_status; + + if (j<0 || j>=MAXJOBS) return; + ch = job_channels[j]; + if (ch<0) return; + + old_status = job_status[j]; + w = ruset (ch, UPIRQ); + wuset (ch, UAPIRQ, PJTTY+PIIOC+PIARO+PICZ+PIVAL); + opt = ruset (ch, UOPTION); + if ((opt & OPTOPC)==0 && (w & IBACKUP)) + wuset (ch, UPC, ruset (ch, UPC) - 1); + + job_status[j] = w; + if (w & PICZ) /* ^Z typed */ + {job_status[j] = js_attn; + return; + } + if (w & PIVAL) /* .VALUE */ + jdovalue (j); + else if (w & PIBRK) /* .BREAK */ + jdobrk (j); + + if (j != job_wait && job_status[j] != old_status && jchandler) + (*jchandler)(j,job_status[j]); + } + +jdovalue (j) /* handle .VALUE */ + + {int ch, ich, cmda, n; + char *p, buf[VALBUFSIZ]; + filespec f; + + ch = job_channels[j]; + job_valret[j] = 0; + job_status[j] = js_valret; + cmda = ruset (ch, USV40) & 0777777; + if (cmda == 0) return; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + access (ich, cmda); + n = VALBUFSIZ; + p = buf; + while (TRUE) + {int w, i, c; + w = uiiot (ich); + for (i=0;i<5;++i) + {c = (w>>29) & 0177; + w =<< 7; + if (c!='\n') {*p++ = c; --n;} + if (c=='\r') {*p++ = '\n'; --n;} + if (!c) break; + if (n<=2) + {*p++ = c = 0; + break; + } + } + if (!c) break; + } + close (ich); + if (stcmp (buf, ":KILL\r") || stcmp (buf, ":KILL\r\n")) + {/* if (job_wait != j) j_kill (j); + else */ job_status[j] = js_suicide; + return; + } + p = calloc (slen (buf) + 1); + stcpy (buf, p); + job_valret[j] = p; + return; + } + +jdobrk (j) /* handle .BREAK */ + /* unless there is a 'fatal error', the job status + must be changed to something reasonable */ + + {int ch, i; + ch = job_channels[j]; + wuset (ch, UAPIRQ, PIBRK); /* reset PIRQ bit */ + i = ruset (ch, USV40); /* the instruction */ + if ((i & ~000740000000) == 042000000033) + i = 045700160000; /* .LOGOUT n, */ + switch (i>>18) { /* opcode */ + +case 045700: /* .BREAK 16 */ + /* if ((i & 020000) && (job_wait != j)) j_kill (j); + else */ job_status[j] = js_suicide; + return; + +case 045500: /* .BREAK 12 */ + jdob12 (j, i); + return; + } + + j_start (j); + } + +jdob12 (j, i) /* handle .BREAK 12 */ + + {int cmda, ich, och; + filespec f; + + cmda = i & 0777777; + if (j_name (j, &f)) return; + if ((ich = open (&f, UII)) < 0) return; + if ((och = open (&f, UIO)) < 0) + {close (ich); + return; + } + access (ich, cmda); + i = uiiot (ich); + if (i & 0200000000000) /* multiple commands */ + {int n, a; + n = (i>>18) | 0777777000000; + a = i & 0777777; + while (n<0) + {access (och, cmda); + ++n; + ++a; + uoiot (och, (n<<18) | a); + access (ich, a-1); + do_brk (j, ich, och, uiiot (ich)); + } + } + else do_brk (j, ich, och, i); + close (ich); + close (och); + j_start (j); + } + +do_brk (j, ich, och, w) /* do .BREAK 12 command W */ + + {int cmd, a, f, i; + + cmd = (w>>18) & 0177777; + a = w & 0777777; + access (och, a); + if (cmd==6) /* send :PRINT defaults */ + {uoiot (och, _DSK); + uoiot (och, rsname ()); + uoiot (och, _FOO); + uoiot (och, _GR); + return; + } + if (cmd==5 && job_jcl[j]) + {f = copen (job_jcl[j], 'r', "s"); + access (ich, a+2); + while (TRUE) + {w = 0; + for (i=0;i<5;++i) w = (w<<7) | (cgetc (f) & 0177); + w =<< 1; + uoiot (och, w); + if ((w & 0377) == 0) break; + if (uiiot (ich)) + {uoiot (och, 0); + break; + } + } + cclose (f); + return; + } + if (cmd==10) /* send XJNAME */ + {uoiot (och, job_xname[j]); + return; + } + } + \ No newline at end of file diff --git a/arc/ar5:c/C10MAP C b/arc/ar5:c/C10MAP C new file mode 100644 index 00000000..9488f97a --- /dev/null +++ b/arc/ar5:c/C10MAP C @@ -0,0 +1,58 @@ +/* + + FILMAP - file mapping routines + + filmap (c, o, s) map in part of a file + filunmap (p, s) unmap part of a file + +*/ + +# include "c.defs" + +/********************************************************************** + + FILMAP - map in a part of a disk file + return a pointer to it + +**********************************************************************/ + +int *filmap (ch, offset, size) + + {int block_no, page_no, word_no, no_pages, i; + int *p; + + block_no = offset>>10; + word_no = offset & 01777; + no_pages = ((word_no + size - 1) >> 10) + 1; + page_no = pg_get (no_pages); + if (page_no < 0) + {puts ("FILMAP: Unable to Allocate Pages.\n"); + return (0); + } + for (i=0;i> 10; + no_pages = ((word_no + size - 1) >> 10) + 1; + pg_ret (page_no, no_pages); + } + + \ No newline at end of file diff --git a/arc/ar5:c/C10MIO CMID b/arc/ar5:c/C10MIO CMID new file mode 100644 index 00000000..69280cd2 --- /dev/null +++ b/arc/ar5:c/C10MIO CMID @@ -0,0 +1,490 @@ +; +; C10MIO - C I/O ROUTINES WRITTEN IN MIDAS +; +; This file is ITS dependent. +; + +TITLE MIO +.INSRT NC +.INSRT NM + +; INCLUDES: +; +; CGETC - CIO GET CHARACTER +; CPUTC - CIO PUT CHARACTER +; CGETI - CIO GET INTEGER (IMAGE) +; CPUTI - CIO PUT INTEGER (IMAGE) +; CEOF - CIO TEST FOR END-OF-FILE +; CFLUSH - CIO FLUSH BUFFER +; REW - REWIND INPUT FILE +; CLOSALL - CIO CLOSE ALL FILES +; CCLOSE - CIO CLOSE FILE +; ISTTY - IS FILE A TTY? +; CISFD - IS PTR AN ACTUAL FILE DESCRIPTOR? +; ITSCHAN - RETURN ACTUAL ITS CHANNEL +; + +; REGISTERS + +FP==3 ; FILE CONTROL BLOCK POINTER +T1==4 ; TEMPORARY + +; VALUES + +NL==12 +CR==15 + +; FILE CONTROL BLOCK ENTRIES + +FBUFFP==0 ; (LEFT HALF) POINTER TO BUFFER (OR ZERO IF NOT BUFFERED) + FCHAN: 160400,,(FP) ; ITS CHANNEL NUMBER + FDEVIC: 100600,,(FP) ; DEVICE CODE +FFLAG==0 ; (RIGHTMOST 8 BITS) FLAGS + PHYEOF==1 ; PHYSICAL EOF REACHED (BUFFERED INPUT) + %OPEN==2 ; FILE IS OPEN + %WRITE==4 ; FILE IS OPEN FOR WRITE + %TTY==10 ; FILE IS TTY + %UNSET==20 ; DEVICE AND CHANNEL NOT SET YET +FBPTR==1 ; POINTER TO NEXT CHAR/WORD OR CHAR/WORD POSITION +FBCNT==2 ; NUMBER OF CHARS/WORDS OR AVAILABLE POSITIONS IN BUFFER +FUCNT==3 ; (LEFT HALF) NUMBER OF CHARS IN UNGETC BUFFER +FUPTR==3 ; (RIGHT HALF) POINTER TO UNGETC BUFFER +FCLSR==4 ; (LEFT HALF) ADDRESS OF CLOSE ROUTINE +FNGETR==4 ; (RIGHT HALF) ADDRESS OF NORMAL GETC ROUTINE +FGETCR==5 ; ADDRESS OF CGETC ROUTINE +FPUTCR==6 ; ADDRESS OF CPUTC ROUTINE +FCBSIZ==7 ; SIZE OF FILE CONTROL BLOCK + +; CONSTANTS + +IBFSIZ==200 +NCHAN==10. +UBFFSZ==20. + +CENTRY CGETC,[FD] +XENTRY GETC,CGETC +XENTRY CGETI,CGETC +XENTRY GETI,CGETC + + HRRZ FP,FD ; FILE DESCRIPTOR + GO @FGETCR(FP) ; JUMP TO APPROPRIATE ROUTINE + +GETBUF: SOSGE FBCNT(FP) ; HERE FOR BUFFERED CHAR INPUT + JSP B,GTBUF1 ; BUFFER EMPTY, GO FILL IT + ILDB A,FBPTR(FP) ; GET NEXT CHAR FROM BUFFER + CAIN A,CR ; IGNORE INCOMING CR + GO GETBUF + RETURN + +GETBIN: SOSGE FBCNT(FP) ; HERE FOR BINARY INPUT + GO GTBIN1 ; BUFFER EMPTY, REFILL IT + MOVE A,@FBPTR(FP) ; GET NEXT WORD FROM BUFFER + AOS FBPTR(FP) ; INCR POINTER + RETURN + +GETSTR: MOVE A,@FBPTR(FP) ; HERE FOR STRING INPUT + AOS FBPTR(FP) ; INCR POINTER + JUMPE A,NEWEOF + RETURN + +GETTTY: CALL TYI ; HERE FOR TTY INPUT + HRRZ FP,FD ; RESTORE FP + JUMPE A,NEWEOF + RETURN + +IENTRY GC$BAD + CROAK BAD CALL TO CGETC/CGETI + SETO A, + RETURN + +GETUN: HLRZ B,FUCNT(FP) ; HERE WHEN CHAR IN UNGETC BUFFER + JUMPLE B,CODE [ ; IS UNGETC BUFFER EMPTY? + HRRZ A,FNGETR(FP) ; YES + MOVEM A,FGETCR(FP) ; RESTORE CGETC ROUTINE + GO (A) ; GET NEXT CHAR + ] + HRRZ A,FUPTR(FP) + ADD A,B + HRRZ A,(A) ; GET CHAR + SUBI B,1 ; DECR COUNT + HRLM B,FUCNT(FP) + RETURN + +NEWEOF: MOVEI A,EOF ; HERE ON NEWLY DISCOVERED EOF + MOVEM A,FGETCR(FP) + HRRM A,FNGETR(FP) ; SET CGETC ROUTINE TO EOF +EOF: SETZ A, + RETURN + +; BUFFERED CHARACTER INPUT - BUFFER READ ROUTINE +; +; CONTAINS HACKERY WHICH ALLOWS DETECTION OF LAST WORD +; OF FILE. TRAILING CONTROL-C'S ARE REMOVED FROM THIS +; WORD. CALLED VIA JSP B, +; + +GTBUF1: HRRZ T1,FFLAG(FP) ; HERE TO FILL OR REFILL BUFFER + TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED? + GO NEWEOF ; YES, ANNOUNCE IT + MOVN A,FBCNT(FP) ; OLD CHARACTER COUNT (CHECKED LATER) + MOVEI T1,5* ; RESET CHARACTER COUNT + MOVEM T1,FBCNT(FP) ; (LAST WORD SAVED FOR NEXT BUFFER) + HLRZ T1,FBUFFP(FP) ; RESET CHARACTER POINTER + HRLI T1,440700 ; TO BEGINNING OF BUFFER + MOVEM T1,FBPTR(FP) + CAIE A,2 ; CHECK OLD COUNT FOR SPECIAL VALUE + GO GTBUF2 ; NORMAL (NOT INIT) CASE + HLRZ T1,FBUFFP(FP) ; FIRST TIME - FILL ENTIRE BUFFER + HRLI T1,-IBFSIZ + GO GTBUF3 + +GTBUF2: HLRZ T1,FBUFFP(FP) ; NORMAL CASE - ONE WORD SAVED FROM LAST READ + MOVE A,IBFSIZ-1(T1) ; GET LAST WORD OF BUFFER (UNREAD) + MOVEM A,(T1) ; MAKE FIRST WORD OF BUFFER + ADDI T1,1 ; ADJUST CPTR TO FILL REST OF BUFFER + HRLI T1,-IBFSIZ+1 + +GTBUF3: LDB A,FCHAN ; ITS CHANNEL NUMBER + LSH A,23. + IOR A,[.IOT T1] + XCT A ; EXECUTE .IOT + JUMPGE T1,-2(B) ; BUFFER WAS FILLED, NO MORE TO DO + HLRES T1 + ADDI T1,IBFSIZ ; NUMBER OF WORDS READ + HLRZ A,FBUFFP(FP) + ADDI A,-1(T1) ; POINTER TO WORD LAST READ + IMULI T1,5 ; NUMBER OF CHARS READ + PPUSH B + MOVEI B,5 ; CHECK FOR AT MOST 5 TRAILING ^C'S + HRLI A,010700 ; BYTE POINTER TO LAST CHAR +GTBUF4: LDB 0,A ; GRAB CHARACTER + ADD A,[070000,,0] ; DECREMENT BYTE POINTER + CAIE 0,3 ; IS IT A ^C + GO GTBUF5 ; NO + SUBI T1,1 ; DECREMENT CHARACTER COUNT + SOJG B,GTBUF4 ; KEEP LOOKING +GTBUF5: PPOP B + MOVEM T1,FBCNT(FP) ; SET CHARACTER COUNT + MOVEI T1,PHYEOF + IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG + GO -2(B) ; THAT'S IT! + +; +; GTBIN1 - INTERNAL CODE FOR BINARY BUFFER GET +; +GTBIN1: HRRZ T1,FFLAG(FP) ; HERE TO REFILL BUFFER IN BINARY MODE + TRNE T1,PHYEOF ; HAS END OF FILE BEEN REACHED? + GO NEWEOF ; YES, ANNOUNCE IT + MOVEI T1,IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) ; BUFFER POINTER + MOVEM T1,FBPTR(FP) ; RESET POINTER + HRLI T1,-IBFSIZ ; COUNTING POINTER FOR IOT + LDB A,FCHAN + LSH A,23. + IOR A,[.IOT T1] ; SET UP .IOT INSTRUCTION + XCT A ; EXECUTE .IOT INSTRUCTION + JUMPGE T1,GETBIN ; BUFFER WAS FILLED, RESUME + HLRES T1 + ADDI T1,IBFSIZ ; NUMBER OF WORDS ACTUALLY READ + MOVEM T1,FBCNT(FP) ; SET COUNTER + MOVEI T1,PHYEOF + IORM T1,FFLAG(FP) ; SET PHYSICAL EOF FLAG + GO GETBIN ; RESUME + +CENTRY CPUTC,[CC,FD] +XENTRY PUTC,CPUTC +XENTRY CPUTI,CPUTC +XENTRY PUTI,CPUTC + + HRRZ FP,FD ; FILE DESCRIPTOR + MOVE A,CC ; CHARACTER (OR INTEGER) TO BE WRITTEN + GO @FPUTCR(FP) ; JUMP TO APPROPRIATE ROUTINE + +PUTBUF: CAIN A,NL ; HERE FOR BUFFERED CHAR OUTPUT + GO CODE [ + CALL CPUTC,[[[CR]],FP] + HRRZ FP,FD + MOVEI A,NL + GO PF$1 + ] + JUMPE A,PC$RET ; DONT WRITE NULLS +PF$1: IDPB A,FBPTR(FP) ; STORE CHAR + SOSG FBCNT(FP) ; BUFFER FULL? + GO CODE [ ; YES + MCALL FLUSHB,[FP,[[IBFSIZ]]] ; FLUSH ENTIRE BUFFER + GO PC$RET + ] +PC$RET: RETURN ; NO, RETURN + +PUTBIN: MOVEM A,@FBPTR(FP) ; HERE ON BINARY OUTPUT + AOS FBPTR(FP) + SOSLE FBCNT(FP) + GO PC$RET + HLRZ T1,FBUFFP(FP) + HRLI T1,-IBFSIZ ; SET UP COUNTING POINTER FOR .IOT + LDB A,FCHAN ; GET ITS CHANNEL NUMBER + LSH A,23. + IOR A,[.IOT T1] ; PREPARE .IOT INSTRUCTION + XCT A ; EXECUTE .IOT INSTRUCTION + MOVEI T1,IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) + MOVEM T1,FBPTR(FP) ; RESET POINTER + GO PC$RET + +PUTSTR: MOVEM A,@FBPTR(FP) ; HERE ON STRING OUTPUT + AOS FBPTR(FP) + GO PC$RET + +PUTTTY: CAIN A,NL ; HERE ON TTY OUTPUT + MOVEI A,CR ; OUTPUT NEWLINES AS CR'S + CALL TYO,[A] + GO PC$RET + +IENTRY PC$BAD + CROAK BAD CALL TO CPUTC/CPUTI + SETO A, + GO PC$RET + +CENTRY CEOF,[FD] + + HRRZ FP,FD + SETZ A, + HRRZ B,FGETCR(FP) + CAIN B,EOF + MOVEI A,1 + CAIN B,GC$BAD + SETO A, + RETURN + +CENTRY UNGETC,[CC,FD] + + HRRZ FP,FD ; FILE DESCRIPTOR + MOVE A,CC ; CHARACTER + HLRZ T1,FUCNT(FP) ; NUMBER OF CHARS IN BUFFER + ADDI T1,1 + CAIL T1,UBFFSZ ; TOO MANY? + GO CODE [ + SETO A, + GO UN$RET + ] + HRLM T1,FUCNT(FP) + HRRZ B,FUPTR(FP) + ADD T1,B + MOVEM A,(T1) ; STORE CHAR + MOVEI B,GETUN + MOVEM B,FGETCR(FP) ; SET UP GETC ROUTINE +UN$RET: RETURN + +CENTRY CFLUSH,[FD] + + MCALL FLUSHP,[FD,[[0]]] + RETURN + +MENTRY FLUSHP,[FD,PADC] + + HRRZ FP,FD + HRRZ A,FPUTCR(FP) ; OUTPUT ROUTINE + CAIE A,PUTBUF + GO FL$RET + HRRZ T1,PADC ; PAD CHARACTER + MOVEI A,5*IBFSIZ ; NUMBER OF CHAR POSITIONS + SUB A,FBCNT(FP) ; NUMBER OF ACTUAL CHARS IN BUFFER + JUMPLE A,FL$RET ; BUFFER IS EMPTY + IDIVI A,5 + JUMPE B,FL$1 ; NO PARTIALLY FILLED WORDS + MOVN B,B + ADDI B,5 + IDPB T1,FBPTR(FP) ; FILL OUT WITH ^C'S + SOJG B,.-1 + ADDI A,1 +FL$1: MCALL FLUSHB,[FP,A] +FL$RET: RETURN + +MENTRY FLUSHB,[FD,SIZE] + + MOVE FP,FD ; FILE POINTER + MOVN T1,SIZE ; SIZE OF FILLED PART OF BUFFER + HRLZ T1,T1 ; CONSTRUCT + HLR T1,FBUFFP(FP) ; .IOT POINTER + LDB B,FCHAN + LSH B,23. + IOR B,[.IOT T1] ; PREPARE .IOT INSTRUCTION + XCT B ; EXECUTE .IOT INSTRUCTION + MOVEI T1,5*IBFSIZ + MOVEM T1,FBCNT(FP) ; RESET COUNTER + HLRZ T1,FBUFFP(FP) + HRLI T1,440700 + MOVEM T1,FBPTR(FP) ; RESET ABPTR + RETURN + +CENTRY REW,[FD] + + HRRZ FP,FD + SETOM FBCNT(FP) + HRRZ A,FFLAG(FP) + TRZ A,PHYEOF + HRRM A,FFLAG(FP) + MOVE A,GETTAB+1 + MOVEM A,FGETCR(FP) + LDB A,FCHAN + .CALL [SETZ ? 'ACCESS ? A ? 401000,,0] + CROAK REW: ACCESS FAILED + RETURN + +CENTRY CLOSALL,,[COUNTER] ; CLOSE ALL C FILES + + MOVEI A,NCHAN-1 + MOVEM A,COUNTER + MOVE A,COUNTER +CA$1: CALL CCLOSE,[FCBTBL(A)] + SOSL A,COUNTER + GO CA$1 + RETURN + +CENTRY CCLOSE,[FD] + + HRRZ FP,FD + HLRZ A,FCLSR(FP) + GO (A) ; JUMP TO APPROPRIATE ROUTINE + +CLOBUF: MCALL FLUSHP,[FP,[[3]]] + GO CLIBUF + +CLOBIN: MOVE A,FBCNT(FP) ; HERE ON BINARY OUTPUT + SUBI A,IBFSIZ + JUMPGE A,CLIBUF + HRLZ A,A + HLR A,FBUFFP(FP) + LDB B,FCHAN + LSH B,23. + IOR B,[.IOT A] + XCT B ; FLUSH BUFFER + +CLIBUF: LDB A,FCHAN ; HERE ON BUFFERED AND BINARY INPUT + ; ALSO FALL THROUGH FROM BUFFERED AND BINARY OUTPUT + CALL MCLOSE,[A] + MOVE FP,FD + +CLTTY: SETZ A, ; HERE ON TTY AND FALL THROUGH + +CLOSE2: MOVEI T1,%OPEN ; HERE TO CLEAR %OPEN BIT + ANDCAM T1,FFLAG(FP) + MOVEI T1,GC$BAD ; SET ROUTINES TO BAD + MOVEM T1,FGETCR(FP) + MOVEI T1,PC$BAD + MOVEM T1,FPUTCR(FP) + MOVE T1,[CL$BAD,,GC$BAD] + MOVEM T1,FCLSR(FP) +CL$RET: RETURN + +CLOSTR: MOVE A,FBPTR(FP) ; HERE ON STRING OUTPUT + SETZM (A) ; APPEND NULL ONTO STRING + GO CLOSE2 ; RETURN POINTER TO NULL CHAR + +IENTRY CL$BAD + SETO A, + GO CL$RET + +CENTRY ISTTY,[FD] + + HRRZ FP,FD + HRRZ A,FFLAG(FP) + TRNE A,%UNSET ; IS DEVICE CODE VALID? + GO IS$RET ; NO -- MUST BE A TTY + LDB A,FDEVICE ; GET IT + CAILE A,2 ; TEST FOR TTY DEVICES + SETZ A, +IS$RET: RETURN + +; INTERNAL ROUTINE TO SET DEVICE AND CHANNEL +; MUST BE THE TTY INPUT OR OUTPUT CHANNEL +; RETURN DEVICE CODE + +MENTRY SETDEV,[FD] + + HRRZ FP,FD + MOVE A,FFLAG(FP) + TRNE A,%WRITE + MOVEI B,ZTYOOPN" + TRNN A,%WRITE + MOVEI B,ZTYIOPN" + VCALL (B) + JUMPL A,SD$RET ; VALID CHANNEL RETURNED? + HRRZ FP,FD + DPB A,FCHAN ; YES - STORE IT + LSH A,23. + IOR A,[.STATUS A] + XCT A + ANDI A,77 ; GET DEVICE FROM CHANNEL STATUS + DPB A,FDEVIC ; STORE DEVICE + MOVEI T1,%UNSET ; CLEAR %UNSET BIT + ANDCAM T1,FFLAG(FP) +SD$RET: RETURN + +CENTRY CISFD,[FD] + + MOVE A,FD + CAIGE A,C0FCBS+1 + GO ISF$NO + CAIL A,C0FCBS+1+NCHAN*FCBSIZ + GO ISF$NO + MOVEI A,1 + RETURN +ISF$NO: SETZ A, + RETURN + +CENTRY ITSCHAN,[FD] + + HRRZ FP,FD + HRRZ A,FFLAG(FP) + TRNN A,%UNSET ; IS CHANNEL CODE VALID? + GO IC$1 ; YES - GET IT + MCALL SETDEV,[FD] ; NO -- SET IT AND RETURN IT + RETURN +IC$1: LDB A,FCHAN ; GET CHANNEL + RETURN + +.PDATA +MDATA GETTAB + GETTTY + GETBUF + GETBIN + GETSTR + GC$BAD + GC$BAD + GC$BAD + GC$BAD + +MDATA PUTTAB + PC$BAD + PC$BAD + PC$BAD + PC$BAD + PUTTTY + PUTBUF + PUTBIN + PUTSTR + +MDATA CLOTAB + CLTTY + CLIBUF + CLIBUF + CLTTY + CLTTY + CLOBUF + CLOBIN + CLOSTR + +; STATIC DATA AREAS + +.UDATA +MDATA C0FCBS + BLOCK NCHAN*FCBSIZ+1 + +MDATA FCBTBL +REPEAT NCHAN C0FCBS+1+.RPCNT*FCBSIZ + +END + \ No newline at end of file diff --git a/arc/ar5:c/C10PAG C b/arc/ar5:c/C10PAG C new file mode 100644 index 00000000..512e57ea --- /dev/null +++ b/arc/ar5:c/C10PAG C @@ -0,0 +1,111 @@ +/* + * C PAGE Handling Package + * + * routines: + * + * pg = pg_get (n) + * rc = pg_ret (pg, n) + * b = pg_exist (pg) + * i = pg_nshare (pg) + * i = pp_nshare (p) + * + */ + +# include "c.defs" + +# rename page_table "PAGTAB" +# rename first_free_page "FFPAGE" + +int first_free_page; +extern int page_table [256]; +extern int cerr; + +/********************************************************************** + + PG_GET - Page Get + + Allocate "n" contiguous unused pages in the address space. + Return the number of the lowest page allocated, or -1 + if unable to allocate pages. + +**********************************************************************/ + +int pg_get (n) + + {int page, i, top, tp, n_free; + + if (n<1 || n>254) return (-1); + page = first_free_page; /* first page we examine */ + top = 256-n; /* highest possible low page */ + n_free = 0; /* number of free pages we see */ + while (page <= top) + {for (i=0;i=n) break; /* success */ + page =+ i+1; + } + if (page > top) return (-1); + for (i=0;i256) + {cprint (cerr, "PG_RET: invalid page number %d.\n", page); + return (-1); + } + if (page < first_free_page) first_free_page = page; + while (--n >= 0) + {page_table[page] = 0; + corblk (0, -1, page, -1, page); + ++page; + } + return (0); + } + +/********************************************************************** + + PG_EXIST - Does page exist in address space? + +**********************************************************************/ + +pg_exist (page_no) + + {int blk[4]; + + cortyp (page_no, blk); + return (page_table[page_no] = (blk[0] != 0)); + } + + +/********************************************************************** + + PG_NSHARE - Return number of times page is shared + +**********************************************************************/ + +pp_nshare (p) {return (pg_nshare (p>>10));} + +pg_nshare (page_no) + + {int blk[4]; + + cortyp (page_no, blk); + return (blk[3] & 0777777); + } + + \ No newline at end of file diff --git a/arc/ar5:c/C10RUN CMID b/arc/ar5:c/C10RUN CMID new file mode 100644 index 00000000..a3a1ee4d --- /dev/null +++ b/arc/ar5:c/C10RUN CMID @@ -0,0 +1,431 @@ +; +; C10RUN - BASIC C RUN-TIME SUPPORT +; +; This file is ITS dependent. +; + +TITLE CRUN +.INSRT NC +.INSRT NM + +.GLOBAL A,B,C,D,P,GO,.CCALL,.VCALL,.ACALL,.XCALL + +PDLSIZ==20000 ; DESIRED PDL SIZE +MAXARG==40. ; MAXIMUM NUMBER OF ARGUMENTS +BUFSZ==250. ; COMMAND BUFFER SIZE IN CHARACTERS +TP==16 + +; +; START-UP ROUTINE +; + +IENTRY START + + ; ENABLE INTERRUPTS + + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLO A,OPTOPC+OPTINT ; SET OLD PC ON MPV, IOC AND + ; USE NEW INTERRUPT STACKING SCHEME + .SUSET [.SOPTI,,A] ; SET OPTION WORD + + MOVE A,[-TSINTL",,TSINT"] ; SET UP INTERRUPT HANDLING + MOVEM A,42 + MOVEI A,%PIMPV+%PIPDL ; ENABLE MPV AND PDL OVERFLOW + .SUSET [.SMASK,,A] + + ;SET UP UUO HANDLER + + MOVE A,[JSR UUOH"] + MOVEM A,41 + + MOVE P,PDLBOT ; STACK + MOVE TP,TPINIT ; TIME STACK (IF IN TIMING MODE) + MCALL $SETUP +IENTRY RESTART + MOVE P,PDLBOT + VCALL @CALLER,[ARGC,[[ARGV]]] + CALL CEXIT,[[[0]]] +IENTRY .EXIT + SETZM TIMING + SKIPE EXITER + VCALL @EXITER ; CLEAN-UP TIMING + .LOGOUT ; IN CASE WE ARE AT TOP LEVEL + .BREAK 16,160000 ; COMMIT SUICIDE + +; SETUP ROUTINE + +; TURN OFF TTY ECHOING, READ AND PARSE JCL COMMAND, +; GET JOB NAME, INITIALIZE I/O, OPEN TTY + +MENTRY $SETUP + + ; TURN OFF TTY ECHOING + + .SUSET [.RTTY,,A] ; READ TTY WORD + TLNE A,400000 ; TEST %TBNOT BIT + GO SET$0 ; DONT HAVE TTY + .OPEN 17,[SIXBIT/ TTY/] + GO SET$0 ; WHO CARES IF IT FAILS + .CALL [SETZ ; TURN OFF ECHOING + 'TTYSET + 1000,,17 + [020202020202] + SETZ [030202020202] + ] + JFCL + .CLOSE 17, + +SET$0: .CLOSE 1, ; HACK FOR TOP-LEVEL BOOTSTRAP + .CLOSE 2, + .CLOSE 3, + + ; READ JCL + + .SUSET [.ROPTI,,A] ; READ OPTION WORD + TLNN A,OPTCMD ; IS THERE SOME JCL + GO SET$2 ; NOPE + + SETZM JCLBUF ; FIRST WORD -- MAKE SURE ITS THERE + SETOM JCLBUF+-1 ; LAST WORD OF JCLBUF + .BREAK 12,[..RJCL,,JCLBUF] ; READ JCL + + ; READ JOB NAME + +SET$2: .SUSET [.RXJNAME,,XJNAME] + + ; PARSE JCL + + MCALL PRSARG,[[[440700,,JCLBUF]],[[ARGBUF]],[[ARGV]],XJNAME,[[MAXARG]]] + MOVEM A,ARGC + + CALL C0INIT ; INITIALIZE C I/O ROUTINES + CALL FXARG,[ARGC,[[ARGV]]] ; DO REDIRECTION OF STANDARD I/O + MOVEM A,ARGC + + .SUSET [.RTTY,,A] ; READ TTY WORD + TLNE A,400000 ; TEST %TBNOT BIT + GO SET$R ; RETURN IF DONT HAVE TTY + CALL TYIOPN ; ENABLE INTERRUPT CHARS +SET$R: RETURN + +IENTRY STKDMP + + PUSH P,0 ; SAVE REGISTERS + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,[0] ; PLACE TO SAVE 'REAL' RETURN ADDRESS + PUSH P,[0] ; ZERO ARG TO STKDMP + .VALUE [ASCIZ\..XECP/0/1Q +P\] + MOVEM 0,-1(P) ; SAVE AWAY 'REAL' RETURN ADDRESS + PUSHJ P,ZSTKDMP" + POP P,(P) + POP P,D + POP P,C + POP P,B + POP P,A + POP P,0 + POPJ P, + +; +; EXIT ROUTINES +; + +CENTRY CEXIT,[CC] + CALL CLOSALL + MOVE A,CC + GO .EXIT + +CENTRY CQUIT,[CC] + CROAK CQUIT CALLED + CALL CEXIT,[CC] + + +; CODE TO PERFORM LOAD-TIME INITIALIZATION +; FLUSHES ZERO PAGES IN IMPURE AREAS + +.IDATA +; NO LITERALS IN THIS CODE! + +IENTRY LBINIT ; INIT FOR MAKING LIBRARY + SETZM IFLUSH ; DON'T FLUSH ZERO-PAGES BECAUSE + ; MAKLIB EXPECTS THEM TO BE THERE + MOVE A,LBD1 ; RESET FLUSH-FLAG WHEN DONE + MOVEM A,IDONE + GO LINIT +LBD1: SETOM IFLUSH + +IENTRY LINIT + + MOVEI P,ARGV ; TEMPORARY PDL + +IENTRY ISTART + + JFCL + + ; SETUP SEGMENT BOUNDARIES + + HLRZ A,20 + MOVEM A,SEG0LO + HRRZ A,20 + MOVEM A,SEG0HI + SETZM 20 + HLRZ A,21 + MOVEM A,SEG1LO + HRRZ A,21 + MOVEM A,SEG1HI + SETZM 21 + HLRZ A,22 + MOVEM A,SEG2LO + HRRZ A,22 + MOVEM A,SEG2HI + SETZM 22 + HLRZ A,23 + MOVEM A,SEG3LO + HRRZ A,23 + MOVEM A,SEG3HI + SETZM 23 + + ; INITIALIZE PAGE-TABLE + + MOVEI A,256. +I$LOOP: SOJL A,I$SMSH ; A IS PAGE NUMBER + .CALL I$CORT ; GET PAGE INFO + .VALUE I$MES1 ; SYSTEM CALL LOST + MOVEM B,PAGTAB(A) + GO I$LOOP + + ; NOW LOOK FOR .CCALLS TO SMASH + +I$SMSH: SKIPE TIMING ; DON'T SMASH IF TIMING + GO I$FLSH + SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA +I$S1: ADDI A,1 ; NEXT WORD + CAML A,SEG2HI ; AT END OF CODE AREA? + GO I$PURE ; DONE + HLRZ B,(A) ; INSTRUCTION + TRZ B,000777 ; ISOLATE OPCODE + CAIE B,(.CCALL) ; IS IT A .CCALL? + GO I$S1 ; NO, GO ON + HLRZ B,(A) ; THE INSTRUCTION AGAIN + TRNN B,000037 ; IS INDEXING OR INDIRECTION USED + GO I$S6 ; NO, IT'S A CONSTANT CALL + TRZ B,777000 ; SMASH OPCODE + IORI B,(.VCALL) ; MAKE IT A .VCALL + HRLM B,(A) ; SMASH THE .CCALL + GO I$S1 ; GO ON TO NEXT WORD + +I$S6: HRRZ C,(A) ; THE CALLED PROCEDURE + JUMPE C,I$S1 ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO I$S1 ; NO, NOT A PROCEDURE + LDB B,[270400,,(A)] ; THE NUMBER OF ACTUAL ARGS + CAIE 0,(B) ; DO THE NUMBERS MATCH? + GO I$S2 ; NO + MOVEI B,(PUSHJ P,) + HRLM B,(A) ; SMASH .CCALL TO PUSHJ + GO I$S1 + + ; HERE IF NUMBER OF ACTUALS AND FORMALS ARE DIFFERENT + +I$S2: SUBI 0,(B) ; NUMBER OF EXTRA ACTUALS NEEDED + JUMPL 0,I$S5 ; TOO MANY ACTUALS GIVEN + MOVE B,0 + ADDI B,2 + CL I$ALLC ; ALLOCATE SPACE FOR PROG + HRRZ B,D ; ADDRESS OF BLOCK + HRLI B,(JSP D,) ; CONSTRUCT CALL TO IT + MOVEM B,(A) ; SMASH ORIGINAL CALL + SUBI D,1 +I$S3: SOJL 0,I$S4 ; FOR EACH MISSING ARG + PUSH D,PZERO ; COMPILE A PUSH OF ZERO + GO I$S3 +I$S4: PUSH D,PUSHD ; COMPILE A PUSH OF D (RETURN ADDRESS) + HRLI C,(GO) ; MAKE JUMP TO CALLED PROC + PUSH D,C ; COMPILE CALL + GO I$S1 ; FINISHED WITH THIS CALL + + ; HERE IF NUMBER OF ACTUALS EXCEEDS NUMBER OF FORMALS + +I$S5: MOVEI B,3 ; GET TWO WORDS + CL I$ALLC + HRRZ B,D ; ADDRESS OF BLOCK + HRLI B,(JSP D,) ; MAKE CALL TO IT + MOVEM B,(A) ; SMASH ORIGINAL CALL + MOVN B,0 ; NUMBER OF EXTRA ARGS + HRLI B,(SUBI P,) ; CONSTRUCT INSTRUCTION + MOVEM B,(D) ; STORE IN BLOCK + MOVE B,PUSHD + MOVEM B,1(D) + HRLI C,(GO) ; MAKE JUMP TO CALLED PROC + MOVEM C,2(D) ; STORE IN BLOCK + GO I$S1 ; FINISHED WITH THIS CALL + + ; NOW PURIFY HIGH SEGMENTS + +I$PURE: MOVE A,SEG2LO + TRZ A,1777 + MOVE B,SEG2HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PBLK + .VALUE I$MES4 + MOVE A,SEG3LO + TRZ A,1777 + MOVE B,SEG3HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PBLK + .VALUE I$MES4 + + ; NOW LOOK FOR ZERO-PAGES TO FLUSH + +I$FLSH: SKIPN IFLUSH + GO I$DONE + MOVEI A,0 ; FIRST PAGE IS 1 (CAN'T FLUSH 0!) +NXTPAG: ADDI A,1 ; CURRENT PAGE NUMBER + MOVE B,A + LSH B,10. ; POINTER TO FIRST WORD IN PAGE + CAMLE B,SEG1HI ; STILL IN IMPURE AREA? + GO I$DONE ; NO, DONE + SKIPN PAGTAB(A) ; DOES PAGE EXIST? + GO NXTPAG ; NO, TRY NEXT ONE +NXTWRD: SKIPE (B) ; IS THE WORD ZERO + GO NXTPAG ; NO, CAN'T FLUSH THIS PAGE + ADDI B,1 ; NEXT WORD + TRNE B,1777 ; IN NEXT PAGE? + GO NXTWRD ; NO, KEEP GOING + .CALL I$CORB ; YES, DELETE PAGE + .VALUE I$MES2 ; SYSTEM CALL LOST + GO NXTPAG ; GO ON TO NEXT PAGE + +I$DONE: + +IENTRY IDONE + + JFCL + SETZ A, ; CLEAN UP + SETZ B, ; LIKE A GOOD BOY SHOULD + SETZ C, + SETZ D, + .BREAK 16,0 ; RETURN TO LOADER + + ; STORAGE ALLOCATOR FOR .CCALL COMPILER + ; CALL WITH SIZE IN B + ; RETURNS ADDRESS IN D + +I$ALLC: MOVE D,SEG3HI ; TOP OF PATCH SPACE + ADDI D,1 ; POINT TO NEW BLOCK + ADDB B,SEG3HI ; NEW TOP OF PATCH SPACE + LSH B,-10. ; PAGE OF TOP OF PATCH SPACE + SKIPE PAGTAB(B) ; DOES PAGE EXIST? + RTN ; YES + .CALL I$GETB ; GET PAGE + .VALUE I$MES3 ; SYSTEM CALL LOST + SETOM PAGTAB(B) ; UPDATE PAGE TABLE + RTN ; RETURN + +MDATA TIMING + 0 + +IFLUSH: -1 ; FLUSH ZERO PAGES +I$CORT: SETZ ? 'CORTYP ? A ? 402000,,B +I$CORB: SETZ ? 'CORBLK ? 1000,,0 ? 1000,,%JSELF ? SETZ A +I$PBLK: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A +I$GETB: SETZ ? 'CORBLK ? 1000,,%CBNDR+%CBNDW ? 1000,,%JSELF ? + B ? 401000,,%JSNEW +I$MES1: ASCIZ/CORTYP FAILED/ +I$MES2: ASCIZ/PAGE-DELETE FAILED/ +I$MES3: ASCIZ/PAGE-GET FAILED/ +I$MES4: ASCIZ/PURIFY FAILED/ + +.CODE + +IENTRY FIXIFY + + JUMPL A,FIXL + FADR A,[.499999] + UFA A,[233000000000'] + TLZ B,777000' + JRST @0 +FIXL: MOVN A,A + FADR A,[.499999] + UFA A,[233000000000'] + TLZ B,777000' + MOVN B,B + JRST @0 + +; IMPURE AREA + +.IDATA + -1 ; THIS STUFF MUST NOT BE FLUSHED! +MDATA PAGTAB ; PAGE TABLE + BLOCK 256. +MDATA ARGV + BLOCK MAXARG ; POINTERS TO ARGS PLACED HERE +MDATA XJNAME + BLOCK 1 ; JOB NAME +MDATA SEG0LO + 0 +MDATA SEG0HI + 0 +MDATA SEG1LO + 0 +MDATA SEG1HI + 0 +MDATA SEG2LO + 0 +MDATA SEG2HI + 0 +MDATA SEG3LO + 0 +MDATA SEG3HI + 0 + ; END OF WIRED-DOWN STUFF (PROTECTED + ; ON THIS END BY CALLER) +MDATA CALLER + ZMAIN" ; C ROUTINE CALLED AS PROGRAM +MDATA PURBOT + 0 +MDATA PURTOP + 0 + +.UDATA +MDATA EXITER + BLOCK 1 ; EXIT ROUTINE (FOR TIMING) +ARGC: BLOCK 1 ; NUMBER OF ARGUMENTS TO MAIN +JCLBUF: BLOCK BUFSZ/5 ; JCL BUFFER +ARGBUF: BLOCK BUFSZ ; MAIN ARGS BUFFER +PDL: BLOCK PDLSIZ ; THE STACK +.IDATA +MDATA PDLBOT + PDL +MDATA PDLTOP + PDL+PDLSIZ-1 +.PDATA +MDATA PZERO + PUSH P,ZERO +MDATA ZERO + 0 +MDATA PUSHD + PUSH P,D +MDATA TPINIT ; SET BY TINIT + 0 + +CONSTANTS + +MDATA PATCH + +END START + \ No newline at end of file diff --git a/arc/ar5:c/C10SAV CMID b/arc/ar5:c/C10SAV CMID new file mode 100644 index 00000000..ca3840d9 --- /dev/null +++ b/arc/ar5:c/C10SAV CMID @@ -0,0 +1,44 @@ +; +; CSAVE - Routine to prepare for saving a program file +; +; This file is ITS dependent. +; This file contains the size of the shared library file. +; + +TITLE CSAVE +.INSRT NC +.INSRT NM + +.GLOBAL TYICHN,TYOCHN,PDLBOT,PDLTOP + +CENTRY CSAVE + + SETOM TYICHN + SETOM TYOCHN + MOVE A,[-10.,,246.] + .CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A] + ; DELETE SHARED LIBRARY PAGES + CROAK CORBLK FAILED + + ; DELETE STACK PAGES + + MOVE A,PDLBOT + ADDI A,1777 + TRZ A,1777 ; MOVE TO NEXT PAGE BOUNDARY + MOVE B,PDLTOP ; LAST WORD OF STACK + ADDI B,1 + TRZ B,1777 ; MOVE TO PREVIOUS PAGE BOUNDARY + LSH A,-10. + LSH B,-10. ; GET PAGE NUMBERS + SUB B,A ; NUMBER OF PAGES + MOVN B,B ; NEGATIVE NUMBER OF PAGES + HRL A,B ; MAKE COUNTING POINTER + + .CALL [SETZ ? 'CORBLK ? MOVEI 0 ? MOVEI %JSELF ? SETZ A] + CROAK CORBLK FAILED + + .VALUE [ASCIZ/:PDUMP /] + RETURN + +END + \ No newline at end of file diff --git a/arc/ar5:c/C10SFD C b/arc/ar5:c/C10SFD C new file mode 100644 index 00000000..cea578d4 --- /dev/null +++ b/arc/ar5:c/C10SFD C @@ -0,0 +1,25 @@ +/********************************************************************** + + SETFDIR - Set File Directory (and defaults) + (obsolete) + +**********************************************************************/ + +char *setfdir (buf, name, dir) + char *buf, *name, *dir; + + {filespec fs1, fs2; + char *p; + + fparse (name, &fs1); + fparse (dir, &fs2); + if (fs2.dir==0) fs2.dir=fs2.fn1; + if (fs2.dev) fs1.dev = fs2.dev; + else if (fs1.dev==0) fs1.dev=csto6("dsk"); + if (fs2.dir) fs1.dir = fs2.dir; + else if (fs1.dir==0) fs1.dir=rsname(); + p = prfile (&fs1, buf); + *p = 0; + return (buf); + } + \ No newline at end of file diff --git a/arc/ar5:c/C10SRY CMID b/arc/ar5:c/C10SRY CMID new file mode 100644 index 00000000..f6d8bcbe --- /dev/null +++ b/arc/ar5:c/C10SRY CMID @@ -0,0 +1,64 @@ +; +; C10SRY - CHANGE .VCALL'S TO PUSHJ'S +; +; This file is ITS dependent. +; This routine assumes a superior DDT. +; + +TITLE SORRY +.INSRT NC +.INSRT NM + +.GLOBAL SEG2LO,SEG2HI,SEG3LO,SEG3HI + +IENTRY SORRY + + .VALUE [ASCIZ/:UNPURE +P/] + +; MOVE A,SEG2LO +; TRZ A,1777 +; MOVE B,SEG2HI +; SUBI B,(A) +; LSH A,-10. +; ADDI B,1777 +; LSH B,-10. +; MOVN B,B +; HRL A,B +; .CALL I$IMPR +; .VALUE + + SKIPA A,SEG2LO ; POINTER TO BEGINNING OF CODE AREA +S1: ADDI A,1 ; NEXT WORD + CAML A,SEG2HI ; AT END OF CODE AREA? + GO DONE + HLRZ B,(A) ; INSTRUCTION + TRZ B,000777 ; ISOLATE OPCODE + CAIE B,(.VCALL) ; IS IT A .CCALL? + GO S1 ; NO, GO ON + HLRZ B,(A) ; THE INSTRUCTION AGAIN + TRZ B,777740 ; FLUSH OPCODE AND ACCUMULATOR + IORI B,(PUSHJ P,) ; MAKE IT A PUSHJ + HRLM B,(A) ; STORE IT + GO S1 + +DONE: MOVE A,SEG2LO + TRZ A,1777 + MOVE B,SEG3HI + SUBI B,(A) + LSH A,-10. + ADDI B,1777 + LSH B,-10. + MOVN B,B + HRL A,B + .CALL I$PURE + .VALUE + + .VALUE [ASCIZ/:PDUMP /] + .BREAK 16,0 + +.PDATA +I$PURE: SETZ ? 'CORBLK ? 1000,,%CBNDR ? 1000,,%JSELF ? 400000,,A +;I$IMPR: SETZ ? 'CORBLK ? 1000,,%CBRED+%CBWRT ? 1000,,%JSELF ? 400000,,A +END + \ No newline at end of file diff --git a/arc/ar5:c/C10STD C b/arc/ar5:c/C10STD C new file mode 100644 index 00000000..29e55ae1 --- /dev/null +++ b/arc/ar5:c/C10STD C @@ -0,0 +1,136 @@ +# include "c.defs" +# include "stdio.h" + +/********************************************************************** + + STDIO.C - 'Standard I/O' Simulator for ITS + + Must call STDIO to initialize. + +**********************************************************************/ + +int *stdin, *stdout, *stderr; +extern int cin, cout, cerr; + +stdio () + + {stdin = cin; stdout = cout; stderr = cerr; + on (ctrlg_interrupt, INT_IGNORE); + } + +flopen (name, mode) + char *name, *mode; + + {int f; + f = copen (name, mode[0]); + if (f == OPENLOSS) return (0); + return (f); + } + +int fgetc (f) + + {int c; + c = cgetc (f); + if (c < 0) return (EOF); + if (c == 0 && ceof (f)) return (EOF); + return (c); + } + +int fgeth () + + {return (fgetc (cin));} + +int peekc (f) + + {int c; + c = cgetc (f); + if (c < 0) return (EOF); + if (c == 0 && ceof (f)) return (EOF); + ungetc (c, f); + return (c); + } + +int pkchar () + + {return (peekc (cin));} + +printf (a, b, c, d, e, f, g) + {cprint (cout, a, b, c, d, e, f, g);} + +fprintf (a, b, c, d, e, f, g) + {cprint (a, b, c, d, e, f, g);} + +fclose (f) {cclose (f);} + +fread (f, buf, size, number) char buf[]; + + {int n; + n = size * number; + while (--n >= 0) *buf++ = cgetc (f); + } + +freopen (name, mode, f) char *name, *mode; + + {int i; + cclose (f); + i = copen (name, *mode); + return (i); + } + +/********************************************************************** + + STRING ROUTINES + +**********************************************************************/ + +strcmp (s1, s2) + char *s1, *s2; + + {int c1, c2; + while (TRUE) + {c1 = *s1++; + c2 = *s2++; + if (c1 < c2) return (-1); + if (c1 > c2) return (1); + if (c1 == 0) return (0); + } + } + +strcpy (dest, source) + char *dest, *source; + + {stcpy (source, dest);} + +strcat (dest, source) + char *dest, *source; + + {while (*dest) ++dest; + stcpy (source, dest); + } + +getuid () {return (rsuset (074));} + +getpw (w, buf) char *buf; + {c6tos (w, buf);} + +nowtime (tv) int tv[]; + {cal foo; + now (&foo); + tv[0] = tv[1] = cal2f (&foo); + } + +char *ctime (tv) int tv[]; + {static char buf[100]; + cal foo; + int f; + f2cal (tv[0], &foo); + f = copen (buf, 'w', "s"); + prcal (&foo, f); + cputc ('\n', f); + cclose (f); + return (buf); + } + +unlink (s) {delete (s);} +exit (cc) {cexit (cc);} + \ No newline at end of file diff --git a/arc/ar5:c/C10SYS CMID b/arc/ar5:c/C10SYS CMID new file mode 100644 index 00000000..688b217e --- /dev/null +++ b/arc/ar5:c/C10SYS CMID @@ -0,0 +1,728 @@ +; +; C10SYS - C LIBRARY ROUTINES (INTERFACES TO SYSTEM CALLS) +; +; This file is ITS dependent. +; + +TITLE C10SYS +.INSRT NC +.INSRT NM + +; CONTAINS: + +; SYSOPEN ; OPEN CHANNEL +; CLOSE ; CLOSE CHANNEL +; CHNLOC ; FIND AVAILABLE CHANNEL + +; UIIOT ; PERFORM UNIT INPUT IOT +; UOIOT ; PERFORM UNIT OUTPUT IOT +; SYSREAD ; PERFORM BLOCK INPUT IOT +; SYSWRITE ; PERFORM BLOCK OUTPUT IOT +; SIOT ; STRING IOT + +; SYSFINISH ; FORCE OUTPUT AND WAIT FOR COMPLETION +; SYSFORCE ; FORCE OUTPUT TO DEVICE + +; RESET ; RESET CHANNEL +; STATUS ; GET CHANNEL STATUS +; RFPNTR ; READ FILE ACCESS POINTER +; ACCESS ; PERFORM RANDOM ACCESS ON CHANNEL +; FILLEN ; GET FILE LENGTH +; FILNAM ; GET FILE NAME FROM CHANNEL + +; RAUTH ; READ FILE AUTHOR +; SAUTH ; SET FILE AUTHOR +; RDMPBT ; READ DUMP BIT +; SDMPBT ; SET DUMP BIT +; SREAPB ; SET DO-NOT-REAP BIT +; RFDATE ; READ FILE CREATION DATE +; SFDATE ; SET FILE CREATION DATE +; SRDATE ; SET FILE REFERENCE DATE +; DSKUPD ; UPDATE FILE INFO +; RESRDT ; RESTORE FILE INFO + +; TTYGET ; GET TTY STATUS +; TTYSET ; SET TTY STATUS +; CNSGET ; GET CONSOLE PARAMETERS +; CNSSET ; SET CONSOLE PARAMETERS + +; ITYIC ; READ TTY INTERRUPT CHARACTER +; WHYINT ; WHY WAS I INTERRUPTED? +; SYSLISTEN ; LISTEN FOR TTY INPUT +; RCPOS ; READ CURSOR POSITION +; SCML ; SET # OF COMMAND LINES + +; GETCPU ; RETURN CPU TIME IN 4.069 USEC +; CPUTM ; RETURN CPU TIME IN 1/60 SECONDS +; SLEEP ; GO TO SLEEP +; ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT +; NOW ; GET CURRENT DATE AND TIME + +; CORBLK ; PERFORM PAGE HACKING +; CORTYP ; GET INFORMATION ABOUT PAGE +; PAGEID ; GET NAMED PUBLIC PAGE +; PGWRIT ; CAUSE PAGE TO BE WRITTEN ON DISK + +; RSNAME ; READ SNAME +; SSNAME ; SET SNAME +; RUNAME ; READ USER NAME +; RSUSET ; WHAT = RSUSET (WHERE) +; WSUSET ; WHAT = WSUSET (WHERE, WHAT) +; RUSET ; WHAT = RUSET (WHO, WHERE) +; WUSET ; WHAT = WUSET (WHO, WHERE, WHAT) +; WUSRVAR ; RC = WUSRVAR (JOB, SPEC, VALUE) + +; DELETE ; DELETE A FILE +; SYSDEL ; DELETE FILE +; RENMWO ; RENAME FILE OPEN FOR OUTPUT +; SYSRNM ; EC = SYSRNM (FS1, FS2) +; SYSLNK ; EC = MAKE LINK (FS1, FS2) +; DIRSIZ ; READ DIRECTORY SIZE, QUOTA INFO + +; TRANAD ; RC = TRANAD (JOB, FROM, TO, FLAGS) +; TRANCL ; RC = TRANCL (JOB, FLAGS) +; TRANDL ; RC = TRANDL (JOB, FILESPEC, FLAGS) + +; SYSLOAD ; LOAD A PROGRAM +; PDUMP ; PDUMP A PROGRAM +; UCLOSE ; DESTROY INFERIOR JOB +; SYSDISOWN ; EC = SYSDISOWN (JOBCH) +; REOWN ; EC = REOWN (JOBCH) +; SYSDTACH ; EC = SYSDTACH (JOBCH) +; SYSATACH ; EC = SYSATACH (JOBCH, TTY) + +; ATTY ; GIVE TTY TO INFERIOR +; DTTY ; TAKE TTY FROM INFERIOR + +; WFNZ ; WAIT FOR WORD TO BECOME NON-ZERO +; WFZ ; WAIT FOR WORD TO BECOME ZERO +; VAL7RET ; VALRET AN ASCIZ STRING +; DEMSIG ; SIGNAL A DEMON PROCESS +; SSTATUS ; OBTAIN SYSTEM STATUS + +; MAKTAG ; CREATE A TAG (GLOBAL LABEL) +; GOTAG ; GOTO A TAG, DISMISSING INTERRUPTS + +CENTRY SYSOPEN,[CHAN, FILSPC, MODE] ; OPEN CHANNEL + + HRLZ B,MODE + HRR B,CHAN + HRRZ C,FILSPC + SYSCAL OPEN,[B ? (C) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY CLOSE,[CHAN] ; CLOSE CHANNEL + + SYSCAL CLOSE,[CHAN] + RETURN + +CENTRY CHNLOC ; FIND AVAILABLE CHANNEL + +FIRSTC==1 ; CHANGE TO 0 IF SYSTEM FIXED SO THAT + ; CHANNEL 0 IS NOT ARBITRARILY SMASHED + ; BY .CALL MLINK, ETC. + + MOVEI B,FIRSTC +CL$1: SYSCAL RFNAME,[B ? 2000,,C] + JUMPE C,CL$2 ; CHANNEL NOT OPEN + ADDI B,1 + CAIGE B,20 + GO CL$1 + SETO A, + GO CL$RET +CL$2: MOVE A,B +CL$RET: RETURN + +CENTRY UIIOT,[CHAN] ; PERFORM UNIT INPUT IOT + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.IOT A] + XCT A + RETURN + +CENTRY UOIOT,[CHAN,DATA] ; PERFORM UNIT OUTPUT IOT + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.IOT DATA] + XCT A + MOVE A,DATA + RETURN + +CENTRY SYSREAD,[CHAN,BUFFP,NWORDS] ; PERFORM BLOCK INPUT IOT +XENTRY SYSWRITE,SYSREAD ; PERFORM BLOCK OUTPUT IOT + + MOVN A,NWORDS ; MINUS NUMBER OF WORDS + HRLZ 0,A + HRR 0,BUFFP ; SET UP CPTR + MOVE C,CHAN + ANDI C,17 + LSH C,23. + IOR C,[.IOT 0] + XCT C + HLRE C,0 ; NEW COUNTER + SUB C,A ; NUMBER OF WORDS WRITTEN/READ + MOVE A,C + RETURN + +CENTRY SIOT,[CHAN,BYTP,NBYTES] ; STRING IOT + + SYSCAL SIOT,[CHAN ? BYTP ? NBYTES],SI$LOS + MOVE A,NBYTES +SI$RET: RETURN +SI$LOS: CROAK SIOT LOST + GO SI$RET + +CENTRY SYSFINISH,[CHAN] + + SYSCAL FINISH,[CHAN] + RETURN + +CENTRY SYSFORCE,[CHAN] + + SYSCAL FORCE,[CHAN] + RETURN + +CENTRY RESET,[CHAN] ; RESET CHANNEL + + MOVE A,CHAN + ANDI A,17 + LSH A,23. + IOR A,[.RESET] + XCT A + SETZ A, + RETURN + +CENTRY STATUS,[CHAN] ; GET CHANNEL STATUS + + MOVE A,CHAN + LSH A,23. + IOR A,[.STATUS A] + XCT A + RETURN + +CENTRY RFPNTR,[CHAN] ; READ FILE ACCESS POINTER + + SYSCAL RFPNTR,[CHAN ? MOVEM B],RP$LOS + MOVE A,B +RP$RET: RETURN +RP$LOS: MOVN A,A + GO RP$RET + +CENTRY ACCESS,[CHAN,POS] ; PERFORM RANDOM ACCESS ON CHANNEL + + SYSCAL ACCESS,[CHAN ? POS] + RETURN + +CENTRY FILLEN,[CHAN] ; GET FILE LENGTH + + SYSCAL FILLEN,[CHAN ? 2000,,B],FL$LOS + MOVE A,B +FL$RET: RETURN +FL$LOS: MOVN A,A + GO FL$RET + +CENTRY FILNAM,[CHAN,FILSPC] ; GET FILE NAME FROM CHANNEL + + HRLZ B,CHAN ; CHANNEL + HRR B,FILSPC ; FILESPEC FOR RESULTS + MOVE C,4(B) ; SAVE 5TH WORD + .RCHST B, ; READ CHANNEL STATUS + HRLZS (B) ; LEFT ADJUST DEV + MOVEM C,4(B) ; RESTORE 5TH WORD + RETURN ; DONE + +CENTRY RAUTH,[CHAN] + + SYSCAL RAUTH,[CHAN ? MOVEM B],RA$LOS + MOVE A,B +RA$RET: RETURN +RA$LOS: MOVN A,A + GO RA$RET + +CENTRY SAUTH,[CHAN,AUTHOR] + + SYSCAL SAUTH,[CHAN ? AUTHOR] + RETURN + +CENTRY RDMPBT,[CHAN] + + SYSCAL RDMPBT,[CHAN ? MOVEM B],RD$LOS + MOVE A,B +RD$RET: RETURN +RD$LOS: MOVN A,A + GO RD$RET + +CENTRY SDMPBT,[CHAN,BIT] + + SYSCAL SDMPBT,[CHAN ? BIT] + RETURN + +CENTRY SREAPB,[CHAN,BIT] + + SYSCAL SREAPB,[CHAN ? BIT] + RETURN + +CENTRY RFDATE,[CHAN] ; READ FILE CREATION DATE + + SYSCAL RFDATE,[CHAN ? 2000,,B],RF$LOS + MOVE A,B +RF$RET: RETURN +RF$LOS: MOVN A,A + GO RF$RET + +CENTRY SFDATE,[CHAN,FDATE] ; SET FILE CREATION DATE + + SYSCAL SFDATE,[CHAN ? FDATE] + RETURN + +CENTRY SRDATE,[CHAN,FDATE] ; SET FILE REFERENCE DATE + + SYSCAL SRDATE,[CHAN ? FDATE] + RETURN + +CENTRY DSKUPD,[CHAN] + + SYSCAL DSKUPD,[CHAN] + RETURN + +CENTRY RESRDT,[CHAN] + + SYSCAL RESRDT,[CHAN] + RETURN + +CENTRY TTYGET,[CHAN,BLOCK] ; GET TTY STATUS - WRITES 3 VALUES + + HRRZ B,BLOCK + SYSCAL TTYGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B)] + RETURN + +CENTRY TTYSET,[CHAN,BLOCK] ; SET TTY STATUS - READS 3 VALUES + + HRRZ B,BLOCK + SYSCAL TTYSET,[CHAN ? (B) ? 1(B) ? 2(B)] + RETURN + +CENTRY CNSGET,[CHAN,BLOCK] ; GET CONSOLE STATUS - WRITES 5 VALUES + + HRRZ B,BLOCK + SYSCAL CNSGET,[CHAN ? MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B) + MOVEM 3(B) ? MOVEM 4(B)] + RETURN + +CENTRY CNSSET,[CHAN,BLOCK] ; SET CONSOLE STATUS - READS 5 VALUES + + HRRZ B,BLOCK + SYSCAL CNSSET,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)] + RETURN + +CENTRY WHYINT,[CHAN,BLOCK] + + HRRZ B,BLOCK + SYSCAL WHYINT,[CHAN ? (B) ? 1(B) ? 2(B) ? 3(B) ? 4(B)] + RETURN + +CENTRY ITYIC,[CHAN] ; READ TTY INTERRUPT CHARACTER + + MOVE A,CHAN ; CHANNEL + .ITYIC A, + SETO A, + RETURN + +CENTRY SYSLISTEN,[CHAN] ; NCHARS = SYSLISTEN(CHAN) + + SYSCAL LISTEN,[CHAN ? MOVEM B],LI$LOS + MOVE A,B +LI$RET: RETURN +LI$LOS: MOVN A,A + GO LI$RET + +CENTRY RCPOS,[CHAN] ; READ TTY CURSOR POSITION (V,,H) + + SYSCAL RCPOS,[CHAN ? 2000,,B],RC$LOS + MOVE A,B +RC$RET: RETURN +RC$LOS: MOVN A,A + GO RC$RET + +CENTRY SCML,[CHAN,NUMBER] + + SYSCAL SCML,[CHAN ? NUMBER] + RETURN + +CENTRY GETCPU ; RETURN CPU TIME IN 4.069 USEC + + .SUSET [24,,A] + RETURN + +CENTRY CPUTM ; RETURN CPU TIME IN 1/60 SECONDS + + .SUSET [24,,A] + LSH A,-12. + RETURN + +CENTRY SLEEP,[TIME] ; GO TO SLEEP + + MOVE A,TIME + .SLEEP A, + RETURN + +CENTRY ETIME ; RETURN A TIME FOR ELAPSED TIME MEASUREMENT + + .RDTIME A, + LSH A,1 + RETURN + +CENTRY NOW,[PCAL] ; GET CURRENT DATE AND TIME + + HRRZ D,PCAL ; CAL POINTER + .RDATE C, + LDB A,[360600,,C] ; HIGH-ORDER YEAR SIXBIT + SUBI A,20 + IMULI A,10. + LDB B,[300600,,C] ; LOW-ORDER YEAR SIXBIT + SUBI B,20 + ADDI A,1900.(B) ; YEAR + MOVEM A,(D) + + LDB A,[220600,,C] ; HIGH-ORDER MONTH + SUBI A,20 + IMULI A,10. + LDB B,[140600,,C] ; LOW-ORDER MONTH + SUBI B,20 + ADDI A,(B) + MOVEM A,1(D) ; MONTH + + LDB A,[060600,,C] ; HIGH-ORDER DAY + SUBI A,20 + IMULI A,10. + LDB B,[000600,,C] ; LOW-ORDER DAY + SUBI B,20 + ADDI A,(B) + MOVEM A,2(D) ; DAY + + .RTIME C, + LDB A,[360600,,C] ; HIGH-ORDER HOUR + SUBI A,20 + IMULI A,10. + LDB B,[300600,,C] ; LOW-ORDER HOUR + SUBI B,20 + ADDI A,(B) + MOVEM A,3(D) ; HOUR + + LDB A,[220600,,C] ; HIGH-ORDER MINUTE + SUBI A,20 + IMULI A,10. + LDB B,[140600,,C] ; LOW-ORDER MINUTE + SUBI B,20 + ADDI A,(B) + MOVEM A,4(D) ; MINUTE + + LDB A,[060600,,C] ; HIGH-ORDER SECOND + SUBI A,20 + IMULI A,10. + LDB B,[000600,,C] ; LOW-ORDER SECOND + SUBI B,20 + ADDI A,(B) + MOVEM A,5(D) ; SECOND + + MOVEI A,(D) + RETURN + +CENTRY CORBLK,[A1,A2,A3,A4,A5] ; PERFORM PAGE HACKING + + SYSCAL CORBLK,[A1 ? A2 ? A3 ? A4 ? A5] + RETURN + +CENTRY CORTYP,[PAGNO,OUTPUT] ; GET INFORMATION ABOUT PAGE + + MOVE B,OUTPUT + SYSCAL CORTYP,[PAGNO ? 2000,,(B) ? 2000,,1(B) ? 2000,,2(B) + 2000,,3(B)] + RETURN + +CENTRY PAGEID,[VPN,IDN] ; GET NAMED PUBLIC PAGE + + SYSCAL PAGEID,[VPN ? IDN ? 2000,,B],PI$LOS + MOVE A,B +PI$RET: RETURN +PI$LOS: MOVN A,A + GO PI$RET + +CENTRY PGWRIT,[JOB,VPN] + + SYSCAL PGWRIT,[JOB ? VPN] + RETURN + +CENTRY RSNAME ; READ SNAME + + .SUSET [.RSNAM,,A] + RETURN + +CENTRY SSNAME,[NAME] ; SET SNAME + + MOVE A,NAME + .SUSET [.SSNAM,,A] + RETURN + +CENTRY RUNAME ; READ USER NAME + + .SUSET [.RUNAM,,A] + RETURN + +CENTRY RSUSET,[WHERE] + + HRLZ A,WHERE + TLZ A,600000 ; CLEAR DIRECTION AND BLOCK BITS + ADDI A,A ; RESULT TO A + .SUSET A ; DO IT + RETURN + +CENTRY WSUSET,[WHERE,WHAT] + + HRLZ B,WHERE + TLO B,400000 ; SET DIRECTION BIT + TLZ B,200000 ; CLEAR BLOCK BIT + ADDI B,A ; TAKE WORD FROM A + MOVE A,WHAT + .SUSET B ; DO IT + RETURN + +CENTRY RUSET,[WHO,WHERE] + + HRLZ B,WHERE + TLZ B,600000 ; CLEAR DIRECTION AND BLOCK BITS + ADDI B,A ; RESULT TO A + HRRZ A,WHO + ANDI A,17 ; CHANNEL NUMBER + LSH A,23. + IOR A,[.USET B] + XCT A ; DO IT + RETURN + +CENTRY WUSET,[WHO,WHERE,WHAT] + + HRLZ B,WHERE + TLO B,400000 ; SET DIRECTION BIT + TLZ B,200000 ; CLEAR DIRECTION BIT + ADDI B,A ; TAKE WORD FROM A + HRRZ C,WHO + ANDI C,17 ; CHANNEL NUMBER + LSH C,23. + IOR C,[.USET B] + MOVE A,WHAT + XCT C ; DO IT + RETURN + +CENTRY WUSRVAR,[JOB,SPEC,VALUE] + + SETZ A, + SYSCAL USRVAR,[JOB ? SPEC ? VALUE] + RETURN + +CENTRY DELETE,[FILNAM],[FDEV,FDIR,FFN1,FFN2] ; DELETE A FILE + + MOVEI A,FDEV ; POINTER TO FILESPEC + CALL FPARSE,[FILNAM,A] ; CONSTRUCT FILESPEC + MOVEI A,FDEV + CALL SYSDELETE,[A] ; DELETE THAT FILE + RETURN + +CENTRY SYSDELETE,[FILSPC] ; DELETE FILE + + MOVE B,FILSPC ; ADDRESS OF FILESPEC BLOCK + HRLZI C,(SIXBIT/DSK/) + SKIPN (B) + MOVEM C,(B) + .SUSET [.RSNAM,,C] + SKIPN 3(B) + MOVEM C,3(B) + SYSCAL DELETE,[(B) ? 1(B) ? 2(B) ? 3(B)] + RETURN + +CENTRY RENMWO,[CHAN,FILSPC] ; RENAME FILE OPEN FOR OUTPUT + + HRRZ B,FILSPC + SYSCAL RENMWO,[CHAN ? 1(B) ? 2(B)] + RETURN + +CENTRY SYSRNM,[FILSP1,FILSP2] + + HRRZ B,FILSP1 + HRRZ C,FILSP2 + SYSCAL RENAME,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY SYSLNK,[FILSP1,FILSP2] + + HRRZ B,FILSP1 + HRRZ C,FILSP2 + SYSCAL MLINK,[(B) ? 1(B) ? 2(B) ? 3(B) ? 1(C) ? 2(C) ? 3(C)] + RETURN + +CENTRY DIRSIZ,[CHAN,BLOCK] ; WRITES 2 VALUES + + HRRZ B,BLOCK + SYSCAL DIRSIZ,[CHAN ? (B) ? 1(B)] + RETURN + +CENTRY TRANAD,[JOB,FROM,TO,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + HRRZ C,FROM ; FROM FILESPEC + HRLI C,-4 ; MAKE IT A CPTR + HRRZ D,TO ; TO FILESPEC + HRLI D,-4 ; MAKE IT A CPTR + SYSCAL TRANAD,[B ? C ? D] + RETURN + +CENTRY TRANCL,[JOB,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + SKIPN FLAGS + HRLI B,300003 ; DEFAULT FLAGS + SYSCAL TRANCL,[B] + RETURN + +CENTRY TRANDL,[JOB,FILSPC,FLAGS] + + HRRZ B,JOB + HRL B,FLAGS + HRRZ C,FILSPC + HRLI C,-4 ; MAKE IT A CPTR + SYSCAL TRANDL,[B ? C] + RETURN + +CENTRY SYSLOAD,[JOB,CHAN],[RCODE,OLDIOC] ; LOAD A PROGRAM + + SETZM RCODE + CALL ON,[[[2]],[[1]]] + MOVEM A,OLDIOC + + SYSCAL LOAD,[JOB ? CHAN],LD$LOS +LD$1: CALL ON,[[[2]],OLDIOC] + MOVE A,RCODE + RETURN +LD$LOS: SETOM RCODE + GO LD$1 + +CENTRY PDUMP,[JOBCH,DSKCH] + + SETZ B, + SYSCAL PDUMP,[JOBCH ? DSKCH ? B] + RETURN + +CENTRY UCLOSE,[JCHAN] ; DESTROY INFERIOR JOB + + MOVE A,JCHAN + ANDI A,17 + LSH A,23. + IOR A,[.UCLOSE] + XCT A + RETURN + +CENTRY SYSDISOWN,[JCHAN] + + SYSCAL DISOWN,[JCHAN] + RETURN + +CENTRY REOWN,[JCHAN] + + SYSCAL REOWN,[JCHAN] + RETURN + +CENTRY SYSDTACH,[JCHAN] + + SYSCAL DETACH,[JCHAN] + RETURN + +CENTRY SYSATACH,[JCHAN,TTY] ; TTY<0 => DEFAULT + + SKIPGE TTY + GO AT$1 + SYSCAL ATTACH,[JCHAN ? TTY] +AT$RET: RETURN +AT$1: SYSCAL ATTACH,[JCHAN] + GO AT$RET + +CENTRY ATTY,[JOB] ; GIVE TTY TO INFERIOR + + MOVE B,JOB + ANDI B,17 + LSH B,23. + IOR B,[.ATTY] + SETZ A, + XCT B + SETO A, + RETURN + +CENTRY DTTY,[JOB] ; TAKE TTY FROM INFERIOR + + MOVE B,JOB + ANDI B,17 + LSH B,23. + IOR B,[.DTTY] + SETZ A, + XCT B + SETO A, + RETURN + +CENTRY WFNZ,[PTR] ; WAIT FOR WORD TO BECOME NON-ZERO + + MOVE A,PTR + SKIPN (A) + .HANG + MOVE A,(A) + RETURN + +CENTRY WFZ,[PTR] ; WAIT FOR WORD TO BECOME ZERO + + MOVE A,PTR + SKIPE (A) + .HANG + MOVE A,(A) + RETURN + +CENTRY VAL7RET,[STR] ; VALRET AN ASCIZ STRING + + HRRZ A,STR + HRLI A,(.VALUE) + XCT A + RETURN + +CENTRY DEMSIG,[DEMON] ; SIGNAL A DEMON PROCESS + + SYSCAL DEMSIG,[DEMON] + RETURN + +CENTRY SSTATUS,[VALBLK] ; RETURNS 7 VALUES + + HRRZ B,VALBLK + SYSCAL SSTATUS,[MOVEM (B) ? MOVEM 1(B) ? MOVEM 2(B) + MOVEM 3(B) ? MOVEM 4(B) ? MOVEM 5(B) ? MOVEM 6(B)] + RETURN + +CENTRY MAKTAG,[TAGP] + + HRRZ A,TAGP ; TAG POINTER + MOVE B,(P) ; RETURN PC + MOVEM B,(A) ; SAVE RETURN PC + MOVEI B,-2(P) ; STACK POINTER BEFORE CALL + MOVEM B,1(A) ; SAVE STACK POINTER + RETURN + +CENTRY GOTAG,[TAGP] + + MCALL DISMISS + MOVE A,TAGP + MOVE P,1(A) + HRRZ D,(A) + GO (D) + +END + \ No newline at end of file diff --git a/arc/ar5:c/C10TAP CMID b/arc/ar5:c/C10TAP CMID new file mode 100644 index 00000000..88b423bf --- /dev/null +++ b/arc/ar5:c/C10TAP CMID @@ -0,0 +1,197 @@ +; +; C10TAP - MAG TAPE INTERFACE +; +; This file is ITS dependent. +; + +TITLE C10TAPE +.INSRT NC +.INSRT NM + +TAPIN==17 ; TAPE CHANNEL +TPIBSZ==200 ; SIZE OF TAPE INPUT BUFFER +TPBFSZ==2000 ; SIZE OF TAPE OUTPUT BUFFER + +CENTRY RWND8 ; REWIND TAPE, LEAVE OPEN FOR READ + + .CLOSE TAPIN, + .OPEN TAPIN,[033726,,(SIXBIT/MT0/)] + CROAK UNABLE TO OPEN TAPE FOR READING + MOVE 0,[TAPIN,,[1]] + .MTAPE 0, + JFCL + SETZM CURBLOCK + RETURN + +CENTRY OPEN8 ; OPEN TAPE FOR 8-BIT READ + + MOVE A,TAPECH + CAILE A,0 + GO OP$RTN + CALL RWND8 + SETZM TPICNT + SETZM TPIEOF + SETOM CURBLOCK + MOVEI 0,1 + MOVEM 0,TAPECH +OP$RTN: RETURN + +CENTRY OPNW8 ; OPEN TAPE FOR 8-BIT WRITE + + CALL RWND8 + .OPEN TAPIN,[033707,,(SIXBIT/MT0/)] + CROAK UNABLE TO OPEN TAPE FOR WRITING + MOVEI A,2*TPBFSZ + MOVEM A,TPICNT + MOVE A,[442000,,TPIBUF] + MOVEM A,TPIBFP + SETOM TAPECH + RETURN + +CENTRY GET16 ; READ 16-BITS + + SOSGE TPICNT + CL TPREAD + ILDB A,TPIBFP + ILDB B,TPIBFP + LSH B,10 + IOR A,B + MOVE B,A + ADD B,CHECKSUM + ANDI B,0177777 + MOVEM B,CHECKSUM + RETURN + +CENTRY PUT16,[W] ; WRITE 16 BITS + + MOVE C,W + SOSGE TPICNT ; ANY ROOM ? + CL WRTAPE ; NO, FLUSH BUFFER + MOVE B,C + ADD B,CHECKSUM + ANDI B,0177777 + MOVEM B,CHECKSUM + MOVE B,C + LSH B,-10 + ANDI B,0377 + LSH C,10 + ANDI C,177400 + IOR B,C + MOVE C,B + IDPB C,TPIBFP + RETURN + +CENTRY SEEK8,[ACC] ; RANDOM ACCESS + + SETZM CHARINBUF ; CLEAR GET8 BUFFER + MOVE A,ACC + MOVE B,A + SUB A,CURBLOCK + CAIE A,0 + GO L1 + +; HERE IF DESIRED BLOCK IS IN BUFFER + + MOVEI A,2*TPIBSZ + MOVEM A,TPICNT + MOVE A,[441000,,TPIBUF] + MOVEM A,TPIBFP +SE$RET: RETURN + +L1: SUBI A,1 ; NUMBER OF BLOCKS TO SKIP + SETZM TPICNT + CAIN A,0 + GO SE$RET ; WANT NEXT BLOCK, NOTHING TO SKIP + +; HERE IF NECESSARY TO SKIP SOME BLOCKS + + HRLZ C,A + HRLZI A,TAPIN + HRRI A,C + HRRI C,6 + .MTAPE A, + JFCL + SUBI B,1 + MOVEM B,CURBLOCK + RETURN + +CENTRY CLOS8 ; CLOSE TAPE + + SKIPGE TAPECH + CL FLUSH8 ; FLUSH BUFFER + CALL RWND8 + .CLOSE TAPIN, + SETZM TAPECH + RETURN + +CENTRY EOF8 ; TEST FOR END-OF-FILE + + MOVE A,TPIEOF + RETURN + +; *** BUFFERED I/O ROUTINES *** + +; TPICNT - NUMBER OF 16-BIT INTEGERS IN BUFFER +; TPIBFP - ABPTR TO NEXT 16-BIT INTEGER IN BUFFER +; TPIBUF - THE BUFFER +; TPIEOF - -1 IF END-OF-FILE + +TPR1: SOSL TPICNT + RTN +TPREAD: MOVEI A,2*TPIBSZ + MOVEM A,TPICNT + MOVE A,[441000,,TPIBUF] + MOVEM A,TPIBFP + MOVEI A,TPIBUF + HRLI A,-TPIBSZ + AOS CURBLOCK + .IOT TAPIN,A + JUMPGE A,TPR1 + HLRES A + ADDI A,TPIBSZ + JUMPE A,TPR2 ; END OF FILE + LSH A,1 + MOVEM A,TPICNT + GO TPR1 +TPR2: SETOM TPIEOF + SETZM TPIBUF + RTN + +FLUSH8: MOVEI A,2*TPBFSZ ; FLUSH (MAYBE UNFILLED) BUFFER + SUB A,TPICNT + ADDI A,1 + LSH A,-1 + MOVN A,A + HRLZ A,A + SKIPA + +WRTAPE: HRLZI A,-TPBFSZ ; THIS IS SKIPPED FROM FLUSH8 + HRRI A,TPIBUF + .IOT TAPIN,A ; WRITE BUFFER + MOVEI A,2*TPBFSZ-1 + MOVEM A,TPICNT + MOVE A,[442000,,TPIBUF] + MOVEM A,TPIBFP + RTN + +; *** BUFFERED I/O VARIABLES *** + +.UDATA +TAPECH: BLOCK 1 ; 0 - CLOSED + ; 1 - OPEN FOR READ + ; -1 - OPEN FOR WRITE + +TPICNT: BLOCK 1 ; TAPE I/O VARIABLES +TPIBFP: BLOCK 1 +TPIEOF: BLOCK 1 +TPIBUF: BLOCK TPBFSZ + +MDATA CURBLOCK + BLOCK 1 +MDATA CHECKSUM + BLOCK 1 +MDATA CHARINBUF + BLOCK 1 + +END + \ No newline at end of file diff --git a/arc/ar5:c/C10TMM CMID b/arc/ar5:c/C10TMM CMID new file mode 100644 index 00000000..5e886a32 --- /dev/null +++ b/arc/ar5:c/C10TMM CMID @@ -0,0 +1,111 @@ +; +; C10TMM - Program to determine the timing constants for +; the C timing package (C10TMR). The computed +; times are left in TIME1, TIME2, TIME3. Times +; are in nanoseconds. +; +; This file is ITS dependent. +; This is a stand-alone program. +; + +A==1 +B==2 +C==3 +D==4 +P==17 +CL==PUSHJ P, +RTN==POPJ P, +GO==JRST +.CCALL==1_27. + +TP"=16 ; TIME STACK POINTER +%TPROC==0 ; THE PROCEDURE POINTER +%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE) +%TNCAL==2 ; THE NUMBER OF CALLS +%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME +%TSIZE==4 ; SIZE OF TIME TABLE ENTRY +%FTABL==0 ; POINTER TO TIME TABLE ENTRY +%FTIME==1 ; ACCUMULATED OR START TIME +%FRTNA==2 ; ACTUAL RETURN ADDRESS +%FSIZE==3 ; SIZE OF STACK FRAME + +TIME1: 0 +TIME2: 0 +TIME3: 0 +TIME4: 0 + +START: MOVE P,[-2000,,PDL] + MOVE A,[JSR UUOH] + MOVEM A,41 + .SUSET [24,,TIME1] + CL TSUSET + .SUSET [24,,TIME2] + CL TUUO + .SUSET [24,,TIME3] + CL TEPILOG + .SUSET [24,,TIME4] + MOVE A,TIME2 + SUB A,TIME1 + IMULI A,4069. + IDIVI A,1000. + MOVEM A,TIME1 + MOVE A,TIME3 + SUB A,TIME2 + IMULI A,4069. + IDIVI A,1000. + MOVEM A,TIME2 + MOVE A,TIME4 + SUB A,TIME3 + IMULI A,4069. + IDIVI A,500. + MOVEM A,TIME3 + SETZM TIME4 + .VALUE + +TSUSET: REPEAT 1000.,[.SUSET [24,,C] +] + RTN + +TUUO: REPEAT 1000.,[ + .CCALL 2,0 + ] + RTN + +UUOH: 0 + GO UUO$HANDLER + +UUO$HANDLER: + + MOVEM D,USAVED + LDB D,[330500,,ZERO] + GO @UUOH(D) + +USAVED: 0 +ZERO: 0 +BAR: -1 +BAR2: 0 + 0 + 0 +BAR3: 0 + 0 + 0 + 0 + +TEPILOG: + MOVEI TP,BAR2 + MOVEI B,BAR3 + MOVEI A,0 + REPEAT 500.,[ + MOVE 0,C + SUBI C,37 + SUB C,%FTIME(TP) + MOVE C,%FTABL(TP) + ADDM C,%TTIME(B) + SUBI TP,%FSIZE + ADDI 0,37 + SUBM 0,%FTIME(TP) + GO @[.+1](A) ; TO NEXT LOCATION + ] + RTN +PDL: BLOCK 2000 +END START diff --git a/arc/ar5:c/C10TMR CMID b/arc/ar5:c/C10TMR CMID new file mode 100644 index 00000000..23dd9981 --- /dev/null +++ b/arc/ar5:c/C10TMR CMID @@ -0,0 +1,150 @@ +; +; TIMER - Version of runtime to time procedure calls +; +; This file is ITS dependent. +; (Dependency is system-call to get runtime.) +; + +TITLE TIMER +.INSRT NC +.INSRT NM + +TIMSIZ==1000. +IF1,[ +KLFLAG==0 +PRINTX \KL10 (YES/NO)? \ +.TTYMAC TIMEQ +IFSE TIMEQ,YES,KLFLAG==1 +TERMIN +] + +TP"=16 ; TIME STACK POINTER + +; TIME TABLE ENTRY WORDS + +%TPROC==0 ; THE PROCEDURE POINTER +%TNAME==1 ; THE PROCEDURE NAME (SNARFED FROM PROCEDURE) +%TNCAL==2 ; THE NUMBER OF CALLS +%TTIME==3 ; THE TOTAL AMOUNT OF ACCUMULATED TIME +%TSIZE==4 ; SIZE OF TIME TABLE ENTRY + +; TIME STACK FRAME WORDS + +%FTABL==0 ; POINTER TO TIME TABLE ENTRY +%FTIME==1 ; ACCUMULATED OR START TIME +%FRTNA==2 ; ACTUAL RETURN ADDRESS +%FSIZE==3 ; SIZE OF STACK FRAME + +; TIMING CONSTANTS (IN NANOSECONDS) +; COMPUTED BY PROGRAM 'TTIMM' + +IFE KLFLAG,[ +SUSTIM==387909. ;TIME FOR .SUSET +UUOTIM==27929. ;TIME FOR UUO DISPATCH +EPITIM==30891. ;TIME FOR EPILOG +] + +IFN KLFLAG,[ +SUSTIM==71630. +UUOTIM==3373. +EPITIM==4663. +] + +; +; .CCALL HANDLER (TIMING VERSION) +; + +IENTRY UTCALL + + .SUSET [24,,C] ; JOB ACCUMULATED TIME TO C + SKIPN TIMING" ; IS TIMING ON ? + GO UT$1 ; NO, RESUME NORMAL OPERATION + SUBI C,/4069. + ; FUDGE FOR SUSET AND TIME IT TOOK + ; TO GET HERE + SUBM C,%FTIME(TP) ; DETERMINE CALLER'S ACCUMULATED TIME + ADDI TP,%FSIZE ; ALLOCATE NEW TIME FRAME + + HRRZ B,40 ; CALLED ROUTINE + HRRZ D,-1(B) ; TIMTAB POINTER OR PROC NAME + CAIGE D,TIMTAB ; IS IT A TIMTAB POINTER? + GO UT$3 ; NO + CAMGE D,TIMEP ; IS IT A TIMTAB POINTER? + GO UT$2 ; YES + +UT$3: MOVE A,D ; PROC NAME + MOVE D,TIMEP ; FIRST TIMED CALL OF ROUTINE + CAML D,ETIMEP ; IS TIME TABLE FULL? + GO UT$1 ; YES, IGNORE THIS CALL + MOVEM B,%TPROC(D) ; NO - INITIALIZE NEW TIMTAB ENTRY + MOVEM A,%TNAME(D) + SETZM %TTIME(D) + SETZM %TNCAL(D) + HRRM D,-1(B) ; PUT PTR TO TIMTAB ENTRY IN NAME WORD + MOVEI C,%TSIZE + ADDM C,TIMEP ; ADVANCE POINTER TO NEXT FREE ENTRY + +UT$2: ; HERE WITH PTR TO TIMTAB ENTRY IN D + MOVEM D,%FTABL(TP) ; STORE POINTER IN TIME STACK + AOS %TNCAL(D) ; INCREMENT USE COUNT + +UT$1: ; CONTINUE WITH CALL PROCESSING + HRRZ C,40 ; THE CALLED PROCEDURE + JUMPE C,UCBAD" ; NO SUCH PROCEDURE + HLRZ 0,-1(C) ; THE NUMBER OF FORMAL ARGS + CAIL 0,20 ; REASONABLE NUMBER? + GO UCBAD ; NO, NOT A PROCEDURE + LDB B,[270400,,40] ; THE NUMBER OF ACTUAL ARGS + SUB 0,B ; NUMBER OF ARGS NOT GIVEN + JUMPL 0,CODE [ ; TOO MANY ARGS GIVEN + ADD P,0 ; POP OFF EXTRA ARGS + GO UTDOIT ; MAKE THE CALL + ] +UTLOOP: SOJL 0,UTDOIT ; FOR EACH ARG NEEDED + PUSH P,[0] ; PUSH ZERO ARG + GO UTLOOP ; LOOP +UTDOIT: SKIPN TIMING + GO UT$4 + MOVE B,UUOH ; RETURN ADDRESS + MOVEM B,%FRTNA(TP) ; SAVE IT + MOVEI B,%FTIME(TP) ; CONSTRUCT .SUSET + HRLI B,24 ; GET START TIME FOR CALLED PROC + .SUSET B ; AND STORE IN TIME STACK FRAME + PUSHJ P,(C) ; CALL PROCEDURE + .SUSET [24,,C] ; JOB ACCUMULATED TIME + MOVE 0,C + SUBI C,SUSTIM/4069. ; FUDGE FOR .SUSET TIME + SUB C,%FTIME(TP) ; SUBTRACT START TIME + MOVE B,%FTABL(TP) ; TIMTAB ENTRY POINTER + ADDM C,%TTIME(B) ; ADD TO ACCUMULATED TIME FOR CALLEE + SUBI TP,%FSIZE ; POP TIME STACK FRAME + ADDI 0,/4069. ; FUDGE + SUBM 0,%FTIME(TP) ; ADJUST START TIME OF CALLER + GO @%FRTNA+%FSIZE(TP) ; RETURN TO CALLER + +UT$4: PUSH P,UUOH" + GO (C) + +IENTRY TINIT + + SETOM TIMING" + MOVEI A,UTCALL + MOVEM A,UUOTAB"+1 + MOVEI TP,TIMSTK + MOVEM TP,TPINIT" + MOVEI A,TPRT" + MOVEM A,EXITER" + GO LINIT" + +.IDATA +MDATA TIMEP + TIMTAB +MDATA ETIMEP + TIMTAB+ +.UDATA +MDATA TIMTAB + BLOCK TIMSIZ*%TSIZE +MDATA TIMSTK + BLOCK TIMSIZ +END + \ No newline at end of file diff --git a/arc/ar5:c/C10TPR C b/arc/ar5:c/C10TPR C new file mode 100644 index 00000000..8f6fe1aa --- /dev/null +++ b/arc/ar5:c/C10TPR C @@ -0,0 +1,152 @@ +# include "clib/c.defs" +# include "clib/its.bits" + +/********************************************************************** + + C10TPR - Printing Routine for C Timer Package + *ITS* + +**********************************************************************/ + +# rename null "$NULL$" +# rename timing "TIMING" +# rename timtab "TIMTAB" +# rename timep "TIMEP" +# rename tprt "TPRT" + +struct _tentry {int *proc, pname, count, time;}; +# define tentry struct _tentry + +extern int timing; +extern tentry timtab[], *timep; +extern int cout; + +/* All times are kept in machine-dependent Units + and converted upon output to the appropriate + units. +*/ + +tprt () + + {int fout, /* output file */ + total_time, /* total CPU time used */ + smallest, /* smallest average time */ + time, /* time used by current routine */ + average, /* average time of current routine */ + percent, /* percentage CPU time, current routine */ + cpercent, /* cumulative percentage CPU time */ + ctime, /* cumulative CPU time */ + count, /* number of calls, current routine */ + ncalls, /* total number of calls */ + namep, /* pointer to current routine name */ + nulltime, /* time to call null routine */ + t, + c; + + tentry *ip, *ip1; + + t = rsuset (URUNT); + c = 50; + timing = -1; + while (--c >= 0) + {null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + null (); + } + timing = 0; + + fout = copen ("timer.output", 'a'); + if (fout<0) fout = copen ("timout", 'w'); + if (fout<0) fout = cout; + + cprint (fout, "\n\n\n *** TIMING INFORMATION ***\n\n"); + cprint (fout, "TIME(usec) PERCENT CUM. %% NO. CALLS AVG. TIME ROUTINE NAME\n\n"); + + /* null entry should be last */ + + --timep; + nulltime = timep->time / timep->count; + + /* sort entries in order of decreasing CPU time used */ + + for (ip=timtab;iptime > ip->time) + bswap (ip, ip1, 4); + + total_time = 0; + for (ip=timtab;iptime; + + ncalls = 0; + smallest = 10000; /* big number */ + ctime = 0; + for (ip=timtab;iptime; + ctime =+ time; + percent = (time * 1000) / total_time; + cpercent = (ctime * 1000) / total_time; + count = ip->count; + ncalls =+ count; + namep = (ip->pname) | 0440700000000; + average = time/count; + if (average0) smallest=average; + cprint (fout, "%10d%8d.%1d%8d.%1d", + u2mic (time), percent/10, percent%10, + cpercent/10, cpercent%10); + cprint (fout, "%11d%12d ", count, u2mic (average)); + while (c = ildb (&namep)) cputc (c, fout); + cputc ('\n', fout); + } + + if (smallest= 0) + {t = *p; + *p++ = *q; + *q++ = t; + } + } + +null () {;} + \ No newline at end of file diff --git a/arc/ar5:c/C10TTY C b/arc/ar5:c/C10TTY C new file mode 100644 index 00000000..f5f45ab9 --- /dev/null +++ b/arc/ar5:c/C10TTY C @@ -0,0 +1,376 @@ +/* + * C TTY Package + * + * routines: + * + * tyiopn - open TTY input channel + * tyi - read char from TTY (buffered) + * utyi - read char from TTY (unbuffered) + * get_buf - read string from TTY + * setprompt - set default TYI prompt string + * tyoopn - open TTY output channel + * tyo - output char to TTY (buffered) + * utyo - output char to TTY (unbuffered) + * spctty - output display code (unbuffered) + * tyos - output string to TTY (buffered) + * tyo_flush - flush TTY output buffer + * + * global variables: + * + * ttynp - ^L handler + * + * internal routines: + * + * ttyih - TTY interrupt handler + * ctrlch - return display width of char + * + */ + +# include "c.defs" + +# define tty_input_buffer_size 120 +# define tty_output_buffer_size 60 + +# rename tty_input_channel "TYICHN" +# rename tty_output_channel "TYOCHN" +# rename tty_device_code "TTYDEV" +# rename tty_input_buffer "TYIBUF" +# rename tty_input_ptr "TYIPTR" +# rename tty_input_count "TYICNT" +# rename tty_output_buffer "TYOBUF" +# rename tty_output_ptr "TYOPTR" +# rename tty_output_count "TYOCNT" +# rename tty_output_bptr "TYOBPT" +# rename tty_default_prompt "TTYDPR" + +int tty_input_channel -1; +int tty_output_channel -1; +int tty_device_code -1; +char tty_input_buffer[tty_input_buffer_size]; +char *tty_input_ptr; +int tty_input_count; +char tty_output_buffer[tty_output_buffer_size]; +char *tty_output_ptr {tty_output_buffer}; +int tty_output_count; +int tty_output_bptr; +char *tty_default_prompt; + +int ttxnp(); /* default TTY ^L handler */ +int (*ttynp)() {ttxnp}; /* called on ^L */ + +/********************************************************************** + + TYI - Read Character From TTY (buffered) + +**********************************************************************/ + +tyi () + + {while (tty_input_count <= 0) + {if (tty_input_channel < 0) tyiopn (); + tty_input_count = get_buf (tty_input_buffer, + tty_input_buffer_size, '\r', ""); + tty_input_ptr = tty_input_buffer; + if (tty_input_count == 0) return (0); + } + --tty_input_count; + return (*tty_input_ptr++); + } + +/********************************************************************** + + UTYO - output character to TTY (unbuffered) + +**********************************************************************/ + +utyo (c) + + {if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (tty_output_count > 0) tyo_flush (); + c =& 0177; + if (c != 16) uoiot (tty_output_channel, c); + else + {uoiot (tty_output_channel, '^'); + uoiot (tty_output_channel, 'P'); + } + } + } + +/********************************************************************** + + TYO - output character to TTY + +**********************************************************************/ + +tyo (c) + + {c =& 0177; + + if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (c != 16) {*tty_output_ptr++ = c; ++tty_output_count;} + else + {*tty_output_ptr++ = '^'; + *tty_output_ptr++ = 'P'; + tty_output_count =+ 2; + } + if (c=='\r' || tty_output_count >= tty_output_buffer_size-2) + tyo_flush (); + } + } + +/********************************************************************** + + TYO_FLUSH - flush TTY output buffer + +**********************************************************************/ + +tyo_flush () + + {if (tty_output_channel >= 0 && tty_output_count > 0) + {siot (tty_output_channel, tty_output_bptr, + tty_output_count); + tty_output_ptr = tty_output_buffer; + tty_output_count = 0; + } + } + +/********************************************************************** + + TYOS - Output String to TTY + +**********************************************************************/ + +tyos (s) char s[]; + + {int c; + + while (c = *s++) tyo (c=='\n' ? '\r' : c); + } + +/********************************************************************** + + SPCTTY - Send "special" display control character to TTY. + +**********************************************************************/ + +spctty (c) + + {if (tty_output_channel >= 0 || tyoopn() >= 0) + {if (tty_output_count > 0) tyo_flush (); + uoiot (tty_output_channel, 16); + uoiot (tty_output_channel, c); + } + } + +/********************************************************************** + + UTYI - read character from TTY (unbuffered and unechoed) + +**********************************************************************/ + +int utyi () + + {if (tty_input_channel<0) tyiopn (); + if (tty_output_count > 0) tyo_flush (); + return (uiiot (tty_input_channel)); + } + +/********************************************************************** + + GET_BUF - Read characters from TTY until end-of-file + simulated or given break character seen. + Read characters into given buffer, including + the terminating break character (if any). + Return a count of the number of characters + placed in the buffer. The given prompt string + will be printed first; it will be reprinted + when ^L is typed. + +**********************************************************************/ + +int get_buf (buf, buf_size, break_ch, prompt) char buf[], prompt[]; + + {char *p, *q, pbuf[tty_output_buffer_size]; + int i, c, j; + + if (tty_input_channel<0) tyiopn (); + if (!prompt[0]) /* no explicit prompt */ + {if (tty_output_count > 0) /* use partial output line */ + {tty_output_buffer[tty_output_count] = 0; + stcpy (tty_output_buffer, pbuf); + prompt = pbuf; + } + else if (tty_default_prompt) /* use default */ + prompt = tty_default_prompt; + } + if (prompt != pbuf) tyos (prompt); + if (tty_output_count > 0) tyo_flush (); + p = buf; + i = 0; /* number of chars in buffer */ + + while (TRUE) + {c = uiiot (tty_input_channel); + if (c != break_ch) switch (c) { + +case 0177: /* rubout - delete prev char */ + + if (i>0) + {c = *--p; + --i; + if (tty_device_code==2) /* display */ + {if (c=='\r') + {spctty ('U'); + q = p; + while ((c = *--q) != '\r' && + q>=buf) + {j = ctrlch(c); + while (--j>=0) spctty ('F'); + } + if (q=prompt) + {j = ctrlch(c); + while (--j>=0) spctty ('F'); + } + } + } + else + {j = ctrlch(c); + while (--j>=0) spctty ('X'); + } + } + else utyo (c); + } + continue; + +case '\p': /* redisplay buffer */ + + *p = 0; + (*ttynp) (tty_device_code==2, prompt, buf); + continue; + +case 0: /* simulate end-of-file */ + + q = buf; + while (q < p) {if (*q == '\r') *q = '\n'; ++q;} + return (i); + +case '\n': /* ignore - dont want to echo it */ + + continue; + +default: if (i <= buf_size - 2) + {++i; + utyo (*p++ = c); + } + else utyo (07); /* beep */ + continue; + } + + break; + } + + utyo ('\r'); + *p++ = c; + q = buf; + while (q < p) {if (*q == '\r') *q = '\n'; ++q;} + return (i+1); + } + +/********************************************************************** + + TTXNP - Default TTY ^L handler + +**********************************************************************/ + +ttxnp (display, prompt, buf) + int display; + char *prompt, *buf; + + {if (display) spctty ('C'); else tyo ('\r'); + tyos (prompt); + tyos (buf); + tyo_flush (); + } + +/********************************************************************** + + TTYIH - TTY Input Interrupt Handler + +**********************************************************************/ + +ttyih () + + {int c; + + c = ityic (tty_input_channel); + if (c == 023) signal (ctrls_interrupt); + else if (c == 007) signal (ctrlg_interrupt); + } + +/********************************************************************** + + TYIOPN - Open TTY for INPUT. + +**********************************************************************/ + +channel tyiopn() + + {int block[3]; + if (tty_input_channel < 0) + tty_input_channel = fopen ("/tty", 0); + on (ttyi_interrupt, ttyih); + ttyget (tty_input_channel, block); + block[0] = 020202020202; + block[1] = 030202020202; + ttyset (tty_input_channel, block); + tty_device_code = status (tty_input_channel) & 077; + return (tty_input_channel); + } + +/********************************************************************** + + TYOOPN - Open TTY for OUTPUT. + +**********************************************************************/ + +channel tyoopn() + + {int i; + if (tty_output_channel < 0) + {tty_output_channel = fopen ("/tty", 021); + i = tty_output_buffer; + i =| 0444400000000; + tty_output_bptr = i; + } + return (tty_output_channel); + } + +/********************************************************************** + + CTRLCH - Return the number of characters a character + prints as. + +**********************************************************************/ + +int ctrlch (c) + + {if (c==0177) return (2); + if (c>=' ' || c==033 || c=='\t') return (1); + if (c=='\b' || c==07) return (0); + return (2); + } + +/********************************************************************** + + SETPROMPT - Set Default Input Prompt String + +**********************************************************************/ + +setprompt (s) + char *s; + + {tty_default_prompt = s;} + \ No newline at end of file diff --git a/arc/ar5:c/CDOC 90 b/arc/ar5:c/CDOC 90 new file mode 100644 index 00000000..2a9009b4 --- /dev/null +++ b/arc/ar5:c/CDOC 90 @@ -0,0 +1,1608 @@ +This is the file CLIB;C DOC. + +File: CLIB;C DOC, Node: Top, Previous: (DIR), Up: (DIR), Next: Basics + + + Information on Programming in C + +C is an implementation language, similar to BCPL except that data is +typed. It is the primary language used in the UNIX operating system. +This implementation runs on the ITS and TOPS-20 operating systems and is +moderately compatible with the UNIX C implementation. The UNIX +system calls are NOT implemented, but interfaces to ITS and TOPS-20 +system calls are provided. + +* Menu: + +* Basics:: How to run C programs on ITS. + +* Details:: Differences between C on ITS and UNIX. + +* Getting Started:: Hints on writing C programs. + +* Support Routines:: An introduction to the routines available in the + C runtime environment. + +* Portable I/O:: The Portable I/O Library. + +* Storage allocation:: A dynamic storage allocator. + +* String Routines:: Basic character string routines. + +* Character Arrays:: A character string package that uses dynamic + storage allocation. + +* Math Functions:: Floating point routines for the usual functions. + +* Dates and Times:: Packages for manipulating and printing dates and + times in various formats. + +* System Routines:: Packages of routines for accessing operating + system features. + +* Timer Package:: Runtime support for timing procedure calls. + +* Debugging:: Methods and routines for debugging C programs. + +* Graphics:: Packages for graphics and for working with + images in the new image file format. + +* Miscellaneous:: Various interesting routines. + +* Internals:: Internal documentation. + + +Node: Basics, Previous: Top, Up: Top, Next: Details + + + Running C Programs on ITS + +The C compiler translates C into MIDAS and automatically invokes MIDAS +to assemble the intermediate MIDAS code into a relocatable program. The +command for invoking the C compiler is + + :cc file1 file2 ... + +where the arguments are the filenames of the C source files which are to +be compiled. Each file will be compiled in turn, and if the compilation +is successful, the resulting relocatable file will be placed in the file +"file STK". Arguments that begin with a hyphen are compiler options. + + -c Compile only, do not assemble + -g Do not delete the MIDAS file + -x Syntax check only + -s Produce a symbol table Listing + -b Compile a big function (FUNCTION TOO LARGE) + +For example, the command + + :cc -g foo + +would compile the C program in the file "FOO C" or "FOO >" in the +current directory, place the resulting relocatable program in the file +"FOO STK", and leave the MIDAS output in file "foo MIDAS". + +Relocatable programs produced by the C compiler are loaded together +with the C support routines using STINKR. To load program files "foo", +"bar", and "bletch" and produce a executable file "foo", use the following +STINKR commands (STINKR supplies the equal sign prompts). + + :stinkr + =x clib;clib + =l foo + =l bar + =l bletch + =o ts foo + =^@ + +The ^@ (ASCII NUL) signals end of file on the terminal input file. +These commands could also be written in a file, say "FOO STINKR", +without the NULL. Invoking STINKR with "foo" as a JCL argument would +then execute the STINKR command file and produce a executable program. + +To run the program merely type + + :foo + +The C startup routine will automatically parse the JCL line and pass the +components to the user main program as arguments to the main program. +Refer to node "Getting Started" for a description of these argument +passing conventions. The arguments to the program are delimited by +spaces, so an invocation such as + + :myprog foo bar bletch + +will parse into the four character strings "MYPROG", "foo", "bar", and +"bletch". Command line arguments that contain spaces may be enclosed in +double quotes. In addition, the startup procedure will open the TTY for +input and output on the Portable I/O Library files cin (standard input), +cout (standard output), and cerr (standard error output). + +Certain argument forms are interpreted by the C startup routine as +commands for special I/O initialization. The source or destination of +the standard I/O streams can be specified in the JCL by using the +delimiters described below. + + < Redirects the standard input (CIN) to come from the + indicated file. + + > Redirects the standard output (COUT) to go to the + indicated file. + + >> Redirects the standard output (COUT) to be appended to + the indicated file. + + % Redirects the standard error output (CERR) to the + indicated file. + +The default device is DSK, the default directory is the current +directory, and the default second file name is >. So for example, + + :myprog foo >my;junk + +will pass "MYPROG" and "foo" as arguments to the main routine, +initialize cin to read from file "DSK:sname;FOO >", initialize cout to +append output on the file "DSK:MY;JUNK >", and initialize cerr to direct +output to the terminal. By convention, error messages are output to +cerr. Note that if, for instance, you wanted to read the standard input +from "MY JUNK", the invocation + + :myprog )Programming.) + + +In some situations you must be careful about how you use spaces. Does +x=-10 assign minus ten to x or decrement x by 10? (I don't remember. +Try x =- 10 or x = -10.) Does + + #define FOO (X,Y) + +declare a macro of two arguments, or does it declare FOO to have the +value (X,Y)? (The later case applies, but be careful.) + +Amoung the other problems that users frequently stumble over is the +restriction on the use of ++ and -- for incrementing and decrementing +variables. The C standard does not allow variables of type float or +double to be the targets of these operands and all C implementations +adhere to this restriction. + +The placement of semicolons in programs is sometimes confusing, but the +rule is actually very simple. A statement is either an expression that +ends in a semicolon or it is a compound statement, which is a sequence +of statements enclosed in curly brackets. So + + if(x < y) x = y; else y = x; + +is correct, but + + if(x < y) x = y else y = x; + +is not, nor is + + if(x < y) {x = y; y = 0;}; else y = x; + +which has an extra semicolon after the right curly bracket. + + +Node: Support Routines, Previous: Basics, Up: Top, Next: Portable I/O + + + A Introduction to the Shared Library + + +This node briefly describes a useful subset of the routines available in +the Shared Library. For more complete documentation consult the other +nodes in this tree. Begin with the next node to see all documentation +on the available support packages. Note that not all packages are +included in the Shared Library. For example, the job manipulation +routines are not included. (*note Jobs: Job Handling.) + +When a C program is loaded the STINKR command "x clib;clib" executes a +STINKR command file that creates links to the C library CLIB (which is +also called the Shared Library since at runtime it is shared by all +users running C programs.) This library includes a very general package +for I/O (the Portable I/O Library), some basic character string routines, +the standard mathematics functions, interfaces to ITS system calls, and +the C runtime support package which reads and parses the JCL line and +initializes the standard input, output, and error output I/O streams. + +Before describing some of the routines that are available the relevant +terminology must be introduced. A variable of type SIXBIT is a word +containing left justified sixbit characters. A FILESPEC is a structure +of four SIXBIT variables which contain the device, first filename, +second filename, and directory. A filename is a character string +containing an ITS filename in the form "device:directory;first second". +A pathname is a character string that contains a UNIX-style +representation for filenames. The format is +"/device/directory/first.second". If the device specification is +omitted the file specification is written as "directory/first.second". +The pathname form "first.second" is useful for passing both first and +second filenames to a program on the command line. In filenames and +pathnames, delimiters may be quoted with control-Q. A file descriptor +is used by the Portable I/O Library to identify files and may be taken +to be of type int. The file descriptor is not an ITS channel number, +although it is sometimes referred to as a channel. + +In general, users should try to avoid circumventing the Portable I/O +Library by using the ITS system calls directly. However, access to the +lower level I/O primitives provides the user with features such as +unbuffered TTY input and random access I/O that are not implemented in +the Portable Library. The Library performs fully buffered I/O, so +random access block I/O will not work properly. For random access I/O, +use the system interfaces open, close, sysread, syswrite, and access. +The Portable I/O Library searches for unused I/O channels so users who +open files by using the system interface routine 'open' will not clash +with the Portable Library. + + + PORTABLE I/O ROUTINES + +The C startup procedure initializes the global variables cin, cout, and +cerr as file descriptors for the standard input, standard output, and +standard error output streams. + +copen (filename, mode, options) + Open the indicated file and return a file descriptor or -1 if + the open failed. The filename argument can be either a filename + or pathname specification. The mode is a single character, 'r' + for read, 'w' for write, and 'a' for append to end of file. Read is + assumed if the mode argument is omitted. The options argument + is usually omitted. The option "b" denotes binary (image mode) + I/O and "s" denotes I/O to an incore buffer. The buffer pointer + is supplied in place of the filename. Note that the mode has + type character while the options variable has type pointer to + character. + +cgetc (fd) Read a character from the indicated file descriptor and + return it or return 0 if end of file. + +cputc (c, fd) Write a character to the indicated file descriptor. + +ceof (fd) Test for end of file. +cclose (fd) Close file. +closall() Close all files opened by copen. + +cflush(fd) Force out buffer contents on output stream. +rew(fd) Reset file to beginning. + +ungetc(c, fd) Push character back into stream. + +getchar () Equivalent to cgetc (cin). +putchar (c) Equivalent to cputc (c,cout). + +gets (s1) Read a line from cin. +puts (s1) Write string and newline to cout. + +cprint (fd, format, arg1, arg2, ...) + Formatted print statement like printf in the Standard I/O Library. + The format is a string which may contain format items of the + form %nf, where n is an optional decimal integer taken to be the + minumum field width and f is one of the following characters. + + d - Print next argument (an integer) in decimal + o - Print next argument (an integer) in octal + s - Print next argument (a string) + c - Print next argument (a character) + + The file descriptor can be omitted, in which case cout is used. + +cgeti (fd) Read an integer in image mode. +cputi (i, fd) Write an integer in image mode. + +cexit (cc) Terminate job and close all files. Returning from the + main routine will have the same effect. + +fparse (fn,f) Convert file name or path name to FILESPEC. +prfile (f,fn) Convert FILESPEC to file name. + +istty (fd) Return Boolean value indicating whether file is a TTY. +itschan (fd) Return the actual ITS channel number corresponding to + the file descriptor. + +fprint(x,fd) Print the floating point number x on the indicated file. +atoi(s) Convert string to integer. The first character must be + a digit or minus sign and the conversion is always + performed in base ten. + + + TTY I/O ROUTINES + +utyi () Read character from TTY in unbuffered and unechoed mode. + The TTY is opened if necessary and the output buffer is + flushed before the read. +utyo (c) Output the character to the TTY in unbuffered mode. + The TTY is opened if necessary and the output buffer is + flushed before the write. +tyo_flush() Flush the TTY output buffer. +setprompt(s) Set the default TTY input prompt character string. +spctty(c) Outputs a ^P code to the TTY. + +It is alright to use these TTY routines while also using the Portable +I/O Library for terminal I/O. + + + STORAGE ALLOCATION + +calloc (n) Return pointer to block of n characters. +cfree (p) Free storage pointed to by p. The storage must have + been allocated calloc. + +salloc (n) Allocate a block of n words and return a pointer to it. +sfree (p) Free storage allocated by salloc. + + + BASIC STRING ROUTINES + +slen (s) Return string length. +stcpy (s1, s2) Copy string from S1 to S2. +stcmp (s1, s2) Return TRUE if character strings are equal. +upper(c) Return upper case version of character. +lower(c) Return lower case version of character. + +The Portable I/O Library contains routines for manipulating SIXBIT +characters and strings. (*note SIXBIT: Portable I/O Library.) +The character string package contains routines for manipulating byte +pointers and bit arrays. (*note Bytes and Bits: String Routines.) + + + INTERFACES TO SYSTEM CALLS + +This is a partial summary of the system calls currently available to +users of the Shared Library. Refer to (*note Details: System Routines.) +for more complete documentation. + +open (fs, mode) + Open channel specified by FILESPEC and return ITS channel number + or negative ITS failure code. The mode refers to the ITS file + access mode bits, not the character codes used by the Portable + I/O Library. The routine searches for an unused channel. + + +sysread (ch, buffer, size) Block input IOT. +syswrite (ch, buffer, size) Block output IOT. + +access (ch, i) Set file access pointer. +fillen (ch) Return file length. + +close (ch) Close the channel. + +fdate = rfdate (ch) Read file creation date. +fdate = sfdate (ch, fdate) Set file creation date. +fdate = srdate (ch, fdate) Set file reference date. +rauth (ch) Read file author in SIXBIT. +sauth (ch, w) Set file author in SIXBIT. + +rsname () Return sname in SIXBIT. +runame () Return uname in SIXBIT. +ssname (w) Set sname to value supplied in SIXBIT. + +sleep (n) Sleep for n 30th seconds. + +valret (s) .VALUE a character string or zero. + +etime() Return system elapsed time in 1/60 sec units. +cputm() Return job CPU time in 1/60 sec units. +getcpu() Return job CPU time in 4.096 micro sec units. + + +The Portable I/O Library contains routines for handling SIXBIT data +(*note SIXBIT: Portable I/O Library.) and there is a package of routines +for manipulating and printing dates and times. (*note: Dates and Times.) + +Some useful definitions are available in the file CLIB;CLIB H. + + +Node: Portable I/O, Previous: Basics, Up: Top, Next: Storage Allocation + + + The Portable I/O Library + +Most of the routines in the Portable I/O Library are written in C, but +the most frequently used I/O routines have been hand coded in MIDAS. +The C source routines will be described first, followed by descriptions +of the MIDAS source routines and internal data structures. + +The routine for opening files is COPEN. The arguments to COPEN are a +character string which is a file name or path specification, an optional +character which indicates the mode of access, and an optional character +string containing option codes. The modes are + + 'r' Open file for read access. + 'w Open for write access. + 'a' Open the file for write access and position the file + access pointer at the end of the file. + +The default mode is 'r' for read. Normally, I/O is character oriented +and produces text files. In particular, the lines of a text +file are assumed by the user to be separated by newline +characters with any conversion to the system format performed +by the I/O routines. + +If an options string is given and contains the character "b", +then I/O is integer oriented and the file is processed in image mode. + +If an options string is given containing the character "s" then I/O is +performed to or from a buffer in memory. A pointer to the buffer is +passed in place of the filename argument. Closing a string I/O file +that is open for write will append a NULL character to the string and +return a character pointer to that character. + +COPEN returns a CHANNEL, which is a pointer to a control block, if the +open is successful. It and returns -1 in case of error and leaves the +system error code in the external variable CERRNO. The macro variable +OPENLOSS is frequently set to -1 in macro packages. + +The default filename components are DSK for the device, SNAME for the +directory, and > for the second filename. No default is supplied for +the first filename. COPEN is careful to treat the TTY as a special +case. If a disk file is locked, then COPEN will wait until the file can +be opened. + +The routine GETCHAR takes no arguments, reads a character from the +standard input, and returns it. Zero is returned on end of file. + +The routine GETS takes a character pointer as an argument and reads one +line from the standard input, placing the null terminated line into the +buffer. The newline character is not included. No value is returned +and the buffer is assumed to be large enough. + +The routine PUTCHAR takes a single character as an argument and writes +it on the standard output. The character is returned. + +The routine PUTS takes a character pointer as an argument and writes the +character string and a NEWLINE on the standard output. No value is +returned. + +The routine FPRINT takes a single or double precision floating point +number and a file descriptor as arguments, and prints the floating point +number on the specified file. Both arguments are required. Eight +significant digits are printed in either fixed or floating point +notation depending on the magnitude of the number. + +The routine ATOI takes a character string as an argument and returns an +integer. The first character must be either a digit or a minus sign and +radix 10 is always used. + +The routine MOPEN is called by COPEN to open a file. The TTY is treated +as a special case and MOPEN will wait on a locked file until the file +becomes available. MOPEN requires a FILESPEC and a code word of ITS +access mode bits as arguments. MOPEN calls OPEN to open non-TTY files. +If the file is successfully opened, the ITS channel number is returned, +otherwise the negative ITS failure code is returned. + +The routine MCLOSE can be used to close a channel opened by MOPEN. An +attempt to close the TTY is ignored. A file opened by a call to COPEN +must be closed by a call to CCLOSE, not MOPEN. + +The routine FPARSE will convert an ASCIZ string representation of an ITS +filename or pathname to a FILESPEC. The routine requires a character +string pointer to the filename and a pointer to a FILESPEC block. Zero +is returned if the filename could be parse and -1 is returned if the +format was incorrect. + +The routine PRFILE will convert a FILESPEC into a filename in ITS +format. The arguments are a pointer to the FILESPEC and a character +string pointer to a buffer that is assumed to be large enough for the +resulting filename. Control-Q is placed in front of delimiters that +occur in the components of the filename. + +The routine FOPEN calls FPARSE to parse a filename and then calls OPEN +to open the file. The default filename components are DSK for device +and RSNAME for directory. There are no defaults for the first or second +filenames which s why this routine is almost never used. But if you +really wich to use it, the arguments are a character string pointer to +the filename and an integer containing the ITS mode bits. The ITS +channel number is returned if the open is succesful, otherwise the +negative ITS failure code is returned. + +The routine OPEN takes a FILESPEC and a integer containing the ITS mode +bits, opens the indicated file, and returns the ITS channel number if +the open was successful and the negative ITS failure code if the open +was unsuccessful. The routine calls CHNLOC to find an available channel. +(*note: System Calls.) + +The routines FXARG, C0OPEN, C0INIT, and PRSARG are called by the C +startup procedure to open the TTY as the standard input, output, and +error output I/O streams, parse the JCL, and redirect the standard I/O +streams if the JCL line contains specifications for standard I/O +redirection. + +The routine VALRET takes an ASCIZ character string as an argument and +valrets the command string. In some cases the command string will be +overwritten with garbage. + +The following two routines take a single character as an argument and +return a character of the indicated type as a result. + + CCTO6 Convert ASCII character to sixbit + C6TOC Convert sixbit character to ASCII + +The routine CSTO6 takes a character string pointer as an argument and +returns an integer containing the left justified sixbit representation +of the ASCII character string. The routine C6TOS takes an integer and a +character string pointer as arguments and expands the sixbit characters +in the integer into the character buffer. + +The following Portable I/O routines were hand coded in MIDAS. The +calling sequences of most of these routines are described in the node on +Support Routines (*note MIDAS I/O Routines: Support Routines.) +All of the routines take Portable I/O file descriptor pointers as +arguments, not ITS channel numbers. + + CGETC Read character + CPUTC Write character + CGETI Read integer in image mode + CPUTI Write integer in image mode + UNGETC Push character back into I/O stream + CEOF Test for end of file + CFLUSH Flush buffer + REW Reset channel to beginning + CCLOSE Close file + CLOSALL Close all files + ISTTY Return true if file is a TTY + CISFD Return true if pointer is a file descriptor + ITSCHAN Return the ITS channel number corresponding + to the file desciptor + + +In the Portable I/O Library, the file descriptor points to a file +control block that contains the information on the state of the file. +The structure of a Portable I/O Library file control block is described +below. The fields begin at the left edge of the word. + + struct FCB { + int *fbuffp : 18, /* Pointer to buffer */ + fchan : 4, /* ITS channel number */ + fdevice : 6, /* Device code */ + fflag : 8; /* Flag bits (described below) */ + int *fbprt, /* Pointer to next + character or word in buffer */ + fbnt, /* Number of characters + or words in buffer */ + int fucnt : 18, /* Number of characters + in UNGETC buffer */ + *fuptr : 18; /* Pointer to UNGETC buffer */ + int fclsr() : 18; /* Address of close routine */ + int fngetr(): 18; /* Address of normal close routine */ + int fgetcr(); /* Address of CGETC routine */ + int fputcr(); /* Address of CPUTC rouine */ + }; + + typedef FCB *FD; /* Type definition for the file descriptor + returned to the user */ + +/* Flag bits for the fflag field in the FCB */ + +#define PHYEOF 01 /* Physical EOF */ +#define OPEN 02 /* File is open */ +#define WRITE 04 /* Write access */ +#define TTY 010 /* File is TTY */ +#define UNSET 020 /* Device and channel not yet set */ + + +The size of the buffers used by the Portable I/O Library are 200 octal +words. A maximum of ten Portable I/O Library files may be open at any +time. The number of character that may be pushed back into the I/O +stream is limited to 20. + +The source for the Portable I/O Library exists in the several files in CLIB; + + C10IO C Most of the routines that are written in C + FPRINT C The floating point print routine + ATOI C The ASCII string to integer converter + C10MIO CMID The core routines written in MIDAS + + +Node: Storage Allocation, Previous: Basics, Up: Top, Next: String Routines + + + Storage Allocation + +The Shared Library provides a storage allocator for use by C users. The +storage allocator maintains a linked list of free blocks and merges +adjacent free blocks to minimize fragmentation. The operating system is +called to obtain additional memory pages only when necessary. The +allocator will return a pointer to a zeroed block of the requested size. + +calloc (size) Returns a pointer to a zeroed block of + characters of the requested size. + +cfree (p) Frees a block allocated by calloc. The blocks + may be freed in any order, but it is a gross + error to free a block that has not been + allocated by calloc. + +salloc (size) Allocate a zeroed block of words of the + requested size. + +sfree (p) Free a block allocated by salloc. + +alocstat (nwalloc, nbfree) + Compute allocation statistics. The number of free words is + returned. The number of words that have been allocated by the + operating system and the number of free blocks are returned via + pointers supplied as arguments. + +getcore (size) Calls the page allocation routine in the page + handling package to obtain the requested amount + of space and updates the allocation statistics. + This routine is for internal use. + + +The source code is in the files CLIB;ALLOC CMID and CLIB;C10COR CMID. + + +Node: String Routines, Previous: Basics, Up: Top, Next: Character Arrays + + + Character String Routines and Related Functions + +The Shared library includes several basic routines for manipulating +character strings, byte strings, and bit strings. + +slen (s) Returns the length of a character string excluding the + terminating null character. + +stcpy (s1, s2) Copies string s1 to s2 and returns a pointer to the null + byte at the end of the new copy. The space occupied by + s2 is assumed to be large enough for s1. + +stcmp (s1, s2) Returns TRUE is character strings s1 and s2 are the same + length and have equal contents. + +lower (c) Convert character to lower case. + +upper (c) convert character to upper case. + +bget (s, i) Extract the i th bit from the bit string stored at s. + The bit string begins on a word boundary and the index + origin starts at zero. + +bset (s, i) Set the i th bit. + +ildb (pbp) Do an increment and load byte on the byte pointer stored + at the address supplied as an argument. + +idpb (ch, pbp) Do an increment and deposit byte with the byte and byte + pointer address supplied as arguments. + +These routines are in the file CLIB;STRING CMID and all of these routines +are in the Shared Library. + + +A couple of basic string pattern matching routines are contained in the +file CLIB;MATCH C. The routines defined in this file are described below. + + smatch (p, s) The pattern p is a character string which is to + be matched against the data string s. Certain + characters in p have special meanings. + + '*' Match any substring + '?' Match any character + '\\' Quote following character + + + sindex (p, s) Return the index of the first occurrence of the + string p in the string s. Return -1 if p does + not occur in s. + + +Both of these routines are included in the Shared Library. + + +An interface to the PDP-10 block transfer (BLT) instruction has been +provided as a routine in the source file CLIB;BLT CMID. + + blt(source, dest, number) Will transfer the indicated + number of words from the source + address to the destination + address. + +This routine is available in the Shared Library. + + +The Portable I/O Library contains routines for converting between +characters and strings in sixbit and ASCII formats. +(*note SIXBIT: Portable I/O Library.) + + +Node: Character Arrays, Previous: Basics, Up: Top, Next: Math Functions + + + Array of Characters Package + +The array of characters package supports operations on character strings +stored in a representation that allow the strings to grow and shrink +dynamically. The routines in the array of characters package use the +dynamic storage allocator that is included in the Shared Library. +(*note Dynamic Storage: Storage Allocation.) + +The data structures used in the package can be defined by + +struct rep { /* The representation for an + array of characters */ + int count; /* Reference count */ + char *s; /* Character buffer pointer */ + int csize; /* Logical size of the array */ + int msize; /* Actual size (at least csize + 1) */ +}; + +typedef rep *AC; /* What the user works with */ + + +The functions supported by the package are described below. + + ac_new () => ac create empty array + ac_alloc (size) => ac create empty array withpreferred size + ac_create (string) => ac create with initial value + ac_xh (ac, c) => c extend array with character + ac_trim (ac) => ac trim excess storage + ac_fetch (ac, i) => c fetch character from array + ac_link (ac) => ac make new link to array + ac_unlink (ac) remove link to array + ac_puts (ac, f) print array + ac_cat (ac, ac) => ac concatenate arrays + ac_copy (ac) => ac copy array + ac_string (ac) => *char return string version + ac_size (ac) => size return current size of array + ac_flush (ac) make array empty + ac_n () => int return # of active arrays + + +The default initial storage allocation for creating character arrays is +8 words. One character is stored per word. + +The source for the array of characters package is in CLIB;AC C. + + +Node: Math Functions, Previous: Basics, Up: Top, Next: Dates and Times + + + Floating Point Routines + +All routines accept a single argument that is of type float or double. +Note that C converts all floating point arguments to double precision. + +Most of the floating point routines are in CLIB;CFLOAT CMID. The functions +contained in this package are listed below. + + LOG EXP COS SIN + ATAN SQRT DTRUNCATE DROUND DABS + + +In addition, a random number generator was borrowed from MUDDLE and +exists in the file CLIB;RANDOM CMID. Two routines are available. + + SRAND Set the random number generator seed + RAND Get a random number. + The number is a large integer. + + +Both of these packages are in the Shared Library. + + + +Node: Dates and Times, Previous: Basics, Up: Top, Next: System Routines + + + Date and Time Routines + +This node documents the routines that are available for manipulating +dates and times in various formats. To acquire a file date or the +running time of a program consult the documentation on system calls. +(*note Calls: System Calls.) + + +The date manipulating routines handle three representations for dates. + +(1) CAL Calender date, a system-independent representation + consisting of a record containing six integers + for the year, month, day, hour, minute, and second. + +(2) FDATE The ITS date representation used in file directories. + +(3) UDATE The UNIX date representation, seconds since + Jan 1, 1970, GMT. + +The routines for manipulating these date representations are + + u2cal (udate, cal) Convert UDATE to CAL format + udate = cal2u (cal) Convert CAL format to UDATE format + f2cal (fdate, cal) Convert FDATE to CAL format + fdate = cal2f (cal) Convert CAL format to FDATE + prcal (cal, fd) Print the date and time in CAL format + using the Portable I/O Library file + descriptor supplied in the call + +The structure of a CAL format date can be described by the following +structure. + + struct CAL {int year, month, day, hour, minute, second;}; + +Note that the routines that manipulate CAL format dates require a +pointer to such a structure. All of these date handling routines are +available in the Shared Library. The source is in the file CLIB;DATE C. + + +For printing times, the following routine is useful + + pr60th (time, fd) Will print the time (supplied in units + of 1/60 seconds) using the Portable I/O + Library file descriptor supplied in the + call. The display format is HH:MM:SS.XX + +The source for this routine is in CLIB;PR60TH C. This routine is included +in the Shared Library. + + +Node: System Routines, Previous: Basics, Up: Top, Next: Timer Package + + + System Routines + +This node documents packages of routines that manipulate system +resources such as jobs and memory pages, implement a facility for +handling exceptional program conditions, and provide interfaces to +operating system calls. + +* Menu: + +* TTY I/O Routines:: A package for terminal I/O. + +* Interrupts:: A package for handling user program interrupts. + +* Job Handling:: A package for manipulating ITS jobs. + +* Page Handling:: A package for hacking memory pages. + +* System Calls:: A package of interfaces to ITS system calls. + + +Node: TTY I/O Routines, Up: System Routines, Next: Interrupts + + + The TTY I/O Package + +This node documents the facilities provided by the TTY I/O Package for +performing terminal I/O. Note that this package is used by the Portable +I/O Library for performing TTY I/O and since the Portable I/O Library +provides a more general I/O interface, users are advised to avoid +circumventing the Portable I/O Library by calling the TTY I/O routines +directly. However, the TTY I/O Package provides certain facilities that +are not available in the Portable Library such as unbuffered terminal +input. The TTY I/O routines may be used in conjunction with the +Portable I/O Library for performing terminal I/O without conflict. + + +tyiopn() Open the TTY input channel. The channel number of the TTY + input channel is returned. Even if this routine is + called several times the TTY input channel is only + opened once and only one input buffer is maintained. + +tyi() Read a character from the TTY. The transfer is fully + buffered. + +utyi() Read a character from the TTY. The transfer is + unbuffered and unechoed. The TTY output buffer will be + forced out before the read is performed. + +get_buf(buffer, size, break, prompt) + Read a string from the TTY into the indicated buffer + until the buffer is filled, a NUL character is received, + or the indicated break character is received. The + indicated prompt string (or the default prompt string, + as set by setprompt) is output to the terminal, + unless characters are already available in the TTY input + buffer. The number of characters read is returned. + +setprompt(s) Set the default prompt for terminal reads via tyi(). + +tyoopn() Open the TTY output channel. The channel number is + returned. Even if this routine is called multiple + times, only one TTY output channel is created and only + one TTY output buffer is maintained. + +tyo(c) Output the character to the TTY. The transfer is fully + buffered. + +utyo(c) Output the character to the TTY without buffering. The + TTY output buffer is forced out before the transfer. + +spctty(c) Output the display code without buffering. The TTY + output buffer is forced out before the code is output. + +tyos(s) Output the character string to the TTY with buffering. + +tyo_flush() Force out the TTY output buffer. The characters are + written out using an SIOT operating system call. + +The global variable ttynp contains the address of the ^L handler. The +default ^L handler is ttxnp. When a ^L is encountered in the input +stream, the prompt and the input buffer are redisplayed and the output +buffer is forced out. Before the prompt is redisplayed a carriage +return or the special display code 'C' is output, depending on whether +the terminal is a display. + + +There are two routines that are internal to the TTY package. + +ttyih() TTY interrupt handler +ctrlch(c) Return display width of character + + +The source code for the TTY I/O Package is in CLIB;C10TTY C. + + +Node: Interrupts, Up: System Routines, Next: Job Handling + + + The C Interrupt Package + +The file CLIB;C10INT CMID contains the code for the C interrupt handling +system. Two basic routines are provided by this package for setting an +interrupt handler and signalling an interrupt. + +on (number, handler) Specifies the routine to be invoked when the + interrupt occurs. A pointer to the new handler + is provided in the call. The address of the old + interrupt handler is returned. The number + supplied in the call is one of the code numbers + used in the C interrupt system. + +signal (number) Signal the specified interrupt. + + +Default handlers have been provided for ^S and ^G interrupts. The +default ^S handler flushes the TTY output buffer and inhibits output. +The default ^G handler flushes the TTY output buffer, inhibits output, +and produces a dump of the runtime stack. + +The code numbers used by the C interrupt system are defined in CLIB;C DEFS. +All of the routines described above are in the Shared Library. + + +Node: Job Handling, Up: System Routines, Next: Page Handling + + + Routines for Manipulating Jobs + + +Two simple routines for executing inferior jobs are available, but these +routines are not included in the Shared Library. + + +execs (pname, args) Execute a program with the supplied command string. + +execv (pname, argc, argv) Execute a program with the supplied + argument vector which is in the same + format as the parameters of a main routine. + +Both routines return the following return codes. + + -5 Job valretted something and was not continued + -4 Internal fatal error + -3 Unable to load program file.d + -2 Unable to create job + -1 Unable to open program file + 0 Job terminated normally + other Job terminated abnormally with said PIRQ + +Both routines set the following global variables. + + exctime Job CPU time in 1/60 sec. units + exccode Contents of job's loc 1 at termination + +The source for these routines is in CLIB;C10EXC C. + + +For more sophisticated job handling, use the package in CLIB;C10JOB C. +These routines are not included in the Shared Library. + +The representation of a job is an integer with a value from 0 to 7, +indicating the inferior job number. + + j_create (jname) => # or error code + + j_load (filespec) => # or error code + j_fload (file_name) => # or error code + j_cload (channel, jname) => # or error code + j_own (uname, jname) => # or error code + + error codes: + + -1 unable to open program file + -2 unable to create job + -3 unable to load job + -4 fatal error + -5 (OWN) no such job + -6 (OWN) job not yours + + j_start (#) => rc (return code: non-zero => error) + j_stop (#) => rc + j_disown (#) => rc + j_forget (#) => rc + j_kill (#) => rc + j_snarf (#, inferior_name) => rc + (disown named inferior from stopped job) + j_give_tty (#) => rc + j_take_tty (#) => rc + + j_grab_tty () (grab tty if given to some inferior + and stop job) + j_retn_tty () (return tty to inferior and restart) + + j_wait (#) => status (waits for non-zero status) + j_sts (#) => status + + j_onchange (f) (set handler for status changes) + + j_sjcl (#, s) => rc (set jcl for job) + j_jcl (#) => s (get jcl) + j_ch (#) => ch (return block image output channel to job) + j_name (#, filespec) (set filespec to job name) + + j_val (#) => s (return string valretted by job) + j_fval (#) (flush valret string; or call cfree) + + Job Status: + + -5 => stopped, ^Z typed + -4 => stopped (by superior) + -3 => stopped, valret + -2 => stopped, requested suicide + -1 => no job + 0 => running + >0 => stopped, value is job's first interrupt word + + +Node: Page Handling, Up: System Routines, Next: System Calls + + + Routines for Manipulating Memory Pages + + +The routines documented in this node provide capabilities for managing +memory pages. In order to avoid conflicts with other routines in the C +runtime environment, these routines should be used for allocating memory +pages. Note that the storage management routines documented elsewhere +in this file use these page handling routines, so the manipulation of +memory pages via these routines in conjunction with the use of the +storage allocation package is permissible. + + +pg_get (n) + Allocates n contiguous, unused pages in the address space. + The number of the lowest page allocated is returned. If the + request cannot be met, -1 is returned. + +pg_ret (page, n) + Deallocates n pages in the address space, starting + with the page number supplied in the call. The + routine returns a nonzero value if an error occurs. + +pg_exist (page) + Returns TRUE if the page exists in the address space. + +pg_nshare (page) + Return number of times that a page is shared. + +The source for these routines is in CLIB;C10PAG C and all of these routines +are available in the Shared Library. + + +There are two routines available in the Shared Library for mapping disk +files into memory. + + +filmap (chan, offset, size) + Map part of the disk file open on the specified channel into + memory. The size and offset, in words, of the section to be + moved into memory is specified in the call. The routine returns + a pointer to the beginning of the section in memory. If the + mapping fails because of insufficient memory space, the routine + prints an error message on the standard output and returns + zero. If an error occurs while reading a page, then an error + message is printed on the standard output and a ponter to the + section successfully read is returned. + +filunmap (ptr, size) + Frees pages mapped into memory by filmap. The size of the + section in words and a pointer to the section are supplied in + the call. The contents of the pages are not copied back to + the file. + + +The source for these two routines is in CLIB;C10MAP C and the routines are +included in the Shared Library. + + + +Node: System Calls, Up: System Routines, Next: System Routines + + + ITS System Calls Supported by the Shared Library + +This node documents the system calls that are available through +interfaces in the Shared Library. Before using the routines listed +here, you should check the nodes pertinent to your application to +determine whether there are other routines available that provide more +amicable interfaces to the operating system. + +In general, the system call interfaces are written so that argument +values for the calls are provided as arguments of the procedure +invocation, in the order in which the arguments are expected in the +call, and the routines return the negative value of the ITS failure code +if an error occurs. Note that all channel numbers are ITS channel +numbers, not Portable I/O Library file descriptors, all names are in +sixbit, and all dates are in ITS date format. A package has been +written for manipulating dates and is described in this file. +(*note Dates: Dates and Times.) + + +sysopen (chan, filspc, mode) Open the specified channel +close (chan) Close the specified channel +chnloc() Find and return the number of an + unused channel +uiiot (chan) Perform a unit input IOT +uoiot (chan, data) Perform a unit output IOT +sysread (chan, buffp, nwords) Perform a block input IOT +syswrite (chan, buffp, nwords) Perform a block output IOT +siot (chan, bytp, nbytes) String IOT + +sysfinish (chan) Force output to finish on the + specified channel and wait for + completion +sysforce (chan) Force output to finish, but do + not wait + +reset (chan) Reset channel +status (chan) Get channel status +rfpntr (chan) Read file access pointer +access (chan, pos) Perform random access on channel +fillen (chan) Return the file length in units + appropriate to the mode in which + the file was opened +filnam (chan, filspec) Get file name by which channel + was opened +rauth (chan) Read the name of the author of + the file +sauth (chan, author) Set the name of the file author +rdmpbt (chan) Read the file dump bit +sdmpbt (chan, bit) Set the file dump get +sreapb (chan, bit) Set the file reap bit +rfdate (chan) Read the file creation date +sfdate (chan, fdate) Set the file creation date +srdate (chan, fdate) Set file reference date +dskupd (chan) Update file information +resrdt (chan) Restore file information + +ttyget (chan, block) Get TTY status + (writes 3 values into the block) +ttyset (chan, block) Set TTY status + (reads 3 values from the block) +cnsget (chan, block) Get console status + (writes 5 values into the block) +cnsset (chan, block) Set console status + (reads 5 values from the block) + +whyint (chan, block) Return block of information on + interrupt status +ityic (chan) Read tty interrupt character +syslisten (chan) Listen for input on the channel + (the number of characters is returned) +rcpos (chan) Read TTY cursor position as half + words (v,,h) +scml (chan, number) Set the number of command lines + at the bottom of the screen + +getcpu () Return cpu time in 4.069 micro seconds +cputm () Return cpu time in 1/60 seconds +sleep (time) Sleep for time specified in + 1/30 second units +etime () Return elapsed time 1/60 seconds +now (pcal) Get current date and time + +corblk (a1, a2, a3, a4, a5) Perform page hacking +cortyp (pagno, output) Get information about page +pageid (vpn, idn) Get named public page +pgwrit (job, vpn) Write page to disk + +rsname Read sname +ssname (name) Set sname +runame Read user name + +rsuset (where) USET hacking +wsuset (where, what) +ruset (who, where) +wuset (who, where, what) +wusrvar (job, spec, value) + +delete (fname) Delete a file given an ASCIZ + string containing the + filename. (The Portable I/O + routine fparse is used to + parse the filename.) +sysdelete (filspc) Delete file +renmwo (chan, filspc) Rename file open for output +sysrnm (fspec1, fspec2) Rename file given by fspec1 +syslnk (filsp1, filsp2) Create link from fspec1 to fspec2 +dirsiz (chan, block) Get info on directory size + (writes 2 values into the block) + +tranad (job, from, to, flags) File translation hacking +trancl (job, flags) +trandl (job, filspc, flags) + +sysload (job, chan) Load a program +pdump (jobch, dskch) PDUMP a program +uclose (jchan) Destroy an inferior job +sysdisown (jchan) Disown job +reown (jchan) Reown job +sysdtach (jchan) Detach job +sysatach (jchan, tty) Attach job (TTY < 0 implies default) +atty (job) Give tty to inferior +dtty (job) Take tty from inferior +wfnz (ptr) Wait for word to become non-zero +wfz (ptr) Wait for word to become zero +val7ret (str) Valret an asciz string +demsig (demon) Signal a demon process + +sstatus (valblk) Get system status + (returns 7 values) + +maktag (tagp) Make a tag table entry +gotag (tagp) + +For information on the details of the system calls consult the system +documentation. Try + + :DOC CALL + +at DDT command level. + + +Node: Timer Package, Previous: Basics, Up: Top, Next: Debugging + + + Timing Procedure Calls + +A package of routines is available to gather statistics on the time +spent in the various procedures of a program. The procedure calls are +monitored and a report which includes the percentage of CPU time spent +in each procedure is generated. + +[This package is still being debugged and documented.] + + +Node: Debugging, Previous: Basics, Up: Top, Next: Graphics + + + Debugging Packages + +The code produced by the C compiler contains the hooks for implementing +the C versions of Lisp BAKTRACE and BREAK. A first attempt at BAKTRACE +exists in the file CLIB;STKDMP C. This routine is called by the ^G handler +and so a basic back trace can be obtained by typing control-G. The +stack dump routine displays the names of the called procedures and the +procedure arguments in octal. + +These facilities will be expanded in time. + + +DDT provides several useful facilities for debugging C programs at the +assembly language level. + + ^N Single steps through a program. + p,^N When invoked at the beginning of a subroutine + will continue execution until the subroutine returns. + +There are facilities for setting breakpoints and listing memory +locations. (*note DDT: (INFO;DDT >)Top.) + + + +Node: Graphics, Previous: Basics, Up: Top, Next: Miscellaneous + + + Computer Graphics and Image Processing + +This node documents the packages available in C for displaying graphics +and performing image processing tasks. + +* Menu: + +* TV Graphics:: A basic package for graphics on the Knight TV's. + +* Image files:: A package for reading and writing images in the + new image file format. + + +Node: TV Graphics, Previous: Graphics, Up: Graphics, Next: Image Files + + + TV Graphics Package for Knight TV's + + +The TV graphics package provides the basic primitives for drawing +points, lines, and circles on the Knight TV displays. All of the +drawing functions test to see if the TV has been opened. If it has not +been opened, the TV is opened by calling tvsetup(), which allocates +space for the TV buffer, initializes the TV buffer memory map, clears +the screen, and sets the buffer update mode to inclusive-OR mode so that +overlapping lines will not erase the common point of intersection. The +routine tvwrite uses a default mode of set, since that is advantageous +for dumping images on the screen. All of the line drawing functions +take arguments in units of raster points. The raster is 454 lines high +with 576 bits per line and the origin is at the lower left corner of the +TV screen. All routines return one if the requested operation could be +performed, and zero otherwise. Note that in all cases, the specified +operation will not be performed if it would result in movement off of +the screen. The routine testp is the only plotting function that does +not return 0 if the point is off of the screen or the TV could not be +opened. + + point(x, y) Draw dot at the raster point (x, y). Returns + 0 if the point was not on the screen or the TV + could not be opened, otherwise returns 1. + + testp(x, y) Returns 1, if the indicated point is set, + 0, if the indicated point is clear, and + -1, if the indicated point is off the screen or + if the TV could not be opened. + + line(x0, 01, y1, y1) + Draw a line from (x0, y0) to (x1, y1). Returns + 0 is either point is off the screen or if the TV + mapping could not be established, otherwise + returns 1. + + connect(x, y) Draws a line from the last point drawn to the + indicated point. Returns 1, if the new point lies + on the screen and the line could be drawn, 0 otherwise. + + move(x, y) Move to (x, y) without drawing anything. It + does not open the TV if it is closed. Move + returns 0 if the point is off of the screen, and + returns 1 otherwise. + + circle(x, y, r) Draw a circle of radius r, centered at (x, y). + Returns 1, if the circle is inside the screen and + was successfully drawn, otherwise returns 0. + + tvwrite(line, word, data) + Write the 32 rightmost bits of the supplied data + to the indicated line and word of the TV buffer. + If necessary, the TV is opened and the mode is + changed to SET mode. The routine checks for out + of bounds line and word arguments. Returns 1, + unless the write could not be performed. + + +The following routines are not usually used by casual users since the +graphics primitives described above initialize the state of the TV. + + + tvopen() Map PDP-10 memory onto PDP-11 memory. + A pointer to the beginning of the TV array is + returned, but this pointer may be ignored by + the caller, since the package uses its own copy + of the TV array pointer. A return code of 0 + indicates failure. + + tvclose() Undo the mapping and release the memory used + by the TV array. No value is returned and no + action is taken if the TV is not open. + + tvmode(mode) Change the mode by which updates to the TV + buffer are affected. Useful modes are defined + as macro variables in CLIB;TV H. The previous + mode is returned. + + tvclear() Clear the screen. The cursor is moved to the + lower left corner of the screen. The request is + ignored if the TV is not open and no value is + returned. + + tvbase() Return the value of the TV pointer. The TV pointer + is always 0 if the TV memory is not mapped into + the program address space. + + tvsetup() Open TV, clear the screen, and set the TV mode + to inclusive-OR mode. A pointer to the TV buffer + is returned or 0 if the TV could not be opened. + + +The source for all of these routines is in CLIB;TV C. These routines +are not part of the Shared Library. + +For information on the algorithms used in this graphics package, +consult + + B. K. P. Horn, "Circle Generators for Display Devices", + Computer Graphics and Image Processing 5, 280-288 (1976). + + +Node: Image Files, Previous: TV Graphics, Up: Graphics, Next: Graphics + + + +Node: Miscellaneous, Previous: Basics, Up: Top, Next: Internals + + +This node documents some assorted routines that perform various +interesting and useful functions that do not fit into the taxonomy for +the rest of the C documentation. + +CLIB;C10EXP C Contains a routine for expanding an argument vector that + contains filenames with wild characters. + +CLIB;C10FD C Contains FDMAP(P,F) which calls the procedure F(S) for + all filenames S that match a pattern P. This source + file also contains some routines for working with + directories. + +CLIB;C10FIL C Contains RENAME(S1,S2) which renames file S1 to S2 and + is claimed to work even if S2 exists. + +CLIB;C10FNM C Contains routines for manipulating filenames. + +CLIB;C10STD C Contains interface routines for implementing the + functions of the Standard I/O Library using functions in + the Portable I/O Library. + +CLIB;APFNAM C Contains some routines for appending suffixes to + filenames. + +CLIB;GETSRV C Contains a routine for looking up ARPA net servers. + +CLIB;C10TAP CMID + Contains a magtape interface. + + +Node: Internals, Previous: Basics, Up: Top, Next: Top + + + +---LOCAL Modes:--- +---Mode: Text--- +---Fill Column:72--- +---Auto Fill Mode: 1--- +---End:-- + \ No newline at end of file diff --git a/arc/ar5:c/CFLOAT CMID b/arc/ar5:c/CFLOAT CMID new file mode 100644 index 00000000..725361cf --- /dev/null +++ b/arc/ar5:c/CFLOAT CMID @@ -0,0 +1,217 @@ +; +; CFLOAT - FLOATING POINT STUFF +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE CFLOAT +.INSRT NC +.INSRT NM + +; CONTAINS: LOG, EXP, COS, SIN, ATAN, SQRT, DTRUNCATE, DROUND, DABS + +CENTRY LOG,[V] + + MOVE B,V + JUMPLE B,OUTRNG + LDB D,[331100,,B] ;GRAB EXPONENT + SUBI D,201 ;REMOVE BIAS + TLZ B,777000 ;SET EXPONENT + TLO B,201000 ; TO 1 + MOVE A,B + FSBR A,SQRT2 + FADR B,SQRT2 + FDVB A,B + FMPR B,B + MOVE C,[0.434259751] + FMPR C,B + FADR C,[0.576584342] + FMPR C,B + FADR C,[0.961800762] + FMPR C,B + FADR C,[2.88539007] + FMPR C,A + FADR C,[0.5] + MOVE B,D + FSC B,233 + FADR B,C + FMPR B,[0.693147180] ;LOG E OF 2 + MOVE A,B + RETURN + +CENTRY EXP,[V] + + MOVE B,V + PUSH P,B + MOVM A,B + SETZM B + FMPR A,[0.434294481] ;LOG BASE 10 OF E + MOVE D,[1.0] + CAMG A,D + GO RATEX + MULI A,400 + ASHC B,-243(A) + CAILE B,43 + GO OUTRNG + CAILE B,7 + GO EXPR2 +EXPR1: FMPR D,FLOAP1(B) + LDB A,[103300,,C] + SKIPE A + TLO A,177000 + FADR A,A +RATEX: MOVEI B,7 + SETZM C +RATEY: FADR C,COEF2-1(B) + FMPR C,A + SOJN B,RATEY + FADR C,[1.0] + FMPR C,C + FMPR D,C + MOVE B,[1.0] + SKIPL (P) ;SKIP IF INPUT NEGATIVE + SKIPN B,D + FDVR B,D + MOVE A,B + SUB P,[1,,1] + RETURN + +EXPR2: LDB D,[030300,,B] + ANDI B,7 + MOVE D,FLOAP1(D) + FMPR D,D ;TO THE 8TH POWER + FMPR D,D + FMPR D,D + GO EXPR1 + +COEF2: 1.15129278 + 0.662730884 + 0.254393575 + 0.0729517367 + 0.0174211199 + 2.55491796^-3 + 9.3264267^-4 + +FLOAP1: 1.0 + 10.0 + 100.0 + 1000.0 + 10000.0 + 100000.0 + 1000000.0 + 10000000.0 + +OUTRNG: CROAK [ARGUMENT OUT OF RANGE] + GO RTN1 + +CENTRY COS,[V] + + MOVE B,V + FADR B,[1.570796326] ;COS(X)=SIN (X+PI/2) + CALL SIN,[B] +RTN1: RETURN + +CENTRY SIN,[V] + + MOVE B,V + CL .SIN + RETURN + +.SIN: MOVM A,B + CAMG A,[.0001] + RTN ;GOSPER'S RECURSIVE SIN. + FDVR B,[-3.0] ;SIN(X)=4*SIN(X/-3)**3-3*SIN(X/-3) + CL .SIN + FSC A,1 + FMPR A,A + FADR A,[-3.0] + FMPRB A,B + RTN + +CENTRY SQRT,[V] + + MOVE B,V + MOVE A,B + ASH B,-1 + FSC B,100 +SQ2: MOVE C,B ;NEWTON'S METHOD, SPECINER'S HACK. + FDVRM A,B + FADRM C,B + FSC B,-1 + CAME C,B + GO SQ2 + MOVE A,B + RETURN + +CENTRY ATAN,[V],[TEMP] + + MOVE B,V + MOVEM B,TEMP + MOVM D,B + CAMG D,[0.4^-8] ;SMALL ENOUGH SO ATAN(X)=X? + GO ATAN3 ;YES + CAML D,[7.0^7] ;LARGE ENOUGH SO THAT ATAN(X)=PI/2? + GO ATAN1 ;YES + MOVN C,[1.0] + CAMLE D,[1.0] ;IS ABS(X)<1.0? + FDVM C,D ;NO,SCALE IT DOWN + MOVE B,D + FMPR B,B + MOVE C,[1.44863154] + FADR C,B + MOVE A,[-0.264768620] + FDVM A,C + FADR C,B + FADR C,[3.31633543] + MOVE A,[-7.10676005] + FDVM A,C + FADR C,B + FADR C,[6.76213924] + MOVE B,[3.70925626] + FDVR B,C + FADR B,[0.174655439] + FMPR B,D + JUMPG D,ATAN2 ;WAS ARG SCALED? + FADR B,PI2 ;YES, ATAN(X)=PI/2-ATAN(1/X) + GO ATAN2 +ATAN1: MOVE B,PI2 +ATAN2: SKIPGE TEMP ;WAS INPUT NEGATIVE? + MOVNS B ;YES,COMPLEMENT +ATAN3: MOVE A,B + RETURN + +SQRT2: 1.41421356 +PI2: 3.1415926535/2 + +CENTRY DROUND,[V] + + MOVE A,V + FADR A,[.499999] + JUMPL A,ROUND1 + UFA A,[233000000000] + TLZ B,777000 + GO ROUND2 +ROUND1: UFA A,[233000000000] + TLO B,777000 +ROUND2: MOVE A,B + RETURN + +CENTRY DTRUNCATE,[V] + + MOVE A,V + UFA A,[233000000000] + TLZ B,777000 + MOVE A,B + RETURN + +CENTRY DABS,[V] + + MOVE A,V + JUMPGE A,RET + MOVN A,A + JUMPGE A,RET + TLZ A,400000 +RET: RETURN + +END + \ No newline at end of file diff --git a/arc/ar5:c/CLIB PRGLST b/arc/ar5:c/CLIB PRGLST new file mode 100644 index 00000000..95593c28 --- /dev/null +++ b/arc/ar5:c/CLIB PRGLST @@ -0,0 +1,46 @@ +; CLIB PRGLST +; *ITS* + +; This file is a Stinkr XFILE that lists the program files that make up the +; shared C library. It is used in the construction of a new library. It +; is also used to construct test versions of programs not using the shared +; library and to construct timing versions of programs (which cannot use +; the shared library). + +; The following are ITS- dependent files from C10LIB: + +l c;c10cor +l c;c10exp +l c;c10fd +l c;c10fil +l c;c10fnm +l c;c10fo +l c;c10int +l c;c10io +l c;c10map +l c;c10mio +l c;c10pag +l c;c10sys +l c;c10tty + +; The following are ITS-independent files from CLIB: + +l c;ac +l c;alloc +l c;apfnam +l c;atoi +l c;blt +l c;cfloat +l c;cprint +l c;date +l c;fprint +l c;match +l c;pr60th +l c;random +l c;stkdmp +l c;string +l c;uuoh + +; This must be last: + +l c;c10run diff --git a/arc/ar5:c/CODE INSERT b/arc/ar5:c/CODE INSERT new file mode 100644 index 00000000..4968883f --- /dev/null +++ b/arc/ar5:c/CODE INSERT @@ -0,0 +1,35 @@ +; MACROS FOR SEPARATE CODE LITERAL AREA +; THIS DOES NOT HANDLE RECURSIVE CALLS + +CD%N==0 +IF1,[CD%LOC==0] + +DEFINE CD%AS *PREFIX*,#SEGNO,*SUFFIX* + PREFIX!SEGNO!SUFFIX + TERMIN + +DEFINE CODE BODY +IF2,[ CD%AS/CD%LOC+CD%/,CD%N+1] + + CD%N==CD%N+1 + DOT==.-1 + CD%OLC==. + IF1,[ + BODY + CD%AS /CD%/,CD%N,/==CD%LOC/ + CD%LOC==CD%LOC+<.-CD%OLC> + ] + IF2,[ + CD%AS /LOC CD%LOC+CD%/,CD%N + BODY + ] + LOC CD%OLC + TERMIN + +DEFINE INSCODE + IF1,[ + CD%SIZ==CD%LOC + CD%LOC==. + BLOCK CD%SIZ + ] + TERMIN diff --git a/arc/ar5:c/CPRINT C b/arc/ar5:c/CPRINT C new file mode 100644 index 00000000..a70d3418 --- /dev/null +++ b/arc/ar5:c/CPRINT C @@ -0,0 +1,177 @@ +/* + + CPRINT - C Formatted Print Routine + + Extendable Format Version: + Print Routines should expect the following + arguments (n specified when defined): + 1 to n: n data arguments + n+1: file descriptor + n+2: field width (0 if none given) + +*/ + +# define WORDMASK 077777777777 +# define SMALLEST "-34359738368" + +extern int cin, cout, cerr; +int prc(), prd(), pro(), prs(); + +static int (*format_table[26]) () { + /* a */ 0, 0, prc, prd, 0, 0, 0, 0, + /* i */ 0, 0, 0, 0, 0, 0, pro, 0, + /* q */ 0, 0, prs, 0, 0, 0, 0, 0, + /* y */ 0, 0}; + +static int format_nargs [26] { + /* a */ 0, 0, 1, 1, 0, 0, 0, 0, + /* i */ 0, 0, 0, 0, 0, 0, 1, 0, + /* q */ 0, 0, 1, 0, 0, 0, 0, 0, + /* y */ 0, 0}; + +deffmt (c, p, n) int (*p)(); + + {if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A'); + if (c >= 'a' && c <= 'z') + {if (n >= 0 && n <= 3) + {format_table [c - 'a'] = p; + format_nargs [c - 'a'] = n; + } + else cprint (cerr, "bad nargs to DEFFMT: %d\n", n); + } + else cprint (cerr, "bad character to DEFFMT: %c\n", c); + } + +cprint (a1,a2,a3,a4,a5,a6,a7,a8) + + {int *adx, c, width; + char *fmt; + int fn, (*p)(), n; + + if (cisfd(a1)) /* file descriptor */ + {fn = a1; + fmt = a2; + adx = &a3; + } + else + {fn = cout; + fmt = a1; + adx = &a2; + } + + while (c= *fmt++) + + {if (c!='%') cputc (c,fn); + else + {width = 0; + while ((c = *fmt)>='0' && c<='9') + width = (width*10) + (*fmt++ - '0'); + c = *fmt++; + if (c >= 'A' && c <= 'Z') c =+ ('a' - 'A'); + if (c >= 'a' && c <= 'z') + {p = format_table [c - 'a']; + n = format_nargs [c - 'a']; + if (p) + {switch (n) { + case 0: (*p) (fn, width); break; + case 1: (*p) (adx[0], fn, width); break; + case 2: (*p) (adx[0], adx[1], fn, width); break; + case 3: (*p) (adx[0], adx[1], adx[2], fn, width); break; + } + adx =+ n; + continue; + } + cputc (c, fn); + } + else cputc (c, fn); + } + } + } + +/********************************************************************** + + PRO - Print Octal Integer + +**********************************************************************/ + +pro (i, f, w) + + {int b[30], *p, a; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + p = b; + while (a = ((i>>3) & WORDMASK)) + {*p++ = (i&07) + '0'; + i = a; + } + *p++ = i+'0'; + if (i) *p++ = '0'; + i = w - (p-b); + while (--i>=0) cputc (' ', f); + while (p > b) cputc (*--p, f); + } + +/********************************************************************** + + PRD - Print Decimal Integer + +**********************************************************************/ + +prd (i, f, w) + + {int b[30], *p, a, flag; + + flag = 0; + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + p = b; + if (i < 0) {i = -i; flag = 1;} + if (i < 0) {stcpy (SMALLEST, b); p = b+slen(b); flag = 0;} + else + {while (a = i/10) + {*p++ = i%10 + '0'; + i = a; + } + *p++ = i+'0'; + } + if (flag) *p++ = '-'; + i = w - (p-b); + while (--i>=0) cputc (' ', f); + while (p > b) cputc (*--p, f); + } + +/********************************************************************** + + PRS - Print String + +**********************************************************************/ + +prs (s, f, w) char *s; + + {int i; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + i = (w > 0 ? w - slen (s) : 0); + while (--i >= 0) cputc (' ', f); + while (i = *s++) cputc (i, f); + } + +/********************************************************************** + + PRC - Print Character + +**********************************************************************/ + +prc (c, f, w) + + {int i; + + if (!cisfd(f)) f = cout; + if (w<0 || w>200) w = 0; + i = w - 1; + while (--i >= 0) cputc (' ', f); + cputc (c, f); + } + \ No newline at end of file diff --git a/arc/ar5:c/CRATE 10 b/arc/ar5:c/CRATE 10 new file mode 100644 index 00000000..5c5f0345 --- /dev/null +++ b/arc/ar5:c/CRATE 10 @@ -0,0 +1,39 @@ +TITLE CRATE C LIBRARY DESECRATOR FOR VERSION 10 +A==1 +GO==JRST + +.GLOBAL INIT,PAGENO,NPAGES,VERNAM +INIT: .VALUE [ASCIZ/: INITIALIZE IF NOT FOR VERSION 10  + /] + .CALL [SETZ + SIXBIT/OPEN/ + 1000,,1 ; CHANNEL 1 + [SIXBIT/DSK/] + [SIXBIT/[CLIB]/] + VERNAM + SETZ [SIXBIT/C/] + ] + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE  +/] + MOVN A,NPAGES + HRLZ A,A + HRR A,PAGENO + .CALL [SETZ + 'CORBLK + 1000,,600000 ; READ-WRITE ACCESS + 1000,,-1 ; PUT IN MY MAP + A ; AOBJN POINTER + 401000,,1 ; FROM FILE + ] + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE  +/] + .CLOSE 1, + .VALUE [ASCIZ/: ALL SET  +:SL /] + GO .-1 + +PAGENO: 246. ; FIRST PAGE TO SMASH +NPAGES: 10. ; NUMBER OF PAGES TO SMASH +VERNAM: SIXBIT/10/ ; VERSION NUMBER IN SIXBIT + +END INIT diff --git a/arc/ar5:c/CRATE 9 b/arc/ar5:c/CRATE 9 new file mode 100644 index 00000000..2a34eeb7 --- /dev/null +++ b/arc/ar5:c/CRATE 9 @@ -0,0 +1,40 @@ +TITLE CRATE C LIBRARY DESECRATOR FOR VERSION 9 +A==1 +GO==JRST + +.GLOBAL INIT,PAGENO,NPAGES,VERNAM +INIT: .VALUE [ASCIZ/: INITIALIZE IF NOT FOR VERSION 9  + /] + .CALL [SETZ + SIXBIT/OPEN/ + 1000,,1 ; CHANNEL 1 + [SIXBIT/DSK/] + [SIXBIT/[CLIB]/] + VERNAM + SETZ [SIXBIT/C/] + ] + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE  +/] + MOVN A,NPAGES + HRLZ A,A + HRR A,PAGENO + .CALL [SETZ + 'CORBLK + 1000,,600000 ; READ-WRITE ACCESS + 1000,,-1 ; PUT IN MY MAP + A ; AOBJN POINTER + 401000,,1 ; FROM FILE + ] + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE  +/] + .CLOSE 1, + .VALUE [ASCIZ/: ALL SET  +:SL /] + GO .-1 + +PAGENO: 371 ; FIRST PAGE TO SMASH +NPAGES: 7 ; NUMBER OF PAGES TO SMASH +VERNAM: SIXBIT/9/ ; VERSION NUMBER IN SIXBIT + +END INIT + \ No newline at end of file diff --git a/arc/ar5:c/CTYPE C b/arc/ar5:c/CTYPE C new file mode 100644 index 00000000..bb3285b9 --- /dev/null +++ b/arc/ar5:c/CTYPE C @@ -0,0 +1,17 @@ +# include "ctype.h" + +# define S _S +# define N _N +# define L _L +# define U _U + +char _ctype[] { + 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, + S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + N, N, N, N, N, N, N, N, N, N, 0, 0, 0, 0, 0, 0, + 0, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, + U, U, U, U, U, U, U, U, U, U, U, 0, 0, 0, 0, 0, + 0, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, + L, L, L, L, L, L, L, L, L, L, L, 0, 0, 0, 0, 0}; + \ No newline at end of file diff --git a/arc/ar5:c/DATE C b/arc/ar5:c/DATE C new file mode 100644 index 00000000..b794ef94 --- /dev/null +++ b/arc/ar5:c/DATE C @@ -0,0 +1,155 @@ +/* + +DATE - Date Hacking Routines + +These routines recognize three representations for dates: + +(1) CAL - calender date, a system-independent representation + consisting of a record containing six integers + for the year, month, day, hour, minute, and second + +(2) FDATE - the ITS date representation used in file directories + +(3) UDATE - the UNIX date representation, seconds since + Jan 1, 1970, GMT. + +(4) TDATE - the TOPS-20 date representation + +The routines: + + u2cal (udate, cd) - convert udate to cal + udate = cal2u (cd) - convert cal to udate + f2cal (fdate, cd) - convert fdate to cal + fdate = cal2f (cd) - convert cal to fdate + t2cal (tdate, cd) + tdate = cal2t (cd) + prcal (cd, fd) - print cal (CIO) + + +*/ + +# define ZONE 5 /* offset of local zone from GMT */ +struct _cal {int year, month, day, hour, minute, second;}; +# define cal struct _cal + +static int month_tab1[] {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static int month_tab2[] {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; +static int year_tab[] {0, 365, 2*365, 3*365+1}; + +# define four_years (4*365+1) + +static char *month_name[] { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + +# rename srctab "SRCTAB" + +u2cal (udate, cd) cal *cd; + + {udate =- (ZONE*60*60); + cd->second = udate%60; udate =/ 60; + cd->minute = udate%60; udate =/ 60; + cd->hour = udate%24; udate =/ 24; + cd->year = 1970 + 4*(udate/four_years); + udate =% four_years; + cd->year =+ srctab (year_tab, 4, &udate); + cd->month = srctab (cd->year%4==0 ? month_tab2 : month_tab1, + 12, &udate) + 1; + cd->day = udate + 1; + } + +int cal2u (cd) cal *cd; + + {int udate, year; + + year = cd->year; + udate = cd->second + 60*(cd->minute + 60*(cd->hour + 24*(cd->day-1))); + udate =+ (year%4==0 ? month_tab2 : month_tab1) [cd->month-1] * 60*60*24; + year =- 1970; + if (year<0) year=0; + udate =+ 60*60*24*(four_years*(year/4) + year_tab[year%4]); + udate =+ (ZONE*60*60); + return (udate); + } + +f2cal (fdate, cd) cal *cd; + + {cd->year = 1900 + ((fdate>>27) & 0177); + if ((cd->month = (fdate>>23) & 017) > 12) cd->month = 0; + cd->day = (fdate>>18) & 037; + fdate = (fdate & 0777777) >> 1; + cd->second = fdate % 60; + fdate =/ 60; + cd->minute = fdate % 60; + cd->hour = fdate / 60; + } + +int cal2f (cd) cal *cd; + + {int fdate; + + fdate = 2*(cd->second + 60*(cd->minute + 60*cd->hour)); + fdate =| cd->day << 18; + fdate =| cd->month << 23; + fdate =| (cd->year - 1900) << 27; + return (fdate); + } + +t2cal (tdate, cd) cal *cd; + + {int vec[3], udate; + SYSODCNV (tdate, 0, vec); + cd->year = vec[0] >> 18; + cd->month = (vec[0] & 0777777) + 1; + cd->day = (vec[1] >> 18) + 1; + udate = vec[2] & 0777777; + cd->second = udate%60; udate =/ 60; + cd->minute = udate%60; udate =/ 60; + cd->hour = udate%24; + } + +int cal2t (cd) cal *cd; + + {char buf[100]; + int f; + f = copen (buf, 'w', "s"); + cprint (f, "%d/%d/%d %d:%d:%d", cd->month, cd->day, cd->year, + cd->hour, cd->minute, cd->second); + cclose (f); + return (SYSIDTIM (mkbptr (buf), 0)); + } + +prcal (cd, f) cal *cd; + + {char *s; + int m; + m = cd->month-1; + if (m>=0 && m<=11) s = month_name[m]; + else s = "?"; + cprint (f, "%s%3d%5d ", s, cd->day, cd->year); + cputc (cd->hour/10+'0', f); + cputc (cd->hour%10+'0', f); + cputc (':', f); + cputc (cd->minute/10+'0', f); + cputc (cd->minute%10+'0', f); + cputc (':', f); + cputc (cd->second/10+'0', f); + cputc (cd->second%10+'0', f); + } + +int srctab (tab, sz, n) int *tab, sz, *n; + + {int *p, i; + + p = tab+sz; + i = *n; + + while (--p>=tab) + {if (*p <= i) + {*n = i - *p; + return (p-tab); + } + } + return (0); + } + \ No newline at end of file diff --git a/arc/ar5:c/FPRINT C b/arc/ar5:c/FPRINT C new file mode 100644 index 00000000..2ff150f2 --- /dev/null +++ b/arc/ar5:c/FPRINT C @@ -0,0 +1,90 @@ +# + +/* + * + * FPRINT - Floating-Point Print Routine + * + * requires: + * + * i = dtruncate (d) + * i = dround (d) + * d = dabs (d) + * cputc (c, fd) + * + * internal routines and tables: + * + * fp3, fp4, fp5, fp6, ft0, ft1, ft10 + * + */ + +static double ft0[] {1e1, 1e2, 1e4, 1e8, 1e16, 1e32}; +static double ft1[] {1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32}; +static double ft10[] {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7}; +double dabs (); + +fprint (d, fd) + double d; + + {if (d<0) {cputc ('-', fd); d = dabs (d);} + if (d>0) + {if (d < 1.0) {fp4 (d, 0, fd); return;} + else if (d >= 1e8) {fp4 (d, 1, fd); return;} + } + fp3 (d, fd); + } + +fp3 (d, fd) /* print positive double */ + double d; + + {int i, n; + double fraction; + + i = dtruncate (d); + fraction = d - i; + n = fp5 (i, fd); /* return # of digits printed */ + cputc ('.', fd); + n = 8 - n; + fraction =* ft10[n]; + i = dround (fraction); + fp6 (i, n, fd); /* prints n digits */ + } + +fp4 (d, flag, fd) + double d; + + {int c, e; + + c = 6; + e = 0; + while (--c >= 0) + {e =<< 1; + if (flag ? d >= ft0[c] : d <= ft1[c]) + {++e; + d =* (flag ? ft1[c] : ft0[c]); + } + } + if (d < 1.0) {++e; d =* 10.0;} + fp3 (d, fd); + cputc ('e', fd); + cputc (flag ? '+' : '-', fd); + fp5 (e, fd); + } + +int fp5 (i, fd) /* print decimal integer, return # of digits printed */ + + {int a; + + if (a = i/10) a = fp5 (a, fd); + else a = 0; + cputc (i%10 + '0', fd); + return (a+1); + } + +int fp6 (i, n, fd) /* print decimal integer given # of digits */ + + {if (n>0) + {if (n>1) fp6 (i/10, n-1, fd); + cputc (i%10 + '0', fd); + } + } + \ No newline at end of file diff --git a/arc/ar5:c/GETSRV C b/arc/ar5:c/GETSRV C new file mode 100644 index 00000000..bc277d58 --- /dev/null +++ b/arc/ar5:c/GETSRV C @@ -0,0 +1,79 @@ +# include "c.defs" + +/********************************************************************** + + GETSRV - Lookup name in table of Arpanet Servers + Currently runs only on ITS machines (needs a particular file). + Requires upper case string. + +**********************************************************************/ + +# define TABLESIZE 10000 + +int getsrv (s) char *s; /* return -1 if bad */ + + {static int *p; + int n, *nmtab; + /* first check for decimal host number */ + n = atoi (s); + if (n > 0) return (n); + /* if not a number, must search the table of host names */ + if (!p) /* host file not read in yet */ + {int f, *q, *e; + char *ss; + p = calloc (TABLESIZE); + ss = "sysbin;hosts1 >"; + f = copen (ss, 'r', "b"); + if (f == OPENLOSS) + {cprint ("Unable to find host table: %s\n", ss); + return (-1); + } + e = p + TABLESIZE; + q = p; + while (!ceof (f) && q= 0) + {int nte, nm, bp; + nte = *nmtab++; + nm = nte & 0777777; /* index of name in table */ + nm = p + nm; /* pointer to name in table */ + bp = 0440700000000 | nm; /* byte pointer to name */ + if (_gmatch (bp, s)) /* found entry */ + {int num; + num = nte >> 18; /* index of numtab entry in table */ + if (p[num+2]<0) /* it's a server */ + return (p[num]); + return (-1); + } + } + return (-1); + } + +_gmatch (bp, s) char *s; + + {int c; + while (c = ildb (&bp)) + if (c != *s++) return (FALSE); + return (*s == 0); + } + + +#ifdef testing +main () + + {char buf[100]; + int n; + + while (TRUE) + {cprint ("Enter name:"); + gets (buf); + n = getsrv (buf); + cprint ("Name=%s,Number=%d\n", buf, n); + } + } + +#endif + \ No newline at end of file diff --git a/arc/ar5:c/ITS BITS b/arc/ar5:c/ITS BITS new file mode 100644 index 00000000..f0a2782b --- /dev/null +++ b/arc/ar5:c/ITS BITS @@ -0,0 +1,77 @@ +/* open modes */ + +# define UAI 0 /* unit ascii input */ +# define UAO 1 /* unit ascii output */ +# define BAI 2 /* block ascii input */ +# define BAO 3 /* block ascii output */ +# define UII 4 /* unit image input */ +# define UIO 5 /* unit image output */ +# define BII 6 /* block image input */ +# define BIO 7 /* block image output */ +# define OLD 010 /* open old job only */ + +/* user variables */ + +# define UPC 0 +# define UTTY 02 +# define UUNAME 04 +# define UJNAME 05 +# define USTOP 07 +# define UPIRQ 010 +# define UINF 011 +# define USV40 013 +# define UIPIRQ 014 +# define UAPIRQ 015 +# define USNAME 016 +# define UPICLR 017 +# define URUNT 024 +# define UHSNAME 043 +# define UOPTION 054 +# define USUPPR 065 +# define UXUNAME 074 +# define UXJNAME 075 + +/* USTOP magic bit */ + +# define BUSRC 0100000000000 + +/* .OPTION bits */ + +# define OPTBRK 020000000000 /* can handle .BREAKs */ +# define OPTCMD 040000000000 /* got command arg to give */ +# define OPTOPC 000200000000 /* always reset PC on interrupt */ + +/* first word interrupt bits */ + +# define PJRLT 0200000000000 /* Real-time timer went off [3] (A) */ +# define PJRUN 0100000000000 /* Run-time timer went off [3] (A) */ +# define PJTTY 02000000000 /* Don't have TTY [2] (S) */ +# define PJPAR 01000000000 /* Memory parity error [1] (A) */ +# define PJFOV 0400000000 /* ARFOV (Floating overflow) [3] (S) */ +# define PJWRO 0200000000 /* WIRO (Write in read-only page) [2] (S) */ +# define PJFET 0100000000 /* Fetched insn from impure page [2] (S) */ +# define PJTRP 040000000 /* SYSUUO (System uuo in trap mode) [2] (S) */ +# define PJDBG 02000000 /* System being debugged state change [3] (A) */ +# define PILOS 01000000 /* .LOSE */ +# define PICLI 0400000 /* CLI interrupt [3] (A) */ +# define PIPDL 0200000 /* PDL overflow [3] (S) */ +# define PILTP 0100000 /* 340 or E&S light pen hit [3] (A) */ +# define PIMAR 040000 /* MAR hit. [2] (S) */ +# define PIMPV 020000 /* MPV (memory protect violation) [2] (S) */ +# define PICLK 010000 /* Slow (1/2 sec) clock [3] (A) */ +# define PI1PR 04000 /* Single-instruction proceed [1] (S) */ +# define PIBRK 02000 /* .BREAK instruction executed. [1] (S) */ +# define PIOOB 01000 /* Address out of bounds [2] (S) */ +# define PIIOC 0400 /* IOCERR (I/O channel error) [2] (S) */ +# define PIVAL 0200 /* .VALUE instruction executed [1] (S) */ +# define PIDWN 0100 /* System-going-down status change [3] (A) */ +# define PIILO 040 /* ILOPR, ILUUO (illegal operation) [2] (S) */ +# define PIDIS 020 /* Display memory protect [2] (A) */ +# define PIARO 010 /* Arithmetic overflow [3] (S) */ +# define PIB42 04 /* BADPI (Bad location 42) [1] (S) */ +# define PICZ 02 /* ^Z or CALL typed on terminal [1] (A) */ +# define PITYI 01 /* TTY input (obsolete) [3] (A) */ + +# define IBACKUP (PJTTY|PJWRO|PJFET|PJTRP|PIMPV|PIOOB|PIIOC|PIILO) + /* interrupts where PC may need SOSing */ + \ No newline at end of file diff --git a/arc/ar5:c/MAKLIB C b/arc/ar5:c/MAKLIB C new file mode 100644 index 00000000..fd2f50a5 --- /dev/null +++ b/arc/ar5:c/MAKLIB C @@ -0,0 +1,283 @@ +# include "c.defs" +# include "its.bits" + +/* + + MAKLIB + + *ITS* + + Shared C Library Construction Program + + Loads library stuff from TS CLIB into an inferior. Writes + pure part as a sharable file. Constructs a MIDAS program + to load the impure part and define all symbols. + + *** Instructions for constructing a new version of the + shared C library: + + 1. Edit the file MKCLIB STINKR to contain all of the + files you want to be in the library. See that file + for further instructions. + 2. Create a TS CLIB in the C directory by running Stinkr on + MKCLIB STINKR. + 3. Create a TS MAKLIB using MAKLIB STINKR. + 4. Run TS MAKLIB. + + The STINKR files are kept in C10LIB. + +*/ + +# define MAXSYMS 4000 /* maximum number of symbols */ +# define NAMMASK 0037777777777 /* name mask away flags */ +# define SYMMASK 0037777777777 /* symtab mask for name */ + +struct _syment {int sym, val;}; +typedef struct _syment syment; +syment symtab[MAXSYMS]; +syment *csymp, *esymp; + +main (argc, argv) char *argv[]; + + {int flib, fmak, version, nam, val, npage, pgno, zeroc; + int j, jch, pch, ilo, ihi, plo, phi, count; + char svers[20], buf[50], vbuf[100]; + filespec ff; + syment *p; + + /* open library program file */ + + pch = fopen ("TS CLIB", UII); + if (pch < 0) + {puts ("Unable to find TS CLIB"); + return; + } + + /* create an inferior job */ + + j = j_create (020); + if (j < 0) + {puts ("Unable to create inferior job"); + return; + } + + j_name (j, &ff); + jch = open (&ff, UII); + if (jch < 0) + {puts ("Unable to open inferior job"); + return; + } + + /* load CLIB program into inferior */ + + if (sysload (jch, pch)) + {puts ("Unable to load TS CLIB"); + return; + } + rsymtab (pch); + + flib = copen ("c/[clib].>", 'w', "b"); + if (flib < 0) + {puts ("Unable to create library file"); + return; + } + filnam (itschan (flib), &ff); + version = ff.fn2; + c6tos (version, svers); + apfname (buf, "c/[cmak].foo", svers); + fmak = copen (buf, 'w'); + if (fmak < 0) + {puts ("Unable to create maker file"); + cclose (flib); + delete ("c/clib.>"); + return; + } + cprint ("Creating C library version %s\n", svers); + cprint (fmak, ";\tSHARED C LIBRARY MAKER -- VERSION %s\n\n", svers); + cprint (fmak, ".INSRT C;NC INSERT\n"); + cprint (fmak, "TITLE CLIB C LIBRARY VERSION %s\n\n", svers); + + p = symtab; + while (p < csymp) + {nam = p->sym; + val = p->val; + ++p; + prname (nam, fmak, 0); + cprint (fmak, "\"=%o\n", val); + } + cputc ('\n', fmak); + + /* now define impure area */ + + ilo = jread (lookup (rdname ("SEG0LO")), jch); + ihi = jread (lookup (rdname ("SEG1HI")), jch); + count = ihi - ilo + 1; + + cprint (fmak, "\t.IDATA\n\n"); + zeroc = 0; + access (jch, ilo); + while (--count >= 0) + {val = uiiot (jch); + if (val) + {if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc); + zeroc = 0; + cprint (fmak, "\t%o\n", val); + } + else ++zeroc; + } + if (zeroc>0) cprint (fmak, "\tBLOCK\t%o\n", zeroc); + cputc ('\n', fmak); + + plo = jread (lookup (rdname ("SEG2LO")), jch); + phi = jread (lookup (rdname ("SEG3HI")), jch); + phi =+ 0100; + plo =& ~01777; + npage = (phi - plo + 02000) >> 10; + pgno = plo >> 10; + + cprint (fmak, "IPATCH\": BLOCK 40\n\ + .CODE\n\ +INIT\": MOVEI P,ARGV\n\ + PUSHJ P,MAPIN\"\n\ + MOVEI A,ZMAIN\"\n\ + HRRM A,CALLER\"\n\ + GO START\"\n\n\ +MAPIN: .CALL [SETZ\n\ + SIXBIT/OPEN/\n\ + 1000,,1 ; CHANNEL 1\n\ + [SIXBIT/DSK/]\n\ + [SIXBIT/[CLIB]/]\n\ + [SIXBIT/%s/]\n\ + SETZ [SIXBIT/C/]\n\ + ]\n\ + .VALUE [ASCIZ/: UNABLE TO GET LIBRARY FILE /]\n\ + MOVE A,[-%d.,,%o]\n\ + .CALL [SETZ\n\ + 'CORBLK\n\ + 1000,,200000 ; READ-ONLY\n\ + 1000,,-1 ; PUT IN MY MAP\n\ + A ; AOBJN POINTER\n\ + 401000,,1 ; FROM FILE\n\ + ]\n\ + .VALUE [ASCIZ/: UNABLE TO MAP IN LIBRARY FILE /]\n\ + .CLOSE 1,\n\ + POPJ P,\n\n\ +MAPOUT\":MOVE A,[-%d.,,%o]\n\ + .CALL [SETZ\n\ + 'CORBLK\n\ + 1000,,0 ; DELETE\n\ + 1000,,-1 ; FROM ME\n\ + 400000,,A ; AOBJN POINTER\n\ + ]\n\ + .VALUE [ASCIZ/: CAN'T MAP OUT LIBRARY PAGES /]\n\ + POPJ P,\n\n\ +SINIT\": MOVE A,[PUSHJ P,MAPIN]\n\ + MOVEM A,ISTART\"\n\ + MOVE A,[PUSHJ P,MAPOUT]\n\ + MOVEM A,IDONE\"\n\ + GO LINIT\"\n\n", svers, npage, pgno, npage, pgno); + + cprint (fmak, ".PDATA\NEND INIT\n"); + cclose (fmak); + + count = phi - plo + 1; + count = (count + 01777) & ~01777; + access (jch, plo); + while (--count >= 0) + {val = uiiot (jch); + cputi (val, flib); + } + cclose (flib); + + fmak = copen (vbuf, 'w', "s"); + cprint (fmak, ":KILL\r:MIDAS C;[CREL] %s _ C;[CMAK] %s\r", svers, svers); + cclose (fmak); + valret (vbuf); + } + +int jread (loc, jch) + + {access (jch, loc); + return (uiiot (jch)); + } + +/********************************************************************** + + SYMBOL TABLE + +**********************************************************************/ + +rsymtab (ch) + + {int count; + csymp = symtab; + esymp = symtab + MAXSYMS; + + uiiot (ch); + count = -((uiiot (ch) >> 18) | 0777777000000) / 2; + uiiot (ch); + uiiot (ch); + --count; + + while (--count >= 0) + {int n, val; + n = uiiot (ch) & SYMMASK; + val = uiiot (ch); + csymp->sym = n; + csymp->val = val; + ++csymp; + } + } + +int lookup (sym) + + {syment *p; + + for (p = symtab; p < csymp; ++p) + if (p->sym == sym) return (p->val); + puts ("symbol missing"); + return (01000000); + } + +char tab40[] {' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', '.', '$', '%'}; + +rdname (p) char *p; + + {int w, factor, c; + char *s; + s = p; + w = 0; + factor = (40*40*40*40*40); + while (c = *s++) + {int i; + if (c==' ') continue; + if (factor == 0) continue; + if (c>='a' && c<='z') c =+ ('A'-'a'); + for (i=0;i<40;++i) + if (c == tab40[i]) + {w =+ (i * factor); + factor =/ 40; + break; + } + if (i>=40) break; + } + return (w); + } + +prname (n, fn, w) + + {n =& NAMMASK; + if (n) p40 (n, fn); + } + +p40 (i, fn) + + {int a; + if (a = i/40) p40 (a, fn); + i =% 40; + if (i) cputc (tab40[i], fn); + } + \ No newline at end of file diff --git a/arc/ar5:c/MAKLIB STINKR b/arc/ar5:c/MAKLIB STINKR new file mode 100644 index 00000000..12b5ed90 --- /dev/null +++ b/arc/ar5:c/MAKLIB STINKR @@ -0,0 +1,7 @@ +x clib +l maklib +l apfnam +l c10job +l c10fnm +o ts maklib + \ No newline at end of file diff --git a/arc/ar5:c/MATCH C b/arc/ar5:c/MATCH C new file mode 100644 index 00000000..635f65e1 --- /dev/null +++ b/arc/ar5:c/MATCH C @@ -0,0 +1,94 @@ +# include "c.defs" + +/********************************************************************** + + SMATCH - pattern matching procedure + + The pattern P is a character string which is to be matched + with the data string S. Certain characters in P are treated + special: + + '*' match any substring + '?' match any character + '\\' quote following character + +**********************************************************************/ + +int smatch (p, s) + char *p; + char *s; + + {int c1, c2, i; + + while (TRUE) + {c1 = *p++; + c2 = *s++; + switch (c1) { + + case 0: return (!c2); + case '?': if (!c2) return (FALSE); + continue; + case '*': while (*p=='*') ++p; + if (*p==0) return (TRUE); + i = -1; + do if (smatch (p, s+i)) return (TRUE); + while (s[i++]); + return (FALSE); + case '\\': if (!(c1 = *p++)) return (FALSE); + /* fall through */ + default: if (c1 != c2) return (FALSE); + continue; + } + } + } + +/********************************************************************** + + SINDEX (P, DS) + + Return the index of the first occurrence of the string P + in the string DS. Return -1 if P does not occur in DS. + +**********************************************************************/ + +int sindex (p, ds) + char *p; + char *ds; + + {int c1, c2, start; + char *s, *t1, *t2, *tail; + + s = ds; + start = p[0]; + tail = p+1; + if (start) while (TRUE) + {while ((c2 = *s++) != start) + if (c2==0) return (-1); + t1 = tail; + t2 = s; + while ((c1 = *t1++) == (c2 = *t2++)) + if (c1==0) break; + if (c1==0) break; + } + return (s-ds-1); + } + +# ifdef test + +int main () + + {char buf1[100], buf2[100]; + + while (TRUE) + {cprint ("Pattern: "); + gets (buf1); + cprint ("Data: "); + gets (buf2); + if (smatch (buf1, buf2)) + cprint ("Matched.\n"); + else cprint ("No match.\n"); + } + } + +# endif + \ No newline at end of file diff --git a/arc/ar5:c/MKCLIB STINKR b/arc/ar5:c/MKCLIB STINKR new file mode 100644 index 00000000..e2ad3d5e --- /dev/null +++ b/arc/ar5:c/MKCLIB STINKR @@ -0,0 +1,29 @@ +; Stinkr xfile for loading basic C library in preparation for construction +; of the shared library. + +; note -- it is proper for ZMAIN to be undefined +; note -- it is proper for DATE to have 3 TOPS-20-related names undefined + +; The last two addresses in the 's' command must be set so that nothing +; overlaps and there is no wraparound. You also have to leave some room +; at the end for consing done during loading. + +; The best procedure is to first use 'p' for the last two numbers, which +; tells Stinkr to allocate from the next page boundary. Then run Stinkr +; to find out how big the segments are. Then you can change the starting +; addresses to push the last to segments as close to the end as possible. +; You should leave about 400 octal words for cons space; if you have not +; left enough, stinker will die saying LBINIT failed. + +; If the library has gotten bigger (more pages), the program C10SAV must +; be changed accordingly. + +; C10SRY should not be here; you want to run it before the library is mapped +; in. +; C10SAV should not be here; it maps out the library as it runs. + +s 100,n,755400,774000 +i lbinit +o ts clib + +x c;clib prglst diff --git a/arc/ar5:c/NC INSERT b/arc/ar5:c/NC INSERT new file mode 100644 index 00000000..4a07ea48 --- /dev/null +++ b/arc/ar5:c/NC INSERT @@ -0,0 +1,62 @@ +; C;NC INSERT + +; THIS FILE IS NEEDED TO ASSEMBLE MIDAS PROGRAMS PRODUCED BY +; THE C COMPILER AS WELL AS HAND-CODED MIDAS PROGRAMS DESIGNED +; TO BE LOADED WITH C PROGRAMS + +RELOCATABLE +.INSRT SYSENG;MULSEG INSERT +.MSEG 200000',600000',700000' + +IF1,[ +.MLLIT==1 + +A=1 +B=2 +C=3 +D=4 +P=15. +.CCALL=1_27. +GO=JRST + +EQUALS ENTRY .GLOBAL +EQUALS EXTERN .GLOBAL + +DEFINE .IDATA +.SEG 0 +TERMIN + +DEFINE .UDATA +.SEG 1 +TERMIN + +DEFINE .CODE +.SEG 2 +TERMIN + +DEFINE .PDATA +.SEG 3 +TERMIN + +; STACK HACKING FOR VARIABLE REFERENCES + +%P==0 +DEFINE PPUSH [A] + PUSH P,A + %P==%P+1 + TERMIN +DEFINE PPOP [A] + POP P,A + %P==%P-1 + TERMIN +DEFINE CCALL N,F + .CCALL N,F + %P==%P-N + TERMIN + +];END IF1 + +IF2,[IFDEF FS1,[ + .KILL %A,%P,A,B,C,D,P,GO,.CCALL + ]] + \ No newline at end of file diff --git a/arc/ar5:c/NM INSERT b/arc/ar5:c/NM INSERT new file mode 100644 index 00000000..f6e2ab30 --- /dev/null +++ b/arc/ar5:c/NM INSERT @@ -0,0 +1,164 @@ +.INSRT C;CODE INSERT + +.OFNM2=SIXBIT/STK/ + +CL=PUSHJ P, +RTN=POPJ P, + +.VCALL=2_33 +.ACALL=3_33 +.XCALL=4_33 + +DEFINE SYSCAL NAME,ARGS,DUMMY,LABEL + SETZ A, + .CALL [SETZ + .1STWD SIXBIT /NAME/ + ARGS + 403000,,A + ] + IFSN [LABEL][]GO LABEL + IFSE [LABEL][]MOVN A,A + TERMIN + +DEFINE INFORM A,B +IF1,[PRINTX \ A = B +\] +TERMIN + +; SUPPORT ROUTINES + +DEFINE %LEN [LIST] +%COUNT==0 +IRP ELEM,,LIST + %COUNT==%COUNT+1 + TERMIN +TERMIN + +DEFINE DEFVAR NAME,#OFFSET + DEFINE NAME +&262143.(P)TERMIN +TERMIN + +; DEFINE C-CALLABLE PROCEDURE (C NAME) + +DEFINE CENTRY NAME,[ARGS],[VARS] + PROLOG Z!NAME,NAME,ARGS,VARS + TERMIN + +; DEFINE C-CALLABLE PROCEDURE (MIDAS NAME) + +DEFINE MENTRY NAME,[ARGS],[VARS] + PROLOG NAME,NAME,ARGS,VARS + TERMIN + +; DEFINE MIDAS ENTRY POINT (NOT PROCEDURE) + +DEFINE IENTRY NAME +NAME": TERMIN + +; PROLOG MACRO + +DEFINE PROLOG MNAME,PNAME,[ARGS],[VARS] + %LEN ARGS + %A==%COUNT + %LEN VARS + %V==%COUNT + %OFF== -<%A+%V> + IRP ARGNAM,,ARGS + DEFVAR ARGNAM,%OFF + %OFF==%OFF+1 + TERMIN + %OFF==%OFF+1 + IRP VARNAM,,VARS + DEFVAR VARNAM,%OFF + %OFF==%OFF+1 + TERMIN + %A,,[ASCIZ/PNAME/] +MNAME": IFN %V,[ADDI P,%V] + TERMIN + +; DEFINE SYNONYM FOR C-CALLABLE ENTRY POINT + +DEFINE XENTRY NEWNAME,OLDNAME +Z!NEWNAME"=Z!OLDNAME" +TERMIN + +; DEFINE MIDAS-ACCESSIBLE DATA + +DEFINE MDATA NAME +NAME":TERMIN + +; FATAL ERROR + +DEFINE CROAK STRING/ +.VALUE [ASCIZ \ +: STRING  +\] +TERMIN + +; RETURN STATEMENT + +DEFINE RETURN + IFE %A,[ + IFN %V,[SUBI P,%V] + POPJ P, + ] + IFN %A,[ + SUBI P,%V+%A+1 + JRST @<%A+1>(P) + ] + TERMIN + +; CALL STATEMENT + +DEFINE CALL NAME,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + ICALL NN,NAME + TERMIN + +; MIDAS-CALL STATEMENT + +DEFINE MCALL NAME,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + CCALL NN,NAME" + TERMIN + +; VARIABLE-CALL STATEMENT + +DEFINE VCALL F,[ARGS] + NN==0 + IRP ARG,,ARGS + PPUSH ARG + NN==NN+1 + TERMIN + CCALL NN,F + TERMIN + +; INTERNAL CALL + +DEFINE ICALL N,NAME + CCALL N,Z!NAME" + TERMIN + +; HACK FOR CONSTANTS + +EQUALS NM%EN END +EXPUNGE END +DEFINE END ENDLOC + .CODE + INSCODE + .PDATA + CONSTANTS + NM%EN ENDLOC + TERMIN + +.CODE + \ No newline at end of file diff --git a/arc/ar5:c/PR60TH C b/arc/ar5:c/PR60TH C new file mode 100644 index 00000000..2e9f453a --- /dev/null +++ b/arc/ar5:c/PR60TH C @@ -0,0 +1,56 @@ +# include "c.defs" + +/********************************************************************** + + PR60TH - Print time in 1/60 sec. + + Print time HH:MM:SS.XX on file FILE. + TIME is in units of 1/60 sec. + +**********************************************************************/ + +pr60th (time, file) + + {int ss, sc, mn, hour, zs; + + if (time < 0) time = -time; + zs = TRUE; + ss = time%60; + time = time/60; + sc = time%60; + time = time/60; + mn = time%60; + hour = time/60; + if (hour) + {cprint (file, "%3d:", hour); + zs = FALSE; + } + else cprint (file, " "); + xput2 (mn, file, zs); + if (zs && mn==0) cputc (' ', file); + else + {cputc (':', file); + zs = FALSE; + } + if (zs && !sc) + {cputc (' ', file); + cputc ('0', file); + } + else + {xput2 (sc, file, zs); + zs = FALSE; + } + cputc ('.', file); + xput2 (ss, file, FALSE); + } + +xput2 (val, file, zs) + + {int num; + num = val/10; + if (num>0 || !zs) {cputc ('0'+num, file); zs=FALSE;} + else cputc (' ', file); + num = val%10; + if (num>0 || !zs) cputc ('0'+num, file); + else cputc (' ', file); + } diff --git a/arc/ar5:c/RANDOM CMID b/arc/ar5:c/RANDOM CMID new file mode 100644 index 00000000..89813a85 --- /dev/null +++ b/arc/ar5:c/RANDOM CMID @@ -0,0 +1,31 @@ +; +; RANDOM - RANDOM NUMBER GENERATOR (STOLEN FROM MUDDLE) +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE RANDOM +.INSRT NC +.INSRT NM + +CENTRY SRAND,[SEED] + MOVE A,SEED + ROT A,-1 + MOVEM A,RLOW + RETURN + +CENTRY RAND + MOVE A,RHI + MOVE B,RLOW + MOVEM A,RLOW ;Update Low seed + LSHC A,-1 ;Shift both right one bit + XORB B,RHI ;Generate output and update High seed + MOVE A,B + RETURN + +.IDATA +RHI: 267762113337 +RLOW: 155256071112 +.PDATA + +END diff --git a/arc/ar5:c/STDIO H b/arc/ar5:c/STDIO H new file mode 100644 index 00000000..25bd9ca3 --- /dev/null +++ b/arc/ar5:c/STDIO H @@ -0,0 +1,17 @@ +# define BUFSIZ 512 +# define FILE int +# define NULL 0 +# define EOF (-1) + +# define peekchar pkchar /* avoid name conflict */ +# define fopen flopen /* " */ +# define getc fgetc /* " */ +# define getchar fgeth /* " */ + +# define feof ceof /* direct translation */ +# define putc cputc /* " */ + +extern FILE *stdin, *stdout, *stderr; + +# define ITS ITS + \ No newline at end of file diff --git a/arc/ar5:c/STKDMP C b/arc/ar5:c/STKDMP C new file mode 100644 index 00000000..48b390d0 --- /dev/null +++ b/arc/ar5:c/STKDMP C @@ -0,0 +1,249 @@ +# include "c.defs" + +/********************************************************************** + + STKDMP - C Stack Dumping Routine + + This file is PDP-10 dependent, but essentially system + independent. + +**********************************************************************/ + +# rename findproc "FINDPR" +# rename findframe "FINDFR" +# rename print_name "PRNAME" +# rename callok "CALLOK" + +# rename hack "STKDMP" +# rename seg2lo "SEG2LO" +# rename seg2hi "SEG2HI" +# rename seg3lo "SEG3LO" +# rename seg3hi "SEG3HI" +# rename pdlbot "PDLBOT" +# rename pdltop "PDLTOP" +# rename purbot "PURBOT" +# rename purtop "PURTOP" +# rename intptr "INTPTR" +# rename mpvh "MPVH" +# rename etsint "ETSINT" +# rename uuoh "UUOH" +# rename uuohan "UUO$HA" +# rename euuoh "EUUOH" +# rename caller "CALLER" + +# define ADDI_P 0271740 +# define SUBI_P 0275740 +# define GO_P 0254037 +# define JSP_D 0265200 +# define GO 0254000 + +# define left(x) (((x) >> 18) & 0777777) +# define right(x) ((x) & 0777777) + +extern int *seg2lo, *seg2hi, *seg3lo, *seg3hi, + *pdlbot, *pdltop, *purbot, *purtop, *caller, + mpvh[], etsint[], intptr, uuoh[], uuohan[], euuoh[], + cout, *findframe(), *findproc(), hack[]; + +/********************************************************************** + + STKDMP - Dump stack. + +**********************************************************************/ + +static int tuuoh; + +stkdmp (fd) + + {int *pc; /* procedure pointer */ + int *opc; /* previously printed-out pc */ + int *sp; /* stack pointer */ + + if (!cisfd(fd)) fd = cout; + cputc ('\n', fd); + tuuoh = uuoh[0]; + sp = &fd; /* arg is on the stack */ + pc = right(sp[1]); /* my caller's pc is on the stack */ + opc = -1; + --sp; /* top of stack when he was running */ + if (pc >= hack && pc <= hack+12) /* PUSHJ P,STKDMP$X */ + {pc = right(sp[0]); /* 'real' caller */ + sp =- 7; /* 'real' stack top */ + } + while (TRUE) + {int *proc, nargs, *npc, *namep, *ap; + proc = findproc (pc); + if (proc == 0) break; + nargs = left(proc[-1]); + namep = right(proc[-1]); + sp = findframe (sp, proc, pc); + if (sp == 0) + {if (opc != caller) + {cprint (fd, " "); + print_name (namep, fd); + cprint (fd, "\n"); + } + break; + } + npc = right(sp[0]); + sp =- nargs; + ap = sp; + --sp; + cprint (fd, "%7o ", sp); + print_name (namep, fd); + cprint (fd, " ("); + if (nargs>10) nargs = 10; + while (--nargs >= 0) + {cprint (fd, "%o", *ap++); + if (nargs) cprint (fd, ", "); + } + cprint (fd, ")\n"); + opc = proc; + pc = npc; + } + } + +/********************************************************************** + + FINDPROC - Find beginning of active procedure, given a PC. + +**********************************************************************/ + +int *findproc (pc) int *pc; + + {int *low, *high, n; + + n = 3; + while (--n>=0) + {if (pc >= mpvh && pc < etsint) + {int *p; + p = right(intptr); + pc = right(p[-4]); + continue; + } + if (pc == uuoh+1 || (pc >= uuohan && pc < euuoh)) + {pc = right(tuuoh); + if ((pc[0]>>29)==0) ++pc; /* hack */ + continue; + } + } + if (pc > seg2lo && pc <= seg2hi) + {low = seg2lo; + high = seg2hi; + } + else if (pc > purbot && pc <= purtop) + {low = purbot; + high = purtop; + } + else return (0); + + ++pc; + while (--pc > low) + {int data, c, nargs, *namep; + if ((*pc >> 27) == 0) continue; + data = pc[-1]; + nargs = left(data); + namep = right(data); + if (nargs >= 16) continue; + if (namep < seg3lo || namep > seg3hi) continue; + c = (*namep >> 29); /* left byte */ + if (c < ' ' || c > 'z') continue; + return (pc); + } + return (0); + } + +/********************************************************************** + + FINDFRAME - Find stack frame, given stack top and procedure + pointer, and PC within procedure. Returns pointer + to return address on stack. + +**********************************************************************/ + +int *findframe (sp, proc, pc) int *sp, *proc, *pc; + + {int instr, signal(); + + instr = proc[0]; + if (left(instr) == ADDI_P) /* procedure allocates a frame */ + {int bump; + bump = right(instr); /* local frame size */ + if (pc == proc); /* hasn't allocated it yet */ + else if (left(pc[0]) == GO_P); /* has popped it */ + else sp =- bump; + } + if (pc >= mpvh && pc < etsint) /* was in interrupt handler */ + sp =- 17; /* ignore stuff pushed by handler */ + /* !!! the above is wrong !!! */ + + ++sp; + while (--sp >= pdlbot) + {int data, *opc; + data = *sp; + + /* look for return address word on stack */ + /* check for reasonable status bits */ + if (!(data & 0010000000000)) continue; + /* must be in user mode */ + if (data & 0027637000000) continue; /* bad for status bits */ + + /* check for reasonable old PC (within code segment) */ + opc = right(data) - 1; + if (opc < seg2lo) continue; + if (opc > seg2hi) continue; + + /* check to see if old PC was call to current proc */ + if (callok (opc, proc)) + {if (proc == signal && opc>=mpvh && opc='A' && c<='Z' ? c+('a'-'A') : c, fd); + } + \ No newline at end of file diff --git a/arc/ar5:c/STRING CMID b/arc/ar5:c/STRING CMID new file mode 100644 index 00000000..3d6b68d3 --- /dev/null +++ b/arc/ar5:c/STRING CMID @@ -0,0 +1,132 @@ +; +; STRING - C STRING, BYTE, AND BIT ROUTINES +; +; This file is PDP-10 dependent, system-independent. +; + +TITLE STRING +.INSRT NC +.INSRT NM + +; CONTAINS: + +; SLEN ; STRING LENGTH +; STCPY ; STRING COPY +; STCMP ; STRING COMPARE +; LOWER ; CVT CHAR TO LOWER CASE +; UPPER ; CVT CHAR TO UPPER CASE + +; BGET ; BIT ARRAY BIT GET +; BSET ; BIT ARRAY BIT SET + +; ILDB ; INCREMENT AND LOAD BYTE +; IDPB ; INCREMENT AND DEPOSIT BYTE + +CENTRY SLEN,[STR] ; STRING LENGTH + + MOVE B,STR ; POINTER TO STRING + SETZ A, ; COUNTER +SL$1: MOVE C,(B) ; GET NEXT CHARACTER + SKIPN C + GO SL$RET ; RETURN ON NULL CHAR + ADDI A,1 ; INCR COUNTER + ADDI B,1 ; INCR POINTER + GO SL$1 +SL$RET: RETURN + +CENTRY STCPY,[SRC,DEST] ; STRING COPY + + ; COPY STRING FROM SRC TO DEST + ; RETURN POINTER TO NULL TERMINATING NEW COPY + + MOVE B,SRC ; SOURCE POINTER + MOVE A,DEST ; DESTINATION POINTER +SC$1: MOVE C,(B) ; GET NEXT CHAR + MOVEM C,(A) ; STORE + SKIPN C + GO SC$RET ; RETURN AFTER WRITING NULL CHAR + ADDI B,1 ; INCR SOURCE PTR + ADDI A,1 ; INCR DESTINATION PTR + GO SC$1 +SC$RET: RETURN + +CENTRY STCMP,[S1,S2] ; STRING COMPARE + + MOVE B,S1 + MOVE C,S2 +SM$1: MOVE A,(B) ; GET NEXT CHAR + CAME A,(C) + GO SM$2 ; DIFFERENCE FOUND + ADDI B,1 ; INCR PTR1 + ADDI C,1 ; INCR PTR2 + JUMPN A,SM$1 + SETO A, + GO SM$RET +SM$2: SETZ A, +SM$RET: RETURN + +CENTRY LOWER,[CH] ; CVT CHAR TO LOWER CASE + + MOVE A,CH + CAIGE A,"A + GO LW$RET + CAILE A,"Z + GO LW$RET + ADDI A,"a-"A +LW$RET: RETURN + +CENTRY UPPER,[CH] ; CVT CHAR TO UPPER CASE + + MOVE A,CH + CAIGE A,"a + GO UP$RET + CAILE A,"z + GO UP$RET + SUBI A,"a-"A +UP$RET: RETURN + +CENTRY BGET,[BARRAY,BINDEX] ; BIT ARRAY BIT GET + + HRRZ C,BINDEX + HRRZ A,BARRAY + MOVEI B,(C) ; SUBSCRIPT + + LSH C,-5 ; GET WORD OFFSET + ADDI A,(C) ; GET WORD ADDRESS + MOVE A,(A) ; GET THE WORD + ANDI B,37 ; BIT OFFSET + ROT A,1(B) ; PUT BIT IN RIGHT-MOST POSITION + ANDI A,1 ; GET THE BIT + RETURN + +CENTRY BSET,[BARRAY,BINDEX] ; BIT ARRAY BIT SET + + HRRZ C,BINDEX + HRRZ A,BARRAY + MOVEI B,(C) ; SUBSCRIPT + + LSH C,-5 ; GET WORD OFFSET + ADDI A,(C) ; GET WORD ADDRESS + ANDI B,37 ; BIT OFFSET + MOVN B,B ; NEGATIVE BIT OFFSET + MOVEI C,1 ; A BIT + ROT C,-1(B) ; PUT IN RIGHT POSITION + IORM C,(A) ; SMASH ARRAY WORD + MOVEI A,1 + RETURN + +CENTRY ILDB,[ABPTR] ; INCREMENT AND LOAD BYTE + + HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER + ILDB A,(A) + RETURN + +CENTRY IDPB,[CH,ABPTR] ; INCREMENT AND DEPOSIT BYTE + + MOVE B,CH ; THE CHARACTER + HRRZ A,ABPTR ; ADDRESS OF BYTE POINTER + IDPB B,(A) + RETURN + +END + \ No newline at end of file diff --git a/arc/ar5:c/TESTFD C b/arc/ar5:c/TESTFD C new file mode 100644 index 00000000..1e000dfd --- /dev/null +++ b/arc/ar5:c/TESTFD C @@ -0,0 +1,19 @@ +/********************************************************************** + + TSTFD + Test routine for FD + +**********************************************************************/ + +main () + + {char buf[200]; + extern int puts (); + for (;;) + {cprint ("Enter pattern: "); + gets (buf); + fdmap (buf, puts); + puts (""); + } + } + \ No newline at end of file diff --git a/arc/ar5:c/TTIME C b/arc/ar5:c/TTIME C new file mode 100644 index 00000000..0a9c7636 --- /dev/null +++ b/arc/ar5:c/TTIME C @@ -0,0 +1,123 @@ +/********************************************************************** + + TTIME - Test program for Timing + +**********************************************************************/ + +# rename timing "TIMING" +extern int timing; + +main () + + {int i; + i = 10000; + if (timing) i = 1000; + while (--i >= 0) foo (); + } + +foo () /* calls null 100 times */ + + { + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + null(); + } + +null () {;} diff --git a/arc/ar5:c/UUOH CMID b/arc/ar5:c/UUOH CMID new file mode 100644 index 0000000000000000000000000000000000000000..e73477fb2557ab4b6b796f3e47a5f69e41b55f33 GIT binary patch literal 3570 zcmcguO>f*b5bafq?thp=4mPS?$ccjh_93Mx?uuDS6!@`mY~)ZNE*c;WiYAx-`@SKm z)ozf&aU0Ztu@dz-Gki1ihS$r*brFJTX+@IoKhq3 z#??hd@9zJ&|M>3y!J!45A}pw~ja5OdI0EwBfb( zEvXxCMFv_mD&d(5#Q)P}wOW^V=?pL59$2V_(~19y3uPxBbmF1spO`B+ukgP${Pv_3 zL(?%j0bDN}I4@QgU^|>_bz-kTXi;}Y?g-zrNnU4W)B4ksb*3h*KRa1(4(pfjBTa*} z9p`Ee3&7s&RbMn^U{AcWYihjSJ$qI?ud1@Vtlk#av{jKMO2+tjKPS@8nsa=fh#_#L z8Zra&ILz`P3mr~nGG z77gPDLoT3ck3nq*LshxDIFsj-ts(TavfOhUWBa**q|hC(Poq<-ghO|6Lni!7xFqIk zc2~y3iW7%!r^lg)MbG|RYeLtMrnquA%E8tXSd5{U)F~7rX^(HtIId2J6@NslTjd-F z%oWB|0K<$Hb;-2|41dUJgSdGcB#Q%JzPknL1^z(hHQg#}$OKQUIyL`hEMi#kQG<{SB<-C&O!t1j=JzNjwe#^PY-BnauloP@_D z%mp@nsFB%Zmb++}rIAae12jkx$ufpE>NO?L6JQ$wHxr=e>YWixw+7;D46c1eV|fm{ zt?hbVOF2j>&RGBr5eZaou$nDfwNf`q20!HyjV_Z=46qb2r}WIyO|1P%u3QW7b2jK& zy_sm2GW4Mn-dGxqi{k6lz^acl`rJ}bst_9uG^r~EBuPb?BlvPNx0=sYUW2Rq=p(FIn~C?iR0 z@P>}kP@W6k)baRp5X#P&9pT21Pnu>3zpx^O0fzPPg*J0%j&q!&8G+qQHVsTHp zR+VAj3c16PJ(Mj87eg~F?2*Co3RC43&$qB|jP?Ly`jHYCn7BaB+QO=Z+})ujf#J6_ zGysA}PF*w?D+FdaJ<0u5fxmwUp}?4dW>","=<<","=+","=-","=*","=/","=%","=&","=^","=|"}; + +# include "cnop.h" + +char *sterm[] { + "", "-|", "error", ";", "}", "{", + "]", "[", ")", "(", ":", ",", + ".", "?", "~", "!", "&", "|", + "^", "%", "/", "*", "-", "+", + "=", "<", ">", "++", "--", "==", + "!=", "<=", ">=", "<<", ">>", "->", + "=op", "&&", "||", "c", "INT", "CHAR", + "FLOAT", "DOUBLE", "STRUCT", "AUTO", "STATIC", "EXTERN", + "RETURN", "GOTO", "IF", "ELSE", "SWITCH", "BREAK", + "CONTINUE", "WHILE", "DO", "FOR", "DEFAULT", "CASE", + "ENTRY", "REGISTER", "SIZEOF", "LONG", "SHORT", "UNSIGNED", + "TYPEDEF", "l", "m", "n", "o", "p", + "q", "r", "s", "identifier", "integer", "floatcon", + "string", 0}; + +char *snterm[] { + "", "$accept", "program", "external_definition", "function_definition", "function_specification", + "function_body", "formal_declarations", "compound_statement", "init_declarator_list", "init_declarator", "initializer", + "initial_value_expression_list", "initial_value", "initial_value_expression", "declaration_list", "declaration", "decl_specifiers", + "type_specifier", "literal_type_specifier", "sc_specifier", "declarator_list", "declarator", "$declarator", + "dclr", "function_declarator", "parameter_list", "formal_decl_list", "formal_declaration", "type_decl_list", + "type_declaration", "$type_specifier", "statement_list", "statement", ".expression", "expression_list", + "expression", "lexpression", "fterm", "type_identifier", "term", "cast_type", + "null_decl", "while", "do", "for", "switch", "struct", + "$identifier", "begin", "end", "constant", "c_term", 0}; + +int sq[] { + 0, 0, 4098, 9, 21, 40, 41, 42, 43, 44, + 45, 46, 47, 61, 63, 64, 65, 66, 75, 4099, + 4100, 4101, 4112, 4113, 4114, 4115, 4116, 4121, 4135, 4143, + 75, 4121, 4121, 40, 42, 40, 40, 9, 61, 75, + 4102, 4103, 4114, 4115, 4123, 4124, 4126, 4127, 9, 21, + 75, 4121, 10, 4105, 4106, 4118, 4119, 4120, 4116, 3, + 4114, 9, 7, 5, 75, 4144, 8, 8, 75, 4122, + 4126, 5, 4104, 4145, 4124, 9, 21, 75, 4117, 4118, + 4120, 75, 4120, 4120, 10, 9, 14, 15, 22, 76, + 4147, 4148, 11, 3, 5, 16, 22, 75, 76, 77, + 78, 4107, 4109, 9, 7, 8, 6, 4147, 4125, 4126, + 5, 8, 11, 75, 4111, 4112, 4113, 3, 9, 14, + 15, 16, 21, 22, 27, 28, 48, 49, 50, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 62, 76, + 77, 78, 4104, 4128, 4129, 4132, 4134, 4136, 4139, 4140, + 4141, 4142, 75, 11, 3, 8, 4147, 4147, 4148, 4148, + 4148, 21, 20, 19, 23, 22, 33, 34, 25, 26, + 31, 32, 29, 30, 16, 18, 17, 37, 38, 13, + 4106, 4121, 22, 76, 4108, 4109, 4110, 4147, 75, 76, + 77, 8, 6, 4147, 6, 4, 4126, 4125, 75, 10, + 4128, 4112, 4115, 4137, 75, 4132, 4136, 4136, 4136, 4136, + 4136, 4136, 4136, 3, 4132, 75, 4132, 4133, 9, 3, + 3, 10, 4147, 75, 9, 4136, 4, 4146, 75, 4129, + 3, 21, 20, 19, 23, 22, 33, 34, 25, 26, + 31, 32, 29, 30, 16, 18, 17, 37, 38, 13, + 24, 36, 11, 9, 27, 28, 7, 12, 35, 9, + 4129, 9, 9, 4118, 8, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147, + 4147, 4147, 4147, 4147, 76, 4, 11, 6, 4, 4129, + 4146, 9, 21, 4138, 8, 8, 3, 3, 4132, 4129, + 10, 10, 4137, 4132, 4132, 4132, 4132, 4132, 4132, 4132, + 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, + 4132, 4132, 4132, 4132, 4132, 4131, 4132, 8, 4132, 75, + 75, 4132, 55, 4130, 4132, 4132, 10, 4, 4110, 8, + 4138, 4138, 7, 4136, 8, 4129, 4129, 8, 10, 11, + 8, 6, 8, 9, 3, 8, 4147, 8, 6, 4147, + 4129, 4132, 4132, 4129, 4132, 4130, 4129, 9, 6, 51, + 8, 3, 8, 4129, 3, 4130, 8, 4129, -1}; + +/********************************************************************** + + ERROR MESSAGES + +**********************************************************************/ + +char *m1000[] { + +/* 1000 */ "INVALID CHARACTER", +/* 1001 */ "UNTERMINATED COMMENT", +/* 1002 */ "CHARACTER CONSTANT TOO LONG", +/* 1003 */ "UNTERMINATED CHARACTER CONSTANT", +/* 1004 */ "%t: BAD FUNCTION RETURN TYPE CHANGED TO POINTER", +/* 1005 */ "%t: INVALID USE OF FUNCTION TYPE CHANGED TO POINTER", +/* 1006 */ "UNUSED AUTOMATIC VARIABLE: %t", +/* 1007 */ 0, +/* 1008 */ 0, +/* 1009 */ 0, +/* 1010 */ "INVALID RENAME CONTROL LINE", +/* 1011 */ "UNTERMINATED COMPILE-TIME CONDITIONAL", +/* 1012 */ "INVALID MANIFEST CONSTANT DEFINITION", +/* 1013 */ "INVALID COMPILER CONTROL LINE", +/* 1014 */ "INVALID INCLUDE CONTROL LINE", +/* 1015 */ 0, +/* 1016 */ 0, +/* 1017 */ "TOO FEW ARGUMENTS IN MACRO INVOCATION", +/* 1018 */ "AUTOMATIC EXTERNAL DEFINITIONS NOT ALLOWED", +/* 1019 */ "CLASS DECLARATIONS NOT ALLOWED FOR FUNCTIONS", +/* 1020 */ "INVALID IFDEF OR IFNDEF CONTROL LINE", +/* 1021 */ "%t: FUNCTIONS MUST BE EXTERNAL", +/* 1022 */ "%t: INVALID INITIALIZER TYPE", +/* 1023 */ "%t: TOO MANY INITIALIZERS", +/* 1024 */ "%t: INITIALIZATION OF AUTO VARIABLES NOT IMPLEMENTED", +/* 1025 */ 0, +/* 1026 */ "%t: INITIALIZATION NOT ALLOWED", +/* 1027 */ "%t NOT A PARAMETER", +/* 1028 */ "EMITOP(C): NO MACRO FOR OP %o", +/* 1029 */ "CHOOSE(C): NO OPLOC FOR OP %o", +/* 1030 */ "INVALID UNDEFINE", +/* 1031 */ "%t: INVALID ARRAY SIZE SPECIFICATION", +/* 1032 */ "%t: BIT FIELD NOT IN STRUCTURE DEFINITION", +/* 1033 */ "%t: INVALID BIT FIELD WIDTH", +/* 1034 */ "%t: BIT FIELD MUST BE INT" + }; + +char *m2000[] { + +/* 2000 */ "LINE TOO LONG", +/* 2001 */ "UNTERMINATED STRING CONSTANT", +/* 2002 */ "NOTHING TO BREAK FROM", +/* 2003 */ "NOTHING TO CONTINUE", +/* 2004 */ "CASE NOT IN SWITCH", +/* 2005 */ "DEFAULT NOT IN SWITCH", +/* 2006 */ "%q DELETED", +/* 2007 */ "SYNTAX ERROR. PARSE SO FAR: ", +/* 2008 */ " %q", +/* 2009 */ "TYPE OF EXPRESSION IN GOTO IS INVALID", +/* 2010 */ " |_ ", +/* 2011 */ " %t", +/* 2012 */ "DELETED: ", +/* 2013 */ "SKIPPED: ", +/* 2014 */ "DECLARATION OF %t TOO COMPLICATED", +/* 2015 */ "%t: TOO MANY DIMENSIONS", +/* 2016 */ "INVALID REDECLARATION OF %t", +/* 2017 */ "UNDEFINED LABEL: %t", +/* 2018 */ "INVALID REDEFINITION OF STRUCTURE %t", +/* 2019 */ "INVALID RECURSION IN STRUCTURE DEFINITION", +/* 2020 */ "DUPLICATE CASE IN SWITCH", +/* 2021 */ "MULTIPLE DEFAULT STATEMENTS IN SWITCH", +/* 2022 */ "TYPE OF OPERAND OF %n IS INVALID", +/* 2023 */ "LVALUE REQUIRED AS OPERAND OF %n", +/* 2024 */ "UNDEFINED STRUCTURE: %t", +/* 2025 */ "TYPES OF SUBTRACTED POINTERS MUST BE IDENTICAL", +/* 2026 */ "INVALID CONVERSION OF OPERAND OF %n", +/* 2027 */ "%t UNDEFINED", +/* 2028 */ "CALL OF NON-FUNCTION", +/* 2029 */ "%t NOT A MEMBER OF THE SPECIFIED STRUCTURE", +/* 2030 */ "STRUCTURE REQUIRED", +/* 2031 */ "TYPE CLASH IN CONDITIONAL", +/* 2032 */ "INVALID POINTER COMPARISON", +/* 2033 */ "COPYING OF STRUCTURES NOT IMPLEMENTED", +/* 2034 */ "INVALID POINTER SUBTRACTION", +/* 2035 */ "TEXPR(C): NO MATCH FOR OP %o", +/* 2036 */ "%t: INVALID TYPE OF PARAMETER", +/* 2037 */ "INVALID MACRO DEFINITION", +/* 2038 */ "%t: INITIALIZER MUST BE EXTERNAL OR STATIC", +/* 2039 */ "TOO MANY ARGUMENTS IN FUNCTION CALL", +/* 2040 */ "INVALID USE OF UNDEFINED STRUCTURE %t", +/* 2041 */ "%t IS NOT A TYPE", +/* 2042 */ "INVALID USE OF TYPE NAME %t" + }; + +char *m4000[] { + +/* 4000 */ "NAME TABLE OVERFLOW", +/* 4001 */ "FLOAT/NAME TABLE OVERFLOW", +/* 4002 */ "TOO MANY NESTED DO/WHILE/FOR/SWITCH GROUPS", +/* 4003 */ "PROGRAM TOO COMPLICATED. PARSER STACK OVERFLOW.", +/* 4004 */ "MANIFEST CONSTANT DEFINITION TABLE OVERFLOW", +/* 4005 */ "PROGRAM TOO LARGE: SYMBOL TABLE OVERFLOW", +/* 4006 */ "TYPE TABLE OVERFLOW.", +/* 4007 */ "DECLARATION TOO COMPLICATED", +/* 4008 */ 0, +/* 4009 */ 0, +/* 4010 */ "SWITCH TABLE OVERFLOW: TOO MANY CASES", +/* 4011 */ "EXPRESSION TOO COMPLICATED", +/* 4012 */ "I GIVE UP", +/* 4013 */ "FUNCTION TOO LARGE", +/* 4014 */ "TOO MANY MACRO ARGUMENTS", +/* 4015 */ "UNTERMINATED MACRO DEFINITION", +/* 4016 */ "MACRO ARGUMENTS TOO LONG", +/* 4017 */ "UNTERMINATED MACRO INVOCATION", +/* 4018 */ "TOO MANY NESTED MACRO INVOCATIONS", +/* 4019 */ "TOO MANY NESTED INCLUDE FILES" + }; + +char *m6000[] { + +/* 6000 */ "T(P): ATTEMPT TO REFERENCE T(%d)", +/* 6001 */ "TTEXPR(C): EMPTY REGISTER SET", +/* 6002 */ "POP(P): ATTEMPT TO POP EMPTY DCL STACK", +/* 6003 */ "ASTMT(C): OP %d IN CASE CHAIN", +/* 6004 */ "ICB_GET(M): NO MORE INPUT CONTROL BLOCKS", +/* 6005 */ "TP2O(P): BAD TYPE", +/* 6006 */ "TO2P(C): BAD TYPE", +/* 6007 */ "CGOP(C): RESULT IN INDETERMINATE MEMORY LOCATION", +/* 6008 */ "LEX(P): TOKEN BUFFER OVERFLOW", +/* 6009 */ "ATTRIB(P): INVALID CLASS", +/* 6010 */ "SETSP(P): BAD STACK POINTER", +/* 6011 */ 0, +/* 6012 */ "CGMOVE(C): NON-TEMPORARY MEMORY LOCATION DEMANDED", +/* 6013 */ "FREEREG(C): BAD ARGUMENT", +/* 6014 */ "FIXTYPE(PC): BAD TYPE", +/* 6015 */ "FIXSTR(C): BAD CALL", +/* 6016 */ 0, +/* 6017 */ "RESERVE(C): REGISTER %d NOT FREE", +/* 6018 */ "RESERVE(C): CONFLICTED REGISTER %d NOT FREE", +/* 6019 */ "CLEAR(C): BAD ARGUMENT %d", +/* 6020 */ "ERRCIDN(C): BAD CALL", +/* 6021 */ "CLEAR(C): REGISTER %d BAD UCODE", +/* 6022 */ "SAVE1(C): BAD ARGUMENT %d", +/* 6023 */ "SAVE(C): UNABLE TO FREE REGISTER %d", +/* 6024 */ "MMOVE(C): BAD CTYPE %d", +/* 6025 */ "ANAME(M): ADDRESSING ERROR", +/* 6026 */ "FUDGE(C): BAD ARGUMENT", +/* 6027 */ "READ_NODE(C): BAD OP %d AT LOC %d", +/* 6028 */ 0, +/* 6029 */ "CGCALL(C): BAD RETURN REGISTER", +/* 6030 */ "CRETURN(C): BAD RETURN REGISTER", +/* 6031 */ "CHOOSE(C): NO ACCEPTABLE OPLOC FOR OP %o", +/* 6032 */ "LEX(P): INCONSISTENT TOKEN POINTERS", +/* 6033 */ "PARSE(P): ATTEMPT TO POP EMTPY PARSER STACK", +/* 6034 */ 0, +/* 6035 */ "DP2O(P): BAD DICTIONARY POINTER", +/* 6036 */ 0, +/* 6037 */ "RP2O(P): BAD RECORD POINTER", +/* 6038 */ "CGMOVE(C): UNABLE TO MOVE TO DESIRED LOCATION", +/* 6039 */ "CGMOVE(C): BAD LOC ARGUMENT [%d,%d]", +/* 6040 */ "GETREG(C): BAD ARGUMENT", +/* 6041 */ "INZ(P): BAD INITIALIZER", +/* 6042 */ "DEFCCL(L): COMPILER CONTROL LINE TABLE OVERFLOW", +/* 6043 */ "TOKGET(L): UNRECOGNIZED OPERATOR %d", +/* 6044 */ "MARK(C): REGISTER %d ALREADY MARKED", +/* 6045 */ "UNMARK(C): REGISTER %d NOT MARKED", +/* 6046 */ "CG_FARG(C): DOUBLE ARG IS SHARED", +/* 6047 */ "RO2P(C): BAD RECORD OFFSET" + }; + +/********************************************************************** + + ERROR EDITOR PHASE - MAIN ROUTINE + +**********************************************************************/ + +# ifndef CALL_ERROR + +main (argc, argv) int argc; char *argv[]; + + {if (argc < 4) + {cprint ("C7 Called With Too Few Arguments.\n"); + cexit (100); + } + + cexit (perror (argv[2], argv[3])); + } + +# endif + +/********************************************************************** + + PERROR - Error Editor Processing Routine + +**********************************************************************/ + +perror (fner, fncs) + + {int f_error, lineno, i, p[5], errno, cst_read; + char *f; + + fn_cstore = fncs; + cst_read = FALSE; + + f_error = copen (fner, MREAD, BINARY); + if (f_error == OPENLOSS) return (0); + + while (TRUE) + {errno = geti (f_error); + if (errno==0) + {if (cst_read) eputc ('\n'); + cclose (f_error); + return (0); + } + lineno = geti (f_error); + if (!cst_read) + {if (rcstore ()) return (0); + cst_read = TRUE; + } + for (i=0;i<5;i++) p[i] = geti (f_error); + if (lineno>0) eprint ("\n%d: ", lineno); + if (errno>=6000) eprint ("COMPILER ERROR. "); + + if (errno < 2000) + f = getfmt (errno-1000, m1000, sizeof m1000); + else if (errno < 4000) + f = getfmt (errno-2000, m2000, sizeof m2000); + else if (errno < 6000) + f = getfmt (errno-4000, m4000, sizeof m4000); + else f = getfmt (errno-6000, m6000, sizeof m6000); + + if (f==0) {f = "ERROR %d"; p[0]=errno;} + eprint (f, p[0], p[1], p[2], p[3], p[4]); + } + } + +/********************************************************************** + + GETFMT - get format given + N - relative error number + T - error message table + Z - size of error message table + +**********************************************************************/ + +char *getfmt (n, t, z) + char *t[]; + + {int nm; + + nm = z / sizeof t[0]; + if (n < 0 || n >= nm) return (0); + return (t[n]); + } + +/********************************************************************** + + EPRINT - Error PRINT Routine + +**********************************************************************/ + +eprint (fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9) char fmt[]; + + {int *argp, x, c; + char *s; + + argp = &x1; /* argument pointer */ + while (c = *fmt++) + {if (c != '%') eputc (c); + else + {x = *argp++; + switch (c = *fmt++) { + + case 'd': /* decimal */ + if (x<0) {x= -x; eputc ('-');} + eprd (x); + break; + + case 'q': /* parser state */ + x = sq[x]; + if (x<0) break; + if (x<010000) eprint ("%s", sterm[x]); + else eprint ("<%s>", snterm[x-010000]); + break; + + case 's': /* string */ + s = x; + while (c = *s++) eputc (c); + break; + + case 't': /* token */ + dtoken (x, *argp++); + break; + + case 'n': /* node op */ + eprint ("%s", nodeop[x]); + break; + + case 'm': /* string in cstore */ + eprint ("%s", &cstore[x]); + break; + + default: eputc (c); + argp--; + } + } + } + } + +/********************************************************************** + + EPRD - Print Decimal + +**********************************************************************/ + +eprd (n) + + {int a; + if (a=n/10) eprd (a); + eputc (n%10+'0'); + } + +/********************************************************************** + + EPUTC - write a character onto standard output + + Break lines which exceed 60 characters. + +**********************************************************************/ + +eputc (c) + + {static int column; + extern int cout; + + if (column >= 59 && c == ' ') c = '\n'; + else if (column >= 80 && c != '\n') + {cputc ('\n', cout); + column = 0; + } + cputc (c, cout); + if (c=='\n') column = 0; + else ++column; + } + +/********************************************************************** + + DTOKEN - Print symbolic representation of token + +**********************************************************************/ + +dtoken (tag, index) + + {if (tag >= TIDN) switch (tag) { + +case TIDN: if (index == UNDEF) {eprint ("unnamed"); break;} + if (index >= cssiz) /* structure type or member */ + index =- cssiz; + +case TFLOATC: eprint ("%s", &cstore[index]); + break; + +case TINTCON: eprint ("%d", index); + break; + +case TSTRING: eprint ("\"\""); + break; + } + + else if (tag == TEQOP) eprint ("%s", asgnop[index]); + else eprint ("%s", sterm[tag]); + } + diff --git a/arc/ar6:c/C93 C b/arc/ar6:c/C93 C new file mode 100644 index 00000000..398af5dc --- /dev/null +++ b/arc/ar6:c/C93 C @@ -0,0 +1,44 @@ +# include "cc.h" + +/* + + C Compiler + Routines common to phases M and E + + Copyright (c) 1977 by Alan Snyder + + rcstore + +*/ + + +/********************************************************************** + + RCSTORE - Read CSTORE routine + +**********************************************************************/ + +int rcstore () + + {extern char *fn_cstore, cstore[]; + char *cp, c, *ep; + int f; + + f = copen (fn_cstore, MREAD, BINARY); + if (f == OPENLOSS) + {cprint ("Unable to open '%s'.\n", fn_cstore); + return (TRUE); + } + cp = cstore; + ep = &cstore[cssiz]; + + while (cp < ep) + {c = cgetc (f); + if (c <= 0 && ceof (f)) break; + *cp++ = c; + } + cclose (f); + return (FALSE); + } + + \ No newline at end of file diff --git a/arc/ar6:c/CC 1 b/arc/ar6:c/CC 1 new file mode 100644 index 00000000..e6e75bec --- /dev/null +++ b/arc/ar6:c/CC 1 @@ -0,0 +1,773 @@ +# include "c.defs" + +# define MERGE_LP 1 +# define CALL_ERROR 1 + +/* + + C Compiler Command Routine + Host machine: PDP-10 ITS + + + Compiler Options + + -c compile only + -g do not delete MIDAS file + -k do not delete intermediate files + -s produce symbol table listing + -x syntax check or symbol table listing only + -b for compiling big functions + + m=xxx compile code for machine xxx + + t=abc run TEST versions of phases a, b, c + o=abc run OLD versions of phases a, b, c + n=abc run NORMAL versions of phases a, b, c + d=xxx set compiler debugging argument to xxx + + Meaningful debugging arguments: + + a debug code generator + d debug parser + e debug parser error recovery + m debug macro expander + + +*/ + +/* renamings to allow long names */ + +# define construct_output_file_names cnsofn +# define execute_phase execph +# define set_program_name setpn +# define set_target settrg +# define write_statistics wrstat +# define print_phase_time prphtm +# define perform_assembly perasm +# define process_options proopt +# define process_minus_option promin +# define process_equal_option proeq + +# define phase_name phsnm +# define phase_prog phspr +# define phase_argc phsac +# define phase_argv phsav +# define phase_option phsop +# define phase_et phset +# define phase_pt phspt + +# define argv_L avl +# define argv_LP avlp +# define argv_P avp +# define argv_C avc +# define argv_M avm +# define argv_E ave +# define argv_S avs + +# define target_name tarnam +# define target_suffix tarsfx +# define target_LP_data tarlpd +# define target_obj tarobj + +/* intermediate file names */ + +# define fncs "0.cs" +# define fner "0.er" +# define fnhm "0.hm" +# define fnma "0.ma" +# define fnno "0.no" +# define fnst "0.st" +# define fnsy "0.sy" +# define fnto "0.to" +# define fnty "0.ty" + +/* program file names */ + +# define normal_prefix "/dsk/c/_" +# define old_prefix "/dsk/c/_" +# define test_prefix "/dsk/c/_" + +# define normal_suffix ".bin" +# define old_suffix ".obin" +# define test_suffix ".tbin" + +# define pdp10_suffix "" +# define pdp11_suffix "11" +# define his6000_suffix "60" +# define ibm360_suffix "360" +# define cmac_suffix "-CM" +# define unix_suffix "-UX" +# define new10_suffix "-10" + +# define file_name_size 30 + +/* options */ + +char debug[40]; +char idebug[40]; +int kflag, cflag, gflag, xflag, bflag, sflag; + +/* phase information */ + +# define nphase 7 + +# define phase_L 0 +# define phase_LP 1 +# define phase_P 2 +# define phase_C 3 +# define phase_M 4 +# define phase_E 5 +# define phase_S 6 + +# define ARGC_LP 10 /* arg counts without optional args */ +# define ARGC_P 8 +# define ARGC_C 6 + +char *argv_L[] {debug, 0, fnto, fncs, fner, fnst}; +char *argv_LP[] {debug, 0, fnno, fnty, fner, fnma, fncs, fnst, fnhm, fnsy, 0}; +char *argv_P[] {debug, fnto, fnno, fnty, fner, fnma, fnhm, fnsy, 0}; +char *argv_C[] {debug, fner, fnno, fnty, fnma, "3000"}; +char *argv_M[] {debug, 0, fncs, fner, fnma, fnst, fnhm}; +char *argv_E[] {debug, fner, fncs}; +char *argv_S[] {fncs, fnty, fnsy, 0}; + +char *phase_name[] {"L", "LP", "P", "C", "M", "E", "S"}; +char phase_prog[nphase][file_name_size]; +char *phase_argc[] {6, ARGC_LP, ARGC_P, ARGC_C, 7, 3, 4}; +char **phase_argv[] {argv_L, argv_LP, argv_P, argv_C, argv_M, + argv_E, argv_S}; +int phase_option[] {'n', 'n', 'n', 'n', 'n', 'n', 'n'}; +int phase_et[] {0, 0, 0, 0, 0, 0, 0}; +int phase_pt[] {0, 0, 0, 0, 0, 0, 0}; + +/* target machine information */ + +# define n_target 7 + +# define pdp10 0 +# define pdp11 1 +# define his6000 2 +# define ibm360 3 +# define cmac 4 +# define unix 5 +# define new10 6 + +int target pdp10; + +char *target_name[] { + "pdp10", + "pdp11", + "his6000", + "ibm360", + "cmac", + "unix", + "new10" + }; + +char *target_suffix[] { + pdp10_suffix, + pdp11_suffix, + his6000_suffix, + ibm360_suffix, + cmac_suffix, + unix_suffix, + new10_suffix + }; + +char *target_LP_data[] { + "", + "", + "", + "", + "", + "", + "" + }; + +char *target_obj[] { + "MIDAS", + "PALX", + "GMAP", + "BAL", + "CMAC", + "UNIX", + "NMIDAS" + }; + +/********************************************************************** + + DESCRIPTION OF EXTERNALLY DEFINED ROUTINES + + part of C compiler: + + perror - error message processor + + standard C library: + + copen - open file for input/output + cprint - formatted output + cputc - output character + cclose - close file + istty - is file a terminal? + + reasonably machine-independent: + + stcpy - copy string + stcmp - compare strings + lower - convert char to lower case + execv - execute program passing vector of args + delete - delete file + now - get current date and time + prcal - print date and time + pr60th - print time given in 1/60 second units + + grossly ITS dependent: + + fopen - open file + fillen - determine file length + close - close file + fparse - parse file name + prfile - convert file specification to string + runame - return user name + etime - return an elapsed time + c6tos - convert sixbit to ASCII string + csto6 - convert ASCII to sixbit string + execs - execute program passing string command line + +*/ + +char *sconcat(); + +/********************************************************************** + + THE MAIN PROGRAM + +**********************************************************************/ + +main (argc, argv) int argc; char *argv[]; + + {extern int cout; + int snum, cc, f, i, ttyflag; + cal start_time; + char *s, *source, *fargv[50], buffer[2000]; + char obj_name[file_name_size], + rel_name[file_name_size], + sym_name[file_name_size]; + + --argc; + ++argv; + argc = process_options (argc, argv); + argc = exparg (argc, argv, fargv, buffer); + argv = fargv; + +# ifdef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_LP] = ARGC_LP+1; + argv_LP[ARGC_LP] = s; + } + else phase_argc[phase_LP] = ARGC_LP; + +# endif + +# ifndef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_P] = ARGC_P+1; + argv_P[ARGC_P] = s; + } + else phase_argc[phase_P] = ARGC_P; + +# endif + ttyflag = istty (cout); + + for (snum = 0; snum < argc; ++snum) + {source = argv[snum]; + + /* check that source file exists */ + + if ((f = copen (source, 'r')) == OPENLOSS) + {cprint ("Can't Find '%s'.\n", source); + continue; + } + cclose (f); + + if (!ttyflag || argc>1) cprint ("%s:\n", source); + now (&start_time); + + /* fix debug arg */ + + if (sflag) sconcat (debug, 2, idebug, "s"); + else if (xflag) sconcat (debug, 2, idebug, "x"); + else stcpy (idebug, debug); + + /* construct output file names from source file name */ + + construct_output_file_names (source, obj_name, + rel_name, sym_name); + + cclose (copen (fner, 'w', "b")); + + for (i=0;i= 0) + {s = *ss++; + if (s[0] == '-') process_minus_option (s+1); + else if ((opt = s[0]) && s[1] == '=') + process_equal_option (opt, s+2); + else + {*dd++ = s; + ++n; + } + } + return (n); + } + +/********************************************************************** + + PROCESS_MINUS_OPTION + +**********************************************************************/ + +process_minus_option (s) + char *s; + + {int c; + + while (c = *s) + {*s++ = c = lower (c); + switch (c) { + case 'k': kflag = TRUE; break; + case 'c': cflag = TRUE; break; + case 'g': gflag = TRUE; break; + case 's': sflag = TRUE; break; + case 'x': xflag = TRUE; break; + case 'b': bflag = TRUE; + argv_C[5] = "10000"; + break; + default: cprint ("Unrecognized option: -%c\n", c); + break; + } + } + } + +/********************************************************************** + + PROCESS_EQUAL_OPTION + +**********************************************************************/ + +process_equal_option (opt, s) + char *s; + + {char *r; + int c; + + switch (opt = lower (opt)) { + case 'd': r = idebug; + while (c = *s++) *r++ = lower (c); + *r = 0; + return; + case 'n': + case 'o': + case 't': while (c = *s++) set_phase_option (c, opt); + return; + + case 'm': set_target (s); + return; + + default: cprint ("Unrecognized option: %c=%s\n", opt, s); + } + } + +/********************************************************************** + + CONSTRUCT_OUTPUT_FILE_NAMES + + Construct assembler, relocatable, and symbol table listing + file names from source file name. For the ITS version, + output file names are formed by changing the FNAME2 and + setting the DEVICE to DSK. + +**********************************************************************/ + +construct_output_file_names (source, obj_name, rel_name, sym_name) + char *source, *obj_name, *rel_name; + + {filespec f; + + fparse (source, &f); + f.dev = csto6 ("DSK"); + f.fn2 = csto6 (target_obj[target]); + prfile (&f, obj_name); + if (target==new10) f.fn2 = csto6 ("NSTK"); + else f.fn2 = csto6 ("STK"); + prfile (&f, rel_name); + f.fn2 = csto6 ("SYMTAB"); + prfile (&f, sym_name); + } + +/********************************************************************** + + EXECUTE PHASE + +**********************************************************************/ + +execute_phase (n) int n; + + {extern int exctime, exccode; + int t; + + set_program_name (n); + t = etime (); + if (execv (phase_prog[n], phase_argc[n], phase_argv[n])) + {cprint ("Unable to execute phase %s\n", phase_name[n]); + return (-1); + } + phase_et[n] = etime () - t; + phase_pt[n] = exctime; + return (exccode); + } + +/********************************************************************** + + SET_PHASE_OPTION + + Set phase option for phase PC to be OC. + +**********************************************************************/ + +set_phase_option (pc, oc) + + {int n; + + pc = lower (pc); + switch (pc) { + +# ifdef MERGE_LP + + case 'l': + case 'p': n = phase_LP; break; + +# endif + +# ifndef MERGE_LP + + case 'l': n = phase_L; break; + case 'p': n = phase_P; break; + +# endif + + case 'c': n = phase_C; break; + case 'm': n = phase_M; break; + case 'e': n = phase_E; break; + case 's': n = phase_S; break; + default: cprint ("Unrecognized Phase Designation: %c\n", pc); + return; + } + phase_option[n] = lower (oc); + } + +/********************************************************************** + + SET_PROGRAM_NAME + + Construct the file name of program for the given phase. + +**********************************************************************/ + +set_program_name (n) int n; + + {char *r, *s, *t; + + switch (phase_option[n]) { + case 'o': r = old_prefix; s = old_suffix; + break; + case 't': r = test_prefix; s = test_suffix; + break; + default: cprint ("Unrecognized Phase Option: %c\n", + phase_option[n]); + case 'n': r = normal_prefix; s = normal_suffix; + break; + } + t = target_suffix[target]; + if (n == phase_E || n == phase_S) t = ""; + sconcat (phase_prog[n], 4, r, phase_name[n], t, s); + } + +/********************************************************************** + + SET_TARGET - Set Target Machine + +**********************************************************************/ + +set_target (s) + char *s; + + {int c, i; + char *p; + + p = s; + while (c = *p) *p++ = lower (c); + for (i=0; i+ '\t' */ + {register int c; + while ((c = cgetc (f)) > 0) + {if (c == '-') + {c = cgetc (f); + if (!digit (c)) continue; + while (digit (c)) c = cgetc (f); + if (c != '\t') continue; + cprint ("Assembler Errors.\n"); + cclose (f); + return (TRUE); + } + } + cclose (f); + delete (temp); + } + return (FALSE); + } + +int digit (c) + {return (c>='0' && c<='9');} + +/********************************************************************** + + SCONCAT - String Concatenate + + concatenate strings S1 ... Sn into buffer B + return B + +**********************************************************************/ + +char *sconcat (b, n, s1, s2, s3, s4, s5, s6, s7, s8) + char *b, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; + + {char **s, *p, *q; + int c; + + q = b; + s = &s1; + + while (--n >= 0) + {p = *s++; + while (c = *p++) *q++ = c; + } + + *q = 0; + return (b); + } + +/********************************************************************** + + SLOWER - Convert String To Lower Case + +**********************************************************************/ + +slower (s) char *s; + + {int c; + while (c = *s) *s++ = lower (c); + } + \ No newline at end of file diff --git a/arc/ar6:c/CC 3 b/arc/ar6:c/CC 3 new file mode 100644 index 00000000..e9502f3b --- /dev/null +++ b/arc/ar6:c/CC 3 @@ -0,0 +1,781 @@ +# include "c.defs" + +# define MERGE_LP 1 +# define CALL_ERROR 1 + +/* + + C Compiler Command Routine + Host machine: PDP-10 ITS + + + Compiler Options + + -c compile only + -g do not delete MIDAS file + -k do not delete intermediate files + -s produce symbol table listing + -x syntax check or symbol table listing only + -b for compiling big functions + + m=xxx compile code for machine xxx + + t=abc run TEST versions of phases a, b, c + o=abc run OLD versions of phases a, b, c + n=abc run NORMAL versions of phases a, b, c + d=xxx set compiler debugging argument to xxx + + Meaningful debugging arguments: + + a debug code generator + d debug parser + e debug parser error recovery + m debug macro expander + + +*/ + +/* renamings to allow long names */ + +# define construct_output_file_names cnsofn +# define execute_phase execph +# define set_program_name setpn +# define set_target settrg +# define write_statistics wrstat +# define print_phase_time prphtm +# define perform_assembly perasm +# define process_options proopt +# define process_minus_option promin +# define process_equal_option proeq + +# define phase_name phsnm +# define phase_prog phspr +# define phase_argc phsac +# define phase_argv phsav +# define phase_option phsop +# define phase_et phset +# define phase_pt phspt + +# define argv_L avl +# define argv_LP avlp +# define argv_P avp +# define argv_C avc +# define argv_M avm +# define argv_E ave +# define argv_S avs + +# define target_name tarnam +# define target_suffix tarsfx +# define target_LP_data tarlpd +# define target_obj tarobj + +/* intermediate file names */ + +# define fncs "0.cs" +# define fner "0.er" +# define fnhm "0.hm" +# define fnma "0.ma" +# define fnno "0.no" +# define fnst "0.st" +# define fnsy "0.sy" +# define fnto "0.to" +# define fnty "0.ty" + +/* program file names */ + +# ifdef AI +# define normal_prefix "/dsk/clib/_" +# define old_prefix "/dsk/clib/_" +# define test_prefix "/dsk/clib/_" +#endif + +# ifndef normal_prefix +# define normal_prefix "/dsk/c/_" +# define old_prefix "/dsk/c/_" +# define test_prefix "/dsk/c/_" +# endif + +# define normal_suffix ".bin" +# define old_suffix ".obin" +# define test_suffix ".tbin" + +# define pdp10_suffix "" +# define pdp11_suffix "11" +# define his6000_suffix "60" +# define ibm360_suffix "360" +# define cmac_suffix "-CM" +# define unix_suffix "-UX" +# define new10_suffix "-10" + +# define file_name_size 30 + +/* options */ + +char debug[40]; +char idebug[40]; +int kflag, cflag, gflag, xflag, bflag, sflag; + +/* phase information */ + +# define nphase 7 + +# define phase_L 0 +# define phase_LP 1 +# define phase_P 2 +# define phase_C 3 +# define phase_M 4 +# define phase_E 5 +# define phase_S 6 + +# define ARGC_LP 10 /* arg counts without optional args */ +# define ARGC_P 8 +# define ARGC_C 6 + +char *argv_L[] {debug, 0, fnto, fncs, fner, fnst}; +char *argv_LP[] {debug, 0, fnno, fnty, fner, fnma, fncs, fnst, fnhm, fnsy, 0}; +char *argv_P[] {debug, fnto, fnno, fnty, fner, fnma, fnhm, fnsy, 0}; +char *argv_C[] {debug, fner, fnno, fnty, fnma, "3000"}; +char *argv_M[] {debug, 0, fncs, fner, fnma, fnst, fnhm}; +char *argv_E[] {debug, fner, fncs}; +char *argv_S[] {fncs, fnty, fnsy, 0}; + +char *phase_name[] {"L", "LP", "P", "C", "M", "E", "S"}; +char phase_prog[nphase][file_name_size]; +char *phase_argc[] {6, ARGC_LP, ARGC_P, ARGC_C, 7, 3, 4}; +char **phase_argv[] {argv_L, argv_LP, argv_P, argv_C, argv_M, + argv_E, argv_S}; +int phase_option[] {'n', 'n', 'n', 'n', 'n', 'n', 'n'}; +int phase_et[] {0, 0, 0, 0, 0, 0, 0}; +int phase_pt[] {0, 0, 0, 0, 0, 0, 0}; + +/* target machine information */ + +# define n_target 7 + +# define pdp10 0 +# define pdp11 1 +# define his6000 2 +# define ibm360 3 +# define cmac 4 +# define unix 5 +# define new10 6 + +int target pdp10; + +char *target_name[] { + "pdp10", + "pdp11", + "his6000", + "ibm360", + "cmac", + "unix", + "new10" + }; + +char *target_suffix[] { + pdp10_suffix, + pdp11_suffix, + his6000_suffix, + ibm360_suffix, + cmac_suffix, + unix_suffix, + new10_suffix + }; + +char *target_LP_data[] { + "", + "", + "", + "", + "", + "", + "" + }; + +char *target_obj[] { + "MIDAS", + "PALX", + "GMAP", + "BAL", + "CMAC", + "UNIX", + "NMIDAS" + }; + +/********************************************************************** + + DESCRIPTION OF EXTERNALLY DEFINED ROUTINES + + part of C compiler: + + perror - error message processor + + standard C library: + + copen - open file for input/output + cprint - formatted output + cputc - output character + cclose - close file + istty - is file a terminal? + + reasonably machine-independent: + + stcpy - copy string + stcmp - compare strings + lower - convert char to lower case + execv - execute program passing vector of args + delete - delete file + now - get current date and time + prcal - print date and time + pr60th - print time given in 1/60 second units + + grossly ITS dependent: + + fopen - open file + fillen - determine file length + close - close file + fparse - parse file name + prfile - convert file specification to string + runame - return user name + etime - return an elapsed time + c6tos - convert sixbit to ASCII string + csto6 - convert ASCII to sixbit string + execs - execute program passing string command line + +*/ + +char *sconcat(); + +/********************************************************************** + + THE MAIN PROGRAM + +**********************************************************************/ + +main (argc, argv) int argc; char *argv[]; + + {extern int cout; + int snum, cc, f, i, ttyflag; + cal start_time; + char *s, *source, *fargv[50], buffer[2000]; + char obj_name[file_name_size], + rel_name[file_name_size], + sym_name[file_name_size]; + + --argc; + ++argv; + argc = process_options (argc, argv); + argc = exparg (argc, argv, fargv, buffer); + argv = fargv; + +# ifdef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_LP] = ARGC_LP+1; + argv_LP[ARGC_LP] = s; + } + else phase_argc[phase_LP] = ARGC_LP; + +# endif + +# ifndef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_P] = ARGC_P+1; + argv_P[ARGC_P] = s; + } + else phase_argc[phase_P] = ARGC_P; + +# endif + ttyflag = istty (cout); + + for (snum = 0; snum < argc; ++snum) + {source = argv[snum]; + + /* check that source file exists */ + + if ((f = copen (source, 'r')) == OPENLOSS) + {cprint ("Can't Find '%s'.\n", source); + continue; + } + cclose (f); + + if (!ttyflag || argc>1) cprint ("%s:\n", source); + now (&start_time); + + /* fix debug arg */ + + if (sflag) sconcat (debug, 2, idebug, "s"); + else if (xflag) sconcat (debug, 2, idebug, "x"); + else stcpy (idebug, debug); + + /* construct output file names from source file name */ + + construct_output_file_names (source, obj_name, + rel_name, sym_name); + + cclose (copen (fner, 'w', "b")); + + for (i=0;i= 0) + {s = *ss++; + if (s[0] == '-') process_minus_option (s+1); + else if ((opt = s[0]) && s[1] == '=') + process_equal_option (opt, s+2); + else + {*dd++ = s; + ++n; + } + } + return (n); + } + +/********************************************************************** + + PROCESS_MINUS_OPTION + +**********************************************************************/ + +process_minus_option (s) + char *s; + + {int c; + + while (c = *s) + {*s++ = c = lower (c); + switch (c) { + case 'k': kflag = TRUE; break; + case 'c': cflag = TRUE; break; + case 'g': gflag = TRUE; break; + case 's': sflag = TRUE; break; + case 'x': xflag = TRUE; break; + case 'b': bflag = TRUE; + argv_C[5] = "10000"; + break; + default: cprint ("Unrecognized option: -%c\n", c); + break; + } + } + } + +/********************************************************************** + + PROCESS_EQUAL_OPTION + +**********************************************************************/ + +process_equal_option (opt, s) + char *s; + + {char *r; + int c; + + switch (opt = lower (opt)) { + case 'd': r = idebug; + while (c = *s++) *r++ = lower (c); + *r = 0; + return; + case 'n': + case 'o': + case 't': while (c = *s++) set_phase_option (c, opt); + return; + + case 'm': set_target (s); + return; + + default: cprint ("Unrecognized option: %c=%s\n", opt, s); + } + } + +/********************************************************************** + + CONSTRUCT_OUTPUT_FILE_NAMES + + Construct assembler, relocatable, and symbol table listing + file names from source file name. For the ITS version, + output file names are formed by changing the FNAME2 and + setting the DEVICE to DSK. + +**********************************************************************/ + +construct_output_file_names (source, obj_name, rel_name, sym_name) + char *source, *obj_name, *rel_name; + + {filespec f; + + fparse (source, &f); + f.dev = csto6 ("DSK"); + f.fn2 = csto6 (target_obj[target]); + prfile (&f, obj_name); + if (target==new10) f.fn2 = csto6 ("NSTK"); + else f.fn2 = csto6 ("STK"); + prfile (&f, rel_name); + f.fn2 = csto6 ("SYMTAB"); + prfile (&f, sym_name); + } + +/********************************************************************** + + EXECUTE PHASE + +**********************************************************************/ + +execute_phase (n) int n; + + {extern int exctime, exccode; + int t; + + set_program_name (n); + t = etime (); + if (execv (phase_prog[n], phase_argc[n], phase_argv[n])) + {cprint ("Unable to execute phase %s\n", phase_name[n]); + return (-1); + } + phase_et[n] = etime () - t; + phase_pt[n] = exctime; + return (exccode); + } + +/********************************************************************** + + SET_PHASE_OPTION + + Set phase option for phase PC to be OC. + +**********************************************************************/ + +set_phase_option (pc, oc) + + {int n; + + pc = lower (pc); + switch (pc) { + +# ifdef MERGE_LP + + case 'l': + case 'p': n = phase_LP; break; + +# endif + +# ifndef MERGE_LP + + case 'l': n = phase_L; break; + case 'p': n = phase_P; break; + +# endif + + case 'c': n = phase_C; break; + case 'm': n = phase_M; break; + case 'e': n = phase_E; break; + case 's': n = phase_S; break; + default: cprint ("Unrecognized Phase Designation: %c\n", pc); + return; + } + phase_option[n] = lower (oc); + } + +/********************************************************************** + + SET_PROGRAM_NAME + + Construct the file name of program for the given phase. + +**********************************************************************/ + +set_program_name (n) int n; + + {char *r, *s, *t; + + switch (phase_option[n]) { + case 'o': r = old_prefix; s = old_suffix; + break; + case 't': r = test_prefix; s = test_suffix; + break; + default: cprint ("Unrecognized Phase Option: %c\n", + phase_option[n]); + case 'n': r = normal_prefix; s = normal_suffix; + break; + } + t = target_suffix[target]; + if (n == phase_E || n == phase_S) t = ""; + sconcat (phase_prog[n], 4, r, phase_name[n], t, s); + } + +/********************************************************************** + + SET_TARGET - Set Target Machine + +**********************************************************************/ + +set_target (s) + char *s; + + {int c, i; + char *p; + + p = s; + while (c = *p) *p++ = lower (c); + for (i=0; i+ '\t' */ + {register int c; + while ((c = cgetc (f)) > 0) + {if (c == '-') + {c = cgetc (f); + if (!digit (c)) continue; + while (digit (c)) c = cgetc (f); + if (c != '\t') continue; + cprint ("Assembler Errors.\n"); + cclose (f); + return (TRUE); + } + } + cclose (f); + delete (temp); + } + return (FALSE); + } + +int digit (c) + {return (c>='0' && c<='9');} + +/********************************************************************** + + SCONCAT - String Concatenate + + concatenate strings S1 ... Sn into buffer B + return B + +**********************************************************************/ + +char *sconcat (b, n, s1, s2, s3, s4, s5, s6, s7, s8) + char *b, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; + + {char **s, *p, *q; + int c; + + q = b; + s = &s1; + + while (--n >= 0) + {p = *s++; + while (c = *p++) *q++ = c; + } + + *q = 0; + return (b); + } + +/********************************************************************** + + SLOWER - Convert String To Lower Case + +**********************************************************************/ + +slower (s) char *s; + + {int c; + while (c = *s) *s++ = lower (c); + } + \ No newline at end of file diff --git a/arc/ar6:c/CC H b/arc/ar6:c/CC H new file mode 100644 index 00000000..fffa5de0 --- /dev/null +++ b/arc/ar6:c/CC H @@ -0,0 +1,341 @@ +/* + + C Compiler + Manifest Constants Include File + +*/ + + +/* configuration selectors + + To select the indicated option, uncomment + the corresponding #define. + + To not select the indicated option, enclose + the corresponding #define in comments. + +*/ + +# define MERGE_LP 1 + /* are phases L and P merged? + affects C1.C and C21.C only */ +# define CALL_ERROR 1 + /* is error phase called directly by control + routine? affects C5.C only */ + +# define BOTHCASE 1 + /* distinct upper/lower case in idns */ + +/* various values */ + +# define MREAD 'r' /* read mode */ +# define MWRITE 'w' /* write mode */ +# define MAPPEND 'a' /* append mode */ +# define TEXT "t" /* text file */ +# define BINARY "b" /* binary file */ +# define LEXEOF 0 /* lexget end of file indicator */ + +# define TRUE 1 +# define FALSE 0 +# define NULL 0 +# define UNDEF -1 +# define OPENLOSS -1 /* value returned for unsuccessful open */ + +/* table sizes */ + +# define maxfarg 30 /* maximum number of function arguments */ +# define maxreg 16 /* maximum number of abstract machine registers */ +# define MAXDIMS 8 /* maximum number of dimensions in a type */ +# define maxccl 10 /* size of compiler control line table */ +# define maxargs 10 /* maximum number of args to input macro */ +# define maxdepth 5 /* maximum depth of input macro expansion */ +# define maxicb 3 /* maximum nesting of included files */ +# define margbsz 200 /* size of table holding macro arg tokens */ +# define mhsize 0400 /* size of macro hash table */ +# define mhmask 0377 /* mask for accessing macro hash table */ +# define hshsize 1999 /* size of hash table (prefer prime) */ +# define icb_size 10 /* macro definition level */ +# define cssiz 10000 /* size of character store */ +# define stsize 300 /* size of symbol table (dict) */ +# define mcdsz 3000 /* manifest constant definition table size */ +# define coresz 6600 /* size of core array for function tree */ +# define acoresz 150 /* size of array for expression tree */ +# define pssize 300 /* size of parser stack */ +# define tbsize 30 /* size of parser token buffer */ +# define TTSIZE 600 /* type table size */ +# define GSSIZE 20 /* group stack size */ + +/* character types */ + +# define _LETTER 0 /* identifier or keyword */ +# define _DIGIT 1 /* constant or identifier */ +# define _QUOTE 2 /* character string */ +# define _MCOP 3 /* possible beginning of multi-character op */ +# define _EOL 4 /* carriage return or newline */ +# define _BLANK 5 /* blank or tab */ +# define _INVALID 6 /* invalid character */ +# define _SQUOTE 7 /* character constant */ +# define _PERIOD 8 /* operator or beginning of float constant */ +# define _ESCAPE 9 /* escape character */ +# define _CONTROL 10 /* compiler control line indicator */ +# define _NAME ttype<2 + +/* token tags */ + +# define TEOF 1 /* end of file */ +# define TCONTROL 2 /* beginning of control line (internal) */ +# define TEQOP 36 /* =op's */ +# define TIDN 75 /* identifiers */ +# define TINTCON 76 /* integer constants */ +# define TFLOATC 77 /* float constants */ +# define TSTRING 78 /* string constants */ +# define TLINENO 79 /* line number */ +# define TMARG 80 /* macro argument (internal) */ + +/* type tags */ + +# define TTCHAR 0 /* the first four values may not be changed */ +# define TTINT 1 +# define TTFLOAT 2 +# define TTDOUBLE 3 +# define TTLONG 4 +# define TTUNSIGNED 5 +# define TTUNDEF 6 +# define TTCFIELD 7 +# define TTIFIELD 8 +# define TTPTR 9 +# define TTFUNC 10 +# define TTARRAY 11 +# define TTSTRUCT 12 +# define TTDUMMY 13 + +/* type modifier indicators */ + +# define MPTR 1 +# define MFUNC 2 +# define MARRAY 3 + +/* storage classes */ + +# define c_register 0 /* register */ +# define c_temp 1 /* temporary */ +# define c_auto 1 /* automatic */ +# define c_extdef 2 /* external definition */ +# define c_static 3 /* static */ +# define c_param 4 /* parameter */ +# define c_label 5 /* label */ +# define c_integer 6 /* integer literal */ +# define c_float 7 /* floating-point literal */ +# define c_string 8 /* string literal */ +# define c_indirect 9 /* indirection through reg #0 ... */ +# define c_extern 50 /* external */ +# define c_struct 51 /* structure type */ +# define c_mos 52 /* member of structure */ +# define c_typedef 53 /* type defintion */ +# define c_ustruct 54 /* undefined structure type */ +# define c_ulabel 55 /* undefined label */ +# define c_uauto 56 /* unused auto variable */ + +/* condition codes */ + +# define cc_eq0 0 +# define cc_ne0 1 +# define cc_lt0 2 +# define cc_gt0 3 +# define cc_le0 4 +# define cc_ge0 5 + +/* ctypes */ + +# define ct_bad 0 +# define ct_struct 1 +# define ct_char 2 +# define ct_int 3 +# define ct_float 4 +# define ct_double 5 +# define ct_p0 6 +# define ct_p1 7 +# define ct_p2 8 +# define ct_p3 9 + +/* loc flags */ + +# define l_label 0 +# define l_reg 1 +# define l_mem 2 +# define l_any 3 + +/* nodes */ + +# define n_idn 2 +# define n_int 3 +# define n_float 4 +# define n_string 5 +# define n_call 6 +# define n_qmark 7 +# define n_incb 8 +# define n_inca 9 +# define n_decb 10 +# define n_deca 11 +# define n_star 12 +# define n_addr 13 +# define n_uminus 14 +# define n_bnot 15 +# define n_tvnot 16 +# define n_band 17 +# define n_bior 18 +# define n_bxor 19 +# define n_mod 20 +# define n_div 21 +# define n_times 22 +# define n_minus 23 +# define n_plus 24 +# define n_assign 25 +# define n_eq 26 +# define n_ne 27 +# define n_lt 28 +# define n_gt 29 +# define n_le 30 +# define n_ge 31 +# define n_ls 32 +# define n_rs 33 +# define n_ars 34 +# define n_als 35 +# define n_aplus 36 +# define n_aminus 37 +# define n_atimes 38 +# define n_adiv 39 +# define n_amod 40 +# define n_aand 41 +# define n_axor 42 +# define n_aior 43 +# define n_tv_and 44 +# define n_tv_or 45 +# define n_dot 46 +# define n_colon 47 +# define n_comma 48 +# define n_sizeof 49 +# define n_if 80 +# define n_goto 81 +# define n_branch 82 +# define n_label 83 +# define n_stmtl 84 +# define n_switch 85 +# define n_case 86 +# define n_def 87 +# define n_return 88 +# define n_prog 89 +# define n_exprs 90 +# define n_elist 91 + +/* initializer types */ + +# define i_int 1 +# define i_float 2 +# define i_negfloat 3 +# define i_string 4 +# define i_idn 5 + +/* enodes */ + +# define e_iminus 0000 +# define e_dminus 0001 +# define e_incbi 0002 +# define e_bnot 0006 +# define e_not 0007 +# define e_lseq 0010 +# define e_sw 0012 +# define e_incbc 0013 +# define e_a0 0017 +# define e_a3 0022 +# define e_ind 0023 +# define e_jz0 0024 +# define e_jz3 0027 +# define e_jn0 0030 +# define e_jn3 0033 +# define e_addi 0100 +# define e_eaddi 0101 +# define e_subi 0104 +# define e_esubi 0105 +# define e_muli 0110 +# define e_divi 0114 +# define e_mod 0120 +# define e_ls 0122 +# define e_els 0123 +# define e_rs 0124 +# define e_ers 0125 +# define e_band 0126 +# define e_eand 0127 +# define e_xor 0130 +# define e_exor 0131 +# define e_bor 0132 +# define e_eor 0133 +# define e_and 0134 +# define e_or 0135 +# define e_p0sub 0136 +# define e_assign 0137 +# define e_argi 0140 +# define e_argd 0141 +# define e_arg0 0142 +# define e_add0 0146 +# define e_add3 0151 +# define e_sub0 0152 +# define e_sub3 0155 +# define e_movec 0160 +# define e_comma 0170 +# define e_idn 0177 +# define e_int 0176 +# define e_string 0175 +# define e_float 0174 +# define e_call 0173 +# define e_colon 0172 +# define e_qmark 0171 +# define e_eqi 0200 +# define e_eqd 0206 +# define e_eqp0 0214 +# define e_gep3 0243 +# define e_incbf 0250 +# define e_incbd 0254 +# define e_incb0 0260 + +/* object_modes */ + +# define o_pure 0 /* pure - instructions only */ +# define o_impure 1 /* impure - uninitialized data areas */ +# define o_data 2 /* data - initialized data areas */ +# define o_pdata 3 /* pure data - constants */ + +# define pure if (objmode != o_pure) mpure() +# define impure if (objmode != o_impure) mimpure() +# define data if (objmode != o_data) mdata() +# define pdata if (objmode != o_pdata) mpdata() + +/* structure definitions */ + +# define typedesc struct _typedesc +# define type struct _typedesc * +# define field struct _fielddesc +struct _typedesc { + int tag; /* the basic type or type modifier */ + int size; /* the size of objects of the type + -1 => size undefined */ + int align; /* the alignment class of objects of the type */ + type val; /* first additional value */ + int nelem; /* number of elements in an array */ + }; +struct _fielddesc { + int name; /* UNDEF => end of list */ + type dtype; /* field type */ + int offset; /* offset in structure */ + }; +struct _token {int tag, index, line;}; +struct _cclent {int cname; int (*cproc)();}; + +# define token struct _token +# define cclent struct _cclent + +/* machine dependencies of the machine on which the compiler is running */ + +# define WORDMASK 077777777777 /* mask all but high 3 bits */ +# define SMALLEST "-34359738368" /* smallest integer as string */ + \ No newline at end of file diff --git a/arc/ar6:c/CC11 3 b/arc/ar6:c/CC11 3 new file mode 100644 index 00000000..53756068 --- /dev/null +++ b/arc/ar6:c/CC11 3 @@ -0,0 +1,781 @@ +# include "c.defs" + +# define MERGE_LP 1 +# define CALL_ERROR 1 + +/* + + C Compiler Command Routine + Host machine: PDP-10 ITS + + + Compiler Options + + -c compile only + -g do not delete MIDAS file + -k do not delete intermediate files + -s produce symbol table listing + -x syntax check or symbol table listing only + -b for compiling big functions + + m=xxx compile code for machine xxx + + t=abc run TEST versions of phases a, b, c + o=abc run OLD versions of phases a, b, c + n=abc run NORMAL versions of phases a, b, c + d=xxx set compiler debugging argument to xxx + + Meaningful debugging arguments: + + a debug code generator + d debug parser + e debug parser error recovery + m debug macro expander + + +*/ + +/* renamings to allow long names */ + +# define construct_output_file_names cnsofn +# define execute_phase execph +# define set_program_name setpn +# define set_target settrg +# define write_statistics wrstat +# define print_phase_time prphtm +# define perform_assembly perasm +# define process_options proopt +# define process_minus_option promin +# define process_equal_option proeq + +# define phase_name phsnm +# define phase_prog phspr +# define phase_argc phsac +# define phase_argv phsav +# define phase_option phsop +# define phase_et phset +# define phase_pt phspt + +# define argv_L avl +# define argv_LP avlp +# define argv_P avp +# define argv_C avc +# define argv_M avm +# define argv_E ave +# define argv_S avs + +# define target_name tarnam +# define target_suffix tarsfx +# define target_LP_data tarlpd +# define target_obj tarobj + +/* intermediate file names */ + +# define fncs "0.cs" +# define fner "0.er" +# define fnhm "0.hm" +# define fnma "0.ma" +# define fnno "0.no" +# define fnst "0.st" +# define fnsy "0.sy" +# define fnto "0.to" +# define fnty "0.ty" + +/* program file names */ + +# ifdef AI +# define normal_prefix "/dsk/clib/_" +# define old_prefix "/dsk/clib/_" +# define test_prefix "/dsk/clib/_" +#endif + +# ifndef normal_prefix +# define normal_prefix "/dsk/c/_" +# define old_prefix "/dsk/c/_" +# define test_prefix "/dsk/c/_" +# endif + +# define normal_suffix ".bin" +# define old_suffix ".obin" +# define test_suffix ".tbin" + +# define pdp10_suffix "" +# define pdp11_suffix "11" +# define his6000_suffix "60" +# define ibm360_suffix "360" +# define cmac_suffix "-CM" +# define unix_suffix "-UX" +# define new10_suffix "-10" + +# define file_name_size 30 + +/* options */ + +char debug[40]; +char idebug[40]; +int kflag, cflag, gflag, xflag, bflag, sflag; + +/* phase information */ + +# define nphase 7 + +# define phase_L 0 +# define phase_LP 1 +# define phase_P 2 +# define phase_C 3 +# define phase_M 4 +# define phase_E 5 +# define phase_S 6 + +# define ARGC_LP 10 /* arg counts without optional args */ +# define ARGC_P 8 +# define ARGC_C 6 + +char *argv_L[] {debug, 0, fnto, fncs, fner, fnst}; +char *argv_LP[] {debug, 0, fnno, fnty, fner, fnma, fncs, fnst, fnhm, fnsy, 0}; +char *argv_P[] {debug, fnto, fnno, fnty, fner, fnma, fnhm, fnsy, 0}; +char *argv_C[] {debug, fner, fnno, fnty, fnma, "3000"}; +char *argv_M[] {debug, 0, fncs, fner, fnma, fnst, fnhm}; +char *argv_E[] {debug, fner, fncs}; +char *argv_S[] {fncs, fnty, fnsy, 0}; + +char *phase_name[] {"L", "LP", "P", "C", "M", "E", "S"}; +char phase_prog[nphase][file_name_size]; +char *phase_argc[] {6, ARGC_LP, ARGC_P, ARGC_C, 7, 3, 4}; +char **phase_argv[] {argv_L, argv_LP, argv_P, argv_C, argv_M, + argv_E, argv_S}; +int phase_option[] {'n', 'n', 'n', 'n', 'n', 'n', 'n'}; +int phase_et[] {0, 0, 0, 0, 0, 0, 0}; +int phase_pt[] {0, 0, 0, 0, 0, 0, 0}; + +/* target machine information */ + +# define n_target 7 + +# define pdp10 0 +# define pdp11 1 +# define his6000 2 +# define ibm360 3 +# define cmac 4 +# define unix 5 +# define new10 6 + +int target pdp11; + +char *target_name[] { + "pdp10", + "pdp11", + "his6000", + "ibm360", + "cmac", + "unix", + "new10" + }; + +char *target_suffix[] { + pdp10_suffix, + pdp11_suffix, + his6000_suffix, + ibm360_suffix, + cmac_suffix, + unix_suffix, + new10_suffix + }; + +char *target_LP_data[] { + "", + "", + "", + "", + "", + "", + "" + }; + +char *target_obj[] { + "MIDAS", + "PALX", + "GMAP", + "BAL", + "CMAC", + "UNIX", + "NMIDAS" + }; + +/********************************************************************** + + DESCRIPTION OF EXTERNALLY DEFINED ROUTINES + + part of C compiler: + + perror - error message processor + + standard C library: + + copen - open file for input/output + cprint - formatted output + cputc - output character + cclose - close file + istty - is file a terminal? + + reasonably machine-independent: + + stcpy - copy string + stcmp - compare strings + lower - convert char to lower case + execv - execute program passing vector of args + delete - delete file + now - get current date and time + prcal - print date and time + pr60th - print time given in 1/60 second units + + grossly ITS dependent: + + fopen - open file + fillen - determine file length + close - close file + fparse - parse file name + prfile - convert file specification to string + runame - return user name + etime - return an elapsed time + c6tos - convert sixbit to ASCII string + csto6 - convert ASCII to sixbit string + execs - execute program passing string command line + +*/ + +char *sconcat(); + +/********************************************************************** + + THE MAIN PROGRAM + +**********************************************************************/ + +main (argc, argv) int argc; char *argv[]; + + {extern int cout; + int snum, cc, f, i, ttyflag; + cal start_time; + char *s, *source, *fargv[50], buffer[2000]; + char obj_name[file_name_size], + rel_name[file_name_size], + sym_name[file_name_size]; + + --argc; + ++argv; + argc = process_options (argc, argv); + argc = exparg (argc, argv, fargv, buffer); + argv = fargv; + +# ifdef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_LP] = ARGC_LP+1; + argv_LP[ARGC_LP] = s; + } + else phase_argc[phase_LP] = ARGC_LP; + +# endif + +# ifndef MERGE_LP + + s = target_LP_data[target]; + if (*s) + {phase_argc[phase_P] = ARGC_P+1; + argv_P[ARGC_P] = s; + } + else phase_argc[phase_P] = ARGC_P; + +# endif + ttyflag = istty (cout); + + for (snum = 0; snum < argc; ++snum) + {source = argv[snum]; + + /* check that source file exists */ + + if ((f = copen (source, 'r')) == OPENLOSS) + {cprint ("Can't Find '%s'.\n", source); + continue; + } + cclose (f); + + if (!ttyflag || argc>1) cprint ("%s:\n", source); + now (&start_time); + + /* fix debug arg */ + + if (sflag) sconcat (debug, 2, idebug, "s"); + else if (xflag) sconcat (debug, 2, idebug, "x"); + else stcpy (idebug, debug); + + /* construct output file names from source file name */ + + construct_output_file_names (source, obj_name, + rel_name, sym_name); + + cclose (copen (fner, 'w', "b")); + + for (i=0;i= 0) + {s = *ss++; + if (s[0] == '-') process_minus_option (s+1); + else if ((opt = s[0]) && s[1] == '=') + process_equal_option (opt, s+2); + else + {*dd++ = s; + ++n; + } + } + return (n); + } + +/********************************************************************** + + PROCESS_MINUS_OPTION + +**********************************************************************/ + +process_minus_option (s) + char *s; + + {int c; + + while (c = *s) + {*s++ = c = lower (c); + switch (c) { + case 'k': kflag = TRUE; break; + case 'c': cflag = TRUE; break; + case 'g': gflag = TRUE; break; + case 's': sflag = TRUE; break; + case 'x': xflag = TRUE; break; + case 'b': bflag = TRUE; + argv_C[5] = "10000"; + break; + default: cprint ("Unrecognized option: -%c\n", c); + break; + } + } + } + +/********************************************************************** + + PROCESS_EQUAL_OPTION + +**********************************************************************/ + +process_equal_option (opt, s) + char *s; + + {char *r; + int c; + + switch (opt = lower (opt)) { + case 'd': r = idebug; + while (c = *s++) *r++ = lower (c); + *r = 0; + return; + case 'n': + case 'o': + case 't': while (c = *s++) set_phase_option (c, opt); + return; + + case 'm': set_target (s); + return; + + default: cprint ("Unrecognized option: %c=%s\n", opt, s); + } + } + +/********************************************************************** + + CONSTRUCT_OUTPUT_FILE_NAMES + + Construct assembler, relocatable, and symbol table listing + file names from source file name. For the ITS version, + output file names are formed by changing the FNAME2 and + setting the DEVICE to DSK. + +**********************************************************************/ + +construct_output_file_names (source, obj_name, rel_name, sym_name) + char *source, *obj_name, *rel_name; + + {filespec f; + + fparse (source, &f); + f.dev = csto6 ("DSK"); + f.fn2 = csto6 (target_obj[target]); + prfile (&f, obj_name); + if (target==new10) f.fn2 = csto6 ("NSTK"); + else f.fn2 = csto6 ("STK"); + prfile (&f, rel_name); + f.fn2 = csto6 ("SYMTAB"); + prfile (&f, sym_name); + } + +/********************************************************************** + + EXECUTE PHASE + +**********************************************************************/ + +execute_phase (n) int n; + + {extern int exctime, exccode; + int t; + + set_program_name (n); + t = etime (); + if (execv (phase_prog[n], phase_argc[n], phase_argv[n])) + {cprint ("Unable to execute phase %s\n", phase_name[n]); + return (-1); + } + phase_et[n] = etime () - t; + phase_pt[n] = exctime; + return (exccode); + } + +/********************************************************************** + + SET_PHASE_OPTION + + Set phase option for phase PC to be OC. + +**********************************************************************/ + +set_phase_option (pc, oc) + + {int n; + + pc = lower (pc); + switch (pc) { + +# ifdef MERGE_LP + + case 'l': + case 'p': n = phase_LP; break; + +# endif + +# ifndef MERGE_LP + + case 'l': n = phase_L; break; + case 'p': n = phase_P; break; + +# endif + + case 'c': n = phase_C; break; + case 'm': n = phase_M; break; + case 'e': n = phase_E; break; + case 's': n = phase_S; break; + default: cprint ("Unrecognized Phase Designation: %c\n", pc); + return; + } + phase_option[n] = lower (oc); + } + +/********************************************************************** + + SET_PROGRAM_NAME + + Construct the file name of program for the given phase. + +**********************************************************************/ + +set_program_name (n) int n; + + {char *r, *s, *t; + + switch (phase_option[n]) { + case 'o': r = old_prefix; s = old_suffix; + break; + case 't': r = test_prefix; s = test_suffix; + break; + default: cprint ("Unrecognized Phase Option: %c\n", + phase_option[n]); + case 'n': r = normal_prefix; s = normal_suffix; + break; + } + t = target_suffix[target]; + if (n == phase_E || n == phase_S) t = ""; + sconcat (phase_prog[n], 4, r, phase_name[n], t, s); + } + +/********************************************************************** + + SET_TARGET - Set Target Machine + +**********************************************************************/ + +set_target (s) + char *s; + + {int c, i; + char *p; + + p = s; + while (c = *p) *p++ = lower (c); + for (i=0; i+ '\t' */ + {register int c; + while ((c = cgetc (f)) > 0) + {if (c == '-') + {c = cgetc (f); + if (!digit (c)) continue; + while (digit (c)) c = cgetc (f); + if (c != '\t') continue; + cprint ("Assembler Errors.\n"); + cclose (f); + return (TRUE); + } + } + cclose (f); + delete (temp); + } + return (FALSE); + } + +int digit (c) + {return (c>='0' && c<='9');} + +/********************************************************************** + + SCONCAT - String Concatenate + + concatenate strings S1 ... Sn into buffer B + return B + +**********************************************************************/ + +char *sconcat (b, n, s1, s2, s3, s4, s5, s6, s7, s8) + char *b, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8; + + {char **s, *p, *q; + int c; + + q = b; + s = &s1; + + while (--n >= 0) + {p = *s++; + while (c = *p++) *q++ = c; + } + + *q = 0; + return (b); + } + +/********************************************************************** + + SLOWER - Convert String To Lower Case + +**********************************************************************/ + +slower (s) char *s; + + {int c; + while (c = *s) *s++ = lower (c); + } + \ No newline at end of file diff --git a/arc/ar6:c/CNOP H b/arc/ar6:c/CNOP H new file mode 100644 index 00000000..a1e7c5cf --- /dev/null +++ b/arc/ar6:c/CNOP H @@ -0,0 +1,66 @@ +char *nodeop [] { + "", + "end-file", + "idn", + "integer", + "float", + "string", + "call", + "?", + "++(pre)", + "++(post)", + "--(pre)", + "--(post)", + "* (un)", + "& (un)", + "- (un)", + "~ (un)", + "! (un)", + "& (bin)", + "|", + "^", + "%", + "/", + "* (bin)", + "- (bin)", + "+", + "=", + "<", + ">", + "==", + "!=", + "<=", + ">=", + "<<", + ">>", + "=>>", + "=<<", + "=+", + "=-", + "=*", + "=/", + "=%", + "=&", + "=^", + "=|", + "&&", + "||", + ".", + ":", + ",", + "sizeof", + "","","","","","","","","","","","", + "","","","","","","","","","","","","","","","","","", + "if", + "goto", + "branch", + "label", + "stmtl", + "switch", + "case", + "default", + "return", + "program", + "exprstmt", + "elist"}; + \ No newline at end of file