{$M 32000,100000,655000}
{$I-,R-,V-,S-,B-,G+}
uses dsp,crt,playDMA,dos,safe_IO,crt2,graph;
const MaxIns = 31;
Octaves : ARRAY[1..36] OF WORD = { Tuning-Tabelle fr 3 Oktaven }
(856,808,762,720,678,640,604,570,538,508,480,453,
428,404,381,360,339,320,302,285,269,254,240,226,
214,202,190,180,170,160,151,143,135,127,120,113);
SpeedFact = 1000;
type
MODInstrumentType = RECORD
SampName : ARRAY[0..21] OF CHAR; { Name des Instruments }
SampLen : WORD; { Lnge des Instr. in Worten }
SampTune : BYTE; { FineTune-Einstellung }
SampAmp : BYTE; { Lautst. des Instrumentes }
SampRepS : WORD; { Repeat-Start in Worten }
SampRepL : WORD; { Repeat-Lnge in Worten }
END;
MODHeaderType = RECORD
MODName : ARRAY[0..19] OF CHAR; { MOD-Filename }
MODInstr : ARRAY[1..MaxIns] OF MODInstrumentType; { Instrumente }
MODLen : BYTE; { Lnge des Songs }
MODMisc : BYTE; { CIAA-Speed }
MODPattr : ARRAY[1..128] OF BYTE; { Patternliste }
MODSign : ARRAY[1..4] OF CHAR; { Erkennungs-String }
END;
MODNoteType = ARRAY[1..4] OF BYTE; { Eine Note = 4 Bytes }
MODPatternLine = RECORD { Eine Patternzeile ist }
Channel1, Channel2, { fr 4 Kanle ausgelegt }
Channel3, Channel4 : MODNoteType;
END;
MODPatternType = array[1..64] of MODPatternLine;
dataType = array[1..64000] of byte;
var i:integer;
data: pointer; { Der Buffer }
Buffer1,Buffer2: pointer;
StopPlayer,ReadyForExit: boolean;
UseBuffer: word;
OldInt15: pointer;
FileName: string;
ModF: file;
ModHeader: MODHeaderType;
SampleNames: array[1..MaxIns] of string[22];
Samples: array[1..MaxIns] of pointer;
SampleSizes: array[1..MaxIns] of word;
SampleVols: array[0..MaxIns] of byte; { Volume (0..63) }
SampleRepS,SampleRepL: array[0..MaxIns] of word;
Arrangement: array[1..128] of byte;
Patterns: array[1..128] of ^MODPatternType;
TotPatterns: byte;
OctArray: array[0..855] of byte; { Fr schnellere Notenum-Funktion }
BufferSize: word;
BufferLim,BufferCtr: word;
AktPattern,AktLine: word;
PatternNum: byte;
MixAnz: byte;
AdditVal,ctr: word;
DataSeg,DataOfs: word;
Channel1Seg,Channel1Ofs,
Channel2Seg,Channel2Ofs,
Channel3Seg,Channel3Ofs,
Channel4Seg,Channel4Ofs: word;
Channel1Size,Channel2Size,
Channel3Size,Channel4Size: word;
Channel1Inst,Channel2Inst,
Channel3Inst,Channel4Inst: word;
Channel1Note,Channel2Note,
Channel3Note,Channel4Note: word;
Channel1Vol,Channel2Vol,
Channel3Vol,Channel4Vol: byte;
Channel1RepS,Channel1RepL,
Channel2RepS,Channel2RepL,
Channel3RepS,Channel3RepL,
Channel4RepS,Channel4RepL: word;
Channel1RepLim,Channel2RepLim,
Channel3RepLim,Channel4RepLim: word;
Channel1Rep,Channel2Rep,
Channel3Rep,Channel4Rep: byte;
SpeedListVK,
SpeedListNK: array[1..1000] of word;
Channel1VK,Channel1NK,
Channel2VK,Channel2NK,
Channel3VK,Channel3NK,
Channel4VK,Channel4NK: word;
Channel1SpVK,Channel1SpNK, { Die "Speedkonstanten" fr die Kanle }
Channel2SpVK,Channel2SpNK,
Channel3SpVK,Channel3SpNK,
Channel4SpVK,Channel4SpNK: word;
Speed: byte;
DataAddr: longint;
AddrAndFFFF: word;
FSize: word;
Freq,FreqDiv50: word;
ch: char;
OldLine,OldLine2: byte;
Channel1Peak,Channel2Peak,Channel3Peak,Channel4Peak: byte;
PeakLimit,PeakCtr,OPeakCtr,PeakCtr2: byte;
OldPattern: byte;
s: string;
result: word;
PatternBreak: boolean;
addr: longint; { Fr 'NewInt15 }
IntNo: byte;
t1,t2: word; {..}
WriteInstrs: boolean;
OldInt1C: pointer;
gd,gm: integer;
grmode: boolean;
oldosci: array[1..640] of byte;
oscipos: word;
olddrwnbuf: word;
max,min,med: byte;
channel1buf,channel2buf,channel3buf,channel4buf: pointer;
channelbufs: array[1..4] of pointer;
Channel1BSeg,Channel2BSeg,Channel3BSeg,Channel4BSeg: word;
Channel1BPos,Channel2BPos,Channel3BPos,Channel4BPos: word;
ChannelOsciPos: array[1..4] of word;
oldchannelosci: array[1..4,1..640] of byte;
maxc,minc,medc: array[1..4] of byte;
totc: array[1..4] of longint;
procedure sbFehler;
begin
fehler('DSP kann nicht beschrieben werden');
end;
procedure schreib_dsp(wert : Byte); assembler;
asm
mov cx,10000 { cx = Counter }
mov dx,BASE
add dx,0Ch
@Loop1:
inc bx
in al,dx
and al,80h
cmp al,0
je @OK1
loop @Loop1
call sbFehler
@OK1:
mov al,wert
out dx,al
end;
procedure Schreib_dsp_asm; assembler; { 'Wert' in ah }
asm
mov cx,10000 { cx = Counter }
mov dx,BASE
add dx,0Ch
@Loop1:
inc bx
in al,dx
and al,80h
cmp al,0
je @OK1
loop @Loop1
call sbFehler
@OK1:
xchg ah,al
out dx,al
end;
FUNCTION NoteName(Period : WORD):String;
CONST
NNames : ARRAY[0..11] OF String[2] =
('C-','C#','D-','D#','E-','F-','F#','G-','G#','A-','A#','H-');
VAR
WorkStr : String;
NCount : BYTE;
BEGIN
NCount := 1;
NoteName := '???';
IF (Period = 0) THEN BEGIN
NCount := 37;
NoteName := '---';
END;
WHILE (NCount <= 36) DO BEGIN
IF (Period = Octaves[NCount]) THEN BEGIN
Dec(Ncount);
Str((NCount DIV 12)+1,WorkStr);
NoteName := NNames[NCount-(NCount DIV 12)*12]+WorkStr;
NCount := 37;
END;
Inc(NCount);
END;
END;
function NoteNum(val: word):byte;
var i,n:byte;
begin
n := 0;
for i := 1 to 36 do
if Octaves[i] = val then n := i;
NoteNum := n;
end;
procedure NoteNum_asm; assembler; { selbe Funktion wie oben, allerdings fr Assemblergebrauch:
in: bx = val
out: ax = nummer }
asm
xor ah,ah
mov al,ds:[offset octarray+bx-1]
end;
procedure ReadModFile;
var ctr,ctr2,i,_SSeg,_SOfs,SSize: word;
SamplesTotal,SampleOfs,FSize: LongInt;
begin
for ctr := 1 to MaxIns do begin
Samples[ctr] := nil;
SampleSizes[ctr] := 0;
end;
Close(ModF);
if IOResult <> 0 then ;
Reset(ModF,1);
if IOResult <> 0 then begin
writeln('Ungltiger Dateiname');
halt;
end;
FSize := FileSize(ModF);
BlockRead(ModF,ModHeader,SizeOf(ModHeader));
SamplesTotal := 0;
for ctr := 1 to MaxIns do begin
Inc(SamplesTotal,Swap(ModHeader.MODInstr[ctr].SampLen)*2);
SampleVols[ctr] := ModHeader.MODInstr[ctr].SampAmp;
SampleRepS[ctr] := Swap(ModHeader.MODInstr[ctr].SampRepS)*2;
SampleRepL[ctr] := Swap(ModHeader.MODInstr[ctr].SampRepL)*2;
if SampleRepL[ctr] < 10 then SampleRepL[ctr] := 0;
end;
SampleOfs := FSize-SamplesTotal;
Seek(ModF,SampleOfs);
for ctr := 1 to MaxIns do { Samples laden }
with ModHeader.MODInstr[ctr] do begin
i := 0;
SampleNames[ctr] := '';
while SampName[i] <> #0 do begin
SampleNames[ctr] := SampleNames[ctr]+SampName[i];
Inc(i);
end;
for i := Length(SampleNames[ctr]) to 22 do
SampleNames[ctr] := SampleNames[ctr]+' ';
SSize := Swap(Samplen)*2;
SampleSizes[ctr] := SSize;
if SSize > 0 then begin
GetMem(Samples[ctr],SSize);
FillChar(Samples[ctr]^,SSize,0);
BlockRead(ModF,Samples[ctr]^,SSize);
_SSeg := Seg(Samples[ctr]^);
_SOfs := Ofs(Samples[ctr]^);
(* for ctr2 := 1 to SSize do begin
if Mem[SSeg:SOfs] <= 0 then Mem[SSeg:SOfs] := 128-Abs(Mem[SSeg:SOfs])
else Mem[SSeg:SOfs] := Mem[SSeg:SOfs] + 128;
Inc(SOfs);
end;
*)
asm
push ds
mov cx,SSize
mov si,_SOfs
mov es,_SSeg
mov di,_SOfs
mov ds,_SSeg
@Loop1:
lodsb
sub al,128
stosb
loop @Loop1
pop ds
end;
end;
end;
Move(MODHeader.MODPattr,Arrangement,128);
TotPatterns := ModHeader.MODLen;
Seek(ModF, SizeOf(MODHeader)); { -- Pattern einlesen -- }
for ctr := 1 to ModHeader.ModLen do begin
New(Patterns[ctr]);
BlockRead(ModF,Patterns[ctr]^,SizeOf(Patterns[ctr]^));
end;
Close(modF);
end;
procedure InitSpeedList;
var i:integer;
begin
for i := 1 to 1000 do begin
SpeedListVK[i] := Trunc((60*60/i*1000)/freq);
SpeedListNK[i] := Round(Frac((60*60/i*1000)/freq)*SpeedFact);
{ z.B. VK = 1, NK = 233 -> SpeedList[x] = 1.233 }
end;
end;
procedure InitOctArray;
var i:word;
begin
FillChar(OctArray,sizeof(octarray),0);
for i := 0 to 855 do
if NoteNum(i+1) <> 0 then
OctArray[i] := Notenum(i+1);
end;
procedure InitChannelVars;
begin
DataSeg := Seg(data^);
DataOfs := Ofs(data^);
UseBuffer := 0;
Channel1VK := 0; Channel1NK := 0;
Channel2VK := 0; Channel2NK := 0;
Channel3VK := 0; Channel3NK := 0;
Channel4VK := 0; Channel4NK := 0;
Channel1Inst := 0; Channel1Note := 0; Channel1Size := 0;
Channel2Inst := 0; Channel2Note := 0; Channel2Size := 0;
Channel3Inst := 0; Channel3Note := 0; Channel3Size := 0;
Channel4Inst := 0; Channel4Note := 0; Channel4Size := 0;
Channel1Vol := 0; Channel2Vol := 0;
Channel3Vol := 0; Channel4Vol := 0;
Channel1RepS := 0; Channel1RepL := 0; Channel1Rep := 0; Channel1RepLim := 0;
Channel2RepS := 0; Channel2RepL := 0; Channel2Rep := 0; Channel2RepLim := 0;
Channel3RepS := 0; Channel3RepL := 0; Channel3Rep := 0; Channel3RepLim := 0;
Channel4RepS := 0; Channel4RepL := 0; Channel4Rep := 0; Channel4RepLim := 0;
Channel1SpVK := 0; Channel1SpNK := 0; Channel1Seg := 0; Channel1Ofs := 0;
Channel2SpVK := 0; Channel2SpNK := 0; Channel2Seg := 0; Channel2Ofs := 0;
Channel3SpVK := 0; Channel3SpNK := 0; Channel3Seg := 0; Channel3Ofs := 0;
Channel4SpVK := 0; Channel4SpNK := 0; Channel4Seg := 0; Channel4Ofs := 0;
end;
procedure IncPositions; assembler;
asm
@Channel1:
mov bx,Channel1VK
add bx,2
cmp bx,Channel1Size
jnb @SetToZero1
@OneOK1:
cmp Channel1Rep,0
jz @NoRep1
mov ax,Channel1RepLim
cmp Channel1VK,ax
jb @NoRep1
mov ax,Channel1RepS
mov Channel1VK,ax
@NoRep1:
mov ax,Channel1SpVK
add Channel1VK,ax
mov ax,Channel1SpNK
add Channel1NK,ax
mov ax,speedFact
cmp Channel1NK,ax
jbe @NothingToIncrease1
@DoIt1:
inc Channel1VK
sub Channel1NK,ax
jmp @NothingToIncrease1
@SetToZero1:
mov bx,channel1size
mov channel1vk,bx
cmp Channel1RepL,0
jz @NothingToIncrease1
mov Channel1Rep,1
mov ax,channel1RepS
mov Channel1VK,ax
@NothingToIncrease1:
@Channel2:
mov bx,Channel2VK
add bx,2
cmp bx,Channel2Size
jnb @SetToZero2
@OneOK2:
cmp Channel2Rep,0
jz @NoRep2
mov ax,Channel2RepLim
cmp Channel2VK,ax
jb @NoRep2
mov ax,Channel2RepS
mov Channel2VK,ax
@NoRep2:
mov ax,Channel2SpVK
add Channel2VK,ax
mov ax,Channel2SpNK
add Channel2NK,ax
mov ax,speedFact
cmp Channel2NK,ax
jbe @NothingToIncrease2
@DoIt2:
inc Channel2VK
sub Channel2NK,ax
jmp @NothingToIncrease2
@SetToZero2:
mov bx,channel2size
mov channel2vk,bx
cmp Channel2RepL,0
jz @NothingToIncrease2
mov Channel2Rep,1
mov ax,channel2RepS
mov Channel2VK,ax
@NothingToIncrease2:
@Channel3:
mov bx,Channel3VK
add bx,2
cmp bx,Channel3Size
jnb @SetToZero3
@OneOK3:
cmp Channel3Rep,0
jz @NoRep3
mov ax,Channel3RepLim
cmp Channel3VK,ax
jb @NoRep3
mov ax,Channel3RepS
mov Channel3VK,ax
@NoRep3:
mov ax,Channel3SpVK
add Channel3VK,ax
mov ax,Channel3SpNK
add Channel3NK,ax
mov ax,speedFact
cmp Channel3NK,ax
jbe @NothingToIncrease3
@DoIt3:
inc Channel3VK
sub Channel3NK,ax
jmp @NothingToIncrease3
@SetToZero3:
mov bx,channel3size
mov channel3vk,bx
cmp Channel3RepL,0
jz @NothingToIncrease3
mov Channel3Rep,1
mov ax,channel3RepS
mov Channel3VK,ax
@NothingToIncrease3:
@Channel4:
mov bx,Channel4VK
add bx,2
cmp bx,Channel4Size
jnb @SetToZero4
@OneOK4:
cmp Channel4Rep,0
jz @NoRep4
mov ax,Channel4RepLim
cmp Channel4VK,ax
jb @NoRep4
mov ax,Channel4RepS
mov Channel4VK,ax
@NoRep4:
mov ax,Channel4SpVK
add Channel4VK,ax
mov ax,Channel4SpNK
add Channel4NK,ax
mov ax,speedFact
cmp Channel4NK,ax
jbe @NothingToIncrease4
@DoIt4:
inc Channel4VK
sub Channel4NK,ax
jmp @NothingToIncrease4
@SetToZero4:
mov bx,channel4Size
mov channel4vk,bx
cmp Channel4RepL,0
jz @NothingToIncrease4
mov Channel4Rep,1
mov ax,channel4RepS
mov Channel4VK,ax
@NothingToIncrease4:
end;
procedure AddSamples; assembler;
asm
mov AdditVal,0
mov MixAnz,4
xor ah,ah
@Channel1:
cmp Channel1Seg,0
jz @OK1
@ThreeOK1:
mov es,Channel1Seg
mov di,Channel1Ofs
add di,Channel1VK
mov al,es:[di]
mov bl,Channel1Vol
mul bl
shr ax,6
add AdditVal,ax
{ mov es,Channel1BSeg
mov di,Channel1BPos
stosb
inc Channel1BPos}
@OK1:
{ --------------------------------------------------------------- }
@Channel2:
cmp Channel2Seg,0
jz @OK2
@ThreeOK2:
mov es,Channel2Seg
mov di,Channel2Ofs
add di,Channel2VK
mov al,es:[di]
mov bl,Channel2Vol
mul bl
shr ax,6
add AdditVal,ax
{ mov es,Channel2BSeg
mov di,Channel2BPos
stosb
inc Channel2BPos}
@OK2:
{ --------------------------------------------------------------- }
@Channel3:
cmp Channel3Seg,0
jz @OK3
@ThreeOK3:
mov es,Channel3Seg
mov di,Channel3Ofs
add di,Channel3VK
mov al,es:[di]
mov bl,Channel3Vol
mul bl
shr ax,6
add AdditVal,ax
{ mov es,Channel3BSeg
mov di,Channel3BPos
stosb
inc Channel3BPos
}
@OK3:
{ --------------------------------------------------------------- }
@Channel4:
cmp Channel4Seg,0
jz @OK4
@ThreeOK4:
mov es,Channel4Seg
mov di,Channel4Ofs
add di,Channel4VK
mov al,es:[di]
mov bl,Channel4Vol
mul bl
shr ax,6
add AdditVal,ax
{ mov es,Channel4BSeg
mov di,Channel4BPos
stosb
inc Channel4BPos
}
@OK4:
end;
procedure GetNotes; assembler;
var LineSeg,LineOfs: word;
bval1: byte;
val1: word;
flag1: byte;
c1b1,c1b2,c1b3,c1b4,
c2b1,c2b2,c2b3,c2b4,
c3b1,c3b2,c3b3,c3b4,
c4b1,c4b2,c4b3,c4b4: byte;
aktspeed: byte;
asm
cmp PatternBreak,1
jz @IncPattern
cmp aktline,64
jnz @IncLine
@IncPattern:
mov PatternBreak,0
mov si,offset Arrangement
xor ah,ah
mov al,patternNum
add si,ax
lodsb
inc al
mov aktpattern,ax
mov aktline,1
inc patternNum
jmp @Weiter1
@IncLine:
inc aktline
@Weiter1:
mov si,offset patterns
mov ax,aktpattern
dec ax
shl ax,2
add si,ax
lodsw
mov bx,aktline
dec bx
shl bx,4
add ax,bx
mov LineOfs,ax
lodsw
mov lineSeg,ax
{ ----- Channel 1 -------- }
mov es,lineseg
mov di,lineofs
mov al,byte ptr es:[di]
mov c1b1,al
mov al,byte ptr es:[di+1]
mov c1b2,al
mov al,byte ptr es:[di+2]
mov c1b3,al
mov al,byte ptr es:[di+3]
mov c1b4,al
mov al,byte ptr es:[di+4]
mov c2b1,al
mov al,byte ptr es:[di+5]
mov c2b2,al
mov al,byte ptr es:[di+6]
mov c2b3,al
mov al,byte ptr es:[di+7]
mov c2b4,al
mov al,byte ptr es:[di+8]
mov c3b1,al
mov al,byte ptr es:[di+9]
mov c3b2,al
mov al,byte ptr es:[di+10]
mov c3b3,al
mov al,byte ptr es:[di+11]
mov c3b4,al
mov al,byte ptr es:[di+12]
mov c4b1,al
mov al,byte ptr es:[di+13]
mov c4b2,al
mov al,byte ptr es:[di+14]
mov c4b3,al
mov al,byte ptr es:[di+15]
mov c4b4,al
mov aktspeed, 0FFh
@Channel1:
mov flag1,1
mov ah,c1b1
and ah,0F0h
mov al,c1b3
shr al,4
add al,ah
cmp al,0
jnz @OK1
mov al,c1b3
and al,0Fh
cmp al,0
jz @NextInst1
mov flag1,0
jmp @Effects1
@OK1:
xor ah,ah
mov Channel1Rep,0
push ax
mov si,offset SampleVols
add si,ax
lodsb
mov Channel1Vol,al
pop ax
mov Channel1Inst,ax
dec ax
shl ax,1
mov si,offset SampleSizes
add si,ax
lodsw
dec ax
mov Channel1Size,ax
@Effects1:
mov bl,c1b3 { auf Effekte berprfen }
and bl,0Fh
cmp bl,12
jnz @NoVolSet1
mov al,c1b4
mov channel1vol,al
jmp @VolSet1
@NoVolSet1:
@VolSet1:
cmp bl,10 { Vol-Slide }
jnz @NoVolSlide1
cmp c1b4,0Fh
jg @SlideUp1
mov al,c1b4
sub channel1vol,al
jmp @NoVolSlide1
@SlideUp1:
mov al,c1b4
shr al,4
add channel1vol,al
@NoVolSlide1:
cmp bl,13
jne @NoPatternBreak1
mov PatternBreak,1
@NoPatternBreak1:
cmp bl,15
jnz @NoSpeedSet1
mov al,c1b4
cmp al,aktspeed
jnb @NoSpeedSet1
mov aktspeed,al
@NoSpeedSet1: { ---- }
cmp flag1,0
jz @NextInst1
mov si,offset SampleRepS
mov bx,channel1inst
shl bx,1
add si,bx
lodsw
mov Channel1RepS,ax
mov si,offset SampleRepL
add si,bx
lodsw
mov Channel1RepL,ax
mov bx,Channel1RepS
add ax,bx
mov Channel1RepLim,ax
mov ah,c1b1
mov al,c1b2
and ah,0Fh
cmp ax,0 {!!!!!!!!!}
jz @NextInst1
mov Channel1Note,ax
mov channel1VK,1
mov channel1NK,0
mov ax,Channel1Inst { Sample-Segs/Ofs ausrechnen }
dec ax
shl ax,2
mov si,offset Samples
add si,ax
lodsw
mov Channel1Ofs,ax
lodsw
mov Channel1Seg,ax
mov ax,Channel1Note { Speedkonstanten ausrechnen }
shl ax,1
mov si,offset SpeedListVK
add si,ax
lodsw
mov Channel1SpVK,ax
mov ax,Channel1Note
shl ax,1
mov si,offset SpeedListNK
add si,ax
lodsw
mov Channel1SpNK,ax
@NextInst1: { -- Ready! -- }
@Channel2:
mov flag1,1
mov ah,c2b1
and ah,0F0h
mov al,c2b3
shr al,4
add al,ah
cmp al,0
jnz @OK2
mov al,c2b3
and al,0Fh
cmp al,0
jz @NextInst2
mov flag1,0
jmp @Effects2
@OK2:
xor ah,ah
mov Channel2Rep,0
push ax
mov si,offset SampleVols
add si,ax
lodsb
mov Channel2Vol,al
pop ax
mov Channel2Inst,ax
dec ax
shl ax,1
mov si,offset SampleSizes
add si,ax
lodsw
dec ax
mov Channel2Size,ax
@Effects2:
mov bl,c2b3 { auf Effekte berprfen }
and bl,0Fh
cmp bl,12
jnz @NoVolSet2
mov al,c2b4
mov channel2vol,al
jmp @VolSet2
@NoVolSet2:
@VolSet2:
cmp bl,10 { Vol-Slide }
jnz @NoVolSlide2
cmp c2b4,0Fh
jg @SlideUp2
mov al,c2b4
sub channel2vol,al
jmp @NoVolSlide2
@SlideUp2:
mov al,c2b4
shr al,4
add channel2vol,al
@NoVolSlide2:
cmp bl,13
jne @NoPatternBreak2
mov PatternBreak,1
@NoPatternBreak2:
cmp bl,15
jnz @NoSpeedSet2
mov al,c2b4
cmp al,aktspeed
jnb @NoSpeedSet2
mov aktspeed,al
@NoSpeedSet2: { ---- }
cmp flag1,0
jz @NextInst2
mov si,offset SampleRepS
mov bx,channel2inst
shl bx,1
add si,bx
lodsw
mov Channel2RepS,ax
mov si,offset SampleRepL
add si,bx
lodsw
mov Channel2RepL,ax
mov bx,Channel2RepS
add ax,bx
mov Channel2RepLim,ax
mov ah,c2b1
mov al,c2b2
and ah,0Fh
cmp ax,0 {!!!!!!!!!}
jz @NextInst2
mov Channel2Note,ax
mov channel2VK,1
mov channel2NK,0
mov ax,Channel2Inst { Sample-Segs/Ofs ausrechnen }
dec ax
shl ax,2
mov si,offset Samples
add si,ax
lodsw
mov Channel2Ofs,ax
lodsw
mov Channel2Seg,ax
mov ax,Channel2Note { Speedkonstanten ausrechnen }
shl ax,1
mov si,offset SpeedListVK
add si,ax
lodsw
mov Channel2SpVK,ax
mov ax,Channel2Note
shl ax,1
mov si,offset SpeedListNK
add si,ax
lodsw
mov Channel2SpNK,ax
@NextInst2:
@Channel3:
mov flag1,1
mov ah,c3b1
and ah,0F0h
mov al,c3b3
shr al,4
add al,ah
cmp al,0
jnz @OK3
mov al,c3b3
and al,0Fh
cmp al,0
jz @NextInst3
mov flag1,0
jmp @Effects3
@OK3:
xor ah,ah
mov Channel3Rep,0
push ax
mov si,offset SampleVols
add si,ax
lodsb
mov Channel3Vol,al
pop ax
mov Channel3Inst,ax
dec ax
shl ax,1
mov si,offset SampleSizes
add si,ax
lodsw
dec ax
mov Channel3Size,ax
@Effects3:
mov bl,c3b3 { auf Effekte berprfen }
and bl,0Fh
cmp bl,12
jnz @NoVolSet3
mov al,c3b4
mov channel3vol,al
jmp @VolSet3
@NoVolSet3:
@VolSet3:
cmp bl,10 { Vol-Slide }
jnz @NoVolSlide3
cmp c3b4,0Fh
jg @SlideUp3
mov al,c3b4
sub channel3vol,al
jmp @NoVolSlide3
@SlideUp3:
mov al,c3b4
shr al,4
add channel3vol,al
@NoVolSlide3:
cmp bl,13
jne @NoPatternBreak3
mov PatternBreak,1
@NoPatternBreak3:
cmp bl,15
jnz @NoSpeedSet3
mov al,c3b4
cmp al,aktspeed
jnb @NoSpeedSet3
mov aktspeed,al
@NoSpeedSet3: { ---- }
cmp flag1,0
jz @NextInst3
mov si,offset SampleRepS
mov bx,channel3inst
shl bx,1
add si,bx
lodsw
mov Channel3RepS,ax
mov si,offset SampleRepL
add si,bx
lodsw
mov Channel3RepL,ax
mov bx,Channel3RepS
add ax,bx
mov Channel3RepLim,ax
mov ah,c3b1
mov al,c3b2
and ah,0Fh
cmp ax,0 {!!!!!!!!!}
jz @NextInst3
mov Channel3Note,ax
mov channel3VK,1
mov channel3NK,0
mov ax,Channel3Inst { Sample-Segs/Ofs ausrechnen }
dec ax
shl ax,2
mov si,offset Samples
add si,ax
lodsw
mov Channel3Ofs,ax
lodsw
mov Channel3Seg,ax
mov ax,Channel3Note { Speedkonstanten ausrechnen }
shl ax,1
mov si,offset SpeedListVK
add si,ax
lodsw
mov Channel3SpVK,ax
mov ax,Channel3Note
shl ax,1
mov si,offset SpeedListNK
add si,ax
lodsw
mov Channel3SpNK,ax
@NextInst3:
@Channel4:
mov flag1,1
mov ah,c4b1
and ah,0F0h
mov al,c4b3
shr al,4
add al,ah
cmp al,0
jnz @OK4
mov al,c4b3
and al,0Fh
cmp al,0
jz @NextInst4
mov flag1,0
jmp @Effects4
@OK4:
xor ah,ah
mov Channel4Rep,0
push ax
mov si,offset SampleVols
add si,ax
lodsb
mov Channel4Vol,al
pop ax
mov Channel4Inst,ax
dec ax
shl ax,1
mov si,offset SampleSizes
add si,ax
lodsw
dec ax
mov Channel4Size,ax
@Effects4:
mov bl,c4b3 { auf Effekte berprfen }
and bl,0Fh
cmp bl,12
jnz @NoVolSet4
mov al,c4b4
mov channel4vol,al
jmp @VolSet4
@NoVolSet4:
@VolSet4:
cmp bl,10 { Vol-Slide }
jnz @NoVolSlide4
cmp c4b4,0Fh
jg @SlideUp4
mov al,c4b4
sub channel4vol,al
jmp @NoVolSlide4
@SlideUp4:
mov al,c4b4
shr al,4
add channel4vol,al
@NoVolSlide4:
cmp bl,13
jne @NoPatternBreak4
mov PatternBreak,1
@NoPatternBreak4:
cmp bl,15
jnz @NoSpeedSet4
mov al,c4b4
cmp al,aktspeed
jnb @NoSpeedSet4
mov aktspeed,al
@NoSpeedSet4: { ---- }
cmp flag1,0
jz @NextInst4
mov si,offset SampleRepS
mov bx,channel4inst
shl bx,1
add si,bx
lodsw
mov Channel4RepS,ax
mov si,offset SampleRepL
add si,bx
lodsw
mov Channel4RepL,ax
mov bx,Channel4RepS
add ax,bx
mov Channel4RepLim,ax
mov ah,c4b1
mov al,c4b2
and ah,0Fh
cmp ax,0 {!!!!!!!!!}
jz @NextInst4
mov Channel4Note,ax
mov channel4VK,1
mov channel4NK,0
mov ax,Channel4Inst { Sample-Segs/Ofs ausrechnen }
mov si,offset SpeedListVK
dec ax
shl ax,2
mov si,offset Samples
add si,ax
lodsw
mov Channel4Ofs,ax
lodsw
mov Channel4Seg,ax
mov ax,Channel4Note { Speedkonstanten ausrechnen }
shl ax,1
mov si,offset SpeedListVK
add si,ax
lodsw
mov Channel4SpVK,ax
mov ax,Channel4Note
shl ax,1
mov si,offset SpeedListNK
add si,ax
lodsw
mov Channel4SpNK,ax
@NextInst4:
cmp aktspeed,0FFh
je @NoSpeedSet
mov al,aktspeed
mov speed,al
xor bh,bh
mov ax,freqDiv50
mov bl,speed
mul bx
mov bufferlim,ax
@NoSpeedSet:
cmp Channel1Vol,65
jb @Vol1OK
mov Channel1Vol,0
@Vol1OK:
cmp Channel2Vol,65
jb @Vol2OK
mov Channel2Vol,0
@Vol2OK:
cmp Channel3Vol,65
jb @Vol3OK
mov Channel3Vol,0
@Vol3OK:
cmp Channel4Vol,65
jb @Vol4OK
mov Channel4Vol,0
@Vol4OK:
end;
procedure Mix; assembler;
asm
mov channel1bpos,0
mov channel2bpos,0
mov channel3bpos,0
mov channel4bpos,0
mov ctr,-1
mov cx,buffersize
@BigLoop:
push cx
inc ctr
inc bufferctr
mov ax,bufferctr
cmp ax,bufferlim
jz @NewNote
jmp @IncVars
@NewNote:
mov bufferctr,0
call GetNotes
mov al,totPatterns
mov bl,patternnum
cmp bl,al
jbe @IncVars
mov ctr,-1
mov StopPlayer,1
jmp @ToBigLoop
@IncVars:
call IncPositions
call AddSamples
mov di,DataOfs
mov es,DataSeg
add di,ctr
mov ax,additval
mov cl,MixAnz
div cl
stosb
@ToBigLoop:
pop cx
loop @BigLoop
end;
{ -------------------------------------------------------------------------
-------------------------------------------------------------------------
------------------------------------------------------------------------- }
procedure IRQ7Sperren;
var b: byte;
begin
b := port[$21];
port[$21] := b or 32;
end;
procedure IRQ7Freigeben;
var b: byte;
begin
b := port[$21];
port[$21] := b and (not 32);
end;
procedure Enable; assembler;
asm
sti;
end;
procedure Disable; assembler;
asm
cli;
end;
procedure SetOldInt15;
begin
SetIntVec(IntNo,OldInt15);
end;
procedure SetAddrs;
begin
if Usebuffer = 0 then begin
addr := (Longint(Seg(Buffer2^)) shl 4)+Ofs(Buffer2^);
DataSeg := Seg(Buffer2^);
DataOfs := Ofs(Buffer2^);
Data := Buffer2;
end
else begin
addr := (Longint(Seg(Buffer1^)) shl 4)+Ofs(Buffer1^);
DataSeg := Seg(Buffer1^);
DataOfs := Ofs(buffer1^);
Data := buffer1;
end;
t1 := addr and $FFFF;
t2 := addr shr 16;
end;
procedure NewInt15; interrupt;
var b: byte;
addr: longint;
t: word;
dummy: Pointer;
begin
b := port[$22E];
port[$20] := $20;
Inc(PeakCtr);
if StopPlayer then begin
IRQ7Sperren;
Disable;
SetIntVec(13,OldInt15);
Enable;
IRQ7Freigeben;
ReadyForExit := true;
Exit;
end;
ReadyForExit := false;
if UseBuffer = 0 then UseBuffer := BufferSize
else UseBuffer := 0;
addr := (Longint(Seg(data^)) shl 4 ) + UseBuffer;
port[$0A] := $05;
port[$0C] := 0;
port[$0B] := $49;
t := addr and $FFFF;
port[$02] := t and $FF;
port[$02] := t shr 8;
t := addr shr 16;
port[$83] := t;
port[$03] := (BufferSize-1) and $FF;
port[$03] := (BufferSize-1) shr 8;
port[$0A] := $01;
schreib_dsp($14);
schreib_dsp((BufferSize-1) and $FF);
schreib_dsp((BufferSize-1) shr 8);
if UseBuffer = 0 then begin
DataSeg := Seg(buffer2^);
DataOfs := Ofs(buffer2^);
end
else begin
DataSeg := Seg(buffer1^);
DataOfs := Ofs(buffer1^);
end;
Mix;
OsciPos := 0;
end;
procedure StartMOD_DMA;
var addr: longint;
t: word;
begin
UseBuffer := 0;
ReadyForExit := false;
StopPlayer := false;
DataSeg := Seg(Buffer1^);
DataOfs := Ofs(Buffer1^);
PatternNum := 1;
Mix;
addr := (Longint(Seg(Data^)) shl 4 ) + UseBuffer;
IRQ7Sperren;
Disable;
GetIntVec(13,OldInt15);
SetIntVec(13,@NewInt15);
schreib_dsp($40);
schreib_dsp(256-(1000000 div Freq));
port[$0A] := $05;
port[$0C] := 0;
port[$0B] := $49;
t := addr and $FFFF;
port[$02] := t and $FF;
port[$02] := t shr 8;
t := addr shr 16;
port[$83] := t;
port[$03] := (BufferSize-1) and $FF;
port[$03] := (BufferSize-1) shr 8;
port[$0A] := $01;
Enable;
IRQ7Freigeben;
schreib_dsp($14);
schreib_dsp((BufferSize-1) and $FF);
schreib_dsp((BufferSize-1) shr 8);
if UseBuffer = 0 then begin
DataSeg := Seg(buffer2^);
DataOfs := Ofs(buffer2^);
end
else begin
DataSeg := Seg(buffer1^);
DataOfs := Ofs(buffer1^);
end;
Mix;
end;
procedure StopMOD;
begin
StopPlayer := true;
end;
function MODPlaying:boolean;
begin
MODPlaying := ReadyForExit = false;
end;
{ --------------------- Bildschirmroutinen ------------------------
(sind nicht fr den Player notwendig)
}
procedure BildschirmMaske;
var s1,s2,s3: string;
procedure WriteInstrTab;
var i: byte;
color,color2: byte;
begin
TextBackGround(Black);
color := Cyan;
color2 := Darkgray;
for i := 1 to 16 do begin
GotoXY(5,8+i);
if SampleSizes[i] > 1 then
TextColor(Color)
else TextColor(Color2);
write('#',i,': ',SampleNames[i]);
end;
for i := 1 to 15 do begin
GotoXY(35,8+i);
if SampleSizes[i+16] > 1 then
TextColor(Color)
else TextColor(Color2);
write('#',i+16,': ',SampleNames[i+16]);
end;
TextColor(LightGray);
end;
begin
if (not grMode) then begin
TextColor(LightGray); TextBackGround(black);
ClrScr;
TextColor(Yellow); TextBackGround(Blue);
FSplit(FileName,s1,s2,s3);
write('MODPlay v1.0 by Daniel Lichtenberger ',s2+s3:12);
TextColor(Cyan); TextBackGround(Black);
Rahmen(2,3,45,8,Cyan,EinfachLin,EinfachLin,EinfachLin,EinfachLin);
TextColor(LightGray); TextBackGround(Black);
GotoXY(50,7);
write('Samplefrequenz: ',freq/1000:2:1,' khz');
GotoXY(50,6);
write('Speed: /50 Sek/Note');
GotoXY(50,4);
write('Pattern # ');
GotoXY(50,5);
write('Akt. Notenzeile:');
WriteInstrTab;
end
else begin
gd := Detect;
InitGraph(gd,gm,'C:\BP\BGI');
SetColor(Lightgray);
Rectangle(149,300-100,150+321,300+100);
end;
OldLine := 255;
FillChar(OldOsci,640,0);
FillChar(ChannelOsciPos,SizeOf(ChannelOsciPos),0);
OldDrwnBuf := 0;
OsciPos := 0;
end;
procedure WriteInstrBox;
var i:byte;
begin
if WriteInstrs then begin
GotoXY(3,4);
if Channel1Inst > 0 then
write('#',Channel1Inst,': ',SampleNames[Channel1Inst])
else write(' ');
GotoXY(3,5);
if Channel2Inst > 0 then
write('#',Channel2Inst,': ',SampleNames[Channel2Inst])
else write(' ');
GotoXY(3,6);
if Channel3Inst > 0 then
write('#',Channel3Inst,': ',SampleNames[Channel3Inst])
else write(' ');
GotoXY(3,7);
if Channel4Inst > 0 then
write('#',Channel4Inst,': ',SampleNames[Channel4Inst])
else write(' ');
end
else
begin;
GotoXY(3,4);
if Channel1Inst > 0 then
write('#',Channel1Inst)
else write(' ');
GotoXY(3,5);
if Channel2Inst > 0 then
write('#',Channel2Inst)
else write(' ');
GotoXY(3,6);
if Channel3Inst > 0 then
write('#',Channel3Inst)
else write(' ');
GotoXY(3,7);
if Channel4Inst > 0 then
write('#',Channel4Inst)
else write(' ');
end;
end;
procedure WriteNotes;
var i:byte;
begin
GotoXY(3,10);
Delline;
if AktLine = 1 then DelLine;
GotoXY(3,23);
with Patterns[AktPattern]^[AktLine] do
write(NoteName((Channel1[1] AND $0F)*256+(Channel1[2])),' (',((Channel1[1] AND $F0)+(Channel1[3] SHR 4)):2,') ³ ',
NoteName((Channel2[1] AND $0F)*256+(Channel2[2])),' (',((Channel2[1] AND $F0)+(Channel2[3] SHR 4)):2,') ³ ',
NoteName((Channel3[1] AND $0F)*256+(Channel3[2])),' (',((Channel3[1] AND $F0)+(Channel3[3] SHR 4)):2,') ³ ',
NoteName((Channel4[1] AND $0F)*256+(Channel4[2])),' (',((Channel4[1] AND $F0)+(Channel4[3] SHR 4)):2,') ');
end;
procedure DrawPeak;
var i:byte;
PeakChar: char;
begin;
PeakChar := #22;
if Channel1Peak >= 2 then Dec(Channel1Peak,2)
else Channel1Peak := 0;
if Channel2Peak >= 2 then Dec(Channel2Peak,2)
else Channel2Peak := 0;
if Channel3Peak >= 2 then Dec(Channel3Peak,2)
else Channel3Peak := 0;
if Channel4Peak >= 2 then Dec(Channel4Peak,2)
else Channel4Peak := 0;
if AktLine <> OldLine2 then
with Patterns[Aktpattern]^[AktLine] do begin
OldLine2 := AktLine;
if (Channel1[1] AND $F0)+(Channel1[3] SHR 4) <> 0 then
Channel1Peak := PeakLimit;
if (Channel2[1] AND $F0)+(Channel2[3] SHR 4) <> 0 then
Channel2Peak := PeakLimit;
if (Channel3[1] AND $F0)+(Channel3[3] SHR 4) <> 0 then
Channel3Peak := PeakLimit;
if (Channel4[1] AND $F0)+(Channel4[3] SHR 4) <> 0 then
Channel4Peak := PeakLimit;
end;
GotoXY(31,4);
if Channel1Peak > 0 then begin
TextColor(Green);
for i := 1 to Channel1Peak-1 do write(PeakChar);
TextColor(Red);
write(PeakChar);
end;
for i := Channel1Peak to PeakLimit do write(' ');
GotoXY(31,5);
if Channel2Peak > 0 then begin
TextColor(Green);
for i := 1 to Channel2Peak-1 do write(PeakChar);
TextColor(Red);
write(PeakChar);
end;
for i := Channel2Peak to PeakLimit do write(' ');
GotoXY(31,6);
if Channel3Peak > 0 then begin
TextColor(Green);
for i := 1 to Channel3Peak-1 do write(PeakChar);
TextColor(Red);
write(PeakChar);
end;
for i := Channel3Peak to PeakLimit do write(' ');
GotoXY(31,7);
if Channel4Peak > 0 then begin
TextColor(Green);
for i := 1 to Channel4Peak-1 do write(PeakChar);
TextColor(Red);
write(PeakChar);
end;
for i := Channel4Peak to PeakLimit do write(' ');
TextColor(Lightgray);
end;
procedure WriteAktPattern;
begin
GotoXY(59,4);
write(Patternnum,' (',aktpattern,') ');
GotoXY(67,5);
write(AktLine,' ')
end;
procedure put(x,y:integer;farbe:byte); assembler;
asm
mov ax,80
mul y
mov bx,ax
mov ax,x
mov cl,8
div cl
mov cl,ah
and ah,0
add bx,ax
or ah,128
shr ah,cl
mov dx,3CEh
mov al,8
out dx,ax
mov ax,285h
out dx,ax
mov ax,0A000h
mov es,ax
mov al,es:[bx]
mov al,farbe
mov es:[bx],al
end;
procedure ScrType1;
procedure DrawChannelOscis;
var i,k:integer;
begin
SetViewPort(10,10,150+3*140,120,true);
ClearViewPort;
for k := 1 to 4 do begin
SetViewPort(10+140*(k-1),10,150+140*(k-1),120,true);
{ for i := 1 to 140 do begin
if oldchannelosci[k,i*2] >= medc[k] then
PutPixel(i,60+(oldchannelosci[k,i*2]-medc[k]),black)
else PutPixel(i,60-(medc[k]-oldchannelosci[k,i*2]),black);
end;}
Move(Mem[Seg(channelbufs[k]^):Ofs(channelbufs[k]^)+channeloscipos[k]],oldchannelosci[k],280);
maxc[k] := 0; minc[k] := $FF; totc[k] := 0;
for i := 1 to 140 do begin
oldchannelosci[k,i*2] := oldchannelosci[k,i*2] shr 2;
if oldchannelosci[k,i*2] > maxc[k] then maxc[k] := oldchannelosci[k,i*2]
else if oldchannelosci[k,i*2] < minc[k] then minc[k] := oldchannelosci[k,i*2];
Inc(totc[k],oldchannelosci[k,i*2]);
end;
medc[k] := (totc[k] div 140)-minc[k];
for i := 1 to 140 do
Dec(oldchannelosci[k,i*2],minc[k]);
for i := 1 to 140 do begin
if oldchannelosci[k,i*2] >= medc[k] then
Put(i,60+(oldchannelosci[k,i*2]-medc[k]),green)
else Put(i,60-(medc[k]-oldchannelosci[k,i*2]),green);
end;
Inc(channelOsciPos[k],880);
if channelOsciPos[k] > (BufferSize-320) then channelOsciPos[k] := 0;
if aktline <> oldline then begin
channelOsciPos[k] := 0;
end;
end;
end;
procedure DrawOscis;
var i: integer;
tot: longint;
begin
{ DrawChannelOscis;
SetViewPort(150,300-99,150+320,300+99,true);}
for i := 1 to 320 do begin
if oldosci[i*2] >= med then
Put(150+i,201+100+(oldosci[i*2]-med),black)
else Put(150+i,201+100-(med-oldosci[i*2]),black);
end;
if useBuffer = 0 then
Move(Mem[Seg(buffer1^):Ofs(buffer1^)+oscipos],oldosci,640)
else Move(Mem[Seg(buffer2^):Ofs(buffer2^)+oscipos],oldosci,640);
max := 0; min := $FF; tot := 0;
for i := 1 to 640 do begin
if oldosci[i] > max then max := oldosci[i]
else if oldosci[i] < min then min := oldosci[i];
Inc(tot,oldosci[i]);
end;
{ asm
mov si,offset oldosci
mov cx,639
xor ah,ah
@MaxMinLoop:
lodsb
add word ptr tot,ax
cmp al,max
jg @NewMax
cmp al,min
jb @NewMin
loop @MaxMinLoop
jmp @Ende
@NewMax:
mov max,al
loop @MaxMinLoop
jmp @Ende
@NewMin:
mov min,al
loop @MaxMinLoop
@Ende:
end;}
med := (tot div 640)-min;
for i := 1 to 640 do
Dec(oldosci[i],min);
for i := 1 to 320 do begin
if oldosci[i*2] >= med then
Put(150+i,201+100+(oldosci[i*2]-med),green)
else Put(150+i,201+100-(med-oldosci[i*2]),green);
end;
Inc(OsciPos,880);
if OsciPos > (BufferSize-640) then OsciPos := 0;
{ SetViewPort(0,0,639,479,true);}
end;
procedure DrawInstr;
begin
SetFillStyle(SolidFill,Black);
Bar(0,0,200,50);
SetColor(LightBlue);
if Channel1Inst > 0 then
OutTextXY(10,5,SampleNames[Channel1Inst]);
if Channel2Inst > 0 then
OutTextXY(10,15,SampleNames[Channel2Inst]);
if Channel3Inst > 0 then
OutTextXY(10,25,SampleNames[Channel3Inst]);
if Channel4Inst > 0 then
OutTextXY(10,35,SampleNames[Channel4Inst]);
end;
begin
if (not GrMode) then begin
if peakCtr <> OPeakCtr then begin
OPeakCtr := PeakCtr;
DrawPeak;
end;
if AktLine = OldLine then exit;
OldLine := AktLine;
WriteInstrBox;
{ WriteNotes;}
WriteAktPattern;
GotoXY(57,6);
write(Speed:2);
{ writeln(Channel1VK,'/si',Channel1Size,'/rpl',Channel1RepL,'/svk',Channel1SpVK,'/not',Channel1Note,' ');
writeln(Channel2VK,'/si',Channel2Size,'/rpl',Channel2RepL,'/svk',Channel2SpVK,'/not',Channel2Note,' ');
writeln(Channel3VK,'/si',Channel3Size,'/rpl',Channel3RepL,'/svk',Channel3SpVK,'/not',Channel3Note,' ');
writeln(Channel4VK,'/si',Channel4Size,'/rpl',Channel4RepL,'/svk',Channel4SpVK,'/not',Channel4Note,' ');}
end
else {if aktline <> oldline then} begin
DrawOscis;
if aktline <> oldline then begin
DrawInstr;
oldline := aktline;
OsciPos := 0;
end;
end;
end;
procedure ChainInt(Oldint:pointer);
inline($5B/$58/$89/$EC/$87/$46/$10/$87/$5E/$0E/$5D/$07/$1F/$5F/$5E/
$5A/$59/$CB);
procedure Int1C; interrupt;
begin
ScrType1;
{ ChainInt(OldInt1C);}
port[$20] := $20;
end;
procedure InitInt1C;
var tmr: word;
begin
tmr := longint(1093180) div longint(50);
asm cli end;
port[$40] := tmr and $FF;
port[$40] := tmr shr 8;
asm sti end;
GetIntVec(8,OldInt1C);
SetIntVec(8,@Int1C);
end;
begin
if ParamCount < 1 then begin
writeln('Keine Dateinamen angegeben');
halt;
end;
IntNo := 13;
if ParamCount >= 2 then
Val(ParamStr(2),Freq,result)
else Freq := 15000;
if ParamCount >= 3 then begin
Val(ParamStr(3),IntNo,result);
Inc(IntNo,8);
end;
WriteInstrs := ParamStr(3) <> ' /W';
BufferSize := 5120;
FreqDiv50 := Freq div 50;
Speed := 6;
BufferLim := (freq div 50)*Speed;
BufferCtr := BufferLim-1;
OldPattern := $FF;
writeln('Initialisiere Arrays...');
InitChannelVars;
InitSpeedlist;
InitOctArray;
GetMem(buffer1,buffersize);
GetMem(buffer2,buffersize);
{ GetMem(channel1buf,buffersize div 1);
GetMem(channel2buf,buffersize div 1);
GetMem(channel3buf,buffersize div 1);
GetMem(channel4buf,buffersize div 1);
channelbufs[1] := channel1buf; channelbufs[2] := channel2buf;
channelbufs[3] := channel3buf; channelbufs[4] := channel4buf;
Channel1BSeg := Seg(Channel1Buf^); Channel2BSeg := Seg(Channel2Buf^);
Channel3BSeg := Seg(Channel3Buf^); Channel4BSeg := Seg(Channel4Buf^);
for i := 1 to 4 do Fillchar(channelbufs[i]^,buffersize,0);}
DataSeg := Seg(Buffer1^);
DataOfs := Ofs(Buffer1^);
Data := Ptr(Seg(buffer1^),Ofs(Buffer1^));
{ GetMem(data,buffersize*2);
buffer1 := Ptr(Seg(data^),0);
buffer2 := Ptr(Seg(data^),bufferSize);}
FillChar(buffer1^,buffersize,0);
FillChar(buffer2^,buffersize,0);
{ FreeMem(data,bufferSize*2);}
init_dsp;
FileName := StrUpCase(ParamStr(1));
Assign(ModF, ParamStr(1));
writeln('SB initialisieren...');
schreib_dsp($0D1); (* Speaker an *)
writeln('Lade MOD... (freier Speicher: ',MemAvail div 1024, ' KB)');
ReadMODFile;
AktPattern := Arrangement[1]+1;
AktLine := 0;
KillCursor;
i := 0;
grMode := ParamStr(3) <> 'T';
BildSchirmMaske;
PeakLimit := 13;
Channel1Peak := 0; Channel2Peak := 0; Channel3Peak := 0; Channel4Peak := 0;
PeakCtr := 0; OPeakCtr := 255; PeakCtr2 := 0;
OldLine2 := 255;
DirectVideo := true;
{ GetIntVec($1C,OldInt1C);
SetIntVec($1C,@Int1C);}
StartMOD_DMA;
InitInt1C;
repeat
if keypressed then begin
StopMOD;
repeat until not MODPlaying;
end;
{ ScrType1;}
Inc(i);
until not MODPlaying;
RestoreCursor;
schreib_dsp($0D3); (* Speaker aus *)
init_dsp;
while keypressed do readkey;
SetIntVec(8,OldInt1C);
port[$40] := 0;
port[$40] := 0;
ClrScr;
{$I-} CloseGraph; {$I+}
end.