*************************************************************************
*                                                                       *
*   This is the SLIB library for Tripos on the  M68000                  *
*                                                                       *
*   Modifications:                                                      *
*                                                                       *
*   1 June 82:  First implementation by Martin Richards (at CERN)       *
*   24 Apr 83:  MR    Installed at Cambridge                            *
*                                                                       *
*************************************************************************

*
* Symbol definitions and data structures
*

LIBWORD EQU     23456                   Marks library routines
SECWORD EQU     12345                   Marks a BCPL section

ROOT    EQU     $400                    MC addr of the Tripos root node

CRNTSK  EQU     ROOT+$C
DBPMODE EQU     ROOT+$60
DBPCODE EQU     ROOT+$68

T_PXHAND EQU    44                      Private exception handler (or 0)

INTSON  EQU     $2000                   Supervisor state, level 0
A_UNUSEDTRAP EQU 75                     UNEXPECTED "TRAP"

*
* Register definitions
*
Z       EQUR    A0                      Constant Zero
P       EQUR    A1                      BCPL frame pointer
G       EQUR    A2                      BCPL global pointer
L       EQUR    A3                      Temp reg in save/rtn routines
B       EQUR    A4                      Addr of current routine
S       EQUR    A5                      Save routine addr
R       EQUR    A6                      Return addr
SP      EQUR    A7                      System stack pointer
*
*
        PAGE
*
* Global vector symbols
*
G_ENTER EQU     87*4                    ENTER

        RORG    $0
*
SLIB    DC.L    (SEND-SLIB)/4
        DC.L    SECWORD
        DC.B    17,'SLIB    24-Apr-82',0,0
*
*
        PAGE
*************************************************************************
*                                                                       *
*               RES  :=  ENTER(REGS)                                    *
*                                                                       *
*       ENTER is a BCPL callable function that allows arbitrary         *
* programs to be executed in user state from a Tripos task.             *
* The complete set of machine registers (D0-D7, A0-A6, USP, SR and PC)  *
* are taken from the vector REGS.  ENTER returns, if the user           *
* program executes any of the TRAPSs 1-12, 14-15, returning the         *
* the trap number as result and the user registers in REGS.             *
* If the user program faults in any other way, the standard             *
* Tripos debugging aid is entered, thus allowing for instance           *
* the standard break point and single stepping facilities to            *
* work.                                                                 *
*                                                                       *
*************************************************************************

R_S     EQU     52                      Position of user reg A5
R_R     EQU     56                                  user reg A6
R_USP   EQU     60                                  user reg USP
R_SR    EQU     66                                  user reg SR
R_PC    EQU     68                                  user reg PC

        CNOP    0,4
        DC.L    LIBWORD
        DC.B    7,'Enter  '

ENTER   MOVEM.L G/S/R,4(P)              Preserve the BCPL environment
        MOVEA.L CRNTSK,R
        ADDA.L  R,R
        ADDA.L  R,R                     R = MC addr of CRNTCB
        LEA.L   ENTER1,S
        MOVE.L  S,T_PXHAND(R)           Private exception handler
        MOVEA.L D1,S
        ADDA.L  S,S
        ADDA.L  S,S                     S = MC addr of user regs

        MOVE.L  P,-(SP)                 Preserve BCPL P pointer
        MOVE.L  R_PC(S),-(SP)           Prepare for RTE
        MOVE.W  R_SR(S),-(SP)
        MOVEA.L R_USP(S),R
        MOVE.L  R,USP                   Set the user USP

        MOVEM.L (S),D0-D7/Z-R           and D0-D7, A0-A6

        RTE                             Now enter the user program

        PAGE
*
*    ENTER1 is the entry point of the private exception handler.
* It is called from CALLDBG in KLIB if an exception is
* encountered while running at level 0 and the PXHAND field of the
* current TCB is non zero.  This field holds the entry point
* of the private exception handler.
*
* On entry:  S  = MC address of the handler
*            R  = MC addr of the current TCB
*            SP = MC addr of an area containing the following:
*                       the return link to the kernel,
*                       the old value of S,
*                       the old value of R,
*                       the old value of SR,
*                   and the old value of PC.
*
* From this state executing RTS will re-enter CALLDBG and
* cause the standard exception handling, however the handler
* may choose to handle the exception itself and not return
* via CALLDBG.
*
        PAGE
ENTER1  MOVEA.L DBPMODE,S               S = DBPKT mode
        CMPA.L  #1,S
        BNE.S   ENTER2                  J if not mode 1 (aborts)
        MOVEA.L DBPCODE,S               S = DBPKT code
        CMPA.L  #A_UNUSEDTRAP,S
        BNE.S   ENTER2                  J if not "unexpected TRAP"
        CLR.L   T_PXHAND(R)             Clear provate X handler

        MOVEA.L 18(SP),S                S = BCPL stack pointer
        MOVEA.L (S),R                   R = BCPL first argument
        ADDA.L  R,R
        ADDA.L  R,R                     R = MC addr of user regs

        MOVEM.L D0-D7/Z-B,(R)           Dump the user regs D0-D7, A0-A7
        MOVE.L  4(SP),R_S(R)                     user reg A5
        MOVE.L  8(SP),R_R(R)                     user reg A6
        MOVE.L  USP,Z
        MOVE.L  Z,R_USP(R)                       user reg USP
        MOVE.W  12(SP),R_SR(R)                   user reg SR
        MOVEA.L 14(SP),L
        MOVE.L  L,R_PC(R)                        user reg PC
        LEA.L   22(SP),SP               Correct the system SP

        MOVE.W  #INTSON,SR              Change to level 0
        MOVEA.L S,P                     P = BCPL stack pointer
        MOVEM.L 4(P),G/S/R              Restore the BCPL environment
        SUBA.L  Z,Z

        MOVE.W  -2(L),D1                Calculate the TRAP number
        ANDI.L  #15,D1                  D1 = the TRAP number

        JMP     (R)                     Standard BCPL return

ENTER2  RTS                             Re-enter tripos CALLDBG

*
* Global initialisation list
*
        CNOP    0,4
        DC.L    0                       The end of the list
        DC.L    G_ENTER/4,(ENTER-SLIB)
        DC.L    G_ENTER/4               Highest referenced global
SEND    END






