Derby Owners Club II (Japan, 2001) never left Japan and never had its cards documented. On 6 September 2026 the format gave way. This page is the working map: every byte of a card tagged by how sure we are.
The identity half of the card and every integrity check are settled. The career half (track 2) is mostly open, which is exactly the part that needs more cards. Evidence comes from three real card files posted in the community's #doc-ii channel by varjak_, the author of the DOC II English patch, her photos of the matching in-game screens, and the game's own program ROM. Four of the files are the same horse (アノヨリグドヴィキ, a grey male by Mejiro McQueen out of Air Groove): saved fresh, after one race (9th), after a second race run on a copy of the card with its six ability bytes rewritten to 92, 90, 88, 85, 85, 90 (4th, promoted to B), and after more races including its first win (rank A). Every step changed only track 2. The sample bytes in the tables are from the latest file. The second source is the ROM's own debug printout of a horse record, which labels each field in Japanese (speed, stamina, sharp, start, corner, spurt, turf, dirt, heavy turf, heavy dirt, distance, trust, mood, condition, race experience, race count, wins, training count, running style, five personality traits) and reads them from the same 448-byte record the card unpacker fills, so its labels map onto card bytes directly.
In the byte strips below, a dashed border marks a byte that is stored in the clear; everything else is inside the encrypted block. Every byte now has a known destination: the game's card unpacker was run under emulation on 1,657 copies of a real card, each with one bit flipped, and the record bytes that changed were logged. That is how a byte can be tagged unused with confidence, and how bit-packed bytes are tied to specific record slots even where the ROM has not labelled the slot.
A DOC II card is the same physical object as a World Edition card: three magnetic tracks of 69 bytes, 207 bytes in a Flycast .card file. Track 1 is identity, track 2 is career, track 3 is the header track that starts with the magic string SEGABDY0 (SEGA plus the product code the ROM carries at header offset 0x134, the same construction World Edition uses for SEGABEF0). The reader state machine in the ROM writes track 1 once at card creation and rewrites tracks 2 and 3 during play.
Offsets on this page are track-relative: 0x00 to 0x44 within each track. To find a byte in the 207-byte file, add 0x00, 0x45 or 0x8A for tracks 1, 2 and 3.
What made these cards look like noise is that the first 64 bytes of every track (56 on track 3, which keeps its magic string clear) are encrypted. The routine in the program ROM is a DES-style Feistel block cipher: 64-bit blocks, 16 rounds, eight S-boxes, a key schedule. Sega replaced every table with its own. Each track's block is run through the cipher three times with three different keys, with a fixed byte shuffle between passes. Inside the plaintext sit two integrity checks: a 16-bit table-driven check over the block, and a copy of a few protected bytes XORed with a per-track constant. A card with a single flipped byte fails one of them and the game ejects it.
None of this was re-implemented by hand. The card pipeline was decompiled from the program ROM, and the game's own decode and encode routines were run under an SH-4 emulator. The real card decoded with return code zero (every check on every track passed), and re-encrypting the plaintext reproduced the original file byte for byte. A test card with the sire renamed and one name character changed was then produced with the game's encoder, decoded again cleanly, and loaded in DOC II by the card's owner: the game accepted it.
Encrypted 0x00 to 0x3F, clear 0x40 to 0x44. Not one byte of this track changed when the horse was trained, fed and raced, which is the expected behaviour for an identity track (the ROM writes it once at card creation).
| Offset | Bytes on the sample card | Field | Status | Evidence |
|---|---|---|---|---|
| 0x00–0x08 | 81 AD C8 CA 8F A8 D4 82 8C | Horse name, 9 katakana codes | confirmed | Code c maps to Shift-JIS 0x83 (c minus 0x40), so 81=ア, 8A=カ, D4=ヴ; 00 ends a short name. Two cards decode to the names on their name-entry screens; a test card with one changed code loaded in-game. The bit-flip run confirms all nine bytes feed only the name buffers. |
| 0x09 | BC | Packed flags (record +0x127 and +0x133) | hypothesized | The unpacker splits this byte into two record slots the debug printout does not label. BC on one horse, BE on the other. |
| 0x0A–0x0B | 3C 26 | Two bytes to record +0x128, +0x129 | unknown | Whole-byte copies. The card-creation serializer initialises both to 21; the two horses carry 45/26 and 60/38 and the values did not move across four rewrites of one horse. Unlabelled. |
| 0x0C | 10 | Jockey silks: accent colour in bits 3-0, base colour in bits 7-4 | confirmed | Every default-silk horse reads 10: base colour 1 (grey, the second swatch) and accent 0 (black, the first). Three horses created with base and accent one, two and three swatches along read 21, 32, 43, and one created with both colours on the last swatch reads FF, so each colour is a 0-F index into a sixteen-colour list that starts black, grey, blue, light blue, brown, matching the in-game swatch strip; a horse created with light blue and pink reads 39, so index 9 is pink. Fixed for the life of the card. |
| 0x0D | 00 | Silk pattern in bits 3-0 (16 patterns); bits 7-4 unlabelled | confirmed | Default pattern reads 0; horses one, two and three patterns along read 1, 2, 3; a horse created with the last pattern in the list (the large disc) reads F, so there are sixteen patterns; a blue-and-pink triangle check reads A. The high nibble varies between horses (0, 8, 2, 6, 4 seen) and is not yet named. |
| 0x0E | 50 | Byte to record +0xF2 | unknown | Whole-byte copy, varies per horse (50, 10, A0, 40, 20, 00 seen), fixed across saves. Unlabelled appearance field. |
| 0x0F | 06 | Sex in bits 7-6 (0 牡 male, 1 牝 female, 2 せ gelding); coat index in bits 5-1 | confirmed | The stable screen reads the top two bits of the record word this byte feeds and prints them through the ROM's name table, whose first three entries are 牡, 牝, せ. Three male horses read 0 here and two mares read 1, including a filly the owner named as such. Bits 5-1 are the coat index into the ROM's coat list (栗毛 chestnut 0, 鹿毛 bay 1, 青毛 black 2, 芦毛 grey 3, 栃栗毛 4, 黒鹿毛 5, 白毛 6, then special coats): chestnut reads 0, bay 1, black 2, grey 3 and a dark liver chestnut 4, so the alignment is verified on five coats. |
| 0x10–0x1F | 4D 65 6A 69 72 6F 20 4D 63 51 75 65 65 6E 00 00 | Sire name, 16 bytes ASCII | confirmed | “Mejiro Palmer” on one horse, “Mejiro McQueen” on the other, matching the sires chosen in-game; one byte per record slot +0xFA..+0x109. The test card renamed it and the game loaded it. |
| 0x20–0x2F | 41 69 72 20 47 72 6F 6F 76 65 00 6C 00 00 00 00 | Dam name, 16 bytes ASCII | confirmed | “Racing Jean” and “Air Groove”, matching the dams chosen in-game; record +0x10A..+0x119. |
| 0x30–0x33 | 54 00 50 EF | Coat / appearance word, 32-bit | confirmed | Copied whole to record +0x120 and protected by the XOR check at 0x3C. Not a serial: the card-creation serializer builds it from the game record's two coat and genetics words (+0x52, +0x54; the same words the legacy DOC 2000 writer stores as DOC 2000 card bytes 0x24-0x27, the coat and personality genes), mapping the coat family through a small lookup with special cases. Different on each horse, unchanged across every rewrite. How to decode it into a coat name is still open. |
| 0x34 | 0D | Leg-wrap colour in bits 6-4; other bits unlabelled | hypothesized | Bit 4 is set on the grey-wraps horse (1D) and on both white-wraps horses (DD, 5D) and clear on the black-wraps horse and every plain horse (0D, 00), so leg wraps have no presence flag: their colour is stored here with black reading 0. Grey reads 1; the two white-wrap horses read 5 in bits 6-4, and a horse with red wraps reads 4, so the list is not the silk colour list. Bits 0-3 and 7 vary for other reasons (00 on one fully-default horse, AD on another). |
| 0x35 | D0 | Packed identity bits (record +0x12D, +0x12E) | unknown | D0, DF or 00 across the horses seen, fixed per horse and unrelated to silks or accessories. Unlabelled. |
| 0x36 | 0D | Hood: presence in bit 0, colour in bits 6-4; noseband colour in bits 3-1 | hypothesized | 0D on every horse without a hood; with a hood bit 0 is set and bits 6-4 carry the hood colour: grey (first option) reads 0, the red-hooded horse reads 4, a third hooded horse reads 2, a pink one 5. Bits 3-1 move with the noseband: the four hood-plus-noseband horses read 2, 2, 2 and 4 there (the last with a green noseband), the hood-only horse reads 0, so this looks like the noseband colour. Bit 7 is set on one horse only (pink hood with ears) and is unexplained. Leg wraps do not touch this byte. |
| 0x37 | 40 | Byte to record +0x12F; bit 0 follows the hood | hypothesized | Whole-byte copy that also takes part in name rendering. Bit 0 is 1 on the hood-only horse and on both all-accessories horses, 0 on the noseband-only horse and the plain horses, so it is a second hood-related bit (pattern or colour flag is the natural reading). The upper bits (00, 20, 40, 21, 01, 40, 41 across seven horses) are not yet tied down. |
| 0x38–0x39 | 0F 00 | 16-bit value to record +0x134 | unknown | 15 on both horses, every save. The card-creation serializer derives it from the same coat and genetics words as the appearance word. Unlabelled. |
| 0x3A–0x3B | C1 73 | 16-bit integrity check | confirmed | Table-driven check over bytes 0x00 to 0x39 (routine at 0C09C024), stored to record +0x1AC for reference. Recomputed by the encoder whenever the track changes. |
| 0x3C–0x3F | D5 92 34 7C | ID check | confirmed | Big-endian u32 of bytes 0x30 to 0x33 XOR 81926493, verified on both horses. Consumed by the decoder only; the unpacker never reads these bytes. |
| 0x40–0x41 | 13 00 | Clear 16-bit card-issue counter (same value on all three tracks) | confirmed | Not encrypted; record +0x1A0. Six cards made on the same machine read 0x12, 0x13, 0x17, 0x18, 0x19 in the order they were made, and the value never changes when a card is rewritten. |
| 0x42–0x43 | 02 00 | Clear 16-bit per-card value (same value on all three tracks) | hypothesized | Not encrypted; record +0x1A6. 001E, 0002, 002A, 7910, 2AD1 across five cards, fixed for the life of each card. Looks like a random per-card identifier rather than a counter. |
| 0x44 | 0A | Clear track-type byte | hypothesized | Not encrypted; record +0x1B2. 0A on track 1, 0C on tracks 2 and 3, on every file. |
Encrypted 0x00 to 0x3F, clear 0x40 to 0x44. This is the track that changes as a horse races, so it is the one where before-and-after cards will do the most work.
| Offset | Bytes on the sample card | Field | Status | Evidence |
|---|---|---|---|---|
| 0x00 | 5C | Speed (スピード) | confirmed | Record +0x138. The six ability bytes sit in the order of the in-game HORSE ABILITY panel. Fresh: 31, 30, 29, 51, 28, 25; after a strawberry and a slope session: 31, 30, 37, 51, 28, 66; a card rewritten to 92, 90, 88, 85, 85, 90 loaded and raced with those values kept. Racing later grew one stat to 185, which displayed correctly, while cards written with all six at 254 and at 200 show full bars on the satellite's ability panel but empty bars on the multiboard's pre-race panel. A 254 card built on a real 5-race horse with its history intact behaves the same way, and so do 200, 190 and 185 on that horse, while all six at 100 draw normally. One stat at 250 with the other five at 60 blanks all six bars, so this is not a total cap and not clipping of one bar: the multiboard refuses the whole panel when the stats fail a check. It is not a fixed limit either: the same horse's unedited card, with its spurt at 185, draws normally on the multiboard with that bar the longest, while all six at 185 do not. Bisecting with all six stats equal: 100, 127 and 128 draw, 140, 150, 185, 190, 200 and 254 do not, and a fresh 0-race horse at 128 draws too, so the check is a fixed per-stat ceiling that does not depend on history or on the 0x30-0x37 block (raising that block changes nothing). The lowest ceiling among speed, stamina, sharpness, start and corner lies between 129 and 139; spurt's lies between 185 and 199 (185 legal, 200 not). The bars themselves scale to 255 (127 fills half the box). Which of the five carries the low ceiling is being pinned next. The same 254 card reads Rank A on both screens where the empty-history 200 card read Rank C. |
| 0x01 | 5A | Stamina (粘り, Grit in the English patch) | confirmed | Record +0x139. Fed from game-record +0x3C, the slot the legacy DOC 2000 writer stores as Stamina. |
| 0x02 | 58 | Sharp (切れ味, Burst in the English patch) | confirmed | Record +0x13A. Fed from game-record +0x44, the DOC 2000 Sharp slot. Went 29 to 37 after one strawberry. |
| 0x03 | 55 | Start (スタート) | confirmed | Record +0x13B, game-record +0x5E (DOC 2000 external 1, Start). |
| 0x04 | 57 | Corner (コーナー) | confirmed | Record +0x13C, game-record +0x5F (DOC 2000 external 2, Corner). Grew 85 to 87 across races. |
| 0x05 | B9 | Spurt (末脚, Kick in the English patch) | confirmed | Record +0x13D, game-record +0x62, which the legacy DOC 2000 writer stores in the DOC 2000 Tenacity slot: slot homology only, the game is different. Went 25 to 66 after one slope session, then 90 to 115 and 115 to 185 across races with no training, so racing grows it and the scale runs well past 100. |
| 0x06 | 00 | Byte to record +0x13E | unknown | Zero on every file. Unlabelled. |
| 0x07 | D8 | Distance aptitude (距離) | confirmed | Record +0x13F, labelled 距離 in the debug printout. 216 on this horse in every save: a fixed trait. |
| 0x08–0x09 | 00 00 | Unused | confirmed | The unpacker never reads these two bytes (no bit of either changes any record field). Zero on every file. |
| 0x0A | BD | Personality: 真面目 (serious) | confirmed | Record +0x143, the first of the five trait bytes the debug printout labels; printed raw and as raw minus 128. Fixed per horse. A horse the game announced at creation as having champion signs reads FF in all five trait bytes, every trait at its maximum; one announced as full of promise reads AA 86 A0 C9 BD, every trait above 128; one announced as having a rough personality reads 78 in the first byte (真面目, seriousness, below 128) with the rest just above; ordinary horses read values scattered on both sides of 128. |
| 0x0B | B8 | Personality: 根性 (guts) | confirmed | Record +0x144. |
| 0x0C | 6E | Personality: 目立ち (showiness) | confirmed | Record +0x145. |
| 0x0D | 84 | Personality: 頭 (brains) | confirmed | Record +0x146. |
| 0x0E | 88 | Personality: 気強 (strong will) | confirmed | Record +0x147. |
| 0x0F | 38 | Race experience (レース経験) | confirmed | Record +0x142. 0, 8, 16, 56 across the four saves as the horse raced; the on-screen bar grew in step. |
| 0x10 | 16 | Trust / bond (信頼) | confirmed | Record +0x148. 0 fresh, 4 after the first race, 0 on the save where the owner reported the bond had reset, 22 after stable events. |
| 0x11 | BD | Mood (気分) | confirmed | Record +0x149. 255 fresh, then 213, 169, 189. |
| 0x12 | ED | Condition (体調) | confirmed | Record +0x14A. 253 fresh, then 251, 251, 237. |
| 0x13 | 1C | Byte to record +0x136 | unknown | 00, 03, 0B, 1C across the saves; grows with racing. Unlabelled. |
| 0x14–0x17 | 60 EA 00 00 | Prize money (獲得総賞金), little-endian u32 shifted right 4 bits, in units of 10,000 yen | confirmed | Record +0x14C. The stable screen extracts a 28-bit field here and splits it into 億 and 万. Decodes to 100, 550 and 3750 万 on the raced saves; the screen showed 100万 after the first race. The low four bits of byte 0x14 feed two other record slots (+0x154, +0x15B). |
| 0x18 | 00 | Accessories in bits 1-0 (bit 0 noseband, bit 1 hood); G1 titles 0-5 in bits 7-2 | confirmed | Record +0x154 bits 5-7 and +0x155 bits 0-4. A horse created with only a noseband reads 01, one with only a hood reads 02, one with only leg wraps reads 00. Bits 2-7 are the first six of the 24 G1 title bits (see 0x19). |
| 0x19–0x1A | 00 00 | G1 titles 6-21, one bit each, in the on-screen list order | confirmed | Record +0x155 bits 5-7, +0x156, +0x157 bits 0-4. The 24 title bits run contiguously from byte 0x18 bit 2 (title 0) to byte 0x1B bit 1 (title 23), in the order the pre-race board lists them reading down the columns: February Stakes, Royal Sho, Oka, Satsuki, Tenno Sho S, NHK Mile Cup, Moonlight Dash, Japanese Oaks, Japanese Derby, Yasuda, Takarazuka, Super Dirt Grand Prix, Sprinters Stakes, Shuka, Kikka, Tenno Sho A, QEII Cup, Mile Championship, Japan Cup Dirt, Japan Cup, Hanshin Juvenile Fillies, Asahi Hai Futurity, Arima Kinen, Derby Owners Cup. Verified by a card with bits 5-23 set: the board lit those nineteen and left the first five grey. In the ROM the routine at 0x0C0B8E7E extracts this field (25 bits from bit 7 of the word at record +0x154) and 0x0C0B8D14 turns it into fifteen honours by combination: classic triple crown (Satsuki, Derby, Kikka), filly triple crown (Oka, Oaks, Shuka), Tenno Sho spring and autumn, the three miles (NHK, Yasuda, Mile Championship), February Stakes with Japan Cup Dirt, Japan Cup with Arima Kinen, Takarazuka with Arima Kinen, the three house races (Moonlight Dash, Super Dirt Grand Prix, Derby Owners Cup), and larger combinations of the same. The highest new honour is written to record +0x16B, the slot the debug printout labels as rank. |
| 0x1B | 00 | G1 titles 22-23 in bits 1-0 (Arima Kinen, Derby Owners Cup); bit 2 spare title bit 24; bits 7-3 to record +0x15B | hypothesized | Zero on every file seen. Bits 3-7 land in record +0x15B, which no formatter seen so far reads; unlabelled. |
| 0x1C | 05 | Races run (戦) | confirmed | Record +0x153, the byte the stable screen prints as 戦. 0, 1, 2, 5 across the saves. |
| 0x1D | 01 | Wins (勝) | confirmed | Record +0x152, printed as 勝. 0 until the first win, then 1. |
| 0x1E | 04 | Training sessions (調教) | confirmed | Record +0x16F, printed as 調教 %d回. 1, 2, 2, 4 across the saves; 10 on the older horse. |
| 0x1F | 92 | Byte to record +0x173 | hypothesized | 23, 93, 93, 92 across the saves; B1 on the older horse. Unlabelled, changes at the debut. |
| 0x20 | 40 | Last finishing position (今順位) in bits 3-0, zero-based; bits 7-4 unlabelled | confirmed | The debug printout reads 今順位 from record word +0x15C bits 17-14, and the bit-flip run shows those four record bits are fed by bits 0-3 of this byte. Her saves read 8 after finishing 9th, 3 after 4th, 0 after the win. The high nibble went 1, 2, 4 across the same saves; unlabelled. |
| 0x21–0x23 | 00 00 02 | Packed fields (record +0x158..+0x15F) | hypothesized | Three bytes split across small record slots next to the placing field. Zero on the fresh horse; 02 at 0x23 on the older horse. Unlabelled. |
| 0x24–0x26 | 00 00 00 | Packed fields (record +0x15C, +0x161..+0x163) | hypothesized | Feed the words that hold the placing and running-style fields. Zero on every save of the young horse; unlabelled. |
| 0x27 | B0 | Previous finishing position (前順位) in bits 7-4, zero-based; bits 3-0 to record +0x15C | confirmed | The debug printout reads 前順位 from record word +0x15C bits 13-10, which the bit-flip run traces to bits 4-7 of this byte. 0 before the second race, 8 after it (the previous race was a 9th), B on the later save. |
| 0x28–0x29 | C1 40 | Rank class in byte 0x29 bits 7-5; the rest packed fields (record +0x196, +0x197) | hypothesized | 00 00 until the second race, then 40 20, then C1 40 on the one horse followed through its career. The ROM reads a 3-bit field from the top of record +0x197 (this byte's bits 7-5) and maps only the values 0-4 to a rank code, five levels; 5-7 fall through unchanged (a card written with 5 shows C on the satellite, the default left in the slot, and no badge at all on the multiboard), which is why writing FF FF here kept the letter A but drew a blue badge. The horse carrying 2 shows A, a card written with 3 shows S and one with 4 shows SS, on both the satellite and the multiboard; 0 and 1 are expected to be C and B and are out for confirmation. Rank is therefore stored on the card, not derived: a card with 5億 earned but this field at 0 showed rank C. The lower bits of the word are read by the stable screen after the prize money and are not yet named. |
| 0x2A | 26 | Byte to record +0x160, +0x167 | unknown | 00 until the save with stable events, then 26. Event-flag candidate. |
| 0x2B | 4D | Running style (脚質) in bits 7-5; bits 4-0 to record +0x160, +0x161 | hypothesized | The debug printout prints 脚質 from the low three bits of record +0x161, and those three bits are fed by bits 5-7 of this byte. Values 0, 3, 2, 2 across the saves. The debug printout indexes the ROM's style table with this value: 0 逃げ (front-runner), 1 先行 (stalker), 2 差し (closer), 3 追込 (deep closer), 4 自在 (versatile). So this horse debuted as a deep closer and settled as a closer; the owner's note that the game reveals a horse's style in its early races fits. Not yet checked against the on-screen style, so hypothesized. |
| 0x2C | B1 | Turf aptitude (芝) | confirmed | Record +0x184. Fixed per horse (B1). |
| 0x2D | 60 | Dirt aptitude (ダート) | confirmed | Record +0x185. Fixed per horse (60). |
| 0x2E | 87 | Heavy turf aptitude (重芝) | confirmed | Record +0x186. Fixed per horse (87). |
| 0x2F | 5A | Heavy dirt aptitude (重ダート) | confirmed | Record +0x187. Fixed per horse (5A). |
| 0x30–0x37 | D8 C3 BA C7 C0 C3 BF 89 | Eight bytes to record +0x188..+0x18F | unknown | Whole-byte copies, fixed per horse so far (D8 C3 BA C7 C0 C3 BF 89 on one). Bytes 0x32, 0x33, 0x36, 0x37 are the ones the XOR check protects. Unlabelled, but two ROM routines (0x0C0B9E36, 0x0C0BBD06) read byte 0x30 and branch on whether it is above 128, the same treatment the five personality bytes get, so this block reads as further 128-centred trait values. The pre-race screen lists 24 G1 titles the game tracks per horse (February Stakes through Derby Owners Cup), so a 24-bit title bitfield exists somewhere on the card; none of the horses seen has won a G1, and this block and 0x28-0x29 are the candidates. |
| 0x38–0x39 | 00 00 | Unused | confirmed | Never read by the unpacker. Zero on every file. |
| 0x3A–0x3B | 7B 13 | 16-bit integrity check | confirmed | Same routine as track 1, over bytes 0x00 to 0x39; record +0x1AE. |
| 0x3C–0x3F | C3 87 D7 BE | Scattered-byte check | confirmed | Big-endian u32 of bytes 0x32, 0x33, 0x36, 0x37 XOR 79406837, verified on every file. Consumed by the decoder only. |
| 0x40–0x41 | 13 00 | Clear card-issue counter | confirmed | Not encrypted; record +0x1A2; same value as track 1. |
| 0x42–0x43 | 02 00 | Clear per-card value | hypothesized | Not encrypted; record +0x1A8; same value as track 1. |
| 0x44 | 0C | Clear track-type byte | hypothesized | Not encrypted; record +0x1B3; 0C on every file. |
Clear 0x00 to 0x07 and 0x40 to 0x44, encrypted 0x08 to 0x3F. Nothing on this track changed across training and a race either.
| Offset | Bytes on the sample card | Field | Status | Evidence |
|---|---|---|---|---|
| 0x00–0x07 | 53 45 47 41 42 44 59 30 | Magic string SEGABDY0 | confirmed | Clear, never encrypted; record +0x1B5. SEGA plus the product code at ROM header offset 0x134, the same construction World Edition uses for SEGABEF0. |
| 0x08–0x09 | 00 00 | Packed byte pair to record +0x19B | hypothesized | Both bytes feed one record slot. One code path increments byte 0x09 (capped at 63) before re-encoding, but it stayed 00 through four rewrites, so that path was not taken. Meaning open. |
| 0x0A | 00 | Byte to record +0x19C | unknown | Zero on every file. Unlabelled. |
| 0x0B | 00 | Unused | confirmed | Never read by the unpacker. |
| 0x0C–0x0F | 46 00 F3 03 | Four bytes to record +0x11A..+0x11D | unknown | 5F 00 47 04 on one horse, 46 00 F3 03 on the other, fixed across saves. Per-horse identity data; unlabelled. |
| 0x10 | 05 | Byte to record +0x19D | unknown | 05 on both horses. |
| 0x11 | 00 | Unused | confirmed | Never read by the unpacker. |
| 0x12–0x13 | 27 08 | 16-bit value to record +0x19E | unknown | 0827 on both horses. A date-like reading is tempting and unproven. |
| 0x14–0x15 | F9 F5 | 16-bit value to record +0x34 | unknown | B4C8 on one horse, F5F9 on the other. |
| 0x16–0x39 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 … | Unused | confirmed | Thirty-six bytes the unpacker never reads. Zero on every file, including the well-played horse. |
| 0x3A–0x3B | EA 80 | 16-bit integrity check | confirmed | Same routine, over the 56-byte encrypted block (bytes 0x08 to 0x3F); record +0x1B0. |
| 0x3C–0x3F | 62 84 59 61 | XOR check, constant 62845961 | hypothesized | Stored value equals the constant XOR zero on every file. The decoder compares it against three scattered bytes near 0x09; exact positions not yet pinned. |
| 0x40–0x41 | 13 00 | Clear card-issue counter | confirmed | Not encrypted; record +0x1A4; same value as track 1. |
| 0x42–0x43 | 02 00 | Clear per-card value | hypothesized | Not encrypted; record +0x1AA; same value as track 1. |
| 0x44 | 0C | Clear track-type byte | hypothesized | Not encrypted; record +0x1B4; 0C on every file. |
Three kinds of card file, each compared against the one before it:
Cards can be posted in the community Discord's #doc-ii channel. Everything on this page will be updated as they come in, and the tags moved only when the evidence supports it.
All addresses are SH-4 RAM addresses for epr-22306b.ic22 (file offset plus 0x0C020000). Encode three tracks 0x0C09B190, decode 0x0C09B1CC, one-time init 0x0C09B20C, per-track decoders 0x0C09AAC0 / 0x0C09ACE8 / 0x0C09AF10, round driver 0x0C09B240, f-function 0x0C09B79C, key schedule 0x0C09B6B0, integrity check 0x0C09C024, image-to-record unpacker 0x0C0994B4. Key material lives at 0x8C1520E8 and 0x8C152268 (16 bytes per pass, the low nibble of each byte carries four key bits), S-boxes at 0x8C152FE8 and 0x8C1593A8. The ROM also carries the older single-track DOC 2000 card codec, so DOC II can read a DOC 2000 card. If you emulate this code with Ghidra, note that its SuperH4 model does not set PR on bsr; patch it or nothing returns.
Decoded 6 September 2026. Sample card contributed by varjak_. Written up by the Derby Owners Club preservation project.