SYSTEM FOR EVALUATING THE PERFORMANCE OF A LARGE SCALE PROGRAMMABLE MACHINE CAPABLE OF HAVING A PLURALITY OF TERMINALS ATTACHED THERETO

Abstract: System for emulating plurality of operational terminals connected to the host computer system (10) so that the monitoring test is carried out as if under actual operating conditions. The use of plurality of CPUs (100A - 100AG) provides modularity and allows the system to be scaled to the size (number of host communication ports) of the host computer system (10) rather than requiring a large scale computer to test another large scale computer. The system measures the time between when the information is input to the host computer system and when an expected response is received by the appropriate CPU. Various script programs are prepared to run on the CPUs (100A - 100AG) which will cause the CPUs (100A - 100AG) to generate signals emulating the signals which would be generated by a terminal connected to the host computer system as if the terminal were operated by a human operator.

Description: SYSTEM FOR EVALUATING THE PERFORMANCE OF A LARGE SCALE PROGRAMMABLE MACHINE . CAPABLE OF HAVING A PLURALITY OF TERMINALS ATTACHED THERETO BACKGROUND A. The Field of the Invention. The present invention is directed to systems for evaluating the performance of large scale programmable machines capable of having a plurality of terminals connected thereto. More particularly, the present invention is directed to a method and a system, referred to in the art as a robot, which emulates the actions of human operators and is used for evaluating the performance of a large scale multi-user host computer systems. B. The Background Art. As modern society has come to rely more and more upon the use of programmable machines such as digital computers for business, governmental, scientific, and other applications, the variety of available hardware and software has increased dramatically. For example, only a few years ago an organization looking to acquire a high performance computer system would have had to choose from only a few vendors. As use of digital computers has proliferated throughout society, the number of vendors providing hardware has also rapidly expanded. With the number of possible choices always on the increase, purchasers of large scale computer systems have come to feel an urgent need to determine whether a particular configuration of computer system hardware will perform as specified. Very often, such large scale computer systems are used in organizations where a plurality of terminals, which may include devices such as SUBSTITUTESHEET video terminals, keyboards, bar code readers, and other devices, provide communication with the CPU of the computer system. In such situations, measuring the period of time between when a user, such as a human operator using a bar code reader, inputs information to the CPU and the time required by the CPU to provide an appropriate response is extremely important. Not only does the response time effect the number of transactions which can be handled over a specified period, 10 and thus the profitability or efficiency of the organization, but long delays between inputting required information and receiving appropriate responses causes dissatisfaction and aggravation to the human users of the system at each terminal. 15 Since the acquisition of a large scale computer system is a major capital item in any organization, the area of computer performance evaluation has received increasing attention in recent years. By utilizing computer performance evaluation techniques before purchase 20 of a large scale computer system, it is hoped that the large scale computer system which is chosen can provide . the best performance at the lowest possible cost. Moreover, computer performance evaluation techniques are also used by both hardware and software vendors to " satisfy contractual and customer requirements that the computer system performs at its minimum specifications before the customer takes delivery. Thus, there has been an effort in the art to provide computer performance evaluation systems and techniques to test the performance 30 of hardware, software, and combinations thereof. Vendors of computer hardware often times provide potential customers with specifications indicating that a particular configuration of some large scale computer system will carry out "X million instructions per second 35 SUBSTITUTESHEET (MIPS)" or some other criteria of computing speed and power. Unfortunately, such specifications provide little reliable information concerning the performance of a large scale computer system having many, perhaps hundreds or thousands of communication ports, each having a terminal connected thereto and also requiring an interface with peripheral devices such as magnetic disc drives and other devices. The economic incentives of being able to accurately predict whether a combination of computer hardware and software will perform as specified has lead to the development of various approaches and techniques to carrying out computer performance evaluations. The performance of computers is a function of many interrelated considerations, including the programming tools available, the size of the problem to be solved, the algorithm used to solve the problem, the computer operating system's efficiency, and the architecture of the computer. Generally, three approaches are used to conduct a computer performance evaluation (CPE) . These three approaches include: (1) simulations; (2) benchmark testing; and (3) monitoring. Simulations are a technique of performance evaluation whereby a large scale computer system to be tested is simulated using software programs. When utilizing simulations, it is necessary that both hardware and software functions be simulated by the simulation program. Thus, a program code must be written to simulate functions such as magnetic disc input/output, terminal input/output, data base handling, operating system's functions, and application program functions. Unfortunately, the use of simulation techniques requires that the simulation accurately quantify the performance of each of the components in the large scale SUBSTITUTESHEET computer system being simulated. Without such accurate quantifications, attempts to predict the large scale computer system performance under actual operating conditions becomes impossible. Thus, disadvantageously, a great deal of effort must be spent by programmers to create a simulation program for each computer system to be evaluated. It will be appreciated that if a potential customer desired to estimate the likely performance of ten different large scale computer systems available from different vendors, the amount expended in creating ten different simulation programs (one for each potential computer system) may far outweigh the benefits which come from carrying out the performance evaluation. Moreover, the inherent inaccuracies and uncertainties involved in simulations is ever present. Another computer performance evaluation technique is referred to as benchmark testing. Benchmark testing utilizes a group of computer programs (sometimes referred to as a suite) to test specific performance capabilities of the host computer system. In benchmark testing, it is very important to define what exactly is being tested by each of the computer programs. Significantly, more often than not, benchmark test programs evaluate the quality of the programming code they are written in rather than the performance of the host computer on which they run. In a multi-user environment, three main factors that effect transaction throughput are: (1) multi programming level, (2) data sharing among simultaneous transactions, and (3) the transaction mix. In a benchmark evaluation, it is possible to develop statistics on multi-user capability of a host computer system by running a series of data base inquiries in a single user mode and then again in a multi-user mode. The results of such benchmark testing can then be extrapolated to estimate the SUBSTITUTESHEET performance of the complete system with all terminals in place and operational. For example, benchmark programs may evaluate the difference in performance of the host computer system when the number of users increases from one to ten. The difference in performance may then be extrapolated to estimate the performance of the host computer system when 100 users are placed on a system. Unfortunately, such extrapolation seldom provides an accurate picture of host computer system performance under actual operating conditions. For example, benchmark testing results when using only a few users cannot be extrapolated to predict the performance of the host computer system when a full load of 400, 600, or more, user terminals are added to the system. This is due to the fact that many computer systems perform well up to a particular work load with their performance dropping rapidly as that particular work load is exceeded. Thus, benchmark computer performance evaluation techniques, while more desirable than simulation testing, have major drawbacks and disadvantages when an accurate prediction of host computer system performance under actual operating conditions is expected. The inadequacy of other methods of computer performance evaluation has lead to the development of various techniques for monitoring a large scale host computer system under actual operating conditions. For example, a user determining which computer system to acquire, or the configuration of computer system after a particular vendor has been selected, would, in one form of monitoring testing, actually assemble the complete host computer system with all peripheral terminal devices attached thereto, for example 600 user terminals, and load the CPU with actual application programs and data and have SUBSTITUTESHEET all 600 terminals being used as if under actual operating conditions. Some forms of computer performance evaluation monitoring testing require hardware and/or software which has been specifically developed for a particular computer system in order to measure the transaction throughput which occurs under actual operating conditions. Disadvantageously, the costs of such hardware and/or software for monitoring transactions through the computer system under actual operating conditions is prohibitive for users evaluating computer systems before purchasing the same. Moreover, it will be appreciated that organizing a monitoring test under actual operating conditions is a major logistical feat when a large number of terminals are involved. While the loading of data and application programs into a host computer system is a relatively simple procedure (since the applications programs and data will change relatively little from machine to machine) , the connecting of 600 terminals to the CPU and coordinating the 600 human operators for the duration of the evaluation session is an immense task. Moreover, since human operators are used to input information, the input rate at which information is given to the host computer system cannot be accurately controlled. It will be appreciated that monitoring tests of a large scale host computer system having a large number of terminals connected thereto (e.g.. 100 - 1000 terminals) under actual operating conditions is a very time consuming and expensive task. While such monitoring tests produce evaluations which justify a high degree of confidence therein, the costs and difficulty of performing such monitoring tests make the alternative one which is seldom carried out. SUBSTITUTESHEET As will be appreciated from the foregoing, it would be considered an advance in the art to provide a system for efficiently evaluating the performance of a large scale multi-user computer system. It would also be an advance in the art to provide a system for carrying out computer system evaluation monitoring more efficiently than previously possible. It would be a further advance in the art to provide computer performance efficiency monitoring system which may be particularly adapted for use with a changing number of communication ports which are active on the host computer system. It would be a still further advance in the art to provide a computer performance evaluation system which is readily transported from one location to another and set up for use. still another advance in the art would be to provide a system for computer performance evaluation monitoring under full load conditions without requiring human operators or terminal devices being associated with the host computer. It would be a further advance in the art to provide a system for computer performance evaluation monitoring which allows monitoring tests to be accurately repeated. It would be still another advance in the art to provide a system for computer performance evaluation monitoring that can be used with a large number of different host computer systems with little modification. It would be yet another advance in the art to provide a system for carrying out computer performance evaluation monitoring tests that is cost efficient to use on host computers from a variety of vendors. it would also be an advance in the art to provide a system for computer performance evaluation monitoring which can vary the timing at which transactions u are presented to the host computer system as well accurately vary the transaction rate. It would be still another SUBSTITUTESHEET advance in the art to provide a computer performance evaluation monitoring system which records the time taken to complete each transaction. OBJECTS AND BRIEF SUMMARY OF THE INVENTION In view of the foregoing difficulties and drawbacks found in the prior state of the art, it is a primary object of the present invention to provide an efficient system and method for carrying out computer performance evaluation monitoring of a large scale, multi-user, computer system. It is another object of the present invention to provide a system for computer performance evaluation monitoring which records the time taken by the host computer system for completing each transaction. It is another object of the present invention to provide a computer performance evaluation system and method which can readily vary the type of transactions and also the transaction rate from one monitoring test to another. It is yet another object of the present invention to provide a computer performance evaluation system which can be adapted to carry out monitoring of any number of particular host computer systems efficiently. it is still another object of the present invention to provide a computer performance evaluation monitoring system which may be readily adapted to test varying numbers of communication ports on a host computer system. It is another object of the present invention to provide a system for computer performance evaluation monitoring of a host computer system operating under full load but without requiring a plurality of actual terminal devices and human operators to operate the same. SUBSTITUTESHEET It is still another object of the present invention to provide a computer performance evaluation monitoring system which allows a monitoring test to be repeatedly carried out. It is a still further object of the present invention to provide a computer performance evaluation monitoring system and method which can be used with a variety of different host computer systems while requiring little modification. These and other objects of the present invention will become more apparent during an examination of this disclosure and during the practice of the invention. The present invention includes a system and method for carrying out monitoring of a host computer system so that a computer performance evaluation may be made of the host computer system. Embodiments of the present invention emulate a plurality of operational terminals so that the monitoring test is carried out as if under actual operating conditions for the host computer system. The system of the present invention is modular so that less monitoring test hardware is required as the number of active communication ports on the host computer system decreases. Since the present invention allows computer performance evaluations to be conducted under conditions which are equivalent to actual operating conditions, full confidence may be placed in the test results. The present invention is ideally suited for evaluating the performance of a large scale host computer system having a large number of host communication ports each being capable of communicating with a terminal. The system of the present invention includes a plurality of processing devices, central processing units (CPUs) , or other computing devices. The use of a plurality of CPUs provides modularity and allows the system to be scaled to SUBSTITUTESHEET the size (number of host communication ports) of the host computer system rather than requiring a large scale computer system to test another large scale computer system as was the case in the prior state of the art. Each CPU in the embodiment of the present invention is provided with a plurality of communication ports which comprise one embodiment of a port means. The port means, or CPU communication ports, are connected to the CPU's internal parallel bus. Means is also provided for individually connecting the communication ports to the host communication ports is included in the system. By the communication paths established between the plurality of CPUs and the host computer system, the appropriate CPU carries out steps which sends requests to the host computer system to execute identifiable tasks a d the appropriate CPU also inputs data required by the host computer system. Thus, the signals received by the host CPU appear as if they originated from a terminal and a human operator. one CPU is preferably designated to coordinate the operation of the other CPUs. In many situations it is advantageous to use a master-slave relationship among the CPUs where the master CPU is provided with additional computational power allowing the slave CPUs to be less expensive and less powerful devices. A means for measuring the time between when the information is input to the host computer system and when an expected response is received by the appropriate CPU is provided in the embodiments of the invention. Preferably the time required for each transaction is recorded and the information on the timing of all the transactions later analyzed to provide important information for use in improving the performance of the host computer system. SUBSTITUTE SHEET The method of the present invention includes loading the host computer system with the application program and the accompanying data as if the host computer system were to be used in the final application. Various script programs are prepared to run on the CPUs which will cause the CPUs to generate signals emulating the signals which would be generated by a terminal connected to the host computer system as if the terminal were operated by a human operator. Advantageously, various data pools are created from the data which accompanies the application programs run on the host computer system. A data pool is created for each type of task carried out by the application program. The data pools contain the data which would be input if the host computer system were actually installed and human operators were present at a plurality of terminals. The data pools are accessible by each of the CPUs. Each script program run by the CPUs requests that a certain task or transaction be carried out by the host computer system and thus requires access to only one or a few of the data pools. In the described embodiment, all of the data pools and script programs reside on the master CPU and may be accessed by any of the slave CPUs. All of the scripts carrying out the same task or transaction access data from the same data pool in the order that the data appears in the data pool. Since the data is withdrawn from the data pool in linear order, and the data pools are created from the actual data loaded into the host computer system, a test may be halted at any time and the proper data item used when the test resumes. Since each data pool contains data required by only one type of script program, any number of similar script programs may share the same data pool. Thus, if the number of host communication ports is SUBSTITUTE SHEET increased from 100 to 600, it is generally only necessary to provide enough data for the script programs and, if desired, vary some of the script parameters of the programs. Most advantageously, in most circumstances the script programs for each task remain the same as the number of active host communication ports increases and the same data pools may be used. As will be appreciated, the method of the present invention avoids the impractical task of creating customized script programs when a large number of active host communication ports must be accommodated. Thus, the present invention provides great advantages not heretofore known in the computer performance evaluation field, including an economically implemented system and method for monitoring a large scale multi-user host computer system. BRIEF DESCRIPTION OF THE DRAWINGS Figure 1 is a simplified block diagram showing the presently preferred embodiment of the system of the present invention. Figure 2 is a high level flow chart representing the steps carried out by the slave CPUs represented in Figure 1. Figure 3 is a high level flow chart representing the steps carried out during communications with the communication ports associated with the CPUs represented in Figure 1. Figure 4 is a high level flow chart representing the steps carried out during execution of a transaction between an embodiment of the present invention and a host computer system. Figure 5 is a diagram representing one possible allocation of tasks among some of the communication ports shown in Figure 1. DETAILED DESCRIPTION OF THE PRESENTLY PREFERRED EMBODIMENT In the description which follows, reference will be made to the accompanying drawings wherein like structures are provided with like reference numerals. Furthermore, it should be understood that the following description and the accompanying drawings merely set forth the presently preferred best known mode for carrying out the present invention and thus the disclosure of the invention contained herein should be considered only as exemplary since the invention may be represented in many embodiments other than those described herein. A. Overview As mentioned previously, the most accurate technique for carrying out computer performance evaluations is to monitor the host computer system under actual operating conditions. As mentioned, it is previously known to utilize both software and hardware mo**nitors while the host computer system is actually being used after it has been installed. As will be readily appreciated, previously available software or hardware monitoring techniques are impractical since they require actual assembly of the complete host computer system and a full complement of human operators to carry out the monitoring test. Even when the cost of assembly of the complete host computer system is justified, since human operators are used, repeatedly and accurately varying the load placed on the host computer system from test to test becomes impossible. In order to SUBSTITUTESHEET overcome the drawbacks of previously known hardware and software monitoring techniques, monitoring techniques utilizing a digital computer as a robot were developed. A robot is a device which automates a monitoring test. The robot replaces various terminals and their accompanying human operators. Advantageously, the use of another digital computer to carry out a monitoring test on a host computer system allows the test parameters to be accurately controlled and the host computer system's performance to be accurately measured. Unfortunately, previously available computer performance evaluation monitoring robots all shared several common disadvantages. Among these disadvantages was the generally recognized belief in the industry that a monitoring robot must be of equal or greater capabilities and power compared to the host computer system to be tested. Thus, in order to test a large scale host computer system with 600 communication ports, it was necessary to use another large scale computer system with 600 communication ports. As will be readily understood, the cost of acquiring a large scale computer for a monitoring test in many cases is prohibitive. Moreover, another drawback of the previously available monitoring robots is that a robot which was designed to be used with one particular vendor's host computer system is incompatible with another vendor's host computer system. Still further, even when the use of another large scale computer to test the host computer system is justified, the creation of program code for scripts for each one of a varying number of active SUBSTITUTE SHE communication ports was a laborious and time consuming procedure. As will be more fully appreciated hereafter, the present invention overcomes the disadvantages and drawbacks of the previously available systems and methods for carrying out computer performance evaluation using a monitoring robot. B. The Presently Preferred System Embodiment of the Present Invention As will be appreciated, computer performance evaluation monitoring techniques have application in many different circumstances. One such circumstance is when a host computer system is being selected for use in an automated library system. A large library may have six hundred or more terminals located in one or more buildings. Some of the terminals are used by staff to perform functions such as checking out or checking in materials. Alternatively, many of the terminals are used by patrons performing searches to identify which materials they want to obtain. In both" cases, the human users desire to experience as little delay as possible between inputting a request to a terminal and receiving back the requested information. Thus, it is important to carry out a computer performance evaluation before accepting a particular host computer system configuration to be certain that the response time and transaction rates are acceptable while keeping expenditures for acquiring the host computer system as low as possible. Represented in Figure 1 is a block diagram showing the configuration of the presently preferred robot monitoring system of the present invention. Most advantageously, the embodiment represented in Figure 1 SUBSTITUTESHEET allows a large scale host computer system 10 to be monitored using a plurality of smaller processing devices or CPUs 100A - 100AG. This feature allows the monitoring robot to be much less expensive than using a large scale computer to monitor another large scale computer. Even further, the use of a plurality of smaller CPUs provides modularity clearly not available when another large scale computer system is used to monitor a large scale host computer system having many active communication ports. While monitoring a host computer system having a large number of ports may require 20 smaller CPUs of the type represented in Figure 1, the CPUs represented in Figure 1 may also be divided into two groups and used to monitor two different host computer systems having, for example, only 220 communication ports each. Thus, the system of the present invention provides a flexible monitoring system which can be implemented at a much lower cost than previous attempts where one large scale computer was required to monitor another large scale computer. As shown in Figure 1, the presently preferred system embodiment includes a plurality of processing devices, or CPUs 100A - 100AG, arranged in a master-slave relationship. As will be understood more fully soon, the master-slave relationship is hot essential to carrying out the inventive concepts taught herein but is presently preferred to reduce hardware costs by concentrating computing power in the master CPU 100A while using less powerful and less expensive slave CPUs 100B - 100AG. In the embodiment represented in Figure 1, it is preferred that the master CPU device 100A be one which is available from Everex Computer Systems of Fremont, California having the following attributes: Model: Everex STEP 286/16 SUBSTITUTESHEET RAM: 1 Megabyte Nonvolatile Memory: 40 Megabyte Magnetic Fixed Disk Drive & 5.25 inch Floppy Disk Drive Peripherals: One each of: any standard serial COM port, monitor, and keyboard. Each of the slave CPUs 100B - 100AG may also be identical to the master CPU 100A except that the fixed disk drive, the keyboard, and the monitor may be omitted from the slave CPUs 10OB - 100 AG in order to reduce the cost and the bulk of the embodiment. It will be understood that each of the CPUs 100A - 100AG is provided with an internal paralell communication path or bus, which is not explicitly represented in Figure 1, to which devices such as communication ports may be connected. Those skilled in the art will appreciate that the above specified CPUs are substantially equivalent to an IBM PC/AT computer and that while the specified CPUs are preferred, other equivalent machines could be adapted for use in the illustrated embodiment. It will be further appreciated that the speed of operation of the CPUs is an important criteria in determining whether a particular CPU will perform adequately. Also, as the speed of operation of such devices increases, it may be possible to reduce the number of CPUs necessary to test a host computer system having a constant number of active communication ports. While the arrangement represented in Figure l is preferred, it is to be understood that the inventive concepts of the present invention may be carried out utilizing a plurality of CPUs which are arranged in other than a master-slave relationship. SUBSTITUTESHEET Importantly, the robot monitoring system represented in Figure 1 must include a communication path, generally a cable connection represented at 120B - 120AG, to each host communication port. In order to provide communication paths between the master CPU 100A and the slave CPUs 100B - 100AG, four serial interface cards 104A - 110A are installed in the master CPU 100A. Each serial interface card 104A - 110A provides eight serial ports (designated at 112A - 118A) . Each of the serial ports are connected to the COM ports 102B - 102AG of the slave CPUs 100B - 100AG by way of cables 120A. Likewise, each of the slave CPUs 100B - 100AG are provided with four serial interface cards (represented at 104 - 110 in each of the CPUs 100A - 100AG) to allow connection with up to 1024 host communication ports (represented at 12 in Figure 1) . The serial interface cards 104 - 110 are preferably those available from GTEK, Inc. of Bay St. Louis, Missouri, Model PCSS-8TX serial interface card. Each of the PCSS- 8TX serial interface cards provides eight serial communication ports as represented in Figure l. Each of the communication ports (112 - 118) allows the CPU, with appropriate software discussed later herein, to communicate with another device, i.e.. another CPU or the host computer system 10. As can be seen in Figure 1, the master communication ports (represented at 112A, 114A, 116A, and 118A) are connected to the COM communication ports 102B - 102AG on the slave CPUs 100B - 100AG. Thus, the master CPU 100A can coordinate the operation of up to 32 slave CPUs 100B - 100AG. In turn, each of the slave CPUs 100B - 100AG are provided with four serial interface cards (112, 114, 116, and 118) which allow each slave CPU 100B - 100AG to handle a maximum of 32 communication ports (112, 114, 116, and 118) . The communication ports on each slave CPU may be SUBSTITUTESHEET referred to as "remote" communication ports since they appears as remote communication ports to the host computer system. Thus, each slave CPU 100B - 100AG may be connected to 32 host communication ports 12 allowing the represented embodiment to emulate up to 1024 terminals. It is preferred that the standard , RS-232 communications protocol be used at all communication ports. While a communication protocol other than the standard RS-232 protocol could be used, use of such a standard serial protocol allows standard modular telephone jacks and cords to be used to interconnect the communication ports to one another. In the embodiment illustrated in Figure 1, the master CPU 100A carries out the task of recording the time required for each transaction and also coordinates the functions of all the slave CPUs 100B - 100AG. For example, one function of the master CPU 100A is to ensure that the operation of all of the slave CPUs 100B - 100AG is initially synchronized. Communication from the master CPU 100A is preferably received by each slave CPU 100B - 100AG by a standard COM port 102B - 102AG provided at each slave CPU as is well known in the art. Also represented in Figure 1 is a terminal 130, such as one available from Wyse Technology of San Jose, California, Model 50, which may be used for real time monitoring of transactions and to examine the operation of the embodiment as will be more fully explained hereinafter. The terminal 130 is connected to the master CPU by way of the COM port 102A on the master CPU 100A. Most advantageously, the master CPU 100A and its method of operation as described hereinafter function as a means for logically connecting the terminal 130 to any one of the host communication ports and also allow the results of the SUBSTITUTE SHEET monitoring session to be viewed as the session progresses and to be analyzed immediately thereafter. The arrangement of the CPUs 100A - 100AG represented in Figure 1 are properly referred to as a computer performance evaluation robot. Since the robot can take the place of a large number of terminals and their accompanying human operators, a monitoring test may be carried out much more easily. Moreover, the confidence placed in the monitoring test results obtained using the present invention may be the same or greater than if human operators were used. C. The Presently Preferred Method of Operation of the Embodiments of the Present Invention. Using the system illustrated in Figure 1, computer performance evaluations can be carried out while the host computer system performs under virtually the same conditions as actual operating conditions. One embodiment of the method of the present invention which allows such an accurate emulation of actual operating conditions is contained in the programming code represented in Appendices A - H. It will be understood that the programming code contained in Appendices A - H is merely representative of the steps to be carried out and other programming code may also be used to implement the inventive concepts taught herein. The programming code modules found in Appendices A - H provide the instructions necessary to adapt the system of the present invention described herein to perform as a monitoring robot for a large number of host computer systems. Appendix G provides scripting language definitions and a sample script to carry out the present invention on a host computer system which is to serve as the hardware for a library automation system. Those SUBSTITUTE SHEET familiar with the operation of a library will understand that an automated library system will generally include the following transactions: Circulation Transactions: Patron Record Update Check In Check Out Searching Transactions: Key Word Search Authority Search Indirect Search Alpha Title Search Cataloging Transactions: Bibliographic Record Update Item Record Update Acquisition Transactions: Ordering Receiving The presently preferred embodiment described herein is well adapted to monitor a host computer system capable of carrying out the above-listed transactions utilizing an automated library system such as those available from Dynix, Inc., of Provo, Utah. It will be appreciated, however, that many other types of multi-user host computer systems may also be monitored using the embodiment and the inventive concepts expressed herein. Significantly, in order to accurately emulate actual operating conditions, the embodiments of the present invention allow the rate at which transactions are presented to the host computer system to be varied from task to task as well as vary the rate at which characters are input to the host computer system (i.e. , vary the typing speed) . As an examination of the appendices will reveal, such changes may be made by merely altering some parameters in the scripts previously prepared to carry out SUBSTITUTE SHEET a task or transaction. Importantly, in contrast to the previously available techniques, the script programming code remains substantially unaltered as parameters are changed or additional communication ports are assigned to carry out the script. As will be readily appreciated by those skilled in the art, before a monitoring session is begun, the application software and the database, for example, a library automation program and database, are loaded into the host computer system 10. Also, each communication port of the slave CPUs 100A - 100AG are assigned a task which causes one of several transactions to be carried out at that communication port. Figure 2 is a flow chart showing the high level organization of the steps carried out by the program code utilized by the slave CPUs 100A - 100AG and appended hereto. Beginning at start 200 in the flow chart of Figure 2, upon power up or reboot, the 33 serial communication ports (COM ports 102 and ports 112, 114, 116, and 118) provided on each slave CPU 100B - 100AG are initialized for interrupt servicing as indicated at step 202. It will be appreciated that more or fewer than 33 serial communication ports may be associated with each CPU according to the present invention. It is, however, preferred to utilize one COM port of each slave CPU 100B - 100AG for communication with the master CPU 100A and that the remaining 32 communication ports (112, 114, 116, and 118) be connected to the host communication ports 12. Further, it will be appreciated that communication techniques, such as a network, could be used to allow communication between each of the CPUs. As represented at step 204 in Figure 2, 32 tasks are initialized to appear at one of the 32 communication ports SUBSTITUTESHEET (112, 114, 116, and 118), each of which will process one terminal session. This approach emulates the actual conditions generally found in many host computer systems such as a library automation system. For example, one terminal will be assigned to circulation transactions (patron record update, check in, check out) while another terminal will be assigned to searching transactions (key word search, authority search, indirect search, and alpha title search) . In this way, each of the communication ports on the slave CPUs can appear to the host computer system as if it is a terminal carrying out a particular task. Also, if the host computer system is provided with a number of active communication ports which is not an even multiple of 32, fewer than 32 tasks may be initialized at step 204. In the embodiment described herein, the master CPU 100A is provided with enough memory to be able to store the time required to complete each transaction. Such memory preferably includes a fixed disk drive 132 as represented in Figure 1. Furthermore, the master CPU 100A coordinates the functioning of the slave CPUs 100B - 100AG by giving instructions and also providing data for the CPUs as the scripts are processed. Thus, as represented at step 206, the slave CPUs 100B - 100AG respond to requests for communication with the master CPU 100A. As represented at step 208, each slave CPU reschedules which of the 32 tasks 210A - 210AF will be carried out next. When it is a particular task's turn for execution, the appropriate commands are fetched as shown at step 212, and the command is then executed as represented at step 214. The tasks are again rescheduled (as shown at 216) and the process continues until the monitoring session is completed. However, as mentioned, as each task is rescheduled, the data necessary to execute SUBSTITUTESHEET the command (e.g. , data representing a patron's identification and the bar code numbers needed for a check out transaction) is obtained from the master CPU as represented at 218. Figure 3 is a high level flow chart representing the organization of the interrupt routines for the CPU communication ports (112, 114, 116, and 118) on each slave CPU 100B - 100AG. As shown in Figure 3, as an interrupt from each communication port is received (steps 230A - 230AF) , the slave CPU receives the data from the UART (Universal Asyncronous Receiver/Transmitter) provided at the serial communication port as shown at step 232. The data is then stored in a port specific buffer within the memory of the slave CPU (step 234) and the slave CPU waits until the next interrupt is received as shown at 236. Importantly, as shown in Figure 4, the data needed to carry out a task, such as a check out transaction, is not integral with the scripts. Represented in Figure 4 are a plurality of scripts each carrying out one type of transaction. Figure 4 shows transactions A, B, and N indicating that any desirable number of transaction types may be carried out using the present invention. Each of transactions A-N begins at the step represented at 251A - 251N in Figure 4. When data is required, the data is retrieved from the appropriate data pool (254A - 254N) . EAch of the data pools used in a monitoring session is generated from the database which is loaded into the host computer system so that the transactions carried out are the same as those which would be under actual operating conditions. As represented at step 256A - 256N, a first variable is entered into the host computer system. The variable is retrieved from the appropriate data poll as indicated at data pool 254A. Once the variables have been entered, the SUBSTITUTESHEET transaction waits for a prompt, or some other appropriate response, to be returned from the host computer system as represented at steps 257A - 257N. It is the period of time between entering the variable and receiving the prompt that is measured to determine the response time of the host computer system. The steps of entering another (second) variable 258A - 258N and waiting for another prompt 259A - 259N are repeatedly carried out. After the last prompt is received from the host computer system, the transaction ends as represented at step 260A - 260N. If the monitoring session is complete (step 262A - 262N) then the process ends (step 264A - 264N) . If not, the transaction is begun again. By using the described data pool arrangement, when the number of active communication ports on the host computer system is changed it is not necessary to make any major revisions to any of the scripts, but it is only necessary to make other easily carried out changes. Thus, the laborious task of rewriting lengthy scripts with data embedded therein, as required by previously available methods and systems, is avoided. Moreover, the present invention allows the embodiment described herein to halt and resume a monitoring session when desired. These and other advances inherent in the present invention allow computer performance evaluation monitoring to be carried out much more efficiently than previously possible. Reference will next be made to Figure 5 which is a diagram representing one possible allocation of tasks among some of the communication ports shown in Figure 1. In Figure 5, slave CPU 100B with the serial interface card 104B having eight serial communication ports is illustrated. Figure 5 shows that five communication ports have been allocated to carry out transaction A 250A which derive their data from data pool A 252A. Also shown in SUBSTITUTESHEET Figure 5 are three other communication ports allocated to carry out transaction B 25OB and which all derive their data from data pool B 254B. Significantly, means is also provided in the system and method of operation of the present invention to allow the transactions to have different parameters (e.g.. transaction rate and typing speed) on each communication port. Moreover, changing, adding, or deleting the allocation of transactions may be easily accomplished (either as the number of active host communication ports changes or remains the same) since the scripts reside on the master CPU in the described embodiment and the necessary instructions are communicated to the slave CPUs. In this way, the system embodiment and portions of the programming code contained herein together function as a means for selectively increasing and decreasing the number of active host communication ports which may be monitored. Provided below is a brief summary of the functioning of each portion of programming code contained in Appendices A - H. It will be appreciated that the programming code attached hereto is specifically written for use on the previously described system and contains modules for statistical analysis of the results of a monitoring session as well as other desirable features. Thus, the code attached hereto must be considered as only exemplary of the present invention since many different hardware configurations and software architectures can be used to carry out the present invention. The source code contained in the appendices attached hereto is written in the Microsoft C (version 5) programming language (except for assembly language routines where noted) which is well known to those skilled in the art. Thus, appropriate provision for running such SUBSTITUTESHEET programs on the previously described hardware can be made by those possessing skill in the art. Appendix A Title: Update Session I/O Code Module: US.C The code module (US.C) continued in Appendix A is used to describe the host computer system to be tested and also to set the parameters that control the test session. This code module is used prior to running a test session. Among the items that describe the host computer system to be tested are: NAME; MEMORY SIZE; DISK SIZE; DATABASE SIZE; DATE; TIME; and REMARKS Included among the control parameters are: SESSION LENGTH; TYPING SPEED; THINK-TIME DELAYS; SCRIPT PACING; and the mix of SCRIPTS among the slave CPU ports Appendix B Title: Master Program Code Module: MP.C This code module runs on the master CPU. Using the SESSION.ID parameter created by the US.C module, this module loads the slave CPUs with the appropriate scripts SUBSTITUTESHEET and then starts the slaves processing the scripts. During a session this module records on the master CPU fixed disk the transaction timings made by the slaves and also provides a central location for storing the status reports of all the slave communication reports. Appendix C Title: Slave Program Code Modules: SP.C SPN.C TASK.C . TESTPORT.C TIMER.C TRAFFIC.C TRANS_IT.C SERIAL.H SP.H SP_DATA.H SP_GDATA.H DISPLAY.ASM DISPLAY.C DO_SCRIP.C GETJSCR.C 10.C MAKEDATA.C MEM.C OBEY.C REDUCE.C SLAVE.C SLEEP.C SP_DATA.C SP_GDATA.C SP_SETUP.C RDN.C The SP.C code module runs on each of the slave CPUs and executes the scripts assigned to each of the ports as the master CPU directs. The principle functions of the SP.C code module is to output commands to the host computer system, watch for prompts returned by the host computer system (indicating an appropriate response has been completely delivered, and time the period between the command being output to receipt of the prompt) . The other code modules listed in Appendix C are associated with the SP.C module or are code modules desirable to include during the operation of the slave CPU and/or the master CPU. Appendix D Title: Task Scheduler and Serial Driver Code Modules: TASK.ASM and SERIAL. SM These two assembly language routines are used by both the Master Program and the Slave Program to handle the operation of the serial ports and to provide task scheduling. Appendix E Title: Summary Statistics Code Module: SS.C The SS.C module provides some statistical analysis of the timing data collected by the Master Program and converts the files containing the timing information into a format suitable for further analysis. Appendix F Title: Diagnostic Software Code Module: WORM.C The WORM.C code module is used to diagnose hardware problems in both the slave CPUs and the master CPU. Desirably, this code module allows either an internal or external loopback to be performed on any serial port. It can also be used to logically connect a terminal to any port on the host computer system under test. SUBSTITUTESHEET Appendix G Title: Script Definitions Code Modules: SCRIPT.INC AUTHOR.ASM (sample script) The SCRIPT.INC module contains the definitions of the scripting language used with the described embodiment. The AUTHOR.ASM module is included as an example of a sample script. Appendix H Title: Miscellaneous Code Modules: SPKR.C T.C WHATCOM.C MK.BAT SP1L.BAT SPL.BAT SPNL.BAT SP.DAT MENUNIND.H SES_FILE.H SPN.LNK MENUWIND.C SP1.C TUNES.C The code modules included in Appendix H are miscellaneous modules which are helpful when performing functions such as compiling, linking, or maintaining the programming code. D. Conclusion. In view of the foregoing, it will be appreciated that the present invention provides an efficient system and method for carrying out computer performance evaluation monitoring of a large scale, multi-user, host computer system. SUBSTITUTESHEET The present invention also provides a system and method for computer performance evaluation which records the time taken by the host computer for completing each transaction and also easily allows for varying the type of transactions and also the transaction rate from one monitoring session to another. The present invention also represents an advance over the previously available systems and methods in that it may be readily adapted for use with a wide variety of host computer systems as well as with various numbers of communication ports on a host computer system. Importantly, the present invention provides computer performance evaluation monitoring sessions which accurately show the performance of the host computer system under actual operating conditions as well as providing monitoring sessions which can be repeatably reproduced again and again if necessary. The invention may be embodied in other specific forms without departing from its spirit or essential characteristics. The described embodiments is to be considered in all respects only as illustrative and not restrictive. The scope of the invention is, therefore, indicated by the appended claims rather than by the foregoing description. All changes which come within the meaning and range of equivalency of the claims are to be embraced within their scope. SUBSTITUTESHEET 10 15 APPENDIX A Title: Update Session I/O Code Module: US.C 20 25 30 35 SUBSTITUTESHEET US.C Tuesday, October 18, l'SBS &ag us.c UDdate session ID -files Rholling Stone . Brook Ri haπ .C) 1933 Dvπi;.. Inc. ..include "ses_-f lle.h" #ιnclude " enuwin .h" ♦.include (bsireeπs. ) ♦.include .bkeybrd.h. #ιnclude (.string. > #include <stdlιb.h> ..include .stdio.h) #defιne FALSE 0 #defιne TRUE 1 #defιne DEAD £54 #defιne UNUSED £55 ♦.define DDLabelWidth 15 /*** G L O B ή L ***/ SeεsionlD si ; int sι_updated; /* false if si not changed, true if changed ». char 5i_dtlt[S0] ,sι_ nameLSOJ : FILE *sι_fιle; char sco_d It[30] ; int termsCMaJ.TransTyDeJ ; '* number of terminals for each trans tvcs /* whicn window is visible*/ enum shown '.none_shown,desc_5hown,trans_shown,port_shown) w_shown: MENU masterM ,descM,transM,portM; WINDOW descW,transW,portW; /«** E N D S L 0 B A L S ***/ DisplayMvWindowlWINDϋW ♦ myW. enum shown my_shown; f if '.w_shown != my_εhown. C it .w_shown == desc_snown. Kβmovewindow l&αescw. : else if ι.w_shown == trans_εnown. 1 fcemoveWindow .KtransW. ; else if lw_shown == port_showR.' ftemoveWinαowl jsport w. : ) DisolayWindow imyW. ; w shown = my shown; SUBSTITUTE SHEET US.C Tuesday, October 13, 1938 Pag /**»* Description window display stuff ****/ DDLaoeI .lnt ro , char * I beI) { Wrlte indow(fcdescW,row,DDLabel ιdth-strlen(labeI) ,WHITE.'INTENSITY.Iadel) ; DDStrData(int row, cnar *data) C char *d, *none = "(none)": if (*data=='\0') d = none: else d = data; ClearRec (&descW,row,DDLabelWidth+2,l ,7S-(DDLabelWιdth+2)) ; WπteWιπdαw(£.descW.row,DDLabelWidth+E.WHITE,d) : 3 DDIntData'.int row, int data) { cnar =[£03; ιtoa(data.s.lθ) : DDStrData(row,s) ; DescLaPelsu DDLabel (0, "Machine Name") ; DDLabel U , "Memory Size") ; DDLabel (£, "Disk Size") ; DDLabel (3, "Data Base Size") : DDLabel (4, "Session Date") ; DDLabel (5. "Session Time") : DDLaDel (6, "Remark") ; DDLabel (7. "N Terminals") ; DDLabel (8, "N Trans. Types") ; DDLabelC9, "Think Time") ; DDLabel (10,"Char Throt le") ; DDLabel(11."Timeout Value") ; DescPain '.. C DDStrDat (0, si .machinename. ; DDStrData'.1. si .memorvsize) ; DDStrData(£. si .disKsize) ; DDStrDat (3. si .databasesize. SUBSTITUTE SHEET US.C Tuesday, October IS, 19SS Pag DDStrData(4, si.date); DDStrDat (5, si.time) ; DDStrData(6, si.comment) ; DDIπtDatalV, si .nterminals) ; DDIntData(S, si .ntranstype) ; DDIntData(9, si .thinktime) ; DDIntDatailO.si .charthrottle) ; DDlntDatadl ,sι .timeout) ; /**** Transaction window display stuff ****/ TransRowCol (int tnum, int *row, int *col) *row = (tnum'7)+l ; *col = (tnLim/7)*E5. DTDataiint tnum) ( char dataCIO] ; TransRowCol ltnum,&erow,&.col) ; ClearRect (MransW,row,col+3,l ,£0) ; WrιteWιndow(£_transW.rαw.cαl+3,WHITE,sι .fl lenameCtnum]) : ltoa .si .transE:-:ph'ateLtnumJ ,data,10) ; Wr11eWiπdαw(S_transW,row,col+17-5trlen(data) .WHITE.data) ltoa(si . axTransactionsCtnumJ ,data,10) ; Wrι eWιndow(&transW,row.col+-_3-strlen(dat > .WHIT .da a; TranLabelsO C char sheading = " TranType Rate Max #" ; char labeI[3Ϊ : int ,row, ol ; WπteWiπdαw .transW.O, 0,WHITE! INTENSITY,heading) ; WrιteWιndow ( £ttransW,0.£5.WHITE! INTENSITY.neacinά) : WriteWindow.ZaransW,0,50,WHITE! INTENSITY .heading) ; lapelC13=' . ' ; labelLEJ=' \0' ; for (ι=0; l (MaxTransType; ι++) C labeU0D='A'+i ; TransRowCol (l , ro» ,&.co\. ; wri tewindow lfctransw .row .col .WHITE ! I . EIM≤Π . . labe l . } SUBSTITUTE SHEET US. Tuesday, October IS, 19fc.S Pag TransPaint () int i : CIearRect (&trans ,1 , 3,7,2 . ; ClearRect (ktransW.l .23.7,£0) : ClearRect .&transW,l ,53,7,20) ; for (ι=0; l(si .ntranstype; ι++) DTData(ι); } it***, port window display stuff ****/ ***.*/ int DPCountBadl) /* return the number of dead ports */ C int l ,transtype,nbad; πbad = 0; for (i=0; l (MaxTerminal ; i++) C if (sι.termmaoCι]==DEAD) nbad++: } return '.nbad. : ) DPCount ( ) /* set the arrav -terms -' to no. of terminals for each trans type */ C int ι,transtype: for ii=0; l '.si .ntranstype; ι++. terrn=LιJ=0: for u=0; l (Ma,-. Terminal : ι++) C transtype = si .ter maoCi] ; if (transtypeoi .ntranstype) termsLtranstypeD++: ) DPNTermdnt showlabel) £ char sC5]; if (showlabel) WnteWιndow(kportW,ll ,61 ,WHITE!1NTENSITY."M Terminals: ClearRect (fcportW.ll ,71.1.3) ; ltoa (si .ntermιnals,ε,10) ; WπteWindow( portW,ll ,77-strlen(s) . WHITE, s) : DPTransDa adnt transnum) ( int per , tnum; SUBSTITUTE SHEET US.C Tuesday, October 13, 1-?8S Page char s[5J ; if ( >. (port _page==0 lr.U transnu (l ) '■ (port_page==l U transnum)=10) ) Uransnum .si .ntranstype) ) ( ClearRect (kportw. (transπum'/.10)+l ,71 ,1 ,7) ; ltoaftermsCtransnumJ ,s,10) ; writeWindowdtportW. (transnumy.lU) +1.74-εtr len is) .WHITE, =) ; perc= : else perc = ( ( long ) termεltransnumJ* (long) 100) / i long) si .nterminals : itoaiperc .ε.K 1 . : WnteWindowi&portW, (transnum'/,10) + l ,78-strlen(ε) , WHITE, ε. : 3 DPTranεiint page. 1 « page = < for first page. for εecond oaqe of tranε types * f int l,perc,tnum; char *letter=".:.".s-5J: aort_page = page; ClearRect ItiportW.l .*'.•,10,13) : tor (ι=0; n10; ι++) £ tnum = l + (page<iυ. : letterL0]='A'+tnum; WπteWindowlkportW,ι+l,60.WHITE!IN ENSITY,let er; : if (tnum<sι .ntranstype. £ WπteWιndo d_portW,ι+l ,62, HITE.si . I lenameLtπumj) DPTransDataitnum) ; DPTerminalsO £ unsigned char transtype; char lineltO]; /* ClearRec (ϊ.portW.1.4.12.54) : */ 1=0; for ιrow=0; row (12; row++ι £ co 1=0; for '. j=y; o '.50; .)++ ) £ t r ans t ype = s i . t e mήiap L l ++ j : it (j>0 υ.b .)'/.10==0) lmeLcol++J=' '; it (transtyDe==UNUSi-I ! . lιnel_col++J = .'; else if (transtype==DEAD) lineCcol+-»-2 = "K else lιneLcoι + +J= A' + trans 'pe; SUBSTITUTE SHEET US.C Tuesday, October IS, 19S3 Pag lιneCcol]='\0' ; WπteWιndow(!_portW,row+l .4. HITE. line) ; ) PortLabels'.. £ char »rιumstr="000:" ; int i : or (ι=0; ι(lS; ι++) £ if (l'/.E) numstrtl]='5' : else numstr[l]='0 ' : WπteWindowl&portW, l+l. , WHITE IINTENbl ' f Y .numstr. ; } WπteWιndow ( &portW,0, 62, WHITE! INTENSITY, "TRANTYPE # '/,") ; ) PortPain () £ DPCount <) ; DPTrans( ) : DPTermlnals() ; DPNTerm(TRUE> : /***.*/ /♦**« Auxiliary rou ines ****/ InitDataO memset (&sι ,0,sιzeof(SessionID) ) ; /* zero out si *. memset .si .termmap.UNUSED.t1aκTermιnal) : ει_updated = FMLSE; InitDisplavO £ DescLaaelsO ; DescP int () : TranLabelsO ; PortLabels(.i : PortPaint (> i int DiscardChangeεu /* return TRUE if nothing changed, or if changed and user savs o.-. US.C Tuesday. October 13. 1 SS Psα ! char aπsL i if (sι_updated) £ DialogPrompt ."Throw away changes?" ,"πo" ,ans,S) if (toupper(ansCOD) !='Y') £ Dialogf1sg("Choose 'Save'"); return(FAL5E) ; ) } return(TRUE) ; DUStrdnt row, char *promρt , char *data. int size) £ char πewdataC3003 ; DialogPrompt (promp ,data,newdata,size; ; if (strcmp(data,newdata) !=0) £ strcpv(data.newdata) ; DDStrData(row,data) ; sι_updated = TRUE; ) DUIntdnt row, char *promp , short *data) £ char datastrCt .newdatastritj : int newdata: ιtoa(*αata,datastr,10) ; DialogPromp (Dromp ,datastr.newdatast .sizeo (newdatastr) ) : newdata = atoi(newdatastr) ; if (newdatal=*data) £ *data = newdata; DDlntData(row,newdata) : sι_updated = TRUE; 3 int TranLtrToNu tchar ch! /* convert letter A..T to 0..19. return -1 it not in ntranstype range ♦/ { ch = toupper(ch) ; if (CA'(=ch) hi/, .ch .=< 'A'+si .ntranstype-1) } > return'.ch-'A') : else return(-1) ; ) TUUo dnt tnu i £ int newdata,row.col ; SUBSTITUTE SHEET J , US.C Tuesday, October IS, 1938 Page char datastrL ,newdatastrItϋ ; TransRowCol (tnum,J.row,i:col) ; /* highlight letter * 5 AttπbRect ιi/.transW,row,col ,1 ,≤,BLACK, HITE) ; ltoa(si .transE:- Ratε£tnum] .datastr,10) ; DialogPrompt ("Transaction expected rate, in clock ticks" , atastr, newdatastr.sizεof(newdatastr) ) ; newdata = atoi (newdatastr) ; if (newdata!=si.tranεEκpRate[tnum-l. £ si .transEκpRateCtπum = newdata; sι_updated - TRUE: 10 DTData(tnum) ; _ ιtoa(sι .maxTranεactioπsCtnum] .datastr,10) ; DialogPrompt ("Maximum transactions for session, 0 = unlimited" .datastr, newdatastr.sizeo (newdatastr)) ; newdata = atoi (newdatastr) : if (newdata!=sι .maxTransactιonεLtnum3) £ si.maxTransactionsCtnu ] = newdata: j_g sι_updated = TRUE; OTDataitnum. : AttπbRect i&transW,row,col,1 ,£. HITE!INTENSITY,BLACK) ; TUChange() £ 20 cnar letterCU; int tnum; DialogPrompt ("Letter of transaction to change" ,"" .letter.1) tnum = TranLtrToNumdetterEO]) ; if (tnum==-l) £ DialogMsg." — not a proper letter"); return; 5 j TUUpd(tnum) ; TUAddO £ char fnameCSO] ,*from,*to,ch; 0 lπt χ ! DialogMs (" — transaction table is filled to the Briny return; ) betPileNameC'Name of Script *ι le" ,scc_d I .fname) ; DialogMsgC — no script found or cnoεen") ; 5 return; SUBSTITUTE SHEET l US.C Tuesday, October IS, 1988 Page ) /* back up to end of path, if any */ for (ι=strlen(fname)-l; ι)=0 kit fna eCi] !=' :' && fnameCiJ !='\\' ; 5 i—) ; /* copy file name (minus the extension) */ from = -tname+ι+1; to = εi .+ι lenameL ' si .ntraπεtvpeJ ; while '.. * from!=' \0") vv <«trom'='. • ..■ <. en = »from++; *to++ = toupper(ch;: J 10 *to = '\0-; /* check for already in table */ for (ι=0: l(si .ntranstype h.k strcmp(si . llenameCsi .ntranstype],sι .fllenameCi]) !=0; ι++) : ι+ (ι>.sι .ntranstype) £ DialogNsgC — that script is already in the table"); -. c return; 15 j si .transExpRatetsi .πtranstvoe] = 0; εi.maxTranεactiαnεlsi.ntranstype] = 0: DTData(si.ntranstype) ; TUUpd(εi.πtranstype) ; si.ntranstype++; si_updated = TRUE; DDlntData(8, εi .ntranstype) ; 20 } TUDeleteO C cnar letter[13; int l ,tnum: 25 DialogPrompt("Letter of transaction to delete" ,"",letter,1) ; tnum = TranLtrToNumdetterCO]) ; if (tnum==-l) { DialogMsgl" — not a proper letter"); return: ) /* remove trom array, slide everything else forward */ si.ntranstype—: __ for (ι=tnum; l .εi .ntranstype; ++) C strcpv(ει . ltenametiJ.εi .fιlenamsLι+13. : si.maxTransactlonsCi = si .maxTransactιonsLι+1j; εi .traπsExpRateLiJ = εi .transE.:pRatel_ι- t -l] ; ) TranεPaint .; : DDIntϋata(8, εi.ntranεtype) ; ."* remove from terminal map, alter everything above, change ♦ for (ι=0; l(NaxTerminal: ι++) C 5 if (εi.termmaptι]==tnum) C SUBSTITUTE SHEET -42- US.L Tuesday, October IS, 1*«5S Page si.nterminalε—: sl.termmaoCl]=UNUSED; ) else if ιει .termmapti])tnum kk si .ter mapCi (MaxTransType) si.termmapti]—; } D01ntData(7, si.nterminals) ; sι_u dated = TRUE: ι PURowCol unt pos, int *row, int *col) £ *row = (poε/50) + 1 ; *col = (pos*/.50)+4+( (pos!.50)/10) ; ) PUPosdnt pos) C char sCS ; PURowCoI (pos.__ro ,L.col; : CursorϋtftfcportW. ; ClearRect i&pαrtW,15,74,1.3' : ιtoa(poε,s,10) ; WπteWιndow(t_portW,15.77-εtrlen(s) .WHITE,s) : WπteWindowikportW,row,col ,-1 ,"") ; CursorOn(feportW) : PUWπtednt poε, char ch) C int row,coI; char sC23 : PURowCol(pos,&row,&coI) ; s[03=chs sC13='\0'; WrιteWιndow(8_portW,row,col ,-i,s) PUUnusedtint termno) C int oldtrans; oldtrans = εi .ter mapLtermno3: si .termmapLtermnoJ = UNUSED; /* unused */ if '.oldtrans'.si .πtranstype) . termεColdtrans]—; si.nterminals—: sι_updated = TRUE; SUBSTITUTE SHEET US.C Tuesday, October 13, 1988 Page PUAdddnt termno, int transtype) C εi .termmapCtermno] = transtype; termεCtranstypeJ++: si .ntermιπals++; sι_updated = TRUE; } PUEdltd { int done, uroos,newooε,updtdιεp ,chrdy,key,transtype.1 ,oIdnterm: cnar ch; DialogMsgi" — numDer of trans types is zero. Enter trans types first.") return: 3 DialogMsg("Use arrow eys, tacs, '.PgDn), or transaction letter ιa,&,..) . ad port. '.' = unused Dor . (Esc = αuit") : WriteWir.dcw.&portW,15,61,WHITE!INTENSITY,"Crsr Port ft:"; ; curpos = 0: PϋPoε'.curpos) ; done = FALSE: whi le ( !done) C updtdisp = FALSE: newpos = curpoε; ,. oldπterm = si .nterminals; ch = kbgetkey(∑_key) ; ch = toupper(ch) ; if <key==72) newpos-=50; /* up arrow */ else if (key==77. newpos++: /* right arrow */ else if (key==75) newpos—; /* le+t arrow */ else if U:ey==S0) newpos+=50; /* down arrow */ else if (ch==9) newpos+=10; /* tab «/ else if (κev==15) πewpos-=10; * ba i: tab */ else if (key—115) newpos-=10; /* control left arrow ♦/ else ι+ (key==116) newpos+=10; /* control right arrow *.' else if (ch==S) newpos—; /* backspace * / else if ...ey==3l) { / * PσDπ */ DPTranε(l-port_page) ; PUPos(curDos) ; 3 else if .' ' A'(=ch kk ch( 'ή'+εi .ntranstype; C /* trans »/ PUuπuseo(curpos) ; PUAdd(curpos,ch-'A') ; PUi'J : t e i curpos . h ) ; newρos++ ; updtdisp = TRUE: ) else if .ch=='x'! C /* dead port « ; SUBSTITUTE SHEET , US.C Tuesday, October IS, 19&3 Page PUUnused .curpos) ; si .term apLcurposJ = DEAD: PUwπte. urpos,ch) ; updtdisp = TRUE: newooε++; } else if (ch=='.') ( /* unused port */ PUUnused(curpos) ; PUWrite(curpos,ch) ; updtdisp = TRUE? newpos++; j else if (ch==£7) done = TRUE: if (updtdisp) C CursorOff(kportW) ; for u=port_oage*10: i φort_page*10+10: i++; DPTransDatad) ; if (oldπterm!=sι.nterminals) DPNTerm(FALSE) : CursorOn(S-portW) ; ) curpos = (newpos+MaxTerminal) 'A MaxTerminal; PUPαs(curpoε) ; 3 /* end while */ ClearRect (kportW.Id. l,l,lέ) ; DialogRemoved ; CursorO f(kportW) ; PulermNumd £ cnar lettertlJ: char datastrCfc] .newdatastrt€ ; int newdata; if (si .ntraπstype==0) C Dialogflsg(" — number of trans tvoes is zero. Enter trans vpe≡ first."): return: DialogPrompt ("Letter of transaction" ,"",letter,1) ; tnum = Tran trToNu detterLO]) ; if (tπum==-l) £ DialogMsgC — not a proper letter"); return: } ιtoa(termsCtnum], atastr,10) ; DialogPrompt ("How many terminals" ,datastr.newdatastr,sizeof(newdatastr) ) ; newdata = atoi (newdatastr) : if (newdata==termsCtnum]) return; if ( si .ntermιnalε+newdata-termsLtnum])MaxTermιnal-DPLountBad() ■ ( DialogMsgC — exceeds maximum allowed terminals"!; return: ] for ιι=0; uMaxTerminal ; ι++) { SUBSTITUTE SHEET 1 US.C Tuesday, October IS, l'SSS Page PUUnused d) ; PUWrited,' . '.' ; 5 j * for '.ι=0: (l .MaxTermin l) kk (newdata)O) ; ι++) £ if (sι.termmaptι]==U USED) £ PUAddd.tnum) ; PUWrited , Α'+tnum) ; newdata—; j 3 0 DPT ' rans(port_page) ; DPNTerm(FALSE) : PUAlterd £ int l ,j ,trιum,nterm; 5 char datastrit.j ,newdatastrL6] ; int newdata; float ra io; int newtermsCMaxTransType]; if (εi .ntermιnals==0) £ DialogMsgC — numPer ot terminals is zero. Enter numders first.". 1 : return; } 0 if (si .ntranstype==0) £ DialogMsgC — number of trans types is zero. Enter trans tvpes first."): return: ) ltoa(si .ntermιnals,dataεtr,10) ; DialogPrompt ("Change total number ot terminalε to" ,datastr .newdatastr ,sιzeo+ tne taεtr) ) : newdata = atoi (newdatastr) ; 5 if ,newdata==si .nterminals) return; if (newdata>MaxTermιnal-DPCountBad()) £ DialogMsgC — exceeds maximum allowed terminals"); return; } for (ι=0; i (εi .ntranstype; ι++) newter sLi] = termsC ]; ratio = (float/newdata/ (float. si .nterminals: for d=0; l(MaxTerminal ; ι++. ( Q if .si.termmapLiJ ! - PUUnused(l) ; PUWrite .' . ■ . ; ) l = '.'; for =0; j(si .ntranstype; ++) £ nterm = ratio* ( (float;newtermsCj])+0.5; while (nterm)O kk l(MaxTerminal £ 5 if (si .termmapLi !=DEAD) £ SUBSTITUTE SHEET US.C Tuesday, October IS, 1938 Page PUAdd(i .,ι) : PUWrited , 'A'+jj ; nterm—; 1++: } ) DPTranε(port_page) ; DPNTer (FALSE. 1 ; /****/ /*»** Main routineε. ****/ LoadFileO t if (DiεcardChanges()==FALS£) return; GetFile ameC'lMame of Seεsion ID file" ,=ι_d I ,sι_fname) : if (-«sι_fname=='\0'! C DialσgMεgC' — no file loaded"); return: ει_fιle = fαpen(sι_fname,"rd") : if (sι_ ιle==NULL) (DialogMsgC — can not open file"); return: } freadi&si .sizeo (SessionID) ,1,si_flle) ; fclose(si_file) ; εi_updated = FALSE: DescPaint () ; TransPaint () ; PortPaint() ; DiaiooMεαC"Loaded") ; SaveFileu C DialogPrompt ("Name of Session ID flie" ,eι_fname,=ι_ name, sizeo (sι_ name)) ; if (>εi_fname=='\ύ / ) CDialogfsg(" — no file saved"); return: j DialogMsg("Saving...") ; si_file = openιει_ name,"wb") ; if (sι_fιle==NULL ) (DialogMsgC' — can not create file"); return: } fwrite(&si .sizeo (SesεionID) ,1,si_ ile) ; I m tCommand i i if nεcardChangeε ( ) ==FALSE) return ; lnitData O : lmtDisp lay () ; TransPaint ( ) ; DialogMsg ("Zhe data , she 's ah zappahrooed" ) ; SUBSTITUTE SHEE = US.C Tuesday. October 18, 198£ Pace DescUpdateO char cm : DiεplayMvWιndow(ϊtdeεcW,deεc_shown) ; oescM.lastLolumn = 0: DiεplayMenu .lideεcM) ; cmd = ' ' : while (cmd != 'Q') ( cmd = &etMenu(U_deεcM) : DialogRemoveO ; if (cmd == 'N') DUStr (0,"Name of machine" ,ει .machinenamε, sizeof(si .machineπa e) ) : else if (cmd == 'M') DUStr (l ,"Sιze of machine's memory" ,ει .memory≡ize. sizeof(si .memorvεize) ) ; else if .cmd == 'D') DUStr .5,"Size of machine's disk" ,sι .dis size, sizeof(si .disksize)) : sise if (cmd == 'F') DUStr 13."Size of the data base" ,ει .databasesizε, sizeof(εi .databaεeεize) ) ; else if (cm.d == 'R') DUStr(&,"General remark adout sesεion" ,ει .comment , sizeo (si .comment) ) : elεe if (cmd == '0') DUlnt ( 9,"Inter-operatιon think time, in clock tιcι:ε" ,ksι .thinktl e) : else if (cmd == 'O DUlnt ( 10,"Inter-character wait time, in clock ticks" ,S.si .charthrottle) ; else if (cmd == 'T') DUlnt (11 ,"Time to wait before signaling 'timeout', in clock ticks", ksi .timeout) ; } RemoveMenu(&descM) ; TransUpdateO ( cnar cmd; DisplayMv indow.£.transw,trans_snown. transM.lastColumn = 0: DisolayMeπu .ittranεM) : cmc = ' ' : while (cmd != ' ') C cmd = betMenu(&tranεM. : DialogRemoveO ; if (cmd == 'H') TUAdd( ' : else if (cmd == 'C! TUChange() ; e ι se i r cmC j == 'D') TUDeleteO: SUBSTITUTE SHEET 1 US.C Tuesda y , October IS, 19fc'S Page ) RemoveMenu it-transM) ; } 5 PortUpdateO ( char cmd ; Dis layMyWιndow(&oorttø,port_shown) ; PortPaint () : portM.lastColumn = 0; 0 DιεplayMen d.portl'1) : cmd = ' ' ; while (cmd != 'Q') ( cmd = GetMenu(kportM) ; DialooRemoveO : if (cmd == 'E') PUEditO ; else if (cmd == 'J') PUT ermiNum ( . ; else if (cmd == 'A') PUAlterO ; 5 else if (cmd == 'IM ') DPTransd-port _page) ; Re moveMenu .fctransM) : DD ιIntData(7. si.nter ■ miπals) ; mainO ( 20 char cmd ; int cur_o f ,cur_row,cur_col ,cur_hιgh,cur_low; scpclr(;; /* clear screen */ /* save state of curεor */ cur_off = εccurεt ( .cur_row,kcur_col ,&.cur_hιgh.i.cu.r_low. 25 /* initialize data */ InitMeπu iπo () : strcDV(sι_df It ,"* .ID") ; sι_fname[0] = '\0' : εtrcoy(scp_d It ,"» .SCP") ; w_εhowπ = noπe_shown: * make menus */ 30 MakeMenu(*,masterM. "LoadrLoad a sesεion ID file", "Deεcπptιon:Update sesεion description fields". "Tranεactιoπε:Update transaction table", "Ports:Uodate port table", "Save:Save a sesεion ID file", "Init.Initialize session ID data to nulls", "Quit", "") : J3 MakeMenu(&descM, <__. ___.-««_. c 1 US.C Tuesday, October 18, IΪ&B Page "Name.Machine name being tested". "MemoryiMemory size of machine", "Dis iTota ' l disk size" , "Fιles:Data base size", 5 "Remark:Any ol' thing ya wanna say", "ϋper thiπkilnter-operation think time", "Char waιt:Iπteι—character wait time", "Timeout :Time to wait before signaling inactivity", ""); MakeMenu(ktransM, "Add: dd a transaction type", 0 "Change:Change transaction rate and max trans". "Delete:Delete a transaction type", "Quit", ""); MakeMenu(&pαrt , "Edιt:Modify the table directly", "Terminals:Set the number of terminals for each transac ion". "Alter:Change total terminalε, maintain same percentages", s "Nex :Ne.it page of transaction tvoes" , "Quit", ...... /* make windows */ Makewinαow .i;descw,l__,78." Sesεion Description ", ' .'.1.' ; Ma ewindo .ktranεw.8.73," Transaction Tvoes ",?,£. ; Maκewindow(ϊ_portW,13,7S," Port to Transaction Map ",.',1); 0 InitDataO ; InitDiεplayO ; /* the main loop */ DιεplayMyWindow(&.descW,desc_shown) ; cmd = ' ' ; DιsplayMenu(ϊ_masterM) ; while.cmd != 'Q') ( 5 cmd = GetMenui&masterM) ; DialogRemoveO ; if * (cmd=='L') LoadFileO; else if (cmd=='S') 5aveFileC. ; else if (cmd=='I') InitCommandO else if (cmd=='D') ( RemoveMenu(&masterM) ; DescUpdateO ; o DisplayMenu'.&masterM) ; else if (cmd=='T') ( RemoveMenu (&masterM) : TransUodate O ; DιsplayMenu (^masterM) : . ) else if (cmd== 'p - ) ( RemαveMenu .kmasterM. : 5 PortUpdateO ; SUBSTITUTE SHEET US.C Tuesdav, October IS, 1"3S8 Pass DiεplavMenu(i:maeterM) ; } else if (cmd== -Q ' ) if (DιεcardChanges()==FALΞE. cmd=- : ) /* restore cursor */ scpclrO; * clear screen */ sccurset (cur_row,cur_col) ; scpgcur(cur_off,cur_hιg ,cur_low,CUR_N0_ADJUST) : SUBSTITUTE SHEET 10 15 APPENDIX B Title: Master Program Code Module: MP.C 20 25 30 35 SUBST I TUTESHEET l MP.C Wednesday, August 31, 1'5SS Pag /* Master Processor (C) copyright 1988 Dynix, Inc. written by: J. Wayne Schneider date: 26 July 1938 5 This program controls the slaves in the RHOBOT network. */ #definε FALSE 0 #define TRUE "FALSE #ιnclude (bios.h) 0 (stdio.h) ♦.include (io.h) #include (malloc.h) FILE *εtream; long length; char *meεsage_buff: char *meεsaςeC5]C10-l; char *rx_buffer; mainO C int ι,t,numread; char *mp; stream = open("ID.DAT","rb") ; if (stream == NULL) C putsC'Can't open the ID.DAT file!"); exit(2); ) length = filelength(fileπo(stream)) ; if ((length == -ID i (length > 32767L)) C putεC'File size out of range!"!; message_buff = malloc((int)length) ; i-f lmessage_buff == NULL) C putsC'Not enough memory for messages!"); exit(4) ; ) numread = fread(message_buf ,1,(int)length,stream) ; i (numread != (int)length) C putεC'Error reading ID. AT file!"); exit(5) ; } mp = message_bu f; do { switch (*(mp++)) c case 1: ι=0;Dreak: case 10: i=l;break; case 17: i=£;break; default: continue; } MP.C Wednesday, August 31, 1988 Page t = * (mp++) ; messaged3Ct3 = mp; while(*(mp++) != NULL) ; ) while (mp < (message_buff + numread)); serlaI_in11 (1 ,9600, x03,OxϋB,O 1) ; rx_buffer=malloc(2048) ; if~(rx_buffer == NULL) C puts("Not enough memory for rx_buffer !") ; seπal_ιnιt_ιnterrupt (4 ,rx_duffer ,2048 , 1 ) ; do process O ; whi le (TRUE) : serιal _ιnt_release (4) ; J int processi) I int t; unsigned char c; if lchkbu ()) C c = sgetc <>• swιtch(c) C case 1: printf ( "PROCESS y.s\n" ,message[0]Csgetchar03) jbreak; case 10: print ( "REPORT '/.s\n" .messaged3Cεgetchar03) ;break; defau It: printf("char is J.i\n" ,c) ;break; 3 if (kbhitO) I getchar<) ; 3 * } int sgetcharO C while< lchkbuf() ) reschedule0 ; return sgetc() ; 3 int rescheduleO { SUBSTITUTE SHEET APPENDIX C Title: Slave Program Code Modules: SP.C 1 A 0 υ S TA PN SK- C .C TESTPORT.C TIMER.C TRAFFIC.C TRANS_IT.C SP.H SP_DATA.H 15 SP_GDATA.H DISPLAY.ASM DISPLAY.C INTERϋPT.ASM DO_SCRIP.C GET_SCRIP.C 10.C MAKEDATA.C 20 MEM.C OBEY.C REDUCE.C SLAVE.C SLEEP.C SP_DATA.C SP_GDATA.C 25 SP_SETUP.C RND.C 30 35 SUBSTITUTESHEET 1 SP.C Tuesday, October 13, l'?SS Pag /*.**** ******************************************************* ************ * Slave Processor for the RHOBOT 5 . copyright 1933 yπix. Inc. written by: J. Wayne Schneider date: 1 September 19S≤ Memory model is COMPACT This c-rαgram has no output tc the screen. All commands must come in -from C0 1. All output goes to C0M1 aε well. The 10 serial ports __0-E7. 30-3?. 40-47. 50-57 are used for host script processing, (numbers are octal) This program does not even require a data ile -for initialization. That implies that it must test the com ports to see wnich ones are working. Wε will assume we al avs have 3Ξ. Any that are not working or αon't ε.-:ιst will be flagged as bad and net used. T C Internally, we address the ports in octal as £0 through 57. For all reporting, we reference them as 0 through 31. These numbers also coincide with the 'task_ιti' that is controlling the port. ****.*******.**.**.*********************************************.**********»***/ ♦include (stdio.h) ♦include <malloc.h> ♦ include .εtrmα.h. 20 ♦include "sp.h" ♦include "xrhαbot\sp_data.h" ♦include "sp_gdata.h" ffinclude .h" ♦include "task.h" ******»*»****«*«4**««»«***ft4(«*j.«lf*|r*««*«**«)|*«*««*««»«««k«»*«*^»»«»»*».*. 5 constants »***********.***************************************.******.******.*******...' mt const MASTER_P0RT = 1; /* com port to master * /**************.****************.***,**.**.*.**********.*************.******** ** *• procedure prototypes ft**************************** a**************** ***.*******. *****.********•*. > 0 vci-j read_command_lιne (mt .char *Lj): void hardware_setup(voιd) ; void ιnιtιate_5cπpt_tas..s (void) ; void traff ιc_packetε(voιd) : void ciean_up (void) : l***.*******************************************************.**,****,***,,*!;,, MAIN PROCEDURE 5 ***************************************************** *******t*t*******f**' SUBSTITUTE SHEET SP.C ϊueεαav. ϋctoper 13. l^ai aαe mainlarge,argv) int ar c; char *argv[]; { read_command_line(argc,argv) ; /* get number_of_ports from co line ♦/ hardware_εetupi; : /* fixup clock k CUM1 which MUST wr-rl *: imtιate_script_tasks<) ; /* do all the task startup stuff * reschedule() : /* let everyone init com port */' traffic_packets() ; /* traffic packets between mstr ≡lv *ι ean_up() : * shut it all down for clean stop */ 3 procedure HARDWARE_SETUP Trie clock tick counter must be set to zero for our purposes. CO l is teεteα with an internal loooback. It MUST work or we can't go on. If it fails, we will display an error message and give a =ad tune. If it succeeds, we clear the dis lay and give a cheerful tune. He also must initialize the com port and it's interrupt. *******************.***.********************.*******.*****.**.******,********/ void hardware_setup() C char far *rx_buffer; /* tιmer_ιnιt () ; */ /* run timer int at S hs »/ w ile . t eε t _ or . MAST ER_P0RT ) ) /* test the port *.' diεolav."C0Ml BAD") ; sad_tune (. : i displaysignature) ; /* clear the disolav * chιrrup_tune'.) ; if irx buffer == NULL) ( dιsplay("_fmalloc") ; exit ( 1) : ser ι a 1 _ι n ι t . MA5TER_P0RT , _S_DATA, DTRIRTSI0UT2, ER 1, rκ_buffer,Rx_6UFFER_SlZE,0) ; serial init interrupt(MASTER P0RT,0) ; SUBSTITUTE SHEET SP.C Tuesday, October 18, 198S Page I**************************** ********** ************** ****** * ** ***** * *** ** * orocedure READ_CUMMAND_LINE The command line is checked for argument. There can be none, one. or two arguments. One argument would be a signature to display in the front panel. The other argument would be numeric and represent the number of ports to utilize. The default port count is 32 and tne default signature is blank. Either argument can appear in either position. void read_com.mand_i.ine.argc,argv) int argc; int ι= : char butfC'E : switch (argc ι. case 1: break; / ♦ no argument given » Default; » two or more arαumeπts civen «. £ l = atoi (argvCS]) ; if ii != 0) * C signature = argvll]; brea ; 3 else signature = argvCS] ; 3 /* fall thru tc get arc 1 * ! case E: /* one argument given */ { l = atoi largvLl]) ; if '.l == 0, signature = argvL13; 3 } ι+ . ,ι >= l) kk (ι .= 32) ) c number_of_ports = i ; sprιnt?'.ouff ."V.έd PORTS" ,u ; display .buff. : sleep On. ; disp lay(signature) ; '* set lsolav to ae ault » SUBSTITUTE SHEET 1 SP.C Tuesday, Q tsbsr li', l'?SS c -a 5 /»»»_ !l »» 4»ll4H_«»IHilU>lliU*«__ll«*»**»*_*»»4l_)lll»4* ! m4 44 4(l»« 1 4444444 4 44» procedure IN1TIATE_SCRIPT_TAS S 5 Allocate stac. space and set up all of the task control blocks for the script processing tasks. We also set ourselves uo as a task and determine the maximum stacl. size oased on the number of ports. ****************************** * ************* **** : * .* * . * . * * ** * *** .** * . *** **** * * * , void ιnιtιate_scπpt_tasks(. 0 ιπt i : char near *εtack_ptr; unsigned εtack_ειze: /> stack eize iε near heap εpace divided by portε. Leεε 2 for overhead and forced to an even number «/ stack_sιze = ((_memavl<) / number_of_oortε.' - 2) k xFFFE; 5 first_task.titcbC.-E]) : /* init ourselves as a task *. for u=0;ι<number_ct_oortε;ι++) /* now init the other ta=κs • • ■ { εtack_ptr = _nmalloc(stack_sιze.' ; /* get a new stack »/ if '.stack_ptr == NULL. C dιεplav("_nmalloc") ; " tcbtι3.taε.:_statuε = TASK_5TATϋ _EXl : continue; create_taεk ii.tcdl.i3 ,stack_ptr ,εtack_size,εlave,ι.' : ) /********* * ** * ********************************** * ****** * * ** **** * . *** * ** * ** 5 procedure CLEANjJf-- Fix uo the neceeεary things before we exit. Those things are the clock and the serial interrupts. *************************************************************************/ void clean_up() 0 Cc r* tιmer_undθ'.) ; * .- • * fix the clock ► serial_init_interru.pt ulAS7L_P_P.Ϊ,i.' : * serial interrupts * ' for(i=0;l<number_of_ports;ι++) serιal_ιnιt_ιnterruptu+017.1) : ) 5 SUBSTITUTE SHEET -59- P.N.C Tuesday, October IS, 1983 Pag ■ * Script Processor tor N ports witnout a maεter .C) copyright 1 S8 Oyni. , Inc. written by: J. Wayne Schneiαer dats: September 13SS 3P n 5cπpt_tιle_name Lscr:pt_arguments...] I<data_fI ' .enameJ This program reads the script file specified on the command line and processes it on "n" ports. Data entry can be specified with redirection. ( data_filename. A string argument may be passed to the script processor to be recognized as AR&l. AKDS, ... ARG7. The ports must be PCSS-έ ports. */ #defme TAS.._STATUS_EXIT 0x80 .. induce ( .Pιos.h> #ιnclude <conιo.h) #ιnclude .malloc.h) #ιnclude .stdio.h. ttinclude <bscreens.h> #mclude "sp.h" #ιnclude "s _clata. • ' ..include "sp_gdata.h" #ιnclude "seε_fιle.h" struct t_str gtrans; struct ( cnar far *next : cnar far «stacι.; int stack_lιmιt; int tasι:_status; 3 tcbtSS'J: long length; char «scπpt; char <*targv: mainiargc ,argv) int argc; char «argvU; C int l ,j ,number_of_por s, flag; unsigned εtack_sιze, stack_ptr; trans_ιnιt .&gtraπs,kglobal) ; if .argc < 3> C outs ."Specify a count k script tile to process!"); SPN.C Tuesday, October IB, 1983 Page putsC'SPN n scπpt_f ile_name [script_arguments...3 C<data_f llenameJ") ; exit(l): ) number_of_ports = atoi (argvClD) ; script = get_scrιpt (argv[Ξ3.ϋtlength ,op_id_msg) : scpclr () ; = ιop_ιd_msg[0] == NULL) ? 15 : 9 + strlen(op_id_msgtO]> ; sccurseUO. (80 - i) / £); printf ("SCRIPT - fcs" ,op_ιd_msg _l) ; ses_fιle = fopen ."SPN.OP" ."wo") ; if (ses_ ιle == NULL) perror ("open failed"): err_fιle = f open ."SPN. ERR" ,"w") ; if .err_ ιie == NULL.' perron "error open failed".'; serιal_port_εetup .πumoer_of_ports. : sccurset (l-ii* + 4,tι/lt.) « 40): print ("<πo port) " ; 0 tιmer_ιnιt () ; ;*■ change cloct. to 2 icks--seccnc ♦ targv = i.argvl≤ : * εetuo argv pointer for tasks * .' fιrεt_task<£.tcb[323) ; /* init ourselves as a task */ ' 5 stack_sιze = (_memavl() / number_of_ports - 2) k OxFFFE: sccurset (1 ,2<_.) ; printf("Stack size for tasks is y.d\n" ,stack_εize) ; for .ι=0;ι<πumber_of_pαrts;ι++) £ if igood_port£i+02 3) C stack_ptr = (int) _nmalloc(εtack_sιze) ; /* get a new stack */' Q if (stack_ptr == NULL. printf("Not enough εtack memory tor continue; } create_taε._ tϊ.tcbϊι 3 ,εtack_ptr ,stack_sιzs, aεk,ι.> ; else tcbCι3.task_status = TASk._STATUS_ExiT; 5 SUBSTJTUTE SHEET SPN.C Tuesday, October IS. 19SS Paα reschedule() : /* let everyone init com before intε */ tor .ι=0;ι .number_o+_ports;ι++) » enaole only needed interrupts */ if .good_portL1+0203) serial_ιπιt_ιnterrupt (OSO+i ,0) ; sccurset .24.0) ; printf ."press Esc to exit:"/; do . /* wait tor tasks tc complete * . if '._Pιos_kevbrdi_K.EYBRB_F.EADV) ) if ( ichar;_bio5_.:eyord ι_KEY_.HD_READ) == Oκlp. break; /* break from 'do' loop ♦/ reschedule() ; flag = FALSE; tor (ι=0;ι .number_ofj_orts;ι++. if ( !tcbCι3.task_status ) C flag = TRUE; break; * break from for loop */ ' J whi le (flag) ; for ( i=0;ι<number_of_ports;ι++) /* disable only needed interrupts «/ if ιgood_portC1+0203) serial_ιnιt_ιnterrupt (020+i ,1) ; for =0;i<number_of_ports;ι++) fprιntf(err_file,"performance %ϋ Αύ\n" ,ι+l ,performancε_check[ι+0£03) ; tιmer_undo .. : fclose(seε_ l le) ; ♦close .err_file) ; sccurset '.22,0) ; J /* TASK, routine is here. We hope it is re-entrant. */ task(taεk_ιd) int task_ d; C struct t_εtr trans; char * ΓΆ buffer: r::-:_b ffer=mal lcc .2048) ; 1+ (r.:_buffer == NULL; ( puts("Not enough memory for rx_bu fer " } memset ιrx_buf fer ,0 ,2048) ; εeπa l _ιnιt ιtask_ιd + 020 ,9600 ,0x.03 ,0x0B ,ύxl ,rx_buf fer ,2043 , IGNORE NULL) SUBSTITUTE SHEET SPN.C " luesday. October la, ΪVHB Pag trans = gtranε; do_εcπot (task_ιd + 020,εcript ,length,tarαv,rx buffer + 'S.i.traπε. : 3 /* Terminal routiπeε here replace communication to master * void process'.co x.numb) int comx, numb; { comx -= 020; sccurset (comx%16 + 4, (comx/16) * 40 + 3); printf .'"/.-lύ.lOε" .op_ιd_msg[num ) : J ~ int report icomx,numb) int comx, numb; C char c; comx -= 020; sccurset lcomx!4l6 + 4, icomx/16) * 40 + 14); printf(".-20.20s".εtatuε_msg£numb ) : if'.numb == ≤. 1 i /* sccurset (21 ,'.'.' ; printf("A = abort, anything to continue ?") ; */ c = 'A': /* toupper((char) _bios_keybrd(_. : ,EYBRD_kEAD) . : */ /* scclrmεg<21,0,30) ; */ if (c == 'A') sccurset (comx'/.16 + 4, (comx/16) * 40 + 34); printf("ABORT") : return TRUE; 3 return FALSE; } void check_poιnt(comx,op_id,op_time,wall_time) int comx, op_ιd: long op time, wall time; £ TimingRec t ; int port; port = comx - 020; sccurset (portU6 * 4. (port/16) * 40 + 14): if (op_id == 0) printf ("TRANS-tm y.Sld JiSld" .OD_time,wall_tin.e. s elεe oπntf ("\xFB 1.-6. *s * /.5ld ..Sid" .op_ιd_mεgLoc_idJ ,op_tιme.waι l_tiins. t .ter no = comx; t .opid = oρ_ιd ; ♦..stopwatch = oo time; 1 SPN.C Tueεday, October 13, 1933 Page t.walltickε = wall_tιme: fwπtel&t, εizeof(IimingRec) , 1, εeε file); } 5 int get_data(var) char varClOHSO] : { char «back; for 11=1 ;KlO:ι++) ( 10 sccurset .21.0. : o intf ("getvar:") : bad: = gets(varLι ) ; εc lrmsg(21 ,0,30) ; if (back == NULL) return EOF; if ( strcmp ( varCi],"END") == 0) return EOF; ι+ (strc p .varli] ."") == 0) break: ) τ_g return NULL: int wait .+or_operatorl) C /* sccurse .21 ,0) ; printf("Waiting for operator. Press any kev:"); _bιos_kevbr (_KEVBR _READ) : _ εcc lrmsg '.21 ,0 ,30) ; * / 20 3 int do_exιt (comx) int co :-'.: ( comx -= 020: sccurεet (comx)il6 + 4, .comx/16) * 40 + 35); printf("EXIT") : 25 return TRUE; j 30 35 SUBSTITUTE SHEET -64- TASK.C Monday, October 3, 19E Paαe struct ( char far *πext ; char far *stack; int εtack_lιmιt: int task_εtatus: ) tcbLSBJ: long length; char *script; char «*targv; int task (mt) ; mainO mt l ,j , number _of_ports, flag; unsigned stack_sι:e, stack_ptr: trans_ιnιt ι&gtranε,ε.global) ; number_of_po tε = 32; εcript = get_scπpt (argvC2J ,&length,op_ιd_mεg) ; scpclr() ; i = (oo_ιd_msgC03 == NULL) ? 15 9 + strlen(op_id_msgC03) ; sccurseύo,(80 - i) / S); printf("SCRIPT - 5.s",op_id_msgC0]) ; ,"wb") ; perrorC'open failed"): err_fιle = fopen("SPN.ERR" ,"w") ; if (err_fιle == NULL) oerror("error open failed"); seπal_port_setup (number_o _ports) ; for ( ι= ;ι (number of _ports;i++) C sccurεet (i'/,16 + 4,(ι/lέ) * 40); printf("*/.2d ".i+D : if ( !good_por i+<__03) printf("<no oort>") : tιmer_ιmt () ; /» change clock to 20 ticks/second * / targv = karςvL32 ; /* εetup argv pointer for tasks * / fιrst_task ( l.tcbC323 ) ; /* init ourselves aε a taεk «/ stack_sιze = (_memavl() / number_of_portε - 2) k OxFFFE; SUBSTITUTE SHEET TAS .C Monday, October 3, 1988 Page sccurset (1 ,26) ; printf("Stack size for tasks is */.d\n" ,stack_ειze) ; for (ι=0:ι<number_of_portε;ι++) ( c if (qood_portCi+020]> { εtack_ptr = (int) _nmalloc(stack_size) ; /* get a new stack ♦/ if (stack_ptr == NULL. { printf("Not enough etack memory for Xd\n",i); continue; } create_task(&.tcb[i] ,stack_ptr ,stack_size,task,i) ; 10 - j else tcbti].taεk_status = TASK_STATUS_EXIT; ) rescheduleO ; /* let everyone init com before intε </ for (ι=0:ι (numθer_of_ports;ι++) /* enable onlv needed interrupts » 15 if (good_port[i+0203) seπal_ιnit_ιnterrupt (020+i ,0) ; sccurset (24,0) ; orin ("press Esc to exit:"); do ( /* wait for taεkε to complete */ lf (_bιos_keybr l_KEYBRD_READY. ) 20 if ((char)_bιos_keybrd(_KEYBRD_READ) == Oxlb) break: /* oreak from 'do' loop *■/ rescheduleO ; flag = FALSE: for (i=0;i<number_of_portε;ι++) if ( !tcbCi].taε.._εtatus ) C flag = TRUE; __ break: /* break from for loop * } whl1ε ( lag); for /* disable only needed interrupts */ if (good_portύi+0203) seπal_ιπit_interrupt (020+1 ,1) ; 30 for (ι=0;ι(number_of_ports;ι++) fpπntf (err_f ils, "performance '/id '/.d\n" ,ι + l ,oer+ormaπce_crιeckCi+0203i j tιmer_undo() : fclose'.εeε_f ile) ; fclose(err_f i le) ; sccurset (22,0) ; } 35 SUBSTITUTE SHEET TASK.C Monday, October 3, 19SS Pag /* TASK routine is here. We hope it is re-entrant. */ taεkltas. _ιd) int task id; < struct t_εtr trans; char *rx_bu fer; rx_buffer=malloc(2048) ; if (rκ_buf er == NULL) C puts ("Not enough memory for rκ_bu er !") ; ) memset (rx_buf fer ,0,2048) ; seπal_ιnιt (task_ιd + 020, "3&Q0.0x03, OxOB, Oxl ,r _puf fer ,2048) : trans = gtrans; do_εcπpt (tas _ιd + 020, script , length ,targv,rx_buf fer + 9, ranε) ; } /* Terminal routines here replace communication to master *• void process(com.*.,numb) int comx, numb; £ com- -= 020; sccurset (co :. VΛB + 4, (comx/16) * 40 + 3); oπntf ( " , /ι-10.10ε",op id msoEnumbJ ; ) int report (comx,numb) int comx, numb; { char c; com.- -= 020: sccurset lcomχj.16 + 4, (comx/16) * 40 + 14); printf(" / ι-20.ε s",εtatuε_msgi:numb]) : if(numb == 2) C /* sccurset (21 ,'J) ; printf ( "A = abort, anything to continue '") ; */ c = 'A': /* tou p per ( .char. _bios_kevbrd'_ EVB D_READ. 1 > ; </ /« scclrmεgC21 ,0,80. ; */ if ( == 'A') i sccurset (comx5.lt + 4, ιcom /16) * 40 + 34); printf ( "ABORT") ; return TRUE; return FALSE: } SUBSTITUTE SHEET - TASK.C Monday, October 3, 1988 Page void check_point (com ,op_ιo,op_tιme,wall_tιme) int comx, op_ιd; lonα op time, wall time; 5 c TimingRec t; int port; port = comx - 020: εccurεet (oorty.16 + 4. (port/It.) * 40 + 14); if ( op_id == 0; printf("TRANS-tm 7,5ld '.Sid" ,op_tιme,wall_tιme) ; else printf ( "\xFB '/.-6.6s * /.5ld '/.5ld" ,op_id_msgCoo_ιdi ,op_t " ime,wall_time) ; t .termno = comx; t .stopwatch = oρ_tιme: t.walltickε = wall_tιme: fwrite(Sit. sizeof(TimingRec.. 1. ses_ ile. ; } int get_data(var) char varLlOHSOJ : C int i; char aback; for (i=l ;i <10;ι++) C sccurset (21 ,0) ; oπntf ("getvar :") ; back = gets(varCi]) ; scclrmsg(2l ,0,80) : if (back == NULL) return EOF; if ( εtrcmp ( varCi ] ."END") == 0) return EOF; if (εtrcmp(var[i],"") == 0) break; } return NULL; } int waιt_for_ooerator 0 C * εccurset (21 ,0) : printf ( "Waiting for operator. Press any key:"); _bιos_kevbrd(_KEYBRD_READ) : scclrmεαT21 ,0,80) ; */ } int do_exι (comx) int comx: C comx -= 020: sccurset (comx.l& + 4,(comx/16) * 40 + 35) ; printf ("EXIT") : return TRUE; SUBSTITUTE SHEET TA5K.C Monday, October 3, 1'388 p agg SUBSTITUTE SHEET TESTPORT. Tuesday, October 18, 1988 Pace /♦ Test comx port to see if it exists and works properly (C) copyright 1988 Dynix, Inc. written bv: J. Wayne Schneider date: 2 September 1988 teεt_oort (comx) where comx lε 1 to 77 octal and An error code is returned, 0 means it passed, */ ttdefine FALSE 0 #defιne TRUE 1 ..include "\rhobot\serial . " #ιπcluoe (bios.h) /* Set and check a εingle regiεter in the 8250 */ reg_cnec '.co , val .error) in*, com. val , error: £ outπ .cαm.va I, : if un icom) == val) return FALSE: else return error: 3 /* Test the com port to see if it exists and functions */ teεt_port (comx) int comx: C int l, baudlo, baudhi, ier, lcr, mcr, flag, com, in, out; lonα tml, tπ.2; co = get_com_adr (comx) ; /* translate to a port addresε */ enable_ι () ; /* get_com_adr disables int. we enaole »/ if ( ! com) return 1 ; /* give up immediately on port 0 * tiag = FALSE: '* test +or PCSS--S card */ for . l = 0 : l '. 25b ; ι++) f1ag i= reg_check(com+SC ,I .0;-:0o02 : if '. ..comx <. 010! kk flag) '. '. ((comx > 7) kk !+lag. ) return x0004: /* standard port tt. scratcr. pad * ■ /* or PCSS port #, scratch good *ι /* either means failure */ get_com_adr(comx) ; /* reset scratch on PCSS-S */ SUBSTITUTE SHEET 0269 -70- TESTPORT.C ' luesday, October 18. lySS Page ier = inp(com+IER) : t* preserve the eld reα values * ' lcr = inp(co +LCR) : mcr = ιπρ .com+MCR) ; flag = FALSE; /* assume good until proven otherwise * . tlag = reg_chec. (com+LCR, .FF.υ-O'.'OS) ; '* chec. the line control -eαi≡ter * .■ tlag = reg_check .com+LCR,ux ,g,-(.ιuu3) ; '* be sure divisor latch is cleared •' tlag = reg_chec (com+IER.Urϋυ.UΛ υi : I* leave interrupts disabled */ flag = rsg_chec (com+MCR.O lF,0O02O) ; /* chec. the modem control register * flaα = reg_check'.com+ML .υ..υo,0;<υu . : i * turn o + + the loop for now * •' flag != reg_check(com+LCR,0x80,OxwOS) ; /« set the baud rate divisor latch */ baudlo = ιπp(com+L5D) ; /* preserve the old baud rate * baudhi = ιnp(com+MSD) : flag = reg_check(com+LS ,υvFf- ,0HI ) ; /* chec. out the divisor regs */ flaα = reg_check(com+MSD, ϊFF.0x0080) ; flag = reg_check(com+LSD,0x0C,υ 004 ) ; I* set to 9600 baud »/ flag = reg_chec (cσm+MSD,0xθ0.0 * 0080. : flag = reg_check(com+LCR,0xlF,0,'O008) ; /* set even parity, _. data, 2 stop »' flaα = reg_chec. (com+MCR.ι: i0. 0υ20) : /* set loop bad */ outp(com+THR,0ΛA5) ; /* test tor rx by sending a char * sleep(2. : /* thiε enables interrupte ♦/ get_com_adr(comx) ; /* reset scratch on PCSS-8 V DI * if 7 ■ Tιπp(com+LSR) k DR)) /* check for data read,' * / lag = 0x0100; if (mp " (com+RBR) '= 0xA5) l* compare the data */ flag != reg_chec lcom+IER, x00,0x0010) ; /* disable 8250 mts aαam * / ιnp(com+MSR) ; /* teεt the Modem control lineε * , +1ag != reg_chεc (com+MCR,0-<1F,IJ <χ>2ύ) ; if (ιnp(com+MSR.' '= oxFB) lag = <.><-ι.'400; flag != reg_chec (com+MCR, x10. Q>υo£θ) : if (inp(com+MSR) '= OxOF) tlaα = o^υ400: it ''tlag) /* don t do timed loop ι+ pad alreadv * / _bιos_tιmeofday(_TIME_6ETCL0CK,£-tml) ; /* loop data through tor s time * tor ( ιn=48 . out=42 : in ( Su : .■ C enable_ι ( ); ,* enable interrupts * ' _bιos_ύmeotdav'_TlME_6ETCLUCf..i.tm2) : /* check the time * • it Um2 > (tml + 2)) /* allow enouoh time » C lag = 0x0800j SUBSTITUTE SHEET -71- TESTPϋRT.C Tuesday, October IS, 198b aoe break: } get_com_aor(comx) ; / » reset scratch on PCSS-S i. DI */ if 7αut~< &0) if (inp(com+LSR) k THRE) outp(com+THR.out++) ; if (inp(com+L5R) k DR) if (inp(com+RBR) != m++) lag = 0x0200; get_com_adr(comx) ; /* reset scratch on PCSS-S k DI */ flag = reg_chec (com+LCR,0x80,0x0003; : /* set all back as it wae »/ flag = reg_check(com+MSD,baudhi ,0x0080) ; flag = reg_check(com+LSD,baudlo,0x0040) : flag = reg_chec (com+LC ,lcr,0x0003) ; flap = reg_check(com+MCR.mcr.0x0020) ; flaα = reg_check(com+IER,ier,0x0010) ; enable I o : /# return with interrupts enabled * / return flag; I* return flaα */ / Use external wiring to loop back signals and d§ta. This routine tests that loop back capability. Only DTR k CTS " signals are tested. We expect to use interrupts to test the data coming back. Return an error code, 0 means it passed. It is absolutely neceεεary to have called serιal_ιmt and serιal_ιmt_ιnterrupt , prior to this test. Enable :x interrupts and prepare to run at a minimum of 9&00 baud and 512 byte buffer, It is best to call 'test port' prior to this test. */ int comx: C int c, l, mcr, flag, com, in, out; lonα tml . tm2: com - get_com_adr (comx) ; /* translate to a port address k DI * i f ( ! com ; C enable_i () ; return 0x0001 ; /* give up immediately on sort 0 >/ ) flag = FALSE: /* assume good until proven otherwise ♦/ if (!flaα) I* don't αo timed loop if bad already * l SUBSTITUTE SHEET 0269 -72- TESTPORT.C Tuesday, October 18. 1983 Page ε_clearιcomx,0) ; /* clear the buffer k status */ rx_status(cαmx) : enable_ι(); /* enable interrupts «/ _bios_tιmeofday(_TIME_eETCLOCk t l) ; /* loop data through for a time for ( in=l , out=l ; in < 255 ; ) { _bios_timeo day(_TIME_eETCL0CK,&tm2) ; /* check the time */ if (tm2 ) (tml + 7)) /* allow just enough time */ C flag = OxOSOO; break; 3 if (out < 256) if (εpushc(comx,out)) out++; if ( (c = spullc(comx); != -1) if (c != in++) flaα = 0x0200: ) flag i= rx_εtatus(comx) ; /* check for rx errors */ if (flag) flag != 0x1000; /* set special error code */ enable_i (; : /* return with interrupts enabled */ return flaα; /* invert k return flaα */ 3 SUBSTITUTE SHEET 1 TIMER.C Wednesday, August 31, 1988 Page /* Timer routines are located here. (C) copyright 19S8 Dynix, Inc. written bv: J. Wayne Schneider 5 date: 23 August 1983 */ ..include "εp.h" # include "εp_data.h" ..include (conio.h) ..include <bιos.h> 0 /* Timer_ιnιt resets the count in timer 2 of the S253 so that a clock pulse is exactly l/20th of a second instead of the goofy value used by PCε. We also initialize the system clock to 0 so we never have to worry about running over midnight. At the end of the session, we fix the clocks back to normal. 5 */ void timer_ιnιt () C long t = 0; _bιos_tιmeo day ( _TIME_GETCLOCK,&day_tiπ.e) ; outp ( 0x40.OxOB) ; /* set divisor to 59659 */ outp(0x40,0xE9) ; _bιos_timeofday<_TIME_SETCLOCK,&t) ; /* reset rtc to zero */ 0 3 /* Timer_undo fixeε up what happened in timer_init to return the clock to normal . */ 5 tιmer_undo() C long t; _bιos_t imeof day (_TIME_EETCL0CK ,ki ) ; outp (0x40,0) : /» reset count to 65536 */ outp (0x40,0) ; day_time += (t * 1092) / 1200; /* adjust the clock */ Q _bιos_tιmeo day(_TIME_SETCLOC ,&day_tιme) : 5 SUBSTITUTE SHEET _ TRAFFIC. C Tueεdav, October 18. l * fage /************* * *********************** ************************** * ********* procedure TRAFFIC_PAC.'.£T5 5 All data, between the slave taεks and the master, travels in packets. The packets are routed to the appropriate taεkε by this task. ************************************************************* ** *** * ***** * * /* tdefine DEBUG «/ extern int const MASTER_P0RT; 0 ♦include "sp.h" #ιnciude ..include "sp_gdata.h" ttmclude <bιos.n; Sincluoe (εtdio.h) #ιnciuoe tmalloc.h; /***** **l(;).***-t****+**»«jf).).*4().**#**JS##*)(l(#j.).l4:j( > -» > J.f.****» ****** .H.t.lt... pacret structuree k data ************************************************************** ********** - struct s_chaιn { struct s_packet *head; struct ε packet *taιl; 0 ,, struct ε_chaιn r _chaιnC323 ; /* allocate 32 chain ptrε *' struct ε_chaιn tx_chaιn: * end 1 t: chain ptr *' procedure prototypes ************************************************** **** ***** * ********. * * ** ; 5 void do_rx_traffιc(voιd) : void do_tx_tra fιc(voιd) ; void add_packet(struct ε_oacket *, struct s_chaιn »): struct s_packet *remove_packet(struct s_cham *); struct s_packet *rx_pac et (int) ; void packet_answer(εtruct s_packet «,ιnt); procedure TRAFFIC_PACKETS ****** tit****************************************************************/ void traffιc_packetε(; C for(ever=TRUE;ever;; /* do forever */ C rescheduleO ; /* give everyone a chance to run */ 5 SUBSTITUTE SHEET _ TRAFFIC.ϋ Tuesday, October 18. 1988 Pag it l_bιos_keybrd(_KEYBRD_READY) ) /» give up, when commanded */ if ( (char)_bιθ5_keyord(_KEYBRD_READ) == Oxlb; break; » break from 'do' loop */ 5 oo_rx_tratfιc() ; /* receive data */ do_tx_traffιc<) ; /« transmit data «/ 3 3 1(|r ftk«*|t ι*»** i*l(*κ»_ι^yk>«k#|(ft«*****««#k«|(**«*«κ««)(jij(«k t (i(j(y*«< >'ll»r'*.f-l>4* ) t« procedure DO TX_TRAFFIC 0 If any task has a packet to transmit, we do our best to get it out aε εocn as possible. We expect the longitudinal parity to alreadv pe calculated and stored in the last ooεition. It is included in the count. ******* ************************************************ ** ******** * .1114)1/ void do tx traffic0 5 i static tx_cneck = 0; static int tx_!ength: static struct s_packet *tx; etatic char far *tx_ptr; εwi cn (tx_check) { caεe 0: /* loo for a packet to εend */ { tx = remove_packet (&tx_chaιn) ; if (tx != NULL) tx_check = 1; /* setup to send the oacket »/ break; 3 case 1: /* send tne TYPE code «/ v if ( Ispushc .MASTER_P0RT , tx-)packetLTYPE3) .' crea ; #ιfdef DEBUS printf("TX y.2x",tx-;packetCTYPED) ; #endιf tx_check = 2; break; 3 case 2: /* send the LENGTH */ r if ( !spushc(MASTER_P0RT, t -) acketCLEN3) ) orea : Jfi def DhBUis printf ( "'/.5::",tx-;packetLLEN3) ; #endιf tx check = 3; SUBSTITUTE SHEET _ TRAFFIC. C Tuesday, October IS, 1983 Page t:._ ' ιengtn = tx-,packetlι_£NJ : tx_ptr = iitx-; packe CDE5T ; brea : } 5 caεe 3: /* send the bulk of the DATA * { if (!spushc(MASTER_PQRT, *tx_ptr)) brea ; #ιfdef DEBUG. or l nt f ( " */.3x " , * t x_p t r ) ; #endιf 0 tx_ptr++; —tx_length: it (tx_leπgth) brea : #ιfdef DEBUB printf ("\n") ; #endif 5 tx_check = 0; if (tx- .-packet [TYPE3 != SYN; _ffree(tx) ; /* release acknowledαe packets * ' ) 3 } 0 procedure DO RX TRAFFIC If a cnaracter haε been received, process it. It may be the start of a 5 packet, an ACK. a NAK, or a data part of one of these. Flagε are kept to tell us wnere we are at. ***************************************************»-* >. * ■ *♦**♦****». »« a***** .- void do_rx_traffic() ( etatic int rx_check = o,* Q static int rx_parιty; static int rx_length; static εtruct ε_packet *rx: static char far *rx_ptr; int c: c = spul lc(MASTER_PORT) ; * cneck for a cnaracter « / if '.c == EOF) return; 5 #ιfαef ύEBUii SUBSTITUTE SHEET TRAFFIC.C Tuesdav, October IS, 19SS Paoe printf'."-..2x ",c. : #endιf switch (rx_check) C case 0: /*■ watch for first character >/ ' C switch (c) C case ACK: /* collect any of these kind */ case NAK: case CAN: case BYN: ♦ start of a packet of data */ 1 rx_paπty = c; rx_check = 3; rx = _f ma 11 oc ( ε l zeof ( S_PACK. ) ; if (rx == NULL.' I displayC fmalloc") ; } rx- packet [TYPE] = c: rx_ptr = rx-)oacket + LEN; break ; } default: /* garbaαe cnaracter */ L rx_check = 0; rx_status(MASTER_PORT) ; /* discard errors s≡ well */ brea : ) break : i case 3: I* handle a new packet - length */ f * (rx_ptr+- 1 -) = c; rx_length = c : rx_paπty "= c ; rx_check = 4; break; ) case 4: αet tne data for new packs. » { * (rx_ptr++ = c; rx_paπty ' = c; — rx_leπgth ; if (rx_tength) brea ; / » process the packet by type »/ rx_check = 0: if (rx-)packet[TYPE] != SYN) C SUBSTITUTE SHEET -78- T HFFIC.C Tuesday, October 18, 19SS Page if (rx-/packetL ESTJ . numoer_of_ports) tx_answerCrx-,packetCDEST] = rx-)packet£TYPEJ; _ffree(rx) ; } εlεe if (rx_Daπty) rx_paritv = 0x20; /* including error status »/ rx-) packet ESTATUS] = rx_paπty I rx_εtatuε(MASTER_PORT.> : if (rx-)packetESTATUS] == 0) /» do we ACK or NAK or CAN ? */ if (rx-> packet OEST] < number_of_porte) ( packet_answer<rx,ACK) ; add_packet(rx,&:rx cnamCrx-)packetL EST]3. : } else C packet_answerirx.CAN) : _ffree(rx.' : * lαnore bad address packets * / 7 else C packet_answer(rx,NAK) ; * request retransmission * / _ffree(rx) : } brea ι ) default : /* rx check default */ i rx_cneck = 0; oreak: /tn*******************.************.**************.*.*********.****************. procedure ADD_PACKET Add a packet buffer to the chain of packets, updating head k tail pointers. void add_packet tax, chain) struct s_packet *ax: struct s_chaιn *chaιn; if tchaιn-)taιl == NULL) /*■ if the list is empty »/ chain-,head - ax; /* adjust head tr also *! else cnaιn->taιl->link = ax: /» always add on end of chain «/ chain-. tail = ax; / * always εet tail to point at new one */ SUBSTITUTE SHEET 1 TRAFFIC. Tuesday, October IS, 1Sϋt. Pag /*****«*************************************κ**********«********«*«****«** procedure REMϋVE_PACKET Remove a packet buffer •from the chain ot packetε, updating head k tail pointerε. Return a pointer to the packet, or NULL if " there lε none. ***********»**********»*********«******#************l.*************-4.*-»-*4.»*.' struct s_packet *remove_packet(chain; struct s_chaιn *chaιn; ( 10 struct s_packet *mx; if (chain-)heao == NULL) /* i-f tne list is empty */ return NULL: /* return NULL */ if ((*chaιn-.head) .link == NULL; / " * if tnis is the last item in chain */ chain-;tail = NULL; /* set tail to NULL */ _g inx = chaιn->head; /* Get otr to packet */ chaιn- head = mx-)link: /* Unlink the packet */ return x; /* Return the packet <t/ } /* * ********* ******** ************ ****************** * ******* *** * ** ** * *** ** * * procedure RX_PAC ET 20 * w Receive a packet if there is one . It returns a NULL if there is no packet , or a ptr to a packet . **************************************************.****************.******.*/ struct s_packet «rx_packet (taεk_ιd int task_id ; f return remove_packet (&rx_chaιn[task_id] ) ; 25 } Zee*********************************************************************** procedure PACKEΪ_HN3WER Remove a packet buffer from the chain of packets, updating head k tail pointers. Return a pointer to the packet, or NULL if there is none, a************************************************************************ / 30 void packet_anε er(rx,answer) struct s_packet *rx; mt answer: C struct ε_packet *ax; ax = _ maHo (sizeof(S_PACR)) ; /* get soace for answer */ i (ax == NULL) 35 C SUBSTITUTE SHEET -80- TRAFF1C.C Tuesday, October lϊ, l'ϊ_S Paα oιsplav("_imalloc") : exit (1) ; } ax->packetCTYPE] = answer; ax-)packetLLEN3 = £; ax->packetCDEST] = rx-)packetCSRC] ; ax-;packetCSRC3 = rx->packetCDEST] : add_packet (ax,&tx_chaιπ) ; } /***********************.*********************.**************************?** procedure TX_PACKET Build and transmit a packet. We must wait for an answer before continuing, we can get back ACK. NAK. CAN, or timeout. ***********»*#********************#*****************ι.»****ι,***».***«. ♦*.*♦ int tx_packet (dest ,taεk_ιd, cmd, ten, data) mt deεt ,taεk_ιd , cmd , len; char *data; C struct ε_packet *tx; t parity, I; long tm,new_tm; tx = _fmalloc(ειzeo (S_PACK) ) ; if (tx =- NULL) £ dιsplay("_fmalloc") ; if ( Uen+4) ) FACKET_BUFFER_5IZE ) return LAN: x-) packet [TYPE] = SYN; /* build up the packet */ X-? packet LLEND = len + 4; x-)packetCDEST] = αeεt ; x-;packe BRCJ = task_ιd: x->packetCCMDJ = cmd; paπtv = 5YN ' (len + 4) * αeεt " ' task_ιd ' cmd: for (ι=0;i<len;i++) C tx->packet[DATA+i] = dataCi]; parity "= dataCi] : } tx->packetCDATA+i] = parity; for (i=0;ι<S;i++) /* try to transmit 8 times at most */ C tx_answerCtask_ιdJ = 0; add_packet<tx,&tx_chaιn) ; /* hand it off for transmisεion */ _dιoε_tιmeofdav<_TI.'IE_GETCLOCK.ϊ.tm ) : /* watch the clock wmle we wait */ αo <_ reεcnedule'. ; SUBSTITUTE SHEET τ_ TRAFFIC.C Tuesday, October IS, 1933 Pag if ltx_answerCtaεk_id]) break; _bio5_timeofdav ( _TIME_GETCL0CK,&new_tm) ; } while ( (tm + 200) ) new_tm ); switch .tx_anεwer task_ιd]) C case ACK: return ACK; /x good transmit */ case NAK: break; /* retry */ case CAN: return CAN; /* give up */ default: return -1: /* retry on timeout */ } 0 5 SUBSTITUTE SHEET -82- _TRANS_IT.C Wednesday, Auguεt 31, 1933 Pag /* Tranε_ιnιt iε used to read the data file called "SP.DAT" and initialise some system parameters. If the file is not ound, the parameters are set to a default. 5*/ tinclude "sp.h" #include "sp_data.h" #ιnclude (stdio.h) void trans_init (trans,global) struct t_str *trans; Q struct g_str *glαbal; FILE *stream; char bu f[1003; trans-)rate = 100; /* one every 5 seconds = 12 per minute */ trans-)abort = FALSE; /* don't start by quitting (not in file.'*/ trans-)loop_count - 0; /* unlimited transactions */ 15 global-)think = 40; /* think time is 2 seconds */ global-)timeout = 600; /* don't timeout for 30 seconds */ global-Hhrottle = 5? /* assume 50 wpm typing rate »/ stream = fopen("SP.DAT" ,"r") ; if (stream == NULL) goto gιve_up; if (fgets(buff,100,εtrea ) == NULL) 20 goto give_up; trans-)rate = atoi (buff); if (fgets(buff,100,stream) == NULL) goto give_up: trans-)loop_count = atoi (buff); if (fgets(buff,100,stream) == NULL) goto give_up; global-)think = atoi(buff); 25 if (fgets(buff,100,stream) == NULL) goto give_up; global-)timeout = atoi (buff); if (fgets(buff,100,stream) == NULL) goto give_Lip; global-)throtύe = atoi(buff); g l ve_up : _ j _ fclose (stream) ; JO ) 5 SUBSTITUTE SHEET SERIAL.H Tuesday, October IS, 1938 F'aα '* Serial port definitions (C) copyright 1933 ϋynix, Inc. written by: 3. Wayne Scnneiαer date: 2 September 19SS */ #Be ine RX BUFFER SIZE 204£ #de ine THR o #de ine IER 1 ttdefine 1IR 2 ttdetins ι_CR i #de ine MCR 4 #de ine LS. —. #de ine MSR 6 itdefine SCR #de ine Mb ' D i Kdetine EKdAi Ox'J1 .'* enable receive data available interrupt ♦, #define _S_LwTA 0x03 /* 3 data bits */ Ktie.ire DTR Oxvl .'* data terminal ready */ flde ine RTS Ox'.'≤ * request to send */ #defme GuTE OxOS /* ib master interrupt enable */ fcdefine D 0x01 ttdefine BI 0x10 tfde ins THRE 0x20 #defιne IGNORE NULL 0x01 /*. buffer control reαister values «. void com_break'.int ,ιπt) /* (comx,mask.' mask=l means set, 0=reset *l int rx_status(ιnt) ; I* (comx, returns LSR and buffer status */ int εpull (int. : /* (comx) returns char or -1 if none */ int spushciint ,char) ; /* (comx,c) returns FALSE if failed */ int tx_status(int) : /* (comx) returns FALSE if not ready */ int s_clear(int,ιnt) : /* (comx,flag) zeroes rx buffer. If (flag) then buffer must be empty lεt char far *s buffer.int) /* return rx buffer pointer «/ voiα seπal_ιnιt(int .unεigned,int .in ,int ,char far * .unsigned,int. 1 ; /* args in order are: comx - com port address baud - baud rate αesirec lcr - line control register value mcr - modem control register value ier - interrupt enable register value buff - FAR buffer pointer εi∑e - buffer size in bvtes bcr - buffer control reoister value * SUBSTITUTE SHEET SERIAL. H Tuesday, October 13, 1933 Paα _ . vo id seπal_ιnιt_ιnterru p t ( ιnt.ιnt ) : ,, (comx.maεk) mask=0 ena b les i nt * . < SUBSTITUTE SHEET -85- I SP.M Tuesday, October IS, 1 SS Pag /* so.h contains definitions for general purpose things and functions (C) copyright l'?33 Dvnix. Inc. 5 written by: .1. Wayne Schneider date: 10 August 1'ϋSS ftdefine FALSE 0 #de ine TRUE 1 0 /* Function definitions help prevent programmer errors *ι int tx_oacκet (int .int ,m ,int .char +) : struct s_packet *rx_packet (int) ; void εiavedπt. : * main taεk routine */ 5 int test_port tint) : voiα rescheαule'.void; : void orocess'.mt . int.'j void putvargdnt. unsigned char, char II CSOJ, char #[]): 0 m repor '.int. int;; void chsck_po .-.t tint , int. lone, long;: int getvar'.char 103LS0-] ) ϊ unsigned char *get_εcnpt (unsigned char * . long *. char «[]) : 5 void sputcunt, int); void sputsliπt. char *:: char sgetcunt. ; char *rr_cιrc(char *); n void εt lush Unt) ; void c tea~_ιnpu _wιndow.ιπt > : void do_scriDt iint , char *. long, ctisr *CJ, cnar « .struct t_=tr • '■ void siess'. ns_.cned i t.' : 5 SUBSTITUTE SHEET 1 SP.H Tueεdav, October IS, 19S3 Page void com_oreak(ιnt . int. : int rx_status',ιnt) ; int spushcαnt, cnar); int tx_status nt. : 0 char far « =_bufter (int; ; int waιt_for_operator .void. ) ; void t ιmer_ι nit (void) ; void trans_ιmt (struct t_εtr *, struct g_εtr *. ; mt do_e::i ( mt) : l nt ι- ana _nor.τι '. I nt , l nt ? ; int rx_erro (int) : void check_out '.void ) : /* do_εcπot calls to see i. one * .■ SUBSTITUTE SHEET SP_DATA.H Tuesday, October IS, 1988 Paα I* Blobal data declarations for fa'P.C (C) copyright 1933 Dvmx, Inc. written by: J. Wayne Schneider date: 29 July 198S * extern mt performance_checkt060] ; extern int monιtor_port[0603 ; ftdef e m_buf f _5i _.e 2043 extern char m_buft Lrn_buf f_s ι ze3 : extern i nt m_butf _cnt ; extern char «m_duff_ιn, #m_buft_out : extern long day_tιme; extern char *oo id msαl-50]: extern char *process_ιd_mεg C50] ; extern char status_msgC4] C 153 ; εtruct t_str . unsigned rate: int abort ; unsiαned loop count: }; struct g_εtr t unsigned int think; unsigned int timeout; unsigned int throttle; extern struct g_str global; extern unsigned εtac.-:_si-:e! extern cnar *sιgnature; #de ιne PACKET_BUFFER„SIΪE EόO /* packet + TYPE + LEN •/ ttdefine STATUS '.' /* error status lε here > #defιne TYPE 1 / ' * type of packet, usually 3YN */ #defιne LEN £ /* length of packet */ #defιne DEST 3 /* deεtination taεk id */ fcde ine SRC 4 I* source taεk id * / #defιne CMD 5 /* packet command «/ fcdefine DATA β /* data for command */ tvpedet struct s packet c SUBSTITUTE SHEET -88- ^SP_DA.A.H Tuesday. October 13, 1933 Page struct ε_packet *lιnk: char packet[PACKET„BUFFER_SIZE] ; 3 S PHCK; f.define E ύ 05 /* who are vou? *=/ ..define riCK 0x0b /* good packet */ #defιne NAK 0xl5 /« bad packet */ #define S ' YN Oxl* /* sync εtart of packet */ #defιne CAN 0x13 /* cancel a packet */' #defιne ESC OxlB /# escape from program * #defιne ITEST 'I' /« internal port teεt */ #defιne ETEST 'E' /* external loopback port test */ #define PASS '?' I* pass through to Wyεe */ ♦.define PASS_BREA 'B' /* pass through a break */ #de ine CR OxOD 15 20 25 30 35 SUBSTITUTE SHEET _ SP_6DATA.H Tuesday, October IS, 19SS Page * SP global data Definitions tor use by SP routines (C) copyπgnt V-)Sύ Dvnix, Inc. written bv: j. Wavne Schneider 5 date: 1 September 1Ε_8 extern int gocd_por L3c_] ; extern int *curtcb: 0 extern int number_of_ports; extern struct s_tcb tcbL33]; extern cnar tx_answer[3E] ; extern t ever: SUBSTITUTE SHEET -90- DISPLAY.ASM Tuesday, September SO, 1953 aα To: Dynix, Inc. Attn: Wayne Schneider From: Terry Bell (415) 633-3710 Everex Systems, Ine : Ref: LED Display listing page title display characters to front panel LED .≥3 c Name: Display.asm 03-07-88 . CYL 1.00 — file created cseg segment word public "code- assume cs:cseg, ds:dseg. ss:ssec Equate Values PmtPrt eαu OSOh :oointer to start of parameter PmtL t eαu 040h :ρarameter= limit DisCmd eαu ObOh ;diεolay command for 3043 DisSire eαu OOSh ;dιεplay message size CmdPort eou 064h ;S042 command port DatPort equ 060h :304Ξ data port StatPort equ 064h ;804S status port ; Display: This program will output eight characters to the front panel display module. It will alεo enεure that the eεεage is exactly eight characters and the 804S is properly functional. If not. error messages are displayed on screen. ; Input: Eight characters on command line enclosed by the character ' . ; Output : All registers restored Display proc far push ax ;save AX push bx :save BX push dx :save DX puεh si ;save 31 push ds . • save DS mov ax,seg dεeg ;set DS to data segment mov dε.ax ; mov dx,offset EvSign ;get message address mov ah.9 ! int 21h ;print EVEREX - ' s copyrio SUBSTITUTE SHEET -91- _ DISPL Y". SM Tueεday. September feu. ι9S Paq mov si .PrntPrt ;set pointer to parameter ιoεo. cmp bvte ptr es:Lει],00h :check for valid osra eter je Displ ;go it ves add si,3 ;set to parameter table DiεbS mov al ,es:Csi ] ;check command line for • character cmp al."'" je Dιsp4 ;go if found cmp a1 ,0dh :check for carriage return 0 jε Dispf;. ;go if found cmp si .PmtPrt+PmtLmt :max characters scan Jb Disρ5 ; j b short Dispt. ;print out usage message Dιεp4: mov al ,es:Cει+DiεSιze+l] jcheck for end of messaαe 5 ,ιne DispS :go if message not 8 characters long call DiεpOut soutput characters to display module or al .at :check tor 8 43 errαr onz DiεpS ;go if anv error occured mov dx,of set NoErr ;get message address mov an,9 0 int ≤in :no error message jmp short DispExit ;exιt routine Diεpl : mov dx.of set Useliεi st message address in DX mov an,9 ;D0S print string function int Slh jmp short DispExit 5exit routine DispE: mov dx,offset MEErr ;qet messaαe address in dx 5 mov an .9 ;D0S print string function mt Slh omp εhort DispExit ;exιt routine DiεpΞ mov dx,of set ErrSi mov ah,9 ;DDS print string function rt DispExit :exit routine offset MErr ;get message aααress in D; mov ah.9 :D0S print string function int em : DispExit : POP dε :reεtore DS pop εi :reεtore il 5 pop dx ;reεtore D SUBSTITUTE SHEET -92- DISPLAY.ASM Tuesday, September £0. 1933 Paα pop bx ;restore &x OP ax : estore AX mov ax,4c 0h int £ln ;exit thro endp ; Dispϋut : This routine will output eight characters to the display module. ; Input : SI register containing offset address of message ES register containing εegment address of message ; Output : AL=0 - Mo errors AL=_ - S04S error occured Disoϋut proc near puεh bx :save BX puεhf ;save present flag status cli :ensure no interrupt mov b ,1 ;εet BX count to one call Empty804£ :wait for 3043 not buεv jnr DispϋutExit :go if 304£ error mov a.1.DisC d :dιεp av message command to 304c out C dPort , l :send display command jmp $+£ ;i/o delay Disoϋut1 : call Empty304£ ;wait for 304£ not buεy jπs Dis OutE it :go if 804E error mov al,es:Cbx+si] ;get character out DatPort ,al :εend to display through 304£ jmp *+£ ;i/o delay ine bx ;poιnt to next cnaractsr cmp 0x,DisSiΞs+l ;chec>. for end of message b DispOut1 :continue til done xor al ,al ;clear error code Dispϋut xit : popf :restore flag status pop bx ;restore fcX ret :return to caller DispOut endp EmptvS04£: This routine waits for the S(.' 2 input Duffer : to e otv SUBSTITUTE SHEET -93- DISPLAY. SM Tuesday, September £0, 19SS Pa input : Nothing Output : AL=0 - 804£ input buffer empty AL=E - time out, a04£ input buffer full EmptyS04£ proc near puεn ex :εave LA xor ex,ex ;ma imum wait time EmptyLoo : ln al .St tPort :read b'04£ s atus port jmp $+£ ;ι/o delay and a1. 0000010b ;check for command port full looons EmptyLoop ;continue til empty or timeout POP e :restore CX ret ;return to callerEmptvS04£ endp cseα ends Data Seαment : Program Messages dseq segment EvSign db "EVEREX SYSTEMS, Inc. System Utility VI.0." ,10.13 db "(C) Copyright 193S. All rights reεerved." ,10.13,10,13."$" UseMεα db "usage : DISPLAY 'message'" ,10,13 db message : user defined message " db " ( must be exactly 3 character-.)" ,10,13,10,13."$" NoErr db "Message has been sent to display module — errors .1U.13 db "$" MErr db "Error: Message not found" ,10,13,"$" MEErr dt- "Error: Message must be exactly 3 characters" ,lύ,l ErrS04£ db "Error: 304£ not responding" ,10,13,"*" dseα ends Stack Seαment General Programing Stack sseg segment stack db £58 dup(0) sseα ends end Display SUBSTITUTE SHEET _ -94- DISPLAY.C Monday, October 3, 1983 Pa /* Diεplay text on the Everex Step tront panel leos. Data leεε than S byteε long will be padded with blanks, .C. coovπght 1933 Dvnix, Inc. written by: J. Wayne Schneider date: HI September 1933 * ! int dιsplay(buff) char buffC]: ( 10 int I: int 1; I = εtrleπ(buff. ; εet up for blank padding * disad.e_ι..; * issue display command to 304£ * / whiIe iiπp( x6 ) k 0x0£. 5 outp( x64,Oxb0) ; for (ι=0;ι(S;ι++) /* output display text «/ { while '.inp(0x6 ) k 0x0£) continue; if ii .l. outp(0x60.buff[lJ ' ) : 20 elεe out0(0x60,' ') ; /* Dad with blankε * 3 eπaole_ι<,. ; 3 25 30 35 SUBSTITUTE SHEET 1 INTERUPT.ASM Friday, September 16, 1933 Page TITLE INTERRUPT SPECIAL FUNCTIϋNS ? dιsable_ι 0 ; enable_i () 5 JΈ I SEGMENT BYTE PUBLIC 'CODE- TEXT ENDS DATA SEGMENT WORD PUBLIC • DATA' DATA ENDS CONST SEGMENT WORD PUBLIC 'CONST' CONST ENDS _BSS SEGMENT WORD PUBLIC 'BSS' 10 - BBS ENDS DGROUP GROUP CONST, _BSS, _DATA ASSUME CS: _TEXT. DS: DGROUP, SS: DGROUP, ES:DBROUP _TEXT SEGMENT PUBLIC _dιsaole_ι , _enable_ι 1 - t 5 J _ ιsabie_ι PRUC NEAR CLl RET _dιsable_ι ENDP _enable_ι PROC NEAR STI RET enable l ENDP 20 _TEXT ENDS END 5 0 5 SUBSTITUTE SHEET -96- D0 SCRIP.C Tuesday, October 13, 1933 Paα /• Do a script -file .C. 1 copyπαnt 1933 Dyπix, Inc. written bv: J . Wavne Schneider date: 10 August 1983 Thiε routine will work with both SP and SPl main programs. It procesεeε the script file pointed to bv 'script' on bort 'com: * Start time arguments are pointed to bv 'argv' ' . The integer length o-f the scπot -file is in 'length'. */ #de ine PERF0RMANCE_FENCE 5 ιnclude "sp .h" # include "sp_data .h" .. inc lude . string . rt. .. include .stdio .h, #ιncluoe <bιoe .h> void do_scπpt (comx,scrip , length,argv,ιnput_wιnoow,trans. 1 int comx: char *scπpt ; long length; char *argv[J ; cnar *ιnput_wmdow: struct t_str »trans; { int per+ormance_count ; int t.tl: unsigned int trans_ιteratιon: unsigned char c: unsigned char #ιp,*εcrend,*tιo; long timer[103; char varC10][303; long loop_tm,tm,start_tm,tranε_start_tm,tranε_end_tm; _bιos_tιmeαfday(_TIME_GETCLOC ,&start_tm. ; /* init timer */ /* srand((int)start_tm) ; */ scrend = script + unt)length: IP = script ; do ( c = « (1P++. switc .c _ case 1 ; /* PROCESS *. procesε'.comx up- 1 break: sleep(1. : com_brεa i om ,1. ; SUBSTITUTE SHEET -97- τ_D0_SCRIP.C Tuesday. October IS. 1933 Pag sleep ιl) ; c om_b r e a k ( c omx . .' ; sleep (1. ; brea : 5 case 3: /* SYNCHRONIZE ♦/ waιt_τor_operator .. : sleeo lrand_nor •. trans-, rate.1. > ; brea ; case 4: /* CLEAf._lNPUT_WINDOW *> rx_readvtcomx. : in clear_ιnout_wιnoo .comx. ; prea : case 5: » OUTPUT * whiie ( '.c=* (lp++.. := NUL ) ( it ' .c ( 133) sputc'.ccmx.c) : else putvarα .comx. ,var.arαv. : 15 break; case έ: * BESI _T1MED_L00P ♦ _bιos_tιmeofday ( _TIME_BETCLOC loop_tm) : performance_count=ύ; brea : case 7: /* END_TIMED_L00P ♦/ 20 perfσrmance_count++; _bιos_tιmeo7day(_TIME_SETCL0CK,&.tm) ; i-f (tm .' = (loop_tm * global .timeout > .' £ ip +=2; brea ; } ip = script + (int)*'. int *)iρ; 25 rescheduleO : break; /* 00K_F0R *ι tip = ip: while ( (c=* (IP++) ) != NULL); ii : .εtrstr . input _wιndow, tip) . ι _. = εcr ip t + ι I n ) * ( I nt * ) I o : 30 i+ t De r-formance_count < PERFORMANCE^ LNL ' E ■ P5rtormance_ hect. com;::3++ ; j else ip += 3: break ; case 9: /♦ wAIT_PQw IDLE */ 35 t = tl = Mιp++. : SUBSTITUTE SHEET 6 -98- Dύ_5CRIP.C Tuesday, October 13, 1933 Pa sleep.1.': /* sync to clock tic.-: */ wh11e '.11.' i clear_ιnput_wιπdo icomx) ; /* clear to begin *■ sleep(1» : i-f '.rx_ready(comx)) /* check -for errors or data * tl = t: else tl--: i ' brea : case 10: /* REPORT ♦/ trans->abort = report (comx.* (ιp++. ) : break; case 11 : /* EXIT « trans-; bort = do_exιt (comx; : brea ; case 19: /* BtGir'i_TκAr>ιSAL'Ti-N • trans_ιteratιαn = trans-; loαp_count : trans_start_tm = 0; trans_end_tm = trans-;rate: break ; case IS: /# repeat bEbIN_Tr.ANSACTlQl ♦/ tm = tranε_enα_tm - trans_start_tm: t = trans-. rate - (ιnt)tm; i-f (t > 0) sleep', (t / £) + rand_ncrm(t ,4) . ; _bιos_tιmeofoa i_TIME_£.E CLUCK. fetrans_start „ tm; : brea : case 13: /* END ' RANSACTIOM * _bιos_tιmeoτday ( _TIME_ΕTCLϋL'l : , ,*;trans_end_t.'P.) : check_poιπt (comx.O , (trans_eno_tm - trans_start_tm.. trans_end_tm) ; i-f (trans_ιteratιon) i-f (!( — trans_ιteration) ) C ip += 2; brea : j IP = script + (ιnt;* nt *.ιp: breaKi case 14: /* 5ET_DATA *■ i itιget_αataivar; == EOF; IP = εcript + unt.'* (int «;ιp; else ip += ci! brea : 5 case 15: /* HINH TIME ♦/ SUBSTITUTE SHEET Dϋ_SCRl .L Tuesαav, October is. l'-iSE' : 'aα i-f ( global .think) sleep ( rand_norm ( global .think .4; • * .global .thin.- .' 2) . ; brea ; case 16: /* BEGIN flNER */ _bιos_timeoτdav ( _TIME_BETCLOCK.«-tιmert*ιp]; : ιp++; brea : caee 17: /* CHECKPOINT */ tl = *(ιp++) ; t = * (ip++) ; _b ιos_t lmeotdav ( _T IMEJ3ETCLDCK .ktm) : check_poιnt (comx.t ,tm - timerCt 1 J .tm) : break ; case IS: /* S0T0 */ ip = script + unt)* (int *)ιps brea ; case S53: /* DEFINE _PR0CESS_1D */ case ≤5 : .'* DEFlME~ϋP_lD *1 case Ξ55: /*■ DEFINE TRANS TYPE *■ I while 1 .* ιρ++; ; brea : default : display ."scrpt } check_out () ; * see i-f we must qive UP now */ it uc ;= εcreno) trans-)abort = TRUE: . white . '.trans-)abort) void outvarg co . :,c ,var .argv int comx unsigned cnar c; cnar *argv[J cnar var lull 303 ; C switcn (c :) 1 case 131 souts .comx ,argvL03) ;break; case 141 soutsicomx ,vartl3 ;break; case 14c εputs .comx ,var[≤J; ;break; case 14s sp ts (.comx .varE33> :break; case 144 souts ι.comx .vart43) ;break; case 145 soutsicomx .varC53) : reak: case 146 sputslcomx ,var£63) ;break; case 14? sputεicomx ,varE7J; :break; case 148 soutsicomx ,var[S3 ;break; SUBSTITUTE SHEET U - SCRIP ' Tuesday. October ι B . w 6 Pag case 14*: s p utsιcomx, arL9J, jorea k; d e f ault: ε p utεicomx."NOMHTCH" . • ι SUBSTITUTE SHEET -101- lGET_SCR.C Wednesday, August 31, 19SS Pag /* Read in the script file and generate pointers to the text (C) copyright 1938 Dvnix, Inc. _ written by: J. Wayne Schneider "* date: 10 August 19SS argv - must point to the -filename to open εcript - is a pointer that we will set to the εcript file op_id - is an array of pointers that we set to the 'de ine_op_ids' op_idC03 - is a pointer that we set to the 'transaction type' */~ 0 #include "sp.h" #ιnclude <stdio.h> ♦.include (malloc.h) unsigned char *get_scπpt (argv,length,op_id) unεigned char *argv; char »op_idC3 ; lonq *length; 5 « FILE *stream; int lag,numread; char tcCS03; unsigned char «mp, *scπpt; strcpy(tc,argv) ; strcat(tc,".SCP"; ; εtream = fopen(t ,"rb") ; 0 if (stream == NULL) C puts("Can't open the εcript file!"); exit(S) : ) •length = filelength(fileno(εtream) ) ; if ( ( eπαth == -ID !! <»length > 32767L) ) C 5 putsC'File size out of range!"); exit(3) ; } script = malloc((int) (*length)) ; if (script == NULL) { putsC'Not enough memory for script!"); 0 ) numread -= fread(script ,1 ,(int) (*length) ,stream) ; if(numread != (int) length)) { putsC'Error reading script file!"); exi (5): J p = script ; 5 flag - TRUE; SUBSTITUTE SHEET 1GET_SCR .C Wednesday , August 31 , 198S Pag do C switch (*mp) C case 253: /* define process id */ case 254: mp++; /* define op id */ op_ιdC»mpJ = mp + 1; while <»(mp++. ) ; brea ; case £55: mp++; /* tranεactioπ type */ op_id[03 - mp; xυ while (*<mp++)) ; break; default: flag = FALSE; 3 ) whi le (f lag) ; return εcript ; 5 } 0 5 SUBSTITUTE SHEET -103- 10.C Monday, October 3, 1988 /* (C) copyright l'SSS Dynix, Inc. written by: J. Wayne Schneider date: 28 July 13S8 These are the 1/0 routines that call the assembly level routines, */ .. inc lude (stdio .h) .. include "sp .h" ♦.include "sp_data .h" ♦. include "sp_gdata .h" /* This routine will return a 1 if data is available or 0 otherwise, It also logs errors if they have occurred on the serial oort. * / int rx_ready(comx) mt comx; c int i; l = rx_εtatus (comx) ; if u ~ 1 > char buff LSI : spπntf (buff ,"rx /.£d '.2x" .comx-017 , ι ) ; disolaytbuff ) : ) return l k 1 ; } /* This routine will output a single cnaracter to a serial port, throttled * l V01 d sputctcomx.c) int comx; int c; C sleep(global .throttle) ; while', iεpuεhc(comx.c)) reschedulei) ; } /* This routine will output a string to the specified oort. throttled void soutsicomx,s) int comx: char <s; SUBSTITUTE SHEET 10. C r-iondav, October 3, 193S Pao 1 . while t*ε != \0'. sputc(comx.* (ε++. ; ; 3 5 /* Get a single character from the input port. Wait until it comes. */ char sgetc(comx) int comx: { 0 mt c: while t (c = soullc co x)) == -1) rescheduleO : return c: ) /* 5 Increment the monitor buffer pointer in a circular faehion. */ char *m_cιrc.m, char ♦m: r m++: if ( >= lm_buff + m_buf _ειsε) ) Q m = m_buff; return m; ) /* While there is room in the monitor buffer, get bvtee from rx_buffer aπd transfer them to the monitor buffer. «/ 5 void ε+lushtcomx.' int comx: t int c: while (m_buff_cnt t m_buff_sιze. 0 if i (c=soullc icomx)) == -1) brea ; »m_buff_ιn = tchar) c; m_buff_ιπ = m_cιrc(m_buff_in) ; m_buf f_cnt++; 5 SUBSTITUTE SHEET -105- , 10.C Nonday, October 3, 1988 Pag /* Clear the input window and send cnaracters to monitor if needed. If that is done or not necesεary. clear the rx buffer. */ 5 void clear_ιnput_wιndow(comκ) int comx; C while ( !s_clear(comx,monitor_porttcomx3)) { sflush(comx) ; /* if s-clear failed, try flushinα «/ ) 0 } /* If we are being monitored, flush what we can and continue. */ void monitor(comx) mt comx: 5 c if .monιtor_port[comχ]) ε tushtcomx) ; ) 0 5 0 5 SUBSTITUTE SHEET -106- MA E ATA.C Tuesday, October 18, 193S Paoe /****** MakeData.c Make session ID file Make random timings data files for testing reduction stuff Rholliπg Stone K. Brook Richaπ CC. 193.5 vnix. Inc. ******/ ♦include "seε_file.h" #include tεtdio.h; #ιncluoe cstring.h. ♦.include .stdlib.h. ReadInt ti int «ι: char sC15]; MakeTimeO C char fnametl4]; FILE* f; TimingRec t ; unsigned int l .nterm.nopid.nrec.wall : printf("Making random timing data file\n"); printf("Enter file name to create) ") ; getsifname) ; if (fnameC0J=='\ ') return; f = open( name,"wb") ; if tf == NULL) tprintfC'No can create file."); -eturn:J print ("number of records to create) ") : Readlnt (Ssπrec) ; printf("number of terminals; ") ; Readlnt(knterm) ; printf("number of op ids? ") ; Readlnt (i.nopid) ; wal 1 = 0; for ιι=i; ιt=πrec; ι++) { t.termno = randOJinterm: t.opid = rand () .nop id; t. stopwatch = (randi '/.4 ,+5; wall +- t.stopwatch*(randO'/.S. ; .wallticks = wall : fwrιte(£_t, sizeof(TimingRec) , 1, f): if (lι'/.100)==0) printf("."); SUBSTITUTE SHEET -107- _ Mri EDA . A .C Tuesday , October 18 , 1 SS Page fcloεe (f ) : •3 MakeSessiont) C char fnameCHJ; FILE* f; SessionID ε; printf("Making session ID fιle\n"); 0 printf ("Enter file name to create (εeεsion.l . ". : gets(fname) ; ■ if tfnameC03=='\0') εtrcoytfname,"sesεion.ID") : f = open(fname."wb") ; if (f == NULL) (printf("No can create file."); return;} strcpvts.machinename,"Tandem VLX") ; strcov(s.memαrvsi2e,"lΞMB") ; 5 Ξtrcpvtε.dιεk5i.:e."3 7eOMB") ; εtrcoy ( ε.databasesιzε,"__00,000 titles; 500,000 holdings: ..0,000 patrons"); ≡trcpv'.s.date."l5 feep SS"; : strcpyts.time,"14:00") ; s.commentC03='\0' : print t"number of terminals used in εeεεion) ") : Readlnt is.nterminals) ; print ("number of trans types in session) "! : Readlnt (ks.ntranstype) : for j for 0 .j. 1 : getε(s.fl lenameCj]) ; print (" expected trans rate) ") ; Readlnt<&ε.transExpRatelj]. ; } fwrite.&s. εi∑eof(SessionID) , 1, f, ; fctoεetf) : } wπteid tf .code . idva l ,s) 5 FILE »f : int code.idval; char *s: t fputctcode.f) ; if (code '.= 255) fputcddval ,f) ; touts(s,f); fputc('\0',f) ; } Makebcπot () ( char fname 14J ,ε[50.l ; FI E* f: mt nopid.i; print ("Making script file\n"); print ("Enter file name to create) ") ; 5 getstfname) : SUBSTITUTE SHEET MAf-.EDATA .C Tl lM .. . Tuesday , uctober 13. 1' SS ■ 'ag i f return: f = fo p en ( fnamε,"wb") ; i f tf == NULL ) ConntfC'No can create file.",; return; } pr i ntf ( "transact i on deεcriotion) ' ■ ) ; qetεiε.- wπteιd(f.S55,0,s): 9= t sιs;, pr i ntf ( "how many op ids ) " ) ; Readlnt(knopid ) ; +01 ( ι=i; ι<=nopid; i++) pr i ntf ( " op 'Ad description) " i ) . oets(s); ' ' } πteιd ( f,254,i,=); fclose(f) ; maint) { char cmd: printf'."Size of TiminpRec = rm " : o ^SS - ^^'.—-^ i m i ngReO , = i -- o t seεs i onlD - /.d\n\π". sizeoftSesεionlD . > cmd = ' ' ; while SUBSTITUTE SHEET EM.C Wednesday, September 14, 1988 Raα ^include tmalloc.h) maini) C int l.newε; int sa,hp,εz; char *ns: news = ( _memavl ( )/3S - S) k OxFFFE; for ( ι=0:ι<=3S:i++) { εa = stackavail 0 ; hp = _memav1 () ; sz = _memmax() ; ns = _πmalloc(news) ; printf ( "J.d .stkavl V.u memavl */,u memmax y, u newstk , sa .hp.εz ,ns ) ; SUBSTITUTE SHEET /102 -110- . OBEΫ.C Monday. October 2. I9aϊ Pa /«*****.. *»»lt****f...«*l.*ι.*l.* *» i.*»*»*l.»**^ Obey the Master commands and route data from C0M1 to the slave taεks. 5 (C. copyright 193S Dyπix, Inc. written by: J. Wayne Schneider date: SI September 1933 Once everything gets set up, this is where the slave processor εoends a good deal of its time. This task responds to all data from tne master. It also handleε transmission of all packets to the master. I * , tit****.*************************************************.****.****.*********/ #ιnclude "sp.h" /*************************************************************IM*4...l!*»-il*I.Jt procedure prototypes ********«************************«κ^ int proceεs_pac et tvoid) : /*****************************************************.****4.****....4**f 4 f 4 OBEY the MASTER Process data from the master and pass packets between tasks ano master. ******************************************** *****************************/ 0 obey_master() { int alive = TRUE; char ar ^packet: do ( 5 p acket = rx_packet ( MASTER_ID ) ; /* see if we received a oackεt vet ». if toacket) { alive = process_packet(packet) ; _ free(packet) ; } i while (alive) : ) 0 /******************* ************* ********************** x tt m-t fttt tmxm procedure PROCESS PACKET *«* ****#***»#***##*4rl>********l.**«**).**|44>***«**l(****j.j,* S )f < » # »«) ( ^ S « j(Λ< ,, ># , tjf/ 5 SUBSTITUTE SHEET OBEY.C Monday, October 3. 19B2 Pa int oroceεε_pac! et () SUBSTITUTE SHEET -112- REDUCE.C Friday, September 16, 19SS Pa /» REDUCE AN OP FILE FOR SYSTAT */ ..include (stdio.h) ..include (stdlib.h) ttinclude "seε_file.h" FILE *stream: FILE *out; main (argc,argv) int argc; char *arαvC3: t int n; TimingRec t ; if (argc t3) C outs ("reduce .fil out.fi I"); exit (1) : 3 stream = fopen(argv[13 ,"rb") ; if tstream == NULL) C putsC'can't open input file"); exit(l) ; } out = fopen(argv[H3,"w") ; while (! feof tεtream)) C n = frea (&t , sizeof (t) ,1.stream) : if in != 1) break; fpπntf ( out ,"y.d,y.d,'/.d,y.d\n",t.termno,t .opιd,t.εtoowatch,t .wallticks) : J fclose(stream) ; fclose(out) ; } SUBSTITUTE SHEET -113- •, b ' LAvt.L " lueεdav. October IS. l÷S'3 ^s Slave - this is the slave task that is started tor each port. it must establish communication with the serial oort and 5 prepare to process a script on command. Contained herein are all of the reporting routines called ov do__=crιpt . .C; copvπght lϋ-SS Dynix, Inc. written bv: J. Wayne Schπeider date: El September lθSS ******************************************************************** **** ' 10 /* #defιne DEBUli */ ..include κmallαc.h. ftinciude .stαio.h) ..include "sp.n" #ιnclude ,r ..include "sp_gdata.h" #ιnclude " .h" procedure prototypes void ρrepare_port nt) : struct s_packet *waιt_for_packet (int ) ; 20 void αo_commaπd unt ,struct s_packet *) : *******************************.***************************.***.********.** ' bLAVE PROCEDURE *****.************************************************.*******************• void slave .taεk_ιo) int task id: 25 C struct sj3acket *rx; prepare_port (task_ιd) ; /* prepare our com port */ for (;:) /* do forever */ . rx = waιt_for_packet (task_ιd) ; n #ιfdef DEBUG print f '."taεk *..α doing packet\π" ,tasι._ιd) ; fcendif do_commano'.taεk_id ,rx. ; } ) 35 procedure Dϋ lO.-.PiήNi. SUBSTITUTE SHEET -114- SLAVE.C Tuesday, October 13, ISBis P Do the command that is specified by the packet. **********..*****-t.ri.*.t).*»*#*)...**l.***^ void do_command(task_ιd,rx) int taεk_ιd; struct s_packet *rx; C int comx = task_id + QάQ ; char bu erClύ]: switch irx-. packetCCMOJ) /* respond to the command */ C case PASS: /* pass data through to host */ £ while (pass_thru(taεk_id,comx)) rescheduleO ; break; 3 case ITEST: /* do an internal port test «/ C rx-;packet[DATA] 1= 0x01; / ' * say it is tested */ if (test_port(comx)) rx->packet DATAJ k= ~0x0≤; /* not found */ else rx->packet DATAJ != 0x02; /* found ♦ tx_packet (rx->packetLSRCJ .task_id,ITEST .ά .k(rx->oaci.e DATA- : break; 3 case ETEST: /* do an external oort test */ £ rx->packet DATAJ != 0x04; /* sav it is tested * / if . loop_test_port (comx/ ) rx-,packetCDATA] k= "OxOS; else rx->packetCDATAJ != OxOS; tx_pac.:et .rx-.-packe C5RCJ ,task_ιd.ETEST .£,&',rx-.packetLϋATA.- break; 3 case ESC: /* αuit this program entirely *. C ever = FALSE; brea ; 3 case EN Q : * identify ourselves to master * buf ferCOJ - number_of_ports ; εtrncpv (t.buτfer 13 .signature .9) ; tx_packet irx-> packet SRCJ ,taεk_ιd . ENQ, 10 , buf fer) brea : 3 defaul t : brea : } SUBSTITUTE SHEET -115- ^ SLAVE.C Tuesday. October IS, 198a Pa _t.reeirx. : /* release packet emor * * : ) I *****.************************************************** ************ **^ . , 5 procedure WAIT_FOR_PACKET Very simplv, wait for the flag tnat εayε we have εomething in our packet buffer. ###****l.*#.c»«*-l..!».*.4***#.t**»#lf##l|**^ in struct s_packet *waιt_tor_packet (taεk_id) int taεk_ιd; struct ε_packet *rx: while ( (rx = rx_oacι.et (task_ιd) . == NULL; reschedule 1 ,, i return rx; 15 , I ***************************************.**************************.****.*.. procedure PREPARE_P0RT lest the com port to make sure it is functioning. Allocate the receive ou+ter and prααram the uart. 20 **.****************************************.**********.**.*************.****. * > void prepare_port<tas.-_ιd. int tas.._ιd; C int l j char far »rx_du er: 25 lπt com:: " : = taεk_ιd + £υs for ,ι=u; ι(S ;ι++) / » try several times to teεt por- »/ ' ι+ (teεt_port(comx?. rescheduleiJ ; else { goooj_ortCtask_ιdJ = TRUE; 30 break j % ; /* allocate rx buffer *■ display("malloc") ; exit'.I. : j 35 seπal_.iRit tcom.-*. /* configure com sort */ SUBSTITUTE SHEET -116- 1 3LA E.C Tuesday, October IS; 19SS Pa _S_DA A, Dlk'.RTS.OUT≤, ERύril . rx_ouffer,RX_bUFFER_bIZt,ISNϋRE_NULL. ; serιa ' ι_ιπιt_ιrιterruct .cαmx.ύ) 10 /* Terminal routines here replace communication to master «. void processicomx.numb, lnt comx, nu p; C comx -= 02 ; T C int report (com ,numb) mt comx. numb; C char c: comx -= 020 ; if mump -= 2) C toupper ( ( char ) _bιos_keybrd (_h.EYBRD_REAL':' i return TRUE : i return FALSt; } 5 void cnecκ_poιπt (comx,op_ιd,op_time,wall_time) int comx, op_ιd; long op_tιme, wall time; t int port; port = comx - 020; 0 3 mt get_data ivar . cnar varϋlOHS J ; { i nt i ; char *oack : 5 SUBSTITUTE SHEET ^ SLAVE.C Tuesday, October IS, 1988 P if (back =- NULL) return EOF: if (strcmp(var[i],"END") == 0) return EOF; if (εtrcmpivarLiJ ."") == 0) break: 3 _ 5 return NULL: } int waιt_for_ooerator'.) £ j 0 int comx: C comx -= 020: return TRUE; ) /*********** procedure pass_thru *********** / ■.ς pass_tr.ru '. aεk_ια, comx) int task_ιd, comx; t int l. ■ ' ■ lag: char DufferLΞOD: struct ε_packet »rx; l - rx_status(comx) ; /* check the host for data */ if (l k ϋh> 20 c for ιi=0;ι(20:ι++) ι+ '. (bufferCiJ = spullc(comx) ) == EOF ) Break; x_o c.-:et . .tas _ι .PAES.I ,buffer) ; . if ( (rx = rx_packe (task_ιd)) != NULL) 25 { flag = TRUE; switch (rx-)packet CMDD. C caεe PASS: for(1= ;l (rx->packetCLEN3- ;i++) whιle( !εpuεhc(comx,rx-. oackettDATA+iD) ) rescheduleO ; •jn break: case "PASS: flag = FALSE: break; case PASS_BREA : * pasε a break to tne host • sleep(1) : com_break(comx,D ; sleep(1) : com_break(comx,0. ; 35 sleep(l); SUBSTITUTE SHEET SLAVE.C Tueεday, October 13, 193S Pac break } _ffree(rx) ; return flag; } -eturn TRUE; SUBSTITUTE SHEET , SLEEP.C Friday, September 16, 1988 Pa /* Sleep for "n" clock ticks. Use sleep(1) to svnc with the clock before beginning the actual timing. A sleep(0) does nothing. We always enable interrupts to Pegin. 5 *t ttinclude (bios.h) void sleep(n) unsigned int n: C long tm.new tm; 0 enable_ι () ; C _bios_timeofday(_TIME_GETCLOCK,&tm) ; do { rescheduleO ; _bιos_tιmeofday(_TIME GETCLOCK.knew tm) ; ) while (new_tm < (tm + n) ) ; 5 3 ) 0 5 0 5 SUBSTITUTE SHEET SP_0ATA.C Tuesday, October 18, 1988 Pag /* ύlobal Data definitionε for SP (C) copyright 1988 Dynix, Inc. written ov: 3. Wayne Schneider αate: 29 July 1988 */ #include "\rhoboUsp_data.h" int oerformaπce_check[0603 : int monιtor_portC0603 ; char m_buf f Cm_buff_sιze3 : int m_buff_cnt = 0; char *m_puff_ιn = m_buff: char *m_buff_out = m_buff; lonα dav time: cn ar » co _ι α _mεα L ' J ; char »orαεess_ιd_msgL503 : char 5tatus_mεgi4]L15J = ( ("Success") , ("Failure"), {"Timeout"). {"End of data") ): struct t_str trans: struct g_str glooal ~ C /* 2 second think time */ 40. 1200, 4 /* l minute time out */ ) ; /* 50 worn tyoe rate */ unsigned εtack_sιze; char *eιgnature = "\0"; /* front panel dieplay */ SUBSTITUTE SHEET _ SP_GDATn.C Tueεday, Octooer ii , lyS t. Paα /* SP global data declarations ( C ) copyright 1988 Dyπix, Inc. written by: J. Wavne Schneider 5 date: 1 September 1988 */ #mclude (εtdio.h) #include "task.h" ..include "so_gdata.h" 10 int good_portE32) ; int #curtcb; FILE »εes_file: FILE *err_f le; ic int πumDe'-_o _ports = 32: struct ε_tcb tcb[33J: cnar t:-_answer[32) : int ever; 0 5 0 5 SUBSTITUTE SHEET -122- SP_SETUP.C Friday, September 16, 1988 Pa 1 /* Serial Port Setup muεt look for all 33 ports; initialise all 33 ports, and allocate the buffers for all 33 portε. We do our beεt to validate the functionality of the ports. Any part that fails, will be ignored later. (Except C0M1. If it fails, we _ beep the beeper in desperation.) o (C) copyright 1988 Dynix, Inc. written by: J. Wayne Schneider date: 1 September 1988 */ #include "sp.h" 0 #include "sp_gdata.h" #ιnclude "serial. " ♦include (bios.h) /* Make a cheerful tune on the beeper */ chirrup tuneO « sleep(1) ; utspkr(600) : slee (2) ; utspkr(SlXO ; εleep(2) ; utspkr(900) ; sleep(2) ; utspkr(0) : ) /» Make a sad tune on the beeper to indicate failure */ sad_tune() ~{ utspkr(200) ; sleep(10) : utspkr(100) ; sleep(10) : utspkr(0) ; ) void seπal_port_setup(n) int π: c int l ; for ( i = 0 ; l < 020+n ; ι++ ) { good_portti) - test_port(i) ; ) SUBSTITUTE SHEET SP SETUP. C Friday, September 16, 1988 Pa if ,good_portl_l). chιrrup_tune() ; else sad_tune() ; ) SUBSTITUTE SHEET RND.C Wednesday, August 31, 1983 Pag /* and_norm( mod , type) ; Generate a random number of 'type' 'A mod+1; If type == 1 we get a uniform distribution; If type == 4 we get a normal distrubtion (bell curve); One is added to the 'mod' so the value returned is 0 (= r <= mod. <C) copyright 1988 Dynix, Inc. written by: J. Wayne Schneider date: 29 August 1988 */ ..include "sp.h" ♦include (stdlib.h) int rand_nori7> (mod, type) int mod; int type; { int i; long sum=0; for (i=0;i <type;ι++) sum += ran O 5. (mod + 1); return sum/type; ) SUBSTITUTE SHEET -125- 10 15 APPENDIX D Title: Task Scheduler and Serial Driver Code Modules: TASK.ASM and SERIAL.ASM 20 25 30 35 SUBSTITUTESHEET -126- TASK.ASM Friday, September 16, 1938 P TITLE TASK_SCHEDUL£R for MSC .236 .MODEL COMPACT (C) copyright 1938 Dynix, Inc. date: June 30, 1988 written by: 3 . Wayne Schneider EXTRN ST HQQ:W0RD EXTRN _curtcb: WORD next EQU 0 ;tcb array indexes nexts equ 2 spsave EQU 4 sssave EQU 6 sisave EQU 'ύ status EQU 10 .DATA temp dw 7 temporary storage .CODE PUBLIC _fιrεt_task, _create_task, _reschedule FIRST_TAS (tcb_array_ptr) This routine must be called bv the mam routine to create a TCø for the main routine. Nothing else works until this has been executed. The tcb pointer is an array of four pointers iwords) . FIRST TASK PROC NEAR push bp mov bp.sp mov dx,SEG _curtcb mov eε,dx mov ax,word otr ee:_curtcb ;Don't allow it to happen twice or ax, ord ptr es:_curtcb +2 jn_: ftdone mov d :,Cbp+6) mov bx,Cbp+43 ;bet the tcb pointer mov word ptr es:_curtcb ,ι :An_! lm t il ire mov word ptr es:_curtcb ++:2 ,dx mov es.dx mov ax,stkhqq mov es:sIsaveLdx) ,ax mov essnexttbx),bx ;Lιnk to self SUBSTITUTE SHEET ■ 127- TASK. SM Friday, Si Pa mov es:nexteCbχ] ,dx mov es:sssave[bχ] ,sε mov word ptr eε:statustbχ] ,0 ftdone: mov sp.bp pop bp ret FIRST TASK ENDP CfttATE_TASK(tcb_array_ptr, stack_ptr, stack_sι∑e, functιon_ptr, t,ask_ιd) Create a new task using a new tcb, stack, and the specified function as the starting point. The long stack pointer must be both segment and offset. No argumentε can be paseed to the function. The task_id is an integer used to identify the taεk to itself. CREATE TASK PROC NEAR push bp mov bp,ερ push si ouεh di mov dx,SEG _curtcb ;Make εure f irst_task has run mov es.dx mov bx.word ptr es:_curtcb mov dx.word ptr eε:_curtcb +2 mov ax,bx or ax,dx JΞ ctdone mov es.dx mov ax,[bp+43 ; ;66et tcb pointer k ink i t i n mov cx,Lbp+&] mov si ,es:next[bxJ mov di ,es:nextstbχ] mov es:nextCbχ] ,ax mov es:nextsCbx3 ,cx mov bx,ax mov eε,ex mov es:nextCbx_l ,sι mov es:nextsLbxJ ,dι mov ax.εε ; ;SSet stack poi nters mov es:sssavetbχ] ,ax mov cx,Cbp+S] mov es:slsavetbx-l ,cx mov word ptr esrstatuεCbx] ,0 ;Clear the status dx ,sε Save our own SS ,SP SUBSTITUTE SHEET -128- TASK.ASM Friday, September 16, 19S8 P mov dι,sp mov sι.Cbp+143 5Set the t s _ιd number mov temp,si mov ει,Cbp+123 ;Set function address add cx,Cbp+103 :set sp at end of area mov εs,ax mov εp.cx push temp jPasε his task_id push offset TASK_EXIT :Load his stack push si push ex mov es:spsaveCbχ],sp ;Set his stack pointer mov ss,dx ;Restore our stack pointer mov sp.di ctdonε: pop di pop si mov Ξp.DD POD bp ret CREATE TASK ENDP TASK_EXIT is called whenever any task except main, executes off the end of the code, meaning, it does a RET. When that occurε, we remove them from the tcb chain. TASK. _EXIT PROC NEAR mov dx,SEG _curtcb ;Get current TCB ptr mov es,dx mov bx,word ptr es:_curtcb mov ax,bx mov dx,word ptr es:_curtcb+2 mov cx.dx mov es,dx ;6et link from TCB that's done mov si,es:next[bx3 mov di,es:nex sCbx3 mov word ptr es:statusCbxD,S0h ;Flag it as done tel: mov dx,es:nextsCbχ] ;Set next usr TCB otr mov bx.es:nextCbx3 mov es.dx cmo ax,es:next£bx3 ; and see if we match it .ine tel cmp cx,es:nextsLbx3 te2: mov es:nextCbx ,ει ;Store the new link mov es:nextsCbx ,dι jmp short next usr TASK EXIT ENDP ■ 129- TASK .ASM Friday, September 16, 19SS Pag RESCHEDULE() This routine is called any time a task reschedule is desired. It should most likely be called any time a task finds itself waiting for any reason. This buddy system of taεk scheduling works well if all tasks comply. .RESCHEDULE PROC NEAR push bp mov bp,sp mov dx.SEG _curtcb mov es,dx mov bx.word ptr es:_curtcb mov dx,word ptr es:_curtcb +2 mov ax.bx or ax,dx .12 rdone mov es,dx mov es:spsavetbx3 ,bp :Save current user SP next_usr: ::**<** entry from TASK_EXIT mov cx,eε:nextεtbx3 ;Get next usr TCB mov ax,es:next£bx3 mov dx,SEG _curtcb mov es.dx mov word otr es:_curtcb ,ax ;make him current mov word ptr es:_curtcb +2,cκ mov es,cx mov bx.ax mov ax,es:slεaveCbx3 ;Load his stack limit mov stkhqα.ax mov bp,es:spsave£bx.3 ! and his stack mov ax,es:sssaveCbx.3 mov ss,aκ rdone: mov sp,bp pop bp ret - .R'ESCHEDULE ENDP _TEXT ENDS END -130- SERI L.ASP! Tuesαav, October IS, 1933 :, aα ITLE SEftI L_5ER lCE .286 •MODEL COMPACT.C (C) copyright 1983 Dynix Inc. written by: J. Wavne Schneider date: 12 .'ulv 1988 The routines containeα in this module are for serial port 1/0 include DOS BIOS.INC INTCNTL equ 20h :interrupt control port INTMASK equ 21h ; nterrupt mask port INT2CNTL equ OAOh I T2MASK equ OAlh DR¬ equ 0 {Data register IER equ 1 :interruρt enable register IIR equ 2 ;Interrupt identi ication register LCR eq :Lιne control register MCR equ 4 :Modem control register LSR equ D :Lιne status register MSR equ 6 ;Modem statuε register SCR equ 7 ;PCSS scratch register LSD equ 0 ;Least significant divisor MSD equ 1 ;Most significant divisor THRE equ 20h ;Transmιt Holding Register E ptv RDAI equ 04h :Rx data available nterupt IGNORE NULL edti Olh ;Buffer control bits baud_tao l ow 57600.3840 ,2S8O0,23040,1920υ,1 4u-.',1c.8w,11 ' < d 960 , 30 ,240 .120 .600,300 baud_table_length eαu (*-baud_table)/2 diviεor dw 2. 3. 4. 5. 6. -3. 9. 10 dw 12, 24, 43, 96,192,334 com_to_adr dw 000 .3f3 .2fS .3e3h,2e3h,2fOh,2e0h,3e0h com_to_ιnt db 0, 4, 3, 5, 7, 9, 0, 0 int to com db 0. 0, 5, 2, 1. 3, 0. 4, buff_taole dd 40 dup '.0) vect_save dd 10 duo (0) :Storage for vectors vect_new dd ;Vectorε for mt 0-9 dd tj dd FAR PTR =er_ιnt2 dd FAR PTR ser_ιπt3 dd FAR PTR eer_ιnt4 aa FAR PTR ser ιnt5 1 ShRiHL.M M fueεday, October 18. 1 £ dd 0 dd FAR PTR ser_ιnt7 dd 0 dd FAR PTR ser int? buff_base EQU 0 buff_εise EQU sDis p lacements into a com d uffer 2 datajDtr EQU 4 view_ptr EQU 6 buff_status EQU buff_contro iThis is one byte long I EQU 9 buf _header ;Cαntrol byte EQU 10 10 :Length of header .LODE con . _t . reak i comx,n. Enables ιn=l, or d isables .n=0. break ; com_brea PROC comx:WORD, n:W0RD push com;-: 15 ;Bet the oort addres call get_com_adr add εp.2 add dx,LCR in l.dx and l,3Fh cmo n.υ or a I ,ψ..)f, @ e . 20 out dx.al st: ret com_Prea.- ENDP rx_εtatuε i comx . Returne TRUE if a character i s read y or error 25 The TRUE value contains the status indicators. r. statuε PROC USES DI DS. comx: WORD mov bx.co x :6et the buffer address call gεt_port_buff : ιnto DI:DX mov ax,αata_ptrLdι] c o ax,vιew_ptr£dι] mov ax , 0 oe (5F 30 mov ax , 1 or al ,butf_εtatusCdι] ov BYTE PTR buff_εtatuεLdιJ,0 ret jClear the old etatus rx .s tat us ENDP ,_ i soullc ( comx. 1 Returns the next available cn aracter or OxFFFF I* none. SUBSTITUTE SHEET -132- SERIAL. .ASM Tueεday, , October 18. 19SS Pa spullc PRϋC USES SI I DS. comx; :W0RD mov bx.comx ;Set the buffer address call get_pαrt_buff : into Dl :D.X mov bx,vιew_ptrCdι] cmo bx,oata_ptrtdij mov ax,0FFFFh ; eturn -1 if none ret Sis : mov si ,buff_baseCdι2 mov aI .tbx+ei] sub ah,ah mc bx cmp bx.buff εiseCdi-l .11 @F sub bx.bx \≤\≤ : mov vιew_ trLdι ,bx ret spullc ENDP Thie routine will output a single character to the COM port If the port iε not readv. 0(z. is returned, otherwise l.nr spushc PROC USES DI DS,comx: ORD,char: ORD push comx :Get the uart address call get_com_adr add sp,2 add dx.LSR in aI ,dx sub ah,ah and al.TriRE J2 SF ;Return failure add dx,DR-LSR mov ax,char ;0utput tne character out dx,al sub ax,ax ;Return succeeε ine ax ret souεhc ENDP ; This routine will teεt the com port for output buffer ready. tx_status PROC comx :W0RD push comx ;6et the uart address call get_com_adr add sp,2 add dx.LSR in aI .dx SUBSTITUTE SHEET -133- SERI L. SM Tuesday, October IS, 19£iS : 'ag sub ah,ah and al.THRE ret tx status ENDP Tnis routine will clear the input buffer and reset tne count. If the flag is set. we must check for empty before clearing. If it is not emptv, we return FALSE ELSE we return TRUE. s_clear PROC USES Dl DS ES, comx:W0RD, flag:WORD mov bx.comx :bet the buffer stuff call getjoort_buff cli jDisable interrupts th>-. this test f lag .OFFFFh :See if the flaα is set J2 ι?F cmo ax,vιew_ptrCdι] eti ;Return false if not e Dtv SLID a ,ax ret _£: mov cx.data_ptrl.di] ,.CX-. isF :Don't do a nothing mov a ,0 mov data_ptrCdι3 ,ax ;Clear the count mov vιew_ptrCdιJ,ax mov di .buf _baeeCdi] mov bx.dε mov εs,bx rep stosb sub a .ax ine ax ;Return true ret s cIear ENDP ; This routine returns a far pointer in DΛ:HΛ to tne ports f er s_butfer PROC USES DI DS , comx:μ.URD mov bx.com.. call get_port_bu mov dx.dε mov ax.di SUBSTITUTE SHEET SERI L.rtSπ Tueeday, October IS, ι*__ Paα ret e_buffer ENDP Thie routine sets the 3250 parameters only. εeπal_ιnιt PROC USES DI ES, com* . WORD,baud:WORD, Iine:WQRD,mo d p . n :W0RD,\ i nterrupt :røD.buffer:PTR BvTE. p _sι,e:w D. oήt'"Ol :wiir:D push com.. call lύisable all interrupts +■_ . ■- get_com_aαr now add εp.2 add dx.IEft sub al ,al out dx.al add dx,LCR-IER mov ;Set tne baud rate first aI ,80h out dx.al mov cx.baud_table_leπgth lea di, baud_table mov ax,DGROUP mov es,ax mov ax,baud eld repne εcaεw mov ax, . θ aιιd_tadle_leπgth - 1) * ?r B ,] add dx.LSD-LCR out dx,al add dx.MSD-LSD mov a I ,ah out dx.al add dx.LCR-MSD mov a Λ ,lιπe Oa ϊ^r 5Set tne W ^ C ^gth, εto P , et ado αx.MCR-LCR ;Set DTR) RT mo ax. mo d em -. -._. out dx,al in' aϊ,'dχ R ~ MCR ?Clear PSnding »t»rru D t. add dx,DR-LSR in al.dx in al,dx add dx.MSR-DR in a I , dx add dx.lER-MSR jEnable the orooer interru p ts mov ax. interr pt out dx.al a d d dx,IIR-IER ; and clear Tx mt p end i ng SUBSTITUTE SHEET -135- fi SERIAL.A5M Tuesday, October IS, 1 BS Pa add dx ,SCR-I IR and scratch latch idummy jmp short G?F __. and al .07h ;dummy jmp ehort @F out dx ,al sti {Enable interrupte again mov bx.comx initialise data εize k pointers cmp bx,7 ;Convert for "c" to form "cu" Jd @F : with "u" = 0 sh1 bx,3 __(?: sub bx,10q ;Load otrε to DI :ES shl bx.2 leε di .but+er mov ORD PTR buff_tableCbx3,dι ; and then into the table mov WORD PTR buff table+2Cbx3.es mov bx.buff_header ; uff begins oust past the header mov es:buff_base[dι3 ,bx mov cx,o_sιze sub cx,bu++_header ; Make room for header dec ex and a null at tne end mov es :Duf f_s ι zei.d ι ] ,cx mov ax , ontrol Store the control byte mov es:buff_controlLdιJ ,al xαr ax,ax Clear the insert k remove pointers mov eε:data_ptrCdi] ,ax mov es:vιew_ptr[di3.ax mov es:buff_statustdι3 ,al mov di .ee:buff_baεe£di] ;Now clear the whole buffer ine cx rep stosb ret serial init ENDP This routine setε up the interrupt vector and interrupt maεk according to the com number passed: 1 = C0M1 2 = com2, etc. Com number can also be lOq for C0M1 , 2ύq for com2. etc. : The mask will enable interrupts if 0 and dieable if 1 If the vector hae already been saved, we don't save it again. The flag returned is FALSE if the vector was not set when called. The flag is returned TRUE if the vector wae alreadv set when called, serιal_ιnιt_ιnterrupt PROC USES DS ES Dl , cofr.ΛiWORD, Imas.. :WORD LOCAL flaα:WORD mov D-.,com: ;Usιng con..* gel * .r-e m e^-uot cmp b.,.? :Loπvert torn. "~' " t form "c SUBSTITUTE SHEET -136- SERIAL .ASM Tuesday , October IS, Pa Jle QF εhr bx,S f&l . ; and bx.07h w* mov al ,com_to_ιπttbxJ :Set the εtoraoe pointer in DI cbw mov di .a:-: snl di ,2 mov dx,INTMAS. : . ;Select k setup each Stf-' add a.. o cmp ax,15 .'Adjust for 2nd εet Jle έF add ax,έ0h mov dx.INT2MASf. _lg ; push d.. teεt imaεk.OFFFFh :If (mask == TRUE.' 3Z sn_l mov dx,W0RD PTR vect_εavetdι] ;I-f isaved_vector '= 0) mov ex. ORD PTR vect_save-ι-2[dι mov bx,cx or bx.dx mov flaq.bx ;eave flaq 32 sn_3 mov dε,cx :set the old vector back DOS Set_Iπterruρt_Vector :DS:DX jmp short sn_3 su l i mov dx.WORD PTR vect_savetdι] :If tsaved ^ ve cr == 0." mov ex, ORD PTR vect_save+2Cdι3 mov bx.cx or bx,d:-: mov f lag .bx :save f lag Γ su 2 DUS &et_interrupt_Vector ;Get the old vector ES:fcfλ mov W0RD PTR vect_saveldιJ,bx :and save it mov bx.eε mov WORD PTR vect_save+2[dι] εn c. mov dx.WORD PTR vect_πew[dι3 ;6et the new vec mov ex.WORD F'TR vect_.new-r2- i- mov ds.cx DOS Set Interrupt Vector :DS:DX Sll and ax.07n :&et int number back +or mas. mov ex,ax :Enable interrupts throuπh 325'^A mov ax.lmask mov ah,01h s l aκ.cl not ah SUBSTITUTE SHEET •137- SERlA .ASr-1 Tueεdav, October IS, ly£ Pa mov b1 ,a1 :Save the mask and set the chip POP dx in al.dx and aI ,ah or al.bl out dx,al mov ax, lag :Return lag value ειι_4: ret serlaI_ιmt_ιnterrupt ENDP ************** The following routines are NOT callable bv C get_port_buff Returns in DI :DS tne address of the ports buffer It expects the com/uart number in BX get_port_buff PROC NEAR USES BX cmp bx.7 :Convert for "c" to form "cu" O 6.F : with "u" = 0 shl bx.3 __. sub sx,10q (Load ptrs to our bu++er shl bx.2 Ids αi ,buf _ta le[bx3 ret get_port_butf ENDP get_com_adr Returns in DX k AX tne address of CC'Mn it expects the "n" in COMX "n" must be of form "c" or "cu" where c is com number and u is uart number oet com adr PROC comx:W0RD mov bx.comx cmp bx,7 ϊConvert for "c" to form "cu" Jd gcpl ; with "u" = 0 ehI bx.3 Q" 1 push bx shr bx,2 ;Set tne COM oort address and bx.OOOEh :index into the table mov dx,com_to_adrLbχ] pop ax :Now set the scratch register Ξ short gcp2 ;Return zero if failed and ax.7 add dx.SCR cli ;D1SABLE INTERRUPTS =o tney dor't out dx.al : cause conflicts with scratch rec SUBSTITUTE SHEET 1 SERIAL.ASM Tueedav, October IS, ISQi Paα :dummy jmp short sF ee: add The caller must enable interrupts dx,DR-SCR .imp εhort gco2 gcp2: mov ax,dx ret get_com_ _adr ENDP * ************** seria l interrupt service rout i nes ser intc. PROC FAR j IR Q 2 service for CON 5 ousha :Save all of the register mov bx,2 ;Identιfy ourselvee cal1 ser_ιπt ;Servιce the interrupt oopa iReεtore everbody iret ser ιnt2 :ππd give uo the gnos t ENDP ser int. PROC FAR :1RQ pusha -ervice for 10M mov bx,3 call ser_ιnt popa iret ser_int3 ENDP ser iπt PROC FAR ;1R Q 4 service for COM 1 usha mov bx,4 call ser_iπt oopa iret eer_ιnt ENDP eer int 5 PROC FAR ;IR Q 5 service for COM 3 pusha mov bx,5 call ser_int popa iret εer_ιnt5 ENDP εer int 7 PROC FAR :IR Q 7 service for COM pusha mov bx, ? c ll εer_ιnt oopa iret eer_ιnt7 ENDP eer int S PROC FAR :IR Q S service iε special pusha SUBSTITUTE SHEET SERIAL. SM Tuesday, October IS, 1 S£ ι-'aαe mov bx,9 call ser_int ; returns w/ 20h in al out INT≤CNTL.al oopa εer_ιnt ENDP ser int PROC NEAR :Hll p orts serial service PUSH cs : mov Preserve user's seαmer.*. reciste- cx.έDATA mov s.cx mov bl ,ιnt_to_comCbxl shl j Set the com num b er bx .1 mov :Set the com address dx , com_t o_adr Cbx3 shl bx.E add dx.SCR in al.dx :PCS5 select 2250 thru scratch and al,07h or l.al out dx.al : dummy jmp εhort fiF _|9. add dx,HP-5CR in :Be sure it is rx nt al,dx test iThis clears tx int al,RDrti jn∑ iHandle rx k/or status int RDAS add dx,MSR-HR in ;Clear the modem εtatuε mt al.dx RDA5 : add dx.DR-lIP ; dummy omp :Poιnt a*, αata reoiste- snort (εF mo :get the characte r snort G.F :&*: :DUMMY mov al. 'U' out dx. l mov ; UMMY tor test ah. a I add dx,LSR-DR m ; and the status a I ,dx and al,lEh sub Dx.lOq shl ;Load otrs to our buffer bx.ώ Ids dι,bu f_table[bχ] mov fcx.ds or :Check for valid b u fev bx,di 2 sππ S or an ,an jnz :Check for null sπntl TR buff contr .3,IGN0RE „ NUL : and ignore if necesεar-, SUBSTITUTE SHEET SERIAL.HSP; 'uesd y, October !£-, r_ι:__£: sπntli mov bx,data_ptrC ι j ;get 'empty pcmter mov εi ,buff_baεeLdi] mov Cbx+si] ,ah ;load character into buffer ine bx :increment DOinter cmp bx,buff_si_eCdi] ;end of buffer? i\ επnt2 sub bx,bx or a I ,40h srintE: cmo and set wrap around flag bx,vie _ptrLdι3 -ie sππtS mov data_ptrtdι3,bx : update oointer mp εhort επntl επntS: Di¬ a I ,S0h sππtn: or ;Set the buffer over-Mow +I 5. 5 buff_statusCdiD,al sπn S: : and save the status mov l,20h {signal an end to interrupt out ιntcntl,al pop ds ret εer_ιnt ENDP _TEX r ENDS EMD SUBSTITUTE SHEET 10 15 APPENDIX E Title: Summary Statistics Code Module: SS.C 20 25 30 35 SUBSTITUTESHEET 69 -142- SS.C Tuesday, October IB, 1983 Pa SS.C Calculate summary statistics for responεe times and oaciπgs! provide mean and std.dev. by op id and by terminal output ASCII files for graphics packages Rholling Stone K. Brook ichan (C) l'_>88 Dynix. Inc. * * ****/ tinclude "seε_file .h" ttinclude "menu ind .h" #include .stdio .h. 1 ..include .rnath .h) #ιnclude <memorv.h, #mc lude (strinα .h. /******* G L 0 B A L S *******/ SeesionID session; /* file name stuff */ char «ses_dflt = "*.ID"; char seefnameCSO ; /* name of seeεion file, minus the extension * /* resDonse time stats by op id */ #defιne MaxOpid 256. unsigned short n_opιdCMax0pid3: unsigned long sumx_ODidCMaxOoid] .sumx2_opid[MaxϋpιdJ ; unsigned short max_opi [MaxO d] ,min_opιdCMaxDpid] : /* duration stats by terminal */ uneigned short π_term MaxTermiπaU: unsigned long sumx_termCMaxTerminal3,sumx2_termtMaxTermιnaU ; unsigned short max_termtMaxTermιπalD,min_term r MaxTermιnal-l ,; /* transaction rate stats by terminal </ unsigned short laet_walI[MaxTerminal 1: unsigned long sumx_tran[MaxTermιnaπ.εumx2_tranC. f, laxTermmaij : unsigned snort max_tran[MaxTeπnιnalJ .min_tranL.*iaxTerm:nalj; » descriotive strings */ #defιne DescBufsize 3000 unsigned char deεcCDescBufεizε]; /* buffer for script file neader ♦ short oescldxLMaxUDidJ: /* offset into -desc' for eacn op id description •_ /* User interface stuff </ MENU mainM: WINDOW infoW; SUBSTITUTE SHEET -143- SS.C Tueedav, October IS, 1S88 Pa /******* E N D S L O B A L S *•******/ int Setbession.) /* return l if successful *.' C ctι .τ fnameL-SϋJ ,*from.*to: FILE-* + ; int l : GetFileName("Name of Session flie" ,ses_dfIt ,fname) ; if .+nameL0 =='\0') C DialogMsgC — no file found or chosen"); return(0) ; } /* back up to end of path, if any */ for (ι=strlen.fname)-l : ι>=0 kk fnameCi].'-' :' kk fnamed] !='W; i—); /* coDv file name .minus the exteneion) */ from = fname+ι+1 : to = eeefname; while (<*from!='\0') kk .*from!=' . ')) *to++ = *from++; *to = '\0': f = fopeni name."rb") ; if ( f==NULL) C DialogMsgC — error opening seeεion file"): return.0) ; } fread(ksesεion.sizeof(SessionID) .1. ) : fcloseif) ; return .1) ; } FILE* MakeOetFi le(. C char detnameL≤OJ; FILE* f: strcDy ( detname,sesfname) ; etrcat .detname." .DET") : WrιteWιndow(£αnfoW,4,0,WHITE!INTENSITY,"Details reoort file:") ; WrιteWιndow(fc.ιnfoW, ,21.WHITE,detname) : f = fopenιdetname,"w") ; if (f==NULL) t DialogMsgC — error creating details print file"); return(NULL) ; } fDπntf(f,"Machine: Ks\n" ,seεsιon.machιnename) ; fprlntflf,"------------------=--=--==-====--\ n "; : fprmtftf ,"Memory εize: */.s\n" ,session.memorysizε) ; fpπntf ( f."Disk size: ; fpπntf ( f,"Data base size: '/.s\π",seseιon.databasesιze) ; fpπntf ( f."Session date: .session.date) : SUBSTITUTE SHEET ss.c Tuesday, October 18, 1988 ■ 'aα fpπntf(f,"Session time: '/.s\n" .session.time) ; fpπntf(f."Comment : !.s\n" ,session.comment) ; fpriπtf'.f."\n") ; fpπntf(f," \n"); fpπntf if . " times are given in secondεXn") ; fnπntf '.f ," \n" ) ; " fpπntf if , "\n" ) ; return (f ) ; FILE* MakeS yFi le O c char smynamεCEOJ; FILE* f: strcpvl5myname,sesfname) εtrcat tsmvname." .BMY") ; WriteWindowt&infoW,5,ύ,WHITE!INTENSITY."Summarv reoort file:") ; WπteWindow .kinfαW.S.≥l..JHITE.smyname. ; f = toDen(emvname,"w") ; DialogMsgC — error creating summary print file"); return(NULL) ; } fpriπtf(f,"Machine: ,session.machinename) ; fprmtf.f,"Seeεion date: .seesioπ.date) : ■ fpriπtf( ,"Session time: '/isXn".session.time) : fpπntfif,"Comment : */.s\n" ,session.comment) ; pπntfif,"\n". ; fpπntf(f," \n"); fpπntf(f." times are given in secondεvπ") : fprmtf.f," \n"); fpπntf f,"\n") ; fpriπtf(f," Pacing Throughput Response tιme\π") ; fprintf(f,"Expected Actual Expected Actual Average Std Dev Transactιon\n") : fpπntf(f," \n" return(f) ; ) FILE* MakeSmydatFileO C char smynameC20]; FILE* f: strcov -smyname.seε name) ; strcat ismyname." .DAT") ; Wrltewindow .ϊ.ιn+ow, ,40.WHITE:INTENSITY ."Summary A: :lo. WrlteWinαow(i.ιnfoW. .60.WHITE.εmyname) : f = fθDen(smvname,"w") ; if (f==NULL) C DialogMsgC — error creating summary ASCII file") SUBSTITUTE SHEET -145- SS.C Tuesday, October IS, 19SS Pa return.NULL) ; } fprintf(f,"tran,averesD,stddev\n") ; /* column labels */ c return(f : } SetupFi lettnum,f_oD, _durdat ,f_opdat) int fnum: FILE *»f_op,+ * f_αurdat,*<f_opda ; C char fnameC≤OJ,sfnameC21; FILE *f: ® int l,opιd,dtype,row,col; etrcpvtfπame.session.filenameLfnumD) ; strcati name,".OP") j row = 7+(fnum'/.10) ; col = (fnum/10)*40: WπteWindow(kιnfoW,row,col,WHITE,fname) ; strcpyisfname.sesεion.filenameCfnum]) : 5 etrcat(εfname,".SCP") ; f = fopen(sfname,"rb") ; if (f==NULL) ( DialogMsgC — error opening script file. Proceeding with r.c labels".'; -else C tread(desc,DeεcBufsιze,l ,f) ; fclDseif) ; 0 /* se t up indexes to op id descriDtion strings */ l = 0: while (descCι3>2=.E) ( dtvpe = desctι++]: if (dtype == E55) opid = 0; else i f (dtvoe == 254) oDid = descC i- 1 -!-] : else Copid = -1 ; i++ ; } /* ignore dtype == 253 * / if (opιd) =0. descIdxtopidD = i : 5 l += εtr len .ϊideεcC ι ] ) +l ; i *f_op = fopen( name,"rb") ; strcpvi+name.sesεion.filenametfnum]) ; strcat(fname,".DUR") ; WrItewindow(&ιnfoW.row.col+lci.WHITE,fname/ : *f_durdat = fopen(fname,"w") ; 0 fpriπtf(*f_durdat."term.dur,wall\n") ; /* column labels */ strcpy(fname,session. ilenameCfnum]) j strcat(fname.".DAT") : WπteWιndow(ΣnnfoW,row,col+26.WHITE,fname) ; *f_ODoat = fopen(fname,"w") : foπntf ι f_oodat ; /< column labels 5 InitCountsl) SUBSTITUTE SHEET 69 ■ 146- SS.C Tuesday, October Id, l'SS Pa memset(n_ooid, '\0',sι_:eot(n_ooιd)) ; memset(sumx_opid. '\0' .sizeo 'sumx_ODid)) : memset ιzeof(sumx£_opιd)) ; memeet izeoftmax_opιd)) : memset ,sizeo (mιn_QDid>) ; memset ι.π_term, '\0' .sizeof(n_term)) : memset (sumx_term . '\0',sizeof(sumx_ter.τι) ) ; memset(sum>£_term, '\0'.sizeof(sumx2_term)) ; memset (ma'_term, '\0'.sizeof(m s_term) ) ; memset (mιn_term, '\.-.FF' ,eιzeo+(mιn_term)) : memset(sumx_tran ,'\0' ,sizeof(sumx_tran)) ; memset(sum^2_tran, '\0' ,sizeo (su '2_tran)) : memset (max_traπ, '\υ' ,sιzeo + (max_tran)) ; memse (mιn_tran, '\xFF',sizeof(mιn_tran)) ; memeet(descldx , (deεcldx)) ; i 5ummaπze(f_op,f_durdat ,f_opdat) FILE *f_op: FILE *f_durdat ; FI E *f_opdat; ( TimingRec t; short new_wal1 : lonα tran time; fread(!t .sizeot(TimingRec..1.f_op■ : whi le ( 'feo-rlt_op)) '. n_opιdCt .opιd3++: sum.x_opidCt.opid] += t.stopwatch; sum>'2_αpιd[t.opidD += (long)t .stopwatch* (long. t .stopwatch: if (t.5topwatch(mιn_opιdCt .opιd3) mιn_opιd£t .opιd]=t .stopwatch; if (t .stopwatch,max opidLt .αpιd3) max opidCt .0Did3=t .stαowaten: if (t.ooιd-=0) £ /* duration opid */ n_term r t.termno3++; 5umx_ter.nCt.termno3 += t.stopwatch; 5umx2_termCt.termno] += (loπg)t.stopwatch* (long 1 .stopwatch: if (t .stopwatc <mιn_termCt .ter no]) mιn_termCt.termno] = t.stopwatch: if (t .stopwatch>max_termCt .termno]) max_termCt.termno] = t.stopwatch: new_wall = t .wallticks-t.stopwatch; /* transaction begin time */ 1-* (n_term£t .termno3==l) last_wallCt .termno] = new_wall: else £ traπ_tιme = new_wall - last_wall t .termno3: last_wal tLt.termno] = new_well: sum; _tramt .termno] += tran_tιme; su '£_tran£t .termno] += traπ_tnτιe*t r "an_tιme: ι+ ' tran_t ι e(mm_tranCt .termnoJ ) mιn_traπC t . ime : it ( traπ_t ιme. ma v trsπ. t . termnoJ > a- farLt . ime : SUBSTITUTE SHEET -147- SS.C Tuesday, October IS, 19SS Pa fcπnt (f_durdat , "'Au,'Au ,A' u\n" ,t .termno.t .stoo atch,t .walIticks) ; 3 else tpπnt ιf_opdat, ,t .termno.t.ooid.t.stoowatcr.,t .wal'. ick fread(fc.t .sizeof(TimingRec) ,1 ,f_op) Compute_.'.ean_-_D(sx,sx2,n,mean,sd) unsiαned long sx.sxS: unsigned snort n; double *mean,*εd; C doublε ds/i.dεxci.on,variance; dex = sx: αs e. = sxέ; dπ = n; *mean = dsx/dn: variance = (dsx2 - ((dsx«dsx)/dn))/dn: *sd = sqrt (variance) ; Output_Summarv(fd,fe,fεd,transnum) FILE »fd; /* • detail print file */ FILE *fs; /* summary orint file */ FILE *fsd; /* sum arv ASCII file */ int transnum; /# transaction type currently processing */ £ /* NOTE: In the following, it is mathematically eound to divide the mean and standard Deviation by a constant in order to change units. For examols. we divide the mean and ε.d. by TicksPerSec to change tne units from ticks to secαnde. However, if there becomes a need to have the 'variance' units changed from ticke to seconds, make sure the variance is divided by TicksPerSec squared, not just TickεPerSec. «' mt l: double mean,sd,dtιckspersec.mean_resp_s,sd_resp_s,mean_pace_s,exp; unsigned long sumx_tot,sumx2_tot; unsigned εhort n_tot ,max, in; dtickspersec = TicksPerSec; fpπntf(fd,"Transaction: ") ; if (descIdxC03==0; fpπntf(fd,"«* 'As : no deεcriDtion **\n" .session,fllenameCtransnumJι : else tpπntf(td."'/.s\π".i_descLoescidxC 33) : π_tot = sumx_tot = sumx£_tot = 0: max = 0: min = Oxffff; fpπntf(fd,"Summarv. RESPONSE TIMES by : fprmtflfd," n resp min mean max std dev ; SUBSTITUTE SHEET 10 -148- _ SS.C Tuesday. October IS, 19SS Pag fprintf (fd," \n">: for (ι=l: nMaxOpid; i++) if (n_opιdl " ι]>0) C Compute_Mean_SD(sumx_opιd[ι3 ,sumx£_opidCi3 ,n_ooιd[ι2 ,i:mean,£.εd) ; 5 n_tot += n_opιdti : sumx_t ot += sumx_op i d C i J ; sumx≤_tot += sumxS_oριdCι j ; if (mm_opidCi3<mιn) m = mιn_opιdLiJ; if (max_opidLi3)max) max = max_opιd[ι : fprintfTfd," , /.7hu ",n_opidti3) ; fprintf(fd,"*.7.Slf ",(double)mιn_opιdLι3/dtιcksDersec) : fprintf(fd,"'/.7.2lf " ,mean/dtickspersec) ; 0 forintf ( fd,"..7.2lf " ,(double)max_opιdCi3/dticksoersec) : fDrintf(fd."'/.7.21f ",sd/dtickspersec) ; if : els \ if (n_tot) ) ComDute_Mean_SD(sumx_tot ,sumxΞ_tot ,n_tot ,&mean,£.sd) ; mean_resp_s = meaπ/dtickspersec; 5 sd_reso_s = εd/dticksperεec; fprintf(fd." \π" : orlntf(fd,"y.7hu " ,n_tot) ; fprintf(fd."5.7.2lf ".(double)min dtickspersec) : fprintf(fd,"5.7.2If " ,mean_rεsp_s) ; fprintf<fd,"5.7.£lf ".(double)max/dtιckspersec) ; fprintf(fd,"5(7.2lf ",sd_resp_s) ; fDrintf(fd." TOTALNn") : fprintf ( fsd,"5.ε,'/..2lf,X.SH\n",session.fi1enameltransnumJ ,mean_resp_ε,εd_re s) else i fprintf <fsd,"5.s, -32763, -32763\n" , session. f ilename!. transnum ]> : meaπ_resp_s = 0.0; sd_resp_s = 0.0; ) fpriπtf(fd,"\n\nSummary, transaction DURATIONS by terminal :\n\n") : fprintf(fd." n tran min mean max std dev termina'Λπ". : fprintf(fd," \π") : far (ι=0: i (MaxTerminal; i++) if (n_termCi]>0) { Compute_Mean_SD(sumx_termCi3 ,sumx.2_termCι] ,n_termCi3 ,&mean,s.sd) ; fprιntf7fd."5.7hL. " ,n_termti3) : fprintf (fd," * /.7.2lf " , (double)mιn_term[i : fprintf (fd. "5.7. SH " . ean/dticksDereec) : f pr l nt f ( f , "'A 7.21 f " . (doub 1 e) max_termt i J / d 1 c. l :sperεe : ; fprintf (fd. '7.7. Elf " .sd/dtickεperseo : forintf (fd."7.4d\n",i) : if (n_opιdC03)0) C Compute_Mean_5D ( sumx_opidC0_l ,sumx2_opιdC0.l ,n_opιdC03 ,&mean,*.ed) ; fprintf (fd," \π") ; forintf(fd,'7.7hu ",n_opιd£0J> ; fprintf ( fd.'7.7. 1f ",ldouble)min_opidC03/dtιckeDersec.' ; SUBSTITUTE SHEET -149- ss.c Tueεαay, October 18, l'SSS Pa fprintf(fe.'7.7.Elf " ,meaπ/dtickspersec) : tprintf(fd,"5.7.5If " ,(double)max_opιdCO]/dticksperεec) ; fpriπtf(fd."5.7.Elf " .sd/dtickspereec) ; tDrintf(fd," TOTALΛn") ; n_tot = sumx_tot = sumx£_tot = 0; max = υ: min - Oxffff; fprintf(fd,"\π\nSummary, transaction PACING by terminal :\n\n". ; fprintf(fd." π tran min mean max εtd dev terminal\n") ; fprintf(fd," n a ): for (i=0; l(MaxTerminal ; i++) if <n_term£ι3>l) £ Compute_Mean_SD(sumx_tran£i3,sumx£_tran£i ,π_term£i3-1 ,&mean,&sd) π_tot += π_term£i3-l ; sumx_tot += sumx_tran£i ; sumx£_tot += sufnx2_tranLi3; if (mιn_tran£i <mιn) min - mιn_tran£i3; if (max_tran£ι3>max) max = max_tran£ι3; fprintf(fd,'7.7hu " ,n_term£i3) ; /* show actual # of trans *■/ fprintf(fo."5.7.51f " , (double)min_ ranii3/atickspersec. : fprintf(fd,'7.7.51f " ,mean/dtickspersec) ; fprintf ( fd."5.7.21f ".(dou le)max_tran£ι3/dtickspersec : fprintf(fd,'7.7. I " ,εd/dtickεpersec) ; fprintf : 3 if .p_tαt.O) t Compute_Mean_SD(sumx_tot ,εumx2_tot ,n_tαt ; mean_pace_ε - mean/dtickεperεec: fprintf(fd," \n") ; fprintf<fd.'7.7hu ",n_ooιd£03) ; fprint <fd,'7.7.£lf " , (double)mιn/dtickspersec) ; fpriπtf(fd."5.7.2lf " ,meaπ_pace_s) : fDrintf(fd,"5.7.21f ",(double)max/dticksperεec) ; fprintf(fd,"5.7.EH ' ■ ,sd/dtickspersec) : fprintf(fd," T0TAL\n\n\n") ; else C mean_pace_ε = υ.O; ) if (sesειoπ.tranεExpRate£traπenum3==0) exp = 0.0; else exp = (double, session.actdur/ (double)session.transExpftate£transnumJ fprintf(fs,"5.7.2lf 5.7.2lf 5.7.Elf 5.7hu 5.7.Elf 5.7.2lf 5.s\n"', ( double ) session.transExpRate£transnum3/dtιcksDersec.mean_Dace_s, exp,n_opιd£03 ,mean_resp_s,sd_resp_s,&oesc£deεcldx£033) ; DoSessiorv '.) FILE* f_oo; PILE* f_smy; FILE* f_smydat ; FILE* f det: FILE* f_durdat; SUBSTITUTE SHEET 69 -150- ss.c Tuesday, October IS, -'a FILE* f_oρdat: int i ; ClearWιndow(&ιnfoW) ; if ( iGetSesεioπϋ ? return; WriteWindow(fc nfoW,0.0. HITE.'INTENSITY,''Machine:") WrlteWindow(&ιnfo ,1 ,0,WHITE!INTENSITY," Date:") WπteWindow(t nfo ,έ,0.WHITE!INTENS1T ," l e:".' WrlteWinαo i&infoW,0 , , HITE.session.machinename) ; WriteWindow(kinfoW,l ,9,WHITE.sesεion.date) ; WriteWindow( iπfoW.S,'3, HITE,session.time) ; f_smv = Make5myFιle() : if ιf_smy=-=NULL) return: f_det = MakeDetFileO : if (f_det==NUL ) ( fcloεe( _εmy) ; return; ) f_smydat = MakeSmydatFile() : if .f_smvdat==NULL ) C fclose(f_smv) ; fcloee(f_det) : return: WπteWιndow ( t.ιnfoW.6. 0,INTENSITYjUNDERLINE,"Timings Transactions Operati WπteWindowύ n oW,6.3 ,INTENSIT lUNDERLINE,"Timiπgs ic-.s Doerati for (i=0; l( ' session.ntranstype; i++) £ InitCountsO : SetupFiled ,&f_op,&f_durdat ,&f_opdat) ; if (f_op==NULL) £ DialogMsgC — error opening timings file. No εtats computed."); 3 else C _.ummarise(f_op ,f_durdat ,f_opdat) ; fclose(f_op) : c1ose(f_durdat) ; fc ιoee (f_opdat) : Output Summary ( f_det ,f_emv ,f_εmydat , ι) ; J 3 fcloεe (f_smγ) : fcloεe (f_εmydat ) ; fclose (f det ) : £ char cm ; mt ur_o++ ,cur_rcw ,C T _CO I ,cur_nιgh ,cur_lo ; l mtJ'lenuwiriδ '.. ■ : scoclro; /« clear screen * /* save state of cursor * - cur_off - sccurst (^.cur_row,£.cur_cαl ,ϊtcur_hιgh,i.cur_low,' ; SUBSTITUTE SHEET -151- b =S=.'C Tuesday, October l≥, lSGd Paα Plai'eMenu lϊt ainM , "Fιie:Load a sesεion I τi.e". "Quit" , ,, „ , . Make ιndow(ieinfoW,l7, 78," Summary έtats Kile Information ",7,D; DiSDlavWindow(£.infoW) ; cmd = ' ' ; DιsDlavllenu(fc.maιnM) : while. cmd != 'Q') C cmd = SetMenudimainM) : if .cmd=='F') C Remαve eni &mainM) : DoSessionO ; DιsplavMenu(.maιnM) ; ) ) /« restore cursor */ scpclrO; /* clear screen */ sccurset .cur_row,cur_col) ; scpgcurι.cur_off,cur_hιgh,cur_iow,LuR_NQ_AD U5T) : j SUBSTITUTE SHEET /10269 -152- l SMF'YSTAT .C Tuesday , October 13 , l'SSE Faα Smryb at .z Calculate summary statistics for response times: provide mean and std.dev. ov op id and oy terminal Rnolling Stone I . Broo. Pichan ****** 10 #ιnclude "ses_+ιle.h" ϊtincluαe <stαια.h. #ιnclude .math.h, ttincluoe .memory.h) #ιnclude '.string.h) 5 /******* _ L 0 B A L 5 ******* / SessionID session; /* response time stats bv op id * f,de*ιπe Ma Opid ≥.'t unsigned εhort n_ooidCMa OpidD: unsigned long sum _opιdCMa-Oριd] ,sum '£_opιdCMaM]oιdJ : ~ø unsigned short ϋoidj ϋpidJ: '* duration stats by terminal */ unsigned ehort n_termLMa.-Termιnal]; uneignεd long sum ' -_term[MaxTerminal 3 ,sum ≤_termLMa Terminal]; unsigned εhort ma ' _termCMa>Terminal] .min_ter.nl.Ma.-Terminal3: /* transaction rate etatε bv terminal *. uneigned ehort iast_walUMaxTerminal] : 5 unsigned long ,sum ≤_tran£Ma.- Terminal] ; unsigned short ma _tranCcι 'Terminal] .min_tran[Ma' Terminal; : '* descπotive strings *' ..define DescBu+sire _'."-».' unsigned char descCDescButsiire] : /♦ _.u*ter for s_πot tile -leade- »' sho"t oeεcid LMa UpidT: / - ot+set into Oeεc' tor each oo id deec-ioti: Q '******* £ N D G L 0 B A L b ******* •' int Get≤eεειo r .'.' f* return 1 ι+ euccessful */ { char +nameCl5]; Fl t* +: 5 print-. ("Name o+ εeεsior ID file SUBSTITUTE SHEET o t_r to 1 sday . Uctober IS . iS i Page ϊ * description strings */ * opid = 0; opid = αeεcLι++J; /* ignore dtvoe == 252 * > 10 _ _ n_ODid) ) : memeet '.εu.r.;:_ocιc. '\ ' .sizeof .sum:-:_opid) . : memset .εum.-.___opιd, '\0' .sizeof .sumx£_coid.t . ; memεet izeof(max_opιd; ) ; memeet .εi∑eof .mιn_ooιd) ; memεet (n_term, '\0' ,sιzeof'.n_term) : memεet<sumx_term , 'V.i' ,sιzeof(eumx_term)) ; memset (eumx2_term, '\0' .sizeof(eumx£_term) ) ; 20 memset(max_term, 'Λ0' ,sizeof(max_term) ) ; memεet lmιn_term, '\xFF' .sizeof(min_term)) ; memset .sumx_tran , '\ ' ,sizeof(sumx_tran) ) ; memset .εumx2_tran, '\0' .sizeo (sumxS_tran) ) ; memset(max_tran, '\0' ,sizeof(max_tran)) ; memset ιmιn_tran. ' ' .sizeof(mιn_tran)) : memεet .descIdx '\0- sizeo .deecldx) ) -155- SMRYSTAT.C Tuesday, October IS, 1988 P if .opιd==0) ( /'* duration ooid */ n_termCt .termno]++; sumx_termlt .termno] += t.stopwatch; sumx2_terml ' t .termno] += r,long)t .εtopwatch* (long. 1 1.stopwatch; if it .stopwatch .min_ter.nl.t .termno]) mιn_term[t .termno] = t.stopwatch; if it .stopwatch,max_termCt .termno]) max_ter.nCt .termno] = t.stopwatch; new_wall = t .wallticks-t .stopwatch: /* transaction begin time *.' if (n_termCt .termno]==l) laεt_wallCt .termno = new_wall; else C tran_tιme = new_wall - last_walI t .termno] ; last_walI t .termno] = new_wall; sumx_tranCt.termno] += tran_time; sumx£_tranCt .termno] += traπ_tιme*tran_time; if ( tran_tιme(min_tranCt .termno]) min_tranCt .termno]=tran_time; if (tran_tιme>max_tran t .termno]) max_tran t .termno]=tran_time: } readi&t .sizeo (TiminαRec) .1 , f■ ) Co oute_Mean_SD(s ,sx≤,n,mean.ε ) unsigned long sx.sxS; unsigned short n; double *mean.*sd; C double dsx,dsx£.dn,variance; dsx = sx: dεx£ = sx£; dn = n; *mean = dsx/dn; variance = (dεx≤ - ( (dsx*dsx)/dn))/on: *sd = sqrt (variance) ; } Outout_5ummary(f,tranenum) FILE *f; /* summary print file */ int transnum; /* transaction type currently processing */ C /* NOTE: In the following, it is mathematically sound to divide tne mean and standard deviation bv a constant in order to change units. For example we αivide the mean and s.d. by TicksPerSec to change the units from ticks to seconds, however, if there becomes a need to have the 'variance' units changed from ticks to seconds, make sure the variance is divided bv TicksPerSec squared, not ust TicksPerSec. */ int l ; oouo1e mean,sd,d11ckεpersec: uneigned long suιn.._tot ,sumx£_tot ; unsigned snort n_tot ,max, in; SUBSTITUTE SHEET 1 -156- _ SMKYSTHI ._ Tuesday, uctcber I;, 1_■_.:. Fa dticiepersec = Tic.sPerSec: fprintfi ."Tranεaction: ") ; if (descld^ u]==ϋ) 5 fprintf(f ,"** 'As: no description **\n" .sesεion.fiIenameCtransnum] • ; else +pππtt(f.">.s\π" , -deecCdeecld CO]]) ; tpπntf(f,"-=--=-=----=----=-=---=------=--=----—^ ; n_tot = εum _tot = sum E_tσt = υ: m« ' = 0; min = υ ffff; toπntf(f."Summarv, RESPONSE IMES py operatιon:\π\n") : +prιntf(+," r resp min mean ma. etd dev descrιρtιon\n") : 0 tpπntftt." \n". : tor (1=1; KMaxODid; ι++) if (n_opιdCι])0) C Compute_Mean_SD(sum,'_ooιd ι ,sum ,£_opιd ι] ,n_opιdCι ; n_tot += n_opιdCι]; sum _tot += εum<_op l d l J ; eum. £_tot += sum\£_αpιd ι] ; if ( min_ODidCi] (min) min = mιn_opιdCι]; 5 it ( a _opιdCι J- max. ma- = ma'_opιdCι] ; tDrιntt(+.".'.7hu ",n_ooιdCι]) ; +prιnt 'f .'"/.7.c-lf " , (double)mιn_opidCι] dtιcl εoereec : toπntf '.+ ,"'Λ7.Ξlτ " ,mean/dt ickspersec) ; toπntt '+ ."'Al mdl-f " . (daub te. ma _ooι Lι J/dt ic. eoerse:. ' : +Dπnt+(+, "I'.?. ≤lf " ,sd/dtιc. soersec) : it (deecld : elee 3 0 if (n_totX.D C Cαmpute_Mean_SO(sumx_tot ,sum.<£_tot ,n_tot ,kme&n,ksd! ; fpriπtf (f ," \n") ; or l nt f ( f , " 5.7hu " , n_t ot ) ; tpππtf (f ."'Al.dli ". (double) min/dtic spersec. : fprintf if ,"5.7. ≤lf " ,mean/dt ickspersec) ; tpπntf (f ,"5.7.21f " . (double)ma>_/dtιc soersec. : tpπntf (t, " • /.?.2 If " ,ed/dtιckεpersec) ; 5 fpπntt(f ." TOTMLXΠ") : foππtt i .t » tpπntflf." n tran mm mean a std dev terminal \r"ι fprintf (f ," \π") for (ι=υ: ι<Ma^.ermιnal ; 1++) if (n_termCι3>0 ) C 3Q Com.DUte_Mean_SD(Suπr _termCι] ,suπv"£_tεrmLi] ,n_termCι] ,!mean. =d) ; tpriπtfTf ."'/.7hu " .n_termCι]. : toπntf it ,"y.7.£lt " , (double) ιn_term ι J 'd ic. εpereeo ; tprnt+'*."5'i7.£lf " .mean dtickeoereec. ; fpππt + vt ,'"Λ7.≤1+ " , (douo le»ma-'_termL i J. Ct ' ; fpπnt+(f .".'.7.£ι+ " .=d. dtic. soerεec) : forintf ' t ,"'/,4α •π" ,ιι ; it (n_ODidC J>U.' I ^ ComDute_Mean_3D ( su(τr'_opidC<.' ] ,sum £_opιdC0] ,n_onidi'.>] .i-mear. ,:-εd) ; SUBSTITUTE SHEET -157- SMR.όTAT.C " luesday. October 18, 1988 Fa fprintfif," \n") ; fprintfif."!.7hu " .n_opidCC . : toπntf(f,"5.7.£!t " , (double)mιn_opιdCO]/dtιcksDerεeo : TDriπtfif,"'/ι7.£lf " .mean/dtickspersec) ; 5 forintf(f,"5.7.≥lf ",(double)max_opidCO]/dtickspersec ; fpriπtf(f,"5.7.5lf " .sd/dtickspersec) ; fprintfif," TOTAL\π") ; j n_tot = sumx_tot = sumx£_tot = 0; max = 0: min = υxffft; fDrintf(f ; 0 tpriπtf'.t." π traπ min mean max std αev terminal ; forintf if," .■-."' : tor . l = ( .' : i (.Ma ! eπn I na I : l ++ . i-f ' n_termi l J > 1.' ι ComDu.te_Mean_bL".εum:-._tranLιJ ,sumx£_tranCι] ,n_termtι3-l . mean . sό) ; n_ ot += n_termCi]-l: sumx_tot += sumx_tranCι]; sumx£_tot += sumx£_tranLιJ; 5 if (mιn_tranCi](min) min = mιn_tranCi]; if ima.._tranCi3.max) max = ma _tranCιJ: foπntt(f,"'/,7hu " ,n_termCι3) ; /* show actual ft of trans */ fprintf(f."5.7.£lf " .(double)miπ_tran ι3/dtickspersec; : fprintf(f,"5.7.£lf " ,meaπ/dtickspersec) ; foπnt if."5.7.£If ". (double)max_tran!.iJ/otickspersec ; forintf(f,' .7.£lf ",εd/dtickεpersec) ; fprintf(f,"5.4d\n",ι) ; 0 u it (π } _tot>υ, t Compute_Mean_SD(sumx_tot,sumx£_tot,n_tot ,&.mean,feεd) ; fprintf(f," \n"> ; fprintf(f,"5.7hu ",n_opidC0]) ; fprintf(f,"y.7.£lf ". (double)mιn/dtιckspersec; : fDrintf(f ,"'A7.E\f ",mean/dtickspersec) ; fprintf(f,"5.7.£lf ".(doubte.max/dtlckSDersec) : fprintf(f,"5.7.£lf " .sd/dtickspersec. ; 5 tprinttlf," ; i FILE* _op; FILE* f _smy: 0 int l i if l IbetSesεion'., ) return: orint ("NnMachine: 'As Date: 'As Time: ZsXnVn", session.machinename.session.date.session.time) ; f_smy = MakeSmyFilet) ; it <t_smv==NULD return: 5 for ti= ■ . ' •; l(session.ntranstype; ι++) . SUBSTITUTE SHEET O O Ul o to Ul to o in r-> O Ul n ϋ 3 a tα 10 15 Appendix F Title: Diagnostic Software Code Module: WORM. C 20 25 30 35 SUBSTITUTESHEET 0269 -160- _ WORM.C Tueεday, October IB. l'?£S ca /* WORM is the hardware configuration diagnoeticε for Rhobot . (C) copyright 19ΞS Dvnix, Inc. 5 written by: J. Wayne Schneider date: 7 October 19SS Worm le to be run at the master. It expects a WYSE 50 terminal to be on Cϋfll and the slaves to be connected on PCSS-S ports £0 - ?•?. The internal looodac.: test does not test interrupts. The external loopback test tests receive interrupts and must have Txd connected to Rxd and DTR or RTS connected to CT5. */ /* #defιne DEBUS for monitoring com output * #ιncluoe "\rhoPot\sp_data.h" #ιnclude "see_flle.h" frmclude "\rhobot\seπal .h" ..include "meπuwind.h" #ιnclude .bvideα.h. #ιnclude (bscreens.h) #ιπclude .b evbrd.n. ..include (malloc.h. #ιnclude (string. ) #ιnclude .stdlib.h) #ιnclude (stdio.h) #ιnclude (bios.h) /********** procedure prototypes ****** ***** / char *StatusMeeεage(ιnt) ; int r _from(ιnt ,char *) ; char send(lnt ,char) ; mt tx_tolιnt ,int .int .int ,int .cnar *■ r void DiεplayPortStatuslint,ιnt) ; voiα DiεplavSlaveiDciπt) ; void PortDisolav(char * > ; void Select (int.in .int) ; void LocalTest .void) ; void DisplavComPort (void) ; int externaltint ,int) ; int internal unt,int) s void Comteet (void) ; void save_datalvoιd) : void inιt_dataιvoιd. : void RemoteTest ivoid) : void SlaveTest unt) : void remotednt ,ιnt,ιπt) ; #defιne FALSE 0 #oe ιne IRuE 1 SUBSTITUTE SHEET WHATCOM. Tueeday, October IS, ly≥s ' J Raα if ( !loop_test_port icomx) ) puts (" PASSED") ; else puts ( "FAILED") ; seπal_ιnιt_ιnterrupt (comx.l) : ) else C printf ( "Verification of port 'Aa FAlLEDSn" ,comx ) ; putsC'Loop back test aε not even tried" ) ; 3 int eleepin) int n; C long t l . tm__, ι; _bιo=_t lmeof day ( _T1ME_GETCL0CK .i t tml ) ; for i l = 0 ; l i n ; ι++ ) ( do _bios_timeofday ( _TlME_βETCLOC tmS) ; while ( tml == tm.2) ; tml = tm2; 3 } SUBSTITUTE SHEET -162- _ wϋRM.C Tuesday. October IS. 1-..S& Pag MENU mainM, 1oc 111. re otell; static char rx DufferCSlSl; 5 static int coml_status = u; εtatic int master_statusC3 3 j εtatic char slave_ιdC32]f5i:; etatic int εlave_port_countC32]; etatic int slave_port_statu5[3S][3≤3: maiπi) 0 c char cmd; int cur_off,cur_row,cur_col ,cur_hιgn,cur_low; ιnιt_datai): /* read the data file and init * / scpclrO; /* clear screen */ /* save state of cursor */ cur_off = sccurεt(&cur_row,£.cur_col,£.cur_hιgh,£.cur_lαw> : /* initialize data */ InitMenuWindO ; MakeMenu(femaiπM, "COMl.Teet C0M1 on Master", "Local:Teεt portε on Master", "Remote:Test oortε on the Slaves", "Quit" . Ma.keMenu',£.ioca1M, "Internal .Test ports uεing internal loopback", "External :Teet porte using External loopback connector", "Up-Select next port up the ecreeπ", "Down.Setect next port down the screen". "Clear.-Clear the recorded status", "ϊyDe-thrcugh:Takeover a slave port with the Wvεe terminal' "Quit", "") : MakeMenu(kremoteM, "Request.Request the slave ID", "Slave-Test the slave porte", "Up:5elect next slave up the screen", "Down.Select next slave down the screen", "Clear-Clear the slave status", "Quit", "") : DιeolayMenu(i.maιnM) ; do C =wι 1 ■ .cmd = Be Menu , kmai nrt) ) SUBSTITUTE SHEET -163- WORM.C Tuesday, October IS, 1988 P £ case 'C: RemoveMenu(&mainM) ; Co Teεt() : scpclrO; /* clear screen */ Dis layMenu.kmainM) : break; case 'L': RemoveMenu(&mainM) ; LocalTeεt() : scpclrO; I* clear screen */ DisDlavMeπuf&mainM) : break; case -R' : RemoveMenut∑.m lπ ) ; RemoteTeet() ; εcρclr(); /* clear screen ♦/ isplayMenutcmaiπ!'!,' ; breakj } while (cmd != 'Q') j save_data'.. ; /« restore cursor */ scpclrO: /* clear screen »/ sccurεet (cur_row,cur_col) ; scpgcur(cur_off,cur_hιαh,cur_low,CUR NO ADJUST): /********** procedure RemoteTest ********* * *, void RemoteTest() £ int l , direction = 1; char cmdj char packetL260]: char far *DuffC3≤] ; DisplavMenui^remoteM) : PortDisplayC'Slave Identi ication") ; for (ι=0:ι<3__:ι++) £ DisplaySiavelDu) ; buffLi] = _fmallαc .512) : if (buf tiϊ == NULL) error"): return: } serιal_ιnιt (ι+0E0,%00,υxύ3,0xύb .0x01.bu fLiJ ,51= ,0. ; seπal_ιnιt_ιnterrupt n+ ≤O.O) : ) oo t SUBSTITUTE SHEET -164- ]_ WORM.L Tueeday, October 13, l'?3£ Pa selec '.com. , hLkCi' . WHITE) : switch lcmd = SetMenu .frremoteM) ) r case 'R' : 5 master_etatuεtcom 1 != u lυυ; εwitcn .t _to.com .u.u.E uΛ'.NULL.. £ case -l : master_statuεCcomx-l != υ ≤O; /* εet timeout tlag «/ break: case NA. : master_etatusCcom-'] != ύ" υ; /* εet bad line flag */ 0 break; case CAN: master_statusl.com.-.] '= 0/80; /* set cancel tlag «/ brea. : case AD : master_status r comr'] b=υ 10F; if ( rv_fτom(comx,packet) == -1' master_statusCcom-'J != "10;/* εet timeout tlag */ 5 elee £ elave_port_count[comxJ = packetCDATH3; strncpy(slave_idl.com ] ,kpac\etCDHTA+1] ,3) : } break: ) breat : 0 case -s'. it ι .maeter εtatusCcom'] £• 0 1F - '= '."K".') £ utalarmi) ; breat ; } emovehenu(i.remoteM) ; SlaveTest '.com/; : 5 εcpclri): .-* clear screen * DιsplavMenu(kremoteM) 5 PortDisplayC'Slave identification") : for (ι=υ;ι <≥2:ι++) DisplavSlavei .1) : brea ; case 'Wi direction = -1 ; 0 brea : case 'D': direction = +1; brea ; case 'C: slave_port_count£com '1 = υ; master_statusLcoπv J b= ιj*vF ; slave_ιd[com"3[0] = 0: brea. : 5 } SUBSTITUTE SHEET 1 WORM.C Tueeday, October IS, 1933 Pa DιεplaySlaveΙD(comx) : Select (comx, HITE,BLACK) ; comx += direction: _ if .comx < 0) 5 comx = 31: if (comx > 31) comx = 0; ) while (cmd != 'Q') : for <ι=0;ι ,3S:ι++) £ εerial_inιt ( i+OSO,9600,0x03,0,0,buffCi] ,512,0) ; 0 seπal_ιnιt_interrupt (1+020.1) ; _ffree(buffCι]) ; } RemoveMenu(&remoteM) : " 1 /*********** p Procedure SiaveTest ********** * / void SiaveTest (slave) int slave: £ char tιt ' ιeC40D; char cmd: int l , direction = 1 ; lnt comx=0; DιsplavMenu(ktαcalM) : εtrcDy(tιtle," Slave "> ; εtreat ititle.elave_ιdCelave]) ; strcat .title," port test ") : Port ιsplav(tιtle) : for '.i=0;i<3£;i++) DisplayPortStatusd ,slave_port_εtatuεCεlave]Ci]) ; do £ Select (comx, BLACK, WHITE); switch lemd = 6etMenu(&tocalM) ) £ case 'I': remote .slave,comx,1TEST) ; break: caεe E' s remote(slave,comx,ITEST) ; if lsiave_port_statuε[εlave]Lcomχ] k 0x02; remoteielave,comx,ETEST) j break: case 'U': direction = -1 : break; case '£r: direction = +1 ; SUBSTITUTE SHEET -166- •, WORM.C Tuesday, October 18, 193S P break: case 'C: slave_port_statuεC8lave]Ccomχ] = 0; brea ; 5 case 'T': serial_ιnιt (1 ,9600,0x03,0x0b,0x01 ,rx_buffer,512,0) ; serιal_ιnιt_ιnterrupt (1 ,0.' ; tx_to(s1ave,com , ,PASS, ,NULL) ; vidspmeg13,5.WHITE.BLACK, "*»* Wvεe to Host PASS THR0UBH ***"); vidspmsg(4.11.WHI ' IE.BLAC , "(return) to terminate"): Q do pass_thru(slave.comx) ; while (kbd() != CR. ; tx_to(slave.co x.0.'"PASS,0.NULL) : secIrmεg(3,5,50) ; εcclrmεg(4.1l,50) ; serιal_ιπιt (1 ,9600,0x03, ,0,rx_buffer,512,0) ; seπal_ιπιt_ιnterruDt(1,1. : brea ; 5 DisD } lavPortStatuelcomx,=lave_port_stat εCεl ve]Lcom::];ι ; Select (comx.WHITE,BLACK) : comx += direction: if (comx ( 0) comx = 31 ; if (comx > 31) comx = 0; } while (cmd != 'Q') ; 0 Removerteni &localM) ; ] /*.********* * Drocedure kbd *********** / kbd(. £ l f '. _b ιoε_kevbrd ( _KEYBRD_READY) ) 5 return ._Dios_..evbrd (_KEϊBRD_REA ; & OxFF) : } /#********** orocedure pass_thru ***********/ pass_thru'.s lave ,port) int slave , port ; £ int l ; 0 int comx = slave + 020: char oackεtCPACKET_BUFFER_SIZE]; i = rx_status(l) ; /* check the Wvse for data */ if .1 k Bl) f spullc(l); /* on BREAK clear the null «/ tx_to(elave.port .0.PASS BREAK, ,NULL) ; j SUBSTITUTE SHEET -167- _ WORM.C Tuesday, Octoder IS, lS'άβ P else i-f u k DR. 1 { tor u=0;ι .250;ι++) ι+ ( (packet[ι3 = soulled;) == EOF ) ^ break: tx_to(εlave.port ,0.PA5S.ι .packet) ; ) if lr.._status.com.;) k DR) C it (r:-._trom'.εlave,Dacket) == ACK) tor(i=0:ι(.packetCLEN3-4;ι++> while( Ispuehcd ,packetCDATA+i])) 10 continue: } } /*********** procedure remote *********** / void remote(slave,Dort ,cmd) int slave, port, cmd; 15 ( char packet[PACkET__.UFFER_SIZE3; slave_port_status[slave][port 3 &.=0x0F ; /* clear the status */ switch ( tx_to ( slave,port,0,cmd,S,(char *)S.slave_port_statusl.slave3[port3)) C case -1: slave_port_statuεCεlaveKport3 != 0x£0; '* eet timeout flag «/ 20 brea : case NAK: slave_port_etatuεCslaγeKoort3 != 0x40; /» set dad line flag ♦/ brea : case CAN: slave_Dcrt_εtatuε[slavej[port] := OxSO; i* set cancel flag * ι break: case ACK: 25 if (r::_from(slave,packet) == -1) slave_port_status£slave3Lport3 != 0x10:/* set timeout flag * / else slave_Dort_etatusCslave3CDort] = (int) oacketEDATA] ; break; 3 ) 30 /***** procedure ιnιt_data *****/ void ιnιt_data(. { FILE *stream; 35 stream - fopen("WORM. AT","rb") : SUBSTITUTE SHEET -168- _ WORM.C Tuesday, October IS, 1 • _.£-. if (stream == NULL. 1 return; it .tread(£.com.l_status,sizeof(int) ,1 ,etream) < 1) return; 5 if (fread(maεter_etatuε,sizeo (int) ,32,stream) < 32) return: if (fread(slave_ιd,sizeof(char) ,3S*9,stream) < 3S*9) return: if (fread(εlave_port_count ,sizeof(mt) ,3£,etream) \ 3≤) return; if .fread.slave_port_status,sizeof(int) ,32 » 32,stream) < SS^Sc. 1 return: 0 tclose(stream) ; I / * * *** procedure save data ***** / void save_data() 5 C FILE *stream: stream = tooen("WORM.DAT" ,"wb") ; fwπte .ι>coml_statu5,sizeofunt) ,1,stream) : twrιte(master_status,sizeof(int. ,32.stream; ; fwrιte<elave_ιd,eιzeofichar) .35*9,stream) ; fwritetelave_port_couπt.sizeo (int) .32,stream? : fwrite .slavε_port_status,sizeof(int) ,32*32,stream) ; 0 fclose(stream) : 3 /***** procedure ComTest void Comteet() c cnar cmd; Diεp layflenu li- localM. : do C Di sp lay omport ( ) ; switch (cmd = GetMenu(ϊ_tocalM) ) { case ' I ' : coml_etatus = internal (coml_status , l) ; oreak : case 'E ' : coml_status = internal (coml_status , l ) ; it lco l_st tus t- 0x02) coml_εtatuε = e 'terna l (coml _statuε ,1 ) ; breal ; case 'C : SUBSTITUTE SHEET ■ 169- _ WORM.C Tuesday, October 18, 1 SS P coml_status = 0; brea ; while (cmd != "0. ' Remove.'.enul& ocalM) : ) /********** procedure internal Internal loopback teεt on com port . 0 int internal '.status.comx) int status, comx: int err; status != 0x01 ; /* say it iε tested */ err = test_port (comx) ; if .err) status k= ~0κ02; /# not found */ else status != 0x02; /* found */ return status; } f ********** procedure external External loopback test on com port . **********/ int externa status.com>:) int εtat ε, comx; C εtatus '.= 0x04; /* say it is tested */ seπal_ιnιt (comx,9800, x03,0x0b,0x01 ,rκ_buffer,512,0) ; εerιal_ιmt_interrupt (comx,0) ; if (looo_test_pαrt (comx) ) status k= "0x08: else status != 0x08: seπal_ιnιt_ιnterrupt (comx.l. ; return etatus; 3 /********** procedure DisplayComPort ********* * / void iεclavComPort () SUBSTITUTE SHEET -170- WORM .C Tuesday , October 18. 19Sl : C char *status; seclr sg(5,5.50; : vιdspmsg(5,5,BLACK.WHlTE,"C0f1l: ") ; status ■= Status.lessage(coml_statuε. : vidspmsg(5,11 ,BLACK,WHITE.εtatuε) ; } ********** procedure StatusMessage char *StatusMessage(status) int status: C static cnar msgC25]; ε itch lεtatuε k 0x03; 15 case 2: case 0: strcoy(msg,"(not tested)") ;break; case 1: strcpy(msg," NOT FOUND "):break: case 3: strcpy(mεα," FOUND ");break; } switch (status k OxO ) i 20 case 8: case 0: strcat (msg." not tested)") ;break; case 4: strcat (mεg." failure "):break: case l≤:strcat (msg," GOOD ");break; ) switch '.status k OxFO) C 25 case 0x10: strcat (msg," NO ANSWER") ,-break; case 0x20: strcat(msg." 7TIMEOUT") :break: case 0x40: strcat(mε ," ?NAK") ;brea ; case 0x80: strcat (ms ," 7CANCEL") :brea : return meα: 3 _ - /*********** 30 □rocedure LocalTest ***** ****** / void LocalTes () { char cmd; int l , direction = 1 : int comx=0; 35 -171- WORM.C Tuesday, October IS, 19SS P DieplayMenuf&lαcalM) : PortDiεplayC' ocal Ports"); for (ι=0:i(3S:i++) DisplayPortStatusd ,master_statustι3) ; d o { Select(comx, BLACK, WHITE); switch (cmd = SetMenufklocalM)> C case 'I': master_statusCcomx3 = internal(master_εtatuεCcomχ] .comx+OSO) ; break: case '£ ' ; ' master_statusCcomx_l = internal(master_statusCcomχ],comx+020) : i-f (master_statuεCcomxJ k 0x02) maεter_statusCcomx3 = external (master_statustcomx-l.comx+020) ; brea ; case 'U': direction = -1: brea : case 'D': direction = 1; break: case 'C: master_statusCcomx3 &= OxFFOO; brea : } Dis layPortStatus(comx,master_statustcomx]) ; Select(comx.WHITE,BLACK) ; comx += direction; a (comx ) 31) comx = 0; i-f tcomx < 0) comx = 31; } while (cmd != 'Q') : RemoveMenudilocalM) ; } /********* procedure Select ********* void Select(comx,-fore,back) int comx, -fore, back; C int row,col; εpriπt-f(bu-f-f,'".2d ".comx); row = caπx'AH * E: col = (comx/16) * 40; viosD sα(row.col , -fore, back, bu-ft : 3 /* * * *** * * * procedure PortDisplay SUBSTITUTE SHEET -172- WORM.C Tuesday. October IS, 1 SS Paα Show tne status ot the ports. *********/ void PortDisplay(mεg) char *mεg: { int l : char εtπng[4] ; l = 40-(5trlen(msg)/2) ; vιdepmsg(5,ι , BLACK, WHITE, mεg) ; ■ for u=0:iv3£:ι++) r Selectα, WHITE, BLACK) ; } } /********* procedure DisDlaySlavelD **********/ void DiεplavS ' tavelD.comx) int comx; { int row, col; char bu-.τ[.243: char *msg; switch (master_etatusCcomx_l k 0xlF2) i de-fault: case 0x00: msg = "no por !";break; caee 0x02: meg = "request?";Dreak: case 0x102: εprintt(bu-f-f ,"'A8ε with 'Λ£d ports", εlave_ιdCcomχj,elave_port_countLcomx3) ; meg = bu-f-f; break; case 0x112: msg = "NOANSWER";break; case 0x122: msg = "7TIME0UT" ;break: case 0x142: msg = " ?NAK ";break; case 0x182: msg = "?CAI EL ";break; } col = '.comx/16) * 40 + 3; ecclrms irow.col ,30) : vidsomsg(row,col.WHITE,BLACK,msg) ; /*.******** procedure DisolayF'ortStatuε void DiSDlavPαrtStatuε.comx.statuε) int comx, status; SUBSTITUTE SHEET -173- 1 WORM.C Tuesday. October 13, 198S Pa £ int row, col ; char *meg; • * row = comx.il6 + S; col = lcomx/16) * 40 + 3: mεg = StatusMeεsage(status) ; secIrmsgtrow,col,36) ; vidspmsg(row,col ,WHITE,BLACK,msg) ; ) 0 /********* Dummy routines to -fool other procedures ******** / rescheduleO £ 3 /********* procedure tx_to ******.****/ 5 int tx_to(comx.dest,src,cmd,len.bu-f-f) int comx, dest , src, cmd, len; char *buf-f; £ int try, i, rx_parity, answer; long tm. new_tm; 0 comx += 020; /* make it a PCSS 3 number */ • for (try=0;try(3;try++) /* try to send it 8 times */ £ #itde DEBUS print ("TX - "> #endi rx_paπty = send (comx, SYN) ; rx_paπty ' = sendtcomx.len + 4); 5 rx_parity ' '= eer. (comx, dest ) ; rx_parity "= sen (comx, src ) ; rx_parity "= send (comx, cmd ) ; ■ for (ι=0ϊi(leπ;i++) rx_parity "= send (comx, bu-f-f Ci]) send (comx, rx_parity) ; ♦fi-fde-f DEBUS print-f ("\πRX - ") ; 0 #endιf do £ /* wait -for response */ i = TRUE: switch (answer get(comx, 0)) £ case ACK: case NAK: case CAN: •for (ι=0;i(3;ι++) /* get rest c+ answer *. 5 αet(comx, 0) : SUBSTITUTE SHEET 9 -174- WORM.C Tuesday, October 13, 19S8 Pa case -1: i = FALSE; 3 3 while li) ; #i-f e-f DEBUG πnt-f("\n" ) ; #endi-f if ( answer == ACK !! anewer -- CAN !! answer == -1) break: 3 return answer; 3 char send(comx,c) int comx; char c; £ while( !sDUShc(comx,c) ) continue; #ifdef DEBUG print-f("'/.3x",c) ; #endι return c; 3 int comx:. time; £ mt c: long tm, new_tm; _bιos_tιmeoτ ' day(_TIME_GETCLOCK,&.tm) ; do £ c = epullc(comx) ; if (c != -1) break; _biσs_timeofday ( _TIME_GETCLOCK,£.new_tm) ; 3 while ( (tm + time) > new tm ) ; #ifde-f DEBUG print-fC"y,3x",c); #endi+ return c: 3 /********* * procedure rx_-from **.********* / lnt rx_fromis1ave.packet) int slave; char pacι.εtC3 : C int l, rx_paπty, len; mt c: int comx = slave + 020; /* make tnis a oort address */ SUBSTITUTE SHEET -175- WORM.C Tuesday, October IS, Paα repeat : #ifoef DEBU oπntfl"rx - ") ; #endi-f do £ /* wait tor thp svnc vte • c = get icomx,60) : if (c == -l) return c: 3 while (c != SYN) ; rx_parιtv = c; packet[TYPE] = c; c = get (comx,20) ; /* get tne length */ if (c =-= -1) return c; rx_paπ y "= c; len = c; packetCLEN] = c: • for (i=0;i .len:ι++) /* get the rest of the oacket *■ / r c = get (comx, 0) ; i-f .c == -1) return c; rx_parιty ' = c; packetCDEST+i3 = c ; 3 #ιfdef DEBUS print-f("\πt:-. - ". : #en ι-f if (rx_parιty == 0) /* acknowledge a good oacket » { send(comx,ACK) ; eend(comx,2) ; send(comx,packettSRC3) ; send(comx,packetCDEST]) ; return ACK; 3 sendlcomx, AK) ; /* negative acknowledge */ sendicomx.£) ; send(comx,packetCSRC]) ; send .comx.packetCDESTj; #ι+de+ DEBUb Drintf("\n") : #enαιf goto repeat : SUBSTITUTE SHEET 10 15 APPENDTY d Title: Script Definitions Code Modules: SCRIPT.IN C AUTHOR.ASM (sample script) 20 25 30 35 SUBSTITUTESHEET SCRIPT.INC _ Wednesday, August 31, 19SS Paα .XLIST .XCREF Command Macros for the Script Processor This file is to be included in all script files for MASM (C) copyright 1933 Dynix, Inc. written by: J. Wayne Schneider date: 3 July 1933 .MODEL SMALL .CODE Ascii Constants NULL EQU 0 CR EQU 13 DEFINE_TRANS_TYPE text The de ιne_trans_type macro is used to give a name to the transaction we are running. It is better than using ,ιust the filename. Onlv the MASTER has any real use for this. define_trans_type macro text ~ db S55,text,NULL endm define_op_id name, text The defιne_op_id macro is used at the beginning of all script files to define the mneumonics and their associated descriptions for checkpoints only. The SLAVES never actually use the description but do use the name. The DEFINES must be at the beginning of the script file or the MASTER will not find them. The macro will use $*DNUM to assign numbers in order beginning with 1. $$DNUM ~ 1 DEFINE OP ID macro, name,text name = $$DNUM db 254,name " ,text,NULL $*DNUM = *$DNUM + 1 endm SUBSTITUTE SHEET -178- SCRI T.INC Wednesday, August 31, 1938 Pa de ιne_proceεs_ιd name, text The de ine_process_id macro is used at the beginning of all script file; to define the mneumonics and their associated descriptions. The MASTER uses the descriptions for user interface. The SLAVES never actually use the description out do use the name. The DEFINES must be first in the script file or the MASTER will not find them. These are used by the PROCESS command. The macro will use $$DNUM to assign numbers with define_op_ιd. DEFINE_PROCESS_ID macro name,text name = *$DNUM db £53,name.text , ULL $$DNUM = *ϊDNUM + 1 endm PROCESS <ιd> sends the ID to the master for identi ication purposes The master can use this for real time identi ication of a process within a script. PROCESS MACRO Al DB 01.Al ENDM BREAK This will send a break to the com port for 55 mεecs and the wait for 55 msecs before returning. BREAK MACRO DB 02 ENDM WAIT_FOR_0PERATOR This command allows the master to control synchronisation of tne transactions in the slaves. Only one response is required from the operator to start all of the suspended processes. A random delay, based on the transaction rate, is inserted after the operator resDondε. WAIT FOR OPERATOR MACRO DB 03 ENDM SUBSTITUTE SHEET -179- SCRIPT.INC Wednesday, August 31, 1988 P lhe CLEAR_INPUT_WI DOW command is used to clear the serial receive buffer of stored data. It should be used after a search for a orompt is completed, or ust before an output that will generate a new screen of data. If it is not used enough, the receive buffer mav overflow or a L00K_F0R may find data from a previous screen. CLEAR INPUT WINDOW MACRO DB 04 ENDM OUTPUT (string list) will output to the serial port the string and system variables; termination on null Character throttling is done here. In order to have multiple items in the list, surround them with angle brackets. System variables are VttRl thru VAR and ARB1 thru ARG'3. OUTPUT MACRO Al DB 05 DB Al DB NULL ENDM BEGIN_TIMED_L00P END_TFMED_LOOP These serve to give a timed loop when searching for vaπous strings. Usually used with L00K_F0R. The time is a constant controlled by the master. BEGIN_TI ED_LOϋP starts the timer and END_TIMED_L00P checks the timer. This timer is never reported. NOTE: These cannot be nested! BE6IN_ IMED_L00P MACRO DB 06 ii_ : ENDM END TIMED LOOP MACRO DB 07 DW GB (SB: ENDM SUBSTITUTE SHEET 69 -180- SCRIPT.INC Wednesday, August 31, 1933 Pa LOOK FOR text .label This statement is used to scan the input window for the "text". If it is found, transfer is made to "label", otherwise, it falls through to the next statement. These do NOT clear the input window in either case. You must explicitly clear the input window. 00 _F0R MACRO Al,l_l DB 08 DB Al DB NULL IFB <L1> DW <2F ELSE DW LI ENDIF ENDM WAIT TIL IDLE <n. This command waits for the incoming serial line to be quiet. As long as data continues to come in, we wait. When no data has arrived for n clock ticks, proceed. The numeric argument represents the number of clock ticks to wait for idle line. If not included, the default is one. WAIT TIL IDLE MACRO N DB 09 IFB <N> DB ELSE DB ENDIF ENDM REPORT status Sends a status report to tne master Status types are defined later in the file. The status definitions are hard coded. The master can use it for real time Droceεε following and exception reoortinα, ex. timeout. REPORT MACRO SI DB 10,SI ENDM SUBSTITUTE SHEET -181- SCRIPT.INC Wednesday, August 31, 1938 P EXIT Tells the program we have reached the end. Processing will be suspended until the master requests a new script file to process. EXIT MACRO DB 11 ENDM BE6IN_TRANSACTI0N END_TRANSACTION These are similar to a TIMED_L00P but they are indefinite. Exit from this looo occurs only on a GOTO, an implied GOTO, or the transaction count going to zero. These commands report to the master the transaction ID and check point the time to the transaction file. Transaction throttling is done nere. based on the cumulative transaction time and desired rate. NOTE: There can only be one set of these oer εcπpt file. BEGIN_TRANSACTION MACRO DB 19 iStart cumulative timer $BEG1N_TRANSACTI0N EQU $ DB IE ;Start single timer ENDM END TRANSACTION is just a go to the top of the repeat loop. The number of transactions per session is controlled by this command. It can be set from 1 - 655c or 0 which means indefinite. END TRANSACTION MACRO DB 13 DW $BEG1N_TRANSACTI0N ENDM GET DATA label This will read into the VARn variables a single record of data. The vaπaPtes are limited to VHK'1 through VAR9. The data for an entire transaction must be contained in a sinole recors SUBSTITUTE SHEET 69 -182- SCRIPT.INC Wednesday. August 31, 1985 P for this command to function. The items in the record are assigned to the variables in order. Data is delimited by CR. Records are delimited by a double CR. (or null item; . If an end of file is encountered, it will transfer control to label. GET DATA MACRO LI DB 14 IFB <L1> DW @F ELSE DW LI ENDIF ENDM THINK_TIME will simply give the "user" time to think about the data on the screen. It delays an amount soecified by a global constant modified by a random number. The actual time delayed is the think_tιme +/- 1/2 of the think time. THINK TIME MACRO DB 1-. ENDM BEGIN_T1MER n This will start the clock running specified by n, wnere n is 0 to 9. All it really does, is read the current clock tick counter for later compaπson by the CHECKPOINT. BEGIN TIMER MACRO n 1F£ IF n GT 9 .ERR 5.0UT ? BEGIN_Timer number out of ranoe! ENDIF ENDIF DB 16,n ENDM CHECKPOINT n,op_id This will send the time from timer n and op_id to the master for logging, The time is calculated by subtracting the value in timer π from the current time. The value is in clock ticks, 1/SOth of a second. .4.77S720mhz / 4) / 59659 = £0 SUBSTITUTE SHEET -183- 1 SCRIPT.INC Wednesday, August 31, 19S3 P CHECKPOINT MACRO n,Ll IF2 IF n GT 9 .ERR '.OUT ? CHECKPOINT Timer number out of range! ENDIF ENDIF DB 17,n,Ll ENDM 0 ; GOTO label transfer of control (sorry Nicholas) GOTO MACRO LI DB IS DW LI ENDM 5 W IT_F0R string This will wait for the string. If it doesn't appear in proper time, a tιme_out is reported. If it does appear, the input window is cleared and execution continues. « 0 WAIT_F0R MACRO SI LOCAL WAIT_END , WAITJDVER W ITjDVER : BEGI _TIMED_L00P LO Q KFOR 31 ,W IT_END END_TI ED_LOOP REPORT TIMEJDUT GOTO WAITJDVER WAIT_END : CLEAR_INPUT_ INDOW 5 ENDM i Constants for the Script Processor ; This file is to be included in all script files for MASM ; (C) copyright 1988 Dynix, Inc. Q ; written by: J. Wayne Schneider ; date: 8 July 1988 REPORT STATUS constants SUCCESS EQU OO 5 FAILED EEU 01 SUBSTITUTE SHEET SCRIPT . INC Wedneeday, Auguεt 31, 1988 Pa TIMEJDUT EQU OS END_OF DATA EQU 03 SYSTEM VARIABLE constants ARG1 EQU 131 VAR1 EQU 141 .CREF .LIST SUBSTITUTE SHEET -185- AUTHOR.ASM Wednesday, August 31, 1988 Pa Script file for LOOPING in Author.Browse (C) copyright 1988 Dynix, Inc. written by: J. Wayne Schneider date: 11 July 1988 INCLUDE SCRIPT.INC define_traπs_type "Loop through data doing author search" de ιne_process_id PAC_AUTH0R_BR0WSE,"PAC author search" 0 defιne_op_ιd AUTH0R_T0_BIB,"Author to bib" de ιne_op_ιd PAC_AUTHOR_LAST."PAC time to last data" PROCESS PAC_AUTHOR_BROWSE 5 OUTPUT CR W IT_F0R ">" OUTPUT <"PUBLIC",CR) WAIT_F0R "RETURN" OUTPUT CR W IT_F0R "RETURN" OUTPUT <"2",CR> BEGI _TRANSACTION 20 GET_DATA *END_TRANSACTION WAIT_F0R "first):" OUTPUT <VAR1.CR) BEGIN_TI ER 1 WAIT_F0R "(Return?" THINKTIME OUTPUT <"1",CR> BEGIN_TIMED_L00P 25 L00K_P0R "number".D01 L00K_P0R "Wor..s",D02 END_TI ED_L00P REPORT TIME_0UT EXIT D01 : CLEAR_INPUT_WINDOW THINKTIME OUTPUT <"1" ,CR> _. WAIT_F0R "Quit" - 30 DOE: CL£AR_INPUT_WI DOW THINK_TIME OUTPUT CR CHECK_POINT 1 ,PAC_AUTHOR_LAST THINKTIME OUTPUT <"Q",CR> END_TRANSACT10N AUTH0R_T0_B1B 35 SEND TRANSACTION: SUBSTITUTE SHEET AUTHOR.ASM Wedneeday, August 31, 19ΞS Pa REPORT END_OF_DATA WAIT FOR "first) ι OUTPUT CR WAIT_F0R "RETURN" OUTPUT <"7",CR> WAIT_F0R "RETURN" OUTPUT <"LATER",CR> WAIT_FOR EXIT END SUBSTITUTE SHEET 10 APPENDIX H Title: Miscellaneous Code Modules: SPKR.C T.C WHATCOM.C 15 MK.BAT SP1L.BAT SPL.BAT SPNL.BAT SP.DAT MENU IND.H SES_FILE.H _ n SPN.LNK U MENU IND.C SP1.C TUNES.C 25 30 5 SUBSTITUTESHEET SPKR - C Friday , September 16 , 19SS Page ttinclude <stdlιb.h> #include <butil.h> main (. C int i ,j,k: do { puts. "number:") ; scanf(" , /.d",&i) ; utsp ru): } ..hile (i != 999) ; ) SUBSTITUTE SHEET T,C Frida y , September 16, 1%8 Paαe #ιnclude .stdio.h. main O C se for ( ι=0;ι<32;ι++) sputc ( 02 ,i+4S) ; εputc ( 02 ,0x0D) ; dαto lab; ) SUBSTITUTE SHEET 69 -190- WHATCOM.C Tuesday, October IS, 19S£ •- "• /* (C) copyright 1988 Dyni:., Inc. written by: J. Wayne Schneider date: 6 Julv 19SS This program looks for COM ports and tells you what it +ιπdε uodate July 19, 19SS Readjusted Dorts 1 2 i. ■'-. 5 6 7 Added startuD message Sept 1, 193S Fixed com5 k 6 to match "special" PCSS-8 bept 2, 1988 Totally revised to see PCSS-8 ports Sept 16, 1988 Added external loopback teεt. Invoke with a command line port number. Oct 17, 19SS Removed DTR-CTS from external loσpbac. teεt. */ ttdefine FALSE 0 #define TRUE ( 'FALSE) main larg . argv) int argc ; char *argvC] ; C int comx; char rx_bufferC512] ; puts '" Wh.atC.om v .5 10/17/88") ; puts C" ) : if (argc == 1) i +cr i com:- = 1 ; co .--. . 010 ; com. " .-*-*-) if I. !test_port .comx) ) printfc"I found C0M'/,ld\n" ,com . ; tor ( com- = 10 : comx < 0100 : com-++) if . !teet_port (comx)) .cam--.! : putsC") ; puts<" That'ε All Folks!";; ) else { sscant(argvElH , "'Ao".kcornx) : if (co ;- < 1 ! ! comx ) 077 ! I arαc ) 2) C puts("whatcom <n.\n\n(n> must be in ranαe of 1 to 77 .octal. 1 ' exιt(l); 3 if ( !test_port (comx; ) C pri ntf (' " 'Loop back test of */.o - " ,comx! ; seπal_ιnιt (comx, 9600, 0x03 , 0x0b , 0x01 ,rx_buf fer .512.0.' : serial_imt_interru.pt (comx ,0) ; SUBSTITUTE SHEET MK,β T Wedneεday, August 31, 1988 Pag aεm '/.1 ; if errorlevel 1 goto end link '/.I; exe2bιn */.l i.l.ecp del '/.l.exe :eπd SUBSTITUTE SHEET F riday, Seotember lb, 1988 t-'ao l i nk spl + get_scr+ do_scπp+ slee p -i- ti mer+ trans_ιt+ ιo+ rnd+ sρ_dat a+ serial: SUBSTITUTE SHEET ** L r -(UT r- , " Fπdav, September 16, 19£8 Pag l i nk sp + εp_setup + testport÷ sleep* sp_gdata + task* ser i al ...CTSjISt; SUBSTITUTE SHEET T _ -PIML.BAT Friday, September 16, 19S8 Pa link gspn.lnk SUBSTITUTE SHEET SP.DAT Wednesday, August 31, 1988 Pag 100 transaction rate in ticks, 1 transaction every n ticks 10 number of transactions 10 think time 200 timeout 1 throttle back to 200 wp (assuming 6 characters/word . SUBSTITUTE SHEET -196- 1 MENUWlND .H Tuesday , October 13 , 1988 Pa /***** * menuwmd .h "* Menu and Wi ndow types Rfi l l i n '..tone ( ' .. Brook Richan (C) 1938 Dvni:-: , I nc . ****** / 0 /* bmenu includes bwindow, which includes bεcreens */ ..include (bmenu.h) #defιne MaxMenuGotionε 10 tvσedet struct { BME U «Dmenu! lπt cotsLMaxfienuO tionsJ: 5 char charsCMaxMenuOptionsJ; int lastColu n; } MENU; typedef struct t BWINDOW *wπd; WHERE lo ; BORDER bord; 3 WINDOW; 20 /* function prototypes */ void cdecl InitMeπuwin (. : '* must be called once 3*. Deαιr.r.ιrα * ■ voiα cαecl hakefleπulMENU * .char * /* build a menu structure */ 25 void cdecl DιsplayMenu(MENU *. ; / " * disDlay a menu */ char cdecl GetMeπu(MENU *. ; /* input a menu ODtioπ * / void cdecl RemoveMenu(MENU *) ; /* remove a menu from tne display *■ / void cdecl MaKeWindo (WINDOW *,int .int .char *,ιπt,mt.>; /* build a window structure */ void cdecl DιsplayWιndow(WINDOW *) : /* display a window */ 3Q void cdecl Wr11e lndow( I DOW * . Int , int , int , char *. ; /* write a string at a row. ol «.-' void cdecl ClearWιndow(WIND0W <); /* le r a window to all spaces * •' void cdecl ClearRect (WINDQW * ,ιπt ,ιnt ,ιnt ,ιnt) : /* clear rect. if, window *,• ■ void cdecl AttπpRect .WINDOW * ,ιnt ,ιnt ,ιnt ,int .int ,mt. ; /* change screen at r oi an arer- ♦.• • void cdecl RemoveWindo (WINDOW < /* remove a window * / void cdecl LursorOn(WINDOW *) ;. /* turn cursor on within window ».' __ void cdecl CursorOff(WINDOW * ) : /* turn cursor off within window */ SUBSTITUTE SHEET MENUWlNJj.H Tuesday, October IS, 19S8 ^a voiα cdecl DiaiogPro ct(char *. char * . char * , int.': / ■ * prompt +or a responee « ' void cdecl DialogMs 'char ♦ . ; /* write message to dialog window ♦/ void cdecl DialogRemovei) ; /« remove dialoo window ♦ void cdecl όetPiieName' ha *, char ♦ , char *): /* orompt for a tile name ♦/ SUBSTITUTE SHEET -198- SE≥_FILE.H Tuesday. October IS. 198S Pa /* **** ** *** * * * * ** * ***** **.***** * * ** ** * * * * * ****. ** * * *. Rholling Stone (C) 1S88 Dynix, Inc. Session data file definitions: seε_file.n ,:.. Broo.. ichan Hug lySS «*-»*-»*****»***************'l-Jf*#********-)-******«*-__jl. /*** onstants **«/ #def ιne MaxTerminal 600 " " #de me MaxTran=Type ^* /"• ..def ine TicksPerSec £0 /*** Timinαs Record ***/ typedet struct C short termno; / terminal number ♦/ char opid; /* ODeration id */ uπsigned short stopwatch; /* π clock ticks for the response time ♦/ unsi ned short wallticks: * n clock- ticks since session becan *.' ) TiminαRec; /*** Session Description *«* tyoedef struct ( char machιnenameCt.4.1,memorysi2eCb4-l,dιsksi2eC64J,datafca=esizeCb43, ^ dateL10].ti et103.commentCE363: /* 512 bytes, null terminated string ehort nterminals; /* no. of terminals used in session *■/ short ntranstype; /* no. of transaction types in session */ short thinkti e; /* ave. no. of tic.ce for lnter-oDeration think time * / snort charthro tle: /* no. of ticks Petween characters sent */ snort timeout: /* no. of ticks before signaling timeout */ unsigned char ter maDCMaxTer iπaπ: /« this tells tne transaction type that each terminal is running. For example, if termmapL1173 is 3. tnis means terminal 117 ι= running transaction type 3. */ short traπsE.DRateCMaxTransType]: /* this tells how manv clock ticks snould e between the start of each transaction. For example, if transEχpRste[4j is 1200. the transaction rate for transaction type 4 snould be one transaction every ι£uύ clock tιcf:s (i.e. 1 minute if £0 ticks per second). * ■ εhort maxTransactlonsCMaxTransTypeJ; /♦ maximum transactions to process in the session tor each tvae */ char flleπameCMaxTransTvpeJC'33 ; /* name of disk file for the transaction '.minus extension.!. Indicates where the script and timing data are stored: fileπame.SCP is assembled script filename.OP is opera ion timings T T HEET -199- ES_rlLE.H luesdav. October 13, 193S Pa tilename.TR is transaction duration timings ., For example, it tilenamelEJ is "CK0 h . then D. .au . C..Q.QP ?ne C O.TPN are the assembled script, operation timings and transaction duration timings, respectiveiv. for transac ior. tvpe __. * J bessioπlϋ: SUBSTITUTE SHEET Sr-'N.LNt-. - " riday, September lb, 1933 • 'aα spn+ get_scr+ steeo+ tιmer+ trans_ι + 10+ rnd+ so_setup+ testport+ sp_data+ sp_gdata+ task+ ιnterupt+ seπal ct5_m5c SUBSTITUTE SHEET MENUWIND .C Tuesday . October 13 , 19SS =-sc menuwmd .c Menu and Window handling Rholling Stone . Brook Richaπ (C) 193S Dvnix, Inc. #ιnclude tstdde-f.h) #ιnclude '.stdarg.h. #ιπclude .ctype.h, ι*include -.string.h. fcinclude .αos.h) .stdlib.h, #ιnclude '.search.h< ..include "menuwiπd.h" static WINDOW dialogW: static WHERE menuL. static BORDER menuB; static int dev.actιve_page; / * * * * * * * M £ N U 5 T U F F * * * * * * * / void cdecl lπitMenuWind '.. int mode.columns! meriu.S . t pe = bBRD_Nϋ_B0RDER : enuB.attr = BLACK; menuL.dev = dev = scmαde(ϊ.mode,&.columns,&actιve_paqe. menuL.oage = actιve_page: menuL.corner.row = 0; menuL. orner.col = υ: .'.ai.ewindow .J.dιalogw,≤,7£_," Dialog Window ",3,1>; void cdecl r*.a.:erienu(MENU «ms,char *mι,..., /* ms is a pointer to a menu struct to be used bv tietMenu pass a variable numDer oτ menu items in the form: "Label .Descriptive message" Each Label should start with a unique upper case letter The last parameter should be "" «/ { int col = 0, 52, mnu = 0; va_lιst argjnarker: char labelC50J ,keyC33; mε-. p mer.u = mncreate ( £,SO, HITE,REVERSE, HITE,WHITEI INTENSITY. ; SUBSTITUTE SHEET lMENUWlND.C Tuesday, October IS. 1933 -'a va_start (arg_marker,mi) ; while mi :='\0') { sz = 0; j . /* get the label; leave mi pointing to description */ "* while ..*nu !=': ') kk .*mi _='\0'. ) labelLsz++] = *mι++: labelCszJ = '\0'; it .*mι == ':',' mι++; /* set key to the upper and lower case of first letter of laael * ■ kevCC = label[03: keyCU = tolower(labelC J) : ,:ev[23 = '\ ': /* add menu item to menu */ mnlit ey(mε->pmeπu,0.col,MN_NQPROTECT,label,1 ,0.mi.kev. MN_TRANSN1T!MN_SELECT) ; 0 ms->co ' is[mnum3 = col; ms->chars£mnum3 = ..eyC 3; mnum++; col += sz+E; mi = va_arα(arg_mar..er.char-*.' ; mnl.ey'.ms-.'Dmenu.v, ,3£, ?,r'lN_MEλ. r ,f!lι_ADD,' ; * set SPACE, to right arrow ♦. ms-. ! las Column = 0: void cdecl DisplayMenu.MENU *ms) f mndsplay(ms-.pmenu.&nienuL.&menuB) ; 3 char cdecl GetMenuCMENU *ms /* returns tne menu item character */ C int row,key,ι; int c ; mnlread .ms->pmenu,0,ms->lastColumn,&rcw,&(ms->lastColumn) ,&ch,£.key, for =0; ms-.cαlsti] !=ms- lastColu n: i+* : return<ms-. hars[i3) ; ) else if <.ch==E7) /* .ESC) «/ return( 'Ω') : else return 1 ,toupperi.ch.' .' ; void cdecl hemoveMenu.MENU *ms. C wnremove.ms->Dmenu->pwιn. 1 ; SUBSTITUTE SHEET lMENU IND.L Tuesday, October IS, 1938 c ag , * ****** W I D O W S T U F F ******* / void cdecl MakeWindow(WINDOW *ws,ιnt h,ιπt w,char mtle.int row,int col) q /* ws: pointer to WINDOW structure; gets built bv this proc */ * h,w: height k width of data area of window */ /* title: window title */ /« row,col: row k col of upper left corner of data area inot border.' * . _ ws-.wπd = wncreate.h,w,CYAN) ; ws-Jbord.tyoe = BBRD_DDD !b£RD_TCT; /* single line border, too center titl ws->bord.attr = MR&ENTA: ws-)bord.ttattr = WHITE!INTENSITY: 0 ws-.oαrd.pttitle = title: ws- ) loc.dev = dev; /* as retrieved *rom 'εcmode' */ ws->Iαc.page = actιve_page: /* " * / ws->loc.corner.row = row; ws-/loc.corner.col = col: 5 void cdecl DisplayWindow(WINDOW * ws) C int dsp; wngetopt(ws-)wnd,WN_DEVICE,∑«dsp) ; if <.dΞD==-E) wndsp lay ( ws->wnd ,& <ws~> loc ) ,& <ws-)bord ) ) ; else wnselect (ws-)wnd) ; void cdecl WnteWindow.WINDOW *ws, int row, int col, int atb, char *s. /* ws: Dointer to which window */ /* row,col: row and column to oosition string */ I* atb: video disdav attribute for te.:t * I* s : Dointer to null terminated string */ 5 { wnselect ιws->wnd) ; wncurmovt.row.col) ; wnwrstr(s,atb,-l) ; void cdecl ClearWindow.WINDOW *ws) 0 t wnselect (ws-)wnd) ; wnscroll ( .-1,-1.3CR_UP) : wncurmov .0,0) ; void cdecl ClearRect (WINDOW #ws,ιnt r,ιnt cint h,ιπt w, ς /* clear a rectangular area of a window. r,c: UDoer left row k column of area to clear SUBSTITUTE SHEET , MEIMUWINB.C Tuesday. October IS, IS'88 Pa h,w: heiαht k width of area to clear */ wnscrblk(ws->wnd,r,c,r+h-l ,c+w-l ,-1 ,-1 ,WNSCR_UP,v,Wr._UFDATE. ; s ' void cdecl AttribRect 'WINDOW *ws,ιnt r.int c,ιnt h,int w,ιnt fore.iπt back; / ' » changes screen attribute of a rectangular area of a window. r,c: upper left row k column of area to clear h.w: height k width of area to clear fore.back: attribute of foreground background (-1 for no chance) hint - use fore=BLACK. back=WHITE for reverse *' 0 { wπatrb l lws->wnd ,r ,c ,r+h-l ,c+w-l , ore , back .WNJJPE'ATE. ; } void cdecl RemoveWindo (WINDOW *ws) f wnremove .ws- >wnd) ; 5 ' ' void cdecl Lursorϋn .WINDOW *ws) C wπsetopt ( ws-,'wnd.WN_CUR_OFF, ) ; * enable cursor */ wncursor ιws-,wnd : /* set cursor to this wmcow * j ' 0 void cdecl CursorOff(WINDOW *ws. I wnsetopt .ws->wnd,WN_CUR_GFF,l) ; /* disable cursor */ wncursoriws-/wnd, : /* set cursor to this winnow +.-' j 5 /****** * D I A L O G S T U F F ****** * void cdecl DiaiogPromot (char *prompt. char *dftt. ct-i&r *response. mt size; /* disDlav a Drompt and return the users resoonse. size is max size (in bytes) of response if user presses (RETURN. 1 only, dflt is returned as response ♦ C int key; char res CSO-l; ClearWindow'.&dialogW) ; DisplayWindow(kdialogW) : wnselect .dialogW.wnd) ; wnwrstripromDt .WHITEIINTENSITY,-1 ■ : wnwrstr(" t",WHITE,-1) ; wnwrstridfIt , HITE.-1) : wnwrstr.";' ",WH1TE,-D; 5 wnwrstr.'? " .WHITE!INTENSITY.-1) : SUBSTITUTE SHEET -205- 1 MENUWIND.C Tuesday, October IS, l'?SS Pa CurεαrOn(kdialogW/ ; wnαuery(resp,sizeof(resp) ,&key) ; if *resp-='\0'. strcpv(response,dfIt) ; _ else strcpy.response,resp) ; RemoveWιndow(&.dιaloαW/ : void cdecl DialogMs (cnar *msg) . ClearWindowi&dialogW) ; DiΞplayWιπdow(ϊ.dιalogW) ; 0 CursorOffikdialogW) ; WrlteWindow < alalogW.0.0.WHITE!INTEN5ITY,msg > void cdεc. ialogRemoveu _ Removewindow .__αlaIoα > 5 ' ,** ***** F I L E M E N U S T U F p * * * * * * * / void cdec L 6etFι leName'.char *Drompt. char »dfltwιld. char »fnaπ.e. !* Drompt: prompt to user */ ' 0 /* fname: returns tne name chosen: null if none, must be at least SO tvtes*'' /* dfltwild: default path, containing- wild cards; returned changed */ C unsigned result: struct fιnd_t fileinfo; int n ιles,πrows,ι ,r, ,c .key; char fιlesL ' 50]L14D; /* 100 causes stack overflow! ♦/ BMENU *fmeπu: WHERE w; 5 BORDER b; char kevsCSJ: DialogPrompt '.Drompt ,dfItwild,fname,30) ; it .εtrchr(fname. '*',==NULL> return: /* no wild card */ strcpv .dfltwiId,tname) ; /* wild char input, assign new default */ nfiles = 0: resul t = _do≥_f incf irst (df I ' twi ld ,_A_N0RMAL ,ii+ι leιπfo) ; 0 whi te ( .result == 0) kk .nf ι les (όυ) ) C strcov'flleslnfιles++3 , lleinfo.name ) : result = _dos_fmdnext ikilleinfo) ; if '.nfιles==0) £tnaπ.eC0_l='V.> • ; return;} αsort tflies.nfl les,l< .strcmp; : nrows = nfiles/f' + inflles'/.5K>. : tmenu = ncreate(nrows,?E, ORMAL.REVERSE.NORMAL.NORMAL.' : SUBSTITUTE SHEET 1 MENUWΪND.C Tuesday, October IS. iΕ_8 Rag mnitmkevifmenu,i/5, (i Α5) *15,MN_N0PR0TECT, fllestl] .keys,MN_SELECT) ; j _ mnkev.fmeπu,0,0,32,57,MN_NEXT,MN_ADD) ; > set -.SPACE, to πgnt arrow • • ' w.αev = dev: w.page = actιve_page: w.corner.row = i : w. orner.cc-ι = -•: b.tyoe = bβkD_DDDD!fcBRD_rCT; /* single line border, toe renter title * b.attr = MABENTA: b.ttattr = WHITEjlNTENSIlY; P.pttitle = dfltwild: mndsplay( menu,&w,&b) ; : 0 else i /* form full file name */ /* get path name, if any */ * remember, fname is the same as dfltwild to here * .' for (i=strlen( name)-l ; ( ι ) =0) kk (fnameCi] !=' :') kk ( nameCiD !='\--, ',• : l—) : fnametι+1] = '\0'; /* if : or \ not found, set fname to null * / /* if found, fname set to path * 5 /* append file name to path */' strcat (fname, ilesC(r*5)+(c/15) ]) ; } 0 5 SUBSTITUTE SHEET -207- SPl.C Tuesday, October IS, i'SSB Pag /* bcriDt Processor for only ONE Dort without a master (C) copyright 1983 Dynix, Inc. written by: 3. Wayne Schneider date: 10 August 1988 SPl 5cript_ ιle_name Cscript_argumentε...] [<data_filename] This program reads the script file specified on the command line and processes it on C0 1. Data entry can be specified with redirection. data_ ιlename. A string argument may be passed to the scπct processor to be recognised as nRGl , AR65, ... ARG ' 7. The purpose of this program is to aid 10 in depuααinα script files. #ιncluαe .Dios.h. ..include .como.h) #include .malloc.h #ιnclude .stdio.h) " #mclude "sp.h" #ιnclude "sD_data.h" #ιnclude "ses_flle.h" struct t_st." trans: FILE *ses_tι ie; 20 main'.argc.argv,' int argc: char *argvCD: I char * script ; char *r.-._buf er ; long length: trans_ιmt (&trans,£.global) ; if .argc == 1) ( 25 nuts ("Specify a script file to process!"); j script = get_scπpt (argvCU , ^.length ,op_ιd_msg) ; printf ("SCRIPT - '/.s\n" ,op_ιd_msgC0]) ; rx_duf f er=mal lo (£048) ; 30 if (rx_du er == NULL) I puts ("Not enough memory for rx_bu fer !") j exit (6/ ; J ses_fιle = fopenC'SPl .OP" ,"wb") ; if ιse=_fιle == NULL.' oerror r'ooen failed". ; 35 SUBSTITUTE SHEET 1 SPl.C Tuesday, October IS, 19SS Pa memset (rx_buffe .O.EO^S) ; ser l a 1 _ι n i t ( 1 , '?60 , 0x03 , x06 , xl , rx_buf er , 204S , 1 bNϋκE_NUL . : ιmer_ιnιt (. ; serial init interrupt tl ,0) ; 5 do_5cπpt '.1.s ri t , length ,i.argv[Ej ,r.---:_bu fer + r .i.traπ.si : seπal_ιnιt_ιnterrupt tl ,1) ; tιmer_undo() ; fclose(ses_ lie) ; } 0 /*************.*********.**************************** * **.********** * ****.*** * * orocedure CHECKOUT This routine is called by αo_εcrιpt to see if the operator has asked us _ς void chec _out ( ( char : if (_bιos_keybrd ( _ EYBRD_READY) ) /* give uo, when commanded */ if ((char)_bιos_keybrd(_ EYBRD_READ) == ESC) i print ("\nA = abort, anything to continue ?") : c = toupper', (char)_bιos_keybrdl_KEYBRD_READ..' : 0 □utsi"". ; if '.c == 'A'.' trans.aoort = Thϋc: 5 /* Dummv routine for scheduling is hers */ void resched leO C) /* Terminal routines here replace communication to master *' void processicomx,numb. 1 Q int comx, numb: ( printf'."PROCESS - 'Ad - Vis\r." , omx,op_id_msgtnumb] " ' : } lnt reoort icomx,numb) mt comx, numb: char c 5 oπntf ("REPORT - .'.α - , ccmri, status nsginumb.l. ; SUBSTITUTE SHEET -209- 1 SPl.C Tuesday, October IS, 19BS Pa lfinumb == 5) ( oπntfC'XnA - abort, anything to continue ?") ; ( -:.EVBRD_READ) i : if c == 'A'.' return TRUE; return FALSE; j void check_poιnt (com ,op_ιd,op_tιme,wall_tιme) 10 int comx, op_ιd: long oD_tιme, wall_tιme; ( TimingRec t ; if ' .oD_ιa == 0.' printf ("TRANSACTION times '.Id '/.ld\n" ,op_t ime ,wall_t ime." : else printf ("CHECK. POINT for V,d - '/is is S.ld at '/. id'.n", comx,op_ια_msgCop_ιdJ ,op_ i e, l l_ ime) ; 15 t .termno = comx; t .oo id = σp_ιd; t. stopwatch = op_tιme: t.walltic s = wall_time; fwπtei&t. sizeof (TiminαRec) , 1. ses_file); } int αet data(var) 20 char varClODCSO] ; C int i ; for M = 1 ;ι <1 :ι++.' .. π-rintf ("getva :") : getsivarLi j) : 25 DutsC""); if (strcmp(varCi],"END") == 0) return EOF; if IstrcmptvarLi] ,"") == 0) break; } return NULL: 3 int wait for_operatoro 30 £ printf tor operator. Press any kev:" _bi03_kevbrd(_ Eτ'BR _READ : putsC") ; } int do_exιt (com... int comx: C 35 pu s'. "EX IT") : SUBSTITUTE SHEET SPl .c Tuesday, October IS, 19SS -'ace return TRUE: ) SUBSTITUTE SHEET TUNES.C Monday. October 3, 1988 Page 1 /* here are routines for giving audio response. The chirrup tune is a positive signal that may be used to indicate success. The sad tune is used to indicate failure. (C) copyright 1988 Dynix, Inc. . . written by: 3 . Wayne Schneider date: El September 1983 */ /* Make a cheerful tune on the beeper */ ■ * ■ " chιrrup_tune() { sleep(1) ; utspkr( 00) ; sleep(E) ; utspkr(800) ; sleep(E) ; utspkr(900) : 15 sleep(E) ; utspkr(0. : } /* Make a sad tune on the beeper to indicate failure */ sad _tune() 20 utspkr(S00) ; εleep(lθ) : utspkr(100) ; sleep(10) : utspkr(0) ; } 25 30 * 35 SUBSTITUTE SHEET

Claims: I claim: 1. A system for evaluating the performance of a large scale computer system having a number of host communication ports each capable of connection to a terminal, the system comprising: a plurality of central processing units (CPUs)each having an internal parallel communication path; a plurality of CPU communication ports, each CPU communication port being connected to the parallel communication path provided at each one of the plurality of CPUs; means for coordinating the function of a varying number of the plurality of CPUs; and means for individually interconnecting a plurality of the CPU communication ports to a plurality of the host communication ports such that each CPU communication port appears as a specific terminal to the host communication port connected thereto. 2. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein one of said plurality of CPUs comprises means for recording the response time on a plurality of said host communication ports. 3. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the plurality of CPUs comprises at least five CPUs. SUBSTITUTESHEET 4. A system for evaluating the performance of a large scale computer system as defined in claim 3 wherein the CPU communication ports comprises at least eight communication ports provided on each CPU. 5. A system for evaluating the performance of a large scale computer system as defined in claim 3 wherein each CPU communication port comprises means for converting parallel data communicated from the internal communication path provided in a CPU to serial data to be transmitted on the means for individually interconnecting. 6. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the number of host communication ports comprises at least 640 host communication ports. 7. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the plurality of CPUs comprise a master CPU and a plurality of slave CPUs. 8. A system for evaluating the performance of a large scale computer system as defined in claim 7 further comprising a plurality of communication paths established between the master CPU and each of the plurality of slave CPUs. 9. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the means for coordinating the function of a varying number of the plurality of CPUs comprises a master CPU. SUBSTITUTESHEET 10. A system for evaluating the performance of a large scale computer system as defined in claim 9 wherein the plurality of CPUs comprise a plurality of slave CPUs each connected to the master CPU. 11. A system for evaluating the performance of a large scale computer system as defined in claim 10 wherein the plurality of slave CPUs comprises 32 slave CPUs. 12. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the means for individually interconnecting comprises a plurality of electrical connections, each electrical connection being between a CPU port and one of the host communication ports. 13. A system for evaluating the performance of a large scale computer system as defined in claim 12 wherein each electrical connection comprises a cable connected between each CPU port and each of the host communication ports. 14. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein each of the CPUs is a substantially less powerful computing device than the host computer system. 15. A system for evaluating the performance of a large scale computer system as defined in claim 1 wherein the plurality of CPUs comprises a plurality of microcomputers. SUBSTITUTESHEET 16. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer having a plurality of host communication ports, each port capable of being connected to a terminal, the system comprising: processing means for carrying out functions to emulate a plurality of terminals; port means for establishing a bi-directional communication pathway with the processing means and the plurality of host communicatio ports; connection means for connecting each active host communication port with the port means; and means for selectively increasing and decreasing the number of host communication ports which may be connected to the port means. 17. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer as defined in claim 16 wherein the processing means comprises a plurality of CPUs. 18. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer as defined in claim 17 wherein the plurality of CPUs comprises a master CPU and a plurality of slave CPUs and a communication path established between each slave CPU and the master CPU. SUBSTITUTESHEET v -216- 19. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer as defined in claim 17 wherein the processing means further comprises means for generating electrical signals to emulate a terminal which is adapted to be connected to one of the host communication ports. 20. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer as defined in claim 17 wherein the port means comprises a plurality of serial communication ports provided on the master CPU and each of the slave CPUs. 21. A computer performance evaluation robot capable of evaluating the performance of a large scale host computer as defined in claim 20 wherein the connection means comprises a plurality of cables connecting the serial communication ports on the master and slave CPUs to the host communication ports. SUBSTITUTESHEET 22. A computer performance evaluation robot for determining the response times of a large scale host computer running any of a plurality of multiuser application programs and having a plurality of host communication ports, each host communication port being capable of being connected to a terminal, the system comprising: a plurality of processing devices; means for coordinating the functions of a 10 variable number of processing devices; a plurality of robot communication ports connected to each processing device; means for individually connecting a plurality of the robot communication ports to the plurality of 15 host communication ports; and means for recording the difference between the time when a command is presented at each of the robot communication ports and the time that an expected response is output from the respective host 20 communication port such that the number of response times of the host computer at a specified number of transactions per unit time can be determined. 25 30 i 35 SUBSTITUTESHEET 23. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 wherein the plurality of processing devices comprises a plurality of individual central processing units (CPUs) . 24. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 23 wherein the plurality of CPUs are interconnected and one CPU acts as a master CPU to Coordinate the functions of the remaining slave CPUs and wherein the means for coordinating the operation of at least two processing devices comprises the master CPU. 25. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 further comprising means for varying the rate at which transactions are presented to the host computer and means for varying the rate at which characters are presented to the host computer. 26. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 wherein the plurality of processing devices comprises a plurality of microcomputer devices each of which is substantially less powerful than the host computer. 27. A computer performance evaluation robot for determining the response times of a large scale host SUBSTITUTESHEET computer having a plurality of host communication ports as defined in claim 22 wherein the means for individually connecting a plurality of the robot communication ports comprises a plurality of electrical conductors which are adapted to interconnect one robot communication port to one host communication port. 28. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 wherein the host communication ports and the robot communication ports comprise serial communication ports. 29. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 further comprising a terminal connected to one of the processing devices and means for logically connecting the terminal to any one of the host communication ports. 30. A computer performance evaluation robot for determining the response times of a large scale host computer having a plurality of host communication ports as defined in claim 22 wherein the means for recording the difference between the time when a command is presented and the time that an expected response is output from the host communication port comprises a digital memory device. SUBSTITUTESHEET 31. A system for evaluating the performance of a large scale host computer having a plurality of host serial communication ports, each host serial communication port capable of being connected to a terminal, the system comprising: a master CPU having substantially less computing capacity than the host computer and also comprising a plurality of master serial communication ports; a plurality of slave CPUs, each slave CPU having less computing capacity than the master CPU and also comprising a communication port connected to one master serial communication port and a plurality of slave serial communication ports; a plurality of electrical conductors adapted for connecting the plurality of slave serial communication ports individually to each of the plurality of host serial communication ports such that a serial communication path is formed between each of the host communication ports and one slave communication port; and means for recording the time difference between when each of a plurality of requests for carrying out a transaction is made to the host computer and the time that an identifiable response is received at the corresponding host serial communication ports such that the times required for each transaction may be analyzed to evaluate the host computer's performance. SUBSTITUTESHEET 32. A method of evaluating the performance of multi-user large scale host computer system having plurality of host communication ports capable of having plurality of user terminals connected thereto, the hos computer system also capable of carrying out a pluralit of tasks, the method comprising the steps of: providing a plurality of CPUs, each CPU havin substantially less computing power than the host compute and being provided with a plurality of CPU communicati ports; interconnecting the CPU communication por individually to the host communication ports provided the host computer system such that each CPU communicati port appears to the host computer to be a terminal; presenting at a first CPU communication port request that the host computer carry out a first task; presenting at a second CPU communication port request that the host computer carry out a second task; retrieving data from a first data pool accessible each of the plurality of CPUs, the data being necessary carry out the first task; entering the data to the host computer at the fir CPU communication port; retrieving data from a second data pool accessible each of the plurality of the CPUs, the data bei necessary to carry out the second task; entering the data to the host computer at the seco CPU communication port; timing the period which is required for the ho computer to complete the first task and the period whi is required for the host computer to complete the seco task; and recording the time required to complete the fir task and the time required to complete the second ta SUBSTITUTESHEET in a digital memory device such that the performance of the host computer may be analyzed. 33. A method of evaluating the performance of a multi-user large scale host computer system as defined in claim 32 wherein the step of providing a plurality of CPUs comprises the step of providing a plurality of microcomputers. 34. A method of evaluating the performance of a multi-user large scale host computer system as defined in claim 32 wherein the step of interconnecting the CPU communication ports comprises the step of establishing a serial communication path between each active host communication port and a CPU communication port. 35. A method of evaluating the performance of a multi-user large scale host computer system as defined in claim 32 wherein the step of presenting at a first CPU communication port a request comprises the step of beginning a first transaction to be carried out by the host computer. 36. A method of evaluating the performance of a multi-user large scale host computer system as defined in claim 32 further comprising the steps of: presenting at a third CPU communication port a request that the host computer carry out a third task; presenting at a fourth CPU communication port a request that the host computer carry out a fourth task; retrieving data from the third data pool necessary to carry out the third task and entering the data to the host 10 computer at the third CPU communication port; retrieving data from a fourth data pool necessary to carry out the fourth task and entering the data to the host computer at the fourth CPU communication port; timing the period which is required for the host 15 computer to complete the third task and the period which is required for the host computer to complete the fourth task; and recording the times required to complete the third task and the time required to complete the fourth task in 20 a digital memory device such that the performance of the host computer may be analyzed. 25 30 j 35 SUBSTITUTESHEET

Inventors: RICHAN K BROOK, SCHNEIDER J WAYNE, WILSON RICHARD K, RICHAN, K., BROOK, SCHNEIDER, J., WAYNE, WILSON, RICHARD, K.
Applicants: DYNIX MANAGEMENT INC, DYNIX MANAGEMENT, INC.
Application year: 1990
Main classification: G06F11
IPC codes: G06F11