On the recommendation of @Marcel van Kervinck I took another look at emulating an Intel-based CPU. I was scared off initially by the complexity of the Z80, but the base 8080 instructions are fairly manageable. The initial work on the COSMAC was useful in figuring out how to approach the development of a virtual CPU, but the decision was made to abandon the COSMAC and focus on the 8080.
Given the state of things these days, I was able to complete the development in only 4 weeks. It's still far from done though. Although the code is complete (almost 80 pages) none of it has been tested and there is currently no reasonable way to do this. The code will need unit tests and this involves building some form of simulator to verify the instructions work correctly.
Another consideration is the video memory. The COSMAC had many index registers and the lower few are reserved hardware-specific tasks like DMA and interrupt handling. These weren't needed, so these registers were targeted to the video memory bank. This is not possible with the 8080, so an alternative approach is needed. The current idea is to partially implement the Z80 IX and IY registers and use these to address the video RAM. These wouldn't need to support the actual Z80 instructions though, so there is plenty of room for customization.
Some initial performance numbers can be calculated based on the implementation. The virtual 8080 will operate with an equivalent clock speed around 450kHz or about 60kIPS. This is about 22% the speed of the original 2MHz 8080, or about 15% of the 3MHz 8080A/8085 version. The underlying hardware runs at 8.25MHz, so it takes about 137 CPU clock cycles to execute a singe vCPU instruction (this includes the video control and sync overheads).