SecondReality/MAIN/STARTEMS.C
2017-09-24 01:45:36 +02:00

526 lines
10 KiB
C

/* stmik ems loader (the feared one) */
int loadmode=2;
// 0=all low
// 1=<8K low, >8K EMS
// 2=all EMS
// -1=load no samples
int noems=0;
int gusmode=0;
int nosurround=0;
//#include <stdio.h>
//#include <bios.h> // REGS struct
//#include <malloc.h>
//#include <sys\types.h>
//#include <sys\stat.h>
//#include <fcntl.h>
//#include <io.h>
//#include "stmik.h"
#pragma pack(1)
typedef unsigned char uchar;
int emsenabled;
unsigned emspageframe,emsnullhandle;
void *emsframepnt;
struct ds_smp /* instrument block, sample */
{
char type; /* 1 for sample */
char filename[12];
unsigned char memseg2;
unsigned memseg;
long length;
long lbeg;
long lend;
char vol;
char disk;
char pack; /* 0=normal(disk), 1=amiga(module), 2=ADPCM */
char flags; /* +1=loop */
long c2spd;
char _reserved2[4];
unsigned guspos;
unsigned lend512;
long lastused; /* in ilib, used as time/datestamp */
char name[28];
char _magic[4]; /* "SCRS" */
};
struct ds_fileheader
{
char name[28];
char _magic_pinit; /* 1ah (or 0h in mem when initialized) */
char type; /* 16=module, 17=song */
char _reserved1[2];
int ordnum;
int insnum;
int patnum;
unsigned flags;
int cwtv; /* created with tracker version */
int ffv; /* file format version */
char _magic_signature[4]; /* SCRM */
uchar mastervol;
uchar initspeed;
uchar inittempo;
char _reserved[13];
uchar channel[32]; /* channel types */
};
struct ds_smp *moduleins;
static int freemem(char far *block)
{
int a;
if(block)
{
hfree(block);
}
return(0);
}
static char far *getmem(long size)
{
unsigned int a;
unsigned int paras;
char far *p;
paras=((size+31L)>>4L)+1L;
if(_dos_allocmem(paras,&a))
{
_asm mov ax,7
_asm int 10h
_asm
{
mov dx,3c8h
mov al,0
out dx,al
mov al,16
out dx,al
out dx,al
out dx,al
}
printf("OUT OF MEMORY RESERVING %li BYTE BLOCK! (%i)\n",size,a);
exit(3);
}
p=(char far *)(((long)a)<<16L);
return(p);
}
static char far *insseg2fp(unsigned int seg)
{
if(seg<0xf000) return((char far *)((long)seg<<16));
else
{
int x;
union REGS reg;
seg&=0xfff;
for(x=0;x<4;x++)
{
reg.h.ah=0x44;
reg.h.al=x;
reg.x.bx=x;
reg.x.dx=seg;
int86(0x67,&reg,&reg);
}
return(emsframepnt);
}
}
void checkins(struct ds_smp *ins)
{
char far *p;
if(ins->type==1)
{
memcpy(ins->_magic,"SCRS",4);
if(ins->length==0)
{
ins->flags&=0xfffe;
return;
}
if(ins->vol>64) ins->vol=64;
if(ins->c2spd>65535) ins->c2spd=65535;
/* following three will be >999999 */
if(ins->length>64000) ins->length=64000;
if(ins->lend<=ins->lbeg) ins->flags&=0xfffe; /* disable loop */
if(ins->lbeg>ins->length) ins->lbeg=ins->length;
if(ins->lend>ins->length) ins->lend=ins->length;
/* do sample continuing for fast looping */
if(ins->flags&1)
{
unsigned u,v,i;
p=insseg2fp(ins->memseg);
if(ins->lend512)
{
for(i=ins->lend512;i<ins->length;i++) p[i]=p[i+512];
}
u=(unsigned)ins->lend;
v=(unsigned)ins->lbeg;
for(i=ins->length-1;i>=ins->lend;i--) p[i+512]=p[i];
for(i=0;i<512;i++) p[u+i]=p[v+i];
ins->lend512=ins->lend;
}
else
{
unsigned u,v,i;
p=insseg2fp(ins->memseg);
if(ins->lend512)
{
for(i=ins->lend512;i<ins->length;i++) p[i]=p[i+512];
ins->lend512=0;
}
memset(p+ins->length,128,512);
}
}
else if(ins->type>=2 && ins->type<=7) memcpy(ins->_magic,"SCRI",4);
else memset(ins->_magic,0,4);
}
static unsigned getinsmem(long length)
{
union REGS reg;
unsigned int eh;
char far *p;
length+=512;
if(loadmode && (emsenabled && (length>3000L || loadmode==2)))
{ /* try to get space in ems for the sample */
union REGS reg;
reg.h.ah=0x43;
reg.x.bx=(length+16383L)/16384L;
int86(0x67,&reg,&reg);
eh=reg.x.dx;
if(reg.h.ah==0)
{ /* ok to continue, got mem */
eh|=0xf000;
//printf("{elloc:%04X}\n",eh);
return(eh);
}
}
/* no ems/short sample, try conventional memory */
p=getmem(length);
if(!p) return(0);
eh=(unsigned)((long)p>>16);
//printf("{alloc:%04X}\n",eh);
return(eh);
}
static unsigned xloadins(int handle,long length)
{
char far *p;
unsigned eh;
eh=getinsmem(length);
if(!eh) return(0);
p=insseg2fp(eh);
read(handle,p,(unsigned)length);
return(eh);
}
static int resetems(void)
{
union REGS reg;
if(zemspageframe) emsenabled=1;
if(emsenabled)
{
reg.h.ah=0x45;
reg.x.dx=zemspagehandle;
int86(0x67,&reg,&reg);
}
return(0);
}
static int initems(void)
{
static int emsinitialized=0;
int a;
union REGS reg;
if(noems) return(0);
zemspageframe=0;
emsinitialized=1;
{ /* check for ems */
FILE *f1;
f1=fopen("*EMMXXXX0","rb");
if(f1!=NULL)
{
emsenabled=1;
fclose(f1);
}
}
if(emsenabled)
{
reg.h.ah=0x41;
int86(0x67,&reg,&reg);
zemspageframe=emspageframe=reg.x.bx;
emsframepnt=(char far *)((long)emspageframe*65536L);
if(reg.h.ah!=0 || emspageframe<0x1000) return(-1);
reg.h.ah=0x43;
reg.x.bx=1;
int86(0x67,&reg,&reg);
zemspagehandle=emsnullhandle=reg.x.dx;
}
return(0);
}
static void freeinsmem(struct ds_smp *ins,char far *module)
{
union REGS reg;
unsigned u;
if(ins->type==1 && (u=ins->memseg))
{
u+=((long)module>>16);
//printf("{free:%04X}\n",u);
if(u<0xf000)
{
freemem((char far *)((long)u<<16));
}
else
{
reg.h.ah=0x45;
reg.x.dx=(u&0xfff);
int86(0x67,&reg,&reg);
}
}
ins->memseg=0;
}
static char far *loads3mems(unsigned int h) /* dos file handle */
{
long filebase=0L;
int orders,patterns,instruments;
int moduleseg;
int insseg;
int *parains;
int *parapat;
char far *module;
struct ds_fileheader tmpheader;
struct ds_fileheader *header;
struct ds_smp *ins;
unsigned u;
char far *p;
long l;
int a,b;
if(gusmode)
{
_asm
{
mov dx,a
mov ax,102h ;cleargusmem
mov bx,4
int 0fch
}
}
if(loadmode!=0 && loadmode!=-1) initems();
filebase=tell(h);
read(h,&tmpheader,sizeof(tmpheader));
l=sizeof(struct ds_fileheader)+tmpheader.ordnum+
tmpheader.patnum*2+tmpheader.insnum*2;
module=getmem(l+tmpheader.insnum*0x50+0x10);
moduleins=ins=(struct ds_smp *)((long)module+(((l+0x10)>>4)<<16));
moduleseg=(long)module>>16;
insseg=(long)ins>>16;
lseek(h,filebase,SEEK_SET);
read(h,module,(size_t)l);
header=(struct ds_fileheader *)module;
header->type=16;
orders=header->ordnum;
instruments=header->insnum;
patterns=header->patnum;
parains=(int *)(module+sizeof(struct ds_fileheader)+header->ordnum);
parapat=parains+header->insnum;
for(a=0;a<instruments;a++)
{
lseek(h,filebase+((long)parains[a]<<4L),SEEK_SET);
read(h,ins+a,0x50);
parains[a]=a*5+insseg-moduleseg;
}
for(a=0;a<patterns;a++)
{
b=parapat[a];
if(!b) continue;
lseek(h,filebase+((long)b<<4L),SEEK_SET);
read(h,&u,2);
p=getmem(u);
*(int *)p=u;
read(h,p+2,u-2);
parapat[a]=((long)p>>16)-moduleseg;
}
if(gusmode)
{
char *p=module;
_asm
{
mov bx,4
mov ax,101h
mov dx,word ptr p[2]
int 0fch // initmodule
}
}
for(a=0;a<instruments;a++) if((ins+a)->type==1 && (ins+a)->memseg)
{
long off;
int seg;
if(nosurround && (ins+a)->filename[strlen((ins+a)->filename)-1]=='$')
{
(ins+a)->type=0;
(ins+a)->memseg=0;
(ins+a)->guspos=0;
continue;
}
if(loadmode==-1)
{
(ins+a)->memseg=0;
(ins+a)->guspos=0;
}
else
{
off=(long)(ins+a)->memseg<<4L;
off+=(long)(ins+a)->memseg2<<20L;
lseek(h,filebase+off,SEEK_SET);
seg=xloadins(h,(ins+a)->length);
(ins+a)->memseg=seg;
checkins(ins+a);
(ins+a)->memseg-=moduleseg;
(ins+a)->guspos=0;
}
if(gusmode)
{
if((ins+a)->memseg)
{
_asm
{
mov dx,a
mov ax,100h
mov bx,4
int 0fch
}
freeinsmem(ins+a,module);
}
}
}
return(module);
}
static int frees3mems(char far *module)
{
struct ds_fileheader *header;
struct ds_smp *ins;
int *parains;
int *parapat;
unsigned int u;
long l;
int a;
header=(struct ds_fileheader *)module;
l=sizeof(struct ds_fileheader)+header->ordnum+
header->patnum*2+header->insnum*2;
ins=(struct ds_smp *)((long)module+(((l+0x10)>>4)<<16));
parains=(int *)(module+sizeof(struct ds_fileheader)+header->ordnum);
parapat=parains+header->insnum;
for(a=0;a<header->insnum;a++) if((ins+a)->type==1 && (ins+a)->memseg)
{
freeinsmem(ins+a,module);
}
for(a=0;a<header->patnum;a++)
{
u=parapat[a];
if(u)
{
u+=((long)module>>16);
freemem((char far *)((long)u<<16));
}
}
freemem(module);
if(loadmode!=0 && loadmode!=-1) resetems();
return(0);
}
static int frees3msamples(char far *module)
{
struct ds_fileheader *header;
struct ds_smp *ins;
int *parains;
int *parapat;
long l;
int a;
header=(struct ds_fileheader *)module;
l=sizeof(struct ds_fileheader)+header->ordnum+
header->patnum*2+header->insnum*2;
ins=(struct ds_smp *)((long)module+(((l+0x10)>>4)<<16));
parains=(int *)(module+sizeof(struct ds_fileheader)+header->ordnum);
parapat=parains+header->insnum;
for(a=0;a<header->insnum;a++) if((ins+a)->type==1 && (ins+a)->memseg)
{
freeinsmem(ins+a,module);
}
return(0);
}
static int readys3mems(char far *module)
{
struct ds_fileheader *header;
struct ds_smp *ins;
int *parains;
int *parapat;
long l;
int a;
return(0);
_asm
{
mov dx,a
mov ax,102h ;cleargusmem
mov bx,4
int 0fch
}
header=(struct ds_fileheader *)module;
l=sizeof(struct ds_fileheader)+header->ordnum+
header->patnum*2+header->insnum*2;
ins=(struct ds_smp *)((long)module+(((l+0x10)>>4)<<16));
parains=(int *)(module+sizeof(struct ds_fileheader)+header->ordnum);
parapat=parains+header->insnum;
/*
for(a=0;a<header->insnum;a++) if((ins+a)->type==1 && (ins+a)->memseg)
{
_asm
{
mov dx,a
mov ax,100h
mov bx,4
int 0fch
}
freeinsmem(ins+a,module);
}
*/
return(0);
}
/* external interface */
char * stmik_emsready(char *p) // moves instruments to ems/gravis
{
readys3mems(p);
}
char * stmik_emsload(unsigned int h)
{
char *p;
p=loads3mems(h);
return(p);
}
void stmik_emsfree(char *p)
{
frees3mems(p);
}
void stmik_emsfreesamples(char *p)
{
frees3msamples(p);
}