2 Nintendo Family BASIC Emulator 'eFamilyBASIC'
5 Author : Takeda.Toshiya
13 #include "../datarec.h"
14 #include "../ym2413.h"
16 #define EVENT_DMA_DONE 0
18 void MEMORY::initialize()
20 key_stat = emu->get_key_buffer();
21 joy_stat = emu->get_joy_buffer();
24 register_vline_event(this);
27 void MEMORY::load_rom_image(const _TCHAR *file_name)
29 FILEIO* fio = new FILEIO();
31 memset(save_ram, 0, sizeof(save_ram));
33 if(fio->Fopen(create_local_path(file_name), FILEIO_READ_BINARY)) {
34 // create save file name
35 _TCHAR tmp_file_name[_MAX_PATH];
36 my_tcscpy_s(tmp_file_name, _MAX_PATH, file_name);
37 _TCHAR *dot = _tcsstr(tmp_file_name, _T("."));
38 if(dot != NULL) dot[0] = _T('\0');
39 my_stprintf_s(save_file_name, _MAX_PATH, _T("%s.SAV"), tmp_file_name);
42 fio->Fopen(create_local_path(_T("BASIC.NES")), FILEIO_READ_BINARY);
43 my_tcscpy_s(save_file_name, _MAX_PATH, _T("BACKUP.BIN"));
47 fio->Fread(&header, sizeof(header), 1);
49 rom_size = 0x2000 * header.num_8k_rom_banks();
50 for(uint32_t bit = 0x80000; bit != 0; bit >>= 1) {
52 if(rom_size & (bit - 1)) {
53 rom_size = (rom_size | (bit - 1)) + 1;
58 rom = (uint8_t *)calloc(rom_size, 1);
59 fio->Fread(rom, 0x2000 * header.num_8k_rom_banks(), 1);
62 memset(&header, 0, sizeof(header));
63 header.dummy = 2; // 32KB
64 rom_size = 0x2000 * header.num_8k_rom_banks();
65 rom = (uint8_t *)calloc(rom_size, 1);
66 memset(rom, 0xff, 0x2000 * header.num_8k_rom_banks());
68 if(fio->Fopen(create_local_path(save_file_name), FILEIO_READ_BINARY)) {
69 fio->Fread(save_ram, sizeof(save_ram), 1);
74 rom_mask = (rom_size / 0x2000) - 1;
75 save_ram_crc32 = get_crc32(save_ram, sizeof(save_ram));
78 void MEMORY::save_backup()
80 if(save_ram_crc32 != get_crc32(save_ram, sizeof(save_ram))) {
81 FILEIO* fio = new FILEIO();
82 if(fio->Fopen(create_local_path(save_file_name), FILEIO_WRITE_BINARY)) {
83 fio->Fwrite(save_ram, sizeof(save_ram), 1);
90 void MEMORY::release()
101 memset(ram, 0, sizeof(ram));
103 for(int i = 4; i < 8; i++) {
106 bank_ptr[3] = save_ram;
109 frame_irq_enabled = 0xff;
112 pad1_bits = pad2_bits = 0xff;
121 void MEMORY::write_data8(uint32_t addr, uint32_t data)
126 ram[addr & 0x7ff] = data;
127 } else if(addr < 0x4000) {
128 d_ppu->write_data8(addr, data);
129 } else if(addr == 0x4014) {
131 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
132 register_event_by_clock(this, EVENT_DMA_DONE, 514, false, NULL);
134 dma_addr = data << 8;
135 for(int i = 0; i < 256; i++) {
136 spr_ram[i] = read_data8(dma_addr | i);
138 } else if(addr == 0x4016) {
141 } else if(pad_strobe) {
145 if(joy_stat[0] & 0x10) pad1_bits |= 0x01; // A
146 if(joy_stat[0] & 0x20) pad1_bits |= 0x02; // B
147 if(joy_stat[0] & 0x40) pad1_bits |= 0x04; // SEL
148 if(joy_stat[0] & 0x80) pad1_bits |= 0x08; // START
149 if(joy_stat[0] & 0x01) pad1_bits |= 0x10; // UP
150 if(joy_stat[0] & 0x02) pad1_bits |= 0x20; // DOWN
151 if(joy_stat[0] & 0x04) pad1_bits |= 0x40; // LEFT
152 if(joy_stat[0] & 0x08) pad1_bits |= 0x80; // RIGHT
155 if(joy_stat[1] & 0x10) pad2_bits |= 0x01; // A
156 if(joy_stat[1] & 0x20) pad2_bits |= 0x02; // B
157 if(joy_stat[1] & 0x01) pad2_bits |= 0x10; // UP
158 if(joy_stat[1] & 0x02) pad2_bits |= 0x20; // DOWN
159 if(joy_stat[1] & 0x04) pad2_bits |= 0x40; // LEFT
160 if(joy_stat[1] & 0x08) pad2_bits |= 0x80; // RIGHT
163 if((data & 0x07) == 0x04) {
168 } else if((data & 0x07) == 0x05) {
171 } else if((data & 0x07) == 0x06) {
174 // data recorder (thanks MESS)
175 if((data & 0x07) == 0x07) {
176 d_drec->write_signal(SIG_DATAREC_MIC, 1, 1);
178 d_drec->write_signal(SIG_DATAREC_MIC, 0, 0);
180 } else if(addr < 0x4018) {
182 frame_irq_enabled = data;
184 d_apu->write_data8(addr, data);
185 } else if(addr < 0x6000) {
186 if(header.mapper() == 5) {
187 mmc5_lo_write(addr, data);
188 // } else if(header.mapper() == 85) {
189 // vrc7_lo_write(addr, data);
191 } else if(addr < 0x8000) {
192 if(header.mapper() == 5) {
193 mmc5_save_write(addr, data);
194 // } else if(header.mapper() == 85) {
195 // vrc7_save_write(addr, data);
197 bank_ptr[3][addr & 0x1fff] = data;
200 if(header.mapper() == 5) {
201 mmc5_hi_write(addr, data);
202 } else if(header.mapper() == 85) {
203 vrc7_hi_write(addr, data);
208 uint32_t MEMORY::read_data8(uint32_t addr)
213 return ram[addr & 0x7ff];
214 } else if(addr < 0x4000) {
215 return d_ppu->read_data8(addr);
216 } else if(addr == 0x4014) {
217 return dma_addr >> 8;
218 } else if(addr < 0x4016) {
219 uint32_t val = d_apu->read_data8(addr);
220 if(addr == 0x4015 && !(frame_irq_enabled & 0xc0)) {
224 } else if(addr == 0x4016) {
226 uint32_t val = pad1_bits & 1;
229 val |= d_drec->read_signal(0) ? 2 : 0;
231 val |= key_stat[0x7b] ? 4 : 0; // F12
233 } else if(addr == 0x4017) {
235 uint32_t val = 0xfe | (pad2_bits & 1);
241 if(key_stat[0x77]) val &= ~0x02; // F8
242 if(key_stat[0x0d]) val &= ~0x04; // RETURN
243 if(key_stat[0xdb]) val &= ~0x08; // [
244 if(key_stat[0xdd]) val &= ~0x10; // ]
247 if(key_stat[0x76]) val &= ~0x02; // F7
248 if(key_stat[0xc0]) val &= ~0x04; // @
249 if(key_stat[0xba]) val &= ~0x08; // :
250 if(key_stat[0xbb]) val &= ~0x10; // ;
253 if(key_stat[0x75]) val &= ~0x02; // F6
254 if(key_stat[0x4f]) val &= ~0x04; // O
255 if(key_stat[0x4c]) val &= ~0x08; // L
256 if(key_stat[0x4b]) val &= ~0x10; // K
259 if(key_stat[0x74]) val &= ~0x02; // F5
260 if(key_stat[0x49]) val &= ~0x04; // I
261 if(key_stat[0x55]) val &= ~0x08; // U
262 if(key_stat[0x4a]) val &= ~0x10; // J
265 if(key_stat[0x73]) val &= ~0x02; // F4
266 if(key_stat[0x59]) val &= ~0x04; // Y
267 if(key_stat[0x47]) val &= ~0x08; // G
268 if(key_stat[0x48]) val &= ~0x10; // H
271 if(key_stat[0x72]) val &= ~0x02; // F3
272 if(key_stat[0x54]) val &= ~0x04; // T
273 if(key_stat[0x52]) val &= ~0x08; // R
274 if(key_stat[0x44]) val &= ~0x10; // D
277 if(key_stat[0x71]) val &= ~0x02; // F2
278 if(key_stat[0x57]) val &= ~0x04; // W
279 if(key_stat[0x53]) val &= ~0x08; // S
280 if(key_stat[0x41]) val &= ~0x10; // A
283 if(key_stat[0x70]) val &= ~0x02; // F1
284 if(key_stat[0x1b]) val &= ~0x04; // ESC
285 if(key_stat[0x51]) val &= ~0x08; // Q
286 if(key_stat[0x11]) val &= ~0x10; // CTRL
289 if(key_stat[0x24]) val &= ~0x02; // CLS
290 if(key_stat[0x26]) val &= ~0x04; // UP
291 if(key_stat[0x27]) val &= ~0x08; // RIGHT
292 if(key_stat[0x25]) val &= ~0x10; // LEFT
298 if(key_stat[0x15]) val &= ~0x02; // KANA
299 // if(key_stat[0x10]) val &= ~0x04; // RSHIFT
300 if(key_stat[0xdc]) val &= ~0x08; // '\\'
301 if(key_stat[0x23]) val &= ~0x10; // STOP
304 if(key_stat[0xe2]) val &= ~0x02; // _
305 if(key_stat[0xbf]) val &= ~0x04; // /
306 if(key_stat[0xbd]) val &= ~0x08; // -
307 if(key_stat[0xde]) val &= ~0x10; // ^
310 if(key_stat[0xbe]) val &= ~0x02; // .
311 if(key_stat[0xbc]) val &= ~0x04; // ,
312 if(key_stat[0x50]) val &= ~0x08; // P
313 if(key_stat[0x30]) val &= ~0x10; // 0
316 if(key_stat[0x4d]) val &= ~0x02; // M
317 if(key_stat[0x4e]) val &= ~0x04; // N
318 if(key_stat[0x39]) val &= ~0x08; // 9
319 if(key_stat[0x38]) val &= ~0x10; // 8
322 if(key_stat[0x42]) val &= ~0x02; // B
323 if(key_stat[0x56]) val &= ~0x04; // V
324 if(key_stat[0x37]) val &= ~0x08; // 7
325 if(key_stat[0x36]) val &= ~0x10; // 6
328 if(key_stat[0x46]) val &= ~0x02; // F
329 if(key_stat[0x43]) val &= ~0x04; // C
330 if(key_stat[0x35]) val &= ~0x08; // 5
331 if(key_stat[0x34]) val &= ~0x10; // 4
334 if(key_stat[0x58]) val &= ~0x02; // X
335 if(key_stat[0x5a]) val &= ~0x04; // Z
336 if(key_stat[0x45]) val &= ~0x08; // E
337 if(key_stat[0x33]) val &= ~0x10; // 3
340 if(key_stat[0x10]) val &= ~0x02; // LSHIFT
341 if(key_stat[0x12]) val &= ~0x04; // GRAPH
342 if(key_stat[0x31]) val &= ~0x08; // 1
343 if(key_stat[0x32]) val &= ~0x10; // 2
346 if(key_stat[0x28]) val &= ~0x02; // DOWN
347 if(key_stat[0x20]) val &= ~0x04; // SPACE
348 if(key_stat[0x2e]) val &= ~0x08; // DEL
349 if(key_stat[0x2d]) val &= ~0x10; // INS
354 } else if(addr < 0x6000) {
355 if(header.mapper() == 5) {
356 return mmc5_lo_read(addr);
357 // } else if(header.mapper() == 85) {
358 // return vrc7_lo_read(addr);
362 } else if(addr < 0x8000) {
363 // if(header.mapper() == 5) {
364 // return mmc5_save_read(addr);
365 // } else if(header.mapper() == 85) {
366 // return vrc7_save_read(addr);
368 return bank_ptr[3][addr & 0x1fff];
370 } else if(addr < 0xa000) {
371 return bank_ptr[4][addr & 0x1fff];
372 } else if(addr < 0xc000) {
373 return bank_ptr[5][addr & 0x1fff];
374 } else if(addr < 0xe000) {
375 return bank_ptr[6][addr & 0x1fff];
377 return bank_ptr[7][addr & 0x1fff];
381 void MEMORY::event_vline(int v, int clock)
390 if(v == 240 && !(frame_irq_enabled & 0xc0)) {
392 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
396 if(header.mapper() == 5) {
398 } else if(header.mapper() == 85) {
403 void MEMORY::event_callback(int event_id, int err)
406 d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
409 void MEMORY::set_rom_bank(uint8_t bank, uint32_t bank_num)
411 bank_ptr[bank] = rom + 0x2000 * (bank_num & rom_mask);
412 banks[bank] = bank_num;
415 mmc5_wram_bank[bank] = 8;
420 void MEMORY::mmc5_reset()
422 if(header.mapper() == 5) {
423 mmc5_set_wram_bank(3, 0);
424 set_rom_bank(4, header.num_8k_rom_banks() - 1);
425 set_rom_bank(5, header.num_8k_rom_banks() - 1);
426 set_rom_bank(6, header.num_8k_rom_banks() - 1);
427 set_rom_bank(7, header.num_8k_rom_banks() - 1);
429 for(int i = 0; i < 8; i++) {
430 mmc5_chr_reg[i][0] = i;
431 mmc5_chr_reg[i][1] = (i & 0x03) + 4;
433 mmc5_wram_protect0 = 0x02;
434 mmc5_wram_protect1 = 0x01;
438 // mmc5_split_control = 0;
439 // mmc5_split_bank = 0;
440 mmc5_irq_enabled = 0;
446 uint32_t MEMORY::mmc5_lo_read(uint32_t addr)
448 uint8_t data = (uint8_t)(addr >> 8);
451 data = mmc5_irq_status;
452 mmc5_irq_status &= ~0x80;
453 } else if(addr == 0x5205) {
454 data = (uint8_t)(((mmc5_value0 * mmc5_value1) & 0x00ff) >> 0);
455 } else if(addr == 0x5206) {
456 data = (uint8_t)(((mmc5_value0 * mmc5_value1) & 0xff00) >> 8);
457 } else if(addr >= 0x5c00 && addr < 0x6000) {
458 if(mmc5_gfx_mode == 2 || mmc5_gfx_mode == 3) {
459 data = (d_ppu->get_name_tables() + 0x800)[addr & 0x3ff];
465 void MEMORY::mmc5_lo_write(uint32_t addr, uint32_t data)
469 mmc5_prg_size = data & 0x03;
472 mmc5_chr_size = data & 0x03;
475 mmc5_wram_protect0 = data & 0x03;
478 mmc5_wram_protect1 = data & 0x03;
481 mmc5_gfx_mode = data & 0x03;
484 for(int i = 0; i < 4; i++) {
485 d_ppu->set_ppu_bank(8 + i, data & 0x03);
490 for(int i = 0; i < 0x3c0; i++) {
491 (d_ppu->get_name_tables() + 0xc00)[i] = data;
495 for(int i = 0x3c0; i < 0x400; i++) {
496 (d_ppu->get_name_tables() + 0xc00)[i] = 0x55 * (data & 3);
500 mmc5_set_wram_bank(3, data & 0x07);
506 mmc5_set_cpu_bank(addr & 0x07, data);
516 mmc5_chr_reg[addr & 0x07][0] = data;
517 mmc5_set_ppu_bank(0);
523 mmc5_chr_reg[(addr & 0x03) + 0][1] = data;
524 mmc5_chr_reg[(addr & 0x03) + 4][1] = data;
527 // mmc5_split_control = data;
530 // mmc5_split_scroll = data;
533 // mmc5_split_bank = data & 0x3f;
536 mmc5_irq_line = data;
539 mmc5_irq_enabled = data;
548 if(addr >= 0x5000 && addr <= 0x5015) {
549 // d_mmc5->write_io8(addr, data);
550 } else if(addr >= 0x5c00 && addr <= 0x5fff) {
551 if(mmc5_gfx_mode != 3) {
552 (d_ppu->get_name_tables() + 0x800)[addr & 0x3ff] = data; //(mmc5_irq_status & 0) ? data : 0x40;
559 //uint32_t MEMORY::mmc5_save_read(uint32_t addr)
561 // return bank_ptr[3][addr & 0x1fff];
564 void MEMORY::mmc5_save_write(uint32_t addr, uint32_t data)
566 if(mmc5_wram_protect0 == 0x02 && mmc5_wram_protect1 == 0x01) {
567 if(mmc5_wram_bank[3] < 8) {
568 bank_ptr[3][addr & 0x1fff] = data;
573 void MEMORY::mmc5_hi_write(uint32_t addr, uint32_t data)
575 if(mmc5_wram_protect0 == 0x02 && mmc5_wram_protect1 == 0x01) {
577 if(mmc5_wram_bank[4] < 8) {
578 bank_ptr[4][addr & 0x1fff] = data;
580 } else if(addr < 0xc000) {
581 if(mmc5_wram_bank[5] < 8) {
582 bank_ptr[5][addr & 0x1fff] = data;
584 } else if(addr < 0xe000) {
585 if(mmc5_wram_bank[6] < 8) {
586 bank_ptr[6][addr & 0x1fff] = data;
589 if(mmc5_wram_bank[7] < 8) {
590 bank_ptr[7][addr & 0x1fff] = data;
596 void MEMORY::mmc5_hsync(int v)
599 if(v == mmc5_irq_line) {
600 if(d_ppu->spr_enabled() && d_ppu->bg_enabled()) {
601 mmc5_irq_status |= 0x80;
604 if((mmc5_irq_status & 0x80) && (mmc5_irq_enabled & 0x80)) {
605 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
608 mmc5_irq_status |= 0x40;
612 void MEMORY::mmc5_set_cpu_bank(uint8_t bank, uint32_t bank_num)
614 if(bank_num & 0x80) {
615 if(mmc5_prg_size == 0) {
617 set_rom_bank(4, (bank_num & 0x7c) + 0);
618 set_rom_bank(5, (bank_num & 0x7c) + 1);
619 set_rom_bank(6, (bank_num & 0x7c) + 2);
620 set_rom_bank(7, (bank_num & 0x7c) + 3);
622 } else if(mmc5_prg_size == 1) {
624 set_rom_bank(4, (bank_num & 0x7e) + 0);
625 set_rom_bank(5, (bank_num & 0x7e) + 1);
626 } else if(bank == 7) {
627 set_rom_bank(6, (bank_num & 0x7e) + 0);
628 set_rom_bank(7, (bank_num & 0x7e) + 1);
630 } else if(mmc5_prg_size == 2) {
632 set_rom_bank(4, (bank_num & 0x7e) + 0);
633 set_rom_bank(5, (bank_num & 0x7e) + 1);
634 } else if(bank == 6) {
635 set_rom_bank(6, bank_num & 0x7f);
636 } else if(bank == 7) {
637 set_rom_bank(7, bank_num & 0x7f);
639 } else if(mmc5_prg_size == 3) {
641 set_rom_bank(4, bank_num & 0x7f);
642 } else if(bank == 5) {
643 set_rom_bank(5, bank_num & 0x7f);
644 } else if(bank == 6) {
645 set_rom_bank(6, bank_num & 0x7f);
646 } else if(bank == 7) {
647 set_rom_bank(7, bank_num & 0x7f);
651 if(mmc5_prg_size == 1) {
653 mmc5_set_wram_bank(4, (bank_num & 0x06)+0);
654 mmc5_set_wram_bank(5, (bank_num & 0x06)+1);
656 } else if(mmc5_prg_size == 2) {
658 mmc5_set_wram_bank(4, (bank_num & 0x06)+0);
659 mmc5_set_wram_bank(5, (bank_num & 0x06)+1);
662 mmc5_set_wram_bank(6, bank_num & 0x07);
664 } else if(mmc5_prg_size == 3) {
666 mmc5_set_wram_bank(4, bank_num & 0x07);
667 } else if(bank == 5) {
668 mmc5_set_wram_bank(5, bank_num & 0x07);
669 } else if(bank == 6) {
670 mmc5_set_wram_bank(6, bank_num & 0x07);
676 void MEMORY::mmc5_set_wram_bank(uint8_t bank, uint32_t bank_num)
679 bank_ptr[bank] = save_ram + 0x2000 * bank_num;
680 mmc5_wram_bank[bank] = bank_num;
682 set_rom_bank(bank, banks[bank]);
686 void MEMORY::mmc5_set_ppu_bank(uint8_t mode)
688 if(mmc5_chr_size == 0) {
689 d_ppu->set_ppu_bank(0, mmc5_chr_reg[7][mode] * 8 + 0);
690 d_ppu->set_ppu_bank(1, mmc5_chr_reg[7][mode] * 8 + 1);
691 d_ppu->set_ppu_bank(2, mmc5_chr_reg[7][mode] * 8 + 2);
692 d_ppu->set_ppu_bank(3, mmc5_chr_reg[7][mode] * 8 + 3);
693 d_ppu->set_ppu_bank(4, mmc5_chr_reg[7][mode] * 8 + 4);
694 d_ppu->set_ppu_bank(5, mmc5_chr_reg[7][mode] * 8 + 5);
695 d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 8 + 6);
696 d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 8 + 7);
697 } else if(mmc5_chr_size == 1) {
698 d_ppu->set_ppu_bank(0, mmc5_chr_reg[3][mode] * 4 + 0);
699 d_ppu->set_ppu_bank(1, mmc5_chr_reg[3][mode] * 4 + 1);
700 d_ppu->set_ppu_bank(2, mmc5_chr_reg[3][mode] * 4 + 2);
701 d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode] * 4 + 3);
702 d_ppu->set_ppu_bank(4, mmc5_chr_reg[7][mode] * 4 + 0);
703 d_ppu->set_ppu_bank(5, mmc5_chr_reg[7][mode] * 4 + 1);
704 d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 4 + 2);
705 d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 4 + 3);
706 } else if(mmc5_chr_size == 2) {
707 d_ppu->set_ppu_bank(0, mmc5_chr_reg[1][mode] * 2 + 0);
708 d_ppu->set_ppu_bank(1, mmc5_chr_reg[1][mode] * 2 + 1);
709 d_ppu->set_ppu_bank(2, mmc5_chr_reg[3][mode] * 2 + 0);
710 d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode] * 2 + 1);
711 d_ppu->set_ppu_bank(4, mmc5_chr_reg[5][mode] * 2 + 0);
712 d_ppu->set_ppu_bank(5, mmc5_chr_reg[5][mode] * 2 + 1);
713 d_ppu->set_ppu_bank(6, mmc5_chr_reg[7][mode] * 2 + 0);
714 d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode] * 2 + 1);
716 d_ppu->set_ppu_bank(0, mmc5_chr_reg[0][mode]);
717 d_ppu->set_ppu_bank(1, mmc5_chr_reg[1][mode]);
718 d_ppu->set_ppu_bank(2, mmc5_chr_reg[2][mode]);
719 d_ppu->set_ppu_bank(3, mmc5_chr_reg[3][mode]);
720 d_ppu->set_ppu_bank(4, mmc5_chr_reg[4][mode]);
721 d_ppu->set_ppu_bank(5, mmc5_chr_reg[5][mode]);
722 d_ppu->set_ppu_bank(6, mmc5_chr_reg[6][mode]);
723 d_ppu->set_ppu_bank(7, mmc5_chr_reg[7][mode]);
727 uint8_t MEMORY::mmc5_ppu_latch_render(uint8_t mode, uint32_t addr)
731 if(mmc5_gfx_mode == 1 && mode == 1) {
733 uint32_t bank_num = ((d_ppu->get_name_tables() + 0x800)[addr] & 0x3f) << 2;
734 d_ppu->set_ppu_bank(0, bank_num + 0);
735 d_ppu->set_ppu_bank(1, bank_num + 1);
736 d_ppu->set_ppu_bank(2, bank_num + 2);
737 d_ppu->set_ppu_bank(3, bank_num + 3);
738 d_ppu->set_ppu_bank(4, bank_num + 0);
739 d_ppu->set_ppu_bank(5, bank_num + 1);
740 d_ppu->set_ppu_bank(6, bank_num + 2);
741 d_ppu->set_ppu_bank(7, bank_num + 3);
742 data = (((d_ppu->get_name_tables() + 0x800)[addr] & 0xc0) >> 4) | 0x01;
745 mmc5_set_ppu_bank(mode);
752 void MEMORY::vrc7_reset()
754 if(header.mapper() == 85) {
755 vrc7_irq_enabled = 0;
756 vrc7_irq_counter = 0;
758 d_opll->write_signal(SIG_YM2413_MUTE, 0, 0);
761 set_rom_bank(6, header.num_8k_rom_banks() - 2);
762 set_rom_bank(7, header.num_8k_rom_banks() - 1);
764 d_opll->write_signal(SIG_YM2413_MUTE, 1, 1);
768 //uint32_t MEMORY::vrc7_lo_read(uint32_t addr)
773 //void MEMORY::vrc7_lo_write(uint32_t addr, uint32_t data)
777 //uint32_t MEMORY::vrc7_save_read(uint32_t addr)
779 // return bank_ptr[3][addr & 0x1fff];
782 //void MEMORY::vrc7_save_write(uint32_t addr, uint32_t data)
784 // bank_ptr[3][addr & 0x1fff] = data;
787 void MEMORY::vrc7_hi_write(uint32_t addr, uint32_t data)
789 switch(addr & 0xf038) {
791 set_rom_bank(4, data);
795 set_rom_bank(5, data);
798 set_rom_bank(6, data);
802 d_opll->write_io8(addr >> 5, data);
805 d_ppu->set_ppu_bank(0, data);
809 d_ppu->set_ppu_bank(1, data);
812 d_ppu->set_ppu_bank(2, data);
816 d_ppu->set_ppu_bank(3, data);
819 d_ppu->set_ppu_bank(4, data);
823 d_ppu->set_ppu_bank(5, data);
826 d_ppu->set_ppu_bank(6, data);
830 d_ppu->set_ppu_bank(7, data);
833 switch(data & 0x03) {
835 d_ppu->set_mirroring(MIRROR_VERT);
838 d_ppu->set_mirroring(MIRROR_HORIZ);
841 d_ppu->set_mirroring(0, 0, 0, 0);
844 d_ppu->set_mirroring(1, 1, 1, 1);
850 vrc7_irq_latch = data;
854 vrc7_irq_counter = vrc7_irq_latch;
856 vrc7_irq_enabled = data & 0x03;
860 vrc7_irq_enabled = (vrc7_irq_enabled & 0x01) * 3;
865 void MEMORY::vrc7_hsync(int v)
867 if(vrc7_irq_enabled & 0x02) {
868 if(vrc7_irq_counter == 0xff) {
869 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
870 vrc7_irq_counter = vrc7_irq_latch;
877 #define STATE_VERSION 2
879 #include "../../statesub.h"
881 void MEMORY::decl_state_header(header_t *p)
883 DECL_STATE_ENTRY_1D_ARRAY((p->id), 3); // 'NES'
884 DECL_STATE_ENTRY_UINT8((p->ctrl_z)); // control-z
885 DECL_STATE_ENTRY_UINT8((p->dummy));
886 DECL_STATE_ENTRY_UINT8((p->num_8k_vrom_banks));
887 DECL_STATE_ENTRY_UINT8((p->flags_1));
888 DECL_STATE_ENTRY_UINT8((p->flags_2));
889 DECL_STATE_ENTRY_1D_ARRAY((p->reserved), 1);
892 void MEMORY::decl_state()
894 enter_decl_state(STATE_VERSION);
896 DECL_STATE_ENTRY_STRING(save_file_name, sizeof(save_file_name) / sizeof(_TCHAR));
897 decl_state_header(&header);
899 DECL_STATE_ENTRY_UINT32(rom_size);
900 // DECL_STATE_ENTRY_UINT32(rom_mask);
901 DECL_STATE_ENTRY_VARARRAY_VAR(rom, rom_size);
902 DECL_STATE_ENTRY_1D_ARRAY(ram, sizeof(ram));
903 DECL_STATE_ENTRY_1D_ARRAY(save_ram, sizeof(save_ram));
904 DECL_STATE_ENTRY_UINT32(save_ram_crc32);
905 DECL_STATE_ENTRY_1D_ARRAY(banks, sizeof(banks) / sizeof(uint32_t));
906 DECL_STATE_ENTRY_UINT16(dma_addr);
907 DECL_STATE_ENTRY_UINT8(frame_irq_enabled);
908 DECL_STATE_ENTRY_1D_ARRAY(mmc5_wram_bank, sizeof(mmc5_wram_bank)/ sizeof(uint32_t));
909 DECL_STATE_ENTRY_2D_ARRAY(mmc5_chr_reg, 8, 2);
910 DECL_STATE_ENTRY_UINT32(mmc5_value0);
911 DECL_STATE_ENTRY_UINT32(mmc5_value0);
912 DECL_STATE_ENTRY_UINT8(mmc5_wram_protect0);
913 DECL_STATE_ENTRY_UINT8(mmc5_wram_protect1);
914 DECL_STATE_ENTRY_UINT8(mmc5_prg_size);
915 DECL_STATE_ENTRY_UINT8(mmc5_chr_size);
916 DECL_STATE_ENTRY_UINT8(mmc5_gfx_mode);
917 // DECL_STATE_ENTRY_UINT8(mmc5_split_control);
918 // DECL_STATE_ENTRY_UINT8(mmc5_split_bank);
919 DECL_STATE_ENTRY_UINT8(mmc5_irq_enabled);
920 DECL_STATE_ENTRY_UINT8(mmc5_irq_status);
921 DECL_STATE_ENTRY_UINT32(mmc5_irq_line);
922 DECL_STATE_ENTRY_UINT8(vrc7_irq_enabled);
923 DECL_STATE_ENTRY_UINT8(vrc7_irq_counter);
924 DECL_STATE_ENTRY_UINT8(vrc7_irq_latch);
925 DECL_STATE_ENTRY_BOOL(pad_strobe);
926 DECL_STATE_ENTRY_UINT8(pad1_bits);
927 DECL_STATE_ENTRY_UINT8(pad2_bits);
928 DECL_STATE_ENTRY_BOOL(kb_out);
929 DECL_STATE_ENTRY_UINT8(kb_scan);
933 void MEMORY::save_state(FILEIO* state_fio)
935 if(state_entry != NULL) {
936 state_entry->save_state(state_fio);
938 // state_fio->FputUint32(STATE_VERSION);
939 // state_fio->FputInt32(this_device_id);
941 // state_fio->Fwrite(save_file_name, sizeof(save_file_name), 1);
942 // state_fio->Fwrite(&header, sizeof(header), 1);
943 // state_fio->FputUint32(rom_size);
944 //// state_fio->FputUint32(rom_mask);
945 // state_fio->Fwrite(rom, rom_size, 1);
946 // state_fio->Fwrite(ram, sizeof(ram), 1);
947 // state_fio->Fwrite(save_ram, sizeof(save_ram), 1);
948 // state_fio->FputUint32(save_ram_crc32);
949 // state_fio->Fwrite(banks, sizeof(banks), 1);
950 // state_fio->FputUint16(dma_addr);
951 // state_fio->FputUint8(frame_irq_enabled);
952 // state_fio->Fwrite(mmc5_wram_bank, sizeof(mmc5_wram_bank), 1);
953 // state_fio->Fwrite(mmc5_chr_reg, sizeof(mmc5_chr_reg), 1);
954 // state_fio->FputUint32(mmc5_value0);
955 // state_fio->FputUint32(mmc5_value0);
956 // state_fio->FputUint8(mmc5_wram_protect0);
957 // state_fio->FputUint8(mmc5_wram_protect1);
958 // state_fio->FputUint8(mmc5_prg_size);
959 // state_fio->FputUint8(mmc5_chr_size);
960 // state_fio->FputUint8(mmc5_gfx_mode);
961 // state_fio->FputUint8(mmc5_split_control);
962 // state_fio->FputUint8(mmc5_split_bank);
963 // state_fio->FputUint8(mmc5_irq_enabled);
964 // state_fio->FputUint8(mmc5_irq_status);
965 // state_fio->FputUint32(mmc5_irq_line);
966 // state_fio->FputUint8(vrc7_irq_enabled);
967 // state_fio->FputUint8(vrc7_irq_counter);
968 // state_fio->FputUint8(vrc7_irq_latch);
969 // state_fio->FputBool(pad_strobe);
970 // state_fio->FputUint8(pad1_bits);
971 // state_fio->FputUint8(pad2_bits);
972 // state_fio->FputBool(kb_out);
973 // state_fio->FputUint8(kb_scan);
976 bool MEMORY::load_state(FILEIO* state_fio)
979 if(state_entry != NULL) {
980 mb = state_entry->load_state(state_fio);
982 if(!mb) return false;
983 // if(state_fio->FgetUint32() != STATE_VERSION) {
986 // if(state_fio->FgetInt32() != this_device_id) {
989 // state_fio->Fread(save_file_name, sizeof(save_file_name), 1);
990 // state_fio->Fread(&header, sizeof(header), 1);
991 // rom_size = state_fio->FgetUint32();
992 //// rom_mask = state_fio->FgetUint32();
993 rom_mask = (rom_size / 0x2000) - 1;
997 // rom = (uint8_t *)malloc(rom_size);
998 // state_fio->Fread(rom, rom_size, 1);
999 // state_fio->Fread(ram, sizeof(ram), 1);
1000 // state_fio->Fread(save_ram, sizeof(save_ram), 1);
1001 // save_ram_crc32 = state_fio->FgetUint32();
1002 // state_fio->Fread(banks, sizeof(banks), 1);
1003 // dma_addr = state_fio->FgetUint16();
1004 // frame_irq_enabled = state_fio->FgetUint8();
1005 // state_fio->Fread(mmc5_wram_bank, sizeof(mmc5_wram_bank), 1);
1006 // state_fio->Fread(mmc5_chr_reg, sizeof(mmc5_chr_reg), 1);
1007 // mmc5_value0 = state_fio->FgetUint32();
1008 // mmc5_value0 = state_fio->FgetUint32();
1009 // mmc5_wram_protect0 = state_fio->FgetUint8();
1010 // mmc5_wram_protect1 = state_fio->FgetUint8();
1011 // mmc5_prg_size = state_fio->FgetUint8();
1012 // mmc5_chr_size = state_fio->FgetUint8();
1013 // mmc5_gfx_mode = state_fio->FgetUint8();
1014 // mmc5_split_control = state_fio->FgetUint8();
1015 // mmc5_split_bank = state_fio->FgetUint8();
1016 // mmc5_irq_enabled = state_fio->FgetUint8();
1017 // mmc5_irq_status = state_fio->FgetUint8();
1018 // mmc5_irq_line = state_fio->FgetUint32();
1019 // vrc7_irq_enabled = state_fio->FgetUint8();
1020 // vrc7_irq_counter = state_fio->FgetUint8();
1021 // vrc7_irq_latch = state_fio->FgetUint8();
1022 // pad_strobe = state_fio->FgetBool();
1023 // pad1_bits = state_fio->FgetUint8();
1024 // pad2_bits = state_fio->FgetUint8();
1025 // kb_out = state_fio->FgetBool();
1026 // kb_scan = state_fio->FgetUint8();
1029 if(header.mapper() == 5) {
1030 for(int i = 3; i < 8; i++) {
1031 mmc5_set_wram_bank(i, mmc5_wram_bank[i]);
1034 for(int i = 4; i < 8; i++) {
1035 set_rom_bank(i, banks[i]);
1037 bank_ptr[3] = save_ram;