#resize TRUE
#parsecommandline TRUE
#stack 1024
#pragma option de
#use80386

?include "SB.h--"
?include "MODLOAD.h--"
?include "MODPLAY.h--"

byte ErrorMesg="Error loading Module file.\n";
byte MsgNotFound="Sound Blaster not found.\n";
word Scope[320];
word RowOfs[256];

main()
{
	CSWORD[#SegDS]=DS;
	DetectSb();	//Detect the SB Addr,
	IF(@PARAMCOUNT()==0)EXIT(byte 1);
	LoadModule(@PARAMSTR(0));
	IF(ErrorInfo!=0){
		WRITESTR(#ErrorMesg);
		goto EX;
	}
	MixSpeed=22000;
	SbInit();
	SETVIDEOMODE(byte 0X13);
	CX=128;	// Make a lookup table
	BX=0;		// for fastest pixel
	DX=100-64*320;// addressing.
	loop(CX){
		RowOfs[BX]=DX;
		RowOfs[BX+2]=DX;
		DX+=320;
		BX+=4;
	}
	GWRITESTR("\n           Tiny Mod Player.\n      Adapted on C-- Mishel Sheker.",byte 11);
	do{
		SbPoll();
		ES=0XA000;
		SI=DmaBuffer;	// get current samples
		CX=0;					//to be drawed ...
		DX=0;
		do{
			BX=DX;	//(save Index)
			DI=Scope[BX];//get old SCOPE pixel address
			ESBYTE[DI]=0;//erase it!
			$lodsb;		//get a sample (8-bit)
			BL=AL;		//calc new pixel address...
			BH=0;
			BX+=BX;
			DI=RowOfs[BX]+CX;
			BX=DX;		//(restore Index)
			Scope[BX]=DI;//save new address...
			ESBYTE[DI]=10;// and DRAW.
			DX+=2;
			CX++;
		}while(CX<320);
		IF(EndModule)@BIOSPUSHKEY(0x11b);
	}while(@BIOSKEYCHECK()==0);
	@BIOSREADKEY();
	@SETVIDEOMODE(byte 3);
	SbDone();
EX:
	FreeModule();
	EXIT(byte 0);
}

void DetectSb()
{
	BX=0x210;
	do{
		DX=BX+6;
		outp(1);
		inp();
		inp();
		inp();
		inp();
		outp(0);
		DL+=8;
		CX=100;
		loop(CX){
			loop(CX){
				inp();
				AL|=AL;
				IF(MINUSFLAG)GOTO GETID;
			}
			GOTO NEXTPORT;
GETID:
			DL-=4;
			inp();
			IF(AL==0xAA)GOTO FOUND;
			DL+=4;
		}
NEXTPORT:
		BX+=0x10;
	}while(BX<=0x260);
	goto FAIL;
FOUND:
	SbAddr=BX;
	$cli
	BL=inp(0x21);
	outp(0b11111111,0x21);
	ES=0;
	$push ESDWORD[0x28]	//irq2
	$push ESDWORD[0x2c] // irq3
	$push ESDWORD[0x34]	// irq5
	$push ESDWORD[0x3C]	// irq7
	ESWORD[0x28]=#TrapIrq2;
	ESWORD[0x2A]=CS;
	ESWORD[0x2C]=#TrapIrq3;
	ESWORD[0x2E]=CS;
	ESWORD[0x34]=#TrapIrq5;
	ESWORD[0x36]=CS;
	ESWORD[0x3C]=#TrapIrq7;
	ESWORD[0x3E]=CS;
	AL=BL&0b01010011;	// enable IRQs 2,3,5,7.
	outp(AL,0x21);
	$sti
	SbIrq=0;
	DX=SbAddr+12;
	do{
		inp();
		AL|=AL;
	}while(MINUSFLAG);
	outp(0xF2);
	CX=0;
	loop(CX){
		IF(SbIrq!=0)BREAK;
	}
	outp(BL,0x21);
	$cli
	ES=0;
	$pop ESDWORD[0x3c]
	$pop ESDWORD[0x34]
	$pop ESDWORD[0x2C]
	$pop ESDWORD[0x28]
	$cli
	IF(SbIrq==0){
FAIL:
		WRITESTR(#MsgNotFound);
		EXIT(byte 0);
	}
}

void TrapIrq2()
inline
{
	$push AX
	AX=2;
	GOTO TrapIrq;
}

void TrapIrq3()
inline
{
	$push AX
	AX=3;
	GOTO TrapIrq;
}

void TrapIrq5()
inline
{
	$push AX
	AX=5;
	GOTO TrapIrq;
}

void TrapIrq7()
inline
{
	$push AX
	AX=7;
//	GOTO TrapIrq;
}

void /*interrupt*/ TrapIrq()
inline
{
	$push    DX,DS
	DX=CSWORD[#SegDS];
	DS=DX;
	SbIrq=AX;
	DX=SbAddr+14;
	inp();
	@EOI();
	$pop     DS,DX,AX
	$iret
}
