Open Collections

UBC Theses and Dissertations

UBC Theses Logo

UBC Theses and Dissertations

Microsput : a microcomputer operating system for planar magnetron sputtering McMahon, Richard William 1982

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Notice for Google Chrome users:
If you are having trouble viewing or searching the PDF with Google Chrome, please download it here instead.

Item Metadata

Download

Media
831-UBC_1982_A7 M25.pdf [ 22.33MB ]
Metadata
JSON: 831-1.0095276.json
JSON-LD: 831-1.0095276-ld.json
RDF/XML (Pretty): 831-1.0095276-rdf.xml
RDF/JSON: 831-1.0095276-rdf.json
Turtle: 831-1.0095276-turtle.txt
N-Triples: 831-1.0095276-rdf-ntriples.txt
Original Record: 831-1.0095276-source.json
Full Text
831-1.0095276-fulltext.txt
Citation
831-1.0095276.ris

Full Text

MICROSPUT: A MICROCOMPUTER OPERATING SYSTEM FOR PLANAR MAGNETRON SPUTTERING by RICHARD WILLIAM MCMAHON B.A.Sc, The University of B r i t i s h Columbia, 1979 A THESIS SUBMITTED IN PARTIAL FULFILMENT OF THE REQUIREMENTS FOR THE DEGREE OF MASTER OF APPLIED SCIENCE in THE FACULTY OF GRADUATE STUDIES (Department of Physics) We accept this thesis as conforming" to the required standard THE UNIVERSITY OF BRITISH COLUMBIA OCTOBER 1982 Richard William McMahon, 1982 In presenting t h i s thesis i n p a r t i a l f u l f i l m e n t of the requirements for an advanced degree at the University of B r i t i s h Columbia, I agree that the Library s h a l l make i t f r e e l y available for reference and study. I further agree that permission for extensive copying of t h i s thesis for scholarly purposes may be granted by the head of my department or by his or her representatives. I t i s understood that copying or publication of t h i s thesis for f i n a n c i a l gain s h a l l not be allowed without my written permission. Department O f Physics  The University of B r i t i s h Columbia 1956 Main Mall Vancouver, Canada V6T 1Y3 18 October 1982 i i ABSTRACT A Microcomputer software package was developed to monitor and c o n t r o l the p l a n a r magnetron s p u t t e r i n g p r o c e s s , and to r e c o r d and d i s p l a y data from the process equipment. The system, dubbed MicroSput, was designed to be as f l e x i b l e as p o s s i b l e , without s a c r i f i c i n g p r e c i s i o n of process c o n t r o l or comprehensiveness of o p e r a t i o n s performed. MicroSput was s u c c e s s f u l l y employed to provide plasma v o l t a g e c o n t r o l , which in turn allowed unprecedented i n v e s t i g a t i o n s of the of the p l a n a r magnetron s p u t t e r i n g p r o c e s s . i i i TABLE OF CONTENTS ABSTRACT i i LIST OF FIGURES v ACKNOWLEDGMENT . v i INTRODUCTION 1 CHAPTER TWO Overview of MicroSput S t r u c t u r e 8 CHAPTER THREE MicroSput Software S p e c i f i c to S p u t t e r i n g 15 CHAPTER FOUR MicroSput G e n e r a l i z e d Parameter Software 25 CHAPTER FIVE Data F i l i n g and P l o t t i n g 41 CHAPTER SIX El 2 A n a l o g / D i g i t a l Input/Output I n t e r f a c e Programming 56 CHAPTER SEVEN MicroSput M u l t i T a s k i n g Software 70 CHAPTER EIGHT General Purpose MicroSput Subprogram Modules 84 CONCLUSION 87 REFERENCES 88 APPENDIX A Un i t I n t e r f a c e s 89 APPENDIX B Compiler L i s t i n g of Program Sputter 120 APPENDIX C Compiler L i s t i n g s APPENDIX D Compiler L i s t i n g s APPENDIX E Compiler L i s t i n g s APPENDIX F Compiler L i s t i n g s of Parameter U n i t s of E12 I n t e r f a c e U n i t s of M u l t i t a s k i n g U n i t s of General U n i t s V L I S T OF F IGURES F I G U R E 1 S t r u c t u r e o f M i c r o S p u t C o m p i l a t i o n U n i t s 6 F I G U R E 2 P a r a m e t e r D i s p l a y S c r e e n Image ' s p u t t e r ' 16 F I G U R E 3 G a s L e a k V a l v e C h a r a c t e r i s t i c s 22 F I G U R E 4 P a r a m e t e r E d i t i n g S c r e e n Image ' p r m e d i t ' 34 F IGURE 5 P a r a m e t e r W a l k i n g S c r e e n Image ' w a l k e r ' 37 F IGURE 6 P a r a m e t e r F i l i n g S c r e e n Image ' p a r a m s a v ' 48 F I G U R E 7 P a r a m e t e r P l o t t i n g S c r e e n Image ' p l o t s e t ' 54 F I G U R E 8 A n a l o g I n p u t M u l t i p l e x i n g S c r e e n Image ' t r i g a n a ' . . . 67 F I G U R E 9 S c r e e n Image D e v e l o p m e n t T e s t P a t t e r n ' t e s t ' 83 v i ACKNOWLEDGMENT I would l i k e to express my s i n c e r e g r a t i t u d e and a p p r e c i a t i o n to the many people who helped me with the MicroSput development and t h e s i s p r e p a r a t i o n . The f e l l o w members of our s p u t t e r i n g group deserve my s p e c i a l thanks. Dr. Robert Parsons provided i n s p i r a t i o n and c o n s t r u c t i v e c r i t i c i s m c o n s i s t e n t l y throughout the p r o j e c t ; he and Dr. C h a r l e s Schwerdtfeger went c o n i d e r a b l y out of t h e i r way to e d i t and comment on the document in time f o r the graduation d e a d l i n e . John A f f i n i t o throughly t e s t e d and manipulated a l l aspects of the v a r i o u s software v e r s i o n s . Michael B r e t t and Dr. Juan Rostworowski generously l i s t e n e d to and commented on my f r u s t r a t i o n s with many t e c h n i c a l problems. B r i a n S u l l i v a n helped me expand my work to take advantage of the resources of the Computing Centre. The microcomputer system development work continues to r e l y h e a v i l y on P h y s i c s Departmental t e c h n i c a l support. Design of f i x e d computer equipment for use i n an e v o l v i n g l a b o r a t o r y s e t t i n g i s a constant c h a l l e n g e ; the work of Stan Knotek and Tom F e l t o n i s proof of t h e i r e x p e r t i s e i n t h i s s i t u a t i o n . I am a l s o indebted to Mary Ann P o t t s f o r her p a t i e n t a s s i s t a n c e d u r i n g the i n i t i a l stages of the programming. 1 INTRODUCTION Planar magnetron (PM) s p u t t e r i n g i s a high r a t e t h i n f i l m d e p o s i t i o n process [1-3]. Because s p u t t e r i n g i s non-thermal, i t can be s u c c e s s f u l l y employed to d e p o s i t c o a t i n g s on p l a s t i c s u b s t r a t e s . With adequate c o n t r o l of process parameters such as the v a r i o u s gas flows and the plasma v o l t a g e , a PM s p u t t e r i n g system can be used to d e p o s i t f i l m s of a r b i t r a r y s t o i c h i o m e t r y [ 4 ] . One a p p l i c a t i o n where c o n t r o l l e d s t o i c h i o m e t r i c f i l m s on c l e a r p l a s t i c s u b s t r a t e s i s u s e f u l i s in the f a b r i c a t i o n of t r a n s p a r e n t window i n s u l a t i o n [ 5 ] , C l e a r , i n f r a r e d r e f l e c t i v e c o a t i n g s e i t h e r a p p l i e d to p l a s t i c and attached to windows, or a p p l i e d d i r e c t l y to the window g l a z i n g , can be expected to cut the r a d i a t i v e component of heat t r a n s f e r through a window by more than 60% [ 6 ] . In 1978 a r e s e a r c h group in the P h y sics Department at UBC began the development of a PM s p u t t e r i n g system for use i n d e p o s i t i n g n o n - s t o i c h i o m e t r i c i n f r a r e d r e f l e c t i v e c o a t i n g s . In order to gain as i n t i m a t e a f a m i l i a r i t y as p o s s i b l e with the s p u t t e r i n g process, the system was designed and b u i l t in-house. The f i r s t experimental f i l m s were produced in May of 1980 using manual c o n t r o l ; at the same time work began on a microcomputer program to p r o v i d e automatic c o n t r o l . I t was f e l t that by using a microcomputer to c o n t r o l the system, the optimum system s t a b i l i t y , r e p e a t a b i l i t y and p r e c i s i o n would be reached. Since there were no precedents in the l i t e r a t u r e f o r microcomputer c o n t r o l of a g e n e r a l purpose experimental s p u t t e r i n g system, i t 2 was necessary to design the software, l i k e the s p u t t e r i n g hardware, beginning at the ground l e v e l . By October of 1980 automatic c o n t r o l was being used in a l l experiments. No a c t u a l i n c r e a s e i n system performance c o u l d be a t t r i b u t e d to the computer at that time; the program was u s e f u l simply from a convenience p o i n t of view. The program s t r u c t u r e at that p o i n t c o n s i s t e d of one loop which would c o n t i n u a l l y c y c l e about checking the v a r i o u s p i e c e s of s p u t t e r i n g equipment. The software had been w r i t t e n i n Pascal and ran on the UCSD Pas c a l V e r s i o n II o p e r a t i n g system. The Cromemco computer hardware i n c l u d e d a Z80 microcomputer, 48K RAM, 4FDC floppy d i s k c o n t r o l l e r , two 80K mini f l o p p y disk d r i v e s , and a TU-ART s e r i a l port to d r i v e the T e l e t y p e p r i n t e r . A Soroc IQ 120 VDT provided operator i n t e r a c t i o n . An in-house a n a l o g / d i g i t a l input/output system was b u i l t to i n t e r f a c e to the experimental equipment. The d e l i v e r y i n October 1980 of a hardware c l o c k was a t u r n i n g p o i n t i n the programming methods. With a time r e f e r e n c e for a l l a l g o r i t h m s , the software tended to develop towards a more m u l t i t a s k i n g approach. Measurement and c o n t r o l were performed for each parameter a c c o r d i n g to elapsed time: s e r v i c i n g of i n d i v i d u a l p i e c e s of equipment was done a c c o r d i n g to a queue, i n t o which the tasks were pl a c e d on the b a s i s of d e s i r e d execution time. The program was, however, becoming i n c r e a s i n g l y complex. I t was a l s o outgrowing i t s modest hardware host: more memory, l a r g e r d i s k d r i v e s , and a f a s t e r p r i n t e r were a l l needed. Two c o n f l i c t i n g plans f o r the computer system's f u t u r e were emerging among the r e s e a r c h group. One p r o p o s a l was to scrap 3 the e x i s t i n g software i n favor of an on l i n e i n t e r p r e t i v e Basic system. Only an i n t e r p r e t i v e system, i t was argued, c o u l d p r o v i d e the programming f l e x i b i l i t y necessary i n an experimental l a b o r a t o r y . Furthermore, the Basic programming language was understood by a l l group members; Pas c a l was not. Each of the s p u t t e r i n g personnel would, under the Basic system, modify h i s own v e r s i o n of the s p u t t e r i n g program to s u i t h i s p a r t i c u l a r experimental needs and programming t a s t e . F i n a l l y , the e x i s t i n g computer system had not p r o v i d e d any s c i e n t i f i c breakthrough in PM s p u t t e r i n g c o n t r o l ; there seemed to be l i t t l e p o i n t i n continued development towards i n c r e a s i n g the program s t r u c t u r e . The c o n f l i c t i n g p r oposal was f o r continued system development towards a s i n g l e comprehensive s p u t t e r i n g o p e r a t i n g system. Equipment would not only be c o n t r o l l e d , but data would be saved and d i s p l a y e d . Process c o n t r o l would c a r r y on u n i n t e r r u p t e d even d u r i n g lower p r i o r i t y jobs such as operator i n t e r a c t i o n . Suggestions of s p e c i f i c m o d i f i c a t i o n s r e q u i r e d f o r p a r t i c u l a r experimental c o n d i t i o n s would be analysed as to the more general problem which might b e t t e r be s o l v e d . Program changes would be made more slowly but e v e n t u a l l y , i t was hoped, would be r a r e l y r e q u i r e d . Only by adhering to the high goals of program s t r u c t u r e , g e n e r a l i t y , and c o n s i s t a n c y would optimal system performance be reached. C l e a r l y the s t r u c t u r e d programming methods enforced by the P a s c a l language b e t t e r s u i t e d the second p r o p o s a l . Without any c l e a r consensus as to which programming method would e v e n t u a l l y prove s u p e r i o r , work c a r r i e d on in a somewhat p r o b a t i o n a r y manner with the P a s c a l system. Another 16K of RAM, 4 two Shugart 250K 8" d i s k d r i v e s , and an IDS 460G p r i n t e r were purchased. The a r r i v a l i n e a r l y 1981 of the UCSD p-System V e r s i o n IV added g r e a t l y to the development momentum. A t o t a l of seven s e p a r a t e l y compiled program modules had been allowed by the p r e v i o u s v e r s i o n ; there was v i r t u a l l y no l i m i t to program mod u l a r i t y i n V e r s i o n IV. The new system supported the q u a s i - c o n c u r r e n t execution of program tasks on a p r i o r i t y b a s i s ; use of t h i s f e a t u r e was e a g e r l y a n t i c i p a t e d but delayed because of the programming changes that would be r e q u i r e d . The sharing of memory among program segments was a l s o a new and v a l u a b l e f e a t u r e of V e r s i o n IV; development of a s i n g l e omnibus s p u t t e r i n g program would have soon r e q u i r e d more memory than allowed by the computer system. A new s p u t t e r i n g c o n t r o l package was in p l a c e by A p r i l of 1981. One added f e a t u r e of the new software system was the choice of c u r r e n t , power, or v o l t a g e as the feedback parameter to c o n t r o l the high v o l t a g e plasma dc c u r r e n t source. Use of the v o l t a g e c o n t r o l mode in r e a c t i v e s p u t t e r i n g experiments allowed us to explore what was p r e v i o u s l y known as a runaway t r a n s i t i o n between a m e t a l l i c and a f u l l y r e a c t e d t a r g e t [ 7 ] . By s t a b l e v o l t a g e c o n t r o l w i t h i n the t r a n s i t i o n r e gion we were ab l e to d e p o s i t f i l m s of a r b i t r a r y s t o i c h i o m e t r y [ 4 ] . T h i s proved to be the s c i e n t i f i c breakthrough needed to j u s t i f y the previous software development work. Development of the software package cont i n u e d . The programming was reworked to take advantage of the p-System concurrency support. Even g r e a t e r emphasis was p l a c e d on mod u l a r i t y and g e n e r a l i t y . . A l l communications with the VDT were 5 done i n a manner independent of the manufacturer's s p e c i f i c command s e t . The name MicroSput was coined to apply to the o v e r a l l set of program modules. T h i s l a t e s t software v e r s i o n was ready f o r use i n October, 1982. The e x p l a n a t i o n and documentation of MicroSput i s the t o p i c of t h i s t h e s i s . The o b j e c t i v e of MicroSput i s to i n t e r a c t i v e l y monitor, c o n t r o l , r e c o r d and d i s p l a y data from the v a r i o u s p i e c e s of vacuum and e l e c t r o n i c equipment which comprise a r e a c t i v e planar magnetron s p u t t e r i n g system. The s t a t e of the s p u t t e r i n g system can be c h a r a c t e r i z e d by the values of a set of i n t e r - r e l a t e d s p u t t e r i n g parameters. These values must be measured or c a l c u l a t e d and, where a s s o c i a t e d c o n t r o l hardware e x i s t s , must be compared with o p e r a t o r - s p e c i f i e d s e t p o i n t s to generate hardware c o n t r o l s i g n a l s . The values may a l s o be sent to s u i t a b l e d i s p l a y and/or r e c o r d i n g d e v i c e s . For a r e s e a r c h s p u t t e r i n g system the set of parameters of i n t e r e s t to the experimenter i s mutable. One must be able to extend and a l t e r the software e a s i l y as re s e a r c h r e s u l t s , n e c e s s i t a t e the a d d i t i o n or m o d i f i c a t i o n of s p u t t e r i n g hardware. MicroSput achieves t h i s e s s e n t i a l a d a p t a b i l i t y by p r o v i d i n g a l a r g e pool of s e p a r a t e l y compiled, independent u t i l i t y r o u t i n e s which are i n c r e a s i n g l y t i e d together at higher programming l e v e l s (see F i g . 1). For t h i s reason, MicroSput i s r e f e r r e d to by the author as an o p e r a t i n g system; i t i s hoped that MicroSput w i l l be of general use f o r the o p e r a t i o n of both s p u t t e r i n g and no n - s p u t t e r i n g experiments. The s t r u c t u r e of t h i s t h e s i s i s as f o l l o w s . Chapter Two i s an overview of the MicroSput system; a short e x p l a n a t i o n of each o 6 Sputter P l o t t e r ParamSave ParamEdi t Walker ParamUt i1 Parameter P l o t U t i l TrigAna E l2Sched ScrnBuf f ReadRybd Schedule S t a r t e r E12AnaI0 E12DigI0 E1 2ISR DataBus Wr i tCons Clock E x t r a S c r Mi scFunc ErrMessg F i g u r e 1. S t r u c t u r e of MicroSput c o m p i l a t i o n u n i t s . U n i t s at top of the F i g u r e have access to those below. 7 of the module groupings i n F i g . 1 i s presented. Chapter Three d e t a i l s the top module l e v e l , the program S p u t t e r . The g e n e r a l i z e d parameter l e v e l modules are d e a l t with i n Chapters Four and F i v e . Chapter Six p r e s e n t s the modules developed to operate the a n a l o g / d i g i t a l i n t e r f a c e hardware. Modules of general use in m u l t i t a s k i n g programs are e x p l a i n e d i n Chapter Seven, and those of general use f o r any programs in Chapter E i g h t . Chapter Nine concludes the t h e s i s . Appendices i n c l u d e the g l o b a l d e c l a r a t i o n s made by each module and the e n t i r e l i s t i n g s of MicroSput. The at sig n ('@') i s used in the l i s t i n g s f o r the Pascal p o i n t e r . 8 CHAPTER TWO Overview of MicroSput S t r u c t u r e MicroSput i s w r i t t e n i n Pas c a l and runs on the UCSD p-System V e r s i o n IV.0 o p e r a t i n g system. Three p-System extensions to standard P a s c a l upon which the MicroSput s t r u c t u r e h e a v i l y r e l i e s are ( l ) s e p a r a t e l y compiled subprogram modules, (2) memory o v e r l a y s , and (3) m u l t i t a s k i n g . A UCSD p-System subprogram module i s c a l l e d a c o m p i l a t i o n u n i t . A u n i t i s a group of s e p a r a t e l y compiled c o n s t a n t s , types, v a r i a b l e s , procedures, f u n c t i o n s , and processes which can be l i n k e d i n t o a program f o r use at run time. U n i t s are i d e a l f o r grouping together programming to form s e l f c o n s i s t e n t packages such as sending data to an x-y p l o t t e r , d e f i n i n g a type complex and su p p l y i n g some complex number o p e r a t i o n s , and reading and checking bounds of data entered with the keyboard. Because a c o m p i l a t i o n u n i t can use the data and r o u t i n e s of other u n i t s , and u n i t s are w r i t t e n and compiled s e p a r a t e l y , the UCSD p-System allows a pyramid s t r u c t u r e d h i e r a r c h y of i n c r e a s i n g l y s p e c i f i c u n i t s r e l y i n g on and t y i n g together modules of more general use. A c o m p i l a t i o n u n i t i s comprised of two p a r t s : ( 1 ) the i n t e r f a c e , which p r o v i d e s a l l d e c l a r a t i o n s of c o n s t a n t s , types, v a r i a b l e s , procedures, f u n c t i o n s , and processes a v a i l a b l e to programs (or other u n i t s ) using the u n i t , and (2) the implementation, which p r o v i d e s the r e a l i z a t i o n of the r o u t i n e s d e c l a r e d i n the i n t e r f a c e . Data and r o u t i n e s d e c l a r e d i n the implementation part may be used to help i n t h i s 9 r e a l i z a t i o n ; however only d e c l a r a t i o n s made i n the i n t e r f a c e p a r t are a v a i l a b l e e x p l i c i t l y . Each u n i t ' s implementation may c o n t a i n an i n i t i a l i z a t i o n and/or h a l t i n g p a r t ; a l l i n i t i a l i z a t i o n s of the used u n i t s are executed before the main program begins and a l l h a l t i n g p a r t s are executed a f t e r the main program i s terminated. Memory o v e r l a y s allow the execution of a UCSD p-System program which i s too l a r g e to f i t e n t i r e l y in random access memory (RAM). The minimum amount of program code which can be read i n t o RAM or o v e r w r i t t e n i n RAM i s a code segment. Procedures, f u n c t i o n s , and processes may be e x p l i c i t l y d e c l a r e d as code segments. A l l remaining r o u t i n e s i n a c o m p i l a t i o n u n i t w i l l a c t as one f u r t h e r code segment. Only the segment of program code which i s a c t u a l l y running need be i n RAM at any i n s t a n t . When memory i s requested because of an expanding stack, a dynamic memory a l l o c a t i o n , or a c a l l to a r o u t i n e in an o v e r l a i d segment, the memory c o n t a i n i n g the l e a s t used segments w i l l be o v e r l a i d . M u l t i t a s k i n g allows quasi concurrent execution of separate p r o c e s s e s . Process s y n c h r o n i z a t i o n and e x c l u s i o n are accomplished v i a w a i t i n g f o r and s i g n a l l i n g semaphores. A process can continue past a wait statement only i f the semaphore upon which i t waits has been s i g n a l l e d . Any number of processes may wait f o r a s i n g l e semaphore, but only one (that which has the h i g h e s t p r i o r i t y ) can continue execution each time the semaphore i s s i g n a l l e d . Every execution of a s i g n a l or a wait statement f o r c e s the o p e r a t i n g system to check a l l processes and continue execution with the hi g h e s t p r i o r i t y process which i s no 10 longer w a i t i n g . Each p-System process i s a s s i g n e d a p r i o r i t y (0 i s lowest, 255 h i g h e s t ) and a l l o c a t e d i t s own data e v a l u a t i o n stack (of 40 or more words) when i t i s s t a r t e d . The main program i s i t s e l f a task; i t s p r i o r i t y i s 128, and i t s stack s i z e i s l i m i t e d only by the amount of a v a i l a b l e memory. The MicroSput c o m p i l a t i o n u n i t s are shown in F i g . 1. L i s t i n g s of the i n t e r f a c e p a r t s of these modules are contained in Appendix A. The u n i t s are grouped in the f i g u r e a c c o r d i n g to programming l e v e l . The most general program l e v e l , shown at the bottom of F i g . 1, c o n s i s t s of the u n i t s Clock, ErrMessg, MicsFunc, ExtraScreenOps, and WritCons. These u n i t s c o n t a i n d e c l a r a t i o n s and r o u t i n e s which might be u s e f u l in any UCSD p-System program. Clock d e f i n e s the type tim_rec, a 32 b i t i n t e g e r , and p r o v i d e s a set of u s e f u l 32 b i t i n t e g e r o p e r a t i o n s and c o n v e r s i o n s . ErrMessg s u p p l i e s a systematic method of h a n d l i n g d e t e c t e d f a t a l e r r o r s , producing a c l e a n e x i t from the program and the d i s p l a y of a message d e s c r i b i n g the e r r o r . MiscFunc c o n t a i n s an assortment of general purpose mathemetical and c h a r a c t e r o p e r a t i o n s . ExtraScreenOps i s an extension to the u n i t ScreenOps, which i s provided as part of the UCSD p-System to allow a s t a n d a r d i z e d method of communicating with the video d i s p l a y t e r m i n a l (VDT). WritCons i s a set of procedures which send formatted data to the VDT screen. The next l e v e l of MicroSput subprograms i n c l u d e s u n i t s which are u s e f u l f o r m u l t i t a s k i n g . S t a r t e r a c t s as a look up t a b l e f o r process stack s i z e s and p r i o r i t i e s ; s i n c e a l l MicroSput processes are s t a r t e d with i n f o r m a t i o n from t h i s u n i t , i t i s the only f i l e which must be e d i t e d when one wishes to 11 change the system p r i o r i t i e s . DataBus d e f i n e s a type handshake and p r o v i d e s a l l the r o u t i n e s needed f o r synchronous and/or asynchronous data t r a n s f e r between proc e s s e s . Schedule allows for s y n c h r o n i z a t i o n of processes with hardware events: the system c l o c k , VDT input s t a t u s , and e x t e r n a l d e v i c e s are p o l l e d (the l a t t e r v i a a handshake to e x t e r n a l device s c h e d u l i n g u n i t s ) ; and process timeout waits and operator command waits are queued and s e r v i c e d . ReadKybd s u p p l i e s formatted asynchronous VDT in p u t . ScrnBuff p r o v i d e s a normally d i s k r e s i d e n t pool of background VDT screen images, and channels formatted data from processes to the VDT screen only when the c o r r e c t screen image i s d i s p l a y e d . The general and m u l t i t a s k i n g module groupings are useable on any UCSD p-System implementation, because they operate only on standard i / o hardware (the VDT, disk d r i v e s , the system c l o c k ) . Conversely, the E12 subprogram group makes no use of the standard i / o hardware, but i n s t e a d operates the analog/ d i g i t a l i / o i n t e r f a c e 1 s p e c i f i c to the computer system in Hennings room 118D at UBC. A l l r o u t i n e s i n the E12 group are w r i t t e n in Assembler. E12ISR i n c l u d e s the i n t e r r u p t s e r v i c e r o u t i n e s used f o r d i g i t a l output p u l s i n g and analog input m u l t i p l e x i n g ; E12ISR i s not meant to be used by u n i t s other those i n the E12 group. E12DigI0 d e f i n e s a type d i g i t a l and pr o v i d e s access to the TTL inputs and outputs. E12AnaI0 operates the analog inputs and outputs; the m u l t i p l e x e d UBC Physics E l e c t r o n i c s Lab Job No. E12. 1 2 i n t e g r a t i n g analog input i s kept c o n s t a n t l y c o n v e r t i n g by i n t e r r u p t s e r v i c e r o u t i n e s . The t h i r d l e v e l of MicroSput modules t i e s together and adds to the standard system r o u t i n e s from the gen e r a l and m u l t i t a s k i n g groups, and the non-standard E12 s p e c i f i c group. E12Sched p o l l s the E12 d i g i t a l and analog inputs ( v i a a handshake with the Schedule u n i t ) and queues and s e r v i c e s d i g i t a l and analog input s t a t e process w a i t s . TrigAna allows the operator to i n t e r a c t i v e l y s e l e c t the E12 analog input m u l t i p l e x i n g method, and to save the m u l t i p l e x i n g i n f o r m a t i o n f o r the next MicroSput run. P l o t U t i l p r o v i d e s a set of n o n - i n t e r a c t i v e r o u t i n e s to c o n t r o l an x-y p l o t t e r connected to the E12 i n t e r f a c e . The f o u r t h MicroSput module l e v e l d e f i n e s and works with g e n e r a l i z e d parameters. The u n i t Parameter d e f i n e s a parameter i n f o r m a t i o n r e c o r d , which i n c l u d e s the parameter name, u n i t s , and s i n g l e c h a r a c t e r command key, the parameter value and upper l i m i t , the minimum process wait between parameter s e r v i c e s , the d i s p l a y screen image, p o s i t i o n and format i n f o r m a t i o n f o r the parameter name, u n i t s , and value, and the parameter value as read back from a data f i l e . If the parameter value i s measured from the analog inputs, then the parameter i n f o r m a t i o n record p o i n t s to an analog i n f o r m a t i o n record, which i n c l u d e s the input channel number, the unsealed input value, the input s c a l i n g f a c t o r , the unsealed value from which an input must d r i f t before being noted, and the amount that d r i f t must be. If the parameter i s a l s o c o n t r o l l e d , the parameter i n f o r m a t i o n r e c o r d p o i n t s to a c o n t r o l i n f o r m a t i o n r e c o r d , which i n c l u d e s the 13 s e t p o i n t , the r a t e of change of the parameter valu e , the d e r i v a t i v e feedback m u l t i p l i e r , and the screen image, p o s i t i o n , and f o r m a t t i n g i n f o r m a t i o n f o r the s e t p o i n t d i s p l a y . The u n i t Parameter a l s o p r o v i d e s a set of r o u t i n e s which perform n o n - i n t e r a c t i v e manipulations of the parameters, such as reading the analog input i n f o r m a t i o n , c a l c u l a t i n g the c o n t r o l increment, d i s p l a y i n g the l a t e s t value, and i n i t i a l i z i n g and saving the l i s t of parameter i n f o r m a t i o n between runs. The u n i t s ParamUtil, ParamEdit, and Walker provide some mis c e l l a n e o u s r o u t i n e s u s e f u l f o r i n t e r a c t i v e manipulations of the parameters. One ParamUtil r o u t i n e p r o v i d e s a prompt l i n e s p e c i f y i n g the s i n g l e c h a r a c t e r command and name of a l l parameters, a l l measured parameters, a l l c o n t r o l l e d parameters, or a l l measured and c o n t r o l l e d parameters. * Another ParamUtil r o u t i n e prompts the operator f o r a c o n t r o l l e d parameter and reads and checks the bounds of a new s e t p o i n t s p e c i f i c a t i o n . The MicroSput u n i t ParamEdit allows the operator to e d i t the parameter, analog, and c o n t r o l i n f o r m a t i o n r e c o r d f i e l d s . Walker i n t e r a c t i v e l y scans one c o n t r o l l e d parameter s e t p o i n t . ParamSave performs the saving of parameter values on flopp y d i s k . The operator s e l e c t s the f i l e to w r i t e t o, the parameters to save, the data i n t e g r a t i o n time, and f o r automatic saving, the frequency of data s a v i n g . The operator may a l s o s e l e c t a f i l e to read data from ( t h i s may, but need not, be the d a t a ' w r i t e f i l e ) . The MicroSput u n i t P l o t t e r allows the operator to choose parameters to p l o t , and p l o t s the values of those parameters as read from the data read f i l e . 14 The top MicroSput l e v e l i s the program S p u t t e r . Sputter uses a set of g e n e r a l i z e d parameters and a s s o c i a t e d processes to read, r e c o r d , d i s p l a y , and/or c o n t r o l a l l the s p u t t e r i n g vacuum and e l e c t r o n i c equipment. 1 5 CHAPTER THREE MicroSput Software S p e c i f i c To S p u t t e r i n g The h i g h e s t l e v e l c o m p i l a t i o n u n i t i n MicroSput i s the program S p u t t e r (see l i s t i n g i n Appendix B). T h i s u n i t i s the only p a r t of MicroSput which t r e a t s the v a r i o u s s p u t t e r i n g parameters a c c o r d i n g to t h e i r exact hardware nature; i t i s t h e r e f o r e the only f i l e which must be e d i t e d when parameters are to be added or a l t e r e d , although one may a l s o want to change the parameter inf o r m a t i o n f i l e (see Chapter Four) and the process stack s i z e and p r i o r i t y f i l e (see Chapter Seven). The f i r s t r o u t i n e to be executed in Sputter i s the segment procedure S p u t l n i t , which i n i t i a l i z e s a few parameter s p e c i f i c v a r i a b l e s (see l i s t i n g ) , c a l l s the Parameter procedure P r m l n i t (which in turn i n i t i a l i z e s the date and time d i s p l a y s and s t a r t s up s e r v i c i n g of the a n a l o g / d i g i t a l i n t e r f a c e ) , c r e a t e s and i n i t i a l i z e s a l l parameter i n f o r m a t i o n records (by s u c c e s s i v e c a l l s to the Parameter f u n c t i o n PrmGet), and s t a r t s the parameter s e r v i c i n g processes (the process stack s i z e s and p r i o r i t i e s are determined by s u c c e s s i v e c a l l s to the S t a r t e r procedure S t r t l n f o ) . The parameter d i s p l a y screen image (see F i g . 2) i s then w r i t t e n to the VDT, and S p u t l n i t terminated. Since i n i t i a l i z a t i o n i s only r e q u i r e d once per run of MicroSput, the segment S p u t l n i t i s from t h i s p o i n t on swappable ( i . e . may be o v e r l a i d ) , and t h e r e f o r e does not waste v a l u a b l e RAM space. For the remainder of the MicroSput run, the main program task loops, prompting the operator by d i s p l a y i n g the f o l l o w i n g s t r i n g @ name u n i t s value s e t p o i n t M i c r o S p u t I t ime: date: C O R O N A vacuum co a t e r s i n c . Figu r e 2 . Parameter d i s p l a y screen image ' s p u t t e r ' . 17 a c r o s s the top of the VDT screen: " S p u t t e r : S ( e t p o i n t W(alk D ( a t a l o g P ( l o t E ( d i t T(ime Q ( u i t " . The operator e n t e r s the corresponding i n t e r a c t i o n mode, when d e s i r e d , by t y p i n g one of the f o l l o w i n g c h a r a c t e r s : S, W, D, P, E, T, or Q ( i n upper or lower case, a l l other responses are i g n o r e d ) . The s e t p o i n t i n t e r a c t i o n mode allows the operator to i n i t i a l i z e and to a l t e r parameter s e t p o i n t s . A c a l l i s made to the ParamUtil procedure PrmEdSet, which prompts f o r the parameter name, checks before a c c e p t i n g the entered s e t p o i n t v a l u e , and re t u r n s with a p o i n t e r to the parameter i n f o r m a t i o n r e c o r d of the parameter j u s t changed. Any f u r t h e r changes r e q u i r e d by the hardware nature of the parameter can then be made from w i t h i n the program Sp u t t e r ; i n f a c t the only cases where t h i s i s necessary with the present set of parameters i s when one a l t e r s a- s e t p o i n t c o n t r o l l i n g the high v o l t a g e plasma dc c u r r e n t source. Since only one of c u r r e n t , v o l t a g e , or power c o n t r o l can be in e f f e c t at any given i n s t a n t , the other two parameter feedback loops must be d i s a b l e d , and t h e i r s e t p o i n t v a l u e s erased from the screen. The s e t p o i n t i n t e r a c t i o n mode cont i n u e s u n t i l the escape key i s pressed i n s t e a d of a parameter s e l e c t i o n . The walk i n t e r a c t i o n mode allows the operator to set up the automatic scanning (or 'walking') of a parameter s e t p o i n t . The e n t i r e operation- i s performed by a c a l l to the Walker procedure ParamWalk. The data l o g g i n g i n t e r a c t i o n mode allows the operator to s e l e c t read and/or w r i t e data f i l e s and to s p e c i f y the parameters to save, the i n t e g r a t i o n time f o r those saves, and 18 f o r automatic data saving, the data r e c o r d save frequency. The e n t i r e o p e r a t i o n i s performed by a c a l l to the ParamSave procedure ParamFile. The p l o t data i n t e r a c t i o n mode allows the operator to s e l e c t the p l o t parameters and bounds. I f , while i n the data log mode, the operator has s p e c i f i e d the read f i l e to be the same as the write f i l e , the data p l o t t e d w i l l be that of the c u r r e n t run. In that case, both the o l d p o i n t s a l r e a d y i n the f i l e and the new p o i n t s being added to i t are p l o t t e d . The e n t i r e o p e r a t i o n i s performed by a c a l l to the P l o t t e r procedure P l o t S e t u p . The time i n t e r a c t i o n mode i s simply a r e s e t of t = 0 , the i n i t i a l time from which the VTD d i s p l a y of the time and the data l o g g i n g w r i t e f i l e time entry are r e f e r e n c e d . T h i s r e s e t i s performed by a c a l l to the Clock procedure TimSetTO. The e d i t and q u i t i n t e r a c t i o n modes both c r e a t e c a l l s to the Sputter segment procedure S p u t E d i t . In the e d i t mode case, the operator i s prompted with the f o l l o w i n g s t r i n g : " E d i t : P a r a m e t e r s T ( r i g g e r s dcS(upply R(eturn". 'P' produces a c a l l to the ParamEdit procedure PrmEdit, which allows the operator to i n t e r a c t i v e l y e d i t a number of constants c o n t a i n e d in the parameter i n f o r m a t i o n r e c o r d s . 'T' generates a c a l l to the TrigAna procedure T r i g S e t u p , which allows the operator to i n t e r a c t i v e l y choose the m u l t i p l e x i n g method of the analog i n p u t s . 'S' causes the operator to be f u r t h e r prompted with: "Supply Gain: I ( c u r r e n t V ( o l t a g e W(power". The operator s e l e c t s one of the three supply parameters and types i n the in v e r s e of i t s feedback loop g a i n . T h i s a t t e n u a t i o n i s the 19 change i n analog output c o n t r o l v o l t a g e (0... 10'volts) r e q u i r e d f o r a given change i n supply c u r r e n t (amps), v o l t a g e ( v o l t s ) , or power ( w a t t s ) . 'R' r e s u l t s i n the e d i t mode being e x i t e d . In the q u i t mode case, the screen image i s c l e a r e d , and the operator i s presented with: "R(eturn to or [escjape from MicroSput:". If the operator types 'R', the screen image i s re-loa d e d and s p u t t e r i n g i s cont i n u e d . P r e s s i n g the escape key i s the normal method of t e r m i n a t i o n of MicroSput. The program Sputter c o n t a i n s s e r v i c i n g processes f o r a l l parameters. A l l of these processes have the same general o v e r a l l s t r u c t u r e — w h i l e MicroSput i s running, c o n t i n u a l l y loop doing the f o l l o w i n g : read or c a l c u l a t e the parameter value; i f the parameter i s c o n t r o l l e d , c a l c u l a t e and send the c o n t r o l output; d i s p l a y the new parameter value; and wait f o r a s p e c i f i e d delay p e r i o d . Of the present set of parameters, four are simple readings and d i s p l a y s of analog i n p u t s : anode, r f _ b i a s , e x t r a _ l , and ex t r a _ 2 . Since there are no d i s t i n g u i s h i n g hardware f e a t u r e s between these parameters (other than data such as name, channel number, f u l l s c a l e value, e t c . ) , they are processed by four d i f f e r e n t s t a r t s of the Sputter process MeasTask. T h i s process simply loops, a l t e r n a t e l y c a l l i n g two Parameter procedures. PrmRead waits f o r the analog input value to d r i f t from i t s l a s t r e ading, then reads and s c a l e s the v a l u e . PrmShow w r i t e s the value to the screen ( i f the parameter d i s p l a y image i s a c t i v e ) , checks to see i f a warning message should be d i s p l a y e d ( i . e . i f the value i s above an operator s p e c i f i e d upper l i m i t ) , and waits out the remainder of the operator s p e c i f i e d delay between 20 s e r v i c e s of that parameter. The s u b s t r a t e dc bias v o l t a g e i s fed through a 100:1 v o l t a g e d i v i d e r to the r f _ b i a s parameter analog i n p u t ; 2 the f l o a t i n g anode dc v o l t a g e i s fed through a 33:1 v o l t a g e d i v i d e r to the anode parameter analog i n p u t . The s p u t t e r i n g pressure i s a l s o a simple read & d i s p l a y parameter with the a d d i t i o n a l need to choose the pressure gauge range s e t t i n g from one of three decades. 3 L i k e MeasTask, the Sputter process PresTask loops, f i r s t c a l l i n g the Parameter procedure PrmRead, then PrmShow. However, before the loop i s complete, PresTask checks the analog input value ( i n m i l l i v o l t s ) : i f l e s s than 1000 (or g r e a t e r than 11500), the present range value i s checked. If the range i s not al r e a d y on maximum (minimum) gain, the l o c a l procedure ChangeRange i s c a l l e d . ChangeRange s e l e c t s the new decade using a p a i r of d i g i t a l outputs." The analog input s c a l i n g f a c t o r i s then m u l t i p l i e d or d i v i d e d by ten, the value d i s p l a y decimal f i e l d decremented or incremented by one, and a wait of one second for the meter to s e t t l e i s performed. A l l c o n t r o l l e d parameters use the Parameter f u n c t i o n Prmlncrm to determine the next d e s i r e d increment i n the parameter va l u e . Prmlncrm produces a c o n t r o l increment designed 2 A l l i n t e r f a c i n g between MicroSput hardware and high v o l t a g e equipment i s done through high v o l t a g e 1/16 amp fuses (Buss HJV 1/16). 3 MKS Baratron Type 170M-6B c a p a c i t i v e manometer. 4 C u r r e n t l y b i t s 5 & 6: both high s e l e c t s 1 Torr f u l l s c a l e , 6 high, 5 low s e l e c t s 100 mTorr f u l l s c a l e , and 6 low, 5 high s e l e c t s 10 mTorr f u l l s c a l e . 21 to d r i v e the parameter towards i t s s e t p o i n t i n a manner which depends upon the a b s o l u t e value of the d i f f e r e n c e between the s e t p o i n t and the value expressed as a percentage of f u l l s c a l e reading of that parameter. If the percentage i s g r e a t e r than 10%, the c o n t r o l increments are designed to skew the parameter value at a constant (operator s p e c i f i e d ) r a t e of change; i f l e s s than 10%, they w i l l f o r c e the value to decay towards the s e t p o i n t e x p o n e n t i a l l y (the decay constant i s chosen to match the skew r a t e s at the c r o s s o v e r between the two c o n t r o l methods). In order f o r parameter c o n t r o l to perform p r o p e r l y , the Prmlncrm c a l l e r must then s c a l e the increment value by the i n v e r s e of the feedback loop g a i n . For n o n - l i n e a r c o n t r o l s i t u a t i o n s t h i s s c a l e f a c t o r w i l l be v a r i a b l e . MicroSput may d r i v e up to four gas leak v a l v e s , 5 using a custom four channel d r i v e r 6 and four gas flow meters. 7 Each gas flow parameter i s s e r v i c e d by i t s own s t a r t of the Sputter process GasTask. GasTask d e a l s with s e v e r a l severe n o n - l i n e a r i t i e s of the leak v a l v e s . The p o s i t i o n of these leak v a l v e s v a r i e s , to f i r s t approximation, e x p o n e n t i a l l y with the sum of a l l past a p p l i e d c o n t r o l pulses (see F i g . 3). U n f o r t u n a t e l y , the exponent depends on both the p o s i t i o n of the v a l v e , and the d i r e c t i o n of motion (opening or c l o s i n g ) . GasTask approximates the true v a l v e c h a r a c t e r i s t i c s by choosing 5 G r a n v i l l e P h i l l i p s Model 216. 6 UBC Physics E l e c t r o n i c s Lab Job No. E62. 7 Hastings Type H-5 Model NALL-5. 22 * t O OS O CvJ + o + 0.0 0.5 1.0 sum of pulse lengths (seconds) 1.5 F i g u r e 3. C o n t r o l c h a r a c t e r i s t i c f o r gas leak valve #1. T r i a n g l e s p o i n t i n g upwards and downwards rep-resent i n c r e a s i n g and d e c r e a s i n g flow, respec-t i v e l y . I n i t i a l flows are 0.04 cc/m upwards, 0.05 cc/m downwards. 23 each v a l v e ' s exponent from a set of e m p i r i c a l constants determined at d i f f e r e n t flow r a t e s and d i r e c t i o n s of motion. GasTask a l s o accounts f o r severe valve backlash (over one second in v a l v e #1) by i n c r e a s i n g the c o n t r o l pulse by an e m p i r i c a l amount on every change of d i r e c t i o n . The v a l v e s are assumed to have been opening j u s t before the s t a r t of the MicroSput run. In t h i s way, any i n i t i a l backlash e r r o r w i l l serve to c l o s e the v a l v e s , a v o i d i n g overpressure d i s a s t e r s . A f i n a l p r o c e s s i n g problem of delay in the v a l v e , meter, and manifold can be handled only by a l a r g e between-service wait (e.g. 2 seconds) and slow c o n t r o l slew rate (e.g. 2% of f u l l s c a l e per second). The gas v a l v e c o n t r o l pulses are sent to the custom d r i v e r using four d i g i t a l o u t p u t s . 8 The pulses are sent by c a l l i n g the E12DigIO assembler procedure DigPulse, which uses a programmable i n t e r r u p t timer to r e s e t the p u l s e , s i n c e the execution of GasTask might be suspended in favour of other processes when the p u l s e r e s e t time a r r i v e s . Four MicroSput parameters are a s s o c i a t e d with the high v o l t a g e dc c u r r e n t s u p p l y : 9 s p l y _ c t r l , c u r r e n t , v o l t a g e , and power. The s p l y _ c t r l value i s the c o n t r o l v o l t a g e sent to the dc supply, and i s c a l c u l a t e d and d i s p l a y e d by whichever of c u r r e n t , v o l t a g e , or power parameter i s c o n t r o l l i n g the supply. 8 C u r r e n t l y b i t s 0 and 1 s e l e c t the v a l v e , a d d r e s s i n g a c c o r d i n g to the valve number in base two, a c t i v e low. B i t 2 a c t i v e low w i l l c l o s e the s e l e c t e d v a l v e , while b i t 3 a c t i v e low w i l l open i t . 9 Plasma Therm Type MDS 5000D. 24 The c u r r e n t and v o l t a g e values are read from analog inputs connected to a custom i s o l a t e d f l o a t i n g ammeter 1 0 i n the anode le g of the dc supply and a 100:1 vo l t a g e d i v i d e r fed by the cathode v o l t a g e , r e s p e c t i v e l y . Both c u r r e n t and v o l t a g e processes s i g n a l the power process to c a l c u l a t e and operate on the new power val u e . When the operator commands the main Sputter task to h a l t execution by t y p i n g Q ( u i t , [escjape, or when a s u b s i d i a r y task has d e t e c t e d a f a t a l e r r o r and r e s e t the g l o b a l Schedule boolean v a r i a b l e 'running', the main task r e s e t s 'running' and shuts down a l l s u b s i d i a r y processes by c a l l i n g the Walker procedure wkHalt, the ReadKybd procedure r k H a l t , the ScrnBuff procedure sbHalt, the ParamSave procedure p f H a l t , and the P l o t t e r procedure p l H a l t . 1 0 UBC Physics E l e c t r o n i c s Lab Job No. G90. 25 CHAPTER FOUR MicroSput G e n e r a l i z e d Parameter Software In any programming s i t u a t i o n which i n v o l v e s monitoring, r e c o r d i n g , and/or c o n t r o l l i n g of process parameters, the software engineer must decide whether to s e r v i c e each parameter with i t s own custom set of data and r o u t i n e s , or to make use of conceptual s i m i l a r i t i e s between the sundry parameters and write a l i b r a r y of g e n e r a l i z e d parameter m a n i p u l a t i o n s . The former method r e q u i r e s l i t t l e forethought; f u r t h e r custom programming can be done at a l a t e r date by other programmers without having to l e a r n or to conform to any standards. In g e n e r a l , however, t h i s route w i l l l e a d to a l a r g e amount of r e p e t i t i v e programming and may, on a microcomputer, r e q u i r e more memory than i s a v a i l a b l e . Conversely, by d e s i g n i n g a s t a n d a r d i z e d parameter data type and p r o v i d i n g g e n e r a l i z e d r o u t i n e s , one w i l l a v o i d d u p l i c a t i o n and waste of memory. Future a d d i t i o n of f u r t h e r parameters w i l l be t r i v i a l , p r o v i d i n g the standard i s understood and the new equipment to be i n t e r f a c e d to f i t s w i t h i n i t . E x t e n s i o n of the g e n e r a l i z e d parameter method to new problems may, at some p o i n t , r e q u i r e a r e d e f i n i t i o n of the parameter data type; a means to do t h i s without complete program r e v i s i o n must be made a v a i l a b l e . MicroSput s e r v i c e s s p u t t e r i n g process parameters v i a the g e n e r a l i z e d method. The parameter programming l e v e l of MicroSput i n c l u d e s s i x c o m p i l a t i o n u n i t s : Parameter, ParamUtil, ParamEdit, Walker, ParamSave, and P l o t t e r (see l i s t i n g s i n Appendix C ) . These 26 modules d e f i n e the in f o r m a t i o n and provide the r o u t i n e s r e q u i r e d to i n t e r a c t i v e l y monitor and r e c o r d and d i s p l a y data from any e l e c t r o n i c equipment which measures and/or c o n t r o l s a continuous, slowly v a r y i n g process parameter. The g e n e r a l i z e d parameter modules are r e s t r i c t e d to use on the microcomputer system i n room 118D of Hennings at UBC, since they make use of the E12 subprogram group. U n i t s ParamSave and P l o t t e r are d e s c r i b e d in Chapter F i v e . The data s t r u c t u r e s upon which a l l parameter l e v e l modules operate are the parameter, analog, and c o n t r o l i n f o r m a t i o n r e c o r d s . Since the parameter i n f o r m a t i o n records c o n t a i n p o i n t e r s to analog and c o n t r o l i n f o r m a t i o n r e c o r d s , the set of a l l three records can be unambiguously r e f e r r e d to by mentioning only the f i r s t . The data f i e l d s of these records are o u t l i n e d in Chapter 1. A copy of the r e c o r d t r i p l e t f o r every MicroSput parameter i s kept i n the f i l e uti1:system.param between MicroSput runs. Sputter (or any other high l e v e l program) i n i t i a l i z e s p o i n t e r s to and reads each set of records by c a l l i n g the Parameter f u n c t i o n PrmGet, g i v i n g a non v a r i a b l e name which i d e n t i f i e s the parameter record i n the f i l e . The row p o s i t i o n in the parameter d i s p l a y screen image of the parameter name, u n i t s , value, and s e t p o i n t ( i f the l a t t e r e x i s t s ) are assigned by s e q u e n t i a l c a l l s to PrmGet such that the f i r s t parameter i n i t i a l i z e d by PrmGet w i l l be d i s p l a y e d at the top of the image, the second j u s t below the f i r s t , e t c . PrmGet a l s o adds the i n i t i a l i z e d parameter to a l i n k e d l i s t of parameters, which i s used l a t e r i n the run f o r searches of an operator s p e c i f i e d parameter f i e l d entry (such as name or s i n g l e c h a r a c t e r command 27 key) . The body of PrmGet i s contained i n the segment f u n c t i o n ParamlO, along with PrmPut and P r m l n i t . PrmPut, which i s c a l l e d by the h a l t i n g code of the Parameter u n i t , performs the i n v e r s e f u n c t i o n of PrmGet, dumping the parameter records out to t h e i r save f i l e at the end of the MicroSput run. The parameter d i s p l a y screen image name and time, date, and warning message d i s p l a y p o s i t i o n s must be passed to P r m l n i t before any parameter i n i t i a l i z a t i o n can proceed. Besides i n i t i a l i z i n g d i s p l a y s e r v i c i n g of the time, date, and warning message, P r m l n i t s t a r t s up analog input wait s e r v i c i n g and m u l t i p l e x i n g by c a l l i n g the El2Sched procedure E12Start and the TrigAna procedure T r i g l n i t , r e s p e c t i v e l y . Those two u n i t s cannot be completely s t a r t e d up by t h e i r i n i t i a l i z a t i o n codes, as t h e i r f u l l i n i t i a l i z a t i o n s r e q u i r e data and r o u t i n e s from other u n i t s , which i n turn may not be i n i t i a l i z e d f i r s t . The u n i t i n i t i a l i z a t i o n p a r t s are executed in an order depending on the p-System run time l i n k i n g method, and may vary from one program to the next. One can be sure that a l l u n i t i n i t i a l i z a t i o n p a r t s have been run only when the main program execution begins. P r m l n i t , PrmGet, and PrmPut are implemented in the segment ParamlO, s i n c e they are needed at only the beginning or end of the MicroSput run, and may t h e r e f o r e be o v e r l a i d d u r i n g normal e x e c u t i o n . The Parameter c o m p i l a t i o n u n i t c o n t a i n s a number of short procedures u s e f u l f o r parameter p r o c e s s i n g , most of which are passed a p o i n t e r to the parameter to operate on. PrmRead ensures that the parameter i s a measured one ( i f measure i s n i l , the ErrMessg procedure ErrorNoted i s c a l l e d , h a l t i n g MicroSput 28 e x e c u t i o n ) . A c a l l to the E12Sched procedure WaitAnalog i s not ret u r n e d from u n t i l the analog input channel has been read and observed to have d r i f t e d . The El2AnaI0 procedure AnaRead i s then used to determine the input value as w e l l as i t s f i r s t d e r i v a t i v e with respect to time. The value i s s c a l e d , and PrmAnaSet i s c a l l e d to mark the new d r i f t requirements. PrmAnaSet s p e c i f i e s the value to d r i f t from to be the s e t p o i n t , f o r c o n t r o l l e d parameters, or the l a t e s t r eading, f o r non c o n t r o l l e d parameters. The amount of d r i f t i s e i t h e r j u s t below the r e s o l u t i o n of the l e a s t s i g n i f i c a n t d i s p l a y d i g i t , i f the parameter value i s s t a b l e , or zero, i f the parameter value has p r e v i o u s l y been changing or out of bounds. I t i s necessary to r e t u r n from WaitAnalog once when the parameter value f i r s t s e t t l e s i n t o i t s s p e c i f i e d range i n order that the screen d i s p l a y e d value be c o r r e c t during the coming d r i f t wait. The d r i f t p o s i t i o n and a l l o w a b l e e r r o r are communicated to the analog input i n t e r r u p t s e r v i c e r o u t i n e v i a the El2AnaI0 procedure AnaSetBound. The l a t t e r a l s o s p e c i f i e s the minimum change in time that must have passed before the i n t e r r u p t s e r v i c e r o u t i n e can approximate the r a t e of change of the input value using the change in value d i v i d e d by the change in time. T h i s minimum i n t e r v a l i s taken to be e i t h e r one q u a r t e r of the minimum wait time between parameter s e r v i c e s , or one h a l f second, whichever i s s m a l l e r . Processes s e r v i c i n g the c o n t r o l l e d parameters can c a l c u l a t e the next d e s i r e d increment in the parameter value by a c a l l to the Parameter f u n c t i o n Prmlncrm. Li k e PrmRead, Prmlncrm notes an e r r o r and h a l t s MicroSput i f the parameter has no c o n t r o l 29 i n f o r m a t i o n r e c o r d . If c o n t r o l has not been i n i t i a l i z e d (by operator s p e c i f i c a t i o n of a s e t p o i n t ) or i f the operator has d i s a b l e d c o n t r o l ( i n the parameter e d i t i n t e r a c t i o n mode), Prmlncrm w i l l r e t u r n with an increment of zero. I f the value i s above the upper l i m i t or below zero, the negative of that e r r o r w i l l be r e t u r n e d . Otherwise, the increment w i l l be c a l c u l a t e d as the d i f f e r e n c e between the s e t p o i n t and the value, minus the d e r i v a t i v e feedback loop gain times the rate of change of the v a l u e . The l a t t e r increment, when added i n t o an ongoing c o n t r o l s i g n a l , p r o v i d e s f i r s t order p r o p o r t i o n a l i n t e g r a l (PI) c o n t r o l , in the l i m i t of zero elapsed time between s e r v i c e s . However, no matter which method i s used to f i n d the c o n t r o l increment, the l a t t e r . i s l i m i t e d i n a b s o l u t e value so as to ensure a parameter value skew r a t e of no g r e a t e r than that s p e c i f i e d by the o p e r a t o r . The d e r i v a t i v e feedback gain i s chosen such that the skew r a t e l i m i t w i l l , i n p r a c t i c e , only take e f f e c t when the parameter value i s more than 10% of f u l l s c a l e d i f f e r e n t from the s e t p o i n t . Newly measured or c a l c u l a t e d values can be d i s p l a y e d on the VDT screen by c a l l i n g the Parameter procedure PrmShow. For three completely independent reasons, a procedure c a l l e d by a parameter s e r v i c e process cannot d i r e c t l y w r ite the value to the screen, but must i n s t e a d pass the value to a screen updating p r o c e s s . One problem i s that the p-System write statement r e q u i r e s a l a r g e amount of stack space (about 250 words) to do the c o n v e r s i o n of the r e a l number to ASCII c h a r a c t e r s , then send i t over a s e r i a l l i n e to the VDT. To i n c r e a s e the stack s i z e s of perhaps a dozen parameter s e r v i c e processes would use up 30 about s i x k i l o b y t e s of RAM. A second problem with w r i t i n g to the screen by parameter s e r v i c i n g processes i s added execution time: the mentioned ASCII c o n v e r s i o n and s e r i a l l i n e t r a n s m i s s i o n r e q u i r e a s u b s t a n t i a l amount of cpu time, yet need not n e c e s s a r i l y be done with as high a p r i o r i t y as parameter measurement and c o n t r o l . The f i n a l problem i s that values should a c t u a l l y only be w r i t t e n when one of many p o s s i b l e background VDT screen images i s a c t i v e , and c o n v e r s e l y must be w r i t t e n as soon as that image i s reloaded, even though the parameter may be s t a b l e and thus not s e r v i c e d immediately. PrmShow t h e r e f o r e d i s p l a y s the parameter value by c a l l i n g the ScrnBuff procedure sbTossReal, which s i g n a l s a separate process to do the a c t u a l w r i t i n g only when a new value i s r e c e i v e d and the parameter d i s p l a y screen image i s a c t i v e or when that image i s r eloaded. The value i s a l s o compared to the parameter's upper l i m i t ; i f g r e a t e r , the boolean warning i s set and the Parameter process ParamWarn i s s i g n a l l e d . If the parameter's boolean value beep has been set by the o p e r a t o r , the VDT i s beeped: t h i s f e a t u r e allows the operator to a u d i b l y determine the a c t u a l frequency of s e r v i c i n g of the parameter. The c l o c k i s then checked, and whatever time d i f f e r e n c e remains between the s p e c i f i e d s e r v i c e delay and the time elapsed executing PrmShow so f a r (a task switch may have occ u r r e d using up some of the delay) i s waited out with a c a l l to the Schedule procedure W a i t T i c k . The remaining Parameter g l o b a l r o u t i n e s are PrmPoint, PrmList, and PrmEdited. PrmPoint updates a c o n t r o l l e d parameter's s e t p o i n t with the given number, sends i t to the 31 parameter d i s p l a y screen ( i n the same manner as the value i s w r i t t e n ) , and, f o r measured parameters, c a l l s PrmAnaSet to note the change in s e t p o i n t from which to d r i f t . PrmList r e t u r n s the p o i n t e r to the l i n k e d l i s t of parameter i n f o r m a t i o n r e c o r d s . The use of a f u n c t i o n to r e t u r n the value of t h i s p o i n t e r , r a t h e r than simply d e c l a r i n g the p o i n t e r v a r i a b l e as g l o b a l , ensures i t cannot be a l t e r e d by e x t e r n a l u n i t s . PrmEdited notes that one or more parameter i n f o r m a t i o n records has been e d i t e d , and t h e r e f o r e enables PrmPut at the end of the MicroSput run. Two processes are i n c l u d e d i n the u n i t Parameter. ShowTime i s very s h o r t . While MicroSput runs, i t simply loops, a l t e r n a t e l y w a i t i n g one second by c a l l i n g the Schedule procedure WaitTick, and s i g n a l l i n g the VDT screen updating process to d i s p l a y the time, by c a l l i n g the ScrnBuff procedure sbTossNow. ParamWarn i s somewhat longer, and i n f a c t i s d e c l a r e d as a code segment, s i n c e i t i s not expected to be needed very o f t e n . While MicroSput i s running, and i f an upper l i m i t e r r o r has been s i g n a l l e d , ParamWarn loops, f l a s h i n g to the VDT screen ( v i a ScrnBuff procedure s b T o s s S t r i n g ) a message naming the parameter and warning of the e r r o r . The name of the parameter i n e r r o r i s found by c y c l i n g through the parameter l i s t l o o k i n g f o r a parameter with the boolean warning s e t . T h i s search method i n s u r e s that i f more than one l i m i t e r r o r occurs at a given time, the problematic parameter names w i l l be f l a s h e d a l t e r n a t e l y . ParamWarn waits f o r another upper l i m i t e r r o r s i g n a l when the complete l i s t has been c y c l e d through without f i n d i n g a true warning. 32 The MicroSput c o m p i l a t i o n u n i t ParamUtil c o n t a i n s three r o u t i n e s u s e f u l f o r operator i n t e r a c t i o n . The f u n c t i o n PrmNamed searches the parameter l i s t f o r a parameter with the given name; l i k e a l l MicroSput name o p e r a t i o n s , PrmNamed i s case independent. I f found, a p o i n t e r to that parameter's i n f o r m a t i o n record i s returned, otherwise the n i l p o i n t e r i s giv e n . The f u n c t i o n PrmPrmpt composes a prompt l i n e s t r i n g from the given t i t l e (e.g. ' S e t p o i n t : ' ) , the parameter s i n g l e c h a r a c t e r commands and names (e.g. *V(oltage I ( c u r r e n t A(rgon'), and the t r a i l e r ' [ e s c ] ' . If the boolean must_meas i s s e t , then only those parameters whose values are read from the analog inputs are i n c l u d e d i n the prompt; s i m i l a r l y i f the boolean m u s t _ c t r l i s s e t , then only those parameters which are capable of being c o n t r o l l e d are i n c l u d e d . The prompt l i n e i s r e b u i l t every time PrmPrmpt i s c a l l e d , so as to not waste memory space saving i t and to allow the operator to change the parameter name or s i n g l e c h a r a c t e r command while i n the parameter e d i t i n t e r a c t i o n mode. The time needed to b u i l d the prompt l i n e i s co n s i d e r e d to be unimportant s i n c e most operator i n t e r a c t i o n time i s expected to pass w a i t i n g f o r the operator to respond. A f t e r each parameter name i s added to the prompt l i n e , the system s t a t e i s p o l l e d and execution of higher p r i o r i t y t asks i s allowed by a c a l l to the Schedule procedure P o l l l n p u t s . When the prompt l i n e i s ready, a c a l l i s made to the ReadKybd procedure PromptCapIn, which prompts the operator by w r i t i n g the new s t r i n g at the s p e c i f i e d VDT screen p o s i t i o n . If the s t r i n g i s too long to f i t a c r o s s the screen, PromptCapIn w i l l break i t up i n t o p o r t i o n s which can be c y c l i c a l l y viewed by t y p i n g '?'. 33 PromptCapIn i s not returned from u n t i l one of the s p e c i f i e d c h a r a c t e r s ( i n t h i s case, a parameter s i n g l e c h a r a c t e r command or the escape key) i s typed ( i n upper or lower c a s e ) . If the escape key was the operator response, PrmPrmpt re t u r n s the n i l p o i n t e r . Otherwise, the parameter l i s t i s scanned and a p o i n t e r to the parameter inf o r m a t i o n r e c o r d c o n t a i n i n g the response i s returned. One example of the use of PrmPrmpt i s the ParamUtil f u n c t i o n PrmEdSet. The l a t t e r c a l l s PrmPrompt; i f the r e s u l t i s not n i l , the ReadKybd procedure FetchReal c l e a r s the s p e c i f i e d s e t p o i n t value from the screen and reads i n a new number, a c c e p t i n g i t only i f i t i s between zero and the upper l i m i t . The Parameter procedure PrmPoint i s then c a l l e d to begin p r o c e s s i n g with t h i s new s e t p o i n t . PrmEdSet r e t u r n s with the PrmPrompt r e s u l t . The c o m p i l a t i o n u n i t ParamEdit c o n t a i n s only one g l o b a l procedure, PrmEdit (which t h e r e f o r e a c t s as a code segment). T h i s procedure performs i n t e r a c t i v e e d i t i n g of the parameter, analog, and c o n t r o l i n f o r m a t i o n r e c o r d s . PrmEdit i s the l a r g e s t example of menial programming which needs to be done only once when using the g e n e r a l i z e d parameter programming method d i s c u s s e d at the beginning of t h i s chapter. The main concerns of the procedure are to pro v i d e a f a s t , user f r i e n d l y method of e d i t i n g and to ensure a l l operator inputs are v a l i d . PrmEdit begins execution by l o a d i n g the e d i t i n g background VDT screen image, 'prmedit' (see F i g . 4 ) . T h i s image c o n s i s t s of a name or s t r i n g d e s c r i b i n g each of the e d i t a b l e parameter f i e l d s , and a blank area i n which data from each f i e l d can be N(ame U ( n i t s I(d L ( i m i t D(ecimals W(ait B(eep C(hannel i n F ( u l l s c a l e S(lew rate E(nable Parameter Constants name: u n i t s : i d upper l i m i t : decimal f i e l d minimum wait between s e r v i c e s (seconds) beep console each s e r v i c e : Measurement Constants analog input channel: f u l l s c a l e ( 1 0 V ) v a l u e : C o n t r o l Constants maximum slew r a t e : % f u l l s c a l e c o n t r o l enabled: Figure 4 . Parameter e d i t i n g screen image 'prmedit'. 3 5 w r i t t e n . L i k e a l l MicroSput procedures using background VDT screen images with data f i e l d s , PrmEdit keeps the f i e l d c o o r d i n a t e s i n a t a b l e of con s t a n t s at the top of the procedure source f i l e so that changes i n the screen image can be made without s e a r c h i n g through the f i l e f o r c o o r d i n a t e r e f e r e n c e s . A parameter i s prompted f o r by a c a l l to the ParamUtil procedure PrmPrmpt. The data f i e l d s from the chosen parameter are then w r i t t e n to the screen by v a r i o u s c a l l s to WritCons procedures. Some of the data must be converted to be presented i n a user f r i e n d l y form. For example, the analog input s c a l i n g f a c t o r i s m u l t i p l i e d by the f u l l s c a l e analog input reading of 10,000 and presented as the parameter's f u l l s c a l e v a l u e , which i s presumed to be of more immediate use to the operator. If the parameter value i s not measured from an analog input or i s not c o n t r o l l e d , blanks w i l l be sent to the measurement and/or c o n t r o l data f i e l d s to erase any pre v i o u s parameter f i e l d e n t r i e s . A prompt l i n e and command c h a r a r a c t e r match set are c o n s t r u c t e d of commands ac c o r d i n g to whether or not the parameter value i s measured and/or c o n t r o l l e d . The ReadKybd procedure PromptCapIn i s used to determine the op e r a t o r ' s c h o i c e of data f i e l d to change. If a data f i e l d i s chosen, rather than immediately e x i t i n g the e d i t , the Parameter procedure PrmEdited i s c a l l e d which enables the Parameter h a l t i n g code to save the e d i t e d records upon MicroSput t e r m i n a t i o n . A l l data are read in by c a l l s to v a r i o u s ReadKybd procedures which blank out the screen image data f i e l d before a c c e p t i n g new va l u e s . New parameter names and s i n g l e c h a r a c t e r commands are checked f o r c o n f l i c t s •with those a l r e a d y i n use. If the f i r s t c h a r a c t e r of a new name 36 i s not a l r e a d y another parameter's command key, i t i s c o n s c r i p t e d f o r use with the newly named parameter. Changes to the f u l l s c a l e input or number of decimals to d i s p l a y a u t o m a t i c a l l y change the measurement maximum accept a b l e d r i f t e r r o r such that a l l a c c e p t a b l e d r i f t w i l l be below the r e s o l u t i o n of the l e a s t s i g n i f i c a n t d i g i t d i s p l a y e d . Any changes which might a l t e r the a c t u a l delay parameter s e r v i c e s set the beep boolean so that the operator w i l l be aware of the e f f e c t . Parameter f i e l d e d i t i n g continues u n t i l the operator types 'Q' to q u i t , upon which another e d i t parameter i s prompted f o r . The formerly a c t i v e screen image i s reloaded and PrmEdit returned from when the operator presses the escape key i n s t e a d of a parameter s e l e c t i o n . The g e n e r a l i z e d parameter subprogram l e v e l module Walker i n t e r a c t i v e l y steps, or 'walks', a parameter s e t p o i n t across a given range at a given r a t e . The u n i t i n i t i a l i z a t i o n code i n i t i a l i z e s the walking parameter p o i n t e r to n i l , motion to be stopped, and a r b i t r a r i l y chooses the d e f a u l t scan time to be t h i r t y minutes. The S t a r t e r procedure S t r t l n f o i s c a l l e d to determine stack s i z e and p r i o r i t y , and the process WalkSetp i s s t a r t e d . The l a t t e r waits f o r a s i g n a l from the operator i n t e r a c t i o n segment procedure PrmWalk. A c a l l to PrmWalk causes the parameter walk i n t e r a c t i o n mode screen image 'walkset' to be loaded (see F i g . 5 ) . The screen image data f i e l d s are w r i t t e n and the operator i s prompted f o r a command. Any command except 'E' ( e x i t ) w i l l d i s a b l e the walking process WalkSetp. The parameter to walk, s e t p o i n t range bounds, and time r e q u i r e d to cover the range can Walk: P(arameter L(ow H(igh T(ime U(p D(own S(top E ( x i t @ walk parameter: range: <= s e t p o i n t <= cover range in minutes s e t p o i n t motion i s Figure 5 . Parameter walking screen image 'walkset'. 1^ 38 a l l be e d i t e d . Walking can be d i r e c t e d towards i n c r e a s i n g or de c r e a s i n g s e t p o i n t , s t a r t i n g at the present s e t p o i n t value, or can be remain d i s a b l e d . Upon r e c i e v i n g the e x i t command, i f walking i s enabled, the walking step s i z e i s chosen to be the r e s o l u t i o n of the l e a s t s i g n i f i c a n t d i g i t on the parameter s e t p o i n t (and value) d i s p l a y , and the process delay time r e q u i r e d to cover the s p e c i f i e d range with that step s i z e i s c a l c u l a t e d . The p r e v i o u s l y a c t i v e screen image i s reloaded, and PrmWalk i s returned from. The process WalkSetp i n i t i a l l y waits f o r a s i g n a l to begin walking. Upon r e c i e v i n g that s i g n a l , and while MicroSput c o n t i n u e s execution, WalkSetp loops as f o l l o w s : the process d e l a y time i s waited v i a a c a l l to the Schedule procedure WaitTick; while w a i t i n g i s enabled and the s e t p o i n t has not reached the end of i t s walk, the walking process executes an inner loop; and the s i g n a l to r e s t a r t i s waited f o r . The inner loop c o n s i s t s o f : read the system c l o c k and c a l c u l a t e the elap s e d time s i n c e l a s t s e r v i c e (higher p r i o r i t y processes may have delayed WalkSetp longer than r e q u i r e d ) ; c a l c u l a t e the new s e t p o i n t based on the a c t u a l elapsed time by a c a l l to the Parameter procedure PrmPoint; and wait out the process delay time, again c a l l i n g W a i t T i c k . When MicroSput execution i s h a l t e d , the WalkSetp process w i l l probably be w a i t i n g on i t s s i g n a l to begin or to r e s t a r t , s i n c e the operator i s most l i k e l y to complete or d i s a b l e a parameter walk before t e r m i n a t i n g the run. U n f o r t u n a t e l y , the UCSD p-System has been designed so that a l l of a c o m p i l a t i o n u n i t ' s processes must complete t h e i r execution before the u n i t ' s 39 h a l t i n g code w i l l be executed. T h i s means that a g l o b a l boolean v a r i a b l e s p e c i f y i n g that MicroSput i s running r a t h e r than t e r m i n a t i n g i t s run must be checked before each semaphore wait, and a l l system semaphores must be s i g n a l l e d a f t e r the running boolean i s r e s e t but before a c t u a l program t e r m i n a t i o n . The MicroSput u n i t Schedule d e c l a r e s a g l o b a l running v a r i a b l e for t h i s purpose. Most u n i t s using i n t e r n a l semaphores, i n c l u d i n g Walker, supply a h a l t i n g procedure to s i g n a l the semaphores at the program's end. The procedure wkHalt i s provided f o r t h i s reason. As mentioned at the beginning of t h i s chapter, a method f o r adding to and a l t e r i n g the l i s t of MicroSput parameters and t h e i r i n f o r m a t i o n records i s needed. If one simply wants to add to the parameter l i s t , one need only e d i t Sputter and wr i t e the s e r v i c i n g p r o c e s s . If i t i s d e s i r e d to s t a r t the process using S t r t l n f o (as i s normally the c a s e ) , one must a l s o e d i t that u n i t to i n c l u d e the process name, stack s i z e and p r i o r i t y . To add the new parameter i n f o r m a t i o n r e c o r d to the f i l e uti1:system.param, execute the f i l e u t i l : p a t c h p a r a m . T h i s program al l o w s the operator to c r e a t e or destroy i n f o r m a t i o n r e c o r d e n t r i e s and, f o r each e x i s t i n g f i l e e n t r y , to change the programmed name, whether or not the parameter i s measured, and whether or not i t i s to be c o n t r o l l e d . If the a c t u a l s t r u c t u r e of a parameter i n f o r m a t i o n record i s to be changed, then the f i l e uti1:fmtparam w i l l be of use. T h i s program i s e d i t e d once the new record s t r u c t u r e i s known. It reads the data from the o l d f i l e util:system.param, reformats i t a c c o r d i n g to the new s t r u c t u r e provided by the programmer, and w r i t e s the new data to the f i l e utilrnewsystem.param. The system f i l e r can be used to change the o l d records to a backup f i l e , e.g. util:oldsystem.param and the new records to util:system.param. One must be sure not to remove the o l d records f i l e u n t i l the e d i t e d system i s working p r o p e r l y . Of course, i f the parameter i n f o r m a t i o n r e c o r d s t r u c t u r e i s changed, then a l l parameter l e v e l and higher u n i t s must be e d i t e d to i n c o r p o r a t e the changes, recompiled, and returned i n t h e i r new form to the MicroSput f i l e , microsput.code. The l a t t e r can be done by executing the f i l e u t i l : l i b r a r y . c o d e , the c o d e f i l e l i b r a r i a n s u p p l i e d as p a r t of the UCSD p-System. 41 CHAPTER FIVE Data F i l i n g and P l o t t i n g The only type of data MicroSput i s c u r r e n t l y capable of f i l i n g and d i s p l a y i n g are the elapsed time ( i n seconds) and one or more of the parameter v a l u e s . Development v e r s i o n s of MicroSput had i n c l u d e d a user e d i t a b l e c o m p i l a t i o n u n i t Cruncher, i n which the operator c o u l d write h i s own l i s t of f u n c t i o n s of the parameter values and elapsed time. T h i s u n i t was l i n k e d i n t o MicroSput, and i t s f u n c t i o n s were made a v a i l a b l e to the operator as p o s s i b l e axes c h o i c e s f o r the x-y p l o t . T h i s idea proved to be a very u s e f u l extension of the on l i n e data a n a l y s i s c a p a b i l i t i e s of MicroSput. Perhaps somewhat i n e v i t a b l y , though, the p r o v i s i o n of Cruncher to simply s e l e c t two axes f u n c t i o n s was soon found to be not enough to s a t i s f y the e d i t i n g needs of every experiment. There was o f t e n a need to p r i n t records of some or a l l of the parameter v a l u e s , to i n c l u d e one or more i n t e r a c t i v e l y chosen c o n s t a n t s i n the axes f u n c t i o n c a l c u l a t i o n s , or to i n v e r t or take the l o g a r i t h m of an e x i s t i n g a x i s f u n c t i o n without w r i t i n g a whole new f u n c t i o n . These and other needs g e n e r a l l y c o u l d be met only by c o r r u p t i n g the o r i g i n a l l y s t r a i g h t forward Cruncher r o u t i n e s to the poi n t where they were much more complex and non standard than those in the 'hidden' f i l i n g and p l o t t i n g u n i t s . The v e r s i o n of MicroSput now i n use does not i n c l u d e a Cruncher module. Data a n a l y s i s , other than the p l o t t i n g of parameter values and e l a p s e d time, must be done by user w r i t t e n programs a f t e r the 42 MicroSput experiment i s complete. I t i s hoped that t h i s documentation w i l l be s u f f i c i e n t f o r the user to e d i t the data f i l i n g and p l o t t i n g r o u t i n e s themselves, and t h e r e f o r e w i l l e v e n t u a l l y be able to more f u l l y perform on l i n e data a n a l y s i s than with the former MicroSput programs. I t i s a l s o hoped that in the longer term a t r u l y on l i n e data manipulation method w i l l be developed. Expansion of MicroSput to i n c l u d e data l o g g i n g and a n a l y s i s from d e v i c e s which do not f i t r e a d i l y i n t o the g e n e r a l i z e d parameter concept (such as the use of a mass or o p t i c a l spectrometer f o r purposes other than determining the i n t e n s i t y of j u s t a few s p e c t r a l l i n e s ) a l s o w i l l present problems. One may attempt to handle the new equipment data independently of the parameter value data. If so, one'should be aware that a standard e i g h t inch floppy d i s k r e q u i r e s up to three q u a r t e r s second to skew from one f i l e to another; no MicroSput p r o c e s s i n g can be done during t h i s wait. A l s o , the p-System method of a l l o c a t i n g d i s k space when more than one f i l e i s open f o r w r i t i n g on one d i s k tends to e v e n t u a l l y d i v i d e the a v a i l a b l e d i s k space up i n t o many small areas, hence r a p i d l y d e c r e a s i n g the maximum data f i l e s i z e ( t h i s problem does not occur when only one w r i t e f i l e per d i s k i s open at any i n s t a n t ) . Perhaps a new d i s k d r i v e w i l l be added with every new MicroSput d e v i c e . The p-System l i m i t i s s i x d r i v e s . One may be able to e f f i c i e n t l y s t o r e a l l the new f i l e s on a l a r g e , f a s t hard d i s k . In any case, a method of c o r r e l a t i n g the data from the v a r i o u s f i l e s w i l l probably be needed. Perhaps the elapsed time would be saved i n a l l f i l e s , and a method of i n t e r p o l a t i n g data from 43 some of the f i l e s to match up with that from the others would be w r i t t e n . A completely d i f f e r e n t approach would be to r e w r i t e the data saving and p l o t t i n g p o r t i o n s of MicroSput so that a s i n g l e data f i l e would handle a l l types. T h i s approach was attempted (the r e s u l t i s the u n i t DataLog) but unused. Each process wishing to use the DataLog f i l e f i r s t wrote a record type i d e n t i f y i n g name in the f i l e ; the rec o r d type was then a s s i g n e d a one byte keyword. Data was w r i t t e n as a rec o r d which i n c l u d e d the keyword, a one byte r e c o r d s i z e , and f i n a l l y the a c t u a l data ( s i z e words of i t ) . The rec o r d types were s o r t e d out when reading the f i l e a c c o r d i n g to the keyword and a s s o c i a t e d name i d e n t i f i e r . Although t e s t i n g of the DataLog module proved i t s e f f e c t i v e n e s s i n s o f a r as speed and data compatabi1ity are concerned, the u n i t was c o n s i d e r e d to be too bulky and complicated for the c u r r e n t MicroSput v e r s i o n , c o n s i d e r i n g no non-standard equipment i s supported by i t . No c o n s i d e r a t i o n has yet been given to the problem of d i s p l a y i n g non-standard data. The u n i t ParamSave handles MicroSput data f i l i n g . A l l data f i l e s have the s u f f i x '.PDAT' to d i s t i n g u i s h them as parameter data. The PDAT f i l e s t r u c t u r e i s headed by a l i s t of saved parameter names ( i . e . of type s t r i n g [ 8 ] ) ended by the empty name (''), followed by the data i n t e g r a t i o n time i n seconds (type r e a l ) , and f i n a l l y the data r e c o r d s . A PDAT data record i s a l i s t of r e a l values c o n s i s t i n g of the elapsed time followed by the value of each named parameter. The ad v i s e d method of reading and w r i t i n g a PDAT f i l e i s to d e c l a r e a f i l e of r e a l s , get or put the name l i s t v i a an a r r a y [ l . . 3 ] of r e a l typed b u f f e r 44 using the p-System i n t r i n s i c moveleft, get or put the i n t e g r a t i o n time, and get or put each l i s t e d parameter read_data or value once per data r e c o r d read or w r i t e . The maximum number of v a l i d bytes per name i s nine (one le n g t h , e i g h t c h a r a c t e r s ) , l e a v i n g three or more unused i n each r e a l a rray b u f f e r . W r i t i n g these t r a i l i n g c h a r a c t e r s as the ASCII space i s recommended i f the f i l e i s ever to be viewed using the p-System program Patch. I f a PDAT f i l e i s t r e a t e d as a f i l e of r e a l s , the f i l e boolean i n t r i n s i c eof (end of f i l e ) w i l l become true when the l a s t r e c o r d has been read. If a detected f a t a l e r r o r occurs d u r i n g a MicroSput run, any e x i s t i n g w r i t e f i l e w i l l be s a f e l y c l o s e d by the ParamSave h a l t i n g code. However, in some i n s t a n c e s (such as a power f a i l u r e ) the e r r o r w i l l not be dete c t e d and the write f i l e i n f o r m a t i o n w i l l not be entered i n the disk d i r e c t o r y . Should t h i s misfortune occur, most of the data w i l l be r e t r i e v e d i f the f o l l o w i n g recovery method i s e x a c t l y f o l l o w e d . Reboot the p-System and enter the system f i l e r . Do not perform any commands which may wr i t e to the d i s k (other than i t s d i r e c t o r y ) or move f i l e s about. Use the f i l e r 'make' command to c r e a t e a PDAT f i l e without s p e c i f y i n g i t s l e n g t h . T h i s w i l l c r e a t e a d i r e c t o r y entry f o r a f i l e i n the l a r g e s t empty disk space, the same space where the l o s t f i l e l i e s . E x i t the f i l e r . If d e s i r e d , the p-System program Patch can now be used to confirm the f i l e e x i s t a n c e by viewing the new f i l e ' s block zero (using the mixed ASCII/hex mode). The parameter name l i s t should c l e a r l y appear at the beginning of the block. No f u r t h e r ASCII data was w r i t t e n to the f i l e ; viewing each block s u c c e s s i v e l y , 45 one can determine the maximum p o s s i b l e extent of the f i l e by not i n g the f i r s t block i n which s e n s i b l e s t r i n g s appear. T h i s w i l l , however, not n e c e s s a r i l y be the a c t u a l l a s t block of the f i l e as non-ASCII data may have been p r e v i o u s l y w r i t t e n to the d i s k . I f Patch i s used to f i n d the maximum p o s s i b l e f i l e l e n g t h , the system f i l e r remove and make commands can be used to remake the f i l e , s p e c i f y i n g the new l e n g t h . Run MicroSput, and p l o t some data from the f i l e , c o u n t i n g the disk d r i v e c l i c k s e i t h e r before or a f t e r i t i s evident that garbage i s being p l o t t e d . The d r i v e c l i c k s once per f i l e block, so the counted c l i c k s w i l l betray the a c t u a l l e n g t h of the f i l e . Use the system f i l e r remove and make commands to c o r r e c t the f i l e l e n g t h . U n f o r t u n a t e l y , a l l data i n the f i l e ' s u n f i l l e d block b u f f e r when the system crashed w i l l not have been p h y s i c a l l y w r i t t e n to the disk and i s i r r e t r i e v a b l e . T h i s w i l l amount to at most 128 r e a l numbers, or i n the case of only one parameter being saved ( p l u s , as always, time'), 64 data r e c o r d s . The u n i t ParamSave d e c l a r e s one g l o b a l r e a l v a r i a b l e , param_time, and four g l o b a l r o u t i n e s , f u n c t i o n ParamGet and procedures ParamReset, ParamFile, and p f H a l t . The v a r i a b l e param_time i s the l a t e s t elapsed time read from the data read f i l e . ParamFile i n t e r a c t i v e l y opens and c l o s e s read and write f i l e s , s e l e c t s the wr i t e f i l e parameters, i n t e g r a t i o n time, and s i n g l e or m u l t i p l e r e c o r d s a v i n g . In the l a t t e r mode, the p e r i o d i c i t y of record saving can a l s o be s e t . Write f i l e data saving can be i n t e r a c t i v e l y d i s a b l e d and enabled. ParamReset reads the read f i l e header, determining the read f i l e parameter l i s t and d i s p l a y i n g the read data i n t e g r a t i o n time. ParamGet i s 46 c a l l e d to read one data r e c o r d i n t o the read f i l e parameters' read_data v a r i a b l e s , but re t u r n s f a l s e i f an end of f i l e has been encountered. The procedure p f H a l t , l i k e wkHalt, s i g n a l s a l l i n t e r n a l semaphores once and must be c a l l e d at the program end, a f t e r the g l o b a l Schedule boolean v a r i a b l e running has been r e s e t . The procedure ParamFile r e p e a t e d l y loops,.prompting the operator with a s t r i n g which informs him of the c u r r e n t write f i l e e n a b l e / d i s a b l e s t a t u s and s i n g l e or m u l t i p l e r e c o r d save mode. The command c h o i c e s are a l s o presented as 'S(tatus L(ogging F ( i l e s E ( x i t ' . Typing 'S' tog g l e s the wr i t e data e n a b l e / d i s a b l e s t a t u s , 'L' tog g l e s the s i n g l e / m u l t i p l e record save mode, 'F' produces a c a l l to the segment procedure PrmFile, and 'E' e x i t s the ParamFile loop. T o g g l i n g from m u l t i p l e to s i n g l e r e c o r d saving a u t o m a t i c a l l y -enables the data w r i t i n g process f o r one rec o r d , a f t e r which i t w i l l be d i s a b l e d . F u r t h e r s i n g l e records can be w r i t t e n by e n a b l i n g data w r i t i n g each time ( i t w i l l a u t o m a t i c a l l y be d i s a b l e d a f t e r each record i s saved). The segment procedure PrmFile i n t e r a c t i v e l y chooses the data read and write f i l e names, s e l e c t s the parameters f o r w r i t i n g , data i n t e g r a t i o n time, and data save c y c l e time. R e l a t i v e to RAM and simple input/output port o p e r a t i o n s , d i s k o p e r a t i o n s o f t e n take a l a r g e amount of cpu time, most of which c o n s i s t s of wa i t i n g f o r the d i s k to revolve or the head to skew between t r a c k s . Opening and c l o s i n g of d i s k f i l e s , e s p e c i a l l y when performing checking o p e r a t i o n s to ensure no data f i l e s are i n a d v e r t a n t l y removed, i s thus a slow o p e r a t i o n . In order that 47 execution of important c o n t r o l processes i s not o v e r l y a f f e c t e d by PrmFile o p e r a t i o n s , c a l l s of the l o c a l procedure TaskSwitch are s p r i n k l e d throughout PrmFile, i n c l u d i n g one c a l l a f t e r every d i s k o p e r a t i o n . TaskSwitch c a l l s the Schedule procedure P o l l l n p u t s , which i s not returned from u n t i l a l l higher p r i o r i t y p r o c e s s i n g i s done. The l o c a l procedure CheckError i s then c a l l e d . T h i s procedure i s r e q u i r e d a f t e r every r o u t i n e c a l l which might execute a s i g n a l or wait (and t h e r e f o r e allow other processes to run): the ErrMessg f u n c t i o n ErrorNoted i s checked to determine i f a f a t a l e r r o r has been de t e c t e d ; i f so, the o r i g i n a l ParamFile c a l l i s immediately e x i t e d . The PrmFile TaskSwitch and CheckError c a l l s w i l l not be i n d i v i d u a l l y mentioned i n the f o l l o w i n g d i s c u s s i o n . The f i r s t job of the PrmFile procedure i s to wr i t e the background VDT screen image 'paramsav' to the screen (see F i g . 6 ) . The names of any open f i l e s , i n t e g r a t i o n and c y c l e times, and parameter read and w r i t e l i s t s are sent to t h e i r r e s p e c t i v e screen image data areas. The operator i s asked to choose between read f i l e or write f i l e i n t e r a c t i o n , or to escape from f u r t h e r PrmFile o p e r a t i o n s . In e i t h e r f i l e i n t e r a c t i o n case, the ensuing s e r i e s of q u e s t i o n s and answers depends on the cu r r e n t s t a t e of the f i l e s and the operator s u p p l i e d responses. If a f i l e i s open a l r e a d y , the a check i s made to ensure the operator wishes i t c l o s e d . Once a f i l e has been c l o s e d , a new f i l e name i s prompted f o r . P r e s s i n g the r e t u r n key i n l i e u of a f i l e name e x i t s the read or wr i t e f i l e i n t e r a c t i o n with the r e s p e c t i v e f i l e remaining c l o s e d . I f a new w r i t e f i l e i s s p e c i f i e d with the same name as an e x i s t i n g f i l e on the d i s k , F i l e s t a t u s : W (rite R(ead <esc> Write F i l e s t a t u s : P(arameter l i s t C ( y c l e time I ( n t e g r a t e time Q ( u i t @ write parameters read parameters Write f i l e i n formation name: save c y c l e time: seconds i n t e g r a t i o n time: seconds Read f i l e information name: i n t e g r a t i o n time: seconds Fig u r e 6. Parameter f i l i n g screen image 'paramsav'. 49 the operator must v e r i f y that i t i s to be destroyed. S p e c i f y i n g a n o n s e n s i c a l write f i l e name can cause a det e c t e d f a t a l e r r o r , a problem which might be worth c o r r e c t i n g i n the near f u t u r e . S p e c i f i c a t i o n of a nonexistant read f i l e has the same r e s u l t as p r e s s i n g the return key on l y . Supplying the same read f i l e name as that of an open w r i t e f i l e r e s u l t s i n the l a t t e r being read by the former, without i n t e r r u p t i n g the data w r i t e process. In e i t h e r case, the read f i l e ' s parameter l i s t and data i n t e g r a t i o n time are read from the d i s k and d i s p l a y e d . In the wr i t e f i l e i n t e r a c t i o n case, the l o c a l procedure EditWStatus i s c a l l e d to set up the w r i t e f i l e i n f o r m a t i o n . The operator i s repea t e d l y prompted to s e l e c t the wr i t e parameter l i s t , i n t e g r a t i o n time, m u l t i p l e r e c o r d save c y c l e time, or to q u i t EditWStatus. In the two time s e l e c t i o n cases, the operator i s simply r e q u i r e d to enter the new time, i n seconds. Only i n t e g r a t i o n times between zero seconds and the c y c l e time w i l l be accepted; only c y c l e times between the i n t e g r a t i o n time and 546 seconds w i l l be accepted (the l a t t e r l i m i t i s to a v o i d i n t e g e r overflow when the c y c l e time i s stored as a signed i n t e g e r of one s i x t i e t h second r e s o l u t i o n ) . In the wr i t e parameter l i s t s e l e c t i o n , repeated c a l l s to the Parameter procedure PrmPrmpt r e t u r n with a p o i n t e r to the operator s e l e c t e d parameter, or n i l i f the escape key was pressed. If the po i n t e d to parameter i s not al r e a d y in the l i s t , i t i s i n c o r p o r a t e d i n ; i f i t i s al r e a d y in the l i s t , i t i s removed. Each change i n the parameter l i s t i s recorded on the screen. The n i l p o i n t e r f l a g s the end of wr i t e parameter l i s t e d i t i n g . The outer EditWStatus loop c o n t i n u e s u n t i l the operator types the q u i t command. I f , at t h i s p o i n t , the write 50 parameter l i s t i s empty, the data w r i t i n g i s aborted and f i l e c l o s e d . Otherwise, the new parameter l i s t and i n t e g r a t i o n time are w r i t t e n to the new w r i t e f i l e and the data saving process i s s i g n a l l e d that a new f i l e i s ready. The data saving process does not a c t u a l l y begin saving unless or u n t i l data w r i t i n g has been enabled. The operator i s once again allowed to choose between read or w r i t e f i l e i n t e r a c t i o n , or to e x i t P r m F i l e . In the l a t t e r case, the p r e v i o u s l y a c t i v e screen image i s reloaded, and PrmFile r e t u r n s from the ParamFile c a l l . Parameter value data and e l a p s e d time are w r i t t e n to the .PDAT f i l e by the segment process ParamPut. T h i s process i s s t a r t e d by the segment procedure P D a t S t r t , which i n turn i s c a l l e d from the ParamSav i n i t i a l i z a t i o n code. PDatStrt a l s o i n i t i a l i z e s a number of i n t e r n a l ParamSav v a r i a b l e s such as the enabled s t a t u s ( f a l s e ) , read and w r i t e parameter l i s t p o i n t e r s ( n i l ) , read and w r i t e f i l e s t a t e s ( c l o s e d ) , and data i n t e g r a t i o n time ( a r b i t r a r i l y one second). The S t a r t e r procedure S t r t l n f o i s used to determine the ParamPut stack s i z e and p r i o r i t y . ParamPut i n i t i a l l y waits f o r a s i g n a l that a new w r i t e f i l e has been opened. While MicroSput continues to run, ParamPut loops as f o l l o w s . A short inner loop i s executed which waits f o r e i t h e r or both s i g n a l s a s s o c i a t e d with w r i t e f i l e being opened and with w r i t e f i l e being enabled; the loop i s e x i t e d as soon as, but not before, both c o n d i t i o n s are t r u e . While the c o n d i t i o n s continue to remain t r u e , a longer inner loop i s executed, completing the ParamPut outer loop. The second inner loop determines the parameter value and execution time averages and w r i t e s them to the d i s k . I f the c y c l e time i s g r e a t e r than 51 the i n t e g r a t i o n time, the El2AnaIO procedure AnalnStatus i s c a l l e d t o dump the analog input i n t e g r a t i o n sums. The Clock procedure TimSubTO i s c a l l e d to rec o r d the s t a r t of the input i n t e g r a t i o n , and the Schedule procedure WaitTick i s c a l l e d to wait out the i n t e g r a t i o n . TimSubTO and AnalnStatus are again c a l l e d to determine the average o f f s e t c l o c k reading during the i n t e g r a t i o n , and the analog input averages f o r a l l channels, r e s p e c t i v e l y . The average elapsed time i s w r i t t e n to the f i l e . If r eading of the wr i t e f i l e i s enabled, that time value i s a l s o c o p i e d to the g l o b a l param_time. The wr i t e parameter l i s t i s t r a v e r s e d , data values being w r i t t e n to the f i l e (and, f o r the case of reading the wr i t e f i l e , to the parameter inf o r m a t i o n r e c o r d read_data f i e l d s ) a c c o r d i n g to whether or not the value i s measured from the analog i n p u t s . If so, the corresponding i n t e g r a t e d channel value i s s c a l e d and w r i t t e n . Otherwise, the present parameter value i s used. In the read data from the wr i t e f i l e case, the ParamGet process i s s i g n a l l e d that new data i s a v a i l a b l e . If the s i n g l e r e c o r d data saving mode has been s e l e c t e d , data w r i t i n g i s d i s a b l e d . If the save c y c l e time i s gr e a t e r than the i n t e g r a t i o n time, WaitTick i s c a l l e d to wait out the d i f f e r e n c e , completing the second inner ParamPut loop. The procedure ParamReset i s used to prepare an al r e a d y opened data read f i l e f o r reading, s t a r t i n g at the f i r s t data r e c o r d . ParamReset may be c a l l e d to rewind the data read f i l e at any time, but only responds i f the f i l e i s open. If reading of the w r i t e f i l e has been s e l e c t e d , a copy of the wr i t e f i l e b u f f e r i s t r a n s f e r r e d to the read f i l e b u f f e r by the l o c a l procedure CopyWtoR. Once r e s e t , data can be read from t h i s 52 c o p i e d read f i l e only up to the l a s t data p o i n t w r i t t e n before the copy made; end of f i l e w i l l be true beyond t h i s p o i n t even though new data may have been w r i t t e n to the f i l e subsequenty. In any case, the data read f i l e i s r e s e t and the read parameter l i s t and read data i n t e g r a t i o n time are read. The f i r s t r e a l data number i s p o i n t e d to by one f u r t h e r get i n s t r u c t i o n , mimicing the P a s c a l standard i m p l i c i t get on r e s e t . The f u n c t i o n ParamGet attempts to read the next data read f i l e r e c o r d i n t o param_time and the read parameter i n f o r m a t i o n r e c o r d read_data f i e l d s . If the read f i l e end has been reached and reading of the data f i l e has not been enabled, the f a l s e r e s u l t i s returned; otherwise the r e s u l t w i l l be t r u e . If new wr i t e data has al r e a d y been loaded f o r reading, that f a c t i s noted and ParamGet returned from. If the end of f i l e has not been reached, the new read data r e c o r d i s loaded and ParamGet returned from. In t h i s case, no task s w i t c h i n g i s allowed while reading and copying the data read f i l e , as a ParamPut execution c o u l d o v e r w r i t e part of the data, followed by the switch back to ParamGet o v e r w r i t i n g the r e s t . F i n a l l y , i f none of the above have caused a r e t u r n from ParamGet, the new wr i t e data r e c o r d l o a d i n g i s waited f o r . Parameter value data p l o t t i n g i s performed by the c o m p i l a t i o n module P l o t t e r . Only two P l o t t e r r o u t i n e s are e x p l i c i t l y a v a i l a b l e : P lotSetup, which i n t e r a c t i v e l y s e t s up and s t a r t s the p l o t t i n g , and p l H a l t which s i g n a l s an i n t e r n a l semaphore. The procedure p l H a l t must be c a l l e d to shut down the i n t e r n a l p l o t t i n g process a f t e r the g l o b a l Schedule boolean v a r i a b l e running has been r e s e t but before the program i s 53 a c t u a l l y t e r m i n a t e d . P l o t S e t u p c o n s i s t s o f o n l y one p r o g r a m m i n g l i n e : a c a l l t o t h e segment p r o c e d u r e P l o t S e t . The UCSD p - S y s t e m d o e s n o t a l l o w s e g m e n t p r o c e d u r e s t o be d e c l a r e d i n t h e i n t e r f a c e p a r t , so s e g m e n t p r o c e d u r e s c a n o n l y be made g l o b a l l y a v a i l a b l e v i a an e x t r a dummy r o u t i n e . P l o t S e t b e g i n s by i n i t i a l i z i n g VDT a r r o w a n d e s c a p e key v a r i a b l e s ; t h e A S C I I c o d e g e n e r a t e d by t h e s e k e y s i s non s t a n d a r d , and c a n o n l y be d e t e r m i n e d by c a l l s t o t h e p - S y s t e m s u p p l i e d u n i t S c r e e n O p s o r i t s M i c r o S p u t e x t e n s i o n , E x t r a S c r e e n O p s . The f i r s t t i m e P l o t S e t i s c a l l e d , t h e x - y r e c o r d e r pen w i l l be moved up t o t h e t o p r i g h t h a n d c o r n e r o f t h e p l o t t o e n a b l e t h e o p e r a t o r t o s e t t h e p h y s i c a l p l o t s i z e . The b a c k g r o u n d VDT s c r e e n image ' p l o t s e t ' - i s l o a d e d ( s e e F i g . 7 ) . The c u r r e n t c h o i c e s f o r a x e s p a r a m e t e r s , t h e i r u n i t s , a n d t h e b o u n d s o f t h e p l o t a r e w r i t t e n t o t h e i r r e s p e c t i v e f i e l d s i n t h e s c r e e n i m a g e . I f t h e o p e r a t o r p r e s s e s t h e e s c a p e k e y , P l o t S e t w i l l be e x i t e d w i t h no c h a n g e s . O t h e r w i s e , p l o t t i n g i s d i s a b l e d w h i l e t h e c h a n g e s a r e m a d e . P l o t S e t l o o p s , a l l o w i n g t h e o p e r a t o r t o c h a n g e t h e a x e s p a r a m e t e r s ( e l a p s e d t i m e c a n be c h o o s e n a s an a b s c i s s a o n l y ) , a n d t o s e l e c t t h e p l o t b o u n d s e i t h e r m a n u a l l y o r by r e a d i n g t h e e n t i r e d a t a f i l e and d e t e r m i n i n g t h e e x t e n t o f t h e d a t a . In t h e m a n u a l c a s e t h e a r r o w k e y s a r e u s e d t o s e l e c t w h i c h b o u n d i s t o be i n p u t . T h e l o o p i s e x i t e d e i t h e r by p r e s s i n g t h e e s c a p e k e y , i n w h i c h c a s e no p l o t t i n g i s d o n e , o r ' S ' ( s e n d ) , i n w h i c h c a s e t h e P l o t U t i l p r o c e d u r e P l o t B o u n d s i s p a s s e d t h e new s e t o f d a t a b o u n d s , t h e P l o t U t i l p r o c e d u r e P l o t A x e s i s c a l l e d t o draw a r e c t a n g l e a r o u n d t h e p l o t a t t h e minimum a n d maximum a x e s e x t e n t s , t h e P a r a m S a v e P l o t t e r : X , Y ( a x i s ) D ( a t a o r <arrows> ( b o u n d s ) S ( e n d <esc> ( ) S e t up a x e s & b o u n d s f o r x - y p l o t t e r t h e n s e n d t h e d a t a o r e s c a p e ( ) F i g u r e 7 . P a r a m e t e r p l o t t i n g s c r e e n image ' p l o t s e t ' . UI 55 procedure ParamReset i s c a l l e d to r e s e t the data read f i l e , p l o t t i n g i s enabled, and the i n t e r n a l p l o t t i n g process PlotData i s s i g n a l l e d . The process PlotData i s s t a r t e d by. the procedure P l o t S t r t , which i n turn i s c a l l e d by the P l o t t e r i n i t i a l i z a t i o n code. P l o t S t r t i n i t i a l i z e s some i n t e r n a l data v a l u e s , such as the p l o t t i n g enabled s t a t u s ( f a l s e ) and the axes parameters ( n i l ) . The S t a r t e r procedure S t r t l n f o i s c a l l e d to look up the PlotData stack s i z e and p r i o r i t y . While MicroSput continues to run, PlotData r e p e a t e d l y executes a loop c o n s i s t i n g of a wait to be s i g n a l l e d to s t a r t p l o t t i n g , and an inner loop. The inner loop c y c l e s u n t i l p l o t t i n g i s d i s a b l e d or the ParamSave f u n c t i o n ParamGet i s f a l s e , p l o t t i n g the chosen parameter read_data values by c a l l i n g the P l o t U t i l procedures P l o t , PlotDrop, and P l o t L i f t . These procedures move the pen to the given x and y p o s i t i o n and wait for i t to h a l t , drop the pen onto the paper and wait a short delay, and l i f t the pen back up, w a i t i n g the same short d e l a y . 56 CHAPTER SIX E12 Analog/Digital Input/Output Interface Programming Two leve l s of MicroSput subprogram modules are used to . operate the E12 analog/digital input/output interface (see l i s t i n g s in Appendix D). The E12 l e v e l i s s e l f - r e l i a n t ; the E12 Multitasking l e v e l uses the E12, multitasking, and general unit l e v e l s . A l l MicroSput programming using the E12 interface i s s p e c i f i c to the microcomputer system in room 118D of the Hennings Building at UBC, since only one such interface was b u i l t . The UBC Physics Electronics Lab now uses a decendant of the El 2 interface, c a l l e d the Phys 44 bus, for general purpose electronics i n t e r f a c i n g . To avoid b u i l t in obsolecence, future versions of MicroSput w i l l use commercially available interfacing equipment which adheres to the S100 microcomputer bus standard, the RS232 s e r i a l communication standard, or the GPIB p a r a l l e l communication standard wherever possible. The Phys 44 bus w i l l be used when no acceptable commercial equipment can be obtained. The E12 interface includes: a sixty Hertz thirty-two b i t clock; eight opto-isolated TTL inputs; eight opto-isolated TTL outputs; one sixteen channel multiplexed bipolar single ended integrating analog input with one t h i r t i e t h second conversion time, one m i l l i v o l t resolution, ten volt f u l l scale, twelve volt overscale, and an input impedence of 180 kiloohms; eight unipolar single ended analog outputs with ten volt f u l l scale into a high impedance load or five volt f u l l scale into a f i f t y 57 ohm l o a d , four of which have e i g h t b i t r e s o l u t i o n (outputs 1...4), and four of which have twelve b i t r e s o l u t i o n (outputs 5...8). A l l of the r o u t i n e s i n the E12 stand alone modules are w r i t t e n i n assembler. The u n i t E12ISR c o n t a i n s a l l the i n t e r r u p t s e r v i c i n g ; s i n c e c a l l s to E12ISR r o u t i n e s are made d i r e c t l y by the cpu r a t h e r than v i a the p-System, E12ISR may n e i t h e r be o v e r l a i d nor moved about i n RAM. T h i s r i g i d i t y i s made known to the p-System by d e c l a r i n g the assembler r o u t i n e s as .PROC and .FUNC. The modules El2DigIO and El2AnaI0 c o n t a i n the r e l o c a t a b l e ( i . e . swappable and moveable) r o u t i n e s ( d e c l a r e d as .RELPROC and .RELFUNC) which i n t e r a c t with and complement the i n t e r r u p t s e r v i c i n g to pro v i d e f u l l stand alone o p e r a t i o n of the E1 2 i n t e r f a c e . Because c o m p i l a t i o n u n i t s are, i n g e n e r a l ; subject to the memory management of the p-System, assembler r o u t i n e s i n one module are not capable of d i r e c t l y c a l l i n g those in another. Interdependent assembler r o u t i n e s are meant to be l i n k e d together i n t o the same host c o m p i l a t i o n u n i t . G l o b a l data areas, on the other hand, are f i x e d in p o s i t i o n throughout a program l i f e t i m e . Assembler r o u t i n e s can, t h e r e f o r e , be informed of the addresses of r o u t i n e s in other memory and p o s i t i o n locked u n i t s only by keeping those addresses in a t a b l e i n c l u d e d as g l o b a l data. The f i r s t d e c l a r e d v a r i a b l e i n E12ISR i s jumptabl, which c o n t a i n s jumps to a number of i n t e r n a l u t i l i t y r o u t i n e s . G l o b a l data needed f o r d i g i t a l output p u l s i n g (performed by an i n t e r r u p t s e r v i c e r o u t i n e but c o n t r o l l e d by an El2 D i g I 0 r o u t i n e ) i n c l u d e s the c u r r e n t d i g i t a l output word, a boolean value to i n d i c a t e whether or not a pulse i s a c t i v e , the 58 time at which to p a s s i v a t e the p u l s e , the d i g i t a l value of the p a s s i v a t i o n , and a mask s p e c i f y i n g which b i t s are being pulsed. E12 d i g i t a l r o u t i n e s operate on a s i x t e e n b i t d i g i t a l word, even though only e i g h t are p h y s i c a l l y a v a i l a b l e , i n order that expansion to s i x t e e n b i t s of TTL i / o may be e a s i l y performed. G l o b a l data needed for analog input m u l t i p l e x i n g ( a l s o performed by an i n t e r r u p t s e r v i c e r o u t i n e but c o n t r o l l e d and read by El2AnaI0 procedures) i n c l u d e s a s i x t e e n channel packed r e c o r d of the input reading, sum of past readings, count of those readings, values necessary f o r an input r a t e of change c a l c u l a t i o n , boolean i n d i c a t i n g the value has been read and d i f f e r s from a set value by more than a maximum e r r o r , the set value and maximum e r r o r , a p r i o r i t y f o r use i n the input channel m u l t i p l e x i n g scheme, and a boolean i n d i c a t i n g the input value i s to be negated upon being read. E12ISR c o n t a i n s only one d e c l a r e d r o u t i n e , I n i t E 1 2 i s r , which c o p i e s the a c t u a l jump t a b l e to the jumptabl v a r i a b l e and c o p i e s the addresses of the two i n t e r r u p t s e r v i c e r o u t i n e s to the l o c a t i o n s s p e c i f i e d by the i n t e r r u p t hardware. The d i g i t a l p u l s i n g i n t e r r u p t s e r v i c e r o u t i n e , DigServ, i s s e r v i c e d by a programmable i n t e r v a l timer on the Cromemco TU-ART board. T h i s timer has a r e s o l u t i o n of s i x t y - f o u r microseconds and a count of up to 255. Programming the timer with a f u l l count w i l l t h e r e f o r e cause an i n t e r r u p t approximately one s i x t i e t h second l a t e r . MicroSput uses the TTL output pulses to c o n t r o l the gas leak v a l v e s , which are d r i v e n by s i x t y Hertz ac motors. The minimum useable pulse t h e r e f o r e corresponds to the maximum i n t e r v a l timer count. In order to get longer p u l s e s , 59 one can not simply r e s t a r t the timer a predetermined number of times: some computer a c t i v i t i e s , such as d i s k access, can only be performed by p e r i o d i c a l l y d i s a b l i n g a l l i n t e r r u p t s . The cumulative e f f e c t of these subpulse length e r r o r s w i l l r e s u l t in a pulse much longer than s p e c i f i e d , and may d r i v e the v a l v e s f a r beyond t h e i r intended p o s i t i o n . DigServ i n s t e a d terminates long pulses a c c o r d i n g to a hardware c l o c k reading, so the d i s a b l e d i n t e r r u p t e r r o r i s not cumulative. The u n i t E l 2 D i g I 0 p r o v i d e s higher l e v e l programming access to the d i g i t a l p u l s i n g and other E12 d i g i t a l i / o o p e r a t i n g r o u t i n e s . The type d i g i t a l i s d e c l a r e d to be the set of i n t e g e r s zero through f i f t e e n ; i f a number i s a member of the set then the corresponding TTL input or output b i t i s high. The procedures DigRead and DigStatus read the c u r r e n t s t a t e s of the d i g i t a l inputs and outputs, r e s p e c t i v e l y . DigWrite changes the b i t s s p e c i f i e d in a mask to the s u p p l i e d v a l u e s . DigPulse performs a DigWrite, takes the complement of the w r i t t e n values (but not the mask), and r e w r i t e s the new values a s p e c i f i e d time l a t e r . DigPStat r e t u r n s the l e n g t h of time remaining i n a p u l s e , i n s i x t i e t h seconds. The i n i t i a l i z a t i o n code of E12DigI0 c a l l s I n i t E l 2 i s r to copy the jump t a b l e and DigWrites b i t s zero through seven high ( c o n t r o l l e d d e v i c e s are assumed to use a c t i v e low). The h a l t i n g code waits f o r p u l s i n g to end and again DigWrites the outputs h i g h . By f a r the l a r g e s t p o r t i o n of E12 programming i s d e d i c a t e d to s e r v i c i n g the m u l t i p l e x e d analog input. The i n t e r r u p t s e r v i c e r o u t i n e AnaServ ensures the maximum p o s s i b l e data rate over a l l channels by keeping the analog input c o n s t a n t l y 60 c o n v e r t i n g and m u l t i p l e x i n g the input channels a c c o r d i n g to user s p e c i f i e d p r i o r i t i e s . Each channel i s assigned a m u l t i p l e x p r i o r i t y between zero and e i g h t i n c l u s i v e . A sweep of input channel numbers, s t a r t i n g at channel s i x t e e n and ending at one, i s repeated throughout the MicroSput run. Each sweep decrements an i n t e r n a l counter by one, s t a r t i n g at 128. The counter i s r e s t a r t e d at 128 when i t reaches zero. Whether or not a channel i s read on that sweep depends on whether two d i v i d e s evenly i n t o the counter p r i o r i t y times. Thus a l l p r i o r i t y zero channels are read every sweep, p r i o r i t y one every second sweep, p r i o r i t y two every f o u r t h sweep, e t c . through to p r i o r i t y seven channels read every 128th sweep. Channels with p r i o r i t y of e i g h t are never read. L i k e DigServ, AnaServ uses a TU-ART programmable i n t e r v a l timer to generate an i n t e r r u p t approximately every one s i x t i e t h second. If an input c o n v e r s i o n has completed (as i t g e n e r a l l y w i l l have every second t e s t ) , the input value i s read. To in s u r e that a maximum data r a t e i s achieved, the next channel to t r i g g e r w i l l have a l r e a d y been c a l c u l a t e d ; the channel i s s e l e c t e d and co n v e r t e r i s t r i g g e r e d . The time i s read and saved f o r use i n rate of change c a l c u l a t i o n s for the channel j u s t t r i g g e r e d . At t h i s p o i n t a l l necessary data i s taken; a l l i n t e r r u p t s except the AnaServ i n t e r r u p t i t s e l f are enabled so that f u r t h e r AnaServ manipulations can proceed without a f f e c t i n g other i n t e r r u p t s e r v i c e r o u t i n e s . The index r e g i s t e r IX i s loaded with the p r e v i o u s l y c a l c u l a t e d address of the channel i n f o r m a t i o n record f o r the channel j u s t read. Data f i e l d s in the r e c o r d can then be s p e c i f i e d by simply s u p p l y i n g the o f f s e t "61 from the IX value, a l l o w i n g a l l channel records to be manipulated using the same assembler code. The time i n t e r v a l between t h i s and a pr e v i o u s reading i s c a l c u l a t e d ; i f greater than the s p e c i f i e d minimum (a c o n d i t i o n needed to ensure the d i g i t a l e r r o r i n a rate of change c a l c u l a t i o n i s l i m i t e d ) , the time i n t e r v a l , p r evious reading, and the c u r r e n t time are saved. The input o v e r l o a d f l a g i s checked; i f t r u e , the value 12000 i s s u b s t i t u t e d f o r the reading (the maximum v a l i d reading i s 11999); otherwise the input i s converted from b i n a r y coded decimal (as s u p p l i e d by the co n v e r t e r ) to n a t u r a l b i n a r y . The input sign b i t i s checked and e x c l u s i v e or'd with the channel's i n v e r t boolean. The l a t t e r i s user s u p p l i e d and allows the sign of negative v a l u e s (e.g. cathode volta g e ) to be immediately dropped. If the r e s u l t i s t r u e , the value i s s u b t r a c t e d from zero. The new reading i s saved. It i s a l s o added i n t o the three byte reading sum, and the sum count incremented. Since 256 times the maximum reading of 12000 r e q u i r e s l e s s than three bytes, the sum counter w i l l overflow before the sum does. If the l a t t e r occurs, the sum i s d i v i d e d by two ( i . e . s h i f t e d r i g h t one b i t ) and the count i s set to 128. The average value c a l c u l a t i o n , sum d i v i d e d by count, w i l l be u n a f f e c t e d except f o r the one b i t l o s s i n r e s o l u t i o n . The reading i s then s u b t r a c t e d from the d r i f t s e t p o i n t value, a b s o l u t e value of the d i f f e r e n c e i s taken, and the r e s u l t compared to the maximum a l l o w a b l e d r i f t . If the value i s out of bounds, the ready b i t i n the channel i n f o r m a t i o n r e c o r d i s s e t . The next channel c o n v e r s i o n i s prepared f o r , AnaServ i n t e r r u p t reenabled, and the i n t e r r u p t c a l l r e t u r n e d from. 62 The p r e p a r a t i o n f o r next channel c o n v e r s i o n proceeds as f o l l o w s . The number of the channel j u s t t r i g g e r e d i s decremented by one. If the r e s u l t i s zero, channel s i x t e e n i s s u b s t i t u t e d and the channel sweep count i s decremented. If the sweep count has been reduced to zero, 128 i s s u b s t i t u t e d . The number of times two d i v i d e s i n t o the sweep count i s c a l c u l a t e d a c c o r d i n g to the number of times i t can be s h i f t e d r i g h t before a one i s s h i f t e d out. The r e s u l t i n g power of two i s saved f o r ev e n t u a l comparison with a l l s i x t e e n channel p r i o r i t i e s . The p r i o r i t y of the channel i s compared to the power of two; i f l e s s than or equal to then the channel i s s e l e c t e d , otherwise the c a l c u l a t i o n i s redone. One should note that t h i s method w i l l become i n c r e a s i n g l y i n e f f i c i e n t as the minimum channel p r i o r i t y f a c t o r i s i n c r e a s e d above zero; indeed the c a l c u l a t i o n w i l l loop i n f i n a t e l y i f a l l p r i o r i t i e s are e i g h t . The p r i o r i t y s e t t i n g r o u t i n e ( s ) must be wary of t h i s problem. The c o m p i l a t i o n u n i t E12AnaI0 pro v i d e s higher l e v e l programming access to the analog inputs and outputs. Care must be taken when passin g data to and from areas c o n t r o l l e d by i n t e r r u p t s e r v i c e r o u t i n e s , as i n t e r r u p t s o c c u r r i n g when a data t r a n s f e r i s only p a r t i a l l y completed may o v e r w r i t e some, but not a l l , of the r e c o r d . In g e n e r a l , E12AnaI0 r o u t i n e s d i s a b l e i n t e r r u p t s during the s e n s i t i v e program steps. The procedure AnalnGo d i s t r i b u t e s packed a r r a y s of channel i n v e r t booleans and p r i o r i t y numbers among the channel i n f o r m a t i o n r e c o r d s . The p r i o r i t y a r ray i s checked f o r at l e a s t one zero e n t r y ; i f not found, channel 16 p r i o r i t y i s a r b i t r a r i l y n u l l e d . The analog i n f o r m a t i o n record data f i e l d s are c l e a r e d and the AnaServ 63 i n t e r r u p t i s enabled. The procedure AnaSetBound i s used to change, f o r a s i n g l e channel, the p o i n t from which a d r i f t i s measured, the amount by which that d r i f t must exceed, and the minimum time i n t e r v a l necessary f o r a rate of change c a l c u l a t i o n . AnaReady draws together a l l the d r i f t e r r o r exceeded booleans and prese n t s them as a set of ready input channels. The booleans are a l l r e s e t by t h i s c a l l , so s u c c e s s i v e AnaReady c a l l s w i l l present only the newly ready channels. AnaRead f e t c h e s a channel's l a t e s t input value, change i n readi n g , and change in time ( i t i s e a s i e s t to d i v i d e the l a t t e r two from w i t h i n the P a s c a l c a l l e r ) and a l s o r e s e t s the d r i f t e r r o r exceeded boolean. AnalnStatus i s u s e f u l f o r a data l o g g i n g c a l l e r : an a l l channel array of records c o n t a i n i n g the l a t e s t reading, sum, and number of readings i n that sum i s re t u r n e d . D r i f t e r r o r exceeded booleans are not r e s e t by t h i s c a l l , but sums and counts are zeroed, a l l o w i n g AnalnStatus to perform as a mul t i c h a n n e l i n t e g r a t e and dump r o u t i n e . AnalnStop d i s a b l e s the AnaServ i n t e r r u p t . Analog output i s supported by three r o u t i n e s : AnaWrite, AnaOutRead, and AnaOutStatus. AnaWrite sends a value to the s p e c i f i e d output channel, ensuring that i t i s w i t h i n the range 0...255 f o r channels 1...4 and 0...4095 f o r channels 5...8. The output values are saved in a b u f f e r and can be i n d i v i d u a l l y read back using AnaOutRead, or as a group with AnaOutStatus. The E12AnaI0 i n i t i a l i z a t i o n code c a l l s the E12ISR procedure I n i t E l 2 i s r to copy the jump t a b l e , i n i t i a l i z e s a l l channel d r i f t set va l u e s , maximum d r i f t e r r o r s , and minimum change in time values to zero, minus one, and one h a l f second r e s p e c t i v e l y . AnaReady i s c a l l e d to r e s e t a l l 64 channel ready booleans. AnaWrite i s c a l l e d once per output channel, s e t t i n g a l l outputs to zero. The E12AnaI0 h a l t i n g code again zeroes a l l outputs, and ends by c a l l i n g AnalnStop to ensure i n t e r r u p t s e r v i c i n g i s h a l t e d . The E12 M u l t i t a s k i n g subprogram module l e v e l i n c l u d e s three u n i t s : E12Sched, TrigAna, and P l o t U t i l . El2Sched a c t s as a task s c h e d u l i n g u n i t f o r p r o c e s s i n g which must be synchronized with d i g i t a l or analog input s t a t e s . TrigAna saves the input channel m u l t i p l e x i n g p r i o r i t i e s and i n v e r t booleans between MicroSput runs, and allows i n t e r a c t i v e e d i t i n g of those values during a MicroSput run. P l o t U t i l uses E12 o p e r a t i o n s to provide n o n - i n t e r a c t i v e c o n t r o l of an x-y p l o t t e r . Three procedures are d e c l a r e d by El2Sched: E12Start, W a i t B i t , and WaitAnalog. E12Start i s implemented by the segment procedure E l 2 S t r t . The l a t t e r i n i t i a l i z e s f l a g s and semaphores to i n d i c a t e no d i g i t a l or analog input s t a t e s are c u r r e n t l y being processed. The S t a r t e r procedure S t r t l n f o i s c a l l e d to determine the stack s i z e and p r i o r i t y of the i n t e r n a l input p o l l i n g p r o c e s s , P o l l e r , and the l a t t e r i s s t a r t e d . El2Sched cannot be i n i t i a l i z e d by i t s own i n i t i a l i z a t i o n code s i n c e i t r e l i e s on E12DigI0, E12AnaI0 and Schedule having a l l been p r e v i o u s l y i n i t i a l i z e d . The i n t e r n a l process P o l l e r begins by c a l l i n g the Schedule procedure DvceJoin, thereby j o i n i n g the Schedule u n i t ' s e x t e r n a l d e v i ce p o l l i n g handshake. DvceJoin and DvceAcpt c a l l s are returned from each time the high p r i o r i t y input s t a t e p o l l i n g process i n t e r n a l to Schedule l o o p s . The l a t t e r loops once per c a l l of the Schedule procedure P o l l l n p u t s ; such c a l l s are 65 l i b e r a l l y s p r i n k l e d throughout MicroSput. A f t e r j o i n i n g the e x t e r n a l d e v i c e handshake, and while MicroSput continues to run, P o l l e r loops as f o l l o w s . If one or more W a i t B i t c a l l s are o u t s t a n d i n g , the El2DigIO procedure DigRead checks the d i g i t a l i n p u t s . The input v a l u e s are compared to those requested by the W a i t B i t c a l l s ; semaphores corresponding to those i n agreement are s i g n a l l e d . If one or more WaitAnalog c a l l s are outstanding, the'El2AnaI0 procedure AnaReady determines which input channels have been read and observed to have d r i f t e d out of bounds by the analog input i n t e r r u p t s e r v i c i n g . Semaphores corresponding to any such channels which have a l s o been requested by WaitAnalog c a l l s are s i g n a l l e d . An acceptor handshake i s then performed by a c a l l to the Schedule procedure AcptHshk. During MicroSput t e r m i n a t i o n , a f i n a l P o l l l n p u t s c a l l assures AcptHshk i s returned • from and the P o l l e r loop e x i t e d ; a DvceQuit c a l l breaks o f f the Schedule handshake, and a l l semaphores a s s o c i a t e d with the d i g i t a l and analog inputs are s i g n a l l e d (thereby a l l o w i n g a l l o u t s t a n d i n g W a i t B i t and WaitAnalog c a l l s to be returned from) . The procedures W a i t B i t and WaitAnalog are not returned from u n t i l a s p e c i f i e d TTL input b i t number has ac h i v e d the given s t a t e or a s p e c i f i e d analog input channel has d r i f t e d beyond i t s p r e v i o u s l y set bounds, r e s p e c t i v e l y . Only one process can wait on a given b i t or channel at a time; s u c c e s s i v e W a i t B i t or WaitAnalog c a l l s s p e c i f y i n g the same b i t or channel number are queued and s e r v i c e d a c c o r d i n g to process p r i o r i t y . Both WaitBit and WaitAnalog c a l l the Schedule procedure P o l l l n p u t s and wait for a b i t or channel s p e c i f i c semaphore, which ensures an 66 immediate check of the E12 input s t a t e as o u t l i n e d i n the preceding paragraph. The c o m p i l a t i o n module TrigAna d e c l a r e s one v a r i a b l e , ana_names, and two procedures, T r i g l n i t and T r i g S e t u p . The v a r i a b l e ana_names i s a s i x t e e n channel array of names ( i . e . s t r i n g [ 8 ] ) which MicroSput higher l e v e l procedures may a s s o c i a t e with each channel. These names d e f a u l t to the n u l l s t r i n g '' upon execution of the TrigAna i n i t i a l i z a t i o n code. T r i g l n i t f i r s t checks to see i f the p r i o r i t y and i n v e r t boolean i n f o r m a t i o n f i l e has been read; i f not, the l o c a l procedure TrigRead i s c a l l e d to do so (the i n f o r m a t i o n i s kept i n the f i l e u t i l : s y s t e m . p r i o ) . Note that the f i l e v a r i a b l e i s d e c l a r e d l o c a l l y w i t h i n the TrigRead procedure; i t i s thus i m p l i c i t l y c r e a t e d on the stack when TrigRead i s c a l l e d , and destroyed when TrigRead i s e x i t e d . F i l e b u f f e r s a s s o c i a t e d with f i l e s d e c l a r e d g l o b a l l y w i t h i n a u n i t remain a c t i v e on the heap throughout the program e x i s t a n c e ; i f the f i l e i s g e n e r a l l y unused, at l e a s t 300 words of RAM are wasted. T r i g l n i t then c a l l s the l o c a l procedure T r i g g e r to a c t u a l l y s t a r t up the i n t e r r u p t s e r v i c i n g . T r i g g e r checks the p r i o r i t i e s f o r the minimum p r i o r i t y number: i f e i g h t , the E l 2 A n a I O procedure AnalnStop i s c a l l e d s i n c e no channels are to be read; otherwise that minimum number i s s u b t r a c t e d from a l l p r i o r i t y numbers to ensure maximum e f f i c i e n c y of the AnaServ i n t e r r u p t process, and AnalnGo i s c a l l e d . T r i g S e t u p a l s o begins by reading the input f i l e i f i t ' s not a l r e a d y read. The background screen image ' t r i g a n a ' i s loaded (see F i g . 8 ) . The channel names, which may have been changed Set Analog T r i g g e r i n g ; 1..16(channel I ( n v e r t P ( r i o r i t y Q ( u i t Channel: chan name i n v e r t p r i o r i t y readings/sec Each channel i s t r i g g e r e d every ( 2 * * p r i o r i t y ) t h scan, s t a r t i n g with channel 16. P r i o r i t y range i s 0..7. Average sampling frequency depends on a l l channel p r i o -r i t i e s and i s lower than shown when i n t e r r u p t s are o f t e n d i s a b l e d , such as dur-ing d i s k access. Channels with i n v e r t true are recorded as the negative of t h e i r a c t u a l p h y s i c a l v a l u e . 1 2 3 4 5 6 7 8 9 10 1 1 12 1 3 1 4 1 5 16 Figure 8. Analog input m u l t i p l e x i n g screen image ' t r i g a n a ' CTl ~0 68 from t h e i r d e f a u l t value by a higher l e v e l MicroSput procedure, are d i s p l a y e d , as w e l l as the input i n v e r t boolean and p r i o r i t y f o r a l l channels of p r i o r i t y l e s s than e i g h t . A c a l c u l a t i o n i s done to determine the average data r a t e on each channel, based on the e x i s t i n g p r i o r i t i e s and one t h i r t i e t h second conversion time, and the r e s u l t s are d i s p l a y e d . Channel s i x t e e n i s a r b i t r a r i l y s e l e c t e d f o r i n i t i a l i n t e r a c t i o n . A prompt i s d i s p l a y e d and an i n t e r a c t i o n loop continued u n t i l the operator chooses to leave i t (by t y p i n g 'Q' f o r q u i t ) . The p r e v i o u s l y a c t i v e screen image i s reloaded and T r i g S e t u p e x i t e d . The T r i g S e t u p i n t e r a c t i o n loop c o n s i s t s of the f o l l o w i n g . The operator chooses a new channel (by t y p i n g i t s number), to toggle the channel's i n v e r t boolean (by t y p i n g ' I ' ) , or to change the channel's p r i o r i t y (by t y p i n g 'P'). In the l a t t e r case, the new p r i o r i t y i s entered by t y p i n g a number zero through seven, or c a r r i a g e r e t u r n f o r no t r i g g e r i n g ( i . e . p r i o r i t y e i g h t ) . The i n d i v i d u a l channels' average data r a t e c a l c u l a t i o n s are redone and d i s p l a y e d , and the new i n v e r t booleans and p r i o r i t i e s loaded by c a l l i n g T r i g g e r . I f any changes have been made to any of the i n v e r t booleans or t r i g g e r p r i o r i t i e s , the TrigAna h a l t i n g code w i l l w r i t e the new values to the d i s k upon program t e r m i n a t i o n . The E12 M u l t i t a s k i n g l e v e l u n i t P l o t U t i l operates an x-y p l o t t e r . 1 1 F i v e procedures are d e c l a r e d : PlotBounds, 1 1 P l o t U t i l c u r r e n t l y uses analog outputs 7 and 6 f o r x and y axes, r e s p e c t i v e l y . Pen motion i s d e t e c t e d with d i g i t a l input b i t 7, and pen z - a x i s c o n t r o l i s fed from d i g i t a l output b i t 7. The m o d i f i c a t i o n s performed on the Hewlett-Packard 7044A X-Y 69 P l o t , P l o t L i f t , PlotDrop, and PlotAxes. PlotBounds must be c a l l e d with the minimum and maximum a b s c i s s a and o r d i n a t e values f o r the p l o t before any p l o t t i n g can proceed. P l o t s c a l e s and o f f s e t s the s p e c i f i e d x,y data and moves the pen to the r e s u l t i n g c o o r d i n a t e s . P l o t c a l l s the E12Sched procedure W a i t B i t to ensure pen motion i s complete before r e t u r n i n g . P l o t L i f t and PlotDrop l i f t and drop the pen from and on to the paper, r e s p e c t i v e l y ; each procedure c a l l s the Schedule procedure WaitTick r e q u e s t i n g a one twentieth second delay to ensure the z - a x i s motion i s completed. PlotAxes l i f t s the pen, moves i t to the lower l e f t hand corner of the p l o t , drops i t , moves i t to the upper l e f t , upper r i g h t , lower r i g h t , and lower l e f t hand c o r n e r s s u c c e s s i v e l y , and f i n a l l y l i f t s the pen and r e t u r n s . Recorder r e q u i r e d f o r motion d e t e c t i o n and z - a x i s c o n t r o l were made and documented by M.L.W. Thewalt in h i s M.Sc. T h e s i s , UBC, October 1975. 70 CHAPTER SEVEN MicroSput M u l t i t a s k i n g U t i l i t i e s The MicroSput c o m p i l a t i o n modules in the m u l t i t a s k i n g group are u s e f u l f o r any UCSD p-System V e r s i o n IV.0 implementation. A l l e x t e r n a l equipment operated by these modules (the VDT, d i s k d r i v e s and system c l o c k ) are d r i v e n by the p-code i n t e r p r e t e r ; the compiled code of the modules w i l l run without m o d i f i c a t i o n or r e c o m p i l a t i o n on any of the l a r g e number of microcomputer systems supported by the p-System. The c o m p i l a t i o n u n i t s comprising the m u l t i t a s k i n g group are S t a r t e r , DataBus, Schedule, ReadKybd, and ScrnBuff (see Appendix E f o r l i s t i n g s ) . The l a t t e r two u n i t s may prove u s e f u l in programming s i t u a t i o n s where s u b s i d i a r y processes are not used e x p l i c i t l y , although they are b u l k i e r and slower than necessary in that case. ReadKybd can be used to ensure that a l l operator entered input i s e r r o r f r e e and w i t h i n s p e c i f i e d bounds. ScrnBuff i s u s e f u l for m a i n t a i n i n g a pool of background screen images and d i s p l a y i n g s e l e c t e d images to the VDT screen. S t r t e r i s meant to be user e d i t a b l e . I t s s i n g l e procedure, S t r t l n f o , determines the stack s i z e and p r i o r i t y of a named process by searching a t a b l e (as ammended by the user) fo r the given u n i t and process names. One might think i t would be wiser to have S t r t l n f o read the stack s i z e and p r i o r i t y from a data f i l e , a v o i d i n g the need to recompile S t a r t e r each change. U n f o r t u n a t e l y , that method would e i t h e r mean a waste of 300 RAM words f o r a f i l e d e c l a r e d g l o b a l l y i n S t a r t e r ' s implementation 71 p a r t , or a long MicroSput s t a r t u p time, f o r a data f i l e d e c l a r e d w i t h i n S t r t l n f o and t h e r e f o r e opened and c l o s e d each c a l l . As with other MicroSput name o p e r a t i o n s , the u n i t and process names are converted to upper case ( v i a a c a l l to the MiscFunc procedure Uppercase) before comparison so as to render the comparison case independent. If the process s t a r t u p i n f o r m a t i o n i s not found, a c a l l to the ErrMessg procedure NoteError d i s p l a y s a message to that e f f e c t and h a l t s the MicroSput i n i t i a l i z a t i o n . An i n t e g e r constant s t a c k _ s a f e t y i s added to a l l t a b u l a t e d stack s i z e s to account f o r the p o s s i b l e need of a stack l a r g e r than s p e c i f i e d . T h i s f e a t u r e i s pro v i d e d because of the d i f f i c u l t y in determining the minimum workable process stack s i z e . The l a t t e r can only be done by t r i a l and e r r o r : set s t a c k _ s a f e t y to zero; choose a stack s i z e f o r the process in q u e s t i o n ; compile S t a r t e r and run MicroSput. I f the run proceeds as expected, t r y again with a smaller stack; i f a stack overflow occurs, reboot the p-System and t r y again with a l a r g e r s tack. The n e c e s s i t y to recompile S t a r t e r many times i n t h i s s i t u a t i o n may prompt the user to leave the S t a r t e r c o d e f i l e separate from the r e s t of the MicroSput l i b r a r y . When a s a t i s f a c t o r y stack s i z e has been a t t a i n e d , i n c r e a s e the s t a c k _ s a f e t y and compile S t a r t e r f o r a f i n a l time. The value one may want f o r s t a c k _ s a f e t y remains a user compromise between a small value (e.g. zero) and a s s o c i a t e d high r i s k of stack overflow (an e r r o r f a t a l to both MicroSput and the u n d e r l y i n g p-System), and a l a r g e value (e.g. f i f t y words) and a s s o c i a t e d decrease i n execution speed of a l l MicroSput tasks ( f i f t y words f o r each of, say,, twenty processes uses up two k i l o b y t e s of RAM, 72 r e q u i r i n g e x t r a p-System memory management p r o c e s s i n g ) . Of course, i f one i s w i l l i n g to spend long enough at the t r i a l and e r r o r experiments, the exact minimum r e q u i r e d stack s i z e can be found and s t a c k _ s a f e t y can be n u l l e d without any r i s k of stack overflow e r r o r s . The u n i t DataBus p r o v i d e s a method of s y n c h r o n i z a t i o n of and communication between processes, independent of process p r i o r i t i e s . The type handshake i s d e f i n e d f o r t h i s use; the a c t u a l handshake data f i e l d s are meant to be manipulated by DataBus procedures o n l y . Processes must be e i t h e r a c c e p t o r s , in which case they wait f o r the handshake to occur (and perhaps use some a s s o c i a t e d new d a t a ) , or sources, in which case they generate a handshake s i g n a l (and perhaps update an a s s o c i a t e d data r e c o r d ) . Any number of a c c e p t o r s and sources may share a handshake; u n l i k e processes w a i t i n g on semaphores, a l l acceptor processes w i l l r e c i e v e a s i n g l e handshake s i g n a l . Acceptors may be e i t h e r synchronous or asynchronous. Synchronous a c c e p t o r s must i n i t i a l l y j o i n the handshake ( v i a a c a l l t.o A c p t J o i n ) , a f t e r which they continue to c y c l e , c a l l i n g AcptHshk with the synchronous boolean t r u e , u n t i l they are ready to leave the handshake ( v i a a c a l l to A c p t Q u i t ) . Asynchronous acceptors may c a l l AcptHshk at any time, with the synchronous boolean f a l s e . Synchronous acceptors w i l l n o t i c e and act upon every handshake s i g n a l ; indeed they must a l l c y c l e and r e - c a l l AcptHshk (or AcptQuit) before the source process can proceed. Asynchronous a c c e p t o r s may miss some handshake s i g n a l s , depending on the r e l a t i v e p r i o r i t i e s of the asynchronous acceptor and a l l sources. I f more than one source process shares the same 73 handshake, and the handshake i s being used to r e g u l a t e data flow through a b u f f e r , then one source must exclude a l l others from access to that data b u f f e r ( v i a a c a l l to SrceLock), change the b u f f e r , then c a l l SrceHshk with the unlocked boolean f a l s e . If only one source i s i n v o l v e d , or i f the handshake i s being used fo r s y n c h r o n i z a t i o n but not data t r a n s f e r , then SrceHshk can be independently c a l l e d with the unlocked boolean t r u e . Before a handshake can be used, i t must be i n i t i a l i z e d by a c a l l to H s h k l n i t . The u n i t Schedule d e c l a r e s one g l o b a l v a r i a b l e , running, and s i x g l o b a l r o u t i n e s , P o l l l n p u t s , DvceJoin, DvceAcpt, DvceQuit, W a i t T i c k , and WaitChar. The boolean running i s i n i t i a l l y set and remains set throughout the MicroSput run; i t i s r e s e t to f l a g the t e r m i n a t i o n of the run. A l l processes must check running before executing a wait statement, and terminate execution upon the r e s e t c o n d i t i o n . P o l l l n p u t s i s a one l i n e procedure: i t s i g n a l s the i n t e r n a l semaphore task_done. DvceJoin, DvceAcpt, and DvceQuit are used by a l l e x t e r n a l device task s c h e d u l i n g u n i t s to p o l l t h e i r input s t a t e s . They are a l s o a l l one l i n e procedures, c a l l i n g A c p t J o i n , AcptHshk (synchronous), and AcptQuit r e s p e c t i v e l y with the i n t e r n a l handshake d v c e _ p o l l as t h e i r parameter. WaitTick and WaitChar can be used by e x t e r n a l r o u t i n e s to synchronize t h e i r execution with the t i c k i n g of the system c l o c k and the operator entered VDT c h a r a c t e r s , r e s p e c t i v e l y . The i n t e r n a l Schedule process P o l l e r p o l l s the s t a t e of the system c l o c k and the VDT keyboard, and s i g n a l s e x t e r n a l device p o l l i n g processes to perform t h e i r p o l l by a d v c e _ p o l l source 74 handshake. P o l l e r s t a r t s by w a i t i n g f o r a task_done s i g n a l . Upon r e c i e p t , and while the g l o b a l running i s t r u e , P o l l e r loops as f o l l o w s . If one or more WaitTick c a l l s are outstanding, a l i n k e d l i s t of semaphores and s i g n a l times i s p o i n t e d t o . The l i s t i s ordered i n terms of the s i g n a l times; the s i g n a l time of the f i r s t member of the l i s t i s the e a r l i e s t time at which any WaitTick semaphores are to be s i g n a l l e d . If the s i g n a l time of the f i r s t member i n the l i s t has a r r i v e d , i t i s s i g n a l l e d and removed from the l i s t . The next l i n k in the l i s t i s s i m i l a r l y t r e a t e d , e t c . u n t i l e i t h e r a l i n k i s found whose s i g n a l time has not a r r i v e d , or the l i s t has been emptied. If a WaitChar c a l l i s o u t s t a n d i n g , the s i z e of i n t e r p r e t e r VDT input c h a r a c t e r queue i s checked. The f i r s t c h a r a c t e r i n the queue i s read and compared to the c h a r a c t e r match set s u p p l i e d as a WaitChar parameter. If the c h a r a c t e r i s a member of the s e t , then the WaitChar semaphore i s s i g n a l l e d ; otherwise the next c h a r a c t e r i n the queue i s checked, e t c . , u n t i l e i t h e r a v a l i d c h a r a c t e r i s found or the queue i s emptied. An unlocked source handshake with d v c e _ p o l l i s performed, and the task_done semaphore i s waited f o r . The ErrMessg f u n c t i o n ErrorNoted i s checked at the end of every loop; i f t r u e , running i s r e s e t . When running f i n a l l y i s r e s e t , e i t h e r because of a MicroSput detected e r r o r or because of operator s e l e c t e d program t e r m i n a t i o n , a l l l i n k s i n the WaitTick semaphore l i s t are s i g n a l l e d , the WaitChar semaphore i s s i g n a l l e d , and a d v c e _ p o l l source handshake i s performed. The procedure WaitTick simply s i g n a l s task_done i f i t s s p e c i f i e d time increment to wait i s zero or l e s s . Otherwise, 75 the system c l o c k i s read and added to the s p e c i f i e d increment. A new l i n k f o r the WaitTick semaphore l i s t i s c r e a t e d and i t s s i g n a l time i n i t i a l i z e d with the time a d d i t i o n r e s u l t . The new re c o r d i s p l a c e d i n the l i n k e d l i s t immediately before any other l i n k with a grea t e r s i g n a l time, or at the end of the l i s t , i f no such l i n k e x i s t s . The input p o l l i n g semaphore task_done i s s i g n a l l e d , and the new semaphore i s waited f o r . The record i s disp o s e d and WaitTick e x i t e d once the semaphore has been s i g n a l l e d . The f u n c t i o n WaitChar can s e r v i c e only one c a l l i n g process at a time; any f u r t h e r WaitChar c a l l s while a former WaitChar c a l l i s outstanding w i l l be p l a c e d i n a queue based on process p r i o r i t y . The c h a r a c t e r match set s p e c i f i e d by the WaitChar c a l l being s e r v i c e d i s recorded f o r use by the P o l l e r process, the input p o l l i n g semaphore task_done i s s i g n a l l e d , and the WaitChar semaphore i s waited f o r . WaitChar r e t u r n s with the f i r s t o perator typed c h a r a c t e r which i s a member of i t s match s e t . A l l MicroSput processes d e s c r i b e d so f a r i n t h i s t h e s i s encounter a wait statement at at l e a s t one p o i n t i n t h e i r e x e c ution loop. In every case the s i g n a l l i n g of the semaphore upon which they wait can u l t i m a t e l y be t r a c e d back to a s i g n a l of the task_done semaphore, upon which the o v e r a l l input s t a t e i s p o l l e d once. I t i s p o s s i b l e to imagine a time i n t e r v a l d u r i n g which no inputs occur. A l l MicroSput tasks w i l l e v e n t u a l l y reach a wait statement, with the lowest p r i o r i t y p rocesses g e t t i n g there l a s t . P o l l l n p u t s w i l l have been c a l l e d and w i l l have s i g n a l l e d task_done many times, but by hypothesis 7 6 none of the inputs upon which the processes wait or e v e n t u a l l y w i l l wait are a c t i v e . When the lowest p r i o r i t y process reaches i t s wait, a l l MicroSput execution w i l l stop. Even i f the inputs then become a c t i v e , there are no processes remaining to c a l l P o l l l n p u t s , and thus none of the newly a c t i v e inputs w i l l be acted upon. C l e a r l y a minimum p r i o r i t y process i s r e q u i r e d to perform one task per loop: s i g n a l task_done. The Schedule process DumpTime i s i n c l u d e d f o r t h i s reason. E v e n t u a l l y , i t may be d e s i r e d to do some a d d i t i o n a l small task, such as scan an o s c i l l o s c o p e beam once, whenever no other processes are ready. In that case, the new process must be given a p r i o r i t y g r e a t e r than that of DumpTime. It i s e s s e n t i a l that any process which never encounters a wait statement c a l l s P o l l l n p u t s on each loop, and that i t s p r i o r i t y i s below those of a l l other needed MicroSput p r o c e s s e s . The MicroSput c o m p i l a t i o n u n i t ReadKybd performs two f u n c t i o n s : formatted asynchronous e r r o r checking VDT input, and VDT curso r c o n t r o l . Most ReadKybd programming i s concerned with the former; a wide assortment of f u n c t i o n s and procedures are prov i d e d to read v a r i o u s data types from the VDT keyboard, a l l o w i n g the execution of other processes to continue d u r i n g the e n t r y . In a l l cases, only r e l e v a n t c h a r a c t e r s are accepted; i n most cases the completed entry i s r e j e c t e d and must be re-en t e r e d i f beyond s p e c i f i e d l i m i t s . The VDT cu r s o r c o n t r o l i s necessary to allow the echoing of VDT keyboard e n t r i e s . When a data f i e l d i s being entered by the operator, other processes are d i s a l l o w e d from moving the c u r s o r (and t h e r e f o r e from w r i t i n g any new data to the s c r e e n ) . Only when the cu r s o r i s 77 r e s t i n g i n a known p o s i t i o n ( i n t h i s case, the end of a prompt l i n e ) i s the c u r s o r a v a i l a b l e f o r data d i s p l a y purposes. In p r a c t i c e , t h i s r e s t r i c t i o n i s very t o l e r a n t , as operator r e a c t i o n time to prompts i s g e n e r a l l y much slower than p r o c e s s i n g time. ReadKybd operator input r o u t i n e s are w r i t t e n in p a i r s . One of the p a i r , given the p r e f i x 'Read', does not move the cursor before input; the other, given the p r e f i x 'Fetch', moves the c u r s o r as s p e c i f i e d , then executes i t s 'Read' twin. Before a c c e p t i n g input, the r o u t i n e s g e n e r a l l y blank out the data f i e l d i n t o which the c h a r a c t e r s comprising the data w i l l be echoed; where not f i x e d by the data type, the l e n g t h of t h i s f i e l d i s s u p p l i e d as a parameter. Read/Fetch r o u t i n e s can be used to read a c h a r a c t e r (which must be i n a given s e t ) , an upper case c h a r a c t e r ( i . e . t r a n s l a t e a l l lower case before checking a g a i n s t the s e t ) , a boolean, an i n t e g e r , a r e a l ( i n e i t h e r f i x e d decimal or s c i e n t i f i c n o t a t i o n ) , or a s t r i n g . The numerical e n t r i e s are checked a g a i n s t s u p p l i e d minima and maxima; i f they are out of bounds, the read o p e r a t i o n i s redone. A l l read o p e r a t i o n s are done one c h a r a c t e r at a time v i a c a l l s to the Schedule procedure WaitChar. T h i s method i s used so that p r o c e s s i n g may continue a c c o r d i n g to process p r i o r i t i e s d u r i n g the data e n t r y . The e n t r y of data c h a r a c t e r by c h a r a c t e r r e q u i r e s a s i z e a b l e amount of programming overhead, p a r t i c u l a r l y i n the numerical input c a s e s ; programmers using the MicroSput l i b r a r y f o r n o n - m u l t i t a s k i n g uses may wish to a v o i d use of ReadKybd for t h i s reason. 78 One operator input r o u t i n e which i s not part of a Read/Fetch p a i r i s the f u n c t i o n PromptCapIn. A prompt l i n e , s u p p l i e d as a PromptCapIn parameter, i s d i s p l a y e d a c r o s s the screen, s t a r t i n g at the given p o s i t i o n . I f the prompt l i n e i s too long to f i t across the screen, i t i s broken up i n t o s u b s t r i n g s , s t a r t i n g at the f i r s t double space (the part before that i s assumed to be a t i t l e , e.g. 'Se t p o i n t : ' , and i s not subje c t to the s u b s t r i n g c y c l i n g a l g o r i t h m ) . The d i s p l a y e d s u b s t r i n g s are c y c l e d through each time the operator types a qu e s t i o n mark; the f a c t that more prompt s u b s t r i n g s are a v a i l a b l e i s shown by a qu e s t i o n mark d i s p l a y e d at the end of the e x i s t i n g s u b s t r i n g , j u s t over the c u r s o r . While PromptCapIn waits f o r an operator response, the c u r s o r i s f r e e d f o r other data d i s p l a y p r o c e s s i n g uses. Those processes should have requested the cu r s o r by c a l l i n g CursBorrow; r e t u r n s w i l l be made from a l l outstanding CursBorror c a l l s . When done, the d i s p l a y processes c a l l CursReturn which i n turn r e p l a c e s the cu r s o r back at the end of the prompt. When a v a l i d c h a r a c t e r has been r e c i e v e d , PromptCapIn d i s a b l e s the CursBorrow r e t u r n s and erases the prompt l i n e . The c o m p i l a t i o n u n i t ScrnBuff a l s o performs two f u n c t i o n s : o p e r a t i n g the background VDT screen image p o o l , and b u f f e r i n g and channeling data from MicroSput processes to the VDT screen when the c o r r e c t background image i s loaded. Screen images are c r e a t e d u s i n g the p-System e d i t e r and added to the screen l i b r a r y u t i 1 : s y s t e m . s c r n using the MicroSput screen f i l e l i b r a r i a n program, ScrnSave. The l a t t e r t r e a t s screen images i n the same manner that the p-System code f i l e l i b r a r i a n program, 79 L i b r a r y , t r e a t s o b j e c t code segments. The tex t f i l e v e r s i o n of a screen image c o n s i s t s of two p a r t s : the prompt l i s t , and the image. The prompt l i s t i s a s e r i e s of prompt l i n e s to be used in a s s o c i a t i o n with the background screen image. The l i s t i s l i m i t e d to a t o t a l of 512 c h a r a c t e r s ; i t i s terminated by the p o i n t e r c h a r a c t e r . The f u n c t i o n ScrnPrompt can be c a l l e d d u r i n g a MicroSput run to determine the RAM l o c a t i o n of one of the prompts a s s o c i a t e d with a loaded screen image. The prompts are numbered s e q u e n t i a l l y , s t a r t i n g at zero . The image part of the screen t e x t f i l e f o l l o w s the prompt l i s t ; i t w i l l be loaded by ScrnBuff procedures as l i n e s 1...23 of the VDT image (the VDT l i n e s are numbered downwards, s t a r t i n g at z e r o ) . Background screen images are i d e n t i f i e d by a MicroSput name v a r i a b l e . The name i s used both to determine the screen image's whereabouts i n the l i b r a r y f i l e , and to determine which VDT f i e l d s are a v a i l a b l e to accept b u f f e r e d d i s p l a y data. The l o a d i n g and r e l o a d i n g of background screen images i s performed i n a manner s i m i l a r to the c a l l i n g of and r e t u r n i n g from P a s c a l procedures. The procedure ScrnEnter (name) i s c a l l e d to l o a d a screen. The named screen image remains a c t i v e u n t i l e i t h e r another ScrnEnter c a l l or a ScrnReturn c a l l i s made. Sc r n C l e a r can be c a l l e d to erase the VDT screen without d e a c t i v a t i n g the c u r r e n t image. ScrnRefresh w i l l r e w r i t e the a c t i v e image to the VDT. If a ScrnEnter c a l l i s made while one screen image i s a c t i v e , the newly named screen image w i l l be loaded, but the formerly a c t i v e image's ScrnEnter w i l l remain o u t s t a n d i n g . A ScrnReturn c a l l performed while the second image i s a c t i v e w i l l r e t u r n to and r e l o a d the f i r s t image. Any number 80 of ScrnEnter/ScrnReturn p a i r s may be nested. The prompts a s s o c i a t e d with an a c t i v e screen image are a v a i l a b l e , v i a the ScrnPrompt f u n c t i o n , whether the a c t i v e image has been c l e a r e d t or r e f r e s h e d . The a c t i v e prompts are saved i n RAM, s i n c e they are expected to be needed many times d u r i n g the l i f e t i m e of an image. The a c t i v e image, on the other hand, remains disk r e s i d e n t . I t i s read from the d i s k and c o p i e d to the VDT screen one block at a time upon each ScrnEnter, ScrnRefresh, or ScrnReturn c a l l . The Schedule procedure P o l l L n p u t s i s c a l l e d between block t r a n s f e r s , and the i n t e r n a l screen image data f i e l d updating process i s s i g n a l l e d upon completed screen w r i t e . The r e c o r d types sb_format and sb_dspl are d e c l a r e d by ScrnBuff to f a c i l i t a t e b u f f e r i n g and channeling of process data to the VDT a c c o r d i n g to the c u r r e n t l y a c t i v e and d i s p l a y e d screen image. The sb_format packed r e c o r d i n c l u d e s boolean e n t r i e s i n d i c a t i n g whether or not the proper screen image i s d i s p l a y e d , the d i s p l a y of a p a r t i c u l a r f i e l d i s enabled, new data has been r e c i e v e d f o r that f i e l d , and f o r r e a l data, whether to use s c i e n t i f i c or f i x e d decimal d i s p l a y . Numerical e n t r i e s i n c l u d e the c o o r d i n a t e s of the data f i e l d , the s i z e of the f i e l d , and f o r r e a l data with f i x e d decimal d i s p l a y , the number of decimal p l a c e s . The s b _ d s p l record i n c l u d e s an sb_format r e c o r d , a data type i d e n t i f i e r (boolean, i n t e g e r , r e a l , s t r i n g , or time), and f o r the f i r s t four data types, the data value b u f f e r . The value r e t u r n e d by the Clock procedure TimSubTO i s used f o r d i s p l a y i n s t e a d of a b u f f e r e d time v a l u e . Data value b u f f e r i n g and channeling i s i n i t i a l i z e d for each sb_dspl r e c o r d by a c a l l to the f u n c t i o n sbLink. The f u n c t i o n 81 c r e a t e s a new sb_dspl r e c o r d , i n i t i a l i z e s i t with the given data, and r e t u r n s with a p o i n t e r to i t . The f u n c t i o n sbLink a l s o i n s e r t s the sb_dspl r e c o r d i n t o a l i n k e d l i s t of s i m i l a r records a s s o c i a t e d with the given screen image. The proper l i s t can then be loaded when i t s screen image becomes a c t i v e , and p e r i o d i c a l l y t r a v e r s e d by an i n t e r n a l screen data f i e l d s updating p r o c e s s . Data d i s p l a y i s enabled f o r boolean, i n t e g e r , r e a l , s t r i n g , or time v a l u e s by c a l l i n g sbTossBoolean, sbTossInteger, sbTossReal, s b T o s s S t r i n g , or sbTossNow r e s p e c t i v e l y , g i v i n g the data value (except f o r time) and sb_dspl r e c o r d p o i n t e r as parameters. If the new data value d i f f e r s from the o l d , and i f the d e s i r e d image i s a c t u a l l y being d i s p l a y e d , the sbToss procedure a l s o s i g n a l s the i n t e r n a l screen data f i e l d updating process ( v i a a source handshake) to t r a v e r s e i t s s b _dspl r e c o r d l i s t . In the case that the l a t t e r process has a lower p r i o r i t y than that of the c a l l e r , the a c t u a l c o n v e r s i o n of the data to ASCII c h a r a c t e r s and sending the r e s u l t to the VDT w i l l not occur immediately. The ScrnBuff screen data f i e l d updating process Update i n i t i a l l y waits on an asynchronous acceptor handshake. The asynchronous form of handshake i s r e q u i r e d so that Update can proceed at i t s own ( p o s s i b l y slow) execution r a t e without impeding the data monitor and c o n t r o l p r o c e s s i n g . Once the handshake i s r e c i e v e d , and while MicroSput continuew to run, the f o l l o w i n g loop i s performed. The ReadKybd procedure CursBorrow i s c a l l e d to o b t a i n use of. the VDT c u r s o r . I f a screen image i s d i s p l a y e d , and i f there i s data w a i t i n g to be sent to i t , the l i n k e d data b u f f e r l i s t i s t r a v e r s e d and ready data f i e l d s 82 u p d a t e d . The R e a d K y b d p r o c e d u r e C u r s R e t u r n r e t u r n s c u r s o r c o n t r o l t o t h e R e a d K y b d p r o c e d u r e s . A f u r t h e r d a t a r e a d y s i g n a l i s a w a i t e d v i a an a s y n c r o n o u s a c c e p t o r h a n d s h a k e , a n d t h e l o o p i s r e p e a t e d . The b a c k g r o u n d s c r e e n image ' t e s t ' i s i n c l u d e d i n t h e M i c r o S p u t s c r e e n l i b r a r y f o r d e v e l o p m e n t p u r p o s e s o n l y ( s e e F i g . 9 ) . T h i s image i s e s p e c i a l l y u s e f u l f o r d e t e r m i n i n g t h e c o o r d i n a t e s a n d s i z e s o f d a t a f i e l d s i n a n e w l y c r e a t e d s c r e e n i m a g e . The t e x t f i l e v e r s i o n o f t h e l a t t e r i s p r i n t e d o u t a n d a l i g n e d o v e r t h e t e s t g r i d on a l i g h t t a b l e , a n d t h e f i e l d c o o r d i n a t e s r e a d f r o m t h e g r i d . I f t h e p r o g r a m m e r remembers t o r e f e r e n c e a l l d a t a f i e l d c o o r d i n a t e s a n d f i e l d s i z e s t o a c o n s t a n t t a b l e a t t h e b e g i n n i n g o f t h e p r o g r a m s o u r c e f i l e , c h a n g e s t o t h e s c r e e n image w i l l be p o s s i b l e w i t h minimum p r o g r a m - e d i t i n g . T e s t e r : T h i s i s t e s t T e s t e r : T h i s i s t e s t T e s t e r : T h i s i s t e s t @ + — 1 — 2~-prompt p rompt p r o m p t z e r o , o n e , t w o , w h i c h w h i c h w h i c h i s i s i s n o t v e r y l o n g f a i r l y l o n g a s v e r y v e r y v e r y y o u c a n l o n g , s o se 1 7 1 + + + + + + 1 + + + + + + + F i g u r e 9 . S c r e e n image d e v e l o p m e n t t e s t p a t t e r n ' t e s t ' . oo to 84 CHAPTER EIGHT General Purpose MicroSput Subprogram Modules The most general purpose programming l e v e l of MicroSput i n c l u d e s the c o m p i l a t i o n u n i t s Clock, ErrMessg, MiscFunc, ExtraScreenOps, and WritCons (see Appendix F f o r l i s t i n g s ) . These modules are u s e f u l f o r programming on any UCSD p-System implementation, and are compatible with but do not use m u l t i t a s k i n g . Clock p r o v i d e s a number of u t i l i t y r o u t i n e s to manipulate data from the system c l o c k . ErrMessg p r o v i d e s a standard method of program t e r m i n a t i o n and e r r o r message d i s p l a y upon d e t e c t e d f a t a l e r r o r s . MiscFunc p r o v i d e s a p o t p o u r r i of mathematical and c h a r a c t e r o p e r a t i o n s . ExtraScreenOps extends the VDT o p e r a t i o n s s u p p l i e d in the p-System u n i t ScreenOps. WritCons performs formatted data w r i t i n g to the VDT. The u n i t Clock, as implemented, i s a c t u a l l y not p o r t a b l e between computer types. For reasons of convenience and speed, some of the Clock r o u t i n e s are w r i t t e n i n assembler. The lack of machine independence i s c o n s i d e r e d to be unimportant, s i n c e MicroSput i s c u r r e n t l y run on only one computer type (the Z80). A l l the Clock d e c l a r a t i o n s , with the exception of TimReset, c o u l d be e a s i l y r e w r i t t e n i n P a s c a l i f the need ever arose. The procedure TimReset i s not used by any other MicroSput u n i t s and c o u l d be implemented as a simple begin-end p a i r . The 32 b i t signed i n t e g e r type tim__rec i s d e c l a r e d by Clock f o r use in system c l o c k readings and m a n i p u l a t i o n s . The standard p-System system c l o c k counts upward from zero at the 85 r a t e of s i x t y counts per second. The tim_rec r e s o l u t i o n , one s i x t i e t h second, i s r e f e r r e d to by MicroSput as one t i c k . Tiiri_rec types may be added, s u b t r a c t e d , compared, or checked a g a i n s t the system c l o c k reading by Clock procedures. They may a l s o be converted to r e a l numbers ( i n seconds) and back again, or to c h a r a c t e r s t r i n g s of hours:minutes:seconds. A r e f e r e n c e time, t = 0 , may be s e t , and the system c l o c k reading r e l a t i v e to that r e f e r e n c e may be o b t a i n e d . The u n i t ErrMessg d e c l a r e s two r o u t i n e s , NoteError and E r r o r N o t e d . The f i r s t i s c a l l e d when a f a t a l MicroSput e r r o r i s d e t e c t e d . Two i n t e g e r s , the e r r o r number to use in a look up t a b l e of e r r o r messages, and an i n f o r m a t i o n number (such as the value of the p-System g l o b a l i o r e s u l t ) to i n s e r t i n t o that message are passed as parameters, A boolean r e q u e s t i n g an immediate MicroSput h a l t i s a l s o passed. If i t i s f a l s e , the e r r o r message w i l l not be w r i t t e n and the program w i l l not be terminated u n t i l a l l p r o c e s s i n g i n a l l MicroSput u n i t s i s s a f e l y shut down. E r r o r s o c c u r r i n g i n an i n i t i a l i z a t i o n code must pass the immediate boolean as t r u e . The e r r o r message i s read from the data f i l e u t i l r s y s t e m . e r r s . T h i s f i l e i s produced by running the program in u t i 1 : s a v e e r r s . c o d e , which uses the t e x t f i l e u t i 1 : u b c e r r o r s . t e x t as i t s source of e r r o r messages. The boolean f u n c t i o n ErrorNoted i s normally f a l s e but becomes true i f and when NoteError i s c a l l e d . The u n i t MiscFunc c o n t a i n s a number of m i s c e l l a n e o u s o p e r a t i o n s which have proven to be needed by two or more MicroSput modules. Base ten l o g a r i t h m and a n t i l o g a r i t h m are p r o v i d e d f o r r e a l numbers. Signum, minimum, maximum, and value 86 l i m i t i n g f u n c t i o n s are a v a i l a b l e f o r both r e a l s and i n t e g e r s . A d d i t i o n and s u b t r a c t i o n of unsigned i n t e g e r s ( u s e f u l when adding addresses) are d e c l a r e d . Routines which convert s i n g l e c h a r a c t e r s or e n t i r e s t r i n g s to upper case are a l s o s u p p l i e d . ExtraScreenOps makes two ext e n s i o n s to the p-System u n i t ScreenOps. The f u n c t i o n MapCommandKey determines the ASCII code of a non-standard c o n t r o l c h a r a c t e r , given i t s ScreenOps symbolic name. The ExtraScreenOps i n i t i a l i z a t i o n code f i l l s a t a b l e of these mappings; c a l l s made a f t e r i n i t i a l i z a t i o n i s complete can pass the boolean parameter as f a l s e to allow MapCommandKey to simply look the code up. MapDate r e t u r n s with the c u r r e n t date i n format day-month-year (e.g. l8-Oct-82), assuming the operator has set that date using the system f i l e r b efore the MicroSput run. Most WritCons procedures are d e c l a r e d i n p a i r s . One of the p a i r has the p r e f i x 'Write' added to i t s name; the other 'Toss'. Write procedures send the data to the VDT screen s t a r t i n g at the c u r r e n t c u r s o r p o s i t i o n , while Toss procedures move the cu r s o r to a given p o s i t i o n and perform the twin W r i t e . Where not f i x e d by the data type, a f i e l d l e n g t h i s s p e c i f i e d i n the procedure parameters: t h i s i s the t o t a l number of c h a r a c t e r s i n c l u d i n g l e a d i n g or t r a i l i n g blanks that w i l l be used i n the w r i t e . S t r i n g s w i l l be l e f t j u s t i f i e d i n the given f i e l d ; a l l other data types w i l l be r i g h t j u s t i f i e d . Write and/or Toss procedures are pro v i d e d for boolean, blank c h a r a c t e r s t r i n g s , i n t e g e r s , r e a l s ( i n f i x e d decimal or s c i e n t i f i c n o t a t i o n s ) , c h a r a c t e r s , and s t r i n g s . 87 CONCLUSIONS The convenience of using MicroSput to operate a PM s p u t t e r i n g system i s e v i d e n t . The computer system has been used r e g u l a r l y by members of the UBC P h y s i c s s p u t t e r i n g group s i n c e i t s e a r l i e s t v e r s i o n i n October 1980. Unwanted d r i f t of independent system parameters i s e l i m i n a t e d . Incremental scanning of one independent parameter may be performed, and a r e c o r d of the e v o l u t i o n of dependent parameters kept and d i s played. The s c i e n t i f i c need f o r computer o p e r a t i o n of the PM s p u t t e r i n g process has a l s o been shown. A number of f a c t o r s such as the t a r g e t e r o s i o n p r o f i l e , magnetic f i e l d s t r e n g t h , outgassing r a t e , and s u b s t r a t e holder geometry are d i f f i c u l t to reproduce each experiment. These f a c t o r s u s u a l l y must be accounted f o r by e m p i r i c a l constants i n known parameter r e l a t i o n s h i p s . The systematic r e c a l i b r a t i o n of the s p u t t e r i n g apparatus each experiment has become a r e g u l a r p a r t of the experimental p r e p a r a t i o n procedures, using MicroSput i n i t s parameter scan mode. As mentioned i n the I n t r o d u c t i o n , computer c o n t r o l of the t a r g e t v o l t a g e has a l s o proven to be an i n v a l u a b l e process method f o r the f a b r i c a t i o n of c l e a r , i n f r a r e d r e f l e c t i v e c o a t i n g s . REFERENCES J.A. Thornton, J . Vac. S c i . Technol. j_5, 171 ( 1 9 7 8 ) , and Thin F i l m Processes, e d i t e d by J.L. Vossen and W. Kern (Academic, New York, 1 9 7 8 ) , Chap. 1 1 - 2 . R.K. Waits, J . Vac. S c i . Technol. JJ5, 179 ( 1 9 7 8 ) , and Thin  F i l m Processes, e d i t e d by J.L. Vossen and W. Kern (Academic, New York, 1 9 7 8 ) , Chap. I I - 2 . D.B. F r a s e r , in Thin F i l m Processes, e d i t e d by J.L. Vossen and W. Kern (Academic, New York, 1 9 7 8 ) , Chap. I I - 3 . R. McMahon, J . A f f i n i t o , and R.R. Parsons, J . Vac. S c i . Technol. 2 0 , 376 ( 1 9 8 2 ) . J.C.C. Fan and F . J . Bachner, Appl. O p t i c s VS, 1012 ( 1 9 7 6 ) . R. McMahon, Sol Note 3 ( S o l a r Energy S o c i t e y of Canada, Winnipeg, 1 9 8 0 ) . S. Maniv, C. Miner, and W.D. Westwood, J . Vac. S c i . Technol. 18, 195 ( 1 9 8 1 ) . Appendix A I n t e r f a c e Part f o r Unit Parameter Page {@L-} Uses ScrnBuff; {@L@} Type ana _ i n f o = are r e c o r d { a l l times chan_in: 1 . . 1 6 ; raw_input: - 1 2 0 0 0 . s e t p t : - 1 2 0 0 0 . . 1 2 0 0 0 maxerr: - 1 . . 24000 ; s t a b l e : boolean; s c a l e _ i n : r e a l end; i n { 12000 { { { t i c k s } analog i n channel number } { unsealed input value } wait f o r reading <> se t p t } by > maxerr } l a s t reading s t a b l e ? } a c u t a l u n i t s / m i l l i v o l t i n C t r l i n f o = rec o r d { a l l times are i n seconds } { measured d ( v a l u e ) / d t per sec } { d e s i r e d c o n t r o l p o i n t } { c a l c ' d d e r i v a t i v e m u l t i p l i e r } s e t _ d s p l : s b _ d s p l _ p t r { s e t p o i n t d i s p l a y i n f o } end; d v a l _ d t : r e a l ; s e t p o i n t : r e a l ; D: r e a l ; param_ptr = param_info @param_info; : record hard_name: s t r i n g [ 8 ] next: param_ptr; name: s t r i n g [ 8 ] ; u n i t s : s t r i n g [ 4 ] ; i d : char; value: r e a l ; h i g h l i m : r e a l ; delay: 0..maxint; warning: boolean; beep: boolean; name_dspl: s b _ d s p l _ p t r v a l _ d s p l : s b _ d s p l _ p t r ; u n i t _ d s p l : s b _ d s p l _ p t r read data: r e a l { f i x e d program l a b e l } parameter l i s t l i n k up } " name } u n i t s } " i d e n t i f i e r } " value } which value mustn't exceed } (min) wait between s e r v i c e s } warning message d i s p l a y e d ? } beep console each s e r v i c e ? } : { name d i s p l a y i n f o } { value " " } : { u n i t s " " } l a t e s t value form read f i l e } Appendix A I n t e r f a c e Part f o r Unit Parameter Page read_next: param_ptr; wr i t e _ n e x t : param_ptr; measure: @ana_info; { c o n t r o l : @ c t r l i n f o { { read data value l i n k up } { w r i t e " " } i f measured, p o i n t t o i n f o } i f c o n t r o l l e d , " " } end; Procedure PrmRead (param: param_ptr); { wait f o r chan_in reading to move from s t a b l e , s c a l e i t , i f c o n t r o l f i n d d v a l _ d t } F u n c t i o n Prmlncrm (param: param_ptr): r e a l ; { c a l c u l a t e d i f f e r e n t i a l c o n t r o l increment f o r param } Procedure PrmShow (param: param_ptr); { send value (& warning message ?) to screen, use up delay t i c k s } Procedure PrmAnaSet (param: param_p.tr); { c a l l - AnaSetBounds f o r measured channel } Procedure PrmPoint ( s e t p t : r e a l ; param: param_ptr); { change given parameter's s e t p o i n t to (bounded) setpt } F u n c t i o n PrmList: param_ptr; { p o i n t to beginning of l i n k e d l i s t of parameters } Procedure Prmlnit (monitor_image: sb_name; x_time, y_time, x_date, y_date, x_warn, y_warn: i n t e g e r ) ; { I n i t i a l i z e u n i t , g ive name of parameter monitor screen image and c o o r d i n a t e s of time, date & warning d i s p l a y : don't c a l l from i n i t i a l i z a t i o n part } F u n c t i o n PrmGet (fixed_name: sb_name): param_ptr; { i n i t i a l i z e named parameter: c a l l a f t e r P r m l n i t } Appendix A I n t e r f a c e Part for Unit Parameter Procedure PrmEdited; { c a l l to f l a g a parameter has been e d i t e d } Appendix A I n t e r f a c e Part f o r Unit ParaiiiUtil Page 1 {@L-} Uses ScrnBuff, Parameter; {@L@} Fun c t i o n PrmNamed (name: sb_name): param_ptr; { r e t u r n with named parameter } Fu n c t i o n PrmPrmpt (x, y: i n t e g e r ; t i t l e : s t r i n g ; must_meas, m u s t _ c t r l : boolean): param_ptr; { PromptCapIn f o r a (measured and/or c o n t r o l l e d ? ) parameter i d , using t i t l e : to s t a r t the prompt; r e t u r n n i l when <esc> typed or not running } Fun c t i o n PrmEdSet: param_ptr; { prompt for & read a parameter s e t p o i n t , r e t u r n with a l t e r e d param } Appendix A I n t e r f a c e Part f o r Unit ParamEdit Procedure PrmEdit; { i n t e r a c t i v e l y e d i t system parameters } Appendix A I n t e r f a c e Part for Unit Walker Page 1 Procedure ParamWalk; { set up f o r walking of a parameter s e t p o i n t between two bounds } Procedure wkHalt; { s a f e l y e x i t from walking process } LD i t . Appendix A I n t e r f a c e Part for Unit ParamSav Page 1 Var param_time: r e a l ; { time of l a t e s t parameter read r e c o r d } Procedure ParamReset; { r e s e t parameter read f i l e } Fu n c t i o n ParamGet (wait_ok: boolean): boolean; { update read f i l e r e cord (wait f o r i t ? ) , r e t u r n true i f not eof } Procedure ParamFile; { set up parameter input & output f i l e s } Procedure p f H a l t ; { s a f e l y shut down w r i t i n g process } Appendix A I n t e r f a c e Part f o r Unit P l o t t e r Procedure PlotSetup; { i n t e r a c t i v e l y set up and perform a p l o t } Procedure p l H a l t ; { shut down p l o t t e r process } Appendix A I n t e r f a c e Part for Unit E12ISR Page { T h i s u n i t i s a memory and p o s i t i o n locked segment i n t e r n a l to E l 2 a n a i o and/or E12digio. It i s not meant to be used otherwise. } Const njumpsx3 =21; { 3 * # e n t r i e s i n i s r jump t a b l e } Var { Assembler data areas: in general t h i s data i s not used by P a s c a l as they may be changed by an i s r during such use. } { Data a c t u a l l y used as Z80 opcodes: } jumptabl: packed array [1..njumpsx3] of 0..255; { jumps to some u t i l i t y r o u t i n e s in e l 2 i s r . a } { Data used by d i g i t a l i s r : } p u l s e : boolean; { d i g i t a l pulse i s on? } c u r r d i g : set of 0..15; { current d i g i t a l output } p l s q u i t : 0..maxint; { lsword of time to turn o f f p u l s e } p l s d a t a , plsmask: set of 0..15; { used to end pulse } { Data used by analog i s r : } anabuff: a r r a y [1..16] of packed record reading: i n t e g e r ; sum_count: 0..255; sum_lsbyte: 0..255; sum_msword: i n t e g e r ; 11 : i n t e g e r ; xO: i n t e g e r ; x 1 : i n t e g e r ; d e l t a _ t : 0..maxint; ready: boolean; s e t p o i n t : i n t e g e r ; maxerror: i n t e g e r ; l a t e s t reading of input } # readings summed for average c a l c ' n l e a s t s i g n i f i c a n t byte of that sum } most " word " " " } lsword of time when dx/dt c a l c ' n done reading at time tO } " t l } 11 -tO, w i l l be >= min_dt } channel i s beyond s e t p o i n t by maxerr? check reading a g a i n s t t h i s value } and set ready i f s t r a y e d beyond } } Appendix A I n t e r f a c e Part f o r Unit E12ISR Page min_dt: 0..255; p r i o r i t y : 0..8; f i l l e r : 0..3; i n v e r t : boolean; newddt: boolean end; { dx/dt:= x1-x0 / t 1 - t 0 ok a f t e r min_dt } { i f < 8, t r i g g e r every 2 * * p r i o r i t y pass } { unused } { i n v e r t t h i s channel's reading? } { dx/dt c a l c ' n updated by l a t e s t i s r ? } Procedure I n i t E 1 2 i s r ; { must be c a l l e d by E12dig/anaio i n i t i a l i z a t i o n } Appendix A I n t e r f a c e Part f o r Unit E12DigI0 Page 1 { d i g i t a l input/output r o u t i n e s f o r E12 ( a l i a s Grey Box); outputs 0..7 are i n i t i a l i z e d & h a l t e d high, 8:.15 low } Type digwait = 0..maxint; d i g i t a l = set of 0..15; { e.g. [1..3,7] means b i t s 1, 2, 3, and 7 are s e t , 0, 4, 5, 6 and 8..15 are re s e t } Procedure DigRead (Var data: d i g i t a l ) ; { data:= input } Procedure DigWrite (data, mask: d i g i t a l ) ; { output:= (data i n t e r s e c t mask) union (current output i n t e r s e c t (complement(mask)) ) } Fu n c t i o n DigPStat: digwait; { number of t i c k s remaining i n curent pulse ( i f any) } Procedure DigPulse (data, mask: d i g i t a l ; t i c k s : d i g w a i t ) ; { DigWrite (data, mask). A f t e r t i c k s / 60 seconds, i n t e r r u p t w i l l DigWrite (complement(data), mask). Di g P u l s e must not be c a l l e d when DigPStat i s > 0 } Procedure DigStatus (Var data: d i g i t a l ) ; { data:= c u r r e n t output } VD VD Appendix A I n t e r f a c e Part for Unit E12AnaI0 Page 1 { analog input/outupt r o u t i n e s f o r E12 ( a l i a s Grey Box); outputs are i n i t i a l i z e d & h a l t e d to 0. Note that analog input can ONLY be done using i n t e r r p u t s } Type ana_in_chan = 1..16; ana_in_range = - 12000..12000; ana_err_range = -1 .. 24000; ana_mindt_range = 1..255; ana_dx_range = -24000..24000; ana_dt_range = K.maxint; ana_chan_flags = packed a r r a y [ana_in_chan] of boolean; a n a _ p r i o r i t i e s = packed a r r a y [ana_in_chan] of 0..8; ana_chan_set = set of 0..15; a n a _ i n _ t a b l e = a r r a y [ana_in_chan] of packed r e c o r d reading: ana_in_range; sum_lsbyte, count: 0..255; sum_msword: i n t e g e r end; ana_out_chan = 1..8; ana_out_range = 0..4095; ana out t a b l e = a r r a y [ana out chan] of ana out range; — — • — —. — — Procedure AnalnGo ( i n v e r t s : ana_chan_flags; p r i o r i t i e s : a n a _ p r i o r i t i e s ) ; { Zero a l l i n t e r n a l input values and i n t e g r a t i o n sum b u f f e r s . Turn on i n t e r r u p t d r i v e n analog input p o l l i n g , p a s s i n g i n v e r t input value booleans and channel p r i o r i t y v a l u e s . At l e a s t one channel's p r i o r i t y must be 0 (highest p r i o r i t y ) . Channels of p r i o r i t y 8 w i l l not be t r i g g e r e d . } Procedure AnaSetBound (channel: ana_in_chan; s e t p o i n t : ana_in_range; maxerror: ana_err_range; o o Appendix A I n t e r f a c e Part f o r Unit E12AnaI0 Page mindt: ana_mindt_range); { Set analog input channel s e t p o i n t and maxerror, minimum dt f o r d/dt c a l c u l a t i o n , r e s e t channel ready. I n i t i a l l y a l l s e t p o i n t s are 0, a l l maxerrors are - 1 , and a l l mindts are 30 t i c k s . } Procedure AnaReady (Var ready: ana_chan_set); { Detect which analog inputs have been read s i n c e i n i t i a l i z a t i o n or the l a s t AnaReady or AnalnStatus, and c u r r e n t l y d i f f e r from t h e i r s e t p o i n t by more than t h e i r maxerror. Note that channels are numbered from 0 to 15 here! } Procedure AnaRead (channel: ana_in_chan; Var reading: ana_in_range; Var d e l t a _ r e a d i n g : ana_dx_range; Var d e l t a _ t i m e : ana_dt_range); { Read current value of an analog input, and the d i f f e r e n c e s i n value and time of the l a s t two readings. } Procedure AnalnStatus (Var ana_inputs: a n a _ i n _ t a b l e ) ; { Read a l l c u r r e n t values of analog inputs, dump i n t e g r a t i o n sums. } Procedure AnalnStop; { Turn o f f i n t e r r u p t d r i v e n analog input p o l l i n g . } Procedure AnaWrite (data: ana_out_range; channel: ana_out_chan); { Send data to analog output channel. } F u n c t i o n AnaOutRead (channel: ana_out_chan): ana_out_range; { Read current value of analog output channel. } Procedure AnaOutStatus (Var ana_outputs: a n a _ o u t _ t a b l e ) ; { Read a l l current values of analog outputs. } Appendix A I n t e r f a c e Part f o r Unit E12Sched Page 1 Const s c h _ h i b i t = 7; { highest numbered d i g i t a l input b i t } sch_hichan =16; { highest numbered analog input channel } Type sch_bitno = 0 . . s c h _ h i b i t ; sch_channo = 1..sch_hichan; Procedure E12Start; { i n i t i a l i z e E12 d evice p o l l i n g } Procedure WaitBit ( b i t : sch_bitno; value: boolean); { Wait for a d i g i t a l input b i t of given v a l u e . S u c c e s s i v e c a l l s are queued. } Procedure WaitAnalog (chan: sch_channo); { Wait for analog input chan to d i f f e r from i t s s e t p o i n t by more than +/- i t s maxerror. Successive c a l l s are queued. } o Appendix A I n t e r f a c e Part f o r Unit TrigAna Page Var ana_names: array [1..16] of s t r i n g [ 8 ] ; Procedure T r i g l n i t ; { Read channel i n v e r t and p r i o r i t i e s from d i s k , s t a r t t r i g g e r i n g } Procedure TrigSetup; { I n t e r a c t i v e l y change analog t r i g g e r p r i o r i t i e s } o A p p e n d i x A I n t e r f a c e P a r t f o r U n i t P l o t U t i l P a g e P r o c e d u r e P l o t B o u n d s ( x m i n , xmax, y m i n , ymax: r e a l ) ; { s e t s p l o t x 6 y r a n g e s } P r o c e d u r e P l o t ( x , y : r e a l ) ; { move pen t o x , y , w a i t f o r i t t o s t o p } P r o c e d u r e P l o t L i f t ; { l i f t pen o f f c h a r t } P r o c e d u r e P l o t D r o p ; { d r o p pen o n t o c h a r t } P r o c e d u r e P l o t A x e s ; { p l o t r e c t a n g l e o f s i z e b o u n d s } o A p p e n d i x A I n t e r f a c e P a r t f o r U n i t S t a r t e r P a g e 1 T y p e s t r t _ n a m e = s t r i n g [ 8 ] ; P r o c e d u r e S t r t l n f o ( u n i t _ n a m e , p r o c e s s _ n a m e : s t r t _ n a m e ; v a r s t a c k , p r i o : i n t e g e r ; c a l l _ f r o m _ i n i t i a l i z a t i o n _ p a r t : b o o l e a n ) ; { l o o k up s t a c k s i z e and p r i o r i t y f o r named p r o c e s s ( f r o m b o d y o f u n i t o r f rom i n i t i a l i z a t i o n p a r t ? ) } o Appendix A I n t e r f a c e Part for Unit DataBus Page { type handshake v a r i a b l e s must be manipulated only by c a l l s to DataBus procedures } Type handshake = r e c o r d l o c k : semaphore; n_sync_acpt: 0..maxint; n_async_acpt: 0..maxint; a t t e n t i o n : semaphore; rea d y _ f o r _ d a t a : semaphore; d a t a _ v a l i d : semaphore; data_accepted: semaphore end; { Any number of source and acceptor processes, with any convenient p r i o r -i t i e s , may share one handshake. The source handshake waits f o r synch-ronous acceptors o n l y . } Procedure AcptJoin (var h: handshake); { c a l l to accept f i r s t synchronous data } Procedure AcptHshk (var h: handshake; synchronous: b'oolean); { c a l l to accept asynchronous or other than f i r s t * synchronous data } Procedure AcptQuit (var h: handshake); { c a l l upon acceptance and use of l a s t d e s i r e d synchronous data } Procedure SrceLock (var h: handshake); { c a l l to exclude a l l other sources from handshake, allow data change } Procedure SrceHshk (var h: handshake; unlocked: boolean); { c a l l a f t e r data changed—unlocked i s true i f f SrceLock wasn't c a l l e d f i r s t } A p p e n d i x A I n t e r f a c e P a r t f o r U n i t D a t a B u s P r o c e d u r e H s h k l n i t ( v a r h : h a n d s h a k e ) ; { i n i t i a l i z e t y p e h a n d s h a k e } Page 2 o Appendix A I n t e r f a c e Part for Unit Schedule Page 1 Type sch_chset = set of char; Var running: boolean; { The c o n d i t i o n of a l l repeating loop p r o c e s s e s - - r e s e t to end the program and shut down a l l p r o c e s s i n g } Procedure P o l l l n p u t s ; { S i g n a l p o l l i n g process to check c l o c k , keyboard, and SrceHshk the e x t e r n a l device p o l l } Procedure DvceJoin; { J o i n e x t e r n a l device p o l l synchronous a c c e p t o r s } Procedure DvceAcpt (synchronous: boolean); { Accept e x t e r n a l device p o l l } Procedure DvceQuit; { Leave e x t e r n a l device p o l l synchronous a c c e p t o r s } Procedure WaitTick ( t i c k s : i n t e g e r ) ; { Wait for t i c k s / 6 0 seconds ( u n l i m i t e d number of c a l l e r s ) } F unction WaitChar (chars: s c h _ c h s e t ) : char; { Wait for a console c h a r a c t e r in the set chars ( c a l l e r s are queued and w i l l be s a t i s f i e d in t h e i r c a l l sequence) } o 00 Appendix A I n t e r f a c e Part f o r Unit ReadKybd Page { Routines f o r reading keyboard, a l l o w i n g Schedule to s i g n a l competing processes while w a i t i n g f o r keyboard c h a r a c t e r } Type rk_chset = set of char; r k _ l o n g _ s t r i n g = s t r i n g [ 2 5 5 ] ; Procedure CursBorrow; Procedure CursReturn; { A process wanting to write to the screen must CursBorrow, do the wri t e without a task switch, CursReturn } Fun c t i o n ReadCharln (return_on_match: r k _ c h s e t ) : char; Function FetchCharln (x,y: i n t e g e r ; return_on_match: r k _ c h s e t ) : char; { Return with char when a char i n r e t u r n on_match has been typed. The char i s not echoed to the screen. T Function ReadCapIn (return_on_match: r k _ c h s e t ) : char; Function FetchCapIn (x,y: i n t e g e r ; return_on_match: r k _ c h s e t ) : char; Function PromptCapIn (x,y: i n t e g e r ; prompt: rk l o n g _ s t r i n g ; return_on_match: rk_chsetT: char; { Return with char when a char i n return_on_match has been typed. A l p h a b e t i c chars are converted to upper case. The char i s not echoed to the screen. In t h i r d case, f i r s t send prompt to x,y, broken i n t o s e v e r a l pieces by ' ' i f necessary, r o t a t i n g the pie c e s when '?' i s typed } Function ReadBoolean: boolean; Function FetchBoolean (x,y: i n t e g e r ) : boolean; { ReadCapIn ( [ ' T ' , ' F ' ] ) , echo 'true ' or ' f a l s e ' } Function Readlnteger (field,min,max: i n t e g e r ) : i n t e g e r ; Function F e t c h l n t e g e r (x,y,field,min,max: i n t e g e r ) : i n t e g e r ; { Return with an inte g e r between min and max r i g h t j u s t i f i e d i n a f i e l d of given width } Appendix A I n t e r f a c e Part f o r Unit ReadKybd Page Fun c t i o n ReadReal ( f i e l d , d e c _ f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; F u n c t i o n FetchReal ( x , y , f i e l d , d e c _ f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; { Return with a r e a l between min and max r i g h t j u s t i f i e d i n a f i e l d of given width with d e c _ f i e l d f o l l o w i n g the decimal } Function ReadFloat ( f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; F u n c t i o n F e t c h F l o a t ( x , y , f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; { Return with a r e a l between min and max read as mantissa and exponent } Procedure ReadString (var s: s t r i n g ; f i e l d : i n t e g e r ) ; Procedure F e t c h S t r i n g (x,y: i n t e g e r ; var s: s t r i n g ; f i e l d : i n t e g e r ) ; { Return with new s t r i n g of length <= f i e l d i n v a r i a b l e s } Procedure r k H a l t ; { C a l l upon program end to re t u r n from a l l CursBorrow waits } Appendix A I n t e r f a c e Part f o r Unit ScrnBuff Page { process data d i s p l a y and screen image l i f o s t a c k i n g r o u t i n e s } Type sb_name = s t r i n g [ 8 ] ; sb_prmt_no = 0..255; sb_prmt = s t r i n g f 2 5 5 ] ; sb_prmt_ptr = @sb_prmt; sb_format = packed record s c r n _ v a l i d : boolean; enabled: boolean; new_data: boolean; x: 0..79; y: 0..23; f i e l d : 0..80; d e c _ f i e l d : 0..79; f l o a t : boolean end; sb_kind = (sb_bool, s b _ i n t , sb_re, sb_stng, sb_now); sb _ d s p l _ p t r = @sb_dspl; sb_dspl = record n e x t _ d s p l : s b _ d s p l _ p t r ; format: sb format; { screen image d i s p l a y e d ? } { data d i s p l a y enabled? } { d i s p l a y e d value out of date? } { c o l of s t a r t of data f i e l d } { row of data f i e l d } { s i z e of " " } for sb_re: # decimal p l a c e s } " ": s c i e n t i f i c n o t a t i o n } { case sb sb' sb" kind: bool: i n t : r e : sb_stng: end; sb_kind of (b: boolean) ( i : i n t e g e r ) ( r : r e a l ) ; ( s : s t r i n g ) { i n t e r n a l l i n k u p } { d i s p l a y i n f o r m a t i o n } { data type, value } F u n c t i o n sbLink { Create the have maximum (image: sb_name; fmt: sb_format; k: s b _ k i n d ) : s b _ d s p l _ p t r ; named kind of data, i n i t i a l i z e format (type sb_stng w i l l s length of f m t . f i e l d ) , l i n k i n t o image's d i s p l a y l i s t } { sbToss procedures: i f value <> d a t a _ p t r . v a l u e then copy value, Toss Appendix A I n t e r f a c e Part f o r Unit ScrnBuff Page 2 as soon as screen image i s v a l i d ; s t r i n g uses v a r i a b l e value to reduce needed stack s i z e ; now uses c l o c k reading - TO at t o s s time } Procedure sbTossBoolean (value: boolean; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbTossInteger (value: i n t e g e r ; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbTossReal (value: r e a l ; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sb T o s s S t r i n g (var value: s t r i n g ; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbTossNow ( d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbDisable ( d a t a _ p t r : sb_dspl p t r ) ; { d i s a b l e d i s p l a y (sbToss re-enables) T Procedure ScrnEnter (name: sb_name); { Sc r n C l e a r , a c t i v a t e named screen image (or blank screen i f name i s 'NIL'), ScrnRefresh i t } Fun c t i o n ScrnPrompt (prompt_num: sb_prmt_no): sb_prmt_ptr; { P o i n t to given prompt ( >= 0 ) of a c t i v e screen image } Procedure ScrnClear; { s c C l r S c r e e n (and note a c t i v e screen not v a l i d ) } Procedure ScrnRefresh; { Write a c t i v e screen image l i n e s 1..23 ( c l e a r screen i f none) } Procedure ScrnReturn; { S c r n C l e a r , r e - a c t i v a t e whatever image was a c t i v e before l a s t ScrnEnter, ScrnRefresh i t } Procedure sbHalt; { c a l l to h a l t data d i s p l a y p r o c e s s i n g } Appendix A In t e r f a c e Part f o r Unit Clock Page 1 { c l o c k reading u t i l i t i e s } Type tim_rec = record hiword, loword: int e g e r end; { two's complement 32 b i t i n t e g e r } tim_hms = s t r i n g [ 8 ] ; Var tim_ovflw: boolean; { TimAdd & TimMinus overflow f l a g } Procedure TimReset; { reset system c l o c k to 0 } Procedure TimAdd (var sum: tim_rec; a,b: t i m _ r e c ) ; { sum:= a + b } Procedure TimMinus (var d i f f : tim_rec; a,b: t i m _ r e c ) ; { d i f f : = a - b } Function Tim_aLTb (a,b: t i m _ r e c ) : boolean; { r e s u l t : = a < b } Function TimArrived ( t : t i m _ r e c ) : boolean; { r e s u l t : = t <= c l o c k reading } Function TimlnSeconds ( t : t i m _ r e c ) : r e a l ; { r e s u l t : = t in seconds } Procedure TimOfSeconds (var t : tim_rec; r : r e a l ) ; -' { t:= r, where r i s in seconds } Procedure TimlnHMS (var hms: tim_hms; t : t i m _ r e c ) ; { convert t to hh:mm:ss, 00:00:00 <= hms <= 99:59:59 } Procedure TimSetTO; Appendix A I n t e r f a c e Part f o r Unit Clock { read c l o c k , l e t r e s u l t be known as tO } Procedure TimSubTO (var t : t i m _ r e c ) ; { r e t u r n with c l o c k reading - tO } Page Appendix A I n t e r f a c e Part f o r Unit ErrMessg Page 1 Function ErrorNoted: boolean; { True i f f NoteError has been c a l l e d . } Procedure NoteError (n, i n f o : i n t e g e r ; immediate: boolean); { Write n'th e r r o r message ( i n c l u d i n g i n f o as part of the message) from e r r o r l o g upon program h a l t (or immediately & h a l t ) . } Appendix A I n t e r f a c e Part f o r Unit MiscFunc Page { power of 10 f u n c t i o n s } F u n c t i o n TenToThe (x: r e a l ) : r e a l ; { I0**r } • Function Log ( r : r e a l ) : r e a l ; { base 10 l o g a r i t h m } { signum f u n c t i o n s } F u n c t i o n rSgn ( r : r e a l ) : r e a l ; { i f r<0.0 then -1.0 e l s e 1.0 } Function iSgn ( i : i n t e g e r ) : i n t e g e r ; { i f i<0 then -1 e l s e 1 } { min and max f u n c t i o n s } Function rMin (a,b: r e a l ) : r e a l ; { i f a<b then a e l s e b } F u n c t i o n rMax (a,b: r e a l ) : r e a l ; { i f a>b then a e l s e b } Function iMin (a,b: i n t e g e r ) : i n t e g e r ; { i f a<b then a e l s e b } F u n c t i o n iMax (a,b: i n t e g e r ) : i n t e g e r ; { i f a>b then a e l s e b } { l i m i t i n g f u n c t i o n s } Function rBounded ( r , min, max: r e a l ) : r e a l ; { rMax (min, rMin(r,max)) } Function rAbsBndd ( r , bound: r e a l ) : r e a l ; { rBounded ( r , -bound, bound) } Function iBounded ( i , min, max: i n t e g e r ) : i n t e g e r ; { i n t e g e r rBounded } Function iAbsBndd ( i , bound: i n t e g e r ) : i n t e g e r ; { i n t e g e r rAbsBndd } { unsigned int e g e r f u n c t i o n s } Function usiAdd (a,b: i n t e g e r ) : i n t e g e r ; { a + b } F u n c t i o n usiMinus (a,b: i n t e g e r ) : i n t e g e r ; { a - b } { c h a r a c t e r f u n c t i o n s } Function UpperChar (c: c h a r ) : char; { change c to upper case } { s t r i n g f u n c t i o n s } Procedure Uppercase (Var s: s t r i n g ) ; { change s to upper case } Appendix A I n t e r f a c e Part f o r Unit E x t r a S c r Page 1 { Ex t r a ScreenOps r o u t i n e s } {@L-} Uses ScreenOps; {@L@} Function MapCommandKey (command: sc_key_command; c a l l _ f r o m _ i n i t i a l i z i o n _ p a r t : b o o l e a n ) : char; { Inverse of scMapCrtCommand: c a l l s to t h i s f u n c t i o n must have the second parameter true i f made from an i n i t i a l i z a t i o n p art } Procedure MapDate (var d a t e : * s t r i n g ) ; { return with the c u r r e n t date as 'dd-mmm-yy' } Appendix A I n t e r f a c e Part f o r Unit WritCons { procedures to send formatted values to c o n s o l e : } Procedure WriteBoolean (b: boolean); Procedure TossBoolean (x, y: i n t e g e r ; b: boolean); { w r i t e a boolean value as 'true ' or ' f a l s e ' } F u n c t i o n WriteNot (b: boolean): boolean; F u n c t i o n TossNot (x, y: i n t e g e r ; b: boolean): boolean; { r e s u l t : = not b, WriteBoolean ( r e s u l t ) } Procedure WriteBlanks ( f i e l d : i n t e g e r ) ; Procedure TossBlanks (x, y, f i e l d : i n t e g e r ) ; { w r i t e f i e l d blanks } Procedure WriteErase ( f i e l d : i n t e g e r ) ; Procedure TossErase (x, y, f i e l d : i n t e g e r ) ; { WriteBlanks ( f i e l d ) , r e t u r n cursor to s t a r t i n g p o s i t i o n } Procedure W r i t e L e f t ( f i e l d : i n t e g e r ) ; { w r i t e f i e l d backspaces without e r a s i n g } Procedure WriteBackspaces ( f i e l d : i n t e g e r ) ; { w r i t e f i e l d backspaces, e r a s i n g c h a r a c t e r s along the way } Procedure T o s s l n t e g e r (x, y, i , f i e l d : i n t e g e r ) ; { move cursor to x,y and write i r i g h t j u s t i f i e d i n a f i e l d of given width } Procedure WriteReal ( r : r e a l ; f i e l d , d e c _ f i e l d : i n t e g e r ) ; Procedure TossReal (x, y: i n t e g e r ; r: r e a l ; f i e l d , d e c _ f i e l d : i n t e g e r ) ; { w r i t e r r i g h t j u s t i f i e d i n a f i e l d of width f i e l d with d e c _ f i e l d a f t e r the decimal. If d e c _ f i e l d = 0 , the r e a l w i l l be w r i t t e n as an i n t e g e r . r i s rounded to the decChar'th d i g i t before w r i t i n g } Procedure W r i t e F l o a t ( r : r e a l ; f i e l d : i n t e g e r ) ; Appendix A I n t e r f a c e Part f o r Unit WritCons Page 2 Procedure T o s s F l o a t (x, y: i n t e g e r ; r : r e a l ; f i e l d : i n t e g e r ) ; { w r i t e r i n s c i e n t i f i c n o t a t i o n r i g h t j u s t i f i e d a f i e l d of blanks } Procedure TossChar (x, y: i n t e g e r ; ch: c h a r ) ; { send c u r s o r to x,y and w r i t e ch: 1 } Procedure W r i t e S t r i n g (s: s t r i n g ; f i e l d : i n t e g e r ) ; Procedure T o s s S t r i n g (x, y: i n t e g e r ; s: s t r i n g ; f i e l d : i n t e g e r ) ; { w r i t e s ( i f f i e l d > 0 then l e f t j u s t i f i e d i n a f i e l d of blanks) } Appendix B Compiler L i s t i n g of Program S p u t t e r Page 1 3 0 0: d 1 4 2 1 : d 1 5 2 1 : d 1 232 2 1 : d 1 4 15 2 1 : d 1 56 1 2 1 : d 1 586 2 1 : d 1 597 2 1 : d 1 598 2 1 : d 1 599 2 1 : d 1 600 2 1 : d 1 601 2 1 : d 1 602 2 1 : d 1 603 2 1 • d 1 604 2 1 d 1 605 2 1 d 1 606 2 1 d 1 607 2 1 d 1 608 2 1 d 10 609 2 1 d 13 6 10 2 1 d 15 61 1 2 1 d 16 612 2 1 d 19 6 13 2 1 d 20 614 2 1 d 28 615 2 1 d 28 6 16 2 1 d 28 617 2 1 d 1 618 2 1 d 1 619 2 1 d 1 620 2 1 d 1 62 1 2 1 d 1 622 2 1 d 1 623 2 1 d 1 624 2 1 d 1 625 2 1 1 d 1 626 2 1 1 :d 1 627 2 1 1 : d 2 628 21 1 :d 5 629 2 1 1 :d 6 630 2 1 1 :d 6 631 2 1 2 :0 0 632 2 1 2 : 1 0 633 21 1 :0 . 0 634 2 1 1 :0 0 635 21 1 :d 1 636 2d 3 :0 0 637 2 1 3 : 1 0 638 2 1 3 : 1 3 {$L remout:} Program S p u t t e r ; <$L-> <$L-> <$L-> <$L-> Uses ScreenOps, E x t r a S c r . Schedule. ReadKybd. S c r n B u f f . <$L<5>} MiscFunc, E12digI0. E12AnaI0. T r i g A n a , WritCons. {$L@> C l o c k , Parameter, P a r a m U t i l , ParamEdit, Walker. <$Lia} ParamSave. P l o t t e r , <$L®> <$U ut i 1 : s t a r t e r . code) S t a r t e r ; {$L(S} Const x_time = - 17 y time = x_date = - 17 y date = x warn = = 1 1 y warn = hi _ g a s = = 2; { h i g h e s t Type gas_num -= 0. h i _gas; 17 < d i s p l a y p o s i t i o n f o r time > { " " " date > { " " - . " warning } Var s p l y _ c t r l , c u r r e n t , v o l t a g e , power, anode, p r e s s u r e . r f _ b i a s , e x t r a l . e x t r a 2 : param_ptr; gas: array[gas_num] of param_ptr; power_ready: semaphore; power_noted: boolean;, b a c k l a s h : array[gas_num] of i n t e g e r ; com: char; C t r l . d C t r l d i . d C t r l dV. dCtrl_dW: r e a l ; P r o cess CurrTask; P r o c e s s V o l t T a s k ; P r o c e s s WattTask; Process PresTask; Process GasTask (n forward; forward; forward; forward; gas_num) forward; P r o c e s s MeasTask (param: param_ptr); forward; Segment Procedure S p u t l n i t ; Const u_name = 'Sputter'; Var p i d : p r o c e s s i d ; n, s t a c k , p r i o : i n t e g e r ; num: s t r 1 n g [ 1 ]; Procedure G e t S t r t l n f o Begi n S t r t l n f o (u_name, param® End; < of G e t S t r t l n f o > (param: param_ptr); hard name, stack, pr i o. f a 1se) Procedure MeasStrt (param: param_ptr); Begin G e t S t r t l n f o (param); s t a r t (MeasTask (param). p i d . s t a c k , p r i o ) O Appendix B Compiler L i s t i n g of Program S p u t t e r Page 2 639 2 1 1 0 0 640 2 1 1 0 0 64 1 2 1 1 0 0 642 21 1 1 0 643 2 1 1 1 18 644 2 1 1 1 32 645 21 1 1 43 646 21 1 1 54 647 21 1 1 65 648 2 1 1 1 76 649 2 1 1 1 87 650 2 1 1 1 98 65 1 21 1 2 107 652 2 1 1 3 107 653 2 1 1 3 1 18 654 2 1 1 2 158 655 2 1 1 1 167 656 2 1 1 1 178 657 21 1 1 189 658 21 1 1 200 659 21 1 1 212 660 2 1 1 1 2 15 661 2 1 1 1 232 662 21 1 1 235 663 2 1 1 1 252 664 21 1 1 255 665 21 1 1 272 666 2 1 1 1 275 667 2 1 1 1 278 668 2 1 1 1 295 669 2 1 1 1 326 670 2 1 1 2 335 67 1 2 1 1 3 335 672 2 1 1 3 346 673 21 1 2 367 674 21 1 1 372 675 21 1 1 375 676 21 1 1 378 677 21 1 1 381 678 21 1 0 0 679 2 1 1 0 0 680 2 1 1 0 0 681 2 1 d 1 682 26 1 d 1 683 26 1 d 1 684 26 2 0 0 685 26 2 1 0 686 26 2 1 4 687 26 2 1 68 688 26 1 0 0 dCtrl_dW: x date. End; { of MeasStrt } Begin < * * * S p u t l n i t *** } d C t r l _ d I : = 5.6; dCtrl_dV:= 0.40; P r m l n i t ('Sputter'. x_time. y_time, s p l y _ c t r l ; = PrmGet ( ' s p l y e t r 1 ' ) ; c u r r e n t : = PrmGet ( ' c u r r e n t ' ) ; v o l t a g e : = PrmGet ( ' v o l t a g e ' ) ; power : = PrmGet ('power'); anode:= PrmGet ('anode'); pressure:= PrmGet ( ' p r e s s u r e ' ) ; f o r n:= 0 to h i _ g a s do Beg i n s t r (n. num ) : gas[n]:= PrmGet (concat ('gas[',r End; { of f o r ) r f _ b i a s : = PrmGet ('rf b i a s ' ) ; extra1:= PrmGet (' e x t r a t ' ); extra2:= PrmGet ( ' e x t r a 2 ' ) ; s e m i n i t (power_ready, 0) G e t S t r t l n f o ( c u r r e n t ) ; s t a r t (CurrTask, p i d . s t a c k , G e t S t r t l n f o ( v o l t a g e ) ; s t a r t ( V o l t T a s k , p i d , st a c k , G e t S t r t l n f o (power); s t a r t (WattTask, p i d , st a c k , MeasStrt (anode); G e t S t r t l n f o ( p r e s s u r e ) : s t a r t (PresTask, p i d , s t a c k , p r i o ) ; b a c k l a s h [ 0 ] : = 23;* 'back 1ash[ 1 ] : = 67; f o r n:= 0 to h i _ g a s do Begin G e t S t r t l n f o ( g a s ( n ] ) ; s t a r t (GasTask ( n ) , p i d . s t a c k , p r i o ) End; ( of f o r ) MeasStrt ( r f _ b i a s ) ; MeasStrt ( e x t r a l ) ; MeasStrt ( e x t r a 2 ) ; S c r n E n t e r (u_name) End; < of Segment S p u t l n i t > 0.4; date, warn, y_warn); ]' )) power_noted:= t r u e ; p r i o ) ; p r i o ) ; p r i o ) ; b a c k l a s h [ 2 ] : = 22; Segment Procedure S p u t E d i t (c:- c h a r ) : Procedure E d i t D C t r l ( i d : c h a r ; var { e d i t supply c o n t r o l g a i n ) Beg i n s c E r a s e T o E o l (0.0); w r i t e ( ' d C t r l / d ' , i d , ' ['. d C t r l d C t r l _ d x : = ReadFloat (8, 1.0E-30, End; { of E d i t D C t r l > d c t r 1 dx: r e a l ) ; dx:8, ' ] 1 .0E30) Appendix B Compiler L i s t i n g of Program S p u t t e r Page 689 26 1 0 0 B e g i n 690 26 1 1 0 i f c = ' E ' 691 26 1 1 1 then Case PromptCapIn (0, 0. 692 26 1 2 8 ' E d i t : P a r a m e t e r s T ( r i g g e r s d . c . S ( u p p l y R ( e t u r n ' , 693 26 1 2 13 ['P','T','S','R']) of 694 26 1 2 25 ' P ' : PrmEdi t; 695 26 1 2 30 ' T ' : Tr i gSetup: 696 26 1 2 35 'S': Case PromptCapIn (0, 0, 697 26 t 3 38 'Supply Gain: H c u r r e n t V ( o l t a g e Wfpower', 698 26 1 3 43 [ ' I ' , 'V. 'W]) of 699 26 1 3 55 ' I ' : E d i t D C t r l ('I'. d C t r 1 _ d I ) : 700 26 1 3 63 'V: E d i t D C t r l ('V. d C t r l _ d V ) ; 701 26 1 3 7 1 'W: E d i t D C t r l {'VI', dCtrl_dW) 702 26 1 3 75 End { of 'M' > 703 26 1 2 82 End { o f 'E' } 704 26 1 1 87 e l s e Begin 705 26 1 3 89 S c r n C l e a r ; 706 26 1 3 91 com:= PromptCapIn (0, 0, 707 26 1 3 94 ' R f e t u r n to or <esc>ape from M i c r o S p u t : ' , 708 26 1 3 99 tMapCommandKey (sc_escape_key, f a l s e ) , ' R ']); 709 26 1 3 1 19 i f (com = 'R') and r u n n i n g then S c r n R e f r e s h 7 10 26 1 2 130 End { of '0' > 7 1 1 26 1 0 0 End; { of Segment S p u t E d i t ) 712 26 1 0 0 713 26 1 0 0 714 26 1 0 0 Procedure D i s a b l e C t r l (param: param_ptr); 715 2 1 d 1 7 16 2 1 d 1 { d i s a b l e c o n t r o l of param ( c a l l o n l y when i n ' S p u t t e r ' s c r e e n image) 7 17 2 8 0 0 Begin 7 18 2 8 1 0 with param® . c o n t r o l @ . s e t _ d s p l <°>. forma t do 7 19 2 8 2 7 Beg i n 720 2 8 3 7 enabled:= f a 1se; 721 2 8 3 12 TossBlanks (x, y, f i e l d ) 722 2 8 2 26 End { of i f , with } 723 2 1 0 0 End; { of D i s a b l e C t r l > 724 2 1 0 0 725 2 1 0 0 726 2 1 d 1 Procedure G e t S e t p o i n t s ; 727 2 9 d 1 Var param: param_ptr: 728 2 9 0 0 Beg i n 729 2 9 1 0 Repeat 730 2 9 2 0 param:= PrmEdSet; 731 2 9 2 5 i f (param = c u r r e n t ) or (param = v o l t a g e ) 732 .2 9 2 1 1 or (param = power) then 733 2 9 3 18 Beg i n 734 2 9 4 18 i f param <> c u r r e n t then D i s a b l e C t r l ( c u r r e n t ) ; 735 2 9 4 25 i f param <> v o l t a g e then D i s a b l e C t r l ( v o l t a g e ) ; 736 2 9 4 32 i f param <> power then D i s a b l e C t r l (power) 737 2 9 3 37 End { of param i s s u p p l y } 738 2 9 1 39 Unt i1 param = n i l ; Appendix B Compiler L i s t i n g of Program S p u t t e r Page 4 739 2 1 0 0 End: { of G e t S e t p o i n t s } 740 2 1 0 0 74 1 2 1 0 0 742 2 1 d 1 Procedure PowerAttn; . 743 2 10 0 0 Beg i n 744 2 10 1 0 i f power noted then 745 2 10 2 3 Beg i n 74S 2 10 3 3 power_noted:= f a l s e ; 747 2 10 3 6 s i g n a l (power_ready) 748 2 10 2 9 End { of i f } 749 2 1 0 0 End; { of PowerAttn > 750 2 1 0 0 751 2 1 0 0 752 2 1 d 1 Procedure C t r l S p l y ( d C t r l : r e a l ) ; 753 2 11 d 1 Const chan_out = 8; 754 2 11 0 0 Beg i n 755 2 11 1 0 with s p l y c t r l @ do 756 2 11 2 2 Begin 757 2 11 3 2 value:= rBounded ( v a l u e + d C t r l , 0.0, 10.0) 758 2 11 3 23 AnaWrite (round (409.5*value ) , chan_out); 759 2 11 3 44 delay:= 0; 760 2 11 3 54 i f r u nning then PrmShow ( s p l y _ c t r l ) 761 2 11 2 60 End < of w i t h > 762 2 1 0 0 End; < of C t r l S p l y > 763 2 1 0 0 764 2 1 0 0 765 2 1 d 1 P r o c e s s CurrTask; 766 2 2 0 0 Beg 1 n 767 2 2 1 2 wh i1e runn i ng do 768 2 2 2 7 Beg i n 769 2 2 3 7 PrmRead ( c u r r e n t ) ; 770 2 2 3 1 1 C t r l S p l y ( d C t r l _ d I * Prmlncrm ( c u r r e n t ) ) ; 77 1 2 2 3 23 PowerAt tn; 772 2 2 3 25 i f r u nning then PrmShow ( c u r r e n t ) 773 2 2 2 31 End; < of whi1e ) 774 2 2 1 36 s i g n a l (power_ready) 775 2 1 0 ' 0 End; { of CurrTask ) 776 2 1 0 0 777 2 1 0 0 778 2 1 d 1 P r o c e s s V o l t T a s k ; 779 2 3 0 0 Beg i n 780 2 3 1 2 w h i l e running do 781 2 3 2 7 Begi n 782 2 3 3 7 PrmRead ( v o l t a g e ) ; 783 2 3 3 1 1 C t r l S p l y ( d C t r l _ d V * Prmlncrm ( v o l t a g e ) ) ; 784 2 3 3 23 PowerAt tn; 785 2 3 3 25 i f r u nning then PrmShow ( v o l t a g e ) 786 2 3 2 31 End { of whi1e } 787 2 1 0 0 End; { of V o l t T a s k > 788 2 1 0 0 Appendix B Compiler L i s t i n g of Program S p u t t e r Page 789 2 1 0 0 790 2 1 d 1 P r o c e s s WattTask; 791 2 4 0 0 Beg i n 792 2 4 1 2 with powers, c o n t r o l ? do 793 2 4 2 8 wh i l e running do 794 2 4 3 13 Begin 795 2 4 4 13 wait (power_ready): power_noted:= t r u e ; 796 2 4 4 19 v a l u e : = voltage®.va1ue * cur rentes . va 1 ue: 797 2 4 4 32 dval dt:= voltage®.value * current®.control®.dva1_dt 798 2 4 4 40 + current®.va1ue * voltage®.contro1®.dva1_ 799 2 4 4 53 C t r l S p l y ( d C t r l _ d V * Prmlncrm (power)); 800 2 4 4 65 i f r u n n i n g then PrmShow (power) 801 2 4 3 71 End { of while } 802 2 1 O 0 End; { of WattTask > 803 2 1 0 0 804 2 1 0 0 805 2 1 d 1 Process PresTask; 806 2 5 d 1 Var range: i n t e g e r ; 807 2 5 d 2 mask: d i g i t a l ; 808 2 5 d 3 809 2 5 d 3 Procedure ChangeRange ( i : i n t e g e r ) ; 810 2 12 0 0 Beg i n 8 1 1 2 12 1 0 range:= range + i ; 812 2 12 1 7 Case range of 813 2 12 1 1 1 3: DigWrite (mask, mask); 8 14 2 12 1 20 2: DigWrite ( [ 6 ] , mask); 8 15 2 12 1 32 1: DigWrite ( [ 5 ] , mask) 8 16 2 12 1 39 End; { of Case } 8 17 2 12 1 47 wi t h pressure®, measure®, va1_dsp1®.format do 818 2 12 2 59 Beg i n 819 2 12 3 59 s c a l e in:= s c a l e _ i n * TenToThe ( i ) ; 820 2 12 3 74 dec fie1d:= d e c _ f i e l d - i ; 82 1 2 12 3 92 i f r unning then 822 2 12 4 97 WaitTick (60 - d e l a y ) { a l l o w meter to s e t t l e ) 823 2 12 2 103 End .{ of with } 824 2 5 0 0 End: { of ChangeRange ) 825 2 5 0 0 826 2 5 0 0 Begi n 827 2 5 1 2 mask:= [5,6]; 828 2 5 1 8 range:= 3; 829 2 5 1 10 wi t h pressure®.measure® do 830 2 5 2 14 wh i l e running do 831 2 5 3 19 Beg i n 832 2 5 4 19 PrmRead ( p r e s s u r e ) ; 833 2 5 4 23 i f r u nning then 834 2 5 5 28 Begi n 835 2 5 6 28 PrmShow ( p r e s s u r e ) ; 836 2 5 6 32 i f raw_input < 1000 837 2 5 6 34 then i f range > 1 then ChangeRange (-1) 838 2 5 7 47 e l se Appendix B Compiler L i s t i n g of Program S p u t t e r Page 839 2 5 : 6 51 840 2 5 : 7 55 84 1 2 5 : 5 67 842 2 5 : 3 69 843 2 5 • 1 71 844 2 1 0 0 845 2 1 0 0 846 2 1 0 0 847 2 1 d 1 848 2 6 d 1 849 2 6 d 1 850 2 6 d 1 85 1 2 6 d 2 852 2 6 d 5 853 2 6 O 0 854 2 6 1 2 855 2 6 1 7 856 2 6 1 10 857 2 6 1 17 858 2 6 1 24 859 2 6 1 24 860 2 6 1 34 86 1 2 6 1 40 862 2 6 2 46 863 2 6 3 46 864 2 6 3 58 865 2 6 4 64 866 2 6 5 64 867 2 6 5 85 868 2 6 7 107 869 2 6 8 107 870 2 6 8 124 871 2 6 8 128 872 2 6 9 131 873 2 6 0 139 874 2 6 O 149 875 2 6 1 157 876 2 6 1 167 877 2 6 9 177 878 2 6 .0 185 879 2 6 :0 195 880 2 6 :8 212 88 1 2 6 :9 215 882 2 6 :0 223 883 2 6 :0 233 884 2 6 :9 243 885 2 6 :0 251 886 2 6 :0 261 887 2 6 : 1 269 888 2 6 : 1 279 e l s e i f raw_input > 11500 then i f range < 3 then ChangeRange (1) End { of i f r u n n i n g > End; { of w h i l e } ChangeRange (3-range) { ensure param i n f o saved on range.3 } End; { of PresTask > P r o c e s s GasTask { (n Const move_open = 3 ; move_close = 2; Var p u l s e : i n t e g e r ; address, move_mask df, d t _ d f , 1imi ted Beg i n last_move:= [move_openJ; Case n of ( address v a l v e gas_num) }; 1ast_move: rea 1 ; d i g i t a l w i t h a c t i v e low } 0 1 2 End; df : = address:= address:= address:= { of Case 0.0; running do [0,1] ; HI: [0] > wh i 1 e Beg i n PrmRead ( g a s [ n ] ) ; i f r u nning then Beg i n df:= df + Prmlncrm ( g a s [ n ] ) ; i f df <> 0.0 then with gas[n]© do Begin { n o n - l i n e a r i t y } l i m i t e d : 5 rBounded ( v a l u e , 0.01, Case n of h i g h l i m ) ; 0: i f df > 0.0 then 1f 1im1 ted >= 0.555 then dt_df:= 9.6 / l i m i t e d e l s e i f l i m i t e d >= 0.092* then dt_df:= 15.1 / l i m i t e d e l s e dt_df:= 27.8 / l i m i t e d e l s e i f l i m i t e d >= 2.00 then dt_df:= 21.7 / l i m i t e d e l s e dt_df:= 15.2 / l i m i t e d ; 1: i f df > 0.0 then i f l i m i t e d >= 0.698 then dt_df:= 10.9 / l i m i t e d e l s e dt_df:= 16.7 / l i m i t e d e l s e i f l i m i t e d >= 3.91 then dt_df:= 34.5 / l i m i t e d e l s e i f l i m i t e d >= 0.272 then dt_df:= 21.3 / l i m i t e d e l s e dt df:= 16.7 / l i m i t e d ; Appendix B Compiler L i s t i n g of Program S p u t t e r Page 889 2 6 : 8 295 2: i f df > 0.0 890 2 6: 9 298 then i f l i m i t e d >= 0.406 891 2 6 : 0 306 then dt df:= 6.10 / l i m i t e d 892 2 6 : 0 316 e l s e i f 1Imited >= 0.169 893 2 6 : 1 324 then dt_df:= 9.52 / l i m i t e d 894 2 6 : 1 334 e l s e dt_df:= 11.2 / l i m i t e d 895 2 6: 9 344 e l s e i f 1im i t ed >- 1.15 896 2 6 : 0 352 then dt_df:= 55.6 / l i m i t e d 897 2 6 : 0 362 e l s e i f l i m i t e d >= 0.474 898 2 6 : 1 370 then dt d f : - 30.3 / l i m i t e d 899 2 6 ;  1 380 e l s e dt_df:= 13.9 / l i m i t e d 900 2 6 : 8 390 End: < of Case > 901 2 6 ; :8 399 pulse:= round ( d f * d t _ d f ) ; 902 2 6 : 8 407 i f r u nning and ( p u l s e <> 0) then 903 2 6 :9 4 16 Beg i n 904 2 6 :0 4 16 df:= df - p u l s e / d t _ d f : 905 2 6 :0 428 pulse:= lAbsBndd ( p u l s e , d e l a y d i v 5); 906 2 6: :0 438 i f p u l s e > 0 907 2 6 :0 439 then move_mask:= [move_open] 908 2 6 : 0 443 e l s e Begin 909 2 6 : 2 450 move mask:= [move_clos]; 910 2 6 : 2 455 pulse:= - p u l s e 91 1 2 6 : 1' 455 End; 912 2 6 :0 458 i f l a s t move <> move_mask then pulse:= p u l s e 913 2 6 :0 477 w h i l e DlgPStat <> 0 do W a i t T i c k ( D i g P S t a t ) ; 914 2 6 :0 492 DigWrite ( a d d r e s s , [ 0 , 1 ] ) ; 915 2 6 :0 500 D i g P u l s e ( [ ] , movemask, p u l s e ) : 916 2 6 :0 513 i f l a s t move <> move mask then 917 2 6 : 1 520 Beg i n 9 18 2 6 : 2 520 l a s t move : = move_mask; 919 2 6 : 2 525 i f r u nning then WaitTick (back 1ash[n]) 920 2 6 : 1 539 End ( o f i f } 921 2 6 :9 54 1 End { of p u l s e <> 0 > 922 2 6 : 7 54 1 End; { of df <> 0.0 > 923 2 6 :5 54 1 i f r u nning then PrmShow ( g a s [ n ] ) 924 2 6 : 4 555 End f of i f ) 925 2 6 : 2 558 End < of w h i l e } 926 2 1 :0 0 End; < of GasTask } 927 2 1 :0 0 928 2 1 :0 0 929 2 1 : d 1 P r o c e s s MeasTask ( (param: param_ptr) ); 930 2 1 :d 1 { measure & d i s p l a y o n l y } 931 2 7 :0 0 Beg i n 932 2 7 : 1 2 w h i l e running do 933 2 7 : 2 7 Beg i n 934 2 7 : 3 7 PrmRead (param); 935 2 7 : 3 1 1 i f r u nning then PrmShow (param) 936 2 7 : 2 17 End < of whi1e ) 937 2 1 :0 0 End; { of MeasTask } 938 2 1 :0 0 Appendix B Compiler L i s t i n g of Program S p u t t e r Page 8 939 2 1 0 0 940 2 1 0 0 Begin { *** main *** } 94 1 2 1 1 0 Sp u t I n i t: 942 2 1 1 3 i f r unning then 943 2 1 2 8 Repeat 944 2 1 3 8 com: = PromptCapIn (0, 945 2 1 3 1 1 ' S p u t t e r : S ( e t p o i n t 94G 2 1 3 16 [ 'S' .'W'.'D'.'E','P' 947 2 1 3 28 i f r u n n i n g then 948 2 1 4 33 Case com of 949 2 1 4 37 950 2 1 4 37 'S' G e t S e t p o i n t s ; '951 2 1 4 4 1 952 2 1 4 4 1 ' w ParamWalk; 953 2 1 4 46 954 2 1 4 46 'D' ParamF i1e: 955 2 1 4 51 95G 2 1 4 51 -p. P l o t S e t u p ; 957 2 1 4 56 958 2 1 4 56 'T' TimSetTO; 959 2 1 4 61 960 2 1 4 61 ' E ' , '0' : SputEdi t 961 2 1 4 63 962 2 1 4 63 End { of Case } 963 2 1 2 7 1 U n t i l not running or (c 964 2 1 1 86 runn i ng := f a l s e ; 965 2 1 1 90 wkHalt; 966 2 1 1 93 r k H a l t : 967 2 1 1 95 s b H a l t ; 968 2 1 1 97 p f H a l t ; 969 2 1 1 100 p1 Ha 11 970 2 0 0 End. 0, W(alk D ( a t a l o g , 'T' , ' 0 ' ] ) ; P ( l o t E ( d i t T(ime Q(u1t' (com) MapCommandKey (sc_escape_key, f a l s e ) ) ; End of C o m p i l a t i o n . Appendix C Comp i 1 er L i s t i n g of U n i t Parameter Page 1 3 0 0 d 4 2 1 d 5 2 1 d 6 2 1 d 7 2 1 d 8 2 1 d 9 2 1 d 76 2 1 d 77 2 1 d 78 2 1 d 79 2 1 d 80 2 1 d 8 1 2 1 d 82 2 1 d 83 2 1 d 84 2 1 d 85 2 1 d 86 2 1 d 87 2 1 d 88 2 1 d 89 2 1 d 90 2 1 d 9 1 2 1 d 92 2 1 d 93 2 1 d 94 2 1 d 95 2 1 d 96 2 1 d 97 2 1 d 98 2 1 d 99 2 1 d 100 2 1 d 101 2 1 d 102 2 1 d 103 2 1 d 104 2 1 d 105 2 1 d 106 2 1 d 107 2 1 d 108 2 1 d 109 2 1 d 1 10 2 1 d 1 1 1 2 1 d 1 12 2 1 d 1 13 2 1 d 1 14 2 1 d 1 15 2 1 d 1 16 2 1 d 1 17 2 1 d {$L remout:> U n i t Parameter; I n t e r f a c e <$L-> Uses Sc r n B u f f ; {$L@> Type a n a _ i n f o - r e c o r d { a l l chan_i n: 1. raw_input: times a re i n t i c k s > 16; < analog In channel number } • 12000. .12000; < u n s e a l e d input v a l u e } s e t p t : -12000..12000; maxerr: - 1. .24000; s t a b l e : boolean; s c a l e _ i n : r e a l end; c t r l _ i n f o = r e c o r d { a l l times a r e dva1_dt: rea1; se t p o i nt: rea1; D : rea1 : s e t _ d s p l : s b _ d s p l _ p t r end ; param_ptr = ®param_info; param_info = r e c o r d hard_name: s t r i n g [ 8 ] ; next: param_ptr; name: st r i ng[8 ] ; un i t s : s t r i n g[4]; i d : c h ar: va1ue: rea1; h i g h l i m: rea1 ; de1 ay: 0. .max i nt; warning: boolean; beep: boolean; name_dspl va1_dsp1: { wait f o r r e a d i n g <> s e t p t > { by > maxerr } { l a s t r e a d i n g s t a b l e ? } { a c u t a l u n i t s / m i l l i v o l t i n in seconds } < measured d ( v a l u e ) / d t per sec } { d e s i r e d c o n t r o l p o i n t } { c a l c ' d d e r i v a t i v e m u l t i p l i e r } { s e t p o i n t d i s p l a y i n f o } uni t _ d s p l r e a d d a t a : read_next: w r i t e next s b _ d s p l _ p t r s b _ d s p l _ p t r ; s b _ d s p l _ p t r rea 1 ; { param_pt r; : param_ptr; measure c o n t r o l end; ®ana_info; © C t r l i n f o { f i x e d program l a b e l } parameter l i s t l i n k up } " name } " u n i t s } i d e n t i f i e r > v a l u e } which v a l u e mustn't exceed } (min) wait between s e r v i c e s ] warning message d i s p l a y e d ? } beep c o n s o l e each s e r v i c e ? } : { name d i s p l a y Info ) { v a l u e " " } ; { u n i t s " " > l a t e s t v a l u e form read f i l e ] { read d a t a v a l u e l i n k up } { w r i t e " " " } i f measured, p o i n t to i n f o ) i f contro11ed, " " " ) 00 Appendix C Compiler L i s t i n g of U n i t Parameter Page 1 18 2 1 d 1 Procedure PrmRead (param: param_ptr): 1 19 2 1 d 1 { wait f o r chan i n r e a d i n g to move from s t a b l e , s c a l e I t , 120 2 1 d 1 i f c o n t r o l f i n d d v a l _ d t } 12 1 2 1 d 1 122 2 1 d 1 F u n c t i o n Prmlncrm (param: param_ptr): r e a l ; 123 2 1 d 1 < c a l c u l a t e d i f f e r e n t i a l c o n t r o l increment f o r param } 124 2 1 d 1 125 2 1 d 1 Procedure PrmShow (param: param_ptr); t i c k s > 126 2 1 d 1 { send v a l u e (& warning message ?) to s c r e e n , use up d e l a y 127 2 1 d 1 128 2 1 d 1 Procedure PrmAnaSet (param: param_ptr); 129 2 1 d 1 { cal1 AnaSetBounds f o r measured channel } 130 2 1 d 1 131 2 1 d 1 Procedure PrmPoint ( s e t p t : r e a l ; param: param_ptr); 132 2 1 d 1 { change g i v e n parameter's s e t p o i n t to (bounded) s e t p t > 133 2 1 d 1 o 134 2 1 d 1 F u n c t i o n P r m L i s t : param_ptr; 135 2 1 d 1 { p o i n t to b e g i n n i n g of l i n k e d l i s t of parameters } 136 2 1 d 1 137 2 1 d 1 Procedure P r m l n i t (monitor_image: sb_name; 138 2 1 d 2 x time, y_time, x_date, y_date. 139 2 1 d 2 x warn, y_warn: i n t e g e r ) ; 140 2 1 d 1 { I n i t i a l i z e u n i t , g i v e name of parameter monitor s c r e e n image 14 1 2 1 d 1 and c o o r d i n a t e s of time, date & warning d i s p l a y : 142 2 1 d 1 don't c a l l from i n i t i a l i z a t i o n p a r t } 143 2 1 d 1 144 2 1 d 1 F u n c t i o n PrmGet (fixed_name: sb_name): param_ptr; 145 2 1 d 1 { i n i t i a l i z e named parameter: c a l l a f t e r P r m l n i t } 146 2 1 d 1 147 2 1 d 1 Procedure PrmEdited; 148 2 1 d 1 { c a l l to f l a g a parameter has been e d i t e d ) 149 2 1 d 1 150 2 1 d 1 Implementation 151 2 1 d 1 152 2 1 d 1 31 1 2 1 d 1 {$L-} Uses ErrMessg, Clock, MiscFunc. ScreenOps, E x t r a S c r 437 2 1 d 1 {$L-> Schedule. E12AnaI0, E12Sched, T r i g A n a , {$L©> 448 2 1 d 1 <$L-) {$U u t i 1 : s t a r t e r . c o d e ) S t a r t e r ; {$L®> 449 2 . 1 d 1 450 2 1 d 1 Const f warn = 57; 45 1 2 1 d 1 yO param = 3; ytop param = 22; 452 2 1 d 1 f i l e _ n a m e = 'UTIL:SYSTEM.PARAM'; 453 2 1 d 1 454 2 1 d 1 Type p _ f i 1 e = f i l e of r e c o r d 455 2 1 d 1 parm: param_info; 456 2 1 d 1 meas: a n a _ i n f o : 457 2 1 d 1 C t r l : C t r l i n f o ; 458 2 1 d 1 d e c i m a l s : i n t e g e r 459 2 1 d 1 end; 460 2 1 d 1 Appendix C Compiler L i s t i n g of U n i t Parameter Page 3 461 2 1 : d 1 Var p a r a m _ l i s t : param_ptr; 462 2 1 : d 2 warn d s p l , t i m e _ d s p l : s b _ d s p l _ p t r ; 463 2 1 : d 4 warn ready: boolean; 464 2 1 : d 5 warn sem: semaphore; 465 2 1 : d 7 y param: y0_param..ytop_param; 466 2 1 • d 8 mon_image: s t r i n g [ 8 ] ; 467 2 1 : d 13 unchanged: boolean; 468 2 1 • d 14 469 2 1 d 14 470 2 1 d 14 47 1 2 1 d 14 Pr o c e s s ShowTime; forward; 472 2 1 d 1 473 2 1 d 1 474 2 1 d 1 475 2 1 d 1 Segment Process ParamWarn; 476 14 1 d 1 Const warn 1 = '!!! Warning: '; 477 14 1 d 1 warn 2 = ' v a l u e exceeds i t s upper bound ! ! ' ; 478 14 1 d 1 Var message: s t r i n g [ f _ w a r n ] ; 479 14 1 d 30 blank: s t r i ng[1]; 480 14 1 d 31 beep: char; 481 14 1 d 32 param, p r e v i o u s , messaged: param_ptr; 482 14 1 d 35 483 14 1 0 0 Begin { ** ParamWarn ** > 484 14 1 1 3 beep:= chr ( 7 ) ; 485 14 1 1 6 b1ank:= ''; 486 14 1 1 14 messaged:= n i l ; 487 14 1 1 17 wa i t (warn_sem); 488 14 1 1 20 param:= p a r a m _ l i s t ; 489 14 ^ 1 23 w h i l e r u n n i n g do 490 14 1 2 29 Begin 491 14 1 3 29 prev i o u s : = param; 492 14 1 3 33 Repeat 493 14 1 4 33 with param® do i f next = n i l then param : = param 494 14 1 5 43 e l s e param := next; 495 14 1 3 53 U n t i l param©.warning or (param = p r e v i o u s ) ; 496 14 1 3 65 i f param®.warn 1ng 497 14 1 3 67 then Begin 498 14 1 5 7 1 i f param <> messaged then 499 14 1 6 77 Beg i n warn_2); 500 14 1 7 77 message:= concat (warn_1, param®.name. 501 14 1 7 120 messaged:= param; 502 14 1 7 124 Pol 1 Inputs 503 14 1 6 124 End: 504 14 1 5 127 u n i t w r i t e (1, beep. 1); 505 14 1 5 136 s b T o s s S t r i n g (message, warn_dspl): 506 14 1 5 140 i f r u nning then WaitTick (90); 507 14 1 •5" 150 i f r u nning then 508 14 1 :6 155 Beg 1 n 509 14 1 : 7 155 u n i t w r i t e (1, beep. 1); 510 14 1 • 7 164 s b T o s s S t r i n g (blank. warn_dspl); 1 Appendix C Compiler L i s t i n g of Un i t Parameter Page 5 1 1 14 1 7 169 512 14 1 6 175 5 1 3 14 1 4 178 514 14 1 3 178 515 14 1 5 180 5 1G 14 1 5 183 517 14 1 4 186 518 14 1 2 186 519 14 1 0 0 520 14 1 0 0 52 1 14 1 0 0 522 14 1 0 0 523 2 1 d 1 524 2 1 d 2 525 17 1 d 1 526 17 1 d 347 527 (commented ' : ') 528 {commented ' : '} 529 17 1 d 347 530 17 1 d 1 531 17 1 d 1 532 17 1 d 1 533 17 2 d 1 534 17 2 d 2 535 17 2 d 4 536 17 2 d 6 537 17 2 d 7 538 17 2 0 0 539 17 2 1 0 540 17 2 1 3 54 1 17 2 1 9 542 17 2 1 18 543 17 2 1 21 544 17 2 1 33 545 17 2 1 39 546 17 2 1 45 547 17 2 2 45 548 17 2 3 45 549 17 2 3 76 550 17 2 3 86 551 17 2 3 107 552 17 2 3 1 17 553 17 2 . 3 120 554 17 2 : 3 150 555 17 2 : 2 159 556 17 2 : 1 159 557 17 2 : 1 162 558 17 2 : 1 166 559 17 2 : 1 182 560 17 2 : 1 201 i f r u n n i n g then W a i t T i c k (30) End { of i f run n i n g ) End { of then warning } e l s e Begin warn_ready:= t r u e ; wait (warn_sem) End { of e l s e not warning ) End { of whi1e } End; { of ParamWarn } Segment F u n c t i o n ParamlO (new_name; sb_name; x_time, y_time, x_date, y_date, x_warn. y_warn: i n t e g e r ) : param_ptr; Var p a r a m _ f i l e : p _ f i 1 e ; Procedure P r m l n i t { { In i t i a 1 i ze un i t and c o o r d i n a t e s don ' t ca 1 1 .from Var p i d : p r o c e s s i d ; s t a c k , p r i o : i n t e g e r ; fmt: sb_forn>at: d a t e _ d s p l : s b _ d s p l _ p t r ; date: st r i n g [9]; B e g i n unchanged:= true; Uppercase (new_name); mon_image:= new_name: param_l i s t : = n i l ; warn_ready:= t r u e ; s e m i n i t y_param:= yO_param; f i l l c h a r (fmt. s i z e o f ( f m t ) , with fmt do Beg 1 n x:= x_warn; warn_dsp1:= x : = x t i me; t i me dsp1 : = (monitor_image: sb_name; x_time. y_time, x_date, y_date, x_warn, y_warn: i n t e g e r ) }; g i v e name of parameter monitor s c r e e n i mage of time & warning d i s p l a y : i n i t i a l i z a t i o n p a r t > (warn_sem, 0); 0); y:= y_warn; f i e l d : = f_warn; sbLink (mon_image, fmt, s b _ s t n g ) ; y:= y _ t i me; _ sbLink (mon_image, fmt, sb_now) ; sbTossNow ( t i m e _ d s p l ) ; x : = x_date; y:= y_date; f i e l d : = 9: date_dspl:= sbLink (mon_image, fmt, s b _ s t n g ) ; End: MapDate ( d a t e ) ; s b T o s s S t r i n g (date, d a t e _ d s p l ) ; S t r t l n f o ('Parametr', 'ShowTime'. s t a c k , p r i o . f a l s e ) ; s t a r t (ShowTime. p i d , s t a c k , p r i o ) ; S t r t l n f o ('Parametr'. 'Warning', s t a c k , p r i o , f a l s e ) ; Appendix C Compiler L i s t i n g o f - U n i t Parameter Page 5 561 17 2 1 217 s t a r t (ParamWarn, p i d , s t a c k , p r i o ) ; 562 17 2 1 237 E 1 2 S t a r t : 563 17 2 1 240 Tr i g l n i t 564 17 1 0 0 End; { of P r m l n i t > 565 17 1 0 0 566 17 1 0 0 {$1-} 567 17 1 0 0 568 17 1 d 1 Procedure PFOpen; 569 17 3 0 0 Begin 570 17 3 1 0 r e s e t (param f i l e , f i l e _ n a m e ) ; 571 17 3 1 13 i f i o r e s u 1 t <> 0 572 17 3 1 16 then N o t e E r r o r (300, i o r e s u l t . f a l s e ) 573 17 3 1 26 e l s e i f eof ( p a r a m _ f i l e ) then N o t e E r r o r (301, 0, f a l s e ) 574 17 3 1 46 i f E r r o r N o t e d then e x i t (ParamlO) 575 17 1 0 0 End; ( of PFOpen } 576 17 1 0 0 577 17 1 d 1 Procedure PFGet; 578 17 4 0 0 B e g i n 579 17 4 1 0 get (param_f i l e ) ; 580 17 4 1 6 i f i o r e s u l t <> 0 then N o t e E r r o r (309, i o r e s u l t , f a l s e ) ; 581 17 4 1 21 i f E r r o r N o t e d then e x i t (ParamlO) 582 17 1 0 0 End; < of PFGet } 583 17 1 0 0 584 17 1 0 0 {$1 + } 585 17 1 0 0 586 17 1 d 1 Procedure PrmGet { (fixed_name: sb_name): param_ptr }; 587 17 1 d 1 { i n i t i a l i z e named parameter: c a l l a f t e r P r m l n i t > 588 17 5 d 1 Const x_name = 46; f_name = 8; 589 17 5 d 1 x u n i t = 56; f _ u n i t = 4; 590 17 5 d 1 x_val = 63; f _ v a l = 7; 591 17 5 d 1 x_set = 72; f _ s e t = 7; 592 17 5 d 1 Var param: param p t r ; 593 17 5 d 2 fmt: sb_format: ' 594 17 5 d 4 p i d : p r o c e s s i d ; 595 17 5 d 5 s t a c k , p r i o : i n t e g e r ; 596 17 5 d 7 597 17 5 d 7 F u n c t i o n Found: boolean; 598 17 6 0 0 Beg i n 599 17 6 1 0 Found:= param f11e®.parm.hard name = new_name 600 17 5 0 0 End; ( of Found > 601 17 5 0 0 602 17 5 d 1 F u n c t i o n Link (k: s b k i n d ; xx, f : i n t e g e r ) : s b _ d s p l _ p t r ; 603 17 7 0 • 0 Begin 604 17 7 1 0 with fmt do Begin x:= xx; f 1 e l d : = f End; 605 17 7 1 22 Link:= sbLink (mon image, fmt, k) 606 17 5 0 0 End; 607 17 5 0 0 608 17 5 0 0 B e g i n < ** PrmGet ** } 609 17 5 1 0 param:= n i l ; 610 17 5 1 2 PFOpen; Appendix C Compiler L i s t i n g of U n i t Parameter Page 6 61 1 17 5 : 1 4 i f y param >= ytop_param 612 17 5 : 1 5 then N o t e E r r o r (302, ytop_param-yO_param, f a l s e ) 6 13 17 5 : 1 16 e l s e Begin 614 17 5 : 3 21 new (param); 615 17 5 : 3 26 Uppercase (new_name); 616 17 5 : 3 32 w h i l e not ( Found or eof ( p a r a m _ f i l e ) ) do PFGet 617 17 5 : 3 51 i f not Found 6 18 17 5: 3 51 then N o t e E r r o r (303. 0, f a l s e ) 619 17 5: 3 61 e l s e w i t h param_file©, param®, fmt do 620 17 5 : 5 7 1 Beg i n 621 17 5: 6 71 param®:= parm ; 622 17 5 : 6 76 va1ue:= 0.0; 623 17 5 : 6 83 w a r n i n g : 5 f a l s e ; 624 17 5 : 6 88 n e x t : 5 p a r a m _ l i s t ; 625 17 5: 6 93 param l i s t : - param; 626 17 5: 6 96 read_data:= 0.0; 627 17 5 : 6 103 read next:= n i l ; 628 17 5 : 6 108 wr i te next:= n i l ; 629 17 5 : 6 1 13 f i l l c h a r (fmt, s i z e o f ( f m t ) , 0 ) : 630 17 5 : 6 1 19 y param: 5 y_param + 1; 631 17 5; :6 126 y:= y param; dec f i e l d : 5 d e c i m a l s ; 632 17 5: :6 145 name d s p l : 5 Link ( s b _ s t n g , x_name, f_name); 633 17 5 :6 156 s b T o s s S t r i n g (name, name_dspl); 634 17 5 :6 164 u n i t dspl:= Link ( s b _ s t n g , x _ u n i t , f _ u n i t ) ; 635 17 5 :6 175 S b T o s s S t r i n g ( u n i t s , u n i t _ d s p l ) ; 636 17 5 :6 183 val d s p l : 5 Link (s"b_re. x _ v a l , f _ v a l ) : 637 17 5 :6 194 sbTossReal ( v a l u e , v a l _ d s p l ) ; 638 17 5 :6 203 i f c o n t r o l <> n i l then 639 17 5 : 7 209 Beg i n 640 17 5 :8 209 new (contro1 ) ; 64 1 17 5 :8 2 16 control®:= C t r l ; 642 17 5 :8 225 with control© do 643 17 5 :9 230 Beg i n 644 17 5 :0 230 s e t p o i n t : 5 0.0: 645 17 5 :0 237 set d s p l : 5 Link ( s b _ r e , x s e t , f _ s e t ) 646 17 5 :9 245 End { of with } 647 17 5 : 7 248 End: ( of c o n t r o l ) 648 17 5 :6 248 i f measure <> n i l then 649 17 5 : 7 254 Beg i n 650 17 5 :8 254 new (measure): 651 17 5 :8 261 measure®: 5 meas; 652 17 5 :8 270 with measure® do 653 17 5 :9 275 Beg i n 654 17 5 :0 275 ana n a m e s [ c h a n _ i n ] : 5 name; 655 17 5 :0 292 stab 1e:= f a 1se 656 17 5 :9 295 End; { of w i t h ) 657 1 7 5 : 8 297 PrmAnaSet (param) 658 17 5 : 7 298 End { of measure > 659 1 7 5 : 5 300 End { of f i l e r e c o r d found } 660 17 5 : 2 300 End; { of e l s e y_param ok ) Appendix C Compiler L i s t i n g of U n i t Parameter Page 7 661 17 5 1 300 ParamlO: = param 662 17 1 0 0 End; ( of PrmGet } 663 17 1 0 0 664 17 1 d 1 Procedure PrmPut; 665 17 8 d 1 Var param: param_ptr; 666 17 8 d 2 rec no: i n t e g e r ; 667 17 8 0 0 Begi n 668 17 8 1 0 i f not unchanged then 669 17 8 2 5 Beg i n 670 17 8 3 5 PFOpen; 671 17 8 3 7 param:= p a r a m _ l i s t : 672 17 8 3 9 w h i l e param <> n i l do with param© do 673 17 8 5 17 Beg i n 674 17 8 6 17 rec_no:= 0; 675 17 8 6 19 w h i l e param fi1e®.parm.hard name <> hard_name do 676 17 8 7 27 Beg i n 677 17 8 8 27 PFGet; 678 17 8 8 29 rec no:= rec_no + 1 679 17 8 7 30 End; 680 17 8 6 34 {$1-} seek (param_f1le, r e c _ n o ) ; <$I+> 68 1 17 8 6 4 1 i f i o r e s u l t <> 0 then N o t e E r r o r (310, i o r e s u l t , t r u e ) ; 682 17 8 6 56 with param_file© do 683 17 8 7 59 Begi n 684 17 8 8 59 parm:= param©; 685 •17 8 8 64 i f measure <> n i l then meas:= measure®; 686 17 8 8 79 i f c o n t r o l <> n i l then ctrl-:= control®; 687 17 8 8 94 d e c i m a l s : ^ va1_dspl®.format.dec_fie 1 d 688 17 8 7 104 End; { of w i t h param_f1le© } 689 17 8 6 106 ($I-> put ( p a r a m _ f i l e ) ; <$I+) 690 17 8 6 1 12 i f i o r e s u l t <> 0 then N o t e E r r o r (304, i o r e s u l t . t r u e ) ; 691 17 8 6 127 param:= next; 692 17 8 6 130 i f param <> n i l then 693 17 8 7 134 Beg i n 694 17 8 8 134 ($I-> r e s e t ( p a r a m _ f i 1 e ) ; {$1+} 695 17 8 8 140 i f i o r e s u l t <> 0 then N o t e E r r o r (311, i o r e s u l t , t r u e ) 696 17 8 7 153 End ( o f not n i l ) 697 17 8 5 155 End { of w h i l e , with param® ) 698 17 8 2 155 End ( o f i f not unchanged > 699 17 1 0 0 End; < of PrmPut > 700 17 1 0 0 701 17 1 0 0 Begin ( *** ParamlO *** } 702 17 1 1 17 ParamlO:= n i l ; 703 17 1 1 21 i f x_time < 80 then P r m l n i t 704 17 1 1 29 e l s e i f x_time = 80 then PrmGet 705 17 1 2 40 e l s e PrmPut 706 17 1 0 0 End; { of Segment ParamlO } 707 17 1 0 0 708 17 1 0 0 709 (commented ' : '} Procedure P r m l n i t { (monitor_image: sb_name; 7 10 2 1 d 1 x_time, y_time, x_warn, y_warn: i n t e g e r ) }; Appendix C Compiler L i s t i n g of U n i t Parameter Page 8 7 1 1 2 1 :d 1 { I n i t i a l i z e u n i t , g i v e name of parameter monitor s c r e e n image 712 2 1 :d 1 and c o o r d i n a t e s of time & warning d i s p l a y : 7 13 2 1 :d 1 don't c a l l from i n i t i a l i z a t i o n p a r t } 7 14 2 8 :d 1 Var dummy: param_ptr; 7 15 2 8 :0 0 Beg i n 7 16 2 8 : 1 5 dummy:= ParamlO (monitor_1mage, x_time, y_time. 7 17 2 8 : 1 10 x date, y_date, x_warn, y_warn) 7 18 2 1 :0 0 End; { of P r m l n i t > 7 19 2 1 :0 0 720 2 1 :0 0 72 1 2 1 : d 1 F u n c t i o n PrmGet ( (f1xed_name: sb_name): param_ptr >; 722 2 1 : d 1 { i n i t i a l i z e named parameter: c a l l a f t e r P r m l n i t } 723 2 9 :0 0 Begi n 724 2 9 : 1 4 PrmGet: 5 ParamlO (fixed_name, 80, 0, 0, 0. 0, 0) 725 2 1 :0 0 End; { of PrmGet > 726 2 1 :0 0 727 2 1 :0 0 728 2 1 :d 1 Procedure PrmEdlted; 729 2 1 :d 1 { c a l l to f l a g a parameter has been e d i t e d > 730 2 10 :0 0 Beg i n 73 1 2 10 : 1 0 i f unchanged then unchanged: 5 f a l s e 732 2 1 :0 0 End; < of PrmEdited } 733 2 1 :0 0 734 2 1 :0 0 735 2 1 :d 1 F u n c t i o n E x i s t s ( e r r : boolean; i d : char; err_num: i n t e g e r ) : boolean; 736 2 12 :0 0 Beg i n 737 2 12 : 1 0 i f e r r then N o t e E r r o r ( e r r n u m , o r d ( i d ) , f a l s e ) ; 738 2 12 : 1 8 E x i s t s : 5 not e r r 739 2 1 :0 0 End; { of E x i s t s } 740 2 1 :0 0 74 1 2 1 :0 O 742 2 1 :d 1 F u n c t i o n C t r l E x i s t s (param: param_ptr; err_num: i n t e g e r ) : boolean; 743 2 13 :0 0 Beg i n 744 2 13 : 1 0 wi t h param© do C t r l E x i s t s : 5 E x i s t s ( c o n t r o l 5 n i 1 , i d , err_num) 745 2 1 :0 0 End; { of C t r l E x i s t s } 746 2 1 :0 0 747 2 1 :0 0 748 2 1 :d 1 F u n c t i o n M e asExists (param: param_ptr; err_num: i n t e g e r ) : boolean; 749 2 14 :0 0 Beg i n 750 2 14 : 1 0 wi t h param© do M e a s E x i s t s : 5 E x i s t s (measure=ni1, i d , err_num) 751 2 1 :0 0 End; ( of Mea s E x i s t s } 752 2 1 :0 0 753 2 1 :0 0 754 2 1 :d 1 P r o c e s s ShowTime; 755 2 1 1 :0 0 Begin 756 2 1 1 : 1 2 wh i1e runn i ng do 757 2 1 1 : 2, 7 Beg i n 758 2 1 1 : 3 7 WaitTick (60); 759 2 1 1 : 3 1 2 i f r u nning then sbTossNow ( t i m e _ d s p l ) 760 2 1 1 : 2 18 End; { of w h i l e r u n n i n g > Appendix C Compiler L i s t i n g of U n i t Parameter Page 9 7G1 2 1 1 : 1 22 s i g n a l (warn_sem) { shut down ParamWarn p r o c e s s } 762 2 1 : 0 0 End: < of ShowTime > 763 2 1 : 0 0 764 2 1 : 0 0 Procedure PrmShow { (param: param_ptr) >: 765 2 1 : d 1 766 2 1 : d 1 { send value (& warning message ?) to s c r e e n , use up d e l a y 767 2 4 : d 1 Var t l . t2: ti m _ r e c ; 768 2 4 : d 5 769 2 4 : 0 0 Begin ( ** PrmShow +* > 770 2 4 : 1 0 wi t h t1 do time (hiword, loword): 77 1 2 4 : 1 4 wi t h param®. t2 do 772 2 4 : 2 6 Begin 773 2 4 : 3 6 sbTossReal ( v a l u e . v a l _ d s p l ) ; 774 2 4 : 3 15 warning:= v a l u e > h i g h l i m ; 775 2 4 : 3 29 i f warning and warn_ready then 776 2 4 : 4 36 Beg i n 777 2 4 : 5 36 warn ready:= f a l s e ; 778 2 4 : 5 39 s i g n a l (warn_sem) 779 2 4 : 4 42 End; { of i f warning } 780 2 4 ; : 3 42 i f beep then w r i t e ( c hr ( 7 ) ) ; 781 2 4 : 3 57 time (hiword, loword): 782 2 4 : 3 61 TimMinus ( t 2 , t2, t 1 ) ; 783 2 4 : 3 66 i f running then W a i t T i c k (de1 ay-1oword) 784 2 4 : 2 76 End < of with } 785 2 1 :0 0 End; { of PrmShow > 786 2 1 :0 0 787 2 1 :0 0 Procedure PrmAnaSet { (param: param_ptr) >; 788 2 1 : d 1 789 2 1 :d 1 { c a l 1 AnaSetBounds f o r measured channel ) 790 2 5 : d 1 Var e r r : i n t e g e r ; 79 1 2 5 :0 0 Begi n 792 2 5 : 1 0 i f M e a s E x i s t s (param. 305) then 793 2 5 : 2 9 wi t h param®, measure® do 794 2 5 : 3 15 Beg i n 795 2 5 :4 15 i f s t a b l e then err:- maxerr 796 2 5 : 4 19 e l s e e rr:= - 1 ; 797 2 5 : 4 27 i f contro1 = n i l 798 2 5 : 4 30 then setpt:= raw_input 799 2 5 : 4 36 e l s e w i t h control® do 800 2 5 : 6 52 i f s e t dspl®.format.enabled 801 2 5 :6 58 then setpt:= round ( s e t p o i n t / s c a l e i n ) 802 2 5 :6 73 e l s e setpt:= raw_input; 803 2 5 :4 97 AnaSetBound (chan i n , s e t p t , e r r . 804 2 5 : 4 1 18 iBounded ( d e l a y d i v 4. 1, 30)) 805 2 5 : 3 132 End 806 2 1 :0 0 End; < of PrmAnaSet ) 807 2 1 :0 0 808 2 1 :0 0 809 2 1 :d 1 Procedure PrmRead < (param: param_ptr) >; 810 2 1 : d 1 ( wait f o r chan in r e a d i n g to move from s t a b l e , s c a l e 1t, Appendix C Compiler L i s t i n g of U n i t Parameter Page 10 81 1 2 1 : :d 1 i f c o n t r o l f i n d d v a l _ d t > 812 2 2 : d 1 Var dx, d t : i n t e g e r : 813 2 2 : 0 0 Begin 814 2 2 : 1 0 i f M e a s E xists (param, 306) then with param®, measure® do 815 2 2 : 3 15 Begin 816 2 2 : 4 15 WaitAnalog ( c h a n _ i n ) ; 817 2 2 : 4 23 i f r u nning then 818 2 2 :5 28 Begin 8 19 2 2 : 6 28 AnaRead (chan i n , raw_input, dx. d t ) : 820 2 2 :6 4 1 value:= s c a l e i n * raw_input; 82 1 2 2 : 6 53 s t a b l e : = abs (raw_input - s e t p t ) <= maxerr; 822 2 2 :6 66 i f c o n t r o l <> n i l 823 2 2 :6 69 then Begin 824 2 2 :8 72 i f s t a b l e then 825 2 2 :9 76 s t a b l e : 5 abs (dx * d e l a y ) d i v dt <= maxerr; 826 2 2 :8 91 control®.dval_dt:= s c a l e _ i n * dx / (dt / 60.0) 827 2 2 : 7 107 End; < of c o n t r o l ) 828 2 2 :6 109 PrmAnaSet (param) 829 2 2 :5 1 10 End ( of i f r u n n i n g ) 830 2 2 :3 112 End { of with > 83 1 2 1 :0 0 End; { of PrmRead > 832 2 1 :0 0 833 2 1 :0 0 834 2 1 :d 1 F u n c t i o n Prmlncrm { (param: param_ptr): r e a l }; 835 2 1 :d 1 { c a l c u l a t e d i f f e r e n t i a l c o n t r o l increment f o r param } 836 2 3 :d 1 Var s i gna1 : rea1 ; 837 2 3 :0 0 Beg i n 838 2 3 : 1 0 Prmlncrm:= O.O; { i n case doesn't e x i s t or not e n a b l e d ) 839 2 3 : 1 5 i f C t r l E x i s t s (param, 307) then with param®, control® do 840 2 3 : 3 20 i f s e t dspl®.format.enabled then 84 1 2 3 : 4 29 Beg i n 842 2 3 : 5 29 i f v a l u e >= h i g h l i m 843 2 3 :5 33 then s i g n a l : = h i g h l i m - v a l u e 844 2 3 :5 45 e l s e i f v a l u e <= 0.0 845 2 3 :6 57 then s i g n a l : = - v a l u e 846 2 3 :6 64 e l s e s i g n a l : = setpo1nt-va1ue - D*dva l _ d t ; 847 2 3 : 5 91 Prmlncrm:= delay/60.0 * rAbsBndd ( s i g n a l , highlim*0.1/(D+ 1 848 2 3 :4 121 End { o f i f enabled } 849 2 1 :0 0 End; { of Prmlncrm > 850 2 1 :0 0 85 1 2 1 :0 0 Procedure PrmPoint { ( s e t p t : r e a l ; param: param_ptr) ); 852 2 1 : d 1 853 2 1 :d 1 { change g i v e n parameter's s e t p o i n t to (bounded) s e t p t ) 854 2 6 :0 0 Begin ' 855 2 6 : 1 0 i f C t r l E x i s t s (param, 308) then 856 2 6 : 2 9 with param®, control© do 857 2 6 : 3 15 Begin 858 2 6 :4 15 s e t p o i n t : = rBounded ( s e t p t , 0.0, h i g h l i m ) ; 859 2 6 : 4 32 sbTossReal ( s e t p o i n t , s e t _ d s p l ) ; 860 2 6 : 4 40 i f measure <> n i l then PrmAnaSet (param) Appendix C Compiler L i s t i n g of U n i t Parameter Page 861 2 6 :3 47 End { of with } 862 2 1 :0 0 End; { of PrmPoint > 863 2 1 :0 0 864 2 1 :0 0 F u n c t i o n PrmList {: param_ptr } 865 2 1 :d 1 ; 866 2 1 :d 1 { p o i n t to b e g i n n i n g of l i n k e d l i s t of parameters 867 2 7 :0 0 Beg i n 868 2 7 : 1 0 PrmList:= p a r a m _ l i s t 869 2 1 :0 0 End; { of PrmList } 870 2 1 :0 0 871 2 1 :0 0 872 2 1 :0 0 Begin { u n i t i n i t i a l i z a t i o n & h a l t i ng code } 873 2 1 : 1 0 * * + . 0. 0. 0. 0, 0) { 874 2 1 : 1 3 param 1i s t : = ParamlO ('', 81. 875 2 :0 0 End. save p a r a m _ f i l e } End of C o m p i l a t i o n Appendix C Compiler L i s t i n g of U n i t ParamUtil Page 3 0 0 d 1 {$L remout:} 4 2 1 d 1 Uni t ParamUt11 : 5 2 1 .d 1 6 2 1 d 1 7 2 1 d 1 I n t e r f a c e 8 2 1 d 1 152 2 1 d 1 {$L-} Uses S c r n B u f f , Parameter: {$L®> 153 2 1 d 1 F u n c t i o n PrmNamed (name: sb_name): param_ptr; 154 2 1 d 1 155 2 1 d 1 { r e t u r n with named parameter > 156 2 1 d 1 157 2 1 d 1 F u n c t i o n PrmPrmpt (x, y: i n t e g e r ; t i t l e : s t r i n g ; 158 2 1 d must meas, m u s t _ c t r l : b o o l e a n ) : param_ptr; 159 2 1 d 1 { PromptCapIn f o r a (measured and/or c o n t r o l l e d ? ) parameter i d . 160 {commented ' : ' > u s i n g t i t l e : to s t a r t the prompt; 161 2 1 d 1 r e t u r n n i l when <esc> typed or not r u n n i n g ) 162 2 1 d 1 -163 2 1 d 1 F u n c t i o n PrmEdSet: param_ptr; 164 2 1 d 1 { prompt f o r & read a parameter s e t p o i n t , r e t u r n w i t h a l t e r e d param ) 165 2 1 d 1 166 2 1 d 1 167 2 1 d 1 Implementati on 168 2 1 d 0 169 2 1 d 0 {$L-> Uses ScreenOps, E x t r a S c r . MiscFunc. Schedule, ReadKybd; {$L©} 362 2 1 d 0 363 2 1 d 0 364 2 1 d 0 F u n c t i o n PrmNamed { (name: sb_name): param_ptr }; 365 2 1 d 0 366 2 1 d 1 { r e t u r n with named parameter > 367 2 2 .d 1 Var param: param_ptr; 368 2 2 d 2 done: boolean; 369 2 2 :d 3 F u n c t i o n Found (p name: sb_name): boolean; 370 2 5 :0 0 Begi n . . 371 2 5 : 1 4 Uppercase (p_name); 372 2 5 : 1 7 Found:= p_name = name 373 2 2 :0 0 End; { of Found ) 374 2 2 :0 0 Beg i n 375 2 2 : 1 4 Uppercase (name); 376 2 2 : 1 7 param:= PrmL i s t ; 377 2 2 : 1 1 1 Repeat 378 2 2 : 2 1 1 done:= Found (param©,name); 379 2 2 : 2 19 i f not done then param:= param®.next 380 2 2 : 1 23 U n t i l done or (param = n i l ) ; 38 1 2 2 : 1 32 PrmNamed:= param 382 2 1 :0 0 End; { of PrmNamed } 383 2 1 :0 0 384 2 1 :0 0 385 {commented : ' ) F u n c t i o n PrmPrmpt { (x, y: i n t e g e r ; t i t l e : s t r i n g ; 386 2 1 :d 1 must meas, m u s t _ c t r l : b o o l e a n ) : param_ptr >; Appendix C Compiler L i s t i n g of U n i t ParamUtil Page 2 387 2 1 : d 1 { PromptCapIn f o r a (measured and/or c o n t r o l l e d ? ) parameter i d . 388 {commented ' : ' ) u s i n g t i t l e : to . s t a r t the prompt; 389 2 1 : d 1 r e t u r n n i l when <esc> typed or not r u n n i n g } 390 2 3 : d 1 Var param: param_ptr; 391 2 3 : d 2 s : sb_prmt; 392 2 3 : d 130 match: set of char; 393 2 3 : d 146 i d e n t i t y : char; 394 2 3 : 0 0 Begi n 395 2 3 : 1 8 s:= ' <esc>': 396 2 3 : 1 15 match:= [MapCommandKey (sc_escape_key, f a l s e ) ] ; 397 2 3 : 1 29 param:= PrmL i s t : 398 2 3 : 1 33 w h i l e param <> n i l do with param© do 399 2 3 : 3 43 Beg i n 400 2 3 : 4 43 i f (not m u s t _ c t r l or ( c o n t r o l <> n i l ) ) 401 2 3 : 4 55 and (not must meas or (measure <> n i l ) ) then 402 2 3 : ;5 70 Beg 1 n 403 2 3 : 6 70 s:= concat (' ('. name, s ) ; 404 2 3 : 6 1 16 s[3]:= i d ; 405 2 3 : 6 125 i f UpperChar (name[1]) = i d then d e l e t e ( s , 5, 1); 406 2 3 : 6 149 match:= match + [ i d ] ; 407 2 3 :6 170 Pol 1 Inputs 408 2 3 :5 170 End; < i f > 409 2 3 : 4 172 param:= next 4 10 2 3 : 3 172 End; { w h i l e with > 4 1 1 2 3 : 1 180 i f r u n n i n g then 4 12 2 3 : 2 185 i d e n t i t y : ^ PromptCapIn (x, y, concat ( t i t l e , ':', s ) , match); 4 13 2 3 : 1 246 i f not running or ( i d e n t i t y = MapCommandKey (sc_escape_key, f a l s e ) ) 4 14 2 3 : 1 259 then param:= n i l 4 15 2 3 : 1 262 e l s e Begin 4 16 2 3 : 3 266 param:= PrmL i s t : 4 17 2 3 : 3 270 w h i l e param©.id <> i d e n t i t y do param:= param©.next 4 18 2 3 : 2 279 End; ( of e l s e } 4 19 2 3 : 1 283 PrmPrmpt:= param 420 2 1 :0 0 End; { of PrmPrmpt > 42 1 2 1 :0 0 422 2 1 :0 0 423 2 1 :d 1 F u n c t i o n PrmEdSet { : param_ptr }; 424 2 1 :d 1 < prompt f o r & read a parameter s e t p o i n t , r e t u r n with a l t e r e d param > 425 2 4 :d 1 Var param: param_ptr; 426 2 4 :0 0 Beg i n 427 2 4 : 1 0 param:= PrmPrmpt (0. 0, ' S e t p o i n t ' . f a l s e , t r u e ) : 428 2 4 : 1 13 i f param <> n i l then 429 2 4 : 2 17 w i t h param®, control®.set_dsp1©.format do 430 2 4 : 3 26 PrmPoint (FetchReal (x. y, f i e l d , d e c _ f i e l d , 0.0, h i g h l i m ) . 431 2 4 : 3 58 param); 432 2 4 : 1 6 1 PrmEdSet:= param 433 2 1 :0 0 End; { of PrmSetpt ) 434 2 1 :0 0 435 2 1 :0 0 436 2 :0 0 End. Appendix C Compiler L i s t i n g of U n i t ParamUtil Page End of C o m p i l a t i o n . Appendix C Compiler L i s t i n g of U n i t ParamEdit Page 3 0 0 d 1 {$L remout:> 4 2 1 d 1 Uni t ParamEdi t; 5 2 1 d 1 6 2 1 d 1 7 2 1 d 1 I n t e r f a c e 8 2 1 d 1 9 2 1 d 1 Procedure PrmEdit 10 2 1 d 1 { i n t e r a c t i v e l y e d i t system parameters } 1 1 2 1 d 1 12 2 1 d 1 Implementat ion 13 2 1 d 1 14 2 1 d 1 239 2 1 d 1 ($L-> Uses MiscFunc. WritCons, Schedu1e, ReadKybd 344 2 1 d 1 ($L-> TrigAna, Parameter, ParamUt i1 <$L©} 345 2 1 d 1 34G 2 1 d 1 347 2 1 d 1 Procedure PrmEdit 348 2 1 d 1 { i n t e r a c t i v e l y e d i t system parameters } 349 2 1 d 1 350 2 2 d 1 Const e d i t _ i m a g e = = 'PRMEDIT' ; 351 2 2 d 1 x_name = 34 y_name = 6 f name = 8; 352 2 2 d 1 x u n i t = 55 y u n i t = 6 f un i t = 4 ; 353 2 2 d 1 x_1d = 6 9 y _ i d = 6 354 2 2 d 1 x_uppr = 41 y_uppr = 7 355 2 2 d 1 x dec = 69 y_dec = 7 f _dec 1 : 356 2 2 d 1 x_wa i t = 69 y wa i t = 8 f wa i t = 6; d_ 357 2 2 d 1 x beep = 55 y_beep = 9 358 2 2 d 1 x chan = 50 y chan = 14 f_chan = 2; 359 2 2 d 1 x _ f u l 1 = 53 y _ f u l l = 15 • 360 2 2 d 1 x slew = 47 y s1ew = 20 f_s1ew = 2; 361 2 2 d 1 x_enab - 45 y_enab = 21 362 2 2 d 1 363 2 2 d 1 Var ch: char; 364 2 2 d 2 prompt: sb_prmt; 365 2 2 d 130 v a l i d i d s . match: set of char: 366 2 2 d 162 param: param_ptr: 367 2 2 d 163 f r e . d_re: i n t e g e r ; 368 2 2 d 165 369 2 2 d 165 Procedure AddPrompt ( i : i n t e g e r ) ; 370 2 3 d 1 Var prompt p t r : sb_prmt_ptr; 371 2 3 0 0 Beg i n 372 2 3 1 0 prompt_ptr:= ScrnPrompt ( 1 ) 373 2 3 1 1 1 prompt:= concat (prompt. prompt ptr©) 374 2 3 1 38 Pol 1 Inputs; 375 2 3 1 40 i f not running then e x i t (PrmEdit) 376 2 2 0 0 End; < of AddPrompt } 377 2 2 0 0 378 2 2 d 1 Procedure N o t e l d ; 379 2 4 O 0 Begin Appendix C Compiler L i s t i n g of U n i t ParamEdit Page 2 380 2 4 : 1 0 with paramo do v a l i d _ i d s : = v a l i d _ i d s - [ i d ] 38 1 2 2 : 0 0 End; { of Removeld } 382 2 2 : 0 0 . 383 2 2 : d 1 Procedure Pool Id; 384 2 5 : 0 0 Beg i n 385 2 5 : 1 0 with param® do v a l i d _ i d s : = v a l i d _ i d s + [ i d ] 386 2 2 : 0 0 End; { of N o t e l d } 387 2 2 : 0 0 388 2 2 : d 1 Procedure FetchName; 389 2 6 : d 1 Var oldname, newname: sb_name; 390 2 6 : 0 0 Begin 391 2 6 : 1 0 w i t h param® do 392 2 6 : 2 5 Begin 393 2 6 : 3 5 oldname:= name; 394 2 6 : 3 12 name:= ''; 395 2 6 :3 2 1 Repeat 396 2 6 : 4 2 1 F e t c h S t r i n g (x_name, y_name, newname, f_name) 397 2 6 : 3 26 U n t i l PrmNamed (newname) = n i l ; 398 2 6 :3 37 name:= newname; 399 2 6 : 3 44 s b T o s s S t r i n g (name, name_dspl); 400 2 6 : 3 52 i f measure <> n i l then ana_names[measure®.chan_1n] 401 2 6 : 3 77 i f UpperChar (name[1]) i n v a l i d _ i d s then 402 2 6 : 4 96 Beg i n 403 2 6 :5 96 Pool Id; 404 2 6 : 5 98 id:= UpperChar (name[1]): 405 2 6 : 5 1 1 1 N o t e l d ; 406 2 6 : 5 113 TossChar (x i d , y i d , id) 407 2 6 : 4 1 19 End { of i f } 408 2 6 : 2 12 1 End < of with ) 409 2 2 :0 0 End; ( o f 'N' ) 4 10 2 2 :0 0 41 1 2 2 :d 1 F u n c t i o n F u l l S c a l e : r e a l ; 412 2 7 :0 0 Begin 4 13 2 7 : 1 0 with param® do 4 14 2 7 : 2 4 Begin 4 15 2 7 : 3 4 i f measure = n i l 4 16 2 7 : 3 7 then Fu11Scale:= 1.0E38 417 2 7 : 3 1 1 e l s e F u l l Scale:= measure®.sea 1 e _ i n * 10000.0 4 18 2 7 : 2 24 End { of w i t h > 4 19 2 2 :0 0 End; < of F u l l S c a l e } 4 20 2 2 :0 0 42 1 2 2 : d 1 Procedure ChangeBeep; 422 2 8 :0 0 Beg i n 423 2 8 : 1 0 w i t h param® do beep:= TossNot (x_beep, y_beep, beep) 424 2 2 :0 0 End; ( of ChangeBeep } 425 2 2 :0 0 426 2 2 :d 1 Procedure BeepOn; 427 2 9 :0 0 Beg i n 428 2 9 : 1 0 i f not param®.beep then ChangeBeep 429 2 2 :0 0 End; { of BeepOn } Appendix C Compiler L i s t i n g of U n i t ParamEdit Page 430 2 2 0 0 Procedure SetDecimal ( d s p l : s b _ d s p l _ p t r ) ; 431 2 2 d 1 432 2 10 0 0 Beg i n 433 2 10 1 0 dspl®.format.dec_field:= d_re 434 2 2 0 0 End; { of SetDecimal > 435 2 2 0 0 436 2 2 d 1 Procedure CalcMaxerr; 437 2 1 1 0 0 B e g i n 438 2 1 1 1 0 w i t h param®.measure® do 439 2 1 1 2 6 Beg i n 440 2 1 1 3 6 maxerr:= trunc (0.499999 / s c a l e _ i n / pwroften ( d _ r e ) ) ; 44 1 2 1 1 3 33 PrmAnaSet (param) 442 2 1 1 2 36 End { of with ) 443 2 2 0 0 End; { of CalcMaxerr } 444 2 2 0 0 445 2 2 d 1 Procedure F e t c h F u l 1 ; 446 2 12 0 0 B e g i n 447 2 12 1 0 w i t h param® do 448 2 12 2 4 measure®.sea 1e i n : = 449 2 12 2 9 FetchReal (x f u l l , y f u l l , f _ r e . d_re. 1.0E-32, 1.0E38) 450 2 12 2 26 / 10000.0: 451 2 12 1 33 CalcMaxerr 452 2 2 0 0 End: < of FetchFul1 } 453 2 2 0 0 454 2 2 0 0 Begin < + * * ParamEdt *** } 455 2 2 1 0 v a l i d _ i d s : = ['0'..'9'. 'A'..'Z']; 456 2 2 1 13 param:= PrmL i s t ; 457 2 2 1 20 w h i l e param <> n i l do 458 2 2 2 26 Beg i n 459 2 2 3 26 N o t e l d ; 460 2 2 3 28 param:= param®.next 46 1 2 2 2 3 1 End; { of w h i l e ) 462 2 2 1 37 S c r n E n t e r (edit_1mage); 463 2 2 1 44 464 2 2 1 44 i f r u nning then 465 2 2 2 50 Repeat 466 2 2 3 50 param:= PrmPrmpt (0. 0, 'ParamEdit', f a l s e , f a l s e ) ; 467 2 2 3 66 i f param <> n i l then with param® do 468 2 2 5 80 Beg i n 469 2 2 6 80 with val dspl®.format do 470 2 2 7 90 Beg i n 47 1 2 2 8 90 f re:= f i e l d ; d re:- d e c _ f i e l d 472 2 2 7 101 End; 473 2 2 6 1 12 T o s s S t r i n g (x name, y name, name, f_name); 474 2 2 6 124 T o s s S t r i n g ( x _ u n i t , y _ u n i t , u n i t s . f _ u n i t ) ; 475 2 2 6 1 36 TossChar ( x _ i d , y _ i d , i d ) ; 476 2 2 6 146 TossReal (x_uppr, y_uppr, h i g h l i m , f _ r e , d _ r e ) ; 477 2 2 6 163 T o s s l n t e g e r ( x d e c , y_dec, d r e , f _ d e c ) : 478 2 2 6 172 TossReal (x_wa11, y_wa11, del ay/60.0. f _ w a i t , d_wa11); 479 2 2 •6 189 TossBoolean (x_beep, y_beep, beep); Appendix C Compiler L i s t i n g of U n i t ParamEdit Page 480 2 2 : 6 199 48 1 2 2 : 6 208 482 2 2 : 6 2 19 483 2 2 : 6 222 484 2 2 : 6 235 485 2 2 : 6 240 486 2 2 : 8 243 487 2 2 : 8 249 488 2 2 : 7 255 489 2 2 : 6 257 490 2 2 : 8 267 49 1 2 2 : 9 267 492 2 2 : 9 270 493 2 2 : 9 290 494 2 2 : 9 300 495 2 2 : 8 313 496 2 2 : 6 315 497 2 2 : 6 320 498 2 2 : 8 323 499 2 2 : 8 329 500 2 2 : 7 333 501 2 2 :6 335 502 2 2 :8 345 503 2 2 :9 345 504 2 2 :9 348 505 2 2 : 9 368 506 2 2 : 9 389 507 2 2 :8 401 508 2 2 :8 403 509 2 2 :6 403 5 10 2 2 : 7 403 51 1 2 2 : 7 445 512 2 2 : 7 453 513 2 2 :8 459 514 2 2 :8 463 515 2 2 :8 468 516 2 2 :0 468 517 2 2 :0 479 518 2 2 :9 489 5 19 2 2 : 8 494 520 2 2 :0 494 52 1 2 2 :0 496 522 2 2 :0 502 523 2 2 :0 519 524 2 2 :0 529 525 2 2 :9 529 526 2 2 : 8 534 527 2 2 : 9 539 528 2 2 :8 563 529 2 2 :0 563 chan); re) prompt:= name; prompt!1]:= UpperChar (prompt[1]) AddPrompt ( 0 ) ; match:= [ ' N ' , 'U', ' I ' . 'L', ' D ' , i f measure = n i1 then B e g i n TossBlanks (x_chan, y_chan, TossBlanks ( x _ f u l l , y _ f u l 1 , End { of then } e l s e with measure® do Beg i n AddPrompt (1 ) ; match:= match + ['C, ' F ' J ; T o s s l n t e g e r (x_chan, y_chan, TossReal ( x _ f u l l , y _ f u l i , F u l l S c a l e , End; { of e l s e } i f con tro1 = n i l then Begin TossBlanks (x_slew, y_slew, TossBlanks (x_enab, y_enab, End { of then } e l s e w i th control® do B e g i n AddPrompt ( 2 ) ; -match:= match + t'S', ' E ' ] ; T o s s l n t e g e r (x_slew, y_slew, TossBoolean (x_enab, y_enab, End; { of e l s e > '0' ] chan i n f_s1ew ) ; 5) , f _ c h a n ) ; f re,. d re) round (10.0/(D+1.0)), f _ s l e w ) : s e t dspl®.format.enabled) O ( u i t ' ) , match); Repeat ch:= PromptCapIn (0, 0, concat(prompt, i f ch <> '0' then PrmEdited: i f r u n n i n g then Case ch of 'N': FetchName; 'U' : Beg i n F e t c h S t r i n g ( x _ u n i t , y _ u n i t , u n i t s , f _ u n i t ) ; S b T o s s S t r i n g ( u n i t s , u n i t _ d s p l ) End; ' I ' : Beg i n Pool Id; TossBlanks ( x _ i d , y _ i d , 1); id:= FetchCapIn ( x _ i d , y _ i d , v a l i d _ i d s ) ; TossChar (x_1d, y _ i d , i d ) ; N o t e l d End; ' L ' : high1 im: = FetchReal (x_uppr, y_uppr, f _ r e , d_re, 0.0, F u l l S c a l e ) : ' D ' : Beg i n d_re:= F e t c h l n t e g e r (x_dec, y_dec, f_dec, 0, f _ r e - 3 ) ; Appendix C Compiler L i s t i n g of U n i t ParamEdit Page 5 530 2 2 :0 579 531 2 2 :0 586 532 2 2 : 1 594 533 2 2 :0 602 534 2 2 :0 612 535 2 2 :9 612 536 2 2 :8 617 537 2 2 :0 617 538 2 2 :0 625 539 2 2 :0 648 540 2 2 :0 662 54 1 2 2 :9 662 542 2 2 :8 667 543 2 2 : 8 672 544 2 2 :0 680 545 2 2 : 1 680 546 2 2 : 1 699 547 2 2 : 1 702 548 2 2 : 1 7 15 549 2 2 :0 728 550 2 2 :8 739 551 2 2 :8 744 552 2 2 :0 752 553 2 2 : 1 752 554 2 2 : 1 767 555 2 2 : 1 776 556 2 2 :0 776 557 2 2 :8 780 558 2 2 :0 797 559 2 2 : 1 797 560 2 2 : 1 815 561 2 2 : 2 823 562 2 2 :3 823 563 2 2 : 3 848 564 2 2 : 2 858 565 2 2 : 1 860 566 2 2 :0 871 567 2 2 :8 874 568 2 2 :6 879 569 2 2 :6 880 570 2 2 :5 880 57 1 2 2 :2 886 572 2 2 :2 894 573 2 2 : 1 894 574 2 1 :0 0 575 2 1 :0 0 576 2 1 :0 0 577 2 :0 0 End of C o m p i l a t i o n . SetDecimal ( v a l _ d s p l ) ; i f c o n t r o l <> n i l then SetDecimal (contro1 ©.set_dsp1): i f measure <> n i l then C a l c M a x e r r ; BeepOn End; { of 'D' > 'W' : Beg i n de1ay:= round (60.0 * FetchReal (x_wait, y_wait, f _ w a i t , d_wa1t, 0.01, 99.99)); i f measure <> n i l then PrmAnaSet (param); BeepOn End; < of 'W } 'B': ChangeBeep: 'C': with measure® do Beg i n ana_names[chan_in]:= ''; chan_in:= F e t c h l n t e g e r (x_chan, y_chan, f_chan, 1, 16); ana_names[cnan_in]:= name End: { of 'C } 'F' : FetchFul1 ; 'S': with control© do Beg i n D:- 10.0 / Fetchlnteger(x_s1ew,y_s1ew,f_s1ew,1.10) - 1.0; BeepOn End; { of 'S' ) 'E': with control®, set_dsp1©.format do Begi n enabled:= TossNot ( x e n a b , y_enab, e n a b l e d ) ; i f e n a b l e d then Beg i n s e t p o i n t : = rBounded ( v a l u e , 0.0, h i g h l i m ) ; sbTossReal ( s e t p o i n t . s e t _ d s p l ) End: ( of i f > i f measure <> n i l then PrmAnaSet (param) End ( o f 'E' } End { Case } U n t i l ch = '0' End ( o f i f with param® > Unt i1 param = n i l ; ScrnReturn End: { of PrmEdit > End. cn Appendix C Compiler L i s t i n g of Un i t Walker Page 1 3 0 0 d 1 {$L remout:} 4 2 1 d 1 U n i t Walker; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 Procedure ParamWalk; i 9 2 1 d 1 < s e t up f o r walki n g of a parameter s e t p o i n t between two bounds } 10 2 1 d 1 1 1 2 1 d 1 Procedure wkHalt; 12 2 1 d 1 < s a f e l y e x i t from w a l k i n g p r o c e s s } 13 2 1 d 1 14 2 1 d 1 Implementat i on 15 2 1 d 1 16 2 1 d 1 247 2 1 d 1 {$L-} Uses Clock, Schedule, WritCons, ReadKybd, S c r n B u f f , {$L®} 342 2 1 d 1 {$L-> Parameter, P a r a m U t i l , <$L®> 353 2 1 d 1 {$L-} <$U u t i 1 : s t a r t e r . c o d e ) S t a r t e r ; ($L®> 354 ' 2 1 d 1 355 2 1 d 1 356 2 1 d 1 Type move = (down, stop, up); 357 2 1 d 1 358 2 1 d 1 359 2 1 d 1 Var param: param_ptr; 360 2 1 d 2 bottom, top, dset dt, minutes: r e a l ; 361 2 1 d 10 w d e l a y : i n t e g e r ; 362 2 1 d 1 1 motion: move; 363 2 1 d 12 tO: tim r e c ; 364 2 1 d 14 wa1k: semaphore: 365 2 , 1 d 16 366 2 1 d 16 367 2 1 d 16 P rocess WalkSetp; forward; 368 2 1 d 1 369 2 1 d 1 370 2 1 d 1 371 2 1 d 1 Segment Procedure W a l k l n i t ; 372 1 1 1 d 1 Var p i d : p r o c e s s i d ; 373 1 1 1 d 2 st a c k , p r i o : i n t e g e r ; 374 1 1 1 0 0 Beg i n 375 1 1 1 1 0 param:= n i l ; 376 1 1 1 1 3 mot ion:= st o p : 377 1 1 1 1 6 minutes:= 30.0; 378 1 1 1 1 12 sem i n i t ( w a l k . O ) ; 379 1 1 1 1 2 1 S t r t l n f o ('WALKER', 'WALKSETP', s t a c k , p r i o , t r u e ) ; 380 1 1 1 1 37 s t a r t (WalkSetp, p i d , s t a c k , p r i o ) 381 1 1 1 0 0 End; { of W a l k l n i t } 382 1 1 1 0 0 383 1 1 1 0 O 384 1 1 1 0 0 385 2 1 d 1 Segment Procedure PrmWalk; Appendix C Compiler L i s t i n g of U n i t Walker 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 4 10 41 1 412 4 13 4 14 415 4 16 417 418 4 19 420 42 1 422 423 424 425 426 427 428 429 430 43 1 432 433 434 435 2 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 1 :0 { s e t Const up f o r w a l k i n g of a parameter s e t p o i n t 5:4 2 3 5 6 6 1 1 0 4 0 0 0 4 13 22 27 O 0 1 0 0 4 4 8 8 0 0 1 0 0 2 3 6 1 1 16 20 22 35 35 53 62 73 xname x 1 ow x 1 unt x t i me xmove 18 12 20 20 24 yname xh i gh xhunt y t i me ymove 8 43 51 13 16 f name yrang fu n i t f t i me f move 8 1 1 4 6 7 Page between two bounds } { parameter d i s p l a y } f r a n g = 1 2 : { range } { range bound u n i t s } dt ime = 1: { t ime > < motion d i s p l a y > Var ch: char; prompt: sb_prmt_ptr; f _ r e , d_re: i n t e g e r ; mov: move; Procedure TossMove: Type movestring = s t r i n g [ f m o v e ] ; Procedure T o s s S t r ( s : m o v e s t r i n g ) : Begin T o s s S t r i n g (xmove, ymove. s. fmove) End: { of T o s s S t r ) Begin { ** TossMove ** } Case mov of down: T o s s S t r ('down'); stop: T o s s S t r ('stopped'): up T o s s S t r ('up' ) End { of Case } End; < of TossMove > Procedure SetMotion (m: move): Begin i f param <> n i l then Beg i n mov:= m; TossMove End; ( of SetMotion > End; { of SetMotion ) Procedure TossParam; Begin TossMove; i f param = n.i 1 then Begin TossBlanks (xname, yname, TossBlanks (x1ow, yrang, TossBlanks (xhigh, yrang. End < of n i l > e l s e with param®, c o n t r o l s _ Begi n f_re:= f i e l d ; d_re:= d e c _ f i e l d : T o s s S t r i n g (xname. yname, name, fname); TossReal (xlow, yrang, bottom, f _ r e . d_re) T o s s S t r i n g ( x l u n t , yrang, u n i t s , f u n i t ) ; fname); f r a n g ) : f r a n g ) , s e t dspl®.format do CO Appendix C Compiler L i s t i n g of Un i t Walker Page 436 14 5 4 82 TossReal (xhigh, yrang, top, f _ r e , d _ r e ) : 437 14 5 4 94 T o s s S t r i n g (xhunt, yrang, u n i t s , f u n i t ) 438 14 5 3 102 End { of not n i l > 439 14 1 0 0 End: { of TossParam } 440 14 1 0 0 44 1 14 1 0 0 Begin { *** PrmWalk +** } 442 14 1 1 0 mov:= mot i on; 443 14 1 1 2 S c r n E n t e r ('WALKSET'): 444 14 1 1 9 prompt:= ScrnPrompt ( 0 ) ; 445 14 1 1 18 TossParam; 446 14 1 1 20 TossReal (xtime, ytime, minutes, f t i m e , d t l m e ) : 447 14 1 1 29 i f running then 448 14 1 2 35 Repeat 449 14 1 3 35 ch:= PromptCapIn (0, 0. prompt®, ['P'.'L'.'H'.'T ' , ' U ' , ' D ' 450 14 1 3 51 i f ch <> 'E' then motion:= stop: 45 1 14 1 3 59 i f r u nning then 452 14 1 4 65 Case ch of 453 14 1 4 68 ' P ' : 454 14 1 5 68 Begin 455 14 1 6 68 param:= PrmPrmpt (0. 0. 'Walker', f a l s e . t r u e ) ; 456 14 1 6 83 i f param = n i l 457 14 1 6 84 then mov:= stop 458 14 1 6 87 e l s e B e g i n 459 14 1 8 91 bdttorn:= param®.control®.setpo1nt; 460 14 1 8 100 top:= bottom 461 14 1 7 102 End; { of <> ni1 > 462 14 1 6 106 TossParam 463 14 1 5 106 End; { of 'P' } 464 14 1 4 1 10 'L' : 465 14 1 5 1 10 i f param <> n i l then 466 14 1 6 1 14 bottom:= FetchReal (xlow, yrang, f _ r e , d _ r e , 0.0, 467 14 1 4 133 'H' : 468 14 1 5 133 i f param <> n i l then 469 14 1 6 137 top:= FetchReal ( x h i g h , yrang, f _ r e , d_re, 470 14 1 6 146 bottom, param®.highlim) ; 471 14 1 4 158 'T' : 472 14 1 5 158 minutes:^ FetchReal (xtime, ytime, f t i m e . dtlme, 0. 473 14 1 4 177 'U' : 474 14 1 5 177 SetMot ion (up); 475 14 1 4 182 'D' : 476 14 1 5 182 SetMotion (down); 477 14 1 4 187 'S' : 478 14 1 5 187 SetMotion ( s t o p ) 479 14 1 4 188 End < of Case } 480 14 1 2 195 U n t i l not running or (ch = 'E ' ) : 48 1 14 1 1 207 i f top = bottom then mov:= stop; 482 14 1 1 218 i f (motion = stop) and (mov <> stop ) then 483 14 1 2 227 Beg i n 484 14 1 3 227 PrmPoint (param®.contro1®.setpoint, param); 485 14 1 3 236 dset dt:= ( t o p - bottom) / (60.0 * min u t e s ) ; 'S' , 'E' ]); (—1 i t * 10 Appendix C Compiler L i s t i n g of U n i t Walker Page 4 486 14 1 : 3 254 w delay:= round (60.0 / pwroften ( d _ r e ) / d s e t _ d t ) ; 487 14 1 : 3 270 i f mov = down then dset_dt:= - d s e t _ d t ; 488 14 1 : 3 281 with tO do time ( h i word, loword); 489 14 1 : 3 290 mot i on:= mov; 490 14 1 : 3 293 s i gna1 (wa1k ) 49 1 14 1 : 2 296 End; { of motion > 492 14 1 : 1 296 ScrnReturn 493 14 1 : 0 0 End; { of Segment PrmWalk } 494 14 1 : 0 0 495 14 1 : 0 0 496 2 1 : d 1 Procedure ParamWalk; 497 2 2 : 0 0 B e g i n 498 2 2 : 1 0 PrmWa1k 499 2 1 : :0 0 End: ( of ParamWalk > 500 2 1 : 0 0 501 2 1 : :0 0 502 2 1 : :d 1 P r o c e s s WalkSetp; 503 2 4 : d 1 Var t, d t : t i m_rec: 504 2 4 : d 5 F u n c t i o n KeepWalking: boolean; 505 2 5 :0 0 B e g i n 506 2 5 : 1 0 with param©.control® do 507 2 5 : 2 4 KeepWalking:= r u n n i n g 508 2 5 : 2 4 and ( ( (motion = down) and ( s e t p o i n t > bottom) 509 2 5 : 2 20 or ( (motion = up) and ( s e t p o i n t < top) ) 510 2 4 :0 0 End; { of KeepWalking ) 51 1 2 4 :0 0 Beg i n 512 2 4 : 1 2 wa11 (wa1k ) ; 5 1 3 2 4 : 1 5 wh i1e runn i ng do 514 2 4 : 2 10 B e g i n 515 2 4 : 3 10 W a i t T i c k (w_delay); 516 2 4 : 3 13 whil e KeepWalking do 517 2 4 : 4 18 Beg i n 518 2 4 : 5 18 with t do time (hiword, loword); 519 2 4 : 5 22 TimMinus ( d t . t . tO); 520 2 4 : 5 28 PrmPoint (param®.control®.setpoint 521 2 4 :5 33 + d s e t _ d t * TimlnSeconds ( d t ) , param); 522 2 4 :5 47 tO:= t; 523 2 4 :5 53 i f KeepWalking then W a i t T i c k (w_delay) 524 2 4 : 4 59 End; { of w h i l e KW } 525 2 4 : 3 63 mot ion:= stop; 526 2 4 : 3 66 i f r u nning then wait (walk) 527 2 4 : 2 74 End { of w h i l e r u n n i n g } 528 2 1 :0 0 End: { of WalkSetp > 529 2 1 :0 0 530 2 1 :0 0 531 2 1 :d 1 Procedure wkHa1t; 532 2 1 : d 1 < s a f e l y e x i t from w a l k i n g p r o c e s s ) 533 2 3 :0 0 Beg i n 534 2 3 : 1 0 s i gna1 (wa1k) 535 2 1 :0 O End: < of wkHalt ) Appendix C Compiler L i s t i n g of U n i t Walker Page 536 2 1 :0 0 537 2 1 :0 0 538 2 1 :0 0 Begi n 539 2 1 : 1 0 W a l k l n i t 540 2 :0 0 End. End of C o m p i l a t i o n . Appendix C Compiler L i s t i n g of U n i t ParamSave Page 1 3 0 0 d 1 {$L remout:> 4 2 1 d 1 Uni t ParamSave; 5 2 1 d 1 6 2 1 d 1 7 2 1 d 1 I n t e r f a c e 8 2 1 d 1 9 2 1 d 1 Var param time: r e a l ; { time of l a t e s t parameter read r e c o r d } IO 2 1 d 1 1 2 1 d Procedure ParamReset: 12 2 1 d 1 { r e s e t parameter read f i l e > 13 2 1 d 1 14 2 1 d 1 F u n c t i o n ParamGet (wait_ok: b o o l e a n ) : b o o l e a n : 15 2 1 d 1 { update read f i l e r e c o r d (wait f o r I t ? ) , r e t u r n t r u e i f not eof ) 1G 2 1 d 1 17 2 1 d 1 Procedure ParamFile; 18 2 1 d 1 { s e t up parameter input $ output f i l e s } 19 2 1 d 1 20 2 1 d 1 Procedure p f H a l t ; 21 2 1 d 1 ( s a f e l y shut down w r i t i n g p r o c e s s ) 22 2 1 d 1 23 2 1 d 1 Implementa11 on 24 2 1 d 3 25 2 1 d 3 226 2 1 d 3 {$L-> Uses Clock, E12AnaI0, Schedule, ScreenOps, {$L©} 347 2 1 d 3 {$L-> E x t r a S c r , WritCons. ReadKybd, ErrMessg, ($L®> 540 2 1 d 3 {$L-} MiscFunc, S c r n B u f f , Parameter, P a r a m U t i l , <$L@) 551 2 1 d 3 {$L-} ($U u t i 1 : s t a r t e r . c o d e ) S t a r t e r ; ($L®) 552 2 1 d 3 553 2 1 d 3 ($1- t u r n o f f io c h e c k i n g : i o r e s u l t i s looked at when n e c e s s a r y 554 2 1 d 3 555 2 1 d 3 556 2 1 d 3 Const s u f f i x = '.PDAT': { parameter d a t a f i l e s u f f i x > 557 2 1 d 3 no f i l e = " ; { ' f i l e name' f o r no f i l e } 558 2 1 d 3 559 2 1 d 3 Var r e a d f i l e , w r i t e f i l e : f i l e of r e a l ; { parameter save f i l e s ) 560 2 1 d 3 561 2 1 d 607 r e a d l i s t , w r i t e l i s t : param_ptr; { l i s t of 1/o parameters ) 562 2 1 d 609 readname, writename: s t r i n g ! 1 8 ] ; { names of f i l e s } 563 2 1 d 629 readopen, writeopen: boolean; ( f i l e s opened? } 564 2 1 d 63 1 r e w r i t t e n : semaphore; { w r i t e f i l e opened } 565 2 1 d 633 enabled: boolean: { o k . to go ahead and w r i t e d a t a } 566 2 1 d 634 s i n g l e : boolean; ' { but o n l y f o r a s i n g l e r e c o r d } 567 2 1 d 635 w r i t e d a t a : semaphore; { s i g n a l when ena b l e d > 568 2 1 d 637 ignore, i n t e g r a t e : i n t e g e r ; { t i c k s between 8. d u r i n g averages 569 2 1 d 639 r average: r e a l ; { read f i l e ' s i n t e g r a t e , seconds } 570 2 1 d 64 1 r e a d w r i t e : boolean: { read f i l e = w r i t e f i l e } 57 1 2 1 d 642 rw a v a i l : semaphore; { new w r i t e d a t a a v a i l a b l e i n read f i l e 572 2 1 d 644 rw v a l i d : boolean; { " " " i s v a l i d ) 573 2 1 d 645 Ln Appendix C Compiler L i s t i n g of Un i t ParamSave Page 574 2 1 d 575 2 1 d 576 2 1 d 577 2 1 d 578 2 1 d 579 2 1 d 580 2 1 d 581 2 1 d 582 2 1 d 583 16 1 d 584 16 1 d 585 16 1 d 586 16 1 d 587 16 1 d 588 16 1 d 589 16 1 d 590 16 1 d 591 16 1 d 592 16 1 d 593 16 1 d 594 16 1 d 595 16 1 d 596 16 1 d 597 16 1 d 598 16 1 d 599 16 1 d 600 16 1 d 601 16 1 d 602 16 2 0 603 16 2 1 604 16 1 0 605 16 1 0 606 16 1 d 607 16 3 0 608 16 3 1 609 16 3 1 610 16 1 0 61 1 16 1 0 612 16 1 d 613 16 4 0 614 16 4 1 615 16 4 1 616 16 1 0 617 16 1 0 618 16 1 d 619 16 5 0 620 16 5 1 62 1 16 1 0 622 16 1 0 623 16 1 d 645 645 Procedure PFPut (err_num: i n t e g e r ) ; forward; { put ( w r i t e f i l e ) . i f i o e r r o r then N o t e E r r o r (err_num) 2 3 7 8 9 10 10 0 0 0 0 1 0 0 2 0 0 1 0 0 8 0 0 1 0 0 0 0 1 Segment Procedure P r m F i l e ; { s e t up parameter input & output f i l e s } Const x_rnam = = 7 y rnam = = 19 f_name = 23 x wnam = = 7 y wnam -= 10 x c y c l = = 17 y c y c l • = 1 1 f c y c l = 7; x_wint = = 18 y w i nt • = 12 f _ i n t = 6; x r1nt = - 18 y r1nt = = 20 x r 1 s t = - 64 x wist = = 44 { parameter y _ l i s t = = 4 f _ l i s t = = 8 Type n _ s t r i n g = s t r i n g [ f _ n a m e ] ; q _ s t r i n g = s t r 1 n g [ 3 9 ] : Var ch: char; prompt: sb_prmt_ptr; c y c l e , average: r e a l ; param: param_ptr; y: i n t e g e r ; w r i t e _ o k : boolean; Procedure C h e c k E r r o r ; r Begi n i f E r r o r N o t e d then e x i t ( P a r a m F i l e ) End; { of CheckError ) Procedure TaskSwitch; Begin Pol 1 Inputs; C h e c k E r r o r End; { of TaskSwitch ) Procedure E r r o r (n: i n t e g e r ) ; Beg i n N o t e E r r o r (n, i o r e s u l t . f a l s e ) ; TaskSwi t c h End; ( of E r r o r ) Procedure TossWName; Beg i n T o s s S t r i n g (x_wnam. y_wnam, writename, f_name) End; ( of TossWName > Procedure TossRName; ui Appendix C Compiler L i s t i n g of U n i t ParamSave Page 3 624 16 6 0 0 Beg i n 625 16 6 1 0 T o s s S t r i n g (x rnam. y mam, readname, f_name) 626 16 1 0 0 End; {• of TossRName > 627 16 1 0 0 628 16 1 d 1 F u n c t i o n Ask ( q u e s t i o n : q _ s t r i n g ) : boolean; 629 16 7 0 0 Begin 630 16 7 1 5 u n i t c l e a r ( 1 ) ; { dump type ahead b u f f e r > 631 16 7 1 8 Ask:= PromptCapIn (0, 0, q u e s t i o n , ['Y'.'N']) = 'Y'; 632 16 7 1 29 CheckError 633 16 1 0 0 End; { of Ask ) 634 16 1 0 0 F u n c t i o n FetchName (x, y: i n t e g e r ; var name: n _ s t r 1 n g ) : boolean 635 16 1 d 1 636 16 8 d 1 Var l e n , f i e l d : i n t e g e r ; 637 16 8 O 0 Beg i n 638 16 8 1 0 F e t c h S t r i n g (x, y, name, f_name); 639 16 8 1 10 CheckError; 640 16 8 1 12 i f name = no_f i1e 64 1 16 8 1 14 then FetchName:= f a l s e 642 16 8 1 22 e l s e Begin 643 16 8 3 27 FetchName := true;. 644 16 8 3 30 Uppercase (name); 645 16 8 3 35 1 en : = l e n g t h (name); 646 16 8 3 40 i f ( l e n <= 5) or (pos ( s u f f i x , name) <> len-5) then 647 16 8 4 62 Beg i n 648 16 8 5 62 f i e l d : = pos (':'. name) + 10; 649 16 8 5 77 i f l e n > f i e l d then d e l e t e (name, f i e l d + 1 , l e n - f i e l d ) ; 650 16 8 5 92 name:= concat (name, s u f f i x ) 651 16 8 4 1 15 End ( o f i f pos } 652 16 8 2 1 18 End { of name <> '' > 653 16 1 0 0 End: ( of FetchName } 654 16 1 0 0 Procedure TossPName (x: i n t e g e r : name: n _ s t r i n g ) ; 655 16 1 d 1 656 • 16 9 0 0 Begin 657 16 9 1 5 T o s s S t r i n g (x, y, name, f _ l i s t ) ; 658 16 9 1 13 TaskSw i t c h ; 659 16 9 1 15 y:= y + 1 660 16 1 0 0 End; { of TossPName > 661 16 1 O 0 662 16 1 d 1 Procedure TossWList; 663 16 10 d 1 Var param: param_ptr; 664 16 10 0 0 Beg 1 n 665 16 10 1 0 y:= y_1 i s t: 666 16 10 1 4 param:= w r i t e l i s t ; 667 16 10 1 8 wh i l e param <> n i l do w i t h param® do 668 16 10 3 14 Begin 669 16 10 4 14 TossPName (x w i s t , name); 670 16 10 4 22 param:= w r i t e _ n e x t 67 1 16 10 3 22 End; { of w h i l e > 672 16 10 1 28 i f y < 24 then TossBlanks (x w i s t , y, f _ l i s t ) 673 16 1 0 0 End; { of TossWList ) Cn Appendix C Comp11er L i s t i n g of U n i t ParamSave Page 4 674 16 1 0 0 675 16 1 d 1 Procedure T o s s R L i s t : 676 16 1 1 d 1 Var param: param_ptr: 677 16 1 1 0 0 Begin 678 16 1 1 1 0 y:= y _ l i s t ; 679 16 1 1 1 4 param:= read l i s t ; 680 16 1 1 1 8 w h i l e param <> n i l do with param© do 681 16 1 1 3 14 Begi n 682 16 1 1 4 14 TossPName ( x _ r l s t . name); 683 16 1 1 4 22 param:= read_next 684 16 1 1 3 22 End; { of whi1e > 685 16 1 1 1 28 f o r y:= y to 24 do TossBlanks ( x _ r l s t , y. f _ l 1 s t ) ; 686 16 1 1 1 56 i f readopen 687 16 1 1 1 56 then TossReal (x r i n t . y r i n t , r _ a v e r a g e . f _ i n t , 2) 688 16 1 1 1 69 e l s e TossBlanks (x r i n t , y r i n t . f _ 1 n t ) 689 16 1 0 0 End; { of T o s s R L i s t } 690 16 1 0 0 691 16 1 d 1 Procedure T o g g l e W r i t e ; 692 16 12 d 1 Var l i n k : param_ptr; 693 16 12 0 0 Begi n 694 16 12 1 0 i f w r i t e l i s t = param 695 16 12 1 3 then Begin { param i s f i r s t i n l i s t : remove i t } 696 16 12 3 7 w r i t e l i s t : = param©.writenext; 697 16 12 3 14 param©.writenext:= n i l 698 16 12 2 18 End 699 16 12 1 20 e l s e i f w r i t e l i s t = n i l 700 16 12 2 25 then w r i t e l i s t : = param { 11st was empty: add param 701 16 12 2 28 e l s e Begin 702 16 12 2 35 { check remainder of l i s t f o r param } 703 16 12 4 35 1i nk:= w r i t e l i s t ; 704 16 12 4 39 Repeat with link® do 705 16 12 6 4 1 i f w r i t e n e x t = param 706 16 12 6 44 then Begin 707 16 12 6 48 < param i s i n l i s t : remove i t } 708 16 12 8 48 wr1tenext:= wr1tenext©.wr i t e n e x t ; 709 16 12 8 57 param©.wr1tenext:= n i l ; 710 16 12 8 63 l i n k : = n i l { q u i t Repeat loop ) 7 1 1 16 12 7 63 End { of remove ) 712 16 12 6 65 e l s e Begin { param not yet found } 713 16 12 8 67 i f w r i t e n e x t = n i l then 714 16 12 9 73 Beg i n 715 16 12 9 73 { param not in w r i t e l i s t : add i t to the 11st ) 716 16 12 0 73 param©.writenext:= w r i t e l i s t ; 717 16 12 0 81 w r i t e l i s t : = param 7 18 16 12 9 81 End; 719 16 12 8 86 l i n k : = w r i t e n e x t { t r y next l i n k ) 720 16 12 7 86 End < of not yet found } 72 1 16 12 4 90 Unt i1 1 ink = ni1 722 16 12 3 91 End; { of look through l i s t ) 723 16 12 1 94 TossWL i s t <_n Appendix C Comp i 1 e r L i s t i n g of U n i t ParamSave Page 5 724 16 1 : :0 0 End; { of ToggleWrite > 725 16 1 : :0 0 726 16 1 : :d 1 Procedure EditWStatus; 727 16 13 : d 1 Var ch: char; 728 16 13: :d 2 prompt: sb prmt_ptr; 729 16 13: :0 0 Beg i n 730 16 13 : 1 0 prompt:= ScrnPrompt ( 1 ) ; 731 16 13 : 1 10 C h e c k E r r o r ; 732 16 13 : 1 12 Repeat 733 16 13 : 2 12 ch:= PromptCapIn (0. 0, prompt®, [ ' P ' , ' C ' , ' I ' , ' 0 ' ] ) : 734 16 13 : 2 29 C h e c k E r r o r ; 735 16 13 : 2 31 Case ch of 736 16 13 : 2 34 'P': { determine parameters to save > 737 16 13 :3 34 Repeat 738 16 13 : 3 34 { prompt f o r parameter to save } 739 16 13 : 4 34 param:= PrmPrmpt 740 16 13 :4 34 (0, 0, 'Write Parameters', f a l s e , f a l s e ) ; 74 1 16 13 :4 50 C h e c k E r r o r ; 742 16 13 :4 52 i f param <> n i l 743 16 13 :4 54 then 744 16 13 : 4 57 { t o g g l e whether or not param i s i n w r i t e l i s t } 745 16 13 :5 57 ToggleWr i te 746 16 13 : 3 57 Unt i1 param = n i l ; 747 16 13 : 2 66 ' I ' : 748 16 13 : 3 66 average:= FetchReal (x wint, y_wint, f _ i n t , 2, 749 16 13 : 3 75 O O . rM1n (99.99, c y c l e ) ) 750 16 13 : 2 96 'C : 751 16 13 : 3 96 c y c l e : = FetchReal ( x _ c y c l , y_cyc1, f _ c y c 1 , 2, 752 16 13 : 3 105 average, 546 .1 1 ) 753 16 13 : 2 112 End ( of Case ) 754 16 13 : 1 12 1 Unt i1 ch = '0' 755 16 1 :0 0 End: { of EditWStatus } 756 16 1 :0 0 757 16 1 :d 1 Procedure PutName (name: sb_name); 758 16 14 :d 1 Var dummy: a r r a y {1..3] of r e a l ; 759 16 14 :d 7 i : i n t e ger; 760 16 14 :0 0 Beg i n 76 1 16 14 :0 0 { f o r e a s i e r Patch: } 762 16 14 : 1 6 f i l l c h a r (dummy, s i z e o f (dummy), ' ' ) ; 763 16 14 : 1 13 move l e f t (name, dummy, le n g t h (name) + 1): 764 16 14 : 1 25 f o r 1:= 1 to 3 do 765 16 14 : 2 34 Begi n 766 16 14 : 3 34 writefi1e@:= dummy[i]; 767 16 14 : 3 45 PFPut (402) 768 16 14 : 2 48 End; { of f o r > 769 16 14 : 1 55 TaskSwi t c h 770 16 1 :0 0 End; { of PutName } 77 1 16 1 :0 0 772 16 1 :d 1 Procedure ClosRead; 773 16 15 :0 0 Be g i n Appendix C Compiler L i s t i n g of U n i t ParamSave Page 6 774 16 15 1 0 c1ose ( r e a d f i1e ) ; 775 16 15 1 7 readopen:= f a l s e ; 776 16 15 1 1 1 readname:= n o _ f i l e ; 777 16 15 1 20 r e a d l i st:= n i l ; 778 16 15 1 24 i f r e a d w r i t e then 779 16 15 2 29 Beg i n 780 16 15 3 29 readwrite:= f a l s e ; 781 16 15 3 33 rw va1i d:= t r u e ; 782 16 15 3 37 s i gna1 (rw ava i1) 783 16 15 2 41 End; < of i f } 784 16 15 1 4 1 TaskSwi t c h ; 785 16 15 1 43 TossRL1st 786 16 1 0 0 End; { of ClosRead > 787 16 1 0 0 788 16 1 0 0 Begin { *** P r m F i l e *** } 789 16 1 1 0 Scr n E n t e r ('PARAMSAV'); 790 16 1 1 8 TaskSwi t c h ; 791 16 1 1 10 { w r i t e the i n f o r m a t i o n ) 792 16 1 1 10 TossWName: 793 16 1 1 . 12 average:^ i n t e g r a t e / 60.0: 794 16 1 1 22 c y c l e : = ( i g n o r e + i n t e g r a t e ) / 60.0; 795 16 1 1 36 TossReal (x c y c l , y _ c y c l , c y c l e , f _ c y c l , 2); 796 16 1 1 44 TossReal (x wint, y wint, average, f _ i n t , 2); 797 16 1 1 52 TossRName; 798 16 1 1 54 { l i s t the w r i t e parameters ) 799 16 1 1 54 TossWL i s t ; 800 16 1 1 56 { l i s t the read parameters ) 801 16 1 1 56 TossRL i s t ; 802 16 1 1 58 803 16 1 1 58 prompt:= ScrnPrompt ( 0 ) : 804 16 1 1 68 CheckError; 805 16 1 1 70 Repeat 806 16 1 2 70 ch:= PromptCapIn (0, 0, prompt®. 807 16 1 2 75 ['W','R',MapCommandKey (sc_escape_key, 808 16 1 2 95 C h e c k E r r o r ; 809 16 1 2 97 Case ch of 8 10 16 1 2 101 81 1 16 1 2 101 'W' : 8 12 16 1 3 101 Beg i n 813 16 1 4 101 1f writeopen then 814 16 1 4 106 < ensure a new w r i t e f i l e i s d e s i r e d ) 815 16 1 5 106 i f Ask ('Close o l d w r i t e f i l e ? ' ) then 816 16 1 6 1 16 Beg i n 817 16 1 7 1 16 c l o s e ( w r i t e f i l e , l o c k ) ; 818 16 1 7 122 enabled:= f a 1se; 8 19 16 1 7 126 writeopen:= f a l s e ; 820 16 1 7 130 writename:= no f i l e ; 82 1 16 1 7 139 i f r e a d w r i t e then 822 16 1 8 144 Beg i n 823 16 1 9 144 C1osRead; Appendix C Compiler L i s t i n g . o f U n i t ParamSave Page 7 824 16 1 9 146 TossRName 825 16 1 8 146 End; ( of i f 1 826 16 1 7 148 TaskSw i t e n 827 16 1 6 148 End; { of c l o s e o l d w r i t e f i l e } 828 16 1 6 150 829 16 1 6 150 { open new f i l e o n l y i f o l d one c l o s e d } 830 16 1 4 150 i f not w r i t e o p e n then 83 1 16 1 5 157 Beg i n 832 16 1 6 157 wr i te_ok:= f a l s e ; 833 16 1 6 160 i f FetchName (x wnam, y_wnam, writename) 834 16 1 6 166 then B e g i n 835 16 1 6 171 { see i f a l r e a d y e x i s t s > 836 16 1 8 171 r e s e t ( w r i t e f i l e . writename); 837 16 1 8 182 i f I o r e s u l t = 10 838 16 1 8 185 then Begin 839 16 1 0 188 wr i te_ok:= t r u e ; 840 16 1 0 191 c l o s e ( w r i t e f i l e . normal) { no problem ) 84 1 16 1 9 197 End { of 10 > 842 16 1 8 197 e l s e i f i o r e s u l t <> 0 843 16 1 9 202 then E r r o r (410) 844 16 1 9 208 e1se Beg i n , 845 16 1 1 212 TaskSw i t c h ; 846 16 1 1 2 14 { a l r e a d y e x i s t s ; d e s t r o y i t ? > 847 16 1 1 214 i f Ask (concat ('Destroy o l d ', writename 848 16 1 1 253 then B e g i n 849 16 1 3 257 w r i t e ok:= t r u e ; 850 16 1 3 260 c l o s e ( w r i t e f i l e , purge) ( remove i t } 851 16 1 2 266 End { of d e s t r o y ) 852 16 1 1 266 e l s e B e g i n 853 16 1 3 268 c l o s e ( w r i t e f i l e , n ormal): { don't " 854 16 1 3 274 writename:= n o _ f i 1 e 855 16 1 2 277 End; { of don't d e s t r o y > 856 16 1 1 283 TaskSwi t c h 857 16 1 0 283 End; { of a l r e a d y e x i s t s > 858 16 1 0 285 859 16 1 8 285 TossWName: 860 16 1 8 287 i f wr i te ok then 861 16 1 9 290 Begin 862 16 1 9 290 < o.k. to r e w r i t e new w r i t e f i l e } 863 16 1 0 290 TaskSwi t c h ; 864 16 1 0 292 r e w r i t e ( w r i t e f i l e , writename); 865 16 1 0 303 1 f i o r e s u l t <> 0 866 16 1 O 306 then E r r o r (400) 867 16 1 0 312 e l s e B e g i n 868 16 1 2 316 Edi tWStatus; 869 16 1 2 318 { ensure w r i t e l i s t i s not empty } 870 16 1 2 3 18 i f wr i t e l 1 s t = n i l 87 1 16 1 2 321 then Begin 872 16 1 4 324 c l o s e ( w r i t e f i l e , normal); 873 16 1 4 330 writename:= no f i l e : Append i x C Compiler L i s t i n g of U n i t ParamSave Page 8 874 16 1 4 339 TossWName 875 16 1 3 339 End { of n i l wri t e l 1 s t } 876 16 1 2 34 1 e l s e B e g i n 877 16 1 2 343 { save w r i t e l i s t names i n w r i t e f i l e } 878 16 1 4 343 param:= w r i t e l i s t ; 879 16 1 4 347 Repea t 880 16 1 5 347 PutName (param®.name); 88 1 16 1 5 353 param:= param®.wr1tenext 882 16 1 4 354 Unt i1 param = n i l ; 883 16 1 4 36 1 PutName (''); { f l a g end of names header } 884 16 1 4 368 i n t e g r a t e s round (60.0 * a v e r a g e ) ; 885 16 1 4 378 ignore:= round (60.0 * c y c l e ) - i n t e g r a t e ; 886 16 1 4 392 ( save I n t e g r a t i o n time } 887 16 1 4 392 writefile®:= average; 888 16 1 4 396 PFPut (403); 889 16 1 4 401 TaskSw i t c h ; 890 16 1 4 403 { t u r n on ParamPut p r o c e s s } 891 16 1 4 403 writeopen:= t r u e ; 892 16 1 4 407 s i g n a l ( r e w r i t t e n ) 893 16 1 3 41 1 End < of w r i t e l i s t <> n i l } 894 16 1 1 4 1 1 End < of no r e w r i t e e r r o r } 895 16 1 1 4 1 1 896 16 1 9 41 1 End < of writename <> no_f11e ) 897 16 1 7 4 1 1 End; { of w r i t e o p e n } 898 16 1 7 41 1 899 16 1 6 4 1 1 TaskSw i t c h 900 16 1 5 4 1 1 End { of open new w r i t e f i l e ) 901 16 1 5 4 13 902 16 1 3 4 13 End; { of 'W' } 903 16 1 3 416 904 16 1 2 4 16 ' R ' : 905 16 1 3 416 Begin 906 16 1 3 416 { i f read f i l e a l r e a d y opened, determine i t s s t a t u s } 907 16 1 4 4 16 1f readopen then 908 16 1 4 421 { ensure a new f i l e i s d e s i r e d ) 909 16 1 5 42 1 i f Ask ('Close o l d read f i l e ? ' ) 910 16 1 5 427 then ClosRead; 91 1 16 1 5 433 912 16 1 5 433 ( open new read f i l e If any e x i s t i n g one 1s c l o s e d } 913 16 1 4 433 1f not readopen then 914 16 1 5 440 Beg i n 915 16 1 5 440 < read f i l e name, open the f i l e } 916 16 1 6 440 1f FetchName (x_rnam, y_rnam, readname) then 917 16 1 7 450 Beg i n 918 16 1 8 450 i f readname = writename 9 19 16 1 8 453 then readwrite:= t r u e 920 16 1 8 461 e l s e B e g i n 92 1 16 1 0 467 r e s e t ( r e a d f i l e , readname); 922 16 1 0 479 readwrite:= f a l s e 923 16 1 9 479 End; { of e l s e ) Appendix C Compiler L i s t i n g of U n i t ParamSave Page 9 924 16 1 8 483 i f r e a d w r i t e or ( i o r e s u l t = 0) 925 16 1 8 491 then Begin 926 16 1 8 494 { f i l e opened s u c c e s s f u l l y > 927 16 1 0 494 TaskSw i t c h ; 928 16 1 0 496 readopen:= t r u e ; 929 16 1 0 500 { c r e a t e the read l i s t > 930 16 1 0 500 i f r e a d w r i t e then 931 16 1 1 505 B e g i n 932 16 1 2 505 r e a d l i s t : = w r i t e l i s t ; 933 16 1 2 511 w h i l e r e a d l i s t <> n i l do w i t h readlist® do 934 16 1 4 522 Begi n 935 16 1 5 522 read_next:= w r i t e _ n e x t ; 936 16 1 5 529 r e a d l i s t : = w r i t e next 937 16 1 4 529 End: { of w h i l e } 938 16 1 2 537 r e a d l i s t : = w r i t e l i s t ; 939 16 1 2 543 r average:= average 940 16 1 1 546 End { of r e a d w r i t e } 94 1 16 1 0 549 e l s e ParamReset; 942 16 1 0 553 TossRL i s t 943 16 1 9 553 End { of s u c c e s s f u l open } 944 16 1 8 555 e l s e readname:= n o f 1 1 e { f i l e does not e x i s t 945 16 1 7 560 End; { of f i l e named > 946 16 1 6 566 TossRName 947 16 1 5 566 End { of not readopen } 948 16 1 3 568 End { o f 'R' } 949 16 1 3 568 950 16 1 2 568 End { of Case } 951 16 1 1 573 U n t i l ch = MapCommandKey (sc_escape_key, f a l s e ) ; 952 16 1 1 583 ScrnReturn; 953 16 1 1 586 Po11 Inputs 954 16 1 0 0 End; { of P r m F i l e ) 955 16 1 0 0 956 16 1 0 0 957 16 1 0 0 958 2 1 d 1 Segment Process ParamPut; 959 2 1 d 1 { w r i t e l i s t e d parameter v a l u e s to w r i t e f i l e ) 960 20 1 d 1 Var 11, t2: t im_rec; 961 20 1 d 5 raw t a b l e : a n a _ i n _ t a b l e ; 962 20 1 d 53 param: param_ptr; 963 20 1 d 54 F u n c t i o n SaveOK: boolean; 964 20 2 0 0 Begin 965 20 ' 2 1 0 SaveOK:= ru n n i n g and writ e o p e n and e n a b l e d 966 20 1 0 0 End; { of SaveOK } 967 20 1 0 0 Beg i n 968 20 1 1 3 wa i t (rewr i t t e n ) ; 969 20 1 1 7 w h i l e running do 970 20 1 2 13 Begin 97 1 20 1 2 13 { wait f o r w r i t e f i l e to be opened & ena b l e d } 972 20 1 3 13 Repeat 973 20 1 4 13 i f r u nning and not writ e o p e n then wait ( r e w r i t t e n ) ; Appendix C Compiler L i s t i n g of U n i t ParamSave Page 974 20 1 4 27 i f r u n n i n g and not enabled then wait ( w r i t e _ d a t a ) 975 20 1 3 4 1 U n t i l not running or (writeopen and e n a b l e d ) ; 976 20 1 3 55 < save data u n t i l not ( writeopen and enabled) } 977 20 1 3 55 whi1e SaveOK do 978 20 1 4 6 1 Beg i n 979 20 1 4 61 { dump i n t e g r a t i o n sums } 980 20 1 5 61 i f ignore > 0 then A n a l n S t a t u s ( r a w _ t a b l e ) : 981 20 1 5 7 1 { r e c o r d time, wait out i n t e g r a t i o n time } 982 20 1 5 7 1 TimSubTO ( t 1 ) ; 983 20 1 5 74 W a i t T i c k ( i n t e g r a t e ) ; 984 20 1 5 79 i f SaveOK then 985 20 1 6 85 Begin 986 20 1 6 85 ( read time and a n a l o g input v a l u e s ) 987 20 1 7 85 TimSubTO ( t 2 ) ; 988 20 1 7 88 A n a l n S t a t u s ( r a w _ t a b l e ) ; 989 20 1 7 91 { p r o c e s s and save those v a l u e s } 990 20 1 7 91 TimMinus ( t 2 , t2, t 1 ) ; 991 20 1 7 96 writefile®:= TimlnSeconds (t1) + 0.5 * TimlnSeconds ( t 2 ) ; 992 20 1 7 1 13 i f r e a d w r i t e then param_time:= writefile®; 993 20 1 7 123 PFPut (404); 994 20 1 7 128 param:= w r i t e l i s t ; 995 20 1 7 133 w h i l e param <> n i l do with param® do 996 20 1 9 142 Begin 997 20 1 0 142 i f measure = n i l ' 998 20 1 0 146 then writefile®:= v a l u e 999 20 1 0 150 e l s e w i th measure®, raw_tab1e[chan_in] do 1000 20 1 2 176 i f count <= 1 1001 20 1 2 183 then writefile®:= s c a l e i n * r e a d i n g 1002 20 1 2 193 e l s e writefile®:= s c a l e _ i n 1003 20 1 3 202 * (256.0*sum msword + sum_lsbyte) / count 1004 20 1 0 235 i f r e a d w r i t e then read_data:= writefile®; 1005 20 1 0 247 PFPut (405); 1006 20 1 O 252 param:= w r i t e _ n e x t 1007 20 1 9 252 End; { of w h i l e , with } 1008 20 1 7 260 i f r e a d w r i t e and not r w _ v a l i d then 1009 20 1 8 270 Beg i n 1010 20 1 8 270 ( note new r e a d / w r i t e data } 101 1 20 1 9 270 rw__va 1 i d : = t r u e ; 1012 20 1 9 274 s i g n a l (rw_ava11) 1013 20 1 8 278 End; { of s i g n a l new r e a d / w r i t e data } 1014 20 1 7 278 i f s i n g l e then enabled:= f a l s e ; 1015 20 1 7 287 { wait f o r ignore parameter save time to pass } 1016 20 1 7 287 i f r u nning then W a i t T i c k ( i g n o r e ) 1017 20 1 6 295 End { o f i f } 1018 20 1 4 297 End { of whi1e } 1019 20 1 2 297 End { of w h i l e r u n n i n g } 1020 20 1 0 0 End { of Segment ParamPut > 1021 20 1 0 0 1022 20 1 O 0 1023 2 1 d 1 Segment Procedure P D a t S t r t ; Appendix C Compiler L i s t i n g of U n i t ParamSave Page 11 1024 22 1 d 1 Var p i d : p r o c e s s i d : 1025 22 1 d 2 s t a c k , p r i o : i n t e g e r ; 1026 22 1 0 0 Begin 1027 22 1 1 0 r e a d l i s t : = n i l ; w r i t e l i s t : 3 n i l ; 1028 22 1 1 8 readopen:= f a l s e ; w r i t e o p e n : 3 f a l s e ; 1029 22 1 1 16 readname:= no f i l e ; writename:- read_ name: 1030 22 1 1 34 s e m i n i t ( r e w r i t t e n , 0 ) ; 103 1 • 22 1 1 44 enabled:= f a l s e ; s i n g l e : 3 f a l s e ; 1032 22 1 1 52 s e m i n i t ( w r i t e _ d a t a , 0 ) : 1033 22 1 1 62 i g n o r e s 1140; i n t e g r a t e : 3 60; 1034 22 1 1 73 r e a d w r i t e : 3 f a l s e ; s e m i n i t (rw a v a i l , 0) ; rw va1i d: 1035 22 1 1 91 S t r t l n f o ('ParamSav', 'ParamPut', s t a c k , p r i o , t r u e ) ; 1036 22 1 1 107 s t a r t (ParamPut, p i d , s t a c k , p r i o ) 1037 22 1 0 0 End; < of P D a t S t r t > 1038 22 1 0 0 1039 22 1 0 0 1040 22 1 0 0 104 1 2 1 d 1 Procedure ParamF i1e; 1042 2 4 d 1 Var ch: char; 1043 2 4 d 2 a b l e : s t r i ng[8]; 1044 2 4 d 7 r e p t : s t r i ng[8]; 1045 2 4 0 , 0 Begi n 1046 2 4 1 • 0 Repeat 1047 2 4 2 0 i f e nabled then a b l e : 3 'enabled' 1048 2 4 2 6 e l s e able:= ' d i s a b l e d ' ; 1049 2 4 2 21 1f s i n g l e then rept:= ' s i n g l e ' 1050 2 4 2 27 e l s e r e p t : = ' m u l t i p l e ' ; 105 1 2 4 2 42 ch:= PromptCapIn 1052 2 4 2 42 (0. 0. concat ('DataLog: S ( t a t u s ['. a b l e , 1053 2 4 2 69 '] L ( o g g i n g [ ' . r e p t , '] F( 1054 2 4 2 103 t ' S ' . ' L ' . ' F ' . ' E ' ] ) ; 1055 2 4 2 1 15 i f r u nning then 1056 2 4 3 120 Case ch of 1057 2 4 3 123 'S': Begi n 1058 2 4 5 123 enabled:= not enabled; 1059 2 4 5 130 i f e n a b l e d then s i g n a l (wr i t e _ d a t a ) 1060 2 4 4 139 End; < of 'S' ) 1061 2 4 3 14 1 'L ' : Begin 1062 2 4 5 141 s i n g l e : = not s i n g l e ; 1063 2 4 5 148 1f not en a b l e d then 1064 2 4 6 153 Beg 1 n 1065 2 4 7 153 enab1ed:= t r u e ; 1066 2 4 7 157 s i g n a l (wr1te_data) 1067 2 4 6 161 End { of not enabled ) 1068 2 4 4 161 End; { of 'L' } 1069 2 4 3 163 ' F ' : PrmF i1e 1070 2 4 3 163 End { of Case > 107 1 2 4 1 17 1 U n t i l E r r o r N o t e d or (ch = 'E') 1072 2 1 0 0 End; { of Param F i l e ) 1073 2 1 0 0 = f a 1se; E ( x i t ' ), to Appendix C Compiler L i s t i n g of U n i t ParamSave Page 12 1074 2 1 :0 0 1075 2 1 :d 1 Procedure PFPut { ( e r r num: i n t e g e r ) ); 1076 2 1 :d 1 { put ( w r i t e f i l e ) , i f i o e r r o r then N o t e E r r o r (err_num) } 1077 2 6 :0 0 Beg i n 1078 2 6 : 1 0 put (wr i t e f i 1 e ) ; 1079 2 6 : 1 5 i f i o r e s u l t <> 0 then N o t e E r r o r ( e r r num, i o r e s u l t , f a l s e ) 1080 2 1 :0 0 End; ( of PFPut > 1081 2 1 :0 0 1082 2 1 :d 1 Procedure PFGet (err_num: i n t e g e r ) ; 1083 2 1 :d 1 < get ( r e a d f i l e ) , i f i o e r r o r then N o t e E r r o r (err_num) > 1084 2 7 :0 0 Beg i n 1085 2 7 : 1 0 get ( r e a d f i 1 e ) ; 1086 2 7 : 1 6 i f i o r e s u l t <> 0 then N o t e E r r o r ( e r r num, i o r e s u l t , f a l s e ) 1087 2 1 :0 0 End; < of PFGet > 1088 2 1 :0 0 1089 2 1 :0 0 1090 2 1 :d 1 Procedure ParamReset; 1091 2 1 :d 1 { r e s e t parameter read f i l e > 1092 2 2 :d 1 Var o l d param, new_param: param_ptr; 1093 2 2 :d 3 dummy: a r r a y [1..3] of r e a l ; 1094 2 2 :d 9 read name: s t r i n g [ 8 ] ; 1095 2 2 :d 14 i : i n teger; 1096 2 2 : d 15 Procedure CopyWtoR; 1097 2 2 :d 1 { copy w r i t e f i l e b u f f e r s to r e a d f i l e b u f f e r s } 1098 2 8 :d 1 Var window: i n t e g e r ; 1099 2 8 :0 0 Begin 1 100 2 8 :0 0 ( save window p o i n t e r } 1 101 2 8 : 1 0 moveleft ( r e a d f i l e , window, 2 ) : 1 102 2 8 : 1 9 < copy w r i t e f i l e to r e a d f i l e } 1 103 2 8 : 1 9 moveleft ( w r i t e f i l e , r e a d f i l e , s i z e o f ( r e a d f i l e ) ) ; 1 104 2 8 : 1 21 < r e p l a c e window p o i n t e r } 1 105 2 8 : 1 21 moveleft (window, r e a d f i l e , 2) 1 106 2 2 :0 0 End; ( of CopyWtoR > 1 107 2 2 :0 0 Beg 1 n 1 108 2 2 : 1 0 i f readopen then 1 109 2 2 : 2 6 Begin 1 1 10 2 2 : 2 6 { p o i n t to b e g i n n i n g of read f i l e } 1111 2 2 : 3 6 read 11st: = n i l ; 1112 2 2 : 3 10 i f r e a d w r i t e then CopyWtoR; 1113 2 2 : 3 17 r e s e t ( r e a d f i 1 e ) : 1 1 14 2 2 : 3 23 1f i o r e s u I t <> 0 1115 2 2 :3 26 then N o t e E r r o r (401, i o r e s u l t . f a l s e ) ; 1 1 16 ' 2 2 : 3 39 Pol 1 Inputs; 1117 2 2 : 3 4 1 { c r e a t e new read 1 1st } 1 1 18 2 . 2 : 3 4 1 i f r u nning then 1 1 19 2 2 : 4 46 Repeat 1 120 2 2 : 5 46 f o r 1:= 1 to 3 do 1121 2 2 :6 57 Begi n 1 122 2 2 : 7 57 dummy[i]:= readfile©; 1 123 2 2 : 7 70 PFGet (406) Appendix C Compiler L i s t i n g of U n i t ParamSave Page 13 1 124 2 2 : 6 73 End; { of f o r i > 1 125 2 2 : 5 8 1 move l e f t (dummy, read name, s i z e o f (read_name)) ; 1 126 2 2 : 5 89 new param:= PrmNamed (read_name); 1 127 2 2 : 5 97 i f read 11st = n i l 1 128 2 2 : 5 100 then read l i s t : 3 new_param 1 129 2 2 : 5 103 e l s e o l d param©.read_next:= new_param; 1 130 2 2 : 5 1 14 i f new param <> n i l then old_param:= new_param; 1131 2 2 : 5 120 Pol 1 Inputs 1 132 2 2 : 4 120 U n t i l not running or (new_param = n i l ) ; 1 133 2 2 :4 132 { read i n t e g r a t i o n time > 1 134 2 2 : 3 132 r a v e r a g e : 3 readfile®; 1 135 2 2 : 3 140 PFget (407) 1 136 2 2 : 2 143 End ( o f i f readopen > 1 137 2 1 ; :0 0 End; { of ParamReset } 1 138 2 1 :0 0 1 139 2 1 : 0 0 1 140 2 1 : :d 1 F u n c t i o n ParamGet: 114 1 2 1 :d 1 { read s p e c i f i e d parameters' r e a d d a t a from s p e c i f i e d read f i l e 1 142 2 3: : d 1 Var param: param_ptr; 1 143 2 3 :d 2 F u n c t i o n ReadOK: boolean; 1 144 2 9: :0 0 Begin 1 145 2 9 : 1 0 ReadOK:= running and readopen 1 146 2 3 :0 0 End; < of ReadOK } 1 147 2 3: :d 1 Procedure WaitWrite; 1 148 2 10: :0 0 Begin 1 149 2 10 : 1 0 wait (rw_ava1l); { decrement semaphore count ) 1 150 2 10 : 1 4 ParamGet: 3 ReadOK and r w _ v a l i d ; 1151 2 10 : 1 14 rw v a l 1 d : - f a 1se 1 152 2 3 :0 0 End; ( of WaitWrite > 1 153 2 3 :0 0 Begin 1 154 2 3: : 1 0 ParamGet: 3 f a l s e : 1 155 ~2 3: : 1 2 Pol 1 Inputs; 1 156 2 3: : 1 4 i f ReadOK then 1 157 2 3: : 2 9 Beg i n 1 158 2 3: : 3 9 i f rw v a 1 i d 1 159 2 3 : 3 9 then WaitWrite { r e t u r n w i t h the new r e a d / w r i t e r e c o r d } 1 160 2 3 : 3 14 e l s e i f not eof ( r e a d f i l e ) then 1 161 2 3 : 5 27 Begin { r e t u r n w i t h the next o l d read r e c o r d ) 1 162 2 3 : 6 27 param t i m e : 3 read file®; 1 163 2 3: :6 34 PFGet (408): 1 164 2 3 : 6 39 param: 3 r e a d _ l i s t ; 1 165 2 3 :6 43 w h i l e ReadOK and (param <> n i l ) do with param® do 1 166 2 3: :8 54 Beg 1 n 1 167 2 3: :9 54 read d a t a : 3 readfile®; 1 168 2 3: :9 62 PFGet (409); 1 169 2 3: :9 67 param: 3 read_next 1 170 2 3 :8 67 End; { of w h i l e , with > 117 1 2 3: :6 73 ParamGet: 3 ReadOK 1 172 2 3 : 5 73 End { of not eof ) 1 173 2 3: : 4 77 e l s e i f r e a d w r i t e and wait ok then Appendix C Compiler L i s t i n g of U n i t ParamSave Page 14 1 174 2 3 6 86 WaitWrite { wait f o r new r e a d / w r i t e r e c } 1 175 2 3 2 86 End ( of i f ReadOK > 1 176 2 1 0 0 End; { of ParamGet } 1 177 2 1 0 0 1 178 2 1 0 0 1 179 2 1 d 1 Procedure p f H a l t ; 1 180 2 1 d 1 { s a f e l y shut down w r i t i n g p r o c e s s } 1 181 2 5 0 0 Beg i n 1 182 2 5 1 0 readopen:= f a l s e ; w r i t e open:^ f a l s e ; e n a b l e d : 3 f a l s e ; 1 183 2 5 1 12 s i g n a l ( r e w r i t t e n ) ; s i g n a l ( r w _ a v a i l ) ; s i g n a l ( w r i t e _ d a t a ) 1 184 2 5 1 24 c l o s e ( w r i t e f i l e , l o c k ) 1 185 2 1 0 0 End; { of p f H a l t } 1 186 2 1 0 0 1 187 2 1 0 0 1 188 2 1 0 0 Begin < i n i t i a l i z a t i o n > 1 189 2 1 1 19 P D a t S t r t 1 190 2 0 0 End. End of C o m p i l a t i o n . CTi Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page 1 3 0 0 d 4 2 1 d 5 2 1 d 6 2 1 d 7 2 1 d 8 2 1 d 9 2 1 d 10 2 1 d 1 1 2 1 d 12 2 1 d 13 2 1 d 14 2 1 d 15 2 1 d 259 2 1 d 401 2 1 d 4G0 2 1 d 461 2 1 d 462 2 1 d 463 2 1 d 464 2 1 d 465 2 1 d 466 2 1 d 467 2 1 d 468 2 1 d 469 2 1 d 470 2 1 d 471 2 1 d 472 2 1 d 473 2 1 d 474 2 1 d 475 2 1 d 476 2 1 d 477 2 1 d 478 16 1 d 479 16 1 d 480 16 1 d 48 1 16 1 d 482 16 1 d 483 16 1 d 484 16 1 d 485 16 1 d 486 16 1 d 487 16 1 d 488 16 1 d 489 16 1 d 490 16 1 d 49 1 16 1 d 492 16 1 d 493 16 2 0 3 5 13 14 15 16 16 16 3 {$L remout:) Un i t P l o t t e r ; I n t e r f a c e Procedure P l o t S e t u p ; { i n t e r a c t i v e l y set up and perform a p l o t } Procedure p l H a l t ; { shut down p l o t t e r p r o c e s s } Implementat1 on {$L-> Uses ScreenOps. E x t r a S c r , WritCons, ReadKybd, S c r n B u f f , {$L©> {$L-} Schedule, P l o t U t i l , Parameter, P a r a m U t i l , ErrMessg, {$L®) <$L-> MiscFunc, ParamSave, <$U u t i 1 : s t a r t e r . c o d e ) S t a r t e r ; <$L@} Var make_plot: semaphore: xparam, yparam: param_ptr; xmin, xmax, ymin, ymax; r e a l ; x l s t i m e : boolean; en a b l e d : boolean: f i r s t : boolean; F u n c t i o n GetData (var x, y wa i t ok: rea 1 ; b o o l e a n ) : boolean; forward; { r e t u r n w i th data p o i n t s or t r u e i f eof > Segment Procedure P l o t S e t ; { i n t e r a c t i v e l y set up and perform a p l o t } Const < c o o r d i n a t e s of c u r s o r f o r v a r i o u s e n t r i e s } xxmin = 6; xxmax = 67 yx = 22; < x bounds > yymin = 2 1 yymax = 2 xy = 0; { y bounds } xxnam = 33 yxnam = 22 { x parameter name > xxunt = 43 yxunt = 22 < x " u n i t s ) xynam = 2 yynam = 1 1 { y " name } xyunt = 4 yyunt = 12 { y " u n i t s ) xnew. = 53 ynew = 1 1 { p l o t new d a t a o n l y } f rea 1 =11: f name =8; f u n i t = 4; { f i e l d widths maxrea1 .OE37; , up, down l e f t , r i g h t e s c : char; prompt: sb_prmt_ptr; Procedure TossParam (xn, yn, xu. Beg i n yu : i n t e g e r ; param: param_ptr); cri cr. Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page 494 16 2 1 0 i f param = n i l 495 16 2 1 1 then B e g i n 496 16 2 3 4 TossBlanks (xn, yn. f_name); 497 16 2 3 9 TossBlanks (xu, yu, f _ u n i t ) 498 16 2 2 12 End < of n i l } 499 16 2 1 14 e l s e w i t h param© do 500 16 2 3 18 Beg 1 n 501 16 2 4 18 T o s s S t r i n g (xn, yn, name, f_name) ; 502 16 2 4 27 T o s s S t r i n g (xu, yu, u n i t s , f _ u n i t ) 503 16 2 3 34 End { of not n i l > 504 16 1 0 0 End: < of TossParam } 505 16 1 0 0 506 16 1 d 1 Procedure TossXParam; 507 16 3 0 0 Beg i n 508 16 3 1 0 i f x i s t ime 509 16 3 1 0 then B e g i n 510 16 3 3 3 T o s s S t r i n g (xxnam, yxnam, 'time', f _ name): 51 1 16 3 3 14 T o s s S t r i n g (xxunt, yxunt, 'sec', f _ u n i t ) 512 16 3 2 23 End 513 16 3 1 25 e l s e TossParam (xxnam, yxnam, xxunt. yxunt, xparam) 514 16 1 0 0 End; { of TossXParam ) 515 16 1 0 0 516 16 1 d 1 Procedure TossYParam; 517 16 4 0 0 Begin 518 16 4 1 0 TossParam (xynam, yynam. xyunt, yyunt. yparam) 519 16 1 0 0 End; { of TossYParam } 520 16 1 0 0 521 16 1 d 1 Procedure TossBounds; 522 16 5 0 0 Beg i n 523 16 5 1 0 T o s s F l o a t (xxmin, yx, xmin, f _ r e a l ) ; 524 16 5 1 8 T o s s F l o a t (xxmax, yx, xmax, f _ r e a l ) ; 525 16 5 1 17 T o s s F l o a t (xy, yymin, ymin, f _ r e a l ) ; 526 16 5 1 25 T o s s F l o a t (xy, yymax, ymax. f _ r e a l ) 527 16 1 0 0 End; < of TossBounds } 528 16 1 0 0 529 16 1 d 1 Procedure DataBounds; 530 16 6 d 1 Var x, y: rea1; 531 16 6 0 0 Beg i n 532 16 6 1 0 ParamReset; 533 16 6 1 3 i f GetData (xmin, ymin, f a l s e ) 534 16 6 1 9 then Begin 535 16 6 3 13 xmax:= xmin; ymax:= ymin; 536 16 6 3 25 w h i l e GetData (x, y, f a l s e ) do 537 16 6 4 33 Beg 1 n 538 16 6 5 33 i f x < xmin then xmin:= x 539 16 6 5 43 e l s e xmax:= rMax (x. xmax) ; 540 16 6 5 61 i f y < ymin then ymin:= y 54 1 16 6 5 7 1 e l s e ymax:= rMax (y. ymax) 542 16 6 4 85 End; { of w h i l e ) 543 16 6 3 91 TossBounds C5> Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page 3 544 16 6 2 91 End ( of data e x i s t s 1n f i l e ) 545 16 1 0 0 End; { of DataBounds > 546 16 1 0 0 547 16 1 0 0 Begin < *** main body of P l o t S e t + + * } 548 16 1 1 0 up; = MapCommandKey (sc_up_key, f a l s e ) ; 549 16 1 1 6 down:= MapCommandKey (sc_down_key, f a l s e ) ; 550 16 1 1 12 1eft : = MapCommandKey ( s c _ l e f t k e y , f a l s e ) ; 55 1 16 1 1 18 r i ght: - MapCommandKey ( s c _ r i g h t _ k e y , f a l s e ) ; 552 16 1 1 24 esc: = MapCommandKey (sc_escape_key, f a l s e ) : 553 16 1 1 30 i f f i r s t then 554 16 1 2 33 Beg i n pen to top r i g h t c o r n e r so o p e r a t o r can s e t p l o t s i z e ) 555 16 1 2 33 { move 556 16 1 3 33 f i r s t : 3 f a l s e ; 557 16 1 3 36 PlotBounds (xmln, xmax, ymin, ymax); 558 16 1 3 51 P l o t (xmax, ymax) 559 16 1 2 57 End; ( of f i r s t ) 560 16 1 1 60 S c r n E n t e r ( ' P l o t S e t ' ) ; 56 1 16 1 1 67 prompt : 3 ScrnPrompt ( 0 ) ; 562 16 1 1 76 TossBounds; 563 16 1 1 78 TossXParam; TossYParam; 564 16 1 1 82 565 16 1 1 82 Repeat 566 16 1 2 82 ch: 3 PromptCapIn 567 16 1 2 82 (0. 0, prompt®, [' X ',' Y ', 'D'.up,down,1 e f t , r i g h t , 'S',esc]) 568 16 1 2 1 18 i f ch <> esc then e n a b l e d : 3 f a l s e ; 569 16 1 2 125 570 16 1 2 125 i f ch i n [up, down, l e f t , r i g h t ] 57 1 16 1 2 141 then Beg i n 572 16 1 4 144 i f ch 3 up 573 16 1 4 145 then ymax: 3 F e t c h F l o a t 574 16 1 5 150 (xy, yymax, f r e a l , ymln, maxreal) 575 16 1 4 161 e l se 576 16 1 5 166 i f ch 3 down 577 16 1 5 167 then ymin: 3 F e t c h F l o a t 578 16 1 6 172 (xy, yymin, f _ r e a l , -maxreal, ymax) 579 16 1 5 184 e l se 580 16 1 6 189 i f ch 3 l e f t 581 16 1 6 190 then xmin: 3 F e t c h F l o a t 582 16 1 7 195 (xxmin, yx, f ' r e a l . -maxreal, xmax) 583 16 1 6 207 e l se 584 16 1 6 2 12 ( ch 3 r i g h t 585 16 1 7 212 then) xmax: 3 F e t c h F l o a t 586 16 1 7 214 (xxmax. yx, f _ r e a l . xmin, maxreal) 587 16 1 3 226 End 588 16 1 3 229 589 16 1 2 229 e l se 590 16 •1 3 23 1 Case ch of 59 1 16 1 3 234 592 16 1 3 234 ' X ' : Beg i n 593 16 1 5 234 xparam: 3 n i l ; x i s t i m e : 3 f a l s e ; Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page 4 594 16 1 5 240 TossXParam; 595 16 1 5 242 xparam:= PrmPrmpt 596 16 1 5 242 (0, 0, 'X Ax i s (<esc> f o r t i m e ) ' , f a l s e , f a l s e ) ; 597 16 1 5 257 xis t i m e : = xparam = n i l ; 598 16 1 5 262 TossXParam 599 16 1 4 262 End; { of 'X' ) 600 16 1 4 266 601 16 1 3 266 ' Y ' : Begin 602 16 1 5 266 yparam:= n i l ; 603 16 1 5 269 TossYParam; 604 16 1 5 27 1 Repeat 605 16 1 6 27 1 yparam;= PrmPrmpt (0, 0, 'Y A x i s ' , f a l s e , f a l s e ) 606 16 1 5 28 1 U n t i l yparam <> n i l ; 607 16 1 5 290 TossYParam 608 16 1 4 290 End; < of 'Y' ) 609 16 1 4 294 6 10 16 1 3 294 'D': DataBounds 61 1 16 1 3 294 612 16 1 3 294 End < of Case > 613 16 1 3 301 614 16 1 1 301 U n t i l E r r o r N o t e d or (ch i n ['S', e s c ] ) ; 6 15 16 1 1 32 1 i f ch = 'S' then 6 16 16 1 2 326 Beg 1 n 617 16 1 3 326 PlotBounds (xmin, xmax, ymin, ymax); 618 16 1 3 341 P1otAxes; 619 16 1 3 344 ParamReset: 620 16 1 3 347 enab1ed:= t r u e ; 62 1 16 1 3 350 s i g n a l (make p l o t ) 622 16 1 2 353 End; 623 16 1 2 353 624 16 1 1 353 ScrnReturn 625 16 1 0 O End; ( of P l o t S e t ) 626 16 1 0 0 627 16 1 0 O 628 2 1 d 1 Procedure P l o t S e t u p ; 629 2 2 0 O Beg i n 630 2 2 1 0 P l o t S e t 631 2 1 0 0 End: ( of P l o t S e t u p > 632 2 1 0 0 633 2 1 0 0 634 2 1 d 1 F u n c t i o n GetData { (var x. y: r e a l ; wait_ok: b o o l e a n ) : boolean }; 635 2 1 d 1 { r e t u r n with data p o i n t s or t r u e i f eof ) 636 2 4 0 O Beg i n 637 2 4 1 0 i f ParamGet (wait_ok) 638 2 4 1 2 then Begin 639 2 4 3 7 i f x i s t ime 640 2 4 3 7 then x:= param_time 64 1 2 4 3 1 1 e l s e x:= xparam®.read data; 642 2 4 3 24 y:= yparam®.read_data; 643 2 4 3 30 GetData:= t r u e Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page 5 644 2 4 : 2 30 End ( of not eof ) 645 2 4 : 1 32 e l s e GetData:= f a l s e 646 2 1 :0 0 End; ( of GetData } 647 2 1 :0 0 648 2 1 :0 0 649 2 1 :d 1 Pr o c e s s P l o t D a t a ; 650 2 5 :d 1 Var x, y: rea1; 65 1 2 5 :d 5 F u n c t i o n PlotOK: boolean; 652 2 6 :0 0 Beg i n 653 2 6 : 1 0 i f enabled then PlotOK:= GetData (x 654 2 6 : 1 1 1 e l s e PlotOK:= f a l s e 655 2 5 :0 0 End: { of PlotOK > 656 2 5 :0 0 Begin 657 2 5 : 1 2 Repeat 658 2 5 : 2 2 wa i t (make p l o t ) ; 659 2 5 : 2 5 w h i l e PlotOK do 660 2 5 : 3 10 Begin 66 1 2 5 :4 10 P l o t (x, y ) ; 662 2 5 : 4 17 P1otDrop; 663 2 5 : 4 20 P l o t L i f t 664 2 5 : 3 20 End { of w h i l e not eof } 665 2 5 : 1 23 U n t i l not ru n n i n g 666 2 1 :0 0 End; { of P l o t D a t a ) 667 2 1 :0 0 668 2 1 :0 0 669 2 1 :d 1 Procedure P l o t S t r t ; 670 2 7 :d 1 Var p i d : p r o c e s s i d : 671 2 7 :d 2 st a c k , p r i o : i n t e g e r ; 672 2 7 :0 0 Beg i n 673 2 7 : 1 0 xmin:= 0.0: xmax:= 1.0: ymin:= xmin: 674 2 7 : 1 24 x i s t i me:= f a 1se; 675 2 7 : 1 27 enab1ed:= f a 1se: 676 2 7 : 1 30 f i r s t : = t r u e ; 677 2 7 : 1 33 xparam:= n i l ; yparam:= n i l ; 678 2 7 : 1 39 s e m i n i t (make_plot, 0 ) ; 679 2 7 : 1 48 S t r t l n f o ( ' P l o t t e r ' , ' P l o t D a t a ' , stack 680 2 7 : 1 64 s t a r t ( P l o t D a t a . p1d. s t a c k , p r i o ) 68 1 2 1 :0 0 End; < of P l o t S t r t } 682 2 1 :0 0 683 2 1 :0 0 684 2 1 : d 1 Procedure p l H a l t ; 685 2 1 :d 1 ( shut down p l o t t e r p r o c e s s > 686 2 3 :0 0 Beg i n 687 2 3 : 1 0 s i g n a l (make p l o t ) 688 2 1 :0 0 End; { of p l H a l t } 689 2 1 :0 0 690 2 1 :0 0 69 1 2 1 :0 0 Begin < i n i t i a l i z a t i o n > 692 2 1 : 1 0 P l o t S t r t 693 2 :0 0 End. t r u e ) ymax : p r i o , t r u e ) ; l^ o Appendix C Compiler L i s t i n g of U n i t P l o t t e r Page End of C o m p i l a t i o n . Appendix D Compiler L i s t i n g of U n i t E12ISR Page 1 3 0 0 d 1 {$L remout:> 4 2 1 d 1 Uni t E 12 i s r ; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 a 8 2 1 d 1 { T h i s u n i t i s a memory and p o s i t i o n l o c k e d segment i n t e r n a l to E12ana 9 2 1 d 1 and/or E 1 2 d i g i o . I t i s not meant to be used o t h e r w i s e . > 10 2 1 d 1 1 1 2 1 d 1 Const njumpsxS =21; { 3 * tt e n t r i e s i n i s r jump t a b l e } 1 2 2 1 d 1 13 2 1 d 1 Var 14 2 1 d 1 < Assembler data a r e a s : i n general t h i s d a t a i s not used by P a s c a l as 15 2 1 d 1 they may be changed by an i s r d u r i n g such use. } 16 2 1 d 1 17 2 1 d 1 { Data a c t u a l l y used as Z80 opcodes: > 18 2 1 d 1 jumptabl: packed a r r a y [1..njumpsx3] of 0..255; 19 2 1 d 12 { jumps to some u t i l i t y r o u t i n e s 1n e 1 2 i s r . a > 20 2 1 d 12 { Data used by d i g i t a l i s r : •> 2 1 2 1 d 12 p u l s e : boolean; { d i g i t a l p u l s e i s on? > 22 2 1 d 13 c u r r d i g : s e t of 0 . 1 5 ; ( c u r r e n t d i g i t a l output } 23 2 1 d 14 p l s q u i t : 0..maxint; { 1 sword of time to t u r n o f f p u l s e } 24 2 1 d 15 p l s d a t a , plsmask: set of 0 . 1 5 ; { used to end p u l s e } 25 2 1 d 17 { Data used by a n a l o g i s r : } 26 2 1 d 17 anabuff: a r r a y [1..16] of packed r e c o r d 27 2 1 d 17 r e a d i n g : Integer; { l a t e s t r e a d i n g of Input > 28 2 1 d 17 sum count: 0..255; { H r e a d i n g s summed f o r average c a l c ' n } 29 2 1 d 17 sum I s b y t e : 0..255; { l e a s t s i g n i f i c a n t b y t e of that sum } 30 2 1 d 17 sum msword: i n t e g e r ; { most " word " " " } 31 2 1 d 17 t1: i n t e g e r ; { 1 sword of time when dx/dt c a l c ' n done } 32 2 1 d 17 xO: i n t e g e r ; { r e a d i n g at time t o } 33 2 1 d 17 x1: i n teger; { " " " 11 > 34 2 1 d 17 d e l t a t: 0..maxint: { t 1 - t 0 , w i l l be >= m1n_dt > 35 2 1 d 17 ready: boolean: { channel i s beyond s e t p o i n t by maxerr? } 36 2 1 d 17 s e t p o i n t : Integer; { check r e a d i n g a g a i n s t t h i s v a l u e } 37 2 1 d 17 maxerror: i n t e g e r ; < and set ready 1f s t r a y e d beyond > 38 2 1 d 17 min_dt: 0 . 2 5 5 ; { dx/dt:= x1-x0 / t 1 - t 0 ok a f t e r m1n_dt > 39 2 1 d 17 p r i o r i t y : 0..8; { 1f < 8, t r i g g e r e very 2 * * p r i o r i t y pass } 40 2 1 d 17 f i l l e r : 0..3; { unused } 41 2 1 d 17 i n v e r t : boolean; { i n v e r t t h i s c h a n n e l ' s r e a d i n g ? } 42 2 1 d 17 newddt: boolean { dx/dt c a l c ' n updated by l a t e s t i s r ? } 43 2 1 d 17 end; 44 2 1 d 177 45 2 1 d 177 Procedure I n i t E 1 2 i s r ; { must be c a l l e d by E12dig/ana1o i n i t i a l i z a t i o n 46 2 1 d 1 47 2 1 d 1 Imp 1ementat ion 48 2 1 d 177 49 2 1 d 177 Procedure I n i t E 1 2 i s r ; e x t e r n a l ; 50 2 1 d 1 5 1 2 0 0 End. Appendix D Compiler L i s t i n g of U n i t E12I5R Page End of C o m p i l a t i o n . Appendix D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page Page 0 File:E12ISR.A Z80 Assembler IV.0 [a.3] OOOO OOOO OOOO s b i o s .EOU 0 l o c a t i o n of s b i o s i n ram OOOO OOOO OOOO . PROC I n i t E 1 2 i s r OOOO ;Copy E 1 2 i s r jump t a b l e to jumptabl, i n s e r t Anaserv and D i g s e r v address OOOO ; i n i n t e r r u p t v e c t o r t a b l e s . OOOO OOOO .CONST njumpsx3 3 * number of e n t r i e s i n jumptabl OOOO .PUBLIC jumptabl jump t a b l e to r o u t i n e s i n A n a i s r OOOO .PUBLIC c u r r d i g c u r r e n t d i g i t a l output b y t e OOOO OOOO 0030 anavect .EOU sbios+0030H analog i s r e n t r y i n t a b l e oooo 0032 d i g v e c t .EOU sbios+0032H d i g i t a l " " " " oooo 001E mask .EOU sbios+001EH u - a r t i n t e r r u p t mask saved here oooo 0053 maskreg .EOU 53H " " " r e g i s t e r p o r t oooo 00B1 c o n t r o l .EOU 0B1H E12 contro1/dev1ce a d d r e s s p o r t oooo 0040 n o s t r o b .EOU 040H E 12 s t r o b e o f f oooo oooo :Copy a c t u a l jump t a b l e to ( j u m p t a b l ) : oooo 21 * * + * I d HL,jmptabl (HL):= a c t u a l jump t a b l e 0003 1 1 OOOO I d DE , jumptabl (DE):= new jump t a b l e image 0006 01 oooo I d BC,nj umpsx3 number of byt e s i n jump t a b l e 0009 ED BO l d i r move the data OOOB 21 * * + * I d HL,Anaserv get address of Anaserv r o u t i n e 000E 22 3000 I d (anavect),HL i n s e r t 1n t a b l e 0011 21 * * * * I d HL,Digserv repeat f o r D i g s e r v 0014 22 3200 I d ( d i g v e c t ) , H L 0017 AF xor A 0018 32 OOOO I d ( c u r r d i g),A f i r s t D i g W r i t e r e s e t s a l l unmasked b i t s 0O1B C9 r e t 001C 001C 001C jmp t a b l : 001C ;jump t a b l e to r o u t i n e s w i t h i n E121sr: 001C C3 * * * * JP D i gsend mask by t e L w i t h C, update d i g i t a l output 001F C3 * * * * JP GetCfrmA read E12 d i g i t a l input A i n t o C 0022 C3 * * * * JP SendA2C send data i n A to E12 d e v i c e C ( l o s e A) 0025 C3 * * * * JP RdClkDE ;DE:= c l o c k lsword ( l o s e AF, C) 0028 C3 •* * * * JP S t r t a n a t r i g g e r A/D, p r e p a r e b u f f e r s to read i t 002B C3 * * * * JP ISR o f f mask o f f a n a i s r I n t e r r u p t 002 E C3 + * * * JP. ISR_on unmask a n a i s r i n t e r r u p t 0031 0031 ; E x t e r n a l d i g i t a l i s r data a r e a : 003 1 .PUBLIC pu 1 se p u l s e i s on boo l e a n 0031 .PUBLIC p i s q u i t lsword of time to t u r n o f f p u l s e Appendix D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page 0031 .PUBLIC p i s d a t a p u l s e d a t a 0031 - .PUBLIC p1smask " mask 0031 0031 ; D i g i t a l i s r symbols: 0031 0001 d i gb i t . EOU 1 r e l a v e n t b i t i n i n t e r r u p t mask 0031 0056 digt1me . EOU 56H d i g i t a l p u l s e i n t e r v a l timer p o r t 0031 003 1 0031 D i g s e r v 003 1 ;Check c l o c k r e a d i n g a g a i n s t p l s q u i t time. If >=, mask d i g d a t a w i t h digmask 0031 ; and send to d i g i t a l output. 0031 ;Save r e g i s t e r s , check time: 0031 08 ex AF save r e g i s t e r s 0032 D9 exx 0033 CD * + + + c a l 1 RdClkDE get c l o c k r e a d i n g 0036 EB ex DE ,HL in HL 0037 ED 5B OOOO Id DE , ( p i s q u i t ) get q u i t time i n DE 003B AF xor A A:= 0, r e s e t c a r r y 003C ED 52 sbc HL , DE HL: = tt t i c k s beyond t u r n o f f time 003 E F2 + * + + JP P,pu1sdon jump i f at or past t u r n o f f time 0041 ;Time not passed, send 255 to i n t e r v a l timer (-M/60 second): 004 1 3D dec A 0042 D3 56 out (d1gt i me),A r e s t a r t c o u n t e r w i t h 255 0044 D9 getbak: exx get back r e g i s t e r s , enab. i n t e r u p t s , r e t u r n 0045 08 ex AF 0046 FB e i 0047 C9 r e t 0048 ;Pulse i s complete: t u r n i.t o f f and mask o f f i n t e r r u p t : 0048 32 OOOO pu l s d o n Id ( p u l s e ) , A f l a g p u l s e i s o f f 004 B 2 1 1E00 Id HL,mask p o i n t to i n t e r r u p t mask w i t h HL 004E CB 8E r e s d i g b i t.(HL) t u r n o f f d i g s e r v i n t e r r u p t 0050 7E Id A,(HL) get new mask i n A 0051 D3 53 out (maskreg),A send to u - a r t 0053 3A OOOO Id A.(pismask) load r e g i s t e r s w ith p u l s e mask and data 0056 4F Id C. A 0057 3A OOOO Id A.(p1sdata) 005A 6F Id L , A 005B CD + * * * c a l 1 D i gsend send the o f f p u l s e , update c u r r d i g 005 E 18E4 ir getbak get back r e g i s t e r s , e n a b l e i n t e r r u p t s , r e t 0060 0060 0060 RdClkDE 0060 ;Read E12 c l o c k 1 sword i n t o DE. Assume i n t e r r u p t s d i s a b l e d , l o s e AF, C: 0060 0080 mode i n . EOU 080H d i g i t a l input command f l a g 0060 0001 c l k l s b . EOU 1 c l o c k l s b y t e & l a t c h E12 add r e s s 0060 0005 • c1kun1 . EOU 5 c l o c k u n l a t c h E12 address 0060 3E C 1 Id A,c1k1sbInostrob I modein ; l a t c h c l o c k , r e a d l s b y t e of time 0062 CD + * + c a l 1 GetCfrmA 0065 59 Id E ,C save i n E 0066 3C i nc A read next l s b y t e of time Appendix D Assembler L i s t i n g of Uni t E12ISR E x t e r n a l Routines Page 0067 CD **** c a l 1 GetCfrmA 006A 51 l d D,C ;save i n D 006B 3E C5 l d A . c l k u n l nostrob I modein ; u n l a t c h c l o c k 006D 0O60 GetCfrmA: 006D ;Read E12 d i g i t a l input A in t o C. Assume i n t e r r u p t s d i s a b l e d and n o s t r o b 006D ; and mode i n b i t s of A are se t , 1ose F: 006D 00B3 data i n . EOU 0B3H :E12 d i g i t a l Input p o r t 0060 D3 B1 out (contro1 ) , A 006 F E6 BF and -•nostrob ;set s t r o b e 007 1 D3 B1 out ( c o n t r o l ) . A 0073 OE B3 l d C,data 1n ; d i g 1 t a l Input p o r t 0075 ED 48 i n C, (C) ;read the d i g i t a l input p o r t Into C 0077 F6 40 or n o s t r o b ; r e s e t s t r o b e 0079 D3 B1 out ( c o n t r o l ) , A 007B C9 r e t 007C 007C 007C D1gsend 007C ;Send data i n L masked by C to d i g i t a l o u t p u t s , update c u r r d i g . Assumes 007C : i n t e r r u p t s a re d i s a b l e d . Uses AF. BC. HL. 007C 0003 outcomd . EOU 3 ; d i g i t a l output command 007 C 7D Id A . L ;get v a l u e In A 007D A1 and C .accept o n l y unmasked b i t s 007 E 47 l d B. A ;save i n B 007 F 79 l d A . C ;get mask 0080 2F c p l ;complement of mask 0081 2 1 OOOO Id H L .currd i g ;point to o l d output s t a t u s 0084 A6 and (HL) ;leave o n l y masked o l d b i t s 0085 BO or B ;combine w i t h r e q u e s t e d changes 0086 77 l d (HL).A ;update output s t a t u s byte 0087 OE 03 l d ' C.outcomd 0089 0089 SendA2C 0089 :Send data A to E12 d e v i c e C (assume i n t e r r u p t s d i s a b l e d , l o s e AF): 0089 OOBO dataout . EOU OBOH :E12 data output p o r t 0089 D3 BO out ( d a t a o u t ) , A ;set d e v i c e d a t a 008B 79 Id A , C 008C F6 40 or n o s t r o b 008E D3 B1 out ( c o n t r o l ) , A .•select d e v i c e , s t r o b e o f f 0090 E6 BF and -•nostrob 0092 D3 B1 out ( c o n t r o l ) , A :st r o b e the d e v i c e 0094 F6 40 or n o s t r o b 0096 D3 B1 out ( c o n t r o l ) , A :strobe o f f 0098 C9 r e t 0099 0099 0099 0099 ;E x t e r n a l a n a l o g i s r data area : 0099 .PUBLIC anabuff ;analog input b u f f e r s Appendix D Assembler L i s t i n g of Un i t E12ISR E x t e r n a l Routines Page 0099 0099 ; I n t e r n a l a n a l o g i s r data a r e a : 0099 00 channel .BYTE channel to read 009A 01 nxtchan .BYTE 1 " " t r i g g e r 009B OOOO b u f f e r . WORD po i n t e r to channel to read's r e c o r d In anabuff 009D OOOO nx t b u f f . WORD anabuf f " " " t r i g g e r ' s " " " 009 F OOOO t r g t ime . WORD 0 time of most r e c e n t channel t r i g g e r i n g 00A1 01 r o t a t e .BYTE 1 r o t a t e through chan t r i g g e r p e r m u t a t i o n s 00A2 00 t r igpwr .BYTE power of 2 a s s o c i a t e d w i t h r o t a t e 00 A 3 OOA3 :Ana l o g i s r symbols: OOA3 OOOO anab1t . EOU 0 r e l a v e n t b i t i n i n t e r r u p t mask OOA3 0055 anat i me . EOU 55H i n t e r v a l timer g e n e r a t e s I n t e r r u p t s 00 A 3 OOBO e1 2 s t a t . . EOU OBOH e12 s t a t u s p o r t 00A3 OOOO s t a t b i t . EOU 0 A/D s t a t u s b i t i n e 1 2 s t a t (done) 00 A 3 0005 msbb i t . EOU 5 " msbit " " " ( I n v e r t e d ) 00 A 3 0006 s i gnb i t . EOU 6 " s i g n 00A3 0007 overb i t . EOU 7 " o v e r l o a d " " " 00 A 3 ;Anabuff r e c o r d o f f s e t s : 00A3 OOOO read i ng . EOU 0 l a t e s t r e a d i n g of input 00 A 3 0002 sumcnt . EOU 2 tt r e a d i n g s summed 00 A 3 0003 1sbyte . EOU 3 of sum 00 A 3 0004 msword . EOU 4 " " 00A3 0006 11 . EOU 6 time of dx/dt c a l c u l a t i o n 00 A 3 0008 xO . EOU 8 r e a d i n g at time t o 00 A 3 OOOA x1 . EOU 10 " t1 00 A 3 OOOC del t a t . EOU 12 t1-tO 00A3 OOOD ready . EOU 13 r e a d i n g beyond s e t p t by maxerr? 00 A 3 0007 r d y b i t . EOU 7 ready b o o l e a n b i t number 00A3 000E s e t p t . EOU 14 r e a d i n g s e t p o i n t 00A3 0010 maxerr . EOU 16 and maxerror OOA3 0012 m i ndt . EOU 18 wait b e f o r e v a l i d dx/dt OOA3 0013 pr i o r t y . EOU 19 t r i g g e r p r i o r i t y ( b i t s 0..2) 00 A 3 0013 i nver t . EOU 19 i n v e r t s i g n of input? 00 A 3 0006 i n v t b l t . EOU 6 i n v e r t b o o l e a n b i t number 00 A 3 0013 newddt . EOU 19 new dx/dt c a l c ' n v a l i d ? 00 A 3 0007 d d t b i t . EOU 7 newddt b o o l e a n b i t number 00A3 0014 r e c s i ze . EOU 20 s i z e of e n t i r e channel r e c o r d OOA3 OOA3 00 A 3 Anaserv: 00 A 3 :Read l a s t t r i g g e r e d a n a l o g input Into v a l u e S sum b u f f e r s , t r i g g e r the next 00 A 3 ; c h a n n e l : OOA3 ;Save AF and BC r e s t a r t t i m e r : 00 A 3 F5 push AF OOA4 3E FF Id A , 255 Count down 255 * 64 microseconds OOA6 03 55 out (anat i me),A 00 A 8 C5 push BC 00A9 :See i f a c o n v e r s i o n i s complete 00A9 OE BO l d C,e12stat Append i x D Assemb1er L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page OOAB ED 40 in B. (C) OOAD CB 40 b i t s t a t b i t ,B t e s t s t a t u s b i t OOAF 20 * * nz,done i f done, read the new da t a , t r i g g e r next OOB1 C1 pop BC e l s e get back BC OOB2 F 1 pop AF and AF. en a b l e i n t e r r u p t s , r e t u r n OOB3 FB e i OOB4 C9 r e t OOB5 done : OOB5 ;Save o t h e r r e g i s t e r s , read & save data: OOB5 E5 push HL OOBG 05 push DE • OOB7 DD E5 push IX OOB9 OC i nc C read thousands/hundreds d i g i t s OOBA ED 50 in D , (C ) OOBC OC 1 nc C and tens/ones d i g i t s OOBD ED 58 i n E , (C) OOBF D5 push DE save r e a d i n g OOCO C5 push BC and f l a g s OOC1 ; T r i g g e r new c o n v e r s i o n : OOC1 CD * * * * c a l 1 t r i g g e r m OOC4 ; Read new time OOC4 CD 6000 c a l 1 RdClkDE read c l o c k l s b y t e i n t o DE OOC7 ;Mask anaserv n t e r r u p t . enable o t h e r i n t e r r u p t s : OOC7 CD * * * * c a l 1 ISR_off OOCA ;Get j u s t read channel's t r i g g e r time, save j u s t t r i g g e r e d . c h a n n e l ' s time: OOCA 2A 9F00 I d H L . ( t r g t i m e ) j u s t read c h a n n e l ' s t r i g g e r time OOCD ED 53 9F00 I d ( t r g t ime).DE save j u s t t r i g g e r e d c h a n n e l ' s t r i g g e r time OOD1 5D I d E , L copy new read c h a n n e l ' s time to DE OOD2 54 I d D.H 00D3 ;Point to j u s t read c h a n n e l ' s r e c o r d i n anabuff w i t h IX: 00D3 DD 2A 9B00 I d I X . ( b u f f e r ) 00D7 DD CB 13 BE res ddtbit,(IX+newddt) ; r e s e t dx/dt c a l c u l a t i o n v a l i d b o o l e a n OODB ;Subtract prev ous r e a d i n g time from new time: OODB DD 4E 06 I d C, (IX + t 1 ) l s b y t e of o l d time OODE DD 46 07 I d B,(IX + t 1+1 ) msbyte " " " OOE 1 AF xor A r e s e t c a r r y OOE 2 ED 42 sbc HL.BC HL:= d e l t a t OOE 4 :Compare d e l t a t with s p e c i f i e d minimum d e l t a t f o r d/dt c a l c u l a t i o n : OOE 4 7D I d A , L l s b y t e of d e l t a t OOE 5 DD 96 12 sub (IX+mindt) A:= l s b y t e of ( d e l t a t - minimum d e l t a t ) OOE 8 30 * * nc.keepdt i f no borrow, keep the new d e l t a t OOE A 7C I d A.H msbyte of d e l t a t (16 b i t u n s i g n e d i n t e g e r ) OOEB A7 and A i s t h e r e an msbyte > 0 to borrow from? OOEC 28 * * j r z,chkovr i f d e l t a t too s m a l l , s k i p d/dt c a l c u l a t i o n OOEE ;De l t a t >= s p e c i f i e d minimum d e l t a t. Save d e l t a t and time: OOEE DD CB 13 FE keepdt: set ddtbit.(IX+newddt) ;set v a l i d dx/dt c a l c u l a t i o n b i t OOF 2 CB 7C b i t 7,H check f o r d e l t a t > maxint OOF 4 28 * * j r z,$0 i f not, ok OOFG 21 FF7F I d HL,32767 e l s e c l i p d e l t a t at maximum a l l o w e d v a l u e OOF 9 DD 75 OC $0 I d ( I X + d e l t a t ) , L r l s b y t e of d e l t a t Append i x D Assembler L i s t i n g of Un i t E12ISR E x t e r n a l Routines Page OOFC DD 74 OD Id (IX + d e l t a t + 1) ,H :msbyte " " ", r e s e t ready b i t OOFF DD 73 06 Id (IX + t 1 ) , E ;1sbyte of tIme 0102 DD 72 07 Id (IX + t 1+1 ) ,D ;msbyte " " 0105 ;Copy o l d r e a d i n g : 0105 DD 7E OA Id A,(IX + x 1 ) ;pr e v i o u s r e a d i n g , t h i s channel 0108 DD 77 08 Id (IX+xO),A ;save i t 010B DD 7E OB Id A,(IX + x l + 1 ) 010E DD 77 09 Id (IX+XO+1),A 0111 ;Check o v e r l o a d s t a t u s , i f t r u e s e t r e a d i n g to +/- 12000: 0111 C1 chkovr: pop BC ;get back f l a g s 01 12 D1 pop DE ;and r e a d i n g 01 13 21 E02E Id HL,12000 01 16 CB 78 b i t overb i t,B ; t e s t o v e r l o a d b i t 01 18 20 *• * j r nz,chksgn : t r u e : s k i p r e a d i n g c o n v e r s i o n 01 1A ;Convert r e a d i n g to n a t u r a l b i n a r y i n HL: 01 1A 48 Id C,B ;save s t a t u s i n C 01 1B 21 OOOO Id HL.O ;zero b i n a r y r e s u l t r e g i s t e r 01 1E 7B Id A , E ;A: = two l e a s t s i g d i g i t s 01 1F D5 push DE ;save r e a d i n g on s t a c k 0120 1 1 0100 Id DE , 1 0123 CD * * * * c a l 1 AOFHxDE ;sum:= ones 0126 1 1 OAOO Id DE . 10 0129 CD * + * * c a l 1 AOFHxDE ;sum:= sum + tens 012C F 1 pop AF ;A:= two most s i g d i g i t s 012D 1 1 6400 Id • DE,100 0130 CD * * * * c a l 1 AOFHxDE ;sum:=sum + hundreds 0133 1 1 E803 Id DE,1000 0136 CD * * * * c a l 1 AOFHxDE :sum=sum + thousands 0139 4 1 Id B,C ;get s t a t u s back i n B 013A ;Add overrange to resu11: 013A CB 68 b i t msbbi t,B ; t e s t o verrange b i t 013C 2Q* + j r nz,chksgn ;and add to sum i f n e c e s s a r y 013E 1 1 1027 Id DE,10000 ;most s i g b i t c o r r e s p o n d s to 10,000(dec) 0141 19 add HL, DE 0142 ;Check t h i s c hannel's i n v e r t f l a g a g a i n s t hardware s i g n b i t : 0142 DD 7E 13 chksgn: Id A. ( I X + i n v e r t ) ; i n v e r t input b o o l e a n In b i t signb1t=1nvtb1t 0145 A8 xor B ; i n v e r t o n l y If s i g n neg xor i n v e r t f l a g g e d 0146 CB 77 b i t s i gnb i t,A ; t e s t r e s u l t i s i n b i t s i g n b i t 0148 C4 + * * * c a l 1 nz,HL2comp ; i f s i g n n e g a t i v e , 2's complement HL 014B ;Save the new r e s u l t i n r e a d i n g b u f f e r (and as x1?): 014B DD 75 OO Id (IX+reading).L 014E DD 74 01 Id (IX+reading+1),H 0151 DD CB 13 7E b i t d d t b i t , (IX + newddt) ;check whether dx/dt c a l c u l a t i o n was good 0155 28** j r z,sumup ; f a l s e , dx/dt c a l c ' n not yet v a l i d 0157 DD 75 OA Id ( IX + x1 ) ,L ; t r u e , " " i s v a l i d now 015A DD 74 OB Id ( IX + x l + 1 ) .H 015D ;Add r e s u l t to sum b u f f e r : 015D 7D sumup: Id A.L ;get l e a s t s i g by t e of a/d r e a d i n g 015E DD 86 03 add A, ( IX+lsbyte) ;add to l e a s t s i g by t e of sum 0161 DD 77 03 Id ( I X + l s b y t e ) , A ;and save Appendix D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page 0164 7C Id A , H get most s i g b y t e of a/d r e a d i n g 0165 DD 8E 04 adc A,(IX+msword) add w i t h c a r r y to next l e a s t s i g b y t e of sum 0168 DD 77 04 Id (IX+msword),A and save 016B ;Check s i g n of HL. If neg, add O f f h and c a r r y to msb e l s e add 0 and c a r r y : 016B 3E 00 Id A,0 016D CB 7C b i t 7, H s i g n 016F 28 * * ir z,$0 017 1 3D dec A 0172 DD 8E 05 $0 adc A,(IX+msword+1) add c a r r y to most s i g b y t e of sum 0175 DD 77 05 Id (IX+msword+1),A and save 0178 ;Counter w i l l o v e r f l o w b e f o r e sum does s i n c e |max read1ng| < 128*256: 0178 DD 34 02 i nc (IX+sumcnt) increment c o u n t e r 017B 20 * * ir nz,beyond check f o r c o u n t e r o v e r f l o w ( c t r = 256 = 0) 017D DD 36 02 80 Id (IX+sumcnt).128 yes: s e t c o u n t e r to 256 / 2 := 128 0181 DD CB 05 2E s r a (IX+msword+1) and d i v i d e sum by 2 (keep s i g n ! ) 0185 DD CB 04 1E r r (IX+msword) 0189 DD CB 03 1E r r ( IX+1sbyte) 018D ; See i f e r r o r exceeded: c a l c u l a t e d i f f e r e n c e between r e a d i n g and s e t p o i n t : 018D DD 5E OE beyond: Id E .(IX+setpt) l s b y t e of s e t p o i n t 0190 DD 56 OF Id D,(IX+setpt+1) msbyte " " 0193 AF xor A r e s e t c a r r y 0194 ED 52 sbc HL.DE ' ' HL : = v a l u e - s e t p o i n t 0196 FC * * * * c a l 1 m.HL2comp take a b s o l u t e v a l u e 0199 ; See i f d i f f e r e n c e i s g r e a t e r than s p e c i f i e d maxerror: 0199 DD 5E 10 Id E,(IX+maxerr ) 1sbyte of maxerror 019C DD 56 1 1 Id D.(IX+maxerr+1 ) msbyte " " 019F AF xor A 01A0 EB ex DE .HL HL:= maxerror, DE:= | a c t u a l e r r o r | 01A1 ED 52 sbc HL ,DE HL: = maxerror - j a c t u a l e r r o r | 01A3 ; Set ready i f f l a c t u a l e r r o r j exceeds maxerror: 01A3 F2 * * * * JP p,1oad no, leave ready b i t r e s e t 01A6 DD CB OD FE se t r d y b i t . ( I X + ready) 01AA ; Set up f o r next c h a n n e l , get back r e g i s t e r s , r e - e n a b l e anaserv, r e t u r n : 01AA CD * * * * 1 oad c a l 1 loadnxt set up f o r next channel read 01AD DD E1 pop IX 01AF D1 pop DE 01B0 CD * * * * c a l 1 ISR on unmask anaserv i n t e r r u p t 01B3 E 1 pop HL 01B4 C1 pop BC 01B5 F 1 pop AF 01B6 C9 r e t 01B7 01B7 01B7 AOFHxDE 01B7 :Calcu1ate HL: = HL + ASOfh * DE. Uses AF, DE, HL, B. 01B7 06 04 Id B.4 fou r b i t s of A to p r o c e s s 01B9 CB 47 $10 b i t 0. A 1s l e a s t s i g b i t h i ? 01BB 28 * + ir z,$0 no, don't change r e s u l t 01BD 19 add HL.DE yes, add c o n s t . DE to r e s u l t 01BE CB 3F $0 s r 1 A A : = A d i v 2 Append i x D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page 01C0 CB 23 s 1 a E DE:= DE * 2 01C2 CB 12 r 1 D 01C4 10F3 d j n z $10 loop f o r a l l f o u r b i t s 01C6 C9 r e t r e t u r n w i t h top 4 b i t s of A now i n bottom 01C7 01C7 01C7 HL2comp: 01C7 ; C a l c u l a t e two's complement: HL(2's comp):= O-HL. Changes DE, AF. 01C7 EB ex DE ,HL get number i n DE 01C8 AF xor A r e s e t c a r r y 01C9 67 l d H. A z e r o HL 01CA 6F Id L , A 01CB ED 52 sbc HL , DE HL : = 0 - DE 01CD C9 r e t 01CE 01CE 01CE S t r t a n a : 01CE ;Perform t r i g g e r and loadnxt without i n t e r r u p t s : 01CE F3 d i 01CF CD * * * + c a l 1 t r i g g e r 01D2 CD * * * + c a l 1 1oadnxt 01D5 FB e i 01D6 C9 r e t 01D7 01D7 01D7 t r i gger: 01D7 ; T r i g g e r an A/D convers i on. 01D7 ;Enter with channel i n (nxtchan) r e t u r n w ith A & C changed: 0107 OOOO mux .EOU OH Mu1t i p1exer 01D7 3A 9AOO l d A , (nxtchan) get channel (1..16) to t r i g g e r 01DA 3D dec A 01DB CB E7 se t 4 . A enable m u l t i p l e x e r 01DD OE OO Id C, mux d e v i c e o f f s e t 01DF CD 8900 c a l 1 SendA2C send channel # to m u l t i p l e x e r 01E2 OC i nc C a d t r i g : = mux + 1 01E3 CD 8900 c a l 1 SendA2C 8 t r i g g e r the c o n v e r s i o n 01E6 C9 r e t 01E7 01E7 01E7 1oadnxt: 01E7 ;Prepare the next channel to t r i g g e r . Changes AF, BC, DE, HL, IX. 01E7 ;Load (channe1) = channel Just t r i g g e r e d : 01E7 3A 9A00 l d A.(nxtchan) 01EA 32 9900 l d (channe1),A 01ED ;Load (buf f e r ) : = p o i n t e r to r e c o r d i n anabuff f o r channel J u s t t r i g g e r e d 01ED DD 2A 9D00 l d I X , ( n x t b u f f ) 01F 1 DD 22 9B00 Id ( b u f f e r ) , I X 01F5 :Load r e g i s t e r s f o r next channel f e t c h : 01F5 4F l d C,A C:= channel j u s t t r i g g e r e d 01F6 2 1 A 100 l d H L . r o t a t e p o i n t to r o t a t e count w i t h HL Appendix D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page 9 01F9 OIFC 01FC 01FE 01FF 0201 0201 0205 0207 0208 020A 020A 020C 020C 0200 020F 02 10 02 1 1 0213 0214 02 17 02 17 021A 021C 0210 0220 0221 0223 0223 0224 0227 022B 022C 022C 022C 022C 022C 022F 0230 0232 0233 0235 0236 0237 0237 0237 0237 0237 023A 023B 11 ECFF DD 19 OD 20** DD 21 20O1 OE 10 35 20** 36 80 l d ;Test channel newchan add dec j r ;New t r i g g e r l d l d dec j r a g a i n l d ; S t a r t DE , - r e c s i z e C f o r t r i gger f1 IX ,DE C n z , t r y C r o t a t-1 on: IX,anabuff+ < 15 C, 16 (HL) nz,ca1ct r g with pr i or 1ty 7: (HL),128 tminus s i z e of s i n g l e channel anabuff r e c o r d agged-;point to t e s t c h a n n e l ' s anabuff r e c o r d ;next channel to t e s t :jump i f s t i l l Chans l e f t to t r i g g e r i n r o t a t e * r e c s i z e > ;anabuff r e c o r d f o r chan 16 . channel 16 i s next to t r y decrement r o t a t e count want r o t a t e i n 1..128 ; C a l c u l a t e ( t r i g p w r ) = tflsbits 7E c a l c t r g l d A,(HL) 06 FF Id B.255 1F ck1sb i t r ra 04 1 nc B 30FC j r nc,ck1sb i t 78 Id A , B 32 A200 l d ( t r igpwr ) ,A ; See 1 f channe1 C i s to be t r i DD 7E 13 tr y C l d A . ( I X + p r i o r t y ) E6 OF and 00001111T 47 Id B, A 3A A200 Id A , ( t r i gpwr) B8 cp B 38D9 j r c,newchan ;C : = next channel to t r i g g e r . 79 l d A,C 32 9A00 Id (nxtchan),A DD 22 9DOO l d ( n x t b u f f ) , I X C9 r e t r e s e t 1n ( r o t a t e ) : ; A:= r o t a t e count ; b i t c o u n t e r i n i t i a l i z e d to -1 ;check next l s b i t of A ;1oop u n t i l r o t a t e count b i t found ;save the r o t a t e power ggered: :get c h a n n e l ' s t r i g g e r power of two ;mask o f f n o n - p M o r t y b i t s ;save i n B ;get r o t a t e count power ;see i f r o t a t e ' s power >= c h a n n e l ' s ;yes, t r y next channel DE:= p o i n t e r to i t ' s p r i o r i t y : ;update channel to t r i g g e r ;and save p o i n t e r to next c h a n n e l ' s anabuff ISR_off: ;Mask o f f anaserv i n t e r r u p t . Changes AF, HL, d i s a b l e s / e n a b l e s i n t e r r u p t s . 21 1E00 Id HL.mask ;point to i n t e r r u p t mask w i t h HL p 3 d i ;no i n t e r r u p t s w h i l e (mask) <> (maskreg) CB 86 r e s a n a b i t . ( H L ) ;turn o f f anaserv I n t e r r u p t 7E Id A,(HL) :get new mask i n A D3 53 out (maskreg),A ;send to u - a r t FB e i C9 r e t 21 1E00 F3 CB C6 ISR_on: :Unmask anaserv i n t e r r u p t , l d HL.mask di s e t anabi t.(HL) Changes AF, HL. d i s a b l e s / e n a b l e s i n t e r r u p t s , p o i n t to I n t e r r u p t mask w i t h HL no i n t e r r u p t s w h i l e (mask) <> (maskreg) t u r n on anaserv i n t e r r u p t Appendix D Assembler L i s t i n g of U n i t E12ISR E x t e r n a l Routines Page 10 023D 023E 0240 024 1 0242 0242 0242 0242 7E D3 53 FB C 9 Id out e i r e t . END A. (HL) (maskreg),A :get new mask i n A :send to u - a r t ; i n t e r r u p t s O.K. now Assembly complete: 454 l i n e s 0 e r r o r s f l a g g e d on t h i s assembly CO CJ Appendix D Compiler L i s t i n g of U n i t E12DigI0 Page 1 3 0 0 d 1 {$L remout:} 4 2 1 d 1 U n i t E 1 2 d i g i o ; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 {commented ' : ' > { d i g i t a l i n put/output r o u t i n e s f o r E12 ( a l i a s Grey Box); 8 2 1 d 1 o u t p u t s 0 . 7 are i n i t i a l i z e d & h a l t e d h i g h . 8..15 low } 9 2 1 d 1 10 2 1 d 1 Type d i g w a i t = 0..maxint; 1 1 2 1 d 1 d i g i t a l = set of 0..15; 12 2 1 d i { e.g. [1..3.7] means b i t s 1, 2, 3, and 7 are s e t . 13 2 1 d 1 0, 4, 5. 6 and 8..15 a r e r e s e t } 14 2 1 d 1 15 2 1 d 1 Procedure DigRead (Var d a t a : d i g i t a l ) : 16 2 1 d 1 { data:= Input } 17 2 1 d 1 18 2 1 d 1 Procedure DigWrite ( d a t a , mask: d i g i t a l ) ; 19 2 1 d 1 { output:= (data i n t e r s e c t mask) 20 2 1 d 1 union ( c u r r e n t output i n t e r s e c t (complement(mask)) ) } 2 1 2 1 d 1 22 2 1 d 1 F u n c t i o n D i g P S t a t : d i g w a i t ; 23 n 1 d 1 { number of t i c k s remaining i n c u r e n t p u l s e ( i f any) } 24 2 1 d 1 25 2 1 d 1 Procedure D i g P u l s e ( d a t a , mask: d i g i t a l ; t i c k s : d i g w a i t ) ; 26 2 1 d 1 { D i g W r i t e ( d a t a . mask). A f t e r t i c k s / 60 seconds, i n t e r r u p t 27 2 1 d 1 w i l l D igWrite (comp1ement(data), mask). D i g P u l s e must not 28 2 1 d 1 be c a l l e d when DigPStat i s > 0 } 29 2 1 d 1 30 2 1 d 1 Procedure D i g S t a t u s (Var d a t a : d i g i t a l ) ; 31 2 1 d 1 { data:= c u r r e n t output > 32 2 1 d 1 33 2 1 d 1 Implementat ion 34 2 1 d 0 76 2 1 d 0 <$L-} Uses E 1 2 i s r ; ($L@> 77 2 1 d 0 78 2 1 d 0 Procedure DigRead; e x t e r n a l ; 79 2 1 d 1 Procedure DigWrite; e x t e r n a l ; 80 2 1 d 1 Procedure D i g P u l s e ; e x t e r n a l ; 81 2 1 d 1 Procedure D i g S t a t u s ; e x t e r n a l ; 82 2 1 d 1 F u n c t i o n D i g P S t a t ; e x t e r n a l ; 83 2 1 d 1 84 2 1 0 0 B e g i n 85 2 1 1 0 I n i tE12 i s r ; 86 2 1 1 2 pu1se:= f a 1se; 87 2 1 1 6 DigWr i te ( [ 0 . 7 ] , [ 0 . 1 5 ] ) ; 88 2 1 1 18 * * * . 89 2 1 1 20 w h i l e p u l s e do; < don't q u i t u n t i l p u l s e i s done ) 90 2 1 1 27 DigWri te ( [ 0 . 7 ] , [0. . 15]) 91 2 0 0 End. CD Appendix D Compiler L i s t i n g of U n i t E12DigI0 Page End of C o m p i l a t i o n . 00 Appendix D Assembler L i s t i n g of Un i t E12DigI0 E x t e r n a l Routines Page o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o 0002 0003 0006 0007 0008 OOOA OOOD 000E 000F 0010 001 1 0012 0013 0014 0016 0017 0017 0017 o o o o o o o o T h i s f i l e c o n t a i n s no .PROC. .FUNIC. .BYTE. .WORD. .ASCII, or .BLOCK It i s t h e r e f o r e d y n a m i c a l l y r e l o c a t a b l e , and may move about In ram or be swapped back to d i s k . . PUBLIC .PUBLIC . PUBLIC .PUBLIC .PUBLIC .PUBLIC jumptabl c u r r d i g pu 1 se p1squ i t p1sdata p1smask jump t a b l e to r o u t i n e s i n E121sr c u r r e n t d i g i t a l output b y t e p u l s e i s on bool e a n lsword of time to t u r n o f f p u l s e p u l s e d a t a p u l s e mask OOOO 0003 0006 0009 Digsend .EOU GetCfrmA .EOU SendA2C .EOU RdClkDE .EOU jumptabl+OOH jumptabl+03H jumptabl+06H jumptabl+09H mask by t e L w i t h C, update d i g i t a l output read E12 d e v i c e A i n t o C send data i n A to E12 d e v i c e C ( l o s e A) DE:= c l o c k lsword ( l o s e AF, C) . RELPROC DigRead,1 ;Read d i g i t a l input i n t o parameter #1. Uses AF. BC, and HL, d i s / e n - a b l e s ; i n t e r r u p t s . . DE F saveA 00C6 d i g1 n . EOU 0C6H ; d i g i t a l input command 0002 d i s p l a y . EOU 2 : d i g i t a l d i s p l a y command 3E C6 l d A , d i g i n ;set d i r e c t i o n i n and s t r o b e o f f F3 di ; I s r ' s u s i n g E12 would I n t e r f e r e CD 0300 c a l 1 GetCfrmA :read d i g i t a l input byte i n t o C 4 1 l d B.C -.save input data i n B 79 l d A.C ;get " " " A OE 02 l d C,d i s p l a y CD 0600 c a l 1 SendA2C ;send input to d i g i t a l input d i s p l a y FB e i ;now d i s p l a y and input agree 78 l d A,B ;get back input data 2F c p l ;hardware complements a c t u a l b i t v a l u e s E 1 saveA: pop HL . ; r e t u r n address E3 ex (SP),HL ;point to r e s u l t w i t h HL, r e p l a c e r e t . addr 77 l d (HL).A ;save r e s u 11 23 i nc HL ;re s e t h i g h o r d e r b y t e of r e s u l t 36 OO l d (HL),0 C9 r e t ts .RELPROC DigWrite.2 :Write to d i g i t a l output. Send the v a l u e (parameter #1), changing o n l y those Appendix D Assembler L i s t i n g of U n i t E12DigI0 E x t e r n a l Routines Page 2 o o o o ; b i t s s e t i n the mask (parameter #2). Uses AF, BC. and HL, d i s / e n - a b l e s o o o o ;• i n t e r r u p t s . o o o o o o o o E 1 pop HL r e t u r n address 0001 C1 pop BC get mask i n C 0002 E3 ex (SP),HL get v a l u e i n L, put back r e t u r n a d d r e s s 0003 F3 di no i n t e r r u p t s u n t i l o u t p u t s agree w i t h c u r r d i g 0004 CD OOOO c a l 1 D i gsend send the masked d a t a and change c u r r d i g 0007 FB e i 0008 C9 r e t 0009 0009 0009 OOOO .RELFUNC DigPStat OOOO ;Return with number of t i c k s remaining i n p u l s e . OOOO ; Uses AF, C. DE, HL, d i s / e n - a b l e s i n t e r r u p t s . o o o o o o o o 0056 di gt i me . EOU 56H d i g i t a l p u l s e i n t e r v a l timer p o r t o o o o o o o o ;See i f c u r r e n t l y p u l s i n g : o o o o AF xor A A : = 0 0001 21 OOOO Id HL,pu1se p o i n t to p u l s e on boolean w i t h HL 0004 B6 or (HL) z i s s e t i f not p u l s i n g 0005 28 *• + j r z.pushA r e t u r n O i f not p u l s i n g 0007 ; c a l c u l a t e number of t i c k s remaining: 0007 2A OOOO 1 d HL,(p i s q u i t ) HL:= lsword of p u l s e q u i t time OOOA F3 di d i s a l l o w i n t e r r u p t s w h i l e r e a d i n g c l o c k OOOB CD 0900 c a l 1 RdClkDE DE : = lsword of c l o c k r e a d i n g OOOE FB e i i n t e r r u p t s now o.k. 000F AF xor A r e s e t c a r r y 0010 ED 52 sbc HL.DE HL:= number of t i c k s r e m a i n i n g 0012 F2 JP • P,pushtks ensure >= 0 0015 D3 56 out (d i gt i me),A hasten t u r n o f f of p u l s e 0017 67 pushA: Id H. A HL:= 0 ( = 0 ) 0018 6F Id L. A 0019 D1 pushtks pop DE DE : = r e t u r n a d d r e s s 001A E3 ex (SP).HL (SP):= t i c k s r e m a i n i n g , HL:= junk 001B EB ex DE.HL HL : = r e t u r n address 001C E9 JP (HL) r e t 001D 001D 001D OOOO . RELPROC Di g P u l s e . 3 OOOO ;DigWrite parameters tt \ and HI f o r parameter H3 t i c k s o n l y . OOOO ; Uses AF . BC DE, HL, d i s / e n - a b l e s i n t e r r u p t s . OOOO OOOO OOOO sb i os . EOU OOOOH l o c a t i o n of s t a r t of s b i o s OOOO 001E mask . EOU sbios+001EH u - a r t i n t e r r u p t mask saved here OOOO 0001 d i gb i t . EOU 1 r e l a v e n t b i t i n i n t e r r u p t mask OOOO 0053 maskreg . EOU 53H u - a r t i n t e r r u p t mask p o r t Append i x D Assembler L i s t i n g of Un i t E12DigI0 E x t e r n a l Routines Page OOOO 0056 d i g t i m e .EOU 56H d i g i t a l p u l s e i n t e r v a l timer p o r t OOOO OOOO ;Ensure not a l r e a d y p u l s i n g : OOOO : See i f c u r r e n t l y p u l s i n g : OOOO AF xor A A : = 0 0001 2 1 OOOO l d HL,pulse p o i n t to p u l s e on bo o l e a n with HL 0004 B6 or (HL) z i s s e t i f not p u l s i n g 0005 CO r e t nz i f p u l s i n g , a b o r t 0006 ;Reset p u l s e boolean, unmask i n t e r v a l t i m e r : 0006 F3 d i no i n t e r r u p t s u n t i l p u l s e b o o l e a n c o r r e c t 0007 34 i nc (HL) f l a g we're now p u l s i n g 0008 D3 56 out (d i gt i me).A immediate i n t e r r u p t causes D i g s e r v upon e i OOOA 2 1 1E00 l d HL,mask p o i n t to i n t e r r u p t mask with HL OOOD CB CE set d i g b i t , ( H L ) t u r n on d i g s e r v i n t e r r u p t OOOF 7E l d A.(HL) get new mask i n A 0010 03 53 out (maskreg).A send to u - a r t 0012 ;Get and save parameters: 0012 CD 0900 c a l 1 RdClkDE DE : = c l o c k r e a d i n g 0015 C1 pop BC get r e t u r n address 0016 E 1 pop HL get count 0017 19 add HL , DE c a l c u l a t e time to t u r n o f f p u l s e 0018 22 OOOO l d ( p i s q u i t),HL and save 001B 60 l d H.B HL:= r e t u r n address 001C 69 1 d L.C 0010 C 1 pop BC get mask i n C 001E 79 Id A , C 001F 32 OOOO Id (p1smask ) . A save mask f o r t u r n i n g p u l s e o f f 0022 E3 ex (SP).HL get v a l u e i n L, put back r e t u r n address 0023 7D l d A , L 0024 2F cp 1 0025 32 OOOO l d ( p i s d a t a ) , A save complement of v a l u e f o r p u l s e o f f 0028 ;Turn p u l s e on. a l l o w D i g s e r v to s t a r t c h e c k i n g f o r p u l s e q u i t time: 0028 CD OOOO c a l 1 D i gsend t u r n the p u l s e on 002B FB e i s t a r t c h e c k i n g f o r p u l s e o f f time 002C C9 r e t 0020 002D 002D OOOO .RELPROC DigS t a t u s . 1 OOOO ;Read c u r r e n t d i g i t a l output i n t o parameter A 11®. Uses AF and HL. OOOO OOOO . REF saveA OOOO OOOO 3A OOOO l d A , ( c u r r d i g) get d i g i t a l output s t a t u s b y t e 0003 C3 OOOO JP saveA f i x up s t a c k , r e t u r n 0006 0006 0006 0006 . END Appendix D Assembler L i s t i n g of U n i t E12DigI0 E x t e r n a l Routines Page Assembly complete: 148 l i n e s 0 e r r o r s f l a g g e d on t h i s assembly 00 VD Appendix D Compiler L i s t i n g of U n i t E12AnaI0 Page i 3 4 5 6 7 8 9 10 1 1 12 13 14 15 1G 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 4 1 42 43 44 45 46 47 48 49 50 5 1 0 2 2 2 2 (commented (commented ($L remout:} U n i t E12anaio; I n t e r f a c e { ana 1og ' 1nput/outupt r o u t i n e s f o r E12 ( a l i a s Grey Box); o u t p u t s are i n i t i a l i z e d 8> h a l t e d to 0. Note that a n a l o g input can ONLY be done u s i n g i n t e r r p u t s } in_chan = 1 in_range = ana_err_range = ana_m1ndt_range ana_dx_range = ana_dt_range = in_chan] of b o o l e a n ; i n chan] of 0. .8 ; Type ana_in_ch 1..16; ana_in_r - 12000..12000: - 1 . .24000: = 1 . .255; -24000..24000; 1 . .max i nt; ana_chan_f1ags = packed a r r a y [ana a n a _ p r i o r i t i e s = packed a r r a y [ana ana_chan_set = set of 0..15; a n a _ i n _ t a b l e = a r r a y [ana_in_chan] of packed r e c o r d r e a d i n g : ana_in_range; sum_lsbyte, count: 0 . 2 5 5 ; sum_msword: i n t e g e r end; ana_out_chan = 1..8; ana_out_range = 0..4095; ana_out_tab1e = a r r a y [ana_out_chan] of ana_out_range; Procedure AnalnGo ( i n v e r t s : ana_chan_f1ags; p r i o r i t i e s : a n a p r i o r i t i e s ) ; < Zero a l l i n t e r n a l input v a l u e s and i n t e g r a t i o n sum b u f f e r s . Turn on i n t e r r u p t d r i v e n a n a l o g input p o l l i n g , p a s s i n g i n v e r t input v a l u e booleans and channel p r i o r i t y v a l u e s . At l e a s t one channel's p r i o r i t y must be 0 ( h i g h e s t p r i o r i t y ) . Channels of p r i o r i t y 8 w i l l not be t r i g g e r e d . ) Procedure AnaSetBound ( c h a n n e l : ana_in_chan; s e t p o i n t : ana_in_range; maxerror: ana_err_range; mindt: ana_mindt_range); { Set a n a l o g input channel s e i p o i n t and maxerror, minimum dt f o r d/dt c a l c u l a t i o n , r e s e t channel ready. I n i t i a l l y a l l s e t p o i n t s are 0, a l l maxerrors are -1, and a l l mindts are 30 t i c k s . ) Procedure AnaReady (Var ready: ana_chan_set); { Detect which a n a l o g inputs have been read s i n c e i n i t i a l i z a t i o n or the l a s t AnaReady or A n a l n S t a t u s , and c u r r e n t l y d i f f e r from t h e i r s e t p o i n t by more than t h e i r maxerror. Note that c h a n n e l s are numbered from 0 to 15 here! > O Appendix D Compiler L i s t i n g of U n i t E12AnaI0 Page 2 52 2 1 d 1 Procedure AnaRead ( c h a n n e l : ana_in_chan: 53 2 1 d 1 Var r e a d i n g : ana_in_range; 54 2 1 d Var d e l t a _ r e a d i n g : ana_dx_range; 55 2 1 d Var d e l t a _ t i m e : a n a _ d t _ r a n g e ) : 56 2 1 d 1 { Read c u r r e n t v a l u e of an a n a l o g input, and the d i f f e r e n c e s i n v a l u e 57 2 1 d 1 and time of the l a s t two r e a d i n g s . > 58 2 1 d 1 59 2 1 d 1 Procedure A n a l n S t a t u s (Var a n a _ i n p u t s : a n a _ i n _ t a b l e ) ; 60 2 1 d 1 { Read a l l c u r r e n t v a l u e s of analog i n p u t s , dump i n t e g r a t i o n sums. } 6 1 2 1 d 1 62 2 1 d 1 Procedure AnalnStop; 63 2 1 d 1 { Turn o f f i n t e r r u p t d r i v e n a n a l o g input p o l l i n g . } 64 2 1 d 1 65 2 1 d 1 Procedure AnaWrite ( d a t a : ana out range; c h a n n e l : ana_out_chan); 66 2 1 d 1 { Send data to a n a l o g output c h a n n e l . > 67 2 1 d 1 68 2 1 d 1 F u n c t i o n AnaOutRead ( c h a n n e l : ana_out_chan): ana_out_range; 69 2 1 d 1 { Read c u r r e n t v a l u e of a n a l o g output c h a n n e l . > 70 2 1 d 1 7 1 2 1 d 1 Procedure AnaOutStatus (Var ana_outputs: ana_out_tab1e); 72 2 1 d 1 { Read a l l c u r r e n t v a l u e s of a n a l o g o u t p u t s . } 73 2' 1 d 1 74 2 1 d 1 Imp 1ementat ion 75 2 1 d 0 76 2 1 d 0 1 18 2 1 d 0 {$L-> Uses E 1 2 i s r ; <$L®> 1 19 2 1 d 0 120 2 1 d 0 Var c h a n n e l : i n t e g e r ; 12 1 2 1 d 1 junk: ana chan_set; 122 2 1 d 2 123 2 1 d 2 Procedure AnalnGo: e x t e r n a l ; 124 2 1 d 1 Procedure AnaSetBound; e x t e r n a l ; 125 2 1 d 1 Procedure AnaReady; e x t e r n a l : 126 2 1 d 1 Procedure AnaRead; e x t e r n a l ; 127 2 1 d 1 Procedure A n a l n S t a t u s ; e x t e r n a l ; 128 2 1 d 1 Procedure AnalnStop; e x t e r n a l ; 1 29 2 1 d 1 Procedure AnaWrite; e x t e r n a l ; 130 2 1 d 1 F u n c t i o n AnaOutRead; e x t e r n a l ; 131 2 1 d 1 Procedure AnaOutStatus; e x t e r n a l ; 132 2 1 d 1 133 2 1 0 0 B e g i n 134 2 1 1 0 In i tE12 i s r ; 135 2 1 1 2 { i n i t i a l i z e bounds and ready } 136 2 1 1 2 f o r channel:= 1 to 16 do AnaSetBound ( c h a n n e l , 0, -1, 30) 137 2 1 1 46 AnaReady ( j u n k ) : 138 2 1 1 50 f o r c h a n n e l : 3 1 to 8 do AnaWrite (0, c h a n n e l ) ; 139 2 1 1 79 *.**.. 140 2 1 1 8 1 f o r c h a n n e l : 3 1 to 8 do AnaWrite (0, c h a n n e l ) ; 14 1 2 1 1 1 10 AnalnStop { ensure i n t e r r u p t s e r v i c i n g 1s c l e a r e d } 142 2 0 O End. Appendix D Compiler L i s t i n g of U n i t E12AnaI0 Page End of C o m p i l a t i o n . VD to Appendix D Assembler L i s t i n g of U n i t E12AnaI0 E x t e r n a l Routines Page 0000 OOOO OOOO OOOO OOOO OOOO OOOO OOOO oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo oooo 0003 0004 0005 0006 0007 0008 OOOA T h i s f i l e c o n t a i n s no .PROC, .FUNC. .BYTE, .WORD. .ASCII, or .BLOCK It i s t h e r e f o r e d y n a m i c a l l y r e l o c a t a b l e , and may move about i n ram or be swapped back to d i s k . PUBLIC jumptabl jump t a b l e to r o u t i n e s - i n A n a i s r PUBLIC anabuf f a n a l o g i n p u t s b u f f e r s 0006 SendA2C EOU jumptabl+06H send d a t a i n A to E12 d e v i c e C ( l o s e A) OOOC S t r t a n a EOU jumptabl+OCH t r i g g e r A/D, update (nxtchan) 000F ISR o f f EOU jumptabl+OFH ;mask o f f anaserv i n t e r r u p t 0012 ISR_on EOU jumptabl+12H unmask anaserv i n t e r r u p t ;Anabuff r e c o r d o f f s e t s : OOOO read i ng EOU 0 l a t e s t r e a d i n g of input 0006 11 EOU 6 time of dx/dt c a l c u l a t i o n 0008 xO EOU 8 r e a d i n g at time t o OOOA x1 EOU 10 11 OOOC del t a t EOU 12 t1 - t o OOOD ready EOU 13 r e a d i n g beyond s e t p o i n t by > maxerr? 0007 rdyb i t EOU 7 ready boolean b i t number OOOE s e t p t EOU 14 r e a d i n g s e t p o i n t 0010 maxerr EOU 16 and maxerror 0012 m i ndt EOU 18 wait b e f o r e v a l i d dx/dt 0013 pr i o r t y . EOU 19 t r i g g e r p r i o r i t y / i n v e r t d a t a OOOE ze r o s i z EOU 14 kbytes at b e g i n n i n g of r e c o r d to z e r o 0014 r e c s i ze EOU 20 s i z e of anabuff r e c o r d . RELPR0C AnaInGo,2 ; S t a r t a n a l o g Input p o l l i n g : i n i t i a l i z e channel ; p r i o r i t y v a l u e s , zero anabuff r e a d i n g s , sums, and r e a d i e s . : Parameters #1 and #2 are ; i n v e r t s : ©packed a r r a y [ 1 . . 1 6 ] of boolean ; p r i o r i t i e s : ©packed a r r a y [ 1 . . 1 6 ] of 0..8 ; r e s p e c t i v e l y . Uses AF. BC, DE, HL, IX, IY. ;Ensure p o l l i n g i s turned o f f , pop parameters: CD OFOO c a l l ISR_off F1 pop AF -.return address E1 pop HL ;(HL):= p r i o r i t i e s D1 pop DE ;(DE):= i n v e r t s F5 push AF :put back r e t u r n address E5 push HL ;save p o i n t e r to p r i o r i t i e s FD E1 pop IY ; i n IY ;Ensure at l e a s t one p r i o r i t y i s 0: i n v e r t b o o l e a n and t r i g g e r t1s , xOs and x1s, d e l t a t s Appendix D Assembler L i s t i n g of Un i t E12AnaI0 E x t e r n a l Routines Page OOOA AF xor A :1ook f o r a 0 i n new p r i o r i t y a r r a y OOOB 01 1000 Id BC, 16 ;16 channe1s OOOE ED B1 cp i r 0010 28 j r z, foundO ; i f 0 found, c o n t i n u e 0012 2B dec HL ; e l s e f o r c e channel 16 p r i o r i t y to be 0 0013 36 00 Id (HL),0 0015 ;Point to anabuff with IX, 1 oad HL with i n v e r t b o o l e a n s : 0015 DD 2 1 OOOO foundO : Id IX , anabuff 0019 EB ex DE .HL ;(HL):= i n v e r t s 001 A. 5E Id E,(HL) 001B 23 i nc 001C 56 Id D.'(HL) OO10 EB ex DE .HL ;HL:= i n v e r t s 001E ; Load the i n v e r t booleans i n t o anabuff r e c o r d s : 001E 1 1 1400 1 d DE,recs i ze ; s i z e of anabuff r e c o r d 0021 06 10 Id B, 16 ;tf c h a n n e l s 0023 FD 7E 00 ck i nvt : Id A,(IY+O) ;get p r i o r i t y i n A 0026 CB 40 b i t 0,B ;even channel number (odd B)? 0028 28 * * Jr z, odd ;no. l s b i t s of A are p r i o r i t y indeed 002 A 1F r ra ;yes, want msblts of A 002B 1F r ra 002 C FD 23 i nc IY :point to next p r i o r i t y p a i r 002 E 18 * * j r even 0030 17 odd: r l a ;move two b i t s l e f t 0031 17 r l a 0032 CB 1C even: r r H ; r o t a t e 1 s b i t of HL i n t o c a r r y 0034 CB 1D r r L 0036 1F r ra ;move c a r r y i n t o b i t 6 of A 0037 1F r r a 0038 DD 77 13 Id ( I X + p r i o r t y ) ,A ;save i n anabuff r e c o r d 003B DD 19 add IX .DE ;po i n t to next c h a n n e l ' s r e c o r d 003D 10E4 d j nz ck i nvt ;continue f o r a l l 16 c h a n n e l s 003 F ; S t a r t f i r s t convers i on: 003 F CD OCOO c a l 1 S t r t a n a 004 2 ; I n i t i a l i z e anabuff: 004 2 AF xor A ; A : = 0 a 0043 21 OOOO Id HL,anabuff :(HL):= anabuff 0046 1 1 0600 Id DE,recs i ze - z e r o s i z ;number of byt e s to s k i p per r e c o r d 0049 OE 10 Id C , 16 ; 16 channel s i n a r r a y 004B 06 OE nxtchn : Id B,zeros i z ;number of byt e s to z e r o 004D 77 z e r o : Id (HL),A :zero a by t e 004 E 23 i nc HL 004 F 10FC djnz zero ;cont1nue f o r a l l z e r o s i z b y t e s 0051 19 add HL.DE ; s k i p r e m a i n i n g b y t e s 0052 OD dec C ;next channel 0053 20F6 Jr nz,nxtchn 0055 : Turn p o l 1 i ng on: 0055 C3 1200 JP ISR_on :unmask anaserv I n t e r r u p t , e n a b l e i n t s 0058 0058 Append i x D Assemb1er L i s t i ng of U n i t E12AnaI0 E x t e r n a l Routines Page 0058 0000 .RELPROC AnaSetBound,4 OOOO ;Copy a n a l o g input channel (parameter #1) s e t p o i n t (parameter 01), maxerror OOOO ; (parameter 03) , and mindt ( parameter 04), r e s e t channel ready. Uses AF OOOO ; BC, DE, HL, IX, d i s / e n a b l e s 1 n t e r r u p t s . OOOO OOOO . REF IXptrC OOOO OOOO ; Pop s t a c k : OOOO F 1 pop AF ; r e t u r n address 0001 DD E 1 pop IX ;m i nd t 0003 E 1 pop HL ;maxerror 0004 D 1 pop DE ;setpo i nt 0005 C1 pop BC ;channe1 0006 F5 push AF :put back r e t u r n 0007 DD E5 push IX ;put back mindt 0009 ;Point to channel e n t r y i n anabuff a r r a y w i t h IX: 0009 CD OOOO c a l 1 IXptrC ;point to channel C s e n t r y i n anabuff OOOC ; I n s e r t new s e t p o i n t , maxerror , and mindt Into bounds a r r a y : OOOC F3 d i ;don't change bounds or ready u n t i l done OOOD DD 73 OE Id ( IX+setpt) , E :save s e t p o i n t 0010 DD 72 OF l d (IX+setpt+1),D 0013 DD 75 10 l d (IX+maxerr ) .L ;save maxerror 0016 DD 74 1 1 l d (IX + maxerr+ 1 ) , H 0019 D1 pop DE ;get back mindt 001A DD 73 12 l d (IX+mindt),E ;and save 0010 ;Reset channel ready b i t : 001D DD CB OD BE re s r d y b i t , ( I X + r e a d y ) 002 1 FB e l 0022 C9 r e t 0023 0023 0023 OOOO . RELPROC AnaReady,1 OOOO ;Read a n a l o g input channel ready f l a g s i n t o parameter #1®, r e s e t the f l a g s . OOOO ; Uses AF, B , DE, HL, IX. OOOO OOOO DD 21 OOOO l d IX,anabuff :point to anabuff 0004 1 1 1400 l d DE,recs i ze ;0 bytes per anabuff r e c o r d 0007 06 10 l d B, 16 :channel c o u n t e r 0009 F3 d i OOOA DD 7E OD nxtchn: Id A,(IX+ready) ;get channel ready f l a g i n A OOOD DD CB OD BE res r d y b i t , ( I X + r e a d y ) ; r e s e t the ready f l a g 001 1 17 r 1 a ;get ready f l a g i n c a r r y 0012 CB 1C r r H :move i n t o HL 0014 CB 1D r r L 0016 DD 19 add IX,DE ;point to next c h a n n e l ' s r e c o r d 0018 10FO dj nz nxtchn 001 A FB e i 001B EB ex DE , HL :get ready f l a g s e t i n DE Appendix D Assembler L i s t i n g of Un i t E12AnaI0 E x t e r n a l R o u t i n e s Page 001C E 1 pop HL r e t u r n address 001D E3 ex (SP) ,HL (HL):= r e s u l t b u f f e r , (SP):= r e t u r n 001E 73 •Id (HL) ,E .1 sbyte of ready 001F 23 i nc HL 0020 72 l d (HL),D msbyte 002 1 C9 r e t 002 2 002 2 0022 OOOO . RELPROC AnaRead,4 OOOO ;Read channel (parameter #1) l a t e s t r e a d i n g (parameter # 2 ® ) , d i f f e r e n c e OOOO ; between l a s t e s t two re a d i n g s (parameter # 3 ® ) , and d i f f e r e n c e i n time OOOO ; of those two readi n g s (parameter # 4 ® ) . . OOOO ; Uses AF, BC. DE, HL, IX, IY, d i s / e n - a b l e s i n t e r r u p t s . OOOO OOOO .DEF IXptrC OOOO OOOO ;Pop s t a c k : OOOO F 1 pop AF r e t u r n a d d r e s s 0001 E 1 pop HL ; p o i n t e r to d e l t a t 0002 FD E 1 pop IY p o i n t e r to d e l t a x 0004 D1 pop DE p o i n t e r to l a t e s t r e a d i n g 0005 C1 pop BC channel number 0006 F5 push AF r e p l a c e r e t u r n address 0007 E5 push HL r e p l a c e p o i n t e r to d e l t a t 0008 ;Point to l a t e s t r e a d i n g source b u f f e r w i t h IX, move 2 b y t e s to (DE): 0008 CD * * f * c a l 1 IXptrC (IX):= chan C s r e c o r d In anabuff OOOB F3 di don't change v a l u e w h i l e r e a d i n g i t OOOC DD 7E 00 l d A,(IX+reading) l s b y t e of r e a d i n g OOOF 12 l d (DE) .A 0010 13 i nc DE 001 1 DD 7E 01 l d A,(IX+read1ng+1) ;msbyte of r e a d i n g 0014 12 l d (DE ) ,A 0015 C a l c u l a t e (IY) = de1ta x: 0015 DD 6E OA Id L,(IX+x1) l s b y t e of x1 0018 DD 66 OB l d H,(IX + xl+1 ) msbyte " " 001B DD 5E 08 l d E,(IX+xO) l s b y t e " xO 001E DD 56 09 1 d D.(IX+xO+1) msbyte " 0021 AF xor A r e s e t c a r r y 0022 ED 52 sbc HL .DE c a l c u l a t e d e l t a x 0024 FD 75 00 l d (IY+O).L 1sbyte of " " 0027 FD 74 01 Id (IY+1 ) ,H msbyte 002 A ;Point to d e l t a t s i n k with HL, copy d e l t a t: 002 A E 1 pop HL ©delta t s i n k b u f f e r 002B DD 5E OC l d E , ( IX+deltat) l s b y t e of d e l t a t 002E DD 56 OD l d D.(IX+deltat+ 1 ) msbyte " " 0031 FB e i 0032 CB BA res r d y b i t.D mask o f f ready b i t 0034 7B l d A . E check f o r del t a t = 0 0035 B2 or D Appendix D Assembler L i s t i n g of Un i t E12AnaI0 E x t e r n a l Routines Page 0036 0038 003B 003C 003D 003 E 003 F 003 F 003 F 003 F 0040 004 3 0047 004 8 004 A 004 C 004 E 0050 0052 0054 0056 0058 0059 005 A 005 A 005 A 0000 OOOO OOOO OOOO OOOO oooo oooo oooo oooo oooo oooo 0001 0003 0004 0007 OOOA OOOC OOOD OOOF 0010 0013 0014 0016 0018 20** j r nz.savdt 1f not, ok 11 0100 Id DE . 1 e l s e s u b s t i t u t e 1 so no de v i d e by 0 e r r o r 73 savdt: Id (HL).E 23 i nc HL 72 Id (HL).D C9 r e t IXptrC ;Point to channel C's e n t r y i n anabuff w i t h IX. Uses F. BC, IX: D5 push DE don't change DE 11 1400 Id DE,recs i ze s i z e of s i n g l e channel anabuff r e c o r d DD 2 1 OOOO Id IX.anabuff (IX):= anabuff channel 1 r e c o r d OD dec C get channel i n 0..15 06 04 Id B.4 channel - 1 d e s c r i b e d by 4 b i t s CB 4 1 nx t b i t b i t O.C look at l s b i t of C 28** Ji " z.$0 1f z e r o , n o t h i n g to add DD 19 add IX ,DE " one, add r e c s i z e * 2**(B-4) CB 39 $0 s r 1 C C : = C d i v 2 CB 23 s 1 a E DE : = DE * 2 CB 12 r 1 D 10F2 d j nz n x t b i t c o n t i n u e f o r a l l f o u r b i t s D 1 pop DE get back DE C9 r e t .RELPROC A n a l n S t a t u s . 1 Read e n t i r e a n a l o g input r e a d i n g s a r r a y i n t o parameter #1®, which i s of type anabuff = a r r a y [ 1 . . 1 6 ] of packed r e c o r d r e a d i n g : - 12000.. 12000 sum_lsbyte, count: 0..255 sum_msword: i n t e g e r end. Zero the count, sum_lsbyte, and sum_msword. Uses AF, BC, DE, HL, IY d i s/en-ab 1 es' i n t e r r u p t s . F 1 pop AF r e t u r n address FD E1 pop IY ( IY) : = s i n k b u f f e r F5 push AF 11 1200 Id DE,recs1ze-2 s i z e of anabuff r e c o r d - 2 21 OOOO Id HL.anabuf f (HL):= s o u r c e b u f f e r OE 10 Id C, 16 channel c o u n t e r F3 d i don't change the t a b l e w h i l e 06 06 nxtchn: Id B.6 kbytes per channel to move 7E n x t b y t : Id A.(HL) get s o u r c e b y t e FD 77 00 Id (IY+O),A s i nk i t 23 i nc HL p o i n t to next FD 23 i nc IY 10F7 dj nz nxtbyt move 6 byt e s AF xor A A : = 0 Appendix D Assembler L i s t i n g of U n i t E12AnaI0 E x t e r n a l Routines P a g e 0019 06 04 001B 2B 001C 77 001D 10FC 001F 19 0020 OD 0021 20EA 0023 FB 0024 C9 0025 0025 0025 0000 OOOO OOOO OOOO C3 OFOO 0003 0003 0003 OOOO OOOO OOOO OOOO OOOO OOOO OOOO OOOO E 1 0001 C1 0002 D1 0003 E5 0004 0004 79 0005 FE 05 0007 30** 0009 7A OOOA A7 OOOB 28** OOOD 11 FFOO 0010 00 10 CD **** 0013 F3 0014 73 0015 23 0016. 72 0017 0017 79 0018 FE 04 001A 30** 001C C6 04 001E 4F n x t z r o : Id B,4 dec HL l d (HL),A d j n z n x t z r o add HL, DE dec C j r nz,nxtchn e i r e t ;kbytes per channel to zer o :point t o p r e v i o u s s o u r c e b y t e ;zero i t :zero 6 b y t e s ;point to next c h a n n e l ' s source b u f f e r ;next channel .RELPROC AnalnStop ;Stop a n a l o g input p o l l i n g : JP ISR o f f mask o f f Anaserv i n t e r r u p t : ; l e t E 1 2 i s r r o u t i n e do the work .RELPROC AnaWrite.2 ;Write to an a l o g output. Send v a l u e (parameter #1) to channel (parameter #2) ; Uses AF, BC, DE, and HL, d i s / e n - a b l e s i n t e r r u p t s . .PRIVATE currana:8 : t a b l e of c u r r e n t a n a l o g output v a l u e s .DEF ptHL2C. Idcurani pop pop pop push HL BC DE HL r e t u r n a d d r e s s get channel i n C get v a l u e i n DE put back r e t u r n address ;Check f o r overrange data f o r an e i g h t b i t channel l d cp j r Id and j r l d A.C 5 nc,update A.D A z,update DE.255 get channel i n A check channel number i f channel >= 5, no overrange p o s s i b l e o verrange i f D <> 0 ;overrange: reduce d a t a to 255 :Update the t a b l e of c u r r e n t a n a l o g output v a l u e s : update: c a l 1 d i 1 d i nc Id ptHL2C (HL),E HL (HL),D ;point to e n t r y C i n c u r r a n a w i t h HL, dec C ;no i n t e r r u p t s u n t i l output agrees w i t h t a b l e ; Send the new v a l u e to the an a l o g output: Id cp j r add l d A , C 4 nc,twe1ve A , 4 C , A get p r e d ( c h a n n e l ) i n A check channel number i f channel >- 5 then do 12 b i t output no, 8 b i t d/a: dev. addr. = channel + 3 get d e v i c e address i n C Appendix D Assembler L i s t i n g of Un i t E12AnaI0 E x t e r n a l Routines Page 001F 002 1 0023 0024 0025 0026 0028 002B 002D 002 F 0031 0033 0034 0035 0038 0039 003 A 003A 003 A 003A 003B 003C 003 E 004 1 0042 0043 0044 004 5 0046 0046 0046 0046 0049 004 A 004 C 004 D 004E 004E 004 E 0000 OOOO OOOO OOOO OOOO OOOO OOOO 0001 0002 0003 0006 18* + j r 1sbyte send the l s b y t e CB 27 twe1ve: s 1 a A A:= 2+pred(channel) 3C i nc A 12 b i t c o n v e r t e r : addr:= 2 *chan- 1 4F Id C, A f o r low o r d e r h a l f byte, save i n C 7B Id A.E output l e a s t s i g . 4 b i t s E6 OF and OFH CD 0600 c a l 1 SendA2C send b y t e A to d e v i c e C 06 04 Id B.4 s h i f t output v a l u e r i g h t 4 b i t s to put CB 1A s h i f t : r r D 8 most s i g . b i t s i n t o E CB 1B r r E 10FA d j nz shi f t h i g h o r d e r byte o/p addr = OD dec C 2*chan-2 7B 1sbyte: Id A.E data CD 0600 c a l 1 SendA2C send b y t e A to d e v i c e C FB e i C9 r e t ptHL2C :po i nt OD 79 CB 27 21 OOOO 85 6F DO 24 C9 2 1 OOOO F3 ED BO FB C9 to channel dec Id s 1 a Id add Id r e t i nc r e t 1dcuran i : ; s i n c e c u r r a n a Id d i l d i r e i r e t s e n t r y i n C A.C A HL,currana A . L L . A NC H c u r r a n a w i t h HL. decrement C, change AF: ; p r e d ( c h a n n e l ) get p r e d ( c h a n n e l ) [0..7] i n A , A : = 2*pr e d ( c h a n n e l ) ;po1nt to a n a l o g output save t a b l e add HL:= HL + A cannot be .DEF HL,currana d. Anastatus must be done here: ;(HL):= s o u r c e b u f f e r ;no changing v a l u e s w h i l e t r a n s f e r r i n g -.move the data .RELFUNC AnaOutRead,1 ;Read c u r r e n t a n a l o g output channel g i v e n by parameter #1. ; Uses AF. BC, DE, HL. d i s / e n - a b l e s i n t e r r u p t s . . REF ptHL2C D1 pop DE C1 pop BC E 1 pop HL CD OOOO c a l 1 ptHL2C F3 di r e t u r n a d d r e s s channel number HL:= junk p o i n t to channel C's c u r r o u t e n t r y w i t h HL don't change the v a l u e w h i l e c o p y i n g i t Appendix D Assembler L i s t i n g of U n i t E12AnaI0 E x t e r n a l Routines Page 0007 0008 0009 OOOA OOOB OOOC OOOD 000E 000E OOOE OOOO OOOO OOOO OOOO OOOO OOOO OOOO 0001 0002 0003 0006 0009 0009 0009 0009 4E Id C,(HL) ;get l s b y t e 23 inc HL 46 Id B,(HL) :and msbyte FB e l C5 push BC ; r e t u r n v a l u e on sta c k EB ex DE,HL ;HL:= r e t u r n address E9 j p (HL) .RELPROC AnaOutStatus.1 ;Read a l l c u r r e n t a n a l o g output v a l u e s i n t o parameter #1®. ; Uses F. BC, DE. and HL, d i s / e n - a b l e s i n t e r r u p t s . .REF l d c u r a n i E1 pop HL D1 pop DE E5 push HL 01 1000 Id BC,8*2 C3 OOOO j p l d c u r a n i ; r e t u r n a d d r e s s ;(DE):= s i nk b u f f e r ;8 chann e l s * 2 b y t e s per channel ;a c t u a l r o u t i n e performed w i t h i n Anaread . END Assembly complete: 374 l i n e s O e r r o r s f l a g g e d on t h i s assembly Appendix D Compiler L i s t i n g of U n i t E12Sched Page 3 0 0 d 1 <$L remout:} 4 2 1 d 1 U n i t E12Sched; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 Const sch h i b i t = 7; { h i g h e s t numbered d i g i t a l input b i t } 9 2 1 d 1 sch h i c h a n = 16; < h i g h e s t numbered a n a l o g input channel > 10 2 1 d 1 1 1 2 1 d 1 Type s c h _ b i t n o = 0 . . s c h _ h i b i t ; 12 2 1 d 1 sch channo = 1..sch_hichan; 13 2 1 d 1 14 2 1 d 1 Procedure E 1 2 S t a r t ; 15 2 1 d 1 { i n i t i a l i z e E12 d e v i c e p o l l i n g > 16 2 1 d 1 17 2 1 d 1 Procedure W a i t B i t ( b i t : sch_b1tno; v a l u e : b o o l e a n ) ; 18 2 1 d 1 { Wait f o r a d i g i t a l input b i t of g i v e n v a l u e . S u c c e s s i v e c a l l s 19 2 1 d 1 are queued. > 20 2 1 d 1 21 2 1 d 1 Procedure WaitAnalog (chan: sch_channo); 22 2 1 d 1 { Wait f o r a n a l o g input chan to d i f f e r from i t s s e t p o i n t by 23 2 1 d 1 more than +/- i t s maxerror. S u c c e s s i v e c a l l s a r e queued. } 24 2 1 d 1 25 2 1 d 1 Implementat ion 26 2 1 d 0 27 2 1 d 0 151 2 1 d 0 <$L-} Uses Schedule, E12d1gio, E12anaio, ($L®> 162 2 1 d 0 {$L-} ($U u t i 1 : s t a r t e r . c o d e } S t a r t e r ; <$L@) 163 2 1 d 0 164 2 1 d 0 Const p r e d_hichan = 15: < h i g h e s t a n a l o g channel - 1 ) 165 2 1 d 0 166 2 1 d o Type ana_pred_chan = 0..pred_hichan; 167 2 1 d 0 168 2 1 d 0 Var b i t needed, ana needed: boolean; 169 2 1 d 2 b i t a v a i l : a r r a y [ s c h _ b i t n o ] of semaphore; 170 2 1 d 18 b i t l o c k : a r r a y [sch b i t n o ] of semaphore; 17 1 2 1 d 34 ana a v a i l : a r r a y [sch_channo] of semaphore; 172 2 1 d 66 ana lock: a r r a y [sch channo] of semaphore; 173 2 1 d 98 1ow, h i gh: d i g i t a l ; 174 2 1 d 100 ana request:'ana_chan_set; 175 2 1 d 101 176 2 1 d 101 177 2 1 d 101 P r o c e s s P o l l e r ; forward; 178 2 1 d 1 { A h i g h p r i o r i t y E12 wait request s e r v i c i n g p r o c e s s ) 179 2 1 d 1 180 2 1 d 1 18 1 2 1 d 1 Segment Procedure E 1 2 S t r t ; 182 7 1 d 1 Var p i d : p r o c e s s i d ; 183 7 1 d 2 i , s t a c k , p r i o : i n t e g e r ; 184 7 1 0 0 Begi n Appendix D Compiler L i s t i n g of U n i t E12Sched Page 2 185 7 1 1 0 b i t needed:= f a l s e ; ana_needed:= f a l s e ; 186 7 1 1 6 low:= t ] : high:= [ ] : 187 7 1 1 16 ana_request:= [ ] : 188 7 1 1 2 1 f o r i:= 0 to s c h _ h i b i t do 189 7 1 2 30 Begin 190 7 1 3 30 s e m i n i t ( b i t _ a v a i 1 [ i ] . 0 ) ; 19 1 7 1 3 45 s e m i n i t ( b i t _ l o c k [ i ] , 1) 192 7 1 2 60 End; 193 7 1 1 65 f o r i:= 1 to s c h _ h i c h a n do 194 7 1 2 74 Beg i n 195 7 1 3 74 s e m i n i t ( a n a _ a v a i 1 [ 1 ] , 0 ) ; 196 7 1 3 90 s e m i n i t ( a n a _ l o c k [ i ] , 1) 197 7 1 2 106 End: 198 7 1 1 1 1 1 S t r t l n f o ('E12Sched', ' P o l l e r ' , s t a c k , p r i o , f a l s e ) : 199 7 1 1 126 s t a r t ( P o l l e r , p i d , st a c k , p r i o ) 200 7 1 0 0 End; { of E1 2 S t r t > 201 7 1 0 0 202 7 1 0 0 203 2 1 d 1 Procedure E 1 2 S t a r t ; 204 2 2 0 0 Beg i n 205 2 2 1 0 E 1 2 S t r t 206 2 1 0 0 End; { of E12Start ) 207 2 1 0 0 208 2 1 0 0 209 2 1 d 1 Procedure W a i t B i t ; 2 10 2 1 d 1 { Wait f o r a d i g i t a l input b i t of v a l u e } 2 1 1 2 3 0 0 Begin 212 2 3 1 0 wait ( b i t l o c k [ b i t ] ) : { queue s u c c e s s i v e c a l l s ) 2 13 2 3 1 9 i f v a l u e then high:= h i g h + [ b i t ] 214 2 3 1 18 e l s e low:= low + [ b i t ] : 215 2 3 1 36 bit_needed:= t r u e ; 216 2 3 1 39 Po111nputs: 2 17 2 3 1 4 1 wa.i t ( b i t aval 1 [ b i t ] ) ; 218 2 3 1 50 s i g n a l ( b i t _ l o c k [ b i t ] ) { a l l o w next c a l l i n queue > 219 2 1 0 0 End; { of W a i t B i t } 220 2 1 0 0 221 2 1 0 0 222 2 1 d 1 Procedure WaitAnalog; 223 2 1 d 1 { Wait f o r chan input to d i f f e r from s e t p o i n t > +- e r r o r 224 2 4 0 0 Beg i n 225 2 4 1 0 wait (ana l o c k [ c h a n ] ) ; { queue s u c c e s s i v e c a l l s ) 226 2 4 1 10 ana request:= ana_request + [chan-1]; 227 2 4 1 22 ana needed:= t r u e ; 228 2 4 1 25 Pol 1 Inputs; 229 2 4 1 27 wait (ana_avai1[chan] ) ; 230 2 4 1 37 s i g n a l ( a n a _ l o c k ( c h a n ] ) { a l l o w next c a l l i n queue } 231 2 1 0 0 End; < of WaitAnalog > 232 2 1 0 0 233 2 1 0 0 234 2 1 d 1 Pr o c e s s Po11er; Appendix D Compiler L i s t i n g of U n i t E12Sched Page 3 < A h i g h p r i o r i t y E12 wait request s e r v i c i n g p r o c e s s } Var d i g i n , b i t s _ r e a d y : d i g i t a l : anas_ready: ana_chan_set; i : i n t e ger; Beg i n { j o i n d e v i c e p o l l synchronous a c c e p t o r s } DvceJo i n; w h i l e running do Beg i n i f b i t _ n e e d e d then B e g i n { check d i g i t a l input f o r r e q u e s t e d b i t s } DigRead ( d i g i n ) ; b i t s _ r e a d y : = d i g i n * h i g h + ( l o w - d i g i n ) ; i f b i t s _ r e a d y <> [] then Begin high:= h i g h - b i t s _ r e a d y ; 1ow:= low - b i t s _ r e a d y ; bit_needed:= high+low <> [ ] ; i : = 0; f o r i : - 0 to s c h _ h i b i t do i f i in b i t s _ r e a d y then s i g n a l ( b i t _ a v a 1 1 [ i ] ) End ( o f i f b i t s _ r e a d y > End; { of i f b i t _ n e e d e d ) i f ana_needed then Beg i n AnaReady (anas_ready ): anas_ready:- anas_ready * ana_request; i f anas_ready <> [] then Beg i n ana_request:= ana_request - anas_ready; ana_needed:= ana_request <> ( ] ; f o r i:= 0 to p r e d _ h i c h a n do i f i in anas_ready then s i g n a l (ana_avai1[1+1]) End ( o f i f anas_ready } End; ( o f i f ana_needed ) < wait f o r next d e v i c e p o l l > i f r u n n i n g then DvceAcpt ( t r u e ) End; { of w h i l e running > ( program e x e c u t i o n f i n i s h e d : s i g n a l a l l w a i t i n g t a s k s } DvceOu i t : f o r i:= 0 to s c h _ h i b i t do s i g n a l ( b i t _ a v a i 1 [ i ] ) ; f o r i:= 1 to s c h _ h i c h a n do s i g n a l ( a n a _ a v a i 1 [ i ] ) End; ( of P o l l e r ) ^ O 00 235 2 1 : d 1 236 2 5 : d 1 237 2 5 : d 3 238 2 5 : d 4 239 2 5 : 0 0 240 2 5: 0 0 24 1 2 5 : 1 2 242 2 5: 1 4 243 2 5 : 1 4 244 2 5 : 2 10 245 2 5 : 2 10 246 2 5 : 3 10 247 2 5 : ; 4 13 248 2 5 : 4 13 249 2 5 : 5 13 250 2 5: :5 16 251 2 5 : 5 32 252 2 5: :6 38 253 2 5 : 7 38 254 2 5 : 7 48 255 2 5 : 7 58 256 2 5 : 7 70 257 2 5 : 7 72 258 2 5 :8 81 259 2 5 :6 96 260 2 5 : 4 101 261 2 5 : 4 101 262 2 5 : 3 101 263 2 5 : 4 104 264 2 5 : 5 104 265 2 5 : 5 107 266 2 5 :5 1 16 267 2 5 :6 122 268 2 5 :7 122 269 2 5 : 7 132 270 2 5 : 7 140 271 2 5 :8 149 272 2 5 :6 166 273 2 5 :4 171 274 2 5 : 4 171 275 2 5 : 4 171 276 2 5 : 3 171 277 2 5 : 2 1 77 278 2 5 : 2 182 279 2 5 : 2 182 280 2 5 : 1 182 281 2 5 : 1 184 282 2 5 : 1 207 283 2 1 :0 O 284 2 1 :0 0 Appendix D Compiler L i s t i n g of U n i t E12Sched Page 285 2 1:0 0 286 2 :0 0 End. End of C o m p i l a t i o n . to o Appendix D Compiler L i s t i n g of U n i t T r i g A n a Page 1 3 0 0 d 1 {$L remout:} 4 2 1 d 1 U n i t T r igAna; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 Var ana_names: a r r a y [1..16] of s t r i n g [ 8 ] ; 9 2 1 d 81 10 2 1 d 8 1 P rocedure T r i g l n i t ; 1 1 2 1 d 1 { Read channel i n v e r t and p r i o r i t i e s from d i s k , s t a r t t r i g g e r i n g } 12 2 1 d 1 13 2 1 d 1 Procedure T r i g S e t u p ; 14 2 1 d 1 { I n t e r a c t i v e l y change anal o g t r i g g e r p r i o r i t i e s } 15 2 1 d 1 16 2 1 d 1 Implementat ion 17 2 1 d 81 18 2 1 d 81 133 2 1 d 81 <$L-> Uses ErrMessg. MiscFunc. WritCons. Schedule, {$L®> 32 1 2 1 d 81 {$L-} ReadKybd, S c r n B u f f , E12anaio; <$L@> 322 2 1 d 81 323 2 1 d 81 Const f i l e _ n a m e = 'UTIL:SYSTEM.PRIO[1]'; 324 2 1 d 81 lochan = 1; h i c h a n = 16; 325 2 1 d 81 n o t r i g =8; { i f p r i o r i t y [ c h a n ] = n o t r i g , chan never t r i g ' d 326 2 1 d 81 327 2 1 d 81 Type d a t a _ _ f i l e = f i l e of r e c o r d 328 2 1 d 81 i n v e r t ; ana c h a n _ f l a g s ; 329 2 1 d 81 p r i o r i t y : a n a _ p r i o r i t i e s 330 2 1 d 81 end; 331 2 1 d 81 332 2 1 d 81 Var i n v e r t : ana_chan_f1ags; 333 2 1 d 82 p r i o r i t y : a n a _ p r i o r i t i e s ; 334 2 1 d 86 f i l e read, f i l e a l t e r e d : boolean; 335 2 1 d 88 336 2 1 d 88 337 2 1 d 88 Procedure TrigRead: 338 2 4 d 1 Var chan: i n t e g e r ; 339 2 4 d 2 p r i o f i l e : d a t a _ f i l e ; 340 2 4 0 0 Beg i n 34 1 2 4 1 8 {$I-> r e s e t ( p r i o _ f i l e , fi1e_name); {$1+} 342 2 4 1 19 i f i o r e s u I t <> 0 343 2 4 1 22 then N o t e E r r o r (100, i o r e s u l t , f a l s e ) 344 2 4 1 31 e l s e Begin 345 2 4 3 35 1nvert:= p r i o fi1e®.1nvert; 346 2 4 3 4 1 p r i o r i t y : = p r i o fi1e®.priority; 347 2 4 2 49 End; 348 2 4 1 49 Pol 1 Inputs ; 349 2 4 1 51 {$I-> c l o s e ( p r i o _ f i l e . normal): {$I+> 350 2 4 1 56 f i l e read:= t r u e 35 1 2 1 0 0 End; { of TrigRead ) 352 2 1 0 0 Appendix D Compiler L i s t i n g of U n i t T rigAna Page 2 353 2 1 •o 0 354 2 1 :d 1 Procedure T r i g g e r ; 355 2 5 d 1 Var chan. compare: i n t e g e r ; 35G 2 5 .0 0 Begi n 357 2 5 0 0 < ensure lowest p r i o r i t y i s z e r o } 358 2 5 1 0 compare: 3 n o t r i g : 359 2 5 1 2 f o r chan:= lochan to h i c h a n do 360 2 5 2 1 1 compare: 3 i_Min ( p r i o r i t y [ c h a n ] , compare); 36 1 2 5 1 32 i f compare 3 n o t r i g 362 2 5 1 33 then AnalnStop { no channels to t r i g g e r ) 363 2 5 1 36 e l s e Begin 364 2 5 3 4 1 i f compare > 0 then 365 2 5 3 46 < decrease a l l p r i o r i t y p r o p o r t i o n a t e l y } 366 2 5 4 46 f o r c h a n : 3 lochan to h i c h a n do 367 2 5 5 55 i f p r i o r i t y [ c h a n ] <> n o t r i g then 368 2 5 6 69 p r i o r i t y t c h a n ] : = p r i o r i t y [ c h a n ] - compare: 369 2 5 3 101 AnalnGo ( i n v e r t , p r i o r i t y ) 370 2 5 2 105 End { of e l s e > 37 1 2 1 0 0 End; { of T r i g g e r } 372 2 1 0 0 373 2 1 0 0 374 2 1 d 1 Procedure T r i g l n i t ; 375 2 2 0 0 B e g i n 376 2 2 1 0 i f not f i l e _ r e a d then TrigRead: 377 2 2 1 6 i f not E r r o r N o t e d then T r i g g e r 378 2 1 0 0 End; 379 2 1 0 0 380 2 1 0 0 381 2 1 d 1 Procedure T r i g S e t u p ; 382 2 1 d 1 383 2 3 d 1 Const xchan = 10; ychan 3 3; fchan 3 2; ( channel p o s i t i o n , f i e l d ) 384 2 3 d 1 yO 3 6; { o f f s e t to add to channel f o r d i s p l a y l i n e ) 385 2 3 d 1 xname - 37 ( chefhnel name d i s p l a y column } 386 2 3 d 1 fname 3 8 ( " " " f i e l d width ) 387 2 3 d 1 x i n v t - 48 < i n v e r t boolean d i s p l a y column ) 388 2 3 d 1 f i nvt 3 5 { " " " f i e l d w i d t h > 389 2 3 d 1 x p r i o 3 60 { p r i o r i t y d i s p l a y column } 390 2 3 d 1 f p r i o 3 1 { " " f i e l d w i d t h } 391 2 3 d 1 x f r e q 3 69 { frequency d i s p l a y column ) 392 2 3 d 1 f f r e q 3 6 { " " f i e l d width } 393 2 3 d 1 d f r e q 3 2 { " " decimal f i e l d width ) 394 2 3 d 1 395 2 3 d 1 Var com: char; 396 2 3 d 2 chan, y: i n t e g e r ; 397 2 3 d 4 prompt: sb prmt p t r ; 398 2 3 d 5 n t r i g : a r r a y [1ochan..hichan] of i n t e g e r ; 399 2 3 d 2 1 400 2 3 d 2 1 Procedure C h e c k E r r o r ; 401 2 6 0 0 Beg 1 n 402 2 6 1 0 i f E r r o r N o t e d then e x i t ( T r i g S e t u p ) K) O Appendix D Compiler L i s t i n g of U n i t T rigAna Page 3 403 2 3 : 0 0 End; 404 2 3 : 0 0 405 2 3 : d 1 Procedure TaskSwitch; 406 2 7 : 0 0 Begin 407 2 7 : 1 0 Pol 1 Inputs; 408 2 7 : 1 2 Ch e c k E r r o r 409 2 3 : 0 0 End; 4 10 2 3 : 0 0 4 1 1 2 3 : d 1 Procedure F i n d N t r i g (chan: i n t e g e r ) ; 4 12 2 3 : d 1 { c a l c u l a t e number of times each channel i s t r i g g e r e d per c y c l e } 4 13 2 8 : d 1 Var ans, 1: i n t e g e r ; 4 14 2 8: 0 0 Beg i n 4 15 2 8 : 1 0 ans : = 128; 4 16 2 8: 1 3 f o r 1:= 1 to p r i o r i t y [ c h a n ] do ans:= ans d i v 2; 417 2 8 : 1 31 n t r i g[chan]:= ans 418 2 3 : 0 0 End: 4 19 2 3 : 0 0 420 2 3 : d 1 Procedure ShowData: 42 1 2 3 : d 1 { d i s p l a y i n v e r t boolean and t r i g g e r p r i o r i t y f o r a l l channe l s > 422 2 9 : d 1 Var chan. y: i n t e g e r : 423 2 9: 0 0 Begi n 424 2 9 : 1 0 f o r chan:= lochan to h i c h a n do 425 2 9: : 2 9 Beg i n 426 2 9 : 3 9 y:= yO + chan; 427 2 9 : 3 13 T o s s S t r i n g (xname, y, ana_names[chan]. fname); 428 2 9: : 3 29 F i ndNTr i g (chan ) ; 429 2 9: : 3 32 i f p r i o r 1 t y [ c h a n ] <> n o t r i g then 430 2 9 : 4 46 Begin 431 2 9 :5 46 TossBoolean ( x i n v t , y, i n v e r t [ c h a n ] ) ; 432 2 9 :5 62 T o s s l n t e g e r ( x p r i o , y, p r i o r i t y [ c h a n ] , f p r i o ) 433 2 9 : 4 77 End; { of i f > 434 2 9 : 3 79 TaskSw i t c h 435 2 9 : 2 79 End ( o f FindNTr1g > 436 2 3 :0 0 End; { of ShowData } 437 2 3 :0 0 438 2 3 :d 1 Procedure ShowFrequencies; 439 2 3 :d 1 { d i s p l a y t r i g g e r f r e q u e n c i e s f o r a l l c h a n n e l s } 440 2 10 :d 1 Var p. chan: i n t e g e r ; 44 1 2 10 :d 3 per i od: rea1 : 442 2 10 :0 0 Begin { *** ShowFrequencies *** > 443 2 10 : 1 0 p:= 0; 444 2 10 : 1 2 { f i n d p:= c y c l e p e r i o d i n 1/30ths of a second } 445 2 10 : 1 2 f o r chan:'= lochan to h i c h a n do p: = p + n t r i g [ c h a n ] ; 446 2 10 : 1 30 { c o n v e r t p to seconds > 447 2 10 : 1 30 period:= p / 30.0; 448 2 10 : 1 38 < d i s p l a y each c h a n n e l ' s frequency = n t r i g / p e r i o d } 449 2 10 : 1 38 f o r chan:= lochan to h i c h a n do 450 2 10 : 2 47 i f pr1 o r i t y [ c h a n ] <> n o t r i g then 45 1 2 10 : 3 61 Beg i n 452 2 10 : 4 61 TossReal ( x f r e q . yO+chan, n t r i g [ c h a n ] / p e r i o d , f f r e q . d f r e q ) Appendix D Compiler L i s t i n g of U n i t TrigAna Page 453 2 10: :4 85 454 2 10 : 3 85 455 2 3 :0 0 456 2 3 :0 0 457 2 3 :0 0 458 2 3: :0 0 459 2 3 : 1 0 460 2 3: : 1 6 46 1 2 3 : 1 8 462 2 3 : 1 8 463 2 3 : 1 15 464 2 3 : 1 17 465 2 3 : 1 17 466 2 3 : 1 19 467 2 3 : 1 19 468 2 3 : 1 21 469 2 3 : 1 21 470 2 3 : 1 30 47 1 2 3 : 1 32 472 2 3 : 1 32 473 2 3 : 1 38 474 2 3 : 1 44 475 2 3 : 1 44 476 2 3 : 1 44 477 2 3 :2 44 478 2 3 : 2 60 479 2 3 : 2 62 480 2 3 : 2 62 481 2 3 :2 63 482 2 3 :4 72 483 2 3 : 4 77 484 2 3 : 4 87 485 2 3 : 4 92 486 2 3 :5 96 487 2 3 :6 96 488 2 3 :6 1 12 489 2 3 :6 1 14 490 2 3 : 7 1 18 491 2 3 :8 1 18 492 2 3 :8 128 493 2 3 : 7 133 494 2 3 : 5 135 495 2 3 : 4 135 496 2 3 : 3 136 497 2 3 : 3 139 498 2 ' 3 : 2 139 499 2 3 :4 149 500 2 3 :5 149 501 2 3 : 5 153 502 2 3 : 5 183 TaskSwi t c h End { of f o r . i f > End; < of ShowFrequencies } Begin { *** main body of procedure T r i g S e t u p *** } { i f i n v e r t and p r i o r i t y a r r a y s not yet i n i t i a l i z e d , do so ) 1f not f i l e _ r e a d then TrigRead; C h e c k E r r o r ; { get the s c r e e n image > S c r n E n t e r ('TRIGANA'); CheckError; { f i n d n t r i g , d i s p l a y names, i n v e r t and p r i o r i t y d a t a } ShowData; { d i s p l a y channel f r e q u e n c i e s } ShowFrequenc i es; { l o a d prompt } prompt: 3 ScrnPrompt ( 0 ) ; C h e c k E r r o r ; { s t a r t with channel 16, f o r lack of any b e t t e r } c h a n : 3 16; y:= yO + chan; T o s s l n t e g e r (xchan, ychan, chan, f c h a n ) ; Repeat { u n t i l 0 ( u i t } { prompt f o r channel to change or changes to make } com: 3 PromptCapIn (0, 0, prompt®, ['1' . . '9'. ' I ' , 'P'. '0' ] ) ; C h e c k E r r o r ; 1f com i n ['1'..'9'] then Begin TossErase (xchan, ychan, f c h a n ) ; wr i te (com); chan:= ord (com) - o r d ('0'); i f chan 3 1 then Beg i n com:= ReadCharln ( [ ' 0 ' . . '6 ' . c h r ( 1 3 ) ] ) ; C h eckError; i f com <> chr (13) then Beg i n wr i te (com); chan:= 10 + ord(com) - ord('O') End End: y : 3 yO + chan End ( of com i n ['1' . . '9' ] } e l s e i f com <> '0' then Begin Case com of ' I ' : i n v e r t [ c h a n ] : = TossNot ( x i n v t , y, i n v e r t [ c h a n ] ) ; ' P': Beg i n O o Appendix D Compiler L i s t i n g of U n i t T rigAna Page 5 503 2 3 7 183 T o s s E r a s e ( x p r i o , y, f p r i o ) ; 504 2 3 7 189 com:= ReadCharln ( [ c h r ( 1 3 ) , '0' . . '7 ' ] ) ; 505 2 3 7 205 C h e c k E r r o r ; 506 2 3 7 207 i f com = c h r ( 1 3 ) 507 2 3 7 209 then B e g i n 508 2 3 9 21 1 p r i o r i t y [ c h a n ] : = n o t r i g : 509 2 3 9 226 T o s s E r a s e ( x i n v t , y, f i n v t ) ; 510 2 3 9 232 T o s s E r a s e ( x f r e q , y, f f r e q ) 51 1 2 3 8 236 End 512 2 3 7 238 e l s e B e g i n 513 2 3 9 240 w r i t e (com); 514 2 3 9 250 i f p r i o r i t y [ c h a n ] = n o t r i g then 515 . 2 3 0 264 TossBoolean ( x i n v t , y, i n v e r t [ c h a n ] ) 516 2 3 9 280 p r i o r i t y [ c h a n ] : = ord(com) - ord('O') 517 2 3 8 293 End: 518 2 3 7 298 F i n d N t r i g (chan) 519 2 3 6 299 End 520 2 3 5 301 End: ( of Case ) 52 1 2 3 5 306 f i l e a l t e r e d : = t r u e : 522 2 3 5 309 Tr i gger; 523 2 3 5 31 1 i f com <> ' I ' then ShowFrequencies 524 2 3 4 316 End { of com <> '0' } 525 2 3 1 318 U n t i l not running or (com = '0'): 526 2 3 1 330 527 2 3 1 330 { r e t u r n to o r i g i n a l s c r e e n image ) 528 2 3 1 330 ScrnReturn 529 2 1 0 0 End; { of T r i g S e t u p } 530 2 1 0 0 531 2 1 0 0 532 2 1 d 1 Procedure SaveData; 533 2 1 1 d 1 Var p r i o f i l e : d a t a _ f i l e : 534 2 1 1 0 0 Beg i n 535 2 1 1 O 0 < save a l t e r e d p r i o r i t y f i l e ) 536 2 1 1 1 8 ( $ I - > r e w r i t e ( p r i o _ f i l e , f i l e _ n a m e ) ; ($1+) 537 2 1 1 1 19 i f i o r e s u l t <> 0 538 2 1 1 1 22 then N o t e E r r o r (101, i o r e s u l t , t r u e ) 539 2 1 1 1 31 e l s e Begin 540 2 1 1 3 35 p r i o f11e®.1nvert:= i n v e r t ; 541 2 1 1 3 4 1 p r i o f i 1 e®.priority: = p r i o r i t y ; 542 2 1 1 3 49 put ( p r i o f i l e ) 543 2 1 1 2 55 End; 544 2 1 1 1 55 ( $ I - > c l o s e ( p r i o _ f i l e , crunch) {$1+) 545 2 1 0 0 End; { of SaveData } 546 2 1 0 0 547 2 1 0 0 548 2 1 0 0 B e g i n ( i n i t i a l i z e / ha I t ) 549 2 1 1 0 f i l e read:= f a l s e ; f i 1 e _ a 1 t e r e d : = f a l s e ; 550 2 1 1 6 f i l l c h a r (ana names, s i z e o f (ana_names), 0 ) : 551 2 1 1 14 * * * . 552 2 1 1 17 i f f i l e a l t e r e d then SaveData Appendix D Compiler L i s t i n g of U n i t TrigAna Page 553 2 :0 0 End. End of C o m p i l a t i o n . Appendix D C o m p i l e r - L i s t i n g of Un i t P l o t U t i l Page 1 3 0 0 d 1 ($L remout:> 4 2 1 d 1 Uni t PIotUt i1 ; 5 2 1 d 1 G 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 Procedure PlotBounds (xmin, xmax, ymin, ymax: r e a l ) ; 9 2 1 d 1 { s e t s p l o t x & y ranges ) 10 2 1 d 1 1 1 2 1 d 1 Procedure P l o t (x, y: r e a l ) ; ( move pen to x,y. wait f o r i t to stop } 12 2 1 d 1 Procedure P l o t L i f t ; { l i f t pen o f f c h a r t ) 13 2 1 d 1 Procedure PlotDrop; { drop pen onto c h a r t > 14 2 1 d 1 Procedure P l o t A x e s ; < p l o t r e c t a n g l e of s i z e bounds > 15 2 1 d 1 16 2 1 d 1 Imp 1ementat i on 17 2 1 d 1 192 2 1 d 1 ($L-> Uses MiscFunc, Schedule. E12DigI0. E12AnaI0. E12Sched; ($L@> 193 2 1 d 1 194 2 1 d 1 Const pen b i t = 7; < E12 b i t f o r pen motion 6 z a x i s } 195 2 1 d 1 z d e l a y = 3: < t i c k s d e l a y a f t e r z a x i s motion ) 196 2 1 d 1 xchan = 7: ychan = 6; { analog output c h a n n e l s } 197 2 1 d 1 198 2 1 d 1 Var x l o . y l o , x h i , y h i , x s c a l e , y s c a l e : r e a l ; 199 2 1 d 13 200 2 1 d 13 201 2 1 d 13 Procedure PlotBounds; 202 2 2 0 0 Begin 203 2 2 1 0 xlo:= xmin; xhi:= xmax; 204 2 2 1 10 ylo:= ymin; yhi:= ymax; 205 2 2 1 20 xscale:= 4095.0 / (xhi - x l o ) ; 206 2 2 1 34 y s c a l e : = 4095.0 / ( y h i - y l o ) 207 2 1 0 0 End: ( of PlotBounds ) 208 2 1 0 0 209 2 1 0 O 2 10 2 1 d 1 Procedure P l o t ; 21 1 2 3 d 1 Procedure Send (chan: i n t e g e r ; v a l u e , s c a l e , min: r e a l ) : 212 2 7 0 0 Begin 213 2 7 1 0 AnaWrite (round (rBounded (sea 1e*(va1ue-min), 0.0, 4095.0)), chan) 214 2 3 0 0 End; { of P l o t > 215 2 3 0 0 Beg i n 21G 2 3 1 0 Send (xchan, x, x s c a l e , x l o ) : 217 2 3 1 1 1 Send (ychan, y, y s c a l e . y l o ) ; 2 18 2 3 1 22 i f r u n n i n g then 219 2 3 2 27 W a i t B i t (pen b i t , t r u e ) { wait f o r motion to s t o p > 220 2 1 0 0 End; 22 1 2 1 0 0 222 2 1 d 1 Procedure Pen ( d i r e c t i o n : d i g i t a l ) ; 223 2 8 0 0 Begin 224 2 8 1 0 Dig W r i t e ( d i r e c t i o n , [pen b i t ] ) ; 225 2 8 1 8 i f r u n n i n g then W a i t T i c k (z d e l a y ) Appendix D Compiler L i s t i n g of U n i t P l o t U t i l Page 2 22G 2 1 0 0 End: { of Pen }. -227 2 1 0 0 228 2 1 d 1 Procedure P l o t L i f t ; 229 2 4 0 0 Begin 230 2 4 1 0 Pen ([pen b i t ] ) { h i g h 231 2 1 0 0 End; { of P l o t L i f t > 232 2 1 0 0 233 2 1 d 1 Procedure P l o t D r o p ; 234 2 5 0 0 Beg i n 235 2 5 1 0 Pen ([ ] ) ( low to drop 23G 2 1 0 0 End; < of P l o t D r o p > 237 2 1 0 0 238 2 1 0 0 239 2 1 d 1 Procedure P l o t A x e s ; 240 2 6 0 0 Beg i n 241 2 6 1 0 P l o t L i f t ; 242 2 6 1 2 P l o t ( x l o , y l o ) : 243 2 6 1 10 P1otDrop; 244 2 6 1 12 P l o t ( x l o , y h i ) ; 245 2 6 1 20 P l o t ( x h i , y h i ) ; 246 2 6 1 28 P l o t ( x h i , y l o ) ; 247 2 6 1 36 P l o t ( x l o , y l o ) ; 248 2 6 1 44 P l o t L i f t 249 2 1 0 0 End; { of P l o t A x e s ) 250 2 1 0 0 251 2 1 0 0 252 2 1 0 0 B e g i n 253 2 1 1 0 i f f a l s e then { f o r c e 254 2 0 0 End. { of P l o t U t i l ) i n i t i a l i z a t i o n of used u n i t s } End of C o m p i l a t i o n . Appendix E Compiler L i s t i n g of U n i t S t a r t e r Page 1 3 0 0 d 1 4 2 1 d 1 5 2 1 d 1 6 2 1 d 1 7 2 1 d 1 8 2 1 d 1 9 2 1 d 1 10 2 1 d 1 1 1 2 1 d 5 12 2 1 d 7 13 2 1 d 1 14 2 1 d 1 15 2 1 d 1 16 2 1 d 1 17 2 1 d 18 2 1 d 60 2 1 d 61 2 1 d 62 2 1 d 63 2 1 d 64- 2 1 d 1 65 2 2 d 1 66 2 3 d 1 67 2 3 0 0 68 2 3 1 10 69 2 3 2 19 70 2 3 3 28 7 1 ' 2 3 4 28 72 2 3 4 39 73 2 3 3 44 74 2 2 0 0 75 2 2 0 0 76 2 2 0 0 77 2 2 1 10 78 2 2 1 16 79 2 2 1 16 80 2 2 1 16 81 2 2 1 16 82 2 2 1 16 83 2 2 1 16 84 2 2 1 32 85 2 2 1 48 86 2 2 1 65 87 2 2 1 81 88 2 2 1 97 89 2 2 1 1 13 90 2 2 1 129 91 2 2 1 145 92 2 2 1 161 {$L remout:> U n i t S t a r t e r ; I n t e r f a c e Type strt_name = s t r 1 n g [ 8 ] ; Procedure S t r t l n f o (unit_name, var s t a c k , ca11_f rom_ { look up st a c k s i z e and p r i o r . . , .„ u n i t or from i n i t i a l i z a t i o n p a r t ? ) ) Imp 1ementat ion process_name: strt_name; p r i o : i n t e g e r ; i n i t i a 1 1 z a t i o n _ p a r t : b o o l e a n ) ; 1 ty f o r named p r o c e s s (from body of * » \ {$L-} Uses ErrMessg, MiscFunc: <$L©> Procedure S t r t l n f o ; Procedure Try (u_name, p_name: strt_name; stak, p r i o r i t y : i n t e g e r ) Const s t a c k _ s a f e t y = 50; { add t h i s t o a l l l i s t e d s t a c k s i z e s } Beg i n i f unit_name = u_name then i f process_name = p_name then Beg i n stack:= stak + s t a c k _ s a f e t y ; p r i o : = p r i o r i t y ; e x i t ( S t r t l n f o ) End < of - i f p_name } End; { of Try } Begin < ** Uppercase S t r t l n f o > (un i t name); Uppercase (process_name); L i s t the u n i t names, pr o c e s s names, st a c k s i z e , names must be UPPER CASE. Pro c e s s e s a r e l i s t e d p r i o r i t y f o r ease of e d i t i n g o n l y . ) & p r i o r i t y to t r y : in o r d e r of d e c r e a s i n g Try ( 'SCHEDULE' 'POLLER', 95. 230) ; Try ( ' E 1 2SCHED' 'POLLER' , 70, 230) ; Try ('PARAMSAV' 'PARAMPUT', 390, 210) ; Try ('SPUTTER', 'CURRENT', 1 10, 190) ; Try ('SPUTTER', 'VOLTAGE', 1 10. 190) ; Try ( 'SPUTTER ' , 'POWER', 1 10. 190) Try ('SPUTTER ' . 'GAS[0]', 125, 190) • T ry ( 'SPUTTER' . 'GASt1 ] ' , 125 , 190) T ry ('SPUTTER ' . 'GAS[2]', 125, 190) Try ('WALKER', 'WALKSETP', 1 10. 170) M OJ Appendix E Compiler L i s t i n g of U n i t S t a r t e r P a g e 93 2 2 1 177 94 2 2 1 177 95 2 2 1 177 96 2 2 1 177 97 2 2 1 193 98 2 2 1 209 99 2 2 1 225 100 2 2 1 24 1 101 2 2 1 257 102 2 2 1 273 103 2 2 1 289 104 2 2 1 305 105 2 2 1 320 106 2 2 1 335 107 2 2 1 335 108 2 2 1 335 109 2 2 1 339 1 10 2 2 1 395 1 1 1 2 2 1 399 1 12 2 1 0 0 1 13 2 1 O 0 1 14 2 1 0 0 1 15 2 0 0 End of C o m p i l a t i o n . { main o p e r a t o r i n t e r a c t i o n t a s k . . . 128 } Try ( ' SCRNBUFF' 'UPDATE ' , 255. 1 10) Try ( 'SPUTTER' , 'PRESSURE ' . 1 10, 90) Try ( 'SPUTTER ' . 'ANODE ' , 1 10, 90) Try ( 'SPUTTER ' . 'RF BIAS ' , 1 10, 90) Try ( 'SPUTTER ' . 'EXTRA 1 ' , 1 10, 90) Try ( 'SPUTTER ' . 'EXTRA2', 1 10, 90) Try ('PARAMETR' 'WARNING'. 245, 70) Try ('PARAMETR' 'SHOWTIME'. 95, 50) Try ( 'PLOTTER ' , 'PLOTDATA ' . 1 15, 30) Try ( 'SCHEDULE ' 'DUMPTIME', 50. 10) { The f o l l o w i n g code w i l l o n l y be reached i f s t a r t d a t a i s not found: gotoxy (O, 15); w r i t e (' ', unit_name, '/'. process_name, ' ' ) ; No t e E r r o r (102, 0. c a 1 l _ f r o m _ i n i t i a 1 i z a t i o n _ p a r t ) End; { of S t r t l n f o > End. Appendix E Compiler L i s t i n g of U n i t DataBus Page 1 3 0 0: d 4 2 1 : d 5 2 1 : d6 2 1 : d7 2 1 d 8 2 1 d 9 2 1 d 10 2 1 d 1 1 2 1 d 12 2 1 d 13 2 1 d 14 2 1 d 15 2 1 d 16 2 1 d 17 2 1 d 18 2 1 d 19 2 1 d 20 2 1 d 2 1 2 1 d 22 2 1 d 23 2 1 d 24 2 1 d 25 2 1 d 26 2 1 d 27 2 1 d 28 2 1 d 29 2 1 d 30 2 1 d 31 2 1 d 32 2 1 d 33 2 1 d 34 2 1 d 35 2 1 d 36 2 1 d 37 2 1 d 38 2 1 d 39 2 1 d 40 2 1 d 4 1 2 1 d 42 2 1 d 43 2 1 d 44 2 1 d 45 2 1 :d 46 2 1 : d 47 2 1 : d 48 2 1 :d 49 2 2 :0 50 2 2 : 1 5 1 2 2 : 2 0 0 o 1 0 0 2 ($L remout:} U n i t DataBus: I n t e r f a c e < type handshake v a r i a b l e s must be m a n i p u l a t e d o n l y by c a l l s to DataBus procedures } Type handshake r e c o r d l o c k : semaphore: n_sync_acpt: 0..maxint: n_async_acpt: 0..maxint; a t t e n t i o n : semaphore; r e a d y _ f o r _ d a t a : semaphore; d a t a _ v a l i d : semaphore; d a t a a c c e p t e d : semaphore end: { Any number of s o u r c e and a c c e p t o r p r o c e s s e s , w i t h any c o n v e n i e n t p r i o r -i t i e s , may share one handshake. The s o u r c e handshake w a i t s f o r synch-ronous a c c e p t o r s o n l y . > Procedure A c p t J o i n (var h: handshake); < c a l l to a c c e p t f i r s t synchronous d a t a > Procedure AcptHshk (var h: handshake; synchronous: b o o l e a n ) ; { c a l l to accept asynchronous or o t h e r than f i r s t synchronous d a t a ) Procedure A c p t Q u i t ( v a r h: handshake); ( c a l l upon acceptance and use of l a s t d e s i r e d synchronous d a t a ) Procedure SrceLock (var h: handshake); { c a l l to e x clude a l l o t h e r sources from handshake, a l l o w d a t a change ) Procedure SrceHshk (var h: handshake; u n l o c k e d : b o o l e a n ) ; { c a l l a f t e r data changed--unlocked i s t r u e i f f SrceLock wasn't c a l l e d f i r s t ) Procedure H s h k l n i t (var h: handshake); { i n i t i a l i z e type handshake } Implementat ion Procedure A c p t J o i n ; { c a l l to a c c e p t f i r s t synchronous d a t a > Beg i n wi th h do Beg i n Ul Appendix E Compiler L i s t i n g of U n i t DataBus Page 2 52 2 2 : 3 2 wa i t (1ock); 53 2 2 : 3 4 n sync acpt:= n_sync_acpt + 1 : 54 2 2 : 3 16 s i gna1 (1ock ) ; 55 2 2 : 3 18 wa i t ( a t tent i on ) ; 56 2 2 : 3 22 s i g n a l ( r e a d y _ f o r _ d a t a ) ; 57 2 2 : 3 26 wai t (data v a 1 i d ) 58 2 2 : 2 30 End 59 2 1 :0 0 End: 60 2 1 :0 0 61 2 1 :0 0 62 2 1 :d 1 Procedure AcptHshk; 63 2 1 :d 1 { c a l l to accept asynchronous or other than f i r s t synchronous d a t a } 64 2 3 :0 0 Beg i n 65 2 3 : 1 0 with h do 66 2 3 :2 2 Beg i n 67 2 3 : 3 2 i f synchronous then s i g n a l ( d a t a _ a c c e p t e d ) 68 2 3 : 3 9 e l s e n_async_acpt:= n_async_acpt + 1; 69 2 3 : 3 23 wait ( a t t e n t i o n ) ; * 70 2 3 : 3 27 i f synchronous then s i g n a l ( r e a d y _ f o r _ d a t a ) ; 7 1 2 3 : 3 34 wa i t ( d ata va11d) 72 2 3 : 2 38 End • 73 2 1 :0 0 End: 74 2 1 :0 0 75 2 1 :0 0 76 2 1 :d 1 Procedure AcptOu i t; 77 2 1 :d 1 < c a l l upon acceptance and use of l a s t d e s i r e d synchronous d a t a } 78 2 4 :0 0 Beg i n 79 2 4 : 1 0 with h do 80 2 4 : 2 2 Beg i n 81 2 4 : 3 2 n sync acpt:= n_sync_acpt - 1; 82 2 4 : 3 14 s i g n a l (data accepted) 83 2 4 : 2 18 End 84 2 1 :0 0 End: 85 2 1 :0 0 86 2 1 :0 0 87 2 1 :d 1 Procedure SrceLock; 88 2 1 : d 1 { c a l l to i n h i b i t a l l o t h e r sources from handshake, a l l o w data change } 89 2 5 :0 0 B e g i n 90 2 5 : 1 0 wa i t (h.1ock ) 9 1 2 1 :0 0 End; 92 2 1 :0 0 93 2 1 :0 0 94 2 1 :d 1 Procedure SrceHshk; 95 2 1 :d 1 ( c a l l a f t e r data changed--unlocked i s t r u e i f f SrceLock wasn't c a l l e d 96 2 1 : d 1 f i r s t > 97 2 6 :d 1 Var n sync l a t c h e d , n async l a t c h e d : 0..maxint: 98 2 6 :d 3 n: i n t e g e r ; 99 2 6 :0 0 Beg i n 100 2 6 : 1 0 with h do 101 2 6 : 2 2 Beg i n Appendix E Compiler L i s t i n g of U n i t DataBus Page 3 102 2 6 : 3 2 i f u n l o c k ed then wait ( l o c k - ) ; 103 2 6 : 3 7 n sync l a t c h e d : 3 n_sync_acpt; 104 2 6 : 3 15 f o r n:= 1 to n sync l a t c h e d do s i g n a l ( a t t e n t i o n ) ; 105 2 6 : 3 33 n a s y n c _ l a t c h e d : - 0; 106 2 6 : 3 40 w h i l e n_async_acpt > 0 do 107 2 6 : 4 46 Beg i n 108 2 6 :5 46 n:= n a s y n c _ a c p t ; 109 2 6 :5 49 n async acpt:= 0; 1 10 2 6 :5 59 n_async_latched:= n _ a s y n c _ l a t c h e d + n; 1 1 1 2 6 : 5 68 f o r n:= 1 to n do s i g n a l ( a t t e n t i o n ) 1 12 2 6 : 4 8 1 End; 1 13 2 6 : 3 88 f o r n:= 1 to n _ s y n c _ l a t c h e d do wait ( r e a d y _ f o r _ d a t a ) ; 1 14 2 6 : 3 106 f o r n:= 1 to n _ s y n c _ l a t c h e d + n _ a s y n c _ l a t c h e d do s i g n a l 1 15 2 6 : 3 126 f o r n:= 1 to n sync l a t c h e d do wait ( d a t a _ a c c e p t e d ) ; 1 16 2 6 : 3 144 s i gna1 (1ock) 1 17 2 6 : 2 146 End 1 18 2 1 :0 O End; 1 19 2 1 :0 0 120 2 1 :0 0 • 12 1 2 1 :d 1 Procedure H s h k l n i t ; 122 2 1 :d 1 < i n i t i a l i z e type handshake } 123 2 7 :0 0 Begin 124 2 7 : 1 0. w i t h h do 125 2 7 :2 2 Beg i n 126 2 7 : 3 2 semi n i t (1ock , 1 ) ; 127 2 7 :3 10 n_sync_acpt:= 0; 128 2 7 : 3 20 n async_acpt:= O; 129 2 7 : 3 30 s e m i n i t ( a t t e n t i o n , 0 ) ; 130 2 7 : 3 40 s e m i n i t ( r e a d y _ f o r _ d a t a , 0 ) ; 13 1 2 7 : 3 50 s e m i n i t ( d a t a _ v a l i d , 0 ) ; 132 2 7 : 3 60 s e m i n i t ( d a t a _ a c c e p t e d , 0) 133 2 7 : 2 70 End 134 2 1 :0 0 End; 135 2 1 :0 0 136 2 1 :0 0 137 2 :0 0 End. End of C o m p i l a t i o n . Appendix E Compiler L i s t i n g of U n i t Schedule Page 1 3 0 0 d 1 {$L remout:} 4 2 1 d 1 U n i t Schedule: 5 2 1 d 1 G 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 Type sch chset = set of char; 9 2 1 d 1 10 2 1 d 1 Var running: boolean; 1 1 2 1 d 2 { The c o n d i t i o n of a l l r e p e a t i n g loop p r o c e s s e s - - r e s e t to end the 12 2 1 d 2 program and shut down a l l p r o c e s s i n g } 13 2 1 d 2 14 2 1 d 2 Procedure P o l l l n p u t s ; 15 2 1 d 1 { S i g n a l p o l l i n g p r o c e s s to check c l o c k , keyboard, and SrceHshk 16 2 1 d 1 the e x t e r n a l d e v i c e p o l l } 17 2 1 d 1 18 2 1 d 1 Procedure DvceJoin; 19 2 1 d 1 { J o i n e x t e r n a l d e v i c e p o l l synchronous a c c e p t o r s } 20 2 1 d 1 2 1 2 1 d 1 Procedure DvceAcpt (synchronous: b o o l e a n ) ; 22 2 1 d 1 { Accept e x t e r n a l d e v i c e pol1 } 23 2 1 d 1 24 2 1 d 1 Procedure DvceQuit: 25 2 1 d 1 { Leave e x t e r n a l d e v i c e p o l l synchronous a c c e p t o r s > 26 2 1 d 1 27 2 1 d 1 Procedure WaitTick ( t i c k s : i n t e g e r ) ; 28 2 1 d 1 { Wait f o r t i c k s / 6 0 seconds ( u n l i m i t e d number of c a l l e r s ) } 29 2 1 d 1 30 2 1 d 1 F u n c t i o n WaitChar ( c h a r s : sch c h s e t ) : char; 31 2 1 d 1 < Wait f o r a c o n s o l e c h a r a c t e r i n the s e t c h a r s ( c a l l e r s a r e queued 32 2 1 d 1 and w i l l be s a t i s f i e d i n t h e i r c a l l sequence) > 33 2 1 d 1 34 2 • 1 d 1 Implementat ion 35 2 1 d 36 2 1 d 201 2 1 d {$L-} Uses Er'rMessg, C l o c k , ScreenOps, ExtraScreenOps, DataBus, {$L(8} 212 2 1 d ($L-> ($U u t i 1 : s t a r t e r . c o d e } S t a r t e r ; <$L©} 213 2 1 d 2 14 2 1 d 215 2 1 d Type p t r t i c k request = ©tick_request; 2 16 2 1 d t i c k request = r e c o r d 217 2 1 d time to s i g n a l : t i m _ r e c ; 2 18 2 1 d sem_to_signa1: semaphore; 2 19 2 1 d next r e q u e s t : p t r _ t i c k _ r e q u e s t 220 2 1 d end: 221 2 1 d 222 2 1 d Var task done: semaphore; 223 2 1 d dvce_pol1: handshake; 224 2 1 d f i r s t r equest: p t r t i c k r e q u e s t ; 225 2 1 d 0 ti c k _ n e e d e d , char_needed: boolean: Appendix E Compiler L i s t i n g of U n i t Schedule Page 2 226 2 1 d 2 char a v a i l . c h a r _ l o c k : semaphore; 227 2 1 d 6 match: s c h _ c h s e t ; 228 2 1 d 22 ch: char; 229 2 1 d 23 230 2 1 d 23 231 2 1 d 23 P r o c e s s P o l l e r ; forward; 232 2 1 d 1 < A h i g h p r i o r i t y wait request s e r v i c i n g p r o c e s s } 233 2 1 d 1 234 2 1 d 1 P r o c e s s DumpTime; forward; 235 2 1 d 1 { a lowest p r i o r i t y p r o c e s s to absorb unneeded cpu time 236 2 1 d 1 237 2 1 d 1 238 2 1 d 1 Segment Procedure S c h d l n i t : 239 9 1 d 1 Var p i d : p r o c e s s i d ; 240 9 1 d 2 s t a c k , p r i o : i n t e g e r ; 24 1 9 1 0 0 Begin 242 9 1 1 0 runn i ng:= t r u e ; 243 9 1 1 3 t i c k needed: 3 f a l s e ; char_needed:= f a l s e ; 244 9 1 1 9 f 1 r s t _ r e q u e s t : = n i l ; 245 9 1 1 12 s e m i n i t (task_done, 0 ) : 246 9 1 1 2 1 s e m i n i t ( c h a r _ a v a i l . 0 ) ; 247 9 1 1 30 s e m i n i t ( c h a r _ l o c k , 1); 248 9 1 1 39 H s h k l n i t ( d v c e _ p o l l ) ; 249 9 1 1 4 3 S t r t l n f o ('Schedule', ' P o l l e r ' , s t a c k , p r i o , t r u e ) : 250 9 1 1 58 s t a r t ( P o l l e r , p i d , s t a c k , p r i o ) ; 251 9 1 1 75 S t r t l n f o ('Schedule', 'DumpTime', s t a c k , p r i o , t r u e ) ; 252 9 1 1 90 s t a r t (DumpTime, p i d , s t a c k , p r i o ) 253 9 1 0 0 End; < of Segment S c h d l n i t } 254 9 1 0 0 255 9 1 0 0 256 2 1 d 1 Procedure P o l l Inputs; 257 2 2 0 0 Beg i n 258 2 2 1 0 s i g n a l (task_done) 259 2 1 0 0 End; 260 2 1 0 0 261 2 1 d 1 Procedure DvceJoin; 262 2 3 0 0 Begin 263 2 3 1 0 AcptUoin ( d v c e _ p o l l ) 264 2 1 0 0 End; 265 2 1 0 0 266 2 1 d 1 Procedure DvceAcpt; 267 2 4 0 0 Beg i n 268 2 4 1 0 AcptHshk (dvce p o l l , synchronous) 269 2 1 0 0 End; 270 2 1 0 0 27 1 2 1 d 1 Procedure DvceOuit; 272 2 5 0 0 Beg i n 273 2 5 1 0 Acp t Q u i t ( d v c e _ p o l l ) 274 2 1 0 0 End; 275 2 1 0 0 Appendix E Compiler L i s t i n g of U n i t Schedule Page 3 276 2 1 :0 0 277 2 1 :d 1 F u n c t i o n Reqst LE t ( r e q u e s t : p t r _ t i c k _ r e q u e s t : 278 2 1 : d 2 t : tim r e c ) : boolean; 279 2 1 :d 1 { t r u e i f request <> n i l and request©.time_to_signa1 <= t } 280 2 10 :0 0 B e g i n 281 2 10 : 1 5 i f request = n i l 282 2 10 : 1 6 then Reqst LE t:= f a l s e 283 2 10 : 1 9 e l s e Reqst LE t:= not Tim aLTb ( t . request©.time_to_s1gna1) 284 2 1 :0 0 End; 285 2 1 :0 0 286 2 1 :0 0 287 2 1 :d 1 Procedure W a i t T i c k ; 288 2 1 :d 1 { A c a l l to t h i s procedure w i l l r e t u r n t i c k s / 6 0 seconds l a t e r } 289 2 6 :d 1 Var new time, wait time: tim_rec; 290 2 6 :d 5 p r i o r r e q u e s t , r e q u e s t : p t r _ t i c k _ r e q u e s t ; 291 2 6 :0 0 Beg i n 292 2 6 : 1 0 i f t i c k s <= 0 293 2 6 : 1 1 then s i g n a l (task_done) 294 2 6 : 1 8 295 2 6 : 1 8 e l s e Begin 296 2 6 : 1 1 1 ( c a l c u l a t e a b s o l u t e time of r e t u r n to c a l l e r } 297 2 6 : 3 1 1 w i t h new time do time (hiword, loword); 298 2 6 :3 15 with wa i t t i me do 299 2 6 :4 15 B e g i n 300 2 6 : 5 15 1oword:= t i cks; 301 2 6 : 5 17 h i word:= 0 302 2 6 :4 17 End; 303 2 6: : 3 19 TimAdd (new time, new_time, w a i t _ t i m e ) ; 304 2 6 : 3 24 305 2 6 : 3 24 { queue the new t i c k request ) 306 2 6 : 3 24 307 2 6 : 3 24 i f f i r s t _ r e q u e s t = n i l 308 2 6 : 3 25 then Begin { the new request i s the o n l y one } 309 2 6 : 5 28 new ( r e q u e s t ) ; 310 2 6; : 5 33 f i r s t _ r e q u e s t : = r e q u e s t ; 31 1 2 6 :5 36 request©.next_request:= n i l 312 2 6 : 4 39 End { of i f n i l f 1 r s t _ r e q u e s t > 313 2 6: : 4 4 1 314 2 6: : 3 4 1 e l se 315 2 6 : 4 43 i f Tim aLTb (new time, first_request®.time_to_signa1) 316 2 6: : 4 46 then Begin { the new request goes at the f r o n t of the queue 317 2 6 : 6 50 new ( r e q u e s t ) ; 3 18 2 6: : 6 55 request©.next^request:= f i r s t _ r e q u e s t ; 319 2 6: :6 60 f i r s t request:= request 320 2 6: :5 60 End ( of i f T1m_aLTb ) 32 1 2 6 :5 63 322 2 6 : 4 63 e l s e Begin 323 2 6 :6 65 request:= f i r s t _ r e q u e s t ; 324 2 6: :6 67 p r i o r request:= r e q u e s t ; 325 2 6 :6 69 w h i l e Reqst LE t ( r e q u e s t , new_time) do Appendix E Compiler L i s t i n g of U n i t Schedule Page 4 326 2 6 : 7 76 Beg i n 327 2 6 : 8 76 p r i o r _ r e q u e s t : = r e q u e s t ; 328 2 6 :8 78 r e q u e s t : 3 request©.next_request 329 2 6 : 7 79 End; { of w h i l e Reqst_LE_t } 330 2 6 : 7 83 331 2 6 :6 83 i f request - n i l 332 2 6 :6 84 then Begin { the new request i s the l a s t one 1n the queue 333 2 6 : 8 87 new ( r e q u e s t ) : 334 2 6 :8 92 p r i o r request®.next_request:= r e q u e s t ; 335 2 6 :8 97 request®.next_request:= n i l 336 2 6 : 7 100 End < of i f n i l request } 337 2 6 : 7 102 338 2 6 : 6 102 e l s e Begin { the new request goes w i t h i n the queue bounds 339 2 6 :8 104 new ( r e q u e s t ) ; 340 2 6 : 8 109 request®.next_request: 3 pr1or_request©.next_request; 34 1 2 6 :8 1 15 p r i o r request©.next_request:= requ e s t 342 2 6 : 7 1 18 End { of e l s e not n i l request > 343 2 6 : 5 120 End; { of e l s e not n i l f i r s t _ r e q u e s t } 344 2 6 : 5 120 345 2 6 : 5 120 ( f l a g the semaphore and time to s i g n a l f o r t h i s r e q u e s t } 346 2 6 : 3 120 with request® do 347 2 6 : 4 122 Beg i n 348 2 6 : 5 122 time t o _ s i g n a l : = new_t1me; 349 2 6 : 5 127 s e m i n i t (sem_to_signa1, 0 ) ; 350 2 6 : 5 137 t i c k _ n e e d e d : 3 t r u e ; 351 2 6 : 5 140 s i g n a l ( t a s k _ d o n e ) ; 352 2 6 : 5 143 { wait u n t i l sem to s i g n a l i s s i g n a l l e d by P o l l e r } 353 2 6 : 5 143 wait (sem_to_signa1) 354 2 6 : 4 147 End; { of with request® > 355 2 6 : 4 147 356 2 6 :4 147 { a wait of t i c k s / 6 0 seconds has now been a c h i e v e d } 357 2 6 : 3 147 d i s p o s e ( r e q u e s t ) 358 2 6 : 3 152 359 2 6 : 2 152 End { of e l s e t i c k s > 0 > 360 2 1 :0 0 End; < of WaitTick ) 361 2 1 : :0 0 362 2 1 : :0 0 363 2 1 : :d 1 F u n c t i o n WaitChar: 364 2 1 : :d 1 ( Wait f o r a c o n s o l e c h a r a c t e r In cha r s } 365 2 7 : 0 0 Beg i n 366 2 7 : 1 0 wait (char l o c k ) ; { queue WaitChar c a l l s ) 367 2 7 : 1 3 match:= c h a r s : 368 2 7 : 1 13 char needed: 3 t r u e ; 369 2 7 : 1 16 s i g n a l ( t a s k _ d o n e ) ; 370 2 7 : 1 19 wa i t (char_ava11); 371 2 7 : 1 22 i f not running then c h : 3 chr ( 0 ) : 372 2 7 : 1 28 WaitChar.: 3 ch; 373 2 7 : 1 32 s i g n a l (char l o c k ) { a l l o w next queued WaitChar c a l l } 374 2 1 : 0 0 End; < of WaitChar ) 375 2 1 : 0 0 Appendix E Compiler L i s t i n g of U n i t Schedule Page 5 37S 2 1 0 0 377 2 1 d 1 378 2 1 d 1 379 2 8 d 1 380 2 8 d 3 381 2 8 d 4 382 2 8 d 4 383 2 1 1 0 0 384 2 1 1 1 0 385 2 1 1 2 2 386 2 1 1 3 2 387 2 1 1 3 6 388 2 1 1 2 6 389 2 8 0 0 390 2 8 0 0 39 1 2 8 0 0 392 2 8 1 2 393 2 8 1 6 394 2 8 1 6 395 2 8 1 9 396 2 8 1 9 397 2 8 2 13 398 2 8 3 13 399 2 8 3 17 400 2 8 3 17 401 2 8 4 21 402 2 8 4 21 403 2 8 5 21 404 2 8 5 32 405 2 8 4 36 406 2 8 4 39 407 2 8 3 39 408 2 8 4 43 409 2 8 4 43 4 10 2 8 5 43 4 1 1 2 8 5 48 412 2 8 6 57 413 2 8 7 57 414 2 8 7 60 4 15 2 8 7 60 4 16 2 8 7 70 4 17 2 8 7 79 418 2 8 7 82 4 19 2 8 8 95 420 2 8 7 104 42 1 2 8 8 1 14 422 2 8 9 1 14 423 2 8 9 1 17 424 2 8 8 120 425 2 8 6 120 Process Pol 1er; { A hi g h p r i o r i t y wait request s e r v i c i n g p r o c e s s > Var now: t i m _ r e c ; num_dhars: i n t e g e r ; Procedure S i g n a 1 _ f i r s t _ r e q u e s t ; Beg i n with f i r s t _ r e q u e s t @ do Beg i n s i g n a l (sem_to_signa1); f i r s t _ r e q u e s t : = n e x t _ r e q u e s t End { of with f i rst_request<5> } End; < of S i g n a 1 _ f 1 r s t _ r e q u e s t > Begin ch:= ' '; ( wait f o r a task to complete > wai t ( t a s k _ d o n e ) ; wh i1e runn i ng do Beg 1 n with now do time (hiword, loword); i f t i c k _ n e e d e d then Begin { s i g n a l a l l t i c k r e q u e s t s that a re ready to go > wh i l e Re'qst_LE_t ( f i r s t _ r e q u e s t , now) do S i g n a 1 _ f 1 r s t _ r e q u e s t ; i f f i r s t _ r e q u e s t = n i l then tick_needed:= f a l s e End; ( o f i f t i c k _ n e e d e d ) i f char_needed then Begin { check c o n s o l e queued c h a r a c t e r s > u n i t s t a t u s (2. num_chars, 1); wh i l e char_needed and (num_chars > 0) do Beg i n num_chars:= num_chars - 1; { see i f the char i s i n the s p e c i f i e d a c c e p t a b l e s e t > read (keyboard, c h ) ; i f e o l n (keyboard) then ch:= chr (13) { c a r r i a g e r e t u r n ) e l s e i f eof (keyboard) then ch:= MapCommandKey ( s c _ e o f _ k e y , f a l s e ) : i f ch i n match then Beg i n char_needed:= f a l s e ; s i g n a l ( c h a r _ a v a i l ) End { of i f ch i n match } End { of w h i l e char needed } ro Appendix E Compiler L i s t i n g of U n i t Schedule Page 6 426 2 8 4 120 End; { o f i f char_needed > 427 2 8 4 122 428 2 8 3 122 with dvce p o l l do 429 2 8 4 125 i f n_sync_acpt + n_async_acpt > 0 then 430 2 8 5 134 SrceHshk ( d v c e _ p o l l , t r u e ) ; 431 2 8 5 139 432 2 8 5 139 { wait f o r a task to complete } 433 2 8 3 139 wait ( t a s k _ d o n e ) ; 434 2 8 3 142 < ensure no e r r o r has been d e t e c t e d } 435 2 8 3 142 i f E r r o r N o t e d then r u n n i n g : 3 f a l s e 436 2 8 2 147 End; { of w h i l e r u n n i n g ) 437 2 8 2 153 438 2 8 2 153 { program e x e c u t i o n f i n i s h e d : s i g n a l a l l w a i t i n g t a s k s 439 2 8 1 153 w h i l e f i r s t r equest <> n i l do S i g n a l f i r s t r e q u e s t ; 440 2 8 1 16 1 s i g n a l ( c h a r _ a v a 1 1 ) : 44 1 2 8 1 164 SrceHshk ( d v c e _ p o l l , t r u e ) 442 2 1 0 0 End; { of P o l l e r } 443 2 1 0 0 444 2 1 0 0 445 2 1 d 1 P r o c e s s DumpTime; 446 2 1 d 1 { a lowest p r i o r i t y p r o c e s s to absorb unneeded cpu time 447 2 9 0 0 Beg i n 448 2 9 1 2 w h i l e r u n n i n g do s i g n a l ( t a s k done); 449 2 9 1 10 s i g n a l (task_done) 450 2 1 0 0 End; ( of DumpTime } 451 2 1 0 0 452 2 t 0 0 453 2 1 0 0 Begin ( I n i t i a l i z a t i o n of U n i t Schedule } 454 2 1 1 0 S c h d l n i t 455 2 0 0 End. End of C o m p i l a t i o n . to to Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 1 3 0 0 :d 1 {$L remout:} 4 2 1 :d 1 U n i t ReadKybd; 5 2 1 : d 1 6 2 1 : d 1 I n t e r f a c e 7 2 1 d 1 { Rou t i n e s f o r r e a d i n g keyboard, a l l o w i n g Schedule to s i g n a l competing 8 g 2 2 1 d d 1 p r o c e s s e s w h i l e w a i t i n g f o r keyboard c h a r a c t e r } 10 2 1 d 1 Type r k _ c h s e t = s e t of char; 1 1 2 1 d 1 r k _ l o n g _ s t r i n g = s t r i n g [ 2 5 5 ] ; 12 2 1 d 1 13 2 1 d 1 Procedure CursBorrow; 14 2 1 d 1 Procedure CursReturn: 15 2 1 d 1 < A p r o c e s s wanting to w r i t e to the s c r e e n must CursBorrow, do the 1S 2 1 d 1 w r i t e without a task s w i t c h , CursReturn > 17 2 1 d 1 18 2 1 d 1 F u n c t i o n ReadCharln (return_on_match: rk c h s e t ) : char; 19 2 1 d 1 F u n c t i o n F e t c h C h a r l n (x.y: i n t e g e r ; return_on_match: r k _ c h s e t ) : char; 20 2 1 d 1 { Return with char when a char in r e t u r n on match has been typed. 21 2 1 d 1 The char i s not echoed to the s c r e e n . } 22 2 1 d 1 23 2 1 d 1 F u n c t i o n ReadCapIn ( r e t u r n on match: rk c h s e t ) : char; 24 2 1 d 1 F u n c t i o n FetchCapIn (x.y: i n t e g e r ; r e t u r n on match: rk c h s e t ) : char; 25 2 1 d 1 F u n c t i o n PromptCapIn (x.y: i n t e g e r : prompt: rk long s t r i n g : 26 2 1 d r e t u r n _ o n match: rk c h s e t ) : c h a r ; 27 2 1 d 1 < Return with char when a char i n r e t u r n on match has been typed. 28 2 1 d 1 A l p h a b e t i c c h a r s a re c o n v e r t e d to upper ca s e . The char i s not 29 2 1 d 1 echoed to the s c r e e n . In t h i r d case, f i r s t send prompt to x.y. 30 2 1 d 1 broken i n t o s e v e r a l p i e c e s by ' ' i f n e c e s s a r y , r o t a t i n g the 3 1 2 1 d 1 p i e c e s when '?' i s typed > 32 2 1 d 1 33 2 1 d 1 F u n c t i o n ReadBoolean: boolean; 34 2 1 d 1 F u n c t i o n FetchBoolean (x,y: i n t e g e r ) : boolean; 35 2 1 d 1 { ReadCapIn ( [ ' T ' . ' F ' ] ) , echo 'true ' or ' f a l s e ' > 36 2 1 d 1 37 2 1 d 1 F u n c t i o n Readlnteger (field,min,max: i n t e g e r ) : i n t e g e r ; 38 2 1 d 1 F u n c t i o n FetchInteger.(x,y,fie1d,min,max: I n t e g e r ) : I n t e g e r ; 39 2 1 d 1 { Return w i t h an i n t e g e r between min and max r i g h t j u s t i f i e d i n 40 2 1 d 1 a f i e l d of g i v e n width } 4 1 2 1 d 1 42 2 1 d 1 F u n c t i o n ReadReal ( f i e 1 d , d e c _ f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; 43 2 1 d 1 F u n c t i o n FetchReal ( x , y , f i e 1 d , d e c f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; 44 2 1 d 1 { Return with a r e a l between min and max r i g h t j u s t i f i e d i n a f i e l d 45 2 1 d 1 of g i v e n width with dec f i e l d f o l l o w i n g the decimal ) 46 2 1 d 1 47 2 1 d 1 F u n c t i o n ReadFloat ( f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; 48 2 1 d 1 F u n c t i o n F e t c h F l o a t ( x . y , f i e l d : i n t e g e r ; min,max: r e a l ) : r e a l ; 49 2 1 d 1 < Return with a r e a l between min and max read as m a n t i s s a and 50 2 1 d 1 exponent > 51 2 1 • d 1 Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 2 52 2 1 d 1 Procedure R e a d S t r i n g (var s: s t r i n g ; f i e l d : i n t e g e r ) ; 53 2 1 d 1 Procedure F e t c h S t r i n g (x,y: i n t e g e r ; var s: s t r i n g ; f i e l d : i n t e g e r ) ; 54 2 1 d 1 { Return with new s t r i n g of l e n g t h <= f i e l d i n v a r i a b l e s > 55 2 1 d 1 56 2 1 d 1 Procedure r k H a l t ; 57 2 1 d 1 { C a l l upon program end to r e t u r n from a l l CursBorrow w a i t s } 58 2 1 d 1 59 2 1 d 1 Implementat ion 60 2 1 d 1 6 1 2 1 d 1 182 2 1 d 1 <$L-) Uses ScreenOps, ExtraScreenOps, ErrMessg, MiscFunc, <$L©> 294 2 1 d 1 <$L-} WritCons. DataBus. Schedule; ($L®> 295 2 1 d 1 296 2 1 d 1 Var BS, CR. DEL. LEFT: char; 297 2 1 d 5 c u r s x, c u r s y: i n t e g e r ; 298 2 1 d 7 c u r s busy: boolean; 299 2 1 d 8 c u r s a v a i l : handshake; 300 2 1 d 20 301 2 1 d 20 302 2 1 d 20 Procedure RubChar (Var s: s t r i n g ) ; forward; 303 2 1 d 1 304 2 1 d 1 Procedure R u b S t r i n g (Var s: s t r i n g ) ; forward; 305 2 1 d 1 306 2 1 d 1 307 2 1 d 1 Segment F u n c t i o n ReadNumber ( f i e l d , d e c _ f i e l d : i n t e g e r ; 308 2 1 d 2 min,max: r e a l ) : r e a l ; 309 2 1 d 1 310 10 1 d 1 Var r e t u r n on match: s c _ c h s e t ; 31 1 10 1 d 17 f r s t d i g . dot_pos, l e n , c t r : 0..21; 312 10 1 d 2 1 r, s i gn: rea1: 313 10 1 d 25 num s t r : s t r i n g [ 2 1 ] : 314 10 1 d 36 one ch: s t r i ng[ 1 ]; 315 10 1 d 37 ch: char; 3 16 10 1 d 38 317 10 1 d 38 Procedure CheckError; 318 10 1 d 1 { Check f o r UBC system e r r o r ) 319 10 2 0 0 Beg i n 320 10 2 1 0 i f E r r o r N o t e d then 32 1 10 2 2 5 Begin ReadNumber:= min; e x i t (ReadNumber) End 322 10 1 0 0 End; 323 10 1 0 0 324 10 1 0 0 Beg i n 325 10 1 1 0 i f min > max then 326 10 1 2 9 B e g i n N o t e E r r o r (110, 0, f a l s e ) : C h e c k E r r o r End; 327 10 1 1 17 one ch:= ' '; 328 10 1 1 25 329 10 1 1 25 Repeat ( Read the num_str as a s t r i n g u n t i l no e r r o r s are d e t e c t e d } 330 10 1 1 25 { Erase work space } 33 1 10 1 2 25 W r i t e E r a s e ( f i e l d ) ; 332 10 1 2 29 Ul Appendix E Compiler L i s t i n g of U n i t ReadKybd { Page 333 10 1 2 29 334 10 1 2 29 335 10 1 2 37 336 10 1 2 64 337 10 1 2 86 338 10 1 2 95 339 10 1 2 97 340 10 1 2 97 34 1 10 1 2 106 342 10 1 2 121 343 10 1 2 129 344 10 1 2 143 345 10 1 2 167 346 10 1 4 171 347 10 1 4 184 348 10 1 6 187 349 10 1 6 194 350 10 1 6 202 351 10 1 7 224 352 10 1 6 240 353 10 1 7 247 354 10 1 5 252 355 10 1 4 263 356 10 1 6 265 357 10 1 6 276 358 10 1 6 283 359 10 1 6 31 1 360 10 1 6 333 361 10 1 5 338 362 10 1 4 349 363 10 1 4 358 364 10 1 3 358 365 10 1 3 363 366 10 1 3 363 367 10 1 2 363 368 10 1 2 372 369 10 1 2 380 370 10 1 2 392 371 10 1 2 4 14 372 10 1 2 428 373 10 1 2 445 374 10 1 3 450 375 10 1 4 450 376 10 1 4 480 377 10 1 3 484 378 10 1 3 489 379 10 1 3 489 380 10 1 2 489 381 10 1 2 495 382 10 1 3 5 17 s t r 1 char at a time to a l l o w m u l t i t a s k i n g > Read the num_ num_str:= ''; return_on_match:= [BS.CR,DEL,LEFT,'-' i f d e c _ f i e l d > 0 then return_on_match: ch:= WaitChar (return_on_match): CheckError; '0' . . '9' ] ; : r e t u r n on match w h i l e not e o l n (keyboard) and ( ( c h i n [BS.DEL,LEFT]) or ((1ength(num_str) < f i e l d ) and ((pos('.',num_str)=0) or (1ength(num_str)-pos('. do Begin i f ch i n [BS,DEL,LEFT] then Begin i f ch - DEL then R u b S t r i n g (num_str) e l s e RubChar (num_str): i f ( d e c _ f i e l d > 0) and (pos ('.',num_ return_on_match:= return_on_match + i f l e n g t h (num_str) = 0 then return_on_match:= return_on_match + End e l s e B e g i n w r i t e (ch) ; one_ch[1]:= ch; num_str:= concat (num_str,one_ch); If ch = '.' then return_on_match return_on_match:= return_on_match End; ch:= WaitChar (return_on_match); CheckError End; -str) < dec f i e l d ) ) ) ) s t r ) [ ' . ' 0) then 1; [ '-' ] r e t u r n _ ['-'] " match - [ Check f o r decimal len:= l e n g t h (num i f 1 en <= 0 then e 1 se i f num s t r [ 1 ] = ' note s i g n ) dot_pos:= pos ( i f dot_pos = 0 Beg i n num_str:= concat dot_pos:= 1ength End; po i n t , s t r ) ; num_str:= '.' W r i t e L e f t ( l e n ) ; '-' then Begin s i g n : : e l s e Begin s i g n : • . ' ,num_str): then -1.0; 1.0; f r s t f r s t " d i g d i g = 2 = 1 End End; (num (num s t r , • s t r ) ); { Convert s t r i n g to r e a l } r:= 0.O; f o r c t r : = f r s t _ d i g r : = r + (ord(num to dot_pos-1 s t r [ c t r ] ) - 4 8 ) do pwrof t e n ( d o t _ p o s - c t r - 1 ) ; Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 4 383 10 1 2 552 f o r c t r : = 1 to 1ength(num_str)-dot_pos do 384 10 1 3 577 r:= r + ( o r d ( n u m _ s t r [ c t r + d o t _ p o s ] ) - 4 8 ) / p w r o f t e n ( c t r ) 385 10 1 2 61 1 r:= r+ s i gn 38G 10 1 2 616 387 10 1 1 616 U n t i l ( r <= max) and ( r >= min); 388 10 1 1 639 389 10 1 1 639 < Send the f o r m a t t e d s t r i n g to the s c r e e n } 390 10 1 1 639 WriteRead ( r , f i e l d , d e c _ f i e l d ) ; 391 10 1 1 648 ReadNumber:= r 392 10 1 0 0 End; { of Segment F u n c t i o n ReadNumber > 393 10 1 0 0 394 10 1 O 0 395 2 1 d 1 Procedure RubChar; 396 2 20 d 1 Var l e n ; i n t e g e r ; 397 2 20 O 0 Beg i n 398 2 20 1 0 1 en:= 1ength ( s) ; 399 2 20 1 4 i f l e n > 0 then 400 2 20 2 9 Beg i n 401 2 20 3 9 WriteBackspaces ( 1 ) ; 402 2 20 3 12 d e l e t e ( s , 1 en, 1) 403 2 20 2 18 End 404 2 1 0 0 End; 405 2 1 0 0 406 2 1 0 0 407 2 1 d 1 Procedure RubString; 408 2 2 1 d 1 Var l e n : i n t e g e r ; 409 2 21 0 0 Beg i n 4 10 2 21 1 0 1 en:= 1ength ( s ) : 4 1 1 2 21 1 4 i f 1 en > 0 then 4 12 2 21 2 9 Begi n 4 13 2 21 3 9 WriteBackspaces ( l e n ) ; 4 14 2 21 3 12 s : = 4 15 2 21 2 13 End 4 16 2 1 0 0 End; 4 17 2 1 0 0 418 2 1 0 0 419 2 1 d 1 F u n c t i o n ReadCharln; 420 2 4 0 0 Beg i n 42 1 2 4 1 0 ReadCharln:= WaitChar ( r e t u r n on match) 422 2 1 0 • 0 End; 423 2 1 0 0 424 2 1 d 1 F u n c t i o n F e t c h C h a r l n ; 425 2 5 0 0 Beg i n 426 2 5 1 0 gotoxy (x, y ) ; FetchCharIn:= WaitChar (return_on_match) 427 2 1 0 0 End: 428 2 1 0 0 429 2 1 0 0 430 2 1 d 1 F u n c t i o n ReadCapIn; 431 2 6 d 1 Var ch: char; 432 2 6 0 0 Beg 1 n Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 5 433 2 6 1 0 Repeat . 434 2 6 2 0 ch: = UpperChar (WaitChar (return_on_match + [ ' a ' . . ' z ' ] ) ) 435 2 6 1 18 U n t i l (ch i n return_on_match) or E r r o r N o t e d : 436 2 6 1 33 ReadCapIn:= ch 437 2 1 0 0 End; 438 2 1 0 0 439 2 1 d 1 F u n c t i o n FetchCapIn; 440 2 7 0 0 Begin 44 1 2 7 1 0 gotoxy (x. y ) : FetchCapIn:= ReadCapIn (return_on_match) 442 2 1 0 0 End: 443 2 1 0 0 444 2 1 d 1 F u n c t i o n PromptCapIn; 445 2 8 d 1 Var ch: char; 446 2 8 d 2 t i t l e , index, room, l e n , xO: i n t e g e r ; 447 2 8 d 7 1 i ne: s t r 1 n g [ 7 9 ] ; 448 2 8 d 47 t a i l : s t r i ng[3]; 449 2 8 d 49 Procedure TaskSwitch; 450 2 22 0 0 Be g i n 45 1 2 22 1 0 Po11 Inputs; 452 2 22 1 3 i f E r r o r N o t e d then e x i t (PromptCapIn) 453 2 8 0 0 End: { of TaskSwitch } 454 2 8 0 0 Begin { +** PromptCapIn *** } 455 2 8 0 0 { r e c o r d c u r s o r p o s i t i o n , e r a s e the l i n e from t h e r e ) 456 2 8 1 7 x0:= x; sc E r a s e T o E o l (xO, y ) ; 457 2 8 1 17 < i n i t i a l i z e prompt t r a i l e r , move c u r s o r to p o s i t i o n } 458 2 8 1 17 t a l l : = ' ? ': t a i 1 [ 3 ] := chr ( 8 ) ; 459 2 8 1 31 PromptCapIn:= chr ( 0 ) ; < i n case of task e r r o r > 460 2 8 1 35 < look f o r l e a d i n g prompt t i t l e - - e . g . 'Commands: ' } 461 2 8 1 35 t i t l e : = pos (' ', prompt) + 1; 462 2 8 1 49 i f t i t l e > 1 then 463 2 8 2 54 Beg i n 464 2 8 2 54 { w r i t e the t i t l e , remove i t from prompt, p o i n t c u r s o r beyond 465 2 8 3 54 u n i t w r i t e (1. prompt!1]. t i t l e ) ; 466 2 8 3 64 d e l e t e (prompt, 1, t i t l e ) ; 467 2 8 3 7 1 x : = x + t i t l e ; 468 2 8 3 79 TaskSwi t c h 469 2 8 2 79 End; 470 2 8 1 81 curs_y:= y: 471 2 8 1 86 i ndex:= 1; 472 2 8 1 88 Repeat ( u n t i l v a l i d ch r e c i e v e d > 473 2 8 1 88 ( e r a s e any e x i s t i n g d i s p l a y on remainder of l i n e y } 474 2 8 2 88 s c E r a s e T o E o l (x. y ) ; 475 2 8 2 96 { f i n d room f o r prompt, remaining l e n g t h of prompt } 476 2 8 2 96 room:= 78 - x; 477 2 8 2 103 len:= l e n g t h (prompt) - ( i n d e x - 1 ) ; 478 2 8 2 1 1 1 i f l e n <= room 479 2 8 2 1 12 then Begin 480 2 8 2 1 16 { remaining l e n g t h f i t s i n room: w r i t e i t . no '?' } 48 1 2 8 4 1 16 i f l e n > 0 then u n i t w r i t e (1, p r o m p t [ i n d e x ] , l e n ) ; 482 2 8 4 131 uni twri te (1, t a i 1 [ 1 ] , 1); Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 6 483 2 8 : 4 14 1 cu r s x:= x + 1 en + 1 : 484 2 8 : 4 149 { c y c l e back to b e g i n n i n g of prompt > 485 2 8 : 4 149 i ndex:= 1 486 2 8 : 3 149 End 487 2 8 : 2 151 e l s e Begin 488 2 8 : 2 153 { remaining l e n g t h does not f i t i n room: f i n d a ' ' break 489 2 8 : 4 153 Repeat 490 2 8 : 5 153 w h i l e prompt[index+room] <> ' ' do room:= room - 1; 49 1 2 8 : 5 169 room:- room - 1 492 2 8 : 4 170 U n t i l prompt[index+room] = ' '; 493 2 8 : 4 183 TaskSwi t c h : 494 2 8 : 4 185 < w r i t e remaining prompt up to break, t r a i l w i t h a '?' } 495 2 8 : 4 185 u n i t w r i t e (1, prompt[index ] , room); 496 2 8 : 4 195 uni twr1te (1. ta i1[ 1 ] . 3); 497 2 8 : 4 205 c u r s x:= x + room + 1; 498 2 8 : 4 2 13 { c y c l e to next p a r t of prompt } 499 2 8 : 4 213 index:= index + room + 2 500 2 8 : 3 216 End; 501 2 8 : 2 219 curs_busy:= f a l s e ; 502 2 8 : 2 222 SrceHshk ( c u r s _ a v a i l , t r u e ) ; 503 2 8 : 2 227 ch:= ReadCapIn (return_on_match + [ ' ? ' ] ) ; 504 2 8 : 2 246 curs_busy:= t r u e 505 2 8 : 1 246 Unt i1 ch <> '?': 506 2 8 : 1 256 { remove prompt ) 507 2 8 : 1 256 s c E r a s e T o E o l (xO, y ) ; 508 2 8 : 1 262 PromptCapIn:= ch 509 2 1 :0 0 End; 510 2 1 :0 0 5 1 1 2 1 :0 0 512 2 1 :d 1 F u n c t i o n ReadBoolean; 513 2 9 :d 1 Var b: boolean; 514 2 9 :0 0 B e g i n 515 2 9 : 1 0 Wr i t e E r a s e ( 5 ) ; 516 2 9 : 1 3 b:= ReadCapIn ( [ ' T ' . ' F ' ] ) = 'T'; 517 2 9 : 1 18 Wr i teBoo1ean ( b ) ; 518 2 9 : 1 21 ReadBoo1ean:= b 519 2 1 :0 0 End; 520 2 1 :0 0 521 2 1 :d 1 F u n c t i o n FetchBoo1ean: 522 2 10 :0 0 Beg i n 523 2 10 : 1 0 gotoxy (x, y ) ; FetchBoo1ean:= ReadBoolean 524 2 1 :0 0 End; 525 2 1 :0 0 526 2 1 :0 0 527 2 1 :d 1 F u n c t i o n Readlnteger; 528 2 1 1 :0 0 Beg i n 529 2 1 1 : 1 0 Readlnteger:= t r u n c (ReadNumber ( f i e l d , 0, min, max)) 530 2 1 :0 0 End; 53 1 2 1 :0 0 532 2 1 : d 1 F u n c t i o n F e t c h l n t e g e r ; Appendix E Compiler L i s t i n g of U n i t ReadKybd Page 7 533 2 12 : 0 0 Begin 534 2 12 : 1 0 gotoxy ( x . y ) ; 535 2 12 : 1 5 F e t c h l n t e g e r : = t r u n c (ReadNumber ( f i e l d . 0. min, max)) 536 2 1 : 0 0 End: 537 2 1 : 0 0 538 2 1 :0 0 539 2 1 :d 1 F u n c t i o n ReadReal; 540 2 13 :0 0 Begin 54 1 2 13 : 1 0 ReadReal:= ReadNumber ( f i e l d , d e c _ f i e l d , min, max) 542 2 1 :0 0 End: 543 2 1 :0 0 544 2 1 :d 1 F u n c t i o n F e t c h R e a l ; 545 2 14 :0 0 Beg i n 546 2 14 : 1 0 gotoxy ( x . y ) ; 547 2 14 : 1 5 FetchReal:= ReadNumber ( f i e l d . d e c _ f i e l d . min, max) 548 2 1 :0 0 End; 549 2 1 :0 0 550 2 1 :0 0 55 i 2 1 :d 1 F u n c t i o n ReadFloat; 552 2 15 :d 1 Const h i _ m a n t i s s a = 9.999999; 553 2 15 :d 1 hi exponent = 37; 554 2 15 :d 1 Var m a n t _ f i e l d , exponent: i n t e g e r ; 555 2 15 :d 3 mant i s s a , r: rea1: 556 2 15 :d 7 Procedure C h e c k E r r o r ; 557 2 15 :d 1 < Check f o r UBC system e r r o r ) 558 2 23 :0 0 B e g i n 559 2 23 : 1 0 i f E r r o r N o t e d then 560 2 23 : 2 5 Begin R e a d F l o a t : 3 min; e x i t ( R e a d F l o a t ) End 561 2 15 :0 0 End; 562 2 15 :0 0 Beg i n 563 2 15 :0 0 { check f o r min > max e r r o r > 564 2 15 : 1 0 i f min > max then 565 2 15 :2 8 Begin N o t e E r r o r (111, 0. f a l s e ) ; C h e c k E r r o r End; 566 2 15 : 1 16 mant f i e l d : = f i e l d - 4; 567 2 15 : 1 20 Repeat 568 2 15 : 2 20 W r i t e B l a n k s ( m a n t _ f i e l d ) ; 569 2 15 : 2 23 w r i t e ('Esxx ' ) ; 570 2 15 :2 37 W r i t e L e f t ( f i e 1 d - m a n t _ f 1 e 1 d ) : 571 2 15 :2 42 Repeat 572 2 15 : 3 42 W r i t e L e f t ( m a n t _ f i e l d ) ; 573 2 15 : 3 45 mant i s s a : = 574 2 15 : 3 46 ReadReal ( m a n t _ f i e l d , m a n t _ f i e l d - 3 , -h1_mant1ssa, 575 2 15 : 3 62 Che c k E r r o r 576 2 15 : 2 62 U n t i l (mantissa = 0.0) or ( a b s ( m a n t i s s a ) >= 1.0); 577 2 15 : 2 80 wr i te ( ' E ' ) ; 578 2 15 : 2 91 exponent: 3 Readlnteger (3, -hi_exponent, hi_exponent) 579 2 15 : 2 101 Ch e c k E r r o r ; 580 2 15 : 2 103 r:= mantissa * Ten_to_the (exponent); 58 1 2 15 : 2 1 14 W r i t e L e f t ( f i e l d ) 582 2 15 : 1 1 15 U n t i l ( r >= min) and ( r <= max): to O J o Appendix fc' Compiler L i s t i n g of U n i t ReadKybd Page 8 583 2 15 : 1 131 W r i t e F l o a t ( r , f i e l d ) : 584 2 15 : 1 136 ReadF1 oat:= r 585 2 1 :0 0 End: 586 2 1 :0 0 587 2 1 :d 1 F u n c t i o n F e t c h F l o a t ; 588 2 16 :0 0 B e g i n 589 2 16 : 1 0 gotoxy (x,y ) ; 590 2 16 : 1 5 F e t c h F l o a t : = ReadFloat ( f i e l d , min, max) 591 2 1 :0 0 End; 592 2 1 :0 0 593 2 1 :0 0 594 2 1 :d 1 Procedure R e a d S t r i n g ; 595 2 17 :d 1 Var ch: char: 596 2 17 :d 2 one ch: s t r i n g [1]: 597 2 17 :d 3 Procedure C h e c k E r r o r ; 598 2 17 :d 1 { Check f o r UBC system e r r o r ) 599 2 24 :0 0 B e g i n 600 2 24 : 1 0 i f E r r o r N o t e d then B e g i n s:= ''; e x i t ( R e a d S t r i n g ) 601 2 17 :0 0 End; 602 2 17 :0 0 Beg i n 603 2 17 : 1 0 W r i t e E r a s e ( f i e l d ) ; 604 2 17 : 1 4 s : = ' ' ; one ch:= ' ': 605 2 17 : 1 19 ch:= WaitChar ([ BS . CR , DEL . LEFT , ' '..'->']): 606 2 17 : 1 48 C h e c k E r r o r ; 607 2 17 : 1 50 w h i l e not e o l n (keyboard) 608 2 17 : 1 59 and ( ( c h i n [BS,DEL,LEFT]) or ( l e n g t h ( s ) < f i e l d ) ) do 609 2 17 : 2 85 Beg i n 610 2 17 : 3 85 i f (ch = BS) or (ch = LEFT) 61 1 2 17 : 3 91 then RubChar (s) 6 12 2 17 : 3 96 e l s e i f ch = DEL 6 13 2 17 : 4 101 then R u b S t r i n g ( s ) 6 14 2 17 : 4 106 e l s e i f ch >- ' ' then 615 2 17 :6 1 16 Beg i n 6 16 2 17 :7 1 16 w r i t e (ch) ; 6 17 2 17 : 7 126 one_ch[1]:= ch; 6 18 2 17 : 7 131 s:= concat ( s , one_ch) 6 19 2 17 :6 153 End; 620 2 17 : 3 156 ch:= WaitChar ([ BS , CR , DEL . LEFT , ' '..'->']): 62 1 2 17 : 3 185 C h e c k E r r o r 622 2 17 : 2 185 End 623 2 1 :0 0 End; 624 2 1 :0 0 625 2 1 :d 1 Procedure F e t c h S t r 1 n g ; 626 2 18 :0 0 Beg i n 627 2 18 : 1 0 gotoxy ( x . y ) ; R e a d S t r i n g ( s , f i e l d ) 628 2 1 :0 0 End: 629 2 1 :0 0 630 2 1 :0 0 631 2 1 : d 1 Procedure CursBorrow; 632 2 2 :0 0 Beg i n Appendix E Compiler L i s t i n g of Un i t ReadKybd 633 2 2 : 1 0 w h i l e c u r s busy and ru n n i n g do AcptHshk ( c u r s 634 2 1 :0 0 End: 635 2 1 :0 0 636 2 1 :d 1 Procedure CursReturn; 637 2 3 :0 0 Beg i n 638 2 3 : 1 0 gotoxy ( c u r s x, c u r s _ y ) 639 2 1 :0 0 End; 640 2 1 :0 0 64 1 2 1 :0 0 642 2 1 :d 1 Procedure r k H a l t ; 643 2 19 :0 0 Beg i n 644 2 19 : 1 0 SrceHshk ( c u r s a v a i l , t r u e ) 645 2 . 1 :0 0 End: 646 2 1 :0 0 647 2 1 :0 0 648 2 1 :0 0 Beg i n 649 2 1 : 1 0 BS : = MapCommandKey (sc_backspace_key, t r u e ) ; 650 2 1 : 1 7 CR:= chr (13); 651 2 1 : 1 10 DEL:= MapCommandKey ( s c _ d e l _ k e y , t r u e ) ; 652 2 1 : 1 17 LEFT:= MapCommandKey ( s c l e f t _ k e y . t r u e ) ; 653 2 1 : 1 24 curs_busy:= t r u e ; 654 2 1 : 1 27 H s h k l n i t ( c u r s a v a i l ) 655 2 :0 0 End. End of C o m p i l a t i o n . Page 9 f a l s e ) NJ NJ Appendix E Compiler L i s t i n g of U n i t S c r n B u f f Page 1 3 O 0 d 4 2 1 d 5 2 1 d 6 2 1 d 7 2 1 d 8 2 1 d 9 2 1 d 10 2 1 d 1 1 2 1 d 12 2 1 d 13 2 1 d 14 2 1 d 15 2 1 d 16 2 1 d 17 2 1 d 18 2 1 d 19 2 1 d 20 2 1 d 21 2 1 d 22 2 1 d 23 2 1 d 24 2 1 d 25 2 1 d 26 2 1 d 27 2 1 d 28 2 1 d 29 2 1 d 30 2 1 d 31 2 1 d 32 2 1 d 33 2 1 d 34 2 1 d 35 2 1 d 36 2 1 d 37 2 1 d 38 2 1 d 39 2 1 d 40 2 1 d 41 {commented 42 2 1 d 43 2 1 d 44 2 1 d 45 2 1 d 46 2 1 d 47 2 1 d 48 2 1 d 49 2 1 d 50 2 1 d 5 1 2 1 d {$L remout:} U n i t S c r n B u f f ; I n t e r f a c e { p r o c e s s data d i s p l a y and s c r e e n image 1 i f o s t a c k i n g r o u t i n e s > Type sb_name = s t r i n g [ 8 ] ; sb_prmt_no - 0..255; sb_prmt = s t r i n g [ 2 5 5 ] ; sb_prmt_ptr = ®sb_prmt; sb_format = packed r e c o r d s c r n _ v a l i d : boolean; enabled: boolean; new_data: boolean; x: 0..79; y: 0..23; f i e l d : 0..80: dec_f i e l d : 0. .79; f1 oat: boolean end; s b _ k i n d = ( s b _ b o o l , sb_1nt s b _ d s p l _ p t r = ®sb_dspl: sb_dspl = r e c o r d n e x t _ d s p l : sb_dspl format: sb_format: case k i n d : sb k i n d of sb_boo1 sb_1nt: s b _ r e : s b _ s t n g end; { s c r e e n image d i s p l a y e d ? } { data d i s p l a y enabled? } { d i s p l a y e d v a l u e out of date? } { c o l of s t a r t of d a t a f i e l d } { row of d a t a f i e l d } { s i z e of " " } { f o r s b _ r e : ft decimal p l a c e s } { " ": s c i e n t i f i c n o t a t i o n } s b _ r e , s b _ s t n g , sb_now); p t r ; (b: boolean) ; ( i : 1nteger); ( r : r e a 1 ) ; ( s: s t r i ng) { 1nterna1 1 i nkup ) ( d i s p l a y i n f o r m a t i o n } < data type, v a l u e } F u n c t i o n sbLink (image: sb_name: fmt: sb_format; k: sb_k1nd): s b _ d s p l _ p t r ; { C r e a t e the named k i n d of data, i n i t i a l i z e format ( t y p e s b _ s t n g w i l l have maximum s l e n g t h of f m t . f i e l d ) , l i n k i n t o Image's d i s p l a y l i s t } { sbToss procedures: i f v a l u e <> data_ptr.va1ue then copy v a l u e . Toss as soon as s c r e e n image i s v a l i d ; , s t r i n g uses v a r i a b l e v a l u e to reduce needed stack s i z e ; now uses c l o c k r e a d i n g - TO at t o s s time } Procedure sbTossBoolean ( v a l u e : boolean; d a t a _ p t r : s b _ d s p l _ p t r ) : Procedure s b T o s s I n t e g e r ( v a l u e : i n t e g e r ; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbTossReal ( v a l u e : r e a l ; d a t a _ p t r : s b _ d s p 1 _ p t r ) ; Procedure S b T o s s S t r i n g (var v a l u e : s t r i n g ; d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure sbTossNow ( d a t a _ p t r : s b _ d s p l _ p t r ) ; Procedure s b D i s a b l e ( d a t a _ p t r : s b _ d s p l _ p t r ) ; ( d i s a b l e d i s p l a y (sbToss r e - e n a b l e s ) } Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 2 52 2 1 d 1 Procedure S c r n E n t e r (name: sb name): 53 2 1 d 1 ( S c r n C l e a r , a c t i v a t e named s c r e e n image (or blank s c r e e n 1f name 54 2 1 d 1 1s 'NIL'), S c r n R e f r e s h i t } 55 2 1 d 1 56 2 1 d 1 F u n c t i o n ScrnPrompt (prompt_num: sb_prmt_no): sb_prmt_ptr; 57 2 1 d 1 { P o i n t to g i v e n prompt ( >= 0 ) of a c t i v e s c r e e n image } 58 2 1 d 1 59 2 1 d 1 Procedure S c r n C l e a r ; 60 2 1 d 1 { s c C l r S c r e e n (and note a c t i v e s c r e e n not v a l i d ) ) 61 2 1 d 1 62 2 1 d 1 Procedure S c r n R e f r e s h ; 63 2 1 d 1 { W r i t e a c t i v e s c r e e n image l i n e s 1..23 ( c l e a r s c r e e n i f none) } 64 2 1 d 1 65 2 1 d 1 Procedure ScrnReturn; 66 2 1 d 1 { S c r n C l e a r , r e - a c t i v a t e whatever image was a c t i v e b e f o r e l a s t 67 2 1 d 1 S c r n E n t e r , S c r n R e f r e s h i t } 68 2 1 d 1 69 2 1 d 1 Procedure s b H a l t ; 70 2 1 d 1 { c a l l to h a l t data d i s p l a y p r o c e s s i n g } 7 1 2 1 d 1 72 2 1 d 1 Implementation 73 ' 2 1 d 1 74 2 1 d 1 27 1 2 1 d 1 {$L-} Uses ScreenOps. ErrMessg, C l o c k , WritCons, DataBus, ($L@) 385 2 1 d 1 {$L-> Schedule, ReadKybd, MiscFunc, ($L©) 396 2 1 d 1 ($L-> {$U u t i 1 : s t a r t e r . c o d e ) S t a r t e r ; {$L®} 397 2 1 d 1 398 2 1 d 1 Const f i l e n a m e = 'UTIL:SYSTEM.SCRN'; 399 2 1 d 1 dspl empty s i z e = 4; 400 2 1 d 1 401 2 1 d 1 Type s c r n i n f o = packed r e c o r d 402 2 1 d 1 i m a g e b l k s : 0..255; { M of b l k s of image } 403 2 1 d 1 prmts b l k : 0..255; { prompts b l o c k # } 404 2 1 d 1 image b y t e s : i n t e g e r ; { l e n g t h of image } 405 2 1 d 1 num prmts: 0..255; ( number of prompts ) 406 2 1 d 1 prmt_words: 0..255 { l e n g t h of prompts ) 407 2 1 d 1 end; 408 2 1 d 1 o n e _ d i r e c = r e c o r d 409 2 1 d 1 name: sb name; { s c r e e n image i d e n t i f i e r } 4 10 2 1 d 1 i n f o : s c r n i n f o ; { " " i n f o r m a t i o n } 4 1 1 2 1 d 1 end; 4 12 2 1 d 1 d i r e c _ t y p e = a r r a y [0..31] of one_d1rec; 413 2 1 d 1 prmt type = packed a r r a y [ 0 . 5 1 1 ] of 0..255; 4 14 2 1 d 1 r f r s h _ p t r = ©rfrsh; 4 15 2 1 d 1 r f r s h = r e c o r d 416 2 1 d 1 next r f r s h : r f r s h _ p t r ; { l i n k up } 4 17 2 1 d 1 name: sb_name; { r e l a v e n t s c r e e n Image } 4 18 2 1 d 1 d s p l _ l i s t : s b _ d s p l _ p t r { l i s t of d i s p l a y i n f o r m a t i o n 4 19 2 1 d 1 end; 420 2 1 d 1 stack l i n k = r e c o r d Appendix E Compiler L i s t i n g of Un i t ScrnBuff Page 3 42 1 2 1 :d 1 former: ©stack 11nk; { 422 2 1 :d 1 case Info to w r i t e : boolean of ( 423 2 1 :d 1 t r u e : ( i n f o : s c r n 1nfo; { 424 2 1 :d 1 r f r s h _ l i n k : r f r s h _ p t r ) ( 425 2 1 .d 1 end; 426 2 1 :d 1 427 2 1 d 1 428 2 1 d 1 Var s c r e e n f i l e : f i l e ; 429 2 1 d 4 1 b l o c k : ©direc_type; 430 2 1 d 42 image_words: i n t e g e r ; 43.1 2 1 d 43 t o s : ©stack 1i nk; 432 2 1 d 44 prompts: ©prmt_type; 433 2 1 d 45 p r m t p t r : sb_prmt_ptr; 434 2 1 d 46 r f r s h l i s t : r f r s h p t r ; 435 2 1 d 47 t o s s _ d a t a : handshake: 436 2 1 d 59 io name: sb name; 437 2 • 1 d 64 s e a r c h _ p t r : r f r s h _ p t r ; 438 2 1 d 65 11nk_data_ptr: s b _ d s p l _ p t r ; 439 2 1 d 66 l i n k fmt: sb format; 440 2 1 d 68 1 i nk k: sb k i nd; 44 1 2 1 d 69 442 2 1 d 69 443 2 1 d 69 F u n c t i o n T o s l n f o : boolean; forward; 444 2 1 d 1 445 2 1 d 1 446 2 1 d 1 447 2 1 d 1 Segment Procedure ScrnIO ( j i n t e g e r ) ; 448 2 1 d 1 449 2 1 d 1 450 12 1 d 1 Procedure NewBlock; 45 1 12 2 0 0 Beg i n 452 12 2 1 0 i f b l o c k = n i l then new ( b l o c k ) 453 12 1 0 0 End; 454 12 1 0 0 455 12 1 0 0 456 12 1 d 1 Procedure DspzPrmts; 457 12 1 d 1 { d i s p o s e of prompts } 458 12 3 0 0 Beg i n 459 12 3 1 0 i f prompts <> n i l then 460 12 3 2 5 v a r d i s p o s e (prompts, tos©.1nfo.prmt words) 46 1 12 1 0 0 End; 462 12 1 0 0 463 12 1 0 0 464 12 1 d 1 Procedure Search; 465 12 1 d 1 { p o i n t to named r f r s h l i s t e n t r y (or n i l i f not found) 466 12 4 0 0 Begin 467 12 4 1 0 s e a r c h ptr:= r f r s h l i s t ; 468 12 4 1 4 i f s e a r c h p t r <> n i l then 469 12 4 2 9 w h i l e ( s e a r c h ptr©.name <> 1o_name) 470 12 4 2 19 and ( s e a r c h ptr©.next r f r s h <> n i l ) do 11nk up > sc r e e n • n o t n i l } s c r e e n i n f o } r e f r e s h " p t r } to O J Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 4 47 1 12 4 : 3 27 search_ptr:= s e a r c h ptr®.next r f r s h ; 472 12 4 : 1 34 1f s e a r c h p t r <> n i l then 473 12 4 : 2 39 i f search_ptr®.name <> io name then 474 12 4 : 3 50 s e a r c h ptr:= n i l 475 12 1 :0 0 End; 476 12 1 :0 0 477 12 1 :0 0 478 12 1 :d 1 Procedure FlagData ( v a l i d : b o o l e a n ) ; 479 12 5 :d 1 Var d a t a p t r : sb d s p l p t r ; 480 1 2 5 :0 O Beg i n 481 12 5 : 1 0 w i t h tos® do 482 12 5 : 2 3 Begin 483 12 5 : 3 3 i f ( r f r s h _ l i n k <> n i l ) and ru n n i n g then w i t h r f r s h link® 484 12 5 : 5 16 1f d s p l _ l i s t <> n i l then 485 12 5 :6 21 Begin 486 12 5 : 7 2 1 d ata_ptr:= d s p l _ l i s t ; 487 12 5 : 7 24 Repeat 488 12 5 :8 24 wi t h data_ptr®, format do 489 12 5 :9 30 Beg i n 490 12 5 :0 30 s c r n va1i d:= va1i d; 491 12 5 :0 35 i f e nabled then new_data:= t r u e ; 492 12 5 :0 46 data ptr:= next d s p l 493 12 5 :9 46 End 494 12 5 : 7 • 49 U n t i l data p t r = n i l ; 495 12 5 : 7 53 i f va11d then 496 12 5 :8 . 56 Beg i n 497 12 5: : 9 56 SrceHshk ( t o s s _ d a t a , t r u e ) ; 498 12 5: :9 61 . . < pol1 inputs f o r c o n t r o l p r o c e s s e s ) 499 12 5: :9 61 Pol 1 Inputs 500 12 5: : 8 6 1 End 501 12 5: :6 63 End { of i f ds p l l i s t <> n i l } 502 12 5 : 2 63 End { of with tos® } 503 12 1 : 0 0 End; { of FlagData > 504 12 1 : 0 0 505 12 1 : 0 0 506 12 1 : d 1 Procedure W r i t e S c r e e n ; 507 12 6 : d 1 Var i , n: i n teger; 508 12 6 : 0 0 Beg i n 509 12 6: 1 0 NewB1ock; 510 12 6: 1 2 wi t h tos®.info do , 51 1 12 6 : 2 7 f o r n:= 1 to image b l k s do 512 12 6 : 3 19 i f r u n n i n g then 513 12 6 : 4 24 Begin 514 12 6 : 4 24 { attempt to read the s c r e e n Image b u f f e r } 515 12 6 : 4 24 <$I-} 5 16 12 6 : 5 24 i f b l o c k r e a d ( s c r e e n f i l e , block®, 1. prmts_blk+n) <> 517 12 6: 6 44 N o t e E r r o r (126, i o r e s u l t . f a l s e ) ; 5 18 12 6 : 6 52 <$I + > 519 12 ' 6 : 5 52 Pol 1 Inputs; 520 12 6 : 5 54 ( copy the image to t h e ' s c r e e n } Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 5 521 12 6 • 5 54 i f n = image_blks then i : = image b y t e s mod 512 522 12 6 • 5 63 e l s e i : = 512; 523 12 6 :5 78 i f r u nning then u n i t w r i t e (1. block®. 1): 524 12 6 5 92 Pol 1 Inputs 525 12 6 4 92 End; { o f i f } 526 12 6 4 99 { b u f f e r i s no longer needed > 527 12 6 1 99 d i spose (b1ock); 528 12 6 1 107 { f l a g d i s p l a y data } 529 12 6 1 107 F l a g D a t a ( t r u e ) 530 12 1 0 0 End; { of W r i t e S c r e e n } 531 12 1 0 0 532 12 1 0 0 533 12 1 d 1 Procedure LoadScreen: 534 12 1 d 1 { read the prompts, w r i t e the image > 535 12 1 d 1 536 12 7 d 1 Procedure C h e c k E r r o r (bomb: boolean; e r r num: i n t e g e r ) ; 537 12 7 d 1 { note e r r o r on bomb, p o l l i n p uts } 538 12 8 0 0 Beg i n 539 12 8 1 0 i f bomb then N o t e E r r o r (err_num, i o r e s u l t , f a l s e ) ; 540 12 8 1 10 Pol 1 Inputs; 54 1 12 8 1 12 i f E r r o r N o t e d then e x i t (LoadScreen) 542 12 7 0 0 End; { of Ch e c k E r r o r ) 543 12 7 0 0 544 12 7 0 0 Begin { *** LoadScreen **+ ) 545 12 7 1 0 NewBlock; 546 12 7 1 2 wi t h tos®.info do 547 12 7 2 7 Beg i n 548 12 7 2 7 { read the prompts i n t o b l o c k b u f f e r ) 549 12 7 2 7 <$I-> 550 12 7 3 7 Ch e c k E r r o r ( b l o c k r e a d ( s c r e e n f i l e , block®, 551 12 7 3 13 1, prmts b l k ) <> 1, 122) ; 552 12 7 3 28 <$I + > 553 12 7 3 28 { move to prompts b u f f e r } 554 12 7 3 28 i f prmt_words > 0 then 555 12 7 4 38 Begi n 556 12 7 5 38 C h e c k E r r o r (varnew (prompts, prmt words) <> prmt words 557 12 7 5 61 moveleft (block®, prompts®, prmt words + prmt words) 558 12 7 4 82 End; 559 12 7 4 82 { c a l c u l a t e s c r e e n b u f f e r s i z e } 560 12 7 3 82 image_words:= 1mage_blks*256 56 1 12 7 2 86 End: < of with tos® ) 562 12 7 2 92 { copy the loaded image to the s c r e e n } 563 12 7 1 92 Wr1teScreen 564 12 1 0 0 End; { of LoadScreen ) 565 12 1 0 0 566 12 1 0 0 567 12 1 d 1 Procedure C l e a r S c r e e n ; 568 12 9 0 0 Beg i n 569 12 9 1 0 i f T o s l n f o then FlagData ( f a l s e ) ; 570 12 9 1 8 scC 1 r S c r e e n Appendix E Compiler L i s t i n g of U n i t S c r n B u f f Page 6 571 12 1 :0 0 End; 572 12 1 :0 0 573 . 12 1 :0 0 574 12 1 :d 1 Procedure E n t e r S c r e e n ; 575 12 10 :d 1 Var new_tos: ®stack_link; 57G 12 10 :d 2 new i n f o : boolean; 577 12 10 :d 3 578 12 10 :d 3 Procedure C h e c k E r r o r (bomb: boolean; err_num: i n t e g e r ) ; 579 12 10 :d 1 { note e r r o r on bomb, p o l l i n p uts ) 580 12 1 1 :0 0 Beg i n 581 12 1 1 : 1 0 i f bomb then N o t e E r r o r ( e r r num, i o r e s u l t , f a l s e ) ; 582 12 1 1 : 1 10 Pol 1 Inputs; 583 12 1 1 : 1 12 i f E r r o r N o t e d then e x i t ( S c r n E n t e r ) 584 12 10 :0 0 End; { of CheckError } 585 12 10 :0 0 586 12 10 :d 1 Procedure G e t l n f o ; 587 12 10 :d 1 { look f o r i n f o c o r r e s p o n d i n g to name i n d i r e c t o r y } 588 12 12 :d 1 Var c u r r d i r e c : i n t e g e r ; 589 12 12 :d 2 found: boolean; 590 12 12 :0 0 Beg i n 591 12 12 : 1 0 NewB1ock; 592 12 12 : 1 2 ($1-) 593 12 12 : 1 2 Che c k E r r o r ( b l o c k r e a d ( s c r e e n f i l e , block®, 1, 0) <> 594 12 12 : 1 20 ($1 + ) 595 12 12: 1 20 < attempt to p o i n t to the re q u e s t e d s c r e e n image ) 596 12 12 : 1 20 c u r r _ d i rec:= - 1; 597 12 12 : 1 23 Repeat 598 12 12 : 2 23 c u r r _ d i r e c : = c u r r d i r e c + 1: 599 12 12 : 2 26 found:= b1ock®[curr_direc].name = i o name 600 12 12 : 1 34 U n t i l found or ( c u r r d i r e c >= 31); 601 12 12 : 1 47 ( ensure d i r e c t o r y e n t r y was found } 602 12 12 : 1 47 C h e c k E r r o r (not found, 121); 603 12 12 : 1 53 { copy d i r e c t o r y e n t r y to new tos®.info } 604 12 12 : 1 53 tos®.info:= block®[curr d i r e c ] . i n f o 605 12 10: 0 0 End; { of G e t l n f o > 606 12 10: 0 0 607 12 10: 0 0 Begin { *** E n t e r S c r e e n *** > 608 12 10: 0 0 ( get r i d of any o l d prompts > 609 12 10: 1 0 DspzPrmts; 610 12 10: 1 2 ( c o n v e r t name to upper case > 61 1 12 10: 1 2 Uppercase ( i o name): 6 12 12 10: 1 7 ( c l e a r c u r r e n t Image, r e s e t v a l i d } 613 12 10: 1 7 C l e a r S c r e e n ; 614 12 10: 1 9 { push c u r r e n t l y a c t i v e image > 615 12 10: 1 9 new_info:= io name <> 'NIL'; 616 12 10: 1 19 i f new i n f o 617 12 10: 1 19 then new (new tos , t r u e ) 618 12 10: 1 27 e l s e new (new t o s . f a l s e ) ; 619 12 10: 1 34 w i t h new tos® do 620 12 10: 2 36 Beg i n U) Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 7 621 12 10 : 3 36 former: = t o s : 622 12 10 : 3 40 tos:= new_tos; 623 12 10 : 3 43 1nfo_to_wr1te:= new_info; 624 12 10 : 3 48 i f new i n f o then 625 12 10 : 4 51 B e g i n 626 12 10 :4 51 { r e a d the new tos s c r e e n ' s i n f o } 627 12 10 : 5 51 G e t l n f o : 628 12 10 :5 53 { p o i n t to a c t i v e r f r s h 11st e n t r y } 629 12 10 : 5 53 Search; 630 12 10 : 5 55 r f r s h l i n k : = s e a r c h p t r ; 631 12 10 : 5 61 { read prompts, w r i t e image } 632 12 10 : 5 61 LoadScreen 633 12 10 :4 61 End { of i f new_info } 634 12 10 : 2 63 End; { of with new tos® > 635 12 1 :0 0 End; { of E n t e r S c r e e n > 636 12 1 :0 0 637 12 1 :0 0 638 12 1 :d 1 Procedure PromptScreen; 639 12 13 :d 1 Var i . o f f s e t , dumbptr: i n t e g e r ; 640 12 13: :d 4 64 1 12 13: :d 4 Procedure E r r o r ; 642 12 14 : 0 0 Beg i n 643 12 14 : 1 O N o t e E r r o r (124, j , f a l s e ) 644 12 13 : 0 0 End; 645 12 13 : 0 0 646 12 13 : 0 0 B e g i n { *** PromptScreen *** } 647 12 13 : 0 0 { lo a d the p o i n t e r to the r e q u e s t e d prompt l i n e } 648 12 13 : 1 0 prmtptr:= n11; 649 12 13: 1 3 i f not T o s l n f o 650 12 13: 1 3 then E r r o r 65 1 12 13: 1 8 e l s e i f j >= tos®.info.num_prmts 652 12 13: 2 20 then E r r o r 653 12 13: 2 24 e l s e B e g i n 654 12 13 : 4 28 o f f s e t : = 0; 655 12 13 : 4 30 { c a l c u l a t e o f f s e t : = p o s i t i o n of r e q u e s t e d s t r i n g 656 12 13 : 4 30 f o r i:= 1 to j do 657 12 13: 5 40 o f f s e t : = o f f s e t + prompts®[offset] + 1; 658 12 13: 5 58 { add o f f s e t to prompts, p l a c e r e s u l t i n p r m t p t r } 659 12 13: 4 58 moveleft (prompts, dumbptr, 2); 660 12 13 : 4 66 dumbptr:= u s i A d d (dumbptr, o f f s e t ) ; 661 12 13 : 4 73 moveleft (dumbptr, prmtptr, 2) 662 12 13: 3 81 End 663 12 1 : 0 0 End; { of PromptScreen } 664 12 1 : 0 0 665 12 1 : 0 0 666 12 1 : d 1 Procedure R e f r e s h S c r e e n ; 667 12 15 : 0 0 B e g i n 668 12 15 : 1 0 C l e a r S c r e e n ; 669 12 15 : 1 2 i f T o s l n f o then W r i t e S c r e e n 670 12 1 : 0 0 End: { of S c r n R e f r e s h } i n prompts ) to co Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 8 G7 1 12 1 0 0 G72 12 1 0 0 G73 12 1 d 1 Procedure ReturnScreen: 674 12 16 d 1 Var o l d tos:®stack_link; 675 12 16 0 0 B e g i n 676 12 16 0 0 { get r i d of any o l d prompts } 677 12 16 1 0 DspzPrmts: 678 12 16 1 2 < c l e a r c u r r e n t image, r e s e t v a l i d > 679 12 16 1 2 C1earScreen; 680 12 16 1 4 i f tos = n 1 1 681 12 16 1 6 then N o t e E r r o r (128, 0. f a l s e ) 682 12 16 1 13 e l s e Begin 683 12 16 1 17 { pop s c r e e n , d i s p o s e of o l d top of s t a c k } 684 12 16 3 17 o l d t o s : = tos; 685 12 16 3 20 with o l d tos® do 686 12 16 4 22 Beg i n 687 12 16 5 22 tos:= former; 688 12 16 5 26 i f i n f o to w r i t e 689 12 16 5 26 then d i s p o s e ( o l d t o s , t r u e ) 690 12 16 5 35 e l s e d i s p o s e ( o l d _ t o s , f a l s e ) 69 1 12 16 4 42 End; 692 12 16 3 42 i f T o s l n f o then LoadScreen 693 12 16 2 47 End { of e l s e o l d tos <> n i l } 694 12 1 0 0 End: { of ReturnScreen ) 695 12 1 0 0 696 12 1 0 0 697 12 1 0 0 B e g i n { *** ScrnIO *** > 698 12 1 1 0 i f j <= 255 699 12 1 1 1 then PromptScreen 700 12 1 1 6 e l s e Case j of 701 12 1 2 13 256 DspzPrmts; 702 12 1 2 17 257 Search; 703 12 1 2 2 1 258 E n t e r S c r e e n ; 704 12 1 2 25 259 C1earScreen; 705 12 1 2 29 260 R e f r e s h S c r e e n ; 706 12 1 2 33 261 ReturnScreen 707 12 1 2 33 End 708 12 1 0 O End; < of Segment ScrnIO } 70"9 12 1 0 0 7 10 12 1 0 0 7 1 1 12 1 0 0 7 12 2 1 d 1 P r o c e s s Update; forward; 713 2 1 d 1 714 2 1 d 1 7 15 2 1 d 1 7 16 2 1 d 1 Segment Procedure S c r n l n i t ( i n i t i a l i z e : b oolean) 717 2 1 d 1 718 2 1 d 1 7 19 16 1 d 1 Procedure I n i t ; 720 16 2 d 1 Var p i d : p r o c e s s i d ; Appendix E Compiler L i s t i n g of Un i t ScrnBuff Page 9 72 1 16 2 :d 2 st a c k , p r i o : i n t e g e r : 722 16 2 :0 0 Begin 723 16 2 : 1 0 b l o c k : 3 n i l ; prompts: 3 n i l ; tos:= n i l ; r f r s h _ 1 1 s t : = n i l ; 724 16 2 : 1 12 H s h k l n i t ( t o s s _ d a t a ) : 725 16 2 : 1 16 S t r t l n f o ( ' S c r n B u f f , 'Update', s t a c k , p r i o , t r u e ) : 726 16 2 : 1 32 s t a r t (Update, p i d , s t a c k , p r i o ) ; 727 16 2 : 1 49 { open s c r e e n _ f i l e ) 728 16 2 : 1 49 ($1-) r e s e t ( s c r e e n _ f i 1 e , f i l e n a m e ) ; ($I+> 729 16 2 : 1 61 i f l o r e s u l t <> 0 then N o t e E r r o r (127, i o r e s u l t . t r u e ) 730 16 1 :0 0 End; { of I n i t > 731 16 1 :0 0 732 16 1 :0 0 733 16 1 :d 1 Procedure Link; 734 16 1 : d 1 { C r e a t e g i v e n k i n d of data, l i n k i n t o g i v e n image's d i s p l a y l i s t 735 16 3 :d 1 Var s i z e : i n t e g e r ; 736 16 3 :0 0 Beg i n 737 16 3 :0 0 ( look f o r a l r e a d y c r e a t e d (?) image r e f r e s h ) 738 16 3 : 1 0 Uppercase (1o_name); 739 16 3 : 1 5 ScrnIO (257); { s e a r c h f o r name i n r e f r e s h l i s t > 740 16 3 : 1 1 1 i f s e a r c h _ p t r - n i l then 741 16 3 : 2 16 Beg i n 742 16 3 : 2 16 { s t a r t a new image r e f r e s h l i s t > 743 16 3 : 3 16 new ( s e a r c h _ p t r ) ; 744 16 3: : 3 22 w i t h . s e a r c h ptr® do 745 16 3 : 4 25 Beg i n 746 16 3 : 5 25 next r f r s h : - r f r s h l i s t ; 747 16 3: :5 29 r f r s h _ l i s t : = s e a r c h _ p t r ; 748 16 3 : 5 33 name:= i o name; 749 16 3 : 5 41 dsp1 11st:= n i l 750 16 3 : 4 44 End { of with search_ptr® } 751 16 3 : 2 46 End; ( of i f se a r c h p t r <> n i l ) 752 16 3 : 2 46 { c r e a t e new l i n k data p t r . i n i t i a l i z e , l i n k Into p o i n t e d to l i s t } 753 16 3 :  1 46 Case 1i n k k of 754 16 3: : 1 50 sb b o o l : new ( 1 i n k _ d a t a _ p t r , s b _ b o o l ) ; 755 16 3: 1 58 sb i n t : new ( 1 i n k _ d a t a _ p t r , s b _ 1 n t ) : 756 16 3: 1 66 s b _ r e : new (11nk_data_ptr, s b _ r e ) ; 757 16 3: 1 74 sb s t n g : Begin 758 16 3: 3 74 s i z e : = dspl_empty_s1ze + (11nk_fmt.f1e1d+2) d l v 2; 759 16 3: 3 88 i f varnew (11nk_data_ptr, s i z e ) <> s i z e then 760 16 3 : 4 98 N o t e E r r o r (129, s i z e , f a l s e ) 761 16 3 : 2 102 End; 762 16 3 : 1 106 sb now: new (I1nk_data p t r , sb_now) 763 16 3 : 1 1 12 End: < of Case 11nk_k } 764 16 3 : 1 1 17 with s e a r c h ptr®, l i n k data ptr®. format do 765 16 3 : 2 127 Beg 1 n 766 16 3 : 3 127 next_dspl:= d s p l _ l i s t ; 767 16 3 : 3 131 dsp l l i s t : - l i n k d a t a p t r ; 768 16 3 : 3 137 format:= 1i nk fmt; 769 16 3 : 3 145 1f n e x t _ d s p l = n i l 770 16 3 : 3 147 then, s c r n v a l i d : 3 f a l s e Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 10 77 1 16 3 3 153 e l s e s c r n v a l i d : = next_dsp1 ©.format.scrn_va1id; 772 16 3 3 168 enabled:= f a l s e ; 773 16 3 3 173 new data:= f a l s e ; 774 16 3 3 178 k i nd:= 11nk_k 775 16 3 2 181 End { of with l i n k data ptr© > 776 16 1 0 0 End; { of Link } 777 16 1 0 0 778 16 1 0 0 779 16 1 0 0 Begin { +** S c r n l n i t *** } 780 16 1 1 0 i f i n i t i a l i z e 781 16 1 1 0 then I n i t 782 16 1 1 3 e l s e Link 783 16 1 0 0 End; { of Segment S c r n l n i t > 784 16 1 0 0 785 16 1 0 0 786 16 1 0 0 787 2 1 d 1 F u n c t i o n T o s l n f o ; 788 •2 .i '& 1 5 0 0 Beg i n 789 -.2 * 1 0 i f tos = n i 1 790 2 15 1 2 then TosInfo:= f a l s e 791 2 15 1 5 e l s e TosInfo:= tos©.info_to_write 792 2 1 0 0 End; 793 2 1 0 0 794 2 1 0 0 795 2 1 d 1 Procedure S c r n E n t e r ; 796 2 1 0 0 Begin io name:= name; ScrnIO (258) End: 797 2 1 0 0 798 2 1 d 1 F u n c t i o n ScrnPrompt; 799 2 1 0 0 Begin ScrnIO (prompt_num); ScrnPrompt:= prmt_ptr End 800 2 1 0 0 801 2 1 d 1 Procedure S c r n C l e a r ; 802 2 1 0 0 Begin ScrnIO (259) End; 803 2 1 0 0 804 2 1 d 1 Procedure S c r n R e f r e s h ; 805 2 1 0 0 Begin ScrnIO (260) End; 806 2 1 0 0 807 2 1 d 1 Procedure ScrnReturn; 808 2 1 0 0 Begin ScrnIO (261) End; 809 2 1 0 0 810 2 1 0 0 81 1 2 1 d 1 F u n c t i o n sbLink; 812 2 2 0 0 Beg i n 813 2 2 1 10 i o name:= i mage; 8 14 2 2 1 16 1 ink fmt:= fmt; 8 15 2 2 1 22 1 i nk_k:= k; 8 16 2 2 1 25 S c r n I n i t ( f a 1se); 817 2 2 1 29 sbLink:= 1 i n k _ d a t a _ p t r 8 18 2 1 0 0 End; { of sbLink ) 8 19 2 1 0 0 820 2 1 0 0 Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 1 1 82 1 2 1 :d 1 Procedure s b H a l t ; 822 2 14 :0 0 Beg i n 823 2 14 : 1 0 SrceHshk ( t o s s data, t r u e ) 824 2 1 :0 0 End; { of H a l t ) 825 2 1 :0 0 826 2 1 :0 0 827 2 1 :0 0 828 2 1 :0 0 829 2 1 :d 1 Procedure NoteData ( d a t a _ p t r : sb dspl p t r ) ; 830 2 17 :0 0 B e g i n 831 2 17 : 1 0 w i t h data_ptr@, format do 832 2 17 : 2 6 Beg i n 833 2 17 : 3 6 enabled:= t r u e ; . 834 2 17 :3 1 1 i f r u n n i n g and s c r n _ v a l i d and not new d a t a 835 2 17 : 3 19 then B e g i n 836 2 17 :5 27 new_data:= t r u e : 837 2 17 :5 32 SrceHshk ( t o s s data, t r u e ) 838 2 17 : 4 35 End 839 2 17 : 3 37 e l s e new data:= t r u e 840 2 17 : 2 42 End { of with ) 84 1 2 1 :0 0 End; { of NoteData } 842 2 1 :0 0 843 2 1 :0 0 844 2 1 :d 1 Procedure sbTossBoolean; 845 2 3 :0 0 Beg i n 846 2 3 : 1 0 w i t h data_ptr© do 847 2 3 : 2 2 i f not format.enabled or (b <> v a l u e ) then 848 2 3 : 3 16 Beg i n 849 2 3 : 4 16 b : = va1ue; 850 2 3 :4 2 1 NoteData (data p t r ) 851 2 3 : 3 22 End 852 2 1 : :0 0 End: { of sbTossBoo1ean } 853 2 1 : :0 0 854 2 1 : 0 0 855 2 1 : d 1 Procedure s b T o s s I n t e g e r ; 856 2 4 : 0 0 Beg i n 857 2 4 : 1 0 w i t h d a t a ptr© do 858 2 4 : 2 2 i f not format e n a b l e d or ( i <> v a l u e ) then 859 2 4 : 3 16 B e g i n 860 2 4 : 4 16 i : = va1ue; 86 1 2 4 : 4 2 1 NoteData (data p t r ) 862 2 4 : 3 22 End 863 2 1 : 0 0 End; { of SbTossInteger ) ' 864 2 1 : 0 0 865 2 1 : 0 0 866 2 1 : d 1 Procedure sbTossReal; 867 2 5 : 0 O Beg i n 868 2 5: 1 0 w i t h data_ptr© do 869 2 5: 2 2 i f not format.enabled or ( r <> v a l u e ) then 870 2 5: 3 20 Beg i n Appendix E Compiler L i s t i n g of U n i t ScrnBuff Page 12 87 1 2 5 : 4 20 r : = va1ue; 872 2 5 :4 26 NoteData (data p t r ) 873 2 5 : 3 27 End 874 2 1 :0 0 End; < of sbTossReal } 875 2 1 :0 0 876 2 1 :0 0 877 2 1 :d 1 Procedure s b T o s s S t r i n g ; 878 2 6 :0 0 Beg i n 879 2 6 : 1 0 w i t h data_ptr®, format do 880 2 . 6 : 1 6 ( ensure v a l u e doesn't o v e r f l o w s b u f f e r } 881 2 6 : 2 6 i f l e n g t h ( v a l u e ) > f i e l d 882 2 6 : 2 9 then N o t e E r r o r (123, l e n g t h ( v a l u e ) , f a l s e ) 883 2 6 : 2 24 e l s e 1f not enabled or (s <> v a l u e ) then 884 2 6 :4 44 Begin 885 2 6 :5 44 s : = va1ue; 886 2 6 :5 51 NoteData (data p t r ) 887 2 6 : 4 52 End { of i f } 888 2 1 :0 0 End; < of s b T o s s S t r i n g } 889 2 1 :0 0 890 2 1 :0 0 891 2 1 :d 1 Procedure sbTossNow: 892 2 7 :0 0 Beg i n 893 2 7 : 1 0 NoteData ( d a t a _ p t r ) 894 2 1 :0 0 End; { of sbTossNow } 895 2 1 :0 0 896 2 1 :0 0 897 2 1 :d 1 Procedure s b D i s a b l e ; 898 2 8 :0 0 Begin 899 2 8 : 1 0 data_ptr®.format.enab1ed:= f a l s e 900 2 1 :0 0 End; { of s b D i s a b l e ) 901 2 1 :0 0 902 2, 1 :0 0 903 ' 2 1 :d 1 P r o c e s s Update; 904 2 16 : d 1 Var d a t a _ p t r : s b _ d s p l _ p t r ; 905 2 16 :d 2 906 2 16 :d 2 Procedure DsplNow; 907 2 18 :d 1 Var now: t i m _ r e c ; 908 2 18 :d 3 hms: t i m hms; 909 2 18 :0 0 Begi n 910 2 18 : 1 0 TimSubTO (now): 91 1 2 18 : 1 3 Tim_in hms (hms, now); 912 2 18 : 1 7 w i t h data_ptr@>, format do T o s s S t r i n g (x, y. 913 2 16 : 0 0 End; ( of DsplNow > 914 2 16 : 0 0 915 2 16 : 0 0 Begin { *** Update + * + } 916 2 16 : 1 2 AcptHshk ( t o s s _ d a t a , f a l s e ) ; 917 . 2 16 : ; 1 7 w h i l e running do 918 2 16 : 2 13 Beg i n 919 2 16 : 3 13 CursBorrow; 920 2 16 : 3 16 i f r u n n i n g and T o s l n f o then Appendix E Compiler L i s t i n g of U n i t S c r n B u f f Page 13 92 1 2 16 :4 26 with tos© do 922 2 16 : 5 29 i f r f r s h _ l i n k <> n i l then 923 2 16 :6 36 Beg i n 924 2 16 : 7 36 data p t r : - r f r s h link©.dspl l i s t ; 925 2 16 : 7 40 w h i l e d a t a _ p t r <> n i l do 926 2 16 :8 46 with data_ptr®, format do 927 2 16 :9 52 Begin 928 2 16 :0 52 i f new data and enabled and s c r n _ v a l i d then 929 2 16 : 1 69 Beg i n 930 2 16 : 2 69 new_data:= f a l s e : 931 2 16 : 2 74 Case k i n d of 932 2 16 : 2 78 sb b o o l : TossBoolean (x, y, b ) ; 933 2 16 : 2 92 sb i n t : T o s s l n t e g e r (x, y, i , f i e l d ) ; 934 2 16 : 2 112 sb r e : Begin 935 2 16 : 4 1 12 i f f l o a t 936 2 16 : 4 112 then T o s s F l o a t (x, y, r, f i e l d ) 937 2 16 : 4 138 e l s e TossReal (x, y, r, f i e l d , dec 938 2 16 : 3 166 End; 939 2 16 : 2 170 sb_ s t n g : T o s s S t r i n g (x, y, s, f i e l d ) ; 940 2 16 : 2 192 sb_now: DsplNow 941 2 16 : 2 192 End < of Case } 942 2 16 : 1 199 End; { of i f ) 94 3 2 16 :0 199 data_ptr:= next_dspl 944 2 16 : 9 199 End { of w i t h data_ptr© ) 945 2 16: :6 202 End; < of i f ru n n i n g e t c . ) 946 2 16: : 3 205 CursReturn; 947 2 16 : 3 208 i f r u n n i n g then AcptHshk ( t o s s _ d a t a , f a l s e ) 948 2 16 : 2 216 End { of w h i l e r u n n i n g > 949 2 1 : 0 0 End; { of Update > 950 2 1 : 0 0 951 2 1 : 0 0 952 2 1 : O 0 Begin 953 2 1 : : 1 10 S c r n l n i t ( t r u e ) 954 2 :0 0 End. End of C o m p i l a t i o n . Appendix F Compiler L i s t i n g of U n i t Clock Page 1 3 0 0 d 1 <$L remout:> 4 2 1 d 1 U n i t Clock; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e < c l o c k r e a d i n g u t i l i t i e s > 7 2 1 d 1 8 2 1 d 1 Type tim r e c = r e c o r d hiword, loword; i n t e g e r end; 9 2 1 d 1 { two's complement 32 b i t i n t e g e r > 10 2 1 d 1 tim hms = s t r i n g [ 8 ] : 1 1 2 1 d 1 12 2 .1 d 1 Var tim ovflw: boolean; 13 2 1 d 2 < TimAdd & TimMinus o v e r f l o w f l a g > 14 2 1 d 2 15 2 1 d 2 Procedure TimReset; { r e s e t system c l o c k to 0 } 16 2 1 d 1 17 2 1 d 1 Procedure TimAdd (var sum: ti m _ r e c : a. b: t i m_rec) ; 18 2 1 d 1 { sum:= a + b > 19 2 1 d 1 20 2 1 d 1 Procedure TimMinus (var d i f f : t i m _ r e c ; a.b: t i m_rec); 2 1 2 1 d 1 { d i f f : = a - b } 22 2 1 d 1 23 2 1 d 1 F u n c t i o n Tim aLTb (a.b: t i m _ r e c ) : boolean; 24 2 1 d 1 { resu1t:= a < b > 25 2 1 d 1 26 2 1 d 1 F u n c t i o n T i m A r r i v e d ( t : tim r e c ) : boolean; 27 2 1 d 1 ( r e s u l t : = t <= c l o c k r e a d i n g } 28 2 1 d 1 29 2 1 d 1 F u n c t i o n TimlnSeconds ( t : t i m _ r e c ) : r e a l ; 30 2 1 d 1 { r e s u l t : = t in seconds ) 31 2 1 d 1 32 2 1 d 1 Procedure TimOfSeconds (var t: t i m _ r e c ; r: rea1 ) ; 33 2 1 d 1 { t:= r, where r i s i n seconds ) 34 2 1 d 1 35 2 1 d 1 Procedure TimlnHMS ( v a r hms: tim_hms; t: tim r e c ) ; 36 2 1 d 1 < c o n v e r t t to hh:mm:ss, 00:00:00 <= hms <= 99:59:59 37 2 1 d 1 38 2 1 d 1 Procedure TimSetTO: 39 2 1 d 1 { read c l o c k , l e t r e s u l t be known as t o } 40 2 1 d 1 4 1 2 1 d 1 Procedure TimSubTO (var t: t i m _ r e c ) ; 42 2 1 d 1 ( r e t u r n with c l o c k r e a d i n g - tO > 43 2 1 d 1 44 2 1 d 1 Imp 1ementat ion 45 2 1 d 1 46 2 1 d 1 47 2 1 d 1 48 2 1 d 1 49 2 1 d 1 F u n c t i o n E r r o r N o t e d : boolean; 50 2 1 d 1 { True i f f N o t e E r r o r has been c a l l e d . } 5 1 2 1 d 1 Appendix F Compiler L i s t i n g of U n i t Clock Page 2 52 2 1 d 1 Procedure N o t e E r r o r (n, i n f o : i n t e g e r ; immediate: b o o l e a n ) ; 53 2 1 d 1 { Wr1te n'th e r r o r message ( i n c l u d i n g nfo as p a r t of the mess age) 54 2 1 d 1 from e r r o r log upon program h a l t (or immediately & h a l t ) . } 55 2 1 d 1 56 2 1 d 1 Uses ErrMessg; 57 2 1 d 1 58 2 1 d 1 59 2 1 d 1 Const l o l i m =3; { a r r a y p o s i t i o n s of low 8 h i g h s i g n i f l i m i t s > 60 2 1 d 1 h i 1 i m = 6 ; 6 1 2 1 d 1 62 2 1 d 1 63 2 1 d 1 Var tO: t i m _ r e c ; 64 2 1 d 3 s i gn i f : a r r a y [1 .8] of tim r e c ; < s i g n i f i c a n c e / d i g i t of hms } 65 2 1 d 19 66 2 1 d 19 67 2 1 d 19 Procedure TimReset; e x t e r n a 1; 68 2 1 d 1 Procedure TimAdd; e x t e r n a l ; 69 2 1 d 1 Procedure TimMinus; e x t e r n a l ; 70 2 1 d 1 F u n c t i o n Tim aLTb; e x t e r n a l ; 7 1 2 1 d 1 F u n c t i o n T i m A r r i v e d ; e x t e r n a 1 ; 72 2 1 d 1 73 2 1 d 1 74 2 1 d 1 Segment Procedure C l o k l n i t ; 75 4 1 d 1 Const h o u r l O h i = 32 h ouMOlo = -2688 { hiword, loword of } 76 4 1 d 1 hourhi = 3 h o u r l o = 19392 ( s i g n i f i c a n c e of > 77 4 1 d 1 minlOhi = 0 m i n l O l o = -29536 < each d i g i t i n hms } 78 4 1 d 1 m i nh i = 0 minlo = 3600 79 4 1 d 1 seelOh 1 = 0 sec 101o = 600 80 4 1 d 1 s e c h i = 0 s e c l o = 60 8 1 4 1 d 1 1o1i mh i = 0 l o l i m l o = O 82 4 1 d 1 hi 1imhi = 329 h i l i m l o = -26940 83 4 1 d 1 Procedure Load ( i , h i , 1o: i n teger ) ; 84 4 2 0 0 Beg i n 85 4 2 1 0 with s i gn i f [ i ] do 86 4 2 2 10 Beg i n hi word: = h i ; loword:= l o End 87 4 1 0 0 End; { of Load > 88 4 1 0 0 Begin ( *** C l o k l n i t *** } 89 4 1 0 0 < l o a d tim hms d i g i t s i g n i f i c a n c e a r r a y } 90 4 1 1 0 Load (1. hour 10hi, hour 101o); 91 4 1 1 8 Load (2, h o u r h i , h o u r l o ) ; 92 4 1 1 15 Load (4, m i n l O h i , m i n l O l o ) ; 93 4 1 1 22 Load (5, minhi, m l n l o ) ; 94 4 1 1 29 Load (7, s e c i O h i , s e d O l o ) ; 95 4 1 1 36 Load (8, s e c h i , s e c l o ) ; 96 4 1 1 42 < use s i g n 1 f [ 1 o 1 i m ] and [ h i l i m ] f o r range e n t r i e s > 97 4 1 1 42 Load ( l o l i m , l o l i m h i , l o l i m l o ) ; 98 4 1 1 47 Load ( h i l i m . h i l i m h i , h i l i m l o ) ; 99 4 1 1 56 { r e s e t system c l o c k & t o > 100 4 1 1 56 T1mReset; 101 4 1 1 58 { can't TimSetTO s i n c e r e s e t takes up to 1/60 sec to take e f f e c t > 1^ Appendix F Compiler L i s t i n g of U n i t Clock Page 3 102 4 1 1 58 f i l l c h a r ( t o , s i z e o f ( t o ) , 0) 103 4 1 0 0 End; { of Segment C l o k l n i t > 104 4 1 0 0 105 4 1 0 0 106 2 1 d 1 F u n c t i o n TimlnSeconds; 107 2 1 d 1 { r e s u l t : 3 t i n seconds } 108 2 7 0 0 Begin 109 2 7 1 5 with t do 1 10 2 7 2 5 Begin 1 1 1 2 7 3 5 i f loword < 0 then h i w o r d : 3 hiword + 1; 1 12 2 7 3 13 Timlnseconds:= (65536.0 * hiword + loword) / 60.O 1 13 2 7 2 23 End 1 14 2 1 0 0 End; 1 15 2 1 0 0 1 16 2 1 0 0 1 17 2 1 d 1 Procedure TimOfSeconds; 1 18 2 1 d 1 { t:= r . where r i s i n seconds } 1 19 2 8 0 0 Begin 120 2 8 1 0 r : - r * 60.0: 12 1 2 8 1 8 with t do 122 2 8 2 10 Beg i n 123 2 8 3 10 h i w o r d : 3 round ( r / 65536.0); 1 24 2 8 3 21 l o w o r d : 3 round ( r - 65536.0*hiword) 125 2 8 2 32 End 126 2 1 0 0 End; 127 2 1 0 0 128 2 1 0 0 129 2 1 d 1 Procedure TimlnHMS: 130 {commented : '} { c o n v e r t t to hh:mm:ss, 00:00:00 <= hms < 3 99:59:59: a v o i d 131 2 1 d 1 long i n t e g e r s f o r speed & memory s a v i n g s > 132 2 9 d 1 Var i , d i g i t : i n t e g e r ; 133 2 9 d 3 sum: t i m_rec; 134 2 9 0 0 Beg i n 135 2 9 0 0 { check f o r range e r r o r } 136 2 9 1 5 i f Tim_aLTb ( t , s i g n i f [ 1 o l i m ] ) or Tim_aLTb (s1gnif[hi1im], 137 2 9 1 29 then N o t e E r r o r (1, t.hiword, f a l s e ) 138 2 9 1 37 e l s e Begin 139 2 9 1 4 1 { i n i t i a l i z e hms > 140 2 9 3 4 1 hms: 3 ' ' ; 14 1 2 9 3 48 { c a l c u l a t e a l l hms d i g i t s ) 142 2 9 3 48 f o r d i g i t : 3 1 to 8 do 143 2 9 4 57 i f not ( d i g i t i n [ l o l i m , h i l i m ] ) then 144 2 9 5 64 Beg i n 145 2 9 5 64 { c a l c u l a t e i : 3 the d i g i t ' t h d i g i t } 146 2 9 6 64 1 : 3 0: 147 2 9 6 66 sum: 3 sign1f[digit]; 148 2 9 6 79 w h i l e Tim_aLTb (sum, t) do 149 2 9 7 86 Begin 150 2 9 8 86 i : 3 1 + 1 ; 151 2 9 8 89 TimAdd (sum, sum, s1gnif[digit] ) Appendix F Compiler L i s t i n g of U n i t Clock Page 4 152 2 9 7 100 End: { of whi1e > 153 2 9 7 104 ( s u b t r a c t i * s i g n i f from t } 154 2 9 6 104 TimMinus (sum, sum, s i g n i f [ d i g i t ] ) ; 155 2 9 6 1 17 TimMinus ( t , t. sum); 156 2 9 6 122 h m s [ d i g i t ] : = chr ( i + ord('O')) 157 2 9 5 129 End < of f o r , i f } 158 2 9 2 130 End { of no range e r r o r } -159 2 1 O 0 End; < of TimlnHMS } 160 2 1 0 0 161 2 1 0 0 162 2 1 d 1 Procedure TimSetTO; 163 2 1 d 1 { read c l o c k , l e t r e s u l t be known as t o } 164 2 10 0 0 Beg i n 165 2 10 1 0 w i t h tO do time (hiword, loword) 166 2 1 0 0 End; 167 2 1 0 0 168 2 1 0 0 169 2 1 d 1 Procedure TimSubTO; 170 2 1 d 1 { r e t u r n with c l o c k r e a d i n g - tO } 17 1 2 1 1 0 0 Beg i n 172 2 1 1 1 0 with t do time (hiword. loword); 173 2 1 1 1 8 TimMinus ( t . t. tO) 174 2 1 0 0 End; 175 2 1 O 0 176 2 1 0 0 1 77 2 1 0 0 B e g i n 178 2 1 1 0 CI o k I n i t 179 2 0 0 End. End of C o m p i l a t i o n . N J I D Appendix F Assembler L i s t i n g of U n i t Clock E x t e r n a l Routines Page ;This f i l e c o n t a i n s no .PROC. .FUNIC, ; d y n a m i c a l l y r e l o c a t a b l e , and may or i n t e r n a l d a t a a r e a s . I t i s t h e r e f o r e move about i n ram or be swapped out to d i 0000 0040 0091 sb i os .EOU jmptabl .EOU c l k r e a d .EOU 0000H sbios+0040H jmptabl+0051H l o c a t i o n of s b i o s i n ram s b i o s jump t a b l e s b i o s c l o c k read r o u t i n e .RELPROC TimReset ; r e s e t system c l o c k : 0094 c l k i n i t .EOU jmptabl+0054H :sbi o s c l o c k i n i t i a l i z a t i o n r o u t i n e oooo C3 9400 JP c l k i n i t 0003 0003 0003 0000 .RELPROC TimAdd.3 OOOO ;time type a d d i t i o n : sum (param1®):= a (param2®) + b (param3@) OOOO OOOO .REF ckover OOOO OOOO C1 pop BC : r e t u r n address 0001 E 1 Pop HL : p o i n t e r to b 0002 D1 pop DE ; p o i n t e r to a 0003 DD E 1 pop IX ; p o i n t e r to sum 0005 C5 push BC ; r e p l a c e r e t u r n address 0006 AF xor A : r e s e t c a r r y 0007 06 04 Id B,4 :4 by t e s i n time_type 0009 addbyte: 0009 :add c u r r e n t byte of b to c u r r e n t byte of a, save i n c: 0009 1A Id A,(DE) : c u r r e n t b y t e of a OOOA 8E adc A.(HL ) :add w i t h c a r r y to c u r r e n t byte OOOB DD 77 00 Id (IX+O),A ; save r e s u l t i n c u r r e n t b y t e of OOOE :point to next byte of a. b. and sum: OOOE 23 i nc HL :point to next byte of b OOOF 13 i nc DE . ,. „ „ „ „ a 0010 DD 23 i nc IX . >. i. i. .. r e s u i t 0012 10F5 dj nz addbyte 0014 C3 OOOO JP ckover ;check f o r and f l a g o v e r f l o w .RELPROC TimMinus.3 time_type s u b t r a c t i o n : d i f f (param!©): a (param2®) - b (param3©): Appendix F Assembler L i s t i n g of U n i t Clock E x t e r n a l Routines Page 2 oooo .DEF ckover, minus oooo • time m a n i p u l a t i o n o v e r / u n d e r f l o w b o o l e a n oooo .PU8LIC t i movf1w oooo oooo C1 pop BC r e t u r n address 0001 E 1 pop HL p o i n t e r to b 0002 D 1 pop DE p o i n t e r to a 0003 DD E 1 pop IX p o i n t e r to d i f f 0005 C5 push BC r e p l a c e r e t u r n address 0006 AF m i nus: xor A r e s e t borrow 00O7 06 04 l d B.4 4 bytes i n time_type 0009 subbyte c u r r e n t b y t e of a, save i n c: 0009 ; s u b t r a c t c u r r e n t byte of b from 0009 1A l d A. (DE) c u r r e n t b y t e of a OOOA 9E sbc A,(HL) s u b t r a c t w i t h borrow c u r r e n t b y t e of b OOOB DD 77 00 l d (IX+O).A save r e s u l t i n c u r r e n t b y t e of d i f f OOOE ;po i nt to next byte of a. b, and d i f f : OOOE 23 i nc HL p o i n t to next b y t e of b OOOF 13 i nc DE " a 0010 DD 23 i nc IX " " " " " r e s u l t 0012 10F5 dj nz subbyte 0014 60 ckover : l d H.B HL : - 0 0015 68 Id L.B 0016 E2 * * * + JP PO. $ 1 i f no o v e r f l o w , r e s e t timovflw 0019 2C 1 nc L e l s e s e t ti m o v f l w 001 A 22 OOOO $1 l d ( t imovfIw),HL f l a g o v e r f l o w i f c a r r y s e t 0010 C9 r e t 001E 001E 00 1E OOOO .RELFUNC Tim aLTb,2 OOOO :resu1t ( b o o l e a n ) : 3 a (paraml®) < b (param2®): OOOO OOOO .DEF deLThl OOOO . REF m i nus OOOO OOOO .PRIVATE d i f f : 2 dummy d i f f e r e n c e b u f f e r OOOO oooo C 1 pop BC r e t u r n address 0001 E 1 pop HL p o i n t e r to b 0002 D1 pop DE p o i n t e r to a 0003 F 1 pop AF junk u n n e c e s s a r y p-code word 0004 C5 push BC save r e t u r n a d d r e s s on s t a c k 0005 DD 2 1 OOOO deLThl : Id I X . d i f f p o i n t e r to dummy d i f f 0009 CD OOOO ca l 1 m i nus HL: = t i m o v f l w : 3 a - b o v e r f l o w e d OOOC 3A 0300 l d A . ( d i f f + 3 ) check s i g n of d i f f OOOF 07 r 1 ca loa d s i g n b i t i n t o b i t 0 0010 AD xor L a < b i f f d i f f < 0 or o v e r f l o w , not bo t h 001 1 E6 01 and 1 keep o n l y b i t 0 0013 6F 1 d L . A HL : = boo l e a n r e s u l t Append i x F Assembler L i s t1ng of Uni t Clock E x t e r n a l Routines Page 0014 E3 ex (SP).HL put r e s u l t on st a c k , r e t u r n address i n HL 0015 E9 JP (HL) r e t u r n 0016 0016 * 0016 0000 .RELFUNC TimArrived,1 OOOO ;resu1t ( b o o l e a n ) : 3 not ( c l o c k r e a d i n g < t (paraml©) ) : OOOO OOOO . REF deLThl OOOO OOOO .PRIVATE now:2 c l o c k r e a d i n g b u f f e r OOOO OOOO CD 9100 c a l 1 c1kread DE:= lsword, HL:= msword of c l o c k r e a d i n g 0003 ED 53 OOOO Id (now),DE save 1 sword 0007 22 0200 l d (now+2),HL " msword OOOA FD E 1 pop IY r e t u r n a d d r e s s OOOC E 1 pop HL p o i n t e r to t OOOD F 1 pop AF junk u n n e c e s s a r y p-code word OOOE 1 1 OOOO l d DE,now p o i n t e r to c l o c k r e a d i n g 001 1 CD OOOO ca l 1 deLThl get (SP) := now < t 0014 C1 pop BC get b o o l e a n r e s u l t 0015 CB 19 r r C i n c a r r y 0017 3F c c f complement i t 0018 CB 1 1 r l C put back i n b i t 0 001A C5 push BC save b o o l e a n (SP):= not (now < t ) 001B FD E5 push IY r e t u r n a d d r e s s 001D C9 r e t 001 E 001E 001E 001E . END Assemb1y comp1ete: 130 1ines 0 e r r o r s f l a g g e d on t h i s assembly Appendix F Compiler L i s t i n g of Un i t ErrMessg Page 1 3 0 0 d 1 {$L remout:> 4 2 1 d 1 U n i t ErrMessg; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 8 2 1 d 1 F u n c t i o n E r r o r N o t e d : boolean; 9 2 1 d 1 < True i f f N o t e E r r o r has been c a l l e d . > 10 2 1 d 1 1 1 2 1 d 1 Procedure N o t e E r r o r (n, i n f o : i n t e g e r ; immediate: b o o l e a n ) ; 12 2 1 d 1 { Wri t e n'th e r r o r message ( i n c l u d i n g i n f o as p a r t of the message) 13 2 1 d 1 from e r r o r l og upon program h a l t (or immediately & h a l t ) . ) 14 2 1 d 1 15 2 1 d 1 Implementat ion 1G 2 1 d 83 2 1 d ($L-> Uses ScreenOps; ($L®> 84 2 1 d 85 2 1 d Var e r r d e t e c t e d : boolean; 86 2 1 d e r r num, e r r i n f o : i n t e g e r ; 87 2 1 d 1 88 2 1 d 1 89 2 1 d 1 Segment Procedure W r i t e E r r ; 90 4 1 d 1 Const l o g name = ' u t i 1 :system.errs'; 91 4 1 d 1 Var e r r o r _ l o g : f i l e of r e c o r d 92 4 1 d 1 n: i n t e g e r ; 93 4 1 d 1 s: st r i ng[77] 94 4 1 d 1 end; 95 4 1 d 341 p: i n t e g e r ; 96 4 1 d 342 message: s t r i n g [ 8 3 ] ; 97 4 1 d 384 e r r f l a g : s t r i n g [ 6 ] ; 98 4 1 d 388 Procedure Unknown; 99 4 2 0 0 Beg i n 100 4 2 1 0 w r i t e ('Unknown e r r o r ( i n f o = ', e r r _1nfo, ' ) ' , c h r ( 7 ) ) 101 4 1 O 0 End: 102 4 1 0 0 Begin { W r i t e E r r > 103 4 1 1 8 scErasEOS (0, 20); 104 4 1 1 12 scDown; 105 4 1 1 14 w r i t e l n (chr ( 7 ) , '===>>> UBC P h y s i c s E r r o r H', e r r num, ': <<<= 106 4 1 1 65 i f ( e r r num < 1) or ( e r r num > 999) 107 4 1 1 75 then Unknown 108 4 1 1 78 e l s e Begin 109 4 1 3 83 ($I-> r e s e t ( e r r o r _ l o g , log_name); {$! + > 1 10 4 1 3 93 1f i o r e s u l t <> 0 1 1 1 4 1 3 96 then Unknown 1 12 4 1 3 99 e l s e Begin 1 13 4 1 5 104 while (error_log®.n < e r r num) 1 14 4 1 5 109 and not eof ( e r r o r log) 1 15 4 1 5 1 15 and ( i o r e s u l t = 0) 1 16 4 1 5 122 do ($1-) get ( e r r o r l o g ) ; {$! + } 1 17 4 1 5 1 30 with e r r o r log® do Co 125 4 1:0 179 126 4 1:0 192 127 4 1:0 201 Appendix F Compiler L i s t i n g of U n i t ErrMessg Page 118 4 1:6 134 i f n <> err_num 119 4 1:6 138 then Unknown 120 4 1:6 141 e l s e B e g i n 121 4 1:8 145 message: 3 s; 122 4 1:8 156 p:= pos ('##', message) + 1; 123 4 1:8 172 i f p > 1 then 124 4 1:9 179 B e g i n s t r ( e r r _ i n f o , e r r _ f l a g ) ; d e l e t e (message, p, 1); i n s e r t ( e r r _ f l a g , message, p) 128 4 1:9 215 End: I of i f p > 1 ) 129 4 1:8 215 w r i t e (message, c h r ( 7 ) ) 130 4 1:7 236 End < of e l s e n = err_num > 131 4 1:4 236 End; { of e l s e i o r e s u l t = 0 > 132 4 1:3 236 {$1-} c l o s e ( e r r o r _ l o g , normal) ($1+) 133 4 1:2 240 End { of err_num i n range 1..999 > 134 4 1:0 0 End; < of W r i t e E r r > 135 4 1:0 0 136 4 1:0 0 137 2 1:d 1 F u n c t i o n E r r o r N o t e d ; 138 2 2:0 0 Begin 139 2 2:1 0 E r r o r N o t e d : 3 e r r _ d e t e c t e d 140 2 1:0 0 End; 141 2 1:0 0 142 2 1:0 0 143 2 1:d 1 Procedure N o t e E r r o r ; 144 2 3:0 0 B e g i n 145 2 3:0 0 ( ensure second e r r o r doesn't wipe out f i r s t u n l e s s immediate } 146 2 3:1 0 i f immediate or not e r r _ d e t e c t e d then 147 2 3:2 6 Begin 148 2 3:3 6 e r r _ d e t e c t e d : = t r u e ; 149 2 3:3 9 err_num:- n; 150 2 3:3 12 e r r _ i n f o : = i n f o 151 2 3:2 12 End; 152 2 3:1 15 i f immediate then 153 2 3:2 18 Begin 154 2 3:3 18 W r i t e E r r ; 155 2 3:3 20 e x i t (program) 156 2 3:2 25 End 157 2 1:0 0 End: 158 2 1:0 0 159 2 1:0 0 160 2 1:0 0 Begin { ErrMessg i n i t i a l i z a t i o n > 161 2 1:1 0 e r r _ d e t e c t e d : = f a l s e ; 162 2 1:1 3 *** : 163 2 1:1 6 i f e r r _ d e t e c t e d then W r i t e E r r 164 2 :0 0 End. End of C o m p i l a t i o n . 4^ Appendix F Compiler L i s t i n g of U n i t MiscFunc Page 3 0 0 : d 4 2 1 :d 5 2 1 : d S 2 1 :d 7 2 1 d 8 2 1 d 9 2 1 d 10 2 1 d 1 1 2 1 d 12 2 1 d 13 2 1 d 14 2 1 d 15 2 1 d 1G 2 1 d 17 2 1 d 18 2 1 d 19 2 1 d 20 2 1 d 2 1 2 1 d 22 2 1 d 23 2 1 d 24 2 1 d 25 2 1 d 26 2 1 d 27 2 1 d 28 2 1 d 29 2 1 d 30 2 1 d 31 2 1 d 32 2 1 d 33 2 1 d 34 2 1 d 35 2 1 d 36 2 1 d 37 2 1 d 38 2 1 d 39 2 1 d 40 2 1 d 0 4 1 2 1 d 0 42 2 1 d 0 43 2 1 d 0 44 2 2 0 0 45 2 2 1 0 46 2 1 0 0 47 2 1 0 0 48 2 1 d 1 49 2 3 0 0 50 2 3 1 0 5 1 2 1 0 0 {$L remout:} U n i t MiscFunc; { m i s c e l l a n e o u s s h o r t f u n c t i o n s and p r o c e d u r e s } I n t e r f a c e { power of 10 f u n c t i o n s } F u n c t i o n TenToThe ( r : r e a l ) : r e a l ; { 10**r ) F u n c t i o n Log ( r : r e a l ) : r e a l ; { base 10 l o g a r i t h m ) { signum f u n c t i o n s } F u n c t i o n rSgn ( r : r e a l ) : r e a l ; { i f r<0.0 then -1.0 e l s e 1.0 } F u n c t i o n 1Sgn ( i : i n t e g e r ) : i n t e g e r ; { i f 1<0 then -1 e l s e 1 ) { min and max f u n c t i o n s ) F u n c t i o n rMin (a.b F u n c t i o n rMax (a.b F u n c t i o n 1Min (a.b F u n c t i o n iMax (a.b r e a l ) : r e a l ; { i f a<b then a e l s e b ) r e a l ) : r e a l ; { i f a>b then a e l s e b } I n t e g e r ) : i n t e g e r ; { i f a<b then a e l s e b } i n t e g e r ) : i n t e g e r ; { i f a>b then a e l s e b } { l i m i t i n g f u n c t i o n s } F u n c t i o n rBounded ( r , min, max: r e a l ) : r e a l ; { rMax (min, rMin(r.max)) F u n c t i o n rAbsBndd ( r , bound: r e a l ) : r e a l ; { rBounded ( r , -bound, bound) F u n c t i o n iBounded ( i , min, max: i n t e g e r ) : Integer; { i n t e g e r rBounded } F u n c t i o n iAbsBndd (1. bound: i n t e g e r ) : i n t e g e r : { i n t e g e r rAbsBndd > { unsigned i n t e g e r f u n c t i o n s ) F u n c t i o n u s i A d d (a,b: i n t e g e r ) : i n t e g e r ; { a + b } F u n c t i o n u s i M i n u s (a,b: i n t e g e r ) : i n t e g e r ; < a - b ) { c h a r a c t e r f u n c t i o n s > F u n c t i o n UpperChar ( c : c h a r ) : char; { s t r i n g f u n c t i o n s > Procedure Uppercase (Var s: s t r i n g ) ; Imp1ementat i on Const ln10 = 2.302585; F u n c t i o n TenToThe; Beg i n TenToThe:= exp ( l n 1 0 * r ) End; F u n c t i o n Log; Beg i n Log:= l n ( r ) / ln10 End; { change c to upper case } { change s to upper case } U l U l Appendix F Compiler L i s t i n g of U n i t MiscFunc Page 2 52 2 1 :0 0 53 2 1 :0 0 54 2 1 :d 1 F u n c t i o n rSgn; 55 2 4 :0 0 Beg i n 56 2 4 : 1 0 i f r < 0.0 then rSgn : 3 -1.0 57 2 4 : 1 9 e l s e rSgn : 3 1 .0 58 2 1 :0 0 End; 59 2 1 :0 0 60 2 * 1 :d 1 F u n c t i o n iSgn; 61 2 5 :0 0 Beg i n 62 2 5 : 1 0 i f 1 < 0 then i Sgn: 3 - 1 63 2 5 : 1 5 e l se i S g n : 3 1 64 2 1 :0 0 End; 65 2 1 :0 0 66 2 1 :0 0 67 2 1 : d 1 F u n c t i o n rMin; 68 2 6 :0 0 Beg i n 69 2 6 : 1 0 i f a < b then rM i n : 3 a 70 2 6 : 1 8 e l se rM i n : 3 b 7 1 2 1 :0 0 End; 72 2 1 :0 0 73 2 1 :d 1 F u n c t i o n rMax; 74 2 7 :0 0 Begi n 75 2 7 : 1 0 i f a > b then rMax: 3 a 76 2 7 : 1 8 e 1 se rMax: 3 b 77 2 1 :0 0 End: 78 2 1 :0 0 79 2 1 : d 1 F u n c t i o n iMin; 80 2 8 :0 0 Begi n 81 2 8 : 1 0 i f a < b then i M i n : 3 a 82 2 8 : 1 5 e 1 se iM1n: 3 b 83 2 1 : :0 0 End; 84 2 1 : :0 0 85 2 1 : :d 1 F u n c t i o n iMax; 86 2 9: 0 0 Begi n 87 2 9 : 1 0 i f a > b then i Max: 3 a 88 2 9 : 1 5 e 1 se i Max:- b 89 2 1 : 0 0 End: 90 2 1 : 0 0 91 2 1 : 0 0 92 2 1 : d 1 F u n c t i o n rBounded; 93 2 10: 0 0 Beg i n 94 2 10: 1 0 rBounded: 3 rMax (min. rM1n ( r , 95 2 1 : 0 0 End; 96 2 1 : 0 0 97 2 1 : d 1 F u n c t i o n rAbsBndd; 98 2 1 1 : 0 0 Beg i n 99 2 1 1 : 1 0 rAbsBndd: 3 rBounded ( r -bound, 100 2 1 : 0 0 End; 101 2 1 : 0 0 ISJ Cn Appendix F Compiler L i s t i n g of U n i t MiscFunc Page 3 102 2 1 :d 1 F u n c t i o n iBounded; 103 2 12 :0 0 Begi n 104 2 12 : 1 0 iBounded: 3 iMax (min, iM1n (1, max)) 105 2 1 :0 0 End; 106 2 1 :0 0 107 2 1 :d 1 F u n c t i o n iAbsBndd; 108 2 13 :0 0 Beg i n 109 2 13 : 1 0 iAbsBndd: 3 iBounded ( i , -bound, bound) 1 10 2 1 :0 0 End; 1 1 1 2 1 :0 0 1 12 2 1 :0 0 -1 13 2 1 :d 1 F u n c t i o n usIAdd: 1 14 2 14 :0 0 Beg i n 1 15 2 14 : 1 0 u s i A d d : 3 a + b { note that IV.0 run time e r r o r 05 does not happen ) 1 16 2 1 :0 0 End; 1 17 2 1 :0 0 1 18 2 1 :d 1 F u n c t i o n u s i M i n u s ; 1 19 2 15 :0 0 Begi n 120 2 15 : 1 0 u s i M i n u s : 3 a - b { note that IV.0 run time e r r o r 05 does not happen 121 2 1 :0 0 End: 122 2 1 :0 0 • 123 2 1 :0 0 124 2 1 :d 1 F u n c t i o n UpperChar; 125 2 16 :0 0 Beg i n 126 2 16 : 1 0 i f c i n ['a'..'z'] then UpperChar: 3 chr ( o r d ( c ) - 32) 127 2 16 : 1 14 e l s e UpperChar: 3 c 128 2 1 :0 0 End; 129 2 1 :0 0 130 2 1 :0 0 131 2 1 :d 1 Procedure Uppercase; 132 2 17 :d 1 Var i : i n t eger; 133 2 17 :0 0 B e g i n • 134 2 17 : 1 0 f o r i:= 1 to l e n g t h ( s ) do s [ i ] : 3 UpperChar ( s [ 1 ] ) 135 2 1 :0 0 End; 136 2 1 :0 0 137 2 1 :0 0 138 2 :0 0 End. End of C o m p i l a t i o n . to Appendix F Compiler L i s t i n g of U n i t E x t r a S c r Page 1 3 0 0 d 1 {$L remout:> 4 2 1 d 1 U n i t ExtraScreenOps; 5 2 1 d 1 6 2 1 d 1 I n t e r f a c e 7 2 1 d 1 { E x t r a ScreenOps r o u t i n e s > 8 2 1 d 1 75 2 1 d 1 <$L-> Uses ScreenOps; <$L@> 76 2 1 d 1 77 2 1 d 1 Funct ion MapCommandKey (command: sc key command: 78 2 1 d c a l l from i n i t i a l i z i o n p a r t : b o o l e a n ) : char; 79 2 1 d 1 { Inverse of scMapCrtCommand: c a l l s t o t h i s f u n c t i o n must have 80 2 1 d 1 the second parameter t r u e i f made from an i n i t i a l i z a t i o n p a r t } 81 2 1 d 1 82 2 1 d 1 Procedure MapDate ( v a r date: s t r i n g ) ; 83 2 1 d 1 { r e t u r n with the c u r r e n t date as 'dd-mmm-yy' } 84 2 1 d 1 85 2 1 d 1 Implementat i on 86 2 1 d 0 87 2 r d 0 88 2 1 d 0 Var map: a r r a y [sc_key_command] of char; 89 2 1 d 11 90 2 1 d 11 91 2 1 d 11 Segment Procedure ExtraDat (var date: s t r i n g ) ; 92 4 1 d 1 Var d, y s t r i n g[2]; 93 4 1 d 5 m: s t r i ng[3]; 94 4 1 d 7 t i n f o : sc i n f o type: 95 4 1 0 0 Beg i n 96 4 1 1 0 s c U s e l n f o ( s c get, t i n f o ) ; 97 4 1 1 4 wi t h t_ 1nfo.sc date do 98 4 1 2 4 Beg i n 99 4 1. 3 4 s t r (day, d ); 100 4 1 3 17 s t r ( y e a r , y ) ; 101 4 1 3 30 Case month of 102 4 1 3 37 0 m:= '00'; 103 4 1 3 46 1 m : = 'dan' 104 4 1 3 55 2 m:= 'Feb' 105 4 1 3 64 3 m: = 'Mar' 106 4 1 3 73 4 m : = ' Apr ' 107 4 1 3 82 5 m:= 'May' 108 4 1 3 91 6 m:= 'Oun' 109 4 1 3 100 7 m:= 'Ju1 ' 1 10 4 1 3 109 8 m:= 'Aug' 1 1 1 4 1 3 1 18 9 m:= 'Sep' 1 12 4 1 3 127 10 m : = ' Oct' 1 13 4 1 3 136 1 1 m: = 'Nov' 1 14 4 1 3 145 12 m : = ' Dec' 1 15 4 1 3 146 End; { of Case } 1 16 4 1 3 157 date = concat (d m, y) 1 17 4 1 2 205 End { of with } U l CD Appendix F Compiler L i s t i n g of U n i t E x t r a S c r 1 18 4 1 :0 0 1 19 4 . 1 :0 0 120 4 1 :0 0 12 1 2 1 : d 1 122 2 3 :0 0 123 2 3 : 1 0 124 2 1 :0 0 125 2 1 :0 0 126 2 1 :0 0 127 2 1 : d 1 128 2 4 : d 1 129 2 4 :0 0 130 2 4 : 1 0 131 2 4 : 1 2 132 2 4 : 2 8 133 2 4 : 3 8 134 2 4 : 2 14 135 2 4 : 1 28 136 2 4 : 1 31 137 2 4 : 1 34 138 2 4 : 2 39 139 2 4 : 2 44 140 2 4 : 3 50 14 1 2 1 :0 0 142 2 1 :0 0 143 2 1 :0 0 144 2 1 : d 1 145 2 2 :0 0 146 2 2 : 1 0 147 2 2 : 1 0 148 2 2 : 1 5 149 2 1 :0 0 150 2 1 :0 0 151 2 1 :0 0 152 2 1 : :d 1 153 2 5 : d 1 154 2 5 : 0 0 155 2 5: 1 0 156 2 5: 2 9 157 2 1 : 0 0 158 2 1 : 0 0 159 2 1 : 0 0 160 2 1 : 0 0 161 2 1 : 1 0 162 2 0 0 End; < of Segment ExtraDat } Procedure MapDate; Beg i n ExtraDate (date) End; { of ExtraDate } F u n c t i o n OneMap (command: sc_key_command): char; Var t e s t : char; Begin tes t : = chr ( 0 ) ; i f scHasKey (command) then Repeat test : = succ ( t e s t ) U n t i l (scMapCrtCommand ( t e s t ) = command) or i f t e s t < chr (255) then OneMap:= t e s t e l s e i f command = sc_backspace_key then OneMap:- OneMap ( s c _ l e f t _ k e y ) e l s e i f command = sc _ e o f _ k e y then OneMap:= OneMap ( s c _ e t x _ k e y ) End; F u n c t i o n MapCommandKey; Begi n i f c a 1 1 _ f r o m _ 1 n i t i a 1 i z a t i o n _ p a r t then MapCommandKey:= OneMap (command) e l s e MapCommandKey:= map [command] End; Procedure InitMap; Var command: sc_key_command; Beg 1 n f o r command:= sc_backspace_key to s c _ n o t _ l e g a l map [command]:= OneMap (command) End; Beg i n Ini tMap End. End of C o m p i l a t i o n . Page 2 255) ; N J U l Appendix F Compiler L i s t i n g of U n i t WritCons Page 3 0 0 d 4 2 1 d 5 2 1 d 6 2 1 d 7 2 1 d .8 2 1 d 9 2 1 d 10 2 1 d 1 1 2 1 d 12 2 1 d 13 2 1 d 14 2 1 d 15 2 1 d 1G 2 1 d 17 2 1 d 18 2 1 d 19 2 1 d 20 2 1 d 2 1 2 1 d 22 2 1 d 23 2 1 d 24 2 1 d 25 2 1 d 26 2 1 d 27 2 1 d 28 2 1 d 29 2 1 d 30 2 1 d 31 2 1 d 32 2 1 d 33 2 1 d 34 2 1 d 35 2 1 d 36 2 1 d 37 2 1 d 38 2 1 d 39 2 1 d 40 2 1 d 4 1 2 1 d 42 2 1 d 43 2 1 d 44 2 1 d 45 2 1 d 46 2 1 d 47 2 1 d 48 2 1 d 49 2 1 d 50 2 1 d 5 1 2 1 d ($L remout:> U n i t WritCons; I n t e r f a c e { procedures to send f o r m a t t e d v a l u e s to c o n s o l e : ) Procedure W r i t e B o o l e a n (b: b o o l e a n ) ; Procedure TossBoolean (x, y: i n t e g e r ; b: b o o l e a n ) ; { w r i t e a boolean v a l u e as 'true ' or ' f a l s e ' } F u n c t i o n WriteNot (b: b o o l e a n ) : boolean; F u n c t i o n TossNot (x. y: i n t e g e r ; b: b o o l e a n ) : boolean; { r e s u l t : = not b, W r i t e B o o l e a n ( r e s u l t ) > Procedure W r i t e B l a n k s ( f i e l d : i n t e g e r ) ; Procedure TossBlanks (x, y, f i e l d : i n t e g e r ) ; < w r i t e f i e l d b lanks > Procedure W r i t e E r a s e ( f i e l d : i n t e g e r ) ; Procedure T o s s E r a s e (x. y, f i e l d : i n t e g e r ) : { W r i t e B l a n k s ( f i e l d ) , r e t u r n c u r s o r to s t a r t i n g p o s i t i o n > Procedure W r i t e L e f t ( f i e l d : i n t e g e r ) : { w r i t e f i e l d backspaces without e r a s i n g > Procedure WriteBackspaces ( f i e l d : i n t e g e r ) ; { w r i t e f i e l d backspaces, e r a s i n g c h a r a c t e r s a l o n g the way } Procedure T o s s l n t e g e r (x, y, i , f i e l d : i n t e g e r ) ; { move c u r s o r to x.y and w r i t e i r i g h t j u s t i f i e d g i v e n width ) in a f i e l d of Procedure WriteReal ( r : r e a l ; f i e l d , d e c _ f i e l d : i n t e g e r ) Procedure TossReal (x, y: i n t e g e r ; r: rea1; f i e l d , dec { w r i t e r r i g h t j u s t i f i e d i n a f i e l d of a f t e r the d e c i m a l . If dec f i e l d = 0, f i e l d : i n t e g e r ) ; width f i e l d w i t h the rea1 w i l l be d e c _ f i e l d wr i t ten as an i n t e g e r . r i s rounded to the d e c C h a r ' t h d i g i t b e f o r e w r i t i n g } Procedure W r i t e F l o a t ( r : r e a l ; f i e l d : i n t e g e r ) ; Procedure T o s s F l o a t (x, y: i n t e g e r ; r : r e a l ; f i e l d : i n t e g e r ) ; < w r i t e r i n s c i e n t i f i c n o t a t i o n r i g h t j u s t i f i e d a f i e l d of b l a n k s ) Procedure TossChar (x, y: i n t e g e r ; ch: c h a r ) : ( send c u r s o r to x,y and w r i t e ch:1 ) Procedure W r i t e S t r i n g ( s : s t r i n g ; f i e l d : i n t e g e r ) ; Procedure T o s s S t r i n g (x, y: i n t e g e r ; s: s t r i n g ; f i e l d : i n t e g e r ) ; < w r i t e s ( i f f i e l d > 0 then l e f t j u s t i f i e d i n a f i e l d of b l a n k s ) ) Imp 1ementat i on o Appendix F Compiler L i s t i n g of U n i t WritCons Page 2 52 2 1 :d 164 2 1 :d {$L-} Uses ScreenOps, ExtraScreenOps. MiscFunc; 165 2 1 :d ft 166 2 1 :d 167 2 1 :d Var backspaces: packed a r r a y [0..79] of char; { 168 . 2 1 : d 169 2 1 :d 170 2 1 :d Procedure WriteBoolean; 17 1 2 2 :0 0 Beg 1 n 172 2 2 : 1 0 If b then W r i t e S t r i n g ('true ', 5) 173 2 2 : 1 9 e l s e W r i t e S t r i n g ( ' f a l s e ' , 5) 174 2 1 :0 0 End; 175 2 1 :0 0 176 2 1 :d 1 Procedure TossBoolean; 177 2 3 :0 0 B e g i n 178 2 3 : 1 0 gotoxy ( x , y ) ; WriteBoolean (b) 179 2 1 :0 0 End: 180 2 1 :0 0 181 2 1 :d 1 F u n c t i o n WriteNot; 182 2 4 :0 0 Beg i n 183 2 4 : 1 0 W r i t e B o o l e a n (not b ) ; WriteNot:= not b 184 2 1 :0 0 End; 185 2 1 :0 0 186 2 1 :d 1 F u n c t i o n TossNot; 187 2 5 :0 0 Beg i n 188 2 5 : 1 0 gotoxy (x, y ) ; TossNot:= WriteNot (b) 189 2 1 :0 0 End: 190 2 1 :0 0 191 2 1 :0 0 192 2 1 :d 1 Procedure W r i t e B l a n k s ; 193 2 1 :d 1 ( use blank compression } 194 2 6 : d 1 Const DLE = 16; 195 2 6 :d 1 Var b l a n k s : packed a r r a y [0..1] of 0..255; 196 2 6 :0 0 Beg i n 197 2 6 : 1 0 b l a n k s [0]:= DLE : 198 2 6 : 1 11 b l a n k s [ 1 j : = 32 + f i e l d ; 199 2 6 : 1 25 u n i t w r i t e (1, b l a n k s , 2) 200 2 1 :0 0 End; 201 2 1 :0 0 202 2 1 :d 1 Procedure TossBlanks; 203 2 7 :0 0 B e g i n 204 2 7 : 1 0 gotoxy ( x . y ) ; W r i t e B l a n k s ( f i e l d ) 205 2 1 :0 0 End: 206 2 1 :0 0 207 2 1 :0 0 208 2 1 :d 1 Procedure W r i t e E r a s e : 209 2 8 :0 0 B e g i n 2 10 2 8 : 1 0 Wri teBlanks ( f i e l d ) ; 2 1 1 2 8 : 1 3 W r i t e L e f t ( f i e l d ) 2 12 2 1 :0 0 End; Appendix F Compiler L i s t i n g of U n i t WritCons Page 2 13 2 1 : 0 0 2 14 2 1 :d 1 Procedure T o s s E r a s e ; 2 15 2 9 : 0 0 Beg i n 2 1 6 . 2 9 : 1 0 gotoxy ( x . y ) ; W r i t e E r a s e ( f i e l d ) 2 17 2 1 : 0 O End; 2 18 2 1 : 0 0 2 1 9 2 1 : 0 0 2 2 0 2 1 :d 1 Procedure W r i t e L e f t ; 221 2 10 : 0 0 Beg i n 2 2 2 2 10 : 1 O u n i t w r i t e ( 1 , backspaces, f i e l d ) 2 2 3 2 1 : 0 0 End; 2 2 4 2 1 : 0 0 2 2 5 2 1 :d 1 Procedure WriteBackspaces; 2 2 6 2 1 1 : 0 0 Beg i n 2 2 7 2 1 1 : 1 0 W r i t e L e f t ( f i e l d ) ; 2 2 8 2 1 1 : 1 3 W r i t e E r a s e ( f i e l d ) 2 2 9 2 1 : 0 O End; 2 3 0 2 1 : 0 0 231 2 1 : 0 0 2 3 2 2 1 :d 1 Procedure T o s s l n t e g e r ; 2 3 3 2 12 : 0 0 Begin 234 2 12 : 1 0 gotoxy ( x . y ) ; w r i t e ( i : f i e l d ) 2 3 5 2 1 : 0 0 End; 2 3 6 2 1 : 0 O 2 3 7 2 1 : 0 0 2 3 8 2 1 :d 1 Procedure W r i t e R e a l ; 2 3 9 2 13 : 0 0 Beg i n 2 4 0 2 13 : 1 0 i f d e c _ f i e l d > 0 24 1 2 13 : 1 1 then w r i t e ( r : f 1 e l d : d e c _ f i e 1 d ) 2 4 2 2 13 : 1 16 e l s e i f a b s ( r ) > maxint 2 4 3 2 13: : 2 21 then w r i t e ( r : f i e l d : 1 ) 2 4 4 2 13 : : 2 39 e l s e w r i t e ( r o u n d ( r ) : f 1 e 1 d ) 2 4 5 2 1 : : 0 0 End: 2 4 6 2 1 : : 0 0 2 4 7 2 1 : :d 1 Procedure TossReal; 2 4 8 2 14 : 0 0 Beg i n 2 4 9 2 14 : : 1 0 gotoxy ( x . y ) ; 2 5 0 2 14 : 1 4 WriteReal ( r , f i e l d , dec f i e l d ) 251 2 1 : 0 0 End; 2 5 2 2 1 : 0 0 2 5 3 2 1 : o 0 2 5 4 2 1 : d 1 Procedure W r i t e F l o a t ; 2 5 5 2 15 : d 1 Var exponent: i n t e g e r ; 2 5 6 2 15 : d 2 mant i s s a : rea1 ; 2 5 7 2 1 5 : 0 0 Beg i n 2 5 8 2 15 : 1 0 i f r = 0 . 0 2 5 9 2 15 : 1 2 then Begin 2 6 0 2 15 : 3 8 exponent:= 0 ; 261 2 15 : 3 10 mant i ssa:= 0 . 0 2 6 2 2 15 : 2 1 1 End Appendix F Compiler L i s t i n g of U n i t WritCons Page 4 2G3 2 15 : 1 15 e l s e Begin 264 2 15 : 3 17 exponent:= round ( L o g ( a b s ( r ) ) - 0 . 4 9 9 9 9 9 ) ; 265 2 15 : 3 30 mantissa:= r / Ten to the (exponent) 266 2 15 : 2 37 End; 267 2 15 : 1 4 1 W riteReal ( m a n t i s s a , f i e l d - 4 , i min ( f i e l d - 7 , 5 ) ) ; 268 2 15 : 1 55 i f exponent >= 0 269 2 15 : 1 56 then i f exponent > 9 then w r i t e ('E+', exponent) 270 2 15 :2 87 e l s e w r i t e ('E+0', exponent) 27 1 2 15 : 1 1 1 1 e l s e i f exponent < -9 then w r i t e ('E', exponent) 272 2 15 : 2 139 e l s e w r i t e ('E-0', -exponent) 273 2 1 :0 0 End; 274 2 1 :0 0 275 2 1 :d 1 Procedure T o s s F l o a t ; 276 2 16 :0 0 Beg i n 277 2 16 : 1 0 gotoxy ( x . y ) ; W r i t e F l o a t ( r , f i e l d ) 278 2 1 :0 0 End; 279 2 1 .0 O 280 2 1 :0 0 28 1 2 1 :d 1 Procedure TossChar; 282 2 17 :0 0 Begin 283 2 17 : 1 0 gotoxy ( x . y ) ; w r i t e (ch) 284 2 1 :0 o End; 285 2 1 :0 0 286 2 1 :0 0 287 2 1 :d 1 Procedure Wr1teStr1ng: 288 2 18 :d 1 Var l e n : i n t e g e r ; 289 2 18 :0 0 Begin 290 2 18 : 1 5- len:= 1ength ( s ) ; 291 2 18 : 1 9 i f f i e l d <= 0 then fie1d:= l e n 292 2 18 : 1 15 e l s e 1 en:= iMin ( l e n . f i e l d ) : 293 2 18 : 1 27 i f l e n > 0 then u n i t w r i t e (1. s [ 1 ] , l e n ) ; 294 2 18 : 1 4 1 i f f i e l d > l e n then W r i t e B l a n k s ( f i e l d - l e n ) 295 2 1 : 0 0 End; 296 2 1 : 0 0 297 2 1 : d 1 Procedure T o s s S t r i n g ; 298 2 19: 0 0 Begin 299 2 19 : 1 5 gotoxy ( x . y ) ; W r i t e S t r i n g ( s . f i e l d ) 300 2 1 : 0 0 End: 301 2 1 : 0 0 302 2 1 : 0 0 303 2 1 : 0 0 Beg i n 304 2 1 : 1 0 f i l l c h a r (backspaces. 80. MapCommandKey ( s c backspace key 305 2 0 0 End. End of C o m p i l a t i o n . isj O J 

Cite

Citation Scheme:

        

Citations by CSL (citeproc-js)

Usage Statistics

Share

Embed

Customize your widget with the following options, then copy and paste the code below into the HTML of your page to embed this item in your website.
                        
                            <div id="ubcOpenCollectionsWidgetDisplay">
                            <script id="ubcOpenCollectionsWidget"
                            src="{[{embed.src}]}"
                            data-item="{[{embed.item}]}"
                            data-collection="{[{embed.collection}]}"
                            data-metadata="{[{embed.showMetadata}]}"
                            data-width="{[{embed.width}]}"
                            data-media="{[{embed.selectedMedia}]}"
                            async >
                            </script>
                            </div>
                        
                    
IIIF logo Our image viewer uses the IIIF 2.0 standard. To load this item in other compatible viewers, use this url:
https://iiif.library.ubc.ca/presentation/dsp.831.1-0095276/manifest

Comment

Related Items