Google
 

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