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.
|
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
|
# sequence format
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ run a.out on Amiga. it should play the exported song.
|
||||||
- 00 xxxxxx yyyy: set loc/len
|
- 00 xxxxxx yyyy: set loc/len
|
||||||
- x: loc
|
- x: loc
|
||||||
- y: len
|
- y: len
|
||||||
- 01 xxxx yy: initialize wavetable (xxxx: pos; yy: length)
|
- 01 xxxxxx yyyy: initialize wavetable (xxxx: pos; yy: length)
|
||||||
- 06 xxxx: set period
|
- 06 xxxx: set period
|
||||||
- 08 xx: set volume
|
- 08 xx: set volume
|
||||||
- 0a xxxx: set data
|
- 0a xxxx: set data
|
||||||
|
|
|
@ -10,6 +10,7 @@ COLOR00 = $dff180
|
||||||
chipBase=$dff000
|
chipBase=$dff000
|
||||||
|
|
||||||
DMACONR = $02
|
DMACONR = $02
|
||||||
|
POTGOR = $16
|
||||||
DMACON = $96
|
DMACON = $96
|
||||||
ADKCON = $9e
|
ADKCON = $9e
|
||||||
AUDBASE = $a0
|
AUDBASE = $a0
|
||||||
|
@ -25,6 +26,7 @@ AUD3VOL = $d8
|
||||||
|
|
||||||
code_c
|
code_c
|
||||||
init:
|
init:
|
||||||
|
move.b #2,$bfe001
|
||||||
lea chipBase,a0
|
lea chipBase,a0
|
||||||
move.w #15,DMACON(a0)
|
move.w #15,DMACON(a0)
|
||||||
waitCon:
|
waitCon:
|
||||||
|
@ -43,24 +45,37 @@ waitCon:
|
||||||
main:
|
main:
|
||||||
bsr waitVBlank
|
bsr waitVBlank
|
||||||
|
|
||||||
;move.w curColor,d0
|
move.w #$000,d4
|
||||||
;move.w d0,COLOR00
|
move.w d4,COLOR00
|
||||||
;addi.w #1,d0
|
|
||||||
;move.w d0,curColor
|
|
||||||
|
|
||||||
|
lea chipBase,a0
|
||||||
|
btst.b #2,POTGOR(a0)
|
||||||
|
bne next
|
||||||
|
|
||||||
|
lea state(pc),a0
|
||||||
|
move.w #1,2(a0)
|
||||||
|
|
||||||
|
next:
|
||||||
bsr nextTick
|
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:
|
waitVBlank:
|
||||||
move.l (VPOSR),d0
|
move.l (VPOSR),d0
|
||||||
and.l #$1ff00,d0
|
and.l #$1ff00,d0
|
||||||
cmp.l #$8c00,d0
|
cmp.l #$bc00,d0
|
||||||
bne waitVBlank
|
bne waitVBlank
|
||||||
waitVBlank2:
|
waitVBlank2:
|
||||||
move.l (VPOSR),d0
|
move.l (VPOSR),d0
|
||||||
and.l #$1ff00,d0
|
and.l #$1ff00,d0
|
||||||
cmp.l #$8d00,d0
|
cmp.l #$bd00,d0
|
||||||
bne waitVBlank2
|
bne waitVBlank2
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
@ -146,9 +161,7 @@ testFF:
|
||||||
cmp.b #$ff,d0
|
cmp.b #$ff,d0
|
||||||
bne testOther
|
bne testOther
|
||||||
theEnd:
|
theEnd:
|
||||||
move.w #$fff,d4
|
lea sequence(pc),a2
|
||||||
move.w d4,COLOR00
|
|
||||||
bra theEnd
|
|
||||||
testOther:
|
testOther:
|
||||||
; something else
|
; something else
|
||||||
bra nextTick1
|
bra nextTick1
|
||||||
|
@ -187,11 +200,44 @@ testChannel:
|
||||||
chanNotZero:
|
chanNotZero:
|
||||||
; check for 8 (VOL)
|
; check for 8 (VOL)
|
||||||
cmp.b #8,d0
|
cmp.b #8,d0
|
||||||
bne chanOther
|
bne chanWaveChange
|
||||||
; write volume
|
; write volume
|
||||||
clr.w d2
|
clr.w d2
|
||||||
move.b (a2)+,d2
|
move.b (a2)+,d2
|
||||||
bra chanWrite
|
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:
|
chanOther:
|
||||||
; get value and write
|
; get value and write
|
||||||
clr.w d2
|
clr.w d2
|
||||||
|
@ -225,6 +271,7 @@ curColor:
|
||||||
|
|
||||||
state:
|
state:
|
||||||
dc.w 0 ; ticks
|
dc.w 0 ; ticks
|
||||||
|
dc.w 0 ; quit
|
||||||
|
|
||||||
cnop 0,4
|
cnop 0,4
|
||||||
|
|
||||||
|
@ -241,7 +288,8 @@ sequence:
|
||||||
sampleData:
|
sampleData:
|
||||||
incbin "sample.bin"
|
incbin "sample.bin"
|
||||||
|
|
||||||
;data_f
|
cnop 0,4
|
||||||
|
|
||||||
wavetable:
|
wavetable:
|
||||||
incbin "wave.bin"
|
incbin "wave.bin"
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,23 @@
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
#include "../platform/amiga.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> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
std::vector<DivROMExportOutput> ret;
|
std::vector<DivROMExportOutput> ret;
|
||||||
|
std::vector<WaveEntry> waves;
|
||||||
|
unsigned int wavesDataPtr=0;
|
||||||
|
WaveEntry curWaveState[4];
|
||||||
|
|
||||||
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
||||||
|
|
||||||
e->stop();
|
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);
|
sample->write(&((const unsigned char*)amiga->getSampleMem(0))[0x400],amiga->getSampleMemUsage(0)-0x400);
|
||||||
if (sample->tell()&1) sample->writeC(0);
|
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
|
// seq.bin
|
||||||
SafeWriter* seq=new SafeWriter;
|
SafeWriter* seq=new SafeWriter;
|
||||||
seq->init();
|
seq->init();
|
||||||
|
@ -86,8 +94,54 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
if (e->nextTick(false,true)) {
|
if (e->nextTick(false,true)) {
|
||||||
done=true;
|
done=true;
|
||||||
amiga->getRegisterWrites().clear();
|
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;
|
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
|
// get register writes
|
||||||
std::vector<DivRegWrite>& writes=amiga->getRegisterWrites();
|
std::vector<DivRegWrite>& writes=amiga->getRegisterWrites();
|
||||||
for (DivRegWrite& j: writes) {
|
for (DivRegWrite& j: writes) {
|
||||||
|
@ -144,6 +198,13 @@ std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
|
|
||||||
EXTERN_BUSY_END;
|
EXTERN_BUSY_END;
|
||||||
|
|
||||||
|
// wave.bin
|
||||||
|
SafeWriter* wave=new SafeWriter;
|
||||||
|
wave->init();
|
||||||
|
for (WaveEntry& i: waves) {
|
||||||
|
wave->write(i.data,i.width);
|
||||||
|
}
|
||||||
|
|
||||||
// finish
|
// finish
|
||||||
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));
|
||||||
|
|
|
@ -509,7 +509,7 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
||||||
if (dmaOn) rWrite(0x96,0x8000|dmaOn);
|
if (dmaOn) rWrite(0x96,0x8000|dmaOn);
|
||||||
|
|
||||||
for (int i=0; i<4; i++) {
|
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(0x200+i,(chan[i].irLocH<<16)|chan[i].irLocL);
|
||||||
addWrite(0x204+i,chan[i].irLen);
|
addWrite(0x204+i,chan[i].irLen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ class DivPlatformAmiga: public DivDispatch {
|
||||||
|
|
||||||
friend void putDispatchChip(void*,int);
|
friend void putDispatchChip(void*,int);
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
friend class DivExportAmigaValidation;
|
||||||
|
|
||||||
void irq(int ch);
|
void irq(int ch);
|
||||||
void rWrite(unsigned short addr, unsigned short val);
|
void rWrite(unsigned short addr, unsigned short val);
|
||||||
|
|
Loading…
Reference in a new issue