Hello fellow retroists,
Having recently got CP/M booting directly on my eZ80 for RC kit, I wanted/needed a way to run CP/M programs that directly access hardware. Programs designed for standard RomWBW based RC2014/RCBus systems with a stock Z80 CPU - that assume 8-bit I/O addressing and expect Wayne's HBIOS BIOS (RST 8) functions.
This is where the system boots directly from storage - without the typical 512K RAM/ROM module running RomWBW. Its loads CP/M into a section of its linear memory address and implements a CBIOS for the eZ80's and associated hardware.
As there is no RomWBW - then there is no HBIOS - so I needed to create a compatibility layer - a set of minimal equivalent HBIOS functions for various features (such as timers and uart etc)
I wanted to be able to run various RomWBW distributed applications (eg: WDATE, TIMER, TUNE and others...)
WDATE and TIMER only needed me to implement the required HBIOS calls. I can now run those programs directly - no recompile -- they just work.
But for
TUNE.COM - I was only able to get it to work with the --HBIOS argument - where it directs PTx streams to the HBIOS sound driver. Running it this way works - but its limited to just the 3 standard audio channels - no noise channel support.
To get full compatibility, I needed to wrap the execution of the TUNE program - and fully interpret the binary - translating all I/O operations to the appropriate platform range of $FFxx. I had to write a Z80 emulator to run on the eZ80. (Zilog all the way down!) I got a version committed to my repo yesterday, and now I can do the following CP/M command and play any tune targetting any hardware:
EMU TUNE ITERATN.PT3 --MSX
EMU.COM is a Z80 emulator program running on the eZ80 CPU. It's a full Z80 instruction set emulator - with all I/O forceably mapped to the range $FFxx - it also ignores unimplemented opcodes, preventing the eZ80's rebooting when it encounters unimplemented opcodes.
The emulator switches between native and interpreted code. When the program makes any BDOS/HBIOS call, the system switches back to native execution - so all OS and HBIOS calls run natively on the CPU - only the program's code is executed under the interpreter.
Its obviously slower - but for the TUNE example - its still more than fast enough to play at the correct speed.
It was a learning experience trying to create this EMU program (I had previously implemented the Z80 interpreter). It was not too complicated, but rather fiddly - re-hooking the BDOS (CALL 5), WARM BOOT (CALL 0), and HBIOS calls to be intercepted - relocating code below BDOS - restoring the hooks on exit etc - and correctly parsing the command line (I did not know that the CCP parses the command line extracting filenames into the default FCBs - now I do).
It needs more testing and more features are need to be completed/added.
Cheers
Dean