mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-30 08:23:01 +00:00
more
This commit is contained in:
parent
07ed76a63b
commit
ced4fd8ee1
8 changed files with 247 additions and 21 deletions
4
src/asm/68k/amigatest/Makefile
Normal file
4
src/asm/68k/amigatest/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
all: player
|
||||||
|
|
||||||
|
player: player.s
|
||||||
|
vasmm68k_mot -Fhunkexe -kick1hunks -o player player.s
|
|
@ -26,24 +26,23 @@ run a.out on Amiga. it should play the exported song.
|
||||||
|
|
||||||
# sequence format
|
# sequence format
|
||||||
|
|
||||||
## 00-0F: global
|
## 00-0F: per-channel (00, 10, 20, 30)
|
||||||
|
|
||||||
- 00: do nothing
|
- 00 xxxxxx yyyy: set loc/len
|
||||||
- 01: next tick
|
|
||||||
- 02 xx: wait
|
|
||||||
- 03 xxxx: wait
|
|
||||||
- 06 xxxx: write to DMACON
|
|
||||||
- 0a xxxx: write to INTENA
|
|
||||||
- 0e xxxx: write to ADKCON
|
|
||||||
|
|
||||||
## 10-1F: per-channel (10, 20, 30, 40)
|
|
||||||
|
|
||||||
- 10 xxxxxx yyyy zzzzzz wwww: set loc/len
|
|
||||||
- x: loc
|
- x: loc
|
||||||
- y: len
|
- y: len
|
||||||
- z: loc after interrupt
|
- 01 xxxx yy: initialize wavetable (xxxx: pos; yy: length)
|
||||||
- w: len after interrupt
|
- 06 xxxx: set period
|
||||||
- 12 xxxx yy: initialize wavetable (xxxx: pos; yy: length)
|
- 08 xx: set volume
|
||||||
- 16 xxxx: set period
|
- 0a xxxx: set data
|
||||||
- 18 xx: set volume
|
|
||||||
- 1a xxxx: set data
|
## F0-FF: global
|
||||||
|
|
||||||
|
- f0: do nothing
|
||||||
|
- f1: next tick
|
||||||
|
- f2 xx: wait
|
||||||
|
- f3 xxxx: wait
|
||||||
|
- f6 xxxx: write to DMACON
|
||||||
|
- fa xxxx: write to INTENA
|
||||||
|
- fe xxxx: write to ADKCON
|
||||||
|
- ff: end of song
|
||||||
|
|
|
@ -5,9 +5,34 @@
|
||||||
|
|
||||||
VPOSR = $dff004
|
VPOSR = $dff004
|
||||||
COLOR00 = $dff180
|
COLOR00 = $dff180
|
||||||
|
DMACONR = $dff002
|
||||||
|
DMACON = $dff096
|
||||||
|
AUD0LCH = $dff0a0
|
||||||
|
AUD0LCL = $dff0a2
|
||||||
|
AUD0LEN = $dff0a4
|
||||||
|
AUD0PER = $dff0a6
|
||||||
|
AUD0VOL = $dff0a8
|
||||||
|
AUD0DAT = $dff0aa
|
||||||
|
|
||||||
cseg
|
cseg
|
||||||
move.l #0,d0
|
move.w #15,d0
|
||||||
|
move.w d0,DMACON
|
||||||
|
|
||||||
|
testDMACon:
|
||||||
|
move.w DMACON,d0
|
||||||
|
btst #0,d0
|
||||||
|
bne testDMACon
|
||||||
|
|
||||||
|
lea sampleData(pc),a0
|
||||||
|
move.l a0,AUD0LCH
|
||||||
|
move.w #$2000,d0
|
||||||
|
move.w d0,AUD0LEN
|
||||||
|
move.w #$a0,d0
|
||||||
|
move.w d0,AUD0PER
|
||||||
|
move.w #$40,d0
|
||||||
|
move.w d0,AUD0VOL
|
||||||
|
move.l #$8201,d0
|
||||||
|
move.w d0,DMACON
|
||||||
|
|
||||||
main:
|
main:
|
||||||
jsr waitVBlank
|
jsr waitVBlank
|
||||||
|
@ -30,3 +55,14 @@ data_c
|
||||||
|
|
||||||
curColor:
|
curColor:
|
||||||
dc.w 0
|
dc.w 0
|
||||||
|
|
||||||
|
sampleData:
|
||||||
|
incbin "sample.bin"
|
||||||
|
|
||||||
|
data_f
|
||||||
|
|
||||||
|
sequence:
|
||||||
|
incbin "seq.bin"
|
||||||
|
|
||||||
|
wavetable:
|
||||||
|
incbin "wave.bin"
|
||||||
|
|
|
@ -48,6 +48,10 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
|
#define EXTERN_BUSY_BEGIN e->softLocked=false; e->isBusy.lock();
|
||||||
|
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
|
||||||
|
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev145"
|
#define DIV_VERSION "dev145"
|
||||||
#define DIV_ENGINE_VERSION 145
|
#define DIV_ENGINE_VERSION 145
|
||||||
// for imports
|
// for imports
|
||||||
|
|
|
@ -19,9 +19,135 @@
|
||||||
|
|
||||||
#include "amigaValidation.h"
|
#include "amigaValidation.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../platform/amiga.h"
|
||||||
|
|
||||||
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
std::vector<DivROMExportOutput> DivExportAmigaValidation::go(DivEngine* e) {
|
||||||
e->testFunction();
|
std::vector<DivROMExportOutput> ret;
|
||||||
|
DivPlatformAmiga* amiga=(DivPlatformAmiga*)e->getDispatch(0);
|
||||||
|
|
||||||
return std::vector<DivROMExportOutput>();
|
e->stop();
|
||||||
|
e->repeatPattern=false;
|
||||||
|
e->setOrder(0);
|
||||||
|
EXTERN_BUSY_BEGIN_SOFT;
|
||||||
|
|
||||||
|
// determine loop point
|
||||||
|
int loopOrder=0;
|
||||||
|
int loopRow=0;
|
||||||
|
int loopEnd=0;
|
||||||
|
e->walkSong(loopOrder,loopRow,loopEnd);
|
||||||
|
|
||||||
|
e->curOrder=0;
|
||||||
|
e->freelance=false;
|
||||||
|
e->playing=false;
|
||||||
|
e->extValuePresent=false;
|
||||||
|
e->remainingLoops=-1;
|
||||||
|
|
||||||
|
// play the song ourselves
|
||||||
|
bool done=false;
|
||||||
|
|
||||||
|
// sample.bin
|
||||||
|
SafeWriter* sample=new SafeWriter;
|
||||||
|
sample->init();
|
||||||
|
for (int i=0; i<256; i++) {
|
||||||
|
sample->writeI(0);
|
||||||
|
}
|
||||||
|
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++) {
|
||||||
|
sample->writeC(i<<3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// seq.bin
|
||||||
|
SafeWriter* seq=new SafeWriter;
|
||||||
|
seq->init();
|
||||||
|
|
||||||
|
amiga->toggleRegisterDump(true);
|
||||||
|
|
||||||
|
// write song data
|
||||||
|
e->playSub(false);
|
||||||
|
size_t songTick=0;
|
||||||
|
size_t lastTick=0;
|
||||||
|
bool writeLoop=false;
|
||||||
|
int loopPos=-1;
|
||||||
|
for (int i=0; i<e->chans; i++) {
|
||||||
|
e->chan[i].wentThroughNote=false;
|
||||||
|
e->chan[i].goneThroughNote=false;
|
||||||
|
}
|
||||||
|
while (!done) {
|
||||||
|
if (loopPos==-1) {
|
||||||
|
if (loopOrder==e->curOrder && loopRow==e->curRow && e->ticks==1) {
|
||||||
|
writeLoop=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e->nextTick(false,true)) {
|
||||||
|
done=true;
|
||||||
|
amiga->getRegisterWrites().clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// get register writes
|
||||||
|
std::vector<DivRegWrite>& writes=amiga->getRegisterWrites();
|
||||||
|
for (DivRegWrite& j: writes) {
|
||||||
|
if (lastTick!=songTick) {
|
||||||
|
int delta=songTick-lastTick;
|
||||||
|
if (delta==1) {
|
||||||
|
seq->writeC(0xf1);
|
||||||
|
} else if (delta<256) {
|
||||||
|
seq->writeC(0xf2);
|
||||||
|
seq->writeC(delta);
|
||||||
|
} else if (delta<65536) {
|
||||||
|
seq->writeC(0xf3);
|
||||||
|
seq->writeS_BE(delta);
|
||||||
|
}
|
||||||
|
lastTick=songTick;
|
||||||
|
}
|
||||||
|
if (j.addr>=0x200) { // direct loc/len change
|
||||||
|
if (j.addr&4) { // len
|
||||||
|
seq->writeS_BE(j.val);
|
||||||
|
} else { // loc
|
||||||
|
seq->writeC((j.addr&3)<<4);
|
||||||
|
seq->writeC(j.val>>16);
|
||||||
|
seq->writeC(j.val>>8);
|
||||||
|
seq->writeC(j.val);
|
||||||
|
}
|
||||||
|
} else if (j.addr<0xa0) {
|
||||||
|
// don't write INTENA
|
||||||
|
if ((j.addr&15)!=10) {
|
||||||
|
seq->writeC(0xf0|(j.addr&15));
|
||||||
|
seq->writeS_BE(j.val);
|
||||||
|
}
|
||||||
|
} else if ((j.addr&15)!=0 && (j.addr&15)!=2 && (j.addr&15)!=4) {
|
||||||
|
seq->writeC(j.addr-0xa0);
|
||||||
|
if ((j.addr&15)==8) {
|
||||||
|
seq->writeC(j.val);
|
||||||
|
} else {
|
||||||
|
seq->writeS_BE(j.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writes.clear();
|
||||||
|
|
||||||
|
songTick++;
|
||||||
|
}
|
||||||
|
// end of song
|
||||||
|
seq->writeC(0xff);
|
||||||
|
|
||||||
|
amiga->toggleRegisterDump(false);
|
||||||
|
|
||||||
|
e->remainingLoops=-1;
|
||||||
|
e->playing=false;
|
||||||
|
e->freelance=false;
|
||||||
|
e->extValuePresent=false;
|
||||||
|
|
||||||
|
EXTERN_BUSY_END;
|
||||||
|
|
||||||
|
// finish
|
||||||
|
ret.push_back(DivROMExportOutput("sample.bin",sample));
|
||||||
|
ret.push_back(DivROMExportOutput("wave.bin",wave));
|
||||||
|
ret.push_back(DivROMExportOutput("seq.bin",seq));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,6 +419,10 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
||||||
chWrite(i,0,0);
|
chWrite(i,0,0);
|
||||||
chWrite(i,2,i<<8);
|
chWrite(i,2,i<<8);
|
||||||
chWrite(i,4,chan[i].audLen);
|
chWrite(i,4,chan[i].audLen);
|
||||||
|
if (dumpWrites) {
|
||||||
|
addWrite(0x200+i,i<<8);
|
||||||
|
addWrite(0x204+i,chan[i].audLen);
|
||||||
|
}
|
||||||
rWrite(0x96,0x8000|(1<<i));
|
rWrite(0x96,0x8000|(1<<i));
|
||||||
} else {
|
} else {
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
|
@ -436,10 +440,18 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
||||||
chWrite(i,0,0);
|
chWrite(i,0,0);
|
||||||
chWrite(i,2,0x400);
|
chWrite(i,2,0x400);
|
||||||
chWrite(i,4,1);
|
chWrite(i,4,1);
|
||||||
|
if (dumpWrites) {
|
||||||
|
addWrite(0x200+i,0x400);
|
||||||
|
addWrite(0x204+i,1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
chWrite(i,0,start>>16);
|
chWrite(i,0,start>>16);
|
||||||
chWrite(i,2,start);
|
chWrite(i,2,start);
|
||||||
chWrite(i,4,len);
|
chWrite(i,4,len);
|
||||||
|
if (dumpWrites) {
|
||||||
|
addWrite(0x200+i,start);
|
||||||
|
addWrite(0x204+i,len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rWrite(0x96,0x8000|(1<<i));
|
rWrite(0x96,0x8000|(1<<i));
|
||||||
|
@ -454,11 +466,19 @@ void DivPlatformAmiga::tick(bool sysTick) {
|
||||||
chan[i].irLocL=0x400;
|
chan[i].irLocL=0x400;
|
||||||
chan[i].irLen=1;
|
chan[i].irLen=1;
|
||||||
}
|
}
|
||||||
|
if (dumpWrites) {
|
||||||
|
addWrite(0x200+i,(chan[i].irLocH<<16)|chan[i].irLocL);
|
||||||
|
addWrite(0x204+i,chan[i].irLen);
|
||||||
|
}
|
||||||
rWrite(0x9a,0x8000|(128<<i));
|
rWrite(0x9a,0x8000|(128<<i));
|
||||||
} else {
|
} else {
|
||||||
chWrite(i,0,0);
|
chWrite(i,0,0);
|
||||||
chWrite(i,2,0x400);
|
chWrite(i,2,0x400);
|
||||||
chWrite(i,4,1);
|
chWrite(i,4,1);
|
||||||
|
if (dumpWrites) {
|
||||||
|
addWrite(0x200+i,0x400);
|
||||||
|
addWrite(0x204+i,1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
|
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include "../fileutils.h"
|
||||||
#include "IconsFontAwesome4.h"
|
#include "IconsFontAwesome4.h"
|
||||||
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
// 0: all directions
|
// 0: all directions
|
||||||
|
@ -575,6 +577,40 @@ void FurnaceGUI::drawMobileControls() {
|
||||||
if (ImGui::Button("Switch to Desktop Mode")) {
|
if (ImGui::Button("Switch to Desktop Mode")) {
|
||||||
toggleMobileUI(!mobileUI);
|
toggleMobileUI(!mobileUI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int numAmiga=0;
|
||||||
|
for (int i=0; i<e->song.systemLen; i++) {
|
||||||
|
if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numAmiga) {
|
||||||
|
ImGui::Text(
|
||||||
|
"this is NOT ROM export! only use for making sure the\n"
|
||||||
|
"Furnace Amiga emulator is working properly by\n"
|
||||||
|
"comparing it with real Amiga output."
|
||||||
|
);
|
||||||
|
ImGui::Text("Directory");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::InputText("##AVDPath",&workingDirROMExport);
|
||||||
|
if (ImGui::Button("Bake Data")) {
|
||||||
|
std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
|
||||||
|
if (workingDirROMExport.size()>0) {
|
||||||
|
if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR;
|
||||||
|
}
|
||||||
|
for (DivROMExportOutput& i: out) {
|
||||||
|
String path=workingDirROMExport+i.name;
|
||||||
|
FILE* outFile=ps_fopen(path.c_str(),"wb");
|
||||||
|
if (outFile!=NULL) {
|
||||||
|
fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile);
|
||||||
|
fclose(outFile);
|
||||||
|
}
|
||||||
|
i.data->finish();
|
||||||
|
delete i.data;
|
||||||
|
}
|
||||||
|
showError(fmt::sprintf("Done! Baked %d files.",(int)out.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3697,6 +3697,7 @@ bool FurnaceGUI::loop() {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::InputText("##AVDPath",&workingDirROMExport);
|
ImGui::InputText("##AVDPath",&workingDirROMExport);
|
||||||
if (ImGui::Button("Bake Data")) {
|
if (ImGui::Button("Bake Data")) {
|
||||||
|
std::vector<DivROMExportOutput> out=e->buildROM(DIV_ROM_AMIGA_VALIDATION);
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
|
|
Loading…
Reference in a new issue