Пакет документации о рестартах iS-DOS 1969 г.

Рестарты - WIND.SYS (#70...#7F).


 

#70 (112) $scrol

 

Еще один чрезвычайно полезный при работе с текстами рестарт - scrol(#70). Он позволяет смещать содержимое рабочей области окна на строку вверх или вниз.

При работе рестарта предусмотрено программирование заполнения крайнего левого и крайнего правого знакомест в освободившейся строке (нижней при движении вверх и наоборот).

Входные параметры:   IX - вектор окна

HL - значение крайних байтов заполнения освободившейся строки (образ кодируется в двоичном представлении, например: одинарная линия по краю кодируется как 10000000 00000001 и т.п.)

A - режим работы: A=0 - настройка рестарта на вектор окна - вызывается один раз перед началом работы в данном окне. Настройка сохраняется на все время работы до следующего вызова scrol c нулевым значением в регистре A.

A=1 - скроллинг на строку вверх

A=2 - скроллинг на строку вниз

Для нормальной работы scrol необходимы еще два параметра, добавляемые к стандартному вектору окна и располагающиеся непосредственно перед ним:

IX-1 скорость скроллинга - возможные значения - 1, 2, 4, 8 определяет время, в течение которого строка перемещается на 8 пикселей по вертикали

IX-2 задержка скроллинга - возможные значения от 0 до 255 - регулирует время паузы между последовательными вызовами рестарта

Подбором этих двух параметров достигается наибольшая плавность движения при требуемой скорости скроллинга.

Пример:

 

Листинг 15 Применение $scrol(#70)

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

 

;настройка процедуры scroll на вектор окна:

 

LD IX,WIND         ;вектор окна

LD C,#70        ;код рестарта

LD HL,#0000 ;заполнение

XOR A              ;в регистре A - 0

RST #10

 

;печать строки prstr подфункция 3

 

LD IX,WIND

LD HL,TEXT

LD C,#68

LD E,3

LD A,%00001010

LD B,1

RST #10

 

;скроллинг окна вверх в цикле на 5 строк

 

LD B,5

 

M1           PUSH BC

LD C,#70        ;код рестарта

LD A,1            ;скроллинг вверх

LD IX,WIND    ;вектор окна

LD HL,#0000 ;заполнение

RST #10

POP BC

DJNZ M1

CALL WAIT

JP EXIT

 

;вектор окна + 2 байта для рестарта $scrol(#70)

 

DEFB 25           ;задержка

DEFB 01           ;скорость

WIND     DEFB 0

DEFB 5

DEFB 12

DEFB 25

DEFB %00000111

DEFB %00000001

DEFB 2

DEFB 25

 

;текст для печати

 

TEXT      DEFM "Так работает scrol(#70)"

DEFB #0D

DEFB #03

 

Применение рестарта scrol вместе с рестартами печати (например prstr) позволяет организовать на экране режим "бегущего текста".

Рассмотрим еще один пример:

 

Листинг 16 Программа "бегущий текст"

 

ORG #5D64

 

;процедура открытия окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

 

;настройка процедуры scrol на вектор окна:

 

LD IX,WIND

LD C,#70

LD HL,0

XOR A

RST #10

 

;входные параметры для процедуры печати

 

LD A,%00001010

 

;в рег. A - биты 7 и 6 определяют режим выравнивания

;биты 5...0 определяют отступ от верхнего края окна

 

LD B,1       ;номер строки в тексте (строки отделяются друг от друга символом с кодом #0D)

M1           PUSH AF    ;сохранить регистр A

PUSH BC   ;сохранить BC

 

;печать строки по номеру ее в тексте

 

LD IX,WIND    ;адрес вектора окна

LD HL,TEXT    ;адрес начала текста

LD C,#68        ;код prstr

LD E,3            ;код подфункции

RST #10

CALL SCROLL  ;вызов scrol

POP BC            ;восстановить BC

INC B             ;увеличить номер строки в тексте

LD A,B           ;проверка на число

CP 9               ;напечатанных строк

JP Z,END         ;выход, если все строки напечатаны

POP AF          ;восстановить A

JR M1            ;переход к печати следующей строки

 

;вектор окна + 2 байта для рестарта $scrol(#70)

 

DEFB 25           ;задержка

DEFB 01           ;скорость

WIND     DEFB 1

DEFB 1

DEFB 12

DEFB 28

DEFB %00000111

DEFB %00000001

DEFB 4

DEFB 35

 

;текст для печати

 

TEXT      DEFM "Эта программа"

DEFB 13

DEFM "представляет собой пример"

DEFB 13

DEFM "организации в системе"

DEFB 13

DEFM "IS-DOS работы с экраном"

DEFB 13

DEFM "в режиме 'бегущий текст'"

DEFB 13

DEFM "Вывод текста организуется"

DEFB 13

DEFM "при помощи рестартов"

DEFB 13

DEFM "scrol(#70) и prstr(#68)"

DEFB 13

 

;Дополнительные процедуры:

 

SCROLL LD C,#70         ;процедура скрол-

LD A,1            ;линга окна на

LD IX,WIND    ;строку вверх

LD HL,#0000

RST #10

RET

 

END         POP AF        ;завершение работы

CALL WAIT

JR EXIT

 

#71 (113) $tylin

 

Распечатка строки по вектору для edstr от XS (позиции курсора) до конца видимой области.

Вход: IX - адрес вектора ("ошибок быть не может")(см. ПРИЛОЖЕНИЯ 10..13)

 

#72 (114) $g_scr

 

Возвращение в регистре HL' адреса вектора экрана и beep'a (см. ПРИЛОЖЕНИЕ 14)


 

#73 (115) $cls

 

Если при вызове рестарта cls в регистре A находится 0, то происходит полная очистка экрана - все пиксели сбрасываются, область цветовых атрибутов заполняется текущим значением системной переменной PAPER, находящейся в векторе экрана, адрес которого можно получить, используя рестарт $q_scr(#72). Также при этом цвет бордюра приводится в соответствие с текущим значением системной переменной BORD из того же вектора. Формат задания значений цветов стандартный, атрибуты бордюра кодируются тремя младшими байтами, остальные байты игнорируются.

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

Как уже говорилось выше, доступ к системным переменным PAPER и BORD можно получить через вектор экрана, адрес которого возвращает в регистре HL' рестарт $q_scr(#72). Вектор экрана (не путать с вектором окна) представляет собой область системных переменных, уровня WIND.SYS. Необходимые нам переменные располагаются в нем следующим образом:

Если в регистре IX - адрес вектора экрана, то

(IX+0) - значение PAPER

(IX+1) - значение BORD

Остальные системные переменные этого вектора будут рассмотрены позднее.

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

 

LD C,#72        ;код рестарта q_scr

RST #10

EXX                 ;HL - адрес вектора

PUSH HL        ;переносим его

POP IX           ;в регистр IX

LD A,%00101010

LD (IX+0)        ;загрузка атрибутов экрана

LD A,%00000100

LD (IX+1)        ;загрузка атрибутов бордюра

 

После этого Вы смело можете обнулять регистр A и вызывать cls:

 

XOR A

LD C,#73

RST #10

 

значения цветов будут установлены именно так, как Вы и хотели.

Рассмотрим пример:

 

Листинг 17 Пример работы $cls

 

ORG #5D64

 

;установка цветовых атрибутов без сброса пикселей (A - байт атрибутов)

 

LD A,%00111000

LD C,#73                 ;код рестарта $cls

RST #10

CALL WAIT

 

;установка значений системных переменных PAPER и BORD

 

LD C,#72          ;получение адреса

RST #10              ;вектора экрана

EXX                    ;в HL - адрес

PUSH HL          ;перенос адреса

POP IX             ;в регистр IX

LD A,%00101010

LD (IX+0),A       ;установка цветов экрана

LD A,%00000011

LD (IX+1),A       ;установка цветов бордюра

 

;полная очистка экрана, цвета берутся из системных переменных PAPER и BORD

 

XOR A                ;в A - 0

LD C,#73

RST #10

CALL WAIT

JR EXIT

#74 (116) EMPTY

 

Не используется

 

#75 (117) EMPTY

 

Не используется

 

#76 (118) $y, #77 (119) $n

 

Еще два рестарта отвечают за включение и выключение в текущей позиции экрана мигающего курсора.

Положение курсора определяется уже знакомой нам системной переменной XYPOS, находящейся в векторе символьного устройства вывода.

Рестарт $y(#76) включает курсор в текущей позиции, а рестарт $n(#77) - выключает. Координаты курсора абсолютные.

Процедура изображения мигающего курсора добавляется в цепочку процедур, вызываемых по прерываниям от таймера при помощи рестарта $im2(#1E) из уровня DOS.SYS.

При включении следующего курсора не забывайте убирать предыдущий, хотя никаких серьезных последствий, кроме "засорения" экрана останками курсоров это не вызовет, а рестарт $n(#77) спокойно уберет их все за один прием.

Пример:

 

Листинг 19 Пример работы с курсором

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

 

;печать строк текста из буфера в окне через подфункцию 3 рестарта $prstr

 

LD IX,WIND

LD C,#68

LD E,3

LD HL,TEXT

LD A,%11000010

LD B,1

RST #10

LD C,#68

LD E,3

LD B,2

LD HL,TEXT

LD A,%11000100

RST #10

CALL WAIT

 

;включение и перемещение курсора по экрану

 

LD B,12

LD H,4            ;Y-смещение для wtpos

LD L,5            ;X-смещение для $wtpos

M1           PUSH BC

PUSH HL

LD C,#6B       ;вызов wtpos, уста-

RST #10            ;новка начальных координат курсора

LD C,#76        ;включение курсора

RST #10

CALL WAIT     ;ожидание клавиши

LD C,#77        ;выключение курсора

RST #10

POP HL          ;увеличение смеще-

INC HL            ;ния координат

POP BC

DJNZ M1          ;перейти к началу цикла с новыми координатами

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "Рестарты y(#76)"

DEFMn(#77)"

DEFB #0D

DEFM "включение-выключение"

DEFM "курсора"

DEFB #0D

DEFB #03

 

#78 (120) EMPTY

 

Не используется.

 

#79 (121) EMPTY

 

Не используется.

 

#7A (122) EMPTY

 

Не используется.

 

#7B (123) EMPTY

 

Не используется.

 

#7C (124) $d_a, #7D (125) $a_d

 

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

Рестарт d_a(#7C) - преобразует целое 2-х или 4-х байтовое число в ASCII-строку

Входные параметры:   C - код рестарта (#7C)

DE - число, которое надо преобразовать

HL - адрес выходного буфера

A - длина выходного буфера

B - основание системы счисления (2, 8, 10, 16)

Состояние флага C определяет формат числа:

флаг C=0 - 2-х байтовое число

флаг C=1 - 4-х байтовое число

На выходе образуется требуемое число в символьной форме, причем строка внутри буфера выравнивается по правой границе, а оставшаяся левая часть дополняется пробелами. При переполнении буфера рестарт возвращается в вызывающую программу с установленным флагом C (независимо от его первоначального состояния) и кодом ошибки 1 (переполнение буфера) в регистре A.

При переводе чисел в 16-ричную, 8-ричную и двоичную системы символы этих систем (#, o, % и т. п. ) не применяются и в буфер не вносятся, поэтому за принадлежностью числа к той или иной системе следите самостоятельно.

Рассмотрим пример:

 

Листинг 20 Перевод чисел в символьную форму и распечатка их в окне

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

 

;перевод числа из 2-х байтовой формы в символьную (в DE - число)

 

LD C,#7C            ;код рестарта

LD DE,#9C40      ;исходное число

LD HL,TEXT        ;адрес буфера

LD A,5                ;длина буфера

SCF                      ;сбросим

CCF                      ;флаг C

LD B,10              ;десятичная система счисления

RST #10

 

;печать числа в символьной форме через подфункцию 1 рестарта $prstr

 

LD IX,WIND

LD C,#68

LD E,1

LD HL,TEXT

LD A,%11000010

LD B,5

RST #10

CALL WAIT

 

;перевод числа из 4-х байтовой формы в символьную (в DE - адрес числа)

 

LD C,#7C          ;код рестарта

LD HL,TEXT      ;адрес буфера

LD DE,TABL     ;адрес числа

LD A,8              ;длина буфера

LD B,16            ;16-ричная система счисления

SCF                    ;установим флаг C

RST #10

 

;печать числа в окне

 

LD IX,WIND

LD C,#68

LD E,1

LD HL,TEXT

LD A,%11000100

LD B,8

RST #10

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 38

 

;текстовый буфер

 

TEXT      DEFM "           "

 

;исходное 4-х байтовое число

 

TABL      DEFW #0000     ;младшие 2 байта

DEFW #9C40      ;старшие 2 байта

 

Рестарт $a_d(#7D) предназначен для обратного перевода числа из символьной формы в стандартную четырехбайтовую. Он преобразует ASCII-строку указанной длины, или завершенную кодом #0D, игнорируя ведущие пробелы. Результат располагается в альтернативных регистрах - младшие байты в регистровой паре HL', старшие байты - в регистровой паре DE', при этом в регистровой паре BC' остается адрес продолжения входного буфера.

Входные параметры:   C - код рестарта (#7D)

HL - адрес входного буфера

A - длина входного буфера; если A=0, то преобразуется строка до символа с кодом #0D

B - основание системы счисления по умолчанию. Основание системы счисления не должно быть больше 16, причем 0 трактуется как 10 (десятичная система)

Система счисления может также определяться первым символом ASCII-строки:

# h H   - 16-ричная система

d           - десятичная система

o O     - восьмеричная система

%b      - двоичная система

Выходные параметры:   DE'- старшие байты числа

HL'- младшие байты числа

BC'- адрес следующего символа ASCII буфера

Этот рестарт в комплексе с предыдущим позволяет производить арифметические действия над числами, хранящимися в символьной форме (например внутри текста).

Рассмотрим пример. Пусть необходимо напечатать строку "10000+12=", выполнить указанное в ней арифметическое действие и напечатать результат (см. Листинг 21).

 

Листинг 21 Пример использования $a_d(#7D) арифметические действия над числом в символьной форме

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD A,2

LD C,#61

RST #10

 

;печать строки с исходным числом

 

LD HL,TEXT

LD C,#68

LD E,1

LD B,9              ;длина всей строки

LD A,%11000001

RST #10

CALL WAIT

 

;перевод числа в 4-х байтовую форму

 

LD HL,TEXT        ;адрес входного буфера

LD A,5                ;кол-во символов в исходном числе

LD B,10            ;система счисления

LD C,#7D          ;код рестарта

RST #10

EXX

 

;на выходе в HL - младшие байты, а в DE - старшие

 

LD BC,12          ;сложение чисел

ADD HL,BC

PUSH DE            ;помещение резуль-

PUSH HL          ;тата в буфер

LD HL,TABL

POP DE

LD (HL),E

INC HL

LD (HL),D

INC HL

POP DE

LD (HL),E

INC HL

LD (HL),D

 

;перевод числа в символьную форму результат помещается в текст на место исходного числа

 

LD C,#7C

LD HL,TEXT

LD A,5                 ;кол-во символов числа - результата

LD B,10

LD DE,TABL

SCF

RST #10

 

;печать результата

 

LD C,#68

LD E,1

LD IX,WIND

LD HL,TEXT

LD B,5

LD A,%11000011

RST #10

CALL WAIT

JP EXIT

 

;вектор окна

 

WIND     DEFB 1

DEFB 1

DEFB 5

DEFB 30

DEFB %00000111

DEFB %00000001

DEFB 3

DEFB 35

 

;текстовый буфер

 

TEXT      DEFM "10000+12="

 

;буфер числа

 

TABL      DEFB #00

DEFB #00

DEFB #00

DEFB #00

 

Еще одним практическим примером использования рестартов $a_d и $d_a может служить Листинг 22 - программа перевода чисел из одной системы счисления в другую

 

Листинг 22 Перевод чисел в 16-ричную систему (пример использования $d_a)

 

ORG #5D64

 

;открытие окна

 

CALL CLS

LD IX,WIND

LD C,#61

LD A,2

RST #10

 

;печать пояснительного текста

 

LD C,#66

RST #10

 

;ввод числа с клавиатуры

 

START   LD C,#88             ;рестарт $ed_dig

LD A,17            ;из уровня SHELL

LD DE,#0402       ;будет рассмотрен

LD HL,#0000     ;в следующих

LD IX,WIND         ;выпусках серии

RST #10

JP C,START

JP NZ,EXIT

 

;помещение числа в буфер

 

EXX

EX DE,HL

LD HL,TABL

LD (HL),E

INC HL

LD (HL),D

 

;перевод числа из 4-х байтовой формы в символьную (в DE - адрес числа)

 

LD C,#7C          ;код рестарта

LD HL,TEXT        ;адрес буфера

LD DE,(TABL)   ;адрес числа

LD A,16            ;длина буфера

LD B,16            ;система счисления

SCF

CCF                    сбросим флаг C

RST #10

 

;печать числа в окне

 

LD IX,WIND

LD C,#68

LD E,1

LD HL,TEXT

LD A,%10000100

LD B,16

RST #10

CALL WAIT

CP #10

JP Z,EXIT

JP START

 

;вектор окна

 

WIND  DEFB 1

DEFB 1

DEFB 8

DEFB 30

DEFB %00001111

DEFB %00000001

DEFB 3

DEFB 36

 

;пояснительный текст

 

DEFM "Перевод чисел в 16-ричную"

DEFM "систему"

DEFB #0D

DEFM " Входное значение"

DEFM "   Результат     "

DEFB #0D

DEFB #0D

DEFM "                     "

DEFM "                   0"

DEFB #0D

DEFB #0D

DEFM "   (C) PENCRAFT 1994 "

DEFM "SS+A - Выход"

DEFB #0D

DEFB #03

 

;текстовый буфер

 

TEXT      DEFM "               "

 

;буфер числа

 

TABL      DEFW #0000

 

#7E (126) $analys

 

Рестарт analys(#7E) позволяет организовать в Вашей программе таблицу процедур. Он находит в таблице адрес необходимой процедуры по ее коду и передает ей управление.

Входные параметры:   HL - адрес таблицы процедур

A - код процедуры

Таблица состоит из записей по три байта, из которых первый - код процедуры, а два оставшихся - ее адрес в стандартном формате (первый байт - младший).

Последней записью должна быть процедура обработки ситуации "код не найден", для нее зарезервирован код #FF, после которого и следует поместить ее адрес.

На выходе из рестарта при передаче управления процедуре в регистре HL сохраняется адрес таблицы, в A - код команды, а регистр BC' содержит адрес процедуры, которой передается управление. Остальные регистры (кроме альтернативного набора) не изменяются и могут быть использованы для передачи параметров. Переход к процедуре осуществляется путем помещения ее адреса рестартом analys на стек и подачей команды RET, поэтому передача параметров через стек в данном случае нежелательна во избежание путаницы с адресами.

Все процедуры должны заканчиваться инструкцией RET, которая возвращает управление в точку, следующую за вызовом рестарта analys.

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


 

Листинг 23 Вызов процедур по таблице рестарт $analys(#7E)

 

ORG #5D64

CALL CLS

 

;установка координат курсора

 

LD H,10          ;Y-coord курсора

LD L,20             ;X-coord курсора

LD C,#0C        ;вызов prapd, уста-

RST #10            ;новка начальных координат курсора

 

;основная программа

 

MAIN      LD C,#76           ;включение курсора

RST #10

LD C,#12          ;вызов вектора

RST #10            ;символьного устройства

EXX                 ;вывода, HL - адрес

INC HL            ;координат курсора

EX DE,HL       ;помещаем его в DE

CALL WAIT     ;ожидание клавиши, в A - код клавиши

PUSH AF        ;сохраним его

LD C,#77        ;выключение курсора

RST #10

POP AF          ;восстановим регистр A

LD HL,TABL      ;адрес таблицы процедур

LD C,#7E        ;код рестарта analys

RST #10            ;вызов рестарта

 

;управление передается по адресу из таблицы в соответствии с кодом клавиши по окончании отработки процедуры - возврат по RET на следующую после вызова рестарта команду

 

CP #F4             ;проверка на

RET Z             ;окончание работы

JP MAIN           ;повторить цикл

 

;таблица процедур

 

TABL      DEFB #0B         ;CS+7

DEFW UP

DEFB #0A        ;CS+6

DEFW DOWN

DEFB #08         ;CS+5

DEFW LEFT

DEFB #09         ;CS+8

DEFW RIGHT

DEFB #10         ;SS+A

DEFW END

DEFB #FF        ;остальные клавиши

DEFW NO_KEY

 

;процедуры

 

UP           EX DE,HL       ;увеличение

INC HL              ;координаты Y

DEC (HL)

RET

 

DOWN   EX DE,HL       ;уменьшение

INC HL              ;координаты Y

INC (HL)

RET

 

LEFT      EX DE,HL       ;уменьшение

DEC (HL)        ;координаты X

RET

 

RIGHT    EX DE,HL       ;увеличение

INC (HL)          ;координаты X

RET

 

NO_KEY   RET                ;"ключ не найден"

 

END         XOR A            ;установка парамет-

LD A,#F4          ;ров для выхода в

RET                  ;IS-DOS и флага Z для выхода из цикла MAIN

 

;после отработки процедур инструкция RET осуществляет переход к следующей после вызова рестарта analys команде.

 

#7F (127) $edstr

 

Редактирование строки в тексте. Отрабатывает все печатные коды (символы) + 6 управляющих: клавиши 1,2,3,5,8,0 с Caps Shift'ом.

Вход:     IX - вектор, (на входе необходимо инициировать LNST, XS и COM)

Выход:  CARRY - системная ошибка (см. ПРИЛОЖЕНИЯ 10..13).




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Реклама - реклама и обьявления от и для спектрумистов.
body postbox - нам пишут: хорошо что кто-то что-то ещё под спек делает.
Лоцман - О игре MECHANIC WARS.
IS-DOS Ассемблер - эта рубрика понравится не только тем кто не знает ассемблер или знает его плохо, но и тем кто имеет за плечами уже большой опыт работы в кодах Z-80.
7 Origins - Семерка лучших origin'ов-мудрых и не очень выражений.

В этот день...   29 марта