New terminal outputs using serial: morse and spkmodem.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-01-16 20:39:54 +01:00
parent 34f71cb866
commit b78d6c32e3
10 changed files with 512 additions and 132 deletions

View file

@ -22,6 +22,84 @@
#include <grub/types.h>
#include <grub/err.h>
enum
{
/* The PIT channel value ports. You can write to and read from them.
Do not mess with timer 0 or 1. */
GRUB_PIT_COUNTER_0 = 0x40,
GRUB_PIT_COUNTER_1 = 0x41,
GRUB_PIT_COUNTER_2 = 0x42,
/* The PIT control port. You can only write to it. Do not mess with
timer 0 or 1. */
GRUB_PIT_CTRL = 0x43,
/* The speaker port. */
GRUB_PIT_SPEAKER_PORT = 0x61,
};
/* The speaker port. */
enum
{
/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
from timer 2. */
GRUB_PIT_SPK_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. */
GRUB_PIT_SPK_DATA = 0x02,
GRUB_PIT_SPK_TMR2_LATCH = 0x20
};
/* The PIT control port. You can only write to it. Do not mess with
timer 0 or 1. */
enum
{
GRUB_PIT_CTRL_SELECT_MASK = 0xc0,
GRUB_PIT_CTRL_SELECT_0 = 0x00,
GRUB_PIT_CTRL_SELECT_1 = 0x40,
GRUB_PIT_CTRL_SELECT_2 = 0x80,
/* Read and load control. */
GRUB_PIT_CTRL_READLOAD_MASK= 0x30,
GRUB_PIT_CTRL_COUNTER_LATCH = 0x00, /* Hold timer value until read. */
GRUB_PIT_CTRL_READLOAD_LSB = 0x10, /* Read/load the LSB. */
GRUB_PIT_CTRL_READLOAD_MSB = 0x20, /* Read/load the MSB. */
GRUB_PIT_CTRL_READLOAD_WORD = 0x30, /* Read/load the LSB then the MSB. */
/* Mode control. */
GRUB_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. */
GRUB_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. */
GRUB_PIT_CTRL_PROGR_ONE_SHOT = 0x02,
/* Rate generator. Output is low for one period of the counter, and
high for the other. */
GRUB_PIT_CTRL_RATE_GEN = 0x04,
/* Square wave generator. Output is low for one half of the period,
and high for the other half. */
GRUB_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. */
GRUB_PIT_CTRL_SOFTSTROBE = 0x08,
/* Hardware triggered strobe. Like software triggered strobe, but
only starts the counter when the gate pin is set to high. */
GRUB_PIT_CTRL_HARDSTROBE = 0x0a,
/* Count mode. */
GRUB_PIT_CTRL_COUNT_MASK = 0x01,
GRUB_PIT_CTRL_COUNT_BINARY = 0x00, /* 16-bit binary counter. */
GRUB_PIT_CTRL_COUNT_BCD = 0x01 /* 4-decade BCD counter. */
};
void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics);
#endif /* ! KERNEL_CPU_PIT_HEADER */

47
include/grub/speaker.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef GRUB_SPEAKER_HEADER
#define GRUB_SPEAKER_HEADER 1
#include <grub/cpu/io.h>
#include <grub/i386/pit.h>
/* The frequency of the PIT clock. */
#define GRUB_SPEAKER_PIT_FREQUENCY 0x1234dd
static inline void
grub_speaker_beep_off (void)
{
unsigned char status;
status = grub_inb (GRUB_PIT_SPEAKER_PORT);
grub_outb (status & ~(GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA),
GRUB_PIT_SPEAKER_PORT);
}
static inline void
grub_speaker_beep_on (grub_uint16_t pitch)
{
unsigned char status;
unsigned int counter;
if (pitch < 20)
pitch = 20;
else if (pitch > 20000)
pitch = 20000;
counter = GRUB_SPEAKER_PIT_FREQUENCY / pitch;
/* Program timer 2. */
grub_outb (GRUB_PIT_CTRL_SELECT_2
| GRUB_PIT_CTRL_READLOAD_WORD
| GRUB_PIT_CTRL_SQUAREWAVE_GEN
| GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL);
grub_outb (counter & 0xff, GRUB_PIT_COUNTER_2); /* LSB */
grub_outb ((counter >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */
/* Start speaker. */
status = grub_inb (GRUB_PIT_SPEAKER_PORT);
grub_outb (status | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA,
GRUB_PIT_SPEAKER_PORT);
}
#endif