From 262eaa19c12ef3862defeef62968c1e5414f386b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 Mar 2023 01:44:35 -0500 Subject: [PATCH] Amiga: validation export wave support --- src/asm/68k/amigatest/README.md | 9 ++-- src/asm/68k/amigatest/player.s | 72 ++++++++++++++++++++----- src/engine/export/amigaValidation.cpp | 75 ++++++++++++++++++++++++--- src/engine/platform/amiga.cpp | 2 +- src/engine/platform/amiga.h | 1 + 5 files changed, 135 insertions(+), 24 deletions(-) diff --git a/src/asm/68k/amigatest/README.md b/src/asm/68k/amigatest/README.md index 22022982e..5ac4a9cd4 100644 --- a/src/asm/68k/amigatest/README.md +++ b/src/asm/68k/amigatest/README.md @@ -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 diff --git a/src/asm/68k/amigatest/player.s b/src/asm/68k/amigatest/player.s index 9234b17bd..1a41bf835 100644 --- a/src/asm/68k/amigatest/player.s +++ b/src/asm/68k/amigatest/player.s @@ -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" + diff --git a/src/engine/export/amigaValidation.cpp b/src/engine/export/amigaValidation.cpp index 385c8e3df..7e63d3be4 100644 --- a/src/engine/export/amigaValidation.cpp +++ b/src/engine/export/amigaValidation.cpp @@ -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 DivExportAmigaValidation::go(DivEngine* e) { std::vector ret; + std::vector waves; + unsigned int wavesDataPtr=0; + WaveEntry curWaveState[4]; + DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0); e->stop(); @@ -54,13 +69,6 @@ std::vector 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 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; jwriteC((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& writes=amiga->getRegisterWrites(); for (DivRegWrite& j: writes) { @@ -144,6 +198,13 @@ std::vector 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)); diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index e07fa80a7..14f2de80a 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -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<