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 | ||