• R/O
  • SSH
  • HTTPS

gpsp-kai: Commit


Commit MetaInfo

Revision281 (tree)
Zeit2007-10-15 05:02:11
Autortakka

Log Message

3.2 test 04
ZIPファイル使用時のフリーズバグの対応
PSP-2000でのスリープ時のメモリ破壊に対応

Ändern Zusammenfassung

Diff

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