kolibrios-fun/programs/mp3s/trunk/mp3s.asm
Andrey Halyavin (halyavin) 065b8d32b2 programs sources added
git-svn-id: svn://kolibrios.org@31 a494cfbc-eb01-0410-851d-a64ba20cac60
2006-01-03 09:43:31 +00:00

792 lines
12 KiB
NASM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Tiny MP3 Shoutcast Server v0.1 (vt) ;
; ;
; Compile with FASM for Menuet ;
; ;
; Listening to port 8008 ;
; Connect with eg: 192.168.1.22:8008 ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
version equ '0.3'
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; program start
dd I_END ; program image size
dd 0x80000 ; memory usage
dd 0x20000 ; stack
dd 0,0
include 'lang.inc'
include 'macros.inc'
; 0x0+ program image
; 0x1ffff stack
; 0x20000 work area for file read
; 0x40000+ file send buffer ( 100 kb )
START: ; start of execution
mov [status],0
call clear_input
call draw_window ; at first, draw the window
still:
mov eax,23 ; wait here for event
mov ebx,2
int 0x40
call check_events
call check_connection_status
cmp [status],4
je start_transmission
jmp still
check_events:
cmp eax,1 ; redraw request ?
jz red
cmp eax,2 ; key in buffer ?
jz key
cmp eax,3 ; button in buffer ?
jz button
ret
red: ; redraw
call draw_window
ret
key:
mov eax,2 ; Just read it and ignore
int 0x40
ret
button: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; close
jne no_close
mov eax,-1
int 0x40
no_close:
cmp ah,2 ; button id=2 ?
jnz tst3
; open socket
mov eax,53
mov ebx,5
mov ecx,8008 ; local port # - http
mov edx,0 ; no remote port specified
mov esi,0 ; no remote ip specified
mov edi,0 ; PASSIVE open
int 0x40
mov [socket], eax
mov [posy],1
mov [posx],0
mov [read_on],1
call check_for_incoming_data
call draw_window
ret
tst3:
cmp ah,4
je close_socket
cmp ah,6
je close_socket
jmp no_socket_close
close_socket:
mov edx,eax
; Close socket
mov eax, 53
mov ebx, 8
mov ecx, [socket]
int 0x40
mov esp,0x1fff0
cmp dh,6
je read_string
jmp still
no_socket_close:
cmp ah,9
jne no_bps_add
add [bps],8*1000
call draw_window
ret
no_bps_add:
cmp ah,8
jne no_bps_sub
sub [bps],8*1000
call draw_window
ret
no_bps_sub:
ret
clear_input:
mov edi,input_text
mov eax,0
mov ecx,60*40
cld
rep stosb
ret
read_string:
mov [addr],dword filename
mov [ya],dword 95
mov edi,[addr]
mov eax,32
mov ecx,30
cld
rep stosb
call print_text
mov edi,[addr]
f11:
mov eax,10
int 0x40
cmp eax,2
jne read_done
mov eax,2
int 0x40
shr eax,8
cmp eax,13
je read_done
cmp eax,8
jnz nobsl
cmp edi,[addr]
jz f11
sub edi,1
mov [edi],byte 32
call print_text
jmp f11
nobsl:
cmp eax,dword 31
jbe f11
cmp eax,dword 95
jb keyok
sub eax,32
keyok:
mov [edi],al
call print_text
add edi,1
mov esi,[addr]
add esi,30
cmp esi,edi
jnz f11
read_done:
mov ecx,40
mov eax,0
cld
rep movsb
call print_text
jmp still
print_text:
pusha
mov eax,13
mov ebx,56*65536+30*6
mov ecx,[ya]
shl ecx,16
mov cx,8
mov edx,0xffffff
int 0x40
mov eax,4
mov edx,[addr]
mov ebx,56*65536
add ebx,[ya]
mov ecx,0x000000
mov esi,30
int 0x40
popa
ret
wait_for dd 0x0
transmission_start dd 0x0
sentbytes dd 0x0
start_transmission:
call clear_input
mov eax,5
mov ebx,50
int 0x40
call check_for_incoming_data
call draw_window
call send_header
mov [fileinfo+4],dword 0 ; start from beginning
mov [read_to],0x40000
mov [playpos],0x40000
mov ecx,1024 / 512
new_buffer:
mov eax,[read_to]
mov ebx,1
call read_file
loop new_buffer
newpart:
call check_connection_status
call draw_window
mov eax,26
mov ebx,9
int 0x40
mov [transmission_start],eax
mov [sentbytes],0
newblock:
mov eax,[read_to]
mov ebx,2
call read_file
wait_more:
mov eax,26
mov ebx,9
int 0x40
cmp eax,[wait_for]
jge nomw
mov eax,5
mov ebx,1
int 0x40
jmp wait_more
nomw:
add eax,2
mov [wait_for],eax
mov eax,11
int 0x40
call check_events
mov eax,53
mov ebx,255
mov ecx,103
int 0x40
cmp eax,0
jne wait_more
; write to socket
mov eax,53
mov ebx,7
mov ecx,[socket]
mov edx,[playadd]
mov esi,[playpos]
int 0x40
add [sentbytes],edx
mov esi,[playpos]
add esi,[playadd]
mov edi,0x40000
mov ecx,110000 / 4
cld
rep movsd
mov eax,[playadd]
sub [read_to],eax
call check_for_incoming_data
call show_progress
call check_rate
mov eax, 53
mov ebx, 6
mov ecx, [socket]
int 0x40
cmp eax,4
jne end_stream
cmp [read_to],0x40000
jge newblock
end_stream:
; Close socket
mov eax, 53
mov ebx, 8
mov ecx, [socket]
int 0x40
mov eax,5
mov ebx,5
int 0x40
; Open socket
mov eax,53
mov ebx,5
mov ecx,8008 ; local port # - http
mov edx,0 ; no remote port specified
mov esi,0 ; no remote ip specified
mov edi,0 ; PASSIVE open
int 0x40
mov [socket], eax
mov [posy],1
mov [posx],0
mov [read_on],0
call draw_window
jmp still
check_rate:
pusha
mov eax,[bps]
xor edx,edx
mov ebx,8*100
div ebx
shl eax,1
mov [playadd],eax
mov eax,26
mov ebx,9
int 0x40
sub eax,[transmission_start]
shr eax,1
imul eax,[playadd]
mov edx,0x00dd00
cmp [sentbytes],eax
jge sendok
sub eax,20000
cmp [sentbytes],eax ; a long buffer underrun correction
jge no_buffer_overrun ; actually leads to overrun
mov [sentbytes],eax
no_buffer_overrun:
add [playadd],150
mov edx,0xdd0000
sendok:
mov eax,13
mov ebx,320*65536+10
mov ecx,105*65536+10
int 0x40
mov eax,47
mov ebx,4*65536
mov ecx,[playadd]
mov edx,322*65536+106
mov esi,0x000000
; int 0x40
popa
ret
show_progress:
pusha
mov eax,13
mov ebx,236*65536+10*6
mov ecx,107*65536+8
mov edx,0xffffff
int 0x40
mov ecx,[fileinfo+4]
imul ecx,512
mov eax,47 ; file read
mov ebx,9*65536
mov edx,236*65536+107
mov esi,0x000000
int 0x40
popa
ret
playpos dd 0x100000
playadd dd 256000 / 8 / 100
send_header:
pusha
mov [playpos],0x40000
mov esi,fileinfo+5*4
mov edi,transname
mov ecx,30
cld
rep movsb
mov eax, 53
mov ebx, 7
mov ecx, [socket]
mov edx, headere-headers
mov esi, headers
int 0x40
popa
ret
read_file:
cmp [read_to],0x40000+2000
jg cache_ok
mov [read_on],1
cache_ok:
cmp [read_to],0x40000+95500
jg no_read_1
mov [fileinfo+12],eax
mov [fileinfo+8],ebx
mov eax,58
mov ebx,fileinfo
int 0x40
cmp eax,0
jne no_read_1
mov eax,[fileinfo+8]
add [fileinfo+4],eax
add [read_to],512*2
ret
no_read_1:
mov [read_on],0
ret
check_for_incoming_data:
pusha
mov eax, 53
mov ebx, 2
mov ecx, [socket]
int 0x40
cmp eax,0
je _ret_now
new_data:
mov eax, 53
mov ebx, 2
mov ecx, [socket]
int 0x40
cmp eax,0
je _ret
mov eax,53
mov ebx,3
mov ecx,[socket]
int 0x40
cmp bl,10
jne no_lf
inc [posy]
mov [posx],0
jmp new_data
no_lf:
cmp bl,20
jb new_data
inc [posx]
cmp [posx],60
jbe xok
inc [posy]
mov [posx],0
xok:
cmp [posy],12
jbe yok
mov [posy],1
yok:
mov eax,[posy]
imul eax,60
add eax,[posx]
mov [input_text+eax],bl
jmp new_data
_ret:
; call draw_window
_ret_now:
popa
ret
check_connection_status:
pusha
mov eax, 53
mov ebx, 6
mov ecx, [socket]
int 0x40
cmp eax,[status]
je .ccs_ret
mov [status],eax
add eax,48
mov [text+20],al
call draw_window
.ccs_ret:
popa
ret
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
draw_window:
pusha
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,1 ; 1, start of draw
int 0x40
mov eax,0 ; Draw Window
mov ebx,50*65536+410
mov ecx,100*65536+141
mov edx,0x03ffffff
mov esi,0x00405080
mov edi,0x00405080
int 0x40
mov eax,4 ; Window label
mov ebx,8*65536+8
mov ecx,0x10ffffff
mov edx,wls
mov esi,wle-wls
int 0x40
mov eax,8 ; Start server
mov ebx,(25)*65536+21
mov ecx,57*65536+10
mov edx,2
mov esi,0x409040
int 0x40 ; Stop server
mov eax,8
mov ebx,(25)*65536+21
mov ecx,69*65536+10
mov edx,4
mov esi,0x904040
int 0x40
mov esi,0x3366d0
mov eax,8 ; Enter filename
mov ebx,(25)*65536+21
mov ecx,93*65536+10
mov edx,6
int 0x40
mov eax,8 ; Decrease transfer rate
mov ebx,(25)*65536+10
mov ecx,105*65536+10
mov edx,8
int 0x40
mov eax,8 ; Increase transfer rate
mov ebx,(36)*65536+10
mov ecx,105*65536+10
mov edx,9
int 0x40
mov ebx,10*65536+35 ; draw info text
mov ecx,0x00000000
mov edx,text
mov esi,40
newline:
mov eax,4
int 0x40
add ebx,12
add edx,40
cmp [edx],byte 'x'
jnz newline
mov eax,4 ; Filename
mov ebx,56*65536+95
mov ecx,0x000000
mov edx,filename
mov esi,30
int 0x40
mov eax,[bps]
xor edx,edx
mov ebx,1000
div ebx
mov ecx,eax
mov eax,47
mov ebx,3*65536
mov edx,58*65536+107
mov esi,0x00000000
int 0x40
mov [input_text+0],dword 'RECE'
mov [input_text+4],dword 'IVED'
mov [input_text+8],dword ': '
mov ebx,230*65536+35 ; draw info text
mov ecx,0x00000000
mov edx,input_text
mov esi,28
mov edi,7
newline2:
mov eax,4
int 0x40
add ebx,10
add edx,60
dec edi
jnz newline2
mov eax,38
mov ebx,210*65536+210
mov ecx,22*65536+136
mov edx,0x6699cc ; 002288
int 0x40
mov eax,38
mov ebx,211*65536+211
mov ecx,22*65536+136
mov edx,0x336699 ; 002288
int 0x40
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
popa
ret
; DATA AREA
text:
db ' TCB status: 0 '
db ' '
db ' Activate - port 8008 '
db ' Stop server '
db ' '
db ' > '
db ' < > Kbps '
db 'x'; <- END MARKER, DONT DELETE
headers:
db 'ICY 200 OK',13,10
db 'icy-notice1:This stream requires Winamp or xmms',13,10
db 'icy-url:http://www.menuetos.org',13,10
db 'icy-pub: 1',13,10
db 'icy-name: Menuet Mp3 Shoutcast Radio ',version,' - '
transname:
db ' ',13,10,13,10
headere:
wls: db 'MP3 shoutcast server ',version
wle:
socket dd 0
status dd 0
posy dd 1
posx dd 0
read_on db 1
read_to dd 0
addr dd 0
ya dd 0
bps dd 128*1000
fileinfo: dd 0,0,0,0,0x20000
filename: db '/RD/1/MENUET.MP3',0
times 50 db 0
input_text:
I_END: