|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 177792 (0x2b680) Types: TextFile Names: »D75«
└─⟦a2495fc4f⟧ Bits:30005867/disk10.imd Dokumenter (RCSL m.m.) └─⟦this⟧ »D75«
1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_._ 1. The Multiprogramming Utility System (MUS) for the RC3600 line of computers has the aim - to simulate parallel processing including interprocess communi- cation and interrupt processing. - to give a strong framework for I/O processing, both on charac- ter level and on record oriented level. - to support the user in the running of the system, which inclu- des easy operator communication and an operating system that takes care of core administration and creation and removal of processes. These goals have been reached by creation of the following soft- ware modules: - a monitor, implementing multiprogramming. - driver programs for common devices. These lay down the rules which are to be followed in coding drivers for new devices. These rules are purely a matter of overall cleanlines, and no real destinction is made between driver programs and other programs. - reentrant I/O procedures designed around the zone concept, which has shown to be a clean and tidy way to describe device peculiarities, buffering, record formatting and - packing in- volved in any I/O activity. - a basic operating system, which caters for program load and de- letion, process creation and removal and start or stop of exis- ting processes. The operating system is described in a seperate manual. \f The different modules may be put together in a hierarcial manner. Below is a figure showing the hierarchy. User processes may be build on top of all modules depending on what is needed to fit the usage. \f F_2_._ _ _ _ _ _ _ _ _B_A_S_I_C_ _C_O_N_C_E_P_T_S_._ 2. As an introduction to a detailed description of the monitor this chapter deals with the three fundamental items: programs, proces- ses and message buffers, handled by the monitor. A p_r_o_g_r_a_m_ is a collection of instructions. The execution of a program in a given storage area is called a p_r_o_c_e_s_s_. A process is identified by a unique p_r_o_c_e_s_s_ _n_a_m_e_, used in all references to it. Thus other processes need not be aware of the absolute loca- tion of the process in the storage, but can refer to it by name. Processes can communicate by sending m_e_s_s_a_g_e_s_, carried in a m_e_s_- s_a_g_e_ _b_u_f_f_e_r_ to each other. After the processing of a message, the receiving process returns an a_n_s_w_e_r_ to the sending process in the same message buffer. The term e_v_e_n_t_ denotes a message or an answer. When events arrive to a process from other processes, they are linked to the e_v_e_n_t_ q_u_e_u_e_ which is a part of the process description. This chapter will apply concepts described later in this manual, so it is recommended at first only to read it to get an idea of the contents of program descriptors, process descriptors and mes- sage buffers and then turn back to it after reading about the mo- nitor. All parameter names mentioned in the following are defined as permanent symbols in the assembler and can thus be applied when coding assembler programs. The values are the corresponding dis- placements in the format descriptions. Following the three descriptions is an example showing, how they should be initialized in an assembler program. \f T_2_._1_ _ _ _ _ _ _ _P_r_o_c_e_s_s_e_s_._ 2.1 Each process running under the MUS (DOMUS) monitor must have a process descriptor, where all the information about the process &_ needed by the monitor to simulate multiprocessing is collected. The start address of a process (specified after the terminating .END) should be the process descriptor address. In this way, the operating system is able to find the process descriptor, when loading a process. The first part of a p_r_o_c_e_s_s_ _d_e_s_c_r_i_p_t_o_r_ must contain the following parameters, each consisting of one word if nothing else is speci- fied. PROC.NEXT: Next process in a queue of processes (see PROC.PREV). PROC.PREV: Previous process in a queue of processes. Together with PROC.NEXT, this element is used to link the process to the running queue or to the delay queue. If the process is not in a queue, the parameters both point to the process itself. PROC.CHAIN: Next process in the process chain. All process descriptors are linked together in a chain. PROC.CARRY When interrupted the process uses bit 15 of this field as save location for the carry bit. PROC.NAME: Process name consisting of t_h_r_e_e_ _w_o_r_d_s_. The process is identified by this text of one to five characters; unused character posi- tions must equal zero. PROC.EVENT: The event queue head, consisting of t_w_o_ w_o_r_d_s_. The first word points to the first e- vent in the event queue and the second word points to the last event in the event queue. If the queue is empty, both words point to\f PROC.EVENT. The event queue contains messages and answers to the process. PROC.BUFFE: Head of the message buffer chain which con- tains all message buffers belonging to the process. PROC.PROG: Address of the descriptor of the program exe- cuted by the process. PROC.STATE: This location indicates the actual state of the process. If the process is waiting and more than one reason is specified it is started again, when one of the conditions is fullfilled. Possible states of a process are: 0: r_u_n_n_i_n_g_, i.e. the process is linked to running queue and wants to have time slices for execution, or: w_a_i_t_i_n_g_ _f_o_r_ _s_o_f_t_w_a_r_e_ _t_i_m_e_r_, i.e. the process is linked to delay queue. bit 0: s_t_o_p_p_e_d_, i.e. the process is stopped. 3 to 63: w_a_i_t_i_n_g_ _f_o_r_ _i_n_t_e_r_r_u_p_t_ _o_r_ _s_o_f_t_w_a_r_e_ t_i_m_e_r_. i.e. the process is waiting for an interrupt from the device with device no. = state. In addi- tion, it is linked to the delay queue and waits for the software timer. ' 63: w_a_i_t_i_n_g_ _f_o_r_ _a_n_s_w_e_r_. The process waits for an answer to a message it has sent in the message buffer with address = state. - 1: w_a_i_t_i_n_g_ _f_o_r_ _e_v_e_n_t_. The process is started again, when a buffer is linked to its event queue, i.e. when either a message or an answer\f arrives. - 2: w_a_i_t_i_n_g_ _f_o_r_ _e_v_e_n_t_ _o_r_ _s_o_f_t_w_a_r_e_ _t_i_m_e_r_. As above, but if an event has not arrived when the timer runs out, the process is started with time- out. -3 to -63:w_a_i_t_i_n_g_ _f_o_r_ _e_v_e_n_t_,_ _s_o_f_t_w_a_r_e_ _t_i_m_e_r_ o_r_ _i_n_t_e_r_r_u_p_t_ from device no = -state. PROC.TIMER: Timer count. The number of timer periods the process still may wait in the delay queue. If the process is in the delay queue, this timer count is decremented for each timer interrupt and when it becomes zero, the process is started again. PROC.PRIOR: Priority. Priorities are unsigned 16 bits in- tegers and zero must not be used. The next process to use the CPU is chosen cyclically among the processes with highest priority. (See ch. 3.1 about the running queue). PROC.BREAD: Break address. This address is entered after a break of the process, e.g. caused by a program error or an operator break. PROC.AC0: Saved AC0. See below. PROC.AC1: Saved AC1. See below. PROC.AC2: Saved AC2.See below. PROC.AC3: Saved AC3. Before the process is interrupted the regis- ters will be saved here and when the process becomes active again, these locations will be loaded into the registers such that the state of the processor is the same when the execu- tion continues. (The carry bit is saved and reloaded from the proc.carry field). \f After loading the process, the registers are loaded with the values of these parameters and the process is started in the address specified in PSW (see below). PROC.PSW: Program status word. When the process is interrupted, the program counter is saved in proc.psw (0:15). When the process becomes active again, execution continues from the word address saved here. When initially loaded and started the contents of proc.psw (0:14) is used as a normal relocable start address for the process and must be specified as such. Proc.psw is then reorganized by the loader and proc.psw (15) is saved in proc.carry (15). PROC.SAVE: Work location for the system procedures. Following these locations, the process descriptor may contain any number of optional words. E.g. a driver process using the driver utility procedures must contain six words directly following the before-mentioned: PROC.BUF: Saved message buffer address. PROC.ADDRE: Current value of address (BUF.MESS2). PROC.COUNT: Current value of count (BUF.MESS1). PROC.RESER: Process descriptor address of reserving process. Zero indicates no reserver. PROC.CONVT: Conversion table address. Zero indicates no conversion. PROC.CLINT: Interrupt handling entry. This address is en- tered in disabled mode, when an interrupt ar- rives from a device which the process wants to supervise. \f T_2_._2_ _ _ _ _ _ _ _P_r_o_g_r_a_m_s_._ The code executed by a process is a p_r_o_g_r_a_m_. A program head con- tains information about the size and name of the program and a &_ descriptor word. PROG.PSPEC: The program descriptor word describes the use of the program. BIT 0: Own bit. Set, if the program con- tains its own process descriptor after the program. Bit 1: Reentrant bit. Set, if the program is reentrant. Bit 5: Parameter bit. Set, if the program wants parameters transferred from DOMUS. Bit 6: Paged program bit. Set, if the pro- gram is paged. Bit 7: Reservation bit. Set in a reserv- able driver process. PROG.PSTART: Address of the first instruction in the pro- gram. PROG.CHAIN: Link to next program in the program chain. All program descriptors are linked together in a chain. PROG.SIZE: Size in words of the program. PROG.NAME: Program name in t_h_r_e_e_ _w_o_r_d_s_. The program is identified by this text of one to five cha- racters. Unused character positions must e- qual zero. \f T_2_._3_ _ _ _ _ _ _ _M_e_s_s_a_g_e_s_ _-_ _a_n_s_w_e_r_s_._ 2.3 Communication between processes is handled by four monitor func- tions, which enable the processes to exchange information in such &_ a way that only one process at a time accesses the information. The information is carried in a m_e_s_s_a_g_e_ _b_u_f_f_e_r_ (short: buffer) consisting of a head of six words and an information part of four words. BUF.NEXT: Next buffer in a queue of buffers (see be- low). BUF.PREV: Previous buffer in a queue of buffers. Together with BUF.NEXT this element is used to link the buffer to the event queue of a process. When the buffer is not in use, both elements point to the buffer itself. BUF.CHAIN: Next buffer in a chain of buffers. All mes- sage buffers belonging to a process are chained together. BUF.SIZE: Size of the buffer. At present the size e- quals ten. BUF.SENDE: Sender process descriptor address. This value is permanent as the process sends information in a message buffer belonging to itself. BUF.RECEI: Receiver parameter. The value of this parameter indicates the state of the buffer. 0: The buffer is f_r_e_e_ and can be used to send information. ' 0: The buffer contains a m_e_s_s_a_g_e_ sent to another process and BUF.RECEI = receiver process de- scriptor address. 0: The buffer contains an a_n_s_w_e_r_ from a process that has received a mes-\f sage in this buffer, and BUF.RECEI = -(process descriptor address of the receiver of the message being answered). BUF.MESS0: Information words. BUF.MESS1: Optional contents depending on the use. BUF.MESS2: The standard usage in drivers is described in BUF.MESS3: chapter 4. T_ &_ Fig. 1 If a process wants to send information to other processes, it must own a pool of buffers linked together in a chain with head in PROC.BUFFE (fig. 1). By means of the monitor function SENDMES- SAGE the information is copied into the first free buffer within the pool and the buffer is linked to the event queue of a n_a_m_e_d_ r_e_c_e_i_v_e_r_. The receiver gets information about the message by means of WAITEVENT. After processing of the message, the recei-\f ving process returns an a_n_s_w_e_r_ to the sending process in t_h_e_ _s_a_m_e_ b_u_f_f_e_r_, which now is linked to the event queue of the sender (= owner) process. This answering is handled by SENDANSWER. If the original sender gets information about the answer by means of WAITEVENT, the buffer has to be released by using WAITANSWER. If the sender wants to wait for an answer to a specific message, it suffices to use WAITANSWER. For further details, see the description of the monitor func- tions, chapter 3.2. 2_._4_ _ _ _ _ _ _ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_ _o_f_ _t_h_e_ _D_e_s_c_r_i_p_t_o_r_s_._ 2.4 Below is shown in an example, how a program descriptor and a process descriptor with two message buffers are coded. Parameters marked with * must always be initialized by the programmer with values as indicated in the example. Unmarked parameters are set by the system during execution.\f ;program descriptor: PG1: 1B0+1B1 ;*this program is reentrant and ;contains its proc.desc. PG2 ; 0 ;* PC1-PG2 ; .TXT .PXX0'0'. ;*program name, three words. PG2: . ;program: . PG3: . ;start of execution . ; PG4: . ;break address . \f PC1: ;process descriptor: .+0 ;* .-1 ;* 0 ;* PC2-PC1 ; .TXT .PXX0'0'. ;*process name, three words. .+0 ;*when the event queue .-1 ;*is empty it must point to ; itself MESB1 ;*1. message buffer, if no ; message buffers, it must ; be 0. PG1 ;*used to find the ; program descriptor ; e.g. when the process is ; removed. 1B0 ;*state = stopped ; during load. 0 ; 1B7 ;*zero must not be used. PG4 ;*address entered ; at break. 0 ; 0 ; PC1 ;*proc.desc.addr ; must be in AC2 at start. 0 ; PG3*2 ;*execution is started ; in PG3 with carry = 0 ; and the registers loaded ; with the four values above. 0 ; . ; optional words in . ; process descriptor. . ; \f ;message buffers: MESB1: .+0 ; .-1 ; MESB2 ;*next message buffer 10 ;* PC1 ;*sender.proc.desc.addr. 0 ;*buffer free .BLK 4 ; mess0-mess3 irrelevant MESB2: .+0 ; .-1 ; 0 ;*last in chain 10 ;* PC1 ;*sender.proc.addr. 0 ;*buffer free .BLK 4 ;mess0-mess3 irrelevant . ; optional words in . ; process desc . . T_ PC2: ;end of process desc. .END PC1 ;*the start address ; must be the process ; desc.addr. Example 1. Initialization of descriptors. Parameters marked with * must be &_ initialized by the programmer. \f F_3_._ _ _ _ _ _ _ _ _M_O_N_I_T_O_R_._ 3. The primary purpose of the monitor is to implement multiprogram- ming that is simulation of parallel execution of several active processes on a single physical processor. In order to do this, the running process is interrupted at regu- lar intervals (20 msek.) by a Real Time Clock device, RTC. When such an interrupt occurs, the monitor gains control of the pro- cessor, saves the registers of the interrupted process and deter- mines, which process is to get the next time slice for instruc- tion execution. Switching from one process to another is also performed, whenever a process must wait for the completion of in- put/output. Another purpose of the monitor is to execute indivisible func- tions in disabled mode, which is necessary to implement multipro- gramming. E.g. functions allowing synchronization between proces- ses and exchange of information in such a way that only one pro- cess at a time access the information. Also interrupts from all other devices than RTC are intercepted by the monitor, and the interrupt handling monitor functions give processes the ability to synchronize with the devices. The monitor functions are de- scribed in chapter 3.2. T_3_._1_ _ _ _ _ _ _ _M_o_n_i_t_o_r_ _D_e_s_c_r_i_p_t_o_r_._ 3.1 The monitor is itself organized as a process. Its process de- scriptor contains variables and tables for the monitor. Only the &_ first part of the monitor process descriptor, corresponding to a normal process descriptor, is shown here. Some of these parame- ters are used as the corresponding parameters in the normal pro- cess description in order to let the monitor run as a dummy pro- cess when no other process wants execution time. The remaining\f locations are used for monitor variables and constants. CUR: First process in running queue. +1: Last process is running queue. Head of running queue. +2: First in process chain. WORK1: Monitor work location. WORK2: Monitor work location. TABLE: Ref. to start of device table. TOPTA: Ref. to top of device table. DFIRS: First process in delay queue +1: Last process in delay queue. Head of delay queue. +2: Ref. to break process-function. PFIRS: First in program chain. +1: State. Monitor state is always zero, because the moni- tor is always in running queue. RUNNI: Ref. to head of running queue (= 400_D_D_8U_U_5_). +1: Priority. Monitor priority is zero, which is the lowest possible. EXIT: Monitor exit address. EFIRS: First in free core. FFIRS: Last in free core. DELAY: Ref. to head of delay queue. +1: The dummy program. (jmp .+0). +2: Psw of dummy process. (.-1). AREAP: Ref. to head of area process chain. AFIRS: First in area process chain. FREQU: Frequency of RTC. Must always be zero, which corre- sponds to 50 Hz (=20 msek). MASK: Interrupt mask. CORES: Core size. PROGR: Ref. to head of program chain. +1: Address of monitor clear interrupt routine. +2: Address of RTC clear interrupt routine. \f RTIME: Real time count. T_w_o_ _w_o_r_d_s_, where the number of real time clock interrupts is counted. The number is (RTIME+0)*20UU5160DD5 + (RTIME+1). POWIN: Power failure. The number of power failures since dead start. T_ 3_._1_._1_ _ _ _ _ _R_u_n_n_i_n_g_ _Q_u_e_u_e_._ 3.1.1 The first two locations of the monitor process descrip- tor contain the head of the running queue. All proces- &_ ses wanting to compete for time slices are linked to the running queue. The first process in the running queue is the one that is actually running, and there- fore a process can always find its process descriptor address in CUR (except in a drivers clear interrupt routine. See chapter 4). This process is called the c_u_r_r_e_n_t_ _p_r_o_c_e_s_s_. The p_r_i_o_r_i_t_y_ of a process is a 16 bit integer. The priority of the monitor process i.e. the dummy process is zero, which is the lowest possible and must not be used by other processes. Inser- tion in the running queue is done in order of the priority that is, the process with the highest priority is inserted as the first in the queue. Among processes of the same priority, a new is inserted as the last one (see fig. 2). At each interrupt from RTC, the current process is relinked as the last process with that priority and the process that now is first in the queue, becomes the current process. \f T_ &_ Fig. 2 T_ 3_._1_._2_ _ _ _ _ _P_r_o_c_e_s_s_ _C_h_a_i_n_._ All process descriptors are linked together in a p_r_o_c_e_s_s_ _c_h_a_i_n_. The chain field is word no. two relative to the start of the pro- &_ cess descriptor, but the contents of the field is the address of the first word of the next process descriptor in the chain. The predefined symbol PROCE contains the address of the monitor pro- cess descriptor and can therefore be used as reference to the head of process chain. \f T_3_._1_._3_ _ _ _ _ _D_e_v_i_c_e_ _T_a_b_l_e_._ 3.1.3 All interrupts from devices are intercepted by the monitor, and processes can then synchronize with devices by using the inter- &_ rupt handling monitor functions. A d_e_v_i_c_e_ _t_a_b_l_e_, containing one word for each device number, is maintained by the monitor. When a process wants to supervise a device, it inserts its own process descriptor address in bit 0-14 of the device table entrance be- longing to the device. Only one process, called a driver process, can supervise a device. If a driver process wants to wait for an interrupt from a device, it calls the monitor function WAITIN- TERRUPT, which removes the process from the running queue and sets its state to waiting for interrupt (fig. 3). When an interrupt arrives, bit 15 in the appropriate device table entrance is set and the process descriptor is used to find the clear-interrupt routine (in proc.clint), which is then executed. If the driver process is waiting for interrupt, bit 15 is cleared again and the process is linked to the running queue. If not, bit 15 indicates that an interrupt is pending and next time the pro- cess wants to wait for an interrupt, it is immidiately relinked to the running queue. Driver processes are described in detail in chapter 4. \f T_ Device no. k is supervised by process A and device no. j is su- pervised by process C, which is waiting for interrupt from the device, or for software timer. Fig. 3. &_ \f T_ &_ Fig. 4 During the initialization of the system, the monitor process is inserted as supervisor for all devices. I.e. if an interrupt ar- rives from a device which is not supervised by a driver process, the monitors clear interrupt routine is executed. This routine clears the interrupt and counts the number of such "unknown" interrupts in a variable located just in front of the first in- struction of the routine. T_ 3_._1_._4_ _ _ _ _ _D_e_l_a_y_ _q_u_e_u_e_._ 3.1.4 If a process is not running, it may be waiting for an event (i.e. a message or an answer), waiting for an interrupt or stopped. In &_ all cases of waiting, the monitor function used makes it possible to specify a maximum number of timer periods, it wants to wait.\f If this possibility is used, the process is linked to the d_e_l_a_y_ q_u_e_u_e_ and the specified number of periods is inserted in the pa- rameter TIMER in the process descriptor. For each timer (RTC) interrupt, PROC.TIMER is decreased by one for all processes in the delay queue. When the timer count for a process becomes zero it is started, i.e. removed from the delay queue and inserted in the running queue, according to its priority (see fig. 4). DELAY contains a reference to the head of the delay queue. T_3_._1_._5_ _ _ _ _ _P_r_o_g_r_a_m_ _C_h_a_i_n_ 3.1.5 All program descriptors are linked together in a program chain. PFIRS is the head of this chain and PROGR is a pointer to the &_ head of the program chain and can be used as start address when searching for a specific program in the chain (see SEARCHITEM, chapter 3.2). T_3_._1_._6_ _ _ _ _ _F_r_e_e_ _C_o_r_e_ _A_r_e_a_._ 3.1.6 During the initialization of the system, the core size is found and inserted into the parameters CORES and FFIRS. EFIRS is used by MUS and points at the first free location in core, while DOMUS uses the parameter CORE (not shown here) as head of a chain of free core items. T_3_._1_._7_ _ _ _ _ _T_h_e_ _D_u_m_m_y_ _P_r_o_c_e_s_s_._ 3.1.7 As mentioned before, the monitor process descriptor is organized as a normal process descriptor, containing the parameter values &_ necessary to let the monitor run a dummy process when no other process wants to run. The program executed by the dummy process is the instruction JMP.+0. The location corresponding to PROC.PSW\f points to the dummy program. Other parameters needed to enable the monitor to run as a dummy process are state and priority, which are both zero. Zero is the lowest priority possible and must not be used by other processes. T_3_._1_._8_ _ _ _ _ _A_r_e_a_ _P_r_o_c_e_s_s_ _C_h_a_i_n_._ 3.1.8 A pool of free area processes are linked together in a chain with head in AFIRST. AREAP is a reference to this head. Area processes are described in chapter 8. T_ 3_._1_._9_ _ _ _ _ _I_n_t_e_r_r_u_p_t_ _M_a_s_k_._ 3.1.9 A copy of the hardware interrupt priority mask is kept in MASK. The MUS system initialization applies a zero mask, i.e. interrupt &_ requests are enabled from all devices, and the system does not support the use of the instruction MSKO. It is not recommended to use this instruction but if necessary, it must be carried out in disabled mode and the value needed to disable interrupts from the priority levels wanted must be or>ed to MASK and the result re- stored in MASK (also in disabled mode ) before the interrupt mask out instruction is applied with the new mask. After a power failure the system is again supplied with a zero interrupt priority mask. T_ 3_._1_._1_0_ _ _ _ _R_e_a_l_ _T_i_m_e_ _C_l_o_c_k_._ 3.1.10 From software it is possible to select between four real time clock frequencies, but in the MUS/DOMUS system, 20 msek. is always used. \f T_3_._1_._1_1_ _ _ _ _P_o_w_e_r_ _F_a_i_l_u_r_e_._ 3.1.11 At power failure the accumulators and the program counter are saved in the process descriptor of the current process and a jump &_ instruction to the power restart routine is saved in location 0. At power-up, an IORST instruction is executed and all processes in the device table are break>ed with error number -4. (See BREAKPROCESS, chapter 3.2). T_3_._2_ _ _ _ _ _ _ _M_o_n_i_t_o_r_ _f_u_n_c_t_i_o_n_s_._ 3.2 This chapter describes the monitor functions. Monitor functions are executed in disabled mode and are called from assembler pro- &_ grams by writing their names. In the assembler, they are defined as permanent symbols and are substituted with jump-subroutine-in- structions. In the following >l_i_n_k_> is the address of the first instruction after the function-call, and it is automatically contained in AC3 when the function is entered. The return value of AC3 is for all functions the process descriptor address of the calling process (cur). If nothing else is mentioned, the function returns to the address >link>. T_ 3_._2_._1_ _ _ _ _ _F_u_n_c_t_i_o_n_ _W_A_I_T_I_N_T_E_R_R_U_P_T_._ 3.2.1 call return AC0 unchanged AC1 device device AC2 delay cur AC3 link cur link+0 timeout &_ link+1 interrupt \f The corresponding entry in the device table is checked for an in- terrupt. If an interrupt is pending, return is immidiately made to (link+1). If no interrupt is pending, the process is removed from the run- ning queue and is inserted in the delay queue. >Delay> (AC2) is inserted as timer count in the process descriptor and the process is stopped with state waiting for interrupts or software timer (state = device). If d_e_l_a_y_ _=_ _0_, a maximum delay period of 65535 timer periods ( 25 minutes) is used. If d_e_l_a_y_ _=_ _1_, the waiting period is between 0 and 20 msek. Waitinterrupt may be used as a pure timer when d_e_v_i_c_e_ _=_ _0_. In this case state = 0 is preserved. If an interrupt arrives before the time specified by >delay> runs out the process is set running (i.e. removed from delay queue and inserted in running queue with state = 0) and return is made to link+1. Otherwise, the process is set running when the delay period runs out and return is made to link. Note: Before any call of WAITINTERRUPT with device '0, the de- vice table must be initialized to process-descriptor-add- ress*2. This may be done by procedure SETINTERRUPT (see chapter 4). \f T_ Ex: . . JSR DGCOM,2 ;start device LDA 1 DGDEV,2 ;load device no. LDA 2 .512 ;load timer WAITINTERRUPT ;waitinterrupt (device, ;delay); JMP DGTIM ;+0: timeout return . ;+1: interrupt return . . . . . . DGTIM: . . . &_ Example 2. T_ 3_._2_._2_ _ _ _ _ _F_u_n_c_t_i_o_n_ _S_E_N_D_M_E_S_S_A_G_E_._ 3.2.2 call return error return AC0 unchanged unchanged AC1 address address address AC2 name address buf error number &_ AC3 link cur cur \f Selects a free message buffer belonging to the calling process and copies the four message words placed from >address> and on- wards into this message buffer (BUF.MESS0-BUF.MESS3). The message buffer is then linked into the event queue of the receiving pro- cess with name placed in >name address> and onwards. The recei- ving process is activated, if it is waiting for an event. The calling process continues execution after being informed about the address of the message buffer in AC2. If a process with the given name could not be found in the pro- cess chain SENDMESSAGE returns with e_r_r_o_r_ _n_u_m_b_e_r_ _=_ _-_2_. If the message buffer pool of the sending process does not contain a free message buffer, the function returns with e_r_r_o_r_ _n_u_m_b_e_r_ _=_ _-_3_. \f T_ Ex: TTYNA: .+1 .TXT.TTY0'0'. ; MESAD: .+1 ;address of message 1 ;mess0 80 ;mess1 INSTR*2 ;mess2 ;mess3, irrelevant here INSTR: .BLK 40 STADR: LDA 1 MESAD ;message address LDA 2 TTYNA ;name address SENDMESSAGE ;sendmessage (mesad, ;ttyna) MOVZL# 2, 2 SZC ;if TTY not found JMP ERROR ;then got error WAITANSWER ;else wait for answer to . ;that buffer . &_ Example 3. \f T_ Before SENDMESSAGE: &_ \f T_ After SENDMESSAGE &_ Fig. 5 T_3_._2_._3_ _ _ _ _ _F_u_n_c_t_i_o_n_ _W_A_I_T_A_N_S_W_E_R_:_ 3.2.3 call return AC0 first AC1 second AC2 buf buf &_ AC3 link cur When a process has sent a message, the answer to it will be re- turned in the same message buffer. WAITANSWER delays the process until an answer arrives in the message buffer given as a para- meter. The first two words of an answer (i.e. BUF.MESS0 and BUF.MESS1) are copied into AC0 and AC1 and t_h_e_ _m_e_s_s_a_g_e_ _b_u_f_f_e_r_ _i_s_ _\f r_e_l_e_a_s_e_d_. N_o_t_e_ that WAITANSWER is the only monitor function that releases a message buffer. This means that WAITANSWER must also be used if the process has received information about the answer by means of WAITEVENT or WAIT (see these functions). T_ Ex: LDA 3 CUR ; LDA 2 BUFFE,3 ; WAITANSWER ;waitanswer (1.mess buf- ;fer) MOV# 0,0 SZR ;if buf.mess0'0 then JMP ERROR ;goto error; . ;the message buffer . ;is now released. &_ Example 4. \f T_ After WAITANSWER: &_ Fig. 6 T_ 3_._2_._4_ _ _ _ _ _F_u_n_c_t_i_o_n_ _W_A_I_T_E_V_E_N_T_._ 3.2.4 call return AC0 first AC1 second AC2 buf next buf AC3 link cur Link+0 answer &_ link+1 message The process is delayed until an event (a message or an answer) is linked to its event queue a_f_t_e_r_ _t_h_e_ _m_e_s_s_a_g_e_ _b_u_f_f_e_r_ _g_i_v_e_n_ _a_s_ _p_a_r_a_-\f m_e_t_e_r_. If >buf> is zero, the event queue is examined from its beginning. The calling process is supplied with the address of the new event in AC2 and with MESS0 and MESS1 from the event in AC0 and AC1. If the event arrived is an answer, the function returns to link+0; otherwise link+1 is chosen. Note that if an answer arrives, WAITANSWER must be used to re- lease the message buffer. T_ Ex: SUB 0,0 ;buf:= 0 WAITEVENT ;waitevent JMP ANSW ;+0: answer . ;+1: message . . . ANSW: WAITANSWER ;release message buffer . . &_ Example 5 \f T_ 3_._2_._5_ _ _ _ _ _F_u_n_c_t_i_o_n_ _W_A_I_T_._ 3.2.5 call return return (answer or message) (timeout or interrupt) AC0 delay first unchanged AC1 device second device AC2 buf next buf cur AC3 link cur cur link+0 timeout link+1 interrupt link+2 answer &_ link+3 message This function performs the combined functions of WAITINTERRUPT and WAITEVENT. >Delay> is inserted as timer count in the process descriptor and the process is linked to the delay queue. If >de- vice> is non-zero, the device table is checked for an interrupt. Then it waits, either for an interrupt, a timeout or an event af- ter the buffer given as a parameter. If >buf> is zero, the event queue is examined from the beginning. The return depends on, what happens first as listed above, and the contents of the registers are as for WAITEVENT or WAITINTER- RUPT depending on the return. Note again that if an answer arrives, the message buffer should be released by means of WAITANSWER. \f T_ Ex: LDA 2 CUR ; LDA 0 .512 ;delay LDA 1 DEV,2 ;device SUB 2,2 ;buf: = 0 WAIT ;wait (delay, device, ;buf) JMP DTIM ;+0: timeout JMP DINT ;+1: interrupt JMP DANS ;+2: answer . ;+3: message &_ Example 6 T_ 3_._2_._6_ _ _ _ _ _F_u_n_c_t_i_o_n_ _S_E_N_D_A_N_S_W_E_R_._ 3.2.6 call return AC0 first first AC1 second second AC2 buf buf &_ AC3 link cur >Buf> is the address at the message buffer which the calling pro- cess wants to answer. >First> and >second> are copied into MESS0 and MESS1 of the message buffer and the buffer is then delivered as an answer in the event queue of the original sender (i.e. the owner of the buffer). If the calling process also wants to return information in MESS2 and MESS3 of the buffer, this information must be stored directly in BUF.MESS2 and BUF.MESS3 by the calling process before SENDANSWER is called. \f T_ Ex: WAITEVENT ; JMP DANS ; +0: answer STA 2 BUF,3 ; +1: message . ; . ;handling of message SUB 0,0 ;buf.mess0: = 0 LDA 1 COUNT,3 ;buf.mess1: = cur.count LDA 2 BUF,3 ; SENDANSWER &_ Example 7 \f T_ After SENDANSWER: &_ Fig. 7 T_ 3_._2_._7_ _ _ _ _ _F_u_n_c_t_i_o_n_ _S_E_A_R_C_H_I_T_E_M_._ 3.2.7 call return AC0 unchanged AC1 chain head chain head AC2 name addr item &_ AC3 link cur If the chain with the address of the chain head placed in AC1 contains an item with the name placed in >name address> and on-\f wards, the address of this item is delivered; otherwise a zero is delivered. The address of the head of the process (program) chain is con- tained in the monitor parameter PROCE (PROGR). An item in the process chain can be found as shown in ex. 8. T_ Ex: NAADR: .+1 .TXT .PTR0'0'. START: LDA 1 PROCE ;process chain head LDA 2 NAADR ;name address SEARCHITEM ;searchitem (PROCE, PTR) MOV# 2,2 SNR ;if item not found JMP NOTFO ;then goto notfo. . ;else continue . . . &_ Example 8 \f T_ Ex: C1: .+3 ;chain S100 ;size .TXT .P1000'. ;name .+3 ;chain S101 ;size .TXT .P1010'. ;name .+3 ;chain S102 ;size .TXT .P1020'. ;name 0 ;chain S103 ;size .TXT .P1030'. ;name C1REF: .+1-CHAIN ;ref. to head of chain C1 C1-CHAIN ;head of chain C1 ; NAADR: .+1 .TXT .P1020'. START: LDA 1 C1REF ;chain head LDA 2 NAADR ;name address SEARCHITEM ;searchitem (C1, name) MOV# 2,2 SNR ;if item not in C1 then JMP NOTFO ;goto notfound; &_ Example 9 \f T_3_._2_._8_ _ _ _ _ _F_u_n_c_t_i_o_n_ _B_R_E_A_K_P_R_O_C_E_S_S_._ 3.2.8 call return AC0 error number error number AC1 unchanged AC2 proc proc &_ AC3 link cur The process given as parameter with process descriptor address in AC2 is started at its break address with the following accumula- tor contents: T_ AC0 error number AC1 unchanged AC2 proc &_ AC3 PSW (its old program counter) The following error numbers are used by MUS/DOMUS system proce- dures: -4: All processes inserted in the device table are break>ed with error number -4 at power interrupt. -3: From the coroutine monitor procedure CSENDMESSAGE. No system operations available to send messages. 3. 1: The break>ed process has received a message from a process which has been cleaned after it has sent the message (see function CLEANPROCESS). 2: The process is break>ed by the operator. \f 3: A MUSIL program is break>ed with error number 3 if it reaches the end. 5: The status returned from a zone contains a hard-error-bit which is not set in the giveup mask of the zone (see WAITTRANSFER, chapter 5). 6: From the coroutine monitor procedures SAVELINK and RETURN. Stack over- or underflow. 3. 7: a) Page system break. b) Break from the coroutine monitor procedure WAITGEN. No system operation available for receiving messages although reserved. 3. 8: Reserver removed. Only reservable (driver) process that is processes with bit 7 set in the program description word. T_ Ex: LDA 1 PROCE ; LDA 2 NAADR ;searchitem (process- SEARCHITEM ;chain, name) MOV# 2,2 SNR ;if proc not found JMP ERROR ;item goto error LDA 0 .16 ;else BREAKPROCESS ;breakprocess (16, proc) . . . . &_ Example 10 \f T_ 3_._2_._9_ _ _ _ _ _F_u_n_c_t_i_o_n_ _C_L_E_A_N_P_R_O_C_E_S_S_._ 3.2.9 call return AC0 unchanged AC1 unchanged AC2 proc proc &_ AC3 link cur Messages to the process given as parameter are answered with sta- tus (= MESS0) = 0 and bytecount (= MESS1) = 0. Answers to the process are released. Messages from the process are released and the receivers are break>ed with error number = 1. The function is used to tidy up, e.g. the operating system S app- lies it before killing a process. CLEANPROCESS must be used with special care, as it may cause the processor to run in disabled mode for an unpredictable time. T_ Ex: LDA 2 CUR ;the process CLEANPROCESS ;cleans itself &_ \f T_ Ex: NAADR: .+1 ; .TXT .P220'0'. ; START: LDA 1 PROCE ; LDA 2 NAADR ; SEARCHITEM ;searchitem (PROCE, P22) MOV# 2,2 SZR ;if P22 in processchain CLEANPROCESS ;then CLEANPROCESS (P22) . . &_ Example 11 T_ 3_._2_._1_0_ _ _ _ _F_u_n_c_t_i_o_n_ _S_T_O_P_P_R_O_C_E_S_S_._ 3.2.10 call return AC0 unchanged AC1 unchanged AC2 proc proc &_ AC3 link cur The process is set in state stopped and removed from the delay- or running queue. If it was waiting for event or answer, PSW is decreased by 1. This ensures that the monitor function is called again if STARTPROCESS is performed. T_ Ex: LDA 2 CUR ;the process &_ STOPPROCESS ;stops itself. \f T_3_._2_._1_1_ _ _ _ _F_u_n_c_t_i_o_n_ _S_T_A_R_T_P_R_O_C_E_S_S_._ 3.2.11 call return AC0 unchanged AC1 unchanged AC2 proc proc &_ AC3 link cur If the process is in state stopped, it is set running. Otherwise, the function is dummy. T_ Ex: LDA 1 PROCE ; LDA 2 NAADR ;searchitem, (process- SEARCHITEM ;chain, name addr) MOV# 0,0 SNR ;if process found JMP ERROR ; STARTPROCESS ;then start it; &_ Example 12 T_ 3_._2_._1_2_ _ _ _ _F_u_n_c_t_i_o_n_ _R_E_C_H_A_I_N_._ 3.2.12 call return error return AC0 old old old AC1 new new new AC2 elem elem -3 &_ AC3 link cur cur The parameters >old> and >new> are chain head addresses and >e- lem> is the address of an item. This item is removed from the old chain and inserted in the new chain. \f Error return: If the element does not exist in the old chain, the function returns with AC2 = -3. Ex: C1: .+3 ;chain S100 ;size .TXT .P1000'. ;name .+3 ;chain S101 ;size .TXT .P1010'. ;name CHELM: .+3 ;chain S102 ;size .TXT .P1020'. ;name 0 ;chain S103 ;size .TXT .P1030'. ;name C2: 0 ;empty chain C1REF: .+1-CHAIN ;ref to head of chain C1 C1-CHAIN ;head of chain C1 C2REF: .+1-CHAIN ;ref to head of chain C2 C2-CHAIN ;head of chain C2 ELEM: CHELM-CHAIN ;P102 START: LDA 0 C1REF ;old: = chain C1 LDA 1 C2REF ;new: = chain C2 \f LDA 2 ELEM ;elem: = P102 RECHAIN ;rechain (elem, old, new) MOVZL# 2,2 SZC ;if elem not in chain ;then JMP ERROR ;goto error . . T_ Before RECHAIN: &_ \f T_ After RECHAIN: &_ Example 13 T_ 3_._3_ _ _ _ _ _ _ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_ _o_f_ _t_h_e_ _M_o_n_i_t_o_r_._ 3.3 When the basic system is loaded, the initialization module (MUI) is started. After an IORST has been performed and the real time &_ clock has been started, all processes in the basic system are linked into the process chain and the running queue and their programs are inserted in the program chain. The process descrip- tor addresses of processes in the basic system are found from lo- cation 4020_D_D_8U_U_5_ and on, where they have been inserted by system generation programs. This sequence stops with the value -1. Then the device table is initialized with the program status word (PSW) of the dummy process, which means that if an interrupt appears from\f a device not supervised by a driver process, the clear interrupt routine specified in the monitor process descriptor is executed. This routine counts all such interrupts in a variable, placed just in front of its first instruction. At last the core size is calculated and the first process in the running queue, which is S because S has the highest priority, be- comes active. As MUI is always placed after S in a basic system, it is overwritten when the first process is loaded by the opera- tor. T_ 3_._4_ _ _ _ _ _ _ _P_r_o_c_e_s_s_o_r_ _E_x_p_a_n_s_i_o_n_._ 3.4 The processor expansion system, which makes it possible to communicate between processes placed in two different processors, consists of a software module, XCOMX, a copy of which is placed in each processor. XCOMX is a normal MUS process which takes care of sending messages and data destined for processes in the other processor and returning answers the other way. The system is de- scribed in 4. The only monitor function that takes special care of XCOMX is SENDMESSAGE. When a message is sent, SENDMESSAGE searches for the receiving process in the process chain. If it is found, the message is inserted in its event queue, but if it is not found, the function will instead search for XCOMX. If XCOMX is present, the message is linked into the event queue of XCOMX, which then takes care of sending it to the other processor. In addition the name of the receiving process and the address of the buffer are stored in a table starting in the monitor variable COMLIST. This information is needeed by XCOMX. COMLIST and the lenght of this table, COMNO, is set by XCOMX, when it is loaded. \f 4_._ _ _ _ _ _ _ _ _D_R_I_V_E_R_ _P_R_O_C_E_S_S_E_S_._ 4. 4_._1_ _ _ _ _ _ _ _I_n_t_r_o_d_u_c_t_i_o_n_._ 4.1 A driver process is a normal process seen from the monitor, but it is dedicated to communicate with a device. Under special cir- cumstances it might take care of several devices. E.g. console input and console output driver. The reason for introduction of processes dedicated to device con- trol are: - to let more than one process communicate with a de- vice. Without a driver as interface this would demand explicit arrangements among involved processes. - to handle devices in a more uniform way. That is, in- troduction of standard operations, standard status information and blocking of all input/output, also for character oriented devices. - to realize simple and time-saving conversions of cha- racters directly from input or output to the devi- ces. Other processes must then request the driver process to perform input/output by means of messages, and the driver processes are thus the only processes which actually execute I/O instructions and take care of the device dependant interrupt service. The messages accepted by the driver process should conform to the below mentioned standards, and the answers should also be of a standard form. As the zone procedures used by the application program expect special reactions in connection with the exception handling all \f messages must be returned by the driver within a finite time. Furthermore, the driver must enter a reject state after return of a hard error status, in which all transput messages are rejected with a non-processed status. This reject state is important and necessary when input/output is of a sequential nature, as the errormarked message must be in- put/output before the following transfer request are granted when multibuffered input/output is used. This driver reaction is not used in the handling of devices with an input/output structure more complex than simple sequential in- put/output transfer. The driver reject state must be cleared by special messages send by the user process. 4_._2_ _ _ _ _ _ _ _D_e_v_i_c_e_ _H_a_n_d_l_i_n_g_._ 4.2 Before any I/O instructions are executed, the driver process should clear the device in question by the device specific I/O instruction (normally a NIOC DEVNO). Then the driver must insert its process descriptor address shifted one left (bit 15 = 0) in the corresponding device table entry, either directly or by a call of the procedure SETINTER- RUPT, which will also execute the above mentioned NIOC instruc- tion. \f ex: ; DIRECT INSERTION IN DEVICE TABLE ; LDA 3 E000 ; ADDR: = TABLE LDA 1 E001 ; ADD 1,3 ; ADDR: = TABLE + DEVNO; LDA 2 CUR ; MOVZL 2,0 ; WORD(ADDR): = CUR ; SHIFT 1; STA 0 +0,3 ; . . E000: DEVTA ; ADDRESS OF DEVICE TABLE E001: DEVNO ; DEVICENUMBER Example 14A ; USE OF PROCEDURE SETINTERRUPT ; LDA 1 E002 ; SETINTERRUPT ; SETINTERRUPT (DEVNO); .; NIOC DEVNO . E002: DEVNO Example 14B \f When the device table word is initialized, all interrupts from the device will cause the call of a user defined interrupt proce- dure given by its address in the process descriptor with the dis- placement CLINT (see fig. 8). Fig. 8 Organisation of device table, process descriptor and in- terrupt procedure in a driver process. The user defined interrupt procedure must obey the following con- ventions: \f U_s_e_r_ _i_n_t_e_r_r_u_p_t_ _p_r_o_c_e_d_u_r_e_ Call Return AC0 - destroyed AC1 device unchanged AC2 process descriptor addr unchanged AC3 link destroyed T_h_e_ _p_r_o_c_e_d_u_r_e_ _i_s_ _c_a_l_l_e_d_ by t_h_e_ _m_o_n_i_t_o_r_ _i_n_ _d_i_s_a_b_l_e_d_ _m_o_d_e_ _a_n_d_ _i_t_ m_u_s_t_ _n_o_t_ _c_h_a_n_g_e_ _t_h_i_s_ _s_t_a_t_e_. I_t_ _m_u_s_t_ _r_e_t_u_r_n_ _w_i_t_h_ _t_h_e_ _d_e_v_i_c_e_ _i_n_t_e_r_- r_u_p_t_ _r_e_q_u_e_s_t_ _c_l_e_a_r_e_d_,_ _a_n_d_ _i_t_ _m_u_s_t_ _n_o_t_ _c_a_l_l_ _o_t_h_e_r_ _s_y_s_t_e_m_ _p_r_o_c_e_- d_u_r_e_s_ _o_r_ _u_s_e_ _a_n_y_ _s_y_s_t_e_m_ _v_a_r_i_a_b_l_e_s_. (The standard variable CUR t.ex. points to the interrupted process and n_o_t_ to the driver process). The amount of data processing must be as small as possible since it affects the system overhead. Priorities in interrupt service by means of the hardware MASKOUT feature is not supported. Instead, the interrupt service time should be kept at a minimum in the disabled interrupt service routine, and the priority between different devices can then be achieved by the process priority, as active processes are assig- ned CPU time according to the process priorities. Data handling should also be done outside the interrupt service routine as all system variables and procedures can be used freely in this case. The system offers a standard interrupt procedure which only exe- cutes a NIOC device'. This procedure can be selected by the sys- tem address CLEAR. If at return the driver process is in a state waiting for inter- rupt from the interrupting device, the process is set running. \f If the process is in any other state, the interrupt is indicated by the monitor setting bit 15 in the device table word, thus in- dicating one or more interrupts from the actual device. This bit is only cleared if the process calls the WAITINTERRUPT function, in which case the return from WAITINTERRUPT takes place immidiately, or when the bit is cleared by an initialization as mentioned above, using the procedure SETINTERRUPT. If the process start or interrupt indication is not wanted, the return can be made by an indirect jump to the monitor exit action (JMP@ EXIT). No check is performed on the selected device code, and special care must be taken to secure that two driver processes do not use the same device code. The device codes 0, 1, 2, 3, 4, 140_D_D_8U_U_5_ and 770_D_D_8U_U_5_ are used exclusively by the system and must not be used by any driver. Devicecode 140_D_D_8U_U_5_ is the real time clock (RTC) and code 770_D_D_8U_U_5_ is the CPU. Other standard RC 3600 device codes can be found in the appendix. 4_._3_ _ _ _ _ _ _ _D_r_i_v_e_r_ _I_n_t_e_r_f_a_c_e_._ 4.3 User programs communicate with a driver by means of messages with two standard formats: control and transput. A control message in- dicates an operation which does not imply any actual input or output but performs positioning, selects different facilities such as parity, density, baud rate, conversion etc. A transput message requests input to or output from a message defined core- area. Regardless of the message type, the answer returned when a mes- sage has been processed by the driver process contains a status\f word, which describes the success of the requested operation. 4_._3_._1_ _ _ _ _ _C_o_n_t_r_o_l_ _M_e_s_s_a_g_e_s_._ 4.3.1 The standard format of a control message is: 0 14 15 MESS0 MODE 00 MESS1 SPECIAL 1 MESS2 SPECIAL 2 MESS3 SPECIAL 3 The mode is any array of bits which specifies the actions to be taken. An action is performed if the corresponding bit is one. The in- terpretation proceeds normally from bit 13 to bit 0. Not all ac- tions are relevant for specific driver processes and some com- plex drivers will give other reactions than the standard reac- tions described below: \f Fig. 9 Standard mode bits in RC 3600 MUS system. The standard mode bits can be seen in the word layout in fig. 9. R_e_s_e_r_v_a_t_i_o_n_ If bit 13 is set in the MESS0 word, the action depends on the contents of MESS1 as follows: MESS1'0: The sender of the message is set as reserver of the driver, i.e. the sender gains exclu- sive access to the driver process, and mes- sages from other processes are rejected. MESS1=0: The gained reservation is cancelled and the driver process will accept any message again. \f C_o_n_v_e_r_s_i_o_n_ If bit 12 is set in the MESS0 word, the MESS2 part (special 2) is taken as a byteaddress of a conversion table. A table address of zero specifies no conversion. Format and in- terpretation of the table is dependent on the driver. Note that if conversion is used, reservation ought to be done. T_e_r_m_i_n_a_t_i_o_n_ Normally used only by output devices, as it indicates that the data, which has previously been output, must be terminated logi- cally. E.g. for a magnetic tape, a file mark is written and for a paper tape punch a leader is punched. The termination action is taken, if bit 11 of the MESS0 word is set. P_o_s_i_t_i_o_n_ The document is positioned according to the information in the message, or the special parameters are taken from the message words MESS2 and MESS3. If the message is interpreted as a true position command, MESS2 (special 2) is taken as the wanted file position and MESS3 (spe- cial 3) is taken as the new block position. In special cases, the maximum value of MESS3 is too small and the wanted blockposition is calculated by taking the first byte of MESS0 as the most significant part and MESS3 as the least signi- ficant part. As the presence of bit 10 in the MESS0 part of the message nor- mally indicates parameters in MESS2 and MESS3, this bit is nor-\f mally the only one set in the word and thus it is not used to- gether with actions indicated by other bits. D_i_s_c_o_n_n_e_c_t_i_o_n_ If bit 9 of the MESS0 part is set, the device in question is set local if possible. E.g. a magnetic tape is rewound and the sta- tion is set off-line. E_r_a_s_u_r_e_ Only relevant for output devices, which are able to cancel pre- vious output. E.g. some inches of magnetic tape are erased or a flexible disc sector is marked as a skip sector. G_e_n_e_r_a_l_ If all bits are zero in the MESS0 part, a sense of the device is executed by the driver. If the driver is able to handle a number of devices connected to the same controller with a single device code, the first byte can be used as a stream number and the above mentioned actions can then be done for the stream in question. E.g. several VDU>s connected to a multiplexer. \f Example a) Control message with request for reservation and conversion table address 17777DD8UU. (I/O procedure OPEN). b) Control message requesting position to file 2, block 10DD8UU. (I/O procedure SETPOSITION). 4_._3_._2_ _ _ _ _ _T_r_a_n_s_p_u_t_ _M_e_s_s_a_g_e_s_._ 4.3.2 A transput message requests an operation, which involves transfer of data to or from a core area. The core area can be transferred by the driver either byte by byte with programmed input/output or directly from the core area by hardware controlled DMA transfer (DMA = Direct Memory Access), but seen from the user process there is no difference as the data is handed over as a whole block. The standard format of a transput message is: \f 4_._3_._2_._1_ _ _ _I_n_p_u_t_._ 4.3.2.1 MESS0 operation 01 MESS1 bytecount MESS2 byteaddress MESS3 special 4_._3_._2_._2_ _ _ _O_u_t_p_u_t_._ 4.3.2.2 MESS0 operation 11 MESS1 bytecount MESS2 byteaddress MESS3 special Fig. 10 Standard formats of input and output messages. The operation field of MESS0 transmits information about the mode of transfer. E.g. parity, format or special actions. The bytecount in MESS1 specifies the number of bytes to be trans- ferred to or from the core area, pointed out by the first byte given in the MESS2 word of the message (byte address). MESS3 contains special information concerning the transfer t.ex. the block number of the wanted block to be read/written on a ran- dom accessible device. \f The first byte of MESS0 can be used as a stream number or as an extension to the special information in MESS3. Bit 8 set in MESS0 is normally used to indicate that MESS2 should be interpreted as a wordaddress. The core area to input or output must have a layout as seen in fig. 11. The bytes are packed left to right in the memory words with the first byte in the lowest memory address. Fig. 11 Layout of core area pointed out by a transput message. \f Example 15: a) Input message requesting transfer of 10DD8UU bytes to address 12765DD8UU. b) Output message requesting transfer of 20DD8UU bytes from address 13775DD8UU and on. 4_._3_._3_ _ _ _ _ _A_n_s_w_e_r_s_._ 4.3.3 The answers returned in the message buffer is independent of the message type received and the format is: 4_._3_._3_._1_ _ _ _A_n_s_w_e_r_._ 4.3.3.1 MESS0 status MESS1 bytecount MESS2 special 1 MESS3 special 2 Fig. 12 Standard answer \f The MESS0 part of the message is an array of bits called status, which conveys information about device errors or call errors and gives information about the success of the device action requested by the received message. The different bits have been given special meanings in order to standardize error recovery in the user input/output procedures. The status returned on a successfull operation should be zero, except for the below mentioned bits 3, 4, 5 which have device de- pendent informative functions only. The standard status bit interpretation is: bit mnemonic clean 0 disconnected * The device is not pre- sent. 1 off-line * The device is or has been off-line. The device is not ready. 2 device busy * The device was tempora- rily not able to execute the operation. 3 device spec 1 Device dependent, infor- mative. 4 device spec 2 Device dependent, infor- mative. 5 device spec 3 Device dependent, infor- mative. Document write protected. (Returned with >illegal> when output\f transfers are attempted) 6 illegal * Device reserved. Operation illegal or un- known. 7 eof * Logical end of document is detected. E.g. file mark read, end of trans- mission. 8 block error * The core area specified is too small to hold the input block, or the out- put block was too big for the document. 9 data late * The high speed data chan- nel responded too late, and data was lost. 10 parity * One or more invalid cha- racters were input or one or more characters were output badly on the docu- ment (device read after write feature). 11 end medium * Physical end of medium. E.g. end-of-tape, paper tape reader empty, paper out on printer. 12 position error * The requested position was nonsense or not found. \f 13 Not used by driver. Used by I/O procedures to in- dicate the absense of the driver process. 14 timeout * An expected interrupt was not received within a maximum driver specified time. 15 rejected * The message was returned without any treatment, because a previously re- turned answer contained a cleanbit as marked in this table. All statusbits marked with * are called cleanbits. This means that all the following transput messages received after the re- turn of one or more of these bits should be rejected with status bit 15. This enables the user to reestablish the original se- quence of messages in the driver event queue after an error reco- very. The driver accepts transput messages again after reception of a control message. Special care must be taken when status is returned on control messages. Logical meaningless status as block length error or pa- rity error on position messages should be avoided. The bytecount of answer specifies the number of bytes actually transferred. Special 1 and special 2 can be used for special information con- cerning the transfer or operation, and they normally hold the filecount (special 1) and blockcount (special 2) if position in- formation has meaning in connection with the actual device. \f 4_._4_ _ _ _ _ _ _ _S_y_s_t_e_m_ _U_t_i_l_i_t_y_ _P_r_o_c_e_d_u_r_e_s_._ 4.4 4_._4_._1_ _ _ _ _ _F_o_r_m_a_t_s_._ 4.4.1 As an aid to the driverprogrammer a number of actions, which fre- quently have to be executed in any driver, are collected as re- entrant routines. Furthermore, these routines are designed to give the standard driverinterface expected by the basic I/O pro- cedures used for standard I/O operations. If these procedures are used, the process descriptor should con- tain a number of extra words after the standard variable SAVE. These words are given by the displacements below and can be fetched relative to the process descriptor (CUR): BUF: Address of the current message buffer found by the procedures NEXTOPERATION and WAITOPE- RATION when returning. It is also used as a call parameter to these procedures set by the programmer or the procedure RETURNANSWER. ADDRE: Value of MESS2 of the current message buffer i.e. the first byte address of the data in case of a transput message. Used by the procedure RETURNANSWER for calculation of the bytecount in the returned message. COUNT: Value of MESS1 of the current message buffer, i.e. the number of bytes in case of a trans- put message. RESER: Word containing the address of the reserver- process description set and cleared by the procedure SETRESERVATION and checked by the procedures NEXTOPERATION and WAITOPERATION. \f CONVT: Word containing the conversion table address fetched from the message indicated by BUF when SETCONVERSION is called. CLINT: Address of the interrupt procedure to be called by the monitor when the device requests an interrupt. System address CLEAR can be used if only a NIOC devno' is wanted. STTAB: Standard conversion table address. Used by some drivers supporting standard conversion. If the user requests no conversion, this address is taken as the conversion table address. STTAB is set by special system programs. 4_._4_._2_ _ _ _ _ _P_r_o_c_e_d_u_r_e_s_._ 4.4.2 4_._4_._2_._1_ _ _ _P_r_o_c_e_d_u_r_e_ _N_E_X_T_O_P_E_R_A_T_I_O_N_._ 4.4.2.1 call return (+0, +1, +2): AC0 - mode AC1 - count AC2 cur cur AC3 - buf +0: control message received. +1: input message received. +2: output message received. SAVE: destroyed BUF: set by procedure COUNT: set by procedure ADDRE: set by procedure \f >Mode> returned in AC0 is equal to MESS0 SHIFT -2. This procedure is used when the driver is ready for a new operation, and will delay the driver process until a relevant message arrives in its event queue. If the word BUF in the process descriptor is set equal to -1 either by the programmer or the procedure RETURNANSWER, indica- ting return of a hard error in a previous answer, the procedure will automatically return all transput messages received, with the not processed status (1b15) and zero bytecount, until a con- trol message is received. At the receival of a control message, the BUF is reset and the procedure returns. If a message is received with a sender different from a nonzero reserver word (RESER) in the process description, this message is returned automatically with illegal status, and the procedure will not return but continue to examine the event queue. If a transput message is received with zero bytecount (MESS1 = 0) this message is returned with zero status and zero bytecount. The procedure thus saves the program from testing the special case of zero bytecount, and the standard instruction decrement and skip if zero (DSZ)can be used freely on the word COUNT in the process description. If a control message (MESS0(15:15) = 0) is received, the message buffer address is saved in BUF, and COUNT and ADDRESS is set equal to MESS1 and MESS2 of the message buffer. Return is to the word following the call. If a transput message (MESS0(15:15)=1) is received, the message buffer address is saved in BUF and COUNT and ADDRESS is set equal to MESS1 and MESS2. Return is to the second word following the call if the operation is input else to the third word. \f Process First message buffer BUF ADDR COUNT RESER CONVT CLINT MESS0 MESS1 MESS2 MESS3 Fig. 13 \f Fig. 14 Procedure NEXTOPERATION flow \f 4.4.2.2 4_._4_._2_._2_ _ _ _P_r_o_c_e_d_u_r_e_ _W_A_I_T_O_P_E_R_A_T_I_O_N_._ Call return +0, +1 return +2 return +3, +4, +5 AC0 timer unchanged destroyed mode AC1 deviceno unchanged destroyed count AC2 cur destroyed destroyed cur AC3 - cur cur buf +0: Timer expired +1: Interrupt received +2: Answer received or the procedure has returned a buffer automatically. +3: Control message received +4: Input message received +5: Output message received SAVE: Destroyed BUF: Set by procedure COUNT: Set by procedure ADDRES: Set by procedure >Mode> returned in AC0 is MESS0 SHIFT -2. This procedure may be used by a driver process when it is necessary to wait for either device interrupt, timeout or a message. The procedure will treat the received messages as described in the procedure NEXTOPERATION, i.e. check the reserver, transput- message with zero bytecount and reject action if BUF equals -1. If the timer given as parameter in the call expires before any message or answer is received, the procedure will return to the address following the call. The procedure can be used without the interrupt return if the given devicenumber is set to zero, thus indicating a wait for the real time clock. \f The timer is given in units of 20 ms. When called, the process descriptor word BUF must be equal to 0, indicating wait for any buffer, or -1, indicating wait for any buffer but reject transput messages received. If wait for a message following a buffer in the event queue is wanted, BUF must contain the address of this buffer. Fig. 15 If BUF in process descriptor contains the address of message buffer BUF#1, the address of message buffer BUF#2 is returned by procedure WAITOPERATION. Return is made to the third word if the procedure returns a mes- sage with the not processed status or illegal status, or if it returns a transput message with zero bytecount. \f If an answer is received, return is made to the same address and the answer can then be fetched by a call of the procedure WAIT- ANSWER on the relevant message buffer. The address of the answered message buffer is not returned by the procedure. Note that when the procedure is called, BUF must be equal to 0 or -1 or point to a message buffer in the event queue, otherwise a system breakdown may occur as there is no check on the parame- ters. 4_._4_._2_._3_ _ _ _P_r_o_c_e_d_u_r_e_ _R_E_T_U_R_N_A_N_S_W_E_R_._ 4.4.2.3 Call Return AC0 status status AC1 MESS2 to buf destroyed AC2 cur cur AC3 - destroyed SAVE: Destroyed BUF: Set to zero if no hardbits present in status (bit 0-2, bit 6-14) else -1. COUNT: Undefined ADDRE: Undefined The parameter status is set into MESS0 of the message buffer pointed out by BUF. The number of bytes (MESS1) is calculated by subtracting the ori- ginal byte address still remaining in the message buffer (MESS2) from the updated byte address found in ADDRE in the process de- scription. \f If one of the clean bits is set in status, the BUF word is set to -1, indicating that following transput messages must be returned with the not processed status (1B15). The message buffer is returned to the sender process by means of the SENDANSWER procedure. The word BUF m_u_s_t_ point to a message buffer in the driver event queue, otherwise the call will cause system break down. 4_._4_._2_._4_ _ _ _P_r_o_c_e_d_u_r_e_ _S_E_T_R_E_S_E_R_V_A_T_I_O_N_._ 4.4.2.4 Call Return AC0 operation operation/2 AC1 - destroyed AC2 cur cur AC3 - destroyed RESER: Set by the procedure. If bit 15 of the operation (reservation bit of MESS0 when shifted 2 to the left by NEXTOPERATION) is nonzero, MESS1 of the message buffer given in BUF is examined. If this word is nonzero, the sender of the message is inserted as reserver of the process (RESER word), otherwise the word RESERVER is set to zero, indicating no reserver process. \f 4_._4_._2_._5_ _ _ _P_r_o_c_e_d_u_r_e_ _S_E_T_C_O_N_V_E_R_S_I_O_N_._ 4.4.2.5 Call Return AC0 operation operation/2 AC1 - destroyed AC2 cur cur AC3 - destroyed CONVT: Set by the procedure. If bit 15 of the parameter operation (conversion bit of MESS0 when shifted 3 left by NEXTOPERATION and SETRESERVATION) is non- zero, the CONVT is set equal to MESS2 of the message buffer given in BUF. 4_._4_._2_._6_ _ _ _P_r_o_c_e_d_u_r_e_ _C_O_N_B_Y_T_E_._ 4.4.2.6 Call Return AC0 byte newbyte AC1 - destroyed AC2 cur cur AC3 - destroyed The returnvalue >newbyte> is the bytevalue found at relative lo- cation >byte> in the conversion table specified by the process descriptor word CONVT. The conversion table address must be a byteaddress, and the new bytevalue is fetched as: \f . . LDA 1 CONVT,2 ; ADD 0,1 ; GETBYTE ; . If the convertion table address is zero, the procedure is dummy and the byte returned is the same as given in the call. 4_._4_._2_._7_ _ _ _P_r_o_c_e_d_u_r_e_ _G_E_T_B_Y_T_E_._ 4.4.2.7 Call Return AC0 - byte AC1 byte addr byte addr AC2 - cur AC3 - destroyed Fetch the byte at the given byte address. The wordaddress of the word containing the byte is taken as (byte addr)/2, and if bit 15 is set in the byte address, the rightmost byte is delivered, else the leftmost. 4_._4_._2_._8_ _ _ _P_r_o_c_e_d_u_r_e_ _P_U_T_B_Y_T_E_._ 4.4.2.8 Call Return AC0 byte unchanged AC1 byteaddr byteaddr AC2 - cur AC3 - destroyed \f Store the byte value given as parameter at the given byteaddress. The byteaddress is interpreted as in the GETBYTE procedure. The remaining part of the word containing the byte is unchanged if the byte given is in the range 0 to 255. ; Procedure MOVEBYTES ; call return ; AC0 count destroyed ; AC1 to-addr destroyed ; AC2 from-addr cur ; AC3 - destroyed ; The procedure moves >count> byte to the byte address to-addr ; from the byte address from-addr ; MBYTE: STA 3 LINK ; MOVEBYTES: STA 1 TOADDR ; STA 2 FRADDR ; STA 0 BCOUNT ; REPEAT LOOP: LDA 1 FRADDR ; GETBYTE ; GETBYTE (FRADDR, BYTE); LDA 1 TOADDR ; PUTBYTE ; PUTBYTE (TOADDR, BYTE); ISZ TOADDR ; TOADDR:=TOADDR+1; \f ISZ FRADDR ; FRADDR:=FRADDR+1; DSZ BCOUNT ; COUNT:=COUNT-1 JMP LOOP ; UNTIL COUNT = 0 JMP LINK ; RETURN LINK: 0 ; BCOUNT: 0 ; TOADDR: 0 ; FRADDR: 0 ; Example 16 Use of PUTBYTE and GETBYTE 4_._4_._2_._9_ _ _ _P_r_o_c_e_d_u_r_e_ _M_U_L_T_I_P_L_Y_._ 4.4.2.9 Call Return AC0 op1 result(0:15) high part AC1 op2 result(16:31) low part AC2 - cur AC3 - destroyed SAVE: Destroyed Computes the unsigned double length product of the two single length operands, result:=op1*op2. The result is 32 bits long. \f 4_._4_._2_._1_0_ _ _P_r_o_c_e_d_u_r_e_ _D_I_V_I_D_E_._ 4.4.2.10 Call Return AC0 dividend quotient AC1 divisor divisor AC2 - cur AC3 - remainder SAVE: Destroyed Performs a short division of the 16 bit dividend extended with zeroes by the divisor, giving single length quotient and remain- der. quotient:= dividend//divisor remainder:= dividend REM divisor Division with a zero divisor is not checked and delivers unpre- dictable results. 4_._4_._2_._1_1_ _ _P_r_o_c_e_d_u_r_e_ _S_E_T_I_N_T_E_R_R_U_P_T_._ 4.4.2.11 Call Return AC0 - destroyed AC1 deviceno deviceno AC2 - unchanged AC3 - destroyed The procedure is executed with interrupt disabled. It includes the process as user of the device. The device given by >deviceno> is cleared by a NIOC deviceno' instruction. Any interrupt request from deviceno will cause a call of the interrupt procedure defined by CLINT in the process descriptor. \f A standard system procedure is CLEAR, which executes a NIOC in- struction. LOOP: . ; LOOP: . . . NEXTOPERATION ; NEXTOPERATION (MODE); JMP CONTR ; +0: GOTO CONTROL; JMP ILLEGAL ; +1: GOTO ILLEGAL; . ; +2: OUTPUT . . ; . ; JMP OK ; GOTO OKSTATUS; CONTR: SETRESERVATION ; CONTROL: SETCONVERSION ; SETRESERVATION; MOVZR 0,0 SNC ; SETCONVERSION; JMP OK ; IF TERMINATION THEN . ; BEGIN . ; . . ; . . ; . . ; END; . ; GOTO OKSTATUS ILLEGAL: LDA 0 SILLE ; ILLEGAL: JMP RET ; STATUS:= ILLEGAL OK : LDA 0 .0 ; OKSTATUS: RET : RETURNANSWER ; STATUS:= 0 JMP LOOP ; RETURNANSWER; \f 4_._5_ _ _ _ _ _ _ _D_r_i_v_e_r_ _R_e_q_u_i_r_e_m_e_n_t_s_._ 4.5 In the previous sections a number of driver standards have been mentioned. These standards are fulfilled if the MUS utility pro- cedures are used and if the messageformats described are accepted by the drivers and the answers returned are of standard layout. When drivers are designed, it should be noted that I/O instruc- tions are not checked by the system and it is then the program- mers responsibility that other system components are left un- touched in all situations. Therefore the use of IORST,MSKO in- structions is not allowed and special care must be taken if INTDS and INTEN instructions are used, as the system performance can decrease rapidly when too much driver code is executed in dis- abled mode. It should also be noted that the system offers no memory protec- tion and even small programming errors can have disastrous ef- fects on the whole system. 4_._5_._1_ _ _ _ _ _B_r_e_a_k_ _A_c_t_i_o_n_._ 4.5.1 The driver can, as all processes, be breaked with a number of causes, e.g. if a message buffer is removed from its event queue by the monitor after a process kill or at system start up after power failure. Whenever the driver is breaked it must stop all operations in progress on the device and clear the device table entry for in- terrupt indications. This can normally be done by call of the procedure SETINTERRUPT, which will clear both the device and the device table. If the break cause is not power failure, the reserver must be cleared, hereby releasing the driver e.g. on request from the operator. \f If continued operation on the device is impossible without loss of data, this must be indicated in the answer to the next message received, and the user process must then take care of the error recovery. Continued operation is normally only possible on de- vices, which supports repetition of the previous operation, and can not be done on other devicetypes, as the process state before the break can not be reestablished. 4_._5_._2_ _ _ _ _ _D_e_v_i_c_e_ _h_a_n_d_l_i_n_g_._ 4.5.2 The device handling depends heavily on the actual device, but all synchronization with the device must be achieved by means of in- terrupts, as busy waiting will use too much CPU-time in a multi- programmed system. The devices are normally designed such that interrupts are only requested after the device has been started by the programmer with a S or P pulse. It is a general rule that interrupt requests are awaited only for a maximum device specific time, and if it is not received within this time, the status timeout is indicated and the device is cleared to prevent an interrupt after the timeout (procedure SETINTERRUPT). The normal procedure for device handling is then: \f . ; SETUP DEVICE PARAMETERS . . ; . ; NIOS DEVNO ; START (DEVNO) ; LDA 1 .10 ; LDA 2 .DEVNO ; WAITINTERRUPT ; WAITINTERRUPT (DEVNO, ; 10*20 ms) JMP TIMO ; +0: GOTO TIMEOUT . ; . .DEVNO: DEVNO ; ; TIMEOUT: TIMO: SETINTERRUPT ; SETINTERRUPT (DEVNO) LDA 0 STIMER ; STATUS:= TIMEOUT; . . . . Example 17 4_._6_ _ _ _ _ _ _ _D_r_i_v_e_r_ _I_n_c_a_r_n_a_t_i_o_n_s_._ 4.6 If a number of devices of the same type are connected to the sys- tem, the code to handle the devices will only differ on few points. To save memory space, the driver for the first incarna- tion can be coded reentrant, which means that other incarnations of the same driver need only to be the process descriptor execu- ting the same code as the first driver. The driver can be coded reentrant if all device specific varia- bles, constants and instructions are fetched relative to the pro-\f cess description, and placed in the process descriptor following the words used by the utility procedures. This can be seen in example 18. (Note that I/O instructions must also be placed in the process descriptor, as the device number is an integral part of the instruction). The connection of a second process description to the program in question can be done using a small program, which searches in the program chain for the reentrant program and, when found, reas- signs the process break address, interrupt procedure address and jumps to the program start. Appendix D contains as an example a listing of the paper tape punch driver and the second paper tape punch driver. \f Example 18 Process incarnations. \f 5_._ _ _ _ _ _ _ _ _B_A_S_I_C_ _I_/_O_ _H_A_N_D_L_I_N_G_._ 5. 5_._1_ _ _ _ _ _ _ _G_e_n_e_r_a_l_ _D_e_s_c_r_i_p_t_i_o_n_._ 5.1 The I/O operations in the MUS system is based on dedicated device handling processes, called drivers. All user requests for operations on a specific device are trans- ferred to the corresponding driver process by means of the funda- mental monitor functions SENDMESSAGE and WAITANSWER. As previous described, the information to the driver is transferred in a mes- sage buffer containing 4 16 bits words, which is interpreted by the driver process. In order to ease the use of the driver process and to simplify the possibility of using multibuffered input/output, a number of reentrant I/O procedures have been included in the MUS-system. The procedures work on a data structure called z_o_n_e_ or f_i_l_e_d_e_- s_c_r_i_p_t_o_r_. The fundamental concept that all communication is done by means of messages, is not broken, and the basic I/O procedures must be viewed as the first level on top of the monitor functions. Correspondingly, the character and record input/output procedures are the next level on top of the basic I/O procedures. \f Fig. 16 The procedure hierarchy in the MUS system. It is then possible for the user to build his own dedicated pro- cedures at all levels over the monitor functions, if the offered procedures do not fit the actual usage. All MUS high level procedures work on a zone, which is a collec- tion of information and data buffers, normally pointed out by the programmer by its wordaddress. The zone contains three parts: 1) T_h_e_ _z_o_n_e_ _d_e_s_c_r_i_p_t_o_r_ It contains informations about the document and the device that holds it. It holds furthermore information concerning the data accessible to the user, i.e. the storage area which\f is not involved in device input/output and thus can be fetched or filled by the program. 2) T_h_e_ _s_h_a_r_e_ _d_e_s_c_r_i_p_t_o_r_s_ The share descriptor holds information about the data buffer associated with it, and the state of data, i.e. if the data is or has been processed by the driver. It holds moreover a copy of the message, which requested the data transfer, conse- quently repetition of the transfer is possible if it was re- jected because of an error. 3) T_h_e_ _b_u_f_f_e_r_ _a_r_e_a_ The area from/to which the actual data transfer is done by the driver on request from the I/O procedures. \f The memory layout of a zone with two shares is then: Fig. 17 \f On fig. 17 the following references can be seen: 1) In the file descriptor a pointer to the share involved in user I/O. The pointer is updated by the I/O procedures. 2) In the share descriptor a pointer to the data buffer connected to the share descriptor. The pointer is static. 3) The share descriptors are linked cyclically. In this way the next share descriptor and its associated data buffer can be selected by the pointer mentioned in 1), when the data buffer has been filled with data and a message has been sent to the driver requesting the transfer to the document. The pointers are static. 5_._2_ _ _ _ _ _ _ _Z_o_n_e_ _f_o_r_m_a_t_._ 5.2 The zone is in all procedure calls identified by the word add- ress of its first location, and the words in the zone descriptor can be fetched by the user by means of this address and the dis- placements below recognized by the assembler: ZNAME The document name (drivername) 6 characters, 3 words. This process will receive all messages generated by the I/O procedures. SIZE Size of zone descriptor area. ZMODE The operation. This word is used as operation code in all transput messages to the driver. All central procedures transfer the first byte of this word as the first byte in the operation code to the driver. \f If the last two bits are equal to 11 the operation is output. If the are equal to 01 the operation is input. The word is set by the procedure OPEN. ZKIND The kind used for errorhandling and initialization actions (see later). ZMASK The giveupmask. This mask is compared with the status received from the driver. If common bits are set, the defined giveup pro- cedure is called. ZGIVE The address of the user giveup procedure. The procedure is called, if an error is returned and the errorbit is present in the giveupmask ZFILE Used for file position with some document kinds. ZBLOCK Used for block position with some document kinds. ZCONV Conversion table address. This address is transferred to the driver in an OPEN call. ZBUFF Buffer address. Used by MUSIL interpreter. ZSIZE Size of buffer. Used by MUSIL interpreter. ZFORM Format code for records. Used by Record I/O procedures. ZLENG Length of current record. \f Used by Record I/O procedures. ZFIRS First of record. Used by record and Character I/O procedures. The byte address of the first byte in the current record. ZTOP Top of record. Byteaddress of the first byte after the current record. ZUSED Used share. Word address of the currently used share descriptor. See fig. 17. ZSHAR Share length. The number of bytes in each data buffer. ZREM The number of bytes in the current data buffer not yet processed, or the number of bytes left in the data buf- fer to output. Z0 Status. The status returned on the last checked transfer. O_n_l_y_ _ d_e_f_i_n_e_d_ _i_n_ _t_h_e_ _g_i_v_e_u_p_ _p_r_o_c_e_d_u_r_e_. The zone contains a number of auxiliary words, exclusively used by the procedures. The number of these are given by the assembly constant ZAUX, which also includes the above mentioned Z0 word. The total size of a standard zone descriptor is given by the\f assembly constant Z. 5_._3_ _ _ _ _ _ _ _S_h_a_r_e_ _D_e_s_c_r_i_p_t_o_r_ _F_o_r_m_a_t_._ 5.3 A share descriptor is identified by the word address of its first location. The share descriptor of the current share can be found in the zone descriptor word ZUSED. The share state can then be found as: ; AC2 = zone address LDA 3 ZUSED,2 ; LDA 0 SSTAT,3 ; SOPER Operation to the driver MESS0 in the message generated SCOUN Number of bytes transferred MESS1 in the message generated SADDR Address of the data buffer MESS2 in the message generated SSPEC Special MESS3 in the message generated These four words are used as the message to the docu- ment and are unaltered when the answer is received. In this way it is possible to repeat the operation if the transfer was unsuccessful. SNEXT Next share The wordaddress of the next share descriptor. All share descriptors are linked cyclically. \f SSTAT State of share Value 0 The data buffer can be used. '0 The data buffer is involved in transfer to the device. The word contains the address of the message buffer carrying the transfer re- quest. SFIRS First byte address. The byte address of the first byte in the associated data buffer. The address is transferred to ZTOP in zone descriptor, when the next share is made available to the user after input of data or before output of data. The size of the standard share descriptor can be found as the standard assembler constant SSIZE. \f * ZNAME SIZE ZMODE ZKIND * ZMASK * ZGIVE * ZFILE ZBLOCK ZCONV * Z ZBUFF ZSIZE ZFORM * ZLENG ZFIRS ZTOP ZUSED * word address of current sharede- ZSHAR * scriptor ZREM ZAUX Fig. 18 zone layout. All words marked with * must be set by the programmer before use. \f SOPER SCOUNT SADDR SSIZE SSPEC SNEXT * wordaddress of next share descriptor. SSTAT=0 * SFIRS * byte address of first data byte Fig. 19 share descriptor layout. All words marked with * must be set by the programmer before use. 5_._4_ _ _ _ _ _ _ _Z_o_n_e_ _S_e_t_u_p_._ 5.4 When the zone data structure is used in the assembler, a number of words in the zone descriptor and share descriptor must be pre- defined by the programmer. 5_._4_._1_ _ _ _ _ _Z_o_n_e_ _D_e_s_c_r_i_p_t_o_r_._ 5.4.1 The document name must be initialized. The kind must be set. (See chapter 5.5) The giveupmask must be set. The giveupprocedure address must be defined. The conversion table must be defined as a byteaddress (0 if no conversion). The record format must be defined. (see chapter 6.) The record length must be defined if fixedlength formats are going to be used. The address of the used share descriptor must be defined. The share length (data buffer size) must be set as a number of bytes. \f 5_._4_._2_ _ _ _ _ _S_h_a_r_e_ _D_e_s_c_r_i_p_t_o_r_._ 5.4.2 All sharedescriptors must be linked cyclically in the words SNEXT. Sharedescriptor status must be set to 0. The first byte in the associated data buffer must be set in the sharedescriptor word SFIRS. 5_._4_._3_ _ _ _ _ _M_e_s_s_a_g_e_ _B_u_f_f_e_r_ _P_o_o_l_ _S_i_z_e_._ 5.4.3 A number of message buffers must be set up too. If the process uses n zones, each with NDdiUu shares, the number of message buffers must be 1+ 0UUUnDDDDDD5i=1UUU (NDdiUu-1) This number is sufficient if all I/O is done with the Basic I/O procedures. Else all user generated messages must be added. If the zones are used in a coroutine environment (see 3), the number af message buffers must be 0UUUnDDDDDD5i=1UUU NDdiUu \f T0001: ; LIST ZONE DESCRIPTOR .TXT .<LPT 0'. ; NAME T0061-T0001 ; SIZE 0 ; MODE 1 ; KIND .RDX 2 1110001111111110 ; MASK .RDX 10 P0099 ; GIVEUP 0 ; FILE 1 ; BLOCK 0 ; CONVERSION T0061 ; BUFFER T0069-T0061 ; SIZE OF BUFFER 0 ; FORMAT 0 ; LENGTH T0062 ; FIRST T0062 ; TOP T0061 ; USED SHARE 512 ; SHARE LENGTH 512 ; REMAINING .BLK ZAUX ; AUXILIARY T0061: ;LIST SHARE DESCRIPTOR 0 ; OPERATION 0 ; COUNT 0 ; ADDRESS 0 ; SPECIAL T0061 ; NEXT SHARE 0 ; STATE T0062 ; FIRST SHARED T0062= .*2 ;FIRST SHARED: .BLK 512/2 ; MAKE ROOM FOR SHARE T0069: ;TOP OF BUFFER: Example 19. \f 5_._5_ _ _ _ _ _ _ _D_o_c_u_m_e_n_t_ _i_d_e_n_t_i_f_i_c_a_t_i_o_n_._ 5.5 A document is a physical medium, which is able to contain data and which is mounted on a device. In the zone descriptor, the document in question is described by: 1) The name of the driver process, which controls the device. 2) The mode, which describes the operation requested at the dri- ver when data is transferred to the document. E.g. if charac- ters should be output with or without parity check informa- tion. 3) The kind of the device. An array of bits, which describes, how transfer errors should be handled and special actions on each transfer or control operation. The following bits are at present defined: Bit 15: c_h_a_r_a_c_t_e_r_ _o_r_i_e_n_t_e_d_ Set if the device transfers characters one by one. If an error is returned before output of the whole data block and the transfer is re- peated in the users giveup procedure, only the characters not yet output are requested to be transferred. Examples are papertape punches and lineprinters used in unformatted mode. \f bit 14: B_l_o_c_k_ _O_r_i_e_n_t_e_d_._ Used, if the datablocks are transferred as a unit to/from the device. If repetition is ne- cessary, the whole block must be transferred again. Examples are cardreaders and punches, magne- tic tapes, discs and line printers used in formatted mode. bit 13: P_o_s_i_t_i_o_n_a_b_l_e_._ Set, if positioning has any effect. Must be set, if the document has to be repositioned before a datatransfer is repeated. Examples: magnetic tapes and discs. bit 12: R_e_p_e_a_t_a_b_l_e_._ Set, if automatic repetition can be performed by the system on special status bits. Examples: magnetic tapes and discs. bit 11: C_a_t_a_l_o_g_ _f_i_l_e_._ Must be set, if the filesystem is used. Auto- matic creation and removal of catalog area processes is performed and any input/output is requested with 512 bytes buffer size. (See chapter 8). bit 0: C_o_r_o_u_t_i_n_e_ _b_i_t_._ Set, if the process uses the RC 3600 Corou- tine Monitor (see 3). Call of Basic I/O procedures will not delay the whole process but only the calling coroutine by a call of\f the procedure CWANSWER. 5_._6_ _ _ _ _ _ _ _E_x_c_e_p_t_i_o_n_ _H_a_n_d_l_i_n_g_._ 5.6 In the input/output procedures the user may select certain status bits which, if set in the answer to a message to the driver, will transfer control to a user defined procedure. Before the user procedure is called, a number of automatic error recovery actions are performed, depending on the zone kind. The statusbits returned from the driver are interpreted as: name error type bit 0 disconnected hard error bit 1 offline hard error bit 2 device busy repeat error bit 3 device bit 1 informative bit 4 device bit 2 informative bit 5 device bit 3 informative bit 6 illegal hard error bit 7 end of file hard error bit 8 block length error hard error bit 9 data late repeat error bit 10 parity error repeat error bit 11 end medium hard error bil 12 position error hard error bit 13 driver missing hard error bit 14 timeout hard error If the error is classified as a repeat error and the zone kind is repeatable, the operation is repeated up to 5 times, before the users giveup procedure is called. If the kind word has the posi- tionable bit set, the position is adjusted to the file count specified in ZFILE and the blocknumber ZBLOCK-1 before the\f repetition is performed. When repetition takes place, the whole data block is requested to be input/output again, but if the kind is characteroriented, only the part of the buffer not yet output is requested to be trans- ferred. An operation is repeated a maximum of 5 times. If it is still erroneous, it is classified as having a hard error. When a hard error is detected, the users giveup mask is compared with the status received. If one of the hard error bits present in status is not set in the giveup mask, the process is breaked with errorcode = 5, and the status in accumulator 1. If however the giveup mask bit 15 is set, the giveup procedure is called unconditionally. After the standard check, the status is compared with the user giveup mask. If any bits are common, the giveup procedure is called. 5_._6_._1_ _ _ _ _ _U_s_e_r_ _G_i_v_e_u_p_._ 5.6.1 call return (normal return, repeat share) AC0 - - AC1 status status AC2 zone zone AC3 return address return address The Z0 word in the zone is the status of the call. The ZREM word is the actual number of bytes input or the share- length, if the operation was output. The ZTOP word contains the byteaddress of the first byte trans-\f ferred. Depending on the giveup action, return can take place in three different ways: 1) A jump to the main program. The error is accepted and the transfer is unsuccessful. 2) Return to the given return address. The error is accepted and the transfer is unsuccessful. Return is made to the procedure which caused the transfer. Pleace note that character and record I/O procedures will not return with zero bytes transferred, i.e. the procedure call is repeated until any bytes have been transferred, and this can easily cause loops in the program. 3) The operation can be repeated by a jump to the repeataction. This is done with the predefined instruction .REPEATSHARE. Please note that if the repetition of the operation is suc- cessful, the final return is made to the procedure which caused the faulty transfer. I/O effecting procedures on the same zone must not be called in the giveup action, if return to the calling I/O procedure is wanted by means of .REPEATSHARE or via the given return address. When the basic procedures handle an answer, the status word is augmented with the following bits: bit 13: Set, if the receiver process is not loaded. bit 13: Set, if a control operation with command (14:15) = 10 is checked. 5.7.2\f 5_._6_._2_ _ _ _ _ _G_i_v_e_u_p_ _P_r_o_c_e_d_u_r_e_ _E_x_a_m_p_l_e_._ 5.6.2 The giveup procedure is used with a zone, to which input is made by the INCHAR procedure. Errors indicating end of file or end of medium are converted to input of the character EM (25): GIVE: LDA 0 ZREM,2 ; IF ZONE.ZREM '0 THEN MOV 0,0 SZR ; RETURN JMP +0,3 ; LDA 0 EMSTAT ; IF STATUS AND 1b7+1b11 AND 1,0 SNR ; '0 THEN JMP HARDERROR ;BEGIN STA 3 LINK ; STA 2 ZONE ; PUTBYTE (EM,ZONE.ZTOP); LDA 1 ZTOP,2 ; LDA 0 .EM ; PUTBYTE ; LDA 0 .1 ; ZONE.ZREM:=1; LDA 2 ZONE ; STA 0 ZREM,2 ; STATUS:=0; LDA 3 LINK ; SUB 1,1 ; RETURN; JMP +0,3 ; END; HARDER: . . LINK: 0 ; SAVE LINK ZONE: 0 ; SAVE ZONE EMSTAT: 1b7+1b11 ; EOF, EM STATUS .EM: 25 ; CHARACTER EM 5_._7_ _ _ _ _ _ _ _R_e_p_e_a_t_ _A_c_t_i_o_n_s_._ 5.7 When a driver returns a harderror, it enters a reject state, in which all transput messages are returned with the non-processed status (1b15). This state is only changed, if a control operation is received. The basic I/O procedures will repeat a message with\f the nonprocessed status automatically after a harderror status. These procedures concerning harderrors, guaranties that the right sequence of messages is maintained in the drivers event queue. As an example, see the following drawings of multibuffered error recovery: E_R_R_O_R_ _I_S_ _D_E_T_E_C_T_E_D_ _A_T_ _T_H_E_ _D_R_I_V_E_R_ \f A_F_T_E_R_ _E_R_R_O_R_ E_R_R_O_R_ _R_E_C_O_V_E_R_Y_ \f D_E_V_I_C_E_ _R_E_A_D_Y_ Fig. 20. 5_._8_ _ _ _ _ _ _ _B_a_s_i_c_ _I_/_O_ _P_r_o_c_e_d_u_r_e_s_._ 5.8 The basic I/O procedure calls are predefined in the system assembler. The procedures are thus called by their names, and the return address is then given by the CPU in AC3. If procedures must be called with another return address, the same names can be used with a leading character >.> \f Example: N_o_r_m_a_l_ _u_s_e_:_ LDA 0 .3 ; LDA 2 ZONE ; OPEN ; ; RETURN HERE S_p_e_c_i_a_l_ _u_s_e_:_ LDA 0 .3 ; LDA 2 ZONE ; LDA 3 RETAD ; .OPEN ; RETAD: LABLE . . . LABLE: ; RETURN HERE When basic I/O transfer procedures return, the following values have been updated: ZBLOCK is set equal to MESS3 of the answer if the zone is set to be positionable and if status '1b6, 1b13 and 1b15. If the zone is not defined to be positionable, ZBLOCK is incremented with one for each block successfully input/output. ZFILE is set equal to MESS2 of the answer if the zone is set to be positionable and the status '1b6, 1b13 and 1b15. \f ZREM if the mode is input, ZREM is set equal to the number of bytes input or, if mode is output, equal to ZSHAREL. ZTOP is set to the byteaddress of the first byte in the cur- rent data buffer. The address is fetched from SFIRST in the used share. 5_._8_._1_ _ _ _ _ _I_n_i_t_i_a_l_i_z_a_t_i_o_n_ _P_r_o_c_e_d_u_r_e_s_._ 5.8.1 5_._8_._1_._1_ _ _ _P_r_o_c_e_d_u_r_e_ _O_P_E_N_._ 5.8.1.1 Call return AC0 operation destroyed AC1 - destroyed AC2 zone zone AC3 - destroyed The operation is placed in the modeword (ZMODE) of the zone de- scriptor. The remaining bytes of the zone (ZREM) is initialized either to zero, if the operation is input, or to sharelength (ZSHAREL) if operation is output. The top of the zone points to the first byte in the data buffer. To initialize the transfer, a control message is sent to the pro- cess specified by ZNAME. The message requests reservation and conversion. \f Message generated: MESS0 ZMODE (0:7) 14Dd8Uu MESS1 ' 0 MESS2 ZCONV MESS3 - 5_._8_._1_._2_ _ _ _P_r_o_c_e_d_u_r_e_ _S_E_T_P_O_S_I_T_I_O_N_._ 5.8.1.2 Call Return AC0 block destroyed AC1 file destroyed AC2 zone zone AC3 - destroyed This procedure first waits for all transfers by means of the pro- cedure WAITZONE. Then a position message is sent to the process with the name given in ZNAME. ZREM and ZTOP are defined as for OPEN. Message generated: MESS0 ZMODE(0:7) 40Dd8Uu MESS1 - MESS2 FILE MESS3 BLOCK \f 5_._8_._1_._3_ _ _ _P_r_o_c_e_d_u_r_e_ _W_A_I_T_Z_O_N_E_._ 5.8.1.3 Call Return AC0 - unchanged AC1 - unchanged AC2 zone zone AC3 - destroyed Terminates the current activities of the zone. If the zone is opened for output, the last block is output as if OUTBLOCK was called, and then all pending transfers are awaited and checked, i.e. the giveupprocedure may be called. If the zone is opened for input, all transfers are awaited, but not checked. If the last block is output, the message generated is: MESS0 ZMODE MESS1 ZSHAREL - ZREM**ZSHAREL if MESS2 ZUSED.SFIRSTZKIND(11)=1 MESS3 ZBLOCK ZREM and ZTOP are defined as for OPEN. 5_._8_._1_._4_ _ _ _P_r_o_c_e_d_u_r_e_ _C_L_O_S_E_._ 5.8.1.4 Call Return AC0 - destroyed AC1 release destroyed AC2 zone zone AC3 - destroyed The zone is first set neutral by means of WAITZONE. \f If the zone is opened for output, a termination, and if >release> is nonzero also a release-reservation and disconnection control message is sent to the process with the name given in ZNAME. If the zone is opened for input, a sense, and if >release> is nonzero a release-reservation and disconnection control message is sent. ZMODE is then set to zero and the control message is awaited an- swered by the WAITZONE procedure. \f Message generated: MESS0 ZMODE(0:7) OP MESS1 0 MESS2 - MESS3 ZBLOCK OP is specified in the table above. All zonepointers and values are undefined. Example: LDA 2 ZONE ; LDA 0 .3 ; OPEN ; OPEN(ZONE 3); LOOP: LDA 0 BLOCK ; REPEAT LDA 1 FILE ; SETPOSITION(ZONE,FILE, ; BLOCK); SETPOSITION ; . ; DATA PROCESSING . ; ; FILE:=FILE+1; SUB 1,1 ; CLOSE ; CLOSE(ZONE,FALSE); LDA 0 .3 ; OPEN(ZONE, 3) OPEN ;UNTIL FILE=10 LDA 0 ZFILE,2 ; STA 0 FILE ; CLOSE(ZONE,TRUE); LDA 1 .10 ; SUB 1,0 SZR ; JMP LOOP ; CLOSE ; Example 20. \f 5_._8_._2_ _ _ _ _ _I_N_P_U_T_/_O_U_T_P_U_T_ _P_r_o_c_e_d_u_r_e_s_._ 5.8.2 5_._8_._2_._1_ _ _ _P_r_o_c_e_d_u_r_e_ _T_R_A_N_S_F_E_R_._ 5.8.2.1 Call Return AC0 operation destroyed AC1 length destroyed AC2 zone zone AC3 - destroyed Initiates a transfer operation given by >operation> and with bytecount >length> to/from the databuffer pointed to by the used sharedescriptor. After a call, the state of the sharedescriptor is set to the ad- dress of the messagebuffer, which was sent to the process given by ZNAME. The used share is updated to the next sharedescriptor in the sharedescriptor chain. The procedure does not check the state of the currently used share. If the state is nonzero, the messagebuffer address saved is lost and the message buffer is never released for use. Message generated: MESS0 operation MESS1 length MESS2 ZUSED.SFIRST MESS3 ZBLOCK All zone pointers and values are undefined. \f 5_._8_._2_._2_ _ _ _P_r_o_c_e_d_u_r_e_ _W_A_I_T_T_R_A_N_S_F_E_R_._ 5.8.2.2 Call Return AC0 - destroyed AC1 - destroyed AC2 zone zone AC3 - destroyed If state in the used sharedescriptor is free the procedure re- turns immidiately, otherwise it waits for an answer to the mes- sage placed in the message buffer given by state and when the an- swer is received, it sets the state to zero (free). When the answer arrives, the status is checked as described in Exception Handling and the user giveup procedure can then be called. After return, the pointers are updated as: If a repetition of the message is generated, either by the user or by the system, the message sent is: \f ZMODE(0:7) OP - ZFILE ZBLOCK OP = +1b10 (position) if ZKIND (13) = 1 +1b8 (erasure) if status (10) = 1 (parity) and zone is opened for output. Example: The procedure INBLOCK can only be coded with the fundamental pro- cedures TRANSFER and WAITTRANSFER. All data buffers are sent to the input driver and then the first one sent is awaited. ANEXT: LDA 3 ZUSED,2 ; LDA 3 SSTATE,3 ; WHILE ZONE.USED.STATE ; = 0 DO MOV 3,3 SZR ; JMP AWAIT ; LDA 0 ZMODE,2 ; TRANSFER (ZONE,ZSHAREL, ; ZMODE); LDA 1 ZSHAREL,2 ; TRANSFER ; JMP ANEXT ; AWAIT: WAITTRANSFER ; WAITTRANSFER (ZONE); 5_._8_._2_._3_ _ _ _P_r_o_c_e_d_u_r_e_ _I_N_B_L_O_C_K_._ 5.8.2.3 Call Return AC0 - destroyed AC1 - destroyed AC2 zone zone Ac3 - destroyed \f Administrates the basic cyclic buffering strategy for input pro- cedures like INCHAR and GETREC. The databuffers are represented by circles. INBLOCK starts the transfer of 1, 2 and 3. Then it waits for buffer 1, after which the data is ready for processing. The second call will request transfer to buffer 1 and wait for 2. After return ZREM and ZTOP are defined as: \f The messages generated are: MESS0 ZMODE MESS1 ZSHARE MESS2 ZUSED.SFIRST MESS3 ZBLOCK 5_._8_._2_._4_ _ _ _P_r_o_c_e_d_u_r_e_ _O_U_T_B_L_O_C_K_._ 5.8.2.4 Call Return AC0 - destroyed AC1 - destroyed AC2 zone zone AC3 - - Administrates the basic cyclic buffering of output. At first, buffer 1 is filled with output and after a call of OUT- BLOCK, the first buffer is sent for processing. Buffer 2 is then ready to be filled. When buffer 1 is reached again, the answer is awaited and checked before the data buffer is ready to receive data again. \f The message generated is: ZMODE ZSHAREL - ZREM* *ZSHAREL if ZKIND(11)=1 ZUSED.SFIRST ZBLOCK After return, ZREM and ZTOP are defined as: \f \f «eof»