github publish

This commit is contained in:
Ondrej Novak 2025-01-24 18:27:22 +01:00
commit 506e23bf32
542 changed files with 120675 additions and 0 deletions

71
ZVUK/ANALYSE/DOSMEM.C Normal file
View file

@ -0,0 +1,71 @@
/*********************************************/
/*** DOS memory allocation - DOSMEM.C ***/
/*** vykostena verze chlumakova memalloc.c ***/
/*********************************************/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosmem.h"
/*** Alokace pole v dolni pameti ***/
void *mem_alloc(int size)
{
static union REGS r;
MEMREC memrec;
r.x.eax=0x0100;
r.x.ebx=(size>>4)+1;
size=r.x.ebx<<4;
int386(0x31,&r,&r);
if (r.x.cflag)
{
printf ("No fucking DOS memory left!!!");
exit(1);
}
memrec.ptr=(void *)((r.x.eax&0xFFFF)<<4);
Selector=memrec.selector=(short int)r.x.edx;
return memrec.ptr;
}
/*** Uvolneni dolni pameti ***/
void mem_free(void *ptr)
{
union REGS r;
if(ptr!=NULL)
{
r.x.eax=0x0101;
r.x.edx=Selector;
int386(0x31,&r,&r);
if(r.x.cflag)
printf("Cannot free DOS memory!!!!");
}
}
/*** Vyvolani preruseni pomoci protected modu ***/
void WtNs386(int IntNum, DPMIREGS *dpmiregs)
{
union REGS r;
struct SREGS sr;
r.w.ax=0x300;
r.h.bl=(char)IntNum;
r.h.bh=0;
r.w.cx=0;
segread(&sr);
sr.es=FP_SEG(dpmiregs);
r.x.edi=FP_OFF(dpmiregs);
int386x(0x31,&r,&r,&sr);
}

46
ZVUK/ANALYSE/DOSMEM.H Normal file
View file

@ -0,0 +1,46 @@
/************************************/
/*** Hlavickovt soubor k DOSMEM.H ***/
/************************************/
typedef enum
{ DOS_MEMORY,
NEW,
} MEMORY_ITEMS;
typedef struct
{ int EDI;
int ESI;
int EBP;
int reserved;
int EBX;
int EDX;
int ECX;
int EAX;
short int Flags;
short int ES;
short int DS;
short int GS;
short int IP;
short int CS;
short int SP;
short int SS;
} DPMIREGS;
typedef struct
{ void *ptr;
int size;
int selector; //smysl jen u DOS_MEMORY
} MEMREC;
#define D32RealSeg(P) ((((unsigned int)(P))>>4)&0xFFFF)
#define D32RealOff(P) (((unsigned int)(P))&0xF)
int Selector;
DPMIREGS dpmiregs;
void *mem_alloc(int size);
void mem_free(void *ptr);
void WtNs386(int IntNum, DPMIREGS *dpmiregs);

5
ZVUK/ANALYSE/FLC.C Normal file
View file

@ -0,0 +1,5 @@
//
// Knihovna pro dekompresi FLC souboru
//
#include "flc.h"

54
ZVUK/ANALYSE/FLC.H Normal file
View file

@ -0,0 +1,54 @@
//
// Hlavickovy soubor ke knihovne FLC.C slouzici k dekompresi FLC
//
#ifndef _FLC_H
#define _FLC_H
typedef struct FLCHEADER {
unsigned int size; // delka souboru vcetne hlavicky
unsigned short idflc; // ID FLC=0AF12h
unsigned short frames; // pocet frejmu
unsigned short width; // sirka vsech obrazku
unsigned short height; // vyska vsech obrazku
unsigned short color; // hloubka barvy (bpp)
unsigned short flag1;
unsigned int speed; // rychlost prehravani (v 1/1000 s)
unsigned short reserv1; // rezervovany
unsigned int date1; // datum a cas vytvoreni
unsigned int serial; // seriove cislo programu
unsigned int date2; // datum a cas posledni zmeny
unsigned short XA;
unsigned short YA;
char reserv2 [42]; // rezervovano
unsigned int offset1; // offset prvniho frame
unsigned int offset2; // offset druheho frame
char reserv3 [40]; // rezervovano
} flcheader;
typedef struct FRAMEHEADER {
unsigned int size; // velikost frame v bytech
unsigned short sign; // znacka frame OFAF1h
unsigned short actions; // pocet akci v tomto frame
char reserv [8]; // rezervovano
} frameheader;
typedef struct ACTIONHEADER {
unsigned int size; // velikost akce v bytech
unsigned short code; // kod akce
// 04h - predani casti nebo cele palety
// 07h - predavani zmenenych casti obrazu
// 0Dh - vymaze obrazovku
// 0Fh - cela obrazovka v RLE
// 10h - nekomprimovana kopie cele obrazovky
// nasleduji data akce
} actionheader;
char frame_buffer [307200];
char *flc_buffer;
void Get_first_frame (void);
void Get_next_frame (void);
void Decompress_frame (void);
#endif

54
ZVUK/ANALYSE/PLAY.C Normal file
View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include "flc.h"
flcheader h_flc;
frameheader h_frame;
actionheader h_action;
void main (int argc, char *argv[])
{
FILE *flc;
long pozice;
int frames, actions, x, y;
flc = fopen (argv[1], "rb");
fread (&h_flc, sizeof(flcheader), 1, flc);
frames=h_flc.frames;
printf ("\nHlavicka FLC souboru %s:\n", argv[1]);
printf ("Delka celeho souboru: %d\n", h_flc.size);
printf ("Pocet frame: %d\n", h_flc.frames);
printf ("Velikost filmu: %dx%d\n", h_flc.width, h_flc.height);
printf ("Hloubka barvy: %d\n", h_flc.color);
printf ("Rychlost prehravani: %d fps\n", 1000/h_flc.speed);
printf ("Offset prvniho frame: %d\n", h_flc.offset1);
fseek (flc, h_flc.offset1, SEEK_SET);
for (x=0; x<=(frames-1); x++)
{
fread (&h_frame, sizeof(frameheader), 1, flc);
actions=h_frame.actions;
printf ("\nHlavicka %d framu:\n", x+1);
printf ("Velikost framu: %d\n", h_frame.size);
printf ("Pocet akci ve framu: %d\n", h_frame.actions);
for (y=0; y<=(actions-1); y++)
{
pozice = ftell (flc);
fread (&h_action, sizeof(actionheader), 1, flc);
fseek (flc, (pozice+h_action.size), SEEK_SET);
printf ("\nHlavicka %d akce:\n", y+1);
printf ("Velikost dat pro tuto akci: %d\n", h_action.size);
printf ("Kod akce: %x\n", h_action.code);
}
getch ();
_clearscreen (_GCLEARSCREEN);
}
fclose (flc);
}

296
ZVUK/ANALYSE/VESA.C Normal file
View file

@ -0,0 +1,296 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "vesa.h"
#include "dosmem.h"
extern void wm_ChangeBank_(int bank);
#pragma aux (ASM) wm_ChangeBank_;
void Set_VESA_mode (int mode)
{
union REGS r;
r.w.ax=0x4f02;
r.w.bx=mode;
int386 (0x10, &r, &r);
}
void Show_screen (char *display)
{
wm_ChangeBank_ (0);
memmove (0xa0000, display, 65536);
wm_ChangeBank_ (1);
memmove (0xa0000, (display+65536), 65536);
wm_ChangeBank_ (2);
memmove (0xa0000, (display+131072), 65536);
wm_ChangeBank_ (3);
memmove (0xa0000, (display+196608), 65536);
wm_ChangeBank_ (4);
memmove (0xa0000, (display+262144), 45056);
}
void Put_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
break;
};
}
}
void Get_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
break;
};
}
}
void Get_VESA_info (void)
{
char far *str;
VESA_INFO_BLOCK *p;
p=(VESA_INFO_BLOCK *)mem_alloc(sizeof(VESA_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS));
dpmiregs.EAX=0x00004f00;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaInfoBlock,str,sizeof(VESA_INFO_BLOCK));
mem_free(p);
if(dpmiregs.EAX!=0x4f)
{
printf ("VESA Bios extension not found!!!!");
exit (1);
}
}
void Get_mode_info (int mode)
{
char far *str;
VESA_MODE_INFO_BLOCK *p;
p=(VESA_MODE_INFO_BLOCK *)mem_alloc(sizeof(VESA_MODE_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS)); //nuluje registry
dpmiregs.EAX=0x00004f01;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
dpmiregs.ECX=mode;
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaModeInfoBlock,str,sizeof(VESA_INFO_BLOCK));
_VGAGran=VesaModeInfoBlock.WinGranularity;
mem_free(p);
}

70
ZVUK/ANALYSE/VESA.H Normal file
View file

@ -0,0 +1,70 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#ifndef __VESA_H
#define __VESA_H
typedef struct
{ char VESASignature[4];
short VESAversion;
unsigned OEMStringPtr;
char capabilities[4];
short int *videomodeptr;
short int TotalMemory;
char dummy[236];
} VESA_INFO_BLOCK;
typedef struct
{ short unsigned ModeAttributes;
char WinAAttributes;
char WinBAttributes;
short unsigned WinGranularity;
short unsigned WinSize;
short unsigned WinASegment;
short unsigned WinBSegment;
short unsigned WinFuncPtroff;
short unsigned WinFuncPtrseg;
short unsigned BytesPerScanLine;
short unsigned XResolution;
short unsigned YResolution;
char Xcharsize;
char Ycharsize;
char NumberOfPlanes;
char BitsPerPixel;
char NumberOfBanks;
char MemoryModel;
char BankSize;
char NumberOfImagePages;
char Reserved;
char RedMaskSize;
char RedFieldPosition;
char GreenMaskSize;
char GreenFieldPosition;
char BlueMaskSize;
char BlueFieldPosition;
char RsvdMaskSize;
char DirectColorModeInfo;
char Dummy[216];
} VESA_MODE_INFO_BLOCK;
VESA_MODE_INFO_BLOCK VesaModeInfoBlock;
VESA_INFO_BLOCK VesaInfoBlock;
extern unsigned char _VGAPage=0;
extern unsigned char _VGAGran=0;
void Set_VESA_mode (int mode);
void Show_screen (char *display);
void Get_VESA_info (void);
void Get_mode_info (int mode);
void Put_image (int x, int y, int xlen, int ylen, char *image);
void Get_image (int x, int y, int xlen, int ylen, char *image);
#endif

63
ZVUK/ANALYSE/VESA_.ASM Normal file
View file

@ -0,0 +1,63 @@
;EAX EDX EBX ECX
.386p
jumps
;############################################################################
; Constanty
;############################################################################
dlt_x equ 640
dlt_y equ 480
;############################################################################
; Datovy segment
;############################################################################
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
align 4
EXTRN __VGAPage:BYTE
EXTRN __VGAGran:BYTE
_DATA ENDS
DGROUP GROUP _DATA
;############################################################################
; Kodovy segment
;############################################################################
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME cs:_TEXT, ds:_DATA
public wm_ChangeBank__
wm_ChangeBank__ PROC
push es
pushad
push eax
mov edx, eax
mov ebx, 0000h
mov eax, 4f05h
int 10h
pop eax
mov edx, eax
mov ebx, 0001h
mov eax, 4f05h
int 10h
popad
pop es
ret
wm_ChangeBank__ endp
;----------------------------------------------------------------------------
_TEXT ENDS
END

71
ZVUK/DOSMEM.C Normal file
View file

@ -0,0 +1,71 @@
/*********************************************/
/*** DOS memory allocation - DOSMEM.C ***/
/*** vykostena verze chlumakova memalloc.c ***/
/*********************************************/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosmem.h"
/*** Alokace pole v dolni pameti ***/
void *mem_alloc(int size)
{
static union REGS r;
MEMREC memrec;
r.x.eax=0x0100;
r.x.ebx=(size>>4)+1;
size=r.x.ebx<<4;
int386(0x31,&r,&r);
if (r.x.cflag)
{
printf ("No fucking DOS memory left!!!");
exit(1);
}
memrec.ptr=(void *)((r.x.eax&0xFFFF)<<4);
Selector=memrec.selector=(short int)r.x.edx;
return memrec.ptr;
}
/*** Uvolneni dolni pameti ***/
void mem_free(void *ptr)
{
union REGS r;
if(ptr!=NULL)
{
r.x.eax=0x0101;
r.x.edx=Selector;
int386(0x31,&r,&r);
if(r.x.cflag)
printf("Cannot free DOS memory!!!!");
}
}
/*** Vyvolani preruseni pomoci protected modu ***/
void WtNs386(int IntNum, DPMIREGS *dpmiregs)
{
union REGS r;
struct SREGS sr;
r.w.ax=0x300;
r.h.bl=(char)IntNum;
r.h.bh=0;
r.w.cx=0;
segread(&sr);
sr.es=FP_SEG(dpmiregs);
r.x.edi=FP_OFF(dpmiregs);
int386x(0x31,&r,&r,&sr);
}

46
ZVUK/DOSMEM.H Normal file
View file

@ -0,0 +1,46 @@
/************************************/
/*** Hlavickovt soubor k DOSMEM.H ***/
/************************************/
typedef enum
{ DOS_MEMORY,
NEW,
} MEMORY_ITEMS;
typedef struct
{ int EDI;
int ESI;
int EBP;
int reserved;
int EBX;
int EDX;
int ECX;
int EAX;
short int Flags;
short int ES;
short int DS;
short int GS;
short int IP;
short int CS;
short int SP;
short int SS;
} DPMIREGS;
typedef struct
{ void *ptr;
int size;
int selector; //smysl jen u DOS_MEMORY
} MEMREC;
#define D32RealSeg(P) ((((unsigned int)(P))>>4)&0xFFFF)
#define D32RealOff(P) (((unsigned int)(P))&0xF)
int Selector;
DPMIREGS dpmiregs;
void *mem_alloc(int size);
void mem_free(void *ptr);
void WtNs386(int IntNum, DPMIREGS *dpmiregs);

67
ZVUK/EXAMPLE.ASM Normal file
View file

@ -0,0 +1,67 @@
.model small
.386
DGROUP group _DATA
tchannel struct
PLAYPOS DD ?
STARTLOOP DD ?
ENDLOOP DD ?
SPEEDMAJ DD ?
SPEEDMIN DW ?
MINORPOS DW ?
SMPTYPE DW ?;0 - DISABLED, 1 - 8 BIT, 2 - 16 BIT
VOLUMELEFT DW ?
VOLUMERIGHT DW ?
tchannel ends
extrn _chaninfo:dword
extrn _mixbuffer:dword
extrn _backsnd:dword ;ukazatel na buffer s hudbou na pozadi (64Kb)
extrn _backstep:dword ;krok o kolik se meni _backsnd
extrn _backsndbuff:dword ;buffer hudby na pozadi
extrn _jumptable:dword[3] ;[0] - skip, [1] - mix8, [2] - mix16
extrn _getdma:dword
extrn _ido:dword
extrn _predstih:word
extrn _lastdma:dword
extrn _lastmix:dword
extrn _surpos:dword
extrn _mixpos:dword
extrn _mixsize:dword
extrn _dmaposadr:dword
extrn _dpmiselector:word
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
PUBLIC _MIXER
_MIXER: ;THIS IS MAIN MIXING PROCEDURE.
;BEFORE USING, YOU MUST SET UP ALL VARIBLES TO THE CORRECT VALUES.
;_MIXBUFFER MUST START ON PAGE OF MEMORY (EXP 0x10000 0x20000 0x30000)
;PROCEDURE MUST BE CALLED EACH 18ms OR LITTLE.
;IF YOU USING INTERRUPT, REMEBER, THAT YOU MUST STORE ALL REGISTERS
;BEFORE USE.
; CALL calcsize ;VYPOCET DELKY MIXOVANI
mov edi,_mixpos ;Nejprve se vymaze mixovaci pamet
mov ecx,_mixsize
shr ecx,2
xor eax,eax
MIXCLR: mov [edi],eax
add di,4
dec ecx
jnz MIXCLR
mov ebx,_chaninfo ;TED SE ZACNE MIXOVAT
MIXING: xor eax,eax
mov ax,[ebx]offset tchannel.smptype
_TEXT ends
end

176
ZVUK/FLC.C Normal file
View file

@ -0,0 +1,176 @@
//
// Knihovna pro dekompresi FLC souboru
//
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include <i86.h>
#include "flc.h"
void Open_FLC (char *filename)
{
flc = fopen (filename, "rb");
fread (&h_flc, sizeof(flcheader), 1, flc);
}
void Close_FLC (void)
{
fclose (flc);
free (flc_buffer);
}
void Get_first_frame (void)
{
fseek (flc, h_flc.offset1, SEEK_SET);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Get_next_frame (void)
{
free (flc_buffer);
fread (&h_frame, sizeof(frameheader), 1, flc);
flc_buffer = (char*)malloc((h_frame.size-sizeof(frameheader)));
fread (flc_buffer, (h_frame.size-sizeof(frameheader)), 1, flc);
}
void Decompress_frame (void)
{
unsigned short x,y,z,w;
unsigned short changes, nfo_word, packets, offset, row;
int frame_pos=0;
unsigned int scr_pos;
char c1, c2, c3, a;
char hi, lo;
for (z=1; z<=h_frame.actions; z++)
{
memmove ( &h_action, (flc_buffer+frame_pos), sizeof(actionheader) );
switch (h_action.code)
{
case 4:
a=1;//fcl_buffer[frame_pos];
// b=0;//flc_buffer[frame_pos];
// c=256; //0=256
frame_pos+=10;
outp (0x3c8, 0);
for (x=0; x<=768; x++) outp (0x3c9, (flc_buffer[(x+frame_pos)]/=4) );
frame_pos+=768;
break;
case 7:
frame_pos+=6;
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos]; frame_pos++;
changes=hi*256+lo;
row=0;
for (y=0; y<=(changes-1); y++) // pocet menenych radek
{
lo=flc_buffer[frame_pos]; frame_pos++;
hi=flc_buffer[frame_pos]; frame_pos++;
nfo_word=hi*256+lo;
scr_pos=row*h_flc.width;
if (nfo_word>=0xC000) // preskakovane radky
{
nfo_word=0xFFFF-nfo_word+1;
row+=nfo_word;
}
else
{
for (z=1; z<=nfo_word; z++) // pocet menenych bloku
{
x=1; a=0;
offset = flc_buffer[frame_pos]; // rel. offset bloku
frame_pos++;
scr_pos+=offset;
// while (!a) // zmena bloku
// {
c1 = flc_buffer[frame_pos];
frame_pos++;
if (c1>128)
{
c1=0xFF-c1+1;
c2=flc_buffer[frame_pos];
frame_pos++;
c3=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
frame_buffer[scr_pos]=c3;
scr_pos++; }
}
else
{
// c3=0xFF-c3+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++;
frame_buffer[scr_pos]=flc_buffer[frame_pos];
frame_pos++;
scr_pos++; }
}
// if (x>=640) a=1;
// }
}
row++;
}
}
// frame_pos+=h_action.size;
break;
case 15:
frame_pos+=6;
for (y=0; y<=(h_flc.height-1); y++)
{
frame_pos++; x=1; //a=0;
scr_pos=y*h_flc.width;
while (x<=h_flc.width)
{
c1 = flc_buffer[frame_pos];
frame_pos++;
if (c1<128)
{
c2=flc_buffer[frame_pos];
frame_pos++;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=c2;
scr_pos++;
x++; }
}
else
{
c1=0xFF-c1+1;
for (w=1; w<=c1; w++)
{ frame_buffer[scr_pos]=flc_buffer[frame_pos];
scr_pos++;
frame_pos++;
x++; }
}
}
}
break;
default: frame_pos+=h_action.size;
break;
};
}
}

61
ZVUK/FLC.H Normal file
View file

@ -0,0 +1,61 @@
//
// Hlavickovy soubor ke knihovne FLC.C slouzici k dekompresi FLC
//
#ifndef _FLC_H
#define _FLC_H
typedef struct FLCHEADER {
unsigned int size; // delka souboru vcetne hlavicky
unsigned short idflc; // ID FLC=0AF12h
unsigned short frames; // pocet frejmu
unsigned short width; // sirka vsech obrazku
unsigned short height; // vyska vsech obrazku
unsigned short color; // hloubka barvy (bpp)
unsigned short flag1;
unsigned int speed; // rychlost prehravani (v 1/1000 s)
unsigned short reserv1; // rezervovany
unsigned int date1; // datum a cas vytvoreni
unsigned int serial; // seriove cislo programu
unsigned int date2; // datum a cas posledni zmeny
unsigned short XA;
unsigned short YA;
char reserv2 [42]; // rezervovano
unsigned int offset1; // offset prvniho frame
unsigned int offset2; // offset druheho frame
char reserv3 [40]; // rezervovano
} flcheader;
typedef struct FRAMEHEADER {
unsigned int size; // velikost frame v bytech
unsigned short sign; // znacka frame OFAF1h
unsigned short actions; // pocet akci v tomto frame
char reserv [8]; // rezervovano
} frameheader;
typedef struct ACTIONHEADER {
unsigned int size; // velikost akce v bytech
unsigned short code; // kod akce
// 04h - predani casti nebo cele palety
// 07h - predavani zmenenych casti obrazu
// 0Dh - vymaze obrazovku
// 0Fh - cela obrazovka v RLE
// 10h - nekomprimovana kopie cele obrazovky
// nasleduji data akce
} actionheader;
FILE *flc;
flcheader h_flc;
frameheader h_frame;
actionheader h_action;
char frame_buffer [307205];
char *flc_buffer;
//unsigned int ladici;
void Open_FLC (char *filename);
void Close_FLC (void);
void Get_first_frame (void);
void Get_next_frame (void);
void Decompress_frame (void);
#endif

54
ZVUK/PLAY.C Normal file
View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <conio.h>
#include <graph.h>
#include <dos.h>
#include "flc.h"
#include "vesa.h"
void Set_TEXT_mode (void);
void main (int argc, char *argv[])
{
int x;
Open_FLC (argv[1]);
printf ("\nHlavicka FLC souboru %s:\n", argv[1]);
printf ("Delka celeho souboru: %d\n", h_flc.size);
printf ("Pocet frame: %d\n", h_flc.frames);
printf ("Velikost filmu: %dx%d\n", h_flc.width, h_flc.height);
printf ("Hloubka barvy: %d\n", h_flc.color);
// printf ("Rychlost prehravani: %d fps\n", 1000/h_flc.speed);
printf ("Offset prvniho frame: %d\n", h_flc.offset1);
getch ();
Set_VESA_mode (0x101);
delay (1000);
Get_first_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
for (x=2; x<=h_flc.frames; x++)
{
Get_next_frame ();
Decompress_frame ();
Show_screen (frame_buffer);
delay (7);
}
getch ();
Set_TEXT_mode ();
Close_FLC ();
}
void Set_TEXT_mode (void)
{
union REGS inr, outr;
inr.h.ah = 0x00;
inr.h.al = 03;
int386 (0x10, &inr, &outr);
}

254
ZVUK/SNDPACK.C Normal file
View file

@ -0,0 +1,254 @@
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define BLK_SIZE 8192
short ampl_table[256];
signed short source[BLK_SIZE];
char target[BLK_SIZE];
long sfreq;
unsigned short chans;
FILE *sf,*tf;
char *nsource;
char *ntarget;
long ssize;
long rsize,blck;
char difftype=4;
void Create_table_16()
{
int a,c,d,e;
float b;
d=-1;e=0;
for(a=0;a<128;a++)
{
b=(a/128.0);
switch (difftype)
{
case 1:b=(b*32768.0);break;
case 2:b=(b*b*32768.0);break;
case 3:b=(b*b*b*32768.0);break;
case 4:b=(b*b*b*b*32768.0);break;
case 5:b=(b*b*b*b*b*32768.0);break;
}
c=(int)b;
if (c==d) e++;
d=c;c+=e;
ampl_table[128+a]=c;
ampl_table[128-a]=-c;
}
}
int find_index(int value)
{
int i;
if (value==0) return 128;
if (value>0)
{
for(i=128;i<256;i++)
if (ampl_table[i]>value) return i-1;
return 255;
}
else
{
for(i=128;i>=0;i--)
if (ampl_table[i]<value) return i+1;
return 1;
}
}
void compress_buffer_mono()
{
int i;
int last,val;
char indx;
last=0;
for(i=0;i<BLK_SIZE;i++)
{
val=source[i];
indx=find_index(val-last);
last+=ampl_table[indx];
target[i]=indx;
}
}
void compress_buffer_stereo()
{
int i;
int last1;
int last2,val;
char indx;
last1=0;
last2=0;
for(i=0;i<BLK_SIZE;i++)
{
if (i & 1)
{
val=source[i];
indx=find_index(val-last1);
last1+=ampl_table[indx];
if (last1>32768 || last1<-32768) abort();
target[i]=indx;
}
else
{
val=source[i];
indx=find_index(val-last2);
last2+=ampl_table[indx];
if (last2>32768 || last2<-32768) abort();
target[i]=indx;
}
}
}
void find_data()
{
char w[5]="data";
int i,d;
i=0;
do
{
d=fgetc(sf);
if (d==w[i]) i++;else i=0;
if (d==EOF) abort();
}
while (i<4);
}
void open_files()
{
int i=0;
sf=fopen(nsource,"rb");
tf=fopen(ntarget,"wb");
if (sf==NULL || tf==NULL) abort();
fseek(sf,0x16,SEEK_SET);
fread(&chans,1,2,sf);
fread(&sfreq,1,4,sf);
find_data();
fread(&ssize,1,4,sf);
rsize=ssize;
blck=rsize/sizeof(source);
fwrite(&chans,1,2,tf);
fwrite(&sfreq,1,4,tf);
fwrite(&ssize,1,4,tf);
fwrite(&blck,1,4,tf);
fwrite(&i,1,4,tf);
fwrite(&i,1,4,tf);
fwrite(&ampl_table,1,sizeof(ampl_table),tf);
}
int read_buffer()
{
int l;
if (rsize>sizeof(source)) l=sizeof(source); else l=rsize;
rsize-=l;
memset(source,0,sizeof(source));
return fread(source,1,l,sf);
}
void write_buffer()
{
int i,j;
i=sizeof(target);
j=sizeof(source);
fwrite(&i,1,sizeof(i),tf);
fwrite(&j,1,sizeof(j),tf);
fwrite(target,1,sizeof(target),tf);
}
void timestate(int tim3,int tim4)
{
if (tim3<0) tim3=0;
tim3/=CLOCKS_PER_SEC;
tim4/=CLOCKS_PER_SEC;
cprintf("Packing time: %02d:%02d Remainig: %02d:%02d ",tim4/60,tim4%60,tim3/60,tim3%60);
}
void pack()
{
long size;
int i,j,pt;
long tim1,tim2,tim3,tim4;
pt=(ssize/(2*chans))/sfreq;
cprintf("\n\r"
"Packing sample : %s --> %s\n\r"
"Lenght : %10d KB\n\r"
"Total blocks : %10d blocks \n\r"
"Sample freq. : %10d Hz\n\r"
"Sample type : 16-bit %s\n\r"
"Aproximation : %10d \n\r"
"Playing time : %02d:%02d\n\r",
nsource,ntarget,ssize/1024,blck,sfreq,chans==1?"mono":"stereo",difftype,pt/60,pt%60);
timestate(88*60+88,88*60+88);
for (i=0;i<40;i++) putch('.');
putch('\r');
tim1=clock();
do
{
size=read_buffer();
if (chans==1) compress_buffer_mono();
else compress_buffer_stereo();
j=ftell(sf)*40/ssize;
putch('\r');
tim2=clock();
tim3=(tim2-tim1);
tim4=(int)((((float)ssize/ftell(sf))*tim3));
tim3=tim4-tim3;
timestate(tim3,tim4);
for(i=0;i<j;i++) putch(254);
write_buffer();
}
while (rsize);
cprintf("\n\r"
"Final lenght : %10d KB\n\r"
,ftell(tf)/1024);
}
void shutdown()
{
fclose(tf);
fclose(sf);
}
main(int argc,char **argv)
{
cprintf("\nBredy's differencial sample packer for 16-bit samples\n\r"
"Packing ratio is always 50%%. Packed sample doesn't identical\n\r"
"with original, but there are very little differences.\n\r"
"(C)1997 by Bredy.\n\r");
if (argc<3)
{
cprintf("\nUsage: SNDPACK source.wav target.mus [dt]\n\n\r"
" dt - type of aproximation. its means:\n\r"
" dt = 1: linear (bad quality) \n\r"
" dt = 2: xý\n\r"
"generaly dt = n: xü\n\r"
" dt must be in 0 < dt < 6. Default value for dt is 4\n\n\r");
exit(0);
}
nsource=argv[1];
ntarget=argv[2];
if (argc==4) sscanf(argv[3],"%d",&difftype);
Create_table_16();
open_files();
pack();
shutdown();
}

74
ZVUK/SPK_TEST.C Normal file
View file

@ -0,0 +1,74 @@
/*
PCSPEAKER TESTING
Tento program testuje knihovnu PCSPEAK.ASM.
Program alokuje 64Kb v dolni casti pameti. Pote zacne tento blok prehravat
stale dokola rychlosti 16000 Hz. Prehrava se nahodny obsah, takze by mel byt
slyset nejakej sum nebo neco podobneho.
*/
#include <stdio.h>
#include <conio.h>
#include <pcspeak.h>
#include <i86.h>
UWORD seg; //Segment bufferu
UWORD sel; //Selector na buffer
//Funkce pro alokaci v dolni casti pameti.
// Alloc dos memory
void dosalloc (unsigned para,unsigned short *rmseg,unsigned short *select)
{
union REGS regs;
regs.w.ax = 0x100;
regs.w.bx = para;
int386 (0x31,&regs,&regs);
*rmseg = regs.w.ax;
*select = regs.w.dx;
}
//Funkce pro uvolneni v dolni casti pameti.
// Free dos memory
void dosfree (unsigned short select)
{
union REGS regs;
regs.w.ax = 0x101;
regs.w.dx = select;
int386 (0x31,&regs,&regs);
}
void alloc_buffer() //nejprve se zaalokuje buffer
{
dosalloc(65536/16,&seg,&sel);
}
void dealloc_buffer() //dealokace
{
dosfree(sel);
}
void speaker_test()
{
puts("Init...");
rm_proc_set(seg,sel,PORT_SPK,SPK_MODE);//Nastav rm_proc
load_rm_proc(); //nahraj rm_proc do dolni pameti
pc_speak_enable(); //PCSPEAKER do modu DAC (pokud se hraje na spk)
pc_speak_run(19000,18); //Zacni prehravat buffer (18Hz emulacni frekvence)
puts("Running...");
getche(); //cekej na klavesu
puts("Stopping...");
pc_speak_stop(); //Zastav prehravani
pc_speak_disable(); //PCSPEAKER vrat do normalniho rezimu
purge_rm_proc(); //vymaz rm_proc z dolni pameti
puts("Ending...");
}
void main()
{
alloc_buffer(); //Alokuj buffer
speaker_test(); //Test
dealloc_buffer(); //Dealokuj buffer
}

834
ZVUK/TRACK.C Normal file
View file

@ -0,0 +1,834 @@
#include <stdio.h>
#include <zvuk.h>
#include <conio.h>
#include <mem.h>
#include <stdlib.h>
#include <bios.h>
#include <dos.h>
#include <i86.h>
#include <strlite.h>
#include <memman.h>
#define SCRADR 0xb8000
#define SCRSIZE (80*25*2)
#define SCRLLEN 80
#define VOL_BLOCK (bfreq/44)
#define BVSTEP 2350
extern char backsndbuff[BACK_BUFF_SIZE];
extern volatile long backsnd;
extern volatile long backstep;
extern volatile int backfine;
extern int bfreq,bblocks,bvolume;
extern FILE *bsnd;
extern unsigned short bchans;
extern long blength;
extern int bblock_size;
extern int device;
extern int devport;
char manual_refresh=0;
int get_playing_time(char *filename)
{
open_backsound(filename);
fclose(bsnd);
if (blength!=-1) return (bblocks*bblock_size)/(bfreq*bchans);else return 0;
}
TSTR_LIST read_dir(char *mask,int attrs)
{
TSTR_LIST flist;
int index=0;
char c[80];
struct find_t s;
int rc;
int doba;
flist=create_list(256);
if (flist==NULL) return flist;
rc=_dos_findfirst(mask,attrs,&s);
while (rc==0)
{
char d[13],*p;
int i=0,j;
if (attrs==_A_NORMAL || s.attrib & attrs)
{
p=&d;d[12]='\0';
while (s.name[i]!='.' && s.name[i]!='\0' ) *p++=s.name[i++];
if (s.name[i]!='\0') j=i+1;else j=i;
while (i<8)
{
*p++=32;i++;
}
i=3;
*p++='.';
while (s.name[j]!='\0')
{
*p++=s.name[j++];
i--;
}
while (i>0)
{
*p++=32;
i--;
}
doba=get_playing_time(s.name);
sprintf(c,"%s %02d:%02d",d,doba/60,doba%60);
if (str_replace(&flist,index++,c)==NULL)
{
release_list(flist);
return NULL;
}
}
rc=_dos_findnext(&s);
}
sort_list(flist,-1);
str_delfreelines(&flist);
return flist;
}
void name_conv(char *c)
{
char *a,*b,cn,cd;
a=c;b=c;
cn=4;cd=0;
for(;*a && cn;a++,cn-=cd)
{
if (*a!=32) *b++=*a;
if (*a=='.') cd=1;
}
*b--='\0';
if (*b=='.') *b='\0';
}
long music_size;
int block_size;
int block_max;
int vybrano=0;
int posledni=-1;
char error=0;
typedef char TDIGIT[10];
TSTR_LIST adresar;
char istr[300];
char pause=0;
unsigned short *screen;
TDIGIT digits[15]=
{ "ÛßÛ"
"Û Û"
"ßßß",
" Û"
" Û"
" ß",
"ßßÛ"
"Ûßß"
"ßßß",
"ßßÛ"
"ßßÛ"
"ßßß",
"Û Û"
"ßßÛ"
" ß",
"Ûßß"
"ßßÛ"
"ßßß",
"Ûßß"
"ÛßÛ"
"ßßß",
"ÛßÛ"
"ß Û"
" ß",
"ÛßÛ"
"ÛßÛ"
"ßßß",
"ÛßÛ"
"ßßÛ"
"ßßß",
" Ü "
" Ü "
" ",
" "
"ßßß"
" "
};
void load_font(char *font,int start,int count);
#pragma aux load_font =\
"cli"\
"mov edx,3c4h"\
"mov eax,0402h"\
"out dx,ax"\
"mov eax,0704h"\
"out dx,ax"\
"Mov edx,3ceh"\
"mov eax,0204h"\
"out dx,ax"\
"mov eax,0005h"\
"out dx,ax"\
"mov ax,0406h"\
"out dx,ax"\
"shl ecx,5"\
"mov edx,edi"\
"mov edi,0a0000h"\
"add edi,ecx"\
"Opk: mov ecx,4"\
"rep movsd"\
"add edi,16"\
"dec edx"\
"jne opk"\
"mov edx,3c4h"\
"mov eax,0302h"\
"out dx,ax"\
"mov eax,0304h"\
"out dx,ax"\
"mov edx,3ceh"\
"mov eax,0004h"\
"out dx,ax"\
"mov eax,1005h"\
"out dx,ax"\
"mov eax,0E06h"\
"out dx,ax"\
"sti"\
parm [ESI][ECX][EDI] modify [EDX EAX];
void font_effekt1();
#pragma aux font_effekt1 =\
"mov ecx,32"\
"mov edi,127"\
"mov edx,3c4h"\
"mov eax,0402h"\
"out dx,ax"\
"mov eax,0704h"\
"out dx,ax"\
"Mov edx,3ceh"\
"mov eax,0204h"\
"out dx,ax"\
"mov eax,0005h"\
"out dx,ax"\
"mov ax,0406h"\
"out dx,ax"\
"shl ecx,5"\
"mov edx,edi"\
"mov esi,0a0000h"\
"mov edi,0a4000h"\
"push ecx"\
"mov ecx,2000h"\
"rep movsb"\
"pop ecx"\
"mov edi,0a4000h"\
"add edi,ecx"\
modify [EDX EAX ESI ECX EDI];
void font_effekt2();
#pragma aux font_effekt2 =\
"Opk: mov al,0ffh"\
"stosb"\
"add edi,14"\
"stosb"\
"add edi,16"\
"dec edx"\
"jne opk"\
"mov edx,3c4h"\
"mov eax,0302h"\
"out dx,ax"\
"mov eax,0304h"\
"out dx,ax"\
"mov edx,3ceh"\
"mov eax,0004h"\
"out dx,ax"\
"mov eax,1005h"\
"out dx,ax"\
"mov eax,0E06h"\
"out dx,ax"\
modify [EDX EAX ESI ECX EDI];
void font_effekt()
{
font_effekt1();
font_effekt2();
}
#pragma aux dve_sady modify [EAX EBX EDX]=\
"mov ebx,1"\
"mov eax,1103h"\
"int 10h"\
"cli"\
"mov edx,3d4h"\
"mov eax,0100h"\
"out dx,ax"\
"mov edx,3c4h"\
"mov al,1"\
"out dx,al"\
"inc edx "\
"in al,dx "\
"or al,1"\
"out dx,al"\
"mov edx,03dah"\
"in al,dx"\
"mov edx,03c0h"\
"mov al,13h"\
"out dx,al"\
"mov al,0"\
"out dx,ax"\
"mov al,32"\
"out dx,al"\
"mov edx,3d4h"\
"mov eax,0300h"\
"out dx,ax"\
"sti"\
void dve_sady();
void set_palcolor(int index,int r,int g,int b);
#pragma aux set_palcolor parm [ebx][edx][eax][ecx]=\
"mov ch,al"\
"mov dh,dl"\
"mov eax,1010h"\
"int 10h"
void def_fbars()
{
char f_bars[8][16];
int i,j;
memset(f_bars,0,sizeof(f_bars));
for(i=0;i<8;i++)
for(j=0;j<=i;j++)
f_bars[7-i][15-j*2]=255;
load_font(f_bars,192,8);
for(i=0;i<16;i++) f_bars[0][i]=1;
for(i=0;i<16;i++) f_bars[1][i]=192;
for(i=0;i<16;i++) f_bars[2][i]=255*(i>13);
load_font(f_bars,200,3);
}
void disp_digit(int x,int y,char num)
{
unsigned short *adr;
char *c;
adr=screen+y*SCRLLEN+x;
c=&digits[num];
for(y=0;y<3;y++,adr+=SCRLLEN-3)
for(x=0;x<3;x++) *(char *)(adr++)=*c++;
}
void clear_window(int x1,int y1,int x2,int y2,int color)
{
int x,y;
unsigned short *adr;
color<<=8;color+=32;
for(y=y1;y<=y2;y++)
{
adr=screen+y*SCRLLEN;
for(x=x1;x<=x2;x++)
adr[x]=color;
}
}
void disp_str(int x,int y,char *c,int color)
{
unsigned short *adr;
adr=screen+y*SCRLLEN+x;
while (*c) *adr++=*(c++)+(color<<8);
}
void disp_vbar_track(int x,int y,int step)
{
unsigned short *adr;
int drw=0;char cl;
adr=screen+y*SCRLLEN+x;
while (drw<32768)
{
cl=15;
drw+=step;
adr[0]=200+(cl<<8);
adr[3]=201+(cl<<8);
adr-=SCRLLEN;
}
}
void disp_bnum(int x,int y,int num,int dgs)
{
char sgn;
sgn=num<0;num=abs(num);
while (dgs>0 || num>0)
{
disp_digit(x,y,num%10);
num/=10;dgs--;
x-=4;
}
if (sgn) disp_digit(x,y,11);
}
void disp_chan(int x,int y,int value,int step)
{
unsigned short *adr;
int drw=0;char cl;
adr=screen+y*SCRLLEN+x;
while (drw<32768)
{
if (drw>=value) cl=0;
else if (drw>24660) cl=12;
else if (drw>16384) cl=14;
else cl=10;
drw+=step;
if (drw>value && cl>0)
*adr=192+8*(drw-value)/step+(cl<<8);
else
*adr=192+(cl<<8);
adr-=SCRLLEN;
}
*adr=202+(15<<8);
}
void init(int a,int b,int c,int d)
{
screen=(unsigned short *)SCRADR;
clear_window(0,0,79,24,15);
disp_str(0,0,"Output Device:",9);
disp_str(0,1,"Parameters:",9);
disp_str(0,3,"Track name:",9);
disp_str(0,4,"Mode:",9);
disp_str(0,5,"Blocks:",9);
disp_str(0,6,"Size:",9);
disp_str(0,7,"Playing time:",9);
if (a==-1)
if (sound_detect(&a,&b,&c,&d))
{
disp_str(16,0,"No sound device found",14);
exit(1);
}
set_mixing_device(a,22050,b,c,d);
disp_str(16,0,device_name(a),14);
if (a>=DEV_SB10 && a<=DEV_ULTRA)
{
sprintf(istr,"port %03X dma %1d irq %1X",b,c,d);
disp_str(16,1,istr,13);
}
clear_window(50,0,79,3,30);
clear_window(50,4,79,7,4*16+15);
}
void open_files(char *filename,char fade)
{
long total;
char spaces[50];
memset(spaces,32,50);spaces[30]=0;
if (bsnd!=NULL)fclose(bsnd);
if (filename!=NULL)if (fade) change_music(filename);else open_backsound(filename);
else blength=-1;
music_size=blength;
block_size=bblock_size;
disp_str(16,3,spaces,12);
error=0;
if (music_size==-1)
{
disp_str(16,3,"Track NOT found",12);
block_size=1;
bchans=1;
bfreq=1;
bblocks=0;
error=1;
}
else disp_str(16,3,filename,12);
if (bchans==1)
sprintf(istr,"16-bit mono %5d Hz ",bfreq);
else
sprintf(istr,"16-bit stereo %5d Hz",bfreq);
disp_str(16,4,istr,11);
sprintf(istr,"%05d",bblocks);
disp_str(16,5,istr,10);
sprintf(istr,"%05d KB",music_size/1024);
disp_str(16,6,istr,15);
total=(bblocks*block_size)/(bfreq*bchans);
sprintf(istr,"%02d:%02d",total/60,total%60);
disp_str(16,7,istr,14);
block_max=bblocks;
}
void display_time(int bblocks)
{
long time,b;
if (error)
{
disp_bnum(76,1,88,2);
disp_digit(68,1,10);
disp_bnum(64,1,88,2);
}
else
{
b=bblocks+128*1024/block_size;
if (b>block_max) b-=block_max;
time=(b*block_size)/(bfreq*bchans);
disp_bnum(76,1,time%60,2);
disp_digit(68,1,10);
disp_bnum(64,1,time/60,2);
}
}
void display_bblocks(int bblocks)
{
long b;
if (error)
disp_bnum(76,5,88888,5);
else
{
b=bblocks+128*1024/block_size;
if (b>block_max) b-=block_max;
disp_bnum(76,5,b,5);
}
}
void volume_bars(int *left,int *right)
{
int i,k,l,r;
static last=0;
static sl,sr;
r=backsnd-last;
if (r<0) r+=BACK_BUFF_SIZE/4;
if (r>VOL_BLOCK)
{
*left=sl;
*right=sr;
sr-=1000;
sl-=1000;
last=backsnd;
for(i=0;i<VOL_BLOCK;i++)
{
k=backsnd+i;
if (k>=BACK_BUFF_SIZE/4) k-=BACK_BUFF_SIZE/4;;
l=*((short *)backsndbuff+k*2);
r=*((short *)backsndbuff+k*2+1);
if (l>sl)
sl=l;
if (r>sr)
sr=r;
}
}
}
char retrace()
//vraci stav kresliciho paprsku na obrazovce
{
return (((~inp(0x3da)) & 8)>>3);
}
void wait_retrace()
//ceka na zpetny chod
{
while (!retrace());
while (retrace());
}
void disp_volume()
{
disp_chan(77,23,bvolume*64,BVSTEP);
disp_chan(78,23,bvolume*64,BVSTEP);
disp_vbar_track(76,23,BVSTEP);
}
void show_dir(int sel_file,int playing)
{
int cn=str_count(adresar);
int i=sel_file-5;
char spaces[32];
int color;
memset(spaces,32,32);
spaces[31]=0;
for(;i<sel_file+5;i++)
{
if (sel_file==i) color=3+(playing==i?2:0);
else color=9+(playing==i?2:0);
if (i<0 || i>=cn || adresar[i]==NULL)disp_str(3,i-sel_file+17,spaces,0);
else disp_str(3,i-sel_file+17,adresar[i],color);
}
color=3+(playing==sel_file?2:0);
disp_str(1,17," ",color);
disp_str(21,17," ",color);
disp_str(0,17,"È",color);
disp_str(23,17,"É",color);
}
void play_next(char **next)
{
posledni++;
if (posledni>=str_count(adresar)) posledni=0;
if (adresar[posledni]==NULL) posledni=0;
if (adresar[posledni]==NULL) {*next=NULL;posledni=0;}
else
{
static char c[50];
vybrano=posledni;
show_dir(vybrano,posledni);
strcpy(c,adresar[vybrano]);
name_conv(c);
open_files(c,0);
fclose(bsnd);
*next=c;
}
}
void set_new_position()
{
static int l=0,r=0;
int i=bblocks;
long c;
int delta1=5,delta2=1;
int volsave;
char zn,oldzn;
c=get_timer_value();
do
{
if (_bios_keybrd(_KEYBRD_READY))
switch (zn=_bios_keybrd(_KEYBRD_READ)>>8)
{
case 'M':i-=delta2;
if (i<0) i=0;
display_time(i);
c=get_timer_value();
delta1--;
break;
case 'K':i+=delta2;if (i>=block_max) i=block_max-1;
display_time(i);
c=get_timer_value();
delta1--;
break;
}
if (delta1<0)
{
delta1=5;
delta2++;
}
if (zn!=oldzn) delta2=1;
oldzn=zn;
display_bblocks(bblocks);
volume_bars(&l,&r);
mix_back_sound(0);
disp_chan(37,23,l,BVSTEP);
disp_chan(38,23,l,BVSTEP);
disp_chan(41,23,r,BVSTEP);
disp_chan(42,23,r,BVSTEP);
}
while (get_timer_value()-c<50);
if (i==bblocks) return;
volsave=get_snd_effect(SND_MUSIC);
set_snd_effect(SND_MUSIC,0);
set_snd_effect(SND_MUSIC,volsave);;
delta1=0;
if (i>bblocks && (i-bblocks)<(block_max-i))
{
fseek(bsnd,4,SEEK_CUR);
for(;bblocks<i;bblocks++)
{
fseek(bsnd,-(12+block_size),SEEK_CUR);
fread(&delta1,1,4,bsnd);
if (delta1!=block_size) break;
display_bblocks(bblocks);
}
fseek(bsnd,-4,SEEK_CUR);
}
if (i>bblocks) open_backsound(NULL);
for(;bblocks!=i;bblocks--)
{
fread(&delta1,1,4,bsnd);
fseek(bsnd,4+delta1,SEEK_CUR);
display_bblocks(bblocks);
}
}
extern int bxbass;
extern unsigned short predstih;
extern int dmatable[8][4];
extern char intr_test;
static void print_dma(int dma_num)
{
int i,j,k;
i=inp(dmatable[dma_num][0]);
j=inp(dmatable[dma_num][0]);
k=inp(dmatable[dma_num][2]);
cprintf("%04X %0X|",i+j*256,k);
}
static void print_all_dma()
{
int i;
static char negate;
for(i=0;i<8;i++) print_dma(i);
if (intr_test)
{
negate=!negate;
intr_test=0;
}
cprintf(" %c %d\r",negate?'*':' ',predstih);
}
void MIXER();
#pragma aux MIXER modify [eax ebx ecx edx esi edi];
char refresh()
{
static int l=0,r=0;
char *c;
int z;
mix_back_sound(0);
if (manual_refresh)
{
MIXER();
predstih=0x8000;
if (device==DEV_SB16)
{
int i;
i=inp(devport+0xf);
i=inp(devport+0xe);
}
}
else
{
display_bblocks(bblocks);
display_time(bblocks);
print_all_dma();
volume_bars(&l,&r);
disp_chan(37,23,l,BVSTEP);
disp_chan(38,23,l,BVSTEP);
disp_chan(41,23,r,BVSTEP);
disp_chan(42,23,r,BVSTEP);
}
if (error && adresar[0]!=NULL)
{
play_next(&c);
open_files(c,0);
}
while (_bios_keybrd(_KEYBRD_READY))
switch (_bios_keybrd(_KEYBRD_READ)>>8)
{
case 1:return 0;
case 'M':
case 'K': set_new_position();break;
case 0x39:if (pause) start_mixing(); else stop_mixing();
pause=!pause;
break;
case 0x17:set_snd_effect(SND_OUTFILTER,2);break;
case 'I': if (bvolume<512) bvolume+=4;
disp_volume();
break;
case 'Q': if (bvolume>3) bvolume-=4;else bvolume=0;
disp_volume();
break;
case 'G': if (check_snd_effect(SND_LSWAP))
{
z=get_snd_effect(SND_LSWAP);
z+=0xf;if (z>0xff) z=0xff;
set_snd_effect(SND_LSWAP,z);
}break;
case 'O': if (check_snd_effect(SND_LSWAP))
{
z=get_snd_effect(SND_LSWAP);
z-=0xf;if (z<0) z=0;
set_snd_effect(SND_LSWAP,z);
}
case 'H': if (vybrano>0)
{
vybrano--;show_dir(vybrano,posledni);
}break;
break;
case 'P': if (vybrano+1<str_count(adresar) && adresar[vybrano+1]!=NULL)
{
vybrano++;show_dir(vybrano,posledni);
}
break;
case ';':bxbass+=16;if (bxbass>256) bxbass=256;break;
case '<':bxbass-=16;if (bxbass<0) bxbass=0;break;
case 0x1c:if (adresar[vybrano]!=NULL)
{
char c[50];
posledni=vybrano;
show_dir(vybrano,posledni);
strcpy(c,adresar[vybrano]);
name_conv(c);
open_files(c,vybrano);
break;
}
}
return 1;
}
void restore_mode();
#pragma aux restore_mode=\
"mov eax,3"\
"int 10h"\
modify [eax];
main(int argc,char *argv[])
{
int a,b,c,d;
adresar=read_dir("*.mus",_A_NORMAL);
if (argc!=2 && argc!=6 && (argc!=1 || adresar[0]==NULL))
{
int i;
printf("\n\nUsage: TRACK trackname [device] [port] [dma] [irq] \n"
" or TRACK * [device] [port] [dma] [irq] - plays current directory."
"\n\nDevice numbers:\n");
for (i=0;i<7;i++) printf("%d. %s\n",i,device_name(i));
puts("\nIf you use character '~' (tilda) as trackname, it will have the same\n"
"effect as '*' so you will able to play sound background in WIN95\n"
"But the volume bars will not display correct values.");
exit(0);
}
if (argc==6)
{
sscanf(argv[2],"%d",&a);
sscanf(argv[3],"%x",&b);
sscanf(argv[4],"%d",&c);
sscanf(argv[5],"%d",&d);
}
else
a=-1;
if (argv[1][0]=='~') manual_refresh=1;
def_fbars();
//dve_sady();
//font_effekt();
set_palcolor(57,0,42,42);
set_palcolor(5,0,63,63);
init(a,b,c,d);
open_files(argv[1],0);
start_mixing();
disp_vbar_track(36,23,BVSTEP);
disp_vbar_track(40,23,BVSTEP);
disp_volume();
show_dir(0,1);
konec_skladby=play_next;
while (refresh());
stop_mixing();
clear_window(0,0,79,24,15);
restore_mode();
}

296
ZVUK/VESA.C Normal file
View file

@ -0,0 +1,296 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#include <dos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "vesa.h"
#include "dosmem.h"
extern void wm_ChangeBank_(int bank);
#pragma aux (ASM) wm_ChangeBank_;
void Set_VESA_mode (int mode)
{
union REGS r;
r.w.ax=0x4f02;
r.w.bx=mode;
int386 (0x10, &r, &r);
}
void Show_screen (char *display)
{
wm_ChangeBank_ (0);
memmove (0xa0000, display, 65536);
wm_ChangeBank_ (1);
memmove (0xa0000, (display+65536), 65536);
wm_ChangeBank_ (2);
memmove (0xa0000, (display+131072), 65536);
wm_ChangeBank_ (3);
memmove (0xa0000, (display+196608), 65536);
wm_ChangeBank_ (4);
memmove (0xa0000, (display+262144), 45056);
}
void Put_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((0xa0000+posunuti), (image+a*(xlen+1)+c), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((0xa0000+posunuti+c), (image+a*(xlen+1)+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((0xa0000+posunuti), (image+a*(xlen+1)), xlen);
break;
};
}
}
void Get_image (int x, int y, int xlen, int ylen, char *image)
{
int a,b,c,d;
long int posunuti=0;
int banka;
if (y<103) {wm_ChangeBank_ (0); banka=0;}
if (y>103 && y<205) {wm_ChangeBank_ (1); banka=1;}
if (y>205 && y<308) {wm_ChangeBank_ (2); banka=2;}
if (y>308 && y<410) {wm_ChangeBank_ (3); banka=3;}
if (y>410) {wm_ChangeBank_ (4); banka=4;}
for (a=0; a<=ylen; a++)
{
d=y+a;
switch (d)
{
case 102:
if ((x+xlen)<256){
posunuti=(y+a)*640+x;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (1); banka=1;}
if (x>=256){
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
}
if (x<256 && (x+xlen)>256){
posunuti=(y+a)*640+x; b=x; c=0;
while (b!=256)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (1); banka=1;
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 204:
if ((x+xlen)<512){
posunuti=(((y+a)*640+x)-65536);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (2); banka=2;}
if (x>=512){
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<512 && (x+xlen)>512){
posunuti=(((y+a)*640+x)-65536); b=x; c=0;
while (b!=512)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (2); banka=2;
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 307:
if ((x+xlen)<128){
posunuti=(((y+a)*640+x)-131072);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (3); banka=3;}
if (x>=128){
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<128 && (x+xlen)>128){
posunuti=(((y+a)*640+x)-131072); b=x; c=0;
while (b!=128)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (3); banka=3;
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
case 409:
if ((x+xlen)<384){
posunuti=(((y+a)*640+x)-196608);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
wm_ChangeBank_ (4); banka=4;}
if (x>=384){
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);}
if (x<384 && (x+xlen)>384){
posunuti=(((y+a)*640+x)-196608); b=x; c=0;
while (b!=384)
{memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti), 1);
posunuti++; b++; c++;}
wm_ChangeBank_ (4); banka=4;
posunuti=(((y+a)*640+x)-262144);
memmove ((image+a*(xlen+1)+c), (0xa0000+posunuti+c), (xlen-c));}
break;
default:
posunuti=(y+a)*640+x-banka*65536;
memmove ((image+a*(xlen+1)), (0xa0000+posunuti), xlen);
break;
};
}
}
void Get_VESA_info (void)
{
char far *str;
VESA_INFO_BLOCK *p;
p=(VESA_INFO_BLOCK *)mem_alloc(sizeof(VESA_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS));
dpmiregs.EAX=0x00004f00;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaInfoBlock,str,sizeof(VESA_INFO_BLOCK));
mem_free(p);
if(dpmiregs.EAX!=0x4f)
{
printf ("VESA Bios extension not found!!!!");
exit (1);
}
}
void Get_mode_info (int mode)
{
char far *str;
VESA_MODE_INFO_BLOCK *p;
p=(VESA_MODE_INFO_BLOCK *)mem_alloc(sizeof(VESA_MODE_INFO_BLOCK));
memset(&dpmiregs,0,sizeof(DPMIREGS)); //nuluje registry
dpmiregs.EAX=0x00004f01;
dpmiregs.DS=D32RealSeg(p);
dpmiregs.ES=D32RealSeg(p);
dpmiregs.EDI=D32RealOff(p);
dpmiregs.ECX=mode;
WtNs386(0x10,&dpmiregs);
str=(char far *)MK_FP(Selector,0);
_fmemcpy(&VesaModeInfoBlock,str,sizeof(VESA_INFO_BLOCK));
_VGAGran=VesaModeInfoBlock.WinGranularity;
mem_free(p);
}

70
ZVUK/VESA.H Normal file
View file

@ -0,0 +1,70 @@
/********************************/
/* Prace se SVGA VESA adapterem */
/********************************/
#ifndef __VESA_H
#define __VESA_H
typedef struct
{ char VESASignature[4];
short VESAversion;
unsigned OEMStringPtr;
char capabilities[4];
short int *videomodeptr;
short int TotalMemory;
char dummy[236];
} VESA_INFO_BLOCK;
typedef struct
{ short unsigned ModeAttributes;
char WinAAttributes;
char WinBAttributes;
short unsigned WinGranularity;
short unsigned WinSize;
short unsigned WinASegment;
short unsigned WinBSegment;
short unsigned WinFuncPtroff;
short unsigned WinFuncPtrseg;
short unsigned BytesPerScanLine;
short unsigned XResolution;
short unsigned YResolution;
char Xcharsize;
char Ycharsize;
char NumberOfPlanes;
char BitsPerPixel;
char NumberOfBanks;
char MemoryModel;
char BankSize;
char NumberOfImagePages;
char Reserved;
char RedMaskSize;
char RedFieldPosition;
char GreenMaskSize;
char GreenFieldPosition;
char BlueMaskSize;
char BlueFieldPosition;
char RsvdMaskSize;
char DirectColorModeInfo;
char Dummy[216];
} VESA_MODE_INFO_BLOCK;
VESA_MODE_INFO_BLOCK VesaModeInfoBlock;
VESA_INFO_BLOCK VesaInfoBlock;
extern unsigned char _VGAPage=0;
extern unsigned char _VGAGran=0;
void Set_VESA_mode (int mode);
void Show_screen (char *display);
void Get_VESA_info (void);
void Get_mode_info (int mode);
void Put_image (int x, int y, int xlen, int ylen, char *image);
void Get_image (int x, int y, int xlen, int ylen, char *image);
#endif

63
ZVUK/VESA_.ASM Normal file
View file

@ -0,0 +1,63 @@
;EAX EDX EBX ECX
.386p
jumps
;############################################################################
; Constanty
;############################################################################
dlt_x equ 640
dlt_y equ 480
;############################################################################
; Datovy segment
;############################################################################
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
align 4
EXTRN __VGAPage:BYTE
EXTRN __VGAGran:BYTE
_DATA ENDS
DGROUP GROUP _DATA
;############################################################################
; Kodovy segment
;############################################################################
_TEXT SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME cs:_TEXT, ds:_DATA
public wm_ChangeBank__
wm_ChangeBank__ PROC
push es
pushad
push eax
mov edx, eax
mov ebx, 0000h
mov eax, 4f05h
int 10h
pop eax
mov edx, eax
mov ebx, 0001h
mov eax, 4f05h
int 10h
popad
pop es
ret
wm_ChangeBank__ endp
;----------------------------------------------------------------------------
_TEXT ENDS
END

872
ZVUK/ZVUK1.C Normal file
View file

@ -0,0 +1,872 @@
#include <stdlib.h>
#include <stdio.h>
//#include <i86.h>
#include <dpmi.h>
#include <conio.h>
#include <mem.h>
#include <bios.h>
#include <dos.h>
#define MIX_MONO 8
#define MIX_STEREO 16
#define MIX_16STEREO 32
#define MUSIC1 "..\\music\\ascent.mus"
#define MUSIC2 "..\\music\\late.mus"
#define MUSIC3 "..\\music\\december.mus"
#define MUSIC4 "..\\music\\ssi.mus"
#define MUSIC5 "..\\music\\test.mus"
#define BACK_BUFF_SIZE 0x40000
#define DEV_SB10 0x0e
#define DEV_SB20 0x10
#define DEV_SBPRO 0x12
#define DEV_SB16 0x14
#define DEV_WWS 0x16
#define DEV_ULTRA 0x18
#define DEV_DAC 0x1A
#define DEV_PCSPEAKER 0x1C
#define MIX_REZERVA 0x50
#define build_dac_xlat() \
{\
int i;\
for(i=0;i<256;i++) da_xlat[i]=i;\
}\
#define sendsb(data) \
while (inp(sbport+0xc) & 0x80);\
outp(sbport+0xc,data)
#define recivesb(data)\
while (!(inp(sbport+0xe) & 0x80));\
data=inp(sbport+0xa)
char detect_enables[8];
#define irqdetect(irq) \
{\
if (detect_enables[irq]) \
sbirq=irq;\
detect_enables[irq]=0;\
inp(sbport+0xE);\
outp(0x20,0x20);\
}
typedef struct tchannel
{
char *play_pos, *start_loop, *end_loop;
long speed_maj;
unsigned short speed_min, minor_pos, sample_type, vol_left, vol_right;
}TCHANNEL;
char musiclist[5][30]={
MUSIC1,MUSIC2,MUSIC3,MUSIC4,MUSIC5};
TCHANNEL chaninfo[32];
char *mixbuffer;
char backsndbuff[BACK_BUFF_SIZE];
volatile long backsnd=0;
volatile long backstep=1;
volatile int backfine=0;
long jumptable[3];
long getdma;
long ido;
unsigned short predstih=0x960;
long lastdma;
long lastmix;
long mixpos;
long surpos;
long mixsize;
long dmaposadr;
long dmasizadr;
long dmapageadr;
long dmanum;
int dmamask;
int dmamode;
int device;
long samplerate=1000;
long mixfreq=100;
long idt_map[2];
int call_back_data;
int call_back_sel;
unsigned short dpmiselector;
char mixer_zavora=0;
FILE *bsnd;
unsigned short bchans;
short btable[256];
int bfreq,bblocks,bvolume=255;
char depack[32768];
char da_xlat[256]; // Xlat tabulka pro DA a PC Speaker;
int dac_port; //DAC port
int test_counter=0;
char *sample1;
long last_load_size;
int dmatable[8][4]=
{
{0,1,0x87,0x0A0B},
{2,3,0x83,0x0A0B},
{4,5,0x81,0x0A0B},
{6,7,0x82,0x0A0B},
{0xd0,0xd1,0x8f,0xD4D6},
{0xd2,0xd3,0x8b,0xD4D6},
{0xd4,0xd5,0x89,0xD4D6},
{0xd6,0xd7,0x8a,0xD4D6}
};
int irqtable[16]={8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77};
void *load_file(char *filename)
{
FILE *f;
long size,*p;
f=fopen(filename,"rb");
if (f==NULL) abort();
fseek(f,0,SEEK_END);
size=ftell(f);
fseek(f,0,SEEK_SET);
p=(void *)malloc(size);
if (fread(p,1,size,f)!=size) abort;
fclose(f);
last_load_size=size;
return p;
}
char *buff_alloc();
#pragma aux buff_alloc modify[ebx ecx edx] value [eax]
void mixer();
#pragma aux mixer modify [eax ebx ecx edx esi edi]
void setsbpro();
#pragma aux setsbpro modify [eax edi]
void setsb2();
#pragma aux setsb2 modify [eax edi]
void setsb16();
#pragma aux setsb16 modify [eax edi]
int sbport=0x220;
int sbirq=0;
void init_dma(int dma)
{
dmanum=dma;
dmaposadr=dmatable[dma][0];
dmasizadr=dmatable[dma][1];
dmapageadr=dmatable[dma][2];
dmamask=dmatable[dma][3] >> 8;
dmamode=dmatable[dma][3] & 0xff;
}
void prepare_dma(char *adr)
{
int poz;
outp(0x0C,0);outp(0xD8,0);
outp(dmamask,(dmanum & 3)+0x04);
outp(dmamode,(dmanum & 3)+0x58);
if (dmanum>3) poz=(long)adr >> 1; else poz=(long)adr;
outp(dmaposadr,poz & 0xff);
outp(dmaposadr,(poz>>8) & 0xff);
outp(dmapageadr,poz>>16);
outp(dmasizadr,0xff);
outp(dmasizadr,0xff);
outp(dmamask,dmanum & 3+0x04);
}
void reset_blaster()
{
int counter=100;
outp(sbport+0x6,1);
delay(10);
outp(sbport+0x6,0);
while (inp(sbport+0x0A)!=0xAA && counter--) delay(1);
}
void start_sbmono()
{
prepare_dma(mixbuffer);
sendsb(0xd1);
sendsb(0x40);
sendsb(256 - (1000000 / samplerate));
sendsb(0x48);
sendsb(0xff);
sendsb(0xff);
sendsb(0x1c);
}
void stop_sbmono()
{
sendsb(0xd3);
sendsb(0xd0);
//sendsb(0xda);
//sendsb(0xd0);
}
void start_sb16();
void __interrupt __far sb16_irq()
{
int i=32767;
i=inp(sbport+0xf);
i=inp(sbport+0xe);
// sendsb(0xb6);
// sendsb(0x30);
// sendsb(i & 0xff);
// sendsb(i >> 8); //play(16bit,signed,stereo,16384);
outp(0x20,0x20);
outp(0xA0,0x20);
}
void start_sb16()
{
int i=16383;
outp(sbport+0x4,0x81);
outp(sbport+0x5,1 << dmanum);
outp(sbport+0x4,0x80);
switch (sbirq)
{
case 2:outp(sbport+0x5,0xf1);break;
case 5:outp(sbport+0x5,0xf2);break;
case 7:outp(sbport+0x5,0xf4);break;
}
outp(sbport+0x4,0x80);
prepare_dma(mixbuffer);
sendsb(0xd1); //speaker(enable)
sendsb(0x41);
sendsb(samplerate>>8);
sendsb(samplerate & 0xff); //Set_sample_rate(samplerate);
sendsb(0xb4);
sendsb(0x30);
sendsb(i & 0xff);
sendsb(i >> 8); //play(16bit,signed,stereo,16384);
outp(0x21,inp(0x21) & ~(1<<sbirq));
_dos_setvect(irqtable[sbirq],sb16_irq);
}
void stop_sb16()
{
sendsb(0xd3); //speaker(disable)
sendsb(0xd5); //Halt_DMA_16bit()
sendsb(0xd9); //Exit_autoinit_16bit();
sendsb(0xd5); //Halt_DMA_16bit()
if (sbirq<8)
{
outp(0x21,inp(0x21) | (1<<sbirq));
}
else
{
outp(0xA1,inp(0xA1) | (1<<(sbirq-8)));
}
}
void start_sbstereo()
{
prepare_dma(mixbuffer);
sendsb(0xd1);
sendsb(0x40);
sendsb((65536 - (256000000 / (samplerate*2)))>>8);
sendsb(0x48);
sendsb(0xff);
sendsb(0xff);
sendsb(0x90);
outp(sbport+0x4,0x0e);
outp(sbport+0x5,0x13);
}
void __interrupt __far sb10_irq()
{
int i=32767;
i=inp(sbport+0xe);
sendsb(0x14);
sendsb(0xff);
sendsb(0xff);
outp(0x20,0x20);
outp(0xA0,0x20);
}
void start_sb10()
{
prepare_dma(mixbuffer);
sendsb(0xd1);
sendsb(0x40);
sendsb((65536 - (256000000 / (samplerate*2)))>>8);
sendsb(0x14);
sendsb(0xff);
sendsb(0xff);
outp(0x21,inp(0x21) & ~(1<<sbirq));
_dos_setvect(irqtable[sbirq],sb10_irq);
}
void stop_sb10()
{
sendsb(0xd3); //speaker(disable)
sendsb(0xd5); //Halt_DMA_16bit()
if (sbirq<8)
{
outp(0x21,inp(0x21) | (1<<sbirq));
}
else
{
outp(0xA1,inp(0xA1) | (1<<(sbirq-8)));
}
}
int open_backsound(char *filename)
{
static char lastname[128];
if (filename!=NULL)
{
lastname[127]=0;
strncpy(lastname,filename,127);
}
bsnd=fopen(lastname,"rb");
if (bsnd==NULL) return -1;
fread(&bchans,1,2,bsnd);
fread(&bfreq,1,4,bsnd);
fread(&bblocks,1,4,bsnd);
fread(&bblocks,1,4,bsnd);
fseek(bsnd,8,SEEK_CUR);
fread(&btable,1,sizeof(btable),bsnd);
return 0;
}
void load_music_block()
{
if (bsnd!=NULL)
{
fseek(bsnd,8,SEEK_CUR);
fread(&depack,1,sizeof(depack),bsnd);
}
else
{
memset(&depack,0x80,sizeof(depack));
bblocks=0;
}
}
int mix_back_sound(char synchro)
{
static int remain=0;
static int last[2];
static int swap=0,depos=0,nextpos=0;
int count,val;
if (synchro==1)
{
remain=32767;
depos=0;
last[0]=0;
last[1]=0;
return nextpos;
}
if (synchro==2)
{
nextpos=backsnd*4+16;
if (nextpos>BACK_BUFF_SIZE) nextpos-=BACK_BUFF_SIZE;
return nextpos;
}
for(;;)
{
val=backsnd*4-nextpos;
if (val<0) val+=BACK_BUFF_SIZE;
if (val<32768) return nextpos;
for(count=16384;count>0;count--)
{
if (remain==0)
{
bblocks--;
if (bblocks<=0)
{
fclose(bsnd);
open_backsound(NULL);
}
load_music_block();
last[0]=0;
last[1]=0;
remain=32768;
depos=0;
}
val=btable[depack[depos++]];remain--;
val+=last[swap];
last[swap++]=val;
if (swap>=bchans) swap=0;
val=(val*bvolume)>>8;
if (val>32676) val=32767;
if (val<-32767) val=-32767;
*(short *)(backsndbuff+(nextpos))=val;
nextpos+=2;
if (nextpos>=BACK_BUFF_SIZE) nextpos=0;
}
}
}
void fade_music()
{
short *p;
int i,j,k,l,m;
mix_back_sound(0);
k=backsnd*2;
i=k;
p=(short *)&backsndbuff;
m=mix_back_sound(1);
m=m-k*2;
if (m<0) m+=BACK_BUFF_SIZE;
m/=2;
j=m;m/=256;
do
{
l=j/256;
p[i]=p[i]*l/m;
i++;j--;if (j<0) j=0;
if (i>BACK_BUFF_SIZE/2) i=0;
}
while (i!=k);
memset(&depack,0x80,sizeof(depack));
}
void stop_sbstereo()
{
reset_blaster();
outp(sbport+0x4,0x0e);
outp(sbport+0x5,0x11);
//sendsb(0xda);
//sendsb(0xd0);
}
int init_blaster(int port)
{
sbport=port;
reset_blaster();
return(inp(sbport+0x0a)==0xaa);
}
void prepare_mixing(int mode)
{
predstih=samplerate/mixfreq+MIX_REZERVA;
predstih+=MIX_REZERVA+predstih;
predstih*=(mode/MIX_MONO);
switch (mode)
{
case MIX_MONO:setsb2();break;
case MIX_STEREO:setsbpro();break;
case MIX_16STEREO:setsb16();break;
}
backsndbuff[0]=0;backstep=bfreq*0x10000/samplerate;backsnd=0;
//backsndbuff[0]=128;backstep=0;backsnd=0;
lastdma=0;
mixpos=(long)(mixbuffer+predstih);
memset(chaninfo,0,sizeof(TCHANNEL)*32);
memset(mixbuffer,0x80,65536);
}
void play_sample(int channel,void *sample,long size,long lstart,long sfreq,int type)
{
chaninfo[channel].play_pos=sample;
chaninfo[channel].start_loop=(char *)sample+lstart;
chaninfo[channel].end_loop=(char *)sample+size;
chaninfo[channel].speed_maj=sfreq/samplerate;
chaninfo[channel].speed_min=(sfreq%samplerate)*65536/samplerate;
chaninfo[channel].sample_type=type;
}
void set_channel_volume(int channel,int left,int right)
{
chaninfo[channel].vol_left=left;
chaninfo[channel].vol_right=right;
}
void set_bass_treble(int x,int y)
{
outp(sbport+4,0x44);outp(sbport+5,y);
outp(sbport+4,0x45);outp(sbport+5,y);
outp(sbport+4,0x46);outp(sbport+5,x);
outp(sbport+4,0x47);outp(sbport+5,x);
}
void mixing()
{
int c;int smpsize;
int treble=240,bass=240;
sample1=(char *)load_file("d:\\music\\samples\\fx\\playboy.smp");
smpsize=last_load_size;
set_channel_volume(0,32768,0);
set_channel_volume(1,0,32768);
for (c=2;c<12;c++)
set_channel_volume(c,(c-2)*3000,27000-(c-2)*3000);
c=0;
while (c!=1)
{
int a,b;
a=inp(dmaposadr);
a+=inp(dmaposadr)<<8;
b=(bblocks*65536)/(22050*bchans*2);
cprintf("%04X %6X %6X volume %03d block:%04d time %02d:%02d %10d\r",a,mixpos,mixsize,bvolume,bblocks,b/60,b%60,test_counter);
mix_back_sound(0);
//mixer();
c=0;
while (_bios_keybrd(_KEYBRD_READY))
{
c=_bios_keybrd(_KEYBRD_READ)>>8;
switch(c)
{
case 'H': if (bvolume<512) bvolume++;break;
case 'P': if (bvolume>0) bvolume--;break;
case 'I': if (treble<240) treble+=16;set_bass_treble(bass,treble);break;
case 'Q': if (treble>0) treble-=16;set_bass_treble(bass,treble);break;
case 'G': if (bass<240) bass+=16;set_bass_treble(bass,treble);break;
case 'O': if (bass>0) bass-=16;set_bass_treble(bass,treble);break;
case 'M': if (bblocks>0)
{
mixer_zavora=1;
backsnd+=8196;if (backsnd>BACK_BUFF_SIZE/4) backsnd-=BACK_BUFF_SIZE/4;
mixer_zavora=0;
}
break;
case 'K': if (ftell(bsnd)>2*(32768+8))
{
fseek(bsnd,-2*(32768+8),SEEK_CUR);
bblocks++;
load_music_block();
}
break;
case 0x17:
do
{
a=inp(dmaposadr);
a+=inp(dmaposadr)<<8;
}
while (!(a & 1));
do
{
a=inp(dmaposadr);
a+=inp(dmaposadr)<<8;
}
while (a & 1);
outp(sbport+0x4,0x0e);
outp(sbport+0x5,inp(sbport+0x5) ^ 0x20);
break;
default:
if (c>=2 && c<=11)
play_sample(c-2,sample1,smpsize,smpsize,11000,1);
else
if (c>=';' && c<='@')
{
fclose(bsnd);
fade_music();
open_backsound(musiclist[c-';']);
}
}
}
}
}
int int_relocation();
#pragma aux int_relocation modify [eax ebx ecx edx esi edi]
void int_mixer_alloc(int num);
#pragma aux int_mixer_alloc parm [ebx] modify [eax ecx edx esi edi]
int int_dealloc();
#pragma aux int_dealloc modify [eax ebx ecx edx esi edi]
void __interrupt __far int_normal();
void high_speed_parm(void *mix,int dosdelay,char *xlattab,int port);
#pragma aux high_speed_parm parm [ebx][eax][esi][edx] modify [edi]
void int_high_alloc(int num);
#pragma aux int_high_alloc parm [ebx] modify [eax ecx edx esi edi]
void int_init()
{
int l;
_dos_setvect(0x1c,int_normal);
l=0x1234bc/mixfreq;
outp(0x43,0x34);
outp(0x40,l%256);
outp(0x40,l/256);
}
void int_highspeed(int port)
{
int l;
_dos_setvect(0x1c,int_normal);
high_speed_parm(mixbuffer,samplerate/mixfreq,da_xlat,port);
int_high_alloc(0x8);
l=0x1234bc/samplerate;
outp(0x43,0x34);
outp(0x40,l%256);
outp(0x40,l/256);
}
void set_mixing_device(int mix_dev,int mix_freq,...)
{
int *p;
samplerate=mix_freq;
mixbuffer=buff_alloc();
p=&mix_freq;p++;
device=mix_dev;
switch (mix_dev)
{
case DEV_SB10:
case DEV_SB20:
case DEV_SBPRO:
case DEV_SB16:
init_blaster(p[0]);
init_dma(p[1]);
sbirq=p[2];
break;
case DEV_DAC:
dac_port=p[0];
break;
}
}
void start_mixing()
{
switch (device)
{
case DEV_SB10:
start_sb10();
int_init();
prepare_mixing(MIX_MONO);
break;
case DEV_SB20:
start_sbmono();
int_init();
prepare_mixing(MIX_MONO);
break;
case DEV_SBPRO:
start_sbstereo();
int_init();
prepare_mixing(MIX_STEREO);
break;
case DEV_SB16:
start_sb16();
int_init();
prepare_mixing(MIX_16STEREO);
break;
case DEV_DAC:
build_dac_xlat();
prepare_mixing(MIX_MONO);
int_highspeed(dac_port);
break;
}
}
void stop_mixing()
{
outp(0x43,0x34);
outp(0x40,0);
outp(0x40,0);
switch (device)
{
case DEV_SB10:
stop_sb10();
break;
case DEV_SB20:
stop_sbmono();
break;
case DEV_SBPRO:
stop_sbstereo();
break;
case DEV_SB16:
stop_sb16();
break;
case DEV_DAC:
int_dealloc();
break;
}
}
void __far __interrupt sb_detect_irq2()
irqdetect(2)
void __far __interrupt sb_detect_irq3()
irqdetect(3)
void __far __interrupt sb_detect_irq5()
irqdetect(5)
void __far __interrupt sb_detect_irq7()
irqdetect(7)
char *device_name(int device)
{
static char names[][25]=
{
"Unsupported Device",
"Sound Blaster",
"Sound Blaster 2",
"Sound Blaster Pro/2",
"Sound Blaster 16+",
"Windows Sound System",
"UltraSound",
"DAC on LPT",
"Internal Hooker",
"Pro Audio Spectrum"
};
switch (device)
{
case DEV_SB10:return names[1];
case DEV_SB20:return names[2];
case DEV_SBPRO:return names[3];
case DEV_SB16:return names[4];
case DEV_WWS:return names[5];
case DEV_ULTRA:return names[6];
case DEV_DAC:return names[7];
case DEV_PCSPEAKER:return names[8];
}
return names[0];
}
int sb_detect(int *dev,int *port,int *dma, int *irq)
{
int i,a,j;
char ver_lo;
char ver_hi;
void __far *irqsave2,__far *irqsave3,__far *irqsave5,__far *irqsave7;
int dmasaves[4];
char dmadis[4];
int dmatesting[4]={1,3,0,1};
*port=0x210;
do
{
sbport=*port;
outp(sbport+6,1);delay(1);
outp(sbport+6,0);
for(i=0;i<100 && inp(sbport+0xA)!=0xAA;i++) delay(1);
(*port)+=0x10;
}
while (i==100 && sbport<0x280);
if (i==100) return -1; //NOT DETECTED;
*port=sbport;
sendsb(0xe1);
recivesb(ver_lo);
recivesb(ver_hi);
switch (ver_hi)
{
case 1: *dev=DEV_SB10;break;
case 2: if (ver_lo) *dev=DEV_SB20;break;
case 3: *dev=DEV_SBPRO;break;
case 4: *dev=DEV_SB16;break;
default: *dev=DEV_SB10;break;
}
if (*dev==DEV_SB16)
{
outp(sbport+4,0x80);
i=inp(sbport+5);
*irq=5;
if (i & 8) *irq=7;
if (i & 4) *irq=7;
if (i & 2) *irq=5;
if (i & 1) *irq=2;
outp(sbport+4,0x81);
i=inp(sbport+5);
*dma=1;
if (i & 1) *dma=0;
if (i & 2) *dma=1;
if (i & 8) *dma=3;
return 0;
}
for(i=0;i<4;i++)
{
outp(0xc,0);
a=inp(dmatable[i][0]);
a=a+256*inp(dmatable[i][0]);
dmasaves[i]=a;
}
irqsave2=_dos_getvect(irqtable[2]);
irqsave3=_dos_getvect(irqtable[3]);
irqsave5=_dos_getvect(irqtable[5]);
irqsave7=_dos_getvect(irqtable[7]);
_dos_setvect(irqtable[2],sb_detect_irq2);
_dos_setvect(irqtable[3],sb_detect_irq3);
_dos_setvect(irqtable[5],sb_detect_irq5);
_dos_setvect(irqtable[7],sb_detect_irq7);
ver_lo=inp(0x21);
outp(0x21,0x53);
memset(detect_enables,0x1,sizeof(detect_enables));
delay(100);
sbirq=-1;
sendsb(0xf2);
delay(1);
_dos_setvect(irqtable[2],irqsave2);
_dos_setvect(irqtable[3],irqsave3);
_dos_setvect(irqtable[5],irqsave5);
_dos_setvect(irqtable[7],irqsave7);
outp(0x21,ver_lo);
if (sbirq==-1) return -2; //DETECTION ERROR
*irq=sbirq;
for(i=0;i<4;i++)
{
outp(0xc,0);
a=inp(dmatable[i][0]);
a=a+256*inp(dmatable[i][0]);
dmadis[i]=(dmasaves[i]==a);
}
for (j=0,*dma=-1;j<4 && *dma==-1;j++)
{
i=dmatesting[j];
init_dma(i);
prepare_dma(NULL);
sendsb(0xd3);
sendsb(0x14);
sendsb(0xff);
sendsb(0x7f);
delay(100);
outp(0xc,0);
a=inp(dmatable[i][0]);
a=a+256*inp(dmatable[i][0]);
if (dmasaves[i]!=a && dmadis[i]) *dma=i;
reset_blaster();
}
if (*dma==-1) return -2;
return 0;
}
main()
{
int a,b,c,d;
printf("%d\n",sizeof(TCHANNEL));
if (sb_detect(&a,&b,&c,&d))
{
printf("SB not present\n");
return;
}
//a=DEV_SBPRO;
printf("%s\n",device_name(a));
//printf("IRQ:\n");
//scanf("%d",&d);
set_mixing_device(a,22050,b,c,d);
printf("Port %03X dma %d irq %d freq %d.\n",b,c,d,samplerate);
open_backsound(MUSIC1);
start_mixing();
mixing();
stop_mixing();
printf("\n\n\n");
}

271
ZVUK/ZVUK1A.ASM Normal file
View file

@ -0,0 +1,271 @@
.model small
.386
DGROUP group _DATA
tchannel struct
PLAYPOS DD ?
STARTLOOP DD ?
ENDLOOP DD ?
SPEEDMAJ DD ?
SPEEDMIN DW ?
MINORPOS DW ?
SMPTYPE DW ?;0 - DISABLED, 1 - 8 BIT, 2 - 16 BIT
VOLUMELEFT DW ?
VOLUMERIGHT DW ?
tchannel ends
extrn _chaninfo:dword
extrn _mixbuffer:dword
extrn _backsnd:dword ;ukazatel na buffer s hudbou na pozadi (64Kb)
extrn _backstep:dword ;krok o kolik se meni _backsnd
extrn _backsndbuff:dword ;buffer hudby na pozadi
extrn _jumptable:dword[3] ;[0] - skip, [1] - mix8, [2] - mix16
extrn _getdma:dword
extrn _ido:dword
extrn _predstih:word
extrn _lastdma:dword
extrn _lastmix:dword
extrn _surpos:dword
extrn _mixpos:dword
extrn _mixsize:dword
extrn _dmaposadr:dword
extrn _dpmiselector:word
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
PUBLIC MIXER_
MIXER_: ;THIS IS MAIN MIXING PROCEDURE.
;BEFORE USING, YOU MUST SET UP ALL VARIBLES TO THE CORRECT VALUES.
;_MIXBUFFER MUST START ON PAGE OF MEMORY (EXP 0x10000 0x20000 0x30000)
;PROCEDURE MUST BE CALLED EACH 55ms OR LITTLE.
;IF YOU USING INTERRUPT, REMEBER, THAT YOU MUST STORE ALL REGISTERS
;BEFORE USE.
CALL calcsize ;VYPOCET DELKY MIXOVANI
mov edi,_mixpos ;Nejprve se vymaze mixovaci pamet
mov ecx,_mixsize
shr ecx,2
jnz MIXOK
ret
MIXOK: xor eax,eax
MIXCLR: mov [edi],eax
add di,4
dec ecx
jnz MIXCLR
lea ebx,_chaninfo ;TED SE ZACNE MIXOVAT
MIXING: xor eax,eax
mov ax,smptype[ebx]
call _jumptable[eax*4]
add ebx,sizeof(tchannel)
cmp ebx,(32*sizeof(tchannel))+offset _chaninfo
jnz MIXING
call _ido
mov ecx,_mixsize
add word ptr _mixpos,cx
add word ptr _surpos,cx
ret
CALCSIZE:call _getdma ;eax - pozice v mixovaci pameti
mov ebx,_lastdma
mov _lastdma,eax
sub ax,bx
add ax,_predstih
add ax,word ptr _lastdma
mov bx,word ptr _mixpos
sub ax,bx
js CALCEND
and ax,not 3
add ax,4
and eax,0ffffh
mov _mixsize,eax
ret
CALCEND:mov _mixsize,0
ret
ADDC macro REG1,REG2,CLIP
local addc1
add REG1,REG2
jno addc1
shl REG2,1
Mov REG2,CLIP
adc REG2,0
mov REG1,REG2
addc1:
endm
MIXS_ :;primixuje sampl do bufferu (8-bit stereo)
;musi platit vsechny promenne a ebx je adresa kanalu
mov edi,_mixpos
mov ecx,_mixsize
mov esi,[ebx]
push ebp
mov bp,minorpos[ebx]
mixslp: mov al,[esi]
mov ah,al
mov edx,eax
mov al,byte ptr volumeleft[ebx+1]
imul dl
shl eax,1
mov dl,ah
mov al,byte ptr volumeright[ebx+1]
imul dh
shl eax,1
mov dh,ah
mov ax,[edi]
addc al,dl,7fh
addc ah,dh,7fh
mov [edi],ax ;je smixovano
add di,2 ;dalsi pozice
add bp,speedmin[ebx]
adc esi,speedmaj[ebx]
cmp esi,endloop[ebx]
jc mixsskp
mov esi,startloop[ebx]
cmp esi,endloop[ebx]
jnz mixsskp
mov smptype[ebx],0
jmp mixsend
mixsskp:dec ecx
dec ecx
jnz mixslp
mixsend:mov minorpos[ebx],bp
mov playpos[ebx],esi
pop ebp
ret
mixskip:ret
mixs2: ret
m8sido: mov esi,_mixpos
mov edi,_surpos ;surpos musi byt liche
mov ecx,_mixsize
mov edx,_backsnd ;backsnd-index na hudbu v pozadi
m8sido1:mov al,[edi] ;vem surround data
sar al,1 ;sniz jejich hlasitost
mov ah,[esi] ;vem namixovana data
addc al,ah,7fh ;secti je mezi sebou
mov ah,byte ptr _backsndbuff[edx] ;ven data z hudby v pozadi
add dx,word ptr _backstep ;mezitim jdi na dalsi index
addc al,ah,7fh ;secti je mexi sebou
mov [edi],al
inc di ;dalsi pozice v mixbuff
inc si
dec ecx ;dokud to neni vsechno
jnz m8sido1 ;opakuj
mov _backsnd,edx ;zachovej index do backsoundbuff
mov esi,_surpos ;nyni pracuj jiz s prehravanymi daty
and esi,not 1
mov edi,esi
sub si,2 ;pozice o jeden sampl za
mov ecx,_mixsize ;velikost/2
shr ecx,1
m8sido2:mov ax,[esi] ;vem cely sampl
xor ax,8080h
mov bx,[edi]
xor bx,8080h
;add al,bl ;uplna prumerovaci interpolace
;rcr al,1
;add ah,bh
;rcr ah,1
mov [esi],ax
add di,2 ;dalsi vzorek
add si,2
dec ecx
jnz m8sido2 ;dokud neni konec
ret
sbdma: mov edx,_dmaposadr
out 0ch,al
out 0d8h,al
xor eax,eax
in al,dx
xchg al,ah
in al,dx
xchg al,ah
add eax,offset _mixbuffer
ret
PUBLIC setsbpro_
setsbpro_:
lea edi,_jumptable
mov eax,offset mixskip
stosd
mov eax,offset mixs_
stosd
mov eax,offset mixs2
stosd
mov _getdma,offset sbdma
mov _ido,offset m8sido
ret
dpmibufalloc:
mov ax,0100h
int 31h
ret
public buff_dealloc_
buff_dealloc_:
mov dx,_dpmiselector
mov ax,0101h
int 31h
ret
public buff_alloc_
buff_alloc_:
mov ebx,4200
call dpmibufalloc
jc allcerror
test eax,0fffh
jz allc_ok
push eax
mov eax,0101h
int 31h
pop eax
mov ebx,eax
and ebx,0f000h
add ebx,1000h
sub ebx,eax
dec ebx
call dpmibufalloc
jc allcerror
push edx
call buff_alloc_
mov ecx,edx
pop edx
push eax
mov eax,0101h
int 31h
pop eax
ret
allc_ok:mov _dpmiselector,dx
shl eax,4
ret
allcerror:
mov word ptr _dpmiselector,0
xor eax,eax
ret
_TEXT ends
end

741
ZVUK/ZVUK2A.ASM Normal file
View file

@ -0,0 +1,741 @@
.model small
.386P
DGROUP group _DATA
tchannel struct
PLAYPOS DD ?
STARTLOOP DD ?
ENDLOOP DD ?
SPEEDMAJ DD ?
SPEEDMIN DW ?
MINORPOS DW ?
SMPTYPE DW ?;0 - DISABLED, 1 - 8 BIT, 2 - 16 BIT
VOLUMELEFT DW ?
VOLUMERIGHT DW ?
tchannel ends
rm_playdata struct
XLAT_TAB DB 256 DUP(?)
SCANOFS DW ?
SCANSEG DW ?
PORT DW ?
rm_playdata ends
extrn _chaninfo:dword
extrn _mixbuffer:dword
extrn _backsnd:dword ;ukazatel na buffer s hudbou na pozadi (64Kb)
extrn _backstep:dword ;krok o kolik se meni _backsnd
extrn _backfine:dword ;citac udavajici kdy se zmeni _backsnd
extrn _backsndbuff:dword ;buffer hudby na pozadi
extrn _call_back_data:dword ;data_call_back_procedury
extrn _call_back_sel:word ;data_call_back_procedury
extrn _jumptable:dword[3] ;[0] - skip, [1] - mix8, [2] - mix16
extrn _getdma:dword
extrn _ido:dword
extrn _predstih:word
extrn _lastdma:dword
extrn _lastmix:dword
extrn _surpos:dword
extrn _mixpos:dword
extrn _mixsize:dword
extrn _dmaposadr:dword
extrn _dpmiselector:word
extrn _idt_map:dword
extrn _test_counter:dword
extrn _mixer_zavora:byte
_TEXT segment byte public 'CODE' use32
assume CS:_TEXT
assume DS:DGROUP
PUBLIC MIXER_
MIXER_: ;THIS IS MAIN MIXING PROCEDURE.
;BEFORE USING, YOU MUST SET UP ALL VARIBLES TO THE CORRECT VALUES.
;_MIXBUFFER MUST START ON PAGE OF MEMORY (EXP 0x10000 0x20000 0x30000)
;PROCEDURE MUST BE CALLED EACH 55ms OR LITTLE.
;IF YOU USING INTERRUPT, REMEBER, THAT YOU MUST STORE ALL REGISTERS
;BEFORE USE.
cmp _mixer_zavora,0
jnz mixend
inc _mixer_zavora
CALL calcsize ;VYPOCET DELKY MIXOVANI
mov edi,_mixpos ;Nejprve se vymaze mixovaci pamet
mov ecx,_mixsize
shr ecx,2
jz MIXALL
MIXOK: xor eax,eax
MIXCLR: mov [edi],eax
add di,4
dec ecx
jnz MIXCLR
lea ebx,_chaninfo ;TED SE ZACNE MIXOVAT
MIXING: xor eax,eax
mov ax,smptype[ebx]
call _jumptable[eax*4]
add ebx,sizeof(tchannel)
cmp ebx,(32*sizeof(tchannel))+offset _chaninfo
jnz MIXING
call _ido
mov ecx,_mixsize
add word ptr _mixpos,cx
MIXALL: mov _mixer_zavora,0
MIXEND: ret
CALCSIZE:call _getdma ;eax - pozice v mixovaci pameti
mov ebx,_lastdma
mov _lastdma,eax
sub ax,bx
add ax,_predstih
add ax,word ptr _lastdma
mov bx,word ptr _mixpos
sub ax,bx
js CALCEND
and ax,not 3
add ax,4
and eax,0ffffh
mov _mixsize,eax
ret
CALCEND:mov _mixsize,0
ret
ADDC macro REG1,REG2,CLIP
local addc1
add REG1,REG2
jno addc1
shl REG2,1
Mov REG2,CLIP
adc REG2,0
mov REG1,REG2
addc1:
endm
MIXS_ :;primixuje sampl do bufferu (8-bit stereo)
;musi platit vsechny promenne a ebx je adresa kanalu
mov edi,_mixpos
mov ecx,_mixsize
mov esi,[ebx]
push ebp
mov bp,minorpos[ebx]
mixslp: mov dl,[esi]
mov dh,dl
mov al,byte ptr volumeleft[ebx+1]
imul dl
shl eax,1
mov dl,ah
mov al,byte ptr volumeright[ebx+1]
imul dh
shl eax,1
mov dh,ah
mov ax,[edi]
addc al,dl,7fh
addc ah,dh,7fh
mov [edi],ax ;je smixovano
add di,2 ;dalsi pozice
add bp,speedmin[ebx]
adc esi,speedmaj[ebx]
cmp esi,endloop[ebx]
jc mixsskp
mov esi,startloop[ebx]
cmp esi,endloop[ebx]
jnz mixsskp
mov smptype[ebx],0
jmp mixsend
mixsskp:dec ecx
dec ecx
jnz mixslp
mixsend:mov minorpos[ebx],bp
mov playpos[ebx],esi
pop ebp
ret
mixskip:ret
mixs2 :;primixuje sampl do bufferu (16-bit stereo)
;musi platit vsechny promenne a ebx je adresa kanalu
mov edi,_mixpos ;vem mixovaci pozici
mov ecx,_mixsize ;vem pocet potrebnych bajtu
mov esi,[ebx] ;vyzvedni ukazatel na sample
push ebp ;zachovej bp
mov bp,minorpos[ebx] ;bp pro tuto chvili predstavuje minorpozici
mix2slp:mov dl,[esi+1] ;vem sample, ale jen vyssi bajt
mov dh,dl ;zkopiruj levy kanal do praveho
mov al,byte ptr volumeleft[ebx+1];vyzvedni hlasitost leveho kanalu
imul dl ;nasob vzorek hlasitosti
shl eax,1 ;vysledek je v ah vydelen 256x
mov dl,ah ;schovej vysledek do dl
mov al,byte ptr volumeright[ebx+1];to same pro pravy kanal
imul dh
shl eax,1
mov dh,ah
mov ax,[edi] ;ted precti aktualni stav samplu v bufferu
addc al,dl,7fh ;pricti levy kanal s clippingem
addc ah,dh,7fh ;pricti pravy kanal s clippingem
mov [edi],ax ;je smixovano
add di,2 ;dalsi pozice
add bp,speedmin[ebx] ;skok po minor hodnotach
lahf ;uchovej priznaky v ah (hlavne cf)
adc esi,speedmaj[ebx] ;skok po major hodnotach
sahf ;obnov cf
adc esi,speedmaj[ebx] ;a jeste jednou celkem o 2xvic nez je rychlost
cmp esi,endloop[ebx] ;test na konec samplu
jc mix2sskp ;pokud jsme prekrocili konec mohou nastat dva
mov esi,startloop[ebx];pripady:
cmp esi,endloop[ebx] ; bud ma sampl opakovani pak zacina na adrese
jnz mix2sskp ; startloop nebo nema
mov smptype[ebx],0 ; pak je vypnut
jmp mix2send ;skoc na konec
mix2sskp:dec ecx ;pokracujeme v prehravani
dec ecx ;byly naplneny 2 bajty, citac o 2 dolu
jnz mix2slp ;opakuj cele mixovani dokud neni citac nule
mix2send:mov minorpos[ebx],bp ;uloz minorpozici
mov playpos[ebx],esi ;uloz majorpozici
pop ebp ;obnov BP
ret ;konec
m8sido: mov esi,_mixpos ;vem mixovaci pozici
sub si,2 ;o jeden sampl dozadu
mov edi,_backfine ;finepozice
mov ebx,_backsnd ;pozice v bufferu
mov ecx,_mixsize ;pocet bajtu
sub ecx,2
shl ecx,16 ;uloz do horni poloviny ecx
mov ax,[esi] ;vezmi sample
xor eax,8080h ;neznaminkova korekce
m8sido1:add si,2 ;dalsi sample
mov dx,[esi] ;nacti do dx sample
xor edx,8080h ;neznaminkova korekce
add al,dl ;secti leve kanaly
rcr al,1 ;nasleduje deleni 2x prumer
add ah,dh ;totez pro prave kanaly
rcr ah,1
xor eax,8080h ;neznaminkova korekce
mov cl,byte ptr _backsndbuff[1+ebx*4] ;nacti back sound pro levej kanal
mov ch,byte ptr _backsndbuff[3+ebx*4];nactu back sound pro pravej kanal
addc al,cl,7fh ;secti s clippingem levy kanal
addc ah,ch,7fh ;secti s clippingem pravy kanal
add di,word ptr _backstep ;pricti fine pozici
adc bx,word ptr [_backstep+2];preteceni jde do bx plus step
and ebx,03ffffh ;celkem 16384*4 samplu
xor eax,8080h ;neznaminkova korekce
sub si,2 ;uloz na zdrojovou pozici
mov [esi],ax
add si,2
mov eax,edx ;pouzity sampl pro prumerovani se
sub ecx,20000h ;do ax a odecti dva takty pro citac
jnc m8sido1 ;a opakuj dokud neni konec
mov _backsnd,ebx
mov _backfine,edi
ret ;navrat
sbdma: mov edx,_dmaposadr
out 0ch,al
out 0d8h,al
xor eax,eax
in al,dx
xchg al,ah
in al,dx
xchg al,ah
add eax,_mixbuffer
ret
PUBLIC setsbpro_
setsbpro_:
lea edi,_jumptable
mov eax,offset mixskip
stosd
mov eax,offset mixs_
stosd
mov eax,offset mixs2
stosd
mov _getdma,offset sbdma
mov _ido,offset m8sido
ret
MIXM_ :;primixuje sampl do bufferu (8-bit mono)
;musi platit vsechny promenne a ebx je adresa kanalu
mov edi,_mixpos ;vezmi mixovaci pozici
mov ecx,_mixsize ;vezmi delku mixovani
mov esi,[ebx] ;nacti ukazatel na aktualni pozici v samplu
push ebp ;uchovej docasne BP
mov bp,minorpos[ebx] ;bp ma novou ulohu, drzi minor pozici
mov al,byte ptr volumeleft[ebx+1] ;vypocti hlasitost
mov ah,byte ptr volumeright[ebx+1]
add al,ah
rcr al,1 ;jak prumer leve a prave hlasitosti
mov dh,al
mixmlp: mov al,[esi] ;vezmi sample
imul dh ;vynasob s hlasitosti
shl eax,1 ;vydel /256x (ah je vysledek)
mov al,[edi] ;vezmi momentalni obsah bufferu
addc al,ah,7fh ;secti s clippingem
mov [edi],al ;je smixovano
inc di ;dalsi pozice
add bp,speedmin[ebx]
adc esi,speedmaj[ebx]
cmp esi,endloop[ebx]
jc mixmskp
mov esi,startloop[ebx]
cmp esi,endloop[ebx]
jnz mixmskp
mov smptype[ebx],0
jmp mixmend
mixmskp:dec ecx
jnz mixmlp
mixmend:mov minorpos[ebx],bp
mov playpos[ebx],esi
pop ebp
ret
m8mido: mov esi,_mixpos ;vem mixovaci pozici
dec si ;o jeden sampl dozadu
lea edi,_backfine ;ukazatel na back sound buffer
mov ebx,_backsnd ;pozice v bufferu
mov ecx,_mixsize ;pocet bajtu
dec ecx
shl ecx,16 ;uloz do horni poloviny ecx
mov al,[esi] ;vezmi sample
xor eax,80h ;neznaminkova korekce
m8mido1:inc si ;dalsi sample
mov dl,[esi] ;nacti do dx
xor edx,80h ;neznaminkova korekce
add al,dl ;secti kanal
rcr al,1 ;nasleduje deleni 2x prumer
xor eax,80h ;vysledek oznamenkuj - bude se scitat
mov cl,byte ptr _backsndbuff[1+ebx*4];nacti back sound pro levej kanal
mov ch,byte ptr _backsndbuff[3+ebx*4];nactu back sound pro pravej kanal
add di,word ptr _backstep ;pricti fine pozici
adc bx,word ptr [_backstep+2];preteceni jde do bx plus step
and ebx,03ffffh ;celkem 16384*4 samplu
sar cl,1 ;del levy kanal 2ma
sar ch,1 ;del pravy kanal 2ma
add cl,ch ;secti oba kanaly
addc al,cl,7fh ;secti s clippingem kanal
xor eax,80h ;neznaminkova korekce pro SB Pro
dec si ;uloz na zdrojovou pozici
mov [esi],al
inc si
mov eax,edx ;pouzity sampl pro prumerovani se
sub ecx,10000h ;do ax a odecti jeden takt pro citac
jnc m8mido1 ;a opakuj dokud neni konec
mov _backsnd,ebx
ret ;navrat
mixm2: ret ;navrat
PUBLIC setsb2_
setsb2_:
lea edi,_jumptable
mov eax,offset mixskip
stosd
mov eax,offset mixm_
stosd
mov eax,offset mixm2
stosd
mov _getdma,offset sbdma
mov _ido,offset m8mido
ret
MIX16_ :;primixuje sampl do bufferu (16-bit stereo)
;musi platit vsechny promenne a ebx je adresa kanalu
mov edi,_mixpos ;vem mixovaci pozici
mov ecx,_mixsize ;vem mixovaci delku
mov esi,[ebx] ;vyzvedni ukazatel na sample
push ebp ;uchovej BP
mov bp,minorpos[ebx] ;bp bude drzet minor pozice
mix1lp: mov al,[esi] ;nacti sample
mov dl,al ;al a dl obsahuji levej a pravej kanal
mov ah,byte ptr volumeright[ebx+1] ;nacti pravou hlastitot
imul ah ;vynasob hlasitosti
shl eax,1 ;vse je vyreseno, deleni neni potreba
xchg edx,eax ;ted pracuj s druhym kanalem
mov ah,byte ptr volumeleft[ebx+1] ;nactu hlasitost
imul ah ;vynasob
shl eax,1
addc [edi],dx,7fffh ;k aktualnimu vzorku pricti hodnotu
add di,2 ;dalsi pozice
addc [edi],ax,7fffh ;je smixovano
add di,2 ;dalsi pozice
add bp,speedmin[ebx]
adc esi,speedmaj[ebx]
cmp esi,endloop[ebx]
jc mix1skp
mov esi,startloop[ebx]
cmp esi,endloop[ebx]
jnz mix1skp
mov smptype[ebx],0
jmp mix1end
mix1skp:sub ecx,4
jnz mix1lp
mix1end:mov minorpos[ebx],bp
mov playpos[ebx],esi
pop ebp
ret
mix162: ret
m16ido: push ebp
mov esi,_mixpos ;vem mixovaci pozici
sub si,4 ;o jeden sampl dozadu
mov edi,_backfine ;finepozice
mov ebx,_backsnd ;pozice v bufferu
mov ecx,_mixsize ;pocet bajtu
sub ecx,4
shl ecx,16 ;uloz do horni poloviny ecx
mov eax,[esi] ;vezmi sample
xor eax,80008000h ;neznaminkova korekce
m16ido1:add si,4 ;dalsi sample
mov ebp,eax
and ebp,0ffff0000h
mov edx,[esi] ;nacti do dx sample
xor edx,80008000h ;neznaminkova korekce
add ax,dx ;secti leve kanaly
rcr ax,1 ;nasleduje deleni 2x prumer
add ebp,edx ;totez pro prave kanaly
rcr ebp,1
shld eax,ebp,16
xor eax,80008000h ;neznaminkova korekce
mov cx,word ptr _backsndbuff[ebx*4] ;nacti back sound pro levej kanal
addc ax,cx,7fffh ;secti s clippingem levy kanal
mov cx,word ptr _backsndbuff[2+ebx*4];nacti back sound pro pravej kanal
rol eax,16
addc ax,cx,7fffh ;secti s clippingem pravy kanal
add di,word ptr _backstep ;pricti fine pozici
adc bx,word ptr [_backstep+2];preteceni jde do bx plus step
and ebx,03ffffh ;celkem 16384*4 samplu
sub si,4 ;uloz na zdrojovou pozici
mov [esi],eax
add si,4
mov eax,edx ;pouzity sampl pro prumerovani se
sub ecx,40000h ;do ax a odecti ctyri takty pro citac
jnc m16ido1 ;a opakuj dokud neni konec
pop ebp
mov _backsnd,ebx
mov _backfine,edi
ret ;navrat
PUBLIC setsb16_
setsb16_:
lea edi,_jumptable
mov eax,offset mixskip
stosd
mov eax,offset mix16_
stosd
mov eax,offset mix162
stosd
mov _getdma,offset sbdma
mov _ido,offset m16ido
ret
dpmibufalloc:
mov ax,0100h
int 31h
ret
public buff_dealloc_
buff_dealloc_:
mov dx,_dpmiselector
mov ax,0101h
int 31h
ret
public buff_alloc_
buff_alloc_:
mov ebx,4200
call dpmibufalloc
jc allcerror
test eax,0fffh
jz allc_ok
push eax
mov eax,0101h
int 31h
pop eax
mov ebx,eax
and ebx,0f000h
add ebx,1000h
sub ebx,eax
dec ebx
call dpmibufalloc
jc allcerror
push edx
call buff_alloc_
mov ecx,edx
pop edx
push eax
mov eax,0101h
int 31h
pop eax
ret
allc_ok:mov _dpmiselector,dx
shl eax,4
ret
allcerror:
mov word ptr _dpmiselector,0
xor eax,eax
ret
public int_relocation_
int_relocation_:
mov eax,0de0ah
int 67h
shl ebx,16
mov bx,cx
rol ebx,16
mov eax,ebx
ret
public int_mixer_alloc_
int_mixer_alloc_:
lea eax,_idt_map
sidt [eax]
; db 0fh
; db 01
; db 08h
add eax,2
mov eax,[eax]
shl ebx,3
add eax,ebx
cli
mov edi,eax
push ds
pop es
mov ecx,offset int_normal_
mov eax,ecx
stosw
mov ax,cs
stosw
mov eax,8e00h
stosw
mov eax,ecx
shr eax,16
stosw
sti
mov ebx,1000h
call dpmibufalloc
mov esi,4*8
mov edi,offset rm_old
mov ecx,4
rep movsb
mov _call_back_sel,dx
mov esi,offset rm_data_
mov edi,eax
shl edi,4
mov _call_back_data,edi
mov ecx,1000
rep movsb
mov edi,4*8
mov word ptr [edi],8
mov [edi+2],ax
ret
public int_high_alloc_
int_high_alloc_:
lea eax,_idt_map
sidt [eax]
add eax,2
mov eax,[eax]
shl ebx,3
add eax,ebx
cli
mov edi,eax
push ds
pop es
mov ecx,offset int_hspd_
mov eax,ecx
stosw
mov ax,cs
stosw
mov eax,8e00h
stosw
mov eax,ecx
shr eax,16
stosw
sti
mov ebx,1000h
call dpmibufalloc
mov esi,4*8
mov edi,offset rm_old
mov ecx,4
rep movsb
mov _call_back_sel,dx
mov esi,offset rm_data_
mov edi,eax
shl edi,4
mov _call_back_data,edi
mov ecx,1000
rep movsb
mov edi,4*8
; mov word ptr [edi],(high_speed - rm_data_)
; mov [edi+2],ax
ret
public high_speed_parm_
;eax dos delay
;edx port
;ebx mixbuffer
;esi xlattab
high_speed_parm_:
mov edi,offset w_max
mov [edi],ax
mov edi,offset rm_hspd
mov ecx,64
rep movsd
xor eax,eax
stosw
mov eax,ebx
shr eax,4
stosw
mov eax,edx
stosw
ret
public int_dealloc_
int_dealloc_:
mov edi,4*8
mov esi,offset rm_old
mov ecx,4
rep movsb
mov dx,_call_back_sel
mov ax,101h
int 31h
ret
public int_normal_:
int_normal_:
cli
pushad
push ds
push es
mov ax,seg _DATA
mov ds,ax
mov es,ax
inc _test_counter
mov al,20h
out 20h,al
sti
call mixer_
cli
pop es
pop ds
popad
iretd
public int_hspd_: ;high speed mode interrupt - pro D/A a PC Speaker
int_hspd_:
push ds
push esi
push ebx
push edx
push eax
mov al,20h
out 20h,al
mov ax,seg _DATA
mov ds,ax
mov ebx,_call_back_data
add ebx,(offset rm_hspd-offset rm_data_)
xor eax,eax
xor esi,esi
mov ax,[ebx+scanofs]
mov si,[ebx+scanseg]
shl esi,4
add esi,eax
mov dx,[ebx+port]
lodsb
xlatb
out dx,al
inc word ptr [ebx+scanofs]
mov ebx,_call_back_data
dec word ptr [ebx]
jnz hs_end
mov ax,[ebx+2]
mov [ebx],ax
sti
call mixer_
cli
hs_end:
pop eax
pop ebx
pop edx
pop esi
pop ds
iretd
_TEXT ends
_TEXT16 SEGMENT BYTE PUBLIC USE16 'CODE'
ASSUME cs:_TEXT16
public rm_proc_:
rm_data_:
w_count:dw 2 ;citac preruseni
w_max dw 2 ;maximalni hodnota citace
rm_old dw ? ;stary vektor preruseni
dw ?
rm_proc_:
cli
int 1ch
cli
push si
xor si,si
dec word ptr cs:[si]
jnz w_skip
push ax
mov ax,cs:[si+2]
mov cs:[si],ax
pop ax
pushf
call dword ptr cs:[si+4]
w_skip: pop si
iret
rm_hspd db 300 dup(?)
high_speed:
push ds
push si
push bx
push dx
push ax
mov bx,offset rm_hspd-offset rm_data_
lds si,cs:[bx+scanofs]
mov dx,cs:[bx+port]
lodsb
xlat cs:
out dx,al
mov cs:[bx+scanofs],si
mov al,20h
out 20h,al
dec word ptr cs:[0]
jnz hspd_end
mov ax,cs:[2]
mov cs:[0],ax
pushf
call dword ptr cs:[4]
int 1ch
hspd_end:
pop ax
pop dx
pop bx
pop si
pop ds
iret
_TEXT16 ends
end