He jugado un poco con una forma de generar "música" o ruidos (como preferíais
), mediante una formula matemática.
Lo vi hace un tiempo en un blog y he probado con algunas de las formulas, con el AY del MSX.
http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.htmlNo suena igual por la velocidad de ejecución, pero adaptándolas se puede conseguir resultados curiosos.
Os dejo el código en C, por si queréis probarlo o adaptarlo a ASM.
y un par de ROMs con las dos formulas.
/* ========================================================================== */
/* */
/* sound_01.c */
/* by 2012 aorante */
/* */
/* Description: */
/* Algorithmic symphonies */
/* ========================================================================== */
// http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html
__sfr __at 0xA8 g_slotPort;
#define HALT __asm halt __endasm
#define BASE5 0x1800
typedef enum {false = 0, true = 1} boolean;
// unsigned integer
typedef unsigned int uint;
// unsigned char
typedef unsigned char byte;
byte sound_get(byte reg);
void sound_set(byte reg, byte val);
void setChannel(byte NumChannel, boolean isTone, boolean isNoise);
void vpoke(uint address, byte value);
void vprint(byte posx, byte posy, char* text);
void main(void) {
__asm
di
ld sp, (#0xFC4A)
ei
__endasm;
g_slotPort = (g_slotPort & 0xCF) | ((g_slotPort & 0x0C) << 2);
start();
}
void start()
{
uint t;
uint freq;
sound_set(8,15);
setChannel(0,true,false);
vprint(4,15,"Algorithmic Symphonies 1");
for(t=0;t<65535;t++) //65536
{
//freq=t*(t>>11&t>>8&123&t>>3); //by tejeez
freq=(t*(t>>11&t>>8&123&t>>3))>>6; //01
//freq=(t*(t>>5|t>>8))>>(t>>16); // by tejeez
//freq=((t*(t>>12&t>>6))>>(t>>16))>>4; //02
sound_set(0,freq & 0xFF);
sound_set(1,(freq & 0xFF00)/255);
}
sound_set(8,0);
vprint(3,17,"Press any key to continue...");
pressKey();
CHKRAM();
}
void pressKey()
{
__asm
call #0x009F ;CHGET
__endasm;
}
void CHKRAM()
{
__asm
call 0x0000
__endasm;
}
// activa tono y ruido de uno de los tres canales del PSG
void setChannel(byte NumChannel, boolean isTone, boolean isNoise)
{
byte newValue;
newValue = sound_get(7);
if(NumChannel==0)
{
if(isTone==true){newValue&=254;}else{newValue|=1;}
if(isNoise==true){newValue&=247;}else{newValue|=8;}
}
if(NumChannel==1)
{
if(isTone==true){newValue&=253;}else{newValue|=2;}
if(isNoise==true){newValue&=239;}else{newValue|=16;}
}
if(NumChannel==2)
{
if(isTone==true){newValue&=251;}else{newValue|=4;}
if(isNoise==true){newValue&=223;}else{newValue|=32;}
}
sound_set(7,newValue);
}
void sound_set(byte reg, byte val)
{
reg;
val;
__asm
ld a, 4(ix)
ld e, 5(ix)
call 0x0093
__endasm;
}
byte sound_get(byte reg)
{
reg;
__asm
ld A,4(ix)
call 0x0096
ld L,A
__endasm;
}
void vprint(byte posx, byte posy, char* text)
{
uint address = BASE5 + (posy * 32) + posx; // calcula la posicion en la VRAM
while(*(text)) vpoke(address++,*(text++));
}
void vpoke(uint address, byte value)
{
address;
value;
__asm
ld l,4(ix)
ld h,5(ix)
ld a,6(ix)
call 0x004D
__endasm;
}