! System include file for MOUSE
! August 1986 version

%option "-low-nons"

{* global object definitions *}

%recordformat queue fm -
  (%short tag,size,
  %record(queue fm)%name forward,backward,header)

%recordformat run queue fm -
  (%record(queue fm)queue, %bytename interrupter)

%recordformat semaphore fm -
  (%record(queue fm)queue,%integer count, %record(semaphore fm)%name assoc)

%recordformat mailbox fm -
  (%record(queue fm)queue,%record(semaphore fm)%name semaphore)

%recordformat message fm -
  (%record(queue fm)queue,
   %record(mailbox fm)%name reply)

%recordformatspec poa fm {FE02 process-own area}

%recordformat process fm -
  (%bytearray i(1:512) %or-
   %record(queue fm)queue,
   %record(run queue fm)%name target,
   %record(mailbox fm)%name async,

{* boot processor local part follows *}

   %integer ssp, xvt, tvt, reftime, cputime, membot, memtop,
   %record(poa fm)%name poa,
   %record(*)%name state, %short quota,hysteresis)

{* local objects *}

%recordformat interrupt handler fm -
  (%record(queue fm)queue, %integer pc,a4)

%recordformat {priority} state fm -
  (%record(queue fm)queue %or -
   %short *,*,%record(state fm)%name lower,higher,*,
   %record(run queue fm)%name target,
   %short priority,quota,hysteresis,*)

{* kernel and local operations for interrupt handlers *}

@16_3f00-6*64 %routine int enqueue(%record(*)%name item,q)
@16_3f00-6*63 %record(*)%map int dequeue(%record(queue fm)%name q)
@16_3f00-6*62 %routine intrequeue(%record(*)%name item,q)
@16_3f00-6*61 %record(*)%map int unqueue(%record(queue fm)%name q)
@16_3f00-6*60 %record(queue fm)%map int inqueue(%record(*)%name item,left,right)
@16_3f00-6*59 %record(queue fm)%map int exqueue(%record(*)%name item)
@16_3f00-6*58 %routine int signal semaphore(%record(semaphore fm)%name s)
@16_3f00-6*57 %integerfn int test semaphore(%record(semaphore fm)%name s)
@16_3f00-6*56 %routine return from interrupt
@16_3f00-6*55 %routine wait for interrupt
@16_3f00-6*54 %routine add interrupt handler -
                 (%record(interrupt handler fm)%name h,%integer level)
@16_3f00-6*53 %routine remove interrupt handler -
                 (%record(interrupt handler fm)%name h)

{* kernel operations for user processes *}

%systemroutinespec enqueue(%record(*)%name item,%record(queue fm)%name q)
%systemrecord(*)%mapspec dequeue(%record(queue fm)%name q)
%systemroutinespec requeue(%record(*)%name item,%record(queue fm)%name q)
%systemrecord(*)%mapspec unqueue(%record(queue fm)%name q)
%systemrecord(queue fm)%mapspec inqueue(%record(*)%name item,left,right)
%systemrecord(queue fm)%mapspec exqueue(%record(*)%name item)

%systemroutinespec signal semaphore(%record(semaphore fm)%name s)
%systemroutinespec semaphore wait(%record(semaphore fm)%name s)
%systemintegerfnspec test semaphore(%record(semaphore fm)%name s)

%systemroutinespec send message -
   (%record(*{message fm})%name message,
    %record(mailbox fm)%name box,reply)
%systemrecord(*{message fm})%mapspec receive message -
   (%record(mailbox fm)%name box)

{* utility procedures for initialising kernel objects *}

%systemroutinespec setup queue(%record(queue fm)%name q)
%systemroutinespec setup semaphore(%record(semaphore fm)%name s)
%systemroutinespec setup message(%record(* {message fm})%name m,%integer size)
%systemroutinespec setup mailbox -
   (%record(mailbox fm)%name b,%record(semaphore fm)%name s)
%systemroutinespec setup interrupt handler -
   (%record(interrupt handler fm)%name i,%integer pc)
%systemroutinespec setup process(%record(process fm)%name p)

{* local operations *}

%systemintegerfnspec set sr(%integer newsr)
%systemintegerfnspec or to sr(%integer newsr)

%systemrecord(state fm)%mapspec scheduling state(%integer priority)
%systemintegerfnspec cpu type
%systemrecord(process fm)%mapspec current process
%systemintegerfnspec real time
%systemintegerfnspec cpu time

%systemroutinespec set priority(%record(process fm)%name p,%integer prio)

%systemrecord(process fm)%mapspec create process -
   (%integer size,pc,priority,%record(queue fm)%name queue)

%systemroutinespec delete process(%record(process fm)%name pcb)

! End of kernel specs - FE02 stuff follows

!Dictionaries are organised as binary trees with parent pointers.
!Balancing is for further study.  Dictionary descriptors contain
!a pointer to the root of the tree, plus a pointer to an alternative
!dictionary, to be searched if the sought entry is not found in the
!current dictionary's tree.  Dictionary cells are normally allocated
!economically, i.e. they do not allow space for a 255 character string
!at the end, but only enough.

%recordformatspec dict cell fm
%recordformat dict fm -
  (%record(dict fm)%name alt,%record(dict cell fm)%name tree)
%recordformat dict cell fm -
  (%record(dict cell fm)%name parent,left,right,
   %integer token,%string(255)s)

!The event record officially contains only EVENT, SUB, LINE, EXTRA,
!and MESSAGE.  Semi-officially also R.  PC and DISPLAY are unofficial,
!and pun on MESSAGE being bigger than it needs to be.

%recordformat event fm -
  (%byte event,sub, %half line,
   %integer extra,%string(255-32)message,
   %integer pc,%integerarray display(1:7),
   %integerarray r(0:15))

!Stream control block.
!P  points at next character to be transferred.
!L  Refresh/Flush needs to be called if P>=L prior to transfer.
!BS Start address of buffer.
!BL End address of buffer (BL-BS = size of buffer).
!FS Address of first character in file (whether or not mapped).
!FL Address of last+1 character in file (w.o.n.m, FL-FS = file size).
!Normally we have FS<=BS<=P<=L<=(BL,FL), and P-FL = current position
!within file (relative to 0 being the first character).
!FASTPC: Entry point of REFRESH or FLUSH routine (if input or output).
!GLA: A4 of device driver module.
!SERPC: Entry point of general service routine.
!MODE: Determines whether input or output, and devdep modes.
!NEXT: next SCB on this stream (to be re-instated on CLOSE).
!ACB: Access control block (for further study).
!A,B,C,D: Spare fields for device specific use.
!FILENAME: (at end for economic allocation) Full canonical file name.

%recordformat scb fm -
  (%integer p,l,bs,bl,fs,fl,fastpc,gla,serpc,mode,
   %record(scb fm)%name next,%record(*)%name acb,
   %integer a,b,c,d,%string(255)filename)

!File connection record.
!Keeps track of pre-loaded files (tentative)

%recordformat fcr fm -
  (%record(fcr fm)%name next,%integer start,size,%half count,flags)

%recordformat trap fm (%record(trap fm)%name next,%integer pc,gla,spare)

!Heap cells look like this when they're holes.  When they're used,
!they look like (%byte level %or %integer size, <user portion>).

%recordformat heap cell fm -
  (%byte level %or %integer size,
   %record(heap cell fm)%name forward,backward)
%recordformat heap header fm -
  (%byte level %or %integer size,
   %record(heap cell fm)%name holes,%integer front,limit,end)

!FE02 Object file header.

%recordformat fe02 header fm -
  (%half tyver,flags,export,import,%integer codesize,%half reset,main,
   %integer ownsize,stackreq,%short dlim,charlim,spare1,spare2)

!FE02 External object descriptor.

%recordformat fe02 object fm -
  (%half flags,extra,%integer type,offset,%string(255)name)

!FE02 indirector (GLA entry).
!For data object it's just a 4-byte pointer.
!For %system procedures it's a 6-byte JMP.
!For %external procedures it's a 12-byte {Move.l #??,A4; Jmp ??}.
!For %dynamics it's also 12 bytes, which are like %externals after
!the first call, but initially different.

%recordformat fe02 indir fm -
  (%integer address %or -
   %half op1, %integer opd1, %half op2,%integer opd2)

!(Loader's) Module activation record.
!Keeps track, within the current program activation, of which
!modules are loaded, and where their respective GLAs are.

%recordformat mar fm -
  (%record(mar fm)%name next,%record(fe02 header fm)%name header,%integer gla)
  
!(Loader's) Loaded external object.
!Keeps track, within the current program activation, of which
!external objects are loaded, where their FE02 descriptors are,
!what module they're in, and where the objects themselves are.

%recordformat leo fm -
  (%record(leo fm)%name left,right,
   %record(fe02 object fm)%name object,
   %record(mar fm)%name module,%integer address)

!(Loader's) Program activation record.
!Contains a link to the next (more global) program activation record
!in the same process, and the roots for the list of module activation
!records and the tree of object activatiuons records.

%recordformat par fm -
  (%record(par fm)%name next,
   %record(mar fm)%name modules,%record(leo fm)%name objects)

!(Loader's) Undischarged dynamic reference record.
!Contains (a path to) all the information needed by the loader
!to satisfy a dynamic procedure reference.

%recordformat dyn fm {undischarged dynamic reference} -
  (%record(fe02 object fm)%name object,%record(par fm)%name program)

!Layout of a Process-Own-Area.

%recordformat poa fm(%bytearray b(1:1024) %or-
  %record(trap fm)%name trap %or-
  %integer evlink,%integerarray display(1:7),
  %byte event,eventsub,%short eventline,%integer eventextra,
  %string(255-32)eventmessage,
  %integer eventpc,%integerarray eventdisplay(1:7),
  %integerarray eventr(0:15),
  %integer scratch1,scratch2,excepth,
  %record(par fm)%name topprog,
  (%record(heap header fm)%name heap %or %integer heapbase,stacklim),
  %record(scb fm)%name curin,curout,%integer instream,outstream,
  %record(scb fm)%namearray in,out(0:7),%string(255)cliparam,
  %record(dict fm)%name masterdict,extdict,moddict,logdict,fildict,comdict,
  %integer membot,memtop)

%systemroutinespec connectfile(%string(255)file,%integer mode,
   %integername start,size)

%systemroutinespec resetinput
%systemroutinespec resetoutput
%systemintegerfnspec instream
%systemintegerfnspec outstream
%systemstring(255)%fnspec cliparam
%systempredicatespec split(%string(255)%name s,l,r)

%systemroutinespec heapput(%integer x)
%systemroutinespec mark
%systemroutinespec release

%systemroutinespec preconnect(%string(255)file,%integer start,size)
%systemroutinespec install(%record(fe02 header fm)%name h,%string(255)file)
%systemroutinespec preload(%String(255) file)

%externalroutinespec run process (%string(255) file,
                                  %Integer space,priority)

%systemintegerfnspec makeentry(%string(255)name,%record(dict fm)%name dict)
%systemintegerfnspec findentry(%string(255)name,%record(dict fm)%name dict)
%systemstring(255)%fnspec translateentry(%integer t)
%systemroutinespec deleteentry(%integer t,%record(dict fm)%name d)
%systemintegerfnspec firstentry(%record(dict fm)%name d)
%systemintegerfnspec nextentry(%integer t)
%systemrecord(dict fm)%mapspec create dict(%string(255)s)
%systemrecord(dict fm)%mapspec find dict(%string(255)s)

%systemrecord(scb fm)%mapspec new scb(%string(*)%name s)
%systemrecord(scb fm)%mapspec open(%integer mode,%string(255)filename)

%systemroutinespec toupper(%string(*)%name s)
%systemstring(*)%mapspec newstring(%string(255)s)
%systempredicatespec dynamicload(%string(255)s,%integername pc,gla)

%systemroutinespec prompt(%string(255)s)

%systemroutinespec createlogicalname(%string(255)log,equiv)
%systemroutinespec deletelogicalname(%string(255)s)
%systempredicatespec translatelogicalname(%string(*)%name s)

%constinteger inputmode=0,outputmode=1,appendmode=2,modifymode=3

%constinteger {function codes for IO service} -
  ser closin = 0,
  ser closout = 1,
  ser setin = 2,
  ser setout = 3,
  ser prompt = 4,
  ser dropout = 5,
  ser refresh = 6,
  ser flush = 7

@0(a5) %record(poa fm)poa

@16_3f00 -24 %integerfn muldiv(%integer a,b,c)
@16_3f00-120 %integerfn heapget(%integer amount) {also NEW}
@16_3f00-180 %routine setinput(%integer byte)
@16_3f00-186 %routine setoutput(%integer byte)

! Temporaries

@16_40c %routine putlong(%integer x)
@16_41c %routine putsym(%integer x)
@16_420 %routine putstring(%string(255)s)
