Subj не у кого не завалялся? (для картинки)
Желательно фремовый.
Вид для печати
Subj не у кого не завалялся? (для картинки)
Желательно фремовый.
1994. одно время там в лидерах была процедура из terminator-2 длиной 11 байт. щас посмотрю точно скажу
млин, 2 раза ошибся. 1995 год, 2й номер, процедура длиной 33 байта :) а из терминатора - 39 байт
Цитата:
Сообщение от zx-ревю 1995`2б стр. 44
а так ещё автор IceClimber хвалился, что у него самая фастовая и манюсенькая...
а нахрена в вышеприведённой процедуре?
это можно спотойно заменить на простоКод:xor e
and e
xor e
ибоКод:and e
и ещё одно: все эти процедурки по 30 байт будут не очень красиво затемнять картинку, если на ней есть и пэйпер, и инк, и брайт.Код:xor e : and e : xor e == xor a,e : and a,e : xor a,e == ((a ^ e) & e) ^ e
a : 0 : 1 : 0 : 1
e : 0 : 0 : 1 : 1
((a^e)&e)^e : 0 : 0 : 0 : 1
a&e : 0 : 0 : 0 : 1
я вот в таргете делал с табличкой в 256 байт, это конечно не 33 байта, но зато сверхфастово, правильно и красиво выглядит :)
Сорри за кривость и ламость - писалось наживую прям тут в посте /и все это нехило оптимизируемо и по скорости, и по размеру/...Код:LD B,8
F_OUT04
LD HL,#5800
F_OUT03
LD A,(HL)
AND %11000000
LD E,A
LD A,(HL)
AND %00000111
JR Z,F_OUT01
DEC A
F_OUT01 LD D,A
LD A,(HL)
RRCA
RRCA
RRCA
AND %00000111
JR Z,F_OUT02
DEC A
F_OUT02 RLCA
RLCA
RLCA
OR D
OR E
LD (HL),A
INC HL
LD A,H
CP #5B
JR NZ,F_OUT03
HALT
DJNZ F_OUT04
уважаемый Sinus - почему фэйдоут сделанный по подобию будет работать криво?
идея такая (пишу прямо тут, ничего не проверял, и в оригинальный код не смотрел):Цитата:
Поделись?
табличка ATTR_TABLE должна быть расположена по круглому адресу.Код:LD LX,8
ONCE HALT
LD H,'ATTR_TABLE
LD DE,#5800
LOOP DUP 32
LD A,(DE)
LD L,A
LDI
EDUP
JP NZ,LOOP
DEC LX
JP NZ,ONCE
есть одна проблема: если аттрибут будет #FF (хотя нах кому нужет белый папер, белый инк с брайтом и с флэшэм :) ? ), то после LDI рег. H перескочит на другой адрес. но эта проблема надуманная, ибо такое нигде не встречается.
самая главная фишка это конечно таблички :) но я сейчас так не вспомню что я там писал в них. надо код искать.
зы. от DUP 32 можно избавится, это значительно сократит размер процедуры, но зато будет не мега фастово :)
Добавлено через 3 минуты
твой фэйд будет работать прямо, но очень не быстро.Цитата:
уважаемый Sinus - почему фэйдоут сделанный по подобию будет работать криво?
а если сделать его быстро, то он хорошо вырастет в размере :)
А так ли важна тут быстрота то? Ведь аттрибуты за фрейм хоть как кидай, опоздать к инту невозможно. Или при этом ещё что-то считается?
кстати, а вот может взять и посчитать сколько тактов (хотя бы примерно, по бордюру) занимают эти маленькие фэйдилки?
у меня просто нет времени, а было бы интересно :)
Добавлено через 1 минуту
вообще если flash не используется, то табличка может занимать 128 байт, и 21 байт сама процедура (можно сократить ещё если использовать JR а не JP, но будет медленнее)Цитата:
ну уж все равно ИМХА будет занимать меньше чем твой плюс табличка
DUP убери, и будет 21
Самая правильная и быстрая процедура была из терминатора, на которой столько копьев ревюшники сломали.
первой была в этюдах (номер 3 от 94 г):
длина:Код:
DI
LD BC,#0000
LD D,#5B
AGAIN
LD HL,#5800
NEXT_A
LD A,(HL)
CP С
JR Z,NEXT_B
DEC (HL)
NEXT_B
INC HL
LD A,H
CP D
JR NZ,NEXT_A
DJNZ AGAIN
EI
RET
номер 4 за 94 (цитата из терминатора):
честно говоря замучало, но листинги приводились именно так - с десятичными значениями круглых в общем то чисел, привожу тут авторские версии.Код:LD B,7
L4
HALT
LD HL,SPEED
L0
DEC HL
LD A,L
OR H
JR NZ,L0
LD HL,22528
L3
LD A,(HL)
AND 56
JR Z,L1
SUB 8
L1
LD C,A
LD A,(HL)
AND 7
JR Z,L2
DEC A
L2
OR C
LD (HL),A
INC HL
LD A,H
CP 91
JR NZ,L3
DJNZ L4
RET
номер 6 за 94г:
Длина: 40 байтКод:LD B,8
LD C,#C7
LOOP
LD A,C
SUB 8
LD (COM),A
LD C,A
LD HL,22528
LD DE,768
L1
LD A,(HL)
DEFB #C9 ; тут собирается команда res n,(hl)
COM
DEFB 0
LD (HL),A
INC HL
DEC DE
LD A,D
OR E
JR NZ,L1
PUSH BC
LD BC,#1800
L2
DEC BC
LD A,B
OR C
JR NZ,L2
POP BC
DJNZ LOOP
RET
номер 2 за 95г.:
длина: 33 байтаКод:EI
LD E,255
L1
LD HL,22528
LD BC,768
AND A
RR E
L2
LD A,(HL)
XOR E
AND E
XOR E
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,L2
LD B,4
L3
HALT
DJNZ L3
XOR A
CP E
JR NZ,L1
RET
общий недостаток всех процедур: что отдельно ведётся адрес и отдельно ведётся счётчик. О чём собственно указано в ревю номер 3 того же года. то есть окончание становится вида:
и уходят все связанные с DE операции.Код:INC HL
LD A,H
CP #5B
JR NZ,L2
Далее, можно оптимизировать принцип гашения - убрать регистр маски, просто сдвига вправо с потерей вытесненного бита. В результате получается совсем короткая процедура, но от редакции:
длина: 22 байтаКод:PAUSE EQU 4
LD B,8
L1
LD HL,#5800
L2
SRL (HL)
INC HL
LD A,H
CP #5B
JR NZ,L2
LD C,PAUSE
L3
HALT
DEC C
JR NZ,L3
DJNZ L1
RET
лучшая читательская процедура - длина 24 байта, оптимизация достигнута изменением расположения фрагмента задержки:
номер 4 от 95г.:Код:PAUSE EQU 4
LD B,%01111111
L1
LD L,PAUSE
L3
HALT
DEC L
JR NZ,L3
LD H,#58
L2
LD A,(HL)
AND B
LD (HL),A
INC HL
LD A,H
CP #5B
JR NZ,L2
SRL B
JR C,L1
RET
длина: 23 байтаКод:PAUSE EQU 4
CLRSCR
LD C,127
L1
LD HL,23295
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L2
LD B,PAUSE
L3
HALT
DJNZ L3
RRC C
JR C,L1
RET
номер 5 от 95г.:
в этой процедуре используется пара HL на уменьшение, благодарая чему не портится (как при увеличении) лишняя область памяти, кроме того не задаётся содержимое регистра L (собственно длина 22 байта), ведь всё равно этот первый бит отдаётся на мерцание (которое редко используется и находиться должно в нижней части экрана), и кроме того при повторном проходе он будет обнулён.Код:PAUSE EQU 5
LD C,#FF
L1
LD H,#5A
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 2,H
JR Z,L2
SRL C
RET NC
LD B,PAUSE
L3
HALT
DJNZ L3
JR L1
далее процедура от редакции (длина 21 байт):
Эта процедура не зависит от прерываний (EI|DI), так как задержка происходит не через HALT а посредством многократных проходов с одним и тем же байтом-маской.Код:PAUSE EQU 5
LD C,#FF
L3
LD B,PAUSE
L2
LD H,#5A
L1
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L1
DJNZ L2
SRL C
JR C,L3
RET
тут видимо была поставлена большая жирная если не точка, то точка с запятой точно, потому что следующая гасилочка была только в 4-5 от 96г.:
длина самого вывода (начинается с метки FADEOUT) - 20 байт, что само по себе рекордно, правда требуется навесок в виде процедуры подготовки данных (DAL_TBL), кроме того это "правильная" процедура вывода - она гасит как в терминаторе, а не упрощённо по битам.Код:PREPARE
LD HL,DAL_TBL
PREP_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
INC L
JR NZ,PREP_T
FADEOUT
LD D,DAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
LD B,7
W_RAY
HALT
LD HL,#5800
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
INC HL
LD A,H
CP #5B
JR C,ATR_DEC
DJNZ W_RAY
RET
DAL_TBL
DEFS 256
и тут же процедура-рекордсмен, того же автора, длина аж 19 байт (опять же исключая процедуру подготовки), тоже по терминаторскому алгоритму:
Код:PAL_TBL EQU 0-(256*8)
FADEOUT
LD D,PAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
W_RAY
HALT
LD H,#5A
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
DEC HL
BIT 3,H
JR NZ,ATR_DEC
INC D
JR NZ W_RAY
RET
PREPARE
LD HL,PAL_TBL
LD BC,#800
FILL_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
CPI
JP PE,FILL_T
RET
самый лучщий набор зажигалок был в моей View. (смотрите подпись или ищите на zx.da.ru). Код приложен. Я выдёргивал все эти зажигалки из тех же ревюшек, де факто перебрал все какие мог, это лучшие.
Ага, забыл добавить. Там названия зажигалок SCR1, SCR2,... SCR8.
В программе они по рандомайзу запускаются. Где картинка должна лежать очевидно переменная BUFF. Оттуда она дёргается. Большинство зажигалок привязаны к ровным адресам картинки, поэтому адреса для BUFF брать кратные #200.
Хоть бы рассказали, для таких неучей как я, принцип Треминатора что ли...
Ну у меня под рукой всегда ревюшки да и знаю я их почти наизусть :-)
В отечественных "гасилках" "гасили" просто:
ld b,#ff - маска гашения
...
ld a,(hl)
and b - нафигарили по маске
ld (hl),a
...
and a - сбросили флаг переноса
rrc b - вставили его в старший бит, так и получается 255->127->63->...->3->1->0 - то есть 8 (или 9) циклов.
...
jr nz,start
то есть сразу уйдёт флеш, потом яркость, потом фон, потом чернила.
в терминаторе было круче
там было хитрое гашение - там учитывалось что атрибуты идут последовательно, вначале гашение чернил, потом (раз в цикл гашения чернил) гашение фона, делается простым уменьшением байта атрибута. Какие то объекты сразу "погаснут" так как их атрибут сразу станет 0, какие то будут достаточно долго (у которых включена яркость и фон). Итого максимум 256 циклов (djnz в оригинальном алгоритме при установке B в 0).
Даже на ходу соптимизировав код терминатора можно получить такое:
Длина - 20 байт :-)Код:LD DE,#0001
LD B,D
AGAIN
LD HL,#5AFF
NEXT_A
LD A,(HL)
SUB E
ADC A,D
LD (HL),A
NEXT_B
DEC HL
BIT 2,H
JR Z,NEXT_A
HALT
DJNZ AGAIN
RET
Можно на 1 байт сколбасить (19 байт по терминаторскому алгоритму!!!), сделав LD H,#5B вместо LD HL,#5AFF. Всё равно идёт на уменьшение, всё равно проверка идёт на Bit 2,H, однако может испортиться область #5b00-#5bff (так как L может быть равной и 255), однако не надо никаких буферов и предварительных подготовок.
Особое внимание на конструкцию
Её нужно трактовать какКод:SUB E
ADC A,D
Она уменьшает аккумулятор на 1 но не меньше 0.Код:SUB 1
ADC A,0
19 байт :-) можно сократить до 18 сделав то самое LD A,#5B :-)Код:LD B,0
AGAIN
LD HL,#5AFF
NEXT_A
XOR A
ADD A,(HL)
JR Z,$+3
DEC (HL)
NEXT_B
DEC HL
BIT 2,H
JR Z,NEXT_A
HALT
DJNZ AGAIN
RET
Ревюшниками и не снилось :-) Правда а тактах чуток длиннее
А что можете подсказать по поводу пиксельного FADE_IN.
сейчас попробовал делать тупо:
---
AND (IX)
INC IX
OR (HL)
LD (DE),A
----
где IX - адреса из ПЗУ. но получается некрасиво
Попробуй просто следить за тем, что бы ix не выходил за пределы относительно нормального рандомного битового поля ПЗУ, например:
Оптимально, имхо, 5 таких итераций, затем ldir-ом оригинальную картинку в экран/буфер. Можно еще массив случайных чисел самому генерировать в озу перед выводом на экран картинки. Ну и, естественно, если целый экран фейдится, желательно использовать промежуточный буфер и последующий быстрый вывод на экран, что бы не было заметно, как фазы прорисовываются.Код:....
;инициализация ix, что бы каждую итерацию адрес был разный
ld a,r
ld xl,a
;в районе адреса #0600 в пзу 48-го бейсика относительно хорошие "рандомные" данные для нашего случая
ld xh,#06
....
inc ix
ld a,xh
cp 9
;что бы ix далеко не убегал
jr nz,met1
ld xh,#06
met1 ....
Только что добили все эклетронные номера ZX Ревю , там в этюдах дофига всяких проявлялок экрана.
2Kurles: Спасибо, идею понял, реализовал, то что надо!
2newart: Вам отдельный респект, отличный проект, давно читаю. Одного только не хватает у вас, (или я не нашел?) поиска по сайту (по текстам статей). Облако тегов - не то