TEST LINE
(c) Gris
Здравствуйте многоуважаемые читатели.
Сейчас я вам расскажу, тем, кто не
знает, как программно определить, сколь-
ко тактов в строке у машины, оснащённой
портом #FF.
Немного истории. Жутко мне понрави-
лась игрушка Ивана Крутя "Тетрис-
Сокобан", может видели ее (там ещё на
бордюре надпись "TESO"). Так как у меня
Scorpion, эта надпись у меня злейше "ко-
зявилась", что меня очень доставало.
Поэтому я решил переделать вывод на бор-
дюр. Со временем у меня получилось и я
захотел сделать ремикс этой игры с
настраиваемым бордюрным эффектом, но тут
выяснилось, что даже у Scorрion'ов длина
строки различается. Со слов ZS'а су-
ществуют следующие варианты длин строк
экрана: 216, 224, 232 такта. Я подумал и
решил сделать автонастройку для машин, в
которых есть порт #FF.
Рассказывать о построении экрана я не
буду, - смотрите ZX-REVIEW, электронные
номера. Суть данного метода проста, хотя
наши кодеры не поняли мою реализацию
оного. Сущность порта #FF состоит в том,
что через него читаются атрибуты, кото-
рые в момент чтения рисуются лучом на
экране. Для определения длины строки в
тактах необходимо вычислить цикл
прорисования линии. Сделать это можно,
используя различные атрибуты. ZS предла-
гал отметить атрибутом начало экрана
(адрес 22528=#5800) и читать порт #FF до
тех пор, пока не появится этот атрибут
дважды, мол, обязательно мы на него по-
падём. Я же считаю, что нельзя полагать-
ся на случай, ведь луч может и переско-
чить этот атрибут. Поэтому надо некото-
рую часть экрана (строчки 4, я думаю,
хватит) заполнить атрибутами,
индивидальными для каждого столбца зна-
комест, т.к. луч от начала экрана может
попасть и на 1-е, и на 2-е, и на другое
знакоместо, в пределах первых несколь-
ких. Но остальные знакоместа нам нужно
тоже особо обозначить, поскольку наша
задача на этом этапе состоит в определе-
нии места экрана, с которого мы начнём
отсчитывать ход луча. Краткий алгоритм:
1. Заполняем область атрибутов
увеличивающимся значением от #00 до #1F
для каждой строки.
2. Формируем п/п чтения из порта -
блок команд INI, штук 100 (можно и мень-
ше, сами подберете) с RET на конце.
3. Делаем EI: HALT и пропускаем вер-
хнюю часть бордюра.
4. Передаем управление п/п, из п.2
5. Анализируем полученные в результа-
те п.4 данные (блоки #FF с небольшим ко-
личеством индивидуальных атрибутов):
- конец каждого блока "#FF'ов" озна-
чает переход к новой линии изображения;
- первый байт, отличный от #FF и ад-
рес, в котором он встретился, нужно
"запомнить";
- ищем следующий такой же байт и
определяем сколько до него байт от пер-
вого, вычислив таким образом, сколько
раз выполнилась команда INI, пока луч
рисовал одну линию;
- умножаем полученное число на дли-
тельность команды INI - на 16 и делим на
число блоков #FF - число линий.
А вот реализация приведённого алго-
ритма ("извинтиляюсь", программа не
оптимизирована):
;(C) Gris 24.12.2000г.
;Test tacts in screen line.
;Enter: no data,
;Exit: A=number of tacts in line.
ORG #6000
DELAY EQU #0210
ReadFF EQU #8000
CALL FilAtr
CALL MakeINI
EI
HALT
DI
WAIT LD BC,DELAY;#0210
WTLP DEC BC
LD A,B
OR C
JR NZ,WTLP
LD HL,ReadFF
LD C,#FF
CALL ReadFF
CALL ANALIZ
EI
RET
FilAtr PUSH BC
PUSH HL
LD HL,#5800
LD B,8
MFilLP PUSH BC
LD B,#20
LD C,0
FilLP LD (HL),C
INC HL
INC C
DJNZ FilLP
POP BC
DJNZ MFilLP
POP HL
POP BC
RET
MakeINI LD HL,ReadFF
LD A,#ED; INI
LD C,#A2;
LD B,#0
MKLP LD (HL),A
INC HL
LD (HL),C
INC HL
DJNZ MKLP
LD (HL),#C9
RET
ANALIZ LD HL,ReadFF
LD BC,0
LD A,#FF
L1 CP (HL)
JR NZ,AN1
INC HL
JR L1
AN1 LD A,(HL);LOAD ZM
LD D,A; STORE ZM TO D
INC HL
INC B
L2 LD A,(HL)
CP D
JR Z,AN2
CP #FF
JR Z,AN3
E_AN3 INC B; COUNT ALL BYTES
INC HL
JR L2
AN3 INC C; COUNT LINES
LD A,#FF
L3 CP (HL)
JR NZ,L2
INC B; COUNT ALL BYTES
INC HL
JR L3
AN2 LD H,0
LD L,B
DUP 4 ;
ADD HL,HL;MUL 16 (INI time).
EDUP ;
EX DE,HL
LD H,0
LD L,C
CALL DIVB2
LD A,E
RET
;Здесь использована часть мат.
;библиотеки В. Медноногова.
;MATHEMATICAL LIBRARY MATH-ZX
;(C) Coрer Feet
FREE16 DEFS 16
DIVB LD D,0 ;E/L--E(MOD in D)
DIVB2 PUSH HL ;DE/L--E
PUSH BC
LD B,8
EX DE,HL
LD D,E
LD E,0
DIV1B OR A
RR D
RR E
SBC HL,DE
JR NC,MDIVB
ADD HL,DE
MDIVB RLA
DJNZ DIV1B
CPL
LD D,L
LD E,A
POP BC
POP HL
RET