├── .gitignore ├── LICENSE ├── README.md ├── from_NRage_docs ├── MBC1 operation.txt ├── MBC3 Operation.txt ├── MBC5 interfaces.txt ├── Mbc1.gif ├── Transfer Pak.txt ├── mbc3.txt ├── mbc5.bmp ├── mbc5cpld.html └── mbc5cpld_files │ ├── bullet5.gif │ ├── cpldsche.gif │ ├── sim_i4o4.gif │ └── sim_rom.gif ├── schematic.png ├── setup.jpg └── src ├── arduinogbdump ├── arduinogbdump.pde ├── aux_code.cpp ├── aux_code.h ├── cart_helper_class.cpp ├── cart_helper_class.h ├── cart_helper_enums.h ├── cart_helper_mbc_funcs.h ├── misc_types.h ├── some_globals.cpp ├── some_globals.h ├── tags ├── tpak_class.cpp ├── tpak_class.h └── types_c.taghl └── communicator ├── concatenate_banks.sh ├── makefile └── src ├── communicator_class.cpp ├── communicator_class.hpp ├── main.cpp ├── misc_types.hpp ├── stuffs.cpp ├── stuffs.hpp ├── tags └── types_c.taghl /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2016 Andrew Clark (FL4SHK) 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | arduinogbdump 2 | ============= 3 | 4 | This is a project that can **create GB/GBC ROMs from real cartridges**, as 5 | well as **copy save data to/from real cartridges.** 6 | 7 | Required hardware: a **supported** Arduino, an N64 controller, an N64 8 | Transfer Pak, and a pull-up resistor. 9 | 10 | 11 | arduinogbdump is heavily based on brownan's [Gamecube-N64-Controller](https://github.com/brownan/Gamecube-N64-Controller) 12 | 13 | 14 | 15 | #Features/Compatibility 16 | **Note**: All GB and GBC **Pokemon** games *should* be possible to dump 17 | with arduinogbdump. Not every Pokemon game has been tested, but it is 18 | believed by the author that all Pokemon games use a supported MBC. 19 | 20 | There is currently support for dumping ROMs from cartridges of the 21 | following types: 22 | 1. ROM Only (32 kiB) 23 | 2. MBC1 24 | 3. MBC2 25 | 4. MBC3 26 | 5. MBC5 (*mostly* complete support, but only works for ROMs up to 4 MiB. 27 | However, the author doesn't know of any games that are larger than 4 MiB 28 | anyway.) 29 | 30 | 31 | There is currently support for dumping RAM from cartridges of the following 32 | types: 33 | 1. MBC1 34 | 2. MBC2 35 | 3. MBC3 (No RTC support yet) 36 | 4. MBC5 37 | 38 | 39 | There is currently support for restoring RAM to cartridges of the following 40 | types: 41 | 1. MBC1 42 | 2. MBC3 (No RTC support yet) 43 | 3. MBC5 44 | 45 | 46 | All testing of the communicator program has been done on *Linux*. It is not 47 | known whether it would even compile on other systems, but there's a good 48 | chance of it working on other Unices (such as FreeBSD). 49 | 50 | 51 | #How to Connect the Arduino Board to the N64 Controller 52 | Here is a schematic of the setup: 53 | ![schematic.png](schematic.png) 54 | 55 | Note that the *Arduino* pins used for everything are intended to be the 56 | same **no matter which type of Arduino is used**. 57 | 58 | Also, here is a photo of the setup (taken in January, 2015): 59 | ![setup.jpg](setup.jpg) 60 | 61 | **Note**: It is **not necessary** to break the N64 62 | controller's cable (though the controller cable can certainly be 63 | re-connected if the user chooses to break it). Wires can be inserted into 64 | the holes at the end of the N64 controller's cable. The holes correspond 65 | to the red, white, and black wires of the N64 controller. 66 | [Here](http://s.hswstatic.com/gif/n64-pinout.gif) is a schematic of the N64 67 | controller's connector. 68 | 69 | 70 | 71 | #Arduino Board Compatibility 72 | As is the case with the Gamecube-N64-Controller project, the Arduino <-> 73 | N64 controller timing code is specific to Arduino boards with 8-bit AVRs 74 | clocked at 16 MHz. 75 | 76 | The following Arduino boards *have been tested* and are working with this 77 | project for sure: 78 | 1. Arduino Micro 79 | 2. Arduino Mega 2560 80 | 81 | However, it is *likely* that the other Arduino boards that use the following 82 | AVR microcontrollers would work as well: 83 | 1. ATmega32U4 (includes the **Arduino Leonardo**) 84 | 2. ATmega1280 (includes the original **Arduino Mega**) 85 | 3. ATmega2560 (This is what the Arduino Mega 2560 uses.) 86 | 87 | Support for the Arduino Uno is planned as well. 88 | 89 | #Credits/Thanks 90 | As previously mentioned, arduinogbdump is heavily based on [This](https://github.com/brownan/Gamecube-N64-Controller) 91 | 92 | The 1964 emulator and the NRage plugin (compiled with debugging functions) 93 | were really helpful in figuring out how real games (Pokemon Stadium 2 in 94 | particular) used the Transfer Pak. The NRage docs were also instrumental 95 | for getting this to work. Some of them have been included with this 96 | project for reference. 97 | 98 | The two CRC-related functions were taken from libdragon (though only one of 99 | them is in use). 100 | 101 | There were also various websites whose URLs escape me. 102 | 103 | Additionally, the folks of IRC channel #n64dev on EFnet have been very 104 | helpful, especially when I was first working on this project in Spring 105 | 2013. 106 | 107 | 108 | -------------------------------------------------------------------------------- /from_NRage_docs/MBC1 operation.txt: -------------------------------------------------------------------------------- 1 | Writing a value into 0x2000-0x3FFF will select the ROM bank to use. only 2 | the lower 4 bits of this value are used. If the selected bank, after 3 | shedding th unused bits, is 0x00, then the bank is set to 0x01 4 | 5 | -------------------------------------------------------------------------------- /from_NRage_docs/MBC3 Operation.txt: -------------------------------------------------------------------------------- 1 | Please note, that this document describes reading/writing on the actual cartridge, disregarding all internal gameboy architecture. 2 | 3 | Writing a value to 0x2000-0x3FFF will set the current selected ROM bank. This bank is located at 0x4000-0x7FFF. Also, when bank 0 is selected, it is remapped to be bank 1. Bank 1 is the default selection. 4 | 5 | When selecting the ROM bank, if you specify a bank number >= 0x40, the number will roll back to 0x00 6 | 7 | 8 | Writing a value to 0x4000-0x5FFF will set the current RAM bank, accessable at 0xA000-0xBFFF. if a value >= 0x04 is given, the value will cycle back to 0x00. Bank 0 is the default selection. 9 | 10 | Memory Map: 11 | 0x0000-0x3FFF = ROM Bank 0, unswitchable 12 | 0x0000-0x1FFF (Write) = RAM Bank Write Enable (0x0A = Enable, 0x00 = Disable) 13 | 0x2000-0x3FFF (Write) = ROM Bank Select (0x00-0x3F) 14 | 0x4000-0x7FFF = ROM Bank X, switchable 15 | 0x4000-0x5FFF (Write) = RAM Bank Select (0x00-0x03) 16 | 0x6000-0x7FFF (Write) = Counter Latch (0x00=unlatch, 0x01=latch) 17 | 0x8000-0x9FFF = Memory hole (returns 0x00) 18 | 0xA000-0xBFFF = Cartridge RAM, switchable 19 | 0xC000-0xFFFF = Memory hole (returns 0x00) 20 | -------------------------------------------------------------------------------- /from_NRage_docs/MBC5 interfaces.txt: -------------------------------------------------------------------------------- 1 | MBC5: 2 | 3 | 4 | Specs, the MBC5 memory sizes in short : 5 | 6 | - ROM upto 64MBit (8MByte) divided into 512 banks, each 16kByte. 7 | - RAM upto 1MBit (128kByte) divided into 16 banks, each 8kByte 8 | 9 | 10 | Memory map for the MBC5/CPLD 11 | 12 | MBC5 memory bank switching is obtained by writing the high order adress mask for the 13 | memory space in question into latches memorymapped into the normal ROM adresses space 14 | as given in the following list. 15 | 16 | ----------------------------------------------------------------------------------------- 0x5000 17 | RAM Bank Register (RAMB) 18 | Switchable RAM bank select (4 AA bits) 19 | XXXX BBBB 20 | ----------------------------------------------------------------------------------------- 0x4000 21 | Upper ROM Bank Register (ROMB1) 22 | Switchable ROM bank high select (9th RA bit) 23 | XXXX XXXH 24 | ----------------------------------------------------------------------------------------- 0x3000 25 | Lower ROM Bank Register (ROMB0) 26 | Switchable ROM bank low select (First 8 RA bits) 27 | LLLL LLLL 28 | ----------------------------------------------------------------------------------------- 0x2000 29 | External Extended Memory Register (RAMG) 30 | (This is ram enable on original MBC5 with 0x0A) 31 | 7 6 5 4 3 2 1 0 32 | | | | 33 | | | 1 = RAM write enable 34 | | | 0 = RAM write inhibit 35 | | | 36 | | 1 = LED on 37 | | 0 = LED off 38 | | 39 | 1 = IO enable 40 | 0 = IO disable 41 | ----------------------------------------------------------------------------------------- 0x0000 42 | 43 | After reset : RAMB = bank 0, ROMBx = bank 0, RAMG = 0, LED off and i/o disabled. 44 | -------------------------------------------------------------------------------- /from_NRage_docs/Mbc1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/Mbc1.gif -------------------------------------------------------------------------------- /from_NRage_docs/Transfer Pak.txt: -------------------------------------------------------------------------------- 1 | This is all the information I was able to decode from Transfer Pak captures. 2 | 3 | Writes: 4 | 5 | Addresses C000-FFFF access the GB cart. The actual address written is calculated by gbAddress = (dwAddress & 0x3FFF) | ((TPakCurrentBank & 3) * 0x4000) 6 | Addresses 8000-8FFF is used to set some flags on the TPak. It's not known what bits mean what, but it is used to enable/disable the GB cart and some spects of the TPak. 7 | Addresses A000-AFFF is used to set the current TPak bank. This is used when reading/writing the GB Cart. 8 | Addresses B000-BFFF is used to set some access mode of some sort. It's not known what this is used for. 9 | 10 | Reads: 11 | 12 | Addresses 8000-8FFF is used to query the enable state. 1 = enabled, 0 = disabled. 13 | Addresses B000-BFFF is used to query the cart enable state: 14 | Returns 0x89 when access mode = 1, 0x80 when mode = 0 15 | Sets bit 2 of the first return value if the access mode was recently changed. Will not set bit 2 again untill access mode is changed again. 16 | Addresses C000-FFFF is used to read the GB Cart. See whe Writes section to find out how to derive the GB Cart address. 17 | -------------------------------------------------------------------------------- /from_NRage_docs/mbc3.txt: -------------------------------------------------------------------------------- 1 | Memory Bank Controller (MBC) 3 for GameBoy Information 2 | 3 | by bRILLO hEAD, 1-Jan-98 4 | 5 | The MBC3 is a memory controller for some GameBoy carts 6 | that supports 7 | ROMs up to 16megabits (2megabytes) and RAM up to 256kbits 8 | (32kbytes). It has a built-in clock counter that requires 9 | an external 32.768KHz crystal for operation. 10 | 11 | Reg 0 - $0000-$1fff - RAM/clock write protect 12 | 13 | $0A - Enable 14 | $00 - Disable 15 | 16 | Reg 1 - $2000-$3fff - ROM Bank Select 17 | 18 | $00-$3F - Rom bank # 19 | 20 | Reg 2 - $4000-$5fff - RAM Bank/Clock Reg Select 21 | 22 | $00-$03 - RAM bank # 23 | $08-$0c - Clock register # 24 | 25 | Reg 3 - $6000-$7fff - Latch clock counter data 26 | 27 | Writing $00 and then $01 latches clock data. 28 | Another write $00 and write $01 is required 29 | to latch data again. 30 | 31 | Reg SEC - $08 - Seconds counter 32 | 33 | Reg MIN - $09 - Minutes counter 34 | 35 | Reg HRS - $0A - Hours counter 36 | 37 | Reg DAYL- $0B - Lower 8 bits of day counter 38 | 39 | Reg DAYH- $0C - bit 0 = Upper 1 bit of day counter 40 | bit 6 = start(0)/stop(1) clock counter 41 | bit 7 = Day counter carry bit 42 | 43 | 44 | Notes: 45 | 46 | Bit 7 of Reg DAYH once set stays set until a 0 is written. 47 | 48 | To access the clock counter the ram bank must first be turned 49 | on by writing $0A to Reg 0. 50 | 51 | To read the clock counter value, set Reg 3 to $01. This latches 52 | the values of all registers so they won't change on you while your 53 | trying to read them. However, this does not prevent the internal 54 | counters from keeping correct time. If reg 3 is already set to 55 | $01 then write $00 and then $01. 56 | 57 | For example, to read Reg SEC write $08 to Reg 2. The value of 58 | Reg SEC can then be read from any address in $A000-$BFFF range. 59 | Use a similar process for writing to a register. 60 | 61 | Due to slow MBC3/clock interfacing, 4 machine cycles (16 clock cycles) 62 | are required between register accesses. 63 | -------------------------------------------------------------------------------- /from_NRage_docs/mbc5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5.bmp -------------------------------------------------------------------------------- /from_NRage_docs/mbc5cpld.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5cpld.html -------------------------------------------------------------------------------- /from_NRage_docs/mbc5cpld_files/bullet5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5cpld_files/bullet5.gif -------------------------------------------------------------------------------- /from_NRage_docs/mbc5cpld_files/cpldsche.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5cpld_files/cpldsche.gif -------------------------------------------------------------------------------- /from_NRage_docs/mbc5cpld_files/sim_i4o4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5cpld_files/sim_i4o4.gif -------------------------------------------------------------------------------- /from_NRage_docs/mbc5cpld_files/sim_rom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/from_NRage_docs/mbc5cpld_files/sim_rom.gif -------------------------------------------------------------------------------- /schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/schematic.png -------------------------------------------------------------------------------- /setup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fl4shk/arduinogbdump/cc6e9fa79081d80312aade68c6fcfd3db4bc419b/setup.jpg -------------------------------------------------------------------------------- /src/arduinogbdump/arduinogbdump.pde: -------------------------------------------------------------------------------- 1 | #include "misc_types.h" 2 | 3 | #include "some_globals.h" 4 | #include "aux_code.h" 5 | #include "tpak_class.h" 6 | #include "cart_helper_class.h" 7 | 8 | 9 | 10 | void setup() 11 | { 12 | memset( N64_raw_dump, 0, 33 ); 13 | 14 | 15 | pinMode( 13, OUTPUT ); 16 | 17 | // Communication with gamecube controller on this pin 18 | // Don't remove these lines, we don't want to push +5V to the controller 19 | digitalWrite( N64_PIN, LOW ); 20 | pinMode( N64_PIN, INPUT ); 21 | 22 | 23 | // Initialize the gamecube controller by sending it a null byte. This 24 | // is unnecessary for a standard controller, but is required for the 25 | // Wavebird. 26 | unsigned char initialize = 0x00; 27 | noInterrupts(); 28 | N64_send( &initialize, 1 ); 29 | N64_read_addr(); 30 | 31 | 32 | // Stupid routine to wait for the gamecube controller to stop 33 | // sending its response. We don't care what it is, but we 34 | // can't start asking for status if it's still responding 35 | int x; 36 | for ( x=0; x<64; x++ ) 37 | { 38 | // make sure the line is idle for 64 iterations, should 39 | // be plenty.x 40 | 41 | if (!N64_QUERY) 42 | { 43 | x = 0; 44 | 45 | //digitalWrite( 13, HIGH ); 46 | //delay(200); 47 | //digitalWrite( 13, LOW ); 48 | } 49 | } 50 | 51 | // Query for the gamecube controller's status. We do this 52 | // to get the 0 point for the control stick. 53 | //unsigned char command[] = { 0x01 }; 54 | //N64_send( command, 1 ); 55 | // read in data and dump it to N64_raw_dump 56 | //N64_get(); 57 | interrupts(); 58 | 59 | Serial.begin(115200); 60 | 61 | // 2 ms timeout 62 | Serial.setTimeout(2); 63 | 64 | //tpak_stuff_2(); 65 | } 66 | 67 | 68 | void loop() 69 | { 70 | tpak_stuff_2(); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/arduinogbdump/aux_code.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "aux_code.h" 3 | #include "tpak_class.h" 4 | #include "cart_helper_class.h" 5 | 6 | 7 | 8 | 9 | void print_mem_managed() 10 | { 11 | for ( int i=0; i 0 ) 91 | { 92 | if ( hamburger.interpret_serial_message() == 1 ) 93 | { 94 | return; 95 | } 96 | } 97 | } 98 | } 99 | 100 | void translate_raw_data() 101 | { 102 | // The get_N64_status function sloppily dumps its data 1 bit per byte 103 | // into the get_status_extended char array. It's our job to go through 104 | // that and put each piece neatly into the struct N64_status 105 | int i; 106 | memset(&N64_status, 0, sizeof(N64_status)); 107 | // line 1 108 | // bits: A, B, Z, Start, Dup, Ddown, Dleft, Dright 109 | for (i=0; i<8; i++) { 110 | N64_status.data1 |= N64_raw_dump[i] ? (0x80 >> i) : 0; 111 | } 112 | // line 2 113 | // bits: 0, 0, L, R, Cup, Cdown, Cleft, Cright 114 | for (i=0; i<8; i++) { 115 | N64_status.data2 |= N64_raw_dump[8+i] ? (0x80 >> i) : 0; 116 | } 117 | // line 3 118 | // bits: joystick x value 119 | // These are 8 bit values centered at 0x80 (128) 120 | for (i=0; i<8; i++) { 121 | N64_status.stick_x |= N64_raw_dump[16+i] ? (0x80 >> i) : 0; 122 | } 123 | for (i=0; i<8; i++) { 124 | N64_status.stick_y |= N64_raw_dump[24+i] ? (0x80 >> i) : 0; 125 | } 126 | } 127 | 128 | 129 | /** 130 | * This sends the given byte sequence to the controller 131 | * length must be at least 1 132 | * Oh, it destroys the buffer passed in as it writes it 133 | */ 134 | void N64_send(unsigned char *buffer, char length) 135 | { 136 | // Send these bytes 137 | char bits; 138 | 139 | bool bit; 140 | 141 | // This routine is very carefully timed by examining the assembly 142 | // output. Do not change any statements, it could throw the timings 143 | // off. 144 | // 145 | // We get 16 cycles per microsecond, which should be plenty, but we 146 | // need to be conservative. Most assembly ops take 1 cycle, but a few 147 | // take 2. 148 | // 149 | // I use manually constructed for-loops out of gotos so I have more 150 | // control over the outputted assembly. I can insert nops where it was 151 | // impossible with a for loop. 152 | 153 | asm volatile (";Starting outer for loop"); 154 | outer_loop: 155 | { 156 | asm volatile (";Starting inner for loop"); 157 | bits=8; 158 | inner_loop: 159 | { 160 | // Starting a bit, set the line low 161 | asm volatile (";Setting line to low"); 162 | N64_LOW; // 1 op, 2 cycles 163 | 164 | asm volatile (";branching"); 165 | if (*buffer >> 7) { 166 | asm volatile (";Bit is a 1"); 167 | // 1 bit 168 | // remain low for 1us, then go high for 3us 169 | // nop block 1 170 | asm volatile ("nop\nnop\nnop\nnop\nnop\n"); 171 | 172 | asm volatile (";Setting line to high"); 173 | N64_HIGH; 174 | 175 | // nop block 2 176 | // we'll wait only 2us to sync up with both conditions 177 | // at the bottom of the if statement 178 | asm volatile ("nop\nnop\nnop\nnop\nnop\n" 179 | "nop\nnop\nnop\nnop\nnop\n" 180 | "nop\nnop\nnop\nnop\nnop\n" 181 | "nop\nnop\nnop\nnop\nnop\n" 182 | "nop\nnop\nnop\nnop\nnop\n" 183 | "nop\nnop\nnop\nnop\nnop\n" 184 | ); 185 | 186 | } else { 187 | asm volatile (";Bit is a 0"); 188 | // 0 bit 189 | // remain low for 3us, then go high for 1us 190 | // nop block 3 191 | asm volatile ("nop\nnop\nnop\nnop\nnop\n" 192 | "nop\nnop\nnop\nnop\nnop\n" 193 | "nop\nnop\nnop\nnop\nnop\n" 194 | "nop\nnop\nnop\nnop\nnop\n" 195 | "nop\nnop\nnop\nnop\nnop\n" 196 | "nop\nnop\nnop\nnop\nnop\n" 197 | "nop\nnop\nnop\nnop\nnop\n" 198 | "nop\n"); 199 | 200 | asm volatile (";Setting line to high"); 201 | N64_HIGH; 202 | 203 | // wait for 1us 204 | asm volatile ("; end of conditional branch, need to wait 1us more before next bit"); 205 | 206 | } 207 | // end of the if, the line is high and needs to remain 208 | // high for exactly 16 more cycles, regardless of the previous 209 | // branch path 210 | 211 | asm volatile (";finishing inner loop body"); 212 | --bits; 213 | if (bits != 0) { 214 | // nop block 4 215 | // this block is why a for loop was impossible 216 | asm volatile ("nop\nnop\nnop\nnop\nnop\n" 217 | "nop\nnop\nnop\nnop\n"); 218 | // rotate bits 219 | asm volatile (";rotating out bits"); 220 | *buffer <<= 1; 221 | 222 | goto inner_loop; 223 | } // fall out of inner loop 224 | } 225 | asm volatile (";continuing outer loop"); 226 | // In this case: the inner loop exits and the outer loop iterates, 227 | // there are /exactly/ 16 cycles taken up by the necessary operations. 228 | // So no nops are needed here (that was lucky!) 229 | --length; 230 | if (length != 0) { 231 | ++buffer; 232 | goto outer_loop; 233 | } // fall out of outer loop 234 | } 235 | 236 | // send a single stop (1) bit 237 | // nop block 5 238 | asm volatile ("nop\nnop\nnop\nnop\n"); 239 | N64_LOW; 240 | // wait 1 us, 16 cycles, then raise the line 241 | // 16-2=14 242 | // nop block 6 243 | asm volatile ("nop\nnop\nnop\nnop\nnop\n" 244 | "nop\nnop\nnop\nnop\nnop\n" 245 | "nop\nnop\nnop\nnop\n"); 246 | N64_HIGH; 247 | 248 | } 249 | 250 | void N64_get() 251 | { 252 | // listen for the expected 8 bytes of data back from the controller and 253 | // blast it out to the N64_raw_dump array, one bit per byte for extra speed. 254 | // Afterwards, call translate_raw_data() to interpret the raw data and pack 255 | // it into the N64_status struct. 256 | asm volatile (";Starting to listen"); 257 | unsigned char timeout; 258 | char bitcount = 32; 259 | char *bitbin = N64_raw_dump; 260 | 261 | // Again, using gotos here to make the assembly more predictable and 262 | // optimization easier (please don't kill me) 263 | read_loop: 264 | timeout = 0x3f; 265 | // wait for line to go low 266 | while (N64_QUERY) { 267 | if (!--timeout) 268 | return; 269 | } 270 | // wait approx 2us and poll the line 271 | asm volatile ( 272 | "nop\nnop\nnop\nnop\nnop\n" 273 | "nop\nnop\nnop\nnop\nnop\n" 274 | "nop\nnop\nnop\nnop\nnop\n" 275 | "nop\nnop\nnop\nnop\nnop\n" 276 | "nop\nnop\nnop\nnop\nnop\n" 277 | "nop\nnop\nnop\nnop\nnop\n" 278 | ); 279 | *bitbin = N64_QUERY; 280 | ++bitbin; 281 | --bitcount; 282 | if (bitcount == 0) 283 | return; 284 | 285 | // wait for line to go high again 286 | // it may already be high, so this should just drop through 287 | timeout = 0x3f; 288 | while (!N64_QUERY) { 289 | if (!--timeout) 290 | return; 291 | } 292 | goto read_loop; 293 | 294 | } 295 | 296 | void loop2() 297 | { 298 | // Command to send to the gamecube 299 | // The last bit is rumble, flip it to rumble 300 | // yes this does need to be inside the loop, the 301 | // array gets mutilated when it goes through N64_send 302 | unsigned char command[] = {0x01}; 303 | 304 | // don't want interrupts getting in the way 305 | noInterrupts(); 306 | // send those 3 bytes 307 | //N64_send(command, 1); 308 | // read in data and dump it to N64_raw_dump 309 | //N64_get(); 310 | // end of time sensitive code 311 | interrupts(); 312 | 313 | delay(25); 314 | 315 | } 316 | 317 | 318 | word calc_addr_crc ( word address ) 319 | { 320 | /* CRC table */ 321 | uint16_t xor_table[16] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x1F, 0x0B, 0x16, 0x19, 0x07, 0x0E, 0x1C, 0x0D, 0x1A, 0x01 }; 322 | uint16_t crc = 0; 323 | 324 | /* Make sure we have a valid address */ 325 | address &= ~0x1F; 326 | 327 | /* Go through each bit in the address, and if set, xor the right value into the output */ 328 | for( int i = 15; i >= 5; i-- ) 329 | { 330 | /* Is this bit set? */ 331 | if( ((address >> i) & 0x1) ) 332 | { 333 | crc ^= xor_table[i]; 334 | } 335 | } 336 | 337 | /* Just in case */ 338 | crc &= 0x1F; 339 | 340 | /* Create a new address with the CRC appended */ 341 | return address | crc; 342 | } 343 | 344 | unsigned char calc_data_crc( unsigned char *data ) 345 | { 346 | unsigned char ret = 0; 347 | 348 | for( int i = 0; i <= 32; i++ ) 349 | { 350 | for( int j = 7; j >= 0; j-- ) 351 | { 352 | int tmp = 0; 353 | 354 | if( ret & 0x80 ) 355 | { 356 | tmp = 0x85; 357 | } 358 | 359 | ret <<= 1; 360 | 361 | if( i < 32 ) 362 | { 363 | if( data[i] & (0x01 << j) ) 364 | { 365 | ret |= 0x1; 366 | } 367 | } 368 | 369 | ret ^= tmp; 370 | } 371 | } 372 | 373 | return ret; 374 | } 375 | 376 | void N64_read_addr() 377 | { 378 | // listen for the expected 8 bytes of data back from the controller and 379 | // blast it out to the N64_raw_dump array, one bit per byte for extra speed. 380 | // Afterwards, call translate_raw_data() to interpret the raw data and pack 381 | // it into the N64_status struct. 382 | asm volatile (";Starting to listen"); 383 | unsigned char timeout; 384 | word bitcount = N64_mem_size; 385 | char *bitbin = N64_mem_dump; 386 | 387 | // Again, using gotos here to make the assembly more predictable and 388 | // optimization easier (please don't kill me) 389 | read_loop: 390 | timeout = 0x3f; 391 | // wait for line to go low 392 | while (N64_QUERY) { 393 | if (!--timeout) 394 | return; 395 | } 396 | // wait approx 2us and poll the line 397 | asm volatile ( 398 | "nop\nnop\nnop\nnop\nnop\n" 399 | "nop\nnop\nnop\nnop\nnop\n" 400 | "nop\nnop\nnop\nnop\nnop\n" 401 | "nop\nnop\nnop\nnop\nnop\n" 402 | "nop\nnop\nnop\nnop\nnop\n" 403 | "nop\nnop\nnop\nnop\nnop\n" 404 | ); 405 | *bitbin = N64_QUERY; 406 | ++bitbin; 407 | --bitcount; 408 | if (bitcount == 0) 409 | return; 410 | 411 | // wait for line to go high again 412 | // it may already be high, so this should just drop through 413 | timeout = 0x3f; 414 | while (!N64_QUERY) { 415 | if (!--timeout) 416 | return; 417 | } 418 | goto read_loop; 419 | 420 | } 421 | 422 | 423 | 424 | bool cmp_buf( const char* to_cmp, int num_recv ) 425 | { 426 | return ( strncmp( buf, to_cmp, num_recv ) == 0 ); 427 | } 428 | -------------------------------------------------------------------------------- /src/arduinogbdump/aux_code.h: -------------------------------------------------------------------------------- 1 | #ifndef aux_code_h 2 | #define aux_code_h 3 | 4 | #include "some_globals.h" 5 | #include "pins_arduino.h" 6 | 7 | 8 | #if ( defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) ) 9 | #define PORT_THING default_bitwise_thing 10 | #elif defined (__AVR_ATmega32U4__) 11 | #define PORT_THING micro_bitwise_thing 12 | #elif ( defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) ) 13 | #define PORT_THING mega_bitwise_thing 14 | #else 15 | #error This program doesn't work on your Arduino (yet)! 16 | #endif 17 | 18 | 19 | // This should be used for the Arduino Uno. 20 | static const byte default_bitwise_thing = 0x04; 21 | 22 | // This should be used for the Arduino Micro or Arduino Leonardo. 23 | static const byte micro_bitwise_thing = 0x02; 24 | 25 | 26 | //// If I knew the correct value for the Arduino Mega, I would have said to 27 | //// use this for it. 28 | // This should be used for the Arduino Mega or Arduino Mega 2560. 29 | static const byte mega_bitwise_thing = 0x10; 30 | 31 | 32 | 33 | #define N64_PIN 2 34 | //#define N64_PIN_DIR DDRD 35 | 36 | // these two macros set arduino pin 2 to input or output, which with an 37 | // external 1K pull-up resistor to the 3.3V rail, is like pulling it high or 38 | // low. These operations translate to 1 op code, which takes 2 cycles 39 | #if ( defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) ) 40 | #define N64_HIGH DDRD &= ~PORT_THING 41 | #define N64_LOW DDRD |= PORT_THING 42 | #define N64_QUERY (PIND & PORT_THING) 43 | #elif defined (__AVR_ATmega32U4__) 44 | #define N64_HIGH DDRD &= ~PORT_THING 45 | #define N64_LOW DDRD |= PORT_THING 46 | #define N64_QUERY (PIND & PORT_THING) 47 | #elif ( defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) ) 48 | #define N64_HIGH DDRE &= ~PORT_THING 49 | #define N64_LOW DDRE |= PORT_THING 50 | #define N64_QUERY (PINE & PORT_THING) 51 | #else 52 | #error This program doesn't work on your Arduino (yet)! 53 | #endif 54 | 55 | 56 | 57 | void print_mem_managed(); 58 | void print_mem_managed2(); 59 | void write_mem_managed(); 60 | 61 | void print_crc_managed(); 62 | 63 | void clear_mem_dump(); 64 | 65 | void manage_mem_dump(); // arrange data into bytes 66 | 67 | 68 | 69 | void N64_stuff( unsigned char *buff, char length ); 70 | 71 | 72 | void N64_stuff_2( unsigned char *buff, char length ); 73 | 74 | 75 | void tpak_stuff_2(); 76 | 77 | 78 | void tpak_stuff(); 79 | 80 | 81 | void translate_raw_data(); 82 | 83 | 84 | 85 | /** 86 | * This sends the given byte sequence to the controller 87 | * length must be at least 1 88 | * Oh, it destroys the buffer passed in as it writes it 89 | */ 90 | void N64_send(unsigned char *buffer, char length); 91 | 92 | 93 | void N64_get(); 94 | 95 | 96 | void loop2(); 97 | 98 | 99 | word calc_addr_crc( word address ); 100 | 101 | 102 | unsigned char calc_data_crc( unsigned char *data ); 103 | 104 | void N64_read_addr(); 105 | 106 | 107 | bool cmp_buf( const char* to_cmp, int num_recv ); 108 | 109 | 110 | #endif // aux_code_h 111 | -------------------------------------------------------------------------------- /src/arduinogbdump/cart_helper_class.cpp: -------------------------------------------------------------------------------- 1 | #include "aux_code.h" 2 | #include "cart_helper_class.h" 3 | 4 | 5 | cart_helper::cart_helper() 6 | { 7 | my_tpak.init(*this); 8 | } 9 | 10 | cart_helper::~cart_helper() 11 | { 12 | } 13 | 14 | void cart_helper::set_cart_stuff() 15 | { 16 | clear_mem_dump(); 17 | my_tpak.read(0xC140); 18 | manage_mem_dump(); //print_mem_managed(); 19 | delay(100); 20 | 21 | 22 | set_raw_data( N64_mem_managed[7], N64_mem_managed[8], 23 | N64_mem_managed[9] ); 24 | interpret_raw_data(); 25 | 26 | //mbc = N64_mem_managed[7]; 27 | //rom_size = N64_mem_managed[8]; 28 | //ram_size = N64_mem_managed[9]; 29 | //set_num_rom_banks(); 30 | //set_num_ram_kb(); 31 | 32 | ////print_cart_stuff(); 33 | } 34 | 35 | void cart_helper::print_cart_stuff() 36 | { 37 | print_raw_data(); 38 | 39 | switch (cart_mbc_type) 40 | { 41 | // No MBC at all 42 | case rom_only: 43 | Serial.println("MBC type: None"); 44 | break; 45 | 46 | // MBC1 47 | case mbc1: 48 | case mbc1_ram: 49 | Serial.println("MBC type: MBC1"); 50 | break; 51 | 52 | // MBC2 53 | case mbc2: 54 | Serial.println("MBC type: MBC2"); 55 | break; 56 | 57 | // MBC3 58 | case mbc3: 59 | case mbc3_timer: 60 | case mbc3_timer_ram: 61 | case mbc3_ram: 62 | Serial.println("MBC type: MBC3"); 63 | break; 64 | 65 | // MBC5 66 | case mbc5: 67 | case mbc5_ram: 68 | Serial.println("MBC type: MBC5"); 69 | //Serial.println("MBC type: MBC5, with external RAM"); 70 | break; 71 | 72 | // Something else 73 | case unknown_mbc_type: 74 | Serial.println("Unknown MBC type."); 75 | break; 76 | } 77 | 78 | Serial.print("This cartridge has "); 79 | Serial.print( rom_size, DEC ); 80 | Serial.println(" ROM banks."); 81 | 82 | 83 | switch (ram_size) 84 | { 85 | case rs_none: 86 | Serial.println("This cartridge has no external RAM."); 87 | break; 88 | 89 | case rs_2: 90 | Serial.println("This cartridge has 2 kiB of external RAM."); 91 | break; 92 | 93 | case rs_8: 94 | Serial.println("This cartridge has 8 kiB of external RAM."); 95 | break; 96 | 97 | case rs_32: 98 | Serial.println("This cartridge has 32 kiB of external RAM."); 99 | break; 100 | 101 | case rs_128: 102 | Serial.println("This cartridge has 128 kiB of external RAM."); 103 | break; 104 | 105 | case rs_mbc2: 106 | Serial.println("This cartridge has no external RAM, but it" 107 | "does have an MBC2. MBC2's have built-in RAM."); 108 | break; 109 | 110 | 111 | } 112 | } 113 | 114 | void cart_helper::set_raw_data( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size, 115 | uint8_t s_raw_ram_size ) 116 | { 117 | raw_cart_type = s_raw_cart_type; 118 | raw_rom_size = s_raw_rom_size; 119 | raw_ram_size = s_raw_ram_size; 120 | } 121 | 122 | void cart_helper::print_raw_data() 123 | { 124 | Serial.println( raw_cart_type, HEX ); 125 | Serial.println( raw_rom_size, HEX ); 126 | Serial.println( raw_ram_size, HEX ); 127 | } 128 | 129 | void cart_helper::interpret_raw_data() 130 | { 131 | // Set the value of the MBC 132 | switch (raw_cart_type) 133 | { 134 | // No MBC 135 | case 0x00: 136 | cart_mbc_type = rom_only; 137 | break; 138 | 139 | // MBC1 140 | case 0x01: 141 | cart_mbc_type = mbc1; 142 | break; 143 | case 0x02: 144 | case 0x03: 145 | cart_mbc_type = mbc1_ram; 146 | break; 147 | 148 | // MBC2 149 | case 0x05: 150 | case 0x06: 151 | cart_mbc_type = mbc2; 152 | break; 153 | 154 | // MBC3 155 | case 0x0f: 156 | cart_mbc_type = mbc3_timer; 157 | break; 158 | case 0x10: 159 | cart_mbc_type = mbc3_timer_ram; 160 | break; 161 | case 0x11: 162 | cart_mbc_type = mbc3; 163 | break; 164 | case 0x12: 165 | case 0x13: 166 | cart_mbc_type = mbc3_ram; 167 | break; 168 | 169 | // MBC5 170 | case 0x19: 171 | cart_mbc_type = mbc5; 172 | break; 173 | case 0x1a: 174 | case 0x1b: 175 | cart_mbc_type = mbc5_ram; 176 | break; 177 | case 0x1c: // Technically includes rumble 178 | cart_mbc_type = mbc5; 179 | break; 180 | case 0x1d: // Technically includes rumble 181 | case 0x1e: // Technically includes rumble 182 | cart_mbc_type = mbc5_ram; 183 | break; 184 | default: 185 | cart_mbc_type = unknown_mbc_type; 186 | break; 187 | } 188 | 189 | 190 | // Set the number of ROM banks 191 | rom_size = 2 << raw_rom_size; 192 | 193 | 194 | // Set the size of RAM 195 | if ( cart_mbc_type != mbc2 ) 196 | { 197 | switch ( raw_ram_size & 0x03 ) 198 | { 199 | // No external cart RAM 200 | case 0x00: 201 | ram_size = rs_none; 202 | break; 203 | 204 | // 2 kiB of external cart RAM 205 | case 0x01: 206 | ram_size = rs_2; 207 | break; 208 | 209 | // 8 kiB of external cart RAM 210 | case 0x02: 211 | ram_size = rs_8; 212 | break; 213 | 214 | // 32 kiB (4 banks of 8 kiB each) of external cart RAM 215 | case 0x03: 216 | ram_size = rs_32; 217 | break; 218 | 219 | // 128 kiB (16 banks of 8 kiB each) of external cart RAM 220 | case 0x04: 221 | ram_size = rs_128; 222 | break; 223 | } 224 | } 225 | else 226 | { 227 | // MBC2 has its own built-in RAM that is rather odd in that it 228 | // stores 512 "bytes" that are 4 bits each. 229 | // Addressing for the MBC2's built-in RAM is the same as it would 230 | // be if the "bytes" were 8 bits each instead of 4 bits each. 231 | ram_size = rs_mbc2; 232 | } 233 | } 234 | 235 | 236 | 237 | 238 | // Misc. Helper Functions 239 | 240 | uint8_t cart_helper::calc_tpak_bank( uint16_t gb_addr ) 241 | { 242 | // Unfortunately, the AVR instruction set can only shift by one bit at 243 | // a time, but this is still probably fast enough given that it won't 244 | // be called all that often. 245 | 246 | return (uint8_t)( gb_addr >> 14 ); 247 | } 248 | 249 | 250 | uint16_t cart_helper::calc_tpak_addr( uint16_t gb_addr ) 251 | { 252 | return (uint16_t)( gb_addr | 0xc000 ); 253 | } 254 | 255 | 256 | 257 | void cart_helper::read_with_gb_addr( uint16_t gb_addr ) 258 | { 259 | my_tpak.set_bank( calc_tpak_bank(gb_addr) ); 260 | my_tpak.read( calc_tpak_addr(gb_addr) ); 261 | 262 | //if ( ( gb_addr >= 0x0000 ) && ( gb_addr < 0x4000 ) ) 263 | //{ 264 | // my_tpak.set_bank(0x00); 265 | // my_tpak.read( gb_addr + 0xc000 ); 266 | //} 267 | //else if ( ( gb_addr >= 0x4000 ) && ( gb_addr < 0x8000 ) ) 268 | //{ 269 | // my_tpak.set_bank(0x01); 270 | // my_tpak.read( gb_addr + 0x8000 ); 271 | //} 272 | //else if ( ( gb_addr >= 0x8000 ) && ( gb_addr < 0xc000 ) ) 273 | //{ 274 | // my_tpak.set_bank(0x02); 275 | // my_tpak.read( gb_addr + 0x4000 ); 276 | //} 277 | //else 278 | //{ 279 | // my_tpak.set_bank(0x03); 280 | // my_tpak.read(gb_addr); 281 | //} 282 | } 283 | 284 | void cart_helper::write_byte_with_gb_addr( uint16_t gb_addr, uint8_t data ) 285 | { 286 | my_tpak.set_bank( calc_tpak_bank(gb_addr) ); 287 | my_tpak.write_byte( calc_tpak_addr(gb_addr), data ); 288 | 289 | } 290 | 291 | // End of Misc. Helper Functions 292 | 293 | 294 | 295 | // This function ALSO waits for serial data 296 | int cart_helper::interpret_serial_message() 297 | { 298 | memset( buf, bufsize, 0 ); 299 | 300 | int num_recv = Serial.readBytes( buf, bufsize ); 301 | //delay(10); 302 | 303 | 304 | //if ( num_recv > 0 ) 305 | //{ 306 | // Serial.print("I received this many bytes: "); 307 | // Serial.println( num_recv, DEC ); 308 | //} 309 | //delay(10); 310 | // 311 | //// temporary 312 | //return 0; 313 | 314 | 315 | // If we didn't receive anything 316 | if ( num_recv <= 0 ) 317 | { 318 | //delay(10); 319 | return 0; 320 | } 321 | 322 | 323 | if ( buf[0] == sm_print_cart_stuff ) 324 | { 325 | print_cart_stuff(); 326 | } 327 | else if ( buf[0] == sm_get_cart_stuff ) 328 | { 329 | const uint num_to_write = 32; 330 | byte to_write[num_to_write]; 331 | memset( to_write, 0x00, num_to_write ); 332 | 333 | addr_packet rom_size_pkt; 334 | rom_size_pkt.w = rom_size; 335 | 336 | 337 | to_write[0] = cart_mbc_type; 338 | 339 | // I like Big Endian more than Little Endian. 340 | to_write[1] = (byte)(rom_size_pkt.hi); 341 | to_write[2] = (byte)(rom_size_pkt.lo); 342 | 343 | to_write[3] = ram_size; 344 | 345 | 346 | Serial.write( to_write, num_to_write ); 347 | } 348 | 349 | // I'm not sure that this will work properly... 350 | else if ( buf[0] == sm_reset_tpak ) 351 | { 352 | //// Disable the tpak 353 | //my_tpak.write_byte( 0x8000, 0x80 ); 354 | //delay(100); 355 | // 356 | //my_tpak.read(); 357 | //delay(100); 358 | // 359 | //my_tpak.write_byte( 0x8000, 0x80 ); 360 | //delay(100); 361 | // 362 | //my_tpak.read(); 363 | //delay(100); 364 | // 365 | // 366 | //// Enable the tpak 367 | //my_tpak.write_byte( 0x8000, 0x84 ); 368 | //delay(100); 369 | // 370 | //my_tpak.read(); 371 | //delay(100); 372 | // 373 | //my_tpak.write_byte( 0x8000, 0x84 ); 374 | //delay(100); 375 | // 376 | //my_tpak.read(); 377 | //delay(100); 378 | // 379 | 380 | for ( uint8_t i=0; i<32; ++i ) 381 | { 382 | Serial.write(i); 383 | } 384 | return 1; 385 | 386 | } 387 | 388 | else if ( buf[0] == sm_gb_read_32_bytes ) 389 | { 390 | // Treat the address as Big Endian 391 | addr_packet gb_addr_pkt; 392 | gb_addr_pkt.hi = (byte)(buf[1]); 393 | gb_addr_pkt.lo = (byte)(buf[2]); 394 | 395 | uint16_t gb_addr = gb_addr_pkt.w; 396 | 397 | //Serial.println( gb_addr, HEX ); 398 | 399 | uint8_t tpak_bank = calc_tpak_bank(gb_addr); 400 | uint16_t tpak_addr = calc_tpak_addr(gb_addr); 401 | 402 | //uint8_t tpak_bank = 0x00; 403 | //uint16_t tpak_addr = 0xc000 + gb_addr; 404 | 405 | my_tpak.set_bank(tpak_bank); 406 | 407 | clear_mem_dump(); 408 | my_tpak.read(tpak_addr); 409 | manage_mem_dump(); 410 | //print_mem_managed(); 411 | write_mem_managed(); 412 | } 413 | else if ( buf[0] == sm_gb_write_32_bytes ) 414 | { 415 | // Treat the address as Big Endian 416 | addr_packet gb_addr_pkt; 417 | gb_addr_pkt.hi = (byte)(buf[1]); 418 | gb_addr_pkt.lo = (byte)(buf[2]); 419 | 420 | uint16_t gb_addr = gb_addr_pkt.w; 421 | 422 | 423 | uint8_t to_write[32]; 424 | memcpy( to_write, &buf[3], 32 ); 425 | 426 | uint8_t tpak_bank = calc_tpak_bank(gb_addr); 427 | uint16_t tpak_addr = calc_tpak_addr(gb_addr); 428 | 429 | 430 | //clear_mem_dump(); 431 | 432 | //Serial.write( to_write, 32 ); 433 | 434 | 435 | my_tpak.set_bank(tpak_bank); 436 | my_tpak.write( tpak_addr, to_write ); 437 | 438 | 439 | 440 | 441 | // I don't necessarily NEED this loop, so I might be getting rid of 442 | // it in a later revision, if I can make stuff work properly 443 | // without it. 444 | 445 | //for ( uint i=0; i<32; ++i ) 446 | for ( uint i=0; i<16; ++i ) 447 | { 448 | //Serial.write(to_write[i]); 449 | //Serial.write((uint8_t)i); 450 | //Serial.write(my_tpak.get_bank()); 451 | 452 | Serial.write(gb_addr_pkt.hi); 453 | Serial.write(gb_addr_pkt.lo); 454 | 455 | } 456 | } 457 | 458 | else if ( buf[0] == sm_gb_read_var_num_bytes ) 459 | { 460 | addr_packet gb_start_addr_pkt, num_bytes_pkt; 461 | 462 | // The GB address to read from is in buf[1] and buf[2] (uint16_t) 463 | gb_start_addr_pkt.hi = (byte)(buf[1]); 464 | gb_start_addr_pkt.lo = (byte)(buf[2]); 465 | 466 | 467 | // The number of bytes to read is in buf[3] and buf[4] (uint16_t) 468 | num_bytes_pkt.hi = (byte)(buf[3]); 469 | num_bytes_pkt.lo = (byte)(buf[4]); 470 | 471 | uint16_t gb_start_addr = gb_start_addr_pkt.w, 472 | num_bytes = num_bytes_pkt.w; 473 | 474 | uint8_t tpak_bank = calc_tpak_bank(gb_start_addr); 475 | long tpak_addr = calc_tpak_addr(gb_start_addr); 476 | long tpak_addr_end = tpak_addr + num_bytes; 477 | 478 | my_tpak.set_bank(tpak_bank); 479 | 480 | for ( ; tpak_addr 0 ) 522 | { 523 | int num_recv2 = Serial.readBytes 524 | ( &(buf[num_bytes - left_to_read]), 1024 ); 525 | 526 | left_to_read -= num_recv2; 527 | 528 | } 529 | 530 | 531 | uint8_t tpak_bank = calc_tpak_bank(gb_start_addr); 532 | long tpak_addr = calc_tpak_addr(gb_start_addr); 533 | long tpak_addr_end = tpak_addr + num_bytes; 534 | my_tpak.set_bank(tpak_bank); 535 | 536 | const uint num_to_write = 32; 537 | uint8_t to_write[num_to_write]; 538 | 539 | //memcpy( to_write, &( buf[gb_start_addr-0xa000] ), num_to_write ); 540 | 541 | //for ( uint i=0; i 7 | //typedef unsigned char u8; typedef signed char s8; 8 | //typedef unsigned int u16; typedef signed int s16; 9 | //typedef unsigned int uint; 10 | 11 | //typedef uint8_t u8; typedef int8_t s8; 12 | //typedef uint16_t u16; typedef int16_t s16; 13 | typedef unsigned int uint; 14 | 15 | 16 | // 8 bytes of data that we get from the controller 17 | struct N64_status_t { 18 | // bits: 0, 0, 0, start, y, x, b, a 19 | unsigned char data1; 20 | // bits: 1, L, R, Z, Dup, Ddown, Dright, Dleft 21 | unsigned char data2; 22 | char stick_x; 23 | char stick_y; 24 | }; 25 | 26 | union addr_packet 27 | { 28 | word w; 29 | struct 30 | { 31 | byte lo, hi; 32 | }; 33 | }; 34 | 35 | 36 | #endif // misc_types_h 37 | -------------------------------------------------------------------------------- /src/arduinogbdump/some_globals.cpp: -------------------------------------------------------------------------------- 1 | #include "misc_types.h" 2 | 3 | #include "some_globals.h" 4 | 5 | N64_status_t N64_status; 6 | char N64_raw_dump[33]; // 1 received bit per byte 7 | 8 | char N64_mem_dump[N64_mem_size+1]; 9 | 10 | unsigned char N64_mem_managed[N64_byte_size]; 11 | 12 | char buf[bufsize]; 13 | -------------------------------------------------------------------------------- /src/arduinogbdump/some_globals.h: -------------------------------------------------------------------------------- 1 | #ifndef some_globals_h 2 | #define some_globals_h 3 | 4 | #include "misc_types.h" 5 | 6 | // 8 bytes of data that we get from the controller 7 | extern N64_status_t N64_status; 8 | extern char N64_raw_dump[33]; // 1 received bit per byte 9 | 10 | static const word N64_mem_size = 264; 11 | extern char N64_mem_dump[N64_mem_size+1]; 12 | 13 | static const word N64_byte_size = 33; 14 | extern unsigned char N64_mem_managed[N64_byte_size]; 15 | 16 | 17 | // Buffer for Serial.readBytesUntil() 18 | static const int bufsize = 1072; 19 | extern char buf[bufsize]; 20 | 21 | 22 | 23 | #endif // some_globals_h 24 | -------------------------------------------------------------------------------- /src/arduinogbdump/tags: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ 2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ 3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ 4 | !_TAG_PROGRAM_NAME Exuberant Ctags // 5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ 6 | !_TAG_PROGRAM_VERSION 5.8 // 7 | N64_HIGH aux_code.h 40;" kind:d 8 | N64_HIGH aux_code.h 44;" kind:d 9 | N64_HIGH aux_code.h 48;" kind:d 10 | N64_LOW aux_code.h 41;" kind:d 11 | N64_LOW aux_code.h 45;" kind:d 12 | N64_LOW aux_code.h 49;" kind:d 13 | N64_PIN aux_code.h 33;" kind:d 14 | N64_QUERY aux_code.h 42;" kind:d 15 | N64_QUERY aux_code.h 46;" kind:d 16 | N64_QUERY aux_code.h 50;" kind:d 17 | N64_byte_size some_globals.h /^static const word N64_byte_size = 33;$/;" kind:v 18 | N64_get aux_code.cpp /^void N64_get()$/;" kind:f signature:() 19 | N64_get aux_code.h /^void N64_get();$/;" kind:p signature:() 20 | N64_mem_dump some_globals.cpp /^char N64_mem_dump[N64_mem_size+1];$/;" kind:v 21 | N64_mem_managed some_globals.cpp /^unsigned char N64_mem_managed[N64_byte_size];$/;" kind:v 22 | N64_mem_size some_globals.h /^static const word N64_mem_size = 264;$/;" kind:v 23 | N64_raw_dump some_globals.cpp /^char N64_raw_dump[33]; \/\/ 1 received bit per byte$/;" kind:v 24 | N64_read_addr aux_code.cpp /^void N64_read_addr()$/;" kind:f signature:() 25 | N64_read_addr aux_code.h /^void N64_read_addr();$/;" kind:p signature:() 26 | N64_send aux_code.cpp /^void N64_send(unsigned char *buffer, char length)$/;" kind:f signature:(unsigned char *buffer, char length) 27 | N64_send aux_code.h /^void N64_send(unsigned char *buffer, char length);$/;" kind:p signature:(unsigned char *buffer, char length) 28 | N64_status some_globals.cpp /^N64_status_t N64_status;$/;" kind:v 29 | N64_status_t misc_types.h /^struct N64_status_t {$/;" kind:s 30 | N64_status_t::data1 misc_types.h /^ unsigned char data1;$/;" kind:m struct:N64_status_t access:public 31 | N64_status_t::data2 misc_types.h /^ unsigned char data2;$/;" kind:m struct:N64_status_t access:public 32 | N64_status_t::stick_x misc_types.h /^ char stick_x;$/;" kind:m struct:N64_status_t access:public 33 | N64_status_t::stick_y misc_types.h /^ char stick_y;$/;" kind:m struct:N64_status_t access:public 34 | N64_stuff aux_code.cpp /^void N64_stuff( unsigned char *buff, char length )$/;" kind:f signature:( unsigned char *buff, char length ) 35 | N64_stuff aux_code.h /^void N64_stuff( unsigned char *buff, char length );$/;" kind:p signature:( unsigned char *buff, char length ) 36 | N64_stuff_2 aux_code.cpp /^void N64_stuff_2( unsigned char *buff, char length )$/;" kind:f signature:( unsigned char *buff, char length ) 37 | N64_stuff_2 aux_code.h /^void N64_stuff_2( unsigned char *buff, char length );$/;" kind:p signature:( unsigned char *buff, char length ) 38 | PORT_THING aux_code.h 11;" kind:d 39 | PORT_THING aux_code.h 13;" kind:d 40 | PORT_THING aux_code.h 9;" kind:d 41 | addr_packet misc_types.h /^union addr_packet$/;" kind:u 42 | addr_packet::__anon1::hi misc_types.h /^ byte lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 43 | addr_packet::__anon1::lo misc_types.h /^ byte lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 44 | addr_packet::w misc_types.h /^ word w;$/;" kind:m union:addr_packet access:public 45 | addr_pkt tpak_class.h /^ addr_packet addr_pkt;$/;" kind:m class:tpak access:protected 46 | aux_code_h aux_code.h 2;" kind:d 47 | buf some_globals.cpp /^char buf[bufsize];$/;" kind:v 48 | bufsize some_globals.h /^static const int bufsize = 1072;$/;" kind:v 49 | calc_addr_crc aux_code.cpp /^word calc_addr_crc ( word address )$/;" kind:f signature:( word address ) 50 | calc_addr_crc aux_code.h /^word calc_addr_crc( word address );$/;" kind:p signature:( word address ) 51 | calc_data_crc aux_code.cpp /^unsigned char calc_data_crc( unsigned char *data )$/;" kind:f signature:( unsigned char *data ) 52 | calc_data_crc aux_code.h /^unsigned char calc_data_crc( unsigned char *data );$/;" kind:p signature:( unsigned char *data ) 53 | calc_tpak_addr cart_helper_class.cpp /^uint16_t cart_helper::calc_tpak_addr( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 54 | calc_tpak_addr cart_helper_class.h /^ uint16_t calc_tpak_addr( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 55 | calc_tpak_bank cart_helper_class.cpp /^uint8_t cart_helper::calc_tpak_bank( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 56 | calc_tpak_bank cart_helper_class.h /^ uint8_t calc_tpak_bank( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 57 | calc_tpak_bank_and_tpak_addr cart_helper_class.h /^ void calc_tpak_bank_and_tpak_addr( uint16_t gb_addr, $/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr, uint8_t& tpak_bank, uint16_t& tpak_addr ) 58 | cart_helper cart_helper_class.cpp /^cart_helper::cart_helper()$/;" kind:f class:cart_helper signature:() 59 | cart_helper cart_helper_class.h /^ cart_helper();$/;" kind:p class:cart_helper access:public signature:() 60 | cart_helper cart_helper_class.h /^class cart_helper$/;" kind:c 61 | cart_helper::calc_tpak_addr cart_helper_class.cpp /^uint16_t cart_helper::calc_tpak_addr( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 62 | cart_helper::calc_tpak_addr cart_helper_class.h /^ uint16_t calc_tpak_addr( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 63 | cart_helper::calc_tpak_bank cart_helper_class.cpp /^uint8_t cart_helper::calc_tpak_bank( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 64 | cart_helper::calc_tpak_bank cart_helper_class.h /^ uint8_t calc_tpak_bank( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 65 | cart_helper::calc_tpak_bank_and_tpak_addr cart_helper_class.h /^ void calc_tpak_bank_and_tpak_addr( uint16_t gb_addr, $/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr, uint8_t& tpak_bank, uint16_t& tpak_addr ) 66 | cart_helper::cart_helper cart_helper_class.cpp /^cart_helper::cart_helper()$/;" kind:f class:cart_helper signature:() 67 | cart_helper::cart_helper cart_helper_class.h /^ cart_helper();$/;" kind:p class:cart_helper access:public signature:() 68 | cart_helper::cart_mbc_type cart_helper_class.h /^ mbc_type cart_mbc_type;$/;" kind:m class:cart_helper access:public 69 | cart_helper::dump_rom cart_helper_class.h /^ void dump_rom();$/;" kind:p class:cart_helper access:public signature:() 70 | cart_helper::dump_rom cart_helper_mbc_funcs.h /^void cart_helper::dump_rom()$/;" kind:f class:cart_helper signature:() 71 | cart_helper::interpret_raw_data cart_helper_class.cpp /^void cart_helper::interpret_raw_data()$/;" kind:f class:cart_helper signature:() 72 | cart_helper::interpret_raw_data cart_helper_class.h /^ void interpret_raw_data();$/;" kind:p class:cart_helper access:public signature:() 73 | cart_helper::interpret_serial_message cart_helper_class.cpp /^int cart_helper::interpret_serial_message()$/;" kind:f class:cart_helper signature:() 74 | cart_helper::interpret_serial_message cart_helper_class.h /^ int interpret_serial_message();$/;" kind:p class:cart_helper access:public signature:() 75 | cart_helper::interpret_serial_message2 cart_helper_class.h /^ int interpret_serial_message2( int num_recv );$/;" kind:p class:cart_helper access:public signature:( int num_recv ) 76 | cart_helper::mbc1_disable_ram cart_helper_class.h /^ void mbc1_disable_ram();$/;" kind:p class:cart_helper access:public signature:() 77 | cart_helper::mbc1_disable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc1_disable_ram()$/;" kind:f class:cart_helper signature:() 78 | cart_helper::mbc1_dump_ram cart_helper_class.h /^ void mbc1_dump_ram();$/;" kind:p class:cart_helper access:public signature:() 79 | cart_helper::mbc1_dump_rom cart_helper_class.h /^ void mbc1_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 80 | cart_helper::mbc1_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::mbc1_dump_rom()$/;" kind:f class:cart_helper signature:() 81 | cart_helper::mbc1_enable_ram cart_helper_class.h /^ void mbc1_enable_ram();$/;" kind:p class:cart_helper access:public signature:() 82 | cart_helper::mbc1_enable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc1_enable_ram()$/;" kind:f class:cart_helper signature:() 83 | cart_helper::mbc1_set_rom_bank cart_helper_class.h /^ void mbc1_set_rom_bank( uint8_t n_rom_bank_full );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_full ) 84 | cart_helper::mbc1_set_rom_bank_hi cart_helper_class.h /^ void mbc1_set_rom_bank_hi( uint8_t n_rom_bank_hi );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_hi ) 85 | cart_helper::mbc1_set_rom_bank_lo cart_helper_class.h /^ void mbc1_set_rom_bank_lo( uint8_t n_rom_bank_lo );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_lo ) 86 | cart_helper::mbc1_set_rom_bank_lo cart_helper_mbc_funcs.h /^void cart_helper::mbc1_set_rom_bank_lo( uint8_t n_rom_bank_lo )$/;" kind:f class:cart_helper signature:( uint8_t n_rom_bank_lo ) 87 | cart_helper::mbc2_dump_rom cart_helper_class.h /^ void mbc2_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 88 | cart_helper::mbc3_dump_rom cart_helper_class.h /^ void mbc3_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 89 | cart_helper::mbc5_disable_ram cart_helper_class.h /^ void mbc5_disable_ram();$/;" kind:p class:cart_helper access:public signature:() 90 | cart_helper::mbc5_disable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_disable_ram()$/;" kind:f class:cart_helper signature:() 91 | cart_helper::mbc5_dump_ram cart_helper_class.h /^ void mbc5_dump_ram();$/;" kind:p class:cart_helper access:public signature:() 92 | cart_helper::mbc5_dump_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_dump_ram()$/;" kind:f class:cart_helper signature:() 93 | cart_helper::mbc5_dump_rom cart_helper_class.h /^ void mbc5_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 94 | cart_helper::mbc5_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::mbc5_dump_rom()$/;" kind:f class:cart_helper signature:() 95 | cart_helper::mbc5_enable_ram cart_helper_class.h /^ void mbc5_enable_ram();$/;" kind:p class:cart_helper access:public signature:() 96 | cart_helper::mbc5_enable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_enable_ram()$/;" kind:f class:cart_helper signature:() 97 | cart_helper::mbc5_set_ram_bank cart_helper_class.h /^ void mbc5_set_ram_bank( uint8_t n_ram_bank );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_ram_bank ) 98 | cart_helper::mbc5_set_ram_bank cart_helper_mbc_funcs.h /^void cart_helper::mbc5_set_ram_bank( uint8_t n_ram_bank )$/;" kind:f class:cart_helper signature:( uint8_t n_ram_bank ) 99 | cart_helper::mbc5_set_rom_bank cart_helper_class.h /^ void mbc5_set_rom_bank( uint8_t n_rom_bank, uint8_t hbit );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank, uint8_t hbit ) 100 | cart_helper::mbc5_set_rom_bank cart_helper_mbc_funcs.h /^void cart_helper::mbc5_set_rom_bank( uint8_t n_rom_bank, uint8_t hbit )$/;" kind:f class:cart_helper signature:( uint8_t n_rom_bank, uint8_t hbit ) 101 | cart_helper::my_tpak cart_helper_class.h /^ tpak my_tpak;$/;" kind:m class:cart_helper access:public 102 | cart_helper::print_cart_stuff cart_helper_class.cpp /^void cart_helper::print_cart_stuff()$/;" kind:f class:cart_helper signature:() 103 | cart_helper::print_cart_stuff cart_helper_class.h /^ void print_cart_stuff();$/;" kind:p class:cart_helper access:public signature:() 104 | cart_helper::print_raw_data cart_helper_class.cpp /^void cart_helper::print_raw_data()$/;" kind:f class:cart_helper signature:() 105 | cart_helper::print_raw_data cart_helper_class.h /^ void print_raw_data();$/;" kind:p class:cart_helper access:public signature:() 106 | cart_helper::ram_size cart_helper_class.h /^ ram_size_type ram_size;$/;" kind:m class:cart_helper access:public 107 | cart_helper::raw_cart_type cart_helper_class.h /^ uint8_t raw_cart_type;$/;" kind:m class:cart_helper access:public 108 | cart_helper::raw_ram_size cart_helper_class.h /^ uint8_t raw_ram_size;$/;" kind:m class:cart_helper access:public 109 | cart_helper::raw_rom_size cart_helper_class.h /^ uint8_t raw_rom_size;$/;" kind:m class:cart_helper access:public 110 | cart_helper::read_with_gb_addr cart_helper_class.cpp /^void cart_helper::read_with_gb_addr( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 111 | cart_helper::read_with_gb_addr cart_helper_class.h /^ void read_with_gb_addr( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 112 | cart_helper::rom_only_dump_rom cart_helper_class.h /^ void rom_only_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 113 | cart_helper::rom_only_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::rom_only_dump_rom()$/;" kind:f class:cart_helper signature:() 114 | cart_helper::rom_size cart_helper_class.h /^ uint16_t rom_size;$/;" kind:m class:cart_helper access:public 115 | cart_helper::set_cart_stuff cart_helper_class.cpp /^void cart_helper::set_cart_stuff()$/;" kind:f class:cart_helper signature:() 116 | cart_helper::set_cart_stuff cart_helper_class.h /^ void set_cart_stuff();$/;" kind:p class:cart_helper access:public signature:() 117 | cart_helper::set_raw_data cart_helper_class.cpp /^void cart_helper::set_raw_data( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size,$/;" kind:f class:cart_helper signature:( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size, uint8_t s_raw_ram_size ) 118 | cart_helper::set_raw_data cart_helper_class.h /^ void set_raw_data( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size,$/;" kind:p class:cart_helper access:public signature:( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size, uint8_t s_raw_ram_size ) 119 | cart_helper::write_byte_with_gb_addr cart_helper_class.cpp /^void cart_helper::write_byte_with_gb_addr( uint16_t gb_addr, uint8_t data )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr, uint8_t data ) 120 | cart_helper::write_byte_with_gb_addr cart_helper_class.h /^ void write_byte_with_gb_addr( uint16_t gb_addr, uint8_t data );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr, uint8_t data ) 121 | cart_helper::~cart_helper cart_helper_class.cpp /^cart_helper::~cart_helper()$/;" kind:f class:cart_helper signature:() 122 | cart_helper::~cart_helper cart_helper_class.h /^ ~cart_helper();$/;" kind:p class:cart_helper access:public signature:() 123 | cart_helper_class_h cart_helper_class.h 2;" kind:d 124 | cart_helper_enums_h cart_helper_enums.h 2;" kind:d 125 | cart_helper_mbc_funcs_h cart_helper_mbc_funcs.h 2;" kind:d 126 | cart_mbc_type cart_helper_class.h /^ mbc_type cart_mbc_type;$/;" kind:m class:cart_helper access:public 127 | clear_mem_dump aux_code.cpp /^void clear_mem_dump()$/;" kind:f signature:() 128 | clear_mem_dump aux_code.h /^void clear_mem_dump();$/;" kind:p signature:() 129 | cmp_buf aux_code.cpp /^bool cmp_buf( const char* to_cmp, int num_recv )$/;" kind:f signature:( const char* to_cmp, int num_recv ) 130 | cmp_buf aux_code.h /^bool cmp_buf( const char* to_cmp, int num_recv );$/;" kind:p signature:( const char* to_cmp, int num_recv ) 131 | command tpak_class.h /^ uint8_t command[wcmd_size];$/;" kind:m class:tpak access:protected 132 | current_bank tpak_class.h /^ char current_bank;$/;" kind:m class:tpak access:protected 133 | data1 misc_types.h /^ unsigned char data1;$/;" kind:m struct:N64_status_t access:public 134 | data2 misc_types.h /^ unsigned char data2;$/;" kind:m struct:N64_status_t access:public 135 | default_bitwise_thing aux_code.h /^static const byte default_bitwise_thing = 0x04;$/;" kind:v 136 | dump_rom cart_helper_class.h /^ void dump_rom();$/;" kind:p class:cart_helper access:public signature:() 137 | dump_rom cart_helper_mbc_funcs.h /^void cart_helper::dump_rom()$/;" kind:f class:cart_helper signature:() 138 | enable_tpak tpak_class.cpp /^void tpak::enable_tpak()$/;" kind:f class:tpak signature:() 139 | enable_tpak tpak_class.h /^ void enable_tpak();$/;" kind:p class:tpak access:public signature:() 140 | get_access_mode tpak_class.cpp /^void tpak::get_access_mode()$/;" kind:f class:tpak signature:() 141 | get_access_mode tpak_class.h /^ void get_access_mode();$/;" kind:p class:tpak access:public signature:() 142 | get_bank tpak_class.cpp /^char tpak::get_bank() const$/;" kind:f class:tpak signature:() const 143 | get_bank tpak_class.h /^ char get_bank() const;$/;" kind:p class:tpak access:public signature:() const 144 | hi misc_types.h /^ byte lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 145 | init tpak_class.cpp /^void tpak::init( cart_helper& the_cart_helper )$/;" kind:f class:tpak signature:( cart_helper& the_cart_helper ) 146 | init tpak_class.h /^ void init( cart_helper& the_cart_helper );$/;" kind:p class:tpak access:public signature:( cart_helper& the_cart_helper ) 147 | interpret_raw_data cart_helper_class.cpp /^void cart_helper::interpret_raw_data()$/;" kind:f class:cart_helper signature:() 148 | interpret_raw_data cart_helper_class.h /^ void interpret_raw_data();$/;" kind:p class:cart_helper access:public signature:() 149 | interpret_serial_message cart_helper_class.cpp /^int cart_helper::interpret_serial_message()$/;" kind:f class:cart_helper signature:() 150 | interpret_serial_message cart_helper_class.h /^ int interpret_serial_message();$/;" kind:p class:cart_helper access:public signature:() 151 | interpret_serial_message2 cart_helper_class.h /^ int interpret_serial_message2( int num_recv );$/;" kind:p class:cart_helper access:public signature:( int num_recv ) 152 | lo misc_types.h /^ byte lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 153 | loop2 aux_code.cpp /^void loop2()$/;" kind:f signature:() 154 | loop2 aux_code.h /^void loop2();$/;" kind:p signature:() 155 | manage_mem_dump aux_code.cpp /^void manage_mem_dump() \/\/ arrange data into bytes $/;" kind:f signature:() 156 | manage_mem_dump aux_code.h /^void manage_mem_dump(); \/\/ arrange data into bytes $/;" kind:p signature:() 157 | mbc1 cart_helper_enums.h /^ mbc1, \/\/ MBC1 only, no RAM$/;" kind:e enum:mbc_type 158 | mbc1_disable_ram cart_helper_class.h /^ void mbc1_disable_ram();$/;" kind:p class:cart_helper access:public signature:() 159 | mbc1_disable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc1_disable_ram()$/;" kind:f class:cart_helper signature:() 160 | mbc1_dump_ram cart_helper_class.h /^ void mbc1_dump_ram();$/;" kind:p class:cart_helper access:public signature:() 161 | mbc1_dump_rom cart_helper_class.h /^ void mbc1_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 162 | mbc1_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::mbc1_dump_rom()$/;" kind:f class:cart_helper signature:() 163 | mbc1_enable_ram cart_helper_class.h /^ void mbc1_enable_ram();$/;" kind:p class:cart_helper access:public signature:() 164 | mbc1_enable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc1_enable_ram()$/;" kind:f class:cart_helper signature:() 165 | mbc1_ram cart_helper_enums.h /^ mbc1_ram, \/\/ MBC1 and RAM$/;" kind:e enum:mbc_type 166 | mbc1_set_rom_bank cart_helper_class.h /^ void mbc1_set_rom_bank( uint8_t n_rom_bank_full );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_full ) 167 | mbc1_set_rom_bank_hi cart_helper_class.h /^ void mbc1_set_rom_bank_hi( uint8_t n_rom_bank_hi );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_hi ) 168 | mbc1_set_rom_bank_lo cart_helper_class.h /^ void mbc1_set_rom_bank_lo( uint8_t n_rom_bank_lo );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank_lo ) 169 | mbc1_set_rom_bank_lo cart_helper_mbc_funcs.h /^void cart_helper::mbc1_set_rom_bank_lo( uint8_t n_rom_bank_lo )$/;" kind:f class:cart_helper signature:( uint8_t n_rom_bank_lo ) 170 | mbc2 cart_helper_enums.h /^ mbc2, \/\/ MBC2 (includes built-in RAM)$/;" kind:e enum:mbc_type 171 | mbc2_dump_rom cart_helper_class.h /^ void mbc2_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 172 | mbc3 cart_helper_enums.h /^ mbc3, \/\/ MBC3 only, no RTC, no RAM$/;" kind:e enum:mbc_type 173 | mbc3_dump_rom cart_helper_class.h /^ void mbc3_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 174 | mbc3_ram cart_helper_enums.h /^ mbc3_ram, \/\/ MBC3 and RAM, but no RTC$/;" kind:e enum:mbc_type 175 | mbc3_timer cart_helper_enums.h /^ mbc3_timer, \/\/ MBC3 and RTC, but no RAM$/;" kind:e enum:mbc_type 176 | mbc3_timer_ram cart_helper_enums.h /^ mbc3_timer_ram, \/\/ MBC3, RTC, and RAM$/;" kind:e enum:mbc_type 177 | mbc5 cart_helper_enums.h /^ mbc5, \/\/ MBC5 only, no RAM$/;" kind:e enum:mbc_type 178 | mbc5_disable_ram cart_helper_class.h /^ void mbc5_disable_ram();$/;" kind:p class:cart_helper access:public signature:() 179 | mbc5_disable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_disable_ram()$/;" kind:f class:cart_helper signature:() 180 | mbc5_dump_ram cart_helper_class.h /^ void mbc5_dump_ram();$/;" kind:p class:cart_helper access:public signature:() 181 | mbc5_dump_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_dump_ram()$/;" kind:f class:cart_helper signature:() 182 | mbc5_dump_rom cart_helper_class.h /^ void mbc5_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 183 | mbc5_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::mbc5_dump_rom()$/;" kind:f class:cart_helper signature:() 184 | mbc5_enable_ram cart_helper_class.h /^ void mbc5_enable_ram();$/;" kind:p class:cart_helper access:public signature:() 185 | mbc5_enable_ram cart_helper_mbc_funcs.h /^void cart_helper::mbc5_enable_ram()$/;" kind:f class:cart_helper signature:() 186 | mbc5_ram cart_helper_enums.h /^ mbc5_ram, \/\/ MBC5 and RAM$/;" kind:e enum:mbc_type 187 | mbc5_set_ram_bank cart_helper_class.h /^ void mbc5_set_ram_bank( uint8_t n_ram_bank );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_ram_bank ) 188 | mbc5_set_ram_bank cart_helper_mbc_funcs.h /^void cart_helper::mbc5_set_ram_bank( uint8_t n_ram_bank )$/;" kind:f class:cart_helper signature:( uint8_t n_ram_bank ) 189 | mbc5_set_rom_bank cart_helper_class.h /^ void mbc5_set_rom_bank( uint8_t n_rom_bank, uint8_t hbit );$/;" kind:p class:cart_helper access:public signature:( uint8_t n_rom_bank, uint8_t hbit ) 190 | mbc5_set_rom_bank cart_helper_mbc_funcs.h /^void cart_helper::mbc5_set_rom_bank( uint8_t n_rom_bank, uint8_t hbit )$/;" kind:f class:cart_helper signature:( uint8_t n_rom_bank, uint8_t hbit ) 191 | mbc_type cart_helper_enums.h /^enum mbc_type$/;" kind:g 192 | mega_bitwise_thing aux_code.h /^static const byte mega_bitwise_thing = 0x10;$/;" kind:v 193 | micro_bitwise_thing aux_code.h /^static const byte micro_bitwise_thing = 0x02;$/;" kind:v 194 | misc_types_h misc_types.h 2;" kind:d 195 | my_tpak cart_helper_class.h /^ tpak my_tpak;$/;" kind:m class:cart_helper access:public 196 | print_cart_stuff cart_helper_class.cpp /^void cart_helper::print_cart_stuff()$/;" kind:f class:cart_helper signature:() 197 | print_cart_stuff cart_helper_class.h /^ void print_cart_stuff();$/;" kind:p class:cart_helper access:public signature:() 198 | print_crc_managed aux_code.cpp /^void print_crc_managed()$/;" kind:f signature:() 199 | print_crc_managed aux_code.h /^void print_crc_managed();$/;" kind:p signature:() 200 | print_mem_managed aux_code.cpp /^void print_mem_managed()$/;" kind:f signature:() 201 | print_mem_managed aux_code.h /^void print_mem_managed();$/;" kind:p signature:() 202 | print_mem_managed2 aux_code.h /^void print_mem_managed2();$/;" kind:p signature:() 203 | print_mem_managed_2 aux_code.cpp /^void print_mem_managed_2()$/;" kind:f signature:() 204 | print_raw_data cart_helper_class.cpp /^void cart_helper::print_raw_data()$/;" kind:f class:cart_helper signature:() 205 | print_raw_data cart_helper_class.h /^ void print_raw_data();$/;" kind:p class:cart_helper access:public signature:() 206 | ram_size cart_helper_class.h /^ ram_size_type ram_size;$/;" kind:m class:cart_helper access:public 207 | ram_size_type cart_helper_enums.h /^enum ram_size_type$/;" kind:g 208 | raw_cart_type cart_helper_class.h /^ uint8_t raw_cart_type;$/;" kind:m class:cart_helper access:public 209 | raw_ram_size cart_helper_class.h /^ uint8_t raw_ram_size;$/;" kind:m class:cart_helper access:public 210 | raw_rom_size cart_helper_class.h /^ uint8_t raw_rom_size;$/;" kind:m class:cart_helper access:public 211 | rcmd_size tpak_class.h /^ static const word wcmd_size = 35, rcmd_size = 3;$/;" kind:m class:tpak access:protected 212 | read tpak_class.cpp /^void tpak::read( uint16_t read_addr )$/;" kind:f class:tpak signature:( uint16_t read_addr ) 213 | read tpak_class.cpp /^void tpak::read()$/;" kind:f class:tpak signature:() 214 | read tpak_class.h /^ void read( uint16_t read_addr );$/;" kind:p class:tpak access:public signature:( uint16_t read_addr ) 215 | read tpak_class.h /^ void read();$/;" kind:p class:tpak access:public signature:() 216 | read_with_gb_addr cart_helper_class.cpp /^void cart_helper::read_with_gb_addr( uint16_t gb_addr )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr ) 217 | read_with_gb_addr cart_helper_class.h /^ void read_with_gb_addr( uint16_t gb_addr );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr ) 218 | rom_only cart_helper_enums.h /^ rom_only, \/\/ 32 kiB of ROM, no MBC$/;" kind:e enum:mbc_type 219 | rom_only_dump_rom cart_helper_class.h /^ void rom_only_dump_rom();$/;" kind:p class:cart_helper access:public signature:() 220 | rom_only_dump_rom cart_helper_mbc_funcs.h /^void cart_helper::rom_only_dump_rom()$/;" kind:f class:cart_helper signature:() 221 | rom_size cart_helper_class.h /^ uint16_t rom_size;$/;" kind:m class:cart_helper access:public 222 | rs_128 cart_helper_enums.h /^ rs_128, \/\/ 128 kiB of external cart RAM, 16 banks of 8 kiB each$/;" kind:e enum:ram_size_type 223 | rs_2 cart_helper_enums.h /^ rs_2, \/\/ 2 kiB of external cart RAM, not even a full bank$/;" kind:e enum:ram_size_type 224 | rs_32 cart_helper_enums.h /^ rs_32, \/\/ 32 kiB of external cart RAM, 4 banks of 8 kiB each$/;" kind:e enum:ram_size_type 225 | rs_8 cart_helper_enums.h /^ rs_8, \/\/ 8 kiB of external cart RAM, 1 bank of 8 kiB$/;" kind:e enum:ram_size_type 226 | rs_mbc2 cart_helper_enums.h /^ rs_mbc2,$/;" kind:e enum:ram_size_type 227 | rs_none cart_helper_enums.h /^ rs_none, \/\/ 0 kiB of external cart RAM$/;" kind:e enum:ram_size_type 228 | serial_msg_type cart_helper_enums.h /^enum serial_msg_type$/;" kind:g 229 | set_access_mode tpak_class.cpp /^void tpak::set_access_mode( bool n_mode )$/;" kind:f class:tpak signature:( bool n_mode ) 230 | set_access_mode tpak_class.h /^ void set_access_mode( bool n_mode );$/;" kind:p class:tpak access:public signature:( bool n_mode ) 231 | set_bank tpak_class.cpp /^void tpak::set_bank( char n_tpak_bank )$/;" kind:f class:tpak signature:( char n_tpak_bank ) 232 | set_bank tpak_class.h /^ void set_bank( char n_tpak_bank );$/;" kind:p class:tpak access:public signature:( char n_tpak_bank ) 233 | set_cart_stuff cart_helper_class.cpp /^void cart_helper::set_cart_stuff()$/;" kind:f class:cart_helper signature:() 234 | set_cart_stuff cart_helper_class.h /^ void set_cart_stuff();$/;" kind:p class:cart_helper access:public signature:() 235 | set_raw_data cart_helper_class.cpp /^void cart_helper::set_raw_data( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size,$/;" kind:f class:cart_helper signature:( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size, uint8_t s_raw_ram_size ) 236 | set_raw_data cart_helper_class.h /^ void set_raw_data( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size,$/;" kind:p class:cart_helper access:public signature:( uint8_t s_raw_cart_type, uint8_t s_raw_rom_size, uint8_t s_raw_ram_size ) 237 | sm_gb_read_32_bytes cart_helper_enums.h /^ sm_gb_read_32_bytes,$/;" kind:e enum:serial_msg_type 238 | sm_gb_read_var_num_bytes cart_helper_enums.h /^ sm_gb_read_var_num_bytes,$/;" kind:e enum:serial_msg_type 239 | sm_gb_write_32_bytes cart_helper_enums.h /^ sm_gb_write_32_bytes,$/;" kind:e enum:serial_msg_type 240 | sm_gb_write_var_num_bytes cart_helper_enums.h /^ sm_gb_write_var_num_bytes,$/;" kind:e enum:serial_msg_type 241 | sm_get_cart_stuff cart_helper_enums.h /^ sm_get_cart_stuff,$/;" kind:e enum:serial_msg_type 242 | sm_print_cart_stuff cart_helper_enums.h /^ sm_print_cart_stuff,$/;" kind:e enum:serial_msg_type 243 | sm_reset_tpak cart_helper_enums.h /^ sm_reset_tpak,$/;" kind:e enum:serial_msg_type 244 | some_globals_h some_globals.h 2;" kind:d 245 | stick_x misc_types.h /^ char stick_x;$/;" kind:m struct:N64_status_t access:public 246 | stick_y misc_types.h /^ char stick_y;$/;" kind:m struct:N64_status_t access:public 247 | tpak tpak_class.cpp /^tpak::tpak()$/;" kind:f class:tpak signature:() 248 | tpak tpak_class.h /^ tpak();$/;" kind:p class:tpak access:public signature:() 249 | tpak tpak_class.h /^class tpak$/;" kind:c 250 | tpak::addr_pkt tpak_class.h /^ addr_packet addr_pkt;$/;" kind:m class:tpak access:protected 251 | tpak::command tpak_class.h /^ uint8_t command[wcmd_size];$/;" kind:m class:tpak access:protected 252 | tpak::current_bank tpak_class.h /^ char current_bank;$/;" kind:m class:tpak access:protected 253 | tpak::enable_tpak tpak_class.cpp /^void tpak::enable_tpak()$/;" kind:f class:tpak signature:() 254 | tpak::enable_tpak tpak_class.h /^ void enable_tpak();$/;" kind:p class:tpak access:public signature:() 255 | tpak::get_access_mode tpak_class.cpp /^void tpak::get_access_mode()$/;" kind:f class:tpak signature:() 256 | tpak::get_access_mode tpak_class.h /^ void get_access_mode();$/;" kind:p class:tpak access:public signature:() 257 | tpak::get_bank tpak_class.cpp /^char tpak::get_bank() const$/;" kind:f class:tpak signature:() const 258 | tpak::get_bank tpak_class.h /^ char get_bank() const;$/;" kind:p class:tpak access:public signature:() const 259 | tpak::init tpak_class.cpp /^void tpak::init( cart_helper& the_cart_helper )$/;" kind:f class:tpak signature:( cart_helper& the_cart_helper ) 260 | tpak::init tpak_class.h /^ void init( cart_helper& the_cart_helper );$/;" kind:p class:tpak access:public signature:( cart_helper& the_cart_helper ) 261 | tpak::rcmd_size tpak_class.h /^ static const word wcmd_size = 35, rcmd_size = 3;$/;" kind:m class:tpak access:protected 262 | tpak::read tpak_class.cpp /^void tpak::read( uint16_t read_addr )$/;" kind:f class:tpak signature:( uint16_t read_addr ) 263 | tpak::read tpak_class.cpp /^void tpak::read()$/;" kind:f class:tpak signature:() 264 | tpak::read tpak_class.h /^ void read( uint16_t read_addr );$/;" kind:p class:tpak access:public signature:( uint16_t read_addr ) 265 | tpak::read tpak_class.h /^ void read();$/;" kind:p class:tpak access:public signature:() 266 | tpak::set_access_mode tpak_class.cpp /^void tpak::set_access_mode( bool n_mode )$/;" kind:f class:tpak signature:( bool n_mode ) 267 | tpak::set_access_mode tpak_class.h /^ void set_access_mode( bool n_mode );$/;" kind:p class:tpak access:public signature:( bool n_mode ) 268 | tpak::set_bank tpak_class.cpp /^void tpak::set_bank( char n_tpak_bank )$/;" kind:f class:tpak signature:( char n_tpak_bank ) 269 | tpak::set_bank tpak_class.h /^ void set_bank( char n_tpak_bank );$/;" kind:p class:tpak access:public signature:( char n_tpak_bank ) 270 | tpak::tpak tpak_class.cpp /^tpak::tpak()$/;" kind:f class:tpak signature:() 271 | tpak::tpak tpak_class.h /^ tpak();$/;" kind:p class:tpak access:public signature:() 272 | tpak::wcmd_size tpak_class.h /^ static const word wcmd_size = 35, rcmd_size = 3;$/;" kind:m class:tpak access:protected 273 | tpak::write tpak_class.cpp /^void tpak::write( uint16_t write_addr )$/;" kind:f class:tpak signature:( uint16_t write_addr ) 274 | tpak::write tpak_class.cpp /^void tpak::write( uint16_t write_addr, uint8_t* msg )$/;" kind:f class:tpak signature:( uint16_t write_addr, uint8_t* msg ) 275 | tpak::write tpak_class.cpp /^void tpak::write()$/;" kind:f class:tpak signature:() 276 | tpak::write tpak_class.h /^ void write( uint16_t write_addr );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr ) 277 | tpak::write tpak_class.h /^ void write( uint16_t write_addr, uint8_t* msg );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr, uint8_t* msg ) 278 | tpak::write tpak_class.h /^ void write();$/;" kind:p class:tpak access:public signature:() 279 | tpak::write_byte tpak_class.cpp /^void tpak::write_byte( uint16_t write_addr, uint8_t data )$/;" kind:f class:tpak signature:( uint16_t write_addr, uint8_t data ) 280 | tpak::write_byte tpak_class.h /^ void write_byte( uint16_t write_addr, uint8_t data );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr, uint8_t data ) 281 | tpak::~tpak tpak_class.cpp /^tpak::~tpak()$/;" kind:f class:tpak signature:() 282 | tpak::~tpak tpak_class.h /^ ~tpak();$/;" kind:p class:tpak access:public signature:() 283 | tpak_class_h tpak_class.h 2;" kind:d 284 | tpak_stuff aux_code.h /^void tpak_stuff();$/;" kind:p signature:() 285 | tpak_stuff_2 aux_code.cpp /^void tpak_stuff_2()$/;" kind:f signature:() 286 | tpak_stuff_2 aux_code.h /^void tpak_stuff_2();$/;" kind:p signature:() 287 | translate_raw_data aux_code.cpp /^void translate_raw_data()$/;" kind:f signature:() 288 | translate_raw_data aux_code.h /^void translate_raw_data();$/;" kind:p signature:() 289 | uint misc_types.h /^typedef unsigned int uint;$/;" kind:t 290 | unknown_mbc_type cart_helper_enums.h /^ unknown_mbc_type \/\/ Debug, etc.$/;" kind:e enum:mbc_type 291 | w misc_types.h /^ word w;$/;" kind:m union:addr_packet access:public 292 | wcmd_size tpak_class.h /^ static const word wcmd_size = 35, rcmd_size = 3;$/;" kind:m class:tpak access:protected 293 | write tpak_class.cpp /^void tpak::write( uint16_t write_addr )$/;" kind:f class:tpak signature:( uint16_t write_addr ) 294 | write tpak_class.cpp /^void tpak::write( uint16_t write_addr, uint8_t* msg )$/;" kind:f class:tpak signature:( uint16_t write_addr, uint8_t* msg ) 295 | write tpak_class.cpp /^void tpak::write()$/;" kind:f class:tpak signature:() 296 | write tpak_class.h /^ void write( uint16_t write_addr );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr ) 297 | write tpak_class.h /^ void write( uint16_t write_addr, uint8_t* msg );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr, uint8_t* msg ) 298 | write tpak_class.h /^ void write();$/;" kind:p class:tpak access:public signature:() 299 | write_byte tpak_class.cpp /^void tpak::write_byte( uint16_t write_addr, uint8_t data )$/;" kind:f class:tpak signature:( uint16_t write_addr, uint8_t data ) 300 | write_byte tpak_class.h /^ void write_byte( uint16_t write_addr, uint8_t data );$/;" kind:p class:tpak access:public signature:( uint16_t write_addr, uint8_t data ) 301 | write_byte_with_gb_addr cart_helper_class.cpp /^void cart_helper::write_byte_with_gb_addr( uint16_t gb_addr, uint8_t data )$/;" kind:f class:cart_helper signature:( uint16_t gb_addr, uint8_t data ) 302 | write_byte_with_gb_addr cart_helper_class.h /^ void write_byte_with_gb_addr( uint16_t gb_addr, uint8_t data );$/;" kind:p class:cart_helper access:public signature:( uint16_t gb_addr, uint8_t data ) 303 | write_mem_managed aux_code.cpp /^void write_mem_managed()$/;" kind:f signature:() 304 | write_mem_managed aux_code.h /^void write_mem_managed();$/;" kind:p signature:() 305 | ~cart_helper cart_helper_class.cpp /^cart_helper::~cart_helper()$/;" kind:f class:cart_helper signature:() 306 | ~cart_helper cart_helper_class.h /^ ~cart_helper();$/;" kind:p class:cart_helper access:public signature:() 307 | ~tpak tpak_class.cpp /^tpak::~tpak()$/;" kind:f class:tpak signature:() 308 | ~tpak tpak_class.h /^ ~tpak();$/;" kind:p class:tpak access:public signature:() 309 | -------------------------------------------------------------------------------- /src/arduinogbdump/tpak_class.cpp: -------------------------------------------------------------------------------- 1 | #include "aux_code.h" 2 | #include "tpak_class.h" 3 | #include "cart_helper_class.h" 4 | 5 | tpak::tpak() 6 | { 7 | } 8 | 9 | 10 | tpak::~tpak() 11 | { 12 | } 13 | 14 | 15 | void tpak::init( cart_helper& the_cart_helper ) 16 | { 17 | delay(255+150); 18 | 19 | enable_tpak(); 20 | delay(100); 21 | 22 | read(); 23 | delay(100); 24 | 25 | enable_tpak(); 26 | delay(100); 27 | 28 | read(); 29 | delay(100); 30 | 31 | get_access_mode(); 32 | delay(100); 33 | 34 | set_access_mode(0xFF); 35 | delay(100); 36 | 37 | get_access_mode(); 38 | delay(100); 39 | 40 | the_cart_helper.set_cart_stuff(); 41 | 42 | } 43 | 44 | 45 | 46 | 47 | void tpak::enable_tpak() 48 | { 49 | memset( &command[3], 0x84, 32 ); 50 | write(0x8000); 51 | } 52 | 53 | 54 | void tpak::get_access_mode() 55 | { 56 | read(0xB000); 57 | } 58 | 59 | 60 | void tpak::set_access_mode( bool n_mode ) 61 | { 62 | memset( &command[3], (char)n_mode, 32 ); 63 | write(0xB000); 64 | } 65 | 66 | 67 | void tpak::set_bank( char n_tpak_bank ) 68 | { 69 | current_bank = n_tpak_bank; 70 | 71 | memset( &command[3], n_tpak_bank, 32 ); 72 | write(0xA000); 73 | } 74 | 75 | 76 | // There is no way to ask the real life Transfer Pak for its current bank, 77 | // so this class will keep track of it. 78 | char tpak::get_bank() const 79 | { 80 | return current_bank; 81 | } 82 | 83 | 84 | void tpak::write() 85 | { 86 | command[0] = 0x03; 87 | command[1] = addr_pkt.hi; 88 | command[2] = addr_pkt.lo; 89 | 90 | N64_stuff( command, wcmd_size ); 91 | } 92 | 93 | 94 | 95 | void tpak::write( uint16_t write_addr ) 96 | { 97 | addr_pkt.w = calc_addr_crc(write_addr); 98 | command[0] = 0x03; 99 | command[1] = addr_pkt.hi; 100 | command[2] = addr_pkt.lo; 101 | 102 | N64_stuff( command, wcmd_size ); 103 | } 104 | 105 | 106 | 107 | void tpak::write( uint16_t write_addr, uint8_t* msg ) 108 | { 109 | addr_pkt.w = calc_addr_crc(write_addr); 110 | memcpy( &command[3], msg, 32 ); 111 | command[0] = 0x03; 112 | command[1] = addr_pkt.hi; 113 | command[2] = addr_pkt.lo; 114 | 115 | N64_stuff( command, wcmd_size ); 116 | } 117 | 118 | 119 | // Write a single, repeated byte 120 | void tpak::write_byte( uint16_t write_addr, uint8_t data ) 121 | { 122 | addr_pkt.w = calc_addr_crc(write_addr); 123 | //memcpy( &command[3], msg, 32 ); 124 | 125 | memset( &command[3], data, 32 ); 126 | command[0] = 0x03; 127 | command[1] = addr_pkt.hi; 128 | command[2] = addr_pkt.lo; 129 | 130 | N64_stuff( command, wcmd_size ); 131 | } 132 | 133 | 134 | //void tpak::write_nocrc( uint16_t write_addr ) 135 | //{ 136 | // addr_pkt.w = write_addr; 137 | // command[0] = 0x03; 138 | // command[1] = addr_pkt.hi; 139 | // command[2] = addr_pkt.lo; 140 | // 141 | // N64_stuff( command, wcmd_size ); 142 | //} 143 | 144 | 145 | 146 | //void tpak::write_nocrc( uint16_t write_addr, uint8_t *msg ) 147 | //{ 148 | // addr_pkt.w = write_addr; 149 | // memcpy( &command[3], msg, 32 ); 150 | // command[0] = 0x03; 151 | // command[1] = addr_pkt.hi; 152 | // command[2] = addr_pkt.lo; 153 | // 154 | // N64_stuff( command, wcmd_size ); 155 | //} 156 | 157 | 158 | 159 | void tpak::read() 160 | { 161 | command[0] = 0x02; 162 | command[1] = addr_pkt.hi; 163 | command[2] = addr_pkt.lo; 164 | 165 | N64_stuff( command, rcmd_size ); 166 | } 167 | 168 | 169 | 170 | void tpak::read( uint16_t read_addr ) 171 | { 172 | addr_pkt.w = calc_addr_crc(read_addr); 173 | command[0] = 0x02; 174 | command[1] = addr_pkt.hi; 175 | command[2] = addr_pkt.lo; 176 | 177 | N64_stuff( command, rcmd_size ); 178 | } 179 | 180 | 181 | 182 | //void tpak::read_nocrc( uint16_t read_addr ) 183 | //{ 184 | // addr_pkt.w = read_addr; 185 | // command[0] = 0x02; 186 | // command[1] = addr_pkt.hi; 187 | // command[2] = addr_pkt.lo; 188 | // 189 | // N64_stuff( command, rcmd_size ); 190 | //} 191 | 192 | 193 | -------------------------------------------------------------------------------- /src/arduinogbdump/tpak_class.h: -------------------------------------------------------------------------------- 1 | #ifndef tpak_class_h 2 | #define tpak_class_h 3 | 4 | 5 | #include "some_globals.h" 6 | 7 | #include "misc_types.h" 8 | 9 | class cart_helper; 10 | 11 | // A class for talking to an N64 Transfer Pak 12 | class tpak 13 | { 14 | protected: // variables 15 | static const word wcmd_size = 35, rcmd_size = 3; 16 | uint8_t command[wcmd_size]; 17 | addr_packet addr_pkt; 18 | 19 | 20 | //char mbc, rom_size, ram_size; int num_rom_banks, num_ram_kb; 21 | 22 | // The Transfer Pak's current bank 23 | char current_bank; 24 | 25 | public: // functions 26 | tpak(); 27 | ~tpak(); 28 | 29 | void init( cart_helper& the_cart_helper ); 30 | 31 | void enable_tpak(); 32 | 33 | void get_access_mode(); 34 | void set_access_mode( bool n_mode ); 35 | 36 | void set_bank( char n_tpak_bank ); 37 | 38 | // There is no way to ask the real life Transfer Pak for its current 39 | // bank, so this class will keep track of it. 40 | char get_bank() const; 41 | 42 | void write(); 43 | 44 | // appends address CRC to write_addr 45 | void write( uint16_t write_addr ); 46 | void write( uint16_t write_addr, uint8_t* msg ); 47 | 48 | // Write a single, repeated byte 49 | void write_byte( uint16_t write_addr, uint8_t data ); 50 | 51 | 52 | //// doesn't touch write_addr's CRC stuff 53 | //void write_nocrc( uint16_t write_addr ); 54 | //void write_nocrc( uint16_t write_addr, uint8_t *msg ); 55 | 56 | 57 | void read(); 58 | void read( uint16_t read_addr ); 59 | 60 | //void read_nocrc( uint16_t read_addr ); 61 | 62 | }; 63 | 64 | #endif // tpak_class_h 65 | -------------------------------------------------------------------------------- /src/arduinogbdump/types_c.taghl: -------------------------------------------------------------------------------- 1 | syn keyword CTagsStructure N64_status_t 2 | syn keyword CTagsMember ram_size lo rcmd_size stick_y data2 cart_mbc_type raw_rom_size w data1 raw_cart_type stick_x wcmd_size addr_pkt hi raw_ram_size my_tpak current_bank rom_size command 3 | syn keyword CTagsUnion addr_packet 4 | syn keyword CTagsGlobalVariable N64_status N64_raw_dump N64_mem_managed N64_mem_dump buf 5 | syn keyword CTagsConstant mega_bitwise_thing bufsize N64_byte_size N64_mem_size micro_bitwise_thing default_bitwise_thing 6 | syn keyword CTagsEnumeratorName ram_size_type serial_msg_type mbc_type 7 | syn keyword CTagsEnumerationValue mbc1_ram unknown_mbc_type rs_2 mbc5 sm_get_cart_stuff rs_32 mbc3_ram sm_gb_read_32_bytes rom_only mbc3 mbc3_timer rs_none sm_gb_write_32_bytes sm_print_cart_stuff mbc2 sm_gb_write_var_num_bytes sm_gb_read_var_num_bytes mbc3_timer_ram mbc5_ram rs_8 sm_reset_tpak rs_128 rs_mbc2 mbc1 8 | syn keyword CTagsFunction print_raw_data mbc5_set_ram_bank mbc1_dump_ram manage_mem_dump get_bank calc_tpak_bank write_mem_managed interpret_serial_message2 interpret_serial_message dump_rom mbc2_dump_rom mbc1_set_rom_bank_lo mbc1_enable_ram N64_stuff_2 set_raw_data print_cart_stuff calc_addr_crc print_mem_managed_2 read N64_read_addr write write_byte mbc5_enable_ram print_mem_managed2 mbc5_dump_rom 9 | syn keyword CTagsFunction translate_raw_data N64_stuff mbc1_set_rom_bank_hi tpak_stuff_2 mbc1_set_rom_bank mbc3_dump_rom enable_tpak get_access_mode print_crc_managed mbc5_set_rom_bank mbc1_dump_rom tpak_stuff mbc5_dump_ram set_access_mode mbc1_disable_ram N64_get interpret_raw_data set_bank write_byte_with_gb_addr rom_only_dump_rom loop2 init set_cart_stuff read_with_gb_addr cmp_buf calc_tpak_addr print_mem_managed calc_tpak_bank_and_tpak_addr calc_data_crc N64_send mbc5_disable_ram clear_mem_dump 10 | syn keyword CTagsType uint 11 | syn keyword CTagsDefinedName PORT_THING N64_HIGH cart_helper_mbc_funcs_h some_globals_h N64_LOW cart_helper_class_h misc_types_h tpak_class_h aux_code_h N64_PIN N64_QUERY cart_helper_enums_h 12 | syn keyword CTagsClass cart_helper tpak 13 | 14 | -------------------------------------------------------------------------------- /src/communicator/concatenate_banks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat ${1}_bank_[[:digit:]].bin ${1}_bank_[[:digit:]][[:digit:]].bin ${1}_bank_[[:digit:]][[:digit:]][[:digit:]].bin >> ${1}.gb 4 | #rm ${1}_bank* 5 | -------------------------------------------------------------------------------- /src/communicator/makefile: -------------------------------------------------------------------------------- 1 | CXX_DIRS=src 2 | 3 | 4 | PROJ=$(shell basename $(CURDIR)) 5 | 6 | 7 | CXX=g++ 8 | LD=gcc 9 | 10 | 11 | BASE_FLAGS=-masm=intel -Wall -O3 12 | CXX_FLAGS=-std=c++11 $(BASE_FLAGS) 13 | LD_FLAGS=-lstdc++ -lm 14 | 15 | 16 | 17 | OBJDIR=objs 18 | DEPDIR=deps 19 | OBJDIR_TEMP=objs_temp 20 | 21 | CXX_SOURCES=$(foreach DIR,$(CXX_DIRS),$(notdir $(wildcard $(DIR)/*.cpp))) 22 | 23 | export VPATH := $(foreach DIR,$(CXX_DIRS),$(CURDIR)/$(DIR)) 24 | 25 | CXX_OFILES=$(patsubst %.cpp,$(OBJDIR)/%.o,$(CXX_SOURCES)) 26 | OFILES=$(CXX_OFILES) 27 | 28 | CXX_PFILES=$(patsubst %.cpp,$(DEPDIR)/%.P,$(CXX_SOURCES)) 29 | PFILES=$(CXX_PFILES) 30 | 31 | CXX_OFILES_TEMP=$(patsubst %.cpp,$(OBJDIR_TEMP)/%.o,$(CXX_SOURCES)) 32 | OFILES_TEMP=$(CXX_OFILES_TEMP) 33 | 34 | 35 | all : all_pre $(OFILES) 36 | $(LD) $(OBJDIR)/*.o -o $(PROJ) $(LD_FLAGS) 37 | 38 | debug : all_pre $(OFILES) 39 | $(LD) $(OBJDIR)/*.o -o $(PROJ) $(LD_FLAGS) -g 40 | 41 | all_objs : all_pre $(OFILES) 42 | @# 43 | 44 | all_pre : 45 | mkdir -p $(OBJDIR) $(DEPDIR) 46 | 47 | $(CXX_OFILES) : $(OBJDIR)/%.o : %.cpp 48 | @#echo "Generating dependency information for "$@"...." 49 | @echo $@" was updated or has no object file. (Re)Compiling...." 50 | $(CXX) $(CXX_FLAGS) -MMD -c $< -o $@ 51 | @cp $(OBJDIR)/$*.d $(DEPDIR)/$*.P 52 | @sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ 53 | -e '/^$$/ d' -e 's/$$/ :/' < $(OBJDIR)/$*.d >> $(DEPDIR)/$*.P 54 | @rm -f $(OBJDIR)/$*.d 55 | 56 | -include $(PFILES) 57 | 58 | 59 | .PHONY : clean 60 | clean : 61 | rm -rfv $(OBJDIR) $(DEPDIR) $(PROJ) tags *.taghl 62 | 63 | .PHONY : clean_objs_with_no_source 64 | clean_objs_with_no_source : 65 | @mkdir -p $(OBJDIR_TEMP) 66 | @#ls $(OBJDIR) 67 | @echo "Removing object files that don't have corresponding source files...." 68 | @for objfile in $(OFILES); \ 69 | do \ 70 | if [ -f $$objfile ]; \ 71 | then \ 72 | mv $$objfile $(OBJDIR_TEMP); \ 73 | fi; \ 74 | done; 75 | @#ls $(OBJDIR_TEMP) 76 | @rm -rf $(OBJDIR) 77 | @mkdir -p $(OBJDIR) 78 | @for objfile in $(OFILES_TEMP); \ 79 | do \ 80 | if [ -f $$objfile ]; \ 81 | then \ 82 | mv $$objfile $(OBJDIR); \ 83 | fi; \ 84 | done; 85 | @#ls $(OBJDIR) 86 | @rmdir $(OBJDIR_TEMP) 87 | 88 | 89 | 90 | @#rm -rfv $(OBJDIR_TEMP) 91 | 92 | 93 | 94 | .PHONY : check_build 95 | check_build : 96 | make clean_objs_with_no_source && make -j8 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/communicator/src/communicator_class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef uint8_t u8; typedef int8_t s8; 4 | typedef uint16_t u16; typedef int16_t s16; 5 | typedef uint32_t u32; typedef int32_t s32; 6 | typedef uint64_t u64; typedef int64_t s64; 7 | typedef unsigned int uint; 8 | 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | #include "misc_types.hpp" 25 | #include "stuffs.hpp" 26 | 27 | 28 | #include "communicator_class.hpp" 29 | 30 | 31 | communicator::communicator( int argc, char** argv ) 32 | { 33 | //if ( of_name != "" ) 34 | //{ 35 | // ofile.open( of_name, ios_base::out | ios_base::binary ); 36 | //} 37 | // 38 | //if ( if_name != "" ) 39 | //{ 40 | // ifile.open( if_name, ios_base::in | ios_base::binary ); 41 | //} 42 | 43 | //fd = open( argv[1], O_RDWR | O_NOCTTY | O_NONBLOCK | O_SYNC ); 44 | fd = open( argv[1], O_RDWR | O_NOCTTY | O_NONBLOCK ); 45 | 46 | if ( fd < 0 ) 47 | { 48 | cout << "Error opening Arduino." << endl; 49 | return; 50 | } 51 | 52 | // Wait for the Arduino Mega to finish resetting. It'd be nice if it 53 | // didn't always reset upon serial connection! 54 | usleep(1000 * 1000); 55 | 56 | string argv2 = argv[2], argv3 = argv[3]; 57 | 58 | 59 | communicator_action action; 60 | 61 | if ( argv2 == "dump_rom" ) 62 | { 63 | action = do_rom_dump; 64 | } 65 | else if ( argv2 == "dump_rom_banks" ) 66 | { 67 | action = do_rom_banks_dump; 68 | } 69 | else if ( argv2 == "dump_ram" ) 70 | { 71 | action = do_ram_dump; 72 | } 73 | else if ( argv2 == "restore_ram" ) 74 | { 75 | action = do_ram_restore; 76 | } 77 | else 78 | { 79 | cout << "Error: Invalid command.\n"; 80 | return; 81 | } 82 | 83 | 84 | u16 start_bank = 0x0000, num_banks = 0x0000; 85 | 86 | switch (action) 87 | { 88 | case do_rom_dump: 89 | of_name = argv3; 90 | ofile.open( of_name, ios_base::out | ios_base::binary ); 91 | 92 | if ( !ofile.is_open() ) 93 | { 94 | cout << "Error opening file \"" << of_name << "\" for" 95 | << " writing!\n"; 96 | return; 97 | } 98 | 99 | if ( argc > 4 ) 100 | { 101 | stringstream the_sstm; 102 | the_sstm << argv[4]; 103 | 104 | the_sstm >> start_bank; 105 | } 106 | if ( argc > 5 ) 107 | { 108 | stringstream the_sstm; 109 | the_sstm << argv[5]; 110 | 111 | the_sstm >> num_banks; 112 | } 113 | // Arguments past argv[5] are ignored 114 | 115 | dump_rom( start_bank, num_banks ); 116 | 117 | break; 118 | 119 | case do_rom_banks_dump: 120 | // In this case, of_name is used as the base name for all the 121 | // ROM bank files that are to be generate 122 | of_name = argv3; 123 | 124 | if ( argc > 4 ) 125 | { 126 | stringstream the_sstm; 127 | the_sstm << argv[4]; 128 | 129 | the_sstm >> start_bank; 130 | } 131 | if ( argc > 5 ) 132 | { 133 | stringstream the_sstm; 134 | the_sstm << argv[5]; 135 | 136 | the_sstm >> num_banks; 137 | } 138 | // Arguments past argv[5] are ignored 139 | 140 | dump_rom_banks_to_separate_files( start_bank, num_banks ); 141 | 142 | break; 143 | 144 | case do_ram_dump: 145 | of_name = argv3; 146 | ofile.open( of_name, ios_base::out | ios_base::binary ); 147 | 148 | if ( !ofile.is_open () ) 149 | { 150 | cout << "Error opening file \"" << of_name << "\" for" 151 | << " writing!\n"; 152 | return; 153 | } 154 | 155 | dump_ram(); 156 | 157 | break; 158 | 159 | case do_ram_restore: 160 | if_name = argv3; 161 | ifile.open( if_name, ios_base::in | ios_base::binary ); 162 | 163 | if ( !ifile.is_open() ) 164 | { 165 | cout << "Error opening file \"" << if_name << "\" for" 166 | << " reading!\n"; 167 | return; 168 | } 169 | 170 | restore_ram(); 171 | 172 | break; 173 | 174 | default: 175 | cout << "There's some weird bug....\n"; 176 | return; 177 | break; 178 | } 179 | 180 | 181 | } 182 | 183 | communicator::~communicator() 184 | { 185 | } 186 | 187 | 188 | void communicator::get_cart_stuff() 189 | { 190 | send_buf[0] = sm_get_cart_stuff; 191 | 192 | while ( do_select_for_write(fd) ) 193 | { 194 | cout << "Unable to write!\n"; 195 | } 196 | 197 | int num_written_bytes = write( fd, send_buf.data (), 1 ); 198 | if ( num_written_bytes <= 0 ) 199 | { 200 | cout << "No bytes were written!\n"; 201 | exit(1); 202 | } 203 | 204 | for (;;) 205 | { 206 | int select_result = do_select_for_read(fd); 207 | 208 | if ( select_result == 1 ) 209 | { 210 | cout << "Error in select()ing for read()!\n"; 211 | exit(1); 212 | } 213 | else if ( select_result == 2 ) 214 | { 215 | //cout << "The Arduino isn't ready to be read() from!\n"; 216 | } 217 | else 218 | { 219 | //cout << "Ready to read()!\n"; 220 | break; 221 | } 222 | } 223 | 224 | if ( loop_for_reading_32_bytes() ) 225 | { 226 | exit(1); 227 | } 228 | 229 | cart_mbc_type = (mbc_type)(recv_buf[0]); 230 | 231 | addr_packet rom_size_pkt; 232 | rom_size_pkt.hi = recv_buf[1]; 233 | rom_size_pkt.lo = recv_buf[2]; 234 | 235 | rom_size = rom_size_pkt.w; 236 | 237 | ram_size = (ram_size_type)(recv_buf[3]); 238 | 239 | cout << hex << cart_mbc_type << " " << rom_size << " " << ram_size 240 | << dec << endl; 241 | 242 | //exit(1); 243 | } 244 | 245 | 246 | void communicator::hl_read_32_bytes( u16 gb_addr ) 247 | { 248 | send_buf[0] = sm_gb_read_32_bytes; 249 | 250 | addr_packet temp_pkt; 251 | temp_pkt.w = gb_addr; 252 | 253 | send_buf[1] = temp_pkt.hi; 254 | send_buf[2] = temp_pkt.lo; 255 | 256 | 257 | while ( do_select_for_write(fd) ) 258 | { 259 | cout << "Unable to write!\n"; 260 | } 261 | 262 | write( fd, send_buf.data(), 3 ); 263 | 264 | 265 | loop_for_reading_32_bytes(); 266 | 267 | // received data is now in recv_buf 268 | } 269 | 270 | 271 | void communicator::hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, 272 | u16 num_bytes ) 273 | { 274 | send_buf[0] = sm_gb_read_var_num_bytes; 275 | 276 | addr_packet gb_start_addr_pkt, num_bytes_pkt; 277 | 278 | gb_start_addr_pkt.w = gb_start_addr; 279 | num_bytes_pkt.w = num_bytes; 280 | 281 | send_buf[1] = gb_start_addr_pkt.hi; 282 | send_buf[2] = gb_start_addr_pkt.lo; 283 | 284 | send_buf[3] = num_bytes_pkt.hi; 285 | send_buf[4] = num_bytes_pkt.lo; 286 | 287 | 288 | while ( do_select_for_write(fd) ) 289 | { 290 | cout << "Unable to write!\n"; 291 | } 292 | 293 | write( fd, send_buf.data(), 5 ); 294 | 295 | loop_for_reading_var_num_bytes(num_bytes); 296 | 297 | ofile.write( recv_buf.data(), num_bytes ); 298 | ofile.flush(); 299 | 300 | } 301 | 302 | void communicator::hl_write_32_bytes( u16 gb_addr ) 303 | { 304 | send_buf[0] = sm_gb_write_32_bytes; 305 | 306 | addr_packet temp_pkt; 307 | temp_pkt.w = gb_addr; 308 | 309 | send_buf[1] = temp_pkt.hi; 310 | send_buf[2] = temp_pkt.lo; 311 | 312 | //memset( &send_buf[3], the_byte, 32 ); 313 | 314 | while( do_select_for_write(fd) ) 315 | { 316 | cout << "Unable to write!\n"; 317 | } 318 | 319 | write( fd, send_buf.data(), 3 ); 320 | 321 | loop_for_reading_32_bytes(); 322 | 323 | // received data is now in recv_buf 324 | } 325 | 326 | // This function writes a single, repeated byte (for stability) to an 327 | // address in GB format, NOT tpak format. 328 | void communicator::hl_write_rept_byte( u16 gb_addr, u8 the_byte ) 329 | { 330 | //do_buf_memsets(); 331 | 332 | send_buf[0] = sm_gb_write_32_bytes; 333 | 334 | addr_packet temp_pkt; 335 | temp_pkt.w = gb_addr; 336 | 337 | send_buf[1] = temp_pkt.hi; 338 | send_buf[2] = temp_pkt.lo; 339 | 340 | memset( &send_buf[3], the_byte, 32 ); 341 | 342 | while ( do_select_for_write(fd) ) 343 | { 344 | cout << "Unable to write!\n"; 345 | } 346 | 347 | write( fd, send_buf.data(), 35 ); 348 | 349 | loop_for_reading_32_bytes(); 350 | 351 | // received data is now in recv_buf 352 | } 353 | 354 | 355 | 356 | // The max value for num_bytes is 1024 (0x400) 357 | // More than 0x400 bytes will probably cause a buffer overflow on 358 | // the Arduino. 359 | void communicator::hl_read_from_ifile_and_write_bytes( u16 gb_start_addr, 360 | u16 num_bytes, u8 gb_ram_bank ) 361 | { 362 | send_buf[0] = sm_gb_write_var_num_bytes; 363 | 364 | addr_packet gb_start_addr_pkt, num_bytes_pkt; 365 | 366 | gb_start_addr_pkt.w = gb_start_addr; 367 | num_bytes_pkt.w = num_bytes; 368 | 369 | send_buf[1] = gb_start_addr_pkt.hi; 370 | send_buf[2] = gb_start_addr_pkt.lo; 371 | 372 | send_buf[3] = num_bytes_pkt.hi; 373 | send_buf[4] = num_bytes_pkt.lo; 374 | 375 | while ( do_select_for_write(fd) ) 376 | { 377 | } 378 | write( fd, send_buf.data(), 5 ); 379 | 380 | loop_for_reading_32_bytes(); 381 | 382 | while ( do_select_for_write(fd) ) 383 | { 384 | } 385 | 386 | ifile.seekg( gb_start_addr - 0xa000 + ( 0x2000 * gb_ram_bank ) ); 387 | ifile.read( send_buf.data(), num_bytes ); 388 | 389 | cout << hex << ifile.tellg() << endl; 390 | 391 | write( fd, send_buf.data(), num_bytes ); 392 | 393 | 394 | string from_arduino; 395 | 396 | while ( do_select_for_read(fd) ) 397 | { 398 | } 399 | do_arduino_read( fd, from_arduino ); 400 | 401 | cout << from_arduino; 402 | //cout << "LIVE TO BEEF AGAIN! Is end.\n\n\n"; 403 | } 404 | 405 | 406 | void communicator::dump_rom_test() 407 | { 408 | send_buf[0] = sm_gb_read_var_num_bytes; 409 | 410 | addr_packet gb_start_addr_pkt, num_bytes_pkt; 411 | 412 | gb_start_addr_pkt.w = 0x0000; 413 | num_bytes_pkt.w = 0x4000; 414 | 415 | send_buf[1] = gb_start_addr_pkt.hi; 416 | send_buf[2] = gb_start_addr_pkt.lo; 417 | 418 | send_buf[3] = num_bytes_pkt.hi; 419 | send_buf[4] = num_bytes_pkt.lo; 420 | 421 | while( do_select_for_write(fd) ) 422 | { 423 | cout << "Unable to write!\n"; 424 | } 425 | 426 | write( fd, send_buf.data(), 5 ); 427 | 428 | 429 | for( uint i2=0; i2<( num_bytes_pkt.w / 0x20 ); ++i2 ) 430 | { 431 | loop_for_reading_32_bytes(); 432 | 433 | ofile.write( recv_buf.data(), 0x20 ); 434 | ofile.flush(); 435 | } 436 | 437 | 438 | } 439 | 440 | 441 | 442 | void communicator::rom_only_dump_single_rom_bank( u16 bank ) 443 | { 444 | cout << "Dumping ROM bank " << bank << endl; 445 | 446 | if ( bank == 0x0000 ) 447 | { 448 | hl_read_bytes_and_write_to_ofile( 0x0000, rom_bank_size ); 449 | } 450 | else 451 | { 452 | hl_read_bytes_and_write_to_ofile( 0x4000, rom_bank_size ); 453 | } 454 | } 455 | 456 | void communicator::mbc1_dump_single_rom_bank( u16 bank ) 457 | { 458 | cout << "Dumping ROM bank " << bank << endl; 459 | 460 | if ( bank == 0x0000 ) 461 | { 462 | hl_read_bytes_and_write_to_ofile( 0x0000, rom_bank_size ); 463 | } 464 | else 465 | { 466 | // Enable ROM-banking mode 467 | hl_write_rept_byte( 0x6000, 0x00 ); 468 | 469 | // Write the upper 2 bits of the ROM bank 470 | hl_write_rept_byte( 0x4000, (u8)( ( bank & 0x60 ) >> 5 ) ); 471 | 472 | // Write the lower 5 bits of the ROM bank 473 | hl_write_rept_byte( 0x2000, (u8)( bank & 0x1f ) ); 474 | 475 | // Finally, read the ROM bank 476 | hl_read_bytes_and_write_to_ofile( 0x4000, rom_bank_size ); 477 | } 478 | 479 | } 480 | 481 | void communicator::mbc2_dump_single_rom_bank( u16 bank ) 482 | { 483 | cout << "Dumping ROM bank " << bank << endl; 484 | 485 | if( bank == 0x0000 ) 486 | { 487 | hl_read_bytes_and_write_to_ofile( 0x0000, rom_bank_size ); 488 | } 489 | else 490 | { 491 | hl_write_rept_byte( 0x2100,(u8)( bank & 0x0f ) ); 492 | hl_read_bytes_and_write_to_ofile( 0x4000, rom_bank_size ); 493 | } 494 | 495 | } 496 | 497 | void communicator::mbc3_dump_single_rom_bank( u16 bank ) 498 | { 499 | cout << "Dumping ROM bank " << bank << endl; 500 | 501 | if( bank == 0x0000 ) 502 | { 503 | hl_read_bytes_and_write_to_ofile( 0x0000, rom_bank_size ); 504 | } 505 | else 506 | { 507 | hl_write_rept_byte( 0x2000, (u8)( bank & 0x7f ) ); 508 | hl_read_bytes_and_write_to_ofile( 0x4000, rom_bank_size ); 509 | } 510 | } 511 | 512 | void communicator::mbc5_dump_single_rom_bank( u16 bank ) 513 | { 514 | cout << "Dumping ROM bank " << bank << endl; 515 | 516 | // MBC5 is nice because it lets me do everything with just the 517 | // SWITCHABLE ROM bank 518 | hl_write_rept_byte( 0x2000, (u8)( bank & 0xff ) ); 519 | hl_read_bytes_and_write_to_ofile( 0x4000, rom_bank_size ); 520 | } 521 | 522 | 523 | 524 | 525 | void communicator::rom_only_dump_rom() 526 | { 527 | get_cart_stuff(); 528 | 529 | if ( cart_mbc_type != rom_only ) 530 | { 531 | cout << "Error: The cartridge type is not \"rom_only\"!\n"; 532 | return; 533 | } 534 | 535 | rom_only_dump_single_rom_bank(0x0000); 536 | rom_only_dump_single_rom_bank(0x0001); 537 | } 538 | 539 | void communicator::mbc1_dump_rom( u16 start_bank, u16 num_banks ) 540 | { 541 | get_cart_stuff(); 542 | 543 | if ( ( cart_mbc_type != mbc1 ) && ( cart_mbc_type != mbc1_ram ) ) 544 | { 545 | cout << "Error: The cartridge doesn't seem to have an MBC1!\n"; 546 | return; 547 | } 548 | 549 | if ( ( num_banks == 0x0000 ) || ( num_banks - start_bank ) > rom_size ) 550 | { 551 | for ( uint i=start_bank; i rom_size ) 578 | { 579 | for ( uint i=start_bank; i rom_size ) 609 | { 610 | for ( uint i=start_bank; i 256 ) 636 | { 637 | cout << "Error: Even though the cartridge has an MBC5, it is not" 638 | << " yet supported.\n"; 639 | cout << "Details: Too many ROM banks.\n"; 640 | return; 641 | } 642 | 643 | 644 | if ( ( num_banks == 0x0000 ) || ( num_banks - start_bank ) > rom_size ) 645 | { 646 | //cout << "1234\n\n"; 647 | for ( uint i=start_bank; i rom_size ) 697 | { 698 | for ( uint i=start_bank; i> the_bank_str; 705 | 706 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 707 | ios_base::out | ios_base::binary ); 708 | mbc1_dump_single_rom_bank(i); 709 | ofile.close(); 710 | } 711 | } 712 | else 713 | { 714 | for ( uint i=start_bank; i> the_bank_str; 721 | 722 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 723 | ios_base::out | ios_base::binary ); 724 | mbc1_dump_single_rom_bank(i); 725 | ofile.close(); 726 | } 727 | } 728 | } 729 | 730 | void communicator::mbc2_dump_rom_banks_to_separate_files( u16 start_bank, 731 | u16 num_banks ) 732 | { 733 | get_cart_stuff(); 734 | 735 | if ( cart_mbc_type != mbc2 ) 736 | { 737 | cout << "Error: The cartridge doesn't seem to have an MBC2!\n"; 738 | return; 739 | } 740 | 741 | if ( ( num_banks == 0x0000 ) || ( num_banks - start_bank ) > rom_size ) 742 | { 743 | for ( uint i=start_bank; i> the_bank_str; 750 | 751 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 752 | ios_base::out | ios_base::binary ); 753 | mbc2_dump_single_rom_bank(i); 754 | ofile.close(); 755 | } 756 | } 757 | else 758 | { 759 | for ( uint i=start_bank; i> the_bank_str; 766 | 767 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 768 | ios_base::out | ios_base::binary ); 769 | mbc2_dump_single_rom_bank(i); 770 | ofile.close(); 771 | } 772 | } 773 | 774 | } 775 | 776 | void communicator::mbc3_dump_rom_banks_to_separate_files( u16 start_bank, 777 | u16 num_banks ) 778 | { 779 | get_cart_stuff(); 780 | 781 | if ( ( cart_mbc_type != mbc3 ) && ( cart_mbc_type != mbc3_timer ) 782 | && ( cart_mbc_type != mbc3_timer_ram ) 783 | && ( cart_mbc_type != mbc3_ram ) ) 784 | { 785 | cout << "Error: The cartridge doesn't seem to have an MBC3!\n"; 786 | return; 787 | } 788 | 789 | 790 | if ( ( num_banks == 0x0000 ) || ( num_banks - start_bank ) > rom_size ) 791 | { 792 | for ( uint i=start_bank; i> the_bank_str; 799 | 800 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 801 | ios_base::out | ios_base::binary ); 802 | mbc3_dump_single_rom_bank(i); 803 | ofile.close(); 804 | } 805 | } 806 | else 807 | { 808 | for ( uint i=start_bank; i> the_bank_str; 815 | 816 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 817 | ios_base::out | ios_base::binary ); 818 | mbc3_dump_single_rom_bank(i); 819 | ofile.close(); 820 | } 821 | } 822 | 823 | } 824 | 825 | void communicator::mbc5_dump_rom_banks_to_separate_files( u16 start_bank, 826 | u16 num_banks ) 827 | { 828 | get_cart_stuff(); 829 | 830 | if ( ( cart_mbc_type != mbc5 ) && ( cart_mbc_type != mbc5_ram ) ) 831 | { 832 | cout << "Error: The cartridge doesn't seem to have an MBC5!\n"; 833 | return; 834 | } 835 | 836 | if ( rom_size > 256 ) 837 | { 838 | cout << "Error: Even though the cartridge has an MBC5, it is not" 839 | << " yet supported.\n"; 840 | cout << "Details: Too many ROM banks.\n"; 841 | return; 842 | } 843 | 844 | if ( ( num_banks == 0x0000 ) || ( num_banks - start_bank ) > rom_size ) 845 | { 846 | for ( uint i=start_bank; i> the_bank_str; 853 | 854 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 855 | ios_base::out | ios_base::binary ); 856 | mbc5_dump_single_rom_bank(i); 857 | ofile.close(); 858 | } 859 | } 860 | else 861 | { 862 | for ( uint i=start_bank; i> the_bank_str; 869 | 870 | ofile.open( of_name + "_bank_" + the_bank_str + ".bin", 871 | ios_base::out | ios_base::binary ); 872 | mbc5_dump_single_rom_bank(i); 873 | ofile.close(); 874 | } 875 | } 876 | 877 | } 878 | 879 | 880 | 881 | // Main RAM dumping functions 882 | void communicator::mbc1_dump_ram() 883 | { 884 | switch (ram_size) 885 | { 886 | case rs_none: 887 | cout << "Error: This cartridge doesn't have any RAM.\n"; 888 | break; 889 | 890 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 891 | case rs_2: 892 | // Enable RAM so we can read from it 893 | hl_write_rept_byte( 0x0000, 0x0a ); 894 | 895 | // Now we read the 2 kiB of RAM 896 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 897 | 898 | // Disable RAM for safety 899 | hl_write_rept_byte( 0x0000, 0x00 ); 900 | 901 | break; 902 | 903 | 904 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 905 | case rs_8: 906 | // Enable RAM so we can read from it 907 | hl_write_rept_byte( 0x0000, 0x0a ); 908 | 909 | // Now we read the 8 kiB of RAM 910 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 911 | 912 | // Disable RAM for safety 913 | hl_write_rept_byte( 0x0000, 0x00 ); 914 | 915 | 916 | break; 917 | 918 | case rs_32: 919 | for ( uint i=0; i<4; ++i ) 920 | { 921 | cout << "Dumping RAM bank " << i << endl; 922 | 923 | // In order to set the RAM bank, we have to disable RAM 924 | hl_write_rept_byte( 0x0000, 0x00 ); 925 | 926 | // Now we enable RAM banking mode 927 | hl_write_rept_byte( 0x6000, 0x01 ); 928 | 929 | // Now we set the RAM bank 930 | hl_write_rept_byte( 0x4000, (u8)( i & 0x03 ) ); 931 | 932 | // Then we enable RAM again 933 | hl_write_rept_byte( 0x0000, 0x0a ); 934 | 935 | // Now we read the 8 kiB of RAM 936 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 937 | } 938 | 939 | // Disable RAM for safety 940 | hl_write_rept_byte( 0x0000, 0x00 ); 941 | 942 | break; 943 | 944 | default: 945 | 946 | break; 947 | } 948 | } 949 | void communicator::mbc2_dump_ram() 950 | { 951 | // All MBC2 chips have built-in RAM (512x4bits) 952 | 953 | // Enable RAM so we can read from it 954 | hl_write_rept_byte( 0x0000, 0x0a ); 955 | 956 | // Read the RAM contents 957 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x200 ); 958 | 959 | // Disable RAM again, for safety 960 | hl_write_rept_byte( 0x0000, 0x00 ); 961 | } 962 | void communicator::mbc3_dump_ram() 963 | { 964 | switch (ram_size) 965 | { 966 | case rs_none: 967 | cout << "Error: This cartridge doesn't have any RAM.\n"; 968 | break; 969 | 970 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 971 | // I'm not sure MBC5 cartridges ever had only 2 kiB of RAM. 972 | case rs_2: 973 | // Enable RAM so we can read from it 974 | hl_write_rept_byte( 0x0000, 0x0a ); 975 | 976 | // Now we read the 2 kiB of RAM 977 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 978 | 979 | // Disable RAM for safety 980 | hl_write_rept_byte( 0x0000, 0x00 ); 981 | 982 | break; 983 | 984 | 985 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 986 | case rs_8: 987 | // Enable RAM so we can read from it 988 | hl_write_rept_byte( 0x0000, 0x0a ); 989 | 990 | // Now we read the 8 kiB of RAM 991 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 992 | 993 | // Disable RAM for safety 994 | hl_write_rept_byte( 0x0000, 0x00 ); 995 | 996 | 997 | break; 998 | 999 | case rs_32: 1000 | for ( uint i=0; i<4; ++i ) 1001 | { 1002 | cout << "Dumping RAM bank " << i << endl; 1003 | 1004 | // In order to set the RAM bank, we have to disable RAM 1005 | hl_write_rept_byte( 0x0000, 0x00 ); 1006 | 1007 | // Now we set the RAM bank 1008 | hl_write_rept_byte( 0x4000, (u8)( i & 0x0f ) ); 1009 | 1010 | // Then we enable RAM again 1011 | hl_write_rept_byte( 0x0000, 0x0a ); 1012 | 1013 | 1014 | // Now we read the 8 kiB of RAM 1015 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 1016 | } 1017 | 1018 | // Disable RAM for safety 1019 | hl_write_rept_byte( 0x0000, 0x00 ); 1020 | 1021 | break; 1022 | 1023 | default: 1024 | 1025 | break; 1026 | } 1027 | 1028 | } 1029 | void communicator::mbc5_dump_ram() 1030 | { 1031 | switch (ram_size) 1032 | { 1033 | case rs_none: 1034 | cout << "Error: This cartridge doesn't have any RAM.\n"; 1035 | break; 1036 | 1037 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 1038 | // I'm not sure MBC5 cartridges ever had only 2 kiB of RAM. 1039 | case rs_2: 1040 | // Enable RAM so we can read from it 1041 | hl_write_rept_byte( 0x0000, 0x0a ); 1042 | 1043 | // Now we read the 2 kiB of RAM 1044 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 1045 | 1046 | // Disable RAM for safety 1047 | hl_write_rept_byte( 0x0000, 0x00 ); 1048 | 1049 | break; 1050 | 1051 | 1052 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 1053 | case rs_8: 1054 | // Enable RAM so we can read from it 1055 | hl_write_rept_byte( 0x0000, 0x0a ); 1056 | 1057 | // Now we read the 8 kiB of RAM 1058 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 1059 | 1060 | // Disable RAM for safety 1061 | hl_write_rept_byte( 0x0000, 0x00 ); 1062 | 1063 | 1064 | break; 1065 | 1066 | case rs_32: 1067 | for ( uint i=0; i<4; ++i ) 1068 | { 1069 | cout << "Dumping RAM bank " << i << endl; 1070 | 1071 | // In order to set the RAM bank, we have to disable RAM 1072 | hl_write_rept_byte( 0x0000, 0x00 ); 1073 | 1074 | // Now we set the RAM bank 1075 | hl_write_rept_byte( 0x4000, (u8)( i & 0x0f ) ); 1076 | 1077 | // Then we enable RAM again 1078 | hl_write_rept_byte( 0x0000, 0x0a ); 1079 | 1080 | 1081 | // Now we read the 8 kiB of RAM 1082 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 1083 | } 1084 | 1085 | // Disable RAM for safety 1086 | hl_write_rept_byte( 0x0000, 0x00 ); 1087 | 1088 | break; 1089 | 1090 | case rs_128: 1091 | for ( uint i=0; i<16; ++i ) 1092 | { 1093 | cout << "Dumping RAM bank " << i << endl; 1094 | 1095 | // In order to set the RAM bank, we have to disable RAM 1096 | hl_write_rept_byte( 0x0000, 0x00 ); 1097 | 1098 | // Now we set the RAM bank 1099 | hl_write_rept_byte( 0x4000, (u8)( i & 0x0f ) ); 1100 | 1101 | // Then we enable RAM again 1102 | hl_write_rept_byte( 0x0000, 0x0a ); 1103 | 1104 | 1105 | // Now we read the 8 kiB of RAM 1106 | hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 1107 | } 1108 | 1109 | // Disable RAM for safety 1110 | hl_write_rept_byte( 0x0000, 0x00 ); 1111 | 1112 | break; 1113 | 1114 | default: 1115 | 1116 | break; 1117 | } 1118 | } 1119 | 1120 | // Main RAM restoring functions 1121 | void communicator::mbc1_restore_ram() 1122 | { 1123 | switch (ram_size) 1124 | { 1125 | case rs_none: 1126 | cout << "Error: This cartridge doesn't have any RAM.\n"; 1127 | break; 1128 | 1129 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 1130 | case rs_2: 1131 | // Enable RAM so we can read from it 1132 | hl_write_rept_byte( 0x0000, 0x0a ); 1133 | 1134 | // Now we read the 2 kiB of RAM 1135 | //hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 1136 | 1137 | hl_read_from_ifile_and_write_bytes( 0xa000, 0x400 ); 1138 | hl_read_from_ifile_and_write_bytes( 0xa400, 0x400 ); 1139 | 1140 | // Disable RAM for safety 1141 | hl_write_rept_byte( 0x0000, 0x00 ); 1142 | 1143 | break; 1144 | 1145 | 1146 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 1147 | case rs_8: 1148 | // Enable RAM so we can read from it 1149 | hl_write_rept_byte( 0x0000, 0x0a ); 1150 | 1151 | // Now we read the 8 kiB of RAM 1152 | //hl_read_bytes_and_write_to_ofile( 0xa000, 0x2000 ); 1153 | 1154 | for ( uint i=0x0000; i<0x2000; i+=0x400 ) 1155 | { 1156 | hl_read_from_ifile_and_write_bytes( 0xa000 + i, 0x400 ); 1157 | } 1158 | 1159 | // Disable RAM for safety 1160 | hl_write_rept_byte( 0x0000, 0x00 ); 1161 | 1162 | 1163 | break; 1164 | 1165 | case rs_32: 1166 | for ( uint i=0; i<4; ++i ) 1167 | { 1168 | cout << "Dumping RAM bank " << i << endl; 1169 | 1170 | // In order to set the RAM bank, we have to disable RAM 1171 | hl_write_rept_byte( 0x0000, 0x00 ); 1172 | 1173 | // Now we enable RAM banking mode 1174 | hl_write_rept_byte( 0x6000, 0x01 ); 1175 | 1176 | // Now we set the RAM bank 1177 | hl_write_rept_byte( 0x4000, (u8)( i & 0x03 ) ); 1178 | 1179 | // Then we enable RAM again 1180 | hl_write_rept_byte( 0x0000, 0x0a ); 1181 | 1182 | // Now we write the 8 kiB of RAM 1183 | for ( uint j=0x0000; j<0x2000; j+=0x400 ) 1184 | { 1185 | hl_read_from_ifile_and_write_bytes( 0xa000 + j, 0x400, 1186 | i ); 1187 | } 1188 | } 1189 | 1190 | // Disable RAM for safety 1191 | hl_write_rept_byte( 0x0000, 0x00 ); 1192 | 1193 | break; 1194 | 1195 | default: 1196 | 1197 | break; 1198 | } 1199 | } 1200 | void communicator::mbc2_restore_ram() 1201 | { 1202 | 1203 | } 1204 | void communicator::mbc3_restore_ram() 1205 | { 1206 | switch (ram_size) 1207 | { 1208 | case rs_none: 1209 | cout << "Error: This cartridge doesn't have any RAM.\n"; 1210 | break; 1211 | 1212 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 1213 | // I'm not sure MBC3 cartridges ever had only 2 kiB of RAM. 1214 | case rs_2: 1215 | // Enable RAM so we can write to it 1216 | hl_write_rept_byte( 0x0000, 0x0a ); 1217 | 1218 | // Now we write the 2 kiB of RAM 1219 | //hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 1220 | 1221 | hl_read_from_ifile_and_write_bytes( 0xa000, 0x400 ); 1222 | hl_read_from_ifile_and_write_bytes( 0xa400, 0x400 ); 1223 | 1224 | // Disable RAM for safety 1225 | hl_write_rept_byte( 0x0000, 0x00 ); 1226 | 1227 | break; 1228 | 1229 | 1230 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 1231 | case rs_8: 1232 | // Enable RAM so we can read from it 1233 | hl_write_rept_byte( 0x0000, 0x0a ); 1234 | 1235 | // Now we write the 8 kiB of RAM 1236 | for ( uint i=0x0000; i<0x2000; i+=0x400 ) 1237 | { 1238 | hl_read_from_ifile_and_write_bytes( 0xa000 + i, 0x400 ); 1239 | } 1240 | 1241 | 1242 | // Disable RAM for safety 1243 | hl_write_rept_byte( 0x0000, 0x00 ); 1244 | 1245 | break; 1246 | 1247 | case rs_32: 1248 | for ( uint i=0; i<4; ++i ) 1249 | { 1250 | cout << "Restoring RAM bank " << i << endl; 1251 | 1252 | 1253 | // Disable RAM so that we can change RAM banks. 1254 | // It'd be nice if they'd SAY that you need to do that in 1255 | // places like the Pan Docs. I had a hard time figuring 1256 | // out why I wasn't getting valid RAM data, and this was 1257 | // the reason. It was a very annoying bug to squash. 1258 | hl_write_rept_byte( 0x0000, 0x00 ); 1259 | 1260 | // Set the RAM bank. 1261 | hl_write_rept_byte( 0x4000, (u8)( i & 0x03 ) ); 1262 | 1263 | // Enable RAM again so we can write to it. 1264 | hl_write_rept_byte( 0x0000, 0x0a ); 1265 | 1266 | 1267 | // Now we write the 8 kiB of RAM 1268 | for ( uint j=0x0000; j<0x2000; j+=0x400 ) 1269 | { 1270 | hl_read_from_ifile_and_write_bytes( 0xa000 + j, 0x400, 1271 | i ); 1272 | } 1273 | } 1274 | 1275 | // Disable RAM for safety 1276 | hl_write_rept_byte( 0x0000, 0x00 ); 1277 | 1278 | break; 1279 | 1280 | default: 1281 | 1282 | break; 1283 | } 1284 | } 1285 | void communicator::mbc5_restore_ram() 1286 | { 1287 | switch (ram_size) 1288 | { 1289 | case rs_none: 1290 | cout << "Error: This cartridge doesn't have any RAM.\n"; 1291 | break; 1292 | 1293 | // 0x800 bytes (2 kiB) of RAM (not even a full 8 kiB bank) 1294 | // I'm not sure MBC5 cartridges ever had only 2 kiB of RAM. 1295 | case rs_2: 1296 | // Enable RAM so we can write to it 1297 | hl_write_rept_byte( 0x0000, 0x0a ); 1298 | 1299 | // Now we write the 2 kiB of RAM 1300 | //hl_read_bytes_and_write_to_ofile( 0xa000, 0x800 ); 1301 | 1302 | hl_read_from_ifile_and_write_bytes( 0xa000, 0x400 ); 1303 | hl_read_from_ifile_and_write_bytes( 0xa400, 0x400 ); 1304 | 1305 | // Disable RAM for safety 1306 | hl_write_rept_byte( 0x0000, 0x00 ); 1307 | 1308 | break; 1309 | 1310 | 1311 | // 0x2000 bytes (8 kiB) of RAM (only one full 8 kiB bank) 1312 | case rs_8: 1313 | // Enable RAM so we can read from it 1314 | hl_write_rept_byte( 0x0000, 0x0a ); 1315 | 1316 | // Now we write the 8 kiB of RAM 1317 | for ( uint i=0x0000; i<0x2000; i+=0x400 ) 1318 | { 1319 | hl_read_from_ifile_and_write_bytes( 0xa000 + i, 0x400 ); 1320 | } 1321 | 1322 | 1323 | // Disable RAM for safety 1324 | hl_write_rept_byte( 0x0000, 0x00 ); 1325 | 1326 | break; 1327 | 1328 | case rs_32: 1329 | for( uint i=0; i<4; ++i ) 1330 | { 1331 | // Disable RAM so that we can change RAM banks. 1332 | // It'd be nice if they'd SAY that you need to do that in 1333 | // places like the Pan Docs. I had a hard time figuring 1334 | // out why I wasn't getting valid RAM data, and this was 1335 | // the reason. It was a very annoying bug to squash. 1336 | hl_write_rept_byte( 0x0000, 0x00 ); 1337 | 1338 | // Set the RAM bank. 1339 | hl_write_rept_byte( 0x4000, (u8)( i & 0x03 ) ); 1340 | 1341 | // Enable RAM again so we can write to it. 1342 | hl_write_rept_byte( 0x0000, 0x0a ); 1343 | 1344 | 1345 | // Now we write the 8 kiB of RAM 1346 | for ( uint j=0x0000; j<0x2000; j+=0x400 ) 1347 | { 1348 | hl_read_from_ifile_and_write_bytes( 0xa000 + j, 0x400, 1349 | i ); 1350 | } 1351 | } 1352 | 1353 | // Disable RAM for safety 1354 | hl_write_rept_byte( 0x0000, 0x00 ); 1355 | 1356 | break; 1357 | 1358 | case rs_128: 1359 | for ( uint i=0; i<16; ++i ) 1360 | { 1361 | // Disable RAM so that we can change RAM banks. 1362 | // It'd be nice if they'd SAY that you need to do that in 1363 | // places like the Pan Docs. I had a hard time figuring 1364 | // out why I wasn't getting valid RAM data, and this was 1365 | // the reason. It was a very annoying bug to squash. 1366 | hl_write_rept_byte( 0x0000, 0x00 ); 1367 | 1368 | // Set the RAM bank. 1369 | hl_write_rept_byte( 0x4000, (u8)( i & 0x0f ) ); 1370 | 1371 | // Enable RAM again so we can write to it. 1372 | hl_write_rept_byte( 0x0000, 0x0a ); 1373 | 1374 | 1375 | // Now we write the 8 kiB of RAM 1376 | for ( uint j=0x0000; j<0x2000; j+=0x400 ) 1377 | { 1378 | hl_read_from_ifile_and_write_bytes( 0xa000 + j, 0x400, 1379 | i ); 1380 | } 1381 | } 1382 | 1383 | // Disable RAM for safety 1384 | hl_write_rept_byte( 0x0000, 0x00 ); 1385 | 1386 | break; 1387 | 1388 | default: 1389 | 1390 | break; 1391 | } 1392 | } 1393 | 1394 | 1395 | 1396 | 1397 | void communicator::dump_rom( u16 start_bank, u16 num_banks ) 1398 | { 1399 | get_cart_stuff(); 1400 | 1401 | if ( cart_mbc_type == rom_only ) 1402 | { 1403 | cout << "No MBC at all, just a 32 kiB ROM\n"; 1404 | rom_only_dump_rom(); 1405 | } 1406 | else if ( ( cart_mbc_type >= mbc1 ) && ( cart_mbc_type <= mbc1_ram ) ) 1407 | { 1408 | cout << "MBC1\n"; 1409 | mbc1_dump_rom( start_bank, num_banks ); 1410 | } 1411 | else if ( cart_mbc_type == mbc2 ) 1412 | { 1413 | cout << "MBC2\n"; 1414 | mbc2_dump_rom( start_bank, num_banks ); 1415 | } 1416 | else if ( ( cart_mbc_type >= mbc3 ) && ( cart_mbc_type <= mbc3_ram ) ) 1417 | { 1418 | cout << "MBC3\n"; 1419 | mbc3_dump_rom( start_bank, num_banks ); 1420 | } 1421 | else if ( ( cart_mbc_type >= mbc5 ) && ( cart_mbc_type <= mbc5_ram ) ) 1422 | { 1423 | cout << "MBC5\n"; 1424 | mbc5_dump_rom( start_bank, num_banks ); 1425 | } 1426 | else 1427 | { 1428 | cout << "Error: Unknown ROM type\n"; 1429 | } 1430 | } 1431 | 1432 | void communicator::dump_rom_banks_to_separate_files( u16 start_bank, 1433 | u16 num_banks ) 1434 | { 1435 | get_cart_stuff(); 1436 | 1437 | if ( cart_mbc_type == rom_only ) 1438 | { 1439 | cout << "No MBC at all, just a 32 kiB ROM\n"; 1440 | rom_only_dump_rom_banks_to_separate_files(); 1441 | } 1442 | else if ( ( cart_mbc_type >= mbc1 ) && ( cart_mbc_type <= mbc1_ram ) ) 1443 | { 1444 | cout << "MBC1\n"; 1445 | mbc1_dump_rom_banks_to_separate_files( start_bank, num_banks ); 1446 | } 1447 | else if ( cart_mbc_type == mbc2 ) 1448 | { 1449 | cout << "MBC2\n"; 1450 | mbc2_dump_rom_banks_to_separate_files( start_bank, num_banks ); 1451 | } 1452 | else if ( ( cart_mbc_type >= mbc3 ) && ( cart_mbc_type <= mbc3_ram ) ) 1453 | { 1454 | cout << "MBC3\n"; 1455 | mbc3_dump_rom_banks_to_separate_files( start_bank, num_banks ); 1456 | } 1457 | else if ( ( cart_mbc_type >= mbc5 ) && ( cart_mbc_type <= mbc5_ram ) ) 1458 | { 1459 | cout << "MBC5\n"; 1460 | mbc5_dump_rom_banks_to_separate_files( start_bank, num_banks ); 1461 | } 1462 | else 1463 | { 1464 | cout << "Error: Unknown ROM type\n"; 1465 | } 1466 | } 1467 | 1468 | void communicator::dump_ram() 1469 | { 1470 | get_cart_stuff(); 1471 | 1472 | switch (cart_mbc_type) 1473 | { 1474 | case mbc1_ram: 1475 | mbc1_dump_ram(); 1476 | break; 1477 | 1478 | case mbc2: 1479 | mbc2_dump_ram(); 1480 | break; 1481 | 1482 | case mbc3_timer_ram: 1483 | case mbc3_ram: 1484 | mbc3_dump_ram(); 1485 | break; 1486 | 1487 | case mbc5_ram: 1488 | mbc5_dump_ram(); 1489 | break; 1490 | 1491 | default: 1492 | cout << "Error: There isn't any RAM in this cartridge." 1493 | << endl; 1494 | break; 1495 | } 1496 | } 1497 | 1498 | void communicator::restore_ram() 1499 | { 1500 | get_cart_stuff(); 1501 | 1502 | switch (cart_mbc_type) 1503 | { 1504 | case mbc1_ram: 1505 | mbc1_restore_ram(); 1506 | break; 1507 | 1508 | case mbc2: 1509 | mbc2_restore_ram(); 1510 | break; 1511 | 1512 | case mbc3_timer_ram: 1513 | case mbc3_ram: 1514 | mbc3_restore_ram(); 1515 | break; 1516 | 1517 | case mbc5_ram: 1518 | mbc5_restore_ram(); 1519 | break; 1520 | 1521 | default: 1522 | cout << "Error: There isn't any RAM in this cartridge." 1523 | << endl; 1524 | break; 1525 | } 1526 | } 1527 | 1528 | -------------------------------------------------------------------------------- /src/communicator/src/communicator_class.hpp: -------------------------------------------------------------------------------- 1 | #ifndef communicator_cls_hpp 2 | #define communicator_cls_hpp 3 | 4 | #include 5 | 6 | enum communicator_action 7 | { 8 | do_rom_dump, 9 | 10 | // do_rom_banks_dump was added because sometimes the Transfer Pak stops 11 | // being possible to read from. It is so finicky. 12 | do_rom_banks_dump, 13 | 14 | do_ram_dump, 15 | do_ram_restore, 16 | 17 | }; 18 | 19 | class communicator 20 | { 21 | public: // variables 22 | static constexpr u32 rom_bank_size = 0x4000; 23 | 24 | int fd; 25 | 26 | // Buffers for Sending/Receiving data 27 | //// They really don't need to be as large as they are, but... 28 | array< char, 2048 > send_buf; 29 | array< char, rom_bank_size > recv_buf; 30 | 31 | 32 | 33 | // fstreams for I/O 34 | fstream ofile, ifile; 35 | 36 | // filenames 37 | string of_name, if_name; 38 | 39 | mbc_type cart_mbc_type; 40 | u16 rom_size; 41 | ram_size_type ram_size; 42 | 43 | 44 | public: // functions 45 | //communicator( int s_fd, const string& s_of_name, 46 | // const string& s_if_name ); 47 | communicator( int argc, char** argv ); 48 | ~communicator(); 49 | 50 | void get_cart_stuff(); 51 | 52 | 53 | 54 | // High Level Helper Functions 55 | void hl_read_32_bytes( u16 gb_addr ); 56 | void hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, 57 | u16 num_bytes ); 58 | 59 | void hl_write_32_bytes( u16 gb_addr ); 60 | void hl_write_rept_byte( u16 gb_addr, u8 the_byte ); 61 | void hl_read_from_ifile_and_write_bytes( u16 gb_start_addr, 62 | u16 num_bytes, u8 gb_ram_bank=0x00 ); 63 | 64 | inline int loop_for_reading_32_bytes(); 65 | inline int loop_for_reading_var_num_bytes( u16 num_bytes ); 66 | 67 | 68 | void dump_rom_test(); 69 | 70 | 71 | // Single ROM bank dumping functions 72 | void rom_only_dump_single_rom_bank( u16 bank ); 73 | void mbc1_dump_single_rom_bank( u16 bank ); 74 | void mbc2_dump_single_rom_bank( u16 bank ); 75 | void mbc3_dump_single_rom_bank( u16 bank ); 76 | void mbc5_dump_single_rom_bank( u16 bank ); 77 | 78 | // Main ROM dumping functions 79 | void rom_only_dump_rom(); 80 | void mbc1_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 ); 81 | void mbc2_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 ); 82 | void mbc3_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 ); 83 | void mbc5_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 ); 84 | 85 | 86 | void rom_only_dump_rom_banks_to_separate_files(); 87 | void mbc1_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, 88 | u16 num_banks=0x0000 ); 89 | void mbc2_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, 90 | u16 num_banks=0x0000 ); 91 | void mbc3_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, 92 | u16 num_banks=0x0000 ); 93 | void mbc5_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, 94 | u16 num_banks=0x0000 ); 95 | 96 | 97 | // Main RAM dumping functions 98 | void mbc1_dump_ram(); 99 | void mbc2_dump_ram(); 100 | void mbc3_dump_ram(); 101 | void mbc5_dump_ram(); 102 | 103 | // Main RAM restoring functions 104 | void mbc1_restore_ram(); 105 | void mbc2_restore_ram(); 106 | void mbc3_restore_ram(); 107 | void mbc5_restore_ram(); 108 | 109 | 110 | 111 | void dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 ); 112 | void dump_rom_banks_to_separate_files( u16 start_bank=0x0000, 113 | u16 num_banks=0x0000 ); 114 | void dump_ram(); 115 | void restore_ram(); 116 | }; 117 | 118 | 119 | inline int communicator::loop_for_reading_32_bytes() 120 | { 121 | 122 | int left_to_read = 32; 123 | 124 | while ( left_to_read > 0 ) 125 | { 126 | int num_read = read( fd, &( recv_buf[32 - left_to_read] ), 127 | recv_buf.size() ); 128 | 129 | if ( num_read < 0 ) 130 | { 131 | cout << "There was an error reading from the Arduino: " 132 | << num_read << "\n"; 133 | cout << "This was the error: " << strerror(errno) << "\n"; 134 | return 1; 135 | } 136 | //else if ( num_read == 0 ) 137 | //{ 138 | // cout << "Nothing was read....\n"; 139 | // 140 | // //exit(1); 141 | //} 142 | 143 | left_to_read -= num_read; 144 | 145 | //cout << left_to_read << endl; 146 | //cout << "Still in left_to_read while loop!\n"; 147 | } 148 | 149 | return 0; 150 | } 151 | inline int communicator::loop_for_reading_var_num_bytes( u16 num_bytes ) 152 | { 153 | 154 | int left_to_read = num_bytes; 155 | 156 | while ( left_to_read > 0 ) 157 | { 158 | int num_read = read( fd, &( recv_buf[num_bytes - left_to_read] ), 159 | recv_buf.size() ); 160 | 161 | if ( num_read < 0 ) 162 | { 163 | cout << "There was an error reading from the Arduino.\n"; 164 | return 1; 165 | } 166 | //else if ( num_read == 0 ) 167 | //{ 168 | // cout << "Nothing was read....\n"; 169 | // 170 | // //exit(1); 171 | //} 172 | 173 | left_to_read -= num_read; 174 | 175 | //cout << left_to_read << endl; 176 | //cout << "Still in left_to_read while loop!\n"; 177 | } 178 | 179 | return 0; 180 | } 181 | 182 | 183 | #endif // communicator_cls_hpp 184 | -------------------------------------------------------------------------------- /src/communicator/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef uint8_t u8; typedef int8_t s8; 4 | typedef uint16_t u16; typedef int16_t s16; 5 | typedef uint32_t u32; typedef int32_t s32; 6 | typedef uint64_t u64; typedef int64_t s64; 7 | typedef unsigned int uint; 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | #include "misc_types.hpp" 24 | #include "stuffs.hpp" 25 | #include "communicator_class.hpp" 26 | 27 | 28 | 29 | int main( int argc, char** argv ) 30 | { 31 | if ( argc < 4 ) 32 | { 33 | cout << "Usage 1: " << argv[0] << " arduino_serial_file dump_rom " 34 | << "rom.gb\n"; 35 | cout << "Usage 2: " << argv[0] << " arduino_serial_file " 36 | << "dump_rom_banks base_name\n"; 37 | cout << "Usage 3: " << argv[0] << " arduino_serial_file " 38 | << "dump_rom_banks base_name start_bank\n"; 39 | cout << "Usage 4: " << argv[0] << " arduino_serial_file " 40 | << "dump_rom_banks base_name start_bank num_banks\n"; 41 | cout << "Usage 5: " << argv[0] << " arduino_serial_file dump_ram " 42 | << "save_data.sav\n"; 43 | cout << "Usage 6: " << argv[0] << " arduino_serial_file " 44 | << "restore_ram save_data.sav\n"; 45 | return 0; 46 | } 47 | 48 | communicator the_communicator( argc, argv ); 49 | 50 | //communicator the_communicator( fd, argv[2], "" ); 51 | 52 | 53 | 54 | 55 | 56 | //if ( argc == 3 ) 57 | //{ 58 | // the_communicator.dump_rom(); 59 | //} 60 | //else if ( argc == 4 ) 61 | //{ 62 | // stringstream the_sstm; 63 | // the_sstm << argv[3]; 64 | // 65 | // u16 start_bank; 66 | // the_sstm >> start_bank; 67 | // 68 | // the_communicator.dump_rom(start_bank); 69 | //} 70 | //else if ( argc == 5 ) 71 | //{ 72 | // stringstream the_sstm; 73 | // u16 start_bank, num_banks; 74 | // 75 | // the_sstm << argv[3]; 76 | // the_sstm >> start_bank; 77 | // the_sstm.clear(); 78 | // 79 | // the_sstm << argv[4]; 80 | // the_sstm >> num_banks; 81 | // 82 | // cout << start_bank << " " << num_banks << endl; 83 | // 84 | // the_communicator.dump_rom( start_bank, num_banks ); 85 | //} 86 | 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /src/communicator/src/misc_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef misc_types_hpp 2 | #define misc_types_hpp 3 | 4 | 5 | // This union needs to be updated so that big endian AND little endian 6 | // hosts are supported. Currently, ONLY little endian hosts are supported. 7 | union addr_packet 8 | { 9 | u16 w; 10 | struct 11 | { 12 | u8 lo, hi; 13 | }; 14 | }; 15 | 16 | 17 | // Only supported MBC types are listed here. 18 | // There's no need to specify whether the cart has a battery or not, so 19 | // that information is left out of this enum. 20 | enum mbc_type 21 | { 22 | // No MBC at all 23 | rom_only, // 32 kiB of ROM, no MBC 24 | 25 | // MBC1 26 | mbc1, // MBC1 only, no RAM 27 | mbc1_ram, // MBC1 and RAM 28 | 29 | // MBC2 30 | mbc2, // MBC2 (includes built-in RAM) 31 | 32 | // MBC3 33 | mbc3, // MBC3 only, no RTC, no RAM 34 | mbc3_timer, // MBC3 and RTC, but no RAM 35 | mbc3_timer_ram, // MBC3, RTC, and RAM 36 | mbc3_ram, // MBC3 and RAM, but no RTC 37 | 38 | // MBC5 39 | mbc5, // MBC5 only, no RAM 40 | mbc5_ram, // MBC5 and RAM 41 | 42 | // Something else 43 | unknown_mbc_type // Debug, etc. 44 | }; 45 | 46 | enum ram_size_type 47 | { 48 | // non-MBC2, non-MBC5 RAM sizes 49 | rs_none, // 1 kiB of external cart RAM 50 | rs_2, // 2 kiB of external cart RAM, not even a full bank 51 | rs_8, // 8 kiB of external cart RAM, 1 bank of 8 kiB 52 | rs_32, // 32 kiB of external cart RAM, 4 banks of 8 kiB each 53 | 54 | // Only MBC5 allows 128 kiB of external cart RAM 55 | rs_128, // 128 kiB of external cart RAM, 16 banks of 8 kiB each 56 | 57 | 58 | // MBC2 includes some NON-EXTERNAL cart RAM, i.e. it's in the MBC2 chip 59 | // itself. It is weird though, since it's 512x4 bits, where each 60 | // "byte" is 4 bits. It shouldn't be surprising that MBC2 wasn't used 61 | // in that many games though. 62 | rs_mbc2, 63 | 64 | }; 65 | 66 | 67 | 68 | // Serial Messages between Arduino and Computer 69 | // Types of Serial Message 70 | enum serial_msg_type 71 | { 72 | sm_print_cart_stuff, 73 | sm_get_cart_stuff, 74 | 75 | sm_reset_tpak, 76 | 77 | sm_gb_read_32_bytes, 78 | sm_gb_write_32_bytes, 79 | 80 | 81 | // Read a variable number of bytes 82 | sm_gb_read_var_num_bytes, 83 | 84 | // Write a variable number of bytes to the cartridge 85 | sm_gb_write_var_num_bytes, 86 | 87 | }; 88 | 89 | 90 | #endif // misc_types_hpp 91 | -------------------------------------------------------------------------------- /src/communicator/src/stuffs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef uint8_t u8; typedef int8_t s8; 4 | typedef uint16_t u16; typedef int16_t s16; 5 | typedef uint32_t u32; typedef int32_t s32; 6 | typedef uint64_t u64; typedef int64_t s64; 7 | typedef unsigned int uint; 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "misc_types.hpp" 22 | #include "stuffs.hpp" 23 | 24 | int do_select_for_write( int fd ) 25 | { 26 | fd_set readfds, writefds, exceptfds; 27 | int nfds = fd + 1; 28 | 29 | FD_ZERO(&readfds); 30 | FD_ZERO(&writefds); 31 | FD_ZERO(&exceptfds); 32 | 33 | // We want to wait until we can write to the Arduino. 34 | FD_SET( fd, &writefds ); 35 | 36 | // Wait 10 ms 37 | timeval timeout = { 0, 10000 }; 38 | 39 | if ( select( nfds, &readfds, &writefds, &exceptfds, &timeout ) < 0 ) 40 | { 41 | return 1; 42 | } 43 | 44 | if ( !FD_ISSET( fd, &writefds ) ) 45 | { 46 | return 2; 47 | } 48 | 49 | return 0; 50 | 51 | } 52 | 53 | int do_select_for_read( int fd ) 54 | { 55 | 56 | fd_set readfds, writefds, exceptfds; 57 | int nfds = fd + 1; 58 | 59 | FD_ZERO(&readfds); 60 | FD_ZERO(&writefds); 61 | FD_ZERO(&exceptfds); 62 | 63 | // We want to wait until we can read from the Arduino. 64 | FD_SET( fd, &readfds ); 65 | 66 | 67 | // Wait 10 ms 68 | timeval timeout = { 0, 10000 }; 69 | 70 | if ( select( nfds, &readfds, &writefds, &exceptfds, &timeout ) < 0 ) 71 | { 72 | return 1; 73 | } 74 | 75 | if ( !FD_ISSET( fd, &readfds ) ) 76 | { 77 | return 2; 78 | } 79 | 80 | return 0; 81 | 82 | } 83 | 84 | 85 | 86 | // Send text to the Arduino 87 | //void do_arduino_write( int fd, string& to_arduino ) 88 | //{ 89 | // wait_until_we_can_write(fd); 90 | // write( fd, to_arduino.c_str(), to_arduino.size() ); 91 | //} 92 | 93 | // Read text from the Arduino 94 | void do_arduino_read( int fd, string& from_arduino ) 95 | { 96 | do_select_for_read(fd); 97 | from_arduino = ""; 98 | 99 | char c = 0; 100 | do 101 | { 102 | int num_read = read( fd, &c, 1 ); 103 | 104 | if ( num_read > 0 ) 105 | { 106 | from_arduino += c; 107 | } 108 | } while ( c != '\n' ); 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/communicator/src/stuffs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef stuffs_hpp 2 | #define stuffs_hpp 3 | 4 | 5 | int do_select_for_write( int fd ); 6 | int do_select_for_read( int fd ); 7 | 8 | 9 | // Send text to the Arduino 10 | //void do_arduino_write( int fd, string& to_arduino ); 11 | 12 | // Read text from the Arduino 13 | void do_arduino_read( int fd, string& from_arduino ); 14 | 15 | 16 | 17 | #endif // stuffs_hpp 18 | -------------------------------------------------------------------------------- /src/communicator/src/tags: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ 2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ 3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ 4 | !_TAG_PROGRAM_NAME Exuberant Ctags // 5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ 6 | !_TAG_PROGRAM_VERSION 5.8 // 7 | addr_packet misc_types.hpp /^union addr_packet$/;" kind:u 8 | addr_packet::__anon1::hi misc_types.hpp /^ u8 lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 9 | addr_packet::__anon1::lo misc_types.hpp /^ u8 lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 10 | addr_packet::w misc_types.hpp /^ u16 w;$/;" kind:m union:addr_packet access:public 11 | cart_mbc_type communicator_class.hpp /^ mbc_type cart_mbc_type;$/;" kind:m class:communicator access:public 12 | communicator communicator_class.cpp /^communicator::communicator( int argc, char** argv )$/;" kind:f class:communicator signature:( int argc, char** argv ) 13 | communicator communicator_class.hpp /^ communicator( int argc, char** argv );$/;" kind:p class:communicator access:public signature:( int argc, char** argv ) 14 | communicator communicator_class.hpp /^class communicator$/;" kind:c 15 | communicator::cart_mbc_type communicator_class.hpp /^ mbc_type cart_mbc_type;$/;" kind:m class:communicator access:public 16 | communicator::communicator communicator_class.cpp /^communicator::communicator( int argc, char** argv )$/;" kind:f class:communicator signature:( int argc, char** argv ) 17 | communicator::communicator communicator_class.hpp /^ communicator( int argc, char** argv );$/;" kind:p class:communicator access:public signature:( int argc, char** argv ) 18 | communicator::dump_ram communicator_class.cpp /^void communicator::dump_ram()$/;" kind:f class:communicator signature:() 19 | communicator::dump_ram communicator_class.hpp /^ void dump_ram();$/;" kind:p class:communicator access:public signature:() 20 | communicator::dump_rom communicator_class.cpp /^void communicator::dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 21 | communicator::dump_rom communicator_class.hpp /^ void dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 22 | communicator::dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 23 | communicator::dump_rom_banks_to_separate_files communicator_class.hpp /^ void dump_rom_banks_to_separate_files( u16 start_bank=0x0000,$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 24 | communicator::dump_rom_test communicator_class.cpp /^void communicator::dump_rom_test()$/;" kind:f class:communicator signature:() 25 | communicator::dump_rom_test communicator_class.hpp /^ void dump_rom_test();$/;" kind:p class:communicator access:public signature:() 26 | communicator::fd communicator_class.hpp /^ int fd;$/;" kind:m class:communicator access:public 27 | communicator::get_cart_stuff communicator_class.cpp /^void communicator::get_cart_stuff()$/;" kind:f class:communicator signature:() 28 | communicator::get_cart_stuff communicator_class.hpp /^ void get_cart_stuff();$/;" kind:p class:communicator access:public signature:() 29 | communicator::hl_read_32_bytes communicator_class.cpp /^void communicator::hl_read_32_bytes( u16 gb_addr )$/;" kind:f class:communicator signature:( u16 gb_addr ) 30 | communicator::hl_read_32_bytes communicator_class.hpp /^ void hl_read_32_bytes( u16 gb_addr );$/;" kind:p class:communicator access:public signature:( u16 gb_addr ) 31 | communicator::hl_read_bytes_and_write_to_ofile communicator_class.cpp /^void communicator::hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, $/;" kind:f class:communicator signature:( u16 gb_start_addr, u16 num_bytes ) 32 | communicator::hl_read_bytes_and_write_to_ofile communicator_class.hpp /^ void hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, $/;" kind:p class:communicator access:public signature:( u16 gb_start_addr, u16 num_bytes ) 33 | communicator::hl_read_from_ifile_and_write_bytes communicator_class.cpp /^void communicator::hl_read_from_ifile_and_write_bytes( u16 gb_start_addr,$/;" kind:f class:communicator signature:( u16 gb_start_addr, u16 num_bytes, u8 gb_ram_bank ) 34 | communicator::hl_read_from_ifile_and_write_bytes communicator_class.hpp /^ void hl_read_from_ifile_and_write_bytes( u16 gb_start_addr,$/;" kind:p class:communicator access:public signature:( u16 gb_start_addr, u16 num_bytes, u8 gb_ram_bank=0x00 ) 35 | communicator::hl_write_32_bytes communicator_class.cpp /^void communicator::hl_write_32_bytes( u16 gb_addr )$/;" kind:f class:communicator signature:( u16 gb_addr ) 36 | communicator::hl_write_32_bytes communicator_class.hpp /^ void hl_write_32_bytes( u16 gb_addr );$/;" kind:p class:communicator access:public signature:( u16 gb_addr ) 37 | communicator::hl_write_rept_byte communicator_class.cpp /^void communicator::hl_write_rept_byte( u16 gb_addr, u8 the_byte )$/;" kind:f class:communicator signature:( u16 gb_addr, u8 the_byte ) 38 | communicator::hl_write_rept_byte communicator_class.hpp /^ void hl_write_rept_byte( u16 gb_addr, u8 the_byte );$/;" kind:p class:communicator access:public signature:( u16 gb_addr, u8 the_byte ) 39 | communicator::if_name communicator_class.hpp /^ string of_name, if_name;$/;" kind:m class:communicator access:public 40 | communicator::ifile communicator_class.hpp /^ fstream ofile, ifile;$/;" kind:m class:communicator access:public 41 | communicator::loop_for_reading_32_bytes communicator_class.hpp /^ inline int loop_for_reading_32_bytes();$/;" kind:p class:communicator access:public signature:() 42 | communicator::loop_for_reading_32_bytes communicator_class.hpp /^inline int communicator::loop_for_reading_32_bytes()$/;" kind:f class:communicator signature:() 43 | communicator::loop_for_reading_var_num_bytes communicator_class.hpp /^ inline int loop_for_reading_var_num_bytes( u16 num_bytes );$/;" kind:p class:communicator access:public signature:( u16 num_bytes ) 44 | communicator::loop_for_reading_var_num_bytes communicator_class.hpp /^inline int communicator::loop_for_reading_var_num_bytes( u16 num_bytes )$/;" kind:f class:communicator signature:( u16 num_bytes ) 45 | communicator::mbc1_dump_ram communicator_class.cpp /^void communicator::mbc1_dump_ram()$/;" kind:f class:communicator signature:() 46 | communicator::mbc1_dump_ram communicator_class.hpp /^ void mbc1_dump_ram();$/;" kind:p class:communicator access:public signature:() 47 | communicator::mbc1_dump_rom communicator_class.cpp /^void communicator::mbc1_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 48 | communicator::mbc1_dump_rom communicator_class.hpp /^ void mbc1_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 49 | communicator::mbc1_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc1_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 50 | communicator::mbc1_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc1_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 51 | communicator::mbc1_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc1_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 52 | communicator::mbc1_dump_single_rom_bank communicator_class.hpp /^ void mbc1_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 53 | communicator::mbc1_restore_ram communicator_class.cpp /^void communicator::mbc1_restore_ram()$/;" kind:f class:communicator signature:() 54 | communicator::mbc1_restore_ram communicator_class.hpp /^ void mbc1_restore_ram();$/;" kind:p class:communicator access:public signature:() 55 | communicator::mbc2_dump_ram communicator_class.cpp /^void communicator::mbc2_dump_ram()$/;" kind:f class:communicator signature:() 56 | communicator::mbc2_dump_ram communicator_class.hpp /^ void mbc2_dump_ram();$/;" kind:p class:communicator access:public signature:() 57 | communicator::mbc2_dump_rom communicator_class.cpp /^void communicator::mbc2_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 58 | communicator::mbc2_dump_rom communicator_class.hpp /^ void mbc2_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 59 | communicator::mbc2_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc2_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 60 | communicator::mbc2_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc2_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 61 | communicator::mbc2_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc2_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 62 | communicator::mbc2_dump_single_rom_bank communicator_class.hpp /^ void mbc2_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 63 | communicator::mbc2_restore_ram communicator_class.cpp /^void communicator::mbc2_restore_ram()$/;" kind:f class:communicator signature:() 64 | communicator::mbc2_restore_ram communicator_class.hpp /^ void mbc2_restore_ram();$/;" kind:p class:communicator access:public signature:() 65 | communicator::mbc3_dump_ram communicator_class.cpp /^void communicator::mbc3_dump_ram()$/;" kind:f class:communicator signature:() 66 | communicator::mbc3_dump_ram communicator_class.hpp /^ void mbc3_dump_ram();$/;" kind:p class:communicator access:public signature:() 67 | communicator::mbc3_dump_rom communicator_class.cpp /^void communicator::mbc3_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 68 | communicator::mbc3_dump_rom communicator_class.hpp /^ void mbc3_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 69 | communicator::mbc3_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc3_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 70 | communicator::mbc3_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc3_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 71 | communicator::mbc3_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc3_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 72 | communicator::mbc3_dump_single_rom_bank communicator_class.hpp /^ void mbc3_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 73 | communicator::mbc3_restore_ram communicator_class.cpp /^void communicator::mbc3_restore_ram()$/;" kind:f class:communicator signature:() 74 | communicator::mbc3_restore_ram communicator_class.hpp /^ void mbc3_restore_ram();$/;" kind:p class:communicator access:public signature:() 75 | communicator::mbc5_dump_ram communicator_class.cpp /^void communicator::mbc5_dump_ram()$/;" kind:f class:communicator signature:() 76 | communicator::mbc5_dump_ram communicator_class.hpp /^ void mbc5_dump_ram();$/;" kind:p class:communicator access:public signature:() 77 | communicator::mbc5_dump_rom communicator_class.cpp /^void communicator::mbc5_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 78 | communicator::mbc5_dump_rom communicator_class.hpp /^ void mbc5_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 79 | communicator::mbc5_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc5_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 80 | communicator::mbc5_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc5_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 81 | communicator::mbc5_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc5_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 82 | communicator::mbc5_dump_single_rom_bank communicator_class.hpp /^ void mbc5_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 83 | communicator::mbc5_restore_ram communicator_class.cpp /^void communicator::mbc5_restore_ram()$/;" kind:f class:communicator signature:() 84 | communicator::mbc5_restore_ram communicator_class.hpp /^ void mbc5_restore_ram();$/;" kind:p class:communicator access:public signature:() 85 | communicator::of_name communicator_class.hpp /^ string of_name, if_name;$/;" kind:m class:communicator access:public 86 | communicator::ofile communicator_class.hpp /^ fstream ofile, ifile;$/;" kind:m class:communicator access:public 87 | communicator::ram_size communicator_class.hpp /^ ram_size_type ram_size;$/;" kind:m class:communicator access:public 88 | communicator::recv_buf communicator_class.hpp /^ array< char, rom_bank_size > recv_buf;$/;" kind:m class:communicator access:public 89 | communicator::restore_ram communicator_class.cpp /^void communicator::restore_ram()$/;" kind:f class:communicator signature:() 90 | communicator::restore_ram communicator_class.hpp /^ void restore_ram();$/;" kind:p class:communicator access:public signature:() 91 | communicator::rom_bank_size communicator_class.hpp /^ static constexpr u32 rom_bank_size = 0x4000;$/;" kind:m class:communicator access:public 92 | communicator::rom_only_dump_rom communicator_class.cpp /^void communicator::rom_only_dump_rom()$/;" kind:f class:communicator signature:() 93 | communicator::rom_only_dump_rom communicator_class.hpp /^ void rom_only_dump_rom();$/;" kind:p class:communicator access:public signature:() 94 | communicator::rom_only_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::rom_only_dump_rom_banks_to_separate_files()$/;" kind:f class:communicator signature:() 95 | communicator::rom_only_dump_rom_banks_to_separate_files communicator_class.hpp /^ void rom_only_dump_rom_banks_to_separate_files();$/;" kind:p class:communicator access:public signature:() 96 | communicator::rom_only_dump_single_rom_bank communicator_class.cpp /^void communicator::rom_only_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 97 | communicator::rom_only_dump_single_rom_bank communicator_class.hpp /^ void rom_only_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 98 | communicator::rom_size communicator_class.hpp /^ u16 rom_size;$/;" kind:m class:communicator access:public 99 | communicator::send_buf communicator_class.hpp /^ array< char, 2048 > send_buf;$/;" kind:m class:communicator access:public 100 | communicator::~communicator communicator_class.cpp /^communicator::~communicator()$/;" kind:f class:communicator signature:() 101 | communicator::~communicator communicator_class.hpp /^ ~communicator();$/;" kind:p class:communicator access:public signature:() 102 | communicator_action communicator_class.hpp /^enum communicator_action$/;" kind:g 103 | communicator_cls_hpp communicator_class.hpp 2;" kind:d 104 | do_arduino_read stuffs.cpp /^void do_arduino_read( int fd, string& from_arduino )$/;" kind:f signature:( int fd, string& from_arduino ) 105 | do_arduino_read stuffs.hpp /^void do_arduino_read( int fd, string& from_arduino );$/;" kind:p signature:( int fd, string& from_arduino ) 106 | do_ram_dump communicator_class.hpp /^ do_ram_dump,$/;" kind:e enum:communicator_action 107 | do_ram_restore communicator_class.hpp /^ do_ram_restore,$/;" kind:e enum:communicator_action 108 | do_rom_banks_dump communicator_class.hpp /^ do_rom_banks_dump,$/;" kind:e enum:communicator_action 109 | do_rom_dump communicator_class.hpp /^ do_rom_dump,$/;" kind:e enum:communicator_action 110 | do_select_for_read stuffs.cpp /^int do_select_for_read( int fd )$/;" kind:f signature:( int fd ) 111 | do_select_for_read stuffs.hpp /^int do_select_for_read( int fd );$/;" kind:p signature:( int fd ) 112 | do_select_for_write stuffs.cpp /^int do_select_for_write( int fd )$/;" kind:f signature:( int fd ) 113 | do_select_for_write stuffs.hpp /^int do_select_for_write( int fd );$/;" kind:p signature:( int fd ) 114 | dump_ram communicator_class.cpp /^void communicator::dump_ram()$/;" kind:f class:communicator signature:() 115 | dump_ram communicator_class.hpp /^ void dump_ram();$/;" kind:p class:communicator access:public signature:() 116 | dump_rom communicator_class.cpp /^void communicator::dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 117 | dump_rom communicator_class.hpp /^ void dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 118 | dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 119 | dump_rom_banks_to_separate_files communicator_class.hpp /^ void dump_rom_banks_to_separate_files( u16 start_bank=0x0000,$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 120 | dump_rom_test communicator_class.cpp /^void communicator::dump_rom_test()$/;" kind:f class:communicator signature:() 121 | dump_rom_test communicator_class.hpp /^ void dump_rom_test();$/;" kind:p class:communicator access:public signature:() 122 | fd communicator_class.hpp /^ int fd;$/;" kind:m class:communicator access:public 123 | get_cart_stuff communicator_class.cpp /^void communicator::get_cart_stuff()$/;" kind:f class:communicator signature:() 124 | get_cart_stuff communicator_class.hpp /^ void get_cart_stuff();$/;" kind:p class:communicator access:public signature:() 125 | hi misc_types.hpp /^ u8 lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 126 | hl_read_32_bytes communicator_class.cpp /^void communicator::hl_read_32_bytes( u16 gb_addr )$/;" kind:f class:communicator signature:( u16 gb_addr ) 127 | hl_read_32_bytes communicator_class.hpp /^ void hl_read_32_bytes( u16 gb_addr );$/;" kind:p class:communicator access:public signature:( u16 gb_addr ) 128 | hl_read_bytes_and_write_to_ofile communicator_class.cpp /^void communicator::hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, $/;" kind:f class:communicator signature:( u16 gb_start_addr, u16 num_bytes ) 129 | hl_read_bytes_and_write_to_ofile communicator_class.hpp /^ void hl_read_bytes_and_write_to_ofile( u16 gb_start_addr, $/;" kind:p class:communicator access:public signature:( u16 gb_start_addr, u16 num_bytes ) 130 | hl_read_from_ifile_and_write_bytes communicator_class.cpp /^void communicator::hl_read_from_ifile_and_write_bytes( u16 gb_start_addr,$/;" kind:f class:communicator signature:( u16 gb_start_addr, u16 num_bytes, u8 gb_ram_bank ) 131 | hl_read_from_ifile_and_write_bytes communicator_class.hpp /^ void hl_read_from_ifile_and_write_bytes( u16 gb_start_addr,$/;" kind:p class:communicator access:public signature:( u16 gb_start_addr, u16 num_bytes, u8 gb_ram_bank=0x00 ) 132 | hl_write_32_bytes communicator_class.cpp /^void communicator::hl_write_32_bytes( u16 gb_addr )$/;" kind:f class:communicator signature:( u16 gb_addr ) 133 | hl_write_32_bytes communicator_class.hpp /^ void hl_write_32_bytes( u16 gb_addr );$/;" kind:p class:communicator access:public signature:( u16 gb_addr ) 134 | hl_write_rept_byte communicator_class.cpp /^void communicator::hl_write_rept_byte( u16 gb_addr, u8 the_byte )$/;" kind:f class:communicator signature:( u16 gb_addr, u8 the_byte ) 135 | hl_write_rept_byte communicator_class.hpp /^ void hl_write_rept_byte( u16 gb_addr, u8 the_byte );$/;" kind:p class:communicator access:public signature:( u16 gb_addr, u8 the_byte ) 136 | if_name communicator_class.hpp /^ string of_name, if_name;$/;" kind:m class:communicator access:public 137 | ifile communicator_class.hpp /^ fstream ofile, ifile;$/;" kind:m class:communicator access:public 138 | lo misc_types.hpp /^ u8 lo, hi;$/;" kind:m struct:addr_packet::__anon1 access:public 139 | loop_for_reading_32_bytes communicator_class.hpp /^ inline int loop_for_reading_32_bytes();$/;" kind:p class:communicator access:public signature:() 140 | loop_for_reading_32_bytes communicator_class.hpp /^inline int communicator::loop_for_reading_32_bytes()$/;" kind:f class:communicator signature:() 141 | loop_for_reading_var_num_bytes communicator_class.hpp /^ inline int loop_for_reading_var_num_bytes( u16 num_bytes );$/;" kind:p class:communicator access:public signature:( u16 num_bytes ) 142 | loop_for_reading_var_num_bytes communicator_class.hpp /^inline int communicator::loop_for_reading_var_num_bytes( u16 num_bytes )$/;" kind:f class:communicator signature:( u16 num_bytes ) 143 | main main.cpp /^int main( int argc, char** argv )$/;" kind:f signature:( int argc, char** argv ) 144 | mbc1 misc_types.hpp /^ mbc1, \/\/ MBC1 only, no RAM$/;" kind:e enum:mbc_type 145 | mbc1_dump_ram communicator_class.cpp /^void communicator::mbc1_dump_ram()$/;" kind:f class:communicator signature:() 146 | mbc1_dump_ram communicator_class.hpp /^ void mbc1_dump_ram();$/;" kind:p class:communicator access:public signature:() 147 | mbc1_dump_rom communicator_class.cpp /^void communicator::mbc1_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 148 | mbc1_dump_rom communicator_class.hpp /^ void mbc1_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 149 | mbc1_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc1_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 150 | mbc1_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc1_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 151 | mbc1_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc1_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 152 | mbc1_dump_single_rom_bank communicator_class.hpp /^ void mbc1_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 153 | mbc1_ram misc_types.hpp /^ mbc1_ram, \/\/ MBC1 and RAM$/;" kind:e enum:mbc_type 154 | mbc1_restore_ram communicator_class.cpp /^void communicator::mbc1_restore_ram()$/;" kind:f class:communicator signature:() 155 | mbc1_restore_ram communicator_class.hpp /^ void mbc1_restore_ram();$/;" kind:p class:communicator access:public signature:() 156 | mbc2 misc_types.hpp /^ mbc2, \/\/ MBC2 (includes built-in RAM)$/;" kind:e enum:mbc_type 157 | mbc2_dump_ram communicator_class.cpp /^void communicator::mbc2_dump_ram()$/;" kind:f class:communicator signature:() 158 | mbc2_dump_ram communicator_class.hpp /^ void mbc2_dump_ram();$/;" kind:p class:communicator access:public signature:() 159 | mbc2_dump_rom communicator_class.cpp /^void communicator::mbc2_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 160 | mbc2_dump_rom communicator_class.hpp /^ void mbc2_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 161 | mbc2_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc2_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 162 | mbc2_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc2_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 163 | mbc2_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc2_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 164 | mbc2_dump_single_rom_bank communicator_class.hpp /^ void mbc2_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 165 | mbc2_restore_ram communicator_class.cpp /^void communicator::mbc2_restore_ram()$/;" kind:f class:communicator signature:() 166 | mbc2_restore_ram communicator_class.hpp /^ void mbc2_restore_ram();$/;" kind:p class:communicator access:public signature:() 167 | mbc3 misc_types.hpp /^ mbc3, \/\/ MBC3 only, no RTC, no RAM$/;" kind:e enum:mbc_type 168 | mbc3_dump_ram communicator_class.cpp /^void communicator::mbc3_dump_ram()$/;" kind:f class:communicator signature:() 169 | mbc3_dump_ram communicator_class.hpp /^ void mbc3_dump_ram();$/;" kind:p class:communicator access:public signature:() 170 | mbc3_dump_rom communicator_class.cpp /^void communicator::mbc3_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 171 | mbc3_dump_rom communicator_class.hpp /^ void mbc3_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 172 | mbc3_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc3_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 173 | mbc3_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc3_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 174 | mbc3_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc3_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 175 | mbc3_dump_single_rom_bank communicator_class.hpp /^ void mbc3_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 176 | mbc3_ram misc_types.hpp /^ mbc3_ram, \/\/ MBC3 and RAM, but no RTC$/;" kind:e enum:mbc_type 177 | mbc3_restore_ram communicator_class.cpp /^void communicator::mbc3_restore_ram()$/;" kind:f class:communicator signature:() 178 | mbc3_restore_ram communicator_class.hpp /^ void mbc3_restore_ram();$/;" kind:p class:communicator access:public signature:() 179 | mbc3_timer misc_types.hpp /^ mbc3_timer, \/\/ MBC3 and RTC, but no RAM$/;" kind:e enum:mbc_type 180 | mbc3_timer_ram misc_types.hpp /^ mbc3_timer_ram, \/\/ MBC3, RTC, and RAM$/;" kind:e enum:mbc_type 181 | mbc5 misc_types.hpp /^ mbc5, \/\/ MBC5 only, no RAM$/;" kind:e enum:mbc_type 182 | mbc5_dump_ram communicator_class.cpp /^void communicator::mbc5_dump_ram()$/;" kind:f class:communicator signature:() 183 | mbc5_dump_ram communicator_class.hpp /^ void mbc5_dump_ram();$/;" kind:p class:communicator access:public signature:() 184 | mbc5_dump_rom communicator_class.cpp /^void communicator::mbc5_dump_rom( u16 start_bank, u16 num_banks )$/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 185 | mbc5_dump_rom communicator_class.hpp /^ void mbc5_dump_rom( u16 start_bank=0x0000, u16 num_banks=0x0000 );$/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 186 | mbc5_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::mbc5_dump_rom_banks_to_separate_files( u16 start_bank, $/;" kind:f class:communicator signature:( u16 start_bank, u16 num_banks ) 187 | mbc5_dump_rom_banks_to_separate_files communicator_class.hpp /^ void mbc5_dump_rom_banks_to_separate_files( u16 start_bank=0x0000, $/;" kind:p class:communicator access:public signature:( u16 start_bank=0x0000, u16 num_banks=0x0000 ) 188 | mbc5_dump_single_rom_bank communicator_class.cpp /^void communicator::mbc5_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 189 | mbc5_dump_single_rom_bank communicator_class.hpp /^ void mbc5_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 190 | mbc5_ram misc_types.hpp /^ mbc5_ram, \/\/ MBC5 and RAM$/;" kind:e enum:mbc_type 191 | mbc5_restore_ram communicator_class.cpp /^void communicator::mbc5_restore_ram()$/;" kind:f class:communicator signature:() 192 | mbc5_restore_ram communicator_class.hpp /^ void mbc5_restore_ram();$/;" kind:p class:communicator access:public signature:() 193 | mbc_type misc_types.hpp /^enum mbc_type$/;" kind:g 194 | misc_types_hpp misc_types.hpp 2;" kind:d 195 | of_name communicator_class.hpp /^ string of_name, if_name;$/;" kind:m class:communicator access:public 196 | ofile communicator_class.hpp /^ fstream ofile, ifile;$/;" kind:m class:communicator access:public 197 | ram_size communicator_class.hpp /^ ram_size_type ram_size;$/;" kind:m class:communicator access:public 198 | ram_size_type misc_types.hpp /^enum ram_size_type$/;" kind:g 199 | recv_buf communicator_class.hpp /^ array< char, rom_bank_size > recv_buf;$/;" kind:m class:communicator access:public 200 | restore_ram communicator_class.cpp /^void communicator::restore_ram()$/;" kind:f class:communicator signature:() 201 | restore_ram communicator_class.hpp /^ void restore_ram();$/;" kind:p class:communicator access:public signature:() 202 | rom_bank_size communicator_class.hpp /^ static constexpr u32 rom_bank_size = 0x4000;$/;" kind:m class:communicator access:public 203 | rom_only misc_types.hpp /^ rom_only, \/\/ 32 kiB of ROM, no MBC$/;" kind:e enum:mbc_type 204 | rom_only_dump_rom communicator_class.cpp /^void communicator::rom_only_dump_rom()$/;" kind:f class:communicator signature:() 205 | rom_only_dump_rom communicator_class.hpp /^ void rom_only_dump_rom();$/;" kind:p class:communicator access:public signature:() 206 | rom_only_dump_rom_banks_to_separate_files communicator_class.cpp /^void communicator::rom_only_dump_rom_banks_to_separate_files()$/;" kind:f class:communicator signature:() 207 | rom_only_dump_rom_banks_to_separate_files communicator_class.hpp /^ void rom_only_dump_rom_banks_to_separate_files();$/;" kind:p class:communicator access:public signature:() 208 | rom_only_dump_single_rom_bank communicator_class.cpp /^void communicator::rom_only_dump_single_rom_bank( u16 bank )$/;" kind:f class:communicator signature:( u16 bank ) 209 | rom_only_dump_single_rom_bank communicator_class.hpp /^ void rom_only_dump_single_rom_bank( u16 bank );$/;" kind:p class:communicator access:public signature:( u16 bank ) 210 | rom_size communicator_class.hpp /^ u16 rom_size;$/;" kind:m class:communicator access:public 211 | rs_128 misc_types.hpp /^ rs_128, \/\/ 128 kiB of external cart RAM, 16 banks of 8 kiB each$/;" kind:e enum:ram_size_type 212 | rs_2 misc_types.hpp /^ rs_2, \/\/ 2 kiB of external cart RAM, not even a full bank$/;" kind:e enum:ram_size_type 213 | rs_32 misc_types.hpp /^ rs_32, \/\/ 32 kiB of external cart RAM, 4 banks of 8 kiB each$/;" kind:e enum:ram_size_type 214 | rs_8 misc_types.hpp /^ rs_8, \/\/ 8 kiB of external cart RAM, 1 bank of 8 kiB$/;" kind:e enum:ram_size_type 215 | rs_mbc2 misc_types.hpp /^ rs_mbc2,$/;" kind:e enum:ram_size_type 216 | rs_none misc_types.hpp /^ rs_none, \/\/ 1 kiB of external cart RAM$/;" kind:e enum:ram_size_type 217 | s16 communicator_class.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 218 | s16 main.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 219 | s16 stuffs.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 220 | s32 communicator_class.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 221 | s32 main.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 222 | s32 stuffs.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 223 | s64 communicator_class.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 224 | s64 main.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 225 | s64 stuffs.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 226 | s8 communicator_class.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 227 | s8 main.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 228 | s8 stuffs.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 229 | send_buf communicator_class.hpp /^ array< char, 2048 > send_buf;$/;" kind:m class:communicator access:public 230 | serial_msg_type misc_types.hpp /^enum serial_msg_type$/;" kind:g 231 | sm_gb_read_32_bytes misc_types.hpp /^ sm_gb_read_32_bytes,$/;" kind:e enum:serial_msg_type 232 | sm_gb_read_var_num_bytes misc_types.hpp /^ sm_gb_read_var_num_bytes,$/;" kind:e enum:serial_msg_type 233 | sm_gb_write_32_bytes misc_types.hpp /^ sm_gb_write_32_bytes,$/;" kind:e enum:serial_msg_type 234 | sm_gb_write_var_num_bytes misc_types.hpp /^ sm_gb_write_var_num_bytes,$/;" kind:e enum:serial_msg_type 235 | sm_get_cart_stuff misc_types.hpp /^ sm_get_cart_stuff,$/;" kind:e enum:serial_msg_type 236 | sm_print_cart_stuff misc_types.hpp /^ sm_print_cart_stuff,$/;" kind:e enum:serial_msg_type 237 | sm_reset_tpak misc_types.hpp /^ sm_reset_tpak,$/;" kind:e enum:serial_msg_type 238 | stuffs_hpp stuffs.hpp 2;" kind:d 239 | u16 communicator_class.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 240 | u16 main.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 241 | u16 stuffs.cpp /^typedef uint16_t u16; typedef int16_t s16;$/;" kind:t file: 242 | u32 communicator_class.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 243 | u32 main.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 244 | u32 stuffs.cpp /^typedef uint32_t u32; typedef int32_t s32;$/;" kind:t file: 245 | u64 communicator_class.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 246 | u64 main.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 247 | u64 stuffs.cpp /^typedef uint64_t u64; typedef int64_t s64;$/;" kind:t file: 248 | u8 communicator_class.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 249 | u8 main.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 250 | u8 stuffs.cpp /^typedef uint8_t u8; typedef int8_t s8;$/;" kind:t file: 251 | uint communicator_class.cpp /^typedef unsigned int uint;$/;" kind:t file: 252 | uint main.cpp /^typedef unsigned int uint;$/;" kind:t file: 253 | uint stuffs.cpp /^typedef unsigned int uint;$/;" kind:t file: 254 | unknown_mbc_type misc_types.hpp /^ unknown_mbc_type \/\/ Debug, etc.$/;" kind:e enum:mbc_type 255 | w misc_types.hpp /^ u16 w;$/;" kind:m union:addr_packet access:public 256 | ~communicator communicator_class.cpp /^communicator::~communicator()$/;" kind:f class:communicator signature:() 257 | ~communicator communicator_class.hpp /^ ~communicator();$/;" kind:p class:communicator access:public signature:() 258 | -------------------------------------------------------------------------------- /src/communicator/src/types_c.taghl: -------------------------------------------------------------------------------- 1 | syn keyword CTagsMember rom_bank_size w ram_size rom_size cart_mbc_type fd lo ofile hi recv_buf if_name send_buf ifile of_name 2 | syn keyword CTagsUnion addr_packet 3 | syn keyword CTagsEnumeratorName communicator_action serial_msg_type ram_size_type mbc_type 4 | syn keyword CTagsEnumerationValue sm_gb_read_var_num_bytes mbc3_ram mbc5 rs_mbc2 sm_gb_write_var_num_bytes sm_get_cart_stuff rs_8 mbc1_ram sm_gb_read_32_bytes unknown_mbc_type rs_2 sm_print_cart_stuff rs_none mbc3_timer sm_gb_write_32_bytes rs_128 mbc3 do_rom_banks_dump do_ram_dump mbc5_ram rom_only mbc1 sm_reset_tpak do_rom_dump mbc3_timer_ram rs_32 do_ram_restore mbc2 5 | syn keyword CTagsFunction mbc5_dump_single_rom_bank rom_only_dump_single_rom_bank hl_read_from_ifile_and_write_bytes mbc2_dump_rom mbc5_dump_rom do_select_for_read dump_rom_test mbc5_restore_ram restore_ram hl_write_rept_byte get_cart_stuff mbc2_restore_ram mbc1_dump_single_rom_bank mbc2_dump_ram mbc3_dump_ram dump_rom_banks_to_separate_files hl_write_32_bytes mbc1_dump_rom mbc5_dump_ram dump_rom 6 | syn keyword CTagsFunction do_arduino_read dump_ram mbc2_dump_rom_banks_to_separate_files rom_only_dump_rom loop_for_reading_var_num_bytes rom_only_dump_rom_banks_to_separate_files mbc3_dump_single_rom_bank loop_for_reading_32_bytes hl_read_32_bytes hl_read_bytes_and_write_to_ofile mbc1_restore_ram mbc3_dump_rom mbc1_dump_ram mbc2_dump_single_rom_bank mbc5_dump_rom_banks_to_separate_files do_select_for_write mbc3_restore_ram main mbc1_dump_rom_banks_to_separate_files mbc3_dump_rom_banks_to_separate_files 7 | syn keyword CTagsDefinedName communicator_cls_hpp misc_types_hpp stuffs_hpp 8 | syn keyword CTagsClass communicator 9 | 10 | " Matches for file communicator_class.cpp: 11 | if (has_key(b:TagHighlightPrivate, "NormalisedPath") && b:TagHighlightPrivate["NormalisedPath"] == "communicator_class.cpp") || TagHighlight#Option#GetOption("IgnoreFileScope") 12 | syn keyword CTagsType s64 s32 u64 s8 uint u8 s16 u16 u32 13 | 14 | endif 15 | " Matches for file stuffs.cpp: 16 | if (has_key(b:TagHighlightPrivate, "NormalisedPath") && b:TagHighlightPrivate["NormalisedPath"] == "stuffs.cpp") || TagHighlight#Option#GetOption("IgnoreFileScope") 17 | syn keyword CTagsType s64 s32 u64 s8 uint u8 s16 u16 u32 18 | 19 | endif 20 | " Matches for file main.cpp: 21 | if (has_key(b:TagHighlightPrivate, "NormalisedPath") && b:TagHighlightPrivate["NormalisedPath"] == "main.cpp") || TagHighlight#Option#GetOption("IgnoreFileScope") 22 | syn keyword CTagsType s64 s32 u64 s8 uint u8 s16 u16 u32 23 | 24 | endif 25 | --------------------------------------------------------------------------------