mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 08:23: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
|
||||
- y: len
|
||||
- 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
|
||||
- 08 xx: set volume
|
||||
- 0a xxxx: set data
|
||||
|
|
|
@ -174,6 +174,7 @@ testChannel:
|
|||
andi.b #15,d0
|
||||
; check for 0
|
||||
bne chanNotZero
|
||||
sampleWrite:
|
||||
; write loc/len
|
||||
move.w #$f0f,d4
|
||||
move.w d4,COLOR00
|
||||
|
@ -200,15 +201,38 @@ testChannel:
|
|||
chanNotZero:
|
||||
; check for 8 (VOL)
|
||||
cmp.b #8,d0
|
||||
bne chanWaveChange
|
||||
bne chanSampleBook
|
||||
; write volume
|
||||
clr.w d2
|
||||
move.b (a2)+,d2
|
||||
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:
|
||||
; check for 1 (wave change)
|
||||
cmp.b #1,d0
|
||||
bne chanOther
|
||||
bne chanWaveBookB
|
||||
; copy wave
|
||||
clr.l d2
|
||||
move.b (a2)+,d2
|
||||
|
@ -229,14 +253,41 @@ chanWaveChange:
|
|||
lsl.l #8,d2
|
||||
or.b (a2)+,d2
|
||||
|
||||
; don't copy a zero-length wave
|
||||
tst.l d2
|
||||
beq nextTick1
|
||||
copyWave:
|
||||
move.w (a0)+,(a1)+
|
||||
subq.l #2,d2
|
||||
bne copyWave
|
||||
bsr copyWave
|
||||
bra nextTick1
|
||||
chanWaveBookB:
|
||||
; check for 3 (wave change from book)
|
||||
cmp.b #3,d0
|
||||
bne chanWaveBookW
|
||||
|
||||
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
|
||||
chanOther:
|
||||
; get value and write
|
||||
|
@ -263,6 +314,45 @@ endTick:
|
|||
move.w d4,COLOR00
|
||||
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
|
||||
cnop 0,4
|
||||
|
||||
|
@ -272,24 +362,27 @@ curColor:
|
|||
state:
|
||||
dc.w 0 ; ticks
|
||||
dc.w 0 ; quit
|
||||
|
||||
cnop 0,4
|
||||
|
||||
seqAddr:
|
||||
dc.l 0
|
||||
|
||||
cnop 0,4
|
||||
|
||||
sampleBook:
|
||||
incbin "sbook.bin"
|
||||
cnop 0,4
|
||||
|
||||
waveBook:
|
||||
incbin "wbook.bin"
|
||||
cnop 0,4
|
||||
|
||||
sequence:
|
||||
incbin "seq.bin"
|
||||
|
||||
cnop 0,4
|
||||
|
||||
sampleData:
|
||||
incbin "sample.bin"
|
||||
|
||||
cnop 0,4
|
||||
|
||||
wavetable:
|
||||
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> ret;
|
||||
std::vector<WaveEntry> waves;
|
||||
std::vector<SampleBookEntry> sampleBook;
|
||||
unsigned int wavesDataPtr=0;
|
||||
WaveEntry curWaveState[4];
|
||||
unsigned int sampleBookLoc=0;
|
||||
|
||||
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
||||
|
||||
|
@ -133,11 +143,19 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
|||
wavesDataPtr+=curWaveState[i].width;
|
||||
}
|
||||
|
||||
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);
|
||||
if (waveNum<256) {
|
||||
seq->writeC((i<<4)|3);
|
||||
seq->writeC(waveNum);
|
||||
} else if (waveNum<65536) {
|
||||
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&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
|
||||
seq->writeC((j.addr&3)<<4);
|
||||
seq->writeC(j.val>>16);
|
||||
seq->writeC(j.val>>8);
|
||||
seq->writeC(j.val);
|
||||
sampleBookLoc=j.val;
|
||||
}
|
||||
} else if (j.addr<0xa0) {
|
||||
// don't write INTENA
|
||||
|
@ -204,8 +245,29 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
|||
for (WaveEntry& i: waves) {
|
||||
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
|
||||
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("wave.bin",wave));
|
||||
ret.push_back(DivROMExportOutput("seq.bin",seq));
|
||||
|
|
|
@ -144,6 +144,16 @@ int SafeWriter::writeI(int val) {
|
|||
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) {
|
||||
return write(&val,8);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue