What's new

Chip 8

ChaosBlade

My Heart Chose.. Revenge.
Then is there some special config modes for use with unmanaged c++ ?

Anyhow, fstream works now (fstream isnt as smart as fopen i guess, if we are in append mode and trying to open a file that doesnt exist, it doesnt create a blank one like fopen, it fails :p).

I really wanna solve the "to mod or not to mod" issue, because as much as i understand, you have to to one of the two:

1) modulate the coordinates, im not sure at which values cause Y%32 BREAKS games like blitz (anyone can run blitz fine with mod at 32 ?).

2) Encapsule the actual codeline that writes to the screen with an if statement to check we havent gone over 0-31 for Y and 0-63 for X.

Correct me if im wrong, so i could tag chip8 as done and move on to schip8 :p
 
Last edited:

smcd

Active member
iostream and fstream are not part of the STL, and using it like <iostream.h> is improper since the latest revision of the C++ standard. "using namespace std;" has nothing to do with "managed C++" at all, it's part of the standard.
 

ChaosBlade

My Heart Chose.. Revenge.
"using namespace std;" isnt part of the C++ Standard as far as i know, the fact is we never needed the std prefix before the .NET ide's. Maybe its part of the .NET\C# standard, but im not coding in those languagues anyway.
I DO know the .h postfix isnt needed for premade headers.

Anyway back on topic, aside from the little issue in my last post im waiting for a response to, the 2nd issue would be wheter to increase or not the Index counter on the save\load opcodes. Id like to get a solid definition on both so i could rest assured they're working and move on ;)
 

Dark Stalker

New member
"using namespace std;" is definitely part of the standard, just Microsoft didn't follow the standard very much (probably to purposely break cross-platform programming) in earlier versions.
 
Last edited:

zenogais

New member
"using namespace" has been a part of the C++ standard for years. Just because MS didn't comply doesn't mean its not part of the C++ standard. Also iostream and fstream are part of the C++ standard libarary not the standard template library, though the STL has constructs like istream_iterator and ostream_iterator that are meant to work with them.
 

Doomulation

?????????????????????????
ChaosBlade said:
"using namespace std;" isnt part of the C++ Standard as far as i know, the fact is we never needed the std prefix before the .NET ide's. Maybe its part of the .NET\C# standard, but im not coding in those languagues anyway.
I DO know the .h postfix isnt needed for premade headers.

Anyway back on topic, aside from the little issue in my last post im waiting for a response to, the 2nd issue would be wheter to increase or not the Index counter on the save\load opcodes. Id like to get a solid definition on both so i could rest assured they're working and move on ;)
All the standard c++ libraries are included in the std namespace, and all c++ standard libraries does not have the .h extension. So the c++ library for iostream would be #include <iostream>.

As for your other questions:
Modulate: you don't need it. Take a look at my source and see I'm not using it. I'm not breaking any games. Only field doesn't work correctly.
Increment I: Do not do this. While some docs may say so, they are incorrect. Dave winter's doc does not tell you to increment them, thus you do not.
About writing off-screen: no game does this afaik, except for field. So either you ignore it or print an error. I ignored it to retain compability for field.

That all your questions, then? :)
 

ChaosBlade

My Heart Chose.. Revenge.
Well, run logs of drawing for pong, blitz and brix.. when the paddles try to go off screen or in blitz when the plane is about to go off screen, there are requests to draw at Y = 32 (unless my emulator is reading something wrong here), which is off-screen as far as i can tell since it also writes at Y = 0 sometimes, 0-32 == 33 Pixels.

About ignoring it - I cant not account for it in my emulator, because if it tries writing to #32 when my array is 0-31, it will access some protected memory it should not.
 

ChaosBlade

My Heart Chose.. Revenge.
Its not a problem going around that programming wise, it just seems odd to me that games were programmed to write to 0-32 when the screen is only 32 pixels.

Anyway, im clearing up things, maybe switching to jump tables and such, and moving on to schip opcodes.
 

ShizZy

Emulator Developer
After trying to write a GB emu, I realized the best bet was to come back and write a Chip8 emulator first. So that's what I did. Took about 2 days... 1 day to write it, and another to figure out why it wasn't working :p Just about every game seems to run fine, despite a few minor glitches in some of them. It emulates everything but user input, which is *almost* done. Once I do that, I'm going to go back and work on GB. Though I'll probably find myself back here again trying to emulate super chip8. Oh well :p Here's some shots...
 

secretemu

Future Emu Creator Hopefully
nice one ;)

lately ive been rearching
i learned most things about bit shifting (preety easy)and oher manipulations.
helped me understand emu a bit better. get it (bit better)

from reading documentations and other stuff its quite obvious that you emulate the cpu first. can anyone show me an example of what you do and he order it goes in.

any tutorials on opening bin files and puting it into the computers memroy at least thats what i think you do. thanks in advanced
im using c++.
 

ShizZy

Emulator Developer
Hey secretemu, it's all relativelly simple. The general process I use is to make the window and initialize whatever API I am using first, set up the ROM loader, and then program the CPU/Interpreter. That way I can load roms and test it before I finish. There's a number of tuts on the CPU already, so I won't go into that, but to load a ROM into memory, you would do something like this:

Code:
        fileHandle = fopen( fileloc, "rb" );
        unsigned char romsize = 0xFFF;

	bytenum = fread(memory+0x200,romsize,1,fileHandle);

	// double check that rom loaded properly
	// ----------------
	if (!bytenum || !cpu.memory){
                // error message here, rom didnt load
		return FALSE;
	}

	fclose( fileHandle );
        return;

What that does is copy the file with the path name of fileloc (either code an open dialog, or prompt the user for the path), into memory. memory is an unsigned character variable. It also tells the program to read romsize bytes, which is 0xFFF, the max size of a chip8 rom. Keep in mind, memory isn't setup to load that much, so you need to allocate the space. So, somewhere before you call the rom loading function, add this line:

Code:
cpu.memory = (unsigned char*)malloc(0xFFF))

Now, you're rom is loaded into your chip8 memory. Simple as that. All you need to do now is grab the opcode in your CPU loop, which is as simple as:

Code:
 opcode = ((memory[PC]<<8) + cpu.memory[PC+1]); // grab the op

The variable PC is of course your program counter, which get's incremented by 2 bytes every CPU loop. Remember to start it out at 0x200, because that's were the game data begins in the ROM.

Just a little lesson :happy: Assuming that you're using C/C++, but if not - it's all the same idea. If you... or anyone else, needs help - feel free to message me. I'll do what I can!
 

secretemu

Future Emu Creator Hopefully
thanks it finally makes sence to me now. im running experiment with hex and bin. is it possible to load the bin and convert it to hex or normal real numbers before emulating it ( doesn't really matter if you donk know its only to learn more about emu. you helped me a lot inaway thanks:party:
 

secretemu

Future Emu Creator Hopefully
wait im still stuck here is an example of how to load text

BOOL LoadFile(HWND hEdit, LPSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;

hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if(dwFileSize != 0xFFFFFFFF)
{
LPSTR pszFileText;
pszFileText = (LPSTR)GlobalAlloc(GPTR, dwFileSize - 0);
if(pszFileText != NULL)
{
DWORD dwRead;
if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
{
pszFileText[dwFileSize] = 0; // Null terminator
if(SetWindowText(hEdit, pszFileText))
bSuccess = TRUE; // It worked!
}
GlobalFree(pszFileText);
}
}
CloseHandle(hFile);
}
return bSuccess;
}



how would i modify this to load the bin into the text file
(what i mean is how do i load all the numbers)
aka bits
hope this makes sence

thanks again

ps: is memory an unsigned char becaues it must be 1 bit in size
 
Last edited:

ShizZy

Emulator Developer
Well, keep in mind - to a computer, all the number formats are the same. Say you had a variable X, it would be read exactly the same as X=0xF (hexidecimal for 15), or X=15. With that in mind, to write to a text file, you can do something like this:

Code:
void WriteFile(char fileloc[])
{
     FILE *handle;

     // create the text file for writing
     handle = fopen("log.txt", "w");

     // write to it
     fprintf(handle, "Here is the memory:\n %x ", memory);

     // close the file
     fclose( handle );
}

That function simply creates the file handle, and opens the file log.txt for writing (or creates it if it does not exist). Then, it uses the fprintf command to copy the phrase "Here is the memory:", and then spit out the memory variable after it. Lastly, the file handle is closed.
 

secretemu

Future Emu Creator Hopefully
i cant compile it i dont know if i typed it in the wrong way or not
could you give me a full example of loading the bin for me to compare it with mine
(i suppose your sick of me asking you for requests sorry)
 

ShizZy

Emulator Developer
That's all there is too it. Make sure memory is a global variable, if not then add extern unsigned char memory; somewhere in that file so the compiler knows to use it. You might be getting errors if you're not including the proper headers. Add these to that CPP file:

Code:
#include <windows.h>
#include <memory.h>
#include <stdio.h>
#include <commctrl.h>
#include <commdlg.h>

You might not need all of them, but the file functions lie in commdlg.h, and it may rely on some of the others (esp. windows.h).
 

secretemu

Future Emu Creator Hopefully
sorry about the confusion i was talking about a win 32 app

eg.
#include <windows.h>

#define IDC_MAIN_TEXT 1001

BOOL LoadFile(HWND hEdit, LPSTR pszFileName)
{
HANDLE hFile;
BOOL bSuccess = FALSE;

hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if(dwFileSize != 0xFFFFFFFF)
{
LPSTR pszFileText;
pszFileText = (LPSTR)GlobalAlloc(GPTR, dwFileSize - 0);
if(pszFileText != NULL)
{
DWORD dwRead;
if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
{
pszFileText[dwFileSize] = 0; // Null terminator
if(SetWindowText(hEdit, pszFileText))
bSuccess = TRUE; // It worked!
}
GlobalFree(pszFileText);
}
}
CloseHandle(hFile);
}
return bSuccess;
}


/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)

{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */

/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);

/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;

/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);

/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}

/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}


/* This function is called by the Windows function DispatchMessage() */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
CreateWindow("EDIT", "",
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE |
ES_WANTRETURN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwnd, (HMENU)IDC_MAIN_TEXT, g_hInst, NULL);



case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}

when i was asking before what i ment was how do i load bins in general onto IDC_MAIN_TEXT as it is above.
thank again
 
Last edited:

Top