command stream work

disassemble call/jump/ret instructions
prepare for relocation
implement loop (but it doesn't work)
This commit is contained in:
tildearrow 2025-04-03 05:09:40 -05:00
parent 20f322d78c
commit 28f8423f23
4 changed files with 87 additions and 18 deletions

View file

@ -69,6 +69,8 @@ hex | description
.. | ... .. | ...
ef | preset delay 15 ef | preset delay 15
----|------------------------------------ ----|------------------------------------
f0 | UNUSED - placeholder used during optimization passes (3-byte nonce follows)
f1 | no operation
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

@ -115,6 +115,12 @@ bool DivCSPlayer::tick() {
case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xc7: case 0xc8: case 0xc9: case 0xca:
command=next-0xb4; command=next-0xb4;
break; break;
case 0xf0: // placeholder
stream.readC();
stream.readC();
stream.readC();
break;
case 0xf1: // nop
case 0xf7: case 0xf7:
command=stream.readC(); command=stream.readC();
break; break;

View file

@ -22,8 +22,6 @@
/* /*
#define WRITE_TICK(x) \ #define WRITE_TICK(x) \
if (!wroteTick[x]) { \
wroteTick[x]=true; \
if (tick-lastTick[x]>255) { \ if (tick-lastTick[x]>255) { \
chanStream[x]->writeC(0xfc); \ chanStream[x]->writeC(0xfc); \
chanStream[x]->writeS(tick-lastTick[x]); \ chanStream[x]->writeS(tick-lastTick[x]); \
@ -35,7 +33,6 @@
chanStream[x]->writeC(0xfe); \ chanStream[x]->writeC(0xfe); \
} \ } \
lastTick[x]=tick; \ lastTick[x]=tick; \
}
*/ */
void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
@ -205,6 +202,10 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
} }
} }
void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr) {
// TODO... this is important!
}
SafeWriter* DivEngine::saveCommand() { SafeWriter* DivEngine::saveCommand() {
stop(); stop();
repeatPattern=false; repeatPattern=false;
@ -228,7 +229,8 @@ SafeWriter* DivEngine::saveCommand() {
SafeWriter* chanStream[DIV_MAX_CHANS]; SafeWriter* chanStream[DIV_MAX_CHANS];
unsigned int chanStreamOff[DIV_MAX_CHANS]; unsigned int chanStreamOff[DIV_MAX_CHANS];
bool wroteTick[DIV_MAX_CHANS]; std::vector<size_t> tickPos[DIV_MAX_CHANS];
int loopTick=-1;
memset(cmdPopularity,0,256*sizeof(int)); memset(cmdPopularity,0,256*sizeof(int));
memset(delayPopularity,0,256*sizeof(int)); memset(delayPopularity,0,256*sizeof(int));
@ -268,12 +270,22 @@ SafeWriter* DivEngine::saveCommand() {
memset(lastTick,0,DIV_MAX_CHANS*sizeof(int)); memset(lastTick,0,DIV_MAX_CHANS*sizeof(int));
while (!done) { while (!done) {
for (int i=0; i<chans; i++) {
tickPos[i].push_back(chanStream[i]->tell());
}
if (loopTick==-1) {
if (loopOrder==curOrder && loopRow==curRow) {
if ((ticks-((tempoAccum+virtualTempoN)/virtualTempoD))<=0) {
logI("loop is on tick %d",tick);
loopTick=tick;
}
}
}
if (nextTick(false,true) || !playing) { if (nextTick(false,true) || !playing) {
done=true; done=true;
break; break;
} }
// get command stream // get command stream
memset(wroteTick,0,DIV_MAX_CHANS*sizeof(bool));
if (curDivider!=divider) { if (curDivider!=divider) {
curDivider=divider; curDivider=divider;
chanStream[0]->writeC(0xfb); chanStream[0]->writeC(0xfb);
@ -306,8 +318,23 @@ SafeWriter* DivEngine::saveCommand() {
} }
tick++; tick++;
} }
if (!playing || loopTick<0) {
for (int i=0; i<chans; i++) {
chanStream[i]->writeC(0xff);
}
} else {
for (int i=0; i<chans; i++) {
if ((int)tickPos[i].size()>loopTick) {
chanStream[i]->writeC(0xfa);
chanStream[i]->writeI(tickPos[i][loopTick]);
logD("chan %d loop addr: %x",i,tickPos[i][loopTick]);
} else {
logW("chan %d unable to find loop addr!",i);
chanStream[i]->writeC(0xff);
}
}
}
logV("%d",tick); logV("%d",tick);
memset(wroteTick,0,DIV_MAX_CHANS*sizeof(bool));
cmdStreamEnabled=oldCmdStreamEnabled; cmdStreamEnabled=oldCmdStreamEnabled;
int sortCand=-1; int sortCand=-1;
@ -353,7 +380,6 @@ SafeWriter* DivEngine::saveCommand() {
} }
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {
chanStream[i]->writeC(0xff);
// optimize stream // optimize stream
SafeWriter* oldStream=chanStream[i]; SafeWriter* oldStream=chanStream[i];
SafeReader* reader=oldStream->toReader(); SafeReader* reader=oldStream->toReader();

View file

@ -94,6 +94,41 @@ String disasmCmd(unsigned char* buf, size_t bufLen, unsigned int addr) {
case 0xec: case 0xed: case 0xee: case 0xef: case 0xec: case 0xed: case 0xee: case 0xef:
return fmt::sprintf("qwait (%d)",(int)(buf[addr]-0xe0)); return fmt::sprintf("qwait (%d)",(int)(buf[addr]-0xe0));
break; break;
case 0xf0:
if (addr+3>=bufLen) return "???";
return fmt::sprintf("opt %.2x%.2x%.2x",(int)buf[addr+1],(int)buf[addr+2],(int)buf[addr+3]);
break;
case 0xf1:
return "nop";
break;
case 0xf4:
if (addr+2>=bufLen) return "???";
return fmt::sprintf("callsym %.4x",(int)(buf[addr+1]|(buf[addr+2]<<8)));
break;
case 0xf5:
if (addr+4>=bufLen) return "???";
return fmt::sprintf("call %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
break;
case 0xf6:
if (addr+4>=bufLen) return "???";
return fmt::sprintf("callb32 %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
break;
case 0xf7:
return "CMD";
break;
case 0xf8:
if (addr+2>=bufLen) return "???";
return fmt::sprintf("callb16 %.4x",(int)(buf[addr+1]|(buf[addr+2]<<8)));
break;
case 0xf9:
return "ret";
break;
case 0xfa:
return fmt::sprintf("jmp %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
break;
case 0xfb:
return fmt::sprintf("rate %.8x",(unsigned int)(buf[addr+1]|(buf[addr+2]<<8)|(buf[addr+3]<<16)|(buf[addr+4]<<24)));
break;
case 0xfc: case 0xfc:
if (addr+2>=bufLen) return "???"; if (addr+2>=bufLen) return "???";
return fmt::sprintf("waits %d",(int)(buf[addr+1]|(buf[addr+2]<<8))); return fmt::sprintf("waits %d",(int)(buf[addr+1]|(buf[addr+2]<<8)));