Rev 3704 | Rev 3790 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3704 | Rev 3789 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2013. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; ftpc.asm - FTP client for KolibriOS ;; |
6 | ;; ftpc.asm - FTP client for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
11 | ;; Version 2, June 1991 ;; |
11 | ;; Version 2, June 1991 ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
14 | 14 | ||
15 | format binary as "" |
15 | format binary as "" |
16 | - | ||
17 | __DEBUG__ = 0 |
- | |
18 | __DEBUG_LEVEL__ = 1 |
16 | |
19 | BUFFERSIZE = 1024 |
17 | BUFFERSIZE = 1024 |
20 | 18 | ||
21 | STATUS_CONNECTING = 0 |
19 | STATUS_CONNECTING = 0 |
22 | STATUS_CONNECTED = 1 |
20 | STATUS_CONNECTED = 1 |
23 | STATUS_NEEDPASSWORD = 2 |
21 | STATUS_NEEDPASSWORD = 2 |
24 | STATUS_LOGGED_IN = 3 |
22 | STATUS_LOGGED_IN = 3 |
25 | 23 | ||
26 | use32 |
24 | use32 |
27 | ; standard header |
25 | ; standard header |
28 | db 'MENUET01' ; signature |
26 | db 'MENUET01' ; signature |
29 | dd 1 ; header version |
27 | dd 1 ; header version |
30 | dd start ; entry point |
28 | dd start ; entry point |
31 | dd i_end ; initialized size |
29 | dd i_end ; initialized size |
32 | dd mem+0x1000 ; required memory |
30 | dd mem+0x1000 ; required memory |
33 | dd mem+0x1000 ; stack pointer |
31 | dd mem+0x1000 ; stack pointer |
34 | dd s ; parameters |
32 | dd s ; parameters |
35 | dd 0 ; path |
33 | dd 0 ; path |
36 | 34 | ||
37 | include '../../macros.inc' |
35 | include '../../macros.inc' |
38 | purge mov,add,sub |
36 | purge mov,add,sub |
39 | include '../../proc32.inc' |
37 | include '../../proc32.inc' |
40 | include '../../dll.inc' |
38 | include '../../dll.inc' |
41 | include '../../debug-fdo.inc' |
- | |
42 | include '../../network.inc' |
39 | include '../../network.inc' |
43 | 40 | ||
44 | include 'usercommands.inc' |
41 | include 'usercommands.inc' |
45 | include 'servercommands.inc' |
42 | include 'servercommands.inc' |
46 | 43 | ||
47 | ; entry point |
44 | ; entry point |
48 | start: |
45 | start: |
49 | 46 | ||
50 | DEBUGF 1, "hello" |
47 | mcall 40, 0 |
51 | ; load libraries |
48 | ; load libraries |
52 | stdcall dll.Load, @IMPORT |
49 | stdcall dll.Load, @IMPORT |
53 | test eax, eax |
50 | test eax, eax |
54 | jnz exit |
51 | jnz exit |
55 | ; initialize console |
52 | ; initialize console |
56 | push 1 |
- | |
57 | call [con_start] |
53 | invoke con_start, 1 |
58 | push title |
- | |
59 | push 25 |
- | |
60 | push 80 |
- | |
61 | push 25 |
- | |
62 | push 80 |
- | |
63 | call [con_init] |
54 | invoke con_init, 80, 25, 80, 25, title |
64 | 55 | ||
65 | ; Check for parameters |
56 | ; Check for parameters |
66 | cmp byte [s], 0 |
57 | cmp byte [s], 0 |
67 | jne resolve |
58 | jne resolve |
68 | 59 | ||
69 | main: |
60 | main: |
70 | call [con_cls] |
61 | invoke con_cls |
71 | ; Welcome user |
62 | ; Welcome user |
72 | push str1 |
- | |
73 | call [con_write_asciiz] |
63 | invoke con_write_asciiz, str1 |
74 | 64 | ||
75 | ; write prompt |
65 | ; write prompt |
76 | push str2 |
66 | invoke con_set_flags, 0x0a |
77 | call [con_write_asciiz] |
67 | invoke con_write_asciiz, str2 |
78 | ; read string |
68 | ; read string |
79 | mov esi, s |
69 | mov esi, s |
80 | push 256 |
70 | invoke con_gets, esi, 256 |
81 | push esi |
71 | invoke con_write_asciiz, str4 ; newline |
82 | call [con_gets] |
72 | invoke con_set_flags, 0x07 |
83 | ; check for exit |
73 | ; check for exit |
84 | test eax, eax |
74 | test eax, eax |
85 | jz done |
75 | jz done |
86 | cmp byte [esi], 10 |
76 | cmp byte [esi], 10 |
87 | jz done |
77 | jz done |
88 | 78 | ||
89 | resolve: |
79 | resolve: |
90 | - | ||
91 | ; delete terminating '\n' |
80 | ; delete terminating '\n' |
92 | mov esi, s |
81 | mov esi, s |
93 | @@: |
82 | @@: |
94 | lodsb |
83 | lodsb |
95 | cmp al, 0x20 |
84 | cmp al, 0x20 |
96 | ja @r |
85 | ja @r |
97 | mov byte [esi-1], 0 |
86 | mov byte [esi-1], 0 |
98 | - | ||
99 | ; call [con_cls] |
- | |
100 | push str3 |
87 | |
101 | call [con_write_asciiz] |
- | |
102 | push s |
88 | invoke con_write_asciiz, str3 |
103 | call [con_write_asciiz] |
89 | invoke con_write_asciiz, s |
104 | 90 | ||
105 | ; resolve name |
91 | ; resolve name |
106 | push esp ; reserve stack place |
92 | push esp ; reserve stack place |
107 | push esp ; fourth parameter |
- | |
108 | push 0 ; third parameter |
- | |
109 | push 0 ; second parameter |
- | |
110 | push s ; first parameter |
- | |
111 | call [getaddrinfo] |
93 | invoke getaddrinfo, s, 0, 0, esp |
112 | pop esi |
94 | pop esi |
113 | ; test for error |
95 | ; test for error |
114 | test eax, eax |
96 | test eax, eax |
115 | jnz fail |
97 | jnz fail |
116 | 98 | ||
117 | ; write results |
99 | ; write results |
118 | push str8 |
- | |
119 | call [con_write_asciiz] |
100 | invoke con_write_asciiz, str8 |
120 | ; mov edi, esi |
101 | ; mov edi, esi |
121 | 102 | ||
122 | ; convert IP address to decimal notation |
103 | ; convert IP address to decimal notation |
123 | mov eax, [esi+addrinfo.ai_addr] |
104 | mov eax, [esi+addrinfo.ai_addr] |
124 | mov eax, [eax+sockaddr_in.sin_addr] |
105 | mov eax, [eax+sockaddr_in.sin_addr] |
125 | mov [sockaddr1.ip], eax |
106 | mov [sockaddr1.ip], eax |
126 | push eax |
- | |
- | 107 | ||
127 | call [inet_ntoa] |
108 | invoke inet_ntoa, eax |
128 | ; write result |
109 | ; write result |
129 | push eax |
- | |
130 | call [con_write_asciiz] |
110 | invoke con_write_asciiz, eax |
131 | ; free allocated memory |
111 | ; free allocated memory |
132 | push esi |
- | |
133 | call [freeaddrinfo] |
112 | invoke freeaddrinfo, esi |
134 | - | ||
135 | push str9 |
- | |
136 | call [con_write_asciiz] |
- | |
- | 113 | ||
137 | 114 | invoke con_write_asciiz, str9 |
|
138 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
115 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
139 | cmp eax, -1 |
116 | cmp eax, -1 |
140 | je fail2 |
117 | je socket_error |
141 | mov [socketnum], eax |
- | |
142 | 118 | mov [socketnum], eax |
|
143 | push str11 |
- | |
144 | call [con_write_asciiz] |
119 | |
145 | - | ||
146 | mcall connect, [socketnum], sockaddr1, 18 |
- | |
147 | - | ||
148 | mcall 40, EVM_STACK |
120 | invoke con_write_asciiz, str11 |
149 | - | ||
150 | mov [status], STATUS_CONNECTING |
- | |
151 | mov [offset], buffer_ptr |
121 | mcall connect, [socketnum], sockaddr1, 18 |
152 | 122 | mov [status], STATUS_CONNECTING |
|
153 | push str12 |
- | |
154 | call [con_write_asciiz] |
123 | |
155 | - | ||
156 | wait_for_serverdata: |
- | |
157 | mcall 10 |
124 | invoke con_write_asciiz, str12 |
158 | 125 | ||
159 | call [con_get_flags] |
126 | wait_for_servercommand: |
160 | test eax, 0x200 ; con window closed? |
127 | |
161 | jnz exit |
128 | ; invoke con_write_asciiz, str_dbg |
162 | 129 | ||
- | 130 | ; receive socket data |
|
- | 131 | mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, 0 |
|
163 | ; receive socket data |
132 | inc eax |
164 | mcall recv, [socketnum], [offset], BUFFERSIZE, MSG_DONTWAIT |
133 | jz socket_error |
165 | inc eax |
134 | dec eax |
166 | jz wait_for_serverdata |
- | |
167 | dec eax |
135 | jz wait_for_servercommand |
168 | jz wait_for_serverdata |
136 | |
169 | 137 | ; invoke con_write_asciiz, str_dbg2 |
|
170 | ; extract commands, copy them to "s" buffer |
138 | |
171 | add eax, buffer_ptr ; eax = end pointer |
139 | ; extract commands, copy them to "s" buffer |
172 | mov esi, buffer_ptr ; esi = current pointer |
140 | lea ecx, [eax + buffer_ptr] ; ecx = end pointer |
173 | .nextcommand: |
141 | mov esi, buffer_ptr ; esi = current pointer |
174 | mov edi, s |
142 | mov edi, s |
175 | .byteloop: |
143 | .byteloop: |
176 | cmp esi, eax |
144 | cmp esi, ecx |
177 | jae wait_for_serverdata |
145 | jae wait_for_servercommand |
178 | lodsb |
146 | lodsb |
179 | cmp al, 10 ; excellent, we might have a command |
147 | cmp al, 10 ; excellent, we might have a command |
180 | je .got_command |
148 | je .got_command |
181 | cmp al, 13 ; just ignore this crap |
149 | cmp al, 13 ; just ignore this byte |
182 | je .byteloop |
150 | je .byteloop |
183 | stosb |
151 | stosb |
184 | jmp .byteloop |
152 | jmp .byteloop |
185 | - | ||
186 | ; we have a newline check if its a command |
153 | .got_command: ; we have a newline check if its a command |
187 | .got_command: |
- | |
188 | xor al, al |
154 | xor al, al |
189 | stosb |
155 | stosb |
190 | ; push esi eax |
- | |
191 | - | ||
192 | ; print it to the screen |
- | |
193 | pushd s |
- | |
194 | call [con_write_asciiz] |
- | |
195 | pushd str4 ; newline |
- | |
196 | call [con_write_asciiz] |
- | |
197 | - | ||
198 | ; cmp byte[s+2], " " |
- | |
199 | ; jne .not_command |
- | |
200 | - | ||
201 | lea ecx, [edi - s] |
- | |
202 | call server_parser |
- | |
203 | - | ||
204 | ; .not_command: |
- | |
205 | ; pop eax esi |
- | |
206 | ; jmp .nextcommand |
- | |
- | 156 | ||
- | 157 | sub edi, s ; length |
|
- | 158 | push edi |
|
- | 159 | ||
- | 160 | invoke con_set_flags, 0x03 ; change color |
|
- | 161 | invoke con_write_asciiz, s ; print servercommand |
|
- | 162 | invoke con_write_asciiz, str4 ; newline |
|
- | 163 | invoke con_set_flags, 0x07 |
|
207 | 164 | ||
208 | 165 | pop ecx |
|
209 | 166 | jmp server_parser ; parse command |
|
210 | 167 | ||
211 | wait_for_usercommand: |
168 | wait_for_usercommand: |
- | 169 | ||
- | 170 | invoke con_set_flags, 0x0a |
|
212 | 171 | ||
213 | cmp [status], STATUS_CONNECTED |
172 | cmp [status], STATUS_CONNECTED |
214 | je .connected |
173 | je .connected |
215 | 174 | ||
216 | cmp [status], STATUS_NEEDPASSWORD |
175 | cmp [status], STATUS_NEEDPASSWORD |
217 | je .needpass |
176 | je .needpass |
218 | 177 | ||
219 | ; write prompt |
178 | ; write prompt |
220 | push str2 |
- | |
221 | call [con_write_asciiz] |
179 | invoke con_write_asciiz, str2 |
222 | ; read string |
180 | ; read string |
223 | mov esi, s |
181 | mov esi, s |
224 | push 256 |
- | |
225 | push esi |
- | |
226 | call [con_gets] |
182 | invoke con_gets, esi, 256 |
227 | - | ||
228 | call [con_get_flags] |
183 | invoke con_set_flags, 0x07 |
229 | test eax, 0x200 ; con window closed? |
- | |
230 | jnz exit |
- | |
231 | 184 | ||
232 | cmp dword[s], "list" |
185 | cmp dword[s], "list" |
233 | je cmd_list |
186 | je cmd_list |
234 | 187 | ||
235 | cmp dword[s], "help" |
188 | cmp dword[s], "help" |
236 | je cmd_help |
189 | je cmd_help |
237 | - | ||
238 | push str_unkown |
190 | |
239 | call [con_write_asciiz] |
- | |
240 | 191 | invoke con_write_asciiz, str_unknown |
|
241 | jmp wait_for_usercommand |
192 | jmp wait_for_usercommand |
242 | 193 | ||
243 | 194 | ||
244 | .connected: |
195 | .connected: |
245 | - | ||
246 | push str_user |
196 | |
247 | call [con_write_asciiz] |
- | |
248 | 197 | invoke con_write_asciiz, str_user |
|
249 | mov dword[s], "USER" |
198 | mov dword[s], "USER" |
250 | mov byte[s+4], " " |
- | |
251 | - | ||
252 | ; mov [status], STATUS_NEEDPASSWORD |
- | |
253 | inc [status] |
- | |
254 | 199 | mov byte[s+4], " " |
|
255 | jmp .send |
200 | jmp .send |
256 | 201 | ||
257 | 202 | ||
258 | .needpass: |
203 | .needpass: |
259 | push str_pass |
- | |
260 | call [con_write_asciiz] |
- | |
- | 204 | ||
261 | 205 | invoke con_write_asciiz, str_pass |
|
262 | mov dword[s], "PASS" |
206 | mov dword[s], "PASS" |
263 | mov byte[s+4], " " |
207 | mov byte[s+4], " " |
264 | - | ||
265 | ; mov [status], STATUS_LOGGED_IN |
- | |
266 | inc [status] |
- | |
267 | 208 | ||
268 | .send: |
209 | .send: |
269 | ; read string |
210 | ; read string |
270 | mov esi, s+5 |
211 | mov esi, s+5 |
271 | push 256 |
- | |
272 | push esi |
- | |
273 | call [con_gets] |
212 | invoke con_gets, esi, 256 |
274 | 213 | ||
275 | mov edi, s+5 |
214 | mov edi, s+5 |
276 | mov ecx, 256 |
215 | mov ecx, 256 |
277 | xor al, al |
216 | xor al, al |
278 | repne scasb |
217 | repne scasb |
279 | lea esi, [edi-s-1] |
218 | lea esi, [edi-s-1] |
280 | mcall send, [socketnum], s |
219 | mcall send, [socketnum], s, , 0 |
281 | - | ||
282 | jmp wait_for_usercommand |
- | |
283 | - | ||
284 | - | ||
- | 220 | ||
- | 221 | invoke con_write_asciiz, str4 ; newline |
|
- | 222 | invoke con_set_flags, 0x07 |
|
285 | 223 | jmp wait_for_servercommand |
|
286 | 224 | ||
287 | 225 | ||
288 | 226 | ||
289 | open_dataconnection: |
227 | open_dataconnection: |
290 | cmp [status], STATUS_LOGGED_IN |
228 | cmp [status], STATUS_LOGGED_IN |
291 | jne .fail |
229 | jne .fail |
292 | 230 | ||
293 | mov dword[s], "PASV" |
231 | mov dword[s], "PASV" |
294 | mov byte[s+4], 10 |
232 | mov byte[s+4], 10 |
295 | mcall send, [socketnum], s, 5 |
233 | mcall send, [socketnum], s, 5, 0 |
296 | - | ||
297 | ret |
234 | ret |
298 | 235 | ||
299 | .fail: |
236 | .fail: |
300 | push str6 |
- | |
301 | call [con_write_asciiz] |
237 | invoke con_write_asciiz, str6 |
302 | - | ||
303 | ret |
238 | ret |
304 | 239 | ||
305 | - | ||
306 | fail2: |
- | |
307 | push str6 |
- | |
- | 240 | ||
- | 241 | ||
308 | call [con_write_asciiz] |
242 | socket_error: |
309 | 243 | invoke con_write_asciiz, str6 |
|
310 | jmp fail.wait |
244 | jmp fail.wait |
311 | 245 | ||
312 | fail: |
246 | fail: |
313 | push str5 |
- | |
314 | call [con_write_asciiz] |
247 | invoke con_write_asciiz, str5 |
315 | .wait: |
248 | .wait: |
316 | push str10 |
- | |
317 | call [con_write_asciiz] |
249 | invoke con_write_asciiz, str10 |
318 | call [con_getch2] |
250 | invoke con_getch2 |
319 | jmp main |
251 | jmp main |
320 | 252 | ||
321 | done: |
253 | done: |
322 | push 1 |
- | |
323 | call [con_exit] |
254 | invoke con_exit, 1 |
324 | exit: |
- | |
- | 255 | ||
325 | 256 | exit: |
|
326 | mcall close, [socketnum] |
257 | mcall close, [socketnum] |
327 | mcall -1 |
258 | mcall -1 |
328 | 259 | ||
329 | 260 | ||
330 | 261 | ||
331 | ; data |
262 | ; data |
332 | title db 'FTP client',0 |
263 | title db 'FTP client',0 |
333 | str1 db 'FTP client for KolibriOS v0.01',10,10,'Please enter ftp server address.',10,0 |
264 | str1 db 'FTP client for KolibriOS v0.02',10,10,'Please enter ftp server address.',10,0 |
334 | str2 db '> ',0 |
265 | str2 db '> ',0 |
335 | str3 db 'Resolving ',0 |
266 | str3 db 'Resolving ',0 |
336 | str4 db 10,0 |
267 | str4 db 10,0 |
337 | str5 db 10,'Name resolution failed.',10,0 |
268 | str5 db 10,'Name resolution failed.',10,0 |
338 | str6 db 10,'Socket error.',10,0 |
269 | str6 db 10,'Socket error.',10,0 |
339 | str8 db ' (',0 |
270 | str8 db ' (',0 |
340 | str9 db ')',10,0 |
271 | str9 db ')',10,0 |
341 | str10 db 'Push any key to continue.',0 |
272 | str10 db 'Push any key to continue.',0 |
342 | str11 db 'Connecting',10,0 |
273 | str11 db 'Connecting...',10,0 |
343 | str12 db 'Connected!',10,0 |
274 | str12 db 'Waiting for welcome message.',10,0 |
344 | str_user db "username: ",0 |
275 | str_user db "username: ",0 |
345 | str_pass db "password: ",0 |
276 | str_pass db "password: ",0 |
346 | str_unkown db "unkown command",10,0 |
277 | str_unknown db "unknown command",10,0 |
347 | str_help db "available commands:",10,10 |
278 | str_help db "available commands:",10,10 |
348 | db "help list",10,0 |
279 | db "help list",10,0 |
349 | 280 | ||
350 | str_open db "opening data socket",10,0 |
281 | str_open db "opening data socket",10,0 |
- | 282 | ||
- | 283 | str_dbg db 'debug',10,0 |
|
- | 284 | str_dbg2 db 'debug2',10,0 |
|
351 | 285 | ||
352 | sockaddr1: |
286 | sockaddr1: |
353 | dw AF_INET4 |
287 | dw AF_INET4 |
354 | .port dw 0x1500 ; 21 |
288 | .port dw 0x1500 ; 21 |
355 | .ip dd 0 |
289 | .ip dd 0 |
356 | rb 10 |
290 | rb 10 |
357 | 291 | ||
358 | sockaddr2: |
292 | sockaddr2: |
359 | dw AF_INET4 |
293 | dw AF_INET4 |
360 | .port dw 0 |
294 | .port dw 0 |
361 | .ip dd 0 |
295 | .ip dd 0 |
362 | rb 10 |
296 | rb 10 |
363 | - | ||
364 | include_debug_strings ; ALWAYS present in data section |
- | |
365 | - | ||
366 | 297 | ||
367 | 298 | ||
368 | ; import |
299 | ; import |
369 | align 4 |
300 | align 4 |
370 | @IMPORT: |
301 | @IMPORT: |
371 | 302 | ||
372 | library network, 'network.obj', console, 'console.obj' |
303 | library network, 'network.obj', console, 'console.obj' |
373 | 304 | ||
374 | import network, \ |
305 | import network, \ |
375 | getaddrinfo, 'getaddrinfo', \ |
306 | getaddrinfo, 'getaddrinfo', \ |
376 | freeaddrinfo, 'freeaddrinfo', \ |
307 | freeaddrinfo, 'freeaddrinfo', \ |
377 | inet_ntoa, 'inet_ntoa' |
308 | inet_ntoa, 'inet_ntoa' |
378 | 309 | ||
379 | import console, \ |
310 | import console, \ |
380 | con_start, 'START', \ |
311 | con_start, 'START', \ |
381 | con_init, 'con_init', \ |
312 | con_init, 'con_init', \ |
382 | con_write_asciiz,'con_write_asciiz', \ |
313 | con_write_asciiz,'con_write_asciiz', \ |
383 | con_exit, 'con_exit', \ |
314 | con_exit, 'con_exit', \ |
384 | con_gets, 'con_gets',\ |
315 | con_gets, 'con_gets',\ |
385 | con_cls, 'con_cls',\ |
316 | con_cls, 'con_cls',\ |
386 | con_getch2, 'con_getch2',\ |
317 | con_getch2, 'con_getch2',\ |
387 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
318 | con_set_cursor_pos, 'con_set_cursor_pos',\ |
388 | con_write_string, 'con_write_string',\ |
319 | con_write_string, 'con_write_string',\ |
- | 320 | con_get_flags, 'con_get_flags', \ |
|
389 | con_get_flags, 'con_get_flags' |
321 | con_set_flags, 'con_set_flags' |
390 | 322 | ||
391 | 323 | ||
392 | i_end: |
324 | i_end: |
393 | 325 | ||
394 | active_passive db ? |
326 | active_passive db ? |
395 | socketnum dd ? |
327 | socketnum dd ? |
396 | datasocket dd ? |
328 | datasocket dd ? |
397 | buffer_ptr rb 2*BUFFERSIZE |
329 | buffer_ptr rb 2*BUFFERSIZE |
398 | status db ? |
330 | status db ? |
399 | offset dd ? |
- | |
400 | 331 | ||
401 | s rb 1024 |
332 | s rb 1024 |
402 | 333 | ||
403 | mem: |
334 | mem: |