I’ve been mulling over a challenge in constrained programming - an application has recently come to light which might benefit from printable Z80 code. That is, I was thinking of CALLING code embedded in a REM statement on an Amstrad CPC (emulator here), to act as a bootstrap for this coprocessor adapter by @Revaldinho:
A REM statement should be a convenient and dense way to get a little bit of machine code into a machine, but whereas Sinclair’s machines allow easy entry of pretty much any byte value into a REM, I think Locomotive Basic doesn’t. And whereas I’m familiar with the x86 being programmed using only bytes in the range 0x20 to 0x7e, it seems a little challenging on the Z80.
According to this opcode map, we do get all sorts of register moves and load and store, and inc and dec, and even a doubling operator, as well as a small handful of conditional jumps. And we get a complement instruction. But for a backward jump, or a return, or an IN, we will need an unprintable byte, so I think we’re forced to construct or modify some code bytes in a preamble.
Hmm, but it might turn out that the resultant REM statement is so long that a simple Basic equivalent will be easier to type in… as this is only a first bootstrap, performance isn’t an issue. For example:
FOR A=1024 TO 1048
POKE A,INP(&FD80)
NEXT
CALL 1024
(I’m deliberately keeping this very simple: open-loop communication with no checking, and just pulling a specific constant number of bytes. The coprocessor provides the bytes, and they form the second level of bootstrap which can run a bit more robustly and generally, to load the third level, or maybe the application.)
See also the previous discussion in Communications on Toshiba T1000 laptop, where we found several links about programming the x86 using only printable ASCII (or even, only ECHOable ASCII). And for entertainment here’s a video about a 20 page text file which contains its own source code, its rationale, and is also a DOS application: