|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 75264 (0x12600) Types: TextFile Names: »codemaninp«, »tramosinp«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt. └─⟦0364f57e3⟧ └─⟦185aba3e6⟧ »libman« └─⟦this⟧ └─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ. └─⟦4334b4c0b⟧ └─⟦this⟧ »tramosinp« └─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦845422199⟧ »libman« └─⟦this⟧
lookup codeman if ok.yes (scope temp codeman clear temp codeman ) codeman=set 100 scope user codeman codeman=compose *se#* #pl 297,15,260,0,0# #lw 190# #ld12# #pn 0,0# #ps 0# #sj# #lm 0# Computer Departement #0010#H.C.Ørsted Institute Universitetsparken 5 DK-2100 København Ø #nl##ct# HCØ RC8000 algol8 library External slang coded algolprocedures for processcontrol and operating systems #nl2# Anders Lindgård "codeman" #nl5# #0020##lm 80# report 80-02 #lm0# #pn 5,0# #rj# #ps 0# Copyright 1980 Anders Lindgård. For the time being this procedure set can be used freely for research or other nonprofit purposes. Any other use demands written permission from the author. #ps 0##ct# #0030# #0030#external slang coded algol procedures for processcontrol and operating systems. ========================================= #rj# #ns 1,3,Historical note# #nl##np# In november 1970 an RC4000 computer was put in operation at the H.C.Ørsted Institute. It was the intention to use the computer simultaniously as a process control computer and as a conventional #0040#batch/on line computer. At the time of delivery no operating system existed whitch could fulfill these requirements, except by using the computer in a full time sharing mode with the different programs running in different part of the fast direct access store. For economic reasons the process control programs had to be very small and had to be written in assembler language. Since one of the greatest advantages of using a computer for control of experimental equipment, instead of #0050#building the nescesary hardware is the possibility of easy change in measuring and control strategy, it was considered more convenient to write the process control programs in a higher programming language as algol 6. Two things were nessesary to make this feasible. A special operating system, and some extensions to the existing algol system. After some considerations of the problems involved, we decided that the operating system was just as essential for the process #0060#control purposes as the process control programs themselves, and possibilities for easy strategy change would be very convenient here too. We then decided to extend the algol system in such a way that it would be possible to write both the operating system and the process control programs in algol. These considerations were partly based on some experience with a very simple swopping operating system developed by L.Svalgård for the Meteorological Institute. #0070#This is by no means the perfect operating system for processcontrol but it gave us the possibility to write most of our programs in algol. This has speeded our programming up enormously. #nl##np# The algol system from Regnecentralen is a very nice system for normal use but not really intended for writing operating systems or processcontrol- programs. It is the zone concept which makes all the trouble. It is very elegant to use #0080#zones when using printers,backing store, typewriters, cardreaders etc. either block ori- ented or character oriented. But when designing or developing operating systems or using simple devices as D/A-A/D-converters, digital registers, counters etc. it is indeed very slow and clumsy. We then decided to extend the algol system with procedures with the following scope: #sj# 1) Make the handling of simple devices modular, #0090# faster and more elegant. 2) Make the catalog handling more direct. 3) Give possibilities for using addresses. 4) Make it simple to read in the monitor tables (and write if you are allowed to do it). 5) Make it possible to make a swopping process- control operating system in algol. 6) Make the bitmanipulation of integers simpler. 7) Make monitorprocedures accessible to an algol program with formats very close to #0100# the formats of ref. 2. 8) Make the monitor calls faster. 9) Make it possible and easy to use the fileprocessor procedures of ref. 3. #rj# #ns 1,3,The procedures# #nl##np# The procedures can be regarded as an extension of the algol 7 system. The description is written as an extension of chapter 9 in the algol 7 manual #0110#(ref 1). Later descriptions vil be made in the same format. #np# The procedures can be considered translated with index.no. This is due to speed-up considerations for processcontrol. You should be very concerned about making arrays large enough, else the fate of your program is unpredictable. #np# Some of the procedures are not intended to be used #0120#by normal algol users. If you are not a systems programmer avoid the use of the hardwaretest procedures. The reaction to an illegetemate use is normally a break, but any reaction may occur. #nl2##np# The procedures have some very special features which are not found in normal algol procedures. #ns 1,2,The parameter name.# #nl##np# This is normally specified: #0130##nl# string or integer or <any type> array #nl# That is to say that either a string or integer or an array can be used in the call. The array can have any type (boolean, integer, real or long) and must have at least 8 (10) bytes of core and the name must be placed in the first part. The unused part of the 8 bytes must be zero. If you are using an integer this is assumed to #0140#be a process description address. In that case the integer is used as byte 8-9 in the name area in the call of send message. #cm(At HCØ the monitor procedure send message is modified to utilize this).# In all the procedures where you can use a process description address it is not checked that it really is one. You might utilize this if you note that a process description address points to the word preceding the name. However in the case of send message a true process description address should be #0150#used. If not your program is sloved down. NOTE that in case of send message or a procedure using the monitor procedure send message an array as name must have 10 bytes, because the monitorprocedure send message stores the name table entry in byte 8-9.#cm At HCØ you can have the same speed up as with the name table entry by using the process descrip- tion address.# In case of a string the procedure can handle up to 12 letters (a name is less than or equal to 11 #0160#letters) and use it as a name in the monitor call. NB There is one special case where the string mechanism does not work: If you have the construc- tion: #nl# string A(increase(i)) #nl# with the name in the array A and the name has more than 6 letters. There should however be no need for such a construction as you can use an array directly #0170#instead. #ns 1,2,Other parameters# #nl##np# Nearly all integer parameters demands strict type agreement. This is checked at compile time. The reason for this restriction is to save computing time, and space on the code procedure segments. It was the feeling of the author that is really has no meaning to use reals as addresses. #ns 1,3,Error situations# #0180##nl##np# Many of the procedures can give a break in case of a parameter error. The normal break situation is break 6 which is parameter error in call of a monitor- procedure or break 0 if you try to store out- side your own core. The running system will then write the string specified as alarm address as errormessage in "called from ". #ns 1,3,Operating systems# #nl##np# #0190# #0190#For operating system purposes some of the procedures exists in two versions. One for normal use and one for using in a central loop. All those considered nessesary for a central loop are placed on one segment with alarm address: p-proc. Many of them have no parameters but uses standard variables instead. This should speed the procedures up and save space in core for the central loop. #ns 1,3,RC8000 version compared with the RC4000 version# #nl2# #0200#The changes are: #sj# 1. Some procedure has been removed as they are meaningless using the RC8000 monitor. 2. The connect procedure has been changed to include the stacking of the zone. As a consequence stackcuri and stackcuro are removed. 3. The procedure packtext and reservesegm are sligtly modified. 4. The monitor procedure calls are changed to match #0210# the RC8000 monitor 3. 5. Some procedures have changed names due to nameconflict with names of RC-procedures. ref. 1: H. Dinsen Hansen (Editor) Algol 6, users manual (1.ed,2.printing) RCSL 31-D322 Regnecentralen København 1974 ref. 2: Per Brinch Hansen Multiprogramming system (2.ed) Regnecentralen Copenhagen 1971 #0220# #0220#ref. 3: Søren Lauesen File Processor Users Manual Regnecentralen Copenhagen 1969 ref. 4: Anders Lindgård External Slang Coded algolprocedures for procescontrol and operating system rapport 25 Kemisk laboratorium III #0230# Københavns Universitet #ps# Alphabetic list of procedures and variables. #cm desbegin# 1980-04-12 procedure alarm(list); integer alarmterm; integer ba; integer procedure byte_load(addr); integer bytes; #0240# procedure byte_store(addr,byte); #cm integer procedure called_from(skip); # integer procedure c_area_proc(name); #cm procedure catch_buf; # #cm procedure catch_error(P); # integer procedure change_base(name,disp); integer procedure change_tail(name,tail); boolean procedure check_pda(pda); #cm integer procedure clean_buf(pda); # procedure clear_array(a); #0250# procedure clear_stat(name,doc); procedure close_out; integer procedure connect_cur_i(name); integer procedure connect_cur_o(name); integer console; integer procedure copy_zone(buffer_address,first,last); integer coreaddr; integer procedure c_pseudo_proc(name); integer procedure create_entry(name,tail); integer procedure create_int(name,param); #0260#integer procedure create_per(name,device_no); integer procedure description(name); long procedure double_load(addr); procedure double_store(addr,double); #cm procedure dump; # #cm procedure end_program(succes); # #cm integer error_cause; # integer procedure exclude(name,devno); integer procedure first_addr(a); integer from; #0270# #0270#integer procedure gcd(u,v); long procedure gcdl(u,v); integer procedure gen_copy(buffer,param,moved); integer procedure generate_n(A); long procedure get_clock; integer procedure get_event(ba); integer procedure head_and_tail(name,tail); integer procedure inchar_cur; integer procedure include(name,devno); integer procedure include_all(name); #0280#integer procedure init_proc(name,param); integer instacked; integer procedure integer_and(i1,i2); integer procedure integer_exor(i1,i2); integer procedure integer_neg(i); integer procedure integer_or(i1,i2); integer last_used; integer procedure lookup_aux(name,doc,tail); integer procedure lookup_entry(name); integer procedure lookup_tail(name,tail); #0290# #0290#integer messadd; integer procedure modify_int(name,registers); procedure monitorproc(no,w); integer procedure move_b; integer procedure move_bytes(from,to,bytes); integer procedure move_text(addr,s); integer nameentry; procedure nameload(addr,A); procedure outchar_cur(char); procedure outend_cur(char); #0300#integer out_stacked; integer procedure own_descr; procedure packtext(A,source); integer parent; integer pda; integer procedure perm_aux(name,doc,key); integer procedure perm_entry(name,key); integer procedure proc_id_bit(idbit); integer procedure program; procedure redef_array(A,first,elements); #0310#integer procedure regret_mess(buf); #cm procedure release_per; # procedure release_proc(name); integer procedure relocate(name,new); integer procedure remove_entry(name); integer procedure remove_proc(name); integer procedure rename_entry(old,new); integer procedure reserveproc(name,param); integer procedure reserve_segm(name,segm); integer result; #0320##cm procedure return_rs; # integer procedure rs_table; integer procedure scope_login(name); integer procedure scope_pro(name); integer procedure scope_temp(name); integer procedure scope_user(name); procedure send_a; procedure send_answer(result,ba,answer); integer procedure send_m; integer procedure send_message(name,mess); #0330#integer procedure send_mess_id(name,id,M); integer procedure set_bit(word,bitno.bitvalue); integer procedure set_bs_claim(name,doc,claimlist); integer procedure set_cat_base(name,lower_base,upper_base); integer procedure set_en_base(name,lower_base,upper_base); integer procedure set_prio(name,level); integer procedure short_load(addr); integer procedure start_i; integer procedure start_int(name); integer procedure stop_i; #0340#integer procedure stop_int(name,result); boolean procedure test_bit(word,bitno); integer procedure test_event(last_buffer,event_id); integer to; integer trap_base; procedure unstack_cur_i; procedure unstack_cur_o; procedure wait(sec); integer procedure wait_a; integer procedure wait_answer(ba,answer); #0350#integer procedure wait_event(ba); integer procedure wait_message(NAME,result,mess); integer procedure word_l; integer procedure word_load(addr); procedure word_store(addr,word); integer procedure zone_des(z); #cm desend# #ps0# Procedure alarm. 80-04-20 #rj# #0360# #0360#The procedure calls write(out,list) and if the standard integer alarmterm is zero this is followed by a call of the running system procedure general alarm. The number written after ***alarm is blocksread. If alarmterm = 2 then the call of write is also suppressed and the procedure is completely blind. #sj# Call: alarm(list); #0370# #0370# list (call value, general address). One or more parameters. These parameters are evaluated by write. Example: begin integer i; i:=2; alarm(<:wrong value :>,i); end Output: #0380#wrong value 2 ***alarm 7 conproc called from line 4-5 The number following the text ***alarm is blocksread Integer alarmterm 80-04-14 alarmterm controls the effect of the procedure alarm. See above. 0 = termination of program 1 = writing of alarm text only 2 = alarm is blind #0390# #0390# #0390# Integer ba. 25-8-72 The buffer address. Used by the procedures waita and senda. Integer procedure byte_load. 11-3-72 Loads the storage halfword addressed as an unsigned integer and deliver it as the value of the proce- dure. The procedure work exactly as the machineinstruction bz. Call: byte_load(addr); byteload (return value, integer). The #0400# storage byte addressed extended with zeroes to the left. addr (call value, integer). Address of byte. Integer bytes. 25-8-72 Number of bytes to be moved. Must be even. Used by the procedure moveb. Procedure byte_store. 80-04-20 Stores the right halfword of the integer in the storage word addressed. The procedure works excactly as the machine- #0410#instruction hs. Call: half_word_store(addr,byte); addr (call value, integer). The address of the storage halfword to be changed. halfword (call value, integer). The word of which the rigth half is sto- red. #cm Integer procedure called_from. 10.12.75 The purpose of this procedure is to be able to let an algol program trace through the algol stack at any time during a run and find all linenumbers. The procedure goes back in the stack skip levels and find the linenumbers. If the segment found is not a main program segment then the lower line becomes negative. The stack picture is unchanged after the execution of the procedure. Call: calledfrom(skip); calledfrom (return value, integer). The number of the lower line interval. skip (call and return, address integer). The number of levels in the stack theprocedure should go back. At return the negative number of the upper line interval. # Integer procedure c_area_proc. 13-7-72 Makes an area on the backing store avaible as an external process for the calling process. Call: c_area_proc(name); careaproc (return value, integer). The result of the monitor procedure create area process. Zero if area process created. name (call value, string or integer or <any type> array). #0440# The name or process description address of the area. #cm Procedure catch_buf. 11-2-76 A call of this procedure changes some instruction in the algol running system. When the program goes through the termination part of running system a jump to this procedure is performed. All messages in the queue of other processes are regretted if possible else the procedure waits for an answer. After this has been done the normal termination action of running system is performed. Call: catchbuf; # #cm Procedure catch_error 11-2-76 WARNING: Do not use this procedure unless you are familiar with the internal structure of the algol running system. Improper use may cause any reaction. Reports from users telling that it oes not work properly are not accepted. A call of this procedure changes some instructions in the ter- mination part of the algol running system, causing a jump to the user procedure P in the call of catcherror. P is called if a run time error occurs or even when the program terminates though the last end of the program. P may be declared in an inner block as the scope rules of algol do not apply to this procedure. The purpose of catcherror is to make it possible in an easy way to write a more comprehensive epilog procedure than the one performed by running system. It is strictly required that P do not contain any run time errors, else the output from running system is nonsense. Only the first call of catcherror has any effect. The standard integer errorcause (see errorcause) will contain the reason for calling P. To return to the running system termi- nation procedure the procedure returnrs should be used(see returnrs). The action of letting P terminate by going through the final end of P is undefined. Due to the behaviour or running system it is only possible to call P once. Call: catcherror(P); P (call value, procedure). A user procedure for handling the program termination. Example: begin procedure error; begin if errorcause=-10 then returnrs; write(out,<:<10>errorcause :>,errorcause); returnrs; end; catcherror(error); alarm(<:error :>); end # Integer procedure change_base. 80-04-20 #0490# #0490# Changes the address base of a child process. Call: change_base(name,disp); changebase (return value, integer); The result of the monitor procedure change address base. zero means address base changed. name (call value, string or integer or <any type> array). The name or process description address of the child process. disp (call value, integer). The value of disp is added to the address base of the #0500# child and all logical adresses in the child process description are changed accordingly. Integer procedure change_tail. 80-04-12 Changes the tail of an entry in the catalog. Call: change_tail(name,tail); changeentry (return value,integer). The result of the monitor procedure change entry. Zero if entry changed. name (call value,string or integer or <any type> array). The name or process description #0510# address of the entry to be changed. tail (call value,integer array). The new tail. Must have 10 elements. Boolean procedure check_pda. 28-2-73 Checks whether the value of the parameter is a process description address. Call: checkpda(pda); checkpda (return value, boolean). True if the address given is a process description address, otherwise false. #0520# pda (call value, integer). The address to be checked. #cm Integer procedure clean_buf. 2.04.76. The message buffer pool is scanned and those message buffers which has a sender equal to the parameter pda are regretted. For a succesful regret the following must be fulfilled: the calling process must be the parent or the same process which is specified by pda, and not answered messages must be pending on processes which are allowed to regret. Call: cleanbuf(pda); cleanbuf (return value, integer). The returned value means: -1: pda does not decripe an internal process 0: ok, >0: number of unsuccesfully attempt to regret. pda (call value, address integer). The process description address of the internal process of which message buffers should be regretted. When pda = 0 the calling process is assumed. When pda = calling process then the spare message buffer from the Algol-system is not regretted. # Procedure clear_array 13-7-72 Sets every bit in an array equal to zero. Call: clear_array(a); a (call and return value, <any type> array). The array to be cleared #0550# #0550# #0550# Integer procedure clear_stat 80-04-20 Clears the write and read access counters for an entry in an auxillary catalog describing an area entry. Call: clear_stat(name,doc); clearstat (return value, integer). The result of the monitor procedure clear statistics in aux entry. zero if the write and read access counters are cleared. name (call value, string or integer or <any type> array). The name or process description address #0560# of the catalog entry. doc (call value, string or integer or <any type> array). The name or process description address of the document having the auxillary catalog. Procedure close_out 5-6-73 An EM-character (value 25) is written on current output. Furthermore the part of the share filled with characters is output. (See fp- manual page 53). After this the zone is unstacked and the integer outstacked is decrementet by one. Call: closeout; #0570# #0570# #0570# Integer procedure connect_cur_i. 80-04-20 Stack the current input zone and connect current input to a file. The zone state is unchanged. The integer instacked is incre- mented by one. See FP-manual (ref. 3). Call: connectcuri(name); connectcuri (return value,integer). Zero for normal connection otherwise hard error. name (call value, string or <any type> array). The name of the filedescriptor. This must be the #0580# name of a catalog entry (filedescriptor). Integer procedure connect_cur_o. 80-04-20 Stack the current output zone and connect current output to a file. The zone state is unchanged. The integer instacked is incremented by one. See FP-manual (ref. 3). Call: connectcuro(name); connectcuro (return value,integer). Zero for normal connection otherwise hard error. name (call value, string or <any type> array). The #0590# name of the filedescriptor. This must be the name of a catalog entry (filedescriptor). Integer console 80-04-12 #rj# The process description address of parent console. In case of operating system s it is the true console. For other operating systems it is the operating system. #sj# Integer procedure copy_zone 16-3-72 Makes the monitor call copy jd 1<11+70. First #0600#and last must be within calling process. Delivers bytes and chars transferred in first and last. Call: copy_zone(ba,first,last); copyzone (return value, integer). The result of the transfer. As for wait answer. ba (call value, integer). The buffer address. Must be in the queue of the calling process. first (call and return value, integer). #0610# At call time it should be the first address of the area to be copied. It returns with the no of bytes transferred last (call and return value, integer). At call time it should be the last address to be copied. It returns with the no of chars transferred. Integer core_addr. 4-9-72 The address of a storage word. #0620#Used by the procedure word_l. Integer procedure c_pseudo_proc. 80-04-20 Creates a pseudo process with the name specified. The process is created among the area processes and any message to the process will be linked to the queue of the parent with the pseudo process as receiver. The parent is the process creating the pseudo process. Call: cpseudoproc(name); cpseudoproc (return value,integer). The result of the monitor procedure create pseudo process. Zero if process created. #0630# #0630# name (call value,string, integer or <any type> array). The name or process description address. Integer procedure create_entry. 16-3-72 Creates an entry in the catalog with name as name and the array tail as tail part. Call: create_entry(name,tail); createentry (return value, integer). The result of the monitorprocedure. Zero if entry created. name (call value string or integer or <any type> array). #0640# Contains the name or process description address of the entry. tail (call value integer array). Must con- tain the tail of the entry. Should have at least 10 elements. Integer procedure create_int. 30-6-72 Creates an internal process with a given name. Call: create_int(name,param); createint (return value, integer). The result of the monitorprocedure create in- #0650# ternal process. Zero if process created. name (call value, string or integer or <any type> array). The name or process description address of the child process. param (call value, integer array). Should have at least 9 elements. param(1):=first storage address; param(2):=top storage address; param(3):=bufferclaim shift 12 add areaclaim; #0660#param(4):=catalogmask; param(5):=protection _register shift 12 add protection_key; param(6):=max base (lower) param(7):=max base (upper) param(8):=standard base = catalog base(lower) param(9):=standard base = catalog base (upper) Integer procedure create_per. 7-9-72 Creates a peripheral process for a unit having the software device number specified and gives it a name. Normal user programs can only handle magnetic tape stations. #0670# #0670# #0670#Call: create_per(name,dev_no); createper (return value, integer). The result of the monitorprocedure. Zero if process created. name (call value string or integer or <any type> array). Contains the name or process description address of the peripheral process to be created. dev_no (call value, integer). The device number of the peripheral unit. Integer procedure description. 30-5-72 #0680# #0680#Finds the process description address of a process. Call: description(name); description (return value, integer). The result of the monitor procedure process description. Zero if the process was not found else the process description address. name (call value, string or integer or <any type> array). The name or process description address of the process. Long procedure double_load 80-04-12 #0690# #0690#Delivers as result the double word in primary store addressed by addr. Call: double_load(addr); doubleload (return value, long). The double word addressed. addr (call value, integer). Address of the double word to be fetched. Procedure double_store. 30-5-72 Stores the long double as a double word in primary store at address given by addr. Call: double_store(addr,double); #0700# addr (call value, integer). The address in core store where the double word is to be stored. double (call value, double). The double word to be stored. #cm Procedure dump. 28.06.73 This procedure changes some instructions in the algol running system. When the break occurs a primary image is dumped on the backing store in a working area. The name of the area is written on current output by a call of the fp-procedure out- text (See ref. 3). The first 16 bytes of the dump contains: first of dump+ 0: first address of process area + 2: w0 + 4: w1 + 6: w2 + 8: w3 +10: exception register +12: instruction counter +14: interrupt cause. Call: dump; # #cm Procedure end_program. 12-02-73 The program is terminated by an exit to the fileprocessor. The parameter signals whether the execution was succesful. See ref. 3. Call: endprogram(succes); succes (call value, boolean). If the boolean is true the ok-bit in fp is set otherwise it is cleared. # #cm Integer error_cause. 28.06.73 Used in connection with the procedure catch_error. This integer contains the errorcause when a program tries to terminate through the algol running system. If errorcause is positive it points to the address of an alarmtext which which is going to be printed by running system. If negative the meaning of errorcause is: -1: stack alarm -2: index alarm -3: zone alarm (index) -4: case alarm -5: syntax -6: integer fault -7: floating fault -8: param alarm -9: break -10: end (normal termination) -11: bytes -12: field alarm # #0750# #0750# Integer procedure exclude. 18-12-72 Excludes a child process as a user of a device. Call: exclude(name,devno); exclude (return value,integer). The result of the monitor procedure exclude user. name (call value,string or <any type array>). The name or process description address of the child. devno (call value,integer). The number of the device from which the child is excluded as a user. #0760# #0760# Integer procedure first_addr. 30-5-72 Finds the first address of an array if an array is the parameter. The address points to the second byte of the array. In case of a simple variable it finds the address of the variable eg. the byte address for a boolean and an integer. For a real or a long it is the address of the byte preceding the last byte. Call: first_addr(a); firstaddr (return value, integer). The byte address of a corresponding to the internal algol kon- #0770# ventions. a (call value, <any type> variable or <any type> array). The item for which the address is wanted. Integer from. 25-8-72 The first address from where a moving should start. Used by the procedure moveb. Integer procedure gcd. 12.09.73 The greatest common divisor of two integers is found. Special arguments: gcd(0,0) = 0, #0780# gcd(u,0) = abs u, gcd(u,v) = gcd(abs u, abs v) >= 0 for all integers u and v. Call: gcd(u,v); gcd (return value, integer). The greatest common divisor of u and v. u (call value, integer). See above. v (call value, integer). See above. Integer procedure gcdl. 3.12.75 The greatest common divisor of two longs is found. Special arguments: #0790# gcdl(0,0) = 0, gcdl(u,0) = abs u, gcdl(u,v) = gcdl(abs u, abs v) >= 0 for all longs u and v. Call: gcdl(u,v); gcdl (return value, long). The greatest common divisor of u and v. u (call value, long). See above. v (call value, long). See above. Integer procedure gen_copy 80-04-20 The procedure allows the receiver of a message buffer to copy information to or from a buffer area, described in the message buffer. See the monitor procedure general copy jd 1<11+84. Call: gen_copy(buffer,param,moved); gencopy (return value, integer) The result of the monitor procedure general copy. Zero if area copied. param (call value, integer array). See below. Must have at least 4 elements. moved (return value, integer). The number of halfwords moved. param(1):=function param(2):=first address of area in own store param(3):=last address of area in own store param(4):=start relative function:=0000 0000 0000 0000 000x xxxy (binary pattern) where y=0 copy from buffer area to area in own store 1 copy to buffer area from area in own store xxxx=relative position of an adress pair in the buffer. operation is relative zero. Integer procedure generate_n. 29-8-72 Generates a name with the format: wrk<6 digits> , followed #0800#by 3 Null characters. Call: generate_n(A); generaten (return value,integer). The result of the monitor procure generate name. Zero if name generated. A (return value,<any type> array). The gene- rated name is stored in this array. Long procedure get_clock. 30-5-72 Senses the internal clock. Call: get_clock; #0810# getclock (return value, long). The updated value of the clock with unit position 0.1 milli- second. Procedure get_event. 30-5-72 Removes a buffer from the queue of the calling process. If the buffer contains an answer it is released. Call: get_event(ba); ba (call value, integer). Must be a buffer address in the queue of the calling process, or break 6 is performed. #0820# #0820# #0820# #0820# Integer procedure head_and_tail. 28.06.73 Searches the catalog for an entry, and finds the head and tail. Call: headandtail(name,tail); headandtail (return value, integer). The result of the monitor procedure lookup head and tail. Zero if entry looked up. name (call value, string,integer or <any type> array). The name or process description address of the #0830# entry. tail (return value, integer array). The head and the tail of the entry. Must have at least 17 elements. tail wil contain the following information: tail(1)=first slice, namekey*8+permkey tail(2)=lower_base of entry name tail(3)=upper_base of entry name tail(4)=name.1 tail(5)=name.2 #0840#tail(6)=name.3 tail(7)=name.4 tail(8)=size of area(>0) tail(9) to tail(17)=optional parameters tail(8) to tail(17) gives the same information as lookup_tail Integer procedure inchar_cur 80-04-12 One character is read from current input by a call of the file- processor (ref. 3). Call: inchar_cur; inchar_cur (return value, integer). The value of the #0850# character. Integer procedure include. 18-12-72 Includes a child process as a user of a device. Call: include(name,devno); include (return value,integer). The result of the monitor procedure include user. name (call value,string or <any type array>). The name or process description address of the child. devno (call value,integer). The device number. #0860# #0860# #0860# #0860# Procedure include_all. 26-6-72 Includes a child process as a user of all devices. Call: include_all(name); name (call value, string or integer or <any type> array). The name or process description address of the child process. Integer procedure init_proc. 26-6-72 Initializes a process with a given name. The integer param has only significanse for HCØ digital outputs. Call: init_proc(name,param); #0870# initproc (return value, integer). The result of the monitorprocedure initialize process. Zero if process initialized. name (call value, string or integer or <any type> array). The name or process description address of the process. param (call value, integer). Only relevant for HCØ digital outputs, where it should be the key. Integer instacked 80-04-20 Used by connectcuri which increases instacked by one each time called and by unstackcuri which decreases instacked by one each time called. Integer procedure integer_and. 26-6-72 The result is a bit for bit logical and operation of two integer words. Call: integer_and(i1,i2); #0880# integerand (return value, integer). The result of a logical and of i1 and i2. i1 (call value, integer). i2 (call value, integer). Integer procedure integer_exor. 7-11-72 The result is a logical exclusive or operation of two integer words. Call: integer_exor(i1,i2); integerexor (return value,integer). The result of a logical exclusive or of i1 and i2. #0890# i1 (call value,integer). i2 (cal value,integer). Integer procedure integer_neg. 5-6-72 The result is a logical negation of an integer word. Call: integer_neg(i); integerneg (return value, integer). The result of a logical negation of i. i (call value, integer). Integer procedure integer_or. 7-9-72 The result is a logical or operation of #0900#two integer words. Call: integer_or(i1,i2); integeror (return value,integer). The result of a logical or of i1 and i2. i1 (call value,integer). i2 (call value,integer). Integer last_used 80-04-20 The running system entry last used. Integer procedure lookup_aux 80-04-20 Looks up an entry in the auxillary catalog specified. Cf. lookup_entry. Call: lookup_aux(name,doc,tail); lookupaux (return value, integer). The result of the monitor procedure lookup aux entry. Zero if entry looked up. name (call value, string or <any type> array. The name or process description address of the entry. doc (call value, string or <any type> array. The name or process description address of the document. tail (return value, integer array). The tail of the entry. At least 10 elements. Integer procedure lookup_entry 5-6-72 Searches the catalog for an entry. Call: lookup_entry(name); lookupentry (return value, integer). The result of the #0910# monitorprocedure lookup entry. Zero if entry looked up. name (call value, string or integer or <any type> array). The name or process description address of the entry. Integer procedure lookup_tail. 5-6-72 Searches the catalog for an entry, and finds the tail. Call: lookup_tail(name,tail); lookuptail (return value, integer). The result of the monitor procedure lookup entry. Zero if entry looked up. #0920# name (call value, string or integer or <any type> array). The name or process description address of the entry. tail (return value, integer array). The tail of the entry. Must have at least 10 elements. tail(1) is the size of an area if it is positive else it gives the mode and kind. Integer messadd. 25-8-72 Address of an answer- or message area. #0930#Used by the procedures sendm, senda and waita. Normally the size of the message or answer area should be at least 16 bytes. Integer procedure modyfy_int 80-04-20 Modifies an internal process and makes it ready for start. Call: modify_int(name, registers); modifyint (return value, integer). The result of the procedure modify internal process. Zero if process modified. name (call value, string or <any type> array). The name or process description address of the child process. registers (call value, integer array). The initial values of the registers for the child process. Must have at least 6 elements. registers(1):=w0 registers(2):=w1 registers(3):=w2 registers(4):=w3 registers(5):=exception register registers(6):=instruction counter. Procedure monitor_proc 13-7-72 Makes a monitor call with the number given by no and the working register values given in w. Call: monitor_proc(no,w); no (call value, integer). The number of the monitor procedure. w (call and return value, integer array). The first four elements are used as register values in the call. The #0940# new register values are delivered there. Procedure move_b. 25-8-72 Moves a number a bytes from one address in primary store to another. The standard variable bytes must contain a even no of bytes. The standard variable from must contain the address of area 1. The standard variable to must contain the address of area 2. The procedure is equivalent to move_bytes. Call: moveb; Integer Procedure move_bytes. 5-6-72 Moves a number of bytes from one address in core to another. #0950# #0950#Call: move_bytes(from,to,bytes); movebytes from (call value, integer). The address of the first byte to be moved. to (call value, integer). The address of the first byte where to be moved. bytes (call value, integer). The number of bytes to be moved. Integer procedure move_text. 15-12-72 Moves a string to an address and forward. #0960# #0960#Call: movetext(addr,s); movetext (return value,integer). Number of bytes moved. addr (call value,integer). The first address from where the string is stored. s (call value,string). The string to be moved. Integer nameentry. 5-6-72 This standard integer is used in connection with the procedures initproc, reserveproc and send message. In a call of initproc or reserveproc it gets the address of the name table entry of #0970#the device initialised or reserved. It is used to speed up the call of send message when a string is used as name. The call is of course only speeded up if you use the correct name table entry for the device. Procedure nameload. 5-6-72 Loads the array A in its first 8 bytes the 8 bytes in core starting with addr. Call: name_load(addr,A); addr (call value, integer). The address in core for the first of the 8 bytes. #0980# The addr should be even. A (return value, <any type> array). The 8 bytes are loaded in the first 8 bytes A. Should have at least 8 bytes. Procedure out-char_cur 80_04-20 Output a single character on the current output zone using the file processor procedure outcharcurrent. See the FP-manual (ref. 3). Call: out_char_cur(char); char (call value, integer). The numerical value of the ISO character. Procedure out_end_cur 80-04-20 Makes a call of the fp-procedure outend as described in the fp-manual (ref. 3). Call: outend(char); char (call value,integer). The value of the character to be output on current output. #0990# #0990# Integer outstacked 80-04-20 Used by the procedure connectcuro which increases outstacked each time called and by the procedures closeout and unstackcuro which decreases outstacked each time called. #0990# Integer procedure own_descr. 13-7-72 Finds the process description address of the calling process. Call: own_descr; owndescr (return value, integer). The process description address of current process. Procedure pack_text. 25.07.73 The specified strings are packed in this way: fisrst string into A(low+0) and A(low+1), second string into A(low+2) and A(low+3), etc. #1000#At most 12 characters are moved for every string and unused elements are cleared. The array is treated as a one-dimensional real array. Call: packtext(A,source); A (return value, <any type> array). The array into which the strings are packed. source (call value, general address). One or more parameters of type string. Integer parent. 13-7-72 The parent process description address. #1010# #1010# #1010# #1010# #1010# Integer pda. 25-8-72 The process description address. Used by the procedures waita and senda. Integer procedure perm-aux. 80_04-20 Permanents an entry in an auxillary catalog. Normally the procedures scope_user, scope_pro should be used. Call: perm_aux(name,doc,key); permaux (return value, integer). The result of the monitor procedure permanent entry in auxillary catalog. Zero if entry permanented. name (call value, string or <any type> array). The name or process description address of the entry. doc (call value, string or <any type> array). The name or process description address of the document holding the entry. key (call value, integer). The permanent key. Integer procedure perm_entry. 5-6-72 #rj# Permanents an entry in the catalog. Normally the procedures scope_temp, scope_login, scope_user, scope_pro should be used. #sj# Call: perm_entry(name,key); permentry (return value, integer). The result of the monitorprocedure. Zero if entry permanented. name (call value string or integer or <any type> array). The name or process description address of the entry. #1020# key (call value, integer). The key. Integer procedure proc_id_bit. 16-2-73 The process description address of the internal process with an identification word according to the one specified in the parameter is found. Call: procidbit(idbit); procidbit (return value, integer). If valid then the corresponding process description address otherwise 0. idbit (call value, integer). The identification word. Integer procedure program. 13-7-72 Finds the address in running system of the name of the program document. Call: program; program (return value, integer). The address of the name of the program document. Example: reserving the program document to prohibit removal during run. #1040# #1040#reserveproc(program-2,0); Procedure redef_array. 29-8-72 Changes the base and dope in the description for an array. Call: redef_array(A,first,elements); A (call value,<any type> array). The array to be redefined. first (call value,integer). The address of the first byte in the new array. elements (call value,integer). The number of elements in the new array. #1050# #1050# #1050# Integer procedure regret_mess. 80-04-20 Removes the specified message buffer in the queue of a process. Operation in the buffer must be even. Call: regretmess(buf); regretmess (return value,integer). The result of the monitor procedure regret message. Zero if regretted. buf (call value, integer). The address of the #1060# message buffer to be regretted. #cm Procedure release_per. 24.04.73 Changes some instructions in the algol running system. When the program tries to terminate all peripheral processes reserved are released. Call: releaseper; # Procedure release_proc. 15-9-72 The reservation of a reserved peripheral process is cancelled. Nothing is done for an internal process. #1070# #1070#Call: release_proc(name); name (call value,string or integer or <any type> array). The name or process description address of the process. Integer procedure relocate 80-04-20 Relocates a child process in primary store. Call: relocate(name,start_address); relocate (return value, integer). The result of the monitor procedure relocate process. Zero means child process relocated. name (call value, string or <any type> array). The name or process description address of the child process. start_address (call value, integer). The new start address for the child process. Integer procedure remove_entry. 6-6-72 Removes an entry from the catalog. Call: remove_entry(name); removeentry (return value, integer). The result of the monitorprocedure remove entry. Zero if entry removed. #1080# name (call value, string or integer or <any type> array). The name or process description address of the entry. Integer procedure remove_proc. 6-6-72 Removes a process with a given name. Call: remove_proc(name); removeproc (return value, integer). The result of the monitorproce- dure remove process. Zero if process is removed. name (call value, string or integer or <any type> array). #1090# The name or process description address of the process. Integer procedure rename_entry. 29-8-72 Changes the name of an entry in the catalog. Call: rename_entry(old,new); renameentry (return value,integer). The result of the monitor procedure rename entry. Zero if entry renamed. old (call value,string or integer or <any type> array). The name or process description address #1100# of the entry in the catalog. new (call value,string or integer or <any type> array). The new name (Has the same format as old). Integer procedure reserve_proc. 6-6-72 Reserves a process with a given name. The integer param has only significance for HCØ digital outputs. Call: reserve_proc(name,param); reserveproc (return value, integer). The result of the monitorprocedure. Zero if process reserved. #1110# name (call value, string or integer or <any type> array). The name or process description address of the process. param (call value, integer). Has only signifi- cance for HCØ digital outputs, where it should contain the key. Integer procedure reserve_segm. 6-6-72 Creates an entry in the catalog with the number of segments and the name specified. The rest of the tail is undefined. #1120# #1120#Call: reserve_segm(name,segm); reservesegm (return value, integer). The result of the monitorprocedure create entry. Zero if the entry is created. name (call value string or integer or <any type> array). The name or process description address of the entry. segm (call value, integer). The number of segments to be reserved. Integer result. 4-9-72 The result of a monitorprocedure. Used by the procedure #1130#senda and stopi. #cm gas# #cm Procedure return_rs. 28.06.73 Used in connection with the procedure catcherror to give a normal return to the algol running system. When the procedure P has been activated by the procedure catcherror and a normal termination is wanted a call of returnrs should be executed. Call: returnrs; # #1140# #1140# Integer procedure rs_table. 23-10-72 Finds the algol first address of the running system table. Call: rstable; rstable (return value,integer). First address of the RS-table - RS entry 42 (victim). integer procedure scope_login 80-04-20 Sets the entry base and permanent key for an entry to scope login. Call: scope_login(name); scopelogin (return value,integer). The result of set entry base+8 if that is greater than zero else the result of permanent entry (permanent entry in aux cat). name (string or <any type> array). The name or process description address of the entry name. integer procedure scope_pro 80-04-20 Sets the entry base and permanent key for an entry to scope project. Call: scope_pro(name); scopepro (return value,integer). The result of set entry base+8 if that is greater than zero else the result of permanent entry (permanent entry in aux cat). name (string or <any type> array). The name or process description address of the entry name. integer procedure scope_temp 80-04-20 Sets the entry base and permanent key for an entry to scope temp. Call: scope_temp(name); scopetemp (return value,integer). The result of set entry base+8 if that is greater than zero else the result of permanent entry (permanent entry in aux cat). name (string or <any type> array). The name or process description address of the entry name. integer procedure scope_user 80-04-20 Sets the entry base and permanent key for an entry to scope user. Call: scope_user(name); scopeuser (return value,integer). The result of set entry base+8 if that is greater than zero else the result of permanent entry (permanent entry in aux cat). name (string or <any type> array). The name or process description address of the entry name. Procedure send_a. 4-9-72 Copies an answer of eight words into a message buffer in which a message has been received and delivers it in the queue of the original sender. The standard variable result must contain the result to be delivered. #1150#The standard variable messadd must contain the answer address. The standard variable ba must contain the buffer address. Equivalent to the procedure send_answer. Call: senda; Procedure send_answer 6-6-72 Sends an answer to a message with the result indicated. Call: send_answer(result,ba,answer); result (call value, integer). The result to be delivered. 0<result<5. ba (call value, integer). The buffer #1160# address. answer (call value, integer array). The answer area. Integer procedure send_m. 25-8-72 Sends a message to a process with the name address specified by the address: pda+2, where pda is the standard variable pda. The standard variable messadd must contain an address of a message area. Equivalent to the procedure send_message. #1170# #1170# #1170#Call: sendm; sendm (return value,integer). Zero if buffer claim exceeded else the buffer address. Integer procedure send_message. 26-6-72 Sends a message to a process with the array mess as message area. Call: send_message(name,mess); sendmessage (return value, integer). The buffer address if a buffer could be selec- ted else zero. #1180# name (call value string or integer or <any type> array, return value in case of an array). The name or process description address of the process. In case of an array it must have 10 halfwords. The name table entry is stored in halfword 8-9. mess (call value, integer array). The message area. When you are using strings as names it is possible to speed #1190#the call up by assigning appropriate values to the integer nameentry just before the call of send message. At HCØ you can use as well the name table entry as the process description address. Integer procedure send_mess_id 80_04_20 Calls send message with a specified value of the message flag. Call: send_mess_id(name,mess,id); sendmessid (return value, integer). The buffer address if a buffer could be selected else zero. name (string or integer or <any type> array, return value in case of an array). The name or process description address of the process. An array must have at least 10 halfwords as the name table entry is stored in halfword 8-9. mess (call value, integer array). The message area. id (call value, integer). The message flag. See test event. See also send message. Integer procedure setbit. 13-7-72 The result of the procedure is the word word with the bit indicated set or cleared. Call: set_bit(word,bitno,bitvalue); setbit (return value, integer). The integer word with the given bit set or cleared. #1200# word (call value, integer). The bitpattern to be changed. bitno (call value, integer). The number of the bit in word to be changed. The bitno is counted from rigth to left starting with zero. bitvalue (call value, integer). The value of the bit either zero or one. Integer procedure set_bs_claims 80-04-20 Transfers backing storage claims between the calling process and a child process. Call: set_bs_claims(name,doc,claimlist); setbsclaims (return value, integer). The result of the monitor procedure set backing storage claims. Zero if claims transferred. name (call value, string or integer or <any type> array). The name or process description address of the child process. doc (call value, string or integer or <any type> array). The name or process description address of the document for which claims are transferred. claimlist (call value, integer array). The claim list. Must have at least 8 elements. claimlist(1):=entry claim key 0 claimlist(2):=segment claim key 0 claimlist(3):=entry claim key 1 claimlist(4):=segment claim key 1 . . claimlist(8):=segment claim key 3 Integer procedure set_cat_base 80-04-20 Changes the catalog base for the current process or for a child process. Call: set_cat_base(name,lower_base,upper_base); setcatbase (return value, integer). The result of the monitor procedure set catalog base. Zero if catalog base changed. name (call value, string or integer or <any type> array). The name or process description address of the process. If the first word is binary 0 the current process is used. lowerbase (call value, integer). Lower limit of base interval. upperbase (call value, integer). Upper limit of base interval. Integer procedure set_en_base 80-04-20 Changes the entry base for a catalog entry. Call: set_en_base(name,lower_base,upper_base); setenbase (return value, integer). The result of the monitor procedure set entry base. Zero if entry base changed. name (call value, string or integer or <any type> array). The name or process description address of the entry. lowerbase (call value, integer). The new lower base. upperbase (call value, integer). The new upper base. Integer procedure set_prio 80-04-20 The priority of a child process is changed. Call: set_prio(name,level); setprio (return value, integer). The result of the monitor procedure set priority. Zero if priority changed. name (call value, string or integer or <any type> array). The name or process description address of the child process. level (call value, integer). The amount the child process will get its priority changed. Integer procedure short_load. 26-6-72 Loads the storage halfword addressed as a signed integer and delivers it as result of the procedure. Call: short_load(addr); #1210# shortload (return value, integer). The halfword addressed extended as a signed halfword. addr (call value, integer). The address of the halfword loaded. Integer procedure start_i. 25-8-72 Starts a child process with the name address specified by the address: pda+2, where pda is the standard variable pda. Equivalent to start_int. Call: starti; #1220# starti (return value,integer). The result of the monitor procedure: start internal process. Zero if process started. Integer procedure start_int. 26-6-72 Starts a child process. Call: start_int(name); startint (return value, integer). The result of of the monitorprocedure start inter- nal process. Zero means process started. name (call value, string or integer or <any type> array). #1230# The name or process description address of the child process. Integer procedure stop_i. 25-8-72 Stops a child process with the name address specified by the address: pda+2, where pda is the standard variable pda. The result is stored in the standard variable result. Zero if stop initiated. Equivalent to stop_int. Call: stop_i; stopi (return value,integer). The buffer address #1240# if a buffer could be selected else 0. Integer procedure stop_int. 26-6-72 Stops a child process. Call: stop_int(name,result); stopint (return value, integer). The buffer address if a buffer could be selec- ted else 0. name (call value, string or integer or <any type> array). The name or process description address of the child process to be stopped. #1250# result (return value, integer). The result of the monitorprocedure stop internal process. Zero if stop is initiated. Boolean procedure testbit. 13-7-72 Examines whether a selected bit is zero or one. If it is one the result of the procedure is true else it is false. Call: test_bit(word,bitno); testbit (return value, boolean). True if the selected bit is one else false. word (call value, integer). The integer to be examined. #1260# bitno (call value, integer). The number of the bit in word to be examined. The bitno is counted from rigth to left starting with zero. Integer procedure test_event 80-04-20 Scans the event queue of the process and returns with a result specifying the state of the next element in the queue. Call: test_event(last_buffer,event_id); testevent (return value, integer) The result of the monitor procedure testevent. -1 means queue empty 0 means message 1 means answer last_buffer (call and return value, integer). At call the previous buffer address; at return the next buffer address. eventid (return value, integer). If answer the message identification flag; if message the process description address of the sender. Integer to. 25-8-72 The first address from where the storing should start. Used by the procedure moveb. Integer trap_base. 1-8-72 The address of the interrupt rutine in running system. Procedure unstack_cur_i. 16-2-73 Unstacks current input by a call of the fileprocessor. #1270#Before unstacking the zone is terminated. The zone state unchanged.The integer instacked is decrementet by one See FP-manual (ref. 3). Call: unstackcuri; Procedure unstack_cur_o. 16-2-73 Unstacks current output by a call of the fileprocessor. Before unstacking the zone is terminated. This does not empty the buffer. See closeout. The integer out- stacked is decremented by one. See FP-manual (ref. 3). #1280# #1280#Call: unstackcuro; Procedure wait. 26-6-72 Delays the process the number of seconds specified. Call: wait(sec); sec (call value, integer). The number of seconds the process is to be delayed. The procedure sends a message to the clock and waits for an answer. Integer procedure wait_a. 25-8-72 #1290# #1290# #1290#Delays the calling process until an answer arrives with buffer address given by the standard variable ba. The standard variable messadd must contain an address of an answer area. Equivalent to the procedure wait_answer. Call: wait_a; waita (return value,integer). The result of the monitor procedure wait answer. One if normal answer. Integer procedure wait_answer. 26-6-72 #1300# #1300#Delays the calling process until an answer arrives with the buffer address ba. The answer area is the array answer. Call: wait_answer(ba,answer); waitanswer (return value, integer). The result of the monitorprocedure wait answer. One if normal answer. ba (call value, integer). The buffer address. Must be a valid buffer address in the queue of the calling process, #1310# or a break 6 is performed. answer (call value, integer array). The answer area. Must have 8 elements. Integer procedure wait_event. 26-6-72 Delays the calling process until an event arrives in queue of the calling process. The spare message buffer of running system is however not treated. Call: wait_event(buffer_address); waitevent (return value, integer). The result of the monitorprocedure wait event. Zero in #1320# case of a message, one in case of an answer. bufferaddress (call and return value, integer). At entry last buffer address. At return next buffer address. If bufferaddress is zero the queue is examined from the start. If neither zero or a buffer address a break 6 is performed. Integer procedure wait_message. 26-6-72 Delays the calling process until a message arrives in the que. Call: wait_message(NAME,result,mess); waitmessage (return value, integer). The buffer address. #1330# NAME (return value, <any type> array). The name of the sender. Should have at least 8 halfwords. result (return value, integer). If it is greater than 0 it is the process description address of the sender. If less than 0 it is -parent description address. mess (return value, integer array). The message area. Integer procedure word_l. 4-9-72 Loads a storage word as an integer. The standard variable #1340#coreaddr must contain the address of the word. Equivalent to the procedure word_load. Call: wordl; wordl (return value,integer). The storage word fetched. Integer procedure word_load. 26-6-72 Loads the storage word addressed as an integer and delivers it as the result of the procedure. Call: word_load(addr); wordload (return value, integer). The storage word #1350# fetched. addr (call value, integer). The address of the word. Procedure word_store. 26-6-72 Stores the integer word in core store at the absolute address given by addr. Call: word_store(addr,word); addr (call value, integer). The address. word (call value, integer). The word to be stored. #1360# #1360# #1360# Integer procedure zone_des 7.09.72 Finds the address of a zone descriptor. Call: zonedes(z); zonedes (return value, integer). In case of a zone it is the absolute zone descriptor address. In case of a zone array the base address of the zone descriptor. z (call value, zone or zone array). #ef# ▶EOF◀