command stream relocation
This commit is contained in:
parent
28f8423f23
commit
491a361392
|
@ -71,6 +71,7 @@ hex | description
|
||||||
----|------------------------------------
|
----|------------------------------------
|
||||||
f0 | UNUSED - placeholder used during optimization passes (3-byte nonce follows)
|
f0 | UNUSED - placeholder used during optimization passes (3-byte nonce follows)
|
||||||
f1 | no operation
|
f1 | no operation
|
||||||
|
f2 | UNUSED - unoptimized extended command
|
||||||
f4 | call symbol (16-bit index follows; only used internally)
|
f4 | call symbol (16-bit index follows; only used internally)
|
||||||
f5 | jump to sub-block (address follows)
|
f5 | jump to sub-block (address follows)
|
||||||
f6 | go to sub-block (32-bit offset follows)
|
f6 | go to sub-block (32-bit offset follows)
|
||||||
|
|
|
@ -35,6 +35,47 @@
|
||||||
lastTick[x]=tick; \
|
lastTick[x]=tick; \
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int getInsLength(unsigned char ins) {
|
||||||
|
switch (ins) {
|
||||||
|
case 0xb8: // ins
|
||||||
|
case 0xc0: // pre porta
|
||||||
|
case 0xc3: // vib range
|
||||||
|
case 0xc4: // vib shape
|
||||||
|
case 0xc5: // pitch
|
||||||
|
case 0xc7: // volume
|
||||||
|
case 0xca: // legato
|
||||||
|
case 0xfd: // waitc
|
||||||
|
return 2;
|
||||||
|
case 0xbe: // pan
|
||||||
|
case 0xc2: // vibrato
|
||||||
|
case 0xc6: // arpeggio
|
||||||
|
case 0xc8: // vol slide
|
||||||
|
case 0xc9: // porta
|
||||||
|
return 3;
|
||||||
|
// speed dial commands
|
||||||
|
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||||
|
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||||
|
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||||
|
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||||
|
return 0;
|
||||||
|
case 0xf0: // opt
|
||||||
|
return 4;
|
||||||
|
case 0xf2: // opt command
|
||||||
|
case 0xf7: // cmd
|
||||||
|
return 0;
|
||||||
|
case 0xf4: // callsym
|
||||||
|
case 0xf8: // callb16
|
||||||
|
case 0xfc: // waits
|
||||||
|
return 3;
|
||||||
|
case 0xf5: // call
|
||||||
|
case 0xf6: // callb32
|
||||||
|
case 0xfa: // jmp
|
||||||
|
case 0xfb: // rate
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON:
|
case DIV_CMD_NOTE_ON:
|
||||||
|
@ -63,7 +104,8 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
w->writeC((unsigned char)c.cmd+0xb4);
|
w->writeC((unsigned char)c.cmd+0xb4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
w->writeC(0xf0); // unoptimized extended command
|
return; // quit for now... we'll implement this later
|
||||||
|
w->writeC(0xf2); // unoptimized extended command
|
||||||
w->writeC(c.cmd);
|
w->writeC(c.cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -204,6 +246,27 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
||||||
|
|
||||||
void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr) {
|
void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr) {
|
||||||
// TODO... this is important!
|
// TODO... this is important!
|
||||||
|
unsigned int delta=destAddr-sourceAddr;
|
||||||
|
for (size_t i=0; i<len;) {
|
||||||
|
int insLen=getInsLength(buf[i]);
|
||||||
|
if (insLen<1) {
|
||||||
|
logE("INS %x NOT IMPLEMENTED...",buf[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (buf[i]) {
|
||||||
|
case 0xf5: // call
|
||||||
|
case 0xfa: { // jmp
|
||||||
|
unsigned int addr=buf[i+1]|(buf[i+2]<<8)|(buf[i+3]<<8)|(buf[i+4]<<24);
|
||||||
|
addr+=delta;
|
||||||
|
buf[i+1]=addr&0xff;
|
||||||
|
buf[i+2]=(addr>>8)&0xff;
|
||||||
|
buf[i+3]=(addr>>16)&0xff;
|
||||||
|
buf[i+4]=(addr>>24)&0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i+=insLen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeWriter* DivEngine::saveCommand() {
|
SafeWriter* DivEngine::saveCommand() {
|
||||||
|
@ -412,7 +475,7 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
next=reader->readC();
|
next=reader->readC();
|
||||||
chanStream[i]->writeC(next);
|
chanStream[i]->writeC(next);
|
||||||
break;
|
break;
|
||||||
case 0xf0: { // full command (pre)
|
case 0xf2: { // full command (pre)
|
||||||
unsigned char cmd=reader->readC();
|
unsigned char cmd=reader->readC();
|
||||||
bool foundShort=false;
|
bool foundShort=false;
|
||||||
for (int j=0; j<16; j++) {
|
for (int j=0; j<16; j++) {
|
||||||
|
@ -494,6 +557,7 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
for (int i=0; i<chans; i++) {
|
for (int i=0; i<chans; i++) {
|
||||||
chanStreamOff[i]=w->tell();
|
chanStreamOff[i]=w->tell();
|
||||||
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
||||||
|
reloc(chanStream[i]->getFinalBuf(),chanStream[i]->size(),0,w->tell());
|
||||||
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
||||||
chanStream[i]->finish();
|
chanStream[i]->finish();
|
||||||
delete chanStream[i];
|
delete chanStream[i];
|
||||||
|
|
Loading…
Reference in a new issue