ハードウェア - フラッシュカートリッジ

「ハードウェア - フラッシュカートリッジ」の編集履歴(バックアップ)一覧はこちら

ハードウェア - フラッシュカートリッジ」(2007/06/18 (月) 09:36:20) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

Visoly / Flash-Advance The older-style non-turbo cartridges contain a single intel 28F Flash, while the newer turbo cartridges contain a pair of chips interleaved. Type Flash RAM Notes 64M 1x 28F640J3A (120ns) 128 KB 3 bank bits, cannot reliably do 3/1 waits Turbo 64M 2 x 28F320J3A (110ns) 256 KB Only has 3 bank bits Turbo 128M 2 x 28F640J3A (120ns) 256 KByte Only has 3 bank bits FA Pro 64M 2 x 28F320J3A (110ns) 256 KByte Also supports 4 kbit eeprom FA Pro 128M 2 x 28F640J3A (120ns) 256 KByte Also supports 4 kbit eeprom FA Pro 256M 2 x 28F640J3A (120ns) 256 KByte Also supports 4 kbit eeprom FA Xtreme 512M/1G 2 or 4 x 28F256K3 256 KByte Notes: * All carts use Intel flash parts. * All of the 256 KB SRAM carts use a NEC D442000LGU chip. * None of the carts support the 64 kbit eeprom type * The three bank bits carts only support the 8 MB, 4 MB, and 256 KB bits (see below for more information). VisolyCommand(uint32 address, uint16 data, uint16 count) for ( ; count > 0; count--) GBA_CART[addr << 1] = data; VisolyUnlock(yes, it really is this stupid!) VisolyCommand(0x987654, 0x5354, 1) VisolyCommand(0x012345, 0x1234, 500) VisolyCommand(0x007654, 0x5354, 1) VisolyCommand(0x012345, 0x5354, 1) VisolyCommand(0x012345, 0x5678, 500) VisolyCommand(0x987654, 0x5354, 1) VisolyCommand(0x012345, 0x5354, 1) VisolyCommand(0x765400, 0x5678, 1) VisolyCommand(0x013450, 0x1234, 1) VisolyCommand(0x012345, 0xABCD, 500) VisolyCommand(0x987654, 0x5354, 1) // Disable the write-protection on the Flash ROM VisolyUnlockFlash VisolyUnlock VisolyCommand(0xF12345, 0x9413, 1) // Select which bank of SRAM is visible (64 KB each, 4 or 8 implemented) VisolySetSRAMBank(bank) VisolyUnlock VisolyCommand(0xA12345, bank & 7, 1) // returns true if the offset is valid // for old-style cartridges bool VisolySetFlashBaseAddress(offset) if (offset & 0xFF3F7FFF) return false base = ((offset >> 22) & 3) | ((offset >> 12) & 8) VisolyUnlock VisolyCommand(0xB5AC97, base, 1) return true // returns true if the offset is valid // for new-style cartridges bool VisolySetFlashBaseAddress(offset) if (offset & 0xFE007FFF) return false base = ((offset >> 22) & 3) | ((offset >> 22) & 4) | ((offset >> 12) & 0x3F8) VisolyUnlock VisolyCommand(0xB5AC97, base, 1) return true The Flash offset register is a bit funky, and only bits 0, 1, and 3 are implemented on the older cartridges. Format of the register is shown below: 15..10 9 8 7 6 5 4 3 2 1 0 - 2 MB 1 MB 512 KB 256 KB 128 KB 64 KB 32 KB 16 MB 8 MB 4 MB Thanks to Jeff Frohwein and Reiner Ziegler GBA Movie Player Components * FlashROM, SST39VF400A 256Kx16 (0x278000BF) or SST39VF800A 512Kx16 (0x278100BF) * CPLD, Actel eX64, 64 pin TQFP Pinout GBA A flash A inverted pin 0 10 1 6 1 11 1 5 2 12 1 4 3 8 1 8 4 9 0 7 5 7 0 18 6 6 0 19 7 5 1 20 8 2 0 23 9 3 1 22 10 4 1 21 11 0 1 25 12 1 1 24 13 - - - 14 - - - 15 - - - 16 13 0 3 17 14 0 2 18 15 0 1 19 16 0 48 20 17 0 17 21 18 0 16 (512K x 16 only) Registers Data register MP_DATA 0x09000000 Error register MP_REG_ERR 0x09020000 Sector # MP_REG_SEC 0x09040000 LBA byte 1 MP_REG_LBA1 0x09060000 LBA byte 2 MP_REG_LBA2 0x09080000 LBA byte 3 MP_REG_LBA3 0x090A0000 0xE0 | LBA byte4 MP_REG_LBA4 0x090C0000 Command register MP_REG_CMD 0x090E0000 Status register MP_REG_STS 0x098C0000 Unlock sequence Unlocking is required to read offset >=0x200. A short unlock sequence that works in most cases can be performed by reading these offsets in order: 0x0134,0x00D4,0x0144,0x00EC,0x01E4,0x0188,0x01F4,0x01D4 M3 CF/SD CompactFlash addresses Data register MP_DATA 0x08800000 Error register MP_REG_ERR 0x08820000 Sector # MP_REG_SEC 0x08840000 LBA byte 1 MP_REG_LBA1 0x08860000 LBA byte 2 MP_REG_LBA2 0x08880000 LBA byte 3 MP_REG_LBA3 0x088A0000 0xE0 | LBA byte4 MP_REG_LBA4 0x088C0000 Command register MP_REG_CMD 0x088E0000 Status register MP_REG_STS 0x080C0000 M3 mode switching: static u16 M3_readHalfword (u32 addr) { return *((vu16*)addr); } void M3_changeMode (u32 mode) { M3_readHalfword (0x08e00002); M3_readHalfword (0x0800000e); M3_readHalfword (0x08801ffc); M3_readHalfword (0x0800104a); M3_readHalfword (0x08800612); M3_readHalfword (0x08000000); M3_readHalfword (0x08801b66); M3_readHalfword (0x08000000 + (mode << 1)); M3_readHalfword (0x0800080e); M3_readHalfword (0x08000000); if ((mode & 0x0f) == 4) { // unlock ROM addr >= 0x200 M3_readHalfword (0x080001e4); M3_readHalfword (0x080001e4); M3_readHalfword (0x08000188); M3_readHalfword (0x08000188); } else { M3_readHalfword (0x09000000); } } // Values for changing mode #define M3_MODE_ROM 0x00400004 #define M3_MODE_MEDIA 0x00400003 #define M3_MODE_RAM_R 0x00400002 #define M3_MODE_RAM_RW 0x00400006 // read-write access (Thanks to Chishm) RAM R/W mode can also be enabled by writing 0xAA55 to 0x09FFEFFE. G6 G6 SDRAM can be made writable by writing 0xAA55 to 0x09FFFFFE. General CF information CF card status: * Inserted: 0x50 * Removed: 0x00 * Ready: 0x58 * DRQ: 0x08 * Busy: 0x80 CF card commands: * LBA: 0xE0 * Read: 0x20 * Write: 0x30 Initialize CF by writing 0x50 to the status register: MP_REG_STS = 0x50. Thanks to DarkFader, Chishm, and MightyMax for info on the GBA MP and M3. SuperCard (CF version) Components: * Lattice ispMACH LC4128V : CPLD (Mach4000 family) * HY57V561620CTP-H (Hynix): 256 Mbit SDRAM, 3.3V, PC133-CL3 * M5M5V208AKV (Mitsubishi): 2 Mbit CMOS SRAM , 2.7-3.6V, 70ns * 29LV400TC-90PFTN (Fairchild also avail. from Fujitsu): 4Mbits FLASH, 90ns, 3V Note: Untested, based on code posted to forum. Credit due to the unknown author of 20051024113435206.zip Name Define Address Size Sector buffer SC_CF_DATA 0x09000000 512 Unlock register SC_UNLOCK 0x09FFFFFE 2 Sector count SC_CF_SECTOR_COUNT 0x09040000 2 LBA byte 1 SC_CF_LBA1 0x09060000 2 LBA byte 2 SC_CF_LBA2 0x09080000 2 LBA byte 3 SC_CF_LBA3 0x090A0000 2 0xE0 | LBA byte4 SC_CF_LBA4 0x090C0000 2 Command register SC_CF_CMD 0x090E0000 2 Status register SC_CF_STATUS 0x099C0000 2 Status register SC_CF_STATUS_L 0x099C0000 1 The status register can be accessed as both a byte or halfword, the others all seem to be treated as halfwords (even though only 8 bits of data are stored in each). I don't have a supercard to test this for sure. Thus, you can't read more than 255 sectors at a time either (possibly 256 if 0 is stored?). Unlike the M3, either the supercard appears to have a 512 byte sector buffer (unlikely), rather than a one byte FIFO, or the daft code just makes use of address mirroring to read the one byte FIFO at 512 addresses (more likely). Format of the Supercard unlock register: 15..3 ? 2 Enable SDRAM 1 Enable CF / SD 0 Always 1 after 0x5AA5 You write 0xA55A twice, then write 0x5 (enable SDRAM), 0x3 (enable CF / SD), or 0x1 (disable SDRAM, presumably also disable CF/SD) twice. I'm going to take a wild guess and say that enabling both SDRAM and CF/SD at the same time is a bad idea. Also, on the cartridges with both SD and CF, are there two seperate bits to enable them? Supercard_Unlock: SC_UNLOCK = 0xA55A SC_UNLOCK = 0xA55A SC_UNLOCK = 0x0003 SC_UNLOCK = 0x0003 Supercard_IsCFInserted SC_CF_STATUS = 0x0050 nop return (SC_CF_STATUS_L == 0x50) Supercard_CFCommand(command, address, count) while ((SC_CF_STATUS_L & 0xC0) != 0x40) ; SC_CF_SECTOR_COUNT = count; SC_CF_LBA1 = address & 0xFF; SC_CF_LBA2 = (address>>8) & 0xFF; SC_CF_LBA3 = (address>>16) & 0xFF; SC_CF_LBA4 = ((address>>24) & 0xFF) | 0xE0; SC_CF_CMD = command; // delay for a little bit, they run a loop of a few cycles for // 16 iterations. The overhead involved in a call to DelayLoop // takes nearly that long, not counting the delay itself, so this // can probably be reduced. Delay16 DelayLoop(0x10) // address is the LBA address on the CF card // count is the number of 512 byte sectors // destination is the memory address to store to Supercard_ReadSectors(address, count, destination) Supercard_CFCommand(0x20, address, count) Delay16 for each sector do while ((SC_CF_STATUS & 0x88) == 0x80) ; Copy 512 bytes from SC_CF_DATA to destination and advance destination end; // source is the memory address to read from // address is the LBA address on the CF card // count is the number of 512 byte sectors Supercard_WriteSectors(source, address, count) Supercard_CFCommand(0x30, address, count) Delay16 for each sector do while ((SC_CF_STATUS & 0x88) == 0x80) ; Copy 512 bytes from source to SC_CF_DATA and advance destination end; while ((SC_CF_STATUS & 0x80) != 0) ; Supercard (SD version) Components * FlashROM, 512KB, Fairchild 29LV400TV-80PFTN * SDRAM, 32 MBytes, Hynix HY57V561620CT-H * SRAM, 256 KBytes, Samsung KM68V2000LTGI-8L * CPLD, Lattice ispMACH LC4128V 75T100-10I * Oscillator, 50 MHz * JTAG connections at bottom cart edge Unlock register 15 ? 14 Should be 1 ? 13 ? 12 some bankswitch? 9..11 ? 8 some bankswitch? 7 ? 5..6 Should be 0 ? 4 0=select ROM, 1=select SD 3 ? 2 SDRAM: 0=write protect, 1=allow writes 1 ? 0 0=select ROM or SD, 1=select SDRAM (bits are manually tested without looking to any code) To set a new value, write 0xA55A to this register twice, then write the desired value twice. Below code is translated from some whack assembly, so it might contain bugs. Credit due to the unknown author of 20051024113435206.zip SC_SD_COMMAND 0x09800000 SC_SD_DATA 0x09000000 SC_SD_READ 0x09100000 //////////////////////////////////////////////////////////// void sd_data_write_s(uint16 * buffer, uint16 * crc16buff) // Wait until it's idle while (!(SC_SD_DATA & 0x100)) ; r3 = SC_SD_DATA; // start bit SC_SD_DATA = 0 r5 = 512; do { r3 = *buffer++ r3 = r3 + (r3 << 20) r4 = r3 << 8 SC_SD_DATA32 = r3 SC_SD_DATA32 = r4 } while (--r5 > 0); if (crc16buff) { r0 = crc16buff r1 = 0 r5 = 8 goto the copy loop again just above } // end bit SC_SD_DATA = 0xFF while (SC_SD_DATA & 0x100) ; r3 = SC_SD_DATA32 r4 = SC_SD_DATA32 //////////////////////////////////////////////////////////// sd_data_read_s(uint16 * destination) while (SC_SD_READ & 0x100) ; // wait for the start bit to clear for (i = 0; i < 256; i++) r3 = SC_SD_READ32 r4 = SC_SD_READ32 r3 = r4 >> 16 *destination++ = r4 >> 16; // Read (and throw away) the CRC-16 (2 bytes) r3 = SC_SD_READ32 r4 = SC_SD_READ32 r3 = SC_SD_READ32 r4 = SC_SD_READ32 // Read (and throw away) the end bit r3 = SC_SD_READ //////////////////////////////////////////////////////////// void sd_com_crc16_s(uint8 * buffer, uint16 num, uint8 * crc16buff) r3 = r4 = r5 = r6 = 0 r7 = 0x80808080 r8 = 0x1021 r1 = r1 << 3 do { if (r7 & 0x80) r2 = *buffer++ r3 = r3 << 1 if (r3 & 0x10000) r3 = r3 ^ r8 if (r2 & (r7>>24)) r3 = r3 ^ r8 r4 = r4 << 1 if (r4 & 0x10000) r4 = r4 ^ r8 if (r2 & (r7>>25)) r4 = r4 ^ r8 r5 = r5 << 1 if (r5 & 0x10000) r5 = r5 ^ r8 if (r2 & (r7>>26)) r5 = r5 ^ r8 r6 = r6 << 1 if (r6 & 0x10000) r6 = r6 ^ r8 if (r2 & (r7>>27)) r6 = r6 ^ r8 r7 = (r7 >> 4) | (r7 << 28) r1 -= 4; } while (r1); mov r2 = crc16buff r8 = 16 do { r7 = r7 << 4 if (r3 & 0x8000) r7 = r7 | 8 if (r4 & 0x8000) r7 = r7 | 4 if (r5 & 0x8000) r7 = r7 | 2 if (r6 & 0x8000) r7 = r7 | 1 r3 = r3 << 1 r4 = r4 << 1 r5 = r5 << 1 r6 = r6 << 1 r8--; if (r8 & 1) *crc16buf++ = r7 } while (r8); //////////////////////////////////////////////////////////// sd_crc7_s(uint8 * buffer, uint16 count) r3 = 0 r4 = 0x80808080 r1 = count*8 do { if (r4 & 0x80) r2 = *buffer++ r3 = r3 << 1 if (r3 & 0x80) r3 ^= 9; if (r2 & (r4>>24)) r3 ^= 9; r4 = (r4 >> 1) | (r4 << 31) } while (--r1 > 0); return (r3 << 1) + 1 //////////////////////////////////////////////////////////// sd_com_read_s while (SC_SD_COMMAND & 1) ; // wait for start bit to clear do r1--; while (r1); //////////////////////////////////////////////////////////// sd_com_write_s(uint8 * buffer, uint32 count): while (!(SC_SD_COMMAND & 1)) ; // wait for start bit to set temp = SC_SD_COMMAND; // throwaway read do { temp = *buffer++ temp = temp + (temp << 17) r4 = temp<<2 r5 = r4<<2 r6 = r5<<2 SC_SD_COMMAND = temp SC_SD_COMMAND = r4 SC_SD_COMMAND = r5 SC_SD_COMMAND = r6 } while (--count) //////////////////////////////////////////////////////////// send_clk(count) do { temp = SC_SD_COMMAND; // throwaway read } while (--count) //////////////////////////////////////////////////////////// // num not used!!!!! void SDCommand(uint8 command, uint8 num, uint32 sector) uint8 buffer[6]; buffer[0] = command | 0x40; buffer[1] = sector >> 24; buffer[2] = (sector >> 16) & 0xFF; buffer[3] = (sector >> 8) & 0xFF; buffer[4] = sector & 0xFF; buffer[5] = sd_crc7_s((u32)databuff, 5); sd_com_write_s(databuff, 6); //////////////////////////////////////////////////////////// void ReadSector(u16 *buff,u32 sector,u8 readnum) { SDCommand(18, 0, sector << 9); for (j = 0; j < readnum; j++) sd_data_read_s((u32)buff+j*512); SDCommand(12, 0, 0); get_resp(); send_clk(0x10); } //////////////////////////////////////////////////////////// get_resp: sd_com_read_s(r0 = ?, r1 = 6) //////////////////////////////////////////////////////////// void WriteSector(uint16 * buffer, uint32 sector, uint8 writenum) { register u16 i,j; u16 crc16[5]; i=writenum; sectno<<=9; SDCommand(25,0,sector); get_resp(); send_clk(0x10); for (j=0;j<i ; j++) { sd_crc16_s((u32)(u32)buff+j*512,512,(u32)crc16); sd_data_write_s((u32)buff+j*512,(u32)crc16); send_clk(0x10); } SDCommand(12,0,0); get_resp(); send_clk(0x10); while((*(u16*)sd_dataadd &0x0100)==0); } //////////////////////////////////////////////////////////// MemoryCard_IsInserted: return (SC_SD_COMMAND & 0x0300 == 0); NeoFlash (same as XG Flash v2 ?) Unlock sequence: 0x09555554:16 = 0xAAAA 0x08AAAAAA:16 = 0x5555 Any read to the AD mux bus will disable the 'unlock'. The following registers are on the compatible bus (0x0E00xxxx on the GBA, 0x0A00xxxx on the DS), and are thus 8 bits wide. Save memory type register (0xFFF8) 7 6 5 4 3 2 1 0 0 1 1 1 1 Mode Mode: * 000: 32 KB SRAM * 001: 64 KB Flash * 010: EEPROM * 101: 128 KB Flash (bankswitched with 0xB0) * dunno about other values Flash offset register (0xFFFE) 7 6 5 4 3 2 1 0 A23 A22 A21 A20 A19 A18 A17 A16 Save memory offset register (0xFFFF) 7 6 5 4 3 2 1 0 Fixed Shared SRAM EEPROM 1 H2 H1 H0 A15 A15 A14 A13 Notes: * The high address bits are shared for all 3 types of memory * EEPROM specific bits are only used for EEPROM * SRAM A15 should be zero when using Flash The flash chip (Intel Z412LA35A on the NeoFlash cart) can be erased/written after being unlocked. If anyone has chip names for Xg1 / Xg2 carts, I'd appreciate the information. EZFlash III The EZF-3 contains five chips: * 32 Mbit NOR flash (mapped in at boot-time) * 128 Mbit PSRAM * 256 Mbit NOR flash * 1 Gbit NAND flash * 2 Mbit SRAM Memory map in OS mode: * 0x08000000: 32 MBit NOR Flash * 0x08400000: 128 MBit PSRAM * 0x08800000: 64 MBit window into 256 MBit NOR flash (see ROM bank reg) * 0x08C00000: ? * 0x08FFE000: NAND flash interface Memory map in game mode: * 256 MBit NOR Flash * 128 MBit PSRAM * 32 MBit NOR Flash The offset into these for 0x08000000 is written to using the ROM page control register (e.g. if you wrote 0 for the page there, the 256 MBit of NOR would fill the cartridge bus, but writing 256 places the PSRAM in the space, ***I think***). // Each page is 1 Mbit void SetRomPage(uint16 page) { *(u16 *)0x9FE0000 = 0xD200; *(u16 *)0x8000000 = 0x1500; *(u16 *)0x8020000 = 0xD200; *(u16 *)0x8040000 = 0x1500; *(u16 *)0x9880000 = page; *(u16 *)0x9FC0000 = 0x1500; } ////////////////////////////////////////////////////////////////////// // Picks a page of SRAM to map in at 0x0E000000(gba) / 0x0A000000(ds) // Each page is 32 KB void SetRampage(uint16 page) { *(u16 *)0x9FE0000 = 0xD200; *(u16 *)0x8000000 = 0x1500; *(u16 *)0x8020000 = 0xD200; *(u16 *)0x8040000 = 0x1500; *(u16 *)0x9C00000 = page; *(u16 *)0x9FC0000 = 0x1500; } ////////////////////////////////////////////////////////////////////// // Enables writes to Flash? void OpenWrite() { *(u16 *)0x9FE0000 = 0xD200; *(u16 *)0x8000000 = 0x1500; *(u16 *)0x8020000 = 0xD200; *(u16 *)0x8040000 = 0x1500; *(u16 *)0x9C40000 = 0x1500; *(u16 *)0x9FC0000 = 0x1500; } ////////////////////////////////////////////////////////////////////// // Disables writes to Flash? void CloseWrite() { *(u16 *)0x9FE0000 = 0xD200; *(u16 *)0x8000000 = 0x1500; *(u16 *)0x8020000 = 0xD200; *(u16 *)0x8040000 = 0x1500; *(u16 *)0x9C40000 = 0xD200; *(u16 *)0x9FC0000 = 0x1500; } ////////////////////////////////////////////////////////////////////// void SetNandControl(uint16 control) { *(u16 *)0x9FE0000 = 0xD200; *(u16 *)0x8000000 = 0x1500; *(u16 *)0x8020000 = 0xD200; *(u16 *)0x8040000 = 0x1500; *(u16 *)0x9400000 = control; *(u16 *)0x9fc0000 = 0x1500; } ROM page control register: 15 1: OS mode, 0: Game mode 14 Dunno 13..12 Which 64 Mbit bank of NOR appears at 0x09400000 .. 0x09C00000 11..9 Dunno, could be more page register 8..0 Page register (in 1 MBit chunks) Bits 13 and 12 do not work in game mode. NAND interface: * 0xFFFFF0: WRITE COMMAND * FFFFF0: WRITE ADDRESS * 0xFFE000 TO 0xFFEFFF: R/W DATA NAND control register format: 15..2 ? 1 0: 8 bit mode, 1: 16 bit mode 0 0: Disabled, 1: Enabled Thanks to Davr and DarkFader for information on the EZF-3. Thanks to pepsiman for the info on enabling SDRAM for M3 / G6 / Supercard. Any information on the EZFA, F2A, and XgFlash 1 carts would be appreciated (and any others I'm not thinking of). ----

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。