
Invaders game in 512 bytes - lelf
https://github.com/nanochess/Invaders
======
s_gourichon
The programmer took great care about register allocation.

On this topic, the Saturn CPU of the HP-48 handheld calculator of the 90's had
quite a lot of registers (9 of them 64-bit, plus a number of others and a
hardware return stack) yet a 4-bit wide bus.

The whole CPU was optimized for BCD (binary coded decimal) computation and
registers were structured into "fields" varying length. Thus you could program
relatively advanced algorithms without having to swap registers with memory or
stack all the time like on e.g. the Z80.

This allowed to write quite advanced things. For example I wrote ASM code that
compiles to a 18kb binary where you can walk into a complex dungeon rendered
in perspective with shading, with writings on walls, monsters, you can find
objects, pick them, throw them, climb stairs, fall in pits.

See [http://amphi-gouri.org/hp48/dm48/](http://amphi-gouri.org/hp48/dm48/) for
details.

~~~
acqq
Sadly, the source code is unreadable without the emulator.

~~~
s_gourichon
Not yet fully complete, but all the source code for run-time is there:
[https://github.com/fidergo-stephane-
gourichon/dm48](https://github.com/fidergo-stephane-gourichon/dm48)

------
userbinator
One thing that you'll notice stands out if you look at this code and compare
it to what a compiler might generate is the very efficient use of registers;
indeed, a compiler that can do this level of optimisation/code generation
would be a "holy grail", but there's been little effort towards that since
traditional code generation and optimisation is "good enough" for most
purposes. However, as this example shows, the actual limit is still very far
away.

~~~
voldacar
Do you know of any work being done in this area? I'm not that familiar with
compiler design but this sounds fascinating.

~~~
rwmj
It's not quite true that no work is done in this area.
[https://en.wikipedia.org/wiki/Superoptimization](https://en.wikipedia.org/wiki/Superoptimization)
is an active area of research, where we try to find the optimal code sequence
(for various values of "optimal" which could include small size, but more
usually highest performance) using various techniques including exhaustive
search, annealing and logic programming.

(To be fair superoptimizing a 512 byte game is far beyond what could be done
today)

------
feiss
The author is an amazing code optimizer and obfuscator, and was winner of
IOCCC many times. Look what he did in js1k 2010: A js chess in 1023 Bytes:
[https://js1k.com/2010-first/demo/750](https://js1k.com/2010-first/demo/750)

His website has much more cool stuff:
[http://nanochess.org/index.html](http://nanochess.org/index.html)

------
Wildgoose
The first program I sold (aged 15) was a version of Space Invaders that ran in
the 512 bytes available on the minimal Acorn Atom microcomputer back at the
beginning of 1981.

Not as impressive as this though!

~~~
jacobush
Given no Internet back then, at least as impressive I'd say.

~~~
Narishma
I wouldn't be so sure. There were other sources of information like computer
magazines, newsletters and clubs.

Most computers back then also came with very detailed manuals, so you could go
far without the need of external documentation.

The Internet brings a lot of distractions as well you didn't have to deal with
back then.

~~~
jacobush
This is true, but speaking only for myself, I got a lot less done then, and it
was really hard to get information. I managed to get data and manuals on my
Spectravideo 728 only after most of my friends had already switched to Amigas
and Ataris :-)

The BBS scene then improved the availability of information for those who
could afford modems and minutes!

------
NikolaNovak
Question; it's been 20 years since I've done assembler, but I want to
understand in what sense is this "512 bytes"?

\- The downloaded COM file is almost 64k

\- The source code appears to be about 4k

Is 512 bytes the memory footprint? Assembled but not linked code? Something
else?

~~~
300bps
_in what sense is this "512 bytes"?...The source code appears to be about 4k_

The source .asm file is about 4k, most of which consists of comments.

The rest is assembly language code with things like:

    
    
            mov ah,al
      

That assembly language which is 17 bytes including the preceding spaces gets
assembled into machine language which is substantially lower. I'm much more
familiar with 6510 assembly than I am 8086 assembly but I believe mov ah,al is
one byte for the mnemonic and two bytes for the registers for a total of 3
bytes. So the actual machine code is far smaller than the assembly source
code.

~~~
acqq
> I believe mov ah,al is one byte for the mnemonic and two bytes for the
> registers for a total of 3 bytes.

Two bytes in the 8086 mode:

    
    
         88C4   mov ah,al
    

And inside, ah and al are encoded with the 3 bits each, spending just 6 bits
for "from which register to which register."

------
bArray
Very nice! I remember also writing my own many years ago under similar
restrictions (it was uploaded to BitBucket in 2016 but existed for much
longer):
[https://bitbucket.org/danielbarry/saxoperatingsystem/src/mas...](https://bitbucket.org/danielbarry/saxoperatingsystem/src/master/PROGRAMS/SPCE/SPCE.ASM)

------
CWuestefeld
For perspective, Atari 2600 had ROM cartridges starting at 2KB, and the
machine itself had 128 bytes RAM. Considering that this game looks better than
Atari 2600 Space Invaders, it seems like a pretty good job.

~~~
filmfact
Well to be fair to the 2600 - the ibm bios brings a fair few kilobytes of code
to the fight.

~~~
theamk
In this case, the BIOS'es contribution is fairly light:

\- video mode change (int 10h, ah=0)

\- RTC clock read (int 1ah, ah=0)

\- keyboard read (int 16h, ah=0 and ah=1)

I am not familiar with Atari 2600 programming, but on the devices of that
class:

video mode change would be at most few outb's, or omitted altogether if
multiple video modes are not supported

"RTC clock" would be a loop waiting for VSYNC, likely less then a dozen
operators

keyboard/joystick will be a simple "inb" at the core. It may, however, require
debouncing, making it the most complex ops.

So in total, this game is amazingly light on the IBM BIOS services. In my
estimation, porting it to BIOS-less 8080 system will only increase the size by
100 bytes at most.

~~~
simcop2387
The fun part of the 2600 is that it doesn't have any real graphics hardware.
You produce the graphics scanline by scanline racing the beam. That's the main
reason the graphics look the way they do, there's no memory for a frame buffer
or even a single scanline unless you dedicate it yourself.

EDIT: Here's the wikipedia article on the topic,
[https://en.wikipedia.org/wiki/Television_Interface_Adaptor](https://en.wikipedia.org/wiki/Television_Interface_Adaptor)

~~~
masswerk
This is how you put an object on the screen on the Atari 2600 (VCS):

1) Horizontal positioning is done by sync. You have to write a value to a
latch register in the exact moment, the beam crosses the desireed location. So
the code has to engage in a delay loop of sorts. However, a CPU clock is 3
pixels long and a minimal delay loop is 5 CPU cycles, providing just a
resolution of 15 pixels for this. Therefore, you have to work out a correction
factor (+7 … -7 pixels) and write this to another register and trigger this by
yet another write to a register.

2) Vertical positioning is done by counting raster lines (you have to do this
anyway, since you have to trigger the vertical blanking and raster retrace on
your own) and, if it's the right one, writing a non-null byte value to the
sprite register in question. Of course, you have to clear it again for those
lines where it ought not to show.

There are just two sprites and three single-pixel objects. So some
repositioning on the fly and additional trickery is required to put something
like Space Invaders on the screen. (There are also background graphics,
consisting of 40 fat pixels, of which you can set up half of them, the other
half either repeated or mirrored. Howewer, these fat pixels are 4 times a
normal pixel wide and all of the same color and not much of use for displaying
game characters.)

The TIA just produces a single raster line as set up over and over, resulting
in a pattern of vertical stripes, which you'll have to interleave cleverly by
your vertical display logic (called a kernel) manipulating the shape and color
of things in order to display a meaningful image. However, as you're doing so,
the beam is racing on…

------
Lowkeyloki
I'd love a screenshot or video or gif or something. I'm on mobile at the
moment and I can't try this out. And I totally understand that it would have
to be a camera pointed at a monitor. That's fine.

~~~
bori5
From the readme:

A small video of the game running over emulation:

    
    
      https://www.youtube.com/watch?v=pC976eejfms

~~~
Lowkeyloki
Wow, that's embarrassing that I missed that. Thank you.

I may have missed it since the README is a plain text file and Github didn't
make that url a link. That's still on me, though.

FWIW, I'll stick it here in a way that's actually a link.

[https://www.youtube.com/watch?v=pC976eejfms](https://www.youtube.com/watch?v=pC976eejfms)

~~~
ngcc_hk
Interesting

------
shitgoose
what? no hadoop? or spring?

~~~
nurettin
wait, those aren't really memes.

~~~
shitgoose
no, these are not memes. they are real. ask any CS graduate to write this
game. my guess it will be at least 5 GB of libraries and a dozen of
microservices.

~~~
nurettin
I thought you meant it facetiously, since the hadoop train passed away five
years ago.

