Witam, to mój pierwszy post, więc proszę o wyrozumiałość. Piszę emulator chip-8 w c#, ale mam problem, gdyż mój program na ekranie nie zwraca nic (cała tablica LCD jest równa 0). Nie wiem co jest tego powodem, ale podejrzewam, że ma to coś wspólnego z wczytaniem pliku. Wrzuciłem cały kod, więc jest dosyć długi. Z góry dziękuje za pomoc.
chip8.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace testconbil
{
class chip8
{
int[] pamiec;
int[] V; // Flagi
int I; // Indeks rejestrow
int pc; // Licznik Programu {PROGRAM COUNTER}
int[] stos;
int wskaznikStosu;
int licznik_Glowny;
int licznik_Dzwieku;
char[] klawisze;
public int[] LCD;
public bool FlagaRysowania;
public chip8()
{
try
{
pamiec = new int[4096];
V = new int[16];
I = 0x0;
stos = new int[16];
wskaznikStosu = 0;
licznik_Dzwieku = 0;
licznik_Glowny = 0;
klawisze = new char[16];
LCD = new int[2048];
pc = 0x200;
FlagaRysowania = true;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show("Krytyczny blad inicjalizacji.");
}
}
public void Wykonaj()
{
int opcode = (pamiec[pc] << 8) | pamiec[pc + 1];
switch (opcode & 0xF000)
{
case 0x0000:
switch (opcode & 0x000F)
{
case 0x0000:
for (int i = 0; i < 2048; ++i)
LCD[i] = 0x0;
FlagaRysowania = true;
pc += 2;
break;
case 0x000E:
wskaznikStosu--;
pc = stos[wskaznikStosu];
pc += 2;
break;
default:
System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
Environment.Exit(-1);
break;
}
break;
case 0x1000:
pc = opcode & 0x0FFF;
break;
case 0x2000:
stos[wskaznikStosu] = pc;
wskaznikStosu++;
pc = opcode & 0x0FFF;
break;
case 0x3000:
if (V[(opcode & 0x0F00) >> 8] == (opcode & 0x00FF))
pc += 4;
else
pc += 2;
break;
case 0x4000:
if (V[(opcode & 0x0F00) >> 8] != (opcode & 0x00FF))
pc += 4;
else
pc += 2;
break;
case 0x5000:
if (V[(opcode & 0x0F00) >> 8] == V[(opcode & 0x00F0) >> 4])
pc += 4;
else
pc += 2;
break;
case 0x6000:
V[(opcode & 0x0F00) >> 8] = opcode & 0x00FF;
pc += 2;
break;
case 0x7000:
V[(opcode & 0x0F00) >> 8] += opcode & 0x00FF;
pc += 2;
break;
case 0x8000:
switch (opcode & 0x000F)
{
case 0x0000:
V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0001:
V[(opcode & 0x0F00) >> 8] |= V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0002:
V[(opcode & 0x0F00) >> 8] &= V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0003:
V[(opcode & 0x0F00) >> 8] ^= V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0004:
if (V[(opcode & 0x00F0) >> 4] > (0xFF - V[(opcode & 0x0F00) >> 8]))
V[0xF] = 1;
else
V[0xF] = 0;
V[(opcode & 0x0F00) >> 8] += V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0005:
if (V[(opcode & 0x00F0) >> 4] > V[(opcode & 0x0F00) >> 8])
V[0xF] = 0;
else
V[0xF] = 1;
V[(opcode & 0x0F00) >> 8] -= V[(opcode & 0x00F0) >> 4];
pc += 2;
break;
case 0x0006:
V[0xF] = V[(opcode & 0x0F00) >> 8] & 0x1;
V[(opcode & 0x0F00) >> 8] >>= 1;
pc += 2;
break;
case 0x0007:
if (V[(opcode & 0x0F00) >> 8] > V[(opcode & 0x00F0) >> 4]) // VY-VX
V[0xF] = 0;
else
V[0xF] = 1;
V[(opcode & 0x0F00) >> 8] = V[(opcode & 0x00F0) >> 4] - V[(opcode & 0x0F00) >> 8];
pc += 2;
break;
case 0x000E:
V[0xF] = V[(opcode & 0x0F00) >> 8] >> 7;
V[(opcode & 0x0F00) >> 8] <<= 1;
pc += 2;
break;
default:
System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
Environment.Exit(-1);
break;
}
break;
case 0x9000:
if (V[(opcode & 0x0F00) >> 8] != V[(opcode & 0x00F0) >> 4])
pc += 4;
else
pc += 2;
break;
case 0xA000:
I = opcode & 0x0FFF;
pc += 2;
break;
case 0xB000:
pc = (opcode & 0x0FFF) + V[0];
break;
case 0xC000:
Random los = new Random();
V[(opcode & 0x0F00) >> 8] = (los.Next(0, 0xFF)) & (opcode & 0x00FF);
pc += 2;
break;
case 0xD000:
{
int x = V[(opcode & 0x0F00) >> 8];
int y = V[(opcode & 0x00F0) >> 4];
int height = opcode & 0x000F;
int pixel;
V[0xF] = 0;
for (int yline = 0; yline < height; yline++)
{
pixel = pamiec[I + yline];
for (int xline = 0; xline < 8; xline++)
{
if ((pixel & (0x80 >> xline)) != 0)
{
if (LCD[(x + xline + ((y + yline) * 64))] == 1)
{
V[0xF] = 1;
}
LCD[x + xline + ((y + yline) * 64)] ^= 1;
}
}
}
FlagaRysowania = true;
pc += 2;
}
break;
case 0xF000:
switch (opcode & 0x00FF)
{
case 0x0007:
V[(opcode & 0x0F00) >> 8] = licznik_Glowny;
pc += 2;
break;
case 0x000A:
{
bool keyPress = false;
for (int i = 0; i < 16; ++i)
{
if (klawisze[i] != 0)
{
V[(opcode & 0x0F00) >> 8] = i;
keyPress = true;
}
}
if (!keyPress)
return;
pc += 2;
}
break;
case 0x0015:
licznik_Glowny = V[(opcode & 0x0F00) >> 8];
pc += 2;
break;
case 0x0018:
licznik_Dzwieku = V[(opcode & 0x0F00) >> 8];
pc += 2;
break;
case 0x001E:
if (I + V[(opcode & 0x0F00) >> 8] > 0xFFF)
V[0xF] = 1;
else
V[0xF] = 0;
I += V[(opcode & 0x0F00) >> 8];
pc += 2;
break;
case 0x0029:
I = V[(opcode & 0x0F00) >> 8] * 0x5;
pc += 2;
break;
case 0x0033:
pamiec[I] = V[(opcode & 0x0F00) >> 8] / 100;
pamiec[I + 1] = (V[(opcode & 0x0F00) >> 8] / 10) % 10;
pamiec[I + 2] = (V[(opcode & 0x0F00) >> 8] % 100) % 10;
pc += 2;
break;
case 0x0055:
for (int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i)
pamiec[I + i] = V[i];
I += ((opcode & 0x0F00) >> 8) + 1;
pc += 2;
break;
case 0x0065:
for (int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i)
V[i] = pamiec[I + i];
I += ((opcode & 0x0F00) >> 8) + 1;
pc += 2;
break;
default:
System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
Environment.Exit(-1);
break;
}
break;
default:
System.Windows.Forms.MessageBox.Show("Nieznany opcode.");
Environment.Exit(-1);
break;
}
if (licznik_Glowny > 0)
licznik_Glowny--;
if (licznik_Dzwieku > 0)
{
if (licznik_Dzwieku == 1)
Console.Beep();
licznik_Dzwieku--;
}
}
public void WczytajAplikacje()
{
OpenFileDialog ROM = new OpenFileDialog();
ROM.Filter = "CHIP 8|*.c8";
System.Windows.Forms.MessageBox.Show("Wybierz aplikacje do wczytania.");
if (ROM.ShowDialog() == DialogResult.OK)
{
StreamReader pliczek = new StreamReader(ROM.FileName);
string buforPliku = pliczek.ReadToEnd();
for (int i = 0; i < buforPliku.Length; i++)
{
pamiec[i] = buforPliku[i];
}
pliczek.Close();
}
else
{
System.Windows.Forms.MessageBox.Show("Aplikacja nie zostala wybrana.");
System.Windows.Forms.MessageBox.Show("Emulator nie moze kontynuowac swojego dzialania.");
Environment.Exit(-1);
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testconbil
{
class Program
{
[STAThread]
static void Main(string[] args)
{
chip8 a = new chip8();
a.WczytajAplikacje();
while (true)
{
a.Wykonaj();
if (a.FlagaRysowania == true)
{
System.Threading.Thread.Sleep(500);
Console.Clear();
for (int y = 0; y < 32; ++y)
{
for (int x = 0; x < 64; ++x)
{
if (a.LCD[(y * 64) + x] == 0)
Console.Write(" ");
else
Console.Write("O");
}
Console.WriteLine();
}
Console.WriteLine();
a.FlagaRysowania = false;
}
else
{
}
}
}
}
}