elizeucoder
New member
You should not ignore it.
while(1)
{
fetchopcode(),
interpretopcode();
}
Procedure TNewThread.Draw;
Var
x,y : Byte;
loop_x,loop_y : Byte;
x_pos,y_pos : Byte;
pixel : Byte;
Begin
// Get X and Y coordinates
x := ReadRegister((op_code and $0F00) shr 8);
y := ReadRegister((op_code and $00F0) shr 4);
// Reset VF register
WriteRegister($0F, $00);
for loop_y := 0 to (op_code and $000F)-1 do
Begin
// Assign a variable to current line
pixel := ReadMemory(rI + loop_y);
for loop_x := 0 to 7 do
Begin
// Check each bit to see if it is on or off
if pixel and ($80 shr loop_x) <> 0 then
Begin
x_pos := (x + loop_x);
y_pos := (y + loop_y);
if Display[x_pos + y_pos* 64] = $01 then WriteRegister($0F, $01);
Display[x_pos + y_pos * 64] := Display[x_pos + y_pos * 64] xor 1;
End;
End;
End;
Render(x,y,(op_code and $000F)-1);
End;
Procedure TNewThread.Render(ppx,ppy,lp:Byte);
Var
py,px : word;
x,y : Byte;
Begin
Form1.Image1.Canvas.Pen.Width := 2;
// Form1.Image1.Canvas.Pen.Color := clBlack;
py := ppy*8;
For y := ppy to ppy+lp do
Begin
px := ppx*8;
For x := ppx to ppx+7 do
Begin
If Display[x+y*64] <> 0 then
Begin
Form1.Image1.Canvas.Pen.Color := clGreen;
Form1.Image1.Canvas.Brush.Color := clGreen;
end
else
begin
Form1.Image1.Canvas.Pen.Color := clBlack;
Form1.Image1.Canvas.Brush.Color := clBlack;
end;
Form1.Image1.Canvas.Rectangle(px,py,px+7,py+7);
inc(px,8);
End;
inc(py,8);
End;
// writeln(ff,'end render');
End;
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "SDL.h"
#include "function.h"
/* If we ever needed any constants we'd put 'em here, but we don't need any
* constants */
main(int argc, char **argv)
{
/* generic math variables */
int i;
int n;
int len;
/* SDL specific crap variables */
SDL_Event event;
SDL_Surface* screen = NULL;
SDL_Surface* finalscreen = NULL;
unsigned int realx = 640;
unsigned int realy = 320;
int multiby = realx / 64;
/* SDL crap */
printf("Initializing SDL.\n");
if((SDL_Init(SDL_INIT_EVERYTHING) == -1)) {
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
/* Video crap */
screen = SDL_SetVideoMode(realx, realy, 24, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Couldn't set specified video mode: %s\n",
SDL_GetError());
exit(1);
}
printf("Initializing CHIP-8.\n");
/* All the crap we need for CHIP-8 */
unsigned int memory[0xfff];
unsigned int stack[0xf];
unsigned int V[0xf];
unsigned int I; // I ain't telling you what this is for.
unsigned int DT = 0;
unsigned int ST = 0;
unsigned int PC = 0x0;
unsigned int SP = 0x0;
unsigned int opcode;
unsigned int key[0xf];
/* set all the crappy keys to zero */
for (i = 0x0; i <= 0xf; i++)
key[i] = 0x0;
unsigned int xres = 64;
unsigned int yres = 32;
/* Put other crap variables here... */
Uint32 color0 = SDL_MapRGB(screen->format, 0, 0, 0);
Uint32 color1 = SDL_MapRGB(screen->format, 170, 170, 170);
Uint32 cpixel;
int wrapx = 0, wrapy = 0;
printf("Opening ROM...\n");
/* File loading crap */
FILE *f = fopen(argv[1], "rb");
fread(&memory, 1, 4096, f);
fclose(f);
printf("ROM loaded.\nRunning happily.\n");
/* The crappy main loop */
for(;;) {
/* TODO: program should exit when ESC is hit */
opcode = memory[PC++];
/* WARNING: massive switch statement */
switch (opcode) {
case 0x0:
if ((opcode& 0x00ff) == 0xe0) {
/* I've gone blind!!! */
SDL_FillRect(SDL_GetVideoSurface(), NULL, color0);
break;
}
if ((opcode& 0x00ff) == 0xee) {
/* What is this I don't even... */
PC = stack + SP;
SP--;
break;
}
break;
case 0x1:
/* Dangnabit */
PC = opcode& 0x0fff;
break;
case 0x2:
/* I hope she made lots of spaghetti code! */
SP++;
stack[SP] = PC;
PC = opcode& 0x0ff;
break;
case 0x3:
/*-*/ // Cassette tape?
if (V[opcode& 0x0f00] == (opcode& 0x00ff))
PC += 2;
break;
case 0x4:
/* GYIYG lives. */
if (V[opcode& 0x0f00] != (opcode& 0x00ff))
PC += 2;
break;
case 0x5:
/* *fart* */
if (V[opcode& 0x0f00] == (opcode& 0x00f0))
PC += 2;
break;
case 0x6:
/* Do I have to put a comment on every one of these? */
V[opcode& 0x0f00] = (opcode& 0x00ff);
break;
case 0x7:
/* VX = VX + KK */
V[opcode& 0x0f00] += (opcode& 0x00ff);
break;
case 0x8:
/* Low level programming is fun for the first 10 minutes. */
/* On a serious note, this section deals with bitwise
* operations */
if ((opcode& 0x000f) == 0) {
V[opcode& 0x0f00] = (opcode& 0x00f0);
break;
}
if ((opcode& 0x000f) == 0x1) {
V[opcode& 0x0f00] |= V[opcode& 0x00f0];
break;
}
if ((opcode& 0x000f) == 0x2) {
V[opcode& 0x0f00] &= V[opcode& 0x00f0];
break;
}
if ((opcode& 0x000f) == 0x3) {
V[opcode& 0x0f00] ^= V[opcode& 0x00f0];
break;
}
if ((opcode& 0x000f) == 0x4) {
V[opcode& 0x0f00] += V[opcode& 0x00f0];
if (V[opcode& 0x0f00] > 255)
V[0xf] = 1;
break;
}
if ((opcode& 0x000f) == 0x5) {
V[opcode& 0x0f00] -= V[opcode& 0x00f0];
if (V[opcode& 0x0f00] >= V[opcode& 0x00f0])
V[0xf] = 1;
else
V[0xf] = 0;
}
if ((opcode& 0x000f) == 0x6) {
if ((V[opcode& 0x0f00]& 0x0) == 1)
V[0xf] = 1;
V[opcode& 0x0f00] /= 2;
break;
}
if ((opcode& 0x000f) == 0x7) {
V[opcode& 0x00f0] -= V[opcode& 0x0f00];
if (V[opcode& 0x00f0] >= V[opcode& 0x0f00])
V[0xf] = 1;
else
V[0xf] = 0;
break;
}
if ((opcode& 0x000f) == 0xe) {
V[opcode& 0x0f00] *= 2;
if ((V[opcode& 0x0f00]& 0xf) == 1)
V[0xf] = 1;
break;
}
break;
case 0x9:
if (V[opcode& 0x0f00] != V[opcode& 0x00f0]) {
PC += 2;
break;
}
break;
case 0xa:
I = (opcode& 0x0fff);
break;
case 0xb:
PC = (opcode& 0x0fff) + V[0];
break;
case 0xc:
/* Oh no random! */
srand(time(NULL));
V[opcode& 0x0f00] = rand() & (opcode& 0x00ff);
break;
case 0xd:
/* Some sprite drawing! */
for (n = (opcode& 0x000f); n > 0; n--) {
while(V[opcode& 0x0f00] + len - wrapx > xres)
wrapx += xres;
while(V[opcode& 0x00f0] + n - wrapy > yres)
wrapy += yres;
len = 0;
PC = memory[I];
while (len <= 8) {
if (SDL_MUSTLOCK(screen)) {
if (SDL_LockSurface(screen) < 0) {
fprintf(stderr, "Can't lock screen: %s\n",
SDL_GetError());
exit(1);
}
}
cpixel = getpixel(screen, V[opcode& 0x0f00] + len,
V[opcode& 0x00f0] + n);
if (cpixel == color1)
V[0xf] = 1;
if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
if (SDL_MUSTLOCK(screen)) {
if (SDL_LockSurface(screen) < 0) {
fprintf(stderr, "Can't lock screen: %s\n",
SDL_GetError());
exit(1);
}
}
putpixel(screen, V[opcode& 0x0f00] + len - wrapx,
V[opcode& 0x00f0] + n - wrapy, color1);
if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
len++;
}
}
break;
case 0xe:
if ((opcode& 0x00ff) == 0x9e) {
if (key[opcode& 0x0f00] != 0)
PC += 2;
break;
}
if ((opcode& 0x00ff) == 0xa1) {
if (key[opcode& 0x0f00] == 0)
PC += 2;
break;
}
break;
case 0xf:
if ((opcode& 0x00ff) == 0x07) {
V[opcode& 0x0f00] = DT;
break;
}
if ((opcode& 0x00ff) == 0x0a) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_1:
key[0x1] = 1;
V[opcode& 0x0f00] = 0x1;
break;
case SDLK_2:
key[0x2] = 1;
V[opcode& 0x0f00] = 0x2;
break;
case SDLK_3:
key[0x3] = 1;
V[opcode& 0x0f00] = 0x3;
break;
case SDLK_4:
key[0xc] = 1;
V[opcode& 0x0f00] = 0xc;
break;
case SDLK_QUOTE:
key[0x4] = 1;
V[opcode& 0x0f00] = 0x4;
break;
case SDLK_COMMA:
key[0x5] = 1;
V[opcode& 0x0f00] = 0x5;
break;
case SDLK_PERIOD:
key[0x6] = 1;
V[opcode& 0x0f00] = 0x6;
break;
case SDLK_p:
key[0xd] = 1;
V[opcode& 0x0f00] = 0xd;
break;
case SDLK_a:
key[0x7] = 1;
V[opcode& 0x0f00] = 0x7;
break;
case SDLK_o:
key[0x8] = 1;
V[opcode& 0x0f00] = 0x8;
break;
case SDLK_e:
key[0x9] = 1;
V[opcode& 0x0f00] = 0x9;
break;
case SDLK_u:
key[0xe] = 1;
V[opcode& 0x0f00] = 0xe;
break;
case SDLK_SEMICOLON:
key[0xa] = 1;
V[opcode& 0x0f00] = 0xa;
break;
case SDLK_q:
key[0x0] = 1;
V[opcode& 0x0f00] = 0x0;
break;
case SDLK_j:
key[0xb] = 1;
V[opcode& 0x0f00] = 0xb;
break;
case SDLK_k:
key[0xf] = 1;
V[opcode& 0x0f00] = 0xf;
break;
default:
break;
}
break;
}
for (i = 0x0; i <= 0xf; i++)
key[i] = 0x0;
break;
}
break;
}
if ((opcode& 0x00ff) == 0x15) {
DT = V[opcode& 0x0f00];
break;
}
if ((opcode& 0x00ff) == 0x18) {
ST = V[opcode& 0x0f00];
break;
}
if ((opcode& 0x00ff) == 0x1e) {
I += V[opcode& 0x0f00];
break;
}
if ((opcode& 0x00ff) == 0x29) {
/* TODO: Hexadecimal font */
break;
}
if ((opcode& 0x00ff) == 0x33) {
/* TODO: BCD */
break;
}
if ((opcode& 0x00ff) == 0x55) {
for (i = 0x0; i <= (opcode& 0x0f00); i++) {
memory[I] = V[i];
I++;
}
break;
}
if ((opcode& 0x00ff) == 0x65) {
for (i = 0x0; i <= (opcode& 0xf00); i++) {
V[i] = memory[I];
I++;
}
break;
}
break;
default:
break;
}
SDL_UpdateRect(finalscreen, 0, 0, 0, 0);
PC += 2;
}
/* printf("THE WHOLE UNIVERSE IS GOING TO DIE!!!\n"); */
printf("Shutting down...\n");
SDL_Quit();
printf("Bye.\n");
exit(0);
}
case 0xa:
I = (opcode& 0x0fff);
// You should put PC += 2 here;
break;
What Doom (We are all DOOMED I TELL YA! err...) is trying to tell you it is good debugging/programming practice to be sure you do something in a place where it is most consistent. In this case after you have read a complete opcode (IE the opcode is now in your pile of data) you don't need a pointer to the current instruction. Therefore you can advance the PC there.A better solution might be to increment the PC at one place instead of several places. So after processing an opcode, add 2 to the PC. Not after each opcode.
c6b026a
b6daeaa2
366d422
7f015f0
87717c7
eaa271d6
a1e00160
27ba1e0
c60b6da
a1e00d60
d6dc028d
94878486
12871f61
82123f46
1690047
1630268
fe688a12
13fd580
13f1580
c812013f
2060c212
d422348e
fe680366
ff791612
179c812
18f00460
6c12fe76
29f165f2
157455d4
8080ee00
80
m_pd3dDevice ->CreateTexture(64, 32, 1, 0, D3DFMT_LIN_A8R8G8B8, D3DPOOL_DEFAULT, &display, 0);
display->LockRect(0,&rect,NULL, NULL);
BYTE* pByte =(BYTE*)rect.pBits;
for (DWORD y=0;y<32;++y)
{
for (DWORD x=0;x<64;++x)
{
DWORD index = (x*4)+(y*rect.Pitch);
pByte[index] = (BYTE)(screen[(y*64) + x] == 0 ? 0x00 : 0xFF);
pByte[index+1] = (BYTE)(screen[(y*64) + x] == 0 ? 0x00 : 0xFF);
pByte[index+2] = (BYTE)(screen[(y*64) + x] == 0 ? 0x00 : 0xFF);
pByte[index+3] = (BYTE)(screen[(y*64) + x] == 0 ? 0x00 : 0xFF);
}
}
display->UnlockRect(0);