home *** CD-ROM | disk | FTP | other *** search
/ CBM Funet Archive / cbm-funet-archive-2003.iso / cbm / documents / chipdata / 64doc < prev    next >
Encoding:
Text File  |  1997-07-30  |  81.4 KB  |  1,945 lines

  1. # $iD: 64DOC,V 1.8 1994/06/03 19:50:04 JOPI eXP $
  2. #
  3. # tHIS FILE IS PART OF cOMMODORE 64 EMULATOR
  4. #      AND pROGRAM dEVELOPMENT sYSTEM.
  5. #
  6. # sEE readme FOR COPYRIGHT NOTICE
  7. #
  8. # tHIS FILE CONTAINS DOCUMENTATION FOR 6502/6510/8500/8502 INSTRUCTION SET.
  9. #
  10. #
  11. # wRITTEN BY 
  12. #   jOHN wEST    (JOHN@UCC.GU.UWA.EDU.AU)
  13. #   mARKO m{$e4}KEL{$e4} (mARKO.mAKELA@hut.fi)
  14. #
  15. #
  16. # $lOG: 64DOC,V $
  17. # rEVISION 1.8  1994/06/03  19:50:04  JOPI
  18. # pATCHLEVEL 2
  19. #
  20. # rEVISION 1.7  1994/04/15  13:07:04  JOPI
  21. # 65XX rEGISTER DESCRIPTIONS ADDED
  22. #
  23. # rEVISION 1.6  1994/02/18  16:09:36  JOPI
  24. #
  25. # rEVISION 1.5  1994/01/26  16:08:37  JOPI
  26. # x64 VERSION 0.2 pl 1
  27. #
  28. # rEVISION 1.4  1993/11/10  01:55:34  JOPI
  29. #
  30. # rEVISION 1.3  93/06/21  13:37:18  JOPI
  31. #  x64 VERSION 0.2 pl 0
  32. # rEVISION 1.2  93/06/21  13:07:15  JOPI
  33. # *** EMPTY LOG MESSAGE ***
  34. #
  35.  
  36.  nOTE: tO EXTRACT THE UUENCODED ml PROGRAMS IN THIS ARTICLE MOST
  37.        EASILY YOU MAY USE E.G. "UUD" BY eDWIN kREMER <EDWIN@ZLOTTY>,
  38.        WHICH EXTRACTS THEM ALL AT ONCE.
  39.  
  40.  
  41.  
  42.     dOCUMENTATION FOR THE nmos 65XX/85XX iNSTRUCTION sET
  43.  
  44.         6510 iNSTRUCTIONS BY aDDRESSING mODES
  45.         6502 rEGISTERS
  46.         6510/8502 uNDOCUMENTED cOMMANDS
  47.         rEGISTER SELECTION FOR LOAD AND STORE
  48.         dECIMAL MODE IN nmos 6500 SERIES
  49.         6510 FEATURES
  50.         dIFFERENT cpu TYPES
  51.         6510 iNSTRUCTION tIMING
  52.         hOW rEAL pROGRAMMERS aCKNOWLEDGE iNTERRUPTS
  53.         mEMORY mANAGEMENT
  54.         aUTOSTART cODE
  55.         nOTES
  56.         rEFERENCES
  57.  
  58.  
  59.                 6510 iNSTRUCTIONS BY aDDRESSING mODES
  60.  
  61. OFF- ++++++++++ pOSITIVE ++++++++++  ---------- nEGATIVE ----------
  62. SET  00      20      40      60      80      A0      C0      E0      MODE
  63.  
  64. +00  brk     jsr     rti     rts     nop*    ldy     cpy     cpx     iMPL/IMMED
  65. +01  ora     and     eor     adc     sta     lda     cmp     sbc     (INDIR,X)
  66. +02   T       T       T       T      nop*T   ldx     nop*T   nop*T     ? /IMMED
  67. +03  slo*    rla*    sre*    rra*    sax*    lax*    dcp*    isb*    (INDIR,X)
  68. +04  nop*    bit     nop*    nop*    sty     ldy     cpy     cpx     zEROPAGE
  69. +05  ora     and     eor     adc     sta     lda     cmp     sbc     zEROPAGE
  70. +06  asl     rol     lsr     ror     stx     ldx     dec     inc     zEROPAGE
  71. +07  slo*    rla*    sre*    rra*    sax*    lax*    dcp*    isb*    zEROPAGE
  72.  
  73. +08  php     plp     pha     pla     dey     tay     iny     inx     iMPLIED
  74. +09  ora     and     eor     adc     nop*    lda     cmp     sbc     iMMEDIATE
  75. +0A  asl     rol     lsr     ror     txa     tax     dex     nop     aCCU/IMPL
  76. +0B  anc**   anc**   asr**   arr**   ane**   lxa**   sbx**   sbc*    iMMEDIATE
  77. +0C  nop*    bit     jmp     jmp  () sty     ldy     cpy     cpx     aBSOLUTE
  78. +0D  ora     and     eor     adc     sta     lda     cmp     sbc     aBSOLUTE
  79. +0E  asl     rol     lsr     ror     stx     ldx     dec     inc     aBSOLUTE
  80. +0F  slo*    rla*    sre*    rra*    sax*    lax*    dcp*    isb*    aBSOLUTE
  81.  
  82. +10  bpl     bmi     bvc     bvs     bcc     bcs     bne     beq     rELATIVE
  83. +11  ora     and     eor     adc     sta     lda     cmp     sbc     (INDIR),Y
  84. +12   T       T       T       T       T       T       T       T         ?
  85. +13  slo*    rla*    sre*    rra*    sha**   lax*    dcp*    isb*    (INDIR),Y
  86. +14  nop*    nop*    nop*    nop*    sty     ldy     nop*    nop*    zEROPAGE,X
  87. +15  ora     and     eor     adc     sta     lda     cmp     sbc     zEROPAGE,X
  88. +16  asl     rol     lsr     ror     stx  Y) ldx  Y) dec     inc     zEROPAGE,X
  89. +17  slo*    rla*    sre*    rra*    sax* Y) lax* Y) dcp*    isb*    zEROPAGE,X
  90.  
  91. +18  clc     sec     cli     sei     tya     clv     cld     sed     iMPLIED
  92. +19  ora     and     eor     adc     sta     lda     cmp     sbc     aBSOLUTE,Y
  93. +1A  nop*    nop*    nop*    nop*    txs     tsx     nop*    nop*    iMPLIED
  94. +1B  slo*    rla*    sre*    rra*    shs**   las**   dcp*    isb*    aBSOLUTE,Y
  95. +1C  nop*    nop*    nop*    nop*    shy**   ldy     nop*    nop*    aBSOLUTE,X
  96. +1D  ora     and     eor     adc     sta     lda     cmp     sbc     aBSOLUTE,X
  97. +1E  asl     rol     lsr     ror     shx**Y) ldx  Y) dec     inc     aBSOLUTE,X
  98. +1F  slo*    rla*    sre*    rra*    sha**Y) lax* Y) dcp*    isb*    aBSOLUTE,X
  99.  
  100.  
  101. ror INTRUCTION IS AVAILABLE ON mc650X MICROPROCESSORS AFTER
  102. jUNE, 1976.
  103.  
  104.  
  105.         lEGEND:
  106.  
  107.         T       jAMS THE MACHINE
  108.         *T      jAMS VERY RARELY
  109.         *       uNDOCUMENTED COMMAND
  110.         **      uNUSUAL OPERATION
  111.         Y)      INDEXED USING y INSTEAD OF x
  112.         ()      INDIRECT INSTEAD OF ABSOLUTE
  113.  
  114.         nOTE THAT THE nop INSTRUCTIONS DO HAVE OTHER ADDRESSING MODES
  115.         THAN THE IMPLIED ADDRESSING. tHE nop INSTRUCTION IS JUST LIKE
  116.         ANY OTHER LOAD INSTRUCTION, EXCEPT IT DOES NOT STORE THE
  117.         RESULT ANYWHERE NOR AFFECTS THE FLAGS.
  118.  
  119.  
  120.                 6502 rEGISTERS
  121.  
  122.   tHE nmos 65XX PROCESSORS ARE NOT RUINED WITH TOO MANY REGISTERS. iN
  123. ADDITION TO THAT, THE REGISTERS ARE MOSTLY 8-BIT. hERE IS A BRIEF
  124. DESCRIPTION OF EACH REGISTER:
  125.  
  126.        pc   pROGRAM cOUNTER
  127.  
  128.             tHIS REGISTER POINTS THE ADDRESS FROM WHICH THE NEXT
  129.             INSTRUCTION BYTE (OPCODE OR PARAMETER) WILL BE FETCHED.
  130.             uNLIKE OTHER REGISTERS, THIS ONE IS 16 BITS IN LENGTH. tHE
  131.             LOW AND HIGH 8-BIT HALVES OF THE REGISTER ARE CALLED pcl
  132.             AND pch, RESPECTIVELY.
  133.  
  134.             tHE pROGRAM cOUNTER MAY BE READ BY PUSHING ITS VALUE ON
  135.             THE STACK. tHIS CAN BE DONE EITHER BY JUMPING TO A
  136.             SUBROUTINE OR BY CAUSING AN INTERRUPT.
  137.  
  138.        s    sTACK POINTER
  139.  
  140.             tHE nmos 65XX PROCESSORS HAVE 256 BYTES OF STACK MEMORY,
  141.             RANGING FROM $0100 TO $01ff. tHE s REGISTER IS A 8-BIT
  142.             OFFSET TO THE STACK PAGE. iN OTHER WORDS, WHENEVER
  143.             ANYTHING IS BEING PUSHED ON THE STACK, IT WILL BE STORED
  144.             TO THE ADDRESS $0100+s.
  145.  
  146.             tHE sTACK POINTER CAN BE READ AND WRITTEN BY TRANSFERING
  147.             ITS VALUE TO OR FROM THE INDEX REGISTER x (SEE BELOW) WITH
  148.             THE tsx AND txs INSTRUCTIONS.
  149.  
  150.        p    pROCESSOR STATUS
  151.  
  152.             tHIS 8-BIT REGISTER STORES THE STATE OF THE PROCESSOR. tHE
  153.             BITS IN THIS REGISTER ARE CALLED FLAGS. mOST OF THE FLAGS
  154.             HAVE SOMETHING TO DO WITH ARITHMETIC OPERATIONS.
  155.  
  156.             tHE p REGISTER CAN BE READ BY PUSHING IT ON THE STACK
  157.             (WITH php OR BY CAUSING AN INTERRUPT). iF YOU ONLY NEED TO
  158.             READ ONE FLAG, YOU CAN USE THE BRANCH INSTRUCTIONS.
  159.             sETTING THE FLAGS IS POSSIBLE BY PULLING THE p REGISTER
  160.             FROM STACK OR BY USING THE FLAG SET OR CLEAR INSTRUCTIONS.
  161.  
  162.             fOLLOWING IS A LIST OF THE FLAGS, STARTING FROM THE 8TH
  163.             BIT OF THE p REGISTER (BIT 7, VALUE $80):
  164.  
  165.             n   nEGATIVE FLAG
  166.  
  167.                 tHIS FLAG WILL BE SET AFTER ANY ARITHMETIC OPERATIONS
  168.                 (WHEN ANY OF THE REGISTERS a, x OR y IS BEING LOADED
  169.                 WITH A VALUE). gENERALLY, THE n FLAG WILL BE COPIED
  170.                 FROM THE TOPMOST BIT OF THE REGISTER BEING LOADED.
  171.  
  172.                 nOTE THAT txs (tRANSFER x TO s) IS NOT AN ARITHMETIC
  173.                 OPERATION. aLSO NOTE THAT THE bit INSTRUCTION AFFECTS
  174.                 THE nEGATIVE FLAG JUST LIKE ARITHMETIC OPERATIONS.
  175.                 fINALLY, THE nEGATIVE FLAG BEHAVES DIFFERENTLY IN
  176.                 dECIMAL OPERATIONS (SEE DESCRIPTION BELOW).
  177.  
  178.             v   OvERFLOW FLAG
  179.  
  180.                 lIKE THE nEGATIVE FLAG, THIS FLAG IS INTENDED TO BE
  181.                 USED WITH 8-BIT SIGNED INTEGER NUMBERS. tHE FLAG WILL
  182.                 BE AFFECTED BY ADDITION AND SUBTRACTION, THE
  183.                 INSTRUCTIONS plp, clv AND bit, AND THE HARDWARE SIGNAL
  184.                 -so. nOTE THAT THERE IS NO sev INSTRUCTION, EVEN THOUGH
  185.                 THE mos ENGINEERS LOVED TO USE eAST eUROPEAN ABBREVIATIONS,
  186.                 LIKE ddr (dEUTSCHE dEMOKRATISCHE rEPUBLIK VS. dATA
  187.                 dIRECTION rEGISTER). (tHE rUSSIAN ABBREVIATION FOR THEIR
  188.                 FORMER TRADE ASSOCIATION comecon IS sev.) tHE -so
  189.                 (sET oVERFLOW) SIGNAL IS AVAILABLE ON SOME PROCESSORS,
  190.                 AT LEAST THE 6502, TO SET THE v FLAG. tHIS ENABLES
  191.                 RESPONSE TO AN i/o ACTIVITY IN EQUAL OR LESS THAN
  192.                 THREE CLOCK CYCLES WHEN USING A bvc INSTRUCTION BRANCHING
  193.                 TO ITSELF ($50 $fe).
  194.  
  195.                 tHE clv INSTRUCTION CLEARS THE v FLAG, AND THE plp AND
  196.                 bit INSTRUCTIONS COPY THE FLAG VALUE FROM THE BIT 6 OF
  197.                 THE TOPMOST STACK ENTRY OR FROM MEMORY.
  198.  
  199.                 aFTER A BINARY ADDITION OR SUBTRACTION, THE v FLAG
  200.                 WILL BE SET ON A SIGN OVERFLOW, CLEARED OTHERWISE.
  201.                 wHAT IS A SIGN OVERFLOW?  fOR INSTANCE, IF YOU ARE
  202.                 TRYING TO ADD 123 AND 45 TOGETHER, THE RESULT (168)
  203.                 DOES NOT FIT IN A 8-BIT SIGNED INTEGER (UPPER LIMIT
  204.                 127 AND LOWER LIMIT -128). sIMILARLY, ADDING -123 TO
  205.                 -45 CAUSES THE OVERFLOW, JUST LIKE SUBTRACTING -45
  206.                 FROM 123 OR 123 FROM -45 WOULD DO.
  207.  
  208.                 lIKE THE n FLAG, THE v FLAG WILL NOT BE SET AS
  209.                 EXPECTED IN THE dECIMAL MODE. lATER IN THIS DOCUMENT
  210.                 IS A PRECISE OPERATION DESCRIPTION.
  211.  
  212.                 a COMMON MISBELIEF IS THAT THE v FLAG COULD ONLY BE
  213.                 SET BY ARITHMETIC OPERATIONS, NOT CLEARED.
  214.  
  215.             1   UNUSED FLAG
  216.  
  217.                 tO THE CURRENT KNOWLEDGE, THIS FLAG IS ALWAYS 1.
  218.  
  219.             b   bREAK FLAG
  220.  
  221.                 tHIS FLAG IS USED TO DISTINGUISH SOFTWARE (brk)
  222.                 INTERRUPTS FROM HARDWARE INTERRUPTS (irq OR nmi). tHE
  223.                 b FLAG IS ALWAYS SET EXCEPT WHEN THE p REGISTER IS
  224.                 BEING PUSHED ON STACK WHEN JUMPING TO AN INTERRUPT
  225.                 ROUTINE TO PROCESS ONLY A HARDWARE INTERRUPT.
  226.  
  227.                 tHE OFFICIAL nmos 65XX DOCUMENTATION CLAIMS THAT THE
  228.                 brk INSTRUCTION COULD ONLY CAUSE A JUMP TO THE irq
  229.                 VECTOR ($fffe). hOWEVER, IF AN nmi INTERRUPT OCCURS
  230.                 WHILE EXECUTING A brk INSTRUCTION, THE PROCESSOR WILL
  231.                 JUMP TO THE nmi VECTOR ($fffa), AND THE p REGISTER
  232.                 WILL BE PUSHED ON THE STACK WITH THE b FLAG SET.
  233.  
  234.             d   dECIMAL MODE FLAG
  235.  
  236.                 tHIS FLAG IS USED TO SELECT THE (bINARY cODED) dECIMAL
  237.                 MODE FOR ADDITION AND SUBTRACTION. iN MOST
  238.                 APPLICATIONS, THE FLAG IS ZERO.
  239.  
  240.                 tHE dECIMAL MODE HAS MANY ODDITIES, AND IT OPERATES
  241.                 DIFFERENTLY ON cmos PROCESSORS. sEE THE DESCRIPTION
  242.                 OF THE adc, sbc AND arr INSTRUCTIONS BELOW.
  243.  
  244.             i   iNTERRUPT DISABLE FLAG
  245.  
  246.                 tHIS FLAG CAN BE USED TO PREVENT THE PROCESSOR FROM
  247.                 JUMPING TO THE irq HANDLER VECTOR ($fffe) WHENEVER THE
  248.                 HARDWARE LINE -irq IS ACTIVE. tHE FLAG WILL BE
  249.                 AUTOMATICALLY SET AFTER TAKING AN INTERRUPT, SO THAT
  250.                 THE PROCESSOR WOULD NOT KEEP JUMPING TO THE INTERRUPT
  251.                 ROUTINE IF THE -irq SIGNAL REMAINS LOW FOR SEVERAL
  252.                 CLOCK CYCLES.
  253.  
  254.             z   zERO FLAG
  255.  
  256.                 tHE zERO FLAG WILL BE AFFECTED IN THE SAME CASES THAN
  257.                 THE nEGATIVE FLAG. gENERALLY, IT WILL BE SET IF AN
  258.                 ARITHMETIC REGISTER IS BEING LOADED WITH THE VALUE
  259.                 ZERO, AND CLEARED OTHERWISE. tHE FLAG WILL BEHAVE
  260.                 DIFFERENTLY IN dECIMAL OPERATIONS.
  261.  
  262.             c   cARRY FLAG
  263.  
  264.                 tHIS FLAG IS USED IN ADDITIONS, SUBTRACTIONS,
  265.                 COMPARISONS AND BIT ROTATIONS. iN ADDITIONS AND
  266.                 SUBTRACTIONS, IT ACTS AS A 9TH BIT AND LETS YOU TO
  267.                 CHAIN OPERATIONS TO CALCULATE WITH BIGGER THAN 8-BIT
  268.                 NUMBERS. wHEN SUBTRACTING, THE cARRY FLAG IS THE
  269.                 NEGATIVE OF bORROW: IF AN OVERFLOW OCCURS, THE FLAG
  270.                 WILL BE CLEAR, OTHERWISE SET. cOMPARISONS ARE A
  271.                 SPECIAL CASE OF SUBTRACTION: THEY ASSUME cARRY FLAG
  272.                 SET AND dECIMAL FLAG CLEAR, AND DO NOT STORE THE
  273.                 RESULT OF THE SUBTRACTION ANYWHERE.
  274.  
  275.                 tHERE ARE FOUR KINDS OF BIT ROTATIONS. aLL OF THEM
  276.                 STORE THE BIT THAT IS BEING ROTATED OFF TO THE cARRY
  277.                 FLAG. tHE LEFT SHIFTING INSTRUCTIONS ARE rol AND asl.
  278.                 rol COPIES THE INITIAL cARRY FLAG TO THE LOWMOST BIT
  279.                 OF THE BYTE; asl ALWAYS CLEARS IT. sIMILARLY, THE ror
  280.                 AND lsr INSTRUCTIONS SHIFT TO THE RIGHT.
  281.  
  282.        a    aCCUMULATOR
  283.  
  284.             tHE ACCUMULATOR IS THE MAIN REGISTER FOR ARITHMETIC AND
  285.             LOGIC OPERATIONS. uNLIKE THE INDEX REGISTERS x AND y, IT
  286.             HAS A DIRECT CONNECTION TO THE aRITHMETIC AND lOGIC uNIT
  287.             (alu). tHIS IS WHY MANY OPERATIONS ARE ONLY AVAILABLE FOR
  288.             THE ACCUMULATOR, NOT THE INDEX REGISTERS.
  289.  
  290.        x    iNDEX REGISTER x
  291.  
  292.             tHIS IS THE MAIN REGISTER FOR ADDRESSING DATA WITH
  293.             INDICES. iT HAS A SPECIAL ADDRESSING MODE, INDEXED
  294.             INDIRECT, WHICH LETS YOU TO HAVE A VECTOR TABLE ON THE
  295.             ZERO PAGE.
  296.  
  297.        y    iNDEX REGISTER y
  298.  
  299.             tHE y REGISTER HAS THE LEAST OPERATIONS AVAILABLE. oN THE
  300.             OTHER HAND, ONLY IT HAS THE INDIRECT INDEXED ADDRESSING
  301.             MODE THAT ENABLES ACCESS TO ANY MEMORY PLACE WITHOUT
  302.             HAVING TO USE SELF-MODIFYING CODE.
  303.  
  304.  
  305.  
  306.                 6510/8502 uNDOCUMENTED cOMMANDS
  307.  
  308.          -- a BRIEF EXPLANATION ABOUT WHAT MAY HAPPEN WHILE
  309.                 USING DON'T CARE STATES.
  310.  
  311.  
  312.         ane $8b         a = (a {$7c} #$ee) & x & #BYTE
  313.                         SAME AS
  314.                         a = ((a & #$11 & x) {$7c} ( #$ee & x)) & #BYTE
  315.  
  316.                         iN REAL 6510/8502 THE INTERNAL PARAMETER #$11
  317.                         MAY OCCASIONALLY BE #$10, #$01 OR EVEN #$00.
  318.                         tHIS OCCURS WHEN THE VIDEO CHIP STARTS dma
  319.                         BETWEEN THE OPCODE FETCH AND THE PARAMETER FETCH
  320.                         OF THE INSTRUCTION.  tHE VALUE PROBABLY DEPENDS
  321.                         ON THE DATA THAT WAS LEFT ON THE BUS BY THE vic-ii.
  322.  
  323.         lxa $ab         c=lEHTI:   a = x = ane
  324.                         aLTERNATE: a = x = (a & #BYTE)
  325.  
  326.                         txa AND tax HAVE TO BE RESPONSIBLE FOR THESE.
  327.  
  328.         sha $93,$9f     sTORE (a & x & (addr_hi + 1))
  329.         shx $9e         sTORE (x & (addr_hi + 1))
  330.         shy $9c         sTORE (y & (addr_hi + 1))
  331.         shs $9b         sha AND txs, WHERE x IS REPLACED BY (a & x).
  332.  
  333.                         nOTE: tHE VALUE TO BE STORED IS COPIED ALSO
  334.                         TO addr_hi IF PAGE BOUNDARY IS CROSSED.
  335.  
  336.         sbx $cb         cARRY AND dECIMAL FLAGS ARE IGNORED BUT THE
  337.                         cARRY FLAG WILL BE SET IN SUBSTRACTION. tHIS
  338.                         IS DUE TO THE cmp COMMAND, WHICH IS EXECUTED
  339.                         INSTEAD OF THE REAL sbc.
  340.  
  341.         arr $6b         tHIS INSTRUCTION FIRST PERFORMS AN and
  342.                         BETWEEN THE ACCUMULATOR AND THE IMMEDIATE
  343.                         PARAMETER, THEN IT SHIFTS THE ACCUMULATOR TO
  344.                         THE RIGHT. hOWEVER, THIS IS NOT THE WHOLE
  345.                         TRUTH. sEE THE DESCRIPTION BELOW.
  346.  
  347. mANY UNDOCUMENTED COMMANDS DO NOT USE and BETWEEN REGISTERS, THE cpu
  348. JUST THROWS THE BYTES TO A BUS SIMULTANEOUSLY AND LETS THE
  349. OPEN-COLLECTOR DRIVERS PERFORM THE and. i.E. THE COMMAND CALLED 'sax',
  350. WHICH IS IN THE store SECTION (OPCODES $a0...$bf), STORES THE RESULT
  351. OF (a & x) BY THIS WAY.
  352.  
  353. mORE FORTUNATE IS ITS OPPOSITE, 'lax' WHICH JUST LOADS A BYTE
  354. SIMULTANEOUSLY INTO BOTH a AND x.
  355.  
  356.  
  357.         $6b  arr
  358.  
  359. tHIS INSTRUCTION SEEMS TO BE A HARMLESS COMBINATION OF and AND ror AT
  360. FIRST SIGHT, BUT IT TURNS OUT THAT IT AFFECTS THE v FLAG AND ALSO HAS
  361. A SPECIAL KIND OF DECIMAL MODE. tHIS IS BECAUSE THE INSTRUCTION HAS
  362. INHERITED SOME PROPERTIES OF THE adc INSTRUCTION ($69) IN ADDITION TO
  363. THE ror ($6a).
  364.  
  365. iN bINARY MODE (d FLAG CLEAR), THE INSTRUCTION EFFECTIVELY DOES AN and
  366. BETWEEN THE ACCUMULATOR AND THE IMMEDIATE PARAMETER, AND THEN SHIFTS
  367. THE ACCUMULATOR TO THE RIGHT, COPYING THE c FLAG TO THE 8TH BIT. iT
  368. SETS THE nEGATIVE AND zERO FLAGS JUST LIKE THE ror WOULD. tHE adc CODE
  369. SHOWS UP IN THE cARRY AND OvERFLOW FLAGS. tHE c FLAG WILL BE COPIED
  370. FROM THE BIT 6 OF THE RESULT (WHICH DOESN'T SEEM TOO LOGICAL), AND THE
  371. v FLAG IS THE RESULT OF AN eXCLUSIVE or OPERATION BETWEEN THE BIT 6
  372. AND THE BIT 5 OF THE RESULT.  tHIS MAKES SENSE, SINCE THE v FLAG WILL
  373. BE NORMALLY SET BY AN eXCLUSIVE or, TOO.
  374.  
  375. iN dECIMAL MODE (d FLAG SET), THE arr INSTRUCTION FIRST PERFORMS THE
  376. and AND ror, JUST LIKE IN bINARY MODE. tHE n FLAG WILL BE COPIED FROM
  377. THE INITIAL c FLAG, AND THE z FLAG WILL BE SET ACCORDING TO THE ror
  378. RESULT, AS EXPECTED. tHE v FLAG WILL BE SET IF THE BIT 6 OF THE
  379. ACCUMULATOR CHANGED ITS STATE BETWEEN THE and AND THE ror, CLEARED
  380. OTHERWISE.
  381.  
  382. nOW COMES THE FUNNY PART. iF THE LOW NYBBLE OF THE and RESULT,
  383. INCREMENTED BY ITS LOWMOST BIT, IS GREATER THAN 5, THE LOW NYBBLE IN
  384. THE ror RESULT WILL BE INCREMENTED BY 6. tHE LOW NYBBLE MAY OVERFLOW
  385. AS A CONSEQUENCE OF THIS bcd FIXUP, BUT THE HIGH NYBBLE WON'T BE
  386. ADJUSTED. tHE HIGH NYBBLE WILL BE bcd FIXED IN A SIMILAR WAY. iF THE
  387. HIGH NYBBLE OF THE and RESULT, INCREMENTED BY ITS LOWMOST BIT, IS
  388. GREATER THAN 5, THE HIGH NYBBLE IN THE ror RESULT WILL BE INCREMENTED
  389. BY 6, AND THE cARRY FLAG WILL BE SET. oTHERWISE THE c FLAG WILL BE
  390. CLEARED.
  391.  
  392. tO HELP YOU UNDERSTAND THIS DESCRIPTION, HERE IS A c ROUTINE THAT
  393. ILLUSTRATES THE arr OPERATION IN dECIMAL MODE:
  394.  
  395.         UNSIGNED
  396.            a,  /* aCCUMULATOR */
  397.            al, /* LOW NYBBLE OF ACCUMULATOR */
  398.            ah, /* HIGH NYBBLE OF ACCUMULATOR */
  399.  
  400.            c,  /* cARRY FLAG */
  401.            z,  /* zERO FLAG */
  402.            v,  /* OvERFLOW FLAG */
  403.            n,  /* nEGATIVE FLAG */
  404.  
  405.            T,  /* TEMPORARY VALUE */
  406.            S;  /* VALUE TO BE arrED WITH aCCUMULATOR */
  407.  
  408.         T = a & S;                      /* pERFORM THE and. */
  409.  
  410.         ah = T >> 4;                    /* sEPARATE THE HIGH */
  411.         al = T & 15;                    /* AND LOW NYBBLES. */
  412.  
  413.         n = c;                          /* sET THE n AND */
  414.         z = !(a = (T >> 1) {$7c} (c << 7)); /* z FLAGS TRADITIONALLY */
  415.         v = (T ^ a) & 64;               /* AND v FLAG IN A WEIRD WAY. */
  416.  
  417.         IF (al + (al & 1) > 5)          /* bcd "FIXUP" FOR LOW NYBBLE. */
  418.           a = (a & 0Xf0) {$7c} ((a + 6) & 0Xf);
  419.  
  420.         IF (c = ah + (ah & 1) > 5)      /* sET THE cARRY FLAG. */
  421.           a = (a + 0X60) & 0Xff;        /* bcd "FIXUP" FOR HIGH NYBBLE. */
  422.  
  423.  
  424.  
  425.         $cb  sbx   x <- (a & x) - iMMEDIATE
  426.  
  427. tHE 'sbx' ($cb) MAY SEEM TO BE VERY COMPLEX OPERATION, EVEN THOUGH IT
  428. IS A COMBINATION OF THE SUBTRACTION OF ACCUMULATOR AND PARAMETER, AS
  429. IN THE 'cmp' INSTRUCTION, AND THE COMMAND 'dex'. aS A RESULT, BOTH a
  430. AND x ARE CONNECTED TO alu BUT ONLY THE SUBTRACTION TAKES PLACE. sINCE
  431. THE COMPARISON LOGIC WAS USED, THE RESULT OF SUBTRACTION SHOULD BE
  432. NORMALLY IGNORED, BUT THE 'dex' NOW HAPPILY STORES TO x THE VALUE OF
  433. (a & x) - iMMEDIATE.  tHAT IS WHY THIS INSTRUCTION DOES NOT HAVE ANY
  434. DECIMAL MODE, AND IT DOES NOT AFFECT THE v FLAG. aLSO cARRY FLAG WILL
  435. BE IGNORED IN THE SUBTRACTION BUT SET ACCORDING TO THE RESULT.
  436.  
  437.  pROOF:
  438.  
  439. BEGIN 644 VSBX
  440. m{$60}0@9$,d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}*d{$60}h#v1*z{$60}_d2n@09$kj0>%
  441. m^qbe^vezj+$kh#f1*zd{$60}2"bi{$60}*({$60}rp{$60}(:-b@.5$k*4#p{$60}e@{$60}h#vq*sai{$60})$k
  442. jd-z@/[$k:0"1*y#4j2x@to\xh$&q*vd{$60}d2n0q,;[$+188/_^]_:_ok>v
  443. {$60}
  444. END
  445.  
  446.  AND
  447.  
  448. BEGIN 644 SBX
  449. m{$60}0@9$,d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi{$60}*!-d2n@3y$kh%&1*zd#
  450. ma?l8i?m*2){$60}#j1@lj3b@29$k:$j0{$60}zgx+*g8r)$k&/bxj?2b8\l)aop(:(7]
  451. mv#b@3;$kh$\q*z!1\2l(1?sp{$60}0!h1?tim]#xh$vq*sai{$60})$kd,n@3[$k:0"1
  452. 9*y#!j2x@to\xh%&q*vd{$60}d2n0l<;[$))88-#x
  453. {$60}
  454. END
  455.  
  456. tHESE TEST PROGRAMS SHOW IF YOUR MACHINE IS COMPATIBLE WITH OURS
  457. REGARDING THE OPCODE $cb. tHE FIRST TEST, VSBX, PROVES THAT sbx DOES
  458. NOT AFFECT THE v FLAG. tHE LATTER ONE, SBX, PROVES THE REST OF OUR
  459. THEORY. tHE VSBX TEST TESTS 33554432 sbx COMBINATIONS (16777216
  460. DIFFERENT a, x AND iMMEDIATE COMBINATIONS, AND TWO DIFFERENT v FLAG
  461. STATES), AND THE SBX TEST DOUBLES THAT AMOUNT (16777216*4 d AND c FLAG
  462. COMBINATIONS). bOTH TESTS HAVE RUN SUCCESSFULLY ON A c64 AND A vIC20.
  463. tHEY OUGHT TO RUN ON c16, +4 AND THE pet SERIES AS WELL. tHE TESTS
  464. STOP WITH brk, IF THE OPCODE $cb DOES NOT WORK AS EXPECTED. sUCCESSFUL
  465. OPERATION ENDS IN rts. aS THE TESTS ARE VERY SLOW, THEY PRINT DOTS ON
  466. THE SCREEN WHILE RUNNING SO THAT YOU KNOW THAT THE MACHINE HAS NOT
  467. JAMMED. oN COMPUTERS RUNNING AT 1 mhZ, THE FIRST TEST PRINTS
  468. APPROXIMATELY ONE DOT EVERY FOUR SECONDS AND A TOTAL OF 2048 DOTS,
  469. WHEREAS THE SECOND ONE PRINTS HALF THAT AMOUNT, ONE DOT EVERY SEVEN
  470. SECONDS.
  471.  
  472. iF THE TESTS FAIL ON YOUR MACHINE, PLEASE LET US KNOW YOUR PROCESSOR'S
  473. PART NUMBER AND REVISION. iF POSSIBLE, SAVE THE EXECUTABLE (AFTER IT
  474. HAS STOPPED WITH brk) UNDER ANOTHER NAME AND SEND IT TO US SO THAT WE
  475. KNOW AT WHICH STAGE THE PROGRAM STOPPED.
  476.  
  477. tHE FOLLOWING PROGRAM IS A cOMMODORE 64 EXECUTABLE THAT mARKO m{$e4}KEL{$e4}
  478. DEVELOPED WHEN TRYING TO FIND OUT HOW THE v FLAG IS AFFECTED BY sbx.
  479. (iT WAS BELIEVED THAT THE sbx AFFECTS THE FLAG IN A WEIRD WAY, AND
  480. THIS PROGRAM SHOWS HOW sbx SETS THE FLAG DIFFERENTLY FROM sbc.)  yOU
  481. MAY FIND THE SUBROUTINE AT $c150 USEFUL WHEN RESEARCHING OTHER
  482. UNDOCUMENTED INSTRUCTIONS' FLAGS. rUN THE PROGRAM IN A MACHINE
  483. LANGUAGE MONITOR, AS IT MAKES USE OF THE brk INSTRUCTION. tHE RESULT
  484. TABLES WILL BE WRITTEN ON PAGES $c2 AND $c3.
  485.  
  486. BEGIN 644 SBX-C100
  487. m{$60},%xh{$60}",#l&,$,&,$l&xj8*b@ll7aol(:(7\n#bm#l$m$,'m$l$(q?op{$60}b@{$60}
  488. m:$7\\{$60},@4,'n#l'0u.x0p=#/sb#0[a+!t,<{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60})bj\!>m#l$m
  489. l$,'=_\'0":t2p=w_pm{$60}!8,k0z:t.p2t0p9d{$60}pid{$60}!*t2p9d{$60}pyd{$60}!<c0y{$60}{$60}m
  490. {$60}
  491. END
  492.  
  493.  
  494. oTHER UNDOCUMENTED INSTRUCTIONS USUALLY CAUSE TWO PRECEDING OPCODES
  495. BEING EXECUTED. hOWEVER 'nop' SEEMS TO COMPLETELY DISAPPEAR FROM 'sbc'
  496. CODE $eb.
  497.  
  498. tHE MOST DIFFICULT TO COMPREHEND ARE THE REST OF THE INSTRUCTIONS
  499. LOCATED ON THE '$0b' LINE.
  500.  
  501. aLL THE INSTRUCTIONS LOCATED AT THE POSITIVE (LEFT) SIDE OF THIS LINE
  502. SHOULD ROTATE EITHER MEMORY OR THE ACCUMULATOR, BUT THE ADDRESSING
  503. MODE TURNS OUT TO BE IMMEDIATE! nO PROBLEM. jUST READ THE OPERAND, LET
  504. IT BE andED WITH THE ACCUMULATOR AND FINALLY USE ACCUMULATOR
  505. ADDRESSING MODE FOR THE INSTRUCTIONS ABOVE THEM.
  506.  
  507. religion_mode_on
  508. /* tHIS PART OF THE DOCUMENT IS NOT ACCURATE.  yOU CAN
  509.    READ IT AS A FAIRY TALE, BUT DO NOT COUNT ON IT WHEN
  510.    PERFORMING YOUR OWN MEASUREMENTS. */
  511.  
  512. tHE REST TWO INSTRUCTIONS ON THE SAME LINE, CALLED 'ane' AND 'lxa'
  513. ($8b AND $ab RESPECTIVELY) OFTEN GIVE QUITE UNPREDICTABLE RESULTS.
  514. hOWEVER, THE MOST USUAL OPERATION IS TO STORE ((a {$7c} #$EE) & x & #$NN)
  515. TO ACCUMULATOR. nOTE THAT THIS DOES NOT WORK RELIABLY IN A REAL 64!
  516. iN THE cOMMODORE 128 THE OPCODE $8b USES VALUES 8c, cc, ee, AND
  517. OCCASIONALLY 0c AND 8e FOR THE or INSTEAD OF ee,ef,fe AND ff USED IN
  518. THE c64. wITH A c128 RUNNING AT 2 mhZ #$ee IS ALWAYS USED.  oPCODE $ab
  519. DOES NOT CAUSE THIS or TAKING PLACE ON 8502 WHILE 6510 ALWAYS PERFORMS
  520. IT. nOTE THAT THIS BEHAVIOUR DEPENDS ON PROCESSOR AND/OR VIDEO CHIP
  521. REVISION.
  522.  
  523. lET'S TAKE A CLOSER LOOK AT $8b (6510).
  524.  
  525.         a <- x & d & (a {$7c} val)
  526.  
  527.         WHERE val COMES FROM THIS TABLE:
  528.  
  529.        x HIGH   d HIGH  d LOW   val
  530.         EVEN     EVEN    ---    $ee (1)
  531.         EVEN     ODD     ---    $ee
  532.         ODD      EVEN    ---    $ee
  533.         ODD      ODD      0     $ee
  534.         ODD      ODD     NOT 0  $fe (2)
  535.  
  536. (1) iF THE BOTTOM 2 BITS OF a ARE BOTH 1, THEN THE lsb OF THE RESULT MAY
  537.     BE 0. tHE VALUES OF x AND d ARE DIFFERENT EVERY TIME i RUN THE TEST.
  538.     tHIS APPEARS TO BE VERY RARE.
  539. (2) val IS $fe MOST OF THE TIME. sOMETIMES IT IS $ee - IT SEEMS TO BE RANDOM,
  540.     NOT RELATED TO ANY OF THE DATA. tHIS IS MUCH MORE COMMON THAN (1).
  541.  
  542.   iN DECIMAL MODE, val IS USUALLY $fe.
  543.  
  544.  
  545. tWO DIFFERENT FUNCTIONS HAVE BEEN DISCOVERED FOR lxa, OPCODE $ab. oNE
  546. IS a = x = ane (SEE ABOVE) AND THE OTHER, ENCOUNTERED WITH 6510 AND
  547. 8502, IS LESS COMPLICATED a = x = (a & #BYTE). hOWEVER, ACCORDING TO
  548. WHAT IS REPORTED, THE VERSION ALTERING ONLY THE LOWEST BITS OF EACH
  549. NYBBLE SEEMS TO BE MORE COMMON.
  550.  
  551. wHAT HAPPENS, IS THAT $ab LOADS A VALUE INTO BOTH a AND x, andING THE
  552. LOW BIT OF EACH NYBBLE WITH THE CORRESPONDING BIT OF THE OLD
  553. a. hOWEVER, THERE ARE EXCEPTIONS. sOMETIMES THE LOW BIT IS CLEARED
  554. EVEN WHEN a CONTAINS A '1', AND SOMETIMES OTHER BITS ARE CLEARED. tHE
  555. EXCEPTIONS SEEM RANDOM (THEY CHANGE EVERY TIME i RUN THE TEST). oOPS -
  556. THAT WAS IN DECIMAL MODE. mUCH THE SAME WITH d=0.
  557.  
  558. wHAT CAUSES THE RANDOMNESS?  pROBABLY IT IS THAT IT IS MARGINAL LOGIC
  559. LEVELS - WHEN TOO MUCH WIRED-ANDING GOES ON, SOME OF THE SIGNALS GET
  560. VERY CLOSE TO THE THRESHOLD. pERHAPS WE'RE SEEING SOME OF THEM STEP
  561. OVER IT. tHE LOW BIT OF EACH NYBBLE IS SPECIAL, SINCE IT HAS TO COPE
  562. WITH CARRY DIFFERENTLY (REMEMBER DECIMAL MODE). wE NEVER SEE A '0'
  563. TURN INTO A '1'.
  564.  
  565. sINCE THESE INSTRUCTIONS ARE UNPREDICTABLE, THEY SHOULD NOT BE USED.
  566.  
  567. tHERE IS STILL VERY STRANGE INSTRUCTION LEFT, THE ONE NAMED sha/x/y,
  568. WHICH IS THE ONLY ONE WITH ONLY INDEXED ADDRESSING MODES. aCTUALLY,
  569. THE COMMANDS 'sha', 'shx' AND 'shy' ARE GENERATED BY THE INDEXING
  570. ALGORITHM.
  571.  
  572. wHILE USING INDEXED ADDRESSING, EFFECTIVE ADDRESS FOR PAGE BOUNDARY
  573. CROSSING IS CALCULATED AS SOON AS POSSIBLE SO IT DOES NOT SLOW DOWN
  574. OPERATION. aS A RESULT, IN THE CASE OF sha/x/y, THE ADDRESS AND DATA
  575. ARE PROCESSED AT THE SAME TIME MAKING and BETWEEN THEM TO TAKE PLACE.
  576. tHUS, THE VALUE TO BE STORED BY sax, FOR EXAMPLE, IS IN FACT (a & x &
  577. (addr_hi + 1)).  oN PAGE BOUNDARY CROSSING THE SAME VALUE IS COPIED
  578. ALSO TO HIGH BYTE OF THE EFFECTIVE ADDRESS.
  579.  
  580. religion_mode_off
  581.  
  582.                 rEGISTER SELECTION FOR LOAD AND STORE
  583.  
  584.    BIT1 BIT0     a  x  y
  585.     0    0             X
  586.     0    1          X
  587.     1    0       X
  588.     1    1       X  X
  589.  
  590. sO, a AND x ARE SELECTED BY BITS 1 AND 0 RESPECTIVELY, WHILE
  591. {$7e}(BIT1{$7c}BIT0) ENABLES y.
  592.  
  593. iNDEXING IS DETERMINED BY BIT4, EVEN IN RELATIVE ADDRESSING MODE,
  594. WHICH IS ONE KIND OF INDEXING.
  595.  
  596. lINES CONTAINING OPCODES XXX000X1 (01 AND 03) ARE TREATED AS ABSOLUTE
  597. AFTER THE EFFECTIVE ADDRESS HAS BEEN LOADED INTO cpu.
  598.  
  599. zEROPAGE,Y AND aBSOLUTE,Y (CODES 10X1 X11X) ARE DISTINQUISHED BY BIT5.
  600.  
  601.  
  602.                  dECIMAL MODE IN nmos 6500 SERIES
  603.  
  604.   mOST SOURCES CLAIM THAT THE nmos 6500 SERIES SETS THE n, v AND z
  605. FLAGS UNPREDICTABLY WHEN PERFORMING ADDITION OR SUBTRACTION IN DECIMAL
  606. MODE. oF COURSE, THIS IS NOT TRUE. wHILE TESTING HOW THE FLAGS ARE
  607. SET, i ALSO WANTED TO SEE WHAT HAPPENS IF YOU USE ILLEGAL bcd VALUES.
  608.  
  609.   adc WORKS IN dECIMAL MODE IN A QUITE COMPLICATED WAY. iT IS AMAZING
  610. HOW IT CAN DO THAT ALL IN A SINGLE CYCLE. hERE'S A c CODE VERSION OF
  611. THE INSTRUCTION:
  612.  
  613.         UNSIGNED
  614.            a,  /* aCCUMULATOR */
  615.            al, /* LOW NYBBLE OF ACCUMULATOR */
  616.            ah, /* HIGH NYBBLE OF ACCUMULATOR */
  617.  
  618.            c,  /* cARRY FLAG */
  619.            z,  /* zERO FLAG */
  620.            v,  /* OvERFLOW FLAG */
  621.            n,  /* nEGATIVE FLAG */
  622.  
  623.            S;  /* VALUE TO BE ADDED TO aCCUMULATOR */
  624.  
  625.         al = (a & 15) + (S & 15) + c;         /* cALCULATE THE LOWER NYBBLE. */
  626.  
  627.         ah = (a >> 4) + (S >> 4) + (al > 15); /* cALCULATE THE UPPER NYBBLE. */
  628.  
  629.         IF (al > 9) al += 6;                  /* bcd FIXUP FOR LOWER NYBBLE. */
  630.  
  631.         z = ((a + S + c) & 255 != 0);         /* zERO FLAG IS SET JUST
  632.                                                  LIKE IN bINARY MODE. */
  633.  
  634.         /* nEGATIVE AND oVERFLOW FLAGS ARE SET WITH THE SAME LOGIC THAN IN
  635.            bINARY MODE, BUT AFTER FIXING THE LOWER NYBBLE. */
  636.  
  637.         n = (ah & 8 != 0);
  638.         v = ((ah << 4) ^ a) & 128 && !((a ^ S) & 128);
  639.  
  640.         IF (ah > 9) ah += 6;                  /* bcd FIXUP FOR UPPER NYBBLE. */
  641.  
  642.         /* cARRY IS THE ONLY FLAG SET AFTER FIXING THE RESULT. */
  643.  
  644.         c = (ah > 15);
  645.         a = ((ah << 4) {$7c} (al & 15)) & 255;
  646.  
  647.  
  648.   tHE c FLAG IS SET AS THE QUICHE EATERS EXPECT, BUT THE n AND v FLAGS 
  649. ARE SET AFTER FIXING THE LOWER NYBBLE BUT BEFORE FIXING THE UPPER ONE.
  650. tHEY USE THE SAME LOGIC THAN BINARY MODE adc. tHE z FLAG IS SET BEFORE
  651. ANY bcd FIXUP, SO THE d FLAG DOES NOT HAVE ANY INFLUENCE ON IT.
  652.  
  653. pROOF: tHE FOLLOWING TEST PROGRAM TESTS ALL 131072 adc COMBINATIONS IN
  654.        dECIMAL MODE, AND ABORTS WITH brk IF ANYTHING BREAKS THIS THEORY.
  655.        iF EVERYTHING GOES WELL, IT ENDS IN rts.
  656.  
  657. BEGIN 600 DADC
  658. m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@   'bi&*  a/n$_$b@+)$kh(v1
  659. m*q@(i?pi#x7]i?li#v7]r0j0 fd%j"d/a?ve^rgp9?pi\ c $) ":0^jl @h
  660. ml ?)h) &""@x:5\x!?v%_0ah*3w@ ! ""8"hbd7[$ je^t7\, 28"4"h**7[
  661. m9?s0!)@) j@8n/be^v7\v a%_= g:(3]1?w0(.;[t(?f_-"#:$d8\ )88*d=
  662. 0&&4ka?ni &4la?ri.&s[  a%
  663.  
  664. END
  665.  
  666.   aLL PROGRAMS IN THIS CHAPTER HAVE BEEN SUCCESSFULLY TESTED ON A vIC20
  667. AND A cOMMODORE 64 AND A cOMMODORE 128d IN c64 MODE. tHEY SHOULD RUN ON
  668. c16, +4 AND ON THE pet SERIES AS WELL. iF NOT, PLEASE REPORT THE PROBLEM
  669. TO mARKO m{$e4}KEL{$e4}. eACH TEST IN THIS CHAPTER SHOULD RUN IN LESS THAN A
  670. MINUTE AT 1 mhZ.
  671.  
  672. sbc IS MUCH EASIER. jUST LIKE cmp, ITS FLAGS ARE NOT AFFECTED BY
  673. THE d FLAG.
  674.  
  675. pROOF:
  676.  
  677. BEGIN 600 DSBC-CMP-FLAGS
  678. m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@   'b@ (3[a/rb xh8:66hl2n@
  679. m09$kh$r1*xii::bq*z!%d2n@4)$k^#bxi?oe_-@(:(7].+be^^7\"&a%_? !
  680. 5 .;[t./f_-#?ra"_8!@x&#cey<7%
  681.  
  682. END
  683.  
  684.  
  685.   tHE ONLY DIFFERENCE IN sbc'S OPERATION IN DECIMAL MODE FROM BINARY MODE
  686. IS THE RESULT-FIXUP:
  687.  
  688.         UNSIGNED
  689.            a,  /* aCCUMULATOR */
  690.            al, /* LOW NYBBLE OF ACCUMULATOR */
  691.            ah, /* HIGH NYBBLE OF ACCUMULATOR */
  692.  
  693.            c,  /* cARRY FLAG */
  694.            z,  /* zERO FLAG */
  695.            v,  /* OvERFLOW FLAG */
  696.            n,  /* nEGATIVE FLAG */
  697.  
  698.            S;  /* VALUE TO BE ADDED TO aCCUMULATOR */
  699.  
  700.         al = (a & 15) - (S & 15) - !c;        /* cALCULATE THE LOWER NYBBLE. */
  701.  
  702.         IF (al & 16) al -= 6;                 /* bcd FIXUP FOR LOWER NYBBLE. */
  703.  
  704.         ah = (a >> 4) - (S >> 4) - (al & 16); /* cALCULATE THE UPPER NYBBLE. */
  705.  
  706.         IF (ah & 16) ah -= 6;                 /* bcd FIXUP FOR UPPER NYBBLE. */
  707.  
  708.         /* tHE FLAGS ARE SET JUST LIKE IN bINARY MODE. */
  709.  
  710.         c = (a - S - !c) & 256 != 0;
  711.         z = (a - S - !c) & 255 != 0;
  712.         v = ((a - S - !c) ^ S) & 128 && (a ^ S) & 128;
  713.         n = (a - S - !c) & 128 != 0;
  714.  
  715.         a = ((ah << 4) {$7c} (al & 15)) & 255;
  716.  
  717.  
  718.   aGAIN z FLAG IS SET BEFORE ANY bcd FIXUP. tHE n AND v FLAGS ARE SET
  719. AT ANY TIME BEFORE FIXING THE HIGH NYBBLE. tHE c FLAG MAY BE SET IN ANY
  720. PHASE.
  721.  
  722.   dECIMAL SUBTRACTION IS EASIER THAN DECIMAL ADDITION, AS YOU HAVE TO
  723. MAKE THE bcd FIXUP ONLY WHEN A NYBBLE OVERFLOWS. iN DECIMAL ADDITION,
  724. YOU HAD TO VERIFY IF THE NYBBLE WAS GREATER THAN 9. tHE PROCESSOR HAS
  725. AN INTERNAL "HALF CARRY" FLAG FOR THE LOWER NYBBLE, USED TO TRIGGER
  726. THE bcd FIXUP. wHEN CALCULATING WITH LEGAL bcd VALUES, THE LOWER NYBBLE
  727. CANNOT OVERFLOW AGAIN WHEN FIXING IT.
  728. sO, THE PROCESSOR DOES NOT HANDLE OVERFLOWS WHILE PERFORMING THE FIXUP.
  729. sIMILARLY, THE bcd FIXUP OCCURS IN THE HIGH NYBBLE ONLY IF THE VALUE
  730. OVERFLOWS, I.E. WHEN THE c FLAG WILL BE CLEARED.
  731.  
  732.   bECAUSE sbc'S FLAGS ARE NOT AFFECTED BY THE dECIMAL MODE FLAG, YOU
  733. COULD GUESS THAT cmp USES THE sbc LOGIC, ONLY SETTING THE c FLAG
  734. FIRST. bUT THE sbx INSTRUCTION SHOWS THAT cmp ALSO TEMPORARILY CLEARS
  735. THE d FLAG, ALTHOUGH IT IS TOTALLY UNNECESSARY.
  736.  
  737.   tHE FOLLOWING PROGRAM, WHICH TESTS sbc'S RESULT AND FLAGS,
  738. CONTAINS THE 6502 VERSION OF THE PSEUDO CODE EXAMPLE ABOVE.
  739.  
  740. BEGIN 600 DSBC
  741. m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@   'bi&*  a/n$_$b@+)$kh':1
  742. m*s@(i?pi#x7]i?li#^7]l /i!1@i#zbe_"gpa?ve^rgp"#ce_2gpl ki7rbp
  743. m#nd/.+ )*+ &z0^p ne?a/t%_87]*+be^^7\"&bh.+cxi?oe_-@(1?w0fvb$
  744. 8_47]t)3f^]">yos0ffa)&- $j3c0b%a@
  745.  
  746. END
  747.  
  748.   oBVIOUSLY THE UNDOCUMENTED INSTRUCTIONS rra (ror+adc) AND isb
  749. (inc+sbc) HAVE INHERITED ALSO THE DECIMAL OPERATION FROM THE OFFICIAL
  750. INSTRUCTIONS adc AND sbc. tHE PROGRAM DRORADC PROVES THIS STATEMENT
  751. FOR ror, AND THE DINCSBC TEST PROVES THIS FOR isb. fINALLY,
  752. DINCSBC-DECCMP PROVES THAT isb'S AND dcp'S (dec+cmp) FLAGS ARE NOT
  753. AFFECTED BY THE d FLAG.
  754.  
  755. BEGIN 644 DRORADC
  756. m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi&*{$60}{$60}a/n$_$b@+)$kh(v1
  757. m*s@(i?pi#x7]i?li#v7]r0j0{$60}fd%j"d/a?ve^rgp9?pi\{$60}c{$60}$){$60}":0^jl{$60}@h
  758. ml{$60}?)h){$60}&""@x:5\x!?v%_0ah*3w@{$60}!{$60}""8"hbd7[${$60}je^t7\,{$60}28"4"h**7[
  759. m9?s0!)@){$60}j@xn/be^r;\9_s8"$7]t"=ha/u%_={$60}@yoo0a>;\t(%h21cp{$60}ea@
  760. 2j1t892n%^zd{$60}92r%_*dx;/l{$60}
  761. {$60}
  762. END
  763.  
  764. BEGIN 644 DINCSBC
  765. m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi&*{$60}{$60}a/n$_$b@+)$kh':1
  766. m*s@(i?pi#x7]i?li#^7]l{$60}/i!1@i#zbe_"gpa?ve^rgp"#ce_2gpl{$60}ki7rbp
  767. m#nd/.+{$60})*+{$60}&z0^p{$60}ne?a/t%_87]*+be^^7\"&bh.+cxi?o&_.?\v{$60}a%_="9
  768. ::(3]1?w0dn;[t)sf_-"8:$d8t{$60}2i.-"&6&#\
  769. {$60}
  770. END
  771.  
  772. BEGIN 644 DINCSBC-DECCMP
  773. m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'b@{$60}(3[a/rb{$60}xh8:7>hl2n@
  774. m3y$kh%r1*xii>zbq*z!3d2n@8)$kbfe_j+$kh%61*z!bd2ox.+be^^;\q_s8
  775. l"&b%_3bxi?of_,?\"&a%_?{$60}!{$60}.;[t-_f_-#;ra"m8!@x&#cfyl;&q\?gyp#8
  776. {$60}
  777. END
  778.  
  779.  
  780.  
  781.                  6510 FEATURES
  782.  
  783.    O  php ALWAYS PUSHES THE bREAK (b) FLAG AS A {$60}1' TO THE STACK.
  784.       jUKKA tAPANIM{$e4}KI CLAIMED IN c=LEHTI ISSUE 3/89, ON PAGE 27 THAT THE
  785.       PROCESSOR MAKES A LOGICAL or BETWEEN THE STATUS REGISTER'S BIT 4 
  786.       AND THE BIT 8 OF THE STACK POINTER REGISTER (WHICH IS ALWAYS 1).
  787.       hE DID NOT GIVE ANY REASONS FOR THIS ARGUMENT, AND HAS REFUSED TO CLARIFY
  788.       IT AFTERWARDS. wELL, THIS WAS NOT THE ONLY ERROR IN HIS ARTICLE...
  789.  
  790.    O  iNDIRECT ADDRESSING MODES DO NOT HANDLE PAGE BOUNDARY CROSSING AT ALL.
  791.       wHEN THE PARAMETER'S LOW BYTE IS $ff, THE EFFECTIVE ADDRESS WRAPS
  792.       AROUND AND THE cpu FETCHES HIGH BYTE FROM $XX00 INSTEAD OF $XX00+$0100.
  793.       e.G. jmp ($01ff) FETCHES pcl FROM $01ff AND pch FROM $0100,
  794.       AND lda ($ff),y FETCHES THE BASE ADDRESS FROM $ff AND $00.
  795.  
  796.    O  iNDEXED ZERO PAGE ADDRESSING MODES NEVER FIX THE PAGE ADDRESS ON
  797.       CROSSING THE ZERO PAGE BOUNDARY.
  798.       e.G. ldx #$01 : lda ($ff,x) LOADS THE EFFECTIVE ADDRESS FROM $00 AND $01.
  799.  
  800.    O  tHE PROCESSOR ALWAYS FETCHES THE BYTE FOLLOWING A RELATIVE BRANCH
  801.       INSTRUCTION. iF THE BRANCH IS TAKEN, THE PROCESSOR READS THEN THE
  802.       OPCODE FROM THE DESTINATION ADDRESS. iF PAGE BOUNDARY IS CROSSED, IT
  803.       FIRST READS A BYTE FROM THE OLD PAGE FROM A LOCATION THAT IS BIGGER
  804.       OR SMALLER THAN THE CORRECT ADDRESS BY ONE PAGE.
  805.  
  806.    O  iF YOU CROSS A PAGE BOUNDARY IN ANY OTHER INDEXED MODE,
  807.       THE PROCESSOR READS AN INCORRECT LOCATION FIRST, A LOCATION THAT IS
  808.       SMALLER BY ONE PAGE.
  809.  
  810.    O  rEAD-mODIFY-wRITE INSTRUCTIONS WRITE UNMODIFIED DATA, THEN MODIFIED
  811.       (SO inc EFFECTIVELY DOES ldx LOC;stx LOC;inx;stx LOC)
  812.  
  813.    O  -rdy IS IGNORED DURING WRITES
  814.       (tHIS IS WHY YOU MUST WAIT 3 CYCLES BEFORE DOING ANY dma --
  815.       THE MAXIMUM NUMBER OF CONSECUTIVE WRITES IS 3, WHICH OCCURS
  816.       DURING INTERRUPTS EXCEPT -reset.)
  817.  
  818.    O  sOME UNDEFINED OPCODES MAY GIVE REALLY UNPREDICTABLE RESULTS.
  819.  
  820.    O  aLL REGISTERS EXCEPT THE pROGRAM cOUNTER REMAIN UNMODIFIED AFTER -reset.
  821.       (tHIS IS WHY YOU MUST PRESET d AND i FLAGS IN THE reset HANDLER.)
  822.  
  823.  
  824.                 dIFFERENT cpu TYPES
  825.  
  826. tHE rOCKWELL DATA BOOKLET 29651n52 (TECHNICAL INFORMATION ABOUT r65c00 
  827. MICROPROCESSORS, DATED oCTOBER 1984), LISTS THE FOLLOWING DIFFERENCES BETWEEN
  828. nmos r6502 MICROPROCESSOR AND cmos r65c00 FAMILY:
  829.  
  830.  1. iNDEXED ADDRESSING ACROSS PAGE BOUNDARY.
  831.         nmos: eXTRA READ OF INVALID ADDRESS.
  832.         cmos: eXTRA READ OF LAST INSTRUCTION BYTE.
  833.  
  834.  2. eXECUTION OF INVALID OP CODES.
  835.         nmos: sOME TERMINATE ONLY BY RESET. rESULTS ARE UNDEFINED.
  836.         cmos: aLL ARE nopS (RESERVED FOR FUTURE USE).
  837.  
  838.  3. jUMP INDIRECT, OPERAND = xxff.
  839.         nmos: pAGE ADDRESS DOES NOT INCREMENT.
  840.         cmos: pAGE ADDRESS INCREMENTS AND ADDS ONE ADDITIONAL CYCLE.
  841.  
  842.  4. rEAD/MODIFY/WRITE INSTRUCTIONS AT EFFECTIVE ADDRESS.
  843.         nmos: oNE READ AND TWO WRITE CYCLES.
  844.         cmos: tWO READ AND ONE WRITE CYCLE.
  845.  
  846.  5. dECIMAL FLAG.
  847.         nmos: iNDETERMINATE AFTER RESET.
  848.         cmos: iNITIALIZED TO BINARY MODE (d=0) AFTER RESET AND INTERRUPTS.
  849.  
  850.  6. fLAGS AFTER DECIMAL OPERATION.
  851.         nmos: iNVALID n, v AND z FLAGS.
  852.         cmos: vALID FLAG ADDS ONE ADDITIONAL CYCLE.
  853.  
  854.  7. iNTERRUPT AFTER FETCH OF brk INSTRUCTION.
  855.         nmos: iNTERRUPT VECTOR IS LOADED, brk VECTOR IS IGNORED.
  856.         cmos: brk IS EXECUTED, THEN INTERRUPT IS EXECUTED.
  857.  
  858.  
  859.  
  860.                 6510 iNSTRUCTION tIMING
  861.  
  862.   tHE nmos 6500 SERIES PROCESSORS ALWAYS PERFORM AT LEAST TWO READS
  863. FOR EACH INSTRUCTION. iN ADDITION TO THE OPERATION CODE (OPCODE), THEY
  864. FETCH THE NEXT BYTE. tHIS IS QUITE EFFICIENT, AS MOST INSTRUCTIONS ARE
  865. TWO OR THREE BYTES LONG.
  866.  
  867.   tHE PROCESSORS ALSO USE A SORT OF PIPELINING. iF AN INSTRUCTION DOES
  868. NOT STORE DATA IN MEMORY ON ITS LAST CYCLE, THE PROCESSOR CAN FETCH
  869. THE OPCODE OF THE NEXT INSTRUCTION WHILE EXECUTING THE LAST CYCLE. fOR
  870. INSTANCE, THE INSTRUCTION eor #$ff TRULY TAKES THREE CYCLES. oN THE
  871. FIRST CYCLE, THE OPCODE $49 WILL BE FETCHED. dURING THE SECOND CYCLE
  872. THE PROCESSOR DECODES THE OPCODE AND FETCHES THE PARAMETER #$ff. oN
  873. THE THIRD CYCLE, THE PROCESSOR WILL PERFORM THE OPERATION AND STORE
  874. THE RESULT TO ACCUMULATOR, BUT SIMULTANEOUSLY IT FETCHES THE OPCODE
  875. FOR THE NEXT INSTRUCTION. tHIS IS WHY THE INSTRUCTION EFFECTIVELY
  876. TAKES ONLY TWO CYCLES.
  877.  
  878.   tHE FOLLOWING TABLES SHOW WHAT HAPPENS ON THE BUS WHILE EXECUTING
  879. DIFFERENT KINDS OF INSTRUCTIONS.
  880.  
  881.   iNTERRUPTS
  882.  
  883.      nmi AND irq BOTH TAKE 7 CYCLES. tHEIR TIMING DIAGRAM IS MUCH LIKE
  884.      brk'S (SEE BELOW). irq WILL BE EXECUTED ONLY WHEN THE i FLAG IS
  885.      CLEAR. irq AND brk BOTH SET THE i FLAG, WHEREAS THE nmi DOES NOT
  886.      AFFECT ITS STATE.
  887.  
  888.      tHE PROCESSOR WILL USUALLY WAIT FOR THE CURRENT INSTRUCTION TO
  889.      COMPLETE BEFORE EXECUTING THE INTERRUPT SEQUENCE. tO PROCESS THE
  890.      INTERRUPT BEFORE THE NEXT INSTRUCTION, THE INTERRUPT MUST OCCUR
  891.      BEFORE THE LAST CYCLE OF THE CURRENT INSTRUCTION.
  892.  
  893.      tHERE IS ONE EXCEPTION TO THIS RULE: THE brk INSTRUCTION. iF A
  894.      HARDWARE INTERRUPT (nmi OR irq) OCCURS BEFORE THE FOURTH (FLAGS
  895.      SAVING) CYCLE OF brk, THE brk INSTRUCTION WILL BE SKIPPED, AND
  896.      THE PROCESSOR WILL JUMP TO THE HARDWARE INTERRUPT VECTOR. tHIS
  897.      SEQUENCE WILL ALWAYS TAKE 7 CYCLES.
  898.  
  899.      yOU DO NOT COMPLETELY LOSE THE brk INTERRUPT, THE b FLAG WILL BE
  900.      SET IN THE PUSHED STATUS REGISTER IF A brk INSTRUCTION GETS
  901.      INTERRUPTED. wHEN brk AND irq OCCUR AT THE SAME TIME, THIS DOES
  902.      NOT CAUSE ANY PROBLEMS, AS YOUR PROGRAM WILL CONSIDER IT AS A
  903.      brk, AND THE irq WOULD OCCUR AGAIN AFTER THE PROCESSOR RETURNED
  904.      FROM YOUR brk ROUTINE, UNLESS YOU CLEARED THE INTERRUPT SOURCE IN
  905.      YOUR brk HANDLER. bUT THE SIMULTANEOUS OCCURRENCE OF nmi AND brk
  906.      IS FAR MORE FATAL. iF YOU DO NOT CHECK THE b FLAG IN THE nmi
  907.      ROUTINE AND SUBTRACT TWO FROM THE RETURN ADDRESS WHEN NEEDED, THE
  908.      brk INSTRUCTION WILL BE SKIPPED.
  909.  
  910.      iF THE nmi AND irq INTERRUPTS OVERLAP EACH OTHER (ONE INTERRUPT
  911.      OCCURS BEFORE FETCHING THE INTERRUPT VECTOR FOR THE OTHER
  912.      INTERRUPT), THE PROCESSOR WILL MOST PROBABLY JUMP TO THE nmi
  913.      VECTOR IN EVERY CASE, AND THEN JUMP TO THE irq VECTOR AFTER
  914.      PROCESSING THE FIRST INSTRUCTION OF THE nmi HANDLER. tHIS HAS NOT
  915.      BEEN MEASURED YET, BUT THE irq IS VERY SIMILAR TO brk, AND MANY
  916.      SOURCES STATE THAT THE nmi HAS HIGHER PRIORITY THAN irq. hOWEVER,
  917.      IT MIGHT BE THAT THE PROCESSOR TAKES THE INTERRUPT THAT COMES
  918.      LATER, I.E. YOU COULD LOSE AN nmi INTERRUPT IF AN irq OCCURRED IN
  919.      FOUR CYCLES AFTER IT.
  920.  
  921.      aFTER FINISHING THE INTERRUPT SEQUENCE, THE PROCESSOR WILL START
  922.      TO EXECUTE THE FIRST INSTRUCTION OF THE INTERRUPT ROUTINE. tHIS
  923.      PROVES THAT THE PROCESSOR USES A SORT OF PIPELINING: IT FINISHES
  924.      THE CURRENT INSTRUCTION (OR INTERRUPT SEQUENCE) WHILE READING THE
  925.      OPCODE OF THE NEXT INSTRUCTION.
  926.  
  927.      reset DOES NOT PUSH PROGRAM COUNTER ON STACK, AND IT LASTS
  928.      PROBABLY 6 CYCLES AFTER DEACTIVATING THE SIGNAL. lIKE nmi, reset
  929.      PRESERVES ALL REGISTERS EXCEPT pc.
  930.  
  931.  
  932.   iNSTRUCTIONS ACCESSING THE STACK
  933.  
  934.      brk
  935.  
  936.         #  ADDRESS r/w DESCRIPTION
  937.        --- ------- --- -----------------------------------------------
  938.         1    pc     r  FETCH OPCODE, INCREMENT pc
  939.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY),
  940.                        INCREMENT pc
  941.         3  $0100,s  w  PUSH pch ON STACK, DECREMENT s
  942.         4  $0100,s  w  PUSH pcl ON STACK, DECREMENT s
  943.         5  $0100,s  w  PUSH p ON STACK (WITH b FLAG SET), DECREMENT s
  944.         6   $fffe   r  FETCH pcl
  945.         7   $ffff   r  FETCH pch
  946.  
  947.  
  948.      rti
  949.  
  950.         #  ADDRESS r/w DESCRIPTION
  951.        --- ------- --- -----------------------------------------------
  952.         1    pc     r  FETCH OPCODE, INCREMENT pc
  953.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
  954.         3  $0100,s  r  INCREMENT s
  955.         4  $0100,s  r  PULL p FROM STACK, INCREMENT s
  956.         5  $0100,s  r  PULL pcl FROM STACK, INCREMENT s
  957.         6  $0100,s  r  PULL pch FROM STACK
  958.  
  959.  
  960.      rts
  961.  
  962.         #  ADDRESS r/w DESCRIPTION
  963.        --- ------- --- -----------------------------------------------
  964.         1    pc     r  FETCH OPCODE, INCREMENT pc
  965.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
  966.         3  $0100,s  r  INCREMENT s
  967.         4  $0100,s  r  PULL pcl FROM STACK, INCREMENT s
  968.         5  $0100,s  r  PULL pch FROM STACK
  969.         6    pc     r  INCREMENT pc
  970.  
  971.  
  972.      pha, php
  973.  
  974.         #  ADDRESS r/w DESCRIPTION
  975.        --- ------- --- -----------------------------------------------
  976.         1    pc     r  FETCH OPCODE, INCREMENT pc
  977.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
  978.         3  $0100,s  w  PUSH REGISTER ON STACK, DECREMENT s
  979.  
  980.  
  981.      pla, plp
  982.  
  983.         #  ADDRESS r/w DESCRIPTION
  984.        --- ------- --- -----------------------------------------------
  985.         1    pc     r  FETCH OPCODE, INCREMENT pc
  986.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
  987.         3  $0100,s  r  INCREMENT s
  988.         4  $0100,s  r  PULL REGISTER FROM STACK
  989.  
  990.  
  991.      jsr
  992.  
  993.         #  ADDRESS r/w DESCRIPTION
  994.        --- ------- --- -------------------------------------------------
  995.         1    pc     r  FETCH OPCODE, INCREMENT pc
  996.         2    pc     r  FETCH LOW ADDRESS BYTE, INCREMENT pc
  997.         3  $0100,s  r  INTERNAL OPERATION (PREDECREMENT s?)
  998.         4  $0100,s  w  PUSH pch ON STACK, DECREMENT s
  999.         5  $0100,s  w  PUSH pcl ON STACK, DECREMENT s
  1000.         6    pc     r  COPY LOW ADDRESS BYTE TO pcl, FETCH HIGH ADDRESS
  1001.                        BYTE TO pch
  1002.  
  1003.  
  1004.  
  1005.   aCCUMULATOR OR IMPLIED ADDRESSING
  1006.  
  1007.         #  ADDRESS r/w DESCRIPTION
  1008.        --- ------- --- -----------------------------------------------
  1009.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1010.         2    pc     r  READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
  1011.  
  1012.  
  1013.   iMMEDIATE ADDRESSING
  1014.  
  1015.         #  ADDRESS r/w DESCRIPTION
  1016.        --- ------- --- ------------------------------------------
  1017.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1018.         2    pc     r  FETCH VALUE, INCREMENT pc
  1019.  
  1020.  
  1021.   aBSOLUTE ADDRESSING
  1022.  
  1023.      jmp
  1024.  
  1025.         #  ADDRESS r/w DESCRIPTION
  1026.        --- ------- --- -------------------------------------------------
  1027.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1028.         2    pc     r  FETCH LOW ADDRESS BYTE, INCREMENT pc
  1029.         3    pc     r  COPY LOW ADDRESS BYTE TO pcl, FETCH HIGH ADDRESS
  1030.                        BYTE TO pch
  1031.  
  1032.  
  1033.      rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
  1034.                         lax, nop)
  1035.  
  1036.         #  ADDRESS r/w DESCRIPTION
  1037.        --- ------- --- ------------------------------------------
  1038.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1039.         2    pc     r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1040.         3    pc     r  FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
  1041.         4  ADDRESS  r  READ FROM EFFECTIVE ADDRESS
  1042.  
  1043.  
  1044.      rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
  1045.                                      slo, sre, rla, rra, isb, dcp)
  1046.  
  1047.         #  ADDRESS r/w DESCRIPTION
  1048.        --- ------- --- ------------------------------------------
  1049.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1050.         2    pc     r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1051.         3    pc     r  FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
  1052.         4  ADDRESS  r  READ FROM EFFECTIVE ADDRESS
  1053.         5  ADDRESS  w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1054.                        AND DO THE OPERATION ON IT
  1055.         6  ADDRESS  w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1056.  
  1057.  
  1058.      wRITE INSTRUCTIONS (sta, stx, sty, sax)
  1059.     
  1060.         #  ADDRESS r/w DESCRIPTION
  1061.        --- ------- --- ------------------------------------------
  1062.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1063.         2    pc     r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1064.         3    pc     r  FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
  1065.         4  ADDRESS  w  WRITE REGISTER TO EFFECTIVE ADDRESS
  1066.  
  1067.  
  1068.   zERO PAGE ADDRESSING
  1069.  
  1070.      rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
  1071.                         lax, nop)
  1072.  
  1073.         #  ADDRESS r/w DESCRIPTION
  1074.        --- ------- --- ------------------------------------------
  1075.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1076.         2    pc     r  FETCH ADDRESS, INCREMENT pc
  1077.         3  ADDRESS  r  READ FROM EFFECTIVE ADDRESS
  1078.  
  1079.  
  1080.      rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
  1081.                                      slo, sre, rla, rra, isb, dcp)
  1082.  
  1083.         #  ADDRESS r/w DESCRIPTION
  1084.        --- ------- --- ------------------------------------------
  1085.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1086.         2    pc     r  FETCH ADDRESS, INCREMENT pc
  1087.         3  ADDRESS  r  READ FROM EFFECTIVE ADDRESS
  1088.         4  ADDRESS  w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1089.                        AND DO THE OPERATION ON IT
  1090.         5  ADDRESS  w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1091.  
  1092.  
  1093.      wRITE INSTRUCTIONS (sta, stx, sty, sax)
  1094.     
  1095.         #  ADDRESS r/w DESCRIPTION
  1096.        --- ------- --- ------------------------------------------
  1097.         1    pc     r  FETCH OPCODE, INCREMENT pc
  1098.         2    pc     r  FETCH ADDRESS, INCREMENT pc
  1099.         3  ADDRESS  w  WRITE REGISTER TO EFFECTIVE ADDRESS
  1100.  
  1101.   zERO PAGE INDEXED ADDRESSING
  1102.  
  1103.      rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
  1104.                         lax, nop)
  1105.  
  1106.         #   ADDRESS  r/w DESCRIPTION
  1107.        --- --------- --- ------------------------------------------
  1108.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1109.         2     pc      r  FETCH ADDRESS, INCREMENT pc
  1110.         3   ADDRESS   r  READ FROM ADDRESS, ADD INDEX REGISTER TO IT
  1111.         4  ADDRESS+i* r  READ FROM EFFECTIVE ADDRESS
  1112.  
  1113.        nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
  1114.  
  1115.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
  1116.                 I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
  1117.  
  1118.  
  1119.      rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
  1120.                                      slo, sre, rla, rra, isb, dcp)
  1121.  
  1122.         #   ADDRESS  r/w DESCRIPTION
  1123.        --- --------- --- ---------------------------------------------
  1124.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1125.         2     pc      r  FETCH ADDRESS, INCREMENT pc
  1126.         3   ADDRESS   r  READ FROM ADDRESS, ADD INDEX REGISTER x TO IT
  1127.         4  ADDRESS+x* r  READ FROM EFFECTIVE ADDRESS
  1128.         5  ADDRESS+x* w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1129.                          AND DO THE OPERATION ON IT
  1130.         6  ADDRESS+x* w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1131.  
  1132.        nOTE: * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
  1133.                I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
  1134.  
  1135.  
  1136.      wRITE INSTRUCTIONS (sta, stx, sty, sax)
  1137.  
  1138.         #   ADDRESS  r/w DESCRIPTION
  1139.        --- --------- --- -------------------------------------------
  1140.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1141.         2     pc      r  FETCH ADDRESS, INCREMENT pc
  1142.         3   ADDRESS   r  READ FROM ADDRESS, ADD INDEX REGISTER TO IT
  1143.         4  ADDRESS+i* w  WRITE TO EFFECTIVE ADDRESS
  1144.  
  1145.        nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
  1146.  
  1147.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
  1148.                 I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
  1149.  
  1150.  
  1151.   aBSOLUTE INDEXED ADDRESSING
  1152.  
  1153.      rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
  1154.                         lax, lae, shs, nop)
  1155.  
  1156.         #   ADDRESS  r/w DESCRIPTION
  1157.        --- --------- --- ------------------------------------------
  1158.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1159.         2     pc      r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1160.         3     pc      r  FETCH HIGH BYTE OF ADDRESS,
  1161.                          ADD INDEX REGISTER TO LOW ADDRESS BYTE,
  1162.                          INCREMENT pc
  1163.         4  ADDRESS+i* r  READ FROM EFFECTIVE ADDRESS,
  1164.                          FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
  1165.         5+ ADDRESS+i  r  RE-READ FROM EFFECTIVE ADDRESS
  1166.  
  1167.        nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
  1168.  
  1169.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1170.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
  1171.  
  1172.               + tHIS CYCLE WILL BE EXECUTED ONLY IF THE EFFECTIVE ADDRESS
  1173.                 WAS INVALID DURING CYCLE #4, I.E. PAGE BOUNDARY WAS CROSSED.
  1174.  
  1175.  
  1176.      rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
  1177.                                      slo, sre, rla, rra, isb, dcp)
  1178.  
  1179.         #   ADDRESS  r/w DESCRIPTION
  1180.        --- --------- --- ------------------------------------------
  1181.         1    pc       r  FETCH OPCODE, INCREMENT pc
  1182.         2    pc       r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1183.         3    pc       r  FETCH HIGH BYTE OF ADDRESS,
  1184.                          ADD INDEX REGISTER x TO LOW ADDRESS BYTE,
  1185.                          INCREMENT pc
  1186.         4  ADDRESS+x* r  READ FROM EFFECTIVE ADDRESS,
  1187.                          FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
  1188.         5  ADDRESS+x  r  RE-READ FROM EFFECTIVE ADDRESS
  1189.         6  ADDRESS+x  w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1190.                          AND DO THE OPERATION ON IT
  1191.         7  ADDRESS+x  w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1192.  
  1193.        nOTES: * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1194.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
  1195.  
  1196.  
  1197.      wRITE INSTRUCTIONS (sta, stx, sty, sha, shx, shy)
  1198.  
  1199.         #   ADDRESS  r/w DESCRIPTION
  1200.        --- --------- --- ------------------------------------------
  1201.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1202.         2     pc      r  FETCH LOW BYTE OF ADDRESS, INCREMENT pc
  1203.         3     pc      r  FETCH HIGH BYTE OF ADDRESS,
  1204.                          ADD INDEX REGISTER TO LOW ADDRESS BYTE,
  1205.                          INCREMENT pc
  1206.         4  ADDRESS+i* r  READ FROM EFFECTIVE ADDRESS,
  1207.                          FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
  1208.         5  ADDRESS+i  w  WRITE TO EFFECTIVE ADDRESS
  1209.  
  1210.        nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
  1211.  
  1212.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1213.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100. bECAUSE
  1214.                 THE PROCESSOR CANNOT UNDO A WRITE TO AN INVALID
  1215.                 ADDRESS, IT ALWAYS READS FROM THE ADDRESS FIRST.
  1216.  
  1217.  
  1218.   rELATIVE ADDRESSING (bcc, bcs, bne, beq, bpl, bmi, bvc, bvs)
  1219.  
  1220.         #   ADDRESS  r/w DESCRIPTION
  1221.        --- --------- --- ---------------------------------------------
  1222.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1223.         2     pc      r  FETCH OPERAND, INCREMENT pc
  1224.         3     pc      r  fETCH OPCODE OF NEXT INSTRUCTION,
  1225.                          iF BRANCH IS TAKEN, ADD OPERAND TO pcl.
  1226.                          oTHERWISE INCREMENT pc.
  1227.         4+    pc*     r  fETCH OPCODE OF NEXT INSTRUCTION.
  1228.                          fIX pch. iF IT DID NOT CHANGE, INCREMENT pc.
  1229.         5!    pc      r  fETCH OPCODE OF NEXT INSTRUCTION,
  1230.                          INCREMENT pc.
  1231.  
  1232.        nOTES: tHE OPCODE FETCH OF THE NEXT INSTRUCTION IS INCLUDED TO
  1233.               THIS DIAGRAM FOR ILLUSTRATION PURPOSES. wHEN DETERMINING
  1234.               REAL EXECUTION TIMES, REMEMBER TO SUBTRACT THE LAST
  1235.               CYCLE.
  1236.  
  1237.               * tHE HIGH BYTE OF pROGRAM cOUNTER (pch) MAY BE INVALID
  1238.                 AT THIS TIME, I.E. IT MAY BE SMALLER OR BIGGER BY $100.
  1239.  
  1240.               + iF BRANCH IS TAKEN, THIS CYCLE WILL BE EXECUTED.
  1241.  
  1242.               ! iF BRANCH OCCURS TO DIFFERENT PAGE, THIS CYCLE WILL BE
  1243.                 EXECUTED.
  1244.  
  1245.  
  1246.   iNDEXED INDIRECT ADDRESSING
  1247.  
  1248.      rEAD INSTRUCTIONS (lda, ora, eor, and, adc, cmp, sbc, lax)
  1249.  
  1250.         #    ADDRESS   r/w DESCRIPTION
  1251.        --- ----------- --- ------------------------------------------
  1252.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1253.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1254.         3    POINTER    r  READ FROM THE ADDRESS, ADD x TO IT
  1255.         4   POINTER+x   r  FETCH EFFECTIVE ADDRESS LOW
  1256.         5  POINTER+x+1  r  FETCH EFFECTIVE ADDRESS HIGH
  1257.         6    ADDRESS    r  READ FROM EFFECTIVE ADDRESS
  1258.  
  1259.        nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1260.              I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1261.  
  1262.      rEAD-mODIFY-wRITE INSTRUCTIONS (slo, sre, rla, rra, isb, dcp)
  1263.  
  1264.         #    ADDRESS   r/w DESCRIPTION
  1265.        --- ----------- --- ------------------------------------------
  1266.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1267.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1268.         3    POINTER    r  READ FROM THE ADDRESS, ADD x TO IT
  1269.         4   POINTER+x   r  FETCH EFFECTIVE ADDRESS LOW
  1270.         5  POINTER+x+1  r  FETCH EFFECTIVE ADDRESS HIGH
  1271.         6    ADDRESS    r  READ FROM EFFECTIVE ADDRESS
  1272.         7    ADDRESS    w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1273.                            AND DO THE OPERATION ON IT
  1274.         8    ADDRESS    w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1275.  
  1276.        nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1277.              I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1278.  
  1279.      wRITE INSTRUCTIONS (sta, sax)
  1280.  
  1281.         #    ADDRESS   r/w DESCRIPTION
  1282.        --- ----------- --- ------------------------------------------
  1283.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1284.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1285.         3    POINTER    r  READ FROM THE ADDRESS, ADD x TO IT
  1286.         4   POINTER+x   r  FETCH EFFECTIVE ADDRESS LOW
  1287.         5  POINTER+x+1  r  FETCH EFFECTIVE ADDRESS HIGH
  1288.         6    ADDRESS    w  WRITE TO EFFECTIVE ADDRESS
  1289.  
  1290.        nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1291.              I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1292.  
  1293.   iNDIRECT INDEXED ADDRESSING
  1294.  
  1295.      rEAD INSTRUCTIONS (lda, eor, and, ora, adc, sbc, cmp)
  1296.  
  1297.         #    ADDRESS   r/w DESCRIPTION
  1298.        --- ----------- --- ------------------------------------------
  1299.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1300.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1301.         3    POINTER    r  FETCH EFFECTIVE ADDRESS LOW
  1302.         4   POINTER+1   r  FETCH EFFECTIVE ADDRESS HIGH,
  1303.                            ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
  1304.         5   ADDRESS+y*  r  READ FROM EFFECTIVE ADDRESS,
  1305.                            FIX HIGH BYTE OF EFFECTIVE ADDRESS
  1306.         6+  ADDRESS+y   r  READ FROM EFFECTIVE ADDRESS
  1307.  
  1308.        nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1309.               I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1310.  
  1311.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1312.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
  1313.  
  1314.               + tHIS CYCLE WILL BE EXECUTED ONLY IF THE EFFECTIVE ADDRESS
  1315.                 WAS INVALID DURING CYCLE #5, I.E. PAGE BOUNDARY WAS CROSSED.
  1316.  
  1317.  
  1318.      rEAD-mODIFY-wRITE INSTRUCTIONS (slo, sre, rla, rra, isb, dcp)
  1319.  
  1320.         #    ADDRESS   r/w DESCRIPTION
  1321.        --- ----------- --- ------------------------------------------
  1322.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1323.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1324.         3    POINTER    r  FETCH EFFECTIVE ADDRESS LOW
  1325.         4   POINTER+1   r  FETCH EFFECTIVE ADDRESS HIGH,
  1326.                            ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
  1327.         5   ADDRESS+y*  r  READ FROM EFFECTIVE ADDRESS,
  1328.                            FIX HIGH BYTE OF EFFECTIVE ADDRESS
  1329.         6   ADDRESS+y   r  READ FROM EFFECTIVE ADDRESS
  1330.         7   ADDRESS+y   w  WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
  1331.                            AND DO THE OPERATION ON IT
  1332.         8   ADDRESS+y   w  WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
  1333.  
  1334.        nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1335.               I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1336.  
  1337.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1338.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
  1339.  
  1340.  
  1341.      wRITE INSTRUCTIONS (sta, sha)
  1342.  
  1343.         #    ADDRESS   r/w DESCRIPTION
  1344.        --- ----------- --- ------------------------------------------
  1345.         1      pc       r  FETCH OPCODE, INCREMENT pc
  1346.         2      pc       r  FETCH POINTER ADDRESS, INCREMENT pc
  1347.         3    POINTER    r  FETCH EFFECTIVE ADDRESS LOW
  1348.         4   POINTER+1   r  FETCH EFFECTIVE ADDRESS HIGH,
  1349.                            ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
  1350.         5   ADDRESS+y*  r  READ FROM EFFECTIVE ADDRESS,
  1351.                            FIX HIGH BYTE OF EFFECTIVE ADDRESS
  1352.         6   ADDRESS+y   w  WRITE TO EFFECTIVE ADDRESS
  1353.  
  1354.        nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
  1355.               I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1356.  
  1357.               * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
  1358.                 AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
  1359.  
  1360.  
  1361.   aBSOLUTE INDIRECT ADDRESSING (jmp)
  1362.  
  1363.         #   ADDRESS  r/w DESCRIPTION
  1364.        --- --------- --- ------------------------------------------
  1365.         1     pc      r  FETCH OPCODE, INCREMENT pc
  1366.         2     pc      r  FETCH POINTER ADDRESS LOW, INCREMENT pc
  1367.         3     pc      r  FETCH POINTER ADDRESS HIGH, INCREMENT pc
  1368.         4   POINTER   r  FETCH LOW ADDRESS TO LATCH
  1369.         5  POINTER+1* r  FETCH pch, COPY LATCH TO pcl
  1370.  
  1371.        nOTE: * tHE pch WILL ALWAYS BE FETCHED FROM THE SAME PAGE
  1372.                THAN pcl, I.E. PAGE BOUNDARY CROSSING IS NOT HANDLED.
  1373.  
  1374.  
  1375.  
  1376.                 hOW rEAL pROGRAMMERS aCKNOWLEDGE iNTERRUPTS
  1377.  
  1378.   wITH rmw INSTRUCTIONS:
  1379.  
  1380.         ; BEGINNING OF COMBINED RASTER/TIMER INTERRUPT ROUTINE
  1381.         lsr $d019       ; CLEAR vic INTERRUPTS, READ RASTER INTERRUPT FLAG TO c
  1382.         bcs RASTER      ; JUMP IF vic CAUSED AN INTERRUPT
  1383.         ...             ; TIMER INTERRUPT ROUTINE
  1384.  
  1385.         oPERATIONAL DIAGRAM OF lsr $d019:
  1386.  
  1387.           #  DATA  ADDRESS  r/w  
  1388.          --- ----  -------  ---  ---------------------------------
  1389.           1   4e     pc      r   FETCH OPCODE
  1390.           2   19    pc+1     r   FETCH ADDRESS LOW
  1391.           3   d0    pc+2     r   FETCH ADDRESS HIGH
  1392.           4   XX    $d019    r   READ MEMORY
  1393.           5   XX    $d019    w   WRITE THE VALUE BACK, ROTATE RIGHT
  1394.           6  XX/2   $d019    w   WRITE THE NEW VALUE BACK
  1395.  
  1396.         tHE 5TH CYCLE ACKNOWLEDGES THE INTERRUPT BY WRITING THE SAME
  1397.         VALUE BACK. iF ONLY RASTER INTERRUPTS ARE USED, THE 6TH CYCLE
  1398.         HAS NO EFFECT ON THE vic. (iT MIGHT ACKNOWLEDGE ALSO SOME
  1399.         OTHER INTERRUPTS.)
  1400.  
  1401.  
  1402.  
  1403.   wITH INDEXED ADDRESSING:
  1404.  
  1405.         ; ACKNOWLEDGE INTERRUPTS TO BOTH ciaS
  1406.         ldx #$10
  1407.         lda $dcfd,x
  1408.  
  1409.         oPERATIONAL DIAGRAM OF lda $dcfd,x:
  1410.  
  1411.           #  DATA  ADDRESS  r/w  DESCRIPTION
  1412.          --- ----  -------  ---  ---------------------------------
  1413.           1   bd     pc      r   FETCH OPCODE
  1414.           2   fd    pc+1     r   FETCH ADDRESS LOW
  1415.           3   dc    pc+2     r   FETCH ADDRESS HIGH, ADD x TO ADDRESS LOW
  1416.           4   XX    $dc0d    r   READ FROM ADDRESS, FIX HIGH BYTE OF ADDRESS
  1417.           5   YY    $dd0d    r   READ FROM RIGHT ADDRESS
  1418.  
  1419.  
  1420.         ; ACKNOWLEDGE INTERRUPTS TO cia 2
  1421.         ldx #$10
  1422.         sta $ddfd,x
  1423.  
  1424.         oPERATIONAL DIAGRAM OF sta $ddfd,x:
  1425.  
  1426.           #  DATA  ADDRESS  r/w  DESCRIPTION
  1427.          --- ----  -------  ---  ---------------------------------
  1428.           1   9d     pc      r   FETCH OPCODE
  1429.           2   fd    pc+1     r   FETCH ADDRESS LOW
  1430.           3   dc    pc+2     r   FETCH ADDRESS HIGH, ADD x TO ADDRESS LOW
  1431.           4   XX    $dd0d    r   READ FROM ADDRESS, FIX HIGH BYTE OF ADDRESS
  1432.           5   AC    $de0d    w   WRITE TO RIGHT ADDRESS
  1433.  
  1434.  
  1435.   wITH BRANCH INSTRUCTIONS:
  1436.  
  1437.         ; ACKNOWLEDGE INTERRUPTS TO cia 2
  1438.                 lda #$00  ; CLEAR n FLAG
  1439.                 jmp $dd0a
  1440.         dd0a    bpl $dc9d ; BRANCH
  1441.         dc9d    brk       ; RETURN
  1442.  
  1443.         yOU NEED THE FOLLOWING PREPARATIONS TO INITIALIZE THE cia REGISTERS:
  1444.  
  1445.                 lda #$91  ; ARGUMENT OF bpl
  1446.                 sta $dd0b
  1447.                 lda #$10  ; bpl
  1448.                 sta $dd0a
  1449.                 sta $dd08 ; LOAD THE tOd VALUES FROM THE LATCHES
  1450.                 lda $dd0b ; FREEZE THE tOd DISPLAY
  1451.                 lda #$7f
  1452.                 sta $dc0d ; ASSURE THAT $dc0d IS $00
  1453.  
  1454.         oPERATIONAL DIAGRAM OF bpl $dc9d:
  1455.  
  1456.           #  DATA  ADDRESS  r/w  DESCRIPTION
  1457.          --- ----  -------  ---  ---------------------------------
  1458.           1   10    $dd0a    r   FETCH OPCODE
  1459.           2   91    $dd0b    r   FETCH ARGUMENT
  1460.           3   XX    $dd0c    r   FETCH OPCODE, ADD ARGUMENT TO pcl
  1461.           4   YY    $dd9d    r   FETCH OPCODE, FIX pch
  1462.         ( 5   00    $dc9d    r   FETCH OPCODE )
  1463.  
  1464.  
  1465.         ; ACKNOWLEDGE INTERRUPTS TO cia 1
  1466.                 lsr       ; CLEAR n FLAG
  1467.                 jmp $dcfa
  1468.         dcfa    bpl $dd0d
  1469.         dd0d    brk
  1470.  
  1471.         ; aGAIN YOU NEED TO SET THE tOd REGISTERS OF cia 1 AND THE
  1472.         ; iNTERRUPT cONTROL rEGISTER OF cia 2 FIRST.
  1473.  
  1474.         oPERATIONAL DIAGRAM OF bpl $dd0d:
  1475.  
  1476.           #  DATA  ADDRESS  r/w  DESCRIPTION
  1477.          --- ----  -------  ---  ---------------------------------
  1478.           1   10    $dcfa    r   FETCH OPCODE
  1479.           2   11    $dcfb    r   FETCH ARGUMENT
  1480.           3   XX    $dcfc    r   FETCH OPCODE, ADD ARGUMENT TO pcl
  1481.           4   YY    $dc0d    r   FETCH OPCODE, FIX pch
  1482.         ( 5   00    $dd0d    r   FETCH OPCODE )
  1483.  
  1484.  
  1485.         ; ACKNOWLEDGE INTERRUPTS TO cia 2 AUTOMAGICALLY
  1486.                 ; PREPARATIONS
  1487.                 lda #$7f
  1488.                 sta $dd0d       ; DISABLE ALL INTERRUPT SOURCES OF cia2
  1489.                 lda $dd0e
  1490.                 and #$be        ; ENSURE THAT $dd0c REMAINS CONSTANT
  1491.                 sta $dd0e       ; AND STOP THE TIMER
  1492.                 lda #$fd
  1493.                 sta $dd0c       ; PARAMETER OF bpl
  1494.                 lda #$10
  1495.                 sta $dd0b       ; bpl
  1496.                 lda #$40
  1497.                 sta $dd0a       ; rti/PARAMETER OF lsr
  1498.                 lda #$46
  1499.                 sta $dd09       ; lsr
  1500.                 sta $dd08       ; LOAD THE tOd VALUES FROM THE LATCHES
  1501.                 lda $dd0b       ; FREEZE THE tOd DISPLAY
  1502.                 lda #$09
  1503.                 sta $0318
  1504.                 lda #$dd
  1505.                 sta $0319       ; CHANGE nmi VECTOR TO $dd09
  1506.                 lda #$ff        ; tRY CHANGING THIS INSTRUCTION'S OPERAND
  1507.                 sta $dd05       ; (SEE COMMENT BELOW).
  1508.                 lda #$ff
  1509.                 sta $dd04       ; SET INTERRUPT FREQUENCY TO 1/65536 CYCLES
  1510.                 lda $dd0e
  1511.                 and #$80
  1512.                 ora #$11
  1513.                 ldx #$81
  1514.                 stx $dd0d       ; ENABLE TIMER INTERRUPT
  1515.                 sta $dd0e       ; START TIMER
  1516.  
  1517.                 lda #$00        ; tO SEE THAT THE INTERRUPTS REALLY OCCUR,
  1518.                 sta $d011       ; USE SOMETHING LIKE THIS AND SEE HOW
  1519.         loop    dec $d020       ; CHANGING THE BYTE LOADED TO $dd05 FROM
  1520.                 bne loop        ; #$ff TO #$0f CHANGES THE IMAGE.
  1521.  
  1522.         wHEN AN nmi OCCURS, THE PROCESSOR JUMPS TO kERNAL CODE, WHICH JUMPS TO
  1523.         ($0318), WHICH POINTS TO THE FOLLOWING ROUTINE:
  1524.  
  1525.         dd09    lsr $40         ; CLEAR n FLAG
  1526.                 bpl $dd0a       ; nOTE: $dd0a CONTAINS rti.
  1527.  
  1528.         oPERATIONAL DIAGRAM OF bpl $dd0a:
  1529.  
  1530.           #  DATA  ADDRESS  r/w  DESCRIPTION
  1531.          --- ----  -------  ---  ---------------------------------
  1532.           1   10    $dd0b    r   FETCH OPCODE
  1533.           2   11    $dd0c    r   FETCH ARGUMENT
  1534.           3   XX    $dd0d    r   FETCH OPCODE, ADD ARGUMENT TO pcl
  1535.           4   40    $dd0a    r   FETCH OPCODE, (FIX pch)
  1536.  
  1537.  
  1538.   wITH rti:
  1539.  
  1540.         ; THE FASTEST POSSIBLE INTERRUPT HANDLER IN THE 6500 FAMILY
  1541.                 ; PREPARATIONS
  1542.                 sei
  1543.                 lda $01         ; DISABLE rom AND ENABLE i/o
  1544.                 and #$fd
  1545.                 ora #$05
  1546.                 sta $01
  1547.                 lda #$7f
  1548.                 sta $dd0d       ; DISABLE cia 2'S ALL INTERRUPT SOURCES
  1549.                 lda $dd0e
  1550.                 and #$be        ; ENSURE THAT $dd0c REMAINS CONSTANT
  1551.                 sta $dd0e       ; AND STOP THE TIMER
  1552.                 lda #$40
  1553.                 sta $dd0c       ; STORE rti TO $dd0c
  1554.                 lda #$0c
  1555.                 sta $fffa
  1556.                 lda #$dd
  1557.                 sta $fffb       ; CHANGE nmi VECTOR TO $dd0c
  1558.                 lda #$ff        ; tRY CHANGING THIS INSTRUCTION'S OPERAND
  1559.                 sta $dd05       ; (SEE COMMENT BELOW).
  1560.                 lda #$ff
  1561.                 sta $dd04       ; SET INTERRUPT FREQUENCY TO 1/65536 CYCLES
  1562.                 lda $dd0e
  1563.                 and #$80
  1564.                 ora #$11
  1565.                 ldx #$81
  1566.                 stx $dd0d       ; ENABLE TIMER INTERRUPT
  1567.                 sta $dd0e       ; START TIMER
  1568.  
  1569.                 lda #$00        ; tO SEE THAT THE INTERRUPTS REALLY OCCUR,
  1570.                 sta $d011       ; USE SOMETHING LIKE THIS AND SEE HOW
  1571.         loop    dec $d020       ; CHANGING THE BYTE LOADED TO $dd05 FROM
  1572.                 bne loop        ; #$ff TO #$0f CHANGES THE IMAGE.
  1573.  
  1574.         wHEN AN nmi OCCURS, THE PROCESSOR JUMPS TO kERNAL CODE, WHICH
  1575.         JUMPS TO ($0318), WHICH POINTS TO THE FOLLOWING ROUTINE:
  1576.  
  1577.         dd0c    rti
  1578.  
  1579.         hOW ON EARTH CAN THIS CLEAR THE INTERRUPTS? rEMEMBER, THE
  1580.         PROCESSOR ALWAYS FETCHES TWO SUCCESSIVE BYTES FOR EACH
  1581.         INSTRUCTION.
  1582.  
  1583.         a LITTLE MORE PRACTICAL VERSION OF THIS IS REDIRECTING THE nmi
  1584.         (OR irq) TO YOUR OWN ROUTINE, WHOSE LAST INSTRUCTION IS jmp
  1585.         $dd0c OR jmp $dc0c.  iF YOU WANT TO CONFUSE MORE, CHANGE THE 0
  1586.         IN THE ADDRESS TO A HEXADECIMAL DIGIT DIFFERENT FROM THE ONE
  1587.         YOU USED WHEN WRITING THE rti.
  1588.  
  1589.         oR YOU CAN COMBINE THE LATTER TWO METHODS:
  1590.  
  1591.         dd09    lsr $XX  ; XX IS ANY APPROPRIATE bcd VALUE 00-59.
  1592.                 bpl $dcfc
  1593.         dcfc    rti
  1594.  
  1595.         tHIS EXAMPLE ACKNOWLEDGES INTERRUPTS TO BOTH ciaS.
  1596.  
  1597.  
  1598.   iF YOU WANT TO CONFUSE THE EXAMINERS OF YOUR CODE, YOU CAN USE ANY
  1599. OF THESE TECHNIQUES. aLTHOUGH THESE EXAMPLES USE NO UNDEFINED OPCODES,
  1600. THEY DO NOT NECESSARILY RUN CORRECTLY ON cmos PROCESSORS. hOWEVER, THE
  1601. rti EXAMPLE SHOULD RUN ON 65c02 AND 65c816, AND THE LATTER BRANCH
  1602. INSTRUCTION EXAMPLE MIGHT WORK AS WELL.
  1603.  
  1604.   tHE rmw INSTRUCTION METHOD HAS BEEN USED IN SOME DEMOS, OTHERS WERE
  1605. DEVELOPED BY mARKO m{$e4}KEL{$e4}. hIS FAVOURITE IS THE AUTOMAGICAL rti
  1606. METHOD, ALTHOUGH IT DOES NOT HAVE ANY PRACTICAL APPLICATIONS, EXCEPT
  1607. FOR SOME TIME DEPENDENT DATA DECRYPTION ROUTINES FOR VERY COMPLICATED
  1608. COPY PROTECTIONS.
  1609.  
  1610.  
  1611.  
  1612.                 mEMORY mANAGEMENT
  1613.  
  1614.  
  1615. tHE PROCESSOR'S POINT OF VIEW
  1616.  
  1617.   tHE cOMMODORE 64 HAS ACCESS TO MORE MEMORY THAN ITS PROCESSOR CAN
  1618. DIRECTLY HANDLE. tHIS IS POSSIBLE BY BANKING THE MEMORY. tHERE ARE
  1619. FIVE USER CONFIGURABLE INPUTS THAT AFFECT THE BANKING. tHREE OF THEM
  1620. CAN BE CONTROLLED BY PROGRAM, AND THE REST TWO SERVE AS CONTROL LINES
  1621. ON THE MEMORY EXPANSION PORT.
  1622.  
  1623.   tHE 6510 mpu HAS AN INTEGRATED i/o PORT WITH SIX i/o LINES. tHIS
  1624. PORT IS ACCESSED THROUGH THE MEMORY LOCATIONS 0 AND 1. tHE LOCATION 0
  1625. IS THE dATA dIRECTION rEGISTER FOR THE pERIPHERAL DATA rEGISTER, WHICH
  1626. IS MAPPED TO THE OTHER LOCATION. wHEN A BIT IN THE ddr IS SET, THE
  1627. CORRESPONDING pr BIT CONTROLS THE STATE OF A CORRESPONDING pERIPHERAL
  1628. LINE AS AN OUTPUT. wHEN IT IS CLEAR, THE STATE OF THE pERIPHERAL LINE
  1629. IS REFLECTED BY THE pERIPHERAL REGISTER. tHE pERIPHERAL LINES ARE
  1630. NUMBERED FROM 0 TO 5, AND THEY ARE MAPPED TO THE ddr AND pr BITS 0 - 5,
  1631. RESPECTIVELY. tHE 8502 PROCESSOR, WHICH IS USED IN THE cOMMODORE 128,
  1632. HAS SEVEN pERIPHERAL LINES IN ITS i/o PORT. tHE PIN p6 IS CONNECTED TO
  1633. THE asc/cc KEY (cAPS LOCK IN eNGLISH VERSIONS).
  1634.  
  1635.   tHE i/o LINES HAVE THE FOLLOWING FUNCTIONS:
  1636.  
  1637.      dIRECTION  lINE  fUNCTION
  1638.      ---------  ----  --------
  1639.         OUT      p5   cASSETTE MOTOR CONTROL. (0 = MOTOR SPINS)
  1640.         IN       p4   cASSETTE SENSE. (0 = play BUTTON DEPRESSED)
  1641.         OUT      p3   cASSETTE WRITE DATA.
  1642.         OUT      p2   charen
  1643.         OUT      p1   hiram
  1644.         OUT      p0   loram
  1645.  
  1646.   tHE DEFAULT VALUE OF THE ddr REGISTER IS $2f, SO ALL LINES EXCEPT
  1647. cASSETTE SENSE ARE OUTPUTS. tHE DEFAULT pr VALUE IS $37 (dATASSETTE
  1648. MOTOR STOPPED, AND ALL THREE MEMORY MANAGEMENT LINES HIGH).
  1649. iF YOU TURN ANY MEMORY MANAGEMENT LINE TO INPUT, THE EXTERNAL PULL-UP
  1650. RESISTORS MAKE IT TO LOOK LIKE IT IS OUTPUTTING LOGICAL "1". tHIS
  1651. IS ACTUALLY WHY THE COMPUTER ALWAYS SWITCHES THE romS IN UPON STARTUP:
  1652. pULLING THE -reset LINE LOW RESETS ALL pERIPHERAL LINES TO INPUTS,
  1653. THUS SETTING ALL THREE PROCESSOR-DRIVEN MEMORY MANAGEMENT LINES TO
  1654. LOGICAL "1" LEVEL.
  1655.  
  1656.   tHE TWO REMAINING MEMORY MANAGEMENT LINES ARE -exrom AND -game ON
  1657. THE CARTRIDGE PORT. eACH LINE HAS A PULL-UP RESISTOR, SO THE LINES
  1658. ARE "1" BY DEFAULT.
  1659.  
  1660.   eVEN THOUGH THE MEMORY BANKING HAS BEEN IMPLEMENTED WITH A 82s100
  1661. pROGRAMMABLE _lOGIC_ aRRAY, THERE IS ONLY ONE CONTROL LINE THAT SEEMS
  1662. TO BEHAVE LOGICALLY AT FIRST SIGHT, THE -charen LINE. iT IS MOSTLY
  1663. USED TO CHOOSE BETWEEN i/o ADDRESS SPACE AND THE CHARACTER GENERATOR
  1664. rom. tHE FOLLOWING MEMORY MAP INTRODUCES THE ODDITIES OF -charen AND
  1665. THE OTHER MEMORY MANAGEMENT LINES. iT IS BASED ON THE MEMORY MAPS IN
  1666. THE cOMMODORE 64 pROGRAMMER'S rEFERENCE gUIDE, PP. 263 - 267, AND SOME
  1667. ERRORS AND INACCURACIES HAVE BEEN CORRECTED.
  1668.  
  1669.   tHE LEFTMOST COLUMN OF THE TABLE CONTAINS ADDRESSES IN HEXADECIMAL
  1670. NOTATION. tHE COLUMNS ASIDE IT INTRODUCE ALL POSSIBLE MEMORY
  1671. CONFIGURATIONS. tHE DEFAULT MODE IS ON THE LEFT, AND THE ABSOLUTELY
  1672. MOST RARELY USED uLTIMAX GAME CONSOLE CONFIGURATION IS ON THE RIGHT.
  1673. (hAS ANYBODY EVER SEEN ANY uLTIMAX GAMES?) eACH MEMORY CONFIGURATION
  1674. COLUMN HAS ONE OR MORE FOUR-DIGIT BINARY NUMBERS AS A TITLE. tHE BITS,
  1675. FROM LEFT TO RIGHT, REPRESENT THE STATE OF THE -loram, -hiram, -game
  1676. AND -exrom LINES, RESPECTIVELY. tHE BITS WHOSE STATE DOES NOT MATTER
  1677. ARE MARKED WITH "X". fOR INSTANCE, WHEN THE uLTIMAX VIDEO GAME
  1678. CONFIGURATION IS ACTIVE (THE -game LINE IS SHORTED TO GROUND), THE
  1679. -loram AND -hiram LINES HAVE NO EFFECT.
  1680.  
  1681.  
  1682.       DEFAULT                      001X                       uLTIMAX
  1683.        1111   101X   1000   011X   00X0   1110   0100   1100   XX01
  1684. 10000
  1685. ----------------------------------------------------------------------
  1686.  f000
  1687.        kERNAL ram    ram    kERNAL ram    kERNAL kERNAL kERNAL romh(*
  1688.  e000
  1689. ----------------------------------------------------------------------
  1690.  d000  io/c   io/c   io/ram io/c   ram    io/c   io/c   io/c   i/o
  1691. ----------------------------------------------------------------------
  1692.  c000  ram    ram    ram    ram    ram    ram    ram    ram     -
  1693. ----------------------------------------------------------------------
  1694.  b000                         
  1695.        basic  ram    ram    ram    ram    basic  romh   romh    -
  1696.  a000                         
  1697. ----------------------------------------------------------------------
  1698.  9000                         
  1699.        ram    ram    ram    ram    ram    roml   ram    roml   roml(*
  1700.  8000                         
  1701. ----------------------------------------------------------------------
  1702.  7000                         
  1703.                          
  1704.  6000                         
  1705.        ram    ram    ram    ram    ram    ram    ram    ram     -
  1706.  5000                         
  1707.                          
  1708.  4000                         
  1709. ----------------------------------------------------------------------
  1710.  3000                            
  1711.                          
  1712.  2000  ram    ram    ram    ram    ram    ram    ram    ram     -
  1713.                          
  1714.  1000                         
  1715. ----------------------------------------------------------------------
  1716.  0000  ram    ram    ram    ram    ram    ram    ram    ram    ram
  1717. ----------------------------------------------------------------------
  1718.  
  1719.     *) iNTERNAL MEMORY DOES NOT RESPOND TO WRITE ACCESSES TO THESE
  1720.        AREAS.
  1721.  
  1722.  
  1723.     lEGEND: kERNAL      e000-ffff       kERNAL rom.
  1724.  
  1725.             io/c        d000-dfff       i/o ADDRESS SPACE OR cHARACTER
  1726.                                         GENERATOR rom, SELECTED BY
  1727.                                         -charen. iF THE charen BIT IS
  1728.                                         CLEAR, THE CHARACTER GENERATOR
  1729.                                         rom WILL BE SELECTED. iF IT IS
  1730.                                         SET, THE i/o CHIPS ARE
  1731.                                         ACCESSIBLE.
  1732.  
  1733.             io/ram      d000-dfff       i/o ADDRESS SPACE OR ram,
  1734.                                         SELECTED BY -charen. iF THE
  1735.                                         charen BIT IS CLEAR, THE
  1736.                                         CHARACTER GENERATOR rom WILL
  1737.                                         BE SELECTED. iF IT IS SET, THE
  1738.                                         INTERNAL ram IS ACCESSIBLE.
  1739.  
  1740.             i/o         d000-dfff       i/o ADDRESS SPACE.
  1741.                                         tHE -charen LINE HAS NO EFFECT.
  1742.  
  1743.             basic       a000-bfff       basic rom.
  1744.  
  1745.             romh        a000-bfff OR    eXTERNAL rom WITH THE -romh LINE
  1746.                         e000-ffff       CONNECTED TO ITS -cs LINE.
  1747.  
  1748.             roml        8000-9fff       eXTERNAL rom WITH THE -roml LINE
  1749.                                         CONNECTED TO ITS -cs LINE.
  1750.  
  1751.             ram         VARIOUS RANGES  cOMMODORE 64'S INTERNAL ram.
  1752.  
  1753.             -           1000-7fff AND   oPEN ADDRESS SPACE. 
  1754.                         a000-cfff       tHE cOMMODORE 64'S MEMORY CHIPS
  1755.                                         DO NOT DETECT ANY MEMORY ACCESSES
  1756.                                         TO THIS AREA EXCEPT THE vic-ii'S
  1757.                                         dma AND MEMORY REFRESHES.
  1758.  
  1759.     note:   wHENEVER THE PROCESSOR TRIES TO WRITE TO ANY rom AREA
  1760.             (kERNAL, basic, charom, roml, romh), THE DATA WILL GET
  1761.             "THROUGH THE rom" TO THE c64'S INTERNAL ram.
  1762.  
  1763.             fOR THIS REASON, YOU CAN EASILY COPY DATA FROM rom TO ram,
  1764.             WITHOUT ANY BANK SWITCHING. bUT IMPLEMENTING EXTERNAL
  1765.             MEMORY EXPANSIONS WITHOUT dma IS VERY HARD, AS YOU HAVE TO
  1766.             USE A 256 BYTE WINDOW ON THE i/o1 OR i/o2 AREA, LIKE
  1767.             georam, OR THE uLTIMAX MEMORY CONFIGURATION, IF YOU DO NOT
  1768.             WANT THE DATA TO BE WRITTEN BOTH TO INTERNAL AND EXTERNAL
  1769.             ram.
  1770.  
  1771.             hOWEVER, THIS IS NOT TRUE FOR THE uLTIMAX VIDEO GAME
  1772.             CONFIGURATION. iN THAT MODE, THE INTERNAL ram IGNORES ALL
  1773.             MEMORY ACCESSES OUTSIDE THE AREA $0000-$0fff, UNLESS THEY
  1774.             ARE PERFORMED BY THE vic, AND YOU CAN WRITE TO EXTERNAL
  1775.             MEMORY AT $1000-$cfff AND $e000-$ffff, IF ANY, WITHOUT
  1776.             CHANGING THE CONTENTS OF THE INTERNAL ram.
  1777.  
  1778.  
  1779. a NOTE CONCERNING THE i/o AREA
  1780.  
  1781.   tHE i/o AREA OF THE cOMMODORE 64 IS DIVIDED AS FOLLOWS:
  1782.  
  1783.      aDDRESS RANGE  oWNER
  1784.      -------------  -----
  1785.        d000-d3ff    mos 6567/6569 vic-ii vIDEO iNTERFACE cONTROLLER
  1786.        d400-d7ff    mos 6581 sid sOUND iNTERFACE dEVICE
  1787.        d800-dbff    cOLOR ram (ONLY LOWER NYBBLES ARE CONNECTED)
  1788.        dc00-dcff    mos 6526 cia cOMPLEX iNTERFACE aDAPTER #1
  1789.        dd00-ddff    mos 6526 cia cOMPLEX iNTERFACE aDAPTER #2
  1790.        de00-deff    uSER EXPANSION #1 (-i/o1 ON eXPANSION pORT)
  1791.        df00-dfff    uSER EXPANSION #2 (-i/o2 ON eXPANSION pORT)
  1792.  
  1793.   aS YOU CAN SEE, THE ADDRESS RANGES FOR THE CHIPS ARE MUCH LARGER
  1794. THAN REQUIRED. bECAUSE OF THIS, YOU CAN ACCESS THE CHIPS THROUGH
  1795. MULTIPLE MEMORY AREAS. tHE vic-ii APPEARS IN ITS WINDOW EVERY $40
  1796. ADDRESSES. fOR INSTANCE, THE ADDRESSES $d040 AND $d080 ARE BOTH MAPPED
  1797. TO THE sPRITE 0 x CO-ORDINATE REGISTER. tHE sid HAS ONE REGISTER
  1798. SELECTION LINE LESS, THUS IT APPEARS AT EVERY $20 BYTES. tHE cia CHIPS
  1799. HAVE ONLY 16 REGISTERS, SO THERE ARE 16 COPIES OF EACH IN THEIR MEMORY
  1800. AREA.
  1801.  
  1802.   hOWEVER, YOU SHOULD NOT USE OTHER ADDRESSES THAN THOSE SPECIFIED BY
  1803. cOMMODORE. fOR INSTANCE, THE cOMMODORE 128 MAPPED ITS ADDITIONAL i/o
  1804. CHIPS TO THIS SAME MEMORY AREA, AND THE sid RESPONDS ONLY TO THE
  1805. ADDRESSES d400-d4ff, ALSO WHEN IN c64 MODE. aND THE cOMMODORE 65, OR
  1806. THE c64dx, WHICH UNFORTUNATELY DID NOT MAKE ITS WAY TO THE MARKET,
  1807. COULD NARROW THE MEMORY WINDOW RESERVED FOR ITS csg 4567 vic-iii.
  1808.  
  1809.  
  1810. tHE VIDEO CHIP
  1811.  
  1812.   tHE mos 6567/6569 vic-ii vIDEO iNTERFACE cONTROLLER HAS ACCESS TO
  1813. ONLY 16 KILOBYTES AT A TIME. tO ENABLE THE vic-ii TO ACCESS THE WHOLE
  1814. 64 Kb MEMORY SPACE, THE MAIN MEMORY IS DIVIDED TO FOUR BANKS OF 16 Kb
  1815. EACH. tHE LINES pa0 AND pa1 OF THE SECOND cia ARE THE INVERSE OF THE
  1816. VIRTUAL vic-ii ADDRESS LINES va14 AND va15, RESPECTIVELY. tO SELECT A
  1817. vic-ii BANK OTHER THAN THE DEFAULT, YOU MUST PROGRAM THE cia LINES TO
  1818. OUTPUT THE DESIRED BIT PAIR. fOR INSTANCE, THE FOLLOWING CODE SELECTS
  1819. THE MEMORY AREA $4000-$7fff (BANK 1) FOR THE VIDEO CONTROLLER:
  1820.  
  1821.     lda $dd02 ; dATA dIRECTION rEGISTER a
  1822.     ora #$03  ; sET PINS pa0 AND pa1 TO OUTPUTS
  1823.     sta $dd02
  1824.     lda $dd00
  1825.     and #$fc  ; mASK THE LOWMOST BIT PAIR OFF
  1826.     ora #$02  ; sELECT vic-ii BANK 1 (THE INVERSE OF BINARY 01 IS 10)
  1827.     sta $dd00
  1828.  
  1829.   wHY SHOULD YOU SET THE PINS TO OUTPUTS? hARDWARE reset RESETS ALL
  1830. i/o LINES TO INPUTS, AND THANKS TO THE cia'S INTERNAL PULL-UP
  1831. RESISTORS, THE INPUTS ACTUALLY OUTPUT LOGICAL HIGH VOLTAGE LEVEL. sO,
  1832. UPON -reset, THE VIDEO BANK 0 IS SELECTED AUTOMATICALLY, AND OLDER
  1833. kERNALS COULD LEAVE IT UNINITIALIZED.
  1834.  
  1835.   nOTE THAT THE vic-ii ALWAYS FETCHES ITS INFORMATION FROM THE
  1836. INTERNAL ram, TOTALLY IGNORING THE MEMORY CONFIGURATION LINES. tHERE
  1837. IS ONLY ONE EXCEPTION TO THIS RULE: tHE CHARACTER GENERATOR rom.
  1838. uNLESS THE uLTIMAX MODE IS SELECTED, vic-ii "SEES" CHARACTER GENERATOR
  1839. rom IN THE MEMORY AREAS 1000-1fff AND 9000-9fff. iF THE uLTIMAX
  1840. CONFIGURATION IS ACTIVE, THE vic-ii FETCHES ALL DATA FROM THE INTERNAL
  1841. ram.
  1842.  
  1843.  
  1844. aCCESSING THE MEMORY PLACES 0 AND 1
  1845.  
  1846.   aLTHOUGH THE ADDRESSES 0 AND 1 OF THE PROCESSOR ARE HARD-WIRED TO
  1847. ITS ON-CHIP i/o PORT REGISTERS, YOU CAN ACCESS THE MEMORY PLACES 0 AND
  1848. 1. tHE VIDEO CHIP ALWAYS READS FROM ram (OR CHARACTER GENERATOR rom),
  1849. SO YOU CAN USE IT TO READ ALSO FROM 0 AND 1. eNABLE THE BIT-MAP SCREEN
  1850. AND SET THE START ADDRESS OF THE GRAPHICS SCREEN TO 0. nOW YOU CAN SEE
  1851. THESE TWO MEMORY LOCATIONS IN THE UPPER LEFT CORNER. aLTERNATIVELY,
  1852. YOU COULD SET THE CHARACTER GENERATOR START ADDRESS TO 0, IN WHICH
  1853. CASE YOU WOULD SEE THESE LOCATIONS IN @ CHARACTERS (CODE 0). oR, YOU
  1854. CAN ACTIVATE A SPRITE WITH START ADDRESS 0. wHICHEVER METHOD YOU
  1855. CHOOSE, YOU CAN READ THESE LOCATIONS WITH SPRITE COLLISION REGISTERS.
  1856. dEFINE A SPRITE CONSISTING OF ONLY ONE DOT, AND MOVE IT TO READ THE 8
  1857. BITS OF EACH BYTE WITH THE SPRITE TO SPRITE OR SPRITE TO BACKGROUND
  1858. COLLISION REGISTERS.
  1859.   
  1860.   bUT HOW CAN YOU WRITE TO THESE LOCATIONS? iF YOU EXECUTE THE COMMAND
  1861. poke 53265,59, YOU WILL SEE THAT THE MEMORY PLACE 1 CHANGES ITS VALUE
  1862. WILDLY. iF YOU DISABLE THE INTERRUPTS (poke53664,127), IT WILL REMAIN
  1863. STABLE. hOW IS THIS POSSIBLE? wHEN THE PROCESSOR WRITES TO 0 OR 1, IT
  1864. WILL PUT THE ADDRESS ON THE ADDRESS BUS AND SET THE r/-w LINE TO INDICATE
  1865. A WRITE CYCLE, BUT IT DOES NOT PUT THE DATA ON THE DATA BUS. tHUS, IT
  1866. WRITES "RANDOM" DATA. oF COURSE THIS DATA IS NOT TRULY RANDOM. aCTUALLY
  1867. IT IS SOMETHING THAT THE VIDEO CHIP LEFT ON THE BUS ON ITS CLOCK HALF.
  1868. sO, IF YOU WANT TO WRITE A CERTAIN VALUE ON 0 OR 1, YOU HAVE TO MAKE THE
  1869. VIDEO CHIP TO READ THAT VALUE JUST BEFORE THE STORE CYCLE. tHIS REQUIRES
  1870. VERY ACCURATE TIMING, BUT IT CAN BE ACHIEVED EVEN WITH A CAREFULLY
  1871. WRITTEN basic PROGRAM. jUST WAIT THE VIDEO CHIP TO BE IN THE TOP OR
  1872. BOTTOM BORDER AND THE BEAM TO BE IN THE MIDDLE OF THE SCREEN (NOT IN THE
  1873. SIDE BORDERS). aT THIS AREA, THE VIDEO CHIP WILL ALWAYS READ THE LAST
  1874. BYTE OF THE VIDEO BANK (BY DEFAULT $3fff). nOW, IF YOU STORE ANYTHING TO
  1875. THE i/o PORT REGISTERS 0 OR 1 WHILE THE VIDEO CHIP IS REFRESHING THIS
  1876. SCREEN AREA, THE CONTENTS OF THE MEMORY PLACE $3fff WILL BE WRITTEN TO
  1877. THE RESPECTIVE MEMORY PLACE (0 OR 1).  nOTE THAT THIS TRICK DOES NOT WORK
  1878. RELIABLY ON ALL COMPUTERS.  yOU NEED GOOD rf PROTECTION, AS THE DATA BUS
  1879. WILL NOT BE DRIVEN AT ALL WHEN THE VALUE REMAINS ON IT.
  1880.  
  1881.   oN THE c128 IN ITS 2 mhZ MODE, YOU CAN WRITE TO THE MEMORY PLACES
  1882. WITH AN EASIER KLUDGE.  jUST MAKE SURE THAT THE VIDEO CHIP IS NOT
  1883. PERFORMING THE MEMORY REFRESH (AS IT WOULD SLOW DOWN TO 1 mhZ IN THAT
  1884. CASE), AND USE SOME INSTRUCTION THAT READS FROM A PROPER MEMORY LOCATION
  1885. BEFORE WRITING TO 0 OR 1.  iNDEXED ZERO-PAGE ADDRESSING MODES ARE GOOD
  1886. FOR IT.  i TESTED THIS TRICK WITH ldx#1 FOLLOWED BY sta $ff,x.  aS YOU
  1887. CAN READ FROM THE INSTRUCTION TIMING SECTION OF THIS DOCUMENT, THE
  1888. INSTRUCTION FIRST READS FROM $ff (THE BASE ADDRESS) AND THEN WRITES TO 0.
  1889. tHE TIMING CAN BE DONE WITH A SIMPLE lda$d012:cmp$d012:beq *-3 LOOP.
  1890. bUT IN THE c128 MODE YOU CAN RELOCATE THE STACK PAGE TO ZERO PAGE, SO
  1891. THIS TRICK IS NOT REALLY USEFUL.
  1892.  
  1893.   yOU CAN ALSO READ THE MEMORY PLACES 0 AND 1 MUCH FASTER THAN WITH
  1894. SPRITE COLLISIONS. jUST MAKE THE VIDEO CHIP TO READ FROM 0 OR 1, AND
  1895. THEN READ FROM NON-CONNECTED ADDRESS SPACE ($de00-$dfff ON A STOCK c64;
  1896. ALSO $d700-$d7ff ON c128'S). aCTUALLY, YOU CAN PRODUCE A COMPLETE MAP
  1897. OF THE VIDEO TIMING ON YOUR COMPUTER BY MAKING A LOOP THAT READS FROM
  1898. OPEN ADDRESS SPACE, PAUSING ONE FRAME AND ONE CYCLE IN BETWEEN. aND IF
  1899. YOU ARE INTO COPY PROTECTIONS, YOU COULD WRITE A PROGRAM ON THE OPEN
  1900. ADDRESS SPACE. jUST REMEMBER THAT THERE MUST BE A BYTE ON THE BUS FOR
  1901. EACH CLOCK CYCLE.
  1902.  
  1903.   tHESE TRICKS UNFORTUNATELY DO NOT WORK RELIABLY ON ALL UNITS. sO FAR
  1904. i HAVE HAD THE OPPORTUNITY TO TRY IT ON THREE COMPUTERS, TWO OF WHICH
  1905. WERE cOMMODORE 128 dcr'S (c128'S HOUSED IN METAL CASE WITH A 1571 FLOPPY
  1906. DISK DRIVE, WHOSE CONTROLLER IS INTEGRATED ON THE MOTHER BOARD). oNE
  1907. c128dcr DROVE SOME OF ITS DATA BITS TOO HEAVILY TO HIGH STATE.  nO WONDER,
  1908. SINCE ITS HOUSING CONSISTED OF SOME NEWSPAPERS SPREAD ON THE FLOOR.
  1909.  
  1910.  
  1911.  
  1912.                 aUTOSTART cODE
  1913.  
  1914.   aLTHOUGH THIS DOCUMENT CONCENTRATES ON HARDWARE, THERE IS ONE THING
  1915. THAT YOU MUST KNOW ABOUT THE FIRMWARE TO GET COMPLETE CONTROL OVER
  1916. YOUR COMPUTER. aS THE cOMMODORE 64 ALWAYS SWITCHES THE romS ON UPON
  1917. -reset, YOU CANNOT RELOCATE THE reset VECTOR BY WRITING SOMETHING IN
  1918. ram. iNSTEAD, YOU HAVE TO USE THE aUTOSTART CODE THAT WILL BE
  1919. RECOGNIZED BY THE kernal rom. iF THE MEMORY PLACES FROM $8004 THROUGH
  1920. $8008 CONTAIN THE petscii STRING 'cbm80' (c3 c2 cd 38 30), THE reset
  1921. ROUTINE JUMPS TO ($8000) AND THE DEFAULT nmi HANDLER JUMPS TO ($8002).
  1922.  
  1923.   sOME PROGRAMS THAT LOAD INTO ram TAKE ADVANTAGE OF THIS AND DON'T
  1924. LET THE MACHINE TO BE RESET. yOU DON'T HAVE TO MODIFY THE rom TO GET
  1925. RID OF THIS ANNOYING BEHAVIOUR. sIMPLY GROUND THE -exrom LINE FOR THE
  1926. BEGINNING OF THE reset SEQUENCE.
  1927.  
  1928.  
  1929.  
  1930.                 nOTES
  1931.  
  1932.   sEE THE mcs 6500 mICROCOMPUTER fAMILY pROGRAMMING mANUAL FOR LESS
  1933. INFORMATION.
  1934.  
  1935.  
  1936. rEFERENCES:
  1937.   c64 mEMORY mAPS       c64 pROGRAMMER'S rEFERENCE gUIDE, PP. 262-267
  1938.                         c64 sCHEMATIC dIAGRAM
  1939.   6510 bLOCK dIAGRAM    c64 pROGRAMMER'S rEFERENCE gUIDE,  P. 404
  1940.   iNSTRUCTION sET       c64 pROGRAMMER'S rEFERENCE gUIDE, PP. 254-255, 416-417
  1941. c64/128 rEAL pROGRAMMER'S rEVENGE gUIDE
  1942.                         c=lEHTI MAGAZINE 4/87
  1943.