Advertisement
Zoinkity

MM VRU Running dASM

Feb 26th, 2018
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 45.72 KB | None | 0 0
  1. 80088AB0 0x9AB0 send or jam (A2) msg A1 to queue A0
  2. 80088C00
  3. 80088DA0 0x9DA0 800991AC = 0
  4. 80088DB0
  5. 80088E70 0x9E70 read or wait (A2) to write msg from queue A0 to A1
  6. 80088FB0
  7.  
  8. 800890B0 0xA0B0 V0 = errors when sending Shift-JIS string A1 to VRU using handle A0
  9. accepts: A0=p->VRU handle, A1=p->Shift-JIS string
  10. v = call 800936D0(@A0+0, @A0+4, SP+4B) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  11. if v:
  12. return v
  13. if SP[4B] & 2: # Err 0xF if Slot Empty set
  14. return 0xF
  15. l = 0
  16. while A1[l]:
  17. l += 2
  18. call 8008A5D0(SP+20, 0x28) # initialize A1 bytes at A0
  19. # 80089134: byteswap data, aligned to the right side of the buffer
  20. v = 0x27 - l
  21. for i in range(0, l, 2):
  22. SP[v+i+1] = A1[i]
  23. SP[v+i] = A1[i+1]
  24. # 8008917C
  25. if l >= 0xF:
  26. v = call 80091E10(@A0+0, @A0+4, 0, SP+20) # V0 = error state when sending SI cmd 0xA writing data A3 to VRU address A2 on port A1, informing queue A0
  27. if v:
  28. return v
  29. v = call 80091E10(@A0+0, @A0+4, 0, SP+34) # V0 = error state when sending SI cmd 0xA writing data A3 to VRU address A2 on port A1, informing queue A0
  30. if v:
  31. return v
  32. v = call 8008A520(A0, SP+4B) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  33. if not v:
  34. return 0
  35. elif v & 0x100:
  36. return 0xD # VRU buffer overflow
  37. elif v & 0x200:
  38. return 0xE # invalid word
  39. elif v & 0xFF00:
  40. return 5
  41. return v
  42. 80089240
  43.  
  44. 8008A520 0xB520 V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  45. accepts: A0=p->VRU handle, A1=p->controller status flags
  46. v = call 800936D0(@A0+0, @A0+4, A1) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  47. if v:
  48. return v
  49. if A1[0] & 1: # Err 0xF if Slot Filled set
  50. return 0xF
  51. v = call 8008FE70(@A0+0, @A0+4, 0, SP+20) # V0 = error state when sending SI cmd 0xB reading data from VRU address A2 on port A1 to A3, informing queue A0
  52. if v:
  53. return v
  54. A0[C] = SP[20] & 7 # state
  55. if SP[20] & 0x40:
  56. return 0xF
  57. return SP[21] << 8
  58. 8008A5D0 0xB5D0 initialize A1 bytes at A0
  59.  
  60. 8008A670 0xB670 write controller pak with rumble yada yada...
  61. 8008A7D8 0xB7D8 rumble pak yada yada...
  62. 8008A8E4
  63.  
  64. 8008AA40 0xBA40 create message queue 8009EAB8
  65. 80098E60 = True
  66. call 800901E0(8009EAB8, 8009EAB0, 1) # create msg queue A0 with A2 msgs at A1
  67. call 80088AB0(8009EAB8, 0, False) # send or jam (A2) msg A1 to queue A0
  68. 8008AA90 0xBA90 wait for msg on queue 8009EAB8, creating queue if necessary
  69. if not @80098E60:
  70. call 8008AA40() # create message queue 8009EAB8
  71. call 80088E70(8009EAB8, SP+1C, True) # read or wait (A2) to write msg from queue A0 to A1
  72. 8008AAD4 0xBAD4 send msg 0 to queue 8009EAB8
  73. call 80088AB0(8009EAB8, 0, True) # send or jam (A2) msg A1 to queue A0
  74. 8008AB00
  75.  
  76. 8008AF30 0xBF30 V0 = error state when sending SI cmd 1 reading controllers
  77. accepts: A0=p->queue
  78. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  79. if 8009EB10[0] != 1:
  80. call 8008B040() # fill buffer 8009EAD0 with SI status or reset (A0) commands
  81. call 8008BD10(1, 8009EAD0) # read or write (A0) between rdram A1 and pifram
  82. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  83. # 8008AF7C
  84. v = call 8008BD10(0, 8009EAD0) # read or write (A0) between rdram A1 and pifram
  85. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  86. return v
  87. 8008AFB4
  88. 8008B040 0xC040 fill buffer 8009EAD0 with SI status or reset (A0) commands
  89. 8008B110 0xC110 V0 = error state when writing VRU listening results to A1 using handle A0
  90. accepts: A0=p->VRU handle, A1=p->target
  91. if @A0+8 not in range(1,5):
  92. return 5
  93. if @A0+8 == 1:
  94. # 8008B15C
  95. v = call 800936D0(@A0+0, @A0+4, SP+5F) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  96. if v:
  97. return v
  98. if SP[5F] & 1:
  99. return 0xC
  100. v = call 8008FE70(@A0+0, @A0+4, 0, SP+38) # V0 = error state when sending SI cmd 0xB reading data from VRU address A2 on port A1 to A3, informing queue A0
  101. if v:
  102. return v
  103. A0[C] = SP[38] & 7
  104. 8009EB60[0] = SP[38] & 7
  105. if A0[C] not in (0, 7):
  106. return 0xC
  107. if @A0+8 in (1, 2):
  108. # 8008B1D8
  109. A0+8 = 2
  110. v = call 800936D0(@A0+0, @A0+4, SP+5F) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  111. if v:
  112. return v
  113. if SP[5F] & 2: # Err 0xF if Slot Empty set
  114. return 0xF
  115. SP+38 = 0x600
  116. v = call 80097500(@A0+0, @A0+4, 0, SP+38) # V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2, informing queue A0
  117. if v:
  118. return v
  119. if @A0+8 in (1, 2, 3):
  120. # 8008B240
  121. A0+8 = 3
  122. v = call 800936D0(@A0+0, @A0+4, SP+5F) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  123. if v:
  124. return v
  125. if SP[5F] & 1: # Err 0xF if Slot Filled set
  126. return 0xF
  127. v = call 80090770(@A0+0, @A0+4, 0, SP+38) # V0 = error state when sending SI cmd 9 reading data from VRU address A2 on port A1 to A3, informing queue A0
  128. if v:
  129. return v
  130. A1[0:2] = (SP[3D] << 8) + SP[3C] # error flags
  131. A1[2:4] = SP[3E] # number of valid results
  132. A1[4:6] = (SP[41] << 8) + SP[40] # mic voice level
  133. A1[6:8] = (SP[43] << 8) + SP[42] # voice level relative to noise
  134. A1[8:A] = (SP[45] << 8) + SP[44] # voice length
  135. for i in range(0, 0x14, 4): # not really a loop, but less confusing this way for comparison's sake
  136. A1[A+i:C+i] = (SP[47+i] << 8) + SP[46+i]
  137. A1[14+i:16+i] = (SP[49+i] << 8) + SP[48+i]
  138. # 8008B400
  139. if A1[A:C] == 0x7FFF: # when no hits, ensure no results listed
  140. A1[2:4] = 0
  141. A0[C] = SP[5A] & 7
  142. if not 8009EB60[0] or not A0[C]:
  143. A0+8 = 0
  144. return v
  145. if @A0+8 in (1, 2, 3, 4):
  146. # 8008B42C
  147. A0+8 = 4
  148. v = call 800936D0(@A0+0, @A0+4, SP+5F) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  149. if v:
  150. return v
  151. if SP[5F] & 1: # Err 0xF if Slot Filled set
  152. return 0xF
  153. v = call 8008FE70(@A0+0, @A0+4, 0, SP+38) # V0 = error state when sending SI cmd 0xB reading data from VRU address A2 on port A1 to A3, informing queue A0
  154. if v:
  155. return v
  156. A0[C] = SP[38] & 7
  157. if A0[C]:
  158. return 0xF
  159. return v
  160. 8008B4E0
  161.  
  162. 8008BD10 0xCD10 read or write (A0) between rdram A1 and pifram
  163. 8008BDC0
  164.  
  165. 8008FCD0 0x10CD0 V0 = errors when clearing A1 strings from VRU using handle A0
  166. accepts: A0=p->VRU handle, A1=#strings
  167. v = call 800936D0(@A0+0, @A0+4, SP+2B) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  168. if v:
  169. return v
  170. if SP[2B] & 2: # Err 0xF if Slot Empty set
  171. return 0xF
  172. SP+24 = 0x2000000 | (A1 << 8)
  173. v = call 80097500(@A0+0, @A0+4, 0, SP+24) # V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2, informing queue A0
  174. if v:
  175. return v
  176. v = call 8008A520(A0, SP+2B) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  177. if v & 0xFF00:
  178. return 5
  179. return v
  180. 8008FD80
  181.  
  182. 8008FE70 0x10E70 V0 = error state when sending SI cmd 0xB reading data from VRU address A2 on port A1 to A3, informing queue A0
  183. accepts: A0=p->queue, A1=controller slot, A2=address, A3=p->target
  184. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  185. for i in range(2, 0, -1):
  186. if @8009EB10 != 0xB or @80098FE0 != A1:
  187. 8009EB10 = 0xB
  188. 80098FE0 = A1
  189. 800A01D0[:A1] = repeat(0, A1)
  190. 800A01D0[3C] = 1
  191. 800A01D0[A1] = 0xFF
  192. 800A01D0[A1+1] = 3
  193. 800A01D0[A1+2] = 3
  194. 800A01D0[A1+3] = 0xB
  195. 800A01D0[A1+8] = 0xFF
  196. 800A01D0[A1+9] = 0xFE
  197. # 8008FF88
  198. 800A01D0[A1+4] = A2 >> 3
  199. v = call 80092040(A2) # V0 = controller pak address checksum for A0
  200. 800A01D0[A1+5] = (A2 << 5) | v
  201. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  202. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  203. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  204. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  205. # 8008FFE0
  206. v = (800A01D0[A1+2] & 0xC0) >> 4
  207. if v:
  208. v = 1
  209. break
  210. crc = call 800900A0(800A01D0+A1+6, 2) # V0 = controller pak data checksum for A1 bytes at A0
  211. if crc != 800A01D0[A1+8]:
  212. v = call 800936D0(A0, A1, SP+10) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  213. if v:
  214. break
  215. v = 4
  216. else:
  217. call 80092260(800A01D0+A1+6, A3, 2) V0 = p->A2 bytes copied from A0 to A1
  218. if v != 4:
  219. break
  220. # 8009005C
  221. call 8008AAD4() # send msg 0 to queue 8009EAB8
  222. return v
  223. 800900A0 V0 = controller pak data checksum for A1 bytes at A0
  224. accepts: A0=p->data, A1=length
  225. 80090140 0x11140 V0 = p->char A1 in string A0 else None
  226. 80090180 0x11180 V0 = strlen(A0)
  227. 800901A8 0x111A8 copy string A1 to A0
  228. 800901E0 0x111E0 create msg queue A0 with A2 msgs at A1
  229. 80090210
  230.  
  231. 80090770 0x11770 V0 = error state when sending SI cmd 9 reading data from VRU address A2 on port A1 to A3, informing queue A0
  232. accepts: A0=p->msg queue, A1=initial controller port, A2=address, A3=p->target
  233. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  234. for i in range(2, 0, -1):
  235. if 8009EB10[0] != 9 or @80098FE0 != A1:
  236. 8009EB10 = 9
  237. 80098FE0 = A1
  238. 800A01D0[:A1] = repeat(0, A1)
  239. 800A01D0[3C] = 1
  240. 800A01D0[A1] = 0xFF
  241. 800A01D0[A1+1] = 3
  242. 800A01D0[A1+2] = 0x25
  243. 800A01D0[A1+3] = 9
  244. 800A01D0[A1+2A] = 0xFF
  245. 800A01D0[A1+2B] = 0xFE
  246. # 80090888
  247. 800A01D0[A1+4] = A2 >> 3
  248. v = call 80092040(A2) # V0 = controller pak address checksum for A0
  249. 800A01D0[A1+5] = (A2 << 5) | v
  250. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  251. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  252. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  253. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  254. # 800908D0
  255. f = (800A01D0[A1+2] & 0xC0) >> 4
  256. if f:
  257. f = 1
  258. else:
  259. v = call 800900A0(800A01D0[A1+6], 0x24) # V0 = controller pak data checksum for A1 bytes at A0
  260. if v == 800A01D0[A1+2A]:
  261. call 80092260(800A01D0[A1+6], A3, 0x24) # V0 = p->A2 bytes copied from A0 to A1
  262. else:
  263. f = call 800936D0(A0, A1, SP+10) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  264. if f:
  265. break
  266. f = 4
  267. if f != 4:
  268. break
  269. call 8008AAD4() # send msg 0 to queue 8009EAB8
  270. return f
  271. 800909A0
  272.  
  273. 80091670 0x12670 initialize VRU and read current state
  274. accepts: A0=p->queue, A1=p->VRU handle, A2=controller slot
  275. A1+0 = A0 # p->queue
  276. A1+4 = A2 # controller slot
  277. A1+8 = 0 # mode
  278. SP[37] = 0
  279. v = call 800936D0(A0, A2, SP+37) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  280. if v:
  281. return v
  282. v = call 800917B0(A0, A2) # sends SI cmd 0xFD to controller slot A1, informing queue A0
  283. if v:
  284. return 4
  285. # 800916DC
  286. for i in range(5): # addresses, >> 3 actual: (0x1E, 0x6E, 8, 0x56, 3)
  287. v = call 800918A0(A0, A2, 80098FD0[i]) # send 0xD cmd with address A2 to VRU controller slot A1, informing queue A0
  288. if v:
  289. return v
  290. # 80091710
  291. v = call 800936D0(A0, A2, SP+37) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  292. if v:
  293. return v
  294. if SP[37] & 2:
  295. return 0xF # Err 0xF if Slot Empty set
  296. SP+30 = 0x100
  297. v = call 80097500(A0, A2, 0, SP+30) # V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2, informing queue A0
  298. if v:
  299. return v
  300. v = call 8008A520(A1, SP+37) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  301. if v & 0xFF00:
  302. return 5
  303. return v
  304. 800917B0 0x127B0 sends SI cmd 0xFD to controller slot A1, informing queue A0
  305. accepts: A0=p->queue, A1=controller slot
  306. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  307. 800A01D0+3C = True
  308. 800A01D0[0:A1] = repeat(0, A1)
  309. 800A01D0[A1] = 0xFD
  310. 800A01D0[A1 + 1] = 0xFE
  311. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  312. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  313. v = call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  314. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  315. call 8008AAD4() # send msg 0 to queue 8009EAB8
  316. return v
  317. 800918A0 0x128A0 V0 = error state when sending SI cmd 0xD with address A2 to VRU controller slot A1, informing queue A0
  318. accepts: A0=p->queue, A1=controller slot, A2=address
  319. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  320. for i in range(2, 0, -1):
  321. if 8009EB10[0] != 0xD or @80098FE0 != A1:
  322. 8009EB10[0] = 0xD
  323. 80098FE0 = A1
  324. 800A01D0[0:A1] = repeat(0, A1)
  325. 800A01D0[A1] = 3
  326. 800A01D0[A1+1] = 1
  327. 800A01D0[A1+2] = 0xD
  328. 800A01D0[A1+5] = 0
  329. 800A01D0[A1+6] = 0xFE
  330. 800A01D0+3C = 1
  331. # 800919A4
  332. 800A01D0[A1+3] = A2
  333. 800A01D0[A1+4] = call 80092040(A2 << 3) # V0 = controller pak address checksum for A0
  334. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  335. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  336. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  337. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  338. f = 800A01D0[A1+1] & 0xC0
  339. f >>= 4
  340. if f:
  341. f = 1
  342. # autopasses through test at 80091A34
  343. break
  344. if 800A01D0[A1+5] & 1:
  345. f = call 800936D0(A0, A1, SP+10) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  346. if f:
  347. call 8008AAD4() # send msg 0 to queue 8009EAB8
  348. return f
  349. f = 4
  350. # 80091A34
  351. if f != 4:
  352. break
  353. # 80047C5C
  354. call 8008AAD4() # send msg 0 to queue 8009EAB8
  355. return f
  356. 80091A90
  357.  
  358. 80091BE0 0x12BE0 V0 = error state when sending SI cmd 2 with address A2 to controller slot A1, informing queue A0
  359. accepts: A0=p->queue, A1=controller slot, A2=address
  360. # Read controller slot cmd.
  361. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  362. for i in range(2, 0, -1):
  363. if 8009EB10[0] != 2 or @80098FE0 != A1:
  364. 8009EB10[0] = 2
  365. 80098FE0 = A1
  366. 800A01D0[0:A1] = repeat(0, A1)
  367. 800A01D0[A1] = 3
  368. 800A01D0[A1+1] = 0x21
  369. 800A01D0[A1+2] = 0x2
  370. 800A01D0[A1+25] = 0xFF
  371. 800A01D0[A1+26] = 0xFE
  372. # 80091CF8
  373. 800A01D0[A1+4] = A2 >> 3
  374. v = call 80092040(A2) # V0 = controller pak address checksum for A0
  375. 800A01D0[A1+5] = (A2 << 5) | v
  376. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  377. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  378. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  379. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  380. # 80091D50
  381. f = (800A01D0[A1+2] & 0xC0) >> 4
  382. if f:
  383. f = 1
  384. else:
  385. crc = call 80092110(800A01D0[A1+6]) # V0 = controller pak data checksum for A0
  386. if crc == 800A01D0[A1+25]:
  387. call 80092260(A0, A1, 0x20) # V0 = p->A2 bytes copied from A0 to A1
  388. else:
  389. f = call 8008C360(A0, A1)
  390. if f:
  391. break
  392. f = 4
  393. if f != 4:
  394. break
  395. call 8008AAD4() # send msg 0 to queue 8009EAB8
  396. return f
  397. 80091E10 0x12E10 V0 = error state when sending SI cmd 0xA writing data A3 to VRU address A2 on port A1, informing queue A0
  398. accepts: A0=p->queue, A1=controller port, A2=address, A3=p->data
  399. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  400. for i in range(2, 0, -1):
  401. if @8009EB10 != 0xA and @80098FE0 != A1:
  402. 8009EB10 = 0xA
  403. 80098FE0 = A1
  404. 800A01D0[:A1] = repeat(0, A1)
  405. 800A01D0[3C] = 1
  406. 800A01D0[A1] = 0xFF
  407. 800A01D0[A1+1] = 0x17
  408. 800A01D0[A1+2] = 1
  409. 800A01D0[A1+3] = 0xA
  410. 800A01D0[A1+1A] = 0xFF
  411. 800A01D0[A1+1B] = 0xFE
  412. # 80091F28
  413. 800A01D0[A1+4] = A2 >> 3
  414. v = call 80092040(A2) # V0 = controller pak address checksum for A0
  415. 800A01D0[A1+5] = (A2 << 5) | v
  416. call 80092260(A3, 800A01D0+A1+6, 0x14) # V0 = p->A2 bytes copied from A0 to A1
  417. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  418. crc = call 800900A0(A3, 0x14) # V0 = controller pak data checksum for A1 bytes at A0
  419. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  420. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  421. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  422. f = (800A01D0[A1+2] & 0xC0) >> 4
  423. if f:
  424. f = 1
  425. break
  426. if 800A01D0[A1+1A] != crc:
  427. f = call 800936D0(A0, A1, SP+10) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  428. if f:
  429. break
  430. f = 4
  431. if f != 4:
  432. break
  433. # 800561FC
  434. call 8008AAD4() # send msg 0 to queue 8009EAB8
  435. return f
  436. 80092040 0x13040 V0 = controller pak address checksum for A0
  437. 80092110 0x13110 V0 = controller pak data checksum for A0
  438. 800921B0 0x131B0 V0 = @80098E4C
  439. 800921C0
  440.  
  441. 80092260 0x13260 V0 = p->A2 bytes copied from A0 to A1
  442.  
  443. 80093260 0x14260 V0 = errors when sending VRU cmd 7 and testing state
  444. accepts: A0=p->VRU handle
  445. v = call 800936D0(@A0+0, @A0+4, SP+3F) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  446. if v:
  447. return v
  448. if SP[3F] & 2:
  449. return 0xF # Err 0xF if Slot Empty set
  450. if not @A0+8:
  451. return 5
  452. SP+38 = 0x700
  453. v = call 80097500(@A0+0, @A0+4, 0, SP+38) # V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2, informing queue A0
  454. if not v:
  455. # 800932F0
  456. for i in range(0x14):
  457. v = call 8008A520(A0, SP+3F) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  458. if not v & 0xFF00:
  459. A0+8 = 0
  460. elif not v & 7:
  461. v = 0
  462. A0+8 = 0
  463. elif (v & 7) == 7:
  464. v = 5
  465. else:
  466. A0+8 = 0
  467. if v != 0xF:
  468. break
  469. SP+40 = i
  470. # 80093358
  471. return v
  472. 80093380
  473. 800933E0 0x143E0 initialize and read controller presence flags to A1, informing queue A0
  474. accepts: A0=p->msg queue, A1=p->presence flags
  475. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  476. f = 0
  477. for i in range(3, 0, -1):
  478. call 8009356C(0)
  479. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  480. call 80088E70(A0, SP+68, True) # read or wait (A2) to write msg from queue A0 to A1
  481. SP+6C = call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  482. call 80088E70(A0, SP+68, True) # read or wait (A2) to write msg from queue A0 to A1
  483. call 80093620(SP+67, SP+54) # copy result of SI status request to A1, setting presence flags to A0
  484. ...
  485. # 80093528
  486. call 8008AAD4() # send msg 0 to queue 8009EAB8
  487. A1[0] = f
  488. 8009356C 0x1456C fill buffer 800A01D0 with SI status or reset (A0) commands
  489. accepts: A0=command (0 or -1)
  490. 80093620 copy result of SI status request to A1, setting presence flags to A0
  491. accepts: A0=p->flags, A1=p->results
  492. 800936D0 0x146D0 V0 = error state for status of controller ports A1 on, writing status flags to A2
  493. accepts: A0=p->msg queue, A1=initial controller port, A2=status flags
  494. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  495. f = 0
  496. for i in range(2, 0, -1):
  497. if f != 4:
  498. 8009EAD0+3C = 1
  499. for j in range(A1):
  500. 8009EAD0[j] = 0
  501. 8009EAD0[j:j+2] = (1, 3)
  502. j += 2
  503. 8009EAD0[j] = 0
  504. 8009EAD0[j+6] = 0xFE
  505. 8009EB10[0] = 0xFE
  506. call 8008BD10(1, 8009EAD0) # read or write (A0) between rdram A1 and pifram
  507. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  508. # 800937BC
  509. call 8008BD10(0, 8009EAD0) # read or write (A0) between rdram A1 and pifram
  510. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  511. SP[60:66] = 8009EAD0[A1:A1+6]
  512. f = (SP[61] & 0xC0) >> 4
  513. A2[0] = SP[65]
  514. if f:
  515. f = 1 if f & 8 else 4
  516. elif SP[63] or SP[64] != 1:
  517. f = 0xB
  518. elif SP[65] & 4:
  519. f = 4
  520. if f != 4:
  521. break
  522. # 80093878
  523. call 8008AAD4() # send msg 0 to queue 8009EAB8
  524. return f
  525. 800938C0
  526.  
  527. 80093C20 0x14C20
  528. accepts: A0=controller port
  529. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  530. 8009EB10[1] = max(A0, 4)
  531. 8009EB10[0] = 0xFE
  532. call 8008AAD4() # send msg 0 to queue 8009EAB8
  533. 80093C80
  534.  
  535. 80093EA0 0x14EA0 ???; manages controller pak read and write requests, but beyond the scope of what I'm doing now
  536. accepts: A0=p->queue, A1, A2=controller slot
  537. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  538. f = call 8008C360(A0, A2)
  539. call 8008AAD4() # send msg 0 to queue 8009EAB8
  540. A1+4 = A0
  541. if f:
  542. return f
  543. A1+0 = 0
  544. A1+8 = A2
  545. f = call 800940A8()
  546. if f:
  547. return f
  548. f = call 80093BA0(A1, 0)
  549. if f:
  550. return f
  551. f = call 80091BE0(@A1+4, @A1+8, 1, SP+48) # V0 = error state when sending SI cmd 2 with address A2 to controller slot A1, informing queue A0
  552. call 8008D754(SP+48, SP+6A, SP+68)
  553. ...
  554. 800940A8
  555.  
  556. 80094D60 0x15D60 V0 = error state when sending SI cmd 3 with data A3 to address A2 on port A1, informing queue A0
  557. accepts: A0=p->queue, A1=controller slot, A2=addy (11 bits), A3=p->data
  558. # Controller pak write.
  559. 80094FB0 write word A2 to hardware offset A1 using EPI handle A0
  560. 80095110
  561.  
  562. 800965B0 0x175B0 V0 = @80098E54
  563. 800965C0 0x175C0 V0 = errors when sending A2 bytes of data A1 to VRU using handle A0
  564. accepts: A0=p->VRU handle, A1=p->data, A2=length
  565. v = call 800936D0(@A0+0, @A0+4, SP+3B) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  566. if v:
  567. return v
  568. if SP[3B] & 2: # Err 0xF if Slot Empty set
  569. return 0xF
  570. A2 += A2 & 1 # LE HW alignment
  571. call 8008A5D0(SP+24, 0x14) # initialize A1 bytes at A0
  572. SP[0x36 - A2] = 4
  573. v = A2 + (A2 & 1)
  574. for i in range(0, A2, 2):
  575. addr = i + 0x14 - v
  576. SP[24+addr] = A1[i]
  577. SP[25+addr] = A1[i+1]
  578. if A2 & 1:
  579. SP[37] = 0
  580. # 80096698
  581. v = call 80091E10(@A0+0, @A0+4, 0, SP+10) # V0 = error state when sending SI cmd 0xA writing data A3 to VRU address A2 on port A1, informing queue A0
  582. if v:
  583. return v
  584. v = call 8008A520(A0, SP+3B) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  585. if v & 0xFF00:
  586. return 5
  587. return v
  588. 80096700
  589.  
  590. 80097320 0x18320 ???; VRU initialization for specific memory banks...
  591. accepts: A0=p->VRU handle, A1=bool, A2=index
  592. v = 0x98 if A1 else 0x18
  593. v = call 800918A0(@A0+0, @A0+4, v) # send 0xD cmd with address A2 to VRU controller slot A1, informing queue A0
  594. if v:
  595. return v
  596. if not 0 <= A2 < 8:
  597. return 5
  598. v = 800991B0[A2] + 2
  599. v &= 0xFF
  600. call 800918A0(@A0+0, @A0+4, v) # send 0xD cmd with address A2 to VRU controller slot A1, informing queue A0
  601. 800973D0 0x183D0 V0 = error state when sending VRU cmd 5 (stop listening) using VRU handle A0
  602. accepts: A0=p->VRU handle
  603. v = call 800936D0(@A0+0, @A0+4, SP+2B) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  604. if v:
  605. return v
  606. if SP[2B] & 2: # Err 0xF if Slot Empty set
  607. return 0xF
  608. if @A0+8:
  609. return 5
  610. SP+24 = 0x5000000
  611. v = call 80097500(@A0+0, @A0+4, 0, SP+24) # V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2, informing queue A0
  612. if v:
  613. return v
  614. v = call 8008A520(A0, SP+2B) # V0 = errors when reading controller status to A1 and and set VRU state in handle A0
  615. if v & 0xFF00:
  616. return 5
  617. A0+8 = 1
  618. return v
  619. 80097490
  620.  
  621. 80097500 0x18500 V0 = error state when sending SI cmd 0xC with data A3 to VRU address A2 on port A1, informing queue A0
  622. accepts: A0=p->queue, A1=controller slot, A2=addy (11 bits), A3=p->data
  623. call 8008AA90() # wait for msg on queue 8009EAB8, creating queue if necessary
  624. for i in range(2, 0, -1):
  625. if 8009EB10[0] != 0xC and @80098FE0 != A1:
  626. # 80097570
  627. 8009EB10[0] = 0xC
  628. 80098FE0 = A1
  629. 800A01D0[:A1] = repeat(0, A1)
  630. 800A01D0+3C = 1
  631. 800A01D0[A1] = 0xFF
  632. 800A01D0[A1+1] = 7
  633. 800A01D0[A1+2] = 1
  634. 800A01D0[A1+3] = 0xC
  635. 800A01D0[A1+A] = 0xFF
  636. 800A01D0[A1+B] = 0xFE
  637. # 80097618
  638. 800A01D0[A1+4] = A2 >> 3
  639. v = call 80092040(A2) # V0 = controller pak address checksum for A0
  640. 800A01D0[A1+5] = (A2 << 5) | v
  641. call 80092260(A3, 800A01D0+A1+6, 4) # V0 = p->A2 bytes copied from A0 to A1
  642. call 8008BD10(1, 800A01D0) # read or write (A0) between rdram A1 and pifram
  643. crc = call 800900A0(A3, 4) & 0xFF # V0 = controller pak data checksum for A1 bytes at A0
  644. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  645. call 8008BD10(0, 800A01D0) # read or write (A0) between rdram A1 and pifram
  646. call 80088E70(A0, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  647. v = 800A01D0[A1+2] & 0xC0
  648. v >>= 4
  649. if v:
  650. v = 1
  651. elif 800A01D0[A1+A] != crc:
  652. # 800976A4
  653. v = call 800936D0(A0, A1, SP+6B) # V0 = error state for status of controller ports A1 on, writing status flags to A2
  654. if not v:
  655. v = 4
  656. # 800976D4
  657. if v != 4:
  658. break
  659. # 800976E8
  660. call 8008AAD4() # send msg 0 to queue 8009EAB8
  661. return v
  662. 80097730
  663.  
  664. 80098FD0 0x19FD0 VRU init addresses; >> 3 for actual
  665. 1E 6E 08 56 03
  666. 80098FD8
  667.  
  668. 800991B0 0x1A1B0 VRU addresses, unknown purpose; >> 3 for actual
  669. 00 80 40 C0 20 A0 60 E0
  670. 800991B8
  671.  
  672. +_+
  673.  
  674. 801138A8
  675. accepts: A0
  676. ...
  677. # 80114100
  678. f = A0[20:22]
  679. if not (f nor ~0x4000):
  680. # 80114118
  681. A0[1CA5] &= ~4
  682. A0[169C8][224:226] = 0
  683. A0[169C8][222:224] = A0[169C8][224:226]
  684. SP+30 = 1
  685. 801BA6E4[0:2] = 0
  686. # goto 8011450C
  687. else:
  688. if not (f nor ~0x8000) or call 801A0060() == 1: # If A button or most recent, best VRU hit == 1
  689. # 80114174
  690. ...
  691. # goto 8011450C
  692. ...
  693. 8011455C
  694.  
  695. 801707A4 V0 = p->controller queue
  696. v = @801CBCE0
  697. call 80088E70(v+4C, SP+1C, True) # read or wait (A2) to write msg from queue A0 to A1
  698. return @SP+1C
  699. 801707D8 identical to 801707A4
  700. 8017080C write response from controller queue to A0
  701. accepts: A0=p->target
  702. v = @801CBCE0
  703. call 80088AB0(v+4C, A0, True) # send or jam (A2) msg A1 to queue A0
  704. 8017083C identical to 801707A4
  705. 8017086C
  706.  
  707. 80171158 initialize all connected VRU
  708. j = @801CBCE0
  709. for i in range(j[2C8]): # for controllers connected...
  710. if j[2C9+i] == 4:
  711. v = call 801707A4() # V0 = p->controller queue
  712. f = call 80091670(v, 801FD708, i) # initialize VRU and read current state
  713. call 8017080C(v) # response from controller queue
  714. if not f: # if no errors...
  715. j[2C9 + i] = 5 # set to a "normal" controller type to avoid reinit
  716. 801CBCE8 = 2 # always run this, in case you need to reinit later
  717. call 8019FE10() # unconditional return
  718. # 80171230
  719. if @801CBCE8 == 1:
  720. 801CBCE8 = 0
  721. 8017127C compile a table of controller types
  722. v = @801CBCE0
  723. f = 0 # flags for "real" controllers
  724. # 801712D4
  725. for i in range(4):
  726. c = v + (i << 2)
  727. if not c[17]: # no error
  728. kind = c[14:16] & 0x1F07
  729. if kind == 2: # mouse
  730. # 80171334
  731. if not v[2C9+i]:
  732. v[2C9+i] = 3
  733. elif kind == 5: # controller
  734. # 80171314
  735. f |= 1 << i
  736. if not v[2C9+i]:
  737. v[2C9+i] = 1
  738. elif kind == 0x100: # VRU
  739. # 8017134C
  740. if not v[2C9+i]:
  741. v[2C9+i] = 4
  742. v[2CD+i] = 0
  743. else:
  744. # 80171370
  745. if not v[2C9+i]:
  746. v[2C9+i] = 0xFF
  747. else:
  748. # 80171388
  749. if v[2C9+i]:
  750. if v[2C9+i] == 1: # weird conditional there
  751. v[2CD+i] = 0
  752. v[2D5+i] = 0xFF
  753. v[2C9+i] = 0
  754. else:
  755. v[2C9+i] = 0
  756. # 801713C4
  757. v+0 = f
  758. 801713E4
  759. SP+1C = call 801707A4() # V0 = p->controller queue
  760. call 8008AF30(@SP+1C) # V0 = error state when sending SI cmd 1 reading controllers
  761. v = @801CBCE0
  762. if @v+4:
  763. call @v+4(@v+8)
  764. call 80088E70(@SP+1C, 0, True) # read or wait (A2) to write msg from queue A0 to A1
  765. call 8008AFB4(v+2B0)
  766. call 8008A5D0(v+2B6, 0x12) # initialize A1 bytes at A0
  767. if v[47E]:
  768. call 8008A5D0(v+2B0, 0x18) # initialize A1 bytes at A0
  769. # 8017146C
  770. call 8008E6D0(@SP+1C)
  771. call 80088E70(@SP+1C, 0 True) # read or wait (A2) to write msg from queue A0 to A1
  772. call 8008E74C(v+14)
  773. call 8017080C(@SP+1C) # response from controller queue
  774. call 8017127C() # compile a table of controller types
  775. call 8017086C()
  776. call 80170F40()
  777. if @v+C:
  778. call @v+C(@v+10)
  779. # 801714D8
  780. if @801CBCE8:
  781. call 80171158() # initialize all connected VRU
  782. if 8009E84D[0]:
  783. call 80170B34()
  784. else:
  785. if v[47C] > 0:
  786. v[47C] -= 1
  787. call 80170B34()
  788. elif not v[47D]:
  789. call 80170B34()
  790. elif not v[47E]:
  791. call 801708CC()
  792. v[47D] -= 1
  793. # 80171580
  794. 801CBCE4 += 1
  795. 801715A0
  796.  
  797. 8018E8C8
  798. accepts: A0, A1=p->args
  799. v = 801F0DC0[7878] << 3
  800. 801F0DC0+79F4+v = A0
  801. 801F0DC0+79F4+v+4 = @A1+0
  802. 801F0DC0[7878] += 1
  803. if 801F0DC0[7878] == 801F0DC0[7879]:
  804. 801F0DC0[7878] -= 1
  805. 8018E914 call 8018E8C8(A0, p->A1)
  806. accepts: A0, A1
  807. 8018E938 same as 8018E914()
  808. accepts: A0, A1
  809. 8018E95C call 8018E8C8(A0, p->(A1 << 0x18))
  810. accepts: A0, A1
  811. 8018E98C call 8018E8C8(A0, p->(A1 << 0x10))
  812. accepts: A0, A1
  813. 8018E9BC
  814.  
  815. 8018ED18
  816. v = call 80088E70(@80208748, SP+18, False) # read or wait (A2) to write msg from queue A0 to A1
  817. if v == -1:
  818. return 0
  819. if 80205209[0] == @SP+18:
  820. return 1
  821. else:
  822. return -1
  823. 8018ED70
  824.  
  825. 80199118
  826. v = call 801A4648()
  827. if v:
  828. return
  829. v = call 801A470C()
  830. if v:
  831. return
  832. call 80198968()
  833. call 80198704()
  834. call 801A0078() # ???; listens for and provides VRU word results
  835. call 8019B108(801FD3B8)
  836. call 8019B108(801FD3C8)
  837. call 8019B488()
  838. call 8019D700()
  839. call 8019E08C()
  840. call 8019AEF8()
  841. call 8019CE00()
  842. call 8019C900()
  843. call 8019D058()
  844. call 8019EA20()
  845. call 8019C2AC()
  846. call 8019F424()
  847. call 801A2670()
  848. call 801A38B0() # execute commands in table at 801FFE90
  849. call 801A27CC()
  850. call 801A3C3C()
  851. call 8019A31C()
  852. call 8018E9BC()
  853. 80199200 NERFED; saves A0 to the stack
  854. 80199208 NERFED; saves A0, A1 to the stack
  855. 80199214
  856.  
  857. 8019F840
  858. accepts: A0, A1
  859. A0 &= 0xFFFF
  860. A1 &= 0xFFFF
  861. call 801A3888(0x74000001)
  862. call 801A3888(0x74040000 | A0 >> 8)
  863. call 801A3888(0x74050000 | A0 & 0xFF)
  864. call 801A3AB0(0, 0, 0x7F, 1)
  865. v = call 801A3930(4)
  866. if call 801A3930(4) != 0xFFFF and call 801A3930(4) != 1:
  867. call 801A2BE4(4, 0)
  868. call 8018E938(0xF8000000, 0)
  869. # 8019F8F0
  870. if call 801A3930(3): == 0x81A:
  871. call 801A3AB0(0, 3, 0x7F, 1)
  872. call 801A3888(0x4000001)
  873. for i in range(0x10):
  874. # 8019F930
  875. j = (1 << i)
  876. if A1 & j or A0 & j:
  877. call 801A3888(0x84010001 | i << 8)
  878. 8019F988
  879.  
  880. 8019FCB0
  881. call 8019FBB4(1)
  882. call 8018E938(0xF2FF0000, 1)
  883. call 8018E9BC()
  884. call 8018E938(0xF8000000, 0)
  885. 801FD528[0] = 0
  886. 801D0EAC[0] = 0
  887. 801FD4FE[0] = 0
  888. 8019FD04
  889. call 8019FCB0()
  890. v = 801D5C04[0]
  891. if v < 0xA:
  892. v = @801D6060+(v<<2)
  893. call 8018E938(0xE6000100, v + 0x18)
  894. 8019FD54 ???; sends VRU strings, unmasking the 2nd and 6th word
  895. accepts: A0 (unused)
  896. 801D5C08[0] = 1
  897. call 8019F434()
  898. call 80199068()
  899. call 8019A090()
  900. call 801A4898()
  901. call 801A289C()
  902. call 8019FF38() # send VRU strings at 801D3310, unmasking the 2nd and 6th word
  903. if 801D5C04[0] == 0xB:
  904. call 801A0B20(0x6F) # set values in table 801FFDD4 based on mask A0
  905. 8019FDC4
  906. call 801A4898()
  907. call 8018E938(0xF2FF0000, 1)
  908. call 8019F434()
  909. call 8019A090()
  910. call 8019FBB4(1)
  911. call 8019FF38() # send VRU strings at 801D3310, unmasking the 2nd and 6th word
  912. 8019FE10 unconditional return
  913. 8019FE18 send VRU strings at 801D3310 with masks set on for all
  914. if 801D356C[0]: # if turned "on", turn "off" to send data
  915. q = call 801707D8() # V0 = p->controller queue
  916. call 80093260(801FD708) # V0 = errors when sending VRU cmd 7 and testing state
  917. call 8017083C(@q+0) # write response from controller queue to A0
  918. # 8019FE58
  919. v = call 801A0424() # V0 = p->VRU data buffer
  920. i = 0
  921. while i <= 0:
  922. SP[38+i] = v[0+i]
  923. i += 1
  924. v = call 801A0188(801D3310) # send strings at A0 to VRU
  925. if v:
  926. return v
  927. for i in range(6):
  928. # 8019FEA0
  929. j = i >> 3
  930. if i < 0: # which it can't be
  931. j = (i + 7) >> 3
  932. k = i & 7
  933. if i < 0 and k: # which it still can't be
  934. k -= 8
  935. if (SP[38+j] >> k) & 1:
  936. call 801A0430(i) # set and update VRU word mask for entry A0
  937. # 8019FEF8
  938. call 801A0348(0x320, 2, 0x400, 0x1F4, 0x7D0) # set VRU threshold levels
  939. 801D356C[0] = 1 # turn "on"
  940. 8019FF38 send VRU strings at 801D3310, unmasking the 2nd and 6th word
  941. call 801A0430(-1) # set and update VRU word mask for entry A0
  942. if not 801D356C[0]: # return if turned "off"
  943. return
  944. q = call 801707D8() # V0 = p->controller queue
  945. call 80093260(801FD708) # V0 = errors when sending VRU cmd 7 and testing state
  946. call 8017083C(@q+0) # write response from controller queue to A0
  947. e = call 801A0188(801D3310) # send strings at A0 to VRU
  948. call 801A0430(-1) # set and update VRU word mask for entry A0
  949. # 8019FF90
  950. if not e:
  951. call 801A0348(0x320, 2, 0x400, 0x1F4, 0x7D0) # set VRU threshold levels
  952. 801D356C[0] = 1 # turn "on"
  953. # 8019FFC0
  954. call 8019FFE0(5) # if turned "on", unset and update VRU word mask for entry A0
  955. call 8019FFE0(1) # if turned "on", unset and update VRU word mask for entry A0
  956. 8019FFE0 if turned "on", unset and update VRU word mask for entry A0
  957. accepts: A0=index
  958. if not 801D356C[0]: # turned "off"
  959. return
  960. if A0 < 6:
  961. call 801A05E0(A0) # unset and update VRU word mask for entry A0
  962. 801A0020 if turned "on", set VRU string mask for word A0
  963. accepts: A0=index
  964. if not 801D356C[0]: # turned "off"
  965. return
  966. if A0 < 6:
  967. call 801A0430(A0) # set and update VRU word mask for entry A0
  968. 801A0060 V0 = most recent, best VRU hit; V0 = 801D3574[0:2]
  969. 801A006C V0 = VRU mode flags; 801D356C[0]
  970. 801A0078 ???; listens for and provides VRU word results
  971. if 801D356C[0] & 2: # if tacit, send strings and masks
  972. 801D356C[0] &= 1
  973. call 8019FE18() # send VRU strings at 801D3310 with masks set on for all
  974. if not 801D356C[0]: # return if turned "off"
  975. return
  976. v = call 801A0768() # listen for registered set of VRU words and fetch results
  977. if v:
  978. # 801A00BC
  979. 801D3578[0] += 1
  980. 801D3578[0] &= 0xFF
  981. if 801D3578[0] == 0xA:
  982. 801D356C[0] = 0 # turn "off"
  983. 801D3574[0:2] = -1
  984. return
  985. else:
  986. # 801A00F4
  987. 801D3578[0] = 0
  988. # 801A0100
  989. v = call 801A02F0() # V0=p->VRU results; pop @801FD6F0+8, send VRU cmd 5
  990. 801D3570 = v # p->most recent VRU results
  991. if not v:
  992. 801D3574[0:2] = -1
  993. else:
  994. 801D3574[0:2] = v[A:C] # first, best hit
  995. 801A0150 V0 = -1 if VRU error A0 in (1, 4, 5, 11, 13, 14, 15) else 0
  996. accepts: A0=VRU error state
  997. A0 -= 1
  998. # if A0 < 0xF:
  999. # call @801DF5FC+(A0<<2)()
  1000. if A0 in (0, 3, 4, A, C, D, E)
  1001. # 801A0174
  1002. return -1
  1003. else:
  1004. return 0
  1005. 801A0188 send strings at A0 to VRU
  1006. accepts: A0=p->string pointers
  1007. 801FD6F0[4] = 0
  1008. 801FD6F0+8 = 0 # NULL pointer to VRU results
  1009. 801FD6F0[C:E] = 0x3E8 # deviance threshold
  1010. 801FD6F0[E:10] = 5 # maximum acceptable results
  1011. 801FD6F0[10:12] = 0 # error flag mask
  1012. 801FD6F0+0 = A0
  1013. ctrl = @801FD6F0+0
  1014. q = call 801707D8() # V0 = p->controller queue
  1015. e = call 8008FCD0(801FD708, ctrl[258]) # V0 = errors when clearing A1 strings from VRU using handle A0
  1016. call 8017083C(q) # write response from controller queue to A0
  1017. if e:
  1018. return e
  1019. # 801A0218
  1020. v = ctrl[258] - 1 # count - 1
  1021. if v < 7:
  1022. v += 7
  1023. v >>= 3 # SRA
  1024. v += 1
  1025. for i in range(v):
  1026. 801FD758[i] = 0
  1027. # 801A0258
  1028. for i in range(ctrl[258]):
  1029. q = call 801707D8() # V0 = p->controller queue
  1030. v = A0 + (i * 0x1E)
  1031. e = call 800890B0(801FD708, v) # V0 = errors when sending Shift-JIS string A1 to VRU using handle A0
  1032. call 8017083C(q) # write response from controller queue to A0
  1033. if call 801A0150(e): # V0 = -1 if VRU error A0 in (1, 4, 5, 11, 13, 14, 15) else 0
  1034. call 801A097C(v) # write SJIS string A0 phonetically to 801FD760
  1035. return e
  1036. 801A02F0 V0=p->VRU results; pop @801FD6F0+8, send VRU cmd 5
  1037. v = @801FD6F0+8
  1038. 801FD6F0+8 = 0
  1039. q = call 801707D8() # V0 = p->controller queue
  1040. call 800973D0(801FD708) # V0 = error state when sending VRU cmd 5 (stop listening) using VRU handle A0
  1041. call 8017083C(q) # write response from controller queue to A0
  1042. return v
  1043. 801A033C V0 = p->VRU instance; V0 = @801FD6F0+0
  1044. 801A0348 set VRU threshold levels
  1045. accepts: A0=deviance threshold, A1=maximum #results, A2=error flag mask, A3=minimum voice level from mic, SP+10=minimum relative voice level
  1046. 801FD6F0[C:E] = A0
  1047. 801FD6F0[E:10] = A1
  1048. 801FD6F0[10:12] = A2
  1049. 801FD6F0[12:14] = A3
  1050. 801FD6F0[14:16] = @SP+10
  1051. 801A037C
  1052. accepts: A0, A1
  1053. v = @801FD6F0+0
  1054. if not v:
  1055. return
  1056. SP+18 = call 801707D8() # V0 = p->controller queue
  1057. SP+1C = call 80097320(801FD708, A0, A1) # ???; VRU initialization for specific memory banks...
  1058. call 8017083C(@SP+18) # write response from controller queue to A0
  1059. if @SP+1C:
  1060. call 801A0150(@SP+1C) # V0 = -1 if VRU error A0 in (1, 4, 5, 11, 13, 14, 15) else 0
  1061. 801A03E8
  1062.  
  1063. 801A0424 V0 = p->VRU data buffer; V0 = 801FD758
  1064. 801A0430 set and update VRU word mask for entry A0
  1065. accepts: A0=index
  1066. v = @801FD6F0+0
  1067. A0 &= 0xFFFF
  1068. if v:
  1069. c = 801FD6F0[258]
  1070. f = True
  1071. else: # if strings aren't present, assume full buffer, create a table, then don't send it.
  1072. c = 0x14
  1073. f = False
  1074. if A0 == 0xFFFF:
  1075. # 801A046C
  1076. for i in range(c):
  1077. j = i + 7 if i < 0 else i # This can't happen though
  1078. j >>= 3
  1079. k = i & 7
  1080. if i < 0 and k:
  1081. k -= 8
  1082. 801FD758[j] |= 1 << k
  1083. else:
  1084. # 801A04DC
  1085. i = A0
  1086. if i < 0:
  1087. i += 7
  1088. i >>= 3
  1089. j = A0 & 7
  1090. if A0 < 0 and j:
  1091. j -= 8
  1092. k = 1 << j
  1093. if 801FD758[i] & k:
  1094. f = False
  1095. else:
  1096. 801FD758[i] |= k
  1097. # 801A0530
  1098. if not f:
  1099. return
  1100. SP[22] = c
  1101. SP+1C = call 801707D8() # V0 = p->controller queue
  1102. SP+24 = call 80093260(801FD708) # V0 = errors when sending VRU cmd 7 and testing state
  1103. call 8017083C(@SP+1C) # write response from controller queue to A0
  1104. if @SP+1C and 801FD6F4[0]:
  1105. 801FD6F4[0] = 0
  1106. return
  1107. SP+1C = call 801707D8() # V0 = p->controller queue
  1108. v = c - 1
  1109. if v < 0:
  1110. v += 7
  1111. v >>= 3
  1112. SP+24 = call 800965C0(801FD708, 801FD758, v + 1) # V0 = errors when sending A2 bytes of data A1 to VRU using handle A0
  1113. call 8017083C(@SP+1C) # write response from controller queue to A0
  1114. 801FD6F4 = 0
  1115. 801A05E0 unset and update VRU word mask for entry A0
  1116. accepts: A0=index
  1117. v = @801FD6F0
  1118. if not v:
  1119. f, c = False, 0x14
  1120. else:
  1121. f, c = True, v[258]
  1122. if A0 == 0xFFFF:
  1123. # 801A061C
  1124. j = c - 1
  1125. if j < 0:
  1126. j += 7
  1127. j >>= 3
  1128. j += 1
  1129. 801FD758[0:j] = repeat(0, j)
  1130. else:
  1131. # 801A0664
  1132. j = A0
  1133. if j < 0: # this can't happen...
  1134. j += 7
  1135. j >>= 3
  1136. k = A0 & 7
  1137. if A0 < 0 and k:
  1138. k -= 8
  1139. v = 801FD758[j] & (1 << k)
  1140. if not v:
  1141. # if not set, don't update
  1142. f = False
  1143. else:
  1144. # untoggle flag and update
  1145. 801FD758[j] &= ~(1 << k)
  1146. # 801A06BC
  1147. if not f:
  1148. return
  1149. SP[22] = c
  1150. SP+1C = call 801707D8() # V0 = p->controller queue
  1151. SP+24 = call 80093260(801FD708) # V0 = errors when sending VRU cmd 7 and testing state
  1152. call 8017083C(@SP+1C) # write response from controller queue to A0
  1153. if @SP+24 and 801FD6F0[4]:
  1154. 801FD6F0[4] = 0
  1155. return @SP+24
  1156. j = c - 1
  1157. if j < 0:
  1158. j += 7
  1159. j >>= 3
  1160. j += 1
  1161. SP+1C = call 801707D8() # V0 = p->controller queue
  1162. SP+24 = call 800965C0(801FD708, 801FD758, j) # V0 = errors when sending A2 bytes of data A1 to VRU using handle A0
  1163. call 8017083C(@SP+1C) # write response from controller queue to A0
  1164. 801FD6F0[4] = 0
  1165. return @SP+24
  1166. 801A0768 listen for registered set of VRU words and fetch results
  1167. if 801FD6F0[4] == 0:
  1168. # 801A07A0: stop listening
  1169. SP+1C = call 801707D8() # V0 = p->controller queue
  1170. SP+24 = call 800973D0(801FD708) # V0 = error state when sending VRU cmd 5 (stop listening) using VRU handle A0
  1171. call 8017083C(@SP+1C) # write response from controller queue to A0
  1172. 801FD6F4[0] = 1
  1173. elif 801FD6F0[4] == 1:
  1174. # 801A07D4: fetch results
  1175. SP+1C = call 801707D8() # V0 = p->controller queue
  1176. SP+24 = call 8008B110(801FD708, 801FD718) # V0 = error state when writing VRU listening results to A1 using handle A0
  1177. call 8017083C(@SP+1C) # write response from controller queue to A0
  1178. v = call 801A0150(@SP+24) # V0 = -1 if VRU error A0 in (1, 4, 5, 11, 13, 14, 15) else 0
  1179. if v:
  1180. return v
  1181. # if 801FD714[0] < 8:
  1182. # call @801DF638+(801FD714[0]<<2)()
  1183. if 801FD714[0] == 0:
  1184. # 801A0834
  1185. 801FD6F0[4] = 2
  1186. elif 801FD714[0] == 7:
  1187. # 801A0844
  1188. 801FD6F0[4] = 2
  1189. elif 801FD6F0[4] == 2:
  1190. # 801A0854: verify results and reset
  1191. if not (801FD718[0:2] & 801FD6F0[10:12]): # error not in mask
  1192. if 801FD718[2:4] <= 801FD6F0[E:10] and # no more than given number of results
  1193. 801FD718[14:16] <= 801FD6F0[C:E] and # best hit's deviance below threshold
  1194. 801FD718[4:6] >= 801FD6F0[12:14] and # above minimum voice level from mic
  1195. 801FD718[6:8] >= 801FD6F0[14:16]: # voice level relative to noise above minimum
  1196. 801FD6F0+8 = 801FD738 # set p->VRU results
  1197. 801FD738[0:1E] = 801FD718[0:1E]
  1198. # 801A0908
  1199. SP+1C = call 801707D8() # V0 = p->controller queue
  1200. call 80093260(801FD708) # V0 = errors when sending VRU cmd 7 and testing state
  1201. call 8017083C(@SP+1C) # write response from controller queue to A0
  1202. SP+1C = call 801707D8() # V0 = p->controller queue
  1203. SP+24 = call 800973D0(801FD708) # V0 = error state when sending VRU cmd 5 (stop listening) using VRU handle A0
  1204. call 8017083C(@SP+1C) # write response from controller queue to A0
  1205. 801FD6F0[4] = 1
  1206. # 801A0958
  1207. return call 801A0150(@SP+24) # V0 = -1 if VRU error A0 in (1, 4, 5, 11, 13, 14, 15) else 0
  1208. 801A0970 reset listening state; 801FD6F0 = 0
  1209. 801A097C write SJIS string A0 phonetically to 801FD760
  1210. accepts: A0=p->VRU string
  1211. l = call 80090180(A0) # V0 = strlen(A0)
  1212. for i in range(0, l, 2):
  1213. SP[28:2A] = A0[i:i+2]
  1214. if SP[28] == 0x83:
  1215. # 801A0A0C: katakana
  1216. v = SP[29] * 3
  1217. 801FD760[i] = 801D36A0[v - 0xC0]
  1218. 801FD760[i+1] = 801D36A0[v - 0xBF]
  1219. elif SP[28] == 0x82:
  1220. # 801A0A48: hiragana
  1221. v = SP[29] * 3
  1222. 801FD760[i] = 801D3580[v - 0x1DD]
  1223. 801FD760[i+1] = 801D3580[v - 0x1DC]
  1224. elif SP[28:2A] == 0x815B: # 'ー'
  1225. # 801A0A88
  1226. 801FD760[i:i+2] = 0x2D2D # "--"
  1227. else:
  1228. # 801A0AB8
  1229. 801FD760[i:i+2] = 0x2020 # " "
  1230. # 801A0AD8
  1231. # 801A0AEC
  1232. 801FD760[l] = 0
  1233. 801A0B20 set values in table 801FFDD4 based on mask A0
  1234. accepts: A0=mask
  1235. for i in range(A0):
  1236. for j in range(8):
  1237. 801FFDD4.append(bool(i & 1))
  1238. i >>= 1
  1239. 801A0B78
  1240.  
  1241. 801A2C64
  1242. accepts: A0
  1243. cmd = A0 >> 0x1C # upper nibble
  1244. v = (A0 >> 0x18) & 7
  1245. # if cmd < 0x10:
  1246. # call @801DF680+(cmd<<2)(A0, v)
  1247. if cmd == 0:
  1248. # 801A2CAC
  1249. ...
  1250. elif cmd == 1:
  1251. # 801A2E30
  1252. ...
  1253. elif cmd == 2:
  1254. # 801A2E50
  1255. ...
  1256. elif cmd == 3:
  1257. # 801A3020
  1258. ...
  1259. elif cmd == 4:
  1260. # 801A3180
  1261. ...
  1262. elif cmd == 5:
  1263. # 801A3238
  1264. ...
  1265. elif cmd == 0xD:
  1266. # 801A332C
  1267. ...
  1268. elif cmd == 6:
  1269. # 801A3404
  1270. ...
  1271. elif cmd == 7:
  1272. # 801A3508
  1273. ...
  1274. elif cmd == 8:
  1275. # 801A3544
  1276. ...
  1277. elif cmd == 9:
  1278. # 801A35D0
  1279. ...
  1280. elif cmd == 0xA:
  1281. # 801A35FC
  1282. ...
  1283. elif cmd == 0xB:
  1284. # 801A3694
  1285. ...
  1286. elif cmd == 0xC:
  1287. # 801A36C0
  1288. ...
  1289. elif cmd == 0xE:
  1290. # 801A3760
  1291. ...
  1292. elif cmd == 0xF:
  1293. # 801A37EC: VRU
  1294. v = (A0 >> 0x10) & 0xFF
  1295. if not v:
  1296. # 801A3804
  1297. 801D5BCC[0] = (A0 >> 8) & 0xFF
  1298. v = 801D5C04[0]
  1299. 801D5C04[0] = A0 & 0xFF
  1300. call 8018EDC4()
  1301. call 8019FD54(v) # ???; sends VRU strings, unmasking the 2nd and 6th word
  1302. call 8018E938(0xF8000000, 0)
  1303. else:
  1304. # 801A384C
  1305. 801D5C0C = A0
  1306. 80200D1C[0] = 0x14
  1307. 80200D1C[2:4] = 0x7FFF
  1308. 80200D1C[4:6] = 0x666
  1309. # 801A3874
  1310. return
  1311. 801A3888 append command A0 to table at 801FFE90
  1312. accepts: A0=command
  1313. v = 801D5BF0[0] << 2
  1314. 801FFE90+v = A0
  1315. 801D5BF0[0] += 1
  1316. 801A38B0 execute commands in table at 801FFE90
  1317. while 801D5BF0[4] != 801D5BF0[0]:
  1318. # 801A38EC
  1319. v = 801D5BF0[4] << 2
  1320. 801D5BF0[4] += 1
  1321. call 801A2C64(@801FFE90+v)
  1322. 801A3930
  1323. 801A399C
  1324.  
  1325. 801A4648
  1326. v = 801D5C08[0]
  1327. if not v:
  1328. return v
  1329. if v == 1:
  1330. v = call 8018ED18()
  1331. if v == 1:
  1332. 801D5C08[0] = 0
  1333. call 8018E95C(0x46020000, 801D5BCC[0])
  1334. call 8019FD04()
  1335. return 801D5C08[0]
  1336. elif v == 2:
  1337. v = call 8018ED18()
  1338. while v != 1:
  1339. call 8018ED18()
  1340. 801D5C08[0] = 0
  1341. call 8018E95C(0x46020000, 801D5BCC[0])
  1342. call 8019FD04()
  1343. return 801D5C08[0]
  1344. 801A470C
  1345. 801A4898
  1346.  
  1347. 801D3310 VRU word buffer
  1348. アトナンジカン atonanjikan How many hours left En_Gs gossip stone
  1349. ハイチーズ haichīzu say cheese (master) pictograph
  1350. オキロー okirō wake up En_Hidden_Nuts sleeping Deku Scrub
  1351. オスワリ osuwari sit
  1352. ミルク miruku milk En_Cow cow
  1353. ハイヤー haiyā hiya! En_Horse Epona
  1354. 801D3568 +258 number of strings
  1355. 801D356C[0] +25C VRU flags
  1356. xxxxxxx0 turned "off"
  1357. xxxxxxx1 turned "on"
  1358. xxxxxx10 device not ready (indicates you need to send it a word list)
  1359. 801D3570 +260 p->most recent VRU results or None
  1360. 801D3574[0:2] +264 first, best VRU hit or -1 or 0x7FFF
  1361.  
  1362. 801D3580 phonetic table for hiragana (debug on error)
  1363. 801D36A0 phonetic table for katakana (debug on error)
  1364. 801D37C0
  1365.  
  1366. 801FD6F0 some kind of (very heavy) VRU manager
  1367. +0 801FD6F0 p->VRU instance (801D3310)
  1368. +4 801FD6F4[0] listening state
  1369. +8 801FD6F8 p->VRU results or NULL
  1370. +C 801FD6FC[0:2] deviance threshold {0x320, 0x3E8}
  1371. +E 801FD6FE[0:2] maximum number of returned results {2, 5}
  1372. +10 801FD700[0:2] error flag mask for results {0x400, 0}
  1373. 0400 voice too low; occurs with low voice levels and relative voice levels, unsure rules
  1374. 0800 voice too high; any voice level over 0xDAC(?) appears to trigger this
  1375. 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.
  1376. 8000 too much noise; relative voice level below 0x190(?) appears to trigger this
  1377. +12 801FD702[0:2] minimum voice level from mic {0x1F4}
  1378. +14 801FD704[0:2] minimum voice level relative to noise {0x7D0}
  1379. +18 801FD708 p->VRU handle
  1380. +24 801FD714 status (0-7)
  1381. +28 801FD718 listening results buffer; 0x1E
  1382. +48 801FD738 current listening results; 0x1E
  1383. +68 801FD758 data buffer
  1384. +70 801FD760 buffer for phonetic string on transmission error; 0x20
  1385. +90 801FD780
  1386.  
  1387. Listening results are ordered a little differently than the actual returned command data.
  1388. The VRUs produce signed, little-endian values. Listening results are big-endian.
  1389. Results are reorganized so indices and deviance are grouped.
  1390. 0x0 2 error flags
  1391. 0x2 2 # valid results (results under "normal" deviance)
  1392. 0x4 2 voice level from mic
  1393. 0x6 2 voice level relative to noise
  1394. 0x8 2 voice length (prob. milliseconds)
  1395. 0xA 2 hit 1: index or 0x7FFF
  1396. 0xC 2 hit 2: index or 0x7FFF
  1397. 0xE 2 hit 3: index or 0x7FFF
  1398. 0x10 2 hit 4: index or 0x7FFF
  1399. 0x12 2 hit 5: index or 0x7FFF
  1400. 0x14 2 hit 1: deviance value
  1401. 0x16 2 hit 2: deviance value
  1402. 0x18 2 hit 3: deviance value
  1403. 0x1A 2 hit 4: deviance value
  1404. 0x1C 2 hit 5: deviance value
  1405. 0x1E 2 mode + status flags; normally should report 0040
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement