Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/nml/nmum11.m11
There are no other files named nmum11.m11 in the archive.
.TITLE NMUM11 - NMU MCB Specific Assembly Functions
.IDENT /X01070/
.ENABLE LC ;Lower Case Please!!
;
; COPYRIGHT (c) 1980, 1981, 1982
; DIGITAL EQUIPMENT CORPORATION
; Maynard, Massachusetts
;
; This software is furnished under a license and may be used
; and copied only in accordance with the terms of such license
; and with the inclusion of the above copyright notice. This
; software or any other copies thereof may not be provided or
; otherwise made available to any other person. No title to
; and ownership of the software is hereby transferred.
;
; The information in this software is subject to change
; without notice and should not be construed as a commitment
; by DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL assumes no responsibility for the use or reliability
; of its software on equipment which is not supplied by
; DIGITAL.
;
;
;++
;
; FACILITY: LSG DECnet Network Management
;
; ABSTRACT:
;
; This module contains all system specific assembly routines necessary
; for support of common NML routines.
;
; ENVIRONMENT: MCB V3.x
;
; AUTHOR: Scott G. Robinson CREATION DATE: 29-DEC-80
;
; MODIFIED BY:
;
; 01 - Ensure Saving of all important registers
; 02 - Change SS$MSG to SS.MES
; 03 - Increase dynamic storage
; 04 - Add 32-bit utility routines $ADD32, $SUB32, and $SGN32.
; 05 - Whoops! the word meanings were reversed!
; 06 - Set up *full* stack in SS$TNI.
; Remove MEMSIZ to variable at MEMTOP.
; 07 - Reduce size of allocatable memory from 10000. to 9980.
;
;--
.SBTTL MACRO Definitions
;
; System Macro Calls
;
.MCALL ALUN$S,QIOW$S
;
; System Symbol Definitions
;
; NETDF$
;
; Local Macro Definitions
;
; PUSH and POP macros are used to manipulate elements onto and
; from the stack.
;
.MACRO PUSH ARG
.IRP A,<ARG>
.IF NB A
MOV A,-(SP) ;Push A onto stack
.IFF
CLR -(SP) ;Allocate a 0 word
.ENDC
.ENDM
.ENDM PUSH
.MACRO POP ARG
.IRP A,<ARG>
.IF NB A
MOV (SP)+,A ;Pop A off stack
.IFF
TST (SP)+ ;Remove word from stack
.ENDC
.ENDM
.ENDM POP
;
.SBTTL Local Data Definitions
;
; NMU Task Block for MCB Environments:
;
.globl TB.STK,TB.CTX,TB.STR
;
.PSECT $OWN$,D
;
; Tasking State Variables
;
CURTSK:: .WORD 0 ;Currently executing Thread
PRVTSK:: .WORD 0 ;Previously executing Thread
SAVESP:: .WORD 0 ;Temporary for current SP
SAVER0:: .WORD 0 ;Temporary for current R0
;
; The entire free space is kept in PSECT $$COR$
;
; The memory allocation algorithm needs to know what the
; highest location allocated is. MEMTOP is both the highest address
; that can be allocated and a variable pointing to available memory.
;
.PSECT $$COR$,D
MEMBOT::.BLKW 9980.
MEMTOP::.WORD MEMBOT
;
INTNST:: .WORD 0 ;Interrupt nesting count
;
.SBTTL SS$CTX - Switch Tasks Contrxt
.PSECT $CODE$,I,RO
;++
; global routine SS$CTX(NEXT_TASK) : novalue
;
; FUNCTIONAL DESCRIPTION:
;
; SS$CTX saves the current task context in its TASK_BLOCK
; and starts up another task from the NEXT_TASK BLOCK.
; All registers are saved and restored when switching among
; tasks.
;
; FORMAL PARAMETERS:
;
; NEXT_TASK - the next TASK_BLOCK to schedule
;
; IMPLICIT INPUTS:
;
; CURTSK - the currently running TASK_BLOCK
; Misc locations in the TASK_BLOCKs
;
; IMPLICIT OUTPUTS:
;
; PRVTSK - set to the previous CURTSK
; CURTSK - set to NEXT_TASK
; Misc locations in the TASK_BLOCK
;
; COMPLETION CODES:
;
; None
;
; SIDE EFFECTS:
;
; None - all this is by design
;
;--
SS$CTX:: ;Switch Task Context
MOV R0,SAVER0 ;Preserve R0
MOV CURTSK,R0 ;Save CURTSK and determine validity
MOV R0,PRVTSK ;
BNE 10$ ;Valid so save context
MOV 2(SP),R0 ;Setup NEXT_TASK in R0
BR 20$
10$: MOV SAVER0,R0 ;Restore R0
JSR R1,SAVALL ;Save important registers on current stack
MOV PRVTSK,R0 ;Return R0 to CURRENT_TASK
MOV SP,TB.CTX(R0) ;Save context SP
MOV 16.(SP),R0 ;Get NEXT_TASK BLOCK address
20$: MOV TB.CTX(R0),SP ;Setup new context
MOV R0,CURTSK ;Setup Current Task
;---------------------------------
; Debugging code
;
.GLOBL SS.MES,TB.NAM
MOV #TB.NAM,-(SP) ;Print out Task Name
ADD R0,(SP)
JSR PC,SS.MES
MOV #CRLF,(SP)
JSR PC,SS.MES
TST (SP)+
;---------------------------------
RTS PC ; and return to it
CRLF: .byte 15,12,0,0
;
.SBTTL SS$TNI - NMU Task Initialization
; .PSECT $CODE$
;++
; global routine SS$TNI(TASK_BLOCK, STACK_SIZE) : novalue
;
; FUNCTIONAL DESCRIPTION:
;
; SS$TNI initializes the task block for execution. It
; only initializes the stack.
;
; FORMAL PARAMETERS:
;
; TASK_BLOCK - the task block address
; STACK_LENGTH - the length of the task stack
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; Misc locations in the TASK_BLOCK
;
; COMPLETION CODES:
;
; None
;
; SIDE EFFECTS:
;
; None - all this is by design
;
;--
.GLOBL US.FIN
SS$TNI:: ;Initialize the task block
PUSH <R0,R1> ;Save destroyed registers
MOV SP,SAVESP ;Save current stack pointer
MOV 8.(SP),R1 ;R1 = TASK_BLOCK
MOV 6.(SP),R0 ;R0 = Size of task stack in words
ASL R0 ;R0 = Size of task stack in bytes
ADD #TB.STK,R0 ;R0 = Tasks Stack Offset
ADD R1,R0 ;R0 = Task Block Stack Top
MOV R0,SP ;; New Stack pointer Setup
MOV #US.FIN,-(SP) ;; Trap cases of task exit
MOV TB.STR(R1),-(SP);; Push starting address
JSR R1,SAVALL ;; Save Context
MOV SP,TB.CTX(R1) ;; Save Context pointer
MOV SAVESP,SP ;Restore original context
POP <R1,R0> ;Restore original registers
RTS PC ;Exit
;
.SBTTL SAVALL - Save All Registers
; .PSECT $CODE$
;++
; JSR R1,SAVALL
;
; FUNCTIONAL DESCRIPTION:
;
; SAVALL saves R0-R5 onto the stack.
;
; FORMAL PARAMETERS:
;
; None
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; None
;
; COMPLETION CODES:
;
; None
;
; SIDE EFFECTS:
;
; None
;
;--
SAVALL: PUSH <R2,R3,R4,R5,R0,R1> ;Real R1 is already on Stack
; R1 just saved is return address
MOV 12.(SP),R1 ;Restore Real R1
JSR PC,@(SP)+ ;Call ourselves as Co-Routine
POP <R0,R5,R4,R3,R2,R1> ;Restore all registers
RTS PC
;
.SBTTL SS$FIN - NMU Task Exiting Processing
; .PSECT $CODE$
;++
; global routine SS$FIN : novalue
;
; FUNCTIONAL DESCRIPTION:
;
; SS$TNI initializes the task block for execution. It
; only initializes the stack.
;
; FORMAL PARAMETERS:
;
; TASK_BLOCK - the task block address
; STACK_LENGTH - the length of the task stack
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; Misc locations in the TASK_BLOCK
;
; COMPLETION CODES:
;
; None
;
; SIDE EFFECTS:
;
; None - all this is by design
;
;--
NMU$FA:: ;!!!!TEMPORARILY !!!!
IOT ;Blow up for now!
RTS PC ;Exit
;
.SBTTL SS$COR - Allocate another block from MEMBOT
;++
; global routine SS$COR(AMOUNT)
;
; FUNCTIONAL DESCRIPTION:
;
; SS$COR allocates AMOUNT of memory from the memory pool and updates
; MEMTOP to reflect that allocation.
;
; FORMAL PARAMETERS:
;
; AMOUNT - the amount of memory to allocate
;
; IMPLICIT INPUTS:
;
; MEMTOP - the current top of memory
;
; IMPLICIT OUTPUTS:
;
; MEMTOP - updated to reflect the allocation
;
; Routine Value:
;
; Address of beginning of memory block or
; 0 if the AMOUNT is unavailable
;
; SIDE EFFECTS:
;
; None
;
;--
; .PSECT $CODE$,I,RO
.GLOBL $SAVE5
SS$COR:: ;Try to allocate a block of memory
JSR R1,$SAVE5 ;Save a few registers
MOV 14.(SP),R1 ;AMOUNT to R1
MOV MEMTOP,R0 ;Current top of memory to R0
ADD R0,R1 ;Add in amount of allocation
INC R1 ;Round to Word Boundary
BIC #1,R1 ;..
CMP #MEMTOP,R1 ;Are we over memory?
BHI 10$ ;No, so update allocation
CLR R0 ;Yes, set return Value
RTS PC ; and Exit
10$: MOV R1,MEMTOP ;Set new top of memory
;R0 is start of block
RTS PC ;Exit
;
.SBTTL $ADD32 - Add two 32 bit numbers
;++
; linkage ADD = jsr (register = 0, register = 1);
; global routine $ADD32 (VAL1 : vector [2], VAL2 : vector [2]) : ADD
;
; FUNCTIONAL DESCRIPTION:
;
; This routine performs VAL2 = .VAL2 + .VAL1
;
; FORMAL PARAMETERS:
;
; VAL1 - address of 32-bit value
; VAL2 - address of 32-bit value
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; None
;
; Routine Value:
;
; None
;
; SIDE EFFECTS:
;
; None
;
;--
; .PSECT $CODE$,I,RO
.GLOBL $SAVE5
$ADD32:: ;Add two 32 bit numbers
ADD (R0)+,(R1)+
ADC (R1)
ADD (R0),(R1)
CMP -(R0),-(R1)
RETURN
;
.SBTTL $SUB32 - Subtract two 32 bit numbers
;++
; linkage SUB = jsr (register = 0, register = 1);
; global routine $SUB32 (VAL1 : vector [2], VAL2 : vector [2]) : SUB
;
; FUNCTIONAL DESCRIPTION:
;
; This routine performs VAL2 = .VAL2 - .VAL1
;
; FORMAL PARAMETERS:
;
; VAL1 - address of 32-bit value
; VAL2 - address of 32-bit value
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; None
;
; Routine Value:
;
; None
;
; SIDE EFFECTS:
;
; None
;
;--
; .PSECT $CODE$,I,RO
.GLOBL $SAVE5
$SUB32:: ;Sub two 32 bit numbers
SUB (R0)+,(R1)+
SBC (R1)
SUB (R0),(R1)
CMP -(R0),-(R1)
RETURN
;
.SBTTL $SGN32 - Return sign of 32 bit number
;++
; linkage SGN = jsr (register = 1);
; global routine $SGN32 (VAL : vector [2]) : SGN
;
; FUNCTIONAL DESCRIPTION:
;
; This routine returns SIGN (.VAL)
;
; FORMAL PARAMETERS:
;
; VAL - address of 32-bit value
;
; IMPLICIT INPUTS:
;
; None
;
; IMPLICIT OUTPUTS:
;
; None
;
; Routine Value:
;
; -1 if .VAL lss 0
; 0 if .VAL eql 0
; +1 if .VAL gtr 0
;
; SIDE EFFECTS:
;
; None
;
;--
; .PSECT $CODE$,I,RO
.GLOBL $SAVE5
$SGN32:: ;Get sign of 32 bit number
CLR R0
TST 2(R1)
BLT 20$
BGT 10$
TST (R1)
BEQ 30$
10$: INC R0
RETURN
20$: DEC R0
30$: RETURN
;
;
.END