Rev 559 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download
Определения, описанные в этом документе, объявлены в файле '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