PAGE 80,132
.XLIST
;This file contains macros for use in subroutine calling
;Adapted from R. Startz' book, p.90
;
	TEMP_COUNT=0
PUSHTEMP MACRO	TO_BE_PUSHED,NAME_TO_USE  ;Push temporary value
	TEMP_COUNT=TEMP_COUNT+1
	PUSH	TO_BE_PUSHED
IFNB	<NAME_TO_USE>
	NAME_TO_USE=-2*TEMP_COUNT
ENDIF
	ENDM
;
;
POPTEMP	MACRO	TO_BE_POPPED	;Pop value from stack
IF	TO_BE_POPPED
	ADD	SP,2*(TO_BE_POPPED)
	TEMP_COUNT=TEMP_COUNT-(TO_BE_POPPED)
ENDIF
	ENDM
;
;
external MACRO routinelist
LOCAL	arg
	IRP	arg,<routinelist>
	EXTRN	arg:FAR
	ENDM
	ENDM
;
;
segdef	MACRO
;Segment definition according to Microsoft FORTRAN Powerstation
	.386P
_BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS	ENDS
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
_CONST	SEGMENT DWORD USE32 PUBLIC 'DATA'
_CONST	ENDS
_DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA	ENDS
	ENDM
;
;
subroutine MACRO	subname,codeseg,argumentlist
LOCAL	argloc,arg,arglength
;Count arguments
	argcount=0
	IRP	arg,<argumentlist>
	argcount=argcount+1
	ENDM
;Compute location of argument address
	arglength=4
	argloc=2+arglength*argcount
	IRP	arg,<argumentlist>
	arg=argloc
	argloc=argloc-arglength
	ENDM
;Start
	PUBLIC	subname
codeseg SEGMENT BYTE	PUBLIC	'CODE'
subname	PROC	FAR
	ASSUME CS:codeseg,DS:DGROUP,SS:DGROUP,ES:DGROUP
	PUSH	BP
	MOV	BP,SP
	PUSHTEMP SI
	PUSHTEMP DI
	PUSHTEMP DS
	ENDM
;
;
return	MACRO	subname,codeseg
	TEMP_COUNT=TEMP_COUNT-3
	POP	DS
	POP	DI
	POP	SI
	POP	BP
	RET	4*argcount
subname ENDP
codeseg	ENDS
.ERRNZ	TEMP_COUNT
	ENDM
;
;
calll	MACRO	reg,sub,argumentlist
LOCAL	arg
;Count arguments
	argcount=0
	IRP	arg,<argumentlist>
	MOV	reg,SEG arg
	PUSH	reg
	MOV	reg,OFFSET arg
	PUSH	reg
	ENDM
	CALL	FAR PTR sub
	ENDM
;
;
getvar	MACRO	dest,src
        LES     SI,DWORD PTR [BP+src]
        MOV     dest,ES:[SI]
	ENDM
;
;
putvar	MACRO	dest,src
        LES     SI,DWORD PTR [BP+dest]
        MOV     ES:[SI],src
	ENDM
;
;
getvar1	MACRO	dest,src
        LES     SI,DWORD PTR [BP+src]
	MOV	AL,ES:[SI]
        MOV     dest,AL
	ENDM
;
;
putvar1	MACRO	dest,src
        LES     SI,DWORD PTR [BP+dest]
	MOV	AL,src
        MOV     ES:[SI],AL
	ENDM
;
;
getvar2	MACRO	dest,src
        LES     SI,DWORD PTR [BP+src]
	MOV	AX,ES:[SI]
        MOV     dest,AX
	ENDM
;
;
putvar2	MACRO	dest,src
        LES     SI,DWORD PTR [BP+dest]
	MOV	AX,src
        MOV     ES:[SI],AX
	ENDM
;
;
getvar4	MACRO	dest,src
        LES     SI,DWORD PTR [BP+src]
	MOV	AX,ES:[SI]
        MOV     dest,AX
	MOV	AX,ES:[SI+2]
        MOV     dest+2,AX
	ENDM
;
;
putvar4	MACRO	dest,src
        LES     SI,DWORD PTR [BP+dest]
	MOV	AX,src
        MOV     ES:[SI],AX
	MOV	AX,src+2
	MOV	ES:[SI+2],AX
	ENDM
;
;
shrtadr MACRO	long,ix,iy,nx,off
;Compute short address of 2-D array element
	MOV	AX,iy
	DEC	AX
	MUL	nx
	ADD	AX,ix
	DEC	AX
	REPT	long-1
	SHL	AX,1
	ENDM
	ADD	off,AX
	ENDM
;
;
longadr	MACRO	long,ix,iy,nx,seg,off,ladlab
;Compute long address of 2-D array element
	MOV	AX,iy
	DEC	AX
	MUL	nx
	DEC	ix
	ADD	AX,ix
	ADC	DX,0
	INC	ix
	REPT	long-1
	CLC
	RCL	AX,1
	RCL	DX,1
	ENDM
	ADD	AX,off
	ADC	DX,0
	JZ	ladlab
	MOV	CL,12
	SHL	DX,CL
	MOV	CX,seg
	ADD	CX,DX
	MOV	seg,CX
ladlab:	MOV	off,AX
	ENDM
.LIST

FLAT	GROUP _TEXT, _BSS, _CONST, _DATA
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
