Please take a look at the first URL. ZX lines are interlaced x8 like CPC ones, but ZX has 3 screen blocks. CPC has 1 fullscreen block. The HL register is used as shown at the graph. The Y coordinate bits are rearranged so memory mapping fix to the three blocks.
If you have a pseudo ZX framebuffer at CPC's &4000 without the 3 blocks, just one full block, just modify how Y bits are stored in HL and you have a just 1 block framebuffer interlaced x8.
The trick is that Y5, Y4 and Y3 are used as low bits for Y coirdinate. This maps 4x 2kb blocks, and 3 of them are used for the 3 screen blocks.
You have spectrum like geometry , but the map is 010 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 ... But ZX is 010 Y7 Y6 Y2 Y1 Y0 Y5 Y4 Y3 ...
You have to change the way HL is used , change the H increments for the Y2-Y0 to L, and the L block manipulation of Y5-Y3 to H