Login

Subversion Repositories NedoOS

Rev

Rev 569 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

Определения, описанные в этом документе, объявлены в файле '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