Определения, описанные в этом документе, объявлены в файле 'sys_h.asm',
который в свою очередь линкует файл 'sysdefs.asm'.

Данный документ подразумевает использование асм-компилятора sjasmplus из репозитория NedoOS.
sjasmplus поставляется в виде исполнияемого файла sjasmplus.exe для OS Windows. 
А также в виде исходного кода для самостоятельной сбоки под вами используюмую OS.

************************* Используемые выражения *************************
байт - минимальня единица хранения данных в ОЗУ ZX-Spectrum, равная 8 битам.

0x - приставка к константе, обозначающая число представленном в шестнадцатиричной систаме измерения.

хост(host) - точка подключения

errno - номер ошибки

big-endian - представление числа в ОЗУ. Сначала старший байт, затем младший.
	К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x12,0x34
little-endian - представление числа в ОЗУ. Это представление использует процессор z80.
	Сначала младший байт, затем старший. В этом документе, по умолчанию, все числа little-endian.
	К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x34,0x12

SOCKET - дескриптор сокета. Знаковое 8-битное число.

sockaddr_in - структура, размером 15 байт, со следующими полями:
	sin_family - семейство адресов, беззнаковое 8-битное число.
		в текущей реализации допускается только значение 2 (AF_INET).
	sin_port - номер порта, 16-битное беззнаковое big-endian число.
	sin_addr - IP-адрес. Массив из четырёх 8-битных беззнаковых чисел.
		к примеру IP-адрес 1.2.3.4 располагается в памяти как defb 1,2,3,4
	sin_zero - зарезервировано. массив из 8 байт.

************************* Возможные номера ошибок (errno)*************************
SHUT_RDWR 		EQU 2
ERR_EAGAIN		EQU 35		;/* Try again */
ERR_EWOULDBLOCK	EQU ERR_EAGAIN	;/* Operation would block */
ERR_INTR 		EQU 4
ERR_NFILE 		EQU 23
ERR_ALREADY 	EQU 37
ERR_NOTSOCK 	EQU 38
ERR_EMSGSIZE 	EQU 40    ;/* Message too long */
ERR_PROTOTYPE 	EQU 41
ERR_AFNOSUPPORT EQU 47
ERR_HOSTUNREACH EQU 65
ERR_ECONNABORTED EQU	53	/* Software caused connection abort */
ERR_CONNRESET 	EQU 54
ERR_NOTCONN 	EQU 57

************************* Протоколы соединений *************************
SOCK_STREAM EQU 0x01		;tcp/ip
SOCK_ICMP 	EQU 0x02		;icmp
SOCK_DGRAM 	EQU 0x03		;udp/ip

AF_INET EQU 2

***********************************************************
*********************** Определения ***********************
***********************************************************
При вызове функций ядра считается, что возможна порча всех 
регистров(за исключением SP).

Все вызовы не блокирующие(за исключением OS_NETCONNECT), т.е. 
не ожидадают отправку\прием данных, либо подключения.
При необходимости использования блокирующих функций - реализовывать самостоятельно внутри процесса.

*********************** OS_NETSOCKET **********************
	Создаёт сокет.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		D - семейство адресов, беззнаковое 8-битное число, допускается только значение 2 (AF_INET).
		E - протокол соединения(0x01 tcp/ip, 0x02 icmp, 0x03 udp/ip)
	Возвращаемые значения в регистрах:
		L - SOCKET при положительном значении, при отрицательном значении  - функция завершилась с ошибкой.
		А - errno при ошибке.
		
	Возможные ошибки:
		ERR_AFNOSUPPORT - семейство адресов не поддерживается
		ERR_NFILE		- нет свободных сокетов
		ERR_PROTOTYPE	- протокол не поддерживается
		
	Пример создания TCP/IP сокета:
		LD D,AF_INET;2
		LD E,SOCK_STREAM
		OS_NETSOCKET
		BIT 7,L
		JP NZ,ERR_EXIT	;обработка ошибки
		LD A,L
		LD (SOC),A		;сохраняем дескриптор сокета.
		
	Примечания:
		При закрытии процесса, закрываются все сокеты созданные этим процессом.
		Сокеты защищены от использования другим процессом.
		Номер исходящего порта присваивается автоматически из диапазона 49152...65535
		
*********************** OS_NETSHUTDOWN **********************
	Закрытие сокета.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		A - SOCKET
		E - Варианты закрытия, 0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст.
	Возвращаемые значения в регистрах:
		L - При отрицательном значении  - функция завершилась с ошибкой.
		А - errno при ошибке.
	
	Пример закрытия сокета с ожиданием опустошения буфера отправки:
close_wait:
		LD A,(SOC)
		LD E,1
		OS_NETSHUTDOWN
		BIT 7,L
		RET Z			;сокет закрылся
		CP ERR_EAGAIN
		JP NZ,ERR_EXIT		;обработка ошибки не связанной с ожиданием отправки.
		OS_YIELD		;не обязательно. Если время не критично,
						;то отдадим квант времени системе.
		JR close_wait ;ожидаем отправки данных
		
	Возможные ошибки:
		ERR_NOTSOCK - не действительный дескриптор сокета
		ERR_EAGAIN	- буфер отправки не пуст
		
	Примечание: Керналь закрывает сокеты процесса при закрытии процесса. 
		Но, ввиду ограниченного количества сокетов, рекомендуется закрывать сокет 
		как только он становится не нужен.
	
*********************** OS_NETCONNECT **********************
	Подключить TCP/IP сокет к хосту.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		A - SOCKET
		DE - указатель на структуру sockaddr_in содержащую IP адрес и порт хоста.
	Возвращаемые значения в регистрах:
		L - При отрицательном значении  - функция завершилась с ошибкой.
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK 	- не действительный дескриптор сокета
		ERR_ALREADY 	- сокет уже подключен
		ERR_HOSTUNREACH	- хост не доступн, либо отверг подключение.
		
	Пример подключения к хосту с IP адресом 1.2.3.4 на порт 80:
		LD A,(SOC)
		LD DE,destination_host
		OS_NETCONNECT
		BIT 7,L
		JP NZ,ERR_EXIT	;обработка ошибки
		... ;подключились
		
destination_host		
		DEFB AF_INET 
		DEFB 0,80				;порт назначения
		DEFB 1,2,3,4			;IP адрес назначения
		DEFB 0,0,0,0,0,0,0,0	;резерв
		
	Примечание: Данная функция применима только к TCP/IP сокетам.

*********************** OS_BIND **********************
	Присвоение сокету конкретного номера исходящего порта.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		A - SOCKET
		DE - указатель на структуру sockaddr_in содержащую номер исходящего порта.
			(остальные поля структуры не используются, но обязаны присутствовать)
	Возвращаемые значения в регистрах:
		L - При отрицательном значении - функция завершилась с ошибкой.
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK 	- не действительный дескриптор сокета
		
	Пример присвоения сокету исходяего порта 433:
		LD A,(SOC)
		LD DE,source_host
		OS_BIND
		BIT 7,L
		JP NZ,ERR_EXIT	;обработка ошибки
		... ;удачно, продолжаем работу
		
source_host		
		DEFB AF_INET 
		DEFB high(433),low(433)	;исходящий порт
		DEFB 0,0,0,0			;исходящий IP адрес (не используется в текущей реализации)
		DEFB 0,0,0,0,0,0,0,0	;резерв
	Примечание: В режиме TCP/IP функция вызывается(если нужна) до вызовов OS_NETCONNECT	или OS_LISTEN.
	
*********************** OS_LISTEN **********************
	Включить режим прослушивания исходящего порта(режим сервера) TCP/IP сокета.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		A - SOCKET
	Возвращаемые значения в регистрах:
		L - При отрицательном значении - функция завершилась с ошибкой.
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK 	- не действительный дескриптор сокета
		ERR_ALREADY 	- сокет уже подключен
		
	Пример включения режима прослушивания:
		LD A,(SOC)
		OS_LISTEN
		BIT 7,L
		JP NZ,ERR_EXIT	;обработка ошибки
		... ;удачно, продолжаем работу
		
	Примечание: Данная функция применима только к TCP/IP сокетам.
		Как правило функция вызывается(если нужна) после вызова OS_BIND.
		
*********************** OS_ACCEPT **********************
	Принять входящее TCP/IP подключение.
	Макрос вызова функции ядра.
	Все аргументы в регистрах:
		A - SOCKET
	Возвращаемые значения в регистрах:
		L - SOCKET при положительном значении, при отрицательном значении  - функция завершилась с ошибкой.
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK 		- не действительный дескриптор сокета
		ERR_ECONNABORTED	- общая ошибка сокета
		ERR_EAGAIN			- входящих подключений пока нет
		
	Пример принятия соединения с ожиданием подключения:
WAIT_CLIENTS
		LD A,(SOC)
		OS_ACCEPT
		BIT 7,L
		JR Z,ESTABLISHED
		CP ERR_EAGAIN
		JP NZ,ERR_EXIT	;обработка ошибки
		OS_YIELD		;не обязательно. Если время реагирования на подключение не критично,
						;то отдадим квант времени системе.
		JR WAIT_CLIENTS	;никто не подключился, ждём
ESTABLISHED
		LD A,L				;удачно
		LD (SOC_CLIENT),A	;сохраняем дескриптор сокета.
		... ;продолжаем работу
		
	Примечания: Данная функция применима только к TCP/IP сокетам.
		Функция вызывается после вызова OS_LISTEN.
		Возвращает новый дескриптор сокета с принятым соединением. Сокет прослушки продолжает слушать.
		Если дальнейшая прослушка не требуется, то рекомендуется сразу закрывать слушающий сокет.
		При недостатке сокетов, возвращается дескриптор подключенного сокета прослушки, 
		в этом случае нет дальнейшего прослушивания.
		Т.е. при закрытии слушающего сокета, необходимо проверить(путем сравнения дескрипторов)
		не является ли он сокетом с принятым соединением.
		
*********************** OS_WIZNETREAD **********************
	Прочитать входящие данные.
	Макрос вызова функции ядра.
	
	При протоколе TCP/IP все аргументы в регистрах:
		A - SOCKET
		DE - указатель на буфер для принятия данных
		HL - размер буфера(в байтах)
	При протоколе отличном от TCP/IP все аргументы в регистрах:
		A - SOCKET
		DE - указатель на структуру sockaddr_in, в неё помещается(ядром) IP-адрес и порт хоста отправившего данные.
		IX - указатель на буфер для принятия данных
		HL - размер буфера(в байтах)
	Возвращаемые значения в регистрах:
		HL - при отрицательном значении функция завершилась с ошибкой,
			про значении больше нуля возвращается действительный размер(в байтах) принятых данных,
			нулевого значения вызов не возвращает.
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK - не действительный дескриптор сокета
		ERR_EAGAIN	- входящих данных пока нет
		ERR_NOTCONN	- сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP)
		
	Пример принятия данных по протоколу TCP/IP с ожиданием данных:
WAIT_DATA
		LD A,(SOC)
		LD DE,BUF
		LD HL,BUF_SIZE
		OS_WIZNETREAD
		BIT 7,H
		JR Z,RECEIVED	;ошибок нет
		CP ERR_EAGAIN
		JP NZ,ERR_EXIT	;обработка ошибки
		OS_YIELD		;не обязательно. Если время реагирования на пришедшие данные не критично,
						;то отдадим квант времени системе.
		JR WAIT_DATA	;данных нет, ждём
RECEIVED
		LD (DATA_SIZE),HL	;удачно. если требуется, то сохраняем количество принятых данных.
		... ;продолжаем работу

BUF		DEFS 1000
BUF_SIZE EQU $-BUF
	
	Примечания: При протоколе отличном от TCP/IP, необходимо единовременно прочитать весь пакет, 
		иначе недовычитанные данные пакета игнорируются.

*********************** OS_WIZNETWRITE **********************
	Отправить пакет данных.
	Макрос вызова функции ядра.
	
	При протоколе TCP/IP все аргументы в регистрах:
		A - SOCKET
		DE - указатель на буфер с данными
		HL - размер данных(в байтах), в текущей реализации максимум 8192 байта
	При протоколе отличном от TCP/IP все аргументы в регистрах:
		A - SOCKET
		DE - указатель на структуру sockaddr_in, в неё необходимо поместить IP-адрес и порт хоста получателя
		IX - указатель на буфер с данными
		HL - размер данных(в байтах), в текущей реализации максимум 8192 байта
	Возвращаемые значения в регистрах:
		HL - при отрицательном значении функция завершилась с ошибкой,
			иначе возвращается действительный размер(в байтах) отправленных данных,
		А - errno при ошибке.
	Возможные ошибки:
		ERR_NOTSOCK - не действительный дескриптор сокета
		ERR_NOTCONN	- сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP)
		ERR_EMSGSIZE - в буфере отправки нет места, либо пакет слишком большой
		
	Пример отправки данных по протоколу TCP/IP с ожиданием данных:
WAIT_SEND
		LD A,(SOC)
		LD DE,BUF
		LD HL,BUF_SIZE
		OS_WIZNETWRITE
		BIT 7,H
		JR Z,SEND_OK	;ошибок нет
		CP ERR_EMSGSIZE
		JP NZ,ERR_EXIT	;обработка ошибки
		OS_YIELD		;не обязательно. Если время не критично,
						;то отдадим квант времени системе.
		JR WAIT_SEND	;буфер отправки переполнен, ждём освобождения
SEND_OK
		LD (DATA_SIZE),HL	;удачно. если требуется, то сохраняем количество отправленных данных.
		... ;продолжаем работу
	
BUF		DEFB "Hello World!"
BUF_SIZE EQU $-BUF
				