Hello, everyone.
1. My emulator executed 43319 instructions after launched AD&D Hillsfar (J), whether my MMC1 implementation manner was wrong?
following is stdout
Write addr 9000 data 1e
Write addr b000 data 0
Write addr ff00 data 0
Write addr ff00 data 1a
Write addr ff00 data 12
执行未文档化的操作码 $92
执行指令总数 43319
执行未文档化的操作码 means CPU executed one bad opcode, maybe CPU not switched
PRG-ROM Bank properly.
执行指令总数 means CPU already executed instructions
2. When my emulator run Double Dragon, a strange thing occured.
When I killed the boss of mission 3 the mission didn't over, I went ahead and wraped to mission 3's start.
Here is my MMC1 implementation using C++:
1. My emulator executed 43319 instructions after launched AD&D Hillsfar (J), whether my MMC1 implementation manner was wrong?
following is stdout
Write addr 9000 data 1e
Write addr b000 data 0
Write addr ff00 data 0
Write addr ff00 data 1a
Write addr ff00 data 12
执行未文档化的操作码 $92
执行指令总数 43319
执行未文档化的操作码 means CPU executed one bad opcode, maybe CPU not switched
PRG-ROM Bank properly.
执行指令总数 means CPU already executed instructions
2. When my emulator run Double Dragon, a strange thing occured.
When I killed the boss of mission 3 the mission didn't over, I went ahead and wraped to mission 3's start.
Here is my MMC1 implementation using C++:
Code:
#ifndef __MAPPER001__H__
#define __MAPPER001__H__
/*********************************************
*
* 2013年12月12日22:46:58
*
* Mapper001 (MMC1)
*
* Example :
* Double Dragon 1
*********************************************/
#include <iostream>
using namespace std;
#include "Mapper.h"
#include "ROMParser.h"
// CPU Memory
extern BYTE *PROM[4];
// PPU Memory
extern BYTE *VROM[8];
class Mapper001 : public Mapper
{
public:
Mapper001(ROMParser *parser):Mapper(parser){
// PROM BANK 16KB
// VROM BANK 4KB
// 开始的16KB
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + i * 0x2000;
}
// 结尾的16KB
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (np - 1) * 0x4000 + i * 0x2000;
}
for(int i = 0;i < 8;i++){
::VROM[i] = Mapper::VROM + i * 0x400;
}
// 清空寄存器
memset(this->reg, 0, sizeof(reg));
// 清空临时寄存器
Reg = 0;
// 写偏移置为0
Pos = 0;
}
void SetData(WORD addr, BYTE data){
if(data & 0x80){ // 复位
Pos = 0;
reg[0] |= 0x0C;
}else{
// 想写入的数据
BYTE b = data & 0x01;
b ? Reg |= (1 << Pos) : Reg &= ~(1 << Pos);
Pos++;
//cout<<"This is "<<hex<<(int)Pos<<"th write addr\t$"<<addr<<"\tdata\t$"<<(int)data<<endl;
if(Pos == 5){ // full
Reg &= 0x1F;
cout<<"Write addr\t"<<hex<<(int)addr<<"\tdata\t"<<(int)Reg<<endl;
if(addr < 0xA000){ // 设置镜像 固定BANK
reg[0] = Reg;
this->Write0();
}else if(addr < 0xC000){ // 设置VROM $0000 8K 或 4K
reg[1] = Reg;
this->Write1();
}else if(addr < 0xE000){ // 设置VROM $1000 4K
reg[2] = Reg;
this->Write2();
}else{ // 设置PROM
reg[3] = Reg;
this->Write3();
}
Pos = 0;
}
}
}
void Load(BYTE* /*data*/, int /*len*/){
cout<<"Mapper未实现加载状态"<<endl;
//system("pause");
}
BYTE* Save(int * /*len*/){
cout<<"Mapper未实现保存状态"<<endl;
//system("pause");
return NULL;
}
private:
BYTE reg[4];
BYTE Reg; // 临时寄存器
BYTE Pos; // 0 ~ 4
void Write0(){
int mirror;
int which = (0x03 & reg[0]);
switch(which){
case 0:
mirror = 2;
break;
case 1:
mirror = 3;
break;
case 2:
mirror = 1;
break;
default:
mirror = 0;
}
ppu->SetMirrorManner( mirror );
// 固定BANK
switch((reg[0] >> 2) & 0x03){
case 2: // fix first bank at $8000
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + i * 0x2000;
}
break;
case 3: // fix last bank at $C000
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (Mapper::np - 1) * 0x4000 + i * 0x2000;
}
break;
}
}
void Write1(){
reg[1] %= 2 * Mapper::nv;
if(0x10 & reg[0]){ // 切换4KB VROM in $0000
for(int i = 0;i < 4;i++){
::VROM[i] = Mapper::VROM + (0x1F & reg[1]) * 0x1000 + 0x400 * i;
}
}else{ // 切换8KB VROM
for(int i = 0;i < 8;i++){
::VROM[i] = Mapper::VROM + (0x1F & reg[1]) * 0x1000 + 0x400 * i;
}
}
}
void Write2(){
if(0x10 & reg[0]){
reg[2] %= 2 * Mapper::nv;
for(int i = 0;i < 4;i++){ // 切换4KB VROM in $1000
::VROM[4 + i] = Mapper::VROM + (0x1F & reg[2]) * 0x1000 + 0x400 * i ;
}
}
}
void Write3(){
if(!(0x08 & reg[0])){ // 切换32KB PROM
//reg[3] %= Mapper::np / 2;
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + ((0x0F & reg[3]) >> 1) * 0x8000 + i * 0x2000;
::PROM[i + 2] = Mapper::PROM + ((0x0F & reg[3]) >> 1) * 0x8000 + i * 0x2000 + 0x4000;
}
}else{ // 切换16KB PROM
//reg[3] %= Mapper::np;
if((0x0c & reg[0]) == 0x0c){ // in $8000
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + (0x0F & reg[3]) * 0x4000 + i * 0x2000;
}
}else if((0x08 & reg[0]) == 0x08){ // in $C000
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (0x0F & reg[3]) * 0x4000 + i * 0x2000;
}
}else{
cout<<"16KB 切换出错"<<endl;
system("pause");
}
}
}
};
#endif
#define __MAPPER001__H__
/*********************************************
*
* 2013年12月12日22:46:58
*
* Mapper001 (MMC1)
*
* Example :
* Double Dragon 1
*********************************************/
#include <iostream>
using namespace std;
#include "Mapper.h"
#include "ROMParser.h"
// CPU Memory
extern BYTE *PROM[4];
// PPU Memory
extern BYTE *VROM[8];
class Mapper001 : public Mapper
{
public:
Mapper001(ROMParser *parser):Mapper(parser){
// PROM BANK 16KB
// VROM BANK 4KB
// 开始的16KB
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + i * 0x2000;
}
// 结尾的16KB
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (np - 1) * 0x4000 + i * 0x2000;
}
for(int i = 0;i < 8;i++){
::VROM[i] = Mapper::VROM + i * 0x400;
}
// 清空寄存器
memset(this->reg, 0, sizeof(reg));
// 清空临时寄存器
Reg = 0;
// 写偏移置为0
Pos = 0;
}
void SetData(WORD addr, BYTE data){
if(data & 0x80){ // 复位
Pos = 0;
reg[0] |= 0x0C;
}else{
// 想写入的数据
BYTE b = data & 0x01;
b ? Reg |= (1 << Pos) : Reg &= ~(1 << Pos);
Pos++;
//cout<<"This is "<<hex<<(int)Pos<<"th write addr\t$"<<addr<<"\tdata\t$"<<(int)data<<endl;
if(Pos == 5){ // full
Reg &= 0x1F;
cout<<"Write addr\t"<<hex<<(int)addr<<"\tdata\t"<<(int)Reg<<endl;
if(addr < 0xA000){ // 设置镜像 固定BANK
reg[0] = Reg;
this->Write0();
}else if(addr < 0xC000){ // 设置VROM $0000 8K 或 4K
reg[1] = Reg;
this->Write1();
}else if(addr < 0xE000){ // 设置VROM $1000 4K
reg[2] = Reg;
this->Write2();
}else{ // 设置PROM
reg[3] = Reg;
this->Write3();
}
Pos = 0;
}
}
}
void Load(BYTE* /*data*/, int /*len*/){
cout<<"Mapper未实现加载状态"<<endl;
//system("pause");
}
BYTE* Save(int * /*len*/){
cout<<"Mapper未实现保存状态"<<endl;
//system("pause");
return NULL;
}
private:
BYTE reg[4];
BYTE Reg; // 临时寄存器
BYTE Pos; // 0 ~ 4
void Write0(){
int mirror;
int which = (0x03 & reg[0]);
switch(which){
case 0:
mirror = 2;
break;
case 1:
mirror = 3;
break;
case 2:
mirror = 1;
break;
default:
mirror = 0;
}
ppu->SetMirrorManner( mirror );
// 固定BANK
switch((reg[0] >> 2) & 0x03){
case 2: // fix first bank at $8000
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + i * 0x2000;
}
break;
case 3: // fix last bank at $C000
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (Mapper::np - 1) * 0x4000 + i * 0x2000;
}
break;
}
}
void Write1(){
reg[1] %= 2 * Mapper::nv;
if(0x10 & reg[0]){ // 切换4KB VROM in $0000
for(int i = 0;i < 4;i++){
::VROM[i] = Mapper::VROM + (0x1F & reg[1]) * 0x1000 + 0x400 * i;
}
}else{ // 切换8KB VROM
for(int i = 0;i < 8;i++){
::VROM[i] = Mapper::VROM + (0x1F & reg[1]) * 0x1000 + 0x400 * i;
}
}
}
void Write2(){
if(0x10 & reg[0]){
reg[2] %= 2 * Mapper::nv;
for(int i = 0;i < 4;i++){ // 切换4KB VROM in $1000
::VROM[4 + i] = Mapper::VROM + (0x1F & reg[2]) * 0x1000 + 0x400 * i ;
}
}
}
void Write3(){
if(!(0x08 & reg[0])){ // 切换32KB PROM
//reg[3] %= Mapper::np / 2;
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + ((0x0F & reg[3]) >> 1) * 0x8000 + i * 0x2000;
::PROM[i + 2] = Mapper::PROM + ((0x0F & reg[3]) >> 1) * 0x8000 + i * 0x2000 + 0x4000;
}
}else{ // 切换16KB PROM
//reg[3] %= Mapper::np;
if((0x0c & reg[0]) == 0x0c){ // in $8000
for(int i = 0;i < 2;i++){
::PROM[i] = Mapper::PROM + (0x0F & reg[3]) * 0x4000 + i * 0x2000;
}
}else if((0x08 & reg[0]) == 0x08){ // in $C000
for(int i = 0;i < 2;i++){
::PROM[i + 2] = Mapper::PROM + (0x0F & reg[3]) * 0x4000 + i * 0x2000;
}
}else{
cout<<"16KB 切换出错"<<endl;
system("pause");
}
}
}
};
#endif