mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 06:53:01 +00:00
Amiga: validation export sample/wave book
tiny optimization
This commit is contained in:
parent
262eaa19c1
commit
527f962c1b
4 changed files with 192 additions and 24 deletions
|
@ -33,6 +33,9 @@ run `player` on Amiga. it should play the exported song.
|
||||||
- x: loc
|
- x: loc
|
||||||
- y: len
|
- y: len
|
||||||
- 01 xxxxxx yyyy: initialize wavetable (xxxx: pos; yy: length)
|
- 01 xxxxxx yyyy: initialize wavetable (xxxx: pos; yy: length)
|
||||||
|
- 02 xx: set loc/len from sample book
|
||||||
|
- 03 xx: initialize wavetable from wave book
|
||||||
|
- 04 xxxx: initialize wavetable from wave book (short)
|
||||||
- 06 xxxx: set period
|
- 06 xxxx: set period
|
||||||
- 08 xx: set volume
|
- 08 xx: set volume
|
||||||
- 0a xxxx: set data
|
- 0a xxxx: set data
|
||||||
|
|
|
@ -174,6 +174,7 @@ testChannel:
|
||||||
andi.b #15,d0
|
andi.b #15,d0
|
||||||
; check for 0
|
; check for 0
|
||||||
bne chanNotZero
|
bne chanNotZero
|
||||||
|
sampleWrite:
|
||||||
; write loc/len
|
; write loc/len
|
||||||
move.w #$f0f,d4
|
move.w #$f0f,d4
|
||||||
move.w d4,COLOR00
|
move.w d4,COLOR00
|
||||||
|
@ -200,15 +201,38 @@ testChannel:
|
||||||
chanNotZero:
|
chanNotZero:
|
||||||
; check for 8 (VOL)
|
; check for 8 (VOL)
|
||||||
cmp.b #8,d0
|
cmp.b #8,d0
|
||||||
bne chanWaveChange
|
bne chanSampleBook
|
||||||
; write volume
|
; write volume
|
||||||
clr.w d2
|
clr.w d2
|
||||||
move.b (a2)+,d2
|
move.b (a2)+,d2
|
||||||
bra chanWrite
|
bra chanWrite
|
||||||
|
chanSampleBook:
|
||||||
|
; check for 2 (loc/len from book)
|
||||||
|
cmp.b #2,d0
|
||||||
|
bne chanWaveChange
|
||||||
|
|
||||||
|
move.w #$f0f,d4
|
||||||
|
move.w d4,COLOR00
|
||||||
|
clr.l d3
|
||||||
|
move.b (a2)+,d3
|
||||||
|
bsr getSampleBook
|
||||||
|
|
||||||
|
; write loc/len
|
||||||
|
lea sampleData,a0
|
||||||
|
add.l a0,d2
|
||||||
|
lea chipBase,a0
|
||||||
|
move.b d1,d0
|
||||||
|
andi.l #$f0,d0
|
||||||
|
addi.l #$a0,d0
|
||||||
|
adda.l d0,a0
|
||||||
|
move.l d2,(a0)+ ; location
|
||||||
|
move.w d3,(a0) ; length
|
||||||
|
|
||||||
|
bra nextTick1
|
||||||
chanWaveChange:
|
chanWaveChange:
|
||||||
; check for 1 (wave change)
|
; check for 1 (wave change)
|
||||||
cmp.b #1,d0
|
cmp.b #1,d0
|
||||||
bne chanOther
|
bne chanWaveBookB
|
||||||
; copy wave
|
; copy wave
|
||||||
clr.l d2
|
clr.l d2
|
||||||
move.b (a2)+,d2
|
move.b (a2)+,d2
|
||||||
|
@ -229,14 +253,41 @@ chanWaveChange:
|
||||||
lsl.l #8,d2
|
lsl.l #8,d2
|
||||||
or.b (a2)+,d2
|
or.b (a2)+,d2
|
||||||
|
|
||||||
; don't copy a zero-length wave
|
bsr copyWave
|
||||||
tst.l d2
|
bra nextTick1
|
||||||
beq nextTick1
|
chanWaveBookB:
|
||||||
copyWave:
|
; check for 3 (wave change from book)
|
||||||
move.w (a0)+,(a1)+
|
cmp.b #3,d0
|
||||||
subq.l #2,d2
|
bne chanWaveBookW
|
||||||
bne copyWave
|
|
||||||
|
|
||||||
|
clr.l d3
|
||||||
|
move.b (a2)+,d3
|
||||||
|
bsr getWaveBook
|
||||||
|
|
||||||
|
lea sampleData,a1
|
||||||
|
andi.l #$30,d1
|
||||||
|
lsl.l #4,d1
|
||||||
|
adda.l d1,a1
|
||||||
|
|
||||||
|
bsr copyWave
|
||||||
|
bra nextTick1
|
||||||
|
chanWaveBookW:
|
||||||
|
; check for 4 (wave change from book short)
|
||||||
|
cmp.b #4,d0
|
||||||
|
bne chanOther
|
||||||
|
|
||||||
|
clr.l d3
|
||||||
|
move.b (a2)+,d3
|
||||||
|
lsl.l #8,d3
|
||||||
|
or.b (a2)+,d3
|
||||||
|
bsr getWaveBook
|
||||||
|
|
||||||
|
lea sampleData,a1
|
||||||
|
andi.l #$30,d1
|
||||||
|
lsl.l #4,d1
|
||||||
|
adda.l d1,a1
|
||||||
|
|
||||||
|
bsr copyWave
|
||||||
bra nextTick1
|
bra nextTick1
|
||||||
chanOther:
|
chanOther:
|
||||||
; get value and write
|
; get value and write
|
||||||
|
@ -263,6 +314,45 @@ endTick:
|
||||||
move.w d4,COLOR00
|
move.w d4,COLOR00
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
; a0: source. a1: destination. d2: length.
|
||||||
|
copyWave:
|
||||||
|
; don't copy a zero-length wave
|
||||||
|
tst.l d2
|
||||||
|
beq noCopy
|
||||||
|
copyWaveLoop:
|
||||||
|
move.w (a0)+,(a1)+
|
||||||
|
subq.l #2,d2
|
||||||
|
bne copyWaveLoop
|
||||||
|
noCopy:
|
||||||
|
rts
|
||||||
|
|
||||||
|
; put wave book entry in a0/d2. d3: index (modified).
|
||||||
|
getWaveBook:
|
||||||
|
lea waveBook(pc),a3
|
||||||
|
lsl.l #2,d3
|
||||||
|
move.l (a3,d3),d2
|
||||||
|
move.l d2,d3
|
||||||
|
rol.l #8,d2
|
||||||
|
andi.l #$ff,d2
|
||||||
|
bne getWaveBook2
|
||||||
|
move.w #$100,d2
|
||||||
|
getWaveBook2:
|
||||||
|
andi.l #$ffffff,d3
|
||||||
|
add.l #wavetable,d3
|
||||||
|
move.l d3,a0
|
||||||
|
rts
|
||||||
|
|
||||||
|
; get sample book entry in d2/d3. d3: index.
|
||||||
|
getSampleBook:
|
||||||
|
lea sampleBook(pc),a3
|
||||||
|
lsl.l #3,d3
|
||||||
|
adda.l d3,a3
|
||||||
|
move.l (a3)+,d2
|
||||||
|
move.l (a3)+,d3
|
||||||
|
andi.l #$ffffff,d2
|
||||||
|
andi.l #$ffff,d3
|
||||||
|
rts
|
||||||
|
|
||||||
data_c
|
data_c
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
|
@ -272,24 +362,27 @@ curColor:
|
||||||
state:
|
state:
|
||||||
dc.w 0 ; ticks
|
dc.w 0 ; ticks
|
||||||
dc.w 0 ; quit
|
dc.w 0 ; quit
|
||||||
|
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
seqAddr:
|
seqAddr:
|
||||||
dc.l 0
|
dc.l 0
|
||||||
|
cnop 0,4
|
||||||
|
|
||||||
|
sampleBook:
|
||||||
|
incbin "sbook.bin"
|
||||||
|
cnop 0,4
|
||||||
|
|
||||||
|
waveBook:
|
||||||
|
incbin "wbook.bin"
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
sequence:
|
sequence:
|
||||||
incbin "seq.bin"
|
incbin "seq.bin"
|
||||||
|
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
sampleData:
|
sampleData:
|
||||||
incbin "sample.bin"
|
incbin "sample.bin"
|
||||||
|
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
wavetable:
|
wavetable:
|
||||||
incbin "wave.bin"
|
incbin "wave.bin"
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,21 @@ struct WaveEntry {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SampleBookEntry {
|
||||||
|
unsigned int loc;
|
||||||
|
unsigned short len;
|
||||||
|
SampleBookEntry():
|
||||||
|
loc(0),
|
||||||
|
len(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
std::vector<DivROMExportOutput> ret;
|
std::vector<DivROMExportOutput> ret;
|
||||||
std::vector<WaveEntry> waves;
|
std::vector<WaveEntry> waves;
|
||||||
|
std::vector<SampleBookEntry> sampleBook;
|
||||||
unsigned int wavesDataPtr=0;
|
unsigned int wavesDataPtr=0;
|
||||||
WaveEntry curWaveState[4];
|
WaveEntry curWaveState[4];
|
||||||
|
unsigned int sampleBookLoc=0;
|
||||||
|
|
||||||
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
||||||
|
|
||||||
|
@ -133,11 +143,19 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
wavesDataPtr+=curWaveState[i].width;
|
wavesDataPtr+=curWaveState[i].width;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq->writeC((i<<4)|1);
|
if (waveNum<256) {
|
||||||
seq->writeC(waves[waveNum].pos>>16);
|
seq->writeC((i<<4)|3);
|
||||||
seq->writeC(waves[waveNum].pos>>8);
|
seq->writeC(waveNum);
|
||||||
seq->writeC(waves[waveNum].pos);
|
} else if (waveNum<65536) {
|
||||||
seq->writeS_BE(waves[waveNum].width);
|
seq->writeC((i<<4)|4);
|
||||||
|
seq->writeS_BE(waveNum);
|
||||||
|
} else{
|
||||||
|
seq->writeC((i<<4)|1);
|
||||||
|
seq->writeC(waves[waveNum].pos>>16);
|
||||||
|
seq->writeC(waves[waveNum].pos>>8);
|
||||||
|
seq->writeC(waves[waveNum].pos);
|
||||||
|
seq->writeS_BE(waves[waveNum].width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,12 +178,35 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
}
|
}
|
||||||
if (j.addr>=0x200) { // direct loc/len change
|
if (j.addr>=0x200) { // direct loc/len change
|
||||||
if (j.addr&4) { // len
|
if (j.addr&4) { // len
|
||||||
seq->writeS_BE(j.val);
|
int sampleBookIndex=-1;
|
||||||
|
for (size_t i=0; i<sampleBook.size(); i++) {
|
||||||
|
if (sampleBook[i].loc==sampleBookLoc && sampleBook[i].len==(j.val&0xffff)) {
|
||||||
|
sampleBookIndex=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sampleBookIndex==-1) {
|
||||||
|
if (sampleBook.size()<256) {
|
||||||
|
SampleBookEntry e;
|
||||||
|
e.loc=sampleBookLoc;
|
||||||
|
e.len=j.val&0xffff;
|
||||||
|
sampleBookIndex=sampleBook.size();
|
||||||
|
sampleBook.push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampleBookIndex==-1) {
|
||||||
|
seq->writeC((j.addr&3)<<4);
|
||||||
|
seq->writeC(sampleBookLoc>>16);
|
||||||
|
seq->writeC(sampleBookLoc>>8);
|
||||||
|
seq->writeC(sampleBookLoc);
|
||||||
|
seq->writeS_BE(j.val);
|
||||||
|
} else {
|
||||||
|
seq->writeC(((j.addr&3)<<4)|2);
|
||||||
|
seq->writeC(sampleBookIndex);
|
||||||
|
}
|
||||||
} else { // loc
|
} else { // loc
|
||||||
seq->writeC((j.addr&3)<<4);
|
sampleBookLoc=j.val;
|
||||||
seq->writeC(j.val>>16);
|
|
||||||
seq->writeC(j.val>>8);
|
|
||||||
seq->writeC(j.val);
|
|
||||||
}
|
}
|
||||||
} else if (j.addr<0xa0) {
|
} else if (j.addr<0xa0) {
|
||||||
// don't write INTENA
|
// don't write INTENA
|
||||||
|
@ -204,8 +245,29 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
for (WaveEntry& i: waves) {
|
for (WaveEntry& i: waves) {
|
||||||
wave->write(i.data,i.width);
|
wave->write(i.data,i.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sbook.bin
|
||||||
|
SafeWriter* sbook=new SafeWriter;
|
||||||
|
sbook->init();
|
||||||
|
for (SampleBookEntry& i: sampleBook) {
|
||||||
|
// 8 bytes per entry
|
||||||
|
sbook->writeI_BE(i.loc);
|
||||||
|
sbook->writeI_BE(i.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wbook.bin
|
||||||
|
SafeWriter* wbook=new SafeWriter;
|
||||||
|
wbook->init();
|
||||||
|
for (WaveEntry& i: waves) {
|
||||||
|
wbook->writeC(i.width);
|
||||||
|
wbook->writeC(i.pos>>16);
|
||||||
|
wbook->writeC(i.pos>>8);
|
||||||
|
wbook->writeC(i.pos);
|
||||||
|
}
|
||||||
|
|
||||||
// finish
|
// finish
|
||||||
|
ret.push_back(DivROMExportOutput("sbook.bin",sbook));
|
||||||
|
ret.push_back(DivROMExportOutput("wbook.bin",wbook));
|
||||||
ret.push_back(DivROMExportOutput("sample.bin",sample));
|
ret.push_back(DivROMExportOutput("sample.bin",sample));
|
||||||
ret.push_back(DivROMExportOutput("wave.bin",wave));
|
ret.push_back(DivROMExportOutput("wave.bin",wave));
|
||||||
ret.push_back(DivROMExportOutput("seq.bin",seq));
|
ret.push_back(DivROMExportOutput("seq.bin",seq));
|
||||||
|
|
|
@ -144,6 +144,16 @@ int SafeWriter::writeI(int val) {
|
||||||
return write(&val,4);
|
return write(&val,4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SafeWriter::writeI_BE(int val) {
|
||||||
|
unsigned char bytes[4] {
|
||||||
|
(unsigned char)((val>>24)&0xff),
|
||||||
|
(unsigned char)((val>>16)&0xff),
|
||||||
|
(unsigned char)((val>>8)&0xff),
|
||||||
|
(unsigned char)(val&0xff)
|
||||||
|
};
|
||||||
|
return write(bytes,4);
|
||||||
|
}
|
||||||
|
|
||||||
int SafeWriter::writeL(int64_t val) {
|
int SafeWriter::writeL(int64_t val) {
|
||||||
return write(&val,8);
|
return write(&val,8);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue