Hacker News new | past | comments | ask | show | jobs | submit login
Prince of Persia source code released (Apple II assembly) (github.com/jmechner)
379 points by andrewf on April 17, 2012 | hide | past | favorite | 70 comments



I'll have to find some time to settle down in a deep leather chair with my smoking jacket and a snifter of brandy for a fine evening of reading through someone else's code.

Sounds like fun!


I really hope the YC comment section doesn't become the reddit.


My apologies. Jeff Atwood made me a guest blogger without asking me first, then added some boilerplate that I didn't agree with. I'd have given him permission, had he asked, and I appreciate the inbound traffic, so I didn't complain. However, this seemed like the perfect opportunity for some humor while clarifying my position :-)


Love it!


Oh, how history repeats itself..


Brilliant!


So many down votes? I liked the reference to the recent item "Learn to read the source, Luke"[1] quite a lot!

[1]: http://news.ycombinator.com/item?id=3849203


I think the reason you were downvoted was that your comment didn't really say anything unique- it just agreed with the parent.


And, just as a reminder, there is a wonderful book. It's from the journal Jordan Mechner kept at the time. It's an excellent read.

http://jordanmechner.com/ebook/


I agree, it is quite interesting to read his thoughts as he was going through the process of developing the game and what the industry was like at the time.


This is a very interesting thought exercise on "what if you could send modern programming languages back to the 1980s?" http://prog21.dadgum.com/6.html

It would be interesting to analyze early Apple ][ game images and see which didn't use assembly. Wizardry was a notable example for using USCD Pascal, essentially running in a VM. Infocom games of course used Z-code. Applesoft BASIC was fine for some text adventures (Eamon for example).

There were also programs like Microsoft's TASC that compiled Applesoft to binary, much of the speedup gained by converting floating point values to integer.

The SWEET16 interpreter was also built-in to ROM, but I don't know if any titles used it.

But almost every game relied on some kind of special graphics technique to wow the player, and that usually meant at least one neato routine hand-optimized in assembly. Drawing a sprite to the Apple's frame buffer was actually much more complex than blasting RGB values like we do today.


Not just text adventures, the original version of Ultima I was written in Applesoft BASIC too.


Thanks for that link. I never knew Marble Madness was written in C!


Aztec-C's performance on the II at least was terrible. A colleague explored it for a project and gave up - the program ended up being developed in GraFORTH.

Very fast.



I never did assembly on those old machines, just BASIC and Logo in elementary school, and some Turbo C by the time we had a 386.

I had heard of assembly and thought it was inherently "scary" and obtuse. But this PoP code is pretty easy to follow, and I probably should have taken the plunge way earlier.

Neat.


I recently thought about how I started programming and to my dismay I probably held myself back by 6 years or so by lack of confidence:

1. not having the confidence to talk to the 3 or 4 older kids at school who clearly knew about this stuff. 16 & 17-year olds were terrifying to my 10-year-old self. They of course graduated secondary school soon after, so there was a small window and I missed it.

2. I really wish I hadn't believed any adults claiming this stuff was "hard" or "scary". None of them did any real programming, so how would they know? I should have just pestered my parents to find me an x86 instruction and architecture reference - I'm sure I could have worked everything out from there, after all I had enough spare time. I started with BASICA on an 8088 and eventually was given a 486 after my parents got fed up with me hogging their computer; alas, it took years before I picked up C & C++ and assembly language shortly after. As a 10-year old in rural Austria, my possibilities for obtaining this kind of information myself were pretty limited, and everyone (parents, teachers) was constantly encouraging me to focus on science (physics) instead of programming.

Still, I shouldn't harp on too much about #2. I was into electronics before I heard about programming and was obsessed with wanting to build my own computer, and tried to get hold of information on doing so, only to be told it was "impossible". (a 6502 plus some manuals would almost certainly have done the trick, and in 1993 couldn't have been that expensive - but I guess by that point the "kit" computers were long dead) So clearly being more assertive about wanting programming information would not have helped much either.

I hope I don't fuck this part up if I have kids of my own.


I hope I don't fuck this part up if I have kids of my own.

The hard part is the "thing to learn" may not be computers and programming, it may be something entirely new. That's why your elders seem like they were out of touch- tech was so new and all. It looks like a great choice from 2012, but from 1990 it was more of an unknown, and there will be similar developments in the future in other fields that challenge new parents to allow their kids to explore fledgeling prospects.


Hmm, not sure I believe that. I think anyone with any foresight in 1990 realized that computing was going to change the world. They may not have realized the scale, or the details of it though. I think those of us who's parents acted on that are really blessed with the jumpart we got on the world to come


Yeah, that's my takeaway, too. Offer up a variety of things to try, but encourage whatever they happen to be passionate about, not what I'm passionate about. (and know when I'm out of my depth)


See also this (http://news.ycombinator.com/item?id=961713) discussion about the source code documentation.


I didn't know it was all written in Assembly. Is there any documentation to help with reading the code?

Thanks for the code btw. PoP is a landmark in the history of computer games.


Of course, you need only go to the horse's mouth. [1]

It's been posted before but Jordan, the creator of both Karateka and Prince of Persia, has a wonderful series of journals documenting his travails with video games and the movie industry. [2] As part of this he has a detailed description of his trek out to California and a lot of details on technical obstacles that make you thankful to live in the second decade of the third millennium.

[1] http://jordanmechner.com/wp-content/uploads/1989/10/popsourc...

[2] http://jordanmechner.com/


Cue DCPU-16 port in 3..2..


Wow, and the day after the 35th anniversary of the first public showing of the Apple II: http://techland.time.com/2012/04/16/apple-ii-forever-a-35th-...


No license or copyright stated. Doh!

(Which technically means we don't have permission to do anything with the source at all, though I doubt that's what Jordan intended.)


You can trade patches. Isn't that how Linux got started, as patches to Minix?


No, it started as a Minix clone by Linus.


Nope, it was initially a terminal emulator, which he used to access the large UNIX servers of the university. Initial development was done on Minix.


I wonder, how was this ported to PC? Completely rewritten from scratch? Or was there some AppleII -> x86 translator?


Effectively, yes. It sounds like it was basically a rewrite. The book of journals for the game development that lots of other folks have led to talked about the process of finding a programmer to do the work in a fair bit of detail. Like everyone else has said, the journals are well worth reading. Best money I've spent on an e-book this year for sure.


In those days it would have been almost certainly rewritten. Although it would maintain a lot of similarities.


Loved that game when I was a kid.

love the sound code. Having to write your own "tone" routines to tweak a sound out of the speaker...


I love the 6502. One day I'll finally get to learn VHDL and build myself a 64-bit 6564. x86 is no fun.


You can use the OpenCore 6502 as a start. Cut-and-paste!

http://opencores.org/project,6502vhdl


wait! no "megahit" in source? this can't be real...


Maybe that cheat was only in the PC version?

I wonder how the PC version (which I've played and fondly remember) and Apple 2 version differ.


Jordan, regarding the PC version, 01/26/1990:

This is going to be the definitive version of Prince of Persia. With VGA and a sound card, on a fast machine, it'll blow the Apple away. (In contrast, none of the Karateka conversions was as good as the Apple original)


Anyone got any good Apple Assembly manuals? :-)


Depends. The CPU is "just" a 6502, so there's plenty:

* http://www.6502.org/

* Most of the machine code books here: http://www.bombjack.org/commodore/books-generic.htm

As for Apple-II specific details (graphics chipset etc.) someone else will need to chip in - never even saw an Apple-II during my childhood, Norway like much of Europe was Commodore dominated.


This made me laugh. The words "Apple II" and "graphics chipset" don't belong in the same sentence! The Apple II graphics were a fantastic, and fantastically weird, low-hardware hack.

http://en.wikipedia.org/wiki/Apple_II_graphics#Video_output_...


That does sound rather strange. But fascinating...

Stuff like that seems like it might explain some of the mutual disdain that Chuck Peddle and Woz seems to have ended up with after their early encounters (when Peddle was on his 6502 "sales tours"; though maybe interviews and books have exaggerated it).

I can totally see this being the type of hack that would excite someone like Woz to pull off but that would make Peddle's straight laced inner formal engineer rage... Combine Commodore / MOS engineerings early problems getting a decent color graphics chip together but cultural refusal to go for something more hacky (the did plenty hacky stuff but only when Tramiel put jobs on the line) to get out the door quicker, with plenty of blame being put allocated to Peddle on a regular basis, and I can see lots of ego getting caught up in it..


I think you will be interested in the design of the Macintosh video/audio hardware, too, then; http://www.folklore.org/StoryView.py?story=Sound_By_Monday.t... gives some details.

IIRC, things were even better. There were two (740 byte, IIRC) buffers from which samples were taken at every horizontal refresh.

The sound driver used one to get samples to send to the speaker; the disk driver used the other to control the rotation speed of the disk drive (using pulse-width modulation).


Apple II assembly coder here, and the book I used is in your second link, "Using 6502 Assembly Language" by Randy Hyde. Mine had your link's cover, not the cover shown on Amazon:

http://www.bombjack.org/commodore/books/pdf/A2_Hyde_6502_Asm...

See also http://www.callapple.org/cat/ap0010.htm and http://www.amazon.com/Using-6502-assembly-language-program/d...

For Apple II details, supplemented that with a number of patterns books like Beagle Bros Big Tip Book: http://beagle.applearchives.com/books/big_tip_book_ocrpdf.zi...


That second link is a treasure trove of 80s-era computer books. I'm surprised at how many of those I owned and/or read.


If you go up a bit it actually has most English language Amiga and Commodore related magazines as well...


I had no idea it had been written in assembly. I am amazed. The awesomeness of this thread is unprecedented.


To give you another example: Transport Tycoon was also written in assembly.


Almost all of Rollercoaster Tycoon as well. Blew my mind when I found out.


Can't they publish the source code for those as well? I'm sure many of the original developers of early games that are now abandonware still have a backup of the source code lying around.


I think this part of the README is relevant:

  Thanks to Jason Scott and Tony Diaz for successfully   
  extracting the source code from a 22-year-old 3.5" floppy 
  disk archive, a task that took most of a long day and 
  night, and would have taken much longer if not for Tony's 
  incredible expertise, perseverence, and well-maintained 
  collection of vintage Apple hardware.
From this we learn that the code, today, only existed in an out-dated medium, readable on vintage hardware, and even meeting those prerequisites, still involved a fair amount of human expertise and time to extract.

I'm sure they could, but unless they also have a book to promote, it's probably not worth their time. Well, I think it would be, simply as a contribution to the history/record of the era... but they likely aren't going to recoup the time or effort other than in goodwill. (I also suspect there's probably legal, copyright, and ownership issues involved as well.)


I can't find the Makefile :D


Now just wait 10 minutes to get a port to DCPU-16.


[deleted]


It's not like there was a choice -- at that time, you had to do a lot in a small space, with very little in the way of computational power. If you wanted to write a game, you had to do so in assembly. Mind you, games were much simpler then.

And sure, x86 might be easier to understand, but it's not the original PoP. That's what this is about, not just the code.


Actually ..

I happened to be in the office of someone who was doing language translation on the PC version of PoP at the time; He had a copy of the source code for that, and it was C.

That was twenty years ago. I only got a glimpse of one screenful of code, but I remember feeling special for that nonetheless :)


x86 might be easier to understand for someone who happens to know x86, but frankly for someone who doesn't have previous exposure to assembly, I'd be willing to bet it'd be far quicker to pick up the 6502...


Really depends on what you mean by x86. If you're talking 16-bit real mode code, it's pretty straightforward -- C in assembly form, largely. If you're talking pmode code, modern asm, I tend to agree. I hope this rekindles an interest in 6502 asm, though!


I'm an old C64 and Amiga guy - the first time I saw x86 code I was horrified. 16-bit real mode or not, when I finally gave up on my dying Amiga was when I stopped writing assembly as well - x86 assembly was where I drew the line. I didn't want to make that transition.

In other words, I don't agree that 16-bit real mode is much better. Now, mdern x86_64 code is starting to get tolerable, with more orthogonal register, for example. But I'd rather chew off my own hand than be forced to write any large amount of 16 or 32 bit x86 assembly....

Then again, I'm horribly opinionated about programming language syntax...


Amigaaaaaaaaaaaaaaaaaaaaaaaaaaa!


To those that didn't get the reference: http://www.youtube.com/watch?v=GMATCbC0g3I :)


European demoscene is virtually unknown for the rest of the world :(


The x86 is actually fairly straightforward, as long as you don't try messing around with A20-gates, GDTs and legacy modes (i.e. not staying in protected/long mode the OS has given you). It's only when you try to build things such as bootloaders that x86 starts getting nasty. Backwards-compatibility can be quite evil.


It's not that it's complicated. Few assembly languages manages to be all that complicated, at least if you avoid some of the more bizarre addressing modes ...

It's that it's horribly ugly and full of warts.

The biggest issue I have with x86 is not even trying to make things orthogonal (until x86_64, which does a tolerable job cleaning up a lot of the mess).

Some of it could probably be improved simply by ditching the syntax, and renaming stuff and pretending a lot of the rest simply doesn't exist, but you'd be left with something that looks very different from a typical x86 assembly listing..

But some stuff you don't avoid unless you go 64 bit: The registers alone gives me gives me hives, starting with the naming convention, where the M68k for example is straight forward: D0 through D7 = data registers. A0- A7 = address registers. For a lot of things they can even be used entirely interchangeably.

No addressing parts of the registers with special names, or mumbo jumbo restrictions on what can be done with different registers (that was excusable when the 6502 was a viable competitor, but even that followed clear and simple rules (Arithmetic on the accumulator (A), indexing with the X and Y registers) and didn't layer complexity on top of complexity. Bank switching / segments? Nope, we don't clutter the CPU with junk like that. Either you use a memory address or IO lines (or, as it happens, on the 6510 in the C64, IO lines mapped to a memory address).

Maybe I'm just still sore the M68k lost the performance race and I "had to" get a PC.


(See also my response to gaius.)

As you noted, the x86_64 sorted out some of the mess.

Personally, I think a big issue is the whole backwards-compatibility thing. It causes all sorts of nastiness, and a complete overhaul of the architecture is impossible because everything depends on it! (Which is one of the reasons the IA-64 never really became a hit.)

I vote we design our own processors, and write a new kernel to boot. ;)


Right, but compare it to ARM, VAX, MIPS or even 68k. There are plenty of people who got assembly "right"; Intel isn't one of them. Not by a long shot.


Um... ARM got assembly "right" three or four separate times at last count (depends if you count thumb and thumb2 as distinct architectures). And I believe they now have three equally "right" (and mutually incompatible) floating point architectures.

Everything has warts (and x86 more than most). But don't pretend that ARM is clean. Or VAX (integer polynomial instructions? Non-IEEE floating point what now?). Or MIPS (A branch delay what? Multiply outputs to a separate register?). Or even 68k (let me puke garbage on your stack, I'll just tell you how much room you need).


As a matter of fact, I agree. The fact that x86 won the consumer market is, IMHO, very much one of those clever-marketing-and-quick-standardization-cases.


So does it use any unofficial opcodes for performance?

(IIRC, the 6502 decoded instructions by bitmasks; say bit 7 meant "load" and bit 6 meant "move" or some such thing. So you could trigger combination instructions that'd still execute in 3 cycles but perform the work of two instructions that'd normally take 6. This might have been 6510-only, but I don't think it was.)


"How MOS 6502 Illegal Opcodes really work": http://www.pagetable.com/?p=39


Sadly, the 65C02 used on the //c and //e enhanced converted those to NOPs :-(

I actually had to rewrite some code because of that. I remember the comments in the source code were less than kind towards the engineers responsible. I may even have the listings somewhere.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: