Back in 1983, I was writing the operating system for my microcomputer, later named "Galaksija" (Galaxy), as it was the name of magazine which published this DIY project for hobbyists (more than 8000 were built). It was based on Z80A CPU and it used EPROM 2732, which had only 4K of space for the operating system and BASIC programming language, so I had to save every byte I could.
Video was supported by software, and CPU had to execute 32 NOPs (which lasts exactly 32x4 clock cycles) to generate one scan line on the screen, as in the same time it automatically incremented R (Refresh) register which was transparently used to address video memory locations. I could also use some other non-conflicting instructions, assuming that they also take four clock cycles to execute. I used it to make some optimization, but there were still a lot of NOPs which "ate" my code space.
Several years before that, I didn't have computer and I had to assembe the code manually, with pencil and paper. There were some rules which helped me in this process, for instance instruction MOV r,r (move data from register to register) was coded like this:
Then I noticed something - bits 7 and 6 of the opcode, which were always 01 for LD instruction, are the same as in ASCII codes for uppercase characters. As Galaksija had uppercase only, I could replace NOPs with LD instructions, and use them at the same place as message strings (in fact, there were only three of them: BREAK, HOW and SORRY). The first one was suitable enough for my idea.
So I had the code which could be executed in two ways: as program code, and as message string, plus the terminator byte 0x00 (NOP again). The only thing I had to do is to repair some damage at some registers which were in use for video interrupt routine. I had enough NOPs (or LDs) for that.
Some more NOPs were already replaced with some useful 4-cycle instructions in video routine (not messages), but there were still four NOPs left, which I could use to save even more code space. I used them to store floating point zero constant (used in FP arithmetic routines), which was coded as 0x00000080 (last byte is FP exponent), but in Little Endian format, it was 00008000. NOP was "0x00", and what could be "0x80"? Luckily, it was non-conflicting LD A,B.
Ten bytes of free code space! Can you imagine how happy I was?
All fans of the Galaksija personal computer are welcome to the site dedicated to Galaksija and its clones - http://www.xn----7sbombne2agmgm0c.xn--p1ai/Galaksija/.
Here you can repeat new clones of this computer using Gerber files. See the section Galaksija Plus.
If you have any questions, you can contact me - fifan072@gmail.com