Жизнь как зебра
И я думаю, что продолжение афоризма легко прочитать. А пока я расскажу о создании 1К. Идея возникла совершенно случайно, когда я готовил работу Stripes к Di:Halt 2015 года. Кроме готовой работы остался один исходник с необычным эффектом, возможно, что в алгоритм вкралась ошибка. Вот эту ошибку я решил развить в тот момент, когда увидел, что работ категории 1К не было.
Хорошо, у меня был простой музончик, который когда-то написал splin7er(спасибо, Роман!) и я решил пойти ва-банк и втиснуть музыку. Что? Большой размер мелодии и код проигрывателя? Не страшно, у меня есть выигрыватель!
Довольно петросянства, взглянем на код:
Этот замысловатый код генерирует спрайт из полос, причем полоски отображаются зеркальнымиdevice zxspectrum128
ORG #6000
runi:
ld hl,$8000
ld de,$00FF
ld bc,$00FF;FF00
tt2:
push hl
tt1:
ld (hl),d:inc l
ld (hl),e:inc l
bit 4,l
jr z,tt1
ex de,hl
add hl,hl
jr nc,no_rot
set 0,l
no_rot:
ex de,hl
tt3:
ld (hl),c:inc l
ld (hl),b:inc l
bit 5,l
jr z,tt3
or a
rr b
rr c
jr nc,no_7b
set 7,b
no_7b:
pop hl
inc h:jr nz,tt2
ld hl,$800FА вторая часть заполняет полосы, таким образом вышло от что:
ld bc,$0201
rrlp2:
push hl,bc
rrlp1:
ld a,(hl):or c:ld (hl),a;добавить
rrc c
jr nc,noinchl1
inc hl
noinchl1:
djnz rrlp1
pop bc,hl
inc h
rlc c
jr nc,noinchl2
dec hl
noinchl2:
inc b,b
jr nz,rrlp2
;-----------------------sine precalcНаверное. одним решением будет использование калькулятора для вычисления синуса, но я противник долгих ожиданий depacking/decrunching..
ld hl, unk_63A6
ld de, #7c00
ld c, e
ld xl, 10h
loc_600F:
ld b, 4
loc_6011:
xor a
rl (hl)
rla
rl (hl)
rla
add a, c
ld c, a
ld (de), a
inc e
djnz loc_6011
inc hl
dec xl
jr nz, loc_600F
ld h, d
ld l, e
loc_6027:
ld (de), a
inc e
dec l
ld a, (hl)
jr nz, loc_6027
loc_602D:
ld a, (hl)
; neg
ld (de), a
inc de
inc l
jr nz, loc_602D
;----------------------------
ld hl,unk_63A6Теперь инициализация прерывания для воспроизведения музончика и работа интро.
ld b,32
frmlp:
ld (hl),$ED:inc hl
ld (hl),$A0:inc hl
djnz frmlp
ld (hl),$C9:inc hl
; jr $
;----------------------------
diЭто таблица для генерации синуса
ld a,$5B,i,a
im 2
ld hl,INTVEC,($5BFF),hl
doi:ei:halt
ld hl,#4020
rv: ld de,0000
inc e,e
dec d,d,d
ld (rv+1),de
ld ixl,$B0
drlp:
push hl
ld h,$7C
ld l,e
ld a,(hl)
ld l,d
add a,(hl)
pop hl
push de
push hl
sra a
or $80
ld d,a,e,0
ex de,hl
call unk_63A6
pop hl
pop de
INC h:LD A,h
AND 7:jr nz,$+12
LD A,L:ADD A,#20:LD L,A:jr c,$+6
LD A,H:SUB 8:LD H,A
inc e,e,e
dec d,d
dec ixl
jp nz,drlp
jp doi
;----------------------------
INTVEC
PUSH AF,BC,DE,HL
call play
POP HL,DE,BC,AF
EI:RETI
unk_63A6:А где музон спросите вы, если не уснули после чтения исходника? А музон где-то там, наверное легко догадаться об этой таинственной технологии.
db 026h
db 066h
db 066h
db 066h
db 065h
db 096h
db 059h
db 055h
db 095h
db 055h
db 015h
db 045h
db 011h
db 010h
db 041h
db 0
end
display /d,runi
display /d,end-begin
savesna "!void.sna",runi
savebin "z0rb.bin",begin,end-begin
song:incbin "tune.psg"
db $FD
;---------------play PSG dump-----------+16 из процедуры(смещение в .psg) я убрал, обрезал 16 байт заголовка для того, чтобу втиснуть код при упаковке zx7. Нет, пакер не выход, конечно, но расчет на сжатие был имеенно таким. Было бы здорово, если нашелся умелец и написал простейший 1K tracker, но об этом приходится мечтать.
play:
psgplay:ld a,1:or a:jr z,psga
dec a:ld (psgplay+1),a:ret
psga: ld hl,song;+16
dumpreg:
ld e,(hl):inc hl
ld a,e
cp #FF:jr z,stoplay
cp #FE:jr nz,nogetwait
ld e,(hl):inc hl;(hl)*4
ld a,e
add a,a
add a,a
ld (psgplay+1),a:jr stoplay
nogetwait:
cp #FD:jr z,stoplay2
ld bc,0xfffd
out (c),e
ld e,(hl):inc hl
ld b,0xbf
out (c),e
jr dumpreg
stoplay2:
ld hl,song;+16
stoplay:
ld (psga+1),hl
ret