diff --git a/headers.js b/headers.js index 6a7d0ba..73b2dcf 100644 --- a/headers.js +++ b/headers.js @@ -1,8 +1,79 @@ for (const el of document.querySelectorAll("[id]")) { - el.classList.add("haspara") + el.classList.add("haspara"); const pilcrow = document.createElement("a"); - pilcrow.className = "pilcrow" + pilcrow.className = "pilcrow"; pilcrow.href = "#" + el.id; - pilcrow.innerHTML = "¶" - el.prepend(pilcrow) + pilcrow.innerHTML = "¶"; + el.prepend(pilcrow); } + +const foldable = (root, children) => { + let state = true; + root.addEventListener("click", (e) => { + if (e.target.classList.contains("pilcrow")) state = true; + else state = !state; + + children.style.height = state ? "auto" : "0"; + children.style.overflow = state ? "visible" : "hidden"; + if (state) root.classList.remove("closed"); + else root.classList.add("closed"); + }); + root.classList.add("toggle-root"); +}; + +const make_foldable = (root) => { + const child_stacks = new Array(10).fill(null).map(() => ({ children: [], root: null })); + + const flush_header = (this_level, sibling) => { + for (let level = 9; level >= this_level; level--) { + const stack = child_stacks[level]; + + if (!stack.root) continue; + + const new_e = document.createElement("div"); + for (const old_e of stack.children) { + old_e.remove(); + new_e.appendChild(old_e); + } + + foldable(stack.root, new_e); + let parent_level; + for (parent_level = level - 1; parent_level > 0; parent_level--) if (child_stacks[parent_level].root) break; + + if (parent_level === -1) { + if (sibling) root.insertBefore(new_e, sibling); + else root.appendChild(new_e); + } else { + stack.root.remove(); + child_stacks[parent_level].children.push(stack.root); + child_stacks[parent_level].children.push(new_e); + } + + stack.root = null; + stack.children.length = 0; + } + }; + + for (const child of [...root.children]) { + if (/^H\d$/.test(child.tagName)) { + const this_level = parseInt(child.tagName[1]) - 1; + + flush_header(this_level, child); + + child_stacks[this_level].root = child; + continue; + } + + for (let level = 9; level >= 0; level--) { + if (child_stacks[level].root) { + child_stacks[level].children.push(child); + break; + } + } + } + + for (let level = 9; level >= 0; level--) { + flush_header(level, null); + } +}; +make_foldable(document.body); diff --git a/images/mxstartup.png b/images/mxstartup.png new file mode 100644 index 0000000..8ac1758 Binary files /dev/null and b/images/mxstartup.png differ diff --git a/styles.css b/styles.css index da698bb..69c3c77 100644 --- a/styles.css +++ b/styles.css @@ -144,7 +144,7 @@ table.nav td { .pilcrow { position: absolute; right: calc(100%); - padding-right: 4px; + padding-right: 24px; top: .1em; font-size: .9em; text-decoration: none; @@ -234,6 +234,30 @@ mark { text-underline-offset: 1px; } +.toggle-root { + cursor: pointer; + position: relative; +} +.toggle-root::before { + opacity: .5; + content: ""; + display: block; + border: 4px solid currentColor; + border-left-color: transparent; + border-top-color: transparent; + position: absolute; + left: -18px; + top: 50%; + transform: translateY(-50%) rotate(45deg); + transition: transform 100ms ease-out, opacity 100ms ease-out; +} +.toggle-root:hover::before { + opacity: 1; +} +.toggle-root.closed::before { + transform: translateY(-50%) rotate(-45deg); +} + @media (prefers-color-scheme: dark) { body { background-color: #000; diff --git a/templates/pages/proto/cardmng.html b/templates/pages/proto/cardmng.html index 5f8d720..edc8a36 100644 --- a/templates/pages/proto/cardmng.html +++ b/templates/pages/proto/cardmng.html @@ -50,6 +50,40 @@
cardmng.getdatalist
Some requests use refid
, some use dataid
, and some use both. What exactly you use these
+ values for is largely left up to the server implementer, as the game will echo them back verbatim, however here are
+ three suggestions:
refid |
+ An ID that references the user | +
data |
+ An ID that references the game specific data for this user/game combination | +
refid |
+ A session token issued during card auth | +
data |
+ An ID that references the game specific data for this user/game combination | +
refid |
+ An ID that references the user | +
data |
+ The same as refid; we can use database joins for accessing game data | +
cardmng.inquire
Request information about a card that has been inserted or touched against a reader.
@@ -76,12 +110,11 @@refid |
- A reference to this card to be used in other requests | +See section about refid and dataid |
dataid |
- Appears to be set the same as refid ; presumably to allow different keys for game state vs
- login details. |
+ See section about refid and dataid |
newflag |
@@ -94,12 +127,16 @@
||
expired |
- ? Just set to 0 . |
+ ? Just set it to 0 . |
+
newflag |
+ ? Just set it to 0 . |
cardmng.getrefid
Register a new card to this server.
+Register a new card to this server. In the process, we're also going to create a game profile.
{% highlight "cxml" %}@@ -122,20 +159,21 @@
- refid
A reference to this card to be used in other requests +See section about refid and dataid - dataid
Appears to be set the same as +refid
; presumably to allow different keys for game state vs - login details.See section about refid and dataid - pcode
? Not present in captured data. +? Just omit this +
cardmng.bindmodel
Create a data profile for this card on the current game. Request and response should be fairly self-explanatory.
+Request:
{% highlight "cxml" %}diff --git a/templates/pages/protocol.html b/templates/pages/protocol.html index 7115d2e..b8d5d24 100644 --- a/templates/pages/protocol.html +++ b/templates/pages/protocol.html @@ -219,5 +219,7 @@ Possible XRPC requests
+Of which properly documented:
+ {{ generate_xrpc_list()|safe }} {% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/partition.html b/templates/pages/sega/partition.html new file mode 100644 index 0000000..a4ee57e --- /dev/null +++ b/templates/pages/sega/partition.html @@ -0,0 +1,269 @@ +{% extends "sega.html" %} +{% block title %}SEGA Partition Structure{% endblock %} +{% block body %} +
-cardmng
SEGA Partition Structure
+ +Games on the Ring* series use MBR partitioned drives. The core partition structure is as follows:
+ ++ +
+ ++ + + +Partition +Size +Format +Content ++ +1 +1.5GiB +NTFS +Windows XP Embedded 2009 ++ +2 +1.5GiB +NTFS +Windows recovery partition ++ +3 +remaining space +Extended Partition (LBA) +Game data ++ + +4 ++ + + Extended partitions are structed by a linked list of partition headers at the beginning of each partition. These + headers reserve 3Fh blocks for their information, however only use a single block at the start of this + for actual data. SEGA make use of the remaining blocks in the first extended partition header for SEGA boot records. +
+ ++ +
+ ++ + + +Partition offset (blocks) +Content ++ +0 +Extended partition header ++ +1 +SEGA Partition Description ++ +2 +SEGA Boot Record (1) ++ +3 +SEGA Boot Record (2) ++ +4-63 +Additional data storage ++ + +64-... +Actual partition data +Two identical copies of the SEGA Boot Record are present. This is for redundancy; if either is corrupted, an attempt + will be made to restore it from the other copy.
+ +SEGA Partition Description
+ +The SEGA Partition Description (SPD) largely echos the structure laid out by the extended partition headers, however + is the table SEGA loaders preferentially read. It takes up all 512 bytes of the block; it's structure is as follows: +
+ ++ +
+ ++ + + ++ 0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F ++ +00h +CRC32 +Ver ++ + +10h +Slot content +? +Block size +Block count ++ + +20h +Slot content +? +Block size +Block count ++ + +30h +Slot content +? +Block size +Block count ++ + +... ++ + +F0h +Slot content +? +Block size +Block count ++ The slot content types are:
++ +
+ ++ + + +Value +Meaning ++ +10h +original0 ++ +11h +original1 ++ +20h +patch0 ++ +21h +patch1 ++ +30h +os ++ + +40h +app_data +SEGA Boot Record
+ +The SEGA Boot Record (SBR) contains detailed information about the content of each slot.
+ ++ +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/software/boot.html b/templates/pages/sega/software/boot.html new file mode 100644 index 0000000..e2b5cbf --- /dev/null +++ b/templates/pages/sega/software/boot.html @@ -0,0 +1,13 @@ +{% extends "sega.html" %} +{% block title %}Boot Sequence{% endblock %} +{% block body %} ++ + + ++ 0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F ++ +00h +CRC32 +Ver ++ + +10h ++ + +20h +Bootslot ++ 5x slot status ++ + +30h ++ + +... ++ +A0h ++ +B0h ++ +C0h ++ +D0h ++ +E0h ++ + +F0h +Boot Sequence
+ +This page is a stub for now.
+ ++
+ +{% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/software/mxmaster.html b/templates/pages/sega/software/mxmaster.html new file mode 100644 index 0000000..0085880 --- /dev/null +++ b/templates/pages/sega/software/mxmaster.html @@ -0,0 +1,23 @@ +{% extends "sega.html" %} +{% block title %}mxmaster{% endblock %} +{% block body %} +- mxprestartup
+- mxstartup
+mxmaster
+ +mxmaster is the program responsible for orchastrating the entire system.
+ +It first spawns the following list of programs:
+ ++
+ +{% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/software/mxprestartup.html b/templates/pages/sega/software/mxprestartup.html new file mode 100644 index 0000000..8f77357 --- /dev/null +++ b/templates/pages/sega/software/mxprestartup.html @@ -0,0 +1,15 @@ +{% extends "sega.html" %} +{% block title %}mxprestartup{% endblock %} +{% block body %} +- +
s:\mxkeychip.exe
- +
s:\mxnetwork.exe -p 40104
- +
s:\mxstorage.exe
- +
s:\mxinstaller.exe -cmdport 40102 -binport 40103
(sometimes with-openmode any
appended)- +
s:\mxgcatcher.exe {appboot.platformid} {appboot.gameid} {appboot.networkaddr} {appboot.keyid}
- +
s:\mxgfetcher.exe {appboot.platformid} {appboot.gameid} {appboot.networkaddr} {appboot.keyid}
- +
s:\mxgdeliver.exe {appboot.platformid} {appboot.gameid} {appboot.networkaddr} {appboot.keyid}
- +
C:\WINDOWS\system32\regini.exe S:\default_regset.txt
- + +
c:\System\Execute\mxsegaboot.exe
mxprestartup
+ +mxprestartup is the first program to run when the AppUser user logs in.
+ +This program's sole job is to construct the password for SystemUser, and spawn mxstartup.exe as SystemUser.
+ +Micetools contains a full version of this program, with a few additions for ease of use. It + can be found on the micetools repository.
+ +{% endblock %} \ No newline at end of file diff --git a/templates/pages/sega/software/mxstartup.html b/templates/pages/sega/software/mxstartup.html new file mode 100644 index 0000000..ae21b5c --- /dev/null +++ b/templates/pages/sega/software/mxstartup.html @@ -0,0 +1,133 @@ +{% extends "sega.html" %} +{% block title %}mxstartup{% endblock %} +{% block body %} +mxstartup
+ +mxstartup is responsible for some very initial system checks, loading the S: drive, and handing over to mxmaster.exe.
+ +This is the first time anything other than the Windows XP boot screen will be shown.
+ + + +mxstartup is responsible for a number of error codes, listed below. This table contains every error mxstartup can + produce, to the best of my knowledge.
++ +
++ + + +Error code +Message +Meaning ++ +0500 +SecurityCheck error ++ + +0501 +CheckEwfState error ++ + +0502 +GetSystemVersion error ++ + +0503 +GetsystemKeyFile ++ + +0504 +SetDiskAccessPrivilege ++ + +0505 +MountSystem ++ + +0506 +MountUpdate error ++ + +0507 +ExecuteMaMaster ++ + +0508 +GetOSUpdateKeyFile error ++ + +0509 +ExecuteMxOSUpdate error ++ + +0510 +ChangeEWFStateEnable error ++ + +0511 +GetSBRSlotOSState error ++ + +0512 +Deleate Key File error ++ + +0513 +MountDriver error ++ + +0514 +CheckPlatform error ++ + +0540 +Unmount error ++ + +0541 +MountRecoveryVolume error ++ + +0543 +MxChangeActivePartition error ++ + +0545 +osuSystemReboot error ++ + +0546 +GetSystemDiskNumber error ++ + + +???? +SetBackupComputerName failed ++ These errors are also reported into the Application event log, under the source
+ +{% endblock %} \ No newline at end of filemxstartup
.