ZXNet эхоконференция «code.zx»


тема: Кидаю чушь в массы.



от: Aleksey Malov
кому: All
дата: 30 Mar 2000
Приветствую тебя, All!

Генератор chunky 8*8 методм ordered dithering.
Попробуйте сделать адрес chtab равным #4000.
В процедуре я пожертвовал скоростью ради объема. Hе сложно увеличить скорость,
хотя при этом увеличится длина процедуры на несколько байт.

ld hl,chtab;адрес chunky table должен быть кратен #800
cls ld (hl),0;очищаем таблицу
inc hl
bit 3,h
jr z,cls;если адрес расположения
;chunky table равен #x800,то
;поставить jr nz,cls
dchunk ld e,l
dchun1 ld d,e
ld h,3
dch1 xor a;в этом цикле определяются
sub d;координаты
rrc d;точки
rrc d;которыю
rra ;надо поставить
rl c ;в chunky table
rra
rl b
dec h
jr nz,dch1
;теперь в C-y, в B-X
ld a,c
inc a;можно убрать, но тогда
;точка будет поставлена
;на пиксел выше, чем надо
and 7
add a,chtab/256
ld h,a
ld a,#40;теперь определяем
;бит, соответствующий
;данной точке
rrca:djnz $-1
xor (hl);именно Xor
ld (hl),a
inc e
jr nz,dchun1
dec l
jr nz,dchunk

длина процедуры 49 байт, хотя, возможно, что можно попытаться сделать короче.

Процедура расчета chunk'ов 4*4 by MEGUS/BW/XPJ.
LD HL,CH_IMG;запакованная таблица chunk'ов
LD DE,TEMP_BUFFER;временный 64
;байтовый буффер TEMP_BUFFER=#xx00
LD B,32
;распаковываем таблицу во временный буффер
L0 LD A,(HL):RLD:LD (DE),A:INC DE
LD A,(HL):RLD:LD (DE),A:INC DE
INC HL
DJNZ L0
LD H,D
LD L,B
LD E,B
LD BC,CHUNKY_TB;адрес 1k таблицы
;chunk'ов равный #xx00
L1 LD A,(DE)
XOR (HL)
AND 15
XOR (HL)
LD (BC),A
INC BC
INC L
LD A,L
AND 15
JR NZ,L1
INC E
LD A,E
AND #F0
LD L,A
SUB #40
JR NZ,L1

;теперь создаем таблицу указателей на chunky, если надо, конечно.
;после предыдущей процедуры A=0
LD H,CHUNKPTR/256;в таблице
;указателей содержатся младшие байты
;адресов chunk'ов
LD D,H
I_C_PTR LD B,16
LD L,D
I_C_PT1 LD (HL),A
INC A
INC L
DJNZ I_C_PT1
INC H
OR A
JR NZ,I_C_PTR
ret

;запакованная таблица chunky.
CH_IMG DW #AA08,#AAAA,#FFBE,#FFFF
DW #0000,#5544,#5555,#FFDD
DW #2A02,#AAAa,#BFAB,#FFFF
DW #0000,#1501,#5555,#7F57
Длина процедуры с таблицей: 64+32=96 байт.

Процедуры генерации синусных таблиц.
Основаны на использовании второй производной. Данные в тaблице
SINTAB хрaнятся в виде двухбитовых приращений производной синусной
функции, увеличенных на единицу.
Следующая процедура генерирует 512 байтовую знаковую таблицу
синусов с амлитудой 255:

LD HL,SINTAB-1 ;таблица данных
LD DE,SINUS+255;таблица синусов, SINUS=#xx00
LD BC,#06FA;B=-C=разность первых двух значений оригинальной таблицы
синусов.
INS INC E ;расчет нового значения
LD A,E
AND 3 ;проверка на конец байта
JR NZ,$+3;таблицы данных
INC HL ;переходим к новому байту
XOR A ;взяли приращение
RLC (HL) ;разности
RLA ;из
RLC (HL) ;таблицы
RLA
DEC A ;теперь приращение=-1..+2
ADD A,B ;прибавили его к текущей
LD B,A ;разности
ADD A,C ;и к текущему значению
LD C,A ;синуса
CALL INSSR;поместили в память
;положительное и отрицательное
;значения синуса в I и III четверти
PUSH DE
LD A,128;теперь помещаем +sin и -sin
SUB E ;во II и IV четверти
LD E,A
LD A,C
CALL INSSR
POP DE
BIT 6,E ;проверка на окончание
JR Z,INS
;здесь можно поставить ret, либо разместить какие-нибудь свои процедуры
INSSR LD (DE),A
SET 7,E
NEG
LD (DE),A
INC D
SBC A,A
LD (DE),A
RES 7,E
XOR A
LD (DE),A
DEC D
RET
SINTAB ;упакованные данные
DB #58,#56,#15,#55
DB #49,#21,#85,#52
DB #21,#54,#88,#54
DB #85,#52,#15,#48,#55
ДЛИНА ПРОЦЕДУРЫ ВМЕСТЕ С ТАБЛИЦЕЙ 77 БАЙТ.

Следующая процедура создает 256-байтовую знаковую таблицу 8-битовых
синусов с амплитудой 127. Она короче опубликованной в BORNDEAD 75-байтовой
процедуры создания беззнаковых синусов.

LD HL,SINTAB-1 ;таблица данных
LD DE,SINUS+255;таблица синусов
;SINUS=#xx00
LD BC,#03FD;B=-C=разность первых двух
;значений оригинальной таблицы синусов.
INS INC E ;расчет нового значения
LD A,E
AND 3 ;проверка на конец байта
JR NZ,$+3;таблицы данных
INC HL ;переходим к новому байту
XOR A ;взяли приращение
RLC (HL) ;разности
RLA ;из
RLC (HL) ;таблицы
RLA
DEC A ;теперь приращение=-1..+2
ADD A,B ;прибавили его к текущей
LD B,A ;разности
ADD A,C ;и к текущему значению
LD C,A ;синуса
LD (DE),A;занесли в I четверть
PUSH DE
LD A,#80
SUB E
LD E,A
LD A,C
LD (DE),A;во II четверть
SET 7,E
NEG
LD (DE),A;в IV четверть
POP DE
SET 7,E
LD (DE),A;в III четверть
RES 7,E
BIT 6,E
JR Z,INS; конец процедуры
...
DEFB #55,#61,#55,#55
DEFB #49,#52,#48,#86
DEFB #15,#55,#49,#18
DEFB #58,#49,#48,#61,#55

Длина процедуры с таблицей: 51+17=68 байт

На основании данного алгоритма можно построить программу, создающую
таблицу тангенсов для углов от 0 до 31 градусов (в Wolf-подобной части MALADY
4k intro by MEGUS/BW/XPJ используется именно эта процедура, правда
немного упрощенная для получения беззнаковых значений) или таблицу любой
другой функции, вторая производная которой находится в интервале [-1..2],
хотя, строго говоря, понятие производной не применимо к дискретным
последовательностям. Под словом "вторая производная" следует понимать
разность приращений функции.

Альтернативный вывод Chunk'ов.

Опубликованный в BORNDEAD#5 способ вывода chunk'ов несомненно очень
крут (80 тактов на 2 chunky), однако обладает двумя недостатками: размер 16
килобайт и, следовательно, практическая невозможность вывода в 2 экрана.
Предлагаемый мною способ, основан на BORNDEAD'овском, но занимает 8
килобайт, а значит может преспокойно сидеть в 7 странице и кидать
данные в #c000 и в #4000. Максимальное время одного цикла: 82 такта,
минимальное - 70 (!) тактов на пару chunk'ов.
Chunky имеют четные номера с #е0 по #fе. Для работы необходимо подготовить
в 7 странице следующее:

#E070: LD H,A
LD (HL),#XX;3
INC H ;раза
LD (HL),#XX
INC L
RET
#E07E: ... ;аналогично

#E0E0: JR #E070
JR #E07E
...
#E0EE: JR #E0D2
JR #E100
JR #E10E
...
#E0FE: JR #E162
#E100: LD H,A
LD (HL),#XX;3
INC H ;раза
LD (HL),#XX
INC L
RET
#E10Е: ... ;аналогично

ну, вы поняли.
Вместо #XX надо поставить байт,
соответствующий строке пары выводимых
chunk'ов, причем, вместо LD (HL),#XX при
определенных значениях #XX поставить
следующее:

#XX=#00 => LD (HL),B
#XX=#FF => LD (HL),C
#XX=#AA => LD (HL),D
#XX=#55 => LD (HL),E
Вывод же осушествляется следующим
образом:
c2pout:
ld (STK+1),SP
ld hl,screen_addres
LD SP,CHSCR;CHUNKY SCREEN
LD BC,#00FF
LD DE,#AA55
RET
C2PRT LD HL,C2PRT
PUSH HL
STK LD SP,0
RET

В CHSCR в конце каждой строки стоит адрес следующих кусков кода:
ld a,h
add a,NN ;NN - разность старших байтов адресов (n+1)-oй и n-ой строк в экране
ld l,MM ;MM - мл. байт адреса начала следующей строки
ld sp,адрес следующей строки в chunky buffer
ret
в конце chunky buffer поместить адрес C2PRT.

Процедура нахождения наибольшего общего
делителя двух чисел (может быть,
кому-нибудь пригодится):
;на входе:HL,DE - два числа не равные нулю
;на выходе: DE - наиб. общий делитель.

FIND_NOD
JR NO1
NOT ADD HL,DE
EX DE,HL
NO1 OR A
NOD SBC HL,DE
JR C,NOT
JR NZ,NOD
RET

Желаю вам здоровья, счастья и творческих узбеков.
Aleksey Malov aka VIVID/Brainwave.




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Реклама - рекламые объявления.
Игры - Прохождение игры Times of Lore.
Паралельные измерения - 10 легендарнейших компьютеров на все времена.
Письмо №309 - Свердловская обл, г Лесной
Обзор - обучающие программа для детей: "ЗВУК", позволяющая оцифровывать аналоговые сигналы.

В этот день...   19 апреля