┌──────────────────────────────┐
│ │
│ РЕТРО │
│ │
└──────────────────────────────┘
Дж.Хардман, Э.Хьюзон.
40 ЛУЧШИХ ПРОЦЕДУР.
(Продолжение. Начало см. ZX РЕВЮ
97/1-2)
РАЗДЕЛ B
4. ВВЕДЕНИЕ
В разделе B представлены прог-
раммы в машинном коде. Для прос-
тоты и удобства использования
они даны в стандартном формате.
Во введении описывается этот
формат и дается программа на
BASIC'е, которая может быть ис-
пользована для загрузки прог-
рамм в память.
Длина: Это длина программы
в байтах.
Количество Выполнение некоторых
переменных: программ может по-
требовать изменения
значения одной или
более переменных,
передаваемых в прог-
рамму через буфер
принтера.
Контрольная Каждая программа да-
сумма: на в виде последова-
тельности целых по-
ложительных чисел,
помещаемых в после-
довательные ячейки
памяти. Контрольная
сумма (т.е. сумма
всех чисел вводимой
подпрограммы) дается
для того, чтобы Вы
были уверены в пра-
вильности загрузки.
Функция: Дается краткое опи-
сание задачи, выпол-
няемой с помощью
программы.
Переменные: Определяется имя,
длина и адрес в бу-
фере принтера каж-
дой переменной. Пе-
ременная длиной в
один байт (целое по-
ложительное число в
пределах от 0 до
255) передается в
программу из BASIC'а
или с клавиатуры че-
рез POKE.
┌──────────────────────────────┐
│ POKE ячейка, значение │
│ Двухбайтовая переменная │
│ передается с помощью 2-х │
│ команд: │
│ POKE ячейка, значение-256* │
│ INT(значение/256): │
│ POKE ячейка+1, │
│ INT(значение/256) │
│ Используемые ячейки являются │
│ ячейками памяти буфера │
│ принтера. │
└──────────────────────────────┘
Вызов Программы вызыва-
подпрограммы: ются с использова-
нием функции USR,
которая должна
быть включена в
команду. Если про-
грамма в машин-
ном коде не пере-
дает какое-то зна-
чение обратно в
BASIC по заверше-
нии, то использу-
ется команда:
RANDOMIZE USR адрес
┌──────────────────────────────┐
│ Если Вам надо, чтобы │
│ результат был возвращен в ре-│
│ гистровой паре BC, то вызов │
│ делается так: │
│ LET A = USR адрес │
│ или │
│ PRINT USR адрес │
│ в зависимости от того, │
│ должны ли возвращаемые данные│
│ сохраняться в переменной │
│ BASIC'а или выводиться │
│ на экран. │
└──────────────────────────────┘
Контроль Объясняются провер-
ошибок: ки, выполняемые про-
граммой для нелогич-
ных или противоречи-
вых значений пере-
менных, параметров и
т.п.
Комментарии: Объясняются возмож-
ные варианты в прог-
раммах.
Листинг в Программы представ-
машинном лены на языке ассем-
коде: блера. Для загрузки
в память использует-
ся третья колонка -
"Числа для ввода".
Все числа здесь даны
в десятичной систе-
ме.
Как она Объяснение принципа
работает: работы программы.
ЗАГРУЗЧИК МАШИННОГО КОДА
Почти все программы из этой
книги перемещаемые, т.е. они бу-
дут работать корректно независи-
мо от того, в каком месте RAM мы
их поместим. Если программа не
перемещаемая, то в комментариях
объясняется, как она должна быть
изменена, если ее нужно сохра-
нить в другой области памяти. В
разделе A (часть 2) мы видели,
что ZX-SPECTRUM использует раз-
личные части RAM для различных
фукнций и что область между
ячейками, указанными системными
переменными RAMTOP и UDG, пред-
назначена для хранения подпрог-
рамм в машинном коде.
Программа BP может быть ис-
пользована для загрузки, измене-
ния и перемещения программы в
машинном коде. С ее помощью
пользователь может переустано-
вить указатель RAMTOP, что даст
больше свободного пространства
для машинных кодов; ввести прог-
рамму с клавиатуры; перейти впе-
ред или назад для корректировки
ошибки; вставить или удалить
часть программы.
Программа BP. Загрузчик
машинного кода (MC LOADER)
100 GO SUB 8100
200 REM ***** Вычисление доступной памяти
210 LET min = 1+PEEK 23730+256*PEEK 23731
220 LET p = PEEK 23732+256*PEEK 23733
230 LET t = p - min + 1
400 REM ***** Определение стартового адреса
410 PRINT "Lowest possible start = ";min..."Maximum space
avalible = ";t
420 INPUT "Do you wish to change the lowest start address
(Y or N) ?";z$
430 IF z$="Y" OR z$="y" THEN GO TO 7000
440 INPUT "Enter address at which to start loading machine
code";a
450 IF a<min OR a>p THEN BEEP .2,24: GO TO 440
500 GO SUB 8100
510 LET t=t-a+min
520 PRINT "You can use up to ";t" bytes"...
530 LET u=PEEK 23675+256*PEEK 23676
540 IF a<u AND u<p THEN PRINT "If you use more than ";u-a;
"bytes, you will overwrite the user defined graphics
area."
550 IF a>=U THEN PRINT "You will overwrite the user defined
graphics area."
560 INPUT "Is that OK (Y or N) ? ";z$
570 IF z$="N" OR z$="n" THEN GO TO 7000
580 IF z$<>"Y" AND z$<>"y" THEN BEEP .2,24: GO TO 560
700 REM *** GO AHEAD AND LOAD
710 LET l=a
750 GOSUB 8200
760 INPUT "Enter number, b, f, i, d or t ";z$
770 IF z$="" THEN BEEP .2,24: GO TO 760
780 LET a$=CHR$ (CODE z$(1) - 32*(z$(1)>"@"))
790 GO TO 800+200*(a$="B")+300*(a$="F")+400*(a$="I")+500*(a$=
"D")+600*(a$="T")
800 LET x=VAL z$
810 IF l>p THEN BEEP .2,24: GO TO 750
820 IF x<0 OR x>256 OR x<>INT x THEN BEEP .2,24: GO TO 760
830 POKE l,x
840 LET l=l+1
850 GO TO 740
1000 REM *** Перемещение вперед
1010 LET l=l-1
1020 IF LEN z$>1 THEN LET l=l+1-VAL z$(2 TO)
1030 IF l<a THEN LET l=a
1040 GO TO 740
1100 REM *** Перемещение назад
1110 LET l=l+1
1120 IF LEN z$>1 THEN LET l=l-1+VAL z$(2 TO)
1130 IF l>p THEN LET l=p
1140 GO TO 740
1200 REM *** Вставка
1210 IF LEN z$=1 THEN LET n=1: GO TO 1225
1220 LET n=VAL z$(2 TO): IF n<1 OR n>p-1 OR n<> INT n THEN
BEEP .2,24: GO TO 740
1225 CLS: GOSUB 8100: PRINT TAB 6;"Inserting in progress"
1230 FOR j=p TO l+n STEP -1
1240 POKE j, PEEK (j-n)
1250 NEXT j
1260 FOR j=l TO l+n-1
1270 POKE j,0
1280 NEXT j
1290 GO TO 740
1300 REM *** Удаление
1310 IF LEN z$=1 THEN LET n=1: GO TO 1330
1320 LET n=VAL z$(2 TO): IF n<1 OR n>p-l OR n<> INT n THEN
BEEP .2,24: GO TO 740
1330 IF n<0 OR n>p-l THEN BEEP .2,24: GO TO 1320
1340 CLS : GOSUB 8100 : PRINT TAB 6;"DELETING IN PROGRESS"
1350 FOR j=l TO p-n
1360 POKE j, PEEK (j+n)
1370 NEXT j
1380 GO TO 740
1400 STOP
1401 PRINT AT 21,7;"PROGRAM TERMINATED"
1410 STOP
7000 REM *** Изменение RAMTOP
7010 INPUT "ENTER NEW START ADDRESS ";a
7020 IF a<27000 OR a>p THEN BEEP .2,24: GO TO 710
7030 CLEAR a-1
7040 RUN
7999 STOP
8100 CLS
8110 PRINT TAB 6;"MACHINE CODE LOADER"...
8120 RETURN
8200 REM *** Вывод содержимого памяти
8210 GOSUB 8100
8220 PRINT "ADDRESS DECIMAL CHECK SUM"
8230 LET c=0
8240 LET s=l-8 : IF s<a THEN LET s=a : GO TO 8280
8250 FOR j=a TO s-1
8260 LET c=c+PEEK j
8270 NEXT j
8280 LET f=s+17 : IF f>p THEN LET f=p
8290 FOR j=s TO f
8300 LET c=c+PEEK j
8310 PRINT AT j-s+3,1;j; TAB 12;PEEK j; TAB 22;c
8320 NEXT j
8400 LET pos=1-s+3
8410 PRINT AT pos,12; FLASH 1; PEEK l
8420 RETURN
Когда программа BP запускает-
ся, она печатает младший адрес,
с которого программа в машинных
кодах может быть введена и сох-
ранена, т.е. на единицу больший,
чем RAMTOP.
В машине с 48К памяти младший
адрес 65368, если пользователь
на обновлял системную перемен-
ную RAMTOP.
В конце ОЗУ обычно резерви-
руются 168 байтов для UDG, но
программа позволяет пользовате-
лю использовать и эту область,
если он пожелает. Он может так-
же выбрать новый возможный млад-
ший адрес, который программа за-
тем помещает в системную пере-
менную RAMTOP, используя коман-
ду CLEAR. Данные не могут быть
введены по адресу, меньшему, чем
27000, т.к. иначе нарушаются
границы области, требующейся для
самой программы BP. Программа BP
запрашивает адрес, с которого
должна стартовать программа в
машинных кодах. Таким образом,
пользователь может резервировать
область для нескольких процедур
и затем загружать их каждую от-
дельно.
Рисунок BP1 показывает формат
дисплея после того, как с ячей-
ки 32000 была загружена програм-
ма "Screen Invert". Первая ко-
лонка - адрес, вторая - содержи-
мое ячейки памяти с этим адре-
сом, третья - контрольная сумма.
Программа "Screen Invert" имеет
18 байтов в длину и ее кон-
трольная сумма 1613. Следова-
тельно, она занимает ячейки с
32000 до 32017 и контрольная
сумма дана для ячейки 32017,
т.е. сумма содержимого ячеек
(32000...32017) равна 1613.
┌──────────────────────────────┐
│ MACHINE CODE LOADER │
├──────────────────────────────┤
│ ADDRESS DECIMAL CHECK SUM │
│ 32000 33 33 │
│ 32001 0 33 │
│ 32002 64 97 │
│ 32003 1 98 │
│ 32004 0 98 │
│ 32005 24 122 │
..... ... ...
│ 32012 11 836 │
│ 32013 120 956 │
│ 32014 177 1133 │
│ 32015 32 1165 │
│ 32016 247 1412 │
│ 32017 201 1613 │
│ │
│ Рис. BP1. Представлен экран │
│ во время работы загрузчика │
│ машинного кода. Программа │
│ "Screen Invert" загружена с │
│ адреса 32000. │
└──────────────────────────────┘
На основном экране внимание
пользователя привлекается к од-
ной ячейке - содержимое этой
ячейки мерцает. Эта ячейка яв-
ляется текущей и первоначально
это выбранный стартовый адрес
программы. Пользователь вводит
целое число между 0 и 255 вклю-
чительно, которое программа MC
LOADER помещает в текущую ячей-
ку. Затем следующий адрес стано-
вится текущей ячейкой. Пользова-
тель может не вводить число, а
вместо этого выбрать для коррек-
тировки вариант, описанный в
таблице BT1.
┌──────────┬───────────────────┐
│ Код │ Вариант │
├──────────┼───────────────────┤
│B │Перейти на один │
│ │адрес назад │
│B n(число)│Перейти на n │
│ │адресов назад │
│F │Перейти на один │
│ │адрес вперед │
│F n(число)│Перейти на n │
│ │адресов вперед │
│I n(число)│Вставить n байтов, │
│ │каждый из которых │
│ │содержит 0 │
│D n(число)│Удалить n байтов в │
│ │текущей области │
│T │Закончить программу│
├──────────┴───────────────────┤
│ Таблица BT1. │
│ Возможные варианты │
│редактирования машинного кода.│
└──────────────────────────────┘
5. ПОДПРОГРАММЫ СДВИГА.
5.1. Сдвиг атрибутов влево.
Длина: 23
Количество переменных: 1
Контрольная сумма: 1574
Назначение: Эта программа
сдвигает атрибуты всех символов
экрана влево на одно знакоместо.
Переменные:
Имя: new attr
Длина: 1
Ячейка: 23296
Комментарий: это атрибут, вво-
димый в крайнюю правую колонку.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: Эта программа по-
лезна для выделения области тек-
ста или графики. Для прокручива-
ния только 22 верхних строк 24*
должно быть изменено на 22.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22528 33 0 88
LD A,(23296) 58 0 91
LD C,24 14 24*
NEXT_L LD B,31 6 31
NEXT_C INC HL 35
LD E,(HL) 94
DEC HL 43
LD (HL),E 115
INC HL 35
DJNZ NEXT_C 16 249
LD (HL),A 119
INC HL 35
DEC C 13
JR NZ,NEXT_L 32 242
2
Как она работает:
В пару регистров HL загружает-
ся адрес области атрибутов. Ак-
кумулятор загружается значением
атрибута, вводимым в правую ко-
лонку. В регистр C загружается
количество строк для сдвига - он
теперь может быть использован
как счетчик строк. В регистр B
заносится число на 1 меньшее,
чем число символов в строке,
чтобы он использовался как счет-
чик. HL увеличивается, чтобы
указать на следующий атрибут,
который загружается в E-регистр.
HL уменьшается, и по адресу HL
помещается значение из E-регис-
тра. HL увеличивается вновь,
чтобы указать на следующий атри-
бут. Регистр B уменьшается, и
если он не равен 0, то происхо-
дит переход к NEXT_C. HL теперь
указывает на правую колонку, и
по адресу HL помещается значение
из аккумулятора. HL увеличивает-
ся, чтобы указать на следующую
строку - NEXT_L. Счетчик строк
(регистр C) уменьшается. Если
значение результата не равно 0,
подпрограмма возвращается назад
к NEXT_L.
По окончании работы программа
возвращается в BASIC.
5.2. Сдвиг атрибутов вправо.
Длина: 23
Количество переменных: 1
Контрольная сумма: 1847
Назначение: Эта программа
сдвигает атрибуты всех символов
экрана вправо на одно знакоместо.
Переменные:
Имя: new attr
Длина: 1
Ячейка: 23296
Комментарий: это атрибут, вво-
димый в крайнюю левую колонку.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: Эта программа по-
лезна для выделения области тек-
ста или графики. Для прокручива-
ния только 22 верхних строк 24*
должно быть изменено на 22.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,23295 33 255 88
LD A,(23296) 58 0 91
LD C,24 14 24*
NEXT_L LD B,31 6 31
NEXT_C DEC HL 43
LD E,(HL) 94
INC HL 35
LD (HL),E 115
DEC HL 43
DJNZ NEXT_C 16 249
LD (HL),A 119
DEC HL 43
DEC C 13
JR NZ,NEXT_L 32 242
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес последнего байта облас-
ти атрибутов. Аккумулятор загру-
жается значением атрибута для
ввода в левую кололнку. В ре-
гистр C загружается количество
строк для сдвига - он использу-
ется как счетчик строк. В ре-
гистр B заносится число на 1
меньшее, чем число символов в
строке, для использования его в
качестве счетчика.
HL увеличивается, чтобы ука-
зать следующий атрибут. Значе-
ние этого атрибута загружается в
E-регистр. HL увеличивается, и
по адресу HL помещается значение
из E-регистра. HL уменьшается
снова для указания адреса следу-
ющего атрибута. Счетчик в регис-
тре B уменьшается, и если он не
равен 0, то - возврат назад к
NEXT_C. HL теперь указывает на
крайнюю левую колонку, и в ячей-
ку с адресом HL помещается зна-
чение из аккумулятора. HL
уменьшается для указания право-
го конца следующей строки. Счет-
чик строк уменьшается, и если он
не равен 0 - возврат назад к
NEXT_L.
Программа возвращается в BASIC.
5.3. Сдвиг атрибутов вверх.
Длина: 21
Количество переменных: 1
Контрольная сумма: 1591
Назначение: Эта программа
сдвигает атрибуты всех символов
экрана вверх на одно знакоместо.
Переменные:
Имя: new attr
Длина: 1
Ячейка: 23296
Комментарий: Это атрибут, вво-
димый в нижнюю строку.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: Эта программа по-
лезна для выделения области тек-
ста или графики. Для прокручива-
ния только 22 верхних строк 224*
должно быть изменено на 160.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22560 33 32 88
LD DE,22528 17 0 88
LD BC,736 1 224* 2
LDIR 237 176
LD A,(23296) 58 0 91
LD B,32 6 32
NEXT_C LD (DE),A 18
INC DE 19
DJNZ NEXT_C 16 252
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес второй строки атрибу-
тов, в DE загружается адрес пер-
вой строки и BC загружается чис-
лом байтов для перемещения.
Количество байтов, определен-
ное в регистровой паре BC, копи-
руется в ячейки памяти с адре-
сом, находящимся в DE из ячеек,
начинающихся с адреса в HL, ис-
пользуя инструкцию LDIR. Эти ре-
зультаты в DE указывают на ниж-
нюю строку атрибутов. Аккумуля-
тор загружается кодом атрибута
для ввода в нижнюю строку. B-ре-
гистр загружается числом симво-
лов на одной строке - он ис-
пользуется как счетчик.
По адресу DE помещается значе-
ние из аккумулятора, а затем DE
увеличивается для указания на
следующий байт. Счетчик уменьша-
ется, и если он не равен 0, под-
программа возвращается в NEXT_C.
Затем программа возвращается в
BASIC.
5.4. Сдвиг атрибутов вниз.
Длина: 21
Количество переменных: 1
Контрольная сумма: 2057
Назначение: Эта программа
сдвигает атрибуты всех символов
экрана вниз на одно знакоместо.
Переменные:
Имя: new attr
Длина: 1
Ячейка: 23296
Комментарий: Это атрибут, вво-
димый в верхнюю строку.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: Эта программа по-
лезна для выделения области тек-
ста или графики. Для прокручива-
ния только 22 верхних строк дол-
жны быть изменены: 223* на 159,
255* на 191, 224* на 160.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,23263 33 223* 90
LD DE,23295 17 255* 90
LD BC,736 1 224* 2
LDDR 237 184
LD A,(23296) 58 0 91
LD B,32 6 32
NEXT_C LD (DE),A 18
DEC DE 27
DJNZ NEXT_C 16 252
RET 201
2
Как она работает:
В HL загружается адрес послед-
него атрибута 23-й строки. В DE
загружается адрес последнего ат-
рибута 24-й строки. В BC загру-
жается число байтов для переме-
щения. Затем команда LDDR пере-
мещает байты (их количество ука-
зано в регистровой паре BC) из
адреса в HL по адресу в DE. Эти
результаты в DE хранят адрес
последнего атрибута первой стро-
ки.
В аккумулятор загружается зна-
чение атрибута для ввода в вер-
хнюю строку. В B-регистр загру-
жается число байтов в верхней
строке - он используется как
счетчик. В ячейку с адресом DE
помещается значение из аккумуля-
тора, и DE уменьшается для ука-
зания на следующий байт. Счет-
чик уменьшается, и если он не
равен 0, подпрограмма возвраща-
ется к NEXT_C.
Программа затем возвращается в
BASIC.
5.5 Сдвиг влево на один символ.
Длина: 21
Количество переменных: 0
Контрольная сумма: 1745
Назначение: Эта программа про-
кручивает графику экрана на один
символ влево.
Вызов подпрограммы:
RANDOMIZE USR адрес
Контроль ошибок: Нет.
Комментарий: Эта программа по-
лезна при организации экрана в
качестве "окна", показывающего в
данный момент меньшую часть
большой дисплейной области. Это
"окно" перемещается, используя
подпрограммы сдвига.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,16384 33 0 64
LD D,L 85
LD A,192 62 192
NEXT_L LD B,31 6 31
NEXT_B INC HL 35
LD E,(HL) 94
DEC HL 43
LD (HL),E 115
INC HL 35
DJNZ NEXT_B 16 249
LD (HL),D 114
INC HL 35
DEC A 61
JR NZ,NEXT_L 32 242
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес дисплейного файла, а
D-регистр устанавливается в 0. В
аккумулятор загружается число
строк на экране. В B-регистр
загружается значение на 1
меньшее, чем число символов в
строке - оно является числом
байтов для копирования.
HL увеличивается для указания
на следующий адрес, и содержимое
из этой ячейки загружается в
E-регистр. HL уменьшается, и в
ячейку с адресом HL загружается
значение из E-регистра. HL уве-
личивается для адресации следую-
щего байта, и счетчик в B-регис-
тре уменьшается. Если он не ра-
вен 0, подпрограмма возвращает-
ся к NEXT_B.
Если регистр B равен 0, это
означает, что последний байт
строки скопирован и HL указы-
вает на правый крайний байт. По
этому адресу в регистровой паре
HL помещается 0, и HL увеличи-
вается, указывая на следующую
строку. Счетчик строк - аккуму-
лятор - уменьшается, и если он
не равен нулю, происходит пере-
ход к NEXT_L.
Программа возвращается в BASIC.
5.6.Сдвиг вправо на один символ.
Длина: 22
Количество переменных: 0
Контрольная сумма: 1976
Назначение: Эта программа
прокручивает содержимое дисплей-
ного файла на один символ впра-
во.
Вызов подпрограммы:
RANDOMIZE USR адрес
Контроль ошибок: Нет.
Комментарий: Эта программа по-
лезна при организации экрана в
качестве "окна", показывающего в
данный момент меньшую часть
большой дисплейной области. Это
"окно" перемещается, используя
подпрограммы сдвига.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22527 33 255 87
LD D,0 22 0
LD A,192 62 192
NEXT_L LD B,31 6 31
NEXT_B DEC HL 43
LD E,(HL) 94
INC HL 35
LD (HL),E 115
DEC HL 43
DJNZ NEXT_B 16 249
LD (HL),D 114
DEC HL 35
DEC A 61
JR NZ,NEXT_L 32 242
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес последнего байта дис-
плейного файла, а D-регистр ус-
танавливается в 0. В аккумуля-
тор загружается число строк на
экране. В B-регистр загружается
значение на 1 меньшее, чем чис-
ло символов в строке - он ис-
пользуется как счетчик.
HL уменьшается, указывая на
следующий байт, и его значение
загружается в E-регистр. HL за-
тем увеличивается, и в ячейку с
адресом HL загружается значение
E-регистра. HL уменьшается, ука-
зывая на следующий байт, и счет-
чик (B-регистр) уменьшается.
Если он не равен 0, подпрограм-
ма возвращается в NEXT_B.
Если регистр B равен 0, это
означает, что HL указывает на
крайний левый байт строки. За-
тем по адресу в регистровой паре
HL помещается 0, и HL уменьшает-
ся, указывая на следующую стро-
ку. Счетчик строк (аккумулятор)
уменьшается и, если он не равен
0, происходит переход к NEXT_L.
Программа возвращается в BASIC.
5.7. Сдвиг вверх на один символ.
Длина: 68
Количество переменных: 0
Контрольная сумма: 6328
Назначение: Программа сдвигает
содержимое дисплейного файла
вверх на восемь пикселей.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: нет.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,16384 33 0 64
LD DE,16416 17 32 64
SAVE PUSH HL 229
PUSH DE 213
LD C,23 14 23
NEXT_L LD B,32 6 32
COPY_B LD A,(DE) 26
LD (HL),A 119
LD A,C 121
AND 7 230 7
CP 1 254 1
JR NZ,NEXT_B 32 2
SUB A 151
LD (DE),A 18
NEXT_B INC HL 35
INC DE 19
DJNZ COPY_B 16 241
DEC C 13
JR Z,REST 40 19
LD A,C 121
AND 7 230 7
CP 0 254 0
JR Z,N_BLOCK 40 22
CP 7 254 7
JR NZ,NEXT_L 32 225
PUSH DE 213
LD DE,1792 17 0 7
ADD HL,DE 25
POP DE 209
JR NEXT_L 24 217
REST POP DE 209
POP HL 225
INC D 20
INC H 36
LD A,H 124
CP 72 254 72
JR NZ,SAVE 32 204
RET 201
N_BLOCK PUSH HL 229
LD HL,1792 33 0
ADD HL,DE 25
EX DE,HL 235
POP HL 225
JR NEXT_L 24 198
2
Как она работает:
В пару регистров HL загружает-
ся адрес начала дисплейного фай-
ла, а в DE загружается адрес
байта через восемь линий вниз.
HL и DE сохраняются в стеке. В
C-регистр загружается число на 1
меньшее, чем число строк на эк-
ране. В B-регистр загружается
количество байтов на одной ли-
нии дисплея - он используется
как счетчик.
В аккумулятор загружается
байт, адресованный DE, и это
значение загружается в ячейку по
адресу HL. В аккумулятор загру-
жается содержимое C-регистра и,
если оно равно 1, 9 или 17, то в
ячейку по адресу DE помещается
0. HL и DE увеличиваются, указы-
вая на следующий байт. Счетчик в
B-регистре уменьшается, и если
он не равен 0, происходит пере-
ход к 'COPY_B'.
Счетчик строк в регистре C за-
тем уменьшается. Если он равен
0, происходит переход к
'RESTORE'. Если C содержит 8 или
16, то происходит переход к
'N_BLOCK'. Если C не содержит 7
или 15, подпрограмма переходит к
'NEXT_L'. Затем 1792 прибавляет-
ся к HL - теперь HL указывает на
следующий блок экрана. Подпрог-
рамма переходит к 'NEXT_L'.
В процедуре 'REST' DE и HL бе-
рутся из стека и 256 прибавляет-
ся к каждому их них. Т.о., DE и
HL указывают на строку, позиция
которой ниже, чем та, что была в
предыдущем цикле. Если HL содер-
жит значение 18432, подпрограм-
ма возвращается в BASIC, иначе
происходит переход к процедуре
'SAVE'. В процедуре 'N_BLOCK'
1972 прибавляется к DE - таким
образом DE указывает на следую-
щий блок экрана. Подпрограмма
затем возвращается к 'NEXT_L'.
По окончании работы происходит
возврат в BASIC.
5.8. Сдвиг вниз на один символ.
Длина: 73
Количество переменных: 0
Контрольная сумма: 7987
Назначение: эта программа
сдвигает содержимое дисплейного
файла вниз на восемь пикселей.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: нет.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22527 33 255 87
LD DE,22495 17 223 87
SAVE PUSH HL 229
PUSH DE 213
LD C,23 14 23
NEXT_L LD B,32 6 32
CORY_B LD A,(DE) 26
LD (HL),A 119
LD A,C 121
AND 7 230 7
CP 1 254 1
JR NZ,NEXT_B 32 2
SUB A 151
LD (DE),A 18
NEXT_B DEC HL 43
DEC DE 27
DJNZ COPY_B 16 241
DEC C 13
JR Z,REST 40 21
LD A,C 121
AND 7 230 7
CP 0 254 0
JR Z,N_BLOCK 40 24
CP 7 254 7
JR NZ,NEXT_L 32 225
PUSH DE 213
LD DE,1792 17 0 7
AND A 167
SBC HL,DE 237 82
POP DE 209
JR NEXT_L 24 215
REST POP DE 209
POP HL 225
DEC D 21
DEC H 37
LD A,H 124
CP 79 254 79
RET Z 200
JR SAVE 24 201
N_BLOCK PUSH HL 229
LD HL,1792 33 0 7
EX DE,HL 235
AND A 167
SBC HL,DE 237 82
EX DE,HL 235
POP HL 225
JR NEXT_L 24 193
2
Как она работает:
В пару регистров HL загружает-
ся адрес последнего байта дис-
плейного файла, а в DE загру-
жается адрес байта, соответ-
ствующего изображению, отстояще-
му на восемь линий вверх. HL и
DE сохраняются на стеке. В C-ре-
гистр загружается число на 1
меньшее, чем число строк на эк-
ране. Затем в B-регистр загру-
жается количество байтов на од-
ной линии дисплея - он ис-
пользуется как счетчик.
В аккумулятор загружается байт
с адресом DE, и это значение пе-
ресылается в ячейку по адресу HL.
В аккумулятор загружается (для
проверки) содержимое регистра C
и, если оно равно 1, 9 или 17,
то в ячейку по адресу DE поме-
щается 0. HL и DE уменьшается на
единицу, указывая на следующий
байт дисплея. Счетчик байтов в
регистре B уменьшается и, если
он не равен 0, происходит пере-
ход к 'COPY_B'.
Далее уменьшается счетчик
строк в регистре C. Если он ра-
вен 0, происходит переход к про-
цедуре 'REST'. Если C содержит 8
или 16, то происходит переход к
процедуре 'N_BLOCK'. Если C не
содержит 7 или 15, подпрограмма
переходит к 'NEXT_L'. Затем из
HL вычитается 1792 - теперь HL
указывает на следующую треть эк-
рана и подпрограмма переходит к
'NEXT_L'.
В процедуре 'REST' значения DE
и HL берутся из стека, и из них
вычитается число 256. В итоге DE
и HL указывают на строку, пози-
ция которой выше, чем та, что
была в предыдущем цикле. Если HL
содержит значение 20479, под-
программа возвращается в BASIC,
иначе происходит переход к про-
цедуре 'SAVE'.
В процедуре 'N_BLOCK' 1972 вы-
читается из DE, т.е. после этого
DE указывает на следующий блок
экрана. Подпрограмма затем пере-
ходит к 'NEXT_L'.
5.9. Сдвиг влево на один пиксел.
Длина: 17
Количество переменных: 0
Контрольная сумма: 1828
Назначение: сдвиг содержимого
дисплейного файла на один пиксел
влево.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: эта программа
осуществляет более плавное пере-
мещение, чем сдвиг влево на один
символ, но требуется вызывать ее
восемь раз, чтобы переместить
дисплей на один полный символ.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22527 33 255 87
LD C,192 14 192
NEXT_L LD B,32 6 32
OR A 183
NEXT_B RL (HL) 203 22
DEC HL 43
DJNZ NEXT_B 16 251
DEC C 13
JR NZ,NEXT_L 32 245
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес последнего байта дис-
плейного файла, а в регистр C
загружается количество линий в
дисплейном файле (он использует-
ся как счетчик линий). В ре-
гистр B загружается количество
байтов на одной линии (он ис-
пользуется как счетчик байтов).
Флаг переноса устанавливается в
0.
Байт, адресованный HL, сдви-
гается на один бит влево, бит
переноса копируется в крайний
правый бит, а крайний левый бит
копируется во флаг переноса. Па-
ра регистров HL уменьшается для
указания на следующий байт и
счетчик (B-регистр) уменьшается.
Если он не равен 0, подпрограм-
ма осуществляет переход к
NEXT_B, иначе уменьшается коли-
чество обрабатываемых линий и,
если оно не равно 0, подпрограм-
ма возвращается к процедуре
NEXT_L.
По окончании работы программа
возвращается в BASIC.
5.10. Сдвиг вправо на один пик-
сел.
Длина: 17
Количество переменных: 0
Контрольная сумма: 1550
Назначение: сдвиг содержимого
дисплейного файла на один пиксел
вправо.
Вызов подпрограммы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: эта программа
осуществляет более плавное пере-
мещение, чем сдвиг вправо на
один символ, но требуется восемь
раз вызывать эту программу, что-
бы переместить дисплей на один
полный символ.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,16384 33 0 64
LD C,192 14 192
NEXT_L LD B,32 6 32
OR A 183
NEXT_B RR (HL) 203 30
INC HL 35
DJNZ NEXT_B 16 251
DEC C 13
JR NZ,NEXT_L 32 245
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес дисплейного файла, а в
C-регистр загружается количес-
тво линий на экране (он ис-
пользуется как счетчик линий). В
регистр B загружается количес-
тво байтов на одной линии (он
используется как счетчик
байтов). Флаг переноса устанав-
ливается в 0. Байт по адресу HL
сдвигается на один бит вправо,
бит переноса копируется в край-
ний левый бит, а крайний правый
бит копируется во флаг переноса.
Пара регистров HL увеличивается,
указывая на следующий байт и
счетчик (B-регистр) уменьшается.
Если он не равен 0, подпрограм-
ма осуществляет переход к
NEXT_B, иначе уменьшается коли-
чество обрабатываемых линий и,
если оно не равно 0, подпрограм-
ма возвращается к NEXT_L.
Закончив работу, процедура
возвращается в BASIC.
5.11.Сдвиг вверх на один пиксел.
Длина: 91
Количество переменных: 0
Контрольная сумма: 9228
Назначение: сдвиг содержимого
дисплейного файла вверх на один
пиксел.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: нет.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,16384 33 0 64
LD DE,16640 17 0 65
LD C,192 14 192
NEXT_L LD B,32 6 32
CORY_B LD A,(DE) 26
LD (HL),A 119
LD A,C 121
CP 2 254 2
JR NZ,NEXT_B 32 2
SUB A 151
LD (DE),A 18
NEXT_B INC DE 19
INC HL 35
DJNZ COPY_B 16 243
PUSH DE 213
LD DE,224 17 224 0
ADD HL,DE 25
EX (SP),HL 227
ADD HL,DE 25
EX DE,HL 235
POP HL 225
DEC C 13
LD A,C 121
AND 7 230 7
CP 0 254 0
JR NZ,SUBTR 32 10
PUSH DE 213
LD DE,2016 17 224 7
AND A 167
SBC HL,DE 237 82
POP DE 209
JR N_BLOCK 24 14
SUBTR CP 1 254 1
JR NZ,N_BLOCK 32 10
PUSH HL 229
EX DE,HL 235
LD DE,2016 17 224 7
AND A 167
SBC HL,DE 237 82
EX DE,HL 235
POP HL 225
N_BLOCK LD A,C 121
AND 63 230 63
CP 0 254 0
JR NZ,ADD 32 6
LD A,7 62 7
ADD A,H 132
LD H,A 103
JR NEXT_L 24 187
ADD CP 1 254 1
JR NZ,NEXT_L 32 183
LD A,7 62 7
ADD A,7 130
LD D,A 87
LD A,C 121
CP 1 254 1
JR NZ,NEXT_L 32 174
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес дисплейного файла, а в
DE адрес первого байта второй
строки дисплея. В регистр C заг-
ружается число линий на экране.
В регистр B загружается количес-
тво байтов на одной строке - он
используется как счетчик.
В аккумулятор загружается байт
с адресом в DE, и это значение
передается в ячейку по адресу
HL. В аккумулятор заносится со-
держимое регистра C. Если оно
равно 2, то DE указывает на ниж-
нюю строку экрана и по этому ад-
ресу записывается 0. HL и DE
увеличиваются, чтобы указать на
следующий байт. Счетчик в регис-
тре B уменьшается и, если он не
равен 0, происходит переход к
COPY_B.
224 добавляется к регистровым
парам HL и DE, чтобы они указы-
вали на следующую строку экрана.
Затем уменьшается регистр C,
счетчик линий. Если содержимое
регистра C не кратно 8, происхо-
дит переход к SUBTR, иначе 2016
вычитается из HL и происходит
переход к N_BLOCK. Теперь HL
указывает на следующие 8 линий.
В процедуре SUBTR, если значе-
ние (C-1) не кратно 8, происхо-
дит переход к N_BLOCK, иначе
2016 вычитается из DE, т.е. те-
перь DE указывает на следующие 8
линий. В процедуре N_BLOCK, ес-
ли значение C-регистра кратно
64, 1792 добавляется к HL и де-
лается переход к NEXT_LINE - те-
перь HL указывает на следующий
блок из 64 линий. В процедуре
ADD, если значение (C-1) не
кратно 64, 1792 добавляется к
DE, чтобы пара DE указывала на
следующий блок 64 линий. Если
C-регистр не содержит 1, то
программа возвращается к N_LINE,
иначе возврат в BASIC.
5.12. Сдвиг вниз на один пиксел.
Длина: 90
Количество переменных: 0
Контрольная сумма: 9862
Назначение: сдвиг содержимого
дисплейного файла вниз на один
пиксел.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: нет.
Комментарий: нет.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА
147.
LD HL,22527 33 255 87
LD DE,22271 17 255 86
LD C,192 14 192
NEXT_L LD B,32 6 32
CORY_B LD A,(DE) 26
LD (HL),A 119
LD A,C 121
CP 2 254 2
JR NZ,NEXT_B 32 2
SUB A 151
LD (DE),A 18
NEXT_B DEC DE 27
DEC HL 43
DJNZ COPY_B 16 243
PUSH DE 213
LD DE,224 17 224 0
ADD A 167
SBC HL,DE 237 82
EX (SP),HL 227
AND A 167
SBC HL,DE 237 82
EX DE,HL 235
POP HL 225
DEC C 13
LD A,C 121
AND 7 230 7
CP 0 254 0
JR NZ,ADD 32 8
PUSH DE 213
LD DE,2016 17 224 7
ADD HL,DE 25
POP DE 209
JR N_BLOCK 24 11
ADD CP 1 254 1
JR NZ,N_BLOCK 32 7
PUSH HL 229
LD HL,2016 33 224 7
ADD HL,DE 25
EX DE,HL 235
POP HL 225
N_BLOCK LD A,C 121
AND 63 230 63
CP 0 254 0
JR NZ,SUBTR 32 6
LD A,H 124
SUB 7 214 7
LD H,A 103
JR NEXT_L 24 188
SUBTR CP 1 254 1
JR NZ,NEXT_L 32 184
LD A,D 122
SUB 7 214 7
LD D,A 87
LD A,C 121
CP 1 254 1
JR NZ,NEXT_L 32 175
RET 201
2
Как она работает:
В пару регистров HL загружает-
ся адрес последнего байта дис-
плейного файла, а в пару регис-
тров DE загружается адрес байта
линии, которая находится непос-
редственно над этим байтом. В
регистр C загружается число ли-
ний экрана. В регистр B загру-
жается количество байтов на од-
ной строке дисплея - он ис-
пользуется как счетчик.
В аккумулятор загружается байт
из ячейки с адресом в DE, и это
значение загружается в ячейку по
адресу HL. В аккумулятор загру-
жается содержимое регистра C.
Если оно равно 2, то DE указы-
вает на верхнюю строку экрана, в
адрес которой заносился 0. HL и
DE уменьшаются, чтобы указать на
следующие байты. Счетчик (B-ре-
гистр) уменьшается и, если он не
равен 0, происходит переход к
COPY_B.
224 вычитается из регистровых
пар HL и DE - теперь они указы-
вают на следующую строку экрана.
Регистр C (счетчик строк)
уменьшается. Если содержимое ре-
гистра C кратно 8, т.е. выполне-
но 8 циклов для одной строки,
происходит переход к процедуре
ADD, иначе 2016 добавляется к HL
и происходит переход к N_BLOCK -
HL теперь указывает на следую-
щие 8 линий.
В процедуре ADD, если значе-
ние (C-1) не делится без остат-
ка на 8, происходит переход к
N_BLOCK, в противном случае 2016
добавляется к DE, чтобы пара ре-
гистров DE указывала на следую-
щие 8 линий. В процедуре
N_BLOCK, если значение C-регис-
тра делится без остатка на 64,
из HL вычитается 1792. HL те-
перь указывает на следующий блок
из 64 линий, и происходит пере-
ход к NEXT_L. В процедуре SUBTR,
если значение (C-1) не кратно
64, из DE вычитается 1792 - в
итоге DE указывает на следующий
блок из 64 линий.
Если C-регистр не содержит 1,
то подпрограмма возвращается к
NEXT_LINE, иначе в BASIC.