grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: play.c


From: Vincent Pelletier
Subject: Re: play.c
Date: Sat, 05 Nov 2005 21:20:48 +0100
User-agent: Debian Thunderbird 1.0.7 (X11/20051017)

Yoshinori K. Okuji wrote:
> I point out some stylish mistakes.

For once that I have the Changelog entry right :) .

> You must put the starting brace character on next line:

Please don't waste your time giving an example when it's that trivial,
or please do it in the diff file directly...

> The lines are folded incorrectly.

I also corrected the lines length where needed.

Vincent Pelletier
Index: commands/i386/pc/play.c
===================================================================
RCS file: commands/i386/pc/play.c
diff -N commands/i386/pc/play.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ commands/i386/pc/play.c     5 Nov 2005 14:06:00 -0000
@@ -0,0 +1,251 @@
+/* play.c - command to play a tune  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005  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;
+}
+
+
+#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 */
Index: conf/i386-pc.rmk
===================================================================
RCS file: /cvsroot/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.50
diff -u -p -r1.50 i386-pc.rmk
--- conf/i386-pc.rmk    24 Oct 2005 10:23:46 -0000      1.50
+++ conf/i386-pc.rmk    5 Nov 2005 14:06:02 -0000
@@ -117,7 +117,7 @@ pkgdata_MODULES = _chain.mod _linux.mod 
        apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod       \
        help.mod default.mod timeout.mod configfile.mod vbe.mod         \
        vesafb.mod vbetest.mod vbeinfo.mod search.mod gzio.mod          \
-       terminfo.mod serial.mod xfs.mod affs.mod sfs.mod
+       terminfo.mod serial.mod xfs.mod affs.mod sfs.mod play.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -347,3 +347,8 @@ search_mod_LDFLAGS = $(COMMON_LDFLAGS)
 gzio_mod_SOURCES = io/gzio.c
 gzio_mod_CFLAGS = $(COMMON_CFLAGS)
 gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For play.mod.
+play_mod_SOURCES = commands/i386/pc/play.c
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]