Guy Perfect wrote:
It’s far simpler to use pre-allocated static memory and use the stack by declaring struct variables in high-order functions.
Sure, unless you don’t know and can’t predict how much memory you’re going to need, or you need variable-sized structures, which is probably cr1901’s situation.
Virtual Boy has 64KB of on-board memory. If you’re considering setting up a paging system, be careful you don’t wind up using it all just trying to keep track of where it is.
Wouldn’t you need extra hardware to do paging?
My programs have two “threads”, if you will, that run side-by-side to present the user experience: there’s the audio thread, and the video/game thread.
So basically, they work the same way commercial games do.
Well, actually, Red Alarm’s gameplay runs at the same speed regardless of the frame rate (look at the final stage where it gets really low), so that’s an approach to take if you can’t guarantee that your frames will always render in the same time.
Insmouse also updates objects on the VIP interrupt, but I think all other video stuff is done in the same “thread” as gameplay.
Other programmers have other approaches: I know for a fact that the GBA Pokémon games process all of the audio through interrupts, since whenever you crash the game by putting a hacked mon in the PC, the music keeps playing…
So does Galactic Pinball. Try getting more than 100 million on UFO. 🙂
cr1901 wrote:
Does anyone familiar with disassembling commercial games know whether any commercial games implemented a small heap manager in the VB RAM for maintaining data structures like event queues and possibly alternative stacks for interrupt processing and the like?
I don’t know, but I guess Red Alarm uses one because of its complexity (huge levels with moving parts and tons of enemies). Maybe Golf does too, although I’m not sure whether a renderer like that requires dynamic memory allocation.
As a follow up, does anyone have any experience writing a small heap manager for VB RAM?
Yes.
(Edit: you’re probably better off writing your own for your specific requirements, e.g. whether you need one that uses handles and can defragment the heap, like the classic Mac OS, or you want one that’s really fast but uses pointers directly, like DOS.)
If anyone has alternative ways of handling hardware events that don’t just resort to polling each time a hardware request is made, and are a bit more controlled than “worrying if a received interrupt will interfere with speed-critical game-logic processing or other fun race conditions” I’d love to hear your feedback.
Can you give some examples? You can often get away with polling, but yes, the code might be more elegant with interrupts.
And one last q: Is VB music typically controlled by the timer interrupt (i.e. wait until timer interrupt to change the playing sample)?
Yes, I think that’s how all commercial games do it. As usual, you can get away with calling a “do sounds” function in a VIP-synchronized loop, but if you want more precise timing, interrupts are the way to go, and you usually don’t have to worry about race conditions.
- This reply was modified 10 years, 2 months ago by HorvatM.
cr1901 wrote:
Guy Perfect wrote:
I don’t use GCCVB for my Virtual Boy development…Just out of curiosity, what DO you use then?
He uses “devkitv810”, which is also based on GCC, so I’m not sure how it is better than gccVB. When he’s too cool for C and assembly, he writes instructions manually with a hex editor.
I’ve found links to the official C compiler (Virtual Utopia C Compiler) that Intelligent Systems sent developers on this site… I’m considering running a DOSBOX session and using that to compile instead, even if the optimization wouldn’t be as good as GCC.
VUCC is actually quite good, I think it’s better than GCC in some situations. It’s also very flexible. But unless you have a really fast computer, it would be probably too slow in DOSBox. There’s also the question of how legal it is to use it.
I think I used Dillo. I use Links, Arachne, or Dillo, depending on the purpose. Links is great all-around (with text and graphics modes), Arachne supports animated GIFs and the mouse wheel, and Dillo has tabs and the best CSS support. No DOS browser supports JavaScript, but PVB doesn’t really require it.
BTW, Mednafen is also being ported to DOS, but I don’t know when it will be available (I’m not involved in its development).
By silence, do you mean SSTOP? Is it any different if you just set the volume of each channel to 0?
Thanks for the rip!
BTW, the title screen music is also played on the “take a break” screen (the one with the cup of tea, after hole 9 in the tournament), where it’s slightly longer and it loops. You also missed two other tracks, so here they are.
Attachments:
The note looks like “本体上部のVBカセットスロットの止め具です。” to me, but I’m no expert.
Very cool. Have you tested any existing homebrew code with it?
No, I’m not actually developing anything, just playing/testing more homebrew ROMs recently, and most are well below 2 MB.
That would be ideal, but I got the impression that it’s not possible.
http://www.planetvb.com/modules/newbb/viewtopic.php?topic_id=3673&post_id=8666#forumpost8666
If it will be, there’s still the question of what to do with old FlashBoys that may not support this.
MineStorm wrote:
I can’t test them because I don’t have a stand for my VB.
Then what are you waiting for? Print one!
Seriously though, would that be possible? The prices of stand-alone (pun not intended) stands and stand components on eBay are ridiculous.
I agree with thunderstruck. At least for me, competitions are stressful, and even if everyone started making something now, it would take more than a year to make a professional-quality finished game.
Instead, if we had a general celebration, everyone could help. For example, we could get recordings of music from hardware for those games that haven’t been recorded yet, new reviews (of both commercial and homebrew games), new ROM hacks (OK, this generally requires programming knowledge, but for Insmouse there’s InsmEdit :P), and I’m sure Protoman and VectrexRoli will shoot some videos for the occasion.
Additionally, two other historically important assemblers diverge on the matter.
ISAS, Intelligent Systems’ assembler for Virtual Boy development, which was used for commercial games, only recognizes the form “SETF 10, r1”.
FXAS, Hudson’s assembler for PC-FX development, only recognizes “SETFNZ r1”.
Regarding CLI and SEI, do we even know how long the stock V810 methods take? Specifically:
; CLI
movea 0xEFFF, $0, $10
stsr $PSW, $11
and $10, $11
ldsr $11, $PSW
; SEI
stsr $PSW, $10
ori 0x1000, $10, $10
ldsr $10, $PSW
I can’t find the duration of LDSR and STSR in the V810 manual.
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?
Just a thought. Could this be the mythical “Hong Kong cartridge with all commercial games, including prototypes”? I think a bad translation could cause this to be produced from “a cartridge dumper being able to dump all commercial games, including prototypes”.
It’s really cool that they recognize VB as the spiritual predecessor of today’s home VR systems, but I’m sure they’re not expecting to ever get that much money, which is probably why they’re setting the bar that high.
If they do get it, they will probably spend as little as possible on VB support and instead concentrate on the other (much more attractive) goals. Although I do wonder how they’re going to make it work. Maybe they want a million because they know it’s going to make the development so much longer to make it VB compatible. Maybe they will need to manufacture their own cartridges with extra RAM and a faster CPU. 🙂
HollowedEmpire wrote:
So according to the unofficial doc, r1-r5 *seem* to be free from what I saw. The V810 Architecture manual seems to suggest they are used for the stack among other things. The seminar slideshow suggests similar, but says it depends on what tools you’re using. And finally, the V810 Architecture Summary flyer claim it is utilized by assemblers and compilers.What I want to know is, which ones are exactly in use and which aren’t? And would it be wise to not utilize them, for sake of possible future debugging tools or such things?
Register 1 is supposed to be used for loading large constants into other registers, as in:
movhi 0xABCE, $0, $1
movea 0xEF12, $1, $10 ; $10 is now 0xABCDEF12
Apparently nobody at NEC noticed that you can use the same destination register in both instructions. VUCC (the compiler used for commercial games) also uses it for comparing values when a constant is too large to be encoded into the CMP instructions. I don’t think GCC uses it at all though.
I have never seen register 2 used.
Register 3 is the stack pointer. You can use it as a general purpose register if you store it into a global variable and disable interrupts, since interrupt handlers save all other registers onto the stack (this depends on the compiler though, so maybe gccVB/VBDE does not do that, but VUCC does).
Register 4 is intended to be used for fast (one instruction – LD or ST with a non-zero offset) access to global variables, and VUCC does use it for that, but I think GCC doesn’t, or maybe you need to declare variables specially to take advantage of it.
I have never seen register 5 used.
If you use register 30 and you don’t use bitstring instructions, remember that it is also implicitly used as the destination for the remainder of DIV and DIVU and the high 32 bits of the result of MUL and MULU.
You can also use register 31 if you store it somewhere before calling another function. You don’t have to disable interrupts because interrupt handlers will save and restore it.
To a certain degree, everything is possible. But doing this would require so much work that in the end, you’d have a remake, not a port, because SNES and VB are completely different systems.