Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Will send all commands to this thing up to four times in a row, assuming no errors.
- Refer to these two dumps:
- vru.USA-all-test.txt (E Pikachu) https://pastebin.com/5Fr9G36N
- DdG_log_full_route_statuses.bin.txt (J Densha) https://pastebin.com/rNe7CQNf
- All logged commands are taken after sending and reading back response.
- All listed below are PIF commands, sent to the SI like normal controller commands. Values marked "address" will use the standard pifcmd address checksum algo, though it's suspected the field is ignored in most commands. "Data" uses the standard pifcmd data checksum.
- In pythonese:
- def ctrl_address_crc(address):
- """Returns checksum used for HW address."""
- ret = 0
- for i in range(16):
- ret <<= 1
- v = 0x15 if ret & 0x20 else 0
- ret |= bool(address & 0x400)
- address <<= 1
- ret ^= v
- return ret & 0x1F
- def ctrl_data_crc(data, length=None):
- """Returns checksum for data sent to serial device.
- If length is not given, uses the length of the data.
- NOTE! Normal 32byte controller pak data must be 32 bytes,
- not 33! That was an assumption on their part!"""
- ret = 0
- if length is None:
- length = len(data)
- for i in data[:length]:
- m = 0x80
- while m:
- ret <<= 1
- x = bool(i & m)
- if ret & 0x100:
- ret ^= 0x85 - x
- else:
- ret += x
- m >>= 1
- for i in range(8):
- ret <<= 1
- if ret & 0x100:
- ret ^= 0x85
- return ret & 0xFF
- Important commands:
- FD
- Device channel reset
- read 0x25 bytes of data from VRU addy
- 03.25.09xxxx.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcc
- send:
- x combination of value and address checksum
- FFE0 address
- 001F checksum
- recieve:
- d data (0x24)
- data is 16bit byteswapped
- c data checksum for d
- set to 0xFF on send
- data breakdown:
- 0 4 unknown; J & E VRUs always seems to report 80000F00
- 4 2 error flags
- 6 2 # valid results (?)
- 8 2 voice level from mic
- A 2 relative voice level
- C 2 voice length (prob. milliseconds)
- E 2 hit 1: index or 0x7FFF
- 10 2 hit 1: deviance value
- 12 2 hit 2: index or 0x7FFF
- 14 2 hit 2: deviance value
- 16 2 hit 3: index or 0x7FFF
- 18 2 hit 3: deviance value
- 1A 2 hit 4: index or 0x7FFF
- 1C 2 hit 4: deviance value
- 1E 2 hit 5: index or 0x7FFF
- 20 2 hit 5: deviance value
- 22 2 mode + status flags; normally should report 0040
- 23 1 data checksum
- error flags appear to be (byteswapped):
- 0400 voice too low; occurs with low voice levels and relative voice levels, unsure rules
- 0800 voice too high; any voice level over 0xDAC(?) appears to trigger this
- 4000 no valid matches; I think this means the deviation for all results is greater than the default 0x640 seen in software, since can report match results anyway.
- 8000 too much noise; relative voice level below 0x190(?) appears to trigger this
- 0x7FFF is always reported as an index when fewer than that number of entries are loaded into memory. For example, if only four words are loaded, index 5 will always be 0x7FFF.
- write 0x14 bytes of data to VRU addy
- 17.01.0Axxxxdddddddddddddddddddddddddddddddddddddddd.cc
- send:
- x combination of value and address checksum
- FFE0 address
- 001F checksum
- d data (0x14)
- data should be 16bit byteswapped, aligned right (so NULLs to the left but strings reading left->right, byteswapped.)
- recieve:
- c data checksum for d
- set to 0xFF on send
- J str data pattern is:
- ----0300 0000dddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd ddddff00
- Max length to send is 0x22, aligned to right side of buffer (0x26 - len(data)) and preceeded by 3. Data is 16bit LE. Flag indicates status after sending command. There's a NULL between the string and the 0003.
- Regardless, address always appears to be 0.
- Except for ー only Katakana and Hiragana may be used.
- Invalid as first char: ーんっゎンッヮヵヶ
- ぁ can only follow ふフヴ
- ァ can only follow ふフヴ
- ぃ can only follow うてでふウテデフヴ
- ィ can only follow うてでふウテデフヴ
- ぅ can only follow とどふトドフヴ
- ゥ can only follow とどふトドフヴ
- ぇ can only follow うしえちぢつふウシジチヂツフヴ
- ェ can only follow うしえちぢつふウシジチヂツフヴ
- ぉ can only follow うふウフヴ
- ォ can only follow うふウフヴ
- ゃ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ゅ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ょ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ャ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ュ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ョ can only follow きしちにひみりぎじぢびぴキシチニヒミリギジヂビピヴ
- ー cannot follow きっンッ
- ん and ン cannot repeat (んん or ンン)
- っ can only follow ーあいうえおなにぬねのまみむめもやゆよらりるれろわゐゑをんぁぃぅぇぉゃゅょっゎアイウエオナニヌネノマミムメモヤユヨラリルレロワヰヱヲンァィゥェォャュョッヮ
- ッ can only follow ーあいうえおなにぬねのまみむめもやゆよらりるれろわゐゑをんぁぃぅぇぉゃゅょっゎアイウエオナニヌネノマミムメモヤユヨラリルレロワヰヱヲンァィゥェォャュョッヮ
- E str data pattern is pretty much same:
- ----0300 0000 dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd 0000
- Always sent in sets of four commands, even when data is shorter than this.
- Refer to "USA VRU Sound Indicies.txt" for values. https://pastebin.com/ajLzRLze
- Also used to send the string mask patterns. Data is right-aligned and padded with zeroes to an even length, followed with command 0004. Set bits allow strings, unset ignores.
- read 2 bytes from VRU addy (mode & status)
- 03.03.0Bxxxx.ddddcc
- send:
- x combination of value and address checksum
- FFE0 address
- 001F checksum
- recieve:
- d data recieved from VRU (byteswapped)
- FF00 ???; returns error 5 when set
- 0200 ???; returns error 0xE or 5 when set (same error as bad wchar)
- 0100 ???; returns error 0xD or 5 when set
- 0040 ???; returns error 0xF when set
- 0007 mode
- c data checksum for d
- set to 0xFF on send
- write 4 bytes to VRU addy (HW commands/status + HW data)
- 07.01.0Cxxxxdddddddd.cc
- send:
- x combination of value and address checksum
- FFE0 address
- 001F checksum
- d data (4 bytes, byteswapped)
- 0007 0000 mode
- 0000 FFFF argument
- recieve:
- c data checksum for d
- set to 0xFF on send
- uses: (shown is byteswapped)
- 000 0200xx00 clears x strings from device
- 000 00000700 used when VRU Status is 1, 3, or 5 before setting words
- 000 05000000 stops listening
- 000 00000600 starts listening
- flags = VRU HW state when initializing(?) address; believed to control power
- 03.01.0Dxxxx.ff
- send:
- x combination of value and address checksum
- FFE0 address
- 001F checksum
- recieve:
- f error flags
- set to 0 on send
- Note they use a table of address, >> 3 actual: (1E, 6E, 08, 56, 03).
- Each is sent in-sequence, assuming nothing goes wrong.
- Also used when switching the device "off" and "on"; i.e.:
- Off:
- 03.01.0D080E.00
- 07.01.0C000005000000.4E
- 03.03.0B0000.010097
- 03.03.0B0000.050044
- On:
- 03.01.0D0000.00
- 03.03.0B0000.000000
- 07.01.0C000000000600.78
- Step 1: detect if a VRU is attached
- send SI Status commands. Device type is 0x100.
- reinit software flags
- On initial connect:
- check status:
- send SI Status cmd
- return Err 1 after four retests if Not Present flag
- return Err 0xB after four retests if not a VRU (device type != 0x100)
- return Err 4 if IO Error flag
- return Err 4 if addy crc error
- send SI cmd 0xFD to channel (initializes channel)
- return Err 4 on failure
- send SI cmd 0xD: 0F0
- if flag (cmd[5]) & 1, retest up to four times
- return Err 1 if Not Present, IO Error, or error retesting device status
- return Err 4 after four retests if flag & 1
- send SI cmd 0xD: 370
- (as above)
- send SI cmd 0xD: 040
- (as above)
- send SI cmd 0xD: 2B0
- (as above)
- send SI cmd 0xD: 018
- (as above)
- check status:
- (as above)
- return 0xF if Slot Empty flag
- send SI cmd 0xC: 000 00000100
- return Err 1 if Not Present, IO Error, or error retesting device status
- return Err 4 if data crc mismatch after four retests
- read VRU state:
- check status:
- (as above)
- return Err 0xF if Slot Filled flag
- state = send SI cmd 0xB: 000
- return Err 1 if Not Present or IO Error
- return Err 4 if data crc mismatch after four retests
- return Err 0xF if state & 0x40
- return Err 5 if state & 0xFF00
- USA initialization slightly different.
- After sending 0xFD commands, wait until Count advances 0x23C346. Presumably this is to ensure it's been adequately powered.
- check status
- state = send SI cmd 0xB: 000
- save status read by 0xB command to a register for comparison later. Looks like 0100 flag indicates USA; error 5 is returned on a mismatch.
- continue as normal
- State flag returned by status reads is inverted between J and U devices. (0:Japan, 1:USA)
- Step 2: send strings (J)
- if state in (1, 3, 5):
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- return 5 if mode == 0
- send SI cmd 0xC: 000 00000700
- (as above)
- [presumes no error; if one occurs loads uninitialized value off stack]
- retest 20 times
- read VRU state:
- (as above)
- mode = 0 if state & 0xFF00
- mode = 0, return 0 if (state & 7) == 0
- return Err 5 if (state & 7) == 7
- return Err state if state != 0xF
- return Err 0x10 if all retests fail
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- send SI cmd 0xC: 000 0200##00 # number of strings
- (as above)
- read VRU state:
- (as above)
- return Err 5 state & 0xFF00
- for i in strings:
- return Err 0xE if string unusable
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- byteswap i
- buf[0:0x26 - len(i)] = repeat(0, 0x26 - len(i))
- buf[0x26-len(i):] = i
- buf[0x22-len(i)] = 3
- if len(i) > 0xE:
- send SI cmd 0xA: 000 buf[:0x14]
- return Err 1 if Not Present or IO Error
- return Err 4 if data crc mismatch after four retests
- send SI cmd 0xA: 000 buf[0x14:0x28]
- (as above)
- read VRU state:
- (as above)
- return Err 0xD if state & 0x100
- return Err 0xE if state & 0x200
- return Err 5 if state & 0xFF00
- if also sending stringmask:
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- l = len(data) + (len(data) & 1)
- if len(data) & 1:
- data.append(0)
- byteswap data
- buf[0x12 - l] = 4
- buf[0x14-l:] = data
- send SI cmd 0xA: 000 buf[:0x14]
- (as above)
- return Err 5 if state & 0xFF00
- Step 2: send strings (E)
- if state not in (1, 3, 5):
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- return 5 if mode == 0
- send SI cmd 0xC: 000 00000700
- (as above)
- [presumes no error; if one occurs loads uninitialized value off stack]
- retest 20 times
- read VRU state:
- (as above)
- mode = 0 if state & 0xFF00
- mode = 0, return 0 if (state & 7) == 0
- return Err 5 if (state & 7) == 7
- return Err state if state != 0xF
- return Err 0x10 if all retests fail
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- send SI cmd 0xC: 000 0200##00 # number of strings
- (as above)
- read VRU state:
- (as above)
- return Err 5 state & 0xFF00
- for i in strings:
- # If no sum, no blocknum, or no length given, fill them in. (Official did this already)
- # If your sound entries are big endian, flip to little.
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- byteswap i
- buf[0:0x4F - len(i)] = repeat(0, 0x4F - len(i))
- buf[0x4F-len(i):] = i
- buf[0x4A-len(i)] = 3
- for j in range(0, 0x50, 0x14):
- send SI cmd 0xA: 000 buf[j:j+0x14]
- return Err 1 if Not Present or IO Error
- return Err 4 if data crc mismatch after four retests
- read VRU state:
- (as above)
- return Err 0xD if state & 0x100
- return Err 0xE if state & 0x200
- return Err 5 if state & 0xFF00
- if also sending stringmask:
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- l = len(data) + (len(data) & 1)
- if len(data) & 1:
- data.append(0)
- # If necessary, pad data to even length and byteswap data.
- buf[0x26 - l] = 4
- buf[0x28-l:] = data
- send SI cmd 0xA: 000 buf[:0x14]
- (as above)
- read VRU state:
- (as above)
- send SI cmd 0xA: 000 buf[0x14:0x28]
- ditto
- read VRU state:
- (as above)
- return Err 5 if state & 0xFF00
- Setting unresponsive until needed:
- 01.03.00.000100
- 03.03.0B0000.000000
- 03.01.0D080E.00 # optional to lower power
- 01.03.00.000101
- 07.01.0C000005000000.4E
- 01.03.00.000100
- 03.03.0B0000.010097
- 01.03.00.000101
- ...
- 01.03.00.000100
- 03.03.0B0000.050044
- 01.03.00.000101
- 03.01.0D0000.00 # optional to raise power
- 01.03.00.000101
- ...
- Fetching results:
- check status:
- (as above)
- return Err 0xF if Slot Empty flag
- return Err 5 if mode != 0
- send SI cmd 0xC: 000 05000000 # #results to read back?
- (as above)
- read VRU state
- (as above)
- return Err 5 if state & 0xFF00
- mode = 1
- (if previous Err 0xC returned resets state to listening)
- # with power regulation(?)
- 01.03.00.000100
- 03.03.0B0000.000000
- 01.03.00.000101
- 07.01.0C000000000600.78
- 01.03.00.000100
- 03.25.090000.80000F00000002009D057C07B004000077040400CC041000F9041400030505001205400097
- 03.01.0D0000.00
- # disable again
- 03.01.0D080E.00
- 01.03.00.000100
- 07.01.0C000005000000.4E
- 01.03.00.000100
- 03.03.0B0000.010097
- 01.03.00.000101
- #without
- 01.03.00.000100
- 03.03.0B0000.000000
- 01.03.00.000101
- 07.01.0C000000000600.78
- 01.03.00.000100
- 03.25.090000.80000F000000010045069A3570040700AC011000E60200001903120040031E005603400094
- # disable again
- 01.03.00.000100
- 07.01.0C000005000000.4E
- 01.03.00.000100
- 03.03.0B0000.010097
- 01.03.00.000101
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement