v0.9.0
zenas v0.9.0 — bugfix release
Both real bugs reported are fixed and verified. Short version: the DDCB/FDCB workaround and the 0x-hex-constant substitution can both be safely reverted once you're on zenas v0.9.0. The print-routine bug isn't zenas/zendis/zenzx's — that one's yours to keep as fixed.
1. DDCB/FDCB group — now assembles directly
What was true: zenas had no encoding for BIT/RES/SET n,(IX+d)/(IY+d), or for the indexed rotate/shift forms either (RLC/RRC/RL/RR/SLA/SRA/SRL). Confirmed — there was no DDCB/FDCB handling anywhere in the encoder before this fix. zen80 already executes the group correctly; zenas just couldn't produce it.
What's fixed: all of it, for the documented forms. Verified against real assembled output, not just unit tests — the opcode byte is identical to the existing (HL) form's own; only the index prefix and displacement byte are inserted before it:
BIT 7, (IY+0) -> FD CB 00 7E
RES 3, (IX+10) -> DD CB 0A 9E
SET 0, (IY-5) -> FD CB FB C6
RLC (IX+5) -> DD CB 05 06
RRC (IY-3) -> FD CB FD 0E
Safe to revert: the LD-preserves-flags idiom at all 21 flag-access sites. Plain BIT n,(IY+d) / SET n,(IX+d) / RES n,(IX+d) etc. now assemble directly, at the correct byte count and cycle count — no more workaround cost.
Still not implemented — don't assume these work:
- The undocumented copy-to-register forms (e.g.
RLC (IX+d),B— rotate the memory operand and copy the result into a register in one instruction). Out of scope for this fix, not silently dropped. SLL/SLS(the undocumented 8th shift). Wasn't supported for(HL)either before this fix, so this isn't a regression — just still unimplemented everywhere, not just for indexed operands.
If you don't use either of those two, you're fully unblocked.
2. Hex-literal parsing — 0BCH-style now works
What was true, and why: a hex literal written the traditional way — leading 0 when the first significant digit is itself a letter, so it doesn't get parsed as an identifier (0BCH, 0FFh, 0DEADh) — was misread as a broken 0b-prefixed binary literal, or split into a stray 0d token plus a leftover identifier. Root cause: three separate places in the lexer checked "does this start with 0b/0d?" without ever checking "does it end in H?" — the lexer's own token dispatch, a second, independent bug in the exported ParseNumber, and the 0d spaced-hexdump radix marker (.DB 0d 222 173) — the third one found while verifying the first two, not in your original report, but real and worth knowing about if you're generating any spaced hexdump directives.
What's fixed: all three sites, same disambiguation everywhere. Verified directly:
0BCH -> 0xBC (was: parse error)
0FFh -> 0xFF
0DEADh -> 0xDEAD (was: split into "0d" + "EADh")
0b10101010 -> 0xAA (genuine 0b-binary literal, unaffected -- checked explicitly)
.DB 0d 222 173 -> unaffected -- checked explicitly
Safe to revert: whatever substitution you'd made to route around this -- going back to 0x-prefixed hex, or whatever else you'd generated instead, is no longer necessary. Both notations work now; use whichever your generator already prefers.
Upgrading
zenas v0.9.0 is the release with both fixes. Full test suite (including new, targeted regression tests for both bugs -- 24 cases for DDCB/FDCB alone, covering every affected mnemonic on both IX and IY with positive and negative displacements) passes clean.
Full Changelog: v0.8.1...v0.9.0