File: pc-engine.cpp

package info (click to toggle)
ares 126-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 32,600 kB
  • sloc: cpp: 356,508; ansic: 20,394; makefile: 16; sh: 2
file content (128 lines) | stat: -rw-r--r-- 4,543 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
struct PCEngine : Cartridge {
  auto name() -> string override { return "PC Engine"; }
  auto extensions() -> vector<string> override { return {"pce"}; }
  auto load(string location) -> bool override;
  auto save(string location) -> bool override;
  auto analyze(vector<u8>& rom) -> string;
};

auto PCEngine::load(string location) -> bool {
  vector<u8> rom;
  if(directory::exists(location)) {
    append(rom, {location, "program.rom"});
  } else if(file::exists(location)) {
    rom = Cartridge::read(location);
  }
  if(!rom) return false;

  this->location = location;
  this->manifest = analyze(rom);
  auto document = BML::unserialize(manifest);
  if(!document) return false;

  pak = new vfs::directory;
  pak->setAttribute("title",  document["game/title"].string());
  pak->setAttribute("region", document["game/region"].string());
  pak->setAttribute("board",  document["game/board"].string());
  pak->append("manifest.bml", manifest);
  pak->append("program.rom",  rom);

  if(auto node = document["game/board/memory(type=RAM,content=Save)"]) {
    Medium::load(node, ".ram");
  }
  if(auto node = document["game/board/memory(type=RAM,content=Dynamic)"]) {
    Medium::load(node, ".dram");
  }
  if(auto node = document["game/board/memory(type=RAM,content=Work)"]) {
    Medium::load(node, ".wram");
  }

  return true;
}

auto PCEngine::save(string location) -> bool {
  auto document = BML::unserialize(manifest);

  if(auto node = document["game/board/memory(type=RAM,content=Save)"]) {
    Medium::save(node, ".ram");
  }

  return true;
}

auto PCEngine::analyze(vector<u8>& data) -> string {
  if((data.size() & 0x1fff) == 512) {
    //remove header if present
    memory::move(&data[0], &data[512], data.size() - 512);
    data.resize(data.size() - 512);
  }

  string digest = Hash::SHA256(data).digest();

  string region = "NTSC-U";
  string board = "Linear";
  if(data.size() ==  0x60000) board = "Split";
  if(data.size() == 0x280000) board = "Banked";

  //Populous
  if(digest == "16a796634a2b3da417a775cb64ffa3322ad7baf901c288934d28df967f7977f6") board = "RAM", region = "NTSC-J";
  if(digest == "bfc2e6dd19f2cb642d3a7bd149b9a5eb5a8007f0f1c626eb62ded2a1f609814e") board = "RAM", region = "NTSC-J";

  //Ten no Koe Bank
  if(digest == "16d43e32b34ed40b0a59f4122370f4d973af33a6122c9ccbfab6bb21cf36f1b3") board = "RAM";

  //PC Engine System Card 1.00
  if(digest == "afe9f27f91ac918348555b86298b4f984643eafa2773196f2c5441ea84f0c3bb") board = "System Card", region = "NTSC-J";

  //PC Engine System Card 2.00
  if(digest == "909f2153e624b76392684434ba5aa3e394cbba0318a0dda350140cb61ce9bc49") board = "System Card", region = "NTSC-J";

  //PC Engine System Card 2.10
  if(digest == "0deb13845c7e44ea78a25bbbe324afd60a0ec29ea5a4cf5780349f1598d24cd3") board = "System Card", region = "NTSC-J";

  //PC Engine Super System Card 3.00
  //PC Engine Arcade Card Duo
  //PC Engine Arcade Card Pro
  //note: because all three cards use the same ROM image, it is not possible to distinguish them here.
  //since the Arcade Card Pro is the most capable card, and is fully backward compatible, that is chosen here.
  if(digest == "e11527b3b96ce112a037138988ca72fd117a6b0779c2480d9e03eaebece3d9ce") board = "Arcade Card Pro", region = "NTSC-J";

  //TurboGrafx System Card 2.00
  if(digest == "edba5be43803b180e1d64ca678c3f8bdbf07180c9e2a65a5db69ad635951e6cc") board = "System Card", region = "NTSC-U";

  //TurboGrafx Super System Card 3.00
  if(digest == "cadac2725711b3c442bcf237b02f5a5210c96f17625c35fa58f009e0ed39e4db") board = "Super System Card", region = "NTSC-U";

  string s;
  s += "game\n";
  s +={"  sha256: ", digest, "\n"};
  s +={"  name:   ", Medium::name(location), "\n"};
  s +={"  title:  ", Medium::name(location), "\n"};
  s +={"  region: ", region, "\n"};
  s +={"  board:  ", board, "\n"};
  s += "    memory\n";
  s += "      type: ROM\n";
  s +={"      size: 0x", hex(data.size()), "\n"};
  s += "      content: Program\n";
  if(board == "RAM") {
  s += "    memory\n";
  s += "      type: RAM\n";
  s += "      size: 0x8000\n";
  s += "      content: Save\n";
  }
  if(board == "Super System Card" || board == "Arcade Card Pro") {
  s += "    memory\n";
  s += "      type: RAM\n";
  s += "      size: 0x30000\n";
  s += "      content: Work\n";
  s += "      volatile\n";
  }
  if(board == "Arcade Card Duo" || board == "Arcade Card Pro") {
  s += "    memory\n";
  s += "      type: RAM\n";
  s += "      size: 0x200000\n";
  s += "      content: Dynamic\n";
  s += "      volatile\n";
  }
  return s;
}