diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 35e093e73..d00b88824 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,6 +11,11 @@ include( FindPkgConfig )
 option( NO_ASM "Disable assembly code" )
 if( CMAKE_COMPILER_IS_GNUCXX )
 	option( NO_STRIP "Do not strip Release or MinSizeRel builds" )
+	# At least some versions of Xcode fail if you strip with the linker
+	# instead of the separate strip utility.
+	if( APPLE )
+		set( NO_STRIP ON )
+	endif( APPLE )
 endif( CMAKE_COMPILER_IS_GNUCXX )
 
 if( CMAKE_SIZEOF_VOID_P MATCHES "8" )
@@ -232,13 +237,6 @@ endif( FMOD_LIBRARY )
 
 # Search for NASM
 
-if( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc)
-	if( NOT NO_ASM )
-		message( STATUS "Disabling assembly code for PowerPC." )
-		set( NO_ASM ON )
-	endif( NOT NO_ASM )
-endif( CMAKE_SYSTEM_PROCESSOR MATCHES powerpc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc )
-
 if( NOT NO_ASM )
 	if( UNIX AND X64 )
 		find_program( GAS_PATH as )
@@ -297,7 +295,12 @@ if( NOT NO_ASM )
 			set( ASM_FLAGS )
 			set( ASM_SOURCE_EXTENSION .s )
 		else( X64 )
-			set( ASM_FLAGS -f elf -DM_TARGET_LINUX -i${CMAKE_CURRENT_SOURCE_DIR}/ )
+			if( APPLE )
+				set( ASM_FLAGS -fmacho -DM_TARGET_MACHO )
+			else( APPLE )
+				set( ASM_FLAGS -felf )
+			endif( APPLE )
+			set( ASM_FLAGS "${ASM_FLAGS}" -DM_TARGET_LINUX -i${CMAKE_CURRENT_SOURCE_DIR}/ )
 			set( ASM_SOURCE_EXTENSION .asm )
 		endif( X64 )
 	else( UNIX )
diff --git a/src/asm_ia32/a.asm b/src/asm_ia32/a.asm
index 196e8317a..07b00fe25 100644
--- a/src/asm_ia32/a.asm
+++ b/src/asm_ia32/a.asm
@@ -93,7 +93,16 @@ setupvlineasm:
 	selfmod premach3a, machvsh8+6
 	ret
 
+%ifdef M_TARGET_MACHO
+	SECTION .text align=64
+%else
 	SECTION .rtext	progbits alloc exec write align=64
+%endif
+
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_a_start
+rtext_a_start:
+%endif
 
 ;eax = xscale
 ;ebx = palookupoffse
@@ -538,3 +547,8 @@ ALIGN 16
 mvcase0:	jmp beginmvlineasm4
 
 align 16
+
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_a_end
+rtext_a_end:
+%endif
diff --git a/src/asm_ia32/tmap.asm b/src/asm_ia32/tmap.asm
index e4c477598..04b86d09d 100644
--- a/src/asm_ia32/tmap.asm
+++ b/src/asm_ia32/tmap.asm
@@ -285,7 +285,16 @@ R_SetSpanSize_ASM:
 	
 aret:	ret
 
+%ifdef M_TARGET_MACHO
+	SECTION .text align=64
+%else
 	SECTION .rtext	progbits alloc exec write align=64
+%endif
+
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_tmap_start
+rtext_tmap_start:
+%endif
 
 rtext_start:
 
@@ -1738,6 +1747,10 @@ ac4nil:	pop		edi
 		ret
 
 rtext_end:
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_tmap_end
+rtext_tmap_end:
+%endif
 		align	16
 
 ;************************
diff --git a/src/asm_ia32/tmap2.asm b/src/asm_ia32/tmap2.asm
index 7f6ed82da..63eee0044 100644
--- a/src/asm_ia32/tmap2.asm
+++ b/src/asm_ia32/tmap2.asm
@@ -216,7 +216,13 @@ SetTiltedSpanSize:
 	
 	ret
 
+%ifndef M_TARGET_MACHO
 	SECTION .rtext	progbits alloc exec write align=64
+%else
+	SECTION .text align=64
+GLOBAL rtext_tmap2_start
+rtext_tmap2_start:
+%endif
 
 rtext_start:
 
@@ -628,3 +634,7 @@ fetch10	mov	al,[ebp+esi+SPACEFILLER4]
 	ret
 
 rtext_end:
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_tmap2_end
+rtext_tmap2_end:
+%endif
diff --git a/src/asm_ia32/tmap3.asm b/src/asm_ia32/tmap3.asm
index 49444419c..3791b4ff0 100644
--- a/src/asm_ia32/tmap3.asm
+++ b/src/asm_ia32/tmap3.asm
@@ -80,7 +80,13 @@ setupvlinetallasm:
 	selfmod shifter1, shift12+6
 	ret
 
+%ifdef M_TARGET_MACHO
+	SECTION .text align=64
+GLOBAL rtext_tmap3_start
+rtext_tmap3_start:
+%else
 	SECTION .rtext	progbits alloc exec write align=64
+%endif
 
 ALIGN 16
 
@@ -331,3 +337,8 @@ shift12:	shr	ecx,16
 		pop	ebx
 		pop	ebp
 		ret
+
+%ifdef M_TARGET_MACHO
+GLOBAL rtext_tmap3_end
+rtext_tmap3_end:
+%endif
diff --git a/src/d_main.cpp b/src/d_main.cpp
index 3b1e841a5..520127b9b 100644
--- a/src/d_main.cpp
+++ b/src/d_main.cpp
@@ -38,7 +38,7 @@
 #endif
 #include <float.h>
 
-#ifdef unix
+#if defined(unix) || defined(__APPLE__)
 #include <unistd.h>
 #endif
 
diff --git a/src/doomtype.h b/src/doomtype.h
index 7757a3cc6..31f96d2ab 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -44,12 +44,6 @@
 
 // Since this file is included by everything, it seems an appropriate place
 // to check the NOASM/USEASM macros.
-#if defined(__APPLE__)
-// The assembly code needs to be tweaked for Mach-O before enabled on Macs.
-#ifndef NOASM
-#define NOASM
-#endif
-#endif
 
 // There are three assembly-related macros:
 //
diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index f1cbe4446..28217f663 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -3495,7 +3495,7 @@ inline int getshort (int *&pc)
 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) 
 inline int uallong(int &foo)
 {
-	return *foo;
+	return foo;
 }
 #else
 inline int uallong(int &foo)
diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp
index 5650c0781..4305a07ca 100644
--- a/src/sdl/i_main.cpp
+++ b/src/sdl/i_main.cpp
@@ -44,6 +44,10 @@
 #include <gtk/gtk.h>
 #endif
 #include <locale.h>
+#if defined(__MACH__) && !defined(NOASM)
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
 
 #include "doomerrors.h"
 #include "m_argv.h"
@@ -201,6 +205,46 @@ static int DoomSpecificInfo (char *buffer, char *end)
 	return p;
 }
 
+#if defined(__MACH__) && !defined(NOASM)
+// NASM won't let us create custom sections for Mach-O. Whether that's a limitation of NASM
+// or of Mach-O, I don't know, but since we're using NASM for the assembly, it doesn't much
+// matter.
+extern "C"
+{
+	extern void *rtext_a_start, *rtext_a_end;
+	extern void *rtext_tmap_start, *rtext_tmap_end;
+	extern void *rtext_tmap2_start, *rtext_tmap2_end;
+	extern void *rtext_tmap3_start, *rtext_tmap3_end;
+};
+
+static void unprotect_pages(long pagesize, void *start, void *end)
+{
+	char *page = (char *)((intptr_t)start & ~(pagesize - 1));
+	size_t len = (char *)end - (char *)start;
+	if (mprotect(page, len, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
+	{
+		fprintf(stderr, "mprotect failed\n");
+		exit(1);
+	}
+}
+
+static void unprotect_rtext()
+{
+	static void *const pages[] =
+	{
+		rtext_a_start, rtext_a_end,
+		rtext_tmap_start, rtext_tmap_end,
+		rtext_tmap2_start, rtext_tmap2_end,
+		rtext_tmap3_start, rtext_tmap3_end
+	};
+	long pagesize = sysconf(_SC_PAGESIZE);
+	for (void *const *p = pages; p < &pages[countof(pages)]; p += 2)
+	{
+		unprotect_pages(pagesize, p[0], p[1]);
+	}
+}
+#endif
+
 int main (int argc, char **argv)
 {
 	printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n\n",
@@ -214,6 +258,10 @@ int main (int argc, char **argv)
 	seteuid (getuid ());
     std::set_new_handler (NewFailure);
 
+#if defined(__MACH__) && !defined(NOASM)
+	unprotect_rtext();
+#endif
+	
 #ifndef NO_GTK
 	GtkAvailable = gtk_init_check (&argc, &argv);
 #endif