Subversion Repositories Kolibri OS

Rev

Rev 1568 | Go to most recent revision | 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
;;================================================================================================;;
1573 IgorA 84
	push ecx
845 mikedld 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
1573 IgorA 91
	pop ecx
845 mikedld 92
	ret
93
endp
94
 
95
;;================================================================================================;;
96
proc libini._.skip_nonblanks _f ;/////////////////////////////////////////////////////////////////;;
97
;;------------------------------------------------------------------------------------------------;;
98
;? --- TBD ---                                                                                    ;;
99
;;------------------------------------------------------------------------------------------------;;
100
;> --- TBD ---                                                                                    ;;
101
;;------------------------------------------------------------------------------------------------;;
102
;< --- TBD ---                                                                                    ;;
103
;;================================================================================================;;
1573 IgorA 104
	push ecx
845 mikedld 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
1048 mikedld 115
	cmp	al, ini.COMMENT_CHAR
116
	jne	@f
117
	stdcall libini._.skip_line, [_f]
118
	jmp	@b
845 mikedld 119
    @@: stdcall libini._.unget_char, [_f]
1573 IgorA 120
	pop ecx
845 mikedld 121
	ret
122
endp
123
 
124
;;================================================================================================;;
125
proc libini._.skip_spaces _f ;////////////////////////////////////////////////////////////////////;;
126
;;------------------------------------------------------------------------------------------------;;
127
;? --- TBD ---                                                                                    ;;
128
;;------------------------------------------------------------------------------------------------;;
129
;> --- TBD ---                                                                                    ;;
130
;;------------------------------------------------------------------------------------------------;;
131
;< --- TBD ---                                                                                    ;;
132
;;================================================================================================;;
1573 IgorA 133
	push ecx
845 mikedld 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]
1573 IgorA 141
	pop ecx
845 mikedld 142
	ret
143
endp
144
 
145
;;================================================================================================;;
146
proc libini._.skip_line _f ;//////////////////////////////////////////////////////////////////////;;
147
;;------------------------------------------------------------------------------------------------;;
148
;? --- TBD ---                                                                                    ;;
149
;;------------------------------------------------------------------------------------------------;;
150
;> --- TBD ---                                                                                    ;;
151
;;------------------------------------------------------------------------------------------------;;
152
;< --- TBD ---                                                                                    ;;
153
;;================================================================================================;;
1573 IgorA 154
	push ecx
845 mikedld 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]
1573 IgorA 164
	pop ecx
845 mikedld 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
919 mikedld 181
	invoke	file.seek, [ebx + IniFile.fh], eax, SEEK_SET
845 mikedld 182
	stdcall libini._.preload_block, ebx
1048 mikedld 183
	add	esi, eax
845 mikedld 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
1048 mikedld 213
    @@: mov	[ebx + IniFile.cnt], eax
845 mikedld 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]
919 mikedld 232
	invoke	file.seek, [ebx + IniFile.fh], [ebx + IniFile.pos], SEEK_SET
845 mikedld 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
919 mikedld 278
	invoke	file.seek, ebx, eax, SEEK_SET
279
    @@: invoke	file.seek, ebx, [_delta], SEEK_CUR
845 mikedld 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
1048 mikedld 287
	sub	eax, ecx
919 mikedld 288
	invoke	file.seek, ebx, eax, SEEK_CUR
1568 diamond 289
	push	ecx
1048 mikedld 290
	invoke	file.write, ebx, [buf], ecx
1568 diamond 291
	pop	ecx
292
	cmp	eax, ecx
293
	jz	@b
294
  .fail:
295
	or	eax, -1
296
	pop	ecx ebx
297
	ret
845 mikedld 298
  .done:
299
	mov	eax, [_delta]
300
	neg	eax
919 mikedld 301
	invoke	file.seek, ebx, eax, SEEK_CUR
845 mikedld 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
919 mikedld 319
    @@: invoke	file.seek, ebx, edx, SEEK_SET
845 mikedld 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
919 mikedld 330
	invoke	file.seek, ebx, edx, SEEK_SET
845 mikedld 331
	invoke	file.read, ebx, [buf], ini.BLOCK_SIZE
332
	mov	ecx, eax
333
	mov	eax, [_delta]
334
	sub	eax, ecx
919 mikedld 335
	invoke	file.seek, ebx, eax, SEEK_CUR
845 mikedld 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
 
919 mikedld 369
	pop	eax
370
	invoke	file.seek, [ebx + IniFile.fh], eax, SEEK_SET
845 mikedld 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
;;================================================================================================;;
1573 IgorA 436
	push	ebx ecx edi
845 mikedld 437
 
438
	mov	ecx, [_f]
919 mikedld 439
	invoke	file.seek, [ecx + IniFile.fh], 0, SEEK_SET
845 mikedld 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
1573 IgorA 472
	pop	edi ecx ebx
845 mikedld 473
	xor	eax, eax
474
	ret
475
 
476
  .exit_error:
1573 IgorA 477
	pop	edi ecx ebx
845 mikedld 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
1048 mikedld 559
    @@: cmp	edi, [_buffer]
560
	jb	@f
561
	cmp	byte[edi], 32
845 mikedld 562
	ja	@f
563
	mov	byte[edi], 0
564
	dec	edi
1048 mikedld 565
	jmp	@b
845 mikedld 566
    @@: pop	eax edi
567
	ret
568
endp
988 mikedld 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
1327 diamond 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