command stream relocation

This commit is contained in:
tildearrow 2025-04-03 06:26:25 -05:00
parent 28f8423f23
commit 491a361392
2 changed files with 67 additions and 2 deletions

View file

@ -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)

View file

@ -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];