I recently joined a Facebook group Z80 Assembly for the ZX Spectrum which, as its name suggests, is a group focused on Z80 assembly language coding for the ZX range of computers.
The group recently organized a couple of casual Z80 coding challenges, the first of which was to fill the ZX Spectrum screen with a checkerboard pattern:
Something simple for the first challenge. Write the shortest code to fill the screen with a chequerboard pattern of 1 pixel squares. No RAM, ROM other than the 6144 byte bitmap screen memory should be written to.
Target: under 25 bytes.
1. Your program shouldn’t rely on the initial contents of registers.
2. Programs must return. The RET instruction is included in the size.
3. So everyone has a fair chance comment with the code size not code.
4. There are no prizes, just the chance to show off your coding skill.
This yielded some interesting solutions, the winning examples of which are archived here on John Metcalf’s blog site. The winning solutions came in at 15 bytes (see link), I could only manage 16 bytes:
checker_speccy: ld hl,$5700
l0: dec l
The next challenge was to mirror the ZX Speccy screen:
Something slightly more complex this time. Write the shortest code to mirror the entire Sinclair Spectrum screen (256×192 pixels) left to right including the colours / attributes. The deadline is Monday 15th, midday (GMT).
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.
The winning solutions are again archived on John Metcalf’s site. The winning solution came in at 34(!) bytes; my effort came in @ a reasonable 38 bytes:
mirror_speccy: ld hl,$57ff
The Z80 programming prowess demonstrated by the winning entries is pretty impressive. The spec for the second challenge was to come up with a solution in the smallest number of bytes (which is not typical for real world applications), and I think many of us were thrown by this. For example, in order to save one byte in one of the winning solutions, Introspec observed that while seeking to load an immediate value of 0x8 in the B register, he already had the value 0x58 in the H register; the genius observation here was that 0x58 would do just as nicely as 0x8 since all that the value was used for was a loop count, and that rotating some registers around 88 (0x58) times is merely 11 times slower than rotating the same values 8 times, but it saves one whole byte, which is a win in this case!
Not that this stuff is directly useful in my day job, but I am definitely learning some new tricks here.
As an aside, I downloaded the excellent (and free!) “Zeus” Z80 development IDE by Simon Brattel for this stuff. The download (Windows only, unfortunately, but works well in VMWare Fusion on my Mac) can be found here, along with numerous example files. Zeus comprises an editor, assembler, disassembler, Spectrum Emulator and debugger. Highly recommended.
Looking forward to more of these challenges!