home *** CD-ROM | disk | FTP | other *** search
- {///////////////////////////////////////////////////////////////////////////}
- { Ca y est... je me suis décidé à mettre le source de HEADACHE dans le
- domaine public! A mon point de vue, c'est un petit programme assez peu
- important, mais c'est a priori susceptible d' intéresser quelques uns
- d'entre vous. Ceux-ci sont évidemment curieux de savoir comment "ça"
- marche! En fait, c'est relativement simple (une fois que l'on a visualisé
- le fichier PCX), sauf peut-être en ce qui concerne la partie graphique en
- BASM. J'ai fait un effort violent en réécrivant les routines SB pour le
- DMA entièrement en TP (à l'origine c'est en BASM et pour toute ligne IRQ
- et canal DMA, et avec une réelle détection automatique du port). Voilà!,
- sachez donc tirer profit de ce petit cadeau et évitez de faire partie du
- club très large des LAMERS en "pompant" bêtement et en changeant les
- textes des messages...
-
- ATTENTION! le numéro de téléphone dans la démo n'est plus valable!!!...
- Pour de plus amples informations, d'éventuelles suggestions, ou tout
- simplement pour le fun, vous pouvez m'écrire à l'adresse suivante:
-
- Patrick Ruelle
- 43, av. de Grande Bretagne
- 98000 Monaco
- Principauté de Monaco
-
- Evidemment je n'ai pas pris la décision de diffuser ce source dans le
- but de demander de l'argent, mais il va de soit que toutes sortes de dons
- sont acceptés (carte postale, matos, argent, spécialités locales, docs,
- etc...). N'oubliez pas non plus que cette diffusion ne m'enlève nullement
- mes droits d'auteur de cette mmm... de démo; ce petit package peut être
- diffusé librement à condition de rester sous sa forme initiale:
-
- HEADACHE.EXE 01/08/94 13264 L'exécutable utilisant HEADIMG et les HEADSEQ
- HEADACHE.PAS 01/08/94 17253 Le source principal de la démo
- SB_DMA .PAS 01/08/94 9170 Le source des routines DMA pour la SB
- HEADACHE.PCX 25/04/93 8471 L'image des sprites au format PCX
- HEADIMG .RAW 25/07/94 64768 " " " en format brut (img+pal)
- HEADSEQ .1 25/07/94 20040 Le 1er pattern digital de musique
- HEADSEQ .2 25/07/94 20168 " 2e " " " "
- HEADSEQ .3 25/07/94 20040 " 3e " " " "
- HEADSEQ .4 25/07/94 20168 " 4e " " " "
- HEADSEQ .5 25/07/94 20168 " 5e " " " "
- HEADSEQ .6 25/07/94 20168 " 6e " " " "
- HEADSEQ .7 25/07/94 20104 " 7e " " " "
- ------
- TOTAL 253782
-
- La version actuelle est remaniée exprès pour la diffusion de ce package,
- mais en fait ce programme date de début 1993...
-
- Patrick Ruelle (Monac) / GRYPHAEA }
- {///////////////////////////////////////////////////////////////////////////}
- UNIT SB_DMA; {Uniquement pour IRQ=7 et DMA=1, mais facilement adaptable}
- {pour un autre IRQ et DMA. La détection automatique du port}
- {de base se fait en testant les Dizaines avec InitDSP. }
- INTERFACE
-
-
- VAR
- s :ARRAY[1..7] OF Pointer;
- sequence :BYTE;
- sounds :Pointer;
- snd,sze,sizes:WORD;
-
-
- FUNCTION InitDSP(base:WORD):BOOLEAN;
- PROCEDURE SpeakerON;
- PROCEDURE SpeakerOFF;
- PROCEDURE ArreteDMA;
- PROCEDURE InitPlayback(son:Pointer; taille:WORD; frequence:WORD);
- PROCEDURE FinPlayBack;
-
-
- IMPLEMENTATION
-
-
- USES Crt,Dos;
-
-
- VAR
- DSP_RESET,DSP_READ_DATA,
- DSP_WRITE_DATA,
- DSP_WRITE_STATUS,
- DSP_DATA_AVAIL,i,Offse :WORD;
- OldIRQ :Pointer;
- Page :BYTE;
-
-
- FUNCTION InitDSP(base:WORD):BOOLEAN; {1<=base<=6 correspond à 210h à 260h}
- BEGIN
- base:=base*$10;
- {Calculs des adresses utiles}
- DSP_RESET :=base+$206;
- DSP_READ_DATA :=base+$20A;
- DSP_WRITE_DATA :=base+$20C;
- DSP_WRITE_STATUS:=base+$20C;
- DSP_DATA_AVAIL :=base+$20E;
- {Reinitialise le DSP}
- Port[DSP_RESET]:=1;
- Delay(30);
- Port[DSP_RESET]:=0;
- Delay(30);
- IF (Port[DSP_DATA_AVAIL] AND $80=$80) AND (Port[DSP_READ_DATA]=$AA) THEN
- InitDSP:=True
- ELSE
- InitDSP:=False;
- END;
-
-
- PROCEDURE EcritDSP(valeur:BYTE);
- BEGIN
- WHILE Port[DSP_WRITE_STATUS] AND $80<>0 DO;
- Port[DSP_WRITE_DATA]:=valeur;
- END;
-
-
- FUNCTION LitDSP:BYTE;
- BEGIN
- WHILE Port[DSP_DATA_AVAIL] AND $80=0 DO;
- LitDSP:=Port[DSP_READ_DATA];
- END;
-
-
- PROCEDURE EcritDAC(Commande:BYTE);
- BEGIN
- EcritDSP($10);
- EcritDSP(Commande);
- END;
-
-
- FUNCTION LitDAC:BYTE;
- BEGIN
- EcritDSP($20);
- LitDAC:=LitDSP;
- END;
-
-
- PROCEDURE SpeakerON;
- BEGIN
- EcritDSP($D1);
- END;
-
-
- PROCEDURE SpeakerOFF;
- BEGIN
- EcritDSP($D3);
- END;
-
-
- PROCEDURE ArreteDMA;
- BEGIN
- EcritDSP($D0);
- END;
-
-
- PROCEDURE Playback;INTERRUPT; {Routine greffée sur l'IRQ déclenchée par le}
- VAR {DSP de la carte SoundBlaster en fin de DMA }
- recu :BYTE;
- BEGIN
- {Accusé de réception}
- recu:=Port[DSP_DATA_AVAIL];
- {Calcul de l'adresse Physique et Page de la sequence}
- offse :=Seg(sounds^) SHL 4+Ofs(sounds^);
- page :=(Seg(sounds^)+Ofs(sounds^) SHR 4) SHR 12;
- {Préparation du DMAC pour le transfert}
- Port[$0A]:=5; {5=4+CanalDMA; donc 7=DMA3}
- Port[$0C]:=0;
- Port[$0B]:=$49; {Via DAC}
- Port[$02]:=Lo(offse );{06 pour DMA3}
- Port[$02]:=Hi(offse );{06 pour DMA3}
- Port[$83]:=page;
- Port[$03]:=Lo(sizes); {07 pour DMA3}
- Port[$03]:=Hi(sizes); {07 pour DMA3}
- Port[$0A]:=1; {Canal DMA}
- {Activation du transfert par le DAC}
- EcritDSP($14);
- EcritDSP(Lo(sizes));
- EcritDSP(Hi(sizes));
- {Actualisation de la séquence à jouer; ici on est en tâche de fond}
- {Le morceau est constitué d'un assemblage de 44 patterns parmi 7, }
- {pour une durée approximative de 1mn20s à 11KHz. Le bouclage est}
- {effectif après le 44e pattern }
- Inc(sequence);
- IF sequence>44 THEN sequence:=1;
- CASE sequence OF
- 1..4 :BEGIN
- Snd:=1;
- Sze:=19976-1;
- END;
- 8,13..15,17..19,30,32,38,40:BEGIN
- Snd:=2;
- Sze :=20104-1;
- END;
- 5..7,9..11,41 :BEGIN
- Snd:=3;
- Sze :=19976-1;
- END;
- 12,16,20,33..36,42..44 :BEGIN
- Snd:=4;
- Sze :=20104-1;
- END;
- 21..23,25..27,29,37 :BEGIN
- Snd:=5;
- Sze :=20104-1;
- END;
- 24 :BEGIN
- Snd:=6;
- Sze :=20104-1;
- END;
- 28,31,39 :BEGIN
- Snd:=7;
- Sze :=20040-1;
- END;
- END;
- sounds:=s[snd];
- sizes :=sze; {à ce niveau la taille est déja ajustée à -1}
- {Avis de fin d'interruption au contrôleur d'INT}
- Port[$20]:=$20;
- END;
-
-
- PROCEDURE ActiveIRQ(i:WORD);
- BEGIN
- IF i<8 THEN
- PORT[$21]:=PORT[$21] AND (NOT (1 SHL i))
- ELSE
- BEGIN
- PORT[$A1]:=PORT[$A1] AND (NOT (1 SHL (i-8)));
- PORT[$21]:=PORT[$21] AND (NOT (1 SHL 2));
- END;
- END;
-
-
- PROCEDURE DesactiveIRQ(i:WORD);
- BEGIN
- IF i<8 THEN
- PORT[$21]:=PORT[$21] OR (1 SHL i)
- ELSE
- BEGIN
- PORT[$A1]:=PORT[$A1] OR (1 SHL (i-8))
- END;
- END;
-
-
- FUNCTION ChangeVecteurIRQ(i:WORD; Vec:POINTER):POINTER;
- VAR
- p:POINTER;
- j:WORD;
- BEGIN
- IF i<8 THEN
- j:=i+$08
- ELSE
- j:=i+$68;
- GetIntVec(j,p);
- SetIntVec(j,Vec);
- ChangeVecteurIRQ:=p;
- END;
-
-
- PROCEDURE InitPlayback(son:Pointer; taille:WORD; frequence:WORD);
- VAR time_constant:WORD;
- BEGIN
- {Définit la fréquence}
- time_constant:=256-1000000 DIV frequence;
- EcritDSP($40);
- EcritDSP(time_constant);
- SpeakerON;
- taille:=taille-1;
- sounds:=son;
- offse :=Seg(sounds^) SHL 4+Ofs(sounds^);
- page :=(Seg(sounds^)+Ofs(sounds^) SHR 4) SHR 12;
- Port[$0A]:=5;
- Port[$0C]:=0;
- Port[$0B]:=$49;
- Port[$02]:=Lo(offse);
- Port[$02]:=Hi(offse);
- Port[$83]:=page;
- Port[$03]:=Lo(taille);
- Port[$03]:=Hi(taille);
- Port[$0A]:=1;
- {La routine PlayBack est sur l'IRQ 7}
- OldIRQ:=ChangeVecteurIRQ(7,@PlayBack);
- ActiveIRQ(7);
- EcritDSP($14);
- EcritDSP(Lo(taille));
- EcritDSP(Hi(taille));
- {Préparation pour la sequence suivante (jouée alors par la routine IRQ)}
- Sequence:=2;
- snd:=1;
- sze:=19976-1;
- sounds:=s[snd];
- sizes :=sze; {à ce niveau la taille est déja ajustée à -1}
- END;
-
-
- PROCEDURE FinPlayBack;
- VAR p:Pointer;
- BEGIN
- ArreteDMA;
- DesactiveIRQ(7);
- p:=ChangeVecteurIRQ(7,OldIRQ);
- SpeakerOFF;
- END;
-
-
- END.
-