race condition fix from 2007 (gpsp09-2xb_1)
[gpsp.git] / memory.c
CommitLineData
2823a4c8 1/* gameplaySP
2 *
3 * Copyright (C) 2006 Exophase <exophase@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "common.h"
21
22u32 load_file_zip(u8 *filename);
23
24// This table is configured for sequential access on system defaults
25
26u32 waitstate_cycles_sequential[16][3] =
27{
28 { 1, 1, 1 }, // BIOS
29 { 1, 1, 1 }, // Invalid
30 { 3, 3, 6 }, // EWRAM (default settings)
31 { 1, 1, 1 }, // IWRAM
32 { 1, 1, 1 }, // IO Registers
33 { 1, 1, 2 }, // Palette RAM
34 { 1, 1, 2 }, // VRAM
35 { 1, 1, 2 }, // OAM
36 { 3, 3, 6 }, // Gamepak (wait 0)
37 { 3, 3, 6 }, // Gamepak (wait 0)
38 { 5, 5, 9 }, // Gamepak (wait 1)
39 { 5, 5, 9 }, // Gamepak (wait 1)
40 { 9, 9, 17 }, // Gamepak (wait 2)
41 { 9, 9, 17 }, // Gamepak (wait 2)
42};
43
44// Different settings for gamepak ws0-2 sequential (2nd) access
45
46u32 gamepak_waitstate_sequential[2][3][3] =
47{
48 {
49 { 3, 3, 6 },
50 { 5, 5, 9 },
51 { 9, 9, 17 }
52 },
53 {
54 { 2, 2, 3 },
55 { 2, 2, 3 },
56 { 2, 2, 3 }
57 }
58};
59
60u16 palette_ram[512];
61u16 oam_ram[512];
62u16 palette_ram_converted[512];
63u16 io_registers[1024 * 16];
64u8 ewram[1024 * 256 * 2];
65u8 iwram[1024 * 32 * 2];
66u8 vram[1024 * 96 * 2];
67
68u8 bios_rom[1024 * 32];
69u32 bios_read_protect;
70
71// Up to 128kb, store SRAM, flash ROM, or EEPROM here.
72u8 gamepak_backup[1024 * 128];
73
74// Keeps us knowing how much we have left.
75u8 *gamepak_rom;
76u32 gamepak_size;
77
78dma_transfer_type dma[4];
79
80u8 *memory_regions[16];
81u32 memory_limits[16];
82
83typedef struct
84{
85 u32 page_timestamp;
86 u32 physical_index;
87} gamepak_swap_entry_type;
88
89u32 gamepak_ram_buffer_size;
90u32 gamepak_ram_pages;
91
92// Enough to map the gamepak RAM space.
93gamepak_swap_entry_type *gamepak_memory_map;
94
95// This is global so that it can be kept open for large ROMs to swap
96// pages from, so there's no slowdown with opening and closing the file
97// a lot.
98#ifdef PSP_BUILD
99
100file_tag_type gamepak_file_large = -1;
101
102#else
103
104file_tag_type gamepak_file_large = NULL;
105
106#endif
107
108u32 direct_map_vram = 0;
109
110// Writes to these respective locations should trigger an update
111// so the related subsystem may react to it.
112
113// If OAM is written to:
114u32 oam_update = 1;
115
116// If GBC audio is written to:
117u32 gbc_sound_update = 0;
118
119// If the GBC audio waveform is modified:
120u32 gbc_sound_wave_update = 0;
121
122// If the backup space is written (only update once this hits 0)
123u32 backup_update = 0;
124
125// Write out backup file this many cycles after the most recent
126// backup write.
127const u32 write_backup_delay = 10;
128
129
130typedef enum
131{
132 BACKUP_SRAM,
133 BACKUP_FLASH,
134 BACKUP_EEPROM,
135 BACKUP_NONE
136} backup_type_type;
137
138typedef enum
139{
140 SRAM_SIZE_32KB,
141 SRAM_SIZE_64KB
142} sram_size_type;
143
144// Keep it 32KB until the upper 64KB is accessed, then make it 64KB.
145
146backup_type_type backup_type = BACKUP_NONE;
147sram_size_type sram_size = SRAM_SIZE_32KB;
148
149typedef enum
150{
151 FLASH_BASE_MODE,
152 FLASH_ERASE_MODE,
153 FLASH_ID_MODE,
154 FLASH_WRITE_MODE,
155 FLASH_BANKSWITCH_MODE
156} flash_mode_type;
157
158typedef enum
159{
160 FLASH_SIZE_64KB,
161 FLASH_SIZE_128KB
162} flash_size_type;
163
164flash_mode_type flash_mode = FLASH_BASE_MODE;
165u32 flash_command_position = 0;
166u8 *flash_bank_ptr = gamepak_backup;
167
168flash_device_id_type flash_device_id = FLASH_DEVICE_MACRONIX_64KB;
169flash_manufacturer_id_type flash_manufacturer_id =
170 FLASH_MANUFACTURER_MACRONIX;
171flash_size_type flash_size = FLASH_SIZE_64KB;
172
173u8 read_backup(u32 address)
174{
175 u8 value;
176
177 if(backup_type == BACKUP_NONE)
178 backup_type = BACKUP_SRAM;
179
180 if(backup_type == BACKUP_SRAM)
181 {
182 value = gamepak_backup[address];
183 }
184 else
185
186 if(flash_mode == FLASH_ID_MODE)
187 {
188 /* ID manufacturer type */
189 if(address == 0x0000)
190 value = flash_manufacturer_id;
191 else
192
193 /* ID device type */
194 if(address == 0x0001)
195 value = flash_device_id;
196 }
197 else
198 {
199 value = flash_bank_ptr[address];
200 }
201
202 return value;
203}
204
205#define read_backup8() \
206 value = read_backup(address & 0xFFFF) \
207
208#define read_backup16() \
209 value = 0 \
210
211#define read_backup32() \
212 value = 0 \
213
214
215// EEPROM is 512 bytes by default; it is autodetecte as 8KB if
216// 14bit address DMAs are made (this is done in the DMA handler).
217
218typedef enum
219{
220 EEPROM_512_BYTE,
221 EEPROM_8_KBYTE
222} eeprom_size_type;
223
224typedef enum
225{
226 EEPROM_BASE_MODE,
227 EEPROM_READ_MODE,
228 EEPROM_READ_HEADER_MODE,
229 EEPROM_ADDRESS_MODE,
230 EEPROM_WRITE_MODE,
231 EEPROM_WRITE_ADDRESS_MODE,
232 EEPROM_ADDRESS_FOOTER_MODE,
233 EEPROM_WRITE_FOOTER_MODE
234} eeprom_mode_type;
235
236
237eeprom_size_type eeprom_size = EEPROM_512_BYTE;
238eeprom_mode_type eeprom_mode = EEPROM_BASE_MODE;
239u32 eeprom_address_length;
240u32 eeprom_address = 0;
241s32 eeprom_counter = 0;
242u8 eeprom_buffer[8];
243
244
245void function_cc write_eeprom(u32 address, u32 value)
246{
247 switch(eeprom_mode)
248 {
249 case EEPROM_BASE_MODE:
250 backup_type = BACKUP_EEPROM;
251 eeprom_buffer[0] |= (value & 0x01) << (1 - eeprom_counter);
252 eeprom_counter++;
253 if(eeprom_counter == 2)
254 {
255 if(eeprom_size == EEPROM_512_BYTE)
256 eeprom_address_length = 6;
257 else
258 eeprom_address_length = 14;
259
260 eeprom_counter = 0;
261
262 switch(eeprom_buffer[0] & 0x03)
263 {
264 case 0x02:
265 eeprom_mode = EEPROM_WRITE_ADDRESS_MODE;
266 break;
267
268 case 0x03:
269 eeprom_mode = EEPROM_ADDRESS_MODE;
270 break;
271 }
272 address16(eeprom_buffer, 0) = 0;
273 }
274 break;
275
276 case EEPROM_ADDRESS_MODE:
277 case EEPROM_WRITE_ADDRESS_MODE:
278 eeprom_buffer[eeprom_counter / 8]
279 |= (value & 0x01) << (7 - (eeprom_counter % 8));
280 eeprom_counter++;
281 if(eeprom_counter == eeprom_address_length)
282 {
283 if(eeprom_size == EEPROM_512_BYTE)
284 {
285 eeprom_address =
286 (address16(eeprom_buffer, 0) >> 2) * 8;
287 }
288 else
289 {
290 eeprom_address = (((u32)eeprom_buffer[1] >> 2) |
291 ((u32)eeprom_buffer[0] << 6)) * 8;
292 }
293
294 address16(eeprom_buffer, 0) = 0;
295 eeprom_counter = 0;
296
297 if(eeprom_mode == EEPROM_ADDRESS_MODE)
298 {
299 eeprom_mode = EEPROM_ADDRESS_FOOTER_MODE;
300 }
301 else
302 {
303 eeprom_mode = EEPROM_WRITE_MODE;
304 memset(gamepak_backup + eeprom_address, 0, 8);
305 }
306 }
307 break;
308
309 case EEPROM_WRITE_MODE:
310 gamepak_backup[eeprom_address + (eeprom_counter / 8)] |=
311 (value & 0x01) << (7 - (eeprom_counter % 8));
312 eeprom_counter++;
313 if(eeprom_counter == 64)
314 {
315 backup_update = write_backup_delay;
316 eeprom_counter = 0;
317 eeprom_mode = EEPROM_WRITE_FOOTER_MODE;
318 }
319 break;
320
321 case EEPROM_ADDRESS_FOOTER_MODE:
322 case EEPROM_WRITE_FOOTER_MODE:
323 eeprom_counter = 0;
324 if(eeprom_mode == EEPROM_ADDRESS_FOOTER_MODE)
325 {
326 eeprom_mode = EEPROM_READ_HEADER_MODE;
327 }
328 else
329 {
330 eeprom_mode = EEPROM_BASE_MODE;
331 }
332 break;
333 }
334}
335
336#define read_memory_gamepak(type) \
337 u32 gamepak_index = address >> 15; \
338 u8 *map = memory_map_read[gamepak_index]; \
339 \
340 if(map == NULL) \
341 map = load_gamepak_page(gamepak_index & 0x3FF); \
342 \
343 value = address##type(map, address & 0x7FFF) \
344
345#define read_open8() \
346 if(!(reg[REG_CPSR] & 0x20)) \
347 value = read_memory8(reg[REG_PC] + 4 + (address & 0x03)); \
348 else \
349 value = read_memory8(reg[REG_PC] + 2 + (address & 0x01)) \
350
351#define read_open16() \
352 if(!(reg[REG_CPSR] & 0x20)) \
353 value = read_memory16(reg[REG_PC] + 4 + (address & 0x02)); \
354 else \
355 value = read_memory16(reg[REG_PC] + 2) \
356
357#define read_open32() \
358 if(!(reg[REG_CPSR] & 0x20)) \
359 { \
360 value = read_memory32(reg[REG_PC] + 4); \
361 } \
362 else \
363 { \
364 u32 current_instruction = read_memory16(reg[REG_PC] + 2); \
365 value = current_instruction | (current_instruction << 16); \
366 } \
367
368u32 function_cc read_eeprom()
369{
370 u32 value;
371
372 switch(eeprom_mode)
373 {
374 case EEPROM_BASE_MODE:
375 value = 1;
376 break;
377
378 case EEPROM_READ_MODE:
379 value = (gamepak_backup[eeprom_address + (eeprom_counter / 8)] >>
380 (7 - (eeprom_counter % 8))) & 0x01;
381 eeprom_counter++;
382 if(eeprom_counter == 64)
383 {
384 eeprom_counter = 0;
385 eeprom_mode = EEPROM_BASE_MODE;
386 }
387 break;
388
389 case EEPROM_READ_HEADER_MODE:
390 value = 0;
391 eeprom_counter++;
392 if(eeprom_counter == 4)
393 {
394 eeprom_mode = EEPROM_READ_MODE;
395 eeprom_counter = 0;
396 }
397 break;
398
399 default:
400 value = 0;
401 break;
402 }
403
404 return value;
405}
406
407
408#define read_memory(type) \
409 switch(address >> 24) \
410 { \
411 case 0x00: \
412 /* BIOS */ \
413 if(reg[REG_PC] >= 0x4000) \
414 value = address##type(&bios_read_protect, address & 0x03); \
415 else \
416 value = address##type(bios_rom, address & 0x3FFF); \
417 break; \
418 \
419 case 0x02: \
420 /* external work RAM */ \
421 address = (address & 0x7FFF) + ((address & 0x38000) * 2) + 0x8000; \
422 value = address##type(ewram, address); \
423 break; \
424 \
425 case 0x03: \
426 /* internal work RAM */ \
427 value = address##type(iwram, (address & 0x7FFF) + 0x8000); \
428 break; \
429 \
430 case 0x04: \
431 /* I/O registers */ \
432 value = address##type(io_registers, address & 0x3FF); \
433 break; \
434 \
435 case 0x05: \
436 /* palette RAM */ \
437 value = address##type(palette_ram, address & 0x3FF); \
438 break; \
439 \
440 case 0x06: \
441 /* VRAM */ \
442 address &= 0x1FFFF; \
443 if(address > 0x18000) \
444 address -= 0x8000; \
445 \
446 value = address##type(vram, address); \
447 break; \
448 \
449 case 0x07: \
450 /* OAM RAM */ \
451 value = address##type(oam_ram, address & 0x3FF); \
452 break; \
453 \
454 case 0x08: \
455 case 0x09: \
456 case 0x0A: \
457 case 0x0B: \
458 case 0x0C: \
459 /* gamepak ROM */ \
460 if((address & 0x1FFFFFF) >= gamepak_size) \
461 { \
462 value = 0; \
463 } \
464 else \
465 { \
466 read_memory_gamepak(type); \
467 } \
468 break; \
469 \
470 case 0x0D: \
471 if((address & 0x1FFFFFF) < gamepak_size) \
472 { \
473 read_memory_gamepak(type); \
474 } \
475 else \
476 { \
477 value = read_eeprom(); \
478 } \
479 \
480 break; \
481 \
482 case 0x0E: \
483 case 0x0F: \
484 read_backup##type(); \
485 break; \
486 \
487 default: \
488 read_open##type(); \
489 break; \
490 } \
491
492#define trigger_dma(dma_number) \
493 if(value & 0x8000) \
494 { \
495 if(dma[dma_number].start_type == DMA_INACTIVE) \
496 { \
497 u32 start_type = (value >> 12) & 0x03; \
498 u32 dest_address = address32(io_registers, (dma_number * 12) + 0xB4) & \
499 0xFFFFFFF; \
500 \
501 dma[dma_number].dma_channel = dma_number; \
502 dma[dma_number].source_address = \
503 address32(io_registers, (dma_number * 12) + 0xB0) & 0xFFFFFFF; \
504 dma[dma_number].dest_address = dest_address; \
505 dma[dma_number].source_direction = (value >> 7) & 0x03; \
506 dma[dma_number].repeat_type = (value >> 9) & 0x01; \
507 dma[dma_number].start_type = start_type; \
508 dma[dma_number].irq = (value >> 14) & 0x01; \
509 \
510 /* If it is sound FIFO DMA make sure the settings are a certain way */ \
511 if((dma_number >= 1) && (dma_number <= 2) && \
512 (start_type == DMA_START_SPECIAL)) \
513 { \
514 dma[dma_number].length_type = DMA_32BIT; \
515 dma[dma_number].length = 4; \
516 dma[dma_number].dest_direction = DMA_FIXED; \
517 if(dest_address == 0x40000A4) \
518 dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_B; \
519 else \
520 dma[dma_number].direct_sound_channel = DMA_DIRECT_SOUND_A; \
521 } \
522 else \
523 { \
524 u32 length = \
525 address16(io_registers, (dma_number * 12) + 0xB8); \
526 \
527 if((dma_number == 3) && ((dest_address >> 24) == 0x0D) && \
528 ((length & 0x1F) == 17)) \
529 { \
530 eeprom_size = EEPROM_8_KBYTE; \
531 } \
532 \
533 if(dma_number < 3) \
534 length &= 0x3FFF; \
535 \
536 if(length == 0) \
537 { \
538 if(dma_number == 3) \
539 length = 0x10000; \
540 else \
541 length = 0x04000; \
542 } \
543 \
544 dma[dma_number].length = length; \
545 dma[dma_number].length_type = (value >> 10) & 0x01; \
546 dma[dma_number].dest_direction = (value >> 5) & 0x03; \
547 } \
548 \
549 address16(io_registers, (dma_number * 12) + 0xBA) = value; \
550 if(start_type == DMA_START_IMMEDIATELY) \
551 return dma_transfer(dma + dma_number); \
552 } \
553 } \
554 else \
555 { \
556 dma[dma_number].start_type = DMA_INACTIVE; \
557 dma[dma_number].direct_sound_channel = DMA_NO_DIRECT_SOUND; \
558 address16(io_registers, (dma_number * 12) + 0xBA) = value; \
559 } \
560
561
562#define access_register8_high(address) \
563 value = (value << 8) | (address8(io_registers, address)) \
564
565#define access_register8_low(address) \
566 value = ((address8(io_registers, address + 1)) << 8) | value \
567
568#define access_register16_high(address) \
569 value = (value << 16) | (address16(io_registers, address)) \
570
571#define access_register16_low(address) \
572 value = ((address16(io_registers, address + 2)) << 16) | value \
573
574cpu_alert_type function_cc write_io_register8(u32 address, u32 value)
575{
576 switch(address)
577 {
578 case 0x00:
579 {
580 u32 dispcnt = io_registers[REG_DISPCNT];
581
582 if((value & 0x07) != (dispcnt & 0x07))
583 oam_update = 1;
584
585 address8(io_registers, 0x00) = value;
586 break;
587 }
588
589 // DISPSTAT (lower byte)
590 case 0x04:
591 address8(io_registers, 0x04) =
592 (address8(io_registers, 0x04) & 0x07) | (value & ~0x07);
593 break;
594
595 // VCOUNT
596 case 0x06:
597 case 0x07:
598 break;
599
600 // BG2 reference X
601 case 0x28:
602 access_register8_low(0x28);
603 access_register16_low(0x28);
604 affine_reference_x[0] = (s32)(value << 4) >> 4;
605 address32(io_registers, 0x28) = value;
606 break;
607
608 case 0x29:
609 access_register8_high(0x28);
610 access_register16_low(0x28);
611 affine_reference_x[0] = (s32)(value << 4) >> 4;
612 address32(io_registers, 0x28) = value;
613 break;
614
615 case 0x2A:
616 access_register8_low(0x2A);
617 access_register16_high(0x28);
618 affine_reference_x[0] = (s32)(value << 4) >> 4;
619 address32(io_registers, 0x28) = value;
620 break;
621
622 case 0x2B:
623 access_register8_high(0x2A);
624 access_register16_high(0x28);
625 affine_reference_x[0] = (s32)(value << 4) >> 4;
626 address32(io_registers, 0x28) = value;
627 break;
628
629 // BG2 reference Y
630 case 0x2C:
631 access_register8_low(0x2C);
632 access_register16_low(0x2C);
633 affine_reference_y[0] = (s32)(value << 4) >> 4;
634 address32(io_registers, 0x2C) = value;
635 break;
636
637 case 0x2D:
638 access_register8_high(0x2C);
639 access_register16_low(0x2C);
640 affine_reference_y[0] = (s32)(value << 4) >> 4;
641 address32(io_registers, 0x2C) = value;
642 break;
643
644 case 0x2E:
645 access_register8_low(0x2E);
646 access_register16_high(0x2C);
647 affine_reference_y[0] = (s32)(value << 4) >> 4;
648 address32(io_registers, 0x2C) = value;
649 break;
650
651 case 0x2F:
652 access_register8_high(0x2E);
653 access_register16_high(0x2C);
654 affine_reference_y[0] = (s32)(value << 4) >> 4;
655 address32(io_registers, 0x2C) = value;
656 break;
657
658 // BG3 reference X
659 case 0x38:
660 access_register8_low(0x38);
661 access_register16_low(0x38);
662 affine_reference_x[1] = (s32)(value << 4) >> 4;
663 address32(io_registers, 0x38) = value;
664 break;
665
666 case 0x39:
667 access_register8_high(0x38);
668 access_register16_low(0x38);
669 affine_reference_x[1] = (s32)(value << 4) >> 4;
670 address32(io_registers, 0x38) = value;
671 break;
672
673 case 0x3A:
674 access_register8_low(0x3A);
675 access_register16_high(0x38);
676 affine_reference_x[1] = (s32)(value << 4) >> 4;
677 address32(io_registers, 0x38) = value;
678 break;
679
680 case 0x3B:
681 access_register8_high(0x3A);
682 access_register16_high(0x38);
683 affine_reference_x[1] = (s32)(value << 4) >> 4;
684 address32(io_registers, 0x38) = value;
685 break;
686
687 // BG3 reference Y
688 case 0x3C:
689 access_register8_low(0x3C);
690 access_register16_low(0x3C);
691 affine_reference_y[1] = (s32)(value << 4) >> 4;
692 address32(io_registers, 0x3C) = value;
693 break;
694
695 case 0x3D:
696 access_register8_high(0x3C);
697 access_register16_low(0x3C);
698 affine_reference_y[1] = (s32)(value << 4) >> 4;
699 address32(io_registers, 0x3C) = value;
700 break;
701
702 case 0x3E:
703 access_register8_low(0x3E);
704 access_register16_high(0x3C);
705 affine_reference_y[1] = (s32)(value << 4) >> 4;
706 address32(io_registers, 0x3C) = value;
707 break;
708
709 case 0x3F:
710 access_register8_high(0x3E);
711 access_register16_high(0x3C);
712 affine_reference_y[1] = (s32)(value << 4) >> 4;
713 address32(io_registers, 0x3C) = value;
714 break;
715
716 // Sound 1 control sweep
717 case 0x60:
718 access_register8_low(0x60);
719 gbc_sound_tone_control_sweep();
720 break;
721
722 case 0x61:
723 access_register8_low(0x60);
724 gbc_sound_tone_control_sweep();
725 break;
726
727 // Sound 1 control duty/length/envelope
728 case 0x62:
729 access_register8_low(0x62);
730 gbc_sound_tone_control_low(0, 0x62);
731 break;
732
733 case 0x63:
734 access_register8_high(0x62);
735 gbc_sound_tone_control_low(0, 0x62);
736 break;
737
738 // Sound 1 control frequency
739 case 0x64:
740 access_register8_low(0x64);
741 gbc_sound_tone_control_high(0, 0x64);
742 break;
743
744 case 0x65:
745 access_register8_high(0x64);
746 gbc_sound_tone_control_high(0, 0x64);
747 break;
748
749 // Sound 2 control duty/length/envelope
750 case 0x68:
751 access_register8_low(0x68);
752 gbc_sound_tone_control_low(1, 0x68);
753 break;
754
755 case 0x69:
756 access_register8_high(0x68);
757 gbc_sound_tone_control_low(1, 0x68);
758 break;
759
760 // Sound 2 control frequency
761 case 0x6C:
762 access_register8_low(0x6C);
763 gbc_sound_tone_control_high(1, 0x6C);
764 break;
765
766 case 0x6D:
767 access_register8_high(0x6C);
768 gbc_sound_tone_control_high(1, 0x6C);
769 break;
770
771 // Sound 3 control wave
772 case 0x70:
773 access_register8_low(0x70);
774 gbc_sound_wave_control();
775 break;
776
777 case 0x71:
778 access_register8_high(0x70);
779 gbc_sound_wave_control();
780 break;
781
782 // Sound 3 control length/volume
783 case 0x72:
784 access_register8_low(0x72);
785 gbc_sound_tone_control_low_wave();
786 break;
787
788 case 0x73:
789 access_register8_high(0x72);
790 gbc_sound_tone_control_low_wave();
791 break;
792
793 // Sound 3 control frequency
794 case 0x74:
795 access_register8_low(0x74);
796 gbc_sound_tone_control_high_wave();
797 break;
798
799 case 0x75:
800 access_register8_high(0x74);
801 gbc_sound_tone_control_high_wave();
802 break;
803
804 // Sound 4 control length/envelope
805 case 0x78:
806 access_register8_low(0x78);
807 gbc_sound_tone_control_low(3, 0x78);
808 break;
809
810 case 0x79:
811 access_register8_high(0x78);
812 gbc_sound_tone_control_low(3, 0x78);
813 break;
814
815 // Sound 4 control frequency
816 case 0x7C:
817 access_register8_low(0x7C);
818 gbc_sound_noise_control();
819 break;
820
821 case 0x7D:
822 access_register8_high(0x7C);
823 gbc_sound_noise_control();
824 break;
825
826 // Sound control L
827 case 0x80:
828 access_register8_low(0x80);
829 gbc_trigger_sound();
830 break;
831
832 case 0x81:
833 access_register8_high(0x80);
834 gbc_trigger_sound();
835 break;
836
837 // Sound control H
838 case 0x82:
839 access_register8_low(0x82);
840 trigger_sound();
841 break;
842
843 case 0x83:
844 access_register8_high(0x82);
845 trigger_sound();
846 break;
847
848 // Sound control X
849 case 0x84:
850 sound_on();
851 break;
852
853 // Sound wave RAM
854 case 0x90 ... 0x9F:
855 gbc_sound_wave_update = 1;
856 address8(io_registers, address) = value;
857 break;
858
859 // Sound FIFO A
860 case 0xA0:
861 sound_timer_queue8(0, value);
862 break;
863
864 // Sound FIFO B
865 case 0xA4:
866 sound_timer_queue8(1, value);
867 break;
868
869 // DMA control (trigger byte)
870 case 0xBB:
871 access_register8_low(0xBA);
872 trigger_dma(0);
873 break;
874
875 case 0xC7:
876 access_register8_low(0xC6);
877 trigger_dma(1);
878 break;
879
880 case 0xD3:
881 access_register8_low(0xD2);
882 trigger_dma(2);
883 break;
884
885 case 0xDF:
886 access_register8_low(0xDE);
887 trigger_dma(3);
888 break;
889
890 // Timer counts
891 case 0x100:
892 access_register8_low(0x100);
893 count_timer(0);
894 break;
895
896 case 0x101:
897 access_register8_high(0x100);
898 count_timer(0);
899 break;
900
901 case 0x104:
902 access_register8_low(0x104);
903 count_timer(1);
904 break;
905
906 case 0x105:
907 access_register8_high(0x104);
908 count_timer(1);
909 break;
910
911 case 0x108:
912 access_register8_low(0x108);
913 count_timer(2);
914 break;
915
916 case 0x109:
917 access_register8_high(0x108);
918 count_timer(2);
919 break;
920
921 case 0x10C:
922 access_register8_low(0x10C);
923 count_timer(3);
924 break;
925
926 case 0x10D:
927 access_register8_high(0x10C);
928 count_timer(3);
929 break;
930
931 // Timer control (trigger byte)
932 case 0x103:
933 access_register8_low(0x102);
934 trigger_timer(0);
935 break;
936
937 case 0x107:
938 access_register8_low(0x106);
939 trigger_timer(1);
940 break;
941
942 case 0x10B:
943 access_register8_low(0x10A);
944 trigger_timer(2);
945 break;
946
947 case 0x10F:
948 access_register8_low(0x10E);
949 trigger_timer(3);
950 break;
951
952 // IF
953 case 0x202:
954 address8(io_registers, 0x202) &= ~value;
955 break;
956
957 case 0x203:
958 address8(io_registers, 0x203) &= ~value;
959 break;
960
961 // Halt
962 case 0x301:
963 if((value & 0x01) == 0)
964 reg[CPU_HALT_STATE] = CPU_HALT;
965 else
966 reg[CPU_HALT_STATE] = CPU_STOP;
967
968 return CPU_ALERT_HALT;
969 break;
970
971 default:
972 address8(io_registers, address) = value;
973 break;
974 }
975
976 return CPU_ALERT_NONE;
977}
978
979cpu_alert_type function_cc write_io_register16(u32 address, u32 value)
980{
981 switch(address)
982 {
983 case 0x00:
984 {
985 u32 dispcnt = io_registers[REG_DISPCNT];
986 if((value & 0x07) != (dispcnt & 0x07))
987 oam_update = 1;
988
989 address16(io_registers, 0x00) = value;
990 break;
991 }
992
993 // DISPSTAT
994 case 0x04:
995 address16(io_registers, 0x04) =
996 (address16(io_registers, 0x04) & 0x07) | (value & ~0x07);
997 break;
998
999 // VCOUNT
1000 case 0x06:
1001 break;
1002
1003 // BG2 reference X
1004 case 0x28:
1005 access_register16_low(0x28);
1006 affine_reference_x[0] = (s32)(value << 4) >> 4;
1007 address32(io_registers, 0x28) = value;
1008 break;
1009
1010 case 0x2A:
1011 access_register16_high(0x28);
1012 affine_reference_x[0] = (s32)(value << 4) >> 4;
1013 address32(io_registers, 0x28) = value;
1014 break;
1015
1016 // BG2 reference Y
1017 case 0x2C:
1018 access_register16_low(0x2C);
1019 affine_reference_y[0] = (s32)(value << 4) >> 4;
1020 address32(io_registers, 0x2C) = value;
1021 break;
1022
1023 case 0x2E:
1024 access_register16_high(0x2C);
1025 affine_reference_y[0] = (s32)(value << 4) >> 4;
1026 address32(io_registers, 0x2C) = value;
1027 break;
1028
1029 // BG3 reference X
1030
1031 case 0x38:
1032 access_register16_low(0x38);
1033 affine_reference_x[1] = (s32)(value << 4) >> 4;
1034 address32(io_registers, 0x38) = value;
1035 break;
1036
1037 case 0x3A:
1038 access_register16_high(0x38);
1039 affine_reference_x[1] = (s32)(value << 4) >> 4;
1040 address32(io_registers, 0x38) = value;
1041 break;
1042
1043 // BG3 reference Y
1044 case 0x3C:
1045 access_register16_low(0x3C);
1046 affine_reference_y[1] = (s32)(value << 4) >> 4;
1047 address32(io_registers, 0x3C) = value;
1048 break;
1049
1050 case 0x3E:
1051 access_register16_high(0x3C);
1052 affine_reference_y[1] = (s32)(value << 4) >> 4;
1053 address32(io_registers, 0x3C) = value;
1054 break;
1055
1056 // Sound 1 control sweep
1057 case 0x60:
1058 gbc_sound_tone_control_sweep();
1059 break;
1060
1061 // Sound 1 control duty/length/envelope
1062 case 0x62:
1063 gbc_sound_tone_control_low(0, 0x62);
1064 break;
1065
1066 // Sound 1 control frequency
1067 case 0x64:
1068 gbc_sound_tone_control_high(0, 0x64);
1069 break;
1070
1071 // Sound 2 control duty/length/envelope
1072 case 0x68:
1073 gbc_sound_tone_control_low(1, 0x68);
1074 break;
1075
1076 // Sound 2 control frequency
1077 case 0x6C:
1078 gbc_sound_tone_control_high(1, 0x6C);
1079 break;
1080
1081 // Sound 3 control wave
1082 case 0x70:
1083 gbc_sound_wave_control();
1084 break;
1085
1086 // Sound 3 control length/volume
1087 case 0x72:
1088 gbc_sound_tone_control_low_wave();
1089 break;
1090
1091 // Sound 3 control frequency
1092 case 0x74:
1093 gbc_sound_tone_control_high_wave();
1094 break;
1095
1096 // Sound 4 control length/envelope
1097 case 0x78:
1098 gbc_sound_tone_control_low(3, 0x78);
1099 break;
1100
1101 // Sound 4 control frequency
1102 case 0x7C:
1103 gbc_sound_noise_control();
1104 break;
1105
1106 // Sound control L
1107 case 0x80:
1108 gbc_trigger_sound();
1109 break;
1110
1111 // Sound control H
1112 case 0x82:
1113 trigger_sound();
1114 break;
1115
1116 // Sound control X
1117 case 0x84:
1118 sound_on();
1119 break;
1120
1121 // Sound wave RAM
1122 case 0x90 ... 0x9E:
1123 gbc_sound_wave_update = 1;
1124 address16(io_registers, address) = value;
1125 break;
1126
1127 // Sound FIFO A
1128 case 0xA0:
1129 sound_timer_queue16(0, value);
1130 break;
1131
1132 // Sound FIFO B
1133 case 0xA4:
1134 sound_timer_queue16(1, value);
1135 break;
1136
1137 // DMA control
1138 case 0xBA:
1139 trigger_dma(0);
1140 break;
1141
1142 case 0xC6:
1143 trigger_dma(1);
1144 break;
1145
1146 case 0xD2:
1147 trigger_dma(2);
1148 break;
1149
1150 case 0xDE:
1151 trigger_dma(3);
1152 break;
1153
1154 // Timer counts
1155 case 0x100:
1156 count_timer(0);
1157 break;
1158
1159 case 0x104:
1160 count_timer(1);
1161 break;
1162
1163 case 0x108:
1164 count_timer(2);
1165 break;
1166
1167 case 0x10C:
1168 count_timer(3);
1169 break;
1170
1171 // Timer control
1172 case 0x102:
1173 trigger_timer(0);
1174 break;
1175
1176 case 0x106:
1177 trigger_timer(1);
1178 break;
1179
1180 case 0x10A:
1181 trigger_timer(2);
1182 break;
1183
1184 case 0x10E:
1185 trigger_timer(3);
1186 break;
1187
1188 // P1
1189 case 0x130:
1190 break;
1191
1192 // Interrupt flag
1193 case 0x202:
1194 address16(io_registers, 0x202) &= ~value;
1195 break;
1196
1197 // WAITCNT
1198 case 0x204:
1199 break;
1200
1201 // Halt
1202 case 0x300:
1203 if(((value >> 8) & 0x01) == 0)
1204 reg[CPU_HALT_STATE] = CPU_HALT;
1205 else
1206 reg[CPU_HALT_STATE] = CPU_STOP;
1207
1208 return CPU_ALERT_HALT;
1209
1210 default:
1211 address16(io_registers, address) = value;
1212 break;
1213 }
1214
1215 return CPU_ALERT_NONE;
1216}
1217
1218
1219cpu_alert_type function_cc write_io_register32(u32 address, u32 value)
1220{
1221 switch(address)
1222 {
1223 // BG2 reference X
1224 case 0x28:
1225 affine_reference_x[0] = (s32)(value << 4) >> 4;
1226 address32(io_registers, 0x28) = value;
1227 break;
1228
1229 // BG2 reference Y
1230 case 0x2C:
1231 affine_reference_y[0] = (s32)(value << 4) >> 4;
1232 address32(io_registers, 0x2C) = value;
1233 break;
1234
1235 // BG3 reference X
1236 case 0x38:
1237 affine_reference_x[1] = (s32)(value << 4) >> 4;
1238 address32(io_registers, 0x38) = value;
1239 break;
1240
1241 // BG3 reference Y
1242 case 0x3C:
1243 affine_reference_y[1] = (s32)(value << 4) >> 4;
1244 address32(io_registers, 0x3C) = value;
1245 break;
1246
1247 // Sound FIFO A
1248 case 0xA0:
1249 sound_timer_queue32(0, value);
1250 break;
1251
1252 // Sound FIFO B
1253 case 0xA4:
1254 sound_timer_queue32(1, value);
1255 break;
1256
1257 default:
1258 {
1259 cpu_alert_type alert_low =
1260 write_io_register16(address, value & 0xFFFF);
1261
1262 cpu_alert_type alert_high =
1263 write_io_register16(address + 2, value >> 16);
1264
1265 if(alert_high)
1266 return alert_high;
1267
1268 return alert_low;
1269 }
1270 }
1271
1272 return CPU_ALERT_NONE;
1273}
1274
1275#define write_palette8(address, value) \
1276
1277#define write_palette16(address, value) \
1278{ \
1279 u32 palette_address = address; \
1280 address16(palette_ram, palette_address) = value; \
1281 convert_palette(value); \
1282 address16(palette_ram_converted, palette_address) = value; \
1283} \
1284
1285#define write_palette32(address, value) \
1286{ \
1287 u32 palette_address = address; \
1288 u32 value_high = value >> 16; \
1289 u32 value_low = value & 0xFFFF; \
1290 address32(palette_ram, palette_address) = value; \
1291 convert_palette(value_high); \
1292 convert_palette(value_low); \
1293 value = (value_high << 16) | value_low; \
1294 address32(palette_ram_converted, palette_address) = value; \
1295} \
1296
1297
1298void function_cc write_backup(u32 address, u32 value)
1299{
1300 value &= 0xFF;
1301
1302 if(backup_type == BACKUP_NONE)
1303 backup_type = BACKUP_SRAM;
1304
1305
1306 // gamepak SRAM or Flash ROM
1307 if((address == 0x5555) && (flash_mode != FLASH_WRITE_MODE))
1308 {
1309 if((flash_command_position == 0) && (value == 0xAA))
1310 {
1311 backup_type = BACKUP_FLASH;
1312 flash_command_position = 1;
1313 }
1314
1315 if(flash_command_position == 2)
1316 {
1317 switch(value)
1318 {
1319 case 0x90:
1320 // Enter ID mode, this also tells the emulator that we're using
1321 // flash, not SRAM
1322
1323 if(flash_mode == FLASH_BASE_MODE)
1324 flash_mode = FLASH_ID_MODE;
1325
1326 break;
1327
1328 case 0x80:
1329 // Enter erase mode
1330 if(flash_mode == FLASH_BASE_MODE)
1331 flash_mode = FLASH_ERASE_MODE;
1332 break;
1333
1334 case 0xF0:
1335 // Terminate ID mode
1336 if(flash_mode == FLASH_ID_MODE)
1337 flash_mode = FLASH_BASE_MODE;
1338 break;
1339
1340 case 0xA0:
1341 // Write mode
1342 if(flash_mode == FLASH_BASE_MODE)
1343 flash_mode = FLASH_WRITE_MODE;
1344 break;
1345
1346 case 0xB0:
1347 // Bank switch
1348 // Here the chip is now officially 128KB.
1349 flash_size = FLASH_SIZE_128KB;
1350 if(flash_mode == FLASH_BASE_MODE)
1351 flash_mode = FLASH_BANKSWITCH_MODE;
1352 break;
1353
1354 case 0x10:
1355 // Erase chip
1356 if(flash_mode == FLASH_ERASE_MODE)
1357 {
1358 if(flash_size == FLASH_SIZE_64KB)
1359 memset(gamepak_backup, 0xFF, 1024 * 64);
1360 else
1361 memset(gamepak_backup, 0xFF, 1024 * 128);
1362 backup_update = write_backup_delay;
1363 flash_mode = FLASH_BASE_MODE;
1364 }
1365 break;
1366
1367 default:
1368 break;
1369 }
1370 flash_command_position = 0;
1371 }
1372 if(backup_type == BACKUP_SRAM)
1373 gamepak_backup[0x5555] = value;
1374 }
1375 else
1376
1377 if((address == 0x2AAA) && (value == 0x55) &&
1378 (flash_command_position == 1))
1379 {
1380 flash_command_position = 2;
1381 }
1382 else
1383 {
1384 if((flash_command_position == 2) &&
1385 (flash_mode == FLASH_ERASE_MODE) && (value == 0x30))
1386 {
1387 // Erase sector
1388 memset(flash_bank_ptr + (address & 0xF000), 0xFF, 1024 * 4);
1389 backup_update = write_backup_delay;
1390 flash_mode = FLASH_BASE_MODE;
1391 flash_command_position = 0;
1392 }
1393 else
1394
1395 if((flash_command_position == 0) &&
1396 (flash_mode == FLASH_BANKSWITCH_MODE) && (address == 0x0000) &&
1397 (flash_size == FLASH_SIZE_128KB))
1398 {
1399 flash_bank_ptr = gamepak_backup + ((value & 0x01) * (1024 * 64));
1400 flash_mode = FLASH_BASE_MODE;
1401 }
1402 else
1403
1404 if((flash_command_position == 0) && (flash_mode == FLASH_WRITE_MODE))
1405 {
1406 // Write value to flash ROM
1407 backup_update = write_backup_delay;
1408 flash_bank_ptr[address] = value;
1409 flash_mode = FLASH_BASE_MODE;
1410 }
1411 else
1412
1413 if(backup_type == BACKUP_SRAM)
1414 {
1415 // Write value to SRAM
1416 backup_update = write_backup_delay;
1417 // Hit 64KB territory?
1418 if(address >= 0x8000)
1419 sram_size = SRAM_SIZE_64KB;
1420 gamepak_backup[address] = value;
1421 }
1422 }
1423}
1424
1425#define write_backup8() \
1426 write_backup(address & 0xFFFF, value) \
1427
1428#define write_backup16() \
1429
1430#define write_backup32() \
1431
1432#define write_vram8() \
1433 address &= ~0x01; \
1434 address16(vram, address) = ((value << 8) | value) \
1435
1436#define write_vram16() \
1437 address16(vram, address) = value \
1438
1439#define write_vram32() \
1440 address32(vram, address) = value \
1441
1442// RTC code derived from VBA's (due to lack of any real publically available
1443// documentation...)
1444
1445typedef enum
1446{
1447 RTC_DISABLED,
1448 RTC_IDLE,
1449 RTC_COMMAND,
1450 RTC_OUTPUT_DATA,
1451 RTC_INPUT_DATA
1452} rtc_state_type;
1453
1454typedef enum
1455{
1456 RTC_COMMAND_RESET = 0x60,
1457 RTC_COMMAND_WRITE_STATUS = 0x62,
1458 RTC_COMMAND_READ_STATUS = 0x63,
1459 RTC_COMMAND_OUTPUT_TIME_FULL = 0x65,
1460 RTC_COMMAND_OUTPUT_TIME = 0x67
1461} rtc_command_type;
1462
1463typedef enum
1464{
1465 RTC_WRITE_TIME,
1466 RTC_WRITE_TIME_FULL,
1467 RTC_WRITE_STATUS
1468} rtc_write_mode_type;
1469
1470rtc_state_type rtc_state = RTC_DISABLED;
1471rtc_write_mode_type rtc_write_mode;
1472u8 rtc_registers[3];
1473u32 rtc_command;
1474u32 rtc_data[12];
1475u32 rtc_status = 0x40;
1476u32 rtc_data_bytes;
1477s32 rtc_bit_count;
1478
1479u32 encode_bcd(u8 value)
1480{
1481 return ((value / 10) << 4) | (value % 10);
1482}
1483
1484#define write_rtc_register(index, _value) \
1485 update_address = 0x80000C4 + (index * 2); \
1486 rtc_registers[index] = _value; \
1487 rtc_page_index = update_address >> 15; \
1488 map = memory_map_read[rtc_page_index]; \
1489 \
1490 if(map == NULL) \
1491 map = load_gamepak_page(rtc_page_index & 0x3FF); \
1492 \
1493 address16(map, update_address & 0x7FFF) = _value \
1494
1495void function_cc write_rtc(u32 address, u32 value)
1496{
1497 u32 rtc_page_index;
1498 u32 update_address;
1499 u8 *map;
1500
1501 value &= 0xFFFF;
1502
1503 switch(address)
1504 {
1505 // RTC command
1506 // Bit 0: SCHK, perform action
1507 // Bit 1: IO, input/output command data
1508 // Bit 2: CS, select input/output? If high make I/O write only
1509 case 0xC4:
1510 if(rtc_state == RTC_DISABLED)
1511 rtc_state = RTC_IDLE;
1512 if(!(rtc_registers[0] & 0x04))
1513 value = (rtc_registers[0] & 0x02) | (value & ~0x02);
1514 if(rtc_registers[2] & 0x01)
1515 {
1516 // To begin writing a command 1, 5 must be written to the command
1517 // registers.
1518 if((rtc_state == RTC_IDLE) && (rtc_registers[0] == 0x01) &&
1519 (value == 0x05))
1520 {
1521 // We're now ready to begin receiving a command.
1522 write_rtc_register(0, value);
1523 rtc_state = RTC_COMMAND;
1524 rtc_command = 0;
1525 rtc_bit_count = 7;
1526 }
1527 else
1528 {
1529 write_rtc_register(0, value);
1530 switch(rtc_state)
1531 {
1532 // Accumulate RTC command by receiving the next bit, and if we
1533 // have accumulated enough bits to form a complete command
1534 // execute it.
1535 case RTC_COMMAND:
1536 if(rtc_registers[0] & 0x01)
1537 {
1538 rtc_command |= ((value & 0x02) >> 1) << rtc_bit_count;
1539 rtc_bit_count--;
1540 }
1541
1542 // Have we received a full RTC command? If so execute it.
1543 if(rtc_bit_count < 0)
1544 {
1545 switch(rtc_command)
1546 {
1547 // Resets RTC
1548 case RTC_COMMAND_RESET:
1549 rtc_state = RTC_IDLE;
1550 memset(rtc_registers, 0, sizeof(rtc_registers));
1551 break;
1552
1553 // Sets status of RTC
1554 case RTC_COMMAND_WRITE_STATUS:
1555 rtc_state = RTC_INPUT_DATA;
1556 rtc_data_bytes = 1;
1557 rtc_write_mode = RTC_WRITE_STATUS;
1558 break;
1559
1560 // Outputs current status of RTC
1561 case RTC_COMMAND_READ_STATUS:
1562 rtc_state = RTC_OUTPUT_DATA;
1563 rtc_data_bytes = 1;
1564 rtc_data[0] = rtc_status;
1565 break;
1566
1567 // Actually outputs the time, all of it
1568 case RTC_COMMAND_OUTPUT_TIME_FULL:
1569 {
1570 struct tm *current_time;
1571 time_t current_time_flat;
1572 u32 day_of_week;
1573
1574 time(&current_time_flat);
1575 current_time = localtime(&current_time_flat);
1576
1577 day_of_week = current_time->tm_wday;
1578 if(day_of_week == 0)
1579 day_of_week = 6;
1580 else
1581 day_of_week--;
1582
1583 rtc_state = RTC_OUTPUT_DATA;
1584 rtc_data_bytes = 7;
1585 rtc_data[0] = encode_bcd(current_time->tm_year % 100);
1586 rtc_data[1] = encode_bcd(current_time->tm_mon + 1);
1587 rtc_data[2] = encode_bcd(current_time->tm_mday);
1588 rtc_data[3] = encode_bcd(day_of_week);
1589 rtc_data[4] = encode_bcd(current_time->tm_hour);
1590 rtc_data[5] = encode_bcd(current_time->tm_min);
1591 rtc_data[6] = encode_bcd(current_time->tm_sec);
1592
1593 break;
1594 }
1595
1596 // Only outputs the current time of day.
1597 case RTC_COMMAND_OUTPUT_TIME:
1598 {
1599 struct tm *current_time;
1600 time_t current_time_flat;
1601
1602 time(&current_time_flat);
1603 current_time = localtime(&current_time_flat);
1604
1605 rtc_state = RTC_OUTPUT_DATA;
1606 rtc_data_bytes = 3;
1607 rtc_data[0] = encode_bcd(current_time->tm_hour);
1608 rtc_data[1] = encode_bcd(current_time->tm_min);
1609 rtc_data[2] = encode_bcd(current_time->tm_sec);
1610 break;
1611 }
1612 }
1613 rtc_bit_count = 0;
1614 }
1615 break;
1616
1617 // Receive parameters from the game as input to the RTC
1618 // for a given command. Read one bit at a time.
1619 case RTC_INPUT_DATA:
1620 // Bit 1 of parameter A must be high for input
1621 if(rtc_registers[1] & 0x02)
1622 {
1623 // Read next bit for input
1624 if(!(value & 0x01))
1625 {
1626 rtc_data[rtc_bit_count >> 3] |=
1627 ((value & 0x01) << (7 - (rtc_bit_count & 0x07)));
1628 }
1629 else
1630 {
1631 rtc_bit_count++;
1632
1633 if(rtc_bit_count == (rtc_data_bytes * 8))
1634 {
1635 rtc_state = RTC_IDLE;
1636 switch(rtc_write_mode)
1637 {
1638 case RTC_WRITE_STATUS:
1639 rtc_status = rtc_data[0];
1640 break;
1641 }
1642 }
1643 }
1644 }
1645 break;
1646
1647 case RTC_OUTPUT_DATA:
1648 // Bit 1 of parameter A must be low for output
1649 if(!(rtc_registers[1] & 0x02))
1650 {
1651 // Write next bit to output, on bit 1 of parameter B
1652 if(!(value & 0x01))
1653 {
1654 u8 current_output_byte = rtc_registers[2];
1655
1656 current_output_byte =
1657 (current_output_byte & ~0x02) |
1658 (((rtc_data[rtc_bit_count >> 3] >>
1659 (rtc_bit_count & 0x07)) & 0x01) << 1);
1660
1661 write_rtc_register(0, current_output_byte);
1662
1663 }
1664 else
1665 {
1666 rtc_bit_count++;
1667
1668 if(rtc_bit_count == (rtc_data_bytes * 8))
1669 {
1670 rtc_state = RTC_IDLE;
1671 memset(rtc_registers, 0, sizeof(rtc_registers));
1672 }
1673 }
1674 }
1675 break;
1676 }
1677 }
1678 }
1679 else
1680 {
1681 write_rtc_register(2, value);
1682 }
1683 break;
1684
1685 // Write parameter A
1686 case 0xC6:
1687 write_rtc_register(1, value);
1688 break;
1689
1690 // Write parameter B
1691 case 0xC8:
1692 write_rtc_register(2, value);
1693 break;
1694 }
1695}
1696
1697#define write_rtc8() \
1698
1699#define write_rtc16() \
1700 write_rtc(address & 0xFF, value) \
1701
1702#define write_rtc32() \
1703
1704#define write_memory(type) \
1705 switch(address >> 24) \
1706 { \
1707 case 0x02: \
1708 /* external work RAM */ \
1709 address = (address & 0x7FFF) + ((address & 0x38000) * 2) + 0x8000; \
1710 address##type(ewram, address) = value; \
1711 break; \
1712 \
1713 case 0x03: \
1714 /* internal work RAM */ \
1715 address##type(iwram, (address & 0x7FFF) + 0x8000) = value; \
1716 break; \
1717 \
1718 case 0x04: \
1719 /* I/O registers */ \
1720 return write_io_register##type(address & 0x3FF, value); \
1721 \
1722 case 0x05: \
1723 /* palette RAM */ \
1724 write_palette##type(address & 0x3FF, value); \
1725 break; \
1726 \
1727 case 0x06: \
1728 /* VRAM */ \
1729 address &= 0x1FFFF; \
1730 if(address >= 0x18000) \
1731 address -= 0x8000; \
1732 \
1733 write_vram##type(); \
1734 break; \
1735 \
1736 case 0x07: \
1737 /* OAM RAM */ \
1738 oam_update = 1; \
1739 address##type(oam_ram, address & 0x3FF) = value; \
1740 break; \
1741 \
1742 case 0x08: \
1743 /* gamepak ROM or RTC */ \
1744 write_rtc##type(); \
1745 break; \
1746 \
1747 case 0x09 ... 0x0C: \
1748 /* gamepak ROM space */ \
1749 break; \
1750 \
1751 case 0x0D: \
1752 write_eeprom(address, value); \
1753 break; \
1754 \
1755 case 0x0E: \
1756 write_backup##type(); \
1757 break; \
1758 } \
1759
1760u8 function_cc read_memory8(u32 address)
1761{
1762 u8 value;
1763 read_memory(8);
1764 return value;
1765}
1766
1767u16 function_cc read_memory16_signed(u32 address)
1768{
1769 u16 value;
1770
1771 if(address & 0x01)
1772 {
1773 return (s8)read_memory8(address);
1774 }
1775 else
1776 {
1777 read_memory(16);
1778 }
1779
1780 return value;
1781}
1782
1783// unaligned reads are actually 32bit
1784
1785u32 function_cc read_memory16(u32 address)
1786{
1787 u32 value;
1788
1789 if(address & 0x01)
1790 {
1791 address &= ~0x01;
1792 read_memory(16);
1793 ror(value, value, 8);
1794 }
1795 else
1796 {
1797 read_memory(16);
1798 }
1799
1800 return value;
1801}
1802
1803
1804u32 function_cc read_memory32(u32 address)
1805{
1806 u32 value;
1807 if(address & 0x03)
1808 {
1809 u32 rotate = (address & 0x03) * 8;
1810 address &= ~0x03;
1811 read_memory(32);
1812 ror(value, value, rotate);
1813 }
1814 else
1815 {
1816 read_memory(32);
1817 }
1818
1819 return value;
1820}
1821
1822cpu_alert_type function_cc write_memory8(u32 address, u8 value)
1823{
1824 write_memory(8);
1825 return CPU_ALERT_NONE;
1826}
1827
1828cpu_alert_type function_cc write_memory16(u32 address, u16 value)
1829{
1830 write_memory(16);
1831 return CPU_ALERT_NONE;
1832}
1833
1834cpu_alert_type function_cc write_memory32(u32 address, u32 value)
1835{
1836 write_memory(32);
1837 return CPU_ALERT_NONE;
1838}
1839
1840char backup_filename[512];
1841
1842u32 load_backup(char *name)
1843{
1844 file_open(backup_file, name, read);
1845
1846 if(file_check_valid(backup_file))
1847 {
1848 u32 backup_size = file_length(name, backup_file);
1849
1850 file_read(backup_file, gamepak_backup, backup_size);
1851
1852 file_close(backup_file);
1853
1854 // The size might give away what kind of backup it is.
1855 switch(backup_size)
1856 {
1857 case 0x200:
1858 backup_type = BACKUP_EEPROM;
1859 eeprom_size = EEPROM_512_BYTE;
1860 break;
1861
1862 case 0x2000:
1863 backup_type = BACKUP_EEPROM;
1864 eeprom_size = EEPROM_8_KBYTE;
1865 break;
1866
1867 case 0x8000:
1868 backup_type = BACKUP_SRAM;
1869 sram_size = SRAM_SIZE_32KB;
1870 break;
1871
1872 // Could be either flash or SRAM, go with flash
1873 case 0x10000:
1874 backup_type = BACKUP_FLASH;
1875 sram_size = FLASH_SIZE_64KB;
1876 break;
1877
1878 case 0x20000:
1879 backup_type = BACKUP_FLASH;
1880 flash_size = FLASH_SIZE_128KB;
1881 break;
1882 }
1883 return 1;
1884 }
1885 else
1886 {
1887 backup_type = BACKUP_NONE;
1888 memset(gamepak_backup, 0xFF, 1024 * 128);
1889 }
1890
1891 return 0;
1892}
1893
1894u32 save_backup(char *name)
1895{
1896 if(backup_type != BACKUP_NONE)
1897 {
1898 file_open(backup_file, name, write);
1899
1900 if(file_check_valid(backup_file))
1901 {
1902 u32 backup_size;
1903
1904 switch(backup_type)
1905 {
1906 case BACKUP_SRAM:
1907 if(sram_size == SRAM_SIZE_32KB)
1908 backup_size = 0x8000;
1909 else
1910 backup_size = 0x10000;
1911 break;
1912
1913 case BACKUP_FLASH:
1914 if(flash_size == FLASH_SIZE_64KB)
1915 backup_size = 0x10000;
1916 else
1917 backup_size = 0x20000;
1918 break;
1919
1920 case BACKUP_EEPROM:
1921 if(eeprom_size == EEPROM_512_BYTE)
1922 backup_size = 0x200;
1923 else
1924 backup_size = 0x2000;
1925 break;
1926 }
1927
1928 file_write(backup_file, gamepak_backup, backup_size);
1929
1930 file_close(backup_file);
1931 return 1;
1932 }
1933 }
1934
1935 return 0;
1936}
1937
1938void update_backup()
1939{
1940 if(backup_update != (write_backup_delay + 1))
1941 backup_update--;
1942
1943 if(backup_update == 0)
1944 {
1945 save_backup(backup_filename);
1946 backup_update = write_backup_delay + 1;
1947 }
1948}
1949
1950void update_backup_force()
1951{
1952 save_backup(backup_filename);
1953}
1954
1955#define CONFIG_FILENAME "game_config.txt"
1956
1957u8 *skip_spaces(u8 *line_ptr)
1958{
1959 while(*line_ptr == ' ')
1960 line_ptr++;
1961
1962 return line_ptr;
1963}
1964
1965s32 parse_config_line(u8 *current_line, u8 *current_variable, u8 *current_value)
1966{
1967 u8 *line_ptr = current_line;
1968 u8 *line_ptr_new;
1969
1970 if((current_line[0] == 0) || (current_line[0] == '#'))
1971 return -1;
1972
1973 line_ptr_new = strchr(line_ptr, ' ');
1974 if(line_ptr_new == NULL)
1975 return -1;
1976
1977 *line_ptr_new = 0;
1978 strcpy(current_variable, line_ptr);
1979 line_ptr_new = skip_spaces(line_ptr_new + 1);
1980
1981 if(*line_ptr_new != '=')
1982 return -1;
1983
1984 line_ptr_new = skip_spaces(line_ptr_new + 1);
1985 strcpy(current_value, line_ptr_new);
1986 line_ptr_new = current_value + strlen(current_value) - 1;
1987 if(*line_ptr_new == '\n')
1988 {
1989 line_ptr_new--;
1990 *line_ptr_new = 0;
1991 }
1992
1993 if(*line_ptr_new == '\r')
1994 *line_ptr_new = 0;
1995
1996 return 0;
1997}
1998
1999s32 load_game_config(u8 *gamepak_title, u8 *gamepak_code, u8 *gamepak_maker)
2000{
2001 u8 current_line[256];
2002 u8 current_variable[256];
2003 u8 current_value[256];
2004 u8 config_path[512];
2005 u8 *line_ptr;
2006 u32 fgets_value;
2007 FILE *config_file;
2008
2009 idle_loop_target_pc = 0xFFFFFFFF;
2010 iwram_stack_optimize = 1;
2011 bios_rom[0x39] = 0x00;
2012 bios_rom[0x2C] = 0x00;
2013 translation_gate_targets = 0;
2014 flash_device_id = FLASH_DEVICE_MACRONIX_64KB;
2015
2016#if (defined(PSP_BUILD) || defined(ARM_ARCH)) && !defined(_WIN32_WCE)
2017 sprintf(config_path, "%s/%s", main_path, CONFIG_FILENAME);
2018#else
2019 sprintf(config_path, "%s\\%s", main_path, CONFIG_FILENAME);
2020#endif
2021
2022 config_file = fopen(config_path, "rb");
2023
2024 if(config_file)
2025 {
2026 while(fgets(current_line, 256, config_file))
2027 {
2028 if(parse_config_line(current_line, current_variable, current_value)
2029 != -1)
2030 {
2031 if(strcmp(current_variable, "game_name") ||
2032 strcmp(current_value, gamepak_title))
2033 continue;
2034
2035 if(!fgets(current_line, 256, config_file) ||
2036 (parse_config_line(current_line, current_variable,
2037 current_value) == -1) ||
2038 strcmp(current_variable, "game_code") ||
2039 strcmp(current_value, gamepak_code))
2040 continue;
2041
2042 if(!fgets(current_line, 256, config_file) ||
2043 (parse_config_line(current_line, current_variable,
2044 current_value) == -1) ||
2045 strcmp(current_variable, "vender_code") ||
2046 strcmp(current_value, gamepak_maker))
2047 continue;
2048
2049 while(fgets(current_line, 256, config_file))
2050 {
2051 if(parse_config_line(current_line, current_variable, current_value)
2052 != -1)
2053 {
2054 if(!strcmp(current_variable, "game_name"))
2055 {
2056 fclose(config_file);
2057 return 0;
2058 }
2059
2060 if(!strcmp(current_variable, "idle_loop_eliminate_target"))
2061 idle_loop_target_pc = strtol(current_value, NULL, 16);
2062
2063 if(!strcmp(current_variable, "translation_gate_target"))
2064 {
2065 if(translation_gate_targets < MAX_TRANSLATION_GATES)
2066 {
2067 translation_gate_target_pc[translation_gate_targets] =
2068 strtol(current_value, NULL, 16);
2069 translation_gate_targets++;
2070 }
2071 }
2072
2073 if(!strcmp(current_variable, "iwram_stack_optimize") &&
2074 !strcmp(current_value, "no"))
2075 {
2076 iwram_stack_optimize = 0;
2077 }
2078
2079 if(!strcmp(current_variable, "flash_rom_type") &&
2080 !strcmp(current_value, "128KB"))
2081 {
2082 flash_device_id = FLASH_DEVICE_MACRONIX_128KB;
2083 }
2084
2085 if(!strcmp(current_variable, "bios_rom_hack_39") &&
2086 !strcmp(current_value, "yes"))
2087 {
2088 bios_rom[0x39] = 0xC0;
2089 }
2090
2091 if(!strcmp(current_variable, "bios_rom_hack_2C") &&
2092 !strcmp(current_value, "yes"))
2093 {
2094 bios_rom[0x2C] = 0x02;
2095 }
2096 }
2097 }
2098
2099 fclose(config_file);
2100 return 0;
2101 }
2102 }
2103
2104 fclose(config_file);
2105 }
2106
2107 return -1;
2108}
2109
2110s32 load_gamepak_raw(char *name)
2111{
2112 file_open(gamepak_file, name, read);
2113
2114 if(file_check_valid(gamepak_file))
2115 {
2116 u32 file_size = file_length(name, gamepak_file);
2117
2118 // First, close the last one if it was open, we won't
2119 // be needing it anymore.
2120 if(file_check_valid(gamepak_file_large))
2121 file_close(gamepak_file_large);
2122
2123 // If it's a big file size keep it, don't close it, we'll
2124 // probably want to load from it more later.
2125 if(file_size <= gamepak_ram_buffer_size)
2126 {
2127 file_read(gamepak_file, gamepak_rom, file_size);
2128
2129 file_close(gamepak_file);
2130
2131#ifdef PSP_BUILD
2132 gamepak_file_large = -1;
2133#else
2134 gamepak_file_large = NULL;
2135#endif
2136 }
2137 else
2138 {
2139 // Read in just enough for the header
2140 file_read(gamepak_file, gamepak_rom, 0x100);
2141 gamepak_file_large = gamepak_file;
2142 }
2143
2144 return file_size;
2145 }
2146
2147 return -1;
2148}
2149
2150u8 gamepak_title[13];
2151u8 gamepak_code[5];
2152u8 gamepak_maker[3];
2153u8 gamepak_filename[512];
2154
2155u32 load_gamepak(char *name)
2156{
2157 char *dot_position = strrchr(name, '.');
2158 s32 file_size;
2159 u8 cheats_filename[256];
2160
2161 if(!strcmp(dot_position, ".zip"))
2162 file_size = load_file_zip(name);
2163 else
2164 file_size = load_gamepak_raw(name);
2165
2166 // A dumb April fool's joke was here once :o
2167
2168 if(file_size != -1)
2169 {
2170 gamepak_size = (file_size + 0x7FFF) & ~0x7FFF;
2171
2172 strcpy(backup_filename, name);
2173 strncpy(gamepak_filename, name, 512);
2174 change_ext(gamepak_filename, backup_filename, ".sav");
2175
2176 load_backup(backup_filename);
2177
2178 memcpy(gamepak_title, gamepak_rom + 0xA0, 12);
2179 memcpy(gamepak_code, gamepak_rom + 0xAC, 4);
2180 memcpy(gamepak_maker, gamepak_rom + 0xB0, 2);
2181 gamepak_title[12] = 0;
2182 gamepak_code[4] = 0;
2183 gamepak_maker[2] = 0;
2184
2185 load_game_config(gamepak_title, gamepak_code, gamepak_maker);
2186 load_game_config_file();
2187
2188 change_ext(gamepak_filename, cheats_filename, ".cht");
2189 add_cheats(cheats_filename);
2190
2191 return 0;
2192 }
2193
2194 return -1;
2195}
2196
2197s32 load_bios(char *name)
2198{
2199 file_open(bios_file, name, read);
2200
2201 if(file_check_valid(bios_file))
2202 {
2203 file_read(bios_file, bios_rom, 0x4000);
2204
2205 // This is a hack to get Zelda working, because emulating
2206 // the proper memory read behavior here is much too expensive.
2207 file_close(bios_file);
2208 return 0;
2209 }
2210
2211 return -1;
2212}
2213
2214// DMA memory regions can be one of the following:
2215// IWRAM - 32kb offset from the contiguous iwram region.
2216// EWRAM - like segmented but with self modifying code check.
2217// VRAM - 96kb offset from the contiguous vram region, should take care
2218// Palette RAM - Converts palette entries when written to.
2219// OAM RAM - Sets OAM modified flag to true.
2220// I/O registers - Uses the I/O register function.
2221// of mirroring properly.
2222// Segmented RAM/ROM - a region >= 32kb, the translated address has to
2223// be reloaded if it wraps around the limit (cartride ROM)
2224// Ext - should be handled by the memory read/write function.
2225
2226// The following map determines the region of each (assumes DMA access
2227// is not done out of bounds)
2228
2229typedef enum
2230{
2231 DMA_REGION_IWRAM,
2232 DMA_REGION_EWRAM,
2233 DMA_REGION_VRAM,
2234 DMA_REGION_PALETTE_RAM,
2235 DMA_REGION_OAM_RAM,
2236 DMA_REGION_IO,
2237 DMA_REGION_GAMEPAK,
2238 DMA_REGION_EXT,
2239 DMA_REGION_BIOS,
2240 DMA_REGION_NULL
2241} dma_region_type;
2242
2243dma_region_type dma_region_map[16] =
2244{
2245 DMA_REGION_BIOS, // 0x00 - BIOS
2246 DMA_REGION_NULL, // 0x01 - Nothing
2247 DMA_REGION_EWRAM, // 0x02 - EWRAM
2248 DMA_REGION_IWRAM, // 0x03 - IWRAM
2249 DMA_REGION_IO, // 0x04 - I/O registers
2250 DMA_REGION_PALETTE_RAM, // 0x05 - palette RAM
2251 DMA_REGION_VRAM, // 0x06 - VRAM
2252 DMA_REGION_OAM_RAM, // 0x07 - OAM RAM
2253 DMA_REGION_GAMEPAK, // 0x08 - gamepak ROM
2254 DMA_REGION_GAMEPAK, // 0x09 - gamepak ROM
2255 DMA_REGION_GAMEPAK, // 0x0A - gamepak ROM
2256 DMA_REGION_GAMEPAK, // 0x0B - gamepak ROM
2257 DMA_REGION_GAMEPAK, // 0x0C - gamepak ROM
2258 DMA_REGION_EXT, // 0x0D - EEPROM
2259 DMA_REGION_EXT, // 0x0E - gamepak SRAM/flash ROM
2260 DMA_REGION_EXT // 0x0F - gamepak SRAM/flash ROM
2261};
2262
2263#define dma_adjust_ptr_inc(ptr, size) \
2264 ptr += (size / 8) \
2265
2266#define dma_adjust_ptr_dec(ptr, size) \
2267 ptr -= (size / 8) \
2268
2269#define dma_adjust_ptr_fix(ptr, size) \
2270
2271#define dma_adjust_ptr_writeback() \
2272 dma->dest_address = dest_ptr \
2273
2274#define dma_adjust_ptr_reload() \
2275
2276#define dma_print(src_op, dest_op, transfer_size, wb) \
2277 printf("dma from %x (%s) to %x (%s) for %x (%s) (%s) (%d) (pc %x)\n", \
2278 src_ptr, #src_op, dest_ptr, #dest_op, length, #transfer_size, #wb, \
2279 dma->irq, reg[15]); \
2280
2281#define dma_smc_vars_src() \
2282
2283#define dma_smc_vars_dest() \
2284 u32 smc_trigger = 0 \
2285
2286#define dma_vars_iwram(type) \
2287 dma_smc_vars_##type() \
2288
2289#define dma_vars_vram(type) \
2290
2291#define dma_vars_palette_ram(type) \
2292
2293#define dma_oam_ram_src() \
2294
2295#define dma_oam_ram_dest() \
2296 oam_update = 1 \
2297
2298#define dma_vars_oam_ram(type) \
2299 dma_oam_ram_##type() \
2300
2301#define dma_vars_io(type) \
2302
2303#define dma_segmented_load_src() \
2304 memory_map_read[src_current_region] \
2305
2306#define dma_segmented_load_dest() \
2307 memory_map_write[dest_current_region] \
2308
2309#define dma_vars_gamepak(type) \
2310 u32 type##_new_region; \
2311 u32 type##_current_region = type##_ptr >> 15; \
2312 u8 *type##_address_block = dma_segmented_load_##type(); \
2313 if(type##_address_block == NULL) \
2314 { \
2315 if((type##_ptr & 0x1FFFFFF) >= gamepak_size) \
2316 break; \
2317 type##_address_block = load_gamepak_page(type##_current_region & 0x3FF); \
2318 } \
2319
2320#define dma_vars_ewram(type) \
2321 dma_smc_vars_##type(); \
2322 u32 type##_new_region; \
2323 u32 type##_current_region = type##_ptr >> 15; \
2324 u8 *type##_address_block = dma_segmented_load_##type() \
2325
2326#define dma_vars_bios(type) \
2327
2328#define dma_vars_ext(type) \
2329
2330#define dma_ewram_check_region(type) \
2331 type##_new_region = (type##_ptr >> 15); \
2332 if(type##_new_region != type##_current_region) \
2333 { \
2334 type##_current_region = type##_new_region; \
2335 type##_address_block = dma_segmented_load_##type(); \
2336 } \
2337
2338#define dma_gamepak_check_region(type) \
2339 type##_new_region = (type##_ptr >> 15); \
2340 if(type##_new_region != type##_current_region) \
2341 { \
2342 type##_current_region = type##_new_region; \
2343 type##_address_block = dma_segmented_load_##type(); \
2344 if(type##_address_block == NULL) \
2345 { \
2346 type##_address_block = \
2347 load_gamepak_page(type##_current_region & 0x3FF); \
2348 } \
2349 } \
2350
2351#define dma_read_iwram(type, transfer_size) \
2352 read_value = address##transfer_size(iwram + 0x8000, type##_ptr & 0x7FFF) \
2353
2354#define dma_read_vram(type, transfer_size) \
2355 read_value = address##transfer_size(vram, type##_ptr & 0x1FFFF) \
2356
2357#define dma_read_io(type, transfer_size) \
2358 read_value = address##transfer_size(io_registers, type##_ptr & 0x7FFF) \
2359
2360#define dma_read_oam_ram(type, transfer_size) \
2361 read_value = address##transfer_size(oam_ram, type##_ptr & 0x3FF) \
2362
2363#define dma_read_palette_ram(type, transfer_size) \
2364 read_value = address##transfer_size(palette_ram, type##_ptr & 0x3FF) \
2365
2366#define dma_read_ewram(type, transfer_size) \
2367 dma_ewram_check_region(type); \
2368 read_value = address##transfer_size(type##_address_block, \
2369 type##_ptr & 0x7FFF) \
2370
2371#define dma_read_gamepak(type, transfer_size) \
2372 dma_gamepak_check_region(type); \
2373 read_value = address##transfer_size(type##_address_block, \
2374 type##_ptr & 0x7FFF) \
2375
2376// DMAing from the BIOS is funny, just returns 0..
2377
2378#define dma_read_bios(type, transfer_size) \
2379 read_value = 0 \
2380
2381#define dma_read_ext(type, transfer_size) \
2382 read_value = read_memory##transfer_size(type##_ptr) \
2383
2384#define dma_write_iwram(type, transfer_size) \
2385 address##transfer_size(iwram + 0x8000, type##_ptr & 0x7FFF) = read_value; \
2386 smc_trigger |= address##transfer_size(iwram, type##_ptr & 0x7FFF) \
2387
2388#define dma_write_vram(type, transfer_size) \
2389 address##transfer_size(vram, type##_ptr & 0x1FFFF) = read_value \
2390
2391#define dma_write_io(type, transfer_size) \
2392 write_io_register##transfer_size(type##_ptr & 0x3FF, read_value) \
2393
2394#define dma_write_oam_ram(type, transfer_size) \
2395 address##transfer_size(oam_ram, type##_ptr & 0x3FF) = read_value \
2396
2397#define dma_write_palette_ram(type, transfer_size) \
2398 write_palette##transfer_size(type##_ptr & 0x3FF, read_value) \
2399
2400#define dma_write_ext(type, transfer_size) \
2401 write_memory##transfer_size(type##_ptr, read_value) \
2402
2403#define dma_write_ewram(type, transfer_size) \
2404 dma_ewram_check_region(type); \
2405 \
2406 address##transfer_size(type##_address_block, type##_ptr & 0x7FFF) = \
2407 read_value; \
2408 smc_trigger |= address##transfer_size(type##_address_block, \
2409 (type##_ptr & 0x7FFF) - 0x8000) \
2410
2411#define dma_epilogue_iwram() \
2412 if(smc_trigger) \
2413 { \
2414 /* Special return code indicating to retranslate to the CPU code */ \
2415 return_value = CPU_ALERT_SMC; \
2416 } \
2417
2418#define dma_epilogue_ewram() \
2419 if(smc_trigger) \
2420 { \
2421 /* Special return code indicating to retranslate to the CPU code */ \
2422 return_value = CPU_ALERT_SMC; \
2423 } \
2424
2425#define dma_epilogue_vram() \
2426
2427#define dma_epilogue_io() \
2428
2429#define dma_epilogue_oam_ram() \
2430
2431#define dma_epilogue_palette_ram() \
2432
2433#define dma_epilogue_GAMEPAK() \
2434
2435#define dma_epilogue_ext() \
2436
2437#define print_line() \
2438 dma_print(src_op, dest_op, transfer_size, wb); \
2439
2440#define dma_transfer_loop_region(src_region_type, dest_region_type, src_op, \
2441 dest_op, transfer_size, wb) \
2442{ \
2443 dma_vars_##src_region_type(src); \
2444 dma_vars_##dest_region_type(dest); \
2445 \
2446 for(i = 0; i < length; i++) \
2447 { \
2448 dma_read_##src_region_type(src, transfer_size); \
2449 dma_write_##dest_region_type(dest, transfer_size); \
2450 dma_adjust_ptr_##src_op(src_ptr, transfer_size); \
2451 dma_adjust_ptr_##dest_op(dest_ptr, transfer_size); \
2452 } \
2453 dma->source_address = src_ptr; \
2454 dma_adjust_ptr_##wb(); \
2455 dma_epilogue_##dest_region_type(); \
2456 break; \
2457} \
2458
2459#define dma_transfer_loop(src_op, dest_op, transfer_size, wb); \
2460{ \
2461 u32 src_region = src_ptr >> 24; \
2462 u32 dest_region = dest_ptr >> 24; \
2463 dma_region_type src_region_type = dma_region_map[src_region]; \
2464 dma_region_type dest_region_type = dma_region_map[dest_region]; \
2465 \
2466 switch(src_region_type | (dest_region_type << 4)) \
2467 { \
2468 case (DMA_REGION_BIOS | (DMA_REGION_IWRAM << 4)): \
2469 dma_transfer_loop_region(bios, iwram, src_op, dest_op, \
2470 transfer_size, wb); \
2471 \
2472 case (DMA_REGION_IWRAM | (DMA_REGION_IWRAM << 4)): \
2473 dma_transfer_loop_region(iwram, iwram, src_op, dest_op, \
2474 transfer_size, wb); \
2475 \
2476 case (DMA_REGION_EWRAM | (DMA_REGION_IWRAM << 4)): \
2477 dma_transfer_loop_region(ewram, iwram, src_op, dest_op, \
2478 transfer_size, wb); \
2479 \
2480 case (DMA_REGION_VRAM | (DMA_REGION_IWRAM << 4)): \
2481 dma_transfer_loop_region(vram, iwram, src_op, dest_op, \
2482 transfer_size, wb); \
2483 \
2484 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_IWRAM << 4)): \
2485 dma_transfer_loop_region(palette_ram, iwram, src_op, dest_op, \
2486 transfer_size, wb); \
2487 \
2488 case (DMA_REGION_OAM_RAM | (DMA_REGION_IWRAM << 4)): \
2489 dma_transfer_loop_region(oam_ram, iwram, src_op, dest_op, \
2490 transfer_size, wb); \
2491 \
2492 case (DMA_REGION_IO | (DMA_REGION_IWRAM << 4)): \
2493 dma_transfer_loop_region(io, iwram, src_op, dest_op, \
2494 transfer_size, wb); \
2495 \
2496 case (DMA_REGION_GAMEPAK | (DMA_REGION_IWRAM << 4)): \
2497 dma_transfer_loop_region(gamepak, iwram, src_op, dest_op, \
2498 transfer_size, wb); \
2499 \
2500 case (DMA_REGION_EXT | (DMA_REGION_IWRAM << 4)): \
2501 dma_transfer_loop_region(ext, iwram, src_op, dest_op, \
2502 transfer_size, wb); \
2503 \
2504 case (DMA_REGION_BIOS | (DMA_REGION_EWRAM << 4)): \
2505 dma_transfer_loop_region(bios, ewram, src_op, dest_op, \
2506 transfer_size, wb); \
2507 \
2508 case (DMA_REGION_IWRAM | (DMA_REGION_EWRAM << 4)): \
2509 dma_transfer_loop_region(iwram, ewram, src_op, dest_op, \
2510 transfer_size, wb); \
2511 \
2512 case (DMA_REGION_EWRAM | (DMA_REGION_EWRAM << 4)): \
2513 dma_transfer_loop_region(ewram, ewram, src_op, dest_op, \
2514 transfer_size, wb); \
2515 \
2516 case (DMA_REGION_VRAM | (DMA_REGION_EWRAM << 4)): \
2517 dma_transfer_loop_region(vram, ewram, src_op, dest_op, \
2518 transfer_size, wb); \
2519 \
2520 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_EWRAM << 4)): \
2521 dma_transfer_loop_region(palette_ram, ewram, src_op, dest_op, \
2522 transfer_size, wb); \
2523 \
2524 case (DMA_REGION_OAM_RAM | (DMA_REGION_EWRAM << 4)): \
2525 dma_transfer_loop_region(oam_ram, ewram, src_op, dest_op, \
2526 transfer_size, wb); \
2527 \
2528 case (DMA_REGION_IO | (DMA_REGION_EWRAM << 4)): \
2529 dma_transfer_loop_region(io, ewram, src_op, dest_op, \
2530 transfer_size, wb); \
2531 \
2532 case (DMA_REGION_GAMEPAK | (DMA_REGION_EWRAM << 4)): \
2533 dma_transfer_loop_region(gamepak, ewram, src_op, dest_op, \
2534 transfer_size, wb); \
2535 \
2536 case (DMA_REGION_EXT | (DMA_REGION_EWRAM << 4)): \
2537 dma_transfer_loop_region(ext, ewram, src_op, dest_op, \
2538 transfer_size, wb); \
2539 \
2540 case (DMA_REGION_BIOS | (DMA_REGION_VRAM << 4)): \
2541 dma_transfer_loop_region(bios, vram, src_op, dest_op, \
2542 transfer_size, wb); \
2543 \
2544 case (DMA_REGION_IWRAM | (DMA_REGION_VRAM << 4)): \
2545 dma_transfer_loop_region(iwram, vram, src_op, dest_op, \
2546 transfer_size, wb); \
2547 \
2548 case (DMA_REGION_EWRAM | (DMA_REGION_VRAM << 4)): \
2549 dma_transfer_loop_region(ewram, vram, src_op, dest_op, \
2550 transfer_size, wb); \
2551 \
2552 case (DMA_REGION_VRAM | (DMA_REGION_VRAM << 4)): \
2553 dma_transfer_loop_region(vram, vram, src_op, dest_op, \
2554 transfer_size, wb); \
2555 \
2556 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_VRAM << 4)): \
2557 dma_transfer_loop_region(palette_ram, vram, src_op, dest_op, \
2558 transfer_size, wb); \
2559 \
2560 case (DMA_REGION_OAM_RAM | (DMA_REGION_VRAM << 4)): \
2561 dma_transfer_loop_region(oam_ram, vram, src_op, dest_op, \
2562 transfer_size, wb); \
2563 \
2564 case (DMA_REGION_IO | (DMA_REGION_VRAM << 4)): \
2565 dma_transfer_loop_region(io, vram, src_op, dest_op, \
2566 transfer_size, wb); \
2567 \
2568 case (DMA_REGION_GAMEPAK | (DMA_REGION_VRAM << 4)): \
2569 dma_transfer_loop_region(gamepak, vram, src_op, dest_op, \
2570 transfer_size, wb); \
2571 \
2572 case (DMA_REGION_EXT | (DMA_REGION_VRAM << 4)): \
2573 dma_transfer_loop_region(ext, vram, src_op, dest_op, \
2574 transfer_size, wb); \
2575 \
2576 case (DMA_REGION_BIOS | (DMA_REGION_PALETTE_RAM << 4)): \
2577 dma_transfer_loop_region(bios, palette_ram, src_op, dest_op, \
2578 transfer_size, wb); \
2579 \
2580 case (DMA_REGION_IWRAM | (DMA_REGION_PALETTE_RAM << 4)): \
2581 dma_transfer_loop_region(iwram, palette_ram, src_op, dest_op, \
2582 transfer_size, wb); \
2583 \
2584 case (DMA_REGION_EWRAM | (DMA_REGION_PALETTE_RAM << 4)): \
2585 dma_transfer_loop_region(ewram, palette_ram, src_op, dest_op, \
2586 transfer_size, wb); \
2587 \
2588 case (DMA_REGION_VRAM | (DMA_REGION_PALETTE_RAM << 4)): \
2589 dma_transfer_loop_region(vram, palette_ram, src_op, dest_op, \
2590 transfer_size, wb); \
2591 \
2592 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_PALETTE_RAM << 4)): \
2593 dma_transfer_loop_region(palette_ram, palette_ram, src_op, dest_op, \
2594 transfer_size, wb); \
2595 \
2596 case (DMA_REGION_OAM_RAM | (DMA_REGION_PALETTE_RAM << 4)): \
2597 dma_transfer_loop_region(oam_ram, palette_ram, src_op, dest_op, \
2598 transfer_size, wb); \
2599 \
2600 case (DMA_REGION_IO | (DMA_REGION_PALETTE_RAM << 4)): \
2601 dma_transfer_loop_region(io, palette_ram, src_op, dest_op, \
2602 transfer_size, wb); \
2603 \
2604 case (DMA_REGION_GAMEPAK | (DMA_REGION_PALETTE_RAM << 4)): \
2605 dma_transfer_loop_region(gamepak, palette_ram, src_op, dest_op, \
2606 transfer_size, wb); \
2607 \
2608 case (DMA_REGION_EXT | (DMA_REGION_PALETTE_RAM << 4)): \
2609 dma_transfer_loop_region(ext, palette_ram, src_op, dest_op, \
2610 transfer_size, wb); \
2611 \
2612 case (DMA_REGION_BIOS | (DMA_REGION_OAM_RAM << 4)): \
2613 dma_transfer_loop_region(bios, oam_ram, src_op, dest_op, \
2614 transfer_size, wb); \
2615 \
2616 case (DMA_REGION_IWRAM | (DMA_REGION_OAM_RAM << 4)): \
2617 dma_transfer_loop_region(iwram, oam_ram, src_op, dest_op, \
2618 transfer_size, wb); \
2619 \
2620 case (DMA_REGION_EWRAM | (DMA_REGION_OAM_RAM << 4)): \
2621 dma_transfer_loop_region(ewram, oam_ram, src_op, dest_op, \
2622 transfer_size, wb); \
2623 \
2624 case (DMA_REGION_VRAM | (DMA_REGION_OAM_RAM << 4)): \
2625 dma_transfer_loop_region(vram, oam_ram, src_op, dest_op, \
2626 transfer_size, wb); \
2627 \
2628 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_OAM_RAM << 4)): \
2629 dma_transfer_loop_region(palette_ram, oam_ram, src_op, dest_op, \
2630 transfer_size, wb); \
2631 \
2632 case (DMA_REGION_OAM_RAM | (DMA_REGION_OAM_RAM << 4)): \
2633 dma_transfer_loop_region(oam_ram, oam_ram, src_op, dest_op, \
2634 transfer_size, wb); \
2635 \
2636 case (DMA_REGION_IO | (DMA_REGION_OAM_RAM << 4)): \
2637 dma_transfer_loop_region(io, oam_ram, src_op, dest_op, \
2638 transfer_size, wb); \
2639 \
2640 case (DMA_REGION_GAMEPAK | (DMA_REGION_OAM_RAM << 4)): \
2641 dma_transfer_loop_region(gamepak, oam_ram, src_op, dest_op, \
2642 transfer_size, wb); \
2643 \
2644 case (DMA_REGION_EXT | (DMA_REGION_OAM_RAM << 4)): \
2645 dma_transfer_loop_region(ext, oam_ram, src_op, dest_op, \
2646 transfer_size, wb); \
2647 \
2648 case (DMA_REGION_BIOS | (DMA_REGION_IO << 4)): \
2649 dma_transfer_loop_region(bios, io, src_op, dest_op, \
2650 transfer_size, wb); \
2651 \
2652 case (DMA_REGION_IWRAM | (DMA_REGION_IO << 4)): \
2653 dma_transfer_loop_region(iwram, io, src_op, dest_op, \
2654 transfer_size, wb); \
2655 \
2656 case (DMA_REGION_EWRAM | (DMA_REGION_IO << 4)): \
2657 dma_transfer_loop_region(ewram, io, src_op, dest_op, \
2658 transfer_size, wb); \
2659 \
2660 case (DMA_REGION_VRAM | (DMA_REGION_IO << 4)): \
2661 dma_transfer_loop_region(vram, io, src_op, dest_op, \
2662 transfer_size, wb); \
2663 \
2664 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_IO << 4)): \
2665 dma_transfer_loop_region(palette_ram, io, src_op, dest_op, \
2666 transfer_size, wb); \
2667 \
2668 case (DMA_REGION_OAM_RAM | (DMA_REGION_IO << 4)): \
2669 dma_transfer_loop_region(oam_ram, io, src_op, dest_op, \
2670 transfer_size, wb); \
2671 \
2672 case (DMA_REGION_IO | (DMA_REGION_IO << 4)): \
2673 dma_transfer_loop_region(io, io, src_op, dest_op, \
2674 transfer_size, wb); \
2675 \
2676 case (DMA_REGION_GAMEPAK | (DMA_REGION_IO << 4)): \
2677 dma_transfer_loop_region(gamepak, io, src_op, dest_op, \
2678 transfer_size, wb); \
2679 \
2680 case (DMA_REGION_EXT | (DMA_REGION_IO << 4)): \
2681 dma_transfer_loop_region(ext, io, src_op, dest_op, \
2682 transfer_size, wb); \
2683 \
2684 case (DMA_REGION_BIOS | (DMA_REGION_EXT << 4)): \
2685 dma_transfer_loop_region(bios, ext, src_op, dest_op, \
2686 transfer_size, wb); \
2687 \
2688 case (DMA_REGION_IWRAM | (DMA_REGION_EXT << 4)): \
2689 dma_transfer_loop_region(iwram, ext, src_op, dest_op, \
2690 transfer_size, wb); \
2691 \
2692 case (DMA_REGION_EWRAM | (DMA_REGION_EXT << 4)): \
2693 dma_transfer_loop_region(ewram, ext, src_op, dest_op, \
2694 transfer_size, wb); \
2695 \
2696 case (DMA_REGION_VRAM | (DMA_REGION_EXT << 4)): \
2697 dma_transfer_loop_region(vram, ext, src_op, dest_op, \
2698 transfer_size, wb); \
2699 \
2700 case (DMA_REGION_PALETTE_RAM | (DMA_REGION_EXT << 4)): \
2701 dma_transfer_loop_region(palette_ram, ext, src_op, dest_op, \
2702 transfer_size, wb); \
2703 \
2704 case (DMA_REGION_OAM_RAM | (DMA_REGION_EXT << 4)): \
2705 dma_transfer_loop_region(oam_ram, ext, src_op, dest_op, \
2706 transfer_size, wb); \
2707 \
2708 case (DMA_REGION_IO | (DMA_REGION_EXT << 4)): \
2709 dma_transfer_loop_region(io, ext, src_op, dest_op, \
2710 transfer_size, wb); \
2711 \
2712 case (DMA_REGION_GAMEPAK | (DMA_REGION_EXT << 4)): \
2713 dma_transfer_loop_region(gamepak, ext, src_op, dest_op, \
2714 transfer_size, wb); \
2715 \
2716 case (DMA_REGION_EXT | (DMA_REGION_EXT << 3)): \
2717 dma_transfer_loop_region(ext, ext, src_op, dest_op, \
2718 transfer_size, wb); \
2719 } \
2720 break; \
2721} \
2722
2723#define dma_transfer_expand(transfer_size) \
2724 switch((dma->dest_direction << 2) | dma->source_direction) \
2725 { \
2726 case 0x00: \
2727 dma_transfer_loop(inc, inc, transfer_size, writeback); \
2728 \
2729 case 0x01: \
2730 dma_transfer_loop(dec, inc, transfer_size, writeback); \
2731 \
2732 case 0x02: \
2733 dma_transfer_loop(fix, inc, transfer_size, writeback); \
2734 \
2735 case 0x03: \
2736 break; \
2737 \
2738 case 0x04: \
2739 dma_transfer_loop(inc, dec, transfer_size, writeback); \
2740 \
2741 case 0x05: \
2742 dma_transfer_loop(dec, dec, transfer_size, writeback); \
2743 \
2744 case 0x06: \
2745 dma_transfer_loop(fix, dec, transfer_size, writeback); \
2746 \
2747 case 0x07: \
2748 break; \
2749 \
2750 case 0x08: \
2751 dma_transfer_loop(inc, fix, transfer_size, writeback); \
2752 \
2753 case 0x09: \
2754 dma_transfer_loop(dec, fix, transfer_size, writeback); \
2755 \
2756 case 0x0A: \
2757 dma_transfer_loop(fix, fix, transfer_size, writeback); \
2758 \
2759 case 0x0B: \
2760 break; \
2761 \
2762 case 0x0C: \
2763 dma_transfer_loop(inc, inc, transfer_size, reload); \
2764 \
2765 case 0x0D: \
2766 dma_transfer_loop(dec, inc, transfer_size, reload); \
2767 \
2768 case 0x0E: \
2769 dma_transfer_loop(fix, inc, transfer_size, reload); \
2770 \
2771 case 0x0F: \
2772 break; \
2773 } \
2774
2775cpu_alert_type dma_transfer(dma_transfer_type *dma)
2776{
2777 u32 i;
2778 u32 length = dma->length;
2779 u32 read_value;
2780 u32 src_ptr = dma->source_address;
2781 u32 dest_ptr = dma->dest_address;
2782 cpu_alert_type return_value = CPU_ALERT_NONE;
2783
2784 // Technically this should be done for source and destination, but
2785 // chances are this is only ever used (probably mistakingly!) for dest.
2786 // The only game I know of that requires this is Lucky Luke.
2787 if((dest_ptr >> 24) != ((dest_ptr + length - 1) >> 24))
2788 {
2789 u32 first_length = ((dest_ptr & 0xFF000000) + 0x1000000) - dest_ptr;
2790 u32 second_length = length - first_length;
2791 dma->length = first_length;
2792
2793 dma_transfer(dma);
2794
2795 dma->length = length;
2796
2797 length = second_length;
2798 dest_ptr += first_length;
2799 src_ptr += first_length;
2800 }
2801
2802 if(dma->length_type == DMA_16BIT)
2803 {
2804 src_ptr &= ~0x01;
2805 dest_ptr &= ~0x01;
2806 cycle_dma16_words += length;
2807 dma_transfer_expand(16);
2808 }
2809 else
2810 {
2811 src_ptr &= ~0x03;
2812 dest_ptr &= ~0x03;
2813 cycle_dma32_words += length;
2814 dma_transfer_expand(32);
2815 }
2816
2817 if((dma->repeat_type == DMA_NO_REPEAT) ||
2818 (dma->start_type == DMA_START_IMMEDIATELY))
2819 {
2820 dma->start_type = DMA_INACTIVE;
2821 address16(io_registers, (dma->dma_channel * 12) + 0xBA) &=
2822 (~0x8000);
2823 }
2824
2825 if(dma->irq)
2826 {
2827 raise_interrupt(IRQ_DMA0 << dma->dma_channel);
2828 return_value = CPU_ALERT_IRQ;
2829 }
2830
2831 return return_value;
2832}
2833
2834// Be sure to do this after loading ROMs.
2835
2836#define map_region(type, start, end, mirror_blocks, region) \
2837 for(map_offset = (start) / 0x8000; map_offset < \
2838 ((end) / 0x8000); map_offset++) \
2839 { \
2840 memory_map_##type[map_offset] = \
2841 ((u8 *)region) + ((map_offset % mirror_blocks) * 0x8000); \
2842 } \
2843
2844#define map_null(type, start, end) \
2845 for(map_offset = start / 0x8000; map_offset < (end / 0x8000); \
2846 map_offset++) \
2847 { \
2848 memory_map_##type[map_offset] = NULL; \
2849 } \
2850
2851#define map_ram_region(type, start, end, mirror_blocks, region) \
2852 for(map_offset = (start) / 0x8000; map_offset < \
2853 ((end) / 0x8000); map_offset++) \
2854 { \
2855 memory_map_##type[map_offset] = \
2856 ((u8 *)region) + ((map_offset % mirror_blocks) * 0x10000) + 0x8000; \
2857 } \
2858
2859#define map_vram(type) \
2860 for(map_offset = 0x6000000 / 0x8000; map_offset < (0x7000000 / 0x8000); \
2861 map_offset += 4) \
2862 { \
2863 memory_map_##type[map_offset] = vram; \
2864 memory_map_##type[map_offset + 1] = vram + 0x8000; \
2865 memory_map_##type[map_offset + 2] = vram + (0x8000 * 2); \
2866 memory_map_##type[map_offset + 3] = vram + (0x8000 * 2); \
2867 } \
2868
2869#define map_vram_firstpage(type) \
2870 for(map_offset = 0x6000000 / 0x8000; map_offset < (0x7000000 / 0x8000); \
2871 map_offset += 4) \
2872 { \
2873 memory_map_##type[map_offset] = vram; \
2874 memory_map_##type[map_offset + 1] = NULL; \
2875 memory_map_##type[map_offset + 2] = NULL; \
2876 memory_map_##type[map_offset + 3] = NULL; \
2877 } \
2878
2879
2880// Picks a page to evict
2881u32 page_time = 0;
2882
2883u32 evict_gamepak_page()
2884{
2885 // Find the one with the smallest frame timestamp
2886 u32 page_index = 0;
2887 u32 physical_index;
2888 u32 smallest = gamepak_memory_map[0].page_timestamp;
2889 u32 i;
2890
2891 for(i = 1; i < gamepak_ram_pages; i++)
2892 {
2893 if(gamepak_memory_map[i].page_timestamp <= smallest)
2894 {
2895 smallest = gamepak_memory_map[i].page_timestamp;
2896 page_index = i;
2897 }
2898 }
2899
2900 physical_index = gamepak_memory_map[page_index].physical_index;
2901
2902 memory_map_read[(0x8000000 / (32 * 1024)) + physical_index] = NULL;
2903 memory_map_read[(0xA000000 / (32 * 1024)) + physical_index] = NULL;
2904 memory_map_read[(0xC000000 / (32 * 1024)) + physical_index] = NULL;
2905
2906 return page_index;
2907}
2908
2909u8 *load_gamepak_page(u32 physical_index)
2910{
2911 if(physical_index >= (gamepak_size >> 15))
2912 return gamepak_rom;
2913
2914 u32 page_index = evict_gamepak_page();
2915 u32 page_offset = page_index * (32 * 1024);
2916 u8 *swap_location = gamepak_rom + page_offset;
2917
2918 gamepak_memory_map[page_index].page_timestamp = page_time;
2919 gamepak_memory_map[page_index].physical_index = physical_index;
2920 page_time++;
2921
2922 file_seek(gamepak_file_large, physical_index * (32 * 1024), SEEK_SET);
2923 file_read(gamepak_file_large, swap_location, (32 * 1024));
2924 memory_map_read[(0x8000000 / (32 * 1024)) + physical_index] = swap_location;
2925 memory_map_read[(0xA000000 / (32 * 1024)) + physical_index] = swap_location;
2926 memory_map_read[(0xC000000 / (32 * 1024)) + physical_index] = swap_location;
2927
2928 // If RTC is active page the RTC register bytes so they can be read
2929 if((rtc_state != RTC_DISABLED) && (physical_index == 0))
2930 {
2931 memcpy(swap_location + 0xC4, rtc_registers, sizeof(rtc_registers));
2932 }
2933
2934 return swap_location;
2935}
2936
2937void init_memory_gamepak()
2938{
2939 u32 map_offset = 0;
2940
2941 if(gamepak_size > gamepak_ram_buffer_size)
2942 {
2943 // Large ROMs get special treatment because they
2944 // can't fit into the 16MB ROM buffer.
2945 u32 i;
2946 for(i = 0; i < gamepak_ram_pages; i++)
2947 {
2948 gamepak_memory_map[i].page_timestamp = 0;
2949 gamepak_memory_map[i].physical_index = 0;
2950 }
2951
2952 map_null(read, 0x8000000, 0xD000000);
2953 }
2954 else
2955 {
2956 map_region(read, 0x8000000, 0x8000000 + gamepak_size, 1024, gamepak_rom);
2957 map_null(read, 0x8000000 + gamepak_size, 0xA000000);
2958 map_region(read, 0xA000000, 0xA000000 + gamepak_size, 1024, gamepak_rom);
2959 map_null(read, 0xA000000 + gamepak_size, 0xC000000);
2960 map_region(read, 0xC000000, 0xC000000 + gamepak_size, 1024, gamepak_rom);
2961 map_null(read, 0xC000000 + gamepak_size, 0xE000000);
2962 }
2963}
2964
2965void init_gamepak_buffer()
2966{
2967 // Try to initialize 32MB (this is mainly for non-PSP platforms)
2968 gamepak_rom = NULL;
2969
2970 gamepak_ram_buffer_size = 32 * 1024 * 1024;
2971 gamepak_rom = malloc(gamepak_ram_buffer_size);
2972
2973 if(gamepak_rom == NULL)
2974 {
2975 // Try 16MB, for PSP, then lower in 2MB increments
2976 gamepak_ram_buffer_size = 16 * 1024 * 1024;
2977 gamepak_rom = malloc(gamepak_ram_buffer_size);
2978
2979 while(gamepak_rom == NULL)
2980 {
2981 gamepak_ram_buffer_size -= (2 * 1024 * 1024);
2982 gamepak_rom = malloc(gamepak_ram_buffer_size);
2983 }
2984 }
2985
2986 // Here's assuming we'll have enough memory left over for this,
2987 // and that the above succeeded (if not we're in trouble all around)
2988 gamepak_ram_pages = gamepak_ram_buffer_size / (32 * 1024);
2989 gamepak_memory_map = malloc(sizeof(gamepak_swap_entry_type) *
2990 gamepak_ram_pages);
2991}
2992
2993void init_memory()
2994{
2995 u32 i;
2996 u32 map_offset = 0;
2997
2998 memory_regions[0x00] = (u8 *)bios_rom;
2999 memory_regions[0x01] = (u8 *)bios_rom;
3000 memory_regions[0x02] = (u8 *)ewram;
3001 memory_regions[0x03] = (u8 *)iwram + 0x8000;
3002 memory_regions[0x04] = (u8 *)io_registers;
3003 memory_regions[0x05] = (u8 *)palette_ram;
3004 memory_regions[0x06] = (u8 *)vram;
3005 memory_regions[0x07] = (u8 *)oam_ram;
3006 memory_regions[0x08] = (u8 *)gamepak_rom;
3007 memory_regions[0x09] = (u8 *)(gamepak_rom + 0xFFFFFF);
3008 memory_regions[0x0A] = (u8 *)gamepak_rom;
3009 memory_regions[0x0B] = (u8 *)(gamepak_rom + 0xFFFFFF);
3010 memory_regions[0x0C] = (u8 *)gamepak_rom;
3011 memory_regions[0x0D] = (u8 *)(gamepak_rom + 0xFFFFFF);
3012 memory_regions[0x0E] = (u8 *)gamepak_backup;
3013
3014 memory_limits[0x00] = 0x3FFF;
3015 memory_limits[0x01] = 0x3FFF;
3016 memory_limits[0x02] = 0x3FFFF;
3017 memory_limits[0x03] = 0x7FFF;
3018 memory_limits[0x04] = 0x7FFF;
3019 memory_limits[0x05] = 0x3FF;
3020 memory_limits[0x06] = 0x17FFF;
3021 memory_limits[0x07] = 0x3FF;
3022 memory_limits[0x08] = 0x1FFFFFF;
3023 memory_limits[0x09] = 0x1FFFFFF;
3024 memory_limits[0x0A] = 0x1FFFFFF;
3025 memory_limits[0x0B] = 0x1FFFFFF;
3026 memory_limits[0x0C] = 0x1FFFFFF;
3027 memory_limits[0x0D] = 0x1FFFFFF;
3028 memory_limits[0x0E] = 0xFFFF;
3029
3030 // Fill memory map regions, areas marked as NULL must be checked directly
3031 map_region(read, 0x0000000, 0x1000000, 1, bios_rom);
3032 map_null(read, 0x1000000, 0x2000000);
3033 map_ram_region(read, 0x2000000, 0x3000000, 8, ewram);
3034 map_ram_region(read, 0x3000000, 0x4000000, 1, iwram);
3035 map_region(read, 0x4000000, 0x5000000, 1, io_registers);
3036 map_null(read, 0x5000000, 0x6000000);
3037 map_null(read, 0x6000000, 0x7000000);
3038 map_vram(read);
3039 map_null(read, 0x7000000, 0x8000000);
3040 init_memory_gamepak();
3041 map_null(read, 0xE000000, 0x10000000);
3042
3043 // Fill memory map regions, areas marked as NULL must be checked directly
3044 map_null(write, 0x0000000, 0x2000000);
3045 map_ram_region(write, 0x2000000, 0x3000000, 8, ewram);
3046 map_ram_region(write, 0x3000000, 0x4000000, 1, iwram);
3047 map_null(write, 0x4000000, 0x5000000);
3048 map_null(write, 0x5000000, 0x6000000);
3049
3050 // The problem here is that the current method of handling self-modifying code
3051 // requires writeable memory to be proceeded by 32KB SMC data areas or be
3052 // indirectly writeable. It's possible to get around this if you turn off the SMC
3053 // check altogether, but this will make a good number of ROMs crash (perhaps most
3054 // of the ones that actually need it? This has yet to be determined).
3055
3056 // This is because VRAM cannot be efficiently made incontiguous, and still allow
3057 // the renderer to work as efficiently. It would, at the very least, require a
3058 // lot of hacking of the renderer which I'm not prepared to do.
3059
3060 // However, it IS possible to directly map the first page no matter what because
3061 // there's 32kb of blank stuff sitting beneath it.
3062 if(direct_map_vram)
3063 {
3064 map_vram(write);
3065 }
3066 else
3067 {
3068 map_null(write, 0x6000000, 0x7000000);
3069 }
3070
3071 map_null(write, 0x7000000, 0x8000000);
3072 map_null(write, 0x8000000, 0xE000000);
3073 map_null(write, 0xE000000, 0x10000000);
3074
3075 memset(io_registers, 0, 0x8000);
3076 memset(oam_ram, 0, 0x400);
3077 memset(palette_ram, 0, 0x400);
3078 memset(iwram, 0, 0x10000);
3079 memset(ewram, 0, 0x80000);
3080 memset(vram, 0, 0x18000);
3081
3082 io_registers[REG_DISPCNT] = 0x80;
3083 io_registers[REG_P1] = 0x3FF;
3084 io_registers[REG_BG2PA] = 0x100;
3085 io_registers[REG_BG2PD] = 0x100;
3086 io_registers[REG_BG3PA] = 0x100;
3087 io_registers[REG_BG3PD] = 0x100;
3088 io_registers[REG_RCNT] = 0x8000;
3089
3090 backup_type = BACKUP_NONE;
3091
3092 sram_size = SRAM_SIZE_32KB;
3093 flash_size = FLASH_SIZE_64KB;
3094
3095 flash_bank_ptr = gamepak_backup;
3096 flash_command_position = 0;
3097 eeprom_size = EEPROM_512_BYTE;
3098 eeprom_mode = EEPROM_BASE_MODE;
3099 eeprom_address = 0;
3100 eeprom_counter = 0;
3101
3102 flash_mode = FLASH_BASE_MODE;
3103
3104 rtc_state = RTC_DISABLED;
3105 memset(rtc_registers, 0, sizeof(rtc_registers));
3106 bios_read_protect = 0xe129f000;
3107}
3108
3109void bios_region_read_allow()
3110{
3111 memory_map_read[0] = bios_rom;
3112}
3113
3114void bios_region_read_protect()
3115{
3116#ifdef GP2X_BUILD
3117 memory_map_read[0] = NULL;
3118#endif
3119}
3120
3121
3122#define savestate_block(type) \
3123 cpu_##type##_savestate(savestate_file); \
3124 input_##type##_savestate(savestate_file); \
3125 main_##type##_savestate(savestate_file); \
3126 memory_##type##_savestate(savestate_file); \
3127 sound_##type##_savestate(savestate_file); \
3128 video_##type##_savestate(savestate_file) \
3129
3130void load_state(char *savestate_filename)
3131{
3132 file_open(savestate_file, savestate_filename, read);
3133 if(file_check_valid(savestate_file))
3134 {
3135 char current_gamepak_filename[512];
3136 char savestate_gamepak_filename[512];
3137 u32 i;
3138 u32 current_color;
3139
3140 file_seek(savestate_file, (240 * 160 * 2) + sizeof(time_t), SEEK_SET);
3141
3142 strcpy(current_gamepak_filename, gamepak_filename);
3143
3144 savestate_block(read);
3145
3146 file_close(savestate_file);
3147
3148 flush_translation_cache_ram();
3149 flush_translation_cache_rom();
3150 flush_translation_cache_bios();
3151
3152 oam_update = 1;
3153 gbc_sound_update = 1;
3154 if(strcmp(current_gamepak_filename, gamepak_filename))
3155 {
3156 u32 dot_position = strcspn(current_gamepak_filename, ".");
3157
3158 // We'll let it slide if the filenames of the savestate and
3159 // the gamepak are similar enough.
3160 strcpy(gamepak_filename, current_gamepak_filename);
3161 if(strncmp(savestate_filename, current_gamepak_filename, dot_position))
3162 {
3163 if(load_gamepak(gamepak_filename) != -1)
3164 {
3165 reset_gba();
3166 // Okay, so this takes a while, but for now it works.
3167 load_state(savestate_filename);
3168 }
3169 else
3170 {
3171 quit();
3172 }
3173
3174 return;
3175 }
3176 }
3177
3178 for(i = 0; i < 512; i++)
3179 {
3180 current_color = palette_ram[i];
3181 palette_ram_converted[i] =
3182 convert_palette(current_color);
3183 }
3184
3185 // Oops, these contain raw pointers
3186 for(i = 0; i < 4; i++)
3187 {
3188 gbc_sound_channel[i].sample_data = square_pattern_duty[2];
3189 }
3190 current_debug_state = STEP;
3191 instruction_count = 0;
3192
3193 reg[CHANGED_PC_STATUS] = 1;
3194 }
3195}
3196
3197u8 savestate_write_buffer[506947];
3198u8 *write_mem_ptr;
3199
3200void save_state(char *savestate_filename, u16 *screen_capture)
3201{
3202 write_mem_ptr = savestate_write_buffer;
3203 file_open(savestate_file, savestate_filename, write);
3204 if(file_check_valid(savestate_file))
3205 {
3206 time_t current_time;
3207 file_write_mem(savestate_file, screen_capture, 240 * 160 * 2);
3208
3209 time(&current_time);
3210 file_write_mem_variable(savestate_file, current_time);
3211
3212 savestate_block(write_mem);
3213 file_write(savestate_file, savestate_write_buffer,
3214 sizeof(savestate_write_buffer));
3215
3216 file_close(savestate_file);
3217 }
3218}
3219
3220
3221#define memory_savestate_builder(type) \
3222void memory_##type##_savestate(file_tag_type savestate_file) \
3223{ \
3224 u32 i; \
3225 \
3226 file_##type##_variable(savestate_file, backup_type); \
3227 file_##type##_variable(savestate_file, sram_size); \
3228 file_##type##_variable(savestate_file, flash_mode); \
3229 file_##type##_variable(savestate_file, flash_command_position); \
3230 file_##type##_variable(savestate_file, flash_bank_ptr); \
3231 file_##type##_variable(savestate_file, flash_device_id); \
3232 file_##type##_variable(savestate_file, flash_manufacturer_id); \
3233 file_##type##_variable(savestate_file, flash_size); \
3234 file_##type##_variable(savestate_file, eeprom_size); \
3235 file_##type##_variable(savestate_file, eeprom_mode); \
3236 file_##type##_variable(savestate_file, eeprom_address_length); \
3237 file_##type##_variable(savestate_file, eeprom_address); \
3238 file_##type##_variable(savestate_file, eeprom_counter); \
3239 file_##type##_variable(savestate_file, rtc_state); \
3240 file_##type##_variable(savestate_file, rtc_write_mode); \
3241 file_##type##_array(savestate_file, rtc_registers); \
3242 file_##type##_variable(savestate_file, rtc_command); \
3243 file_##type##_array(savestate_file, rtc_data); \
3244 file_##type##_variable(savestate_file, rtc_status); \
3245 file_##type##_variable(savestate_file, rtc_data_bytes); \
3246 file_##type##_variable(savestate_file, rtc_bit_count); \
3247 file_##type##_array(savestate_file, eeprom_buffer); \
3248 file_##type##_array(savestate_file, gamepak_filename); \
3249 file_##type##_array(savestate_file, dma); \
3250 \
3251 file_##type(savestate_file, iwram + 0x8000, 0x8000); \
3252 for(i = 0; i < 8; i++) \
3253 { \
3254 file_##type(savestate_file, ewram + (i * 0x10000) + 0x8000, 0x8000); \
3255 } \
3256 file_##type(savestate_file, vram, 0x18000); \
3257 file_##type(savestate_file, oam_ram, 0x400); \
3258 file_##type(savestate_file, palette_ram, 0x400); \
3259 file_##type(savestate_file, io_registers, 0x8000); \
3260 \
3261 /* This is a hack, for now. */ \
3262 if((flash_bank_ptr < gamepak_backup) || \
3263 (flash_bank_ptr > (gamepak_backup + (1024 * 64)))) \
3264 { \
3265 flash_bank_ptr = gamepak_backup; \
3266 } \
3267} \
3268
3269memory_savestate_builder(read);
3270memory_savestate_builder(write_mem);
3271