Subversion Repositories Kolibri OS

Rev

Rev 1726 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                   ;;
  3. ;;    IRC CLIENT for KolibriOS                       ;;
  4. ;;                                                   ;;
  5. ;;    License: GPL / See file COPYING for details    ;;
  6. ;;    Copyright 2004 (c) Ville Turjanmaa             ;;
  7. ;;    Copyright 2009 (c) CleverMouse                 ;;
  8. ;;                                                   ;;
  9. ;;    Compile with FASM for Kolibri                  ;;
  10. ;;                                                   ;;
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12.  
  13. version equ '0.6'
  14.  
  15.  
  16. ;__DEBUG__ equ 1
  17. ;__DEBUG_LEVEL__ equ 1
  18.  
  19. use32
  20.  
  21.                 org     0x0
  22.  
  23.                 db      'MENUET01'              ; 8 byte id
  24.                 dd      0x01                    ; required os
  25.                 dd      START                   ; program start
  26.                 dd      initialized_size        ; program image size
  27.                 dd      0x100000                ; required amount of memory
  28.                 dd      0x100000
  29.                 dd      0,0
  30.  
  31. include "../../../macros.inc"
  32. include "../../../proc32.inc"
  33. include "../../../develop/libraries/network/network.inc"
  34. include "dll.inc"
  35. ;include "fdo.inc"
  36. include "eth.inc"
  37. include "lang.inc"
  38.  
  39. ; connection statuses
  40. STATUS_DISCONNECTED = 0 ; disconnected
  41. STATUS_RESOLVING    = 1 ; resolving server name
  42. STATUS_CONNECTING   = 2 ; connecting to server
  43. STATUS_CONNECTED    = 3 ; connected
  44. ; where to display status
  45. STATUS_X = 25 + 22*6
  46. STATUS_Y = 183 + 7*12
  47.  
  48. ; supported encodings
  49. CP866 = 0
  50. CP1251 = 1
  51. UTF8 = 2
  52. ; where to display encoding
  53. ENCODING_X = 25 + 15*6
  54. ENCODING_Y = 183 + 3*12
  55.  
  56. def_server_name db      'chat.freenode.net',0             ; default server name
  57.  
  58. user_nick       dd      12                                ; length
  59.                 db      'kolibri_user           '         ; string
  60. user_nick_max = $ - user_nick - 4
  61.  
  62. user_real_name  dd      14                                ; length
  63.                 db      'KolibriOS User         '         ; string
  64. user_real_name_max = $ - user_real_name - 4
  65.  
  66.  
  67. START:                          ; start of execution
  68.  
  69.     stdcall dll.Load, @IMPORT
  70.     test eax,eax
  71.     jnz  exit
  72.  
  73.     mov  eax,40
  74.     mov  ebx,11000111b
  75.     mcall
  76.     mcall 60, 1, ipcbuf, ipcbuf.size
  77.     mcall 9, 0xe0000, -1
  78.     mov  eax,[ebx+process_information.PID]
  79.     mov  [main_PID],eax
  80.  
  81.         mov     esi, def_server_name
  82.         mov     edi, irc_server_name
  83. @@:
  84.         lodsb
  85.         stosb
  86.         test    al, al
  87.         jnz     @b
  88.  
  89.     mov  edi,I_END
  90.     mov  ecx,60*120
  91.     mov  al,32
  92.     cld
  93.     rep  stosb
  94.  
  95.     mov  eax,[rxs]
  96.     imul eax,11
  97.     mov  [pos],eax
  98.  
  99.     mov  ebp,0
  100.     mov  edx,I_END
  101.  
  102. redraw:                         ; redraw
  103.     call draw_window            ; at first, draw the window
  104.  
  105. still:
  106.  
  107.     mov  eax,10                 ; wait here for event
  108.     mcall
  109.  
  110.     dec  eax                    ; redraw
  111.     je   redraw
  112.     dec  eax                    ; key
  113.     je   main_window_key
  114.     dec  eax                    ; button
  115.     je   button
  116.     cmp  al,4
  117.     jz   ipc
  118.  
  119.     call process_network_event
  120.  
  121.     cmp  [I_END+120*60],byte 1
  122.     jne  no_main_update
  123.     mov  [I_END+120*60],byte 0
  124.     mov  edx,I_END
  125.     call draw_channel_text
  126.   no_main_update:
  127.  
  128.     call print_channel_list
  129.  
  130.     jmp  still
  131.  
  132. button:                         ; button
  133.  
  134.     mov  eax,17                 ; get id
  135.     mcall
  136.  
  137.     cmp  ah,1                   ; close program
  138.     jne  noclose
  139. exit:
  140.     or   eax,-1
  141.     mcall
  142.   noclose:
  143.     cmp  ah,21
  144.     jne  no_change_encoding
  145.     cmp  byte[edx-1],0
  146.     jnz  still
  147.     mov  eax,[encoding]
  148.     inc  eax
  149.     mov  edx,msgbox_struct
  150.     mov  byte[edx],al
  151.     mov  byte[edx-1],1 ; msgbox is running
  152.     push mb_stack
  153.     push edx
  154.     call [mb_create]
  155.     push msgbox_func_array
  156.     call [mb_setfunctions]
  157.     jmp  still
  158.   no_change_encoding:
  159.  
  160.     call socket_commands
  161.  
  162.     jmp  still
  163.  
  164. ipc:
  165.     mov  edx,msgbox_struct
  166.     cmp  byte[edx-1],0
  167.     jz   @f
  168.     mov  byte[edx-1],0
  169.     mov  al,[edx]
  170.     dec  eax
  171.     mov  byte[encoding],al
  172.     call update_encoding
  173.     jmp  ipc_done
  174. @@:
  175.     call process_command
  176. ipc_done:
  177.     mov  dword [ipcbuf+4], 8
  178.     jmp  still
  179.  
  180. main_window_key:
  181.  
  182.     mov  eax,2
  183.     mcall
  184.  
  185.     shr  eax,8
  186.  
  187.     cmp  eax,8
  188.     jne  no_bks2
  189.     cmp  [xpos],0
  190.     je   still
  191.     dec  [xpos]
  192.     call print_entry
  193.     jmp  still
  194.    no_bks2:
  195.  
  196.     cmp  eax,20
  197.     jbe  no_character2
  198.     mov  ebx,[xpos]
  199.     mov  [send_string+ebx],al
  200.     inc  [xpos]
  201.     cmp  [xpos],80
  202.     jb   noxposdec
  203.     mov  [xpos],79
  204.   noxposdec:
  205.     call print_entry
  206.     jmp  still
  207.   no_character2:
  208.  
  209.     cmp  eax,13
  210.     jne  no_send2
  211.     cmp  [xpos],0
  212.     je   no_send2
  213.     cmp  [send_string],byte '/'   ; server command
  214.     jne  no_send2
  215.     call process_command
  216.     jmp  still
  217.   no_send2:
  218.  
  219.     jmp  still
  220.  
  221.  
  222. socket_commands:
  223.  
  224.     cmp  ah,22       ; connect
  225.     jnz  tst3
  226.  
  227. ; ignore if status is not "disconnected"
  228.         cmp     [status], STATUS_DISCONNECTED
  229.         jnz     .nothing
  230.  
  231. ; start name resolving
  232.         inc     [status]        ; was STATUS_DISCONNECTED, now STATUS_RESOLVING
  233.         push    gai_reqdata
  234.         push    ip_list
  235.         push    0
  236.         push    0
  237.         push    irc_server_name
  238.         call    [getaddrinfo_start]
  239.         test    eax, eax
  240.         jns     getaddrinfo_done
  241.         call    update_status
  242. .nothing:
  243.         ret
  244.  
  245.   tst3:
  246.  
  247.  
  248.     cmp  ah,23        ; write userinfo
  249.     jnz  tst4
  250.  
  251. ; ignore if status is not "connected"
  252.         cmp     [status], STATUS_CONNECTED
  253.         jnz     .nothing
  254.  
  255. ; create packet in packetbuf
  256.         mov     edi, packetbuf
  257.         mov     edx, edi
  258.         mov     esi, string0
  259.         mov     ecx, string0l-string0
  260.         rep     movsb
  261.         mov     esi, user_real_name+4
  262.         mov     ecx, [esi-4]
  263.         rep     movsb
  264.         mov     al, 13
  265.         stosb
  266.         mov     al, 10
  267.         stosb
  268.         mov     esi, string1
  269.         mov     ecx, string1l-string1
  270.         rep     movsb
  271.         mov     esi, user_nick+4
  272.         mov     ecx, [esi-4]
  273.         rep     movsb
  274.         mov     al, 13
  275.         stosb
  276.         mov     al, 10
  277.         stosb
  278. ; send packet
  279.         xchg    edx, edi
  280.         sub     edx, edi
  281.         mov     esi, edi
  282.         mcall   53, 7, [socket]
  283.     .nothing:
  284.         ret
  285.  
  286.   tst4:
  287.  
  288.  
  289.     cmp  ah,24     ; close socket
  290.     jz   disconnect
  291.   no_24:
  292.  
  293.  
  294.     ret
  295.  
  296. getaddrinfo_done:
  297. ; The address resolving is done.
  298. ; If eax is zero, address is resolved, otherwise there was some problems.
  299.         test    eax, eax
  300.         jz      .good
  301. .disconnect:
  302. ; Change status to "disconnected" and return.
  303.         and     [status], 0
  304.         call    update_status
  305.         ret
  306. .good:
  307. ; We got a list of IP addresses. Try to connect to first of them.
  308.         mov     eax, [ip_list]
  309.         mov     esi, [eax + addrinfo.ai_addr]
  310.         mov     esi, [esi + sockaddr_in.sin_addr]
  311.         push    eax
  312.         call    [freeaddrinfo]
  313.         mcall   53, 5, 0, 6667, , 1
  314.         cmp     eax, -1
  315.         jz      .disconnect
  316. ; Socket has been opened. Save handle and change status to "connecting".
  317.         mov     [socket], eax
  318.         inc     [status]        ; was STATUS_RESOLVING, now STATUS_CONNECTING
  319.         call    update_status
  320.         ret
  321.  
  322. process_network_event:
  323. ; values for status: 0, 1, 2, 3
  324.         mov     eax, [status]
  325.         dec     eax
  326. ; 0 = STATUS_DISCONNECTED - do nothing
  327. ; (ignore network events if we are disconnected from network)
  328.         js      .nothing
  329. ; 1 = STATUS_RESOLVING
  330.         jz      .resolving
  331. ; 2 = STATUS_CONNECTING
  332.         dec     eax
  333.         jz      .connecting
  334. ; 3 = STATUS_CONNECTED
  335.         jmp     .connected
  336. .resolving:
  337. ; We are inside address resolving. Let the network library work.
  338.         push    ip_list
  339.         push    gai_reqdata
  340.         call    [getaddrinfo_process]
  341. ; Negative returned value means that the resolving is not yet finished,
  342. ; and we continue the loop without status change.
  343. ; Zero and positive values are handled by getaddrinfo_done.
  344.         test    eax, eax
  345.         jns     getaddrinfo_done
  346. .nothing:
  347.         ret
  348. .connecting:
  349. ; We are connecting to the server, and socket status has changed.
  350.         mcall   53, 6, [socket]
  351. ; Possible values for status: SYN_SENT=2, SYN_RECEIVED=3, ESTABLISHED=4, CLOSE_WAIT=7
  352. ; First two mean that we are still connecting, and we must continue wait loop
  353. ; without status change.
  354. ; Last means that server has immediately closed the connection,
  355. ; and status becomes "disconnected".
  356.         cmp     eax, 4
  357.         jb      .nothing
  358.         jz      .established
  359.         and     [status], 0
  360.         call    update_status
  361. ; close socket
  362.         mcall   53, 8
  363.         ret
  364. .established:
  365. ; The connection has been established, change status from "connecting" to "connected".
  366.         inc     [status]
  367.         call    update_status
  368. ; Fall through to .connected, because some data can be already in buffer.
  369. .connected:
  370.         call    read_incoming_data
  371. ; Handle closing socket by the server.
  372.         mcall   53, 6, [socket]
  373.         cmp     eax, 4
  374.         jnz     disconnect
  375.         ret
  376.  
  377. disconnect:
  378. ; Release all allocated resources.
  379. ; Exact actions depend on current status.
  380.         mov     eax, [status]
  381.         dec     eax
  382. ; 0 = STATUS_DISCONNECTED - do nothing
  383.         js      .nothing
  384. ; 1 = STATUS_RESOLVING
  385.         jz      .resolving
  386. ; 2 = STATUS_CONNECTING, 3 = STATUS_CONNECTED
  387. ; In both cases we should close the socket.
  388.         mcall   53, 8, [socket]
  389.         jmp     .disconnected
  390. .resolving:
  391. ; Let the network library handle abort of resolving process.
  392.         push    gai_reqdata
  393.         call    [getaddrinfo_abort]
  394. .disconnected:
  395. ; In all cases, set status to "disconnected".
  396.         and     [status], 0
  397.         call    update_status
  398. .nothing:
  399.         ret
  400.  
  401. msgbox_notify:
  402.         inc     byte [msgbox_running]
  403.         mcall   60,2,[main_PID],0,1
  404.         ret
  405.  
  406. print_channel_list:
  407.  
  408.     pusha
  409.  
  410.     mov  eax,13
  411.     mov  ebx,415*65536+6*13
  412.     mov  ecx,27*65536+12*10
  413.     mov  edx,0xffffff
  414.     mcall
  415.  
  416.     mov  eax,4
  417.     mov  ebx,415*65536+27
  418.     mov  ecx,[index_list_1]
  419.     mov  edx,channel_list+32
  420.   newch:
  421.     movzx esi,byte [edx+31]
  422.     and  esi,0x1f
  423.     mcall
  424.     add  edx,32
  425.     add  ebx,12
  426.     cmp  edx,channel_list+32*10
  427.     jbe  newch
  428.  
  429.   no_channel_list:
  430.  
  431.     popa
  432.  
  433.     ret
  434.  
  435.  
  436. print_user_list:
  437.  
  438.     pusha
  439.  
  440.   newtry:
  441.  
  442.     mov  edx,ebp
  443.     imul edx,120*80
  444.     add  edx,120*60+8+I_END
  445.     cmp  [edx],byte 1
  446.     je   nonp
  447.  
  448.     mov  edx,ebp
  449.     imul edx,120*80
  450.     add  edx,120*70+I_END
  451.     mov  edi,edx
  452.  
  453.     mov  eax,[edx-8]
  454.     mov  ebx,[edx-4]
  455.     add  ebx,edx
  456.     sub  ebx,3
  457.     inc  eax
  458.     dec  edx
  459.   newnss:
  460.     inc  edx
  461.     dec  eax
  462.     jz   startuu
  463.   asdf:
  464.     cmp  [edx],word '  '
  465.     jne  nodouble
  466.     inc  edx
  467.   nodouble:
  468.     cmp  [edx],byte ' '
  469.     je   newnss
  470.     inc  edx
  471.     cmp  edx,ebx
  472.     jbe  asdf
  473.     dec  dword [edi-8]
  474.  
  475.     popa
  476.     ret
  477.  
  478.   startuu:
  479.  
  480.     cmp  [edx],byte ' '
  481.     jne  startpr
  482.     inc  edx
  483.   startpr:
  484.  
  485.     pusha
  486.     mov  eax,13
  487.     mov  ebx,415*65536+6*13
  488.     mov  ecx,27*65536+12*10
  489.     mov  edx,0xffffff
  490.     mcall
  491.     popa
  492.  
  493.     mov  eax,4
  494.     mov  ebx,415*65536+27
  495.  
  496.     mov  ebp,0
  497.   newuser:
  498.  
  499.     mov  esi,0
  500.   newusers:
  501.     cmp  [edx+esi],byte ' '
  502.     je   do_print
  503.     inc  esi
  504.     cmp  esi,20
  505.     jbe  newusers
  506.   do_print:
  507.  
  508.     mov  ecx,[index_list_1]
  509.     cmp  [edx],byte '@'
  510.     jne  no_op
  511.     mov  ecx,[index_list_2]
  512.   no_op:
  513.  
  514.     mcall
  515.  
  516.     inc  ebp
  517.     cmp  ebp,10
  518.     je   nonp
  519.  
  520.     add  ebx,12
  521.  
  522.     add  edx,esi
  523.  
  524.     inc  edx
  525.     cmp  [edx],byte ' '
  526.     jne  newuser
  527.     inc  edx
  528.     jmp  newuser
  529.  
  530.   nonp:
  531.  
  532.     popa
  533.  
  534.     ret
  535.  
  536.  
  537. start_user_list_at dd 0x0
  538.  
  539. recode_to_cp866:
  540.         rep     movsb
  541.         ret
  542.  
  543. recode_to_cp1251:
  544.         xor     eax, eax
  545.         jecxz   .nothing
  546.   .loop:
  547.         lodsb
  548.         cmp     al,0x80
  549.         jb      @f
  550.         mov     al,[cp866_table-0x80+eax]
  551.     @@: stosb
  552.         loop    .loop
  553.   .nothing:
  554.         ret
  555.  
  556. recode_to_utf8:
  557.         jecxz   .nothing
  558.   .loop:
  559.         lodsb
  560.         cmp     al, 0x80
  561.         jb      .single_byte
  562.         and     eax, 0x7F
  563.         mov     ax, [utf8_table+eax*2]
  564.         stosw
  565.         loop    .loop
  566.         ret
  567.   .single_byte:
  568.         stosb
  569.         loop    .loop
  570.   .nothing:
  571.         ret
  572.  
  573. recode:
  574.         mov     eax, [encoding]
  575.         jmp     [recode_proc+eax*4]
  576.  
  577. process_command:
  578.  
  579.     pusha
  580.  
  581.     mov  eax,[xpos]
  582.     mov  [send_string+eax+0],byte 13
  583.     mov  [send_string+eax+1],byte 10
  584.  
  585.     mov  eax,[rxs]
  586.     imul eax,11
  587.     mov  [pos],eax
  588.     mov  eax,[send_to_channel]
  589.     imul eax,120*80
  590.     add  eax,I_END
  591.     mov  [text_start],eax
  592.  
  593.     cmp  [send_string],byte '/'   ; server command
  594.     je   server_command
  595.  
  596. ; Ignore data commands when not connected.
  597.         cmp     [status], STATUS_CONNECTED
  598.         jnz     sdts_ret
  599.  
  600.     mov  bl,13
  601.     call print_character
  602.     mov  bl,10
  603.     call print_character
  604.     mov  bl,'<'
  605.     call print_character
  606.  
  607.     mov  esi,user_nick+4
  608.     mov  ecx,[user_nick]
  609.   newnp:
  610.     mov  bl,[esi]
  611.     call print_character
  612.     inc  esi
  613.     loop newnp
  614.  
  615.     mov  bl,'>'
  616.     call print_character
  617.     mov  bl,' '
  618.     call print_character
  619.  
  620.     mov  ecx,[xpos]
  621.     mov  esi,send_string
  622.   newcw:
  623.     mov  bl,[esi]
  624.     call print_character
  625.     inc  esi
  626.     loop newcw
  627.  
  628.     mov  eax,dword [send_to_channel]
  629.     shl  eax,5
  630.     add  eax,channel_list
  631.     mov  esi,eax
  632.  
  633.     mov  edi,send_string_header+8
  634.     movzx ecx,byte [eax+31]
  635.     cld
  636.     rep  movsb
  637.  
  638.     mov  [edi],word ' :'
  639.  
  640.     mov   esi, send_string_header
  641.     mov   ecx,10
  642.     movzx ebx,byte [eax+31]
  643.     add   ecx,ebx
  644.  
  645.     mov   edi, packetbuf
  646.     rep   movsb
  647.  
  648.     mov  esi,send_string
  649.     mov  ecx,[xpos]
  650.     inc  ecx
  651.  
  652.         call    recode
  653.  
  654.         mov     esi, packetbuf
  655.         mov     edx, edi
  656.         sub     edx, esi
  657.         mcall   53, 7, [socket]
  658.  
  659.         mov     [xpos], 0
  660.     jmp  sdts_ret
  661.  
  662.   server_command:
  663.  
  664.     cmp  [send_string+1],dword 'anic'
  665.     jne  no_set_nick
  666.  
  667.     mov  ecx,[xpos]
  668.     sub  ecx,7
  669.     cmp  ecx,user_nick_max
  670.     jb   @f
  671.     mov  ecx,user_nick_max
  672.   @@:
  673.     mov  [user_nick],ecx
  674.  
  675.     mov  esi,send_string+7
  676.     mov  edi,user_nick+4
  677.     cld
  678.     rep  movsb
  679.  
  680.     pusha
  681.     mov  edi,text+70*1+15
  682.     mov  al,32
  683.     mov  ecx,15
  684.     cld
  685.     rep  stosb
  686.     popa
  687.  
  688.     mov  esi,user_nick+4
  689.     mov  edi,text+70*1+15
  690.     mov  ecx,[esi-4]
  691.     cld
  692.     rep  movsb
  693.  
  694.     mov  [xpos],0
  695.     call draw_window
  696.  
  697.     popa
  698.     ret
  699.  
  700.   no_set_nick:
  701.  
  702.     cmp  [send_string+1],dword 'area'
  703.     jne  no_set_real_name
  704.  
  705.     mov  ecx,[xpos]
  706.     sub  ecx,7
  707.     cmp  ecx,user_real_name_max
  708.     jb   @f
  709.     mov  ecx,user_real_name_max
  710.   @@:
  711.     mov  [user_real_name],ecx
  712.  
  713.     mov  esi,send_string+7
  714.     mov  edi,user_real_name+4
  715.     cld
  716.     rep  movsb
  717.  
  718.     pusha
  719.     mov  edi,text+70*0+15
  720.     mov  al,32
  721.     mov  ecx,15
  722.     cld
  723.     rep  stosb
  724.     popa
  725.  
  726.     mov  esi,user_real_name+4
  727.     mov  edi,text+70*0+15
  728.     mov  ecx,[esi-4]
  729.     rep  movsb
  730.  
  731.     mov  [xpos],0
  732.     call draw_window
  733.  
  734.     popa
  735.     ret
  736.  
  737.   no_set_real_name:
  738.  
  739.     cmp  [send_string+1],dword 'aser'
  740.     jne  no_set_server
  741.  
  742.     mov  ecx,[xpos]
  743.     sub  ecx,7
  744.  
  745.     mov  esi,send_string+7
  746.     mov  edi,irc_server_name
  747.     rep  movsb
  748.     mov  al,0
  749.     stosb
  750.  
  751.     pusha
  752.     mov  edi,text+70*2+15
  753.     mov  al,32
  754.     mov  ecx,15
  755.     cld
  756.     rep  stosb
  757.     popa
  758.  
  759.     mov  ecx,[xpos]
  760.     sub  ecx,7
  761.     mov  esi,send_string+7
  762.     mov  edi,text+70*2+15
  763.     rep  movsb
  764.  
  765.     mov  [xpos],0
  766.     call draw_window
  767.  
  768.     popa
  769.     ret
  770.  
  771.    no_set_server:
  772.  
  773. ; All other commands require a connection to the server.
  774.         cmp     [status], STATUS_CONNECTED
  775.         jnz     sdts_ret
  776.  
  777.  
  778.     cmp  [send_string+1],dword 'quer'
  779.     jne  no_query_create
  780.  
  781.     mov  edi,I_END+120*80
  782.     mov  eax,1 ; create channel window - search for empty slot
  783.    newse2:
  784.     mov  ebx,eax
  785.     shl  ebx,5
  786.     cmp  dword [channel_list+ebx],dword '    '
  787.     je   free_found2
  788.     add  edi,120*80
  789.     inc  eax
  790.     cmp  eax,[max_windows]
  791.     jb   newse2
  792.  
  793.   free_found2:
  794.  
  795.     mov  edx,send_string+7
  796.  
  797.     mov  ecx,[xpos]
  798.     sub  ecx,7
  799.     mov  [channel_list+ebx+31],cl
  800.  
  801.     call create_channel_name
  802.  
  803.     push edi
  804.     push eax
  805.     mov  [edi+120*60+8],byte 1 ; query window
  806.     mov  al,32
  807.     mov  ecx,120*60
  808.     cld
  809.     rep  stosb
  810.     pop  eax
  811.     pop  edi
  812.  
  813.     ; eax has the free position
  814. ;    mov  [thread_screen],edi
  815.     call create_channel_window
  816.  
  817.     mov  [xpos],0
  818.  
  819.     popa
  820.     ret
  821.  
  822.   no_query_create:
  823.  
  824.  
  825.     mov  esi, send_string+1
  826.     mov  ecx, [xpos]
  827.     inc  ecx
  828.     mov  edi, packetbuf
  829.     call recode
  830.     mov  esi, packetbuf
  831.     mov  edx, edi
  832.     sub  edx, esi
  833.  
  834.     mov  eax, 53      ; write server command
  835.     mov  ebx, 7
  836.     mov  ecx, [socket]
  837.     mcall
  838.  
  839.   send_done:
  840.  
  841.     mov  [xpos],0
  842.  
  843.     cmp  [send_string+1],dword 'quit'
  844.     jne  no_quit_server
  845.     mov  eax,5
  846.     mov  ebx,200
  847.     mcall
  848.  
  849.     mov  eax, 53      ; close socket
  850.     mov  ebx, 8
  851.     mov  ecx, [socket]
  852.     mcall
  853.  
  854.     mov  ecx,[max_windows]
  855.     mov  edi,I_END
  856.   newclose:
  857.     mov  [edi+120*60+4],byte  1
  858.     call notify_channel_thread
  859.     add  edi,120*80
  860.     loop newclose
  861.  
  862.     popa
  863.     ret
  864.  
  865.   no_quit_server:
  866.  
  867.   sdts_ret:
  868.  
  869.     popa
  870.     ret
  871.  
  872. get_next_byte:
  873. ; Load next byte from the packet, translating to cp866 if necessary
  874. ; At input esi = pointer to data, edx = limit of data
  875. ; Output is either (translated) byte in al with CF set or CF cleared.
  876.         mov     eax, [encoding]
  877.         jmp     [get_byte_table+eax*4]
  878.  
  879. get_byte_cp866:
  880.         cmp     esi, edx
  881.         jae     .nothing
  882.         lodsb
  883. .nothing:
  884.         ret
  885.  
  886. get_byte_cp1251:
  887.         cmp     esi, edx
  888.         jae     .nothing
  889.         lodsb
  890.         cmp     al, 0x80
  891.         jb      @f
  892.         and     eax, 0x7F
  893.         mov     al, [cp1251_table+eax]
  894. @@:
  895.         stc
  896. .nothing:
  897.         ret
  898.  
  899. get_byte_utf8:
  900. ; UTF8 decoding is slightly complicated.
  901. ; One character can occupy one or more bytes.
  902. ; The boundary in packets theoretically can be anywhere in data,
  903. ; so this procedure keeps internal state between calls and handles
  904. ; one byte at a time, looping until character is read or packet is over.
  905. ; Globally, there are two distinct tasks: decode byte sequence to unicode char
  906. ; and convert this unicode char to our base encoding (that is cp866).
  907. ; 1. Check that there are data.
  908.         cmp     esi, edx
  909.         jae     .nothing
  910. ; 2. Load byte.
  911.         lodsb
  912.         movzx   ecx, al
  913. ; 3. Bytes in an UTF8 sequence can be of any of three types.
  914. ; If most significant bit is cleared, sequence is one byte and usual ASCII char.
  915. ; First byte of a sequence must be 11xxxxxx, other bytes are 10yyyyyy.
  916.         and     al, 0xC0
  917.         jns     .single_byte
  918.         jp      .first_byte
  919. ; 4. This byte is not first in UTF8 sequence.
  920. ; 4a. Check that the sequence was started. If no, it is invalid byte
  921. ; and we simply ignore it.
  922.         cmp     [utf8_bytes_rest], 0
  923.         jz      get_byte_utf8
  924. ; 4b. Otherwise, it is really next byte and it gives some more bits of char.
  925.         mov     eax, [utf8_char]
  926.         shl     eax, 6
  927.         lea     eax, [eax+ecx-0x80]
  928. ; 4c. Decrement number of bytes rest in the sequence.
  929. ; If it goes to zero, character is read, so return it.
  930.         dec     [utf8_bytes_rest]
  931.         jz      .got_char
  932.         mov     [utf8_char], eax
  933.         jmp     get_byte_utf8
  934. ; 5. If the byte is first in UTF8 sequence, calculate the number of leading 1s
  935. ; - it equals total number of bytes in the sequence; some other bits rest for
  936. ; leading bits in the character.
  937. .first_byte:
  938.         mov     eax, -1
  939. @@:
  940.         inc     eax
  941.         add     cl, cl
  942.         js      @b
  943.         mov     [utf8_bytes_rest], eax
  944.         xchg    eax, ecx
  945.         inc     ecx
  946.         shr     al, cl
  947.         mov     [utf8_char], eax
  948.         jmp     get_byte_utf8
  949. ; 6. If the byte is ASCII char, it is the character.
  950. .single_byte:
  951.         xchg    eax, ecx
  952. .got_char:
  953. ; We got the character, now abandon a possible sequence in progress.
  954.         and     [utf8_bytes_rest], 0
  955. ; Now second task. The unicode character is in eax, and now we shall convert it
  956. ; to cp866.
  957.         cmp     eax, 0x80
  958.         jb      .done
  959. ; 0x410-0x43F -> 0x80-0xAF, 0x440-0x44F -> 0xE0-0xEF, 0x401 -> 0xF0, 0x451 -> 0xF1
  960.         cmp     eax, 0x401
  961.         jz      .YO
  962.         cmp     eax, 0x451
  963.         jz      .yo
  964.         cmp     eax, 0x410
  965.         jb      .unrecognized
  966.         cmp     eax, 0x440
  967.         jb      .part1
  968.         cmp     eax, 0x450
  969.         jae     .unrecognized
  970.         sub     al, (0x40-0xE0) and 0xFF
  971.         ret
  972. .part1:
  973.         sub     al, 0x10-0x80
  974. .nothing:
  975. .done:
  976.         ret
  977. .unrecognized:
  978.         mov     al, '?'
  979.         stc
  980.         ret
  981. .YO:
  982.         mov     al, 0xF0
  983.         stc
  984.         ret
  985. .yo:
  986.         mov     al, 0xF1
  987.         stc
  988.         ret
  989.  
  990. read_incoming_data:
  991.         pusha
  992. .packetloop:
  993. .nextpacket:
  994.         mcall   53, 11, [socket], packetbuf, 1024
  995.         test    eax, eax
  996.         jz      .nothing
  997.         mov     esi, edx        ; esi = pointer to data
  998.         add     edx, eax        ; edx = limit of data
  999. .byteloop:
  1000.         call    get_next_byte
  1001.         jnc     .nextpacket
  1002.         cmp     al, 10
  1003.         jne     .no_start_command
  1004.         mov     [cmd], 1
  1005. .no_start_command:
  1006.         cmp     al, 13
  1007.         jne     .no_end_command
  1008.         mov     ebx, [cmd]
  1009.         mov     byte [ebx+command-2], 0
  1010.         call    analyze_command
  1011.         mov     edi, command
  1012.         mov     ecx, 250
  1013.         xor     eax, eax
  1014.         rep     stosb
  1015.         mov     [cmd], eax
  1016.         mov     al, 13
  1017. .no_end_command:
  1018.         mov     ebx, [cmd]
  1019.         cmp     ebx, 512
  1020.         jge     @f
  1021.         mov     [ebx+command-2], al
  1022.         inc     [cmd]
  1023. @@:
  1024.         jmp     .byteloop
  1025. .nothing:
  1026.         popa
  1027.         ret
  1028.  
  1029.  
  1030. create_channel_name:
  1031.  
  1032.     pusha
  1033.  
  1034.   search_first_letter:
  1035.     cmp  [edx],byte ' '
  1036.     jne  first_letter_found
  1037.     inc  edx
  1038.     jmp  search_first_letter
  1039.   first_letter_found:
  1040.  
  1041.     mov  esi,edx
  1042.     mov  edi,channel_list
  1043.     add  edi,ebx
  1044.     mov  ecx,30
  1045.     xor  eax,eax
  1046.   newcase:
  1047.     mov  al,[esi]
  1048.     cmp  eax,'a'
  1049.     jb   nocdec
  1050.     cmp  eax,'z'
  1051.     jg   nocdec
  1052.     sub  al,97-65
  1053.   nocdec:
  1054.     mov  [edi],al
  1055.     inc  esi
  1056.     inc  edi
  1057.     loop newcase
  1058.  
  1059.     popa
  1060.  
  1061.     ret
  1062.  
  1063.  
  1064. create_channel_window:
  1065.  
  1066.     pusha
  1067.  
  1068.     mov  [cursor_on_off],0
  1069.  
  1070. ;    mov  [thread_nro],eax
  1071.  
  1072.     mov  edx,[thread_stack]
  1073.     sub  edx,8
  1074.     mov  [edx],eax
  1075.     mov  [edx+4],edi
  1076.     mov  eax,51
  1077.     mov  ebx,1
  1078.     mov  ecx,channel_thread
  1079.     mcall
  1080.     mov  [edi+120*60+12], eax
  1081.  
  1082.     add  [thread_stack],0x4000
  1083. ;    add  [thread_screen],120*80
  1084.  
  1085.     popa
  1086.  
  1087.     ret
  1088.  
  1089.  
  1090. print_entry:
  1091.  
  1092.     pusha
  1093.  
  1094.     mov  eax,13
  1095.     mov  ebx,8*65536+6*80
  1096.     mov  ecx,151*65536+13
  1097.     mov  edx,0xffffff
  1098.     mcall
  1099.  
  1100.     mov  eax,4
  1101.     mov  ebx,8*65536+154
  1102.     mov  ecx,0x000000
  1103.     mov  edx,send_string
  1104.     mov  esi,[xpos]
  1105.     mcall
  1106.  
  1107.     popa
  1108.  
  1109. ; Fall through to draw_cursor.
  1110. ;    ret
  1111.  
  1112. draw_cursor:
  1113.  
  1114.     pusha
  1115.  
  1116.     mov  eax,9
  1117.     mov  ebx,0xe0000
  1118.     mov  ecx,-1
  1119.     mcall
  1120.  
  1121.     cmp  ax,word [0xe0000+4]
  1122.     setnz dl
  1123.     movzx edx,dl
  1124.     neg edx
  1125.     and edx,0xffffff
  1126. ;    jne  no_blink
  1127.  
  1128. ;    call print_entry
  1129.  
  1130.     mov  ebx,[xpos]
  1131.     imul ebx,6
  1132.     add  ebx,8
  1133.     mov  cx,bx
  1134.     shl  ebx,16
  1135.     mov  bx,cx
  1136.     mov  ecx,151*65536+163
  1137.     mov  eax,38
  1138.     mcall
  1139.  
  1140.     popa
  1141.  
  1142.     ret
  1143.  
  1144. ;  no_blink:
  1145. ;
  1146. ;    mov  eax,13
  1147. ;    mov  ebx,8*65536+6*60
  1148. ;    mov  ecx,151*65536+13
  1149. ;    mov  edx,0xffffff
  1150. ;    mcall
  1151.  
  1152.     popa
  1153.  
  1154.     ret
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160. set_channel:
  1161.  
  1162.     pusha
  1163.  
  1164.     ; UPPER / LOWER CASE CHECK
  1165.  
  1166.     mov  esi,eax
  1167.     mov  edi,channel_temp
  1168.     mov  ecx,40
  1169.     xor  eax,eax
  1170.   newcase2:
  1171.     mov  al,[esi]
  1172.     cmp  eax,'#'
  1173.     jb   newcase_over2
  1174.     cmp  eax,'a'
  1175.     jb   nocdec2
  1176.     cmp  eax,'z'
  1177.     jg   nocdec2
  1178.     sub  al,97-65
  1179.   nocdec2:
  1180.     mov  [edi],al
  1181.     inc  esi
  1182.     inc  edi
  1183.     loop newcase2
  1184.   newcase_over2:
  1185.     sub  edi,channel_temp
  1186.     mov  [channel_temp_length],edi
  1187.  
  1188.     mov  eax,channel_temp
  1189.  
  1190.     mov  [text_start],I_END+120*80
  1191.     mov  ebx,channel_list+32
  1192.     mov  eax,[eax]
  1193.  
  1194.     mov  edx,[channel_temp_length]
  1195.  
  1196.   stcl1:
  1197.     cmp  dl,[ebx+31]
  1198.     jne  notfound
  1199.  
  1200.     pusha
  1201.     xor  eax,eax
  1202.     xor  edx,edx
  1203.     mov  ecx,0
  1204.   stc4:
  1205.     mov  dl,[ebx+ecx]
  1206.     mov  al,[channel_temp+ecx]
  1207.     cmp  eax,edx
  1208.     jne  notfound2
  1209.     inc  ecx
  1210.     cmp  ecx,[channel_temp_length]
  1211.     jb   stc4
  1212.     popa
  1213.  
  1214.     jmp  found
  1215.  
  1216.   notfound2:
  1217.     popa
  1218.  
  1219.   notfound:
  1220.     add  [text_start],120*80
  1221.     add  ebx,32
  1222.     cmp  ebx,channel_list+19*32
  1223.     jb   stcl1
  1224.  
  1225.     mov  [text_start],I_END
  1226.  
  1227.   found:
  1228.  
  1229.     popa
  1230.  
  1231.     ret
  1232.  
  1233.  
  1234. channel_temp:         times   100   db   0
  1235. channel_temp_length   dd      0x0
  1236.  
  1237.  
  1238.  
  1239. print_nick:
  1240.  
  1241.     pusha
  1242.  
  1243.     mov  eax,command+1
  1244.     mov  dl,'!'
  1245.     call print_text
  1246.  
  1247.     popa
  1248.     ret
  1249.  
  1250.  
  1251. analyze_command:
  1252.  
  1253.     pusha
  1254.  
  1255.     mov  [text_start],I_END
  1256.     mov  ecx,[rxs]
  1257.     imul ecx,11
  1258.     mov  [pos],ecx
  1259.  
  1260. ;    mov  bl,13
  1261. ;  call print_character
  1262. ;    mov  bl,10
  1263. ;  call print_character
  1264.  
  1265. ;    mov  ecx,[cmd]
  1266. ;    sub  ecx,2
  1267. ;    mov  esi,command+0
  1268. ;  newcmdc:
  1269. ;    mov  bl,[esi]
  1270. ;  call print_character
  1271. ;    inc  esi
  1272. ;    loop newcmdc
  1273.  
  1274.     mov   edx,I_END
  1275. ;  call  draw_channel_text
  1276.  
  1277. ;    cmp  [cmd],20
  1278. ;    jge  cmd_len_ok
  1279. ;
  1280. ;    mov  [cmd],0
  1281. ;
  1282. ;    popa
  1283. ;    ret
  1284.  
  1285.  
  1286.   cmd_len_ok:
  1287.  
  1288.     cmp  [command],dword 'PING'  ; ping response
  1289.     jne  no_ping_responce
  1290.  
  1291.     call print_command_to_main
  1292.  
  1293.     mov  [command],dword 'PONG'
  1294.  
  1295.     call print_command_to_main
  1296.  
  1297.     mov  eax,4
  1298.     mov  ebx,100*65536+3
  1299.     mov  ecx,0xffffff
  1300.     mov  edx,command
  1301.     mov  esi,[cmd]
  1302.     mov  [command+esi-1],word '**'
  1303. ;    mcall
  1304.  
  1305.     mov  eax,53
  1306.     mov  ebx,7
  1307.     mov  ecx,[socket]
  1308.     mov  edx,[cmd]
  1309.     mov  esi,command
  1310.     mov  word [esi+edx-2], 0x0a0d
  1311.     mcall
  1312.  
  1313.     popa
  1314.     ret
  1315.  
  1316.   no_ping_responce:
  1317.  
  1318.     mov  eax,[rxs]
  1319.     imul eax,11
  1320.     mov  [pos],eax
  1321.  
  1322.     mov  [command],byte '<'
  1323.  
  1324.     mov  eax,command
  1325.     mov  ecx,100
  1326.    new_blank:
  1327.     cmp  [eax],byte ' '
  1328.     je   bl_found
  1329.     inc  eax
  1330.     loop new_blank
  1331.     mov  eax,50
  1332.   bl_found:
  1333.  
  1334.     inc  eax
  1335.     mov  [command_position],eax
  1336.  
  1337.     mov  esi,eax
  1338.     mov  edi,irc_command
  1339.     mov  ecx,8
  1340.     cld
  1341.     rep  movsb
  1342.  
  1343.  
  1344.     cmp  [irc_command],'PRIV'  ; message to channel
  1345.     jne  no_privmsg
  1346.  
  1347.     ; compare nick
  1348.  
  1349.     mov  eax,[command_position]
  1350.     add  eax,8
  1351.     call compare_to_nick
  1352.     cmp  [cresult],0
  1353.     jne  no_query_msg
  1354.     mov  eax,command+1
  1355.   no_query_msg:
  1356.     call set_channel
  1357.  
  1358.     mov  ecx,100 ; [cmd]
  1359.     mov  eax,command+10
  1360.   acl3:
  1361.     cmp  [eax],byte ':'
  1362.     je   acl4
  1363.     inc  eax
  1364.     loop acl3
  1365.     mov  eax,10
  1366.   acl4:
  1367.     inc  eax
  1368.  
  1369.     cmp  [eax+1],dword 'ACTI'
  1370.     jne  no_action
  1371.     push eax
  1372.     mov  eax,action_header_short
  1373.     mov  dl,0
  1374.     call print_text
  1375.     mov  eax,command+1
  1376.     mov  dl,'!'
  1377.     call print_text
  1378.     mov  bl,' '
  1379.     call print_character
  1380.     pop  eax
  1381.     add  eax,8
  1382.     mov  dl,0
  1383.     call print_text
  1384.     call notify_channel_thread
  1385.     popa
  1386.     ret
  1387.  
  1388.   no_action:
  1389.  
  1390.     push eax
  1391.     mov  bl,10
  1392.     call print_character
  1393.     mov  eax,command
  1394.     mov  dl,'!'
  1395.     call print_text
  1396.     mov  bl,'>'
  1397.     call print_character
  1398.     mov  bl,' '
  1399.     call print_character
  1400.     pop  eax
  1401.  
  1402.     mov  dl,0
  1403.     call print_text
  1404.     call notify_channel_thread
  1405.  
  1406.     popa
  1407.     ret
  1408.  
  1409.   no_privmsg:
  1410.  
  1411.  
  1412.     cmp  [irc_command],'PART'    ; channel leave
  1413.     jne  no_part
  1414.  
  1415.     ; compare nick
  1416.  
  1417.     mov  eax,command+1
  1418.     call compare_to_nick
  1419.     cmp  [cresult],0
  1420.     jne  no_close_window
  1421.  
  1422.     mov  eax,[command_position]
  1423.     add  eax,5
  1424.     call set_channel
  1425.  
  1426.     mov  edi,[text_start]
  1427.     mov  [edi+120*60+4],byte 1
  1428.     call notify_channel_thread
  1429.  
  1430.     popa
  1431.     ret
  1432.  
  1433.   no_close_window:
  1434.  
  1435.     mov  eax,[command_position]
  1436.     add  eax,5
  1437.     call set_channel
  1438.  
  1439.     mov  eax,action_header_red
  1440.     mov  dl,0
  1441.     call print_text
  1442.     mov  eax,command+1
  1443.     mov  dl,'!'
  1444.     mov  cl,' '
  1445.     call print_text
  1446.     mov  eax,has_left_channel
  1447.     mov  dl,0
  1448.     call print_text
  1449.     mov  eax,[command_position]
  1450.     add  eax,5
  1451.     mov  dl,' '
  1452.     call print_text
  1453.     call notify_channel_thread
  1454.  
  1455.     popa
  1456.     ret
  1457.  
  1458.   no_part:
  1459.  
  1460.  
  1461.     cmp  [irc_command],'JOIN'    ; channel join
  1462.     jne  no_join
  1463.  
  1464.     ; compare nick
  1465.  
  1466.     mov  eax,command+1
  1467.     call compare_to_nick
  1468.     cmp  [cresult],0
  1469.     jne  no_new_window
  1470.  
  1471.     mov  edi,I_END+120*80
  1472.     mov  eax,1 ; create channel window - search for empty slot
  1473.    newse:
  1474.     mov  ebx,eax
  1475.     shl  ebx,5
  1476.     cmp  dword [channel_list+ebx],dword '    '
  1477.     je   free_found
  1478.     add  edi,120*80
  1479.     inc  eax
  1480.     cmp  eax,[max_windows]
  1481.     jb   newse
  1482.  
  1483.   free_found:
  1484.  
  1485.     mov  edx,[command_position]
  1486.     add  edx,6
  1487.  
  1488.     push eax
  1489.     push edx
  1490.     mov  ecx,0
  1491.    finde:
  1492.     inc  ecx
  1493.     inc  edx
  1494.     movzx eax,byte [edx]
  1495.     cmp  eax,'#'
  1496.     jge  finde
  1497.     mov  [channel_list+ebx+31],cl
  1498.     pop  edx
  1499.     pop  eax
  1500.  
  1501.     call create_channel_name
  1502.  
  1503.     push edi
  1504.     push eax
  1505.     mov  [edi+120*60+8],byte 0 ; channel window
  1506.     mov  al,32
  1507.     mov  ecx,120*60
  1508.     cld
  1509.     rep  stosb
  1510.     pop  eax
  1511.     pop  edi
  1512.  
  1513.     ; eax has the free position
  1514. ;    mov  [thread_screen],edi
  1515.     call create_channel_window
  1516.  
  1517.   no_new_window:
  1518.  
  1519.     mov  eax,[command_position]
  1520.     add  eax,6
  1521.     call set_channel
  1522.  
  1523.     mov  eax,action_header_blue
  1524.     mov  dl,0
  1525.     call print_text
  1526.     mov  eax,command+1
  1527.     mov  dl,'!'
  1528.     mov  cl,' '
  1529.     call print_text
  1530.  
  1531.     mov  eax,joins_channel
  1532.     mov  dl,0
  1533.     call print_text
  1534.  
  1535.     mov  eax,[command_position]
  1536.     add  eax,6
  1537.     mov  dl,0
  1538.     call print_text
  1539.     call notify_channel_thread
  1540.  
  1541.     popa
  1542.     ret
  1543.  
  1544.   no_join:
  1545.  
  1546.  
  1547.     cmp  [irc_command],'NICK'      ; nick change
  1548.     jne  no_nick_change
  1549.  
  1550.         add     [command_position], 6
  1551. ; test for change of my nick
  1552.         mov     esi, command+1
  1553.         mov     edi, user_nick+4
  1554.         mov     ecx, [edi-4]
  1555.         repz    cmpsb
  1556.         jnz     .notmy
  1557.         cmp     byte [esi], '!'
  1558.         jnz     .notmy
  1559. ; yes, this is my nick, set to new
  1560.         mov     esi, [command_position]
  1561.         or      ecx, -1
  1562.         mov     edi, esi
  1563.         xor     eax, eax
  1564.         repnz   scasb
  1565.         not     ecx
  1566.         dec     ecx
  1567.         cmp     ecx, user_nick_max
  1568.         jb      @f
  1569.         mov     ecx, user_nick_max
  1570. @@:
  1571.         mov     edi, user_nick+4
  1572.         mov     [edi-4], ecx
  1573.         rep     movsb
  1574.  
  1575.         mov     edi, text+70*1+15
  1576.         mov     al, ' '
  1577.         mov     cl, 15
  1578.         push    edi
  1579.         rep     stosb
  1580.         pop     edi
  1581.         mov     esi, user_nick+4
  1582.         mov     ecx, [esi-4]
  1583.         cmp     ecx, 15
  1584.         jb      @f
  1585.         mov     ecx, 15
  1586. @@:
  1587.         rep     movsb
  1588.         mov     [xpos], 0
  1589.         call    draw_window
  1590. .notmy:
  1591. ; replace nick in all lists of users
  1592.         mov     ebx, I_END + 120*70
  1593. .channels:
  1594.         mov     esi, ebx
  1595.         mov     edx, [esi-4]
  1596.         add     edx, esi
  1597. .nicks:
  1598.         mov     edi, command+1
  1599.         cmp     byte [esi], '@'
  1600.         jnz     @f
  1601.         inc     esi
  1602. @@:
  1603.         cmp     esi, edx
  1604.         jae     .srcdone
  1605.         lodsb
  1606.         cmp     al, ' '
  1607.         jz      .srcdone
  1608.         scasb
  1609.         jz      @b
  1610. @@:
  1611.         cmp     esi, edx
  1612.         jae     .nextchannel
  1613.         lodsb
  1614.         cmp     al, ' '
  1615.         jnz     @b
  1616. .nextnick:
  1617.         cmp     esi, edx
  1618.         jae     .nextchannel
  1619.         lodsb
  1620.         cmp     al, ' '
  1621.         jz      .nextnick
  1622.         dec     esi
  1623.         jmp     .nicks
  1624. .srcdone:
  1625.         cmp     byte [edi], '!'
  1626.         jnz     .nextnick
  1627. ; here we have esi -> end of nick which must be replaced to [command_position]+6
  1628.         lea     edx, [edi-command-1]
  1629.         sub     esi, edx
  1630.         or      ecx, -1
  1631.         xor     eax, eax
  1632.         mov     edi, [command_position]
  1633.         repnz   scasb
  1634.         not     ecx
  1635.         dec     ecx
  1636.         push    ecx
  1637.         cmp     ecx, edx
  1638.         jb      .decrease
  1639.         jz      .copy
  1640. .increase:
  1641. ; new nick is longer than the old
  1642.         push    esi
  1643.         lea     edi, [ebx+120*10]
  1644.         lea     esi, [edi+edx]
  1645.         sub     esi, ecx
  1646.         mov     ecx, esi
  1647.         sub     ecx, [esp]
  1648.         dec     esi
  1649.         dec     edi
  1650.         std
  1651.         rep     movsb
  1652.         cld
  1653.         pop     esi
  1654.         jmp     .copy
  1655. .decrease:
  1656. ; new nick is shorter than the old
  1657.         push    esi
  1658.         lea     edi, [esi+ecx]
  1659.         add     esi, edx
  1660.         lea     ecx, [ebx+120*10]
  1661.         sub     ecx, edi
  1662.         rep     movsb
  1663.         pop     esi
  1664. .copy:
  1665. ; copy nick
  1666.         mov     edi, esi
  1667.         dec     edi
  1668.         mov     esi, [command_position]
  1669.         pop     ecx
  1670.         sub     edx, ecx
  1671.         sub     [ebx-4], edx
  1672.         rep     movsb
  1673.         mov     al, ' '
  1674.         stosb
  1675. .nextchannel:
  1676.         add     ebx, 120*80
  1677.         cmp     ebx, I_END + 120*70 + 120*80*19
  1678.         jb      .channels
  1679.  
  1680.     mov  [text_start],I_END
  1681.     add  [text_start],120*80
  1682.  
  1683.  new_all_channels3:
  1684.  
  1685.     mov  eax,action_header_short
  1686.     mov  dl,0
  1687.     call print_text
  1688.     mov  eax,command+1
  1689.     mov  dl,'!'
  1690.     call print_text
  1691.     mov  eax,is_now_known_as
  1692.     mov  dl,0
  1693.     call print_text
  1694.     mov  eax,[command_position]
  1695.     mov  dl,0
  1696.     call print_text
  1697.     call notify_channel_thread
  1698.  
  1699.     add  [text_start],120*80
  1700.     cmp  [text_start],I_END+120*80*20
  1701.     jb   new_all_channels3
  1702.  
  1703.     popa
  1704.     ret
  1705.  
  1706.   no_nick_change:
  1707.  
  1708.  
  1709.      cmp  [irc_command],'KICK'      ; kick
  1710.      jne  no_kick
  1711.  
  1712.     mov  [text_start],I_END
  1713.     add  [text_start],120*80
  1714.  
  1715.     mov  eax,[command_position]
  1716.     add  eax,5
  1717.     call set_channel
  1718.  
  1719. ; new_all_channels4:
  1720.  
  1721.     mov  eax,action_header_short
  1722.     mov  dl,0
  1723.     call print_text
  1724.     mov  eax,command+1
  1725.     mov  dl,'!'
  1726.     call print_text
  1727.      mov  eax,kicked
  1728.      mov  dl,0
  1729.     call print_text
  1730.     mov  eax,[command_position]
  1731.     add  eax,5
  1732.     mov  dl,0
  1733.     call print_text
  1734.     call notify_channel_thread
  1735.  
  1736. ;    add  [text_start],120*80
  1737. ;    cmp  [text_start],I_END+120*80*20
  1738. ;    jb   new_all_channels4
  1739.  
  1740.     popa
  1741.     ret
  1742.  
  1743.   no_kick:
  1744.  
  1745.  
  1746.  
  1747.  
  1748.     cmp  [irc_command],'QUIT'    ; irc quit
  1749.     jne  no_quit
  1750.  
  1751.     mov  [text_start],I_END
  1752.     add  [text_start],120*80
  1753.  
  1754.  new_all_channels2:
  1755.  
  1756.     mov  eax,action_header_red
  1757.     mov  dl,0
  1758.     call print_text
  1759.     mov  eax,command+1
  1760.     mov  dl,'!'
  1761.     call print_text
  1762.     mov  eax,has_quit_irc
  1763.     mov  dl,0
  1764.     call print_text
  1765.     call notify_channel_thread
  1766.  
  1767.     add  [text_start],120*80
  1768.     cmp  [text_start],I_END+120*80*20
  1769.     jb   new_all_channels2
  1770.  
  1771.     popa
  1772.     ret
  1773.  
  1774.   no_quit:
  1775.  
  1776.  
  1777.     cmp  [irc_command],dword 'MODE'  ; channel mode change
  1778.     jne  no_mode
  1779.  
  1780.     mov  [text_start],I_END
  1781.     add  [text_start],120*80
  1782.  
  1783.     mov  eax,[command_position]
  1784.     add  eax,5
  1785.     call set_channel
  1786.  
  1787.  new_all_channels:
  1788.  
  1789.     mov  eax,action_header_short
  1790.     mov  dl,0
  1791.     call print_text
  1792.  
  1793.     call print_nick
  1794.  
  1795.     mov  eax,sets_mode
  1796.     mov  dl,0
  1797.     call print_text
  1798.  
  1799.     mov  eax,[command_position]
  1800.     add  eax,5
  1801.     mov  dl,0
  1802.     call print_text
  1803.     call notify_channel_thread
  1804.  
  1805. ;    add  [text_start],120*80
  1806. ;    cmp  [text_start],I_END+120*80*20
  1807. ;    jb   new_all_channels
  1808.  
  1809.     popa
  1810.     ret
  1811.  
  1812.   no_mode:
  1813.  
  1814.  
  1815.     cmp  [irc_command],dword '353 '  ; channel user names
  1816.     jne  no_user_list
  1817.  
  1818.     mov  eax,[command_position]
  1819.    finde2:
  1820.     inc  eax
  1821.     cmp  [eax],byte '#'
  1822.     jne  finde2
  1823.     call set_channel
  1824.  
  1825.    finde3:
  1826.     inc  eax
  1827.     cmp  [eax],byte ':'
  1828.     jne  finde3
  1829.  
  1830.     pusha
  1831.     cmp  [user_list_pos],0
  1832.     jne  no_clear_user_list
  1833.     mov  edi,[text_start]
  1834.     add  edi,120*70
  1835.     mov  [edi-8],dword 0
  1836.     mov  [edi-4],dword 0
  1837.     mov  al,32
  1838.     mov  ecx,1200
  1839.     cld
  1840.     rep  stosb
  1841.   no_clear_user_list:
  1842.     popa
  1843.  
  1844.     push eax
  1845.  
  1846.     mov  esi,eax
  1847.     inc  esi
  1848.     mov  edi,[text_start]
  1849.     add  edi,120*70
  1850.     add  edi,[user_list_pos]
  1851.     mov  edx,edi
  1852.     mov  ecx,command
  1853.     add  ecx,[cmd]
  1854.     sub  ecx,[esp]
  1855.     sub  ecx,3
  1856.     and  ecx,0xfff
  1857.     cld
  1858.     rep  movsb
  1859.  
  1860.     pop  eax
  1861.     mov  ebx,command
  1862.     add  ebx,[cmd]
  1863.     sub  ebx,eax
  1864.     sub  ebx,2
  1865.     mov  [edx+ebx-1],dword '    '
  1866.  
  1867.     add  [user_list_pos],ebx
  1868.  
  1869.     mov  eax,[user_list_pos]
  1870.     mov  ebx,[text_start]
  1871.     add  ebx,120*70
  1872.     mov  [ebx-4],eax
  1873.     call notify_channel_thread
  1874.  
  1875.     popa
  1876.     ret
  1877.  
  1878.   user_list_pos dd 0x0
  1879.  
  1880.   no_user_list:
  1881.  
  1882.  
  1883.     cmp  [irc_command],dword '366 '  ; channel user names end
  1884.     jne  no_user_list_end
  1885.  
  1886.     mov  [user_list_pos],0
  1887.  
  1888.     popa
  1889.     ret
  1890.  
  1891.   no_user_list_end:
  1892.  
  1893.     mov  [command],byte '-'
  1894.     call print_command_to_main
  1895.  
  1896.     popa
  1897.  
  1898.     ret
  1899.  
  1900.  
  1901. cresult db 0
  1902.  
  1903. compare_to_nick:
  1904.  
  1905. ; input  : eax = start of compare
  1906. ; output : [cresult] = 0 if match, [cresult]=1 if no match
  1907.  
  1908.  
  1909.     pusha
  1910.  
  1911.     mov  esi,eax
  1912.     mov  edi,0
  1913.  
  1914.   new_nick_compare:
  1915.  
  1916.     mov  bl,byte [esi]
  1917.     mov  cl,byte [user_nick+4+edi]
  1918.  
  1919.     cmp  bl,cl
  1920.     jne  nonickm
  1921.  
  1922.     add  esi,1
  1923.     add  edi,1
  1924.  
  1925.     cmp  edi,[user_nick]
  1926.     jb   new_nick_compare
  1927.  
  1928.     movzx eax,byte [esi]
  1929.     cmp  eax,40
  1930.     jge  nonickm
  1931.  
  1932.     popa
  1933.     mov  [cresult],0
  1934.     ret
  1935.  
  1936.   nonickm:
  1937.  
  1938.     popa
  1939.     mov  [cresult],1
  1940.     ret
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946. print_command_to_main:
  1947.  
  1948.     pusha
  1949.  
  1950.     mov  [text_start],I_END
  1951.     mov  ecx,[rxs]
  1952.     imul ecx,11
  1953.     mov  [pos],ecx
  1954.  
  1955.     mov  bl,13
  1956.     call print_character
  1957.     mov  bl,10
  1958.     call print_character
  1959.  
  1960.     mov  ecx,[cmd]
  1961.     sub  ecx,2
  1962.     mov  esi,command
  1963.    newcmdc2:
  1964.     mov  bl,[esi]
  1965.     call print_character
  1966.     inc  esi
  1967.     loop newcmdc2
  1968.  
  1969.     mov   edx,I_END
  1970.     call  draw_channel_text
  1971.  
  1972.     popa
  1973.  
  1974.     ret
  1975.  
  1976.  
  1977.  
  1978.  
  1979. print_text:
  1980.  
  1981.     pusha
  1982.  
  1983.     mov  ecx,command-2
  1984.     add  ecx,[cmd]
  1985.  
  1986.   ptr2:
  1987.     mov  bl,[eax]
  1988.     cmp  bl,dl
  1989.     je   ptr_ret
  1990.     cmp  bl,0
  1991.     je   ptr_ret
  1992.     call print_character
  1993.     inc  eax
  1994.     cmp  eax,ecx
  1995.     jbe  ptr2
  1996.  
  1997.   ptr_ret:
  1998.  
  1999.     mov  eax,[text_start]
  2000.     mov  [eax+120*60],byte 1
  2001.  
  2002.     popa
  2003.     ret
  2004.  
  2005.  
  2006. cp1251_table:
  2007.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; 8
  2008.   db '?','?','?','?','?',$F9,'?','?' , '?','?','?','?','?','?','?','?' ; 9
  2009.   db '?',$F6,$F7,'?',$FD,'?','?','?' , $F0,'?',$F2,'?','?','?','?',$F4 ; A
  2010.   db $F8,'?','?','?','?','?','?',$FA , $F1,$FC,$F3,'?','?','?','?',$F5 ; B
  2011.   db $80,$81,$82,$83,$84,$85,$86,$87 , $88,$89,$8A,$8B,$8C,$8D,$8E,$8F ; C
  2012.   db $90,$91,$92,$93,$94,$95,$96,$97 , $98,$99,$9A,$9B,$9C,$9D,$9E,$9F ; D
  2013.   db $A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7 , $A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF ; E
  2014.   db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; F
  2015.  
  2016. ;    0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F
  2017.  
  2018. utf8_table:
  2019.         times 80h dw 0x98C3     ; default placeholder
  2020. ; 0x80-0xAF -> 0x90D0-0xBFD0
  2021. repeat 0x30
  2022. store byte 0xD0 at utf8_table+2*(%-1)
  2023. store byte 0x90+%-1 at utf8_table+2*%-1
  2024. end repeat
  2025. ; 0xE0-0xEF -> 0x80D1-0x8FD1
  2026. repeat 0x10
  2027. store byte 0xD1 at utf8_table+2*(0xE0-0x80+%-1)
  2028. store byte 0x80+%-1 at utf8_table+2*(0xE0-0x80+%)-1
  2029. end repeat
  2030. ; 0xF0 -> 0x81D0, 0xF1 -> 0x91D1
  2031. store dword 0x91D181D0 at utf8_table+2*(0xF0-0x80)
  2032.  
  2033. cp866_table:
  2034.   db $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7 , $C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ; 8
  2035.   db $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7 , $D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF ; 9
  2036.   db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; A
  2037.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; B
  2038.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; C
  2039.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; D
  2040.   db $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7 , $F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF ; E
  2041.   db $A8,$B8,$AA,$BA,$AF,$BF,$A1,$A2 , $B0,$95,$B7,'?',$B9,$A4,'?','?' ; F
  2042.  
  2043. ;    0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F
  2044.  
  2045. print_character:
  2046.  
  2047.     pusha
  2048.  
  2049.     cmp  bl,13     ; line beginning
  2050.     jne  nobol
  2051.     mov  ecx,[pos]
  2052.     add  ecx,1
  2053.   boll1:
  2054.     sub  ecx,1
  2055.     mov  eax,ecx
  2056.     xor  edx,edx
  2057.     mov  ebx,[rxs]
  2058.     div  ebx
  2059.     cmp  edx,0
  2060.     jne  boll1
  2061.     mov  [pos],ecx
  2062.     jmp  newdata
  2063.   nobol:
  2064.  
  2065.     cmp  bl,10     ; line down
  2066.     jne  nolf
  2067.    addx1:
  2068.     add  [pos],dword 1
  2069.     mov  eax,[pos]
  2070.     xor  edx,edx
  2071.     mov  ecx,[rxs]
  2072.     div  ecx
  2073.     cmp  edx,0
  2074.     jnz  addx1
  2075.     mov  eax,[pos]
  2076.     jmp  cm1
  2077.   nolf:
  2078.   no_lf_ret:
  2079.  
  2080.  
  2081.     cmp  bl,15    ; character
  2082.     jbe  newdata
  2083.  
  2084.     mov  eax,[irc_data]
  2085.     shl  eax,8
  2086.     mov  al,bl
  2087.     mov  [irc_data],eax
  2088.  
  2089.     mov  eax,[pos]
  2090.     call draw_data
  2091.  
  2092.     mov  eax,[pos]
  2093.     add  eax,1
  2094.   cm1:
  2095.     mov  ebx,[scroll+4]
  2096.     imul ebx,[rxs]
  2097.     cmp  eax,ebx
  2098.     jb   noeaxz
  2099.  
  2100.     mov  esi,[text_start]
  2101.     add  esi,[rxs]
  2102.  
  2103.     mov  edi,[text_start]
  2104.     mov  ecx,ebx
  2105.     cld
  2106.     rep  movsb
  2107.  
  2108.     mov  esi,[text_start]
  2109.     mov  ecx,[rxs]
  2110.     imul ecx,61
  2111.     add  esi,ecx
  2112.  
  2113.     mov  edi,[text_start]
  2114.     mov  ecx,[rxs]
  2115.     imul ecx,60
  2116.     add  edi,ecx
  2117.     mov  ecx,ebx
  2118.     cld
  2119.     rep  movsb
  2120.  
  2121.     mov  eax,ebx
  2122.     sub  eax,[rxs]
  2123.   noeaxz:
  2124.     mov  [pos],eax
  2125.  
  2126.   newdata:
  2127.  
  2128.     mov  eax,[text_start]
  2129.     mov  [eax+120*60],byte 1
  2130.  
  2131.     popa
  2132.     ret
  2133.  
  2134. notify_channel_thread:
  2135.         pusha
  2136.         mov     eax, [text_start]
  2137.         mov     ecx, [eax+120*60+12]
  2138.         mcall   60, 2, , 0, 1
  2139.         popa
  2140.         ret
  2141.  
  2142.  
  2143. draw_data:
  2144.  
  2145.     pusha
  2146.  
  2147.     and  ebx,0xff
  2148.     add  eax,[text_start]
  2149.     mov  [eax],bl
  2150.  
  2151.     popa
  2152.     ret
  2153.  
  2154.  
  2155.  
  2156. draw_window:
  2157.  
  2158.     pusha
  2159.  
  2160.     mov  eax,12
  2161.     mov  ebx,1
  2162.     mcall
  2163.  
  2164.     xor  eax,eax                   ; draw window
  2165.     mov  ebx,5*65536+499
  2166.     mov  ecx,5*65536+381
  2167.     mov  edx,[wcolor]
  2168.     add  edx,0x14ffffff
  2169.     mov  edi,title
  2170.     mcall
  2171.  
  2172.     mov  eax,8                     ; button: change encoding
  2173.     mov  ebx,(ENCODING_X-2)*65536+38
  2174.     mov  ecx,(ENCODING_Y-2)*65536+12
  2175.     mov  edx,21
  2176.     mov  esi,[main_button]
  2177.     mcall
  2178.  
  2179. ;    mov  eax,8                    ; button: open socket
  2180.     mov  ebx,43*65536+22
  2181.     mov  ecx,241*65536+10
  2182. ;    mov  edx,22
  2183.     inc  edx
  2184.     mcall
  2185.  
  2186.     ;mov  eax,8                    ; button: send userinfo
  2187.     mov  ebx,180*65536+22
  2188.     mov  ecx,241*65536+10
  2189. ;    mov  edx,23
  2190.     inc  edx
  2191.     mcall
  2192.  
  2193.     ;mov  eax,8                    ; button: close socket
  2194.     mov  ebx,317*65536+22
  2195.     mov  ecx,241*65536+10
  2196. ;    mov  edx,24
  2197.     inc  edx
  2198.     mcall
  2199.  
  2200.     mov  eax,38                    ; line
  2201.     mov  ebx,5*65536+494
  2202.     mov  ecx,148*65536+148
  2203.     mov  edx,[main_line]
  2204.     mcall
  2205.     add  ecx,1*65536+1
  2206.  
  2207.     mov  eax,38                    ; line
  2208.     mov  ebx,5*65536+494
  2209.     mov  ecx,166*65536+166
  2210.     mcall
  2211.     add  ecx,1*65536+1
  2212.  
  2213.     mov  eax,38                    ; line
  2214.     mov  ebx,410*65536+410
  2215.     mov  ecx,22*65536+148
  2216.     mcall
  2217.     add  ebx,1*65536+1
  2218.  
  2219.     mov  ebx,25*65536+183          ; info text
  2220.     mov  ecx,0x000000
  2221.     mov  edx,text
  2222.     mov  esi,70
  2223.   newline:
  2224.     mov  eax,4
  2225.     mcall
  2226.     add  ebx,12
  2227.     add  edx,70
  2228.     cmp  [edx],byte 'x'
  2229.     jne  newline
  2230.  
  2231.     mov  edx,I_END                ; text from server
  2232.     call draw_channel_text
  2233.  
  2234.     call print_entry
  2235.  
  2236.     mov  eax,12
  2237.     mov  ebx,2
  2238.     mcall
  2239.  
  2240.     popa
  2241.  
  2242.     ret
  2243.  
  2244. update_status:
  2245.         pusha
  2246.         mov     esi, [status]
  2247.         mov     edi, text + 7*70 + 22
  2248.         mov     ecx, status_text_len
  2249.         push    ecx
  2250.         imul    esi, ecx
  2251.         add     esi, status_text
  2252.         mov     edx, edi
  2253.         rep     movsb
  2254.         pop     esi
  2255.         mcall   4, STATUS_X*65536+STATUS_Y, 0x40000000, , , 0xFFFFFF
  2256.         popa
  2257.         ret
  2258.  
  2259. update_encoding:
  2260.         pusha
  2261.         mov     edx, 21
  2262.         mcall   8       ; delete button
  2263.         mov     esi, [main_button]
  2264.         mcall   , <(ENCODING_X-2),38>, <(ENCODING_Y-2),12>      ; recreate it
  2265.         mov     esi, [encoding]
  2266.         mov     edi, text + 3*70 + 15
  2267.         mov     ecx, encoding_text_len
  2268.         push    ecx
  2269.         imul    esi, ecx
  2270.         add     esi, encoding_text
  2271.         mov     edx, edi
  2272.         rep     movsb
  2273.         pop     esi
  2274.         mcall   4, ENCODING_X*65536+ENCODING_Y, 0
  2275.         popa
  2276.         ret
  2277.  
  2278. main_line    dd 0x000000
  2279. main_button  dd 0x6565cc
  2280.  
  2281. if lang eq ru
  2282. text:
  2283. db '   ‚ è¥ ¨¬ï  : KolibriOS User  - ¬¥­ï©â¥ â ª: /areal Jill User        '
  2284. db '   ¨ª       : kolibri_user    - ¬¥­ï©â¥ â ª: /anick Jill             '
  2285. db '   ‘¥à¢¥à    : freenode.net    - ¬¥­ï©â¥ â ª: /aserv irc.by           '
  2286. db '   Š®¤¨à®¢ª  : UTF-8                                                  '
  2287. db '                                                                      '
  2288. db '        1) Connect             2) Send userinfo       3) Disconnect   '
  2289. db '                                                                      '
  2290. db '   ‘â âãá ᮥ¤¨­¥­¨ï: ­¥ ᮥ¤¨­¥­®                                    '
  2291. db '                                                                      '
  2292. db '   Š®¬ ­¤ë, ¤®áâã¯­ë¥ ¯®á«¥ ãáâ ­®¢ª¨ ᮥ¤¨­¥­¨ï:                     '
  2293. db '                                                                      '
  2294. db '   /join #ChannelName         - ­ ¯à¨¬¥à: /join #kolibrios            '
  2295. db '   /part #ChannelName         - ­ ¯à¨¬¥à: /part #windows              '
  2296. db '   /query Nickname            - ­ ¯à¨¬¥à: /query Mary                 '
  2297. db '   /quit                      - ®ª¨­ãâì á¥à¢¥à ¨ § ªàëâì ᮪¥â       '
  2298. db 'x' ; <- END MARKER, DONT DELETE
  2299.  
  2300. status_text:
  2301. db      '­¥ ᮥ¤¨­¥­®            '
  2302. db      '¯®«ãç î ¨¬ï á¥à¢¥à ...  '
  2303. db      'ᮥ¤¨­¥­¨¥...           '
  2304. db      'ᮥ¤¨­¥­®               '
  2305. status_text_len = 24
  2306.  
  2307. encoding_text:
  2308. db      'CP866 '
  2309. db      'CP1251'
  2310. db      'UTF-8 '
  2311. encoding_text_len = 6
  2312.  
  2313. else
  2314. text:
  2315. db '   Real name : KolibriOS User  - change with eg /areal Jill User      '
  2316. db '   Nick      : kolibri_user    - change with eg /anick Jill           '
  2317. db '   Server    : freenode.net    - change with eg /aserv irc.by         '
  2318. db '   Encoding  : UTF-8                                                  '
  2319. db '                                                                      '
  2320. db '        1) Connect             2) Send userinfo       3) Disconnect   '
  2321. db '                                                                      '
  2322. db '   Connection status: disconnected                                    '
  2323. db '                                                                      '
  2324. db '   Commands after established connection:                             '
  2325. db '                                                                      '
  2326. db '   /join #ChannelName         - eg /join #kolibrios                   '
  2327. db '   /part #ChannelName         - eg /part #windows                     '
  2328. db '   /query Nickname            - eg /query Mary                        '
  2329. db '   /quit                      - Quit server and Close socket          '
  2330. db 'x' ; <- END MARKER, DONT DELETE
  2331.  
  2332. status_text:
  2333. db      'disconnected            '
  2334. db      'resolving server name...'
  2335. db      'connecting...           '
  2336. db      'connected               '
  2337. status_text_len = 24
  2338.  
  2339. encoding_text:
  2340. db      'CP866 '
  2341. db      'CP1251'
  2342. db      'UTF-8 '
  2343. encoding_text_len = 6
  2344. end if
  2345.  
  2346. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2347. ;
  2348. ;                        CHANNEL THREADS
  2349. ;
  2350. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2351.  
  2352.  
  2353.  
  2354. channel_thread:
  2355.  
  2356. ;    mov   ebp,[thread_nro]
  2357.     pop   ebp
  2358.     pop   edx
  2359.  
  2360.     mov   eax,ebp
  2361.     shl   eax,14
  2362.     add   eax,0x80000
  2363.     mov   esp,eax
  2364.  
  2365. ;    mov   edi,ebp       ; clear thread memory
  2366. ;    imul  edi,120*80
  2367. ;    add   edi,I_END
  2368. ;    mov   ecx,120*80
  2369. ;    mov   al,32
  2370. ;    cld
  2371. ;    rep   stosb
  2372.  
  2373. ; Create IPC buffer in the stack.
  2374.         push    eax
  2375.         push    eax
  2376.         push    eax
  2377.         push    8
  2378.         push    0
  2379.         mov     ecx, esp
  2380.         push    edx
  2381.         mcall   60, 1, , 20
  2382.         pop     edx
  2383.         mcall   40, 1100111b
  2384.  
  2385. ;    mov   edx,[thread_screen]
  2386.  
  2387.   thread_redraw:
  2388.     call  thread_draw_window
  2389.     call  draw_channel_text
  2390.     call  print_user_list
  2391.     call  print_entry
  2392.  
  2393.   w_t:
  2394.  
  2395.     mov  esi,ebp
  2396.     imul esi,120*80
  2397.     add  esi,I_END
  2398.     cmp  [esi+120*60+4],byte 1
  2399.     jne  no_channel_leave
  2400.     mov  [esi+120*60+4],byte 0
  2401.     mov  edi,ebp
  2402.     shl  edi,5
  2403.     mov  dword [channel_list+edi],dword '    '
  2404.     mov  byte  [channel_list+edi+31],byte 1
  2405.     mov  eax,-1
  2406.     mcall
  2407.   no_channel_leave:
  2408.  
  2409.     mcall 10
  2410.     dec   eax
  2411.     jz    thread_redraw
  2412.     dec   eax
  2413.     jz    thread_key
  2414.     dec   eax
  2415.     jz    thread_end
  2416.     cmp   al,4
  2417.     jz    thread_ipc
  2418.     call  check_mouse
  2419.     jmp   w_t
  2420.   thread_end:
  2421.     mov   eax,17
  2422.     mcall
  2423.     mov   eax,ebp
  2424.     imul  eax,120*80
  2425.     add   eax,I_END
  2426.     cmp   [eax+120*60+8],byte 0 ; channel window
  2427.     je    not_close
  2428.     mov   eax,ebp
  2429.     shl   eax,5
  2430.     add   eax,channel_list
  2431.     mov   [eax],dword '    '
  2432.     mov   [eax+31],byte 1
  2433.     mov   eax,-1
  2434.     mcall
  2435.   not_close:
  2436.     mov   [text_start],eax
  2437.     mov   eax,nocl
  2438.   newcc:
  2439.     mov   bl,[eax]
  2440.     call  print_character
  2441.     inc   eax
  2442.     cmp   [eax],byte 0
  2443.     jne   newcc
  2444.     call  draw_channel_text
  2445.     jmp   w_t
  2446.    nocl:   db  13,10,'To exit channel, use PART or QUIT command.',0
  2447.   thread_ipc:
  2448.     mov   byte [esp+4], 8 ; erase message from IPC buffer
  2449.    no_end:
  2450.  
  2451.     cmp   [edx+120*60],byte 1
  2452.     jne   no_update
  2453.     mov   [edx+120*60],byte 0
  2454.     call  draw_channel_text
  2455.   no_update:
  2456.  
  2457.     call  print_user_list
  2458.  
  2459.   nopri2:
  2460.  
  2461.     jmp   w_t
  2462.  
  2463.  
  2464.  
  2465. check_mouse:
  2466.  
  2467.     pusha
  2468.  
  2469.     mov  eax,37
  2470.     mov  ebx,1
  2471.     mcall
  2472.  
  2473.     mov  ebx,eax
  2474.     shr  eax,16
  2475.     and  ebx,0xffff
  2476.  
  2477.     cmp  eax,420
  2478.     jb   no_mouse
  2479.     cmp  eax,494
  2480.     jg   no_mouse
  2481.  
  2482.     cmp  ebx,145
  2483.     jg   no_mouse
  2484.     cmp  ebx,23
  2485.     jb   no_mouse
  2486.  
  2487.  
  2488.     cmp  ebx,100
  2489.     jb   no_plus
  2490.     mov  eax,ebp
  2491.     imul eax,120*80
  2492.     add  eax,120*70+I_END
  2493.     inc  dword [eax-8]
  2494.     call print_user_list
  2495.     mov  eax,5
  2496.     mov  ebx,8
  2497.     mcall
  2498.     jmp  no_mouse
  2499.   no_plus:
  2500.  
  2501.     cmp  ebx,80
  2502.     jg   no_mouse
  2503.     mov  eax,ebp
  2504.     imul eax,120*80
  2505.     add  eax,120*70+I_END
  2506.     cmp  dword [eax-8],dword 0
  2507.     je   no_mouse
  2508.     dec  dword [eax-8]
  2509.     call print_user_list
  2510.     mov  eax,5
  2511.     mov  ebx,8
  2512.     mcall
  2513.  
  2514.   no_minus:
  2515.  
  2516.   no_mouse:
  2517.  
  2518.     popa
  2519.  
  2520.     ret
  2521.  
  2522.  
  2523.  
  2524.  
  2525. thread_key:
  2526.  
  2527.     mov  eax,2
  2528.     mcall
  2529.  
  2530.     shr  eax,8
  2531.  
  2532.     cmp  eax,8
  2533.     jne  no_bks
  2534.     cmp  [xpos],0
  2535.     je   w_t
  2536.     dec  [xpos]
  2537.     call print_entry
  2538.     jmp  w_t
  2539.    no_bks:
  2540.  
  2541.     cmp  eax,20
  2542.     jbe  no_character
  2543.     mov  ebx,[xpos]
  2544.     mov  [send_string+ebx],al
  2545.     inc  [xpos]
  2546.     cmp  [xpos],80
  2547.     jb   xpok
  2548.     mov  [xpos],79
  2549.   xpok:
  2550.     call print_entry
  2551.     jmp  w_t
  2552.   no_character:
  2553.  
  2554.     cmp  eax,13
  2555.     jne  no_send
  2556.     cmp  [xpos],0
  2557.     je   no_send
  2558.     mov  dword [send_to_channel],ebp
  2559.     pusha
  2560.     mcall 60,2,[main_PID],0,1
  2561.   wait_for_sending:
  2562.     mov  eax,5
  2563.     mov  ebx,1
  2564.     mcall
  2565.     cmp  dword [ipcbuf+4],8
  2566.     jne  wait_for_sending
  2567.     popa
  2568.     call draw_channel_text
  2569.     call print_entry
  2570.     jmp  w_t
  2571.   no_send:
  2572.  
  2573.     jmp  w_t
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580. draw_channel_text:
  2581.  
  2582.     pusha
  2583.  
  2584.     mov   eax,4
  2585.     mov   ebx,10*65536+26
  2586.     mov   ecx,12
  2587.     mov   esi,[rxs]
  2588.   dct:
  2589.     pusha
  2590.     mov   cx,bx
  2591.     shl   ecx,16
  2592.     mov   cx,9
  2593.     mov   eax,13
  2594.     mov   ebx,10*65536
  2595.     mov   bx,word [rxs]
  2596.     imul  bx,6
  2597.     mov   edx,0xffffff
  2598.     mcall
  2599.     popa
  2600.     push  ecx
  2601.     mov   eax,4
  2602.     mov   ecx,0
  2603.     cmp   [edx],word '* '
  2604.     jne   no_red
  2605.     mov   ecx,0x0000ff
  2606.    no_red:
  2607.     cmp   [edx],word '**'
  2608.     jne   no_light_blue
  2609.     cmp   [edx+2],byte '*'
  2610.     jne   no_light_blue
  2611.     mov   ecx,0x0000ff
  2612.   no_light_blue:
  2613.     cmp   [edx],byte '#'
  2614.     jne   no_blue
  2615.     mov   ecx,0x0000ff
  2616.   no_blue:
  2617.     mcall
  2618.     add   edx,[rxs]
  2619.     add   ebx,10
  2620.     pop   ecx
  2621.     loop  dct
  2622.  
  2623.     popa
  2624.     ret
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630. thread_draw_window:
  2631.  
  2632.     pusha
  2633.  
  2634.     mov  eax,12
  2635.     mov  ebx,1
  2636.     mcall
  2637.  
  2638.     mov  ebx,ebp                   ; draw window
  2639.     shl  ebx,16+4
  2640.     xor  eax,eax
  2641.     mov  ecx,ebx
  2642.     mov  bx,499
  2643.     mov  cx,170
  2644.  
  2645.     mov  edx,[wcolor]
  2646.     add  edx,0x03ffffff
  2647.     mov  esi,0x80555599
  2648.     mov  edi,0x00ffffff
  2649.  
  2650.     mcall
  2651.  
  2652.     mov  eax,ebp                   ; label
  2653.     add  eax,48
  2654.     mov  [labelc+14],al
  2655.     mov  eax,ebp
  2656.     shl  eax,5
  2657.     add  eax,channel_list
  2658.     mov  esi,eax
  2659.     mov  edi,labelc+17
  2660.     movzx ecx,byte [eax+31]
  2661.     cld
  2662.     rep   movsb
  2663.  
  2664.     mov  esi,17                    ; print label
  2665.     movzx ebx,byte [eax+31]
  2666.     add  esi,ebx
  2667.     mov  eax,4
  2668.     mov  ebx,9*65536+8
  2669.     mov  ecx,0x00ffffff
  2670.     mov  edx,labelc
  2671.     mcall
  2672.  
  2673.     mov  eax,38                    ; line
  2674.     mov  ebx,5*65536+494
  2675.     mov  ecx,148*65536+148
  2676.     mov  edx,[channel_line_sun]
  2677.     mcall
  2678.     add  ecx,1*65536+1
  2679.     mov  edx,[channel_line_shadow]
  2680.     mcall
  2681.  
  2682.  
  2683.     ;mov  eax,38                   ; line
  2684.     mov  ebx,410*65536+410
  2685.     mov  ecx,22*65536+148
  2686.     mov  edx,[channel_line_sun]
  2687.     mcall
  2688.     add  ebx,1*65536+1
  2689.     mov  edx,[channel_line_shadow]
  2690.     mcall
  2691.  
  2692.     mov  eax,12
  2693.     mov  ebx,2
  2694.     mcall
  2695.  
  2696.     popa
  2697.  
  2698.     ret
  2699.  
  2700.  
  2701. ; DATA AREA
  2702.  
  2703. socket  dd  0x0
  2704.  
  2705. bgc  dd  0x000000
  2706.      dd  0x000000
  2707.      dd  0x00ff00
  2708.      dd  0x0000ff
  2709.      dd  0x005500
  2710.      dd  0xff00ff
  2711.      dd  0x00ffff
  2712.      dd  0x770077
  2713.  
  2714. tc   dd  0xffffff
  2715.      dd  0xff00ff
  2716.      dd  0xffffff
  2717.      dd  0xffffff
  2718.      dd  0xffffff
  2719.      dd  0xffffff
  2720.      dd  0xffffff
  2721.      dd  0xffffff
  2722.  
  2723. channel_line_sun    dd 0x9999ff
  2724. channel_line_shadow dd 0x666699
  2725.  
  2726. cursor_on_off  dd  0x0
  2727.  
  2728. max_windows    dd  20
  2729.  
  2730. thread_stack   dd  0x9fff0
  2731. ;thread_nro     dd 1
  2732. ;thread_screen  dd I_END+120*80*1
  2733.  
  2734. action_header_blue  db  10,'*** ',0
  2735. action_header_red   db  10,'*** ',0
  2736.  
  2737. action_header_short db  10,'* ',0
  2738.  
  2739. has_left_channel db  ' has left ',0
  2740. joins_channel    db  ' has joined ',0
  2741. is_now_known_as  db  ' is now known as ',0
  2742. has_quit_irc     db  ' has quit IRC',0
  2743. sets_mode        db  ' sets mode ',0
  2744. kicked           db  ' kicked from ',0
  2745.  
  2746. index_list_1     dd  0x0000bb
  2747. index_list_2     dd  0x0000ff
  2748.  
  2749. posx             dd  0x0
  2750. incoming_pos     dd  0x0
  2751. incoming_string: times 128 db 0
  2752.  
  2753. pos          dd  0x0
  2754.  
  2755. text_start   dd  I_END
  2756. irc_data     dd  0x0
  2757. print        db  0x0
  2758. cmd          dd  0x0
  2759. rxs          dd  66
  2760.  
  2761. res:         db  0,0
  2762. command:     times  600  db 0x0
  2763.  
  2764. nick         dd  0,0,0
  2765. irc_command  dd  0,0
  2766.  
  2767. command_position  dd 0x0
  2768. counter           dd  0
  2769. send_to_server    db 0
  2770.  
  2771. channel_list:     times 32*20 db 32
  2772. send_to_channel   dd 0x0
  2773.  
  2774. send_string_header:  db     'privmsg #eax :'
  2775.                      times  100  db  0x0
  2776.  
  2777. send_string:         times  100  db  0x0
  2778. xpos         dd  0
  2779.  
  2780. string0:     db  'USER guest ser1 ser2 :'
  2781. string0l:
  2782. string1:     db  'nick '
  2783. string1l:
  2784.  
  2785. attribute   dd  0
  2786. scroll      dd  1
  2787.             dd  12
  2788.  
  2789. numtext     db  '                     '
  2790.  
  2791. wcolor      dd  0x000000
  2792.  
  2793. labelc      db  'AIRC - WINDOW X: #xxx                 '
  2794. title       db  'IRC client ',version,0
  2795.  
  2796. ipcbuf:
  2797.         dd      0
  2798.         dd      8
  2799.         dd      ?
  2800.         dd      ?
  2801.         db      ?
  2802. .size = $
  2803.  
  2804. align 4
  2805. @IMPORT:
  2806.  
  2807. library network, 'network.obj', msgbox, 'msgbox.obj'
  2808. import  network, \
  2809.         getaddrinfo_start,      'getaddrinfo_start',    \
  2810.         getaddrinfo_process,    'getaddrinfo_process',  \
  2811.         getaddrinfo_abort,      'getaddrinfo_abort',    \
  2812.         freeaddrinfo,           'freeaddrinfo'
  2813. import  msgbox, mb_create, 'mb_create', mb_setfunctions, 'mb_setfunctions'
  2814.  
  2815. msgbox_running  db      ?       ; must be the byte before msgbox_struct
  2816.                                 ; look to the handler of button 21
  2817. msgbox_struct:
  2818. .default:
  2819.         dw      ?       ; default button, will be filled with current encoding
  2820.         db      'Encoding',0
  2821.         db      'Select encoding for all messages:',0
  2822.         db      'CP866',0
  2823.         db      'CP1251',0
  2824.         db      'UTF-8',0
  2825.         db      0
  2826.  
  2827. align 4
  2828. status          dd      STATUS_DISCONNECTED
  2829. encoding        dd      UTF8
  2830. recode_proc     dd      recode_to_cp866, recode_to_cp1251, recode_to_utf8
  2831. get_byte_table  dd      get_byte_cp866, get_byte_cp1251, get_byte_utf8
  2832. msgbox_func_array:
  2833. times 3         dd      msgbox_notify
  2834. initialized_size:
  2835.  
  2836. main_PID        dd      ?       ; identifier of main thread
  2837. utf8_bytes_rest dd      ?       ; bytes rest in current UTF8 sequence
  2838. utf8_char       dd      ?       ; first bits of current UTF8 character
  2839. gai_reqdata     rb      32      ; buffer for getaddrinfo_start/process
  2840. ip_list         dd      ?       ; will be filled as pointer to addrinfo list
  2841. irc_server_name rb      256     ; buffer for irc_server_name
  2842. packetbuf       rb      1024    ; buffer for packets to server
  2843. mb_stack        rb      1024    ; stack for messagebox thread
  2844.  
  2845. ;;
  2846. ;;   Channel data at I_END
  2847. ;;
  2848. ;;   120*80 * channel window (1+)
  2849. ;;
  2850. ;;      At         Size
  2851. ;;
  2852. ;;      00      ,  120*60   window text 120 characters per row
  2853. ;;  120*60      ,  1        text is updated
  2854. ;;  120*60+4    ,  1        close yourself
  2855. ;;  120*60+8    ,  1        0 = channel window  :  1 = private chat
  2856. ;;  120*60+12    , 4        identifier of the thread
  2857. ;;  120*61      ,  256      channel name
  2858. ;;  120*61+254  ,  254      channel entry text from user
  2859. ;;  120*61+255  ,  1        length of entry text
  2860. ;;  120*69+248  ,  4        display names from n:th name
  2861. ;;  120*69+252  ,  4        length of names string
  2862. ;;  120*70      ,  1200     names separated with space
  2863. ;;
  2864. I_END:
  2865.