Кодерам закорючки на бордере - Бордюрные эффекты - это всегда что-то, а скорее - нечто, закрытое за тремя печатями тайны...

Понял тебя, никаких урезаний! Вот статья целиком в Markdown-разметке, с восстановленными листингами асма, очищенная от HTML-тегов, с исправленными переносами и OCR-ошибками:

# КОДЕРАМ

## ZX И ДРУГИЕ ЗАКАРЛЮЧКИ НА BORDER'Е

**(C) Николай Витенко и Денис Токарчук**

Да... Бордюрные эффекты — это всегда что-то, а скорее — нечто, закрытое за тремя печатями тайны. Во всяком случае, для обычного человека, а иногда даже для обычного кодера. Например, я (DWT) недоумевал — зачем эти левые команды в этих пятикилометровых листингах?!? Но методом проб и ошибок, а также с подачи великого покорителя бордюра (как его называет Alex) Николая Витенко (VNN), догадался-таки, что вся эта куча бездейственных (на первый взгляд) команд натыкана везде лишь для задержек, чтобы все на бордюре совпадало точечка-в-точечку... 

А когда разбираешься с бордюром и, как мы всегда и делаем, раскладываешь "по полочкам" — все становится легко, просто и ясно как божий день. Именно это мы и попробуем сделать в рамках этой статьи.

Как известно, художества на бордюре, какими бы они ни были сложными и заковыристыми, делаются практически однотипно — в порт `#FE` засылается какое-то значение (цвет от 0 до 7), выдерживается пауза, затем записывается новое значение, выдерживается пауза, и т.д. "Почему так?" — задаст вопрос начинающий кодер. Да потому, что бордюр — это далеко не обычный спектрумовский экран, и к нему обращаться можно лишь через порт, засылая всего одно значение за один раз. При рисовании бордюра компьютер как бы идет сверху вниз слева направо и заполняет все на своем пути заданным цветом. Однако спектрумовские проггеры усекли это и ухитрились делать на бордюре очень многое, вплоть до рисования там каких-то надписей и бегущих строк.

На бордюре 1 такт задержки равен двум экранным пикселям. Таким образом, минимальной графической единицей в нормальном (не турбо) режиме является линия длиной 24 пикселя :(. Меньше, к великому сожалению, сделать нельзя (минимальная скорость команды засылки в порт `OUT (C),A` / `OUT (#FE),A` = 12 тактов, а $12 \times 2 = 24$). 

Одна строка (бордюрная) равна 224 тактам, значение которой на разновидностях Спектрума разное (бывает и 216, и 232 такта)... Кроме того, количество этих строк на всем экране также варьируется от одного стандарта к другому (на Пентагоне = 320 линий).

Отсюда становится ясно, что любой бордюрный эффект зависит прежде всего от временных тактовых характеристик вашего компьютера. К несчастью, в постсоветских странах наплодилась целая куча модификаций Спектрума, в разной степени отличающихся друг от друга, в частности и этими пресловутыми временными характеристиками (INT — временной интервал (тактовый), за который вырисовывается весь бордюр (хотя правильнее сказать немного по-другому, но у нас статья-то про бордюр...)). 

А к счастью :), уже принята за стандарт, как демо-машина — "Pentagon 128" с ее длиннющим интом (71680 тактов). Именно на этот комп мы и будем ориентироваться, а вы — кодеры (начинающие и не очень начинающие) — сможете, я думаю, подогнать эффект под INT вашего компа.

Но мы отвлеклись. Итак, а как же наш VNN умудряется-таки рисовать нечто (или что-то?) с плавными переходами, без ощущения "квадратности"? Очень (точнее, не очень) просто! У нашего родного Z80 команды по скорости выполнения неравноценны — есть команды по 11, есть по 8 тактов, есть по 10, по 15, по 23, и т.д. Наверное, вы изучали в школе арифметику и можете сказать, как получить разницу в единицу. Правильно, надо вычесть. На бордюре ситуация аналогичная! 

Луч (назовем "идущую" линию на бордюре так) идет слева направо, и ему плевать, что вы и как делаете. Его цель — заполнить бордюр. Ваша цель — сделать что-то на бордюре. Значит, хоть какие вы команды ни суйте в свою программу между засылками значений в порт, на бордюре это будет отражаться лишь длиною той или иной линии. Зная это, можно сделать вывод — делая расстояние между линиями в разное количество тактов (точек), можно добиться даже "овальности" и "раскосости". А такое расстояние как раз и делается этими неравноценными командами!

Приведу несколько примеров:

```assembly
; Пример 1
...
        LD DE,#0700
        LD C,#FE
МЕТКА1
        EI
        HALT
        OUT (C),E
...
        OUT (C),D
        OUT (C),E
        OUT (C),D
        NOP
        OUT (C),E
        JP МЕТКА1

Этой не очень большой процедуркой мы на бордюре выведем белую линию размером 24 пикселя и линию размером 32 пикселя. На месте первых трех точек должна быть процедура активизации прерываний для того, чтобы ничего нашей бордюрной программе "не мешало" (лучше в обработчике прерывания поставить RET). На месте вторых трех точек должна быть процедурка задержки, которая бы "смещала" линии на видимую часть бордюра.

Эта небольшая процедурка красочно демонстрирует, как можно добиться линий разной длины на бордюре. Казалось, NOP — команда бесполезная, однако размещая ее между командой засылки белого цвета и командой засылки черного цвета, мы тем самым делаем белую линию длиннее на $4 \times 2 = 8$ пикселей!

А делая подобные манипуляции с "фоновым" (черным) цветом, мы можем сдвинуть линию на вторую строчку, но со смещением в 1 такт (2 пикселя). Примерно так (если у вас, конечно, Pentagon):

; Пример 2
...
        LD DE,#0500
        LD C,#FE
МЕТКА2
        EI
        HALT
        OUT (C),E
...
        OUT (C),D
        OUT (C),E

        DUP 48   ;-+
        NOP      ; |
        EDUP     ; |- Команды "задержки" (сдвига)
                 ; |
        AND 0    ;-+

        OUT (C),D
        OUT (C),E
        JP МЕТКА2

Троеточия означают то же, что и означали в предыдущем примере.

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

Как это работает: команды задержки "сдвигают" вторую белую линию на ($48 \times 4 = 192$ такта от NOP'ов; AND 0 = 7 тактов) 199 тактов. "А почему не 223, ведь чтобы получить смещение, необходимо именно столько времени?" — опять спросит начинающий. А вы забыли про команды OUT (C),D и OUT (C),E, которые также входят в это время: $12 + 12 + 199 = 223$. Вот так-то.

А теперь попробуйте сделать три, четыре, пять или больше линий, которые по отношению друг к другу были бы сдвинуты на два пикселя (1 такт). Это сделать очень просто. В приложении вы найдете вышеприведенную процедурку, чтобы вы смогли посмотреть, как она работает...

Свою миссию мы считаем выполненной. Как сделать "ZX", вы поняли (я надеюсь), а чтобы вы нас не обматюкали (типа — "А где обещанный ZX на бордюре, ламеры вы этакие!?!!"), в приложении к газете покоится (с миром, аминь :)) ) исходник, который и рисует это пресловутое "ZX". Там есть пара управляющих клавиш (O и P), которыми можно "подогнать" эффект под ваши такты... Исходники, как всегда, в ALASM'е...

Если возникнут какие-либо вопросы, обращайтесь в редакцию — там вам помогут добрым словом и дельным советом...

Поделитесь вашим мнением о статье