Play Online
Preservation › The software › The DOC II card
Preservation · Software · DOC II

The DOC II card: byte map and cipher

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.

Where this stands

168bytes per card confirmed
23bytes hypothesized
16bytes still unknown
16real card files (thirteen horses) decoded, plus 1,657 single-bit-flipped images run through the game's own unpacker

The identity half of the card and every integrity check are settled. The career half (track 2) now has most of its bytes named too; what is left there is 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.

confirmedthe game's own code names the field and the decoded bytes agree with it
hypothesizedinferred from code structure or from homology with the DOC 2000 card, not yet checked against a second card or a before/after pair
unknownthe bytes exist and the game reads them, but nothing about their meaning is established

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.

The container

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.

The cipher

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. The plaintext also carries integrity checks, so a card with a single flipped byte is ejected. The cipher's keys and the checks' details are kept private here.

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.

Track 1: identity

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).

81ADC8CA8FA8D4828CBC3C26100050064D656A69726F204D63517565656E00004169722047726F6F7665006C00000000540050EF0DD00D400F00C173D592347C130002000A
OffsetBytes on the sample cardFieldStatusEvidence
0x00–0x0881 AD C8 CA 8F A8 D4 82 8CHorse name, 9 katakana codesconfirmedCode 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.
0x09BCHidden breeding weight in bits 7-2 (record +0x127); the rest to record +0x133hypothesizedThe unpacker splits this byte into two record slots the debug printout does not label. BC on one horse, BE on the other, so bits 7-2 read 47 on both. The foal generator reads record +0x127 bits 7-2 as the horse's hidden breeding weight: birth stats, growth ceilings and grade lean toward the parent with the larger weight, while surfaces, distance and personality are each copied from one parent, and the heavier parent is the less likely one to pass them on; the foal takes one parent's weight whole, 50/50 (see the FAQ's DOC II foal inheritance entry). House-roster weights run 26 to 60. The record side has been read twice independently; that these card bits feed it comes from one pass, so the row stays hypothesized.
0x0A–0x0B3C 26Bloodlines: the horse's sire line (0x0A, record +0x128) and its dam's sire line (0x0B, record +0x129)confirmedWhole-byte copies, fixed across four rewrites of one horse. Each is an index into the ROM's list of 105 bloodline names. A foal gets its sire's line in the first byte and its dam's own line in the second, and the cross (nick) tables read these four lines from the two parents (read twice independently; see the FAQ's DOC II nicks entry). The sample horse, by Mejiro McQueen out of Air Groove, reads 60 and 38, Partholon and Kampala: Mejiro McQueen's male line goes back to Partholon, and Air Groove's sire Tony Bin is by Kampala. The other horse reads 45 and 26 (Mejiro Sanman and Fine Top). The card-creation serializer gives a newly created horse the same default line in both bytes.
0x0C10Jockey silks: accent colour in bits 3-0, base colour in bits 7-4confirmedEvery 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.
0x0D00Silk pattern in bits 3-0 (16 patterns); bits 7-4 unlabelledconfirmedDefault 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.
0x0E50Byte to record +0xF2unknownWhole-byte copy, varies per horse (50, 10, A0, 40, 20, 00 seen), fixed across saves. Unlabelled appearance field.
0x0F06Sex in bits 7-6 (0 牡 male, 1 牝 female; the ROM's label table also has 2 せ gelding); coat index in bits 5-1confirmedThe 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. The label table does include せ (gelding) as value 2, but the game's foal generator only ever writes colt or filly, so no cabinet or Lab horse is a gelding. Bits 5-1 are the coat index into the ROM's 25-entry coat list: 0 栗毛 chestnut, 1 鹿毛 bay, 2 青毛 black, 3 芦毛 grey, 4 栃栗毛 liver chestnut (Dark Chestnut on the English patch), 5 黒鹿毛 dark bay, 6 白毛 white, 24 青鹿毛 brown (Dark Brown on the English cabinet), three more grey codes (10, 11 and 22) and fourteen codes the game all names 特殊毛, special (7 to 9, 12 to 21 and 23). Chestnut reads 0, bay 1, black 2, grey 3 and a dark liver chestnut 4, so the alignment is verified on five coats. Which coat a horse gets is worked out from the genes in bytes 0x30 to 0x33.
0x10–0x1F4D 65 6A 69 72 6F 20 4D 63 51 75 65 65 6E 00 00Sire name, 16 bytes ASCIIconfirmed“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–0x2F41 69 72 20 47 72 6F 6F 76 65 00 6C 00 00 00 00Dam name, 16 bytes ASCIIconfirmed“Racing Jean” and “Air Groove”, matching the dams chosen in-game; record +0x10A..+0x119.
0x30–0x3354 00 50 EFCoat genes, 32-bit (16 two-bit genes)confirmedCopied whole to record +0x120. Not a serial: it holds the horse's coat genes. The foal generator splits the word into 16 two-bit genes and, for each one, gives the foal one of the sire's two copies and one of the dam's at random; the coat index at 0x0F is then decoded from the genes (read twice independently). Grey is dominant, and white and the special coats need two copies of a recessive gene that no house-roster horse carries; each copy can mutate at birth (see the FAQ's DOC II coats entry for the odds). The card-creation serializer builds this word 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.
0x340DLeg-wrap colour in bits 6-4; other bits unlabelledhypothesizedBit 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 it is not a presence flag: whether wraps are fitted is stored on track 2 (byte 0x14 bit 3), and 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).
0x35D0Packed identity bits (record +0x12D, +0x12E)unknownD0, DF or 00 across the horses seen, fixed per horse and unrelated to silks or accessories. Unlabelled.
0x360DHood colour in bits 6-4; noseband colour in bits 3-1 (hood presence is track 2 byte 0x18 bit 1)hypothesizedBits 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. Bit 0 is not the hood flag, as this row once said: it is set on horses with no hood (the default 0D), and later hooded horses read 30 and 82 with bit 0 clear. Whether a hood is fitted is track 2 byte 0x18 bit 1. 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.
0x3740Byte to record +0x12F; bit 0 follows the hoodhypothesizedWhole-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–0x390F 0016-bit value to record +0x134unknown15 on both horses, every save. The card-creation serializer derives it from the same coat and genetics words as the appearance word. Unlabelled.
0x3A–0x3BC1 7316-bit integrity checkconfirmedAn integrity check over the track (details kept private). Recomputed by the game whenever the track changes.
0x3C–0x3FD5 92 34 7CID checkconfirmedA second integrity check (details kept private). The unpacker never reads these bytes.
0x40–0x4113 00Clear 16-bit card-issue counter (same value on all three tracks)confirmedNot 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–0x4302 00Clear 16-bit per-card value (same value on all three tracks)hypothesizedNot 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.
0x440AClear track-type bytehypothesizedNot encrypted; record +0x1B2. 0A on track 1, 0C on tracks 2 and 3, on every file.

Track 2: career

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.

5C5A585557B900D80000BDB86E84883816BDED1C60EA0000000000000501049240000002000000B0C140264DB160875AD8C3BAC7C0C3BF8900007B13C387D7BE130002000C
OffsetBytes on the sample cardFieldStatusEvidence
0x005CSpeed (スピード)confirmedRecord +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. Why some edited cards show empty bars. The game rejects edited stats that honest play cannot produce and blanks the panel; honest growth never trips it. The bars themselves scale to 255 (127 fills half the box). The same 254 card reads Rank A on both screens where the empty-history 200 card read Rank C.
0x015AStamina (粘り, Grit in the English patch)confirmedRecord +0x139. Fed from game-record +0x3C, the slot the legacy DOC 2000 writer stores as Stamina.
0x0258Sharp (切れ味, Burst in the English patch)confirmedRecord +0x13A. Fed from game-record +0x44, the DOC 2000 Sharp slot. Went 29 to 37 after one strawberry.
0x0355Start (スタート)confirmedRecord +0x13B, game-record +0x5E (DOC 2000 external 1, Start).
0x0457Corner (コーナー)confirmedRecord +0x13C, game-record +0x5F (DOC 2000 external 2, Corner). Grew 85 to 87 across races.
0x05B9Spurt (末脚, Kick in the English patch)confirmedRecord +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.
0x0600Byte to record +0x13EunknownZero on every file. Unlabelled.
0x07D8Distance aptitude (距離)confirmedRecord +0x13F, labelled 距離 in the debug printout. 216 on this horse in every save: a fixed trait.
0x08–0x0900 00UnusedconfirmedThe unpacker never reads these two bytes (no bit of either changes any record field). Zero on every file.
0x0ABDPersonality: 真面目 (serious)confirmedRecord +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.
0x0BB8Personality: 根性 (guts)confirmedRecord +0x144.
0x0C6EPersonality: 目立ち (showiness)confirmedRecord +0x145.
0x0D84Personality: 頭 (brains)confirmedRecord +0x146.
0x0E88Personality: 気強 (strong will)confirmedRecord +0x147.
0x0F38Race experience (レース経験)confirmedRecord +0x142. 0, 8, 16, 56 across the four saves as the horse raced; the on-screen bar grew in step.
0x1016Trust / bond (信頼)confirmedRecord +0x148. 0 fresh, 4 after the first race, 0 on the save where the owner reported the bond had reset, 22 after stable events.
0x11BDMood (気分)confirmedRecord +0x149. 255 fresh, then 213, 169, 189.
0x12EDCondition (体調)confirmedRecord +0x14A. 253 fresh, then 251, 251, 237.
0x131CFinishing points: adds 12 minus the finishing place at every raceconfirmedRecord +0x136. At 9 of 9 race transitions it rose by 12 minus the finish (a win adds 11, a 3rd 9, an 8th 4, a 12th nothing), and it never moved at a training or other save (0 of 37). The first horse's saves (00, 03, 0B, 1C) fit too. The arithmetic is confirmed, and so is its use: when the feeding screen sees 100 or more it takes off 100 and offers a special food (tropical fruit or drink for front runners, cheese for closers). It has nothing to do with rank.
0x14–0x1760 EA 00 00Prize money (獲得総賞金), little-endian u32 shifted right 4 bits, in units of 10,000 yen; byte 0x14 bit 3 = leg wraps fittedconfirmedRecord +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). Bit 3 of byte 0x14 is the leg-wrap flag: it lands with the noseband and hood bits (0x18 bits 0-1) in record +0x154 bits 4-6, and labelled horses match 5 of 5.
0x1800Accessories in bits 1-0 (bit 0 noseband, bit 1 hood); G1 titles 0-5 in bits 7-2confirmedRecord +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 (the wraps flag is 0x14 bit 3). On six new horses the game saved the accessories a few seconds after the first full save, and one test horse lost all three after a race. Bits 2-7 are the first six of the 24 G1 title bits (see 0x19).
0x19–0x1A00 00G1 titles 6-21, one bit each, in the on-screen list orderconfirmedRecord +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, Takamatsunomiya Kinen, Oka Sho, Satsuki Sho, Tenno Sho (Spring), NHK Mile Cup, Moonlight Dash, Oaks, Japanese Derby, Yasuda Kinen, Takarazuka Kinen, Dirt Grand Prix, Sprinters Stakes, Shuka Sho, Kikka Sho, Tenno Sho (Autumn), Queen Elizabeth II 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 checks 15 honours built from it, each with its own name in the ROM (read twice independently): 三冠 triple crown (Satsuki Sho, Japanese Derby, Kikka Sho); 五冠 five crowns (those three plus Japan Cup and Arima Kinen); 牝馬三冠 filly triple crown (Oka Sho, Oaks, Shuka Sho); 牝馬五冠 filly five crowns (those three plus Queen Elizabeth II Cup and Hanshin Juvenile Fillies); マイル三冠 mile triple crown (NHK Mile Cup, Yasuda Kinen, Mile Championship); 秋の王道 the autumn championship route (Tenno Sho (Autumn), Japan Cup, Arima Kinen); オリジナルG1 the game's own G1s (Derby Owners Cup, Dirt Grand Prix, Moonlight Dash); and eight pairs: ダートG1 (February Stakes, Japan Cup Dirt), ベストスプリンター賞 (Takamatsunomiya Kinen, Sprinters Stakes), ベストステイヤー賞 (Tenno Sho (Spring), Kikka Sho), ダブルグランプリ (Takarazuka Kinen, Arima Kinen), 春の王道 (Tenno Sho (Spring), Takarazuka Kinen), ダブル天皇賞 (both Tenno Sho races), ダブルJカップ (Japan Cup, Japan Cup Dirt) and ダブルSSタイトル (Japan Cup, Derby Owners Cup). Japan Cup with Arima Kinen on its own is not an honour, and Asahi Hai Futurity counts toward none. Each name fits its set of titles, which independently confirms the title bit order. The four crowns also get their own in-game messages. The highest new honour is written to record +0x16B, the slot the debug printout labels as rank (the rank letter itself is stored at 0x29).
0x1B00G1 titles 22-23 in bits 1-0 (Arima Kinen, Derby Owners Cup); bit 2 spare title bit 24; bits 7-3 to record +0x15BhypothesizedZero on every file seen. Bits 3-7 land in record +0x15B, which no formatter seen so far reads; unlabelled.
0x1C05Races run (戦)confirmedRecord +0x153, the byte the stable screen prints as 戦. 0, 1, 2, 5 across the saves.
0x1D01Wins (勝)confirmedRecord +0x152, printed as 勝. 0 until the first win, then 1.
0x1E04Training sessions (調教)confirmedRecord +0x16F, printed as 調教 %d回. 1, 2, 2, 4 across the saves; 10 on the older horse.
0x1F92Last training menu in bits 7-4; bits 3-0 probably the result grade of that sessionconfirmedRecord +0x173. The debug printout's メニュー:%s (0x0C113E76) reads these four bits and prints them through the ROM's menu table: 0 森林 forest, 1 温泉 hot spring, 2 単走芝 solo turf, 3 単走ダート solo dirt, 4 単走ウッド solo wood, 5 単走坂路 solo slope, 6 併せ芝 paired turf, 7 併せダート paired dirt, 8 併せウッド paired wood, 9 併せ坂路 paired slope, 10 コーナー corner, 11 プール pool, 12 調教, 13 レース. The byte changed at 29 of 30 trainings (the other repeated the same menu with the same result) and at 0 of 9 races, and the stat that grew most matches the menu. The low four bits read 0 to 4 on all 55 trained cards, matching the ROM's five training results (完璧 perfect, 大成功 great success, 成功 success, 失敗 failure, 大失敗 big failure); that reading is still a hypothesis.
0x2040Last finishing position (今順位) in bits 3-0, zero-based; bits 7-4 start the finish countersconfirmedThe 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: it is the low end of the finish counters (see 0x21 to 0x23).
0x21–0x2300 00 02Finish counters: read 0x20 to 0x23 as a little-endian u32; bits 4-10 count finishes 4th or worse, 11-17 third places, 18-24 second places, 25-31 winsconfirmedRecord +0x158..+0x15F. Each counter is 7 bits. On 91 of 91 cards the four counters add up to the race count (0x1C) and the win counter equals the wins byte (0x1D), and at 9 of 9 race transitions exactly the counter for that race's finish moved. No second place has been seen yet, so the second-place slot is inferred from the gap between the other two and from the sum always holding. Zero on the fresh horse.
0x24–0x2600 00 00Packed fields (record +0x15C, +0x161..+0x163)hypothesizedFeed the words that hold the placing and running-style fields. Zero on every save of the young horse and constant on every card in the playtest vault; unlabelled.
0x27B0Previous finishing position (前順位) in bits 7-4, zero-based; bits 3-0 to record +0x15CconfirmedThe 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.
0x28C1Low byte of the rank word (record +0x196): looks like rank and win markershypothesizedRead with 0x29 as one word, the bits below the rank look like markers: bit 6 set once a horse has reached B, bit 7 once it has reached A, and bits 0 and 1 after its first and second wins (40 at rank B with no win, 41 after a first win, C1 at rank A with one win, C3 at rank A with two). Four states on two horses and no contradiction; hypothesized until an S horse or a third win is seen. The stable screen reads these bits after the prize money.
0x2940Rank in bits 7-5 (0 C, 1 B, 2 A, 3 S, 4 SS); bits 4-0 the top of the rank word's other bits (record +0x197)confirmed00 until the second race, then 20, then 40 on the one horse followed through its career. The debug printout's 現在のランク (0x0C1140F2) extracts exactly this field and names it from the ROM's table 0 C, 1 B, 2 A, 3 S, 4 SS, 5 OP, and the playtest vault fits (0, then 1, then 2 as the horse's prize money grew). Rank follows the horse's total prize money and is rechecked after every race: B from 5 million yen, A from 30 million, S from 100 million and SS from 500 million, so it never goes down (see the FAQ's DOC II rank entry). The rank reader at 0x0C097C9C maps only 0-4 to a rank code; 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. Rank is therefore stored on the card, not derived: a card with 5億 earned but this field at 0 showed rank C.
0x2A26Byte to record +0x160, +0x167unknown00 until the save with stable events, then 26. Event-flag candidate.
0x2B4DRace development (展開) in bits 7-5; bits 4-0 to record +0x160, +0x161hypothesizedRecord +0x161 low three bits, fed by bits 5-7 of this byte. The debug printout prints this field under 展開 (race development), through the same name table as running style: 0 逃げ (front-runner), 1 先行 (start dash), 2 差し (last spurt), 3 追込 (stretch-runner), 4 自在 (almighty). (Its 脚質 line comes from the race-entry record, not from the card.) Values 0, 3, 2, 2 across the saves, so this horse debuted as 追込 and settled as 差し; the owner's note that the game reveals a horse's style in its early races fits. It moves only at races (4 of 9), never at training (0 of 30). The code's rule (see the FAQ's DOC II running style entry): after each race the game records 逃げ if the horse was 1st or 2nd early in the race, 先行 if 3rd or 4th, otherwise 差し if it was in the top nine late in the race, else 追込; the horse uses that style in its next race, and the card keeps the last five. The game never records or suggests 自在. This byte's link to that record is not yet checked against the on-screen style, so hypothesized.
0x2CB1Turf aptitude (芝)confirmedRecord +0x184. Fixed per horse (B1).
0x2D60Dirt aptitude (ダート)confirmedRecord +0x185. Fixed per horse (60).
0x2E87Heavy turf aptitude (重芝)confirmedRecord +0x186. Fixed per horse (87).
0x2F5AHeavy dirt aptitude (重ダート)confirmedRecord +0x187. Fixed per horse (5A).
0x30D8Copy of the distance aptitude (0x07)confirmedRecord +0x188. Equals byte 0x07 on 91 of 91 cards. Two ROM routines (0x0C0B9E36, 0x0C0BBD06) branch on whether it is above 128, consistent with a 128-centred aptitude.
0x31–0x36C3 BA C7 C0 C3 BFGrowth ceilings, one per stat, in stat order (Speed, Stamina, Sharp, Start, Corner, Spurt)confirmedRecord +0x189..+0x18E. Growth clamps each stat to its own ceiling (0x0C0C7894), and the training-gain code weights each gain by how much room is left, (ceiling minus stat) divided by ceiling (0x0C0C76A4). Fixed for life on every save; 0xA0 to 0xD9 (160 to 217) on the horses read. Going to the farm lifts a retired horse's stats past them.
0x3789Grade: each group of three stats is held to 3 x gradeconfirmedRecord +0x18F. Speed + Stamina + Sharp can never grow past 3 × grade, and neither can Start + Corner + Spurt: when training or a race would push a group over, the growth routine (0x0C0C7580 and its three siblings) trims the stat that just grew back to fit. At grade 139 the limit is 417, so a horse at 140/140/140 loses 3 on whichever stat it just trained, which every test horse showed. Real horses read 132 to 140 (0x84 to 0x8C), unchanged through every training and race; the one save that looks like a retirement raised it from 139 to 148 (0x8B to 0x94). The creation ladder at 0x0C0D09C2 is only the legacy DOC 2000 import.
0x38–0x3900 00UnusedconfirmedNever read by the unpacker. Zero on every file.
0x3A–0x3B7B 1316-bit integrity checkconfirmedSame kind of check as track 1 (details kept private).
0x3C–0x3FC3 87 D7 BEXOR checkconfirmedA second integrity check (details kept private).
0x40–0x4113 00Clear card-issue counterconfirmedNot encrypted; record +0x1A2; same value as track 1.
0x42–0x4302 00Clear per-card valuehypothesizedNot encrypted; record +0x1A8; same value as track 1.
0x440CClear byte (record +0x1B3)hypothesizedNot encrypted. Not a constant track type, as this row once said: it reads 0B on 70 of 75 playtest-vault cards and 0C on 5, all real cabinet writes, and one test horse went from 0B to 0C between two saves (Flycast files read 0C). Meaning open.

Track 3: header

Clear 0x00 to 0x07 and 0x40 to 0x44, encrypted 0x08 to 0x3F. Nothing on this track changed across training and a race either.

5345474142445930000000004600F30305002708F9F5000000000000000000000000000000000000000000000000000000000000000000000000EA8062845961130002000C
OffsetBytes on the sample cardFieldStatusEvidence
0x00–0x0753 45 47 41 42 44 59 30Magic string SEGABDY0confirmedClear, never encrypted; record +0x1B5. SEGA plus the product code at ROM header offset 0x134, the same construction World Edition uses for SEGABEF0.
0x0800Retired flag in bit 0 (record +0x19B bit 7); the other bits unlabelledconfirmedThe unpacker writes bit 0 of this byte to record +0x19B bit 7, and the routine that sorts a card into racing or retired stallion or mare reads that bit (read twice independently). It was set by exactly one save in the playtest vault: 12 seconds after a normal race save, with no race or training counted, every stat rose 22 to 101 points and the grade went from 139 to 148, and the next save on that card started a new horse. That is the horse going to the farm: retiring lifts all six stats and can raise the grade (see the FAQ's DOC II retire and grade entries).
0x0900Breeding-screen use counter, 0 to 63 (record +0x19B bits 6-1)confirmedEach time a retired horse's card is read at the cabinet's breeding screen, the game adds 1 to this byte while it is under 63, re-encodes the card and writes it back (0x0C0D002C), before any foal is made; only one stallion card and one mare card count per visit (read twice independently). The count drives breeder wear: the first uses are free, 18 of them for a horse with fewer than 30 races and training sessions combined, down to 9 at 70 or more; after that the horse wears: a worn stallion lowers the foal's birth stats and his ability messages start after about 17 to 26 uses in all, while worn parents of either sex lower its growth ceilings and grade; a broodmare's messages come sooner, and her wear never lowers birth stats. House-roster horses never wear (see the FAQ's DOC II breeding decline entry for the message points and sizes). The byte stayed 00 through four rewrites of a horse that never bred.
0x0A00Byte to record +0x19CunknownZero on every file. Unlabelled.
0x0B00UnusedconfirmedNever read by the unpacker.
0x0C–0x0F46 00 F3 03Four bytes to record +0x11A..+0x11Dunknown5F 00 47 04 on one horse, 46 00 F3 03 on the other, fixed across saves. Per-horse identity data; unlabelled.
0x1005Byte to record +0x19Dunknown05 on both horses.
0x1100UnusedconfirmedNever read by the unpacker.
0x12–0x1327 0816-bit value to record +0x19Eunknown0827 on both horses. A date-like reading is tempting and unproven.
0x14–0x15F9 F516-bit value to record +0x34unknownB4C8 on one horse, F5F9 on the other.
0x16–0x3900 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …UnusedconfirmedThirty-six bytes the unpacker never reads. Zero on every file, including the well-played horse.
0x3A–0x3BEA 8016-bit integrity checkconfirmedSame kind of check (details kept private).
0x3C–0x3F62 84 59 61XOR checkhypothesizedA second integrity check (details kept private).
0x40–0x4113 00Clear card-issue counterconfirmedNot encrypted; record +0x1A4; same value as track 1.
0x42–0x4302 00Clear per-card valuehypothesizedNot encrypted; record +0x1AA; same value as track 1.
0x440CClear track-type bytehypothesizedNot encrypted; record +0x1B4; 0C on every file.

What would settle the open rows

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.

Notes for people reading the ROM

All addresses are SH-4 RAM addresses for epr-22306b.ic22 (file offset plus 0x0C020000). The image-to-record unpacker is at 0x0C0994B4; the cipher's routines, keys and tables are kept private. 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_. Updated 30 September 2026 with the grade rule, the growth ceilings, the finish counters, finishing points, last training menu and rank table, from a 19 September pass over the arcade's playtest cards; updated again the same day with the retired flag, the breeding-screen use counter, the bloodline bytes, the coat genes and coat list, and the named honours, from a second, independent pass over the ROM. Written up by the Derby Owners Club preservation project.

Back to the software page Bring us a card