diff --git a/Emulator/Agnus/AgnusDma.cpp b/Emulator/Agnus/AgnusDma.cpp index 441b70964..e493a761e 100644 --- a/Emulator/Agnus/AgnusDma.cpp +++ b/Emulator/Agnus/AgnusDma.cpp @@ -466,30 +466,30 @@ Agnus::updateBplEvents(u16 dmacon, u16 bplcon0, int first, int last) // Allocate slots if (hires) { - for (int i = first; i <= last; i++) + for (isize i = first; i <= last; i++) bplEvent[i] = inHiresDmaAreaOdd(i) ? bplDMA[1][channels][i] : inHiresDmaAreaEven(i) ? bplDMA[1][channels][i] : EVENT_NONE; // Add extra shift register events if the even/odd DDF windows differ // These events are like BPL_H0 events without performing DMA. - for (int i = ddfHires.strtEven; i < ddfHires.strtOdd; i++) + for (isize i = ddfHires.strtEven; i < ddfHires.strtOdd; i++) if ((i & 3) == 3 && bplEvent[i] == EVENT_NONE) bplEvent[i] = BPL_SR; - for (int i = ddfHires.stopOdd; i < ddfHires.stopEven; i++) + for (isize i = ddfHires.stopOdd; i < ddfHires.stopEven; i++) if ((i & 3) == 3 && bplEvent[i] == EVENT_NONE) bplEvent[i] = BPL_SR; } else { - for (int i = first; i <= last; i++) + for (isize i = first; i <= last; i++) bplEvent[i] = inLoresDmaAreaOdd(i) ? bplDMA[0][channels][i] : inLoresDmaAreaEven(i) ? bplDMA[0][channels][i] : EVENT_NONE; // Add extra shift register events if the even/odd DDF windows differ // These events are like BPL_L0 events without performing DMA. - for (int i = ddfLores.strtEven; i < ddfLores.strtOdd; i++) + for (isize i = ddfLores.strtEven; i < ddfLores.strtOdd; i++) if ((i & 7) == 7 && bplEvent[i] == EVENT_NONE) bplEvent[i] = BPL_SR; - for (int i = ddfLores.stopOdd; i < ddfLores.stopEven; i++) + for (isize i = ddfLores.stopOdd; i < ddfLores.stopEven; i++) if ((i & 7) == 7 && bplEvent[i] == EVENT_NONE) bplEvent[i] = BPL_SR; } diff --git a/Emulator/Agnus/Blitter/FastBlitter.cpp b/Emulator/Agnus/Blitter/FastBlitter.cpp index 624484a7b..7c2e16645 100644 --- a/Emulator/Agnus/Blitter/FastBlitter.cpp +++ b/Emulator/Agnus/Blitter/FastBlitter.cpp @@ -259,7 +259,7 @@ Blitter::doFastLineBlit() bool single_dot = false; u8 minterm = (u8)(bltcon >> 16); - for (int i = 0; i < height; ++i) + for (isize i = 0; i < height; ++i) { // Read C-data from memory if the C-channel is enabled if (c_enabled) { diff --git a/Emulator/Agnus/Copper/Copper.cpp b/Emulator/Agnus/Copper/Copper.cpp index a1d50f07e..e3c3970bb 100644 --- a/Emulator/Agnus/Copper/Copper.cpp +++ b/Emulator/Agnus/Copper/Copper.cpp @@ -134,7 +134,7 @@ Copper::findVerticalMatch(i16 vStrt, i16 vComp, i16 vMask, i16 &result) const i16 vStop = agnus.frame.numLines(); // Iterate through all vertical positions - for (int v = vStrt; v < vStop; v++) { + for (isize v = vStrt; v < vStop; v++) { // Check if the comparator triggers at this position if ((v & vMask) >= (vComp & vMask)) { @@ -151,7 +151,7 @@ Copper::findHorizontalMatch(i16 hStrt, i16 hComp, i16 hMask, i16 &result) const i16 hStop = HPOS_CNT; // Iterate through all horizontal positions - for (int h = hStrt; h < hStop; h++) { + for (isize h = hStrt; h < hStop; h++) { // Check if the comparator triggers at this position if ((h & hMask) >= (hComp & hMask)) { diff --git a/Emulator/Agnus/EventHandler.h b/Emulator/Agnus/EventHandler.h index a87bfa035..b3ed0d19b 100644 --- a/Emulator/Agnus/EventHandler.h +++ b/Emulator/Agnus/EventHandler.h @@ -51,20 +51,16 @@ public: // Returns true iff the specified slot contains any event -template bool hasEvent() const { - assert(s < SLOT_COUNT); return slot[s].id != (EventID)0; } +template bool hasEvent() const { return slot[s].id != (EventID)0; } // Returns true iff the specified slot contains a specific event -template bool hasEvent(EventID id) const { - assert(s < SLOT_COUNT); return slot[s].id == id; } +template bool hasEvent(EventID id) const { return slot[s].id == id; } // Returns true iff the specified slot contains a pending event -template bool isPending() const { - assert(s < SLOT_COUNT); return slot[s].triggerCycle != NEVER; } +template bool isPending() const { return slot[s].triggerCycle != NEVER; } // Returns true iff the specified slot contains a due event -template bool isDue(Cycle cycle) const { - assert(s < SLOT_COUNT); return cycle >= slot[s].triggerCycle; } +template bool isDue(Cycle cycle) const { return cycle >= slot[s].triggerCycle; } // diff --git a/Emulator/Amiga.cpp b/Emulator/Amiga.cpp index 8f5832b09..afb2cb424 100644 --- a/Emulator/Amiga.cpp +++ b/Emulator/Amiga.cpp @@ -214,7 +214,6 @@ Amiga::getConfigItem(Option option) const return agnus.getConfigItem(option); case OPT_DENISE_REVISION: - case OPT_BRDRBLNK: case OPT_HIDDEN_SPRITES: case OPT_HIDDEN_LAYERS: case OPT_HIDDEN_LAYER_ALPHA: @@ -280,12 +279,15 @@ Amiga::getConfigItem(Option option, long id) const case OPT_DRIVE_TYPE: case OPT_EMULATE_MECHANICS: - case OPT_DRIVE_NOISE_ENABLE: - case OPT_DRIVE_EJECT_NOISE: - case OPT_DRIVE_INSERT_NOISE: - case OPT_DRIVE_STEP_NOISE: - case OPT_DRIVE_POLL_NOISE: - + case OPT_DRIVE_PAN: + case OPT_STEP_VOLUME: + case OPT_POLL_VOLUME: + case OPT_INSERT_VOLUME: + case OPT_EJECT_VOLUME: + return df[id]->getConfigItem(option); + + case OPT_DEFAULT_FILESYSTEM: + case OPT_DEFAULT_BOOTBLOCK: return df[id]->getConfigItem(option); case OPT_PULLUP_RESISTORS: @@ -309,7 +311,7 @@ Amiga::configure(Option option, long value) // Inform the GUI if the configuration has changed if (changed) queue.put(MSG_CONFIG); - // Dump the current configuration in debugging mode + // Dump the current configuration in debug mode if (changed && CNF_DEBUG) dump(Dump::Config); return changed; @@ -323,8 +325,8 @@ Amiga::configure(Option option, long id, long value) // Inform the GUI if the configuration has changed if (changed) queue.put(MSG_CONFIG); - - // Dump the current configuration in debugging mode + + // Dump the current configuration in debug mode if (changed && CNF_DEBUG) dump(Dump::Config); return changed; @@ -365,7 +367,15 @@ void Amiga::_dump(Dump::Category category, std::ostream& os) const { if (category & Dump::Config) { - + + if (CNF_DEBUG) { + + df0.dump(Dump::Config); + paula.dump(Dump::Config); + paula.muxer.dump(Dump::Config); + ciaA.dump(Dump::Config); + denise.dump(Dump::Config); + } } if (category & Dump::State) { diff --git a/Emulator/AmigaPublicTypes.h b/Emulator/AmigaPublicTypes.h index d79e9acee..5c46687d2 100644 --- a/Emulator/AmigaPublicTypes.h +++ b/Emulator/AmigaPublicTypes.h @@ -25,7 +25,6 @@ enum_long(OPT) // Denise OPT_DENISE_REVISION, - OPT_BRDRBLNK, // Real-time clock OPT_RTC_MODEL, @@ -43,17 +42,19 @@ enum_long(OPT) // Disk controller OPT_DRIVE_CONNECT, OPT_DRIVE_SPEED, - OPT_DRIVE_NOISE_ENABLE, - OPT_DRIVE_EJECT_NOISE, - OPT_DRIVE_INSERT_NOISE, - OPT_DRIVE_STEP_NOISE, - OPT_DRIVE_POLL_NOISE, OPT_LOCK_DSKSYNC, OPT_AUTO_DSKSYNC, // Drives OPT_DRIVE_TYPE, OPT_EMULATE_MECHANICS, + OPT_DRIVE_PAN, + OPT_STEP_VOLUME, + OPT_POLL_VOLUME, + OPT_INSERT_VOLUME, + OPT_EJECT_VOLUME, + OPT_DEFAULT_FILESYSTEM, + OPT_DEFAULT_BOOTBLOCK, // Ports OPT_SERIAL_DEVICE, @@ -79,6 +80,7 @@ enum_long(OPT) // Mouse OPT_PULLUP_RESISTORS, + OPT_SHAKE_DETECTION, OPT_MOUSE_VELOCITY, // Paula audio diff --git a/Emulator/AmigaTypes.h b/Emulator/AmigaTypes.h index 19fecf733..877ebca96 100644 --- a/Emulator/AmigaTypes.h +++ b/Emulator/AmigaTypes.h @@ -32,7 +32,6 @@ struct OptionEnum : Reflection { case OPT_SLOW_RAM_MIRROR: return "SLOW_RAM_MIRROR"; case OPT_DENISE_REVISION: return "DENISE_REVISION"; - case OPT_BRDRBLNK: return "BRDRBLNK"; case OPT_RTC_MODEL: return "RTC_MODEL"; @@ -47,17 +46,18 @@ struct OptionEnum : Reflection { case OPT_DRIVE_CONNECT: return "DRIVE_CONNECT"; case OPT_DRIVE_SPEED: return "DRIVE_SPEED"; - case OPT_DRIVE_NOISE_ENABLE: return "DRIVE_NOISE_ENABLE"; - case OPT_DRIVE_INSERT_NOISE: return "DRIVE_NOISE_INSERT"; - case OPT_DRIVE_EJECT_NOISE: return "DRIVE_NOISE_EJECT"; - case OPT_DRIVE_STEP_NOISE: return "DRIVE_NOISE_STEP"; - case OPT_DRIVE_POLL_NOISE: return "DRIVE_NOISE_POLL"; - case OPT_LOCK_DSKSYNC: return "LOCK_DSKSYNC"; case OPT_AUTO_DSKSYNC: return "AUTO_DSKSYNC"; case OPT_DRIVE_TYPE: return "DRIVE_TYPE"; case OPT_EMULATE_MECHANICS: return "EMULATE_MECHANICS"; + case OPT_DRIVE_PAN: return "DRIVE_PAN"; + case OPT_STEP_VOLUME: return "STEP_VOLUME"; + case OPT_POLL_VOLUME: return "POLL_VOLUME"; + case OPT_INSERT_VOLUME: return "INSERT_VOLUME"; + case OPT_EJECT_VOLUME: return "EJECT_VOLUME"; + case OPT_DEFAULT_FILESYSTEM: return "DEFAULT_FILESYSTEM"; + case OPT_DEFAULT_BOOTBLOCK: return "DEFAULT_BOOTBLOCK"; case OPT_SERIAL_DEVICE: return "SERIAL_DEVICE"; diff --git a/Emulator/Base/Makefile b/Emulator/Base/Makefile new file mode 100644 index 000000000..020279d7a --- /dev/null +++ b/Emulator/Base/Makefile @@ -0,0 +1,15 @@ +SRC=$(wildcard *.cpp) +OBJ=$(SRC:.cpp=.o) + +.PHONY: all clean + +all: $(OBJ) + @echo > /dev/null + +clean: + @echo "Cleaning up $(CURDIR)" + @rm -f *.o + +%.o: %.cpp $(DEPS) + @echo "Compiling $<" + @$(MYCC) $(MYFLAGS) -c -o $@ $< diff --git a/Emulator/Base/MsgQueue.cpp b/Emulator/Base/MsgQueue.cpp index 9991e8437..c1a8778f5 100644 --- a/Emulator/Base/MsgQueue.cpp +++ b/Emulator/Base/MsgQueue.cpp @@ -28,15 +28,23 @@ MsgQueue::addListener(const void *listener, Callback *func) void MsgQueue::removeListener(const void *listener) -{ - put(MSG_UNREGISTER); +{ + Callback *callback = nullptr; synchronized { for (auto it = listeners.begin(); it != listeners.end(); it++) { - if (it->first == listener) { listeners.erase(it); break; } + + if (it->first == listener) { + callback = it->second; + listeners.erase(it); + break; + } } } + + // Send a last message to the listener + if (callback) callback(listener, MSG_UNREGISTER, 0); } Message diff --git a/Emulator/Base/MsgQueuePublicTypes.h b/Emulator/Base/MsgQueuePublicTypes.h index 3f9d678c1..b72f892bc 100644 --- a/Emulator/Base/MsgQueuePublicTypes.h +++ b/Emulator/Base/MsgQueuePublicTypes.h @@ -55,13 +55,10 @@ enum_long(MSG_TYPE) MSG_DRIVE_LED_OFF, MSG_DRIVE_MOTOR_ON, MSG_DRIVE_MOTOR_OFF, - MSG_DRIVE_HEAD, - MSG_DRIVE_HEAD_NOISE, - MSG_DRIVE_HEAD_POLL, // DEPRECATED + MSG_DRIVE_STEP, + MSG_DRIVE_POLL, MSG_DISK_INSERT, - MSG_DISK_INSERT_NOISE, MSG_DISK_EJECT, - MSG_DISK_EJECT_NOISE, MSG_DISK_SAVED, MSG_DISK_UNSAVED, MSG_DISK_PROTECT, diff --git a/Emulator/Base/MsgQueueTypes.h b/Emulator/Base/MsgQueueTypes.h index 0d5450013..f596ae445 100644 --- a/Emulator/Base/MsgQueueTypes.h +++ b/Emulator/Base/MsgQueueTypes.h @@ -58,13 +58,10 @@ struct MsgTypeEnum : Reflection { case MSG_DRIVE_LED_OFF: return "DRIVE_LED_OFF"; case MSG_DRIVE_MOTOR_ON: return "DRIVE_MOTOR_ON"; case MSG_DRIVE_MOTOR_OFF: return "DRIVE_MOTOR_OFF"; - case MSG_DRIVE_HEAD: return "DRIVE_HEAD"; - case MSG_DRIVE_HEAD_NOISE: return "DRIVE_HEAD_NOISE"; - case MSG_DRIVE_HEAD_POLL: return "DRIVE_HEAD_POLL"; + case MSG_DRIVE_STEP: return "DRIVE_STEP"; + case MSG_DRIVE_POLL: return "DRIVE_POLL"; case MSG_DISK_INSERT: return "DISK_INSERT"; - case MSG_DISK_INSERT_NOISE: return "DISK_INSERT_SOUND"; case MSG_DISK_EJECT: return "DISK_EJECT"; - case MSG_DISK_EJECT_NOISE: return "DISK_EJECT_SOUND"; case MSG_DISK_SAVED: return "DISK_SAVED"; case MSG_DISK_UNSAVED: return "DISK_UNSAVED"; case MSG_DISK_PROTECT: return "DISK_PROTECT"; diff --git a/Emulator/CPU/CPU.cpp b/Emulator/CPU/CPU.cpp index 414c3f2d7..30d028500 100644 --- a/Emulator/CPU/CPU.cpp +++ b/Emulator/CPU/CPU.cpp @@ -15,8 +15,14 @@ #include "Memory.h" #include "MsgQueue.h" +// +// Moira +// + +namespace moira { + void -CPU::sync(int cycles) +Moira::sync(int cycles) { // Advance the CPU clock clock += cycles; @@ -26,61 +32,31 @@ CPU::sync(int cycles) } u8 -CPU::read8(u32 addr) +Moira::read8(u32 addr) { return mem.peek8 (addr); } u16 -CPU::read16(u32 addr) -{ - u16 result = mem.peek16 (addr); - - /* - static int counter = 0; - if (addr == 0xc001b0) { - if (counter == 928) { - amiga.signalStop(); - // COPREG_DEBUG = 1; - } - debug("%d: exec::allocMem(%x,%x)\n", counter++, reg.d[0], reg.d[1]); - } - */ - /* - if (addr >= 0xE80000 && addr <= 0xE8FFFF) { - debug("get_word: Zorro(%x) = %x\n", addr, result); - } - */ - /* - if (addr >= 0xDC0000 && addr <= 0xDEFFFF) { - debug("read16(%x) = %x\n", addr, result); - } - - if (addr >= 0xD80000 && addr <= 0xD8FFFF) { - debug("read16(%x) = %x (%x,%x %x,%x %x,%x)\n", addr, result, - agnus.busOwner[agnus.pos.h-2], agnus.busValue[agnus.pos.h-2], - agnus.busOwner[agnus.pos.h-1], agnus.busValue[agnus.pos.h-1], - agnus.busOwner[agnus.pos.h-0], agnus.busValue[agnus.pos.h-0]); - } - */ - - return result; +Moira::read16(u32 addr) +{ + return mem.peek16 (addr); } u16 -CPU::read16Dasm(u32 addr) +Moira::read16Dasm(u32 addr) { return mem.spypeek16 (addr); } u16 -CPU::read16OnReset(u32 addr) +Moira::read16OnReset(u32 addr) { return mem.chip ? read16(addr) : 0; } void -CPU::write8(u32 addr, u8 val) +Moira::write8(u32 addr, u8 val) { trace(XFILES && addr - reg.pc < 5, "XFILES: write8 close to PC %x\n", reg.pc); @@ -88,22 +64,28 @@ CPU::write8(u32 addr, u8 val) } void -CPU::write16 (u32 addr, u16 val) +Moira::write16 (u32 addr, u16 val) { trace(XFILES && addr - reg.pc < 5, "XFILES: write16 close to PC %x\n", reg.pc); mem.poke16 (addr, val); } +u16 +Moira::readIrqUserVector(u8 level) const +{ + return 0; +} + void -CPU::signalReset() +Moira::signalReset() { trace(XFILES, "XFILES: RESET instruction\n"); amiga.softReset(); } void -CPU::signalStop(u16 op) +Moira::signalStop(u16 op) { if (!(op & 0x2000)) { trace(XFILES, "XFILES: STOP instruction (%x)\n", op); @@ -111,67 +93,67 @@ CPU::signalStop(u16 op) } void -CPU::signalTAS() +Moira::signalTAS() { trace(XFILES, "XFILES: TAS instruction\n"); } void -CPU::signalHalt() +Moira::signalHalt() { messageQueue.put(MSG_CPU_HALT); } void -CPU::signalAddressError(moira::AEStackFrame &frame) +Moira::signalAddressError(moira::AEStackFrame &frame) { trace(XFILES, "XFILES: Address error exception %x %x %x %x %x\n", frame.code, frame.addr, frame.ird, frame.sr, frame.pc); } void -CPU::signalLineAException(u16 opcode) +Moira::signalLineAException(u16 opcode) { trace(XFILES, "XFILES: lineAException(%x)\n", opcode); } void -CPU::signalLineFException(u16 opcode) +Moira::signalLineFException(u16 opcode) { trace(XFILES, "XFILES: lineFException(%x)\n", opcode); } void -CPU::signalIllegalOpcodeException(u16 opcode) +Moira::signalIllegalOpcodeException(u16 opcode) { trace(XFILES, "XFILES: illegalOpcodeException(%x)\n", opcode); } void -CPU::signalTraceException() +Moira::signalTraceException() { // debug(XFILES, "XFILES: traceException\n"); } void -CPU::signalTrapException() +Moira::signalTrapException() { trace(XFILES, "XFILES: trapException\n"); } void -CPU::signalPrivilegeViolation() +Moira::signalPrivilegeViolation() { } void -CPU::signalInterrupt(u8 level) +Moira::signalInterrupt(u8 level) { debug(INT_DEBUG, "Executing level %d IRQ\n", level); } void -CPU::signalJumpToVector(int nr, u32 addr) +Moira::signalJumpToVector(int nr, u32 addr) { bool isIrqException = nr >= 24 && nr <= 31; @@ -181,18 +163,30 @@ CPU::signalJumpToVector(int nr, u32 addr) } void -CPU::breakpointReached(u32 addr) +Moira::addressErrorHandler() +{ + +} + +void +Moira::breakpointReached(u32 addr) { amiga.setControlFlags(RL_BREAKPOINT_REACHED); } void -CPU::watchpointReached(u32 addr) +Moira::watchpointReached(u32 addr) { amiga.setControlFlags(RL_WATCHPOINT_REACHED); } -CPU::CPU(Amiga& ref) : AmigaComponent(ref) +} + +// +// CPU +// + +CPU::CPU(Amiga& ref) : moira::Moira(ref) { } diff --git a/Emulator/CPU/CPU.h b/Emulator/CPU/CPU.h index 09100b5ce..3e0c214d7 100644 --- a/Emulator/CPU/CPU.h +++ b/Emulator/CPU/CPU.h @@ -14,7 +14,7 @@ #include "Moira.h" #include "Macros.h" -class CPU : public AmigaComponent, public moira::Moira { +class CPU : public moira::Moira { // Result of the latest inspection CPUInfo info; @@ -116,6 +116,7 @@ class CPU : public AmigaComponent, public moira::Moira { private: + /* void sync(int cycles) override; u8 read8(u32 addr) override; u16 read16(u32 addr) override; @@ -144,7 +145,7 @@ class CPU : public AmigaComponent, public moira::Moira { void breakpointReached(u32 addr) override; void watchpointReached(u32 addr) override; - + */ // // Working with the clock diff --git a/Emulator/CPU/Moira/Moira.cpp b/Emulator/CPU/Moira/Moira.cpp index c278587fb..010641de9 100644 --- a/Emulator/CPU/Moira/Moira.cpp +++ b/Emulator/CPU/Moira/Moira.cpp @@ -22,11 +22,12 @@ namespace moira { #include "StrWriter_cpp.h" #include "MoiraDasm_cpp.h" -Moira::Moira() +Moira::Moira(Amiga &ref) : AmigaComponent(ref) { if (BUILD_INSTR_INFO_TABLE) info = new InstrInfo[65536]; if (ENABLE_DASM) dasm = new DasmPtr[65536]; + printf("sizeof(ExecPtr) = %zu\n", sizeof(ExecPtr)); createJumpTables(); } diff --git a/Emulator/CPU/Moira/Moira.h b/Emulator/CPU/Moira/Moira.h index f6452d1ee..25a4b7a2e 100644 --- a/Emulator/CPU/Moira/Moira.h +++ b/Emulator/CPU/Moira/Moira.h @@ -9,6 +9,8 @@ #pragma once +#include "AmigaComponent.h" + #include "MoiraConfig.h" #include "MoiraTypes.h" #include "MoiraDebugger.h" @@ -21,7 +23,7 @@ namespace moira { // Execution control flags -class Moira { +class Moira : public AmigaComponent { friend class Debugger; friend class Breakpoints; @@ -136,7 +138,7 @@ class Moira { public: - Moira(); + Moira(Amiga &ref); virtual ~Moira(); void createJumpTables(); @@ -202,6 +204,8 @@ class Moira { protected: +#if 0 + // Reads a byte or a word from memory virtual u8 read8(u32 addr) = 0; virtual u16 read16(u32 addr) = 0; @@ -245,6 +249,51 @@ class Moira { // Called when a breakpoint is reached virtual void watchpointReached(u32 addr) { }; +#endif + + // Reads a byte or a word from memory + u8 read8(u32 addr); + u16 read16(u32 addr); + + // Special variants used by the reset routine and the disassembler + u16 read16OnReset(u32 addr); + u16 read16Dasm(u32 addr); + + // Writes a byte or word into memory + void write8 (u32 addr, u8 val); + void write16 (u32 addr, u16 val); + + // Provides the interrupt level in IRQ_USER mode + u16 readIrqUserVector(u8 level) const; + + // Instrution delegates + void signalReset(); + void signalStop(u16 op); + void signalTAS(); + + // State delegates + void signalHalt(); + + // Exception delegates + void signalAddressError(AEStackFrame &frame); + void signalLineAException(u16 opcode); + void signalLineFException(u16 opcode); + void signalIllegalOpcodeException(u16 opcode); + void signalTraceException(); + void signalTrapException(); + void signalPrivilegeViolation(); + void signalInterrupt(u8 level); + void signalJumpToVector(int nr, u32 addr); + + // Exception delegates + void addressErrorHandler(); + + // Called when a breakpoint is reached + void breakpointReached(u32 addr); + + // Called when a breakpoint is reached + void watchpointReached(u32 addr); + // // Accessing the clock @@ -258,7 +307,8 @@ class Moira { protected: // Advances the clock (called before each memory access) - virtual void sync(int cycles) { clock += cycles; } + void sync(int cycles); + // virtual void sync(int cycles) { clock += cycles; } // diff --git a/Emulator/Denise/Denise.cpp b/Emulator/Denise/Denise.cpp index 7afb44a5a..53937afe6 100644 --- a/Emulator/Denise/Denise.cpp +++ b/Emulator/Denise/Denise.cpp @@ -51,7 +51,6 @@ Denise::getConfigItem(Option option) const switch (option) { case OPT_DENISE_REVISION: return config.revision; - case OPT_BRDRBLNK: return config.borderblank; case OPT_HIDDEN_SPRITES: return config.hiddenSprites; case OPT_HIDDEN_LAYERS: return config.hiddenLayers; case OPT_HIDDEN_LAYER_ALPHA: return config.hiddenLayerAlpha; @@ -81,16 +80,7 @@ Denise::setConfigItem(Option option, long value) config.revision = (DeniseRevision)value; return true; - - case OPT_BRDRBLNK: - - if (config.borderblank == value) { - return false; - } - - config.borderblank = value; - return true; - + case OPT_HIDDEN_SPRITES: if (config.hiddenSprites == value) { @@ -189,8 +179,6 @@ Denise::_dump(Dump::Category category, std::ostream& os) const printf("_dump(Config)\n"); os << DUMP("Chip revision"); os << DeniseRevisionEnum::key(config.revision) << std::endl; - os << DUMP("Borderblank"); - os << YESNO(config.borderblank) << std::endl; os << DUMP("Hidden sprites"); os << HEX8 << (int)config.hiddenSprites << std::endl; os << DUMP("Hidden layers"); @@ -919,7 +907,7 @@ Denise::drawAttachedSpritePixelPair(Pixel hpos) void Denise::updateBorderColor() { - if (config.borderblank && ecsena() && BRDRBLNK()) { + if (config.revision != DENISE_OCS && ecsena() && BRDRBLNK()) { borderColor = 64; // Pure black } else { borderColor = 0; // Background color diff --git a/Emulator/Denise/DenisePublicTypes.h b/Emulator/Denise/DenisePublicTypes.h index e6075a3bd..e7ab4f817 100644 --- a/Emulator/Denise/DenisePublicTypes.h +++ b/Emulator/Denise/DenisePublicTypes.h @@ -19,8 +19,9 @@ enum_long(DENISE_REV) { - DENISE_OCS, // Revision 8362R8 - DENISE_ECS, // Revision 8373 (not supported yet) + DENISE_OCS, // Revision 8362R8 + DENISE_OCS_BRDRBLNK, // Revision 8362R8 + ECS Border blank feature + DENISE_ECS, // Revision 8373 (not supported yet) DENISE_COUNT }; @@ -71,9 +72,6 @@ typedef struct { // Emulated chip model DeniseRevision revision; - - // Borderblank feature (was introduced with ECS chipset) - bool borderblank; // Hides certain sprites u8 hiddenSprites; diff --git a/Emulator/Denise/DeniseTypes.h b/Emulator/Denise/DeniseTypes.h index f981d3b26..81055f672 100644 --- a/Emulator/Denise/DeniseTypes.h +++ b/Emulator/Denise/DeniseTypes.h @@ -28,9 +28,10 @@ struct DeniseRevisionEnum : Reflection { { switch (value) { - case DENISE_OCS: return "OCS"; - case DENISE_ECS: return "ECS"; - case DENISE_COUNT: return "???"; + case DENISE_OCS: return "OCS"; + case DENISE_OCS_BRDRBLNK: return "OCS_BRDRBLNK"; + case DENISE_ECS: return "ECS"; + case DENISE_COUNT: return "???"; } return "???"; } diff --git a/Emulator/Drive/Drive.cpp b/Emulator/Drive/Drive.cpp index e0efc9537..dca5c0b12 100644 --- a/Emulator/Drive/Drive.cpp +++ b/Emulator/Drive/Drive.cpp @@ -13,6 +13,7 @@ #include "Agnus.h" #include "CIA.h" #include "DiskFile.h" +#include "FSDevice.h" #include "MsgQueue.h" Drive::Drive(Amiga& ref, isize n) : AmigaComponent(ref), nr(n) @@ -24,6 +25,8 @@ Drive::Drive(Amiga& ref, isize n) : AmigaComponent(ref), nr(n) config.startDelay = MSEC(380); config.stopDelay = MSEC(80); config.stepDelay = USEC(8000); + config.defaultFileSystem = FS_OFS; + config.defaultBootBlock = BB_NONE; } const char * @@ -46,11 +49,13 @@ Drive::getConfigItem(Option option) const case OPT_DRIVE_TYPE: return (long)config.type; case OPT_EMULATE_MECHANICS: return (long)config.mechanicalDelays; - case OPT_DRIVE_NOISE_ENABLE: return (long)config.noiseEnable; - case OPT_DRIVE_EJECT_NOISE: return (long)config.noiseEject; - case OPT_DRIVE_INSERT_NOISE: return (long)config.noiseInsert; - case OPT_DRIVE_STEP_NOISE: return (long)config.noiseStep; - case OPT_DRIVE_POLL_NOISE: return (long)config.noisePoll; + case OPT_DRIVE_PAN: return (long)config.pan; + case OPT_STEP_VOLUME: return (long)config.stepVolume; + case OPT_POLL_VOLUME: return (long)config.pollVolume; + case OPT_EJECT_VOLUME: return (long)config.ejectVolume; + case OPT_INSERT_VOLUME: return (long)config.insertVolume; + case OPT_DEFAULT_FILESYSTEM: return (long)config.defaultFileSystem; + case OPT_DEFAULT_BOOTBLOCK: return (long)config.defaultBootBlock; default: assert(false); @@ -58,6 +63,12 @@ Drive::getConfigItem(Option option) const } } +bool +Drive::setConfigItem(Option option, long value) +{ + return setConfigItem(option, nr, value); +} + bool Drive::setConfigItem(Option option, long id, long value) { @@ -75,11 +86,9 @@ Drive::setConfigItem(Option option, long id, long value) if (config.type == value) { return false; } - if (value != DRIVE_DD_35 && value != DRIVE_HD_35) { throw ConfigUnsupportedError(); } - config.type = (DriveType)value; return true; @@ -88,48 +97,63 @@ Drive::setConfigItem(Option option, long id, long value) if (config.mechanicalDelays == value) { return false; } - config.mechanicalDelays = value; return true; - case OPT_DRIVE_NOISE_ENABLE: - - if (config.noiseEnable == value) { + case OPT_DRIVE_PAN: + + if (config.pan == value) { return false; } - config.noiseEnable = value; + config.pan = value; return true; - - case OPT_DRIVE_EJECT_NOISE: - if (config.noiseEject == value) { + case OPT_STEP_VOLUME: + + if (config.stepVolume == value) { return false; } - config.noiseEject = value; + config.stepVolume = value; return true; - case OPT_DRIVE_INSERT_NOISE: + case OPT_POLL_VOLUME: - if (config.noiseInsert == value) { + if (config.pollVolume == value) { return false; } - config.noiseInsert = value; + config.pollVolume = value; return true; - case OPT_DRIVE_STEP_NOISE: + case OPT_EJECT_VOLUME: - if (config.noiseStep == value) { + if (config.ejectVolume == value) { return false; } - config.noiseStep = value; + config.ejectVolume = value; return true; - case OPT_DRIVE_POLL_NOISE: + case OPT_INSERT_VOLUME: - if (config.noisePoll == value) { + if (config.insertVolume == value) { return false; } - config.noisePoll = value; + config.insertVolume = value; + return true; + + case OPT_DEFAULT_FILESYSTEM: + + if (config.defaultFileSystem == value) { + return false; + } + config.defaultFileSystem = value; + return true; + + case OPT_DEFAULT_BOOTBLOCK: + + if (config.defaultBootBlock == value) { + return false; + } + config.defaultBootBlock = value; return true; default: @@ -158,11 +182,12 @@ Drive::_dump(Dump::Category category, std::ostream& os) const os << DUMP("Start delay") << DEC << config.startDelay << std::endl; os << DUMP("Stop delay") << DEC << config.stopDelay << std::endl; os << DUMP("Step delay") << DEC << config.stepDelay << std::endl; - os << DUMP("Noise enable") << ISENABLED(config.noiseEnable) << std::endl; - os << DUMP("Insert noise") << ISENABLED(config.noiseInsert) << std::endl; - os << DUMP("Eject noise") << ISENABLED(config.noiseEject) << std::endl; - os << DUMP("Head step noise") << ISENABLED(config.noiseStep) << std::endl; - os << DUMP("head poll noise") << ISENABLED(config.noisePoll) << std::endl; + os << DUMP("Insert volume") << ISENABLED(config.insertVolume) << std::endl; + os << DUMP("Eject volume") << ISENABLED(config.ejectVolume) << std::endl; + os << DUMP("Step volume") << ISENABLED(config.stepVolume) << std::endl; + os << DUMP("Poll volume") << ISENABLED(config.pollVolume) << std::endl; + os << DUMP("Default file system") << FSVolumeTypeEnum::key(config.defaultFileSystem) << std::endl; + os << DUMP("Default boot block") << BootBlockIdEnum::key(config.defaultBootBlock) << std::endl; } if (category & Dump::State) { @@ -546,12 +571,14 @@ Drive::step(isize dir) if (ALIGN_HEAD) head.offset = 0; // Notify the GUI - if (config.noiseEnable && (pollsForDisk() ? config.noisePoll : config.noiseStep)) { - messageQueue.put(MSG_DRIVE_HEAD_NOISE, (nr << 8) | head.cylinder); + if (pollsForDisk()) { + messageQueue.put(MSG_DRIVE_POLL, + config.pan << 24 | config.pollVolume << 16 | head.cylinder << 8 | nr); } else { - messageQueue.put(MSG_DRIVE_HEAD, (nr << 8) | head.cylinder); + messageQueue.put(MSG_DRIVE_STEP, + config.pan << 24 | config.stepVolume << 16 | head.cylinder << 8 | nr); } - + // Remember when we've performed the step stepCycle = agnus.clock; } @@ -645,11 +672,8 @@ Drive::ejectDisk() disk = nullptr; // Notify the GUI - if (config.noiseEnable && config.noiseEject) { - messageQueue.put(MSG_DISK_EJECT_NOISE, nr); - } else { - messageQueue.put(MSG_DISK_EJECT, nr); - } + messageQueue.put(MSG_DISK_EJECT, + config.pan << 24 | config.ejectVolume << 16 | nr); } } @@ -711,12 +735,24 @@ Drive::insertDisk(Disk *disk) head.offset = 0; // Notify the GUI - if (config.noiseEnable && config.noiseInsert) { - messageQueue.put(MSG_DISK_INSERT_NOISE, nr); - } else { - messageQueue.put(MSG_DISK_INSERT, nr); - } + messageQueue.put(MSG_DISK_INSERT, + config.pan << 24 | config.insertVolume << 16 | nr); + + return true; + } + + return false; +} + +bool +Drive::insertBlankDisk() +{ + auto desc = FSDeviceDescriptor(INCH_35, DISK_DD, config.defaultFileSystem); + + if (FSDevice *volume = FSDevice::makeWithFormat(desc)) { + volume->setName(FSName("Disk")); + volume->makeBootable(config.defaultBootBlock); return true; } diff --git a/Emulator/Drive/Drive.h b/Emulator/Drive/Drive.h index a9e547e63..2f6794669 100644 --- a/Emulator/Drive/Drive.h +++ b/Emulator/Drive/Drive.h @@ -98,6 +98,7 @@ class Drive : public AmigaComponent { const DriveConfig &getConfig() const { return config; } long getConfigItem(Option option) const; + bool setConfigItem(Option option, long value) override; bool setConfigItem(Option option, long id, long value) override; @@ -265,7 +266,8 @@ class Drive : public AmigaComponent { void ejectDisk(); bool insertDisk(Disk *disk); - + bool insertBlankDisk(); + u64 fnv() const; // diff --git a/Emulator/Drive/DrivePublicTypes.h b/Emulator/Drive/DrivePublicTypes.h index bf10d1743..04fc9ae71 100644 --- a/Emulator/Drive/DrivePublicTypes.h +++ b/Emulator/Drive/DrivePublicTypes.h @@ -12,6 +12,8 @@ #pragma once #include "Aliases.h" +#include "FilePublicTypes.h" +#include "FSPublicTypes.h" // // Enumerations @@ -58,11 +60,15 @@ typedef struct Cycle stepDelay; // Noise settings - bool noiseEnable; - bool noiseEject; - bool noiseInsert; - bool noiseStep; - bool noisePoll; + i16 pan; + u8 stepVolume; + u8 pollVolume; + u8 insertVolume; + u8 ejectVolume; + + // Blank disk defaults + FSVolumeType defaultFileSystem; + BootBlockId defaultBootBlock; } DriveConfig; diff --git a/Emulator/FileSystems/FSBlock.cpp b/Emulator/FileSystems/FSBlock.cpp index 56ae35607..f580ea156 100644 --- a/Emulator/FileSystems/FSBlock.cpp +++ b/Emulator/FileSystems/FSBlock.cpp @@ -20,6 +20,7 @@ #include "FSPartition.h" #include "FSRootBlock.h" #include "FSUserDirBlock.h" +#include FSBlock * FSBlock::makeWithType(FSPartition &p, Block nr, FSBlockType type) diff --git a/Emulator/FileSystems/FSBootBlock.cpp b/Emulator/FileSystems/FSBootBlock.cpp index e20730db6..699ff2b53 100644 --- a/Emulator/FileSystems/FSBootBlock.cpp +++ b/Emulator/FileSystems/FSBootBlock.cpp @@ -9,10 +9,10 @@ #include "config.h" #include "BootBlockImage.h" - #include "FSBootBlock.h" #include "FSDevice.h" #include "FSPartition.h" +#include "string.h" FSBootBlock::FSBootBlock(FSPartition &p, Block nr) : FSBlock(p, nr) { @@ -117,18 +117,21 @@ FSBootBlock::dump() const } void -FSBootBlock::writeBootBlock(long bootBlockID, int page) +FSBootBlock::writeBootBlock(BootBlockId id, isize page) { assert(page == 0 || page == 1); - debug(FS_DEBUG, "writeBootBlock(id: %ld, page: %d)\n", bootBlockID, page); - - // Read boot block image from the database - BootBlockImage image = BootBlockImage(bootBlockID); + debug(FS_DEBUG, "writeBootBlock(%s, %zd)\n", BootBlockIdEnum::key(id), page); - if (page == 0) { - image.write(data + 4, 4, 511); // Write 508 bytes (skip header) - } else { - image.write(data, 512, 1023); // Write 512 bytes + if (id != BB_NONE) { + + // Read boot block image from the database + auto image = BootBlockImage(id); + + if (page == 0) { + image.write(data + 4, 4, 511); // Write 508 bytes (skip header) + } else { + image.write(data, 512, 1023); // Write 512 bytes + } } } diff --git a/Emulator/FileSystems/FSBootBlock.h b/Emulator/FileSystems/FSBootBlock.h index d6f7699ab..a36d8bf34 100644 --- a/Emulator/FileSystems/FSBootBlock.h +++ b/Emulator/FileSystems/FSBootBlock.h @@ -10,6 +10,7 @@ #pragma once #include "FSBlock.h" +#include "FileTypes.h" struct FSBootBlock : FSBlock { @@ -36,5 +37,5 @@ struct FSBootBlock : FSBlock { // Block specific methods // - void writeBootBlock(long id, int page); + void writeBootBlock(BootBlockId id, isize page); }; diff --git a/Emulator/FileSystems/FSDataBlock.cpp b/Emulator/FileSystems/FSDataBlock.cpp index f5f7ca26f..dd628a5fc 100644 --- a/Emulator/FileSystems/FSDataBlock.cpp +++ b/Emulator/FileSystems/FSDataBlock.cpp @@ -11,6 +11,7 @@ #include "FSDataBlock.h" #include "FSDevice.h" #include "FSPartition.h" +#include FSDataBlock::FSDataBlock(FSPartition &p, u32 nr) : FSBlock(p, nr) { diff --git a/Emulator/FileSystems/FSDevice.cpp b/Emulator/FileSystems/FSDevice.cpp index 3a61a828b..673f9c9fe 100644 --- a/Emulator/FileSystems/FSDevice.cpp +++ b/Emulator/FileSystems/FSDevice.cpp @@ -11,7 +11,8 @@ #include "IO.h" #include "FSDevice.h" - +#include "limits.h" +#include #include #include diff --git a/Emulator/FileSystems/FSDevice.h b/Emulator/FileSystems/FSDevice.h index e2fc81286..1092f1c1a 100644 --- a/Emulator/FileSystems/FSDevice.h +++ b/Emulator/FileSystems/FSDevice.h @@ -166,7 +166,7 @@ class FSDevice : AmigaObject { public: // Installs a boot block - void makeBootable(long bootBlockID) { partitions[cp]->makeBootable(bootBlockID); } + void makeBootable(BootBlockId id) { partitions[cp]->makeBootable(id); } // Removes a boot block virus from the current partition (if any) void killVirus() { partitions[cp]->killVirus(); } diff --git a/Emulator/FileSystems/FSEmptyBlock.cpp b/Emulator/FileSystems/FSEmptyBlock.cpp index 9d9b0246e..cd7a57490 100644 --- a/Emulator/FileSystems/FSEmptyBlock.cpp +++ b/Emulator/FileSystems/FSEmptyBlock.cpp @@ -9,6 +9,7 @@ #include "config.h" #include "FSEmptyBlock.h" +#include "string.h" FSItemType FSEmptyBlock::itemType(isize byte) const diff --git a/Emulator/FileSystems/FSObjects.cpp b/Emulator/FileSystems/FSObjects.cpp index 3328d0725..113fffaf6 100644 --- a/Emulator/FileSystems/FSObjects.cpp +++ b/Emulator/FileSystems/FSObjects.cpp @@ -11,6 +11,7 @@ #include "FSObjects.h" #include "FSBlock.h" #include +#include FSString::FSString(const char *str, isize l) : limit(l) { diff --git a/Emulator/FileSystems/FSPartition.cpp b/Emulator/FileSystems/FSPartition.cpp index 44db07809..7efc50408 100644 --- a/Emulator/FileSystems/FSPartition.cpp +++ b/Emulator/FileSystems/FSPartition.cpp @@ -11,6 +11,9 @@ #include "config.h" #include "FSPartition.h" #include "FSDevice.h" +#include +#include +#include FSPartition * FSPartition::makeWithFormat(FSDevice &dev, FSPartitionDescriptor &layout) @@ -460,13 +463,13 @@ FSPartition::locateAllocationBit(Block nr, isize *byte, isize *bit) const } void -FSPartition::makeBootable(long bootBlockID) +FSPartition::makeBootable(BootBlockId id) { assert(dev.blocks[firstBlock + 0]->type() == FS_BOOT_BLOCK); assert(dev.blocks[firstBlock + 1]->type() == FS_BOOT_BLOCK); - ((FSBootBlock *)dev.blocks[firstBlock + 0])->writeBootBlock(bootBlockID, 0); - ((FSBootBlock *)dev.blocks[firstBlock + 1])->writeBootBlock(bootBlockID, 1); + ((FSBootBlock *)dev.blocks[firstBlock + 0])->writeBootBlock(id, 0); + ((FSBootBlock *)dev.blocks[firstBlock + 1])->writeBootBlock(id, 1); } void @@ -475,11 +478,11 @@ FSPartition::killVirus() assert(dev.blocks[firstBlock + 0]->type() == FS_BOOT_BLOCK); assert(dev.blocks[firstBlock + 1]->type() == FS_BOOT_BLOCK); - long bootBlockID = isOFS() ? 0 : isFFS() ? 1 : -1; + long id = isOFS() ? BB_AMIGADOS_13 : isFFS() ? BB_AMIGADOS_20 : BB_NONE; - if (bootBlockID != -1) { - ((FSBootBlock *)dev.blocks[firstBlock + 0])->writeBootBlock(bootBlockID, 0); - ((FSBootBlock *)dev.blocks[firstBlock + 1])->writeBootBlock(bootBlockID, 1); + if (id != BB_NONE) { + ((FSBootBlock *)dev.blocks[firstBlock + 0])->writeBootBlock(id, 0); + ((FSBootBlock *)dev.blocks[firstBlock + 1])->writeBootBlock(id, 1); } else { memset(dev.blocks[firstBlock + 0]->data + 4, 0, bsize() - 4); memset(dev.blocks[firstBlock + 1]->data, 0, bsize()); diff --git a/Emulator/FileSystems/FSPartition.h b/Emulator/FileSystems/FSPartition.h index 143b57e76..0911a68b7 100644 --- a/Emulator/FileSystems/FSPartition.h +++ b/Emulator/FileSystems/FSPartition.h @@ -9,7 +9,8 @@ #pragma once -#include "FSPublicTypes.h" +#include "FSTypes.h" +#include "FileTypes.h" #include "FSDescriptors.h" struct FSPartition : AmigaObject { @@ -148,7 +149,7 @@ struct FSPartition : AmigaObject { public: // Installs a boot block - void makeBootable(long id); + void makeBootable(BootBlockId id); // Eliminates boot block virus (if any) void killVirus(); diff --git a/Emulator/FileSystems/FSRootBlock.h b/Emulator/FileSystems/FSRootBlock.h index f911b17d5..1af064d3a 100644 --- a/Emulator/FileSystems/FSRootBlock.h +++ b/Emulator/FileSystems/FSRootBlock.h @@ -8,6 +8,7 @@ #pragma once #include "FSBlock.h" +#include struct FSRootBlock : FSBlock { diff --git a/Emulator/Files/AmigaFile.cpp b/Emulator/Files/AmigaFile.cpp index 68067fcfd..7338daada 100644 --- a/Emulator/Files/AmigaFile.cpp +++ b/Emulator/Files/AmigaFile.cpp @@ -19,7 +19,7 @@ #include "HDFFile.h" #include "RomFile.h" #include "ExtendedRomFile.h" - +#include "string.h" AmigaFile::AmigaFile(isize capacity) { diff --git a/Emulator/Files/DiskFiles/ADFFile.cpp b/Emulator/Files/DiskFiles/ADFFile.cpp index da0b99474..be7cc244b 100644 --- a/Emulator/Files/DiskFiles/ADFFile.cpp +++ b/Emulator/Files/DiskFiles/ADFFile.cpp @@ -271,13 +271,13 @@ ADFFile::killVirus() if (isOFSVolumeType(getDos())) { msg("a standard OFS bootblock\n"); - BootBlockImage bb = BootBlockImage((long)0); + BootBlockImage bb = BootBlockImage(BB_AMIGADOS_13); bb.write(data + 4, 4, 1023); } else if (isFFSVolumeType(getDos())) { msg("a standard FFS bootblock\n"); - BootBlockImage bb = BootBlockImage((long)1); + BootBlockImage bb = BootBlockImage(BB_AMIGADOS_20); bb.write(data + 4, 4, 1023); } else { @@ -288,7 +288,7 @@ ADFFile::killVirus() } bool -ADFFile::formatDisk(FSVolumeType fs, long bootBlockID) +ADFFile::formatDisk(FSVolumeType fs, BootBlockId id) { assert_enum(FSVolumeType, fs); @@ -308,7 +308,7 @@ ADFFile::formatDisk(FSVolumeType fs, long bootBlockID) volume->setName(FSName("Disk")); // Write boot code - volume->makeBootable(bootBlockID); + volume->makeBootable(id); // Export the file system to the ADF volume->exportVolume(data, size, &error); diff --git a/Emulator/Files/DiskFiles/ADFFile.h b/Emulator/Files/DiskFiles/ADFFile.h index c807795ae..444c82cb7 100644 --- a/Emulator/Files/DiskFiles/ADFFile.h +++ b/Emulator/Files/DiskFiles/ADFFile.h @@ -106,7 +106,7 @@ class ADFFile : public DiskFile { public: - bool formatDisk(FSVolumeType fs, long bootBlockID); + bool formatDisk(FSVolumeType fs, BootBlockId id); // diff --git a/Emulator/Files/DiskFiles/BootBlockImage.cpp b/Emulator/Files/DiskFiles/BootBlockImage.cpp index 5567b4522..3a1a1002b 100644 --- a/Emulator/Files/DiskFiles/BootBlockImage.cpp +++ b/Emulator/Files/DiskFiles/BootBlockImage.cpp @@ -9,6 +9,7 @@ #include "config.h" #include "BootBlockImage.h" +#include // // Bootblock images @@ -1166,18 +1167,18 @@ BootBlockImage::BootBlockImage(const char *name) } } -BootBlockImage::BootBlockImage(long bootBlockID) +BootBlockImage::BootBlockImage(BootBlockId bootBlockID) { memset(data, 0, 1024); const char *name; switch (bootBlockID) { - case 0: name = "AmigaDOS Standard Bootblock 1.3"; break; - case 1: name = "AmigaDOS Standard Bootblock 2.0"; break; - case 10: name = "SCA Virus"; break; - case 11: name = "Byte Bandit 1 Virus"; break; - default: name = ""; break; + case BB_AMIGADOS_13: name = "AmigaDOS Standard Bootblock 1.3"; break; + case BB_AMIGADOS_20: name = "AmigaDOS Standard Bootblock 2.0"; break; + case BB_SCA: name = "SCA Virus"; break; + case BB_BYTE_BANDIT: name = "Byte Bandit 1 Virus"; break; + default: name = ""; break; } BootBlockImage bb = BootBlockImage(name); diff --git a/Emulator/Files/DiskFiles/BootBlockImage.h b/Emulator/Files/DiskFiles/BootBlockImage.h index cba1e1172..f134c2318 100644 --- a/Emulator/Files/DiskFiles/BootBlockImage.h +++ b/Emulator/Files/DiskFiles/BootBlockImage.h @@ -9,7 +9,7 @@ #pragma once -#include "FilePublicTypes.h" +#include "FileTypes.h" #include typedef struct @@ -36,7 +36,7 @@ class BootBlockImage { // Constructors BootBlockImage(const u8 *buffer); BootBlockImage(const char *name); - BootBlockImage(long id); + BootBlockImage(BootBlockId id); // Exports the image void write(u8 *buffer, isize first = 0, isize last = 0); diff --git a/Emulator/Files/DiskFiles/EXEFile.cpp b/Emulator/Files/DiskFiles/EXEFile.cpp index e929f3f5a..306f4d5d6 100644 --- a/Emulator/Files/DiskFiles/EXEFile.cpp +++ b/Emulator/Files/DiskFiles/EXEFile.cpp @@ -46,7 +46,7 @@ EXEFile::readFromStream(std::istream &stream) volume->setName(FSName("Disk")); // Make the volume bootable - volume->makeBootable(0); + volume->makeBootable(BB_AMIGADOS_13); // Add the executable FSBlock *file = volume->makeFile("file", data, size); diff --git a/Emulator/Files/FilePublicTypes.h b/Emulator/Files/FilePublicTypes.h index c30003841..9da76f446 100644 --- a/Emulator/Files/FilePublicTypes.h +++ b/Emulator/Files/FilePublicTypes.h @@ -86,3 +86,13 @@ enum_long(BB_TYPE) BB_COUNT }; typedef BB_TYPE BootBlockType; + +enum_long(BB_ID) +{ + BB_NONE, + BB_AMIGADOS_13, + BB_AMIGADOS_20, + BB_SCA, + BB_BYTE_BANDIT +}; +typedef BB_ID BootBlockId; diff --git a/Emulator/Files/FileTypes.h b/Emulator/Files/FileTypes.h index 8e1aae44b..8a6b6e6c3 100644 --- a/Emulator/Files/FileTypes.h +++ b/Emulator/Files/FileTypes.h @@ -10,7 +10,7 @@ #pragma once #include "FilePublicTypes.h" -#include "DiskPublicTypes.h" +#include "DiskTypes.h" #include "Reflection.h" struct FileTypeEnum : Reflection { @@ -101,14 +101,36 @@ struct BootBlockTypeEnum : Reflection { } static const char *prefix() { return "BB"; } - static const char *key(DiskDensity value) + static const char *key(BootBlockType value) { switch (value) { - case DISK_SD: return "SD"; - case DISK_DD: return "DD"; - case DISK_HD: return "HD"; - case DISK_COUNT: return "???"; + case BB_STANDARD: return "STANDARD"; + case BB_VIRUS: return "VIRUS"; + case BB_CUSTOM: return "CUSTOM"; + case BB_COUNT: return "???"; + } + return "???"; + } +}; + +struct BootBlockIdEnum : Reflection { + + static bool isValid(long value) + { + return (unsigned long)value < BB_COUNT; + } + + static const char *prefix() { return "BB"; } + static const char *key(BootBlockId value) + { + switch (value) { + + case BB_NONE: return "NONE"; + case BB_AMIGADOS_13: return "AMIGADOS_13"; + case BB_AMIGADOS_20: return "AMIGADOS_20"; + case BB_SCA: return "SCA"; + case BB_BYTE_BANDIT: return "BYTE_BANDIT"; } return "???"; } diff --git a/Emulator/Files/HDFFile.cpp b/Emulator/Files/HDFFile.cpp index da4d529a0..05c093e36 100644 --- a/Emulator/Files/HDFFile.cpp +++ b/Emulator/Files/HDFFile.cpp @@ -9,8 +9,8 @@ #include "config.h" #include "HDFFile.h" - #include "IO.h" +#include "string.h" HDFFile::HDFFile() { diff --git a/Emulator/Foundation/Chrono.cpp b/Emulator/Foundation/Chrono.cpp index 62d7a7ebb..7d334aba4 100644 --- a/Emulator/Foundation/Chrono.cpp +++ b/Emulator/Foundation/Chrono.cpp @@ -7,6 +7,7 @@ // See https://www.gnu.org for license information // ----------------------------------------------------------------------------- +#include "config.h" #include "Chrono.h" #ifdef __MACH__ @@ -62,6 +63,8 @@ Time::now() void Time::sleep() { + struct timespec req, rem; + if (ticks > 0) { req.tv_sec = 0; req.tv_nsec = ticks; diff --git a/Emulator/Foundation/Concurrency.cpp b/Emulator/Foundation/Concurrency.cpp index 4aa2f8605..c6d19c435 100644 --- a/Emulator/Foundation/Concurrency.cpp +++ b/Emulator/Foundation/Concurrency.cpp @@ -8,7 +8,6 @@ // ----------------------------------------------------------------------------- #include "config.h" - #include "Concurrency.h" Mutex::Mutex() diff --git a/Emulator/Foundation/Debug.cpp b/Emulator/Foundation/Debug.cpp index 945cc121d..98a7562cc 100644 --- a/Emulator/Foundation/Debug.cpp +++ b/Emulator/Foundation/Debug.cpp @@ -7,6 +7,7 @@ // See https://www.gnu.org for license information // ----------------------------------------------------------------------------- +#include "config.h" #include "Debug.h" void hexdump(u8 *p, isize size, isize cols, isize pad) diff --git a/Emulator/Foundation/IO.cpp b/Emulator/Foundation/IO.cpp index 00951bfe3..abee6e055 100644 --- a/Emulator/Foundation/IO.cpp +++ b/Emulator/Foundation/IO.cpp @@ -7,7 +7,9 @@ // See https://www.gnu.org for license information // ----------------------------------------------------------------------------- +#include "config.h" #include "IO.h" +#include "string.h" namespace util { diff --git a/Emulator/Foundation/Macros.h b/Emulator/Foundation/Macros.h index 460020ddd..c3c5f80c3 100644 --- a/Emulator/Foundation/Macros.h +++ b/Emulator/Foundation/Macros.h @@ -9,6 +9,8 @@ #pragma once +#include + // // Converting units // diff --git a/Emulator/Foundation/RingBuffer.h b/Emulator/Foundation/RingBuffer.h index 90c08f383..2f76f9aba 100644 --- a/Emulator/Foundation/RingBuffer.h +++ b/Emulator/Foundation/RingBuffer.h @@ -9,6 +9,7 @@ #pragma once +#include "config.h" #include "Aliases.h" #include @@ -82,7 +83,7 @@ template struct RingBuffer T& read() { - assert(!isEmpty()); + assert(!isEmpty()); i64 oldr = r; r = next(r); diff --git a/Emulator/Foundation/SSEUtils.cpp b/Emulator/Foundation/SSEUtils.cpp index e46ff4443..2b7218279 100644 --- a/Emulator/Foundation/SSEUtils.cpp +++ b/Emulator/Foundation/SSEUtils.cpp @@ -8,7 +8,6 @@ // ----------------------------------------------------------------------------- #include "config.h" - #include "SSEUtils.h" #if (defined(__i386__) || defined(__x86_64__)) && defined(__MACH__) diff --git a/Emulator/Foundation/Serialization.h b/Emulator/Foundation/Serialization.h index d73d28421..6123613bd 100644 --- a/Emulator/Foundation/Serialization.h +++ b/Emulator/Foundation/Serialization.h @@ -11,7 +11,7 @@ #include "Aliases.h" #include "Macros.h" - +#include // // Basic memory buffer I/O diff --git a/Emulator/Foundation/TimeDelayed.h b/Emulator/Foundation/TimeDelayed.h index cb0481ae0..425285820 100644 --- a/Emulator/Foundation/TimeDelayed.h +++ b/Emulator/Foundation/TimeDelayed.h @@ -109,11 +109,11 @@ template class TimeDelayed : AmigaObject { T current() { return pipeline[0]; } // Reads a value from the pipeline with the standard delay - T delayed() { return pipeline[std::max((i64)0, timeStamp - AS_DMA_CYCLES(*clock) + delay)]; } + T delayed() { return pipeline[std::max(0LL, timeStamp - AS_DMA_CYCLES(*clock) + delay)]; } // Reads a value from the pipeline with a custom delay T readWithDelay(u8 customDelay) { assert(customDelay <= delay); - return pipeline[std::max(0, timeStamp - AS_DMA_CYCLES(*clock) + customDelay)]; + return pipeline[std::max(0LL, timeStamp - AS_DMA_CYCLES(*clock) + customDelay)]; } }; diff --git a/Emulator/Makefile b/Emulator/Makefile index 10fe2801b..3c150e87a 100644 --- a/Emulator/Makefile +++ b/Emulator/Makefile @@ -1,11 +1,12 @@ SUBDIRS = \ -Agnus CIA CPU Denise Drive Files FileSystems Foundation LogicBoard Memory \ -Paula Peripherals xdms +Agnus Base CIA CPU Denise Drive Files FileSystems Foundation LogicBoard \ +Memory Paula Peripherals xdms MYCC = g++ -std=c++17 -Wfatal-errors MYFLAGS = \ -Wall \ +-I $(CURDIR)/.. \ -I $(CURDIR) \ -I $(CURDIR)/Agnus \ -I $(CURDIR)/Agnus/Blitter \ @@ -20,6 +21,7 @@ MYFLAGS = \ -I $(CURDIR)/Files/RomFiles \ -I $(CURDIR)/FileSystems \ -I $(CURDIR)/Foundation \ +-I $(CURDIR)/Base \ -I $(CURDIR)/LogicBoard \ -I $(CURDIR)/Memory \ -I $(CURDIR)/Paula \ diff --git a/Emulator/Memory/Memory.h b/Emulator/Memory/Memory.h index 3ad3bf024..274bd9e64 100644 --- a/Emulator/Memory/Memory.h +++ b/Emulator/Memory/Memory.h @@ -11,7 +11,7 @@ #include "MemoryTypes.h" #include "AmigaComponent.h" -#include "FilePublicTypes.h" +#include "FileTypes.h" #include "Macros.h" //#include "FileTypes.h" @@ -370,9 +370,9 @@ class Memory : public AmigaComponent { bool hasExt() { return ext != nullptr; } // Erases an installed Rom - void eraseRom() { assert(rom); memset(rom, 0, config.romSize); } - void eraseWom() { assert(wom); memset(wom, 0, config.womSize); } - void eraseExt() { assert(ext); memset(ext, 0, config.extSize); } + void eraseRom() { memset(rom, 0, config.romSize); } + void eraseWom() { memset(wom, 0, config.womSize); } + void eraseExt() { memset(ext, 0, config.extSize); } // Installs a Boot Rom or Kickstart Rom void loadRom(class RomFile *rom) throws; diff --git a/Emulator/Paula/Audio/AudioFilter.cpp b/Emulator/Paula/Audio/AudioFilter.cpp index 3c6c4828e..72385448f 100644 --- a/Emulator/Paula/Audio/AudioFilter.cpp +++ b/Emulator/Paula/Audio/AudioFilter.cpp @@ -9,6 +9,7 @@ #include "config.h" #include "AudioFilter.h" +#include "math.h" AudioFilter::AudioFilter(Amiga& ref) : AmigaComponent(ref) { diff --git a/Emulator/Paula/Audio/Muxer.cpp b/Emulator/Paula/Audio/Muxer.cpp index cb0e68138..2158e141f 100644 --- a/Emulator/Paula/Audio/Muxer.cpp +++ b/Emulator/Paula/Audio/Muxer.cpp @@ -14,6 +14,7 @@ #include "MsgQueue.h" #include "Oscillator.h" #include "Macros.h" +#include Muxer::Muxer(Amiga& ref) : AmigaComponent(ref) { diff --git a/Emulator/Paula/DiskController/DiskControllerEvents.cpp b/Emulator/Paula/DiskController/DiskControllerEvents.cpp index aac11f446..577aca0cc 100644 --- a/Emulator/Paula/DiskController/DiskControllerEvents.cpp +++ b/Emulator/Paula/DiskController/DiskControllerEvents.cpp @@ -12,6 +12,7 @@ #include "Agnus.h" #include "Drive.h" +#include void DiskController::serviceDiskEvent() diff --git a/Emulator/Peripherals/Mouse.cpp b/Emulator/Peripherals/Mouse.cpp index 3a4bb7b12..09156811f 100644 --- a/Emulator/Peripherals/Mouse.cpp +++ b/Emulator/Peripherals/Mouse.cpp @@ -18,6 +18,7 @@ Mouse::Mouse(Amiga& ref, ControlPort& pref) : AmigaComponent(ref), port(pref) { config.pullUpResistors = true; + config.shakeDetection = true; config.velocity = 100; updateScalingFactors(); @@ -49,6 +50,7 @@ Mouse::getConfigItem(Option option) const switch (option) { case OPT_PULLUP_RESISTORS: return config.pullUpResistors; + case OPT_SHAKE_DETECTION: return config.shakeDetection; case OPT_MOUSE_VELOCITY: return config.velocity; default: @@ -71,7 +73,15 @@ Mouse::setConfigItem(Option option, long id, long value) } config.pullUpResistors = value; return true; - + + case OPT_SHAKE_DETECTION: + + if (config.shakeDetection == value) { + return false; + } + config.shakeDetection = value; + return true; + case OPT_MOUSE_VELOCITY: printf("config: OPT_MOUSE_VELOCITY\n"); @@ -104,6 +114,7 @@ Mouse::_dump(Dump::Category category, std::ostream& os) const if (category & Dump::Config) { os << DUMP("Pull-up resistors") << YESNO(config.pullUpResistors) << std::endl; + os << DUMP("Shake detection") << YESNO(config.shakeDetection) << std::endl; os << DUMP("Velocity") << config.velocity << std::endl; } diff --git a/Emulator/Peripherals/Mouse.h b/Emulator/Peripherals/Mouse.h index 64c537772..fcbf2c9d0 100644 --- a/Emulator/Peripherals/Mouse.h +++ b/Emulator/Peripherals/Mouse.h @@ -11,6 +11,7 @@ #include "PortTypes.h" #include "AmigaComponent.h" +#include "Chrono.h" class ShakeDetector { @@ -28,7 +29,7 @@ class ShakeDetector { // Time stamps u64 lastTurn = 0; - u64 lastShake = 0; + Time lastShake; public: diff --git a/Emulator/Peripherals/PortPublicTypes.h b/Emulator/Peripherals/PortPublicTypes.h index dbf76f9c1..5b9de4196 100644 --- a/Emulator/Peripherals/PortPublicTypes.h +++ b/Emulator/Peripherals/PortPublicTypes.h @@ -105,6 +105,7 @@ SerialPortInfo; typedef struct { bool pullUpResistors; + bool shakeDetection; long velocity; } MouseConfig; diff --git a/GUI/Controller/MacAudio.swift b/GUI/Controller/MacAudio.swift index d043b5e09..6116e7272 100644 --- a/GUI/Controller/MacAudio.swift +++ b/GUI/Controller/MacAudio.swift @@ -153,7 +153,50 @@ public class MacAudio: NSObject { } // Plays a sound file - func playSound(name: String, volume: Float = 1.0) { + func playStepSound(drive id: Int) { + + playSound(name: "drive_head", + volume: parent.amiga.getConfig(.STEP_VOLUME, drive: id), + pan: parent.amiga.getConfig(.DRIVE_PAN, drive: id)) + } + + func playPollSound(drive id: Int) { + + playSound(name: "drive_head", + volume: parent.amiga.getConfig(.POLL_VOLUME, drive: id), + pan: parent.amiga.getConfig(.DRIVE_PAN, drive: id)) + } + + func playInsertSound(drive id: Int) { + + playSound(name: "insert", + volume: parent.amiga.getConfig(.INSERT_VOLUME, drive: id), + pan: parent.amiga.getConfig(.DRIVE_PAN, drive: id)) + } + + func playEjectSound(drive id: Int) { + + playSound(name: "eject", + volume: parent.amiga.getConfig(.EJECT_VOLUME, drive: id), + pan: parent.amiga.getConfig(.DRIVE_PAN, drive: id)) + } + + func playSound(name: String, volume: Int, pan: Int) { + + let p = pan <= 100 ? pan : pan <= 300 ? 200 - pan : -400 + pan + + let scaledVolume = Float(volume) / 100.0 + let scaledPan = Float(p) / 100.0 + + // track("\(name) \(scaledVolume) \(scaledPan)") + + playSound(name: name, volume: scaledVolume, pan: scaledPan) + } + + func playSound(name: String, volume: Float = 1.0, pan: Float = 0.0) { + + // Only proceed if the volume is greater 0 + if volume == 0.0 { return } // Check for cached players for this sound file if audioPlayers[name] == nil { @@ -179,7 +222,7 @@ public class MacAudio: NSObject { for player in audioPlayers[name]! where !player.isPlaying { player.volume = volume - player.pan = Float(prefs.driveSoundPan) + player.pan = pan player.play() return } diff --git a/GUI/Controller/MyController.swift b/GUI/Controller/MyController.swift index ff3deb71a..9cdb96c82 100644 --- a/GUI/Controller/MyController.swift +++ b/GUI/Controller/MyController.swift @@ -66,7 +66,7 @@ class MyController: NSWindowController, MessageReceiver { // Timer lock var timerLock: NSLock! - + // Screenshot and snapshot timers var snapshotTimer: Timer? var screenshotTimer: Timer? // DEPRECATED @@ -95,7 +95,7 @@ class MyController: NSWindowController, MessageReceiver { // Remembers the running state for the pauseInBackground feature var pauseInBackgroundSavedState = false - + // // Timers // @@ -438,6 +438,9 @@ extension MyController { func processMessage(_ msg: Message) { + var driveNr: Int { return msg.data & 0xFF } + var driveCyl: Int { return (msg.data >> 8) & 0xFF; } + switch msg.type { case .REGISTER: @@ -445,9 +448,7 @@ extension MyController { case .UNREGISTER: track("Unregistered from message queue") - // From now on, it's save to delete the document. - // To trigger deletion, we remove any reference to it. - mydocument = nil + shutDown() case .CONFIG: inspector?.fullRefresh() @@ -552,32 +553,21 @@ extension MyController { refreshStatusBar() updateWarp() - case .DRIVE_HEAD_NOISE, - .DRIVE_HEAD: - if pref.driveSounds && pref.driveHeadSound { - macAudio.playSound(name: "drive_head", volume: 0.3) - } - refreshStatusBar(drive: msg.data >> 8, cylinder: msg.data % 0xFF) - - case .DRIVE_HEAD_POLL: - if pref.driveSounds && pref.drivePollSound { - macAudio.playSound(name: "drive_head", volume: 0.3) - } - refreshStatusBar(drive: msg.data >> 8, cylinder: msg.data % 0xFF) + case .DRIVE_STEP: + macAudio.playStepSound(drive: driveNr) + refreshStatusBar(drive: driveNr, cylinder: driveCyl) - case .DISK_INSERT_NOISE, - .DISK_INSERT: - if pref.driveSounds && pref.driveInsertSound { - macAudio.playSound(name: "insert", volume: 0.3) - } - if msg.data == 0 { mydocument.setBootDiskID(amiga.df0.fnv) } + case .DRIVE_POLL: + macAudio.playPollSound(drive: driveNr) + refreshStatusBar(drive: driveNr, cylinder: driveCyl) + + case .DISK_INSERT: + if driveNr == 0 { mydocument.setBootDiskID(amiga.df0.fnv) } + macAudio.playInsertSound(drive: driveNr) refreshStatusBar() - case .DISK_EJECT_NOISE, - .DISK_EJECT: - if pref.driveSounds && pref.driveEjectSound { - macAudio.playSound(name: "eject", volume: 0.3) - } + case .DISK_EJECT: + macAudio.playEjectSound(drive: driveNr) refreshStatusBar() case .DISK_UNSAVED, @@ -610,15 +600,19 @@ extension MyController { hideOrShowDriveMenus() case .RECORDING_STARTED: - window?.backgroundColor = .warningColor refreshStatusBar() case .RECORDING_STOPPED: - window?.backgroundColor = .windowBackgroundColor refreshStatusBar() + case .SHAKING: + metal.lastShake = DispatchTime.init(uptimeNanoseconds: 0) + if pref.releaseMouseByShaking { + metal.releaseMouse() + } + default: track("Unknown message: \(msg)") assert(false) diff --git a/GUI/Controller/MyControllerMenu.swift b/GUI/Controller/MyControllerMenu.swift index 602e2e274..ab69506ad 100644 --- a/GUI/Controller/MyControllerMenu.swift +++ b/GUI/Controller/MyControllerMenu.swift @@ -474,6 +474,33 @@ extension MyController: NSMenuItemValidation { myAppDelegate.clearRecentlyExportedDiskURLs(drive: sender.tag) } + /* + @IBAction func newDiskAction(_ sender: NSMenuItem!) { + + track() + + // Get drive type + let type = DriveType.init(rawValue: config.dfnType(sender.tag)) + + // Create a blank disk + var adf: ADFFileProxy + switch type { + case .DD_35: adf = ADFFileProxy.make(with: .INCH_35, density: .DD) + case .HD_35: adf = ADFFileProxy.make(with: .INCH_35, density: .HD) + case .DD_525: adf = ADFFileProxy.make(with: .INCH_525, density: .DD) + default: fatalError() + } + + // Write file system + adf.formatDisk(pref.blankDiskFormat, bootBlock: pref.bootBlock) + + // Insert disk into drive + amiga.diskController.insert(sender.tag, file: adf) + + myAppDelegate.clearRecentlyExportedDiskURLs(drive: sender.tag) + } + */ + @IBAction func insertDiskAction(_ sender: NSMenuItem!) { // Ask the user if an unsafed disk should be replaced diff --git a/GUI/Metal/MetalView.swift b/GUI/Metal/MetalView.swift index 3c01ec36a..f4c3726bb 100644 --- a/GUI/Metal/MetalView.swift +++ b/GUI/Metal/MetalView.swift @@ -33,12 +33,8 @@ public class MetalView: MTKView { var mouse2: GamePad? // Variables needed to detect a shaking mouse - var dxsign = CGFloat(1) - var dxsum = CGFloat(0) - var dxturns = 0 - var lastTurn = DispatchTime.init(uptimeNanoseconds: 0) var lastShake = DispatchTime.init(uptimeNanoseconds: 0) - + required public init(coder: NSCoder) { super.init(coder: coder) diff --git a/GUI/Metal/MetalViewEvents.swift b/GUI/Metal/MetalViewEvents.swift index c1ca6d71a..4ea5c8490 100644 --- a/GUI/Metal/MetalViewEvents.swift +++ b/GUI/Metal/MetalViewEvents.swift @@ -137,8 +137,8 @@ public extension MetalView { let dy = event.deltaY // Make coordinate independent of the actual window size - let scaleX = (256.0 * 400.0) / frame.width - let scaleY = (256.0 * 300.0) / frame.height + let scaleX = (256.0 * 400.0) / frame.width / 128.0 + let scaleY = (256.0 * 300.0) / frame.height / 128.0 let dxdy = NSPoint.init(x: dx * scaleX, y: dy * scaleY) // Report the new location to the Amiga mouse @@ -146,12 +146,7 @@ public extension MetalView { mouse1!.processMouseEvents(delta: dxdy) } else { mouse2!.processMouseEvents(delta: dxdy) - } - - // Check for a shaking mouse movement - if prefs.releaseMouseByShaking && mouseIsShaking(dx: dx, dy: dy) { - releaseMouse() - } + } } } @@ -194,52 +189,4 @@ public extension MetalView { } } } - - func mouseIsShaking(dx: CGFloat, dy: CGFloat) -> Bool { - - // Accumulate the travelled distance - dxsum += abs(dx) - - // Check for a direction reversal - if dx * dxsign < 0 { - - let dt = DispatchTime.diffMilliSec(lastTurn) - dxsign = -dxsign - - // track("\(dxturns) \(dxsign) \(dx) \(dxabssum) \(dt)") - - // A direction reversal is considered part of a shake, if the - // previous reversal happened a short while ago. - if dt < 400 { - - // Eliminate jitter by demanding that the mouse has travelled - // a long enough distance. - if dxsum > 400 { - - dxturns += 1 - dxsum = 0 - - // Report a shake if the threshold has been reached. - if dxturns > 3 { - - // track("Mouse shake detected") - lastShake = DispatchTime.now() - dxturns = 0 - return true - } - } - - } else { - - // Time out. The user is definitely not shaking the mouse. - // Let's reset the recorded movement histoy. - dxturns = 0 - dxsum = 0 - } - - lastTurn = DispatchTime.now() - } - - return false - } } diff --git a/GUI/Settings/Configuration/AudioPrefs.swift b/GUI/Settings/Configuration/AudioConf.swift similarity index 70% rename from GUI/Settings/Configuration/AudioPrefs.swift rename to GUI/Settings/Configuration/AudioConf.swift index a7393efa3..1c9e2966a 100644 --- a/GUI/Settings/Configuration/AudioPrefs.swift +++ b/GUI/Settings/Configuration/AudioConf.swift @@ -26,12 +26,18 @@ extension ConfigurationController { // Out audVolL.integerValue = config.volL audVolR.integerValue = config.volR - audSamplingMethod.selectItem(withTag: config.samplingMethod) - audFilterType.selectItem(withTag: config.filterType) - audFilterAlwaysOn.state = config.filterAlwaysOn ? .on : .off - audFilterAlwaysOn.isEnabled = config.filterType != FilterType.NONE.rawValue + // Drives + audDf0Pan.integerValue = config.df0Pan + audDf1Pan.integerValue = config.df1Pan + audDf2Pan.integerValue = config.df2Pan + audDf3Pan.integerValue = config.df3Pan + audStepVolume.integerValue = config.stepVolume + audPollVolume.integerValue = config.pollVolume + audInsertVolume.integerValue = config.insertVolume + audEjectVolume.integerValue = config.ejectVolume + // Buttons audPowerButton.isHidden = !bootable } @@ -102,18 +108,42 @@ extension ConfigurationController { refresh() } - @IBAction func audFilterTypeAction(_ sender: NSPopUpButton!) { - - config.filterType = sender.selectedTag() + @IBAction func audDrivePanAction(_ sender: NSSlider!) { + + switch sender.tag { + case 0: config.df0Pan = sender.integerValue + case 1: config.df1Pan = sender.integerValue + case 2: config.df2Pan = sender.integerValue + case 3: config.df3Pan = sender.integerValue + default: fatalError() + } refresh() } - @IBAction func audFilterAlwaysOnAction(_ sender: NSButton!) { + @IBAction func audStepVolumeAction(_ sender: NSSlider!) { - config.filterAlwaysOn = sender.state == .on + config.stepVolume = sender.integerValue refresh() } - + + @IBAction func audPollVolumeAction(_ sender: NSSlider!) { + + config.pollVolume = sender.integerValue + refresh() + } + + @IBAction func audInsertVolumeAction(_ sender: NSSlider!) { + + config.insertVolume = sender.integerValue + refresh() + } + + @IBAction func audEjectVolumeAction(_ sender: NSSlider!) { + + config.ejectVolume = sender.integerValue + refresh() + } + @IBAction func audPresetAction(_ sender: NSPopUpButton!) { track() diff --git a/GUI/Settings/Configuration/CompatibilityPrefs.swift b/GUI/Settings/Configuration/CompatibilityConf.swift similarity index 80% rename from GUI/Settings/Configuration/CompatibilityPrefs.swift rename to GUI/Settings/Configuration/CompatibilityConf.swift index b68ac5840..2bbb77e40 100644 --- a/GUI/Settings/Configuration/CompatibilityPrefs.swift +++ b/GUI/Settings/Configuration/CompatibilityConf.swift @@ -10,20 +10,24 @@ extension ConfigurationController { func refreshCompatibilityTab() { - - // let config = amiga.config - + // Graphics compClxSprSpr.state = config.clxSprSpr ? .on : .off compClxSprPlf.state = config.clxSprPlf ? .on : .off compClxPlfPlf.state = config.clxPlfPlf ? .on : .off // Blitter - let a = config.blitterAccuracy - compBltAccuracy.integerValue = a - compBltLevel1.textColor = (a >= 1) ? .labelColor : .tertiaryLabelColor - compBltLevel2.textColor = (a >= 2) ? .labelColor : .tertiaryLabelColor + let level = config.blitterAccuracy + compBltAccuracy.integerValue = level + compBltLevel1.textColor = (level >= 1) ? .labelColor : .tertiaryLabelColor + compBltLevel2.textColor = (level >= 2) ? .labelColor : .tertiaryLabelColor + // Chipset features + let ocsAgnus = config.agnusRev == AgnusRevision.OCS.rawValue + compSlowRamMirror.state = config.slowRamMirror ? .on : .off + compSlowRamMirror.isEnabled = !ocsAgnus + compTodBug.state = config.todBug ? .on : .off + // Floppy drives let speed = config.driveSpeed compDriveSpeed.selectItem(withTag: Int(speed)) @@ -65,7 +69,19 @@ extension ConfigurationController { config.blitterAccuracy = sender.integerValue refresh() } + + @IBAction func compSlowRamMirrorAction(_ sender: NSButton!) { + + config.slowRamMirror = sender.state == .on + refresh() + } + + @IBAction func compTodBugAction(_ sender: NSButton!) { + config.todBug = sender.state == .on + refresh() + } + @IBAction func compDriveSpeedAction(_ sender: NSPopUpButton!) { config.driveSpeed = sender.selectedTag() diff --git a/GUI/Settings/Configuration/Configuration.swift b/GUI/Settings/Configuration/Configuration.swift index 6a79a4213..264891346 100644 --- a/GUI/Settings/Configuration/Configuration.swift +++ b/GUI/Settings/Configuration/Configuration.swift @@ -40,30 +40,26 @@ class Configuration { get { return amiga.getConfig(.AGNUS_REVISION) } set { amiga.configure(.AGNUS_REVISION, value: newValue) } } - var slowRamMirror: Bool { - get { return amiga.getConfig(.SLOW_RAM_MIRROR) != 0 } - set { amiga.configure(.SLOW_RAM_MIRROR, enable: newValue) } - } var deniseRev: Int { get { return amiga.getConfig(.DENISE_REVISION) } set { amiga.configure(.DENISE_REVISION, value: newValue) } } - var borderBlank: Bool { - get { return amiga.getConfig(.BRDRBLNK) != 0 } - set { amiga.configure(.BRDRBLNK, enable: newValue) } - } var ciaRev: Int { get { return amiga.getConfig(.CIA_REVISION) } set { amiga.configure(.CIA_REVISION, value: newValue) } } - var todBug: Bool { - get { return amiga.getConfig(.TODBUG) != 0 } - set { amiga.configure(.TODBUG, enable: newValue) } - } var rtClock: Int { get { return amiga.getConfig(.RTC_MODEL) } set { amiga.configure(.RTC_MODEL, value: newValue) } } + var filterType: Int { + get { return amiga.getConfig(.FILTER_TYPE) } + set { amiga.configure(.FILTER_TYPE, value: newValue) } + } + var filterAlwaysOn: Bool { + get { return amiga.getConfig(.FILTER_ALWAYS_ON) != 0} + set { amiga.configure(.FILTER_ALWAYS_ON, enable: newValue) } + } var chipRam: Int { get { return amiga.getConfig(.CHIP_RAM) } set { amiga.configure(.CHIP_RAM, value: newValue) } @@ -141,6 +137,15 @@ class Configuration { get { return dfnType(3) } set { setDfnType(3, type: newValue) } } + var blankDiskFormat = PeripheralsDefaults.std.blankDiskFormat + var blankDiskFormatIntValue: Int { + get { return amiga.getConfig(.DEFAULT_FILESYSTEM, drive: 0) } + set { amiga.configure(.DEFAULT_FILESYSTEM, value: newValue) } + } + var bootBlock: Int { + get { return amiga.getConfig(.DEFAULT_BOOTBLOCK, drive: 0) } + set { amiga.configure(.DEFAULT_BOOTBLOCK, value: newValue) } + } var gameDevice1 = PeripheralsDefaults.std.gameDevice1 { didSet { @@ -184,6 +189,14 @@ class Configuration { get { return amiga.getConfig(.BLITTER_ACCURACY) } set { amiga.configure(.BLITTER_ACCURACY, value: newValue) } } + var slowRamMirror: Bool { + get { return amiga.getConfig(.SLOW_RAM_MIRROR) != 0 } + set { amiga.configure(.SLOW_RAM_MIRROR, enable: newValue) } + } + var todBug: Bool { + get { return amiga.getConfig(.TODBUG) != 0 } + set { amiga.configure(.TODBUG, enable: newValue) } + } var eClockSyncing: Bool { get { return amiga.getConfig(.ECLOCK_SYNCING) != 0 } set { amiga.configure(.ECLOCK_SYNCING, enable: newValue) } @@ -278,13 +291,37 @@ class Configuration { get { return amiga.getConfig(.SAMPLING_METHOD) } set { amiga.configure(.SAMPLING_METHOD, value: newValue) } } - var filterType: Int { - get { return amiga.getConfig(.FILTER_TYPE) } - set { amiga.configure(.FILTER_TYPE, value: newValue) } + var df0Pan: Int { + get { return amiga.getConfig(.DRIVE_PAN, drive: 0) } + set { amiga.configure(.DRIVE_PAN, id: 0, value: newValue) } } - var filterAlwaysOn: Bool { - get { return amiga.getConfig(.FILTER_ALWAYS_ON) != 0} - set { amiga.configure(.FILTER_ALWAYS_ON, enable: newValue) } + var df1Pan: Int { + get { return amiga.getConfig(.DRIVE_PAN, drive: 1) } + set { amiga.configure(.DRIVE_PAN, id: 1, value: newValue) } + } + var df2Pan: Int { + get { return amiga.getConfig(.DRIVE_PAN, drive: 2) } + set { amiga.configure(.DRIVE_PAN, id: 2, value: newValue) } + } + var df3Pan: Int { + get { return amiga.getConfig(.DRIVE_PAN, drive: 3) } + set { amiga.configure(.DRIVE_PAN, id: 3, value: newValue) } + } + var stepVolume: Int { + get { return amiga.getConfig(.STEP_VOLUME, drive: 0) } + set { amiga.configure(.STEP_VOLUME, value: newValue) } + } + var pollVolume: Int { + get { return amiga.getConfig(.POLL_VOLUME, drive: 0) } + set { amiga.configure(.POLL_VOLUME, value: newValue) } + } + var insertVolume: Int { + get { return amiga.getConfig(.INSERT_VOLUME, drive: 0) } + set { amiga.configure(.INSERT_VOLUME, value: newValue) } + } + var ejectVolume: Int { + get { return amiga.getConfig(.EJECT_VOLUME, drive: 0) } + set { amiga.configure(.EJECT_VOLUME, value: newValue) } } // @@ -463,13 +500,13 @@ class Configuration { amiga.suspend() agnusRev = defaults.agnusRev.rawValue - slowRamMirror = defaults.slowRamMirror deniseRev = defaults.deniseRev.rawValue - borderBlank = defaults.borderBlank ciaRev = defaults.ciaRev.rawValue - todBug = defaults.todBug rtClock = defaults.realTimeClock.rawValue - + + filterType = defaults.filterType.rawValue + filterAlwaysOn = defaults.filterAlwaysOn + chipRam = defaults.chipRam slowRam = defaults.slowRam fastRam = defaults.fastRam @@ -488,13 +525,13 @@ class Configuration { amiga.suspend() agnusRev = defaults.integer(forKey: Keys.Hrw.agnusRev) - slowRamMirror = defaults.bool(forKey: Keys.Hrw.slowRamMirror) deniseRev = defaults.integer(forKey: Keys.Hrw.deniseRev) - borderBlank = defaults.bool(forKey: Keys.Hrw.borderBlank) ciaRev = defaults.integer(forKey: Keys.Hrw.ciaRev) - todBug = defaults.bool(forKey: Keys.Hrw.todBug) rtClock = defaults.integer(forKey: Keys.Hrw.realTimeClock) + filterType = defaults.integer(forKey: Keys.Hrw.filterType) + filterAlwaysOn = defaults.bool(forKey: Keys.Hrw.filterAlwaysOn) + chipRam = defaults.integer(forKey: Keys.Hrw.chipRam) slowRam = defaults.integer(forKey: Keys.Hrw.slowRam) fastRam = defaults.integer(forKey: Keys.Hrw.fastRam) @@ -513,13 +550,13 @@ class Configuration { let defaults = UserDefaults.standard defaults.set(agnusRev, forKey: Keys.Hrw.agnusRev) - defaults.set(slowRamMirror, forKey: Keys.Hrw.slowRamMirror) defaults.set(deniseRev, forKey: Keys.Hrw.deniseRev) - defaults.set(borderBlank, forKey: Keys.Hrw.borderBlank) defaults.set(ciaRev, forKey: Keys.Hrw.ciaRev) - defaults.set(todBug, forKey: Keys.Hrw.todBug) defaults.set(rtClock, forKey: Keys.Hrw.realTimeClock) + defaults.set(filterType, forKey: Keys.Hrw.filterType) + defaults.set(filterAlwaysOn, forKey: Keys.Hrw.filterAlwaysOn) + defaults.set(chipRam, forKey: Keys.Hrw.chipRam) defaults.set(slowRam, forKey: Keys.Hrw.slowRam) defaults.set(fastRam, forKey: Keys.Hrw.fastRam) @@ -546,6 +583,9 @@ class Configuration { df2Type = defaults.driveType[2].rawValue df3Type = defaults.driveType[3].rawValue + blankDiskFormat = defaults.blankDiskFormat + bootBlock = defaults.bootBlock + gameDevice1 = defaults.gameDevice1 gameDevice2 = defaults.gameDevice2 serialDevice = defaults.serialDevice.rawValue @@ -567,6 +607,9 @@ class Configuration { df1Type = defaults.integer(forKey: Keys.Per.df1Type) df2Type = defaults.integer(forKey: Keys.Per.df2Type) df3Type = defaults.integer(forKey: Keys.Per.df3Type) + + blankDiskFormatIntValue = defaults.integer(forKey: Keys.Per.blankDiskFormat) + bootBlock = defaults.integer(forKey: Keys.Per.bootBlock) gameDevice1 = defaults.integer(forKey: Keys.Per.gameDevice1) gameDevice2 = defaults.integer(forKey: Keys.Per.gameDevice2) @@ -589,11 +632,13 @@ class Configuration { defaults.set(df1Type, forKey: Keys.Per.df1Type) defaults.set(df2Type, forKey: Keys.Per.df2Type) defaults.set(df3Type, forKey: Keys.Per.df3Type) - + + defaults.set(blankDiskFormat, forKey: Keys.Per.blankDiskFormat) + defaults.set(bootBlock, forKey: Keys.Per.bootBlock) + defaults.set(gameDevice1, forKey: Keys.Per.gameDevice1) defaults.set(gameDevice2, forKey: Keys.Per.gameDevice2) defaults.set(serialDevice, forKey: Keys.Per.serialDevice) - } // @@ -606,6 +651,9 @@ class Configuration { blitterAccuracy = defaults.blitterAccuracy + slowRamMirror = defaults.slowRamMirror + todBug = defaults.todBug + eClockSyncing = defaults.eClockSyncing slowRamDelay = defaults.slowRamDelay @@ -631,6 +679,9 @@ class Configuration { blitterAccuracy = defaults.integer(forKey: Keys.Com.blitterAccuracy) + slowRamMirror = defaults.bool(forKey: Keys.Com.slowRamMirror) + todBug = defaults.bool(forKey: Keys.Com.todBug) + eClockSyncing = defaults.bool(forKey: Keys.Com.eClockSyncing) slowRamDelay = defaults.bool(forKey: Keys.Com.slowRamDelay) @@ -656,6 +707,9 @@ class Configuration { defaults.set(blitterAccuracy, forKey: Keys.Com.blitterAccuracy) + defaults.set(slowRamMirror, forKey: Keys.Com.slowRamMirror) + defaults.set(todBug, forKey: Keys.Com.todBug) + defaults.set(eClockSyncing, forKey: Keys.Com.eClockSyncing) defaults.set(slowRamDelay, forKey: Keys.Com.slowRamDelay) @@ -691,8 +745,15 @@ class Configuration { volL = defaults.volL volR = defaults.volR samplingMethod = defaults.samplingMethod.rawValue - filterType = defaults.filterType.rawValue - filterAlwaysOn = defaults.filterAlwaysOn + + df0Pan = defaults.drivePan[0] + df1Pan = defaults.drivePan[1] + df2Pan = defaults.drivePan[2] + df3Pan = defaults.drivePan[3] + stepVolume = defaults.stepVolume + pollVolume = defaults.pollVolume + insertVolume = defaults.insertVolume + ejectVolume = defaults.ejectVolume amiga.resume() } @@ -715,8 +776,15 @@ class Configuration { volL = defaults.integer(forKey: Keys.Aud.volL) volR = defaults.integer(forKey: Keys.Aud.volR) samplingMethod = defaults.integer(forKey: Keys.Aud.samplingMethod) - filterType = defaults.integer(forKey: Keys.Aud.filterType) - filterAlwaysOn = defaults.bool(forKey: Keys.Aud.filterAlwaysOn) + + df0Pan = defaults.integer(forKey: Keys.Aud.df0Pan) + df1Pan = defaults.integer(forKey: Keys.Aud.df1Pan) + df2Pan = defaults.integer(forKey: Keys.Aud.df2Pan) + df3Pan = defaults.integer(forKey: Keys.Aud.df3Pan) + stepVolume = defaults.integer(forKey: Keys.Aud.stepVolume) + pollVolume = defaults.integer(forKey: Keys.Aud.pollVolume) + insertVolume = defaults.integer(forKey: Keys.Aud.insertVolume) + ejectVolume = defaults.integer(forKey: Keys.Aud.ejectVolume) amiga.resume() } @@ -739,8 +807,15 @@ class Configuration { defaults.set(volL, forKey: Keys.Aud.volL) defaults.set(volR, forKey: Keys.Aud.volR) defaults.set(samplingMethod, forKey: Keys.Aud.samplingMethod) - defaults.set(filterType, forKey: Keys.Aud.filterType) - defaults.set(filterAlwaysOn, forKey: Keys.Aud.filterAlwaysOn) + + defaults.set(df0Pan, forKey: Keys.Aud.df0Pan) + defaults.set(df1Pan, forKey: Keys.Aud.df1Pan) + defaults.set(df2Pan, forKey: Keys.Aud.df2Pan) + defaults.set(df3Pan, forKey: Keys.Aud.df3Pan) + defaults.set(stepVolume, forKey: Keys.Aud.stepVolume) + defaults.set(pollVolume, forKey: Keys.Aud.pollVolume) + defaults.set(insertVolume, forKey: Keys.Aud.insertVolume) + defaults.set(ejectVolume, forKey: Keys.Aud.ejectVolume) } // diff --git a/GUI/Settings/Configuration/ConfigurationController.swift b/GUI/Settings/Configuration/ConfigurationController.swift index 9a04f6808..023e39b8b 100644 --- a/GUI/Settings/Configuration/ConfigurationController.swift +++ b/GUI/Settings/Configuration/ConfigurationController.swift @@ -50,11 +50,8 @@ class ConfigurationController: DialogController { // Chipset @IBOutlet weak var hwAgnusRevisionPopup: NSPopUpButton! - @IBOutlet weak var hwSlowRamMirror: NSButton! @IBOutlet weak var hwDeniseRevisionPopup: NSPopUpButton! - @IBOutlet weak var hwBorderBlank: NSButton! @IBOutlet weak var hwCiaRevisionPopup: NSPopUpButton! - @IBOutlet weak var hwTodBug: NSButton! @IBOutlet weak var hwRealTimeClock: NSPopUpButton! // Memory @@ -62,10 +59,13 @@ class ConfigurationController: DialogController { @IBOutlet weak var hwSlowRamPopup: NSPopUpButton! @IBOutlet weak var hwFastRamPopup: NSPopUpButton! @IBOutlet weak var hwRamInitPattern: NSPopUpButton! - @IBOutlet weak var hwBankMap: NSPopUpButton! @IBOutlet weak var hwUnmappingType: NSPopUpButton! + // Filter + @IBOutlet weak var hwFilterType: NSPopUpButton! + @IBOutlet weak var hwFilterAlwaysOn: NSButton! + // Lock @IBOutlet weak var hwLockImage: NSButton! @IBOutlet weak var hwLockText: NSTextField! @@ -89,6 +89,10 @@ class ConfigurationController: DialogController { @IBOutlet weak var perDf3Connect: NSButton! @IBOutlet weak var perDf3Type: NSPopUpButton! + // Disks + @IBOutlet weak var perDriveBlankDiskFormat: NSPopUpButton! + @IBOutlet weak var perBootCode: NSPopUpButton! + // Ports @IBOutlet weak var perGameDevice1: NSPopUpButton! @IBOutlet weak var perGameDevice2: NSPopUpButton! @@ -118,15 +122,20 @@ class ConfigurationController: DialogController { @IBOutlet weak var compBltLevel2: NSTextField! @IBOutlet weak var compBltLevel1: NSTextField! + // Chipset features + @IBOutlet weak var compSlowRamMirror: NSButton! + @IBOutlet weak var compBorderBlank: NSButton! + @IBOutlet weak var compTodBug: NSButton! + + // Timing + @IBOutlet weak var compEClockSyncing: NSButton! + @IBOutlet weak var compSlowRamDelay: NSButton! + // Disk controller @IBOutlet weak var compDriveSpeed: NSPopUpButton! @IBOutlet weak var compMechanicalDelays: NSButton! @IBOutlet weak var compLockDskSync: NSButton! @IBOutlet weak var compAutoDskSync: NSButton! - - // Timing - @IBOutlet weak var compEClockSyncing: NSButton! - @IBOutlet weak var compSlowRamDelay: NSButton! // Keyboard @IBOutlet weak var compAccurateKeyboard: NSButton! @@ -157,8 +166,16 @@ class ConfigurationController: DialogController { @IBOutlet weak var audVolL: NSSlider! @IBOutlet weak var audVolR: NSSlider! @IBOutlet weak var audSamplingMethod: NSPopUpButton! - @IBOutlet weak var audFilterType: NSPopUpButton! - @IBOutlet weak var audFilterAlwaysOn: NSButton! + + // Drive volumes + @IBOutlet weak var audDf0Pan: NSSlider! + @IBOutlet weak var audDf1Pan: NSSlider! + @IBOutlet weak var audDf2Pan: NSSlider! + @IBOutlet weak var audDf3Pan: NSSlider! + @IBOutlet weak var audStepVolume: NSSlider! + @IBOutlet weak var audPollVolume: NSSlider! + @IBOutlet weak var audEjectVolume: NSSlider! + @IBOutlet weak var audInsertVolume: NSSlider! // Buttons @IBOutlet weak var audOKButton: NSButton! diff --git a/GUI/Settings/Configuration/HardwarePrefs.swift b/GUI/Settings/Configuration/HardwareConf.swift similarity index 86% rename from GUI/Settings/Configuration/HardwarePrefs.swift rename to GUI/Settings/Configuration/HardwareConf.swift index 5c7c1cf6a..a63e0dd84 100644 --- a/GUI/Settings/Configuration/HardwarePrefs.swift +++ b/GUI/Settings/Configuration/HardwareConf.swift @@ -12,18 +12,18 @@ extension ConfigurationController { func refreshHardwareTab() { let poweredOff = amiga.poweredOff - let ocsAgnus = config.agnusRev == AgnusRevision.OCS.rawValue // Chipset hwAgnusRevisionPopup.selectItem(withTag: config.agnusRev) - hwSlowRamMirror.state = config.slowRamMirror ? .on : .off - hwSlowRamMirror.isEnabled = !ocsAgnus hwDeniseRevisionPopup.selectItem(withTag: config.deniseRev) - hwBorderBlank.state = config.borderBlank ? .on : .off hwCiaRevisionPopup.selectItem(withTag: config.ciaRev) - hwTodBug.state = config.todBug ? .on : .off hwRealTimeClock.selectItem(withTag: config.rtClock) + // Audio filter + hwFilterType.selectItem(withTag: config.filterType) + hwFilterAlwaysOn.state = config.filterAlwaysOn ? .on : .off + hwFilterAlwaysOn.isEnabled = config.filterType != FilterType.NONE.rawValue + // Memory hwChipRamPopup.selectItem(withTag: config.chipRam) hwSlowRamPopup.selectItem(withTag: config.slowRam) @@ -58,33 +58,27 @@ extension ConfigurationController { refresh() } - @IBAction func hwSlowRamMirrorAction(_ sender: NSButton!) { - - config.slowRamMirror = sender.state == .on - refresh() - } - @IBAction func hwDeniseRevAction(_ sender: NSPopUpButton!) { config.deniseRev = sender.selectedTag() refresh() } - @IBAction func hwBorderBlankAction(_ sender: NSButton!) { - - config.borderBlank = sender.state == .on + @IBAction func hwFilterTypeAction(_ sender: NSPopUpButton!) { + + config.filterType = sender.selectedTag() refresh() } - @IBAction func hwCiaRevAction(_ sender: NSPopUpButton!) { + @IBAction func hwFilterAlwaysOnAction(_ sender: NSButton!) { - config.ciaRev = sender.selectedTag() + config.filterAlwaysOn = sender.state == .on refresh() } + + @IBAction func hwCiaRevAction(_ sender: NSPopUpButton!) { - @IBAction func hwTodBugAction(_ sender: NSButton!) { - - config.todBug = sender.state == .on + config.ciaRev = sender.selectedTag() refresh() } diff --git a/GUI/Settings/Configuration/PeripheralsPrefs.swift b/GUI/Settings/Configuration/PeripheralsConf.swift similarity index 84% rename from GUI/Settings/Configuration/PeripheralsPrefs.swift rename to GUI/Settings/Configuration/PeripheralsConf.swift index 7a1ecf178..20b07eadc 100644 --- a/GUI/Settings/Configuration/PeripheralsPrefs.swift +++ b/GUI/Settings/Configuration/PeripheralsConf.swift @@ -22,6 +22,11 @@ extension ConfigurationController { perDf2Type.selectItem(withTag: config.df2Type) perDf3Type.selectItem(withTag: config.df3Type) + // Disk + perDriveBlankDiskFormat.selectItem(withTag: config.blankDiskFormatIntValue) + perBootCode.selectItem(withTag: config.bootBlock) + perBootCode.isEnabled = config.blankDiskFormat != .NODOS + // Ports parent.gamePadManager.refresh(popup: perGameDevice1, hide: true) parent.gamePadManager.refresh(popup: perGameDevice2, hide: true) @@ -76,7 +81,25 @@ extension ConfigurationController { } refresh() } + + @IBAction func perBlankDiskFormatAction(_ sender: NSPopUpButton!) { + + track("tag = \(sender.selectedTag())") + + let tag = sender.selectedTag() + config.blankDiskFormatIntValue = tag + refresh() + } + @IBAction func perBootCodeAction(_ sender: NSPopUpButton!) { + + track("tag = \(sender.selectedTag())") + + let tag = sender.selectedTag() + config.bootBlock = tag + refresh() + } + @IBAction func perGameDeviceAction(_ sender: NSPopUpButton!) { track("port: \(sender.tag) device: \(sender.selectedTag())") diff --git a/GUI/Settings/Configuration/RomPrefs.swift b/GUI/Settings/Configuration/RomConf.swift similarity index 100% rename from GUI/Settings/Configuration/RomPrefs.swift rename to GUI/Settings/Configuration/RomConf.swift diff --git a/GUI/Settings/Configuration/VideoPrefs.swift b/GUI/Settings/Configuration/VideoConf.swift similarity index 100% rename from GUI/Settings/Configuration/VideoPrefs.swift rename to GUI/Settings/Configuration/VideoConf.swift diff --git a/GUI/Settings/Defaults.swift b/GUI/Settings/Defaults.swift index c4c2c5d70..8898ed4e3 100644 --- a/GUI/Settings/Defaults.swift +++ b/GUI/Settings/Defaults.swift @@ -127,18 +127,7 @@ extension MyController { struct Keys { struct Gen { - - // Drives - static let blankDiskFormat = "VAMIGA_GEN_BlankDiskFormat" - static let bootBlock = "VAMIGA_GEN_BootBlock" - static let ejectWithoutAsking = "VAMIGA_GEN_EjectWithoutAsking" - static let driveSounds = "VAMIGA_GEN_DriveSounds" - static let driveSoundPan = "VAMIGA_GEN_DriveSoundPan" - static let driveInsertSound = "VAMIGA_GEN_DriveInsertSound" - static let driveEjectSound = "VAMIGA_GEN_DriveEjectSound" - static let driveHeadSound = "VAMIGA_GEN_DriveHeadSound" - static let drivePollSound = "VAMIGA_GEN_DrivePollSound" - + // Fullscreen static let keepAspectRatio = "VAMIGA_GEN_FullscreenKeepAspectRatio" static let exitOnEsc = "VAMIGA_GEN_FullscreenExitOnEsc" @@ -147,24 +136,14 @@ struct Keys { static let warpMode = "VAMIGA_GEN_WarpMode" // Miscellaneous + static let ejectWithoutAsking = "VAMIGA_GEN_EjectWithoutAsking" static let pauseInBackground = "VAMIGA_GEN_PauseInBackground" static let closeWithoutAsking = "VAMIGA_GEN_CloseWithoutAsking" } } struct GeneralDefaults { - - // Drives - let blankDiskFormat: FSVolumeType - let bootBlock: Int - let ejectWithoutAsking: Bool - let driveSounds: Bool - let driveSoundPan: Double - let driveInsertSound: Bool - let driveEjectSound: Bool - let driveHeadSound: Bool - let drivePollSound: Bool - + // Fullscreen let keepAspectRatio: Bool let exitOnEsc: Bool @@ -173,6 +152,7 @@ struct GeneralDefaults { let warpMode: WarpMode // Miscellaneous + let ejectWithoutAsking: Bool let pauseInBackground: Bool let closeWithoutAsking: Bool @@ -181,22 +161,13 @@ struct GeneralDefaults { // static let std = GeneralDefaults.init( - - blankDiskFormat: .OFS, - bootBlock: 0, - ejectWithoutAsking: false, - driveSounds: true, - driveSoundPan: 1.0, - driveInsertSound: true, - driveEjectSound: true, - driveHeadSound: true, - drivePollSound: false, - + keepAspectRatio: false, exitOnEsc: true, warpMode: .off, + ejectWithoutAsking: false, pauseInBackground: false, closeWithoutAsking: false ) @@ -209,21 +180,12 @@ extension UserDefaults { let defaults = GeneralDefaults.std let dictionary: [String: Any] = [ - Keys.Gen.blankDiskFormat: Int(defaults.blankDiskFormat.rawValue), - Keys.Gen.bootBlock: defaults.bootBlock, - Keys.Gen.ejectWithoutAsking: defaults.ejectWithoutAsking, - Keys.Gen.driveSounds: defaults.driveSounds, - Keys.Gen.driveSoundPan: defaults.driveSoundPan, - Keys.Gen.driveInsertSound: defaults.driveInsertSound, - Keys.Gen.driveEjectSound: defaults.driveEjectSound, - Keys.Gen.driveHeadSound: defaults.driveHeadSound, - Keys.Gen.drivePollSound: defaults.drivePollSound, - Keys.Gen.keepAspectRatio: defaults.keepAspectRatio, Keys.Gen.exitOnEsc: defaults.exitOnEsc, Keys.Gen.warpMode: Int(defaults.warpMode.rawValue), + Keys.Gen.ejectWithoutAsking: defaults.ejectWithoutAsking, Keys.Gen.pauseInBackground: defaults.pauseInBackground, Keys.Gen.closeWithoutAsking: defaults.closeWithoutAsking ] @@ -237,21 +199,12 @@ extension UserDefaults { let defaults = UserDefaults.standard - let keys = [ Keys.Gen.blankDiskFormat, - Keys.Gen.bootBlock, - Keys.Gen.ejectWithoutAsking, - Keys.Gen.driveSounds, - Keys.Gen.driveSoundPan, - Keys.Gen.driveInsertSound, - Keys.Gen.driveEjectSound, - Keys.Gen.driveHeadSound, - Keys.Gen.drivePollSound, - - Keys.Gen.keepAspectRatio, + let keys = [ Keys.Gen.keepAspectRatio, Keys.Gen.exitOnEsc, Keys.Gen.warpMode, + Keys.Gen.ejectWithoutAsking, Keys.Gen.pauseInBackground, Keys.Gen.closeWithoutAsking ] @@ -632,7 +585,7 @@ extension UserDefaults { static func romUrl(name: String) -> URL? { do { - let folder = try URL.appSupportFolder("Roms") + let folder = try URL.appSupportFolder("Roms", create: true) return folder.appendingPathComponent(name) } catch { return nil @@ -693,13 +646,14 @@ extension Keys { // Chipset static let agnusRev = "VAMIGA_HW_AgnusRev" - static let slowRamMirror = "VAMIGA_HW_SlowRamMirror" static let deniseRev = "VAMIGA_HW_DeniseRev" - static let borderBlank = "VAMIGA_HW_BorderBlank" static let ciaRev = "VAMIGA_HW_CiaRev" - static let todBug = "VAMIGA_HW_TodBug" static let realTimeClock = "VAMIGA_HW_RealTimeClock" + // Filter + static let filterType = "VAMIGA_HW_FilterType" + static let filterAlwaysOn = "VAMIGA_HW_FilterAlwaysOn" + // Memory static let chipRam = "VAMIGA_HW_ChipRam" static let slowRam = "VAMIGA_HW_SlowRam" @@ -713,21 +667,21 @@ extension Keys { struct HardwareDefaults { - var agnusRev: AgnusRevision - let slowRamMirror: Bool - var deniseRev: DeniseRevision - var borderBlank: Bool - var ciaRev: CIARevision - var todBug: Bool - var realTimeClock: RTCRevision + let agnusRev: AgnusRevision + let deniseRev: DeniseRevision + let ciaRev: CIARevision + let realTimeClock: RTCRevision - var chipRam: Int - var slowRam: Int - var fastRam: Int - var ramInitPattern: RamInitPattern + let filterType: FilterType + let filterAlwaysOn: Bool - var bankMap: BankMap - var unmappingType: UnmappedMemory + let chipRam: Int + let slowRam: Int + let fastRam: Int + let ramInitPattern: RamInitPattern + + let bankMap: BankMap + let unmappingType: UnmappedMemory // // Schemes @@ -736,13 +690,13 @@ struct HardwareDefaults { static let A500 = HardwareDefaults.init( agnusRev: .ECS_1MB, - slowRamMirror: true, deniseRev: .OCS, - borderBlank: false, ciaRev: ._8520_DIP, - todBug: true, realTimeClock: .OKI, + filterType: .BUTTERWORTH, + filterAlwaysOn: false, + chipRam: 512, slowRam: 512, fastRam: 0, @@ -755,13 +709,13 @@ struct HardwareDefaults { static let A1000 = HardwareDefaults.init( agnusRev: .OCS, - slowRamMirror: true, deniseRev: .OCS, - borderBlank: false, ciaRev: ._8520_DIP, - todBug: true, realTimeClock: .NONE, + filterType: .BUTTERWORTH, + filterAlwaysOn: false, + chipRam: 256, slowRam: 0, fastRam: 0, @@ -774,13 +728,13 @@ struct HardwareDefaults { static let A2000 = HardwareDefaults.init( agnusRev: .ECS_2MB, - slowRamMirror: true, deniseRev: .OCS, - borderBlank: false, ciaRev: ._8520_DIP, - todBug: true, realTimeClock: .OKI, + filterType: .BUTTERWORTH, + filterAlwaysOn: false, + chipRam: 512, slowRam: 512, fastRam: 0, @@ -799,13 +753,13 @@ extension UserDefaults { let dictionary: [String: Any] = [ Keys.Hrw.agnusRev: defaults.agnusRev.rawValue, - Keys.Hrw.slowRamMirror: defaults.slowRamMirror, Keys.Hrw.deniseRev: defaults.deniseRev.rawValue, - Keys.Hrw.borderBlank: defaults.borderBlank, Keys.Hrw.ciaRev: defaults.ciaRev.rawValue, - Keys.Hrw.todBug: defaults.todBug, Keys.Hrw.realTimeClock: defaults.realTimeClock.rawValue, + Keys.Hrw.filterType: defaults.filterType.rawValue, + Keys.Hrw.filterAlwaysOn: defaults.filterAlwaysOn, + Keys.Hrw.chipRam: defaults.chipRam, Keys.Hrw.slowRam: defaults.slowRam, Keys.Hrw.fastRam: defaults.fastRam, @@ -824,13 +778,13 @@ extension UserDefaults { let defaults = UserDefaults.standard let keys = [Keys.Hrw.agnusRev, - Keys.Hrw.slowRamMirror, Keys.Hrw.deniseRev, - Keys.Hrw.borderBlank, Keys.Hrw.ciaRev, - Keys.Hrw.todBug, Keys.Hrw.realTimeClock, - + + Keys.Hrw.filterType, + Keys.Hrw.filterAlwaysOn, + Keys.Hrw.chipRam, Keys.Hrw.slowRam, Keys.Hrw.fastRam, @@ -862,6 +816,10 @@ extension Keys { static let df2Type = "VAMIGA_PER_DF2Type" static let df3Type = "VAMIGA_PER_DF3Type" + // Floppy disks + static let blankDiskFormat = "VAMIGA_PER_BlankDiskFormat" + static let bootBlock = "VAMIGA_PER_BootBlock" + // Ports static let gameDevice1 = "VAMIGA_PER_GameDevice1" static let gameDevice2 = "VAMIGA_PER_GameDevice2" @@ -874,6 +832,9 @@ struct PeripheralsDefaults { var driveConnect: [Bool] var driveType: [DriveType] + let blankDiskFormat: FSVolumeType + let bootBlock: Int + var gameDevice1: Int var gameDevice2: Int var serialDevice: SerialPortDevice @@ -887,6 +848,9 @@ struct PeripheralsDefaults { driveConnect: [true, false, false, false], driveType: [.DD_35, .DD_35, .DD_35, .DD_35], + blankDiskFormat: .OFS, + bootBlock: 0, + gameDevice1: 0, gameDevice2: -1, serialDevice: .NONE @@ -909,6 +873,9 @@ extension UserDefaults { Keys.Per.df2Type: defaults.driveType[2].rawValue, Keys.Per.df3Type: defaults.driveType[3].rawValue, + Keys.Per.blankDiskFormat: Int(defaults.blankDiskFormat.rawValue), + Keys.Per.bootBlock: defaults.bootBlock, + Keys.Per.gameDevice1: defaults.gameDevice1, Keys.Per.gameDevice2: defaults.gameDevice2, Keys.Per.serialDevice: defaults.serialDevice.rawValue @@ -931,6 +898,9 @@ extension UserDefaults { Keys.Per.df2Type, Keys.Per.df3Type, + Keys.Per.blankDiskFormat, + Keys.Per.bootBlock, + Keys.Per.gameDevice1, Keys.Per.gameDevice2, Keys.Per.serialDevice @@ -951,6 +921,11 @@ extension Keys { // Blitter static let blitterAccuracy = "VAMIGA_COM_BlitterAccuracy" + // Chipset + static let slowRamMirror = "VAMIGA_COM_SlowRamMirror" + static let borderBlank = "VAMIGA_COM_BorderBlank" + static let todBug = "VAMIGA_COM_TodBug" + // Timing static let eClockSyncing = "VAMIGA_COM_EClockSyncing" static let slowRamDelay = "VAMIGA_COM_SlowRamDelay" @@ -975,6 +950,10 @@ struct CompatibilityDefaults { let blitterAccuracy: Int + let slowRamMirror: Bool + let borderBlank: Bool + let todBug: Bool + let eClockSyncing: Bool let slowRamDelay: Bool @@ -997,6 +976,10 @@ struct CompatibilityDefaults { blitterAccuracy: 2, + slowRamMirror: true, + borderBlank: false, + todBug: true, + eClockSyncing: true, slowRamDelay: true, @@ -1016,6 +999,10 @@ struct CompatibilityDefaults { blitterAccuracy: 2, + slowRamMirror: true, + borderBlank: false, + todBug: true, + eClockSyncing: true, slowRamDelay: true, @@ -1035,6 +1022,10 @@ struct CompatibilityDefaults { blitterAccuracy: 0, + slowRamMirror: true, + borderBlank: false, + todBug: true, + eClockSyncing: false, slowRamDelay: false, @@ -1060,6 +1051,10 @@ extension UserDefaults { Keys.Com.blitterAccuracy: defaults.blitterAccuracy, + Keys.Com.slowRamMirror: defaults.slowRamMirror, + Keys.Com.borderBlank: defaults.borderBlank, + Keys.Com.todBug: defaults.todBug, + Keys.Com.eClockSyncing: defaults.eClockSyncing, Keys.Com.slowRamDelay: defaults.slowRamDelay, @@ -1084,7 +1079,11 @@ extension UserDefaults { let userDefaults = UserDefaults.standard let keys = [ Keys.Com.blitterAccuracy, - + + Keys.Com.slowRamMirror, + Keys.Com.borderBlank, + Keys.Com.todBug, + Keys.Com.eClockSyncing, Keys.Com.slowRamDelay, @@ -1125,8 +1124,16 @@ extension Keys { static let volL = "VAMIGA_AUD_VolumeL" static let volR = "VAMIGA_AUD_VolumeR" static let samplingMethod = "VAMIGA_AUD_SamplingMethod" - static let filterType = "VAMIGA_AUD_FilterType" - static let filterAlwaysOn = "VAMIGA_AUD_FilterAlwaysOn" + + // Drive volumes + static let df0Pan = "VAMIGA_PER_DF0Pan" + static let df1Pan = "VAMIGA_PER_DF1Pan" + static let df2Pan = "VAMIGA_PER_DF2Pan" + static let df3Pan = "VAMIGA_PER_DF3Pan" + static let stepVolume = "VAMIGA_PER_StepVolume" + static let pollVolume = "VAMIGA_PER_PollVolume" + static let insertVolume = "VAMIGA_PER_InsertVolume" + static let ejectVolume = "VAMIGA_PER_EjectVolume" } } @@ -1145,10 +1152,14 @@ struct AudioDefaults { // Out let volL: Int let volR: Int - let samplingMethod: SamplingMethod - let filterType: FilterType - let filterAlwaysOn: Bool + + // Drive + var drivePan: [Int] + var stepVolume: Int + var pollVolume: Int + var insertVolume: Int + var ejectVolume: Int // // Schemes @@ -1168,8 +1179,12 @@ struct AudioDefaults { volL: 50, volR: 50, samplingMethod: .NONE, - filterType: .BUTTERWORTH, - filterAlwaysOn: false + + drivePan: [100, 300, 100, 300], + stepVolume: 50, + pollVolume: 0, + insertVolume: 50, + ejectVolume: 50 ) static let stereo = AudioDefaults.init( @@ -1186,8 +1201,12 @@ struct AudioDefaults { volL: 50, volR: 50, samplingMethod: .NONE, - filterType: .BUTTERWORTH, - filterAlwaysOn: false + + drivePan: [100, 300, 100, 300], + stepVolume: 50, + pollVolume: 0, + insertVolume: 50, + ejectVolume: 50 ) static let mono = AudioDefaults.init( @@ -1204,8 +1223,12 @@ struct AudioDefaults { volL: 50, volR: 50, samplingMethod: .NONE, - filterType: .BUTTERWORTH, - filterAlwaysOn: false + + drivePan: [100, 300, 100, 300], + stepVolume: 50, + pollVolume: 0, + insertVolume: 50, + ejectVolume: 50 ) } @@ -1228,8 +1251,15 @@ extension UserDefaults { Keys.Aud.volL: defaults.volL, Keys.Aud.volR: defaults.volR, Keys.Aud.samplingMethod: Int(defaults.samplingMethod.rawValue), - Keys.Aud.filterType: Int(defaults.filterType.rawValue), - Keys.Aud.filterAlwaysOn: defaults.filterAlwaysOn + + Keys.Aud.df0Pan: defaults.drivePan[0], + Keys.Aud.df1Pan: defaults.drivePan[1], + Keys.Aud.df2Pan: defaults.drivePan[2], + Keys.Aud.df3Pan: defaults.drivePan[3], + Keys.Aud.stepVolume: defaults.stepVolume, + Keys.Aud.pollVolume: defaults.pollVolume, + Keys.Aud.insertVolume: defaults.insertVolume, + Keys.Aud.ejectVolume: defaults.ejectVolume ] let userDefaults = UserDefaults.standard @@ -1252,8 +1282,15 @@ extension UserDefaults { Keys.Aud.volL, Keys.Aud.volR, Keys.Aud.samplingMethod, - Keys.Aud.filterType, - Keys.Aud.filterAlwaysOn] + + Keys.Aud.df0Pan, + Keys.Aud.df1Pan, + Keys.Aud.df2Pan, + Keys.Aud.df3Pan, + Keys.Aud.stepVolume, + Keys.Aud.pollVolume, + Keys.Aud.insertVolume, + Keys.Aud.ejectVolume ] for key in keys { userDefaults.removeObject(forKey: key) } } diff --git a/GUI/Settings/Preferences/GeneralPrefs.swift b/GUI/Settings/Preferences/GeneralPrefs.swift index b10f07f6a..ab1e470e5 100644 --- a/GUI/Settings/Preferences/GeneralPrefs.swift +++ b/GUI/Settings/Preferences/GeneralPrefs.swift @@ -10,27 +10,7 @@ extension PreferencesController { func refreshGeneralTab() { - - let contaminated = pref.bootBlock >= 10 - - // Drive - genDriveBlankDiskFormat.selectItem(withTag: pref.blankDiskFormatIntValue) - genBootCode.selectItem(withTag: pref.bootBlock) - genBootCode.isEnabled = pref.blankDiskFormat != .NODOS - genBootCodeVirus.isHidden = !contaminated - genEjectWithoutAskingButton.state = pref.ejectWithoutAsking ? .on : .off - genDriveSounds.state = pref.driveSounds ? .on : .off - genDriveSoundPan.selectItem(withTag: Int(pref.driveSoundPan)) - genDriveInsertSound.state = pref.driveInsertSound ? .on : .off - genDriveEjectSound.state = pref.driveEjectSound ? .on : .off - genDriveHeadSound.state = pref.driveHeadSound ? .on : .off - genDrivePollSound.state = pref.drivePollSound ? .on : .off - genDriveSoundPan.isEnabled = pref.driveSounds - genDriveInsertSound.isEnabled = pref.driveSounds - genDriveEjectSound.isEnabled = pref.driveSounds - genDriveHeadSound.isEnabled = pref.driveSounds - genDrivePollSound.isEnabled = pref.driveSounds - + // Fullscreen genAspectRatioButton.state = pref.keepAspectRatio ? .on : .off genExitOnEscButton.state = pref.exitOnEsc ? .on : .off @@ -39,67 +19,11 @@ extension PreferencesController { genWarpMode.selectItem(withTag: pref.warpModeIntValue) // Miscellaneous + genEjectWithoutAskingButton.state = pref.ejectWithoutAsking ? .on : .off genPauseInBackground.state = pref.pauseInBackground ? .on : .off genCloseWithoutAskingButton.state = pref.closeWithoutAsking ? .on : .off } - // - // Action methods (Drive) - // - - @IBAction func genDriveSoundsAction(_ sender: NSButton!) { - - pref.driveSounds = sender.state == .on - refresh() - } - - @IBAction func genDriveSoundPanAction(_ sender: NSPopUpButton!) { - - pref.driveSoundPan = Double(sender.selectedTag()) - refresh() - } - - @IBAction func genDriveInsertSoundAction(_ sender: NSButton!) { - - pref.driveInsertSound = sender.state == .on - refresh() - } - - @IBAction func genDriveEjectSoundAction(_ sender: NSButton!) { - - pref.driveEjectSound = sender.state == .on - refresh() - } - - @IBAction func genDriveHeadSoundAction(_ sender: NSButton!) { - - pref.driveHeadSound = sender.state == .on - refresh() - } - - @IBAction func genDrivePollSoundAction(_ sender: NSButton!) { - - track() - pref.drivePollSound = sender.state == .on - refresh() - } - - @IBAction func genBlankDiskFormatAction(_ sender: NSPopUpButton!) { - - let tag = sender.selectedTag() - pref.blankDiskFormatIntValue = tag - refresh() - } - - @IBAction func genBootCodeAction(_ sender: NSPopUpButton!) { - - track("Tag = \(sender.selectedTag())") - - let tag = sender.selectedTag() - pref.bootBlock = tag - refresh() - } - // // Action methods (Fullscreen) // @@ -130,6 +54,12 @@ extension PreferencesController { // Action methods (Miscellaneous) // + @IBAction func genEjectWithoutAskingAction(_ sender: NSButton!) { + + pref.ejectWithoutAsking = (sender.state == .on) + refresh() + } + @IBAction func genPauseInBackgroundAction(_ sender: NSButton!) { pref.pauseInBackground = (sender.state == .on) @@ -145,12 +75,6 @@ extension PreferencesController { refresh() } - @IBAction func genEjectWithoutAskingAction(_ sender: NSButton!) { - - pref.ejectWithoutAsking = (sender.state == .on) - refresh() - } - // // Action methods (Misc) // diff --git a/GUI/Settings/Preferences/Preferences.swift b/GUI/Settings/Preferences/Preferences.swift index 434dc6a6f..f890c19bf 100644 --- a/GUI/Settings/Preferences/Preferences.swift +++ b/GUI/Settings/Preferences/Preferences.swift @@ -18,26 +18,17 @@ class Preferences { - // var myAppDelegate: MyAppDelegate { return NSApp.delegate as! MyAppDelegate } - // // General // // Floppy - var blankDiskFormat = GeneralDefaults.std.blankDiskFormat + var blankDiskFormat = PeripheralsDefaults.std.blankDiskFormat var blankDiskFormatIntValue: Int { get { return Int(blankDiskFormat.rawValue) } set { blankDiskFormat = FSVolumeType.init(rawValue: newValue)! } } - var bootBlock = GeneralDefaults.std.bootBlock - var ejectWithoutAsking = GeneralDefaults.std.ejectWithoutAsking - var driveSounds = GeneralDefaults.std.driveSounds - var driveSoundPan = GeneralDefaults.std.driveSoundPan - var driveInsertSound = GeneralDefaults.std.driveInsertSound - var driveEjectSound = GeneralDefaults.std.driveEjectSound - var driveHeadSound = GeneralDefaults.std.driveHeadSound - var drivePollSound = GeneralDefaults.std.drivePollSound + var bootBlock = PeripheralsDefaults.std.bootBlock // Fullscreen var keepAspectRatio = GeneralDefaults.std.keepAspectRatio @@ -53,6 +44,7 @@ class Preferences { } // Misc + var ejectWithoutAsking = GeneralDefaults.std.ejectWithoutAsking var closeWithoutAsking = GeneralDefaults.std.closeWithoutAsking var pauseInBackground = GeneralDefaults.std.pauseInBackground @@ -154,17 +146,6 @@ class Preferences { func loadGeneralDefaults(_ defaults: GeneralDefaults) { - // Floppy - blankDiskFormat = defaults.blankDiskFormat - bootBlock = defaults.bootBlock - ejectWithoutAsking = defaults.ejectWithoutAsking - driveSounds = defaults.driveSounds - driveSoundPan = defaults.driveSoundPan - driveInsertSound = defaults.driveInsertSound - driveEjectSound = defaults.driveEjectSound - driveHeadSound = defaults.driveHeadSound - drivePollSound = defaults.drivePollSound - // Fullscreen keepAspectRatio = defaults.keepAspectRatio exitOnEsc = defaults.exitOnEsc @@ -173,6 +154,7 @@ class Preferences { warpMode = defaults.warpMode // Misc + ejectWithoutAsking = defaults.ejectWithoutAsking pauseInBackground = defaults.pauseInBackground closeWithoutAsking = defaults.closeWithoutAsking } @@ -181,17 +163,6 @@ class Preferences { let defaults = UserDefaults.standard - // Floppy - blankDiskFormatIntValue = defaults.integer(forKey: Keys.Gen.blankDiskFormat) - bootBlock = defaults.integer(forKey: Keys.Gen.bootBlock) - ejectWithoutAsking = defaults.bool(forKey: Keys.Gen.ejectWithoutAsking) - driveSounds = defaults.bool(forKey: Keys.Gen.driveSounds) - driveSoundPan = defaults.double(forKey: Keys.Gen.driveSoundPan) - driveInsertSound = defaults.bool(forKey: Keys.Gen.driveInsertSound) - driveEjectSound = defaults.bool(forKey: Keys.Gen.driveEjectSound) - driveHeadSound = defaults.bool(forKey: Keys.Gen.driveHeadSound) - drivePollSound = defaults.bool(forKey: Keys.Gen.drivePollSound) - // Fullscreen keepAspectRatio = defaults.bool(forKey: Keys.Gen.keepAspectRatio) exitOnEsc = defaults.bool(forKey: Keys.Gen.exitOnEsc) @@ -200,6 +171,7 @@ class Preferences { warpModeIntValue = defaults.integer(forKey: Keys.Gen.warpMode) // Misc + ejectWithoutAsking = defaults.bool(forKey: Keys.Gen.ejectWithoutAsking) pauseInBackground = defaults.bool(forKey: Keys.Gen.pauseInBackground) closeWithoutAsking = defaults.bool(forKey: Keys.Gen.closeWithoutAsking) } @@ -207,18 +179,7 @@ class Preferences { func saveGeneralUserDefaults() { let defaults = UserDefaults.standard - - // Floppy - defaults.set(blankDiskFormatIntValue, forKey: Keys.Gen.blankDiskFormat) - defaults.set(bootBlock, forKey: Keys.Gen.bootBlock) - defaults.set(ejectWithoutAsking, forKey: Keys.Gen.ejectWithoutAsking) - defaults.set(driveSounds, forKey: Keys.Gen.driveSounds) - defaults.set(driveSoundPan, forKey: Keys.Gen.driveSoundPan) - defaults.set(driveInsertSound, forKey: Keys.Gen.driveInsertSound) - defaults.set(driveEjectSound, forKey: Keys.Gen.driveEjectSound) - defaults.set(driveHeadSound, forKey: Keys.Gen.driveHeadSound) - defaults.set(drivePollSound, forKey: Keys.Gen.drivePollSound) - + // Fullscreen defaults.set(keepAspectRatio, forKey: Keys.Gen.keepAspectRatio) defaults.set(exitOnEsc, forKey: Keys.Gen.exitOnEsc) @@ -227,6 +188,7 @@ class Preferences { defaults.set(warpModeIntValue, forKey: Keys.Gen.warpMode) // Misc + defaults.set(ejectWithoutAsking, forKey: Keys.Gen.ejectWithoutAsking) defaults.set(pauseInBackground, forKey: Keys.Gen.pauseInBackground) defaults.set(closeWithoutAsking, forKey: Keys.Gen.closeWithoutAsking) } diff --git a/GUI/Settings/Preferences/PreferencesController.swift b/GUI/Settings/Preferences/PreferencesController.swift index 88fef1599..6110528c5 100644 --- a/GUI/Settings/Preferences/PreferencesController.swift +++ b/GUI/Settings/Preferences/PreferencesController.swift @@ -11,7 +11,6 @@ class PreferencesController: DialogController { var pref: Preferences { return parent.pref } var gamePadManager: GamePadManager { return parent.gamePadManager! } - // var myAppDelegate: MyAppDelegate { return NSApp.delegate as! MyAppDelegate } @IBOutlet weak var tabView: NSTabView! @@ -19,18 +18,6 @@ class PreferencesController: DialogController { // General // - // Drive - @IBOutlet weak var genDriveBlankDiskFormat: NSPopUpButton! - @IBOutlet weak var genBootCode: NSPopUpButton! - @IBOutlet weak var genBootCodeVirus: NSImageView! - @IBOutlet weak var genEjectWithoutAskingButton: NSButton! - @IBOutlet weak var genDriveSounds: NSButton! - @IBOutlet weak var genDriveSoundPan: NSPopUpButton! - @IBOutlet weak var genDriveInsertSound: NSButton! - @IBOutlet weak var genDriveEjectSound: NSButton! - @IBOutlet weak var genDriveHeadSound: NSButton! - @IBOutlet weak var genDrivePollSound: NSButton! - // Fullscreen @IBOutlet weak var genAspectRatioButton: NSButton! @IBOutlet weak var genExitOnEscButton: NSButton! @@ -39,6 +26,7 @@ class PreferencesController: DialogController { @IBOutlet weak var genWarpMode: NSPopUpButton! // Misc + @IBOutlet weak var genEjectWithoutAskingButton: NSButton! @IBOutlet weak var genPauseInBackground: NSButton! @IBOutlet weak var genCloseWithoutAskingButton: NSButton! diff --git a/GUI/WindowDelegate.swift b/GUI/WindowDelegate.swift index de4ae4ecf..65eae8aec 100644 --- a/GUI/WindowDelegate.swift +++ b/GUI/WindowDelegate.swift @@ -42,6 +42,9 @@ extension MyController: NSWindowDelegate { track() + // Write back screenshot cache + try? mydocument!.persistScreenshots() + // Stop timers timerLock.lock() timer?.invalidate() @@ -52,9 +55,6 @@ extension MyController: NSWindowDelegate { screenshotTimer?.invalidate() screenshotTimer = nil - // Write back screenshot cache - try? mydocument!.persistScreenshots() - // Disconnect and close auxiliary windows inspector?.amiga = nil inspector?.close() @@ -67,11 +67,14 @@ extension MyController: NSWindowDelegate { // Disconnect all game pads gamePadManager.shutDown() - // Unregister from the message queue + // Unregister from the message queue and wait for MSG_UNREGISTER let myself = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque()) amiga.removeListener(myself) - - // Kill the emulator + } + + func shutDown() { + + track("Shutting down the emulator") amiga.kill() amiga = nil } diff --git a/Proxy/AmigaProxy.h b/Proxy/AmigaProxy.h index 43f03b8c8..d461a1ad6 100644 --- a/Proxy/AmigaProxy.h +++ b/Proxy/AmigaProxy.h @@ -142,7 +142,7 @@ @property (readonly, strong) SerialPortProxy *serialPort; - (void)dealloc; -- (void) kill; +- (void)kill; @property (readonly) BOOL isReleaseBuild; @property BOOL warp; diff --git a/Resources/Info.plist b/Resources/Info.plist index fe3457894..3f396124b 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -96,9 +96,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.9.17.2 + 0.9.18 CFBundleVersion - 0.9.17.2 + 0.9.18 LSApplicationCategoryType public.app-category.entertainment LSMinimumSystemVersion diff --git a/XIB files/Configuration.xib b/XIB files/Configuration.xib index 23944b632..6be143bd8 100644 --- a/XIB files/Configuration.xib +++ b/XIB files/Configuration.xib @@ -8,15 +8,21 @@ - - + + + + + + - - + + + + @@ -38,6 +44,8 @@ + + @@ -47,12 +55,13 @@ - + + @@ -60,10 +69,9 @@ - - + @@ -71,6 +79,7 @@ + @@ -421,7 +430,7 @@ DQ - + @@ -443,7 +452,7 @@ DQ - + @@ -451,6 +460,7 @@ DQ + @@ -509,7 +519,7 @@ DQ - + @@ -560,7 +570,7 @@ DQ - + @@ -691,7 +701,7 @@ DQ - + @@ -700,7 +710,7 @@ DQ - + @@ -718,7 +728,7 @@ DQ - + @@ -727,7 +737,7 @@ DQ - + @@ -743,7 +753,7 @@ DQ - + @@ -774,7 +784,7 @@ DQ - + @@ -828,7 +838,7 @@ DQ - + @@ -836,8 +846,17 @@ DQ + + + + + + + + + - + @@ -845,37 +864,43 @@ DQ - - - @@ -977,7 +1002,7 @@ DQ - + @@ -995,7 +1020,7 @@ DQ - + @@ -1019,7 +1044,7 @@ DQ - + @@ -1054,7 +1079,7 @@ DQ - + @@ -1089,7 +1114,7 @@ DQ - + @@ -1109,7 +1134,7 @@ DQ - + @@ -1117,38 +1142,8 @@ DQ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1181,7 +1176,7 @@ DQ - + @@ -1190,7 +1185,7 @@ DQ - + @@ -1199,7 +1194,7 @@ DQ - + @@ -1232,7 +1227,7 @@ DQ - + @@ -1240,6 +1235,120 @@ DQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1454,7 +1563,7 @@ DQ - + @@ -1462,8 +1571,17 @@ DQ + + + + + + + + + - - - - - - - - - - + @@ -1547,7 +1656,7 @@ DQ - + @@ -1555,6 +1664,37 @@ DQ + + + + + + + + + + + @@ -1619,184 +1759,259 @@ DQ - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - - - - - - - - + + - + - - + + - + - - + + + + + + + + + + + + + - - + + + + + + + + + + - - + + - + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + - - + + + + + + + + + + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - + + + + + + + + + + @@ -1805,97 +2020,104 @@ DQ - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - - - - - - - + + + + + + + - - + + - - + + - + + + + + + + + + - - + + - - + + - - + + - + - + - - + + - + - - + + - + - - + + - - + + @@ -1903,62 +2125,83 @@ DQ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1966,7 +2209,7 @@ DQ - + @@ -1975,7 +2218,7 @@ DQ - + @@ -1984,7 +2227,7 @@ DQ - + @@ -1992,7 +2235,7 @@ DQ - + @@ -2001,7 +2244,7 @@ DQ - + @@ -2010,7 +2253,7 @@ DQ - + @@ -2018,7 +2261,7 @@ DQ - + @@ -2027,7 +2270,7 @@ DQ - + @@ -2035,64 +2278,55 @@ DQ - - + + - - - - - - - - + + + + + + + - + - - + + - + - - + + - - + + - - - - - - - - - - + + - - + + - - + + - - + + @@ -2100,56 +2334,6 @@ DQ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2163,7 +2347,7 @@ DQ - + @@ -2172,7 +2356,7 @@ DQ - + @@ -2196,7 +2380,7 @@ DQ - + @@ -2205,7 +2389,7 @@ DQ - + @@ -2235,7 +2419,7 @@ DQ - + @@ -2243,7 +2427,7 @@ DQ - + @@ -2251,7 +2435,7 @@ DQ - + @@ -2260,7 +2444,7 @@ DQ - + @@ -2269,7 +2453,7 @@ DQ - + @@ -2278,7 +2462,7 @@ DQ - + @@ -2299,7 +2483,7 @@ DQ - + @@ -2307,7 +2491,7 @@ DQ - + @@ -2315,7 +2499,7 @@ DQ - + @@ -2324,7 +2508,7 @@ DQ - + @@ -2333,7 +2517,7 @@ DQ - + @@ -2342,7 +2526,7 @@ DQ - + @@ -2350,7 +2534,7 @@ DQ - + @@ -2359,7 +2543,7 @@ DQ - + @@ -2368,7 +2552,7 @@ DQ - + @@ -2389,7 +2573,7 @@ DQ - + @@ -2397,7 +2581,7 @@ DQ - + @@ -2406,7 +2590,7 @@ DQ - + @@ -2415,7 +2599,7 @@ DQ - + @@ -2436,7 +2620,7 @@ DQ - + @@ -2445,7 +2629,7 @@ DQ - + @@ -2466,7 +2650,7 @@ DQ - + @@ -2474,7 +2658,7 @@ DQ - + @@ -2483,7 +2667,7 @@ DQ - + @@ -2491,7 +2675,7 @@ DQ - + @@ -2500,7 +2684,7 @@ DQ - + @@ -2557,7 +2741,7 @@ DQ - + @@ -2566,7 +2750,7 @@ DQ - + @@ -2575,7 +2759,7 @@ DQ - + @@ -2709,7 +2893,7 @@ DQ - + @@ -2718,7 +2902,7 @@ DQ - + @@ -2751,7 +2935,7 @@ DQ - + @@ -2775,7 +2959,7 @@ DQ - + @@ -2784,7 +2968,7 @@ DQ - + diff --git a/XIB files/Preferences.xib b/XIB files/Preferences.xib index 344c6471a..a7dd89f05 100644 --- a/XIB files/Preferences.xib +++ b/XIB files/Preferences.xib @@ -84,16 +84,7 @@ - - - - - - - - - @@ -123,24 +114,6 @@ - - - - - - - - - - - - - - - - - - - - - - + @@ -295,7 +172,7 @@ - + @@ -325,43 +202,29 @@ - - - - - - + + + + + - + - - - - - + - - + + - + - + @@ -370,7 +233,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1780,7 +1585,7 @@