Listing 1: A relocator program for use on 8080 systems. This is a modified version of the relocator program written by Leor Zolman in the July 1977 BYTE. This relocator will move a source program to any location in memory and fix address references. Relocations of a source-program block to any address outside the source are performed without overwriting. The program is designed to run with the Dynamic Debugging Tool (DDT) of the CP/M software system. If need be, the program can be modified to run without a monitor or with another monitor by changing the contents of hexadecimal memory location 2DCC. While differing in some details with Zolman's relocator program, it requires the same information and is run in the same manner.
[8080 source and Z80 source]
 2D00           	ORG	2D00H		;SET ORIGIN
 2D00 31162E    BEGIN:	LXI	SP,STACK+8	;INTIALIZE STACK
 2D03 2A032E    	LHLD	SBOT		;BOTTOM OF SOURCE
 2D06 EB        	XCHG			;D,E=SBOT=(B)
 2D07 2A012E    	LHLD	SSTRT		;H,L=SSTRT=(A)
 2D0A 4D        	MOV	C,L
 2D0B 44        	MOV	B,H		;SAVE IN B,C
 2D0C CDCD2D    	CALL	COMPH		;COMPLIMENT(A) & ADD 1
 2D0F 19        	DAD	D		;H,L=(B)-(A)=BLOCKSIZE
 2D10 E5        	PUSH	H		;SAVE ON STACK
 2D11 2A052E    	LHLD	DTOP		;TOP OF DESTINATION
 2D14 EB        	XCHG			;D,E=DTOP=(C)
 2D15 69        	MOV	L,C
 2D16 60        	MOV	H,B		;H,L=SSTRT
 2D17 CDCD2D    	CALL	COMPH
 2D1A 19        	DAD	D		;H,L=(C)-(A)=DISPL
 2D1B 220C2E    	SHLD	DISPL		;SAVE DISPLACEMENT
 2D1E F5        	PUSH	PSW		;HAS SIGN OF DISPL
 2D1F 3A0B2E    	LDA	FUNC		;CHECK FOR MOVE
 2D22 B7        	ORA	A
 2D23 CA602D    	JZ	STEP2		;IF 0 FIX REF. ONLY
 2D26 F1        	POP	PSW
 2D27 DA3E2D    	JC	DOWN		;(C)>(A) IF CARRY SET
                	;IF COME HERE DESTINATION IS ABOVE SOURCE
                	;SO MOVE IS DONE HEAD-TO-HEAD
 2D2A EB        UP:	XCHG			;H,L=D,E=DTOP
 2D2B D1        	POP	D		;D,E=BLKSIZE
 2D2C 0A        X:	LDAX	B		;B,C=SSTRT=SOURCE PTR.
 2D2D 77        	MOV	M,A		;MOVE TO NEW LOC.
 2D2E 7A        	MOV	A,D
 2D2F B7        	ORA	A
 2D30 C2382D    	JNZ	Y		;CHECK IF THRU
 2D33 7B        	MOV	A,E
 2D34 B7        	ORA	A
 2D35 CA582D    	JZ	TEST		;IF D,E=0 THEN MOVE DONE
 2D38 23        Y:	INX	H		;INCR DEST. PTR. TO NEXT
 2D39 03        	INX	B		;INCR SOURCE PTR.
 2D3A 1B        	DCX	D		;COUNT DOWN BLKSIZE
 2D3B C32C2D    	JMP	X		;CONTINUE
                	;IF COME HERE DESTINATION IS BELOW SOURCE
                	;SO MOVE IS DONE TAIL-TO-TAIL
 2D3E EB        DOWN:	XCHG			;H,L=D,E=DTOP
 2D3F D1        	POP	D		;D,E=BLKSIZE
 2D40 D5        	PUSH	D		;SAVE ON STACK
 2D41 19        	DAD	D		;H,L=DBOT=DTOP+BLKSIZE
 2D42 EB        	XCHG			;D,E=DBOT:H,L=BLKSIZE
 2D43 09        	DAD	B		;H,L=SSTRT+BLKSIZE=SBOT
 2D44 EB        	XCHG			;D,E=SBOT:H,L=DBOT
 2D45 C1        	POP	B		;B,C=BLKSIZE
 2D46 1A        XX:	LDAX	D		;D,E=SOURCE PTR.
 2D47 77        	MOV	M,A		;MOVE TO NEW LOC.
 2D48 78        	MOV	A,B
 2D49 B7        	ORA	A
 2D4A C2522D    	JNZ	YY		;CHECK IF THRU
 2D4D 79        	MOV	A,C
 2D4E B7        	ORA	A
 2D4F CA582D    	JZ	TEST		;B,C=0,MOVE DONE
 2D52 2B        YY:	DCX	H		;PT. TO NEXT DEST.
 2D53 1B        	DCX	D		;PT. TO NEXT SOURCE
 2D54 0B        	DCX	B		;COUNT DOWN BLKSIZE
 2D55 C3462D    	JMP	XX		;CONTINUE
 2D58 3A0B2E    TEST:	LDA	FUNC		;=02 IF MOVE ONLY
 2D5B FE02      	CPI	02H
 2D5D CACC2D    	JZ	DONE
                	;COME HERE TO DO REFERENCE FIXING.
                	;NECESSARY ONLY FOR 3 BYTE OP CODES
 2D60 01E72D    STEP2:	LXI	B,TABL3		;B,C= TABLE PTR
 2D63 2A032E    	LHLD	SBOT		;NEED TO ADD 1 TO SBOT
 2D66 23        	INX	H
 2D67 22032E    	SHLD	SBOT
 2D6A 2A072E    	LHLD	START		;D,E=MEMORY PTR.
 2D6D EB        	XCHG
 2D6E 2A092E    CHEKF:	LHLD	SSTP		;CHECK FOR END OF FILE
 2D71 CDCD2D    	CALL	COMPH		;D,E-MEM. PTR.
 2D74 19        	DAD	D		;D,E-H,L=DIFF.
 2D75 DACC2D    	JC	DONE		;DIFF.>=0,CARRY SET
 2D78 1A        NEXT:	LDAX	D		;LOAD MEM. USING D,E
 2D79 67        	MOV	H,A		;SAVE IN H
 2D7A AF        	XRA	A		;ZERO ACCUM.
 2D7B 6F        	MOV	L,A		;SET UP CNTR.
 2D7C 2C        COMP3:	INR	L		;BUMP CNTR
 2D7D 7D        	MOV	A,L
 2D7E FE1B      	CPI	27D		;CHECK FOR END OF TABLE
 2D80 CA8C2D    	JZ	AGAIN		;IF THRU..LOOK @ 2 BYT OPS
 2D83 0A        	LDAX	B		;LOAD TABLE ENTRY
 2D84 94        	SUB	H		;COMP. WITH CURR. MEM.
 2D85 CAA12D    	JZ	MTCH3		;JMP IF MATCH
 2D88 03        	INX	B		;ELSE BUMP TABLE PTR.
 2D89 C37C2D    	JMP	COMP3		;LOOK AGAIN
 2D8C 01D52D    AGAIN:	LXI	B,TABL2		;NOW,LOOK AT 2 BYTE OPS
 2D8F AF        	XRA	A		;ZERO ACCUM.
 2D90 6F        	MOV	L,A		;SET CTR.
 2D91 2C        COMP2:	INR	L		;BUMP CTR.
 2D92 7D        	MOV	A,L
 2D93 FE13      	CPI	19D		;CHECK FOR END TABLE
 2D95 CAC52D    	JZ	OUT1		;NO MATCH 2 OR 3 BYTE OPS
 2D98 0A        	LDAX	B		;LOAD TABLE ENTRY
 2D99 94        	SUB	H		;COMP. WITH CURRENT MEM.
 2D9A CAC42D    	JZ	OUT2		;JMP IF MATCH
 2D9D 03        	INX	B		;ELSE BUMP TABLE PTR.
 2D9E C3912D    	JMP	COMP2		;LOOK AGAIN
 2DA1 2A032E    MTCH3:	LHLD	SBOT		;FOUND 3 BYTE OP CODE
 2DA4 CDCD2D    	CALL	COMPH		;IS ADDR. IN RANGE?
 2DA7 13        	INX	D		;GET LO ADDR. BYTE
 2DA8 1A        	LDAX	D		;LOAD IN ACC.
 2DA9 4F        	MOV	C,A		;STORE IN C
 2DAA 13        	INX	D		;GET HI ADDR. BYTE
 2DAB 1A        	LDAX	D		;LOAD ACC.
 2DAC 47        	MOV	B,A		;PUT IN B
 2DAD 09        	DAD	B		;H,L=MEM.ADDR.-SBOT
 2DAE DAC52D    	JC	OUT1		;MEM.ADDR.>=SBOT+1,C SET
 2DB1 2A012E    	LHLD	SSTRT		;LESS THAM (A)?
 2DB4 CDCD2D    	CALL	COMPH
 2DB7 09        	DAD	B		;H,L=MEM.ADDR.-SSTRT
 2DB8 D2C52D    	JNC	OUT1		;MEM.ADDR. < SSTRT,C=0
 2DBB 2A0C2E    FIXR:	LHLD	DISPL		;IF COME HERE,IN RANGE.
 2DBE 09        	DAD	B		;H,L=MEM.ADDR.+DISPL
 2DBF 7C        	MOV	A,H
 2DC0 12        	STAX	D		;STORE NEW HI ADDR.
 2DC1 1B        	DCX	D		;PT. AT LO ADDR. BYTE
 2DC2 7D        	MOV	A,L
 2DC3 12        	STAX	D		;STORE NEW LO ADDR. BYTE
 2DC4 13        OUT2:	INX	D
 2DC5 13        OUT1:	INX	D		;ADV. PTR. TO NEXT OP
 2DC6 01E72D    	LXI	B,TABL3		;RESET TABLE PTR.
 2DC9 C36E2D    	JMP	CHEKF		;CONTINUE
 2DCC FF        DONE:	RST	07		;FINIS,RETURN TO DDT
                	;*****  SUBROUTINE  *****
 2DCD 7C        COMPH:	MOV	A,H		;SUBROUTINE USED TO
 2DCE 2F        	CMA			;FIND 2'S COMPLIMENT
 2DCF 67        	MOV	H,A		;REPRESENTATION OF
 2DD0 7D        	MOV	A,L		;H,L REGISTER PAIR
 2DD1 2F        	CMA
 2DD2 6F        	MOV	L,A
 2DD3 23        	INX	H
 2DD4 C9        	RET
                	;*****  TABLES AND CONSTANTS  *****
 2DD5 060E16    TABL2:	DB	06H,0EH,16H	;TABLE OF 2 BYTE
 2DD8 1E262E    	DB	1EH,26H,2EH	;OP CODES
 2DDB 363EC6    	DB	36H,3EH,0C6H
 2DDE CEDED6    	DB	0CEH,0DEH,0D6H
 2DE1 DBDEE6    	DB	0DBH,0DEH,0E6H
 2DE4 EEF6FE    	DB	0EEH,0F6H,0FEH
 2DE7 011121    TABL3:	DB	01H,11H,21H	;TABLE OF 3 BYTE
 2DEA 222A31    	DB	22H,2AH,31H	;OP CODES
 2DED 323AC2    	DB	32H,3AH,0C2H
 2DF0 C3C4CA    	DB	0C3H,0C4H,0CAH
 2DF3 CCCDD2    	DB	0CCH,0CDH,0D2H
 2DF6 D4DADC    	DB	0D4H,0DAH,0DCH
 2DF9 E2E4EA    	DB	0E2H,0E4H,0EAH
 2DFC ECF2F4    	DB	0ECH,0F2H,0F4H
 2DFF FAFC      	DB	0FAH,0FCH
 2E01           SSTRT:	DS	02H		;SOURCE TOP(A)
 2E03           SBOT:	DS	02H		;SOURCE BOTTOM(B)
 2E05           DTOP:	DS	02H		;DESTINATION TOP(C)
 2E07           START:	DS	02H		;START OF REF. FIXING(D)
 2E09           SSTP:	DS	02H		;END OF REF. FIXING(E)
 2E0B           FUNC:	DS	01H		;00=REF. FIX ONLY (F)
                				;02=MOVE ONLY
                				;01=MOVE & FIX
 2E0C           DISPL:	DS	02H		;DISPLACEMENT
 2E0E           STACK:	DS	08H		;MEM. SPACE FOR STACK