@X@~
~L3 COUK1247
80
~V7 56 2 -5
~D 10
~H                    MUSS
~
~
~D 10
~H             BSC211
~D 10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                            ISSUE 11~
~V9 -1
~P
~V9 1
~YBSC211
~S~M~OBASIC COMPILER IMPLEMENTATION DESCRIPTION
~S~M~OSection 21
~S~OSection 21 Program Control
~S~O1. General Description
~BThis section contains the procedures which initialize and
terminate the BASIC run-time system.  Additionally, this section
provides run-time support for exception handling.  In the absence
of programmer specified recovery procedures for exceptions it is
monitored and the program execution terminated.
~S~O2. Interfaces
~S~O2.1 Section Interfaces Used
~
   Section 20 : (Run-Time Configuration Section)~
~S~O2.2 Section Interface
~
Exported Scalars:~
   C.IN.STR~
   C.OUT.STR~
   LAST.PU~
~
Exported Procedures:~
   BIO.INIT.RUN~
   BIO.END.RUN~
   EXCEPTION~
   BIO.EXCEPTION~
   BIO.HANDLER~
   BIO.EXIT.HANDLER~
   BIO.CAUSE~
~Q 5
~
Configuration Parameters:~
   DATA.SEG.NO~
   DATA.SEG.Z~
   HANDLER.Z~
~S11) BIO.INIT.RUN(PROGRAM.EXIT.LABEL)
~BThis procedure is called to initialise the
data-structures of the BASIC run-time system.
For programs, the compiler embeds a call to this procedure at the
beginning.  The currently selected input and output streams are
remembered, and these streams are used for subsequent "INPUT" and
"OUTPUT" statements specifying channel zero.  P1
specifies the program exit label, to which control is returned
after obeying a STOP statement.  Additionally this procedure
nominates BIO.TRAP to be used when system errors in classes
0, 5 or 8 are detected.
~S12) BIO.END.RUN()
~BThis procedure is called to terminate the BASIC run-time system.
The input and output streams that were current at BIO.INIT.RUN time
are reselected, and any working segments created by the run-time
system are released.  Additionally any open channels
are closed.  Finally control is returned to the program
exit label.
~S13) EXCEPTION(MESS.NO,CAPTION,VALUE)
~BThis procedure calls BIO.EXCEPTION for an exception specified by P1,
encoded as follows:~
~3
~
   Bits 0 - 7    Internal exception message number~
   Bit  8 = 0/1  Non-fatal/fatal exception~
~0
~
P2 specifies a caption to be inserted in an error message, and
P3 similarly specifies an optional integer value to be printed.
If Bit 8 of P1 specifies a fatal exception, program execution
is terminated by calling BIO.END.RUN, and a Class 6 Code 200
trap is generated.  Otherwise, control is returned to the calling
procedure.
~S14) BIO.EXCEPTION(MESS.NO<IN16>)
~BCalls to this procedure are planted at for error
conditions detectable at run-time.  P1 gives the number of the
message to be printed as defined by bits 0-7 of P1 in EXCEPTION.
P1 is an internal exception code and is mapped to the
corresponding BASIC EXTYPE.  Setting bit 8 of P1=1 causes the
exception to be treated as non-fatal.
~S15) BIO.HANDLER()HANDLER.ID
~BThis procedure returns the identifier for exception handler code
contained in the calling procedure that is to be entered to process
the current exception.  If the line at which the exception occurred
is not in a protection block then control is returned to the most recently
entered procedure that has programmer specified exception handlers.  See
implementation description for the details.
~S16) BIO.EXIT.HANDLER()HANDLER.ID
~BThis is called to 'exit' an exception handler.  If the current handler
is for a nested protection block, then the identifier for the enclosing
protection block is returned; otherwise control is returned to the
most recently entered procedure that has programmer specified
exception handlers.
~S17) BIO.CAUSE(EX.NO<IN32>)
~BThis procedure is called to force an exception with the BASIC
EXTYPE as specified by P1.
~S~O3. Implementation Description
~S~O3.1 Outline of Operation
~S~M~OException Processing
~BWhen an exception occurs the currently active Basic procedures are
checked to see if any have programmer specified exception handlers,
if there are none the exception is monitored and program execution
terminated.  Otherwise the most recently activated procedure that has
any exception handlers is selected.  The address within the procedure
associated with the exception is determined.  Control is then returned,
via a non-local jump, to the procedure at which the following code is
obeyed:~
~
~M->HANDLER.SWITCH[BIO.HANDLER];
~
The call of BIO.HANDLER determines if the exception occurred in a
protection block, and if it does sets up the control address for the~
~
~NRETRY statement
~NCONTINUE statement
~Nprotection block end
~
The identifier of the exception handler associated with the protection
block is returned and the control switch enters the exception handler
code.
~BWhen the exception is not in a protection block then the
remaining currently active Basic procedures are checked to see if
any have programmer specified exception handlers, if there are
none the exception is monitored and program execution terminated,
otherwise control is transferred to the BIO.HANDLER() call of the
next most recent active procedure that has exception handlers as
described above.
~BThere are four ways of exiting from an exception handler:~
~T# 15
~
#via RETRY~
#via CONTINUE~
#to the statement following the protection block end~
#via EXIT.HANDLER~
~
The first three use label variables set up by the previous call to
BIO.HANDLER.  The last executes the call:~
~
#->HANDLER.SWITCH[BIO.EXIT.HANDLER()]~
~
If the current exception handler is for a nested protection block
then BIO.EXIT.HANDLER returns the exception handler identifiers
for the enclosing protection block and the code for this exception
handler is entered.  If there is no enclosing protection block the
remaining currently active procedures are checked for exception
handlers as described above.
~S1Internal Procedures
~S11) MONITOR(message.no)
~BThis procedure prints a suitable exception message as specified
by P1.
~S12) BIO.TRAP(class.code)
~BThis procedure is nominated by BIO.INIT.RUN to intercept system
errors in classes 0, 5 and 8.  Errors in these classes are handled
by the exception processing mechanism.
~S~O3.2 Data Structures
~T# 15
~
HANDLER.S~IThis is a stack with one entry per activated procedure.  Each
entry has three fields namely: LINE, this is a bounded pointer to a vector
of type LINE.E that specifies the protection block use in the procedure.
A nil pointer means the procedure has no protection blocks.  The field
LAB contains the address and environment of the labelled code:~
~T# 3 18
~
#HANDLER.LABEL:~
#~I->HANDLER.SWITCH[BIO.HANDLER()];~
~T# 15
~
#~Iand lastly the field PROC, which is set to zero for a program
unit and one for an internal function.~
~
LAST.H~IIndex into HANDLER.S to last entry pushed onto stack.~
~
EXLINE~ILine number of Basic statement associated with current
exception.~
~
EXTYPE~INumber of current exception.~
~
RETRY.ADDR~IControl address for RETRY statement.~
~
CONTINUE.ADDR~IControl address for CONTINUE statement.~
~
EXIT.ADDR~IControl address for end of current protection block.~
~
LAST.PU~IProgram unit identifier of most recently activated program unit.~
~
LINE.E~IThis type specifies protection block information.  The type
has four fields namely L.NO, L.ADDR, H.ID, STRUC.  L.NO is the line
number of a Basic statement.  L.ADDR contains the control address of the
start of the statement.
FI.ID is the identifier of the associated exception handler for this
statement.
STRUC is bit encoded as follows:~
~3
~T# 15 20 27
#Bit#0 = 1~IStart of protection block.~
##1 = 1~IEnd of protection block.~
##2 = 1~IStart of control block.~
##3 = 1~IEnd of control block.~
~0
~T# 15
~IFor a procedure within protection blocks then a vector of type
LINE.E is created with one entry for each line of each protection
block.~
~
E.M~IA data vector of exception messages.  The presence of "@"
in a string indicates that an optional caption may be included in
the message at that point, and "$" indicates an integer value
similarly.~
~
E.M.ST~IA data vector holding the sarting positions of error
messages in E.M.~
~
C.IN.STR,~
C.OUT.STR~IThese variables hold respectively the MUSS input
and output stream numbers that were current when BIO.INIT.RUN
was called.~
~
EX.MAP~IA data vector, indexed by internal exception number, holding
the corresponding BASIC EXTYPE numbers.~
~
P.BLK, C.BLK~IThese variables are used to keep track of protection-block
and control-block structure while searching the LINE.E table.~
~
OLD.SEG.NO~IHolds the i.d. of the scratch segment created by
BIO.INIT.RUN.~
~
EX.STAT~IA status variable indicating the kind of exception
being processed.  Bit encoded as:~
~3
~IBit 0 = 1 Non-fatal exception.~
~IBit 1 = 1 Application defined exception.~
~IBit 2 = 1 System error without corresponding~
~I          BASIC.EXTYPE.~
~0
~Y
~V9 -1
~P
~D 15
~HFLOWCHARTS
~
~
~H                BSC211
~V9 -1
~F
//14
@TITLE BSC21(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
PROGRAM CONTROL
@BOX 2.0
MODULE HEADING
@BOX 3.0
GLOBAL VARIABLES
@BOX 4.0
PROCEDURES IN MODULE:
   LIBRARY PROCS
   BIO.INIT.RUN [BSC21.1]
   BIO.END.RUN [BSC21.2]
   BIO.EXCEPTION [BSC21.4]
   BIO.HANDLER [BSC21.5]
   BIO.EXIT.HANDLER [BSC21.6]
   BIO.CAUSE [BSC21.8]

   INTERNAL PROCS
   MONITOR [BSC21.3]
   NEXT.HANDLER [BSC21.7]
   BIO.TRAP [BSC21.9]
@BOX 5.0
END
@BOX 1.1
::PROGRAM CONTROL
@BOX 2.1
#BSC21/1
MODULE(BIO.INIT.RUN, BIO.END.RUN, MONITOR,LAST.PU,
        BIO.HANDLER, BIO.EXIT.HANDLER,BIO.CAUSE,
        C.IN.STR, C.OUT.STR,BIO.EXCEPTION,EXCEPTION,CHAN.EXCEPTION);
@BOX 3.1
*GLOBAL 2;
TYPE LINE.E IS $LO32 L.NO ADDR L.ADDR
               $LO8 H.ID, STRUC;
TYPE HANDLER.E IS ADDR[LINE.E] LINE
                  LABEL LAB
                  $LO8 PR;
::VARIABLES BELOW ARE ACCESSED BY COMPILED BASIC PROGRAM
HANDLER.E[HANDLER.Z] HANDLER.S;
$LI/ADDR[LINE.E]NIL.L=;
$LO16 LAST.H;
$IN32 EXLINE;
$IN32 EXTYPE;
ADDR CONTINUE.ADDR, RETRY.ADDR, EXIT.ADDR;
$IN16 LAST.PU;
::ADDR DECLARED AS LABEL WITHOUT ENVIRONMENT IN COMPILED PROGRAMS
::END OF COMMUNICATION VARIABLES
PSPEC P($IN,$IN);
ADDR P [10] TRAPS;
$IN SYS.CL,SYS.CD;
$IN16 G.EX.NO,P.BLK,FAIL.I,EX.VAL;
$LO8 C.HID,EX.STAT;
ADDR[$LO8]EX.CAP;
ADDR FAIL.ADDR;
$IN C.IN.STR, C.OUT.STR, OLD.SEG.NO;
$LA BIO.EXIT.LABEL;
$LI EX.MAP.Z = 103;
*GLOBAL 7;
#BSC21.0
@B 4.1
*GLOBAL 0;
LSPEC CHAN.EXCEPTION($IN,$IN);
PSPEC BIO.TRAP($IN,$IN);
LSPEC BIO.INIT.RUN ($LA);
LSPEC BIO.END.RUN ();
LSPEC BIO.EXCEPTION ($IN16);
LSPEC BIO.HANDLER()/$LO16;
LSPEC BIO.EXIT.HANDLER()/$LO16;
PSPEC MONITOR($IN,$IN)/$IN32;
PSPEC NEXT.HANDLER($IN)/$LO16;
LSPEC EXCEPTION($IN,ADDR[$LO8],$IN);
LSPEC BIO.CAUSE($IN32);
PROC EXCEPTION(M.NO,CAP,VAL);
CAP => EX.CAP; VAL => EX.VAL;
%100 -=> M.NO;
BIO.EXCEPTION(M.NO);
END
#BSC21.1
#BSC21.2
#BSC21.3
#BSC21.4
#BSC21.5
#BSC21.6
#BSC21.7
#BSC21.8
#BSC21.9
#BSC21.10
@B 5.1
*END
@E

//16
@TITLE BSC21/1(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@B 1
EXTERNAL ENVIRONMENT
@B 2
IMPORTED VARIABLES,PROC SPECS
@B 3
END
@B 1.1
::IMPORTS
@B 2.1
PSPEC BIO.FILE.NAME($IN)/ADDR[$LO8];
PSPEC GET.LINK($LA)/ADDR;
LSPEC ENTER.TRAP($IN,$IN);
PSPEC BIO.INIT.CHAN.TAB();
PSPEC BIO.CLOSE.ALL();
$AD PW0, PW1, PW2, PW3, PW4, PW5, PW6;
$LO64 PWW1, PWW2;
IMPORT LITERAL DATA.SEG.NO, DATA.SEG.Z,HANDLER.Z;
IMPORT LITERAL  $LO8 SP, NL;
$LO8 VAL.FN,BAD.FMT,FMT.ST;
$IN16 LAST.PAR,LAST.O,LAST.I;
$IN G.CHAN.NO;
@E
//16
@TITLE BSC21.0(1,11)
@COL 1S
@BOX 1.0
DATAVECTOR OF EXTYPE NUMBERS
@BOX 1.1
::IF MORE ENTRIES ARE ADDED, UPDATE EX.MAP.Z LITERAL
DATAVEC EX.MAP($IN32)

4005  4006  4007  6001  6002  ::0-4
6003  6004  7001  7002  7002  ::5-9
0     0     0     7003  7004  ::10-14
7199  7199  7110  7051  7199  ::15-19
7206  7111  7112  7207  7199  ::20-24
7301  8002  8003  8011  8102  ::25-29
8102  1007  8101  1007     0  ::30-34
1007  8001  7004  7313  7313  ::35-39
8202  7113  7199  6005  7199  ::40-44
8401  7321  7199  4008  4002  ::45-49
4009  4009  4004  4004  7114  ::50-54
7115  7116  7204  8201  1054  ::55-59
1054  1054  1054  0     1106  ::60-64
6101  3006  4003  4001  1004  ::65-69
1007  7101  7103  7104  7105  ::70-74
7106  7107  1051  8402  3005  ::75-79
3002  3004  3007  8301  8120  ::80-84
1105  8105  1008  8102  8013  ::85-89
7317  0[4]                    ::90-94
0[5]                          ::95-99
10001 10002  10004            ::100-104

END
@END
//16
@TITLE BSC21.1(1,11)
@COL 1S-2R-6R-3R-4R-7R-5F
@FLOW 1-2-6-3-4-7-5
@BOX 1.0
BIO.INIT.RUN(EXIT.LABEL)
@BOX 2.0
CREATE WORKING SEGMENTS
@BOX 3.0
NOTE CURRENT INPUT AND
OUTPUT STREAMS
@BOX 4.0
INITIALISE CHANNEL TABLE
[BSC27.18]
AND GLOBAL VARIABLES
@BOX 5.0
END
@BOX 6.0
REMEMBER EXIT LABEL
@BOX 7.0
NOMINATE BIO.TRAP AS SYSTEM
ERROR HANDLER
@BOX 1.1
PROC BIO.INIT.RUN (EXIT.LABEL);
$IN SCRATCH.SEG.NO, I;
@BOX 2.1
CREATE.SEGMENT (-1, DATA.SEG.Z);
PW1 => SCRATCH.SEG.NO;
INTERCHANGE (SCRATCH.SEG.NO, DATA.SEG.NO);
SCRATCH.SEG.NO => OLD.SEG.NO;
@BOX 3.1
CURRENT.INPUT() => C.IN.STR;
CURRENT.OUTPUT() => C.OUT.STR;
@BOX 4.1
-1 => LAST.H => LAST.PU => LAST.PAR => LAST.I => LAST.O;
0 => VAL.FN => BAD.FMT => FMT.ST;
BIO.INIT.CHAN.TAB();
@BOX 5.1
END
@BOX 6.1
EXIT.LABEL => BIO.EXIT.LABEL;
@BOX 7.1
READ.TRAP(0) => TRAPS[0];
READ.TRAP(5) => TRAPS[5];
READ.TRAP(8) => TRAPS[8];
SET.TRAP(0,^BIO.TRAP);
SET.TRAP(5,^BIO.TRAP);
SET.TRAP(8,^BIO.TRAP);
@END
///14
@TITLE BSC21.2(1,11)
@COL 1S-2R-3R-7R-4R-5R-6F
@FLOW 1-2-3-7-4-5-6
@BOX 1.0
BIO.END.RUN()
@BOX 2.0
CLOSE ANY ACTIVE CHANNELS
[BSC27.11]
@BOX 3.0
RESELECT OLD OUTPUT AND
INPUT STREAMS
@BOX 4.0
RELEASE WORKING SEGMENTS
@BOX 5.0
JUMP TO PROGRAM EXIT LABEL
@BOX 6.0
END
@BOX 7.0
RESET SYSTEM ERROR
HANDLER TRAPS
@BOX 1.1
PROC BIO.END.RUN;
$IN SCRATCH.SEG.NO,I;
$LA EXIT.LABEL;
@BOX 2.1
-1 => LAST.PU;
BIO.CLOSE.ALL();
@BOX 3.1
SELECT.OUTPUT(C.OUT.STR);
SELECT.INPUT(C.IN.STR);
@BOX 4.1
BIO.EXIT.LABEL => EXIT.LABEL;
OLD.SEG.NO => SCRATCH.SEG.NO;
INTERCHANGE (DATA.SEG.NO, SCRATCH.SEG.NO);
RELEASE.SEGMENT (SCRATCH.SEG.NO);
@BOX 5.1
-> EXIT.LABEL;
@BOX 6.1
END
@BOX 7.1
SET.TRAP(0,TRAPS[0]);
SET.TRAP(5,TRAPS[5]);
SET.TRAP(8,TRAPS[8]);
@END
//16
@TITLE BSC21.3(1,11)
@COL 1S-12R-3R-10T-6R-7R-8T-13R-9F
@COL 11R
@ROW 7-11
@FLOW 1-12-3-10N-6-7-8N-13-9
@FLOW 10Y-11-13
@FLOW 8Y-9
@BOX 1.0
MONITOR (MESS.NO, PRINT)
@BOX 3.0
SELECT MONITORING STREAM
@BOX 6.0
OUTPUT ERROR MESSAGE
@BOX 7.0
RESELECT OLD OUTPUT STREAM
@BOX 8.0
NON-FATAL EXCEPTION?
@BOX 9.0
END
@BOX 10.0
SYSTEM ERROR WITHOUT
BASIC EXCEPTION CODE ?
@BOX 11.0
PRINT SYSTEM ERROR MESSAGE
@BOX 12.0
EXCEPTION MESSAGE DATAVECS
@BOX 13.0
RELEASE BIO SEGMENTS
ENTER BASIC RUN-TIME TRAP
@BOX 1.1
PROC MONITOR(M.NO, PRN);
$IN I, J, OLD.OP.STR, TYP,SCR.SEG;
$LO8 CH;
@BOX 3.1
CURRENT.OUTPUT() => OLD.OP.STR;
SELECT.OUTPUT (C.OUT.STR);
NEWLINES(0);
@BOX 4.1
@BOX 6.1
CAPTION(%"BASIC Exception ");
OUTI(EX.TYPE,0);
CAPTION(%" : ");
IF EX.STAT & %2 = 0 THEN
E.M.ST [M.NO & %FF => I] - 1 => J;
E.M.ST [I + 1] => I;
WHILE 1 +> J < I DO
   IF E.M [J] => CH = '@ THEN
      OUT.CH (SP => CH);
      CAPTION (EX.CAP);
   ELSE IF CH = '$$ THEN
         OUTCH(SP => CH);
         OUTI(EX.VAL,0);
         FI
   FI
   OUT.CH (CH);
OD;
ELSE
::NO ELSE CODE
FI
@BOX 7.1
NEWLINES(0);
SELECT.OUTPUT (OLD.OP.STR);
@BOX 8.1
IF EX.STAT & %1 /= 0
@BOX 9.1
END
@BOX 10.1
IF EX.STAT & %4 /= 0
@BOX 11.1
CAPTION(%"BASIC Implementation-defined Exception ");
OUTI(EX.TYPE,0);
CAPTION(%" : ");
OUT.M(SYS.CL,SYS.CD);
@BOX 12.1
DATAVEC E.M($LO8)
   #BSC21.3.1
   #BSC21.3.2
END
#BSC21.3.3
@BOX 13.1
SET.TRAP(0,TRAPS[0]);
SET.TRAP(5,TRAPS[5]);
SET.TRAP(8,TRAPS[8]);
::OLD.SEG.NO => SCR.SEG;
::INTERCHANGE(DATA.SEG.NO,SCR.SEG);
::RELEASE.SEGMENT(SCR.SEG);
ENTER.TRAP (6,200);
@END
//18
@TITLE BSC21.3.1(1,11)
@COL 1S
@BOX 1.0
DATAVECTOR OF EXCEPTION MESSAGES
FOR BASIC RUN-TIME SYSTEM

INTERNAL NUMBERS 0 - 49
@BOX 1.1
"Index$$in TAB < 1"
"Margin index$$< 1"
"Zonewidth index$$< 1"
"Mismatched sizes in numeric array expression"
"Argument of DET not a square matrix"
"Argument of INV not a square matrix" ::5
"Argument of IDN not a square matrix"
"Redimensioning error"
"Channel$$not in range 0 to 255"
"Channel ZERO specified in@"

::10
::11
::12
"Channel$$File@in OPEN already active"
"Channel$$File@in CLOSE already inactive"
"Unrecognisable file attribute in OPEN for File@" ::15
"Invalid record type specified"
"Illegal combination of attributes for File@"
"Record length < 0"
"Record setter not permitted on Channel 0"

"Record index < 1"  ::20
"Keyed files not implemented"
"Illegal key relation"
"Equals relation with NIL key string"
"File@on channel$$without record setter capability"
"File@on channel$$not OUTIN for ERASE"   ::25
"Too few data in input reply"
"Too many data in input reply"
"EOF encountered on input from File@"
"Illegal separator in input-reply from File@"

"Illegal character@in string from read/input"  ::30
"Exponent$$too large"
"Illegal symbol@in number"
"Overflow in evaluation of@constant"
::34
"Invalid DATA statement"  ::35
"Too few data in DATA list"
"Channel$$inactive"
"Attempt to set margin for non-output channel$$"
"Attempt  to set zonewidth for non-output channel$$"

"No format item in format string for output list"   ::40
"Incorrect mode for File@on channel$$"
"Arguments for DOT not vectors"
"Invalid dimensions specified for numeric array"
"Invalid file attribute specifier@"
"Time-out exceeded"  :: 45
"Stream file specified in SKIP REST"
"No more channels available"
"Index in LBOUND < 1"
"Index in LBOUND > dimensions"

@END
//17 16-JULY
@TITLE BSC21.3.2(1,11)
@COL 1S
@BOX 1.0
EXCEPTION MESSAGES 50 UPWARDS
@BOX 1.1
"Index in UBOUND < 1" ::50
"Index in UBOUND > dimensions"
"Index in SIZE < 1"
"Index in SIZE > dimensions"
"Attempted use of unimplemented I/O"
"Inactive channel$$in RESET"  ::55
"No operation since OPEN for File@on channel$$"
"Last operation for File@on channel$$was DELETE"
"Invalid format item@"
"Overflow in string datum for INPUT"

"Overflow in string datum for MAT INPUT" ::60
"Overflow in string datum for LINE INPUT"
"Overflow in string datum for MAT LINE INPUT"
::63
"String overflow in array assignment"
"Mismatched dimensionality in string-array-assignation" ::65
"Attempted division by zero in REM function"
"Invalid argument@in ORD"
"Invalid numeric argument to VAL"
"Numeric overflow in evaluation of VAL"

"Overflow in evaluation of Real constant"  ::70
"No streams available"
"Illegal stream name"
"Stream undefined"
"Incorrect type of stream"
"Incorrect type of document"  ::75
"Unable to open file"
"String overflow"
"Illegal numeric expression$$for time-expression"
"Square root of negative number"

"Illegal exponentiation"  ::80
"Logarithm of zero or negative number"
"Argument of ACOS or ASIN not in range -1 <= x <= 1"
"Record length exceeded on output to file"
"Type mismatch on INTERNAL input from File@"
"Overflow in string datum on input from File@"  ::85
"Syntactically incorrect input-reply from File@"
"Overflow in numeric datum on input from File@"
"Too few data in record on File@"
"Too many data in record on File@"

"@statement only allowed with DISPLAY files"  ::90
::CALLS TO THE FOLLOWING MESSAGES ARE PLANTED AT COMPILE TIME

"GOTO/GOSUB index out of range"  ::100
"RETURN without matching GOSUB"
"No case-block selected and no CASE ELSE"
@END
//16
@TITLE BSC21.3.3(1,11)
@COL 1S
@BOX 1.0
POSITIONS OF EXCEPTION MESSAGES IN DATAVECTOR
@BOX 1.1
$LI/$LO16 P0 = 0, P1 = P0 + 16, P2 = P1 + 16,
          P3 = P2 + 19, P4 = P3 + 44, P5 = P4 + 35,
          P6 = P5 + 35, P7 = P6 + 35, P8 = P7 + 20,
          P9 = P8 + 29, P10 = P9 + 26, P11 = P10,
          P12 = P11 , P13 = P12, P14 = P13 + 35,
          P15 = P14 + 38, P16 = P15 + 47, P17 = P16 + 29,
          P18 = P17 + 43, P19 = P18 + 17,
          P20 = P19 + 40, P21 = P20 + 16,
          P22 = P21 + 27, P23 = P22 + 20,
          P24 = P23 + 35, P25 = P24 + 48, P26 = P25 + 35,
          P27 = P26 + 27, P28 = P27 + 28, P29 = P28 + 35,
          P30 = P29 + 43, P31 = P30 + 43, P32 = P31 + 18,
          P33 = P32 + 24, P34 = P33 + 34, P35 = P34 + 0,
          P36 = P35 + 22, P37 = P36 + 25, P38 = P37 + 16,
          P39 = P38 + 45, P40 = P39 + 49,
          P41 = P40 + 47, P42 = P41 + 35, P43 = P42 + 29,
          P44 = P43 + 46, P45 = P44 + 33, P46 = P45 + 17,
          P47 = P46 + 34, P48 = P47 + 26, P49 = P48 + 19,
          P50 = P49 + 28, P51 = P50 + 19, P52 = P51 + 28,
          P53 = P52 + 17, P54 = P53 + 26, P55 = P54 + 34,
          P56 = P55 + 25, P57 = P56 + 44, P58 = P57 + 45,
          P59 = P58 + 20, P60 = P59 + 34, P61 = P60 + 38,
          P62 = P61 + 39, P63 = P62 + 43, P64 = P63 + 0,
          P65 = P64 + 35, P66 = P65 + 53, P67 = P66 + 42, P68 = P67+23,
          P69 = P68+31, P70 = P69+37, P71 = P70+39, P72 = P71+20, P73 = P72+19,
          P74 = P73+16, P75 = P74+24, P76 = P75+26, P77 = P76+19, P78 = P77+15,
          P79=P78+46, P80=P79+30, P81=P80+22, P82=P81+36, P83=P82+50, P84=P83+40
, P85=P84+42,
          P86=P85+44, P87=P86+46, P88=P87+45, P89=P88+31, P90=P89+32, P91=P90+42
,
          P92=P91, P93=P92, P94=P93, P95=P94, P96=P95, P97=P96,
          P98=P97,P99=P98,
          M0 = P99, M1 = M0 + 29, M2 = M1 + 29,M3=M2+39;

DATAVEC E.M.ST ($LO16)
P0  P1  P2  P3  P4  P5  P6  P7  P8  P9  P10
P11 P12 P13 P14 P15 P16 P17 P18 P19 P20
P21 P22 P23 P24 P25 P26 P27 P28 P29 P30
P31 P32 P33 P34 P35 P36 P37 P38 P39 P40
P41 P42 P43 P44 P45 P46 P47 P48 P49 P50
P51 P52 P53 P54 P55 P56 P57 P58 P59 P60
P61 P62 P63 P64 P65 P66 P67 P68 P69 P70
P71 P72 P73 P74 P75 P76 P77 P78 P79 P80
P81 P82 P83 P84 P85 P86 P87 P88 P89 P90
P91 P92 P93 P94 P95 P96 P97 P98 P99
M0 M1 M2 M3
END
@END
//14
@TITLE BSC21.4(1,11)
@COL 1S-2R-3R-6F
@FLOW 1-2-3-6
@BOX 1.0
BIO.EXCEPTION (MESS.NO)
Bit 8 of MESS.NO:
   = 0 Fatal exception
   = 1 Non-fatal exception
@BOX 2.0
DETERMINE EXTYPE [BSC21.3]
@BOX 3.0
SEARCH HANDLER STACK FOR
MOST RECENTLY ACTIVATED PROC
WITH EXCEPTION HANDLER
[BSC21.7]
@BOX 6.0
END
@BOX 1.1
PROC BIO.EXCEPTION (M.NO);
@BOX 2.1
0 => EX.STAT;
IF M.NO & %100 /= 0 THEN
   %1 => EX.STAT;
FI
EX.MAP[M.NO & %FF => G.EX.NO] => EXTYPE;
@BOX 3.1
NEXT.HANDLER(0);
@BOX 6.1
END
@END
///13
@TITLE BSC21.5(1,11)
@COL 1S-2T-3R-4R-5F
@COL 6R
@ROW 3-6
@FLOW 1-2N-3-4-5
@FLOW 2Y-6-5
@BOX 1.0
BIO.HANDLER()ID
@BOX 2.0
SCAN LINE.E TABLE :
EXCEPTION DID NOT OCCUR
WITHIN A PROTECTION BLOCK ?
@BOX 3.0
SET UP CONTROL ADDRESSES IN GLOBALS :
   RETRY
   CONTINUE
   PROTECTION-BLOCK-END
@BOX 4.0
RETURN EXCEPTION HANDLER I-D
@BOX 5.0
END
@BOX 6.0
SCAN HANDLER STACK FOR NEXT
ACTIVE PROC WITH HANDLER
[BSC21.7]
@BOX 1.1
PROC BIO.HANDLER;
$IN I, J, C.BLK, FOUND, L.Z;
@BOX 2.1
0 => P.BLK => C.BLK => FOUND;
-1 => I;
SELECT HANDLER.S[LAST.H];
SIZE(LINE) => L.Z;
WHILE FOUND = 0 AND 1+>I < L.Z DO
   SELECT LINE^[I];
   IF STRUC & %1 /= 0 THEN 1 +> P.BLK;
   ELSE IF STRUC & %2 /= 0 THEN 1 -> P.BLK;
   ELSE IF STRUC & %4 /= 0 THEN 1 +> C.BLK;
    ELSE IF STRUC & %8 /= 0 THEN 1 -> C.BLK;
    FI FI FI FI
   IF FAIL.ADDR >= L.ADDR < L.ADDR OF LINE^[I+1] THEN
      1 => FOUND;
   FI
OD
IF FOUND = 0
@BOX 3.1
I => J;
L.NO OF LINE^[I] => EXLINE;
L.ADDR OF LINE^[I=>FAIL.I] => RETRY.ADDR;
IF C.BLK /= 0 THEN
   WHILE STRUC OF LINE^[J] & %8 = 0 DO 1 +> J OD;
ELSE
   1 +> J;
FI
L.ADDR OF LINE^[J] => CONTINUE.ADDR;
I => J;
WHILE STRUC OF LINE^[J] & %2 = 0 DO 1 +> J OD;
L.ADDR OF LINE^[J] => EXIT.ADDR;
@BOX 4.1
H.ID OF LINE^[I] => BIO.HANDLER => C.HID;
@BOX 5.1
END
@BOX 6.1
NEXT.HANDLER(1);
@END
///13
@TITLE BSC21.6(1,11)
@COL 1S-2T-3R-4F
@COL 5R
@ROW 3-5
@FLOW 1-2N-3-4
@FLOW 2Y-5-4
@BOX 1.0
BIO.EXIT.HANDLER()NEW.ID
@BOX 2.0
NESTED PROTECTION BLOCK ?
@BOX 3.0
SCAN HANDLER STACK FOR NEXT
ACTIVE PROC WITH HANDLER
[BSC21.7]
@BOX 4.0
END
@BOX 5.0
RETURN I-D OF ENCLOSING
PROTECTION BLOCK
@BOX 1.1
PROC BIO.EXIT.HANDLER;
$LO8 FOUND;
@BOX 2.1
IF P.BLK > 1
@BOX 3.1
NEXT.HANDLER(1);
@BOX 4.1
END
@BOX 5.1
0 => FOUND;
SELECT HANDLER.S[LAST.H];
WHILE FOUND=0 AND 1->FAIL.I >= 0 DO
   IF STRUC OF LINE^[FAIL.I] & %8 /=0 THEN
      1 => FOUND;
   FI
OD
H.ID OF LINE^[FAIL.I] => C.HID
   => BIO.EXIT.HANDLER;
@END
///16
@TITLE BSC21.7(1,11)
@COL 1S-2T-7T-8T-9R-6R-10R-3R-4F
@COL 5R
@ROW 3-5
@FLOW 1-2N-7N-8N-9-6-10-3-4
@FLOW 2Y-5-4
@FLOW 7Y-6
@FLOW 8Y-5
@BOX 1.0
NEXT.HANDLER(POS)ID
   POS = 0 Search from top of handler stack
        = 1 Search from (top-1) of handler stack
@BOX 2.0
SCAN HANDLER STACK FOR NEXT
ACTIVE PROC WITH EXCEPTION HANDLER
NOT FOUND ?
@BOX 3.0
JUMP TO EXCEPTION PROCESSING
CODE FOR THIS PROC
@BOX 4.0
END
@BOX 5.0
MONITOR EXCEPTION AND TERMNATE
EXECUTION IF FATAL
@BOX 6.0
GET FAILING ADDRESS
@BOX 7.0
AT TOP OF STACK?
@BOX 8.0
NON-FATAL EXCEPTION ?
@BOX 9.0
ADD 10000 TO EXTYPE
IF NECESSARY
@BOX 10.0
RESET ANY BIO DATA STRUCTURES
IN USE
@BOX 1.1
PROC NEXT.HANDLER(POS);
$LA H.LAB;
$IN FOUND,H;
@BOX 2.1
LAST.H => H;
0 => FOUND;
WHILE FOUND = 0 AND H >= 0 DO
   IF LINE OF HANDLER.S[H] /= NIL.L THEN
      1 => FOUND
   ELSE
      1 -> H;
   FI
OD
IF FOUND = 0
@BOX 3.1
H => LAST.H;
-> H.LAB;
@BOX 4.1
END
@BOX 5.1
MONITOR(G.EX.NO, 1);
@BOX 6.1
LAB OF HANDLER.S[H] => H.LAB;
GET.LINK(H.LAB) => FAIL.ADDR;
@BOX 7.1
IF POS /= 1
@BOX 8.1
IF EX.STAT & %1 /= 0
@BOX 9.1
IF EXTYPE > 1000 < 100000 THEN
   100000 +> EXTYPE
ELSE
   IF EXTYPE < 0 THEN 100000 -> EXTYPE
FI
FI
@BOX 10.1
-1 => LAST.I => LAST.O;
@END
///14
@TITLE BSC21.8(1,11)
@COL 6R
@COL 1S-2T-3T-7R-4R-5F
@ROW 6-7
@FLOW 1-2N-3N-7-4-5
@FLOW 2Y-6-4
@FLOW 3Y-6-4
@BOX 1.0
BIO.CAUSE(EX.NO)
@BOX 2.0
EX.NO < 1000
(IE APPLICATION DEFINED)?
@BOX 3.0
SEARCH MAP FOR CORRESPONDING
INTERNAL BIO EXCEPTION NO
NOT FOUND?
@BOX 4.0
SEARCH HANDLER STACK FOR
MOST RECENTLY ACTIVATED PROC WITH
EXCEPTION HANDLER [BSC21.7]
@BOX 5.0
END
@BOX 6.0
NOTE UNKNOWN BIO EX NO
@BOX 7.0
NOTE BIO EX NO
@BOX 1.1
PROC BIO.CAUSE(B.EX);
$IN I,FND;
@BOX 2.1
IF B.EX => EXTYPE < 1000
@BOX 3.1
-1 => I => FND;
WHILE FND < 0 AND 1 +> I < EX.MAP.Z DO
   IF EX.MAP[I] = B.EX THEN
      1 => FND
   FI
OD
IF FND < 0
@BOX 4.1
NEXT.HANDLER(0);
@BOX 5.1
END
@BOX 6.1
%2 => EX.STAT;
@BOX 7.1
I => G.EX.NO;
0 => EX.STAT;
@END
///14
@TITLE BSC21.9(1,11)
@COL 1S-10R-2T-3T-4R-11N-5F
@COL 8R-9R
@COL 6T
@ROW 3-6
@ROW 11-8
@FLOW 1-10-2N-3N-4-11-5
@FLOW 2Y-6N-4
@FLOW 6Y-8-9-5
@FLOW 3Y-8
@BOX 1.0
BIO.TRAP(CLASS.CODE)
@BOX 2.0
CLASS 0 ERROR ?
@BOX 3.0
DETERMINE CORRESPONDING
BASIC EXCEPTION CODE
NOT FOUND ?
@BOX 4.0
CAUSE EXCEPTION
[BSC21.8]
@BOX 5.0
END
@BOX 6.0
DETERMINE CORRESPONDING
BASIC EXCEPTION CODE
NOT FOUND ?
@BOX 8.0
NOTE SYSTEM ERROR
@BOX 9.0
CALL NEXT HANDLER
[BSC21.7]
@BOX 10.0
SYSTEM MESSAGE -> BASIC EXCEPTION DATAVECS
@BOX 1.1
PROC BIO.TRAP(E.CL,E.CD);
$IN S,F,FND,EX;
@BOX 2.1
IF E.CL = 0
@BOX 3.1
C.I[E.CL] => S;
C.I[E.CL+1] => F;
0 => FND;
WHILE FND = 0 AND S < F DO
   IF T[S] = E.CD THEN
      1 => FND
   ELSE
      2 +> S;
   FI
OD
IF FND = 1 THEN
   T[S+1] => EX
FI
IF FND = 0
@BOX 4.1
0 => EX.STAT;
BIO.CAUSE(EX);
@BOX 5.1
END
@BOX 6.1
::TBC
IF E.CL=E.CL
@BOX 8.1
E.CL => SYS.CL;
E.CD => SYS.CD;
E.CL * 1000 + E.CD -: 0 => EXTYPE;
%4 => EX.STAT;
@BOX 9.1
NEXT.HANDLER(0);
@BOX 10.1
#BSC21.9.1
@END
///14
@TITLE BSC21.9.1(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
DATAVEC OF SYSTEM ERROR CODES AND
CORRESPONDING BASIC EXCEPTION NOS
@BOX 2.0
POSITION LITERALS
@BOX 3.0
END
@BOX 1.1
DATAVEC T($LO16)
   ::CLASS 0
   ::CLASS 1
   ::CLASS 2
   ::CLASS 3
   ::CLASS 4
   ::CLASS 5
2 8301  ::CLASS 6
   ::CLASS 7
11 3005  12 3002  14 3004  15 3007  16 3007 ::CLASS 8
   ::CLASS 9
END
@BOX 2.1
$LI/$LO16 C0 = 0, C1 = C0, C2 = C1, C3 = C2, C4 = C3,
          C5 = C4,C6 = C5, C7 = C6+2, C8 = C7, C9 = C8+10,
          C10 = C9;

DATAVEC C.I($LO16)
C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  C10
END
@BOX 3.1
::END
@END
///18
@TITLE BSC21.10(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
CHAN.EXCEPTION(MESS.NO,CHAN.I)
@BOX 2.0
GET DOCUMENT NAME FOR CHAN
[BSC27.23]
AND CALL BIO.EXCEPTION
@BOX 3.0
END
@BOX 1.1
PROC CHAN.EXCEPTION(M.NO,CHAN.I);
@BOX 2.1
BIO.FILE.NAME(CHAN.I) => EX.CAP;
G.CHAN.NO => EX.VAL;
BIO.EXCEPTION(M.NO);
@BOX 3.1
END
@END
