MEMPTR - redcode/Z80 GitHub Wiki
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 bco ∧ a ≠ (hli) :pci + 1 else: memptr + 1
|
cpd |
memptr - 1 |
cpdr |
if bco ∧ a ≠ (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
|
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. |
;
;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