Re: Memotest 2017 - Z80 coding contest
Posted: 14 Oct 2017 22:36
My entry came in at 41 bytes and 181 cycles.
It was tested in MEMU running CPM.
It was tested in MEMU running CPM.
The world's first? Memotech MTX Forum
http://www.mtxworld.dk/memorum/
Code: Select all
CALC_PRNG
;* p := p XOR q XOR (p ROL a) XOR ((p XOR q) SHL b)
;* 1111111 1111111
;* q := ((p XOR q) ROL c)
;* 1111111
LD A, L ; BC = DE = (HL XOR DE)
XOR E ; HL = old p
LD C, A
LD E, A
LD A, H
XOR D
LD B, A
LD D, A
; ????????????? SWAP BC and DE USAGE ???????????????
;* p := p XOR q XOR (p ROL a) XOR ((p XOR q) SHL b)
;* 1111111 2222222 1111111
XOR A ; HL = p ROL a
SRL H
RR L
RRA
SRL H
RR L
RRA
OR H
;LD H, A
;* p := p XOR q XOR (p ROL a) XOR ((p XOR q) SHL b)
;* 1111111 333 2222222 1111111
;LD A, H ; BC = (p XOR q) XOR (p XOR a)
XOR B ; DE still equal p XOR q
LD B, A ; HL = not needed any more
LD A, L
XOR C
LD C, A
LD H, D
LD L, E ; HL = DE = p XOR q
;* q := ((p XOR q) ROL c)
;* 1111111 22222
LD A, D ; LSBit into C flag
RRA
RR E ; ROT LSB with C flag
LD A, D ; ROT MSB with C flag
RRA
LD D, E
LD E, A
;* p := p XOR q XOR (p ROL a) XOR ((p XOR q) SHL b)
;* 1111111 333 2222222 1111111 44444
ADD HL, HL
ADD HL, HL
;* p := p XOR q XOR (p ROL a) XOR ((p XOR q) SHL b)
;* 1111111 333 2222222 555 1111111 44444
LD A, H
XOR B
LD B, A
LD A, L
XOR C
LD C, A
; At this point
; BC = new p
; DE = new q
LD H, B
LD L, C
ADD HL, DE
; BC = new p
; HL = PRNG
LD A, B ; Swap BC & HL
LD B, H
LD H, A
LD A, C
LD C, L
LD L, A
RET
I found EX AF,AF' not to be helpful and did not use it, the problem being that while it might save A the carry flag is also switched out and vice-versa. Using the stack was banned mainly to save people from themselves - it was unnecessary and just made the code slower.There was general agreement about the types of optimisations that could be used to reduce the size of the solution, including :-
* rewriting the expressions for P and Q to factorise out common terms, ie: P XOR Q
* rotating in the opposite direction if it was quicker eg: ROL 7 as ROR 1 and swap bytes
* do two XORs in a single operation
* removing instructions that did something then the opposite immedately afterwards
* using alternate registers as save/restore
* picking the registers to hold P and Q on entry/exit so as to leave other registers free that can do other things eg: using P=DE, Q=BC, freeing up HL for the PRN, which is handy as you can ADD HL,HL
* rotating the 17 bit values through the carry
Best PRNG16 and PRNG17 code to follow ...What makes the advanced challenge harder is that p and q are 17-bit, not 16-bit. You can represent the two extra state bits however you choose.