Rev 569 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
518 | alone | 1 | Определения, описанные в этом документе, объявлены в файле 'sys_h.asm', |
2 | который в свою очередь линкует файл 'sysdefs.asm'. |
||
3 | |||
4 | Данный документ подразумевает использование асм-компилятора sjasmplus из репозитория NedoOS. |
||
5 | sjasmplus поставляется в виде исполнияемого файла sjasmplus.exe для OS Windows. |
||
6 | А также в виде исходного кода для самостоятельной сбоки под вами используюмую OS. |
||
7 | |||
8 | ************************* Используемые выражения ************************* |
||
9 | байт - минимальня единица хранения данных в ОЗУ ZX-Spectrum, равная 8 битам. |
||
10 | |||
11 | 0x - приставка к константе, обозначающая число представленном в шестнадцатиричной систаме измерения. |
||
12 | |||
514 | dimkam | 13 | хост(host) - точка подключения |
14 | |||
15 | errno - номер ошибки |
||
16 | |||
17 | big-endian - представление числа в ОЗУ. Сначала старший байт, затем младший. |
||
18 | К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x12,0x34 |
||
19 | little-endian - представление числа в ОЗУ. Это представление использует процессор z80. |
||
20 | Сначала младший байт, затем старший. В этом документе, по умолчанию, все числа little-endian. |
||
21 | К примеру 16 битное число 0x1234 располагается в памяти как DEFB 0x34,0x12 |
||
22 | |||
23 | SOCKET - дескриптор сокета. Знаковое 8-битное число. |
||
24 | |||
25 | sockaddr_in - структура, размером 15 байт, со следующими полями: |
||
26 | sin_family - семейство адресов, беззнаковое 8-битное число. |
||
27 | в текущей реализации допускается только значение 2 (AF_INET). |
||
28 | sin_port - номер порта, 16-битное беззнаковое big-endian число. |
||
29 | sin_addr - IP-адрес. Массив из четырёх 8-битных беззнаковых чисел. |
||
30 | к примеру IP-адрес 1.2.3.4 располагается в памяти как defb 1,2,3,4 |
||
31 | sin_zero - зарезервировано. массив из 8 байт. |
||
32 | |||
33 | ************************* Возможные номера ошибок (errno)************************* |
||
34 | SHUT_RDWR EQU 2 |
||
35 | ERR_EAGAIN EQU 35 ;/* Try again */ |
||
36 | ERR_EWOULDBLOCK EQU ERR_EAGAIN ;/* Operation would block */ |
||
37 | ERR_INTR EQU 4 |
||
38 | ERR_NFILE EQU 23 |
||
39 | ERR_ALREADY EQU 37 |
||
40 | ERR_NOTSOCK EQU 38 |
||
41 | ERR_EMSGSIZE EQU 40 ;/* Message too long */ |
||
42 | ERR_PROTOTYPE EQU 41 |
||
43 | ERR_AFNOSUPPORT EQU 47 |
||
44 | ERR_HOSTUNREACH EQU 65 |
||
45 | ERR_ECONNABORTED EQU 53 /* Software caused connection abort */ |
||
46 | ERR_CONNRESET EQU 54 |
||
47 | ERR_NOTCONN EQU 57 |
||
48 | |||
49 | ************************* Протоколы соединений ************************* |
||
50 | SOCK_STREAM EQU 0x01 ;tcp/ip |
||
51 | SOCK_ICMP EQU 0x02 ;icmp |
||
52 | SOCK_DGRAM EQU 0x03 ;udp/ip |
||
53 | |||
54 | AF_INET EQU 2 |
||
55 | |||
56 | *********************************************************** |
||
518 | alone | 57 | *********************** Определения *********************** |
514 | dimkam | 58 | *********************************************************** |
518 | alone | 59 | При вызове функций ядра считается, что возможна порча всех |
60 | регистров(за исключением SP). |
||
61 | |||
514 | dimkam | 62 | Все вызовы не блокирующие(за исключением OS_NETCONNECT), т.е. |
63 | не ожидадают отправку\прием данных, либо подключения. |
||
64 | При необходимости использования блокирующих функций - реализовывать самостоятельно внутри процесса. |
||
65 | |||
66 | *********************** OS_NETSOCKET ********************** |
||
67 | Создаёт сокет. |
||
518 | alone | 68 | Макрос вызова функции ядра. |
514 | dimkam | 69 | Все аргументы в регистрах: |
70 | D - семейство адресов, беззнаковое 8-битное число, допускается только значение 2 (AF_INET). |
||
71 | E - протокол соединения(0x01 tcp/ip, 0x02 icmp, 0x03 udp/ip) |
||
72 | Возвращаемые значения в регистрах: |
||
73 | L - SOCKET при положительном значении, при отрицательном значении - функция завершилась с ошибкой. |
||
74 | А - errno при ошибке. |
||
75 | |||
76 | Возможные ошибки: |
||
77 | ERR_AFNOSUPPORT - семейство адресов не поддерживается |
||
78 | ERR_NFILE - нет свободных сокетов |
||
79 | ERR_PROTOTYPE - протокол не поддерживается |
||
80 | |||
81 | Пример создания TCP/IP сокета: |
||
559 | alone | 82 | LD D,AF_INET;2 |
514 | dimkam | 83 | LD E,SOCK_STREAM |
84 | OS_NETSOCKET |
||
85 | BIT 7,L |
||
86 | JP NZ,ERR_EXIT ;обработка ошибки |
||
87 | LD A,L |
||
88 | LD (SOC),A ;сохраняем дескриптор сокета. |
||
89 | |||
90 | Примечания: |
||
91 | При закрытии процесса, закрываются все сокеты созданные этим процессом. |
||
92 | Сокеты защищены от использования другим процессом. |
||
93 | Номер исходящего порта присваивается автоматически из диапазона 49152...65535 |
||
94 | |||
95 | *********************** OS_NETSHUTDOWN ********************** |
||
96 | Закрытие сокета. |
||
518 | alone | 97 | Макрос вызова функции ядра. |
514 | dimkam | 98 | Все аргументы в регистрах: |
99 | A - SOCKET |
||
100 | E - Варианты закрытия, 0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст. |
||
101 | Возвращаемые значения в регистрах: |
||
102 | L - При отрицательном значении - функция завершилась с ошибкой. |
||
103 | А - errno при ошибке. |
||
104 | |||
105 | Пример закрытия сокета с ожиданием опустошения буфера отправки: |
||
106 | close_wait: |
||
107 | LD A,(SOC) |
||
108 | LD E,1 |
||
109 | OS_NETSHUTDOWN |
||
110 | BIT 7,L |
||
111 | RET Z ;сокет закрылся |
||
112 | CP ERR_EAGAIN |
||
113 | JP NZ,ERR_EXIT ;обработка ошибки не связанной с ожиданием отправки. |
||
114 | OS_YIELD ;не обязательно. Если время не критично, |
||
115 | ;то отдадим квант времени системе. |
||
116 | JR close_wait ;ожидаем отправки данных |
||
117 | |||
118 | Возможные ошибки: |
||
119 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
120 | ERR_EAGAIN - буфер отправки не пуст |
||
121 | |||
122 | Примечание: Керналь закрывает сокеты процесса при закрытии процесса. |
||
123 | Но, ввиду ограниченного количества сокетов, рекомендуется закрывать сокет |
||
124 | как только он становится не нужен. |
||
125 | |||
126 | *********************** OS_NETCONNECT ********************** |
||
127 | Подключить TCP/IP сокет к хосту. |
||
518 | alone | 128 | Макрос вызова функции ядра. |
514 | dimkam | 129 | Все аргументы в регистрах: |
130 | A - SOCKET |
||
131 | DE - указатель на структуру sockaddr_in содержащую IP адрес и порт хоста. |
||
132 | Возвращаемые значения в регистрах: |
||
133 | L - При отрицательном значении - функция завершилась с ошибкой. |
||
134 | А - errno при ошибке. |
||
135 | Возможные ошибки: |
||
136 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
137 | ERR_ALREADY - сокет уже подключен |
||
138 | ERR_HOSTUNREACH - хост не доступн, либо отверг подключение. |
||
139 | |||
140 | Пример подключения к хосту с IP адресом 1.2.3.4 на порт 80: |
||
141 | LD A,(SOC) |
||
559 | alone | 142 | LD DE,destination_host |
514 | dimkam | 143 | OS_NETCONNECT |
144 | BIT 7,L |
||
145 | JP NZ,ERR_EXIT ;обработка ошибки |
||
146 | ... ;подключились |
||
147 | |||
148 | destination_host |
||
149 | DEFB AF_INET |
||
150 | DEFB 0,80 ;порт назначения |
||
151 | DEFB 1,2,3,4 ;IP адрес назначения |
||
152 | DEFB 0,0,0,0,0,0,0,0 ;резерв |
||
153 | |||
154 | Примечание: Данная функция применима только к TCP/IP сокетам. |
||
155 | |||
156 | *********************** OS_BIND ********************** |
||
157 | Присвоение сокету конкретного номера исходящего порта. |
||
518 | alone | 158 | Макрос вызова функции ядра. |
514 | dimkam | 159 | Все аргументы в регистрах: |
160 | A - SOCKET |
||
161 | DE - указатель на структуру sockaddr_in содержащую номер исходящего порта. |
||
162 | (остальные поля структуры не используются, но обязаны присутствовать) |
||
163 | Возвращаемые значения в регистрах: |
||
164 | L - При отрицательном значении - функция завершилась с ошибкой. |
||
165 | А - errno при ошибке. |
||
166 | Возможные ошибки: |
||
167 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
168 | |||
169 | Пример присвоения сокету исходяего порта 433: |
||
170 | LD A,(SOC) |
||
569 | dimkam | 171 | LD DE,source_host |
514 | dimkam | 172 | OS_BIND |
173 | BIT 7,L |
||
174 | JP NZ,ERR_EXIT ;обработка ошибки |
||
175 | ... ;удачно, продолжаем работу |
||
176 | |||
569 | dimkam | 177 | source_host |
514 | dimkam | 178 | DEFB AF_INET |
179 | DEFB high(433),low(433) ;исходящий порт |
||
180 | DEFB 0,0,0,0 ;исходящий IP адрес (не используется в текущей реализации) |
||
181 | DEFB 0,0,0,0,0,0,0,0 ;резерв |
||
182 | Примечание: В режиме TCP/IP функция вызывается(если нужна) до вызовов OS_NETCONNECT или OS_LISTEN. |
||
183 | |||
184 | *********************** OS_LISTEN ********************** |
||
185 | Включить режим прослушивания исходящего порта(режим сервера) TCP/IP сокета. |
||
518 | alone | 186 | Макрос вызова функции ядра. |
514 | dimkam | 187 | Все аргументы в регистрах: |
188 | A - SOCKET |
||
189 | Возвращаемые значения в регистрах: |
||
190 | L - При отрицательном значении - функция завершилась с ошибкой. |
||
191 | А - errno при ошибке. |
||
192 | Возможные ошибки: |
||
193 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
194 | ERR_ALREADY - сокет уже подключен |
||
195 | |||
196 | Пример включения режима прослушивания: |
||
197 | LD A,(SOC) |
||
198 | OS_LISTEN |
||
199 | BIT 7,L |
||
200 | JP NZ,ERR_EXIT ;обработка ошибки |
||
201 | ... ;удачно, продолжаем работу |
||
202 | |||
203 | Примечание: Данная функция применима только к TCP/IP сокетам. |
||
204 | Как правило функция вызывается(если нужна) после вызова OS_BIND. |
||
205 | |||
206 | *********************** OS_ACCEPT ********************** |
||
207 | Принять входящее TCP/IP подключение. |
||
518 | alone | 208 | Макрос вызова функции ядра. |
514 | dimkam | 209 | Все аргументы в регистрах: |
210 | A - SOCKET |
||
211 | Возвращаемые значения в регистрах: |
||
212 | L - SOCKET при положительном значении, при отрицательном значении - функция завершилась с ошибкой. |
||
213 | А - errno при ошибке. |
||
214 | Возможные ошибки: |
||
215 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
216 | ERR_ECONNABORTED - общая ошибка сокета |
||
217 | ERR_EAGAIN - входящих подключений пока нет |
||
218 | |||
219 | Пример принятия соединения с ожиданием подключения: |
||
220 | WAIT_CLIENTS |
||
221 | LD A,(SOC) |
||
222 | OS_ACCEPT |
||
223 | BIT 7,L |
||
224 | JR Z,ESTABLISHED |
||
225 | CP ERR_EAGAIN |
||
226 | JP NZ,ERR_EXIT ;обработка ошибки |
||
227 | OS_YIELD ;не обязательно. Если время реагирования на подключение не критично, |
||
228 | ;то отдадим квант времени системе. |
||
229 | JR WAIT_CLIENTS ;никто не подключился, ждём |
||
230 | ESTABLISHED |
||
231 | LD A,L ;㤠筮 |
||
232 | LD (SOC_CLIENT),A ;сохраняем дескриптор сокета. |
||
233 | ... ;продолжаем работу |
||
234 | |||
235 | Примечания: Данная функция применима только к TCP/IP сокетам. |
||
236 | Функция вызывается после вызова OS_LISTEN. |
||
237 | Возвращает новый дескриптор сокета с принятым соединением. Сокет прослушки продолжает слушать. |
||
238 | Если дальнейшая прослушка не требуется, то рекомендуется сразу закрывать слушающий сокет. |
||
239 | При недостатке сокетов, возвращается дескриптор подключенного сокета прослушки, |
||
240 | в этом случае нет дальнейшего прослушивания. |
||
241 | Т.е. при закрытии слушающего сокета, необходимо проверить(путем сравнения дескрипторов) |
||
242 | не является ли он сокетом с принятым соединением. |
||
243 | |||
244 | *********************** OS_WIZNETREAD ********************** |
||
245 | Прочитать входящие данные. |
||
518 | alone | 246 | Макрос вызова функции ядра. |
514 | dimkam | 247 | |
248 | При протоколе TCP/IP все аргументы в регистрах: |
||
249 | A - SOCKET |
||
250 | DE - указатель на буфер для принятия данных |
||
251 | HL - размер буфера(в байтах) |
||
252 | При протоколе отличном от TCP/IP все аргументы в регистрах: |
||
253 | A - SOCKET |
||
569 | dimkam | 254 | DE - указатель на структуру sockaddr_in, в неё помещается(ядром) IP-адрес и порт хоста отправившего данные. |
514 | dimkam | 255 | IX - указатель на буфер для принятия данных |
256 | HL - размер буфера(в байтах) |
||
257 | Возвращаемые значения в регистрах: |
||
258 | HL - при отрицательном значении функция завершилась с ошибкой, |
||
569 | dimkam | 259 | про значении больше нуля возвращается действительный размер(в байтах) принятых данных, |
260 | нулевого значения вызов не возвращает. |
||
514 | dimkam | 261 | А - errno при ошибке. |
262 | Возможные ошибки: |
||
263 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
264 | ERR_EAGAIN - входящих данных пока нет |
||
265 | ERR_NOTCONN - сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP) |
||
266 | |||
267 | Пример принятия данных по протоколу TCP/IP с ожиданием данных: |
||
268 | WAIT_DATA |
||
269 | LD A,(SOC) |
||
270 | LD DE,BUF |
||
271 | LD HL,BUF_SIZE |
||
272 | OS_WIZNETREAD |
||
273 | BIT 7,H |
||
274 | JR Z,RECEIVED ;ошибок нет |
||
275 | CP ERR_EAGAIN |
||
276 | JP NZ,ERR_EXIT ;обработка ошибки |
||
277 | OS_YIELD ;не обязательно. Если время реагирования на пришедшие данные не критично, |
||
278 | ;то отдадим квант времени системе. |
||
279 | JR WAIT_DATA ;данных нет, ждём |
||
280 | RECEIVED |
||
281 | LD (DATA_SIZE),HL ;удачно. если требуется, то сохраняем количество принятых данных. |
||
282 | ... ;продолжаем работу |
||
283 | |||
284 | BUF DEFS 1000 |
||
285 | BUF_SIZE EQU $-BUF |
||
286 | |||
287 | Примечания: При протоколе отличном от TCP/IP, необходимо единовременно прочитать весь пакет, |
||
288 | иначе недовычитанные данные пакета игнорируются. |
||
289 | |||
290 | *********************** OS_WIZNETWRITE ********************** |
||
291 | Отправить пакет данных. |
||
518 | alone | 292 | Макрос вызова функции ядра. |
514 | dimkam | 293 | |
294 | При протоколе TCP/IP все аргументы в регистрах: |
||
295 | A - SOCKET |
||
296 | DE - указатель на буфер с данными |
||
297 | HL - размер данных(в байтах), в текущей реализации максимум 8192 байта |
||
298 | При протоколе отличном от TCP/IP все аргументы в регистрах: |
||
299 | A - SOCKET |
||
300 | DE - указатель на структуру sockaddr_in, в неё необходимо поместить IP-адрес и порт хоста получателя |
||
301 | IX - указатель на буфер с данными |
||
302 | HL - размер данных(в байтах), в текущей реализации максимум 8192 байта |
||
303 | Возвращаемые значения в регистрах: |
||
304 | HL - при отрицательном значении функция завершилась с ошибкой, |
||
305 | иначе возвращается действительный размер(в байтах) отправленных данных, |
||
306 | А - errno при ошибке. |
||
307 | Возможные ошибки: |
||
308 | ERR_NOTSOCK - не действительный дескриптор сокета |
||
309 | ERR_NOTCONN - сокет с неустановленным\пропавшем соединением(при протоколе TCP/IP) |
||
310 | ERR_EMSGSIZE - в буфере отправки нет места, либо пакет слишком большой |
||
311 | |||
312 | Пример отправки данных по протоколу TCP/IP с ожиданием данных: |
||
559 | alone | 313 | WAIT_SEND |
514 | dimkam | 314 | LD A,(SOC) |
315 | LD DE,BUF |
||
316 | LD HL,BUF_SIZE |
||
317 | OS_WIZNETWRITE |
||
318 | BIT 7,H |
||
559 | alone | 319 | JR Z,SEND_OK ;ошибок нет |
514 | dimkam | 320 | CP ERR_EMSGSIZE |
321 | JP NZ,ERR_EXIT ;обработка ошибки |
||
322 | OS_YIELD ;не обязательно. Если время не критично, |
||
323 | ;то отдадим квант времени системе. |
||
559 | alone | 324 | JR WAIT_SEND ;буфер отправки переполнен, ждём освобождения |
325 | SEND_OK |
||
514 | dimkam | 326 | LD (DATA_SIZE),HL ;удачно. если требуется, то сохраняем количество отправленных данных. |
327 | ... ;продолжаем работу |
||
328 | |||
329 | BUF DEFB "Hello World!" |
||
330 | BUF_SIZE EQU $-BUF |
||
331 |