home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / c128 / text / 64docs.arc / 64DOC.TXT next >
Text File  |  1993-09-16  |  60KB  |  1,414 lines

  1. ==============================================================================
  2. 64 Documentation
  3. by Jarkko Sonninen, Jouko Valta, John West, and Marko M"akel"a
  4.    (sonninen@lut.fi, jopi@stekt.oulu.fi, john@ucc.gu.uwa.edu.au,
  5.     msmakela@hylk.helsinki.fi)
  6.  
  7. [Ed's Note: I'm leaving this file as is because of its intention to
  8. serve as a reference guide, and not necessarily to be presented in
  9. article format. The detail and clarity with which the authors have
  10. presented the material is wonderful!!]
  11.  
  12. #
  13. # $Id: 64doc,v 1.3 93/06/21 13:37:18 jopi Exp $
  14. #
  15. # This file is part of Commodore 64 emulator
  16. #      and Program Development System.
  17. #
  18. # See README for copyright notice
  19. #
  20. # This file contains documentation for 6502/6510/8502 instruction set.
  21. #
  22. # Written by 
  23. #   Jarkko Sonninen (sonninen@lut.fi)
  24. #   Jouko Valta     (jopi@stekt.oulu.fi)
  25. #   John West       (john@ucc.gu.uwa.edu.au)
  26. #   Marko M"akel"a  (msmakela@hylk.helsinki.fi)
  27. #
  28. # $Log: 64doc,v $
  29. # Revision 1.3  93/06/21  13:37:18  jopi
  30. #  X64 version 0.2 PL 0
  31. # Revision 1.2  93/06/21  13:07:15  jopi
  32. # *** empty log message ***
  33. #
  34. #
  35.  
  36.                 6510 Instructions by Addressing Modes
  37.  
  38.         ++++++++ Positive ++++++++++    -------- Negative ----------
  39.         00      20      40      60      80      a0      c0      e0      mode
  40.  
  41. +00     BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX  Impl/immed
  42. +01     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir,x)
  43. +02      t       t       t       t      NOP*t   LDX     NOP*t   NOP*t  ? /immed
  44. +03     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB* (indir,x)
  45. +04     NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX  Zeropage
  46. +05     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  47. +06     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  48. +07     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  49.  
  50. +08     PHP     PLP     PHA     PLA     DEY     TAY     INY     INX  Implied
  51. +09     ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC  Immediate
  52. +0a     ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP  Accu/impl
  53. +0b     ANC**   ANC**   ASR**   AR
  54.  Cancel 
  55.  
  56. /duck/mailserv/hacking> 
  57.  Interrupt 
  58.  
  59. /duck/mailserv/hacking> 
  60.  
  61.                 6510 Instructions by Addressing Modes
  62.  
  63.         ++++++++ Positive ++++++++++    -------- Negative ----------
  64.         00      20      40      60      80      a0      c0      e0      mode
  65.  
  66. +00     BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX  Impl/immed
  67. +01     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir,x)
  68. +02      t       t       t       t      NOP*t   LDX     NOP*t   NOP*t  ? /immed
  69. +03     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB* (indir,x)
  70. +04     NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX  Zeropage
  71. +05     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  72. +06     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  73. +07     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  74.  
  75. +08     PHP     PLP     PHA     PLA     DEY     TAY     INY     INX  Implied
  76. +09     ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC  Immediate
  77. +0a     ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP  Accu/impl
  78. +0b     ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC* Immediate
  79. +0c     NOP*    BIT     JMP     JMP     STY     LDY     CPY     CPX  Absolute
  80. +0d     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  81. +0e     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  82. +0f     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  83.  
  84. +10     BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ  Relative
  85. +11     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir),y
  86. +12      t       t       t       t       t       t       t       t      ?
  87. +13     SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB* (indir),y
  88. +14     NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP* Zeropage,x
  89. +15     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  90. +16     ASL     ROL     LSR     ROR     STX y)  LDX y)  DEC     INC     -"-
  91. +17     SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP     ISB     -"-
  92.  
  93. +18     CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED  Implied
  94. +19     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  Absolute,y
  95. +1a     NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP* Implied
  96. +1b     SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB* Absolute,y
  97. +1c     NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP* Absolute,x
  98. +1d     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  99. +1e     ASL     ROL     LSR     ROR     SHX**y) LDX y)  DEC     INC     -"-
  100. +1f     SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP     ISB     -"-
  101.  
  102.         Legend:
  103.  
  104.         t       Jams the machine
  105.         *t      Jams very rarely
  106.         *       Undocumented command
  107.         **      Unusual operation
  108.         y)      indexed using IY instead of IX
  109.  
  110.  
  111.  
  112.                 6510/8502 Undocumented Commands
  113.  
  114.          -- A brief explanation about what may happen while
  115.                 using don't care states.
  116.  
  117.  
  118.         ANE $8B         AC = (AC | #$EE) & IX & #byte
  119.                         same as
  120.                         AC = ((AC & #$11 & IX) | ( #$EE & IX)) & #byte
  121.  
  122.                         In real 6510/8502 the internal parameter #$11 may
  123.                         occasionally be #$10, #$01 or even #$00. This occurs
  124.                         probably when the VIC halts the processor right between
  125.                         the two clock cycles of this instruction.
  126.  
  127.         LXA $AB         C=Lehti:   AC = IX = ANE
  128.                         Alternate: AC = IX = (AC & #byte)
  129.  
  130.                         TXA and TAX have to be responsible for these.
  131.  
  132.  
  133.         SHA $93,$9F     Store (AC & IX & (ADDR_HI + 1))
  134.         SHX $9E         Store (IX & (ADDR_HI + 1))
  135.         SHY $9C         Store (IY & (ADDR_HI + 1))
  136.         SHS $9B         SHA and TXS, where X is replaced by (AC & IX).
  137.  
  138.                         Note: The value to be stored is copied also
  139.                         to ADDR_HI if page boundary is crossed.
  140.  
  141.  
  142.         SBX $CB         Carry and Decimal flags are ignored but set in 
  143.                         substraction. This is due to the CMP command,
  144.                         which is executed instead of the real SBC.
  145.  
  146.  
  147.  Many undocumented commands do not use AND between registers, the CPU just
  148.  throws the bytes to a bus simultaneously and lets the open-collector drivers
  149.  perform the AND. I.e. the command called 'SAX', which is in the STORE section
  150.  (opcodes $A0...$BF), stores the result of (AC & IX) by this way.
  151.  
  152.  More fortunate is its opposite, 'LAX' which just loads a byte simultaeously
  153.  into both AC and IX.
  154.  
  155.  
  156.         $CB  SBX   IX <- (AC & IX) - Immediate
  157.  
  158.  The 'SBX' ($CB) may seem to be very complex operation, even though it is
  159.  combination of subtraction of accumulator and parameter, as in the 'CMP'
  160.  instruction, and the command 'DEX'. As a result, both AC and IX are connected
  161.  to ALU but only the subtraction takes place. Since the comparison logic was
  162.  used, the result of subtraction should be normally ignored, but the 'DEX' now
  163.  happily stores to IX the value of (AC & IX) - Immediate.
  164.  That is why this instruction does not have any decimal mode, and it does not
  165.  affect the V flag. Also Carry flag is ignored in the subtraction but set
  166.  according to the result.
  167.  
  168.  Proof:
  169.  
  170.  These test programs show if your machine is compatible with ours
  171.  regarding the opcode $CB. The first test, vsbx, shows that SBX does
  172.  not affect the V flag. The latter one, sbx, shows the rest of our
  173.  theory. The vsbx test tests 33554432 SBX combinations (16777216
  174.  different AC, IX and Immediate combinations, and two different V flag
  175.  states), and the sbx test doubles that amount (16777216*4 D and C flag
  176.  combinations). Both tests have run successfully on a C64 and a Vic20.
  177.  They ought to run on C16, +4 and the PET series as well. The tests
  178.  stop with BRK, if the opcode $CB does not work expectedly. Successful
  179.  operation ends in RTS. As the tests are very slow, they print dots on
  180.  the screen while running so that you know that the machine has
  181.  not jammed. On computers running at 1 MHz, the first test prints
  182.  approximately one dot every four seconds and a total of 2048 dots,
  183.  whereas the second one prints half that amount, one dot every seven seconds.
  184.  
  185.  If the tests fail on your machine, please let us know your processor's part
  186.  number and revision. If possible, save the executable (after it has stopped
  187.  with BRK) under another name and send it to us so that we know at which stage
  188.  the program stopped.
  189.  
  190.  The following program is a Commodore 64 executable that Marko M"akela
  191.  developed when trying to find out how the V flag is affected by SBX.
  192.  (It was believed that the SBX affects the flag in a weird way, and this
  193.  program shows how SBX sets the flag differently from SBC.)
  194.  You may find the subroutine at $C150 useful when researching other 
  195.  undocumented instructions' flags. Run the program in a machine language
  196.  monitor, as it makes use of the BRK instruction. The result tables will be
  197.  written on pages $C2 and $C3.
  198.  
  199.  Other undocumented instructions usually cause two preceding opcodes being
  200.  executed. However 'NOP' seems to completely disappear from 'SBC' code $EB.
  201.  
  202.  The most difficult to comprehend are the rest of the instructions located on
  203.  the '$0B' line.
  204.  
  205.  All the instructions located at the positive (left) side of this line should
  206.  rotate either memory or the accumulator, but the addressing mode turns out
  207.  to be immediate!
  208.  No problem. Just read the operand, let it be ANDed with the accumulator
  209.  and finally use accumulator addressing mode for the instructions above them.
  210.  
  211.  The rest two instructions on the same line, called 'ANE' and 'LXA' ($8B and
  212.  $AB respectively) often give quite unpredictable results.
  213.  However, the most usual operation is to store ((A | #$ee) & X & #$nn) to
  214.  accumulator. Note that this does not work reliably in a real 64!
  215.  On 8502 opcode $8B uses values 8C,CC, EE, and occasionally 0C and 8E for the
  216.  OR instead of EE,EF,FE and FF used by 6510. With 8502 running at 2 MHz #$EE is
  217.  always used.
  218.  Opcode $AB does not cause this OR taking place on 8502 while 6510 always 
  219.  performs it.  Note that this behaviour depends on chip revision.
  220.  
  221.  Let's take a closer look at $8B (6510).
  222.  
  223.         AC <- IX & D & (AC | VAL)
  224.  
  225.         where VAL comes from this table:
  226.  
  227.        IX high  D high  D low   VAL
  228.         even     even    ---    $EE (1)
  229.         even     odd     ---    $EE
  230.         odd      even    ---    $EE
  231.         odd      odd      0     $EE
  232.         odd      odd     not 0  $FE (2)
  233.  
  234.  (1) If the bottom 2 bits of AC are both 1, then the LSB of the result may
  235.     be 0. The values of IX and D are different every time I run the test.
  236.     This appears to be very rare.
  237.  (2) VAL is $FE most of the time. Sometimes it is $EE - it seems to be random,
  238.     not related to any of the data. This is much more common than (1).
  239.  
  240.   In decimal mode, VAL is usually $FE.
  241.  
  242.  
  243.  Two different functions has been discovered for LAX, opcode $AB. One is
  244.  AC = IX = ANE (see above) and the other, encountered with 6510 and 8502,
  245.  is less complicated AC = IX = (AC & #byte). However, according to what is
  246.  reported, the version altering only the lowest bits of each nybble seems to
  247.  be more common.
  248.  
  249.  What happens, is that $AB loads a value into both AC and IX, ANDing
  250.  the low bit of each nybble with the corresponding bit of the old AC. However,
  251.  there are exceptions. Sometimes the low bit is cleared even when AC contains
  252.  a '1', and sometimes other bits are cleared. The exceptions seem random (they
  253.  change every time I run the test). Oops - that was in decimal mode. Much
  254.  the same with D=0.
  255.  
  256.  What causes the randomness?  Probably it is that it is marginal logic levels -
  257.  when too much wired-anding goes on, some of the signals get very close to
  258.  the threshold. Perhaps we're seeing some of them step over it. The low bit
  259.  of each nybble is special, since it has to cope with carry differently
  260.  (remember decimal mode). We never see a '0' turn into a '1'.
  261.  
  262.  Since these instructions are unpredictable, they should not be used.
  263.  
  264.  
  265.  There is still very strange instruction left, the one named SHA/X/Y, which is
  266.  the only one with only indexed addressing modes. Actually, the commands 'SHA',
  267.  'SHX' and 'SHY' are generated by the indexing algorithm.
  268.  
  269.  While using indexed addressing, effective address for page boundary crossing
  270.  is calculated as soon as possible so it does not slow down operation.
  271.  As a result, in the case of SHA/X/Y, the address and data are prosessed at the
  272.  same time making AND between the to take place. Thus, the value to be stored
  273.  by SAX, for example, is in fact (AC & IX & (ADDR_HI + 1)).
  274.  On page boundary crossing the same value is copied also to high byte of the
  275.  effective address.
  276.  
  277.  
  278.  
  279.   Register selection for load and store
  280.  
  281.    bit1 bit0    AC IX IY
  282.     0   0             x
  283.     0   1          x
  284.     1   0       x
  285.     1   1       x  x
  286.  
  287.  So, AC and IX are selected by bits 1 and 0 respectively, while ~(bit1 | bit0)
  288.  enables IY.
  289.  
  290.  Indexing is determined by bit4, even in relative addressing mode, which
  291.  is one kind of indexing.
  292.  
  293.  Lines containing opcodes xxx000x1 (01 and 03) are treated as absolute after
  294.  the effective address has been loaded into CPU.
  295.  
  296.  Zeropage,y and Absolute,y (codes 10x1 x11x) are distinquished by bit5.
  297.  
  298.  
  299.                  Decimal mode in NMOS 6500 series
  300.  
  301.    Most sources claim that the NMOS 6500 series sets the N, V and Z flags
  302.  unpredictably. Of course, this is not true. While testing how the flags are
  303.  set, I also wanted to see what happens if you use illegal BCD values.
  304.  
  305.    ADC works in Decimal mode in a quite complicated way. It is amazing how it
  306.  can do that all in a single cycle. Here's a pseudo code version of the
  307.  instruction:
  308.  
  309.     AC    accumulator
  310.     AL    low nybble of accumulator
  311.     AH    high nybble of accumulator
  312.  
  313.     C    Carry flag
  314.     Z    Zero flag
  315.     V    oVerflow flag
  316.     N    Negative flag
  317.  
  318.     s    value to be added to accumulator
  319.  
  320.     AL = (AC & 15) + (s & 15) + C;        ! Calculate the lower nybble.
  321.  
  322.     if (AL > 9)                ! BCD fixup
  323.       AL += 6;                ! for lower nybble
  324.  
  325.     AH = (A >> 4) + (s >> 4) + (AL > 15);    ! Calculate the upper nybble.
  326.  
  327.     Z = (AC + s + C != 0);            ! Zero flag is set just
  328.                         ! like in Binary mode.
  329.  
  330.     ! Negative and Overflow flags are set with the same logic than in
  331.     ! Binary mode, but after fixing the lower nybble.
  332.  
  333.     N = (AH & 8 != 0);
  334.     V = ((AH & 8) ^ (A >> 4)) && (!(A ^ s) & 128);
  335.  
  336.     if (AH > 9)                ! BCD fixup
  337.       AH += 6;                ! for upper nybble
  338.  
  339.     
  340.  
  341.     ! Carry is the only flag set after fixing the result.
  342.  
  343.     C = (AH > 15);
  344.     AC = ((AH << 4) | (AL & 15)) & 255;
  345.  
  346.  
  347.    The C flag is set as the quiche eaters expect, but the N and V flags 
  348.  are set after fixing the lower nybble but before fixing the upper one.
  349.  They use the same logic than binary mode ADC. The Z flag is set before
  350.  any BCD fixup, so the D flag does not have any influence on it.
  351.  
  352.  Proof: The following test program tests all 131072 ADC combinations in
  353.         Decimal mode, and aborts with BRK if anything breaks this theory.
  354.         If everything goes well, it ends in RTS.
  355.  
  356.    All programs in this chapter have been successfully tested on a Vic20
  357.  and a Commodore 64. They should run on C16, +4 and on the PET series as
  358.  well. If not, please report the problem to Marko M"akel"a. Each test in
  359.  this chapter should run in less than a minute at 1 MHz.
  360.  
  361.    SBC is much easier. Just like CMP, its flags are not affected by
  362.  the D flag.
  363.  
  364.  Proof:
  365.  
  366.    The only difference in SBC's operation in decimal mode from binary mode
  367.  is the result-fixup:
  368.  
  369.     AC    accumulator
  370.     AL    low nybble of accumulator
  371.     AH    high nybble of accumulator
  372.  
  373.     C    Carry flag
  374.     Z    Zero flag
  375.     V    oVerflow flag
  376.     N    Negative flag
  377.  
  378.     s    value to be added to accumulator
  379.  
  380.     AL = (AC & 15) - (s & 15) - !C;        ! Calculate the lower nybble.
  381.  
  382.     if (AL & 16)                ! BCD fixup
  383.       AL -= 6;                ! for lower nybble
  384.  
  385.     AH = (AC >> 4) - (s >> 4) - (AL > 15);    ! Calculate the upper nybble.
  386.  
  387.     if (AH & 16)                ! BCD fixup
  388.       AH -= 6;                ! for upper nybble
  389.  
  390.     ! Flags are set just like in Binary mode.
  391.  
  392.     C = (AC - s - !C > 255);
  393.     Z = (AC - s - !C != 0);
  394.     V = ((AC - s - !C) ^ s) && ((AC ^ s) & 128);
  395.     N = ((AC - s - !C) & 128);
  396.  
  397.     AC = ((AH << 4) | (AL & 15)) & 255;
  398.  
  399.  
  400.    Again Z flag is set before any BCD fixup. The N and V flags are set
  401.  at any time before fixing the high nybble. The C flag may be set in any
  402.  phase.
  403.  
  404.    Decimal subtraction is easier than decimal addition, as you have to
  405.  make the BCD fixup only when a nybble flows over. In decimal addition,
  406.  you had to verify if the nybble was greater than 9. The processor has
  407.  an internal "half carry" flag for the lower nybble, and it uses it to
  408.  trigger the BCD fixup. When calculating with legal BCD values, the
  409.  lower nybble cannot flow over again when fixing it. So the processor
  410.  does not handle overflows while performing the fixup. Similarly, the
  411.  BCD fixup occurs in the high nybble only if the value flows over,
  412.  i.e. when the C flag will be cleared.
  413.  
  414.    Because SBC's flags are not affected by the Decimal mode flag, you
  415.  could guess that CMP uses the SBC logic, only setting the C flag
  416.  first. But the SBX instruction shows that CMP also temporarily clears
  417.  the D flag, although it is totally unnecessary.
  418.  
  419.    The following program, which tests SBC's result and flags,
  420.  contains the 6502 version of the pseudo code example above.
  421.  
  422.  
  423.    Obviously the undocumented instructions RRA (ROR+ADC) and ISB
  424.  (INC+SBC) have inherited also the decimal operation from the official
  425.  instructions ADC and SBC. The program droradc shows this statement
  426.  for ROR, and the dincsbc test shows this for ISB. Finally,
  427.  dincsbc-deccmp shows that ISB's and DCP's (DEC+CMP) flags are not
  428.  affected by the D flag.
  429.  
  430.  
  431.                                  6510 features
  432.    o  PHP always pushes the Break (B) flag as a `1' to the stack.
  433.       Jukka Tapanim"aki claimed in C=lehti issue 3/89, on page 27 that the
  434.       processor makes a logical OR between the status register's bit 4 
  435.       and the bit 8 of the stack register (which is always 1).
  436.  
  437.    o  Indirect addressing modes do not handle page boundary crossing at all.
  438.       When the parameter's low byte is $FF, the effective address wraps 
  439.       around and the CPU fetches high byte from $xx00 instead of $xx00+$0100.
  440.       E.g. JMP ($01FF) fetches PCL from $01FF and PCH from $0100,
  441.       and LDA ($FF),Y fetches the base address from $FF and $00.
  442.  
  443.    o  Indexed zero page addressing modes never fix the page address on
  444.       crossing the zero page boundary.
  445.       E.g. LDX #$01 : LDA ($FF,X) loads the effective address from $00 and $01.
  446.  
  447.    o  The processor always fetches the byte following a relative branch
  448.       instruction. If the branch is taken, the processor reads then the
  449.       opcode from the destination address. If page boundary is crossed, it
  450.       first reads a byte from the old page from a location that is bigger
  451.       or smaller than the correct address by one page.
  452.  
  453.    o  If you cross a page boundary in any other indexed mode,
  454.       the processor reads an incorrect location first, a location that is
  455.       smaller by one page.
  456.  
  457.    o  Read-Modify-Write instructions write unmodified data, then modified
  458.       (so INC effectively does LDX loc;STX loc;INX;STX loc)
  459.  
  460.    o  -RDY is ignored during writes
  461.       (This is why you must wait 3 cycles before doing any DMA -
  462.       the maximum number of consecutive writes is 3, which occurs
  463.       during interrupts except -RESET.)
  464.  
  465.    o  Some undefined opcodes may give really unpredictable results.
  466.  
  467.    o  All registers except the Program Counter remain the same after -RESET.
  468.       (This is why you must preset D and I flags in the RESET handler.)
  469.  
  470.  
  471.                 Different CPU types
  472.  
  473.  The Rockwell data booklet 29651N52 (technical information about R65C00 
  474.  microprocessors, dated October 1984), lists the following differences between
  475.  NMOS R6502 microprocessor and CMOS R65C00 family:
  476.  
  477.  1. Indexed addressing across page boundary.
  478.         NMOS: Extra read of invalid address.
  479.         CMOS: Extra read of last instruction byte.
  480.  
  481.  2. Execution of invalid op codes.
  482.         NMOS: Some terminate only by reset. Results are undefined.
  483.         CMOS: All are NOPs (reserved for future use).
  484.  
  485.  3. Jump indirect, operand = XXFF.
  486.         NMOS: Page address does not increment.
  487.         CMOS: Page address increments and adds one additional cycle.
  488.  
  489.  4. Read/modify/write instructions at effective address.
  490.         NMOS: One read and two write cycles.
  491.         CMOS: Two read and one write cycle.
  492.  
  493.  5. Decimal flag.
  494.         NMOS: Indeterminate after reset.
  495.         CMOS: Initialized to binary mode (D=0) after reset and interrupts.
  496.  
  497.  6. Flags after decimal operation.
  498.         NMOS: Invalid N, V and Z flags.
  499.         CMOS: Valid flag adds one additional cycle.
  500.  
  501.  7. Interrupt after fetch of BRK instruction.
  502.         NMOS: Interrupt vector is loaded, BRK vector is ignored.
  503.         CMOS: BRK is executed, then interrupt is executed.
  504.  
  505.  
  506.  
  507.                 6510 Instruction Timing
  508.  
  509.    The NMOS 6500 series uses a sort of pipelining. It always reads two
  510.  bytes for each instruction. If the instruction was only two cycles long,
  511.  the opcode for the next instruction can be fetched during the third cycle.
  512.  As most instructions are two or three bytes long, this is quite efficient.
  513.  But one-byte instructions take two cycles, even though they could be
  514.  performed in one.
  515.  
  516.    The following tables show what happens on the bus while executing different
  517.  kinds of instructions. The tables having "???" marks at any cycle may be
  518.  totally wrong, but the rest should be absolutely accurate.
  519.  
  520.  
  521.   Interrupts
  522.  
  523.      NMI and IRQ both take 7 cycles. Their timing diagram is much like
  524.      BRK's. IRQ will be executed only when the I flag is clear.
  525.      The processor will usually wait for the current instruction to
  526.      complete before executing the interrupt sequence.
  527.  
  528.      There is one exception to this rule: If a NMI occurs while the
  529.      processor is executing a BRK, the two interrupts may take 7 to 14
  530.      cycles to execute, and the processor may totally lose the BRK
  531.      instruction. Probably the results are similar also with IRQ.
  532.      Marko M"akel"a experimented with BRK/NMI, but he still hasn't
  533.      analyzed the results.
  534.  
  535.      RESET does not push program counter on stack, and we don't know how
  536.      long it lasts. But we know that RESET preserves all registers
  537.      (except PC).
  538.  
  539.  
  540.   Accumulator or implied addressing
  541.  
  542.      BRK
  543.  
  544.         #  address R/W description
  545.        --- ------- --- -----------------------------------------------
  546.         1    PC     R  fetch opcode, increment PC
  547.         2    PC     R  read next instruction byte (and throw it away),
  548.                increment PCR
  549.         3  $0100,S  W  push PCH on stack (with B flag set), decrement S
  550.         4  $0100,S  W  push PCL on stack, decrement S
  551.         5  $0100,S  W  push P on stack, decrement S
  552.         6   $FFFE   R  fetch PCL
  553.         7   $FFFF   R  fetch PCH
  554.  
  555.  
  556.      RTI
  557.  
  558.         #  address R/W description
  559.        --- ------- --- -----------------------------------------------
  560.         1    PCR    R  fetch opcode, increment PCR
  561.         2    PCR    R  read next instruction byte (and throw it away),
  562.                      increment PCR
  563.         3  $0100,S  R  increment S
  564.         4  $0100,S  R  pull P from stack, increment S
  565.         5  $0100,S  R  pull PCL from stack, increment S
  566.         6  $0100,S  R  pull PCH from stack
  567.  
  568.  
  569.      RTS
  570.  
  571.         #  address R/W description
  572.        --- ------- --- -----------------------------------------------
  573.         1    PCR    R  fetch opcode, increment PCR
  574.         2    PCR    R  read next instruction byte (and throw it away),
  575.                increment PCR
  576.         3  $0100,S  R  increment S
  577.         4  $0100,S  R  pull PCL from stack, increment S
  578.         5  $0100,S  R  pull PCH from stack
  579.         6    PCR    R  increment PCR
  580.  
  581.  
  582.      PHA, PHP
  583.  
  584.         #  address R/W description
  585.        --- ------- --- -----------------------------------------------
  586.         1    PCR    R  fetch opcode, increment PCR
  587.         2    PCR    R  read next instruction byte (and throw it away),
  588.                increment PCR
  589.         3  $0100,S  W  push register on stack, decrement S
  590.  
  591.  
  592.      PLA, PLP
  593.  
  594.         #  address R/W description
  595.        --- ------- --- -----------------------------------------------
  596.         1    PCR    R  fetch opcode, increment PCR
  597.         2    PCR    R  read next instruction byte (and throw it away),
  598.                increment PCR
  599.         3  $0100,S  R  increment S
  600.         4  $0100,S  R  pull register from stack
  601.  
  602.         Note: The 3rd cycle does NOT read from PCR.
  603.               Maybe it reads from $0100,S.
  604.  
  605.  
  606.      Other instructions
  607.  
  608.         #  address R/W description
  609.        --- ------- --- -----------------------------------------------
  610.         1    PCR    R  fetch opcode, increment PCR
  611.         2    PCR    R  read next instruction byte (and throw it away),
  612.                increment PCR
  613.  
  614.  
  615.   Immediate addressing
  616.  
  617.         #  address R/W description
  618.        --- ------- --- ------------------------------------------
  619.         1    PCR    R  fetch opcode, increment PCR
  620.         2    PCR    R  fetch value, increment PCR
  621.  
  622.  
  623.   Absolute addressing
  624.  
  625.      JMP
  626.  
  627.         #  address R/W description
  628.        --- ------- --- -------------------------------------------------
  629.         1    PCR    R  fetch opcode, increment PCR
  630.         2    PCR    R  fetch address's low byte to latch, increment PCR
  631.         3    PCR    R  copy latch to PCL, fetch address's high byte to
  632.                latch, increment PCR, copy latch to PCH
  633.  
  634.  
  635.      JSR
  636.  
  637.         #  address R/W description
  638.        --- ------- --- -------------------------------------------------
  639.         1    PCR    R  fetch opcode, increment PCR
  640.         2    PCR    R  fetch address's low byte to latch, increment PCR
  641.         3  $0100,S  R  store latch
  642.         4  $0100,S  W  push PCH on stack, decrement S
  643.         5  $0100,S  W  push PCL on stack, decrement S
  644.         6    PCR    R  copy latch to PCL, fetch address's high byte to
  645.                latch, increment PCR, copy latch to PCH
  646.  
  647.  
  648.      Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
  649.                         LAX, NOP)
  650.  
  651.         #  address R/W description
  652.        --- ------- --- ------------------------------------------
  653.         1    PCR    R  fetch opcode, increment PCR
  654.         2    PCR    R  fetch low byte of address, increment PCR
  655.         3    PCR    R  fetch high byte of address, increment PCR
  656.         4  address  R  read from effective address
  657.  
  658.  
  659.      Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,
  660.                                      SLO, SRE, RLA, RRA, ISB, DCP)
  661.  
  662.         #  address R/W description
  663.        --- ------- --- ------------------------------------------
  664.         1    PCR    R  fetch opcode, increment PCR
  665.         2    PCR    R  fetch low byte of address, increment PCR
  666.         3    PCR    R  fetch high byte of address, increment PCR
  667.         4  address  R  read from effective address
  668.         5  address  W  write the value back to effective address,
  669.                        and do the operation on it
  670.         6  address  W  write the new value to effective address
  671.  
  672.  
  673.      Write instructions (STA, STX, STY, SAX)
  674.     
  675.         #  address R/W description
  676.        --- ------- --- ------------------------------------------
  677.         1    PCR    R  fetch opcode, increment PCR
  678.         2    PCR    R  fetch low byte of address, increment PCR
  679.         3    PCR    R  fetch high byte of address, increment PCR
  680.         4  address  W  write register to effective address
  681.  
  682.  
  683.   Zero page addressing
  684.  
  685.      Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
  686.                         LAX, NOP)
  687.  
  688.         #  address R/W description
  689.        --- ------- --- ------------------------------------------
  690.         1    PCR    R  fetch opcode, increment PCR
  691.         2    PCR    R  fetch address, increment PCR
  692.         3  address  R  read from effective address
  693.  
  694.  
  695.      Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,
  696.                                      SLO, SRE, RLA, RRA, ISB, DCP)
  697.  
  698.         #  address R/W description
  699.        --- ------- --- ------------------------------------------
  700.         1    PCR    R  fetch opcode, increment PCR
  701.         2    PCR    R  fetch address, increment PCR
  702.         3  address  R  read from effective address
  703.         4  address  W  write the value back to effective address,
  704.                        and do the operation on it
  705.         5  address  W  write the new value to effective address
  706.  
  707.  
  708.      Write instructions (STA, STX, STY, SAX)
  709.     
  710.         #  address R/W description
  711.        --- ------- --- ------------------------------------------
  712.         1    PCR    R  fetch opcode, increment PCR
  713.         2    PCR    R  fetch address, increment PCR
  714.         3  address  W  write register to effective address
  715.  
  716.   Zero page indexed addressing
  717.  
  718.      Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
  719.                         LAX, NOP)
  720.  
  721.         #   address  R/W description
  722.        --- --------- --- ------------------------------------------
  723.         1     PCR     R  fetch opcode, increment PCR
  724.         2     PCR     R  fetch address, increment PCR
  725.     3   address   R  read from address, add index register to it
  726.         4  address+I* R  read from effective address
  727.  
  728.        Notes: I denotes either index register (X or Y).
  729.  
  730.               * The high byte of the effective address is always zero,
  731.                 i.e. page boundary crossings are not handled.
  732.  
  733.  
  734.      Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,
  735.                                      SLO, SRE, RLA, RRA, ISB, DCP)
  736.  
  737.         #   address  R/W description
  738.        --- --------- --- ---------------------------------------------
  739.         1     PCR     R  fetch opcode, increment PCR
  740.         2     PCR     R  fetch address, increment PCR
  741.     3   address   R  read from address, add index register X to it
  742.         4  address+X* R  read from effective address
  743.         5  address+X* W  write the value back to effective address,
  744.                          and do the operation on it
  745.         6  address+X* W  write the new value to effective address
  746.  
  747.        Note: * The high byte of the effective address is always zero,
  748.                i.e. page boundary crossings are not handled.
  749.  
  750.  
  751.      Write instructions (STA, STX, STY, SAX)
  752.  
  753.         #   address  R/W description
  754.        --- --------- --- -------------------------------------------
  755.         1     PCR     R  fetch opcode, increment PCR
  756.         2     PCR     R  fetch address, increment PCR
  757.     3   address   R  read from address, add index register to it
  758.         4  address+I* W  write to effective address
  759.  
  760.        Notes: I denotes either index register (X or Y).
  761.  
  762.               * The high byte of the effective address is always zero,
  763.                 i.e. page boundary crossings are not handled.
  764.  
  765.  
  766.   Absolute indexed addressing
  767.  
  768.      Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
  769.                         LAX, LAE, SHS, NOP)
  770.  
  771.         #   address  R/W description
  772.        --- --------- --- ------------------------------------------
  773.         1     PCR     R  fetch opcode, increment PCR
  774.         2     PCR     R  fetch low byte of address, increment PCR
  775.         3     PCR     R  fetch high byte of address,
  776.                          add index register to low address byte,
  777.              increment PCR
  778.         4  address+I* R  read from effective address,
  779.                          fix the high byte of effective address
  780.         4+ address+I  R  re-read from effective address
  781.  
  782.        Notes: I denotes either index register (X or Y).
  783.  
  784.               * The high byte of the effective address may be invalid
  785.                 at this time, i.e. it may be smaller by $100.
  786.  
  787.               + This cycle will be executed only if the effective address
  788.                 was invalid during cycle #4, i.e. page boundary was crossed.
  789.  
  790.  
  791.      Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,
  792.                                      SLO, SRE, RLA, RRA, ISB, DCP)
  793.  
  794.         #   address  R/W description
  795.        --- --------- --- ------------------------------------------
  796.         1    PCR      R  fetch opcode, increment PCR
  797.         2    PCR      R  fetch low byte of address, increment PCR
  798.         3    PCR      R  fetch high byte of address,
  799.                          add index register X to low address byte,
  800.                  increment PCR
  801.         4  address+X* R  read from effective address,
  802.                          fix the high byte of effective address
  803.         5  address+X  R  re-read from effective address
  804.         6  address+X  W  write the value back to effective address,
  805.                          and do the operation on it
  806.         7  address+X  W  write the new value to effective address
  807.  
  808.        Notes: * The high byte of the effective address may be invalid
  809.                 at this time, i.e. it may be smaller by $100.
  810.  
  811.  
  812.      Write instructions (STA, STX, STY, SHA, SHX, SHY)
  813.  
  814.         #   address  R/W description
  815.        --- --------- --- ------------------------------------------
  816.         1     PCR     R  fetch opcode, increment PCR
  817.         2     PCR     R  fetch low byte of address, increment PCR
  818.         3     PCR     R  fetch high byte of address,
  819.                          add index register to low address byte,
  820.              increment PCR
  821.         4  address+I* R  read from effective address,
  822.                          fix the high byte of effective address
  823.         5  address+I  W  write to effective address
  824.  
  825.        Notes: I denotes either index register (X or Y).
  826.  
  827.               * The high byte of the effective address may be invalid
  828.                 at this time, i.e. it may be smaller by $100. Because
  829.         the processor cannot undo a write to an invalid address,
  830.                 it always reads from the address first.
  831.  
  832.  
  833.   Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)
  834.  
  835.         #   address  R/W description
  836.        --- --------- --- ---------------------------------------------
  837.         1     PCR     R  fetch opcode, increment PCR
  838.         2     PCR     R  fetch operand, increment PCR
  839.         3     PCR     R  Fetch opcode of next instruction,
  840.                          If branch is taken, add operand to PCL.
  841.              Otherwise increment PCR.
  842.         3+    PCR*    R  Fetch opcode of next instruction.
  843.                          Fix PCH. If it did not change, increment PCR.
  844.         3!    PCR     R  Fetch opcode of next instruction,
  845.              increment PCR.
  846.  
  847.        Notes: * The high byte of Program Counter (PCH) may be invalid
  848.                 at this time, i.e. it may be smaller or bigger by $100.
  849.  
  850.               + If branch is taken, this cycle will be executed.
  851.  
  852.               ! If branch occurs to different page, this cycle will be
  853.                 executed.
  854.  
  855.  
  856.   Indexed indirect addressing
  857.  
  858.      Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)
  859.  
  860.         #    address   R/W description
  861.        --- ----------- --- ------------------------------------------
  862.         1      PCR      R  fetch opcode, increment PCR
  863.         2      PCR      R  fetch pointer address, add X to it,
  864.                increment PCR
  865.         3      ???      R  internal operation
  866.         4   pointer+X   R  fetch effective address low
  867.         5  pointer+X+1  R  fetch effective address high
  868.         6    address    R  read from effective address
  869.  
  870.        Note: The effective address is always fetched from zero page,
  871.              i.e. the zero page boundary crossing is not handled.
  872.  
  873.      Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)
  874.  
  875.         #    address   R/W description
  876.        --- ----------- --- ------------------------------------------
  877.         1      PCR      R  fetch opcode, increment PCR
  878.         2      PCR      R  fetch pointer address, add X to it,
  879.                increment PCR
  880.         3      ???      R  internal operation
  881.         4   pointer+X   R  fetch effective address low
  882.         5  pointer+X+1  R  fetch effective address high
  883.         6    address    R  read from effective address
  884.         7    address    W  write the value back to effective address,
  885.                            and do the operation on it
  886.         8    address    W  write the new value to effective address
  887.  
  888.        Note: The effective address is always fetched from zero page,
  889.              i.e. the zero page boundary crossing is not handled.
  890.  
  891.      Write instructions (STA, SAX)
  892.  
  893.         #    address   R/W description
  894.        --- ----------- --- ------------------------------------------
  895.         1      PCR      R  fetch opcode, increment PCR
  896.         2      PCR      R  fetch pointer address, add X to it,
  897.                increment PCR
  898.         3      ???      R  internal operation
  899.         4   pointer+X   R  fetch effective address low
  900.         5  pointer+X+1  R  fetch effective address high
  901.         6    address    W  write to effective address
  902.  
  903.        Note: The effective address is always fetched from zero page,
  904.              i.e. the zero page boundary crossing is not handled.
  905.  
  906.   Indirect indexed addressing
  907.  
  908.      Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)
  909.  
  910.         #    address   R/W description
  911.        --- ----------- --- ------------------------------------------
  912.         1      PCR      R  fetch opcode, increment PCR
  913.         2      PCR      R  fetch pointer address, increment PCR
  914.         3    pointer    R  fetch effective address low
  915.         4   pointer+1   R  fetch effective address high,
  916.                            add Y to low byte of effective address
  917.         5   address+Y*  R  read from effective address,
  918.                            fix high byte of effective address
  919.         5+  address+Y   R  read from effective address
  920.  
  921.        Notes: The effective address is always fetched from zero page,
  922.               i.e. the zero page boundary crossing is not handled.
  923.  
  924.               * The high byte of the effective address may be invalid
  925.                 at this time, i.e. it may be smaller by $100.
  926.  
  927.               + This cycle will be executed only if the effective address
  928.                 was invalid during cycle #5, i.e. page boundary was crossed.
  929.  
  930.  
  931.      Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)
  932.  
  933.         #    address   R/W description
  934.        --- ----------- --- ------------------------------------------
  935.         1      PCR      R  fetch opcode, increment PCR
  936.         2      PCR      R  fetch pointer address, increment PCR
  937.         3    pointer    R  fetch effective address low
  938.         4   pointer+1   R  fetch effective address high,
  939.                            add Y to low byte of effective address
  940.         5   address+Y*  R  read from effective address,
  941.                            fix high byte of effective address
  942.         6   address+Y   W  write to effective address
  943.         7   address+Y   W  write the value back to effective address,
  944.                            and do the operation on it
  945.         8   address+Y   W  write the new value to effective address
  946.  
  947.        Notes: The effective address is always fetched from zero page,
  948.               i.e. the zero page boundary crossing is not handled.
  949.  
  950.               * The high byte of the effective address may be invalid
  951.                 at this time, i.e. it may be smaller by $100.
  952.  
  953.  
  954.      Write instructions (STA, SHA)
  955.  
  956.         #    address   R/W description
  957.        --- ----------- --- ------------------------------------------
  958.         1      PCR      R  fetch opcode, increment PCR
  959.         2      PCR      R  fetch pointer address, increment PCR
  960.         3    pointer    R  fetch effective address low
  961.         4   pointer+1   R  fetch effective address high,
  962.                            add Y to low byte of effective address
  963.         5   address+Y*  R  read from effective address,
  964.                            fix high byte of effective address
  965.         6   address+Y   W  write to effective address
  966.  
  967.        Notes: The effective address is always fetched from zero page,
  968.               i.e. the zero page boundary crossing is not handled.
  969.  
  970.               * The high byte of the effective address may be invalid
  971.                 at this time, i.e. it may be smaller by $100.
  972.  
  973.  
  974.   Absolute indirect addressing (JMP)
  975.  
  976.         #   address  R/W description
  977.        --- --------- --- ------------------------------------------
  978.         1     PCR     R  fetch opcode, increment PCR
  979.         2     PCR     R  fetch pointer address low, increment PCR
  980.         3     PCR     R  fetch pointer address high, increment PCR
  981.         4   pointer   R  fetch low address to latch
  982.         5  pointer+1* R  fetch PCH, copy latch to PCL
  983.  
  984.        Note: * The PCH will always be fetched from the same page
  985.                than PCL, i.e. page boundary crossing is not handled.
  986.  
  987.  
  988.  
  989.                 MEMORY MANAGEMENT
  990.  
  991.        normal                                                   ultimax
  992.         1111    101x    011x    001x    1110    0100    1100    xx01
  993.                 1000            00x0
  994. 10000
  995. ------------------------------------------------------------------------
  996.  F000
  997.         Kernal  RAM     Kernal  RAM     Kernal  Kernal  Kernal  module
  998.  E000
  999. ------------------------------------------------------------------------
  1000.  D000   I/O     I/O**   I/O     RAM     I/O     I/O     I/O     I/O
  1001. ------------------------------------------------------------------------
  1002.  C000   RAM     RAM     RAM     RAM     RAM     RAM     RAM      -
  1003. ------------------------------------------------------------------------
  1004.  B000
  1005.         BASIC   RAM     RAM     RAM     BASIC   module  module   -
  1006.  A000
  1007. ------------------------------------------------------------------------
  1008.  9000
  1009.         RAM     RAM     RAM     RAM     module  RAM     module  module
  1010.  8000
  1011. ------------------------------------------------------------------------
  1012.  7000
  1013.  
  1014.  6000
  1015.         RAM     RAM     RAM     RAM     RAM     RAM     RAM      -
  1016.  5000
  1017.  
  1018.  4000
  1019. ------------------------------------------------------------------------
  1020.  3000    
  1021.  
  1022.  2000
  1023.         RAM     RAM     RAM     RAM     RAM     RAM     RAM      RAM    
  1024.  1000
  1025.     
  1026.  0000
  1027. ------------------------------------------------------------------------
  1028.  
  1029.                 **) Chargen not accessible by the CPU
  1030.  
  1031.  
  1032.                 AUTOSTART CODE
  1033.  
  1034.   If memory places $8004 to $8008 contain 'CBM80' (C3 C2 CD 38 30),
  1035.   the RESET routine jumps to ($8000) and the default NMI handler jumps to
  1036.   ($8002).
  1037.  
  1038.  
  1039.                 HOW REAL PROGRAMMERS ACKNOWLEDGE INTERRUPTS
  1040.  
  1041.   With RMW instructions:
  1042.  
  1043.         ; beginning of combined raster/timer interrupt routine
  1044.         LSR $D019       ; clear VIC interrupts, read raster interrupt flag to C
  1045.         BCS raster      ; jump if VIC caused an interrupt
  1046.         ...             ; timer interrupt routine
  1047.  
  1048.         Operational diagram of LSR $D019:
  1049.  
  1050.           #  data  address  R/W  
  1051.          --- ----  -------  ---  ---------------------------------
  1052.           1   4E     PCR     R   fetch opcode
  1053.           2   19    PCR+1    R   fetch address low
  1054.           3   D0    PCR+2    R   fetch address high
  1055.           4   xx    $D019    R   read memory
  1056.           5   xx    $D019    W   write the value back, rotate right
  1057.           6  xx/2   $D019    W   write the new value back
  1058.  
  1059.     The 5th cycle acknowledges the interrupt by writing the same
  1060.     value back. If only raster interrupts are used, the 6th cycle
  1061.     has no effect on the VIC.
  1062.  
  1063.  
  1064.   With indexed addressing:
  1065.  
  1066.         ; acknowledge interrupts to both CIAs
  1067.         LDX #$10
  1068.         LDA $DCFD,X
  1069.  
  1070.         Operational diagram of LDA $DCFD,X:
  1071.  
  1072.           #  data  address  R/W  description
  1073.          --- ----  -------  ---  ---------------------------------
  1074.           1   BD     PCR     R   fetch opcode
  1075.           2   FD    PCR+1    R   fetch address low
  1076.           3   DC    PCR+2    R   fetch address high, add X to address low
  1077.           4   xx    $DC0D    R   read from address, fix high byte of address
  1078.           5   yy    $DD0D    R   read from right address
  1079.  
  1080.  
  1081.         ; acknowledge interrupts to CIA 2
  1082.         LDX #$10
  1083.         STA $DDFD,X
  1084.  
  1085.         Operational diagram of STA $DDFD,X:
  1086.  
  1087.           #  data  address  R/W  description
  1088.          --- ----  -------  ---  ---------------------------------
  1089.           1   9D     PCR     R   fetch opcode
  1090.           2   FD    PCR+1    R   fetch address low
  1091.           3   DC    PCR+2    R   fetch address high, add X to address low
  1092.           4   xx    $DD0D    R   read from address, fix high byte of address
  1093.           5   ac    $DE0D    W   write to right address
  1094.  
  1095.  
  1096.   With branch instructions:
  1097.  
  1098.         ; acknowledge interrupts to CIA 2
  1099.                 LDA #$00  ; clear N flag
  1100.                 JMP $DD0A
  1101.         DD0A    BPL $DC9D ; branch
  1102.         DC9D    BRK       ; return
  1103.  
  1104.         You need the following preparations to initialize the CIA registers:
  1105.  
  1106.                 LDA #$91  ; argument of BPL
  1107.                 STA $DD0B
  1108.                 LDA #$10  ; BPL
  1109.                 STA $DD0A
  1110.                 STA $DD08 ; load the ToD values from the latches
  1111.                 LDA $DD0B ; jam the ToD display
  1112.                 LDA #$7F
  1113.                 STA $DC0D ; assure that $DC0D is $00
  1114.  
  1115.         Operational diagram of BPL $DC9D:
  1116.  
  1117.           #  data  address  R/W  description
  1118.          --- ----  -------  ---  ---------------------------------
  1119.           1   10    $DD0A    R   fetch opcode
  1120.           2   91    $DD0B    R   fetch argument
  1121.           3   xx    $DD0C    R   fetch opcode, add argument to PCL
  1122.           4   yy    $DD9D    R   fetch opcode, fix PCH
  1123.         ( 5   00    $DC9D    R   fetch opcode )
  1124.  
  1125.  
  1126.         ; acknowledge interrupts to CIA 1
  1127.                 LDA #$00  ; clear N flag
  1128.                 JMP $DCFA
  1129.         DCFA    BPL $DD0D
  1130.         DD0D    BRK
  1131.  
  1132.         ; Again you need to set the ToD registers of CIA 1 and the
  1133.         ; Interrupt Control Register of CIA 2 first.
  1134.  
  1135.         Operational diagram of BPL $DD0D:
  1136.  
  1137.           #  data  address  R/W  description
  1138.          --- ----  -------  ---  ---------------------------------
  1139.           1   10    $DCFA    R   fetch opcode
  1140.           2   11    $DCFB    R   fetch argument
  1141.           3   xx    $DCFC    R   fetch opcode, add argument to PCL
  1142.           4   yy    $DC0D    R   fetch opcode, fix PCH
  1143.         ( 5   00    $DD0D    R   fetch opcode )
  1144.  
  1145.  
  1146.         ; acknowledge interrupts to CIA 2 automagically
  1147.                 ; preparations
  1148.                 LDA #$7F
  1149.                 STA $DD0D       ; disable CIA 2's all interrupt sources
  1150.                 LDA $DD0E
  1151.                 AND #$BE        ; ensure that $DD0C remains constant
  1152.                 STA $DD0E       ; and stop the timer
  1153.                 LDA #$FD
  1154.                 STA $DD0C       ; parameter of BPL
  1155.                 LDA #$10
  1156.                 STA $DD0B       ; BPL
  1157.                 LDA #$40
  1158.                 STA $DD0A       ; RTI/parameter of LSR
  1159.                 LDA #$46
  1160.                 STA $DD09       ; LSR
  1161.                 STA $DD08       ; load the ToD values from the latches
  1162.                 LDA $DD0B       ; jam the ToD display
  1163.                 LDA #$09
  1164.                 STA $0318
  1165.                 LDA #$DD
  1166.                 STA $0319       ; change NMI vector to $DD09
  1167.                 LDA #$FF        ; Try changing this instruction's operand
  1168.                 STA $DD05       ; (see comment below).
  1169.                 LDA #$FF
  1170.                 STA $DD04       ; set interrupt frequency to 1/65536 cycles
  1171.                 LDA $DD0E
  1172.                 AND #$80
  1173.                 ORA #$11
  1174.                 LDX #$81
  1175.                 STX $DD0D       ; enable timer interrupt
  1176.                 STA $DD0E       ; start timer
  1177.  
  1178.                 LDA #$00        ; To see that the interrupts really occur,
  1179.                 STA $D011       ; use something like this and see how
  1180.         LOOP    DEC $D020       ; changing the byte loaded to $DD05 from
  1181.                 BNE LOOP        ; #$FF to #$0F changes the image.
  1182.  
  1183.         When an NMI occurs, the processor jumps to Kernal code, which jumps to
  1184.         ($0318), which points to the following routine:
  1185.  
  1186.         DD09    LSR $40         ; clear N flag
  1187.                 BPL $DD0A       ; Note: $DD0A contains RTI.
  1188.  
  1189.         Operational diagram of BPL $DD0A:
  1190.  
  1191.           #  data  address  R/W  description
  1192.          --- ----  -------  ---  ---------------------------------
  1193.           1   10    $DD0B    R   fetch opcode
  1194.           2   11    $DD0C    R   fetch argument
  1195.           3   xx    $DD0D    R   fetch opcode, add argument to PCL
  1196.           4   40    $DD0A    R   fetch opcode, (fix PCH)
  1197.  
  1198.  
  1199.   With RTI:
  1200.  
  1201.         ; the fastest possible interrupt handler in the 6500 family
  1202.                 ; preparations
  1203.         SEI
  1204.         LDA $01        ; disable ROM and enable I/O
  1205.         AND #$FD
  1206.         ORA #$05
  1207.         STA $01
  1208.                 LDA #$7F
  1209.                 STA $DD0D       ; disable CIA 2's all interrupt sources
  1210.                 LDA $DD0E
  1211.                 AND #$BE        ; ensure that $DD0C remains constant
  1212.                 STA $DD0E       ; and stop the timer
  1213.                 LDA #$40
  1214.                 STA $DD0C       ; store RTI to $DD0C
  1215.                 LDA #$0C
  1216.                 STA $FFFA
  1217.                 LDA #$DD
  1218.                 STA $FFFB       ; change NMI vector to $DD0C
  1219.                 LDA #$FF        ; Try changing this instruction's operand
  1220.                 STA $DD05       ; (see comment below).
  1221.                 LDA #$FF
  1222.                 STA $DD04       ; set interrupt frequency to 1/65536 cycles
  1223.                 LDA $DD0E
  1224.                 AND #$80
  1225.                 ORA #$11
  1226.                 LDX #$81
  1227.                 STX $DD0D       ; enable timer interrupt
  1228.                 STA $DD0E       ; start timer
  1229.  
  1230.                 LDA #$00        ; To see that the interrupts really occur,
  1231.                 STA $D011       ; use something like this and see how
  1232.         LOOP    DEC $D020       ; changing the byte loaded to $DD05 from
  1233.                 BNE LOOP        ; #$FF to #$0F changes the image.
  1234.  
  1235.         When an NMI occurs, the processor jumps to Kernal code, which jumps to
  1236.         ($0318), which points to the following routine:
  1237.  
  1238.         DD0C    RTI
  1239.  
  1240.         How on earth can this clear the interrupts? Remember, the processor
  1241.         always fetches two successive bytes for each instruction.
  1242.  
  1243.         A little more practical version of this is redirecting the NMI (or IRQ)
  1244.         to your own routine, whose last instruction is JMP $DD0C or JMP $DC0C.
  1245.         If you want to confuse more, change the 0 in the address to a
  1246.         hexadecimal digit different from the one you used when writing the RTI.
  1247.  
  1248.         Or you can combine the latter two methods:
  1249.  
  1250.         DD09    LSR $xx         ; xx is any appropriate BCD value 00-59.
  1251.                 BPL $DCFC
  1252.         DCFC    RTI
  1253.  
  1254.         This example acknowledges interrupts to both CIAs.
  1255.  
  1256.  
  1257.    If you want to confuse the examiners of your code, you can use any of
  1258.  these techniques. Although these examples use no undefined opcodes, they do
  1259.  not run correctly on CMOS processors. However, the RTI example should run on
  1260.  65C02 and 65C816, and the latter branch instruction example might work as
  1261.  well.
  1262.  
  1263.    The RMW instruction method has been used in some demos, others were
  1264.  developed by Marko M"akel"a. His favourite is the automagical RTI method,
  1265.  although it does not have any practical applications, except for some
  1266.  time dependent data decryption routines for very complicated copy protections.
  1267.  
  1268.  
  1269.  
  1270.                 MAKING USE OF THE I/O REGISTERS
  1271.  
  1272.    If you are making a resident program and want to make as invisible to the
  1273.  system as possible, probably the best method is keeping most of your code
  1274.  under the I/O area (in the RAM at $D000-$DFFF). You need only a short routine
  1275.  in the normally visible RAM that pushes the current value of the processor's
  1276.  I/O register $01 on stack, switches I/O and ROMs out and jumps to this area.
  1277.  Returning from the $D000-$DFFF area is easy even without any routine in the
  1278.  normally visible RAM area. Just write a RTS to an I/O register and return
  1279.  through it.
  1280.  
  1281.    But what if your program needs to use I/O? And how can you write the RTS
  1282.  to an I/O register while the I/O area is switched off? You need a swap area
  1283.  for your program in normally visible memory. The first thing your routine at
  1284.  $D000-$DFFF does is copying the I/O routines (or the whole program) to
  1285.  normally visible memory, swapping the bytes. For instance, if your I/O
  1286.  routines are initially at $D200-$D3FF, exchange the bytes at $D200-$D3FF
  1287.  with the contents of $C000-$C1FF. Now you can call the I/O routines from
  1288.  your routine at $D000-$DFFF, and the I/O routines can switch the I/O area
  1289.  temporarily on to access the I/O circuitry. And right before exiting your
  1290.  program at $D000-$DFFF swaps the old contents of that I/O routine area in,
  1291.  e.g. exchanges the memory areas $D200-$D3FF and $C000-$C1FF again.
  1292.  
  1293.    What I/O registers can you use for the RTS? There are two alternatives:
  1294.  8-bit VIC sprite registers or CIA serial port register. The CIA register is
  1295.  usually better, as changing the VIC registers might change the screen layout.
  1296.  However, also the SP register has some drawbacks: If the machine's CNT1 and
  1297.  CNT2 lines are connected to a frequency source, you must stop either CIA's
  1298.  Timer A to use the SP register method. Normally the 1st CIA's Timer A is the
  1299.  main hardware interrupt source. And if you use the Kernal's RS232, you cannot
  1300.  stop the 2nd CIA's Timer A either. Also, if you don't want to lose any CIA
  1301.  interrupts, remember that the RTS at SP register causes also the Interrupt
  1302.  Control Register to be read.
  1303.  
  1304.    Also keep in mind that the user could press RESTORE while the Kernal ROM
  1305.  and I/O areas are disabled. You could write your own NMI handler (using
  1306.  the NMI vector at $FFFA), but a fast loader that uses very tight timing
  1307.  would still stop working if the user pressed RESTORE in wrong time. So, to
  1308.  make a robust program, you have to disable NMI interrupts. But how is this
  1309.  possible? They are Non-Maskable after all. The NMI interrupt is
  1310.  edge-sensitive, the processor jumps to NMI handler only when the -NMI line
  1311.  drops from +5V to ground. Just cause a NMI with CIA2's timer, but don't
  1312.  read the Interrupt Control register. If you need to read $DD0D in your
  1313.  program, you must add a NMI handler just in case the user presses RESTORE.
  1314.  And don't forget to raise the -NMI line upon exiting the program. This can
  1315.  be done automatically by the latter two of the three following examples.
  1316.  
  1317.  
  1318.         ; Returning via VIC sprite 7 X coordinate register
  1319.  
  1320.         Initialization:   ; This is executed when I/O is switched on
  1321.                 LDA #$60
  1322.                 STA $D015 ; Write RTS to VIC register $15.
  1323.  
  1324.         Exiting:          ; NOTE: This procedure must start at VIC register
  1325.                           ; $12. You have multiple alternatives, as the VIC
  1326.                           ; appears in memory at $D000+$40*n, where $0<=n<=$F.
  1327.  
  1328.                 PLA       ; Pull the saved 6510 I/O register state from stack
  1329.                 STA $01   ; Restore original memory bank configuration
  1330.                           ; Now the processor fetches the RTS command from the
  1331.                           ; VIC register $15.
  1332.  
  1333.  
  1334.         ; Returning via CIA 2's SP register (assuming that CNT2 is stable)
  1335.  
  1336.         Initialization:   ; This is executed when I/O is switched on
  1337.                 LDA $DD0E ; CIA 2's Control Register A
  1338.                 AND #$BF  ; Set Serial Port to input
  1339.                 STA $DD0E ; (make the SP register to act as a memory place)
  1340.                 LDA #$60
  1341.                 STA $DD0C ; Write RTS to CIA 2 register $C.
  1342.  
  1343.         Exiting:          ; NOTE: This procedure must start at CIA 2 register
  1344.                           ; $9. As the CIA 2 appears in memory at $DD00+$10*n,
  1345.                           ; where 0<=n<=$F, you have sixteen alternatives.
  1346.                 PLA
  1347.                 STA $01   ; Restore original memory bank configuration
  1348.                           ; Now the processor fetches the RTS command from
  1349.                           ; the CIA 2 register $C.
  1350.  
  1351.  
  1352.         ; Returning via CIA 2's SP register, stopping the Timer A
  1353.         ; and forcing SP2 and CNT2 to output
  1354.  
  1355.         Initialization:   ; This is executed when I/O is switched on
  1356.                 LDA $DD0E ; CIA 2's Control Register A
  1357.                 AND #$FE  ; Stop Timer A
  1358.                 ORA #$40  ; Set Serial Port to output
  1359.                 STA $DD0E ; (make the SP register to act as a memory place)
  1360.                 LDA #$60
  1361.                 STA $DD0C ; Write RTS to CIA register $C.
  1362.  
  1363.         Exiting:          ; NOTE: This procedure must start at CIA 2 register
  1364.                           ; $9. As the CIA 2 appears in memory at $DD00+$10*n,
  1365.                           ; where, 0<=n<=$F, you have sixteen alternatives.
  1366.                 PLA
  1367.                 STA $01   ; Restore original memory bank configuration
  1368.                           ; Now the processor fetches the RTS command from
  1369.                           ; the CIA 2 register $C.
  1370.  
  1371.         
  1372.    For instance, if you want to make a highly compatible fast loader, make
  1373.  the ILOAD vector ($0330) point to the beginning of the stack area. Remember
  1374.  that the BASIC interpreter uses the first bytes of stack while converting
  1375.  numbers to text. A good address is $0120. Robust programs practically never
  1376.  use so much stack that it could corrupt this routine. Usually only crunched
  1377.  programs (demos and alike) use all stack in the decompression phase. They
  1378.  also make use of the $D000-$DFFF area.
  1379.  
  1380.    This stack routine will jump to your routine at $D000-$DFFF, as described
  1381.  above. For performance's sake, copy the whole byte transfer loop to the swap
  1382.  area, e.g. $C000-$C1FF, and call that subroutine after doing the preliminary
  1383.  work. But what about files that load over $C000-$C1FF? Wouldn't that destroy
  1384.  the transfer loop and jam the machine? Not necessarily. If you copy those
  1385.  bytes to your swap area at $D000-$DFFF, they will be loaded properly, as
  1386.  your program restores the original $C000-$C1FF area.
  1387.  
  1388.    If you want to make your program user-friendly, put a vector initialization
  1389.  routine to the stack area as well, so that the user can restore the fast
  1390.  loader by issuing a SYS command, rather than loading it each time he has
  1391.  pressed STOP & RESTORE or RESET.
  1392.  
  1393.  
  1394.  
  1395.                 NOTES
  1396.  
  1397.  See MCS 6500 Microcomputer Family Programming Manual for more information.
  1398.  There is also a table showing functional description and timing for complete
  1399.  6510 instruction set on C=Hacking magazine issue 1/92 (available via FTP at
  1400.  ccosun.caltech.edu:/pub/rknop/hacking.mag/ and
  1401.  nic.funet.fi:/pub/cbm/c=hacking/).
  1402.  
  1403.  
  1404.  References:
  1405.   C64 Memory Maps       C64 Programmer's Reference Guide pp. 262-267
  1406.   6510 Block Diagram    C64 Programmer's Reference Guide  p. 404
  1407.   Instruction Set       C64 Programmer's Reference Guide pp. 416-417
  1408.                         C=Hacking Volume 1, issue #1, 1/92
  1409.                         C=Lehti magazine 4/87
  1410. =============================================================================
  1411.  
  1412.