Menu

#199 Interface I Local Area Network emulation

open
nobody
None
5
2024-09-16
2009-04-15
No

This patch add *basic* IF1 LAN emulation to fuse.

The Sinclair NET is a one wire realtime fast network without handshaking. Every word in the previouse sentence cause problems in emulations :(
1., one wire:
In a spectrum LAN all IF1 connected to a common wire pair (Data and GND), so every spectrum look all signal on the wire at the same time (like coaxial ethernet or arcnet)
To implement this with FIFOs, FILEs or SOCKETs is an 'Impossible Mission'...
2., fast network
Between 2 data bit there is only 5 machine code instruction execution time, and between two byte there are only 10 more z80 instructions.
To implement this with 'no-so-real-time' FIFOs, FILEs or SOCKETs is more than an 'Impossible Mission'...
3., without handshaking
There is no any handshaking line and there is only a very minimal synchronisation mechanism in the protocoll. (Only one ACK byte after each header and data packet)
To implement the protocoll with similar technic as the RS232 emulation is quite an 'Impossible Mission'

BTW: the protocoll in a nutshell:
Every network station has a network station number (1-64).
The data sent by packets. Every data packet has a 8 byte header packet. A data packet is maximum 255 byte length.

Sending:
First IF1 start monitoring the network line. If there is no activity if1 start to send its own network station number as a final check (During sending, monitor the line to see there is no any 'foreign' activity).
After that, if1 sends the first packet header, and waits for a response byte (0x01). If there is no response in time, if1 sends the header again and again...
If somebody sends a response, then if1 start to sends the data bytes, and waits for a response byte (0x01) again. If there is no response in time, if1 sends the data again and again...
And if there is a response, start the next header and data... and so on.

Receiving:
First if1 start to monitor the line. If there is a start 'bit' than wait some time (skip the first network station number).
After that wait for line activity and read the 8 header byte. If the header checksum, the destination and source station numbers, the serial number of the block are the same as expected sends the response byte.
After that wait for activity and read the data bytes. If data checksum is correct send the response byte.

The implementation:
There is no any way to implement handshaking between two or more runnig fuse, so the emulated network is totally unsynchronised.
Without any 'network hub' only two fuse connected into 'network'.
There is two 'network line': one for sending and one for receiving data, so we have to connect first fuse's `In' line to second fuse's `Out' and vica versa.
When we send something over the network (e.g. SAVE *"n";2) fuse `send' response bytes automatically, so if1 send all header and data without any interaction from the second fuse. If on the second fuse we didn't start receiving (e.g. LOAD *"n";1) its drop all data. So, this is not too realistic.
But if we start receiving (first), then the data is arrive.

In order to create a (more or less) working emulation, fuse has to check a lot of thing. So, we have to check PC to decide where come from the IN or OUT in order to know what we expect (start bit, data bits, release of line, etc), or what we have to send.
We have to compare the header with data in Spectrum memory, in order to receive or drop data when IF1 really wait it or not.
In order to drop unwanted data and detect user cancelation of receiving, there is a new event which appear at every frame once.

Because we have to check PC and memory this emulation works only with IF1 ROM V1 and V2, and of curse with the "original" protocoll.

Example usage (Linux :)

...> mkfifo /tmp/if11
...> mkfifo /tmp/if12
...> fuse -m 48 --interface1 --net-in /tmp/if12 --net-out /tmp/if11
...> fuse -m 48 --interface1 --net-in /tmp/if11 --net-out /tmp/if12

Now on fuse (A):

LOAD \*;"n";2

Now on fuse \(B\):

5 CLS[ENTER]
10 BORDER 6[ENTER]
FORMAT "n";2
SAVE *"n";1

Discussion

  • Gergely Szasz

    Gergely Szasz - 2009-04-15
     
  • Gergely Szasz

    Gergely Szasz - 2009-04-20

    Here is a new patch.

    This patch include a HUB which could connect together more than two fuse, even across the internet.

    The network emulation is changed a little bit. Now, if Fuse want to send data, first emulate network usage to prevent if1 sending the data and send a 'pre-header' and wait for an ACK. If the other end (or somebody in the network) accept the packet, then fuse release the line and read and send the real packet. It practically works like in real life, except one thing: on a real network, if1 send packet again and again while somebody send a valid ack.
    With broadcast there is no ACk, so Fuse read packet even nobody accept the packet.

    Usage of `fhub':
    First we need a `server': simply start `fhub' without any option
    Now, we can connect up to 64 `network interface': `fhub -c server.host.address'
    After that we can connect one Fuse to each `network interface': `fuse --interface1 --net-in /tmp/fhub_i_01 --net-out /tmp/fhub_o_01'
    The correct FIFO names for '--net-in' and '--net-out' we can see on status list in the `network interface' `fhub': just type `stat[ENTER]'. In the line beginning with 'Fuse connected to (in/out):' we can see the full names of the created FIFOs.
    Now, we can use Sinclair Loacal Area Network.
    With `fhub' we can capture traffic on `network interface's or even on the 'hub'. To catch a file, just type: e.g. `get 1.bin' on `fhub' prompt. Now prompt change to 'fhub [1.bin]>' Now, if we e.g.: SAVE *"n";2 SCREEN$ in first Fuse and LOAD *"n";1 SCREEN$ in second Fuse, we get the file in './1.bin'. This file begin with a 9 byte header. If we need only the pure data just type `header' (before `get blahblah') in `fhub' in order to toggle headerless file capture mode. We can capture (headerless) PRINT# files too.
    I'm working on:
    - if we close Fuse when its sending data, may leave 'nic's and 'hub' in inconsistent state
    - not just get, but put (send) files from the host machine to Spectrum
    - get/put files from/to Fuse without Hub and other Spectrum

     
  • Gergely Szasz

    Gergely Szasz - 2009-04-20
     
  • Gergely Szasz

    Gergely Szasz - 2009-06-23

    Here is an improved new patch. Now, the `network game' from Interface I and Microdrive Manual (ftp://ftp.worldofspectrum.org/pub/sinclair/hardware-info/ZXInterfaceIAndMicrodrive_Manual.pdf) works (there is a bug inthe program: if we ask a new game -> Variable not found.. because in line 240 program use RUN 20 which delete all variables but not initialise again...)

    I attach the netgame.szx if somebody want to test :)

    fuse> mkfifo /tmp/fhub_i_01
    fuse> mkfifo /tmp/fhub_o_01
    fuse> fuse --net-in /tmp/fhub_i_01 --net-out /tmp/fhub_o_01 --interface1 netgame.szx
    fuse> fuse --net-in /tmp/fhub_o_01 --net-out /tmp/fhub_i_01 --interface1 netgame.szx

     
  • Gergely Szasz

    Gergely Szasz - 2009-06-23
     
  • Gergely Szasz

    Gergely Szasz - 2009-06-23
     
  • Gergely Szasz

    Gergely Szasz - 2009-06-23

    Here is a patch which add `fhub' to fuse-utils.

     
  • Gergely Szasz

    Gergely Szasz - 2009-06-23

    fhub for fuse-utils

     
  • Stuart Brady

    Stuart Brady - 2011-04-06

    My comments may be two years too late, but hopefully better late than never. :-)

    I really think this should be done in a manner that allows sharing code with DISCiPLE emulation, and allow using a modified IF1 ROM. This means that we should try to rely on events rather than on specific values of PC (and if we do rely on values of PC, then keep those to a minimum). My patch for SAM Messenger emulation should show roughly how you can use events to achieve this, although I could accept that the Sinclair network might be little more complex. Also, any common code between the DISCiPLE and IF1 really belongs in a separate file. That probably means all of the network emulation code, except for the I/O port handling and any sets of values of PC that you use.

    Except for these two fairly minor points, I get the impression that this patch was most of the way there!

     
  • Gergely Szasz

    Gergely Szasz - 2024-09-16

    This is an updated patch to bring Netgame work again...

    On linux console:

    mkfifo /tmp/snet_i_01
    mkfifo /tmp/snet_o_01
    ./fuse --net-in /tmp/snet_i_01 --net-out /tmp/snet_o_01 --interface1 ../netgame.szx &
    ./fuse --net-in /tmp/snet_o_01 --net-out /tmp/snet_i_01 --interface1 ../netgame.szx &
    
     

    Last edit: Gergely Szasz 2024-09-17
  • Justin Eastham

    Justin Eastham - 2024-09-16

    Thank you, Gergely.......much appreciated :-)

     

    Last edit: Justin Eastham 2024-09-16
    • Gergely Szasz

      Gergely Szasz - 2024-09-17

      I'm thinking there's a typo in the above.....

      mkfifo /tmp/snet_i_01
      mkfifo /tmp/snet_i_01

      ......should be :

      mkfifo /tmp/snet_i_01
      mkfifo /tmp/snet_o_01

      Oh, yes ... the curse of copy-paste :(

      Thanks,
      Gergely

       

      Last edit: Gergely Szasz 2024-09-17

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.