home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / MISC / MAG05.ZIP / MAG05.TXT next >
Encoding:
Text File  |  1995-11-07  |  63.7 KB  |  1,701 lines

  1. Spellcaster presents:
  2.  
  3.  
  4. TTTTTTTTTT HH      HH EEEEEEEEEE    MM      MM    AAAA     GGGGGGGGG
  5.     TT     HH      HH EE            MMM    MMM   AA  AA   GG
  6.     TT     HH      HH EE            MM M  M MM  AA    AA  GG  
  7.     TT     HHHHHHHHHH EEEEEE        MM  MM  MM  AAAAAAAA  GG   
  8.     TT     HH      HH EE            MM      MM  AA    AA  GG    GGGG
  9.     TT     HH      HH EE            MM      MM  AA    AA  GG      GG
  10.     TT     HH      HH EEEEEEEEEE    MM      MM  AA    AA   GGGGGGGG
  11.  
  12.                                                         Issue 5
  13.                                                         5-11-95
  14.  
  15.  
  16.  
  17. ■ Index
  18.  
  19.         1. Introduction
  20.           1.1. About the magazine
  21.           1.2. About the author
  22.           1.3. Distribution
  23.           1.4. Contribuitions
  24.           1.5. Hellos and greets
  25.         2. Other types of variables
  26.         3. ASM Op-codes
  27.         4. Graphics, part 4 : Lookup Tables and Virtual Screens
  28.           4.1. Lookup Tables
  29.             4.1.1. What is this ?
  30.             4.1.2. How to use ?
  31.           4.2. Virtual Screens
  32.             4.2.1. What are they ?
  33.             4.2.2. How to implement ?
  34.         5. Hints and tips
  35.         6. Points of view
  36.         7. The adventures of Spellcaster, part 5
  37.  
  38. ■ 1. Introduction
  39.  
  40.   ■ 1.1. About the magazine
  41.  
  42.     Welcome to number 5 of 'The Mag', brought to you, as usual, by Spellcaster,
  43.   alias Diogo de Andrade.
  44.     This issue includes part IV of my mode 13h tutorial, more begginers
  45.   teaching, ASM Op-Codes, hints and tips, and another part of the adventures
  46.   of Spellcaster.
  47.     This magazine is dedicated to all the programmers and would-be programmers
  48.   out there, especially to those that (like me) can't access the Net easily to 
  49.   get valuable information, and to those who wish to learn how to program 
  50.   anything, from demos to games, passing through utilities and all sort of 
  51.   thing your mind can think of.
  52.  
  53.     Now, this is time for excuses... A friend of mine told me that I had an
  54.   error in my assembly article in issue 3. I searched for it, and I realized he
  55.   was right. In line 453, where it reads:
  56.  
  57.                      AX=256 =>   AL=1
  58.                                  AH=1
  59.  
  60.   you should read:
  61.  
  62.                      AX=256 =>   AL=0
  63.                                  AH=1
  64.  
  65.   Sorry about that unforgivable error...
  66.  
  67.     Someone told me that my mode 13h tutorial was a perfect ripoff of the
  68.   Asphyxia's VGA tuts... I don't totally deny the similarities, but I must say
  69.   that it isn't a ripoff. First, I must say that I'm a fan of the Asphyxia's
  70.   tutorial, and I think it's so perfect that I'm even following a similar
  71.   order. But, the explanations are differents, and most of the code. So,
  72.   if anyone out there has a chance, get the Asphyxia's tutorials. They're
  73.   great, especially if you're in demo coding. If you can't get them, ask me
  74.   for them. I have all until number 15. I'm just a big fan that I have something
  75.   to say to Denthor:
  76.  
  77.             "Hello... Love your tuts... Where can I contact you ?"
  78.  
  79.     Deep, wasn't it ?...
  80.  
  81.     When you read this magazine, I'll assume some things. First, I assume you
  82.   have Borland's Turbo Pascal, version 6 and upwards (and TASM for the assembly
  83.   tutorials). I'll also think you have a 80386 (or 386 for short; a 486 would
  84.   be even better), a load of patience and a sense of humor. This last is almost
  85.   essencial, because I don't receive any money for doing this, so I must have
  86.   fun doing it. I will also take for certain you have the 9th grade (or
  87.   equivelent). Finally, I will assume that you have the last issues of
  88.   'The Mag', and that you have grasped the concepts I tried to transmit. If
  89.   you don't have the issues, you can get them by mail, writing to one of the
  90.   adresses shown below (Snail mail and Email).
  91.  
  92.     As I stated above, this magazine will be made especially for those who don't
  93.   know where to get information, or want it all in the same place, and to those
  94.   who want to learn how to program, so I'll try to build knowledge, building up
  95.   your skills issue by issue. If you sometimes fail to grasp some concept, don't
  96.   despair; try to work it out.
  97.     That's what I did... Almost everything I know was learnt from painfull
  98.   experience. If you re-re-re-read the article, and still can't understand it,
  99.   just drop a line, by mail, or just plain forget it. Most of the things I 
  100.   try to teach here aren't linked to each other (unless I say so), so if you
  101.   don't understand something, skip it and go back to it some weeks later. It
  102.   should be clearer for you then. Likewise, if you see any terms or words you 
  103.   don't understand, follow the same measures as before.
  104.  
  105.     Ok, as I'm earing the Net gurus and other god-like creatures talking
  106.   already, I'm just going to explain why I use Pascal.
  107.   For starters, Pascal is a very good language, ideal for the beginner, like 
  108.   BASIC (yech!), but it's powerfull enough to make top-notch programms.
  109.   Also, I'll will be using assembly language in later issues, and Pascal makes
  110.   it so EASY to use. 
  111.   Finally, if you don't like my choice of language, you can stop whining. The
  112.   teory behind each article is very simple, and common with any of the main
  113.   languages (C, C++, Assembly - Yes, that's true... BASIC isn't a decent
  114.   language).
  115.  
  116.     Just one last thing... The final part of the magazine is a little story
  117.   made up by my distorted mind. It's just a little humor I like to write, and
  118.   it hasn't got nothing to do with programming (well, it has a little), but, 
  119.   as I said before, I just like to write it.
  120.  
  121.   ■ 1.2. About the author
  122.  
  123.     Ok, so I'm a little egocentric, but tell me... If you had the trouble of 
  124.   writing hundreds of lines, wouldn't you like someone to know you, even by 
  125.   name ?
  126.  
  127.     My name is Diogo de Andrade, alias Spellcaster, and I'm the creator, 
  128.   editor and writer of this magazine. 
  129.     I live in a small town called Setúbal, just near Lisbon, the capital of
  130.   Portugal... If you don't know where it is, get an encyclopedia, and look for
  131.   Europe. Then, look for Spain. Next to it, there's Portugal, and Setúbal is in
  132.   the middle.
  133.  
  134.     I'm 18 years old, and I just made it in to the university (if you do want
  135.   to know, I'm in the Technical Institute of Lisbon, Portugal), so I'm not 
  136.   a God-Like creature, with dozens of years of practice (I only program by 
  137.   eight years now, and I started in a Spectrum, progressing later to an Amiga.
  138.   I only program in the PC for a year or so), with a mega-computer (I own a 
  139.   386SX, 16 Mhz), that wear glasses with lens that look like the bottom of a 
  140.   bottle (I use glasses, but only sometimes), that has his head bigger than a 
  141.   pumpkin (I have a normal sized head) and with an IQ of over 220 (mine is 
  142.   actually something like 180). I can program in C, C++, Pascal, Assembly 
  143.   and even BASIC (yech!).
  144.  
  145.     So, if I am a normal person, why do I spend time writing this ?
  146.   Well, because I have the insane urge to write thousands of words every now
  147.   and then, and while I'm at it, I may do something productive, like teaching
  148.   someone. I may be young, but I know a lot about computers (how humble I am;
  149.   I know, modesty isn't one of my qualities).
  150.  
  151.     Just one more thing, if you ever program anything, please send to me... I
  152.   would love to see some work you got, maybe I could learn something with it.
  153.   Also, give me a greet in your program/game/demo... I love seeing my name.
  154.  
  155.   ■ 1.3. Distribution
  156.  
  157.     I don't really know when can I do another issue, so, there isn't a fixed
  158.   space of time between two issues. General rule, I will try to do one every two
  159.   weeks, maybe more or maybe less.
  160.     'The Mag' is available by the following means:
  161.  
  162.     - Snail Mail : My address is below, in the Contributions seccion... Just
  163.                    send me a disk and tell me what issues you want, and I
  164.                    will send you them...
  165.  
  166.     - E-Mail : If you E-mail me and ask me for some issues, I will Email you
  167.                back with the relevant issues attached.
  168.  
  169.     - BBS's : I don't know for sure what BBS's have or will have my magazine,
  170.               but I will try to post it in the Skyship BBS.
  171.               If you have a BBS and you want to receive 'The Mag', contact me.
  172.  
  173.                  Skyship BBS numbers: (351)+01-3158088
  174.                                       (351)+01-3151435
  175.  
  176.     By the end of this year (1995), I should have an Internet Page, and some
  177.   more BBS's in my list, besides some ftp's.
  178.  
  179.   ■ 1.4. Contributions
  180.  
  181.     I as I stated before, I'm not a God... I do make mistakes, and I don't 
  182.   have (always) the best way of doing things. So, if you think you've spotted
  183.   an error, or you have thought of a better way of doing things, let me know.
  184.   I'll be happy to receive anything, even if it is just mail saying 'Keep it 
  185.   up'. As all human beings, I need incentive.
  186.  
  187.     Also, if you do like to write, please do... Send in articles, they will be
  188.   welcome, and you will have the chance to see your names up in lights.
  189.     They can be about anything, for a review of a book or program that can
  190.   help a programmer, to a point of view or a moan. I'm specially interested in
  191.   articles explaining XMS, EMS, DMA and Soundblaster/GUS.
  192.  
  193.     If anyone out there has a question or wants to see an article about 
  194.   something in particular, feel free to write... All letters will be answered,
  195.   provided you give me your address.
  196.  
  197.     I'm also trying to start a new demo/game/utility group, and I need all sort 
  198.   of people, from coders (sometimes, one isn't enough), musicians (I can 
  199.   compose, but I'm a bit limited), graphics artists (I can't draw nothing) and
  200.   spreaders... I mean, by a spreader, someone who spreads things, like this mag.
  201.   If you have a BBS and you want it to include this magazine, feel free to
  202.   write me...
  203.  
  204.     You can also contact me personally, if study on the IST (if you don't
  205.   know what the IST is, you don't study there). I'm the freshman with the 
  206.   black hair and dark-brown eyes... The one that is sleeping in Linear
  207.   Algebra class... I recommend you to contact me personally, if you can,
  208.   especially if you are a member of the opposite sex (I'm a man, for those
  209.   of you who are wondering).
  210.  
  211.     My adress is:
  212.                  Praceta Carlos Manito Torres, nº4/6ºC
  213.                  2900 Setúbal
  214.                  Portugal
  215.  
  216.     Email: dgan@rnl.ist.utl
  217.  
  218.  
  219.   1.5. Hellos and greets
  220.  
  221.     I'll say hellos and thanks to all my friend, especially for those who put 
  222.   up with my constant whining:
  223.     Special greets go to Denthor from Asphyxia (for the excelent VGA trainers),
  224.   Draeden from VLA (for assembly tutorials), Joaquim Elder Guerreiro, alias
  225.   Dr.Shadow (Delta Team is still up), Alex "Darkfox" (thanks for letting me
  226.   use your BBS), Joäo Neves for sugestions, testing and BBS services, and all
  227.   the demo groups out there.
  228.     I also want to send a special greet to the first person (and the only one,
  229.   'till now) that responded to my magazine: Pedro Rocha (Thanks, man...).
  230.  
  231.  
  232. ■ 2. Other Types of Variables
  233.  
  234.     In issue one I told you of variables and variable's types. As I think I
  235.   said back then, the list was incomplete. The list of types is gigantic,
  236.   because Pascal gives you the hability to make new types of variables. I will
  237.   talk about that in a future issue. This article is about the variables of
  238.   type real and arrays of variables.
  239.  
  240.   ■ 2.1. Reals
  241.  
  242.     The real type of variables is, as the name sugests, a real. A real is a
  243.   number with a floating point. For example, if you divide 5 by 2, you would
  244.   get a real number (2.5).
  245.     You can use real numbers in the same way you use normal numbers. You can
  246.   even use the same operations.
  247.     You have, with reals, another operation, called /. It is equal to DIV,
  248.   but it doesn't discard the decimal part. So:
  249.  
  250.        Var A:Real
  251.        ........
  252.        ........
  253.        A:=5 Div 2;      -> Var A would be equal to 2
  254.        A:=5 / 2;        -> Var A would be equal to 2.5
  255.  
  256.     Reals have a downside, as everything in life. They are SLOWWWWW...
  257.     But they have great flexibility, because they can store gigantic numbers
  258.   and very small numbers.
  259.     Another thing peculiar about reals is that they store the number in
  260.   scientific format, so if you do Writeln of a real number, you would get
  261.   something like this:
  262.                            1.0000000000E+02
  263.  
  264.     This is equal to 100 ! This could appear if you did something like:
  265.  
  266.          Var A:Real;
  267.          Begin
  268.               A:=100;
  269.               WriteLn(A);
  270.          End;
  271.  
  272.     If you wanted a simpler representation of the number, you'd have to
  273.     change the
  274.               Writeln(A);
  275.     to
  276.               Writeln(A:7:2);
  277.     where 7 is the maximum number of numbers to display and 2 is the number
  278.     of decimal numbers.
  279.  
  280.   ■ 2.2. Arrays
  281.  
  282.     An array is like a table fo variables. It can store various variables
  283.   under a name and an index. So, every individual value in an array has a
  284.   designatory index.
  285.     For example, if you wanted to store the goals your favorite team has scored
  286.   in every game, you'd could do an array, like this:
  287.  
  288.      Var Goals:Array[1..36] Of Byte;
  289.      ..............
  290.      ..............
  291.      Goals[4]:=3;
  292.      ..............
  293.      ..............
  294.  
  295.     This tells the computer to store the value 3 in the forth position of the
  296.   'super-variable' Goals. So, your team has scored 3 goals in the forth match.
  297.     As you can see, arrays are very usefull. In the above example, the array
  298.   was unidimensional, because you only needed one index to access the desired
  299.   value. Now imagine that you wanted to store also the goals the other team
  300.   scored:
  301.  
  302.      Var Goals:Array[1..36,1..2] Of Byte;
  303.      ..............
  304.      ..............
  305.      Goals[1,1]:=3;
  306.      Goals[1,2]:=0;
  307.      ..............
  308.      ..............
  309.  
  310.     So, your team has won the first game, scoring 3 goals, while the other team
  311.   scored none ! This a bi-dimensional array.
  312.     Arrays can have how many dimensions you want, limited to the available
  313.   memory. Don't forget that the memory limit for variables in Pascal is 64Kb.
  314.     Oh, I almost forgot. When you define variable Goals, in the above example,
  315.   you said that each element of Goals was a variable of type Byte. You can
  316.   change that to whetever variable you want (strings, bytes, chars, word, etc).
  317.  
  318.     If you're very, very bright, you figured out something funny. Variable type
  319.   string is a special array of type char. So, when you do something like:
  320.  
  321.      Var A:String[10];
  322.  
  323.     is the almost the same as doing:
  324.  
  325.      Var A:Array[1..10] Of Char;
  326.  
  327.     Following this theory, you can access each char of a string individually,
  328.   specifying the char's index. Example:
  329.  
  330.      Var A:String;
  331.      ...............
  332.      ...............
  333.      A:='Spellchster';
  334.      A[7]:='a';
  335.      ...............
  336.      ...............
  337.  
  338.     A should now contain the correct word 'Spellcaster', instead of the wrong
  339.   'Spellchster'.
  340.  
  341.  
  342.  
  343. ■ 3. ASM Op-Codes
  344.  
  345.     This article was made by request. It is about the assembly instructions of
  346.   the 80x86 processor family. Not all of the instructions are here, because
  347.   most of them are only useful for advanced programmers. Not even I use them,
  348.   most of the time.
  349.     Notice that all timings are for best case and are just there to give you an
  350.   idea of the speed the instruction runs (to give you the hability to know if
  351.   a PUSH/POP is faster than a MOV instruction).
  352.  
  353.     imed  - Imediate value.
  354.     reg   - Register
  355.     reg8  - 8 bit register (ex. AL)
  356.     reg16 - 16 bit register (ex. AH)
  357.     reg32 - 32 bit register (ex. DX:AX)
  358.     mem   - Memory adress
  359.     mem8  - 8 bits of memory address
  360.     mem16 - 16 bits of memory address
  361.     mem32 - 32 bits of memory address
  362.     segreg- Segment register
  363.     acumm - Acumulator (AX, AL, DX:AX)
  364.  
  365.   ADD - Arithmetic Addition
  366.  
  367.         Usage: ADD dest,src
  368.         Modifies flags: AF CF OF PF SF ZF
  369.  
  370.         Adds "src" to "dest" and replacing the original contents of "dest".
  371.  
  372.                                  Clocks
  373.         Operands         808x  286   386   486
  374.  
  375.         reg,reg           3     2     2     1
  376.         mem,reg          16     7     7     3
  377.         reg,mem           9     7     6     2
  378.         reg,immed         4     3     2     1
  379.         mem,immed        17     7     7     3
  380.         accum,immed       4     3     2     1
  381.  
  382.   AND - Logical And
  383.  
  384.         Usage: AND dest,src
  385.         Modifies flags: CF OF PF SF ZF
  386.  
  387.         Performs a logical AND of the two operands replacing the destination
  388.         with the result.
  389.  
  390.                                 Clocks
  391.         Operands         808x  286   386   486
  392.  
  393.         reg,reg           3     2     2     1
  394.         mem,reg          16     7     7     3
  395.         reg,mem           9     7     6     1
  396.         reg,immed         4     3     2     1
  397.         mem,immed        17     7     7     3
  398.         accum,immed       4     3     2     1
  399.  
  400.   BSF - Bit Scan Forward (386+)
  401.   BSR - Bit Scan Reverse (386+)
  402.  
  403.         Usage: BSF dest,src
  404.                BSR dest,src
  405.         Modifies flags: ZF
  406.  
  407.         Scans source operand for first bit set.  Sets ZF if a bit is found
  408.         set and loads the destination with an index to first set bit.  Clears
  409.         ZF is no bits are found set.  BSF scans forward across bit pattern
  410.         (0-n) while BSR scans in reverse (n-0).
  411.  
  412.                                  Clocks
  413.         Operands         808x  286   386   486
  414.  
  415.         reg,reg           -     -   10+3n  6-42   (n is the number of bits in
  416.         reg,mem           -     -   10+3n  7-43    source operand.)
  417.         reg32,reg32       -     -   10+3n  6-42
  418.         reg32,mem32       -     -   10+3n  7-43
  419.  
  420.   BT - Bit Test (386+)
  421.  
  422.         Usage: BT dest,src
  423.         Modifies flags: CF
  424.  
  425.         The destination bit indexed by the source value is copied into the
  426.         Carry Flag.
  427.  
  428.                                  Clocks
  429.         Operands         808x  286   386   486
  430.  
  431.         reg16,immed8      -     -     3     3
  432.         mem16,immed8      -     -     6     6
  433.         reg16,reg16       -     -     3     3
  434.         mem16,reg16       -     -     12    12
  435.  
  436.   CALL - Procedure Call
  437.  
  438.         Usage: CALL destination
  439.         Modifies flags: None
  440.  
  441.         Pushes Instruction Pointer (and Code Segment for far calls) onto
  442.         stack and loads Instruction Pointer with the address of proc-name.
  443.         Code continues with execution at CS:IP.
  444.  
  445.   CLC - Clear Carry
  446.  
  447.         Usage: CLC
  448.         Modifies flags: CF
  449.  
  450.         Clears the Carry Flag.
  451.  
  452.                                  Clocks
  453.         Operands         808x  286   386   486
  454.  
  455.         none              2     2     2     2
  456.  
  457.   CLD - Clear Direction Flag
  458.  
  459.         Usage: CLD
  460.         Modifies flags: DF
  461.  
  462.         Clears the Direction Flag causing string instructions to increment
  463.         the SI and DI index registers.
  464.  
  465.                                  Clocks
  466.         Operands         808x  286   386   486
  467.  
  468.         none              2     2     2     2
  469.  
  470.   CLI - Clear Interrupt Flag (disable)
  471.  
  472.         Usage:  CLI
  473.         Modifies flags: IF
  474.  
  475.         Disables the maskable hardware interrupts by clearing the Interrupt
  476.         flag.
  477.  
  478.                                  Clocks
  479.         Operands         808x  286   386   486
  480.  
  481.         none              2     2     3     5
  482.  
  483.  
  484.   CMC - Complement Carry Flag
  485.  
  486.         Usage: CMC
  487.         Modifies flags: CF
  488.  
  489.         Toggles (inverts) the Carry Flag
  490.  
  491.                                  Clocks
  492.         Operands         808x  286   386   486
  493.  
  494.         none              2     2     2     2
  495.  
  496.   CMP - Compare
  497.  
  498.         Usage: CMP dest,src
  499.         Modifies flags: AF CF OF PF SF ZF
  500.  
  501.         Subtracts source from destination and updates the flags but does
  502.         not save result.  Flags can subsequently be checked for conditions.
  503.  
  504.                                  Clocks
  505.         Operands         808x  286   386   486
  506.  
  507.         reg,reg           3     2     2     1
  508.         mem,reg           9     7     5     2
  509.         reg,mem           9     6     6     2
  510.         reg,immed         4     3     2     1
  511.         mem,immed        10     6     5     2
  512.         accum,immed       4     3     2     1
  513.  
  514.   DEC - Decrement
  515.  
  516.         Usage: DEC dest
  517.         Modifies flags: AF OF PF SF ZF
  518.  
  519.         Unsigned binary subtraction of one from the destination.
  520.  
  521.                                  Clocks
  522.         Operands         808x  286   386   486
  523.  
  524.         reg8              3     2     2     1
  525.         mem              15     7     6     3
  526.         reg16/32          3     2     2     1
  527.  
  528.   DIV - Divide
  529.  
  530.         Usage: DIV src
  531.         Modifies flags: (AF,CF,OF,PF,SF,ZF undefined)
  532.  
  533.         Unsigned binary division of accumulator by source.  If the source
  534.         divisor is a byte value then AX is divided by "src" and the quotient
  535.         is placed in AL and the remainder in AH.  If source operand is a word
  536.         value, then DX:AX is divided by "src" and the quotient is stored in AX
  537.         and the remainder in DX.
  538.  
  539.                                  Clocks
  540.         Operands         808x   286   386   486
  541.  
  542.         reg8             80-90   14    14    16
  543.         reg16           144-162  22    22    24
  544.         reg32              -     -     38    40
  545.         mem8             86-96   17    17    16
  546.         mem16           150-168  25    25    24
  547.         mem32              -     -     41    40
  548.  
  549.   HLT - Halt CPU
  550.  
  551.         Usage: HLT
  552.         Modifies flags: None
  553.  
  554.         Halts CPU until RESET line is activated, NMI or maskable interrupt
  555.         received.  The CPU becomes dormant but retains the current CS:IP
  556.         for later restart.
  557.  
  558.                                  Clocks
  559.         Operands         808x  286   386   486
  560.  
  561.         none              2     2     5     4
  562.  
  563.   IN - Input Byte or Word From Port
  564.  
  565.         Usage: IN accum,port
  566.         Modifies flags: None
  567.  
  568.         A byte, word or dword is read from "port" and placed in AL, AX or
  569.         EAX respectively.  If the port number is in the range of 0-255
  570.         it can be specified as an immediate, otherwise the port number
  571.         must be specified in DX.  Valid port ranges on the PC are 0-1024,
  572.         though values through 65535 may be specified and recognized by
  573.         third party vendors and PS/2's.
  574.  
  575.                                  Clocks
  576.         Operands         808x  286   386    486
  577.  
  578.         accum,immed8    10/14   5     12     14
  579.         accum,DX         8/12   5     13     14
  580.  
  581.   INC - Increment
  582.  
  583.         Usage: INC dest
  584.         Modifies flags: AF OF PF SF ZF
  585.  
  586.         Adds one to destination unsigned binary operand.
  587.  
  588.                                  Clocks
  589.         Operands         808x  286   386   486
  590.  
  591.         reg8              3     2     2     1
  592.         reg16             3     2     2     1
  593.         reg32             3     2     2     1
  594.         mem              15     7     6     3
  595.  
  596.   INT - Interrupt
  597.  
  598.         Usage: INT num
  599.         Modifies flags: TF IF
  600.  
  601.         Initiates a software interrupt by pushing the flags, clearing the
  602.         Trap and Interrupt Flags, pushing CS followed by IP and loading
  603.         CS:IP with the value found in the interrupt vector table.  Execution
  604.         then begins at the location addressed by the new CS:IP
  605.  
  606.   IRET/IRETD - Interrupt Return
  607.  
  608.         Usage:  IRET
  609.                 IRETD  (386+)
  610.         Modifies flags: AF CF DF IF PF SF TF ZF
  611.  
  612.         Returns control to point of interruption by popping IP, CS
  613.         and then the Flags from the stack and continues execution at
  614.         this location.  CPU exception interrupts will return to the
  615.         instruction that cause the exception because the CS:IP placed
  616.         on the stack during the interrupt is the address of the offending
  617.         instruction.
  618.  
  619.   Jxx - Jump Instructions Table
  620.  
  621.        ┌─────────┬───────────────────────────────────┬─────────────────┐
  622.        │Mnemonic │ Meaning                           │ Jump Condition  │
  623.        ├─────────┼───────────────────────────────────┼─────────────────┤
  624.        │  JA     │ Jump if Above                     │ CF=0 and ZF=0   │
  625.        │  JAE    │ Jump if Above or Equal            │ CF=0            │
  626.        │  JB     │ Jump if Below                     │ CF=1            │
  627.        │  JBE    │ Jump if Below or Equal            │ CF=1 or ZF=1    │
  628.        │  JC     │ Jump if Carry                     │ CF=1            │
  629.        │  JCXZ   │ Jump if CX Zero                   │ CX=0            │
  630.        │  JE     │ Jump if Equal                     │ ZF=1            │
  631.        │  JG     │ Jump if Greater (signed)          │ ZF=0 and SF=OF  │
  632.        │  JGE    │ Jump if Greater or Equal (signed) │ SF=OF           │
  633.        │  JL     │ Jump if Less (signed)             │ SF <> OF        │
  634.        │  JLE    │ Jump if Less or Equal (signed)    │ ZF=1 or SF <> OF│
  635.        │  JMP    │ Unconditional Jump                │ unconditional   │
  636.        │  JNA    │ Jump if Not Above                 │ CF=1 or ZF=1    │
  637.        │  JNAE   │ Jump if Not Above or Equal        │ CF=1            │
  638.        │  JNB    │ Jump if Not Below                 │ CF=0            │
  639.        │  JNBE   │ Jump if Not Below or Equal        │ CF=0 and ZF=0   │
  640.        │  JNC    │ Jump if Not Carry                 │ CF=0            │
  641.        │  JNE    │ Jump if Not Equal                 │ ZF=0            │
  642.        │  JNG    │ Jump if Not Greater (signed)      │ ZF=1 or SF <> OF│
  643.        │  JNGE   │ Jump if Not Greater or Equal (sgn)│ SF <> OF        │
  644.        │  JNL    │ Jump if Not Less (signed)         │ SF=OF           │
  645.        │  JNLE   │ Jump if Not Less or Equal (signed)│ ZF=0 and SF=OF  │
  646.        │  JNO    │ Jump if Not Overflow (signed)     │ OF=0            │
  647.        │  JNP    │ Jump if No Parity                 │ PF=0            │
  648.        │  JNS    │ Jump if Not Signed (signed)       │ SF=0            │
  649.        │  JNZ    │ Jump if Not Zero                  │ ZF=0            │
  650.        │  JO     │ Jump if Overflow (signed)         │ OF=1            │
  651.        │  JP     │ Jump if Parity                    │ PF=1            │
  652.        │  JPE    │ Jump if Parity Even               │ PF=1            │
  653.        │  JPO    │ Jump if Parity Odd                │ PF=0            │
  654.        │  JS     │ Jump if Signed (signed)           │ SF=1            │
  655.        │  JZ     │ Jump if Zero                      │ ZF=1            │
  656.        └─────────┴───────────────────────────────────┴─────────────────┘
  657.  
  658.   JMP - Unconditional Jump
  659.  
  660.         Usage: JMP target
  661.         Modifies flags: None
  662.  
  663.         Unconditionally transfers control to "label".  Jumps by default
  664.         are within -32768 to 32767 bytes from the instruction following
  665.         the jump.  NEAR and SHORT jumps cause the IP to be updated while FAR
  666.         jumps cause CS and IP to be updated.
  667.  
  668.   LAHF - Load Register AH From Flags
  669.  
  670.         Usage:  LAHF
  671.         Modifies flags: None
  672.  
  673.         Copies bits 0-7 of the flags register into AH.  This includes flags
  674.         AF, CF, PF, SF and ZF other bits are undefined.
  675.  
  676.         AH := SF ZF xx AF xx PF xx CF
  677.  
  678.                                  Clocks
  679.         Operands         808x  286   386   486
  680.  
  681.         none              4     2     2     3
  682.  
  683.   LDS - Load Pointer Using DS
  684.  
  685.         Usage: LDS dest,src
  686.         Modifies flags: None
  687.  
  688.         Loads 32-bit pointer from memory source to destination register
  689.         and DS.  The offset is placed in the destination register and the
  690.         segment is placed in DS.  To use this instruction the word at the
  691.         lower memory address must contain the offset and the word at the
  692.         higher address must contain the segment.
  693.  
  694.                                  Clocks
  695.         Operands         808x  286   386   486
  696.  
  697.         reg16,mem32       16    7     7     6
  698.  
  699.  
  700.   LES - Load Pointer Using ES
  701.  
  702.         Usage: LES dest,src
  703.         Modifies flags: None
  704.  
  705.         Loads 32-bit pointer from memory source to destination register
  706.         and ES.  The offset is placed in the destination register and the
  707.         segment is placed in ES.  To use this instruction the word at the
  708.         lower memory address must contain the offset and the word at the
  709.         higher address must contain the segment.
  710.  
  711.                                  Clocks
  712.         Operands         808x  286   386   486
  713.  
  714.         reg,mem           16    7     7     6
  715.  
  716.   LFS - Load Pointer Using FS (386+)
  717.  
  718.         Usage: LFS dest,src
  719.         Modifies flags: None
  720.  
  721.         Loads 32-bit pointer from memory source to destination register
  722.         and FS.  The offset is placed in the destination register and the
  723.         segment is placed in FS.  To use this instruction the word at the
  724.         lower memory address must contain the offset and the word at the
  725.         higher address must contain the segment.
  726.  
  727.                                  Clocks
  728.         Operands         808x  286   386   486
  729.  
  730.         reg,mem           -     -     7     6
  731.  
  732.   LODS - Load String (Byte, Word or Double)
  733.  
  734.         Usage:  LODS    src
  735.                 LODSB
  736.                 LODSW
  737.                 LODSD  (386+)
  738.         Modifies flags: None
  739.  
  740.         Transfers string element addressed by DS:SI (even if an operand is
  741.         supplied) to the accumulator.   SI is incremented based on the size
  742.         of the operand or based on the instruction used.  If the Direction
  743.         Flag is set SI is decremented, if the Direction Flag is clear SI
  744.         is incremented.  You can use it with REP prefixes.
  745.  
  746.                                  Clocks
  747.         Operands         808x  286   386   486
  748.  
  749.         src             12/16   5     5     5
  750.  
  751.   LOOP - Decrement CX and Loop if CX Not Zero
  752.  
  753.         Usage: LOOP label
  754.         Modifies flags: None
  755.  
  756.         Decrements CX by 1 and transfers control to "label" if CX is not
  757.         Zero.  The "label" operand must be within -128 or 127 bytes of the
  758.         instruction following the loop instruction
  759.  
  760.   LOOPE/LOOPZ - Loop While Equal / Loop While Zero
  761.  
  762.         Usage:  LOOPE   label
  763.                 LOOPZ   label
  764.         Modifies flags: None
  765.  
  766.         Decrements CX by 1 (without modifying the flags) and transfers
  767.         control to "label" if CX <> 0 and the Zero Flag is set.  The
  768.         "label" operand must be within -128 or 127 bytes of the instruction
  769.         following the loop instruction.
  770.  
  771.   MOV - Move Byte or Word
  772.  
  773.         Usage: MOV dest,src
  774.         Modifies flags: None
  775.  
  776.         Copies byte or word from the source operand to the destination
  777.         operand.
  778.  
  779.                                  Clocks
  780.         Operands         808x  286   386   486
  781.  
  782.         reg,reg           2     2     2     1
  783.         mem,reg           9     3     2     1
  784.         reg,mem           8     5     4     1
  785.         mem,immed        10     3     2     1
  786.         reg,immed         4     2     2     1
  787.         mem,accum        10     3     2     1
  788.         accum,mem        10     5     4     1
  789.         segreg,reg16      2     2     2     3
  790.         segreg,mem16      8     5     5     9
  791.         reg16,segreg      2     2     2     3
  792.         mem16,segreg      9     3     2     3
  793.  
  794.   MOVS - Move String (Byte or Word)
  795.  
  796.         Usage:  MOVS    dest,src
  797.                 MOVSB
  798.                 MOVSW
  799.                 MOVSD  (386+)
  800.         Modifies flags: None
  801.  
  802.         Copies data from addressed by DS:SI (even if operands are given) to
  803.         the location ES:DI destination and updates SI and DI based on the
  804.         size of the operand or instruction used.  SI and DI are incremented
  805.         when the Direction Flag is cleared and decremented when the Direction
  806.         Flag is Set.  You can use it with REP prefixes.
  807.  
  808.                                  Clocks
  809.         Operands         808x  286   386   486
  810.  
  811.         dest,src          18    5     7     7
  812.  
  813.  
  814.   MUL - Unsigned Multiply
  815.  
  816.         Usage: MUL src
  817.         Modifies flags: CF OF (AF,PF,SF,ZF undefined)
  818.  
  819.         Unsigned multiply of the accumulator by the source. If "src" is
  820.         a byte value, then AL is used as the other multiplicand and the
  821.         result is placed in AX.  If "src" is a word value, then AX is
  822.         multiplied by "src" and DX:AX receives the result.  If "src" is
  823.         a double word value, then EAX is multiplied by "src" and EDX:EAX
  824.         receives the result.  The 386+ uses an early out algorithm which
  825.         makes multiplying any size value in EAX as fast as in the 8 or 16
  826.         bit registers.
  827.  
  828.                                  Clocks
  829.         Operands         808x  286   386   486
  830.  
  831.         reg8            70-77   13   9-14  13-18
  832.         reg16          118-113  21   9-22  13-26
  833.         reg32             -     -    9-38  13-42
  834.         mem8            76-83   16  12-17  13-18
  835.         mem16          124-139  24  12-25  13-26
  836.         mem32             -     -   12-21  13-42
  837.  
  838.   NEG - Two's Complement Negation
  839.  
  840.         Usage: NEG dest
  841.         Modifies flags: AF CF OF PF SF ZF
  842.  
  843.         Subtracts the destination from 0 and saves the 2s complement of
  844.         "dest" back into "dest".
  845.  
  846.                                  Clocks
  847.         Operands         808x  286   386   486
  848.  
  849.         reg               3     2     2     1
  850.         mem              16     7     6     3
  851.  
  852.   NOP - No Operation (90h)
  853.  
  854.         Usage: NOP
  855.         Modifies flags: None
  856.  
  857.         This is a do nothing instruction.  It results in occupation of both
  858.         space and time and is most useful for patching code segments.
  859.         (This is the original XCHG AL,AL instruction)
  860.  
  861.                                  Clocks
  862.         Operands         808x  286   386   486
  863.  
  864.         none              3     3     3     1
  865.  
  866.   NOT - One's Compliment Negation (Logical NOT)
  867.  
  868.         Usage: NOT dest
  869.         Modifies flags: None
  870.  
  871.         Inverts the bits of the "dest" operand forming the 1s complement.
  872.  
  873.                                  Clocks
  874.         Operands         808x  286   386   486
  875.  
  876.         reg               3     2     2     1
  877.         mem              16     7     6     3
  878.  
  879.   OR - Inclusive Logical OR
  880.  
  881.         Usage: OR dest,src
  882.         Modifies flags: CF OF PF SF ZF (AF undefined)
  883.  
  884.         Logical inclusive OR of the two operands returning the result in
  885.         the destination.  Any bit set in either operand will be set in the
  886.         destination.
  887.  
  888.                                  Clocks
  889.         Operands         808x  286   386   486
  890.  
  891.         reg,reg           3     2     2     1
  892.         mem,reg          16     7     7     3
  893.         reg,mem           9     7     6     2
  894.         reg,immed         4     3     2     1
  895.         mem8,immed8      17     7     7     3
  896.         mem16,immed16    25     7     7     3
  897.         accum,immed       4     3     2     1
  898.  
  899.   OUT - Output Data to Port
  900.  
  901.         Usage: OUT port,accum
  902.         Modifies flags: None
  903.  
  904.         Transfers byte in AL,word in AX or dword in EAX to the specified
  905.         hardware port address.  If the port number is in the range of 0-255
  906.         it can be specified as an immediate.  If greater than 255 then the
  907.         port number must be specified in DX.  Since the PC only decodes 10
  908.         bits of the port address, values over 1023 can only be decoded by
  909.         third party vendor equipment and also map to the port range 0-1023.
  910.  
  911.                                  Clocks
  912.         Operands         808x  286   386    486
  913.  
  914.         immed8,accum    10/14   3     10     16
  915.         DX,accum         8/12   3     11     16
  916.  
  917.   POP - Pop Word off Stack
  918.  
  919.         Usage: POP dest
  920.         Modifies flags: None
  921.  
  922.         Transfers word at the current stack top (SS:SP) to the destination
  923.         then increments SP by two to point to the new stack top.  CS is not
  924.         a valid destination.
  925.  
  926.                                  Clocks
  927.         Operands         808x  286   386   486
  928.  
  929.         reg16             8     5     4     4
  930.         reg32             4     -     -     4
  931.         segreg            8     5     7     3
  932.         mem16            17     5     5     6
  933.         mem32             5     -     -     6
  934.  
  935.   POPA/POPAD - Pop All Registers onto Stack (8086+)
  936.  
  937.         Usage:  POPA
  938.                 POPAD (386+)
  939.         Modifies flags: None
  940.  
  941.         Pops the top 8 words off the stack into the 8 general purpose 16/32
  942.         bit registers.   Registers are popped in the following order: (E)DI,
  943.         (E)SI, (E)BP, (E)SP, (E)DX, (E)CX and (E)AX.  The (E)SP value popped
  944.         from the stack is actually discarded.
  945.  
  946.                                  Clocks
  947.         Operands         808x  286   386   486
  948.  
  949.         none              -     19    24    9
  950.  
  951.  
  952.   POPF/POPFD - Pop Flags off Stack
  953.  
  954.         Usage:  POPF
  955.                 POPFD (386+)
  956.         Modifies flags: all flags
  957.  
  958.         Pops word/doubleword from stack into the Flags Register and then
  959.         increments SP by 2 (for POPF) or 4 (for POPFD).
  960.  
  961.                                  Clocks
  962.         Operands         808x  286   386   486
  963.  
  964.         none             8/12   5     5     9
  965.  
  966.   PUSH - Push Word onto Stack
  967.  
  968.         Usage:  PUSH src
  969.                 PUSH immed
  970.         Modifies flags: None
  971.  
  972.         Decrements SP by the size of the operand (two or four, byte values
  973.         are sign extended) and transfers one word from source to the stack
  974.         top (SS:SP).
  975.  
  976.                                  Clocks
  977.         Operands         808x  286   386   486
  978.  
  979.         reg16           11/15   3     2     1
  980.         reg32             -     -     2     1
  981.         mem16             16    5     5     4
  982.         mem32             -     -     5     4
  983.         segreg          10/14   3     2     3
  984.         immed             -     3     2     1
  985.  
  986.  
  987.   PUSHA/PUSHAD - Push All Registers onto Stack (8086+)
  988.  
  989.         Usage:  PUSHA
  990.                 PUSHAD (386+)
  991.         Modifies flags: None
  992.  
  993.         Pushes all general purpose registers onto the stack in the following
  994.         order: (E)AX, (E)CX, (E)DX, (E)BX, (E)SP, (E)BP, (E)SI, (E)DI.  The
  995.         value of SP is the value before the actual push of SP.
  996.  
  997.                                  Clocks
  998.         Operands         808x  286   386   486
  999.  
  1000.         none              -     19    24    11
  1001.  
  1002.   PUSHF/PUSHFD - Push Flags onto Stack
  1003.  
  1004.         Usage:  PUSHF
  1005.                 PUSHFD (386+)
  1006.         Modifies flags: None
  1007.  
  1008.         Transfers the Flags Register onto the stack.  PUSHF saves a 16 bit
  1009.         value while PUSHFD saves a 32 bit value.
  1010.  
  1011.                                  Clocks
  1012.         Operands         808x  286   386   486
  1013.  
  1014.         none            10/14   3     4     4
  1015.  
  1016.   RCL - Rotate Through Carry Left
  1017.  
  1018.         Usage: RCL dest,n
  1019.         Modifies flags: CF OF
  1020.  
  1021.            ┌─┐     ┌───────────────┐
  1022.         ┌─■│C│<■──■│7 <────────── 0│<─┐
  1023.         │  └─┘     └───────────────┘  │
  1024.         └─────────────────────────────┘
  1025.  
  1026.         Rotates the bits in the destination to the left "n" times with
  1027.         all data pushed out the left side re-entering on the right.  The
  1028.         Carry Flag holds the last bit rotated out.
  1029.  
  1030.                                  Clocks
  1031.         Operands         808x  286   386   486
  1032.  
  1033.         reg,1             2     2     9     3
  1034.         mem,1             15    7     10    4
  1035.         reg,CL           8+4n  5+n    9    8-30
  1036.         mem,CL          20+4n  8+n    10   9-31
  1037.         reg,immed8        -    5+n     9   8-30
  1038.         mem,immed8        -    8+n    10   9-31
  1039.  
  1040.   RCR - Rotate Through Carry Right
  1041.  
  1042.         Usage: RCR dest,n
  1043.         Modifies flags: CF OF
  1044.  
  1045.            ┌───────────────┐     ┌─┐
  1046.         ┌─>│7 ■─────────> 0│■───>│C│■─┐
  1047.         │  └───────────────┘     └─┘  │
  1048.         └─────────────────────────────┘
  1049.  
  1050.         Rotates the bits in the destination to the right "n" times with
  1051.         all data pushed out the right side re-entering on the left.  The
  1052.         Carry Flag holds the last bit rotated out.
  1053.  
  1054.                                  Clocks
  1055.         Operands         808x  286   386   486
  1056.  
  1057.         reg,1             2     2     9     3
  1058.         mem,1            15     7     10    4
  1059.         reg,CL            8    5+n    9    8-30
  1060.         mem,CL          20+4n  8+n    10   9-31
  1061.         reg,immed8        -    5+n    9    8-30
  1062.         mem,immed8        -    8+n    10   9-31
  1063.  
  1064.   REP - Repeat String Operation
  1065.  
  1066.         Usage:  REP
  1067.         Modifies flags: None
  1068.  
  1069.         Repeats execution of string instructions while CX<>0.  After
  1070.         each string operation, CX is decremented and the Zero Flag is
  1071.         tested.
  1072.  
  1073.                                  Clocks
  1074.         Operands         808x  286   386   486
  1075.  
  1076.         none              2     2     2
  1077.  
  1078.   REPE/REPZ - Repeat Equal/Repeat Zero
  1079.  
  1080.         Usage:  REPE
  1081.                 REPZ
  1082.         Modifies flags: None
  1083.  
  1084.         Repeats execution of string instructions while CX<>0 and the Zero
  1085.         Flag is set.  CX is decremented and the Zero Flag tested after
  1086.         each string operation.
  1087.  
  1088.                                  Clocks
  1089.         Operands         808x  286   386   486
  1090.  
  1091.         none              2     2     2
  1092.  
  1093.   REPNE/REPNZ - Repeat Not Equal/Repeat Not Zero
  1094.  
  1095.         Usage:  REPNE
  1096.                 REPNZ
  1097.         Modifies flags: None
  1098.  
  1099.         Repeats execution of string instructions while CX<>0 and the Zero
  1100.         Flag is clear. CX is decremented and the Zero Flag tested after
  1101.         each string operation. The combination of a repeat prefix and a
  1102.         segment override on processors other than the 386 may result in
  1103.         errors if an interrupt occurs before CX=0.
  1104.  
  1105.                                  Clocks
  1106.         Operands         808x  286   386   486
  1107.  
  1108.         none              2     2     2
  1109.  
  1110.   RET/RETF - Return From Procedure
  1111.  
  1112.         Usage:  RET  nBytes
  1113.                 RETF nBytes
  1114.                 RETN nBytes
  1115.         Modifies flags: None
  1116.  
  1117.         Transfers control from a procedure back to the instruction address
  1118.         saved on the stack.  "n bytes" is an optional number of bytes to
  1119.         release.  Far returns pop the IP followed by the CS, while near
  1120.         returns pop only the IP register.
  1121.  
  1122.   ROL - Rotate Left
  1123.  
  1124.         Usage: ROL dest,n
  1125.         Modifies flags: CF OF
  1126.  
  1127.         ┌─┐     ┌───────────────┐
  1128.         │C│<■┬─■│7 <────────── 0│<─┐
  1129.         └─┘  │  └───────────────┘  │
  1130.              └─────────────────────┘
  1131.  
  1132.         Rotates the bits in the destination to the left "n" times with
  1133.         all data pushed out the left side re-entering on the right.  The
  1134.         Carry Flag will contain the value of the last bit rotated out.
  1135.  
  1136.                                  Clocks
  1137.         Operands         808x  286   386   486
  1138.  
  1139.         reg,1             2     2     3     3
  1140.         mem,1            15     7     7     4
  1141.         reg,CL           8+4n  5+n    3     3
  1142.         mem,CL          20+4n  8+n    7     4
  1143.         reg,immed8        -    5+n    3     2
  1144.         mem,immed8        -    8+n    7     4
  1145.  
  1146.   ROR - Rotate Right
  1147.  
  1148.         Usage:  ROR     dest,n
  1149.         Modifies flags: CF OF
  1150.  
  1151.            ┌───────────────┐     ┌─┐
  1152.         ┌─>│7 ■─────────> 0│■─┬─>│C│   
  1153.         │  └───────────────┘  │  └─┘   
  1154.         └─────────────────────┘        
  1155.  
  1156.         Rotates the bits in the destination to the right "n" times with
  1157.         all data pushed out the right side re-entering on the left.  The
  1158.         Carry Flag will contain the value of the last bit rotated out.
  1159.  
  1160.                                  Clocks
  1161.         Operands         808x  286   386   486
  1162.  
  1163.         reg,1             2     2     3     3
  1164.         mem,1            15     7     7     4
  1165.         reg,CL           8+4n  5+n    3     3
  1166.         mem,CL          20+4n  8+n    7     4
  1167.         reg,immed8        -    5+n    3     2
  1168.         mem,immed8        -    8+n    7     4
  1169.  
  1170.   SAHF - Store AH Register into FLAGS
  1171.  
  1172.         Usage: SAHF
  1173.         Modifies flags: AF CF PF SF ZF
  1174.  
  1175.         Transfers bits 0-7 of AH into the Flags Register.  This includes
  1176.         AF, CF, PF, SF and ZF.
  1177.  
  1178.                                  Clocks
  1179.         Operands         808x  286   386   486
  1180.  
  1181.         none              4     2     3     2
  1182.  
  1183.   SAL/SHL - Shift Arithmetic Left/Shift Logical Left
  1184.  
  1185.         Usage:  SAL dest,n
  1186.                 SHL dest,n
  1187.         Modifies flags: CF OF PF SF ZF
  1188.  
  1189.         ┌─┐     ┌───────────────┐     ┌─┐
  1190.         │C│<───■│7 <────────── 0│<───■│0│
  1191.         └─┘     └───────────────┘     └─┘
  1192.  
  1193.         Shifts the destination left by "n" bits with zeroes shifted
  1194.         in on right.  The Carry Flag contains the last bit shifted out.
  1195.  
  1196.                                  Clocks
  1197.         Operands         808x  286   386   486
  1198.  
  1199.         reg,1             2     2     3     3
  1200.         mem,1            15     7     7     4
  1201.         reg,CL           8+4n  5+n    3     3
  1202.         mem,CL          20+4n  8+n    7     4
  1203.         reg,immed8        -    5+n    3     2
  1204.         mem,immed8        -    8+n    7     4
  1205.  
  1206.   SAR - Shift Arithmetic Right
  1207.  
  1208.         Usage: SAR dest,n
  1209.         Modifies flags: CF OF PF SF ZF (AF undefined)
  1210.  
  1211.            ┌───────────────┐     ┌─┐
  1212.         ┌─■│7 ──────────> 0│───■>│C│
  1213.         │  └───────────────┘     └─┘
  1214.         └───^
  1215.  
  1216.         Shifts the destination right by "n" bits with the current sign
  1217.         bit replicated in the leftmost bit.  The Carry Flag contains the
  1218.         last bit shifted out.
  1219.  
  1220.                                  Clocks
  1221.         Operands         808x  286   386   486
  1222.  
  1223.         reg,1             2     2     3     3
  1224.         mem,1            15     7     7     4
  1225.         reg,CL           8+4n  5+n    3     3
  1226.         mem,CL          20+4n  8+n    7     4
  1227.         reg,immed8        -    5+n    3     2
  1228.         mem,immed8        -    8+n    7     4
  1229.  
  1230.   SHL - Shift Logical Left
  1231.  
  1232.         See: SAL
  1233.  
  1234.   SHR - Shift Logical Right
  1235.  
  1236.         Usage: SHR dest,count
  1237.         Modifies flags: CF OF PF SF ZF (AF undefined)
  1238.  
  1239.         ┌─┐     ┌───────────────┐     ┌─┐
  1240.         │0│───■>│7 ──────────> 0│───■>│C│
  1241.         └─┘     └───────────────┘     └─┘
  1242.  
  1243.         Shifts the destination right by "count" bits with zeroes shifted
  1244.         in on the left.  The Carry Flag contains the last bit shifted out.
  1245.  
  1246.                                  Clocks
  1247.         Operands         808x  286   386   486
  1248.  
  1249.         reg,1             2     2     3
  1250.         mem,1           15+EA   7     7
  1251.         reg,CL           8+4n  5+n    3
  1252.         mem,CL        20+EA+4n 8+n    7
  1253.         reg,immed8        -    5+n    3
  1254.         mem,immed8        -    8+n    7
  1255.  
  1256.   STC - Set Carry Flag
  1257.  
  1258.         Usage: STC
  1259.         Modifies flags: CF
  1260.  
  1261.         Sets the Carry Flag to 1.
  1262.  
  1263.                                  Clocks
  1264.         Operands         808x  286   386   486
  1265.  
  1266.         none              2     2     2     2
  1267.  
  1268.   STD - Set Direction Flag
  1269.  
  1270.         Usage: STD
  1271.         Modifies flags: DF
  1272.  
  1273.         Sets the Direction Flag to 1 causing string instructions to
  1274.         auto-decrement SI and DI instead of auto-increment.
  1275.  
  1276.                                  Clocks
  1277.         Operands         808x  286   386   486
  1278.  
  1279.         none              2     2     2     2
  1280.  
  1281.   STI - Set Interrupt Flag
  1282.  
  1283.         Usage: STI
  1284.         Modifies flags: IF
  1285.  
  1286.         Sets the Interrupt Flag to 1, which enables recognition of all
  1287.         hardware interrupts.
  1288.  
  1289.                                  Clocks
  1290.         Operands         808x  286   386   486
  1291.  
  1292.         none              2     2     2     5
  1293.  
  1294.   STOS - Store String (Byte, Word or Doubleword)
  1295.  
  1296.         Usage: STOS dest
  1297.                STOSB
  1298.                STOSW
  1299.                STOSD
  1300.         Modifies flags: None
  1301.  
  1302.         Stores value in accumulator to location at ES:(E)DI (even if operand
  1303.         is given).  (E)DI is incremented/decremented based on the size of
  1304.         the operand (or instruction format) and the state of the Direction
  1305.         Flag. You can use it with REP prefixes.
  1306.  
  1307.                                  Clocks
  1308.         Operands         808x  286   386   486
  1309.  
  1310.         dest              11    3     4     5
  1311.  
  1312.  
  1313.   SUB - Subtract
  1314.  
  1315.         Usage: SUB dest,src
  1316.         Modifies flags: AF CF OF PF SF ZF
  1317.  
  1318.         The source is subtracted from the destination and the result is
  1319.         stored in the destination.
  1320.  
  1321.                                  Clocks
  1322.         Operands         808x  286   386   486
  1323.  
  1324.         reg,reg           3     2     2     1
  1325.         mem,reg          16     7     6     3
  1326.         reg,mem           9     7     7     2
  1327.         reg,immed         4     3     2     1
  1328.         mem,immed        17     7     7     3
  1329.         accum,immed       4     3     2     1
  1330.  
  1331.   XCHG - Exchange
  1332.  
  1333.         Usage: XCHG dest,src
  1334.         Modifies flags: None
  1335.  
  1336.         Exchanges contents of source and destination.
  1337.  
  1338.                                  Clocks
  1339.         Operands         808x  286   386   486
  1340.  
  1341.         reg,reg           4     3     3     3
  1342.         mem,reg          17     5     5     5
  1343.         reg,mem          17     5     5     3
  1344.         accum,reg         3     3     3     3
  1345.         reg,accum         3     3     3     3
  1346.  
  1347.  
  1348.   XOR - Exclusive OR
  1349.  
  1350.         Usage: XOR dest,src
  1351.         Modifies flags: CF OF PF SF ZF
  1352.  
  1353.         Performs a bitwise exclusive OR of the operands and returns
  1354.         the result in the destination.
  1355.  
  1356.                                  Clocks
  1357.         Operands         808x  286   386   486
  1358.  
  1359.         reg,reg           3     2     2     1
  1360.         mem,reg         16+EA   7     6     3
  1361.         reg,mem          9+EA   7     7     2
  1362.         reg,immed         4     3     2     1
  1363.         mem,immed       17+EA   7     7     3
  1364.         accum,immed       4     3     2     1
  1365.  
  1366.  
  1367.  
  1368. ■ 4. Graphics Part IV - Lookup Tables and Virtual Screens
  1369.  
  1370.     Well, this issues graphics tutorial will cover two of the more powerfull
  1371.   tools you can have. One increases speed, the other makes possible for you to
  1372.   play games. I'll start with the simpler one...
  1373.  
  1374.   ■ 4.1. Lookup Tables
  1375.  
  1376.     ■ 4.1.1. What is this ?
  1377.  
  1378.     As you may noticed, last issue's circle algorithm wasn't very good. It was
  1379.   too SLOWWWWW. How come ?
  1380.     Well, because the computer had to make a sine/cosine calculation for each
  1381.   pixel. Sine and cosines calculations are very slow, even with a maths
  1382.   co-processor.
  1383.     So, what can you do to prevent this ?
  1384.     Well, you can buy a Pentium or you can use Lookup Tables.
  1385.  
  1386.     The Lookup Tables are, like the name sugests, a table where you can search
  1387.   for various data.
  1388.     For example, you could do, in the above case, do a sine/cosine table, which
  1389.   holded the values of the sines and cosines of the 360°. As memory access is
  1390.   faster than any calculations, the circle algorithm would become faster.
  1391.  
  1392.     ■ 4.1.2. How to use ?
  1393.  
  1394.     First, before using the lookup tables, you'll have to allocate them. This
  1395.   is were the tricky stuff begins. A sine table would have to be a table with
  1396.   at least 360 real-type values. And you can't have only the sine values of the
  1397.   'normal' angles (this is, the integer ones). You must have middle angles. For
  1398.   the circle, you'll need about 1800 values, altough this values varies with
  1399.   the size of the circle (the smaller the circle is, the less values it needs).
  1400.   If you do some calculation, you would need 10800 bytes to store a sine table
  1401.   with a 0.2 precision. Adding this with the memory needed for the cosine table,
  1402.   you would have to spend 21600 bytes. This a third of the available memory
  1403.   Pascal allocates for variables.
  1404.     As a normal Pascal array isn't praticle, we must use pointers (for an
  1405.   explanation of pointers, get issue 1. It has an article on pointers).
  1406.     To generate the table, we must first setup some types and variables:
  1407.  
  1408.     Type Table=Array[0..1799] Of Real;
  1409.          PTable=^Table;
  1410.  
  1411.     Var Sines:Ptable;
  1412.         Cosines:Ptable;
  1413.  
  1414.     Then, you must initialize the table:
  1415.  
  1416.     Procedure InitTables;
  1417.     Var A:Word;
  1418.         B:Real;
  1419.     Begin
  1420.          Getmem(Sines,Sizeof(Sines^));
  1421.          Getmem(Cosines,Sizeof(Cosines^));
  1422.          B:=0;
  1423.          For A:=0 To 1799 Do
  1424.          Begin
  1425.               Sines^[A]:=Sin(B);
  1426.               Cosines^[A]:=Cos(B);
  1427.               B:=B+0.005;
  1428.          End;
  1429.     End;
  1430.  
  1431.     After this, you can use it in the circle algorithm...
  1432.  
  1433.     Procedure Circle(X,Y,R:Integer;Col:Byte);
  1434.     Var Px,Py:Integer;
  1435.         Deg:Word;
  1436.     Begin
  1437.          For Deg:=0 to 1799 Do
  1438.          Begin
  1439.               Px:=R*Sines^[Deg]+X;
  1440.               Py:=R*Cosines^[Deg]+Y;
  1441.               PutPixel(Px,Py,Col);
  1442.          End;
  1443.     End;
  1444.  
  1445.     ...and when you're program is over, you delete the tables of the memory:
  1446.  
  1447.     Procedure ClearTables;
  1448.     Begin
  1449.          Freemem(Sines,Sizeof(Sines^));
  1450.          Freemem(Cosines,Sizeof(Cosines^));
  1451.     End;
  1452.  
  1453.     This is pretty straighforward. The only quirk is the pointers, but if you
  1454.   have issue 1 and you have read the article on pointers, you should be fine.
  1455.     With this issue, you should have a file called 'Tunnel.Pas'. It is last
  1456.   issue's program without the lines part and rewriten to use the new circle
  1457.   algorithm.
  1458.  
  1459.   ■ 4.2. Virtual Screens
  1460.  
  1461.     ■ 4.2.1. What are they ?
  1462.  
  1463.     Virtual screens are one of the most powerfull resources you can have in a
  1464.   program you make. Almost every program I make uses them.
  1465.     I can't quite explain what are they. Think of them as an extra screen, a
  1466.   screen where you can write what you want, without changing the current
  1467.   display.
  1468.  
  1469.     Imagine the following example: you are making a game, a horizontal shoot'em
  1470.   up, where a ship goes around kicking some alien butt around, in front of a
  1471.   scrolling background. For every moment of the game, you would have to do
  1472.   this:
  1473.  
  1474.                 1. Update variables
  1475.                 2. Clear Screen
  1476.                 3. Scroll Background
  1477.                 4. Put Your Ship
  1478.                 5. Put Alien Ships
  1479.                 6. Return to Step 1
  1480.  
  1481.     This looks fine, but have some errors. Note that between step 1 and 3, the
  1482.   screen would become totally black. At the rate a computer goes, this would
  1483.   make a terrible flicker on the screen.
  1484.     But how can we mend this ?
  1485.     Using Virtual Screens ! If you wrote all the new image in a spare screen,
  1486.   a screen you can't see, and then you copied that screen to the real screen,
  1487.   the flicker would cease... Now, the course of the program should be something
  1488.   like this:
  1489.  
  1490.                 1. Update variables
  1491.                 2. Clear Virtual Screen
  1492.                 3. Scroll Background In Virtual Screen
  1493.                 4. Put Your Ship In Virtual Screen
  1494.                 5. Put Alien Ships In Virtual Screen
  1495.                 6. Copy Virtual Screen To Real Screen
  1496.                 7. Return to Step 1
  1497.  
  1498.     ■ 4.2.2. How to implement ?
  1499.  
  1500.     Well, remember when I said in the first part, the mode 13h is a linear
  1501.   mode. Also, if you do calculations, you'll find out that a MCGA screen,
  1502.   320x200x256 uses 64000 bytes of memory. Knowing that, you can define virtual
  1503.   screens. Virtual screens are commonly called Virtual Pages, or just Pages.
  1504.     First, you have to define some variables:
  1505.  
  1506.            Const Npages=2
  1507.                  VGA=$A000
  1508.  
  1509.            Var Virt:Array[1..Npages] Of Pointer;
  1510.                VP:Array[1..Npages] Of Word;
  1511.  
  1512.     'Npages' represents the number of virtual pages you use. I usually use two,
  1513.   sometimes three. Don't forget, the more pages you use, the less memory you'll
  1514.   have for other stuff... The two variables (Virt and VP) store the Virtual
  1515.   Pages (Virt) and their Segment (Virt). The segment of the page is very
  1516.   important, because it forms the basis for all drawing operations.
  1517.     In the second  stage, you'll have to initialize the pages:
  1518.  
  1519.     Procedure InitVirt;
  1520.     Var A:Byte;
  1521.     Begin
  1522.          For A:=1 To Npages Do
  1523.          Begin
  1524.               GetMem(Virt[A],64000);
  1525.               VP[A]:=Segment(Virt[A]^);
  1526.          End;
  1527.     End.
  1528.  
  1529.     This procedure generates a 64000 bytes space full of 0's. We know have our
  1530.   virtual screens.
  1531.     Now, to use our virtual screens, you'll have to re-write the drawing
  1532.   procedures. I'll only give you the re-writen PutPixel procedure... It's pretty
  1533.   easy to figure out the other...
  1534.  
  1535.     Procedure PutPixel(X,Y:word;Col:Byte;Where:Word);
  1536.     Begin
  1537.          Mem[Where:(y*320)+x]:=Col;
  1538.     End;
  1539.  
  1540.     Now, everytime you call the PutPixel procedure, you'll have to tell him
  1541.   where to put the pixel... Examples:
  1542.  
  1543.     PutPixel(100,100,10,VGA);        -> This puts a pixel in (100,100) in
  1544.                                         the normal screen.
  1545.  
  1546.     PutPixel(100,100,10,VP[1]);      -> This puts a pixel in (100,100) in
  1547.                                         the first virtual page.
  1548.  
  1549.     PutPixel(100,100,10,VP[2]);      -> This puts a pixel in (100,100) in
  1550.                                         the second virtual page...
  1551.  
  1552.     So, as you can see, it is pretty easy to change the procedures... You just
  1553.   had the Where parameter and take it in account.
  1554.     But, I hear you cry, how can we see the pixels that we have in the virtual
  1555.   pages ?
  1556.     That's easy... You copy the contents of the virtual page to the VGA page.
  1557.   You don't have to clear the screen, because the information in the virtual
  1558.   page overwrites the information the VGA page. You can use the following
  1559.   procedure:
  1560.  
  1561.     Procedure CopyPage(From,Too:Word);
  1562.     Begin
  1563.          WaitVbl;
  1564.          Move(Mem[From:0],Mem[Too:0],64000);
  1565.     End;
  1566.  
  1567.     This copies 64000 bytes from location From:0 to location Too:0. This
  1568.   procedure can also be used to copy from page 1 to page 2, etc... Examples:
  1569.  
  1570.     CopyPage(VGA,PG[1]);        -> This copies the contents of the VGA screen
  1571.                                    to the first virtual page.
  1572.     CopyPage(PG[1],PG[2]);      -> This copies the contents of the first virtual
  1573.                                    page to the second page.
  1574.     CopyPage(PG[2],VGA);        -> This copies the contents of page two to the
  1575.                                    VGA page...
  1576.  
  1577.     I think the principle behind virtual screens is pretty easy to understand,
  1578.   and once you understand it, it is easy to implement, and when it is
  1579.   implemented, your programms will definetly improve...
  1580.     Just one more thing... Don't waste time trying to figure out how to change
  1581.   the palette in a virtual screen... There is only ONE palette, and that
  1582.   palette is used for everything in the screen, including the virtual screens.
  1583.  
  1584.  
  1585.  
  1586. ■ 5. Hints and Tips
  1587.  
  1588.                 *   - Begginners tip
  1589.                 **  - Medium tip
  1590.                 *** - Advanced tip
  1591.  
  1592.  
  1593.     - Extended Sintax (**)
  1594.  
  1595.       If you write {$X+} in the start of a program, you'll enable the Pascal's
  1596.       extended sintax feature. This feature enables you to use functions as
  1597.       they were procedures. In that case, the result would be discarded. The
  1598.       extended sintax enables to do an instruction like:
  1599.  
  1600.                Readkey;
  1601.  
  1602.       instead of
  1603.  
  1604.               C:=Readkey;
  1605.  
  1606.       So, you'll save up a variable and some typing...
  1607.  
  1608.     - Speeding up some routines (**)
  1609.  
  1610.       Sometimes, routines can be optimised by some clever thinking. For
  1611.       instance, you should pre-calculate every value you can. For example, let's
  1612.       assume that used the Sin(PI)+Cos(PI/2) expression (I know this is two, but
  1613.       that's not the point). If you pre-calculate this and store that value in a
  1614.       variable, using the variable from thereafter, your program could be get a
  1615.       major speed up, specially if you used to calculate this inside loops.
  1616.  
  1617.  
  1618. ■ 6. Points of view
  1619.  
  1620.     Well, this issue is almost over, but don't despair... In a couple of weeks
  1621.   or so there will be another one... I think this is the largest issue 'till
  1622.   now (speaking of the text file alone), with over 60k in size... That means
  1623.   more than 61440 characters... My fingers ache just thinking of it.
  1624.  
  1625.     I have no idea of what I'm going to talk today (as in every other days, as
  1626.   the matter of fact...).
  1627.     I think I'll talk about extra-terrestrial life and it's influence in
  1628.   games...
  1629.     I just finishing reading COSMOS by Carl Sagan. I know this is an old book,
  1630.   but I needed something to read during classes. The book is very interesting,
  1631.   because it speaks of aliens and alien lifeforms. As I'm a sci-fi fanatic, I
  1632.   just love it. But, at the same time I love it, I hate it, because it tells me
  1633.   that I'll probably never see aliens and another worlds, unless I put myself
  1634.   in cryogenic sleep when I have my mega-corporation (something like Spellcaster
  1635.   Software Systems) and I'm mega-wealthy.
  1636.     But, if I can't see aliens, I can dream of them and make them real in my
  1637.   games and demos. This has been done before countless times by big software
  1638.   companies. But, everyone of them has different ideas on how aliens are and
  1639.   how they behave. The description I like most is in David Braben's "Elite II",
  1640.   because in his game, aliens aren't all bad or all good. There's a mix of the
  1641.   two, like there is here on good old Earth.
  1642.  
  1643.     I don't know when is the next issue gonna come, because I'm now re-starting
  1644.   an old project, called 'Titans', that I had to drop because lack of memory.
  1645.   The game is based on the Battletech board game and books (I have writen a
  1646.   couple of books now, that have something to do with Battlemechs, altough
  1647.   their part is relatively small. Besides, they are in portuguese). It is a
  1648.   multi-player strategy game, with lots of missions and expansion capabilities.
  1649.   I'm also working on a movie-demo. A movie-demo is a demo with a story behind
  1650.   it, presented to look like a movie. It will have lots of effects, specially
  1651.   solid 3d poligons. So, if anyone out there wants to lend me a hand on these
  1652.   two projects, just contact me... I need help especially in the graphics
  1653.   department, and in the Soundsystem programming.
  1654.     Next issue, I think I'm gonna talk about file accessing (for beginners and
  1655.   more advanced programmers). I'm also gonna teach you how to read a PCX file
  1656.   in the Graphics section. There will be more other stuff, but I still don't
  1657.   know what more to put. If you have any sugestions, mail me...
  1658.  
  1659.     Well, my friends, I must bid you farewell now... Enjoy yourself with:
  1660.  
  1661.  
  1662.  
  1663. ■ 7. The adventures of Spellcaster, the rebel programmer of the year 2018.
  1664.  
  1665.   Episode 5 - A New Dawn
  1666.  
  1667.     The Brotherhood of the Rebel Programmer was going nicely for a month now.
  1668.   Our effort to destroy Comptel was in the meanwhile limited to robbing some
  1669.   computer stores to get the material to penetrate the Gate. We were just in
  1670.   need of some last pieces of equipment. Unfortunely,  the components we were
  1671.   looking for were rare, and they were all kept in Comptel's High Security
  1672.   Stores, the COHISS. Me and Deathripper had a plan, but we needed someone else
  1673.   to drive the getaway jetcar.
  1674.   - So, what are we going to do, man ? - asked Deathripper.
  1675.   - I have a brilliant plan, Karl, - I said ironically - let's walk down the
  1676.     street, aproach the first person we see and say to him: "Excuse me sir,
  1677.     would you mind driving the jetcar in a dangerous and pottencially suicidal
  1678.     mission against Comptel ?".
  1679.   - Don't be stupid, Spellcaster... We must know the person...
  1680.   - Well, last time I checked, all my friends are now friends of Comptel, and
  1681.     they won't help us.
  1682.   - I know someone that could help us, but...
  1683.   - But what ?! - I asked, entusiatically.
  1684.   - ...but, she's in the Sega Corporate Prison.
  1685.   - She ?! You mean a women ?!
  1686.   - Yes... A women... So ?
  1687.   - So ?! We need a man for the job, not a bloody woman !
  1688.   - That 'bloody woman' is my sister... And she is as good with the computer
  1689.     as you and me...
  1690.   I stared at Gundsen. I noticed by his face that in this momment he didn't
  1691.   cared about our plan... He just wanted to save his sister...
  1692.   - Ok, ok... - I said, making Karl smile.
  1693.     In a couple of days, another escape plan was made, again using my Final
  1694.   Judgement Virus... At the end of the night, we went to the Sega Prison,
  1695.   looking down to it from a hill. Morning was breaking, and the sun was rising
  1696.   from behind the mountains ahead of us. A ray of light cut the darkness and
  1697.   hitted me in the eyes. I semi-closed my eyes, seeing the sky in tones of
  1698.   orange. A new dawn for the Brotherhood was about to appear...
  1699.  
  1700.                                              See you in the next issue
  1701.                                             Diogo "SpellCaster" Andrade