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