udo-munk / z80pack

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

DMA memory access should light the HOLD led on IMSAI CP-A #18

Open dmcnaugh opened 6 years ago

dmcnaugh commented 6 years ago

I noticed this while I was figuring out how the imsai-fif.c code worked. I see in the code a number of lines like

bus_request = 1
...
bus_request = 0

but this never lights the HOLD led, as the dma_write() function makes no updates to the front panel. Also there is no code to try and light the HOLD led at the time of any dma_read() in imsai-fif.c.

My first thought was to alter dma_read() and dma_write() to take care of lighting the HOLD led, but then I noticed other modules using dma_read() and dma_write() that aren't meant to be performing DMA memory access, e.g.

(the cromemco-dazzler.c does need to do DMA memory access from what I can tell as the real board doesn't have its own memory) This makes me think there is another kind of "internal" memory access that these modules require that memory.c currently doesn't provide. I have a working solution for this where I have created two new "internal" memory access functions I have named peek() and poke() for sentimental reasons.

Before I post a Pull-Request I am interested to get your feedback whether you agree with my thinking and my outlined solution.

udo-munk commented 6 years ago

The original Dazzler from 1976 does use DMA to access the main memory, the Dazzler II from 2016 uses dual ported RAM to avoid the cycle stealing from the CPU. Blinking the HOLD LED right now is a fake because the DMA device would request bus access from the CPU, which acknowledges this with the HOLD signal and then the LED is on. So far I have not tried the correct implementation because I don't know if the Dazzler display will be realistic enough with a correct implementation. Would be tricky anyway because we need to wait a few microseconds, but we can't with generic UNIX systems, the nanosecond timers are implemented only in real time systems, which folks don't have.

Then the frontpanel doing DMA access also is not correct, the real thing jams instructions into the bus. This is why the DMA functions don't update the LED, it would be just plain wrong.

The peek and poke functions would work arround this issues and the LED's would be a bit more correct, but IMHO the correct implementation should be prefered over one more hack.

This is time consuming so I postponed this to sometime, it is on my todo list. If you would like to work on the correct implementations for this stuff I'm willing to change my priority list and start working on this with you now, it has to be done anyway, but then other things have to wait...

dmcnaugh commented 6 years ago

This is not so important to me for 2 reasons:

The only thing I have left on my list of ideas to share that is not specicifc to my esp32 port is a full implementation of the MPU-B memory bank switching used to switch in/out the MPU-B boot ROM (also compatible with your MPU-A boot ROM) and a bit of RAM that was on the MPU-B. This then allows CP/M to access a full 64K of RAM on the IMSAI (assuming no VIO, but is also compatible if the VIO is selected/enabled). It works with the ROMs you provide with the IMSAI simulation, adheres to the 3 cycle delay, uses IO port 0f3h, the only variations from the spec I have made are:

udo-munk commented 6 years ago

I see it the same as you, correct DMA cycle can be implemented later, it is not so terrible important. Besides what we are doing here I'm working on a MITS 88-DCDD, probably a lot more users would appreciate this over a correct DMA implementation and a fp actually jamming instructions. Well, that would be interesting for your teaching probably.

Right, also the correct mapping of the ROM @ 0 and switching the ROM off would be more important IMHO, to get more memory for CP/M in a correct way.

That 3 cycle delay cause me headaches, why didn't they first jump to d810 and then switched the darn ROM off??? ;-) I sure would like to see your implementation, so fine with me if we do this next.

dmcnaugh commented 6 years ago

Yes, I have also included the double mapped ROM @ 0. It was messy at first, but I've come to like the solution I made. I doubt there are many examples of code other than the MPU-B ROM using this bank switching. Did you make the MPU-A ROM based on the MPU-B or is that original?

I will prepare a PR so you can take a look.

udo-munk commented 6 years ago

Both ROM's are originaly. The MPU-A one is quite interesting, because MPU-A doesn't have the memory management for what the monitor is doing. Must have been on some other board, which later was integrated into MPU-B.

dmcnaugh commented 6 years ago

Move discussion of MPU-B style banked ROM (and RAM) to #20

udo-munk commented 4 years ago

I added new memory access functions getmem() and putmem() to all memory.h sources. For now they are copies from the functions used for DMA devices. This needs to be corrected later, e.g. from the emulation frame we also want to write into ROM's for loading them, and so on. But now with the functions available one can start to rewrite the stuff doing incorrect memory access.

udo-munk commented 4 years ago

In the IMSAI the correct memory access function are used now, so I added update of the HOLD LED in the DMA functions. Works nicely with the FIF FDC, but DMA reads from the Dazzler slow down the PC emulation too much, so I commented updating the LED out in memory.h. Could be tried in the ESP32, probably updating the LED is not causing such an overhead.