__________________________________________ (C) SKL-KEEPER __________________________________________ О печати сообщений в нижних строках экрана Очень часто у начинающих программистов возникает вопрос: а как можно напечатать какое-нибудь сообщение в самых нижних, так называемых, "служебных" строках экрана, т. е. в строках с номерами 22 и 23? Да, практически, так же просто, как и при печати на основной экран! Только надо помнить, что для вывода сообщения в нижнюю часть экрана надо перед применением коман- ды печати открыть другой канал. Как из- вестно, при печати в главной части экрана надо открыть канал #2, а вот для строк с номерами 22 и 23 есть несколько способов заставить процессор печатать сообщение там, где нам надо:-) Напомню, что стандартными каналами для вывода информации на "Спектруме" являются каналы "S" - главная часть экрана, "P" - стандартный ZX-принтер и "K" - нижние две строки экрана. К этим каналам стандартно подключены потоки : - поток "0" - к каналу "K"; - поток "1" - тоже к каналу "K"; - поток "2" - к каналу "S"; - поток "3" - к каналу "P". Так как "Спектрум" не может одновремен- но выдавать информацию, к примеру, и на экран и на принтер, в любой момент времени всегда задействован только один канал вво- да-вывода и только один поток, связанный с ним. Этот канал и этот поток называются текущими. Итак, первый способ сделать текущим ка- нал печати "K" - переключиться на нужный нам поток #1 вызовом процедуры ПЗУ, кото- рая называется CHAN_OPEN и находится по адресу #1601: LD A,1 ;Номер потока - в аккумулятор. CALL #1601 ;Сделали его текущим. Практически то же самое получится, если открыть канал с номером "минус три", или #253. Программируя в машинном коде, переклю- чаться с канала "S" на "K" и наоборот мож- но еще одним способом. Нулевой бит систем- ной переменной TVFLAG, расположенной по адресу #5C3C, несет в себе информацию о том, какой поток в данный отрезок времени является текущим. Когда он выключен, т.е. равен нулю, используется канал "S", а ког- да включен - канал "K". Процедура открытия канала "K" будет выглядеть так: LD A,1 LD (#5C3C),A Таким образом, простейшая процедура пе- чати сообщения в нижних строках экрана бу- дет выглядеть таким образом : LD A,1 ;В "А" - номер канала. CALL #1601 ;Откр. канал систем. окна. LD DE,MES ;Адрес начала сообщения. LD BC,11 ;Длина сообщения. CALL #203C ;Вызов проц. ПЗУ PR_STRING ;для печати сообщения. PAUS HALT ;Эта часть программы - для ;того, чтобы сообщение ;"0:O.K.", появляющ. после ;исполнения программы, не ;переместило выведенную на ;экран строку. В машинных ;кодах это равноценно ко- ;манде "PAUSE 0". Итак, ;ждем прерывания. BIT 5,(IY+1);Проверяем 5й бит систем. ;переменной FLAGS. JR Z,PAUS ;Если клав. не нажималась, ;он выключен, идем на мет- ;ку PAUS. RES 5,(IY+1);Если он включен, выклю- ;чим его и поехали дальше. RET ;Выходим из процедуры. MES DEFB "OUR MESSAGE" ;Текст сообщения. Существует еще один способ печати сооб- щений, самый мощный и часто употребляемый. Его применяют в тех случаях, когда в прог- рамме есть много самых разных сообщений, и программист заранее не знает, когда какое придется печатать. Ведь удобно же печатать текст, указав только его номер в таблице сообщений! Чтобы программа знала, где начинается и где кончается нужное сообщение, применяет- ся такой остроумный прием: в последнем символе каждого сообщения принудительно включается старший бит, т.е., другими сло- вами, к коду последнего символа прибавля- ется число 127. И программа соображает,что если код символа больше 127, то это - мар- кер конца сообщения. Небольшую программу, которую я хочу предложить Вашему вниманию, я "вытащил" из инсталлируемого boot'а MINI BOOT 3.0. Таб- лица возможных надписей должна начинаться с #80. Если надпись состоит из двух строк, то между ними надо ставить код #06. LD A,#03 ;Номер сообщения. CALL PR_MES ;Попробуйте поста- CALL OPROS ;вить сюда цифры RET ;от 0 до 3. А вот перечень возможных сообщений с информацией о том, какому номеру какое со- общение соответствует: Ноль - NO PROGRAMS; Единица - MORE THEN 65 FILES; Двойка - MINI BOOT v3.0 WRITTEN BY ... Тройка - INSERT DISK FOR READING KATАLOG Текст,естественно, можно написать любой свой... PR_MES LD DE,MES_TAB ;Печать надписи CALL #0C0A ;Подпрограмма ;печати сообщений RET Для выполнения этой подпрограммы ПЗУ в DE загружается начальный адрес таблицы со- общений, в регистр A - номер сообщения в ней минус единица. Первым байтом в таблице должен стоять 128 (#80). Для задания конца сообщения старший бит его последнего байта должен быть установлен в единицу. MES_TAB DEFB #80,#16,#0A,#05 DEFB "!!! NO PROGRAMS !!!" DEFB #A0 DEFB #16,#0A,#02,#10,4 DEFB " MORE THEN 65 BASIC FILES" DEFB #A0 DEFB #11,#00,#10,#04,#13,1 DEFB " -= Mini BOOT v3.0 =-" DEFB #06 DEFB "Written by *S.Sergey.* " DEFB "12.06.95" DEFB #A0 DEFB #10,#02,#13,1 DEFB " INSERT NEW DISK" DEFB #06 DEFB " FOR READING CATALOG..." DEFB #A0 OPROS EI ;Для чего эта под- RES 5,(IY+#01) ;программа, дога- HALT ;даться будет не- CALL RAINB ;сложно? BIT 5,(IY+#01) JR Z,OPROS RET RAINB LD HL,#5AE1 ;Радуга на надписи PUSH HL ;в нижней строке. POP DE DEC DE LD BC,#001F LDIR LD HL,#5AFF LD A,(LAB_1) OR A JR Z,LAB_2 LD A,(HL) AND #07 INC A CP #08 JR NZ,LAB_3 XOR A LD (LAB_1),A LD A,#07 LAB_2 LD A,(HL) AND #07 DEC A OR A JR NZ,LAB_3 CPL LD (LAB_1),A LD A,#01 LAB_3 LD (HL),A RET LAB_1 DEFB #FF ------------------------------------------