Page 1 of 1

C++ memory problem

Posted: Wed Mar 10, 2010 1:17 pm
by ehguacho
ok this is my problem: i'm using a Turbo C++ Windows-based compiler to develop a Nintendo NES emulator. i have to reserve memory space for the RAM memory. as I saw in the XNES emulator source code it did like this:

Code: Select all

RAM = (byte *)malloc( 0x10000 );
...but when I do that on my compiler it return an error. it's seems like there's no enough memory on my computer, but i know it's a compiler error. this error always comes out when trying to reserve a block a memory higher than 65535 (no that 0x10000 = 65536).

why does it happen? how i solve this?

this is the code i get so far (please don't laugh XD):

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>

void main(void)
{
	FILE *fp;
	char gamename[50];
	int i,RomBanks16kb,VRomBanks8kb,RamBanks8kb;
	unsigned char *mem,*RAM,*ROM,*VRAM,*VROM,*SRAM;
	unsigned long int kbromsize,pc;

	clrscr();
	strcpy(gamename,"demo.nes");
	for(i = 0;i <= strlen(gamename) - 1;i++)
	{
		gamename[i] = toupper(gamename[i]);
	}
	fp = fopen(gamename,"rb");
	if(!fp)
	{
		printf("Error abriendo el archivo %s. Saliendo...",gamename);
		getch();
		exit(1);
	}
	printf("Archivo %s abierto correctamente",gamename);
	rewind(fp);
	fseek(fp,0L,2);
	kbromsize = ftell(fp);
	printf("\nTamano de la rom: %d kb",kbromsize);
	mem = (unsigned char *)malloc(kbromsize);
	rewind(fp);
	fread(mem,1,kbromsize,fp);
	if(!mem)
	{
		printf("\nError alojando la memoria principal. Saliendo...");
		getch();
		exit(1);
	}
	printf("\nArchivo cargado en memoria correctamente");
	if((mem[0] == 'N') && (mem[1] == 'E') && (mem[2] == 'S'))
	{
		printf("\niNes header encontrado");
	}
	else printf("\nEl archivo %s no es una rom de NES. Saliendo...",gamename);
	RomBanks16kb = mem[4];
	VRomBanks8kb = mem[5];
	printf("\n%d banco(s) de memoria ROM",RomBanks16kb);
	printf("\n%d banco(s) de memoria VROM",VRomBanks8kb);
	RAM = (unsigned char *)malloc(0x10000);
	/*ROM = (unsigned char *)malloc(RomBanks16kb * 16 * 1024);
	VRAM = (unsigned char *)malloc(0x4000);
	VROM = (unsigned char *)malloc(VRomBanks8kb * 8 * 1024);
	SRAM = (unsigned char *)malloc(0x100);*/
	if(!RAM)
	{
		printf("\nError alojando la memoria principal. Saliendo...");
		getch();
      exit(1);
	}

	printf("\n\n");
	pc = 0;
	while(pc <= 139)
	{
		if((pc != 0) && (pc % 20 == 0)) printf("\n");
		printf("%2X ",mem[pc]);
		pc++;
	}

	printf("\n\nSaliendo...");
	getch();
	return;
}
i know i can solve this using the "allegro.h" library, but had a few problems using it in all the compilers but Dev-C++ and I refuse to programm in Dev-C++ because it really sucks hard.

any suggestion will be apreciated!

Posted: Wed Mar 10, 2010 1:53 pm
by tepples
If malloc() doesn't allow 64 KiB allocations, then you must be using a 16-bit compiler, and your executables won't work on 64-bit operating systems unless they're running a separate 16- or 32-bit operating system in VirtualBox.

Dev-C++ isn't a compiler; it's an editor that uses MinGW GCC as its compiler. If you don't like Allegro for some reason, you could always use SDL or straight DirectX; if you don't like MinGW, you could always use Visual C++ Express.

Posted: Wed Mar 10, 2010 2:10 pm
by koitsu
It sounds like the compiler and development environment (read: libc) you're using is intended for DOS (16-bit) environments. Assuming that IS your intention:

The compiler isn't letting you make use of anything larger than 65535 bytes because of 16-bit real mode segment limitations (which also means the libc implementation doesn't support XMS/EMS in DOS, so you literally are limited to 64KBytes of memory for your application... and that includes the heap!). In 16-bit mode, memory is segmented into 64KByte portions.

We assembly programmers used to get around this limitation in DOS by using a DOS extender such as DOS32 or DOS4GW, and running our programs in 32-bit protected mode, but that's assembly. You'd need to find a compiler and libc/library set that provides support for 32-bit protected mode.

If making DOS executables IS NOT what you intended (and I hope that's the case!):

You get to learn to make Windows executables! tepples mentioned SDL for graphics/input -- I highly recommend this -- but an alternate is Allegro (icky). I assume SDL works with the MinGW development environment.

Also, with regards to Visual C++, the VirtualDub author just recently blogged about Visual Studio 2010 RC, and his opinion is mostly positive. However, the Express edition is apparently limited (see the section in his post labelled "Editions").

Posted: Wed Mar 10, 2010 4:04 pm
by ehguacho
ok thanks tepples and koitsu! so what should i do now? download an IDE loke Code::Blocks or something like that? sorry about wasting your time, i'm just a newbbie looking for help :(

Posted: Wed Mar 10, 2010 4:32 pm
by Banshaku
VS C++ express 2008 since it's free. The only problem is that the free edition doesn't come with a resource editor, MFC and ATL.

The real issue will be for resources since you're stuck to do them by hand but other editors exist so it shouldn't be that much a big issue.

Posted: Wed Mar 10, 2010 4:33 pm
by ehguacho
ok, i've installed code::blocks + allegro and now the problem's gone :D
thank you all again!