Subversion Repositories Kolibri OS

Rev

Rev 1573 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
845 mikedld 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 ;;
1001 diamond 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.                                         ;;
845 mikedld 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  ;;
1001 diamond 13
;; Lesser General Public License for more details.                                                ;;
845 mikedld 14
;;                                                                                                ;;
1001 diamond 15
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev.  ;;
16
;; If not, see .                                                    ;;
845 mikedld 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                                                    ;;
31
;> ebx = memory freeing routine                                                        ;;
32
;> ecx = memory reallocation routine                                                ;;
33
;> edx = library loading routine                                                       ;;
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]
1048 mikedld 71
    @@: pop	ecx eax
845 mikedld 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
1048 mikedld 112
	cmp	al, ini.COMMENT_CHAR
113
	jne	@f
114
	stdcall libini._.skip_line, [_f]
115
	jmp	@b
845 mikedld 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
919 mikedld 173
	invoke	file.seek, [ebx + IniFile.fh], eax, SEEK_SET
845 mikedld 174
	stdcall libini._.preload_block, ebx
1048 mikedld 175
	add	esi, eax
845 mikedld 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
1048 mikedld 205
    @@: mov	[ebx + IniFile.cnt], eax
845 mikedld 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]
919 mikedld 224
	invoke	file.seek, [ebx + IniFile.fh], [ebx + IniFile.pos], SEEK_SET
845 mikedld 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
919 mikedld 270
	invoke	file.seek, ebx, eax, SEEK_SET
271
    @@: invoke	file.seek, ebx, [_delta], SEEK_CUR
845 mikedld 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
1048 mikedld 279
	sub	eax, ecx
919 mikedld 280
	invoke	file.seek, ebx, eax, SEEK_CUR
1568 diamond 281
	push	ecx
1048 mikedld 282
	invoke	file.write, ebx, [buf], ecx
1568 diamond 283
	pop	ecx
284
	cmp	eax, ecx
285
	jz	@b
286
  .fail:
287
	or	eax, -1
288
	pop	ecx ebx
289
	ret
845 mikedld 290
  .done:
291
	mov	eax, [_delta]
292
	neg	eax
919 mikedld 293
	invoke	file.seek, ebx, eax, SEEK_CUR
845 mikedld 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
919 mikedld 311
    @@: invoke	file.seek, ebx, edx, SEEK_SET
845 mikedld 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
919 mikedld 322
	invoke	file.seek, ebx, edx, SEEK_SET
845 mikedld 323
	invoke	file.read, ebx, [buf], ini.BLOCK_SIZE
324
	mov	ecx, eax
325
	mov	eax, [_delta]
326
	sub	eax, ecx
919 mikedld 327
	invoke	file.seek, ebx, eax, SEEK_CUR
845 mikedld 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
 
919 mikedld 361
	pop	eax
362
	invoke	file.seek, [ebx + IniFile.fh], eax, SEEK_SET
845 mikedld 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
;;================================================================================================;;
1574 diamond 428
	push	ebx edi
845 mikedld 429
 
430
	mov	ecx, [_f]
919 mikedld 431
	invoke	file.seek, [ecx + IniFile.fh], 0, SEEK_SET
845 mikedld 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
1574 diamond 464
	pop	edi ebx
845 mikedld 465
	xor	eax, eax
466
	ret
467
 
468
  .exit_error:
1574 diamond 469
	pop	edi ebx
845 mikedld 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
1048 mikedld 551
    @@: cmp	edi, [_buffer]
552
	jb	@f
553
	cmp	byte[edi], 32
845 mikedld 554
	ja	@f
555
	mov	byte[edi], 0
556
	dec	edi
1048 mikedld 557
	jmp	@b
845 mikedld 558
    @@: pop	eax edi
559
	ret
560
endp
988 mikedld 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
1327 diamond 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