home *** CD-ROM | disk | FTP | other *** search
- unit mlib;
-
- { Play/R interface unit.
- Copyright 1992, Kevin Weiner, All rights reserved. }
-
- interface
-
- {$i midi.inc}
-
- const
- chan_map = 0;
- chan_ena = 1;
- chan_xpos = 2;
-
- type
-
- channels = array [0..15] of byte;
-
- proc1type = procedure (a: integer);
- proc2type = procedure (a, b: integer);
- proc3type = procedure (a: integer; var b: integer);
- proc4type = procedure (dev: integer; var m: messages; var c, d1, d2: byte);
- proc5type = procedure (dev: integer; m: messages; c, d1, d2: byte);
- func1type = function: longint;
- func2type = function (a: integer): boolean;
-
-
- var
- MidiDriverLoaded: boolean;
- MID: integer;
-
- midiPutByte: proc2type;
- midiInputReady: func2type;
- midiGetbyte: proc3type;
- midiClearInput: proc1type;
- msTimer: func1type;
- midiGetMessage: proc4type;
- midiResend: proc1type;
- midiPutMessage: proc5type;
-
- procedure mfPause;
- procedure mfContinue;
- procedure mfPopup;
- procedure mfRewind;
- function mfPlay(name: string): integer;
- procedure mfSongStat(var playing, done: boolean; var position: longint;
- var songcount, cursong: byte);
- procedure mfFileStat(var stat: byte; var name: string);
- function mfLoad(name: string): integer;
- procedure mfQuiet;
- procedure mfPopEnable(stat: boolean);
- procedure mfVolume(adjust: integer);
- procedure mfTimeMode(mode: integer);
- procedure mfGetChan(datatype: integer; var chan: channels);
- procedure mfSetChan(datatype: integer; chan: channels);
- procedure mfSetPos(time: longint);
- procedure mfSkipSong(n: byte);
- procedure mfLoopMode(n: byte);
-
- function midiDevName(dev: integer; var devname: string;
- var devdesc: string): integer;
- procedure midiPutBuffer(dev: integer; bufptr: pointer; len: word);
- procedure midiPutBuffer1(dev: integer; bufptr: pointer; len: word);
- procedure midiGetBuffer(dev: integer; bufptr: pointer; max: word;
- var recv: word);
- procedure midiReset(dev: integer);
- procedure midiRemove;
-
- implementation
-
- uses dos;
-
- const
- playrid: array [0..7] of char = 'Play/R '; {PlayR id string}
-
- tessmpx = $5453; {hex} {TesSeRact multiplex id}
-
- fcnPause = 0;
- fcnPlay = 1;
- fcnPopup = 2;
- fcnRewind = 3;
- fcnLoadPlay = 4;
- fcnPlayStat = 5;
- fcnLoadStat = 6;
- fcnDoneStat = 7;
- fcnLoad = 8;
- fcnQuiet = 9;
- fcnPopEna = 10;
- fcnVolume = 11;
- fcnReset = 12;
- fcnTimeMode = 13;
- fcnGetChan = 14;
- fcnSetChan = 15;
- fcnSetPos = 16;
- fcnSkipSong = 17;
- fcnLoopMode = 18;
-
- fcnGetName = 20;
- fcnSendShort = 21;
- fcnSendLong = 22;
- fcnCheckInp = 23;
- fcnGetInput = 24;
- fcnGetTime = 25;
- fcnGetCID = 26;
- fcnGetEntry = 27;
-
- fcnRemove = 99;
-
- type
- bytearray = array [0..0] of byte;
- bptr = ^bytearray;
-
- var
- param: array [0..63] of byte; {Play/R parameter data}
- reg: registers; {CPU register set}
- idnum: integer; {Play/R id number}
-
- procedure CallPlayR(fcn: byte);
-
- { Call Play/R using the contents of the byte array "param".
- Byte 0 is the function code, and the rest is any required data. }
-
- begin
- param[0] := fcn;
- reg.ax := tessmpx; {ax = Tess multiplex id}
- reg.es := seg(param); {es = parameter segment}
- reg.di := ofs(param); {di = parameter offset}
- reg.cx := idnum; {cx = PlayR id number}
- reg.bx := $20; {bx = Tess call user function}
- intr($2f, reg); {Call int 2fh}
- end;
-
- procedure mfPause;
-
- begin
- CallPlayR(fcnPause);
- end;
-
- procedure mfContinue;
-
- begin
- CallPlayR(fcnPlay);
- end;
-
- procedure mfPopup;
-
- begin
- CallPlayR(fcnPopup);
- end;
-
- procedure mfRewind;
-
- begin
- CallPlayR(fcnRewind);
- end;
-
- function mfPlay(name: string): integer;
-
- var
- i, n: integer;
-
- begin
- n := length(name);
- for i := 1 to n do
- param[i] := byte(name[i]);
- param[n+1] := 0;
- CallPlayR(fcnLoadPlay);
- mfPlay := param[0];
- end;
-
- procedure mfSongStat(var playing, done: boolean; var position: longint;
- var songcount, cursong: byte);
-
- begin
- CallPlayR(fcnPlayStat);
- playing := boolean(param[0]);
- done := boolean(param[1]);
- move(param[2], position, 4);
- songcount := param[6];
- cursong := param[7];
- end;
-
- procedure mfFileStat(var stat: byte; var name: string);
-
- var
- i: integer;
-
- begin
- CallPlayR(fcnLoadStat);
- stat := param[0];
- i := 1;
- while (param[i] <> 0) and (i < 256) do
- begin
- name[i] := chr(param[i]);
- inc(i);
- end;
- name[0] := chr(i-1);
- end;
-
- function mfLoad(name: string): integer;
-
- var
- i, n: integer;
-
- begin
- n := length(name);
- for i := 1 to n do
- param[i] := byte(name[i]);
- param[n+1] := 0;
- CallPlayR(fcnLoad);
- mfLoad := param[0];
- end;
-
- procedure mfQuiet;
-
- begin
- CallPlayR(fcnQuiet);
- end;
-
- procedure mfPopEnable(stat: boolean);
-
- begin
- param[1] := ord(stat);
- CallPlayR(fcnPopEna);
- end;
-
- procedure mfVolume(adjust: integer);
-
- begin
- param[1] := lo(adjust);
- CallPlayR(fcnVolume);
- end;
-
- procedure mfTimeMode(mode: integer);
-
- begin
- param[1] := lo(mode);
- CallPlayR(fcnTimeMode);
- end;
-
- procedure mfGetChan(datatype: integer; var chan: channels);
-
- var
- i: integer;
-
- begin
- param[1] := datatype;
- CallPlayR(fcnGetChan);
- move(param[2], chan[0], 16);
- end;
-
- procedure mfSetChan(datatype: integer; chan: channels);
-
- var
- i: integer;
-
- begin
- param[1] := datatype;
- move(chan[0], param[2], 16);
- CallPlayR(fcnSetChan);
- end;
-
- procedure mfSetPos(time: longint);
-
- begin
- move(time, param[1], 4);
- CallPlayR(fcnSetPos);
- end;
-
- procedure mfSkipSong(n: byte);
-
- begin
- param[1] := n;
- CallPlayR(fcnSkipSong);
- end;
-
- procedure mfLoopMode(n: byte);
-
- begin
- param[1] := n;
- CallPlayR(fcnLoopMode);
- end;
-
- function midiDevName(dev: integer; var devname: string;
- var devdesc: string): integer;
- var
- i: integer;
-
- begin
- param[1] := dev;
- CallPlayR(fcnGetName);
- if param[1] = 0 then
- begin
- devname := '';
- devdesc := '';
- end
- else
- begin
- for i := 1 to 3 do devname[i] := chr(param[i+1]);
- devname[0] := chr(3);
- for i := 1 to 20 do
- devdesc[i] := chr(param[4+i]);
- devdesc[0] := chr(20);
- end;
- midiDevName := param[1];
- end;
-
- procedure midiPutBuffer(dev: integer; bufptr: pointer; len: word);
-
- begin
- param[1] := dev;
- move(len, param[2], 2);
- move(bufptr, param[4], 4);
- fillchar(param[8], 4, 0);
- CallPlayR(fcnSendLong);
- end;
-
- procedure midiPutBuffer1(dev: integer; bufptr: pointer; len: word);
-
- { Uses direct output }
-
- var
- i: word;
- b: bptr;
-
- begin
- b := bufptr;
- for i := 0 to len-1 do
- midiPutByte(dev, b^[i]);
- end;
-
- procedure midiGetBuffer(dev: integer; bufptr: pointer; max: word;
- var recv: word);
- var
- i: word;
- x: integer;
- b: bptr;
-
- begin
- b := bufptr;
- i := 0;
- while midiInputReady(dev) and (i < max) do
- begin
- midiGetByte(dev, x);
- b^[i] := lo(x);
- inc(i);
- end;
- recv := i;
- end;
-
- procedure midiReset(dev: integer);
-
- begin
- param[1] := lo(dev);
- CallPlayR(fcnReset);
- end;
-
- procedure midiRemove;
-
- begin
- CallPlayR(fcnRemove);
- end;
-
- procedure BindDriver;
-
- begin
- CallPlayR(fcnGetEntry);
- move(param[1], midiPutByte, 4);
- move(param[5], midiInputReady, 4);
- move(param[9], midiGetByte, 4);
- move(param[13], midiClearInput, 4);
- move(param[17], msTimer, 4);
- move(param[21], midiGetMessage, 4);
- move(param[25], midiResend, 4);
- move(param[29], midiPutMessage, 4);
- end;
-
- function CheckRes: integer;
-
- { Check Play/R is loaded - returns id number if found, else -1 }
-
- begin
- reg.ax := tessmpx; {ax = Tess int 2fh muliplex id}
- reg.ds := seg(playrid); {ds = id string segment}
- reg.si := ofs(playrid); {si = id string offset}
- reg.cx := 0; {cx = Tess id counter - must be 0}
- reg.bx := 0; {bx = Tess check resident function}
- intr($2f, reg); {Call int 2fh}
- if reg.ax = $ffff then
- idnum := reg.cx {Found - return tsr id}
- else
- idnum := -1; {Not loaded}
- checkres := idnum;
- end;
-
- begin
- midiDriverLoaded := CheckRes >= 0;
- if midiDriverLoaded then
- begin
- CallPlayR(fcnGetCID);
- MID := param[1];
- BindDriver;
- end;
- end.
-