Index: moonshell11_src/arm9/source/main.cpp
diff -u moonshell11_src/arm9/source/main.cpp:1.1 moonshell11_src/arm9/source/main.cpp:1.2
--- moonshell11_src/arm9/source/main.cpp:1.1	Tue Apr 25 20:42:08 2006
+++ moonshell11_src/arm9/source/main.cpp	Wed Apr 26 13:24:52 2006
@@ -1345,6 +1345,8 @@
     break;
     case DIMT_SCS2: _consolePrintf("SuperCard SD alternative version\n");
     break;
+    case DIMT_MMCF: _consolePrintf("Max Media CF\n");
+    break;
   }
   
   if(keywait==false) return;
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.c
diff -u moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.c:1.1 moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.c:1.2
--- moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.c:1.1	Tue Apr 25 20:42:12 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.c	Wed Apr 26 13:24:51 2006
@@ -60,6 +60,10 @@
  #include "io_nmmc.h"
 #endif
 
+#ifdef SUPPORT_MMCF
+#include "io_mmcf.h"
+#endif
+
 #include "io_scs2.h"
 
 // Keep a pointer to the active interface
@@ -314,6 +318,19 @@
 		// set FC as default IO
 		_consolePrintOne("pass.\n",0);
 		DIMediaType=DIMT_FCSR;
+		return true ;
+	} ;
+	}
+#endif
+
+#ifdef SUPPORT_MMCF
+	if((DIMediaType==DIMT_NONE)||(DIMediaType==DIMT_MMCF)){
+	_consolePrintOne("chkMMCF/",0);
+	active_interface = MMCF_GetInterface() ;
+	if (active_interface->fn_StartUp())
+	{		
+		_consolePrintOne("pass.\n",0);
+		DIMediaType=DIMT_MMCF;
 		return true ;
 	} ;
 	}
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.h
diff -u moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.h:1.1 moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.h:1.2
--- moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.h:1.1	Tue Apr 25 20:42:12 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/disc_io.h	Wed Apr 26 13:24:51 2006
@@ -14,21 +14,23 @@
 
 // Device support options, added by www.neoflash.com
 
-#define SUPPORT_NMMC		// comment out this line to remove Neoflash MK2 MMC Card support
-#define SUPPORT_MPCF		// comment out this line to remove GBA Movie Player support
-#define SUPPORT_M3CF		// comment out this line to remove M3 Perfect CF support
-#define SUPPORT_SCCF		// comment out this line to remove Supercard CF support
-#define SUPPORT_SCSD		// comment out this line to remove Supercard SD support
-#define SUPPORT_M3SD		// comment out this line to remove M3 Perfect SD support (can't write)
+//#define SUPPORT_NMMC		// comment out this line to remove Neoflash MK2 MMC Card support
+//#define SUPPORT_MPCF		// comment out this line to remove GBA Movie Player support
+//#define SUPPORT_M3CF		// comment out this line to remove M3 Perfect CF support
+//#define SUPPORT_SCCF		// comment out this line to remove Supercard CF support
+//#define SUPPORT_SCSD		// comment out this line to remove Supercard SD support
+//#define SUPPORT_M3SD		// comment out this line to remove M3 Perfect SD support (can't write)
 #define SUPPORT_FCSR		// comment out this line to remove GBA Flash Cart support
 
 #define SUPPORT_SCS2		// by gba_nds_fat_2006-03-03 version SCSD driver
 
+#define SUPPORT_MMCF    // Max Media CF
+
 // Disk caching options, added by www.neoflash.com
 // Each additional sector cache uses 512 bytes of memory
 // Disk caching is disabled on GBA to conserve memory
 
-//#define DISC_CACHE				// uncomment this line to enable disc caching
+#define DISC_CACHE				// uncomment this line to enable disc caching
 #define DISC_CACHE_COUNT	256	// maximum number of sectors to cache (512 bytes per sector)
 
 
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.c
diff -u nul moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.c:1.2
--- nul	Thu May  4 09:43:48 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.c	Thu May  4 09:13:13 2006
@@ -0,0 +1,325 @@
+/*
+  io_mmcf.c based on
+
+	io_mpcf.c based on
+
+	compact_flash.c
+	By chishm (Michael Chisholm)
+
+	Hardware Routines for reading a compact flash card
+	using the GBA Movie Player
+
+	CF routines modified with help from Darkfader
+
+	This software is completely free. No warranty is provided.
+	If you use it, please give me credit and email me about your
+	project at chishm@hotmail.com
+
+	See gba_nds_fat.txt for help and license details.
+*/
+
+
+#include "io_mmcf.h"
+
+#ifdef SUPPORT_MMCF
+
+//---------------------------------------------------------------
+// DMA
+#ifdef _CF_USE_DMA
+ #ifndef NDS
+  #include "gba_dma.h"
+ #else
+  #include <nds/dma.h>
+  #ifdef ARM9
+   #include <nds/arm9/cache.h>
+  #endif
+ #endif
+#endif
+
+//---------------------------------------------------------------
+// CF Addresses & Commands
+
+#define CF_RD_DATA          (*(volatile u16*)(0x08000000 + 0x00000))
+#define CF_RD_ERROR         (*(volatile u16*)(0x08000000 + 0x20000))
+#define CF_RD_SECTOR_COUNT  (*(volatile u16*)(0x08000000 + 0x40000))
+#define CF_RD_SECTOR_NO     (*(volatile u16*)(0x08000000 + 0x60000))
+#define CF_RD_CYLINDER_LOW  (*(volatile u16*)(0x08000000 + 0x80000))
+#define CF_RD_CYLINDER_HIGH (*(volatile u16*)(0x08000000 + 0xA0000))
+#define CF_RD_SEL_HEAD      (*(volatile u16*)(0x08000000 + 0xC0000))
+#define CF_RD_STATUS        (*(volatile u16*)(0x08000000 + 0xE0000))
+
+#define CF_WR_DATA          (*(volatile u16*)(0x08000000 + 0x00000))
+#define CF_WR_FEATURES      (*(volatile u16*)(0x08000000 + 0x20000))
+#define CF_WR_SECTOR_COUNT  (*(volatile u16*)(0x08000000 + 0x40000))
+#define CF_WR_SECTOR_NO     (*(volatile u16*)(0x08000000 + 0x60000))
+#define CF_WR_CYLINDER_LOW  (*(volatile u16*)(0x08000000 + 0x80000))
+#define CF_WR_CYLINDER_HIGH (*(volatile u16*)(0x08000000 + 0xA0000))
+#define CF_WR_SEL_HEAD      (*(volatile u16*)(0x08000000 + 0xC0000))
+#define CF_WR_COMMAND       (*(volatile u16*)(0x08000000 + 0xE0000))
+
+#define GAME_PAK		0x08000000			// Game pack start address
+#define MP_DATA			(vu16*)(GAME_PAK + 0x01000000)		// Pointer to buffer of CF data transered from card
+#define MP_REG_LBA1		*(vu16*)(GAME_PAK + 0x01060000)	// 1st byte of sector address
+#define CARD_TIMEOUT	10000000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
+
+
+static bool cf_block_ready(void)
+{
+  int i;
+
+  i = 0;
+
+  /*
+  do
+  {
+    while (!(CF_RD_STATUS & 0x40));
+  } while (CF_RD_STATUS & 0x80); 
+  */
+
+  do
+  {
+    i++;
+    while ( (!(CF_RD_STATUS & 0x40)) && (i < CARD_TIMEOUT) ) i++;    
+  } while ( (CF_RD_STATUS & 0x80) && (i < CARD_TIMEOUT) ); 
+
+  if (i >= CARD_TIMEOUT) return false;
+
+  return true;
+}
+
+
+static bool cf_set_features(u32 feature)
+{
+  if ( !cf_block_ready() ) return false;
+
+  CF_WR_FEATURES = feature;
+  CF_WR_SECTOR_COUNT = 0x00;  // config???
+  CF_WR_SEL_HEAD = 0x00;
+  CF_WR_COMMAND = 0xEF;
+
+  return true;
+}
+
+
+
+/*-----------------------------------------------------------------
+MMCF_IsInserted
+Is a compact flash card inserted?
+bool return OUT:  true if a CF card is inserted
+-----------------------------------------------------------------*/
+bool MMCF_IsInserted (void) 
+{
+  if ( !cf_set_features(0xAA) ) return false;
+
+  return true;
+}
+
+
+/*-----------------------------------------------------------------
+MMCF_ClearStatus
+Tries to make the CF card go back to idle mode
+bool return OUT:  true if a CF card is idle
+-----------------------------------------------------------------*/
+bool MMCF_ClearStatus (void) 
+{
+	return true;
+}
+
+
+/*-----------------------------------------------------------------
+MMCF_ReadSectors
+Read 512 byte sector numbered "sector" into "buffer"
+u32 sector IN: address of first 512 byte sector on CF card to read
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer OUT: pointer to 512 byte buffer to store data in
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool MMCF_ReadSectors (u32 sector, u8 numSecs, void* buffer)
+{
+	int i;
+	int j = (numSecs > 0 ? numSecs : 256);
+	u16 *buff = (u16*)buffer;
+#ifdef _CF_ALLOW_UNALIGNED
+	u8 *buff_u8 = (u8*)buffer;
+	int temp;
+#endif
+
+#if (defined _CF_USE_DMA) && (defined NDS) && (defined ARM9)
+	DC_FlushRange( buffer, j * BYTE_PER_READ);
+#endif
+
+  if ( !cf_block_ready() ) return false;
+
+  CF_WR_SECTOR_COUNT = numSecs;
+  CF_WR_SECTOR_NO = sector;
+  CF_WR_CYLINDER_LOW = sector >> 8;
+  CF_WR_CYLINDER_HIGH = sector >> 16;
+  CF_WR_SEL_HEAD = ((sector >> 24) & 0x0F) | 0xE0;
+  CF_WR_COMMAND = 0x20; // read sectors
+
+  while (j--)
+  {
+    if ( !cf_block_ready() ) return false;
+
+#ifdef _CF_USE_DMA
+ #ifdef NDS
+		DMA3_SRC = (u32)MP_DATA;
+		DMA3_DEST = (u32)buff;
+		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_SRC_FIX;
+ #else
+		DMA3COPY ( MP_DATA, buff, 256 | DMA16 | DMA_ENABLE | DMA_SRC_FIXED);
+ #endif
+		buff += BYTE_PER_READ / 2;
+#elif defined _CF_ALLOW_UNALIGNED
+		i=256;
+		if ((u32)buff_u8 & 0x01) {
+			while(i--)
+			{
+				temp = *MP_DATA;
+				*buff_u8++ = temp & 0xFF;
+				*buff_u8++ = temp >> 8;
+			}
+		} else {
+		while(i--)
+			*buff++ = *MP_DATA; 
+		}
+#else
+		i=256;
+		while(i--)
+			*buff++ = *MP_DATA;
+#endif
+  }
+
+#if (defined _CF_USE_DMA) && (defined NDS)
+	// Wait for end of transfer before returning
+	while(DMA3_CR & DMA_BUSY);
+#endif
+
+	return true;
+}
+
+
+
+/*-----------------------------------------------------------------
+MMCF_WriteSectors
+Write 512 byte sector numbered "sector" from "buffer"
+u32 sector IN: address of 512 byte sector on CF card to read
+u8 numSecs IN: number of 512 byte sectors to read,
+ 1 to 256 sectors can be read, 0 = 256
+void* buffer IN: pointer to 512 byte buffer to read data from
+bool return OUT: true if successful
+-----------------------------------------------------------------*/
+bool MMCF_WriteSectors (u32 sector, u8 numSecs, void* buffer)
+{
+	int i;
+	int j = (numSecs > 0 ? numSecs : 256);
+	u16 *buff = (u16*)buffer;
+#ifdef _CF_ALLOW_UNALIGNED
+	u8 *buff_u8 = (u8*)buffer;
+	int temp;
+#endif
+	
+#if defined _CF_USE_DMA && defined NDS && defined ARM9
+	DC_FlushRange( buffer, j * BYTE_PER_READ);
+#endif
+
+  if ( !cf_block_ready() ) return false;
+
+  CF_WR_SECTOR_COUNT = numSecs;
+  CF_WR_SECTOR_NO = sector;
+  CF_WR_CYLINDER_LOW = sector >> 8;
+  CF_WR_CYLINDER_HIGH = sector >> 16;
+  CF_WR_SEL_HEAD = ((sector >> 24) & 0x0F) | 0xE0;
+  CF_WR_COMMAND = 0x30; // write sectors
+
+  while (j--)
+  {
+    if ( !cf_block_ready() ) return false;
+
+#ifdef _CF_USE_DMA
+ #ifdef NDS
+		DMA3_SRC = (u32)buff;
+		DMA3_DEST = (u32)MP_DATA;
+		DMA3_CR = 256 | DMA_COPY_HALFWORDS | DMA_DST_FIX;
+ #else
+		DMA3COPY( buff, MP_DATA, 256 | DMA16 | DMA_ENABLE | DMA_DST_FIXED);
+ #endif
+		buff += BYTE_PER_READ / 2;
+#elif defined _CF_ALLOW_UNALIGNED
+		i=256;
+		if ((u32)buff_u8 & 0x01) {
+			while(i--)
+			{
+				temp = *buff_u8++;
+				temp |= *buff_u8++ << 8;
+				*MP_DATA = temp;
+			}
+		} else {
+		while(i--)
+			*MP_DATA = *buff++; 
+		}
+#else
+		i=256;
+		while(i--)
+			*MP_DATA = *buff++; 
+#endif
+  }
+
+#if defined _CF_USE_DMA && defined NDS
+	// Wait for end of transfer before returning
+	while(DMA3_CR & DMA_BUSY);
+#endif  
+
+	return true;
+}
+
+/*-----------------------------------------------------------------
+MMCF_Shutdown
+unload the GBAMP CF interface
+-----------------------------------------------------------------*/
+bool MMCF_Shutdown(void) 
+{
+	return MMCF_ClearStatus() ;
+}
+
+/*-----------------------------------------------------------------
+MMCF_StartUp
+initializes the CF interface, returns true if successful,
+otherwise returns false
+-----------------------------------------------------------------*/
+bool MMCF_StartUp(void)
+{
+  /*
+	u8 temp = MP_REG_LBA1;
+	MP_REG_LBA1 = (~temp & 0xFF);
+	temp = (~temp & 0xFF);
+	return (MP_REG_LBA1 == temp);
+  */
+
+  return true;
+}
+
+/*-----------------------------------------------------------------
+the actual interface structure
+-----------------------------------------------------------------*/
+IO_INTERFACE io_mmcf = {
+	DEVICE_TYPE_MMCF,
+	FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA,
+	(FN_MEDIUM_STARTUP)&MMCF_StartUp,
+	(FN_MEDIUM_ISINSERTED)&MMCF_IsInserted,
+	(FN_MEDIUM_READSECTORS)&MMCF_ReadSectors,
+	(FN_MEDIUM_WRITESECTORS)&MMCF_WriteSectors,
+	(FN_MEDIUM_CLEARSTATUS)&MMCF_ClearStatus,
+	(FN_MEDIUM_SHUTDOWN)&MMCF_Shutdown
+} ;
+
+/*-----------------------------------------------------------------
+MPCF_GetInterface
+returns the interface structure to host
+-----------------------------------------------------------------*/
+LPIO_INTERFACE MMCF_GetInterface(void) {
+	return &io_mmcf ;
+} ;
+
+#endif // SUPPORT_MMCF
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.h
diff -u nul moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.h:1.1
--- nul	Thu May  4 09:43:48 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_mmcf.h	Wed Apr 26 13:24:52 2006
@@ -0,0 +1,25 @@
+/*
+	io_mmcf.h 
+
+	Hardware Routines for reading a compact flash card
+	using the GBA Movie Player
+
+	This software is completely free. No warranty is provided.
+	If you use it, please give me credit and email me about your
+	project at chishm@hotmail.com
+
+	See gba_nds_fat.txt for help and license details.
+*/
+
+#ifndef IO_MMCF_H
+#define IO_MMCF_H
+
+// 'MMCF'
+#define DEVICE_TYPE_MMCF 0x4646504D
+
+#include "disc_io.h"
+
+// export interface
+extern LPIO_INTERFACE MMCF_GetInterface(void) ;
+
+#endif	// define IO_MMCF_H
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_scsd.c
diff -u moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_scsd.c:1.1 moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_scsd.c:1.2
--- moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_scsd.c:1.1	Tue Apr 25 20:42:14 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/io_scsd.c	Wed Apr 26 13:24:51 2006
@@ -18,6 +18,8 @@
 
 #include "io_scsd.h"
 
+#ifdef SUPPORT_SCSD
+
 //---------------------------------------------------------------
 #ifdef __cplusplus
 extern "C" {
@@ -31,7 +33,7 @@
 }	   // extern "C"
 #endif
 
-extern bool MPCF_ClearStatus (void);
+//extern bool MPCF_ClearStatus (void);
 
 #define SC_SD_COMMAND 0x09800000
 
@@ -75,6 +77,72 @@
     return true;
 }
 
+
+
+//---------------------------------------------------------------
+// CF Addresses & Commands
+
+#define GAME_PAK		0x08000000			// Game pack start address
+
+// GBAMP CF Addresses
+#define MP_REG_STS		*(vu16*)(GAME_PAK + 0x018C0000)	// Status of the CF Card / Device control
+#define MP_REG_CMD		*(vu16*)(GAME_PAK + 0x010E0000)	// Commands sent to control chip and status return
+#define MP_REG_ERR		*(vu16*)(GAME_PAK + 0x01020000)	// Errors / Features
+
+#define MP_REG_SEC		*(vu16*)(GAME_PAK + 0x01040000)	// Number of sector to transfer
+#define MP_REG_LBA1		*(vu16*)(GAME_PAK + 0x01060000)	// 1st byte of sector address
+#define MP_REG_LBA2		*(vu16*)(GAME_PAK + 0x01080000)	// 2nd byte of sector address
+#define MP_REG_LBA3		*(vu16*)(GAME_PAK + 0x010A0000)	// 3rd byte of sector address
+#define MP_REG_LBA4		*(vu16*)(GAME_PAK + 0x010C0000)	// last nibble of sector address | 0xE0
+
+#define MP_DATA			(vu16*)(GAME_PAK + 0x01000000)		// Pointer to buffer of CF data transered from card
+
+// CF Card status
+#define CF_STS_INSERTED		0x50
+#define CF_STS_REMOVED		0x00
+#define CF_STS_READY		0x58
+
+#define CF_STS_DRQ			0x08
+#define CF_STS_BUSY			0x80
+
+// CF Card commands
+#define CF_CMD_LBA			0xE0
+#define CF_CMD_READ			0x20
+#define CF_CMD_WRITE		0x30
+
+#define CARD_TIMEOUT	10000000		// Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write
+
+
+/*-----------------------------------------------------------------
+MPCF_ClearStatus
+Tries to make the CF card go back to idle mode
+bool return OUT:  true if a CF card is idle
+-----------------------------------------------------------------*/
+static bool MPCF_ClearStatus (void) 
+{
+	int i;
+	
+	// Wait until CF card is finished previous commands
+	i=0;
+	while ((MP_REG_CMD & CF_STS_BUSY) && (i < CARD_TIMEOUT))
+	{
+		i++;
+	}
+	
+	// Wait until card is ready for commands
+	i = 0;
+	while ((!(MP_REG_STS & CF_STS_INSERTED)) && (i < CARD_TIMEOUT))
+	{
+		i++;
+	}
+	if (i >= CARD_TIMEOUT)
+		return false;
+
+	return true;
+}
+
+
+
 bool SCSD_Shutdown(void) {
 	return MPCF_ClearStatus() ;
 } ;
@@ -99,3 +167,5 @@
 LPIO_INTERFACE SCSD_GetInterface(void) {
 	return &io_scsd ;
 } ;
+
+#endif  // SUPPORT_SCSD
Index: moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/mediatype.h
diff -u moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/mediatype.h:1.1 moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/mediatype.h:1.2
--- moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/mediatype.h:1.1	Tue Apr 25 20:42:14 2006
+++ moonshell11_src/arm9/source/gba_nds_fat_2006-02-09_unicode_M3SD_ReadAlignDetect/mediatype.h	Wed Apr 26 13:24:51 2006
@@ -6,7 +6,7 @@
 extern "C" {
 #endif
 
-typedef enum {DIMT_NONE=0,DIMT_M3CF,DIMT_M3SD,DIMT_MPCF,DIMT_SCCF,DIMT_SCSD,DIMT_FCSR,DIMT_NMMC,DIMT_SCS2} EDIMediaType;
+typedef enum {DIMT_NONE=0,DIMT_M3CF,DIMT_M3SD,DIMT_MPCF,DIMT_SCCF,DIMT_SCSD,DIMT_FCSR,DIMT_NMMC,DIMT_SCS2,DIMT_MMCF} EDIMediaType;
 
 extern EDIMediaType DIMediaType;
 
