maziac / DeZog

Visual Studio Code Debugger for Z80/ZX Spectrum.
MIT License
212 stars 35 forks source link

[Feature Request] Zsim: add support for custom IO bindings #32

Closed Centurion256 closed 3 years ago

Centurion256 commented 3 years ago

While using dezog and zsim to develop and debug programs for native Z80, one feature that comes to mind is support for custom IO bindings. Custom IO bindings would allow users to somehow handle input or output to different ports using their own custom logic. Basically, this interface lets the emulator interact with real or emulated IO devices that the user provides.

I thought about this for a while, and it seems to me that the most fitting tool for this would be to utilize sockets. Here is one way this could be implemented:

  1. User sets useCustomIO field to true in order to enable custom IO functionality
  2. User assigns the inputSockets field as follows:
    "inputSockets": [
    {
        "inPort":  "desired_input_port",
        "ipAddress": "desired_ip_address",
        "TCPPort": "desired_tcp_port"
    },
    ],

    A similar object is defined for outputSockets. The terminology is a bit confusing, but inPort or outPort represent the port specified in the in reg, (*) or out (*), reg Z80 assembly instructions, while TCPPort corresponds to a TCP port which uniquely identifies an application on an end device. In case of input, the emulator sends a request upon execution of the "in" command. It then tries to read from the socket and blocks until the response has been received. In case of output, the emulator simply writes the output information to the corresponding socket and continues execution. It is up to the user to implement the correct interface on the other side.

What do you think? I'm willing to help you with this if you wish, although I'm not very familiar with the source code yet. I can also provide a simple client side program for testing purposes.

PS: I am the same person who opened the issue with the ld instruction not being executed properly

maziac commented 3 years ago

Could you describe a complete use case of this. I.e. a complete example what the program would do on the other side of the socket.

I was also thinking about implementing some custom interface for the ports. But I was thinking more of the way the ZX keyboard was implemented in zsim. I.e. for input one could define input ports that would show up in zsim as buttons, organized as 8 buttons for a byte, and one could set/reset the bits in the input port byte individually from the UI. For output even simpler 8 small boxes would be showing the bit state of the port.

That is why I'm asking: Do you have a use case that would not fit with this idea. Do you need to really control another program via sockets?

Centurion256 commented 3 years ago

Yes, I can provide a use case: for example, timers can be interfaced in this way, with different output ports we can configure a timer (set capture-compare, prescaler), start the timer or stop it. With input ports we can read it's value or block until it finishes counting. Ultimately, on a real Z80 computer, I plan to use hardware timers and a IO controller to implement preemptive multitasking in my OS (this is how the dispatcher/scheduler knows when to switch or create processes). Of course I'd rather first test this in some emulated environment, before actually ordering a PCB and potentially missing some important issues.

It would be very difficult to simulate this behaviour using the visual interface you proposed, although I think that it could also be useful for other purposes, especially when debugging simple programs.

maziac commented 3 years ago

OK, I understand your requirement now better.

The zsim simulation so far supports only little HW like some ZX specifics e.g. screen, keyboard. It would, of course, be cool if this "HW" could be extended in some generic form.

I don't like the idea too much to use sockets. I had to use them in some places with DeZog already and it's always a pain until they correctly work. (In node is an additional pain to get them correctly closed.)

It would be nice if it would be somehow possible to configure this HW in a way that sockets are not needed. On the other way I also don't see any other practical solution to it.

But if a socket is used than only one socket should be used. I.e. a communication socket from zsim to the outside world. Then at least a minimum protocol is required. And it is important that the interface is NOT blocking.

Maybe it is also required to output some sort of clock. Not at 3 MHz, of course, that would mean too much traffic. But maybe something at 1kHz. That can be used to align timers etc.

The minimal protocol could simulate the bus. Maybe the following format: 1 byte: control information 2 byte: address 1 byte: data

For an port output eg.: 0x01, 0xABCD, 0xA5 Meaning: 0x01=port out, 0xABCD the port address, 0xA5 the data that was written.

Input is the same but would be sent from the client (the program connected to DeZog). DeZog would simply store this in an array. Internally zsim just reads the array. i.e. this would not block.

I have not yet completely thought this through, but this could be the direction, as it is extendable.

maziac commented 3 years ago

Hi,

it took some time but now there is an API to implement peripherals. It is quite different compared to my last post as I found a way to do it without using sockets. I think/hope that it is more convenient to use.

There is documentation available please have a look here: https://github.com/maziac/DeZog/blob/develop/documentation/zsimPeripherals.md

It also includes a sample project.

Please note that this is not released yet. You need to follow the link as nothing of this is on the master branch, it is on branch 'develop' only. If you think this would be useful to you, I could provide an alpha-release for you for testing.

Centurion256 commented 3 years ago

Hello,

Thank you for your effort. I took a look at the documentation, it indeed seems to be simpler and more flexible than the socket implementation I proposed. It would be great if you could provide me with an alpha version.

maziac commented 3 years ago

Hi, here is the link to a test version: https://github.com/maziac/DeZog/releases/tag/v2.0.0

This also includes other changes for the new 2.0 version. I.e. you need to adjust your launch.json. I'm trying to setup migration documentation, see here (develop branch): https://github.com/maziac/DeZog/blob/develop/documentation/Migration.md Please let me know if something is missing.

I'm not sure which assembler you use. If you use sjasmplus the idea is to change from list file to sld file. Anyhow at the moment you can still use both formats.

And keep in mind: this is an alpha version: expect errors.

maziac commented 3 years ago

Did you find some time to test the new DeZog meanwhile?