speech by Red Sector Inc. [web]
;
; Speech synthesis in 115 bytes by olivier.poudade.free.fr 2013
; based on Microsoft's Speech Application Programming Interface
; tested on "out of the box" XP SP3
; synopsis : speech.com hello world
;
; >fasm speech.asm
; flat assembler version 1.70.03 (786431 kilobytes memory)
; 2 passes, 125 bytes.
; size=125 bytes
; size=123 bytes if replace : vocoder1 db vocoder2-$-2,"cscript ~.vbs|del ~.*",0dh
; size=115 bytes if replace : vocoder1 db vocoder2-$-2,"cscript ~.vbs",0dh
;
; Greets to Dark Bit Factory (DBF) forum members - www.dbfinteractive.com - from Baudsurfer
;
_sp equ 02eh ; 2eh-2fh word SP on entry to last int 21h call (internal cf. http://en.wikipedia.org/wiki/Program_Segment_Prefix)
_ss equ 030h ; 30h-31h word SS on entry to last int 21h call (internal cf. http://en.wikipedia.org/wiki/Program_Segment_Prefix)
org 100h ; start after PSP as binary
mov si,080h ; si=080h start of DTA, [080h]=number of bytes on command-line
lodsb ; si=081h start of 127-byte command-line
add [vocoder3],al ; -2 strips final len(commandstring)+CR of vocoder4 command-line
mov cl,al ; cl=al=[081h]=number of bytes on command-line (terminated by a 00dh)
mov di,vocoder4 ; di=end of vocoder3 command-line
rep movsb ; copy the cmdline arguments which is text to speak
mov si,vocoder2 ; vocoder2=tail of vocoder3 command-line
mov cl,vocoder3-vocoder2; cl=len(vocoder2)
rep movsb ; copy vocoder2 string at tail of vocoder3
call vocoder ; si already points to vocoder3
mov si,vocoder1 ; this last command-line cannot be merged to the previous one because of shell locked pipe flushing
vocoder: mov ah,04ah ; function free memory for shell command.com execution
mov bl,020h ; bl=32 paragraphs=512 bytes(psp+128+vocoder4 overlay)=what to reduce our process to vs. 64k allocated to all .com files
int 21h ; general dos interrupt
mov [_sp],sp ; necessary : int 2eh trashes stack pointer
int 02eh ; function pass command to command interpreter fir execution (cf. http://www.ctyme.com/intr/rb-4248.htm)
push cs ; necessary : int 2eh trashes data segment
pop ds ; ds=cs necessary : int 2eh trashes data segment
mov ss,[_ss] ; necessary : int 2eh trashes stack segment, 030h-031h=ss on entry to last int 21h call (here was function 04ah)
mov sp,[_sp] ; lss sp,[_ss] unusable because _sp !=2eh :(
ret ; return back to shell
vocoder1 db vocoder2-$-2,"cscript ~.vbs|del ~.vbs",0dh ;Offset Size Description (Table 02585) DOS commandline
vocoder2 db 22h,">~.vbs",0dh ;001h var command-line
vocoder3 db vocoder4-$+vocoder1-vocoder2-2,"echo createobject(",22h,"SAPI.SpVoice",22h,").Speak",22h ;000h byte len(command-line) excluding trailing CR
vocoder4: ;xxxh byte 00dh (CR)[ back to the prod ]
