Маленькие тайны ZX-Lprint III
(С) Юрий Пехов, Ярославль,1995.
В последнее время распространенной моделью Spectrum-coBMecTM-мых компьютеров (во всяком случае в Московском регионе) стал "Пен-тагон-128", оснащенный интерфейсом принтера ZX-Lprint III, который позволяет подключать к нему различные типы принтеров как с параллельным, так и с последовательным интерфейсами.
Однако, при использовании этого интерфейса возникает ряд проблем. Пока речь идет о резидентном BASIC'е - т.е. выполнении команд LLIST, LPRINT, СОРУ - особых трудностей нет. Но когда нужно печатать что-то из машинного кода, в особенности графику, возникает потребность в чем-то более простом и изящном, чем управление принтером посредством управления интерфейсом. Кроме того, в процессе печати при нажатии BREAK управление автоматически передается анализатору ошибок резидентного BASIC'а, что не всегда желательно.
ЧИТАТЕЛЬ - Ч И.Т А Т Е Л Ю
С390 |
С1 |
El |
3E |
3F |
18 |
DC |
7E |
E6 |
CA |
C478: 00 10 96 C3 11 A9 C3 13 :35 |
С398 |
07 |
C5 |
06 |
F8 |
4F |
ЗА |
76 |
C4 |
E8 |
C480: B4 C3 16 BE C3 00 00 00 :52 |
СЗАО |
АО |
B1 |
32 |
76 |
C4 |
CI |
23 |
18 |
1С |
|
СЗА8 |
АА |
7E |
E6 |
07 |
07 |
07 |
07 |
C5 |
5A |
Для демонстрации работы проце |
СЗВО |
06 |
C7 |
18 |
E8 |
7E |
E6 |
01 |
C5 |
6A |
дуры можно воспользоваться Бей |
СЗВ8 |
06 |
BF |
OF |
OF |
18 |
DE |
7E |
32 |
04 |
сик -программой (автостарт со 2 |
СЗСО |
78 |
C4 |
23 |
7E |
32 |
77 |
C4 |
23 |
F0 |
строки): |
СЗС8 |
18 |
89 |
F5 |
D9 |
F1 |
E5 |
6F |
26 |
65 |
|
C3D0 |
00 |
29 |
29 |
29 |
ED |
5B |
36 |
5C |
E8 |
1 GO ТО 10 |
C3D8 |
19 |
44 |
4D |
C5 |
ЗА |
77 |
C4 |
87 |
06 |
2 BORDER 7: PAPER 7: INK 0: С |
СЗЕО |
5F |
87 |
83 |
16 |
FF |
14 |
D6 |
08 |
13 |
LEAR 49999: RANDOMIZE USR 15619: |
СЗЕ8 |
30 |
FB |
C6 |
08 |
F5 |
ЗА |
78 |
C4 |
OF |
REM : LOAD "print6"CODE |
C3F0 |
5F |
F1 |
CI |
D5 |
C5 |
FE |
00 |
CC |
28 |
3 RANDOMIZE USR 15619: REM ; |
C3F8 |
ОС |
C4 |
47 |
3E |
08 |
90 |
32 |
75 |
4F |
LOAD "font6"CODE 64600 |
С400 |
С4 |
CD |
4E |
C4 |
54 |
5D |
CI |
CD |
A6 |
4 FOR a=32 TO 127: POKE 50309 |
С408 |
20 |
C4 |
18 |
02 |
AF |
C9 |
ЗА |
77 |
F3 |
-32+a,a: NEXT a: POKE 50405,0: P |
С410 |
С4 |
3C |
32 |
77 |
C4 |
D1 |
CD |
5D |
3C |
ОКЕ 23606,88: POKE 23607,251 |
С418 |
С4 |
ЗА |
76 |
C4 |
77 |
El |
D9 |
C9 |
0E |
10 POKE 50296,0: POKE 50297,0 |
С420 |
1А |
C5 |
F5 |
OA |
4F |
ЗА |
75 |
C4 |
84 |
20 FOR a=l TO 9: RANDOMIZE USR |
С428 |
47 |
F1 |
C5 |
CB |
3F |
10 |
FC |
CI |
CO |
50000: NEXT a |
С430 |
А7 |
CB |
11 |
CB |
17 |
10 |
FA |
77 |
DA |
|
С438 |
23 |
71 |
2B |
24 |
14 |
CI |
03 |
ЗА |
F1 |
Точке входа WRITE соответству |
С440 |
74 |
C4 |
3D |
32 |
74 |
C4 |
20 |
D8 |
DB |
ет адрес 50003, поскольку это де |
С448 |
ЗЕ |
08 |
32 |
74 |
C4 |
C9 |
7B |
E6 |
E6 |
монстрационный вариант. Если Вы |
С450 |
18 |
C6 |
40 |
67 |
7B |
E6 |
07 |
OF |
10 |
захотите получить процедуру печа |
С458 |
0F |
OF |
82 |
6F |
C9 |
7B |
E6 |
18 |
6D |
ти отдельно, удалите строки 3 и 4 |
С460 |
CB |
3F |
CB |
3F |
CB |
3F |
F6 |
58 |
90 |
из листинга на ассемблере. |
С468 |
67 |
7B |
E6 |
07 |
B7 |
IF |
IF |
IF |
OF |
|
С470 |
IF |
82 |
6F |
C9 |
08 |
00 |
38 |
00 |
4D |
* * * |
Среди программного обеспечения, так или иначе работающего с принтером, нечасто встречаются программы, поддерживающие ZX-LPRINT III, а уж тем более последовательный протокол обмена. Здесь я не имею в виду программы на BASIC'е или, к примеру, пакет DEVPAC, печать из которого производится путём вывода через стандартный поток.
Большинство программ (по крайней мере из тех, которые попадались мне) ориентированы на использование КР580ВВ55 с самым разнообразным расположением в адресном пространстве, или на параллельный порт, входящий в состав AY-3-8910/12, (MicroEd, например) . Все эти способы имеют один общий недостаток - они недоступны простому "непаяющему" пользователю, коих, по моим наблюдениям, становится все больше. Кроме того, коммерческая ценность таких программ снижается из-за отсутствия аппаратной поддержки. В качестве примера можно назвать очень симпатичную программу Screen Manager (распространяемую, кстати, ИНФОРКОМом), которая практически неизвестна широкому кругу пользователей.
Сложившуюся ситуацию можно, по-видимому, объяснить недостатком информации о работе ZX-Lprint III.
Не вдаваясь слишком глубоко в схемотехнику, попробую вкратце сформулировать главные принципы работы интерфейса.
Интерфейс состоит из трех основных частей :
- дешифратора адреса;
- теневого ПЗУ;
- портов ввода/вывода.
Как известно, в стандартном ПЗУ Sinclair'82 имеются драйверы для поддержки устройства под названием ZX-Printer, порт которого расположен по адресу #FB. При выполнении команд вывода на печать из BASIC'а происходит опрос этого порта на предмет готовности принтера. Ввиду особенностей построения (а точнее практического отсутствия) дешифратора адреса в базовой модели ZX-Spectrum системе абсолютно безразлично - обращаетесь вы по адресу #FB или по адресу #7В. Однако это не безразлично для дешифратора адреса интерфейса ZX-Lprint III, который, встретив команду IN A,(#FB), подставляет на место стандартного - теневое ПЗУ, а при появлении команды IN А,(#7В), возвращает на место ПЗУ Sinclair. А так как ПЗУ Sinclair'82 (и его наиболее удачные доработки) известны своим постоянством в отношении адресов точек входа в основные подпрограммы, программа в теневом ПЗУ может однозначно определить, какая команда была вызвана из BASIC 'а и выполнить соответствующие действия, в том числе и инициализацию интерфейса по команде LPRINT [CR].
Теневое ПЗУ содержит набор программ для управления некоторыми типами принтеров, собственный интерпретатор команд, процедуры интерфейса с пользователем, управляющую программу и драйверы Centronics и RSJ-232C. При своей работе управляющая программа активно использует буфер принтера в котором организует массив собственных системных переменных и, кроме того, пересылает туда часть процедур, которые затем оттуда вызывает. Связано это с тем, что вызов подпрограмм из ПЗУ Sinclair, которые активно используются, например, для контроля нажатия BREAK, вывода на экран и для других целей, возможен только из ОЗУ, так как эти подпрограммы не предусматривают способов возврата в теневое ПЗУ.
Порты ввода/вывода расположены по адресу #FB (#7В) и, за исключением линии STROBE, особенностей не имеют. Сигнал STROBE формируется D-триггером из сигналов А7, WR, IORQout. В отличие от TR-DOS, здесь порты доступны вне зависимости от того, какое ПЗУ активно - Sinclair или Lpriyit. Следует лишь помнить, что команда IN А,(#FB) активизирует теневое ПЗУ.
Имея такую информацию об особенностях схемы интерфейса и вооружившись распечаткой дизассемблера ПЗУ ZX-Lprint III, можно приступить к решению проблемы адаптации программ. Задачу стоящую перед нами, можно сформулировать следующим образом: создать семейство драйвербв для управления принтерами по протоколам Centronics и RS-232C через аппаратуру интерфейса ZX-Lprint III, не пользуясь концепцией потоков и каналов (поскольку это не всегда удобно), не пользуясь управляющими кодами интерфейса (поскольку это всегда неудобно) и максимально используя процедуры из теневого ПЗУ. При этом не должно иреть значения, был ли инициализирован интерфейс ZX-Lprint III командой LPRINT [CR] или нет.
Начнем с рассмотрения некоторых подпрограмм, находящихся в теневом ПЗУ. Так, вывод информации на принтер по протоколу Centronics производит процедура, расположенная по адресу #00D0. Правда, при работе интерфейса она переносится в буфер принтера и вызывается оттуда. В листинге 1 приводится эта процедура с учетом реального рабочего адреса. Следует иметь в виду, что выполнение этой процедуры начинается при активном основном ПЗУ и запрещенных прерываниях.
Листинг 1.
5В6Е |
F5 |
|
|
PUSH AF |
5B6F |
CD |
54 |
1F |
CALL #1F54 |
5В72 |
D2 |
00 |
0D |
OP NC,#0D00 |
5В75 |
DB |
7В |
|
IN A,(#7B) |
5В77 5В79 5В7В |
Е6 20 F1 |
80 F4 |
|
AND #80 OR NZ,#5B6F POP AF |
5В7С |
D3 |
FB |
|
OUT (#FB),A |
5В7Е 5В80 5В82 |
D3 D3 С9 |
7В FB |
|
OUT (#7B),A OUT (#FB),A RET |
сохранение на стеке байта предназначенного к печати ;вызов подпрограммы BREAK_ ;TEST из основного ПЗУ ;выход в BASIC с сообщением ;BREAK-cont repeats ;чтение порта (не переключая ;ПЗУ)
;выделение бита готовности ;ожидание готовности ;восстановление байта предназначенного для печати ;запись байта в выходной ;регистр
;установка сигнала STROBE ;снятие сигнала STROBE ;возврат в вызывающую ;подпрограмму
Как можно видеть из листинга 1, работа по протоколу Centronics осуществляется из ОЗУ. В ПЗУ Lprint нет фрагментов для вывода по этому протоколу, которые можно было бы корректно вызывать из ОЗУ. Поэтому единственным способом работы по протоколу Centronics будет размещение подобного драйвера в произвольном месте ОЗУ. Примерный вид такого драйвера приведен в листинге 2.
Листинг 2.
Драйвер для печати по протоколу Centronics через аппаратуру ZX-Lprint III
(с) 1994 SUNNY TRAM Research
SEND DI
PUSH AF ;сохранение байта на стеке
OUT (#FB),А ;вывод байта WAIT CALL BREAK ;здесь следует вызвать Подпрограмму,
;которая проконтролировала бы нажатие ;клавиши BREAK и соответствующим ;образом на это отрёагировала
ЧИТАТЕЛЬ-ЧИТАТЕЛЮ
;вызов необязательной подпрограммы, ;которая каким-либо способом (текстом ;или цветом BORDER) информирует о ;неготовности принтера ;чтение порта
;проверка бита готовности принтера ;ожидание готовности ;вызывается для ликвидации следов ;работ'ы процедуры P_NORDY ;снятие со стека выводимого байта ;вывод байта вместе со стробом ;снятие сигнала STROBE
Следует только внимательно следить за стеком при вызове подпрограмм опроса BREAK и вывода сообщений с тем, чтобы не нарушать количества PUSH и РбР и не утерять необходимую информацию.
Теперь рассмотрим более сложный и интересный случай - связь с принтером через последовательный порт. Интерфейс ZX-LprintIII поддерживает передачу по протоколу DTR с передачей 8 бит, 1 стартовый и 2 стоповых бита, без контроля четности. В качестве выхода TxD используется линия D7 параллельного порта, а вход DSR соответствует линии D6 порта #FB.
В отличие от протокола Centronics, процедуры, поддерживающие последовательный обмен, вызываются непосредственно из теневого ПЗУ. Их работа рассматривается в листинге 3
Листинг 3.
; подпрограмма вывода одного байта в последовательный порт ; вызывается при активном теневом ПЗУ и запрещенных ; прерываниях
07ВВ |
С5 |
|
PUSH |
BC |
;сохранение на стеке |
07ВС |
Е5 |
|
PUSH |
HL |
;регистров,которые могут |
07BD |
F5 |
|
PUSH |
AF |
;быть коррумпированы |
07ВЕ |
ЕЕ |
FF |
XOR |
#FF |
;подготовка байта к передаче |
07С0 |
F5 |
|
PUSH |
AF |
;и его сохранение на стеке |
07С1 |
CD |
F9 OE |
CALL |
#06F9 |
;это не ошибка - ПЗУ Lprint |
занимает адреса #0000 - #07FF и поэтому когда оно активно нет разницы между обращением по адресу #06F9, #0EF9 или, скажем, #2EF9 (в пределах адресной области основного ПЗУ, разумеется). Почему адресация в теневом ПЗУ выполнена таким образом, что реальные адреса перемежаются со смещенными на 2 килобайта, мне, к сожалению, неведомо. Тем не менее нас это обстоятельство смущать не должно и, в дальнейшем, в листинге дизассемблера в области кодов я буду указывать содержимое ПЗУ а в мнемониках - реальные значения адреса. По адресу #06F9 в теневом ПЗУ содержится подпрограмма проверки нажатия BREAK.
07С4 |
D2 |
4С 05 |
JP |
NC,#054C |
;переход если BREAK |
07С7 |
DB |
FB |
IN |
A,(#FB) |
;чтение порта готовности |
07С9 |
СВ |
77 |
BIT |
6,A |
;не выключая теневое ПЗУ |
07СВ |
28 |
F4 |
JR |
Z,#07C1 |
;ожидание готовности |
07CD |
06 |
08 |
LD |
B, 8 |
;загрузка счетчика бит |
ЧИТАТЕЛЬ-ЧИТАТЕЛЮ
07CF |
ЗЕ |
FF |
|
LD |
А, #FF |
;вывод стартового бита |
07D1 |
D3 |
FB |
|
OUT |
(#FB),А |
|
|
07D3 |
F1 |
|
|
POP |
AF |
;инвертированный байт |
07D4 |
CD |
ЕЕ |
OF |
CALL |
#07ЕЕ |
;задержка |
|
07D7 |
CB |
OF |
|
RRC |
А |
последовательная передача |
07D9 |
D3 |
FB |
|
OUT |
(#FB),А |
;всех восьми бит |
07DB |
10 |
F7 |
|
DJNZ |
#07D4 |
|
|
07DD |
CD |
EE |
OF |
CALL |
#07ЕЕ |
;задержка |
|
07Е0 |
ЗЕ |
00 |
|
LD |
А, 0 |
;передача |
двух стоповых бит |
07Е2 |
D3 |
FB |
|
OUT |
(#FB),А |
|
|
07Е4 |
CD |
EE |
OF |
CALL |
#07ЕЕ |
;задержка |
|
07Е7 |
CD |
EE |
OF |
CALL |
#07ЕЕ |
;задержка |
|
07ЕА |
F1 |
|
|
POP |
AF |
;восстановление регистров |
07ЕВ |
El |
|
|
POP |
HL |
|
|
07ЧС |
CI |
|
|
POP |
ВС |
|
|
07 ED |
C9 |
|
|
RET |
|
|
|
|
|
|
|
|
Листинг 4 |
|
|
подпрограмма |
задержки |
для последовательного протокола |
к 07ЕЕ |
F5 |
|
|
PUSH |
AF |
сохранение аккумулятора |
07EF |
2A |
FC |
5B |
LD |
HL,(*5BFC) |
|
07F2 |
2B |
|
|
DEC |
HL |
|
|
07F3 |
7C |
|
|
LD |
А, Н |
|
|
07F4 |
B5 |
|
|
OR |
L |
|
|
07F5 |
20 |
FB |
|
JR |
NZ,#07F2 |
|
07F7 |
F1 |
|
|
POP |
AF |
|
|
07F8 |
C9 |
|
|
RET |
|
|
|
При своей работе |
процедура |
из листинга 3 вызывает подпрограмму за- |
держки из |
теневого ПЗУ, работа которой |
рассматривается в листинге 4. |
Как можно |
видеть |
подпрограмма (листинг 4) использует в работе |
двухбайтное число из |
системной переменной интерфейса с адресом #5BFC. |
Число это |
определяет |
скорость |
передачи |
интерфейса и изменяется управ- |
ляющей программой Lprint в зависимости |
от значения системной перемен- |
ной с адресом |
23728. |
Взаимосвязь значения в переменной 23728, скорос- |
ти передачи и |
числа |
по адресу |
#5BFC показана в таблице 1. (Внутренняя |
таблица величин |
задержки для разных |
скоростей |
содержится в теневом |
ПЗУ по адресу |
#0502) |
|
|
|
|
|
|
|
|
|
Таблица 1. |
|
|
Содержимое |
|
|
Скорость передачи |
[ (бод) |
Содержимое адреса |
адреса : |
23728 |
|
|
|
|
#5BFC |
1 |
|
|
|
|
75 |
|
#0714 |
2 |
|
|
|
|
110 |
|
#04D6 |
3 |
|
|
|
|
150 |
|
#038С |
4 |
|
|
|
|
300 |
|
#01С0 |
5 |
|
|
|
|
600 |
|
#00D8 |
6 |
|
|
|
1200 |
|
#006D |
7 |
|
|
|
2400 |
|
#0033 |
8 |
|
|
|
4800 |
|
#0017 |
9 |
|
|
|
9600 |
|
#000А |
|
ЧИТАТЕЛЬ-ЧИТАТЕЛЮ
Листинг 5.
06F9 |
ЗЕ |
7F |
LD |
A, |
#7F |
;опрос клавиши SPACE и если |
06FB |
DB |
FE |
IN |
A, |
#FE |
;она не нажата Ьыход с |
06FD |
1F |
|
RRA |
|
|
установленным флагом Carry |
06FE |
D8 |
|
RET |
С |
|
|
06FF |
ЗЕ |
FE |
LD |
A, |
#FE |
;если нажаты вместе Space |
•0701 |
DB |
FE |
IN |
A, |
#FE |
;и Caps Shift - выход со |
0703 |
1F |
|
RRA |
|
|
;сброшенным флагом Carry |
0704 |
С9 |
|
RET |
|
|
|
Опрос клавиши BREAK производит подпрограмма с адресом #06F9, она приведена в листинге 5.
Если в процессе печати была нажата клавиша BREAK, управление передается программе в теневом ПЗУ с адресом #054С, которая работает весьма любопытно (эта процедура приводится в листинге 6).
Листинг 6.
активизируется основное ПЗУ в котором по этому адресу
054С А 7 AND А
054D DB 7В IN А,(#7В)
054F FB EI
; содержится как раз процедура обработки BREAK пакета работы ; с магнитофоном
DI |
|
PUSH |
AF |
IN |
A, #FB |
POP |
AF |
CALL |
#07BB |
IN |
A, #7B |
EI |
|
RET |
|
;сохранение байта на стеке ;включение теневого ПЗУ
;вызов программы передачи байта ;включение основного ПЗУ
Следует лишь перед началом работы поместить по адресу #5BFC число из таблицы скоростей передачи, сделать это достаточно один раз.
2. Вы пишите (или адаптируете) программу, в которой нежелателен выход в BASIC потому, что разрушена BASIC-система или это снизило бы
Учитывая специфику организации программной поддержки последовательной передачи в ПЗУ ZX-Lprint, можно утверждать, что в зависимости от ситуации, есть три способа пocfpoeния внешнего драйвера. Рассмотрим эти три случая:
1. Вы пишете некоммерческую программу и не боитесь "вываливания" в BASIC при нажатии BREAK во время печати, при этом сама BASIC-система не разрушена и с адресом #5BFC не производится никаких манипуляций, или Вы на 100% уверены в адекватности реакции Вашего BREAK-перехват-чика на нажатие BREAK во время печати и, опять же, с адресом #5BFC не производится никаких манипуляций.
В этом случае можно использовать максимально короткий драйвер, приведенный в листинге 7.
Листинг 7.
ЧИТАТЕЛЬ - ЧИТАТЕЛЮ
коммерческую ценность программы. Возможна ситуация, когда единственной проверкой на BREAK является проверка во время пёчати. При этом, как и в первом случае, буфер принтера не занят. Рассмотрим такую ситуацию на примере адаптации к последовательному протоколу передачи через интерфейс ZX-Lprint программы Screen Manager 2.1 (автор С.Хан-цис). В листинге 8 приведен дизассемблер процедуры печати этой программы .
Листинг 8.
С5 F5
DD СВ 16
20 01 JR
2F CPL
; передаваемого байта в случае необходимости ADD1 4 7 LD В,А сохранение аккумулятора
ADD2 CD ЕЕ AD CALL #ADEE ;проверка на BREAK,
; идентичная процедуре на листинге 5
ADD5 D4 0D В1 CALL NC,#B10D ;подпрограмма которая
; запрашивает подтверждение прерывания печати, и в случае ; положительного ответа корректно выходит из программы
ADC8 ADC9 ADCA ADCE ADD О
PUSH ВС PUSH AF BIT 1,(IX+16) NZ,#ADD1
сохранение регистров ;на стеке
;проверка установленного ;типа интерфейса (IFSP ;или Centronics и инверсия
; печати |
не |
коррумпируя |
стек |
|
ADD 8 |
DB |
5F |
IN |
A,(#5F) |
;ожидание готовности |
ADDA |
17 |
|
RLA |
|
;принтера |
ADDB |
38 |
F5 |
JR |
С,#ADD2 |
|
ADDD |
78 |
|
LD |
А,В |
;восстановление байта |
ADDE |
D3 |
3F |
OUT |
(#3F),A |
;передача байта через |
ADEO |
AF |
|
XOR |
A |
;порт КР580ВВ55 |
ADEl |
D3 |
5F |
OUT |
(#5F),A |
ADE3 |
06 |
63 |
LD |
B,#63 |
|
ADE5 |
10 |
FE |
DJNZ |
#ADE5 |
|
ADE7 |
3E |
01 |
LD |
A, 1 |
|
ADE9 |
D3 |
5F |
OUT |
(#5F),A |
|
ADEB |
F1 |
|
POP |
AF |
;восстановление |
ADEC |
CI |
|
POP |
ВС |
;регистров и |
ADED |
C9 |
|
RET |
|
;возврат |
В листинге |
9.показано, как |
будет выглядеть этот фрагмент nocj |
менений.
Листинг 9.
ADC8 |
F3 |
|
DI |
|
|
ADC9 |
F5 |
|
PUSH |
AF |
сохранение аккумулятора |
ADCA |
CD |
D2 AD |
CALL |
#ADD2 |
;подпрограмма печати |
ADCD |
DB |
7B |
IN |
A, #7B |
;включение основного ПЗУ |
ADCF |
F1 |
|
POP |
AF |
;восстановление аккумуля |
ADD0 |
FB |
|
EI |
|
тора и прерываний |
ADD1 |
C9 |
|
RET |
|
;возврат |
ADD2 |
C5 |
|
PUSH |
ВС |
сохранение регистров |
ADD3 |
E5 |
|
PUSH |
HL |
|
ADD 4 |
F5 |
|
PUSH |
AF |
|
ADD 5 |
EE |
FF |
XOR |
#FF |
;подготовка байта к передаче |
ADD7 |
F5 |
|
PUSH |
AF |
;и его сохранение на стеке |
ЧИТАТЕЛЬ-ЧИТАТЕЛЮ
;включение основного ПЗУ ;проверка на BREAK,
ADD8 DB 7В IN А,#7В
ADDA CD EE AD CALL #ADEE
; идентичная процедуре на листинге 5
ADDD D4 OD B1 CALL NC,#B10D подпрограмма которая
; запрашивает подтверждение прерывания печати, и в случае ; положительного ответа корректно выходит из программы печати не коррумпируя стек
IN A,(#FB) BIT 6,А JR Z,#ADD8 JP #07CD см. Листинг 3 )
ADEO DB FB ADE2 СВ 77 ADE4 28 F4 ADE6 СЗ CD 07 ; теневое ПЗУ (
;чтение порта готовности ;и включение теневого ПЗУ ;ожидание готовности ;переход на программу в
Перед использованием процедуры здесь также следует записать по адресу #5BFC число #000А (для скорости 9600 бод). Разумеется, можно изменить вышеприведенную программу для работы по параллельному протоколу.
3. Самый неприятный случай, когда буфер принтера уже чем-то занят, например, системными переменными BASIC-128. В этой ситуации единственным выходом будет создание где-то в ОЗУ немного измененной копии программ из Листингов 3-5. Я надеюсь, что из предыдущих рассуждений ясно, как это сделать. Правда, такой драйвер получится достаточно длинным, но надо же чем-то платить за удовольствие подключить принтер всего тремя проводами.
Хочется верить в то, что всего вышесказанного достаточно для адаптации любой программы к работе с интерфейсом ZX-Lprint III.