# Memotech MTX on the Internet

This website is being served by an MTX500 with Martin's NFX add-on.

The NFX has an IDE Compact Flash a ROM with 40 column CP/M on it. It also has a Wiznet W5100 which is what gives it physical connectivity to Ethernet.

At Memofest 2017, Martin handed an NFX to me (Andy), and suggested I try to get an MTX onto the Internet.

So I developed a program called NFX.COM which is what is serving up this page.

NFX.COM is hard-coded to use IP address 192.168.1.123, but you must already know this to see this page.

## Chargen service

It includes an implementation of the `chargen` service, running on port 19, and to see this, you can

    $ nc 192.168.1.123 19
    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh
    "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi
    #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij
    ^C

## Echo service

It includes an implementation of the `echo` service, running on port 7, and to see this, you can

    $ nc 192.168.1.123 7
    Hello World
    Hello World
    ^D

## HTTP service

It runs a simple web server, listening on port 80.

It can only serve requests to files in the root directory, as CP/M has no directory structure. Filenames must be 8.3 format. If the filename is omitted, it defaults to `INDEX.HTM`.

It knows the MIME types of a quite a few common file types found on CP/M filesystems, and a few common internet related types such as CSS, JS, GIF, PNG, JPG, TIF, ...

If it spots that it is returning a textual file, then it looks for the ^Z character, and stops returning file content.

If the HTTP service is started with POSTs and DELETEs allowed, then it is possible to upload content to the web server, or delete it :-

    $ curl -X POST --data-binary @newpage.htm http://192.168.1.123/newpage.htm
    $ curl -X DELETE http://192.168.1.123/newpage.htm

Note that uploaded content is padded with ^Z characters to complete the last 128 byte sector. CP/M files are always an integer number of 128 byte sectors long. ^Z is chosen, just in case the content is textual.

## How was it done

I constructed an embedded real-time OS kernel. This uses a "fibrous" programming model to allow multiple concurrent activities to proceed "in parallel". This is because we can be processing several network sockets at once.

In a fibrous model, many calls made to lower level services are passed a routine to call when the work is done, and a value to pass to it. They return immediately, having instructed but not completed the work. At a given level of coding, a thread of execution becomes a sequence of fibers, which are called one after another, often with gaps and other work interleaving them.

On top of this I constructed a library for interacting with the W5100, and network layer above of that. The network layer also provides a "fibrous" interface. So typically code says things like "listen for a connection, and call this fiber when done".

I found that SDCC doesn't generate particularly optimised code for doing block I/O transfers, so I recoded this part in assembler. This gave a 5% speed boost.

Finally, on top of this I created the services, which primarily just use the network layer.

## Speed

If you want to see how slow it is, trying fetching a maze from SMG2M, or big picture of NFX.