From tfm@stmarys.demon.co.uk Tue May 23 10:38:40 1995
From: Tristam Fenton-May <tfm@stmarys.demon.co.uk>
Subject: Sound Blaster Assembely code (OBJ file wanted)
Newsgroups: alt.lang.asm
Date: 18 May 1995 15:48:32 +0100
Organization: St Marys Pharmaceutical Unit
Reply-To: tfm@stmarys.demon.co.uk
Path: fuw.edu.pl!mimuw.edu.pl!backup.sunet.se!sunic!sunic.sunet.se!seunet!news2.swip.net!doc.news.pipex.net!pipex!demon!stmarys.demon.co.uk!tfm
Lines: 766
Sender: news@news.demon.co.uk
Message-ID: <800799652snz@stmarys.demon.co.uk>
NNTP-Posting-Host: dispatch.demon.co.uk
X-Newsreader: Demon Internet Simple News v1.29
X-Posting-Host: stmarys.demon.co.uk

I previously wrote to this group asking for help with a Sound Blaster program
Some body offered to assemble it for me and sent the object file UUENCODED to
me. I now have a UUDECODER so here are the files. I only need the assembly
code assembled, but somebody asked to see the code so I included it all.

I also have another set of source code which I downloaded from the net. I have
UUENCODED this and it is in a seperate file. Please colud somebody assemble the
assembely source code form that to?

Please send the files to

tfm@stmarys.demon.co.uk

Thanks - TFM


-FILE-   CT-INTER.ASM    
	
	.MODEL SMALL
	.CODE

;Assebely for low level Sound Blaster Code
;Designed for TASM
;Defined functions :
;   -   void CallCTVoice(struct REGPACK far *R);
;   -   void CTVoiceAddress(char far *A,unsigned G);
;   -   void Variables(void faqr *StPt,void far *Bspt,void far *BlPt, void far *BtPt, void far *CoPt);
;   -   void UserRoutine(void interrupt *P);

PUBLIC _ctvoiceadress, _callctvoice
PUBLIC _variables, _userroutine


Registers STRUC
	rAX     dw 0
	rBX     dw 0
	rCX     dw 0
	rDX     dw 0
	rBP     dw 0
	rSI     dw 0
	rDI     dw 0
	rDS     dw 0
	rES     dw 0
	rFlags  dw 0
ENDS


@CopyDword MACRO Dest, Source
	mov ax,WORD PTR Source+0
	mov WORD PTR Dest+0,ax
	mov ax,WORD PTR Source+2
	mov WORD PTR Dest+2,ax
ENDM

CTVoicePt       DD 0        ;CT-VOICE address
UserRoutAddress DD 0        ;user routine
BlockStart      DD 0        ;Pointer address
BlockLength     DD 0        ;Long int address
BlockType       DD 0        ;Byte Address
Continue        DD 0        ;Boolean address


;   -   void CTVoiceAddress(char far *A,unsigned G);
; Set the start address of the CT-VOICE driver

_CTVoiceAddress PROC FAR
	ARG A:DWORD,G:WORD
	push bp
	mov bp,sp
	push ds
	lds si, [A]             ;DS:SI points 
	mov dx,ds               ;at CT_VOICE  
	mov ax,si               ;DX:AX=DS:SI 
	add ax,15               ;minimize and 
	shr ax,1                ;round up
	shr ax,1
	shr ax,1
	shr ax,1
	add dx,ax
	mov es,dx               ;ES:0 starts CT_VOICE
	mov cx,[G]              ;CX=driver size
	mov di,cx               ;start at the end 
	add si,cx               ;of the driver 
	inc cx                  ;one more byte
	std
	rep movsb               ;copy driver data
	cld
	mov [WORD PTR CTVoicePt+0],0
	mov [WORD PTR CTVoicePt+2],es
	pop ds
	pop bp
	ret
ENDP

_CallCTVoice PROC FAR
	ARG R:DWORD
	push bp
	mov bp,sp
	push ds                    ;has to be saved
	lds si,[R]                 ;DS:SI points at R
	mov ax,[si+rSI]            ;save used SI
	push ax
	mov ax,[si+rAX]            ;set registers
	mov bx,[si+rBX]
	mov cx,[si+rCX]
	mov dx,[si+rDX]
	mov di,[si+rDI]
	mov es,[si+rES]
	mov ds,[si+rDS]
	pop si
	call [DWORD PTR cs:CTVoicePt]
	push ds
	push si
	lds si,[R]
	mov [si+rAX],ax
	mov [si+rBX],bx
	mov [si+rCX],cx
	mov [si+rDX],dx
	mov [si+rDI],di
	mov [si+rES],es
	mov [si+rDS],ds
	pop ax                        ;AX=SI after call
	mov [si+rSI],ax
	pop ax                        ;AX=DS after call
	mov [si+rDS],ax
	pop ds                        ;Restore DS
	pop bp
	ret
ENDP

;   -   void Variables(void faqr *StPt,void far *Bspt,void far *BlPt, void far *BtPt, void far *CoPt);
; Set pointers to Status Word, BlockStart,BlockLength,BlockType & Continue

_Varibles PROC FAR
	ARG Stp:DWORD,Bsp:DWORD,Blp:DWORD,Btp:DWORD,CoP:DWORD
	push bp
	mov bp,sp
	@CopyDword cs:BlockStart,BsP
	@CopyDword cs:BlockLength,BlP
	@CopyDword cs:BlockType,BtP
	@CopyDword cs:Continue,CoP
	mov bx,5                             ;set pointer to
	les di,StP                           ;StatusWord
	call [DWORD PTR cs:CTVoicePt]
	pop bp
	ret
ENDP


;   -   void UserRoutine(void interrupt *P);
;   Set interrupt routine

_UserRoutine PROC FAR
	ARG P:DWORD
	push bp
	mov bp,sp
	mov ax,[WORD PTR P+0]
	mov [WORD PTR cs:UserRoutAddress+0],ax
	mov dx,[WORD PTR P+2]
	mov [WORD PTR cs:UserRoutAddress+2],dx
	or ax,dx                               ; P=0:0 ?
	jnz NewUserRoutine
	mov bx,13                              ; Yes, turn off routine
	call [DWORD PTR cs:CTVoicePt]
	pop bp
	ret

NewUserRoutine:
	mov ax,offset UserInterFace
	mov dx,cs
	mov bx,13                             ; Set interface
	call [DWORD PTR cs:CTVoicePt]
	pop bp
	ret
ENDP


userinterface:
	push ax                              ;save used
	push si                              ;registers
	push ds
	lds si,[cs:BlockStart]               ;Set Block start
	mov [si],bx                          ;starting from
	mov [si+2],es                        ;block to be played
	lds si,[cs:BlockLength]              ;set block length
	mov ax,[es:bx+1]                     ;with the 24bit
	mov [si],ax                          ;length
	mov ax,[es:bx+3]
	xor ah,ah                            ;delete bits 25-32
	mov [si+2],ax
	lds si,[cs:BlockType]                ;set block type
	mov al,[es:bx]
	mov [si],al
	lds si,[cs:Continue]                 ;set boolean
	mov byte ptr [si],-1                 ;at default True
	pushf                                ;stimulate Int 
	call [DWORD PTR cs:UserRoutAddress]
	cmp byte ptr [si],0                  ;Continue = False ?
	jne ClearCarryFlag                   ;No, process block
	cmp byte ptr [es:bx],0               ;Last block?
	je ClearCarryFlag                    ;Yes, process block
	pop ds                               ;restore registers
	pop si
	pop ax
	stc                                  ;don't process block
	retf                                 ;Return to CT_VOICE
ClearCarryFlag:
	pop ds
	pop si
	pop ax
	clc                                  ;Process block
	retf
ENDP
	END











-FILE- CT-INTER.H

extern void far callctvoice(struct REGPACK far *r);
extern void far UserRoutine(void interrupt far *p);
extern void far ctvoiceaddress(char far *p,unsigned s);
extern void far variables(void far *stpt,void far *bspt,void far *blpt,void far *btpt,void far *copt);










-FILE- CTVOICE.H

#define callok              0
#define carderror           1
#define ioporterror         2
#define dmaerror            3

#define spon                1
#define spoff               0

#define endbl               0
#define nwsamplebl          1
#define samplebl            2
#define silencebl           3
#define markerbl            4
#define textbl              5
#define repeatbl            6
#define repeatendbl         7
#define extrainfobl         8

#define soundblaster        0
#define oldsbpro            1
#define newsbpro            2

#define mic                 0
#define cd_rom              1
#define line                3

#define mainvl              0
#define voicevl             1
#define micvl               2
#define cd_romvl            3
#define linevl              4

#define both                0
#define left                1
#define right               2

#define lowfilter           0
#define highfilter          1
#define outputfilter        0
#define inputfilter         1

#define stereo              1
#define mono                0

#define on                  0
#define off                 1


typedef unsigned char intartype[0xfff0];

typedef struct
	{
	void *start;
	long length;
	intartype far *block;
	} voctp;

extern unsigned statusword;
extern intartype *blockstart;
extern long blocklength;
extern unsigned char blocktype;
extern unsigned char Continue;
extern unsigned char cardtype;
extern unsigned sbioresult;

/*Disk IO*/
extern void loadctdriver(char *n);
extern char checkvocfile(char *n);
extern void loadvocfile(char *n,voctp *v);
extern void savevocfile(char *n,voctp v);
extern void disposevoc(voctp *v);


/*Initialization*/
extern unsigned ctversion();
extern void useport(unsigned p);
extern void useirq(unsigned i);
extern void usechannel(unsigned d);
extern void initializedriver();

/*utilities*/
extern void speaker(unsigned w);
extern void stopvprocess();
extern void driveroff();
extern void userroutine(void interrupt far *p);
void askrate(unsigned *max, unsigned *min,unsigned m, unsigned k);

/*Mixer chip*/
extern void recordmode(unsigned b);
extern void input(unsigned s);
extern void recordingfilter(unsigned b);
extern void volume(unsigned s,unsigned c, unsigned v);
extern void filter(unsigned s,unsigned v);
extern void resetmixer();
extern void readallvolumes();

/*Ask volumes and filter settings*/
extern void returnvolume(unsigned s,unsigned v);
extern void returnfilter(unsigned s);


/*playing*/
extern void pause();
extern void continueplaying();
extern void stoprepettition(unsigned i);
extern void playblock(voctp v);
extern void playembblock(unsigned h, long s);

/*recording*/
extern void recordsample(long l, unsigned sr,voctp *v);
extern void recordembsample(unsigned sr,unsigned h,long s);

/*voc utils*/
extern void firstsubblock(voctp *v);
extern void nextsubblock(voctp *v);

/*functions for CT-TIMER.DRV*/
extern void volumetable(void *v, unsigned char s);
extern void echobuffer(void *e,unsigned s);
extern void command(char *s);
extern unsigned char cvolume();











-FILE- CTVOICE.C

#include<stdio.h>
#include<dos.h>
#include<alloc.h>
#include<string.h>
#include"CT-INTER.H"
#define extern
#include"CTVOICE.H"
#undef extern

struct REGPACK r;
void *ctaddress;

/*Disk I/O */

void loadctdriver(char *n)
	{
	FILE *f;
	char s[9];
	unsigned ctsize;
	if (strcmp(n,"") == 0)
	f=fopen("CT-VOICE.DRV","rb");
	else
	f=fopen(n,"rb");
	fseek(f,3,SEEK_SET);
	fread(&s,9,1,f);        /*read ID*/
	fseek(f,0l,SEEK_END);
	s[9] = 0;
	if (strcmp(s,"CT-VOICE") == 0)
	{
	ctsize = ftell(f);
	fseek(f,0l,SEEK_SET);
	ctaddress = malloc(ctsize + 16);
	fread(ctaddress,ctsize,1,f);
	fclose (f);
	ctvoiceaddress((char far*)ctaddress,ctsize);
	sbioresult=0;
	}
	else
	fclose(f);
	sbioresult = 1;
	}


char checkvocfile(char *n)
	{
	FILE *f;
	char s[20];
	unsigned t1,t2;
	char r;

	r=0;
	f=fopen(n,"rb");
	fread(s,19,1,f);
	s[20] = 0;
	if (strcmp(s,"Creative Voice File") == 0)
	{
	fseek(f,0x16,SEEK_SET);
	fread(&t1,2,1,f);
	fread(&t2,2,1,f);
	t1 = (t1 ^ 0xffff)+0x1234;
	r = t1 == t2;
	}
	fclose(f);
	return r;
	}


void loadvocfile(char *n, voctp *v)
	{
	FILE *f;
	unsigned t;
	/*unsigned sgh, 0fh;unsigned sge, 0fe;*/
	long hs;

	f=fopen (n,"rb");
	fseek (f,0x14,SEEK_SET);
	fread(&t,2,1,f);
	fseek(f,0l,SEEK_END);
	v->length = ftell(f) - t;
	fseek(f,t,SEEK_SET);
	v->start = malloc(v->length);
	fread(v->start,v->length,1,f);
	fclose(f);
	v->block = (intartype far *)v->start;     /* added bit in brackets*/
	}


void savevocfile(char *n, voctp v)
	{
	FILE *f;
	char s[21]="Crative Voice File\x1A";
	unsigned t;

	f= fopen(n,"wb");
	fwrite(s,20,1,f);
	t= 0x001a;
	fwrite(&t,2,1,f);
	t =0x010a;
	fwrite(&t,2,1,f);
	t=(t- 0x1234) ^ 0xffff;
	fwrite(&t,2,1,f);
	fwrite(v.start,v.length,1,f);
	fclose(f);
	}

void disposevoc(voctp *v)
	{
	free(v->start);
	v->start = NULL;
	v->length =0;
	v->block = NULL;
	}



/*Initialization*/
unsigned ctversion()
	{
	r.r_bx=0;
	callctvoice(&r);
	return r.r_ax;
	}

void useport(unsigned p)
	{
	r.r_bx=1;
	r.r_ax=p;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void useirq(unsigned i)
	{
	r.r_bx=2;
	r.r_ax=i;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void usechannel(unsigned d)
	{
	r.r_bx=19;
	r.r_ax=d;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void initializedriver()
	{
	r.r_bx=3;
	callctvoice(&r);
	variables(&statusword,&blockstart,&blocklength,&blocktype,&Continue);
	sbioresult = r.r_ax;
	}

/*utilities*/
void speaker(unsigned w)
	{
	r.r_bx=4;
	r.r_ax=w;
	callctvoice(&r);
	}
void stopvprocess()
	{
	r.r_bx=8;
	callctvoice(&r);
	}
void driveroff()
	{
	r.r_bx=9;
	callctvoice(&r);
	}
void userroutine(void interrupt far *p)
	{
	if (p==NULL)
	UserRoutine(MK_FP(0,0));
	else
		UserRoutine(p);
	}
void askrate(unsigned *max, unsigned *min,unsigned m, unsigned k)
	{
	r.r_bx=26;
	r.r_ax=k;
	r.r_dx=m;
	callctvoice(&r);
	*max = r.r_dx;
	*min = r.r_ax;
	}


/*Mixer chip*/
void recordmode(unsigned b)
	{
	r.r_bx=16;
	r.r_ax=b;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void input(unsigned s)
	{
	r.r_bx=17;
	r.r_ax=s;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void recordingfilter(unsigned b)
	{
	r.r_bx=18;
	r.r_ax=b;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void volume(unsigned s,unsigned c, unsigned v)
	{
	if (c == both)
		{
	volume(s,left,v);
		c = right;
		}
	r.r_bx=21;
	r.r_ax=s;
	r.r_cx=v;
	r.r_dx=c;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void filter(unsigned s,unsigned v)
	{
	r.r_bx=22;
	r.r_ax=s;
	r.r_cx=v;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void resetmixer()
	{
	r.r_bx=23;
	callctvoice(&r);
	}
void readallvolumes()
	{
	r.r_bx=24;
	callctvoice(&r);
	}

/*Ask volumes and filter settings*/
void returnvolume(unsigned s,unsigned v)
	{
	r.r_bx=25;
	r.r_ax=s;
	r.r_dx=v;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void returnfilter(unsigned s)
	{
	if (ctversion() > 0x20a)
		r.r_bx=27;
	else
		r.r_bx=26;
	r.r_ax=s;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}


/*playing*/
void pause()
	{
	r.r_bx=10;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void continueplaying()
	{
	r.r_bx=11;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void stoprepettition(unsigned i)
	{
	r.r_bx=12;
	r.r_ax=i;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}
void playblock(voctp v)
	{
	r.r_bx=6;
	r.r_di=FP_OFF(v.start);
	r.r_es=FP_SEG(v.start);
	callctvoice(&r);
	}
void playembblock(unsigned h, long s)
	{
	r.r_bx=14;
	r.r_dx=h;
	r.r_di=s >> 16;
	r.r_es=s & 0xffff;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}

/*recording*/
void recordsample(long l, unsigned sr,voctp *v)
	{
	v->start = (char far *) malloc(l);
	v->length = l;
	r.r_ax=sr;
	r.r_bx=7;
	r.r_dx=l > 16;
	r.r_dx=l & 65535;
	r.r_di=FP_OFF(v->start);
	r.r_es=FP_SEG(v->start);
	callctvoice(&r);
	}
void recordembsample(unsigned sr,unsigned h,long s)
	{
	r.r_ax=sr;
	r.r_bx=15;
	r.r_dx=h;
	r.r_di=s > 16;
	r.r_es=s & 0xffff;
	callctvoice(&r);
	sbioresult = r.r_ax;
	}

/*voc utils*/
void firstsubblock(voctp *v)
	{
	v->block = (intartype far *)v->start;    /*added bit in brakets*/
	}
void nextsubblock(voctp *v)
	{
	void far *tfm;
	long a;
	a = 16 * (long) FP_SEG(*v->block) + (long) FP_OFF(*v->block);
	a = a + 4 + (*v->block[1]) + (*v->block[2]) < 8 + (* v->block[3]) < 16;
	v->block = (intartype far *)MK_FP((unsigned)a > 4,(unsigned)a & 15);   /*added bit in brakets*/
	} /*I added ^^^^^^^^^^^^^^^        ^^^^^^^^        ^^^^^^^^*/

/*functions for CT-TIMER.DRV*/
void volumetable(void *v, unsigned char s)
	{
	void far *h =(void far *) v;
	r.r_bx=128;
	r.r_ax=0;
	r.r_cx=s;
	r.r_di=FP_OFF(h);
	r.r_es=FP_SEG(h);
	callctvoice(&r);
	}
void echobuffer(void *e,unsigned s)
	{
	void far *h =(void far *) e;
	r.r_bx=128;
	r.r_ax=1;
	r.r_cx=s;
	r.r_di=FP_OFF(h);
	r.r_es=FP_SEG(h);
	callctvoice(&r);
	}
void command(char *s)
	{
	strcat(s,0);
	r.r_bx=129;
	r.r_di=FP_OFF(s);
	r.r_es=FP_SEG(s);
	callctvoice(&r);
	}
unsigned char cvolume()
	{
	r.r_bx=130;
	callctvoice(&r);
	return r.r_ax & 0xff;
	}





-- 
Tristam Fenton-May          tfm@stmarys.demon.co.uk (Wales!!!)
                                      
                                      I~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~I
~~~~T~~~~   I~~~~~~   I\        /I    I  I> I_I ~T~ I~~ I\/I         I
    I       I         I  \    /  I    I  I\ I I  I  I~  I  I         I
    I       I~~~      I    \/    I    I   enterprises!   <C>1994     I
    I       I         I          I    I  RHTFM's Rugby Manager Game  I
    I       I         I          I    I_5.00p_$10_by_UUencoded_Email_I



