V22.0201.002, Machine Organization I, Yap
Fall 1997


This page collects useful information for doing your final project. Please look here for information that I will add, from time to time.


  1. Project Information
  2. Proposal Tips
  4. Programs You Can Use
  5. Technical Notes and Tips
  6. Considerations in Project Design
  7. F.A.Q.s
  8. Bottom of Page



There are things that I like to see in your game proposals:
 	(1) some element of timing
	(2) some animation and graphics
	(3) interesting or innovative twists
Does not mean every proposal has to have all (or even any) of these elements. But if these are missing, I think you better introduce some other nice features that I consider adequate substitute. Note that even with graphics or animation, you may be able to use text modes rather than the graphics modes.

When you write your proposal, try to mention whether you will use any of the following features, and expand on them if necessary:

	(a) random number generator
	(b) use of timer
	(c) setting up of new interrupts
	(d) use of mouse
	(e) video modes: graphics or text mode?
	(f) use of animation
E.g. The usual game of pong has (1) and (2), but is boring from the viewpoint of (3) -- there are plenty of such games available (for instance, there is one in the book).

E.g. The Extreme Volleyball game by students in my previous class is really a simple variation of the pong game, but they gave it a nice twist.

E.g. Don't propose to do tic-tac-toe, in the standard version of this! No timing, no animation, no novelty. But if you want to do a 3D version of this, I would be more receptive.

E.g. Tetris has (1) and (2) but do not propose to do the standard game (it is easy to copy the code for this game from the internet). But I can think of lots of variations of tetris that you can do. One might be to add "obstacle" squares such that a piece can get stuck if lands on the obstacles. Another would be to change the shape of the region in which you play the game (e.g., the bottom edge need not be flat).


Here is the (working) list of proposals. If your proposal is not here, contact me at once!


  1. Random number generator. In many games, you want to generate random numbers. We will provide you with such a program to use, if you need one.
  2. Counting clock ticks. Another critical element in many games is the ability to keep time. The text book (ch.15) has a timer program that is set up as an interrupt. Use this if you need a timer.
  3. Sound. We plan to give a lecture on sound. But even without going into fancy sound (with music, etc), you can use beeps and other simple sounds to improve the quality of your game. We suggest you consider this.
  4. Mouse. If you want to define and change the mouse cursor, please look in our notes on mouse (INT 33h, function 9).
  5. Animation. We will give a lecture on this. Or, look at the sample games.
  6. Collection of VGA graphics routines. A collection of such routines in assembly language and in C language is available in subdirectories "asm" and "c" in the progs directory. The file egalib.asm in vga-asm includes all the other programs. So you could assemble it to test all the routines. However, you need to write your own main program!

    P.S. I found that using "CONST" as name of a segment is illegal in TASM, so you can replace it by "_CONST". There are 3 places where you need to do this.

    There is a line drawing routine (prog086.asm) and a routine to draw a solid box (prog085.asm). I have written some main programs to call these routines (e.g., vgaline.asm uses the routine in prog086.asm).

    One of the most useful programs here is "Bit Block Transfer", _BitBlt in prog087.asm. It copies a block of pixels from a source block to a destination block. Unfortunately, I believe this works only on page 0 of your graphics mode. Look at my files vgablt*.asm to exercise _BltBlt in various modes.

    Also, if the source and destination blocks overlap, there may be some undesirable effects in _BitBlt. My solution is to write another program, called _BitBltX which also does block transfer but calls _BitBlt several times, each time making sure that there is no overlap,


Here is a list of general notes on various aspects of assembly language programming (video, mouse, etc). Below, we mention additional information specific to your final project.
  1. CHOOSING VIDEO MODES. See Video Info for general details about video programming.
    One of the first decisions you need to make is whether to use a text mode or a graphics mode. Although the choices may at first appear confusing, remember that most of you really only need to learn how to use ONE of these modes. In choosing modes, remember that there are simple text capabilities even in graphics mode. Likewise, there are some primitive graphics ability even in text mode. For instance, in text mode using the IBM extended character set, you can draw rectangular boxes (or, mazes) in single or double lines! (INT 10h, function 9 will work for extended character sets) Moreover, the mouse capability (INT 33h) works in text as well as graphics mode.
  2. USEFUL VIDEO MODES. Normally, your MS-DOS Prompt begins in mode 3 (cga text mode). For instance, the pong game in the text is written in this mode. Also, when you exit from your games, you should always reset your screen back to this mode.

    Generally, most games can use more colors in which case I recommend modes 12h or 13h, which are vga graphics modes. These modes have only one video buffer page.

    If you need more than one page, consider using (vga graphics) mode 10h which has two pages. Mode 10h has screen size 640x350, and has 16 colors provided your video buffer is at least 128K. See Helppc for more details. These days, most machines have 256K video buffer, so this is not a problem. To find out what your computer has, use INT 10h, fcn=12h.

    Note that when you switch modes or pages, normal the display is cleared. To prevent this, make sure that bit 7 of AL is set before you call INT 10h.

    	mov ah,0	; set mode
    	mov al,10h	; choose mode 10h
    	or al,80h	; set bit 7 of AL
    	int 10h
  3. USING THE MOUSE in Win95 or WinNT. See Mouse Info for general details about mouse programming.
    If you use mouse inputs, it may not work properly if your program is a window in Win95 or WinNT. The best solution is to take over the whole screen for your program. You can do this by typing ALT-ENTER to toggle between taking over the screen and going back into Win95.
    NOTE: In Win95, you can also choose the ``properties'' menu of the MSDOS Prompt Window, and under the ``misc'' tab, choose to make the mouse exclusive. In WinNT, one can also get to the ``properties|misc'' tab, but it does not seem to work.
    In graphics animation, you often need to delay the display. One way is to use a do-nothing loop. But this approach does not keep absolute time -- the time depends on the speed of your CPU. (Another problem is that this ties up your CPU doing nothing). To avoid this problem, you need to make use of the timer chip in your PC. Chapter 16 of your text book gives a simple solution. Essentially, it writes a timer interrupt procedure called TIMER_TICK (page 344) to be called automatically 18.2 times per second (equivalently, every 55 ms). This procedure simply sets a global variable TIMER_FLAG to 1.

    This TIMER_TICK program is used in pgm16_2 (page 346). It is used to for generating a fixed frequency tone for the sound card (page 347). I have written a sample program (found in the file timeout.asm) to illustrate how you can keep time using the timer_tick interrupt routine. (Look under ``samples'' in class page.)

    NOTE: Another method to keep absolute time is to directly read the clock tick at address 0000:046C and 0000:046E (this is a 32 bit value that is updated by the clock every 55 ms). See the file egalib.asm in the vga-asm directory.

    It is often useful to know if the keyboard buffer is empty or not. You cannot use INT 21h, function 1 for this (why not?). This requires INT 16h, function 1. On return from this interrupt, the zero flag (ZF) is set if keyboard is empty. The program timeout.asm (mentioned above) uses this interrupt function. Actually, DOS also provides a similar interrupt function: INT 21h, function 11h is called the "input status interrupt".
    		INPUT:  ah=11h
    		OUTPUT: al=0 if buffer is empty
    			al=0FFh if buffer is not empty
    Related to this interrupt is the ability to flush the buffer, and execute an input command at the same time.
    	INT 21h, function 0Ch:
    		INPUT:  ah=0Ch
    			al=1,6,7,8 or OAh
    The output depends on which of the subfunctions (1,6,7,8,0Ah) is used. Other inputs are also necessary, depending on the subfunction. For instance, al=0Ah refers to reading a string. In this case, ds:dx must be setup to contain the address of the memory buffer for storing the string input. (This was the subject of HW3.)
    Usually, we use the "small" model and this should be sufficient for many of your projects as well. But suppose you need other models. First, let us note that the small model assumes that there are separate segments for each of the following:
    		code, stack, data.
    Suppose your program does not fit the small model. You can of course, go to full blown definitions of your own segments (using the "SEGMENT" directive). But a more convenient way is to use other ``standard memory models''. We now explained three of the most common ones. In other models, we allow code and data to be put into more than one segment. Moreover, we distinguish several kinds of data segments.
    		data:	has (possibly) initialized data
    		data?:	has only un-initialized data
    		const:	has constant data
    		fardata: has (possibly) initialized data
    		fardata?: has only un-initialized data
    MEDIUM MODEL: data here can be put in one segment but code needs to be put into several segments. To use this model, you use the following directive:
    		.MODEL MEDIUM >csn<
    where >csn< refers to "code segment name". If you have several assembly modules, each with a different >csn<, you can generate several code segments this way. But, in fact, you can also generate more than one code segment within the same assembly module, by using the directive
    		.CODE >csn<
    This directive begins a new code segment with name >csn<_text, or continues a previously started code segment with that name.

    COMPACT MODEL: code here can be put into one segment but data needs to be put into several segments. The usual .DATA directive generates one data segment which is the "near data segment". You can generate other data segments by using the directive

    		.FARDATA >name<
    This begins or continues (possibly) initialized data segment with name >name<. For instance, suppose if you have the statements
    		.FARDATA data1
    		Var1 db ?
    To you can access Var1, you need to first get its segment number into ds. For instance, to set Var1 to the constant 1, you can do
    		mov dx, SEG Var1	; alternatively, use
    					; 	mov dx,data1
    		mov ds, ax		; this sets up ds
    		mov di, OFFSET Var1	; alternatively, use
    					;	lea di,Var1
    		mov [di], BYTE PTR 1
    LARGE MODEL: this is just the combination of the medium and the compact models.
    NOTE: the "assume" statement is useful in these models.
    This is an online system that allows you to get all kinds of technical information for pc programming. Please go to the link called "helppc" to get these files and installation information.


  1. Please restore the video mode after the end of your game! I do not want to restart my machine after testing each of your games!
  2. It is often good to ask the user if they want to replay the game, instead of simply quitting.
  3. It is a good idea to allow the user to set certain parameters for the game (level of play, etc). Do this interactively.
  4. ABSOLUTELY ESSENTIAL: give ONLINE instructions. The simplest is to provide one screen of information at the start of the game, containing the following information:
  5. Remember that the amount of time delay is critical for many games -- if it is too fast, it is impossible to play and if it is too slow, it is boring. But it is often difficult to ensure that the time delay that you have measured perfectly for your machine will be perfect for another machine. E.g., the game may be right for your 386 machine at home, but impossible for my 300 MHz Pentium II machine. Therefore, try to set these time delays as parameters, say, via an EQU statement:
    Better still, allow the user to select the time delay at the start of the game.


1. How do we divide the work among the team members?
I suggest you get together and try to hammer out as much details as possible (short of actually writing the code, but figuring out what functions you need to write, which interrupt numbers, graphics details, etc). Then you should have no trouble figuring out _some_ plan for partitioning the work. Here is one breakdown for a 3-person team:
	1) Main routine and overall logic of the game
	2) Graphics
	3) Input/Output, interface issues, help routines.
But it really depends on your game.


Click HERE to go to the top of page.