C and C++

Moderators: None (Apply to moderate this forum)
Number of threads: 28630
Number of posts: 94612

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Error in C++ / NES emulator programm Posted by ehguacho on 20 Apr 2009 at 8:14 PM
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".
Report
Re: Error in C++ / NES emulator programm Posted by Lundin on 21 Apr 2009 at 3:43 AM
Are you running that compiler for a 16 bit or 32 bit program?

If 16 bit, then the "int" type is probably not large enough to hold a value of x*16*1024. The max value of an "int" is 32767 or 65535, it depends on the compiler setting. In that case, change PRGROM_SIZE to unsigned int.

Report
Re: Error in C++ / NES emulator programm Posted by ehguacho on 21 Apr 2009 at 9:10 AM
variable "pc" is already an unsigned int
Report
Re: Error in C++ / NES emulator programm Posted by Lundin on 21 Apr 2009 at 11:38 PM
The possible problem would be with malloc(), in case the amount of memory is large enough to overflow the int.

Since you don't tell whether this is 16 or 32 bit, I can't help you further.



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.