diff options
Diffstat (limited to 'gba/source/main.c')
| -rw-r--r-- | gba/source/main.c | 592 |
1 files changed, 384 insertions, 208 deletions
| diff --git a/gba/source/main.c b/gba/source/main.c index ee94c35..104866a 100644 --- a/gba/source/main.c +++ b/gba/source/main.c | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | #include <stdio.h> | 8 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| 10 | #include "libSave.h" | 10 | #include "libSave.h" |
| 11 | #include "gamedata.h" | ||
| 12 | #include "link.h" | ||
| 11 | 13 | ||
| 12 | #define REG_WAITCNT *(vu16 *)(REG_BASE + 0x204) | 14 | #define REG_WAITCNT *(vu16 *)(REG_BASE + 0x204) |
| 13 | #define JOY_WRITE 2 | 15 | #define JOY_WRITE 2 |
| @@ -18,224 +20,398 @@ u8 save_data[0x20000] __attribute__ ((section (".sbss"))); | |||
| 18 | 20 | ||
| 19 | s32 getGameSize(void) | 21 | s32 getGameSize(void) |
| 20 | { | 22 | { |
| 21 | if(*(vu32*)(0x08000004) != 0x51AEFF24) | 23 | if(*(vu32*)(0x08000004) != 0x51AEFF24) |
| 22 | return -1; | 24 | return -1; |
| 23 | s32 i; | 25 | s32 i; |
| 24 | for(i = (1<<20); i < (1<<25); i<<=1) | 26 | for(i = (1<<20); i < (1<<25); i<<=1) |
| 27 | { | ||
| 28 | vu16 *rompos = (vu16*)(0x08000000+i); | ||
| 29 | int j; | ||
| 30 | bool romend = true; | ||
| 31 | for(j = 0; j < 0x1000; j++) | ||
| 32 | { | ||
| 33 | if(rompos[j] != j) | ||
| 34 | { | ||
| 35 | romend = false; | ||
| 36 | break; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | if(romend) break; | ||
| 40 | } | ||
| 41 | return i; | ||
| 42 | } | ||
| 43 | |||
| 44 | |||
| 45 | // === (from tonc_memdef.h) =========================================== | ||
| 46 | |||
| 47 | // --- REG_DISPCNT defines --- | ||
| 48 | #define DCNT_MODE0 0x0000 | ||
| 49 | #define DCNT_MODE1 0x0001 | ||
| 50 | #define DCNT_MODE2 0x0002 | ||
| 51 | #define DCNT_MODE3 0x0003 | ||
| 52 | #define DCNT_MODE4 0x0004 | ||
| 53 | #define DCNT_MODE5 0x0005 | ||
| 54 | // layers | ||
| 55 | #define DCNT_BG0 0x0100 | ||
| 56 | #define DCNT_BG1 0x0200 | ||
| 57 | #define DCNT_BG2 0x0400 | ||
| 58 | #define DCNT_BG3 0x0800 | ||
| 59 | #define DCNT_OBJ 0x1000 | ||
| 60 | typedef u16 COLOR; | ||
| 61 | #define MEM_VRAM 0x06000000 | ||
| 62 | #define SCREEN_WIDTH 240 | ||
| 63 | #define vid_mem ((u16*)MEM_VRAM) | ||
| 64 | static inline void m3_plot(int x, int y, COLOR clr) | ||
| 65 | { vid_mem[y*SCREEN_WIDTH+x]= clr; } | ||
| 66 | static inline COLOR RGB15(u32 red, u32 green, u32 blue) | ||
| 67 | { return red | (green<<5) | (blue<<10); } | ||
| 68 | void plot_sqr(int x, int y, COLOR clr) | ||
| 69 | { | ||
| 70 | /*for (int j=0;j<8; j++) | ||
| 25 | { | 71 | { |
| 26 | vu16 *rompos = (vu16*)(0x08000000+i); | 72 | for (int i=0;i<8; i++) |
| 27 | int j; | ||
| 28 | bool romend = true; | ||
| 29 | for(j = 0; j < 0x1000; j++) | ||
| 30 | { | 73 | { |
| 31 | if(rompos[j] != j) | 74 | vid_mem[(y*8+j+32)*SCREEN_WIDTH+x*8+i+32] = clr; |
| 32 | { | ||
| 33 | romend = false; | ||
| 34 | break; | ||
| 35 | } | ||
| 36 | } | 75 | } |
| 37 | if(romend) break; | ||
| 38 | } | 76 | } |
| 39 | return i; | 77 | vid_mem[(y*8+1+32)*SCREEN_WIDTH+x*8+1+32] = RGB15(31,31,31);*/ |
| 78 | } | ||
| 79 | void m3_fill(COLOR clr) | ||
| 80 | { | ||
| 81 | /*int ii; | ||
| 82 | u32 *dst= (u32*)vid_mem; | ||
| 83 | u32 wd= (clr<<16) | clr; | ||
| 84 | |||
| 85 | for(ii=0; ii<SCREEN_WIDTH/4; ii++) | ||
| 86 | *dst++= wd;*/ | ||
| 40 | } | 87 | } |
| 41 | 88 | ||
| 42 | //--------------------------------------------------------------------------------- | 89 | //--------------------------------------------------------------------------------- |
| 43 | // Program entry point | 90 | // Program entry point |
| 44 | //--------------------------------------------------------------------------------- | 91 | //--------------------------------------------------------------------------------- |
| 45 | int main(void) { | 92 | int main(void) |
| 46 | //--------------------------------------------------------------------------------- | 93 | { |
| 94 | //REG_IME = 0; | ||
| 95 | //REG_DISPCNT= DCNT_MODE3 | DCNT_BG2; | ||
| 96 | m3_fill(RGB15(31,31,31)); | ||
| 97 | plot_sqr( 4, 4, RGB15(31, 0, 0) ); // or CLR_RED | ||
| 47 | 98 | ||
| 48 | // the vblank interrupt must be enabled for VBlankIntrWait() to work | 99 | |
| 49 | // since the default dispatcher handles the bios flags no vblank handler | 100 | |
| 50 | // is required | 101 | //*(vu16 *)(REG_BASE + 0x84) = 0x8f; |
| 51 | irqInit(); | 102 | //REG_IME = 1; |
| 52 | irqEnable(IRQ_VBLANK); | 103 | // the vblank interrupt must be enabled for VBlankIntrWait() to work |
| 53 | 104 | // since the default dispatcher handles the bios flags no vblank handler | |
| 54 | consoleDemoInit(); | 105 | // is required |
| 55 | REG_JOYTR = 0; | 106 | //irqInit(); |
| 56 | // ansi escape sequence to set print co-ordinates | 107 | //irqEnable(IRQ_VBLANK); |
| 57 | // /x1b[line;columnH | 108 | |
| 58 | u32 i; | 109 | //consoleDemoInit(); |
| 59 | iprintf("\x1b[9;2HGBA Link Cable Dumper v1.6\n"); | 110 | //REG_JOYTR = 0; |
| 60 | iprintf("\x1b[10;4HPlease look at the TV\n"); | 111 | |
| 61 | // disable this, needs power | 112 | // ansi escape sequence to set print co-ordinates |
| 62 | SNDSTAT = 0; | 113 | // /x1b[line;columnH |
| 63 | SNDBIAS = 0; | 114 | //u32 i; |
| 64 | // Set up waitstates for EEPROM access etc. | 115 | //iprintf("\x1b[9;2HPokemon Gen III Data Extractor\n"); |
| 65 | REG_WAITCNT = 0x0317; | 116 | //iprintf("\x1b[10;4HPlease look at the TV\n"); |
| 66 | //clear out previous messages | 117 | |
| 67 | REG_HS_CTRL |= JOY_RW; | 118 | // disable this, needs power |
| 68 | while (1) { | 119 | //SNDSTAT = 0; |
| 69 | if(REG_HS_CTRL&JOY_READ) | 120 | //SNDBIAS = 0; |
| 70 | { | 121 | |
| 71 | REG_HS_CTRL |= JOY_RW; | 122 | // Set up waitstates for EEPROM access etc. |
| 72 | s32 gamesize = getGameSize(); | 123 | //REG_WAITCNT = 0x0317; |
| 73 | u32 savesize = SaveSize(save_data,gamesize); | 124 | |
| 74 | REG_JOYTR = gamesize; | 125 | //clear out previous messages |
| 75 | //wait for a cmd receive for safety | 126 | REG_HS_CTRL |= JOY_RW; |
| 76 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 127 | sendU32(0); |
| 77 | REG_HS_CTRL |= JOY_RW; | 128 | plot_sqr( 4, 5, RGB15( 0,31, 0) ); // or CLR_LIME |
| 78 | REG_JOYTR = savesize; | 129 | while (1) |
| 79 | //wait for a cmd receive for safety | 130 | { |
| 80 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 131 | waitForWriteAccess(); |
| 81 | REG_HS_CTRL |= JOY_RW; | 132 | //while (recieveU32() != 0); |
| 82 | if(gamesize == -1) | 133 | //waitForAck(); |
| 83 | { | 134 | plot_sqr( 4, 6, RGB15( 0, 0,31) ); // or CLR_BLUE |
| 84 | REG_JOYTR = 0; | 135 | // Send game size to acknowledge that an actual cart is inserted. |
| 85 | continue; //nothing to read | 136 | //s32 gamesize = getGameSize(); |
| 86 | } | 137 | //sendS32(gamesize); |
| 87 | //game in, send header | 138 | //waitForAck(); |
| 88 | for(i = 0; i < 0xC0; i+=4) | 139 | |
| 89 | { | 140 | // If the game size is illegal, start over. |
| 90 | REG_JOYTR = *(vu32*)(0x08000000+i); | 141 | //if (gamesize == -1) |
| 91 | while((REG_HS_CTRL&JOY_READ) == 0) ; | 142 | //{ |
| 92 | REG_HS_CTRL |= JOY_RW; | 143 | // sendS32(0); |
| 93 | } | 144 | // |
| 94 | REG_JOYTR = 0; | 145 | // continue; |
| 95 | //wait for other side to choose | 146 | //} |
| 96 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 147 | |
| 97 | REG_HS_CTRL |= JOY_RW; | 148 | // Identify the inserted game. |
| 98 | u32 choseval = REG_JOYRE; | 149 | if (GAME_RUBY) |
| 99 | if(choseval == 0) | 150 | { |
| 100 | { | 151 | sendS32(1); |
| 101 | REG_JOYTR = 0; | 152 | } else if (GAME_SAPP) |
| 102 | continue; //nothing to read | 153 | { |
| 103 | } | 154 | sendS32(2); |
| 104 | else if(choseval == 1) | 155 | } else if (GAME_FR) |
| 105 | { | 156 | { |
| 106 | //disable interrupts | 157 | sendS32(3); |
| 107 | u32 prevIrqMask = REG_IME; | 158 | } else if (GAME_LG) |
| 108 | REG_IME = 0; | 159 | { |
| 109 | //dump the game | 160 | sendS32(4); |
| 110 | for(i = 0; i < gamesize; i+=4) | 161 | } else if (GAME_EM) |
| 111 | { | 162 | { |
| 112 | REG_JOYTR = *(vu32*)(0x08000000+i); | 163 | sendS32(5); |
| 113 | while((REG_HS_CTRL&JOY_READ) == 0) ; | 164 | } else { |
| 114 | REG_HS_CTRL |= JOY_RW; | 165 | sendS32(-1); |
| 115 | } | 166 | waitForAck(); |
| 116 | //restore interrupts | 167 | |
| 117 | REG_IME = prevIrqMask; | 168 | sendS32(0); |
| 118 | } | 169 | |
| 119 | else if(choseval == 2) | 170 | continue; |
| 120 | { | 171 | } |
| 121 | //disable interrupts | 172 | plot_sqr( 5, 4, RGB15( 31, 0,31) ); |
| 122 | u32 prevIrqMask = REG_IME; | 173 | waitForAck(); |
| 123 | REG_IME = 0; | 174 | plot_sqr( 5, 5, RGB15( 16, 16,16) ); |
| 124 | //backup save | 175 | // Get access to save data. |
| 125 | switch (savesize){ | 176 | pSaveBlock1 SaveBlock1; |
| 126 | case 0x200: | 177 | pSaveBlock2 SaveBlock2; |
| 127 | GetSave_EEPROM_512B(save_data); | 178 | pSaveBlock3 SaveBlock3; |
| 128 | break; | 179 | if (!initSaveData(&SaveBlock1, &SaveBlock2, &SaveBlock3)) |
| 129 | case 0x2000: | 180 | { |
| 130 | GetSave_EEPROM_8KB(save_data); | 181 | // Unsupported game version. |
| 131 | break; | 182 | //iprintf("Unsupported game version\n"); |
| 132 | case 0x8000: | 183 | sendS32(-1); |
| 133 | GetSave_SRAM_32KB(save_data); | 184 | waitForAck(); |
| 134 | break; | 185 | |
| 135 | case 0x10000: | 186 | sendS32(0); |
| 136 | GetSave_FLASH_64KB(save_data); | 187 | |
| 137 | break; | 188 | continue; |
| 138 | case 0x20000: | 189 | } |
| 139 | GetSave_FLASH_128KB(save_data); | 190 | plot_sqr( 5, 6, RGB15( 0, 31,16) ); |
| 140 | break; | 191 | sendS32(1); |
| 141 | default: | 192 | waitForAck(); |
| 142 | break; | 193 | /* |
| 143 | } | 194 | // Send trainer name. |
| 144 | //restore interrupts | 195 | u8* trainerName; |
| 145 | REG_IME = prevIrqMask; | 196 | |
| 146 | //say gc side we read it | 197 | if (GAME_RS) |
| 147 | REG_JOYTR = savesize; | 198 | { |
| 148 | //wait for a cmd receive for safety | 199 | trainerName = SaveBlock2->rs.playerName; |
| 149 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 200 | } else if (GAME_FRLG) |
| 150 | REG_HS_CTRL |= JOY_RW; | 201 | { |
| 151 | //send the save | 202 | trainerName = SaveBlock2->frlg.playerName; |
| 152 | for(i = 0; i < savesize; i+=4) | 203 | } else if (GAME_EM) |
| 153 | { | 204 | { |
| 154 | REG_JOYTR = *(vu32*)(save_data+i); | 205 | trainerName = SaveBlock2->e.playerName; |
| 155 | while((REG_HS_CTRL&JOY_READ) == 0) ; | 206 | } |
| 156 | REG_HS_CTRL |= JOY_RW; | 207 | iprintf("%d\n", trainerName[0]); |
| 157 | } | 208 | iprintf("%d\n", trainerName[1]); |
| 158 | } | 209 | iprintf("%d\n", trainerName[2]); |
| 159 | else if(choseval == 3 || choseval == 4) | 210 | iprintf("%d\n", trainerName[3]); |
| 160 | { | 211 | iprintf("%d\n", trainerName[4]); |
| 161 | REG_JOYTR = savesize; | 212 | iprintf("%d\n", trainerName[5]); |
| 162 | if(choseval == 3) | 213 | iprintf("%d\n", trainerName[6]); |
| 163 | { | 214 | iprintf("%d\n", trainerName[7]); |
| 164 | //receive the save | 215 | |
| 165 | for(i = 0; i < savesize; i+=4) | 216 | u32 tn1 = |
| 166 | { | 217 | (trainerName[0] << 24) |
| 167 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 218 | | (trainerName[1] << 16) |
| 168 | REG_HS_CTRL |= JOY_RW; | 219 | | (trainerName[2] << 8) |
| 169 | *(vu32*)(save_data+i) = REG_JOYRE; | 220 | | (trainerName[3]); |
| 170 | } | 221 | |
| 171 | } | 222 | u32 tn2 = |
| 172 | else | 223 | (trainerName[4] << 24) |
| 173 | { | 224 | | (trainerName[5] << 16) |
| 174 | //clear the save | 225 | | (trainerName[6] << 8) |
| 175 | for(i = 0; i < savesize; i+=4) | 226 | | (trainerName[7]); |
| 176 | *(vu32*)(save_data+i) = 0; | 227 | |
| 177 | } | 228 | sendU32(tn1); |
| 178 | //disable interrupts | 229 | waitForAck(); |
| 179 | u32 prevIrqMask = REG_IME; | 230 | |
| 180 | REG_IME = 0; | 231 | sendU32(tn2); |
| 181 | //write it | 232 | waitForAck(); |
| 182 | switch (savesize){ | 233 | */ |
| 183 | case 0x200: | 234 | // Send trainer ID. |
| 184 | PutSave_EEPROM_512B(save_data); | 235 | u8* trainerId = 0; |
| 185 | break; | 236 | |
| 186 | case 0x2000: | 237 | if (GAME_RS) |
| 187 | PutSave_EEPROM_8KB(save_data); | 238 | { |
| 188 | break; | 239 | trainerId = SaveBlock2->rs.playerTrainerId; |
| 189 | case 0x8000: | 240 | } else if (GAME_FRLG) |
| 190 | PutSave_SRAM_32KB(save_data); | 241 | { |
| 191 | break; | 242 | trainerId = SaveBlock2->frlg.playerTrainerId; |
| 192 | case 0x10000: | 243 | } else if (GAME_EM) |
| 193 | PutSave_FLASH_64KB(save_data); | 244 | { |
| 194 | break; | 245 | trainerId = SaveBlock2->e.playerTrainerId; |
| 195 | case 0x20000: | 246 | } |
| 196 | PutSave_FLASH_128KB(save_data); | 247 | |
| 197 | break; | 248 | u32 tti = |
| 198 | default: | 249 | (trainerId[2] << 8) |
| 199 | break; | 250 | | (trainerId[3]); |
| 200 | } | 251 | |
| 201 | //restore interrupts | 252 | sendU32(tti); |
| 202 | REG_IME = prevIrqMask; | 253 | waitForAck(); |
| 203 | //say gc side we're done | 254 | |
| 204 | REG_JOYTR = 0; | 255 | // Restart, because we're just testing. |
| 205 | //wait for a cmd receive for safety | 256 | sendS32(0); |
| 206 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | 257 | //continue; |
| 207 | REG_HS_CTRL |= JOY_RW; | 258 | break; |
| 208 | } | 259 | |
| 209 | REG_JOYTR = 0; | 260 | /* |
| 210 | } | 261 | |
| 211 | else if(REG_HS_CTRL&JOY_WRITE) | 262 | |
| 212 | { | 263 | //game in, send header |
| 213 | REG_HS_CTRL |= JOY_RW; | 264 | for(i = 0; i < 0xC0; i+=4) |
| 214 | u32 choseval = REG_JOYRE; | 265 | { |
| 215 | if(choseval == 5) | 266 | REG_JOYTR = *(vu32*)(0x08000000+i); |
| 216 | { | 267 | while((REG_HS_CTRL&JOY_READ) == 0) ; |
| 217 | //disable interrupts | 268 | REG_HS_CTRL |= JOY_RW; |
| 218 | u32 prevIrqMask = REG_IME; | 269 | } |
| 219 | REG_IME = 0; | 270 | REG_JOYTR = 0; |
| 220 | //dump BIOS | 271 | //wait for other side to choose |
| 221 | for (i = 0; i < 0x4000; i+=4) | 272 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; |
| 222 | { | 273 | REG_HS_CTRL |= JOY_RW; |
| 223 | // the lower bits are inaccurate, so just get it four times :) | 274 | u32 choseval = REG_JOYRE; |
| 224 | u32 a = MidiKey2Freq((WaveData *)(i-4), 180-12, 0) * 2; | 275 | if(choseval == 0) |
| 225 | u32 b = MidiKey2Freq((WaveData *)(i-3), 180-12, 0) * 2; | 276 | { |
| 226 | u32 c = MidiKey2Freq((WaveData *)(i-2), 180-12, 0) * 2; | 277 | REG_JOYTR = 0; |
| 227 | u32 d = MidiKey2Freq((WaveData *)(i-1), 180-12, 0) * 2; | 278 | continue; //nothing to read |
| 228 | REG_JOYTR = ((a>>24<<24) | (d>>24<<16) | (c>>24<<8) | (b>>24)); | 279 | } |
| 229 | while((REG_HS_CTRL&JOY_READ) == 0) ; | 280 | else if(choseval == 1) |
| 230 | REG_HS_CTRL |= JOY_RW; | 281 | { |
| 231 | } | 282 | //disable interrupts |
| 232 | //restore interrupts | 283 | u32 prevIrqMask = REG_IME; |
| 233 | REG_IME = prevIrqMask; | 284 | REG_IME = 0; |
| 234 | } | 285 | //dump the game |
| 235 | REG_JOYTR = 0; | 286 | for(i = 0; i < gamesize; i+=4) |
| 236 | } | 287 | { |
| 237 | Halt(); | 288 | REG_JOYTR = *(vu32*)(0x08000000+i); |
| 238 | } | 289 | while((REG_HS_CTRL&JOY_READ) == 0) ; |
| 290 | REG_HS_CTRL |= JOY_RW; | ||
| 291 | } | ||
| 292 | //restore interrupts | ||
| 293 | REG_IME = prevIrqMask; | ||
| 294 | } | ||
| 295 | else if(choseval == 2) | ||
| 296 | { | ||
| 297 | //disable interrupts | ||
| 298 | u32 prevIrqMask = REG_IME; | ||
| 299 | REG_IME = 0; | ||
| 300 | //backup save | ||
| 301 | switch (savesize){ | ||
| 302 | case 0x200: | ||
| 303 | GetSave_EEPROM_512B(save_data); | ||
| 304 | break; | ||
| 305 | case 0x2000: | ||
| 306 | GetSave_EEPROM_8KB(save_data); | ||
| 307 | break; | ||
| 308 | case 0x8000: | ||
| 309 | GetSave_SRAM_32KB(save_data); | ||
| 310 | break; | ||
| 311 | case 0x10000: | ||
| 312 | GetSave_FLASH_64KB(save_data); | ||
| 313 | break; | ||
| 314 | case 0x20000: | ||
| 315 | GetSave_FLASH_128KB(save_data); | ||
| 316 | break; | ||
| 317 | default: | ||
| 318 | break; | ||
| 319 | } | ||
| 320 | //restore interrupts | ||
| 321 | REG_IME = prevIrqMask; | ||
| 322 | //say gc side we read it | ||
| 323 | REG_JOYTR = savesize; | ||
| 324 | //wait for a cmd receive for safety | ||
| 325 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | ||
| 326 | REG_HS_CTRL |= JOY_RW; | ||
| 327 | //send the save | ||
| 328 | for(i = 0; i < savesize; i+=4) | ||
| 329 | { | ||
| 330 | REG_JOYTR = *(vu32*)(save_data+i); | ||
| 331 | while((REG_HS_CTRL&JOY_READ) == 0) ; | ||
| 332 | REG_HS_CTRL |= JOY_RW; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | else if(choseval == 3 || choseval == 4) | ||
| 336 | { | ||
| 337 | REG_JOYTR = savesize; | ||
| 338 | if(choseval == 3) | ||
| 339 | { | ||
| 340 | //receive the save | ||
| 341 | for(i = 0; i < savesize; i+=4) | ||
| 342 | { | ||
| 343 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | ||
| 344 | REG_HS_CTRL |= JOY_RW; | ||
| 345 | *(vu32*)(save_data+i) = REG_JOYRE; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | else | ||
| 349 | { | ||
| 350 | //clear the save | ||
| 351 | for(i = 0; i < savesize; i+=4) | ||
| 352 | *(vu32*)(save_data+i) = 0; | ||
| 353 | } | ||
| 354 | //disable interrupts | ||
| 355 | u32 prevIrqMask = REG_IME; | ||
| 356 | REG_IME = 0; | ||
| 357 | //write it | ||
| 358 | switch (savesize){ | ||
| 359 | case 0x200: | ||
| 360 | PutSave_EEPROM_512B(save_data); | ||
| 361 | break; | ||
| 362 | case 0x2000: | ||
| 363 | PutSave_EEPROM_8KB(save_data); | ||
| 364 | break; | ||
| 365 | case 0x8000: | ||
| 366 | PutSave_SRAM_32KB(save_data); | ||
| 367 | break; | ||
| 368 | case 0x10000: | ||
| 369 | PutSave_FLASH_64KB(save_data); | ||
| 370 | break; | ||
| 371 | case 0x20000: | ||
| 372 | PutSave_FLASH_128KB(save_data); | ||
| 373 | break; | ||
| 374 | default: | ||
| 375 | break; | ||
| 376 | } | ||
| 377 | //restore interrupts | ||
| 378 | REG_IME = prevIrqMask; | ||
| 379 | //say gc side we're done | ||
| 380 | REG_JOYTR = 0; | ||
| 381 | //wait for a cmd receive for safety | ||
| 382 | while((REG_HS_CTRL&JOY_WRITE) == 0) ; | ||
| 383 | REG_HS_CTRL |= JOY_RW; | ||
| 384 | } | ||
| 385 | REG_JOYTR = 0; | ||
| 386 | } | ||
| 387 | } else if(REG_HS_CTRL&JOY_WRITE) | ||
| 388 | { | ||
| 389 | REG_HS_CTRL |= JOY_RW; | ||
| 390 | u32 choseval = REG_JOYRE; | ||
| 391 | if(choseval == 5) | ||
| 392 | { | ||
| 393 | //disable interrupts | ||
| 394 | u32 prevIrqMask = REG_IME; | ||
| 395 | REG_IME = 0; | ||
| 396 | //dump BIOS | ||
| 397 | for (i = 0; i < 0x4000; i+=4) | ||
| 398 | { | ||
| 399 | // the lower bits are inaccurate, so just get it four times :) | ||
| 400 | u32 a = MidiKey2Freq((WaveData *)(i-4), 180-12, 0) * 2; | ||
| 401 | u32 b = MidiKey2Freq((WaveData *)(i-3), 180-12, 0) * 2; | ||
| 402 | u32 c = MidiKey2Freq((WaveData *)(i-2), 180-12, 0) * 2; | ||
| 403 | u32 d = MidiKey2Freq((WaveData *)(i-1), 180-12, 0) * 2; | ||
| 404 | REG_JOYTR = ((a>>24<<24) | (d>>24<<16) | (c>>24<<8) | (b>>24)); | ||
| 405 | while((REG_HS_CTRL&JOY_READ) == 0) ; | ||
| 406 | REG_HS_CTRL |= JOY_RW; | ||
| 407 | } | ||
| 408 | //restore interrupts | ||
| 409 | REG_IME = prevIrqMask; | ||
| 410 | } | ||
| 411 | REG_JOYTR = 0; | ||
| 412 | }*/ | ||
| 413 | Halt(); | ||
| 414 | } | ||
| 239 | } | 415 | } |
| 240 | 416 | ||
| 241 | 417 | ||
