I wrote a Game Boy Advance game in Zig
jonot.me
jonot.me
If making the respective loads and stores volatile doesn't solve this problem please feel free to file a bug against the compiler.
Andrew (or any Zig mavens) - What would be the idiomatic way of solving this issue? Can you define your own memcpy with @std.mem.doNotOptimizeAway or something?
There’s a proposal for a way to disable LLVM generating builtin calls like memcpy. But I’d argue volatile would still be more appropriate in this case.
https://github.com/ziglang/zig/issues/22110
Edit: this comment from later in the thread is also relevant:
Windows being by far the most dominant operating system from 97-2015 definitely exacerbated a dearth in knowledge among the young. In the early days internet access was not ubiquitous and shipping an operating system without even a primitive programming environment definitely lead to missed years of programming for me.
I learned a lot about windows, lots of UIs and how the system was constructed somewhat, but no visual studio, no functioning compiler in base and the only interpreter being fucking batchfiles with no docs… come on…
I'll go download them all for archiving.
I tried to use the wayback machine version, but it didn't cache the PDFs right since I guess they're hosted on a public Google Drive
Eventually, though, I just installed a linux partition and literally never looked back. The entire ecosystem of everything I was learning at the time (Python, JS, PHP) was set up for unix. Things have improved over time, and obviously WSL is nice, but it's still a pain.
You just download the official Python installer, and off you go. It even comes with Idle as a reasonably good IDE.
Now you're making me feel old.
Back in these days you had no wheels and I think it was at least a partial reason for why conda was a thing.
Wheels, Conda, and WSL, helped - now, all the R&D guys at work use Python on Windows with PyTorch, TensorFlow, and all that without problems. I'm also using (mini)conda (on Linux) instead of virtualenv - it's nice because I don't need to worry about all my venvs breaking after an OS upgrade.
Anyway, compared to those days (I started with 2.4 on Windows, switched to Linux around 2.7), working with Python on Windows is at least feasible.
The eventual solution for this was something called "Microsoft Visual C++ Compiler for Python 2.7" - which was pretty much just enough of VC++ command line tools packaged to make it possible to build things.
As far as I remember Python REQUIRED to be installed on C: and in something like C:\Python where it would bring 5000 various files.
Even more time ago, I was at a Java class, where my code would work on my computer but just wouldnt work on the computer of the lecturer. I remember the guy spend like 10 minutes looking at the (very simple) code and trying to figure out why the code worked on Windows but not on Linux
That being said Microsoft know windows is terrible for software development which is why it’s so easy to use Linux inside Windows with WSL2. Since Docker Desktop for Windows requires WSL2 it’s very common for any developer AD account to have it locally as admin.
What are you smoking man? Don't impose your beliefs as facts upon Microsoft.
It's a smart play for them to have WSL- it means less friction to target Linux and will keep people writing software on Windows (which increases the likelihood of making software for Windows- especially developer tooling).
I think the parent is wrong that developing software on Windows is hard, my original comment up-thread was largely regarding the fact that in the late-90's and early-00's internet access was not common and getting your hands on a Microsoft Development environment was the furthest thing from easy. Linux, ironically, was easier as it came with all kinds of documentation and interpreters and compilers out of the box.
https://techcommunity.microsoft.com/blog/windowsosplatform/a...
However they have been working on something else for specific workloads,
https://opensource.microsoft.com/blog/2024/11/07/introducing...
(This latter, Windows sucking, is not necessarily meant in isolation but as part of our world: Windows is not supported by many modern tools.)
I don’t think windows sucks, I think that a lot of people outright refuse to use windows and design their tools to run on Linux only, making choices that are optimal for Linux but not for windows. two examples are processes vs threads and opening/closing lots of files. Ironically the Linux first approach of processes over threads doesn’t really scale to the level we want. Postgres is a great example of trying very hard to be multithreaded as it’s hit the multiprocess limit, and struggling to do so.
For better or worse, UNIX has won on embedded and server room.
Despite my UNIX experience across all known vendors, I only use WSL for Linux containers.
For better or worse, UNIX has won on embedded and server room.
I think this is the HN bubble at work. Maybe you mean something qualitatively or quantitatively different than I do when you say server room but every client I've worked with in my extremely conservative industry in the past ten years has been running on site, coloc, or cloud "server rooms" on windows.On embedded most RTOS support some variation of POSIX, even if not fully compliant.
Windows servers seem to be left to Microsoft shops, running a mix of .NET Framework with IIS, SQL Server, Sitecore, Sharepoint, Dynamics, AD.
In terms of IDE support, VSCode with the MS Python extension bundle is a pretty good Python IDE.
Apropos - if I ever win the lottery and don't need a job I'm going to spend some time learning Plan 9. Superficially it seems to be Unix without many of the warts combined with some concepts from NT/VMS that make good sense.
This can be quite a successful career, probably even if you start today.
But he focused on building a long-term sustainable business, not chasing some buzzword-du-jour, VC funded pipedream with a quick exit, and thus no matter his personal success will never have any HN cred.
These sorts of comments really don't fit with what I've seen here. HN is very encouraging even of personal projects.
It’s also similar to working for a boring shipping company vs working at FAANG. You could be doing an identical job at both, but one is perceived by some to have a special cachet.
That is indeed what it says, but I've never seen anything to substantiate this. Lots of people are very curious about people who have side hustles, or side hustles that became main hustles. HN is a set of pretty un-herdlike individuals, and you're as likely to see someone who thinks socialism's a great idea as someone who thinks capitalism's lifted billions out of poverty.
I'd recommend adding OpenGenera and IBM's systems I and Z to that list: a whole bunch of us build careers out of unnecessary unix make-work too
Then I got my first PC with Windows, and I learned a shit ton on it.
I am sure you had little effort to get your games, didn't you?
If you wanted to code, you would have done the same effort to get what you needed.
Magazines were a thing too...
Cheap excuses, the OS is irrelevant here.
Many HN readers frequently forget they lived in the perfect storm to allow their skills to grow.
As far as compilers, Borland shipped a free version of their C++ Builder 5.5 compiler right around that time, too, so on Windows we had that in addition to MinGW.
1) very slow — my modem was never able to achieve more than 2.5-3 KB/s, and
2) pretty expensive given our measly salaries.
I also didn't speak English at all. I first got access to a programming environment at 16, at an age where my Western peers were starting to write operating systems: it was a copy of "pirated" Delphi that came by pure chance. The first couple of years I was making shit that wouldn't impress anybody because there was nothing to learn from besides the standard library, which would probably be achievable by a computer science version of Ramanujan, but not by some random dude like myself.
Please remember about the rest of the world before accusing others of making "cheap excuses". Not every person on this planet lived or lives in the middle of Manhattan; this may very well include GP.
I grew up in the MS-DOS era and my exposure to programming was basically batch files too. That and editing CONFIG.SYS.
Hey now, Windows Script Host (WSH) supported VBA and JScript scripts. WSH was installed by default on systems up through Windows 7, I believe. Scripts run though WSH had access to a wide array of APIs -- a lot was possible. The WSH executable (wscript.exe) was also configured to be the default handler for .js files in Windows Explorer.
Also, HTA apps were an option. Write an HTML file, include a <script> tag with either JS or VBA, and you have access to APIs equivalent to a local HTML file opened on IE5, plus some. This was a popular option at one point for powering CD-ROM autorun menus, among other things.
(The company I worked for used embedded HTA in a massive C++ COM app to render some forms where the fields and values had to be dynamic based on data only known at run time. Debugging was horrible until I learned you could inject Firebug Lite into the HTA apps and at least be able to console.log(). It was truly a dark, dusty corner of Windows programming -- of which there were many.)
I did use it for an "Introduction to programming" magazine article back in mid-2000s though, main reason because it was already there and all you had to do was open Notepad and start typing (...and make sure you save with a .vbs and not a .vbs.txt extension...). I even got an email a few years later by someone telling me they got into programming because of it :-P.
And we didn't had the Internet to learn from.
Personally I don't get this kind of excuses.
I know this because my mother knew more how to program than I did, and I was the one with the passion for it and she was not.
I also discussed this recently with a 47-year-old programmer. and we came to the same conclusion.
That wasn't true of CP/M, UNIX, VMS, Atari ST, Amiga, and many others.
The reality was not the same as 8 bit home computers, and even on those you were limited by BASIC. Anything else like machine code, required the same learning effort.
If you wanted to program, you either bought the programming tools, or pirated them, most of the time.
Then you would need to buy books, computer magazines, or have the luck of local library with computing section, to actually learn how to use them.
The only programming book in my local library was COBOL.
There was no included disk (it was missing) but in hindsight, it would likely not have worked on windows anyway.
Your premise is that I knew what I was looking for, I kinda didn’t.
My first proper exposure to programming anything was when college told me there was a thing called visual studio and .NET; its only later when installing linux that I found that many of the systems were written in interpreted languages and could be modified (yum, apt etc).
That was extremely evolutionary for me.
Just having access to electronics was revolutionary.
How would we even know what to look for, if it wasn't for our curiosity?
My premise is that Microsoft dominance took a few years off my programming journey- obviously I was curious and motivated because otherwise it would have been impossible to he where I am now without motivation and curiosity.
I’m not entirely sure what your argument against this is other than that you potentially had it worse, which is not my point. Obviously motivation and curiosity are enough eventually, since we’re here.
If Linux was the monoculture then it would have happened sooner for me, much sooner.
UNIX was already around doing those days, and it surely wasn't that easier either, unless one was already at the university with enough budget for their computing infrastructure, or something like a bank, although in many countries most likely the most advanced stuff would be MS-DOS terminals connected via Novel Netware, running Clipper applications.
Not in 1980's Portugal.
In the 20000's, an early 3-DVD release (Sarge) was like night and day. Properly documented with all the manuals obtainable either thru Synaptic or the bundled magazine-book.
And for this, one had to be curious, track down people with knowledge, either from computer magazines ads, hanging around electronic stores, eventually find people with similar interests, to meet them physically.
In my case, I had no access to software from other people, but the library had tons of old books for programming all kinds of computers in mistly basic. So first I learned translating commodore etc to gwbasic. The peek and poke gave a trapdoor to assembly, which granted e.g. mouse access. After I managed to install gwbasic as a TSR, I realized I basically had hollowed out the interpretrr, and started writing straight in debug.com. It took 3 years before I discovered MIX C in a dusty corner of a bookshop. It cost a fortune for this kid, and frequently miscompiled things, but it was one of the first pieces of software I got that didn't come with the computer.
sure, the windows installer is easy enough to get set up, but pretty quickly i started noticing a pattern in most documentation/tutorials.
Linux: one-line setup command
Windows: nothing, or a complicated, multi-step process (that rarely works without hiccups)
wasting my time going down rabbit holes debugging my environment was not as fun as actually writing code
QBASIC was always there, though?
From Win98 onwards, Active Scripting was there out of the box with VBScript and JScript. From Vista onwards, .NET runtime shipped as an OS component, and it includes C#, VB.NET, and (back then) JScript.NET compilers in the box. Although, granted, no offline docs in either case.
I did. At one time I did write a program that wrote to video memory in units of 8 bits, but the emulator I was using did not prevent that, so my program worked on the emulator but not on the real hardware, and I could not figure it out until I found out that was the problem and I managed to fix my program so that it would work.
__attribute__((target("arm")))
void interrupt_handler() {
...
}
that fancy __attribute output can be achieved quite nicely using a custom pragma/codegendecl -- we did exactly this for the embedded firmware written in Nim at my previous workplace, to get access to some specific features of the ESP32-S3 (things like RTC_ATTR_NOINIT for example)I would generally expect this optimization to only be done for programs executing in userspace, not os / kernel style programs like this is. I would have expected the equivalent of -nostdlib to handle this automatically. I wonder if the author's build could be tweaked to tell llvm (which zig is based on) not to perform this or other "default to stdlib implementation" style optimizations
As a side note, the optimization pass that detects and replaces memcpy is called LoopIdiomRecognize [2]. It actually detects quite a bit, not just memcpy.
[1]: https://llvm.org/doxygen/TargetLibraryInfo_8cpp_source.html
> IR-level volatile loads and stores cannot safely be optimized into llvm.memcpy or llvm.memmove intrinsics even when those intrinsics are flagged volatile. Likewise, the backend should never split or merge target-legal volatile load/store instructions. Similarly, IR-level volatile loads and stores cannot change from integer to floating-point or vice versa.
Even in a baremetal/OS context, the compiler is generally allowed to split, combine, reorder, and eliminate memory access however it likes as long as the end result is consistent. Being able to do that is very important for performance and code size, which especially matters in embedded or OS dev -- for example, inserting memcpy calls can save on code size for things like passing a medium-sized struct to a function. The memory model for any reasonably low-level programming language nowadays requires you to specify whenever you actually need memory access that look exactly like you wrote.
The OP suggests:
> I know that this is a long shot, but it would be nice if there was some way to specify how memory in certain address ranges need to be addressed.
The downside to this approach is that the compiler doesn't usually know what address range an arbitrary pointer will acccess; it's not resolved until link-time or often runtime. So this would require dynamic checks around every single memory access, which would kill performance. Thus, the solution is to use volatile loads and stores for any memory ranges that need special treatment.
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
> The compiler may generate calls to memcmp, memset, memcpy and memmove.
Wasn't Zig moving off LLVM?
Bitfields! This is valid C:
struct foo {
unsigned bg_priority: 2;
unsigned character_base: 2;
// ...
}; struct bitmap_file_header
{
UWord signature;
UDWord file_size;
UWord reserved_1;
UWord reserved_2;
UDWord file_offset_to_pixel_array;
} __attribute__((packed));#push(pragma(pack(0)) ??
I’ve done a lot of direct register access in C this way. I do like Zigs ability to just define the different sizes though.
#pragma pack(push)
#pragma pack(1)
/* ... */
#pragma pack(pop)
The first two lines can also be condensed into #pragma pack(push, 1) An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf 6.7.2.1 § 10 port_a.data_out |= GPIOA_PIN_1 | GPIOA_PIN_2;
and port_a.pin1 = true;
port_a.pin2 = true;Brutal. I don't miss but banging much.
its crazy how nice knowing 100% of whats going on is
One nit on mobile (Firefox and Chrome, Android), your code blocks overflow the background instead of scrolling.
You left out the most important part of the post.
Related, I found this old post that goes into the basics of GBA coding [1]. It doesn't look nearly as bad as I expected. That said I'm sure performance might be the issue once you start having a few things going.
If you have a good resource please let me know (I prefer C).
Edit: also this library [2].
Can you post the code that's impossible to write properly?
Could you elaborate on this? Does LLVM support this feature? If so, it might not be too hard to get it into Zig.
- The compiler doesn't typically know anything about memory address ranges; that's the linker's business.
- Even if you taught the compiler about memory address ranges, the compiler often won't know what address ranges a pointer could point to at runtime. For instance, suppose you declare a function that takes a pointer as its parameter; and then maybe elsewhere in your code you call it with pointers to various address ranges. What's the compiler supposed to do, check the pointer value at runtime and branch based on its address range? That's certainly not good for performance or code size.
So we clearly need some way to "color" the pointer type itself as belonging to a specific address range -- a function needs to be able to declare what color of memory it wants to operate on, and it should be an error to pass a wrong-colored pointer to a function. Except you can already do this in programming languages today! Create a wrapper type representing a pointer to a specific type of memory (something like 'struct VramPtr(*mut u32)' in Rust), and define read and write functions that issue volatile writes of the correct type (or even inline assembly if you need some specific instruction that volatile doesn't guarantee).
0.13.0 and 0.14.0-dev.2589+0df1f3df2
Both gave the same error:
run gbaimg (tiles.zig) transitive failure │ │ └─ zig build-exe gbaimg Debug native 1 errors
I can't name a fully 8-bit machine with a 3d focused graphics chip. Maybe there are arcade boards?
It arguably fits, because it pairs a 68010 with hardware accelerated 3d graphics. As far as I can tell, it's not quite modern 3d graphics. If you paid for the geometry engine, you did get hardware accelerated transform and clipping. And the framebuffer supported hardware acceleration of 2d polygon. But if you wanted texture mapping, that was all done on the CPU.
I don't think we can consider SGI as having "modern" 3d accelerated graphics until they implemented support for hardware accelerated texturing with the Reality Engine in 1992, long after they switched to MIPS.