Prospero Pascal BEEP

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

Prospero Pascal BEEP

Postby stevepoole » Sun May 24, 2020 9:37 am

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
QL Wafer Drive
Posts: 1964
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Postby tofro » Sun May 24, 2020 1:50 pm

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
Gold Card
Posts: 309
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Postby stevepoole » Sun May 24, 2020 8:39 pm

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
QL Wafer Drive
Posts: 1964
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Postby tofro » Mon May 25, 2020 10:25 am

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
Gold Card
Posts: 309
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Postby stevepoole » Mon May 25, 2020 10:39 pm

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
Gold Card
Posts: 309
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Postby stevepoole » Sat May 30, 2020 9:38 am

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
Gold Card
Posts: 309
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Postby stevepoole » Wed Jun 03, 2020 8:18 pm

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
Gold Card
Posts: 309
Joined: Mon Nov 24, 2014 2:03 pm

Re: Prospero Pascal BEEP

Postby stevepoole » Tue Jun 30, 2020 10:53 pm

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
QL Wafer Drive
Posts: 1964
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Prospero Pascal BEEP

Postby tofro » Tue Jun 30, 2020 11:06 pm

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: 1086
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Prospero Pascal BEEP

Postby NormanDunbar » Tue Jun 30, 2020 11:23 pm

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 - https://www.amazon.co.uk/Arduino-Softwa ... 1484257898, https://www.apress.com/gb/book/9781484257890

Who is online

Users browsing this forum: No registered users and 6 guests