#include #include #include unsigned char buf1[24000],buf2[24000]; int working = 1,valid = 0,count=24000/2; char *bufp = buf1; void far SB_ENTRY(void); void far callback(void); void far (*jumppt)() = SB_ENTRY; struct sppacket { short command; short xflags; void far (*cb)(); short spver; short mfreq; short dmasiz; short dmabuf; short base; short irq; short ldma; short hdma; } packet = {1,4,callback,0,8000,0,0,0,0,0,0 }; void far callback(void) { char far *pos; int len; asm mov word ptr [pos],di asm mov word ptr [pos+2],es asm mov [len],cx if (!valid) return; if (len <= count) { memcpy(pos,bufp,len); } else if (working == 1) { memcpy(pos,bufp,count); valid &= 2; bufp = buf2; len = len - count; count = 24000/2; asm mov word ptr [pos],0 memcpy(pos,bufp,len); working = 2; } else { memcpy(pos,bufp,count); valid &= 1; bufp = buf1; len = len - count; count = 24000/2; asm mov word ptr [pos],0 memcpy(pos,bufp,len); working = 1; } bufp+=len; count -=len; asm mov es,word ptr [pos + 2] asm pop di asm mov di,word ptr [pos] asm push di asm sub cx,cx noupdate: } int song_init(void) { asm push si asm lea si,[packet] asm call [jumppt]; asm jc SB_badinit packet.command = 3; asm lea si,[packet] asm call [jumppt]; asm pop si return 1; SB_badinit: asm pop si return 0; } void song_rundown(void) { asm push si packet.command = 2; asm lea si,[packet] asm call [jumppt]; packet.command = 0; asm lea si,[packet] asm call [jumppt]; asm pop si } void get(char *buf, int flag, FILE *in) { int len,i; memset(buf,0,24000); len = fread(buf,1,24000,in); for (i=0; i < 24000; i+=2) buf[i/2] = (buf[i+1] + 0x80) & 0xff; if (len) valid |= flag; } int main(int argc, char **argv) { FILE *in; if (argc != 2) { printf("usage: play file"); exit(1); } in = fopen(argv[1],"rb"); if (!in) { printf("can't find input file"); exit(1); } get(buf1,1,in); get(buf2,2,in); if (!song_init()) { printf("Sound blaster driver failed"); exit(1); } while (!feof(in) ) { while (valid & 1 ); get(buf1,1,in); if (!feof(in) ) { while (valid & 2 ); get(buf2,2,in); } } while (valid); song_rundown(); if (kbhit()) getch(); return 0; }