.c	Sunday  April 24,1983  00:18  FQ+4D.5H.55M.44S.  -*- Bolio -*-

.chapter "Interfaces to VMS"

.section "Event Flag and Waiting Services"

Note also (nil-interrupt-section-page), on how lan{nil} does
interrupts, which has great bearing on some of these things.
Some of this is bound to change to fit its use better.

When lan{nil} queues an interrupt, it performs both a 7$wake*,
and sets an event flag.  This allows code to wait for things either by
simply hibernating, running queued interrupts, checking something, and
looping back, or by waiting for the logical 2or* of an interesting
event flag with the one lan{nil} uses for interrupts:
.defvar si:*interrupt-event-flag-number*
The value of this is the number of an event flag which gets set when
there are pending interrupts to be processed, and cleared when it is
determined that there aren't any more (they were all run, or interrupt
processing was totally inhibited).  The value of this should
2only* be interpreted this way if it is non-negative.  At certain
times (around startup and suspending) it may be zero or negative.
.end_defvar

.defun si:%allocate-event-flag
Allocates an event flag.  Interface to 7lib$get_ef*.
Returns the event flag number, or the negative of the error code
(kludgey, eh?).  (It should probably signal a specific condition.)
.end_defun

.defun si:%free-event-flag event-flag-number
Deallocates an event flag.  Interface to 7lib$free_ef*.  Returns
3t* (freed it) or 3nil* (already free), otherwise errors out.
.end_defun

.defun si:%reserve-event-flag event-flag-number
Interface to 7lib$reserve_ef*, q.v.  Like
3si:%free-event-flag*:  returns 3t*, 3nil*, or errors out.
.end_defun

.defun si:%clear-event-flag event-flag-number
Clears the event flag 2event-flag-number*.  Returns 3t*
(cleared it), 3nil* (already clear), or an error code (again, this
shoule probably be changed to signal).
.end_defun

.defun si:%set-event-flag event-flag-number
Sets the event flag.  Returns 3t* (set it), 3nil* (already
set), or error code.
.end_defun

.defun si:%read-event-flags representative-event-flag simple-bit-vector
Read event flags.  The event flags of the cluster of which
2representative-event-flag* is a member are read into
2simple-bit-vector*, which must be a simple bit vector 32 bits long.
Returns 3nil* on success, else error code.
.end_defun

.defun si:%wait-for-events representative-event-flag simple-bit-vector
Waits for the logical 2or* of the specified event flags;  the
event flag number 2representative-event-flag* defines which
cluster is being talked about by 2simple-bit-vector*, which must
be a simple bit vector 32 bits long with bits set for the event flags
to be waited for.  For instance, if the event flag number 361* is
being waited for, then 2simple-bit-vector* should contain all
zeros except for bit 29.  lan{Nil} does not automatically 2or*
in its own interrupt event flag bit.  You must do that yourself if you
are prepared to allow interrupts to be run. (This might be changed.)
If you do not, then the wait will be uninterruptible.
.end_defun

.defun si:hibernate
Goes into an infinite loop of hibernating interruptibly, which may of
course be exited by the use of 3throw* from an interrupt.
.end_defun


.section "Time, Timer, and Conversion Services"

lan{Vms} represents time as a 64 bit integer representing
100-nanosecond ticks, apparently in an attempt to make life as
sifficult as possible, since it mainly seems to be only accurate to
centiseconds.  To make arithmetic and comparisons on these reasonable,
lan{nil} provides primitives for converting back and forth into
double precision floating-point numbers.

2Note:  should the 1-time-* in the names of the following two
routines be changed to 1-bintim-*?*

.defun si:%convert-time-to-d_float bintim
2bintim* is a 64-bit long simple bit vector containing a
(non-negative) lan{vms} time.  This converts it to, and returns, the
corresponding double-float.
.end_defun

.defun si:%convert-d_float-to-time double-float bintim
Converts 2double-float* to a 64-bit lan{vms} time, and stuffs
that into 2bintim* (which obviously must be a simple-bit-vector at
least 64 bits long).
.end_defun

The fun_i{elapsed-time} function simply returns the result of
applying the above conversion to the time provided by the
7sys$gettim* system service.

.defun si:vms-set-timer bintim arg
2note:  this will probably change both name and functional
description sometime.*

Queues a timer interrupt for the system-format time in the 64-bit long
simple-bit-vector 2bintim*.  When the timer goes off, the
3:timer* condition is signalled with an argument of 2arg*.
2arg* should probably be a fixnum.
.end_defun


.defun si:numtim simple-bit-vector
This routine diddles a simple-bit-vector buffer to return the current time.
Seven 16-bit nibbles are filled in as follows:
.table 2 250 250
.item 0
year since 1900
.item 1
month of year
.item 2
day of month
.item 3
hour of day
.item 4
minute of hour
.item 5
second of minute
.item 6
hundredths of second
.end_table
.end_defun


.section "Miscellaneous VMS Services"

.defun si:%adjust-working-set-limit limit
Interface to 7sys$adjwsl*.  2limit* is a fixnum amount to
adjust the working set limit, in pages.  The new limit is returned, so
a 2limit* of 30* may be used to get the current limit.

Given the automatic increase in the limit which lan{vms} performs,
it is unclear what use this is.
.end_defun


.defun si:trnlog logical-name
Returns the translation of 2logical-name*, which must be a
simple-string.  Returns 3nil* if there is no translation.
Interfaces directly to 7sys$trnlog*, so case and superfluous
spaces may be significant.
.end_defun

.defun si:%get-vms-error-message status-code string flags
Gets the complete error text associated with 2status-code*, e.g.
.lisp
%RMS-F-FUBAR, You are totally shafted
.end_lisp
2string* should be a simple-string to use as a buffer;  it should
be 256 long (the maximum size ever needed for this).  2flags* are
the flags which tell the 7$getmsg* system service which portions
of the message string to return;  normally this should be 15
(decimal), which returns all of the components.
.end_defun

