Subversion Repositories Kolibri OS

Rev

Rev 485 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
;
2
;    TFTP Wave Player
3
;
4
;    Compile with FASM for Menuet
5
;
6
;
7
;    12.7.2002 - Audio system calls by VT
8
;
9
 
10
use32
331 heavyiron 11
 org	0x0
12
 db	'MENUET01'    ; header
13
 dd	0x01	      ; header version
14
 dd	START	      ; entry point
15
 dd	I_END	      ; image size
16
 dd	I_END+0x10000 ; required memory
17
 dd	I_END+0x10000 ; esp
18
 dd	0x0 , 0x0     ; I_Param , I_Path
31 halyavin 19
 
20
include 'lang.inc'
485 heavyiron 21
include '..\..\..\macros.inc'
31 halyavin 22
 
331 heavyiron 23
delay	   dd  145
31 halyavin 24
wait_for   dd  0x0
25
 
331 heavyiron 26
START:				; start of execution
31 halyavin 27
 
28
    mov  dword [prompt], p9
29
    mov  dword [promptlen], p9len - p9
485 heavyiron 30
 
31
red:
331 heavyiron 32
    call draw_window		; at first, draw the window
31 halyavin 33
 
34
still:
35
 
331 heavyiron 36
    mov  eax,10 		; wait here for event
485 heavyiron 37
    mcall
31 halyavin 38
 
331 heavyiron 39
    cmp  eax,1			; redraw request ?
40
    jz	 red
41
    cmp  eax,2			; key in buffer ?
42
    jz	 key
43
    cmp  eax,3			; button in buffer ?
44
    jz	 button
31 halyavin 45
 
46
    jmp  still
331 heavyiron 47
key:			       ; Keys are not valid at this part of the
48
    mov  eax,2			; loop. Just read it and ignore
485 heavyiron 49
    mcall
31 halyavin 50
    jmp  still
51
 
331 heavyiron 52
button: 		       ; button
53
    mov  eax,17 		; get id
485 heavyiron 54
    mcall
31 halyavin 55
 
331 heavyiron 56
    cmp  ah,1			; button id=1 ?
31 halyavin 57
    jnz  noclose
58
 
59
 
60
    ; close socket before exiting
61
 mov  eax, 53
62
 mov  ebx, 1
63
 mov  ecx, [socketNum]
485 heavyiron 64
    mcall
31 halyavin 65
 
66
 mov  [socketNum], dword 0
67
 
68
 
485 heavyiron 69
    or  eax,-1 	; close this program
70
    mcall
31 halyavin 71
 
72
noclose:
331 heavyiron 73
    cmp  ah,2			; copy file to local machine?
31 halyavin 74
    jnz  nocopyl
75
 
76
    mov   dword [prompt], p5
77
    mov  dword [promptlen], p5len - p5
331 heavyiron 78
    call  draw_window		 ;
31 halyavin 79
 
80
    ; Copy File from Remote Host to this machine
331 heavyiron 81
    call translateData	; Convert Filename & IP address
31 halyavin 82
    mov  edi, tftp_filename + 1
83
    mov  [edi], byte 0x01 ; setup tftp msg
84
    call copyFromRemote
85
 
86
    jmp  still
87
 
88
nocopyl:
89
 
90
 
91
    cmp  ah,4
331 heavyiron 92
    jz	 f1
31 halyavin 93
    cmp  ah,5
331 heavyiron 94
    jz	 f2
31 halyavin 95
    jmp  nof12
96
 
97
  f1:
98
    mov  [addr],dword source
99
    mov  [ya],dword 35
100
    jmp  rk
101
 
102
  f2:
103
    mov  [addr],dword destination
104
    mov  [ya],dword 35+16
105
 
106
  rk:
107
    mov  ecx,15
108
    mov  edi,[addr]
109
    mov  al,' '
110
    rep  stosb
111
 
112
    call print_text
113
 
114
    mov  edi,[addr]
115
 
116
  f11:
117
    mov  eax,10
485 heavyiron 118
    mcall
31 halyavin 119
    cmp  eax,2
331 heavyiron 120
    jz	 fbu
31 halyavin 121
    jmp  still
122
  fbu:
123
    mov  eax,2
485 heavyiron 124
    mcall  ; get key
31 halyavin 125
    shr  eax,8
126
    cmp  eax,8
127
    jnz  nobs
128
    cmp  edi,[addr]
331 heavyiron 129
    jz	 f11
31 halyavin 130
    sub  edi,1
131
    mov  [edi],byte ' '
132
    call print_text
133
    jmp  f11
134
  nobs:
135
    cmp  eax,dword 31
136
    jbe  f11
137
    cmp  eax,dword 95
331 heavyiron 138
    jb	 keyok
31 halyavin 139
    sub  eax,32
140
  keyok:
141
    mov  [edi],al
142
 
143
    call print_text
144
 
145
    add  edi,1
146
    mov  esi,[addr]
147
    add  esi,15
148
    cmp  esi,edi
149
    jnz  f11
150
 
151
    jmp  still
152
 
153
print_text:
154
 
155
    mov  eax,13
156
    mov  ebx,103*65536+15*6
157
    mov  ecx,[ya]
158
    shl  ecx,16
159
    mov  cx,8
160
    mov  edx,0x224466
485 heavyiron 161
    mcall
31 halyavin 162
 
163
    mov  eax,4
164
    mov  ebx,103*65536
165
    add  ebx,[ya]
166
    mov  ecx,0xffffff
167
    mov  edx,[addr]
168
    mov  esi,15
485 heavyiron 169
    mcall
31 halyavin 170
 
171
    ret
172
 
173
 
174
  nof12:
175
    jmp  still
176
 
177
 
178
;***************************************************************************
179
;   Function
180
;      translateData
181
;
182
;   Description
183
;      Coverts the filename and IP address typed in by the user into
184
;      a format suitable for the IP layer.
185
;
186
;    The filename, in source, is converted and stored in tftp_filename
187
;      The host ip, in destination, is converted and stored in tftp_IP
188
;
189
;***************************************************************************
190
translateData:
191
 
192
 ; first, build up the tftp command string. This includes the filename
193
 ; and the transfer protocol
194
 
195
 
196
 ; First, write 0,0
197
 mov  al, 0
198
 mov  edi, tftp_filename
199
 mov  [edi], al
200
 inc  edi
201
 mov  [edi], al
202
 inc  edi
203
 
204
 ; Now, write the file name itself, and null terminate it
205
 mov  ecx, 15
206
 mov  ah, ' '
207
 mov  esi, source
208
 
209
td001:
210
 lodsb
211
 stosb
212
 cmp  al, ah
213
 loopnz td001
214
 
215
 cmp  al,ah  ; Was the entire buffer full of characters?
216
 jne  td002
217
 dec  edi   ; No - so remove ' ' character
218
 
219
td002:
220
 mov  [edi], byte 0
221
 inc  edi
222
 mov  [edi], byte 'O'
223
 inc  edi
224
 mov  [edi], byte 'C'
225
 inc  edi
226
 mov  [edi], byte 'T'
227
 inc  edi
228
 mov  [edi], byte 'E'
229
 inc  edi
230
 mov  [edi], byte 'T'
231
 inc  edi
232
 mov  [edi], byte 0
233
 
234
 mov  esi, tftp_filename
235
 sub  edi, esi
236
 mov  [tftp_len], edi
237
 
238
 
239
 ; Now, convert the typed IP address into a real address
240
 ; No validation is done on the number entered
241
 ; ip addresses must be typed in normally, eg
242
 ; 192.1.45.24
243
 
244
 xor  eax, eax
245
 mov  dh, 10
246
 mov  dl, al
247
 mov  [tftp_IP], eax
248
 
249
 ; 192.168.24.1   1.1.1.1       1. 9.2.3.
250
 
251
 mov  esi, destination
252
 mov  edi, tftp_IP
253
 
254
 mov  ecx, 4
255
 
256
td003:
257
 lodsb
258
 sub  al, '0'
259
 add  dl, al
260
 lodsb
261
 cmp  al, '.'
262
 je  ipNext
263
 cmp  al, ' '
264
 je  ipNext
265
 mov  dh, al
266
 sub  dh, '0'
267
 mov  al, 10
268
 mul  dl
269
 add  al, dh
270
 mov  dl, al
271
 lodsb
272
 cmp  al, '.'
273
 je  ipNext
274
 cmp  al, ' '
275
 je  ipNext
276
 mov  dh, al
277
 sub  dh, '0'
278
 mov  al, 10
279
 mul  dl
280
 add  al, dh
281
 mov  dl, al
282
 lodsb
283
 
284
ipNext:
285
 mov  [edi], dl
286
 inc  edi
287
 mov  dl, 0
288
 loop td003
289
 
290
 ret
291
 
292
 
293
 
294
;***************************************************************************
295
;   Function
296
;      copyFromRemote
297
;
298
;   Description
299
;
300
;***************************************************************************
301
copyFromRemote:
302
 
303
 mov  eax,0x20000-512
304
 mov  [fileposition], eax
305
 
306
 ; Get a random # for the local socket port #
307
 mov  eax, 3
485 heavyiron 308
 mcall
31 halyavin 309
 mov  ecx, eax
331 heavyiron 310
 shr  ecx, 8	; Set up the local port # with a random #
31 halyavin 311
 
312
   ; open socket
313
 mov  eax, 53
314
 mov  ebx, 0
331 heavyiron 315
 mov  edx, 69	 ; remote port
31 halyavin 316
 mov  esi, [tftp_IP]  ; remote IP ( in intenet format )
485 heavyiron 317
 mcall
31 halyavin 318
 
319
 mov  [socketNum], eax
320
 
321
 ; make sure there is no data in the socket - there shouldn't be..
322
 
323
cfr001:
324
 mov  eax, 53
325
 mov  ebx, 3
326
 mov  ecx, [socketNum]
485 heavyiron 327
 mcall    ; read byte
31 halyavin 328
 
329
 mov  eax, 53
330
 mov  ebx, 2
331
 mov  ecx, [socketNum]
485 heavyiron 332
 mcall    ; any more data?
31 halyavin 333
 
334
 cmp  eax, 0
331 heavyiron 335
 jne  cfr001	; yes, so get it
31 halyavin 336
 
337
 ; Now, request the file
338
 mov  eax, 53
339
 mov  ebx, 4
340
 mov  ecx, [socketNum]
341
 mov  edx, [tftp_len]
342
 mov  esi, tftp_filename
485 heavyiron 343
 mcall
31 halyavin 344
 
345
cfr002:
346
 
331 heavyiron 347
    mov  eax,23 		; wait here for event
348
    mov  ebx,1			; Time out after 10ms
485 heavyiron 349
    mcall
31 halyavin 350
 
331 heavyiron 351
    cmp  eax,1			; redraw request ?
352
    je	 cfr003
353
    cmp  eax,2			; key in buffer ?
354
    je	 cfr004
355
    cmp  eax,3			; button in buffer ?
356
    je	 cfr005
31 halyavin 357
 
358
    ; Any data to fetch?
359
 mov  eax, 53
360
 mov  ebx, 2
361
 mov  ecx, [socketNum]
485 heavyiron 362
 mcall
31 halyavin 363
 
364
 cmp  eax, 0
365
 je  cfr002
366
 
367
 push eax     ; eax holds # chars
368
 
369
 ; Update the text on the display - once
370
 mov  eax, [prompt]
371
 cmp  eax, p3
372
 je  cfr008
373
 mov   dword [prompt], p3
374
 mov  dword [promptlen], p3len - p3
331 heavyiron 375
 call  draw_window	      ;
31 halyavin 376
 
377
cfr008:
378
 ; we have data - this will be a tftp frame
379
 
380
 ; read first two bytes - opcode
381
 mov  eax, 53
382
 mov  ebx, 3
383
 mov  ecx, [socketNum]
485 heavyiron 384
 mcall   ; read byte
31 halyavin 385
 
386
 mov  eax, 53
387
 mov  ebx, 3
388
 mov  ecx, [socketNum]
485 heavyiron 389
 mcall   ; read byte
31 halyavin 390
 
391
 pop  eax
392
 ; bl holds tftp opcode. Can only be 3 (data) or 5 ( error )
393
 
394
 cmp  bl, 3
395
 jne  cfrerr
396
 
397
 push eax
398
 
399
 ; do data stuff. Read block #. Read data. Send Ack.
400
 mov  eax, 53
401
 mov  ebx, 3
402
 mov  ecx, [socketNum]
485 heavyiron 403
 mcall   ; read byte
31 halyavin 404
 
405
 mov  [blockNumber], bl
406
 
407
 mov  eax, 53
408
 mov  ebx, 3
409
 mov  ecx, [socketNum]
485 heavyiron 410
 mcall   ; read byte
31 halyavin 411
 
412
 mov  [blockNumber+1], bl
413
 
414
cfr007:
415
 mov  eax, 53
416
 mov  ebx, 3
417
 mov  ecx, [socketNum]
485 heavyiron 418
 mcall   ; read byte
31 halyavin 419
 
420
 mov  esi, [fileposition]
421
 mov  [esi], bl
422
 mov  [esi+1],bl
423
 add  dword [fileposition],2
424
 
425
 mov  eax, 53
426
 mov  ebx, 2
427
 mov  ecx, [socketNum]
485 heavyiron 428
 mcall   ; any more data?
31 halyavin 429
 
430
 cmp  eax, 0
431
 jne  cfr007  ; yes, so get it
432
 
433
 cmp  [fileposition],0x20000+0xffff
434
 jb   get_more_stream
435
 
436
wait_more:
437
 
438
 mov  eax,5    ; wait for correct timer position
331 heavyiron 439
	       ; to trigger new play block
31 halyavin 440
 mov  ebx,1
485 heavyiron 441
 mcall
31 halyavin 442
 
443
 mov  eax,26
444
 mov  ebx,9
485 heavyiron 445
 mcall
31 halyavin 446
 
447
 cmp  eax,[wait_for]
448
 jb   wait_more
449
 
450
 add  eax,[delay]
451
 mov  [wait_for],eax
452
 
453
 mov  esi,0x20000
454
 mov  edi,0x10000
455
 mov  ecx,65536
456
 cld
457
 rep  movsb
458
 
459
 mov  eax,55
460
 mov  ebx,0
461
 mov  ecx,0x10000
485 heavyiron 462
 mcall
31 halyavin 463
 
464
 mov  eax,55
465
 mov  ebx,1
485 heavyiron 466
 mcall
31 halyavin 467
 
468
 mov  [fileposition],0x20000
469
 
470
get_more_stream:
471
 
472
 ; write the block number into the ack
473
 mov  al, [blockNumber]
474
 mov  [ack + 2], al
475
 
476
 mov  al, [blockNumber+1]
477
 mov  [ack + 3], al
478
 
479
 ; send an 'ack'
480
 mov  eax, 53
481
 mov  ebx, 4
482
 mov  ecx, [socketNum]
483
 mov  edx, ackLen - ack
484
 mov  esi, ack
485 heavyiron 485
 mcall
31 halyavin 486
 
487
 ; If # of chars in the frame is less that 516,
488
 ; this frame is the last
489
 pop  eax
490
 cmp  eax, 516
491
 je  cfr002
492
 
493
 ; Write the file
494
 mov  eax, 33
495
 mov  ebx, source
496
 mov  edx, [filesize]
497
 mov  ecx, I_END + 512
498
 mov  esi, 0
485 heavyiron 499
 mcall
31 halyavin 500
 
501
 jmp  cfrexit
502
 
503
cfrerr:
504
 ; simple implementation on error - just read all data, and return
505
 mov  eax, 53
506
 mov  ebx, 3
507
 mov  ecx, [socketNum]
485 heavyiron 508
    mcall	  ; read byte
31 halyavin 509
 
510
 mov  eax, 53
511
 mov  ebx, 2
512
 mov  ecx, [socketNum]
485 heavyiron 513
    mcall	  ; any more data?
31 halyavin 514
 
515
 cmp  eax, 0
331 heavyiron 516
 jne  cfrerr	; yes, so get it
31 halyavin 517
 
331 heavyiron 518
 jmp  cfr006	; close socket and close app
31 halyavin 519
 
331 heavyiron 520
cfr003: 			; redraw request
31 halyavin 521
    call draw_window
522
    jmp  cfr002
523
 
331 heavyiron 524
cfr004: 			; key pressed
525
    mov  eax,2			; just read it and ignore
485 heavyiron 526
    mcall
31 halyavin 527
    jmp  cfr002
528
 
331 heavyiron 529
cfr005: 		       ; button
530
    mov  eax,17 		; get id
485 heavyiron 531
    mcall
31 halyavin 532
 
331 heavyiron 533
    cmp  ah,1			; button id=1 ?
31 halyavin 534
    jne  cfr002     ; If not, ignore.
535
 
536
cfr006:
537
    ; close socket
538
 mov  eax, 53
539
 mov  ebx, 1
540
 mov  ecx, [socketNum]
485 heavyiron 541
    mcall
31 halyavin 542
 
543
 mov  [socketNum], dword 0
544
 
331 heavyiron 545
    mov  eax,-1 		; close this program
485 heavyiron 546
    mcall
31 halyavin 547
 
548
    jmp $
549
 
550
cfrexit:
551
    ; close socket
552
 mov  eax, 53
553
 mov  ebx, 1
554
 mov  ecx, [socketNum]
485 heavyiron 555
    mcall
31 halyavin 556
 
557
 mov  [socketNum], dword 0
558
 
559
    mov   dword [prompt], p4
560
    mov  dword [promptlen], p4len - p4
331 heavyiron 561
    call  draw_window		 ;
31 halyavin 562
 
563
 ret
564
 
565
 
566
 
567
 
568
;   *********************************************
569
;   *******  WINDOW DEFINITIONS AND DRAW ********
570
;   *********************************************
571
 
572
 
573
draw_window:
574
 
331 heavyiron 575
    mov  eax,12 		   ; function 12:tell os about windowdraw
576
    mov  ebx,1			   ; 1, start of draw
485 heavyiron 577
    mcall
31 halyavin 578
 
331 heavyiron 579
				   ; DRAW WINDOW
580
    mov  eax,0			   ; function 0 : define and draw window
581
    mov  ebx,100*65536+230	   ; [x start] *65536 + [x size]
582
    mov  ecx,100*65536+170	   ; [y start] *65536 + [y size]
551 spraid 583
    mov  edx,0x14224466 	   ; color of work area RRGGBB
485 heavyiron 584
    mov  edi,title
585
    mcall
31 halyavin 586
 
331 heavyiron 587
    mov  eax,8		    ; DELETE BUTTON
31 halyavin 588
    mov  ebx,20*65536+190
589
    mov  ecx,111*65536+15
590
    mov  edx,2
591
    mov  esi,0x557799
485 heavyiron 592
    mcall
31 halyavin 593
 
594
    mov  ebx,200*65536+10
595
    mov  ecx,34*65536+10
596
    mov  edx,4
485 heavyiron 597
    mcall
31 halyavin 598
 
599
    mov  ecx,50*65536+10
600
    mov  edx,5
485 heavyiron 601
    mcall
31 halyavin 602
 
603
 
604
 ; Copy the file name to the screen buffer
605
 ; file name is same length as IP address, to
606
 ; make the math easier later.
607
    cld
608
    mov  esi,source
609
    mov  edi,text+13
610
    mov  ecx,15
611
    rep  movsb
612
 
613
 
614
 ; copy the IP address to the screen buffer
615
    mov  esi,destination
616
    mov  edi,text+40+13
617
    mov  ecx,15
618
    rep  movsb
619
 
620
  ; copy the prompt to the screen buffer
621
    mov  esi,[prompt]
622
    mov  edi,text+280
623
    mov  ecx,[promptlen]
624
    rep  movsb
625
 
626
    ; Re-draw the screen text
627
    cld
485 heavyiron 628
    mov  eax,4
331 heavyiron 629
    mov  ebx,25*65536+35	   ; draw info text with function 4
31 halyavin 630
    mov  ecx,0xffffff
631
    mov  edx,text
632
    mov  esi,40
633
  newline:
485 heavyiron 634
    mcall
31 halyavin 635
    add  ebx,16
636
    add  edx,40
637
    cmp  [edx],byte 'x'
638
    jnz  newline
639
 
640
 
331 heavyiron 641
    mov  eax,12 		   ; function 12:tell os about windowdraw
642
    mov  ebx,2			   ; 2, end of draw
485 heavyiron 643
    mcall
31 halyavin 644
 
645
    ret
646
 
647
 
648
; DATA AREA
649
 
331 heavyiron 650
source	     db  'HEAT8M22.WAV   '
31 halyavin 651
destination  db  '192.168.1.24   '
652
 
653
 
331 heavyiron 654
tftp_filename:	times 15 + 9 db 0
31 halyavin 655
tftp_IP:   dd 0
656
tftp_len:   dd 0
657
 
658
addr  dd  0x0
659
ya    dd  0x0
660
 
661
fileposition dd 0 ; Points to the current point in the file
662
filesize  dd 0 ; The number of bytes written / left to write
663
fileblocksize dw 0 ; The number of bytes to send in this frame
664
 
665
text:
666
    db 'SOURCE FILE: xxxxxxxxxxxxxxx            '
667
    db 'HOST IP ADD: xxx.xxx.xxx.xxx            '
668
    db '                                        '
669
    db 'WAVE FORMAT: 8 BIT,MONO,22050HZ         '
670
    db '                                        '
671
    db '     SERVER -> PLAY FILE                '
672
    db '                                        '
673
    db '                                        '
331 heavyiron 674
    db 'x' ; <- END MARKER, DONT DELETE
31 halyavin 675
 
676
 
485 heavyiron 677
title	db   'TFTP Wave Player',0
31 halyavin 678
 
679
prompt: dd 0
680
promptlen: dd 0
681
 
682
 
683
p1:  db 'Waiting for Command '
684
p1len:
685
 
686
p9:  db 'Define SB with setup'
687
p9len:
688
 
689
p2:  db 'Sending File        '
690
p2len:
691
 
692
p3:  db 'Playing File        '
693
p3len:
694
 
695
p4:  db 'Complete            '
696
p4len:
697
 
698
p5:  db 'Contacting Host...  '
699
p5len:
700
 
701
p6:  db 'File not found.     '
702
p6len:
703
 
704
ack:
705
 db 00,04,0,1
706
ackLen:
707
 
708
socketNum:
709
 dd 0
710
 
711
blockNumber:
712
 dw 0
713
 
714
; This must be the last part of the file, because the blockBuffer
715
; continues at I_END.
716
blockBuffer:
717
 db 00, 03, 00, 01
718
I_END:
719