├── README.md ├── bin └── nds.ldw ├── license └── src ├── nds.cpp ├── nds.dsp ├── nds.dsw └── nds.h /README.md: -------------------------------------------------------------------------------- 1 | # NDSLdr 2 | Nintendo DS ROM loader module for IDA Pro 3 | -------------------------------------------------------------------------------- /bin/nds.ldw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patois/NDSLdr/77faf245d615c8b5f2308110388462c988fb512b/bin/nds.ldw -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Dennis Elser 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/nds.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | IDA Loader module for Nintendo DS (NDS) ROM files. 3 | Written by Dennis Elser. 4 | Fixed / Updated by Franck Charlet (hitchhikr@australia.edu). 5 | 6 | Comments: 7 | --------- 8 | This is the first loader module for IDA 9 | I have written so far. It might therefore 10 | give inaccurate results. 11 | 12 | dennis[at]backtrace[dot]de / www[dot]backtrace[dot]de 13 | 14 | 15 | Credits: 16 | -------- 17 | - Rafael Vuijk for the CRC16 Code and the 18 | NDS ROM Header layout 19 | - DataRescue for providing loader sourcecode 20 | with the IDA SDK 21 | 22 | History: 23 | -------- 24 | 25 | 2004/12/29 initial version 26 | 27 | - can disassemble arm7 or arm9 code 28 | - can add additional information about 29 | the ROM to database 30 | 31 | 2005/01/01 version 1.1 32 | 33 | - creates a section for the whole RAM area 34 | and maps the cartridge's code into it 35 | - adds more additional information about 36 | the ROM to database 37 | 38 | 2006/01/17 version 1.11 39 | 40 | - updated sourcecode to be compatible with IDA4.8 SDK 41 | 42 | 2007/10/29 version 1.12 43 | 44 | - updated sourcecode to be compatible with IDA5.x SDK 45 | - added more infos in header structure 46 | - fixed the allowed memory ranges 47 | - added more infos in disassembled header 48 | 49 | 2008/07/17 version 1.13 50 | 51 | - correctly positioned at program's entry point 52 | - corrected the selection of processors 53 | 54 | */ 55 | 56 | #include 57 | #include "../idaldr.h" 58 | #include "nds.h" 59 | 60 | //defines 61 | #define version "v1.13" 62 | 63 | //global data 64 | nds_hdr hdr; 65 | 66 | //-------------------------------------------------------------------------- 67 | // 68 | // the code of CalcCRC16() has been taken from Rafael Vuijk's "ndstool" 69 | // and slightly been modified by me 70 | // 71 | unsigned short CalcCRC16(nds_hdr *ndshdr) 72 | { 73 | unsigned short crc16 = 0xFFFF; 74 | for(int i = 0; i < 350; i++) 75 | { 76 | unsigned char data = *((unsigned char *) ndshdr + i); 77 | crc16 = (crc16 >> 8) ^ crc16tab[(crc16 ^ data) & 0xFF]; 78 | } 79 | return crc16; 80 | } 81 | 82 | //-------------------------------------------------------------------------- 83 | // 84 | // check input file format. if recognized, then return 1 85 | // and fill 'fileformatname'. 86 | // otherwise return 0 87 | // 88 | int idaapi accept_file(linput_t *li, char fileformatname[MAX_FILE_FORMAT_NAME], int n) 89 | { 90 | 91 | ulong filelen; 92 | 93 | if( n!= 0 ) 94 | return 0; 95 | 96 | // get filesize 97 | filelen = qlsize(li); 98 | 99 | // quit, if file is smaller than size of NDS header 100 | if (filelen < sizeof(nds_hdr)) 101 | return 0; 102 | 103 | // set filepos to offset 0 104 | qlseek(li, 0, SEEK_SET); 105 | 106 | // read whole NDS header 107 | if(qlread(li, &hdr, sizeof(nds_hdr)) != sizeof(nds_hdr)) 108 | return 0; 109 | 110 | // check validity of CRC16 value of header 111 | // this is used to determine if this file is an NDS file 112 | if (CalcCRC16(&hdr) != hdr.headerCRC16) 113 | return 0; 114 | 115 | // this is the name of the file format which will be 116 | // displayed in IDA's dialog 117 | qstrncpy(fileformatname, "Nintendo DS ROM", MAX_FILE_FORMAT_NAME); 118 | 119 | // Default processor 120 | set_processor_type("ARM", SETPROC_ALL); 121 | 122 | return (1 | ACCEPT_FIRST); 123 | } 124 | 125 | //-------------------------------------------------------------------------- 126 | // 127 | // load file into the database. 128 | // 129 | void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) 130 | { 131 | 132 | int i; 133 | ea_t startEA; 134 | ea_t endEA; 135 | long offset; 136 | int ARM9; 137 | int found_mem_block; 138 | ea_t entry_point; 139 | 140 | // go to file-offset 0 141 | qlseek(li, 0, SEEK_SET); 142 | 143 | // and read the whole header 144 | qlread(li, &hdr, sizeof(nds_hdr)); 145 | 146 | // display a messagebox asking the user for details 147 | // 1 - Yes 148 | // 0 - No 149 | // -1 - Cancel 150 | int answer = askyn_cv(1, 151 | "NDS Loader by Dennis Elser.\n\n" 152 | "This file possibly contains ARM7 *and* ARM9 code.\n" 153 | "Choose \"Yes\" to load the ARM9 executable,\n" 154 | "\"No\" to load the ARM7 executable\n\n" 155 | "Please note that this loader has not been thoroughly tested!\n" 156 | "If you discover a bug, please let me know: dennis@backtrace.de\n" 157 | "\nDo you want to load the ARM9 code?\n\n" 158 | ,NULL 159 | ); 160 | 161 | // user chose "cancel" ? 162 | if(answer==BADADDR) 163 | { 164 | qexit(1); 165 | } 166 | 167 | // user chose "yes" = arm9 168 | if(answer) 169 | { 170 | set_processor_type("ARM", SETPROC_ALL); 171 | // init 172 | inf.startIP = inf.beginEA = hdr.arm9_entry_address; 173 | startEA = hdr.arm9_ram_address; 174 | endEA = hdr.arm9_ram_address + hdr.arm9_size; 175 | offset = hdr.arm9_rom_offset; 176 | ARM9 = TRUE; 177 | // sanitycheck 178 | if (qlsize(li) < offset+hdr.arm9_size) 179 | { 180 | qexit(1); 181 | } 182 | } 183 | // user chose "no" = arm7 184 | else 185 | { 186 | set_processor_type("ARM710A", SETPROC_ALL); 187 | // init 188 | inf.startIP = inf.beginEA = hdr.arm7_entry_address; 189 | startEA = hdr.arm7_ram_address; 190 | endEA = hdr.arm7_ram_address + hdr.arm7_size; 191 | offset = hdr.arm7_rom_offset; 192 | ARM9 = FALSE; 193 | // sanitycheck 194 | if(qlsize(li) < offset+hdr.arm7_size) 195 | { 196 | qexit(1); 197 | } 198 | } 199 | 200 | // check if segment lies within legal RAM blocks 201 | found_mem_block = FALSE; 202 | for(i = 0; i < sizeof(memory) / sizeof(MEMARRAY); i++) { 203 | if(startEA >= memory[i].start || endEA <= memory[i].end) 204 | { 205 | found_mem_block = TRUE; 206 | break; 207 | } 208 | } 209 | if(!found_mem_block) 210 | { 211 | qexit(1); 212 | } 213 | 214 | // map selector 215 | set_selector(1, 0); 216 | inf.start_cs = 1; 217 | 218 | // create a segment for the legal RAM blocks 219 | for(i = 0; i < sizeof(memory) / sizeof(MEMARRAY); i++) { 220 | if (!add_segm(1, memory[i].start, memory[i].end, "RAM", CLASS_CODE)) 221 | { 222 | qexit(1); 223 | } 224 | } 225 | 226 | // enable 32bit addressing 227 | set_segm_addressing(getseg( startEA ), 1); 228 | 229 | // load file into RAM area 230 | file2base(li, offset, startEA, endEA, FILEREG_PATCHABLE); 231 | 232 | entry_point = ARM9 == TRUE ? hdr.arm9_entry_address : hdr.arm7_entry_address; 233 | 234 | // add additional information about the ROM to the database 235 | describe(startEA, true, "; Created with NDS Loader %s.\n", version); 236 | describe(startEA, true, "; Author 1: dennis@backtrace.de"); 237 | describe(startEA, true, "; Author 2: hitchhikr@australia.edu\n"); 238 | describe(startEA, true, "; Game Title: %s\n", hdr.title); 239 | describe(startEA, true, "; Processor: ARM%c", ARM9 == TRUE ? '9' : '7'); 240 | describe(startEA, true, "; ROM Header size: 0x%08X", hdr.headerSize); 241 | describe(startEA, true, "; Header CRC: 0x%04X\n", hdr.headerCRC16); 242 | describe(startEA, true, "; Offset in ROM: 0x%08X", ARM9 == TRUE ? hdr.arm9_rom_offset : hdr.arm7_rom_offset); 243 | describe(startEA, true, "; Array: 0x%08X - 0x%08X (%d bytes)", startEA, endEA, ARM9 == TRUE ? hdr.arm9_size : hdr.arm7_size); 244 | describe(startEA, true, "; Entry point: 0x%08X\n", entry_point); 245 | 246 | describe(startEA, true, "; --- Beginning of ROM content ---", NULL); 247 | if(entry_point != startEA) 248 | { 249 | describe(entry_point, true, "; --- Entry point ---", NULL); 250 | } 251 | describe(endEA, true, "; --- End of ROM content ---", NULL); 252 | if(entry_point != BADADDR) 253 | { 254 | inf.start_cs = 0; 255 | inf.startIP = entry_point; 256 | } 257 | } 258 | 259 | //---------------------------------------------------------------------- 260 | // 261 | // LOADER DESCRIPTION BLOCK 262 | // 263 | //---------------------------------------------------------------------- 264 | loader_t LDSC = 265 | { 266 | IDP_INTERFACE_VERSION, 267 | 0, // loader flags 268 | // 269 | // check input file format. if recognized, then return 1 270 | // and fill 'fileformatname'. 271 | // otherwise return 0 272 | // 273 | accept_file, 274 | // 275 | // load file into the database. 276 | // 277 | load_file, 278 | // 279 | // create output file from the database. 280 | // this function may be absent. 281 | // 282 | NULL, 283 | NULL, 284 | NULL, 285 | }; 286 | -------------------------------------------------------------------------------- /src/nds.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="nds" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 6 | 7 | CFG=nds - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "nds.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "nds.mak" CFG="nds - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "nds - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") 21 | !MESSAGE "nds - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | MTL=midl.exe 30 | RSC=rc.exe 31 | 32 | !IF "$(CFG)" == "nds - Win32 Release" 33 | 34 | # PROP BASE Use_MFC 0 35 | # PROP BASE Use_Debug_Libraries 0 36 | # PROP BASE Output_Dir "Release" 37 | # PROP BASE Intermediate_Dir "Release" 38 | # PROP BASE Target_Dir "" 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir "Release" 42 | # PROP Intermediate_Dir "Release" 43 | # PROP Ignore_Export_Lib 0 44 | # PROP Target_Dir "" 45 | # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDS_EXPORTS" /YX /FD /c 46 | # ADD CPP /nologo /Gz /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDS_EXPORTS" /D "__IDP__" /D "__NT__" /FD /c 47 | # SUBTRACT CPP /YX 48 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 49 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 50 | # ADD BASE RSC /l 0x419 /d "NDEBUG" 51 | # ADD RSC /l 0x419 /d "NDEBUG" 52 | BSC32=bscmake.exe 53 | # ADD BASE BSC32 /nologo 54 | # ADD BSC32 /nologo 55 | LINK32=link.exe 56 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 57 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ida.lib /nologo /dll /pdb:none /machine:I386 /out:"..\..\loaders\nds.ldw" /libpath:"../../libvc.w32" /export:LDSC 58 | 59 | !ELSEIF "$(CFG)" == "nds - Win32 Debug" 60 | 61 | # PROP BASE Use_MFC 0 62 | # PROP BASE Use_Debug_Libraries 1 63 | # PROP BASE Output_Dir "Debug" 64 | # PROP BASE Intermediate_Dir "Debug" 65 | # PROP BASE Target_Dir "" 66 | # PROP Use_MFC 0 67 | # PROP Use_Debug_Libraries 1 68 | # PROP Output_Dir "Debug" 69 | # PROP Intermediate_Dir "Debug" 70 | # PROP Ignore_Export_Lib 0 71 | # PROP Target_Dir "" 72 | # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDS_EXPORTS" /YX /FD /GZ /c 73 | # ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDS_EXPORTS" /D "__IDP__" /D "__NT__" /FD /GZ /c 74 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 75 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 76 | # ADD BASE RSC /l 0x419 /d "_DEBUG" 77 | # ADD RSC /l 0x419 /d "_DEBUG" 78 | BSC32=bscmake.exe 79 | # ADD BASE BSC32 /nologo 80 | # ADD BSC32 /nologo 81 | LINK32=link.exe 82 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept 83 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ida.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"..\..\loaders\nds.ldw" /pdbtype:sept /libpath:"../../libvc.w32" /export:LDSC 84 | # SUBTRACT LINK32 /pdb:none 85 | 86 | !ENDIF 87 | 88 | # Begin Target 89 | 90 | # Name "nds - Win32 Release" 91 | # Name "nds - Win32 Debug" 92 | # Begin Group "Source Files" 93 | 94 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 95 | # Begin Source File 96 | 97 | SOURCE=.\nds.cpp 98 | # End Source File 99 | # End Group 100 | # Begin Group "Header Files" 101 | 102 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 103 | # Begin Source File 104 | 105 | SOURCE=.\nds.h 106 | # End Source File 107 | # End Group 108 | # Begin Group "Resource Files" 109 | 110 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 111 | # End Group 112 | # End Target 113 | # End Project 114 | -------------------------------------------------------------------------------- /src/nds.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "nds"=.\nds.dsp - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Global: 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<3> 25 | {{{ 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | -------------------------------------------------------------------------------- /src/nds.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | unsigned int start; 3 | unsigned int end; 4 | } MEMARRAY, *LPMEMARRAY; 5 | 6 | MEMARRAY memory[] = { 7 | { 0x02000000, 0x02800000 }, 8 | { 0x037F8000, 0x037FFFFF }, 9 | { 0x03800000, 0x0380FFFF }, 10 | }; 11 | 12 | typedef struct { 13 | 14 | char title[0xC]; 15 | char gamecode[0x4]; 16 | 17 | unsigned char makercode[2]; 18 | unsigned char unitcode; 19 | unsigned char devicetype; // type of device in the game card 20 | unsigned char deviceSize; // capacity 21 | unsigned char reserved1[0x9]; 22 | unsigned char romversion; 23 | unsigned char flags; 24 | 25 | unsigned int arm9_rom_offset; 26 | unsigned int arm9_entry_address; 27 | unsigned int arm9_ram_address; 28 | unsigned int arm9_size; 29 | 30 | unsigned int arm7_rom_offset; 31 | unsigned int arm7_entry_address; 32 | unsigned int arm7_ram_address; 33 | unsigned int arm7_size; 34 | 35 | unsigned int filenameSource; 36 | unsigned int filenameSize; 37 | unsigned int fatSource; 38 | unsigned int fatSize; 39 | 40 | unsigned int arm9overlaySource; 41 | unsigned int arm9overlaySize; 42 | unsigned int arm7overlaySource; 43 | unsigned int arm7overlaySize; 44 | 45 | unsigned int cardControl13; // 0x60 used in modes 1 and 3 46 | unsigned int cardControlBF; // 0x64 used in mode 2 47 | unsigned int bannerOffset; // 0x68 48 | 49 | unsigned short secureCRC16; // 0x6c 50 | 51 | unsigned short readTimeout; // 0x6e 52 | 53 | unsigned int unknownRAM1; // 0x70 54 | unsigned int unknownRAM2; // 0x74 55 | 56 | unsigned int bfPrime1; // 0x78 57 | unsigned int bfPrime2; // 0x7c 58 | unsigned int romSize; // 0x80 59 | 60 | unsigned int headerSize; // 0x84 61 | unsigned int zeros88[14]; // 0x88 62 | unsigned char gbaLogo[156]; // 0xc0 63 | unsigned short logoCRC16; // 0x15c 64 | unsigned short headerCRC16; // 0x15e 65 | 66 | unsigned int debugRomSource; // 0x160 67 | unsigned int debugRomSize; // 0x164 68 | unsigned int debugRomDestination; // 0x168 69 | unsigned int offset_0x16C; // 0x16c 70 | 71 | unsigned char zero[0x90]; // 0x170 72 | } nds_hdr; 73 | 74 | const unsigned short crc16tab[] = 75 | { 76 | 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 77 | 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 78 | 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 79 | 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 80 | 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 81 | 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 82 | 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 83 | 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 84 | 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 85 | 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 86 | 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 87 | 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 88 | 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 89 | 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 90 | 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 91 | 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 92 | 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 93 | 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 94 | 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 95 | 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 96 | 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 97 | 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 98 | 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 99 | 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 100 | 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 101 | 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 102 | 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 103 | 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 104 | 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 105 | 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 106 | 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 107 | 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 108 | }; --------------------------------------------------------------------------------