Amiga: validation export sample/wave book

tiny optimization
This commit is contained in:
tildearrow 2023-03-16 03:33:55 -05:00
parent 262eaa19c1
commit 527f962c1b
4 changed files with 192 additions and 24 deletions

View file

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

View file

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

View file

@ -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
@ -205,7 +246,28 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
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));

View file

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