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