245 lines
7.7 KiB
C
245 lines
7.7 KiB
C
#include "dump.h"
|
|
|
|
/* Desc:Dump cart memory into buffer's data array
|
|
* Pre: buffer elements must be updated to designate how/where to dump
|
|
* buffer's cur_byte must be cleared or set to where to start dumping
|
|
* Post:page dumped from cart memory to buffer.
|
|
* Rtn: SUCCESS or ERROR# depending on if there were errors.
|
|
*/
|
|
uint8_t dump_buff( buffer *buff ) {
|
|
|
|
uint8_t addrH = buff->page_num; //A15:8 while accessing page
|
|
uint8_t bank;
|
|
|
|
switch ( buff->mem_type ) {
|
|
#ifdef NES_CONN
|
|
case NESCPU_4KB:
|
|
//mapper lower nibble specifies NES CPU A12-15
|
|
if (buff->mapper > 0x0F) {
|
|
//mapper can only be 4bits (0-15)
|
|
return ERR_BUFF_PART_NUM_RANGE;
|
|
}
|
|
addrH |= (buff->mapper << 4); // 8 << 12 = shift by 4
|
|
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case NESCPU_4KB_TOGGLE:
|
|
//mapper lower nibble specifies NES CPU A12-15
|
|
if (buff->mapper > 0x0F) {
|
|
//mapper can only be 4bits (0-15)
|
|
return ERR_BUFF_PART_NUM_RANGE;
|
|
}
|
|
addrH |= (buff->mapper << 4); // 8 << 12 = shift by 4
|
|
buff->cur_byte = nes_cpu_page_rd_toggle( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case NESPPU_1KB:
|
|
//mapper bits 2-5 specifies NES PPU A10-13
|
|
if (buff->mapper & 0xC3) { //make sure bits 7, 6, 1, & 0 aren't set
|
|
//mapper can only have bits 2-5 set
|
|
return ERR_BUFF_PART_NUM_RANGE;
|
|
}
|
|
addrH |= buff->mapper; // PPU A10-13 get set based on mapper
|
|
buff->cur_byte = nes_ppu_page_rd_poll( buff->data, addrH, buff->id,
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case NESPPU_1KB_TOGGLE:
|
|
//mapper bits 2-5 specifies NES PPU A10-13
|
|
if (buff->mapper & 0xC3) { //make sure bits 7, 6, 1, & 0 aren't set
|
|
//mapper can only have bits 2-5 set
|
|
return ERR_BUFF_PART_NUM_RANGE;
|
|
}
|
|
addrH |= buff->mapper; // PPU A10-13 get set based on mapper
|
|
buff->cur_byte = nes_ppu_page_rd_toggle( buff->data, addrH, buff->id,
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case NESCPU_PAGE:
|
|
//mapper byte specifies CPU A15-8
|
|
addrH |= buff->mapper;
|
|
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case NESPPU_PAGE:
|
|
//mapper byte specifies PPU A13-8
|
|
if (buff->mapper & 0xC0) { //make sure bits 7, 6 aren't set
|
|
//mapper can only have bits 5-0 set
|
|
return ERR_BUFF_PART_NUM_RANGE;
|
|
}
|
|
addrH |= buff->mapper; // PPU A10-13 get set based on mapper
|
|
buff->cur_byte = nes_ppu_page_rd_poll( buff->data, addrH, buff->id,
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
#endif
|
|
|
|
#ifdef SNES_CONN
|
|
case SNESROM_PAGE: //ROMSEL is always taken low
|
|
//mapper byte specifies SNES CPU A15-8
|
|
addrH |= (buff->mapper); //no shift needed
|
|
buff->cur_byte = snes_page_rd_poll( buff->data, addrH, 0, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
|
|
case SNESSYS_PAGE: //ROMSEL stays high
|
|
//mapper byte specifies SNES CPU A15-8
|
|
addrH |= (buff->mapper); //no shift needed
|
|
buff->cur_byte = snes_page_rd_poll( buff->data, addrH, 1, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
#endif
|
|
|
|
#ifdef GB_CONN
|
|
case GAMEBOY_PAGE:
|
|
//mapper byte specifies CPU A15-8
|
|
addrH |= buff->mapper;
|
|
buff->cur_byte = gameboy_page_rd_poll( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, 1 );
|
|
break;
|
|
case GBA_ROM_PAGE:
|
|
//address must have already been latched
|
|
//we're only telling page_rd the number of bytes to read, and where to put it
|
|
// takes 16bit pointer, 127 / 2 = 63.5 -> 63 so it works
|
|
buff->cur_byte = gba_page_rd( (uint16_t*)buff->data, (buff->last_idx>>1) );
|
|
//buff->cur_byte = gba_page_rd( buff->data, buff->last_idx );
|
|
break;
|
|
#endif
|
|
|
|
#ifdef SEGA_CONN
|
|
case GENESIS_ROM_PAGE0:
|
|
//mapper byte specifies Genesis CPU A15-8
|
|
addrH |= (buff->mapper); //no shift needed
|
|
buff->cur_byte = genesis_page_rd( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx);
|
|
break;
|
|
case GENESIS_ROM_PAGE1:
|
|
//mapper byte specifies Genesis CPU A15-8
|
|
addrH |= (buff->mapper); //no shift needed
|
|
buff->cur_byte = genesis_page_rd( buff->data, addrH+0x0100, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx);
|
|
break;
|
|
#endif
|
|
|
|
#ifdef N64_CONN
|
|
case N64_ROM_PAGE:
|
|
//mapper byte specifies SNES CPU A15-8
|
|
//uint8_t addrH = buff->page_num; //A15:8 while accessing page
|
|
// addrH |= (buff->mapper); //no shift needed
|
|
buff->cur_byte = n64_page_rd( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx);
|
|
break;
|
|
#endif
|
|
|
|
|
|
#ifdef NES_CONN
|
|
case PRGROM:
|
|
addrH |= 0x80; //$8000
|
|
if (buff->mapper == MAP30) {
|
|
//addrH &= 0b1011 1111 A14 must always be low
|
|
addrH &= 0xBF;
|
|
//write bank value to bank table
|
|
//page_num shift by 6 bits A14 >> A8(0)
|
|
bank = (buff->page_num)>>6;
|
|
//mapper register $C000-FFFF
|
|
nes_cpu_wr( 0xC000, bank );
|
|
|
|
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
}
|
|
if (buff->mapper == A53) {
|
|
//write bank value to bank table
|
|
//page_num shift by 7 bits A15 >> A8(0)
|
|
bank = (buff->page_num)>>7;
|
|
//Setup as CNROM, then scroll through outer banks.
|
|
//cpu_wr(0x5000, 0x80); //reg select mode
|
|
// xxSSPPMM SS-size: 0-32KB, PP-prg mode: 0,1 32KB, MM-mirror
|
|
//cpu_wr(0x8000, 0b00000000); //reg value 256KB inner, 32KB banks
|
|
nes_cpu_wr(0x5000, 0x81); //outer reg select mode
|
|
nes_cpu_wr(0x8000, bank); //outer bank
|
|
nes_cpu_wr(0x5000, 0x00); //chr reg select act like CNROM
|
|
}
|
|
/* migrated to script controlled
|
|
if (buff->mapper == EZNSF) {
|
|
//addrH &= 0b1000 1111 A14-12 must always be low
|
|
addrH &= 0x8F;
|
|
//write bank value to bank table
|
|
//page_num shift by 4 bits A12 >> A8(0)
|
|
bank = (buff->page_num)>>4;
|
|
nes_cpu_wr(0x5000, bank); //bank @ $8000-8FFF
|
|
}
|
|
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
*/
|
|
break;
|
|
|
|
case CHRROM: //$0000
|
|
|
|
if (buff->mapper == DPROM) {
|
|
//select bank
|
|
//8KB banks $0000-1FFF
|
|
//page_num shift by 5 bits A13 >> A8(0)
|
|
bank = (buff->page_num)>>5;
|
|
|
|
//write bank to register
|
|
nes_ppu_wr(0x3FFF, bank);
|
|
|
|
addrH &= 0x1F; //only A12-8 are directly addressable
|
|
buff->cur_byte = nes_dualport_page_rd_poll( buff->data, addrH, buff->id,
|
|
buff->last_idx, ~FALSE );
|
|
}
|
|
break;
|
|
|
|
case PRGRAM:
|
|
addrH |= 0x60; //$6000
|
|
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
#endif
|
|
|
|
#ifdef SNES_CONN
|
|
case SNESROM:
|
|
if (buff->mapper == LOROM) {
|
|
addrH |= 0x80; //$8000 LOROM space
|
|
//need to split page_num
|
|
//A14-8 page_num[6-0]
|
|
//A15 high (LOROM)
|
|
//A23-16 page_num[14-7]
|
|
bank = (buff->page_num)>>7;
|
|
}
|
|
if (buff->mapper == HIROM) {
|
|
//need to split page_num
|
|
//A15-8 page_num[7-0]
|
|
//A21-16 page_num[13-8]
|
|
//A22 high (HIROM)
|
|
//A23 ~page_num[14] (bank CO starts first half, bank 40 starts second)
|
|
bank = ((((buff->page_num)>>8) | 0x40) & 0x7F);
|
|
}
|
|
HADDR_SET( bank );
|
|
buff->cur_byte = snes_page_rd_poll( buff->data, addrH, 0, buff->id,
|
|
//id contains MSb of page when <256B buffer
|
|
buff->last_idx, ~FALSE );
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
return ERR_BUFF_UNSUP_MEM_TYPE;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|