;
; Code generated by version NS16000:147
; and then hand edited
; This module must be the last loaded in an image
; in order to define the first free address for the heap area

; Author:   Mick Jordan 
; LastEdit:   "Tue Jul 10 14:37:58 1984"
;             19 Oct 84 19:08:27   : Change of SYSTEM_EXIT for panos
   MODULE SYSTEM
;
   EXPORTC   SYSTEM__SYSTEM
   EXPORTC   SYSTEM_TRANSFER
   EXPORTC   SYSTEM_NEWPROCESS
   EXPORTC   SYSTEM_ENDPROG
   EXPORTC   SYSTEM_EXIT
   EXPORTC SYSTEM_M2TRAP
   IMPORTC TrapHandler_Trap = 'TrapHandler'.'Trap'
   IMPORTC Program_Stop = 'Program'.'Stop'

   MACRO
   Bodge      %Modname
   EXPORTC    %Modname.__%Modname.
   EXPORT     %Modname._1 , %Modname._2
   AREA       SYSTEM_code_frame
%Modname.__%Modname.
   AREA       SYSTEM_data_frame
%Modname._1
%Modname._2
   MEND


   AREADEF SYSTEM_data_frame, [DATA], DOUBLE
   AREA SYSTEM_data_frame
   EXPORT SYSTEM__D
SYSTEM__D
   DEFSB   SYSTEM__D
   ADDRESS   SYSTEM__T
   ADDRESS   SYSTEM__S
   DCD   #X80000000
CPR   EQU   12
   DCD   0      ; current PROCESS
LPR   EQU   16
   DCD   0      ; save area for initial process

SYSTEM__S
   AREADEF SYSTEM_code_frame, [CODE, READ], DOUBLE

   AREA SYSTEM_code_frame
SYSTEM__C

;----------------------------------------------------------------------
; Hand coded procedures exported by the compiler from SYSTEM

; Process handling
; offsets from base of process stack frame
FPSAVE    EQU   0;         ; holds FP when not active
; following set up be NEWPROCESS in pseudo stack frame
; from which to return on first call of TRANSFER
USERPROC    EQU    -4      ; initial procedure descriptor
MODPSR      EQU   -16
PCSLOT      EQU   -20      ; initialsed to STARTPROCESS
FPSLOT      EQU   -24      ; initial FP (zero)

; Entry point to PROCEDURE NEWPROCESS
; Parameters: P: 12(FP)  A: 16(FP)  n: 20(FP)
;            new: 24(FP)  
SYSTEM_NEWPROCESS
   ENTER [],0
   MOVD 16(FP), R0
   ADDD 20(FP), R0         ; word beyond workspace
   ADDQD =-4, R0         ; last word
   MOVD R0, 0(24(FP))      ; set process variable
   ADDR STARTPROCESS, PCSLOT(R0)   ; initial start address
   MOVD 12(FP), USERPROC(R0)   ; user start proc descriptor
   MOVQD =0, FPSLOT(R0)
   SPRD MOD, MODPSR(R0)      ; same module as this
   ADDR FPSLOT(R0), FPSAVE(R0)   ; set initial FP
   EXIT []
   RXP 16

; Entry point to PROCEDURE TRANSFER
; Parameters: 
; VAR source: 12(FP)  VAR destination: 16(FP)  
; save dedicated registers R4-R7
SYSTEM_TRANSFER
   ENTER [R4,R5,R6,R7],0      ;
   SPRD FP, FPSAVE(CPR(SB))   ; save FP of current process
   MOVD 0(16(FP)), R0       ; get new process
   MOVD CPR(SB), 0(12(FP))    ; source := current
   MOVD R0, CPR(SB)      ; current := new
   LPRD FP, FPSAVE(CPR(SB))   ; update frame pointer
   ADDR -16(FP), R0      ; prepare to restore 4 registers
   LPRD SP, R0         ; 
   EXIT [R4,R5,R6,R7]      ;
   RXP 8

; control comes here on first TRANSFER to a new process.
; The user procedure descriptor is at 0(SP).
; If the process returns the program is terminated
STARTPROCESS
   CXPD 0(SP)
   SPRD MOD,TOS      ; on return exit
   BSR  SYSTEM_EXIT

;---------------------------------------------------------------
; Hand coded procedures not exported by the compiler from SYSTEM

; Entry point to PROCEDURE ENDPROG

SYSTEM_ENDPROG
   ENTER [],0      ;   14 (@000E): 
   ADDR SYSTEM__S,R0
   EXIT []      ;   20 (@0014): 
   RXP 0      ;   22 (@0016): 

; Entry point to PROCEDURE EXIT

SYSTEM_EXIT
   ADJSPB      =-8            ; Return to the caller's caller.
   MOVQD       =0 , R0
   RXP         8

; SYSTEM_M2TRAP
; control comes here via a CXP from the trap handler in the module
; in which the trap occurred.
; Arguments:-
; 12(FP) : trap code
; 16(FP) : the PC in the procedure at fault.
; This code transfers to TrapHandle_Trap, faking it to look
; like a direct call from 16(FP)

SYSTEM_M2TRAP
   ENTER [], 0      ; creates a frame
   MOVD 16(FP), 4(FP)   ; set true return address
   LPRD FP, 0(FP)      ; restore user FP
   MOVZWD TDESC, R0   ; module number for 'Trap'
   MOVZWD TDESC+2, R1   ; procedure offset for 'TrapHandler'
   MOVD R0, 0(SP)      ; set up for an RXP
   ADDD 8(R0), R1      ; full address of 'TrapHandler'
   MOVD R1, TOS
   RXP 0         ; go there!
; Entry point to MODULE SYSTEM
; initialisation code.
; set up a dummy process so that first TRANSFER is ok

SYSTEM__SYSTEM
L24   ENTER [],0      ;   24 (@0018): 
   ADDR LPR(SB), CPR(SB)
   EXIT []      ;   27 (@001B): 
   RXP 0      ;   29 (@001D): 

   AREADEF   SYSTEM_code_table, [DATA, READ], DOUBLE
   AREA   SYSTEM_code_table
   
TDESC
   CDESC   TrapHandler_Trap
   

SYSTEM__T
   CDESC   SYSTEM__SYSTEM
   CDESC   SYSTEM_TRANSFER
   CDESC   SYSTEM_NEWPROCESS
   CDESC   SYSTEM_ENDPROG

   Bodge   DecodeArg
   Bodge   Convert
   Bodge   Store
   Bodge   IO
   Bodge   File
   Bodge   Loader
   Bodge   Random
   Bodge   TimeAndDate
   Bodge   Handler
   Bodge   GlobalString
   Bodge   Program
   Bodge   Error
   Bodge   Messages
   Bodge   Command

   AREA    SYSTEM_code_frame

   RXP     0




   END
