home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / JSAGE / ZSUS / PROGPACK / MEYERTUT.LBR / MEYER09.TZT / MEYER09.TXT
Text File  |  2000-06-30  |  18KB  |  440 lines

  1.              CP/M Assembly Language
  2.         Part IX: The Z80 Instruction Set
  3.               by Eric Meyer
  4.  
  5.      Up till now, we have been sticking to the basic Intel 8080
  6. instruction set, for the excellent reason that all CP/M systems
  7. come with 8080 assemblers and can run 8080 code.
  8.      Now, the fact is that the 8080 is 10 years old, and most
  9. CP/M computers today use more advanced CPUs that support the 8080
  10. codes as a subset.
  11.      The latest arrivals on this scene are the HD64180, a very
  12. fast 8-bit CPU, and the V20, actually a 16-bit CPU that can
  13. emulate both an 8088 and an 8-bit 8080.
  14.      But of course the most common chip for some years now has
  15. been the Zilog Z80 .
  16.      CP/M was designed and written for the 8080, but now runs
  17. primarily on Z80s.
  18.      The Z80 has a number of more powerful features -- but most
  19. CP/M systems give you no way to take advantage of them, at least
  20. not directly.
  21.      Worse, whoever wrote the CP/M BIOS for your computer may
  22. have made it positively difficult for you! For example, the
  23. original Osborne Exec BIOS code used, and didn't preserve, some
  24. of the extra Z80 registers on interrupts.     Thus some software
  25. (like TURBO Pascal) that uses the Z80 fully will crash unless you
  26. fix the BIOS. (There's a program called TPATCH.COM in the FOG
  27. library for this -- FOG-CPM.009.)
  28.      Despite all these obstacles, it's worthwhile to learn about
  29. the advantages of the Z80.
  30.      First, then, we'll jump from the Intel to the Zilog world,
  31. and look at a sampling of the Z80 CPU instruction set; finally
  32. we'll return for a look at some clever tricks to allow you to
  33. slip Z80 opcodes past an 8080 assembler.
  34.  
  35.  
  36. 1. Zilog Mnemonics
  37.      "Mnemonics" refers to the conventional names (like "RET")
  38. given to the various CPU instructions. You will have to use those
  39. that your assembler is designed to recognize.
  40.      DRI's 8080 assemblers (ASM, MAC) use Intel mnemonics. Most
  41. Z80 assemblers (like SLR's Z80ASM) use Zilog mnemonics. A few,
  42. like Microsoft's M80, allow you to use either or both.
  43.      It is unfortunate that Zilog decided to invent their own set
  44. of assembler mnemonics, but in many ways they are more logical
  45. than Intel's.
  46.      For example, all "load" instructions (loading some value
  47. into some register) have the mnemonic "LD"; an indirect value
  48. (address) is indicated by parentheses.
  49.      Single registers are denoted by one letter ("H"), pairs by
  50. two ("HL").
  51.      So we have:
  52.  
  53. INTEL        ZILOG             INTEL       ZILOG
  54. MVI  A,##    LD  A,##         LDA  ####       LD  A,(####)
  55. MOV  A,D    LD  A,D          STA  ####       LD  (####),A
  56. LXI  H,####    LD  HL,####         LDAX B       LD  A,(BC)
  57. LHLD ####    LD  HL,(####)         STAX B       LD  (BC),A
  58. SHLD ####    LD  (####),HL         MOV  A,M       LD  A,(HL)
  59.                      MOV  M,A       LD  (HL),A
  60.  
  61.      (Remember, LD HL,0080h puts the VALUE 0080 into HL, while LD
  62. HL,(0080h) puts the value AT ADDRESS 0080 into HL.)
  63.      Unfortunately they don't stop there, but go on to change the
  64. names of just about everything else too:
  65.  
  66. INTEL        ZILOG            INTEL        ZILOG
  67. CPI  ##     CP   ##         PUSH PSW        PUSH AF
  68. CMP  D        CP   D            POP  B        POP  BC
  69. ADI  ##     ADD  A,##        CC     ####        CALL C,####
  70. ADD  D        ADD  A,D        CNZ  ####        CALL NZ,####
  71. ACI  ##     ADC  A,##        JMP  ####        JP     ####
  72. ADC  D        ADC  A,D        RNC         RET  NC
  73. INR  D        INC  D            STC         SCF
  74. INX  H        INC  HL         CMC         CCF
  75. DCR  E        DEC  E            XCHG        EX     DE,HL
  76. DCX  B        DEC  BC         XTHL        EX     (SP),HL
  77. DAD  B        ADD  HL,BC        PCHL        JP     (HL)
  78.  
  79. and so on . . .
  80.      Actually it's pretty straightforward, and not too difficult
  81. to get the hang of it.
  82.      If you're going to do serious Z80 work you should get hold
  83. of a reference book.
  84.      I have the Z80 Instruction Handbook (by N. Wadsworth,
  85. published by Hayden).
  86.      It describes all the instructions, lists them
  87. alphabetically, and gives the actual hex codes (which you need to
  88. include Z80 codes using an 8080 assembler -- more on this later).
  89.  
  90.  
  91. 2. The Z80 CPU
  92.      Zilog designed the Z80 to be an extension of the 8080.
  93.      Thus it contains all the 8080 registers as a subset, and
  94. handles all the 8080 instructions (though they go by different
  95. names).
  96.      In addition, it has an extra set of registers, and a number
  97. of more powerful instructions.
  98.      First the extra registers: they are a complete set of
  99. duplicate or "alternate" registers A'-L', plus a pair of "index"
  100. registers IX, IY.
  101.  
  102.     8080 SUBSET             EXTRA Z80 REGISTERS
  103. +--------+---------+            +------------------+
  104. |   A     |    F    |            |         AF'       |
  105. +--------+---------+            +------------------+
  106. |   B     |    C    |            |         BC'       |
  107. +--------+---------+            +------------------+
  108. |   D     |    E    |            |         DE'       |
  109. +--------+---------+            +------------------+
  110. |   H     |    L    |            |         HL'       |
  111. +--------+---------+            +------------------+
  112. +------------------+            +------------------+
  113. |     SP       |            |         IX        |
  114. +------------------+            +------------------+
  115. |     PC       |            |         IY        |
  116. +------------------+            +------------------+
  117.  
  118.  
  119.      The "alternate" registers can be accessed by means of two
  120. new instructions:
  121.  
  122.     EX    AF,AF'     - exchange AF with AF'
  123.     EXX         - exchange BC,DE,HL with BC',DE',HL'
  124.  
  125.      Thus you have two separate "banks", each like an entire 8080
  126. register set.
  127.      Unfortunately, the advantage of these extra registers is not
  128. as great as it might be, because there are NO instructions to
  129. access them other than these two! (There are no commands LD
  130. HL',HL, etc.)
  131.      The only way to get a value from one bank to the other would
  132. be to PUSH it onto the stack, exchange banks, and POP it back --
  133. very slow and awkward.
  134.      You need to have two quite separate things going on at once
  135. to find the alternate registers useful. Most programmers don't
  136. use them at all. (This is why Osborne felt free to commandeer
  137. them to preserve the other registers during interrupts in the
  138. original Exec BIOS.)
  139.      The "index" registers, which are much more useful, are an
  140. extra set of registers that can be used to point to things. They
  141. work rather like the HL pair, but more powerfully.
  142.      Thus you can refer to the byte AT the address in IX just as
  143. you can the byte AT the address in HL (the 8080 "M register"):
  144.  
  145.     LD  A,(HL)    CP  (HL)       SUB    (HL)  . . .
  146.     LD  A,(IX)    CP  (IX)       SUB    (IX)  . . .
  147.  
  148.      But with the index register, you can also use an OFFSET:.
  149. (Note: some assemblers may require specifying the offset even if
  150. it's zero, e.g., LD A,(IX+0) above.)
  151.  
  152.     LD  A,(IX+4)  CP  (IX+4)  SUB  (IX+4) . . .
  153.  
  154.      This automatically refers to things that are a certain
  155. number of bytes past the address in IX, without having to keep
  156. altering the index register itself, as you would have to with HL:
  157. to add together the bytes (LIST), (LIST+4), and (LIST+9),
  158.  
  159.     LD  IX,LIST   is equivalent to     LXI  H,LIST
  160.     LD  A,(IX)             MOV  A,M
  161.     ADD A,(IX+4)             LXI  D,4
  162.     ADD A,(IX+9)             DAD  D
  163.                      ADD  M
  164.                      DAD  D
  165.                      LXI  D,5
  166.                      ADD  M
  167.  
  168.      Even without this extra power, the index registers would
  169. be a welcome addition just as an extra set of pointers, once you
  170. realize how quickly BC, DE, and HL can be exhausted.
  171.  
  172.  
  173. 3. More Power
  174.      Not only does the Z80 have more registers, it can do more
  175. with the ones it has. Out of all possible bytes 00 . . FF, there
  176. were a handful not defined in the 8080 instruction set, and Zilog
  177. has used them to implement new features on the Z80.
  178.      For example, the Z80 extends to BC and DE some of the
  179. features that only work with HL on the 8080: you can do:
  180.  
  181.     LD  BC,(####)       LD  DE,(####)
  182.     LD  (####),BC       LD  (####),DE
  183.  
  184. without having to get the value into HL first.
  185.      On the Z80 you can do 16-bit subtraction, as well as
  186. addition, more easily, because the ADC "add with carry" and SBC
  187. "subtract with carry" instructions work with the HL register
  188. pair. (Recall that you can subtract constants even on the 8080;
  189. if you want to subtract 10 from HL, rather than use DCX H ten
  190. times, you can write:
  191.  
  192.     LXI    D,-10
  193.     DAD    D
  194.  
  195.      Your assembler will translate -10 into FFF6h, and adding
  196. that will have the effect of subtracting 10. But the Carry flag
  197. is not affected, and there is no direct way to subtract the
  198. contents of DE from HL, in general.)
  199.      On the Z80 you can do not only ADD HL,DE but also
  200.  
  201.     ADC    HL,DE     and    SBC    HL,DE.
  202.  
  203.      Either of these is much nicer than the six separate ones
  204. required to do the same task on the 8080. (Remember what these
  205. were?)
  206.      There is a new set of bit operations that are handy for all
  207. sorts of purposes. Recall that the 8 bits in a byte are commonly
  208. numbered from 0 (least) to 7 (most significant).
  209.      You now have:
  210.  
  211.     BIT   #,reg    SET   #,reg    RES   #,reg
  212.  
  213. where # is 0-7, and "reg" is any 8-bit register, including A-L,
  214. or an indirect (HL) or (IX).
  215.      BIT tests the specified bit, setting the Zero flag if it's
  216. 0. SET sets the bit to 1; RES clears it to 0. Note that some of
  217. this could be done in 8080:
  218.      SET  3,A does the same as ORI  8 but these are easier to
  219. understand, and they work with many registers other than the
  220. Accumulator.
  221.      There are some nice new "shift" operations: e.g., SRL  A
  222. does the same as RLA (Intel RAL) except that a 0, rather than the
  223. Carry flag, is rotated into the empty bit, making division by 2
  224. far easier.
  225.      And all the rotate and shift instructions work on every
  226. register, not just A.
  227.      There are even Z80 instructions that are whole programming
  228. loops in themselves!
  229.      The easiest way to explain how "LDIR" works is to show you a
  230. loop that does the same thing in 8080:
  231.  
  232. LDIR        LOOP:    MOV  A,M
  233.             STAX D
  234.             INX  H
  235.             INX  D
  236.             DCX  B
  237.             MOV  A,B
  238.             ORA  C
  239.             JNZ  LOOP
  240.  
  241.      This is our old "move a string of bytes from one place to
  242. another" routine, all in one instruction!
  243.      Bytes are moved from the HL address to the DE address, one
  244. at a time, each time incrementing the pointers, for a total count
  245. in the BC register. There's also an instruction "LDDR", just the
  246. same except that it decrements HL and DE each time instead of
  247. incrementing them.
  248.      It's worth pointing out that these instructions are not just
  249. a convenience for the programmer; they are also much faster.
  250.      Each instruction in a program has to be fetched into the CPU
  251. from memory (at the PC pointer) before it is executed, a process
  252. which takes several clock cycles.
  253.      There are 10 instruction bytes in the LOOP: above (the JNZ
  254. takes three bytes), and they all have to be fetched again each
  255. time through the loop.
  256.      If you are moving 1000 bytes, that's 10,000 code bytes
  257. fetched, compared to 2 for LDIR.
  258.      Another loop instruction is "CPIR", an amazingly efficient
  259. way to find a byte in a string. Here again is an 8080 routine
  260. that does approximately the same thing:
  261.  
  262. CPIR            PUSH PSW
  263.         LOOP:    POP  PSW
  264.             CMP  M
  265.             INX  H
  266.             DCX  B
  267.             JZ   EXIT
  268.             PUSH PSW
  269.             MOV  A,B
  270.             ORA  C
  271.             JNZ  LOOP
  272.             POP  PSW
  273.         EXIT:
  274.  
  275.      This goes along a string, starting at the HL address, until
  276. it finds a match with the byte in A, or runs out of the count in
  277. BC. There is also an instruction "CPDR" that works downward, each
  278. time decrementing the address in HL.
  279.      Note that all the loop instructions move the pointer even on
  280. the last cycle; so they end up pointing one PAST the byte found,
  281. or the last one moved. So if you want to point to the first
  282. occurrence of BYTE in STRING, you would do something like
  283.  
  284.     LD    HL,STRING
  285.     LD    BC,LENGTH
  286.     LD    A,BYTE
  287.     CPIR
  288.     DEC    HL
  289.  
  290.      After a "CPIR" the Z flag will be set (just like a regular
  291. "CP") if a match was actually found.
  292.      There are "relative jump" instructions on the Z80, denoted
  293. "JR" instead of "JP".
  294.      With a Z80 assembler you can write either
  295.  
  296.     JP    LABEL        JP    Z,LABEL or
  297.     JR    LABEL        JR    Z,LABEL
  298.  
  299.      The difference is that if "LABEL" is nearby enough (within
  300. 128 bytes) a relative jump takes only two bytes, because instead
  301. of storing a two-byte address it stores a one-byte offset.
  302.      Also, code consisting of relative jumps can be moved bodily
  303. to any location in memory and will work just the same.
  304.      A particularly nice relative jump is "DJNZ", as it combines
  305. the common operations of Decrementing a counter (in this case the
  306. B register) and Jumping while NonZero:
  307.  
  308. DJNZ    LABEL    is equivalent to    DEC    B
  309.                     JR    NZ,LABEL
  310.  
  311.      All that in two bytes! (Note that it uses B alone, not BC.)
  312.      There are still more extended Z80 instructions, but these
  313. are about the most useful.
  314.  
  315.  
  316. 4. Faking Out ASM
  317.      All right, so you want the speed, power, and convenience of
  318. Z80 instructions.
  319.      The only question is, how? Well, you could buy a Z80
  320. assembler (like Z80ASM or M80), or experiment with one of several
  321. in the public domain (one of these is also called Z80ASM [FOG-
  322. CPM.111], but don't confuse it with SLR's product).
  323.      But for now, you don't have to buy anything, or even rewrite
  324. all your existing code in Zilog mnemonics, because you can patch
  325. Z80 opcodes right into your 8080 programs.
  326.      Remember it's just a matter of getting the right hex codes
  327. into the COM file, right? If your assembler won't do that
  328. automatically, you can do it by hand.
  329.      You will need a reference to tell you the hex equivalents of
  330. the Z80 instructions you want, for example:
  331.  
  332. LDIR        ED    B0    SBC    HL,BC        ED       42
  333. LDDR        ED    B8    SBC    HL,DE        ED       52
  334. CPIR        ED    B1    LD    BC,(xxyy)   ED       4B yy xx
  335. CPDR        ED    B9    LD    (xxyy),BC   ED       43 yy xx
  336. EX AF,AF'    08        LD    DE,(xxyy)   ED       5B yy xx
  337. EXX        D9        LD    (xxyy),DE   ED       53 yy xx
  338.  
  339.      So all you have to do to get an "LDIR" in the middle of your
  340. program is type in:
  341.  
  342.     DB    0EDH,0B0H
  343.  
  344.      Useful, but ugly. You could also define it as an equate:
  345.  
  346. LDIR    EQU    0B0EDH
  347.  
  348. so that you could have a nice, readable line like:
  349.  
  350.     DW    LDIR
  351.  
  352. instead. (Note that we had to reverse the byte order in the EQU
  353. statement because two-byte values [DW] get stored low byte first.
  354.       Also, when you specify a hex value that starts with a digit
  355. A-F, you must begin with a zero!
  356.      If you just typed in " B0EDH", ASM would think that was a
  357. label name, and complain that IT never got defined.)
  358.      If you have a macro assembler, like MAC, you can do this
  359. even more suavely and define LDIR as a macro:
  360.  
  361. LDIR    MACRO
  362.     DB    0EDH,0B0H
  363.     ENDM
  364.  
  365. so that now you can be just like the Z80 folks and type in:
  366.  
  367. LDIR
  368.  
  369.      In fact, the macro approach can easily be extended to
  370. include instructions that require ARGUMENTS.
  371.      For example, the BIT opcode is CB xx, where "xx" is 40 plus
  372. an amount that varies with the bit and the register. You will
  373. find that MAC, at least, assigns numerical values to register
  374. names as follows:
  375.  
  376. B=0, C=1, D=2, E=3, H=4, L=5, M=6, A=7.
  377.  
  378.      So you could define a BIT macro as follows:
  379.  
  380. BIT    MACRO    B,R
  381.     DB    0CBH,40H+(8*B)+R
  382.     ENDM
  383.  
  384.      Accordingly, BIT 0,A will produce CB 47; BIT 3,M gives CB
  385. 5E; and so on, much more easily than defining each of the
  386. (roughly 80!) possible BIT instructions separately.
  387.      Some MAC users received a file Z80.LIB along with MAC and
  388. HEXCOM. This is a library of macros just like BIT above, that
  389. allow you to use most extended Z80 instructions conveniently.
  390.      If you have it, browse through it. If you don't, you can
  391. create one yourself, following this example. (Beware of conflicts
  392. between your macro names and existing 8080 opcodes, or MAC
  393. reserved keywords. You'll have to call "SET" something like
  394. "SETB" instead, and so on.)
  395.  
  396.  
  397. 5. Caveats
  398.      There is one price to pay for using Z80 instructions: if you
  399. do, your code will run on most, but not all, CP/M systems.
  400.      It will run on a Z80 or compatible chip (like the HD64180,
  401. itself an extension of the Z80), but will not work -- in deed,
  402. will almost always crash -- on a computer with an 8080 or 8085
  403. CPU, or an IBM clone with V20 8080 emulation. (Zenith, for one,
  404. built a lot of 8085 machines that are still out there.)
  405.      You might want to build in a test for the presence of a Z80,
  406. and abort with an error message if you don't have one, before
  407. something less civil happens.
  408.      The best way to do this is to take advantage of a tiny
  409. difference in the Z80's use of the Parity flag. We haven't met
  410. this flag before, as its purpose is rather arcane: after an
  411. arithmetic or logical operation in the Accumulator, the 8080 P
  412. flag gets set or cleared according to whether the Parity of the
  413. result (the number of 1 bits) is Even or Odd.
  414.      As it happens, for arithmetic the Z80 uses the P flag (which
  415. it calls the Parity/Value flag) to indicate signed overflow
  416. instead, with the result that the operation "SUB A" (which zeros
  417. A) will set the P flag (for Even parity) on an 8080/85, but clear
  418. it (for no overflow) on a Z80!
  419.      So the following code can determine which CPU is running
  420.  
  421. (Intel)   SUB  A         (Zilog)   SUB  A
  422.       JPO  ISZ80               JP   PO,ISZ80
  423.       <abort with error>           <abort with error>
  424.    ISZ80: <ok, continue>    ISZ80: <ok, continue>
  425.  
  426.      In fact, this incompatibility is itself another reason why
  427. the P flag doesn't get used as often as Z or C.
  428.  
  429.  
  430. 6. Conclusion
  431.      If you start looking at the source code to many public
  432. domain programs, you will often find puzzling little things like
  433. DW 0B0EDH scattered around. Now you know what they are, and why
  434. they (usually) work.
  435.      In the future, we'll be working in some mixture of 8080 and
  436. Z80-speak. This can be slightly confusing, but it's hard to
  437. avoid; although CP/M systems don't come with Z80 support
  438. software, most programmers do use Z80 instructions. With a little
  439. effort, though, you can keep things straight.
  440.