Forum: PC-Programmierung chip8 interpreter /emulator


von gaosl (Gast)


Lesenswert?

Hi ,
ich wollte einen chip8 interpreter umsetzen.
Dafür muss eine Hauptschleife immer einen neuen Befehl holen, dann 
decodieren und dann ausführen.
Die befehle sind in diesem Fall das Spiel. Allerdings weiß ich nicht 
genau wie ich die Befehle aus der Spieledatei auslesen muss. Denn wenn 
man eine .ch8 Datei mit dem Texteditor öffnet erscheinen da nur 
merkwürdige Zeichen.

Und kein Tutorial geht darauf so genau ein^^

Ich weiß nicht genau ob diese .ch8 dateien wirklich alle Befehle 
hintereinander gereiht haben. Dann könnte man einach immer 16 Bit 
auslesen und in ein Befehlregister reinschreiben.

Naja eigentlich könnte ich das ganze auch einfach testen,wenn ich meine 
Hauptschleife fertig programmiert habe und einfach die Datei einlese xD
Wollte aber trotzdem mal fragen was ihr darüber denkt ^^
Hier ein Link zu .ch8 Dateien.

https://www.zophar.net/pdroms/chip8/chip-8-games-pack.html
1
 // reading an entire binary file
2
#include <iostream>
3
#include <fstream>
4
using namespace std;
5
6
int main() {
7
  streampos size;
8
  char * memblock;
9
10
  ifstream file("Tetris.ch8", ios::in | ios::binary | ios::ate);
11
  if (file.is_open()) {
12
    size = 4;
13
    file.tellg();
14
    memblock = new char[size];
15
    file.seekg(0, ios::beg);
16
    file.read(memblock, size);
17
    file.close();
18
    for (int i = 0; i < size; i++) {
19
      cout << "\n" << memblock[i] << " :" << endl;
20
      for (int j = 7; j >= 0; j--) // or (int i = 0; i < 8; i++)  if you want reverse bit order in bytes
21
        cout << ((memblock[i] >> j) & 1);
22
    }
23
    cout << "\nthe entire file content is in memory";
24
25
    delete[] memblock;
26
  } else
27
    cout << "Unable to open file";
28
  return 0;
29
}

von Atomkraft, warum nicht (Gast)


Lesenswert?

http://devernay.free.fr/hacks/chip8/C8TECH10.HTM

> ich wollte einen chip8 interpreter umsetzen.

Wozu ein Tutorial?

von foobar (Gast)


Lesenswert?

> Ich weiß nicht genau ob diese .ch8 dateien wirklich alle Befehle
> hintereinander gereiht haben.

Die Dateien enthalten die rohen RAM-Inhalt.  Sie werden an 0x200 geladen 
und auch da gestartet.

> Dann könnte man einach immer 16 Bit auslesen und in ein Befehlregister
> reinschreiben.

Du musst 2 Bytes ab der Adresse, auf die der PC zeigt, in dein 
"Befehlsregister" lesen und dann interpretieren.

Da Befehle und Daten beliebig gemischt sind, die Befehle immer 2 Bytes 
lang sind und auch an ungeraden Adressen liegen dürfen, ist ein 
Disassembler nicht mehr trivial.  Aber du willst ja nen Interpreter 
basteln, das ist einfacher ;-)

von gaosl (Gast)


Lesenswert?

Danke für die Antworten,
wenigstens bekomme ich so etwas Motivation :D

>Wozu ein Tutorial?

Ja ich habe eigentlich auch an mich selber den Anspruch durch einfaches 
Nachdenken das ganze umzusetzen.
Denn es geht ja da wahrscheinlich nur um das Prinzip  Fetch Decode 
Execute
Mal schauen^^ Danke nochmal für den Link

>Die Dateien enthalten die rohen RAM-Inhalt.  Sie werden an 0x200 geladen
>und auch da gestartet.

Dann werde ich das mal versuchen :D

von gaosl (Gast)


Lesenswert?

ok , jetzt habe ich zwar schon eine Menge BEfehle abgetippt, aber bin 
mir noch sehr unsicher beim Einlesen aus einem "ROM-Game".
So sieht ein Inhat aus einem Test ROM aus:
1
 à¢ðe¢0a@0ÿ€€b cqÿÒr’ "&óqÿb Aÿ, î            €      À     ƒÀ    ?ÃÃÀ    ÿãÃÀ  ÿããÀ?€ 3ÿÃãÀÀÀ{àãàÿðààãàÿøàþáàñüð?ÿÁáàð|ð=ÿááàð>ð?ÿááàð>ð?óñáàðøùñáàðÿžÿóáàð>ÿóáàø>ÿ?ãÁàø<ÿÃÁà||<ÿƒÃà~|>? Ãà?ø> ÃÀø ÃÀð ‡ÀÀ ‡À   €   €

Eigentlich ist ein Befehl 2 Byte groß.
Wenn ich jetzt die ersten Bytes auslese, müsste ja ein bekannter Befehl 
auftauchen.
Bspw.:
https://www.rapidtables.com/convert/number/ascii-to-hex.html
1
12 02 20 e0 a2 01 f0 65 a2 30 61 40[\code]
2
3
4
Jetzt wollte ich mit Hilfe einer Textdatei einfach mal alle Befehle durchgehen, also einlesen.
5
Ich habe den ersten Befehl zu Test reingeschrieben:
6
0x00EE 
7
Mit diesem Code:
8
[code]ofstream file2("example.bin", ios::out | ios::binary | ios::ate);
9
  if (file2.is_open()) {
10
    file2 << 0b0000000011101110;
Wenn ich das dann aber auslese, werden die Nullen am Anfang ja einfach 
weggelassen.
Wenn ich dann den ersten Befehl (2 Byte) einlese erhalte ich : 
:11101110"irgendeinanderererOpcode !!"

ich würde aber gerne wieder 0b0000000011101110 erhalten, denn es geht ja 
um den Befehl 0x00EE , so erhalte ich aber nur 0xEE, was ja eigentlich 
schon das gleiche ist .
oh man .
Vielleicht hat jemand einen Denkanstoß :P

von gaosl (Gast)


Lesenswert?

Hmm. 0x00 = 0b0000 0000 =

von gaosl (Gast)


Lesenswert?

gaosl schrieb:
> Hmm. 0x00 = 0b0000 0000 =

dort steht eigentlich NULNUL sein oder so ähnlich :,(
http://www.asciitable.com/

von Larry (Gast)


Lesenswert?

Warum nimmst du nicht einfach C und dann ein simples fread?

von gaosl (Gast)


Lesenswert?

ja kann ich auch mal testen , wenn das irgendwie irgendwas hilft :D

(habe auch gerade einfach 0x00EE in ein Array geladen, ok da würde es 
eigentlich sinn machen. Wenn ich weiß, dass ein Element 16 Bit groß ist, 
und der Inhalt EE ist, dann müsste es sich ja um 0x00EE handeln.)

von foobar (Gast)


Lesenswert?

> So sieht ein Inhat aus einem Test ROM aus: [ASCII-Müll]

Den Inhalt der ROMs als ASCII anzuzeigen ist Quatsch.  Schau dir das in 
Hex an, z.B. INVADERS:
1
00000000  12 25 53 50 41 43 45 20  49 4e 56 41 44 45 52 53  .%SPACE INVADERS
2
00000010  20 76 30 2e 39 20 42 79  20 44 61 76 69 64 20 57   v0.9 By David W
3
00000020  49 4e 54 45 52 60 00 61  00 62 08 a3 d3 d0 18 71  INTER`.a.b.....q
4
00000030  08 f2 1e 31 20 12 2d 70  08 61 00 30 40 12 2d 69  ...1 .-p.a.0@.-i
5
00000040  05 6c 15 6e 00 23 87 60  0a f0 15 f0 07 30 00 12  .l.n.#.`.....0..

Geladen wird das nach 0x200.  Disassembliert ergibt das:
1
00000200  12 25   JP  0x225
2
00000202  53 ...  "SPACE INVADERS v0.9 By David WINTER"
3
00000225  60 00   LD  V0,0x00
4
00000227  61 00   LD  V1,0x00
5
00000229  62 08   LD  V2,0x08
6
0000022b  a3 d3   LD  I,0x3d3
7
0000022d  d0 18   DRW V0,V1,8
8
...

> Wenn ich das dann aber auslese, werden die Nullen am Anfang ja einfach
> weggelassen.

Wenn zu zwei Bytes schreiben willst, dann tu das auch.

> Vielleicht hat jemand einen Denkanstoß

Eine allgemeine Programmiereinführung wäre dringend angebracht, danach 
eine für C oder C++ ...

von Larry (Gast)


Lesenswert?

> testen

Da brauch man nichts testen.
fread ist genau dafuer da solchen Binaerkram unfallfrei zu lesen.

von gaosl (Gast)


Lesenswert?

Vielen Dank !
Denke mit den Antworten bin ich erst einmal gut beschäftigt !
:D

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.