Currently:

Netlink uses triggers via reading/writing ports 0x90-0x9F. To overcome
the situation to use this port by accident (in user programs, etc), they
can be only used from
the Enterprise segment where netlink.ROM, otherwise it will be handled
as a regular port. You can ask, why not a "more
standard" solution is used eg special traps via some unused opcode bytes,
etc. The answer: JSep is written by me, except the Z80 core which is not.
I am planning to replace it, modify it, etc, I don't want to put specific
code in it, just a regular Z80 emulator what I want to see there without
any tricks.





Writing port 0x90 (the exact value written does not count at all) triggers
the netlinkfs.rom ROM entry point events. JSep uses the actual Z80 registers to decide
what to do, and it also modifies them if needed. Again: in this case
the value written to 0x90 does not count too much ...

Reading port 0x90 is the "status" port, bits:
	Bit7: HTTP request is pending
	Bit6: HTTP answer error
		bit7 == 0 && bit6 == 0 -> HTTP req was OK
		bit7 == 0 && bit6 == 1 -> HTTP req resulted in ERROR


Writing port 0x91 is the device driver trap, in this case the data written
here _IS_ important, and it's the EXOS call code.




The purpose of NetLink is to provide some kind of primitive "network file
system" for the JSep JavaScript Enterprise-128 emulator. It consist of
the emulation of an "imagined hardware" (emulated by JSep) and softwares
which can use this "hardware" running inside the emulated Enterprise-128.
Note: this kind of hardware would be odd to implement for real (as a real
hardware, for real Enterprise-128) so it's quite unlikely to be usefull
for other purposes. However with a little effort it can be built into
another emulators as well.


Definitions:

	EP address:

		Always three bytes, in order:
			* the low byte of the address
			* the high byte of the address within the SEGMENT
			  (so highest two bits will be ignored!!!!!)
			* the SEGMENT number

		In case of EP address stored in memory, you must follow
		this order, to output an EP address with OUT Z80 op,
		you should also use this sequence.

		You are allowed to exploit the feature that high byte
		is only 6 bit width, and upper two bits are simply ignored.
		You don't need to mask those bits out!

	TWORD:

		Three-byte WORD, a 24 bit long number, consist of three
		bytes. You must be carefull, this is NOT THE SAME as
		EP address! Never ever mix them up! The byte order
		still the "natural" byte order - low byte, high byte, even
		higher byte :)
	
	Request:

		It's a command to be sent for the "hardware" to process
		a request. Most of them will cause to send out HTTP
		requests then (see below) but not all of them!

	HTTP request:

		The protocol (as JSep is written in JavaScript) is HTTP
		between the browser running JSep and the server. It's
		done via AJAX in JSep, but can be implemented to construct
		HTTP requests "by hand" in non-javascript emulators.

	Server:

		The server accepts and process requests sent via HTTP,
		and answer them. Currently that part is not open source,
		but you can implement one using the specification in any
		server side solution (PHP, ASP, Python, JSP, ASP, etc)
		You're free to use the services of JSep web site of course,
		but I keep the rights to close the service (globally or
		selectively for IPs) in case of abuses or other problems.
		Sorry, it's not a business grade service ...
		The server's URL is hard coded into JSep (but since you
		are free to download/use JSep, you can put custom version
		using another server ...).

	Directory:

		This is also colled "folder" ("mappa" in Hungarian)
		nowdays, however I hate that name, it's the good old
		directory for me, as it was before, always.
		The NetLink filesystem has directory hierarchy.
		However accessing the directory is not the same as with
		an EXDOS DISK, as this is not EXDOS (EXDOS using a fixed
		file system - FAT12 - which is not suitable our needs, we
		wants a networked, shared, clustered etc file system working
		throuh the network). More details will be available later
		in this document. The directory separator is / as it is with
		UNIX systems, but since DOS and similar systems uses \ because
		of a mistake of design of ancient DOS versions, both of /
		and \ are accepted, no difference.
	
	File name / file path:

		As the implementation of HTTP is state-less, you must
		always give full pathes! Because of this leading / or \
		is not required though. Walking through the directory
		structure is nothing from the viewpoint of the server,
		it must be implemented in software.

	"Drive letters":

		This kind of stuff is an ancient creation but still used
		by Windows and other systems, like C:, A:, you know. It's
		not used in the UNIX world though. In our file system we
		don't need these, as it's not covered by EXDOS, and also
		you are not limited (in size) so you don't need multiple
		"partitions", in theory you can have 10T storage used
		for JSep in a single directory structure ...


The emulated hardware is simple, to be able to use, you have four I/O ports.
We will call them as port A, B, C, D, to be able to assign a port number
later (but they should follow each other without a gap). Currently
ports between 0x90-0x93 are allocated for ports A, B, C and D.

Port A

	Reading this port is the STATUS register which gives information
	about the last given command.

	Writing this port is the COMMAND register which is some request
	for the "hardware".

Port B, C and D:

	These registers selects a memory area (within the Enterprise-128
	RAM!) to be used to communicate between the "hardware" and the
	software. You can modify any of them at any time, the ports in
	order forms an EP address! One important note though: the address
	is only modified (from the viewpoint of the "hardware") when
	the specific command is sent on port A (see later). This is needed
	as it would be dangerous to modify B, C and D ports and having
	some fatal before writing port D, so memory can be overwritten at
	bad address, or so ... NOTE: It's highly UNDEFINED what happens
	if you specify an EP address which is not RAM, or not decoded area
	at all!

	These ports are WRITE-ONLY ports.

STATUS register:

	Bit 7 is SET if "hardware" is busy (wait for the result!)
	Bit 0 - 6: is the error code
		Error code is only meaningfull if the the "hardware"
		is NOT busy. Then 0 means no error, other values
		mean some kind of error (see later).


Memory area aka "selector":

For proper set up of the address of this area see commands (command: 1)
later. Now the only important thing: the memory area must be set up
by the user and it's used to communicate between the "hardware" and the
software. You must be sure there is enough free RAM specified at setting
up the selector, max of 512 bytes are used! You are free to use the theory
to maintain multiple selectors and on demand just altering the selector
address (again, command 1). The exact layout of the selector/memory area is:

Symbol Offs  length   	meaning
------ ----- ------   	-----------------------------------------------------
SELTYP	+0	2	This WORD specifies the type of the selector. Different set
			of commands requires different kind of selectors.
			The very first byte of a selector shows the type of
			the given selector. Wrong selector type can be set
			up (port B, C and D write, than command 1) for a given
			command, but it causes to get an ERROR in STATUS register
			if you try to execute. This is some kind of protection.
			The lower 4 bits encodes the selector types.
			Currently supported selector types:
			0 = file operation selector
			1 = DMA selector
			2 = FPU selector
			The remaining upper 12 bits are information used
			differently with the given selector type. YOU MUST BE
			CAREFUL: these bits should be ZERO, if a given bit
			is not interpreted in current mode, as later versions
			may use them, so it's important to turn possible extra
			future bits OFF with older softwares!



FILE SELECTOR
~~~~~~~~~~~~~

File operation selector is selector type 0. The 12 upper bits in SELTYP field of the selector has
the following meaning:
		Bit 15: if this bit is set, FADDR is modified after successfull read/write ops.



Symbol Offs  length     meaning
------ ----- ------     -----------------------------------------------------
FNP	+2	3	Pointer (EP address) to the file name.
			The pointed file name must start with a byte
			describing the length of the file name, then
			that number of chatacter follows. You MUST
			use full path, always. Both of / and \ signs
			means "directory component separators", and
			I will write only about / in this document, but
			you can use \ too. Leading and trailing /
			(last case I wrote that I mean \ too) can be
			(and SHOULD) left out. This also means that
			zero length file name actually means the root
			directory of NetLinkFS. File names are case insensitive,
			within the emulator, all characters are converted to
			lower case. Character codes below 32 and above 127
			are INVALID. Two or more / signs after each other
			SHOULD NOT be used, however currently they are
			treated as single one. There is no need to "close"
			the file name with special byte, as length information
			encodes this perfectly. You can set up names
			pointing directory (not file), even root directory
			(zero length name) but general file read/write will
			fail on those, and special commands must be used
			to deal with them. You can figure out that maximal
			file length can be 255 characters, as length information
			is one byte. This also limits the "depth" of directory
			tree you can use, as you must use full paths, and
			file name would be too long once to access a deep
			(or not so deep, but long names ...) directories.
			IMPORTANT: Since it's not FAT file system, you are
			not restricted to DOS and CP/M like file names,
			eg 8 characters, then dot, then 3 characters as
			file extensions ... You can use dot in file names
			as many times as you want, the only limiation that
			FIRST character of a directory component can't be
			DOT!! Also, the file name size is not limited to 8+3
			characters neither within a single path component.

			
FADDR	+5	3	This is an EP address, describing the address data
			is written to, if file READ command is used, also
			data is read from this address if WRITE command is
			used. FADDR
			itself is NOT modified automatically, unless
			bit15 in SELTYP is 1.

			
OFFS	+11	3	This is a TWORD (not EP address!), three bytes
			long integer specifing the file offset, read and
			write file ops should work from. This address is
			automatically incremented after each READ/WRITE.
			File offset does nothing with the Enterprise,
			it's the offset within the file processed by
			the emulator code and/or the remote server. If you
			want to read a file from the beginning, it's logical
			to set it to zero. Current NetLinkFS operations will
			fail if the offset is set outside of the file size
			parameters. For read, the max offset can be
			file_size-1 or your get EOF error. For write, you
			can even set to file_size, which means next written
			write will be appended to the existing file.
			If you think, that 64Kbyte should be enough for
			everyone, you can always have the highest byte
			to zero. However please note, that on read/write
			OFFS is incremented, and if it exceeds 64K, you
			should better to check the highest byte too, if it's
			important ...

FOPLEN	+14	2	This is a WORD, which must be specified by the
			user: the data size, you want to read/write.
			Note: it's not sure that really this amount of
			data can be processed (eg: end of file in case
			of read). In case of diffence between the requested
			and processed data size, FOPLEN is modified by
			the emultator to signal the real amount of processed
			data! In this case, a special error code is set
			(see later at ERROR codes), which should be handled
			differently than other ("fatal") errors (as it can
			mean you could read some amount of data, just not as
			much as you specified!). So that is IMPORTANT:
			as FOPLEN may be modified by the operation you
			should better check it, re-set it before each new
			op, rather than assuming it's always the same what
			you set up, before the first op.


---- THE FOLLOWING BYTES OF SELECTOR are only used in case of FILE/NetlinKFS operations ---
---- THE FOLLOWING BYTES OF SELECTOR are only used in case of DMA operations ---

Bits in SELTYP:

	Bit 15: DMA operation increments counters (bit CLEAR), or decrements (bit SET)
	Bit 14: source counter is clocked (bit CLEAR), or not clocked (bit SET)
	Bit 13: target counter is clocked (bit CLEAR), or not clocked (bit SET)
	Bit 12: DMA operation is copy (bit CLEAR), or exchange (bit SET)
	
	

---- THE FOLLOWING BYTES OF SELECTOR are only used in case of FPU operations ---

FPU selector is quite simple. FPU works as a stack machine, using depth of
16. But you can see - normally - only the top of the stack. You can push/pop elements,
and doing math operations (on number(s) at the top of the stack). basically it
almost work like the FORTH programming language. Some FPUs really work this way
even in hardware, btw.

INTVAL		It's a 4 byte (DWORD) long integer, with or without sign
		bit. This can be used to push integers onto the stack or
		pop numbers (with truncating to integer!). It's the
		command dependent mode, how much bytes are used, there
		are commands to pop/push byte, word, tword and dword
		length data, signed or unsigned. The byte order is
		always the low byte first. There are even command
		to push/pop EP BASIC formatted numbers, so in theory
		you can accelerate BASIC to use this interface, however
		be careful, as values are converted to internal formats,
		possible loosing the famous advantage of IS-BASIC that
		it's not 2-base system but 10 ... See the next value!

ISBASICEXT	For IS-BASIC number reresentation mode, 4 bytes are not
		enough, you must use this too.

FLOATVAL32	This is used to push/pop float values. These will
		be 32 bit IEEE compliant 2-base stored values.

FLOATVAL64	This is used to push/pop float values, like FLOATVAL32
		but 64 bit IEEE ones, technically the internal
		representation of the FPU emulation.

STACKOFFS	Normally you MUST have to set this value to 0xFF.
		It will cause that normal pop/push/etc operations are
		used. If other values are used, then the selected
		stack depth is used to pop/push without "moving" the
		other elements!






As we discussed, there is no state-full directory information (eg: current
directory), as user must send the full path _always_. Of course you're free
to implement softwares which "mimic" the feeling of walking within a directory
tree. As this is not an EXDOS compatible system, one thing is problematic
though: 






Request commands:

	0 = NO-OP, nothing will happen, STATUS register is set to zero.
	FF = the same as 0 NO-OP

	1 = Set memory area

		This command causes to set memory area written to ports
		B, C and D. Before this command the old area is used even
		if you modify ports B, C or D (and if you haven't set up
		old area before, every commands will fail because of
		invalid memory area).
		STATUS register bit 7 will be clear (no need to wait for
		this command), error code is 0, if it's OK, otherwise
		it will be 1 (meaning: invalid memory region is selected,
		and commands using memory area will fault with the same
		error code

	2 = Read system info

	3 = DMA memory-to-memory copy
		This function is not file related, but can be useful:
		it implements quite fast memory-to-memory copy function.
		Selector of FADDR (which is normally file buffer address
		in selector) is used as source, and the otherwise unused
		MADDR is used as destination. FOPLEN is used to encode of
		the size of the DMA transfer (beware: 0 means 1 byte,
		1 means 2 bytes, etc). Currently the emulated speed is to
		transfer four bytes per clock cycle, which means
		16 Mbytes / sec transfer speed.




