ZX-Ревю 1994 №5 1993 г.

Профессиональный подход - процедура "ЗВЁЗДЫ".


Процедура "ЗВЕЗДЫ"

© Константин Короткое, г. Людиново, Калужская область, 1994

В программе "Norton Commander" для IBM-овских машин есть замечательный режим - режим экономии ресурса монитора, который включается автоматически, если в течение некоторого времени на клавиатуре не нажималась ни одна клавиша. При этом экран монитора гаснет, а чтобы информировать пользователя о том, что компьютер включен, на нем формируется картинка "звездного неба". При нажатии на любую клавишу информация на экране восстанавливается.

Предлагаемая процедура служит для создания подобного эффекта в Спектрумовских программах. По-моему, прикладные и системные программы, формирующие на экране статичную, в основном буквенно-цифровую информацию, должны иметь такой режим. Теперь о процедуре.

1. Условия работы.

Для нормальной работы приведенного варианта процедуры должны быть разрешены прерывания первого рода. Процедура работает со вторым (23673) байтом системной переменной FRAMES, выполняющей роль таймерного счетчика. При инициализации процедуры этот байт обнуляется, а затем процедура контролирует превышение заданного значения времени по его содержимому.

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

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

2. Рабочая среда.

Приведенный вариант формирует на экране 25 звезд. Для описания каждой из них необходимо 4 байта: 2 байта - адрес, 3-й байт - длительность текущей фазы, 4-й - яркость. Итого - 4x25=100 байтов (количество звезд может быть изменено, соответственно изменится размер массива). Этот массив памяти не будет никак использоваться до тех пор, пока не заработает процедура.

Для рационального использования ОЗУ можно предложить, по крайней мере, два способа.

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

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

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

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

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

Второе: если изображение монохромное, то можно не сохранять атрибуты - это 768 байтов экономии.

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

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

Кроме того, в головной программе может существовать процедура регенерации или формирования изображения на экране. В этом случае также не нужно сохранять экран, а достаточно просто передать ей управление, если программа переходила в дежурный режим. Об этом можно узнать по состоянию флага "С" - если он сброшен после обращения к процедуре, значит, был дежурный режим.

Приведенный в листинге вариант использует буфер для всего экрана.

00010

ORG

40000

;

00020

ATTR

EQU

22528

; Адрес

файла атрибутов.

00030

SCRA

EQU

16384

; Адрес

экрана.

00040

TIME

EQU

23673

; Адрес

второго байта FRAMES

00050

NST

EQU

25

;Количество звезд.

00060

LASTK

EQU

23560

;Символ с клавиатуры.

00070

SCRL

EQU

6912

;Размер экрана.

00080

OUTB

EQU

71

;Атрибут вспышки.

00090

STBC

EQU

#2D2B

;BC в калькулятор.

00100

STST

EQU

#2AB1

;Параметры строки в калькулятор.

00110

FPBC

EQU

#2DA2

;Из калькулятора в BC.

00120

SETW

EQU

# 1 6BF

;0чистить рабочую обл. и калькулятор

00130

BEEP

EQU

#3F8

;Звуковой сигнал.

00140

VAL

EQU

#1D

;Команда калькулятора.

00150

MULT

EQU

4

00160

INT

EQU

#27

00170

ECAL

EQU

#38

00180

DARK

EQU

0

;Атрибут гашения.

00190

TIM

EQU

3

;Bремя ожидания.5

00200

;

00210

STARS

LD

A, (TIME)

;Информация из таймера.,(TIME)

00220

CP

TIM

;Прошло заданное время?

00230

RET

С

;Если нет, выход с установленным ;флагом "C".

00240

CALL

STSC

; Охранить экран.

00250

LD

HL,SCRA

00260

LD

DE,SCRA+1

00270

XOR

A

00280

LD

(LASTK),A

^брос признака нажатия клавиши.

00290

OUT

(254),A

00300

LD

(HL),A

;Дочистить экран и атрибуты.

00310

LD

BC,SCRL-1

00320

LDIR

00330

LD

HL,17152

00340

LD

B, 3

;Количество сегментов экрана.

00350

N1

PUSH

BC

00360

LD

BC,511

00370

LD

E, L

00380

LD

D, H

00390

INC

DE

00400

LD

(HL),24

;Рисование звезды.

00410

LDIR

00420

LD

DE,1537

;Cмещение адреса до следующего сегме!

00430

ADD

HL, DE

00440

POP

BC

00450

DJNZ

N1

00460

LD

B, NST

;Количество звезд.

00470

LD

IX,ARR

;Адрес массива описания звезд.

00480

IST

CALI

INIT

;Инициализация звезды.

00490

LD

DE,4

;Cмещение до следующего элемента.

00500

ADD

IX, DE

00510

DJNZ

IST

;Инициализация всего массива.

00520

ALL

LD

IX,ARR

00530

LD

B, NST

00540

ONE

DEC

(IX+2)

;Закончилась фаза жизни?

00550

JR

NZ, N2

; Нет.

00560

INC

(IX+3)

;Иначе - увеличить яркость.

00570

PUSH

BC

00580

LD

BC,250

;Максимальная фаза жизни.

00590

CALL

CALC

;Теперь в BC - случайное число.

00600

INC

C

00610

LD

(IX+2),C

;Длительность очередной фазы.

00620

POP

BC

00630

N2

LD

A,(IX+3)

;Яркость звезды.

00640

LD

L, (IX)

00650

LD

H, (IX+1)

;B HL - адрес звезды.

00660

CP

8

; Конец жизни?

00670

OR

NZ, N3

; Нет.

00680

LD

A, #F

00690

AND

(IX+2)

00700

LD

(IX+2),А

Время вспышки.

00710

LD

A,OUTB

00720

N3

CP

9

Звезда сгорела?

00730

JR

NZ, N4

Нет.

00740

LD

(HL),DARK

Погасить звезду.

00750

CALL

INIT

Инициализировать новую звезду.

00760

JR

N5

;

00770

N4

LD

(HL),A

;

00780

N5

LD

DE,4

00790

ADD

IX, DE

;

00800

LD

A,(LASTK)

00810

OR

A

Нажата клавиша?

00820

JR

Z,N6

Нет.

00830

CALL

FPSC

Иначе - восстановить экран.

00840

RST

#28

Подпрограмма "ВЕЕР .25,25".

00850

DEFB

#A2,#A2,MULT

00860

DEFB

#31,#A4,#A4

00870

DEFB

MULT,MULT

, ECAL

00880

CALL

BEEP

3вук, восстановить бордюр.

00890

XOR

A

Сброс флага "С".

00900

LD

(TIME),A

00910

RET

Выход со сброшенным флагом "С"

00920

N6

DJNZ

ONE

Повтор для каждой звезды.

00930

JR

ALL

Повторять до нажатия клавиши.

00940

; Подпрограммы

сохранения и

восстановления экрана.

00950

STSC

LD

HL,SCRA

00960

LD

DE,BUSC

00970

JR

MOVE

00980

FPSC

LD

HL,BUSC

00990

LD

DE,SCRA

01000

MOVE

LD

BC,SCRL

01010

LDIR

01020

RET

;

01030

; Подпрограмма

инициализ ации

одного

элемента массива

01040

; на

входе - в

IX

адрес элемента массива.

01050

INIT

PUSH

ВС

01060

LD

ВС,769

01070

CALL

CALC

Случайное число 0...7 68.

01080

LD

HL,ATTR

Адрес файла атрибутов.

01090

ADD

HL, BC

Адрес звезды.

01100

LD

(IX),L

OHIO

LD

(IX+1) , H

01120

LD

ВС,250

01130

CALL

CALC

01140

INC

С

01150

LD

(IX+2),С

Длительность фазы жизни.

01160

LD

(IX+3),1

Начальная яркость.

01170

POP

ВС

01180

RET

01190

; Подпрограмма,

выполняющая

функцию

бейсик-оператора

01200

; LET

BC=INT(BC*RND)

01210

; на

входе - в

ВС

максимальное значение случайного числа

01220

; на

выходе - в

ВС

случайное

число.

01230

CALC

CALL

STBC

ВС в калькулятор.

01240

LD

ВС,1

Длина команды RND.

01250

LD

DE,RND

Адрес команды.

01260

CALL

STST

Параметры строки в калькулятор

01270

LD

B, VAL

01280

RST

#28

01290

DEFB

VAL,MULT

01300

DEFB

INT,ECAL

01310

CALL

FPBC

Число в ВС.

01320

PUSH

BC

01330

CALL

SETW

01340

POP

BC

01350

RET

01360

RND

DEFB

165

Код токена RND

01370

ARR

DEFS

NST

Массив описаний.

01380

DEFS

NST

Буфер экрана.

01390

DEFS

NST

01400

DEFS

NST

01410

BUSC

DEFS

SCRL

01420

; Пример

использования процедуры.

01430

ENT

01440

OPEN

EQU

#1601

Процедура "Открыть канал".

01450

CLS

EQU

#D6B

Процедура "Очистить экран".

01460

EXAMPL

LD

A, 2

01470

CALL

OPEN

01480

CALL

CLS

01490

LD

A, 2

01500

CALL

OPEN

01510

UN

XOR

A

01520

LD

(TIME),A

Инициализация процедуры.

01530

RES

5,(IY+1)

Сбросить готовность клавиатуры

01540

WAIT

CALL

STARS

Контроль времени.

01550

OR

NC,IIN

Если был дежурный режим.

01560

BIT

5,(IY+1)

Нажата клавиша?

01570

OR

Z,WAIT

Нет.

01580

LD

A,(LASTK)

Иначе в А - код клавиши.

01590

CP

32

01600

RET

C

Выход, если это упр.символ.

01610

RST

#10

Иначе - печать символа

01620

JR

IIN

и зацикливание.

Start

of object: #9C40

(40000)

Length

: #1C82

(07298)

Executes

: #B899

(47957}

После набора программы и ее ассемблирования, запустите процедуру EXAMPL и наберите с ее помощью на экране произвольный текст (не используя клавишу ENTER и другие управляющие клавиши). Не трогайте клавиатуру в течение трех минут (для контрольного запуска это время можно уменьшить, изменив время TIM - замените число 35 на 5 в строке 220 листинга, это уменьшит время ожидания до 30 секунд). Понаблюдайте за работой процедуры>1 и затем нажмите любую клавишу. Информация на экране восстановится, раздастся звуковой сигнал, восстановится цвет бордюра. Выход из EXAMPL - клавиша ENTER.

Комментарий ИНФОРКОМа.

Как обычно, для тех, кто не владеет ассемблером, приводим полный дамп кодового блока. Он состоит из двух частей, между которыми находится буфер. Для демонстрации можете сохранить их как два разных файла: SAVE "starsl" CODE 40000,245 SAVE "stars2" CODE 40257,41




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Hints! - игра Japanese Contrast.
Иной мир - Radeon X700: недорогая основа для геймерских карт.
Новости - Состояние дел у Ростовских спектрумистов: Disabler, Klim, Wild, Dimon, The Rom.
ZХ-Land: Х-Project Аssociation - Взгляд изнyтри - В этoй рyбрикe я бы хoтeл знaкomить вac c гoрoдamи, в кoтoрых Speccy coхрaняeт eщe cвoи пoзиции...
Смайлик - коллекция текстовых смайликов.

В этот день...   21 ноября