Subversion Repositories Kolibri OS

Rev

Rev 1568 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;================================================================================================;;
  2. ;;//// libini_p.asm //// (c) mike.dld, 2006-2008 /////////////////////////////////////////////////;;
  3. ;;================================================================================================;;
  4. ;;                                                                                                ;;
  5. ;; This file is part of Common development libraries (Libs-Dev).                                  ;;
  6. ;;                                                                                                ;;
  7. ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
  8. ;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
  9. ;; of the License, or (at your option) any later version.                                         ;;
  10. ;;                                                                                                ;;
  11. ;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without  ;;
  12. ;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  ;;
  13. ;; Lesser General Public License for more details.                                                ;;
  14. ;;                                                                                                ;;
  15. ;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
  16. ;; If not, see <http://www.gnu.org/licenses/>.                                                    ;;
  17. ;;                                                                                                ;;
  18. ;;================================================================================================;;
  19.  
  20. mem.alloc   dd ?
  21. mem.free    dd ?
  22. mem.realloc dd ?
  23. dll.load    dd ?
  24.  
  25. ;;================================================================================================;;
  26. proc libini._.init ;//////////////////////////////////////////////////////////////////////////////;;
  27. ;;------------------------------------------------------------------------------------------------;;
  28. ;? Library entry point (called after library load)                                                ;;
  29. ;;------------------------------------------------------------------------------------------------;;
  30. ;> eax = memory allocation routine <mem.alloc*>                                                   ;;
  31. ;> ebx = memory freeing routine <mem.free*>                                                       ;;
  32. ;> ecx = memory reallocation routine <mem.realloc*>                                               ;;
  33. ;> edx = library loading routine <dll.load*>                                                      ;;
  34. ;;------------------------------------------------------------------------------------------------;;
  35. ;< eax = 1 (fail) / 0 (ok) (library initialization result)                                        ;;
  36. ;;================================================================================================;;
  37.         mov     [mem.alloc], eax
  38.         mov     [mem.free], ebx
  39.         mov     [mem.realloc], ecx
  40.         mov     [dll.load], edx
  41.  
  42.         invoke  dll.load, @IMPORT
  43.         or      eax, eax
  44.         jz      .ok
  45.  
  46.         xor     eax, eax
  47.         inc     eax
  48.         ret
  49.  
  50.   .ok:  xor     eax,eax
  51.         ret
  52. endp
  53.  
  54. ;;================================================================================================;;
  55. proc libini._.unget_char _f ;/////////////////////////////////////////////////////////////////////;;
  56. ;;------------------------------------------------------------------------------------------------;;
  57. ;? --- TBD ---                                                                                    ;;
  58. ;;------------------------------------------------------------------------------------------------;;
  59. ;> --- TBD ---                                                                                    ;;
  60. ;;------------------------------------------------------------------------------------------------;;
  61. ;< --- TBD ---                                                                                    ;;
  62. ;;================================================================================================;;
  63.         push    eax ecx
  64.         mov     ecx, [_f]
  65.         inc     [ecx + IniFile.cnt]
  66.         dec     esi
  67.         mov     eax, [ecx + IniFile.bsize]
  68.         cmp     [ecx + IniFile.cnt], eax
  69.         jle     @f
  70.         stdcall libini._.unload_block, [_f]
  71.     @@: pop     ecx eax
  72.         ret
  73. endp
  74.  
  75. ;;================================================================================================;;
  76. proc libini._.get_char _f ;///////////////////////////////////////////////////////////////////////;;
  77. ;;------------------------------------------------------------------------------------------------;;
  78. ;? --- TBD ---                                                                                    ;;
  79. ;;------------------------------------------------------------------------------------------------;;
  80. ;> --- TBD ---                                                                                    ;;
  81. ;;------------------------------------------------------------------------------------------------;;
  82. ;< --- TBD ---                                                                                    ;;
  83. ;;================================================================================================;;
  84.         push ecx
  85.         mov     ecx, [_f]
  86.         dec     [ecx + IniFile.cnt]
  87.         jns     @f
  88.         stdcall libini._.preload_block, [_f]
  89.         dec     [ecx + IniFile.cnt]
  90.     @@: lodsb
  91.         pop ecx
  92.         ret
  93. endp
  94.  
  95. ;;================================================================================================;;
  96. proc libini._.skip_nonblanks _f ;/////////////////////////////////////////////////////////////////;;
  97. ;;------------------------------------------------------------------------------------------------;;
  98. ;? --- TBD ---                                                                                    ;;
  99. ;;------------------------------------------------------------------------------------------------;;
  100. ;> --- TBD ---                                                                                    ;;
  101. ;;------------------------------------------------------------------------------------------------;;
  102. ;< --- TBD ---                                                                                    ;;
  103. ;;================================================================================================;;
  104.         push ecx
  105.         mov     ecx, [_f]
  106.     @@: stdcall libini._.get_char, [_f]
  107.         cmp     al, 32
  108.         je      @b
  109.         cmp     al, 13
  110.         je      @b
  111.         cmp     al, 10
  112.         je      @b
  113.         cmp     al, 9
  114.         je      @b
  115.         cmp     al, ini.COMMENT_CHAR
  116.         jne     @f
  117.         stdcall libini._.skip_line, [_f]
  118.         jmp     @b
  119.     @@: stdcall libini._.unget_char, [_f]
  120.         pop ecx
  121.         ret
  122. endp
  123.  
  124. ;;================================================================================================;;
  125. proc libini._.skip_spaces _f ;////////////////////////////////////////////////////////////////////;;
  126. ;;------------------------------------------------------------------------------------------------;;
  127. ;? --- TBD ---                                                                                    ;;
  128. ;;------------------------------------------------------------------------------------------------;;
  129. ;> --- TBD ---                                                                                    ;;
  130. ;;------------------------------------------------------------------------------------------------;;
  131. ;< --- TBD ---                                                                                    ;;
  132. ;;================================================================================================;;
  133.         push ecx
  134.         mov     ecx, [_f]
  135.     @@: stdcall libini._.get_char, [_f]
  136.         cmp     al, 32
  137.         je      @b
  138.         cmp     al, 9
  139.         je      @b
  140.     @@: stdcall libini._.unget_char, [_f]
  141.         pop ecx
  142.         ret
  143. endp
  144.  
  145. ;;================================================================================================;;
  146. proc libini._.skip_line _f ;//////////////////////////////////////////////////////////////////////;;
  147. ;;------------------------------------------------------------------------------------------------;;
  148. ;? --- TBD ---                                                                                    ;;
  149. ;;------------------------------------------------------------------------------------------------;;
  150. ;> --- TBD ---                                                                                    ;;
  151. ;;------------------------------------------------------------------------------------------------;;
  152. ;< --- TBD ---                                                                                    ;;
  153. ;;================================================================================================;;
  154.         push ecx
  155.         mov     ecx, [_f]
  156.     @@: stdcall libini._.get_char, [_f]
  157.         or      al, al
  158.         jz      @f
  159.         cmp     al, 13
  160.         je      @f
  161.         cmp     al, 10
  162.         jne     @b
  163.     @@: stdcall libini._.unget_char, [_f]
  164.         pop ecx
  165.         ret
  166. endp
  167.  
  168. ;;================================================================================================;;
  169. proc libini._.unload_block _f ;///////////////////////////////////////////////////////////////////;;
  170. ;;------------------------------------------------------------------------------------------------;;
  171. ;? --- TBD ---                                                                                    ;;
  172. ;;------------------------------------------------------------------------------------------------;;
  173. ;> --- TBD ---                                                                                    ;;
  174. ;;------------------------------------------------------------------------------------------------;;
  175. ;< --- TBD ---                                                                                    ;;
  176. ;;================================================================================================;;
  177.         push    eax ebx ecx
  178.         mov     ebx, [_f]
  179.         mov     eax, [ebx + IniFile.pos]
  180.         add     eax, -ini.BLOCK_SIZE
  181.         invoke  file.seek, [ebx + IniFile.fh], eax, SEEK_SET
  182.         stdcall libini._.preload_block, ebx
  183.         add     esi, eax
  184.         mov     [ebx + IniFile.cnt], 0
  185.         pop     ecx ebx eax
  186.         ret
  187. endp
  188.  
  189. ;;================================================================================================;;
  190. proc libini._.preload_block _f ;//////////////////////////////////////////////////////////////////;;
  191. ;;------------------------------------------------------------------------------------------------;;
  192. ;? --- TBD ---                                                                                    ;;
  193. ;;------------------------------------------------------------------------------------------------;;
  194. ;> --- TBD ---                                                                                    ;;
  195. ;;------------------------------------------------------------------------------------------------;;
  196. ;< --- TBD ---                                                                                    ;;
  197. ;;================================================================================================;;
  198.         push    eax ebx ecx
  199.         mov     ebx, [_f]
  200.     @@: mov     esi, [ebx + IniFile.buf]
  201.         push    edi
  202.         mov     edi, esi
  203.         mov     ecx, ini.BLOCK_SIZE / 4
  204.         xor     eax, eax
  205.         rep     stosd
  206.         pop     edi
  207.         invoke  file.tell, [ebx + IniFile.fh]
  208.         mov     [ebx + IniFile.pos], eax
  209.         invoke  file.read, [ebx + IniFile.fh], esi, ini.BLOCK_SIZE
  210.         mov     esi,[ebx + IniFile.buf]
  211.         cmp     eax,ini.BLOCK_SIZE
  212.         jl      @f
  213.     @@: mov     [ebx + IniFile.cnt], eax
  214.         mov     [ebx + IniFile.bsize], eax
  215.         pop     ecx ebx eax
  216.         ret
  217. endp
  218.  
  219. ;;================================================================================================;;
  220. proc libini._.reload_block _f ;///////////////////////////////////////////////////////////////////;;
  221. ;;------------------------------------------------------------------------------------------------;;
  222. ;? --- TBD ---                                                                                    ;;
  223. ;;------------------------------------------------------------------------------------------------;;
  224. ;> --- TBD ---                                                                                    ;;
  225. ;;------------------------------------------------------------------------------------------------;;
  226. ;< --- TBD ---                                                                                    ;;
  227. ;;================================================================================================;;
  228.         push    eax ebx ecx
  229.         mov     ebx, [_f]
  230.         push    [ebx + IniFile.bsize]
  231.         push    esi [ebx + IniFile.cnt]
  232.         invoke  file.seek, [ebx + IniFile.fh], [ebx + IniFile.pos], SEEK_SET
  233.         stdcall libini._.preload_block, ebx
  234.         pop     [ebx + IniFile.cnt] esi
  235.         pop     eax
  236.         sub     eax,[ebx + IniFile.bsize]
  237.         sub     [ebx + IniFile.cnt], eax
  238.         pop     ecx ebx eax
  239.         ret
  240. endp
  241.  
  242. ; f_info - contains current file block number
  243. ; esi    - position in block from where to shift
  244. ; ecx    - number of bytes to shift by
  245.  
  246. ;;================================================================================================;;
  247. proc libini._.shift_content _f, _delta ;//////////////////////////////////////////////////////////;;
  248. ;;------------------------------------------------------------------------------------------------;;
  249. ;? Shift file content starting from cursor position (~ delete)                                    ;;
  250. ;? Content is copied by 'delta' bytes up/down                                                     ;;
  251. ;;------------------------------------------------------------------------------------------------;;
  252. ;> --- TBD ---                                                                                    ;;
  253. ;;------------------------------------------------------------------------------------------------;;
  254. ;< eax = -1 (fail) / 0 (ok)                                                                       ;;
  255. ;;================================================================================================;;
  256. locals
  257.   buf dd ?
  258. endl
  259.  
  260.         xor     eax, eax
  261.         cmp     [_delta], 0
  262.         je      .skip
  263.  
  264.         push    ebx ecx
  265.         invoke  mem.alloc, ini.BLOCK_SIZE
  266.         or      eax, eax
  267.         jz      .fail
  268.         mov     [buf], eax
  269.  
  270.         cmp     [_delta], 0
  271.         jl      .down
  272.  
  273.         mov     ebx, [_f]
  274.         mov     ecx, [ebx + IniFile.cnt]
  275.         mov     ebx, [ebx + IniFile.fh]
  276.         invoke  file.tell, ebx
  277.         sub     eax, ecx
  278.         invoke  file.seek, ebx, eax, SEEK_SET
  279.     @@: invoke  file.seek, ebx, [_delta], SEEK_CUR
  280.         invoke  file.eof?, ebx
  281.         or      eax, eax
  282.         jnz     .done
  283.         invoke  file.read, ebx, [buf], ini.BLOCK_SIZE
  284.         mov     ecx, eax
  285.         mov     eax, [_delta]
  286.         neg     eax
  287.         sub     eax, ecx
  288.         invoke  file.seek, ebx, eax, SEEK_CUR
  289.         push    ecx
  290.         invoke  file.write, ebx, [buf], ecx
  291.         pop     ecx
  292.         cmp     eax, ecx
  293.         jz      @b
  294.   .fail:
  295.         or      eax, -1
  296.         pop     ecx ebx
  297.         ret
  298.   .done:
  299.         mov     eax, [_delta]
  300.         neg     eax
  301.         invoke  file.seek, ebx, eax, SEEK_CUR
  302.         invoke  file.seteof, ebx
  303.         stdcall libini._.reload_block, [_f]
  304.         invoke  mem.free, [buf]
  305.         pop     ecx ebx
  306.   .skip:
  307.         ret
  308.  
  309.   .down:
  310.         neg     [_delta]
  311.  
  312.         mov     ebx, [_f]
  313.         mov     ecx, [ebx + IniFile.cnt]
  314.         mov     ebx, [ebx + IniFile.fh]
  315.         invoke  file.tell, ebx
  316.         sub     eax, ecx
  317.         lea     edx, [eax - 1]
  318.         push    edx
  319.     @@: invoke  file.seek, ebx, edx, SEEK_SET
  320.         invoke  file.eof?, ebx
  321.         or      eax, eax
  322.         jnz     @f
  323.         add     edx, ini.BLOCK_SIZE
  324.         jmp     @b
  325.     @@: cmp     edx, [esp]
  326.         je      .skip.2
  327.         add     edx, -ini.BLOCK_SIZE
  328.         cmp     edx, [esp]
  329.         jl      @f
  330.         invoke  file.seek, ebx, edx, SEEK_SET
  331.         invoke  file.read, ebx, [buf], ini.BLOCK_SIZE
  332.         mov     ecx, eax
  333.         mov     eax, [_delta]
  334.         sub     eax, ecx
  335.         invoke  file.seek, ebx, eax, SEEK_CUR
  336.         invoke  file.write, ebx, [buf], ecx
  337.         jmp     @b
  338.     @@:
  339.   .skip.2:
  340.         add     esp, 4
  341.         stdcall libini._.reload_block, [_f]
  342.         invoke  mem.free, [buf]
  343.         pop     ecx ebx
  344.         ret
  345. endp
  346.  
  347. ;;================================================================================================;;
  348. proc libini._.get_value_length _f ;///////////////////////////////////////////////////////////////;;
  349. ;;------------------------------------------------------------------------------------------------;;
  350. ;? --- TBD ---                                                                                    ;;
  351. ;;------------------------------------------------------------------------------------------------;;
  352. ;> --- TBD ---                                                                                    ;;
  353. ;;------------------------------------------------------------------------------------------------;;
  354. ;< --- TBD ---                                                                                    ;;
  355. ;;================================================================================================;;
  356.         push    ebx ecx edx eax
  357.         mov     ebx, [_f]
  358.         invoke  file.tell, [ebx + IniFile.fh]
  359.         push    esi [ebx + IniFile.cnt] [ebx + IniFile.pos]
  360.         sub     eax, [ebx + IniFile.cnt]
  361.         mov     edx, eax
  362.  
  363.         stdcall libini._.skip_line, [_f]
  364.         invoke  file.tell, [ebx + IniFile.fh]
  365.         sub     eax, [ebx + IniFile.cnt]
  366.         sub     eax, edx
  367.         mov     [esp + 4 * 3], eax
  368.  
  369.         pop     eax
  370.         invoke  file.seek, [ebx + IniFile.fh], eax, SEEK_SET
  371.         stdcall libini._.preload_block, [_f]
  372.         pop     [ebx + IniFile.cnt] esi
  373.         pop     eax edx ecx ebx
  374.         ret
  375. endp
  376.  
  377. ;;================================================================================================;;
  378. proc libini._.string_copy ;///////////////////////////////////////////////////////////////////////;;
  379. ;;------------------------------------------------------------------------------------------------;;
  380. ;? --- TBD ---                                                                                    ;;
  381. ;;------------------------------------------------------------------------------------------------;;
  382. ;> --- TBD ---                                                                                    ;;
  383. ;;------------------------------------------------------------------------------------------------;;
  384. ;< --- TBD ---                                                                                    ;;
  385. ;;================================================================================================;;
  386.     @@: lodsb
  387.         or      al, al
  388.         jz      @f
  389.         stosb
  390.         jmp     @b
  391.     @@: ret
  392. endp
  393.  
  394. ;;================================================================================================;;
  395. proc libini._.find_next_section _f ;//////////////////////////////////////////////////////////////;;
  396. ;;------------------------------------------------------------------------------------------------;;
  397. ;? --- TBD ---                                                                                    ;;
  398. ;;------------------------------------------------------------------------------------------------;;
  399. ;> --- TBD ---                                                                                    ;;
  400. ;;------------------------------------------------------------------------------------------------;;
  401. ;< --- TBD ---                                                                                    ;;
  402. ;;================================================================================================;;
  403.         push    ebx edi
  404.  
  405.     @@: stdcall libini._.skip_nonblanks, [_f]
  406.         cmp     al, '['
  407.         je      @f
  408.         or      al, al
  409.         jz      .exit_error
  410.         stdcall libini._.skip_line, [_f]
  411.         or      al, al
  412.         jz      .exit_error
  413.         jmp     @b
  414.     @@:
  415.         pop     edi ebx
  416.         xor     eax, eax
  417.         ret
  418.  
  419.   .exit_error:
  420.         pop     edi ebx
  421.         or      eax, -1
  422.         ret
  423. endp
  424.  
  425. ;;================================================================================================;;
  426. proc libini._.find_section _f, _sec_name ;////////////////////////////////////////////////////////;;
  427. ;;------------------------------------------------------------------------------------------------;;
  428. ;? Find section in file                                                                           ;;
  429. ;? Search is performed from the beginning of file                                                 ;;
  430. ;;------------------------------------------------------------------------------------------------;;
  431. ;> --- TBD ---                                                                                    ;;
  432. ;;------------------------------------------------------------------------------------------------;;
  433. ;< eax = -1 (fail) / 0 (ok)                                                                       ;;
  434. ;< [_f.pos] = new cursor position (right after ']' char if eax = 0, at the end of file otherwise) ;;
  435. ;;================================================================================================;;
  436.         push    ebx ecx edi
  437.  
  438.         mov     ecx, [_f]
  439.         invoke  file.seek, [ecx + IniFile.fh], 0, SEEK_SET
  440.         stdcall libini._.preload_block, [_f]
  441.  
  442.   .next_section:
  443.         stdcall libini._.find_next_section, [_f]
  444.         or      eax, eax
  445.         jnz     .exit_error
  446.  
  447.         stdcall libini._.get_char, [_f]
  448.         stdcall libini._.skip_spaces, [_f]
  449.         mov     edi, [_sec_name]
  450.     @@: stdcall libini._.get_char, [_f]
  451.         cmp     al, ']'
  452.         je      @f
  453.         or      al, al
  454.         jz      .exit_error
  455.         cmp     al, 13
  456.         je      .next_section
  457.         cmp     al, 10
  458.         je      .next_section
  459.         scasb
  460.         je      @b
  461.         cmp     byte[edi - 1], 0
  462.         jne     .next_section
  463.         dec     edi
  464.         stdcall libini._.unget_char, [_f]
  465.         stdcall libini._.skip_spaces, [_f]
  466.         stdcall libini._.get_char, [_f]
  467.         cmp     al, ']'
  468.         jne     .next_section
  469.     @@:
  470.         cmp     byte[edi], 0
  471.         jne     .next_section
  472.         pop     edi ecx ebx
  473.         xor     eax, eax
  474.         ret
  475.  
  476.   .exit_error:
  477.         pop     edi ecx ebx
  478.         or      eax, -1
  479.         ret
  480. endp
  481.  
  482. ;;================================================================================================;;
  483. proc libini._.find_key _f, _key_name ;////////////////////////////////////////////////////////////;;
  484. ;;------------------------------------------------------------------------------------------------;;
  485. ;? Find key in section                                                                            ;;
  486. ;? Search is performed within current section starting from cursor position                       ;;
  487. ;;------------------------------------------------------------------------------------------------;;
  488. ;> --- TBD ---                                                                                    ;;
  489. ;;------------------------------------------------------------------------------------------------;;
  490. ;< eax = -1 (fail) / 0 (ok)                                                                       ;;
  491. ;< [_f.pos] = new cursor position (right after '=' char if eax = 0, at the end of file or right   ;;
  492. ;<            before '[' char otherwise)                                                          ;;
  493. ;;================================================================================================;;
  494.         push    ebx edi
  495.  
  496.   .next_value:
  497.         mov     edi, [_key_name]
  498.         stdcall libini._.skip_line, [_f]
  499.         stdcall libini._.skip_nonblanks, [_f]
  500.         or      al, al
  501.         jz      .exit_error
  502.         cmp     al, '['
  503.         je      .exit_error
  504.     @@: stdcall libini._.get_char, [_f]
  505.         or      al, al
  506.         jz      .exit_error
  507.         cmp     al, '='
  508.         je      @f
  509.         scasb
  510.         je      @b
  511.         cmp     byte[edi - 1], 0
  512.         jne     .next_value
  513.         dec     edi
  514.         stdcall libini._.unget_char, [_f]
  515.         stdcall libini._.skip_spaces, [_f]
  516.         stdcall libini._.get_char, [_f]
  517.         cmp     al, '='
  518.         je      @f
  519.         jmp     .next_value
  520.     @@:
  521.         cmp     byte[edi], 0
  522.         jne     .next_value
  523.  
  524.         pop     edi ebx
  525.         xor     eax, eax
  526.         ret
  527.  
  528.   .exit_error:
  529.         pop     edi ebx
  530.         or      eax, -1
  531.         ret
  532. endp
  533.  
  534. ;;================================================================================================;;
  535. proc libini._.low.read_value _f_addr, _buffer, _buf_len ;/////////////////////////////////////////;;
  536. ;;------------------------------------------------------------------------------------------------;;
  537. ;? --- TBD ---                                                                                    ;;
  538. ;;------------------------------------------------------------------------------------------------;;
  539. ;> --- TBD ---                                                                                    ;;
  540. ;;------------------------------------------------------------------------------------------------;;
  541. ;< --- TBD ---                                                                                    ;;
  542. ;;================================================================================================;;
  543.         push    edi eax
  544.         mov     edi, [_buffer]
  545.         stdcall libini._.skip_spaces, [_f_addr]
  546.     @@: dec     [_buf_len]
  547.         jz      @f
  548.         stdcall libini._.get_char, [_f_addr]
  549.         cmp     al, 13
  550.         je      @f
  551.         cmp     al, 10
  552.         je      @f
  553.         stosb
  554.         or      al, al
  555.         jnz     @b
  556.     @@: stdcall libini._.unget_char, [_f_addr]
  557.         mov     byte[edi], 0
  558.         dec     edi
  559.     @@: cmp     edi, [_buffer]
  560.         jb      @f
  561.         cmp     byte[edi], 32
  562.         ja      @f
  563.         mov     byte[edi], 0
  564.         dec     edi
  565.         jmp     @b
  566.     @@: pop     eax edi
  567.         ret
  568. endp
  569.  
  570. ;;================================================================================================;;
  571. proc libini._.str_to_int ;////////////////////////////////////////////////////////////////////////;;
  572. ;;------------------------------------------------------------------------------------------------;;
  573. ;? --- TBD ---                                                                                    ;;
  574. ;;------------------------------------------------------------------------------------------------;;
  575. ;> esi = string buffer address                                                                    ;;
  576. ;;------------------------------------------------------------------------------------------------;;
  577. ;< eax = binary number representation (no overflow checks made)                                   ;;
  578. ;;================================================================================================;;
  579.         push    edx
  580.  
  581.         xor     eax, eax
  582.         xor     edx, edx
  583.  
  584.     @@: lodsb
  585.         cmp     al, '0'
  586.         jb      @f
  587.         cmp     al, '9'
  588.         ja      @f
  589.         add     eax, -'0'
  590.         imul    edx, 10
  591.         add     edx, eax
  592.         jmp     @b
  593.  
  594.     @@: dec     esi
  595.         mov     eax, edx
  596.         pop     edx
  597.         ret
  598. endp
  599.  
  600. ;;================================================================================================;;
  601. proc libini._.int_to_str ;////////////////////////////////////////////////////////////////////////;;
  602. ;;------------------------------------------------------------------------------------------------;;
  603. ;? --- TBD ---                                                                                    ;;
  604. ;;------------------------------------------------------------------------------------------------;;
  605. ;> eax = number to convert                                                                        ;;
  606. ;> ecx = base                                                                                     ;;
  607. ;> edi = string buffer address                                                                    ;;
  608. ;;------------------------------------------------------------------------------------------------;;
  609. ;< --- TBD ---                                                                                    ;;
  610. ;;================================================================================================;;
  611.         push    ecx edx
  612.  
  613.         or      eax, eax
  614.         jns     @f
  615.         mov     byte[edi], '-'
  616.         inc     edi
  617.     @@: call    .recurse
  618.         pop     edx ecx
  619.         ret
  620.  
  621.   .recurse:
  622.         cmp     eax,ecx
  623.         jb      @f
  624.         xor     edx,edx
  625.         div     ecx
  626.         push    edx
  627.         call    .recurse
  628.         pop     eax
  629.     @@: cmp     al,10
  630.         sbb     al,0x69
  631.         das
  632.         stosb
  633.         retn
  634. endp
  635.  
  636. ;;================================================================================================;;
  637. proc libini._.ascii_to_scan ;_ascii_code ;////////////////////////////////////////////////////////;;
  638. ;;------------------------------------------------------------------------------------------------;;
  639. ;? Translate ASCII code of key to scancode using standard mapping from keymap.key                 ;;
  640. ;;------------------------------------------------------------------------------------------------;;
  641. ;> _ascii_code = [esp+4] = ASCII code to convert                                                  ;;
  642. ;;------------------------------------------------------------------------------------------------;;
  643. ;< eax = 0 (error) / scancode (success)                                                           ;;
  644. ;;================================================================================================;;
  645. ; /sys/keymap.key
  646.         sub     esp, 256
  647.         mov     eax, esp
  648.         push    ebx
  649.         push    'key'
  650.         push    'map.'
  651.         push    '/key'
  652.         push    '/sys'
  653.         push    eax     ; buffer in the stack
  654.         push    0x100   ; read 0x100 bytes
  655.         push    0
  656.         push    0       ; from position zero
  657.         push    0       ; subfunction: read
  658.         mov     ebx, esp
  659.         push    70
  660.         pop     eax
  661.         mcall
  662.         add     esp, 36
  663.         pop     ebx
  664.         test    eax, eax
  665.         jnz     .die
  666.         mov     al, [esp+256+4] ; get ASCII code
  667.         push    edi
  668. ; first keytable - no modifiers pressed
  669. ; check scancodes from 1 to 36h (inclusive)
  670.         lea     edi, [esp+4+1]
  671.         mov     edx, edi
  672.         mov     ecx, 36h
  673.         repnz   scasb
  674.         jz      .found
  675. ; second keytable - Shift pressed
  676.         lea     edi, [esp+4+128+1]
  677.         mov     edx, edi
  678.         mov     ecx, 36h
  679.         repnz   scasb
  680.         jz      .found
  681.         pop     edi
  682. .die:
  683.         xor     eax, eax
  684.         jmp     .ret
  685. .found:
  686.         mov     eax, edi
  687.         sub     eax, edx
  688.         pop     edi
  689. .ret:
  690.         add     esp, 256
  691.         ret     4
  692. endp
  693.