![]() |
![]() |
Sega Megadrive Assembly Programming BasicsCopyright, Lewis Bassett, December 2005
In this chapter we're going to take a look at the insides of a Megadrive, and what each part does. I'll also explain about Binary and Hexadecimal, the two main number systems used in programming. The Megadrive, essentially, is a computer. It consists of a processor, memory, various input devices and many other things. Just like a computer, it reads programs, and displays the output onto a screen (ie, the TV).
Remember, a game cartrige is simply a Printed Circuit Board with a chip on, inside a plastic case with a sticker on. The chip contains our ROM program. Many cartridges also have other things inside, like save memory and extra processors. These things are quite advanced and aren't covered in this document. When we switch the Megadrive on, the first thing it does is run the BIOS, also known as the Megadrive Operating System. This program is also stored on a ROM chip, inside the actual Megadrive itself. It's job is to check the ROM program on our cartridge, and make sure it's a licienced Sega program. This is to stop pirates like us making dodgy illegal code. The BIOS also does other things too.
When the BIOS has finished checking the ROM, the Megadrive copies the cartridge ROM into memory, and it is immediatly run.
A processor is a very complicated circuit. It's job is to take instructions from the ROM program inside the cartridge, and execute them. Some people refer to the processor as being the brain of the machine. Processors are also often called 'CPUs' or 'architectures'. There are many different models of processors, all of which use different instructions and are used differently. The Megadrive uses the Motorola 68000 (also known as the 68k, M68k, etc), which in my opinion is one of the best processors around. The 68k is the main processor. It executes the actual ROM program, and it communicates with the other hardware.
Memory is the place where data is stored. It consists of a series of locations (called cells) which are used to store information which is accessed later. Physically, memory is made up of little chips. There are two main types of memory used by the Megadrive: RAM and ROM. RAM (Random Access Memory) is the temporary storage used by the processor and other hardware. RAM is volatile, which means that if we were to cut off the electricity, it would loose all it's information. RAM can be accessed randomly. This means that the processor (and other hardware) can read or write to any location, anywhere and anytime. ROM (Read Only Memory) is where programs (ie games, etc) are stored safely. ROM cannot be re-written or deleted. The Megadrive Operating System is stored on a ROM chip, and all games are stored on a ROM chip (inside the cartriridge) too. ROM is non volatile, which means we can cut off the power, chuck it off a cliff or eat it and it will still hold the original information stored on it. Remember that memory is a collection of locations, also called cells, arranged in sequence. Each cell can hold one byte of information, that can be read anywhere. Each cell has a unique address that refers to the data stored in it. For example, address '1' refers to the data held in the second cell, since memory addresses always start from zero. Address 255 refers to the data held in the two hundred and sixty sixth cell. In the Megadrive, all the different parts of the memory are arranged into a logical range, called a memory map. This memory map is simply an address range, starting at 0 and finishing at 16777215, which contains the ROM, the main RAM and other hardware components which are explained later. The ROM (which contains our program) is located at address 0, and fishishes at address 4194303. The Megarive's RAM is located at address 16711680 to address 16777215, and is 65536 cells big (which makes it 64 Kilobytes, since each cells is a byte, and each kilobyte is 1024 bytes. I'll explain about the addresses alot more later.
The Megadrive uses three different input devices. The first two are control pads, one for player 1, another for player 2. Each control pad has a 4 directional button, a 'start' button, and 'a', 'b' and 'c' buttons. All of them work by sending their status to an address in RAM, where it can be read by the programmer anytime. The Megadrive also has a third input, the extension port. This works in excactly the same way as the control pads, only, most developers used it for other things, such as transfering data from other computers, or communication.
The VDP (Video Display Processor) is in charge of all things being sent to the TV, including sound. It works by using the main Megadrive RAM to communicate with the main program, and by using it's own memory to generate pictures to send to the TV. Unlike the M68000 which executes our program, the VDP does not really run instructions that we give it. Instead we send it data and simple commands, which it uses to work independently.
The Megadrive also has other hardware, including another processor, which is used to generate sound signals (which are then passed to the VDP to be sent to the TV). This document doesn't cover sound, so I won't explain any of this hardware.
As you know, the Megadrive is a digital machine that uses encoded signals to represent numbers. To keep costs low, and hardware simpler, and digital signal can have two states: 'on' or 'off'. So how exactly to we store numbers, if we can only use two signals? For this we use binary. Binary is a base two number system. This means that a digit can have any one of two values (0 or 1). Our number system, decimal, is a base 10 number system. This means any digit can have one of 10 values (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). What happens if we want to go any higher than 9 using our decimal number system? We'll simply reset our 9 back to zero, and add another column to the left, which now represents tens (10^1) instead of ones (10^0). So, we'll count up and up, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, whoops, we don't have any more digits. It's okay, let's add another column and start again: 10. '1' represents one ten, and '0' represents zero ones. We do exactly the same when we count in Binary. So, 0, 1, oops, we're all out of numbers! Let's add another column to the left which represents twos (2^1) and set out old column back to zero: 10. '1' represents one two, and zero represents zero ones. We then do exactly the same once to 'twos' collumn reaches '1'. We add another column, but this time this column represents fours (which is 2^2). When we run out of digits to use again, we add another column which has the value of eight (2^3). So, what does the Binary number '0100111' represent? Well, you could use the Windows XP calculator and convert it, but we'll convert it bellow. Starting from right to left, we have '1'. One is on the first column which has the value of one, so we have '1' one. The next column has the value of two, and it is set as '1', which means we also have '1' two. The next column represents fours, and it is also set to '1', so we have '1' four. The next column along to the left represents eights, but it is set as '0', which means we have '0' eights. The next column represents sixteens, but is also set to '0'. The next column along represents thirty twos, and is set to '1', so we have '1' thirty twos. The last column, to the far left, represents sixty fours, but is set to '0'. Now to get the value of this number, we just add along the values of all the columns which have '1' in them. That gives us (from right to left): 1 + 2 + 4 + 32 = 39. To convert a decimal to binary, we simply find the largest power of two (1, 2, 4, 8, 16, 32, 64, etc) that can fit into it and set it's column to '1', and then find the next biggest. Let's convert 92 into binary. First of all, the biggest power of two number that fits into 92 is 64, so we set the 64 column to '1', so far our number is : '1000000'. Next we take 64 from 92, giving us 28. The biggest power of two number that fits is 16, so we set the 16 column to '1', but the 32 one (which we skipped because it wouldn't fit into out number) to '0'. Our number so far is: '1010000'. Next we subtract 16, which gives us 12. The biggest power of two number which fits is '8', so we set the 8 column to '1': '1011000. Now we subtract 8, which gives us 4. The biggest power of four number which fits if 4, so we set the 4 column to '1': '1011100'. If we subtract 4 now, we have zero. We just set the remaining two columns to '0' and our number is now converted: '1011100'. Whenever we use Binary numbers, we always prefix them with a'%' to show that we're using Binary, since '10' can also be interpreted as 10, istead of 2. So our converted number is written as: '%1011100'.
Hexademical, what the hell is this? Hexadecimal is a base 16 number system. It works exactly like our decimal number system, but it counts up to 15, instead of 9, using some letters: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. When we're out of digits, we simple add another column as usual, which would have the value of the previous column, multiplied by itself 16 times (ie, x^16). So '10' in hex represents 16, not 10. Hex numbers are always prefixed with a '$'. So 16 in hexadecimal is written as: '$10'. So why use hexadecimal? Our decimal number system seems to work fine enough doesn't it? Well, the problem with decimal is, it's a base 10 system, which isn't a power of 2. Hexadecimal is a base 16 system, which is (2^4). This is actually very usefull. Say we have the binary number '01011111', which is made up of two parts: '0101' and '1111'. Let's say each part represents a pixel on the screen, which the programmer needs to be able to see as they write their program. Because hexadecimal (16) used 4 binary digits (2) for each hex degit, we can use a seperate hex digit to represent each pixel on the screen (%0101 and %1111 become $5 and $F, or $5f). In our decimal system, %01011111 becomes 95 instead of $5f. But what if we want to change just one pixel and keep the other the same. If the two pixels are represented in hex, we just change the left pixel ($5) to say $9. The right pixel stays exactly the same. In hex it becomes $9f, but in decimal it becomes 159. Completely different from out first number 95! However, the hex number only changes a little.
A bit is one binary digit. This is the smallest unit that computer data can have. A byte is made up of eight binary digits. A byte is the size of one cell in memory. When working with bytes, we call 4 bits a nybble. A byte is also made up from two hex digits. A word is made up of 16 bits. On the front of the Megadrive, it says '16-bit'. This means that each instruction executed by the processor at one time is 16 bits in size, or four hexadecimal digits. A long word is 32 bits, or two words. This is the largest size of data that the processor can work with.
ASCII is short for American Standard Code for Information Interchange. It is based on old telegraph codes, and it used to represent letters, numbers and formatting characters used in language. In ASCII, the letter 'A' is represented by $41. Check out This Page for more information on ASCII codes. Whenever we work with ASCII characters, we always put single quotes (') around the string of letters to mark it as an ASCII string. The assembler converts these to numbers for us.
|