hi! i'm trying to programm a Nintendo NES emulator. i've coded some opcodes (NES uses a 6502 processor) and them worked perfectly. but now i'm trying to allocate a piece of memory and i get this error.
after the error, a blue line appears on the line "switch(memory[pc])" and i can't figure out why does it happen, i can't find the error. is it inside of the "switch" instruccion or is it in the "pc" (program counter) variable!? what i'm trying to do is to copy a piece of memory from the NES game rom file to the memory (a piece of memory wich should start at 0x8000). please somebody help me! :(
this is the full source code of my programm.
you can download it from here:
http://www.mediafire.com/download.php?gngttewd432
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <mem.h>
#include <alloc.h>
#define ADDR ((memory[pc + 2] << 8) | memory[pc + 1])
#define PUSH(a) memory[SP + 0x100] = (a); SP--
#define PULL() memory[(++SP) + 0x100]
void main(void)
{
FILE *fp;
unsigned char *memory; // Vector de memoria ROM (PRG Rom)
int i = 0;
unsigned int pc; // Contador de programa
int AR = 0; // Registro A
int XR = 0; // Registro X
int YR = 0; // Registro Y
int C_FLAG = 0; // Carry flag
int S_FLAG = 0; // Sign flag
int Z_FLAG = 0; // Zero flag
int SP = 0xFF; // Puntero a pila
int mirroring; // 0 = Horizontal 1 = Vertical
int trainer, battery;
int ROM_BANKS,VROM_BANKS,CART_SIZE;
int PRGROM_SIZE;
clrscr();
// Carga del archivo
fp = fopen("jumpy.nes","rb");
if(!fp)
{
printf("No se encontro el archivo\n");
getch();
exit(1);
}
else printf("Archivo encontrado\n");
// Cantidad de bancos de ROM y VROM y tamaño del cartucho
fseek(fp,4,0);
ROM_BANKS = fgetc(fp);
VROM_BANKS = fgetc(fp);
printf("%d banco(s) de PRG Rom\n%d banco(s) de CHR Ram\n",ROM_BANKS,VROM_BANKS);
CART_SIZE = ROM_BANKS * 16 + VROM_BANKS * 8;
printf("Tamaño del cartucho: %d kb\n",CART_SIZE);
// Mirroring, Battery, Trainer
fseek(fp,6,0);
switch(fgetc(fp))
{
case 0x0: // Mirroring horizontal
mirroring = 0;
printf("Mirroring: horizontal\nBattery: NO\nTrainer: NO\n");
break;
case 0x1: // Mirroring vertical
mirroring = 1;
printf("Mirroring: vertical\nBattery: NO\nTrainer: NO\n");
break;
case 0x2: // Mirroring horizonal + Battery
mirroring = 0;
battery = 1;
printf("Mirroring: horizontal\nBattery: SI\nTrainer: NO\n");
break;
case 0x3: // Mirroring vertical + Battery
mirroring = 1;
battery = 1;
printf("Mirroring: vertical\nBattery: SI\nTrainer: NO\n");
break;
case 0x4: // Mirroring horizontal + Trainer
mirroring = 0;
trainer = 1;
printf("Mirroring: horizontal\nBattery: NO\nTrainer: SI\n");
break;
case 0x5: // Mirroring vertical + Trainer
mirroring = 1;
trainer = 1;
printf("Mirroring: vertical\nBattery: NO\nTrainer: SI\n");
break;
case 0x6: // Mirroring horizontal + Battery + Trainer
mirroring = 0;
battery = 1;
trainer = 1;
printf("Mirroring: horizontal\nBattery: SI\nTrainer: SI\n");
break;
case 0x7: // Mirroring vertical + Baterry + Trainer
mirroring = 1;
battery = 1;
trainer = 1;
printf("Mirroring: vertical\nBattery: SI\nTrainer: SI\n");
break;
}
// Alojamiento de la memoria
PRGROM_SIZE = ROM_BANKS * 16 * 1024;
memory = (unsigned char *)malloc(PRGROM_SIZE);
if(!memory)
{
printf("No se pudo alojar la memoria\n");
getch();
free(memory);
fclose(fp);
exit(1);
}
else printf("Memoria alojada correctamente\n\n");
memset(memory,0,PRGROM_SIZE);
// Carga del cartucho en memoria
fseek(fp,16,0);
fread(&memory[0x8000],1,PRGROM_SIZE,fp);
// Emulacion del procesador
pc = 0x8000;
//for(i=0;i<=10;i++)
for(;;)
{
while(kbhit())
{
if(getch()==27)
{
free(memory);
fclose(fp);
exit(1);
}
}
switch(memory[pc])
{
case 0x20: // JSR Absolute
printf("%x\tJSR Absolute\n",pc);
PUSH(((pc + 3) >> 8) & 0xFF);
PUSH((pc + 3) & 0xFF);
pc = ADDR;
break;
case 0x60: // RTS Implied
printf("%x\tRTS Implied\n",pc);
pc = PULL();
pc += (PULL() << 8);
break;
case 0x78: // SEI Implied
printf("%x\tSEI Implied\n",pc);
pc++;
break;
case 0x88: // DEY Implied
printf("%x\tDEY Implied\n",pc);
YR = (YR--) & 0xFF;
S_FLAG = YR & 0x80;
Z_FLAG = !(YR);
pc++;
break;
case 0x8C: // STY Absolute,X
printf("%x\tSTY Absolute,X\n",pc);
memory[ADDR] = YR;
pc += 3;
break;
case 0x8D: // STA Absolute
printf("%x\tSTA Aboslute\n",pc);
memory[ADDR] = AR;
pc += 3;
break;
case 0xA1: // LDA (Indirect,X)
printf("%x\tLDA (Indirect,X)\n",pc);
AR = memory[(((memory[pc + 1] + XR + 1) << 8) | (memory[pc + 1] + XR))];
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 2;
break;
case 0xA2: // LDX Immediate
printf("%x\tLDX Immediate\n",pc);
XR = memory[pc + 1];
S_FLAG = XR & 0x80;
Z_FLAG = !(XR);
pc += 2;
break;
case 0xA5: // LDA Zero Page
printf("%x\tLDA Zero Page\n",pc);
AR = memory[pc + 1];
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 2;
break;
case 0xA9: // LDA Immediate
printf("%x\tLDA Immediate\n",pc);
AR = memory[pc + 1];
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 2;
break;
case 0xAD: // LDA Absolute
printf("%x\tLDA Absolute\n",pc);
AR = memory[ADDR];
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 3;
break;
case 0xB1: // LDA (Indirect),Y
printf("%X\tLDA (Indirect),Y\n",pc);
AR = memory[(((memory[pc + 1] + 1) << 8) | memory[pc + 1]) + YR];
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 2;
break;
case 0xB5: // LDA Zero Page,X
printf("%x\tLDA Zero Page,X\n",pc);
AR = memory[pc + 1] + XR;
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 2;
break;
case 0xB9: // LDA Absolute,Y
printf("%x\nLDA Absolute,Y\n",pc);
AR = memory[ADDR] + YR;
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 3;
break;
case 0xBC: // LDY Absolute,X
printf("%x\tLDY Absolute,X\n",pc);
YR = memory[ADDR] + XR;
S_FLAG = YR & 0x80;
Z_FLAG = !(YR);
pc += 3;
break;
case 0xBD: // LDA Absolute,X
printf("%x\tLDA Absolute,X\n",pc);
AR = memory[ADDR] + XR;
S_FLAG = AR & 0x80;
Z_FLAG = !(AR);
pc += 3;
break;
case 0xC8: // INY Implied
printf("%x\tINY Implied\n",pc);
YR = (YR++) & 0xFF;
S_FLAG = YR & 0x80;
Z_FLAG = !(YR);
pc++;
break;
case 0xD0: // BNE Relative
printf("%x\tBNE Relative\n",pc);
Z_FLAG == 0 ? pc = pc - ((~memory[pc + 1]) & 0xFF) + 1 : pc += 2 ;
break;
case 0xD8: // CLD Implied
printf("%x\tCLD Implied\n",pc);
pc++;
break;
case 0xE0: // CPX Immediate
printf("%x\tCPX Immediate\n",pc);
XR - memory[pc + 1] < 0x100 ? C_FLAG = 1 : C_FLAG = 0;
S_FLAG = (XR - memory[pc + 1]) & 0x80;
Z_FLAG = !(XR - memory[pc + 1]);
pc += 2;
break;
case 0xE8: // INX Implied
printf("%x\tINX Implied\n",pc);
XR = (XR++) & 0xFF;
S_FLAG = XR & 0x80;
Z_FLAG = !(XR);
pc++;
break;
case 0xEA: // NOP Implied
printf("%x\tNOP Implied\n",pc);
pc++;
break;
default:
printf("%x\tMemoria: %x\n",pc,memory[pc]);
pc++;
break;
}
}
free(memory);
fclose(fp);
printf("\nFIN");
return;
}
click here to download the code:
http://www.mediafire.com/download.php?gngttewd432
NOTE: the source code is commented in spanish because i'm from Argentina (so sorry about my poor english too).
i'm using a Windows Turbo C++ compiler.
if anything comes up PLEASE email me at "pajarraco14@hotmail.com".