Currently you use ports to print stuff in the CP/M subroutines.
You could change this to something else for readability's sake. At the very least I think it'd make sense to change the subroutine using IN to use OUT, which makes more sense. (Especially since the input you get in that port is hardcoded to 0xFF now, for some reason.)
We talked about this on Discord, but just plonking it here for posterity.
It'd be nice if the disassembly in the debug output was an actual disassembly, ie. that it produced working assembly code. Right now you only print placeholder characters for immediate values, for example.
According to the manual, the ANI instruction clears the carry flag and the half flag (auxiliary flag). This isn't done in i8080.c (case 0xE6). I suggest adding c->hf = 0 at case 0xE6 to reflect this. It still passes all the test with this added, but it was just a discrepancy between my emulator and yours.