diff --git a/src/asm/68k/amigatest/README.md b/src/asm/68k/amigatest/README.md index 5ac4a9cd4..10af4a3b9 100644 --- a/src/asm/68k/amigatest/README.md +++ b/src/asm/68k/amigatest/README.md @@ -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 diff --git a/src/asm/68k/amigatest/player.s b/src/asm/68k/amigatest/player.s index 1a41bf835..42396ebf7 100644 --- a/src/asm/68k/amigatest/player.s +++ b/src/asm/68k/amigatest/player.s @@ -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" - diff --git a/src/engine/export/amigaValidation.cpp b/src/engine/export/amigaValidation.cpp index 7e63d3be4..dc836f33e 100644 --- a/src/engine/export/amigaValidation.cpp +++ b/src/engine/export/amigaValidation.cpp @@ -32,11 +32,21 @@ struct WaveEntry { } }; +struct SampleBookEntry { + unsigned int loc; + unsigned short len; + SampleBookEntry(): + loc(0), + len(0) {} +}; + std::vector DivExportAmigaValidation::go(DivEngine* e) { std::vector ret; std::vector waves; + std::vector sampleBook; unsigned int wavesDataPtr=0; WaveEntry curWaveState[4]; + unsigned int sampleBookLoc=0; DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0); @@ -133,11 +143,19 @@ std::vector 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 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; iwriteC((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 @@ -204,8 +245,29 @@ std::vector DivExportAmigaValidation::go(DivEngine* e) { for (WaveEntry& i: waves) { 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)); diff --git a/src/engine/safeWriter.cpp b/src/engine/safeWriter.cpp index a0c295d30..bd327607b 100644 --- a/src/engine/safeWriter.cpp +++ b/src/engine/safeWriter.cpp @@ -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); }