udo-munk / z80pack

A Zilog Z80 and Intel 8080 systems emulation
MIT License
162 stars 37 forks source link

Bios conin in cpmsys disks cpm22-1.dsk #446

Closed brian-sheldon closed 2 months ago

brian-sheldon commented 2 months ago

While developing my own simulation system, I have been using the cpm 2.2 system disk from the emu8080.js simulator. I wanted to test another,system disk, so I tried the cpm22-1.dsk img from cpmsin disks folder. I was surprised to see it boot as I thought the bios would be very different.

However, at this point, I realized it was not respnding to any keyboard input other than the enter key. Turns out to be an issue with how conin varies in the two bios implementations. The emu8070.js bios has a loop that waits for input to be available before reading the character buffer and returning. The cpmsim bios just returns with whatever input is provided by the sim emulation system, which appears to cause issues. This requires the hardware sim to do the waiting, rather than the bios.

Thinking about this from a hardware point of view, this would effectively be implementing a wait state simulation, which I doibt would be a typical way of implementing these types of devices, but I could be wrong.

Question, what should the standard be for conin, wait loop in the bios, wait loop in hardware, or is there a character that can be returned to prevent negatives effects in cp/m?

Not a big issue for me as I can modify what is needed, I just want the mod to follow standars if they exist. Plus I want to have this information out there as others my run into this issue.

udo-munk commented 2 months ago

There is no easy answer to this. Some other emulations copied hardware implementation from Z80pack machines, which is OK of course, so an OS build for a Z80pack machine might also work on another emulation. If there are implementation differences it will work to some degree, but not everything the same of course. The cpmsim machine usually is running full speed without CPU throttling. Now a lot of 8080/Z80 software is using polling for I/O, for example to check if there is input from the console. This will cause 100% load on the physical host CPU running an emulated 8080/Z80 full speed, after a few seconds the fans will become noisy and blow hot air into your face. So cpmsims SIO's have an idle loop detection for such situations. IMSAI/Altair machines don't need this, because the emulated CPU runs with 2 or 4 MHz, so it is put to sleep often anyway. Then there is software that requires an exact emulation of some special SIO, for example MITS Basic standalone programs. These read the SIO data port without checking status, and if they won't get the expected result this programs don't work. Or look at the Z-1 Cromix implementation, Cromemco used Z80 vector interrupts, not polling all the serial ports at all. So there is no common standard, it all depends on the software you want to run on some emulated machine. If it is your own software you can adjust it appropriate for the machine, if it is historic software you can't or don't want to modify, the machine must be build appropriate to run it.

brian-sheldon commented 2 months ago

Thanks for the great response. It just so happened that I decided to work on implementing some form of idle energy saving. It suddenly occurred to me that knowing the system would be in this do nothing useful loop, there was no reason to keep the cpu emulation running.

I just finishes implementing the energy saving feature, took only minutes. So when conin gets called, if no input is in the buffer, I immediately stop the cpu emulation, setup an event to wait for input, once triggered, set register A to the input value, restart cpu emulation. Just a few short lines of code. And now the z80pack disk works perfectly in my emulator.

On my phone, with the emulator running about 8 mhz, the cpu utilization for the cpu emulation is now running about 0.1% when idle and peaks at around 20% when I run something. So yes, I definitely see how well this works.