command stream work
disassemble call/jump/ret instructions prepare for relocation implement loop (but it doesn't work)
This commit is contained in:
parent
20f322d78c
commit
28f8423f23
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -22,20 +22,17 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define WRITE_TICK(x) \
|
#define WRITE_TICK(x) \
|
||||||
if (!wroteTick[x]) { \
|
if (tick-lastTick[x]>255) { \
|
||||||
wroteTick[x]=true; \
|
chanStream[x]->writeC(0xfc); \
|
||||||
if (tick-lastTick[x]>255) { \
|
chanStream[x]->writeS(tick-lastTick[x]); \
|
||||||
chanStream[x]->writeC(0xfc); \
|
} else if (tick-lastTick[x]>1) { \
|
||||||
chanStream[x]->writeS(tick-lastTick[x]); \
|
delayPopularity[tick-lastTick[x]]++; \
|
||||||
} else if (tick-lastTick[x]>1) { \
|
chanStream[x]->writeC(0xfd); \
|
||||||
delayPopularity[tick-lastTick[x]]++; \
|
chanStream[x]->writeC(tick-lastTick[x]); \
|
||||||
chanStream[x]->writeC(0xfd); \
|
} else if (tick-lastTick[x]>0) { \
|
||||||
chanStream[x]->writeC(tick-lastTick[x]); \
|
chanStream[x]->writeC(0xfe); \
|
||||||
} else if (tick-lastTick[x]>0) { \
|
} \
|
||||||
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();
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
Loading…
Reference in a new issue