From 6a1d621671ba2a81b30cf25c68e4adca140db4ee Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sun, 11 Jul 2010 23:13:12 +0000 Subject: [PATCH] - globalisation of network driver functions (Replaced EthRegDev with NetRegDev) - rewrite/cleanup of socket.inc - started rewrite of tcp.inc - port numbers in application are not byte-swapped anymore - many more fixes and changes - TCP does not work but UDP/IP/ICMP/ARP (partly) work.. (as before) git-svn-id: svn://kolibrios.org@1514 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../net/applications/netcfg/netcfg.asm | 2 + .../net/applications/network_lib/network.asm | 2 +- .../net/applications/nslookup/nslookup.asm | 2 +- .../net/applications/telnet/telnet.asm | 2 +- .../branches/net/applications/tftpc/TFTP.asm | 349 +- .../net/applications/zeroconf/zeroconf.asm | 289 +- kernel/branches/net/core/exports.inc | 156 +- kernel/branches/net/core/sys32.inc | 804 +-- kernel/branches/net/drivers/3c59x.asm | 5 +- kernel/branches/net/drivers/RTL8029.asm | 8 +- kernel/branches/net/drivers/RTL8139.asm | 27 +- kernel/branches/net/drivers/dec21x4x.asm | 7 +- kernel/branches/net/drivers/imports.inc | 8 +- kernel/branches/net/drivers/netdrv.inc | 17 +- kernel/branches/net/drivers/pcnet32.asm | 6 +- kernel/branches/net/drivers/sis900.asm | 47 +- kernel/branches/net/kernel.asm | 5000 ++++++++--------- kernel/branches/net/network/ARP.inc | 17 +- kernel/branches/net/network/IPv4.inc | 176 +- kernel/branches/net/network/ethernet.inc | 397 +- kernel/branches/net/network/icmp.inc | 203 +- kernel/branches/net/network/queue.inc | 4 +- kernel/branches/net/network/socket.inc | 1269 +++-- kernel/branches/net/network/stack.inc | 384 +- kernel/branches/net/network/tcp.inc | 2770 +++++---- kernel/branches/net/network/udp.inc | 122 +- 26 files changed, 6368 insertions(+), 5705 deletions(-) diff --git a/kernel/branches/net/applications/netcfg/netcfg.asm b/kernel/branches/net/applications/netcfg/netcfg.asm index 4a9cec9cad..2cff7afb2f 100644 --- a/kernel/branches/net/applications/netcfg/netcfg.asm +++ b/kernel/branches/net/applications/netcfg/netcfg.asm @@ -157,6 +157,8 @@ draw_window: mcall 12, 1 ; start of draw mcall 0, dword [Form], dword [Form + 4], 0x13ffffff, 0x805080d0, title + mcall 8, 136 shl 16 + 100, 35 shl 16 + 18, 4, 0x00007f00 ; SLIP + call Get_PCI_Info ; get pci version and last bus, scan for and draw each pci device cmp edx, 20 shl 16 + 110 diff --git a/kernel/branches/net/applications/network_lib/network.asm b/kernel/branches/net/applications/network_lib/network.asm index 1b9b5a8301..787722f0b9 100644 --- a/kernel/branches/net/applications/network_lib/network.asm +++ b/kernel/branches/net/applications/network_lib/network.asm @@ -689,7 +689,7 @@ lock xadd [DNSrequestID], eax ; atomically increment ID, get old value push 0 push 0 ; sin_zero push esi ; sin_addr - push AF_INET + (53 shl 24) + push AF_INET + (53 shl 16) ; sin_family and sin_port in network byte order ; 8c. Connect. mcall 74, 4, , esp, sizeof.sockaddr_in diff --git a/kernel/branches/net/applications/nslookup/nslookup.asm b/kernel/branches/net/applications/nslookup/nslookup.asm index 14ca91688f..326a1231ec 100644 --- a/kernel/branches/net/applications/nslookup/nslookup.asm +++ b/kernel/branches/net/applications/nslookup/nslookup.asm @@ -13,7 +13,7 @@ use32 include '../macros.inc' purge mov,add,sub include '../proc32.inc' -include 'dll.inc' +include '../dll.inc' include '../network_lib/network.inc' diff --git a/kernel/branches/net/applications/telnet/telnet.asm b/kernel/branches/net/applications/telnet/telnet.asm index 1a4ef61362..d09745df69 100644 --- a/kernel/branches/net/applications/telnet/telnet.asm +++ b/kernel/branches/net/applications/telnet/telnet.asm @@ -194,7 +194,7 @@ str7 db 'Got data!',10,10,0 sockaddr1: dw AF_INET4 -.port dw 23 shl 8 +.port dw 23 .ip dd 0 rb 10 diff --git a/kernel/branches/net/applications/tftpc/TFTP.asm b/kernel/branches/net/applications/tftpc/TFTP.asm index d23fc45bd1..bffc4c5342 100644 --- a/kernel/branches/net/applications/tftpc/TFTP.asm +++ b/kernel/branches/net/applications/tftpc/TFTP.asm @@ -1,31 +1,35 @@ use32 + org 0x0 - org 0x0 - - db 'MENUET01' - dd 1, START, I_END, IM_END+0x1000, IM_END+0x1000, 0, 0 + db 'MENUET01' + dd 0x1 + dd START + dd I_END + dd IM_END + dd IM_END + dd 0, 0 include '../proc32.inc' include '../macros.inc' -include '../dll.inc' include '../libio.inc' -include '../../../../../programs/develop/libraries/box_lib/trunk/box_lib.mac' +include '../dll.inc' +include 'editbox_ex.mac' include '../network.inc' filebuffer_size equ 4*4096 ; 16kb (dont try to change it yet..) -TIMEOUT equ 500 +TIMEOUT equ 100 buffer_len equ 1500 AF_INET4 equ 2 IP_PROTO_UDP equ 17 -opcode_rrq equ 1 shl 8 -opcode_wrq equ 2 shl 8 -opcode_data equ 3 shl 8 -opcode_ack equ 4 shl 8 -opcode_error equ 5 shl 8 +opcode_rrq equ 1 +opcode_wrq equ 2 +opcode_data equ 3 +opcode_ack equ 4 +opcode_error equ 5 ; read/write request packet ; @@ -51,14 +55,14 @@ opcode_error equ 5 shl 8 ; error packet ; ; 2 bytes 2 bytes string 1 byte -; ----------------------------------------- +; ---------------------------------------- ; | Opcode | ErrorCode | ErrMsg | 0 | -; ----------------------------------------- +; ---------------------------------------- START: -;; mcall 68, 11 + mcall 68, 11 stdcall dll.Load, @IMPORT or eax, eax @@ -185,11 +189,11 @@ draw_window: mcall 4,350*65536+137, 0x80000000, str_kb_s -; mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x00000000 + mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x00000000 - mcall 4,20*65536+137, 0x80000000, [status] + mcall 4,50*65536+137, 0x80000000, str_complete -; mcall 47,1 shl 31 + 3 shl 16 + 1,done,25*65536+137,0x00000000 + mcall 47,1 shl 31 + 3 shl 16 + 1,done,25*65536+137,0x00000000 mcall 12,2 @@ -209,51 +213,40 @@ start_transfer: push esp ; fourth parameter push 0 ; third parameter push 0 ; second parameter - push SRV ; first parameter + push dword SRV ; first parameter call [getaddrinfo] - pop esi ; now we will have pointer to result in esi + pop esi ; test for error test eax, eax jnz still - mov esi, [esi + addrinfo.ai_addr] + mov esi, [esi] mov esi, [esi + sockaddr_in.sin_addr] mov dword [IP], esi - stdcall mem.Alloc, buffer_len - test eax, eax - jz stop_transfer - mov [packetbuff], eax - - invoke file_open, local_addr, O_READ + O_WRITE + O_CREATE - cmp eax, 32 - jb stop_transfer - - mov [fh], eax - - mcall socket, AF_INET4, IP_PROTO_UDP, 0 ; socket_open + mcall socket, AF_INET4, IP_PROTO_UDP, 0 ; socket_open cmp eax, -1 je still mov [socketnum], eax - mcall connect, [socketnum], sockaddr, sockaddr_len ; socket_connect + mcall connect, [socketnum], sockaddr, sockaddr_len ; socket_connect cmp eax, -1 je still mov word [I_END], opcode_rrq - cmp [option_group2],op3 ; method = get? - jz @f + cmp [option_group2],op3 + je @f mov word [I_END], opcode_wrq - @@: + @@: xor al , al mov edi, remote_addr mov ecx, 250 repnz scasb - sub edi, remote_addr + sub edi, remote_addr-1 mov ecx, edi mov edi, I_END+2 mov esi, remote_addr @@ -283,211 +276,168 @@ start_transfer: mov esi, edi mcall send, [socketnum], I_END - mov [last_ack], 0 - -; mcall 26, 9 -; mov [last_time], eax - - mov [status], str_transfering - call draw_window - mcall 40, 10000101b - cmp [option_group2],op3 ; method = get? - jnz send_data_loop + mov [last_ack], 0 + + + + - invoke file_truncate, [fh] receive_data_loop: mcall 23, TIMEOUT dec eax - jz .redraw + jz .red dec eax - dec eax - jz .btn + jz .key - mcall recv, [socketnum], [packetbuff], buffer_len ; receive data - mov esi, [packetbuff] - cmp word[esi], opcode_data + mcall recv, [socketnum], buffer, buffer_len, 0 ; receive data + + cmp word[buffer], opcode_data jne .error mov bx, [last_ack] - inc bx - rol bx, 8 - - cmp word [esi + 2], bx + cmp word [buffer + 2], bx jne .packet_got_lost - inc [last_ack] + cmp eax, 4+512 + je .continue - ; now, we need to store the data - - add esi, 4 - sub eax, 4 - mov ecx, eax - invoke file_write, [fh], esi ,ecx - - cmp ecx, 512 ; full data packet? - jge .continue - - ; last packet, or something else - - mov [status], str_success - -.kill_xfer: - - invoke file_close, [fh] - mcall close, [socketnum] - jmp stop_transfer - +; last packet, or something else .error: - cmp word[esi], opcode_error - je .decode_error - - jmp .continue - .packet_got_lost: + .continue: -; mcall 26, 9 -; mov ebx, [last_time] -; mov [last_time], eax -; xor edx, edx -; sub eax, ebx -; xchg eax, ecx -; div ecx -; mov [kbps], eax -; mcall 47,1 shl 31 + 7 shl 16 + 1,kbps,305*65536+137,0x40000000, 0x00ffffff - - mov word [buffer], opcode_ack ; send ack - mov ax, [last_ack] - rol ax, 8 - mov word [buffer+2], ax + mov word[buffer], opcode_ack ; send ack mcall send, [socketnum], buffer, 4, 0 jmp receive_data_loop +.red: -.btn: - mcall 17 - - jmp .kill_xfer - -.redraw: call draw_window + jmp receive_data_loop -.decode_error: - movzx esi, word[esi + 2] - cmp esi, 7 - cmovg esi, [zero] +.key: + mcall 2 + cmp ah, 2 + jz exit + + ; close socket ? + + jmp receive_data_loop + - mov esi, dword [4*esi + error_crosslist] - mov [status], esi - jmp .kill_xfer ;-------------------------------- -send_data_loop: +send_: - mov word[buffer], opcode_data + invoke file_open, local_addr, O_READ + or eax, eax + jz .exit + mov [fh], eax + + stdcall mem.Alloc, filebuffer_size + or eax, eax + jz .exit + mov [fb], eax + + mov [last_ack], 0 + mov [fo], 0 .read_chunk: - inc [last_ack] - - mov ax, [last_ack] - xchg al, ah - mov word[buffer+2], ax - - invoke file_read, [fh], buffer + 4, 512 + invoke file_seek, [fh], [fo], SEEK_END cmp eax, -1 - je .kill_xfer + je .exit + invoke file_read, [fh], [fb], filebuffer_size + cmp eax, -1 + je .exit + add [fo], filebuffer_size + cmp eax, filebuffer_size + je .packet - add eax, 4 - mov [packetsize], eax + ; ijhidfhfdsndsfqk + +.packet: + + movzx esi, [last_ack] + and esi, 0x000000001f ; last five bits BUFFER SIZE MUST BE 16 kb for this to work !!! + shl esi, 9 ; = * 512 + add esi, [fb] + mov edi, buffer + mov ax, opcode_data + stosw + mov ax, [last_ack] + stosw + mov ecx, 512/4 + rep movsd + + mcall send, [socketnum], buffer, 4+512, 0 ; send data -.send_packet: - mcall send, [socketnum], buffer, [packetsize], 0 ; send data .loop: + mcall 23, TIMEOUT dec eax jz .red dec eax - dec eax - jz .btn + jz .key - mcall recv, [socketnum], [packetbuff], buffer_len ; receive ack - cmp eax, -1 - je .kill_xfer + mcall recv, [socketnum], buffer, buffer_len, 0 ; receive ack - mov esi, [packetbuff] - - cmp word[esi], opcode_error - je .decode_error - - cmp word[esi], opcode_ack - jne .send_packet + cmp word[buffer], opcode_ack + jne .exit mov ax, [last_ack] - xchg al, ah - cmp word[esi+2], ax - jne .send_packet + cmp word[buffer+2], ax + jne .packet + inc [last_ack] + test [last_ack],0x001f + jz .read_chunk + jmp .packet - cmp [packetsize], 512+4 - jne .xfer_ok ; transfer is done - - - - jmp .read_chunk .red: + call draw_window + jmp .loop -.btn: - mcall 17 +.key: + mcall 2 + cmp ah, 2 + jz exit -.kill_xfer: - mov [status], str_fail + ; close socket ? -.xfer_done: + jmp .loop + +.exit: invoke file_close, [fh] - mcall close, [socketnum] - jmp stop_transfer + jmp still -.xfer_ok: - mov [status], str_success - jmp .xfer_done - - -.decode_error: - movzx esi, word[esi + 2] - cmp esi, 7 - cmovg esi, [zero] - - mov esi, dword [4*esi + error_crosslist] - mov [status], esi - - jmp .send_packet @@ -500,16 +450,16 @@ done dd 0 sockaddr: dw AF_INET4 - dw 69 shl 8 + dw 69 IP db 192,168,1,115 sockaddr_len = $ - sockaddr align 16 @IMPORT: -library box_lib , 'box_lib.obj',\ - io_lib , 'libio.obj',\ - network , 'network.obj' +library box_lib , 'box_lib.obj' +library io_lib , 'libio.obj' +library network , 'network.obj' import box_lib ,\ edit_box_draw ,'edit_box' ,\ @@ -538,17 +488,16 @@ import io_lib ,\ file_truncate , 'file_truncate' ,\ file_close , 'file_close' -import network ,\ - inet_ntoa , 'inet_ntoa' ,\ - getaddrinfo , 'getaddrinfo' ,\ - freeaddrinfo , 'freeaddrinfo' +import network ,\ + inet_ntoa , 'inet_ntoa' ,\ + getaddrinfo , 'getaddrinfo' ,\ + freeaddrinfo , 'freeaddrinfo' - -edit1 edit_box 300,80,5 ,0xffffff,0x6f9480,0,0,0,99 ,SRV,ed_focus, 13,13 -edit2 edit_box 300,80,25,0xffffff,0x6a9480,0,0,0,99 ,remote_addr,ed_figure_only, 5,5 -edit3 edit_box 300,80,45,0xffffff,0x6a9480,0,0,0,99 ,local_addr,ed_figure_only, 13,13 -edit4 edit_box 40,340,68,0xffffff,0x6a9480,0,0,0,5 ,BLK,ed_figure_only, 3, 3 +edit1 edit_box 300,80,5 ,0xffffff,0x6f9480,0,0,0,99 ,SRV,ed_focus, 11,11 +edit2 edit_box 300,80,25,0xffffff,0x6a9480,0,0,0,99 ,remote_addr,ed_figure_only, 10,10 +edit3 edit_box 300,80,45,0xffffff,0x6a9480,0,0,0,99 ,local_addr,ed_figure_only, 27,27 +edit4 edit_box 40,340,68,0xffffff,0x6a9480,0,0,0,5 ,BLK,ed_figure_only, 3,3 op1 option_box option_group1,80,68,6,12,0xffffff,0,0,netascii,octet-netascii op2 option_box option_group1,80,85,6,12,0xFFFFFF,0,0,octet,get-octet @@ -558,7 +507,6 @@ op4 option_box option_group2,210,85,6,12,0xFFFFFF,0,0,put,BLK-put option_group1 dd op1 option_group2 dd op3 - Option_boxs1 dd op1,op2,0 Option_boxs2 dd op3,op4,0 @@ -572,11 +520,6 @@ str_blocksize db 'Blocksize:',0 str_kb_s db 'kb/s',0 str_complete db '% complete',0 str_transfer db 'Transfer',0 -str_waiting db 'Welcome!',0 -str_transfering db 'Transfering...',0 - -str_success db 'Tranfser completed sucessfully',0 -str_fail db 'Transfer failed!',0 str_error: ._0 db 'Not defined, see error message (if any).',0 @@ -589,18 +532,6 @@ str_error: ._7 db 'No such user.',0 -error_crosslist: -dd str_error._0 -dd str_error._1 -dd str_error._2 -dd str_error._3 -dd str_error._4 -dd str_error._5 -dd str_error._6 -dd str_error._7 - - - netascii db 'NetASCII' octet db 'Octet' get db 'GET' @@ -611,25 +542,19 @@ BLK db "512",0,0,0 last_ack dw ? fh dd ? ; file handle - -last_time dd ? - -packetbuff dd ? -packetsize dd ? -status dd str_waiting -zero dd 0 +fo dd ? ; file offset +fb dd ? ; file buffer SRV db "192.168.1.115",0 -times (SRV + 256 - $) db 0 +rb (SRV + 256 - $) -remote_addr db "3.png",0 -times (remote_addr + 256 - $) db 0 +remote_addr db "IMG00",0 +rb (remote_addr + 256 - $) -local_addr db "/sys/test.png",0 -times (local_addr + 256 - $) db 0 +local_addr db "/hd0/1/KolibriOS/kernel.mnt",0 +rb (local_addr + 256 - $) I_END: - buffer: rb buffer_len diff --git a/kernel/branches/net/applications/zeroconf/zeroconf.asm b/kernel/branches/net/applications/zeroconf/zeroconf.asm index 23dcf54206..cc561facc1 100644 --- a/kernel/branches/net/applications/zeroconf/zeroconf.asm +++ b/kernel/branches/net/applications/zeroconf/zeroconf.asm @@ -129,203 +129,184 @@ no_IP: START: ; start of execution - mcall 40, 1 shl 7 ; network event + mcall 40, 1 shl 7 ; network event -; eth.set_network_drv 0x00000383 + DEBUGF 1,">Zero-config service:\n" - DEBUGF 1,">Zero-config service:\n" + mcall 75, 1337 shl 16 + 4 -; eth.status eax ; Read the Stack status -; test eax,eax ; if eax is zero, no driver was found -; jnz @f -; DEBUGF 1,"No Card found!\n" -; jmp close + cmp eax, -1 + je close -; @@: -; DEBUGF 1,"Detected card: %x\n",eax -; @@: -; eth.check_cable eax -; test al,al -; jnz @f -; DEBUGF 1,"Cable disconnected!\n" -; mcall 5, 500 ; loop until cable is connected (check every 5 sec) -; jmp @r + mov word[MAC], bx + mov dword[MAC+2], eax -; @@: -; eth.read_mac MAC + DEBUGF 1,"->MAC: %x-%x-%x-%x-%x-%x\n",[MAC]:2,[MAC+1]:2,[MAC+2]:2,[MAC+3]:2,[MAC+4]:2,[MAC+5]:2 - mcall 75, 1337 shl 16 + 4 + cld + mov edi, path ; Calculate the length of zero-terminated string + xor al , al + mov ecx, 1024 + repnz scas byte[es:edi] + dec edi - cmp eax, -1 - je close + mov esi, filename + movsd + movsb - mov word[MAC], bx - mov dword[MAC+2], eax + DEBUGF 1,"->path to ini: %s\n", path - DEBUGF 1,"->MAC: %x-%x-%x-%x-%x-%x\n",[MAC]:2,[MAC+1]:2,[MAC+2]:2,[MAC+3]:2,[MAC+4]:2,[MAC+5]:2 + mcall 68,11 - cld - mov edi, path ; Calculate the length of zero-terminated string - xor al , al - mov ecx, 1024 - repnz scas byte[es:edi] - dec edi - - mov esi, filename - movsd - movsb - - DEBUGF 1,"->path to ini: %s\n", path - - mcall 68,11 - - stdcall dll.Load,@IMPORT - or eax,eax - jnz skip_ini + stdcall dll.Load,@IMPORT + or eax,eax + jnz skip_ini - invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 + invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 - mov eax,dword[inibuf] + mov eax,dword[inibuf] - cmp eax,'stat' - jne skip_ini + cmp eax,'stat' + jne skip_ini - invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 - mov edx, inibuf - call Ip2dword - mcall 75, 3, edx + invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + mcall 75, 3, edx - invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 - mov edx, inibuf - call Ip2dword - mcall 75, 9, edx + invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + mcall 75, 9, edx - invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 - mov edx, inibuf - call Ip2dword - mcall 75, 5, edx + invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + mcall 75, 5, edx - invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 - mov edx, inibuf - call Ip2dword - mcall 75, 7, edx + invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + mcall 75, 7, edx - mcall -1 + mcall -1 skip_ini: - DEBUGF 1,"->Skip ini\n" + DEBUGF 1,"->Skip ini\n" - mcall 74, 0, AF_INET4, IP_PROTO_UDP, 0 ; open socket (parameters: domain, type, reserved) - cmp eax, -1 - je error - mov [socketNum], eax + mcall 74, 0, AF_INET4, IP_PROTO_UDP, 0 ; open socket (parameters: domain, type, reserved) + cmp eax, -1 + je error + mov [socketNum], eax - DEBUGF 1,"->socket %x opened\n", eax + DEBUGF 1,"->socket %x opened\n", eax - mcall 74, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68 - cmp eax, -1 - je error + mcall 74, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68 + cmp eax, -1 + je error - DEBUGF 1,"->Socket Bound to local port 68\n" + DEBUGF 1,"->Socket Bound to local port 68\n" - mcall 74, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67 - cmp eax, -1 - je error + mcall 74, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67 + cmp eax, -1 + je error - DEBUGF 1,"->Connected to 255.255.255.255 on port 67\n" + DEBUGF 1,"->Connected to 255.255.255.255 on port 67\n" - mov byte [dhcpMsgType], 0x01 ; DHCP discover - mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) + mov byte [dhcpMsgType], 0x01 ; DHCP discover + mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) - mcall 26, 9 - imul eax,100 - mov [currTime],eax + mcall 26, 9 + imul eax,100 + mov [currTime],eax buildRequest: ; Creates a DHCP request packet. - DEBUGF 1,"->Building request\n" + DEBUGF 1,"->Building request\n" - stdcall mem.Alloc, BUFFER - mov [dhcpMsg], eax - test eax,eax - jz apipa + stdcall mem.Alloc, BUFFER + mov [dhcpMsg], eax + test eax,eax + jz apipa + ;;; todo: skip this bullcrap - mov edi, eax - mov ecx,BUFFER - xor eax,eax - cld - rep stosb + mov edi, eax + mov ecx, BUFFER + xor eax, eax + cld + rep stosb - mov edx,[dhcpMsg] + ;; todo: put this in a buffer instead of writing bytes and words! - mov [edx], byte 0x01 ; Boot request - mov [edx+1], byte 0x01 ; Ethernet - mov [edx+2], byte 0x06 ; Ethernet h/w len - mov [edx+4], dword 0x11223344 ; xid - mov eax,[currTime] - mov [edx+8], eax ; secs, our uptime - mov [edx+10], byte 0x80 ; broadcast flag set - mov eax, dword [MAC] ; first 4 bytes of MAC - mov [edx+28],dword eax - mov ax, word [MAC+4] ; last 2 bytes of MAC - mov [edx+32],word ax - mov [edx+236], dword 0x63538263 ; magic number - mov [edx+240], word 0x0135 ; option DHCP msg type - mov al, [dhcpMsgType] - mov [edx+240+2], al - mov [edx+240+3], word 0x0433 ; option Lease time = infinity - mov eax, [dhcpLease] - mov [edx+240+5], eax - mov [edx+240+9], word 0x0432 ; option requested IP address - mov eax, [dhcpClientIP] - mov [edx+240+11], eax - mov [edx+240+15], word 0x0437 ; option request list - mov [edx+240+17], dword 0x0f060301 + mov edx,[dhcpMsg] - cmp [dhcpMsgType], byte 0x01 ; Check which msg we are sending - jne request_options + mov [edx], byte 0x01 ; Boot request + mov [edx+1], byte 0x01 ; Ethernet + mov [edx+2], byte 0x06 ; Ethernet h/w len + mov [edx+4], dword 0x11223344 ; xid ;;;;;;; + mov eax,[currTime] + mov [edx+8], eax ; secs, our uptime + mov [edx+10], byte 0x80 ; broadcast flag set + mov eax, dword [MAC] ; first 4 bytes of MAC + mov [edx+28],dword eax + mov ax, word [MAC+4] ; last 2 bytes of MAC + mov [edx+32],word ax + mov [edx+236], dword 0x63538263 ; magic cookie + mov [edx+240], word 0x0135 ; option DHCP msg type + mov al, [dhcpMsgType] + mov [edx+240+2], al + mov [edx+240+3], word 0x0433 ; option Lease time = infinity + mov eax, [dhcpLease] + mov [edx+240+5], eax + mov [edx+240+9], word 0x0432 ; option requested IP address + mov eax, [dhcpClientIP] + mov [edx+240+11], eax + mov [edx+240+15], word 0x0437 ; option request list + mov [edx+240+17], dword 0x0f060301 - mov [edx+240+21], byte 0xff ; "Discover" options + cmp [dhcpMsgType], byte 0x01 ; Check which msg we are sending + jne request_options - mov [dhcpMsgLen], dword 262 ; end of options marker - jmp send_request + mov [edx+240+21], byte 0xff ; "Discover" options + + mov [dhcpMsgLen], dword 262 ; end of options marker + jmp send_request request_options: - mov [edx+240+21], word 0x0436 ; server IP - mov eax, [dhcpServerIP] - mov [edx+240+23], eax + mov [edx+240+21], word 0x0436 ; server IP + mov eax, [dhcpServerIP] + mov [edx+240+23], eax - mov [edx+240+27], byte 0xff ; end of options marker + mov [edx+240+27], byte 0xff ; end of options marker - mov [dhcpMsgLen], dword 268 + mov [dhcpMsgLen], dword 268 send_request: - mcall 74, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket ( send broadcast request ) + mcall 74, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket ( send broadcast request ) - mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response - mov [dhcpMsgLen], eax ; Used as a pointer to the data + mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response + mov [dhcpMsgLen], eax ; Used as a pointer to the data - mcall 23, TIMEOUT*10 ; wait for data + mcall 23, TIMEOUT*10 ; wait for data -read_data: ; we have data - this will be the response +read_data: ; we have data - this will be the response + mcall 74, 7, [socketNum], [dhcpMsg], BUFFER ; read data from socket - mcall 74, 7, [socketNum], [dhcpMsg], BUFFER ; read data from socket + DEBUGF 1,"->%d bytes received\n", eax - DEBUGF 1,"->%d bytes received\n", eax + push eax + mcall 74, 1, [socketNum] ; close the socket + pop eax - push eax - mcall 74, 1, [socketNum] ; close the socket - pop eax + cmp eax, -1 + je error - cmp eax, -1 - je error - - mov [dhcpMsgLen], eax + mov [dhcpMsgLen], eax ; depending on which msg we sent, handle the response ; accordingly. @@ -342,23 +323,23 @@ read_data: ; we have data - this will be the response cmp [dhcpMsgType], byte 0x03 ; did we send a request? je request - jmp close ; really unknown, what we did + jmp close ; really unknown, what we did discover: - call parseResponse + call parseResponse - cmp [dhcpMsgType], byte 0x02 ; Was the response an offer? - jne apipa ; NO - so we do zeroconf - mov [dhcpMsgType], byte 0x03 ; DHCP request - jmp buildRequest + cmp [dhcpMsgType], byte 0x02 ; Was the response an offer? + jne apipa ; NO - so we do zeroconf + mov [dhcpMsgType], byte 0x03 ; DHCP request + jmp buildRequest request: - call parseResponse + call parseResponse - cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be - jne apipa ; NO - so we do zeroconf + cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be + jne apipa ; NO - so we do zeroconf - jmp close + jmp close ;*************************************************************************** ; Function @@ -464,7 +445,7 @@ pr001: pr_exit: ; DEBUGF 1,"Sending ARP announce\n" -; eth.ARP_ANNOUNCE [dhcpClientIP] ; send an ARP announce packet +;;; jmp close @@ -572,7 +553,7 @@ str_type db 'type',0 sockaddr1: dw AF_INET4 - dw 68 shl 8 ; local port + dw 68 ; local port dd 0 ; local IP rb 10 @@ -581,7 +562,7 @@ sockaddr1: sockaddr2: dw AF_INET4 - dw 67 shl 8 ; destination port + dw 67 ; destination port dd -1 ; destination IP rb 10 diff --git a/kernel/branches/net/core/exports.inc b/kernel/branches/net/core/exports.inc index decb89d739..c284136350 100644 --- a/kernel/branches/net/core/exports.inc +++ b/kernel/branches/net/core/exports.inc @@ -9,79 +9,80 @@ $Revision$ iglobal - szKernel db 'KERNEL', 0 - szVersion db 'version',0 + szKernel db 'KERNEL', 0 + szVersion db 'version',0 - szRegService db 'RegService',0 - szGetService db 'GetService',0 + szRegService db 'RegService',0 + szGetService db 'GetService',0 szServiceHandler db 'ServiceHandler',0 szAttachIntHandler db 'AttachIntHandler',0 szGetIntHandler db 'GetIntHandler', 0 - szFpuSave db 'FpuSave',0 - szFpuRestore db 'FpuRestore',0 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 szReservePortArea db 'ReservePortArea',0 - szBoot_Log db 'Boot_Log',0 + szBoot_Log db 'Boot_Log',0 - szPciApi db 'PciApi', 0 - szPciRead32 db 'PciRead32', 0 - szPciRead16 db 'PciRead16', 0 - szPciRead8 db 'PciRead8', 0 - szPciWrite8 db 'PciWrite8',0 - szPciWrite16 db 'PciWrite16',0 - szPciWrite32 db 'PciWrite32',0 + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead16 db 'PciRead16', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',0 + szPciWrite16 db 'PciWrite16',0 + szPciWrite32 db 'PciWrite32',0 - szAllocPage db 'AllocPage',0 - szAllocPages db 'AllocPages',0 - szFreePage db 'FreePage',0 - szGetPgAddr db 'GetPgAddr',0 - szMapPage db 'MapPage',0 - szMapSpace db 'MapSpace',0 - szMapIoMem db 'MapIoMem',0 + szAllocPage db 'AllocPage',0 + szAllocPages db 'AllocPages',0 + szFreePage db 'FreePage',0 + szGetPgAddr db 'GetPgAddr',0 + szMapPage db 'MapPage',0 + szMapSpace db 'MapSpace',0 + szMapIoMem db 'MapIoMem',0 szCommitPages db 'CommitPages',0 szReleasePages db 'ReleasePages',0 szAllocKernelSpace db 'AllocKernelSpace',0 szFreeKernelSpace db 'FreeKernelSpace',0 szKernelAlloc db 'KernelAlloc',0 - szKernelFree db 'KernelFree',0 - szUserAlloc db 'UserAlloc',0 - szUserFree db 'UserFree',0 - szKmalloc db 'Kmalloc',0 - szKfree db 'Kfree',0 + szKernelFree db 'KernelFree',0 + szUserAlloc db 'UserAlloc',0 + szUserFree db 'UserFree',0 + szKmalloc db 'Kmalloc',0 + szKfree db 'Kfree',0 szCreateRingBuffer db 'CreateRingBuffer',0 - szGetPid db 'GetPid',0 + szGetPid db 'GetPid',0 szCreateObject db 'CreateObject',0 szDestroyObject db 'DestroyObject',0 szCreateEvent db 'CreateEvent',0 - szRaiseEvent db 'RaiseEvent',0 - szWaitEvent db 'WaitEvent',0 + szRaiseEvent db 'RaiseEvent',0 + szWaitEvent db 'WaitEvent',0 szDestroyEvent db 'DestroyEvent',0 - szClearEvent db 'ClearEvent',0 + szClearEvent db 'ClearEvent',0 - szLoadCursor db 'LoadCursor',0 + szLoadCursor db 'LoadCursor',0 szSysMsgBoardStr db 'SysMsgBoardStr', 0 szSysMsgBoardChar db 'SysMsgBoardChar', 0 szGetCurrentTask db 'GetCurrentTask',0 - szLFBAddress db 'LFBAddress',0 - szLoadFile db 'LoadFile',0 - szSendEvent db 'SendEvent',0 + szLFBAddress db 'LFBAddress',0 + szLoadFile db 'LoadFile',0 + szSendEvent db 'SendEvent',0 szSetMouseData db 'SetMouseData',0 - szSleep db 'Sleep',0 + szSleep db 'Sleep',0 szGetTimerTicks db 'GetTimerTicks',0 - szStrncat db 'strncat',0 - szStrncpy db 'strncpy',0 - szstrncmp db 'strncmp',0 - szStrnlen db 'strnlen',0 - szStrchr db 'strchr',0 - szStrrchr db 'strrchr',0 + szStrncat db 'strncat',0 + szStrncpy db 'strncpy',0 + szstrncmp db 'strncmp',0 + szStrnlen db 'strnlen',0 + szStrchr db 'strchr',0 + szStrrchr db 'strrchr',0 + szNetRegDev db 'NetRegDev',0 + szNetUnRegDev db 'NetUnRegDev',0 + szNetPtrToNum db 'NetPtrToNum',0 szEthReceiver db 'EthReceiver',0 - szEthRegDev db 'EthRegDev',0 - szEthUnRegDev db 'EthUnRegDev',0 - szEthStruc2Dev db 'EthStruc2Dev',0 + szIPv4Handler db 'IPv4Handler',0 align 16 @@ -91,12 +92,12 @@ kernel_export: dd szServiceHandler , srv_handler dd szAttachIntHandler, attach_int_handler dd szGetIntHandler , get_int_handler - dd szFpuSave , fpu_save + dd szFpuSave , fpu_save dd szFpuRestore , fpu_restore dd szReservePortArea , r_f_port_area dd szBoot_Log , boot_log - dd szPciApi , pci_api + dd szPciApi , pci_api dd szPciRead32 , pci_read32 dd szPciRead16 , pci_read16 dd szPciRead8 , pci_read8 @@ -104,60 +105,61 @@ kernel_export: dd szPciWrite16 , pci_write16 dd szPciWrite32 , pci_write32 - dd szAllocPage , alloc_page ;stdcall - dd szAllocPages , alloc_pages ;stdcall + dd szAllocPage , alloc_page ;stdcall + dd szAllocPages , alloc_pages ;stdcall dd szFreePage , free_page - dd szMapPage , map_page ;stdcall + dd szMapPage , map_page ;stdcall dd szMapSpace , map_space - dd szMapIoMem , map_io_mem ;stdcall + dd szMapIoMem , map_io_mem ;stdcall dd szGetPgAddr , get_pg_addr - dd szCommitPages , commit_pages ;not implemented + dd szCommitPages , commit_pages ;not implemented dd szReleasePages , release_pages dd szAllocKernelSpace, alloc_kernel_space ;stdcall dd szFreeKernelSpace , free_kernel_space ;stdcall - dd szKernelAlloc , kernel_alloc ;stdcall - dd szKernelFree , kernel_free ;stdcall - dd szUserAlloc , user_alloc ;stdcall - dd szUserFree , user_free ;stdcall - dd szKmalloc , malloc - dd szKfree , free + dd szKernelAlloc , kernel_alloc ;stdcall + dd szKernelFree , kernel_free ;stdcall + dd szUserAlloc , user_alloc ;stdcall + dd szUserFree , user_free ;stdcall + dd szKmalloc , malloc + dd szKfree , free dd szCreateRingBuffer, create_ring_buffer ;stdcall - dd szGetPid , get_pid + dd szGetPid , get_pid dd szCreateObject , create_kernel_object dd szDestroyObject , destroy_kernel_object - dd szCreateEvent , create_event ;see EVENT.inc for specification - dd szRaiseEvent , raise_event ;see EVENT.inc for specification - dd szWaitEvent , wait_event ;see EVENT.inc for specification - dd szDestroyEvent , destroy_event ;see EVENT.inc for specification - dd szClearEvent , clear_event ;see EVENT.inc for specification + dd szCreateEvent , create_event ;see EVENT.inc for specification + dd szRaiseEvent , raise_event ;see EVENT.inc for specification + dd szWaitEvent , wait_event ;see EVENT.inc for specification + dd szDestroyEvent , destroy_event ;see EVENT.inc for specification + dd szClearEvent , clear_event ;see EVENT.inc for specification - dd szLoadCursor , load_cursor ;stdcall + dd szLoadCursor , load_cursor ;stdcall dd szSysMsgBoardStr , sys_msg_board_str dd szSysMsgBoardChar , sys_msg_board dd szGetCurrentTask , get_curr_task - dd szLoadFile , load_file ;retval eax, ebx - dd szSendEvent , send_event ;see EVENT.inc for specification + dd szLoadFile , load_file ;retval eax, ebx + dd szSendEvent , send_event ;see EVENT.inc for specification dd szSetMouseData , set_mouse_data ;stdcall - dd szSleep , delay_ms + dd szSleep , delay_ms dd szGetTimerTicks , get_timer_ticks - dd szStrncat , strncat - dd szStrncpy , strncpy - dd szstrncmp , strncmp - dd szStrnlen , strnlen - dd szStrchr , strchr - dd szStrrchr , strrchr + dd szStrncat , strncat + dd szStrncpy , strncpy + dd szstrncmp , strncmp + dd szStrnlen , strnlen + dd szStrchr , strchr + dd szStrrchr , strrchr + dd szNetRegDev , NET_add_device + dd szNetUnRegDev , NET_remove_device + dd szNetPtrToNum , NET_ptr_to_num dd szEthReceiver , ETH_receiver - dd szEthRegDev , ETH_add_device - dd szEthUnRegDev , ETH_remove_device - dd szEthStruc2Dev , ETH_struc2dev + dd szIPv4Handler , IPv4_handler exp_lfb: dd szLFBAddress , 0 - dd 0 ;terminator, must be zero + dd 0 ;terminator, must be zero endg diff --git a/kernel/branches/net/core/sys32.inc b/kernel/branches/net/core/sys32.inc index 32c4e80a49..60652ec81b 100644 --- a/kernel/branches/net/core/sys32.inc +++ b/kernel/branches/net/core/sys32.inc @@ -16,202 +16,202 @@ $Revision$ align 4 ;3A08 build_interrupt_table: - mov edi, idts - mov esi, sys_int - mov ecx, 0x40 - mov eax, (10001110b shl 24) + os_code - @@: movsw ;low word of code-entry - stosd ;interrupt gate type : os_code selector - movsw ;high word of code-entry - loop @b - movsd ;copy low dword of trap gate for int 0x40 - movsd ;copy high dword of trap gate for int 0x40 - lidt [esi] - ret + mov edi, idts + mov esi, sys_int + mov ecx, 0x40 + mov eax, (10001110b shl 24) + os_code + @@: movsw ;low word of code-entry + stosd ;interrupt gate type : os_code selector + movsw ;high word of code-entry + loop @b + movsd ;copy low dword of trap gate for int 0x40 + movsd ;copy high dword of trap gate for int 0x40 + lidt [esi] + ret iglobal align 4 sys_int: ;exception handlers addresses (for interrupt gate construction) - dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc - dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 - dd e16, e17,e18, e19 - times 12 dd unknown_interrupt ;int_20..int_31 + dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc + dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15 + dd e16, e17,e18, e19 + times 12 dd unknown_interrupt ;int_20..int_31 ;interrupt handlers addresses (for interrupt gate construction) - dd irq0, irq_serv.irq_1, irq_serv.irq_2 - if USE_COM_IRQ - dd irq_serv.irq_3, irq_serv.irq_4 + dd irq0, irq_serv.irq_1, irq_serv.irq_2 + if USE_COM_IRQ + dd irq_serv.irq_3, irq_serv.irq_4 else - dd p_irq3, p_irq4 ;??? нестыковка + dd p_irq3, p_irq4 ;??? нестыковка end if - dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 - dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 - dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15 - times 16 dd unknown_interrupt ;int_0x30..int_0x3F + dd irq_serv.irq_5, p_irq6, irq_serv.irq_7 + dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 + dd irq_serv.irq_11, irq_serv.irq_12, irqD,p_irq14,p_irq15 + times 16 dd unknown_interrupt ;int_0x30..int_0x3F ;int_0x40 gate trap (for directly copied) - dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 + dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) - dw 2*($-sys_int-4)-1 - dd idts ;0x8000B100 - dw 0 ;просто выравнивание + dw 2*($-sys_int-4)-1 + dd idts ;0x8000B100 + dw 0 ;просто выравнивание msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b - dd msg_exc_c,msg_exc_d,msg_exc_e + dd msg_exc_c,msg_exc_d,msg_exc_e - msg_exc_8 db "Double fault", 0 - msg_exc_u db "Undefined Exception", 0 - msg_exc_a db "Invalid TSS", 0 - msg_exc_b db "Segment not present", 0 - msg_exc_c db "Stack fault", 0 - msg_exc_d db "General protection fault", 0 - msg_exc_e db "Page fault", 0 + msg_exc_8 db "Double fault", 0 + msg_exc_u db "Undefined Exception", 0 + msg_exc_a db "Invalid TSS", 0 + msg_exc_b db "Segment not present", 0 + msg_exc_c db "Stack fault", 0 + msg_exc_d db "General protection fault", 0 + msg_exc_e db "Page fault", 0 - msg_sel_ker db "kernel", 0 - msg_sel_app db "application", 0 + msg_sel_ker db "kernel", 0 + msg_sel_app db "application", 0 endg macro save_ring3_context { - pushad + pushad } macro restore_ring3_context { - popad + popad } macro exc_wo_code [num] { e#num : - save_ring3_context - mov bl, num - jmp exc_c -} exc_wo_code 0,1,2,3,4,5,6,15,16,19 + save_ring3_context + mov bl, num + jmp exc_c +} exc_wo_code 0,1,2,3,4,5,6,15,16,19 macro exc_w_code [num] { e#num : - add esp, 4 - save_ring3_context - mov bl, num - jmp exc_c -} exc_w_code 8,9,10,11,12,13,17,18 + add esp, 4 + save_ring3_context + mov bl, num + jmp exc_c +} exc_w_code 8,9,10,11,12,13,17,18 uglobal - pf_err_code dd ? + pf_err_code dd ? endg -page_fault_exc: ; дуракоусточивость: селекторы испорчены... - pop [ss:pf_err_code]; действительно до следующего #PF - save_ring3_context - mov bl,14 +page_fault_exc: ; дуракоусточивость: селекторы испорчены... + pop [ss:pf_err_code]; действительно до следующего #PF + save_ring3_context + mov bl,14 -exc_c: ; исключения (все, кроме 7-го - #NM) +exc_c: ; исключения (все, кроме 7-го - #NM) ; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь) - reg_ss equ esp+0x30 - reg_esp3 equ esp+0x2C - reg_eflags equ esp+0x28 - reg_cs3 equ esp+0x24 - reg_eip equ esp+0x20 + reg_ss equ esp+0x30 + reg_esp3 equ esp+0x2C + reg_eflags equ esp+0x28 + reg_cs3 equ esp+0x24 + reg_eip equ esp+0x20 ; это фрэйм от pushad - reg_eax equ esp+0x1C - reg_ecx equ esp+0x18 - reg_edx equ esp+0x14 - reg_ebx equ esp+0x10 - reg_esp0 equ esp+0x0C - reg_ebp equ esp+0x08 - reg_esi equ esp+0x04 - reg_edi equ esp+0x00 + reg_eax equ esp+0x1C + reg_ecx equ esp+0x18 + reg_edx equ esp+0x14 + reg_ebx equ esp+0x10 + reg_esp0 equ esp+0x0C + reg_ebp equ esp+0x08 + reg_esi equ esp+0x04 + reg_edi equ esp+0x00 - Mov ds,ax,app_data ; загрузим правильные значения - mov es,ax ; в сегментные регистры - cld ; и приводим DF к стандарту - movzx ebx,bl + Mov ds,ax,app_data ; загрузим правильные значения + mov es,ax ; в сегментные регистры + cld ; и приводим DF к стандарту + movzx ebx,bl ; redirect to V86 manager? (EFLAGS & 0x20000) != 0? - test byte[reg_eflags+2],2 - jnz v86_exc_c - cmp bl,14 ; #PF - jne @f - call page_fault_handler ; SEE: core/memory.inc - @@: mov esi, [current_slot] - btr [esi+APPDATA.except_mask], ebx - jnc @f - mov eax,[esi+APPDATA.exc_handler] - test eax, eax - jnz IRetToUserHook - @@: cli - mov eax, [esi+APPDATA.debugger_slot] - test eax, eax - jnz .debug - sti + test byte[reg_eflags+2],2 + jnz v86_exc_c + cmp bl,14 ; #PF + jne @f + call page_fault_handler ; SEE: core/memory.inc + @@: mov esi, [current_slot] + btr [esi+APPDATA.except_mask], ebx + jnc @f + mov eax,[esi+APPDATA.exc_handler] + test eax, eax + jnz IRetToUserHook + @@: cli + mov eax, [esi+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti ; not debuggee => say error and terminate - call show_error_parameters ;; only ONE using, inline ??? + call show_error_parameters ;; only ONE using, inline ??? ;mov edx, [TASK_BASE] - mov [edx + TASKDATA.state], byte 4 ; terminate - jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc + mov [edx + TASKDATA.state], byte 4 ; terminate + jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc .debug: ; we are debugged process, notify debugger and suspend ourself ; eax=debugger PID - mov ecx,1 ; debug_message code=other_exception - cmp bl,1 ; #DB - jne .notify ; notify debugger and suspend ourself - mov ebx, dr6 ; debug_message data=DR6_image - xor edx, edx - mov dr6, edx - mov edx, dr7 - mov cl, not 8 - .l1: shl dl,2 - jc @f - and bl, cl - @@: sar cl,1 - jc .l1 - mov cl, 3 ; debug_message code=debug_exception + mov ecx,1 ; debug_message code=other_exception + cmp bl,1 ; #DB + jne .notify ; notify debugger and suspend ourself + mov ebx, dr6 ; debug_message data=DR6_image + xor edx, edx + mov dr6, edx + mov edx, dr7 + mov cl, not 8 + .l1: shl dl,2 + jc @f + and bl, cl + @@: sar cl,1 + jc .l1 + mov cl, 3 ; debug_message code=debug_exception .notify: - push ebx ; debug_message data - mov ebx, [TASK_BASE] - push [ebx+TASKDATA.pid] ; PID - push ecx ; debug_message code ((here: ecx==1/3)) - mov cl, 12 ; debug_message size - call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc - add esp,12 - mov edx, [TASK_BASE] - mov byte [edx+TASKDATA.state], 1 ; suspended - call change_task ; SEE: core/shed.inc - restore_ring3_context - iretd + push ebx ; debug_message data + mov ebx, [TASK_BASE] + push [ebx+TASKDATA.pid] ; PID + push ecx ; debug_message code ((here: ecx==1/3)) + mov cl, 12 ; debug_message size + call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc + add esp,12 + mov edx, [TASK_BASE] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task ; SEE: core/shed.inc + restore_ring3_context + iretd IRetToUserHook: - xchg eax, [reg_eip] - sub dword[reg_esp3], 8 - mov edi, [reg_esp3] - stosd - mov [edi], ebx - restore_ring3_context + xchg eax, [reg_eip] + sub dword[reg_esp3], 8 + mov edi, [reg_esp3] + stosd + mov [edi], ebx + restore_ring3_context unknown_interrupt: - iretd + iretd ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= show_error_parameters: - mov edx,[TASK_BASE] ;not scratched below - DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] - cmp bl, 0x08 - jb .l0 - cmp bl, 0x0e - jbe .l1 - .l0: mov bl, 0x09 - .l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4] - DEBUGF 1, "K : %s\n", eax - mov eax, [reg_cs3+4] - mov edi, msg_sel_app - mov ebx, [reg_esp3+4] - cmp eax, app_code - je @f - mov edi, msg_sel_ker - mov ebx, [reg_esp0+4] - @@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] - DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] - DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx - DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi - ret + mov edx,[TASK_BASE] ;not scratched below + DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid] + cmp bl, 0x08 + jb .l0 + cmp bl, 0x0e + jbe .l1 + .l0: mov bl, 0x09 + .l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4] + DEBUGF 1, "K : %s\n", eax + mov eax, [reg_cs3+4] + mov edi, msg_sel_app + mov ebx, [reg_esp3+4] + cmp eax, app_code + je @f + mov edi, msg_sel_ker + mov ebx, [reg_esp0+4] + @@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4] + DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4] + DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx + DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi + ret ;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= restore reg_ss @@ -231,90 +231,90 @@ show_error_parameters: ; irq1 -> hid/keyboard.inc macro irqh [num] { p_irq#num : - mov edi, num - jmp irqhandler + mov edi, num + jmp irqhandler } p_irq6: - save_ring3_context - mov ax, app_data ;os_data - mov ds, ax - mov es, ax - mov edi, 6 - cmp [v86_irqhooks+edi*8], 0 - jnz v86_irq2 - call fdc_irq - call ready_for_next_irq - restore_ring3_context - iret + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 6 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 + call fdc_irq + call ready_for_next_irq + restore_ring3_context + iret p_irq14: - save_ring3_context - mov ax, app_data ;os_data - mov ds, ax - mov es, ax - mov edi, 14 - cmp [v86_irqhooks+edi*8], 0 - jnz v86_irq2 + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 14 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 ; mov byte [BOOT_VAR + 0x48E], 0xFF - call [irq14_func] - call ready_for_next_irq_1 - restore_ring3_context - iret + call [irq14_func] + call ready_for_next_irq_1 + restore_ring3_context + iret p_irq15: - save_ring3_context - mov ax, app_data ;os_data - mov ds, ax - mov es, ax - mov edi, 15 - cmp [v86_irqhooks+edi*8], 0 - jnz v86_irq2 + save_ring3_context + mov ax, app_data ;os_data + mov ds, ax + mov es, ax + mov edi, 15 + cmp [v86_irqhooks+edi*8], 0 + jnz v86_irq2 ; mov byte [BOOT_VAR + 0x48E], 0xFF - call [irq15_func] - call ready_for_next_irq_1 - restore_ring3_context - iret + call [irq15_func] + call ready_for_next_irq_1 + restore_ring3_context + iret ready_for_next_irq: mov eax,5 - mov [check_idle_semaphore],eax + mov [check_idle_semaphore],eax ; mov al, 0x20 - add eax,(0x20-0x5) + add eax,(0x20-0x5) - out 0x20, al - ret + out 0x20, al + ret ;destroy eax ready_for_next_irq_1: mov eax,5 - mov [check_idle_semaphore],eax + mov [check_idle_semaphore],eax ; mov al, 0x20 - add eax,(0x20-0x5) - out 0xa0,al - out 0x20, al - ret + add eax,(0x20-0x5) + out 0xa0,al + out 0x20, al + ret irqD: - push eax + push eax xor eax,eax - out 0xf0,al - mov al,0x20 - out 0xa0,al - out 0x20,al - pop eax - iret + out 0xf0,al + mov al,0x20 + out 0xa0,al + out 0x20,al + pop eax + iret irqh 2,3,4,5,7,8,9,10,11 irqhandler: - mov esi,edi ; 1 - shl esi,6 ; 1 + mov esi,edi ; 1 + shl esi,6 ; 1 add esi,irq00read ; 1 - shl edi,12 ; 1 + shl edi,12 ; 1 add edi,IRQ_SAVE mov ecx,16 @@ -322,37 +322,37 @@ irqhandler: dec ecx js irqover - movzx edx, word [esi] ; 2+ + movzx edx, word [esi] ; 2+ - test edx, edx ; 1 + test edx, edx ; 1 jz irqover - mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size - mov eax, 4000 ; + 0x4 dword - data begin offset + mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size + mov eax, 4000 ; + 0x4 dword - data begin offset cmp ebx, eax je irqfull - add ebx, [edi + 0x4] ; add data size to data begin offset - cmp ebx, eax ; if end of buffer, begin cycle again + add ebx, [edi + 0x4] ; add data size to data begin offset + cmp ebx, eax ; if end of buffer, begin cycle again jb @f xor ebx, ebx @@: add ebx, edi - movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word + movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word dec eax jz irqbyte dec eax jnz noirqword in ax,dx - cmp ebx, 3999 ; check for address odd in the end of buffer + cmp ebx, 3999 ; check for address odd in the end of buffer jne .odd mov [ebx + 0x10], ax jmp .add_size .odd: - mov [ebx + 0x10], al ; I could make mistake here :) + mov [ebx + 0x10], al ; I could make mistake here :) mov [edi + 0x10], ah .add_size: add dword [edi], 2 @@ -377,37 +377,37 @@ irqhandler: set_application_table_status: - push eax + push eax - mov eax,[CURRENT_TASK] - shl eax, 5 - add eax,CURRENT_TASK+TASKDATA.pid - mov eax,[eax] + mov eax,[CURRENT_TASK] + shl eax, 5 + add eax,CURRENT_TASK+TASKDATA.pid + mov eax,[eax] - mov [application_table_status],eax + mov [application_table_status],eax - pop eax + pop eax - ret + ret clear_application_table_status: - push eax + push eax - mov eax,[CURRENT_TASK] - shl eax, 5 - add eax,CURRENT_TASK+TASKDATA.pid - mov eax,[eax] + mov eax,[CURRENT_TASK] + shl eax, 5 + add eax,CURRENT_TASK+TASKDATA.pid + mov eax,[eax] - cmp eax,[application_table_status] - jne apptsl1 + cmp eax,[application_table_status] + jne apptsl1 xor eax,eax - mov [application_table_status],eax + mov [application_table_status],eax apptsl1: - pop eax + pop eax - ret + ret ; * eax = 64 - номер функции ; * ebx = 1 - единственная подфункция @@ -417,21 +417,21 @@ clear_application_table_status: ; * eax = 1 - недостаточно памяти sys_resize_app_memory: - ; ebx = 1 - resize - ; ecx = new amount of memory + ; ebx = 1 - resize + ; ecx = new amount of memory ; cmp eax,1 dec ebx - jnz .no_application_mem_resize - stdcall new_mem_resize, ecx - mov [esp+32], eax + jnz .no_application_mem_resize + stdcall new_mem_resize, ecx + mov [esp+32], eax .no_application_mem_resize: - ret + ret iglobal ; process_terminating db 'K : Process - terminating',13,10,0 ; process_terminated db 'K : Process - done',13,10,0 - msg_obj_destroy db 'K : destroy app object',13,10,0 + msg_obj_destroy db 'K : destroy app object',13,10,0 endg ; param @@ -439,125 +439,125 @@ endg terminate: ; terminate application - .slot equ esp ;locals + .slot equ esp ;locals - push esi ;save .slot + push esi ;save .slot - shl esi, 8 - cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 - jne @F - pop esi - shl esi, 5 - mov [CURRENT_TASK+esi+TASKDATA.state], 9 - ret + shl esi, 8 + cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 + jne @F + pop esi + shl esi, 5 + mov [CURRENT_TASK+esi+TASKDATA.state], 9 + ret @@: - ;mov esi,process_terminating - ;call sys_msg_board_str + ;mov esi,process_terminating + ;call sys_msg_board_str @@: - cli - cmp [application_table_status],0 - je term9 - sti - call change_task - jmp @b + cli + cmp [application_table_status],0 + je term9 + sti + call change_task + jmp @b term9: - call set_application_table_status + call set_application_table_status ; if the process is in V86 mode... - mov eax, [.slot] - shl eax, 8 - mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack] - add esi, RING0_STACK_SIZE - cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi - jz .nov86 + mov eax, [.slot] + shl eax, 8 + mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack] + add esi, RING0_STACK_SIZE + cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi + jz .nov86 ; ...it has page directory for V86 mode - mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] - mov ecx, [esi+4] - mov [eax+SLOT_BASE+APPDATA.dir_table], ecx + mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0] + mov ecx, [esi+4] + mov [eax+SLOT_BASE+APPDATA.dir_table], ecx ; ...and I/O permission map for V86 mode - mov ecx, [esi+12] - mov [eax+SLOT_BASE+APPDATA.io_map], ecx - mov ecx, [esi+8] - mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx + mov ecx, [esi+12] + mov [eax+SLOT_BASE+APPDATA.io_map], ecx + mov ecx, [esi+8] + mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx .nov86: - mov esi, [.slot] - shl esi,8 - add esi, SLOT_BASE+APP_OBJ_OFFSET + mov esi, [.slot] + shl esi,8 + add esi, SLOT_BASE+APP_OBJ_OFFSET @@: - mov eax, [esi+APPOBJ.fd] - test eax, eax - jz @F + mov eax, [esi+APPOBJ.fd] + test eax, eax + jz @F - cmp eax, esi - je @F + cmp eax, esi + je @F - push esi - call [eax+APPOBJ.destroy] - DEBUGF 1,"%s",msg_obj_destroy - pop esi - jmp @B + push esi + call [eax+APPOBJ.destroy] + DEBUGF 1,"%s",msg_obj_destroy + pop esi + jmp @B @@: - mov eax, [.slot] - shl eax, 8 - stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr] + mov eax, [.slot] + shl eax, 8 + stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr] - mov esi, [.slot] - cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 - jne @F + mov esi, [.slot] + cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 + jne @F - mov [fpu_owner],1 - mov eax, [256+SLOT_BASE+APPDATA.fpu_state] - clts - bt [cpu_caps], CAPS_SSE - jnc .no_SSE - fxrstor [eax] - jmp @F + mov [fpu_owner],1 + mov eax, [256+SLOT_BASE+APPDATA.fpu_state] + clts + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + fxrstor [eax] + jmp @F .no_SSE: - fnclex - frstor [eax] + fnclex + frstor [eax] @@: - mov [KEY_COUNT],byte 0 ; empty keyboard buffer - mov [BTN_COUNT],byte 0 ; empty button buffer + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer ; remove defined hotkeys - mov eax, hotkey_list + mov eax, hotkey_list .loop: - cmp [eax+8], esi - jnz .cont - mov ecx, [eax] - jecxz @f - push dword [eax+12] - pop dword [ecx+12] + cmp [eax+8], esi + jnz .cont + mov ecx, [eax] + jecxz @f + push dword [eax+12] + pop dword [ecx+12] @@: - mov ecx, [eax+12] - push dword [eax] - pop dword [ecx] - xor ecx, ecx - mov [eax], ecx - mov [eax+4], ecx - mov [eax+8], ecx - mov [eax+12], ecx + mov ecx, [eax+12] + push dword [eax] + pop dword [ecx] + xor ecx, ecx + mov [eax], ecx + mov [eax+4], ecx + mov [eax+8], ecx + mov [eax+12], ecx .cont: - add eax, 16 - cmp eax, hotkey_list+256*16 - jb .loop + add eax, 16 + cmp eax, hotkey_list+256*16 + jb .loop ; remove hotkeys in buffer - mov eax, hotkey_buffer + mov eax, hotkey_buffer .loop2: - cmp [eax], esi - jnz .cont2 - and dword [eax+4], 0 - and dword [eax], 0 + cmp [eax], esi + jnz .cont2 + and dword [eax+4], 0 + and dword [eax], 0 .cont2: - add eax, 8 - cmp eax, hotkey_buffer+120*8 - jb .loop2 + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb .loop2 - mov ecx,esi ; remove buttons + mov ecx,esi ; remove buttons bnewba2: mov edi,[BTN_ADDR] mov eax,edi @@ -566,7 +566,7 @@ term9: inc bx bnewba: dec bx - jz bnmba + jz bnmba add eax,0x10 cmp cx,[eax] jnz bnewba @@ -615,10 +615,10 @@ term9: shl edi, 5 mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot] test eax, eax - jz .nodebug + jz .nodebug push 8 pop ecx - push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID + push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID push 2 call debugger_notify pop ecx @@ -626,86 +626,86 @@ term9: .nodebug: popad - mov ebx, [.slot] - shl ebx, 8 - push ebx - mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] + mov ebx, [.slot] + shl ebx, 8 + push ebx + mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] - stdcall kernel_free, ebx + stdcall kernel_free, ebx - pop ebx - mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir] - stdcall kernel_free, ebx + pop ebx + mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir] + stdcall kernel_free, ebx - mov edi, [.slot] - shl edi,8 - add edi,SLOT_BASE + mov edi, [.slot] + shl edi,8 + add edi,SLOT_BASE - mov eax, [edi+APPDATA.io_map] - cmp eax, [SLOT_BASE+256+APPDATA.io_map] - je @F - call free_page + mov eax, [edi+APPDATA.io_map] + cmp eax, [SLOT_BASE+256+APPDATA.io_map] + je @F + call free_page @@: - mov eax, [edi+APPDATA.io_map+4] - cmp eax, [SLOT_BASE+256+APPDATA.io_map+4] - je @F - call free_page + mov eax, [edi+APPDATA.io_map+4] + cmp eax, [SLOT_BASE+256+APPDATA.io_map+4] + je @F + call free_page @@: - mov eax, 0x20202020 - stosd - stosd - stosd - mov ecx,244/4 - xor eax, eax - rep stosd + mov eax, 0x20202020 + stosd + stosd + stosd + mov ecx,244/4 + xor eax, eax + rep stosd ; activate window - movzx eax, word [WIN_STACK + esi*2] - cmp eax, [TASK_COUNT] - jne .dont_activate - pushad + movzx eax, word [WIN_STACK + esi*2] + cmp eax, [TASK_COUNT] + jne .dont_activate + pushad .check_next_window: - dec eax - cmp eax, 1 - jbe .nothing_to_activate - lea esi, [WIN_POS+eax*2] - movzx edi, word [esi] ; edi = process - shl edi, 5 - cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots - je .check_next_window - add edi, window_data + dec eax + cmp eax, 1 + jbe .nothing_to_activate + lea esi, [WIN_POS+eax*2] + movzx edi, word [esi] ; edi = process + shl edi, 5 + cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots + je .check_next_window + add edi, window_data ; \begin{diamond}[19.09.2006] ; skip minimized windows - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .check_next_window + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .check_next_window ; \end{diamond} - call waredraw + call waredraw .nothing_to_activate: - popad + popad .dont_activate: - push esi ; remove hd1 & cd & flp reservation - shl esi, 5 - mov esi, [esi+CURRENT_TASK+TASKDATA.pid] - cmp [hd1_status], esi - jnz @f - call free_hd_channel - and [hd1_status], 0 + push esi ; remove hd1 & cd & flp reservation + shl esi, 5 + mov esi, [esi+CURRENT_TASK+TASKDATA.pid] + cmp [hd1_status], esi + jnz @f + call free_hd_channel + and [hd1_status], 0 @@: - cmp [cd_status], esi - jnz @f - call free_cd_channel - and [cd_status], 0 + cmp [cd_status], esi + jnz @f + call free_cd_channel + and [cd_status], 0 @@: - cmp [flp_status], esi - jnz @f - and [flp_status], 0 + cmp [flp_status], esi + jnz @f + and [flp_status], 0 @@: - pop esi - cmp [bgrlockpid], esi - jnz @f - and [bgrlockpid], 0 - and [bgrlock], 0 + pop esi + cmp [bgrlockpid], esi + jnz @f + and [bgrlockpid], 0 + and [bgrlock], 0 @@: pusha ; remove all irq reservations @@ -718,16 +718,16 @@ term9: newirqfree: cmp [edi + 4 * ebx], eax jne nofreeirq - mov [edi + 4 * ebx], edx ; remove irq reservation - mov [irq_tab + 4 * ebx], edx ; remove irq handler - mov [irq_rights + 4 * ebx], edx ; set access rights to full access + mov [edi + 4 * ebx], edx ; remove irq reservation + mov [irq_tab + 4 * ebx], edx ; remove irq handler + mov [irq_rights + 4 * ebx], edx ; set access rights to full access nofreeirq: inc ebx cmp ebx, 16 - jb newirqfree + jb newirqfree popa - pusha ; remove all port reservations + pusha ; remove all port reservations mov edx,esi shl edx, 5 add edx,CURRENT_TASK @@ -738,7 +738,7 @@ term9: mov esi,[RESERVED_PORTS] test esi,esi - jz rmpr9 + jz rmpr9 rmpr3: @@ -747,7 +747,7 @@ term9: add edi,RESERVED_PORTS cmp edx,[edi] - je rmpr4 + je rmpr4 dec esi jnz rmpr3 @@ -772,7 +772,7 @@ term9: rmpr9: popa - mov edi,esi ; do not run this process slot + mov edi,esi ; do not run this process slot shl edi, 5 mov [edi+CURRENT_TASK + TASKDATA.state],byte 9 ; debugger test - terminate all debuggees @@ -780,7 +780,7 @@ term9: mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot .xd0: cmp eax, [TASK_COUNT] - ja .xd1 + ja .xd1 cmp dword [ecx], esi jnz @f and dword [ecx], 0 @@ -812,23 +812,27 @@ term9: and [application_table_status],0 ;mov esi,process_terminated ;call sys_msg_board_str + + mov eax, [.slot] + call SOCKET_process_end + add esp, 4 ret restore .slot iglobal - boot_sched_1 db 'Building gdt tss pointer',0 - boot_sched_2 db 'Building IDT table',0 + boot_sched_1 db 'Building gdt tss pointer',0 + boot_sched_2 db 'Building IDT table',0 endg build_scheduler: - mov esi,boot_sched_1 - call boot_log + mov esi,boot_sched_1 + call boot_log ; call build_process_gdt_tss_pointer ; mov esi,boot_sched_2 ; call boot_log - ret + ret diff --git a/kernel/branches/net/drivers/3c59x.asm b/kernel/branches/net/drivers/3c59x.asm index 6c56dcb8b3..ebb8c048fb 100644 --- a/kernel/branches/net/drivers/3c59x.asm +++ b/kernel/branches/net/drivers/3c59x.asm @@ -545,7 +545,8 @@ proc service_proc stdcall, ioctl:dword .register: - call EthRegDev + mov [device.type], NET_TYPE_ETH + call NetRegDev cmp eax, -1 je .destroy @@ -566,7 +567,7 @@ proc service_proc stdcall, ioctl:dword .find_devicenum: DEBUGF 1,"Trying to find device number of already registered device\n" - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 1,"Kernel says: %u\n", eax diff --git a/kernel/branches/net/drivers/RTL8029.asm b/kernel/branches/net/drivers/RTL8029.asm index 7471b44f88..03cd00ee08 100644 --- a/kernel/branches/net/drivers/RTL8029.asm +++ b/kernel/branches/net/drivers/RTL8029.asm @@ -309,7 +309,9 @@ proc service_proc stdcall, ioctl:dword mov [DEVICE_LIST+4*eax], ebx inc [DEVICES] - call EthRegDev ; Register the device to kernel (ebx points to device struct) + mov [device.type], NET_TYPE_ETH + call NetRegDev + cmp eax, -1 jz .err ret 4 @@ -320,7 +322,7 @@ proc service_proc stdcall, ioctl:dword .find_devicenum: DEBUGF 1,"Trying to find device number of already registered device\n" mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 1,"Kernel says: %u\n", eax @@ -372,7 +374,7 @@ find_device_num: DEBUGF 1,"Trying to find device number of already registered device\n" mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 1,"Kernel says: %u\n", eax diff --git a/kernel/branches/net/drivers/RTL8139.asm b/kernel/branches/net/drivers/RTL8139.asm index c08edf1b3f..379c6edb6c 100644 --- a/kernel/branches/net/drivers/RTL8139.asm +++ b/kernel/branches/net/drivers/RTL8139.asm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; Realtek 8139 driver for KolibriOS ;; @@ -368,7 +368,9 @@ proc service_proc stdcall, ioctl:dword inc [RTL8139_DEV] ; - call EthRegDev + mov [device.type], NET_TYPE_ETH + call NetRegDev + cmp eax, -1 je .destroy @@ -378,8 +380,7 @@ proc service_proc stdcall, ioctl:dword .find_devicenum: DEBUGF 2,"Trying to find device number of already registered device\n" - mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 2,"Kernel says: %u\n", eax @@ -445,22 +446,25 @@ probe: shr ah , 2 shr ax , 6 and al , 01111111b + mov ecx, HW_VER_ARRAY_SIZE-1 .chip_ver_loop: - cmp al , [hw_ver_array+ecx] + cmp al , [hw_ver_array + ecx] je .chip_ver_found dec ecx jns .chip_ver_loop - xor cl , cl ; default RTL8139 + .unknown: + mov ecx, 8 .chip_ver_found: + cmp ecx, 8 + jg .unknown + mov [device.hw_ver_id], cl - shl ecx, 2 - add ecx, crosslist - mov ecx, [ecx] + mov ecx, [crosslist + ecx*4] mov [device.name], ecx - DEBUGF 2,"Chip version: %s\n",ecx + DEBUGF 2,"Chip version: %s\n", ecx ; wake up the chip @@ -1223,6 +1227,7 @@ device_5 db 'Realtek 8100',0 device_6 db 'Realtek 8139D',0 device_7 db 'Realtek 8139CP',0 device_8 db 'Realtek 8101',0 +device_unknown db 'Unknown RTL8139 clone', 0 crosslist dd device_1 dd device_2 @@ -1232,6 +1237,7 @@ crosslist dd device_1 dd device_6 dd device_7 dd device_8 + dd device_unknown hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with db VER_RTL8139A @@ -1241,6 +1247,7 @@ hw_ver_array db VER_RTL8139 ; This array is used by the probe routine to find db VER_RTL8139D db VER_RTL8139CP db VER_RTL8101 + db 0 HW_VER_ARRAY_SIZE = $-hw_ver_array diff --git a/kernel/branches/net/drivers/dec21x4x.asm b/kernel/branches/net/drivers/dec21x4x.asm index e7d12ee1a2..900d2f3960 100644 --- a/kernel/branches/net/drivers/dec21x4x.asm +++ b/kernel/branches/net/drivers/dec21x4x.asm @@ -449,7 +449,10 @@ proc service_proc stdcall, ioctl:dword test eax, eax jnz .err2 ; If an error occured, exit - call EthRegDev + + mov [device.type], NET_TYPE_ETH + call NetRegDev + cmp eax, -1 je .destroy @@ -460,7 +463,7 @@ proc service_proc stdcall, ioctl:dword .find_devicenum: DEBUGF 2,"Trying to find device number of already registered device\n" mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 2,"Kernel says: %u\n", eax diff --git a/kernel/branches/net/drivers/imports.inc b/kernel/branches/net/drivers/imports.inc index ec5f1eecd9..d1203c8d3b 100644 --- a/kernel/branches/net/drivers/imports.inc +++ b/kernel/branches/net/drivers/imports.inc @@ -88,7 +88,7 @@ kernel_export \ \ LFBAddress,\ \ - EthReceiver,\ - EthRegDev,\ - EthUnRegDev,\ - EthStruc2Dev + NetRegDev,\ + NetUnRegDev,\ + NetPtrToNum,\ + EthReceiver diff --git a/kernel/branches/net/drivers/netdrv.inc b/kernel/branches/net/drivers/netdrv.inc index a8acb7c381..4f03952bf9 100644 --- a/kernel/branches/net/drivers/netdrv.inc +++ b/kernel/branches/net/drivers/netdrv.inc @@ -23,6 +23,12 @@ PAGESIZE equ 4096 +; network driver types + + NET_TYPE_ETH equ 1 + NET_TYPE_SLIP equ 2 + + LAST_IO = 0 @@ -135,10 +141,12 @@ macro make_bus_master bus, dev { movzx edx, dev stdcall PciRead32, ecx ,edx, PCI_REG_COMMAND - or al, PCI_BIT_MASTER or PCI_BIT_PIO - and al, not PCI_BIT_MMIO + or al, PCI_BIT_MASTER ;or PCI_BIT_PIO +; and al, not PCI_BIT_MMIO stdcall PciWrite32, ecx, edx, PCI_REG_COMMAND, eax +;; TODO: try to switch to PIO, and check if PIO works or not.. + } struc IOCTL { @@ -178,9 +186,13 @@ macro virt_to_dma { ; input is eax } +macro NET_DEVICE { + .type dd ? +} ;struc ETH_DEVICE { macro ETH_DEVICE { + NET_DEVICE ; pointers to procedures .unload dd ? .reset dd ? @@ -202,6 +214,7 @@ macro ETH_DEVICE { macro SLIP_DEVICE { + NET_DEVICE ; pointers to procedures .unload dd ? .reset dd ? diff --git a/kernel/branches/net/drivers/pcnet32.asm b/kernel/branches/net/drivers/pcnet32.asm index 75d5d9b9f3..d6d61c7eaa 100644 --- a/kernel/branches/net/drivers/pcnet32.asm +++ b/kernel/branches/net/drivers/pcnet32.asm @@ -553,7 +553,9 @@ proc service_proc stdcall, ioctl:dword test eax, eax jnz .destroy ; If an error occured, exit - call EthRegDev + mov [device.type], NET_TYPE_ETH + call NetRegDev + cmp eax, -1 je .destroy @@ -564,7 +566,7 @@ proc service_proc stdcall, ioctl:dword .find_devicenum: DEBUGF 1,"Trying to find device number of already registered device\n" mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead DEBUGF 1,"Kernel says: %u\n", eax diff --git a/kernel/branches/net/drivers/sis900.asm b/kernel/branches/net/drivers/sis900.asm index b2b4beaa9b..2449ca74fb 100644 --- a/kernel/branches/net/drivers/sis900.asm +++ b/kernel/branches/net/drivers/sis900.asm @@ -36,23 +36,11 @@ format MS COFF include 'proc32.inc' include 'imports.inc' include 'fdo.inc' +include 'netdrv.inc' public START public version -struc IOCTL { - .handle dd ? - .io_code dd ? - .input dd ? - .inp_size dd ? - .output dd ? - .out_size dd ? -} - -virtual at 0 - IOCTL IOCTL -end virtual - NUM_RX_DESC equ 4 ;* Number of RX descriptors * NUM_TX_DESC equ 1 ;* Number of TX descriptors * RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * @@ -61,23 +49,11 @@ MAX_ETH_FRAME_SIZE equ 1516 TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ -struc ETH_DEVICE { -; pointers to procedures - .unload dd ? - .reset dd ? - .transmit dd ? - .set_MAC dd ? - .get_MAC dd ? - .set_mode dd ? - .get_mode dd ? -; status & variables - .bytes_tx dq ? - .bytes_rx dq ? - .packets_tx dd ? - .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) - .name dd ? - .mac dp ? +virtual at 0 + device: + + ETH_DEVICE + ; device specific .io_addr dd ? .pci_bus db ? @@ -91,7 +67,7 @@ align 4 .txd: times (3 * NUM_TX_DESC) dd 0 .rxd: times (3 * NUM_RX_DESC) dd 0 .size: -} +end virtual ; First page is designated to ETH_DEVICE, buffers start from second ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE @@ -102,9 +78,6 @@ ALLOCATION_SIZE = (ALLOCATION_SIZE + 7FFFh) and not 7FFFh MAX_DEVICES = 16 ; maximum number of devices which this driver can handle -virtual at 0 - device ETH_DEVICE -end virtual PCI_HEADER_TYPE equ 0x0e ;8 bit PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit @@ -238,7 +211,9 @@ service_proc: jnz .destroy ; 4n. If device was successfully initialized, register it for the kernel. - call EthRegDev + mov [device.type], NET_TYPE_ETH + call NetRegDev + cmp eax, -1 je .destroy @@ -248,7 +223,7 @@ service_proc: .find_devicenum: mov ebx, eax - call EthStruc2Dev ; This kernel procedure converts a pointer to device struct in ebx + call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx ; into a device number in edi mov eax, edi ; Application wants it in eax instead ret 4 diff --git a/kernel/branches/net/kernel.asm b/kernel/branches/net/kernel.asm index fbfdda5862..951dc3dc77 100644 --- a/kernel/branches/net/kernel.asm +++ b/kernel/branches/net/kernel.asm @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; PROGRAMMING: ;; Ivan Poddubny ;; Marat Zakiyanov (Mario79) @@ -60,24 +60,24 @@ include 'macros.inc' $Revision$ -USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices +USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices ; Enabling the next line will enable serial output console -debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used +debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used include "proc32.inc" include "kglobals.inc" lang fix en include "const.inc" -max_processes equ 255 -tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 +max_processes equ 255 +tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 -os_stack equ (os_data_l-gdts) ; GDTs +os_stack equ (os_data_l-gdts) ; GDTs os_code equ (os_code_l-gdts) graph_data equ (3+graph_data_l-gdts) -tss0 equ (tss0_l-gdts) +tss0 equ (tss0_l-gdts) app_code equ (3+app_code_l-gdts) app_data equ (3+app_data_l-gdts) app_tls equ (3+tls_data_l-gdts) @@ -116,8 +116,8 @@ pci_data_sel equ (pci_data_32-gdts) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; use16 - org 0x0 - jmp start_of_code + org 0x0 + jmp start_of_code version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0 @@ -128,10 +128,10 @@ if lang eq en include "boot/booteng.inc" ; english system boot messages else if lang eq ru include "boot/bootru.inc" ; russian system boot messages -include "boot/ru.inc" ; Russian font +include "boot/ru.inc" ; Russian font else if lang eq et include "boot/bootet.inc" ; estonian system boot messages -include "boot/et.inc" ; Estonian font +include "boot/et.inc" ; Estonian font else include "boot/bootge.inc" ; german system boot messages end if @@ -149,58 +149,58 @@ include "detect/biosdisk.inc" ; CR0 Flags - Protected mode and Paging - mov ecx, CR0_PE + mov ecx, CR0_PE ; Enabling 32 bit protected mode - sidt [cs:old_ints_h] + sidt [cs:old_ints_h] - cli ; disable all irqs - cld - mov al,255 ; mask all irqs - out 0xa1,al - out 0x21,al - l.5: in al, 0x64 ; Enable A20 - test al, 2 - jnz l.5 - mov al, 0xD1 - out 0x64, al - l.6: in al, 0x64 - test al, 2 - jnz l.6 - mov al, 0xDF - out 0x60, al - l.7: in al, 0x64 - test al, 2 - jnz l.7 - mov al, 0xFF - out 0x64, al + cli ; disable all irqs + cld + mov al,255 ; mask all irqs + out 0xa1,al + out 0x21,al + l.5: in al, 0x64 ; Enable A20 + test al, 2 + jnz l.5 + mov al, 0xD1 + out 0x64, al + l.6: in al, 0x64 + test al, 2 + jnz l.6 + mov al, 0xDF + out 0x60, al + l.7: in al, 0x64 + test al, 2 + jnz l.7 + mov al, 0xFF + out 0x64, al - lgdt [cs:tmp_gdt] ; Load GDT - mov eax, cr0 ; protected mode - or eax, ecx - and eax, 10011111b *65536*256 + 0xffffff ; caching enabled - mov cr0, eax - jmp pword os_code:B32 ; jmp to enable 32 bit mode + lgdt [cs:tmp_gdt] ; Load GDT + mov eax, cr0 ; protected mode + or eax, ecx + and eax, 10011111b *65536*256 + 0xffffff ; caching enabled + mov cr0, eax + jmp pword os_code:B32 ; jmp to enable 32 bit mode align 8 tmp_gdt: - dw 23 - dd tmp_gdt+0x10000 - dw 0 + dw 23 + dd tmp_gdt+0x10000 + dw 0 - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10011010b - db 0x00 + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 - dw 0xffff - dw 0x0000 - db 0x00 - dw 11011111b *256 +10010010b - db 0x00 + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 include "data16.inc" @@ -209,65 +209,65 @@ org $+0x10000 align 4 B32: - mov ax,os_stack ; Selector for os - mov ds,ax - mov es,ax - mov fs,ax - mov gs,ax - mov ss,ax - mov esp,0x3ec00 ; Set stack + mov ax,os_stack ; Selector for os + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + mov esp,0x3ec00 ; Set stack ; CLEAR 0x280000 - HEAP_BASE - xor eax,eax - mov edi,0x280000 - mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 - cld - rep stosd + xor eax,eax + mov edi,0x280000 + mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 + cld + rep stosd - mov edi,0x40000 - mov ecx,(0x90000-0x40000)/4 - rep stosd + mov edi,0x40000 + mov ecx,(0x90000-0x40000)/4 + rep stosd ; CLEAR KERNEL UNDEFINED GLOBALS - mov edi, endofcode-OS_BASE - mov ecx, (uglobals_size/4)+4 - rep stosd + mov edi, endofcode-OS_BASE + mov ecx, (uglobals_size/4)+4 + rep stosd ; SAVE & CLEAR 0-0xffff - xor esi, esi - mov edi,0x2F0000 - mov ecx,0x10000 / 4 - rep movsd - mov edi,0x1000 - mov ecx,0xf000 / 4 - rep stosd + xor esi, esi + mov edi,0x2F0000 + mov ecx,0x10000 / 4 + rep movsd + mov edi,0x1000 + mov ecx,0xf000 / 4 + rep stosd - call test_cpu - bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc + call test_cpu + bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc - call init_BIOS32 + call init_BIOS32 ; MEMORY MODEL - call mem_test - call init_mem - call init_page_map + call mem_test + call init_mem + call init_page_map ; ENABLE PAGING - mov eax, sys_pgdir-OS_BASE - mov cr3, eax + mov eax, sys_pgdir-OS_BASE + mov cr3, eax - mov eax,cr0 - or eax,CR0_PG+CR0_WP - mov cr0,eax + mov eax,cr0 + or eax,CR0_PG+CR0_WP + mov cr0,eax - lgdt [gdts] - jmp pword os_code:high_code + lgdt [gdts] + jmp pword os_code:high_code align 4 -bios32_entry dd ? -tmp_page_tabs dd ? +bios32_entry dd ? +tmp_page_tabs dd ? use16 org $-0x10000 @@ -283,45 +283,45 @@ org OS_BASE+$ align 4 high_code: - mov ax, os_stack - mov bx, app_data - mov cx, app_tls - mov ss, ax - add esp, OS_BASE + mov ax, os_stack + mov bx, app_data + mov cx, app_tls + mov ss, ax + add esp, OS_BASE - mov ds, bx - mov es, bx - mov fs, cx - mov gs, bx + mov ds, bx + mov es, bx + mov fs, cx + mov gs, bx - bt [cpu_caps], CAPS_PGE - jnc @F + bt [cpu_caps], CAPS_PGE + jnc @F - or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL + or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL - mov ebx, cr4 - or ebx, CR4_PGE - mov cr4, ebx + mov ebx, cr4 + or ebx, CR4_PGE + mov cr4, ebx @@: - xor eax, eax - mov dword [sys_pgdir], eax - mov dword [sys_pgdir+4], eax + xor eax, eax + mov dword [sys_pgdir], eax + mov dword [sys_pgdir+4], eax - mov eax, cr3 - mov cr3, eax ; flush TLB + mov eax, cr3 + mov cr3, eax ; flush TLB ; SAVE REAL MODE VARIABLES - mov ax, [BOOT_VAR + 0x9031] - mov [IDEContrRegsBaseAddr], ax + mov ax, [BOOT_VAR + 0x9031] + mov [IDEContrRegsBaseAddr], ax ; --------------- APM --------------------- ; init selectors mov ebx,[BOOT_VAR+0x9040] ; offset of APM entry point - movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of + movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of ; protected-mode 32-bit code segment - movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of + movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of ; protected-mode 16-bit code segment - movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of + movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of ; protected-mode 16-bit data segment shl eax, 4 @@ -345,267 +345,267 @@ high_code: mov eax, [BOOT_VAR + 0x9044] ; version & flags mov [apm_vf], eax ; ----------------------------------------- -; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port +; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port ; mov [0xF604],byte 1 ;al - mov al, [BOOT_VAR+0x901F] ; DMA access - mov [allow_dma_access], al - movzx eax, byte [BOOT_VAR+0x9000] ; bpp - mov [ScreenBPP],al + mov al, [BOOT_VAR+0x901F] ; DMA access + mov [allow_dma_access], al + movzx eax, byte [BOOT_VAR+0x9000] ; bpp + mov [ScreenBPP],al - mov [_display.bpp], eax - mov [_display.vrefresh], 60 - mov [_display.disable_mouse], __sys_disable_mouse + mov [_display.bpp], eax + mov [_display.vrefresh], 60 + mov [_display.disable_mouse], __sys_disable_mouse - movzx eax,word [BOOT_VAR+0x900A] ; X max - mov [_display.width], eax - dec eax - mov [Screen_Max_X],eax - mov [screen_workarea.right],eax - movzx eax,word [BOOT_VAR+0x900C] ; Y max - mov [_display.height], eax - dec eax - mov [Screen_Max_Y],eax - mov [screen_workarea.bottom],eax - movzx eax,word [BOOT_VAR+0x9008] ; screen mode - mov [SCR_MODE],eax - mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add - mov [BANK_SWITCH],eax - mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine - cmp [SCR_MODE],word 0x13 ; 320x200 - je @f - cmp [SCR_MODE],word 0x12 ; VGA 640x480 - je @f - movzx eax, word[BOOT_VAR+0x9001] ; for other modes - mov [BytesPerScanLine],ax - mov [_display.pitch], eax + movzx eax,word [BOOT_VAR+0x900A] ; X max + mov [_display.width], eax + dec eax + mov [Screen_Max_X],eax + mov [screen_workarea.right],eax + movzx eax,word [BOOT_VAR+0x900C] ; Y max + mov [_display.height], eax + dec eax + mov [Screen_Max_Y],eax + mov [screen_workarea.bottom],eax + movzx eax,word [BOOT_VAR+0x9008] ; screen mode + mov [SCR_MODE],eax + mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add + mov [BANK_SWITCH],eax + mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine + cmp [SCR_MODE],word 0x13 ; 320x200 + je @f + cmp [SCR_MODE],word 0x12 ; VGA 640x480 + je @f + movzx eax, word[BOOT_VAR+0x9001] ; for other modes + mov [BytesPerScanLine],ax + mov [_display.pitch], eax @@: - mov eax, [_display.width] - mul [_display.height] - mov [_WinMapSize], eax + mov eax, [_display.width] + mul [_display.height] + mov [_WinMapSize], eax - mov esi, BOOT_VAR+0x9080 - movzx ecx, byte [esi-1] - mov [NumBiosDisks], ecx - mov edi, BiosDisksData - rep movsd + mov esi, BOOT_VAR+0x9080 + movzx ecx, byte [esi-1] + mov [NumBiosDisks], ecx + mov edi, BiosDisksData + rep movsd ; GRAPHICS ADDRESSES - and byte [BOOT_VAR+0x901e],0x0 - mov eax,[BOOT_VAR+0x9018] - mov [LFBAddress],eax + and byte [BOOT_VAR+0x901e],0x0 + mov eax,[BOOT_VAR+0x9018] + mov [LFBAddress],eax - cmp [SCR_MODE],word 0100000000000000b - jge setvesa20 - cmp [SCR_MODE],word 0x13 - je v20ga32 - mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 - mov [GETPIXEL],dword Vesa12_getpixel24 - cmp [ScreenBPP],byte 24 - jz ga24 - mov [PUTPIXEL],dword Vesa12_putpixel32 - mov [GETPIXEL],dword Vesa12_getpixel32 + cmp [SCR_MODE],word 0100000000000000b + jge setvesa20 + cmp [SCR_MODE],word 0x13 + je v20ga32 + mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 + mov [GETPIXEL],dword Vesa12_getpixel24 + cmp [ScreenBPP],byte 24 + jz ga24 + mov [PUTPIXEL],dword Vesa12_putpixel32 + mov [GETPIXEL],dword Vesa12_getpixel32 ga24: - jmp v20ga24 + jmp v20ga24 setvesa20: - mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 - mov [GETPIXEL],dword Vesa20_getpixel24 - cmp [ScreenBPP],byte 24 - jz v20ga24 + mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 + mov [GETPIXEL],dword Vesa20_getpixel24 + cmp [ScreenBPP],byte 24 + jz v20ga24 v20ga32: - mov [PUTPIXEL],dword Vesa20_putpixel32 - mov [GETPIXEL],dword Vesa20_getpixel32 + mov [PUTPIXEL],dword Vesa20_putpixel32 + mov [GETPIXEL],dword Vesa20_getpixel32 v20ga24: - cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 - jne no_mode_0x12 - mov [PUTPIXEL],dword VGA_putpixel - mov [GETPIXEL],dword Vesa20_getpixel32 + cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 + jne no_mode_0x12 + mov [PUTPIXEL],dword VGA_putpixel + mov [GETPIXEL],dword Vesa20_getpixel32 no_mode_0x12: ; -------- Fast System Call init ---------- ; Intel SYSENTER/SYSEXIT (AMD CPU support it too) - bt [cpu_caps], CAPS_SEP - jnc .SEnP ; SysEnter not Present - xor edx, edx - mov ecx, MSR_SYSENTER_CS - mov eax, os_code - wrmsr - mov ecx, MSR_SYSENTER_ESP + bt [cpu_caps], CAPS_SEP + jnc .SEnP ; SysEnter not Present + xor edx, edx + mov ecx, MSR_SYSENTER_CS + mov eax, os_code + wrmsr + mov ecx, MSR_SYSENTER_ESP ; mov eax, sysenter_stack ; Check it - xor eax, eax - wrmsr - mov ecx, MSR_SYSENTER_EIP - mov eax, sysenter_entry - wrmsr + xor eax, eax + wrmsr + mov ecx, MSR_SYSENTER_EIP + mov eax, sysenter_entry + wrmsr .SEnP: ; AMD SYSCALL/SYSRET - cmp byte[cpu_vendor], 'A' - jne .noSYSCALL - mov eax, 0x80000001 - cpuid - test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support - jz .noSYSCALL - mov ecx, MSR_AMD_EFER - rdmsr - or eax, 1 ; bit_0 - System Call Extension (SCE) - wrmsr + cmp byte[cpu_vendor], 'A' + jne .noSYSCALL + mov eax, 0x80000001 + cpuid + test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support + jz .noSYSCALL + mov ecx, MSR_AMD_EFER + rdmsr + or eax, 1 ; bit_0 - System Call Extension (SCE) + wrmsr - ; !!!! It`s dirty hack, fix it !!! - ; Bits of EDX : - ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register - ; and the contents of this field, plus 8, are copied into the SS register. - ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register - ; and the contents of this field, plus 8, are copied into the SS register. + ; !!!! It`s dirty hack, fix it !!! + ; Bits of EDX : + ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. - ; mov edx, (os_code + 16) * 65536 + os_code - mov edx, 0x1B0008 + ; mov edx, (os_code + 16) * 65536 + os_code + mov edx, 0x1B0008 - mov eax, syscall_entry - mov ecx, MSR_AMD_STAR - wrmsr + mov eax, syscall_entry + mov ecx, MSR_AMD_STAR + wrmsr .noSYSCALL: ; ----------------------------------------- - stdcall alloc_page - stdcall map_page, tss-0xF80, eax, PG_SW - stdcall alloc_page - inc eax - mov [SLOT_BASE+256+APPDATA.io_map], eax - stdcall map_page, tss+0x80, eax, PG_SW - stdcall alloc_page - inc eax - mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax - stdcall map_page, tss+0x1080, eax, PG_SW + stdcall alloc_page + stdcall map_page, tss-0xF80, eax, PG_SW + stdcall alloc_page + inc eax + mov [SLOT_BASE+256+APPDATA.io_map], eax + stdcall map_page, tss+0x80, eax, PG_SW + stdcall alloc_page + inc eax + mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax + stdcall map_page, tss+0x1080, eax, PG_SW ; LOAD IDT - call build_interrupt_table ;lidt is executed - ;lidt [idtreg] + call build_interrupt_table ;lidt is executed + ;lidt [idtreg] - call init_kernel_heap - stdcall kernel_alloc, RING0_STACK_SIZE+512 - mov [os_stack_seg], eax + call init_kernel_heap + stdcall kernel_alloc, RING0_STACK_SIZE+512 + mov [os_stack_seg], eax - lea esp, [eax+RING0_STACK_SIZE] + lea esp, [eax+RING0_STACK_SIZE] - mov [tss._ss0], os_stack - mov [tss._esp0], esp - mov [tss._esp], esp - mov [tss._cs],os_code - mov [tss._ss],os_stack - mov [tss._ds],app_data - mov [tss._es],app_data - mov [tss._fs],app_data - mov [tss._gs],app_data - mov [tss._io],128 + mov [tss._ss0], os_stack + mov [tss._esp0], esp + mov [tss._esp], esp + mov [tss._cs],os_code + mov [tss._ss],os_stack + mov [tss._ds],app_data + mov [tss._es],app_data + mov [tss._fs],app_data + mov [tss._gs],app_data + mov [tss._io],128 ;Add IO access table - bit array of permitted ports - mov edi, tss._io_map_0 - xor eax, eax - not eax - mov ecx, 8192/4 - rep stosd ; access to 4096*8=65536 ports + mov edi, tss._io_map_0 + xor eax, eax + not eax + mov ecx, 8192/4 + rep stosd ; access to 4096*8=65536 ports - mov ax,tss0 - ltr ax + mov ax,tss0 + ltr ax - mov [LFBSize], 0x800000 - call init_LFB - call init_fpu - call init_malloc + mov [LFBSize], 0x800000 + call init_LFB + call init_fpu + call init_malloc - stdcall alloc_kernel_space, 0x51000 - mov [default_io_map], eax + stdcall alloc_kernel_space, 0x51000 + mov [default_io_map], eax - add eax, 0x2000 - mov [ipc_tmp], eax - mov ebx, 0x1000 + add eax, 0x2000 + mov [ipc_tmp], eax + mov ebx, 0x1000 - add eax, 0x40000 - mov [proc_mem_map], eax + add eax, 0x40000 + mov [proc_mem_map], eax - add eax, 0x8000 - mov [proc_mem_pdir], eax + add eax, 0x8000 + mov [proc_mem_pdir], eax - add eax, ebx - mov [proc_mem_tab], eax + add eax, ebx + mov [proc_mem_tab], eax - add eax, ebx - mov [tmp_task_pdir], eax + add eax, ebx + mov [tmp_task_pdir], eax - add eax, ebx - mov [tmp_task_ptab], eax + add eax, ebx + mov [tmp_task_ptab], eax - add eax, ebx - mov [ipc_pdir], eax + add eax, ebx + mov [ipc_pdir], eax - add eax, ebx - mov [ipc_ptab], eax + add eax, ebx + mov [ipc_ptab], eax - stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \ - (unpack.lc+unpack.lp)))*4 + stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \ + (unpack.lc+unpack.lp)))*4 - mov [unpack.p], eax + mov [unpack.p], eax - call init_events - mov eax, srv.fd-SRV_FD_OFFSET - mov [srv.fd], eax - mov [srv.bk], eax + call init_events + mov eax, srv.fd-SRV_FD_OFFSET + mov [srv.fd], eax + mov [srv.bk], eax - mov edi, irq_tab - xor eax, eax - mov ecx, 16 - rep stosd + mov edi, irq_tab + xor eax, eax + mov ecx, 16 + rep stosd ;Set base of graphic segment to linear address of LFB - mov eax,[LFBAddress] ; set for gs - mov [graph_data_l+2],ax - shr eax,16 - mov [graph_data_l+4],al - mov [graph_data_l+7],ah + mov eax,[LFBAddress] ; set for gs + mov [graph_data_l+2],ax + shr eax,16 + mov [graph_data_l+4],al + mov [graph_data_l+7],ah - stdcall kernel_alloc, [_WinMapSize] - mov [_WinMapAddress], eax + stdcall kernel_alloc, [_WinMapSize] + mov [_WinMapAddress], eax - xor eax,eax - inc eax - mov [CURRENT_TASK],eax ;dword 1 - mov [TASK_COUNT],eax ;dword 1 - mov [TASK_BASE],dword TASK_DATA - mov [current_slot], SLOT_BASE+256 + xor eax,eax + inc eax + mov [CURRENT_TASK],eax ;dword 1 + mov [TASK_COUNT],eax ;dword 1 + mov [TASK_BASE],dword TASK_DATA + mov [current_slot], SLOT_BASE+256 ; set background - mov [BgrDrawMode],eax - mov [BgrDataWidth],eax - mov [BgrDataHeight],eax - mov [mem_BACKGROUND], 4 - mov [img_background], static_background_data + mov [BgrDrawMode],eax + mov [BgrDataWidth],eax + mov [BgrDataHeight],eax + mov [mem_BACKGROUND], 4 + mov [img_background], static_background_data - mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE + mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f - call rerouteirqs + call rerouteirqs ; Initialize system V86 machine - call init_sys_v86 + call init_sys_v86 ; TIMER SET TO 1/100 S - mov al,0x34 ; set to 100Hz - out 0x43,al - mov al,0x9b ; lsb 1193180 / 1193 - out 0x40,al - mov al,0x2e ; msb - out 0x40,al + mov al,0x34 ; set to 100Hz + out 0x43,al + mov al,0x9b ; lsb 1193180 / 1193 + out 0x40,al + mov al,0x2e ; msb + out 0x40,al ; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) ; they are used: when partitions are scanned, hd_read relies on timer ; Also enable IRQ2, because in some configurations ; IRQs from slave controller are not delivered until IRQ2 on master is enabled - mov al, 0xFA - out 0x21, al - mov al, 0x3F - out 0xA1, al + mov al, 0xFA + out 0x21, al + mov al, 0x3F + out 0xA1, al ;!!!!!!!!!!!!!!!!!!!!!!!!!! include 'detect/disks.inc' @@ -621,7 +621,7 @@ include 'boot/rdload.inc' ; mov [dma_hdd],1 ; CALCULATE FAT CHAIN FOR RAMDISK - call calculatefatchain + call calculatefatchain ; LOAD VMODE DRIVER @@ -631,258 +631,258 @@ include 'vmodeld.inc' if 0 mov ax,[OS_BASE+0x10000+bx_from_load] - cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} + cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} je no_lib_load ; LOADING LIBRARES - stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files) - call load_file_parse_table ; prepare file parse table - call set_kernel_conf ; configure devices and gui + stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files) + call load_file_parse_table ; prepare file parse table + call set_kernel_conf ; configure devices and gui no_lib_load: end if ; LOAD FONTS I and II - stdcall read_file, char, FONT_I, 0, 2304 - stdcall read_file, char2, FONT_II, 0, 2560 + stdcall read_file, char, FONT_I, 0, 2304 + stdcall read_file, char2, FONT_II, 0, 2560 - mov esi,boot_fonts - call boot_log + mov esi,boot_fonts + call boot_log ; PRINT AMOUNT OF MEMORY - mov esi, boot_memdetect - call boot_log + mov esi, boot_memdetect + call boot_log - movzx ecx, word [boot_y] - or ecx, (10+29*6) shl 16 ; "Determining amount of memory" - sub ecx, 10 - mov edx, 0xFFFFFF - mov ebx, [MEM_AMOUNT] - shr ebx, 20 - xor edi,edi - mov eax, 0x00040000 + movzx ecx, word [boot_y] + or ecx, (10+29*6) shl 16 ; "Determining amount of memory" + sub ecx, 10 + mov edx, 0xFFFFFF + mov ebx, [MEM_AMOUNT] + shr ebx, 20 + xor edi,edi + mov eax, 0x00040000 inc edi - call display_number_force + call display_number_force ; BUILD SCHEDULER - call build_scheduler ; sys32.inc + call build_scheduler ; sys32.inc - mov esi,boot_devices - call boot_log + mov esi,boot_devices + call boot_log - mov [pci_access_enabled],1 + mov [pci_access_enabled],1 ; SET PRELIMINARY WINDOW STACK AND POSITIONS - mov esi,boot_windefs - call boot_log - call set_window_defaults + mov esi,boot_windefs + call boot_log + call set_window_defaults ; SET BACKGROUND DEFAULTS - mov esi,boot_bgr - call boot_log - call init_background - call calculatebackground + mov esi,boot_bgr + call boot_log + call init_background + call calculatebackground ; RESERVE SYSTEM IRQ'S JA PORT'S - mov esi,boot_resirqports - call boot_log - call reserve_irqs_ports + mov esi,boot_resirqports + call boot_log + call reserve_irqs_ports ; SET PORTS FOR IRQ HANDLERS - mov esi,boot_setrports - call boot_log - ;call setirqreadports + mov esi,boot_setrports + call boot_log + ;call setirqreadports ; SET UP OS TASK - mov esi,boot_setostask - call boot_log + mov esi,boot_setostask + call boot_log - xor eax, eax - mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data - mov dword [SLOT_BASE+APPDATA.exc_handler], eax - mov dword [SLOT_BASE+APPDATA.except_mask], eax + xor eax, eax + mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data + mov dword [SLOT_BASE+APPDATA.exc_handler], eax + mov dword [SLOT_BASE+APPDATA.except_mask], eax - ; name for OS/IDLE process + ; name for OS/IDLE process - mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' - mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' - mov edi, [os_stack_seg] - mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi - add edi, 0x2000-512 - mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi - mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case + mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' + mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' + mov edi, [os_stack_seg] + mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi + add edi, 0x2000-512 + mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi + mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case ; [SLOT_BASE+256+APPDATA.io_map] was set earlier - mov esi, fpu_data - mov ecx, 512/4 - cld - rep movsd + mov esi, fpu_data + mov ecx, 512/4 + cld + rep movsd - mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax - mov dword [SLOT_BASE+256+APPDATA.except_mask], eax + mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax + mov dword [SLOT_BASE+256+APPDATA.except_mask], eax - mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET - mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx - mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx + mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET + mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx + mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx - mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path - mov dword [SLOT_BASE+256+APPDATA.tls_base], eax + mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path + mov dword [SLOT_BASE+256+APPDATA.tls_base], eax - ; task list - mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address + ; task list + mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address inc eax - mov dword [CURRENT_TASK],eax - mov dword [TASK_COUNT],eax - mov [current_slot], SLOT_BASE+256 - mov [TASK_BASE],dword TASK_DATA - mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number - mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number + mov dword [CURRENT_TASK],eax + mov dword [TASK_COUNT],eax + mov [current_slot], SLOT_BASE+256 + mov [TASK_BASE],dword TASK_DATA + mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number + mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number - call init_display - mov eax, [def_cursor] - mov [SLOT_BASE+APPDATA.cursor],eax - mov [SLOT_BASE+APPDATA.cursor+256],eax + call init_display + mov eax, [def_cursor] + mov [SLOT_BASE+APPDATA.cursor],eax + mov [SLOT_BASE+APPDATA.cursor+256],eax ; READ TSC / SECOND - mov esi,boot_tsc - call boot_log - cli - rdtsc ;call _rdtsc - mov ecx,eax - mov esi,250 ; wait 1/4 a second - call delay_ms - rdtsc ;call _rdtsc - sti - sub eax,ecx - shl eax,2 - mov [CPU_FREQ],eax ; save tsc / sec + mov esi,boot_tsc + call boot_log + cli + rdtsc ;call _rdtsc + mov ecx,eax + mov esi,250 ; wait 1/4 a second + call delay_ms + rdtsc ;call _rdtsc + sti + sub eax,ecx + shl eax,2 + mov [CPU_FREQ],eax ; save tsc / sec ; mov ebx, 1000000 ; div ebx ; ў®®ЎйҐ-в® Їа®Ё§ў®¤ЁвҐ«м­®бвм ў ¤ ­­®¬ Є®­ЄаҐв­®¬ ¬Ґб⥠; б®ўҐа襭­® ­ҐЄаЁвЁз­ , ­® зв®Ўл § вЄ­гвм «оЎЁвҐ«Ґ© ; ®ЇвЁ¬Ё§ЁагойЁе Є®¬ЇЁ«пв®а®ў џ‚“... - mov edx, 2251799814 - mul edx - shr edx, 19 - mov [stall_mcs], edx + mov edx, 2251799814 + mul edx + shr edx, 19 + mov [stall_mcs], edx ; PRINT CPU FREQUENCY - mov esi, boot_cpufreq - call boot_log + mov esi, boot_cpufreq + call boot_log - mov ebx, edx - movzx ecx, word [boot_y] - add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is ' - mov edx, 0xFFFFFF - xor edi,edi - mov eax, 0x00040000 + mov ebx, edx + movzx ecx, word [boot_y] + add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is ' + mov edx, 0xFFFFFF + xor edi,edi + mov eax, 0x00040000 inc edi - call display_number_force + call display_number_force ; SET VARIABLES - call set_variables + call set_variables ; SET MOUSE - ;call detect_devices - stdcall load_driver, szPS2MDriver + ;call detect_devices + stdcall load_driver, szPS2MDriver ; stdcall load_driver, szCOM_MDriver - mov esi,boot_setmouse - call boot_log - call setmouse + mov esi,boot_setmouse + call boot_log + call setmouse ; STACK AND FDC - call stack_init - call fdc_init + call stack_init + call fdc_init ; PALETTE FOR 320x200 and 640x480 16 col - cmp [SCR_MODE],word 0x12 - jne no_pal_vga - mov esi,boot_pal_vga - call boot_log - call paletteVGA + cmp [SCR_MODE],word 0x12 + jne no_pal_vga + mov esi,boot_pal_vga + call boot_log + call paletteVGA no_pal_vga: - cmp [SCR_MODE],word 0x13 - jne no_pal_ega - mov esi,boot_pal_ega - call boot_log - call palette320x200 + cmp [SCR_MODE],word 0x13 + jne no_pal_ega + mov esi,boot_pal_ega + call boot_log + call palette320x200 no_pal_ega: ; LOAD DEFAULT SKIN - call load_default_skin + call load_default_skin ;protect io permission map - mov esi, [default_io_map] - stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP - add esi, 0x1000 - stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP + mov esi, [default_io_map] + stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP + add esi, 0x1000 + stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP - stdcall map_page,tss._io_map_0,\ - [SLOT_BASE+256+APPDATA.io_map], PG_MAP - stdcall map_page,tss._io_map_1,\ - [SLOT_BASE+256+APPDATA.io_map+4], PG_MAP + stdcall map_page,tss._io_map_0,\ + [SLOT_BASE+256+APPDATA.io_map], PG_MAP + stdcall map_page,tss._io_map_1,\ + [SLOT_BASE+256+APPDATA.io_map+4], PG_MAP ; LOAD FIRST APPLICATION - cli + cli - cmp byte [BOOT_VAR+0x9030],1 - jne no_load_vrr_m + cmp byte [BOOT_VAR+0x9030],1 + jne no_load_vrr_m - mov ebp, vrr_m - call fs_execute_from_sysdir + mov ebp, vrr_m + call fs_execute_from_sysdir ; cmp eax,2 ; if vrr_m app found (PID=2) sub eax,2 - jz first_app_found + jz first_app_found no_load_vrr_m: - mov ebp, firstapp - call fs_execute_from_sysdir + mov ebp, firstapp + call fs_execute_from_sysdir ; cmp eax,2 ; continue if a process has been loaded sub eax,2 - jz first_app_found + jz first_app_found - mov esi, boot_failed - call boot_log + mov esi, boot_failed + call boot_log - mov eax, 0xDEADBEEF ; otherwise halt - hlt + mov eax, 0xDEADBEEF ; otherwise halt + hlt first_app_found: - cli + cli - ;mov [TASK_COUNT],dword 2 + ;mov [TASK_COUNT],dword 2 push 1 - pop dword [CURRENT_TASK] ; set OS task fisrt + pop dword [CURRENT_TASK] ; set OS task fisrt ; SET KEYBOARD PARAMETERS - mov al, 0xf6 ; reset keyboard, scan enabled - call kb_write + mov al, 0xf6 ; reset keyboard, scan enabled + call kb_write - ; wait until 8042 is ready - xor ecx,ecx + ; wait until 8042 is ready + xor ecx,ecx @@: - in al,64h - and al,00000010b - loopnz @b + in al,64h + and al,00000010b + loopnz @b ; mov al, 0xED ; svetodiody - only for testing! ; call kb_write @@ -891,14 +891,14 @@ first_app_found: ; call kb_write ; call kb_read - mov al, 0xF3 ; set repeat rate & delay - call kb_write + mov al, 0xF3 ; set repeat rate & delay + call kb_write ; call kb_read - mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 - call kb_write + mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 + call kb_write ; call kb_read ;// mike.dld [ - call set_lights + call set_lights ;// mike.dld ] @@ -906,39 +906,39 @@ first_app_found: if defined debug_com_base - ; enable Divisor latch + ; enable Divisor latch - mov dx, debug_com_base+3 - mov al, 1 shl 7 - out dx, al + mov dx, debug_com_base+3 + mov al, 1 shl 7 + out dx, al - ; Set speed to 115200 baud (max speed) + ; Set speed to 115200 baud (max speed) - mov dx, debug_com_base - mov al, 0x01 - out dx, al + mov dx, debug_com_base + mov al, 0x01 + out dx, al - mov dx, debug_com_base+1 - mov al, 0x00 - out dx, al + mov dx, debug_com_base+1 + mov al, 0x00 + out dx, al - ; No parity, 8bits words, one stop bit, dlab bit back to 0 + ; No parity, 8bits words, one stop bit, dlab bit back to 0 - mov dx, debug_com_base+3 - mov al, 3 - out dx, al + mov dx, debug_com_base+3 + mov al, 3 + out dx, al - ; disable interrupts + ; disable interrupts - mov dx, debug_com_base+1 - mov al, 0 - out dx, al + mov dx, debug_com_base+1 + mov al, 0 + out dx, al - ; clear + enable fifo (64 bits) + ; clear + enable fifo (64 bits) - mov dx, debug_com_base+2 - mov al, 0x7 + 1 shl 5 - out dx, al + mov dx, debug_com_base+2 + mov al, 0x7 + 1 shl 5 + out dx, al end if @@ -946,73 +946,73 @@ end if ; START MULTITASKING if preboot_blogesc - mov esi, boot_tasking - call boot_log -.bll1: in al, 0x60 ; wait for ESC key press - cmp al, 129 - jne .bll1 + mov esi, boot_tasking + call boot_log +.bll1: in al, 0x60 ; wait for ESC key press + cmp al, 129 + jne .bll1 end if ; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled ; UNMASK ALL IRQ'S - mov esi,boot_allirqs - call boot_log + mov esi,boot_allirqs + call boot_log - cli ;guarantee forbidance of interrupts. - mov al,0 ; unmask all irq's - out 0xA1,al - out 0x21,al + cli ;guarantee forbidance of interrupts. + mov al,0 ; unmask all irq's + out 0xA1,al + out 0x21,al - mov ecx,32 + mov ecx,32 ready_for_irqs: - mov al,0x20 ; ready for irqs - out 0x20,al - out 0xa0,al + mov al,0x20 ; ready for irqs + out 0x20,al + out 0xa0,al - loop ready_for_irqs ; flush the queue + loop ready_for_irqs ; flush the queue - stdcall attach_int_handler, dword 1, irq1, dword 0 + stdcall attach_int_handler, dword 1, irq1, dword 0 ; mov [dma_hdd],1 - cmp [IDEContrRegsBaseAddr], 0 - setnz [dma_hdd] - mov [timer_ticks_enable],1 ; for cd driver + cmp [IDEContrRegsBaseAddr], 0 + setnz [dma_hdd] + mov [timer_ticks_enable],1 ; for cd driver - sti - call change_task + sti + call change_task - jmp osloop + jmp osloop ; jmp $ ; wait here for timer to take control - ; Fly :) + ; Fly :) include 'unpacker.inc' include 'fdo.inc' align 4 boot_log: - pushad + pushad - mov ebx,10*65536 - mov bx,word [boot_y] - add [boot_y],dword 10 - mov ecx,0x80ffffff ; ASCIIZ string with white color + mov ebx,10*65536 + mov bx,word [boot_y] + add [boot_y],dword 10 + mov ecx,0x80ffffff ; ASCIIZ string with white color xor edi,edi - mov edx,esi + mov edx,esi inc edi - call dtext + call dtext - mov [novesachecksum],1000 - call checkVga_N13 + mov [novesachecksum],1000 + call checkVga_N13 - popad + popad - ret + ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; @@ -1021,17 +1021,17 @@ boot_log: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 32 osloop: - call [draw_pointer] - call check_buttons - call checkwindows + call [draw_pointer] + call check_buttons + call checkwindows ; call check_window_move_request - call checkmisc - call checkVga_N13 - call stack_handler - call checkidle - call check_fdd_motor_status - call check_ATAPI_device_event - jmp osloop + call checkmisc + call checkVga_N13 + call stack_handler + call checkidle + call check_fdd_motor_status + call check_ATAPI_device_event + jmp osloop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; MAIN OS LOOP END ; @@ -1039,33 +1039,33 @@ osloop: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 4 checkidle: - pushad - call change_task - jmp idle_loop_entry + pushad + call change_task + jmp idle_loop_entry idle_loop: - cmp eax,[idlemem] ; eax == [timer_ticks] - jne idle_exit - rdtsc ;call _rdtsc - mov ecx,eax - hlt - rdtsc ;call _rdtsc - sub eax,ecx - add [idleuse],eax + cmp eax,[idlemem] ; eax == [timer_ticks] + jne idle_exit + rdtsc ;call _rdtsc + mov ecx,eax + hlt + rdtsc ;call _rdtsc + sub eax,ecx + add [idleuse],eax idle_loop_entry: - mov eax,[timer_ticks] ; eax = [timer_ticks] - cmp [check_idle_semaphore],0 - je idle_loop - dec [check_idle_semaphore] + mov eax,[timer_ticks] ; eax = [timer_ticks] + cmp [check_idle_semaphore],0 + je idle_loop + dec [check_idle_semaphore] idle_exit: - mov [idlemem],eax ; eax == [timer_ticks] - popad - ret + mov [idlemem],eax ; eax == [timer_ticks] + popad + ret uglobal - idlemem dd 0x0 - idleuse dd 0x0 - idleusesec dd 0x0 - check_idle_semaphore dd 0x0 + idlemem dd 0x0 + idleuse dd 0x0 + idleusesec dd 0x0 + check_idle_semaphore dd 0x0 endg @@ -1088,58 +1088,58 @@ include "kernel32.inc" reserve_irqs_ports: - push eax - xor eax,eax + push eax + xor eax,eax inc eax - mov byte [irq_owner+4*0],al ;1 ; timer - ;mov [irq_owner+4*1], 1 ; keyboard - mov byte [irq_owner+4*6],al ;1 ; floppy diskette - mov byte [irq_owner+4*13],al ;1 ; math co-pros - mov byte [irq_owner+4*14],al ;1 ; ide I - mov byte [irq_owner+4*15],al ;1 ; ide II - pop eax + mov byte [irq_owner+4*0],al ;1 ; timer + ;mov [irq_owner+4*1], 1 ; keyboard + mov byte [irq_owner+4*6],al ;1 ; floppy diskette + mov byte [irq_owner+4*13],al ;1 ; math co-pros + mov byte [irq_owner+4*14],al ;1 ; ide I + mov byte [irq_owner+4*15],al ;1 ; ide II + pop eax ; RESERVE PORTS push 4 - pop dword [RESERVED_PORTS] ;,edi + pop dword [RESERVED_PORTS] ;,edi push 1 - pop dword [RESERVED_PORTS+16+0] ;,dword 1 - and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0 - mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d + pop dword [RESERVED_PORTS+16+0] ;,dword 1 + and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0 + mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d push 1 - pop dword [RESERVED_PORTS+32+0] ;,dword 1 - push 0x30 - pop dword [RESERVED_PORTS+32+4] ;,dword 0x30 + pop dword [RESERVED_PORTS+32+0] ;,dword 1 + push 0x30 + pop dword [RESERVED_PORTS+32+4] ;,dword 0x30 push 0x4d - pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d + pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d push 1 - pop dword [RESERVED_PORTS+48+0] ;,dword 1 + pop dword [RESERVED_PORTS+48+0] ;,dword 1 push 0x50 - pop dword [RESERVED_PORTS+48+4] ;,dword 0x50 - mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf + pop dword [RESERVED_PORTS+48+4] ;,dword 0x50 + mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf push 1 - pop dword [RESERVED_PORTS+64+0] ;,dword 1 + pop dword [RESERVED_PORTS+64+0] ;,dword 1 - mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5 - mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff + mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5 + mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff - ret + ret setirqreadports: - mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte - and dword [irq12read+4],0 ; end of port list + mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte + and dword [irq12read+4],0 ; end of port list ; mov [irq12read+4],dword 0 ; end of port list - ;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte - ;mov [irq04read+4],dword 0 ; end of port list - ;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte - ;mov [irq03read+4],dword 0 ; end of port list + ;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte + ;mov [irq04read+4],dword 0 ; end of port list + ;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte + ;mov [irq03read+4],dword 0 ; end of port list - ret + ret iglobal process_number dd 0x1 @@ -1147,42 +1147,42 @@ endg set_variables: - mov ecx,0x100 ; flush port 0x60 -.fl60: in al,0x60 - loop .fl60 - push eax + mov ecx,0x100 ; flush port 0x60 +.fl60: in al,0x60 + loop .fl60 + push eax - mov ax,[BOOT_VAR+0x900c] - shr ax,1 - shl eax,16 - mov ax,[BOOT_VAR+0x900A] - shr ax,1 - mov [MOUSE_X],eax + mov ax,[BOOT_VAR+0x900c] + shr ax,1 + shl eax,16 + mov ax,[BOOT_VAR+0x900A] + shr ax,1 + mov [MOUSE_X],eax - xor eax,eax - mov [BTN_ADDR],dword BUTTON_INFO ; address of button list + xor eax,eax + mov [BTN_ADDR],dword BUTTON_INFO ; address of button list - mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer - mov byte [KEY_COUNT],al ; keyboard buffer - mov byte [BTN_COUNT],al ; button buffer + mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer + mov byte [KEY_COUNT],al ; keyboard buffer + mov byte [BTN_COUNT],al ; button buffer ; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y ;!! IP 04.02.2005: - mov byte [DONT_SWITCH],al ; change task if possible - pop eax - ret + mov byte [DONT_SWITCH],al ; change task if possible + pop eax + ret align 4 ;input eax=43,bl-byte of output, ecx - number of port sys_outport: - mov edi,ecx ; separate flag for read / write + mov edi,ecx ; separate flag for read / write and ecx,65535 mov eax,[RESERVED_PORTS] test eax,eax jnz .sopl8 - inc eax + inc eax mov [esp+32],eax ret @@ -1199,16 +1199,16 @@ sys_outport: cmp edx,[esi+0] jne .sopl2 cmp ecx,[esi+4] - jb .sopl2 + jb .sopl2 cmp ecx,[esi+8] - jg .sopl2 + jg .sopl2 .sopl3: test edi,0x80000000 ; read ? jnz .sopl4 mov eax,ebx - mov dx,cx ; write + mov dx,cx ; write out dx,al and [esp+32],dword 0 ret @@ -1224,8 +1224,8 @@ sys_outport: .sopl4: - mov dx,cx ; read - in al,dx + mov dx,cx ; read + in al,dx and eax,0xff and [esp+32],dword 0 mov [esp+20],eax @@ -1233,11 +1233,11 @@ sys_outport: display_number: ;It is not optimization - mov eax, ebx - mov ebx, ecx - mov ecx, edx - mov edx, esi - mov esi, edi + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi ; eax = print type, al=0 -> ebx is number ; al=1 -> ebx is pointer ; ah=0 -> display decimal @@ -1253,14 +1253,14 @@ display_number: display_number_force: push eax and eax,0x3fffffff - cmp eax,0xffff ; length > 0 ? + cmp eax,0xffff ; length > 0 ? pop eax jge cont_displ ret cont_displ: push eax and eax,0x3fffffff - cmp eax,61*0x10000 ; length <= 60 ? + cmp eax,61*0x10000 ; length <= 60 ? pop eax jb cont_displ2 ret @@ -1268,7 +1268,7 @@ display_number_force: pushad - cmp al,1 ; ecx is a pointer ? + cmp al,1 ; ecx is a pointer ? jne displnl1 mov ebp,ebx add ebp,4 @@ -1277,7 +1277,7 @@ display_number_force: displnl1: sub esp,64 - test ah,ah ; DECIMAL + test ah,ah ; DECIMAL jnz no_display_desnum shr eax,16 and eax,0xC03f @@ -1305,7 +1305,7 @@ display_number_force: ret no_display_desnum: - cmp ah,0x01 ; HEXADECIMAL + cmp ah,0x01 ; HEXADECIMAL jne no_display_hexnum shr eax,16 and eax,0xC03f @@ -1335,7 +1335,7 @@ display_number_force: ret no_display_hexnum: - cmp ah,0x02 ; BINARY + cmp ah,0x02 ; BINARY jne no_display_binnum shr eax,16 and eax,0xC03f @@ -1414,9 +1414,9 @@ draw_num_text: add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] add ebx,eax mov ecx,[esp+64+32-12+4] - and ecx, not 0x80000000 ; force counted string - mov eax, [esp+64+8] ; background color (if given) - mov edi, [esp+64+4] + and ecx, not 0x80000000 ; force counted string + mov eax, [esp+64+8] ; background color (if given) + mov edi, [esp+64+4] jmp dtext align 4 @@ -1435,7 +1435,7 @@ sys_setup: ; 12 = enable pci access - and [esp+32],dword 0 + and [esp+32],dword 0 dec ebx ; MIDI jnz nsyse1 cmp ecx,0x100 @@ -1447,7 +1447,7 @@ sys_setup: jb nsyse1 mov [midi_base],cx ;bx mov word [mididp],cx ;bx - inc cx ;bx + inc cx ;bx mov word [midisp],cx ;bx ret @@ -1514,76 +1514,76 @@ endg mov [cdid],0xb0 noprsl: dec ecx - jnz nosema - mov [cdbase],0x170 - mov [cdid],0xa0 + jnz nosema + mov [cdbase],0x170 + mov [cdid],0xa0 nosema: dec ecx - jnz nosesl - mov [cdbase],0x170 - mov [cdid],0xb0 + jnz nosesl + mov [cdbase],0x170 + mov [cdid],0xb0 nosesl: - ret + ret iglobal cd_base db 0 endg nsyse4: - - sub ebx,2 ; SYSTEM LANGUAGE - jnz nsyse5 - mov [syslang],ecx - ret + + sub ebx,2 ; SYSTEM LANGUAGE + jnz nsyse5 + mov [syslang],ecx + ret nsyse5: - - sub ebx,2 ; HD BASE - jnz nsyse7 + + sub ebx,2 ; HD BASE + jnz nsyse7 - test ecx,ecx - jz nosethd + test ecx,ecx + jz nosethd - cmp ecx,4 - ja nosethd - mov [hd_base],cl + cmp ecx,4 + ja nosethd + mov [hd_base],cl - cmp ecx,1 - jnz noprmahd - mov [hdbase],0x1f0 - and dword [hdid],0x0 - mov dword [hdpos],ecx + cmp ecx,1 + jnz noprmahd + mov [hdbase],0x1f0 + and dword [hdid],0x0 + mov dword [hdpos],ecx ; call set_FAT32_variables noprmahd: - cmp ecx,2 - jnz noprslhd - mov [hdbase],0x1f0 - mov [hdid],0x10 - mov dword [hdpos],ecx + cmp ecx,2 + jnz noprslhd + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov dword [hdpos],ecx ; call set_FAT32_variables noprslhd: - cmp ecx,3 - jnz nosemahd - mov [hdbase],0x170 - and dword [hdid],0x0 - mov dword [hdpos],ecx + cmp ecx,3 + jnz nosemahd + mov [hdbase],0x170 + and dword [hdid],0x0 + mov dword [hdpos],ecx ; call set_FAT32_variables nosemahd: - cmp ecx,4 - jnz noseslhd - mov [hdbase],0x170 - mov [hdid],0x10 - mov dword [hdpos],ecx + cmp ecx,4 + jnz noseslhd + mov [hdbase],0x170 + mov [hdid],0x10 + mov dword [hdpos],ecx ; call set_FAT32_variables noseslhd: - call reserve_hd1 - call reserve_hd_channel - call free_hd_channel - and dword [hd1_status],0 ; free + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel + and dword [hd1_status],0 ; free nosethd: - ret + ret iglobal hd_base db 0 @@ -1592,33 +1592,33 @@ endg nsyse7: ; cmp eax,8 ; HD PARTITION - dec ebx - jnz nsyse8 - mov [fat32part],ecx + dec ebx + jnz nsyse8 + mov [fat32part],ecx ; call set_FAT32_variables - call reserve_hd1 - call reserve_hd_channel - call free_hd_channel -; pusha - call choice_necessity_partition_1 -; popa - and dword [hd1_status],0 ; free - ret + call reserve_hd1 + call reserve_hd_channel + call free_hd_channel +; pusha + call choice_necessity_partition_1 +; popa + and dword [hd1_status],0 ; free + ret nsyse8: ; cmp eax,11 ; ENABLE LBA READ - and ecx,1 + and ecx,1 sub ebx,3 - jnz no_set_lba_read - mov [lba_read_enabled],ecx - ret + jnz no_set_lba_read + mov [lba_read_enabled],ecx + ret no_set_lba_read: ; cmp eax,12 ; ENABLE PCI ACCESS - dec ebx - jnz no_set_pci_access - mov [pci_access_enabled],ecx - ret + dec ebx + jnz no_set_pci_access + mov [pci_access_enabled],ecx + ret no_set_pci_access: ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -1626,8 +1626,8 @@ include 'vmodeint.inc' ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sys_setup_err: - or [esp+32],dword -1 - ret + or [esp+32],dword -1 + ret align 4 @@ -1643,118 +1643,118 @@ sys_getsetup: ; cmp eax,1 dec ebx - jnz ngsyse1 - movzx eax,[midi_base] - mov [esp+32],eax - ret + jnz ngsyse1 + movzx eax,[midi_base] + mov [esp+32],eax + ret ngsyse1: ; cmp eax,2 dec ebx - jnz ngsyse2 + jnz ngsyse2 - mov edi,[TASK_BASE] - mov ebx,[edi+TASKDATA.mem_start] - add ebx,edx + mov edi,[TASK_BASE] + mov ebx,[edi+TASKDATA.mem_start] + add ebx,edx ; cmp ebx,1 dec ecx - jnz kbnobaseret - mov eax,keymap - mov ecx,128 - call memmove - ret + jnz kbnobaseret + mov eax,keymap + mov ecx,128 + call memmove + ret kbnobaseret: ; cmp ebx,2 dec ecx - jnz kbnoshiftret + jnz kbnoshiftret - mov eax,keymap_shift - mov ecx,128 - call memmove - ret + mov eax,keymap_shift + mov ecx,128 + call memmove + ret kbnoshiftret: ; cmp ebx,3 dec ecx - jne kbnoaltret + jne kbnoaltret - mov eax,keymap_alt - mov ecx,128 - call memmove - ret + mov eax,keymap_alt + mov ecx,128 + call memmove + ret kbnoaltret: ; cmp ebx,9 sub ecx,6 - jnz ngsyse2 - movzx eax,word [keyboard] - mov [esp+32],eax - ret + jnz ngsyse2 + movzx eax,word [keyboard] + mov [esp+32],eax + ret ngsyse2: ; cmp eax,3 dec ebx - jnz ngsyse3 - movzx eax,[cd_base] - mov [esp+32],eax - ret + jnz ngsyse3 + movzx eax,[cd_base] + mov [esp+32],eax + ret ngsyse3: ; cmp eax,5 sub ebx,2 - jnz ngsyse5 - mov eax,[syslang] - mov [esp+32],eax - ret + jnz ngsyse5 + mov eax,[syslang] + mov [esp+32],eax + ret ngsyse5: ; cmp eax,7 sub ebx,2 - jnz ngsyse7 - movzx eax,[hd_base] - mov [esp+32],eax - ret + jnz ngsyse7 + movzx eax,[hd_base] + mov [esp+32],eax + ret ngsyse7: ; cmp eax,8 dec ebx - jnz ngsyse8 - mov eax,[fat32part] - mov [esp+32],eax - ret + jnz ngsyse8 + mov eax,[fat32part] + mov [esp+32],eax + ret ngsyse8: ; cmp eax,9 dec ebx - jnz ngsyse9 - mov eax,[timer_ticks] ;[0xfdf0] - mov [esp+32],eax - ret + jnz ngsyse9 + mov eax,[timer_ticks] ;[0xfdf0] + mov [esp+32],eax + ret ngsyse9: ; cmp eax,11 sub ebx,2 - jnz ngsyse11 - mov eax,[lba_read_enabled] - mov [esp+32],eax - ret + jnz ngsyse11 + mov eax,[lba_read_enabled] + mov [esp+32],eax + ret ngsyse11: ; cmp eax,12 dec ebx - jnz ngsyse12 - mov eax,[pci_access_enabled] - mov [esp+32],eax - ret + jnz ngsyse12 + mov eax,[pci_access_enabled] + mov [esp+32],eax + ret ngsyse12: - mov [esp+32],dword 1 - ret + mov [esp+32],dword 1 + ret get_timer_ticks: - mov eax,[timer_ticks] - ret + mov eax,[timer_ticks] + ret iglobal align 4 mousefn dd msscreen, mswin, msbutton, msset - dd app_load_cursor - dd app_set_cursor - dd app_delete_cursor - dd msz + dd app_load_cursor + dd app_set_cursor + dd app_delete_cursor + dd msz endg readmousepos: @@ -1768,106 +1768,106 @@ readmousepos: ; eax=6 delete cursor ; reserved ; eax=7 get mouse_z - cmp ebx, 7 - ja msset - jmp [mousefn+ebx*4] + cmp ebx, 7 + ja msset + jmp [mousefn+ebx*4] msscreen: - mov eax,[MOUSE_X] - shl eax,16 - mov ax,[MOUSE_Y] - mov [esp+36-4],eax - ret + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov [esp+36-4],eax + ret mswin: - mov eax,[MOUSE_X] - shl eax,16 - mov ax,[MOUSE_Y] - mov esi,[TASK_BASE] - mov bx, word [esi-twdw+WDATA.box.left] - shl ebx,16 - mov bx, word [esi-twdw+WDATA.box.top] - sub eax,ebx + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov esi,[TASK_BASE] + mov bx, word [esi-twdw+WDATA.box.left] + shl ebx,16 + mov bx, word [esi-twdw+WDATA.box.top] + sub eax,ebx - mov edi,[CURRENT_TASK] - shl edi,8 - sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] - rol eax,16 - sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] - rol eax,16 - mov [esp+36-4],eax - ret + mov edi,[CURRENT_TASK] + shl edi,8 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol eax,16 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol eax,16 + mov [esp+36-4],eax + ret msbutton: - movzx eax,byte [BTN_DOWN] - mov [esp+36-4],eax - ret + movzx eax,byte [BTN_DOWN] + mov [esp+36-4],eax + ret msz: - mov edi, [TASK_COUNT] - movzx edi, word [WIN_POS + edi*2] - cmp edi, [CURRENT_TASK] - jne @f - mov ax,[MOUSE_SCROLL_H] - shl eax,16 - mov ax,[MOUSE_SCROLL_V] - mov [esp+36-4],eax - and [MOUSE_SCROLL_H],word 0 - and [MOUSE_SCROLL_V],word 0 - ret + mov edi, [TASK_COUNT] + movzx edi, word [WIN_POS + edi*2] + cmp edi, [CURRENT_TASK] + jne @f + mov ax,[MOUSE_SCROLL_H] + shl eax,16 + mov ax,[MOUSE_SCROLL_V] + mov [esp+36-4],eax + and [MOUSE_SCROLL_H],word 0 + and [MOUSE_SCROLL_V],word 0 + ret @@: - and [esp+36-4],dword 0 + and [esp+36-4],dword 0 ; ret msset: - ret + ret app_load_cursor: - cmp ecx, OS_BASE - jae msset - stdcall load_cursor, ecx, edx - mov [esp+36-4], eax - ret + cmp ecx, OS_BASE + jae msset + stdcall load_cursor, ecx, edx + mov [esp+36-4], eax + ret app_set_cursor: - stdcall set_cursor, ecx - mov [esp+36-4], eax - ret + stdcall set_cursor, ecx + mov [esp+36-4], eax + ret app_delete_cursor: - stdcall delete_cursor, ecx - mov [esp+36-4], eax - ret + stdcall delete_cursor, ecx + mov [esp+36-4], eax + ret is_input: push edx - mov dx,word [midisp] - in al,dx - and al,0x80 - pop edx + mov dx,word [midisp] + in al,dx + and al,0x80 + pop edx ret is_output: push edx - mov dx,word [midisp] - in al,dx - and al,0x40 - pop edx + mov dx,word [midisp] + in al,dx + and al,0x40 + pop edx ret get_mpu_in: push edx - mov dx,word [mididp] - in al,dx - pop edx + mov dx,word [mididp] + in al,dx + pop edx ret put_mpu_out: push edx - mov dx,word [mididp] - out dx,al - pop edx + mov dx,word [mididp] + out dx,al + pop edx ret @@ -1945,7 +1945,7 @@ sys_end: mov eax,[TASK_BASE] mov [eax+TASKDATA.state], 3 ; terminate this program - waitterm: ; wait here for termination + waitterm: ; wait here for termination mov ebx,100 call delay_hs jmp waitterm @@ -1953,42 +1953,42 @@ sys_end: iglobal align 4 sys_system_table: - dd exit_for_anyone ; 1 = obsolete - dd sysfn_terminate ; 2 = terminate thread - dd sysfn_activate ; 3 = activate window - dd sysfn_getidletime ; 4 = get idle time - dd sysfn_getcpuclock ; 5 = get cpu clock - dd sysfn_saveramdisk ; 6 = save ramdisk - dd sysfn_getactive ; 7 = get active window - dd sysfn_sound_flag ; 8 = get/set sound_flag - dd sysfn_shutdown ; 9 = shutdown with parameter - dd sysfn_minimize ; 10 = minimize window - dd sysfn_getdiskinfo ; 11 = get disk subsystem info - dd sysfn_lastkey ; 12 = get last pressed key - dd sysfn_getversion ; 13 = get kernel version - dd sysfn_waitretrace ; 14 = wait retrace - dd sysfn_centermouse ; 15 = center mouse cursor - dd sysfn_getfreemem ; 16 = get free memory size - dd sysfn_getallmem ; 17 = get total memory size - dd sysfn_terminate2 ; 18 = terminate thread using PID - ; instead of slot - dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration - dd sysfn_meminfo ; 20 = get extended memory info - dd sysfn_pid_to_slot ; 21 = get slot number for pid - dd sysfn_min_rest_window ; 22 = minimize and restore any window + dd exit_for_anyone ; 1 = obsolete + dd sysfn_terminate ; 2 = terminate thread + dd sysfn_activate ; 3 = activate window + dd sysfn_getidletime ; 4 = get idle time + dd sysfn_getcpuclock ; 5 = get cpu clock + dd sysfn_saveramdisk ; 6 = save ramdisk + dd sysfn_getactive ; 7 = get active window + dd sysfn_sound_flag ; 8 = get/set sound_flag + dd sysfn_shutdown ; 9 = shutdown with parameter + dd sysfn_minimize ; 10 = minimize window + dd sysfn_getdiskinfo ; 11 = get disk subsystem info + dd sysfn_lastkey ; 12 = get last pressed key + dd sysfn_getversion ; 13 = get kernel version + dd sysfn_waitretrace ; 14 = wait retrace + dd sysfn_centermouse ; 15 = center mouse cursor + dd sysfn_getfreemem ; 16 = get free memory size + dd sysfn_getallmem ; 17 = get total memory size + dd sysfn_terminate2 ; 18 = terminate thread using PID + ; instead of slot + dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration + dd sysfn_meminfo ; 20 = get extended memory info + dd sysfn_pid_to_slot ; 21 = get slot number for pid + dd sysfn_min_rest_window ; 22 = minimize and restore any window sysfn_num = ($ - sys_system_table)/4 endg sys_system: - dec ebx - cmp ebx, sysfn_num - jae @f - jmp dword [sys_system_table + ebx*4] + dec ebx + cmp ebx, sysfn_num + jae @f + jmp dword [sys_system_table + ebx*4] @@: - ret + ret -sysfn_shutdown: ; 18.9 = system shutdown +sysfn_shutdown: ; 18.9 = system shutdown cmp ecx,1 jl exit_for_anyone cmp ecx,4 @@ -2005,7 +2005,7 @@ sysfn_shutdown: ; 18.9 = system shutdown shutdown_processes: dd 0x0 endg -sysfn_terminate: ; 18.2 = TERMINATE +sysfn_terminate: ; 18.2 = TERMINATE cmp ecx,2 jb noprocessterminate mov edx,[TASK_COUNT] @@ -2019,7 +2019,7 @@ sysfn_terminate: ; 18.2 = TERMINATE jz noprocessterminate ;call MEM_Heap_Lock ;guarantee that process isn't working with heap - mov [ecx],byte 3 ; clear possible i40's + mov [ecx],byte 3 ; clear possible i40's ;call MEM_Heap_UnLock cmp edx,[application_table_status] ; clear app table stat @@ -2034,7 +2034,7 @@ sysfn_terminate2: .table_status: cli cmp [application_table_status],0 - je .stf + je .stf sti call change_task jmp .table_status @@ -2043,7 +2043,7 @@ sysfn_terminate2: mov eax,ecx call pid_to_slot test eax,eax - jz .not_found + jz .not_found mov ecx,eax cli call sysfn_terminate @@ -2053,10 +2053,10 @@ sysfn_terminate2: ret .not_found: mov [application_table_status],0 - or dword [esp+32],-1 + or dword [esp+32],-1 ret -sysfn_activate: ; 18.3 = ACTIVATE WINDOW +sysfn_activate: ; 18.3 = ACTIVATE WINDOW cmp ecx,2 jb .nowindowactivate cmp ecx,[TASK_COUNT] @@ -2077,12 +2077,12 @@ sysfn_activate: ; 18.3 = ACTIVATE WINDOW .nowindowactivate: ret -sysfn_getidletime: ; 18.4 = GET IDLETIME +sysfn_getidletime: ; 18.4 = GET IDLETIME mov eax,[idleusesec] mov [esp+32], eax ret -sysfn_getcpuclock: ; 18.5 = GET TSC/SEC +sysfn_getcpuclock: ; 18.5 = GET TSC/SEC mov eax,[CPU_FREQ] mov [esp+32], eax ret @@ -2092,13 +2092,13 @@ sysfn_getcpuclock: ; 18.5 = GET TSC/SEC include 'blkdev/rdsave.inc' ;!!!!!!!!!!!!!!!!!!!!!!!! align 4 -sysfn_getactive: ; 18.7 = get active window +sysfn_getactive: ; 18.7 = get active window mov eax, [TASK_COUNT] movzx eax, word [WIN_POS + eax*2] mov [esp+32],eax ret -sysfn_sound_flag: ; 18.8 = get/set sound_flag +sysfn_sound_flag: ; 18.8 = get/set sound_flag ; cmp ecx,1 dec ecx jnz nogetsoundflag @@ -2113,11 +2113,11 @@ sysfn_sound_flag: ; 18.8 = get/set sound_flag nosoundflag: ret -sysfn_minimize: ; 18.10 = minimize window +sysfn_minimize: ; 18.10 = minimize window mov [window_minimize],1 ret align 4 -sysfn_getdiskinfo: ; 18.11 = get disk info table +sysfn_getdiskinfo: ; 18.11 = get disk info table ; cmp ecx,1 dec ecx jnz full_table @@ -2141,11 +2141,11 @@ sysfn_getdiskinfo: ; 18.11 = get disk info table rep movsd ret -sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) - and dword [esp+32], 0 - ret +sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) + and dword [esp+32], 0 + ret -sysfn_getversion: ; 18.13 = get kernel ID and version +sysfn_getversion: ; 18.13 = get kernel ID and version mov edi,ebx mov esi,version_inf mov ecx,version_end-version_inf @@ -2164,22 +2164,22 @@ sysfn_waitretrace: ; 18.14 = sys wait retrace ret align 4 -sysfn_centermouse: ; 18.15 = mouse centered +sysfn_centermouse: ; 18.15 = mouse centered ; removed here by ; call mouse_centered ;* mouse centered - start code- Mario79 ;mouse_centered: ; push eax - mov eax,[Screen_Max_X] - shr eax,1 - mov [MOUSE_X],ax - mov eax,[Screen_Max_Y] - shr eax,1 - mov [MOUSE_Y],ax + mov eax,[Screen_Max_X] + shr eax,1 + mov [MOUSE_X],ax + mov eax,[Screen_Max_Y] + shr eax,1 + mov [MOUSE_Y],ax ; ret ;* mouse centered - end code- Mario79 xor eax,eax - and [esp+32],eax + and [esp+32],eax ; pop eax ret @@ -2249,14 +2249,14 @@ sysfn_pid_to_slot: sysfn_min_rest_window: pushad - mov eax, edx ; ebx - operating + mov eax, edx ; ebx - operating shr ecx, 1 jnc @f call pid_to_slot @@: - or eax, eax ; eax - number of slot + or eax, eax ; eax - number of slot jz .error - cmp eax, 255 ; varify maximal slot number + cmp eax, 255 ; varify maximal slot number ja .error movzx eax, word [WIN_STACK + eax*2] shr ecx, 1 @@ -2284,7 +2284,7 @@ uglobal screen_workarea RECT ;// mike.dld, 2006-29-01 ] window_minimize db 0 -sound_flag db 0 +sound_flag db 0 endg iglobal @@ -2296,27 +2296,27 @@ version_end: endg UID_NONE=0 -UID_MENUETOS=1 ;official -UID_KOLIBRI=2 ;russian +UID_MENUETOS=1 ;official +UID_KOLIBRI=2 ;russian sys_cachetodiskette: - cmp ebx, 1 - jne .no_floppy_a_save - mov [flp_number], 1 - jmp .save_image_on_floppy + cmp ebx, 1 + jne .no_floppy_a_save + mov [flp_number], 1 + jmp .save_image_on_floppy .no_floppy_a_save: - cmp ebx, 2 - jne .no_floppy_b_save - mov [flp_number], 2 + cmp ebx, 2 + jne .no_floppy_b_save + mov [flp_number], 2 .save_image_on_floppy: - call save_image - mov [esp + 32], dword 0 - cmp [FDC_Status], 0 - je .yes_floppy_save + call save_image + mov [esp + 32], dword 0 + cmp [FDC_Status], 0 + je .yes_floppy_save .no_floppy_b_save: - mov [esp + 32], dword 1 + mov [esp + 32], dword 1 .yes_floppy_save: - ret + ret uglobal ; bgrchanged dd 0x0 @@ -2327,20 +2327,20 @@ endg sys_background: - cmp ebx,1 ; BACKGROUND SIZE + cmp ebx,1 ; BACKGROUND SIZE jnz nosb1 test ecx,ecx ; cmp ecx,0 - jz sbgrr + jz sbgrr test edx,edx ; cmp edx,0 - jz sbgrr + jz sbgrr @@: ;;Maxis use atomic bts for mutexes 4.4.2009 - bts dword [bgrlock], 0 - jnc @f - call change_task - jmp @b + bts dword [bgrlock], 0 + jnc @f + call change_task + jmp @b @@: mov [BgrDataWidth],ecx mov [BgrDataHeight],edx @@ -2348,10 +2348,10 @@ sys_background: pushad ; return memory for old background - mov eax, [img_background] - cmp eax, static_background_data - jz @f - stdcall kernel_free, eax + mov eax, [img_background] + cmp eax, static_background_data + jz @f + stdcall kernel_free, eax @@: ; calculate RAW size xor eax,eax @@ -2376,36 +2376,36 @@ sys_background: jmp .exit .memfailed: ; revert to static monotone data - mov [img_background], static_background_data - xor eax, eax - inc eax - mov [BgrDataWidth], eax - mov [BgrDataHeight], eax - mov [mem_BACKGROUND], 4 + mov [img_background], static_background_data + xor eax, eax + inc eax + mov [BgrDataWidth], eax + mov [BgrDataHeight], eax + mov [mem_BACKGROUND], 4 .exit: popad - mov [bgrlock], 0 + mov [bgrlock], 0 sbgrr: ret nosb1: - cmp ebx,2 ; SET PIXEL + cmp ebx,2 ; SET PIXEL jnz nosb2 mov eax, [img_background] test ecx, ecx - jz @f + jz @f cmp eax, static_background_data - jz .ret + jz .ret @@: mov ebx, [mem_BACKGROUND] add ebx, 4095 and ebx, -4096 sub ebx, 4 cmp ecx, ebx - ja .ret + ja .ret mov ebx,[eax+ecx] and ebx,0xFF000000 ;255*256*256*256 @@ -2416,7 +2416,7 @@ nosb1: ret nosb2: - cmp ebx,3 ; DRAW BACKGROUND + cmp ebx,3 ; DRAW BACKGROUND jnz nosb3 draw_background_temp: ; cmp [bgrchanged],1 ;0 @@ -2430,24 +2430,24 @@ draw_background_temp: ret nosb3: - cmp ebx,4 ; TILED / STRETCHED + cmp ebx,4 ; TILED / STRETCHED jnz nosb4 cmp ecx,[BgrDrawMode] - je nosb41 + je nosb41 mov [BgrDrawMode],ecx ; mov [bgrchanged],1 nosb41: ret nosb4: - cmp ebx,5 ; BLOCK MOVE TO BGR + cmp ebx,5 ; BLOCK MOVE TO BGR jnz nosb5 cmp [img_background], static_background_data jnz @f test edx, edx jnz .fin cmp esi, 4 - ja .fin + ja .fin @@: ; bughere mov eax, ecx @@ -2459,87 +2459,87 @@ draw_background_temp: ret nosb5: - cmp ebx, 6 - jnz nosb6 + cmp ebx, 6 + jnz nosb6 ;;Maxis use atomic bts for mutex 4.4.2009 @@: - bts dword [bgrlock], 0 - jnc @f - call change_task - jmp @b + bts dword [bgrlock], 0 + jnc @f + call change_task + jmp @b @@: - mov eax, [CURRENT_TASK] - mov [bgrlockpid], eax - cmp [img_background], static_background_data - jz .nomem - stdcall user_alloc, [mem_BACKGROUND] - mov [esp+32], eax - test eax, eax - jz .nomem - mov ebx, eax - shr ebx, 12 - or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK - mov esi, [img_background] - shr esi, 12 - mov ecx, [mem_BACKGROUND] - add ecx, 0xFFF - shr ecx, 12 + mov eax, [CURRENT_TASK] + mov [bgrlockpid], eax + cmp [img_background], static_background_data + jz .nomem + stdcall user_alloc, [mem_BACKGROUND] + mov [esp+32], eax + test eax, eax + jz .nomem + mov ebx, eax + shr ebx, 12 + or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK + mov esi, [img_background] + shr esi, 12 + mov ecx, [mem_BACKGROUND] + add ecx, 0xFFF + shr ecx, 12 .z: - mov eax, [page_tabs+ebx*4] - test al, 1 - jz @f - call free_page + mov eax, [page_tabs+ebx*4] + test al, 1 + jz @f + call free_page @@: - mov eax, [page_tabs+esi*4] - or al, PG_UW - mov [page_tabs+ebx*4], eax - mov eax, ebx - shl eax, 12 - invlpg [eax] - inc ebx - inc esi - loop .z - ret + mov eax, [page_tabs+esi*4] + or al, PG_UW + mov [page_tabs+ebx*4], eax + mov eax, ebx + shl eax, 12 + invlpg [eax] + inc ebx + inc esi + loop .z + ret .nomem: - and [bgrlockpid], 0 - mov [bgrlock], 0 + and [bgrlockpid], 0 + mov [bgrlock], 0 nosb6: - cmp ebx, 7 - jnz nosb7 - cmp [bgrlock], 0 - jz .err - mov eax, [CURRENT_TASK] - cmp [bgrlockpid], eax - jnz .err - mov eax, ecx - mov ebx, ecx - shr eax, 12 - mov ecx, [page_tabs+(eax-1)*4] - test cl, USED_BLOCK+DONT_FREE_BLOCK - jz .err - jnp .err - push eax - shr ecx, 12 - dec ecx + cmp ebx, 7 + jnz nosb7 + cmp [bgrlock], 0 + jz .err + mov eax, [CURRENT_TASK] + cmp [bgrlockpid], eax + jnz .err + mov eax, ecx + mov ebx, ecx + shr eax, 12 + mov ecx, [page_tabs+(eax-1)*4] + test cl, USED_BLOCK+DONT_FREE_BLOCK + jz .err + jnp .err + push eax + shr ecx, 12 + dec ecx @@: - and dword [page_tabs+eax*4], 0 - mov edx, eax - shl edx, 12 - push eax - invlpg [edx] - pop eax - inc eax - loop @b - pop eax - and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK - stdcall user_free, ebx - mov [esp+32], eax - and [bgrlockpid], 0 - mov [bgrlock], 0 - ret + and dword [page_tabs+eax*4], 0 + mov edx, eax + shl edx, 12 + push eax + invlpg [edx] + pop eax + inc eax + loop @b + pop eax + and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK + stdcall user_free, ebx + mov [esp+32], eax + and [bgrlockpid], 0 + mov [bgrlock], 0 + ret .err: - and dword [esp+32], 0 - ret + and dword [esp+32], 0 + ret nosb7: ret @@ -2560,7 +2560,7 @@ align 4 sys_getbackground: ; cmp eax,1 ; SIZE - dec ebx + dec ebx jnz nogb1 mov eax,[BgrDataWidth] shl eax,16 @@ -2570,21 +2570,21 @@ sys_getbackground: nogb1: ; cmp eax,2 ; PIXEL - dec ebx + dec ebx jnz nogb2 - mov eax, [img_background] - test ecx, ecx - jz @f - cmp eax, static_background_data - jz .ret + mov eax, [img_background] + test ecx, ecx + jz @f + cmp eax, static_background_data + jz .ret @@: mov ebx, [mem_BACKGROUND] add ebx, 4095 and ebx, -4096 sub ebx, 4 cmp ecx, ebx - ja .ret + ja .ret mov eax,[ecx+eax] @@ -2606,71 +2606,71 @@ nogb1: align 4 sys_getkey: - mov [esp + 32],dword 1 - ; test main buffer - mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK - movzx ecx, word [WIN_STACK + ebx * 2] - mov edx, [TASK_COUNT] - cmp ecx, edx - jne .finish - cmp [KEY_COUNT], byte 0 - je .finish - movzx eax, byte [KEY_BUFF] - shl eax, 8 - push eax - dec byte [KEY_COUNT] - and byte [KEY_COUNT], 127 - movzx ecx, byte [KEY_COUNT] - add ecx, 2 - mov eax, KEY_BUFF + 1 - mov ebx, KEY_BUFF - call memmove - pop eax + mov [esp + 32],dword 1 + ; test main buffer + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK + movzx ecx, word [WIN_STACK + ebx * 2] + mov edx, [TASK_COUNT] + cmp ecx, edx + jne .finish + cmp [KEY_COUNT], byte 0 + je .finish + movzx eax, byte [KEY_BUFF] + shl eax, 8 + push eax + dec byte [KEY_COUNT] + and byte [KEY_COUNT], 127 + movzx ecx, byte [KEY_COUNT] + add ecx, 2 + mov eax, KEY_BUFF + 1 + mov ebx, KEY_BUFF + call memmove + pop eax .ret_eax: - mov [esp + 32], eax - ret + mov [esp + 32], eax + ret .finish: ; test hotkeys buffer - mov ecx, hotkey_buffer + mov ecx, hotkey_buffer @@: - cmp [ecx], ebx - jz .found - add ecx, 8 - cmp ecx, hotkey_buffer + 120 * 8 - jb @b - ret + cmp [ecx], ebx + jz .found + add ecx, 8 + cmp ecx, hotkey_buffer + 120 * 8 + jb @b + ret .found: - mov ax, [ecx + 6] - shl eax, 16 - mov ah, [ecx + 4] - mov al, 2 - and dword [ecx + 4], 0 - and dword [ecx], 0 - jmp .ret_eax + mov ax, [ecx + 6] + shl eax, 16 + mov ah, [ecx + 4] + mov al, 2 + and dword [ecx + 4], 0 + and dword [ecx], 0 + jmp .ret_eax align 4 sys_getbutton: - mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK - mov [esp + 32], dword 1 - movzx ecx, word [WIN_STACK + ebx * 2] - mov edx, [TASK_COUNT] ; less than 256 processes - cmp ecx, edx - jne .exit - movzx eax, byte [BTN_COUNT] - test eax, eax - jz .exit - mov eax, [BTN_BUFF] - shl eax, 8 + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK + mov [esp + 32], dword 1 + movzx ecx, word [WIN_STACK + ebx * 2] + mov edx, [TASK_COUNT] ; less than 256 processes + cmp ecx, edx + jne .exit + movzx eax, byte [BTN_COUNT] + test eax, eax + jz .exit + mov eax, [BTN_BUFF] + shl eax, 8 ; // Alver 22.06.2008 // { - mov al, byte [btn_down_determ] - and al,0xFE ; delete left button bit + mov al, byte [btn_down_determ] + and al,0xFE ; delete left button bit ; } \\ Alver \\ - mov [BTN_COUNT], byte 0 - mov [esp + 32], eax + mov [BTN_COUNT], byte 0 + mov [esp + 32], eax .exit: - ret + ret align 4 @@ -2688,78 +2688,78 @@ sys_cpuusage: ; +30 dword PID , process idenfification number ; - cmp ecx,-1 ; who am I ? + cmp ecx,-1 ; who am I ? jne .no_who_am_i mov ecx,[CURRENT_TASK] .no_who_am_i: - cmp ecx, max_processes - ja .nofillbuf + cmp ecx, max_processes + ja .nofillbuf ; +4: word: position of the window of thread in the window stack - mov ax, [WIN_STACK + ecx * 2] - mov [ebx+4], ax + mov ax, [WIN_STACK + ecx * 2] + mov [ebx+4], ax ; +6: word: number of the thread slot, which window has in the window stack ; position ecx (has no relation to the specific thread) - mov ax, [WIN_POS + ecx * 2] - mov [ebx+6], ax + mov ax, [WIN_POS + ecx * 2] + mov [ebx+6], ax - shl ecx, 5 + shl ecx, 5 ; +0: dword: memory usage - mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage] - mov [ebx], eax + mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage] + mov [ebx], eax ; +10: 11 bytes: name of the process - push ecx - lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name] - add ebx, 10 - mov ecx, 11 - call memmove - pop ecx + push ecx + lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name] + add ebx, 10 + mov ecx, 11 + call memmove + pop ecx ; +22: address of the process in memory ; +26: size of used memory - 1 - push edi - lea edi, [ebx+12] - xor eax, eax - mov edx, 0x100000*16 - cmp ecx, 1 shl 5 - je .os_mem - mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size] - mov eax, std_application_base_address + push edi + lea edi, [ebx+12] + xor eax, eax + mov edx, 0x100000*16 + cmp ecx, 1 shl 5 + je .os_mem + mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size] + mov eax, std_application_base_address .os_mem: - stosd - lea eax, [edx-1] - stosd + stosd + lea eax, [edx-1] + stosd ; +30: PID/TID - mov eax, [ecx+CURRENT_TASK+TASKDATA.pid] - stosd + mov eax, [ecx+CURRENT_TASK+TASKDATA.pid] + stosd ; window position and size - push esi - lea esi, [ecx + window_data + WDATA.box] - movsd - movsd - movsd - movsd + push esi + lea esi, [ecx + window_data + WDATA.box] + movsd + movsd + movsd + movsd ; Process state (+50) - mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state] - stosd + mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state] + stosd ; Window client area box - lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox] - movsd - movsd - movsd - movsd + lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox] + movsd + movsd + movsd + movsd ; Window state - mov al, [ecx+window_data+WDATA.fl_wstate] - stosb + mov al, [ecx+window_data+WDATA.fl_wstate] + stosb - pop esi - pop edi + pop esi + pop edi .nofillbuf: ; return number of processes @@ -2770,133 +2770,133 @@ sys_cpuusage: align 4 sys_clock: - cli + cli ; Mikhail Lisovin xx Jan 2005 - @@: mov al, 10 - out 0x70, al - in al, 0x71 - test al, al - jns @f - mov esi, 1 - call delay_ms - jmp @b + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b @@: ; end Lisovin's fix - xor al,al ; seconds - out 0x70,al - in al,0x71 - movzx ecx,al - mov al,02 ; minutes - shl ecx,16 - out 0x70,al - in al,0x71 - movzx edx,al - mov al,04 ; hours - shl edx,8 - out 0x70,al - in al,0x71 - add ecx,edx - movzx edx,al - add ecx,edx - sti - mov [esp + 32], ecx - ret + xor al,al ; seconds + out 0x70,al + in al,0x71 + movzx ecx,al + mov al,02 ; minutes + shl ecx,16 + out 0x70,al + in al,0x71 + movzx edx,al + mov al,04 ; hours + shl edx,8 + out 0x70,al + in al,0x71 + add ecx,edx + movzx edx,al + add ecx,edx + sti + mov [esp + 32], ecx + ret align 4 sys_date: - cli - @@: mov al, 10 - out 0x70, al - in al, 0x71 - test al, al - jns @f - mov esi, 1 - call delay_ms - jmp @b + cli + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b @@: - mov ch,0 - mov al,7 ; date - out 0x70,al - in al,0x71 - mov cl,al - mov al,8 ; month - shl ecx,16 - out 0x70,al - in al,0x71 - mov ch,al - mov al,9 ; year - out 0x70,al - in al,0x71 - mov cl,al - sti - mov [esp+32], ecx - ret + mov ch,0 + mov al,7 ; date + out 0x70,al + in al,0x71 + mov cl,al + mov al,8 ; month + shl ecx,16 + out 0x70,al + in al,0x71 + mov ch,al + mov al,9 ; year + out 0x70,al + in al,0x71 + mov cl,al + sti + mov [esp+32], ecx + ret ; redraw status sys_redrawstat: - cmp ebx, 1 - jne no_widgets_away - ; buttons away - mov ecx,[CURRENT_TASK] + cmp ebx, 1 + jne no_widgets_away + ; buttons away + mov ecx,[CURRENT_TASK] sys_newba2: - mov edi,[BTN_ADDR] - cmp [edi], dword 0 ; empty button list ? - je end_of_buttons_away - movzx ebx, word [edi] - inc ebx - mov eax,edi + mov edi,[BTN_ADDR] + cmp [edi], dword 0 ; empty button list ? + je end_of_buttons_away + movzx ebx, word [edi] + inc ebx + mov eax,edi sys_newba: - dec ebx - jz end_of_buttons_away + dec ebx + jz end_of_buttons_away - add eax, 0x10 - cmp cx, [eax] - jnz sys_newba + add eax, 0x10 + cmp cx, [eax] + jnz sys_newba - push eax ebx ecx - mov ecx,ebx - inc ecx - shl ecx, 4 - mov ebx, eax - add eax, 0x10 - call memmove - dec dword [edi] - pop ecx ebx eax + push eax ebx ecx + mov ecx,ebx + inc ecx + shl ecx, 4 + mov ebx, eax + add eax, 0x10 + call memmove + dec dword [edi] + pop ecx ebx eax - jmp sys_newba2 + jmp sys_newba2 end_of_buttons_away: - ret + ret no_widgets_away: - cmp ebx, 2 - jnz srl1 + cmp ebx, 2 + jnz srl1 - mov edx, [TASK_BASE] ; return whole screen draw area for this app - add edx, draw_data - CURRENT_TASK - mov [edx + RECT.left], 0 - mov [edx + RECT.top], 0 - mov eax, [Screen_Max_X] - mov [edx + RECT.right], eax - mov eax, [Screen_Max_Y] - mov [edx + RECT.bottom], eax + mov edx, [TASK_BASE] ; return whole screen draw area for this app + add edx, draw_data - CURRENT_TASK + mov [edx + RECT.left], 0 + mov [edx + RECT.top], 0 + mov eax, [Screen_Max_X] + mov [edx + RECT.right], eax + mov eax, [Screen_Max_Y] + mov [edx + RECT.bottom], eax - mov edi, [TASK_BASE] - or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app - call sys_window_mouse - ret + mov edi, [TASK_BASE] + or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app + call sys_window_mouse + ret srl1: - ret + ret sys_drawwindow: @@ -2918,7 +2918,7 @@ sys_drawwindow: jmp draw_window_caption.2 nosyswI: - cmp al,1 ; type II - only reserve area, no draw + cmp al,1 ; type II - only reserve area, no draw jne nosyswII inc [mouse_pause] call [_display.disable_mouse] @@ -2930,7 +2930,7 @@ sys_drawwindow: ret nosyswII: - cmp al,2 ; type III - new style + cmp al,2 ; type III - new style jne nosyswIII inc [mouse_pause] call [_display.disable_mouse] @@ -2943,9 +2943,9 @@ sys_drawwindow: jmp draw_window_caption.2 nosyswIII: - cmp al,3 ; type IV - skinned window - je draw_skin_window - cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window} + cmp al,3 ; type IV - skinned window + je draw_skin_window + cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window} jne nosyswV draw_skin_window: @@ -2970,180 +2970,180 @@ sys_drawwindow: draw_window_caption: - inc [mouse_pause] - call [_display.disable_mouse] + inc [mouse_pause] + call [_display.disable_mouse] - xor eax,eax - mov edx,[TASK_COUNT] - movzx edx,word[WIN_POS+edx*2] - cmp edx,[CURRENT_TASK] - jne @f - inc eax - @@: mov edx,[CURRENT_TASK] - shl edx,5 - add edx,window_data - movzx ebx,[edx+WDATA.fl_wstyle] - and bl,0x0F - cmp bl,3 - je .draw_caption_style_3 ;{for 3 and 4 style write caption} - cmp bl,4 - je .draw_caption_style_3 + xor eax,eax + mov edx,[TASK_COUNT] + movzx edx,word[WIN_POS+edx*2] + cmp edx,[CURRENT_TASK] + jne @f + inc eax + @@: mov edx,[CURRENT_TASK] + shl edx,5 + add edx,window_data + movzx ebx,[edx+WDATA.fl_wstyle] + and bl,0x0F + cmp bl,3 + je .draw_caption_style_3 ;{for 3 and 4 style write caption} + cmp bl,4 + je .draw_caption_style_3 - jmp .not_style_3 + jmp .not_style_3 .draw_caption_style_3: - push edx - call drawwindow_IV_caption - add esp,4 - jmp .2 + push edx + call drawwindow_IV_caption + add esp,4 + jmp .2 .not_style_3: - cmp bl,2 - jne .not_style_2 + cmp bl,2 + jne .not_style_2 - call drawwindow_III_caption - jmp .2 + call drawwindow_III_caption + jmp .2 .not_style_2: - cmp bl,0 - jne .2 + cmp bl,0 + jne .2 - call drawwindow_I_caption + call drawwindow_I_caption ;-------------------------------------------------------------- - .2: ;jmp @f - mov edi,[CURRENT_TASK] - shl edi,5 - test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION - jz @f - mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] - or edx,edx - jz @f + .2: ;jmp @f + mov edi,[CURRENT_TASK] + shl edi,5 + test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + jz @f + mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] + or edx,edx + jz @f - movzx eax,[edi+window_data+WDATA.fl_wstyle] - and al,0x0F - cmp al,3 - je .skinned - cmp al,4 - je .skinned + movzx eax,[edi+window_data+WDATA.fl_wstyle] + and al,0x0F + cmp al,3 + je .skinned + cmp al,4 + je .skinned - jmp .not_skinned + jmp .not_skinned .skinned: - mov ebp,[edi+window_data+WDATA.box.left-2] - mov bp,word[edi+window_data+WDATA.box.top] - movzx eax,word[edi+window_data+WDATA.box.width] - sub ax,[_skinmargins.left] - sub ax,[_skinmargins.right] - push edx - cwde - cdq - mov ebx,6 - idiv ebx - pop edx - or eax,eax - js @f - mov esi,eax - mov ebx,dword[_skinmargins.left-2] - mov bx,word[_skinh] - sub bx,[_skinmargins.bottom] - sub bx,[_skinmargins.top] - sar bx,1 - adc bx,0 - add bx,[_skinmargins.top] - add bx,-3 - add ebx,ebp - jmp .dodraw + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub ax,[_skinmargins.left] + sub ax,[_skinmargins.right] + push edx + cwde + cdq + mov ebx,6 + idiv ebx + pop edx + or eax,eax + js @f + mov esi,eax + mov ebx,dword[_skinmargins.left-2] + mov bx,word[_skinh] + sub bx,[_skinmargins.bottom] + sub bx,[_skinmargins.top] + sar bx,1 + adc bx,0 + add bx,[_skinmargins.top] + add bx,-3 + add ebx,ebp + jmp .dodraw .not_skinned: - cmp al,1 - je @f + cmp al,1 + je @f - mov ebp,[edi+window_data+WDATA.box.left-2] - mov bp,word[edi+window_data+WDATA.box.top] - movzx eax,word[edi+window_data+WDATA.box.width] - sub eax,16 - push edx - cwde - cdq - mov ebx,6 - idiv ebx - pop edx - or eax,eax - js @f - mov esi,eax - mov ebx,0x00080007 - add ebx,ebp + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub eax,16 + push edx + cwde + cdq + mov ebx,6 + idiv ebx + pop edx + or eax,eax + js @f + mov esi,eax + mov ebx,0x00080007 + add ebx,ebp .dodraw: - mov ecx,[common_colours+16];0x00FFFFFF - or ecx, 0x80000000 - xor edi,edi + mov ecx,[common_colours+16];0x00FFFFFF + or ecx, 0x80000000 + xor edi,edi ; // Alver 22.06.2008 // { ; call dtext - call dtext_asciiz_esi + call dtext_asciiz_esi ; } \\ Alver \\ @@: ;-------------------------------------------------------------- - dec [mouse_pause] - call [draw_pointer] - ret + dec [mouse_pause] + call [draw_pointer] + ret iglobal align 4 window_topleft dd \ - 1, 21,\ ;type 0 - 0, 0,\ ;type 1 - 5, 20,\ ;type 2 - 5, ?,\ ;type 3 {set by skin} - 5, ? ;type 4 {set by skin} + 1, 21,\ ;type 0 + 0, 0,\ ;type 1 + 5, 20,\ ;type 2 + 5, ?,\ ;type 3 {set by skin} + 5, ? ;type 4 {set by skin} endg set_window_clientbox: - push eax ecx edi + push eax ecx edi - mov eax,[_skinh] - mov [window_topleft+4*7],eax - mov [window_topleft+4*9],eax + mov eax,[_skinh] + mov [window_topleft+4*7],eax + mov [window_topleft+4*9],eax - mov ecx,edi - sub edi,window_data - shl edi,3 - test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE - jz @f + mov ecx,edi + sub edi,window_data + shl edi,3 + test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE + jz @f - movzx eax,[ecx+WDATA.fl_wstyle] - and eax,0x0F - mov eax,[eax*8+window_topleft+0] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax - shl eax,1 - neg eax - add eax,[ecx+WDATA.box.width] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + mov eax,[eax*8+window_topleft+0] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax + shl eax,1 + neg eax + add eax,[ecx+WDATA.box.width] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax - movzx eax,[ecx+WDATA.fl_wstyle] - and eax,0x0F - push [eax*8+window_topleft+0] - mov eax,[eax*8+window_topleft+4] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax - neg eax - sub eax,[esp] - add eax,[ecx+WDATA.box.height] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax - add esp,4 + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + push [eax*8+window_topleft+0] + mov eax,[eax*8+window_topleft+4] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax + neg eax + sub eax,[esp] + add eax,[ecx+WDATA.box.height] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax + add esp,4 - pop edi ecx eax - ret + pop edi ecx eax + ret @@: - xor eax,eax - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax - mov eax,[ecx+WDATA.box.width] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax - mov eax,[ecx+WDATA.box.height] - mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax + xor eax,eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax + mov eax,[ecx+WDATA.box.width] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax + mov eax,[ecx+WDATA.box.height] + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax - pop edi ecx eax - ret + pop edi ecx eax + ret sys_set_window: @@ -3177,39 +3177,39 @@ sys_set_window: call check_window_position - push ecx esi edi ; save for window fullscreen/resize + push ecx esi edi ; save for window fullscreen/resize ;mov esi,edi - mov cl, [edi+WDATA.fl_wstyle] - mov eax, [edi+WDATA.cl_frames] + mov cl, [edi+WDATA.fl_wstyle] + mov eax, [edi+WDATA.cl_frames] sub edi,window_data shl edi,3 add edi,SLOT_BASE - and cl,0x0F - mov [edi+APPDATA.wnd_caption],0 - cmp cl,3 - je set_APPDATA_wnd_caption - cmp cl,4 ; {SPraid.simba} - je set_APPDATA_wnd_caption + and cl,0x0F + mov [edi+APPDATA.wnd_caption],0 + cmp cl,3 + je set_APPDATA_wnd_caption + cmp cl,4 ; {SPraid.simba} + je set_APPDATA_wnd_caption - jmp @f + jmp @f set_APPDATA_wnd_caption: - mov [edi+APPDATA.wnd_caption],eax - @@: mov esi,[esp+0] + mov [edi+APPDATA.wnd_caption],eax + @@: mov esi,[esp+0] add edi, APPDATA.saved_box - movsd - movsd - movsd - movsd + movsd + movsd + movsd + movsd pop edi esi ecx - mov esi, [CURRENT_TASK] - movzx esi, word [WIN_STACK+esi*2] - lea esi, [WIN_POS+esi*2] - call waredraw + mov esi, [CURRENT_TASK] + movzx esi, word [WIN_STACK+esi*2] + lea esi, [WIN_POS+esi*2] + call waredraw ;;; mov ebx, 1 ;;; call delay_hs @@ -3221,13 +3221,13 @@ sys_set_window: add edx, ebx call calculatescreen - mov [KEY_COUNT],byte 0 ; empty keyboard buffer - mov [BTN_COUNT],byte 0 ; empty button buffer + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer newd: call set_window_clientbox - mov [edi+WDATA.fl_redraw],byte 0 ; no redraw + mov [edi+WDATA.fl_redraw],byte 0 ; no redraw mov edx,edi ret @@ -3235,18 +3235,18 @@ sys_set_window: syscall_windowsettings: .set_window_caption: - dec ebx ; subfunction #1 - set window caption - jnz .exit_fail + dec ebx ; subfunction #1 - set window caption + jnz .exit_fail - ; NOTE: only window owner thread can set its caption, - ; so there's no parameter for PID/TID + ; NOTE: only window owner thread can set its caption, + ; so there's no parameter for PID/TID - mov edi,[CURRENT_TASK] - shl edi,5 + mov edi,[CURRENT_TASK] + shl edi,5 - ; have to check if caption is within application memory limit - ; check is trivial, and if application resizes its memory, - ; caption still can become over bounds + ; have to check if caption is within application memory limit + ; check is trivial, and if application resizes its memory, + ; caption still can become over bounds ; diamond, 31.10.2006: check removed because with new memory manager ; there can be valid data after APPDATA.mem_size bound ; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size] @@ -3254,115 +3254,115 @@ syscall_windowsettings: ; cmp ebx,ecx ; ja .exit_fail - mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ecx - or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ecx + or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION - call draw_window_caption + call draw_window_caption - xor eax,eax ; eax = 0 (success) - ret + xor eax,eax ; eax = 0 (success) + ret ; .get_window_caption: ; dec eax ; subfunction #2 - get window caption ; jnz .exit_fail - ; not implemented yet + ; not implemented yet .exit_fail: - xor eax,eax - inc eax ; eax = 1 (fail) - ret + xor eax,eax + inc eax ; eax = 1 (fail) + ret sys_window_move: - mov edi,[CURRENT_TASK] - shl edi,5 - add edi,window_data + mov edi,[CURRENT_TASK] + shl edi,5 + add edi,window_data - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jnz .window_move_return + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz .window_move_return - push dword [edi + WDATA.box.left] ; save old coordinates - push dword [edi + WDATA.box.top] - push dword [edi + WDATA.box.width] - push dword [edi + WDATA.box.height] + push dword [edi + WDATA.box.left] ; save old coordinates + push dword [edi + WDATA.box.top] + push dword [edi + WDATA.box.width] + push dword [edi + WDATA.box.height] - cmp eax,-1 ; set new position and size - je .no_x_reposition - mov [edi + WDATA.box.left], eax + cmp eax,-1 ; set new position and size + je .no_x_reposition + mov [edi + WDATA.box.left], eax .no_x_reposition: - cmp ebx,-1 - je .no_y_reposition - mov [edi + WDATA.box.top], ebx + cmp ebx,-1 + je .no_y_reposition + mov [edi + WDATA.box.top], ebx .no_y_reposition: - test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP - jnz .no_y_resizing + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .no_y_resizing - cmp ecx,-1 - je .no_x_resizing - mov [edi + WDATA.box.width], ecx + cmp ecx,-1 + je .no_x_resizing + mov [edi + WDATA.box.width], ecx .no_x_resizing: - cmp edx,-1 - je .no_y_resizing - mov [edi + WDATA.box.height], edx + cmp edx,-1 + je .no_y_resizing + mov [edi + WDATA.box.height], edx .no_y_resizing: - call check_window_position - call set_window_clientbox + call check_window_position + call set_window_clientbox - pushad ; save for window fullscreen/resize - mov esi,edi - sub edi,window_data - shr edi,5 - shl edi,8 - add edi, SLOT_BASE + APPDATA.saved_box - mov ecx,4 - cld - rep movsd - popad + pushad ; save for window fullscreen/resize + mov esi,edi + sub edi,window_data + shr edi,5 + shl edi,8 + add edi, SLOT_BASE + APPDATA.saved_box + mov ecx,4 + cld + rep movsd + popad - pushad ; calculcate screen at new position - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - add ecx,eax - add edx,ebx + pushad ; calculcate screen at new position + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx,eax + add edx,ebx - call calculatescreen - popad + call calculatescreen + popad - pop edx ; calculcate screen at old position - pop ecx - pop ebx - pop eax - add ecx,eax - add edx,ebx - mov [draw_limits.left],eax ; save for drawlimits - mov [draw_limits.top],ebx - mov [draw_limits.right],ecx - mov [draw_limits.bottom],edx - call calculatescreen + pop edx ; calculcate screen at old position + pop ecx + pop ebx + pop eax + add ecx,eax + add edx,ebx + mov [draw_limits.left],eax ; save for drawlimits + mov [draw_limits.top],ebx + mov [draw_limits.right],ecx + mov [draw_limits.bottom],edx + call calculatescreen - mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw + mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw - mov eax,edi ; redraw screen at old position - xor esi,esi - call redrawscreen + mov eax,edi ; redraw screen at old position + xor esi,esi + call redrawscreen - mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer - mov [MOUSE_BACKGROUND],byte 0 ; no mouse under - mov [MOUSE_DOWN],byte 0 ; react to mouse up/down + mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under + mov [MOUSE_DOWN],byte 0 ; react to mouse up/down - call [draw_pointer] + call [draw_pointer] - mov [window_move_pr],0 + mov [window_move_pr],0 .window_move_return: - ret + ret uglobal window_move_pr dd 0x0 @@ -3398,7 +3398,7 @@ sheduler: dd sys_sheduler.03 dd sys_sheduler.04 endg -sys_sheduler: +sys_sheduler: ;rewritten by 29.12.2009 jmp dword [sheduler+ebx*4] ;.shed_counter: @@ -3410,20 +3410,20 @@ sys_sheduler: .02: ;.perf_control: inc ebx ;before ebx=2, ebx=3 - cmp ebx,ecx ;if ecx=3, ebx=3 - jz cache_disable + cmp ebx,ecx ;if ecx=3, ebx=3 + jz cache_disable - dec ebx ;ebx=2 - cmp ebx,ecx ; + dec ebx ;ebx=2 + cmp ebx,ecx ; jz cache_enable ;if ecx=2 and ebx=2 - dec ebx ;ebx=1 + dec ebx ;ebx=1 cmp ebx,ecx - jz is_cache_enabled ;if ecx=1 and ebx=1 + jz is_cache_enabled ;if ecx=1 and ebx=1 dec ebx - test ebx,ecx ;ebx=0 and ecx=0 - jz modify_pce ;if ecx=0 + test ebx,ecx ;ebx=0 and ecx=0 + jz modify_pce ;if ecx=0 ret @@ -3431,34 +3431,34 @@ sys_sheduler: ;.rdmsr_instr: ;now counter in ecx ;(edx:eax) esi:edi => edx:esi - mov eax,esi + mov eax,esi mov ecx,edx rdmsr - mov [esp+32],eax - mov [esp+20],edx ;ret in ebx? + mov [esp+32],eax + mov [esp+20],edx ;ret in ebx? ret .04: ;.wrmsr_instr: ;now counter in ecx ;(edx:eax) esi:edi => edx:esi - ; Fast Call MSR can't be destroy - ; Ќ® MSR_AMD_EFER ¬®¦­® Ё§¬Ґ­пвм, в.Є. ў н⮬ ॣЁбвॠ«Ёи - ; ўЄ«оз овбп/ўлЄ«оз овбп а биЁаҐ­­лҐ ў®§¬®¦­®бвЁ - cmp edx,MSR_SYSENTER_CS - je @f - cmp edx,MSR_SYSENTER_ESP - je @f - cmp edx,MSR_SYSENTER_EIP - je @f - cmp edx,MSR_AMD_STAR - je @f + ; Fast Call MSR can't be destroy + ; Ќ® MSR_AMD_EFER ¬®¦­® Ё§¬Ґ­пвм, в.Є. ў н⮬ ॣЁбвॠ«Ёи + ; ўЄ«оз овбп/ўлЄ«оз овбп а биЁаҐ­­лҐ ў®§¬®¦­®бвЁ + cmp edx,MSR_SYSENTER_CS + je @f + cmp edx,MSR_SYSENTER_ESP + je @f + cmp edx,MSR_SYSENTER_EIP + je @f + cmp edx,MSR_AMD_STAR + je @f - mov eax,esi + mov eax,esi mov ecx,edx - wrmsr - ; mov [esp + 32], eax - ; mov [esp + 20], edx ;ret in ebx? + wrmsr + ; mov [esp + 32], eax + ; mov [esp + 20], edx ;ret in ebx? @@: ret @@ -3500,28 +3500,28 @@ ret ; check if pixel is allowed to be drawn checkpixel: - push eax edx + push eax edx - mov edx,[Screen_Max_X] ; screen x size - inc edx - imul edx, ebx - add eax, [_WinMapAddress] - mov dl, [eax+edx] ; lea eax, [...] + mov edx,[Screen_Max_X] ; screen x size + inc edx + imul edx, ebx + add eax, [_WinMapAddress] + mov dl, [eax+edx] ; lea eax, [...] - xor ecx, ecx - mov eax, [CURRENT_TASK] - cmp al, dl - setne cl + xor ecx, ecx + mov eax, [CURRENT_TASK] + cmp al, dl + setne cl - pop edx eax - ret + pop edx eax + ret iglobal cpustring db 'CPU',0 endg uglobal -background_defined db 0 ; diamond, 11.04.2006 +background_defined db 0 ; diamond, 11.04.2006 endg align 4 @@ -3532,8 +3532,8 @@ checkmisc: cmp [ctrl_alt_del], 1 jne nocpustart - mov ebp, cpustring - call fs_execute_from_sysdir + mov ebp, cpustring + call fs_execute_from_sysdir mov [ctrl_alt_del], 0 @@ -3542,24 +3542,24 @@ nocpustart: jne mouse_not_active mov [mouse_active], 0 xor edi, edi - mov ecx, [TASK_COUNT] + mov ecx, [TASK_COUNT] set_mouse_event: add edi, 256 - or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b + or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b loop set_mouse_event mouse_not_active: - cmp [REDRAW_BACKGROUND],byte 0 ; background update ? - jz nobackgr + cmp [REDRAW_BACKGROUND],byte 0 ; background update ? + jz nobackgr cmp [background_defined], 0 - jz nobackgr + jz nobackgr cmp [REDRAW_BACKGROUND], byte 2 jnz no_set_bgr_event xor edi, edi - mov ecx, [TASK_COUNT] + mov ecx, [TASK_COUNT] set_bgr_event: add edi, 256 - or [edi+SLOT_BASE+APPDATA.event_mask], 16 + or [edi+SLOT_BASE+APPDATA.event_mask], 16 loop set_bgr_event no_set_bgr_event: ; mov [draw_data+32 + RECT.left],dword 0 @@ -3577,7 +3577,7 @@ nobackgr: ; system shutdown request cmp [SYS_SHUTDOWN],byte 0 - je noshutdown + je noshutdown mov edx,[shutdown_processes] @@ -3598,21 +3598,21 @@ markz: call [_display.disable_mouse] dec byte [SYS_SHUTDOWN] - je system_shutdown + je system_shutdown noshutdown: - mov eax,[TASK_COUNT] ; termination + mov eax,[TASK_COUNT] ; termination mov ebx,TASK_DATA+TASKDATA.state mov esi,1 newct: mov cl,[ebx] cmp cl,byte 3 - jz terminate + jz terminate cmp cl,byte 4 - jz terminate + jz terminate add ebx,0x20 inc esi @@ -3626,145 +3626,145 @@ redrawscreen: ; eax , if process window_data base is eax, do not set flag/limits - pushad - push eax + pushad + push eax ;;; mov ebx,2 ;;; call delay_hs - ;mov ecx,0 ; redraw flags for apps - xor ecx,ecx + ;mov ecx,0 ; redraw flags for apps + xor ecx,ecx newdw2: - inc ecx - push ecx + inc ecx + push ecx - mov eax,ecx - shl eax,5 - add eax,window_data + mov eax,ecx + shl eax,5 + add eax,window_data - cmp eax,[esp+4] - je not_this_task - ; check if window in redraw area - mov edi,eax + cmp eax,[esp+4] + je not_this_task + ; check if window in redraw area + mov edi,eax - cmp ecx,1 ; limit for background - jz bgli + cmp ecx,1 ; limit for background + jz bgli - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - add ecx,eax - add edx,ebx + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx,eax + add edx,ebx - mov ecx,[draw_limits.bottom] ; ecx = area y end ebx = window y start - cmp ecx,ebx - jb ricino + mov ecx,[draw_limits.bottom] ; ecx = area y end ebx = window y start + cmp ecx,ebx + jb ricino - mov ecx,[draw_limits.right] ; ecx = area x end eax = window x start - cmp ecx,eax - jb ricino + mov ecx,[draw_limits.right] ; ecx = area x end eax = window x start + cmp ecx,eax + jb ricino - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx - mov eax,[draw_limits.top] ; eax = area y start edx = window y end - cmp edx,eax - jb ricino + mov eax,[draw_limits.top] ; eax = area y start edx = window y end + cmp edx,eax + jb ricino - mov eax,[draw_limits.left] ; eax = area x start ecx = window x end - cmp ecx,eax - jb ricino + mov eax,[draw_limits.left] ; eax = area x start ecx = window x end + cmp ecx,eax + jb ricino - bgli: + bgli: - cmp ecx,1 - jnz .az - mov al,[REDRAW_BACKGROUND] - cmp al,2 - jz newdw8 - test al,al - jz .az - lea eax,[edi+draw_data-window_data] - mov ebx,[draw_limits.left] - cmp ebx,[eax+RECT.left] - jae @f - mov [eax+RECT.left],ebx - @@: - mov ebx,[draw_limits.top] - cmp ebx,[eax+RECT.top] - jae @f - mov [eax+RECT.top],ebx - @@: - mov ebx,[draw_limits.right] - cmp ebx,[eax+RECT.right] - jbe @f - mov [eax+RECT.right],ebx - @@: - mov ebx,[draw_limits.bottom] - cmp ebx,[eax+RECT.bottom] - jbe @f - mov [eax+RECT.bottom],ebx - @@: - jmp newdw8 - .az: + cmp ecx,1 + jnz .az + mov al,[REDRAW_BACKGROUND] + cmp al,2 + jz newdw8 + test al,al + jz .az + lea eax,[edi+draw_data-window_data] + mov ebx,[draw_limits.left] + cmp ebx,[eax+RECT.left] + jae @f + mov [eax+RECT.left],ebx + @@: + mov ebx,[draw_limits.top] + cmp ebx,[eax+RECT.top] + jae @f + mov [eax+RECT.top],ebx + @@: + mov ebx,[draw_limits.right] + cmp ebx,[eax+RECT.right] + jbe @f + mov [eax+RECT.right],ebx + @@: + mov ebx,[draw_limits.bottom] + cmp ebx,[eax+RECT.bottom] + jbe @f + mov [eax+RECT.bottom],ebx + @@: + jmp newdw8 + .az: - mov eax,edi - add eax,draw_data-window_data + mov eax,edi + add eax,draw_data-window_data - mov ebx,[draw_limits.left] ; set limits - mov [eax + RECT.left], ebx - mov ebx,[draw_limits.top] - mov [eax + RECT.top], ebx - mov ebx,[draw_limits.right] - mov [eax + RECT.right], ebx - mov ebx,[draw_limits.bottom] - mov [eax + RECT.bottom], ebx + mov ebx,[draw_limits.left] ; set limits + mov [eax + RECT.left], ebx + mov ebx,[draw_limits.top] + mov [eax + RECT.top], ebx + mov ebx,[draw_limits.right] + mov [eax + RECT.right], ebx + mov ebx,[draw_limits.bottom] + mov [eax + RECT.bottom], ebx - sub eax,draw_data-window_data + sub eax,draw_data-window_data - cmp dword [esp],1 - jne nobgrd - mov byte [REDRAW_BACKGROUND], 1 + cmp dword [esp],1 + jne nobgrd + mov byte [REDRAW_BACKGROUND], 1 newdw8: nobgrd: - mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw + mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw ricino: not_this_task: - pop ecx + pop ecx - cmp ecx,[TASK_COUNT] - jle newdw2 + cmp ecx,[TASK_COUNT] + jle newdw2 - pop eax - popad + pop eax + popad - ret + ret calculatebackground: ; background - mov edi, [_WinMapAddress] ; set os to use all pixels - mov eax,0x01010101 - mov ecx, [_WinMapSize] - shr ecx, 2 - rep stosd + mov edi, [_WinMapAddress] ; set os to use all pixels + mov eax,0x01010101 + mov ecx, [_WinMapSize] + shr ecx, 2 + rep stosd - mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! + mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! - ret + ret uglobal - imax dd 0x0 + imax dd 0x0 endg @@ -3772,65 +3772,65 @@ endg delay_ms: ; delay in 1/1000 sec - push eax - push ecx + push eax + push ecx - mov ecx,esi - ; - imul ecx, 33941 - shr ecx, 9 - ; + mov ecx,esi + ; + imul ecx, 33941 + shr ecx, 9 + ; - in al,0x61 - and al,0x10 - mov ah,al - cld + in al,0x61 + and al,0x10 + mov ah,al + cld - cnt1: in al,0x61 - and al,0x10 - cmp al,ah - jz cnt1 + cnt1: in al,0x61 + and al,0x10 + cmp al,ah + jz cnt1 - mov ah,al - loop cnt1 + mov ah,al + loop cnt1 - pop ecx - pop eax + pop ecx + pop eax - ret + ret set_app_param: - mov edi, [TASK_BASE] - mov eax, [edi + TASKDATA.event_mask] - mov [edi + TASKDATA.event_mask], ebx - mov [esp+32], eax - ret + mov edi, [TASK_BASE] + mov eax, [edi + TASKDATA.event_mask] + mov [edi + TASKDATA.event_mask], ebx + mov [esp+32], eax + ret delay_hs: ; delay in 1/100 secs ; ebx = delay time - push ecx - push edx + push ecx + push edx - mov edx,[timer_ticks] + mov edx,[timer_ticks] newtic: - mov ecx,[timer_ticks] - sub ecx,edx - cmp ecx,ebx - jae zerodelay + mov ecx,[timer_ticks] + sub ecx,edx + cmp ecx,ebx + jae zerodelay - call change_task + call change_task - jmp newtic + jmp newtic zerodelay: - pop edx - pop ecx + pop edx + pop ecx - ret + ret align 16 ;very often call this subrutine memmove: ; memory move in bytes @@ -3847,14 +3847,14 @@ memmove: ; memory move in bytes mov esi, eax test ecx, not 11b - jz @f + jz @f push ecx shr ecx, 2 rep movsd pop ecx and ecx, 11b - jz .finish + jz .finish @@: rep movsb @@ -3923,7 +3923,7 @@ sys_programirq: jae .not_owner mov edi, [eax + TASKDATA.pid] cmp edi, [irq_owner + 4 * ecx] - je .spril1 + je .spril1 .not_owner: xor ecx, ecx inc ecx @@ -3946,11 +3946,11 @@ sys_programirq: align 4 get_irq_data: - movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data + movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data xor bh, bh cmp ebx, 16 jae .not_owner - mov edx, [4 * ebx + irq_owner] ; check for irq owner + mov edx, [4 * ebx + irq_owner] ; check for irq owner mov eax,[TASK_BASE] @@ -3964,28 +3964,28 @@ get_irq_data: gidril1: shl ebx, 12 - lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size - mov edx, [eax] ; + 0x4 - data offset + lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size + mov edx, [eax] ; + 0x4 - data offset dec esi jz gid1 - test edx, edx ; check if buffer is empty + test edx, edx ; check if buffer is empty jz gid1 mov ebx, [eax + 0x4] mov edi, ecx - mov ecx, 4000 ; buffer size, used frequently + mov ecx, 4000 ; buffer size, used frequently - cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again + cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again jb @f xor ebx, ebx @@: - lea esi, [ebx + edx] ; calculate data size and offset + lea esi, [ebx + edx] ; calculate data size and offset cld - cmp esi, ecx ; if greater than the buffer size, begin cycle again + cmp esi, ecx ; if greater than the buffer size, begin cycle again jbe @f sub ecx, ebx @@ -4002,11 +4002,11 @@ get_irq_data: rep movsb mov edx, [eax] - mov [eax], ecx ; set data size to zero - mov [eax + 0x4], ebx ; set data offset + mov [eax], ecx ; set data size to zero + mov [eax + 0x4], ebx ; set data offset gid1: - mov [esp+32], edx ; eax + mov [esp+32], edx ; eax ret @@ -4054,14 +4054,14 @@ r_f_port_area: ; pushad - cmp ecx,edx ; beginning > end ? + cmp ecx,edx ; beginning > end ? ja rpal1 cmp edx,65536 jae rpal1 mov eax,[RESERVED_PORTS] - test eax,eax ; no reserved areas ? + test eax,eax ; no reserved areas ? je rpal2 - cmp eax,255 ; max reserved + cmp eax,255 ; max reserved jae rpal1 rpal3: mov ebx,eax @@ -4087,13 +4087,13 @@ r_f_port_area: ; popad ; enable port access at port IO map cli - pushad ; start enable io map + pushad ; start enable io map cmp edx,65536 ;16384 jae no_unmask_io ; jge mov eax,ecx -; push ebp - xor ebp,ebp ; enable - eax = port +; push ebp + xor ebp,ebp ; enable - eax = port new_port_access: ; pushad call set_io_access_rights @@ -4101,9 +4101,9 @@ new_port_access: inc eax cmp eax,edx jbe new_port_access -; pop ebp +; pop ebp no_unmask_io: - popad ; end enable io map + popad ; end enable io map sti mov eax,[RESERVED_PORTS] @@ -4270,7 +4270,7 @@ drawbackground: align 4 -syscall_putimage: ; PutImage +syscall_putimage: ; PutImage sys_putimage: test ecx,0x80008000 jnz .exit @@ -4281,40 +4281,40 @@ sys_putimage: .exit: ret @@: - mov edi,[current_slot] - add dx,word[edi+APPDATA.wnd_clientbox.top] - rol edx,16 - add dx,word[edi+APPDATA.wnd_clientbox.left] - rol edx,16 + mov edi,[current_slot] + add dx,word[edi+APPDATA.wnd_clientbox.top] + rol edx,16 + add dx,word[edi+APPDATA.wnd_clientbox.left] + rol edx,16 .forced: - push ebp esi 0 - mov ebp, putimage_get24bpp - mov esi, putimage_init24bpp + push ebp esi 0 + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp sys_putimage_bpp: ; call [disable_mouse] ; this will be done in xxx_putimage ; mov eax, vga_putimage - cmp [SCR_MODE], word 0x12 - jz @f ;.doit - mov eax, vesa12_putimage - cmp [SCR_MODE], word 0100000000000000b - jae @f - cmp [SCR_MODE], word 0x13 - jnz .doit + cmp [SCR_MODE], word 0x12 + jz @f ;.doit + mov eax, vesa12_putimage + cmp [SCR_MODE], word 0100000000000000b + jae @f + cmp [SCR_MODE], word 0x13 + jnz .doit @@: - mov eax, vesa20_putimage + mov eax, vesa20_putimage .doit: - inc [mouse_pause] - call eax - dec [mouse_pause] - pop ebp esi ebp - jmp [draw_pointer] + inc [mouse_pause] + call eax + dec [mouse_pause] + pop ebp esi ebp + jmp [draw_pointer] syscall_putimage_palette: - mov edi, esi - mov esi, edx - mov edx, ecx - mov ecx, ebx - mov ebx, eax + mov edi, esi + mov esi, edx + mov edx, ecx + mov ecx, ebx + mov ebx, eax sys_putimage_palette: ; ebx = pointer to image ; ecx = [xsize]*65536 + [ysize] @@ -4322,282 +4322,282 @@ sys_putimage_palette: ; esi = number of bits per pixel, must be 8, 24 or 32 ; edi = pointer to palette ; ebp = row delta - mov eax, [CURRENT_TASK] - shl eax, 8 - add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] - rol edx, 16 - add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] - rol edx, 16 + mov eax, [CURRENT_TASK] + shl eax, 8 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol edx, 16 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol edx, 16 .forced: - cmp esi, 1 - jnz @f - push edi - mov eax, [edi+4] - sub eax, [edi] - push eax - push dword [edi] - push 0ffffff80h - mov edi, esp - call put_mono_image - add esp, 12 - pop edi - ret + cmp esi, 1 + jnz @f + push edi + mov eax, [edi+4] + sub eax, [edi] + push eax + push dword [edi] + push 0ffffff80h + mov edi, esp + call put_mono_image + add esp, 12 + pop edi + ret @@: - cmp esi, 2 - jnz @f - push edi - push 0ffffff80h - mov edi, esp - call put_2bit_image - pop eax - pop edi - ret + cmp esi, 2 + jnz @f + push edi + push 0ffffff80h + mov edi, esp + call put_2bit_image + pop eax + pop edi + ret @@: - cmp esi, 4 - jnz @f - push edi - push 0ffffff80h - mov edi, esp - call put_4bit_image - pop eax - pop edi - ret + cmp esi, 4 + jnz @f + push edi + push 0ffffff80h + mov edi, esp + call put_4bit_image + pop eax + pop edi + ret @@: - push ebp esi ebp - cmp esi, 8 - jnz @f - mov ebp, putimage_get8bpp - mov esi, putimage_init8bpp - jmp sys_putimage_bpp + push ebp esi ebp + cmp esi, 8 + jnz @f + mov ebp, putimage_get8bpp + mov esi, putimage_init8bpp + jmp sys_putimage_bpp @@: - cmp esi, 15 - jnz @f - mov ebp, putimage_get15bpp - mov esi, putimage_init15bpp - jmp sys_putimage_bpp + cmp esi, 15 + jnz @f + mov ebp, putimage_get15bpp + mov esi, putimage_init15bpp + jmp sys_putimage_bpp @@: - cmp esi, 16 - jnz @f - mov ebp, putimage_get16bpp - mov esi, putimage_init16bpp - jmp sys_putimage_bpp + cmp esi, 16 + jnz @f + mov ebp, putimage_get16bpp + mov esi, putimage_init16bpp + jmp sys_putimage_bpp @@: - cmp esi, 24 - jnz @f - mov ebp, putimage_get24bpp - mov esi, putimage_init24bpp - jmp sys_putimage_bpp + cmp esi, 24 + jnz @f + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp + jmp sys_putimage_bpp @@: - cmp esi, 32 - jnz @f - mov ebp, putimage_get32bpp - mov esi, putimage_init32bpp - jmp sys_putimage_bpp + cmp esi, 32 + jnz @f + mov ebp, putimage_get32bpp + mov esi, putimage_init32bpp + jmp sys_putimage_bpp @@: - pop ebp esi ebp - ret + pop ebp esi ebp + ret put_mono_image: - push ebp esi ebp - mov ebp, putimage_get1bpp - mov esi, putimage_init1bpp - jmp sys_putimage_bpp + push ebp esi ebp + mov ebp, putimage_get1bpp + mov esi, putimage_init1bpp + jmp sys_putimage_bpp put_2bit_image: - push ebp esi ebp - mov ebp, putimage_get2bpp - mov esi, putimage_init2bpp - jmp sys_putimage_bpp + push ebp esi ebp + mov ebp, putimage_get2bpp + mov esi, putimage_init2bpp + jmp sys_putimage_bpp put_4bit_image: - push ebp esi ebp - mov ebp, putimage_get4bpp - mov esi, putimage_init4bpp - jmp sys_putimage_bpp + push ebp esi ebp + mov ebp, putimage_get4bpp + mov esi, putimage_init4bpp + jmp sys_putimage_bpp putimage_init24bpp: - lea eax, [eax*3] + lea eax, [eax*3] putimage_init8bpp: - ret + ret align 16 putimage_get24bpp: - movzx eax, byte [esi+2] - shl eax, 16 - mov ax, [esi] - add esi, 3 - ret 4 + movzx eax, byte [esi+2] + shl eax, 16 + mov ax, [esi] + add esi, 3 + ret 4 align 16 putimage_get8bpp: - movzx eax, byte [esi] - push edx - mov edx, [esp+8] - mov eax, [edx+eax*4] - pop edx - inc esi - ret 4 + movzx eax, byte [esi] + push edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + pop edx + inc esi + ret 4 putimage_init1bpp: - add eax, ecx - push ecx - add eax, 7 - add ecx, 7 - shr eax, 3 - shr ecx, 3 - sub eax, ecx - pop ecx - ret + add eax, ecx + push ecx + add eax, 7 + add ecx, 7 + shr eax, 3 + shr ecx, 3 + sub eax, ecx + pop ecx + ret align 16 putimage_get1bpp: - push edx - mov edx, [esp+8] - mov al, [edx] - add al, al - jnz @f - lodsb - adc al, al + push edx + mov edx, [esp+8] + mov al, [edx] + add al, al + jnz @f + lodsb + adc al, al @@: - mov [edx], al - sbb eax, eax - and eax, [edx+8] - add eax, [edx+4] - pop edx - ret 4 + mov [edx], al + sbb eax, eax + and eax, [edx+8] + add eax, [edx+4] + pop edx + ret 4 putimage_init2bpp: - add eax, ecx - push ecx - add ecx, 3 - add eax, 3 - shr ecx, 2 - shr eax, 2 - sub eax, ecx - pop ecx - ret + add eax, ecx + push ecx + add ecx, 3 + add eax, 3 + shr ecx, 2 + shr eax, 2 + sub eax, ecx + pop ecx + ret align 16 putimage_get2bpp: - push edx - mov edx, [esp+8] - mov al, [edx] - mov ah, al - shr al, 6 - shl ah, 2 - jnz .nonewbyte - lodsb - mov ah, al - shr al, 6 - shl ah, 2 - add ah, 1 + push edx + mov edx, [esp+8] + mov al, [edx] + mov ah, al + shr al, 6 + shl ah, 2 + jnz .nonewbyte + lodsb + mov ah, al + shr al, 6 + shl ah, 2 + add ah, 1 .nonewbyte: - mov [edx], ah - mov edx, [edx+4] - movzx eax, al - mov eax, [edx+eax*4] - pop edx - ret 4 + mov [edx], ah + mov edx, [edx+4] + movzx eax, al + mov eax, [edx+eax*4] + pop edx + ret 4 putimage_init4bpp: - add eax, ecx - push ecx - add ecx, 1 - add eax, 1 - shr ecx, 1 - shr eax, 1 - sub eax, ecx - pop ecx - ret + add eax, ecx + push ecx + add ecx, 1 + add eax, 1 + shr ecx, 1 + shr eax, 1 + sub eax, ecx + pop ecx + ret align 16 putimage_get4bpp: - push edx - mov edx, [esp+8] - add byte [edx], 80h - jc @f - movzx eax, byte [edx+1] - mov edx, [edx+4] - and eax, 0x0F - mov eax, [edx+eax*4] - pop edx - ret 4 + push edx + mov edx, [esp+8] + add byte [edx], 80h + jc @f + movzx eax, byte [edx+1] + mov edx, [edx+4] + and eax, 0x0F + mov eax, [edx+eax*4] + pop edx + ret 4 @@: - movzx eax, byte [esi] - add esi, 1 - mov [edx+1], al - shr eax, 4 - mov edx, [edx+4] - mov eax, [edx+eax*4] - pop edx - ret 4 + movzx eax, byte [esi] + add esi, 1 + mov [edx+1], al + shr eax, 4 + mov edx, [edx+4] + mov eax, [edx+eax*4] + pop edx + ret 4 putimage_init32bpp: - shl eax, 2 - ret + shl eax, 2 + ret align 16 putimage_get32bpp: - lodsd - ret 4 + lodsd + ret 4 putimage_init15bpp: putimage_init16bpp: - add eax, eax - ret + add eax, eax + ret align 16 putimage_get15bpp: ; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000 - push ecx edx - movzx eax, word [esi] - add esi, 2 - mov ecx, eax - mov edx, eax - and eax, 0x1F - and ecx, 0x1F shl 5 - and edx, 0x1F shl 10 - shl eax, 3 - shl ecx, 6 - shl edx, 9 - or eax, ecx - or eax, edx - pop edx ecx - ret 4 + push ecx edx + movzx eax, word [esi] + add esi, 2 + mov ecx, eax + mov edx, eax + and eax, 0x1F + and ecx, 0x1F shl 5 + and edx, 0x1F shl 10 + shl eax, 3 + shl ecx, 6 + shl edx, 9 + or eax, ecx + or eax, edx + pop edx ecx + ret 4 align 16 putimage_get16bpp: ; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000 - push ecx edx - movzx eax, word [esi] - add esi, 2 - mov ecx, eax - mov edx, eax - and eax, 0x1F - and ecx, 0x3F shl 5 - and edx, 0x1F shl 11 - shl eax, 3 - shl ecx, 5 - shl edx, 8 - or eax, ecx - or eax, edx - pop edx ecx - ret 4 + push ecx edx + movzx eax, word [esi] + add esi, 2 + mov ecx, eax + mov edx, eax + and eax, 0x1F + and ecx, 0x3F shl 5 + and edx, 0x1F shl 11 + shl eax, 3 + shl ecx, 5 + shl edx, 8 + or eax, ecx + or eax, edx + pop edx ecx + ret 4 ; eax x beginning ; ebx y beginning ; ecx x end - ; edx y end + ; edx y end ; edi color __sys_drawbar: - mov esi,[current_slot] - add eax,[esi+APPDATA.wnd_clientbox.left] - add ecx,[esi+APPDATA.wnd_clientbox.left] - add ebx,[esi+APPDATA.wnd_clientbox.top] - add edx,[esi+APPDATA.wnd_clientbox.top] + mov esi,[current_slot] + add eax,[esi+APPDATA.wnd_clientbox.left] + add ecx,[esi+APPDATA.wnd_clientbox.left] + add ebx,[esi+APPDATA.wnd_clientbox.top] + add edx,[esi+APPDATA.wnd_clientbox.top] .forced: inc [mouse_pause] ; call [disable_mouse] cmp [SCR_MODE],word 0x12 - je dbv20 + je dbv20 sdbv20: cmp [SCR_MODE],word 0100000000000000b jge dbv20 cmp [SCR_MODE],word 0x13 - je dbv20 + je dbv20 call vesa12_drawbar dec [mouse_pause] call [draw_pointer] @@ -4612,36 +4612,36 @@ __sys_drawbar: kb_read: - push ecx edx + push ecx edx - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kr_loop: - in al,0x64 - test al,1 - jnz kr_ready - loop kr_loop - mov ah,1 - jmp kr_exit + in al,0x64 + test al,1 + jnz kr_ready + loop kr_loop + mov ah,1 + jmp kr_exit kr_ready: - push ecx - mov ecx,32 + push ecx + mov ecx,32 kr_delay: - loop kr_delay - pop ecx - in al,0x60 - xor ah,ah + loop kr_delay + pop ecx + in al,0x60 + xor ah,ah kr_exit: - pop edx ecx + pop edx ecx - ret + ret kb_write: - push ecx edx + push ecx edx - mov dl,al + mov dl,al ; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's ; kw_loop1: ; in al,0x64 @@ -4651,75 +4651,75 @@ kb_write: ; mov ah,1 ; jmp kw_exit ; kw_ok1: - in al,0x60 - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + in al,0x60 + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kw_loop: - in al,0x64 - test al,2 - jz kw_ok - loop kw_loop - mov ah,1 - jmp kw_exit + in al,0x64 + test al,2 + jz kw_ok + loop kw_loop + mov ah,1 + jmp kw_exit kw_ok: - mov al,dl - out 0x60,al - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov al,dl + out 0x60,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kw_loop3: - in al,0x64 - test al,2 - jz kw_ok3 - loop kw_loop3 - mov ah,1 - jmp kw_exit + in al,0x64 + test al,2 + jz kw_ok3 + loop kw_loop3 + mov ah,1 + jmp kw_exit kw_ok3: - mov ah,8 + mov ah,8 kw_loop4: - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kw_loop5: - in al,0x64 - test al,1 - jnz kw_ok4 - loop kw_loop5 - dec ah - jnz kw_loop4 + in al,0x64 + test al,1 + jnz kw_ok4 + loop kw_loop5 + dec ah + jnz kw_loop4 kw_ok4: - xor ah,ah + xor ah,ah kw_exit: - pop edx ecx + pop edx ecx - ret + ret kb_cmd: - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's c_wait: - in al,0x64 - test al,2 - jz c_send - loop c_wait - jmp c_error + in al,0x64 + test al,2 + jz c_send + loop c_wait + jmp c_error c_send: - mov al,bl - out 0x64,al - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov al,bl + out 0x64,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's c_accept: - in al,0x64 - test al,2 - jz c_ok - loop c_accept + in al,0x64 + test al,2 + jz c_ok + loop c_accept c_error: - mov ah,1 - jmp c_exit + mov ah,1 + jmp c_exit c_ok: - xor ah,ah + xor ah,ah c_exit: - ret + ret setmouse: ; set mousepicture -pointer - ; ps2 mouse enable + ; ps2 mouse enable mov [MOUSE_PICTURE],dword mousepointer @@ -4741,60 +4741,60 @@ end if rerouteirqs: - cli + cli - mov al,0x11 ; icw4, edge triggered - out 0x20,al - call pic_delay - out 0xA0,al - call pic_delay + mov al,0x11 ; icw4, edge triggered + out 0x20,al + call pic_delay + out 0xA0,al + call pic_delay - mov al,0x20 ; generate 0x20 + - out 0x21,al - call pic_delay - mov al,0x28 ; generate 0x28 + - out 0xA1,al - call pic_delay + mov al,0x20 ; generate 0x20 + + out 0x21,al + call pic_delay + mov al,0x28 ; generate 0x28 + + out 0xA1,al + call pic_delay - mov al,0x04 ; slave at irq2 - out 0x21,al - call pic_delay - mov al,0x02 ; at irq9 - out 0xA1,al - call pic_delay + mov al,0x04 ; slave at irq2 + out 0x21,al + call pic_delay + mov al,0x02 ; at irq9 + out 0xA1,al + call pic_delay - mov al,0x01 ; 8086 mode - out 0x21,al - call pic_delay - out 0xA1,al - call pic_delay + mov al,0x01 ; 8086 mode + out 0x21,al + call pic_delay + out 0xA1,al + call pic_delay - mov al,255 ; mask all irq's - out 0xA1,al - call pic_delay - out 0x21,al - call pic_delay + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay - mov ecx,0x1000 - cld -picl1: call pic_delay - loop picl1 + mov ecx,0x1000 + cld +picl1: call pic_delay + loop picl1 - mov al,255 ; mask all irq's - out 0xA1,al - call pic_delay - out 0x21,al - call pic_delay + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay - cli + cli - ret + ret pic_delay: - jmp pdl1 -pdl1: ret + jmp pdl1 +pdl1: ret sys_msg_board_str: @@ -4816,43 +4816,43 @@ sys_msg_board_byte: ; in: al = byte to display ; out: nothing ; destroys: nothing - pushad - mov ecx, 2 - shl eax, 24 - jmp @f + pushad + mov ecx, 2 + shl eax, 24 + jmp @f sys_msg_board_word: ; in: ax = word to display ; out: nothing ; destroys: nothing - pushad - mov ecx, 4 - shl eax, 16 - jmp @f + pushad + mov ecx, 4 + shl eax, 16 + jmp @f sys_msg_board_dword: ; in: eax = dword to display ; out: nothing ; destroys: nothing - pushad - mov ecx, 8 + pushad + mov ecx, 8 @@: - push ecx - rol eax, 4 - push eax - and al, 0xF - cmp al, 10 - sbb al, 69h - das - mov bl, al - xor eax, eax - inc eax - call sys_msg_board - pop eax - pop ecx - loop @b - popad - ret + push ecx + rol eax, 4 + push eax + and al, 0xF + cmp al, 10 + sbb al, 69h + das + mov bl, al + xor eax, eax + inc eax + call sys_msg_board + pop eax + pop ecx + loop @b + popad + ret uglobal msg_board_data: times 4096 db 0 @@ -4864,59 +4864,59 @@ sys_msg_board: ; eax=1 : write : bl byte to write ; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al - mov ecx, [msg_board_count] - cmp eax, 1 - jne .smbl1 + mov ecx, [msg_board_count] + cmp eax, 1 + jne .smbl1 if defined debug_com_base - push dx ax + push dx ax - @@: ; Wait for empty transmit register (yes, this slows down system..) - mov dx, debug_com_base+5 - in al, dx - test al, 1 shl 5 - jz @r + @@: ; Wait for empty transmit register (yes, this slows down system..) + mov dx, debug_com_base+5 + in al, dx + test al, 1 shl 5 + jz @r - mov dx, debug_com_base ; Output the byte - mov al, bl - out dx, al + mov dx, debug_com_base ; Output the byte + mov al, bl + out dx, al - pop ax dx + pop ax dx end if - mov [msg_board_data+ecx],bl - inc ecx - and ecx, 4095 - mov [msg_board_count], ecx - mov [check_idle_semaphore], 5 - ret + mov [msg_board_data+ecx],bl + inc ecx + and ecx, 4095 + mov [msg_board_count], ecx + mov [check_idle_semaphore], 5 + ret .smbl1: - cmp eax, 2 - jne .smbl2 - test ecx, ecx - jz .smbl21 - mov eax, msg_board_data+1 - mov ebx, msg_board_data - movzx edx, byte [ebx] - call memmove - dec [msg_board_count] - mov [esp + 36], edx ;eax - mov [esp + 24], dword 1 - ret + cmp eax, 2 + jne .smbl2 + test ecx, ecx + jz .smbl21 + mov eax, msg_board_data+1 + mov ebx, msg_board_data + movzx edx, byte [ebx] + call memmove + dec [msg_board_count] + mov [esp + 36], edx ;eax + mov [esp + 24], dword 1 + ret .smbl21: - mov [esp+36], ecx - mov [esp+24], ecx + mov [esp+36], ecx + mov [esp+24], ecx .smbl2: - ret + ret sys_process_def: - mov edi, [CURRENT_TASK] + mov edi, [CURRENT_TASK] - dec eax ; 1 = set keyboard mode + dec eax ; 1 = set keyboard mode jne no_set_keyboard_setup shl edi,8 @@ -4926,7 +4926,7 @@ sys_process_def: no_set_keyboard_setup: - dec eax ; 2 = get keyboard mode + dec eax ; 2 = get keyboard mode jne no_get_keyboard_setup shl edi,8 @@ -4938,7 +4938,7 @@ sys_process_def: no_get_keyboard_setup: - dec eax ; 3 = get keyboard ctrl, alt, shift + dec eax ; 3 = get keyboard ctrl, alt, shift jne no_get_keyboard_cas ; xor eax,eax @@ -4960,70 +4960,70 @@ sys_process_def: no_get_keyboard_cas: - dec eax - jnz no_add_keyboard_hotkey + dec eax + jnz no_add_keyboard_hotkey - mov eax, hotkey_list + mov eax, hotkey_list @@: - cmp dword [eax+8], 0 - jz .found_free - add eax, 16 - cmp eax, hotkey_list+16*256 - jb @b - mov dword [esp+36], 1 - ret + cmp dword [eax+8], 0 + jz .found_free + add eax, 16 + cmp eax, hotkey_list+16*256 + jb @b + mov dword [esp+36], 1 + ret .found_free: - mov [eax+8], edi - mov [eax+4], ecx - movzx ebx, bl - lea ebx, [hotkey_scancodes+ebx*4] - mov ecx, [ebx] - mov [eax], ecx - mov [ebx], eax - mov [eax+12], ebx - jecxz @f - mov [ecx+12], eax + mov [eax+8], edi + mov [eax+4], ecx + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov ecx, [ebx] + mov [eax], ecx + mov [ebx], eax + mov [eax+12], ebx + jecxz @f + mov [ecx+12], eax @@: - and dword [esp+36], 0 - ret + and dword [esp+36], 0 + ret no_add_keyboard_hotkey: - dec eax - jnz no_del_keyboard_hotkey + dec eax + jnz no_del_keyboard_hotkey - movzx ebx, bl - lea ebx, [hotkey_scancodes+ebx*4] - mov eax, [ebx] + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov eax, [ebx] .scan: - test eax, eax - jz .notfound - cmp [eax+8], edi - jnz .next - cmp [eax+4], ecx - jz .found + test eax, eax + jz .notfound + cmp [eax+8], edi + jnz .next + cmp [eax+4], ecx + jz .found .next: - mov eax, [eax] - jmp .scan + mov eax, [eax] + jmp .scan .notfound: - mov dword [esp+36], 1 - ret + mov dword [esp+36], 1 + ret .found: - mov ecx, [eax] - jecxz @f - mov edx, [eax+12] - mov [ecx+12], edx + mov ecx, [eax] + jecxz @f + mov edx, [eax+12] + mov [ecx+12], edx @@: - mov ecx, [eax+12] - mov edx, [eax] - mov [ecx], edx - xor edx, edx - mov [eax+4], edx - mov [eax+8], edx - mov [eax+12], edx - mov [eax], edx - mov [esp+36], edx - ret + mov ecx, [eax+12] + mov edx, [eax] + mov [ecx], edx + xor edx, edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax], edx + mov [esp+36], edx + ret no_del_keyboard_hotkey: ret @@ -5031,9 +5031,9 @@ no_del_keyboard_hotkey: align 4 -sys_gs: ; direct screen access +sys_gs: ; direct screen access - cmp eax,1 ; resolution + cmp eax,1 ; resolution jne no_gs1 mov eax,[Screen_Max_X] shl eax,16 @@ -5043,14 +5043,14 @@ sys_gs: ; direct screen access ret no_gs1: - cmp eax,2 ; bits per pixel + cmp eax,2 ; bits per pixel jne no_gs2 movzx eax,byte [ScreenBPP] mov [esp+36],eax ret no_gs2: - cmp eax,3 ; bytes per scanline + cmp eax,3 ; bytes per scanline jne no_gs3 mov eax,[BytesPerScanLine] mov [esp+36],eax @@ -5072,109 +5072,109 @@ sys_pci: align 4 ; system functions -syscall_setpixel: ; SetPixel +syscall_setpixel: ; SetPixel - mov eax, ebx - mov ebx, ecx - mov ecx, edx - mov edx, [TASK_BASE] - add eax, [edx-twdw+WDATA.box.left] - add ebx, [edx-twdw+WDATA.box.top] - mov edi, [current_slot] - add eax, [edi+APPDATA.wnd_clientbox.left] - add ebx, [edi+APPDATA.wnd_clientbox.top] - xor edi, edi ; no force + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, [TASK_BASE] + add eax, [edx-twdw+WDATA.box.left] + add ebx, [edx-twdw+WDATA.box.top] + mov edi, [current_slot] + add eax, [edi+APPDATA.wnd_clientbox.left] + add ebx, [edi+APPDATA.wnd_clientbox.top] + xor edi, edi ; no force ; mov edi, 1 - call [_display.disable_mouse] - jmp [putpixel] + call [_display.disable_mouse] + jmp [putpixel] align 4 -syscall_writetext: ; WriteText +syscall_writetext: ; WriteText - mov eax,[TASK_BASE] - mov ebp,[eax-twdw+WDATA.box.left] - push esi - mov esi,[current_slot] - add ebp,[esi+APPDATA.wnd_clientbox.left] - shl ebp,16 - add ebp,[eax-twdw+WDATA.box.top] - add bp,word[esi+APPDATA.wnd_clientbox.top] - pop esi - add ebx,ebp - mov eax,edi - xor edi,edi - jmp dtext + mov eax,[TASK_BASE] + mov ebp,[eax-twdw+WDATA.box.left] + push esi + mov esi,[current_slot] + add ebp,[esi+APPDATA.wnd_clientbox.left] + shl ebp,16 + add ebp,[eax-twdw+WDATA.box.top] + add bp,word[esi+APPDATA.wnd_clientbox.top] + pop esi + add ebx,ebp + mov eax,edi + xor edi,edi + jmp dtext align 4 -syscall_openramdiskfile: ; OpenRamdiskFile +syscall_openramdiskfile: ; OpenRamdiskFile - mov eax, ebx - mov ebx, ecx - mov ecx, edx - mov edx, esi - mov esi, 12 - call fileread - mov [esp+32], eax - ret + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, 12 + call fileread + mov [esp+32], eax + ret align 4 -syscall_drawrect: ; DrawRect +syscall_drawrect: ; DrawRect - mov edi, edx ; color + gradient - and edi, 0x80FFFFFF - test bx, bx ; x.size - je .drectr - test cx, cx ; y.size - je .drectr + mov edi, edx ; color + gradient + and edi, 0x80FFFFFF + test bx, bx ; x.size + je .drectr + test cx, cx ; y.size + je .drectr - mov eax, ebx ; bad idea - mov ebx, ecx + mov eax, ebx ; bad idea + mov ebx, ecx - movzx ecx, ax ; ecx - x.size - shr eax, 16 ; eax - x.coord - movzx edx, bx ; edx - y.size - shr ebx, 16 ; ebx - y.coord - mov esi, [current_slot] + movzx ecx, ax ; ecx - x.size + shr eax, 16 ; eax - x.coord + movzx edx, bx ; edx - y.size + shr ebx, 16 ; ebx - y.coord + mov esi, [current_slot] - add eax, [esi + APPDATA.wnd_clientbox.left] - add ebx, [esi + APPDATA.wnd_clientbox.top] - add ecx, eax - add edx, ebx - jmp [drawbar] + add eax, [esi + APPDATA.wnd_clientbox.left] + add ebx, [esi + APPDATA.wnd_clientbox.top] + add ecx, eax + add edx, ebx + jmp [drawbar] .drectr: - ret + ret align 4 -syscall_getscreensize: ; GetScreenSize - mov ax, [Screen_Max_X] - shl eax, 16 - mov ax, [Screen_Max_Y] - mov [esp + 32], eax - ret +syscall_getscreensize: ; GetScreenSize + mov ax, [Screen_Max_X] + shl eax, 16 + mov ax, [Screen_Max_Y] + mov [esp + 32], eax + ret align 4 -syscall_cdaudio: ; CD +syscall_cdaudio: ; CD - cmp ebx, 4 - jb .audio - jz .eject - cmp ebx, 5 - jnz .ret + cmp ebx, 4 + jb .audio + jz .eject + cmp ebx, 5 + jnz .ret .load: - call .reserve - call LoadMedium - ;call .free + call .reserve + call LoadMedium + ;call .free jmp .free ; ret .eject: - call .reserve - call clear_CD_cache - call allow_medium_removal - call EjectMedium + call .reserve + call clear_CD_cache + call allow_medium_removal + call EjectMedium ; call .free jmp .free ; ret @@ -5185,39 +5185,39 @@ syscall_cdaudio: ; CD ret .reserve: - call reserve_cd - mov eax, ecx - shr eax, 1 - and eax, 1 - inc eax - mov [ChannelNumber], ax - mov eax, ecx - and eax, 1 - mov [DiskNumber], al - call reserve_cd_channel - and ebx, 3 - inc ebx - mov [cdpos], ebx - add ebx, ebx - mov cl, 8 - sub cl, bl - mov al, [DRIVE_DATA+1] - shr al, cl - test al, 2 - jz .free;.err - ret + call reserve_cd + mov eax, ecx + shr eax, 1 + and eax, 1 + inc eax + mov [ChannelNumber], ax + mov eax, ecx + and eax, 1 + mov [DiskNumber], al + call reserve_cd_channel + and ebx, 3 + inc ebx + mov [cdpos], ebx + add ebx, ebx + mov cl, 8 + sub cl, bl + mov al, [DRIVE_DATA+1] + shr al, cl + test al, 2 + jz .free;.err + ret .free: - call free_cd_channel - and [cd_status], 0 - ret + call free_cd_channel + and [cd_status], 0 + ret .err: - call .free + call .free ; pop eax - ret + ret align 4 -syscall_getpixel: ; GetPixel +syscall_getpixel: ; GetPixel mov ecx, [Screen_Max_X] inc ecx xor edx, edx @@ -5237,10 +5237,10 @@ syscall_getarea: ;ecx = [size x]*65536 + [size y] ;edx = [start x]*65536 + [start y] pushad - inc [mouse_pause] + inc [mouse_pause] ; Check of use of the hardware cursor. cmp [_display.disable_mouse],__sys_disable_mouse - jne @f + jne @f ; Since the test for the coordinates of the mouse should not be used, ; then use the call [disable_mouse] is not possible! cmp dword [MOUSE_VISIBLE],dword 0 @@ -5257,7 +5257,7 @@ syscall_getarea: mov ebx,edx and ebx,0xffff dec eax - dec ebx + dec ebx ; eax - x, ebx - y mov edx,ecx @@ -5265,22 +5265,22 @@ syscall_getarea: and edx,0xffff mov esi,ecx ; ecx - size x, edx - size y - - mov ebp,edx - dec ebp + + mov ebp,edx + dec ebp lea ebp,[ebp*3] - - imul ebp,esi - - mov esi,ecx - dec esi - lea esi,[esi*3] - + + imul ebp,esi + + mov esi,ecx + dec esi + lea esi,[esi*3] + add ebp,esi add ebp,edi add ebx,edx - + .start_y: push ecx edx .start_x: @@ -5297,46 +5297,46 @@ syscall_getarea: sub ebp,3 dec ecx jnz .start_x - pop edx ecx - dec ebx + pop edx ecx + dec ebx dec edx jnz .start_y - dec [mouse_pause] + dec [mouse_pause] ; Check of use of the hardware cursor. cmp [_display.disable_mouse],__sys_disable_mouse - jne @f - call [draw_pointer] + jne @f + call [draw_pointer] @@: popad ret align 4 -syscall_drawline: ; DrawLine +syscall_drawline: ; DrawLine - mov edi, [TASK_BASE] - movzx eax, word[edi-twdw+WDATA.box.left] - mov ebp, eax - mov esi, [current_slot] - add ebp, [esi+APPDATA.wnd_clientbox.left] - add ax, word[esi+APPDATA.wnd_clientbox.left] - add ebp,ebx - shl eax, 16 - movzx ebx, word[edi-twdw+WDATA.box.top] - add eax, ebp - mov ebp, ebx - add ebp, [esi+APPDATA.wnd_clientbox.top] - add bx, word[esi+APPDATA.wnd_clientbox.top] - add ebp, ecx - shl ebx, 16 - xor edi, edi - add ebx, ebp - mov ecx, edx - jmp [draw_line] + mov edi, [TASK_BASE] + movzx eax, word[edi-twdw+WDATA.box.left] + mov ebp, eax + mov esi, [current_slot] + add ebp, [esi+APPDATA.wnd_clientbox.left] + add ax, word[esi+APPDATA.wnd_clientbox.left] + add ebp,ebx + shl eax, 16 + movzx ebx, word[edi-twdw+WDATA.box.top] + add eax, ebp + mov ebp, ebx + add ebp, [esi+APPDATA.wnd_clientbox.top] + add bx, word[esi+APPDATA.wnd_clientbox.top] + add ebp, ecx + shl ebx, 16 + xor edi, edi + add ebx, ebp + mov ecx, edx + jmp [draw_line] align 4 -syscall_getirqowner: ; GetIrqOwner +syscall_getirqowner: ; GetIrqOwner cmp ebx,16 jae .err @@ -5354,7 +5354,7 @@ syscall_getirqowner: ; GetIrqOwner align 4 -syscall_reserveportarea: ; ReservePortArea and FreePortArea +syscall_reserveportarea: ; ReservePortArea and FreePortArea call r_f_port_area mov [esp+32],eax @@ -5362,7 +5362,7 @@ syscall_reserveportarea: ; ReservePortArea and FreePortArea align 4 -syscall_threads: ; CreateThreads +syscall_threads: ; CreateThreads ; eax=1 create thread ; ; ebx=thread start @@ -5377,7 +5377,7 @@ syscall_threads: ; CreateThreads align 4 -read_from_hd: ; Read from hd - fn not in use +read_from_hd: ; Read from hd - fn not in use mov edi,[TASK_BASE] add edi,TASKDATA.mem_start @@ -5392,61 +5392,61 @@ read_from_hd: ; Read from hd - fn not in use ret paleholder: - ret + ret align 4 set_screen: - cmp eax, [Screen_Max_X] - jne .set + cmp eax, [Screen_Max_X] + jne .set - cmp edx, [Screen_Max_Y] - jne .set - ret + cmp edx, [Screen_Max_Y] + jne .set + ret .set: - pushfd - cli + pushfd + cli - mov [Screen_Max_X], eax - mov [Screen_Max_Y], edx - mov [BytesPerScanLine], ecx + mov [Screen_Max_X], eax + mov [Screen_Max_Y], edx + mov [BytesPerScanLine], ecx - mov [screen_workarea.right],eax - mov [screen_workarea.bottom], edx + mov [screen_workarea.right],eax + mov [screen_workarea.bottom], edx - push ebx - push esi - push edi + push ebx + push esi + push edi - pushad + pushad - stdcall kernel_free, [_WinMapAddress] + stdcall kernel_free, [_WinMapAddress] - mov eax, [_display.width] - mul [_display.height] - mov [_WinMapSize], eax + mov eax, [_display.width] + mul [_display.height] + mov [_WinMapSize], eax - stdcall kernel_alloc, eax - mov [_WinMapAddress], eax - test eax, eax - jz .epic_fail + stdcall kernel_alloc, eax + mov [_WinMapAddress], eax + test eax, eax + jz .epic_fail - popad + popad - call repos_windows - xor eax, eax - xor ebx, ebx - mov ecx, [Screen_Max_X] - mov edx, [Screen_Max_Y] - call calculatescreen - pop edi - pop esi - pop ebx + call repos_windows + xor eax, eax + xor ebx, ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + call calculatescreen + pop edi + pop esi + pop ebx - popfd - ret + popfd + ret .epic_fail: - hlt ; Houston, we've had a problem + hlt ; Houston, we've had a problem ; --------------- APM --------------------- uglobal @@ -5462,16 +5462,16 @@ sys_apm: inc eax or dword [esp + 44], eax ; error add eax,7 - mov dword [esp + 32], eax ; 32-bit protected-mode interface not supported + mov dword [esp + 32], eax ; 32-bit protected-mode interface not supported ret @@: -; xchg eax, ecx -; xchg ebx, ecx +; xchg eax, ecx +; xchg ebx, ecx cmp dx, 3 ja @f - and [esp + 44], byte 0xfe ; emulate func 0..3 as func 0 + and [esp + 44], byte 0xfe ; emulate func 0..3 as func 0 mov eax,[apm_vf] mov [esp + 32], eax shr eax, 16 @@ -5483,15 +5483,15 @@ sys_apm: mov esi,[master_tab+(OS_BASE shr 20)] xchg [master_tab], esi push esi - mov edi, cr3 - mov cr3, edi ;flush TLB + mov edi, cr3 + mov cr3, edi ;flush TLB - call pword [apm_entry] ;call APM BIOS + call pword [apm_entry] ;call APM BIOS - xchg eax, [esp] - mov [master_tab], eax - mov eax, cr3 - mov cr3, eax + xchg eax, [esp] + mov [master_tab], eax + mov eax, cr3 + mov cr3, eax pop eax mov [esp + 4 ], edi @@ -5508,248 +5508,248 @@ sys_apm: align 4 -undefined_syscall: ; Undefined system call +undefined_syscall: ; Undefined system call mov [esp + 32], dword -1 ret align 4 -system_shutdown: ; shut down the system +system_shutdown: ; shut down the system - cmp byte [BOOT_VAR+0x9030], 1 - jne @F - ret + cmp byte [BOOT_VAR+0x9030], 1 + jne @F + ret @@: - call stop_all_services - push 3 ; stop playing cd - pop eax - call sys_cd_audio + call stop_all_services + push 3 ; stop playing cd + pop eax + call sys_cd_audio yes_shutdown_param: - cli + cli - mov eax, kernel_file ; load kernel.mnt to 0x7000:0 - push 12 - pop esi - xor ebx,ebx - or ecx,-1 - mov edx, OS_BASE+0x70000 - call fileread + mov eax, kernel_file ; load kernel.mnt to 0x7000:0 + push 12 + pop esi + xor ebx,ebx + or ecx,-1 + mov edx, OS_BASE+0x70000 + call fileread - mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0 - mov edi,OS_BASE+0x40000 - mov ecx,1000 - rep movsb + mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0 + mov edi,OS_BASE+0x40000 + mov ecx,1000 + rep movsb - mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff - mov edi, OS_BASE - mov ecx,0x10000/4 - cld - rep movsd + mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff + mov edi, OS_BASE + mov ecx,0x10000/4 + cld + rep movsd - call restorefatchain + call restorefatchain - mov al, 0xFF - out 0x21, al - out 0xA1, al + mov al, 0xFF + out 0x21, al + out 0xA1, al if 0 - mov word [OS_BASE+0x467+0],pr_mode_exit - mov word [OS_BASE+0x467+2],0x1000 + mov word [OS_BASE+0x467+0],pr_mode_exit + mov word [OS_BASE+0x467+2],0x1000 - mov al,0x0F - out 0x70,al - mov al,0x05 - out 0x71,al + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al - mov al,0xFE - out 0x64,al + mov al,0xFE + out 0x64,al - hlt - jmp $-1 + hlt + jmp $-1 else - cmp byte [OS_BASE + 0x9030], 2 - jnz no_acpi_power_off + cmp byte [OS_BASE + 0x9030], 2 + jnz no_acpi_power_off ; scan for RSDP ; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA). - movzx eax, word [OS_BASE + 0x40E] - shl eax, 4 - jz @f - mov ecx, 1024/16 - call scan_rsdp - jnc .rsdp_found + movzx eax, word [OS_BASE + 0x40E] + shl eax, 4 + jz @f + mov ecx, 1024/16 + call scan_rsdp + jnc .rsdp_found @@: ; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh. - mov eax, 0xE0000 - mov ecx, 0x2000 - call scan_rsdp - jc no_acpi_power_off + mov eax, 0xE0000 + mov ecx, 0x2000 + call scan_rsdp + jc no_acpi_power_off .rsdp_found: - mov esi, [eax+16] ; esi contains physical address of the RSDT - mov ebp, [ipc_tmp] - stdcall map_page, ebp, esi, PG_MAP - lea eax, [esi+1000h] - lea edx, [ebp+1000h] - stdcall map_page, edx, eax, PG_MAP - and esi, 0xFFF - add esi, ebp - cmp dword [esi], 'RSDT' - jnz no_acpi_power_off - mov ecx, [esi+4] - sub ecx, 24h - jbe no_acpi_power_off - shr ecx, 2 - add esi, 24h + mov esi, [eax+16] ; esi contains physical address of the RSDT + mov ebp, [ipc_tmp] + stdcall map_page, ebp, esi, PG_MAP + lea eax, [esi+1000h] + lea edx, [ebp+1000h] + stdcall map_page, edx, eax, PG_MAP + and esi, 0xFFF + add esi, ebp + cmp dword [esi], 'RSDT' + jnz no_acpi_power_off + mov ecx, [esi+4] + sub ecx, 24h + jbe no_acpi_power_off + shr ecx, 2 + add esi, 24h .scan_fadt: - lodsd - mov ebx, eax - lea eax, [ebp+2000h] - stdcall map_page, eax, ebx, PG_MAP - lea eax, [ebp+3000h] - add ebx, 0x1000 - stdcall map_page, eax, ebx, PG_MAP - and ebx, 0xFFF - lea ebx, [ebx+ebp+2000h] - cmp dword [ebx], 'FACP' - jz .fadt_found - loop .scan_fadt - jmp no_acpi_power_off + lodsd + mov ebx, eax + lea eax, [ebp+2000h] + stdcall map_page, eax, ebx, PG_MAP + lea eax, [ebp+3000h] + add ebx, 0x1000 + stdcall map_page, eax, ebx, PG_MAP + and ebx, 0xFFF + lea ebx, [ebx+ebp+2000h] + cmp dword [ebx], 'FACP' + jz .fadt_found + loop .scan_fadt + jmp no_acpi_power_off .fadt_found: ; ebx is linear address of FADT - mov edi, [ebx+40] ; physical address of the DSDT - lea eax, [ebp+4000h] - stdcall map_page, eax, edi, PG_MAP - lea eax, [ebp+5000h] - lea esi, [edi+0x1000] - stdcall map_page, eax, esi, PG_MAP - and esi, 0xFFF - sub edi, esi - cmp dword [esi+ebp+4000h], 'DSDT' - jnz no_acpi_power_off - mov eax, [esi+ebp+4004h] ; DSDT length - sub eax, 36+4 - jbe no_acpi_power_off - add esi, 36 + mov edi, [ebx+40] ; physical address of the DSDT + lea eax, [ebp+4000h] + stdcall map_page, eax, edi, PG_MAP + lea eax, [ebp+5000h] + lea esi, [edi+0x1000] + stdcall map_page, eax, esi, PG_MAP + and esi, 0xFFF + sub edi, esi + cmp dword [esi+ebp+4000h], 'DSDT' + jnz no_acpi_power_off + mov eax, [esi+ebp+4004h] ; DSDT length + sub eax, 36+4 + jbe no_acpi_power_off + add esi, 36 .scan_dsdt: - cmp dword [esi+ebp+4000h], '_S5_' - jnz .scan_dsdt_cont - cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode - jnz .scan_dsdt_cont - mov dl, [esi+ebp+4000h+6] - cmp dl, 4 ; _S5_ package must contain 4 bytes - ; ...in theory; in practice, VirtualBox has 2 bytes - ja .scan_dsdt_cont - cmp dl, 1 - jb .scan_dsdt_cont - lea esi, [esi+ebp+4000h+7] - xor ecx, ecx - cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx - jz @f - cmp byte [esi], 0xA - jnz no_acpi_power_off - inc esi - mov cl, [esi] + cmp dword [esi+ebp+4000h], '_S5_' + jnz .scan_dsdt_cont + cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode + jnz .scan_dsdt_cont + mov dl, [esi+ebp+4000h+6] + cmp dl, 4 ; _S5_ package must contain 4 bytes + ; ...in theory; in practice, VirtualBox has 2 bytes + ja .scan_dsdt_cont + cmp dl, 1 + jb .scan_dsdt_cont + lea esi, [esi+ebp+4000h+7] + xor ecx, ecx + cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx + jz @f + cmp byte [esi], 0xA + jnz no_acpi_power_off + inc esi + mov cl, [esi] @@: - inc esi - cmp dl, 2 - jb @f - cmp byte [esi], 0 - jz @f - cmp byte [esi], 0xA - jnz no_acpi_power_off - inc esi - mov ch, [esi] + inc esi + cmp dl, 2 + jb @f + cmp byte [esi], 0 + jz @f + cmp byte [esi], 0xA + jnz no_acpi_power_off + inc esi + mov ch, [esi] @@: - jmp do_acpi_power_off + jmp do_acpi_power_off .scan_dsdt_cont: - inc esi - cmp esi, 0x1000 - jb @f - sub esi, 0x1000 - add edi, 0x1000 - push eax - lea eax, [ebp+4000h] - stdcall map_page, eax, edi, PG_MAP - push PG_MAP - lea eax, [edi+1000h] - push eax - lea eax, [ebp+5000h] - push eax - stdcall map_page - pop eax + inc esi + cmp esi, 0x1000 + jb @f + sub esi, 0x1000 + add edi, 0x1000 + push eax + lea eax, [ebp+4000h] + stdcall map_page, eax, edi, PG_MAP + push PG_MAP + lea eax, [edi+1000h] + push eax + lea eax, [ebp+5000h] + push eax + stdcall map_page + pop eax @@: - dec eax - jnz .scan_dsdt - jmp no_acpi_power_off + dec eax + jnz .scan_dsdt + jmp no_acpi_power_off do_acpi_power_off: - mov edx, [ebx+48] - test edx, edx - jz .nosmi - mov al, [ebx+52] - out dx, al - mov edx, [ebx+64] + mov edx, [ebx+48] + test edx, edx + jz .nosmi + mov al, [ebx+52] + out dx, al + mov edx, [ebx+64] @@: - in ax, dx - test al, 1 - jz @b + in ax, dx + test al, 1 + jz @b .nosmi: - and cx, 0x0707 - shl cx, 2 - or cx, 0x2020 - mov edx, [ebx+64] - in ax, dx - and ax, 203h - or ah, cl - out dx, ax - mov edx, [ebx+68] - test edx, edx - jz @f - in ax, dx - and ax, 203h - or ah, ch - out dx, ax + and cx, 0x0707 + shl cx, 2 + or cx, 0x2020 + mov edx, [ebx+64] + in ax, dx + and ax, 203h + or ah, cl + out dx, ax + mov edx, [ebx+68] + test edx, edx + jz @f + in ax, dx + and ax, 203h + or ah, ch + out dx, ax @@: - jmp $ + jmp $ no_acpi_power_off: - mov word [OS_BASE+0x467+0],pr_mode_exit - mov word [OS_BASE+0x467+2],0x1000 + mov word [OS_BASE+0x467+0],pr_mode_exit + mov word [OS_BASE+0x467+2],0x1000 - mov al,0x0F - out 0x70,al - mov al,0x05 - out 0x71,al + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al - mov al,0xFE - out 0x64,al + mov al,0xFE + out 0x64,al - hlt - jmp $-1 + hlt + jmp $-1 scan_rsdp: - add eax, OS_BASE + add eax, OS_BASE .s: - cmp dword [eax], 'RSD ' - jnz .n - cmp dword [eax+4], 'PTR ' - jnz .n - xor edx, edx - xor esi, esi + cmp dword [eax], 'RSD ' + jnz .n + cmp dword [eax+4], 'PTR ' + jnz .n + xor edx, edx + xor esi, esi @@: - add dl, [eax+esi] - inc esi - cmp esi, 20 - jnz @b - test dl, dl - jz .ok + add dl, [eax+esi] + inc esi + cmp esi, 20 + jnz @b + test dl, dl + jz .ok .n: - add eax, 10h - loop .s - stc + add eax, 10h + loop .s + stc .ok: - ret + ret end if include "data32.inc" diff --git a/kernel/branches/net/network/ARP.inc b/kernel/branches/net/network/ARP.inc index 49bbd57997..1c16170011 100644 --- a/kernel/branches/net/network/ARP.inc +++ b/kernel/branches/net/network/ARP.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; ARP.INC ;; @@ -12,7 +12,7 @@ ;; Written by hidnplayr@kolibrios.org ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; -;; Version 2, June 1991 ;; +;; Version 2, June- 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -242,15 +242,14 @@ ARP_create_request: mov eax, [IP_LIST+4*edi] ; senderIP push eax - mov edi, [ETH_DRV_LIST + 4*edi] + mov edi, [NET_DRV_LIST + 4*edi] lea eax, [edi + ETH_DEVICE.mac] mov ebx, ETH_BROADCAST mov ecx, 60 ; minimum packet size mov edx, edi ;;; mov di , ETHER_ARP call ETH_create_packet - cmp edi, -1 - je .exit + jz .exit mov ecx, eax @@ -275,7 +274,7 @@ ARP_create_request: DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx push edx ecx - jmp ETH_sender + jmp NET_send .exit: add esp, 8 @@ -523,7 +522,7 @@ ARP_handler: cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet? jne .exit - call ETH_struc2dev + call NET_ptr_to_num DEBUGF 1,"ARP Request packet through device: %u\n", edi inc [ARP_PACKETS_RX+4*edi] cmp edi, -1 @@ -549,7 +548,7 @@ ARP_handler: movsd ; Move sender IP to Dest IP pop esi - mov esi, [ETH_DRV_LIST + 4*esi] + mov esi, [NET_DRV_LIST + 4*esi] lea esi, [esi + ETH_DEVICE.mac] lea edi, [edx + ARP_Packet.SenderMAC] movsd ; Copy MAC address from in MAC_LIST @@ -573,7 +572,7 @@ ARP_handler: DEBUGF 1,"ARP_Handler - Sending reply \n" - jmp ETH_sender ; And send it! + jmp NET_send ; And send it! .exit: call kernel_free diff --git a/kernel/branches/net/network/IPv4.inc b/kernel/branches/net/network/IPv4.inc index dac51465ab..e9c5fbf037 100644 --- a/kernel/branches/net/network/IPv4.inc +++ b/kernel/branches/net/network/IPv4.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; IPv4.INC ;; @@ -18,16 +18,13 @@ $Revision$ -; IP underlying protocols numbers - -ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel - -MAX_FRAGMENTS equ 16 +MAX_FRAGMENTS equ 64 MAX_IP equ MAX_NET_DEVICES +IP_MAX_INTERFACES equ MAX_IP struct IPv4_Packet .VersionAndIHL db ? ; Version[0-3 bits] and IHL(header length)[4-7 bits] - .TypeOfService db ? + .TypeOfService db ? ; precedence [7-5] minimize delay [4], maximize throughput [3], maximize riliability [2] minimize momentary cost [1] and zero [0] .TotalLength dw ? .Identification dw ? .FlagsAndFragmentOffset dw ? ; Flags[0-2] and FragmentOffset[3-15] @@ -58,13 +55,15 @@ ends align 4 uglobal - BROADCAST dd ? + IP_LIST rd MAX_IP SUBNET_LIST rd MAX_IP DNS_LIST rd MAX_IP GATEWAY_LIST rd MAX_IP + IP_PACKETS_TX rd MAX_IP IP_PACKETS_RX rd MAX_IP + FRAGMENT_LIST rb MAX_FRAGMENTS*FRAGMENT_slot.size endg @@ -83,11 +82,11 @@ align 4 IPv4_init: or eax, -1 - mov edi, BROADCAST - mov ecx, 4*MAX_IP+1 + mov edi, IP_LIST + mov ecx, 4*MAX_IP rep stosd - xor eax, eax + inc eax mov edi, FRAGMENT_LIST mov ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP rep stosd @@ -114,10 +113,12 @@ IPv4_init: ;----------------------------------------------------------------- align 4 IPv4_handler: ; TODO: implement handler for IP options - ; TODO2: add code for IPv4 sockets (raw sockets) - - DEBUGF 1,"IP_Handler - start\n" + ; TODO2: add code for raw sockets + DEBUGF 1,"IPv4_Handler, packet from: %u.%u.%u.%u ",\ + [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 + DEBUGF 1,"to: %u.%u.%u.%u\n",\ + [edx + IPv4_Packet.DestinationAddress]:1,[edx + IPv4_Packet.DestinationAddress + 1]:1,[edx + IPv4_Packet.DestinationAddress + 2]:1,[edx + IPv4_Packet.DestinationAddress + 3]:1 ;------------------------------------------- ; Check if the packet still has time to live @@ -133,61 +134,66 @@ IPv4_handler: ; TODO: implement handler for IP options cmp al , 0x05 ; IHL!= 5*4(20 bytes) jnz .has_options - ;------------------------------- -; Now, re-calcualte the checksum +; Now, re-calculate the checksum - ; Re-calculate checksum push edx ebx mov esi, edx call IPv4_checksum pop ebx edx - ; now see if it was correct cmp [edx + IPv4_Packet.HeaderChecksum], 0 jne .dump ; if checksum isn't valid then dump packet DEBUGF 1,"IPv4 Checksum is correct\n" -;------------------------------------------------------- -; Time to find out what interface this packet belongs to +;----------------------------------- +; Check if destination IP is correct -; Therefore we will scan the current list of IP's + call NET_ptr_to_num + shl edi, 2 - mov eax, [edx + IPv4_Packet.DestinationAddress] - mov edi, BROADCAST - mov ecx, MAX_IP+1 + ; check if it matches local ip - .find_ip_loop: - cmp eax, dword [edi] - jz .ip_ok - add edi, 4 - dec ecx - jnz .find_ip_loop + mov eax, dword[IP_LIST+edi] + cmp [edx + IPv4_Packet.DestinationAddress], eax + je .ip_ok - ; it was not on the list, perhaps it's a loopback ? + ; check for broadcast + + mov eax, dword[SUBNET_LIST+edi] not eax - test eax, 127 shl 24 ; 127.x.x.x - jz .ip_ok + or eax, dword[IP_LIST+edi] + cmp [edx + IPv4_Packet.DestinationAddress], eax + je .ip_ok - ; TODO: we need to check for broadcasts (other then 255.255.255.255) + ; or a special broadcast + + cmp [edx + IPv4_Packet.DestinationAddress], -1 + je .ip_ok + +; ; maybe it's a multicast then +; +; mov eax, [edx + IPv4_Packet.DestinationAddress] +; and eax, 0xff000000 +; cmp eax, 224 shl 24 +; je .ip_ok + + ; or a loopback address + + cmp eax, 127 shl 24 + je .ip_ok + + ; or it's not meant for us.. DEBUGF 2,"Destination address does not match!\n" - jmp .dump - -;--------------------------------------------------- -; Now we can update stats and find the device number +;------------------------ +; Now we can update stats .ip_ok: - call ETH_struc2dev ; TODO: make this work on other protocols too! - inc [IP_PACKETS_RX+4*edi] - DEBUGF 1,"Packet comes from %u.%u.%u.%u\n",\ - [edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1 - - - + inc [IP_PACKETS_RX+edi] ;---------------------------------- ; Check if the packet is fragmented @@ -198,14 +204,12 @@ IPv4_handler: ; TODO: implement handler for IP options test [edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f ; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets jnz .is_last_fragment - - ;------------------------------------------------------------------- ; No, it's just a regular IP packet, pass it to the higher protocols .handle_it: ; We reach here if packet hasnt been fragmented, or when it already has been re-constructed movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field - and eax, 0x0000000F ; + and eax, 0x0000000f ; shl eax, 2 ; movzx ecx, word [edx + IPv4_Packet.TotalLength] ; Calculate length of encapsulated Packet xchg cl , ch ; @@ -220,13 +224,13 @@ IPv4_handler: ; TODO: implement handler for IP options pop edx ; Offset to data (tcp/udp/icmp/.. Packet) cmp al , IP_PROTO_TCP - je TCP_handler + je TCP_input cmp al , IP_PROTO_UDP - je UDP_handler + je UDP_input cmp al , IP_PROTO_ICMP - je ICMP_handler + je ICMP_input DEBUGF 2,"unknown Internet protocol: %u\n", al @@ -351,7 +355,7 @@ IPv4_handler: ; TODO: implement handler for IP options cmp esi, -1 jne .count_bytes - mov esi, [esp+4] ;;; + mov esi, [esp+4] mov [edi + FRAGMENT_entry.NextPtr], esi ; Add this packet to the chain, this simplifies the following code mov [esi + FRAGMENT_entry.NextPtr], -1 mov [esi + FRAGMENT_entry.PrevPtr], edi @@ -463,13 +467,15 @@ IPv4_handler: ; TODO: implement handler for IP options ; ; find fragment slot ; -; IN: pointer to fragmented packet in edx ; TODO: the RFC says we should check protocol too +; IN: pointer to fragmented packet in edx ; OUT: pointer to slot in edi, -1 on error ; ;----------------------------------------------------------------- align 4 IPv4_find_fragment_slot: +;;; TODO: the RFC says we should check protocol number too + push eax ebx ecx edx mov ax , word [edx + IPv4_Packet.Identification] mov ecx, MAX_FRAGMENTS @@ -514,7 +520,7 @@ IPv4_decrease_fragment_ttls: dec [esi + FRAGMENT_slot.ttl] jnz .try_next DEBUGF 1,"Fragment slot timed-out!\n" - ; TODO: clear all entry's of timed-out slot +;;; TODO: clear all entry's of timed-out slot .try_next: add esi, 4 loop .loop @@ -524,38 +530,63 @@ IPv4_decrease_fragment_ttls: -;----------------------------------------------------------------- +;------------------------------------------------------------------ +; +; +; IN: dword [esp] = pointer to packet to be fragmented +; dword [esp+4] = buffer size +; edx = pointer to IPv4 header in that packet +; ecx = data length +; ebx = device structure +; +; OUT: / +; +;------------------------------------------------------------------ +align 4 +IPv4_fragment: + +;;; TODO: write code here + + + call kernel_free + add esp, 4 + + ret + + + + +;------------------------------------------------------------------ ; ; Create_IPv4_Packet ; ; IN: eax = dest ip ; ebx = source ip ; ecx = data length -; dx = fragment id +; dx = fragment id ;;;; ; di = protocol ; ; OUT: eax = pointer to buffer start ; ebx = pointer to device struct (needed for sending procedure) ; ecx = unchanged (packet size of embedded data) ; edx = size of complete buffer -; esi = pointer to sending procedure -; edi = pointer to start of data (-1 on error) +; edi = pointer to start of data (0 on error) ; -;----------------------------------------------------------------- ;;; TODO: create fragmented packets +;------------------------------------------------------------------ align 4 IPv4_create_packet: DEBUGF 1,"Create IPv4 Packet (size=%u)\n", ecx - cmp ecx, 1480 + cmp ecx, 65500 ; Max IPv4 packet size jg .exit_ - test ebx, ebx ; if dest ip = 0 + test ebx, ebx ; if source ip = 0 jnz .ip_ok ; and local ip is valid ; use local ip instead cmp [IP_LIST],0xffffffff ; je .ip_ok ; TODO: find solution to send broadcast - ; on device other then device 0 + ; on device other then device 0 mov ebx, [IP_LIST] ; ; .ip_ok: ; @@ -563,7 +594,7 @@ IPv4_create_packet: push ecx eax ebx dx di cmp eax, -1 - je .broadcast ; If it is broadcast, just send + je .broadcast ; If it is broadcast, just send call ARP_IP_to_MAC @@ -582,16 +613,17 @@ IPv4_create_packet: .send: call IPv4_dest_to_dev inc [IP_PACKETS_TX+4*edi] - mov edx, [ETH_DRV_LIST + 4*edi] + mov edx, [NET_DRV_LIST + 4*edi] lea eax, [edx + ETH_DEVICE.mac] mov ebx, esp mov ecx, [esp+18] ;; 18 or 22 ?? add ecx, IPv4_Packet.DataOrOptional mov di , ETHER_IPv4 - call ETH_create_packet ; TODO: figure out a way to make this work with other protocols too + ;;; TODO: detect if packet is too large for ethernet, if so, call IPv4_fragment + call ETH_create_packet ;;; TODO: figure out a way to make this work with other protocols too add esp, 6 - cmp edi, -1 - je .exit + test edi, edi + jz .exit mov [edi + IPv4_Packet.VersionAndIHL], 0x45 ; IPv4, normal length (no Optional header) mov [edi + IPv4_Packet.TypeOfService], 0 @@ -615,19 +647,19 @@ IPv4_create_packet: pop esi edx eax ecx add edi, IPv4_Packet.DataOrOptional - DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx + DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx ret .not_found: - DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" - ; TODO: QUEUE the packet to resend later! + DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n" + ;;;;;; .exit: add esp, 16 .exit_: - DEBUGF 1,"Create IPv4 Packet - failed\n" - or edi, -1 + DEBUGF 1,"Create IPv4 Packet - failed\n" + and edi, 0 ret diff --git a/kernel/branches/net/network/ethernet.inc b/kernel/branches/net/network/ethernet.inc index 60b0b0f6cc..936aaddcdb 100644 --- a/kernel/branches/net/network/ethernet.inc +++ b/kernel/branches/net/network/ethernet.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; ETHERNET.INC ;; @@ -16,17 +16,18 @@ $Revision$ -MAX_ETH_DEVICES equ MAX_NET_DEVICES ETH_QUEUE_SIZE equ 16 struct ETH_FRAME - .DstMAC dp ? ; destination MAC-address [6 bytes] - .SrcMAC dp ? ; source MAC-address [6 bytes] - .Type dw ? ; type of the upper-layer protocol [2 bytes] - .Data: ; data [46-1500 bytes] + .DstMAC dp ? ; destination MAC-address + .SrcMAC dp ? ; source MAC-address + .Type dw ? ; type of the upper-layer protocol + .Data: ; data (46-1500 bytes for a normal packet) ends -struct ETH_DEVICE +virtual at NET_DEVICE.end + + ETH_DEVICE: .unload dd ? .reset dd ? .transmit dd ? @@ -39,18 +40,11 @@ struct ETH_DEVICE .bytes_rx dq ? .packets_tx dd ? .packets_rx dd ? - .mode dd ? ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..) + .mode dd ? .name dd ? .mac dp ? -ends ; the rest of the device struct depends on the type of device - -struct eth_queue_entry - .owner dd ? - .data_ptr dd ? - .data_size dd ? - .size: -ends +end virtual align 4 iglobal @@ -60,13 +54,7 @@ endg align 4 uglobal - ETH_RUNNING dd ? - ETH_DRV_LIST rd MAX_ETH_DEVICES - ETH_IN_QUEUE rd 3*ETH_QUEUE_SIZE+3 -if QUEUE_BEFORE_SENDING - ETH_OUT_QUEUE rd 3*ETH_QUEUE_SIZE+3 -end if endg @@ -83,126 +71,11 @@ endg align 4 ETH_init: - xor eax, eax - mov edi, ETH_RUNNING - mov ecx, (1+MAX_ETH_DEVICES) - rep stosd - - init_queue ETH_IN_QUEUE - -if QUEUE_BEFORE_SENDING - init_queue ETH_OUT_QUEUE -end if + mov [ETH_RUNNING], 0 ret -;----------------------------------------------------------------- -; -; ETH_Add_Device: -; -; This function is called by ethernet drivers, -; to register each running ethernet device to the kernel -; -; IN: Pointer to device structure in ebx -; OUT: Device num in eax, -1 on error -; -;----------------------------------------------------------------- -align 4 -ETH_add_device: - - DEBUGF 1,"ETH_Add_Device: %x ", ebx - - mov eax, [ETH_RUNNING] - cmp eax, MAX_ETH_DEVICES - jge .error - - test eax, eax - jnz .notfirst - mov dword [ETH_IN_QUEUE], eax -if QUEUE_BEFORE_SENDING - mov dword [ETH_OUT_QUEUE], eax -end if - .notfirst: - - mov eax, ebx - mov ecx, MAX_ETH_DEVICES ; We need to check whole list because a device may be removed without re-organizing list - mov edi, ETH_DRV_LIST - - repne scasd ; See if device is already in the list - jz .error - - xor eax, eax - mov ecx, MAX_ETH_DEVICES - mov edi, ETH_DRV_LIST - - repne scasd ; Find empty spot in the list - jnz .error - - sub edi, 4 - mov [edi], ebx ; add device to list - - sub edi, ETH_DRV_LIST ; edi = 4*device num Calculate device number in eax - mov eax, edi ; edx = 4*device num - shr eax, 2 - - inc [ETH_RUNNING] ; Indicate that one more ethernet device is up and running - - DEBUGF 1,"- succes: %u\n",eax - ret - - .error: - or eax, -1 - DEBUGF 2,"Adding ETH device failed\n" - ret - - - - -;----------------------------------------------------------------- -; -; ETH_Remove_Device: -; -; This function is called by ethernet drivers, -; to unregister ethernet devices from the kernel -; -; IN: Pointer to device structure in ebx -; OUT: eax: -1 on error -; -;----------------------------------------------------------------- -align 4 -ETH_remove_device: - - cmp [ETH_RUNNING], 0 - je .error - - mov eax, ebx - mov ecx, MAX_ETH_DEVICES - mov edi, ETH_DRV_LIST - - repne scasd - jnz .error - - xor eax, eax - mov dword [edi-4], eax - - dec [ETH_RUNNING] - jnz .notlast - - mov dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE -if QUEUE_BEFORE_SENDING - mov dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE -end if - - .notlast: - ret - - .error: - or eax, -1 - ret - - - ;----------------------------------------------------------------- ; ; ETH_Receiver: @@ -210,65 +83,16 @@ end if ; This function is called by ethernet drivers, ; It pushes the received ethernet packets onto the eth_in_queue ; -; IN: [esp] = Pointer to buffer +; IN: [esp] = Pointer to buffer ; [esp-4] = size of buffer -; ebx = pointer to eth_device +; ebx = pointer to eth_device ; OUT: / ; ;----------------------------------------------------------------- align 4 ETH_receiver: - -; DEBUGF 1,"ETH_Receiver: " -; push ebx -; mov esi, esp -; add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail -; DEBUGF 1,"Queued packet successfully\n" -; add esp, 4*3 -; -; ret -; -; .fail: -; DEBUGF 1,"ETH_IN_QUEUE is full!\n" -; add esp, 4 -; call kernel_free -; add esp, 4 -; -; ret -; -; -; -;;----------------------------------------------------------------- -;; -;; ETH_Handler: -;; -;; Handles all queued eth packets (called from kernel's main_loop) -;; -;; IN: / -;; OUT: / -;; -;;----------------------------------------------------------------- -;align 4 -;ETH_handler: -; -; get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome -; -; push ETH_handler -; -; lodsd -; mov ebx, eax -; lodsd -; mov ecx, eax -; lodsd -; xchg eax, ecx -; push ecx -; push eax - - -;----------------------------- mov eax, [esp] mov ecx, [esp+4] -;----------------------------- DEBUGF 1,"ETH_Handler - size: %u\n", ecx cmp ecx, 60 ; check packet length @@ -290,136 +114,23 @@ ETH_receiver: DEBUGF 2,"ETH_Handler - dumping\n" call kernel_free add esp, 4 - - .gohome: - ret ; return to get more from queue / to caller - - - - -align 4 -ETH_handler: -ret - - -;----------------------------------------------------------------- -; -; ETH_sender: -; -; This function sends an ethernet packet to the correct driver. -; -; IN: Pointer to buffer in [esp] -; size of buffer in [esp+4] -; pointer to device struct in ebx -; OUT: / -; -;----------------------------------------------------------------- -align 4 -ETH_sender: -if QUEUE_BEFORE_SENDING - DEBUGF 1,"ETH_Sender: queuing for device: %x, %u bytes\n", [esp], [esp + 4] - - push ebx - mov esi, esp - add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail - DEBUGF 1,"Queued packet successfully\n" - add esp, 3*4 - ret - .fail: - DEBUGF 1,"ETH_OUT_QUEUE is full!\n" - add esp, 4 - call kernel_free - add esp, 4 - - ret - - - -;----------------------------------------------------------------- -; -; ETH_send_queued: -; -; IN: / -; OUT: / -; -;----------------------------------------------------------------- -align 4 -ETH_send_queued: - - get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome - - push ETH_send_queued ; this will cause the procedure to check for more packets - ; when a single packet is handled - - mov ebx, [esi] - pushd [esi + 8] - pushd [esi + 4] - - DEBUGF 1,"dequeued packet for device %x\n", ebx -end if - call [ebx+ETH_DEVICE.transmit] ; we will return to get_from_queue macro after transmitting packet - call kernel_free - add esp, 4 ; pop (balance stack) - - .gohome: - ret - - -;----------------------------------------------------------------- -; -; ETH_struc2dev -; -; IN: pointer to device struct in ebx -; -; OUT: edi is -1 on error, device number otherwise -; -;----------------------------------------------------------------- -align 4 -ETH_struc2dev: - push ecx - - mov ecx, MAX_ETH_DEVICES - mov edi, ETH_DRV_LIST - - - .loop: - cmp ebx, [edi] - jz .found - add edi, 4 - dec ecx - jnz .loop - - or edi, -1 - - pop ecx - ret - - .found: - sub edi, ETH_DRV_LIST - shr edi, 2 - - pop ecx - ret - - ;----------------------------------------------------------------- ; ; ETH_create_packet ; -; IN: pointer to source mac in eax -; pointer to destination mac in ebx -; packet size in ecx -; device number in edx -; protocol in di +; IN: eax = pointer to source mac +; ebx = pointer to destination mac +; ecx = packet size +; edx = device number +; di = protocol ; -; OUT: edi is -1 on error, pointer to buffer otherwise -; eax points to buffer start -; ebx is pointer to device structure -; ecx is unchanged (packet size of embedded data) -; edx is size of complete buffer -; esi points to procedure wich needs to be called to send packet +; OUT: edi = 0 on error, pointer to buffer otherwise +; eax = buffer start +; ebx = to device structure +; ecx = unchanged (packet size of embedded data) +; edx = size of complete buffer ; ;----------------------------------------------------------------- align 4 @@ -427,7 +138,7 @@ ETH_create_packet: DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx - cmp ecx, 1500 + cmp ecx, 1500 ;;; jg .exit push ecx di eax ebx edx @@ -436,13 +147,13 @@ ETH_create_packet: push ecx push ecx call kernel_alloc - test eax, eax + mov edi, eax + test edi, edi jz .pop_exit pop ecx pop edx - mov edi, eax pop esi movsd movsw @@ -455,10 +166,9 @@ ETH_create_packet: lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start mov edx, ecx ; Set ebx to complete buffer size pop ecx - mov esi, ETH_sender xor ebx, ebx ;;;; TODO: Fixme - mov ebx, [ETH_DRV_LIST + ebx] + mov ebx, [NET_DRV_LIST + ebx] cmp edx, 46 + ETH_FRAME.Data ; If data size is less then 46, add padding bytes jg .continue @@ -471,12 +181,12 @@ ETH_create_packet: .pop_exit: DEBUGF 2,"Out of ram space!!\n" add esp, 18 - or edi,-1 + and edi, 0 ret .exit: DEBUGF 2,"Packet too large!\n" - or edi, -1 + and edi, 0 ret @@ -497,9 +207,20 @@ ETH_create_packet: align 4 ETH_API: + cmp bh, MAX_NET_DEVICES + jg .error movzx eax, bh shl eax, 2 + cmp bl, 7 + jz .out_queue + cmp bl, 6 + jz .in_queue + + mov eax, dword [NET_DRV_LIST + eax] + cmp [eax + NET_DEVICE.type], NET_TYPE_ETH + jne .error + test bl, bl jz .packets_tx ; 0 dec bl @@ -512,39 +233,28 @@ ETH_API: jz .read_mac ; 4 dec bl jz .write_mac ; 5 - dec bl - jz .in_queue ; 6 - dec bl - jz .out_queue ; 7 -.error: - mov eax, -1 + .error: + DEBUGF 2,"Device is not ethernet type\n" + or eax, -1 ret .packets_tx: - add eax, ETH_DRV_LIST - mov eax, dword [eax] mov eax, dword [eax + ETH_DEVICE.packets_tx] ret .packets_rx: - add eax, ETH_DRV_LIST - mov eax, dword [eax] mov eax, dword [eax + ETH_DEVICE.packets_rx] ret .bytes_tx: - add eax, ETH_DRV_LIST - mov eax, dword [eax] mov ebx, dword [eax + ETH_DEVICE.bytes_tx + 4] mov eax, dword [eax + ETH_DEVICE.bytes_tx] mov [esp+20+4], ebx ; TODO: fix this ugly code ret .bytes_rx: - add eax, ETH_DRV_LIST - mov eax, dword [eax] mov ebx, dword [eax + ETH_DEVICE.bytes_rx + 4] mov eax, dword [eax + ETH_DEVICE.bytes_rx] mov [esp+20+4], ebx ; TODO: fix this ugly code @@ -552,11 +262,6 @@ ETH_API: .read_mac: - add eax, ETH_DRV_LIST - mov eax, [eax] -; push eax -; call dword [eax + ETH_DEVICE.get_MAC] -; pop eax movzx ebx, word [eax + ETH_DEVICE.mac] mov eax, dword [eax + ETH_DEVICE.mac + 2] mov [esp+20+4], ebx ; TODO: fix this ugly code @@ -565,22 +270,24 @@ ETH_API: .write_mac: push ecx push dx - add eax, ETH_DRV_LIST - mov eax, [eax] - mov eax, dword [eax + ETH_DEVICE.set_MAC] + mov eax, [eax + ETH_DEVICE.set_MAC] call eax ret .in_queue: + if ETH_QUEUE add eax, ETH_IN_QUEUE mov eax, [eax + queue.size] + else + or eax, -1 + end if ret .out_queue: -if QUEUE_BEFORE_SENDING + if ETH_QUEUE add eax, ETH_OUT_QUEUE mov eax, [eax + queue.size] -else - mov eax, -1 -end if + else + or eax, -1 + end if ret \ No newline at end of file diff --git a/kernel/branches/net/network/icmp.inc b/kernel/branches/net/network/icmp.inc index 78ed39bd0a..c0dbd26058 100644 --- a/kernel/branches/net/network/icmp.inc +++ b/kernel/branches/net/network/icmp.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; ICMP.INC ;; @@ -21,69 +21,69 @@ $Revision$ ; ICMP types & codes -ICMP_ECHOREPLY equ 0 ; echo reply message +ICMP_ECHOREPLY equ 0 ; echo reply message -ICMP_UNREACH equ 3 - ICMP_UNREACH_NET equ 0 ; bad net - ICMP_UNREACH_HOST equ 1 ; bad host - ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol - ICMP_UNREACH_PORT equ 3 ; bad port - ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop - ICMP_UNREACH_SRCFAIL equ 5 ; src route failed - ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net - ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host - ICMP_UNREACH_ISOLATED equ 8 ; src host isolated - ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access - ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto - ICMP_UNREACH_TOSNET equ 11 ; bad tos for net - ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host - ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib - ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. - ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff +ICMP_UNREACH equ 3 +ICMP_UNREACH_NET equ 0 ; bad net +ICMP_UNREACH_HOST equ 1 ; bad host +ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol +ICMP_UNREACH_PORT equ 3 ; bad port +ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop +ICMP_UNREACH_SRCFAIL equ 5 ; src route failed +ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net +ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host +ICMP_UNREACH_ISOLATED equ 8 ; src host isolated +ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access +ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto +ICMP_UNREACH_TOSNET equ 11 ; bad tos for net +ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host +ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib +ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. +ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff -ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down +ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down -ICMP_REDIRECT equ 5 ; shorter route, codes: - ICMP_REDIRECT_NET equ 0 ; for network - ICMP_REDIRECT_HOST equ 1 ; for host - ICMP_REDIRECT_TOSNET equ 2 ; for tos and net - ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host +ICMP_REDIRECT equ 5 ; shorter route, codes: +ICMP_REDIRECT_NET equ 0 ; for network +ICMP_REDIRECT_HOST equ 1 ; for host +ICMP_REDIRECT_TOSNET equ 2 ; for tos and net +ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host -ICMP_ALTHOSTADDR equ 6 ; alternate host address -ICMP_ECHO equ 8 ; echo service -ICMP_ROUTERADVERT equ 9 ; router advertisement - ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement - ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing +ICMP_ALTHOSTADDR equ 6 ; alternate host address +ICMP_ECHO equ 8 ; echo service +ICMP_ROUTERADVERT equ 9 ; router advertisement +ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement +ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing -ICMP_ROUTERSOLICIT equ 10 ; router solicitation -ICMP_TIMXCEED equ 11 ; time exceeded, code: - ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit - ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass +ICMP_ROUTERSOLICIT equ 10 ; router solicitation +ICMP_TIMXCEED equ 11 ; time exceeded, code: +ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit +ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass -ICMP_PARAMPROB equ 12 ; ip header bad - ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr - ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent - ICMP_PARAMPROB_LENGTH equ 2 ; bad length +ICMP_PARAMPROB equ 12 ; ip header bad +ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr +ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent +ICMP_PARAMPROB_LENGTH equ 2 ; bad length -ICMP_TSTAMP equ 13 ; timestamp request -ICMP_TSTAMPREPLY equ 14 ; timestamp reply -ICMP_IREQ equ 15 ; information request -ICMP_IREQREPLY equ 16 ; information reply -ICMP_MASKREQ equ 17 ; address mask request -ICMP_MASKREPLY equ 18 ; address mask reply -ICMP_TRACEROUTE equ 30 ; traceroute -ICMP_DATACONVERR equ 31 ; data conversion error -ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect -ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you - ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here -ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req -ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply -ICMP_SKIP equ 39 ; SKIP +ICMP_TSTAMP equ 13 ; timestamp request +ICMP_TSTAMPREPLY equ 14 ; timestamp reply +ICMP_IREQ equ 15 ; information request +ICMP_IREQREPLY equ 16 ; information reply +ICMP_MASKREQ equ 17 ; address mask request +ICMP_MASKREPLY equ 18 ; address mask reply +ICMP_TRACEROUTE equ 30 ; traceroute +ICMP_DATACONVERR equ 31 ; data conversion error +ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect +ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you +ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here +ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req +ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply +ICMP_SKIP equ 39 ; SKIP -ICMP_PHOTURIS equ 40 ; Photuris - ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index - ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed - ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed +ICMP_PHOTURIS equ 40 ; Photuris +ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index +ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed +ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed @@ -130,10 +130,10 @@ ICMP_init: ;----------------------------------------------------------------- ; -; ICMP_Handler: +; ICMP_input: ; -; this procedure will send reply's to ICMP echo's -; and insert packets into sockets when needed ;;; TODO: update this to work with fragmented packets too! +; This procedure will send reply's to ICMP echo's +; and insert packets into sockets when needed ; ; IN: Pointer to buffer in [esp] ; size of buffer in [esp+4] @@ -144,20 +144,22 @@ ICMP_init: ; ;----------------------------------------------------------------- align 4 -ICMP_handler: ;TODO: works only on pure ethernet right now ! +ICMP_input: - DEBUGF 1,"ICMP_Handler - buf:%x size:%x dev:%x, size:%x, buf:%x\n", [esp], [esp+4], ebx, ecx, edx +;;; TODO: works only on pure ethernet right now ! + + DEBUGF 1,"ICMP_Handler - start\n" cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request? jne .check_sockets ;;; TODO: check checksum! - DEBUGF 1,"ICMP_Handler - is echo request, through device:%x\n", ebx + DEBUGF 1,"ICMP_Handler - echo request\n" mov byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY ; Change Packet type to reply mov word [edx + ICMP_Packet.Checksum], 0 ; Set checksum to 0, needed to calculate new checksum - call ETH_struc2dev + call NET_ptr_to_num cmp edi,-1 je .dump inc [ICMP_PACKETS_RX+4*edi] @@ -207,8 +209,8 @@ ICMP_handler: ;TODO: works only on pure ethernet right now ! pop ecx edx ebx mov word [edx + ICMP_Packet.Checksum], ax - jmp ETH_sender ; Send the reply - + jmp NET_send ; Send the reply + ; and return to caller of this proc @@ -222,12 +224,12 @@ ICMP_handler: ;TODO: works only on pure ethernet right now ! .try_more: mov ax , [edx + ICMP_Packet.Identifier] .next_socket: - mov esi, [esi + SOCKET_head.NextPtr] + mov esi, [esi + SOCKET.NextPtr] or esi, esi jz .dump - cmp [esi + SOCKET_head.Type], IP_PROTO_ICMP + cmp [esi + SOCKET.Type], IP_PROTO_ICMP jne .next_socket - cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + ICMP_SOCKET.Identifier], ax + cmp [esi + ICMP_SOCKET.Identifier], ax jne .next_socket call IPv4_dest_to_dev @@ -237,7 +239,7 @@ ICMP_handler: ;TODO: works only on pure ethernet right now ! DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi - lea ebx, [esi + SOCKET_head.lock] + lea ebx, [esi + SOCKET.lock] call wait_mutex ; Now, assign data to socket. We have socket address in esi. @@ -249,7 +251,7 @@ ICMP_handler: ;TODO: works only on pure ethernet right now ! add esp, 4 sub edx, esi mov edi, edx - jmp socket_internal_receiver +;;; jmp SOCKET_input .dump: DEBUGF 1,"ICMP_Handler - dumping\n" @@ -260,59 +262,6 @@ ICMP_handler: ;TODO: works only on pure ethernet right now ! ret -;----------------------------------------------------------------- -; -; ICMP_Handler_fragments: -; -; Called by IP_handler, -; this procedure will send reply's to ICMP echo's etc -; -; IN: Pointer to buffer in [esp] -; size of buffer in [esp+4] -; pointer to device struct in ebx -; ICMP Packet size in ecx -; pointer to ICMP Packet data in edx -; OUT: / -; -;----------------------------------------------------------------- -align 4 -ICMP_handler_fragments: ; works only on pure ethernet right now ! - - DEBUGF 1,"ICMP_Handler_fragments - start\n" - - cmp ecx, 65500 - jg .dump - - cmp byte [edx + ICMP_Packet.Type], ICMP_ECHO ; Is this an echo request? discard if not - jne .dump - - mov esi, [esp] - - sub ecx, ICMP_Packet.Data - mov eax, [esi + IPv4_Packet.SourceAddress] - mov ebx, [esi + IPv4_Packet.DestinationAddress] - push word [esi + IPv4_Packet.Identification] - - mov di , [edx + ICMP_Packet.Identifier] - shl edi, 16 - mov di , [edx + ICMP_Packet.SequenceNumber] - - mov esi, edx - add esi, ICMP_Packet.Data - pop dx - shl edx, 16 - mov dx , ICMP_ECHOREPLY shl 8 + 0 ; Type + Code - - call ICMP_create_packet - - .dump: - DEBUGF 1,"ICMP_Handler_fragments - end\n" - - call kernel_free - add esp, 4 ; pop (balance stack) - ret - - ;----------------------------------------------------------------- ; ; Note: ICMP only works on top of IP protocol :) @@ -330,7 +279,7 @@ ICMP_handler_fragments: ; works only on pure ethernet right now ! ; ;----------------------------------------------------------------- align 4 -ICMP_create_packet: +ICMP_output: DEBUGF 1,"Create ICMP Packet\n" @@ -341,9 +290,7 @@ ICMP_create_packet: shr edx, 16 call IPv4_create_packet - - cmp edi, -1 - je .exit + jz .exit DEBUGF 1,"full icmp packet size: %u\n", edx @@ -372,7 +319,7 @@ ICMP_create_packet: and cx , 3 rep movsb - sub edi, edx ;; TODO: find a better way to remember start of packet + sub edi, edx ;;; TODO: find a better way to remember start of packet mov ecx, [ebx + ETH_DEVICE.transmit] push edx edi ecx DEBUGF 1,"Sending ICMP Packet\n" diff --git a/kernel/branches/net/network/queue.inc b/kernel/branches/net/network/queue.inc index 5fb04b8c03..cdfa7b3d01 100644 --- a/kernel/branches/net/network/queue.inc +++ b/kernel/branches/net/network/queue.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; queue.inc ;; @@ -14,7 +14,7 @@ $Revision$ -; The Queues implemented by these macros for a sort of ring-buffer. +; The Queues implemented by these macros form a ring-buffer. ; The data to these queue's always looks like this: ; ; At top, you have the queue struct, wich has the size (number of currently queued packets, read and write pointers. diff --git a/kernel/branches/net/network/socket.inc b/kernel/branches/net/network/socket.inc index 88914db64e..d9863625e7 100644 --- a/kernel/branches/net/network/socket.inc +++ b/kernel/branches/net/network/socket.inc @@ -1,12 +1,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; SOCKET.INC ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; -;; based on code by mike.dld ;; +;; based on code by mike.dld ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; @@ -15,102 +15,177 @@ $Revision$ -struct SOCKET_head - .NextPtr dd ? ; pointer to next socket in list - .PrevPtr dd ? ; pointer to previous socket in list - .Number dd ? ; socket number (unique within single process) - .PID dd ? ; application process id - .Domain dd ? ; INET/UNIX/.. - .Type dd ? ; RAW/UDP/TCP/... - .Protocol dd ? ; ICMP/IPv4/ARP/ - .lock dd ? ; lock mutex - .errorcode dd ? - .end: -ends +virtual at 0 -struct IPv4_SOCKET - .LocalIP dd ? - .RemoteIP dd ? - .SequenceNumber dd ? + SOCKET: + .NextPtr dd ? ; pointer to next socket in list + .PrevPtr dd ? ; pointer to previous socket in list + .Number dd ? ; socket number - ; todo: add options (for func 8 and 9) + .lock dd ? ; lock mutex - .end: -ends + .PID dd ? ; application process id + .Domain dd ? ; INET/UNIX/.. + .Type dd ? ; RAW/UDP/TCP/... + .Protocol dd ? ; ICMP/IPv4/ARP/ + .errorcode dd ? -struct TCP_SOCKET - - .LocalPort dw ? ; In INET byte order - .RemotePort dw ? ; In INET byte order - - .backlog dw ? ; Backlog - .backlog_cur dw ? ; current size of queue for un-accept-ed connections - .last_ack_number dd ? ; used only to let application know that ACK has been received - ; todo: may be use SND_UNA instead - ; todo: may be use events which allow additional information instead - ; todo: may be count acknowledged bytes (at least it has obvious sense) - .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) - .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) - .wndsizeTimer dd ? ; window size timer - - ; Transmission control block - .state dd ? ; TCB state - .timer dd ? ; TCB timer (seconds) - - .ISS dd ? ; initial send sequence number - .IRS dd ? ; initial receive sequence number - .SND_UNA dd ? ; sequence number of unack'ed sent Packets - .SND_NXT dd ? ; next send sequence number to use - .SND_WND dd ? ; send window - .RCV_NXT dd ? ; next receive sequence number to use - .RCV_WND dd ? ; receive window - .SEG_LEN dd ? ; segment length - .SEG_WND dd ? ; segment window - - .flags db ? ; packet flags - - .end: -ends - -struct UDP_SOCKET - - .LocalPort dw ? ; In INET byte order - .RemotePort dw ? ; In INET byte order - .firstpacket db ? - - .end: -ends - -struct ICMP_SOCKET - - .Identifier dw ? ; + .options dd ? + .SO_SND.SB_CC dd ? ;;;;; socket options: number of bytes in socket + .SO_RCV.SB_CC dd ? + .state dd ? ;;;;;;;;; .end: +end virtual -ends +virtual at SOCKET.end -struct IPC_SOCKET + IP_SOCKET: + + .LocalIP dd ? + rd 3 ; for IPv6 addresses + + .RemoteIP dd ? + rd 3 ; for IPv6 addresses + + .end: +end virtual + +virtual at SOCKET.end + + SOCKET_virtual: .ConnectedTo dd ? ; Socket number of other socket this one is connected to .end: +end virtual + +virtual at IP_SOCKET.end + + TCP_SOCKET: + + .LocalPort dw ? ; In INET byte order + .RemotePort dw ? ; In INET byte order + + .backlog dw ? ; Backlog + .backlog_cur dw ? ; current size of queue for un-accept-ed connections + + .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) + .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) + + .t_state dd ? ; TCB state + .t_timer dd ? ; TCB timer (seconds) + .t_rxtshift dd ? + .t_rxtcur dd ? + .t_dupacks dd ? + .t_maxseg dd ? + .t_force dd ? + .t_flags dd ? + +;--------------- +; RFC783 page 21 + +; send sequence + .SND_UNA dd ? ; sequence number of unack'ed sent Packets + .SND_NXT dd ? ; next send sequence number to use + .SND_UP dd ? + .SND_WL1 dd ? ; window minus one + .SND_WL2 dd ? ; + .ISS dd ? ; initial send sequence number + .SND_WND dd ? ; send window + +; receive sequence + .RCV_WND dw ? ; receive window + .RCV_NXT dd ? ; next receive sequence number to use + .RCV_UP dd ? + .IRS dd ? ; initial receive sequence number + +;--------------------- +; Additional variables + +; receive variables + .RCV_ADV dd ? + +; retransmit variables + .SND_MAX dd ? + +; congestion control + .SND_CWND dd ? + .SND_SSTHRESH dd ? + +;---------------------- +; Transmit timing stuff + + .t_idle dd ? + .t_rtt dd ? + .t_rtseq dd ? + .t_srtt dd ? + .t_rttvar dd ? + .t_rttmin dd ? + .max_sndwnd dd ? + +;----------------- +; Out-of-band data + + .t_oobflags dd ? + .t_iobc dd ? + .t_softerror dd ? + + +;--------- +; RFC 1323 + + .SND_SCALE db ? ; Scale factor + .RCV_SCALE db ? + .request_r_scale db ? + .requested_s_scale dd ? + + .ts_recent dd ? + .ts_recent_age dd ? + .last_ack_sent dd ? + + .end: +end virtual + +virtual at IP_SOCKET.end + + UDP_SOCKET: + + .LocalPort dw ? ; In INET byte order + .RemotePort dw ? ; In INET byte order + .firstpacket db ? + + .end: +end virtual + +virtual at IP_SOCKET.end + + ICMP_SOCKET: + + .Identifier dw ? ; + + .end: +end virtual -ends struct socket_queue_entry +; .owner dd ? .data_ptr dd ? + .buf_ptr dd ? .data_size dd ? - .offset dd ? .size: ends + MAX_backlog equ 20 ; backlog for stream sockets SOCKETBUFFSIZE equ 4096 ; in bytes + SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket -SOCKET_QUEUE_LOCATION equ 2048 ; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start +; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start +SOCKET_QUEUE_LOCATION equ SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*socket_queue_entry.size - queue.data uglobal - net_sockets rd 2 + net_sockets rd 4 last_UDP_port dw ? ; These values give the number of the last used ephemeral port last_TCP_port dw ? ; endg @@ -129,8 +204,10 @@ endg align 4 socket_init: - mov [net_sockets], 0 - mov [net_sockets + 4], 0 + xor eax, eax + mov edi, net_sockets + mov ecx, 4 + rep stosd mov [last_UDP_port], MIN_EPHEMERAL_PORT mov [last_TCP_port], MIN_EPHEMERAL_PORT @@ -145,27 +222,27 @@ socket_init: ;----------------------------------------------------------------- align 4 sys_socket: - and ebx, 0x000000FF ; should i remove this line ? - cmp bl , 8 ; highest possible number + cmp ebx, 8 ; highest possible number jg s_error lea ebx, [.table + 4*ebx] jmp dword [ebx] .table: - dd socket_open ; 0 - dd socket_close ; 1 - dd socket_bind ; 2 - dd socket_listen ; 3 - dd socket_connect ; 4 - dd socket_accept ; 5 - dd socket_send ; 6 - dd socket_recv ; 7 - dd socket_get_opt ; 8 -; dd socket_set_opt ; 9 + dd SOCKET_open ; 0 + dd SOCKET_close ; 1 + dd SOCKET_bind ; 2 + dd SOCKET_listen ; 3 + dd SOCKET_connect ; 4 + dd SOCKET_accept ; 5 + dd SOCKET_send ; 6 + dd SOCKET_receive ; 7 + dd SOCKET_get_opt ; 8 +; dd SOCKET_set_opt ; 9 s_error: - mov dword [esp+32],-1 + DEBUGF 1,"socket error\n" + mov dword [esp+32], -1 ret @@ -174,7 +251,6 @@ s_error: ; ; SOCKET_open ; -; ; IN: domain in ecx ; type in edx ; protocol in esi @@ -182,44 +258,18 @@ s_error: ; ;----------------------------------------------------------------- align 4 -socket_open: +SOCKET_open: - DEBUGF 1,"socket_open: domain: %u, type: %u",ecx, edx + DEBUGF 1,"socket_open: domain: %u, type: %u protocol: %x\n", ecx, edx, esi - call net_socket_alloc - or eax, eax + call SOCKET_alloc jz s_error - mov [eax + SOCKET_head.Domain], ecx - mov [eax + SOCKET_head.Type], edx - mov [eax + SOCKET_head.Protocol], esi + mov [eax + SOCKET.Domain], ecx + mov [eax + SOCKET.Type], edx + mov [eax + SOCKET.Protocol], esi - cmp ecx, AF_INET4 - je .af_inet4 - - jmp .done - - - .af_inet4: - - cmp edx, IP_PROTO_TCP - je .tcp - - jmp .done - - .tcp: - - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED - - pseudo_random ebx - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS], ebx - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ebx - - .done: - stdcall net_socket_addr_to_num, eax - DEBUGF 1,", socketnumber: %u\n", eax - - mov [esp+32], eax + mov [esp+32], edi ret @@ -236,12 +286,11 @@ socket_open: ; ;----------------------------------------------------------------- align 4 -socket_bind: +SOCKET_bind: - DEBUGF 1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi + DEBUGF 1,"socket_bind: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - stdcall net_socket_num_to_addr, ecx - cmp eax, -1 + call SOCKET_num_to_ptr jz s_error cmp esi, 2 @@ -259,44 +308,44 @@ socket_bind: ; TODO: write code here - mov dword [esp+32],0 + mov dword [esp+32], 0 ret .af_inet4: + DEBUGF 1,"af_inet4\n" + cmp esi, 6 jl s_error - mov ecx, [eax + SOCKET_head.Type] + mov ecx, [eax + SOCKET.Type] mov bx, word [edx + 2] - DEBUGF 1,"local port: %x ",bx test bx, bx jz .find_free - call socket_check_port - test bx, bx - je s_error + call SOCKET_check_port +; test bx, bx + jz s_error jmp .got_port .find_free: - - call socket_find_port - test bx, bx - je s_error + call SOCKET_find_port +; test bx, bx + jz s_error .got_port: - DEBUGF 1,"using port: %x ",bx - mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx + DEBUGF 1,"using local port: %u", bx + mov word [eax + UDP_SOCKET.LocalPort], bx mov ebx, dword [edx + 4] - mov dword [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], ebx + mov dword [eax + IP_SOCKET.LocalIP], ebx DEBUGF 1,"local ip: %u.%u.%u.%u\n",\ - [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 0]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 1]:1,\ - [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 2]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 3]:1 + [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\ + [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1 - mov dword [esp+32],0 + mov dword [esp+32], 0 ret @@ -306,7 +355,6 @@ socket_bind: ; ; SOCKET_connect ; -; ; IN: socket number in ecx ; pointer to sockaddr struct in edx ; length of that struct in esi @@ -314,12 +362,11 @@ socket_bind: ; ;----------------------------------------------------------------- align 4 -socket_connect: +SOCKET_connect: - DEBUGF 1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi + DEBUGF 1,"socket_connect: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - stdcall net_socket_num_to_addr, ecx - cmp eax, -1 + call SOCKET_num_to_ptr jz s_error cmp esi, 8 @@ -332,74 +379,68 @@ socket_connect: .af_inet4: - cmp [eax + SOCKET_head.Type], IP_PROTO_UDP + cmp [eax + SOCKET.Type], IP_PROTO_UDP je .udp - cmp [eax + SOCKET_head.Type], IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP je .tcp jmp s_error .udp: - mov bx , word [edx + 2] - mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0 - DEBUGF 1,"remote port: %x ",bx + mov word [eax + UDP_SOCKET.RemotePort], bx + mov [eax + UDP_SOCKET.firstpacket], 0 + DEBUGF 1,"remote port: %u ",bx mov ebx, dword [edx + 4] - mov dword [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx + mov dword [eax + IP_SOCKET.RemoteIP], ebx DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1 - mov dword [esp+32],0 + mov dword [esp+32], 0 ret .tcp: - ; TODO: set sequence number to random value + ; set sequence number - lea ebx, [eax + SOCKET_head.lock] + mov ebx, [TCP_sequence_num] + add [TCP_sequence_num], 6400 + mov [eax + TCP_SOCKET.ISS], ebx + + lea ebx, [eax + SOCKET.lock] call wait_mutex ; fill in remote port and IP - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer. - ; TODO: figure out WTF this is +;;;;;; mov [eax + TCP_SOCKET.wndsizeTimer], 0 ; Reset the window timer. + mov bx , word [edx + 2] - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], bx - DEBUGF 1,"remote port: %x ",bx + mov [eax + TCP_SOCKET.RemotePort], bx + DEBUGF 1,"remote port: %u ",bx mov ebx, dword [edx + 4] - mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx + mov [eax + IP_SOCKET.RemoteIP], ebx ; check if local port and IP is ok - cmp [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], 0 + cmp [eax + IP_SOCKET.LocalIP], 0 jne @f - push [IP_LIST] ; device zero = default - pop [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] + push [IP_LIST] ;;;;; device zero = default + pop [eax + IP_SOCKET.LocalIP] @@: - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], 0 + cmp [eax + TCP_SOCKET.LocalPort], 0 jne @f - - mov ecx, [eax + SOCKET_head.Type] - call socket_find_port - test bx, bx - jz s_error - - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx + call SOCKET_find_port @@: +; mov [eax + TCP_SOCKET.t_state], TCB_SYN_SENT + call TCP_output - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT - ; now say hello to the remote tcp socket + mov [eax + SOCKET.lock], 0 - mov bl, TH_SYN - xor ecx, ecx - call TCP_send - - mov dword [esp+32],0 + mov dword [esp+32], 0 ; success! ret @@ -407,36 +448,38 @@ socket_connect: ; ; SOCKET_listen ; -; ; IN: socket number in ecx ; backlog in edx ; OUT: eax is socket num, -1 on error ; ;----------------------------------------------------------------- align 4 -socket_listen: +SOCKET_listen: - DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx + DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n", ecx, edx - stdcall net_socket_num_to_addr, ecx - cmp eax, -1 + call SOCKET_num_to_ptr jz s_error - cmp word [eax + SOCKET_head.Domain], AF_INET4 + cmp word [eax + SOCKET.Domain], AF_INET4 jne s_error - cmp [eax + SOCKET_head.Type], IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP jne s_error + ; TODO: check local port number + cmp edx, MAX_backlog - jb .ok - mov dx , MAX_backlog + jle .ok + mov edx, MAX_backlog .ok: - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN + mov [eax + TCP_SOCKET.backlog], dx + mov [eax + TCP_SOCKET.t_state], TCB_LISTEN + or [eax + SOCKET.options], SO_ACCEPTCON mov dword [esp+32], 0 + ret @@ -444,7 +487,6 @@ socket_listen: ; ; SOCKET_accept ; -; ; IN: socket number in ecx ; addr in edx ; addrlen in esi @@ -452,42 +494,45 @@ socket_listen: ; ;----------------------------------------------------------------- align 4 -socket_accept: +SOCKET_accept: - DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi + DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n", ecx, edx, esi - stdcall net_socket_num_to_addr, ecx - or eax, eax + call SOCKET_num_to_ptr jz s_error - mov esi, eax - cmp word [esi + SOCKET_head.Domain], AF_INET4 + cmp word [eax + SOCKET.Domain], AF_INET4 je .af_inet4 jmp s_error .af_inet4: - cmp [esi + SOCKET_head.Type], IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP je .tcp jmp s_error .tcp: - lea ebx, [esi + SOCKET_head.lock] + lea ebx, [eax + SOCKET.lock] call wait_mutex - movzx eax, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] - test eax, eax + + movzx ebx, [eax + TCP_SOCKET.backlog_cur] + test ebx, ebx jz .unlock_err - dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] - mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + (eax-1)*4] - mov [esi + SOCKET_head.lock], 0 - stdcall net_socket_addr_to_num, eax - mov [esp+32], eax + + dec [eax + TCP_SOCKET.backlog_cur] + mov eax, [eax + TCP_SOCKET.end + (ebx-1)*4] + mov [eax + SOCKET.lock], 0 + mov dword [esp+32], 0 + + call TCP_output ;;;;; + ret + .unlock_err: - mov [esi + SOCKET_head.lock], 0 + mov [eax + SOCKET.lock], 0 jmp s_error @@ -495,94 +540,55 @@ socket_accept: ; ; SOCKET_close ; -; ; IN: socket number in ecx ; OUT: eax is socket num, -1 on error ; ;----------------------------------------------------------------- align 4 -socket_close: +SOCKET_close: - DEBUGF 1,"Socket_close: socknum: %u\n",ecx + DEBUGF 1,"socket_close: socknum: %u\n", ecx - stdcall net_socket_num_to_addr, ecx - or eax, eax + call SOCKET_num_to_ptr jz s_error - cmp [eax + SOCKET_head.Domain], AF_INET4 + cmp [eax + SOCKET.Domain], AF_INET4 jne s_error - cmp [eax + SOCKET_head.Type], IP_PROTO_UDP - je .udp + cmp [eax + SOCKET.Type], IP_PROTO_UDP + je .free - cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP - je .icmp + cmp [eax + SOCKET.Type], IP_PROTO_ICMP + je .free - cmp [eax + SOCKET_head.Type], IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP je .tcp jmp s_error - .udp: - - stdcall net_socket_free, eax - mov dword [esp+32],0 - ret - - - .icmp: - - - - ret - .tcp: - mov dword [esp+32],0 + test [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED ;;;;;; + jz .free - ; first, remove all resend entries for this socket + call TCP_output - call TCP_remove_socket - -; cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN -; je .destroy_tcb -; cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_SENT -; je .destroy_tcb -; cmp [eac + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED -; je .destroy_tcb - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED - je .fin_wait - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED - je .fin_wait - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT - je .last_ack - - stdcall net_socket_free, ebx + mov dword [esp+32], 0 ret - - .last_ack: - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LAST_ACK - jmp .send_fin - - .fin_wait: - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_1 - - .send_fin: - mov bl, TH_FIN + TH_ACK - xor ecx, ecx - call TCP_send +; state must be LISTEN, SYN_SENT, CLOSED or maybe even invalid +; so, we may destroy the socket + .free: + call SOCKET_free + mov dword [esp+32], 0 ret - - ;----------------------------------------------------------------- ; ; SOCKET_receive ; -; ; IN: socket number in ecx ; addr to buffer in edx ; length of buffer in esi @@ -591,37 +597,37 @@ socket_close: ; ;----------------------------------------------------------------- align 4 -socket_recv: +SOCKET_receive: - DEBUGF 1,"Socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n",ecx,edx,esi,edi - stdcall net_socket_num_to_addr, ecx ; get real socket address - or eax, eax + DEBUGF 1,"socket_receive: socknum: %u bufaddr: %x, buflength: %u, flags: %x\n", ecx, edx, esi, edi + + call SOCKET_num_to_ptr jz s_error mov ebx, esi - - DEBUGF 1,"Socket pointer: %x\n", eax - - get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, s_error ; destroys esi and ecx + get_from_queue (eax + SOCKET_QUEUE_LOCATION),\ + SOCKET_QUEUE_SIZE,\ + socket_queue_entry.size,\ + s_error + ; destroys esi and ecx mov edi, edx ; addr to buffer - mov ecx, [esi + socket_queue_entry.data_size] + mov ecx, [esi + socket_queue_entry.data_size] DEBUGF 1,"Got %u bytes of data\n", ecx cmp ecx, ebx jle .large_enough DEBUGF 1,"Buffer too small...\n" jmp s_error + .large_enough: - - push [esi + socket_queue_entry.data_ptr] ; save the buffer addr so we can clear it later - mov esi, [esi + socket_queue_entry.offset] - add esi, [esp] ; calculate the real data offset + push [esi + socket_queue_entry.buf_ptr] ; save the buffer addr so we can clear it later + mov esi, [esi + socket_queue_entry.data_ptr] DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi + mov dword[esp+32+4], ecx ; return number of bytes copied in ebx - mov dword[esp+32+4], ecx ; return number of bytes copied - +; copy the data shr ecx, 1 jnc .nb movsb @@ -632,8 +638,11 @@ socket_recv: jz .nd rep movsd .nd: +; remove the packet ;;; TODO: only if it is empty!! - call kernel_free ; todo: check if ALL applications had the chance to receive data +;;;; call TCP_output ; only if it is tcp + + call kernel_free ret @@ -651,130 +660,76 @@ socket_recv: ; ;----------------------------------------------------------------- align 4 -socket_send: +SOCKET_send: - DEBUGF 1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi + DEBUGF 1,"socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x\n", ecx, edx, esi, edi - stdcall net_socket_num_to_addr, ecx ; get real socket address - or eax, eax + call SOCKET_num_to_ptr jz s_error - cmp word [eax + SOCKET_head.Domain], AF_INET4 + cmp word [eax + SOCKET.Domain], AF_INET4 je .af_inet4 jmp s_error .af_inet4: - DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4 + DEBUGF 1,"af_inet4\n" - cmp [eax + SOCKET_head.Type], IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP je .tcp - cmp [eax + SOCKET_head.Type], IP_PROTO_UDP + cmp [eax + SOCKET.Type], IP_PROTO_UDP je .udp - cmp [eax + SOCKET_head.Type], SOCK_RAW - je .raw - jmp s_error .udp: + DEBUGF 1,"type: UDP\n" - DEBUGF 1,"type: UDP, " - - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort],0 +; check if local port is valid + cmp [eax + UDP_SOCKET.LocalPort], 0 jne @f - push esi - mov ecx, [eax + SOCKET_head.Type] - call socket_find_port - test bx, bx - pop esi - je s_error - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx + call SOCKET_find_port + jz s_error +; Now, send the packet @@: - mov ecx, esi mov esi, edx - call UDP_socket_send + call UDP_output - and dword [esp+32], 0 + mov dword [esp+32], 0 ret .tcp: + DEBUGF 1,"type: TCP\n" - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort],0 +; check if local port is valid + cmp [eax + TCP_SOCKET.LocalPort], 0 jne @f - push esi - mov ecx, [eax + SOCKET_head.Type] - call socket_find_port - test bx, bx - pop esi - je s_error - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], bx + call SOCKET_find_port + jz s_error @@: +;;;; TODO: queue the data - mov ecx, esi - mov esi, edx - mov bl, TH_PUSH + TH_ACK - - call TCP_send - - mov [esp+32], eax - ret - - .raw: - cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP - je .raw_ip - - cmp [eax + SOCKET_head.Protocol], IP_PROTO_ICMP - je .raw_icmp - - jmp s_error - - - .raw_ip: - - ;;;;;; + call TCP_output mov [esp+32], eax ret - .raw_icmp: -; sub ecx, ICMP_Packet.Data -; mov esi, edx -; push ax -; call IPv4_get_frgmnt_num -; mov dx, ax -; pop ax -; shl edx, 16 -; mov dh , [esi + ICMP_Packet.Type] -; mov dl , [esi + ICMP_Packet.Code] -; mov di , [esi + ICMP_Packet.Identifier] -; mov [eax + SOCKET.LocalPort], di ; Set localport to the identifier number, so we can receive reply's -; shl edi, 16 -; mov di , [esi + ICMP_Packet.SequenceNumber] -; add esi, ICMP_Packet.Data -; mov ebx, [eax + SOCKET.LocalIP] -; mov eax, [eax + SOCKET.RemoteIP] -; call ICMP_create_packet - - mov [esp+32], eax - ret ;----------------------------------------------------------------- ; ; SOCKET_get_options ; -; -; IN: socket number in ecx -; edx points to the options: +; IN: ecx = socket number +; edx = pointer to the options: ; dd level, optname, optval, optlen ; OUT: -1 on error ; @@ -784,29 +739,34 @@ socket_send: ; ;----------------------------------------------------------------- align 4 -socket_get_opt: +SOCKET_get_opt: + + DEBUGF 1,"socket_get_opt\n" + + call SOCKET_num_to_ptr + jz s_error cmp dword [edx], IP_PROTO_TCP - jnz .unknown + jnz s_error cmp dword [edx+4], -2 jz @f cmp dword [edx+4], -3 - jnz .unknown + jnz s_error @@: - mov eax, [edx+12] - test eax, eax - jz .fail - cmp dword [eax], 4 - mov dword [eax], 4 - jb .fail - stdcall net_socket_num_to_addr, ecx - test eax, eax - jz .fail - ; todo: check that eax is really TCP socket - mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number] - cmp dword [edx+4], -2 - jz @f - mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] +; mov eax, [edx+12] +; test eax, eax +; jz .fail +; cmp dword [eax], 4 +; mov dword [eax], 4 +; jb .fail +; stdcall net_socket_num_to_addr, ecx +; test eax, eax +; jz .fail +; ; todo: check that eax is really TCP socket +; mov ecx, [eax + TCP_SOCKET.last_ack_number] +; cmp dword [edx+4], -2 +; jz @f +; mov ecx, [eax + TCP_SOCKET.state] @@: mov eax, [edx+8] test eax, eax @@ -815,346 +775,517 @@ socket_get_opt: @@: mov dword [esp+32], 0 ret -.fail: -.unknown: - mov dword [esp+32], -1 - ret ;----------------------------------------------------------------- ; -; SOCKET_find_free_port (local port) +; SOCKET_find_port ; -; works with INET byte order +; Fills in the local port number for TCP and UDP sockets +; This procedure always works because the number of sockets is +; limited to a smaller number then the number of possible ports ; -; IN: type in ecx (TCP/UDP) -; OUT: bx = 0 on error, portnumber otherwise +; IN: eax = socket pointer +; OUT: / ; ;----------------------------------------------------------------- align 4 -socket_find_port: +SOCKET_find_port: - DEBUGF 1,"Socket_find_free_port\n" + DEBUGF 1,"socket_find_free_port\n" - cmp ecx, IP_PROTO_UDP + push ebx esi ecx + + cmp [eax + SOCKET.Type], IP_PROTO_UDP je .udp - cmp ecx, IP_PROTO_TCP + cmp [eax + SOCKET.Type], IP_PROTO_TCP je .tcp + jmp .error + + .done: + mov [eax + UDP_SOCKET.LocalPort], bx + .error: + pop ecx esi ebx + ret + .udp: mov bx, [last_UDP_port] - je .continue + call .findit + mov [last_UDP_port], bx + jmp .done .tcp: mov bx, [last_TCP_port] + call .findit + mov [last_TCP_port], bx + jmp .done - .continue: + .restart: + mov bx, MIN_EPHEMERAL_PORT + .findit: inc bx - .check_only: - mov esi, net_sockets - - .next_socket: - mov esi, [esi + SOCKET_head.NextPtr] - or esi, esi - jz .port_ok - - cmp [esi + SOCKET_head.Type], ecx - jne .next_socket - - rol bx, 8 - cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx - rol bx, 8 ; this doesnt change the zero flag, does it ? - jne .next_socket - cmp bx, MAX_EPHEMERAL_PORT - jle .continue + jz .restart - ; todo: WRAP! -; mov [last_UDP_port], MIN_EPHEMERAL_PORT - .exit: - xor ebx, ebx + call SOCKET_check_port + jz .findit - .port_ok: - rol bx, 8 ret ;----------------------------------------------------------------- ; -; SOCKET_check_port (local port) +; SOCKET_check_port ; -; works with INET byte order +; Checks if a local port number is unused +; If the proposed port number is unused, it is filled in in the socket structure ; -; IN: type in ecx (TCP/UDP) -; port to check in bx -; OUT: bx = 0 on error, unchanged otherwise +; IN: eax = socket ptr (to find out if its a TCP/UDP socket) +; bx = proposed socket number +; +; OUT: ZF = cleared on error ; ;----------------------------------------------------------------- align 4 -socket_check_port: +SOCKET_check_port: + + DEBUGF 1,"socket_check_port\n" + + mov ecx, [eax + SOCKET.Type] mov esi, net_sockets .next_socket: - mov esi, [esi + SOCKET_head.NextPtr] + mov esi, [esi + SOCKET.NextPtr] or esi, esi jz .port_ok - cmp [esi + SOCKET_head.Type], ecx + cmp [esi + SOCKET.Type], ecx jne .next_socket - cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx + cmp [esi + UDP_SOCKET.LocalPort], bx jne .next_socket - xor ebx, ebx + DEBUGF 1,"local port %u already in use\n", bx + ret .port_ok: + mov [eax + UDP_SOCKET.LocalPort], bx + or bx, bx ; set the zero-flag + ret ;----------------------------------------------------------------- ; -; SOCKET_internal_receiver +; SOCKET_input ; ; Updates a socket with received data ; -; Note: the mutex must already be set ! +; Note: the mutex should already be set ! ; ; IN: eax = socket ptr -; ecx = size -; esi = pointer to buffer -; edi = offset +; ebx = pointer to device struct +; ecx = data size +; esi = ptr to data +; [esp] = ptr to buf +; [esp + 4] = buf size ; -; OUT: xxx +; OUT: / ; ;----------------------------------------------------------------- align 4 -socket_internal_receiver: +SOCKET_input: - DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x size=%u socket: %x\n", esi, edi, ecx, eax + DEBUGF 1,"socket_input: socket=%x, data=%x size=%u\n", eax, esi, ecx - push edi ; offset - push ecx ; size - push esi ; data_ptr + mov dword[esp+4], ecx + push esi mov esi, esp - add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, socket_queue_entry.size, notify_network_event.full + + add_to_queue (eax + SOCKET_QUEUE_LOCATION),\ + SOCKET_QUEUE_SIZE,\ + socket_queue_entry.size,\ + SOCKET_input.full + DEBUGF 1,"Queued packet successfully\n" add esp, socket_queue_entry.size + mov [eax + SOCKET.lock], 0 + jmp SOCKET_notify_owner - mov [eax + SOCKET_head.lock], 0 + .full: + DEBUGF 2,"Socket %x is full!\n", eax + mov [eax + SOCKET.lock], 0 + call kernel_free + add esp, 8 -notify_network_event: - ; flag an event to the application - mov edx, [eax + SOCKET_head.PID] ; get socket owner PID + ret + +;----------------------------------------------------------------- +; +; SOCKET_notify_owner +; +; notify's the owner of a socket that something happened +; +; IN: eax = socket ptr +; OUT: / +; +;----------------------------------------------------------------- +align 4 +SOCKET_notify_owner: + + DEBUGF 1,"socket_notify_owner\n" + + call SOCKET_check + jz .error + + push ecx eax esi + +; socket exists, now try to flag an event to the application + + mov eax, [eax + SOCKET.PID] mov ecx, 1 mov esi, TASK_DATA + TASKDATA.pid .next_pid: - cmp [esi], edx + cmp [esi], eax je .found_pid inc ecx add esi, 0x20 cmp ecx, [TASK_COUNT] jbe .next_pid - ret + +; PID not found, TODO: close socket! + + jmp .error2 .found_pid: shl ecx, 8 - or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event + or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK mov [check_idle_semaphore], 200 - ret - .full: - DEBUGF 2,"Socket %x is full!\n",eax - mov [eax + SOCKET_head.lock], 0 - call kernel_free - add esp, 8 + DEBUGF 1,"owner notified\n" + + .error2: + pop esi eax ecx + .error: + ret - +;-------------------------------------------------------------------- +; +; SOCKET_alloc +; ; Allocate memory for socket data and put new socket into the list ; Newly created socket is initialized with calling PID and number and ; put into beginning of list (which is a fastest way). ; -; @return socket structure address in EAX +; IN: / +; OUT: eax = 0 on error, socket ptr otherwise +; edi = socket number +; ZF = cleared on error ; -proc net_socket_alloc stdcall uses ebx ecx edx edi +;-------------------------------------------------------------------- +align 4 +SOCKET_alloc: + + push ecx ebx + stdcall kernel_alloc, SOCKETBUFFSIZE - DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax - ; check if we can allocate needed amount of memory + DEBUGF 1, "socket_alloc: %x ", eax or eax, eax jz .exit - ; zero-initialize allocated memory - push eax +; zero-initialize allocated memory + push eax edi mov edi, eax - mov ecx, SOCKETBUFFSIZE / 4 -; cld xor eax, eax rep stosd - pop eax + pop edi eax init_queue (eax + SOCKET_QUEUE_LOCATION) - ; add socket to the list by changing pointers - mov ebx, net_sockets - push [ebx + SOCKET_head.NextPtr] - mov [ebx + SOCKET_head.NextPtr], eax - mov [eax + SOCKET_head.PrevPtr], ebx - pop ebx - mov [eax + SOCKET_head.NextPtr], ebx - or ebx, ebx - jz @f - mov [ebx + SOCKET_head.PrevPtr], eax +; find first free socket number and use it - @@: ; set socket owner PID to the one of calling process - mov ebx, [TASK_BASE] - mov ebx, [ebx + TASKDATA.pid] - mov [eax + SOCKET_head.PID], ebx - - ; find first free socket number and use it - ;mov edx, ebx mov ebx, net_sockets xor ecx, ecx .next_socket_number: inc ecx .next_socket: - mov ebx, [ebx + SOCKET_head.NextPtr] + mov ebx, [ebx + SOCKET.NextPtr] or ebx, ebx - jz .last_socket_number - cmp [ebx + SOCKET_head.Number], ecx + jz .last_socket + cmp [ebx + SOCKET.Number], ecx jne .next_socket - ;cmp [ebx + SOCKET.PID], edx - ;jne .next_socket mov ebx, net_sockets jmp .next_socket_number - .last_socket_number: - mov [eax + SOCKET_head.Number], ecx + .last_socket: + mov [eax + SOCKET.Number], ecx - .exit: - ret -endp + DEBUGF 1, "(number: %u)\n", ecx -; Free socket data memory and pop socket off the list -; -; @param sockAddr is a socket structure address -; -proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD - mov eax, [sockAddr] - DEBUGF 1, "K : net_socket_free (0x%x)\n", eax - ; check if we got something similar to socket structure address - or eax, eax - jz .error +; Fill in PID + mov ebx, [TASK_BASE] + mov ebx, [ebx + TASKDATA.pid] - ; make sure sockAddr is one of the socket addresses in the list - mov ebx, net_sockets - ;mov ecx, [TASK_BASE] - ;mov ecx, [ecx + TASKDATA.pid] - .next_socket: - mov ebx, [ebx + SOCKET_head.NextPtr] - or ebx, ebx - jz .error - cmp ebx, eax - jne .next_socket - ;cmp [ebx + SOCKET.PID], ecx - ;jne .next_socket + mov [eax + SOCKET.PID], ebx + +; add socket to the list by changing pointers + + mov ebx, [net_sockets + SOCKET.NextPtr] + + mov [eax + SOCKET.PrevPtr], net_sockets + mov [eax + SOCKET.NextPtr], ebx - ; okay, we found the correct one - ; remove it from the list first, changing pointers - mov ebx, [eax + SOCKET_head.NextPtr] - mov eax, [eax + SOCKET_head.PrevPtr] - mov [eax + SOCKET_head.NextPtr], ebx or ebx, ebx jz @f - mov [ebx + SOCKET_head.PrevPtr], eax + add ebx, SOCKET.lock ; lock the next socket + call wait_mutex + sub ebx, SOCKET.lock + mov [ebx + SOCKET.PrevPtr], eax + mov [ebx + SOCKET.lock], 0 + @@: - lea ebx, [eax + SOCKET_head.lock] + mov [net_sockets + SOCKET.NextPtr], eax + + mov edi, ecx + or eax, eax ; used to clear zero flag + .exit: + pop ebx ecx + + ret + + +;---------------------------------------------------- +; +; SOCKET_free +; +; Free socket data memory and remove socket from the list +; +; IN: eax = socket ptr +; OUT: / +; +;---------------------------------------------------- +align 4 +SOCKET_free: + + DEBUGF 1, "socket_free: %x\n", eax + + call SOCKET_check + jz .error + + push ebx + lea ebx, [eax + SOCKET.lock] call wait_mutex - @@: ; and finally free the memory structure used - stdcall kernel_free, [sockAddr] - ret + DEBUGF 1, "freeing socket..\n" + + push eax ; this will be passed to kernel_free + mov ebx, [eax + SOCKET.NextPtr] + mov eax, [eax + SOCKET.PrevPtr] + + DEBUGF 1, "linking socket %x to socket %x\n", eax, ebx + + test eax, eax + jz @f + mov [eax + SOCKET.NextPtr], ebx + @@: + + test ebx, ebx + jz @f + mov [ebx + SOCKET.PrevPtr], eax + @@: + + call kernel_free + pop ebx + + DEBUGF 1, "socket is gone!\n" .error: - DEBUGF 1, "K : failed\n" ret -endp + +;--------------------------------------------------- +; +; SOCKET_num_to_ptr +; ; Get socket structure address by its number -; Scan through sockets list to find the socket with specified number. -; This proc uses SOCKET.PID indirectly to check if socket is owned by -; calling process. ; -; @param sockNum is a socket number -; @return socket structure address or 0 (not found) in EAX +; IN: ecx = socket number +; OUT: ecx = 0 on error, socket ptr otherwise +; ZF = set on error ; -proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD - mov eax, [sockNum] - ; check if we got something similar to socket number +;--------------------------------------------------- +align 4 +SOCKET_num_to_ptr: + + DEBUGF 1,"socket_num_to_ptr: %u ", ecx + + mov eax, net_sockets + + .next_socket: + mov eax, [eax + SOCKET.NextPtr] or eax, eax jz .error - - ; scan through sockets list - mov ebx, net_sockets - ;mov ecx, [TASK_BASE] - ;mov ecx, [ecx + TASKDATA.pid] - .next_socket: - mov ebx, [ebx + SOCKET_head.NextPtr] - or ebx, ebx - jz .error - cmp [ebx + SOCKET_head.Number], eax + cmp [eax + SOCKET.Number], ecx jne .next_socket - ;cmp [ebx + SOCKET.PID], ecx - ;jne .next_socket - ; okay, we found the correct one - mov eax, ebx + test eax, eax + + DEBUGF 1,"(%x)\n", eax + .error: ret + +;--------------------------------------------------- +; +; SOCKET_ptr_to_num +; +; Get socket number by its address +; +; IN: eax = socket ptr +; OUT: eax = 0 on error, socket num otherwise +; ZF = set on error +; +;--------------------------------------------------- +align 4 +SOCKET_ptr_to_num: + + DEBUGF 1,"socket_ptr_to_num: %x ", eax + + call SOCKET_check + jz .error + + mov eax, [eax + SOCKET.Number] + + DEBUGF 1,"(%u)\n", eax + .error: - xor eax, eax ret -endp -; Get socket number by its structure address -; Scan through sockets list to find the socket with specified address. -; This proc uses SOCKET.PID indirectly to check if socket is owned by -; calling process. -; -; @param sockAddr is a socket structure address -; @return socket number (SOCKET.Number) or 0 (not found) in EAX -; -proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD - mov eax, [sockAddr] - ; check if we got something similar to socket structure address - or eax, eax - jz .error - ; scan through sockets list +;--------------------------------------------------- +; +; SOCKET_check +; +; checks if the given value is really a socket ptr +; +; IN: eax = socket ptr +; OUT: eax = 0 on error, unchanged otherwise +; ZF = set on error +; +;--------------------------------------------------- +align 4 +SOCKET_check: + + DEBUGF 1,"socket_check\n" + + push ebx mov ebx, net_sockets - ;mov ecx, [TASK_BASE] - ;mov ecx, [ecx + TASKDATA.pid] + .next_socket: - mov ebx, [ebx + SOCKET_head.NextPtr] + mov ebx, [ebx + SOCKET.NextPtr] or ebx, ebx - jz .error + jz .done cmp ebx, eax + jnz .next_socket + + .done: + mov eax, ebx + test eax, eax + pop ebx + + ret + + + +;--------------------------------------------------- +; +; SOCKET_check_owner +; +; checks if the caller application owns the socket +; +; IN: eax = socket ptr +; OUT: ZF = true/false +; +;--------------------------------------------------- +align 4 +SOCKET_check_owner: + + DEBUGF 1,"socket_check_owner\n" + + push ebx + mov ebx, [TASK_BASE] + mov ebx, [ecx + TASKDATA.pid] + cmp [eax + SOCKET.PID], ebx + pop ebx + + ret + + + + +;--------------------------------------------------- +; +; SOCKET_process_end +; +; Kernel calls this function when a certain process ends +; This function will check if the process had any open sockets +; And update them accordingly +; +; IN: eax = pid +; OUT: / +; +;------------------------------------------------------ +align 4 +SOCKET_process_end: + + DEBUGF 1,"socket_process_end: %x\n", eax + + push ebx + mov ebx, net_sockets + + .next_socket: + + mov ebx, [ebx + SOCKET.NextPtr] + .test_socket: + test ebx, ebx + jz .done + + cmp [ebx + SOCKET.PID], eax jne .next_socket - ;cmp [ebx + SOCKET.PID], ecx - ;jne .next_socket - ; okay, we found the correct one - mov eax, [ebx + SOCKET_head.Number] - ret + DEBUGF 1,"closing socket %x", eax, ebx + + mov [ebx + SOCKET.PID], 0 + + cmp [ebx + SOCKET.Type], IP_PROTO_UDP + je .udp + + cmp [ebx + SOCKET.Type], IP_PROTO_TCP + je .tcp + + jmp .next_socket ; kill all sockets for given PID + + .udp: + mov eax, ebx + mov ebx, [ebx + SOCKET.NextPtr] + call SOCKET_free + jmp .test_socket + + .tcp: + + jmp .next_socket + + .done: + pop ebx - .error: - xor eax, eax ret -endp diff --git a/kernel/branches/net/network/stack.inc b/kernel/branches/net/network/stack.inc index 16060f016e..f075172afb 100644 --- a/kernel/branches/net/network/stack.inc +++ b/kernel/branches/net/network/stack.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; STACK.INC ;; @@ -23,19 +23,22 @@ __DEBUG_LEVEL_OLD__ equ __DEBUG_LEVEL__ __DEBUG_LEVEL__ equ 1 ; this sets the debug level for network part of kernel uglobal - last_1sTick db ? - last_1hsTick dd ? + net_10ms dd ? + net_tmr_count dw ? endg MAX_NET_DEVICES equ 16 -QUEUE_BEFORE_SENDING equ 0 ; 1 or 0 (enable or disable) currently only affects ethernet + +ETH_QUEUE equ 0 ; 1 = enable / 0 = disable MIN_EPHEMERAL_PORT equ 49152 MAX_EPHEMERAL_PORT equ 61000 -ETHER equ 1337 ; TODO: find another value for this (how does it work in posix ?) +; Ethernet protocol numbers ETHER_ARP equ 0x0608 +ETHER_IPv4 equ 0x0008 ; Reversed from 0800 for intel +;Protocol family AF_UNSPEC equ 0 AF_UNIX equ 1 AF_INET4 equ 2 @@ -46,85 +49,88 @@ AF_INET4 equ 2 ;AF_BRIDGE equ 7 ;AF_AAL5 equ 8 ;AF_X25 equ 9 -;AF_INET6 equ 10 +AF_INET6 equ 10 ;AF_MAX equ 12 +; Internet protocol numbers IP_PROTO_IP equ 0 IP_PROTO_ICMP equ 1 IP_PROTO_TCP equ 6 IP_PROTO_UDP equ 17 ; Socket types -SOCK_STREAM = 1 -SOCK_DGRAM = 2 -SOCK_RAW = 3 +SOCK_STREAM equ 1 +SOCK_DGRAM equ 2 +SOCK_RAW equ 3 -TCB_LISTEN equ 1 -TCB_SYN_SENT equ 2 -TCB_SYN_RECEIVED equ 3 -TCB_ESTABLISHED equ 4 -TCB_FIN_WAIT_1 equ 5 -TCB_FIN_WAIT_2 equ 6 -TCB_CLOSE_WAIT equ 7 -TCB_CLOSING equ 8 -TCB_LAST_ACK equ 9 -TCB_TIMED_WAIT equ 10 -TCB_CLOSED equ 11 +; Socket options +SO_ACCEPTCON equ 1 -TH_FIN equ 1 shl 0 -TH_SYN equ 1 shl 1 -TH_RST equ 1 shl 2 -TH_PUSH equ 1 shl 3 -TH_ACK equ 1 shl 4 -TH_URG equ 1 shl 5 +SOCKET_MAXDATA equ 4096 + +; Network driver types +NET_TYPE_ETH equ 1 +NET_TYPE_SLIP equ 2 -macro inc_INET reg { +virtual at 0 - add byte [reg + 3], 1 - adc byte [reg + 2], 0 - adc byte [reg + 1], 0 - adc byte [reg], 0 + NET_DEVICE: + .type dd ? + .end: -} - - -macro add_INET reg { - add byte [reg + 3], cl - adc byte [reg + 2], ch - adc byte [reg + 1], 0 - adc byte [reg], 0 - rol ecx, 16 - add byte [reg + 1], cl - adc byte [reg], ch - rol ecx, 16 -} +end virtual +; Exactly as it says.. macro pseudo_random reg { - add reg, [esp] rol reg, 5 xor reg, [timer_ticks] imul reg, 214013 xor reg, 0xdeadbeef rol reg, 9 +} - pushd reg - mov word [esp], 0x8080 ; kernel heap start addr (os_stack) - xor reg, [esp] - add esp, 4 +macro ntohld reg { + + rol word reg, 8 + rol dword reg, 16 + rol word reg, 8 } +macro ntohlw reg { + + rol word reg, 8 + +} + + include "queue.inc" + +include "ethernet.inc" +;include "slip.inc" + include "ARP.inc" include "IPv4.inc" -include "ethernet.inc" -include "socket.inc" -include "tcp.inc" -include "udp.inc" + include "icmp.inc" +include "udp.inc" +include "tcp.inc" + +include "socket.inc" + + + +align 4 +uglobal + + NET_RUNNING dd ? + NET_DRV_LIST rd MAX_NET_DEVICES + +endg + ;----------------------------------------------------------------- ; @@ -139,28 +145,37 @@ include "icmp.inc" align 4 stack_init: +; Init the network drivers list + + xor eax, eax + mov edi, NET_RUNNING + mov ecx, MAX_NET_DEVICES + 1 + rep stosd + +; Call other init procedures + call ETH_init +; call SLIP_init + call IPv4_init + call ICMP_init + call ARP_init call UDP_init call TCP_init - call ICMP_init + call socket_init - mov al, 0 ; set up 1s timer - out 0x70, al - in al, 0x71 - mov [last_1sTick], al + mov [net_tmr_count], 0 ret - ;----------------------------------------------------------------- ; ; stack_handler ; -; This function calls all network init procedures +; This function is called in kernel loop ; ; IN: / ; OUT: / @@ -169,41 +184,230 @@ stack_init: align 4 stack_handler: - cmp [ETH_RUNNING], 0 + cmp [NET_RUNNING], 0 je .exit ; Test for 10ms tick mov eax, [timer_ticks] - cmp eax, [last_1hsTick] + cmp eax, [net_10ms] je .exit + mov [net_10ms], eax - mov [last_1hsTick], eax - - call ETH_handler ; handle all queued ethernet packets -if QUEUE_BEFORE_SENDING + if ETH_QUEUE + call ETH_handler call ETH_send_queued -end if - call TCP_send_queued + end if + call TCP_10ms - .sec_tick: - - ; Test for 1 second tick - mov al, 0 - out 0x70, al - in al, 0x71 - cmp al, [last_1sTick] - je .exit - - mov [last_1sTick], al + inc [net_tmr_count] + cmp [net_tmr_count], 50 + je .500ms + cmp [net_tmr_count], 100 + jne .exit call ARP_decrease_entry_ttls call IPv4_decrease_fragment_ttls - call TCP_decrease_socket_ttls + call TCP_timer_1000ms + + mov [net_tmr_count], 0 + + .500ms: + call TCP_500ms .exit: ret + +;----------------------------------------------------------------- +; +; NET_Add_Device: +; +; This function is called by the network drivers, +; to register each running NIC to the kernel +; +; IN: Pointer to device structure in ebx +; OUT: Device num in eax, -1 on error +; +;----------------------------------------------------------------- +align 4 +NET_add_device: + + DEBUGF 1,"NET_Add_Device: %x\n", ebx + + mov eax, [NET_RUNNING] + cmp eax, MAX_NET_DEVICES + jge .error + +;---------------------------------- +; Check if device is already listed + mov eax, ebx + mov ecx, MAX_NET_DEVICES ; We need to check whole list because a device may be removed without re-organizing list + mov edi, NET_DRV_LIST + + repne scasd ; See if device is already in the list + jz .error + +;---------------------------- +; Find empty slot in the list + xor eax, eax + mov ecx, MAX_NET_DEVICES + mov edi, NET_DRV_LIST + + repne scasd + jnz .error + + sub edi, 4 + + cmp [ebx + NET_DEVICE.type], NET_TYPE_ETH + je .ethernet + + cmp [ebx + NET_DEVICE.type], NET_TYPE_SLIP + je .slip + + DEBUGF 1,"Unknown network device type: %u\n", [ebx + NET_DEVICE.type] + jmp .error + + .ethernet: + DEBUGF 1,"Trying to add an ethernet driver\n" + + inc [ETH_RUNNING] ; Indicate that one more ethernet device is up and running + jmp .add_it + + .slip: + DEBUGF 1,"Trying to add a slip driver\n" + ;;;; + jmp .error + + + .add_it: + +;----------------------------- +; Add device to the found slot + mov [edi], ebx ; add device to list + + sub edi, NET_DRV_LIST ; Calculate device number in eax + mov eax, edi ; + shr eax, 2 + + inc [NET_RUNNING] ; Indicate that one more network device is up and running + + DEBUGF 1,"Device number: %u\n",eax + ret + + .error: + or eax, -1 + DEBUGF 2,"Adding network device failed\n" + ret + + + +;----------------------------------------------------------------- +; +; NET_Remove_Device: +; +; This function is called by etwork drivers, +; to unregister network devices from the kernel +; +; IN: Pointer to device structure in ebx +; OUT: eax: -1 on error +; +;----------------------------------------------------------------- +align 4 +NET_remove_device: + + cmp [NET_RUNNING], 0 + je .error + +;---------------------------- +; Find the driver in the list + + mov eax, ebx + mov ecx, MAX_NET_DEVICES + mov edi, NET_DRV_LIST + + repne scasd + jnz .error + +;------------------------ +; Remove it from the list + + xor eax, eax + mov dword [edi-4], eax + + dec [NET_RUNNING] + ret + + .error: + or eax, -1 + ret + + + +;----------------------------------------------------------------- +; +; NET_ptr_to_num +; +; IN: ebx = ptr to device struct +; OUT: edi = -1 on error, device number otherwise +; +;----------------------------------------------------------------- +align 4 +NET_ptr_to_num: + push ecx + + mov ecx, MAX_NET_DEVICES + mov edi, NET_DRV_LIST + + .loop: + cmp ebx, [edi] + jz .found + add edi, 4 + dec ecx + jnz .loop + + ; repnz scasd could work too if eax is used instead of ebx! + + or edi, -1 + + pop ecx + ret + + .found: + sub edi, NET_DRV_LIST + shr edi, 2 + + pop ecx + ret + + + + +;-------------------------- +; +; NET_send +; +; IN: ebx = ptr to device struct +; [esp] = data ptr +; [esp + 4] = data size +; +; OUT: / +; +;-------------------------- +align 4 +NET_send: + + call [ebx + ETH_DEVICE.transmit] ;;;; + +;;; TODO:check if packet was sent ok + + call kernel_free + add esp, 4 + ret + + + + ;----------------------------------------------------------------- ; ; checksum_1 @@ -333,7 +537,7 @@ sys_network: cmp ebx, -1 jne @f - mov eax, [ETH_RUNNING] + mov eax, [NET_RUNNING] jmp .return @@: @@ -344,12 +548,12 @@ sys_network: and esi, 0x0000ff00 shr esi, 6 - cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running + cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running je .doesnt_exist - test bl, bl ; 0 = Get device type (ethernet/token ring/...) + test bl, bl ; 0 = Get device type (ethernet/token ring/...) jnz @f - ; todo + xor eax, eax jmp .return @@ -358,7 +562,7 @@ sys_network: dec bl ; 1 = Get device name jnz @f - mov esi, [esi + ETH_DRV_LIST] + mov esi, [esi + NET_DRV_LIST] mov esi, [esi + ETH_DEVICE.name] mov edi, ecx @@ -373,7 +577,7 @@ sys_network: dec bl ; 2 = Reset the device jnz @f - mov esi, [esi + ETH_DRV_LIST] + mov esi, [esi + NET_DRV_LIST] call [esi + ETH_DEVICE.reset] jmp .return @@ -382,7 +586,7 @@ sys_network: dec bl ; 3 = Stop driver for this device jnz @f - mov esi, [esi + ETH_DRV_LIST] + mov esi, [esi + NET_DRV_LIST] call [esi + ETH_DEVICE.unload] jmp .return @@ -407,7 +611,7 @@ sys_network: ;---------------------------------------------------------------- ; -; System Function To work with Protocols (75) +; System function to work with protocols (75) ; ;---------------------------------------------------------------- align 4 @@ -417,8 +621,8 @@ sys_protocols: mov esi, ebx and esi, 0x0000ff00 - shr esi, 6 - cmp dword [esi + ETH_DRV_LIST], 0 ; check if driver is running TODO: check other lists too + shr esi, 6 ; now we have the device num * 4 in esi + cmp dword [esi + NET_DRV_LIST], 0 ; check if driver is running je .doesnt_exist push .return ; return address (we will be using jumps instead of calls) @@ -441,7 +645,7 @@ sys_protocols: cmp ax , ETHER_ARP je ARP_API - cmp ax , ETHER + cmp ax , 1337 je ETH_API add esp, 4 ; if we reached here, no function was called, so we need to balance stack diff --git a/kernel/branches/net/network/tcp.inc b/kernel/branches/net/network/tcp.inc index f762d4d3fd..e538af3c2a 100644 --- a/kernel/branches/net/network/tcp.inc +++ b/kernel/branches/net/network/tcp.inc @@ -1,32 +1,64 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; TCP.INC ;; ;; ;; ;; Part of the tcp/ip network stack for KolibriOS ;; ;; ;; -;; Written by hidnplayr@kolibrios.org ;; -;; Inspired by the TCP code of Mike Hibbit for MenuetOS ;; +;; Written by hidnplayr@kolibrios.org ;; +;; ;; +;; Based on the code of 4.4BSD ;; ;; ;; ;; GNU GENERAL PUBLIC LICENSE ;; ;; Version 2, June 1991 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - $Revision$ -TCP_RETRIES equ 5 ; Number of times to resend a Packet -TCP_PACKET_TTL equ 50 ; resend if not replied to in 1/100 s -TCP_SOCKET_TTL equ 10 ; # of secs to wait before closing socket -TCP_QUEUE_SIZE equ 16 +; Socket states +TCB_CLOSED equ 0 +TCB_LISTEN equ 1 +TCB_SYN_SENT equ 2 +TCB_SYN_RECEIVED equ 3 +TCB_ESTABLISHED equ 4 +TCB_CLOSE_WAIT equ 5 +TCB_FIN_WAIT_1 equ 6 +TCB_CLOSING equ 7 +TCB_LAST_ACK equ 8 +TCB_FIN_WAIT_2 equ 9 +TCB_TIMED_WAIT equ 10 -TCP_MAX_ACKS equ 16 +; Socket Flags +TF_ACKNOW equ 1 shl 0 ; ack peer immediately +TF_DELACK equ 1 shl 1 ; ack, but try to delay it +TF_NODELAY equ 1 shl 2 ; don't delay packets to coalesce +TF_NOOPT equ 1 shl 3 ; don't use tcp options +TF_SENTFIN equ 1 shl 4 ; have sent FIN +TF_REQ_SCALE equ 1 shl 5 ; have/will request window scaling +TF_RCVD_SCALE equ 1 shl 6 ; other side has requested scaling +TF_REQ_TSTMP equ 1 shl 7 ; have/will request timestamps +TF_RCVD_TSTMP equ 1 shl 8 ; a timestamp was received in SYN +TF_SACK_PERMIT equ 1 shl 9 ; other side said I could SACK +; Segment flags +TH_FIN equ 1 shl 0 +TH_SYN equ 1 shl 1 +TH_RST equ 1 shl 2 +TH_PUSH equ 1 shl 3 +TH_ACK equ 1 shl 4 +TH_URG equ 1 shl 5 -struct TCP_Packet +; Segment header options +TCP_OPT_EOL equ 0 ; End of option list. +TCP_OPT_NOP equ 1 ; No-Operation. +TCP_OPT_MAXSEG equ 2 ; Maximum Segment Size. +TCP_OPT_WINDOW equ 3 ; window scale +TCP_OPT_TIMESTAMP equ 8 + +struct TCP_segment .SourcePort dw ? .DestinationPort dw ? .SequenceNumber dd ? @@ -36,59 +68,30 @@ struct TCP_Packet .Window dw ? .Checksum dw ? .UrgentPointer dw ? -; .Options rb 3 -; .Padding db ? - .Data: + .Data: ; ..or options ends struct tcp_in_queue_entry .data_ptr dd ? .data_size dd ? - .offset dd ? ; TODO: replace this in code by absolute address isntead of relative offset + .offset dd ? .size: ends struct tcp_out_queue_entry .data_ptr dd ? .data_size dd ? - .ttl dd ? - .retries dd ? - .owner dd ? - .sendproc dd ? - .seq_num dd ? - .socket dd ? + .size: ends align 4 uglobal - TCP_PACKETS_TX rd MAX_IP - TCP_PACKETS_RX rd MAX_IP - - TCP_IN_QUEUE rd (tcp_in_queue_entry.size*TCP_QUEUE_SIZE+queue.data)/4 - TCP_OUT_QUEUE dd ?, ? - rd (tcp_out_queue_entry.size*TCP_QUEUE_SIZE)/4 - - TCP_ACKS dd ? - TCP_ACK_LIST rd 3*TCP_MAX_ACKS -endg - -align 4 -iglobal -TCPstateHandler: - - dd stateTCB_LISTEN - dd stateTCB_SYN_SENT - dd stateTCB_SYN_RECEIVED - dd stateTCB_ESTABLISHED - dd stateTCB_FIN_WAIT_1 - dd stateTCB_FIN_WAIT_2 - dd stateTCB_CLOSE_WAIT - dd stateTCB_CLOSING - dd stateTCB_LAST_ACK - dd stateTCB_TIME_WAIT - dd stateTCB_CLOSED - + TCP_segments_tx rd IP_MAX_INTERFACES + TCP_segments_rx rd IP_MAX_INTERFACES + TCP_bytes_rx rq IP_MAX_INTERFACES + TCP_bytes_tx rq IP_MAX_INTERFACES + TCP_sequence_num dd ? endg @@ -106,1140 +109,1875 @@ align 4 TCP_init: xor eax, eax - mov edi, TCP_PACKETS_TX - mov ecx, 2*MAX_IP + mov edi, TCP_segments_tx + mov ecx, (6*IP_MAX_INTERFACES) rep stosd - init_queue TCP_IN_QUEUE - -; tcp_out_queue is a special type of queue: -; The first dword is a counter of total packets queued. -; The remaining bytes are socket 'slots' wich use tcp_out_queue_entry data structure. -; An empty slot is know by the fact that tcp_out_queue_entry.data_ptr (first dword of the slot) is set to 0 -; There are TCP_OUT_QUEUE_SIZE number of slots - - xor eax, eax - mov esi, TCP_OUT_QUEUE - mov ecx, TCP_QUEUE_SIZE*tcp_out_queue_entry/4+2+2+3*TCP_MAX_ACKS - rep stosd + mov [TCP_sequence_num],1 ret ;----------------------------------------------------------------- ; -; TCP_decrease_socket_ttls +; decrease socket ttls ; -; IN: / -; OUT: / +; IN: / +; OUT: / +; +; destroys: eax ; ;----------------------------------------------------------------- align 4 -TCP_decrease_socket_ttls: -; scan through all the sockets, decrementing active timers +TCP_timer_1000ms: +; scan through all the active TCP sockets, decrementing active timers - mov ebx, net_sockets - cmp [ebx + SOCKET_head.NextPtr], 0 - je .exit - .next_socket: - mov ebx, [ebx + SOCKET_head.NextPtr] - or ebx, ebx + mov eax, net_sockets + .loop: + mov eax, [eax + SOCKET.NextPtr] + .check_only: + or eax, eax jz .exit - cmp [ebx + SOCKET_head.Type], IP_PROTO_TCP - jne .next_socket + cmp [eax + SOCKET.Type], IP_PROTO_TCP + jne .loop -; DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.state] - - cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], 0 + cmp [eax + TCP_SOCKET.t_timer], 0 jne .decrement_tcb - cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 0 + ;;;;;; cmp [eax + TCP_SOCKET.wndsizeTimer], 0 jne .decrement_wnd - jmp .next_socket + jmp .loop .decrement_tcb: ; decrement it, delete socket if TCB timer = 0 & socket in timewait state - dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer] - jnz .next_socket + dec [eax + TCP_SOCKET.t_timer] + jnz .loop - cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT - jne .next_socket + cmp [eax + TCP_SOCKET.t_state], TCB_TIMED_WAIT + jne .loop - push [ebx + SOCKET_head.PrevPtr] - stdcall net_socket_free, ebx - pop ebx - jmp .next_socket + push [eax + SOCKET.NextPtr] + call SOCKET_free + pop eax + jmp .check_only .decrement_wnd: - dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] - jmp .next_socket +;;;;;; dec [eax + TCP_SOCKET.wndsizeTimer] .exit: ret +;---------------------- +; +; TCP_500ms +; +;---------------------- +align 4 +TCP_500ms: + + add [TCP_sequence_num], 64000 + + ret + + + +;---------------------- +; +; TCP_10ms +; +;---------------------- +align 4 +TCP_10ms: + + ; todo: decrease timers + + ret + + + + ;----------------------------------------------------------------- ; -; TCP_send_queued: +; TCP_input: ; -; Decreases 'ttl' of tcp packets queued. -; if 'ttl' reaches 0, resend the packet and decrease 'retries' -; if 'retries' reaches zero, remove the queued packet +; IN: [esp] = ptr to buffer +; [esp+4] = buffer size +; ebx = ptr to device struct +; ecx = segment size +; edx = ptr to TCP segment +; +; esi = ipv4 source address +; edi = ipv4 dest address ; -; IN: / ; OUT: / ; ;----------------------------------------------------------------- align 4 -TCP_send_queued: +TCP_input: - cmp [TCP_OUT_QUEUE], 0 - je .exit + DEBUGF 1,"TCP_input\n" - mov ebx, TCP_OUT_QUEUE+4 - call wait_mutex +; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length. - mov eax, TCP_QUEUE_SIZE - mov ecx, [TCP_OUT_QUEUE] - mov esi, TCP_OUT_QUEUE+8 + movzx eax, [edx + TCP_segment.DataOffset] + and eax, 0xf0 + shr al , 2 + + DEBUGF 1,"data offset: %u\n", eax + + cmp eax, 20 + jl .drop + + cmp eax, ecx + jg .drop + +;------------------------------- +; Now, re-calculate the checksum + + push eax edx ebx + + push edi + push esi + mov esi, edx + call TCP_checksum ; this destroys edx, ecx and esi (but not edi! :) + + pop ebx edx eax + + cmp [edx + TCP_segment.Checksum], 0 + jnz .drop + + DEBUGF 1,"Checksum is correct\n" + +;----------------------------------------------------------------------------------------- +; Check if this packet has a timestamp option (We do it here so we can process it quickly) + + cmp eax, 20 + 12 ; Timestamp option is 12 bytes + jl .no_timestamp + je .is_ok + + cmp byte [edx + TCP_segment.Data + 12], 0 ; end of option list + jne .no_timestamp + + .is_ok: + test [edx + TCP_segment.Flags], TH_SYN ; SYN flag must not be set + jnz .no_timestamp + + cmp dword [edx + TCP_segment.Data], 0x0101080a ; Timestamp header + jne .no_timestamp + + DEBUGF 1,"timestamp ok\n" + + ; TODO: Parse the options + ; TODO: Set a Bit in the TCP to tell all options are parsed - .loop: - cmp [esi + tcp_out_queue_entry.data_ptr], 0 - jnz .found_one - add esi, tcp_out_queue_entry.size - loop .loop - .exit: - mov [TCP_OUT_QUEUE+4], 0 ret - .found_one: - dec [esi + tcp_out_queue_entry.ttl] - jz .send_it - cmp [esi + tcp_out_queue_entry.data_ptr], -1 - jz .is_ack - .find_next: - add esi, tcp_out_queue_entry.size - dec eax - jz .exit - test ecx, ecx - jnz .loop - mov [TCP_OUT_QUEUE+4], 0 - ret + .no_timestamp: - .send_it: - pusha - mov ebx, [esi + tcp_out_queue_entry.owner] - pushd [esi + tcp_out_queue_entry.data_size] - pushd [esi + tcp_out_queue_entry.data_ptr] - DEBUGF 1,"Now sending TCP packet %x, size: %u, owner: %x, sendproc %x\n", [esp], [esp+4], ebx, [esi + tcp_out_queue_entry.sendproc] - inc [TCP_PACKETS_TX] - call [esi + tcp_out_queue_entry.sendproc] - add esp, 8 - popa +;------------------------------------------- +; Convert Big-endian values to little endian - dec [esi + tcp_out_queue_entry.retries] - jz .remove_it + ntohld [edx + TCP_segment.SequenceNumber] + ntohld [edx + TCP_segment.AckNumber] - mov [esi + tcp_out_queue_entry.ttl], TCP_PACKET_TTL - jmp .find_next + ntohlw [edx + TCP_segment.Window] + ntohlw [edx + TCP_segment.UrgentPointer] - .remove_it: - push [esi + tcp_out_queue_entry.data_ptr] - mov [esi + tcp_out_queue_entry.data_ptr], 0 - call kernel_free - dec [TCP_OUT_QUEUE] - jmp .find_next +;------------------------------------------------------------ +; Next thing to do is find the TCB (thus, the socket pointer) - .is_ack: - pusha - mov eax, [esi + tcp_out_queue_entry.socket] - mov ebx, [esi + tcp_out_queue_entry.owner] - mov ecx, [esi + tcp_out_queue_entry.size] - call TCP_send_ack - popa - mov [esi + tcp_out_queue_entry.data_ptr], 0 - dec [TCP_OUT_QUEUE] - jmp .find_next - - - -;----------------------------------------------------------------- -; -; TCP_handler: -; -; Called by IPv4_handler, -; this procedure will inject the tcp data diagrams in the application sockets. -; -; IN: Pointer to buffer in [esp] -; size of buffer in [esp+4] -; pointer to device struct in ebx -; TCP Packet size in ecx -; pointer to TCP Packet in edx -; SourceAddres (IPv4) in esi -; OUT: / -; -;----------------------------------------------------------------- -align 4 -TCP_handler : - - DEBUGF 1,"TCP_Handler\n" - -; TODO: validate checksum - -; Find a matching socket for received packet, all following expressions must be valid: -; ; IP Packet TCP Destination Port = local Port -; (IP Packet SA = Remote IP) OR (Remote IP = 0) +; (IP Packet SenderAddress = Remote IP) OR (Remote IP = 0) ; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0) mov ebx, net_sockets .socket_loop: - mov ebx, [ebx + SOCKET_head.NextPtr] + mov ebx, [ebx + SOCKET.NextPtr] or ebx, ebx - jz .dump + jz .drop_with_reset - mov ax, [edx + TCP_Packet.DestinationPort] - cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort], ax + cmp [ebx + SOCKET.Type], IP_PROTO_TCP jne .socket_loop - mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] + mov ax, [edx + TCP_segment.DestinationPort] + cmp [ebx + TCP_SOCKET.LocalPort], ax + jne .socket_loop + + mov eax, [ebx + IP_SOCKET.RemoteIP] cmp eax, esi je @f test eax, eax - jne .socket_loop + jnz .socket_loop @@: - mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] - cmp [edx + TCP_Packet.SourcePort] , ax + mov ax, [ebx + TCP_SOCKET.RemotePort] + cmp [edx + TCP_segment.SourcePort] , ax je .found_socket test ax, ax jnz .socket_loop .found_socket: - DEBUGF 1,"Found valid socket for packet\n" + DEBUGF 1,"Socket ptr: %x\n", ebx - inc [TCP_PACKETS_RX] +; ebx now contains the pointer to the socket - add ebx, SOCKET_head.lock +;---------------------------- +; Check if socket isnt closed + + cmp [TCP_SOCKET.t_state], TCB_CLOSED + je .drop + +;---------------- +; Lock the socket + + add ebx, SOCKET.lock ; TODO: figure out if we should lock now already call wait_mutex - sub ebx, SOCKET_head.lock + sub ebx, SOCKET.lock -;------------------------------- -; ebx is pointer to socket -; ecx is size of tcp packet -; edx is pointer to tcp packet +;--------------------------------------- +; unscale the window into a 32 bit value ;;;;;; -; calculate header length - movzx eax, [edx + TCP_Packet.DataOffset] + movzx eax, [edx + TCP_segment.Window] + xchg al, ah + + test [edx + TCP_segment.Flags], TH_SYN + jnz .no_syn + + mov cl , [ebx + TCP_SOCKET.SND_SCALE] + shl eax, cl + + .no_syn: + +;----------------------------------- +; Is this socket a listening socket? + +; If so, create a new socket + + test [ebx + SOCKET.options], SO_ACCEPTCON + jz .no_accept_conn + + + ; TODO: create a new socket + + + .no_accept_conn: + +;---------------------------- +; Compute window scale factor + + +; TODO + + +;------------------------------------- +; Reset idle timer and keepalive timer + + +; TODO + +;----------------------------------------- +; Process TCP options if not in LISTEN state + + test [ebx + TCP_SOCKET.t_state], TCB_LISTEN + jz .dont_do_options + + call TCP_do_options + + .dont_do_options: + +;----------------------------------------------------------------------- +; Time to do some header prediction (Original Principle by Van Jacobson) + + +; There are two common cases for an uni-directional data transfer. +; +; General rule: the packets has no control flags, is in-sequence, +; window width didnt change and we're not retransmitting. +; +; Second rules: +; - If the length is 0 and the ACK moved forward, we're the sender side of the transfer. +; In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer +; +; - If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer. +; If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK + + cmp [TCP_SOCKET.t_state], TCB_ESTABLISHED + jnz .not_uni_xfer + + test [TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG + jnz .not_uni_xfer + + test [TCP_segment.Flags], TH_ACK + jz .not_uni_xfer + + mov eax, [edx + TCP_segment.SequenceNumber] + cmp eax, [ebx + TCP_SOCKET.RCV_NXT] + jne .not_uni_xfer + + movzx eax, [edx + TCP_segment.Window] ;;;;; + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jne .not_uni_xfer + + mov eax, [ebx + TCP_SOCKET.SND_NXT] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jne .not_uni_xfer + +;------------------------------------------------------------------------------- +; If last ACK falls within this segment's sequence number, record the timestamp. + + ; TODO: check if it has a timestamp + + + + +;--------------------------------------- +; check if we are sender in the uni-xfer + +; If the following 4 conditions are all true, this segment is a pure ACK. +; +; - The segment contains no data (ti_len is 0). + + movzx eax, [edx + TCP_segment.DataOffset] and eax, 11110000b shr eax, 2 - DEBUGF 1,"TCP header size: %u\n", eax + sub ecx, eax + jnz .not_sender + +; - The acknowledgment field in the segment (ti_ack) is greater than the largest unacknowledged sequence number (snd_una). +; Since this test is "greater than" and not "greater than or equal to," it is true only if some positive amount of data is acknowledged by the ACK. + + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + jle .not_uni_xfer + +; - The acknowledgment field in the segment (ti_ack) is less than or equal to the maximum sequence number sent (snd_max). + +; mov eax, [edx + TCP_segment.Ack] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jg .not_uni_xfer + +; - The congestion window (snd_cwnd) is greater than or equal to the current send window (snd_wnd). +; This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance. + + mov eax, [ebx + TCP_SOCKET.SND_CWND] + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jl .not_uni_xfer + + DEBUGF 1,"Header prediction: we are sender\n" + +;--------------------------------- +; Packet is a pure ACK, process it + +; Update RTT estimators + +; Delete acknowledged bytes from send buffer + +; Stop retransmit timer + +; Awaken waiting processes + +; Generate more output + + + + + jmp .drop + + + + +;------------------------------------------------- +; maybe we are the receiver in the uni-xfer then.. + + .not_sender: +; The amount of data in the segment (ti_len) is greater than 0 (data count is in ecx) + + +; The acknowledgment field (ti_ack) equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment. + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + jne .not_uni_xfer + +; The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). +;;;; + jnz .not_uni_xfer + +; There is room in the receive buffer for the data in the segment. +;;;; + jnz .not_uni_xfer + +;------------------------------------- +; Complete processing of received data + + DEBUGF 1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx + +; The next expected receive sequence number (rcv_nxt) is incremented by the number of bytes of data. + + add [ebx + TCP_SOCKET.RCV_NXT], ecx + +; Add the data to the socket buffer + +; The receiving process is awakened (by sorwakeup). + +; The delayed-ACK flag is set and the input processing is complete. + + jmp .drop + + + + + +;---------------------------------------------------- +; Header prediction failed, doing it the slow way.. + + .not_uni_xfer: + + DEBUGF 1,"Header prediction failed\n" + +;------------------------ +; calculate header length ;;;;; we already calculated this before! + movzx eax, [edx + TCP_segment.DataOffset] + and eax, 0xf0 + shr eax, 2 + +; Update edx to point to data.. + add edx, eax +; ..and ecx to give data size sub ecx, eax -;------------------------------- -; ecx is size of tcp data +;------------------------------ +; Calculate receive window size -; as a Packet has been received, update the TCB timer + ;;;; -; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges - test [edx + TCP_Packet.Flags], TH_ACK - jz .no_ack ; No ACK, so no data yet -; Calculate ACK number, in intel byte order - mov edi, [edx + TCP_Packet.AckNumber] - bswap edi - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi - DEBUGF 1,"Setting last_ack_number to %u\n", edi +;------------------------- +; TCP slow input procedure -; Dequeue all acknowledged packets - cmp [TCP_OUT_QUEUE], 0 ; first, check if any packets are queued at all - je .no_ack + DEBUGF 1,"TCP slow input procedure\n" - push ebx - mov ebx, TCP_OUT_QUEUE+4 - call wait_mutex - pop ebx + cmp [eax + TCP_SOCKET.t_state], TCB_LISTEN + je .LISTEN + + cmp [eax + TCP_SOCKET.t_state], TCB_SYN_SENT + je .SYN_SENT + + +;-------------------------------------------- +; Protection Against Wrapped Sequence Numbers + + +; First, check timestamp if present + +;;;; TODO + +; Then, check if at least some bytes of data are within window + +;;;; TODO + + jmp .trim_then_step6 + +align 4 +.LISTEN: + + DEBUGF 1,"TCP state: listen\n" + + test [edx + TCP_segment.Flags], TH_RST + jnz .drop + + test [edx + TCP_segment.Flags], TH_ACK + jnz .drop_with_reset + + test [edx + TCP_segment.Flags], TH_SYN + jz .drop + + ; TODO: check if it's a broadcast or multicast, and drop if so + +;;; 28.6 + + ; create a new socket and fill in the nescessary variables + +;; Exit if backlog queue is full +; mov ax, [ebx + TCP_SOCKET.backlog_cur] +; cmp ax, [ebx + TCP_SOCKET.backlog] +; jae .exit + +; Allocate new socket + call SOCKET_alloc + ;;; jz .fail + +; Copy structure from current socket to new, (including lock!) +; We start at PID to reserve the socket num, and the 2 pointers at beginning of socket + lea esi, [edx + SOCKET.PID] + lea edi, [eax + SOCKET.PID] + mov ecx, (TCP_SOCKET.end - SOCKET.PID + 3)/4 + rep movsd + +;; Push pointer to new socket to queue +; movzx ecx, [ebx + TCP_SOCKET.backlog_cur] +; inc [ebx + TCP_SOCKET.backlog_cur] +; mov [ebx + TCP_SOCKET.end + ecx*4], eax + + mov [eax + IP_SOCKET.RemoteIP], esi ; IP source address + + mov cx, [edx + TCP_segment.SourcePort] + mov [eax + TCP_SOCKET.RemotePort], cx + + mov ecx, [edx + TCP_segment.SequenceNumber] + mov [eax + TCP_SOCKET.IRS], ecx + + mov ecx, [eax + TCP_SOCKET.ISS] + mov [eax + TCP_SOCKET.SND_NXT], ecx + + jmp .trim_then_step6 + + + +align 4 +.SYN_SENT: + + DEBUGF 1,"TCP state: syn_sent\n" + + test [edx + TCP_segment.Flags], TH_ACK + jz @f + + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.ISS] + jle .drop_with_reset + + mov eax, [edx + TCP_segment.AckNumber] + cmp eax, [ebx + TCP_SOCKET.SND_MAX] + jg .drop_with_reset + @@: + + + test [edx + TCP_segment.Flags], TH_RST + jz @f + + test [edx + TCP_segment.Flags], TH_ACK + jz .drop + + ;tp = tcp_drop(tp, ECONNREFUSED) + + jmp .drop + @@: + + test [edx + TCP_segment.Flags], TH_SYN + jz .drop + +; now, process received SYN in response to an active open + test [edx + TCP_segment.Flags], TH_ACK + jz @f + + mov eax, [edx + TCP_segment.AckNumber] + mov [ebx + TCP_SOCKET.SND_UNA], eax + + mov eax, [ebx + TCP_SOCKET.SND_UNA] + cmp eax, [ebx + TCP_SOCKET.SND_NXT] + jle @f + mov [ebx + TCP_SOCKET.SND_NXT], eax + + +; TODO: turn off retransmission timer + + mov eax, [edx + TCP_segment.SequenceNumber] + mov [ebx + TCP_SOCKET.IRS], eax + +; TODO: set socket state to connected + + mov [ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED + +; TODO: check if we should scale the connection (567-572) +; TODO: update RTT estimators + + + @@: + +; We have received a syn but no ACK, so we are having a simultaneous open.. + mov [ebx + TCP_SOCKET.t_state], TCB_SYN_RECEIVED + +;------------------------------------- +; Common processing for receipt of SYN + + .trimthenstep6: + + inc [edx + TCP_segment.SequenceNumber] + + cmp cx, [ebx + TCP_SOCKET.RCV_WND] + jle @f + + movzx eax, cx + sub ax, [ebx + TCP_SOCKET.RCV_WND] + ; TODO: 592 + mov cx, [ebx + TCP_SOCKET.RCV_WND] + ; TODO... + @@: + ;;;;; + ;;; jmp .step6 + + + + + +align 4 +.trim_then_step6: + + DEBUGF 1,"Trim, then step 6\n" + +;---------------------------- +; trim any data not in window + + mov eax, [ebx + TCP_SOCKET.RCV_NXT] + sub eax, [edx + TCP_segment.SequenceNumber] + + test eax, eax + jz .no_drop + + test [edx + TCP_segment.Flags], TH_SYN + jz .no_drop + + and [edx + TCP_segment.Flags], not (TH_SYN) + inc [edx + TCP_segment.SequenceNumber] + + cmp [edx + TCP_segment.UrgentPointer], 1 + jl @f + + dec [edx + TCP_segment.UrgentPointer] + + jmp .no_drop + @@: + + and [edx + TCP_segment.Flags], not (TH_URG) + dec eax + + .no_drop: + +; eax holds number of bytes to drop + + +;---------------------------------- +; Check for entire duplicate packet + + cmp eax, ecx + jge .duplicate + + ;;; TODO: figure 28.30 + +;; inc [TCP_segments_rx] + +;; add dword [TCP_bytes_rx], ecx +;; adc dword [TCP_bytes_rx+4], 0 + +;------------------------ +; Check for duplicate FIN + + test [edx + TCP_segment.Flags], TH_FIN + jz @f + inc ecx + cmp eax, ecx + dec ecx + jne @f + + mov eax, ecx + and [edx + TCP_segment.Flags], not TH_FIN + ;;; TODO: set ACKNOW flag + + jmp .no_duplicate + @@: + + ; Handle the case when a bound socket connects to itself + ; Allow packets with a SYN and an ACKto continue with the processing + + +;------------------------------------- +; Generate duplicate ACK if nescessary + +; This code also handles simultaneous half-open or self-connects + + test eax, eax + jnz .drop_after_ack + + cmp [edx + TCP_segment.Flags], TH_ACK + jz .drop_after_ack + + .duplicate: + +;---------------------------------------- +; Update statistics for duplicate packets + + ;;; TODO + + ;;; DROP the packet ?? + + .no_duplicate: + +;----------------------------------------------- +; Remove duplicate data and update urgent offset + + add [edx + TCP_segment.SequenceNumber], eax + + ;;; TODO + + sub [edx + TCP_segment.UrgentPointer], ax + jg @f + + and [edx + TCP_segment.Flags], not (TH_URG) + mov [edx + TCP_segment.UrgentPointer], 0 + @@: + +;-------------------------------------------------- +; Handle data that arrives after process terminates + + cmp [ebx + SOCKET.PID], 0 + jge @f + + cmp [ebx + TCP_SOCKET.t_state], TCB_CLOSE_WAIT + jle @f + + test ecx, ecx + jz @f + + ;;; Close the socket + ;;; update stats + + jmp .drop_with_reset + + @@: + +;---------------------------------------- +; Remove data beyond right edge of window + + mov eax, [edx + TCP_segment.SequenceNumber] + add eax, ecx + sub eax, [ebx + TCP_SOCKET.RCV_NXT] + sub ax, [ebx + TCP_SOCKET.RCV_WND] + + ; eax now holds the number of bytes to drop + + jle .no_excess_data + + ;;; TODO: update stats + + cmp eax, ecx + jl .dont_drop_all + +;;; TODO 700-736 + + .dont_drop_all: + + .no_excess_data: + + +;----------------- +; Record timestamp + + ;;; TODO 737-746 + +;------------------ +; Process RST flags + + test [edx + TCP_segment.Flags], TH_RST + jz .rst_skip + + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .rst_sw_list] + + .rst_sw_list: + dd .rst_skip ;TCB_CLOSED + dd .rst_skip ;TCB_LISTEN + dd .rst_skip ;TCB_SYN_SENT + dd .econnrefused ;TCB_SYN_RECEIVED + dd .econnreset ;TCB_ESTABLISHED + dd .econnreset ;TCB_CLOSE_WAIT + dd .econnreset ;TCB_FIN_WAIT_1 + dd .rst_close ;TCB_CLOSING + dd .rst_close ;TCB_LAST_ACK + dd .econnreset ;TCB_FIN_WAIT_2 + dd .rst_close ;TCB_TIMED_WAIT + + .econnrefused: + + ;;; TODO: debug info + + jmp .close + + .econnreset: + + ;;; TODO: debug info + .close: + + ;;; update stats + + .rst_close: + + ;;; Close the socket + jmp .drop + + .rst_skip: + +;-------------------------------------- +; handle SYN-full and ACK-less segments + + test [edx + TCP_segment.Flags], TH_SYN + jz @f + + ;;; tcp_drop ( ECONNRESET) + jmp .drop_with_reset + + test [edx + TCP_segment.Flags], TH_ACK + jz .drop + +;---------------- +; Process the ACK + + cmp [ebx + TCP_SOCKET.t_state], TCB_SYN_RECEIVED + jg .ack_dup + jl .ack_nodup + +; dd .ack_nodup ;TCB_CLOSED +; dd .ack_nodup ;TCB_LISTEN +; dd .ack_nodup ;TCB_SYN_SENT +; dd .ack_syn_rcvd ;TCB_SYN_RECEIVED +; dd .ack_dup ;TCB_ESTABLISHED +; dd .ack_dup ;TCB_CLOSE_WAIT +; dd .ack_dup ;TCB_FIN_WAIT_1 +; dd .ack_dup ;TCB_CLOSING +; dd .ack_dup ;TCB_LAST_ACK +; dd .ack_dup ;TCB_FIN_WAIT_2 +; dd .ack_dup ;TCB_TIMED_WAIT + + ;;;;; + + .ack_dup: + + ;;;; + + .ack_nodup: + + ;;;; 887 + +;------------------------------------------------- +; If the congestion window was infalted to account +; for the other side's cached packets, retrace it + + ;;;; 888 - 902 + + +;------------------------------------------ +; RTT measurements and retransmission timer + + ;;;;; 903 - 926 + + +;------------------------------------------- +; Open congestion window in response to ACKs + + ;;;; + + +;------------------------------------------ +; Remove acknowledged data from send buffer + + ;;;; 943 - 956 + +;--------------------------------------- +; Wake up process waiting on send buffer + + ;;;;; + + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .ACK_sw_list] + + .ACK_sw_list: + dd .step6 ;TCB_CLOSED + dd .step6 ;TCB_LISTEN + dd .step6 ;TCB_SYN_SENT + dd .step6 ;TCB_SYN_RECEIVED + dd .step6 ;TCB_ESTABLISHED + dd .step6 ;TCB_CLOSE_WAIT + dd ._963 ;TCB_FIN_WAIT_1 + dd ._958 ;TCB_CLOSING + dd ._999 ;TCB_LAST_ACK + dd .step6 ;TCB_FIN_WAIT_2 + dd ._1010 ;TCB_TIMED_WAIT + + +._963: + + + jmp .step6 + + +._958: + + jmp .step6 + +._999: + + jmp .step6 + + +._1010: + + jmp .step6 + + + +align 4 +.step6: + + DEBUGF 1,"step 6\n" + +;-------------------------- +; update window information + + test [edx + TCP_segment.Flags], TH_ACK + jz .no_window_update + + mov eax, [ebx + TCP_SOCKET.SND_WL1] + cmp eax, [edx + TCP_segment.SequenceNumber] + + ;;;; 1021 + +;---------------------------------- +; Keep track of pure window updates + + test ecx, ecx + jz @f + + mov eax, [ebx + TCP_SOCKET.SND_WL2] + cmp eax, [edx + TCP_segment.AckNumber] + jne @f + + ;; mov eax, tiwin + cmp eax, [ebx + TCP_SOCKET.SND_WND] + jle @f + + ;;; update stats + + @@: + + ;; mov eax, incoming window + cmp eax, [ebx + TCP_SOCKET.max_sndwnd] + jle @f + mov [ebx + TCP_SOCKET.max_sndwnd], eax + @@: + mov [ebx + TCP_SOCKET.SND_WND], eax + + mov eax, [edx + TCP_segment.SequenceNumber] + mov [ebx + TCP_SOCKET.SND_WL1], eax + + mov eax, [edx + TCP_segment.AckNumber] + mov [ebx + TCP_SOCKET.SND_WL2], eax + + ;;; needoutput = 1 + + .no_window_update: + + +;----------------- +; process URG flag + + test [edx + TCP_segment.Flags], TH_URG + jz .not_urgent + + cmp [edx + TCP_segment.UrgentPointer], 0 + jz .not_urgent + + cmp [ebx + TCP_SOCKET.t_state], TCB_TIMED_WAIT + je .not_urgent + +; Ignore bogus urgent offsets + + ;;; 1040-1050 + + movzx eax, [edx + TCP_segment.UrgentPointer] + add eax, [ebx + SOCKET.SO_RCV.SB_CC] + cmp eax, SOCKET_MAXDATA + jle .not_urgent + + mov [edx + TCP_segment.UrgentPointer], 0 + and [edx + TCP_segment.Flags], not (TH_URG) + jmp .do_data + + .not_urgent: + +;-------------------------------------- +; processing of received urgent pointer + + ;;; 1051-1093 + +align 4 +.do_data: + + DEBUGF 1,"Do data:\n" + + ; process the data in the segment + + test [edx + TCP_segment.Flags], TH_FIN + jz .process_fin + + test [ebx + TCP_SOCKET.t_state], TCB_FIN_WAIT_1 ;;;;; + jge .dont_do_data + + DEBUGF 1,"Processing data in segment\n" + + ;;; NOW, process the data + + jmp .final_processing + + + .dont_do_data: + + +;--------------- +; FIN processing + + .process_fin: + + DEBUGF 1,"Processing FIN\n" + + mov eax, [ebx + TCP_SOCKET.t_state] + shl eax, 2 + jmp dword [eax + .FIN_sw_list] + + .FIN_sw_list: + dd .no_fin ;TCB_CLOSED + dd .no_fin ;TCB_LISTEN + dd .no_fin ;TCB_SYN_SENT + dd ._1131 ;TCB_SYN_RECEIVED + dd ._1131 ;TCB_ESTABLISHED + dd .no_fin ;TCB_CLOSE_WAIT + dd ._1139 ;TCB_FIN_WAIT_1 + dd .no_fin ;TCB_CLOSING + dd .no_fin ;TCB_LAST_ACK + dd ._1147 ;TCB_FIN_WAIT_2 + dd ._1156 ;TCB_TIMED_WAIT + + + + ._1131: + + ._1139: + + ._1147: + + ._1156: + + + .no_fin: + +;----------------- +; Final processing + + .final_processing: + + DEBUGF 1,"Final processing\n" + + ;;; if debug enabled, output packet + + ;test ;;;needoutput = 1 + ;jnz .outputnow + + test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jz .ret + + .outputnow: + call TCP_output + + .ret: + mov [ebx + SOCKET.lock], 0 + + call kernel_free + ret 4 + +;------------------------------------------ +; Generate an ACK, droping incoming segment + +align 4 +.drop_after_ack: + + DEBUGF 1,"Drop after ACK\n" + + test [edx + TCP_segment.Flags], TH_RST + jnz .drop + + and [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + + call TCP_output + + mov [ebx + SOCKET.lock], 0 + + call kernel_free + ret 4 + + +;------------------------------------------- +; Generate an RST, dropping incoming segment + +align 4 +.drop_with_reset: + + DEBUGF 1,"Drop with reset\n" + + test [edx + TCP_segment.Flags], TH_RST + jnz .drop + + ;;; if its a multicast/broadcast, also drop + + test [edx + TCP_segment.Flags], TH_ACK + jnz .respond_ack + + test [edx + TCP_segment.Flags], TH_SYN + jnz .respond_syn + + mov [ebx + SOCKET.lock], 0 + + call kernel_free + ret 4 + + .respond_ack: + + ;;;; + + call TCP_respond + + jmp .destroy_new_socket + + + .respond_syn: + + ;;;; + + call TCP_respond + + jmp .destroy_new_socket + +;----- +; Drop + +align 4 +.drop: + + DEBUGF 1,"Dropping packet\n" + + ;;;; If debugging options are enabled, output the packet somwhere + + .destroy_new_socket: + + ;;;; kill the newly created socket + + mov [ebx + SOCKET.lock], 0 + + call kernel_free + ret 4 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;--------------------- +; +; TCP_do_options +; +;------------------- + +align 4 +TCP_do_options: + + DEBUGF 1,"TCP_do_options\n" + + push eax + sub eax, 20 + jz .no_options + + lea esi, [edx + TCP_segment.Data] + + +;------------------------------------------- +; Begin the loop by checking for EOL and NOP - push ecx - DEBUGF 1,"Removing all queued packets with smaller ACK\n" - mov ecx, TCP_QUEUE_SIZE - mov esi, TCP_OUT_QUEUE+8 .loop: - cmp [esi + tcp_out_queue_entry.data_ptr], 0 - je .maybe_next - cmp [esi + tcp_out_queue_entry.socket], ebx - jne .maybe_next + cmp byte [esi], TCP_OPT_EOL ; end of option list? + jz .no_options - cmp [esi + tcp_out_queue_entry.seq_num], edi - jg .maybe_next + cmp byte [esi], TCP_OPT_NOP ; nop ? + ;;; cmove edi, 1 ; if so, set option size to 1 + jz .continue ; and continue scanning - DEBUGF 1,"Removing a queued packet\n" +;------------------ +; We have an option - push [esi + tcp_out_queue_entry.data_ptr] - mov [esi + tcp_out_queue_entry.data_ptr], 0 - dec [TCP_OUT_QUEUE] - call kernel_free + movzx edi, byte [esi + 1] ; get the length of this option in edi - .maybe_next: - add esi, tcp_out_queue_entry.size - loop .loop - mov [TCP_OUT_QUEUE+4], 0 - pop ecx +;-------------------------------------- +; Check for Maximum segment size option -; Now call the correct handler, depending on the socket state - .no_ack: - mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] + cmp byte [esi], TCP_OPT_MAXSEG + jne .no_maxseg - cmp eax, TCB_LISTEN - jb .dump - cmp eax, TCB_CLOSED - ja .dump + cmp edi, 4 ; option length + jne .continue - call dword [TCPstateHandler+eax*4-4] + test [edx + TCP_segment.Flags], TH_SYN + jz .continue - .dump: - DEBUGF 1,"Dumping TCP packet\n" - call kernel_free - add esp, 4 ; pop (balance stack) + ; Now parse the option... + + jmp .continue + + .no_maxseg: + +;------------------------ +; Check for Window option + + cmp byte [esi], TCP_OPT_WINDOW + jne .no_window + + cmp edi, 3 ; option length + jne .continue + + test [edx + TCP_segment.Flags], TH_SYN + jz .continue + + ; ... + + jmp .continue + + .no_window: + +;--------------------------- +; Check for Timestamp option + + cmp byte [esi], TCP_OPT_TIMESTAMP + jne .no_timestamp + + cmp edi, 10 ; option length + jne .continue + + ; ... + + + jmp .continue + + .no_timestamp: + +;---------------------------------- +; Future options may be placed here + + + + +;------------------------------ +; Continue scanning for options + + .continue: + add esi, edi + sub eax, edi + jg .loop + + .no_options: + + pop eax ret + +;--------------------------- +; +; TCP_pull_out_of_band +; +; IN: eax = +; ebx = socket ptr +; edx = tcp packet ptr +; +; OUT: / +; +;--------------------------- + +align 4 +TCP_pull_out_of_band: + + DEBUGF 1,"TCP_pull_out_of_band\n" + + ;;;; 1282-1305 + + ret + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + + + ;----------------------------------------------------------------- ; -; TCP_send (Assumes socket mutex set) +; TCP_output ; ; IN: eax = socket pointer -; bl = flags -; ecx = number of bytes to send, may be set to 0 (single ACK) -; esi = pointer to data +;; esi = ptr to data +;; ecx = number of data bytes +; +; OUT: / ; ;----------------------------------------------------------------- align 4 -TCP_send: +TCP_output: - DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl + DEBUGF 1,"TCP_output, socket: %x\n", eax +; We'll detect the length of the data to be transmitted, and flags to be used +; If there is some data, or any critical controls to send (SYN / RST), then transmit +; Otherwise, investigate further + + mov ebx, [eax + TCP_SOCKET.SND_MAX] + cmp ebx, [eax + TCP_SOCKET.SND_UNA] + jne .not_idle + + mov ebx, [eax + TCP_SOCKET.t_idle] + cmp ebx, [eax + TCP_SOCKET.t_rxtcur] + jle .not_idle + +; We have been idle for a while and no ACKS are expected to clock out any data we send.. +; Slow start to get ack "clock" running again. + + mov ebx, [eax + TCP_SOCKET.t_maxseg] + mov [eax + TCP_SOCKET.SND_CWND], ebx + + .not_idle: + .again: + mov ebx, [eax + TCP_SOCKET.SND_NXT] ; calculate offset + sub ebx, [eax + TCP_SOCKET.SND_UNA] ; + + mov ecx, [eax + TCP_SOCKET.SND_WND] ; determine window + cmp ecx, [eax + TCP_SOCKET.SND_CWND] ; + jl @f ; + mov ecx, [eax + TCP_SOCKET.SND_CWND] ; + @@: ; + + call TCP_outflags + +; If in persist timeout with window of 0, send 1 byte. +; Otherwise, if window is small but nonzero, and timer expired, +; we will send what we can and go to transmit state + + test [eax + TCP_SOCKET.t_force], -1 + jz .no_persist_timeout + + test ecx, ecx + jnz .no_zero_window + + cmp ebx, [eax + SOCKET.SO_SND.SB_CC] + jge @f + + and dl, not (TH_FIN) ; clear the FIN flag ??? how can it be set before? + + @@: + inc ecx + jmp .no_persist_timeout + + .no_zero_window: + +;;; mov [eax + TCP_SOCKET.t_timer....TCPT_PERSIST], 0 + mov [eax + TCP_SOCKET.t_rxtshift], 0 + + .no_persist_timeout: + +;;;106 + + mov esi, [eax + SOCKET.SO_SND.SB_CC] + cmp esi, ecx + jl @f + mov esi, ecx + @@: + sub esi, ebx + + cmp esi, -1 + jne .not_minus_one + +; If FIN has been set, but not ACKed, and we havent been called to retransmit, +; len (esi) will be -1 +; Otherwise, window shrank after we sent into it. +; If window shrank to 0, cancel pending retransmit and pull SND_NXT back to (closed) window +; We will enter persist state below. +; If window didn't close completely, just wait for an ACK + + xor esi, esi + + test ecx, ecx + jnz @f + +;;; mov [eax + TCP_SOCKET.t_timer..TCPT_REXMT], 0 + + push [eax + TCP_SOCKET.SND_UNA] + pop [eax + TCP_SOCKET.SND_NXT] + @@: + + .not_minus_one: + +;;; 124 + + cmp esi, [eax + TCP_SOCKET.t_maxseg] + jle @f + + mov esi, [eax + TCP_SOCKET.t_maxseg] + ;sendalot = 1 + + @@: + +;;; 128 + + mov edi, [eax + TCP_SOCKET.SND_NXT] + add edi, esi ; len + sub edi, [eax + TCP_SOCKET.SND_UNA] + add edi, [eax + SOCKET.SO_SND.SB_CC] + cmp edi, 0 + jle @f + + and dl, not (TH_FIN) ; clear the FIN flag + + @@: + + +;;;; 130 TODO: set window (ecx) to space in send buffer + + +;------------------------------ +; Sender silly window avoidance + + test esi, esi + jz .zero_length + + + cmp esi, [eax + TCP_SOCKET.t_maxseg] + je .send + +;;; TODO: 144-145 + + test [eax + TCP_SOCKET.t_force], -1 + jnz .send + +;;; TODO: 149..152 + + .zero_length: + + +;---------------------------------------- +; Check if a window update should be sent + + cmp ecx, 0 ; window + jle .no_window + +;;; TODO 154-172 + + .no_window: + +;-------------------------- +; Should a segment be sent? + + test [ebx + TCP_SOCKET.t_flags], TF_ACKNOW + jnz .send + + test dl, TH_SYN + TH_RST + jnz .send + + mov eax, [ebx + TCP_SOCKET.SND_UP] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + jg .send + + test dl, TH_FIN + jz .enter_persist + + test [ebx + TCP_SOCKET.t_flags], TF_SENTFIN + jnz .send + + mov eax, [ebx + TCP_SOCKET.SND_NXT] + cmp eax, [ebx + TCP_SOCKET.SND_UNA] + je .send + +;-------------------- +; Enter persist state + + .enter_persist: + + DEBUGF 1,"Entering pesist state\n" + + + +;-------------------------------------- +; No reason to send a segment, just ret + + DEBUGF 1,"No reason to send a segment\n" + + ret + + + + + +;----------------------------------------------- +; +; Send a segment +; +; ebx = socket pointer +; dl = flags +; +;----------------------------------------------- + +.send: + + DEBUGF 1,"Preparing to send a segment\n" + + xor edi, edi ; edi will contain the number of header option bytes + +;------------------------------------ +; Send options with first SYN segment + + test dl, TH_SYN + jz .no_options + + mov eax, [ebx + TCP_SOCKET.ISS] + mov [ebx + TCP_SOCKET.SND_NXT], eax + + test [ebx + TCP_SOCKET.t_flags], TF_NOOPT + jnz .no_options + + mov eax, TCP_OPT_MAXSEG shl 24 + 4 shl 16 + mov ax, 1280 ;;;;;; + bswap eax + push eax + + mov di, 4 + + test [ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE + jz .no_syn + + test dl, TH_ACK + jnz .scale_opt + + test [ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE + jz .no_syn + + .scale_opt: + + mov eax, TCP_OPT_WINDOW shl 24 + 4 shl 16 + TCP_OPT_NOP + mov ah, byte [ebx + TCP_SOCKET.request_r_scale] + bswap eax + push eax + + add di, 4 + + .no_syn: + +;------------------------------------ +; Make the timestamp option if needed + + test [ebx + TCP_SOCKET.t_flags], TF_REQ_TSTMP + jz .no_timestamp + + test dl, TH_RST + jnz .no_timestamp + + test dl, TH_ACK + jz .timestamp + + test [ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP + jz .no_timestamp + + .timestamp: + + DEBUGF 1,"Creating a timestamp\n" + + push dword (TCP_OPT_TIMESTAMP shl 8 + 10 + TCP_OPT_NOP shl 16 + TCP_OPT_NOP shl 24) + pushw 0 + mov eax, [timer_ticks] + bswap eax + push eax + + add di, 10 + + .no_timestamp: + + ;; TODO: check if we dont exceed the max segment size + + .no_options: + add edi, TCP_segment.Data + +;----------------------------------- +; Check if we have some data to send + + ;;; mov ecx, [huppeldepup] + + test ecx, ecx + jz .no_data + + ;;; 278-316 + + jmp .header + + .no_data: + + ;;; 317-338 + + +;---------- + + push di dx ebx + + add ecx, edi ; total TCP segment size + + mov eax, [ebx + IP_SOCKET.RemoteIP] + mov ebx, [ebx + IP_SOCKET.LocalIP] mov di , IP_PROTO_TCP - add ecx, TCP_Packet.Data - - push ecx bx eax esi -; Create an IPv4 Packet of the correct size - mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] - mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] - call IPv4_create_packet - cmp edi, -1 - je .fail -; If there is any data, copy it first +;;;; jz .fail + + push edx eax + call NET_send + ret + +;---------------- + + +;------------------------------- +; Now, create the 20-byte header + + .header: + +;----------------------- +; Fill in the TCP header + pop esi + + push [esi + TCP_SOCKET.SND_NXT] + rol word [esp], 8 + rol dword [esp], 16 + pop [edi + TCP_segment.SequenceNumber] + + push [esi + TCP_SOCKET.RCV_NXT] + rol word [esp], 8 + rol dword [esp], 16 + pop [edi + TCP_segment.AckNumber] + + push [esi + TCP_SOCKET.LocalPort] + rol word [esp], 8 + pop [edi + TCP_segment.SourcePort] + + push [esi + TCP_SOCKET.RemotePort] + rol word [esp], 8 + pop [edi + TCP_segment.DestinationPort] + + + mov [edi + TCP_segment.Window], 0x0005 + ; 1280 bytes + mov [edi + TCP_segment.UrgentPointer], 0 + + mov [edi + TCP_segment.DataOffset], 0x50 + + mov [edi + TCP_segment.Flags], cl + + mov [edi + TCP_segment.Checksum], 0 + +;----- + + +;-------------- +; Copy the data + pop esi push edi - add edi, TCP_Packet.Data - sub ecx, TCP_Packet.Data + add edi, TCP_segment.Data ;; + sub ecx, TCP_segment.Data ;;; shr ecx, 1 jnc .nb movsb -.nb: shr ecx, 1 + .nb: + shr ecx, 1 jnc .nw movsw -.nw: test ecx, ecx + .nw: + test ecx, ecx jz .nd rep movsd -.nd: + .nd: pop edi -; Fill in the TCP header - pop esi +;-------------------- +; Create the checksum -; fill in tcp sequence number - push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] - pop [edi + TCP_Packet.SequenceNumber] + push [ebx + IP_SOCKET.LocalIP] + push [ebx + IP_SOCKET.RemoteIP] + call TCP_checksum -; Fill in local and remote ports - push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] - pop dword [edi + TCP_Packet.SourcePort] +;---------------- +; Send the packet -; Acknumber - push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] - pop [edi + TCP_Packet.AckNumber] + ;;;;; -; Fill in other tcp options - pop cx - mov [edi + TCP_Packet.Flags], cl - mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes - mov [edi + TCP_Packet.UrgentPointer], 0 - mov [edi + TCP_Packet.DataOffset], 0x50 - mov [edi + TCP_Packet.Checksum], 0 - -; Get size of total packet back in ecx - pop ecx -; Push pointer to and size of total packet (needed for send procedure) - push edx eax -; push socket number (for TCP_add_to_queue) - push esi - -; Now, calculate the checksum - xchg cl, ch - pushw cx - xchg cl, ch - pushw IP_PROTO_TCP shl 8 - pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. - pushd [edi-8] ; source address - - xor edx, edx - mov esi, edi - call checksum_1 - mov ecx, 12 - mov esi, esp - call checksum_1 -; and store it in TCP header - call checksum_2 - mov [edi + TCP_Packet.Checksum], dx - add esp, 10 ; remove the pseudoheader from stack DEBUGF 1,"Sending TCP Packet to device %x\n", ebx - mov edx, [edi + TCP_Packet.SequenceNumber] - bswap edx mov esi, [ebx + ETH_DEVICE.transmit] - pop cx ; get the length from packet, back from pseudoheader - pop edi - - cmp cx, TCP_Packet.Data shl 8 ; if the packet has no data - je .only_one ; send it only once - - and ecx, 0x0000ffff - xchg cl, ch - sub cx, TCP_Packet.Data - - add_INET (edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ; todo: this should only happen when packet was queued successful - mov ecx, TCP_RETRIES - - jmp .go_for_it - - .only_one: - mov ecx, 1 - .go_for_it: - - mov [edi + SOCKET_head.lock], 0 - jmp TCP_queue ; At last send the packet! - - .fail: - add esp, 2+4 - or eax, -1 ret -;----------------------------------------------------------------- -; -; Queue a TCP packet for sending -; -; IN: [esp] pointer to buffer -; [esp + 4] size of buffer -; ebx = driver struct -; edx = sequence number of this packet in intel byte order -; esi = sender proc -; edi = socket number -; OUT: / +;------------------------- ; -;----------------------------------------------------------------- +; TCP_outflags +; +; IN: eax = socket ptr +; +; OUT: edx = flags +; +;------------------------- align 4 -TCP_queue: +TCP_outflags: - DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx + mov edx, [eax + TCP_SOCKET.t_state] + movzx edx, byte [edx + .flaglist] - cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE - jge .full - - push ebx - mov ebx, TCP_OUT_QUEUE+4 - call wait_mutex - pop ebx - - mov ecx, TCP_QUEUE_SIZE - mov eax, TCP_OUT_QUEUE+8 - .loop: - cmp [eax + tcp_out_queue_entry.data_ptr], 0 - je .found_it - add eax, tcp_out_queue_entry.size - loop .loop - - add esp, 4 - .full: ; silently discard the packet - DEBUGF 1,"TCP queue is full!\n" - call kernel_free - add esp, 4 + DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl ret - .found_it: ; eax points to empty queue entry + .flaglist: - mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES - pop [eax + tcp_out_queue_entry.data_ptr] - pop [eax + tcp_out_queue_entry.data_size] - mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately - mov [eax + tcp_out_queue_entry.owner], ebx - mov [eax + tcp_out_queue_entry.sendproc], esi - mov [eax + tcp_out_queue_entry.seq_num], edx - mov [eax + tcp_out_queue_entry.socket], edi - - inc [TCP_OUT_QUEUE] - - sub eax, TCP_OUT_QUEUE+8 - shr eax, 5 - DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8] - - mov [TCP_OUT_QUEUE+4], 0 - - ret + db TH_RST + TH_ACK ; TCB_CLOSED + db 0 ; TCB_LISTEN + db TH_SYN ; TCB_SYN_SENT + db TH_SYN + TH_ACK ; TCB_SYN_RECEIVED + db TH_ACK ; TCB_ESTABLISHED + db TH_ACK ; TCB_CLOSE_WAIT + db TH_SYN + TH_ACK ; TCB_FIN_WAIT_1 + db TH_SYN + TH_ACK ; TCB_CLOSING + db TH_SYN + TH_ACK ; TCB_LAST_ACK + db TH_ACK ; TCB_FIN_WAIT_2 + db TH_ACK ; TCB_TIMED_WAIT -;----------------------------------------------------------------- +;------------------------- ; -; IN: ebx = socket -; ecx = ack number +; TCP_drop +; +; IN: eax = socket ptr ; ; OUT: / ; +;------------------------- +align 4 +TCP_drop: + + DEBUGF 1,"TCP_drop\n" + +; cmp [eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED +; jl .no_syn_received + + mov [eax + TCP_SOCKET.t_state], TCB_CLOSED + + call TCP_output + +; .no_syn_received: + + ret + + + + + +;--------------------------------------- +; +; TCP_respond +; +; The easy way to send a RST/ACK segment +; +; IN: eax = socket ptr +; +; OUT: / +; +;--------------------------------------- +align 4 +TCP_respond: + + DEBUGF 1,"TCP_respond\n" + + ret + + + +;----------------------------------------------------------------- +; +; TCP_checksum +; +; This is the fast procedure to create or check a UDP header +; - To create a new checksum, the checksum field must be set to 0 before computation +; - To check an existing checksum, leave the checksum as is, +; and it will be 0 after this procedure, if it was correct +; +; IN: push source ip +; push dest ip +; +; esi = packet ptr +; +; OUT: checksum is filled in in packet! (but also in dx) +; ;----------------------------------------------------------------- align 4 -TCP_queue_ack: +TCP_checksum: - DEBUGF 1,"Adding ACK to TCP queue, socket: %x, acknum: %u\n", ebx, ecx +;------------- +; Pseudoheader - cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE - jge .full + ; protocol type + mov edx, IP_PROTO_TCP ; NO shl 8 here ! (it took me ages to figure this one out) - push ebx ecx - mov ebx, TCP_OUT_QUEUE+4 - call wait_mutex + ; source address + add dl, [esp+1+4] + adc dh, [esp+0+4] + adc dl, [esp+3+4] + adc dh, [esp+2+4] - mov ecx, TCP_QUEUE_SIZE - mov eax, TCP_OUT_QUEUE+8 - .loop: - cmp [eax + tcp_out_queue_entry.data_ptr], 0 - je .found_it - add eax, tcp_out_queue_entry.size - loop .loop + ; destination address + adc dl, [esp+1+8] + adc dh, [esp+0+8] + adc dl, [esp+3+8] + adc dh, [esp+2+8] - add esp, 8 - .full: ; silently discard the packet - DEBUGF 1,"TCP queue is full!\n" - ret + ; size + adc dl, cl + adc dh, ch - .found_it: ; eax points to empty queue entry +;--------------------- +; Real header and data - pop [eax + tcp_out_queue_entry.data_size] ; ACK number - mov [eax + tcp_out_queue_entry.data_ptr], -1 ; ACK packet - pop [eax + tcp_out_queue_entry.socket] - mov [eax + tcp_out_queue_entry.retries], 1 - mov [eax + tcp_out_queue_entry.ttl], 20 ; 200 ms - - inc [TCP_OUT_QUEUE] - - sub eax, TCP_OUT_QUEUE+8 - shr eax, 5 - DEBUGF 1,"Added to queue in pos %u, total queued packets: %u\n", eax, [TCP_OUT_QUEUE+8] - - mov [TCP_OUT_QUEUE+4], 0 - - ret - - -; IN: eax = socket pointer -; ebx = device structure -; ecx = ack number - -align 4 -TCP_send_ack: - - DEBUGF 1,"Creating TCP ACK packet, socket: %x, acknum: %x\n", eax, ecx - - push ecx eax - - mov di , IP_PROTO_TCP - mov ecx, TCP_Packet.Data -; Create an IPv4 Packet of the correct size - mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] - mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] - - call IPv4_create_packet - cmp edi, -1 - je .fail - - pop ecx - -; fill in tcp sequence number - push [ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] - pop [edi + TCP_Packet.SequenceNumber] - -; Fill in local and remote ports - push dword [ecx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] - pop dword [edi + TCP_Packet.SourcePort] - -; Acknumber - pop [edi + TCP_Packet.AckNumber] - -; Fill in other tcp options - mov [edi + TCP_Packet.Flags], TH_ACK - mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes - mov [edi + TCP_Packet.UrgentPointer], 0 - mov [edi + TCP_Packet.DataOffset], 0x50 - mov [edi + TCP_Packet.Checksum], 0 - -; Push pointer to and size of total packet (needed for send procedure) - push edx eax esi - -; Now, calculate the checksum - pushw TCP_Packet.Data shl 8 - pushw IP_PROTO_TCP shl 8 - pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. - pushd [edi-8] ; source address - - xor edx, edx - mov ecx, 12 - mov esi, esp + push esi call checksum_1 call checksum_2 - mov [edi + TCP_Packet.Checksum], dx - add esp, 12 ; remove the pseudoheader from stack + pop esi - pop eax - call eax - call kernel_free - add esp, 4 ; pop (balance stack) - ret + neg [esi+UDP_Packet.Checksum] ; zero will stay zero so we just get the checksum + add [esi+UDP_Packet.Checksum], dx ; , else we will get (new checksum - old checksum) in the end, wich should be 0 :) - .fail: - add esp, 8 - ret + ret 8 ; Remove the IPs from stack -;----------------------------------------------------------------- -; -; Remove all queued TCP packets for a specified socket -; -; IN: eax = socket number -; OUT: / -; -; destoys esi and ecx -; -;----------------------------------------------------------------- - -align 4 -TCP_remove_socket: - - cmp [TCP_OUT_QUEUE], 0 - je .skip - - mov ebx, TCP_OUT_QUEUE+4 - call wait_mutex - - mov eax, TCP_QUEUE_SIZE - mov ecx, [TCP_OUT_QUEUE] - mov esi, TCP_OUT_QUEUE+8 - - .loop: - cmp [esi + tcp_out_queue_entry.data_ptr], 0 - jz .maybenext - cmp [esi + tcp_out_queue_entry.socket], eax - jnz .maybenext - - push [esi + tcp_out_queue_entry.data_ptr] - mov [esi + tcp_out_queue_entry.data_ptr], 0 - dec [TCP_OUT_QUEUE] - call kernel_free - - .maybenext: - add esi, tcp_out_queue_entry.size - loop .loop - - mov [TCP_OUT_QUEUE+4], 0 - .skip: - ret - - - - - -;---------- TCB state handlers start here - - - - -align 4 -stateTCB_LISTEN: - - DEBUGF 1,"TCBStateHandler: Listen\n" - - test [edx + TCP_Packet.Flags], TH_SYN ; SYN packet? => send syn+ack, open new socket and set connection to established - jz .exit -; Exit if backlog queue is full - mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] - cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog] - jae .exit -; Allocate new socket - push esi edi - call net_socket_alloc - test eax, eax - jz .fail -; Copy structure from current socket to new, including lock - lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied - lea edi, [eax + SOCKET_head.PID] - mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4 - rep movsd - pop edi esi -; Push pointer to new socket to queue - movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] - inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax - - mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address - mov cx, [edx + TCP_Packet.SourcePort] - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], cx - mov ecx, [edx + TCP_Packet.SequenceNumber] - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], ecx - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], ecx - lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] - inc_INET esi ; RCV.NXT - mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx - - mov [ebx + SOCKET_head.lock], 0 - - push eax -; Now construct the response - mov bl, TH_SYN + TH_ACK - xor ecx, ecx - call TCP_send - pop eax - - mov [eax + SOCKET_head.lock], 0 - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED - call notify_network_event - ret - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - .fail: - add esp, 8 - mov [ebx + SOCKET_head.lock], 0 - ret - - -align 4 -stateTCB_SYN_SENT: - - DEBUGF 1,"TCBStateHandler: Syn_Sent\n" - - ; We are awaiting an ACK to our SYN, with a SYM - ; Look at control flags - expecting an ACK - - mov al, [edx + TCP_Packet.Flags] - - test al, TH_RST - jnz .reset ; jump if RST bit set - - push [edx + TCP_Packet.SequenceNumber] ;; - pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] ;; - inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) ;; - - - push [edx + TCP_Packet.AckNumber] ;;;;;; - pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] ;;;;;; - - and al, TH_SYN + TH_ACK - jz .exit ; jump if none of the following is set: RST, SYN, ACK - - test al, TH_ACK - jz .onlysyn ; jump if only SYN bit is set - - ; If we arrived here, SYN and ACK are set - - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED - pushw TH_ACK - - .send: ; Send an ACK - mov eax, ebx - pop bx - push eax - xor ecx, ecx - call TCP_send - pop ebx - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - .reset: - ; TODO: .... - - ; remove all queued TCP packets for this connection ! - - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED - mov [ebx + SOCKET_head.lock], 0 - ret - - .onlysyn: - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED - pushw TH_SYN + TH_ACK - jmp .send - - - -align 4 -stateTCB_SYN_RECEIVED: - - DEBUGF 1,"TCBStateHandler: Syn_received\n" - - test [edx + TCP_Packet.Flags], TH_RST ; reset connection? => LISTEN - jz .check_ack - - push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemotePort] - pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] - push [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.OrigRemoteIP] - pop [ebx + SOCKET_head.end + IPv4_SOCKET.RemoteIP] - - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_LISTEN - jmp .exit - - .check_ack: - test [edx + TCP_Packet.Flags], TH_ACK ; ACK? => connection established! - jz .exit - - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED - mov eax, ebx - call notify_network_event - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - -if 0 - - -align 4 -stateTCB_ESTABLISHED: - - DEBUGF 1,"TCBStateHandler: Established\n" - - mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] - bswap eax - DEBUGF 1,"RCV_NXT is set to:%u\n", eax - bswap eax - cmp eax, [edx + TCP_Packet.SequenceNumber] - jne .exit ;;;;;; - -; check if we received an ACK - test [edx + TCP_Packet.Flags], TH_ACK - jz .no_ack - - mov ax, [edx + TCP_Packet.Window] - xchg al, ah - cmp ax, 1024 - ja @f - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 - @@: - .no_ack: - -; Now, see if we received any data - test ecx, ecx - jz .nodata - -; Calculate next sequencenumber - add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) - - push edx - DEBUGF 1,"Got %u bytes data!\n", ecx -; calculate header length - movzx eax, [edx + TCP_Packet.DataOffset] - and eax, 11110000b - shr eax, 2 - DEBUGF 1,"TCP header size: %u\n", eax - add edx, eax ; now edx points to data - - add esp, 4 - pop esi ; pointer to buffer - add esp, 4 - - sub edx, esi - mov edi, edx ; offset - mov eax, ebx ; socket ptr - - call socket_internal_receiver ; Place the data from packet into socket - -; lea ebx, [eax + SOCKET_head.lock] -; call wait_mutex - mov ebx, eax - pop edx - - test [edx + TCP_Packet.Flags], TH_FIN + TH_RST - jz .ack - - .nodata: - test [edx + TCP_Packet.Flags], TH_FIN + TH_RST - jz .exit - -; Send an ACK to that fin, and enter closewait state - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT -; Remove all resend entries from the queue - mov eax, ebx - call TCP_remove_socket - - .ack: - push ebx - mov ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] - call TCP_queue_ack - pop ebx - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - -end if - - -align 4 -stateTCB_ESTABLISHED: - - DEBUGF 1,"TCBStateHandler: Established\n" - - mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] - bswap eax - DEBUGF 1,"RCV_NXT is set to:%u\n", eax - bswap eax - cmp eax, [edx + TCP_Packet.SequenceNumber] - jne .exit - -; Calculate next sequencenumber - add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) - - test [edx + TCP_Packet.Flags], TH_FIN + TH_RST - jnz .fin - - .check_ack: - test [edx + TCP_Packet.Flags], TH_ACK - jz .exit - - DEBUGF 1,"Received ACK\n" -; First, look at the incoming window. If this is less than or equal to 1024, -; Set the socket window timer to 1. This will stop an additional Packets being queued. -; ** I may need to tweak this value, since I do not know how many Packets are already queued - push ecx - mov cx, [edx + TCP_Packet.Window] - xchg cl, ch - cmp cx, 1024 - ja @f - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 - @@: - pop ecx - -; Now, see if we received any data - test ecx, ecx - jz .exit - - DEBUGF 1,"Got %u bytes data!\n", ecx -; calculate header length - movzx eax, [edx + TCP_Packet.DataOffset] - and eax, 11110000b - shr eax, 2 - DEBUGF 1,"TCP header size: %u\n", eax - add edx, eax ; now edx points to data - - add esp, 4 - pop esi ; pointer to buffer - add esp, 4 - - sub edx, esi - mov edi, edx ; offset - mov eax, ebx ; socket ptr - - call socket_internal_receiver ; Place the data from packet into socket - - lea ebx, [eax + SOCKET_head.lock] - call wait_mutex - mov ebx, eax - - .ack: - mov eax, ebx - mov bl, TH_ACK - push eax - xor ecx, ecx - call TCP_send ; send the ack - pop ebx - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - .fin: ; we received a FIN or RESET -; Remove all resend entries from the queue - mov ecx, TCP_QUEUE_SIZE - mov esi, TCP_OUT_QUEUE+4 - - .removeloop: - cmp [esi + tcp_out_queue_entry.data_ptr], 0 - je .maybe_next - - ; TODO: check if the packets belong to the same tcp connection ! - - DEBUGF 1,"Removing a queued packet\n" - - push [esi + tcp_out_queue_entry.data_ptr] - mov [esi + tcp_out_queue_entry.data_ptr], 0 - dec [TCP_OUT_QUEUE] - call kernel_free - - .maybe_next: - add esi, tcp_out_queue_entry.size - loop .removeloop - -; Send an ACK to that fin, and enter closewait state - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING - jmp .check_ack - - -align 4 -stateTCB_FIN_WAIT_1: - - DEBUGF 1,"TCBStateHandler: Fin_wait_1\n" - - ; We can either receive an ACK of a fin, or a fin - mov al, [edx + TCP_Packet.Flags] - and al, TH_FIN + TH_ACK - - cmp al, TH_ACK - jne @f - - ; It was an ACK - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_FIN_WAIT_2 - jmp .exit - - @@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING - cmp al, TH_FIN - je @f - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT - - @@: - ; Send an ACK - mov eax, ebx - mov bl, TH_ACK - push eax - xor ecx, ecx - call TCP_send - pop ebx - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - - -align 4 -stateTCB_FIN_WAIT_2: - - DEBUGF 1,"TCBStateHandler: Fin_wait_2\n" - - test [edx + TCP_Packet.Flags], TH_FIN - jz .exit - - ; Change state, as we have a fin - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT - - ; Send an ACK - mov eax, ebx - mov bl, TH_ACK - push eax - xor ecx, ecx - call TCP_send - pop ebx - - .exit: - mov [ebx + SOCKET_head.lock], 0 - ret - - - -align 4 -stateTCB_CLOSE_WAIT: - - DEBUGF 1,"TCBStateHandler: close_wait\n" - ; Intentionally left empty - ; socket_close_tcp handles this - - mov [ebx + SOCKET_head.lock], 0 - ret - - - -align 4 -stateTCB_CLOSING: - - DEBUGF 1,"TCBStateHandler: closingn\n" - - ; We can either receive an ACK of a fin, or a fin - test [edx + TCP_Packet.Flags], TH_ACK - jz .exit - - mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT - - .exit: - - mov [ebx + SOCKET_head.lock], 0 - ret - - -align 4 -stateTCB_LAST_ACK: - - DEBUGF 1,"TCBStateHandler: last_ackn\n" - - ; Look at control flags - expecting an ACK - test [edx + TCP_Packet.Flags], TH_ACK - jz .exit - - mov [ebx + SOCKET_head.lock], 0 - - ; delete the socket - stdcall net_socket_free, ebx - - .exit: - ret - - -align 4 -stateTCB_TIME_WAIT: - - DEBUGF 1,"TCBStateHandler: time_wait\n" - - mov [ebx + SOCKET_head.lock], 0 - - ret - - -align 4 -stateTCB_CLOSED: - - DEBUGF 1,"TCBStateHandler: closed\n" - - mov [ebx + SOCKET_head.lock], 0 - - ret - - - ;--------------------------------------------------------------------------- ; ; TCP_API @@ -1269,11 +2007,11 @@ TCP_API: ret .packets_tx: - add eax, TCP_PACKETS_TX + add eax, TCP_segments_tx mov eax, [eax] ret .packets_rx: - add eax, TCP_PACKETS_RX + add eax, TCP_segments_rx mov eax, [eax] ret diff --git a/kernel/branches/net/network/udp.inc b/kernel/branches/net/network/udp.inc index a0af485e0f..bf7f0b479f 100644 --- a/kernel/branches/net/network/udp.inc +++ b/kernel/branches/net/network/udp.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;; UDP.INC ;; @@ -55,12 +55,11 @@ UDP_init: ret - ;----------------------------------------------------------------- ; -; UDP_Handler: +; UDP_input: ; -; Called by IPv4_handler, +; Called by IPv4_input, ; this procedure will inject the udp data diagrams in the application sockets. ; ; IN: Pointer to buffer in [esp] @@ -76,23 +75,20 @@ UDP_init: ; ;----------------------------------------------------------------- align 4 -UDP_handler: +UDP_input: - DEBUGF 1,"UDP_Handler, checksum:%x, size:%u\n", [edx+UDP_Packet.Checksum]:4, ecx + DEBUGF 1,"UDP_input, size:%u\n", ecx ; First validate, checksum: cmp [edx + UDP_Packet.Checksum], 0 jz .no_checksum - xchg edi, esi ; save ipv4 source address so we can look it up later + xchg edi, esi ; save ipv4 source address to edi so we can use it later push edx - - push esi - push edi + push esi edi mov esi, edx - call UDP_checksum ; this destroys edx, ecx and esi (but not edi! :) - + call UDP_checksum ; this destroys edx, ecx and esi (but not edi...) pop edx cmp [edx + UDP_Packet.Checksum], 0 @@ -108,76 +104,64 @@ UDP_handler: mov eax, net_sockets .try_more: mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header + rol si , 8 .next_socket: - mov eax, [eax + SOCKET_head.NextPtr] + mov eax, [eax + SOCKET.NextPtr] or eax, eax jz .dump - cmp [eax + SOCKET_head.Domain], AF_INET4 + cmp [eax + SOCKET.Domain], AF_INET4 jne .next_socket - cmp [eax + SOCKET_head.Type], IP_PROTO_UDP + cmp [eax + SOCKET.Type], IP_PROTO_UDP jne .next_socket - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], si + cmp [eax + UDP_SOCKET.LocalPort], si jne .next_socket - DEBUGF 1,"found socket with matching domain, type and localport\n" + DEBUGF 1,"using socket: %x\n", eax - ; For dhcp, we must allow any remote server to respond. - ; I will accept the first incoming response to be the one - ; I bind to, if the socket is opened with a destination IP address of - ; 255.255.255.255 - cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff - je .ok1 + ;;; TODO: when packet is processed, check more sockets! - cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi ; edi is IPv4 destination address - jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination + cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff + je @f + cmp [eax + IP_SOCKET.RemoteIP], edi ; edi is the packets source address + jne .try_more + @@: - - DEBUGF 1,"Remote Ip matches\n" - .ok1: - - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0 + cmp [eax + UDP_SOCKET.firstpacket], 0 jz .updateport mov si, [edx + UDP_Packet.SourcePort] - cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si + rol si, 8 + cmp [eax + UDP_SOCKET.RemotePort], si jne .dump push ebx - lea ebx, [eax + SOCKET_head.lock] + lea ebx, [eax + SOCKET.lock] call wait_mutex pop ebx - .ok2: - + .updatesock: + inc [UDP_PACKETS_RX] DEBUGF 1,"Found valid UDP packet for socket %x\n", eax lea esi, [edx + UDP_Packet.Data] movzx ecx, [edx + UDP_Packet.Length] rol cx , 8 sub cx , UDP_Packet.Data - inc [UDP_PACKETS_RX] - - pop edi - add esp, 4 - - sub esi, edi - xchg esi, edi - jmp socket_internal_receiver - + jmp SOCKET_input .updateport: - push ebx - lea ebx, [eax + SOCKET_head.lock] + lea ebx, [eax + SOCKET.lock] call wait_mutex pop ebx mov si, [edx + UDP_Packet.SourcePort] - DEBUGF 1,"Changing remote port to: %x\n", si - mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], si - inc [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket] + rol si, 8 + DEBUGF 1,"Changing remote port to: %u\n", si + mov [eax + UDP_SOCKET.RemotePort], si + inc [eax + UDP_SOCKET.firstpacket] - jmp .ok2 + jmp .updatesock .checksum_mismatch: @@ -202,7 +186,7 @@ UDP_handler: ;----------------------------------------------------------------- ; -; UDP_socket_send +; UDP_output ; ; IN: eax = socket pointer ; ecx = number of bytes to send @@ -211,27 +195,31 @@ UDP_handler: ;----------------------------------------------------------------- align 4 -UDP_socket_send: +UDP_output: - mov edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once - DEBUGF 1,"local port: %x, remote port: %x\n",\ - [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\ - [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4 - mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] - mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] + DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi - DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx + mov dx, [eax + UDP_SOCKET.RemotePort] + DEBUGF 1,"remote port: %u\n", dx + rol dx, 8 + rol edx, 16 + mov dx, [eax + UDP_SOCKET.LocalPort] + DEBUGF 1,"local port: %u\n", dx + rol dx, 8 + + + mov ebx, [eax + IP_SOCKET.LocalIP] + mov eax, [eax + IP_SOCKET.RemoteIP] mov di , IP_PROTO_UDP sub esp, 8 ; Data ptr and data size will be placed here add ecx, UDP_Packet.Data -; TODO: fill in: dx = fragment id +;;; TODO: fragment id push edx esi - call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6 - cmp edi, -1 - je .fail + call IPv4_create_packet + jz .fail mov [esp + 8], eax ; pointer to buffer start mov [esp + 8 + 4], edx ; buffer size @@ -251,22 +239,22 @@ UDP_socket_send: rep movsb pop ecx edi - pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers + pop dword [edi + UDP_Packet.SourcePort] mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum ; Checksum mov esi, edi - pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. + pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. pushd [edi-8] ; source address call UDP_checksum inc [UDP_PACKETS_TX] DEBUGF 1,"Sending UDP Packet to device %x\n", ebx - jmp ETH_sender + + jmp NET_send .fail: - ; todo: queue the packet add esp, 8+8 ret @@ -275,7 +263,7 @@ UDP_socket_send: ;----------------------------------------------------------------- ; -; checksum_udp +; UDP_checksum ; ; This is the fast procedure to create or check a UDP header ; - To create a new checksum, the checksum field must be set to 0 before computation