Original Post

Don’t you love it when new technical details come to light?

In an effort to comprehensively document everything there is to possibly know about Virtual Boy (yes, I’m working on something big), I set my sights on the CPU’s system registers. For the uninitiated, the Virtual Boy’s CPU has not only 32 general-purpose program registers, but 10 system registers containing things like status flags, hardware breakpoint configuration, the processor’s ID, etc.

System registers can be accessed by the program: they can be written to with the LDSR instruction, and read from using the STSR instruction. Those instructions contain a 5-bit register ID field, meaning 32 different IDs, although V810 only defines ten system registers, as follows:

0      EIPC   Exception/Interrupt PC
1      EIPSW  Exception/Interrup PSW
2      FEPC   Duplexed Exception PC
3      FEPSW  Duplexed Exception PSW
4      ECR    Exception Cause Register
5      PSW    Program Status Word
6      PIR    Processor ID Register
7      TKCW   TasK Control Word
8-23   (reserved)
24     CHCW   CacHe Control Word
25     ADTRE  ADdress Trap Register for Execution
26-31  (reserved)

What I was doing was seeing what would happen if you accessed those “reserved” IDs. I mean, what if something happens?

Something happens.

System registers 8-23 and 26-28 probably don’t map to anything. They read back as all zeroes, and cannot be written to. System registers 29-31, on the other hand, exist, and they’re not any of the V810 system registers.

If anyone is able, please look into these to see if we can find additional hardware functionality as of yet unknown to the VB community.

System register 29 can store and load all 32 bits, and it is the only system register capable of doing so (even FEPSW and ADTRE mask off a few bits). Its intended purpose is unkown, and it’s not locked down to an execution address range. For now, it looks like a feasible target for storing a global value not in system WRAM.

System register 30 is read-only and has a value of 0x00000004. This is probably a version ID for the NVC chip, but there’s no way to test that hypothesis.

System register 31 masks off the upper 30 bits, but bit 0 can be written. It’s possible there’s some kind of hardware feature that is enabled and disabled by this register, but I haven’t the foggiest what it is. It’s probably related to the CPU directly; otherwise the flag would be somewhere in the hardware I/O bus address ranges instead.

So again, if anyone can put some investigation into these undocumented system registers, we just might be able to uncover something about Virtual Boy that’s never been uncovered before.

I’ve attached a ROM to test this. Up and Down on the left D-Pad change the current system register, and the A button writes 0xFFFFFFFF to that register. Once that happens, a third line of text appears showing the value that was in the system register immediately after writing to it.

4 Replies

Interesting!

System register 29 can store and load all 32 bits, and it is the only system register capable of doing so (even FEPSW and ADTRE mask off a few bits). Its intended purpose is unkown, and it’s not locked down to an execution address range. For now, it looks like a feasible target for storing a global value not in system WRAM.

This could be useful for when you’ve run out of general purpose registers (Greg Stevens, HollowedEmpire?). For example, you could store general purpose register 31 there, use it for calculations, and restore it at the end of the function.

System register 30 is read-only and has a value of 0x00000004. This is probably a version ID for the NVC chip, but there’s no way to test that hypothesis.

Exercise: test whether STSR-ing from that register is faster than using MOV with the immediate value 4. If it is, I’m going to patch my ROMs to make use of this optimization. πŸ˜› Of course, all emulators would have to be updated.

It would be even more interesting if different Virtual Boys had a different value in that register.

System register 31 masks off the upper 30 bits, but bit 0 can be written.

You mean the upper 31 bits?

Er, right. Upper 31 bits. Only bit 0 can be written.

Very interesting indeed. Have you tried playing around with any of the unused/reserved areas of the memory mapped registers? I’m not-so-secretly hoping there’s a writable flag somewhere that the VIP checks to determine whether or not to swap/clear the frame buffers each frame.

Hmm… that’s kinda interesting. What are the initial values of the registers? Do any of them ever change on their own? It would be interesting to periodically read and randomly change them while running a more complex program to see if anything goofy happens or if they ever change.

If I was to guess, I’d say #31 would be the equivalent of HCCW (Hardware Configuration Control Word) on the V830. In our case, we don’t have internal RAM (unless that’s undocumented too πŸ˜‰ ), which would mean writing that to a 1 would cause interrupts to fail (would try mapping to 0xFE0000x0, which should go into the battery backed RAM area). It’s possible that the bit is just registered and not connected to anything internally as well.

I’m not sure about the others… you could check some of the other NEC V8xx datasheets to see if 29 or 30 were ever used for anything (since, presumably RFU registers would possibly be used in the future πŸ™‚ ). You could also decap the chip and look at the die with a SEM. πŸ˜‰

DogP

 

Write a reply

You must be logged in to reply to this topic.