Hello everyone,
Ok, time for some schooling and I mean at the graduate level! I was lucky enough to come across someone who is and has had computer experience with the apple and programming in Assembly! That's right boys and girls, Assembly language is Machine Language and this is how the tile graphics were programmed in Ultima 1. It would seem that Richard programmed all of the none-essential code in Applesoft basic, such as the menu system, combat, etc; plus the town and castle activities. The bulk of the map graphics were done in Assembly! I'm becoming more informed of just how important it is to understand Assembly language to program anything fast on the Apple IIe!
First let me explain how this all came about... I was starting to go in a wrong direction with regard to the tile graphics, unbeknownst to me! Due to this path I was producing more and more questions for myself that didn't seem to have any answers. So, off to the web I went looking for someone who knew the answers and boy was that the best thing I could have ever done.
I came across an interesting website based on one of my questions, the website is:
When you hit the main website, go to the web link under Elizabeth Daggert's name!
Check it out!!
This woman actually received a letter from the man himself, "Richard Garriott"! Incredible!! Take a look at it on her website! This is a part of history!!!
But I digress, she was gracious enough to respond to my initial questions and give me a little background. When I bombarded her with more questions, she was very patient and understanding, giving me as much detail as she could remember; this is 20 year old info after all!
She is very knowledgeable in programming and computers with emphasis on programming.
What follows is a back and forth, question and answers session between Beth and myself. Please read it all because IT IS GOLD!
Hello,
I'm currently working on a project to revisit the Ultima 1 game and try to program the entire game again from scratch using my apple IIe computer.
I noticed you have had experience with Richard and a game programmed similar to the Ultima game.
How did you do this? How did you program the way the tiles move so smooth and fast?
Do you have any code for the apple I could take a look at?
I am stuck and I can't seem to find any information on how this was done.
Looking for help on how to program the way the map tiles moved vertical and horizontal fast and smooth.
Thanks
Joe
Joe,
Hi there! Thanks for your interest. That’s a good challenge you’ve set yourself.
Well, I’d have to dig around for the code myself at this point – I’m sure I’ve got a bunch but it would take some effort on my part to extract it and get it to you.
I don’t know how deep you’re into this problem, so forgive me if I spell out anything you already know.
· You need to write it in assembly. There’s no other way for it to be fast enough.
· You will be writing directly to the video memory.
· You need to be very aware of what bytes cause which colors to appear on screen. As I recall every byte made 7 possible pixels in a row, though in reality that was less based on whether you were on green/purple or blue/orange columns.
· Tiles are one byte wide and 8 bytes high. This gives about 7x8 pixel tiles, 8 bytes, written vertically into video memory at the correct tile location. I’m trying to remember if I made bigger tiles (e.g. 14x14 or somesuch) but as I recall I settled on the 7x8 thing.
· You will store each tile in non-video memory as a “shape”. So, let’s say “0” is water, “1” is land, “2” is trees, “3” is mountains, etc. You then build a [ X ][ Y ] world map of your tiles, like so:
0 1 0 3 0 0
1 1 0 2 1 0
1 0 0 3 3 0
0 0 0 1 1 1
0 0 1 0 0 0 …etc
· You then know the address of each [ x ][ y ] tile in absolute video memory. On the video update, you copy from the in-system-memory 8 bytes to the relevant tile-display address in video memory.
· You should wait for the VBI (Vertical Blank Interval) to update video memory. I forget how to do that on the Apple II, but basically you want to only update video memory when the video raster scanner is moving instead of drawing. There’s a memory address you can watch for that. This will insure that your video updates are “smooth” instead of “tearing”.
· When the player moves, you update the master grid by introducing a new row or column on one side of the grid while removing the old one from the other. Then redraw.
At one point I built tools for dumping the byte-codes of the shapes as well as building out the maps. A “tile editor” and a “map editor”. You may want to do the same – and it may well be easier to code those in a friendly language other than 6502 assembly and then simply copy your binary data to the Apple for actual testing.
Best of luck, I hope that’s some helpful starting info!
Beth
Hello Beth,
That is probably the most in-depth amount of information regarding the Ultima Tile Graphics subject I've been able to find anywhere on the internet!! I'm totally amazed that no one has writing a tutorial on how Ultima 1 tile graphics were programmed and executed. It is as if it's a mystery or secret that no one ever found out how to do or no one knows how to program. I just can't believe that for a game that is almost 30 years old, the process of showing how to write this type of game is still a mystery! Truly amazing!
I hope to change all that!!
Thanks!!!
First, let me give you some info to see if we are still on the same page.
1. I read that Richard Garriott programmed the entire Ultima 1 thru 3 games in Applesoft basic and machine language. I need to be able to follow this format. He didn't use Assembly so I need to figure out how to do it in these two formats.
[Beth] – okay. Assembly is “machine language”. It was 6502 machine code. Assembly was the only way to make anything fast enough graphically to have a game on the Apple II. Basic is really, really, really slow and its uses are very limited.
Here’s what you’re going to need:
1. Get yourself a 6502 chart. You can learn every instruction, I still have a poster on the wall that has them all. There aren’t that many. Beagle Brothers had an excellent chart at one point…
2. here it is: http://beagle.applearchives.com/the_posters/
Also, check out the links on that page, there might be some other good guides.
Also, check out the links on that page, there might be some other good guides.
2. You need to familiarize yourself with a “Memory Map” of the Apple II. That will answer many of your questions.
The reason this is important is so that you understand where to put your program in memory, where the graphics memory is, etc.
3. Here’s the Apple II RedBook, which is a good resource on a variety of topics:
4. Get yourself an Assembler. I preferred a program called “Merlin”. I didn’t dig too deeply but here’s a site where somebody is talking about using it in 2008, so it’s got to be out there, looks like there’s a bunch more resources at this site as well:
The only reason you use Basic is for things that don’t need to be fast. I got to where I did everything in 6502. At the very least, your graphics MUST be done in Assembly.
3. I've done some test example with 2-dimension arrays to layout the 200 "shapes" /graphic tiles but as you said, this is incredibly slow using basic. You actually see each tiles get laid down on the screen one by one using a loop! Bad!
[Beth] – I remember starting that way as well. Yes, you can’t do anything fast in basic. It’s good for learning, but don’t bother for real.
5. So now I'm at a cross road, I have all these methods of creating tiles/shapes and character fonts that can replace ASCII text characters but I don't know how to make them move across the screen all as one!
[Beth] – Okay, well, that was what I was trying to get at before. So, here’s your display on-screen array:
1 0 1
1 2 3
1 0 4
Now the character steps left. You want to slide the array one column left and add a new column to the right, while leaving the character in the center of the screen. Your display array now looks like this:
0 1 1
2 3 1
0 4 0
That’s all there is to it. You just change every single tile on the screen as the character moves and it gives the illusion of the world moving under the center player.
Your explanation makes sense but I'm still learning how to program in both Applesoft basic and machine language.
How do you assign each tile in absolute video memory? Can you do this using Poke commands?
[Beth] – The links I gave you above should get you started and I bet there’s lots of on-line forums to go to from there as well. Let me try to lay down some concepts for you:
1. Poke and Peek commands literally put values into a particular address in memory (poke) and read from a particular address in memory (peek). On the 64k Apple ][ you have all the memory just sitting in front of you, like a big array. It doesn’t go anywhere. Every bit in memory has a fixed address. You can poke and peek any address you want. So, looking at the memory map you can see where the graphics are drawn from. Literally, at those addresses, the bits in memory is what is displayed on screen. So, to get the idea you could Poke the addresses in the video address space with values and see pixels change on the screen. Make sense?
2. Now, in machine code (6502 Assembly) you are doing the same thing…but it’s easier to understand because your code exists at a literal address in memory. Every 6502 instruction (like a Poke or a Peek in basic) is a 8-bit “op code”. It has an address. It’s cool, because you can literally see every instruction you make take a slot in memory! As your machine code executes, it simply advances from one memory position to the next one, executing each instruction you’ve put in each byte. Can’t get simpler! And using those instructions, all you really do is move memory, add values and the like. So if you write a few instructions in 6502 to change a value in the video memory address range…bingo! You’ve just put graphics on the screen.
I was thinking that you can put all the tiles number representations such as the 0 for water and 1 for trees into a data base listing. Then you use a DIM array and read all the values into memory but where would they go?
I’ve heard about VBI (Vertical Blank Interval) to update video memory but I don’t know anything about how this works. I can’t remember where I read this info but it sound familiar.
If you can find any games you created that are like the Ultima games or any code or programs like the ones you mentioned, it would be greatly appreciated!!!
I don’t want to take time away from anything you are working on but any help you can give would make things a lot easier. I really want to post everything I find out and come up with on a website so everyone can use it. I want to make this all available to others so they can make their own games on the apple II computer using this info.
[Beth] – I think that’s great of you! I really suggest you check out some of the links and online communities/resources out there, though, I bet there’s lots of help to be had. I hope I was able to give you some concepts and applications you can use to start from.
[Joe] - How is this process done where you copy the 8 bytes form in-system memory to the relevant tile-display address in video memory? I know that you can use monitor to input the byte information into a specific memory address, it this what you are taking about?
[Beth] - As I mentioned in the last e-mail, you use 6502 assembly and know where the code is via a memory map. While you can do things using the monitor, that’s seriously a pain. Use a nice assembler, like Merlin. Then you can write in Op Codes. Ideally, find yourself a little program in 6502 assembly so you can see how it’s done!
Basically, you’re going to want to store each of your tile shapes at a fixed address in a section of memory that you know is fixed. That will be your data memory. You know that tile #1 (trees) is at address $1000 (just making this up right now). You know that the video map of the players current position is like this:
1 0 1 2
0 1 1 2
1 0 0 1
So you translate that to video addresses (remember I’m making this up, substitute correct video memory addresses appropriately)
$8000 $8008 $8010 $8018
$8100 $8108 $8110 $8118
$8200 $8208 $8210 $8218
And then you’ll copy the 8 bytes from $1000 to $8000, $8010, $8108, $8110, etc. It’s a bit trickier than that, since you’re going to be copying vertically down the tile, but you can setup a nice loop to do it for you. I suggest you figure out where each horizontal row is in video memory and get each of those addresses. Then you can see how to copy memory from one place to where you want it in video memory, for each horizontal row. It should quickly become clear how to map those rows into addresses for tiles. That’s probably an ideal first-6502 program for you to try to write!
From Beth: You should wait for the VBI (Vertical Blank Interval) to update video memory. I forget how to do that on the Apple II, but basically you want to only update video memory when the video raster scanner is moving instead of drawing. There’s a memory address you can watch for that. This will insure that your video updates are “smooth” instead of “tearing”.
From Joe: first, what is tearing? Is this the aftereffect of what the screen refresh does to the shapes on the screen? How does VBI have any affect when the player can move back and forth really fast by hitting the lift/right arrow keys? I've done this and the tiles still move really smooth! Amazing!
[Beth]- Okay, here’s where I get all the old graphics hardware mixed up. I don’t think the Apple II had page-flipping, so you’re limited to just using the VBI refresh for smooth updates. To understand how this all works, you have to think in terms of CRT monitors. Remember those? Not flat-screens, big old glass tube monitors. They had a “gun” in them that painted the video screen with the colors. This was done mechanically and it took time to refresh the entire screen, writing each row from top to bottom. When the hardware was done filling the video screen, it had to move the “gun” back to the beginning of the page. That also took time. During that time, it wouldn’t be drawing. That “non-drawing” interval is known as the “vertical blank”.
The values being written to the screen are LITERALLY the values in the video memory section of the Apple II. So “tearing” is what happens if you’re writing memory to the video memory at the exact moment the video “gun” is reading to display those bytes on the screen. You end up with half the screen from one frame and half from the other, and it looks like the screen is tearing into two or more sections. Not a good effect for gameplay. So you really want to wait for the video to stop drawing, update all the memory, then let it draw the memory before you write a new frame to it.
From Beth: When the player moves, you update the master grid by introducing a new row or column on one side of the grid while removing the old one from the other. Then redraw.
From Joe: How is this done? Are you saying that you use the memory address to input the new row but how do you move all the other tiles across the screen as one? How does this shift happen? It's as if all the shapes on the screen are attached as one entire images and it moves as one!
[Beth]- Yes – you refill all of the video memory addresses at the same time, for each new frame.
[Beth]- Joseph,
Glad I could help. Sure, feel free to mention and/or link me, that’d be great. I need to bring my website into the modern era, I haven’t touched anything there in years. Maybe getting linked will motivate me to switch it up. J
And I’d say, yeah – without an assembler, you’re not going to get very far. It’s really the only way to craft assembly code.
Are you actually working on an Apple ][ or on an emulator? The emulators I’ve used just let you load “disc images” as though they were actual floppies. If you’re trying to get something onto a really floppy to a real Apple – hah, wow – that’s a bigger pain. You can do it via an Apple 2gs, because those would read/write Apple ][ discs and can connect via an Appletalk network. So, the process I’ve used is to copy onto a floppy and then from a 2gs copy it to a Mac on the network, then from that Mac copy it to a USB stick or to a network-based PC. Presumably that process works in reverse as well.
I bet the files you link to are most easily used on emulators, simply because they’re already on the web. But the bytecode is all the same, so if you can transfer them to physical floppies anything you find online should work just fine on a physical Apple ][. The link you sent has “disk images”, so I’m guessing you should be able to extract those into a file which is just loaded by an emulator as though it were a physical disk.
I think I found you a copy of Merlin here (in case yours doesn’t work):
And here’s a motherlode of stuff:
And here’s another handly reference set of links:
Anything by “Beagle Bros” or just keyword “Beagle” is worth your time to check out 110%. Those guys were the original hackers and nearly everybody who learned to code the Apple ][ owes them big time. Their utilities and charts are golden.
Good luck, I’ll check out your blog and such!
Beth
-------------------
So there you have it, a wealth of information to help all of us to get back on track and in the right direction. I will be researching Assembler programs to try and get my hands on one. Once I get one I will be posting new information about examples of code and progress on Ultima 1. All this new information is going to take a while to digest and it may be a little while till I post some significant code or progress with my Ultima 1 program. Stay tuned though, I will always have new stuff to post with regards to book reviews and program reviews, etc…
Let’s all thank Beth for her incredible help and soon we can get a major portion of the Ultima 1 program going!!!!
Remember, take a look at her website!
Talk to you soon,
Joe
No comments:
Post a Comment