Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ассемблер. Учебное пособие

..pdf
Скачиваний:
178
Добавлен:
02.05.2014
Размер:
557.54 Кб
Скачать

а в конце ее восстановить сохраненный вектор (функция 35h прерывания Int 21h).

Метод, основанный на применении прерывания Int 1Сh, позволяет управлять устройствами в реальном времени циклично с периодом, кратным 1/18 с. Если же необходимо обеспечить управление в произвольные моменты времени в течение суток, то можно применить другой метод, при котором используется прерывание Int 4Аh (прерывание будильника). Рассмотрим применение этого метода.

Для установки будильника надо воспользоваться функцией 06h прерывания Int 1Ah. После этого нужно заменить вектор обработчика Int 4Ah собственным вектором прикладного обработчика. После установки будильника РТС будет генерировать прерывание Int 4Аh каждые сутки в заданное время до тех пор, пока будильник не будет выключен с помощью функции 07h того же прерывания Int 1Ah. Фрагмент программы установки будильника на срабатывание в конкретный момент времени выглядит следующим образом:

; сохраним вектор 4Ah в 2-байтовой ячейке old_4Ah mov ax, 354Ah

int 21h

; установим собственный обработчик прерывания Int 4Ah mov ax, 254Ah

mov dx, offset new_4Ah int 21h

;установим будильник:

;ch=часы, cl=минуты, dh=секунды (BCD-формат)

mov ah, 06Ah int 1Ah

43

3.5. Генерация звука

Создавать простые звуки с помощью системных средств ПК можно двумя способами:

1. Использование канала 2 системного таймера i8254. (рис.3.4)

 

19318Мгц

 

 

 

 

 

CLK

OUT2

 

 

Бит 0

GATE2

 

&

 

 

 

 

Порт 61h

Бит 1

 

 

 

 

 

 

K2

динамик

 

 

 

 

Рис. 3.4. Генерация звука с использованием канала 2 системного таймера i8254

Метод состоит в следующем. Два сигнала: выход OUT канала 2 таймера и бит 1 порта 61h объединяются по схеме логическое "И" и поступают на вход звукогенератора. Поэтому простейший способ генерации звука состоит в программировании канала 2 таймера так, чтобы он выдавал прямоугольный импульс заданной частоты, находящейся в звуковом диапазоне (20 Гц–20 КГц). Для этого следует использовать режим 3 таймера с начальным значением счетчика. Если затем установить биты 0 и 1 порта 61h, то импульс начнет поступать на вход звукогенератора (бит 0 определяет разрешение работы канала 2 GATE=1, а бит 1 – разрешение выдачи прямоугольного сигнала с выхода OUT. Для выключения звука надо сбросить биты 0 - 1 в порте 61h. Преимущество этого метода состоит в том, что, запустив генерацию звука, центральный процессор может выполнять другие действия. Значение счетчика канала 2 вычисляется по формуле:

n=1193181/f,

где 1193181 Гц – тактовая частота таймера, f – требуемая частота звука.

Пример:

;подпрограмма генерации звука

;Вход: АX= частота звука в Гц

Sound proc near

44

push

ax

;сохранить регистры

push

bx

 

push

dx

 

mov

bx, ax

;частота

mov

ax,34DDh

mov

dx,12h

;(dx,ax)=1193181=1234DDh

cmp

dx, bx

;если bx < 18 Гц, то выход,

jnb

Done

;чтобы избежать переполнения

div

bx

;ax=(dx,ax)/bx

mov

bx, ax

;счетчик таймера

in

al, 61h

; в порте 61h

or

al, 3

;установить биты 0,1

out

61h, al

 

;управляющий байт таймера: канал 2, режим 3, двоичный счет

mov

al, 0b6h

mov

dx, 43h

out

dx, al

;вывод в регистр режима

dec

dx

 

mov

al, bl

 

out

dx, al

;младший байт счетчика

mov

al, bh

 

out

dx, al

;старший байт счетчика

Done:

 

 

pop

dx

;восстановить регистры

pop

bx

 

pop

ax

 

ret

 

 

Sound endp

 

 

; подпрограмма выключения генерации звука

No_Sound proc near

 

push ax

 

 

in

al, 61h ;в порте 61h

and

al, not 3

;сбросить биты 0,1

out

61h, al

 

pop

ax

 

ret

 

 

No_Sound endp

45

Для генерации музыки можно использовать следующий алгоритм.

Пусть octave – номер октавы (1, 2, ...); note – номер ноты в октаве (до=1, до#=2, ..., си=12). Тогда:

f := 32.625;

for i := 1 to oktave do f := 2*f;

for i := 1 to note do f := 1.059463094*f; Sound (round(f));

2. Прямое управление динамиком. Второй способ генерации звука состоит в том, чтобы генерировать звуковые импульсы не с помощью выходного сигнала канала 2 таймера, а непосредственной установкой и сбросом бита 1 в порте 61h. При этом, если на вход GATE канала 2 таймера подать запрет (бит 0 в порте 61h должен быть сброшен), то динамик выдаст характерные звуковые щелчки с частотой, определяемой изменением состояния бита 1 порта 61h. Для

формирования

задержек

при моделировании меандра

можно

использовать программный цикл, например:

 

; Программа генерации звука

 

; Вход: N=количество импульсов

 

;FREQ=длительность импульса

 

in

al, 61h

; запрет работы канала 2

 

and

al, not 1

; таймера

 

mov

dx, N

 

 

Repeat:

 

 

 

or

al, 2

; включить динамик

 

out

61h, al

 

 

mov

cx, FREQ

 

Wait_On:

 

; длительность

 

loop

Wait_On ; звучания

 

and

al,not 2

; выключить динамик

 

out

61h,al

 

 

mov

cx,FREQ

 

Wait_Off:

 

; длительность

 

loop

Wait_Off

; паузы

 

dec

dx

 

 

jnz

Repeat

 

 

46

Программирование этого способа основано на следующих формулах:

N=T*f,

FREQ=t/(34*f);

где Т – длительность звучания в сек, f – частота звука в Гц, t

тактовая частота центрального процессора в Гц.

Константа 34 объясняется тем, что длительность каждого из циклов Wait_on и Wait_off приблизительно равна (17*cx) машинных тактов.

Недостаток этого метода заключается в том, что центральный процессор полностью занят генерацией звука – любое прерывание испортит временную диаграмму звукового сигнала. Однако он обеспечивает точную подстройку частоты и позволяет создавать несимметричные импульсы варьированием задержек в циклах

Wait_on и Wait_off.

47

4. Ввод информации с клавиатуры ПК

Клавиатуры соединяются с ПК посредством шифратора, микросхемы, которая преобразует каждый удар по клавише в 8- битовый ASCII-код.

Система ASCII представляет собой набор числовых кодов, используемых в ЭВМ для обмена данными. Стандартный набор символов ASCII (табл. 4.1) состоит из 128 символов от 00H до 7FH, который кроме символов букв, цифр и специальных знаков содержит еще и управляющие символы, необходимые для управления периферийными устройствами ПК.

Все генерируемые клавиатурой коды символов могут быть представлены лишь с помощью так называемой расширенной системы ASCII (256 кодов), в расширении этой системы находятся коды символов псевдографики, букв греческого алфавита или национального алфавита страны пользователя.

Всякий раз, когда Вы нажимаете или отпускаете клавишу, встроенное в клавиатуру устройство запоминает в своей внутренней памяти код нажатия или отпускания (соответственно 1 или 0) в седьмом бите и идентификатор клавиши (scan-код) в остальных битах. После этого устройство посылает системе BIOS прерывание типа 9, сообщающее, что у него есть данные для передачи.

Память клавиатуры способна хранить до 10 операций нажатия и отпускания (ударов), ее переполнение вызывает генерацию звукового сигнала. Система BIOS считывает байты из памяти клавиатуры и преобразует их в коды символов. В процессе преобразования scanкода проверяются, не были ли нажаты некоторые клавиши (без отпускания), что позволяет формировать коды символов, отражающие комбинации клавиш с Ctrl, Shift, Alt. По завершении работы процедура обработки прерывания типа 9 запоминает scan-код и код символа в буфере клавиатуры, находящемся в памяти ПК.

Любой символ из таблицы ASCII можно получить набором кода в десятичном формате на дополнительной клавиатуре при нажатой клавише Alt. Например, ввод символа { осуществляется комбинацией

Alt+123.

48

 

 

Стандартный набор символов ASCII

 

Таблица 4.1

 

 

 

 

 

 

0

1

2

3

4

5

6

 

7

 

 

 

 

 

 

 

 

 

 

0

NULL

DLE

SP

0

@

P

`

 

p

 

 

 

 

 

 

 

 

 

 

1

SOH

DC1

!

1

A

Q

a

 

q

 

 

 

 

 

 

 

 

 

 

2

STX

DC2

«

2

B

R

b

 

r

 

 

 

 

 

 

 

 

 

 

3

ETX

DC3

#

3

C

S

c

 

s

 

 

 

 

 

 

 

 

 

 

4

EOT

DC4

$

4

D

T

d

 

t

 

 

 

 

 

 

 

 

 

 

5

ENQ

NAK

%

5

E

U

e

 

u

 

 

 

 

 

 

 

 

 

 

6

ACK

SYN

&

6

F

V

f

 

v

 

 

 

 

 

 

 

 

 

 

7

BEL

ETB

7

G

W

g

 

w

 

 

 

 

 

 

 

 

 

 

8

BS

CAN

(

8

H

X

h

 

x

 

 

 

 

 

 

 

 

 

 

9

HT

EM

)

9

I

Y

i

 

y

 

 

 

 

 

 

 

 

 

 

A

LF

SUB

*

:

J

Z

j

 

z

 

 

 

 

 

 

 

 

 

 

B

VT

ESC

+

;

K

[

k

 

{

 

 

 

 

 

 

 

 

 

 

C

FF

FS

,

<

L

\

l

 

|

 

 

 

 

 

 

 

 

 

 

D

CR

GS

-

=

M

]

m

 

}

 

 

 

 

 

 

 

 

 

 

E

SO

RS

.

>

N

^

n

 

~

 

 

 

 

 

 

 

 

 

 

F

SI

US

/

?

O

_

o

 

DEL

 

 

 

 

 

 

 

 

 

 

49

Таблица 4.2

 

Расширенные коды клавиш

Расширенный

Функция

Код(HEX)

 

3

Ctrl @

F

BACKSPACE()

10-19

Alt Q W E R T Y U I O P(второй ряд)

1E-26

Alt A S D F G H J K L

2C-32

Alt Z X C V B N M

3B-44

F1-F10

47

Home

48

49

PgUp

4B

4D

4F

End

50

51

PgDn

52

Ins

53

Del

54-5D

Shift F1-F10

5E-67

Ctrl F1-F10

68-71

Alt F1-F10

Когда программа запрашивает введенный символ, BIOS возвращает ASCII-код этого символа и его scan-код в регистрах AL и AH соответственно. Другие клавиши, не представленные в кодах ASCII, возвращают 0 в регистре AL и расширенный код в регистре AH, т.е. для определения кода нажатой клавиши необходимо дважды произвести ввод символа с клавиатуры.

Для работы с клавиатурой ПК программист может использовать функции прерывания 16h BIOS и функции прерывания 21h DOS.

Прерывание 16h предусматривает весьма примитивные операции обмена данными с клавиатурой, которые полезны, когда программа исполняется независимо от DOS.

В зависимости от значения, записываемого в регистр AH, прерывание Int 16h позволяет выполнить следующие операции.

Int 16h, функция 00h, чтение символа с клавиатуры Вызов: АН = 00Н

Возврат: АН = scan-код клавиши,

50

AL = код символа.

Одновременно с чтением продвигается указатель буфера. Если буфер пуст, то программа обработки прерывания ожидает нажатия клавиши и затем продолжает его обработку.

Int 16h, функция 01h, получить состояние клавиатуры Вызов: АН = 01h

Возврат: если флаг нуля сброшен, т.е. ZF=0, то АН = scan-код клавиши,

AL = код символа.

Если ZF=1, то буфер клавиатуры пуст.

При вызове данной функции прерывания буфер клавиатуры не очищается, т.е. при последующем вызове функции 0 прерывания 16h будет считан тот же самый символ.

Int 16h, функция 03h, устанавливает скорость повтора Вызов: АН = 03h

АL = 05h

BH = задержка повторения ( 0-3 от 250мс до 1000мс) BL = скорость повторения (00-1Fh от 30 до 2

символов в секунду). Возврат: ничего не возвращает

Данная функция позволяет настроить клавиатуру под скорость ввода информации пользователем.

Int 16h, функция 10h, прочитать символ с расширенной клавиатуры

Вызов: АН = 10h

Возврат: АН = scan-код клавиши

AL = символ ASCII

Эта функция позволяет получать скан-коды дополнительных клавиш F11 и F12, а также клавиш управления курсором, не используя дважды функцию 00h этого же прерывания.

Более гибкие возможности для программистов предоставляют функции прерывания 21h операционной системы. Рассмотрим наиболее встречающиеся в программах функции.

Int 21H, функция 01H, ввод символа с эхо Вызов: AH = 01h

Возврат: AL = код символа

51

Вводит символ с клавиатуры, а затем отображает его на экране дисплея. Если символ не готов, то ждет его появления. Для чтения расширенных ASCII-кодов функцию необходимо вызвать дважды.

Int 21H, функция 06H, непосредственный ввод-вывод через консоль

Вызов: AH = 06h

DL = запрашиваемая функция

00h – FEh, если запрашивается вывод 0FFh – если запрашивается ввод

Возврат: если DL = 00h – FEh, то ничего не возвращается если DL = 0FFh и ZF=0, то

AL = код символа

ZF = 1 символ не готов

Int 21H, функция 07H, нефильтрованный ввод без эхо Вызов: AH = 07h

Возврат: AL = код символа

Выполняет операцию чтения символа с клавиатуры без отображения его на экране дисплея. Если символа нет, то ждет его появления. Для расширенных кодов клавиатуры функцию следует использовать дважды.

Int 21H, функция 08H, ввод без эхо Вызов: AH = 08h

Возврат: AL = код символа

Те же самые операции, что и функция 07Н, только с проверкой на нажатие Ctrl+Break, т.е. реализована возможность прервать программу.

Int 21H, функция 0AH, нефильтрованный ввод без эхо Вызов: AH = 0Ah

DS:DX = сегмент : адрес буфера

Возврат: возврата нет, так как символ помещается в буфер, созданный пользователем.

Буфер клавиатуры, используемый данной функцией, имеет следующий формат:

1-й байт – максимальное число вводимых символов, установленное программой;

2-й байт – фактическое число прочитанных символов (счетчик числа символов в буфере);

52