Like there is a question. Player for 4k int. Help.
ZXNet echo conference «real.speccy»
From Ilya Kudryavcev → To All 15 October 2002
I had nothing to do, and so I decided to come up with a certain music format so that it would be strongly compressed by a RIP-type packer. With the ability to use your own
short and rather fast music player. Direct road to 4K interiors. Already tested
on 3D-Lame. 17 patterns fit into 1024 bytes together with the player, RIP packaging.
After depacking, the music takes about 9 kilos, and the player about 500.
The algorithm of work is very simple.
1. Take the music in PT3.xx format, and do everything there processing patterns.
Specifically, I digitalize the music channel by channel. Each pattern consists of channels, which
tend to be repeated in several patterns, and maybe in all of them :)
Depends on the imagination of the author of the music :)
That is. In the end, we get a list of “original” channels in the music.
2. We begin to play them all, and copy each int value of this channel into memory. Well, this is the usual way :)
3. After catching the end of the channel :) I begin to compress it, the whole algorithm will be clear from the end of the letter.
4. I build a table of channels in memory, in the order of the original module, so to say a table of patterns, only immediately in the form of channel addresses.
That’s it I want to give you a player for your consideration so that you can shorten it if possible, because I’m already tired. And most importantly, tell me if this is necessary.
I don’t throw away the converter itself, because I don’tI've still finished it, but look at the player.
You need to cut it from the place where it's written about it. The initial installation code doesn't bother me.
By the way, right now it takes up 418 bytes, but while I was writing all this crap, I noticed
one place where you can reduce the byte by 5-8. But this is not the point.
=== Start of PLAY_SP.$C! ===
TO_PAG EQU #8000 ; Module loading address
ORG TO_PAG,#03
; INCBIN "KUKA.C"
ORG #61A8
JP START
CHN DEFB "ACB" ; Selecting the channel layout
START
;----------------------------------------------
;The actual procedure for setting the player to
;the desired channel layout AY
;The procedure is completely optional.
;By default the player is set to ABC
;----------------------------------------------
LD HL,CHN
LD A,(HL)
SUB "A"-8
LD (CP_A+1),A
SUB #08
ADD A,A
LD (CP_AF+1),A
INC HL
LD A,(HL)
SUB "A"-8
LD (CP_B+1),A
SUB #08
ADD A,A
LD (CP_BF+1),A
INC HL
LD A,(HL)
SUB "A"-8
LD (CP_C+1),A
SUB #08
ADD A,A
LD(CP_CF+1),A
;----------------------------------------------
;All sorts of bullshit, such as creating an interrupt table
;Some installation and polling of the space.
;All this bullshit doesn’t bother me at all
;----------------------------------------------
LD BC,#7FFD
LD A,#13
OUT (C),A
XOR A
LD H,'TO_PAG
LD L,A
LD (PL_AD+1),HL
LD (PLAYS+1),A
LD H,#5B
LD D,H
LD E,L
INC E
LD B,#01
LD C,L
LD (HL),#5C
LDIR
LD (HL),#5C
LD A,#C3
LD (#5C5C),A
LD HL,INT
LD (#5C5D),HL
LD A,#5B
LD I,A
IM 2
EI
KEY2 LD BC,#7FFE
IN A,(C)
BIT 0,A
JR Z,EXIT
EI
HALT
JR KEY2
EXIT LD A,#3F
LD I,A
IM 1
EI
LD DE,#0D00
ZATYK LD BC,#FFFD
OUT (C),D
LD B,#BF
OUT (C),E
DEC D
JP P,ZATYK
RET
;----------------------------------------------
;Interrupt procedure.
;Delay is onin order to see on the border
; how many ticks the player is eating.
;---------------------------------
INT DI
LD HL,0
LD DE,0
LD BC,1500
LDIR
LD A,1
OUT (#FE),A
CALL PLAYS
LD A,7
OUT (#FE),A
EI
RET
;----------------------------------------------
;The player itself.
;That’s actually what I would like to shorten.
;If anything...
;------------------------------------------------------------
PLAYS
LD A,#00 ;Let’s check whether it is necessary to change
OR A ;pattern. This location changes
JR NZ,PLAY_N ;the player itself.
PILA LD (PIL+1),SP
PL_AD LD SP,TO_PAG
LOOP POP HL ;
LD A,H ;If the registers are in #0000, then goes
OR L ;Selecting an address in the channel table,
JR NZ,NO_LOOP ;for looping - LOOP
POP HL ;Actually took the address
LD SP,HL ;And went to initiate channels from it.
JR LOOP ;We worked the cycle in the music - LOOP
NO_LOOP
LD (CHN_A+1),HL ;Address of channel A of the current path.
POP HL
LD (CHN_B+1),HL ;Address of channel B of the current path.
POP HL
AAS1 LD(CHN_C+1),HL ;Channel address From the current path.
LD (PL_AD+1),SP ;Save channel table address
LD (PLAYS+1),A ;Set the flag, do not change the pattern.
PIL LD SP,#0000
PLAY_N
INT_A LD HL,#0001 ;The procedure for passing ints for
DEC HL ;Channel A. Sometimes it is necessary.
LD (INT_A+1),HL
LD A,H
OR L
JR NZ,INT_B
INC L
LD (INT_A+1),HL
CHN_A LD HL,#0000 ;Actually the address current
BIT 7,(HL) ;channel control byte A
JR Z,PL_AD_A ;Special command or end
CP_AF LD A,#00 ;Deciphering and entering information
CP_A LD E,#08 ;Into the specified channel.
CALL ZALUPA2
EP_A LD (CHN_A+1),HL ;Save channel address
INT_B LD HL,#0001 ;Same as for channel A
DEC HL
LD (INT_B+1),HL
LD A,H
OR L
JR NZ,INT_C
INC L
LD (INT_B+1),HL
CHN_B LD HL,#0000
BIT 7,(HL)
JR Z,PL_AD_B
CP_BF LD A,#02
CP_B LD E,#09
CALL ZALUPA2
EP_B LD (CHN_B+1),HL
INT_C LD HL,#0001 ;Also For channel C
DEC HL
LD (INT_C+1),HL
LD A,H
OR L
RET NZ
INC L
LD (INT_C+1),HL
CHN_C LD HL,#0000
BIT 7,(HL)
JR Z,PL_AD_C
CP_CF LD A,#04
CP_C LD E,#0A
CALL ZALUPA2
EP_C LD (CHN_C+1),HL
RET
PL_AD_A
CALL DECODE ;Декодеp спец команд
LD (INT_A+1),BC
JR EP_A
PL_AD_B
CALL DECODE
LD (INT_B+1),BC
JR EP_B
PL_AD_C
CALL DECODE
LD (INT_C+1),BC
JR EP_C
DECODE
LD B,A
LD C,#01
INC HL
LD A,(HL)
CP #FF
JR NZ,CH_COM
DEC_1
LD (INT_A+1),BC ;Пpишли сюда? Установили
LD (INT_B+1),BC ;Пpопyскалки интов в 1
LD (INT_C+1),BC ;И пошли на выбоp нового
POP AF ;Паттеpна
JP PL_AD
CH_COM
BIT 7,A
RET NZ ;Hет ни какой команды
; JR Z,INTS_S
; RET
; BIT 6,A
; CALL Z,SK_PATS
INTS_S
AND %00000011 ;Полyчение количества
LD B,A ;интов для пpопyскалки
INC HL
LD C,(HL)
NO_PER
INC HL
RET
ZALUPA2
LD (REG_MT+1),A
INCA
LD (REG_ST+1),A
LD A,E
LD (REG_VOL+1),A
ZALUPA
LD A,(HL)
INC HL
CP #BF
RET Z
;10 - bit number
;----------------
;00 - change TONE ml. byte (1 byte)
;01 - volume change and TONE st. byte (1 byte)
;10 - full change TONE ml. byte + Vol + st. byte (2 byte)
;11 - no change
;
;IF BIT = 1 THEN FLAG = C
RRA
JR C,TN_1 ;0 BIT
RRA
JR C,FL_TV ;1 BIT
CALL ML_TONE
JR ENV
FL_TV
CALL ML_TONE
JR TN_2
TN_1
RRA ;1 BIT
JR C,ENV
TN_2 CALL ST_VL_TONE
;32
;----------------
;00 - change ml.byte Envelope FRQ (1 byte)
;01 - change st.byte Envelope FRQ (1 byte)
;10 - full change Envelope FRQ (2 byte)
;11 - no change
ENV
RRA
JR C,ENV_1
RRA
JR NC,ENV_3
ENV_2
CALL ML_FRQ
JR ENV_0
ENV_3 CALL ML_FRQ
JR MIX
ENV_1
RRA
JR C,MIX
ENV_0
CALL ST_FRQ
;54
;----------------
;00 - change Envelope Period (1 byte)
;01 - change NOISE and MIXER (1 byte)
;10 - change Envelope Period AND Noise AND Mixer (2 byte)
;11 - no change
MIX
RRA
JR C,MIX_1
RRA
JR NC,ENV_PER
MIX_FL
CALL ENV_PER
JR NS_MIX
MIX_1
RRA
RET C
;------------------------------------------
;6 %00011111
;7 %00100100 only two bits (2 and 5)
;MIXED
;6 %00011111
; % ^- Mixer tone (bit 2 reg7)
; %^-- Mixer noise (bit 5 reg7)
;------------------------------------------
NS_MIX
EX AF,AF'
LD D,(HL)
LD E,#06
CALL OUTS
LD A,(REG_VOL+1)
CP #09
JR C,MIX_A
JR Z,MIX_B
LD A,D
AND %01000000
RRCA
RRCA
RRCA
RRCA
LD B,A
LD A,D
AND %10000000
RRCA
RRCA
OR B
LD (MIXER_C+1),A
MIXER
MIXER_A LD A,#00
MIXER_B OR #00
MIXER_C OR #00
LD E,#07
MIXUS CALL TO_PORT
OUT (C),A
EX AF,AF'
RET
MIX_A
LD A,D
AND %01000000
RLCA
RLCA
LD B,A
LD A,D
AND %10000000
RRCA
RRCA
RRCA
RRCA
OR B
LD (MIXER_A+1),A
JR MIXER
MIX_B
LD A,D
AND %01000000
RLCA
RLCA
RLCA
LD B,A
LD A,D
AND %10000000
RRCA
RRCA
RRCA
OR B
LD (MIXER_B+1),A
JR MIXER
ML_TONE
REG_MT LD E,#04
JR OUTS
ML_FRQ
LD E,#0B
JR OUTS
ST_FRQ
LD E,#0C
JR OUTS
ENV_PER
LD E,#0D
OUTS CALL TO_PORT
OUTI
RET
TO_PORT
LD BC,#FFFD
OUT (C),E
LD B,#BF
RET
ST_VL_TONE
LD D,A
EX AF,AF'
LD A,D
RLA
RLA
AND %01000000
RLCA
RLCA
LD C,A
LD A,(HL)
INC HL
LD D,A
OR A
RLA
OR C
; AND #0F ;!!!
REG_ST LD E,#05
CALL TO_PORT
OUT (C),A
LD A,D
RRCA
RRCA
RRCA
; AND #1F
REG_VOL LD E,#0A
JR MIXUS
END
; 76543210
;%00000000
;
;10 - bit number
;----------------
;00 - change TONE ml. byte (1 byte)
;01 - volume change and TONE st. byte (1 byte)
;10 - full change TONE ml. byte + Vol + st. byte (2 byte)
;11 - no change
;
;32
;----------------
;00 - change ml.byte Envelope FRQ (1 byte)
;01 - change st.byte Envelope FRQ (1 byte)
;10 - full change Envelope FRQ (2 byte)
;11 - no change
;54
;----------------
;00 - change Envelope Period (1 byte)
;01 - change NOISE and MIXER (1 byte)
;10 - change Envelope Period AND Noise AND Mixer
;11 - no change
;6
;----------------
;0 - 0 bit from Volume
;7
;----------------
;1 - no change
;0 - spec command in next byte
;Next byte
;7 = 0 - skip ints (1)
;6 = 0 - play from (2b), ints (2b)
;5 =
;4 =
;3 =
;2 =
;1 - two bits from st byte INTS skip counter
;0 - ///
;TONE and Volume
;-------------------------------
;4 %11111111
;5 %00001111
;A %00011111
;mixed reg5 and regA
;%11111111
; ^^^^ - volume
; ^^^^ - FRQ st. byte
;-------------------------------
;ENVELOPE FRQ
;-------------------------------
;B %11111111
;C %11111111
;-------------------------------
;PERIOD
;D %00001111
;6 %00011111
;7 %00100100 only two bits (2 and 5)
;MIXED
;6 %00011111
; % ^- Mixer tone (bit 2 reg7)
; %^-- Mixer noise (bit 5 reg7)
=== Конец PLAY_SP.$C! ===
С yважением HIMIK'S ZxZ/PoS-WT.