Original Post

While hacking with the VIP recently I noticed some odd behavior when strobing DPRST: the background color would shift from full brightness to a dark shade of red, despite my not changing the value of BKCOL. Chapter 29 of Nintendo’s official Virtual Boy development manual says that other than the SYNCE, RE, and DISP flags, the values of the other registers are “indeterminate” after a DPRST. What I found to be odd is that this aforementioned behavior is reliably reproducible on my VB hardware. Are the results of a DPRST really “indeterminate” or is there an observable pattern to it? I did some digging and came up with some numbers and conclusions.

Attached to this post is a small program I wrote that first initializes the VIP registers to a known state and then invokes DPRST in various ways, reading out the values of each readable VIP register after each invocation and then printing them to the screen for examination. Each button press will advance to the next method of invoking DPRST. These test “classes” are, in order:

  • “INITED” : setting all writable VIP registers to known values
  • “NOT INITED” : strobing DPRST | DPEN then reading back the VIP registers
  • This test class is repeated four additional times, each with an increasing number of nop instructions between the st.h to DPCTRL and the first read from VIP registers -> NVC registers

  • “DPRST ONLY” : strobing only DPRST (DPEN is not set), then reading back the VIP registers
  • This test class is repeated four additional times, each with an increasing number of nop instructions between the st.h to DPCTRL and the first read from VIP registers -> NVC registers

  • “BKCOL INITED FIRST” : strobing DPRST | DPEN, setting only BKCOL to a known value, then reading back the VIP registers
  • This test class is repeated nineteen additional times: four total times each for increasing values of BKCOL, then five total times each with an increasing number of nop instructions between the st.h to DPCTRL and the st.h to BKCOL

  • “REST AND FRMCYC NOT INITED” : strobing DPRST | DPEN, then setting the brightness registers in a specific order, then reading back the VIP registers
  • This test class is repeated two additional times, then five total times within each of these with an increasing number of nop instructions between the st.h to DPCTRL and the first st.h to BKCOL:

  • “BRTA INITED FIRST” : BRTA is set first, then BRTB, then BRTC
  • “BRTB INITED FIRST” : BRTB is set first, then BRTA, then BRTC
  • “BRTC INITED FIRST” : BRTC is set first, then BRTA, then BRTB

The test suite then repeats itself, going back to the first “INITED” state.

Here is a link to a Google sheet containing results from my running this test suite five times in a row on one Virtual Boy unit. I have bolded results that differ from the final “settled” result, and I have additionally italicized results that differ between subsequent passes, demonstrating that the time necessary for DPRST to complete is variable and unpredictable, but also that the VIP registers that are affected by a DPRST always arrive at the same result for a given test class after three NVC cycles. The four nops case is tested to prove that its results are identical to the three nops case. https://docs.google.com/spreadsheets/d/1lkFya5fQmpeXU7G6pVVEHpGNzQEouu4-tpy44-VpqzE/edit?usp=sharing

The tl;dr of what I found is two-fold:

  1. DPRST is not instantaneous; it takes a few NVC cycles to complete. The total cycle cost is unpredictable–even across subsequent passes–and does not seem to follow a pattern, however I did observe on my hardware that DPRST would always complete by the time a load/store instruction was executed a minimum of three NVC cycles after the initial DPRST strobe. In other words, sometimes DPRST takes fewer than three NVC cycles + a load/store to complete, but it would always be finished by that time at the latest on my hardware.
  2. Absent of explicit values to reinitialize the display registers after a DPRST, the VIP will use the last value it sees on the data bus as a seed value when resetting the display registers.

In both cases above, when strobing DPRST by writing 0x0303 to DPCTRL, without doing any further memory accesses for at least three NVC cycles thereafter, the last value on the data bus therefore remains 0x0303 and the BRTx registers are all each reset to 0x0003, resulting in a very dark palette and thus explaining the color shift I described at the beginning of this post. The same is true in the “DPRST ONLY” case where only 0x0301 is written to DPCTRL: the BRTx registers are all each reset to 0x0001. Likewise, if one of the BRTx registers is initialized before DPRST completes, the VIP uses that value on the data bus as a seed for the remaining uninitialized display registers, resulting in REST, FRMCYC, and CTA each having the same initial value as that written BRTx register.

None of the currently-maintained Virtual Boy emulators that I know of as of the time of this writing get this right; Mednafen treats a DPRST as an instantaneous action that resets none of the display registers other than the SYNCE, RE, and DISP flags in DPSTTS. I encourage anyone else interested in this little science experiment to run my attached program on their own Virtual Boy hardware to provide more data points here. Though what I’ve discovered about DPRST‘s behavior here doesn’t affect any commercial games to my knowledge, since there’s a pattern to at least some of it I think it would be worth proper emulation for accuracy’s sake.

0 Replies

No replies yet.

 

Write a reply

You must be logged in to reply to this topic.