Amiga: validation export wave support

This commit is contained in:
tildearrow 2023-03-16 01:44:35 -05:00
parent 03f6268336
commit 262eaa19c1
5 changed files with 135 additions and 24 deletions

View file

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

View file

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

View file

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

View file

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

View file

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