kosarev / z80

Fast and flexible Z80/i8080 emulator with C++ and Python APIs
MIT License
65 stars 10 forks source link

Additional Python Callback Handlers #62

Open ToniWestbrook opened 2 months ago

ToniWestbrook commented 2 months ago

Hello - first off, thank you so much for the awesome work on this project. I've finished and will soon be releasing an emulator for a Z80, ISA bus compatible computer that's moving onto the hardware phase. In addition to your Z80 emulator, it contains a custom MMU for banking and interfacing with the ISA bus, a Zilog CTC emulator, a CGA/EGA/VGA text framebuffer emulator, a partial Intel 82077aa emulator for floppies, etc. However, I've had to make the following alterations to the Z80 code to accommodate my project, and I was wondering if you'd think they'd be useful enough to include in the base repo. As a bonus, that would also make it easier for me, as I can just include it as a dependency in my PyPi package and I won't have to include a whole modified copy of your Z80 package. My modifications are as follows:

  1. Python OUT instruction callback handler (it looks like you just added this - I should have just waited a couple weeks!)
  2. Python memory READ callback handler
  3. Python memory WRITE callback handler
  4. Python RETI callback handler (the Zilog CTC emulator needs an efficient way of monitoring when the interrupt routine ended besides polling fetched instructions and/or IFF registers)
  5. Python callback handler for getting the lower portion of the address for Interrupt Mode 2 vectors. I think currently you hard code 0xFF as the lower 8 bits as opposed to fetching it via a read cycle.

1-4 above I implement the exact way you do your other callbacks, very easy and straightforward. # 5 above I do a really hacky way right now by replacing the harcoded 0xFF with a read cycle request of address "-1", which I then detect in my READ callback handler and return the vector address accordingly. I could easily see this instead being an "on_get_int_vector" or something in the z80 base class that gets overridden in the python C module to check for a callback handler like the other 4 items above, but I didn't do it that way yet.

Apologies for the long ticket, but my questions are:

  1. Are there any built in ways that I missed of doing any of those things better?
  2. Would you be interested in incorporating any/all of these changes into your repo,
  3. If so, would you like me to submit what I've done for 1-4 or would you prefer to make the changes yourself
  4. If you'd like me to make a patch for functionality # 5 above, could you recommend which class and location in the class you'd suggest making the on_get_int_vector function? The base classes are all very large and complex (by necessity) and I don't want to disorganize them.

No worries too if you're not interested, I thought I'd just double check. Thanks again for an awesome project, it runs CP/M, MBASIC, all the games I've thrown at it, and all my custom MMU stuff (including memory resident drivers in other banks) with absolutely no problems - you did a great job!

kosarev commented 2 months ago

Hi Toni, yes, those are all exactly the kind of facilities the emulator is meant to provide (and I confirm we currently don't have these exposed in Python).

What you have implemented sounds perfectly reasonable and for the mode 2 int handler I think I would indeed introduce the on_get_int_vector() thing as you guessed, so please do create pull requests. Then should any polishing be necessary, such as finding the right places for new code, I can take care of that.

Thanks for sharing and the kind words. Exciting stuff it is that you are working on!

ToniWestbrook commented 2 months ago

Great, sounds good! I'll submit some pull requests in the next day or so. Thanks again!

mortenjc commented 2 months ago

I also want to applaude you for this project.

While I do not need this particular feature, the emulator has helped me tremendously in (almost) getting an old (1977) z80 based computer (Q1 Lite) up and running. This is being done as part of a Danish Computer History Foundation (pro bono) project.