ПРОГРАММА MONS
Опубликовано: СИНКЛЕР РИСЕЧ
Дата: 14.12.1984г.
НАЧАЛЬНЫЙ СТАРТ
"MONSS" релокатабельная программа, т.е. положение ее в адресном пространстве
не фиксировано и может загружаться по желаемому адресу.
Если после ухода в БЕЙСИК, Вы хотите перезагрузить MONS снова, тогда пере-
дайте управление адресу на 29 больше, чем первоначальный.
Пример: допустим Вы желаете загрузить MONS3 с адреса: #С000 (49152 дес.)
LOAD "MONS3" CODE 49152
RANDOMIZE USR 49152
Для перезагрузки используйте: RANDOMIZE USR 49181. Это позволит избежать
участка программы, ведающего релакатабельностью, перемещающею адреса внутри
программы MONS3 при первом введении. MONS3 занимает около 6К паяти, он содер-
жит свой внутренний стек, т.е. это самосодержащая программа. После введения
программы с ленты возникает сообщение 'MONS3 С Copyright Misoft 1983' и через
несколько секунд - информационное табло (см. приложение). Оно заполнено содер-
жимым регистров и флагов Z80, содержимым 24-х байт памяти и текущим значением
счетчика памяти, который первоначально инициализирован адресом '0'. На верхней
строчке дисплея находится дисассемблированное значение инструкции по адресу
счетчика памяти.
После введения MONS3, все адреса отображены в гексадецимальной форме, но Вы
можете это изменить на десятичном, используя SYMBOL SHIFT 3 - см. следующий
раздел.
Помните, что адреса, тем не менее, должны всегда вводится только в гексадеци-
мальной форме.
Команды с клавиатуры могут вводится как большими, так и малыми буквами. Они
вводятся в ответ на указатель'»' под информацией о содержимом памяти. Некоторые
команды, могущие вызвать катастрофические последствия (в случае ошибки), требу-
ют нажатия SYMBOL SHIFT и командной буквы. Это будет обозначаться знаком
Например, обозначает одновременное нажатие SYMBOL SHIFT и Z. Комиды
действуют немедленно - нет необходимости в ENTER. Несуществующие команды
просто игнорируются. Информационное табло обновляется после каждой команды и
результат каждой команды можно наблюдать немедленно.
Многие из команд требуют введения гексадецимальных чисел (0-9, A-F или a-f)
или по Вашему желанию определить их любыми, негексадецимальными знаками.
Если терминатор является пригодной командой, тогда команда выполняется после
любой предшествующей команды. Если терминатор представляет собой знак'-', тогда
введенное гексадецимальнос число будет возвращено в двух дополнительных формах,
т.е. 1800 дает Е800. Если введено более четырех цифр, то только последние четыре
принимаются во внимание. Если на любой стадии Вы желаете возвратиться в BASIC,
тогда нажмите CAPS SHIFT 1.
ВНИМАНИЕ! MONS3 чтобы обеспечить правильное функционирование делает
прерывания невозможными, поэтому пользователь должен принять меры, чтобы при
работе с MONS3 не происходило прерывания.
ВОЗМОЖНЫЕ КОМАНДЫ
В этой секции, каждый раз, когда ENTER используется для определения
(terminate) гексадецимального числа, то это фактически может быть любой негекса-
децимальный знак (см. СЕКЦИЮ 1). Знак "-" также используется для обозначения
пробела там, где он применяется.
SYMBOL SHIFT 3
Переключает форму отображения адресов между шестнадцатиричной и десяти-
чной системами. При входе в MONS адреса даются в гексадецимальной форме. Ис-
пользуйте эту команду для перехода в десятичную форму и обратно. Это касается всех
адресов, показываемых MONS3, включая адреса, вырабатываемые
DISASSEMBLERom, но это не изменяет содержимого памяти и всегда дается в гекса-
децимальной форме.
SYMBOL SHIFT 4
Отображает дисассемблированную страницу начиная с адреса, находящегося в
счетчике памяти (memory pointer). Это позволяет взглянуть вперед от текущей пози-
ции и увидеть, какие инструкции на подходе. Нажмите ,/ч4* для возврата к "FRONT
PANEL" или любую другую клавишу для чтения следующей страницы дисассембли-
рования.
ENTER
Увеличивает "MEMORY POINTER" на единицу так что 24-х байтовое отображение
теперь расположено симметрично вокруг адреса на 1 больше, чем предыдущий.
CAPS SHIFT 7
Уменьшает MEMORY POINTER на единицу.
CAPS SHIFT 5
Уменьшает MEMORY POINTER на 8. Используется для быстрого возврата.
CAPS SHIFT 8
Увеличивает содержимое счетчика на 8. Используется для быстрого продвижения
вперед.
V ^ ЗАПЯТАЯ
Обновляет MEMORY POINTER так, что он содержит адрес присутствующий в
стеке (индицируется SP). Это полезно, если Вы хотите осмотреться и вернуть адрес
вызываемой программы.
'G'
Поиск в памяти указанной цепочки ("G"et a string). Появляется указатель V и Вы
должны ввести первый байт, который желаете найти, затем ENTER и теперь вводите
следующие байты (и ENTER) в ответ на пока не определите цепочку полностью,
затем одно ENTER в ответ на':' - это обусловит определение цепочки и поиск в памяти,
начиная с текущегб адреса MEMORY POINTER до первой встречи с указанной цепоч-
кой. Когда цепочка будет найдена, дисплей на FRONT PANEL будет обновлен так, что
MEMORY POINTER будет расположен на первом знаке цепочки. Например, допу-
стим необходимо найти в памяти, начиная с адреса #8000 наличие #ЗЕ и #FF (2
байта), действуй так:
М:8000 ENTER - устанавливает MEMORY POINTER на #8000
G:3E ENTER - определяет первый байт цепочки
FF ENTER - определяет второй байт цепочки
ENTER - определяет цепочку
/
/
После заключительного ENTER (или любого гекс знака) *G' начинает поиск в
памяти от #8000 до первого наличия #ЗЕ #FF. После нахождения дисплей обновится.
Чтобы найти последующее местонахождение цепочки, используют команду *N
Переводит десятичное число в его гексадецимальный эквивалент. После возник-
новения указателя введите децимальное число и разделитель (терминатор). В
качестве терминатора можно использовать любой знак, за исключением цифр. После
этого появится знак '' с последующим шестнадцатиричным эквивалентом. 11ажмите
любую клавишу для возврата в режим команд. Например: Н:41472_-А200 - здесь
пробел используется как терминатор.
Т (intelligent сору)
Используетсу для копирования блока памяти с одного места в другое. Его особен-
ность, что блок может быть скопирован на место, перекрывающее свое предыдущее
местонахождение. Т запрашивает для старта адреса копируемого блока ("FIRST:",
"LAST:") и затем адрес, на который блок будет перемещен СТО:"). Введите гексаде-
цимальные числа в ответ на эти запросы. Если начальный адрес больше, чем конеч-
ный, то команда не выполняется.
Т
Исполняет код с указанного адреса. Эта команда через указатель запрашивает
шестнадцатиричное число, после этого внутренний стек переустанавливается и ис-
полнение передается указанному адресу. Если необходимо вернуться к "FRONT
PANEL" после исполнения кода, тогда устанавливается точка разрыва (break point)
(см. команду 'W') в точку, где желаете вернуться к дисплею.
Например: J:B000 ENTER - исполняет код, начиная с #8000. Можно отменить эту
команду доопределения адреса, использовав 'CAPS SHIFT 5 Заметьте, что Г портит
регистры Z80 перед исполнением кода. Программа машинного кода не должна опи-
раться на величины, хранящиеся врегистрах. Если Вы желаете исполнить код с
учетом содержания регистров, тогда нужно использовать команду 'SYMBOL SHIFT
К'(см. ниже).
♦SYMBOL SHIFT К*
Продолжает исполнение с адреса, содержащегося в PROGRAM COUNTER. Эта
команда, вероятно, будет использоваться наиболее часто в соединении с 'W* - пример
поможет разъяснить это использование: допустим идем по одному шагу ,/vZ'; через
данный ниже код и достигли адреса #8920, Если в настоящий момент Вас не интере-
сует проход через подпрограмму по адресу #9000, но желаете знать установку флагов
после обращения к подпрограмме по адресу #8800.
891Е 3EFF LD А,-1
8920 CD0090 CALL #9000
8923 2А0080 LD HL,(#8000)
8926 7Е LD A,(HL)
8927 111488 LD DE,#8814
892A CD0088 CALL #8800
892D 2003 JR NZ,LAB1
892F 320280 LD (#8002), A
8932 211488 LABI LD HL,#8814
Действуйте так: установите точку разрыва (breakpoint) использовав 'W' в ячейке
#892D (но не забудьте сначала применить 'М* для установления MEMORY POINTER)
и выдайте команду ,/чК Исполнение продолжается с адреса содержащегося в PRO-
GRAM COINTER (PC) , который в этом случае равен #8920. Исполнение затем будет
продолжаться до адреса, на который установлен breakpoint (#892D). В этот момент
дисплей будет обновлен и Вы можете проверить состояние флагов итд. После обраще-
ния к подпрограмме в #8800. Затем можно возобновить продвижение шаг за шагом по
коду. Итак полезно для исполнения кода без сперва переустановки стека или
нарушения регистров, как это делает Р.
*L*
Табулирует или дает листинг блока памяти, начинающийся с адреса, содержаще-
гося в MEMORY POINTER. Т/ очищает экран и показывает гексадецимальное пред-
ставление и эквиваленты ASCII 80 байтов памяти, начиная с текущего уровня
MEMORY PQINTER. Адреса будут показаны или в 16-тиричной или в десятичной
форме в зависимости от текущего состояния "FRONT PANEL" (см. выше). Дисплей
состоит из 20 рядов по 4 байта в ряд; ASCII будет показан в конце каждого ряда. Коды
между 0 и 31 включительно изображаются '.'.В конце страницы листинга имеется
возможность возврата к главной "FRONT PANEL", нажав CAPS SHIFT 5 или подо-
ждать на следующей странице из 80 байтов, нажав любую клавишу (кроме CAPS
SHIFT 1).
Устанавливает MEMORY POINTER в указанный адрес. Появляется указатель
требующий ввода 16-тиричного адреса (см.раздел 1). MEMORY POINTER обновля-
ется в соответствии с введенным адресом и дисплей памяти "FRONT PANEL" также
соответственно изменяется. 'М' очень важна и как бы является прелюдией для введе-
ния кода, табулирования памяти и т.д.
*N*
Находит следующее наличие гексцепочки, указанной в команде *G*. 'G* позволяет
Вам определить цепочку и затем ищет ее до первого нахождения. Если нужно найти
следующее наличие цепочки, используйте *N 'N' начинает поиск с MEMORY
POINTER и обновляет дисплей памяти, когда указанная цепочка будет найдена.
'О*
Предназначена для относительного перемещения. Команда берет байт, текуще
адресованный MEMORY POINTER, понимает его как относительное смещение и
обновляет дисплей памяти соответственно. Например: допустим счетчик команд ус-
тановлен на #6800 есть #20 и #16 соответственно - это может быть интерпретировано
как инструкция JR NZ,$+24. Чтобы найти, где эта ветвь продолжится по ненулевому
уровню, нажмите 'О', когда счетчик команд адресует перемещение байт #16. Дисп-
лей затем обновится на центр вокруг #6817, т.е. вокруг требующего значения ветви.
Помните, что относительное перемещение больше чем на #7F (127) понимается
процессором как отрицательное. Команда 'О* учитывает это. См. также команду 'LP
в ее связи с командой 'О*.
»р»
Заполняет память по указанным байтам. Запросы 'P'-'Tirst, Last, With". Введите
шестнадцатиричные числа в ответ на эти запросы, соответствеено первый и последний
адреса включительно блока, который вставляется и байт, которым нужно заполнить
память. Пример:
Р
First:7000 ENTER
Last:77FF ENTER
With:55 ENTER
заполнит ячейки #7000 и #77FF (включительно) байтом #55 ('U'). Бели началь-
ный адрес будет больше, чем конечный, команда будет отмечена.
•Q*
Переключает установку и показ регистров. Вначале дисплей отображает стандар-
тный набор регистров (AF,HL,DE,ВС). Использование 'Q' отобразит альтернативные
регистры (AFHLDEBC'). Повторное нажатие 'Q* ведет к стандартному набору
регистров.
'SIMBOL SHIFT Т
Устанавливает точку разрыва после текущей инструкции и продолжает исполне-
ние. Пример:
9000 В7 OR А
9001 С20098 CALL NZ,#9800
9004 010000 LD BC,0
9800 21FFFF LD HL.-l
Двигаясь по одному uiaiy по коду и достигнув #9001 с ненулевым значением в
регистре А, в результате нулевой флаг будет находиться в положении NZ после
инструкции ОРА. Если Вы теперь используете '^Z' для продолжения движения по
одному uiaiy, то исполнение будет продолжаться по адресу #9800, адресу программы.
При нежелании двигаться по этой подпрограмме, введите команду ,/чТ при адресе
#9004 и CALL будет обойден автоматически, а программа остановится на команде
#9004 для дальнейшего пошагового прохождения программы. Помните, устанав-
ливает точку разрыва после текущей инструкции и затем издает команду (см.
команду ,/чК' с расширенным примером пошагового прохождения программы).
9J*
' к
Команда дисассемблирует блок кодов, факультативно для принтера. Сначала де-
лаются запросы "First:" и "Last:" - адреса кодов, которые нужно дисассемблировать.
Ведите в ответ 16-тиричные адреса, как указано в разделе 1. Если начальный адрес
больше, чем конечный, то команда отменяется. После введения адресов возникнет
вопрос: "Printer?** - ответ ТОЛЬКО заглавная буква "Y" для дисассемблирования в
канал Вашего принтера, или любая другая величина для выхода на экран. Затем
возникнет указатель "Text" для ввода 16-тиричного начального адреса любого текст-
файла, который будет дисассемблирован. Если Вы не хотите, чтобы вырабатывался
текстфайл, просто нажмите ENTER после этого запроса. Если Вы указываете адрес,
тогда текстфайл будет дисассемблирован, начиная еэтого адреса в форме, удобной для
использования GENS3. Если Вы хотите использовать текстфайл с GENS3, то необхо-
димо или выработать его или передвинуть его к первому адресу данному ассемблеру
редактором команд 'Х потому что это адрес начала текста, ожидаемого GENS3.
Вы также должны сообщить GENS3, где находится конец текстфайла; делайте это,
беря адрес "End of text" данный ассемблером (см. ниже) и вставляя его в ячейку
TEXTEND GENS3 (см. учебник GENS3, секция 3.2.). Затем Вы должны ввести
GENS3 теплым стартом для сохранения текста. Если на любой стадии, когда Вы
вырабатываете текстфайл, текст перепишет MONS3, то дисассемблирование отменя-
ется - нажмите любую клавишу для возврата к "FRONT PANEL". Если Вы указали
адрес текстфайла, то поступит запрос "Workspace":" - адрес начала свободной области
памяти, который используется как примитивный SYMBOL TABLE для любой метки
выработанной дисассемблером. Количество необходимой памяти - это два байта для
каждой метки. По умолчанию (просто нажать ENTER) - принимается адрес #6000
(hex). После этого повторно запрашивается "First:","Last:" (включительно) адреса
каждой области данных, которые существуют внутри дисассемблируемого блока.
Области данных - это области, скажем текста, который не должен интерпретиро-
ваться как инструкция для Z80 - вместо этого эти области данных вызывают директи-
вы ассемблера DEFB, выработанные дисассемблером. Если значения байтов находят-
ся между 32 и 127 (#20 и #7F) включительно, тогда дается интерпретация байта
ASCII, например, #41 после DEFB меняются в А. Когда Вы закончили спецификацию
областей данных, или если Вы не желаете указать таковых, просто нажмите ENTER
в ответ на оба запроса.
Команда 'Т' использует область в конце MONS3 для хранения адресов областей
данных и поэтому Вы можете установить так много областей данных, сколько позво-
ляет память; каждая область для хранения данных требует 4 байта. Заметьте, что
использование 'Т' разрушает все точки разрыва (breakpoints), которые были перед
этим установлены (см. команду 'W'). Экран будет теперь очищен. Если Вы запраши-
вали создание текстфайла, будет краткая задержка, зависящая от размера дисассем-
блируемого блока, пока создается SYMBOL TABLE. После этого листинг дисассемб-
лера появится на экране или принтере. Вы можете приостановить листинг в конце
строки, нажав ENTER или SPACE, затем надо нажать CAPS SIHFT 5 для возврата к
"FRONT PANEL" или же любую другую клавишу (кроме CAPS SHIFT 1) для продол-
жения дисассемблирования. Если какой-нибудь OPCODE непригоден, это распозна-
ется как NOP и отмечается "*" после OPCODE'a в листинге.
В команде дисассемблирования дисплей приостанавливается и, если Вы запраши-
ваете производство TEXTFILE, появляется сообщение "End of text ХХХХХ", где
ХХХХХ - это адрес (16-тиричный или десятичный), который нужно заслать РОКЕ
(сначала байт низшего порядка) в ячейку TEXTEND GENS3 для того, чтобы ассемб-
лер мог подобрать этот дисассемблированный текстфайл на теплом старте.
Когда дисассемблирование закончено, нажмите любую клавишу для возврата к
"FRONT PANEL" (кроме CAPS SHIFT 1), что возвращает в BASIC.
Метод вырабатывается, когда необходимо (например, С30078) в форме LXXXX,
где ХХХХ - абсолютный гексадсцимальный адрес метки, но только тогда, когда
данный адрес находится в границах дисассемблера. Если адрес лежит снаружи этого
диапазона, то метка не вырабатывается, а просто сообщается гексадецимальный или
десятичный адрес. Например, если мы дисассемблируем между #7000 и #8000, тогда
инструкция С30078 будет дисассемблирована как JP L7800; с другой стороны, если
дисассемблирование будет производится между #9000 и #9800, то С30078 будет
распознано как JP #7800 или JP 30720 (если использован децимальный дисплей).
Если была ссылка на отдельный адрес в инструкции дисассемблирования, тогда
метка появится в поле меток (после мнемоники) дисассемблирования инструкции с
адресом, но только, если листинг направляется в текстфайл. Пример:
Т
FIRST:8B ENTER
LAST: 9Е ENTER
PRINTER? Y
TEXT: ENTER
FIRST:95 ENTER
LAST: 9E ENTER
FIRST: ENTER
LAST: ENTER
008В FE16 CP #16
008D 3801 JR С, LOO 90
008F 23 INC HL
0090 37 SCF
0091 225D5C LD <#5C5D),HL
0094 C9 RET
0095 BF524E DEFB #BF,"RVN"
0098 C4494E DEFB #С4,Т',ЧГ
009B 4B4559 DEFB "K'"E'"Y"
009E A4 DEFB #A4
'U'
Используется в соединении с командой *0
Помните, что *0*обновляет дисплей памяти в соответствии с относительным пере-
мещением, т.е. он показывает эффект JR или DJMZ инструкции. 'U' используется для
обновления памяти назад, к последнему выданному 'О*. Пример:
7200 47 71F3
7201 20 71F4
<<7202F2<< «71 F5«
7203 06 71F6
DISPLAY 1 DISPLAY 2
Вы находитесь в дисплее 1 и котите получить информацию о месте относительного
прыжка по команде 20F2. Нажимайте 'О* и дисплей памяти изменяется на дисплей
2. Теперь Вы исследуйте код следующий за #71F5 некоторое время и затем желайте
вернутся к коду первоначального прыжка, чтобы видеть, что случится, если установ-
лен нулевой флаг. Нажмите *U* для возврата к месту, когда была выдана команда 'О'.
Все предыдущие наличия команды 'О* - утеряны.
♦у»
Используется в соединении с командой *Х 'V* подобна команде *1Г за исключе-
нием того, что она обновляет дисплей памяти к месту перед выдачей последней
команды *Х Пример:
8702 AF 842D
8703 CD 842Е А2
>>8704 2F« 842F Е5
8705 44 8430 21
DISPLAY 1 DISPLAY 2
Вы находитесь в дисплее 1 и хотите посмотреть на подпрограмму по #842F. На-
жмите 'X' при дисплее центрированном как показано - дисплей затем обновляется к
дисплею 2. После изучения подпрограммы, если захотите вернуться к основной про-
грамме, нажмите 'V* и дисплей 1 появится снова. Как и с 'и* Вы можете использовать
эту команду только для возврата в адрес, на котором Вы дали команду 'Х Все
предыдущие адреса, на которых давалась команда 'X' - теряются.
'W'
Устанавливает breakpoint на MEMORY POINT.
Break point в MONS3 - это инструкция CALL в подпрограмме внутри MONS3,
которая показывает FRONT PANEL таким образом, что дает программисту возмож-
ность остановить исполнение программы и исследовать состояние регистров Z80,
флаги и интересующие ячейки памяти. Так, если Вы хотите остановить исполнение
программы #9876, используйте 'М' для установки счетчика команд на #9876 и затем
выполните *W чтобы установить breakpoint по этому адресу. Три байта кода, кото-
рыве были первоначально у #9876 замещаются инструкцией CALL, которая остано-
вит исполнение. Когда она будет достигнута, она заставит первоначальные 3 байта
быть замещенными по #9876 и "FRONT PANEL" будет показана со всеми регистрами
и флагами в состоянии, в котором они находились перед точкой разрыва. Вы теперь
можете использовать любую возможность MONS3 обычным образом.
ПРИМЕЧАНИЯ. MONS3 использует область памяти в конце своей программы,
которая первоначально содержала адреса перемещения для хранения breakpoint'oe
сколько есть памяти; каждый breakpoint требует 5 байтов для хранения.
Когда исполняется breakpoint MONS3 автоматически восстановит содержимое па-
мяти, которое существовало перед установлением этого breakpoints. Заметьте, что
поскольку команда *Т* также использует эту область памяти, то при ее применении
все breakpoint теряются. Т.к. breakpoint состоит из 3-х байтовой конструкции,
CALL,надо уделить внимание упражнениям для исключительных случаев, например:
8000 ЗЕ 8008 00
8001 01 8009 00
8002 18 800А06
8003 06 800В 02
»8004AF« 800С18
8005 0Е 800D F7
8006 FF 800Е 06
8007 01 800F44
Если Вы установите breakpoint на #8004 и затем начнете исполнение кода с ячейки
#8000, тогда регистр А будет загружаться со значением 1, исполнение передается к
#800А, регистр В будет загружен значением 2 и исполнение передается в ячейку
#8005, но #8005 было переписаномладшим байтом breakpoint call и в результате мы
имеем испорченный код и непредсказуемый результат. Этот тип ситуации довольно
необычен, но Вы должны быть защищены от нее и в этом единственном случае -
передвижение по коду дасг ответ (см. команду ,/vZ' ниже для подробного примера
пошагового продвижения).
Используется для обновления счетчика команд с назначением абсолютного CALL
или JP инструкций. 'X* берт 16 битовый адрес, указанный в счетчике команд (2 байта)
и затем обновляет дисплей памяти так, что он сцентрирован вокруг этого адреса.
Помните, что младший байт половины адреса указан первым байтом, а старшая часть
адреса указана вторым байтом (формат INTEL). Пример: допустим Вы желаете по-
смотреть подпрограмму, которую вызывает код CD0563; установите MEMORY
POINTER, используя *М так что он адресуется 05 внутри инструкции CALL и затем
нажмите 'X'. Дисплей памяти будет обновлен так, что он симметричен относительно
ячейки #6305 (см. также команду 'V в соединении с 'X').
»у»
Ввод ASCII из MEMORY POINTER. *Y* дает Вам новую строку, на которую Вы
можете вводить знаки ASCII непосредственно с клавиатуры. Эти знаки продублиро-
ваны их гексадецимальными эквивалентами и вводятся в память, начиная с текущего
значения счетчика команд. Цепочки знаков должны быть определены CAPS SHIFT 5
и DELETE (CAPS SHIFT 0). DELETE можно использовать для вычеркивания знаков
из цепочки. Когда ввод знаков ASCII прекращен, нажатие CAPS SHIFT 5 обновляет
дисплей так, что MEMORY POINTER расположен сразу после конца цепочки, как она
была введена в память.
'SYMBOL SHIFT Z*
Один шаг. Перед пользованием '^Z' или ,ЛТ как счетчик команд, так и MEMORY
POINTER, должны быть установлены на адрес инструкции, которую Вы вводите.
7080 2А0072 LD HL,(#7200) ;SECTION 1
7083 ED5B0272 LD DE,(#7202)
7087 CD0071 CALL MULT
708A 7C LD A,H
708B CD0071 CALL AOUT
708E 7D LD A,L
708F CD1D71 CALL AOUT
7092 210000 LD HL,0
7100 AF MULT XOR A ;SECTION 2
7101 ED52 SBC HL,DE
7103 19 ADD HL,DE
7104 3001 JR NC,MU1
7106 EB EX DE,HL
7107 B2 MU1 OR D
7108 37 SCF
7109 CO RET NZ
71 OA B3 OR E
710B 5A LD E,D
710C 2007 JR NZ,MU4
710E EB EX DE,HL
71 OF C9 RET
7110 EB MU2 EX DE,HL
7111 19 ADD HL,DE
7112 EB EX DE,IIL
7113 29 MU3 ADD HL,HL
7114 D8 RET С
7115 IF MU4 RRA
7116 30FB JR NZ,MU3
7118 B7 OR A
7119 20F5 JR NZ,MU2
71 IB 19 ADD HL,DE
711С C9 RET
71 ID F5 AOUT PUSH AF -.SECTION 3
71 IE OF RRCA
71 IF OF RRCA
7120 OF RRCA
7121 OF RRCA
7122 CD2674 CALL NIBBLE
7125 F1 POP AF
7126 E60F NIBBLE AND % 1111
7128 C690 ADD A,#90
712A 27 DAA
712В CE40 ADC A,#40
712D 27 DAA
712E FD213A5C LD IY,#5C3A
7132 D7 RST #10
7133 C9 RET
7200 1B2A DEFW 10779
7202 0300 DEFW 3