Prospero Pascal BEEP

Anything QL Software or Programming Related.
stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Prospero Pascal BEEP

Post by stevepoole »

Hi,

Has anyone succeeded in using BEEPs with Prospero Pascal ?

Beep is undefined ( when Timo Salmi's BeepTester program is converted from Compuetr1 pascal ).

What is required is an EXTERNAL BEEP() procedure...

Regards,

Steve.


User avatar
tofro
Font of All Knowledge
Posts: 2686
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Post by tofro »

stevepoole wrote: Beep is undefined ( when Timo Salmi's BeepTester program is converted from Compuetr1 pascal ).
There's no Beep() in ProPascal, indeed. But you can easily create one using the supplied QTrap mechanism.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Post by stevepoole »

Hi Tobias,

I see in life_pas, you use traps, but how they work is not clear to me...

Where did you find the explanatory documentation please ?

An internet search only gave one reply, a link to your QL Forum thread !

Regards,

Steve.


User avatar
tofro
Font of All Knowledge
Posts: 2686
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Post by tofro »

Steve,

IPC Comms is a bit tricky to master (and it's very easy to crash the QL).

Here's my version of Beep for Prospero Pascal. It should take the same parameters as the SuperBASIC BEEP command and produce the same results (except you cannot just omit parameters in Pascal as you can in Basic, so you must specify the full set of parameters). I also added a PROCEDURE BeepOff to shut up the QL.

Code: Select all

SEGMENT Beep;

CONST
   BeepIPC    = 10;
   BeepIPCOff = 11;
   { Signifies the number of bits to send from each byte of the command       }
   { string - where '10' means '8 bits', '00' means '4 bits' in rToL order    }
   { '0000 0000 1010 1010 1010'                                               }
   { ' 4 4  4 4  8 8  8 8  8 8  bits per parameter byte to send               }
   {    0    0    a    a    a                                                 }
   parmsToSend = 00AAAH;
   MT_IPCOM = 11H;

TYPE
   RegSpec = RECORD
      D0, D1, D2, D3 : INTEGER;
      A0, A1, A2, A3 : INTEGER;
   END;

   TIPCCommand = PACKED RECORD
      Command   : CHAR;
      numParms  : CHAR;
      BitsPParm : INTEGER;
      CmdBuffer : ARRAY[0..9] OF CHAR;
      ReplyLen  : CHAR;
   END;

PROCEDURE QTrap (trapNum : INTEGER; RegRec : RegSpec); EXTERNAL;

PROCEDURE Beep (Length, pitch1, pitch2, gradX, gradY, wrap, fuzz, rand : INTEGER);

VAR
   Cmd  : TIPCCommand;
   Regs : RegSpec;
BEGIN
   WITH Cmd DO
   BEGIN
      Command   := Chr(BeepIPC);           { IPC command "BEEP"             }
      numParms  := Chr(10);                { # of parameter bytes to follow }
      BitsPParm := parmsToSend;            { what to send of each parameter }
      CmdBuffer [0] := Chr(pitch1);
      CmdBuffer [1] := Chr(pitch2);
      CmdBuffer [2] := Chr(gradX DIV 256);
      CmdBuffer [3] := Chr(gradX MOD 256);
      CmdBuffer [4] := Chr(Length DIV 256);
      CmdBuffer [5] := Chr(Length MOD 256);
      CmdBuffer [6] := Chr(gradY);
      CmdBuffer [7] := Chr(wrap);
      CmdBuffer [8] := Chr(fuzz);
      CmdBuffer [9] := Chr(rand);
      ReplyLen := Chr(0);
   END;

   WITH Regs DO
   BEGIN
      d0 := MT_IPCOM;
      a3 := Addr (Cmd);
   END;
   QTrap (1, Regs);
END;

PROCEDURE BeepOff;
VAR
   Cmd  : TIPCCommand;
   Regs : RegSpec;
BEGIN
   WITH Cmd DO
   BEGIN
      Command   := Chr(BeepIPCOff);             { IPC command "BEEP OFF"             }
      numParms  := Chr(0);                      { # of parameter bytes to follow }
      BitsPParm := 0;                           { what to send of each parameter }
      ReplyLen := 0;
   END;

   WITH Regs DO
   BEGIN
      d0 := MT_IPCOM;
      a3 := Addr (Cmd);
   END;
   QTrap (1, Regs);
END;

BEGIN
END.
Programs that use Beep must declare the PROCEDURE as EXTERNAL and link to the corresponding _rel file.
I hope I got the parameters right, only checked if the procs produce some sound.
How you do stuff like that: The information on how the command must be sent to the IPC (or, more generally, how to call QDOS traps) is from the QL Technical Guide.

Hope this helps,
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Post by stevepoole »

Hi Tobias,

Many thanks for this BEEP trap-code, which I shall try out tomorrow.

Yes, the QDOS/SMS reference manual also warns about using the IPC traps...

I am using QPC, and wonder if the 'IPC' access is as delicate as on 'real' QLs ?

In any case, delving into 'traps' will be a new experience for me : I shall be on tenterhooks !

Regards,

Steve.


stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Post by stevepoole »

Hi Tobias,

I have compiled and executed your BEEP code successfully. (Very nice with a decent loud speaker system...)
But, in Procedure BeepOff,, ReplyLen needs to be chr(0).

The 'beep duration' parameters seem to vary with the speed of my various PCs. (I had to add 'wait' loops to get correct sound...)

BeepOff is ok too.

Many thanks again, as I would not have been able to implement traps by myself...
Steve.


stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Post by stevepoole »

Hi,
Is anyone using Prospero Pascal under QPC2 ?

Tobias'es BEEP code works fine, except that durations need to be divided by 1000 to give correct output on my laptop.

Similarily, the EXTERNAL 'time' function seems to return a 64-bit integer value, so DIV & MOD can't be used to get hours, mins & secs.

There are probably other instances where PP is assuming a 4Mhz QL processor ?

On the whole, PP works fine, but in the above cases, workarounds are essential. Computer One Pascal seems to be more compliant...

Has anyone else experienced similar problems ?

Steve.


stevepoole
Super Gold Card
Posts: 712
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Post by stevepoole »

Hi,
Prospero's Pascal lacks an INKEY$ routine, which makes the language cumbersome to use, as the alternatives all require an ENTER.

I have devised a random-seeding method to emulate 'Randomise', which is no better than a 'card shuffle', but if there were an INKEY$, it could be greatly enhanced.

Without good seeding, propascal always generates the same random number series, (pretty useless for games).

Pascal was designed for teaching good programming, but without games, I doubt if there will be many takers...

Has anybody found a workaround ?
Regards,
Steve.


User avatar
tofro
Font of All Knowledge
Posts: 2686
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Post by tofro »

stevepoole wrote:Hi,
Prospero's Pascal lacks an INKEY$ routine, which makes the language cumbersome to use, as the alternatives all require an ENTER.

I have devised a random-seeding method to emulate 'Randomise', which is no better than a 'card shuffle', but if there were an INKEY$, it could be greatly enhanced.

Without good seeding, propascal always generates the same random number series, (pretty useless for games).

Pascal was designed for teaching good programming, but without games, I doubt if there will be many takers...
Steve.
Steve,
Something along the lines of

Code: Select all

{ Tries to read a character with timeout. Returns false if none there }
FUNCTION KeyPressed (wait : INTEGER) : CHAR;
CONST
	IO_FBYTE = 1;
VAR 
	Regs    : RegSpec;
	Byte    : CHAR;
BEGIN
	Regs.D0 := IO_FBYTE;
    Regs.D3 := wait; 			{ Timeout  }
	Regs.A0 := Handle (Output);
    qtrap (3, Regs);
    IF Regs.D0 <> 0 THEN
       KeyPressed := Chr(0);
    ELSE
       KeyPressed := Chr (Regs.D1) MOD 256; { mask out upper D1 register }
END;
should do. Hand in the maximum timeout in 1/50s, the function will return either a CHAR or Chr(0) if any eror (including timeout) occurred.

Tobias
Last edited by tofro on Sun Jul 05, 2020 9:36 am, edited 2 times in total.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Prospero Pascal BEEP

Post by NormanDunbar »

There's a missing 'e' in "KeyPressd" when Regs.D0 <> 0. :(

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
Post Reply