Amiga: validation export wave support
This commit is contained in:
parent
03f6268336
commit
262eaa19c1
|
@ -16,13 +16,14 @@ go to file > export Amiga validation data...
|
|||
|
||||
put sample.bin, seq.bin and wave.bin in this directory.
|
||||
|
||||
compile with vasm:
|
||||
type `make`. you need vasm (68000 with Mot syntax) in order for it to work.
|
||||
alternatively, type:
|
||||
|
||||
```
|
||||
vasmm68k_mot -Fhunkexe -kick1hunks player.s
|
||||
vasmm68k_mot -Fhunkexe -kick1hunks -nosym -o player player.s
|
||||
```
|
||||
|
||||
run a.out on Amiga. it should play the exported song.
|
||||
run `player` on Amiga. it should play the exported song.
|
||||
|
||||
# sequence format
|
||||
|
||||
|
@ -31,7 +32,7 @@ run a.out on Amiga. it should play the exported song.
|
|||
- 00 xxxxxx yyyy: set loc/len
|
||||
- x: loc
|
||||
- y: len
|
||||
- 01 xxxx yy: initialize wavetable (xxxx: pos; yy: length)
|
||||
- 01 xxxxxx yyyy: initialize wavetable (xxxx: pos; yy: length)
|
||||
- 06 xxxx: set period
|
||||
- 08 xx: set volume
|
||||
- 0a xxxx: set data
|
||||
|
|
|
@ -10,6 +10,7 @@ COLOR00 = $dff180
|
|||
chipBase=$dff000
|
||||
|
||||
DMACONR = $02
|
||||
POTGOR = $16
|
||||
DMACON = $96
|
||||
ADKCON = $9e
|
||||
AUDBASE = $a0
|
||||
|
@ -25,6 +26,7 @@ AUD3VOL = $d8
|
|||
|
||||
code_c
|
||||
init:
|
||||
move.b #2,$bfe001
|
||||
lea chipBase,a0
|
||||
move.w #15,DMACON(a0)
|
||||
waitCon:
|
||||
|
@ -43,24 +45,37 @@ waitCon:
|
|||
main:
|
||||
bsr waitVBlank
|
||||
|
||||
;move.w curColor,d0
|
||||
;move.w d0,COLOR00
|
||||
;addi.w #1,d0
|
||||
;move.w d0,curColor
|
||||
move.w #$000,d4
|
||||
move.w d4,COLOR00
|
||||
|
||||
lea chipBase,a0
|
||||
btst.b #2,POTGOR(a0)
|
||||
bne next
|
||||
|
||||
lea state(pc),a0
|
||||
move.w #1,2(a0)
|
||||
|
||||
next:
|
||||
bsr nextTick
|
||||
|
||||
bra main
|
||||
lea state(pc),a0
|
||||
tst.w 2(a0)
|
||||
beq main
|
||||
finish:
|
||||
lea chipBase,a0
|
||||
move.w #15,DMACON(a0)
|
||||
clr.l d0
|
||||
rts
|
||||
|
||||
waitVBlank:
|
||||
move.l (VPOSR),d0
|
||||
and.l #$1ff00,d0
|
||||
cmp.l #$8c00,d0
|
||||
cmp.l #$bc00,d0
|
||||
bne waitVBlank
|
||||
waitVBlank2:
|
||||
move.l (VPOSR),d0
|
||||
and.l #$1ff00,d0
|
||||
cmp.l #$8d00,d0
|
||||
cmp.l #$bd00,d0
|
||||
bne waitVBlank2
|
||||
rts
|
||||
|
||||
|
@ -146,9 +161,7 @@ testFF:
|
|||
cmp.b #$ff,d0
|
||||
bne testOther
|
||||
theEnd:
|
||||
move.w #$fff,d4
|
||||
move.w d4,COLOR00
|
||||
bra theEnd
|
||||
lea sequence(pc),a2
|
||||
testOther:
|
||||
; something else
|
||||
bra nextTick1
|
||||
|
@ -187,11 +200,44 @@ testChannel:
|
|||
chanNotZero:
|
||||
; check for 8 (VOL)
|
||||
cmp.b #8,d0
|
||||
bne chanOther
|
||||
bne chanWaveChange
|
||||
; write volume
|
||||
clr.w d2
|
||||
move.b (a2)+,d2
|
||||
bra chanWrite
|
||||
chanWaveChange:
|
||||
; check for 1 (wave change)
|
||||
cmp.b #1,d0
|
||||
bne chanOther
|
||||
; copy wave
|
||||
clr.l d2
|
||||
move.b (a2)+,d2
|
||||
lsl.l #8,d2
|
||||
or.b (a2)+,d2
|
||||
lsl.l #8,d2
|
||||
or.b (a2)+,d2
|
||||
add.l #wavetable,d2
|
||||
move.l d2,a0
|
||||
|
||||
lea sampleData,a1
|
||||
andi.l #$30,d1
|
||||
lsl.l #4,d1
|
||||
adda.l d1,a1
|
||||
|
||||
clr.l d2
|
||||
move.b (a2)+,d2
|
||||
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
|
||||
|
||||
bra nextTick1
|
||||
chanOther:
|
||||
; get value and write
|
||||
clr.w d2
|
||||
|
@ -225,6 +271,7 @@ curColor:
|
|||
|
||||
state:
|
||||
dc.w 0 ; ticks
|
||||
dc.w 0 ; quit
|
||||
|
||||
cnop 0,4
|
||||
|
||||
|
@ -241,7 +288,8 @@ sequence:
|
|||
sampleData:
|
||||
incbin "sample.bin"
|
||||
|
||||
;data_f
|
||||
cnop 0,4
|
||||
|
||||
wavetable:
|
||||
incbin "wave.bin"
|
||||
|
||||
|
|
|
@ -21,8 +21,23 @@
|
|||
#include "../engine.h"
|
||||
#include "../platform/amiga.h"
|
||||
|
||||
struct WaveEntry {
|
||||
unsigned int pos;
|
||||
short width;
|
||||
signed char data[256];
|
||||
WaveEntry():
|
||||
pos(0),
|
||||
width(32) {
|
||||
memset(data,0,256);
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||
std::vector<DivROMExportOutput> ret;
|
||||
std::vector<WaveEntry> waves;
|
||||
unsigned int wavesDataPtr=0;
|
||||
WaveEntry curWaveState[4];
|
||||
|
||||
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
||||
|
||||
e->stop();
|
||||
|
@ -54,13 +69,6 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
|||
sample->write(&((const unsigned char*)amiga->getSampleMem(0))[0x400],amiga->getSampleMemUsage(0)-0x400);
|
||||
if (sample->tell()&1) sample->writeC(0);
|
||||
|
||||
// wave.bin
|
||||
SafeWriter* wave=new SafeWriter;
|
||||
wave->init();
|
||||
for (int i=0; i<32; i++) {
|
||||
wave->writeC(i<<3);
|
||||
}
|
||||
|
||||
// seq.bin
|
||||
SafeWriter* seq=new SafeWriter;
|
||||
seq->init();
|
||||
|
@ -86,8 +94,54 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
|||
if (e->nextTick(false,true)) {
|
||||
done=true;
|
||||
amiga->getRegisterWrites().clear();
|
||||
if (lastTick!=songTick) {
|
||||
int delta=songTick-lastTick;
|
||||
if (delta==1) {
|
||||
seq->writeC(0xf1);
|
||||
} else if (delta<256) {
|
||||
seq->writeC(0xf2);
|
||||
seq->writeC(delta-1);
|
||||
} else if (delta<32768) {
|
||||
seq->writeC(0xf3);
|
||||
seq->writeS_BE(delta-1);
|
||||
}
|
||||
lastTick=songTick;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// check wavetable changes
|
||||
for (int i=0; i<4; i++) {
|
||||
if (amiga->chan[i].useWave) {
|
||||
if ((amiga->chan[i].audLen*2)!=curWaveState[i].width || memcmp(curWaveState[i].data,&(((signed char*)amiga->getSampleMem())[i<<8]),amiga->chan[i].audLen*2)!=0) {
|
||||
curWaveState[i].width=amiga->chan[i].audLen*2;
|
||||
memcpy(curWaveState[i].data,&(((signed char*)amiga->getSampleMem())[i<<8]),amiga->chan[i].audLen*2);
|
||||
|
||||
int waveNum=-1;
|
||||
for (size_t j=0; j<waves.size(); j++) {
|
||||
if (waves[j].width!=curWaveState[i].width) continue;
|
||||
if (memcmp(waves[j].data,curWaveState[i].data,curWaveState[i].width)==0) {
|
||||
waveNum=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (waveNum==-1) {
|
||||
// write new wavetable
|
||||
waveNum=(int)waves.size();
|
||||
curWaveState[i].pos=wavesDataPtr;
|
||||
waves.push_back(curWaveState[i]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get register writes
|
||||
std::vector<DivRegWrite>& writes=amiga->getRegisterWrites();
|
||||
for (DivRegWrite& j: writes) {
|
||||
|
@ -144,6 +198,13 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
|||
|
||||
EXTERN_BUSY_END;
|
||||
|
||||
// wave.bin
|
||||
SafeWriter* wave=new SafeWriter;
|
||||
wave->init();
|
||||
for (WaveEntry& i: waves) {
|
||||
wave->write(i.data,i.width);
|
||||
}
|
||||
|
||||
// finish
|
||||
ret.push_back(DivROMExportOutput("sample.bin",sample));
|
||||
ret.push_back(DivROMExportOutput("wave.bin",wave));
|
||||
|
|
|
@ -509,7 +509,7 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
|||
if (dmaOn) rWrite(0x96,0x8000|dmaOn);
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
if ((dmaOn&(1<<i)) && dumpWrites) {
|
||||
if ((dmaOn&(1<<i)) && !chan[i].useWave && dumpWrites) {
|
||||
addWrite(0x200+i,(chan[i].irLocH<<16)|chan[i].irLocL);
|
||||
addWrite(0x204+i,chan[i].irLen);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ class DivPlatformAmiga: public DivDispatch {
|
|||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
friend class DivExportAmigaValidation;
|
||||
|
||||
void irq(int ch);
|
||||
void rWrite(unsigned short addr, unsigned short val);
|
||||
|
|
Loading…
Reference in a new issue