MEMPTR - redcode/Z80 GitHub Wiki

MEMPTR or WZ?

Instructions affecting MEMPTR

The following table shows the instructions that affect the state of the MEMPTR register and how its value is modified:

Instruction New value of MEMPTR
ld J,(XY+OFFSET)
ld (XY+OFFSET),K
ld (XY+OFFSET),BYTE
U [a,](XY+OFFSET)
V (XY+OFFSET)
G (XY+OFFSET)
G (XY+OFFSET),K
bit N,(XY+OFFSET)
M N,(XY+OFFSET)
M N,(XY+OFFSET),K
XY + OFFSET
ld a,(bc) bc + 1
ld a,(de) de + 1
ld a,(WORD) WORD + 1
ld (bc),a (a << 8) | (c + 1)
ld (de),a (a << 8) | (e + 1)
ld (WORD),a (a << 8) | ((WORD + 1) & FFh)
ld hl,(WORD)
ld SS,(WORD)
ld XY,(WORD)
ld (WORD),hl
ld (WORD),SS
ld (WORD),XY
WORD + 1
ex (sp),hl
ex (sp),XY
(sp)i
ldir
lddr
if bco:
pci + 1
cpi memptr + 1
cpir if bcoa(hli):
pci + 1
else:
memptr + 1
cpd memptr - 1
cpdr if bcoa(hli):
pci + 1
else:
memptr - 1
add hl,SS
adc hl,SS
sbc hl,SS
hli + 1
add XY,WW XYi + 1
rld
rrd
hl + 1
jp WORD
jp Z,WORD
call WORD
call Z,WORD
WORD
jr OFFSET pci + 2 + OFFSET
jr Z,OFFSET if Z:
pci + 2 + OFFSET
djnz OFFSET if bo:
pci + 2 + OFFSET
ret
reti
retn
(spi)
ret Z if Z:
(spi)
rst N pco
in a,(BYTE) ((a << 8) | BYTE) + 1
in J,(c)
in (c)
out (c),J
out (c),0
bc + 1
ini
bci + 1
inir if bo:
pci + 1
else:
bci + 1
ind
bci - 1
indr if bo:
pci + 1
else:
bci - 1
out (BYTE),a (a << 8) | ((BYTE + 1) & FFh)
outi
bco + 1
otir if bo:
pci + 1
else:
bco + 1
outd
bco - 1
otdr if bo:
pci + 1
else:
bco - 1

Notation

Symbol Meaning
J/K 8-bit register: a, b, c, d, e, h, l or a.
SS 16-bit register: bc, de, hl or sp.
WW 16-bit register: bc, de, ix, iy or sp.
XY 16-bit index register: ix or iy.
U Arithmetic/logical operation: add, adc, sub, sbc, and, xor or or cp.
V Increment/decrement operation: inc or dec.
G Rotation/shift operation: rlc, rrc, rl, rr, sla, sra, sll or srl.
M Bit set/reset operation: res or set.
Z Condition: nz, z, nc, c, po, pe, p or m.
N Immediate 3-bit unsigned integer (embedded in the opcode).
BYTE Immediate 8-bit unsigned integer.
OFFSET Immediate 8-bit signed integer (added to the index register).
WORD Immediate 16-bit unsigned integer.
i subfix Initial/input value of the register or memory address.
o subfix Final/output value of the register or memory address.

Reading MEMPTR

;
;WZRD is 'slow' WZ read routine
;put instruction to be tested at WZRD0
;
WZRD:
	DI
WZRD0:
	LD A,(0000H)		;Instruction under test
;
;read WZ[13] immediately after test instruction
;
	BIT 0,(HL)		;F[5] = WZ[13] {F[3] = WZ[11]}
	LD D,20H		;D = 1 << 5 = WZ[13] bit mask
	PUSH AF
	POP BC			;C[5] = WZ[13]
	LD A,C
	AND D			;A = 20H or 00H if WZ[13] = 1 or 0
	LD E,A			;Save WZ[13]
;
;patch JR instruction below
;
	RRCA			;A = 10H or 00H
	RRCA			;A = 08H or 00H
	OR D			;A = 28H or 20H = JR Z or JR NZ opcode
	LD (WZRD2),A		;write opcode
;
;decrement WZ using CPD until WZ[13] flips
;
	LD HL,0			;initialise WZ[12:0] counter to 0
	LD IX,WZRD1		;IX = loop address
WZRD1:
	CPD			;dec HL and WZ
;
;read WZ[13] after decrementing
;
	BIT 0,(HL)		;F[5] = WZ[13] {F[3] = WZ[11]}
	PUSH AF
	POP BC			;C[5] = WZ[13]
	LD A,C
	AND D			;NZ or Z if WZ[13] = 1 or 0
WZRD2:
	JR Z,WZRD3		;Or JR NZ,... jump if WZ[13] flipped
	JP (IX)			;loop to WZRD1
;
;WZ[13] flipped so WZ counting has finished
;As HL = !WZ[12:0] invert it and add WZ[13]
;
WZRD3:
	LD A,H
	CPL			;A = WZ[12:8]
	OR E			;A = WZ[13:8]
	LD H,A			;H = WZ[13:8]			
	LD A,L
	CPL			;A = WZ[7:0]
	LD L,A			;HL = WZ[13:0]
	RET
;
;WZRDF is 'fast' WZ read routine
;put instruction to be tested at WZRDF0
;
WZRDF:
	DI
WZRDF0:
	LD A,(0000H)		;Instruction under test
;
;read WZ[13] immediately after test instruction
;
	BIT 0,(HL)		;F[5] = WZ[13] {F[3] = WZ[11]}
	LD D,20H		;D = 1 << 5 = WZ[13] bit mask
	PUSH AF
	POP BC			;C[5] = WZ[13]
	LD A,C
	AND D			;A = 20H or 00H if WZ[13] = 1 or 0
	LD E,A			;Save WZ[13]
;
;patch JR instructions below
;
	RRCA			;A = 10H or 00H
	RRCA			;A = 08H or 00H
	OR D			;A = 28H or 20H = JR Z or JR NZ opcode
	LD (WZRDF2),A		;write opcode 1
	XOR 08H			;A = 20H or 28H = JR NZ or JR Z opcode
	LD (WZRDF5),A		;write opcode 2
;
;decrement WZ using block of CPD instructions until WZ[13] flips
;block size = 25 but could be changed as desired
;
	LD HL,0FFFFH		;initialise WZ[12:0] counter to -1
	LD IX,WZRDF1		;IX = loop address
WZRDF1:
	CPD			;dec HL and WZ for each CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
	CPD
;
;read WZ[13] after decrementing
;
	BIT 0,(HL)		;F[5] = WZ[13] {F[3] = WZ[11]}
	PUSH AF
	POP BC			;C[5] = WZ[13]
	LD A,C
	AND D			;NZ or Z if WZ[13] = 1 or 0
WZRDF2:
	JR Z,WZRDF3		;Or JR NZ,... jump if WZ[13] flipped
	JP (IX)			;loop to WZRDF1
;
;WZ[13] flipped during CPD block
;increment WZ until WZ[13] flips back
;
WZRDF3:
	LD IX,WZRDF4		;IX = loop address
WZRDF4:
	CPI			;inc HL and WZ
;
;read WZ[13] after incrementing
;
	BIT 0,(HL)		;F[5] = WZ[13] {F[3] = WZ[11]}
	PUSH AF
	POP BC			;C[5] = WZ[13]
	LD A,C
	AND D			;NZ or Z if WZ[13] = 1 or 0
WZRDF5:
	JR NZ,WZRDF6		;Or JR Z,... jump if WZ[13] flipped
	JP (IX)			;loop to WZRDF4
;
;WZ[13] flipped so WZ counting has finished
;As HL = !WZ[12:0] invert it and add WZ[13]
;
WZRDF6:
	LD A,H
	CPL			;A = WZ[12:8]
	OR E			;A = WZ[13:8]
	LD H,A			;H = WZ[13:8]			
	LD A,L
	CPL			;A = WZ[7:0]
	LD L,A			;HL = WZ[13:0]
	RET

Tests

⚠️ **GitHub.com Fallback** ⚠️