Last week I issued the second Z80 programming challenge:
Target: under 50 bytes.
- Your program shouldn't rely on the initial contents of registers.
- No RAM/ROM other than the screen memory should be written to.
- Programs must return. The
RET
instruction is included in the size. - So everyone has a fair chance comment with the code size not code.
- There are no prizes, just the chance to show off your coding skills.
Final Results
We stepped up the difficultly for the second challenge so congratulations to everyone who entered. Introspec ZX and Tim Webber discovered the shortest solutions. Here are the final results:
Coder | Size |
---|---|
Introspec Zx | 34 |
Tim Webber | 34 |
John Metcalf | 34 |
Paul Rhodes | 35 |
Simon Brattel | 35 |
Jim Bagley | 36 |
Steve Wetherill | 38 |
John Young | 49 |
Chris Walsh | 49 |
Dariusz EM | 50 |
Winning Entries
Introspec submitted the first 34 byte solution using a couple of neat tricks. Note the use of CP L
to check which side of the screen it's working on and the byte saved by setting B
to #58
:
ld hl,16384+6912
screenflip: ld d,h
ld a,l
xor #1F
ld e,a
cp l
jr nc,noflip
ld a,(de)
ld c,(hl)
ld (hl),a
ld a,c
ld (de),a
noflip: ld b,#58
ld a,h
cp b
jr nc,skipattr
byteflip: rlc (hl)
rra
djnz byteflip
ld (hl),a
skipattr: dec hl
bit 6,h
jr nz,screenflip
ret
Tim Webber's solution saves a series of addresses on the stack to be used later:
start: ld hl,23296
loop1: dec hl
bit 6, h
ret z
ld a, 87
cp h
jr c, noinv
ld b,8
doinv: rl (hl)
rra
djnz doinv
ld (hl), a
noinv: push hl
bit 4,l
jr nz, loop1
pop de
pop hl
ld a,(de)
ld c, (hl)
ld (hl), a
ex de, hl
ld (hl), c
jr loop1
Although I didn't enter I also found a couple of 34 byte solutions. The first mirrors two bytes in the inner loop:
ld hl,16384
mirror: ld d,h
ld a,l
xor 31
ld e,a
ld a,h
cp 91
ret z
cp 88
ld a,(de)
ld c,a
jr nc,attrib
ld b,8
rrca
mirrorbits: rl (hl)
rra
djnz mirrorbits
db 1 ; skip the next two instructions
attrib: ld a,(hl)
ld (hl),c
ld (de),a
inc l
inc hl
jr mirror
My second has two separate loops. The first loop mirrors bytes, the second mirrors the screen:
ld hl,22527
mir: ld a,128
mirrorbits: rl (hl)
rra
jr nc,mirrorbits
ld (hl),a
dec hl
bit 6,h
jr nz,mir
mirror: inc hl
ld d,h
ld a,l
xor 31
ld e,a
ld a,h
cp 91
ret z
ld a,(de)
ld c,a
ld a,(hl)
ld (hl),c
ld (de),a
inc l
jr mirror
Is 34 Bytes Optimal?
Definitely not! After the deadline a solution was discovered that combines code from Tim Webber and Introspec's entries to mirror the screen in 33 bytes:
start: ld hl,23296 ; Tim Webber/Introspec
loop1: dec hl
bit 6, h
ret z
ld a, h
ld b,88
cp b
jr nc, noinv
doinv: rlc (hl)
rra
djnz doinv
ld (hl), a
noinv: push hl
bit 4,l
jr nz, loop1
pop de
pop hl
ld a,(de)
ld c, (hl)
ld (hl), a
ex de, hl
ld (hl), c
jr loop1
Another 33 byte solution combines the code from Tim Webber and Simon Brattel's entries:
start: ld hl,23296 ; Tim Webber/Simon Brattel
loop1: dec hl
ld a,h
cp 88
jr nc, noinv
and 64
ret z
add a,a
doinv: rlc (hl)
rra
jr nc,doinv
ld (hl), a
noinv: push hl
bit 4,l
jr nz, loop1
pop de
pop hl
ld a,(de)
ld c, (hl)
ld (hl), a
ex de, hl
ld (hl), c
jr loop1
Entries will be available shortly on John Young's website. Thanks to everyone who entered for making the contest a success :-)