Morphic Code

z80 » Advanced

Morphic code is code that edits other code. This is such a broad definition because it changes, as the name hints. You can have a routine that puts a return instruction between some code to return early. It would load the value for ret ($c9) into a nop ($00) so it wouldn't move any code around affecting all addresses after. Morphic code isn't used that often. One time it is used is for random number generators. Here's an example of a random number generator that edits a constant every time it is run.

random_number_generator:
		push hl		;save hl
	ld a,r			;refresh register
				; is increased after
				; every instruction
				; is executed
	ld hl,random_byte_addr	;address of byte
				; we keep changing
	add a,(hl)		;add r to what's at hl
	adc a,a			;multiply by 2 and
				;increase if carry
				; was set last time
	ld (hl),a		;load the result back
				; at hl
		pop hl		;get back hl saved
				; from when we
				; started the routine
	ret
random_byte_addr:
	.db $00			;byte we change

Now that code wasn't trully morphic. It more or less resembled using variables. Morphic code is powerful when used to modify other code as this next example shows. Upon entering this routine, the byte at address loop_iterations will contain the number of times we should loop using djnz. We load that value into the byte loaded into b using the Instruction Pointer ($) and start the loop.

loop_iteration_change:
	ld hl,loop_iteration
	ld a,(hl)
	ld hl,byte_to_change
	ld (hl),a
byte_to_change	= $ + 1		;the $ would be
				; the opcode byte
				; telling the z80
				; to load the following
				; byte into b
				;$ + 1 would be the
				; byte to be loaded
				; into b
	ld b,$00		;the $00 is changed
				; from the 'ld (hl),a'
				; code
	ld a,1			;load a with 1 so we can
				; start multiplying
				; (really adding)
loop:
	add a,a			;a*2=a
	djnz loop
	ret			;we now have a=2^b

loop_iteration:	.db $00		;byte determined before
				; routine starts

Let's reference a Temporary Trash variable within the program code.

	ld a,69
	ld (variable_addr),a

	ld a,$00
variable_addr	=$-1


More from z80 » Advanced
All The Ports // APD // Assembler Directives // Entry Stack // User Fonts // IM 1 // IM 2 // Index, Shadow, and Other Registers // User Interrupt // Morphic Code // On-Off // Reading Keypresses from Port // Shift and Rotate // Simulating Key Presses // Sound // Square-Root Programs // System Flags of TI-OS