
about timers - maybe your case have some timing dll's? i mean plug some dll, where lays timing procedure for microsecunds. or use delay 0 - it eat cpu, but it will be correct timings.
I'm still a bit confused. Are you creating music for a game which should run on a real Sega and uses this GEMS driver ?SeregaZ wrote:not realyVGM have direct line - one line.this "code" can have many, with individual loops. it need for economy place. sega meda drive games is very limited by size
so for example main melody can have length 100, drums track only 10, but have loop per 10 times. and you can hear drums in all track.
It's probably not only volume which is affected by it. It is also very likely the instrument choice results in slight frequency changes while a tone is playing.SeregaZ wrote:PSG have only 1 command, but GEMS have instrument for PSG too. this "instrument" by logic it is behavior of commands - when it need to start, how to up volume in a time, how to fade off - and etc brainbreak unanderstanable thingsit have 7 params - it is plan of behavior.
I'm not sure if it will leak this way or not. You could use the debugger tools. Another option is to use C-style arrays and allocate the memory yourself.SeregaZ wrote:this allocates need to be free, or this new Dim with same name - make frees by default? or i have memory leak?
yes yeswilbert wrote: It's probably not only volume which is affected by it. It is also very likely the instrument choice results in slight frequency changes while a tone is playing.
I know slide effects do this but what I really meant was a sort of vibrato, where the frequency constantly floats around the desired note instead of maintaining the exact note frequency.SeregaZ wrote:yes yesslide effect do this
note still plays, but it change pitch per time. like Rock'n'Roll Racing game songs. it have a loooot this slides
Code: Select all
// DOENVELOPE - update the pitch envelope processor
static void DOENVELOPE(void)
{
UINT8* CurECB; // Register IX
UINT8 TestRes;
UINT32 SegPos; // Register HL
UINT8 SegCntr; // Register A
UINT16 SegVal;
UINT8* CurPB; // Register IY
CurECB = ECB; // point at the envelope control blocks
//envloop:
while(1)
{
DACxME();
if (CurECB[ECBCHAN] & 0x80) // end of list? [BIT #7]
break; // yup - return
if (! (CurECB[ECBCHAN] & 0x40)) // active ? [BIT #6]
{
//envactive: // check if this envelope's timebase has ticked
if (TBASEFLAGS & 0x20) // sfx timebase? [BIT #5]
//envsfx:
TestRes = (TBASEFLAGS & 0x01); // yes - check sfx tick flag [BIT #0]
else
TestRes = (TBASEFLAGS & 0x02); // no - check music tick flag [BIT #1]
if (TestRes)
{
//envticked:
if (CurECB[ECBCTR] == 0) // ctr at 0?
{
//envnextseg: // yes - [Note: The comment is really cut here.]
SegPos = (CurECB[ECBPTRH] << 8) | (CurECB[ECBPTRL] << 0);
SegPos -= 0x1E80; // [1E80 is subtracted to make up for ENV0BUF[]]
SegCntr = ENV0BUF[SegPos];
if (SegCntr == 0)
{
// jr envdone
TestRes = 0x00;
}
else
{
SegPos ++;
CurECB[ECBDELL] = ENV0BUF[SegPos];
SegPos ++;
CurECB[ECBDELH] = ENV0BUF[SegPos]; // ECB's delta <- this segment's delta
SegPos ++;
DACxME();
SegPos += 0x1E80; // [not in actual code, SegPos is relative to ENV0BUF here]
CurECB[ECBPTRL] = (SegPos & 0x00FF) >> 0;
CurECB[ECBPTRH] = (SegPos & 0xFF00) >> 8;
// [fall through to envseg]
}
}
else // no - process segment
{
SegCntr = CurECB[ECBCTR] - 1;
}
if (TestRes) // [need to check that, since envdone skips envseg]
{
//envseg:
CurPB = &PBTBL[CurECB[ECBCHAN] & ~0x20]; // ptr to this channel's pitchbend entries [RES #5]
CurECB[ECBCTR] = SegCntr;
SegVal = (CurPB[PBEBH] << 8) | (CurPB[PBEBL] << 0);
SegVal += (CurECB[ECBDELH] << 8) | (CurECB[ECBDELL] << 0);
CurPB[PBEBL] = (SegVal & 0x00FF) >> 0;
CurPB[PBEBH] = (SegVal & 0xFF00) >> 8;
// [fall through to envneedupd]
}
else
{
//envdone:
CurPB = &PBTBL[CurECB[ECBCHAN] & ~0x20]; // ptr to this channel's pitchbend entries [RES #5]
CurPB[PBEBL] = 0; // zero the envelope bend on this channel
CurPB[PBEBH] = 0;
CurECB[ECBCHAN] = 0x40; // shut off this envelope
//jr envneedupd
}
//envneedupd:
CurPB[PBRETRIG] |= 0x01; // [SET #0]
NEEDBEND = 1;
//jr envnext
}
}
//envnext: // nope - loop
CurECB ++;
}
return;
}
Code: Select all
02 00 00 00 FA E7 FF 32 E7 FF 32 E7 FF 32 E7 FF 00
Code: Select all
00 00 FA E7 FF 32 E7 FF 32 E7 FF 32 E7 FF 00
Code: Select all
*
* Modulator Offset Table
*
dc.b $02,$00 ; Offset to modulator #0: 2
*
* Modulator Data
*
* Modulator 0 "NEW": Pitch
dc.b $57,$04 ; initial value = 1111
dc.b $D05,$5C,$11 ; len = 3333, slope = 4444
dc.b 0
That makes more sense compared to the other code you postedSeregaZ wrote:aha! DOS GEMS is help... particular...Code: Select all
* * Modulator Offset Table * dc.b $02,$00 ; Offset to modulator #0: 2 * * Modulator Data * * Modulator 0 "NEW": Pitch dc.b $57,$04 ; initial value = 1111 dc.b $D05,$5C,$11 ; len = 3333, slope = 4444 dc.b 0