PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

DEC PDP-10 Mini-Assembler Tests

Nested Macro Test

The PDP-10 machine below automatically loads and assembles TEXT.MAC, one of the first tests of the built-in PDPjs MACRO-10 Mini-Assembler.

TEXT.MAC is a copy of the file listed on p. 7-9 of the MACRO-10 Assembler Programmer’s Reference Manual (June 1972). It’s a simple test of nested macro definitions, recursion, expressions using shift operators and character constants, and pseudo-ops IRPC, IFE, IFN, and EXP. It generates 4 words of data.

[PCjs Machine "testka10"]

Waiting for machine "testka10" to load....

Assemble TEXT.MAC:

a 100 TEXT.MAC

Verify the following results:

loading TEXT.MAC
4 words loaded at 000100-000103
00=000000000000 01=000000000000 02=000000000000 03=000000000000 
04=000000000000 05=000000000000 06=000000000000 07=000000000000 
10=000000000000 11=000000000000 12=000000000000 13=000000000000 
14=000000000000 15=000000000000 16=000000000000 17=000000000000 
PC=000100 RA=00000000 EA=000000 C0=0 C1=0 OV=0 ND=0 PD=0 
000100: 014101 102103  UUO     2,102103(1)

Dump the 4 assembled words with the command db 100 l4:

000100: 014101 102103  003 004 011 004 041  ....!
000101: 104105 106107  021 004 051 014 043  ..).#
000102: 110111 112113  022 004 111 024 045  ..I.%
000103: 114000 000000  023 000 000 000 000  .....

Source code from TEXT.MAC:

; From the MACRO-10 ASSEMBLER PROGRAMMER'S REFERENCE MANUAL (June 1972), p. 7-9:
;
;	Example 4 (Figure 7-4) shows nested macros which use IRPC.  The desired operation
;	is to take an ASCII text string and store the characters four per word, left-justified,
;	with the character count stored in the first nine bits of the first word.
;
;	The TEXT macro counts the string characters and invokes the CODE macro to store the
;	characters four per word.  The CODE macro invokes a SHIFT macro which left-justifies the
;	last word if it is not already left-justified.  The first part of the example shows the
;	normal listing, then SALL is set to show what code the macros are generating.
;
; The original listing encoded two of the lines as follows:
;
;	IFN ZZ,<DEFINE SHIFT		;;REMAINDER LEFT
;	 IFE ZZ&777B8,>			;;IF NOT LEFT JUSTIFIED
;
; The April 1978 MACRO-10 manual says that a macro body "must be enclosed in angle brackets",
; so the DEFINE looks wrong, and the IFE contains only a closing angle bracket, which also seems
; wrong.  Perhaps what's shown above is a side-effect of some MACRO-10 listing generation bug
; and not an accurate reflection of the original code.  In any event, after making two small
; modifications below, macro10.js is able to assemble the code fine.
;
; This example also begs the question: did MACRO-10 optimize tail recursion?  Because without
; it, if the SHIFT macro required many iterations (for example, if "ZZ==ZZ_9" was replaced with
; "ZZ==ZZ+9"), wouldn't MACRO-10 blow its stack?  I've noted this in macro10.js as well.
;
	TITLE	STORE TEXT CHARACTER BY CHARACTER
	SUBTTL	%1 5-APR-72

	DEFINE TEXT (C)<
	N==0				;;INITIAL CONDITION
	IRPC C,<N==N+1>			;;COUNT CHARACTERS
	CODE (N,C)			;;CALL MACRO TO STORE TEXT
	>				;END OF TEXT MACRO

	DEFINE CODE (N,C)<
	ZZ==N				;;INITIAL CONDITION
	IRPC C,<
	IFN ZZ&777B8,<
		EXP ZZ			;;WORD FULL
		ZZ==0>			;;START AGAIN WITH 0
	ZZ==ZZ_9+"C">			;;END OF IRPC
	IFN ZZ,<DEFINE SHIFT<		;;REMAINDER LEFT
	 IFE ZZ&777B8,<			;;IF NOT LEFT JUSTIFIED
	  ZZ==ZZ_9			;;MOVE LEFT 9 BITS
	  SHIFT>			;;RECURSE
	 >				;;END OF DEFINE
	SHIFT				;;START MOVING LEFT
	EXP ZZ>				;;END OF IFN ZZ
	>				;END OF CODE MACRO

	TEXT (ABCDEFGHIJKL)
	END

Nested Literal Test

Assemble NESTLIT.MAC:

a 100 NESTLIT.MAC

Source code from NESTLIT.MAC:

; From the MACRO-10 ASSEMBLER PROGRAMMER'S REFERENCE MANUAL (April 1978), p. 2-8:

P=0
T1=1
T2=2

GETCHR:	ILDB T2,T1		;Get a character
	CAIN T2,0		;Is it a null?
	JRST [MOVE T1,TXTPTR#	;Yes, retrieve pointer
		ILDB T2,T1	;Get a new character
		CAIN T2,"?"	;Is it a question mark?
		JRST [MOVE T1,TXTPT1#	;Yes, get alternate pointer
			ILDB T2,T1	;Get the message character
			JRST GETHLP#]	;Go to help routine
		POPJ P,]	;Not question mark, return
	POPJ P,			;Not a null, return