Nintendo 64 Java
mikekohn.net
mikekohn.net
Yeah, almost all RSP code used was written by SGI/Nintendo and used as shipped in the SDK. For a long time emulators simply high level emulated the RSP code based on the hash of the RSP binary and accepted that a few games like Rogue Squadron simply wouldn't run.
Basically a very, very early programmable GPU, but you were writing actual firmware for it, rather than writing the kind of high level shader functions that would come a decade+ later.
(1) 2KiB for RISCV, because immediate offsets are 12bits signed, and the upper end of the address space is usually not mapped to RAM. That is, 4KiB are possible with RISCV if you control the memory map.
Even on systems with MMUs, it's very common that the kernel won't let you map RAM at address zero for several reasons. And the sizes are being talked about are about the size of a single page.
I bet whoever worked at factor 5 in the RSP department would have some good war stories to tell.
The original devs were in a time crunch in the 90s with the limited experience they had for 3d games. It's possible that they were aware of the bug but said "eh, it's playable" and launched it.
> What was the atmosphere like during the final days of coding? I think there was a lot of panicking going on. But it was still very organised, there was lots of people working very hard. I think it was quite laid back at the very end, not many bugs, gameplay was sorted out on time. One of the programmers had quite a hard time of it – two of them decided not to make games anymore because of Mario 64. Not because they didn’t enjoy it, but because they’d burnt themselves out.
https://pixelatron.com/blog/the-making-of-super-mario-64-ful...
That does not sound culturally Japanese to me.
Maybe worth it?
I have no clue how tested it is, and README mentions only up to 2MB ROMs, but it is a start.
# If you have more than 2MB flash, you need to change the flash size by adding -DFLASH_SIZE_MB={one of 2,4,8,16} here.
2MB might be a minimum, as the standard bootcode needs 1MB + 4KB. See my boot_stub or modified 6102 bootcode for ways to bypass the 1MB checksum: https://hcs64.com/n64info.htmlNobody asked, but I'll list differences I've noticed between the real everdrive and the knockoffs: Games that require a cartridge battery won't won't work correctly on the clones, the SD card slot is a lot cheaper on the clones, and the clone doesn't have a USB port (which I think is used for live game dev debugging?)
It's interesting to note that the Everdrives are still actively manufactured in Ukraine, despite the immense difficulties caused by the war.
https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...
- NGEN (part of .NET since day 1)
- MDIL (Windows 8 and 8.1 store apps, partially based on Sigularity)
- .NET Native (UWP, partially taken from Midori/Project N)
- Mono AOT (Xamarin and Blazor)
- IL2CPP / Burst (Unity)
- CosmOS
And now NativeAOT, which currently only supports CLI and libraries workloads.
- Excelsior JET (one of the most known ones, nowadays out of business)
- Aonix (now gone, acquired by PTC)
- PTC (https://www.ptc.com/en/products/developer-tools/perc)
- JamaicaVM (https://www.aicas.com/wp/products-services/jamaicavm)
- Android since version 5 (https://source.android.com/docs/core/runtime/jit-compiler). With version 7 it became JIT/AOT as mechanism to reduce compile times.
- J/Rockit had JIT caches (nowadays merged into OpenJDK)
- WebSphere Real Time and AS/400 JVM, nowadays lives on as OpenJ9 AOT (https://www.eclipse.org/openj9/docs/aot)
- Jikes RVM (https://www.jikesrvm.org/Resources/Presentations/)
- JX research OS (https://en.wikipedia.org/wiki/JX_(operating_system)), not really AOT, but everything gets compiled to native code when loaded, before use
There were also some hardware implementations using the JVM bytecode as Assembly,
- JOP (https://www.jopdesign.com)
- picoJava (https://en.wikipedia.org/wiki/PicoJava)
- ARM's Jazelle (https://en.wikipedia.org/wiki/Jazelle)
- GCJ (iirc only pre 1.5-1.6 java support so never with generic versions, not sure if they ever implented JNI but relied on their own so libraries with native bindings had to be manually ported iirc)
- Excelsior JET was a strong option for a long time on desktops up until 2018, main selling point was resistance to decompilation but not sure if they ran afoul of Oracle licensing or couldn't keep up with the accelerated pace of JDK releases in later years.
(The below were options to various degrees for iOS developers)
- Avian VM ( https://readytalk.github.io/avian/ ), opensource and seems to be up but never really saw an uptake or proper debug tooling iirc, seems inactive by now.
- Robo VM was another strong option with strong support for IDE debuggers,etc since it was used by gamedevs and the initial libgdx author was involved in it. Sadly they were sold out to Xamarin shortly before MS bought out Xamarin and then promptly shut down since MS only had interest in Xamarin for their C# iOS/Android toolkits.
- RoboVM forks, luckily RoboVM core was liberally licensed so forks were possible for those working on mobile games with iOS ports even if the tooling wasn't as slick as the official RoboVM project (No idea if any of the open source variants have caught up, it was a bit chaotic initially with many forks).
- Intel had(have?) some AOT compiler for Java that was an option for libgdx developers for a while but RoboVM being more "native" had more eyes and no idea if Intel really had a business case for it's Java things ? (
(Funnily enough, I was actually doing an AOT one during late uni times to write a thesis on game GC's (and hoping to maybe commercialize), then Oracle bought out Sun and I wrote a JS AOT prototype instead. Hearing of Oracle vs Goog it felt sane but Oracle did showcase RoboVM later on so maybe it was silly)
I don't know what schools are like nowadays but when I was in school I was taught Java and it feels like giving people ways to use that language in odd places is only going to bring about more good and fun projects to the world
I do SEGA Saturn homebrew, and mostly actually just experiments (I’ve never published any of my Saturn projects so far, though I intend to for one of them), and I only really do it for the obscure interest of learning a kind of fairly obscure and complex processor and co-processor architecture for…the love of it?
I don’t care if I make money off it; I don’t really need to, I don’t care if people see or use it; because that’s not the purpose behind the exercise, and I guess that does seem almost strange but the curiosity and learning is what drives me.
I work a 9-5 as a mobile developer and it’s honestly usually not that challenging or growth-inducing. Not that I’m complaining, I love my job and my company, but in order to stay passionate and ‘into’ programming I find doing these weird passion projects really helps.
Hope that makes sense!
EDIT: I’m also a music producer, and one task I really like to do in a similar way to ‘keep up my chops’ is to re-produce an almost carbon copy of a song I’m interested in particular audio engineering qualities about to, EG, learn about particular techniques being used. I’ll obviously never be able to use or sell them, but I can re-apply the techniques I learned in that experience elsewhere.
Have you considered combining your enjoyment for audio production with your programming skills to develop audio plugins? This is also something that could be monetised, although the VST market seems to be pretty saturated. Start as a side project and see where it leads !
Classic
Iirc it's not such a meaningful distinction anymore. "CISC" x86 uses micro-operations internally. "RISC" ARM has several different instruction encodings (ARM, Thumb, Thumb-2, A64). Increasing numbers of people are working in high level languages anyway.
Like generations of CISC before it. That doesn't make it any less CISC.
https://userpages.umbc.edu/~vijay/mashey.on.risc.html
From that page, which collects a number of Usenet posts by John Mashey:
> The RISC characteristics:
> a) Are aimed at more performance from current compiler technology (i.e., enough registers).
> OR
> b) Are aimed at fast pipelining
> - in a virtual-memory environment
> - with the ability to still survive exceptions
> - without inextricably increasing the number of gate delays (notice that I say gate delays, NOT just how many gates).
The point b is where RISC chips really pulled away from CISC in terms of architectural design, especially chips like the MIPS, which Mashey worked on: The MIPS had a number of points where it exposed the tricks it used to pipeline more aggressively, even at the expense of making compilers somewhat harder to write and/or human assembly-language programmers think a bit harder. However, the lack of complicated addressing modes (post-increment, scale-and-offset, etc.) and the lack of register-memory opcodes with ALU operations, and total lack of memory-memory operations, is still a very common feature of RISC design.
On the other hand, it's simpler than ARMv7 - not just because of getting rid of Thumb, it also doesn't have conditional execution.
In the olden days we thought that massively complex instructions on chips with huge microcode would be just the thing. Simplify your code by calling a single machine code instruction that does a complete matrix manipulation, or solves a polynomial, kind of thing.
It turned out that making CPUs that worked that way was expensive and complicated, and if they didn't quite work you were stuck with it. Then, it further turned out that actually it was easier to be Good At Software than it was to be Good At Hardware. If you wrote a clever assembler, and a clever compiler, and some clever libraries, you still didn't need to care about solving horrible maths, you just called a function to do it.
And then, we came around to the idea that it was faster to use small simple instructions and cache a lot of them, and keep as many of the values we were juggling in registers so you didn't waste time with a memory cycle. So, CPUs got simpler instruction architectures and all that space previously used for selecting ever increasingly baroque instructions in the opcode could be used to select from an ever-growing number of registers.
Ultimately CPUs will be only able to do a lsl, mov, add, and xor, in a single conditional instruction, with 131072 64-bit registers to choose from, in a single clock cycle at 10GHz or so. People will still say "well yeah but do you really need that add?"
Both RISC and CISC are effectively marginalized, though. The current trend for everything beyond embedded is somewhere kinda in the middle. With the some pretty pointless nitpicking about if something is or isn't RISC and devolving that entire movement down to just "but it doesn't do memory indexing!" or whatever.
It turns out what makes a fast processor is something that uses both RISC and CISC ideas. And that's what nearly everything does these days as a result, because speed is all that matters