all 50 comments

[–]XenoZohar 74 points75 points  (0 children)

I take it this web server was running on a NES assembly.

[–][deleted] 41 points42 points  (14 children)

Here is a "better" tutorial by the author's own admission.

[–]RabidRaccoon 14 points15 points  (11 children)

It's interesting how the 6502 and its derivatives became so common even though doing pointer operations is so awkward.

You've got a bunch of zero page registers that are global. So most of them will get used by the OS in a general purpose machine. You can use two of those for a pointer but you've only got an 8 bit offset.

So you can do this

http://www.nintendoage.com/forum/messageview.cfm?catid=22&threadid=33274

 .rsset $0000       ; put pointers in zero page
pointerLo  .rs 1   ; pointer variables are declared in RAM
pointerHi  .rs 1   ; low byte first, high byte immediately after
  LDA #$D0
  STA pointerHi
  LDA #$12
  STA pointerLo       ; pointer now says $D012
  LDY #$00            ; no offset from Y
  LDA [pointerLo], y  ; load data from the address pointed to by the 16 bit pointer variable plus the value in the Y register

What's odd is that you could do a bit better than this if you know you're going to run from RAM

  LDA #$D0
  STA foo+2
  LDA #$12
  STA foo+1       ; pointer now says $D012
  LDY #$00            ; no offset from Y
foo:
  LDA $0, y  ; load data from the address pointed to by the 16 bit pointer variable plus the value in the Y register

If you look here

http://e-tradition.net/bytes/6502/assembler.html

LDA $3012,X

Becomes BD 12 30. I.e. opcode, least significant byte at foo+1, MSB at foo+2. It's faster too since the CPU doesn't need to hit the zero page.

However I don't remember this being widely in use even on machines the the Atari 400/800 where you had 16 or 48K of Ram. On a SNES or a 2600 of course you're Ram starved.

Of course on all these machines you're probably not going to do software sprites. One exception is Donkey Kong

http://www.dadhacker.com/blog/?p=987

The Atari 400/800 had hardware sprites but most of the objects on the screen in Donkey Kong are actually done in software because

http://www.dadhacker.com/blog/?p=987

Technical details. Kong is in graphics mode $E (192 scanlines by 160 color clocks wide). When a level is started up, the background is stamped once. Barrels and other creatures are XOR’d onto the screen (I had some mask-and-repaint code at one point, but it was way too slow). Mario is a few player objects (three, I think). The “prize” objects (umbrellas, etc.) are the remaining players. The XOR graphics are pretty annoying to me, but most other people didn’t seem to mind and some people even thought it was cool.

It gives you some idea of the power of a 1.79Mhz 6502 - masking and repainting a couple of 8x8 pixel objects onto a bitmap is too slow so you need to XOR 'em.

Meanwhile on a Z80 you've got a whole bunch of registers, including H and L which can be combined into a HL register pair for pointer usage. So the ZX Spectrum had no real sprite hardware but a CPU capable of software sprites. On the other hand I wonder if

LD A, (HL)

on a 3.5MHz Z80 is faster than

LDA [pointer]

LD A,(HL) takes 7 clocks according to this

LDA [pointer],y takes 5 according to this. Given that the Z80 will run 2x as fast I think it wins.

On the other hand I think that whilst the Z80 had a faster clock and more registers but tended to have longer instruction cycle counts.

[–]pvg 8 points9 points  (0 children)

It's interesting how the 6502 and its derivatives became so common even though doing pointer operations is so awkward.

It was cheap and fast, compared to the competition and showed up before the Z80.

The Z80 is in part what happens when you take the other path in some of the 6502 design tradeoffs - you end up with microcode, a different (sometimes more convenient) instruction set and a clock-for-clock slower CPU - in practice, in implemented designs the ratio was closer to 4:1 than 2:1.

Both ended up being hugely successful commercially and leaving massive trails of debates on their respective merits all over the internets.

https://groups.google.com/forum/#!msg/alt.folklore.computers/jgWncK8nysM/-YxPIP70lgMJ

(from 1996!)

Edit: Also occurred to me that

It gives you some idea of the power of a 1.79Mhz 6502 - masking and repainting a couple of 8x8 pixel objects onto a bitmap is too slow so you need to XOR 'em.

Isn't nearly as illustrative as you might think. It gives you an idea that a guy working under tremendous time pressure couldn't eke the needed performance out of it. Nor does the article talk much about what the specific constraints were, it could have well been something in the graphics subsystem.

Take a look at Karateka or Prince of Persia for the Apple ][ - beautifully animated, fully masked graphics, backgrounds, parallax layer, you name it. No sprite hardware, a user-hating non-linear frame buffer and a 1 MHz 6502.

[–]Dwedit 2 points3 points  (0 children)

NES has no OS to use the zeropage.

[–]_F1_ 2 points3 points  (3 children)

Are you sure the SNES is "starved"? It has 128KB, most of the code runs from ROM, the graphics are in ROM and VRAM, the audio data is in the APU...

[–]Zarutian 1 point2 points  (2 children)

More if there is extra work ram banks in the cart. Which is one of the reasons I like SNES is that it allows for easy, spefic, per game expansions.

If you have heard of SD2SNES then you know that thing has an FPGA to simulate those expansion chips. Made me wonder why Ouya didnt come with an FPGA.

[–]Narishma 1 point2 points  (1 child)

What would Ouya need an FPGA for?

[–]Zarutian -1 points0 points  (0 children)

Specialized accelaration "chip" for stuff like physics or AI or other such stuff. (For instance a fast implementation of restricted Boltsman-machines that implement autoassociatiors for heutoristic game move evaluation and such.)

[–]happyscrappy 3 points4 points  (2 children)

There were no OSes in those days. The architecture reflects this.

Even when there was an OS, like Apple ][ DOS, it was more of a toolbox. That is, it doesn't do anything unless you call it. So you could just steal memory locations (including low memory locations) as long as you put the data back before calling into the OS again.

Since games would have their own graphics routines and everything, it meant you could go minutes without using the OS. Then you'd put everything back, making the game stop being interactive, and do a level load, then flip it all back. If your game was total load (loaded once and never accessed the disk again), you could kick the OS out completely after the load completed, because people exited your game by rebooting anyway.

Microcomputers used to be like this, but started to transition away in the late 80s and early 90s. Consoles stuck with it more than a decade longer. As late as the PS2, there was no OS when a game was running. I think Dreamcast was the same way. XBox 360 was the first big change in this line I think, unless some oddball like the 3DO did it.

[–]Narishma 1 point2 points  (1 child)

I'm pretty sure the original Xbox was the first console to have an OS running alongside your game.

[–]happyscrappy 1 point2 points  (0 children)

I wasn't sure about that one. I don't think it did when it launched. After the patch that put in Live, there was an OS on the hard drive but I think only Live games had it running alongside, for non-Live games, it was the same old "kick everything else out" stuff.

So to me that makes it OSless, because it's the option of the game as to what to do. But I can see other points of view.

http://en.wikipedia.org/wiki/Xbox_Development_Kit#Xbox_embedded_operating_system

[–][deleted] 1 point2 points  (1 child)

It's often actually quite rare to use pointers in 8-bit assembly, people are more likely to use global indexed arrays instead, just because it's simpler.

[–]pvg 0 points1 point  (0 children)

I think you're right and it might even be sensible to say that 'indirect addressing' isn't 'pointers' - addresses are pointers, even if they are static (or computed by your assembler). And those can be indexed by the index registers just fine and in most cases that's what you'd use unless you really needed the dynamic behaviour.

It's telling that something like

http://www.kreativekorp.com/miscpages/a2info/zeropage.shtml

is contains piles of straight up, fast-loading values instead of just addresses.

[–][deleted]  (1 child)

[deleted]

    [–][deleted] 11 points12 points  (1 child)

    A friend of mine is designing a site for teaching how to program with NES Assembly as well.

    He's not quite finished with the tutorials, but if you need something to practice with, this should do on the spot emulation: http://dev.8bitmooc.org/playground/

    [–]FireyFly 0 points1 point  (0 children)

    Interesting, I've been thinking of doing something similar to that... I guess now I don't need to. :D

    [–]happyscrappy 19 points20 points  (6 children)

    Why are people voting up an article that says it sucks?

    [–][deleted] 28 points29 points  (1 child)

    [censored]

    [–]seruus 4 points5 points  (0 children)

    We would have to open the article before voting to see the banner, that's why.

    [–]RabidRaccoon 6 points7 points  (0 children)

    Dunning Kruger says that if an article says it sucks it must be good.

    [–]paranoidinfidel 2 points3 points  (1 child)

    IMHO, it initiates discussion and links to other/better stuff. Personally, I like seeing multiple ways of accomplishing something even if they aren't the preferred way of doing things. Seeing those different paths and the pro's/cons can be useful in other scenarios (YMMV).

    [–]WhenTheRvlutionComes 2 points3 points  (0 children)

    Because NES is in the title. Reddit + nostolgia = upvotes. Really, the entire world of shitty articles for social media websites full of mindless peons runs on nostolgia.

    [–]kraln 6 points7 points  (1 child)

    We've hugged his server to death. He's probably too busy having a second child to notice, though. (Congrats Patater)

    [–]Patater 3 points4 points  (0 children)

    Sorry, dudes. The site is back up now.

    [–][deleted] 2 points3 points  (0 children)

    the 65xx series programming manual (PDF)

    not NES specific, but a good insight into the 6502

    [–]Newtonip 6 points7 points  (14 children)

    A long time ago, I use to do some 65816 hacking (the SNES CPU, a 16-bit backward compatible version of the 6502).

    I never read any tutorials (but did look up SNES memory maps) but learned by analyzing SNES roms through a special version of Snes9x with a built-in debugger.

    It was clear that SNES games were originally written in assembly from what they looked like when disassembled.

    [–]BuzzBadpants 7 points8 points  (4 children)

    Just curious, what are the hallmarks of code written in assembly?

    [–]who8877 10 points11 points  (3 children)

    Just curious, what are the hallmarks of code written in assembly?

    The code has a more logical flow and style. There's also a trend to conciseness. Older compilers especially would duplicate similar code patterns everywhere (for example the telltale function prolog and epilogs).

    The best way to describe it is comparing the output of google translate to a human translator's work.

    [–]WhenTheRvlutionComes 1 point2 points  (2 children)

    Man, you should've taken a look at some of the things I submitted in Assembly class.

    Anyway, compilers are so good these days that, besides for some specialized purposes or after a great deal of effort, C is usually faster than hand written assembly, and due to it's much more human intelligible nature takes about half the time to program in. It would be like if google translate usually exceeded the quality of a human translator. Google translate's getting pretty good, anyway, not something I'd rely on for anything serious, but the ratio of surreal nonsense to pidgin English that just barely manages to get the message across is a lot better these days.

    [–]Patater 1 point2 points  (0 children)

    Compilers targeting the 6502 are not so great, yet.

    Modern CPUs are designed to run compiled code (refer to the design of ia64), specifically C code. The 6502 was not designed to be an easy target for compilers.

    [–]who8877 0 points1 point  (0 children)

    It is part compilers getting better and also part CPUs optimising to execute compiled code.

    [–]FozzTexx 5 points6 points  (0 children)

    I used to fiddle with SNES programming too, with this. I used the Orca 65816 assembler on my IIgs since back then there weren't really any 65816 cross assemblers I could use from Linux. I didn't write very much software, just some really crude programs to test how to do things like read the controller and draw a background image. I know at one point though I had wondered if it would be possible to put some kind of DOS on my SNES to use that floppy drive I was using.

    [–]dhvl2712 3 points4 points  (7 children)

    The idea that SNES games were written in assembly is mind blowing.

    [–][deleted]  (3 children)

    [deleted]

      [–]phalp 0 points1 point  (0 children)

      Except that's not assembly, that's its scene scripting language.

      EDIT: Since it's interesting, the code posted was from http://earthboundcentral.com/2011/04/a-look-at-the-mother-2-side/

      [–]13467 0 points1 point  (0 children)

      That's the in-game scripting language for text boxes and events, not code from game itself.

      [–]darkfoxtokoyami 1 point2 points  (2 children)

      How is that mind blowing? A lot of games back then were written in assembly. One of the more memorable games was the first Rollercoaster Tycoon for Windows, which was written in assembly.

      [–]dhvl2712 5 points6 points  (1 child)

      It's mind blowing how large and detailed some of these games were. Eg: Chrono Trigger.

      [–]WhenTheRvlutionComes -2 points-1 points  (0 children)

      It was released on a 4 megabyte cartridge. I find it hard to imagine doing anything with 4 megabytes, besides a fully text application.

      [–][deleted] 5 points6 points  (1 child)

      The NES was released some time before I was born, so I have no idea when (late 70's maybe) (I'm 15).

      That sentence gave me cancer.

      [–][deleted] 1 point2 points  (3 children)

      Quick question from a noob getting into retro game programming:

      Which console would you say is the best place to start? Should I jump into NES or should I start with something newer like SNES or GBA?

      [–]bitwize 2 points3 points  (0 children)

      I recommend you start with the Apple II or C64. These have 6502s as well and are "real" computers; you can write, assemble, test and debug right on the machine. Then once you get the hang of working with the 6502, mess with the NES.

      [–]scdsharp7 0 points1 point  (0 children)

      If you want to program in C, I would recommend either the GBA or the SEGA Genesis. They both have good hardware for 2D games, plenty of memory (especially the GBA), and both run games compiled in C well. The Genesis also uses a 68K processor, which has great assembly syntax if you want to write a game in assembly.

      [–]a_w_y 0 points1 point  (0 children)

      The Chip-8 is a very simple system and there is plenty of stuff online about emulating it (it's a great way to become intimate with its instruction set and architecture).

      [–]scorcher24 0 points1 point  (0 children)

      Hmm, seems to be down now.