Social Icons

^^

terça-feira, 16 de agosto de 2011

Delphi com assembly (Parte 7)

- Reproduzindo sons com o PC speaker

As instruções assembler IN e OUT permitem ler e escrever em uma porta de
E/S respectivamente.

Para ler de uma porta:

  IN acumulador, porta

IN le um byte, word ou doubleword da porta especificada para o registro
acumulador, isto é, AL, AX, ou EAX para byte, word ou doubleword
respectivamente. O número de porta pode ser uma constante do tipo byte
(0..255) um o registro DX (para acesso a todas as portas de E/S).

Para escrever em uma porta:

  OUT porta, acumulador

OUT escreve o byte, word ou doubleword no registro acumulador para a
porta especificada. Novamente, o número da porta pode ser uma constate
do tipo byte ou o valor do registro DX.

NOTA: Uma vez que IN e OUT implicam no acesso direto ao hardware, e
      sabendo que os Windows NT/2000/XP não permitem que aplicativos
      do usuário acessem o hardware diretamente, essas instruções não
      funcionarão (irão gerar exceções) nesses sistemas operacionais
      (a não ser que estejam rodando em modo protegido no anel 0, ou
      modo kernel).

Abaixo, veremos um exemplo do uso de assembler na leitura e escrita
às portas de E/S para programar os chips 8253/8254 Contador/Timer e
o 8255 Programmable Peripheral Interface (PPI) na placa-mãe de modo
a fazer o PC speaker reproduzir um som.

Os passos para tocar um som usando os chips são os seguintes:

1) Prepare os 8253/8254 para receber a freqüência. Isso é feito ao
   escrever o valor $B6 no Timer Control Register (porta $43).

2) Escrever a freqüência do som no Frequency Register do 8253/8254
   (porta $42). Na verdade, não é a freqüência em Hertz que devemos
   escrever no registro, mas o resultado de 1331000 dividido nesta
   freqüência. Primeiramente devemos escrever o byte de mais baixa
   ordem do resultado para, em seguida, o byte de mais alta ordem.

3) Ligar o PC speaker e fazê-lo utilizar o 8253/8254 Counter/Timer.
   Isso é feito ao definir os dois primeiros bits da Porta B do 8255
   PPI (porta $61).

4) Desligar o PC speaker quando o som finalizar. Isso é feito ao
   zerar o segundo bit da porta B do 8255 PPI (porta $61).

A função assembler inline abaixo implementa os passos listados acima:

  procedure SpeakerSound(Frequency: word; Duration: longint);
  // Copyright (c) 2003 Ernesto De Spirito
  // Visit: http://www.latiumsoftware.com
  // Plays a tone thru the PC speaker using the 8253/8254
  // Counter/Timer chip and the 8255 Programmable Peripheral
  // Interface (PPI) chip on the motherboard.
  // NOTE: This code won't work under Windows NT/2000/XP.
  asm
    push edx          // Push Duration on the stack (for Sleep)
    mov cx, ax        // CX := Frequency;
    // Prepare the 8253/8254 to receive the frequency data
    mov al, $B6       // Function: Expect frequency data
    out $43, al       // Write to Timer Control Register
    // Compute the frequency data
    mov dx, $14       // DX:AX = $144F38
    mov ax, $4F38     //       = 1331000
    div cx            // AX := 1331000 / Frequency;
    // Send the frequency data to the 8253/8254 Counter/Timer chip
    out $42, al       // Write low byte to the Frequency Address
    mov al, ah        // AL := High byte of AX
    out $42, al       // Write high byte to the Frequency Address
    // Tell the 8255 PPI to start the sound
    in al, $61        // Read Port B of the 8255 PPI
    or al, $03        // Set bits 0 and 1:
                      // bit 0 --> use the 8253/8254
                      // bit 1 --> turn speaker on
    out $61, al       // Write to Port B of the 8255 PPI
    // Wait
    call Sleep        // Sleep(Duration); // requires Windows unit
    // Tell the 8255 PPI to stop the sound
    in al, $61        // Read Port B of the 8255 PPI
    and al, NOT 2     // Clear bit 1 (turn speaker off)
    out $61, al       // Write to Port B of the 8255 PPI
  end;

Exemplo de chamada:

  procedure TForm1.Button1Click(Sender: TObject);
  var
    i: integer;
  begin
    Randomize;
    for i := 1 to 3 do
      SpeakerSound(Random(900)+100, 200);
  end;

NOTA: Usar o PC speaker para gerar som é OBSOLETO. Aplicações devem usar
      sons MIDI ou WAVE ao invés.


Nenhum comentário:

Postar um comentário

Popular Posts

 

Seguidores

Hora exata:

Total de visualizações de página