-
Content Count
1,533 -
Joined
-
Last visited
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by Robert M
-
Thanks for the positive responses. I ordered some switches from Mouser Electronics last night. I am hoping that some of them will work for my improved second version. It will be several days before the new switches arrive, so I probably won't have a version 2 for a couple weeks. As for selling the modified controllers, If I think the final design is worthy of selling I will consider doing so. Right now its too much of a hack job and I wouldn't trust them to keep working for the long term. At the least I will post detailed instructions on how to put one together. Cheers!
-
Bah, just use an NES controller modified for atari. I already beat it, there are no special controllers required. Bah! I have never been good with thumb pads. What's really interesting to me is that there is no reason Atari couldn't have put 3 buttons on the driving controller in the first place. There are enough free signal lines for 2 more buttons on a single joystick cord. It could have made for a truly awesome driving controller: Accel, Brake, and shift. Cheers!
-
Hi, I have been dabbling with creating a custom controller for Thrust. I like the driving controller for rotation, but I could never get comfortable with the footpedals for the shields and thrust. So I decided to try and add 2 buttons to a driving controller so that all the needed buttons are on one controller. After several false starts and trial and error, I have finally suceeded. In this first version, I retained the original fire button on the driving controller, and it is still used for firing. I hold the controller in my right hand, and turn the knob with my left. My thumb is on the button where the cable used to come out of the driving controller. That button is for thrusting. The other button rests under my pinky finger and it activates the shields. In play, I like it. My pinky gets tired though. Plus with all the changes to the casing the fire button can twist a tiny bit and bind up a little bit. It doesn't get stuck it just bounces back slower than normal. I have learned alot putting this one together, and I have some ideas for improvements for version 2. Once I get a version I like, I will post instructions on how to make one. Cheers!
-
I have been playing this title quite a bit lately trying to get a handle on it. I don't think I would give it an A mainly for the reason that there is no clear indication how far down your ship can move. I lose lots of ships because I try to fly downward out of the way only to bump into the invisible barrier at the bottom. TIPS: - Don't play with the mode where collisions with purple ships cause you to die. That's impossible because they move too fast. - Get past the shield as soon as possilble, and spend as much time as you can up by the Death Star: Reasons: - Each block of the death star is 20 points. - The more blocks you destroy the longer the DS takes to explode earning you more points (If you survive.) - There is no shield to bump into and die. - There are a number of audio cues in the game. Listen closely. When you hear certain noises it means events are about to happen. - The Green ships are where the big points are. Don't attack them head on! Your shot will pass through and you will crash. - Stay to the center of the screen to avoid getting whacked by ships entering the screen edge. Just dodge the DS shots and keep shooting the DS blocks to rack up points. - Keep moving! Enemies seem to shoot less often. - When you blow the DS, be sure you are ready to get out of the way. Hide on the bottom left or right, but not in the center or corners! Only a few slower fireballs will enter those 2 areas be ready to run to the other area when one comes your way. I always break 20000 pts using these tips and I have gotten over 30000 a couple times. Don't blow the 1st DS until you have at least 10000. Good-luck!
-
Please don't vote this the dumbest question ever!
Robert M replied to jenjoseph's topic in Atari 2600
You can use it with centipede, but you will have to use it in joystick mode. What that means is it will behave like a rolling joystick and not a trackball like in the arcade. Since you are a fan of centipede, it would probably be worth your time to pick one up and see if you like it better than a plain joystick. Sorry if I came off as very negative about Atari trackballs. I paid $40 for one when they first came out and I was disappointed when Atari provided zero games that supported true trackball mode. Cheers! -
Please don't vote this the dumbest question ever!
Robert M replied to jenjoseph's topic in Atari 2600
While it is true that there are rollerball controllers available for the 2600, there are no original titles that support it. The trackball requires special code to implement its proportional movement. Atari in their infinite wisdom, did not implement a coporate policy of supporting exotic controllers in as many titles as possible. Hence the lack of support for the light gun and the trackball. The trackball has a "joystick" mode which reduces motion to 8 directions like a joystick, but you have to keep rolling the ball to move. You also have to roll at top speed constantly, or the player will move along jerkily. There is a hack of missle command that supports the proportional mode of the track ball. http://www.atariage.com/store/product_info...&products_id=31 Maybe you can convince Thomas to make a similar hack for centipede. Cheers! -
So far I have beaten: Switchblade II Crystal Mines II (assuming its okay to have beaten all 180 levels over time. I have never sat down and tried to beat them all on one set of lives :wink: ) I am trying to beat: Toki (Stuck on level 5 boss) Dracula Cheers!
-
Assembly Language Programming - Lesson 6 - Binary Logic
Robert M replied to Robert M's topic in 2600 Programming For Newbies
If you are asking if the 13 in the PUZZLER is decimal, then yes. I am avoiding teaching Hexadecimal until we start using DASM. Please post your solution for the puzzler to the thread. It would be nice to see some different solutions presented. I find I learn this stuff the best by reading work from other people solving the same problem different ways. Cheers! -
Assembly Language Programming - Lesson 6 - Binary Logic
Robert M replied to Robert M's topic in 2600 Programming For Newbies
Ah, good question. 13 decimal = %00010011 in BCD (binary coded decimal) -AND- 13 decimal = %00001101 in binary number format -OR- 13 decimal = $13 in Hexadecimal notation of 13 decimal inBCD number format. -AND- 13 decimal = $0D in Hexadecimal notation of 13 decimal in binary number format I haven't covered hexadecimal notation yet, so other readers should ignore the second half of this reply for now. Did I answer your question? -
Lesson 6 - Binary Logic ====================== I know I promised to start discussing State Machines in Lesson 6, but now I see that I forgot to talk about binary logical functions. Since I just covered binary counting, and binary math; I think it would be best to push State Machines off to lesson 7 and cover binary logic now. Introduction: ------------- What is logic? I could spend days on that topic, so I need to focus on logic as it applied to programming computers. Recall our discussion of bits in Lesson 2. Each bit has one of two possible values 0 or 1. As the programmer you can apply any meaning you wish to each bit your program uses. A common use for bits is to indicate TRUE or FALSE. TRUE is usually represented by 1, and FALSE is represented by 0. Such an arrangement is called positive logic. You can also use negative logic, where TRUE is 0 and FALSE is 1. For this lesson I will confine the discussion to positive logic for all of the examples, since the instructions in the 650X microprocessors use positive logic. For this class we are interested in logic functions that we can perform between pairs of bits representing TRUE and FALSE. Some interesting things can be done with bits using just a few simple logical rules. Logic Functions: ---------------- There are four basic logical functions: AND, OR, XOR, NOT. You can also combine NOT with the other 3 to form 3 more functions: NAND, NOR, and XNOR. I will discuss each logical function in detail. ***************************** NOTE: For all the experienced programmers reviewing this material, I decided to exclude the logical bit-shift operations from this lesson. I will cover bit-shifting and rotations when I cover those instructions. ***************************** The best way to think about binary logical functions is as a special math operator akin to adding and subtracting as we covered in the previous lesson. For all the logical operations, except NOT, there are 2 arguments and a single result. So like addition we can write logical operations as A (oper) B = C, where (oper) is the symbol of the logical function to be performed on A and B resulting in C. Logical AND: ------------ The first function I will present is AND. The function AND is easy to understand. Given A and B, C is TRUE only if A and B are TRUE. Otherwise, C is FALSE. We can present the AND function as a truth table: A B | C ----- ----- | ----- FALSE FALSE | FALSE FALSE TRUE | FALSE TRUE FALSE | FALSE TRUE TRUE | TRUE As a programmer you will use AND to determine if multiple conditions are TRUE at the same time. For example: A = TRUE if the player is carrying the Blue Key. B = TRUE if the player is touching the Blue Door. C = TRUE if the player has the Blue key and is touching the blue door. If C is TRUE, then unlock the Blue Door and play sound effect. ***************** NOTE: ****************************** Above, is an example of what is called pseudocode. Its a list of instructions similar to what an actual program section will look like, but it is written in english rather than the programming language. I will be using psuedocode more and more in these lessons, and you need to get comfortable both reading and writing pseudo code as part of this class. Expect to see exercises where you will read and write pseudocode. ****************************************************** The symbol for AND is &. So, C = A AND B = A & B is the same thing. Logical OR: ----------- The next logical function is OR. Given A and B, C is TRUE if either A or B is TRUE, or both A and B are TRUE. Logical OR in an 'inclusive-OR', not an 'exclusive-OR' as represented by the XOR function to be discussed next. Here is the truth table for OR. A B | C ----- ----- | ----- FALSE FALSE | FALSE FALSE TRUE | TRUE TRUE FALSE | TRUE TRUE TRUE | TRUE The shorthand symbol for OR is '|'. So, C = A OR B = A | B, is equivalent. Logical XOR: ------------ XOR stands for exclusive OR. C is TRUE if either A or B is TRUE, but it is FALSE if A and B are both TRUE or both FALSE. Here is the truth table for XOR: A B | C ----- ----- | ----- FALSE FALSE | FALSE FALSE TRUE | TRUE TRUE FALSE | TRUE TRUE TRUE | FALSE The shorthand symbol for XOR is '^'. So, C = A XOR B = A ^ B is equivalent. Logical NOT: ------------ The function NOT is special in that it takes only 1 argument, not 2. It is akin to using the negative sign in arithmetic to make a number negative. C is the opposite state of the input A. So C is FALSE if A is TRUE. C is TRUE if A is FALSE. Here is the truth table for NOT: A | C ----- | ----- FALSE | TRUE TRUE | FALSE A common way to represent the function NOT is to place a bar over the input like this: _ A = NOT A Another way is to use a tilde like this: ~A = NOT A The second method is easier to implement in the ASCII text of this lesson, but the first method is easier to read (I think). I will try to use the bar notation in my lessons, but if it gets too annoying to type, I may start using the tilde. LOGICAL NAND, NOR, XNOR: ------------------------ The functions NAND, NOR, and XNOR are the logical opposites of AND, OR, and XOR. Its shorthand: A NAND B = NOT (A AND B) A NOR B = NOT (A OR B) A XNOR B = NOT (A XOR B) Here are the truth tables for NAND, NOR, and XNOR: NAND: A B | C ----- ----- | ----- FALSE FALSE | TRUE FALSE TRUE | TRUE TRUE FALSE | TRUE TRUE TRUE | FALSE NOR: A B | C ----- ----- | ----- FALSE FALSE | TRUE FALSE TRUE | FALSE TRUE FALSE | FALSE TRUE TRUE | FALSE XNOR: A B | C ----- ----- | ----- FALSE FALSE | TRUE FALSE TRUE | FALSE TRUE FALSE | FALSE TRUE TRUE | TRUE For notation, I will simply use the NOT bar or tilda in combination with the exiting notation for AND, OR, or XOR. _____ A NAND B = NOT (A AND B) = A & B = ~(A & B) _____ A NOR B = NOT (A OR B) = A | B = ~(A | B) _____ A XNOR B = NOT (A XOR B) = A ^ B = ~(A ^ B) FROM BITS TO BYTES: ------------------- I described the functions above in terms of pairs of bits resulting in a single bit. In programming 650X assembly language, you will perform these functions on pairs of bytes. For each input byte you perform the logic function between the corresponding pairs of bits from each input byte, and place the result bit in the corresponding position in the result byte. Look at the graphic examples below for a picture of the operation. SOME PRACTICAL LOGIC: --------------------- As an assembly language programmer you will make frequent use of binary logic functions in your programs. In this section I provide some practical examples for AND, OR, and XOR. As a programmer you will often use individual bits within bytes to indicate whether conditions in your game environment are TRUE or FALSE, such bits are often refered to as flags. You will often group flags together into bytes to save space in the limited memory of your computer. You will use the AND, OR, XOR logical functions to clear, set, and toggle those flags as events happen in your game. ------ AND - The function AND is often used in programs to reset one or more bits in a byte to zero, while leaving the other bits unchanged. Example: Given: %11011010 Say you want to be sure that the MSB and LSB of the given byte are clear. In this example the LSB is already clear, but you don't want to waste time in your code to figure out if the bits are set and then clear them. With AND you can just clear them. The first step is to create the necessary bit-mask. The bit mask is a byte value that will preserve the bits you want unchanged and clear the bits you want cleared. For each bit to be cleared, reset the bit in the bit mask to 0. For each bit in the given byte to be unchanged, set the bit in the bit mask to 1. So to clear the MSB and LSB, but preserve all other bits as is, the bit mask is: %01111110 C = Given & bitmask = %11011010 & %01111110 = %01011010 ^^^^^^^^ %11011010 |||||||| & %01111110 |||||||| ----------- |||||||| |||||||| |||||||| |||||||+--> 0 & 0 = 0 ----------------++++++++ ||||||+---> 1 & 1 = 1 ----------------+++++++ |||||+----> 0 & 1 = 0 ----------------++++++ ||||+-----> 1 & 1 = 1 ----------------+++++ |||+------> 1 & 1 = 1 ----------------++++ ||+-------> 0 & 1 = 0 ----------------+++ |+--------> 1 & 1 = 1 ----------------++ +---------> 1 & 0 = 0 ----------------+ ------ OR - The OR function is often used to set individual bits to 1 within a byte without changing the state of other bits in the byte. As with using AND to clear bits in a byte, we don't care if the bits are already set will be set by OR'ing the byte with a corresponding bit mask. Every bit we want set in the byte must be set in the bit mask. Any bit clear in the bit mask will be unchanged after the OR. Example: Given: %11011010 - use OR to set the MSB and LSB. bitmask = %10000001 C = Given | bitmask = %11011010 | %10000001 = %11011011 ^^^^^^^^ %11011010 |||||||| or %01111110 |||||||| --------- |||||||| |||||||| |||||||| |||||||+--> 0 | 1 = 1 ----------------++++++++ ||||||+---> 1 | 0 = 1 ----------------+++++++ |||||+----> 0 | 0 = 0 ----------------++++++ ||||+-----> 1 | 0 = 1 ----------------+++++ |||+------> 1 | 0 = 1 ----------------++++ ||+-------> 0 | 0 = 0 ----------------+++ |+--------> 1 | 0 = 1 ----------------++ +---------> 1 | 1 = 1 ----------------+ ------ XOR - The XOR function is often used in code to flip/toggle the state of specific bits in a byte without effecting other bits in the byte. If the bit is 1 it is flipped to 0. If the bit is 0 it is flipped/toggled to 1. As with AND to clear bits, and OR to set bits, for XOR you must create a bitmask to indicate which bits are to be toggled and which are to be unchanged. Each bit set in the bitmask will toggle the bit in the target byte. Each bit in the bitmask reset to 0 will be unchanged in the target byte. Example: Given: %11011010 - use XOR to toggle the MSB and LSB. bitmask = %10000001 C = Given ^ bitmask = %11011010 ^ %10000001 = %01011011 ^^^^^^^^ %11011010 |||||||| or %01111110 |||||||| --------- |||||||| |||||||| |||||||| |||||||+--> 0 ^ 1 = 1 ----------------++++++++ ||||||+---> 1 ^ 0 = 1 ----------------+++++++ |||||+----> 0 ^ 0 = 0 ----------------++++++ ||||+-----> 1 ^ 0 = 1 ----------------+++++ |||+------> 1 ^ 0 = 1 ----------------++++ ||+-------> 0 ^ 0 = 0 ----------------+++ |+--------> 1 ^ 0 = 1 ----------------++ +---------> 1 ^ 1 = 0 ----------------+ ------- MORE LOGIC: There is much more to binary logic, often called Boolean math after its inventor. This lesson has covered enough for our needs, but there is plently more information and advanced techniques for simplifying complex logical equations, for example: ____________________ E = ((A & B) | (C ^ D )) & A We aren't interested in such complex logic in a beginners course, but feel free to explore the topic yourself if interested. Search the internet for "Boolean Math". =========== Excercises: 1. Given the following bytes (A) and bitmask (B) values calculate the result C, for C = A & B, C = A | B, and C = A ^ B a. A = %11111111, B=%10101010 b. A = %00000000, B=%01010101 c. A = %11110000, B=%01110111 2. Given the following bytes (A) and bitmask (B) values calculate the result C, for C = A NAND B, C = A NOR B, and C = A XNOR B a. A = %10110110, B=%00000000 b. A = %11111111, B=%11111111 3. Fill in the blanks '_____' in this pseudocode example with what you believe is the correct logical function. SUBROUTINE CheckPlayerStatus BEGIN IF (PLAYER.has_green_key = TRUE) ___ (Player.is_touching_door) THEN Goto PlayerExitsLevel ELSE IF (Player.touching_monster = TRUE) ___ (Player.touching_arrow) THEN Goto PlayerKilled ELSE IF (Player.touching_gold = TRUE) ___ (Monster.died) THEN Goto PlayerGetsPoints ENDIF END CheckPlayerStatus 4. BONUS PUZZLER!!!! You are running low on available memory for your game. You need to store 2 different counters of events occuring in your game. The first counter counts up from 0 to 7, when the counter reaches 7 the next time it is added to it resets to zero. The second counter, will count down from 13 to 0, once the counter is at zero it stays at zero even if it is decremented again. Devise a method for using binary addition and subtration in combination with AND, OR, or NOR logic functions to allow you to store both counters in a single byte. You must be able to change either counter without affecting the other. Write the pseudo code to change each counter without affecting the other. Your solution must not share any bits between the two counters even though such a solution is technically possible, you do not have enough free clock cycles left in your program to use such a technique.
-
Lesson 5 - Binary Math In lesson 4, I introduced counting with bits using the binary number system. In this lesson I will cover binary arithmetic and conclude my description of negative numbers using two's complement notation. Binary Addition: Adding binary numbers is as easy as 1, 2, 3. In fact all you ever need to know is: 0+0 = 0 0+1 = 1 1+0 = 1 1+1 = 2 1+1+1 = 3 Adding 2 binary numbers uses the same method as adding decimal numbers. The only difference is that in decimal when you add each pair of digits, if the sum is greater than 9, you carry the 10 to the next column. In binary when the sum is greater than 1, then you carry the 2 to the next column. Except the 2 is in binary notation so its %10 instead of the decimal 2. The best way to see this method is probably by example. Let's add 2 numbers in decimal, and then add the same numbers in binary. Example: Decimal: 34 + 67 ------------ || |+-> 4+7 = 11 ------------------+ | | | | | Carry the 10 | | v | +--> 3+6 + 1 = 10 -------------+| | || | Carry the 10 || v || 0+0 + 1 = 1 -------> 101 = Final answer. ^ ^ | | +-+---- Note the leading zeros needed to finish the calculation. Binary: %0100010 (=34) +%1000011 (=67) -------- ||||||| ||||||+- 0+1 = %01----------------------------+ |||||| | | |||||| | No carry | |||||| v | |||||+-- 1+1 + 0 = %10 (=2) ----------------+| ||||| | || ||||| +----+ Carry the 2 (=%10) || ||||| v || ||||+--- 0+0 + 1 = %01 --------------------+|| |||| | ||| |||| +----+ No Carry ||| |||| v ||| |||+---- 0+0 + 0 = %00 -------------------+||| ||| | |||| ||| +----+ No Carry |||| ||| v |||| ||+----- 0+0 + 0 = %00 ------------------+|||| || | ||||| || +----+ No Carry ||||| || v ||||| |+------ 1+0 + 0 = %01 -----------------+||||| | | |||||| | +----+ No Carry |||||| | v |||||| +------- 0+1 + = = %01 ----------------+|||||| | ||||||| | vvvvvvv +- No Carry %1100101 = 101 decimal = Final answer Ta Da! Unfortunately, I chose a poor example in that there is no case of 1 + 1 + 1 in the above example, so lets try another one: Binary Addition exmaple 2: %1101111 (=111 decimal, are you confused yet :P ) +%1111011 (=123 decimal) -------- ||||||| ||||||+- 1+1 = %10 (=2) ----------------------+ |||||| | | |||||| | Carry the 2 (=%10) | |||||| v | |||||+-- 1+1 + 1 = %11 (=3) ----------------+| ||||| | || ||||| +----+ Carry the 2 (=%10) || ||||| v || ||||+--- 1+0 + 1 = %10 --------------------+|| |||| | ||| |||| +----+ Carry the 2 (=%10) ||| |||| v ||| |||+---- 1+1 + 1 = %11 -------------------+||| ||| | |||| ||| +----+ Carry the 2 (=%10) |||| ||| v |||| ||+----- 0+1 + 1 = %10 ------------------+|||| || | ||||| || +----+ Carry the 2 ||||| || v ||||| |+------ 1+1 + 1 = %11 -----------------+||||| | | |||||| | +----+ Carry the 2 |||||| | v |||||| +------- 1+1 + 1 = %11 ----------------+|||||| | ||||||| +-- Carry the 2 --+||||||| |||||||| vvvvvvvv %11101010 = 234 decimal = Final answer | v Please note that the final carry forms a new digit replacing what was a leading zero in the numbers being added. So much for addition, now let's look at subtraction. Binary Subtraction: You may be beginning to suspect, binary subtraction is very similar to decimal subtraction in the same way that binary addition is similar to decimal addtion. If so, then you are correct. Binary subtraction follows the same basic rules as decimal subtraction. The difference is that when you don't have enough to perform the substraction of 2 digits as in decimal, then you do not borrow 10. Rather you will borrow 2. So: 0 - 0 = 0 1 - 0 = 1 0 - 1 = 1 borrow 2 1 - 1 = 0 1 - 0 - 1 = 0 1 - 1 - 1 = 0 borrow 2 | v This 3rd digit in the subtraction represents the borrow from the previous step of the subtraction. As I did for addition, let's try an example: Decimal example: 124 - 115 --- ||| ||+--> 3 - 5 = 9 with borrow of 10 -------+ || | | || +---- borrow ----+ | || v | |+---> 2 - 1 - 1 = 0 --------------------+| | | || | +---+ no borrow || | | || +----> 1 - 1 - 0 = 0 -------------------+|| | ||| +- no borrow vvv 009 = 9 final answer. same example subtraction in Binary: %1111100 (= 124 decimal) - %1110011 (= 115 decimal) -------- ||||||| ||||||| ||||||+---> 0 - 1 = 1 with borrow of 2 ---------+ |||||| | | |||||| +------ borrow ------+ | |||||| v | |||||+----> 0 - 1 - 1 = 0 with borrow of 2 --------+| ||||| | || ||||| +------ borrow ------+ || ||||| v || ||||+-----> 1 - 0 - 1 = 0 ------------------------+|| |||| | ||| |||| +---+ no borrow ||| |||| v ||| |||+------> 1 - 0 - 0 = 1 -----------------------+||| ||| | |||| ||| +---+ no borrow |||| ||| v |||| ||+-------> 1 - 1 - 0 = 0 ----------------------+|||| || | ||||| || +---+ no borrow ||||| || v ||||| |+--------> 1 - 1 - 0 = 0 ---------------------+||||| | | |||||| | +---+ no borrow |||||| | v |||||| +---------> 1 - 1 - 0 = 0 --------------------+|||||| | ||||||| v vvvvvvv no borrow %0001001 = 9 decimal = final answer Ta Da! So you see that binary subtraction closely parallels decimal subtraction. There is a problem, however, that we have not yet addressed. If we subtract a larger number from a smaller one, the result will be negative. In lesson 4, I began discussion of the 2's complement format for binary negative numbers. In that discussion I said that a prime advantage of 2's complement was that addition and substraction of numbers in 2's complement resulted in the correct answer in 2's complement format. Now, let's perform a subtraction with a negative result and see what happens. No new rules are required to perform the subtraction, just follow the same procedure as if the expected result will be positive. Binary subtraction example 2: %1110011 (= 115 decimal) - %1111100 (= 124 decimal) -------- ||||||| ||||||| ||||||+---> 1 - 0 = 1 --------------------------+ |||||| | | |||||| +---+ no borrow | |||||| v | |||||+----> 1 - 0 - 0 = 1 -------------------------+| ||||| | || ||||| +---+ no borrow || ||||| v || ||||+-----> 0 - 1 - 0 = 1 with borrow of 2 -------+|| |||| | ||| |||| +------ borrow ------+ ||| |||| v ||| |||+------> 0 - 1 - 1 = 0 with borrow of 2 ------+||| ||| | |||| ||| +------ borrow ------+ |||| ||| v |||| ||+-------> 1 - 1 - 1 = 1 with borrow of 2 -----+|||| || | ||||| || +------ borrow ------+ ||||| || v ||||| |+--------> 1 - 1 - 1 = 1 with borrow of 2 ----+||||| | | |||||| | +------ borrow ------+ |||||| | v |||||| +---------> 1 - 1 - 1 = 1 with borrow of 2 ---+|||||| | ||||||| Leading Zeros! +------ borrow ------+ ||||||| | v ||||||| +----------> 0 - 0 - 1 = 1 with borrow of 2 --+||||||| | |||||||| v vvvvvvvv BORROW! %11110111 = -9 decimal = final answer Two' Complement Revisited: The answer above is indeed the expected answer of -9 represented in 2's complement binary notation. Don't worry if you are confused, it will all become clear shortly. The most important thing to note from the above example, is that at the end of our calculation there is still a borrow. Since all that remains to subtract are leading zeros, the final borrow can never be resolved. It will produce an infinite set of leading 1's to our final answer if we keep calculating forever. This is the first clue to understanding 2's complement. Negative numbers in two's complement have an infinite number of leading 1's as opposed to positive numbers which have infinite leading zeros. From this we can deduce that for all 2's complement numbers the MSB indicates the sign of the number, exactly the same as sign magnitude notation (lesson 4). If the MSB is set, then the number is negative, if the MSB is clear, then the number is positive. The difference is that 2's complement has no representation for negative 0. %10000000 in 2's complement is not negative zero. Instead it is the largest negative number that the bits other than the sign bit can represent. So %10000000 has 7 zeros that 7 bits, 2^7 = 128, so %10000000 is -128 in 2's complement. FINDING THE TWO' COMPLEMENT: Given any positive binary number you can find its two's complement by inverting all the bits (change all 0's to 1, 1's to 0's) and then add 1. For example: 55 = %01010101 |||||||| Invert all bits vvvvvvvv %10101010 + 1 Add one --------- %10101011 = -55 Likewise we can perform the same process in reverse to convert any negative number in two's complement format to its positive equivalent. -55 = %10101011 - 1 Subtract 1 --------- %10101010 |||||||| Invert all bits. vvvvvvvv %01010101 = 55 Ta Da! [u]THE DREADED OVERFLOW AND UNDERFLOW!:[/u] In lesson 4, I mentioned underflow and overflow. Now I will attempt to explain what they are in detail. In lesson 1, we learned that all information in a computer is stored using bits. In lessons 2 and 3 we explored using enumerations and codes made of bits to store information like kinds of fruit. In lesson 4, we learned the standard method for counting in binary. A key point in all these lessons has been finding the number of bits needed to store the information in question. Up until now, in this lesson, I have assumed I had infinite bits to work with (leading zero's and one's were not shown but implied), but in a real computer the number of bits available is limited. Therefore, the storage of each number used by your program must be restricted to a finite number of bits. Since the 650X famliy of processors are 8-bit processors (Each instruction works with 8 bit chunks of data at a time), we will assume you will be using multiples of 8 bits to store all your numbers. You don't have to use multiples of 8, it simply makes programming easier. Earlier, I showed that the MSB of a 2's complement number is the indicator of the sign of the number. For an 8 bit number (a byte) this means that the magnitude of the number is restricted to 7 bits. There are 128 possible combinations for 7 bits. So for positive numbers we can represent values 0 through 127 with a single byte in two's complement. There is no negative zero, so for negative numbers 8 bits can represent the values -1 through -128. Therefore, 1 bytes can hold signed integers in the range from -128 to 127. Recall from lesson 4, a byte can hold UNSIGNED integers from 0 to 255. Overflow and Underflow are terms meant to describe when an addition or subtraction results in an answer outside the range of values that can be represented by the number of bits being used. Overflow is when the result exceeds the maximum that the number of bits and the chosen format can represent. Underflow is when the result is less that the minimum value that the number of bits and format can represent. Specifically for 8 bits: For signed 8-bit numbers: IF A + B is > 127 then OVERFLOW has occurred. IF A + B is < -128 then UNDERFLOW has occurred. IF A - B is > 127 then OVERFLOW has occurred. IF A - B is < -128 then UNDERFLOW has occurred. For unsigned 8-bit numbers: IF A+B is > 255 then OVERFLOW has occurred. IF A-B is < 0 then UNDERFLOW has occurred. The 650X processors include hardware support for detecting overflow and underflow during math operations. In your programs if overflow or underflow is possible, then you will need to check if it has happened and respond to correct the situation when it does. The details of code to handle overflow and underflow will have to wait for many lessons. For now just understand what it means. [b]BONUS QUIZ[/b]: What are possible correct responses for a program to handle overflow or underflow? BINARY MULIPLICATION AND DIVISION: Let's take some time to understand how multiplication and division are accomplished with binary numbers. All modern processors have built in support for multiplying and dividing integers, but the old 650X processors do not have specific opcodes (instructions) to multiply or divide 2 integers. That means you have to write code to perform a multiply or divide using the instructions that the processor does have. Luckily, the 650X processor family has build in support for adding and subtracting binary numbers. We will therefore use addition to implement multiplication, and subtraction to perform division. Multiplying: Think for a moment about decimal multiplication. What does it mean to say 3 time 5? One way to visualize multiplication is as an area of a rectangle, Area = width times height. Example: Area = Width x height = 3 x 5 = ? 5 VVVVV > OOOOO 3 > OOOOO > OOOOO | v The rectangle of O characters above represents the area of a 3 by 5 rectangle. To calculate the area we simply count the O's. There are 15 O's, which is the same as 3 times 5 = 15! Likewise, to mulitply on a 650X processor, you will solve the problem by adding up the O's of an imaginary rectangle. Your program will Add 5 three times 5+5+5 = 15, or it could add 3 five times 3+3+3+3+3=15. Both ways you accomplish multiplication via repeated addition. Division: In a similar iterative fashion, division is accomplished via repeated subtraction. Example: 15 divided 5 = ? 15 / 5 = 15 - 5 = 10 - 5 = 5 - 5 = 0 -> Remainder = 0 in this case. | | | v v v 1 + 1 + 1 = 3 -> 15 / 5 = 3 Okay, that's enough for today's lesson. Please try the following exercises. Stay tuned for a big change of pace in lesson 6 - State Machines! Exercises: 1. Perform the following binary additions of 2's complement numbers. Express the final result in 8 bits and indicate whether UNDERFLOW or OVERFLOW occurred. a. %10010100 + %01101000 = ? b. %00110100 + %01101111 = ? c. %10011100 + %11111000 = ? d. %01010011 + %11011101 = ? 2. Perform the following binary subtractions of 2's complement numbers. Express the final result in 8 bits and indicate whether UNDERFLOW or OVERFLOW occurred. a. %10110100 - %01001000 = ? b. %00110100 - %01101011 = ? c. %10111100 - %11011010 = ? d. %00010111 - %11010111 = ? 3. Convert the following 8-bit 2's complement numbers to their negative equivalent a. %00010010 b. %01000101 c. %01111111 d. %00000000 4. Convert the following 8-bit 2's complement numbers to their positive equivalent a. %10110110 b. %11001101 c. %11111111 d. %10000000 5. Provide a description of what would constitute OVERFLOW and UNDERFLOW for addition and subtraction involving 16-bit (word) 2's-complement numbers.
-
Have some simple questions for you 6502 gurus!
Robert M replied to 4ever2600's topic in 2600 Programming For Newbies
The Dig is down temporarily while it is being moved to another server and getting revamped. Cheers! -
Lesson 4 - Binary Counting In previous lessons, I have hinted that there is a standard method for counting using bits. In this lesson, I will introduce that standard method. First, I want to reiterate that this is NOT the only way to count using bits. It is simply the most common method, and therefore has considerable support for it built into most microprocessors including the 650X processor Family used in most classic gaming consoles and computers from the late 70's and 80's. Numbering Systems: ------------------ I must assume that if you can read the lessons in this class and understand them, then you must be familiar with decimal numbers and basic arithemetic like adding and subtracting. All decimal numbers are made using the ten digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. When you write a decimal number larger than 9 you must use two or more digits like this: 123 which is one hundred and twenty three. The 1 in 123 does not represent 1 it represents 100. The 2 in 123 is not 2 it is 20. The 3 in 123 does represent 3. Thus we call the 1 the hundreds digit, the 2 the tens digit, and 3 the one's digit. Each digit in a large decimal number represents that digit multiplied by a power of 10 based on its position and summed together. Thus (1 * 10^2) + (2 * 10^1) + (3 * 10^0) = 100 + 20 + 3 = 123 Ta!Da! We count numbers inside computers exactly the same way except that the numbering system in computers does not have 10 digits, it only has 2 digits: 0 and 1 (bits!). The numbering system that uses only 0 and 1 is called the binary numbering system or simply binary. Since it only has 2 digits the value of each binary digit in a large binary number is muliplied by a power of 2 instead of a power of 10 as we do for decimal numbers. The following table shows the positional value of the first 16 bits in the binary number system, as a power of 2. Note that the first position is numbered zero and not one. Bit position. | | Bit value | | 2^0 = 1 => bit 2^1 = 2 2^2 = 4 => octet 2^3 = 8 => nybble 2^4 = 16 2^5 = 32 2^6 = 64 2^7 = 128 => byte 2^8 = 256 2^9 = 512 2^10 = 1024 2^11 = 2048 2^12 = 4096 2^13 = 8192 2^14 = 16384 2^15 = 32768 => word Every computer in the world has a limited number of bits. When you use binary numbers in a computer program you must decide how many bits you will use to store each number that your program must keep track of. For 650X processors the most common numbers of bits to use will be 8 (byte) and 16 (word) because the processor works with data an entire byte at a time for each instruction (see opcodes in lesson 3). You can use any number of bits, but since 8 and 16 are so common we will focus on them for the remainder of this lesson. The same rules will apply to binary numbers made of any number of bits. This should not seem strange, as you can use any number of digits to represent a decimal number. If you don't need all the digits, then your number will have 1 or more leading zeros. 0000123 is the 7-digit decimal number 123, by convention leading zeros are not shown for decimal numbers, but they are always present nonetheless. The same is true for binary numbers. In the real world you can write as big of decimal number as your writing surface will allow. In a computer your writing surface is bits. If you do not have enough bits allocated/available to store a binary number then your program can not store that number and the information will be lost. Such an event is called overflow if the number is too big, or underflow if the number is too small. We will examine overflow and underflow in detail in the next lesson. You may be curious to know what is the biggest binary number you can store in a byte or a word. You already learned the formula in lesson 2 - enumeration. Given N bits, you can store 2^N different values. Counting positive integers starts at zero not one, so N bits can store binary numbers from 0 to (2^N)-1 Example: A byte has 8 bits so N=8: Therefore, a byte can hold unsigned positive integers from 0 to (2^8)-1=256-1=255. From 0 to 255. ALGORITHM to convert decimal to binary: --------------------------------------- To convert a decimal number to binary, you must repeatedly divide that number by 2. The remainder of each division is next binary digit in the binary representation of that decimal number. when there is nothing left to divide, the conversion is done. Example: Convert 123 decimal to its binary equivalent. 123 / 2 = 61 with a remainder of 1 -------+ 61 / 2 = 30 with a remainder of 1 ------+| 30 / 2 = 15 with a remainder of 0 -----+|| 15 / 2 = 7 with a remainder of 1 ----+||| 7 / 2 = 3 with a remainder of 1 ---+|||| 3 / 2 = 1 with a remainder of 1 --+||||| 1 / 2 = 0 with a remainder of 1 -+|||||| ||||||| 123 Decimal = 1111011 binary ALGORITHM to convert binary to decimal: --------------------------------------- Any binary number can be converted to its decimal equivalent, which is often easier for humans to read and understand. To convert a binary number to decimal you must multiply each digit of the binary number by its positional value (see the first table above) and add the digit values together to form the decimal value. Example: Convert 1111011 binary to decimal 1111011 binary ||||||| ||||||+- 1 * 2^0 = 1 * 1 = 1 |||||+-- 1 * 2^1 = 1 * 2 = 2 ||||+--- 0 * 2^2 = 0 * 4 = 0 |||+---- 1 * 2^3 = 1 * 8 = 8 ||+----- 1 * 2^4 = 1 * 16 = 16 |+------ 1 * 2^5 = 1 * 32 = 32 +------- 1 * 2^6 = 1 * 64 = 64 --- 123 decimal Binary Number Notation: ----------------------- Up until now I have been explicitly stating whether a written number is binary or decimal. As you can see it can become tedious to write "binary" or "decimal" after every number to clearly indicate the numbering system being used. Luckily, a handy shorthand notation exists for us to use to save time. For the remainder of this class I will always make use of this notation to indicate whether a number is binary or decimal. Decimal Notation: A decimal number is written with no special notation at all. It is written the same way you have always written decimal numbers. Binary Notation: All binary numbers shall be preceded by the % symbol. Examples: 123 is decimal and %1111011 is its binary equivalent. 101 is decimal = One hundred and one. %101 is binary = 4 + 1 = Five MSB and LSB: Another aspect of binary notation is Most-Significant and Least-Significant Bits (MSB and LSB). By convention a binary number is written from left to right the same as a decimal number. The left-most digit of a number represents the greatest portion of the overall value of the whole number. It is the Most-Significant digit in the number. The right-most digit of any number represents the least portion of the whole value. It is the Least-Significant digit. Each digit in a binary number is a bit. Therefore, the Most-Significant Bit (MSB) of a binary number is the leftmost bit, and the Least-Significant Bit (LSB) is the right most bit. Examples %100010010 ^ ^ | | MSB LSB %10111010010010 ^ ^ | | MSB LSB %100110 ^ ^ | | MSB LSB Please get comfortable with this notation for binary numbers because you will be using it extensively when writing assembly language programs! WHAT about negative numbers! ---------------------------- You may have noticed that so far our discussion of binary has been restricted to positive integers. Computers can count negative numbers, so now we will begin to explore methods for representing negative numbers in binary. We will complete this discussion in Lesson 5. Sign Magnitude Format: The first format for negative numbers we will explore is the sign-magnitude format. The format is easy to understand. For any given binary number add an additional bit to represent the sign of the number. If the sign bit is set, then the number is negative. If the sign bit is clear then the number is positive. The sign bit is the MSB of a sign-magnitude binary number. Examples: %0101 = %0 sign and %101 magnitude = 5 %1101 = %1 sign and %101 magnitude = -5 | +-> The MSB is the Sign bit There is a problem with this method of representing negative numbers. Can you see what that problem is? The problem is with the number zero. Using this system there are 2 instances of zero, a negative zero and a positive zero. There is no such thing as negative zero, so this may not be the best method for representing negative numbers. Two's Complement Format: (Introduction) An alternative to the sign-magnitude format is the two's complement format. Two's complement is superior to sign-magnitude (usually, but not always) because there is only one way to represent zero. Another advantage of two's complement is that when you add or subtract positve and negative numbers, the result is the correct number in two's complement format. To really understand two's complement, you must know how to add and subtract binary numbers. We won't learn how to add and subtract binary numbers until lesson 5, so we will suspend further discussion of negative binary numbers until lesson 5. What about REAL numbers? Yes, you can represent REAL numbers in binary. REAL numbers can also be thought of as fractions (1.23 for example). This is an advanced topic and I don't want to go into it now because I beleive it will confuse more people than it will help them to understand. You can write many, many programs without every needing to use REAL numbers. So just put them out of your mind for now. ------------------------------------------------------------------------- Exercises: 1. Convert 213 to binary 2. Convert %00101100 to decimal 3. Convert 1087 to binary 4. COnvert %1000010100011110 to decimal 5. Using the list of binary numbers below: %00110101 %01000101 %11100001 %10100110 %01001011 %01001110 %11001001 Take the LSB from each of the above numbers, in order from top to bottom, to create a new binary number. The LSB from the first number in the list should be the LSB of the new number. The LSB of the last number in the list is the MSB of the new binary number. What is the new binary number? Now convert that number to decimal. 6. For each of the numbers below, convert them to decimal twice. The first time assume that the numbers are in unsigned positive integer format. The second time assume that the numbers are in sign-magnitude format. a. %1000101 b. %0101010 c. %1100110 d. %0000010 7. What is the range of positive unsigned integers that can be stored in a word. BONUS QUESTION 1: For each number a-d in problem 6, is each number signed or unsigned? (Hint: refer to lesson 1). BONUS Question 2: Is the sign-magnitude format an Enumeration (Lesson 2) or a code (Lesson3), and why? ------------------------------------------------------------------------- NOTE TO READERS: We are rapidly descending from broad concepts to specific details in ASsembly programming. Most often, subsequent lessons will require an understanding of previous lessons. If you have questions after studying this material, do not hesitate to ask.
-
As of 5 minutes ago, I weight 229 pounds Damn Holiday feasts! :wink: I know, it can vary. I'll just weigh myself sometime on the 13th and that will be the weight. A chance to vary by 5 pounds will make the final result more exciting. BTW: I am 6 feet tall.
-
Game Idea: The Matrix: Ataried and Inspector Gadget
Robert M replied to pheedback's topic in Homebrew Discussion
Are you following my Assembly Language course in the Programming for Newbies forum? It would be good to get some feedback/questions in the lesson threads from a newbie to know what I am successfully communicating, and what I am not. Cheers! -
Make sure the catridge case matches the one shown on this website. If its not that form factor, then it is most likely a reproduction. If it seems legit, I would think its worth more than $75.
-
It looks like the shadow cast by the player changes as the Sun moves across the sky. That's very impressive.
-
Assembly Language Programming - Lesson 3 - Codes
Robert M replied to Robert M's topic in 2600 Programming For Newbies
Ah! I was just seeing if anyone was paying attention! Yes, that's it! That's the ticket! Thanks Nukey, I'll edit the previous post! -
Assembly Language Programming - Lesson 3 - Codes
Robert M replied to Robert M's topic in 2600 Programming For Newbies
I agree that on 650x (or any other 8 bit CPU) words are 16 bits. But, the same cannot be said if you are talking about the x86, or 68xxx, or some obscure processor like the PDP-1 or the GI CP1600 used in the Intellivision. Anyway. For the purposes of this tutorial, word = 16 bits and 16 bits = word. Eric Ball and the two Toms are correct in that the definitions for byte and word are not written in stone. Their definitions can vary from computer system to computer system. For the purpose of this course, however, a byte is 8 bits and a word is 16-bits. Cheers! -
Assembly Language Programming - Lesson 3 - Codes
Robert M replied to Robert M's topic in 2600 Programming For Newbies
Sorry for the delay! Excercise ANSWERS: Excerises: 1. Covert the following decimal numbers to BCD format: a. 10 b. 253 c. 7689 d. 4 a. 10 = 0001 0000 b. 253 = 0010 0101 0011 c. 7689 = 0111 0110 1000 1001 d. 4 = 0100 2. Give an example of a 3 bit Gray code. NOTE: There is more than 1 correct answer. Here's a way to make a gray code of any length of bits. Start with a gray code for 1 bit = 0 1 To get a gray code of n+1 bits from a gray code of n bits simply repeat the n code followed (or preceeded) by a single zero, then repeat the n code again in reverse followed by a single 1. So from the above one bit code we get a two bit code as 0+0 = 00 1+0 = 10 Repeat 1 bit code in reverse. 1+1 = 11 0+1 = 01 Simply repeat this process to get a 3 bit gray code: 00+0 = 000 10+0 = 100 11+0 = 110 01+0 = 010 Repeat 2 bit code in reverse... 01+1 = 011 11+1 = 111 10+1 = 101 00+1 = 001 3. How many nybbles are there in a word? We know how many bits are in nybble and a word so we can convert from one to the other by converting words to bits and then bits to nybbles. 1 word = 16 bits 1 nybble = 4 bits nybbles per word = 16/4 = 4 nybbles. 4. How many bits are in 512 bytes? By our definitions there are 8 bits in a byte. So there will be: 512 * 8 = 4096 bits in 512 bytes. {edited: after error was pointed out by Nukey} 5. How many octets are in 72 nybbles? Again we will convert from one unit to bits, and then from bits to the other unit. 72 nybbles * 4 (bits per nybble) = 288 bits 288 bits / 3 bits per octet = 96 octets. 6. You wish to store strings in your program. The strings will contain only capital letters A-Z, spaces, periods, question marks, and a special character that marks the end of the string. How many bits are needed to store each character in a string? By packing the character codes together how many characters could fit into 8 bytes? First we count the total number of symbols possible for each character. A-Z is 26 symbols. Space, period, question mark, and termination are 4 more symbols. 26 + 4 = 30 total possible symbols. We can enumerate the symbols as we learned in lesson 2. The number of bits needed is log(base2) 30 rounded up = 5 bits are needed per symbol in the string! Now the second part of the question asked how many symbols will fit into 8 bytes worth of bits. total bits = 8 bits per byte * 8 bytes = 64 bits. Number of symbols in 8 bytes = 64 bits / 5 bits per symbol = 12.8 symbols Not quite 13 symbols will fit into 8 bytes of space. -
Hi, There is no reason you should not be able to get a crisp picture. Things to try: 1. Check both positions of the channel select switch and see if one is better. 2. Check the connector to the TV for corrosion/dirt. If needed clean it with very very fine steel wool. 3. Get a TV noise reduction filter from Radio shack. 4. Sometimes the RF tuner in the system over time will drift off of the ideal frequency for broadcast to the TV. There is a trim potentiometer inside the VCS that you can turn with a small screwdriver to adjust the output frequency. There is another thread in this forum that details this process. I will add the link if I find it. Good-luck , and happy gaming.
-
Hi, I recently shelled out the big bucks and picked up a copy of Battlezone 2000 for Lynx. I enjoy the game well enough, although I find the missions for points from 2000 to 10000 to be a bit tedious The real reason for this thread is the hidden "3D-game" within the original game. The way to get to this game is detailed on many sites on the web so I won't cover it here. When I came across the code I assumed it would simply be the same game but with filled polygon graphics instead of vectors. I was surprised to see it is a completely different game! Yes, you are still driving a tank, but the game is completely different. You have much more custimization capability. Pluras you have to pick up parts on the battlefield and install them while still under attack. The goal of the game is not clear. It seems like you are trying to clear all the sectors on a very large map using limited resources. I have found a key, and a spinning pyramid that I think the key will open, but how I haven't determined yet. I am just amazed, that there is this completely undocumented game within the game. Its not a mini-game or a variation of the main game. Its a completely new game. The frustrating part is there is no documentation provided for this alternate game. I haven't found any on the web either. So I propose that this thread become a adhoc manual for this new lynx game hidden on the Battlezone cartridge. When you play this game, if you discover something, please add it to the thread. Regards,
-
I wish you well. All emulators are welcome. I can't resist, however, pointing out the irony that a .Net application can only run in Windows32. Keep it coming!
-
Assembly Language Programming - Lesson 3 - Codes
Robert M replied to Robert M's topic in 2600 Programming For Newbies
Sorry the holiday is taking much of my time, I will post the answers on Friday evening. Unless someone else wants to take a shot at posting the answers Cheers! -
Assembly Language Programming - Lesson 3 - Codes In lesson one we learned what a bit is. In lesson 2 we learned how to use bits to enumerate lists of items. In this lesson we are going to learn how to use bits to encode information. DEFINITIONS: Before we study codes, however, we need to take a detour and learn some new terminology. When we enumerated, we saw that with 1 bit we can enumerate 2 items 0 and 1. With 2 bits we can enumerate up to 4 items 00, 01, 10 and 11. So on and so on, such that given N bits we can enumerate up to 2^N items. As you can guess, it is a very common practice to combine bits together for the purpose of enumeration. Some combinations are used so frequently in programming that they have been given special names: 1 bit = a bit 3 bits = an Octet -> Since it can enumerate 8 items. 4 bits = a nybble 8 bits = a byte 16 bits = a word I will be using these terms in all future lessons so get comfortable with them now. For example the Atari 2600 has 128 bytes of RAM. How many bits is that? ANSWER: 128 bytes * 8 bits/byte = 1024 bits. What is RAM? Don't worry I will explain that in a later lesson. If you are sharp eyed you may have noticed something about the naming of the bit strings above. Except for the octet each one is a power of 2! 2^0=1 (bit), 2^1=2(no name), 2^2=4(nybble), 2^3=8(byte), 2^4=16(word). This is no accident. Computers are based on bits and manipulate bits hence powers of two are a natural occurance in digital computers. So these numbers appear very often in programming. As a programmer you will find there are advantages to using powers of 2 in your programming. The odd Octet will become clear in Lesson 4. INTRODUCTION TO CODES: All enumerations are codes, but not all codes are enumerations. What does that mean? It means that enumerations are one type of binary code. In lesson 2, we enCODEd the type of fruit (Apple, orange, bananna, cherry) using bits. What makes enumerations special codes is that they exactly match the binary numbering system used in computers for arithmetic so: Apple = 00 = zero, orange = 01 = one, bananna = 10 = two, cherry = 11 = three. We don't have to encode our types of fruit that way we could encode them as Apple = 10110, Orange = 10000, bannana = 10111, cherry = 11000, but this is now a code and not an enumeration. Operation Codes: One of the most important codes you will become familiar with is Operation Codes. Every microprocessor (CPU) has what is called an instruction set or a set of operation codes. Operation codes is often abbreviated as opcodes. Operation codes are the executable (as opposed to pure information) part of your program. The hardware of the microprocessor reads each opcode in the sequence of the program and performs the action demanded. Later in this course we will explore all of the opcodes in the 6507 microprocessor (the processor in the Atari 2600) in detail. In the 6507 instruction set each opcode is 8-bits long, or 1 byte. The opcodes are not an enumeration, they take all sorts of values using 8 bits within a byte often skipping many bit combinations that would make the code an enumeration. The bits set in each opcode were chosen because they simplified the work of the engineers to build the logic circuits in the microprocessor. Gray Codes: A gray code is a special kind of binary code of N bits. Gray codes are used for counting 0, 1, 2, 3, etc. Gray codes are special in that each time you add or subtract 1 from the code, only 1 bit will change. Here is an example of a 2-bit gray code: 00 = zero 01 = one 11 = two 10 = three 00 = zero (pattern is repeating...) You can see that only one bit changes as you count up or down through the 4 combinations. Gray codes are handy in situations where you want to minimize the amount of harware needed to implement a counting circuit in a computer. In the Atari 2600, the driving controllers (Indy 500) use a 2 bit gray code to encode the direction the paddle is being turned, the speed at which the code changes indicates the speed the paddle is turning at. Binary Coded Decimal (BCD): Binary Coded Decimal or BCD is a method for storing decimal numbers in an easy (sometimes) to use format within a computer. You are already aware of decimal numbers you use them to count all the time: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, etc. In BCD each decimal digit is encoded into a separate nybble = 4 bits. decimal = binary 0 = 0000 1 = 0001 2 = 0010 3 = 0011 4 = 0100 5 = 0101 6 = 0110 7 = 0111 8 = 1000 9 = 1001 Each byte contains 2 nybbles, so each byte can hold 2 BCD digits (00 to 99 decimal). This is an important code for you as a programmer because the 6507 processor has built in support for adding and subtracting BCD numbers. The big advantage for BCD numbers is that each digit is confined to its own nybble. It is therefore easier to isolate the individual digits for drawing them onto the screen. So scores are good candidates for being stored in BCD since you want to draw them on the screen as decimal digits. The big disadvantage for BCD is that you are wasting bits each BCD digit takes 4 bits which if used completely could store 16 values, 6 more than the 10 that it is being used for. ALPHANUMERIC Codes: Programmers use alphanumeric codes to store text information used by their programs. Each letter, digit, and punctuation symbol is assigned a binary code. The minimum number of bits in the code is dependent on the desired number of characters used in your text strings. If you only want capital letters, numbers and the punctuation marks . Then you need 26+10+4 = 40 symbols, which requires 6 bits (from Lesson 2) per character in the string. Text manipulation is not a frequent activity for Atari 2600 games since the resources are so limited. Some games do display text. If your game will, then you need to decide between storing the strings as characters and then expanding them into the graphics to display on the screen, or store them in the cartridge already expanded and ready to display. Its a trade off between speed and storage space. We will explore such trade-offs much much later in the class. There are 2 commonly used Alphanumeric codes for all computers. The first one is called ASCII. ASCII codes are 7 bits long. Therefore there are 128 symbols in the ASCII codes. Many documents on the internet contain ASCII codes. You can recognize these files in Windows as the files with a .txt file type extension. When you write your assembly code programs the program you used to store your code files will most likely store them as ASCII codes. The other common alphanumeric code is the Unicode. Unicode is a 16-bit code. It contains all the letters and symbols needed to display any known language in the world. ASCII has only the letters needed for english. Summary: The examples above are just a few codes. An infinite number of codes is possible because as we learned in Lesson 1, the meaning of the bits is entirely up to the programmer writing the program. Please try the exercises below to cement these new ideas home ----------------------------------------- Excerises: 1. Covert the following decimal numbers to BCD format: a. 10 b. 253 c. 7689 d. 4 2. Give an example of a 3 bit Gray code. NOTE: There is more than 1 correct answer. 3. How many nybbles are there in a word? 4. How many bits are in 512 bytes? 5. How many octets are in 72 nybbles? 6. You wish to store strings in your program. The strings will contain only capital letters A-Z, spaces, periods, question marks, and a special character that marks the end of the string. How many bits are needed to store each character in a string? By packing the character codes together how many characters could fit into 8 bytes? Answers will be posted within 24 hours.
