Subversion Repositories Kolibri OS

Rev

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