[Scummvm-git-logs] scummvm master -> e98e1bf6354017f676c9383498215563069c479e

mikrosk noreply at scummvm.org
Mon Oct 5 00:52:29 UTC 2026


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
fb089caf24 AUDIO: Make nFM dependency Atari-only for now
e98e1bf635 BACKENDS: ATARI: add -mfastcall code paths


Commit: fb089caf24da732e4e51c2cb7edc5f3e51875728
    https://github.com/scummvm/scummvm/commit/fb089caf24da732e4e51c2cb7edc5f3e51875728
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-10-05T10:52:10+10:00

Commit Message:
AUDIO: Make nFM dependency Atari-only for now

The library still needs some attention so let's not pollute common
source code base more than absolutely required. The reasons why it is
still not suitable for generic use:

- The driver set is fixed when nFM is built, and nothing reports it. A
  program can't query it at runtime, and the installed headers don't
  reflect it.

- Asking for a disabled driver isn't reported as an error in 0.4.0.

- The API is still moving.

So ScummVM's device list can only be correct for one known nFM build:
version 0.4.0, built the way dockerized-bb builds it.

Cleanups:

- The dlmalloc code was not only useless but also buggy

- Enter supervisor mode for the drivers which access I/O registers
  directly; the cartridge port and NatFeats work in user mode

- Debug logs for nFM development do not belong to ScummVM

Changed paths:
  R backends/platform/atari/get-nfm.sh
    audio/fmopl.cpp
    audio/nfmopl.cpp
    audio/nfmopl.h
    backends/platform/atari/build-firebee.sh
    configure


diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp
index c760dbc6265..39ba839383a 100644
--- a/audio/fmopl.cpp
+++ b/audio/fmopl.cpp
@@ -59,18 +59,6 @@ OPL *create(Config::OplType type);
 } // End of namespace RetroWaveOPL3
 #endif // ENABLE_RETROWAVE_OPL3
 
-#ifdef USE_NFM
-namespace NfmOPL {
-namespace RealChip {
-OPL *create(Config::OplType type, enum NfmOPL::OplDevice dt);
-} // End of namespace RealChip
-
-namespace EmulatedChip {
-OPL *create(Config::OplType type, enum NfmOPL::OplDevice dt);
-} // End of namespace EmulatedChip
-} // End of namespace NfmOPL
-#endif
-
 // Config implementation
 
 enum OplEmulator {
@@ -86,14 +74,12 @@ enum OplEmulator {
 #ifdef USE_NFM
 	,kNfmNokturnFM2 = 9,
 	kNfmNokturnFM3 = 10,
-	kNfmRWOpl3Express = 11,
-	kNfmOPL2LPT = 12,
-	kNfmOPL3LPT = 13,
-	kNfmCeOPL2AudioBoard = 14,
-	kNfmCeOPL3Duo = 15,
-	kNfmStBusIsaVmeSb = 16,
-	kNfmNatfeatsNull = 17,
-	kNfmNukedOpl3 = 18
+	kNfmOPL2LPT = 11,
+	kNfmOPL3LPT = 12,
+	kNfmCeOPL2AudioBoard = 13,
+	kNfmCeOPL3Duo = 14,
+	kNfmStBusIsaVmeSb = 15,
+	kNfmNatfeatsNull = 16
 #endif
 };
 
@@ -132,14 +118,12 @@ const Config::EmulatorDescription Config::_drivers[] = {
 #ifdef USE_NFM
 	{"nfm_nokturnfm2", _s("[nFM] NokturnFM2 (OPL2)"), kNfmNokturnFM2, kFlagOpl2 },
 	{"nfm_nokturnfm3", _s("[nFM] NokturnFM3 (OPL3)"), kNfmNokturnFM3, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
-	{"nfm_rwopl3", _s("[nFM] RetroWave USB OPL3 Express (OPL3)"), kNfmRWOpl3Express, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
 	{"nfm_opl2lpt", _s("[nFM] Serdaco OPL2LPT (OPL2)"), kNfmOPL2LPT, kFlagOpl2 },
 	{"nfm_opl3lpt", _s("[nFM] Serdaco OPL3LPT (OPL3)"), kNfmOPL3LPT, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
 	{"nfm_ce_opl2ab", _s("[nFM] Cheerful Electronics OPL2 Audio Board (OPL2)"), kNfmCeOPL2AudioBoard, kFlagOpl2 },
 	{"nfm_ce_opl3duo", _s("[nFM] Cheerful Electronics OPL3 Duo! (2xOPL3)"), kNfmCeOPL3Duo, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
 	{"nfm_ce_stbus_isa_vme", _s("[nFM] ST Bus ISA / VME SoundBlaster"), kNfmStBusIsaVmeSb, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
 	{"nfm_natfeats_null", _s("[nFM] NatFeats / NULL"), kNfmNatfeatsNull, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
-	{"nfm_nuked_opl3", _s("[nFM] Nuked-OPL3 softsynth (OPL3)"), kNfmNukedOpl3, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3},
 #endif
 	{ nullptr, nullptr, 0, 0 }
 };
@@ -297,9 +281,6 @@ OPL *Config::create(DriverId driver, OplType type) {
 	case kNfmNokturnFM3:
 		return NfmOPL::RealChip::create(type, NfmOPL::dtNokturnFM3);
 
-	case kNfmRWOpl3Express:
-		return NfmOPL::RealChip::create(type, NfmOPL::dtRWOpl3Express);
-
 	case kNfmOPL2LPT: {
 		if (type == kOpl2) {
 			return NfmOPL::RealChip::create(type, NfmOPL::dtOPL2LPT);
@@ -326,8 +307,6 @@ OPL *Config::create(DriverId driver, OplType type) {
 		return NfmOPL::RealChip::create(type, NfmOPL::dtStBusIsaVmeSb);
 	case kNfmNatfeatsNull:
 		return NfmOPL::RealChip::create(type, NfmOPL::dtNatfeatsOpl);
-	case kNfmNukedOpl3:
-		return NfmOPL::EmulatedChip::create(type, NfmOPL::dtNukedOpl3);
 #endif
 
 	case kNull:
diff --git a/audio/nfmopl.cpp b/audio/nfmopl.cpp
index 897a474dda1..6c261a463c4 100644
--- a/audio/nfmopl.cpp
+++ b/audio/nfmopl.cpp
@@ -21,7 +21,7 @@
 
 /*
     OPL interface using nFM library(https://framagit.org/nokturnal/nfm)
-    for NokturnFM2 / 3, OPL-L carts, CE OPL2 Audio board, CE OPL3 Duo!, Serdaco OPL2LPT / OPL3LPT, RetroWave OPL3 Express and more ...
+    for NokturnFM2 / 3, CE OPL2 Audio board, CE OPL3 Duo!, Serdaco OPL2LPT / OPL3LPT, ST Bus ISA / VME SoundBlaster and NatFeats
     (c) 2023-26 Paweł Góralski
  */
 
@@ -32,108 +32,87 @@
 #include "audio/fmopl.h"
 #include "audio/nfmopl.h"
 
-#include <nfmoplshadowregs.h>
+extern "C"
+{
+#include <nfmcore.h>
+#include <nfmutil.h>
+}
 
-#ifndef RELEASE_BUILD
-	#include "common/debug.h"
-	#define NFM_ENABLE_LOGS 1
-#endif
+#include <mint/osbind.h>
 
 #define NFM_ENABLE_BUFFERED_OUTPUT false
-#define NFM_ENABLE_CUSTOM_ALLOC 1
-
-// TODO set for Linux / Win
-//static const char gsOpl3ExpressPortName[] = "";
-
-#if NFM_ENABLE_CUSTOM_ALLOC
-	// custom allocators
-	#include "backends/platform/atari/dlmalloc.h"
-	#define NFM_MSPACE_SIZE 1*1024
-#endif
 
 namespace OPL {
 namespace NfmOPL {
 
-#if NFM_ENABLE_CUSTOM_ALLOC
-
-extern "C"
-{
-	static mspace s_mNfmSpace = nullptr;
-	static sNfUserMemoryCallbacks s_MemCallbacks;
-	static void *s_nfmMemoryBase = nullptr;
-
-	static void *nfmAlloc(size_t amount, const eNfMemoryFlag flag, void* userData, const char* functionName, char* fileName, uint32_t lineNo) {
-#if NFM_ENABLE_LOGS
-		debug("nfmAlloc()");
-#endif
-		return mspace_malloc(s_mNfmSpace, amount);
-	}
-
-	static void *nfmAlignedAlloc(size_t alignment, size_t amount, const eNfMemoryFlag flag, void* userData, const char* functionName, char* fileName, uint32_t lineNo) {
-#if NFM_ENABLE_LOGS
-		debug("nfmAlignedAlloc()");
-#endif
-		return mspace_memalign(s_mNfmSpace, alignment, amount);
-	}
+namespace RealChip {
 
-	static void *nfmRealloc(void* pOriginal, size_t size, void* userData) {
-#if NFM_ENABLE_LOGS
-		debug("nfmRealloc()");
-#endif
-		return mspace_realloc(s_mNfmSpace, pOriginal, size);
-	}
+class OPL : public ::OPL::OPL, public Audio::RealChip {
+private:
+	Config::OplType _type;
+	OplDevice _deviceType;
+	sFmInterface _iface;
+	funcPtrOplWrite _oplWrite;
+	funcPtrOplWrite _oplEnqueWrite;
+	funcPtrOplFlush _oplFlush;
+	funcPtrOplReset _oplReset;
+
+	sInterfaceInitData _params;
+	sOplInterfaceConfiguration _ifaceCfg;
+
+	int _activeReg;
+	bool _initialized;
+	bool _useBuffer;
+	bool _incapableDevice;
+	bool _needsSupervisor;	// driver accesses I/O registers directly
+	bool _inSupervisor;		// set while a SupervisorScope holds supervisor mode
+public:
+	explicit OPL(Config::OplType type, enum NfmOPL::OplDevice deviceType);
+	~OPL();
+
+	bool init() override final;
+	void reset() override final;
+
+	void write(int portAddress, int value) override final;
+	void writeReg(int reg, int value) override final;
+
+protected:
+
+	void onTimer() override final;
+};
 
-	static void nfmFree(void* ptr, void* userData) {
-#if NFM_ENABLE_LOGS
-		debug("nfmFree()");
-#endif
-		mspace_free(s_mNfmSpace, ptr);
+// Drivers which access I/O registers directly (e.g. the parallel port through
+// the YM2149 at $FFFF8800) cause a bus error in user mode, which is where all
+// ScummVM threads run. The cartridge port and NatFeats are accessible from user
+// mode. ISA access goes through an _ISA cookie driver or machine specific
+// addresses whose requirements are not known, so it uses supervisor mode as a
+// precaution. Nested scopes are cheap: only the outermost one enters
+// supervisor mode.
+class SupervisorScope {
+public:
+	SupervisorScope(bool needed, bool &active) : _active(active), _oldSsp(nullptr) {
+		if (needed && !_active && Super(SUP_INQUIRE) == 0) {
+			_oldSsp = (void *)Super(SUP_SET);
+			_active = true;
+		}
 	}
 
-	static void nfmOutOfMemoryCb(void* userData) {
-#if NFM_ENABLE_LOGS
-		debug("nfmOutOfMemoryCb() out of memory!");
-#endif
+	~SupervisorScope() {
+		if (_oldSsp) {
+			_active = false;
+			SuperToUser(_oldSsp);
+		}
 	}
 
-}
-#endif
-
-#if NFM_ENABLE_LOGS
-static const char *s_DebugConfigMsgStrs[NfmOPL::dtNumDevices] = {
-	"Configuring NokturnFM2 cartridge",
-	"Configuring NokturnFM3 cartridge",
-	"Configuring RetroWave OPL3 Express",
-	"Configuring Serdaco OPL2LPT",
-	"Configuring Serdaco OPL3LPT",
-	"Configuring CE OPL2 Audio Board",
-	"Configuring CE OPL3 Duo!",
-	"Configuring ST Bus ISA / VME SoundBlaster",
-	"Configuring NatFeats / NULL",
-	"Configuring Nuked-OPL3",
+private:
+	bool &_active;
+	void *_oldSsp;
 };
 
-static const char *s_DebugOplWriteStrs[NfmOPL::dtNumDevices] = {
-	"NfmOPL NokturnFM2 writeReg",
-	"NfmOPL NokturnFM3 writeReg",
-	"NfmOPL OPL3 Express writeReg",
-	"NfmOPL OPL2LPT writeReg",
-	"NfmOPL OPL3LPT writeReg",
-	"NfmOPL OPL2AudioBoard writeReg",
-	"NfmOPL OPL3Duo writeReg",
-	"NfmOPL ST Bus ISA / VME SoundBlaster writeReg",
-	"NfmOPL NatFeats / NULL writeReg",
-	"NfmOPL Nuked-OPL3 writeReg",
-};
-#endif
-namespace RealChip {
 // hardware opl
-OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _deviceType(deviceType), _activeReg(0), _initialized(false), _useBuffer(NFM_ENABLE_BUFFERED_OUTPUT), _incapableDevice(false) {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip create");
-#endif
-
+OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _deviceType(deviceType), _activeReg(0), _initialized(false), _useBuffer(NFM_ENABLE_BUFFERED_OUTPUT), _incapableDevice(false), _needsSupervisor(false), _inSupervisor(false) {
 	// defaults
+	memset(&_params, 0, sizeof(_params));
 	_ifaceCfg.deviceType = eFmDriverType::FMD_UNDEFINED;
 	_ifaceCfg.soundchip = CM_UNDEFINED;
 	_ifaceCfg.operationMode = CO_UNDEFINED;
@@ -155,12 +134,6 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 
 	_ifaceCfg.setup = CC_SINGLE;
 
-#if NFM_ENABLE_LOGS
-	if (deviceType < dtNumDevices) {
-		debug(s_DebugConfigMsgStrs[deviceType]);
-	}
-#endif
-
 	switch (deviceType) {
 	case dtNokturnFM2: {
 		_params.uParam.outputPort = OPT_ST_CART;
@@ -180,17 +153,9 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 		_ifaceCfg.setup = CC_SINGLE;
 	}
 	break;
-	case dtRWOpl3Express: {
-		_useBuffer = true;                                          // use buffered output, sending data has significant overhead
-		_params.uOpl3ExpressSettings.outputPort = OPT_USB;
-		_ifaceCfg.deviceType = eFmDriverType::FMD_OPL3EXPRESS;
-		_ifaceCfg.soundchip = CM_OPL3;
-		_ifaceCfg.setup = CC_SINGLE;
-		// TODO set serial port on Win / Linux requested by user
-	}
-	break;
 	case dtOPL2LPT: {
 		_params.uParam.outputPort = OPT_LPT;
+		_needsSupervisor = true;
 
 		_ifaceCfg.deviceType = eFmDriverType::FMD_OPL2LPT;
 		_ifaceCfg.soundchip = CM_OPL2;
@@ -204,6 +169,7 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 	case dtOPL3LPT: {
 		// OPL2 mode is forced internally on anything below TT due to lack of signals
 		_params.uParam.outputPort = OPT_LPT;
+		_needsSupervisor = true;
 
 		_ifaceCfg.deviceType = eFmDriverType::FMD_OPL3LPT;
 		_ifaceCfg.soundchip = CM_OPL3;
@@ -212,6 +178,7 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 	break;
 	case dtOPL2AudioBoard: {
 		_params.uParam.outputPort = OPT_LPT_SPI;
+		_needsSupervisor = true;
 		_params.uCeAudioBoardSettings.isOpl2AudioBoard = true;
 		_ifaceCfg.deviceType = eFmDriverType::FMD_CE_OPL2AUDIO_LPT_SPI;
 		_ifaceCfg.soundchip = CM_OPL2;
@@ -224,6 +191,7 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 	break;
 	case dtOPL3Duo: {
 		_params.uParam.outputPort = OPT_LPT_SPI;
+		_needsSupervisor = true;
 		_params.uCeAudioBoardSettings.isOpl2AudioBoard = false;
 		_ifaceCfg.deviceType = eFmDriverType::FMD_CE_OPL3DUO_LPT_SPI;
 		_ifaceCfg.soundchip = CM_OPL3;
@@ -233,11 +201,11 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 	case dtStBusIsaVmeSb: {
 		// TODO: handle additional VME / ISA parameters if needed
 		_params.uParam.outputPort = OPT_ISA;
+		_needsSupervisor = true;	// precaution, see SupervisorScope
 		_params.uParam.param = 0;
 
 		_ifaceCfg.deviceType = eFmDriverType::FMD_ISA_SB;
 		_ifaceCfg.soundchip = CM_OPL3;
-		_ifaceCfg.operationMode = CO_OPL2,
 		_ifaceCfg.setup = CC_SINGLE;
 	}
 	break;
@@ -256,15 +224,14 @@ OPL::OPL(Config::OplType type, NfmOPL::OplDevice deviceType) : _type(type), _dev
 }
 
 OPL::~OPL() {
+	// stop the timer callbacks before the interface goes away
+	stop();
+
 	if (_initialized == true) {
-#if NFM_ENABLE_LOGS
-		debug("NfmOPL destroy");
-#endif
+		SupervisorScope supervisor(_needsSupervisor, _inSupervisor);
+
 		if (_useBuffer) {
 			// flush
-#if NFM_ENABLE_LOGS
-			debug("OPL flush");
-#endif
 			_oplFlush();
 		}
 
@@ -279,62 +246,20 @@ OPL::~OPL() {
 		_incapableDevice = false;
 		_useBuffer = false;
 		_initialized = false;
-#if NFM_ENABLE_CUSTOM_ALLOC
-		if (s_mNfmSpace) {
-			destroy_mspace(s_mNfmSpace);
-			Mfree(s_nfmMemoryBase);
-			s_nfmMemoryBase = nullptr;
-		}
-#endif
 	}
 }
 
 bool OPL::init() {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip init");
-#endif
 	if (_incapableDevice) {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip OPL2 device cannot emulate requested dual OPL2 / OPL3!");
-#endif
 		return false;
 	}
 
-#if NFM_ENABLE_CUSTOM_ALLOC
-
-	s_nfmMemoryBase = (void *)Mxalloc((int32_t)NFM_MSPACE_SIZE + 256, (int16_t)3);
-
-	if (s_nfmMemoryBase) {
-		s_mNfmSpace = create_mspace_with_base(s_nfmMemoryBase, NFM_MSPACE_SIZE, 0);
-
-		if (s_mNfmSpace == 0) {
-#if NFM_ENABLE_LOGS
-			debug("NfmOPL::RealChip create_mspace failed!");
-#endif
-			return false;
-		}
-
-		// install user memory allocator callbacks
-		s_MemCallbacks.alloc = nfmAlloc;
-		s_MemCallbacks.alignedAlloc = nfmAlignedAlloc;
-		s_MemCallbacks.release = nfmFree;
-		s_MemCallbacks.realloc = nfmRealloc;
-		s_MemCallbacks.outOfMemory = nfmOutOfMemoryCb;
-
-		nfInit(&s_MemCallbacks, NULL);
-
-	} else {
-#if NFM_ENABLE_LOGS
-		debug("NfmOPL::RealChip Out of system memory!");
-#endif
-		return false;
-	}
-#else
-	nfInit(NULL,NULL);
-#endif
+	nfInit(NULL, NULL);
 	_iface = nfCreateInterface(_ifaceCfg);
 
 	if (_iface.setup != CC_UNDEFINED) {
+		SupervisorScope supervisor(_needsSupervisor, _inSupervisor);
+
 		const int32_t retval = nfInitialiseInterface(&_iface, &_params);
 
 		if (retval >= 0) {
@@ -346,23 +271,20 @@ bool OPL::init() {
 			initDualOpl2OnOpl3(_type);
 			_initialized = true;
 
-#if NFM_ENABLE_LOGS
-			debug("NfmOPL::RealChip init OK");
-#endif
 			return true;
 		}
+
+		(void)nfDestroyInterface(&_iface);
 	}
 
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip init failed!");
-#endif
+	(void)nfDeinit();
+
 	return false;
 }
 
 void OPL::reset() {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip reset");
-#endif
+	SupervisorScope supervisor(_needsSupervisor, _inSupervisor);
+
 	for (int16_t i = 0; i < 256; i ++) {
 		writeReg((int)i, 0);
 	}
@@ -397,10 +319,6 @@ void OPL::write(int portAddress, int value) {
 }
 
 void OPL::writeReg(int reg, int value) {
-#if NFM_ENABLE_LOGS
-	debug(s_DebugOplWriteStrs[_deviceType]);
-#endif
-
 	if (_type == Config::kOpl3 || _type == Config::kDualOpl2) {
 		reg &= 0x1ff;
 	} else {
@@ -410,6 +328,7 @@ void OPL::writeReg(int reg, int value) {
 	value &= 0xff;
 
 	if (emulateDualOpl2OnOpl3(reg, value, _type)) {
+		SupervisorScope supervisor(_needsSupervisor, _inSupervisor);
 		sOplRegisterWrite regWrite;
 
 		if (reg < 0x100) {
@@ -429,10 +348,7 @@ void OPL::writeReg(int reg, int value) {
 void OPL::onTimer() {
 	if (_useBuffer) {
 		if (_initialized) {
-#if NFM_ENABLE_LOGS
-			// flush
-			debug("NfmOPL::RealChip flush");
-#endif
+			SupervisorScope supervisor(_needsSupervisor, _inSupervisor);
 			_oplFlush();
 		}
 	}
@@ -440,256 +356,10 @@ void OPL::onTimer() {
 	Audio::RealChip::onTimer();
 }
 
-OPL *create(Config::OplType type, OplDevice device) {
+::OPL::OPL *create(Config::OplType type, OplDevice device) {
 	return new OPL(type, device);
 }
 } // End of namespace RealChip
 
-namespace EmulatedChip {
-OPL::OPL(Config::OplType type, enum NfmOPL::OplDevice deviceType): _type(type), _rate(0), _deviceType(deviceType), _activeReg(0), _initialized(false), _useBuffer(NFM_ENABLE_BUFFERED_OUTPUT), _incapableDevice(false) {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::EmulatedChip create");
-#endif
-	
-	// defaults
-	_ifaceCfg.deviceType = eFmDriverType::FMD_UNDEFINED;
-	_ifaceCfg.soundchip = CM_UNDEFINED;
-	_ifaceCfg.operationMode = CO_UNDEFINED;
-	_ifaceCfg.setup = CC_UNDEFINED;
-	_ifaceCfg.dualChipEmulationEnabled = false;
-
-	_oplWrite = nullptr;
-	_oplEnqueWrite = nullptr;
-	_oplFlush = nullptr;
-	_oplReset = nullptr;
-	_generateAudioStream = nullptr;
-
-	if (_type == Config::kOpl2) {
-		_ifaceCfg.operationMode = CO_OPL2;
-	}
-
-	if (_type == Config::kOpl3 || _type == Config::kDualOpl2) {
-		_ifaceCfg.operationMode = CO_OPL3;
-	}
-
-	_ifaceCfg.setup = CC_SINGLE;
-
-#if NFM_ENABLE_LOGS
-	if (deviceType < dtNumDevices) {
-		debug(s_DebugConfigMsgStrs[deviceType]);
-	}
-#endif
-	switch (deviceType) {
-	case dtNukedOpl3: {
-		_rate = g_system->getMixer()->getOutputRate();
-		_params.uSoftSynthSettings.outputPort = OPT_INTERNAL;
-		_params.uSoftSynthSettings.sampleRate = _rate;
-		_params.uSoftSynthSettings.enableDualChipEmulation = _ifaceCfg.dualChipEmulationEnabled;
-
-		_ifaceCfg.deviceType = FMD_NUKEDOPL3;
-		_ifaceCfg.soundchip = CM_OPL3;
-		_ifaceCfg.operationMode = CO_OPL3;
-		_ifaceCfg.setup = CC_SINGLE;
-	}
-	break;
-
-	default: {
-		warning("NfmOPL::EmulatedChip Unrecognized device type or not software synthesizer!");
-		_incapableDevice = true;
-	}
-	break;
-	};
-}
-
-OPL::~OPL() {
-
-	if (_initialized == true) {
-#if NFM_ENABLE_LOGS
-		debug("NfmOPL::EmulatedChip destroy");
-#endif
-		stop();
-
-		if (_useBuffer) {
-#if NFM_ENABLE_LOGS
-			// flush
-			debug("NfmOPL::EmulatedChip OPL flush");
-#endif
-			_oplFlush();
-		}
-
-		_oplWrite = nullptr;
-		_oplEnqueWrite = nullptr;
-		_oplFlush = nullptr;
-		_oplReset = nullptr;
-		_generateAudioStream = nullptr;
-
-		(void)nfDestroyInterface(&_iface);
-		(void)nfDeinit();
-		_incapableDevice = false;
-		_useBuffer = false;
-		_initialized = false;
-
-#if NFM_ENABLE_CUSTOM_ALLOC
-		if (s_mNfmSpace) {
-			destroy_mspace(s_mNfmSpace);
-			Mfree(s_nfmMemoryBase);
-			s_nfmMemoryBase = nullptr;
-		}
-#endif
-	}
-}
-
-bool OPL::init() {
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::EmulatedChip init");
-#endif
-	if (_incapableDevice) {
-#if NFM_ENABLE_LOGS
-		debug("NfmOPL::EmulatedChip device isn't soft synth type!");
-#endif
-		return false;
-	}
-
-#if NFM_ENABLE_CUSTOM_ALLOC
-
-	s_nfmMemoryBase = (void *)Mxalloc((int32_t)NFM_MSPACE_SIZE + 256, (int16_t)3);
-
-	if (s_nfmMemoryBase) {
-		s_mNfmSpace = create_mspace_with_base(s_nfmMemoryBase, NFM_MSPACE_SIZE, 0);
-
-		if (s_mNfmSpace == 0) {
-#if NFM_ENABLE_LOGS
-			debug("NfmOPL::EmulatedChip create_mspace failed!");
-#endif
-			return false;
-		}
-
-		// install custom memory allocator callbacks
-		s_MemCallbacks.alloc = nfmAlloc;
-		s_MemCallbacks.alignedAlloc = nfmAlignedAlloc;
-		s_MemCallbacks.release = nfmFree;
-		s_MemCallbacks.realloc = nfmRealloc;
-		s_MemCallbacks.outOfMemory = nfmOutOfMemoryCb;
-
-		nfInit(&s_MemCallbacks,NULL);
-
-	} else {
-#if NFM_ENABLE_LOGS
-		debug("NfmOPL::EmulatedChip Out of system memory!");
-#endif
-		return false;
-	}
-#else
-	nfInit(NULL,NULL);
-#endif
-	_iface = nfCreateInterface(_ifaceCfg);
-
-	if (_iface.setup != CC_UNDEFINED) {
-		const int32_t retval = nfInitialiseInterface(&_iface, &_params);
-
-		if (retval >= 0) {
-			_oplWrite = _iface.write;
-			_oplEnqueWrite = _iface.enqueWrite;
-			_oplFlush = _iface.flush;
-			_oplReset = _iface.reset;
-			_generateAudioStream = _iface.generateAudioStream;
-
-			_activeReg = 0;
-
-			initDualOpl2OnOpl3(_type);
-
-			_initialized = true;
-
-#if NFM_ENABLE_LOGS
-			debug("NfmOPL::RealChip init OK");
-#endif
-			return true;
-		}
-	}
-
-#if NFM_ENABLE_LOGS
-	debug("NfmOPL::RealChip init failed!");
-#endif
-	return false;
-}
-
-void OPL::reset() {
-
-	_oplReset();
-
-	for (int16_t i = 0; i < 256; i ++) {
-		writeReg((int)i, 0);
-	}
-
-	if (_type == Config::kOpl3 || _type == Config::kDualOpl2) {
-		for (int16_t i = 0; i < 256; i++) {
-			writeReg((int)i + 256, 0);
-		}
-	}
-
-	_activeReg = 0;
-
-	initDualOpl2OnOpl3(_type);
-}
-
-void OPL::write(int portAddress, int value) {
-	if (portAddress & 1) {
-		writeReg(_activeReg, value);
-		return;
-	} else {
-		if (_type == Config::kOpl2) {
-			_activeReg = value & 0xff;
-			return;
-		} else {
-			// opl3 / dual opl2
-			_activeReg = (value & 0xff) | ((portAddress << 7) & 0x100);
-			return;
-		}
-
-		warning("NfmOPL::EmulatedChip: unsupported OPL mode %d", _type);
-	}
-}
-
-void OPL::writeReg(int reg, int value) {
-#if NFM_ENABLE_LOGS
-	debug(s_DebugOplWriteStrs[_deviceType]);
-#endif
-
-	if (_type == Config::kOpl3 || _type == Config::kDualOpl2) {
-		reg &= 0x1ff;
-	} else {
-		reg &= 0xff;
-	}
-
-	value &= 0xff;
-
-	if (emulateDualOpl2OnOpl3(reg, value, _type)) {
-		sOplRegisterWrite regWrite;
-
-		if (reg < 0x100) {
-			regWrite = {0, (uint8_t)reg, (uint8_t)value};
-		} else {
-			regWrite = {1, (uint8_t)(reg - 0x100), (uint8_t)value};
-		}
-
-		if (_useBuffer) {
-			_oplEnqueWrite(&regWrite);
-		} else {
-			_oplWrite(&regWrite);
-		}
-	}
-}
-
-void OPL::generateSamples(int16 *buffer, int length) {
-	assert(buffer != nullptr);
-	assert(length!=0);
-	_generateAudioStream(buffer, 0, (uint16_t)length / 2);
-}
-
-OPL *create(Config::OplType type, OplDevice device) {
-	return new OPL(type, device);
-}
-} // End of namespace EmulatedChip
-
 } // End of namespace NfmOPL
 } // End of namespace OPL
diff --git a/audio/nfmopl.h b/audio/nfmopl.h
index f629d17b6df..9e72d13b953 100644
--- a/audio/nfmopl.h
+++ b/audio/nfmopl.h
@@ -21,7 +21,7 @@
 
 /*
     OPL interface using nFM library(https://framagit.org/nokturnal/nfm)
-    for NokturnFM2 / 3, OPL-L carts, CE OPL2 Audio board, CE OPL3 Duo!, Serdaco OPL2LPT / OPL3LPT, RetroWave OPL3 Express and more ...
+    for NokturnFM2 / 3, CE OPL2 Audio board, CE OPL3 Duo!, Serdaco OPL2LPT / OPL3LPT, ST Bus ISA / VME SoundBlaster and NatFeats
     (c) 2023-26 Paweł Góralski
  */
 
@@ -30,103 +30,23 @@
 
 #include "audio/fmopl.h"
 
-#ifndef restrict
-	#define restrict __restrict__
-#endif
-
-extern "C"
-{
-#include <nfmcore.h>
-#include <nfmutil.h>
-}
-
 namespace OPL {
 namespace NfmOPL {
 enum OplDevice : int16_t {
 	dtNokturnFM2 = 0,
 	dtNokturnFM3,
-	dtRWOpl3Express,
 	dtOPL2LPT,
 	dtOPL3LPT,
 	dtOPL2AudioBoard,
 	dtOPL3Duo,
 	dtStBusIsaVmeSb,
 	dtNatfeatsOpl,
-	dtNukedOpl3,
 	dtNumDevices
 };
 
 namespace RealChip {
-class OPL : public ::OPL::OPL, public Audio::RealChip {
-private:
-	Config::OplType _type;
-	OplDevice _deviceType;
-	sFmInterface _iface;
-	funcPtrOplWrite _oplWrite;
-	funcPtrOplWrite _oplEnqueWrite;
-	funcPtrOplFlush _oplFlush;
-	funcPtrOplReset _oplReset;
-
-	sInterfaceInitData _params;
-	sOplInterfaceConfiguration _ifaceCfg;
-
-	int _activeReg;
-	bool _initialized;
-	bool _useBuffer;
-	bool _incapableDevice;
-public:
-	explicit OPL(Config::OplType type, enum NfmOPL::OplDevice deviceType);
-	~OPL();
-
-	bool init() override final;
-	void reset() override final;
-
-	void write(int portAddress, int value) override final;
-	void writeReg(int reg, int value) override final;
-
-protected:
-
-	void onTimer() override final;
-};
-};  // End of namespace RealChip
-
-namespace EmulatedChip {
-class OPL : public ::OPL::OPL, public Audio::EmulatedChip {
-private:
-	Config::OplType _type;
-	OplDevice _deviceType;
-	sFmInterface _iface;
-	funcPtrOplWrite _oplWrite;
-	funcPtrOplWrite _oplEnqueWrite;
-	funcPtrOplFlush _oplFlush;
-	funcPtrOplReset _oplReset;
-	funcGenerateAudioStream _generateAudioStream;
-	sInterfaceInitData _params;
-	sOplInterfaceConfiguration _ifaceCfg;
-
-	int _activeReg;
-	uint _rate;
-	bool _initialized;
-	bool _useBuffer;
-	bool _incapableDevice;
-public:
-	explicit OPL(Config::OplType type, enum NfmOPL::OplDevice deviceType);
-	~OPL();
-
-	bool isStereo() const override {
-		return true;
-	}
-
-	bool init() override final;
-	void reset() override final;
-
-	void write(int portAddress, int value) override final;
-	void writeReg(int reg, int value) override final;
-
-protected:
-	void generateSamples(int16 *buffer, int numSamples) override final;
-};
-}; // End of namespace EmulatedChip
+OPL *create(Config::OplType type, OplDevice device);
+} // End of namespace RealChip
 
 } // End of namespace NfmOPL
 } // End of namespace OPL
diff --git a/backends/platform/atari/build-firebee.sh b/backends/platform/atari/build-firebee.sh
index 48aee04c5ac..e175f5476a5 100755
--- a/backends/platform/atari/build-firebee.sh
+++ b/backends/platform/atari/build-firebee.sh
@@ -40,7 +40,6 @@ then
 	--with-freetype2-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
 	--with-mikmod-prefix="$(${PLATFORM}-gcc -print-sysroot)/usr/bin/${CPU_DIR}" \
 	--enable-release \
-	--disable-nfm \
 	--enable-verbose-build \
 	${PLUGINS_FLAGS}
 fi
diff --git a/backends/platform/atari/get-nfm.sh b/backends/platform/atari/get-nfm.sh
deleted file mode 100644
index 0b2a569b390..00000000000
--- a/backends/platform/atari/get-nfm.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash -eux
-# -e: Exit immediately if a command exits with a non-zero status.
-# -u: Treat unset variables as an error when substituting.
-# -x: Display expanded script commands
-
-# downloads and unpacks in ./deps folder precompiled nFM library release for m68k Atari TOS / mintelf gcc stdlib
-NFM_VERSION=0.4.0
-COMMIT_SHORT_SHA=3f970a17
-
-curl -o ./backends/platform/atari/nfm.zip https://nokturnal.pl/downloads/atari/nokturnfm/nfmplay/builds/releases/${NFM_VERSION}/ataritos-mintelf-gcc-stdlib-m68k-${NFM_VERSION}-${COMMIT_SHORT_SHA}.zip
-rm -rf ./backends/platform/atari/deps/nfm
-
-unzip ./backends/platform/atari/nfm.zip "nFM_${NFM_VERSION}/*" -d ./backends/platform/atari/deps/
-mv ./backends/platform/atari/deps/nFM_${NFM_VERSION} ./backends/platform/atari/deps/nfm
-rm ./backends/platform/atari/nfm.zip
\ No newline at end of file
diff --git a/configure b/configure
index 7c3a5f2cee6..ff45575dde9 100755
--- a/configure
+++ b/configure
@@ -1516,8 +1516,8 @@ for ac_option in $@; do
 		;;
 	--with-nfm-prefix=*)
 		arg=`echo $ac_option | cut -d '=' -f 2`
-		NFM_CFLAGS="-I$arg/include -I$arg/include/platform/atari"
-		NFM_LIBS="-L$arg/lib/m68020-60"
+		NFM_CFLAGS="-I$arg/include/nfm"
+		NFM_LIBS="-L$arg/lib"
 		;;
 	--with-flac-prefix=*)
 		arg=`echo $ac_option | cut -d '=' -f 2`
@@ -5640,49 +5640,53 @@ echo "$_retrowave"
 # Check for nFM OPL2/3 library
 #
 echocheck "nFM OPL2 / OPL3"
+case $_host_os in
+mint*)
+	if test -z "$NFM_CFLAGS" ; then
+		NFM_CFLAGS="-I`$CXX --print-sysroot`/usr/include/nfm"
+	fi
+	;;
+*)
+	# only the Atari hardware drivers are supported
+	if test "$_nfm" = yes ; then
+		echo "nFM is supported on Atari only"
+		exit 1
+	fi
+	_nfm=no
+	;;
+esac
+# nfmcore references every driver it was built with, so all of them have to be
+# linked
+NFM_LIBS="$NFM_LIBS -lnfmcore -lnfmutil -ldrvcommon -ldrvnokturnfm -ldrvopl3duo -ldrvopl3express -ldrvoplxlpt -ldrvopllcart -ldrvisasb -ldrvoplnull -lsyscore -lcontainers -lallocators"
 if test "$_nfm" = auto ; then
 	_nfm=no
 	cat > $TMPC << EOF
-
 #include <nfmcore.h>
 #include <nfmutil.h>
 
-sFmInterface gOplIf;
+int main(void) {
+	sOplInterfaceConfiguration ifCfg = {};
+	sInterfaceInitData params = {};
 
-int main(void)
-{
 	nfInit(NULL, NULL);
 
-	sOplInterfaceConfiguration ifCfg;
 	ifCfg.deviceType = FMD_NULL;
-    ifCfg.soundchip = CM_OPL3;
-    ifCfg.operationMode = CO_OPL3;
-    ifCfg.setup = CC_SINGLE;
-    ifCfg.dualChipEmulationEnabled = false;
-
-    sInterfaceInitData params;
+	ifCfg.soundchip = CM_OPL3;
+	ifCfg.operationMode = CO_OPL3;
+	ifCfg.setup = CC_SINGLE;
 	params.uParam.outputPort = OPT_INTERNAL;
-    params.uParam.param = 0;
-
-    gOplIf = nfCreateInterface(ifCfg);
-
-    const int32_t retval = nfInitialiseInterface(&gOplIf, &params);
-
-    if (retval >= 0)
-    {
-	 (void)nfDestroyInterface(&gOplIf);
-     return 0;
-    }
 
-  return -1;
+	sFmInterface iface = nfCreateInterface(ifCfg);
+	(void)nfInitialiseInterface(&iface, &params);
+	(void)nfDestroyInterface(&iface);
+	return nfDeinit();
 }
 EOF
-	cc_check $NFM_CFLAGS -DSC_ENABLE_MALLOC=0 -DNFM_OPL_SHADOW_REG_WRITE_ENABLE=1 $NFM_LIBS -lnfmcore -lnfmutil -ldrvcommon -ldrvnokturnfm -ldrvopl3Duo -ldrvopl3express -ldrvoplxlpt -ldrvopllcart -ldrvisasb -ldrvoplnull -lsyscore -lcontainers -lallocators &&\
-	_nfm=yes
+	cc_check $NFM_CFLAGS -DSC_ENABLE_MALLOC=0 -DNFM_OPL_SHADOW_REG_WRITE_ENABLE=1 $NFM_LIBS && _nfm=yes
 fi
 if test "$_nfm" = yes; then
 	append_var DEFINES "-DSC_ENABLE_MALLOC=0 -DNFM_OPL_SHADOW_REG_WRITE_ENABLE=1"
-	append_var LIBS "$NFM_LIBS -lnfmcore -lnfmutil -ldrvcommon -ldrvnokturnfm -ldrvopl3Duo -ldrvopl3express -ldrvoplxlpt -ldrvopllcart -ldrvisasb -ldrvoplnull -lsyscore -lcontainers -lallocators"
+	append_var LIBS "$NFM_LIBS"
 	append_var INCLUDES "$NFM_CFLAGS"
 fi
 define_in_config_if_yes "$_nfm" 'USE_NFM'


Commit: e98e1bf6354017f676c9383498215563069c479e
    https://github.com/scummvm/scummvm/commit/e98e1bf6354017f676c9383498215563069c479e
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2026-10-05T10:52:10+10:00

Commit Message:
BACKENDS: ATARI: add -mfastcall code paths

It was long overdue.

Changed paths:
    engines/scumm/gfxM68K.S
    engines/scumm/m68k/bylerledecode.inc
    engines/scumm/m68k/bylerledecode_classic.S
    engines/scumm/m68k/bylerledecode_mode0.S
    engines/scumm/m68k/bylerledecode_mode1.S
    engines/scumm/m68k/bylerledecode_mode3.S
    engines/scumm/m68k/bylerledecode_scaled_mode0.S
    engines/scumm/m68k/bylerledecode_scaled_mode0_smask.S
    engines/scumm/m68k/bylerledecode_scaled_mode1.S
    engines/scumm/m68k/bylerledecode_scaled_mode1_smask.S
    engines/scumm/m68k/bylerledecode_scaled_mode3.S


diff --git a/engines/scumm/gfxM68K.S b/engines/scumm/gfxM68K.S
index 43f1e68318a..48a156b1f79 100644
--- a/engines/scumm/gfxM68K.S
+++ b/engines/scumm/gfxM68K.S
@@ -38,8 +38,22 @@
 |     const int textPitch    4+9*4+24(sp)
 | );
 SYM(asmDrawStripToScreen):
-// TODO: __FASTCALL__
 	movem.l	d2-d7/a2-a4,-(sp)		| 9 × 4 = 36 bytes
+#ifdef __FASTCALL__
+						| a0: src32
+						| a1: dst32
+	move.l	(4+9*4,sp),a2			| a2: text32
+
+	lsl.l	#2,d2				| vsPitch
+	move.l	d2,a3				| a3: vsPitch in bytes
+
+	move.l	(4+9*4+4,sp),d2			| textPitch
+	lsl.l	#2,d2				|
+	move.l	d2,a4				| a4: textPitch in bytes
+
+	move.l	d1,d5				| width
+	move.l	d0,d7				| height
+#else
 	move.l	(4+9*4+8,sp),a0			| a0: src32
 	move.l	(4+9*4+12,sp),a1		| a1: dst32
 	move.l	(4+9*4+20,sp),a2		| a2: text32
@@ -53,12 +67,14 @@ SYM(asmDrawStripToScreen):
 	move.l	d0,a4				| a4: textPitch in bytes
 
 	move.l	(4+9*4+4,sp),d5			| width
+	move.l	(4+9*4,sp),d7			| height
+#endif
 	lsr.l	#2,d5				|
 	beq.b	3f
 	subq.l	#1,d5				| d5.w: width/4 - 1 for dbra
 
 	// for (int h = height * m; h > 0; --h) {
-	move.l	(4+9*4,sp),d7
+	tst.l	d7
 	beq.b	3f
 
 	move.w	d5,-(sp)
diff --git a/engines/scumm/m68k/bylerledecode.inc b/engines/scumm/m68k/bylerledecode.inc
index c1dda9bc148..7b56cf68f67 100644
--- a/engines/scumm/m68k/bylerledecode.inc
+++ b/engines/scumm/m68k/bylerledecode.inc
@@ -68,6 +68,27 @@ compData.scaleIndexMask:
 	.set	\name,-sizeof_local_vars
 	.endm
 
+#ifdef __FASTCALL__
+	add_var	arg_pcompData,4		// a0
+	add_var	arg_srcPtr,4		// a1
+	add_var	arg_height,2		// d2
+	add_var	arg_scaleX,1		// d0
+	add_var	arg_scaleY,1		// d1
+
+	.struct 0
+arg_fp:
+	.space	4
+arg_rts:
+	.space	4
+arg_pitch:
+	.space	4	// const int pitch
+arg_numStrips:
+	.space	4	// const int _numStrips
+arg_shadowTable:
+	.space	4	// const byte *_shadowTable
+arg_palette:
+	.space	4	// const uint16 *_palette
+#else
 	.struct 0
 arg_fp:
 	.space	4
@@ -98,3 +119,4 @@ arg_shadowTable:
 	.space	4	// const byte *_shadowTable
 arg_palette:
 	.space	4	// const uint16 *_palette
+#endif
diff --git a/engines/scumm/m68k/bylerledecode_classic.S b/engines/scumm/m68k/bylerledecode_classic.S
index 01dd94dab49..a7886f0d009 100644
--- a/engines/scumm/m68k/bylerledecode_classic.S
+++ b/engines/scumm/m68k/bylerledecode_classic.S
@@ -41,8 +41,12 @@
 |	const byte *_shadowTable,
 |	const uint16 *_palette /* unused */);
 SYM(ByleRLEDecode_Classic):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_mode0.S b/engines/scumm/m68k/bylerledecode_mode0.S
index e808437c2a2..19016514414 100644
--- a/engines/scumm/m68k/bylerledecode_mode0.S
+++ b/engines/scumm/m68k/bylerledecode_mode0.S
@@ -41,8 +41,12 @@
 |	const byte *_shadowTable, /* unused */
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Mode0):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_mode1.S b/engines/scumm/m68k/bylerledecode_mode1.S
index a189ad706c6..cb4b33b550f 100644
--- a/engines/scumm/m68k/bylerledecode_mode1.S
+++ b/engines/scumm/m68k/bylerledecode_mode1.S
@@ -41,8 +41,12 @@
 |	const byte *_shadowTable,
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Mode1):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_mode3.S b/engines/scumm/m68k/bylerledecode_mode3.S
index d6cf1794ad1..c6d724fecaa 100644
--- a/engines/scumm/m68k/bylerledecode_mode3.S
+++ b/engines/scumm/m68k/bylerledecode_mode3.S
@@ -60,8 +60,12 @@ SYM(ByleRLEDecode_Mode3_HE90):
 	move.w	#256,d0
 
 .Lmode3_common:
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 	move.w	d0,(shadow_threshold,a6)
 
diff --git a/engines/scumm/m68k/bylerledecode_scaled_mode0.S b/engines/scumm/m68k/bylerledecode_scaled_mode0.S
index ea086e252ea..4372c9cb08e 100644
--- a/engines/scumm/m68k/bylerledecode_scaled_mode0.S
+++ b/engines/scumm/m68k/bylerledecode_scaled_mode0.S
@@ -43,8 +43,14 @@
 |	const byte *_shadowTable, /* unused */
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Scaled_Mode0):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+	move.b	d0,(arg_scaleX,a6)
+	move.b	d1,(arg_scaleY,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_scaled_mode0_smask.S b/engines/scumm/m68k/bylerledecode_scaled_mode0_smask.S
index 3357f132e84..2b9e0e084b0 100644
--- a/engines/scumm/m68k/bylerledecode_scaled_mode0_smask.S
+++ b/engines/scumm/m68k/bylerledecode_scaled_mode0_smask.S
@@ -43,8 +43,14 @@
 |	const byte *_shadowTable, /* unused */
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Scaled_Mode0_SMask):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+	move.b	d0,(arg_scaleX,a6)
+	move.b	d1,(arg_scaleY,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_scaled_mode1.S b/engines/scumm/m68k/bylerledecode_scaled_mode1.S
index 866c4c47e7d..236ab194e94 100644
--- a/engines/scumm/m68k/bylerledecode_scaled_mode1.S
+++ b/engines/scumm/m68k/bylerledecode_scaled_mode1.S
@@ -44,8 +44,14 @@
 |	const byte *_shadowTable,
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Scaled_Mode1):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+	move.b	d0,(arg_scaleX,a6)
+	move.b	d1,(arg_scaleY,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_scaled_mode1_smask.S b/engines/scumm/m68k/bylerledecode_scaled_mode1_smask.S
index 5db44efbd44..57251d6433b 100644
--- a/engines/scumm/m68k/bylerledecode_scaled_mode1_smask.S
+++ b/engines/scumm/m68k/bylerledecode_scaled_mode1_smask.S
@@ -44,8 +44,14 @@
 |	const byte *_shadowTable,
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Scaled_Mode1_SMask):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+	move.b	d0,(arg_scaleX,a6)
+	move.b	d1,(arg_scaleY,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:
diff --git a/engines/scumm/m68k/bylerledecode_scaled_mode3.S b/engines/scumm/m68k/bylerledecode_scaled_mode3.S
index ad51bff2579..c28be0bc401 100644
--- a/engines/scumm/m68k/bylerledecode_scaled_mode3.S
+++ b/engines/scumm/m68k/bylerledecode_scaled_mode3.S
@@ -44,8 +44,14 @@
 |	const byte *_shadowTable,
 |	const uint16 *_palette);
 SYM(ByleRLEDecode_Scaled_Mode3):
-// TODO: __FASTCALL__
 	link	a6,#-sizeof_local_vars		| a6: frame pointer
+#ifdef __FASTCALL__
+	move.l	a0,(arg_pcompData,a6)
+	move.l	a1,(arg_srcPtr,a6)
+	move.w	d2,(arg_height,a6)
+	move.b	d0,(arg_scaleX,a6)
+	move.b	d1,(arg_scaleY,a6)
+#endif
 	movem.l	d2-d7/a2-a5,-(sp)
 
 	// registers taken so far:




More information about the Scummvm-git-logs mailing list