Browse Source

Sega stubs

master
Bottersnike 10 months ago
parent
commit
efbde9fba9
  1. 204
      docs.py
  2. 2
      headers.js
  3. 14
      styles.css
  4. 14
      templates/base.html
  5. 14
      templates/konami.html
  6. 2
      templates/pages/cardid.html
  7. 2
      templates/pages/flags.html
  8. 2
      templates/pages/getting_started.html
  9. 39
      templates/pages/index.html
  10. 2
      templates/pages/motivation.html
  11. 4
      templates/pages/packet.html
  12. 2
      templates/pages/proto/apsmanager.html
  13. 2
      templates/pages/proto/cardmng.html
  14. 2
      templates/pages/proto/dlstatus.html
  15. 2
      templates/pages/proto/eacoin.html
  16. 2
      templates/pages/proto/esign.html
  17. 2
      templates/pages/proto/esoc.html
  18. 2
      templates/pages/proto/eventlog.html
  19. 2
      templates/pages/proto/facility.html
  20. 2
      templates/pages/proto/game/sv4.html
  21. 2
      templates/pages/proto/matching.html
  22. 2
      templates/pages/proto/message.html
  23. 2
      templates/pages/proto/package.html
  24. 2
      templates/pages/proto/pcbevent.html
  25. 2
      templates/pages/proto/pcbtracker.html
  26. 2
      templates/pages/proto/playerdata.html
  27. 2
      templates/pages/proto/services.html
  28. 2
      templates/pages/proto/sidmgr.html
  29. 2
      templates/pages/proto/system.html
  30. 2
      templates/pages/proto/traceroute.html
  31. 2
      templates/pages/proto/userdata.html
  32. 2
      templates/pages/protocol.html
  33. 6
      templates/pages/sega/hardware/index.html
  34. 206
      templates/pages/sega/index.html
  35. 22
      templates/pages/sega/intro.html
  36. 197
      templates/pages/sega/network/allnet.html
  37. 6
      templates/pages/sega/network/index.html
  38. 4
      templates/pages/sega/software/drivers/columba.html
  39. 6
      templates/pages/sega/software/drivers/index.html
  40. 4
      templates/pages/sega/software/drivers/mxhwreset.html
  41. 4
      templates/pages/sega/software/drivers/mxjvs.html
  42. 4
      templates/pages/sega/software/drivers/mxparallel.html
  43. 4
      templates/pages/sega/software/drivers/mxsmbus.html
  44. 4
      templates/pages/sega/software/drivers/mxsram.html
  45. 4
      templates/pages/sega/software/drivers/mxsuperio.html
  46. 6
      templates/pages/sega/software/index.html
  47. 4
      templates/pages/sega/software/jvs.html
  48. 4
      templates/pages/sega/software/security/dongle.html
  49. 4
      templates/pages/sega/software/security/game.html
  50. 6
      templates/pages/sega/software/security/index.html
  51. 4
      templates/pages/sega/software/security/keychip.html
  52. 2
      templates/pages/server.html
  53. 2
      templates/pages/smartea.html
  54. 2
      templates/pages/smartea.op2_common.get_music_info.html
  55. 4
      templates/pages/transport.html
  56. 11
      templates/sega.html
  57. 6
      xml_lexer.py

204
docs.py

@ -2,24 +2,70 @@ import datetime
import re
import os
from urllib.parse import urlparse
from flask import Flask, send_from_directory, render_template, make_response, request
from flask import Flask, send_from_directory, render_template, make_response, url_for
from livereload import Server
import xml_lexer
# Importing performs monkeypatching
import xml_lexer # NOQA: F401
app = Flask(__name__)
app.jinja_options.setdefault('extensions', []).append('jinja2_highlight.HighlightExtension')
HTAG = re.compile(r"<h(\d)[^>]*id=\"([^\"]+)\"[^>]*>([^<]*)</h")
TOC_HTAG_LEVELS = {"1", "2"}
HOST = "https://bsnk.me"
TEMPLATES = "templates"
PAGES_BASE = "pages"
STATIC = ["images"]
ROOT = os.environ.get("EA_ROOT", "")
EAMUSE_CONTENTS = {
"getting_started.html": ("Getting started and following along", {
0: ("A quick one-stop shop for getting setup with the tools you'll want on hand if you want to investigate "
+ "things for yourself.")
}),
"transport.html": ("Transport layer", None),
"packet.html": ("The inner packet structure", None),
"protocol.html": ("Communication protocol details", {
0: ("There are a crazy number of sub pages here, so just go check the contents there.")
}),
"server.html": "Let's write a server",
0: ("Misc pages", {
"cardid.html": ("Parsing and converting card IDs", ())
}),
}
SEGA_CONTENTS = {
"intro.html": ("Introduction to RingEdge 2", ()),
"hardware": ("Hardware", ()),
"software": ("Software", {
"drivers": ("Device drivers", {
"columba.html": "columba",
"mxsram.html": "mxsram",
"mxhwreset.html": "mxhwreset",
"mxsuperio.html": "mxsuperio",
"mxjvs.html": "mxjvs",
"mxparallel.html": "mxparallel",
"mxsmbus.html": "mxsmbus",
}),
"jvs.html": "JVS",
"security": ("Security", {
"game.html": "Game encryption",
"dongle.html": "Dongles",
"keychip.html": "Keychips",
})
}),
"network": ("Networking", {
"allnet.html": "ALL.Net"
})
}
CONTENTS = {
"": EAMUSE_CONTENTS,
"sega": SEGA_CONTENTS
}
def generate_xrpc_list():
@ -46,12 +92,146 @@ def generate_xrpc_list():
return output + "</ul>"
def generate_toc(base, name, route, start=1):
parts = route.strip("/").split("/")
toc = CONTENTS
for i in parts:
if i in toc:
toc = toc[i]
if isinstance(toc, tuple):
toc = toc[1]
if not isinstance(toc, dict):
return ""
else:
return ""
def walk(toc, path, start=1):
unordered = len(toc) == 1 and 0 in toc
out = f'<{"u" if unordered else "o"}l start="{start}">'
for url in toc:
if isinstance(toc[url], tuple):
name, children = toc[url]
elif isinstance(toc[url], str):
name, children = toc[url], -1
out += "<li>"
if isinstance(url, str):
fqu = f"{ROOT}/{path}"
if not url.startswith("#"):
fqu += "/"
fqu += url
while "//" in fqu:
fqu = fqu.replace("//", "/")
if not fqu.endswith((".html", "/")) and "#" not in fqu:
fqu += "/"
out += f'<a href="{fqu}">{name}</a>'
else:
out += name
out += "</li>"
if children == -1:
continue
if children is None:
filename = "/".join((TEMPLATES, PAGES_BASE, path, url))
while "//" in filename:
filename = filename.replace("//", "/")
if url == "":
filename += "index.html"
with open(filename) as page:
headers = HTAG.findall(page.read())
children = {}
for level, anchor, text in headers:
if level in TOC_HTAG_LEVELS:
children[f"#{anchor}"] = text
if not children:
children = None
if children is not None:
out += walk(children, f"{path}/{url}" if isinstance(url, str) else path)
out += f'</{"u" if unordered else "o"}l>'
return out
return walk(toc, route, start)
def generate_footer(base, name, route):
parts = route.strip("/").split("/")
if not parts:
return ""
toc = CONTENTS
path = []
for i in parts[:-1]:
if i in toc:
path.append(i)
toc = toc[i]
if isinstance(toc, tuple):
toc = toc[1]
if not isinstance(toc, dict):
toc = None
break
elif toc == CONTENTS:
toc = toc[""]
else:
toc = None
break
if toc == CONTENTS and len(parts) == 1:
toc = toc[""]
if toc is None:
siblings = None
else:
siblings = [i for i in toc.keys() if isinstance(i, str)]
try:
us_idx = siblings.index(parts[-1])
except ValueError:
us_idx = -1
parent = "/" + ("/".join(parts[:-1]))
if not parent.endswith("/"):
parent += "/"
footer = "<footer><span>"
if siblings and us_idx > 0:
footer += f'<a href="{parent}{siblings[us_idx - 1]}">Previous page</a>'
footer += "</span><span>"
if parts:
crumbs = []
built = "/"
for i in parts[:-1]:
built += f"{i}"
if not built.endswith((".html", "/")):
built += "/"
crumbs.append(f'<a href="{built}">{i}</a>')
crumbs.append(parts[-1])
footer += "/".join(crumbs)
footer += "</span><span>"
if siblings and us_idx < len(siblings) - 1 and us_idx != -1:
footer += f'<a href="{parent}{siblings[us_idx + 1]}">Next page</a>'
footer += "</span></footer>"
return footer
@app.route("/styles.css")
def styles():
return send_from_directory(".", "styles.css")
@app.route("/tango.css")
def tango():
return send_from_directory(".", "tango.css")
@app.route("/headers.js")
def header_script():
return send_from_directory(".", "headers.js")
@ -82,12 +262,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
for name in files:
if name.endswith(".html"):
def handler(base, name):
def handler(base, name, route):
def handler():
return render_template(
os.path.join(base, name).strip("/").replace("\\", "/"),
ROOT=ROOT,
generate_xrpc_list=generate_xrpc_list
generate_xrpc_list=generate_xrpc_list,
generate_toc=lambda start=1: generate_toc(base, name, route, start),
generate_footer=lambda: generate_footer(base, name, route),
)
return handler
@ -101,17 +283,14 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
if not route.startswith("/"):
route = "/" + route
handler = handler(base, name)
handler = handler(base, name, route)
handler.__name__ == route
app.add_url_rule(route, route, handler)
from flask import url_for
@app.route("/sitemap.xml")
def sitemap():
host_components = urlparse(request.host_url)
host_base = "https://bsnk.me" + ROOT
host_base = HOST + ROOT
links = []
for rule in app.url_map.iter_rules():
@ -133,6 +312,7 @@ def sitemap():
response.headers["Content-Type"] = "application/xml"
return response
if __name__ == '__main__':
app.config['TEMPLATES_AUTO_RELOAD'] = True
app.config['DEBUG'] = True
@ -141,4 +321,4 @@ if __name__ == '__main__':
server = Server(app.wsgi_app)
server.watch(".")
server.serve(port=3000)
server.serve(port=3000)

2
headers.js

@ -6,5 +6,3 @@ for (const el of document.querySelectorAll("[id]")) {
pilcrow.innerHTML = "&para;"
el.prepend(pilcrow)
}
console.log(hasId);

14
styles.css

@ -154,4 +154,16 @@ table.nav td {
.pilcrow:hover {
opacity: 1;
color: #c7254e;
}
}
footer {
width: 100%;
text-align: center;
margin-top: 8px;
}
footer>*:first-child {
float: left;
}
footer>*:last-child {
float: right;
}

14
templates/base.html

@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}{% if self.title() %} | {% endif %}e-Amusement API</title>
<title>{% block title %}{% endblock %}{% if self.title() %} | {% endif %}{% block roottitle %}Arcade Reverse Engineering{% endblock %}</title>
<link rel="stylesheet" href="{{ROOT}}/styles.css?ver=5">
<link rel="stylesheet" href="{{ROOT}}/tango.css">
@ -21,16 +21,8 @@
</head>
<body>
<table class="nav">
<tr>
<td><a href="{{ROOT}}/">Contents</a></td>
<td><a href="{{ROOT}}/transport.html">Transport layer</a></td>
<td><a href="{{ROOT}}/packet.html">Packet format</a></td>
<td><a href="{{ROOT}}/protocol.html">Application Protocol</a></td>
<td><a href="{{ROOT}}/server.html">Let's write a server</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% block rootbody %}{% endblock %}
{{ generate_footer()|safe }}
<script src="{{ROOT}}/headers.js"></script>
</body>

14
templates/konami.html

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block roottitle %}e-Amusement API{% endblock %}
{% block rootbody %}
<table class="nav">
<tr>
<td><a href="{{ROOT}}/">Contents</a></td>
<td><a href="{{ROOT}}/transport.html">Transport layer</a></td>
<td><a href="{{ROOT}}/packet.html">Packet format</a></td>
<td><a href="{{ROOT}}/protocol.html">Application Protocol</a></td>
<td><a href="{{ROOT}}/server.html">Let's write a server</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% endblock %}

2
templates/pages/cardid.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Card IDs{% endblock %}
{% block body %}
<h1>Card ID generation</h1>

2
templates/pages/flags.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Curious flags{% endblock %}
{% block body %}
<br>

2
templates/pages/getting_started.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Following along{% endblock %}
{% block body %}
<h1>Following along</h1>

39
templates/pages/index.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<h1>Benami/Konami e-Amusement API</h1>
@ -18,39 +18,7 @@
</p>
<h2>Contents</h2>
<ol start="0">
<li><a href="./getting_started.html">Getting started and following along</a></li>
<ul>
<li>A quick one-stop shop for getting setup with the tools you'll want on hand if you want to investigate things
for yourself.</li>
</ul>
<li><a href="./transport.html">Transport layer</a></li>
<ol>
<li><a href="./transport.html#packet">Packet structure</a></li>
<li><a href="./transport.html#type">Types</a></li>
</ol>
<li><a href="./packet.html">The inner packet structure</a></li>
<ol>
<li><a href="./packet.html#xml">XML packets</a></li>
<li><a href="./packet.html#binary">Binary packed packets</a></li>
<li><a href="./packet.html#schema">Binary schemas</a></li>
<li><a href="./packet.html#data">Binary data</a></li>
</ol>
<li><a href="./protocol.html">Communication protocol details</a></li>
<ul>
<li>There are a crazy number of sub pages here, so just go check the contents there.</li>
</ul>
<li><a href="./server.html">Let's write a server</a></li>
<ol>
<li><a href="./server.html#groundwork">Groundwork</a></li>
<li><a href="./server.html#handlers">Implementing handlers</a></li>
<li><a href="./server.html#extra">Extra endpoints</a></li>
</ol>
<li>Misc pages</li>
<ol>
<li><a href="./cardid.html">Parsing and converting card IDs</a></li>
</ol>
</ol>
{{ generate_toc(0)|safe }}
<h2>Code snippets</h2>
<p>Across these pages there are a number of code snippets. They roughly break down into three categories:</p>
@ -66,7 +34,4 @@
<p>Assembly and C snippets often come with an accompanying filename and address. If you're interested in learning how
things work in more detail, I'd strongly recommend checking them out. Not all games come with the same version of
files; the provided addresses are for build SDVX build KFC-2019020600, using the default base offset.</p>
<a href="./transport.html">Next page</a>
{% endblock %}

2
templates/pages/motivation.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<p>Why?</p>
<p>I was curious how these APIs work, yet could find little to nothing on Google. There are a number of

4
templates/pages/packet.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Packet format{% endblock %}
{% block body %}
<h1>Packet format</h1>
@ -1023,6 +1023,4 @@
self.request_allocation(4){% endhighlight %}</pre>
</p>
</details>
<a href="./transport.html">Prev page</a> | <a href="./protocol.html">Next page</a>
{% endblock %}

2
templates/pages/proto/apsmanager.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}apsmanager{% endblock %}
{% block body %}
<h1><code>apsmanager</code></h1>

2
templates/pages/proto/cardmng.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}cardmng{% endblock %}
{% block body %}
<h1><code>cardmng</code></h1>

2
templates/pages/proto/dlstatus.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}dlstatus{% endblock %}
{% block body %}
<h1><code>dlstatus</code></h1>

2
templates/pages/proto/eacoin.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}eacoin{% endblock %}
{% block body %}
<h1><code>eacoin</code></h1>

2
templates/pages/proto/esign.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}esign{% endblock %}
{% block body %}
<h1><code>esign</code></h1>

2
templates/pages/proto/esoc.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}esoc{% endblock %}
{% block body %}
<h1><code>esoc</code></h1>

2
templates/pages/proto/eventlog.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}eventlog{% endblock %}
{% block body %}
<h1><code>eventlog</code></h1>

2
templates/pages/proto/facility.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}facility{% endblock %}
{% block body %}
<h1><code>facility</code></h1>

2
templates/pages/proto/game/sv4.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}game.sv4{% endblock %}
{% block body %}
<h1 id="game"><code>game</code></h1>

2
templates/pages/proto/matching.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}matching{% endblock %}
{% block body %}
<h1><code>matching</code></h1>

2
templates/pages/proto/message.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}message{% endblock %}
{% block body %}
<h1><code>message</code></h1>

2
templates/pages/proto/package.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}package{% endblock %}
{% block body %}
<h1><code>package</code></h1>

2
templates/pages/proto/pcbevent.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}pcbevent{% endblock %}
{% block body %}
<h1><code>pcbevent</code></h1>

2
templates/pages/proto/pcbtracker.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}pcbtracker{% endblock %}
{% block body %}
<h1><code>pcbtracker</code></h1>

2
templates/pages/proto/playerdata.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}playerdata{% endblock %}
{% block body %}
<h1><code>playerdata</code></h1>

2
templates/pages/proto/services.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}services{% endblock %}
{% block body %}
<h1><code>services</code></h1>

2
templates/pages/proto/sidmgr.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}sidmgr{% endblock %}
{% block body %}
<h1><code>sidmgr</code></h1>

2
templates/pages/proto/system.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}system{% endblock %}
{% block body %}
<h1><code>system</code></h1>

2
templates/pages/proto/traceroute.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}traceroute{% endblock %}
{% block body %}
<h1><code>traceroute</code></h1>

2
templates/pages/proto/userdata.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}userdata{% endblock %}
{% block body %}
<h1><code>userdata</code></h1>

2
templates/pages/protocol.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Application protocol{% endblock %}
{% block body %}
<h1>Application Protocol</h1>

6
templates/pages/sega/hardware/index.html

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Hardware{% endblock %}
{% block body %}
<h1>Hardware</h1>
{{ generate_toc()|safe }}
{% endblock %}

206
templates/pages/sega/index.html

@ -1,203 +1,11 @@
{% extends "base.html" %}
{% block title %}SEGA Games{% endblock %}
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
<h1>SEGA Games</h1>
<p>This may get its own micro-site at some point if it grows large enough. For now it's mostly just a rambling of notes.
</p>
<p>In some ways SEGA's protocols are simpler than Konami's (none of that XML mess) but in other ways they're more
complicated (hardcoded URLs, multiple services required, etc.)</p>
<h1>RingEdge 2</h1>
<p>Welcome to the sub-site for RingEdge 2 games. What started as a simple desire to start games outside of dev mode
turned into an incredibly deep dive into the inner workings of the RE2 software. Enjoy.</p>
<h2>ALL.Net</h2>
<p>A simple service that exposes two URLs. The hostname must be <code>http://naominet.jp</code>.</p>
<p>Requests should be made with a number of standard HTTP headers, and must be either HTTP version 1.0 or 1.1</p>
<table>
<tr>
<td><code>Connection</code></td>
<td><code>Close</code></td>
</tr>
<tr>
<td><code>Pragma</code></td>
<td><code>DFI</code></td>
</tr>
<tr>
<td><code>User-Agent</code></td>
<td><code>ALL.Net_PC_Win2/ver1.0</code></td>
</tr>
<tr>
<td><code>Content-Type</code></td>
<td><code>application/x-www-form-urlencoded</code></td>
</tr>
<tr>
<td><code>Content-Length</code></td>
<td><i>variable</i></td>
</tr>
</table>
<p>Note that the <code>Pragma</code> header is optional, and the <code>Content-Type</code> header is a lie.</p>
<p>Requests and responses should be <code>POST</code>s, and their body should be base64 encoded, zlib compressed,
<code>x-www-form-urlencoded</code> data. For example, <code>{key: "value", other: "another"}</code> should encode to
<code>eJwdxcEJACAMA8Bt3CLD5BEQFIXSFtw+4OuWHpq7NG5OBXi+BmwzCRo=</code>.
</p>
<p>Responses are expected to contain <code>stat</code> indicating status:</p>
<table>
<tr>
<td><code>1</code></td>
<td>Success</td>
</tr>
<tr>
<td><code>0</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-1</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-2</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-3</code></td>
<td>Failure</td>
</tr>
</table>
<p>This service provides two endpoints, documented below:</p>
<h3><code>/sys/servlet/PowerOn</code></h3>
<h4>Request:</h4>
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&encode=%s&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s\r\n"
"game_id=%s&ver=%s&serial=%s&encode=%s\r\n"
"keychipid=%s&functype=%u&gameid=%s&gamever=%s&boardid=%s&tenpoip=%s&libalibver=%s&datamax=%s&billingtype=%d&protocolver=%s&operatingfix=%d"
(libalibver = 1.110, protocolver = 1.000)
SDBT: Chunithm
SBXL: Maimai
<table>
<tr>
<td><code>game_id</code></td>
<td>4-character game ID</td>
</tr>
<tr>
<td><code>ver</code></td>
<td></td>
</tr>
<tr>
<td><code>serial</code></td>
<td></td>
</tr>
<tr>
<td><code>ip</code></td>
<td></td>
</tr>
<tr>
<td><code>firm_ver</code></td>
<td><code>%01d%02d%02d</code></td>
</tr>
<tr>
<td><code>boot_ver</code></td>
<td><code>%02X%02X</code></td>
</tr>
<tr>
<td><code>format_ver</code></td>
<td></td>
</tr>
<tr>
<td><code>hops</code></td>
<td></td>
</tr>
<tr>
<td><code>encode</code></td>
<td></td>
</tr>
</table>
<h4>Response:</h4>
<table>
<tr>
<td><code>stat</code></td>
<td>See above</td>
</tr>
<tr>
<td><code>uri</code></td>
<td></td>
</tr>
<tr>
<td><code>host</code></td>
<td></td>
</tr>
<tr>
<td><code>region0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name1</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name2</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name3</code></td>
<td></td>
</tr>
<tr>
<td><code>year</code></td>
<td></td>
</tr>
<tr>
<td><code>month</code></td>
<td></td>
</tr>
<tr>
<td><code>day</code></td>
<td></td>
</tr>
<tr>
<td><code>hour</code></td>
<td></td>
</tr>
<tr>
<td><code>minute</code></td>
<td></td>
</tr>
<tr>
<td><code>second</code></td>
<td></td>
</tr>
<tr>
<td><code>place_id</code></td>
<td></td>
</tr>
<tr>
<td><code>setting</code></td>
<td></td>
</tr>
<tr>
<td><code>country</code></td>
<td></td>
</tr>
<tr>
<td><code>timezone</code></td>
<td></td>
</tr>
<tr>
<td><code>res_class</code></td>
<td></td>
</tr>
</table>
<h3><code>/sys/servlet/DownloadOrder</code></h3>
<h2 id="toc">Table of Contents</h2>
{{ generate_toc(0)|safe }}
{% endblock %}

22
templates/pages/sega/intro.html

@ -0,0 +1,22 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
<h1>Introduction to RingEdge 2</h1>
<p>RingEdge 2 (RE2 henceforth) is the main computer used by Sega in a number of their arcade games. In their cronology
it exists as the successor to the RingEdge (no huge surprise there), which itself was the successor to the
Lindbergh, and is the predecessor of Nu. There also exists the RingWide, a slightly less powerful variant of the
Ring* computers. These pages focus on the RE2. I have no reason to believe the RE2 software stack is especially
differnet to that of the RE, but I haven't confirmed this. Nu, however, uses different systems in many places, and
most of the deep-dive pages will not be applicable.</p>
<h2 id="tech">Technical Specifications</h2>
<ul>
<li>Intel Core i3-540, 3.06GHz</li>
<li>Nvidia GeForce GT 545</li>
<li>2GB RAM</li>
<li>32GB SSD (TDK GBDISK RS3)</li>
<li>Intel Q57 Express Motherboard</li>
</ul>
<a href="{{ROOT}}/sega/hardware/">Next chapter</a>
{% endblock %}

197
templates/pages/sega/network/allnet.html

@ -0,0 +1,197 @@
{% extends "sega.html" %}
{% block title %}ALL.Net{% endblock %}
{% block body %}
<h1>ALL.Net</h1>
<p>A simple service that exposes two URLs. The hostname must be <code>http://naominet.jp</code>.</p>
<p>Requests should be made with a number of standard HTTP headers, and must be either HTTP version 1.0 or 1.1</p>
<table>
<tr>
<td><code>Connection</code></td>
<td><code>Close</code></td>
</tr>
<tr>
<td><code>Pragma</code></td>
<td><code>DFI</code></td>
</tr>
<tr>
<td><code>User-Agent</code></td>
<td><code>ALL.Net_PC_Win2/ver1.0</code></td>
</tr>
<tr>
<td><code>Content-Type</code></td>
<td><code>application/x-www-form-urlencoded</code></td>
</tr>
<tr>
<td><code>Content-Length</code></td>
<td><i>variable</i></td>
</tr>
</table>
<p>Note that the <code>Pragma</code> header is optional, and the <code>Content-Type</code> header is a lie.</p>
<p>Requests and responses should be <code>POST</code>s, and their body should be base64 encoded, zlib compressed,
<code>x-www-form-urlencoded</code> data. For example, <code>{key: "value", other: "another"}</code> should encode to
<code>eJwdxcEJACAMA8Bt3CLD5BEQFIXSFtw+4OuWHpq7NG5OBXi+BmwzCRo=</code>.
</p>
<p>Responses are expected to contain <code>stat</code> indicating status:</p>
<table>
<tr>
<td><code>1</code></td>
<td>Success</td>
</tr>
<tr>
<td><code>0</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-1</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-2</code></td>
<td>Failure</td>
</tr>
<tr>
<td><code>-3</code></td>
<td>Failure</td>
</tr>
</table>
<p>This service provides two endpoints, documented below:</p>
<h3><code>/sys/servlet/PowerOn</code></h3>
<h4>Request:</h4>
<!--
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&encode=%s&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s&ip=%s&firm_ver=%01d%02d%02d&boot_ver=%02X%02X&format_ver=%s&hops=%d\r\n"
"game_id=%s&ver=%s&serial=%s\r\n"
"game_id=%s&ver=%s&serial=%s&encode=%s\r\n"
"keychipid=%s&functype=%u&gameid=%s&gamever=%s&boardid=%s&tenpoip=%s&libalibver=%s&datamax=%s&billingtype=%d&protocolver=%s&operatingfix=%d"
(libalibver = 1.110, protocolver = 1.000)
SDBT: Chunithm
SBXL: Maimai -->
<table>
<tr>
<td><code>game_id</code></td>
<td>4-character game ID</td>
</tr>
<tr>
<td><code>ver</code></td>
<td></td>
</tr>
<tr>
<td><code>serial</code></td>
<td></td>
</tr>
<tr>
<td><code>ip</code></td>
<td></td>
</tr>
<tr>
<td><code>firm_ver</code></td>
<td><code>%01d%02d%02d</code></td>
</tr>
<tr>
<td><code>boot_ver</code></td>
<td><code>%02X%02X</code></td>
</tr>
<tr>
<td><code>format_ver</code></td>
<td></td>
</tr>
<tr>
<td><code>hops</code></td>
<td></td>
</tr>
<tr>
<td><code>encode</code></td>
<td></td>
</tr>
</table>
<h4>Response:</h4>
<table>
<tr>
<td><code>stat</code></td>
<td>See above</td>
</tr>
<tr>
<td><code>uri</code></td>
<td></td>
</tr>
<tr>
<td><code>host</code></td>
<td></td>
</tr>
<tr>
<td><code>region0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name0</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name1</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name2</code></td>
<td></td>
</tr>
<tr>
<td><code>region_name3</code></td>
<td></td>
</tr>
<tr>
<td><code>year</code></td>
<td></td>
</tr>
<tr>
<td><code>month</code></td>
<td></td>
</tr>
<tr>
<td><code>day</code></td>
<td></td>
</tr>
<tr>
<td><code>hour</code></td>
<td></td>
</tr>
<tr>
<td><code>minute</code></td>
<td></td>
</tr>
<tr>
<td><code>second</code></td>
<td></td>
</tr>
<tr>
<td><code>place_id</code></td>
<td></td>
</tr>
<tr>
<td><code>setting</code></td>
<td></td>
</tr>
<tr>
<td><code>country</code></td>
<td></td>
</tr>
<tr>
<td><code>timezone</code></td>
<td></td>
</tr>
<tr>
<td><code>res_class</code></td>
<td></td>
</tr>
</table>
<h3><code>/sys/servlet/DownloadOrder</code></h3>
{% endblock %}

6
templates/pages/sega/network/index.html

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Networking{% endblock %}
{% block body %}
<h1>Networking</h1>
{{ generate_toc()|safe }}
{% endblock %}

4
templates/pages/sega/software/drivers/columba.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

6
templates/pages/sega/software/drivers/index.html

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Drivers{% endblock %}
{% block body %}
<h1>Drivers</h1>
{{ generate_toc()|safe }}
{% endblock %}

4
templates/pages/sega/software/drivers/mxhwreset.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/drivers/mxjvs.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/drivers/mxparallel.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/drivers/mxsmbus.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/drivers/mxsram.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/drivers/mxsuperio.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

6
templates/pages/sega/software/index.html

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Software{% endblock %}
{% block body %}
<h1>Software</h1>
{{ generate_toc()|safe }}
{% endblock %}

4
templates/pages/sega/software/jvs.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/security/dongle.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

4
templates/pages/sega/software/security/game.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

6
templates/pages/sega/software/security/index.html

@ -0,0 +1,6 @@
{% extends "sega.html" %}
{% block title %}Security{% endblock %}
{% block body %}
<h1>Security</h1>
{{ generate_toc()|safe }}
{% endblock %}

4
templates/pages/sega/software/security/keychip.html

@ -0,0 +1,4 @@
{% extends "sega.html" %}
{% block title %}{% endblock %}
{% block body %}
{% endblock %}

2
templates/pages/server.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Write a server{% endblock %}
{% block body %}
<h1>Let's write an e-Amusement server!</h1>

2
templates/pages/smartea.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Smart E-Amusement{% endblock %}
{% block body %}
<h1>Smart E-Amusement</h1>

2
templates/pages/smartea.op2_common.get_music_info.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block body %}
<h2><code>op2_common.get_music_info</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>

4
templates/pages/transport.html

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "konami.html" %}
{% block title %}Network format{% endblock %}
{% block body %}
<h1>Network format</h1>
@ -118,6 +118,4 @@ int xrpc_key_and_crypt(char *packet, char *eamuse_info, size_t size) {
feasibly perform no compression at all, and instead insert <code>0xFF</code> every 8 bytes (starting at index 0), to
indicate that all values are literals. While obviously poor for compression, this is an easy way to test without
first implementing a compressor.</p>
<a href="./index.html">Prev page</a> | <a href="./packet.html">Next page</a>
{% endblock %}

11
templates/sega.html

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block roottitle %}RingEdge 2{% endblock %}
{% block rootbody %}
<table class="nav">
<tr>
<td><a href="{{ROOT}}/sega/">Contents</a></td>
<td><a href="{{ROOT}}/sega/network/allnet.html">ALL.Net</a></td>
</tr>
</table>
{% block body %}{% endblock %}
{% endblock %}

6
xml_lexer.py

@ -9,9 +9,11 @@ def italic_attr(lexer, m):
yield m.start() + 2, Comment, m.group()[3:-1]
yield m.end() - 1, String, '"'
def italic_generic(lexer, m):
yield m.start(), Comment, m.group()
def italic_tag(lexer, m):
yield m.start(), Name.Tag, "<"
name = m.group()[3:]