All of lore.kernel.org
 help / color / mirror / Atom feed
* [FILE] Play command
@ 2005-07-12 19:35 Vincent Pelletier
  2005-07-13 16:28 ` Marco Gerards
  0 siblings, 1 reply; 4+ messages in thread
From: Vincent Pelletier @ 2005-07-12 19:35 UTC (permalink / raw)
  To: Grub-devel

[-- Attachment #1: Type: text/plain, Size: 710 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here is the play command source code and some tunes.
I don't submit a patch since I'm not sure where it will (and where the
tunes will) go.

With Marco we thought about contrib/i386/pc/play.c

"Ancestors" of this code are:
GNU/Hurd
Grub 2 cat command
Grub 2 vga for inb & outb

Contributors for the tunes:
FSF_Song I_Feel_Pretty Indiana_Jones_Theme Summertime : GNU/Hurd
Beverly Hills Cop. Star Trek: The next Generation : Marco Gerards
Tetris_Theme : me

Vincent Pelletier
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFC1BuHFEQoKRQyjtURAtfnAJ0Z6EyHKmArEvcGMa7ioMu66zbFZgCglHXy
actaxo6QqQaFx/UfMrvtC+Q=
=C1S1
-----END PGP SIGNATURE-----

[-- Attachment #2: play.c --]
[-- Type: text/x-csrc, Size: 6535 bytes --]

/* play.c - command to play a tune  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2003  Free Software Foundation, Inc.
 *
 *  GRUB is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with GRUB; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Lots of this file is borowed from GNU/Hurd generic-speaker driver */

#include <grub/normal.h>
#include <grub/dl.h>
#include <grub/arg.h>
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>

/* Read a byte from a port.  */
static inline unsigned char
inb (unsigned short port)
{
  unsigned char value;

  asm volatile ("inb    %w1, %0" : "=a" (value) : "Nd" (port));
  asm volatile ("outb   %%al, $0x80" : : );
  
  return value;
}

/* Write a byte to a port.  */
static inline void
outb (unsigned short port, unsigned char value)
{
  asm volatile ("outb   %b0, %w1" : : "a" (value), "Nd" (port));
  asm volatile ("outb   %%al, $0x80" : : );
}

/* The speaker port.  */
#define SPEAKER			0x61

/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
   from timer 2.  */
#define SPEAKER_TMR2		0x01

/* If SPEAKER_TMR2 is not set, this provides direct input into the
   speaker.  Otherwise, this enables or disables the output from the
   timer.  */
#define SPEAKER_DATA		0x02

/* The PIT channel value ports.  You can write to and read from them.
   Do not mess with timer 0 or 1.  */
#define PIT_COUNTER_0		0x40
#define PIT_COUNTER_1		0x41
#define PIT_COUNTER_2		0x42

/* The frequency of the PIT clock.  */
#define PIT_FREQUENCY		0x1234dd

/* The PIT control port.  You can only write to it.  Do not mess with
   timer 0 or 1.  */
#define PIT_CTRL		0x43
#define PIT_CTRL_SELECT_MASK	0xc0
#define PIT_CTRL_SELECT_0	0x00
#define PIT_CTRL_SELECT_1	0x40
#define PIT_CTRL_SELECT_2	0x80

/* Read and load control.  */
#define PIT_CTRL_READLOAD_MASK	0x30
#define PIT_CTRL_COUNTER_LATCH	0x00	/* Hold timer value until read.  */
#define PIT_CTRL_READLOAD_LSB	0x10	/* Read/load the LSB.  */
#define PIT_CTRL_READLOAD_MSB	0x20	/* Read/load the MSB.  */
#define PIT_CTRL_READLOAD_WORD	0x30	/* Read/load the LSB then the MSB.  */

/* Mode control.  */
#define PIT_CTRL_MODE_MASK	0x0e

/* Interrupt on terminal count.  Setting the mode sets output to low.
   When counter is set and terminated, output is set to high.  */
#define PIT_CTRL_INTR_ON_TERM	0x00

/* Programmable one-shot.  When loading counter, output is set to
   high.  When counter terminated, output is set to low.  Can be
   triggered again from that point on by setting the gate pin to
   high.  */
#define PIT_CTRL_PROGR_ONE_SHOT	0x02

/* Rate generator.  Output is low for one period of the counter, and
   high for the other.  */
#define PIT_CTRL_RATE_GEN	0x04

/* Square wave generator.  Output is low for one half of the period,
   and high for the other half.  */
#define PIT_CTRL_SQUAREWAVE_GEN	0x06

/* Software triggered strobe.  Setting the mode sets output to high.
   When counter is set and terminated, output is set to low.  */
#define PIT_CTRL_SOFTSTROBE	0x08

/* Hardware triggered strobe.  Like software triggered strobe, but
   only starts the counter when the gate pin is set to high.  */
#define PIT_CTRL_HARDSTROBE	0x0a

/* Count mode.  */
#define PIT_CTRL_COUNT_MASK	0x01
#define PIT_CTRL_COUNT_BINARY	0x00	/* 16-bit binary counter.  */
#define PIT_CTRL_COUNT_BCD	0x01	/* 4-decade BCD counter.  */

#define T_REST			((short) 0)
#define T_FINE			((short) -1)

struct note {
  short pitch;
  short duration;
};

static void
beep_off (void)
{
  unsigned char status;

  status = inb (SPEAKER) & ~(SPEAKER_TMR2 | SPEAKER_DATA);
  outb (SPEAKER, status);
}

static void
beep_on (short pitch)
{
  unsigned char status;
  unsigned int counter;

  if (pitch < 20)
    pitch = 20;
  else if (pitch > 20000)
    pitch = 20000;

  counter = PIT_FREQUENCY / pitch;

  /* Program timer 2.  */
  outb (PIT_CTRL, PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD
	| PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY);
  outb (PIT_COUNTER_2, counter & 0xff);		/* LSB */
  outb (PIT_COUNTER_2, (counter >> 8) & 0xff);	/* MSB */

  /* Start speaker.  */
  status = inb (SPEAKER) | SPEAKER_TMR2 | SPEAKER_DATA;
  outb (SPEAKER, status);

}

static grub_err_t
grub_cmd_play (struct grub_arg_list *state __attribute__ ((unused)),
	      int argc, char **args)
{
  grub_file_t file;
  struct note buf;
  int tempo;
  unsigned int to;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");

  file = grub_file_open (args[0]);
  if (! file)
    return 0;

  if (grub_file_read (file, (void *) &tempo, sizeof(tempo)) != sizeof(tempo))
    return 0;

  grub_printf ("Now playing %s...\n", args[0]);

  grub_dprintf ("play","tempo = %d\n", tempo);

  while (grub_file_read (file, (void *) &buf, sizeof(struct note)) == sizeof(struct note) &&
         buf.pitch != T_FINE &&
         grub_checkkey () == -1)
    {
      
      grub_dprintf ("play","pitch = %d, duration = %d\n", buf.pitch, buf.duration);

      switch (buf.pitch)
        {
          case T_REST:
            beep_off ();
            break;

          default:
            beep_on (buf.pitch);
            break;
        }

      to = grub_get_rtc () + 120*buf.duration/tempo;
      while ((unsigned int) grub_get_rtc () <= to && grub_checkkey () == -1)
        ;

    }

  beep_off ();

  grub_printf ("Done\n");

  grub_file_close (file);

  while (grub_checkkey () != -1)
    grub_getkey ();

  return 0;
}

\f
#ifdef GRUB_UTIL
void
grub_play_init (void)
{
  grub_register_command ("play", grub_cmd_play, GRUB_COMMAND_FLAG_BOTH,
			 "play FILE", "Play a tune", 0);
}

void
grub_play_fini (void)
{
  grub_unregister_command ("play");
}
#else /* ! GRUB_UTIL */
GRUB_MOD_INIT
{
  (void)mod;			/* To stop warning. */
  grub_register_command ("play", grub_cmd_play, GRUB_COMMAND_FLAG_BOTH,
			 "play FILE", "Play a tune", 0);
}

GRUB_MOD_FINI
{
  grub_unregister_command ("play");
}
#endif /* ! GRUB_UTIL */

[-- Attachment #3: Beverly Hills Cop. --]
[-- Type: application/octet-stream, Size: 216 bytes --]

[-- Attachment #4: FSF_Song --]
[-- Type: application/octet-stream, Size: 188 bytes --]

[-- Attachment #5: I_Feel_Pretty --]
[-- Type: application/octet-stream, Size: 144 bytes --]

[-- Attachment #6: Indiana_Jones_Theme --]
[-- Type: application/octet-stream, Size: 228 bytes --]

[-- Attachment #7: Star Trek: The Next Generation --]
[-- Type: application/octet-stream, Size: 152 bytes --]

[-- Attachment #8: Summertime --]
[-- Type: application/octet-stream, Size: 224 bytes --]

[-- Attachment #9: Tetris_Theme --]
[-- Type: application/octet-stream, Size: 736 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FILE] Play command
  2005-07-12 19:35 [FILE] Play command Vincent Pelletier
@ 2005-07-13 16:28 ` Marco Gerards
  2005-07-13 21:08   ` Vincent Pelletier
  0 siblings, 1 reply; 4+ messages in thread
From: Marco Gerards @ 2005-07-13 16:28 UTC (permalink / raw)
  To: The development of GRUB 2

Vincent Pelletier <subdino2004@yahoo.fr> writes:

Hi Vincent,

> Here is the play command source code and some tunes.
> I don't submit a patch since I'm not sure where it will (and where the
> tunes will) go.

Cool!  Won't it be nice to use a user readable fileformat?  It is not
a requirement from my side, just a suggestion. :)

> With Marco we thought about contrib/i386/pc/play.c
>
> "Ancestors" of this code are:
> GNU/Hurd
> Grub 2 cat command
> Grub 2 vga for inb & outb
>
> Contributors for the tunes:
> FSF_Song I_Feel_Pretty Indiana_Jones_Theme Summertime : GNU/Hurd

Marcus made those.

> Beverly Hills Cop. Star Trek: The next Generation : Marco Gerards

It is not the official theme from Star Trek: TNG, but a tune from an
episode I liked a lot (Innerlight).

> Tetris_Theme : me
>
> Vincent Pelletier
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.1 (GNU/Linux)
>
> iD8DBQFC1BuHFEQoKRQyjtURAtfnAJ0Z6EyHKmArEvcGMa7ioMu66zbFZgCglHXy
> actaxo6QqQaFx/UfMrvtC+Q=
> =C1S1
> -----END PGP SIGNATURE-----
>
> /* play.c - command to play a tune  */
> /*
>  *  GRUB  --  GRand Unified Bootloader
>  *  Copyright (C) 2003  Free Software Foundation, Inc.

This should be 2002, 2004, 2005 if I am not mistaken.  The years 2002,
2004 for the Hurd code and 2005 for your changes.  I do not know where
2003 comes from.

> /* Read a byte from a port.  */
> static inline unsigned char
> inb (unsigned short port)
> {
>   unsigned char value;
>
>   asm volatile ("inb    %w1, %0" : "=a" (value) : "Nd" (port));
>   asm volatile ("outb   %%al, $0x80" : : );
>   
>   return value;
> }
>
> /* Write a byte to a port.  */
> static inline void
> outb (unsigned short port, unsigned char value)
> {
>   asm volatile ("outb   %b0, %w1" : : "a" (value), "Nd" (port));
>   asm volatile ("outb   %%al, $0x80" : : );
> }

Is it possible to share this code?  We need it for VGA and now for
play, we will need it more often for other code which we will write in
the future.

Thanks,
Marco




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FILE] Play command
  2005-07-13 16:28 ` Marco Gerards
@ 2005-07-13 21:08   ` Vincent Pelletier
  2005-07-14  8:20     ` Yoshinori K. Okuji
  0 siblings, 1 reply; 4+ messages in thread
From: Vincent Pelletier @ 2005-07-13 21:08 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 1443 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Marco Gerards wrote:
> Cool!  Won't it be nice to use a user readable fileformat?  It is not
> a requirement from my side, just a suggestion. :)

It might require some [f|s]scanf function, and I don't think it is
welcome in the core just because it is used in such peripheral function.
I thought first about using such format, because it's way easier to
edit... But I finally resigned. Maybe a fscanf function could be added
in this module, then moved in the core if it turns out to be useful.

> This should be 2002, 2004, 2005 if I am not mistaken.  The years 2002,
> 2004 for the Hurd code and 2005 for your changes.  I do not know where
> 2003 comes from.

Grub cat command I think :) . I sadly don't pay much attention to the
sources header :$ .

> Is it possible to share this code?  We need it for VGA and now for
> play, we will need it more often for other code which we will write in
> the future.

Maybe could they be added to kern/i386/pc/startup.S .

Vincent Pelletier
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFC1YK+FEQoKRQyjtURAqE7AJ4oZWUXEHGGUn4S/vRTC8TCG5CkYQCePphj
TR+SdKebKNI7KusrtHCJo6I=
=qRrY
-----END PGP SIGNATURE-----

	

	
		
___________________________________________________________________________ 
Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger 
Téléchargez cette version sur http://fr.messenger.yahoo.com




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FILE] Play command
  2005-07-13 21:08   ` Vincent Pelletier
@ 2005-07-14  8:20     ` Yoshinori K. Okuji
  0 siblings, 0 replies; 4+ messages in thread
From: Yoshinori K. Okuji @ 2005-07-14  8:20 UTC (permalink / raw)
  To: The development of GRUB 2

On Wednesday 13 July 2005 23:08, Vincent Pelletier wrote:
> It might require some [f|s]scanf function, and I don't think it is
> welcome in the core just because it is used in such peripheral function.
> I thought first about using such format, because it's way easier to
> edit... But I finally resigned. Maybe a fscanf function could be added
> in this module, then moved in the core if it turns out to be useful.

There is no rule that you must add POSIX-like functions into the kernel. It is 
also fine to have libc.mod, if necessary.

> > Is it possible to share this code?  We need it for VGA and now for
> > play, we will need it more often for other code which we will write in
> > the future.
>
> Maybe could they be added to kern/i386/pc/startup.S .

No. startup.S should be used only if you must use real mode. In this case, we 
use protected mode, so you should add these functions into a C file or a 
header. Defining them in a header makes sense, because they are inline 
functions.

Okuji



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-07-14  8:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-12 19:35 [FILE] Play command Vincent Pelletier
2005-07-13 16:28 ` Marco Gerards
2005-07-13 21:08   ` Vincent Pelletier
2005-07-14  8:20     ` Yoshinori K. Okuji

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.