












				MEGAMACROS

			Version 6, August 16, 1990


		                REMMEL LABS

			    26 Bay Colony Dr.

		        Ashland, MA USA 01721-1840

			  Phone:  508-881-5086
This instruction manual is in file M.TXT. An editor may be used to
search the file, e.g., search for .SIN to find out about sin(x).

		TABLE OF CONTENTS

Chap. 1.  Introduction

Chap. 2.  Assembly and linking

Chap. 3.  Data types and addressing modes

Chap. 4.  Input/output Megamacros
    A. Terminal Megamacros
    B. Print Megamacros
    C. Disk Megamacros

Chap. 5.  Internal conversion Megamacros

Chap. 6.  Move-bit Megamacro

Chap. 7.  Math Megamacros

Chap. 8.  Complex Megamacros

Chap. 9.  Fast Fourier Transform (FFT)

Chap. 10.  Signal Processing Megamacros

Chap. 11.  Vector and Matrix Megamacros

Chap. 12.  String Megamacros

Chap. 13.  Extended memory Megamacros

Chap. 14.  Floating point error Megamacro

Chap. 15.  Hewlett-Packard plotter Megamacros

Chap. 16.  VT125/240/330/340 and Matrox GT600 Graphics Megamacros

Chap. 17.  Day (date) Megamacro

Chap. 18.  Use of Megamacros with FORTRAN and PASCAL

App. 1.  Modifying the library

App. 2.  Megamacro and subroutine linkage convention
Chap. 1.  INTRODUCTION

An assembly-language Megamacro is like a subroutine, function, or
procedure in a high-level language. The Digital Equipment Corp. (DEC)
supplies macros for simple terminal or disk input/output, but for little
else. Examples of DEC macros:
				.EXIT,  .TTYOUT,  .READW

There are, however, no macros for typing out an integer, writing a
floating-point number to disk, or printing a string. The assembly
language programmer must write special subroutines.

Now this problem is solved!  These macros are called MEGAMACROS because
they do all the functions that one does with a high-level language, and
more. Examples:
	.T10	I		type integer I to screen
	.W0F	F		write floating-point F to disk
	.PS	#S		print string S on printer
	.PEEKF	F,A		read floating-point F from extended memory
	.INVM	#A,#B,#7  	invert 7X7 matrix A
	.PARS	#A,#B,#TERM,R0	parse string A (separate into components)
	.FFT	#Z,#10.,#-1	complex fast Fourier transform
	.MULZ	#Z1,#Z2,#Z3	complex multiply,  Z3 = Z1*Z2

An assembly-language program will execute typically 3 times faster then
FORTRAN or PASCAL. In assembly language the bits can mean anything we
want. An assembly language program can control input/output devices in
real time, with interrupts, at the theoretical speed limit of the
computer. Now the assembly-language programmer can also do the higher
functions for which FORTRAN was invented!

Sample programs are included:
SORT.MAC	sorts integers
SORTS.MAC	sorts strings into alphabetical order
DISKT.MAC	disk input/output
FFT.PAS		PASCAL fast Fourier transform (FFT) algorithm
FFTEST.MAC, FFTEST.FOR, AND FFTEST.PAS	tests FFT Megamacro
MEMT.MAC	tests extended memory addressing
SCRIBE.MAC	plots text
DEMO.MAC	demonstrates MACRO-11 plotting procedures
DEMO.PAS	demonstrates PASCAL plotting procedures
DEMO.FOR	demonstrates FORTRAN plotting procedures
TESLA.MAC	plots electronic circuits
BESSEL.MAC	calculates and plots Bessel functions
EQST.MAC, EQST.FOR, EQST.PAS   tests linear equations Megamacro
INVT.MAC, INVT.FOR, INVT.PAS   tests matrix inversion Megamacro

The Megamacros were originally written as subroutines for research and
for my Boston Univ. course, Computer as a Laboratory Instrument. The
many needed subroutines made linking a chore. The Megamacros resulted
from the organizaion of all those subroutines. Extensive comments are
included to help students understand the programs.
							Ron Remmel
Chap. 2. ASSEMBLY AND LINKING WITH MEGAMACROS

Make one or more backup copies of the disk:

	COPY/DEV DY0: DY1:

The two essential files are M.MLB (Megamacros) and L.OBJ (subroutine
library). Copy these files to your system disk.

Assembly:	MAC URFILE+M/LIB

Linking:	LINK URFILE,L

Non-essential files: The Megamacros are defined in file M.MAC. The .MAC
source files for all library subroutines are included, so that the user
may modify them, if desired (App. 1).

Every Megamacro and subroutine save all registers and accumulators on
the stack and restore them to their original values. This is in contrast
with most DEC macros such as .PRINT, which use R0 for passing numbers,
thus causing the naive user's program to bomb.
Chap. 3. DATA TYPES AND ADDRESSING MODES

B	byte
I	16-bit integer
F	real or floating-point (32 bits)
L	32-bit long integer
Z	64-bit complex (two floating-point numbers, real first)
M	address of matrix (1, 2 or 3-dimensional array of real; Chap. 10)
S	address of a string
V	3-dimensional vector
BK	address of a disk block of 1000 octal bytes

DEC calls the accumulators R0..5, which are easily confused with the
registers. The Megamacros also accept accumulator names A0..5.
At the beginning of the program, the user should define:

	A0=R0
	A1=R1	etc.

Use of other symbols for accumulators may give erratic results, i.e.,

	FREQ=R3
	.TF	FREQ

The Megamacros do floating-point calculations in single-precision
(32-bit) mode and 16-bit integer mode. The floating-point processor must
be in single-precision mode (SETF instruction) and 16-bit integer mode
(SETI) before a Megamacro is executed.

For Megamacros involving bytes, integers, long integers, real, and complex
numbers, the VALUE of that number is required. For example:

	.TF	X	;type real X
	.ADDZ	A,B,C	;add complex  C = A + B

The ADDRESS of a string, matrix or block must be furnished. For example:

	.PS	#ALPHA		;print string ALPHA

All addressing modes work for all data types.  Examples:

.PB	#15		;print carriage return (ASCII 15)

.K10	(R3)+		;input a decimal number from keyboard, stores it in
			;the location pointed to by R3, and autoincrements

.W2S	4(R5)		;write a string addressed by 4(R5) to disk channel 2

.MOVF	(SP)+,66(R5)	;move real numbers as MOV moves integers

.SQRT	A0,@ARRAY+26(R5) ;store SQRT of accum. A0 where directed

.POWR	X+14,@R2,-(SP)	;raise the real number at location X+14
			;to the real power at the address pointed to by R2
			;and pushes the real result onto the stack
Chap. 4. INPUT/OUTPUT MEGAMACROS

The input/output devices are:
	K	keyboard input
	T 	type to screen
	P	printer
	R0	read from disk file on channel 0
	W3	write to disk file on channel 3
	PEEK	read from extended memory
	POKE	write to extended memory
	XMTB	transmit byte to plotter

           TABLE 1:  INPUT/OUTPUT MEGAMACROS

|-CONVERSION TO/FROM ASCII---| |------BINARY TRANSFER-----------------------|

   KEYBOARD SCREEN PRINT PLOT  DISK-READ  DISK-WRITE  MEMORY   EXTENDED-MEMORY
                              CHANNEL 0  CHANNEL 0               READ    WRITE
BYTE    .KB   .TB  .PB         .R0B       .W0B        MOVB     .PEEKB  .POKEB

INTEGER .K2   .T2  .P2 
        .K8   .T8  .P8         .R0I       .W0I        MOV      .PEEKI  .POKEI
        .K10  .T10 .P10

REAL    .KF   .TF  .PF   .LBF  .R0F       .W0F       .MOVF     .PEEKF  .POKEF

LONG    .KL2  .TL2 .PL2  ...... use real Megamacros to transfer 4 bytes.......
INTEGER .KL8  .TL8 .PL8

VECTOR        .TV

MATRIX  .KM   .TM  .PM         .R0M       .W0M       .MOVM      .PEEKM .POKEM

STRING  .KS   .TS  .PS   .LBS  .R0S       .W0S       .MOVS
  QUICK       .TSQ .PSQ  .LBSQ            .W0SQ

LINE    .KL   .TL  .PL   .LBL  .R0L       .W0L       .MOVS
  QUICK       .TLQ .PLQ  .LBLQ            .W0LQ

COMPLEX .KZ   .TZ  .PZ         .R0Z       .W0Z       .MOVZ     .PEEKZ  .POKEZ

DISK BLOCK                     .R0BK      .W0BK


5A. TERMINAL MEGAMACROS

All typing Megamacros call .TB, which uses the DEC .TTYOUT macro. Quick
Megamacros containing a Q transmit the string contained within the angle
brackets. Examples: 

		.TS	#SS		;TYPES HI
		.TSQ	<HI>		;TYPES HI
		.TL	#SS		;TYPES HI CARRIAGE RETURN, LINE FEED
		.TLQ	<HI>		;TYPES HI CARRIAGE RETURN, LINE FEED
		...
	SS:	.ASCIZ	*HI*

.TL is the same as .TS, except that a carriage return and line feed are
typed. If .TL is used without a string, only the CR-LF is typed. The
.PS, .PSQ, W0S and .W0SQ Megamacros do the same thing for the printer
and disk.

The following Megamacros work for VT100 and above terminals. The screen
has 24. rows and 80. columns.  1<= ROW<= 24  and  1 <=COL<= 80.
Row 1 is at the tope, and column 1 is at the left.

.CD	N	move cursor down N spaces. If N omitted, move 1 space.
		Cursor stops at row 24 if moved too far (no error message)

.CL	N	move cursor left N spaces

.CMOV	ROW,COL	move cursor to (ROW,COL)

.CNEX		moves cursor to beginning of next line

.CPOS	ROW,COL,BYTE  after a key typed, reports present cursor position
		and the typed character BYTE. This Megamacro puts the
		terminal I/O into the realtime mode (see above), so that
		each keystroke causes a cursor report.

.CR	N	move cursor right N spaces

.CU	N	move cursor up N spaces

.DWL		for line where cursor is, make letters double width. The
		rightmost letters will fall off screen.

.E		erase display (not graph). Cursor put at (24,1) (lower left)

.EL		erase line where cursor is

.ELL		erase line under & left of cursor; leave cursor in column 1

.ELR		erase line under and to right of cursor

.KPS		make keypad keys transmit special editting characters for
		VT100 and above
		key	ASCII	OCTAL BYTES
		0	ESC Op	33,117,160
		1	ESC Oq	33,117,161
		2	ESC Or	33,117,162
		3	ESC Os	33,117,163
		4	ESC Ot	33,117,164
		5	ESC Ou	33,117,165
		6	ESC Ov	33,117,166
		7	ESC Ow	33,117,167
		8	ESC Ox	33,117,170
		9	ESC Oy	33,117,171
		,	ESC Ol	33,117,154
		-	ESC Om	33,117,155
		.	ESC On	33,117,156
		ENTER	ESC OM	33,117,115
		PF1	ESC OP	33,117,120
		PF2	ESC OQ	33,117,121
		PF3	ESC OR	33,117,122
		PF4	ESC OS	33,117,123

.KPN		make keypad keys transmit normal characters shown on keys

.RIS		resets terminal to initial state (when power turned on)

.SWL		makes letters single width on line where cursor is (default)


5B. PRINT MEGAMACROS

The print Megamacros send bytes directly to the printer, bypassing the
operating system. Interrupts are not used. A tab (ASCII 11) is
automatically replaced by spaces, and a form feed (ASCII 14) by line
feeds, for use with primitive printers such as the LA34. The printer
should be connected at address RCSR=176500; this value can be changed by
editing file PRINT.MAC, and updating the library (App. 1). Four globals
permit adjusting the printout for each printer:

.LENTH	Page length. Default is 66 (6 lines/inch on 11 inch paper).

.LINES  Number of lines to be printed on each page.  55 is a good
	number for manuscripts.  The default is 66.

.MARG	Number of spaces in left margin. Default is zero.

.TOPMG	Number of blank lines of top margin. Default is zero.

The print Megamacros will not work under TSX; instead, the program can
produce a disk file, which can then be printed.

When debugging a program, we often have trouble finding where the error
occurred. A standard debugging technique is to put type statements at
strategic locations in the program. However, this technique often fails
because characters from a type statement are stored in a buffer in the
operating system until the terminal can accept them. If the program
bombs right after the type statement, some characters will be lost.
The print Megamacros do not have this problem, because all characters are
printed before program execution resumes. Use .PB and .PS for debugging!


5C. DISK MEGAMACROS

Program DISKT.MAC demonstrates these disk Megamacros. Up to 4 disk files
may be opened simultaneously on channels 0..3. A channel may be closed
and reopened for a different file, so that hundreds of files may be
accessed sequentially.

To only read file S on channel 2:			.READ2	#S

To create and write file S on channel 1:		.WRIT1	#S
This file may be read also.

String S specifies the file name:	S:	.ASCIZ	*DL1:TEST.DAT*

If the S argument is absent from the Megamacro call, the computer
prompts the user to type the file name.

All bytes of a write file are initially set to zero.

To close a written file on channel 1, use the .CLOS1 Megamacro. As far
as the disk directory is concerned, the file does not exist until .CLOS1
is executed. The last partially-filled output block is always written to
the disk; the undefined bytes of that block contain whatever garbage was
there originally. It is not necessary to close a read-only file (DEC
macro .CLOSE #1 may be used to close channel 1 so that that channel may
be reused).

When a read Megamacro reads beyond the end of the file, the C-bit is
set. When a write Megamacro attempts to write beyond the end of the
file, that file is closed and the program terminates.

The disk read-line Megamacro .R1L ignores carriage returns (ASCII 15),
and treats a line feed (12) or form feed (14) as the end of the string.
If there are two successive line feeds, the string will have no bytes.
When a form feed is encountered, this string is returned: 14,0. For
.R1L, a zero byte is interpreted as the end-of-file, and the C-bit is
set.

The .R0S Megamacro works similarly to the .PARS Megamacro.

	.R0S	S,TERMIN

S is the address where the string is to be put. TERMIN is the address
of a string of terminators. Characters are read from the disk until one
of the characters in the TERMIN string is encountered. Any terminators
at the beginning of the string are discarded. A zero byte is treated
as the end of file.

.PT0 is a global, 32-bit integer indicating the number of bytes from the
start of the file, and functions like an array pointer. The disk
actually reads and writes data in blocks of 2**9 (octal 1000) bytes,
starting with block zero. Let the following be the 32-bit integer P:

P = BBBBBBBBBBBBBBBBBBBBBBBAAAAAAAAA   BLOCK NUMBER= BBBBBBBBBBBBBBBBBBBBBBB
    |  P   ||  P+1 ||  P+2 ||  P+3 |   BYTE NUMBER IN BLOCK =	AAAAAAAAA
              BYTE NUMBER

The most significant 16 bits are at address .PT0, while the least
significant bits are at .PT+2. After each read/write, .PT0 is
incremented by the appropriate amount (autoincrement) .PT0 may be
changed at any time for random access to the file. On writing, only
those bytes which are explicity written are defined; the other bytes
contain whatever garbage was left on the disk.

The following Megamacros read or write a whole block of 1000 octal bytes
at a time, and thus are faster than the other disk Megamacros.

.R0BK	#BUFFER,BLOCK

.W0BK	#BUFFER,BLOCK

BUFFER is an array of 1000 octal bytes, which the user must supply.
Use the DEC macro .CLOSE #0 to close the file.
Chap. 5. INTERNAL CONVERSION MEGAMACROS

Internally all numbers are stored in binary. For input from and output
to the terminal or printer, the following Megamacros convert numbers
from or to a string of bytes.

.CVFS	F,S		;real F to string S

.CVIS	I,S,#10.	;integer I to string S, radix 10.

.CVL2S	L,S		;long integer L to string S, radix 2

.CVL8S	L,S		;long integer L to string S, radix 8

.CVSI	S,I,#8.		;string S to integer I, radix 8

.CVSF	S,F		;string S to real F

.CVSL2	S,L		;string S to long integer L, radix 2

.CVSL8	S,L		;string S to long integer L, radix 8

For the .CVIS and .CVSI Megamacros, binary, octal, and decimal (2, 8,
10) are the permitted radices.
Chap. 6.  MOVE BIT MEGAMACRO

	.MOVBT	A,NA,B,NB,NBITS

This Megamacro moves NBITS from the array at address A, starting at the
NAth bit, to the array at address B, starting with the NBth bit. NA and
NB are unsigned 16-bit integers.
Chap. 7. MATH MEGAMACROS

.ACOS	Z,A		A = arccos(Z)   0 < A < pi

.ASIN	Z,A		A = arcsin(Z)   -pi/2 < A < pi/2

.ATAN2	Y,X,A 		A =arctan(Y/X)    -pi < A < pi

.AVDEV	X,N,AV,SD	average AV and standard deviation SD of N-dimensional
			array X

.BINOM	N,M,B		real B = binomial coeff. = N! / (M! * (N-M)!)
			for N > 130, B sometimes overflows

.CMPL	L1,L2		compare long integers; sets condition codes

.COS	A,Z		Z = cos(A)
							    X
.ERR	X,Y		error function: Y=2*SQRT(1/pi)* integral EXP(-u**2) du
							    0
			ERR (0)         = 0
			ERR (infinity)  = 1
			ERR (-infinity) = -1	odd function
			By C. Hastings, Approximations for Digital Computers,
			Princeton Univ. Press, Princeton, NJ 1955, p. 187

.EXP	X,Y		Y = exp(X)

.FACT	I,F		real F = I! factorial for integer I

.GAMMA	P,Y		gamma function. See GAMMA.MAC

.LN	X,Y		Y = ln(X) to base e

.LOG	X,Y		Y = log(X) to base 10

.LOG2	X,Y		Y = log(X) to base 2

.MIN  F,XLO,XHI,XMIN,I  XMIN is returned as that X which minimizes F over the
			range XLO-->XHI. User must define the F(X) subroutine:
				Location F: entry point
				Location F-4: real X
				Location F-10: F(X)
			Only one minimum is found; it is possible that the
			minimum is XLO or XHI.  I (optional) specifies the
			number of iterations; the accuracy is 1 part in 2**I.
			If I=20(default), the accuracy is 1 part in 1,000,000.
			If I=10, the accuracy is about 1 part in 1000, but the
			program takes half the time as when I=20.
	***The user's F subroutine must save registers and accumulators***


.MONTE	F,INTEG,N,LO1,HI1,LO2,HI2,LO3,HI3,LO4,HI4,LO5,HI5,LO6,HI6
			Does a Monte Carlo integration of the user-supplied
			function whose entry point is F. The answer is INTEG.
			N is the number of events to be generated. If X1 is
			the first variable, then LO1-->X1-->HI1 is the range
			over which X1 is to be integrated. The ranges of up to
			6 variables are optional.
			User must define the F(X) subroutine:
				Location F: entry point
				Location F-4: output of function
				Location F-10: X1 input
				Location F-14: X2 input etc. (optional)		

.NORM	X,Y		integral of normal Gaussian probability distribution
						   X
			Y = SQRT( 1/(2*pi) ) * integral  EXP(-u**2/2) du
					       -infinity
			NORM (-infinity) = 0
			NORM (infinity)  = 1
			NORM (0)         = 0.5

.OFSET	N,I,DI,J,DJ,K,DK   gives offset N in bytes from start of a real array
			1 dimension:   N=I*4		J,DJ,K,DK omitted
			  range of subscript I must be 0..DI-1
			2 dimensions:  N=(I*DJ+J)*4         K,DK omitted
			  range of subscript J must be 0..DJ-1
			3 dimensions:  N=((I*DJ+J)*DK+K)*4
			  range of subscript K must be 0..DK-1
Usually N will be a register. To fetch the element A[1,2,3] of the
array whose dimensions are 5x6x7, for instance, use the following:
	.OFSET	R0,#1,#5,#2,#6,#3,#7
	LDF	A(R0),A3
.OFSET may be used either for fetching or storing.

.POLY	X,N,A,P		evaluates polynomial of degree N with coeff. array A.
			P = A[0]*X**0 + A[1]*X**1 +...+ A[N]*X**N

.POWI	X,N,Y		Y=X**N;  X & Y are real, N is any integer

.POWII	I,J,K		K = I**J for integers I,J,K

.POWR	X,Y,Z		Z = X**Y for X, Y and Z real

.RAND	X		real X is a random number between 0 and 1
			globals .IRN and .JRN are seeds (between 0 and 1E7),
			which determine where the "random" sequence begins.

.RANDS	X		shuffles the numbers produced by .RAND in order
			to remove correlations, but takes more computer time

.RANOR	X		X is a Gaussian-distributed random number with mean=0
			and SD=1.  .RANOR calls .RAND

.ROOT	F,XLO,XHI,XZERO	XZERO is returned for which F(XZERO) = 0 over the
			range XLO-->XHI. User must define F(X) subroutine:
			Location F: entry point
			Location F-4: real X
			Location F-10: F(X)
			Only 1 root is returned. C-bit is set if no root.
	***The user's F subroutine must save registers and accumulators***

.SETRA			use radians for trigonometry (the default)

.SETDE			use degrees for trig calculations, including .PHASZ

.SIN	A,Z		Z = sin(A)

.SQRT	X,Y		Y = sqrt(x)

.TAN	A,Z		Z = tan(A)

.TSTL	L		test long integer and set condition codes
Chap. 8. COMPLEX MEGAMACROS

A complex number Z is an array of two floating-point numbers, real part
first, then the imaginary part. A complex number is passed by VALUE
(like bytes, integers, and floating-point numbers), not by ADDRESS (like
strings and matrixes). Complex numbers may only reside in memory, not
in registers or accumulators.

.ABSZ	Z,F		;real F = |Z| = sqrt(Z[1]**2 + Z[2]**2)

.ADDZ	Z1,Z2,Z3	;Z3 = Z1 + Z2

.CLRZ	Z		;Z = 0

.DIVZ	Z1,Z2,Z3	;Z3 = Z1/Z2

.EQSZ	A,B,N		;like .EQSM, but solves complex eqs.

.EXPZ	Z1,Z2		;Z2 = exp(Z1)

.MULZ	Z1,Z2,Z3	;Z3 = Z1*Z2

.PHASZ	Z,A		;real A = phase angle of Z = arctan(Z[2]/Z[1])

.POWZ	Z1,N,Z2		;Z2 = Z1**N, N any integer

.RECZ	Z1,Z2		;Z2 = 1/Z1 reciprocal

.SUBZ	Z1,Z2,Z3	;Z3 = Z1 - Z2

Because a complex number is actually an array of two elements, the real
and imaginary parts, the matrix Megamacros can be used for complex
matrixes. To type out complex array A of 3 rows and 4 columns, use:

	.TM	#A,#3,#4,#2
Chap. 9.  FAST FOURIER TRANSFORM (FFT)

The file FFT.PAS contains the PASCAL procedure FFT, and a description of
the slow and fast Fourier transforms. See standard texts such as A.V.
Oppenheim and A.S. Willsky, Signals and Systems, Prentice-Hall,
Englewood Cliffs, NJ.

The programs FFTEST.MAC, and FFTEST.FOR demonstrate the .FFT Megamacro
for the respective languages.

These definitions are useful for the FFT:
LAYER 	= number of layers
M	= number of points = 2**LAYER
DT	= sampling interval in sec
T	= M*DT = total sampling period
F	= 1/DT = sampling freq. in Hz
DF	= 1/T = freq. step size in Hz
NYQ	= M/2 = number of the Nyquist-freq. point
FNYQ	= Nyquist freq. = 0.5*F Hz
j	= SQRT(-1)
W	= EXP(2*PI*j/M)

Normally the FFT is done on a complex array Z with M = 2**LAYER points,
where LAYER is a small integer. The .FFT Megamacro is:

.FFT	Z,LAYER,SIGN	;SIGN=-1 for forward transform, +1 for reverse
Chap. 10. SIGNAL PROCESSING MEGAMACROS

A digital computer can filter a physical signal, which was sampled at time
intervals DT, for example, by an analog-to-digital converter. As far as
this digital filter is concerned, the input is simply an array of real
numbers:
			X[0], X[1], X[2] ..

The output array is:	Y[0], Y[1], Y[2] ..

In analogy with linear electronic filters, the most useful digital
filters are linear, that is, if the signal sequence

	X1{0] ..		has output Y1[0] .., and if

	X2[0] .. 		has output Y2[0] ..,

then the filter is linear if the signal

	A*X1[0] + B*X2[0] ..	has output A*Y1[0] + B*Y2[0] ..

for arbitrary constants A and B.

The pure time delay is the simplest digital filter, for which the output
now equals the input N time steps earlier. For example, for N = 10:

input:	 1  2  3  4  5  6  7  8  9 10 11 12 13 14
output:  0  0  0  0  0  0  0  0  0  0  1  2  3  4

	.MACRO	.DELAY	X,Y,N

At the present time, the input is the real number X, while the output is
Y. X and Y are not arrays. The .DELAY macro must be put in a loop; each
time through the loop, the Megamacro stores the present X, and moves the
Nth preceding input into Y. N must be a positive integer (not #5). The
above input/output sequence was produced by this program:

A0=R0		;SAMPLE PROGRAM FOR .DELAY MEGAMACRO
A1=R1
GO:	LDF	#1,A0
LOOP:	.DELAY	A0,A1,10.
	.TF	A0
	.TF	A1
	.TQ
	ADDF	#1,A0
	JMP	LOOP

Butterworth filters are optimally-smooth lowpass filters to remove
high-frequency noise, or high-pass filters to remove the DC and low
frequency components. Program BUTEST.MAC tests the Butterworth filters
for step inputs. This program describes how to make digital filters
corresponding to an analog filter whose transfer function is known. The
derivations of the following filters are also given:

.BUTL1	X,Y,DT,FC	1st-ORDER LOWPASS		X = INPUT NOW
.BUTL2	X,Y,DT,FC	2nd-ORDER LOWPASS		Y = OUTPUT NOW
.BUTL4	X,Y,DT,FC	4th-ORDER LOWPASS		DT = INTERSAMPLE TIME
.BUTH1	X,Y,DT,FC	1st-ORDER HIGHPASS		FC = CUTOFF FREQ IN Hz

Filter time constant = TAU = 1/Wc = 1/(2*pi*Fc), where Wc is the cutoff
frequency in radians/s. The Megamacro must be put into a loop as shown below:

	.MCALL	.BUTL4	X,Y,DT,FC
	MOV	#X,R1
	MOV	#Y,R2
	MOV	#1000.,R0
LOOP:	.BUTL4	(R1)+,(R2)+,DT,FC
	SOB	R0,LOOP
	HALT
DT:	.FLT2	1E-3		;sec
FC:	.FLT2	2		;2 Hz = CORNER FREQ.
X:	.BLKW	2*1000.		;X CONTAINS THE INPUT POINTS
Y:	.BLKW	2*1000.		;Y WILL CONTAIN THE FILTERED POINTS

A bandpass filter can be made with lowpass and highpass filters.
Chap. 11. VECTOR AND MATRIX MEGAMACROS

The following Megamacros operate on 3-dimensional vectors:

.ABSV	#A,X			X = SQRT(Ax**2 + Ay**2 + Az**2), length of A

.ADDV	#A,#B,#C		C-vector = A + B

.CLRV	#A			A-vector = 0

.CROSV	#A,#B,#C		C = cross product of A and B. #A, #B & #C are
				vectors with 3 components

.DOTV	#A,#B,X			Scalar X = dot product of A and B vectors

.MOVV	#A,#B			B-vector = A

.MULV	#A,X,#B			B-vector = X-constant * A-vector

.SUBV	#A,#B,#C		C-VECTOR = A - B

A matrix may have 1, 2 or 3 dimensions. The matrix Megamacro must have
enough arguments to define the matrix size. The input/output matrix
Megamacros in Table 1 must also have their dimensions defined in the
same way. Examples:

.CLRM	#A,#7	    		clear 7 elements of 1-dimensional matrix A

.ADDM	#X,#Y,#Z,#4,#7		Z = X + Y for 4x7 matrixes

.SUBM	#B,#C,#D,#4,#3,#2	D = B - C for 4x3x2 matrixes

For the 3-dimensional matrix D above, the elements are stored in memory:

D[1,1,1], D[1,1,2], D[1,2,1], D[1,2,2],D[1,3,1], D[1,3,2], D[2,1,1] etc.

Matrixes are typed and printed in the same order that they are stored.
The following Megamacros operate only on 2-dimensional matrixes.
Rectangular matrixes have dimension ROWxCOL; square matrixes are NxN.

.DETM	M,N,DET			determinant DET of square matrix M

.EQSM	A,B,N			solve N linear eqs. in N unknowns. A is an
				NxN matrix. B is 1xN. Answer appears in B.
	**** A- AND B-MATRIXES ARE DESTROYED ****
				Programs EQST.MAC and 	EQST.FOR
				demonstrate use of .EQSM

.INVM	A,AI,N			NxN matrix AI is inverse of A
	**** A- AND B-MATRIXES ARE DESTROYED ****

.TRANM	A,NROW,NCOL		transposes NROWxNCOL A-matrix to
				NCOLxNROW A-matrix. Answer is in A-matrix

.MULM	A,I,J,K,B,L,M,N,C	matrix multiplication: C = A*B

The A-matrix has dimension IxJxK, and B has dimensions LxMxN. If a
matrix has fewer than 3 dimensions, put in #1 for the missing
dimensions. One and only one of I, J or K must be a negative number, and
one of L, M or N must be negative, in order to indicate that the sum of
the products will be taken over these two indices.

Example 1:	.MULM	#A,#2,#-3,#1,#B,#-3,#4,#1,#C
		...
	A:	.FLT2	1,2,3		;2X3 matrix
		.FLT2	4,5,6
	B:	.FLT2	7,8,9,10	;3X4 matrix
		.FLT2	11,12,13,14
		.FLT2	15,16,17,18
	C:	.BLKB	4*2*4		;C must of course be 2*4

The two #-3 numbers must be identical, of course. The computer calculates
similarly to the following PASCAL program:

FOR I:= 1 TO 2 DO
	FOR K:= 1 TO 4 DO
		BEGIN
		C[I,K]:= 0;
		FOR J:= 1 TO 3 DO  C[I,K]:= C[I,K] + A[I,J]*B[J,K];
		END;

Example 2:	.MULM	#X,#-2,#3,#4,#Y,#5,#-2,#1,#Z

X has dimension 2x3x4.  Y has dimension 5x2.  Thus Z will be 3x4x5. The
PASCAL equivalent is:

FOR J:= 1 TO 3 DO
	FOR K:= 1 TO 4 DO
		FOR L:= 1 TO 5 DO
			BEGIN
			Z[J,K,L]:= 0;
			FOR I:=1 TO 2 DO Z[J,K,L]:=Z[J,K,L] + X[I,J,K]*Y[L,I];
			END;

Example 3:	.MULM	#P,#2,#3,#-1,#Q,#-1,#1,#1,#R
		...
	P:	.FLT2	1,2,3	;2x3x1 matrix, that is, 2x3
		.FLT2	4,5,6
	Q:	.FLT2	2	;1 dimensional with one element (a scalar)
	R:	.BLKB	4*2*3	;2x3 matrix

This instruction multiplies matrix P by scalar 2.
Chap. 12. STRING MEGAMACROS

.CAPS	S		;changes all lower-case letters to capitals

.CMPS	A,B		;compares the alphanumeric order of strings A and B,
			;and sets condition codes for EQ, LT or GT

.COMBS	A,B,C		;combines strings A and B into string C

.FINDS	A,B,ADDR	;searches string A for first occurence of string B.
			;ADDR=address of found string. C-bit set if not found.

.LONGS	S,L		;L = length of string S

.MOVS	A,B		;move A to B. The instruction .MOVS #A,#A+1 will
			;correctly move string A over one byte.

.REPLS	A,B,C,ADDR	;finds first occurence of string B in string A and
			;replaces string B with C.
			;ADDR = address of found string (optional)
			;C-bit set if not found.

.SMALS	S		;changes all capital letters to small

.TRUNS	A,L		;truncates string A to length L. If the string is
			;shorter than L, it is padded with spaces.

.VALS	S1,S2		;Checks for valid bytes in string S1. If any byte in
			;S1 is not in S2, the C-bit is set.

.PARS	A,B,TERM,ADDR ;Parses string A (splits into component parts).
The string TERM consists of one or more characters which are called
terminators. Each byte from string A is examined; the byte is skipped if
it is a terminator. When a non-terminator is encountered, that and
subsequent bytes are moved to string B, until a terminator byte is
encountered. A zero byte is then put at the end of the B-string. The
program continues to examine the A-string, skipping terminators, until
it finds a non-terminator, whose address is returned in ADDR. A string
of null length (just a zero byte) is returned if no string was found.
The terminators of English words, for instance, are the period, comma,
semicolon etc. (see program SORTS.MAC).

Example:  A-string:  TTXXXTTYY
       TERM-string:  T
.PARS #A,#B,#TERM,ADDR
          B-string:  XXX
               ADDR = address of the first Y in the A-string

.PARS may be used to remove leading or trailing spaces.  Example:

A:	.ASCIZ	*   XXX  *
TERM:	.BYTE	40,0		;40=SPACE
	.PARS	#A,#A,#TERM

The A-string will be XXX.
Chap. 13. EXTENDED MEMORY MEGAMACROS

See Table 1 and demonstration program MEMT.MAC. These are 22-bit
Megamacros to address 4 MB. The PEEK and POKE Megamacros can read from
or write to extended memory, moving a byte B, integer I, real F, or
complex number Z, or a matrix whose address is MATRIX, and whose
dimension is LxMxN.

	.PEEKB	A,B			.POKEB	B,A

	.PEEKI	A,I			.POKEI	I,A

	.PEEKF	A,F			.POKEF	F,A

	.PEEKZ	A,Z			.POKEZ	Z,A

	.PEEKM	A,MATRIX,L,M,N		.POKEM	MATRIX,A,L,M,N

A is a long integer specifying the 22-bit physical address. Memory
mapping is briefly turned on only when a PEEK or POKE Megamacro is
executed. The PEEK and POKE subroutines must not be located within
addresses 100000-117776.

The following program shows how the .CVSL2 macro can be used to help generate
22-bit octal addresses.

	.TITLE	TEST
	.MCALL	.CVSL8,.PEEKI,.T8,.EXIT,.POKEI
GO:	.CVSL8	#S,ADDR	     ;CONVERT STRING S INTO 32-BIT LONG INTEGER ADDR
	.POKEI	#7777,ADDR	;WRITE 7777 TO LOCATION 300000
	.PEEKI	R0,ADDR		;MOVE INTEGER FROM LOCATION 300000 TO R0
	.T8	R0		;TYPE OCTAL
	.EXIT
ADDR:	.BLKW	2		;32-BIT ADDRESS
S:	.ASCIZ	*300000*	;STRING
	.EVEN
	.END	GO

(When power is turned on on the PDP11/23 and PDP11/73, the eight page
descriptor registers (PDR0..7) are automatically loaded with 77406, the
correct value. This might not be true for all PDP11s.)
Chap. 14.  FLOATING POINT ERROR MEGAMACRO

.FPERR	Enables an interrupt upon a floating point error. One of the
	following error messages is typed, the address where the error
	occurred is typed, and the program is stopped.

FLOATING OP CODE ERROR
FLOATING DIVIDE BY ZERO
FLOATING OR DOUBLE TO INTEGER CONVERSION ERROR
FLOATING OVERFLOW
FLOATING UNDEFINED VARIABLE
MAINTENANCE TRAP
FLOATING UNDERFLOW--The number is set to 0, a message typed, and the
		    program is continued
Chap. 15. MEGAMACROS FOR HEWLETT-PACKARD PLOTTERS

The Megamacros for simple line drawings are .PA (plot absolute), which
moves the pen.  Pen up and down are commanded by .PU and .PD. No lines
are drawn unless the pen is already down (exceptions are the labeling
commands.

.PA	X,Y	Move pen to X,Y, using scaled coordinates. See .SCALE below.

.PCM	X,Y	Move pen to X,Y, in cm on paper (no scaling). Origin is at
		lower left when long side of paper is horizontal.

.PD		Pen down. The global .DOWN = 1 if pen is down, 0 if up.

.PU		Pen up

These Megamacros specify distances in centimeters as real coordinates
X,Y. When the paper is held with its long direction horizontal, the
origin is at the lower left. The usable plotter area is 25.75 cm by
19.125 cm. If a coordinate is off the paper, the pen will only move to
the edge of the usable area. In most cases the Megamacro name is the
same as the HP command name.

If either the first or second argument is missing, the previous number
is used, as shown by the following two ways to plot the same a square:
	.PA	#1,#3		.PA	#1,#3
	.PA	#2,#3		.PA	#2
	.PA	#2,#4		.PA	,#4
	.PA	#1,#4		.PA	#1
	.PA	#1,#3		.PA	,#3
This works for all Megamacros having X,Y.

The .PA Megamacro, not .PCM, should be used with the electronic Megamacros.

.AMPL	X,Y,#1	Equilateral triangle for amplifier. Draw line from
		previous point to X,Y. The apex of the triangle (output)
		is at X,Y, and the rest of the triangle is beyond the
		end of the line. For example, if the previous point was
		1,2, and X,Y is 1,3, then the triangle will be directed
		upward. Usually the line should come into the amplifier
		from the right. The distance from vertex to the opposite
		side is 1 cm. Pen ends at X,Y.
		  If third argument is:
			> 0  Draw + at the upper input, - at lower input
			< 0  Draw - at upper input, + at lower input
			0 or missing, draw no signs

.AND	X,Y	And gate, of dimension 1 cm. Drawn similar to .AMPL.

.AA	X,Y,A	Arc absolute. X,Y is the center of rotation of the arc.
		The arc starts at the current pen position and rotates
		counter-clockwise A deg (not radians). If A < 0, the rotation
		is clockwise.

.AR	X,Y	Arrow from preceeding point to X,Y, which is at the arrowhead.

.AXES	SX,SY	Draw axes with abscissa & ordinate labeled by strings SX,SY.
		The .SCALE macro must have been executed previously. If there
		is only one string address SX, SX is labeled on the right
		ordinate, and scaling is defined by the last .SCALE.

.AXESQ	<SX>,<SY>  Draw axes with labels SX and SY; works like .TSQ.

.BOX	X,Y	Rectangular box with one corner at previous pen
		position, and X,Y at diagonally opposite corner

.C	X,Y,#1	Capacitor between preceeding point and X,Y. Optional #1 makes
		polarity labels for electrolytic caps (preceeding pt is +).

.CI	RADIUS	Circle of RADIUS cm centered on current pen position. The pen
		is left up or down as it was previously.

.CRD	X,Y	Current-regulating diode; see diode

.D	X,Y	Diode from preceding point (anode) to X,Y (cathode, same
		direction as current flows)

.DASH	X,Y	Dashed line

.DI	A	Rotate letters by A rad/deg, depending on .SETRA/.SETDE.
		Positive is counterclockwise. The default direction is
		horizontal (long direction of paper).

.FILL	LOX,LOY,HIX,HIY,F	Filled figure (solid, not lines). The computer
		will only fill within the region:

			LOX <= X <= HIX  and  LOY <= Y <= HIY

		The user must supply a subroutine which tells whether or not
		a point X,Y is inside the figure. This subroutine must:

		Have an entry point whose address is F above.
		Get its X from location F-4, just before the entry point
		Get Y from F-8.
		When the subroutine is called, location F-10 must be set
		to 1 or zero, if X,Y is in or out of the figure.
		This subroutine may use any registers or accumulators
		without affecting the rest of the program.

		The pen is left up or down as it was previously.

		See SPOT.MAC for an example of .FILL.

.FUSE	X,Y	Fuse

.G		Ground (diagonal line) at current pen position

.GRID		Draws axes of graph, like .AXES, but no numbers labeled

.J	X,Y	Jumper (half circle) between preceeding point and X,Y

.L	X,Y	Inductor

.LBS	S	Plot (labels) string S.  See .SI and .TS

.LBSQ	<S> 	Quickly label string S within angle brackets

.LBL	S	Label string followed by CR-LF.  See .TL

.LBLQ	<S>	Quickly label string followed by CR-LF

.LED	X,Y	Light-emitting diode; see diode

.NAND	X,Y	Nand gate, of dimension 1 cm. Drawn similar to .AMPL.

.NOR	X,Y	Nor gate, of dimension 1 cm. Drawn similar to .AMPL.

.NPN	EX,EY,CX,CY     NPN transistor. The pen initially must be at the
		node where the base lead goes. (EX,EY) and (CX,CY) are the
		coordinates of the emitter and collector. The pen is at
		(CX,CY) at the end.

.OA	X,Y,DOWN  Output pen position X,Y in cm. Integer DOWN=1 if pen down

.OR	X,Y	OR gate, of dimension 1 cm. Drawn similar to .AMPL.

.PNP	EX,EY,CX,CY    PNP transistor. See .NPN

.R	X,Y	Resistor

.SCALE	XMIN,YMIN,XMAX,YMAX	;All real arguments. When scaling is NOT
in effect, .PA functions like .PCM, with origin at lower left. When
scaling IS in effect, .PA. plots in a 16 cm by 16 cm square (although
the pen can move outside this square). The lower left side of the square
is located at (4 cm, 2 cm). The data points are scaled so that the left
side of the square represents XMIN and the right side XMAX. The bottom
and top of the graph are specified by YMIN and YMAX.

.SI	W,H	Set width & height of letters in cm. W = 0.67*H is the
		suggested width. The default is W = 0.19 cm and H = 0.27 cm.
		The vertical spacing between lines equals H. The horizontal
		spacing between letters equals W/2.

.SP	N	Select pen 1-8. The pen is stored if N=0 or if N is absent.

.SPOT	RADIUS	Filled circle of RADIUS at current pen position. The pen
		is left up or down as it was previously.

.VS	X,Y	Voltage source between the preceeding point and X,Y,
		which is the positive end.

.XMTB	B	Transmit command byte B to plotter.

.XMTQ	<S>	Transmit command string S within angle brackets to plotter.

.XMTS	S	Transmit command string S to plotter.

.ZD	X,Y	Zener diode from preceeding point (anode) to X,Y (cathode)

The plotter should be connected to an RS232 serial interface at address
176510. Because interrupts are not used, the vector address need not be
defined. If a different address is necessary, change the file PLOT.MAC
by changing the statement RCSR=176510, and change the library (App. 1).

The program SCRIBE.MAC plots a text file with any letter size. The
programs DEMO.MAC, DEMO.FOR, and DEMO.PAS demonstrate the plotter
Megamacros.
Chap. 16. VT125/240/330/340 AND MATROX GT600 GRAPHICS MEGAMACROS

These Megamacros  are for the DEC VT125, VT240, VT330 and VT340 graphics
terminals. Pixel coordinates (X,Y) are integers in the range 0 <= X <=
799., and 0 <= Y <= 479. vertically. The lower left corner of the screen
is (0,0).

.VTE		erase text and graphics screens

.VTP	X,Y	light up pixel at X,Y

.VTV	X,Y	draw vector (line) from previous point to (X,Y)

.VTCR	X,Y,B	return cross-hair coordinates X,Y. The arrow keys may
		be used to move the cursor. When some key B is struck,
		X,Y and the byte B are returned.

The Megamacros below are for a VT100 equipped with a Matrox GT600 graphics
board. Integer pixel coordinates X,Y are in the range 0 <= X <= 1023.
and 0 <= Y <= 779. The terminal is returned to normal mode after each
Megamacro is executed.

.GTE		erase VT100 and GT600 screens

.GTP	X,Y	light pixel at point (X,Y)

.GTV	X,Y	draw vector (line) from previous point to (X,Y)

.GTCR	X,Y,B	return cross-hair coordinates (like .VTCR)
Chap. 17.  DAY (DATE) MEGAMACRO

The current date is normally typed in, when the system is booted. The
system program DATE.SAV does this.

		.DAY	S

The .DAY Megamacro gets this date and returns a string S of exactly 13.
bytes (including the zero byte) in the form:

			DEC 25, 1989
Chap. 18.  USE OF MEGAMACROS WITH FORTRAN AND PASCAL

The following Megamacros may be called from DEC Fortran or Oregon
Software Pascal, or any language, which passes arguments by using R5 to
point to a list of the addresses of the arguments. All the usual ways of
passing arguments in Fortran should work, such as:

	CALL CMOV (11, 66)
	CALL LBS ('HELLO')

   MEGAMACRO		   FORTRAN		   PASCAL
.AVDEV	X,N,A,D		CALL AVDEV(X,N,A,D)	AVDEV(X,N,A,D);	AV. & STD.DEV.
.BINOM	N,M,B		B=BINOM(N,M)		F:=BINOM(N,M);	BINOMIAL COEFF
.CD	N		CALL CD(N)		CD(N);		CURSOR DOWN N
.CL	N		CALL CL(N)		CL(N);		CURSOR LEFT N
.CMOV	I,J		CALL CMOV(I,J)		CMOV(I,J);	MOVE CURSOR
.CNEX			CALL CNEX		CNEX;		NEXT LINE
.CPOS	I,J,B		CALL CPOS(I,J,B)	CPOS(I,J,B); 	CURSOR POS.
.CR	N		CALL CR(N)		CR(N);		CURSOR RIGHT N
.CU	N		CALL CU(N)		CU(N);		CURSOR UP N
.DETM	M,N,D		D=DETM(M,N)		D:=DETM(M,N); 	DETERMINATE
.DWL			CALL DWL		DWL;		WIDE LETTERS
.E			CALL E			E;		ERASE SCREEN
.EL			CALL EL			EL;		ERASE LINE
.ELL			CALL ELL		ELL;		ERASE LINE LT
.ELR			CALL ELR		ELR;		ERASE LINE RT
.EQSM	A,B,N		CALL EQSM(A,B,N)	EQSM(A,B,N);	LINEAR EQS
.EQSZ	A,B,N		CALL EQSZ(A,B,N)	EQSZ(A B,N);	COMPLEX EQS
.FACT	I,F		F=FACT(I)		F:=FACT(I);	FACTORIAL
.FFT	Z,LAYER,SIGN	CALL FFT(Z,LAYER,ISIGN) FFT(Z,LAYER,SIGN);  FFT
.GAMMA	X,Y		Y=GAMMA(X)		Y:=GAMMA(X);	GAMMA FUNCTION
.INVM	A,AI,N		CALL INVM(A,AI,N)	INVM(A,AI,N);	INVERT MATRIX
.MOVBT	A,NA,B,NB,NBIT	CALL MOVBT(A,NA,B,NB,NBIT)	none	MOVE BITS
.RAND	X		X=RAND(0)		X:=RAND;	FLAT RANDOM
.RANDS	X		X=RANDS(0)		X:=RANDS;	SHUFFLED RAND
.RANOR	X		X=RANOR(0)		X:=RANOR;	GAUSSIAN RAND
.RIS			CALL RIS		RIS;		RESET TERMINAL
.SWL			CALL SWL		SWL;		NARROW LETTERS
.VTCR	X,Y,B		CALL VTCR(X,Y,B)	VTCR(X,Y,B);	CURSOR POS.
.VTE			CALL VTE		VTE;		ERASE GRAPHICS
.VTP	I,J		CALL VTP(I,J)		VTP(I,J);	LIGHT PIXEL
.VTV	I,J		CALL VTV(I,J)		VTV(I,J);	DRAW LINE


PLOTTER MEGAMACROS

MEGAMACRO		FORTRAN			PASCAL
.A 	X,Y		CALL A(X,Y)		A(X,Y);		AMPLIFIER
.AA	X,Y,A		CALL AA(X,Y,A)		AA(X,Y,A);	ARC ABSOLUTE
.AR	X,Y		CALL AR(X,Y)		AR(X,Y);	ARROW
.AXES	SX,SY		CALL AXES(SX,SY)	AXES(SX,SY);	AXES
.BOX	X,Y		CALL BOX(X,Y)		BOX(X,Y)	RECTANGLE
.C	X,Y		CALL C(X,Y)		C(X,Y);		CAPACITOR
.CI	RADIUS		CALL CI(RADIUS)		CI(RADIUS);	CIRCLE
.D	X,Y		CALL D(X,Y)		D(X,Y);		DIODE
.DI	A		CALL DI(A)		DI(A);		DIRECTION
.G			CALL G			G;		GROUND
.L	X,Y		CALL L(X,Y)		L(X,Y);		INDUCTOR
.LBL	S		CALL LBL('HELLO')	LBL(S);		LABEL LINE
.LBS	S		CALL LBS('GREETINGS')	LBS(S);		LABEL STRING
.NPN	EX,EY,CX,CY	CALL NPN(EX,EY,CX,CY)	NPN(EX,EY,CX,CY);  NPN
.OA	X,Y,DOWN	CALL OA(X,Y,DOWN)	OA(X,Y,DOWN);	PEN POSITION
.PA	X,Y		CALL PA(X,Y)		PA(X,Y);	PLOT ABSOLUTE
.PCM	X,Y		CALL PCM(X,Y)		PCM(X,Y);	PLOT IN cm
.PD			CALL PD			PD;		PEN DOWN
.PNP	EX,EY,CX,CY	CALL PNP(EX,EY,CX,CY)	PNP(EX,EY,CX,CY);  PNP
.PU			CALL PU			PU;		PEN UP
.R	X,Y		CALL R(X,Y)		R(X,Y);		RESISTOR
.SCALE	XMIN,YMIN,XMAX,YMAX
			CALL SCALE(XMIN,YMIN,XMAX,YMAX)		SCALE PLOT
						SCALE(XMIN,YMIN,XMAX,YMAX);
.SI	W,H		CALL SI(W,H)		SI(W,H);	LETTER SIZE
.SP	N		CALL SPN(N)		SPN(N);		SELECT PEN
.V	X,Y		CALL V(X,Y)		V(X,Y);		VOLTAGE SOURCE
.XMTB	B		CALL XMTB(B)		XMTB(B);	SEND BYTE
.XMTS	S		CALL XMTS(S)		XMTS(S);	SEND STRING

Oregon Software Pascal does not permit using constants in nonpascal
procedure calls, because the procedure might change that constant. Use
variables instead, as in this example:

VAR	X, Y: REAL;
PROCEDURE PA (VAR X, Y: REAL); NONPASCAL;

X:= 13.3;	Y:= 6.12;
PA(X,Y);

The file M.PAS contains all the procedure definitions. The needed
procedures must be inserted into your program, which can be done as
follows:
	COPY URPROGR.PAS+M.PAS URPROG.PAS

Use the editor to eliminate unused definitions. Some procedures use some
of the following type definitions, which must be inserted near the
beginning of your program. All strings must be exactly 25 CHAR long,
padded with spaces if necessary.

TYPE	STRING = PACKED ARRAY [1..25] OF CHAR;	MUST BE 25
TYPE	DIM1 = ARRAY [1..10] OF REAL;		CHANGE DIMENSIIONS AS NEEDED
TYPE	DIM2 = ARRAY [1..10,1..10] OF REAL;
TYPE	COMPLEX = ARRAY [1..2] OF REAL;
TYPE	DIM1Z = ARRAY [1..10] OF COMPLEX;
TYPE	DIM2Z = ARRAY [1..10,1..10] OF COMPLEX;
		APPENDIX 1: MODIFYING THE LIBRARY

Make backup copies of files M.MAC, M.MLB, and L.OBJ. The file M.MAC
contains the Megamacro definitions and may be edited. It is converted to
file M.MLB (Macro LiBrary) by typing:

	R LIBR
	M=M/M:500

Suppose that a macro named .MINE has been defined by the user, and this
macro calls subroutine .MINE, which is contained in file MINE.MAC. This
subroutine is inserted into library file L.OBJ by typing:

	MAC MINE+M/LIB
	LIBR L MINE/INSERT

If the subroutine has to be modified, the procedure is:

	MAC MINE+M/LIB
	LIBR L MINE/REPLACE
APPENDIX 2.  MEGAMACRO AND SUBROUTINE LINKAGE CONVENTIONS

Megamacros .MOVF (4 bytes) and .MOVZ (8 bytes) were specifically
designed for moving real and complex data between the Megamacros and
their subroutines. These Megamacros work with all addressing moves. They
save accumulator A0 on the stack, move the real or complex number into
and out of A0, and then restore A0 from the stack. For example, the
.SQRT Megamacro below was copied from the M.MAC file:

	.MACRO	.SQRT	X,Y		Y = SQRT(X)
	.GLOBL	.SQRT
	.MCALL	.MOVF
	.MOVF	X,.SQRT-4
	CALL	.SQRT
	.MOVF	.SQRT-10,Y
	.ENDM

.MOVF moves X to the 4 bytes immediately preceding .SQRT, the entry
point of the SQRT.MAC subroutine. Then .SQRT is called. Part of the file
SQRT.MAC is listed below:

	.TITLE	SQRT
	.GLOBL	.SQRT
A1=R1
A2=R2
SQRTN:	.BLKW	2
N:	.BLKW	2
.SQRT:	MOV	R0,-(SP)
	STF	A1,-(SP)
	STF	A2,-(SP)
	...
	STF	A1,SQRTN
	LDF	(SP)+,A2
	LDF	(SP)+,A1
	MOV	(SP)+,R0
	RETURN

The entry point .SQRT is the only global. The Megamacro has already
moved the number into N, 4 bytes before the entry point. The subroutine
can now address N as a local variable. Register R0 and accumulators A1
and A2 are pushed onto the stack. The square root is computed and moved
to location SQRTN, 8 bytes before the entry point. The accumulators and
register are restored by popping the stack. Returning now to the .SQRT
Megamacro, the answer at location .SQRT-10 is moved to location Y in the
user's program.

These conventions permit Megamacro arguments to be passed to and from
the subroutine for all addressing modes, without altering any registers
or accumulators. The Megamacro itself uses a minimal number of
instructions so that the user can incorporate it into small SOB loops.
                                                                                                                                                                                                                                                                                                                                                                      