Subversion Repositories Kolibri OS

Rev

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

  1. virtual at 0
  2. editor_data:
  3.         .hPlugin        dd      ?
  4.         .hFile          dd      ?
  5. if (.hPlugin <> viewer_data.hPlugin) | (.hFile <> viewer_data.hFile)
  6. error in viewer_IsHandleUsed/editor_IsHandleUsed
  7. end if
  8.         .memsize        dd      ?
  9.         .encoding       db      ?
  10.         .flags          db      ?       ; & 0x80: modified
  11.                                         ; & 0x40: file is locked
  12.                                         ; & 0x20: next key as a symbol
  13.                                         ; & 0x10: replace mode (vs insert)
  14.         .eol            db      ?
  15.                         rb      1
  16.         .first_block    dd      ?
  17.         .last_block     dd      ?
  18.         .numfree        dd      ?
  19.         .freeblocks     dd      ?
  20.         .numlines       dd      ?
  21.         .curline        dd      ?
  22.         .curcol         dd      ?
  23.         ;.curpos_block  dd      ?
  24.         ;.curpos_offs   dd      ?
  25.         .cur_block      dd      ?
  26.         .cur_offs       dd      ?
  27.         .cur_delta      dd      ?
  28.         .cursor_x       dd      ?
  29.         .cursor_y       dd      ?
  30.         align 200h
  31.         .filename       rb      1024
  32.         .hostname       rb      1024
  33. if (.filename <> viewer_data.filename) | (.hostname <> viewer_data.hostname)
  34. error in viewer_getname/editor_getname
  35. end if
  36.         .buf            rb      16384   ; all I/O operations use this buffer
  37.         .basesize = $
  38.         .linedata_start:
  39. end virtual
  40.  
  41. virtual at 0
  42. editor_line:
  43.         .block          dd      ?
  44.         .offs           dw      ?
  45.         ;.length                dd      ?
  46.         .plugdata:
  47. end virtual
  48.  
  49. ; when a file is loaded into the editor, this file is fragmented to blocks
  50. ; each block has RESERVE_IN_BLOCK empty bytes to allow quick inserting
  51. ; must be dword-aligned!
  52. edit.RESERVE_IN_BLOCK = 16
  53. edit.eol_dos = 1        ; DOS/Win EOLn style (0D 0A)
  54. edit.eol_unix = 2       ; Unix EOLn style (0A)
  55. edit.eol_mac = 3        ; MacOS EOLn style (0D)
  56.  
  57. virtual at 0
  58. edit_block_header:
  59.         .next           dd      ?
  60.         .prev           dd      ?
  61.         .limit          dd      ?
  62.         .size = $       ; must be dword-aligned
  63. end virtual
  64.  
  65. edit_file:
  66.         mov     eax, [ebp + panel1_files - panel1_data]
  67.         mov     ecx, [eax+ecx*4]
  68.         test    byte [ecx], 10h
  69.         jz      .file
  70.         ret
  71. .file:
  72. ; calculate required memory size
  73.         cmp     dword [ecx+36], 0
  74.         jnz     .nomemory
  75. ; block size = 4096
  76. ; block header: edit_block_header.size bytes
  77. ; some plugin-specific data can follow
  78. ; reserve RESERVE_IN_BLOCK free bytes in the end of block
  79.         mov     ebx, 4096
  80.         mov     eax, [EditPlugInfo]
  81.         add     eax, edit_block_header.size
  82.         mov     [EditBlockStart], eax
  83.         sub     ebx, eax
  84.         sub     ebx, edit.RESERVE_IN_BLOCK
  85.         mov     [EditBlockSize], ebx
  86. ; now ebx = size of file data in each block
  87.         mov     eax, [ecx+32]
  88. ; if eax == 0, set eax = 1
  89.         sub     eax, 1
  90.         adc     eax, 1
  91.         xor     edx, edx
  92.         div     ebx
  93.         sub     edx, 1
  94.         sbb     eax, -1
  95.         add     eax, [EditDataSize]
  96. ; eax = number of blocks + memory for editor_data structure
  97.         cmp     eax, 0x80000000 shr 12
  98.         jb      .memok
  99. .nomemory:
  100.         push    aEditNoMemory
  101.         mov     eax, esp
  102.         push    ContinueBtn
  103.         push    1
  104.         push    eax
  105.         push    1
  106.         call    SayErr
  107.         pop     eax
  108.         ret
  109. .memok:
  110.         lea     esi, [ebp + panel1_dir - panel1_data]
  111.         push    eax
  112.         push    ecx
  113.         mov     ecx, eax
  114.         shl     ecx, 12
  115.         mov     edx, editor_vtable
  116.         call    new_screen
  117.         pop     ecx
  118.         pop     ebx
  119.         test    eax, eax
  120.         jnz     @f
  121.         ret
  122. @@:
  123.         mov     [ebp + editor_data.memsize], ebx
  124.         mov     al, [EditEOLStyle]
  125.         mov     [ebp + editor_data.eol], al
  126.         mov     eax, dword [esi + panel1_hPlugin - panel1_dir]
  127.         mov     [ebp + editor_data.hPlugin], eax
  128.         test    eax, eax
  129.         jz      .nocopyhostname
  130.         lea     edi, [ebp + editor_data.hostname]
  131.         push    esi
  132.         mov     eax, dword [esi + panel1_parents - panel1_dir]
  133.         mov     esi, dword [esi + panel1_parents_sz - panel1_dir]
  134.         add     esi, eax
  135. @@:
  136.         dec     esi
  137.         cmp     byte [esi-1], 0
  138.         jz      @f
  139.         cmp     byte [esi-1], '/'
  140.         jnz     @b
  141. @@:
  142.         lodsb
  143.         stosb
  144.         test    al, al
  145.         jnz     @b
  146.         pop     esi
  147. .nocopyhostname:
  148.         mov     eax, dword [esi + panel1_hFile - panel1_dir]
  149.         mov     [ebp + editor_data.hFile], eax
  150.         mov     [ebp + editor_data.encoding], encodings.cp866
  151.         xor     eax, eax
  152.         mov     [ebp + editor_data.flags], al
  153.         inc     eax
  154.         mov     [ebp + editor_data.numlines], eax
  155.         lea     edi, [ebp + editor_data.filename]
  156.         mov     ebx, readinfo
  157.         mov     [ebx+21], edi
  158. @@:
  159.         lodsb
  160.         test    al, al
  161.         jz      @f
  162.         stosb
  163.         jmp     @b
  164. @@:
  165.         lea     esi, [ecx+40]
  166.         mov     al, '/'
  167.         cmp     byte [edi-1], al
  168.         jz      @f
  169.         stosb
  170. @@:
  171.         lodsb
  172.         stosb
  173.         test    al, al
  174.         jnz     @b
  175. ; load file into memory
  176.         mov     esi, [ebp + editor_data.memsize]
  177.         mov     edi, [EditDataSize]
  178.         sub     esi, edi        ; esi = number of blocks
  179.         shl     edi, 12
  180.         ;mov    [ebp + editor_data.curpos_block], edi
  181.         mov     [ebp + editor_data.first_block], edi
  182.         mov     [ebp + editor_data.cur_block], edi
  183.         add     edi, ebp        ; edi -> first block
  184.         mov     [ebp + editor_data.linedata_start + editor_line.block], edi
  185.         xor     eax, eax
  186.         mov     [ebx+4], eax
  187.         mov     [ebx+8], eax
  188.         mov     dword [ebx+12], 16384
  189.         lea     eax, [ebp + editor_data.buf]
  190.         mov     [ebx+16], eax
  191.         mov     edx, [ebp + editor_data.hPlugin]
  192.         test    edx, edx
  193.         jz      @f
  194.         pushad
  195.         push    O_READ
  196.         push    dword [ebx+21]
  197.         push    [ebp + editor_data.hFile]
  198.         call    [edx + PluginInfo.open]
  199.         mov     [esp+1Ch], eax
  200.         popad
  201.         test    eax, eax
  202.         jz      ..openerr_in_screen
  203.         mov     ebx, eax
  204. @@:
  205.         mov     ecx, [EditBlockSize]    ; bytes rest in the current block
  206.         add     edi, [EditBlockStart]
  207. .readloop:
  208.         mov     edx, [ebp + editor_data.hPlugin]
  209.         test    edx, edx
  210.         jz      .readnative
  211.         pushad
  212.         push    16384
  213.         push    [readinfo.data]
  214.         push    ebx
  215.         call    [edx + PluginInfo.read]
  216.         mov     [esp+1Ch], eax
  217.         popad
  218.         cmp     eax, -1
  219.         jnz     .readok
  220. ; let us hope that plugin says error itself
  221.         push    ebp
  222.         push    ebx
  223.         call    [edx + PluginInfo.close]
  224.         pop     ebp
  225.         jmp     .readfailed
  226. .readnative:
  227.         push    ebx
  228.         push    70
  229.         pop     eax
  230.         int     40h
  231.         mov     edx, ebx
  232.         xchg    eax, edx
  233.         pop     ebx
  234.         add     dword [ebx+4], eax
  235.         adc     dword [ebx+8], 0
  236.         test    edx, edx
  237.         jz      .readok
  238.         cmp     edx, 6
  239.         jz      .readok
  240.         push    dword [ebx+21]
  241.         push    aCannotReadFile
  242.         xchg    eax, edx
  243.         call    get_error_msg
  244.         push    eax
  245.         mov     eax, esp
  246.         push    RetryOrCancelBtn
  247.         push    2
  248.         push    eax
  249.         push    3
  250.         call    SayErr
  251.         add     esp, 3*4
  252.         test    eax, eax
  253.         jz      .readnative
  254. .readfailed:
  255.         jmp     delete_active_screen
  256. .readok:
  257. ; eax = number of bytes read
  258.         test    eax, eax
  259.         jnz     @f
  260.         push    edi
  261.         sub     edi, ebp
  262.         cmp     edi, [ebp + editor_data.first_block]
  263.         pop     edi
  264.         jnz     .readdone
  265. @@:
  266.         push    eax ebx
  267.         mov     ebx, [readinfo.data]
  268. .loadloop:
  269.         test    ecx, ecx
  270.         jnz     .hasplace
  271.         push    eax
  272.         dec     esi
  273.         jns     .hasblock
  274.         add     [ebp + editor_data.memsize], 8
  275.         add     esi, 8
  276.         mov     ecx, [ebp + editor_data.memsize]
  277.         cmp     ecx, 80000000h shr 12
  278.         jb      @f
  279. .nomemory2:
  280.         pop     eax ebx eax
  281.         call    .nomemory
  282.         jmp     .readfailed
  283. @@:
  284.         sub     edi, ebp
  285.         shl     ecx, 12
  286.         mov     edx, ebp
  287.         call    xpgrealloc
  288.         test    eax, eax
  289.         jz      .nomemory2
  290.         add     edi, eax
  291.         xchg    ebp, eax
  292. .hasblock:
  293.         push    edi
  294.         and     edi, not 0xFFF
  295.         lea     eax, [edi + 0x1000]
  296.         sub     eax, ebp
  297.         stosd   ; edit_block_header.next
  298.         sub     eax, 0x2000
  299.         stosd   ; edit_block_header.prev
  300.         pop     eax
  301.         sub     eax, edi
  302.         add     eax, 8
  303.         stosd   ; edit_block_header.limit
  304.         mov     ecx, [EditPlugInfo]
  305.         inc     ecx
  306.         jz      @f
  307.         dec     ecx
  308. @@:
  309.         xor     eax, eax
  310.         rep     stosb   ; info for plugins: zeroed
  311.         add     edi, 0x1000
  312.         mov     ecx, [EditBlockSize]
  313.         pop     eax
  314. .hasplace:
  315.         push    ecx
  316.         cmp     eax, ecx
  317.         ja      @f
  318.         mov     ecx, eax
  319. @@:
  320.         push    ecx
  321.         push    eax
  322.         push    esi edi
  323.         mov     esi, ebx
  324.         mov     edx, ecx
  325.         shr     ecx, 2
  326.         rep     movsd
  327.         mov     ecx, edx
  328.         and     ecx, 3
  329.         rep     movsb
  330.         mov     ebx, esi
  331.         mov     ecx, edx
  332.         pop     esi
  333. ; calculate number of lines in this block
  334.         test    ecx, ecx
  335.         jz      .4
  336.         mov     al, [esi - 1]
  337.         mov     edx, esi
  338.         sub     edx, [EditBlockStart]
  339.         test    edx, 0xFFF
  340.         jnz     .0
  341.         mov     al, 0
  342.         sub     edx, ebp
  343.         cmp     edx, [ebp + editor_data.first_block]
  344.         jz      .0
  345.         sub     edx, 1000h
  346.         add     edx, ebp
  347.         add     edx, [edx + edit_block_header.limit]
  348.         mov     al, [edx - 1]
  349. .0:
  350.         xor     edx, edx
  351.         cmp     al, 13
  352.         jnz     .1
  353.         mov     dl, 10
  354. .1:
  355.         mov     al, [esi]
  356.         add     esi, 1
  357.         cmp     al, 13
  358.         jz      @f
  359.         cmp     al, 10
  360.         jz      @f
  361.         mov     dl, 0
  362.         sub     ecx, 1
  363.         jnz     .1
  364.         jmp     .4
  365. @@:
  366.         cmp     al, dl
  367.         mov     dl, 0
  368.         jz      .3
  369.         add     [ebp + editor_data.numlines], 1
  370.         cmp     al, 10
  371.         jz      .3
  372.         mov     dl, 10
  373. .3:
  374.         sub     ecx, 1
  375.         jnz     .1
  376. .4:
  377.         pop     esi
  378.         pop     eax
  379.         pop     ecx
  380.         sub     [esp], ecx
  381.         sub     eax, ecx
  382.         pop     ecx
  383.         jnz     .loadloop
  384.         pop     ebx eax
  385.         cmp     eax, 16384
  386.         jz      .readloop
  387. .readdone:
  388.         push    edi
  389.         and     edi, not 0xFFF
  390.         xor     eax, eax
  391.         stosd   ; editor_block_header.next
  392.         lea     eax, [edi - 4 - 0x1000]
  393.         sub     eax, ebp
  394.         stosd   ; editor_block_header.prev
  395.         pop     eax
  396.         sub     eax, edi
  397.         add     eax, 8
  398.         stosd   ; editor_block_header.limit
  399.         mov     ecx, [EditPlugInfo]
  400.         inc     ecx
  401.         jz      @f
  402.         dec     ecx
  403. @@:
  404.         xor     eax, eax
  405.         rep     stosb
  406.         and     edi, not 0xFFF
  407.         lea     ecx, [edi + 0x1000]
  408.         sub     ecx, ebp
  409.         mov     edx, ecx
  410.         shr     ecx, 12
  411.         sub     ecx, [ebp + editor_data.memsize]
  412.         neg     ecx
  413.         mov     [ebp + editor_data.numfree], ecx
  414.         jz      .nofree
  415.         mov     [ebp + editor_data.freeblocks], edx
  416.         push    edi
  417. .addfree:
  418.         add     edi, 1000h
  419.         add     edx, 1000h
  420.         mov     [edi], edx
  421.         loop    .addfree
  422.         mov     [edi], eax
  423.         pop     edi
  424. .nofree:
  425.         sub     edi, ebp
  426.         mov     [ebp + editor_data.last_block], edi
  427.         mov     ecx, [EditDataSize]
  428.         shl     ecx, 12
  429.         mov     [ecx + ebp + edit_block_header.prev], eax
  430.         mov     [ebp + editor_data.curline], eax
  431.         mov     [ebp + editor_data.curcol], eax
  432.         mov     [ebp + editor_data.cursor_x], eax
  433.         inc     eax
  434.         mov     [ebp + editor_data.cursor_y], eax
  435.         mov     eax, [EditBlockStart]
  436.         ;mov    [ebp + editor_data.curpos_offs], eax
  437.         mov     [ebp + editor_data.linedata_start + editor_line.offs], ax
  438.         mov     [ebp + editor_data.cur_offs], eax
  439.         mov     ecx, [ebp + editor_data.first_block]
  440.         cmp     [ecx + edit_block_header.limit], eax
  441.         setz    cl
  442.         movzx   ecx, cl
  443.         dec     ecx
  444.         mov     [ebp + editor_data.cur_delta], ecx
  445.         call    editor_init_lines
  446. editor_OnRedraw:
  447.         mov     eax, [ebp + editor_data.cursor_x]
  448.         mov     [cursor_x], eax
  449.         mov     eax, [ebp + editor_data.cursor_y]
  450.         mov     [cursor_y], eax
  451.         test    [ebp + editor_data.flags], 10h
  452.         jz      @f
  453.         mov     [cursor_size], cursor_big_size
  454. @@:
  455.         call    editor_test_cursor_x
  456.         call    editor_test_cursor_y
  457.         call    editor_set_keybar
  458.         call    editor_draw_text
  459.         ret
  460.  
  461. editor_save:
  462.         cmp     [ebp + editor_data.hPlugin], 0
  463.         jz      .native
  464.         push    aCannotSaveToPlugin
  465.         mov     eax, esp
  466.         push    ContinueBtn
  467.         push    1
  468.         push    eax
  469.         push    1
  470.         call    SayErr
  471.         pop     eax
  472.         ret
  473. .native:
  474.         call    editor_calc_filesize
  475.         mov     ebx, writeinfo
  476.         mov     [ebx+4], eax
  477.         xor     eax, eax
  478.         mov     [ebx+8], eax
  479.         mov     [ebx+12], eax
  480.         mov     [ebx+16], eax
  481.         lea     eax, [ebp + editor_data.filename]
  482.         mov     [ebx+21], eax
  483. .setsize_retry:
  484.         mov     byte [ebx], 4
  485.         push    70
  486.         pop     eax
  487.         push    ebx
  488.         int     0x40
  489.         pop     ebx
  490.         mov     byte [ebx], 3
  491.         test    eax, eax
  492.         jz      .sizeok
  493.         push    dword [ebx+21]
  494.         push    aCannotWriteFile
  495.         call    get_error_msg
  496.         push    eax
  497.         mov     eax, esp
  498.         push    RetryOrCancelBtn
  499.         push    2
  500.         push    eax
  501.         push    3
  502.         call    SayErr
  503.         add     esp, 12
  504.         test    eax, eax
  505.         jz      .setsize_retry
  506. .ret:
  507.         ret
  508. .sizeok:
  509.         and     dword [ebx+4], 0
  510.         mov     esi, [ebp + editor_data.first_block]
  511.         add     esi, ebp
  512.         mov     ebx, [EditBlockStart]
  513.         call    editor_normalize_offs
  514.         jnc     .writeok
  515.         lea     edi, [ebp + editor_data.buf]
  516. .loop:
  517.         mov     ecx, 16384
  518.         call    editor_get_data
  519.         test    eax, eax
  520.         jz      .done
  521.         push    ebx
  522.         mov     ebx, writeinfo
  523.         mov     [ebx+12], eax
  524.         mov     [ebx+16], edi
  525. .write_retry:
  526.         push    70
  527.         pop     eax
  528.         push    ebx
  529.         int     0x40
  530.         pop     ebx
  531.         test    eax, eax
  532.         jz      .writeok
  533.         push    dword [ebx+21]
  534.         push    aCannotWriteFile
  535.         call    get_error_msg
  536.         push    eax
  537.         mov     eax, esp
  538.         push    RetryOrCancelBtn
  539.         push    2
  540.         push    eax
  541.         push    3
  542.         call    SayErr
  543.         add     esp, 12
  544.         test    eax, eax
  545.         jz      .write_retry
  546.         ret
  547. .writeok:
  548.         mov     eax, [ebx+12]
  549.         add     [ebx+4], eax
  550.         adc     dword [ebx+8], 0
  551.         pop     ebx
  552.         jmp     .loop
  553. .done:
  554.         and     [ebp + editor_data.flags], not 0x80
  555.         ret
  556.  
  557. editor_calc_filesize:
  558.         xor     eax, eax
  559.         push    esi
  560.         mov     esi, [ebp + editor_data.first_block]
  561. @@:
  562.         add     esi, ebp
  563.         add     eax, [esi + edit_block_header.limit]
  564.         sub     eax, [EditBlockStart]
  565.         mov     esi, [esi + edit_block_header.next]
  566.         test    esi, esi
  567.         jnz     @b
  568.         pop     ebx
  569.         ret
  570.  
  571. editor_get_data:
  572.         push    edi
  573.         test    esi, esi
  574.         jz      .ret
  575. .loop:
  576.         mov     edx, [esi + edit_block_header.limit]
  577.         sub     edx, ebx
  578.         push    ecx
  579.         cmp     ecx, edx
  580.         jb      @f
  581.         mov     ecx, edx
  582. @@:
  583.         push    esi
  584.         add     esi, ebx
  585.         add     ebx, ecx
  586.         add     eax, ecx
  587.         rep     movsb
  588.         pop     esi
  589.         pop     ecx
  590.         sub     ecx, edx
  591.         jb      .ret
  592.         mov     esi, [esi + edit_block_header.next]
  593.         mov     ebx, [EditBlockStart]
  594.         test    esi, esi
  595.         jz      .ret
  596.         add     esi, ebp
  597.         jmp     .loop
  598. .ret:
  599.         mov     eax, edi
  600.         pop     edi
  601.         sub     eax, edi
  602.         ret
  603.  
  604. editor_get_pos:
  605.         ;mov    esi, [ebp + editor_data.curpos_block]
  606.         ;mov    ebx, [ebp + editor_data.curpos_offs]
  607.         mov     esi, [ebp + editor_data.linedata_start + editor_line.block]
  608.         sub     esi, ebp
  609.         movzx   ebx, [ebp + editor_data.linedata_start + editor_line.offs]
  610. @@:
  611.         test    esi, esi
  612.         jz      @f
  613.         add     esi, ebp
  614.         cmp     ebx, [esi + edit_block_header.limit]
  615.         jb      @f
  616.         mov     esi, [esi + edit_block_header.next]
  617.         mov     ebx, [EditBlockStart]
  618.         jmp     @b
  619. @@:
  620.         ret
  621.  
  622. editor_curline_start:
  623.         mov     edx, [EditPlugInfo]
  624.         add     edx, editor_line.plugdata
  625.         mov     eax, [ebp + editor_data.cursor_y]
  626.         dec     eax
  627.         imul    eax, edx
  628.         lea     edi, [ebp + eax + editor_data.linedata_start]
  629.         mov     esi, [edi + editor_line.block]
  630.         movzx   ebx, [edi + editor_line.offs]
  631.         ret
  632.  
  633. editor_step_forward:
  634. ; in: esi = block (must be nonzero), ebx = offset in block
  635. ; out: esi = block (zero iff EOF reached), ebx = offset in block
  636. ; out: CF=1 iff EOF NOT reached
  637.         inc     ebx
  638. editor_normalize_offs:
  639.         cmp     ebx, [esi + edit_block_header.limit]
  640.         jb      @f
  641.         mov     esi, [esi + edit_block_header.next]
  642.         mov     ebx, [EditBlockStart]
  643.         test    esi, esi
  644.         jz      @f
  645.         add     esi, ebp
  646.         stc
  647. @@:
  648.         ret
  649.  
  650. editor_step_backward:
  651. ; in: esi = block (must be nonzero), ebx = offset in block
  652. ; out: esi = block (zero iff input was at the beginning), ebx = offset in block
  653. ; out: CF=1 iff start of file reached
  654.         dec     ebx
  655.         cmp     ebx, [EditBlockStart]
  656.         jae     @f
  657.         mov     esi, [esi + edit_block_header.prev]
  658.         test    esi, esi
  659.         stc
  660.         jz      @f
  661.         add     esi, ebp
  662.         mov     ebx, [esi + edit_block_header.limit]
  663.         dec     ebx
  664. @@:
  665.         ret
  666.  
  667. editor_get_string:
  668. ; read string up to the end of line
  669. ; in: esi = block, ebx = offset in block
  670. ; in: edi = destination, ecx = maximum number of bytes to copy, edx = number of bytes to skip
  671. ; out: esi = block, ebx = offset in block
  672. ; out: ecx = number of rest bytes (ecx_in - ecx_out = number of copied characters)
  673.         mov     ah, [edit_normal_color]
  674.         cmp     ebx, [esi + edit_block_header.limit]
  675.         jz      .retnp
  676.         push    0       ; current position in line
  677. .loop:
  678.         test    ecx, ecx
  679.         jz      .ret
  680.         mov     al, [esi + ebx]
  681.         cmp     al, 13
  682.         jz      .ret
  683.         cmp     al, 10
  684.         jz      .ret
  685.         cmp     al, 9
  686.         jz      .tab
  687.         inc     dword [esp]
  688.         dec     edx
  689.         jns     .4
  690.         xor     edx, edx
  691.         stosw
  692.         dec     ecx
  693. .4:
  694.         call    editor_step_forward
  695.         jc      .loop
  696. .ret:
  697.         pop     edx
  698. .retnp:
  699.         ret
  700. .tab:
  701.         push    eax edx
  702.         mov     eax, [esp+8]
  703.         xor     edx, edx
  704.         div     [editor_tabsize]
  705.         sub     edx, [editor_tabsize]
  706.         neg     edx
  707.         add     [esp+8], edx
  708.         sub     [esp], edx
  709.         pop     edx eax
  710.         jns     .4
  711.         mov     al, ' '
  712. @@:
  713.         stosw
  714.         dec     ecx
  715.         jz      .ret
  716.         inc     edx
  717.         jnz     @b
  718.         jmp     .4
  719.  
  720. editor_find_newline:
  721. ; in: esi = block, ebx = offset in block
  722. ; out: esi = block, ebx = offset in block, ecx = line length
  723.         xor     ecx, ecx
  724.         test    esi, esi
  725.         jz      .ret0
  726.         cmp     ebx, [esi + edit_block_header.limit]
  727.         jb      .1
  728.         xor     esi, esi
  729. .ret0:
  730.         ret
  731. .1:
  732.         mov     al, [esi + ebx]
  733.         inc     ecx
  734.         call    editor_step_forward
  735.         cmp     al, 13
  736.         jz      .2
  737.         cmp     al, 10
  738.         jz      .2
  739.         test    esi, esi
  740.         jnz     .1
  741. .ret1:
  742.         mov     esi, [ebp + editor_data.last_block]
  743.         add     esi, ebp
  744.         mov     ebx, [esi + edit_block_header.limit]
  745.         ret
  746. .2:
  747.         dec     ecx
  748.         test    esi, esi
  749.         jz      .ret1
  750.         cmp     al, 13
  751.         jnz     .ret
  752.         cmp     byte [esi + ebx], 10
  753.         jnz     .ret
  754.         call    editor_step_forward
  755.         jnc     .ret1
  756. .ret:
  757.         ret
  758.  
  759. editor_prev_newline:
  760.         xor     ecx, ecx
  761.         test    esi, esi
  762.         jnz     @f
  763.         mov     esi, [ebp + editor_data.last_block]
  764.         add     esi, ebp
  765.         mov     ebx, [esi + edit_block_header.limit]
  766. @@:
  767.         call    editor_step_backward
  768.         jc      .ret
  769.         mov     al, [esi + ebx]
  770.         call    editor_step_backward
  771.         jc      .ret
  772.         cmp     al, 10
  773.         jnz     .1
  774.         cmp     byte [esi + ebx], 13
  775.         jnz     .1
  776. @@:
  777.         call    editor_step_backward
  778.         jc      .ret
  779. .1:
  780.         inc     ecx
  781.         mov     al, [esi + ebx]
  782.         cmp     al, 13
  783.         jz      @f
  784.         cmp     al, 10
  785.         jnz     @b
  786. @@:
  787.         dec     ecx
  788.         inc     ebx
  789.         cmp     ebx, [esi + edit_block_header.limit]
  790.         jb      .ret
  791.         mov     esi, [esi + edit_block_header.next]
  792.         mov     ebx, [EditBlockStart]
  793.         test    esi, esi
  794.         jz      .ret
  795.         add     esi, ebp
  796. .ret:
  797.         test    esi, esi
  798.         jnz     @f
  799.         mov     esi, [ebp + editor_data.first_block]
  800.         mov     ebx, [EditBlockStart]
  801.         add     esi, ebp
  802. @@:
  803.         ret
  804.  
  805. editor_init_lines:
  806.         call    editor_get_pos
  807.         test    esi, esi
  808.         jnz     @f
  809.         mov     esi, [ebp + editor_data.last_block]
  810.         add     esi, ebp
  811.         mov     ebx, [esi + edit_block_header.limit]
  812. @@:
  813.         mov     ecx, max_height
  814.         lea     edi, [ebp + editor_data.linedata_start]
  815. .1:
  816.         mov     eax, esi
  817.         stosd   ; editor_line.block
  818.         mov     eax, ebx
  819.         stosw   ; editor_line.offs
  820.         push    ecx
  821.         call    editor_find_newline
  822.         ;mov    eax, ecx
  823.         ;stosd  ; editor_line.length
  824.         xor     eax, eax
  825.         mov     ecx, [EditPlugInfo]
  826.         rep     stosb
  827.         pop     ecx
  828.         loop    .1
  829.         ret
  830.  
  831. editor_draw_status:
  832.         lea     edi, [ebp + editor_data.buf]
  833.         mov     ah, [edit_status_color]
  834.         mov     ecx, [cur_width]
  835.         sub     ecx, 56
  836.         cmp     ecx, 25
  837.         jge     @f
  838.         push    25
  839.         pop     ecx
  840. @@:
  841.         call    viewedit_draw_filename
  842.         inc     ecx
  843.         rep     stosw
  844.         test    [ebp + editor_data.flags], 80h
  845.         jz      @f
  846.         mov     al, '*'
  847. @@:
  848.         stosw
  849.         mov     al, ' '
  850.         test    [ebp + editor_data.flags], 40h
  851.         jz      @f
  852.         mov     al, '-'
  853. @@:
  854.         stosw
  855.         mov     al, ' '
  856.         test    [ebp + editor_data.flags], 20h
  857.         jz      @f
  858.         mov     al, '"'
  859. @@:
  860.         stosw
  861.         mov     al, ' '
  862.         mov     cl, 10
  863.         rep     stosw
  864.         movzx   esi, [ebp+editor_data.encoding]
  865.         lea     esi, [encodings.names+esi*8]
  866.         push    edi esi
  867.         dec     edi
  868.         dec     edi
  869.         std
  870.         add     esi, 8
  871. @@:
  872.         dec     esi
  873.         cmp     byte [esi], ' '
  874.         jz      @b
  875. @@:
  876.         lodsb
  877.         stosw
  878.         cmp     esi, [esp]
  879.         jae     @b
  880.         cld
  881.         pop     esi edi
  882.         mov     esi, aLine
  883.         mov     cl, 8
  884. @@:
  885.         lodsb
  886.         stosw
  887.         loop    @b
  888.         mov     cl, 13
  889.         mov     al, ' '
  890.         rep     stosw
  891.         std
  892.         push    edi
  893.         dec     edi
  894.         dec     edi
  895.         push    eax
  896.         mov     eax, [ebp + editor_data.numlines]
  897.         mov     cl, 10
  898. @@:
  899.         xor     edx, edx
  900.         div     ecx
  901.         xchg    eax, edx
  902.         add     al, '0'
  903.         mov     ah, [edit_status_color]
  904.         stosw
  905.         xchg    eax, edx
  906.         test    eax, eax
  907.         jnz     @b
  908.         mov     al, '/'
  909.         mov     ah, [edit_status_color]
  910.         stosw
  911.         mov     eax, [ebp + editor_data.curline]
  912.         add     eax, [ebp + editor_data.cursor_y]
  913. @@:
  914.         xor     edx, edx
  915.         div     ecx
  916.         xchg    eax, edx
  917.         add     al, '0'
  918.         mov     ah, [edit_status_color]
  919.         stosw
  920.         xchg    eax, edx
  921.         test    eax, eax
  922.         jnz     @b
  923.         pop     eax
  924.         stosw
  925.         cld
  926.         pop     edi
  927.         mov     ah, [edit_status_color]
  928.         mov     esi, aCol
  929.         mov     cl, 7
  930. @@:
  931.         lodsb
  932.         stosw
  933.         loop    @b
  934.         mov     eax, [ebp + editor_data.curcol]
  935.         add     eax, [ebp + editor_data.cursor_x]
  936.         inc     eax
  937.         mov     cl, 10
  938.         push    -'0'
  939. @@:
  940.         xor     edx, edx
  941.         div     ecx
  942.         push    edx
  943.         test    eax, eax
  944.         jnz     @b
  945. @@:
  946.         pop     eax
  947.         mov     ah, [edit_status_color]
  948.         add     al, '0'
  949.         jz      @f
  950.         stosw
  951.         jmp     @b
  952. @@:
  953.         mov     al, ' '
  954.         mov     cl, 13
  955.         rep     stosw
  956.         xor     eax, eax
  957.         xor     edx, edx
  958.         call    get_console_ptr
  959.         lea     esi, [ebp + editor_data.buf]
  960.         mov     ecx, [cur_width]
  961.         shr     ecx, 1
  962.         rep     movsd
  963.         adc     ecx, ecx
  964.         rep     movsw
  965.         cmp     [ebp + editor_data.cur_delta], -1
  966.         jnz     .a
  967.         mov     al, ' '
  968.         mov     byte [edi-4*2], al
  969.         mov     byte [edi-3*2], al
  970.         mov     byte [edi-2*2], al
  971.         mov     byte [edi-1*2], al
  972.         mov     eax, [ebp + editor_data.cur_block]
  973.         add     eax, ebp
  974.         add     eax, [ebp + editor_data.cur_offs]
  975.         movzx   eax, byte [eax]
  976.         mov     cl, 100
  977.         ;xor    edx, edx        ; edx=0 already
  978.         div     ecx
  979.         test    al, al
  980.         jz      @f
  981.         add     al, '0'
  982.         mov     [edi-3*2], al
  983. @@:
  984.         xchg    eax, edx
  985.         aam
  986.         test    ah, ah
  987.         jnz     .b
  988.         cmp     byte [edi-3*2], ' '
  989.         jz      @f
  990. .b:
  991.         add     ah, '0'
  992.         mov     [edi-2*2], ah
  993. @@:
  994.         add     al, '0'
  995.         mov     [edi-1*2], al
  996. .a:
  997.         ret
  998.  
  999. editor_draw_line:
  1000.         push    ecx
  1001.         mov     ecx, [cur_width]
  1002.         test    esi, esi
  1003.         jz      .2
  1004.         lea     edi, [ebp + editor_data.buf]
  1005.         push    edx edi
  1006.         mov     edx, [ebp + editor_data.curcol]
  1007.         call    editor_get_string
  1008.         mov     al, ' '
  1009.         rep     stosw
  1010.         pop     esi edx
  1011.         xor     eax, eax
  1012.         call    get_console_ptr
  1013.         mov     ecx, [cur_width]
  1014.         shr     ecx, 1
  1015.         rep     movsd
  1016.         adc     ecx, ecx
  1017.         rep     movsw
  1018.         pop     ecx
  1019.         ret
  1020. .2:
  1021.         xor     eax, eax
  1022.         call    get_console_ptr
  1023.         mov     al, ' '
  1024.         mov     ah, [edit_normal_color]
  1025.         rep     stosw
  1026.         pop     ecx
  1027.         ret
  1028.  
  1029. editor_draw_text:
  1030.         call    editor_draw_status
  1031.         push    1
  1032.         pop     edx
  1033.         lea     ecx, [ebp + editor_data.linedata_start]
  1034. .1:
  1035.         mov     esi, [ecx + editor_line.block]
  1036.         movzx   ebx, [ecx + editor_line.offs]
  1037.         add     ecx, editor_line.plugdata
  1038.         add     ecx, [EditPlugInfo]
  1039.         call    editor_draw_line
  1040.         inc     edx
  1041.         mov     eax, [cur_height]
  1042.         dec     eax
  1043.         cmp     edx, eax
  1044.         jb      .1
  1045.         jmp     draw_image
  1046.  
  1047. editor_set_keybar:
  1048.         mov     eax, keybar_editor
  1049.         movzx   esi, [ebp+editor_data.encoding]
  1050.         dec     esi
  1051.         jz      @f
  1052.         push    1
  1053.         pop     esi
  1054. @@:
  1055.         lea     esi, [encodings.names+esi*8]
  1056.         lea     edi, [eax+keybar_cp2-keybar_editor]
  1057.         movsd
  1058.         movsw
  1059.         jmp     draw_keybar
  1060.  
  1061. editor_up_scroll:
  1062.         push    ecx
  1063.         sub     [ebp + editor_data.curline], ecx
  1064.         mov     edx, [EditPlugInfo]
  1065.         add     edx, editor_line.plugdata
  1066.         imul    eax, edx, max_height
  1067.         imul    ecx, edx
  1068.         sub     ecx, eax
  1069.         neg     ecx
  1070.         lea     esi, [ebp + ecx + editor_data.linedata_start - 4]
  1071.         lea     edi, [ebp + eax + editor_data.linedata_start - 4]
  1072.         shr     ecx, 2
  1073.         std
  1074.         rep     movsd
  1075.         cld
  1076.         jnc     @f
  1077.         mov     cx, [esi+2]
  1078.         mov     [edi+2], cx
  1079.         sub     edi, 2
  1080. @@:
  1081.         pop     ecx
  1082.         add     edi, 4
  1083.         movzx   ebx, [edi + editor_line.offs]
  1084.         mov     esi, [edi + editor_line.block]
  1085. @@:
  1086.         push    ecx
  1087.         call    editor_prev_newline
  1088.         sub     edi, edx
  1089.         push    edi
  1090.         mov     eax, esi
  1091.         stosd   ; editor_line.offs
  1092.         mov     eax, ebx
  1093.         stosw   ; editor_line.block
  1094.         ;mov    eax, ecx
  1095.         ;stosd  ; editor_line.length
  1096.         mov     ecx, [EditPlugInfo]
  1097.         xor     eax, eax
  1098.         rep     stosb
  1099.         pop     edi
  1100.         pop     ecx
  1101.         loop    @b
  1102. ; fall through to editor_update_cur
  1103.  
  1104. editor_update_cur:
  1105.         mov     ecx, [ebp + editor_data.cursor_x]
  1106.         add     ecx, [ebp + editor_data.curcol]
  1107.         call    editor_curline_start
  1108.         xor     edx, edx        ; current position in the line
  1109.         cmp     ebx, [esi + edit_block_header.limit]
  1110.         jz      .notfound
  1111. .scan:
  1112.         mov     al, [esi+ebx]
  1113.         cmp     al, 13
  1114.         jz      .notfound
  1115.         cmp     al, 10
  1116.         jz      .notfound
  1117.         test    ecx, ecx
  1118.         jz      .found
  1119.         cmp     al, 9
  1120.         jz      .tab
  1121.         inc     edx
  1122.         dec     ecx
  1123.         call    editor_step_forward
  1124.         jc      .scan
  1125. .notfound:
  1126.         test    esi, esi
  1127.         jnz     @f
  1128.         mov     esi, [ebp + editor_data.last_block]
  1129.         add     esi, ebp
  1130.         mov     ebx, [esi + edit_block_header.limit]
  1131. @@:
  1132.         mov     [ebp + editor_data.cur_delta], ecx
  1133.         xor     eax, eax
  1134.         jmp     .reta
  1135. .found:
  1136.         xor     eax, eax
  1137. .founda:
  1138.         or      [ebp + editor_data.cur_delta], -1
  1139. .reta:
  1140.         sub     esi, ebp
  1141.         mov     [ebp + editor_data.cur_block], esi
  1142.         mov     [ebp + editor_data.cur_offs], ebx
  1143.         ret
  1144. .tab:
  1145.         push    edx
  1146.         mov     eax, edx
  1147.         xor     edx, edx
  1148.         div     [editor_tabsize]
  1149.         sub     edx, [editor_tabsize]
  1150.         neg     edx
  1151.         add     [esp], edx
  1152.         cmp     ecx, edx
  1153.         jb      .curintab
  1154.         sub     ecx, edx
  1155.         pop     edx
  1156.         call    editor_step_forward
  1157.         jnc     .notfound
  1158.         test    ecx, ecx
  1159.         jz      .found
  1160.         jmp     .scan
  1161. .curintab:
  1162.         sub     [esp], edx
  1163.         pop     edx
  1164.         cmp     edx, [ebp + editor_data.curcol]
  1165.         setc    al
  1166.         jae     @f
  1167.         mov     [ebp + editor_data.curcol], edx
  1168. @@:
  1169.         sub     edx, [ebp + editor_data.curcol]
  1170.         mov     [ebp + editor_data.cursor_x], edx
  1171.         mov     [cursor_x], edx
  1172.         jmp     .founda
  1173.  
  1174. editor_down_scroll:
  1175.         push    ecx
  1176.         lea     edi, [ebp + editor_data.linedata_start]
  1177.         mov     edx, [EditPlugInfo]
  1178.         add     edx, editor_line.plugdata
  1179.         imul    ecx, edx
  1180.         lea     esi, [edi + ecx]
  1181.         imul    eax, edx, max_height
  1182.         sub     eax, ecx
  1183.         mov     ecx, eax
  1184.         shr     ecx, 2
  1185.         rep     movsd
  1186.         adc     ecx, ecx
  1187.         rep     movsw
  1188. @@:
  1189.         mov     esi, edi
  1190.         sub     esi, edx
  1191.         movzx   ebx, [esi + editor_line.offs]
  1192.         mov     esi, [esi + editor_line.block]
  1193.         pop     ecx
  1194.         jecxz   .ret
  1195. @@:
  1196.         push    ecx
  1197.         call    editor_find_newline
  1198.         mov     eax, esi
  1199.         stosd   ; editor_line.block
  1200.         mov     eax, ebx
  1201.         stosw   ; editor_line.offs
  1202.         ;mov    eax, ecx
  1203.         ;stosd  ; editor_line.length
  1204.         mov     ecx, [EditPlugInfo]
  1205.         xor     eax, eax
  1206.         rep     stosb
  1207.         pop     ecx
  1208.         loop    @b
  1209. .ret:
  1210.         ret
  1211.  
  1212. editor_end_scroll:
  1213.         call    editor_curline_start
  1214. ; calculate visible length of the line (it differs from the real length if tabulations are present)
  1215.         xor     ecx, ecx
  1216.         cmp     ebx, [esi + edit_block_header.limit]
  1217.         jz      .calcdone
  1218. .calcloop:
  1219.         mov     al, [esi+ebx]
  1220.         cmp     al, 10
  1221.         jz      .calcdone
  1222.         cmp     al, 13
  1223.         jz      .calcdone
  1224.         cmp     al, 9
  1225.         jz      .calctab
  1226.         inc     ecx
  1227. .calcnext:
  1228.         call    editor_step_forward
  1229.         jc      .calcloop
  1230.         jmp     .calcdone
  1231. .calctab:
  1232.         mov     eax, ecx
  1233.         xor     edx, edx
  1234.         div     [editor_tabsize]
  1235.         sub     edx, [editor_tabsize]
  1236.         sub     ecx, edx
  1237.         jmp     .calcnext
  1238. .calcdone:
  1239.         test    esi, esi
  1240.         jnz     @f
  1241.         mov     esi, [ebp + editor_data.last_block]
  1242.         add     esi, ebp
  1243.         mov     ebx, [esi + edit_block_header.limit]
  1244. @@:
  1245.         sub     esi, ebp
  1246.         mov     [ebp + editor_data.cur_block], esi
  1247.         mov     [ebp + editor_data.cur_offs], ebx
  1248.         and     [ebp + editor_data.cur_delta], 0
  1249. ; ecx = number of symbols in the line
  1250. ; calculate new position of view range
  1251.         mov     eax, [ebp + editor_data.curcol]
  1252.         cmp     ecx, eax
  1253.         jb      .toleft
  1254.         add     eax, [cur_width]
  1255.         cmp     ecx, eax
  1256.         jae     .toright
  1257.         sub     ecx, [ebp + editor_data.curcol]
  1258.         mov     [ebp + editor_data.cursor_x], ecx
  1259.         mov     [cursor_x], ecx
  1260.         ret
  1261. .toleft:
  1262.         mov     [ebp + editor_data.curcol], ecx
  1263.         and     [ebp + editor_data.cursor_x], 0
  1264.         and     [cursor_x], 0
  1265.         stc
  1266.         ret
  1267. .toright:
  1268.         mov     eax, [cur_width]
  1269.         dec     eax
  1270.         sub     ecx, eax
  1271.         mov     [ebp + editor_data.curcol], ecx
  1272.         mov     [ebp + editor_data.cursor_x], eax
  1273.         mov     [cursor_x], eax
  1274.         stc
  1275.         ret
  1276.  
  1277. editor_move_linestart:
  1278. ; in: esi = block, ebx = start offset, ecx = delta
  1279.         lea     edi, [ebp + editor_data.linedata_start]
  1280.         mov     edx, max_height
  1281. .0:
  1282.         cmp     [edi + editor_line.block], esi
  1283.         jnz     .1
  1284.         movzx   eax, [edi + editor_line.offs]
  1285.         cmp     eax, ebx
  1286.         ja      .2
  1287. ;       push    eax
  1288. ;       add     eax, [edi + editor_line.length]
  1289. ;       cmp     eax, ebx
  1290. ;       jb      @f
  1291. ;       add     [edi + editor_line.length], ecx
  1292. ;@@:
  1293. ;       pop     eax
  1294.         cmp     eax, [esi + edit_block_header.limit]
  1295.         jb      .1
  1296.         push    esi ebx
  1297.         mov     ebx, eax
  1298.         jmp     .3
  1299. .2:
  1300.         push    esi ebx
  1301.         mov     ebx, eax
  1302.         add     ebx, ecx
  1303. .3:
  1304.         cmp     ebx, [esi + edit_block_header.limit]
  1305.         jb      .4
  1306.         cmp     [esi + edit_block_header.next], 0
  1307.         jz      .4
  1308.         sub     ebx, [esi + edit_block_header.limit]
  1309.         mov     esi, [esi + edit_block_header.next]
  1310.         add     esi, ebp
  1311.         add     ebx, [EditBlockStart]
  1312.         jmp     .3
  1313. .4:
  1314.         mov     [edi + editor_line.block], esi
  1315.         mov     [edi + editor_line.offs], bx
  1316.         pop     ebx esi
  1317. .1:
  1318.         add     edi, editor_line.plugdata
  1319.         add     edi, [EditPlugInfo]
  1320.         dec     edx
  1321.         jnz     .0
  1322.         ;lea    edx, [ebp + editor_data.curpos_block]
  1323.         ;call   .5
  1324.         ;add    edx, editor_data.cur_block - editor_data.curpos_block
  1325.         lea     edx, [ebp + editor_data.cur_block]
  1326. ;       call    .5
  1327. ;       ret
  1328. .5:
  1329.         mov     eax, [edx]
  1330.         add     eax, ebp
  1331.         cmp     eax, esi
  1332.         jnz     .6
  1333.         cmp     [edx+4], ebx
  1334.         jbe     @f
  1335.         add     [edx+4], ecx
  1336. @@:
  1337.         mov     eax, [edx+4]
  1338.         sub     eax, [esi + edit_block_header.limit]
  1339.         jb      .6
  1340.         push    ecx
  1341.         mov     ecx, [esi + edit_block_header.next]
  1342.         add     ecx, ebp
  1343.         add     eax, [EditBlockStart]
  1344.         mov     [edx], ecx
  1345.         mov     [edx+4], eax
  1346.         pop     ecx
  1347. .6:
  1348.         ret
  1349.  
  1350. editor_reserve_symbol:
  1351.         push    1
  1352.         pop     ecx
  1353.  
  1354. editor_reserve_space:
  1355. ; Вставляет пустое место внутрь цепочки блоков
  1356. ; in: ecx = number of symbols to add, esi = block, ebx = offset
  1357.         mov     eax, [esi + edit_block_header.limit]
  1358.         add     eax, ecx
  1359.         cmp     eax, 4096
  1360.         ja      .add
  1361.         mov     [esi + edit_block_header.limit], eax
  1362.         push    esi ecx
  1363.         sub     eax, ecx
  1364.         lea     esi, [esi + eax - 1]
  1365.         lea     edi, [esi + ecx]
  1366.         sub     eax, ebx
  1367.         mov     ecx, eax
  1368.         std
  1369.         rep     movsb
  1370.         cld
  1371.         pop     ecx esi
  1372.         call    editor_move_linestart
  1373.         clc
  1374.         ret
  1375. .add:
  1376.         push    ecx
  1377.         mov     eax, [esi + edit_block_header.limit]
  1378.         sub     eax, [EditBlockStart]
  1379.         add     eax, ecx
  1380.         push    eax
  1381.         xor     edx, edx
  1382.         div     [EditBlockSize]
  1383.         push    eax
  1384.         sub     eax, [ebp + editor_data.numfree]
  1385.         jbe     .norealloc
  1386.         mov     edx, [ebp + editor_data.memsize]
  1387.         push    eax edx
  1388.         add     eax, edx
  1389.         mov     ecx, eax
  1390.         shl     ecx, 12
  1391.         mov     edx, ebp
  1392.         call    xpgrealloc
  1393.         pop     edx ecx
  1394.         test    eax, eax
  1395.         jz      .nomem
  1396.         sub     eax, ebp
  1397.         add     ebp, eax
  1398.         add     esi, eax
  1399.         add     [ebp + editor_data.memsize], ecx
  1400.         push    ecx
  1401.         mov     ecx, max_height
  1402.         lea     edi, [ebp + editor_data.linedata_start]
  1403. @@:
  1404.         add     [edi + editor_line.block], eax
  1405.         add     edi, editor_line.plugdata
  1406.         add     edi, [EditPlugInfo]
  1407.         loop    @b
  1408.         pop     ecx
  1409.         shl     edx, 12
  1410.         add     [ebp + editor_data.numfree], ecx
  1411.         lea     edi, [edx + ebp]
  1412.         mov     eax, [ebp + editor_data.freeblocks]
  1413.         mov     [ebp + editor_data.freeblocks], edx
  1414. @@:
  1415.         add     edx, 1000h
  1416.         mov     [edi], edx
  1417.         add     edi, 1000h
  1418.         loop    @b
  1419.         mov     [edi-1000h], eax
  1420. .norealloc:
  1421.         pop     edx
  1422.         push    [esi + edit_block_header.next]
  1423.         push    esi
  1424.         sub     [ebp + editor_data.numfree], edx
  1425.         mov     edi, [ebp + editor_data.freeblocks]
  1426. @@:
  1427.         mov     [esi + edit_block_header.next], edi
  1428.         add     edi, ebp
  1429.         push    edi
  1430.         push    dword [edi]
  1431.         stosd   ; edit_block_header.next - will be filled later
  1432.         mov     eax, esi
  1433.         sub     eax, ebp
  1434.         stosd   ; edit_block_header.prev
  1435.         mov     eax, 4096 - edit.RESERVE_IN_BLOCK
  1436.         stosd   ; edit_block_header.limit
  1437.         mov     eax, [EditBlockSize]
  1438.         sub     [esp+16], eax
  1439.         xor     eax, eax
  1440.         mov     ecx, [EditPlugInfo]
  1441.         rep     stosb
  1442.         pop     edi
  1443.         pop     esi
  1444.         dec     edx
  1445.         jnz     @b
  1446.         mov     [ebp + editor_data.freeblocks], edi
  1447.         mov     edi, esi
  1448.         pop     esi
  1449.         pop     [edi + edit_block_header.next]
  1450.         pop     ecx
  1451.         add     ecx, [EditBlockSize]
  1452.         mov     edx, ecx
  1453.         shr     edx, 1;2
  1454.         mov     eax, ecx
  1455.         sub     eax, edx
  1456.         cmp     eax, [EditBlockSize]
  1457.         jb      @f
  1458.         mov     eax, [EditBlockSize]
  1459.         mov     edx, ecx
  1460.         sub     edx, eax
  1461. @@:
  1462.         add     eax, [EditBlockStart]
  1463.         add     edx, [EditBlockStart]
  1464.         mov     ecx, [esi + edit_block_header.limit]
  1465.         mov     [esi + edit_block_header.limit], eax
  1466.         mov     [edi + edit_block_header.limit], edx
  1467.         sub     ecx, ebx
  1468.         push    ecx
  1469.         push    esi edi ecx
  1470.         add     esi, ecx
  1471.         add     esi, ebx
  1472.         push    edx
  1473.         sub     edx, [EditBlockStart]
  1474.         cmp     ecx, edx
  1475.         jb      @f
  1476.         mov     ecx, edx
  1477. @@:
  1478.         pop     edx
  1479.         sub     [esp], ecx
  1480.         add     edi, edx
  1481.         sub     esi, ecx
  1482.         sub     edi, ecx
  1483.         rep     movsb
  1484.         pop     ecx edi esi
  1485.         push    esi edi
  1486.         lea     edi, [esi + eax - 1]
  1487.         add     esi, ebx
  1488.         lea     esi, [esi + ecx - 1]
  1489.         std
  1490.         rep     movsb
  1491.         cld
  1492.         pop     edi esi
  1493.         pop     ecx
  1494.         mov     ecx, ebx
  1495.         sub     ecx, eax
  1496.         jb      @f
  1497.         push    esi edi
  1498.         add     esi, eax
  1499.         add     edi, [EditBlockStart]
  1500.         rep     movsb
  1501.         pop     edi esi
  1502. @@:
  1503.         push    esi edi
  1504.         sub     esi, ebp
  1505.         sub     edi, ebp
  1506.         cmp     [ebp + editor_data.last_block], esi
  1507.         jnz     @f
  1508.         mov     [ebp + editor_data.last_block], edi
  1509. @@:
  1510.         pop     edi esi
  1511.         pop     ecx
  1512.         call    editor_move_linestart
  1513.         cmp     ebx, [esi + edit_block_header.limit]
  1514.         jb      @f
  1515.         sub     ebx, [esi + edit_block_header.limit]
  1516.         mov     esi, [esi + edit_block_header.next]
  1517.         add     esi, ebp
  1518.         add     ebx, [EditBlockStart]
  1519. @@:
  1520.         clc
  1521.         ret
  1522. .nomem:
  1523.         pop     eax
  1524.         pop     ecx
  1525.         pop     ecx
  1526.         add     esi, ebp
  1527.         stc
  1528.         ret
  1529.  
  1530. editor_delete_symbol:
  1531.         push    1
  1532.         pop     ecx
  1533.  
  1534. editor_delete_space:
  1535. ; Удаляет ecx байт из текста, начиная с esi:ebx
  1536. ; ecx, esi, ebx разрушаются
  1537.         mov     eax, [esi + edit_block_header.limit]
  1538.         sub     eax, ebx
  1539.         cmp     eax, ecx
  1540.         jb      .more1
  1541.         push    esi
  1542.         sub     [esi + edit_block_header.limit], ecx
  1543.         sub     eax, ecx
  1544.         lea     edi, [esi+ebx]
  1545.         lea     esi, [edi+ecx]
  1546.         mov     ecx, eax
  1547.         rep     movsb
  1548.         pop     esi
  1549. .done:
  1550.         call    .collapse_prev
  1551.         call    .collapse_next
  1552.         call    editor_init_lines
  1553.         jmp     editor_update_cur
  1554. .more1:
  1555.         mov     [esi + edit_block_header.limit], ebx
  1556.         sub     ecx, eax
  1557. @@:
  1558.         mov     esi, [esi + edit_block_header.next]
  1559.         add     esi, ebp
  1560.         mov     eax, [esi + edit_block_header.limit]
  1561.         sub     eax, [EditBlockStart]
  1562.         sub     ecx, eax
  1563.         jb      @f
  1564.         call    .delete_block
  1565.         jmp     @b
  1566. @@:
  1567.         add     ecx, eax
  1568.         push    esi
  1569.         mov     eax, [esi + edit_block_header.limit]
  1570.         sub     [esi + edit_block_header.limit], ecx
  1571.         add     eax, esi
  1572.         add     esi, [EditBlockStart]
  1573.         mov     edi, esi
  1574.         add     esi, ecx
  1575.         sub     eax, esi
  1576.         mov     ecx, esi
  1577.         rep     movsb
  1578.         pop     esi
  1579.         call    .collapse_next
  1580.         mov     esi, [esi + edit_block_header.prev]
  1581.         add     esi, ebp
  1582.         jmp     .done
  1583.  
  1584. .delete_block:
  1585.         mov     eax, [esi + edit_block_header.next]
  1586.         mov     edx, [esi + edit_block_header.prev]
  1587.         test    eax, eax
  1588.         jz      .dbfirst
  1589.         mov     [eax + ebp + edit_block_header.prev], edx
  1590.         jmp     @f
  1591. .dbfirst:
  1592.         mov     [ebp + editor_data.first_block], edx
  1593. @@:
  1594.         test    edx, edx
  1595.         jz      .dblast
  1596.         mov     [edx + ebp + edit_block_header.next], eax
  1597.         jmp     @f
  1598. .dblast:
  1599.         mov     [ebp + editor_data.last_block], eax
  1600. @@:
  1601.         mov     eax, [ebp + editor_data.freeblocks]
  1602.         mov     [esi], eax
  1603.         sub     esi, ebp
  1604.         mov     [ebp + editor_data.freeblocks], esi
  1605.         inc     [ebp + editor_data.numfree]
  1606.         ret
  1607.  
  1608. .collapse_prev:
  1609.         mov     eax, [esi + edit_block_header.prev]
  1610.         test    eax, eax
  1611.         jz      .cpno
  1612.         add     eax, ebp
  1613.         mov     edx, [esi + edit_block_header.limit]
  1614.         sub     edx, [EditBlockStart]
  1615.         add     edx, [eax + edit_block_header.limit]
  1616.         cmp     edx, 4096 - edit.RESERVE_IN_BLOCK
  1617.         ja      .cpno
  1618.         mov     edi, eax
  1619. .collapse:      ; (edi) + (esi) -> (edi)
  1620.         push    edi
  1621.         push    esi
  1622.         mov     ecx, [esi + edit_block_header.limit]
  1623.         sub     ecx, [EditBlockStart]
  1624.         add     esi, [EditBlockStart]
  1625.         mov     eax, [edi + edit_block_header.limit]
  1626.         add     [edi + edit_block_header.limit], ecx
  1627.         add     edi, eax
  1628.         rep     movsb
  1629.         pop     esi
  1630.         call    .delete_block
  1631.         pop     esi
  1632. .cpno:
  1633.         ret
  1634. .collapse_next:
  1635.         mov     eax, [esi + edit_block_header.next]
  1636.         test    eax, eax
  1637.         jz      .cpno
  1638.         add     eax, ebp
  1639.         mov     edx, [esi + edit_block_header.limit]
  1640.         sub     edx, [EditBlockStart]
  1641.         add     edx, [eax + edit_block_header.limit]
  1642.         cmp     edx, 4096 - edit.RESERVE_IN_BLOCK
  1643.         ja      .cpno
  1644.         mov     edi, esi
  1645.         mov     esi, eax
  1646.         jmp     .collapse
  1647.  
  1648. editor_OnKey:
  1649.         test    al, 80h
  1650.         jnz     .ret
  1651.         test    [ebp + editor_data.flags], 20h
  1652.         jnz     .symbol
  1653.         mov     esi, editor_ctrlkeys
  1654.         call    process_ctrl_keys
  1655.         jnc     .ret
  1656. .symbol:
  1657.         and     [ebp + editor_data.flags], not 20h
  1658.         test    [ebp + editor_data.flags], 40h
  1659.         jnz     .ret
  1660.         or      [ebp + editor_data.flags], 80h
  1661.         movzx   eax, al
  1662.         call    get_ascii_char
  1663.         mov     esi, [ebp + editor_data.cur_block]
  1664.         add     esi, ebp
  1665.         mov     ebx, [ebp + editor_data.cur_offs]
  1666.         cmp     al, 10
  1667.         jz      .insert_newline
  1668.         cmp     al, 13
  1669.         jz      .insert_newline
  1670.         cmp     [ebp + editor_data.cur_delta], -1
  1671.         jnz     .insert_after_eol
  1672.         test    [ebp + editor_data.flags], 10h
  1673.         jnz     .replace_symbol
  1674.         push    eax
  1675.         call    editor_reserve_symbol
  1676.         pop     eax
  1677.         jc      .ret
  1678. .replace_symbol:
  1679.         cmp     ebx, [esi + edit_block_header.limit]
  1680.         jnz     @f
  1681.         mov     esi, [esi + edit_block_header.next]
  1682.         add     esi, ebp
  1683.         mov     ebx, [EditBlockStart]
  1684. @@:
  1685.         mov     [esi + ebx], al
  1686. .symb_inserted:
  1687.         call    .redraw_curline
  1688.         jmp     .right
  1689. .redraw_curline:
  1690.         call    editor_curline_start
  1691.         mov     edx, [cursor_y]
  1692.         call    editor_draw_line
  1693. .ret:
  1694.         ret
  1695. .insert_after_eol:
  1696.         mov     ecx, [ebp + editor_data.cur_delta]
  1697.         inc     ecx
  1698.         push    eax
  1699.         call    editor_reserve_space
  1700.         pop     eax
  1701.         jc      .ret
  1702.         push    eax
  1703.         mov     edx, ecx
  1704. .2:
  1705.         mov     ecx, [esi + edit_block_header.limit]
  1706.         sub     ecx, ebx
  1707.         lea     edi, [esi + ebx]
  1708.         cmp     ecx, edx
  1709.         jb      @f
  1710.         mov     ecx, edx
  1711. @@:
  1712.         add     ebx, ecx
  1713.         sub     edx, ecx
  1714.         mov     al, ' '
  1715.         rep     stosb
  1716.         jz      @f
  1717.         mov     esi, [esi + edit_block_header.next]
  1718.         add     esi, ebp
  1719.         mov     ebx, [EditBlockStart]
  1720.         jmp     .2
  1721. @@:
  1722.         pop     eax
  1723.         mov     [edi-1], al
  1724.         dec     ebx
  1725.         sub     esi, ebp
  1726.         mov     [ebp + editor_data.cur_block], esi
  1727.         mov     [ebp + editor_data.cur_offs], ebx
  1728.         or      [ebp + editor_data.cur_delta], -1
  1729.         jmp     .symb_inserted
  1730. .insert_newline:
  1731.         push    1
  1732.         pop     ecx
  1733.         cmp     [ebp + editor_data.eol], 2
  1734.         adc     ecx, 0
  1735.         call    editor_reserve_space
  1736.         jc      .ret
  1737. ; Просто так вставлять символ новой строки чревато - из-за существования двухбайтовых комбинаций перевода строки
  1738. ; старый символ может слиться с новым. В таком случае придётся заниматься корректировкой.
  1739. ; Проблема бывает в двух случаях:
  1740. ; если редактор настроен на Unix-стиль и новый перевод строки вставляется непосредственно после
  1741. ;       перевода строки в Mac-стиле;
  1742. ; если редактор настроен на Mac-стиль и новый перевод строки вставляется непосредственно перед
  1743. ;       переводом строки в Unix-стиле.
  1744. ; В этих случаях форсируем перевод строки в текущем стиле файла.
  1745.         mov     al, [ebp + editor_data.eol]
  1746.         cmp     al, edit.eol_dos
  1747.         jz      .insert_eol_dos
  1748.         cmp     al, edit.eol_mac
  1749.         jz      .insert_eol_mac
  1750.         mov     al, 10  ; Unix-style for end-of-line
  1751.         push    esi ebx
  1752.         call    editor_step_backward
  1753.         jc      @f
  1754.         cmp     byte [esi+ebx], 13
  1755.         jnz     @f
  1756.         mov     al, 13  ; force Mac-style to avoid collapse
  1757. @@:
  1758.         pop     ebx esi
  1759.         mov     [esi+ebx], al
  1760.         jmp     .eol_correct
  1761. .insert_eol_mac:
  1762.         mov     al, 13  ; Mac-style for end-of-line
  1763.         push    esi ebx
  1764.         call    editor_step_forward
  1765.         jnc     @f
  1766.         cmp     byte [esi+ebx], 10
  1767.         jnz     @f
  1768.         mov     al, 10  ; force Unix-style to avoid collapse
  1769. @@:
  1770.         pop     ebx esi
  1771.         mov     [esi+ebx], al
  1772.         jmp     .eol_correct
  1773. .insert_eol_dos:
  1774.         mov     byte [esi+ebx], 13
  1775.         call    editor_step_forward
  1776.         mov     byte [esi+ebx], 10
  1777. .eol_correct:
  1778.         call    editor_step_forward
  1779.         test    esi, esi
  1780.         jnz     @f
  1781.         mov     esi, [ebp + editor_data.last_block]
  1782.         add     esi, ebp
  1783.         mov     ebx, [esi + edit_block_header.limit]
  1784. @@:
  1785.         and     [ebp + editor_data.cur_delta], 0
  1786.         cmp     ebx, [esi + edit_block_header.limit]
  1787.         jz      @f
  1788.         mov     al, [esi+ebx]
  1789.         cmp     al, 10
  1790.         jz      @f
  1791.         cmp     al, 13
  1792.         jz      @f
  1793.         dec     [ebp + editor_data.cur_delta]
  1794. @@:
  1795. ; ну что же, в текст нужные символы вставили, теперь надо скорректировать информацию о начале строк на экране
  1796.         mov     edi, [ebp + editor_data.cursor_y]
  1797.         mov     ecx, max_height-1
  1798.         sub     ecx, edi
  1799.         dec     edi
  1800.         mov     eax, [EditPlugInfo]
  1801.         add     eax, editor_line.plugdata
  1802.         imul    edi, eax, max_height
  1803.         imul    ecx, eax
  1804.         lea     edi, [ebp + edi + editor_data.linedata_start - 2]
  1805.         push    esi
  1806.         mov     esi, edi
  1807.         sub     esi, eax
  1808.         shr     ecx, 1
  1809.         std
  1810.         rep     movsw
  1811.         cld
  1812.         pop     esi
  1813.         add     edi, 2
  1814.         sub     edi, eax
  1815.         push    esi
  1816.         mov     esi, edi
  1817.         sub     esi, eax
  1818.         pop     eax
  1819.         stosd   ; editor_line.block
  1820.         sub     eax, ebp
  1821.         mov     [ebp + editor_data.cur_block], eax
  1822.         mov     eax, ebx
  1823.         stosw   ; editor_line.offs
  1824.         mov     [ebp + editor_data.cur_offs], eax
  1825.         ;mov    eax, ecx
  1826.         ;stosd  ; editor_line.length
  1827.         mov     ecx, [EditPlugInfo]
  1828.         xor     eax, eax
  1829.         rep     stosb
  1830. ; на одну строку стало больше
  1831.         inc     [ebp + editor_data.numlines]
  1832. ; курсор окажется в начале строки
  1833.         mov     [ebp + editor_data.cursor_x], eax
  1834.         mov     [ebp + editor_data.curcol], eax
  1835.         mov     [cursor_x], eax
  1836. ; и передвинется на строку ниже
  1837.         mov     eax, [ebp + editor_data.cursor_y]
  1838.         inc     eax
  1839.         mov     edx, [cur_height]
  1840.         dec     edx
  1841.         cmp     eax, edx
  1842.         jae     .down_scroll
  1843.         mov     [ebp + editor_data.cursor_y], eax
  1844.         mov     [cursor_y], eax
  1845.         jmp     editor_draw_text
  1846.  
  1847. .exit_confirm:
  1848.         test    [ebp + editor_data.flags], 80h
  1849.         jz      .exit
  1850.         push    aFileModified
  1851.         mov     eax, esp
  1852.         push    EditorExitBtn
  1853.         push    3
  1854.         push    eax
  1855.         push    1
  1856.         push    aEditorTitle
  1857.         call    SayErrTitle
  1858.         pop     ecx
  1859.         test    eax, eax
  1860.         jz      .save
  1861.         dec     eax
  1862.         jz      .exit
  1863.         ret
  1864. .exit_save:
  1865.         test    [ebp + editor_data.flags], 80h
  1866.         jz      .exit
  1867. .save:
  1868.         call    editor_save
  1869. .exit:
  1870.         call    editor_OnExit
  1871.         jmp     delete_active_screen
  1872. .f2:
  1873.         call    editor_save
  1874.         jmp     .redraw_status
  1875.  
  1876. .up_scroll:
  1877.         cmp     [ebp + editor_data.curline], 0
  1878.         jz      .ret
  1879.         push    1
  1880.         pop     ecx
  1881.         call    editor_up_scroll
  1882.         jmp     editor_draw_text
  1883. .up:
  1884.         mov     eax, [ebp + editor_data.cursor_y]
  1885.         dec     eax
  1886.         jz      .up_scroll
  1887. .set_cursor_y:
  1888.         mov     [ebp + editor_data.cursor_y], eax
  1889.         mov     [cursor_y], eax
  1890.         call    editor_update_cur
  1891.         test    al, al
  1892.         jnz     editor_draw_text
  1893. .redraw_status:
  1894.         call    editor_draw_status
  1895.         jmp     draw_image
  1896. .down:
  1897.         mov     eax, [ebp + editor_data.cursor_y]
  1898.         inc     eax
  1899.         push    eax
  1900.         add     eax, [ebp + editor_data.curline]
  1901.         cmp     eax, [ebp + editor_data.numlines]
  1902.         pop     eax
  1903.         ja      .ret
  1904.         mov     edx, [cur_height]
  1905.         dec     edx
  1906.         cmp     eax, edx
  1907.         jnz     .set_cursor_y
  1908. .down_scroll:
  1909.         inc     [ebp + editor_data.curline]
  1910.         lea     edi, [ebp + editor_data.linedata_start]
  1911.         mov     eax, [EditPlugInfo]
  1912.         add     eax, editor_line.plugdata
  1913.         lea     esi, [edi + eax]
  1914.         imul    ecx, eax, max_height-1
  1915.         shr     ecx, 2
  1916.         rep     movsd
  1917.         adc     ecx, ecx
  1918.         rep     movsw
  1919.         sub     esi, eax
  1920.         sub     esi, eax
  1921.         movzx   ebx, [esi + editor_line.offs]
  1922.         mov     esi, [esi + editor_line.block]
  1923.         call    editor_find_newline
  1924.         mov     eax, esi
  1925.         stosd   ; editor_line.block
  1926.         mov     eax, ebx
  1927.         stosw   ; editor_line.offs
  1928.         ;mov    eax, ecx
  1929.         ;stosd  ; editor_line.length
  1930.         mov     ecx, [EditPlugInfo]
  1931.         xor     eax, eax
  1932.         rep     stosb
  1933.         jmp     .ret2
  1934.  
  1935. .pgup:
  1936.         mov     ecx, [cur_height]
  1937.         sub     ecx, 3
  1938.         mov     edx, [ebp + editor_data.curline]
  1939.         mov     eax, edx
  1940.         push    edx
  1941.         sub     edx, ecx
  1942.         jnc     @f
  1943.         xor     edx, edx
  1944. @@:
  1945.         mov     [ebp + editor_data.curline], edx
  1946.         add     eax, [ebp + editor_data.cursor_y]
  1947.         dec     eax
  1948.         sub     eax, ecx
  1949.         jnc     @f
  1950.         xor     eax, eax
  1951. @@:
  1952.         sub     eax, edx
  1953.         inc     eax
  1954.         mov     [ebp + editor_data.cursor_y], eax
  1955.         mov     [cursor_y], eax
  1956.         pop     ecx
  1957.         sub     ecx, edx
  1958.         push    ecx
  1959.         mov     edx, [EditPlugInfo]
  1960.         add     edx, editor_line.plugdata
  1961.         imul    ecx, edx
  1962.         imul    eax, edx, max_height
  1963.         lea     edi, [ebp + editor_data.linedata_start + eax - 2]
  1964.         mov     esi, edi
  1965.         sub     esi, ecx
  1966.         sub     eax, ecx
  1967.         mov     ecx, eax
  1968.         shr     ecx, 1
  1969.         std
  1970.         rep     movsw
  1971.         cld
  1972.         pop     ecx
  1973.         jecxz   .ret2
  1974.         inc     edi
  1975.         inc     edi
  1976.         mov     esi, [edi + editor_line.block]
  1977.         movzx   ebx, [edi + editor_line.offs]
  1978. @@:
  1979.         push    ecx
  1980.         call    editor_prev_newline
  1981.         sub     edi, edx
  1982.         push    edi
  1983.         mov     eax, esi
  1984.         stosd   ; editor_line.block
  1985.         mov     eax, ebx
  1986.         stosw   ; editor_line.offs
  1987.         ;mov    eax, ecx
  1988.         ;stosd  ; editor_line.length
  1989.         mov     ecx, [EditPlugInfo]
  1990.         xor     eax, eax
  1991.         rep     stosb
  1992.         pop     edi
  1993.         pop     ecx
  1994.         loop    @b
  1995. .ret2:
  1996.         call    editor_update_cur
  1997.         jmp     editor_draw_text
  1998. .pgdn:
  1999.         mov     edx, [cur_height]
  2000.         sub     edx, 2
  2001.         mov     ecx, [ebp + editor_data.curline]
  2002.         push    ecx
  2003.         lea     ecx, [edx + ecx - 1]
  2004.         mov     eax, [ebp + editor_data.numlines]
  2005.         sub     eax, edx
  2006.         jnc     @f
  2007.         xor     eax, eax
  2008. @@:
  2009.         cmp     ecx, eax
  2010.         jb      @f
  2011.         mov     ecx, eax
  2012. @@:
  2013.         mov     [ebp + editor_data.curline], ecx
  2014.         pop     eax
  2015.         push    eax
  2016.         add     eax, [ebp + editor_data.cursor_y]
  2017.         lea     eax, [eax + edx - 1]
  2018.         cmp     eax, [ebp + editor_data.numlines]
  2019.         jb      @f
  2020.         mov     eax, [ebp + editor_data.numlines]
  2021. @@:
  2022.         sub     eax, ecx
  2023.         mov     [ebp + editor_data.cursor_y], eax
  2024.         mov     [cursor_y], eax
  2025.         pop     edx
  2026.         sub     ecx, edx
  2027.         call    editor_down_scroll
  2028.         jmp     .ret2
  2029.  
  2030. .left:
  2031.         call    editor_cursor_left
  2032.         jnc     .redraw_status
  2033.         jmp     editor_draw_text
  2034. .ret3:
  2035.         ret
  2036.  
  2037. .right:
  2038.         cmp     [ebp + editor_data.cur_delta], -1
  2039.         jz      .right_in_text
  2040.         cmp     [ebp + editor_data.curcol], 0x80000000 - 0x1000
  2041.         jae     .ret3
  2042.         inc     [ebp + editor_data.cur_delta]
  2043.         push    1
  2044.         pop     edx
  2045.         jmp     .right_char
  2046. .right_in_text:
  2047.         mov     esi, [ebp + editor_data.cur_block]
  2048.         add     esi, ebp
  2049.         mov     ebx, [ebp + editor_data.cur_offs]
  2050.         mov     al, [esi + ebx]
  2051.         push    eax
  2052.         call    editor_step_forward
  2053.         test    esi, esi
  2054.         jz      .right_eol0
  2055.         mov     al, [esi + ebx]
  2056.         cmp     al, 10
  2057.         jz      .right_eol
  2058.         cmp     al, 13
  2059.         jz      .right_eol
  2060.         jmp     .right_ok
  2061. .right_eol0:
  2062.         mov     esi, [ebp + editor_data.last_block]
  2063.         add     esi, ebp
  2064.         mov     ebx, [esi + edit_block_header.limit]
  2065. .right_eol:
  2066.         inc     [ebp + editor_data.cur_delta]
  2067. .right_ok:
  2068.         sub     esi, ebp
  2069.         mov     [ebp + editor_data.cur_block], esi
  2070.         mov     [ebp + editor_data.cur_offs], ebx
  2071.         pop     eax
  2072.         push    1
  2073.         pop     edx
  2074.         cmp     al, 9
  2075.         jnz     .right_char
  2076.         mov     eax, [ebp + editor_data.curcol]
  2077.         add     eax, [ebp + editor_data.cursor_x]
  2078.         xor     edx, edx
  2079.         div     [editor_tabsize]
  2080.         sub     edx, [editor_tabsize]
  2081.         neg     edx
  2082. .right_char:
  2083.         mov     eax, [ebp + editor_data.cursor_x]
  2084.         add     eax, edx
  2085.         cmp     eax, [cur_width]
  2086.         jb      .set_cursor_x
  2087.         add     eax, [ebp + editor_data.curcol]
  2088.         mov     edx, [cur_width]
  2089.         dec     edx
  2090.         sub     eax, edx
  2091.         mov     [ebp + editor_data.cursor_x], edx
  2092.         mov     [cursor_x], edx
  2093.         mov     [ebp + editor_data.curcol], eax
  2094.         jmp     editor_draw_text
  2095. .set_cursor_x:
  2096.         mov     [ebp + editor_data.cursor_x], eax
  2097.         mov     [cursor_x], eax
  2098.         jmp     .redraw_status
  2099.  
  2100. .home:
  2101.         call    editor_curline_start
  2102.         and     [ebp + editor_data.cur_delta], 0
  2103.         cmp     ebx, [esi + edit_block_header.limit]
  2104.         jz      @f
  2105.         mov     al, [esi+ebx]
  2106.         cmp     al, 10
  2107.         jz      @f
  2108.         cmp     al, 13
  2109.         jz      @f
  2110.         dec     [ebp + editor_data.cur_delta]
  2111. @@:
  2112.         sub     esi, ebp
  2113.         mov     [ebp + editor_data.cur_block], esi
  2114.         mov     [ebp + editor_data.cur_offs], ebx
  2115.         xor     eax, eax
  2116.         mov     [ebp + editor_data.cursor_x], eax
  2117.         mov     [cursor_x], eax
  2118.         xchg    eax, [ebp + editor_data.curcol]
  2119.         test    eax, eax
  2120.         jnz     editor_draw_text
  2121.         jmp     .redraw_status
  2122.  
  2123. .end:
  2124.         call    editor_end_scroll
  2125.         jc      editor_draw_text
  2126.         jmp     .redraw_status
  2127.  
  2128. .ins:
  2129.         xor     [ebp + editor_data.flags], 10h
  2130.         mov     eax, cursor_normal_size
  2131.         test    [ebp + editor_data.flags], 10h
  2132.         jz      @f
  2133.         mov     eax, cursor_big_size
  2134. @@:
  2135.         mov     [cursor_size], eax
  2136.         jmp     draw_image
  2137.  
  2138. .backspace:
  2139.         cmp     [ebp + editor_data.cur_delta], -1
  2140.         jz      @f
  2141.         cmp     [ebp + editor_data.cur_delta], 0
  2142.         jnz     .left
  2143. @@:
  2144.         test    [ebp + editor_data.flags], 40h
  2145.         jnz     .ret3
  2146.         mov     esi, [ebp + editor_data.cur_block]
  2147.         add     esi, ebp
  2148.         mov     ebx, [ebp + editor_data.cur_offs]
  2149.         call    editor_step_backward
  2150.         jc      .ret3
  2151.         push    esi ebx
  2152.         call    editor_cursor_left
  2153.         pop     ebx esi
  2154.         setc    al
  2155.         push    eax
  2156.         push    esi ebx
  2157.         cmp     byte [esi+ebx], 10
  2158.         jnz     @f
  2159.         call    editor_step_backward
  2160.         jc      @f
  2161.         cmp     byte [esi+ebx], 13
  2162.         jnz     @f
  2163.         pop     eax eax
  2164.         jmp     .del_char
  2165. @@:
  2166.         pop     ebx esi
  2167.         jmp     .del_char
  2168. .del:
  2169.         test    [ebp + editor_data.flags], 40h
  2170.         jnz     .ret3
  2171.         mov     esi, [ebp + editor_data.cur_block]
  2172.         add     esi, ebp
  2173.         mov     ebx, [ebp + editor_data.cur_offs]
  2174.         call    editor_normalize_offs
  2175.         jnc     .ret3
  2176.         push    0
  2177. .del_char:
  2178.         or      [ebp + editor_data.flags], 80h
  2179.         mov     al, [esi+ebx]
  2180.         push    1
  2181.         pop     ecx
  2182.         push    eax
  2183.         push    esi ebx
  2184.         cmp     al, 13
  2185.         jnz     @f
  2186.         call    editor_step_forward
  2187.         jnc     @f
  2188.         cmp     byte [esi+ebx], 10
  2189.         jnz     @f
  2190.         inc     ecx
  2191. @@:
  2192.         pop     ebx esi
  2193.         call    editor_delete_space
  2194.         pop     eax
  2195.         cmp     al, 13
  2196.         jz      @f
  2197.         cmp     al, 10
  2198.         jz      @f
  2199.         pop     eax
  2200.         test    al, al
  2201.         jnz     .del1
  2202.         call    .redraw_curline
  2203.         jmp     .redraw_status
  2204. @@:
  2205.         pop     eax
  2206.         dec     [ebp + editor_data.numlines]
  2207.         call    editor_test_cursor_y
  2208. .del1:
  2209.         jmp     editor_draw_text
  2210.  
  2211. .f7:
  2212.         call    find_in_file_dlg
  2213.         jz      .shift_f7
  2214. .f7.ret:
  2215.         ret
  2216. .shift_f7:
  2217. ; search string SearchString in file starting from current cursor position
  2218.         mov     ebx, SearchString
  2219.         xor     eax, eax
  2220.         cmp     byte [ebx], al
  2221.         jz      .f7.ret
  2222.         mov     esi, tolower_table
  2223.         test    [find_in_file_dlgdata.flags_case], 10h
  2224.         jz      @f
  2225.         mov     esi, identical_table
  2226. @@:
  2227.         test    [find_in_file_dlgdata.flags_whole], 10h
  2228.         setnz   al
  2229.         push    eax
  2230.         push    dword [ebp+editor_data.encoding]; always cp866 for now
  2231.                                 ; needs to be revisited after Unicode support in editor
  2232.         call    search_string_pre
  2233.         mov     esi, [ebp + editor_data.cur_block]
  2234.         add     esi, ebp
  2235.         mov     ebx, [ebp + editor_data.cur_offs]
  2236.         call    editor_normalize_offs
  2237.         jnc     .f7.notfound
  2238.         xor     edi, edi
  2239.         push    ebx esi
  2240.         push    edi
  2241.         push    edi
  2242.         test    [find_in_file_dlgdata.flags_whole], 10h
  2243.         jnz     @f
  2244.         movzx   eax, byte [esi+ebx]
  2245.         jmp     .search_loop_next
  2246. @@:
  2247.         mov     edi, edx
  2248. .search_loop:
  2249. ; edx -> FSM, ecx = last state, esi:ebx -> current data,
  2250. ; edi = current state
  2251. ; [esp] = row, [esp+4] = delta in lines
  2252. ; get current symbol
  2253.         movzx   eax, byte [esi+ebx]
  2254. ; calculate next state
  2255.         movzx   edi, byte [edi+eax]
  2256. ; done?
  2257.         cmp     edi, ecx
  2258.         jz      .f7.found
  2259. .search_loop_next:
  2260. ; no; proceed to next symbol
  2261.         add     ebx, 1
  2262.         shl     edi, 8
  2263.         add     dword [esp], 1
  2264.         add     edi, edx
  2265.         cmp     ebx, [esi + edit_block_header.limit]
  2266.         jae     .f7.nextblock
  2267. .f7.nonextblock:
  2268.         cmp     al, 10
  2269.         jz      .f7.newline
  2270.         cmp     al, 13
  2271.         jnz     .search_loop
  2272.         cmp     byte [esi+ebx], 10
  2273.         jnz     .f7.newline
  2274.         call    editor_step_forward
  2275.         jnc     .f7.notfound_pop
  2276. .f7.newline:
  2277.         mov     dword [esp], 0
  2278.         add     dword [esp+4], 1
  2279.         mov     dword [esp+8], esi
  2280.         mov     dword [esp+12], ebx
  2281.         jmp     .search_loop
  2282. .f7.nextblock:
  2283.         call    editor_normalize_offs
  2284.         jc      .f7.nonextblock
  2285. .f7.notfound_pop:
  2286. ; last chance - if we are looking for a whole word, EOF is ok for last symbol
  2287.         test    [find_in_file_dlgdata.flags_whole], 10h
  2288.         jz      @f
  2289.         mov     esi, [ebp + editor_data.last_block]
  2290.         add     esi, ebp
  2291.         mov     ebx, [esi + edit_block_header.limit]
  2292.         movzx   edi, byte [edi+' ']
  2293.         cmp     edi, ecx
  2294.         jz      .f7.found
  2295. @@:
  2296.         add     esp, 10h
  2297. .f7.notfound:
  2298.         jmp     search_failed
  2299. .f7.found:
  2300.         or      [ebp + editor_data.cur_delta], -1
  2301.         sub     ebx, ecx
  2302.         inc     ebx
  2303.         test    [find_in_file_dlgdata.flags_whole], 10h
  2304.         jz      @f
  2305.         inc     ebx
  2306. @@:
  2307.         cmp     ebx, [EditBlockStart]
  2308.         jge     @f
  2309.         sub     ebx, [EditBlockStart]
  2310.         mov     esi, [esi + edit_block_header.prev]
  2311.         add     esi, ebp
  2312.         add     ebx, [esi + edit_block_header.limit]
  2313.         jmp     @b
  2314. @@:
  2315.         sub     esi, ebp
  2316.         mov     [ebp + editor_data.cur_block], esi
  2317.         add     esi, ebp
  2318.         mov     [ebp + editor_data.cur_offs], ebx
  2319.         push    ecx
  2320.         mov     ecx, edx
  2321.         call    pgfree
  2322.         pop     ecx
  2323.         pop     eax
  2324.         pop     edi
  2325. ; esi:ebx -> last symbol of match, eax = row, edi = delta in lines
  2326.         pop     esi ebx
  2327.         test    [find_in_file_dlgdata.flags_whole], 10h
  2328.         jz      @f
  2329.         dec     ecx
  2330. @@:
  2331.         push    ebx esi
  2332.         sub     eax, ecx
  2333.         lea     edx, [eax+1]
  2334.         mov     eax, [ebp + editor_data.curcol]
  2335.         add     eax, [ebp + editor_data.cursor_x]
  2336.         test    edi, edi
  2337.         jz      @f
  2338.         xor     eax, eax
  2339. @@:
  2340.         test    edx, edx
  2341.         jz      .f7.foundpos1
  2342. .f7.findpos1:
  2343.         cmp     byte [ebx+esi], 9
  2344.         jz      .f7.findpos1.tab
  2345.         inc     eax
  2346.         call    editor_step_forward
  2347.         dec     edx
  2348.         jnz     .f7.findpos1
  2349.         jmp     .f7.foundpos1
  2350. .f7.findpos1.tab:
  2351.         push    edx eax
  2352.         xor     edx, edx
  2353.         div     [editor_tabsize]
  2354.         pop     eax
  2355.         sub     edx, [editor_tabsize]
  2356.         sub     eax, edx
  2357.         call    editor_step_forward
  2358.         pop     edx
  2359.         dec     edx
  2360.         jnz     .f7.findpos1
  2361. .f7.foundpos1:
  2362.         pop     esi ebx
  2363.         push    eax
  2364.         cmp     eax, [ebp + editor_data.curcol]
  2365.         jb      .f7.scrollleft
  2366.         sub     eax, [ebp + editor_data.curcol]
  2367.         sub     eax, [cur_width]
  2368.         jb      .f7.xset
  2369.         inc     eax
  2370.         inc     edx
  2371.         add     [ebp + editor_data.curcol], eax
  2372.         jmp     .f7.xset
  2373. .f7.scrollleft:
  2374.         inc     edx
  2375.         mov     [ebp + editor_data.curcol], eax
  2376. .f7.xset:
  2377.         pop     eax
  2378.         push    edx
  2379.         sub     eax, [ebp + editor_data.curcol]
  2380.         mov     [ebp + editor_data.cursor_x], eax
  2381.         mov     [cursor_x], eax
  2382.         add     edi, [ebp + editor_data.cursor_y]
  2383.         push    edi
  2384.         inc     edi
  2385.         cmp     edi, [cur_height]
  2386.         pop     edi
  2387.         jae     .f7.newview
  2388.         mov     [ebp + editor_data.cursor_y], edi
  2389.         mov     [cursor_y], edi
  2390.         jmp     .f7.yset
  2391. .f7.newview:
  2392.         dec     edi
  2393.         mov     [ebp + editor_data.linedata_start + editor_line.block], esi
  2394.         mov     [ebp + editor_data.linedata_start + editor_line.offs], bx
  2395.         add     [ebp + editor_data.curline], edi
  2396.         xor     eax, eax
  2397.         inc     eax
  2398.         mov     [ebp + editor_data.cursor_y], eax
  2399.         mov     [cursor_y], eax
  2400.         call    editor_init_lines
  2401.         call    editor_test_cursor_y
  2402.         inc     dword [esp]
  2403. .f7.yset:
  2404.         pop     eax
  2405.         test    eax, eax
  2406.         jz      .redraw_status
  2407.         jmp     editor_draw_text
  2408.  
  2409. editor_cursor_left:
  2410.         cmp     [ebp + editor_data.cur_delta], -1
  2411.         jz      .in_text
  2412.         dec     [ebp + editor_data.cur_delta]
  2413.         cmp     [ebp + editor_data.cur_delta], -1
  2414.         jnz     .left_cursor
  2415. .in_text:
  2416.         mov     esi, [ebp + editor_data.cur_block]
  2417.         add     esi, ebp
  2418.         mov     ebx, [ebp + editor_data.cur_offs]
  2419.         call    editor_step_backward
  2420.         jc      .ret_clc
  2421.         mov     al, [esi + ebx]
  2422.         cmp     al, 13
  2423.         jz      .eol
  2424.         cmp     al, 10
  2425.         jz      .eol2
  2426.         cmp     al, 9
  2427.         jz      .tab
  2428.         sub     esi, ebp
  2429.         mov     [ebp + editor_data.cur_block], esi
  2430.         mov     [ebp + editor_data.cur_offs], ebx
  2431. .left_cursor:
  2432.         mov     eax, [ebp + editor_data.cursor_x]
  2433.         test    eax, eax
  2434.         jz      @f
  2435.         dec     eax
  2436. .set_cursor_x:
  2437.         mov     [ebp + editor_data.cursor_x], eax
  2438.         mov     [cursor_x], eax
  2439. .ret_clc:
  2440.         clc
  2441.         ret
  2442. @@:
  2443.         dec     [ebp + editor_data.curcol]
  2444.         jmp     .ret_stc
  2445. .tab:
  2446.         mov     eax, [ebp + editor_data.cursor_x]
  2447.         test    eax, eax
  2448.         jz      @f
  2449.         dec     eax
  2450.         mov     [ebp + editor_data.cursor_x], eax
  2451.         mov     [cursor_x], eax
  2452.         call    editor_update_cur
  2453.         test    al, al
  2454.         jz      .ret_clc
  2455. .ret_stc:
  2456.         stc
  2457.         ret
  2458. @@:
  2459.         dec     [ebp + editor_data.curcol]
  2460.         call    editor_update_cur
  2461.         jmp     .ret_stc
  2462. .eol2:
  2463.         push    esi ebx
  2464.         call    editor_step_backward
  2465.         jc      @f
  2466.         cmp     byte [esi + ebx], 13
  2467.         jnz     @f
  2468.         pop     eax eax
  2469.         push    esi ebx
  2470. @@:
  2471.         pop     ebx esi
  2472. .eol:
  2473.         mov     eax, [ebp + editor_data.cursor_y]
  2474.         dec     eax
  2475.         jz      .scroll_left_toup
  2476.         push    0       ; no full redraw
  2477.         mov     [ebp + editor_data.cursor_y], eax
  2478.         mov     [cursor_y], eax
  2479.         jmp     .scroll_left_toend
  2480. .scroll_left_toup:
  2481.         push    1
  2482.         pop     ecx
  2483.         call    editor_up_scroll
  2484.         push    1       ; full redraw required
  2485. .scroll_left_toend:
  2486.         call    editor_end_scroll
  2487.         pop     eax
  2488.         adc     al, 0
  2489.         jnz     .ret_stc
  2490.         jmp     .ret_clc
  2491.  
  2492. editor_test_cursor_x:
  2493.         mov     ecx, [cur_width]
  2494.         dec     ecx
  2495.         mov     eax, [ebp + editor_data.cursor_x]
  2496.         sub     eax, ecx
  2497.         jbe     @f
  2498.         add     [ebp + editor_data.curcol], eax
  2499.         mov     [ebp + editor_data.cursor_x], ecx
  2500.         mov     [cursor_x], ecx
  2501. @@:
  2502.         ret
  2503.  
  2504. editor_test_cursor_y:
  2505.         mov     ecx, [ebp + editor_data.cursor_y]
  2506.         mov     edx, [cur_height]
  2507.         dec     edx
  2508.         dec     edx
  2509.         sub     ecx, edx
  2510.         ja      .scroll_down
  2511.         mov     ecx, [ebp + editor_data.curline]
  2512.         add     ecx, edx
  2513.         sub     ecx, [ebp + editor_data.numlines]
  2514.         ja      .scroll_up
  2515. .clc_ret:
  2516.         clc
  2517.         ret
  2518. .scroll_down:
  2519.         add     [ebp + editor_data.curline], ecx
  2520.         sub     [ebp + editor_data.cursor_y], ecx
  2521.         sub     [cursor_y], ecx
  2522.         call    editor_down_scroll
  2523.         stc
  2524.         ret
  2525. .scroll_up:
  2526.         cmp     ecx, [ebp + editor_data.curline]
  2527.         jb      @f
  2528.         mov     ecx, [ebp + editor_data.curline]
  2529. @@:
  2530.         jecxz   .clc_ret
  2531.         add     [ebp + editor_data.cursor_y], ecx
  2532.         add     [cursor_y], ecx
  2533.         call    editor_up_scroll
  2534.         stc
  2535.         ret
  2536.  
  2537. editor_OnExit:
  2538.         mov     edx, [ebp+editor_data.hPlugin]
  2539.         test    edx, edx
  2540.         jz      @f
  2541.         mov     ebx, [ebp+editor_data.hFile]
  2542.         call    close_handle_if_unused
  2543. @@:
  2544.         ret
  2545.  
  2546. find_in_file_dlg:
  2547.         mov     ebx, find_in_file_dlgdata
  2548.         mov     eax, [cur_width]
  2549.         sub     eax, 12
  2550.         mov     [ebx + dlgtemplate.width], eax
  2551.         dec     eax
  2552.         dec     eax
  2553.         mov     [ebx - find_in_file_dlgdata + find_in_file_dlgdata.width2], eax
  2554.         shr     eax, 1
  2555.         dec     eax
  2556.         dec     eax
  2557.         mov     [ebx - find_in_file_dlgdata + find_in_file_dlgdata.search_x2], eax
  2558.         sub     eax, aSearchBLength-1
  2559.         mov     [ebx - find_in_file_dlgdata + find_in_file_dlgdata.search_x1], eax
  2560.         add     eax, aSearchBLength+3
  2561.         mov     [ebx - find_in_file_dlgdata + find_in_file_dlgdata.cnl_x1], eax
  2562.         add     eax, aCancelBLength - 1
  2563.         mov     [ebx - find_in_file_dlgdata + find_in_file_dlgdata.cnl_x2], eax
  2564.         mov     byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags0], 0xC
  2565.         and     byte [ebx - find_in_file_dlgdata + find_in_file_dlgdata.flags1], not 4