diff --git a/help/6502CPU.html b/help/6502CPU.html index e7b51ce1..820868f9 100644 --- a/help/6502CPU.html +++ b/help/6502CPU.html @@ -56,50 +56,50 @@

-

#

-

# $Id: 6502_cpu.txt,v 1.1.1.1 2004/08/29 01:29:35 bryan Exp $

-

#

-

# This file is part of Commodore 64 emulator

-

#      and Program Development System.

-

#

-

# See README for copyright notice

-

#

-

# This file contains documentation for 6502/6510/8500/8502 instruction set.

-

#

-

#

-

# Written by

-

#   John West       (john@ucc.gu.uwa.edu.au)

-

#   Marko MЉkelЉ    (msmakela@kruuna.helsinki.fi)

-

#

-

#

-

# $Log: 6502_cpu.txt,v $

-

# Revision 1.1.1.1  2004/08/29 01:29:35  bryan

-

# no message

-

#

-

# Revision 1.1  2002/05/21 00:42:27  xodnizel

-

# updates

-

#

-

# Revision 1.8  1994/06/03  19:50:04  jopi

-

# Patchlevel 2

-

#

-

# Revision 1.7  1994/04/15  13:07:04  jopi

-

# 65xx Register descriptions added

-

#

-

# Revision 1.6  1994/02/18  16:09:36  jopi

-

#

-

# Revision 1.5  1994/01/26  16:08:37  jopi

-

# X64 version 0.2 PL 1

-

#

-

# Revision 1.4  1993/11/10  01:55:34  jopi

-

#

-

# Revision 1.3  93/06/21  13:37:18  jopi

-

#  X64 version 0.2 PL 0

-

#

-

# Revision 1.2  93/06/21  13:07:15  jopi

-

# *** empty log message ***

-

#

-

#

-


+

#

+

# $Id: 6502_cpu.txt,v 1.1.1.1 2004/08/29 01:29:35 bryan Exp $

+

#

+

# This file is part of Commodore 64 emulator

+

#      and Program Development System.

+

#

+

# See README for copyright notice

+

#

+

# This file contains documentation for 6502/6510/8500/8502 instruction set.

+

#

+

#

+

# Written by

+

#   John West       (john@ucc.gu.uwa.edu.au)

+

#   Marko MЉkelЉ    (msmakela@kruuna.helsinki.fi)

+

#

+

#

+

# $Log: 6502_cpu.txt,v $

+

# Revision 1.1.1.1  2004/08/29 01:29:35  bryan

+

# no message

+

#

+

# Revision 1.1  2002/05/21 00:42:27  xodnizel

+

# updates

+

#

+

# Revision 1.8  1994/06/03  19:50:04  jopi

+

# Patchlevel 2

+

#

+

# Revision 1.7  1994/04/15  13:07:04  jopi

+

# 65xx Register descriptions added

+

#

+

# Revision 1.6  1994/02/18  16:09:36  jopi

+

#

+

# Revision 1.5  1994/01/26  16:08:37  jopi

+

# X64 version 0.2 PL 1

+

#

+

# Revision 1.4  1993/11/10  01:55:34  jopi

+

#

+

# Revision 1.3  93/06/21  13:37:18  jopi

+

#  X64 version 0.2 PL 0

+

#

+

# Revision 1.2  93/06/21  13:07:15  jopi

+

# *** empty log message ***

+

#

+

#

+


Note: To extract the uuencoded ML programs in this article most

      easily you may use e.g. "uud" by Edwin Kremer ,

      which extracts them all at once.

@@ -124,45 +124,45 @@


6510 Instructions by Addressing Modes


-

off- ++++++++++ Positive ++++++++++  ---------- Negative ----------

-

set  00      20      40      60      80      a0      c0      e0      mode

-


-

+00  BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX     Impl/immed

-

+01  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir,x)

-

+02   t       t       t       t      NOP*t   LDX     NOP*t   NOP*t     ? /immed

-

+03  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    (indir,x)

-

+04  NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX     Zeropage

-

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

-

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

-

+07  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Zeropage

-


-

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

-

+09  ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC     Immediate

-

+0a  ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP     Accu/impl

-

+0b  ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC*    Immediate

-

+0c  NOP*    BIT     JMP     JMP ()  STY     LDY     CPY     CPX     Absolute

-

+0d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute

-

+0e  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Absolute

-

+0f  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Absolute

-


-

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

-

+11  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir),y

-

+12   t       t       t       t       t       t       t       t         ?

-

+13  SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB*    (indir),y

-

+14  NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP*    Zeropage,x

-

+15  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage,x

-

+16  ASL     ROL     LSR     ROR     STX  y) LDX  y) DEC     INC     Zeropage,x

-

+17  SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP*    ISB*    Zeropage,x

-


-

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

-

+19  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,y

-

+1a  NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP*    Implied

-

+1b  SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB*    Absolute,y

-

+1c  NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP*    Absolute,x

-

+1d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,x

-

+1e  ASL     ROL     LSR     ROR     SHX**y) LDX  y) DEC     INC     Absolute,x

-

+1f  SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP*    ISB*    Absolute,x

-


+

off- ++++++++++ Positive ++++++++++  ---------- Negative ----------

+

set  00      20      40      60      80      a0      c0      e0      mode

+


+

+00  BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX     Impl/immed

+

+01  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir,x)

+

+02   t       t       t       t      NOP*t   LDX     NOP*t   NOP*t     ? /immed

+

+03  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    (indir,x)

+

+04  NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX     Zeropage

+

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

+

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

+

+07  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Zeropage

+


+

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

+

+09  ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC     Immediate

+

+0a  ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP     Accu/impl

+

+0b  ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC*    Immediate

+

+0c  NOP*    BIT     JMP     JMP ()  STY     LDY     CPY     CPX     Absolute

+

+0d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute

+

+0e  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Absolute

+

+0f  SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    Absolute

+


+

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

+

+11  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     (indir),y

+

+12   t       t       t       t       t       t       t       t         ?

+

+13  SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB*    (indir),y

+

+14  NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP*    Zeropage,x

+

+15  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage,x

+

+16  ASL     ROL     LSR     ROR     STX  y) LDX  y) DEC     INC     Zeropage,x

+

+17  SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP*    ISB*    Zeropage,x

+


+

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

+

+19  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,y

+

+1a  NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP*    Implied

+

+1b  SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB*    Absolute,y

+

+1c  NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP*    Absolute,x

+

+1d  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Absolute,x

+

+1e  ASL     ROL     LSR     ROR     SHX**y) LDX  y) DEC     INC     Absolute,x

+

+1f  SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP*    ISB*    Absolute,x

+


       ROR intruction is available on MC650x microprocessors after

       June, 1976.


@@ -337,9 +337,9 @@


-- A brief explanation about what may happen while using don't care states.


-

       ANE $8B         A = (A | #$EE) & X & #byte

-

                       same as

-

                       A = ((A & #$11 & X) | ( #$EE & X)) & #byte

+

       ANE $8B         A = (A | #$EE) & X & #byte

+

                       same as

+

                       A = ((A & #$11 & X) | ( #$EE & X)) & #byte


                       In real 6510/8502 the internal parameter #$11

                       may occasionally be #$10, #$01 or even #$00.

@@ -348,15 +348,15 @@

                       of the instruction.  The value probably depends

                       on the data that was left on the bus by the VIC-II.


-

       LXA $AB         C=Lehti:   A = X = ANE

-

                       Alternate: A = X = (A & #byte)

+

       LXA $AB         C=Lehti:   A = X = ANE

+

                       Alternate: A = X = (A & #byte)


                       TXA and TAX have to be responsible for these.


-

       SHA $93,$9F     Store (A & X & (ADDR_HI + 1))

-

       SHX $9E         Store (X & (ADDR_HI + 1))

-

       SHY $9C         Store (Y & (ADDR_HI + 1))

-

       SHS $9B         SHA and TXS, where X is replaced by (A & X).

+

       SHA $93,$9F     Store (A & X & (ADDR_HI + 1))

+

       SHX $9E         Store (X & (ADDR_HI + 1))

+

       SHY $9C         Store (Y & (ADDR_HI + 1))

+

       SHS $9B         SHA and TXS, where X is replaced by (A & X).


                       Note: The value to be stored is copied also

                       to ADDR_HI if page boundary is crossed.

@@ -381,7 +381,7 @@

More fortunate is its opposite, 'LAX' which just loads a byte

simultaneously into both A and X.


-

       $6B  ARR

+

       $6B  ARR


This instruction seems to be a harmless combination of AND and ROR at

first sight, but it turns out that it affects the V flag and also has

@@ -419,36 +419,36 @@

To help you understand this description, here is a C routine that

illustrates the ARR operation in Decimal mode:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          t,  /* temporary value */

-

          s;  /* value to be ARRed with Accumulator */

-


-

       t = A & s;                      /* Perform the AND. */

-


-

       AH = t >> 4;                    /* Separate the high */

-

       AL = t & 15;                    /* and low nybbles. */

-


-

       N = C;                          /* Set the N and */

-

       Z = !(A = (t >> 1) | (C << 7)); /* Z flags traditionally */

-

       V = (t ^ A) & 64;               /* and V flag in a weird way. */

-


-

       if (AL + (AL & 1) > 5)          /* BCD "fixup" for low nybble. */

-

         A = (A & 0xF0) | ((A + 6) & 0xF);

-


-

       if (C = AH + (AH & 1) > 5)      /* Set the Carry flag. */

-

         A = (A + 0x60) & 0xFF;        /* BCD "fixup" for high nybble. */

-


-

       $CB  SBX   X <- (A & X) - Immediate

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

          t,  /* temporary value */

+

          s;  /* value to be ARRed with Accumulator */

+


+

       t = A & s;                      /* Perform the AND. */

+


+

       AH = t >> 4;                    /* Separate the high */

+

       AL = t & 15;                    /* and low nybbles. */

+


+

       N = C;                          /* Set the N and */

+

       Z = !(A = (t >> 1) | (C << 7)); /* Z flags traditionally */

+

       V = (t ^ A) & 64;               /* and V flag in a weird way. */

+


+

       if (AL + (AL & 1) > 5)          /* BCD "fixup" for low nybble. */

+

         A = (A & 0xF0) | ((A + 6) & 0xF);

+


+

       if (C = AH + (AH & 1) > 5)      /* Set the Carry flag. */

+

         A = (A + 0x60) & 0xFF;        /* BCD "fixup" for high nybble. */

+


+

       $CB  SBX   X <- (A & X) - Immediate

+


The 'SBX' ($CB) may seem to be very complex operation, even though it

is a combination of the subtraction of accumulator and parameter, as

in the 'CMP' instruction, and the command 'DEX'. As a result, both A

@@ -461,23 +461,23 @@


Proof:


-

begin 644 vsbx

-

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```*D`H#V1*Z`_D2N@09$KJ0>%

-

M^QBE^VEZJ+$KH#F1*ZD`2"BI`*(`RP`(:-B@.5$K*4#P`E@`H#VQ*SAI`)$K

-

JD-Z@/[$K:0"1*Y#4J2X@TO\XH$&Q*VD`D2N0Q,;[$+188/_^]_:_OK>V

-

`

-

end

-


-

and

-


-

begin 644 sbx

-

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI`*!-D2N@3Y$KH%&1*ZD#

-

MA?L8I?M*2)`#J1@LJ3B@29$K:$J0`ZGX+*G8R)$K&/BXJ?2B8\L)AOP(:(7]

-

MV#B@3;$KH$\Q*Z!1\2L(1?SP`0!H1?TIM]#XH$VQ*SAI`)$KD,N@3[$K:0"1

-

9*Y#!J2X@TO\XH%&Q*VD`D2N0L<;[$))88-#X

-

`

-

end

-


+

begin 644 vsbx

+

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```*D`H#V1*Z`_D2N@09$KJ0>%

+

M^QBE^VEZJ+$KH#F1*ZD`2"BI`*(`RP`(:-B@.5$K*4#P`E@`H#VQ*SAI`)$K

+

JD-Z@/[$K:0"1*Y#4J2X@TO\XH$&Q*VD`D2N0Q,;[$+188/_^]_:_OK>V

+

`

+

end

+


+

and

+


+

begin 644 sbx

+

M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI`*!-D2N@3Y$KH%&1*ZD#

+

MA?L8I?M*2)`#J1@LJ3B@29$K:$J0`ZGX+*G8R)$K&/BXJ?2B8\L)AOP(:(7]

+

MV#B@3;$KH$\Q*Z!1\2L(1?SP`0!H1?TIM]#XH$VQ*SAI`)$KD,N@3[$K:0"1

+

9*Y#!J2X@TO\XH%&Q*VD`D2N0L<;[$))88-#X

+

`

+

end

+


These test programs show if your machine is compatible with ours

regarding the opcode $CB. The first test, vsbx, proves that SBX does

not affect the V flag. The latter one, sbx, proves the rest of our

@@ -508,10 +508,10 @@

language monitor, as it makes use of the BRK instruction. The result

tables will be written on pages $C2 and $C3.


-

begin 644 sbx-c100

-

M`,%XH`",#L&,$,&,$L&XJ8*B@LL7AOL(:(7\N#BM#L$M$,'M$L$(Q?OP`B@`

-

M:$7\\`,@4,'N#L'0U.X0P=#/SB#0[A+!T,<``````````````)BJ\!>M#L$M

-

L$,'=_\'0":T2P=W_PM`!8,K0Z:T.P2T0P9D`PID`!*T2P9D`PYD`!

+

begin 644 sbx-c100

+

M`,%XH`",#L&,$,&,$L&XJ8*B@LL7AOL(:(7\N#BM#L$M$,'M$L$(Q?OP`B@`

+

M:$7\\`,@4,'N#L'0U.X0P=#/SB#0[A+!T,<``````````````)BJ\!>M#L$M

+

L$,'=_\'0":T2P=W_PM`!8,K0Z:T.P2T0P9D`PID`!*T2P9D`PYD`!


Other undocumented instructions usually cause two preceding opcodes

being executed. However 'NOP' seems to completely disappear from 'SBC'

@@ -603,11 +603,11 @@


Register selection for load and store


-

  bit1 bit0     A  X  Y

-

   0    0             x

-

   0    1          x

-

   1    0       x

-

   1    1       x  x

+

  bit1 bit0     A  X  Y

+

   0    0             x

+

   0    1          x

+

   1    0       x

+

   1    1       x  x


So, A and X are selected by bits 1 and 0 respectively, while

~(bit1|bit0) enables Y.

@@ -632,39 +632,39 @@

how it can do that all in a single cycle. Here's a C code version of

the instruction:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          s;  /* value to be added to Accumulator */

-


-

       AL = (A & 15) + (s & 15) + C;         /* Calculate the lower nybble. */

-


-

       AH = (A >> 4) + (s >> 4) + (AL > 15); /* Calculate the upper nybble. */

-


-

       if (AL > 9) AL += 6;                  /* BCD fixup for lower nybble. */

-


-

       Z = ((A + s + C) & 255 != 0);         /* Zero flag is set just

-

                                                like in Binary mode. */

-


-

       /* Negative and Overflow flags are set with the same logic than in

-

          Binary mode, but after fixing the lower nybble. */

-


-

       N = (AH & 8 != 0);

-

       V = ((AH << 4) ^ A) & 128 && !((A ^ s) & 128);

-


-

       if (AH > 9) AH += 6;                  /* BCD fixup for upper nybble. */

-


-

       /* Carry is the only flag set after fixing the result. */

-


-

       C = (AH > 15);

-

       A = ((AH << 4) | (AL & 15)) & 255;

+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

          s;  /* value to be added to Accumulator */

+


+

       AL = (A & 15) + (s & 15) + C;         /* Calculate the lower nybble. */

+


+

       AH = (A >> 4) + (s >> 4) + (AL > 15); /* Calculate the upper nybble. */

+


+

       if (AL > 9) AL += 6;                  /* BCD fixup for lower nybble. */

+


+

       Z = ((A + s + C) & 255 != 0);         /* Zero flag is set just

+

                                                like in Binary mode. */

+


+

       /* Negative and Overflow flags are set with the same logic than in

+

          Binary mode, but after fixing the lower nybble. */

+


+

       N = (AH & 8 != 0);

+

       V = ((AH << 4) ^ A) & 128 && !((A ^ s) & 128);

+


+

       if (AH > 9) AH += 6;                  /* BCD fixup for upper nybble. */

+


+

       /* Carry is the only flag set after fixing the result. */

+


+

       C = (AH > 15);

+

       A = ((AH << 4) | (AL & 15)) & 255;


 The C flag is set as the quiche eaters expect, but the N and V flags

are set after fixing the lower nybble but before fixing the upper one.

@@ -675,14 +675,14 @@

      Decimal mode, and aborts with BRK if anything breaks this theory.

      If everything goes well, it ends in RTS.


-

begin 600 dadc

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH(V1

-

M*Q@(I?PI#X7]I?LI#V7]R0J0 FD%J"D/A?VE^RGP9?PI\ C $) ":0^JL @H

-

ML ?)H) &""@X:5\X!?V%_0AH*3W@ ! ""8"HBD7[$ JE^T7\, 28"4"H**7[

-

M9?S0!)@) J@8N/BE^V7\V A%_= G:(3]1?W0(.;[T(?F_-"#:$D8\ )88*D=

-

0&&4KA?NI &4LA?RI.&S[  A%

-


-

end

+

begin 600 dadc

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH(V1

+

M*Q@(I?PI#X7]I?LI#V7]R0J0 FD%J"D/A?VE^RGP9?PI\ C $) ":0^JL @H

+

ML ?)H) &""@X:5\X!?V%_0AH*3W@ ! ""8"HBD7[$ JE^T7\, 28"4"H**7[

+

M9?S0!)@) J@8N/BE^V7\V A%_= G:(3]1?W0(.;[T(?F_-"#:$D8\ )88*D=

+

0&&4KA?NI &4LA?RI.&S[  A%

+


+

end


 All programs in this chapter have been successfully tested on a Vic20

and a Commodore 64 and a Commodore 128D in C64 mode. They should run on

@@ -695,45 +695,45 @@


Proof:


-

begin 600 dsbc-cmp-flags

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'B@ (3[A/RB XH8:66HL2N@

-

M09$KH$R1*XII::BQ*Z!%D2N@4)$K^#BXI?OE_-@(:(7].+BE^^7\"&A%_? !

-

5 .;[T./F_-#?RA"_8!@X&#CEY<7%

-


-

end

+

begin 600 dsbc-cmp-flags

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'B@ (3[A/RB XH8:66HL2N@

+

M09$KH$R1*XII::BQ*Z!%D2N@4)$K^#BXI?OE_-@(:(7].+BE^^7\"&A%_? !

+

5 .;[T./F_-#?RA"_8!@X&#CEY<7%

+


+

end


 The only difference in SBC's operation in decimal mode from binary mode

is the result-fixup:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          s;  /* value to be added to Accumulator */

-


-

       AL = (A & 15) - (s & 15) - !C;        /* Calculate the lower nybble. */

-


-

       if (AL & 16) AL -= 6;                 /* BCD fixup for lower nybble. */

-


-

       AH = (A >> 4) - (s >> 4) - (AL & 16); /* Calculate the upper nybble. */

-


-

       if (AH & 16) AH -= 6;                 /* BCD fixup for upper nybble. */

-


-

       /* The flags are set just like in Binary mode. */

-


-

       C = (A - s - !C) & 256 != 0;

-

       Z = (A - s - !C) & 255 != 0;

-

       V = ((A - s - !C) ^ s) & 128 && (A ^ s) & 128;

-

       N = (A - s - !C) & 128 != 0;

-


-

       A = ((AH << 4) | (AL & 15)) & 255;

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

          s;  /* value to be added to Accumulator */

+


+

       AL = (A & 15) - (s & 15) - !C;        /* Calculate the lower nybble. */

+


+

       if (AL & 16) AL -= 6;                 /* BCD fixup for lower nybble. */

+


+

       AH = (A >> 4) - (s >> 4) - (AL & 16); /* Calculate the upper nybble. */

+


+

       if (AH & 16) AH -= 6;                 /* BCD fixup for upper nybble. */

+


+

       /* The flags are set just like in Binary mode. */

+


+

       C = (A - s - !C) & 256 != 0;

+

       Z = (A - s - !C) & 255 != 0;

+

       V = ((A - s - !C) ^ s) & 128 && (A ^ s) & 128;

+

       N = (A - s - !C) & 128 != 0;

+


+

       A = ((AH << 4) | (AL & 15)) & 255;

+


 Again Z flag is set before any BCD fixup. The N and V flags are set

at any time before fixing the high nybble. The C flag may be set in any

phase.

@@ -756,13 +756,13 @@

 The following program, which tests SBC's result and flags,

contains the 6502 version of the pseudo code example above.


-

begin 600 dsbc

-

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH':1

-

M*S@(I?PI#X7]I?LI#^7]L /I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL KI7RBP

-

M#ND/.+ )*+ &Z0^P NE?A/T%_87]*+BE^^7\"&BH.+CXI?OE_-@(1?W0FVB$

-

8_47]T)3F^]">YOS0FFA)&- $J3C0B%A@

-


-

end

+

begin 600 dsbc

+

M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH':1

+

M*S@(I?PI#X7]I?LI#^7]L /I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL KI7RBP

+

M#ND/.+ )*+ &Z0^P NE?A/T%_87]*+BE^^7\"&BH.+CXI?OE_-@(1?W0FVB$

+

8_47]T)3F^]">YOS0FFA)&- $J3C0B%A@

+


+

end


 Obviously the undocumented instructions RRA (ROR+ADC) and ISB

(INC+SBC) have inherited also the decimal operation from the official

@@ -771,29 +771,29 @@

dincsbc-deccmp proves that ISB's and DCP's (DEC+CMP) flags are not

affected by the D flag.


-

begin 644 droradc

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH(V1

-

M*S@(I?PI#X7]I?LI#V7]R0J0`FD%J"D/A?VE^RGP9?PI\`C`$)`":0^JL`@H

-

ML`?)H)`&""@X:5\X!?V%_0AH*3W@`!`""8"HBD7[$`JE^T7\,`28"4"H**7[

-

M9?S0!)@)`J@XN/BE^R;\9_S8"$7]T"=HA/U%_=`@YOO0A>;\T(%H21CP`EA@

-

2J1T892N%^ZD`92R%_*DX;/L`

-

`

-

end

-


-

begin 644 dincsbc

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH':1

-

M*S@(I?PI#X7]I?LI#^7]L`/I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL`KI7RBP

-

M#ND/.+`)*+`&Z0^P`NE?A/T%_87]*+BE^^7\"&BH.+CXI?O&_.?\V`A%_="9

-

::(3]1?W0DN;[T)SF_-"8:$D8T`2I.-"&6&#\

-

`

-

end

-


-

begin 644 dincsbc-deccmp

-

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'B@`(3[A/RB`XH8:7>HL2N@

-

M3Y$KH%R1*XII>ZBQ*Z!3D2N@8)$KBFE_J+$KH%61*Z!BD2OX.+BE^^;\Q_S8

-

L"&B%_3BXI?OF_,?\"&A%_?`!`.;[T-_F_-#;RA"M8!@X&#CFYL;&Q\?GYP#8

-

`

-

end

+

begin 644 droradc

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH(V1

+

M*S@(I?PI#X7]I?LI#V7]R0J0`FD%J"D/A?VE^RGP9?PI\`C`$)`":0^JL`@H

+

ML`?)H)`&""@X:5\X!?V%_0AH*3W@`!`""8"HBD7[$`JE^T7\,`28"4"H**7[

+

M9?S0!)@)`J@XN/BE^R;\9_S8"$7]T"=HA/U%_=`@YOO0A>;\T(%H21CP`EA@

+

2J1T892N%^ZD`92R%_*DX;/L`

+

`

+

end

+


+

begin 644 dincsbc

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI&*``A/N$_$B@+)$KH':1

+

M*S@(I?PI#X7]I?LI#^7]L`/I!1@I#ZBE_"GPA?VE^RGP"#CE_2GPL`KI7RBP

+

M#ND/.+`)*+`&Z0^P`NE?A/T%_87]*+BE^^7\"&BH.+CXI?O&_.?\V`A%_="9

+

::(3]1?W0DN;[T)SF_-"8:$D8T`2I.-"&6&#\

+

`

+

end

+


+

begin 644 dincsbc-deccmp

+

M`0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'B@`(3[A/RB`XH8:7>HL2N@

+

M3Y$KH%R1*XII>ZBQ*Z!3D2N@8)$KBFE_J+$KH%61*Z!BD2OX.+BE^^;\Q_S8

+

L"&B%_3BXI?OF_,?\"&A%_?`!`.;[T-_F_-#;RA"M8!@X&#CFYL;&Q\?GYP#8

+

`

+

end



6510 features

@@ -954,617 +954,617 @@


 Instructions accessing the stack


-

    BRK

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away),

-

                      increment PC

-

       3  $0100,S  W  push PCH on stack (with B flag set), decrement S

-

       4  $0100,S  W  push PCL on stack, decrement S

-

       5  $0100,S  W  push P on stack, decrement S

-

       6   $FFFE   R  fetch PCL

-

       7   $FFFF   R  fetch PCH

-


-

    RTI

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull P from stack, increment S

-

       5  $0100,S  R  pull PCL from stack, increment S

-

       6  $0100,S  R  pull PCH from stack

-


-

    RTS

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull PCL from stack, increment S

-

       5  $0100,S  R  pull PCH from stack

-

       6    PC     R  increment PC

-


-

    PHA, PHP

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  W  push register on stack, decrement S

-


-

    PLA, PLP

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull register from stack

-


-

    JSR

-


-

       #  address R/W description

-

      --- ------- --- -------------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

       3  $0100,S  R  internal operation (predecrement S?)

-

       4  $0100,S  W  push PCH on stack, decrement S

-

       5  $0100,S  W  push PCL on stack, decrement S

-

       6    PC     R  copy low address byte to PCL, fetch high address

-

                      byte to PCH

-


-

 Accumulator or implied addressing

-


-

       #  address R/W description

-

      --- ------- --- -----------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  read next instruction byte (and throw it away)

-


-

 Immediate addressing

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch value, increment PC

-


-

 Absolute addressing

-


-

    JMP

-


-

       #  address R/W description

-

      --- ------- --- -------------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

       3    PC     R  copy low address byte to PCL, fetch high address

-

                      byte to PCH

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-

       5  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       6  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  W  write register to effective address

-


-

 Zero page addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-

       4  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       5  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

      --- ------- --- ------------------------------------------

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  W  write register to effective address

-


-

 Zero page indexed addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, NOP)

-


-

       #   address  R/W description

-

      --- --------- --- ------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register to it

-

       4  address+I* R  read from effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address is always zero,

-

               i.e. page boundary crossings are not handled.

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #   address  R/W description

-

      --- --------- --- ---------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register X to it

-

       4  address+X* R  read from effective address

-

       5  address+X* W  write the value back to effective address,

-

                        and do the operation on it

-

       6  address+X* W  write the new value to effective address

-


-

      Note: * The high byte of the effective address is always zero,

-

              i.e. page boundary crossings are not handled.

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #   address  R/W description

-

      --- --------- --- -------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

       3   address   R  read from address, add index register to it

-

       4  address+I* W  write to effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address is always zero,

-

               i.e. page boundary crossings are not handled.

-


-

 Absolute indexed addressing

-


-

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

-

                       LAX, LAE, SHS, NOP)

-


-

       #   address  R/W description

-

      --- --------- --- ------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5+ address+I  R  re-read from effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

             + This cycle will be executed only if the effective address

-

               was invalid during cycle #4, i.e. page boundary was crossed.

-


-

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

-

                                    SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #   address  R/W description

-

      --- --------- --- ------------------------------------------

-

       1    PC       R  fetch opcode, increment PC

-

       2    PC       R  fetch low byte of address, increment PC

-

       3    PC       R  fetch high byte of address,

-

                        add index register X to low address byte,

-

                        increment PC

-

       4  address+X* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+X  R  re-read from effective address

-

       6  address+X  W  write the value back to effective address,

-

                        and do the operation on it

-

       7  address+X  W  write the new value to effective address

-


-

      Notes: * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

    Write instructions (STA, STX, STY, SHA, SHX, SHY)

-


-

       #   address  R/W description

-

      --- --------- --- ------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+I  W  write to effective address

-


-

      Notes: I denotes either index register (X or Y).

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100. Because

-

               the processor cannot undo a write to an invalid

-

               address, it always reads from the address first.

-


-

 Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

-


-

       #   address  R/W description

-

      --- --------- --- ---------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch operand, increment PC

-

       3     PC      R  Fetch opcode of next instruction,

-

                        If branch is taken, add operand to PCL.

-

                        Otherwise increment PC.

-

       4+    PC*     R  Fetch opcode of next instruction.

-

                        Fix PCH. If it did not change, increment PC.

-

       5!    PC      R  Fetch opcode of next instruction,

-

                        increment PC.

-


-

      Notes: The opcode fetch of the next instruction is included to

-

             this diagram for illustration purposes. When determining

-

             real execution times, remember to subtract the last

-

             cycle.

-


-

             * The high byte of Program Counter (PCH) may be invalid

-

               at this time, i.e. it may be smaller or bigger by $100.

-


-

             + If branch is taken, this cycle will be executed.

-


-

             ! If branch occurs to different page, this cycle will be

-

               executed.

-


-

 Indexed indirect addressing

-


-

    Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-

       7    address    W  write the value back to effective address,

-

                          and do the operation on it

-

       8    address    W  write the new value to effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

    Write instructions (STA, SAX)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  read from the address, add X to it

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    W  write to effective address

-


-

      Note: The effective address is always fetched from zero page,

-

            i.e. the zero page boundary crossing is not handled.

-


-

 Indirect indexed addressing

-


-

    Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6+  address+Y   R  read from effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

             + This cycle will be executed only if the effective address

-

               was invalid during cycle #5, i.e. page boundary was crossed.

-


-

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   R  read from effective address

-

       7   address+Y   W  write the value back to effective address,

-

                          and do the operation on it

-

       8   address+Y   W  write the new value to effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

    Write instructions (STA, SHA)

-


-

       #    address   R/W description

-

      --- ----------- --- ------------------------------------------

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   W  write to effective address

-


-

      Notes: The effective address is always fetched from zero page,

-

             i.e. the zero page boundary crossing is not handled.

-


-

             * The high byte of the effective address may be invalid

-

               at this time, i.e. it may be smaller by $100.

-


-

 Absolute indirect addressing (JMP)

-


-

       #   address  R/W description

-

      --- --------- --- ------------------------------------------

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch pointer address low, increment PC

-

       3     PC      R  fetch pointer address high, increment PC

-

       4   pointer   R  fetch low address to latch

-

       5  pointer+1* R  fetch PCH, copy latch to PCL

-


-

      Note: * The PCH will always be fetched from the same page

-

              than PCL, i.e. page boundary crossing is not handled.

-


-

               How Real Programmers Acknowledge Interrupts

-


-

 With RMW instructions:

-


-

       ; beginning of combined raster/timer interrupt routine

-

       LSR $D019       ; clear VIC interrupts, read raster interrupt flag to C

-

       BCS raster      ; jump if VIC caused an interrupt

-

       ...             ; timer interrupt routine

-


-

       Operational diagram of LSR $D019:

-


-

         #  data  address  R/W

-

        --- ----  -------  ---  ---------------------------------

-

         1   4E     PC      R   fetch opcode

-

         2   19    PC+1     R   fetch address low

-

         3   D0    PC+2     R   fetch address high

-

         4   xx    $D019    R   read memory

-

         5   xx    $D019    W   write the value back, rotate right

-

         6  xx/2   $D019    W   write the new value back

-


-

       The 5th cycle acknowledges the interrupt by writing the same

-

       value back. If only raster interrupts are used, the 6th cycle

-

       has no effect on the VIC. (It might acknowledge also some

-

       other interrupts.)

-


-

 With indexed addressing:

-


-

       ; acknowledge interrupts to both CIAs

-

       LDX #$10

-

       LDA $DCFD,X

-


-

       Operational diagram of LDA $DCFD,X:

-


-

         #  data  address  R/W  description

-

        --- ----  -------  ---  ---------------------------------

-

         1   BD     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

         3   DC    PC+2     R   fetch address high, add X to address low

-

         4   xx    $DC0D    R   read from address, fix high byte of address

-

         5   yy    $DD0D    R   read from right address

-


-

       ; acknowledge interrupts to CIA 2

-

       LDX #$10

-

       STA $DDFD,X

-


-

       Operational diagram of STA $DDFD,X:

-


-

         #  data  address  R/W  description

-

        --- ----  -------  ---  ---------------------------------

-

         1   9D     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

         3   DC    PC+2     R   fetch address high, add X to address low

-

         4   xx    $DD0D    R   read from address, fix high byte of address

-

         5   ac    $DE0D    W   write to right address

-


-

 With branch instructions:

-


-

       ; acknowledge interrupts to CIA 2

-

               LDA #$00  ; clear N flag

-

               JMP $DD0A

-

       DD0A    BPL $DC9D ; branch

-

       DC9D    BRK       ; return

-


-

       You need the following preparations to initialize the CIA registers:

-


-

               LDA #$91  ; argument of BPL

-

               STA $DD0B

-

               LDA #$10  ; BPL

-

               STA $DD0A

-

               STA $DD08 ; load the ToD values from the latches

-

               LDA $DD0B ; freeze the ToD display

-

               LDA #$7F

-

               STA $DC0D ; assure that $DC0D is $00

-


-

       Operational diagram of BPL $DC9D:

-


-

         #  data  address  R/W  description

-

        --- ----  -------  ---  ---------------------------------

-

         1   10    $DD0A    R   fetch opcode

-

         2   91    $DD0B    R   fetch argument

-

         3   xx    $DD0C    R   fetch opcode, add argument to PCL

-

         4   yy    $DD9D    R   fetch opcode, fix PCH

-

       ( 5   00    $DC9D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 1

-

               LSR       ; clear N flag

-

               JMP $DCFA

-

       DCFA    BPL $DD0D

-

       DD0D    BRK

-


-

       ; Again you need to set the ToD registers of CIA 1 and the

-

       ; Interrupt Control Register of CIA 2 first.

-


-

       Operational diagram of BPL $DD0D:

-


-

         #  data  address  R/W  description

-

        --- ----  -------  ---  ---------------------------------

-

         1   10    $DCFA    R   fetch opcode

-

         2   11    $DCFB    R   fetch argument

-

         3   xx    $DCFC    R   fetch opcode, add argument to PCL

-

         4   yy    $DC0D    R   fetch opcode, fix PCH

-

       ( 5   00    $DD0D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 2 automagically

-

               ; preparations

-

               LDA #$7F

-

               STA $DD0D       ; disable all interrupt sources of CIA2

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$FD

-

               STA $DD0C       ; parameter of BPL

-

               LDA #$10

-

               STA $DD0B       ; BPL

-

               LDA #$40

-

               STA $DD0A       ; RTI/parameter of LSR

-

               LDA #$46

-

               STA $DD09       ; LSR

-

               STA $DD08       ; load the ToD values from the latches

-

               LDA $DD0B       ; freeze the ToD display

-

               LDA #$09

-

               STA $0318

-

               LDA #$DD

-

               STA $0319       ; change NMI vector to $DD09

-

               LDA #$FF        ; Try changing this instruction's operand

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

               LDA #$00        ; To see that the interrupts really occur,

-

               STA $D011       ; use something like this and see how

-

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

-

               BNE LOOP        ; #$FF to #$0F changes the image.

-


-

       When an NMI occurs, the processor jumps to Kernal code, which jumps to

-

       ($0318), which points to the following routine:

-


-

       DD09    LSR $40         ; clear N flag

-

               BPL $DD0A       ; Note: $DD0A contains RTI.

-


-

       Operational diagram of BPL $DD0A:

-


-

         #  data  address  R/W  description

-

        --- ----  -------  ---  ---------------------------------

-

         1   10    $DD0B    R   fetch opcode

-

         2   11    $DD0C    R   fetch argument

-

         3   xx    $DD0D    R   fetch opcode, add argument to PCL

-

         4   40    $DD0A    R   fetch opcode, (fix PCH)

-


-

 With RTI:

-


-

       ; the fastest possible interrupt handler in the 6500 family

-

               ; preparations

-

               SEI

-

               LDA $01         ; disable ROM and enable I/O

-

               AND #$FD

-

               ORA #$05

-

               STA $01

-

               LDA #$7F

-

               STA $DD0D       ; disable CIA 2's all interrupt sources

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$40

-

               STA $DD0C       ; store RTI to $DD0C

-

               LDA #$0C

-

               STA $FFFA

-

               LDA #$DD

-

               STA $FFFB       ; change NMI vector to $DD0C

-

               LDA #$FF        ; Try changing this instruction's operand

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

               LDA #$00        ; To see that the interrupts really occur,

-

               STA $D011       ; use something like this and see how

-

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

-

               BNE LOOP        ; #$FF to #$0F changes the image.

-


+

    BRK

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away),

+

                      increment PC

+

       3  $0100,S  W  push PCH on stack (with B flag set), decrement S

+

       4  $0100,S  W  push PCL on stack, decrement S

+

       5  $0100,S  W  push P on stack, decrement S

+

       6   $FFFE   R  fetch PCL

+

       7   $FFFF   R  fetch PCH

+


+

    RTI

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away)

+

       3  $0100,S  R  increment S

+

       4  $0100,S  R  pull P from stack, increment S

+

       5  $0100,S  R  pull PCL from stack, increment S

+

       6  $0100,S  R  pull PCH from stack

+


+

    RTS

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away)

+

       3  $0100,S  R  increment S

+

       4  $0100,S  R  pull PCL from stack, increment S

+

       5  $0100,S  R  pull PCH from stack

+

       6    PC     R  increment PC

+


+

    PHA, PHP

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away)

+

       3  $0100,S  W  push register on stack, decrement S

+


+

    PLA, PLP

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away)

+

       3  $0100,S  R  increment S

+

       4  $0100,S  R  pull register from stack

+


+

    JSR

+


+

       #  address R/W description

+

      --- ------- --- -------------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

       3  $0100,S  R  internal operation (predecrement S?)

+

       4  $0100,S  W  push PCH on stack, decrement S

+

       5  $0100,S  W  push PCL on stack, decrement S

+

       6    PC     R  copy low address byte to PCL, fetch high address

+

                      byte to PCH

+


+

 Accumulator or implied addressing

+


+

       #  address R/W description

+

      --- ------- --- -----------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  read next instruction byte (and throw it away)

+


+

 Immediate addressing

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch value, increment PC

+


+

 Absolute addressing

+


+

    JMP

+


+

       #  address R/W description

+

      --- ------- --- -------------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

       3    PC     R  copy low address byte to PCL, fetch high address

+

                      byte to PCH

+


+

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                       LAX, NOP)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+


+

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                    SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+

       5  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       6  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  W  write register to effective address

+


+

 Zero page addressing

+


+

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                       LAX, NOP)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+


+

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                    SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+

       4  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       5  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

      --- ------- --- ------------------------------------------

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  W  write register to effective address

+


+

 Zero page indexed addressing

+


+

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                       LAX, NOP)

+


+

       #   address  R/W description

+

      --- --------- --- ------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

       3   address   R  read from address, add index register to it

+

       4  address+I* R  read from effective address

+


+

      Notes: I denotes either index register (X or Y).

+


+

             * The high byte of the effective address is always zero,

+

               i.e. page boundary crossings are not handled.

+


+

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                    SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #   address  R/W description

+

      --- --------- --- ---------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

       3   address   R  read from address, add index register X to it

+

       4  address+X* R  read from effective address

+

       5  address+X* W  write the value back to effective address,

+

                        and do the operation on it

+

       6  address+X* W  write the new value to effective address

+


+

      Note: * The high byte of the effective address is always zero,

+

              i.e. page boundary crossings are not handled.

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #   address  R/W description

+

      --- --------- --- -------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

       3   address   R  read from address, add index register to it

+

       4  address+I* W  write to effective address

+


+

      Notes: I denotes either index register (X or Y).

+


+

             * The high byte of the effective address is always zero,

+

               i.e. page boundary crossings are not handled.

+


+

 Absolute indexed addressing

+


+

    Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,

+

                       LAX, LAE, SHS, NOP)

+


+

       #   address  R/W description

+

      --- --------- --- ------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

       5+ address+I  R  re-read from effective address

+


+

      Notes: I denotes either index register (X or Y).

+


+

             * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100.

+


+

             + This cycle will be executed only if the effective address

+

               was invalid during cycle #4, i.e. page boundary was crossed.

+


+

    Read-Modify-Write instructions (ASL, LSR, ROL, ROR, INC, DEC,

+

                                    SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #   address  R/W description

+

      --- --------- --- ------------------------------------------

+

       1    PC       R  fetch opcode, increment PC

+

       2    PC       R  fetch low byte of address, increment PC

+

       3    PC       R  fetch high byte of address,

+

                        add index register X to low address byte,

+

                        increment PC

+

       4  address+X* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+X  R  re-read from effective address

+

       6  address+X  W  write the value back to effective address,

+

                        and do the operation on it

+

       7  address+X  W  write the new value to effective address

+


+

      Notes: * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100.

+


+

    Write instructions (STA, STX, STY, SHA, SHX, SHY)

+


+

       #   address  R/W description

+

      --- --------- --- ------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+I  W  write to effective address

+


+

      Notes: I denotes either index register (X or Y).

+


+

             * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100. Because

+

               the processor cannot undo a write to an invalid

+

               address, it always reads from the address first.

+


+

 Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

+


+

       #   address  R/W description

+

      --- --------- --- ---------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch operand, increment PC

+

       3     PC      R  Fetch opcode of next instruction,

+

                        If branch is taken, add operand to PCL.

+

                        Otherwise increment PC.

+

       4+    PC*     R  Fetch opcode of next instruction.

+

                        Fix PCH. If it did not change, increment PC.

+

       5!    PC      R  Fetch opcode of next instruction,

+

                        increment PC.

+


+

      Notes: The opcode fetch of the next instruction is included to

+

             this diagram for illustration purposes. When determining

+

             real execution times, remember to subtract the last

+

             cycle.

+


+

             * The high byte of Program Counter (PCH) may be invalid

+

               at this time, i.e. it may be smaller or bigger by $100.

+


+

             + If branch is taken, this cycle will be executed.

+


+

             ! If branch occurs to different page, this cycle will be

+

               executed.

+


+

 Indexed indirect addressing

+


+

    Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  read from the address, add X to it

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+


+

      Note: The effective address is always fetched from zero page,

+

            i.e. the zero page boundary crossing is not handled.

+


+

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  read from the address, add X to it

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+

       7    address    W  write the value back to effective address,

+

                          and do the operation on it

+

       8    address    W  write the new value to effective address

+


+

      Note: The effective address is always fetched from zero page,

+

            i.e. the zero page boundary crossing is not handled.

+


+

    Write instructions (STA, SAX)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  read from the address, add X to it

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    W  write to effective address

+


+

      Note: The effective address is always fetched from zero page,

+

            i.e. the zero page boundary crossing is not handled.

+


+

 Indirect indexed addressing

+


+

    Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6+  address+Y   R  read from effective address

+


+

      Notes: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

             * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100.

+


+

             + This cycle will be executed only if the effective address

+

               was invalid during cycle #5, i.e. page boundary was crossed.

+


+

    Read-Modify-Write instructions (SLO, SRE, RLA, RRA, ISB, DCP)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   R  read from effective address

+

       7   address+Y   W  write the value back to effective address,

+

                          and do the operation on it

+

       8   address+Y   W  write the new value to effective address

+


+

      Notes: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

             * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100.

+


+

    Write instructions (STA, SHA)

+


+

       #    address   R/W description

+

      --- ----------- --- ------------------------------------------

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   W  write to effective address

+


+

      Notes: The effective address is always fetched from zero page,

+

             i.e. the zero page boundary crossing is not handled.

+


+

             * The high byte of the effective address may be invalid

+

               at this time, i.e. it may be smaller by $100.

+


+

 Absolute indirect addressing (JMP)

+


+

       #   address  R/W description

+

      --- --------- --- ------------------------------------------

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch pointer address low, increment PC

+

       3     PC      R  fetch pointer address high, increment PC

+

       4   pointer   R  fetch low address to latch

+

       5  pointer+1* R  fetch PCH, copy latch to PCL

+


+

      Note: * The PCH will always be fetched from the same page

+

              than PCL, i.e. page boundary crossing is not handled.

+


+

               How Real Programmers Acknowledge Interrupts

+


+

 With RMW instructions:

+


+

       ; beginning of combined raster/timer interrupt routine

+

       LSR $D019       ; clear VIC interrupts, read raster interrupt flag to C

+

       BCS raster      ; jump if VIC caused an interrupt

+

       ...             ; timer interrupt routine

+


+

       Operational diagram of LSR $D019:

+


+

         #  data  address  R/W

+

        --- ----  -------  ---  ---------------------------------

+

         1   4E     PC      R   fetch opcode

+

         2   19    PC+1     R   fetch address low

+

         3   D0    PC+2     R   fetch address high

+

         4   xx    $D019    R   read memory

+

         5   xx    $D019    W   write the value back, rotate right

+

         6  xx/2   $D019    W   write the new value back

+


+

       The 5th cycle acknowledges the interrupt by writing the same

+

       value back. If only raster interrupts are used, the 6th cycle

+

       has no effect on the VIC. (It might acknowledge also some

+

       other interrupts.)

+


+

 With indexed addressing:

+


+

       ; acknowledge interrupts to both CIAs

+

       LDX #$10

+

       LDA $DCFD,X

+


+

       Operational diagram of LDA $DCFD,X:

+


+

         #  data  address  R/W  description

+

        --- ----  -------  ---  ---------------------------------

+

         1   BD     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

         3   DC    PC+2     R   fetch address high, add X to address low

+

         4   xx    $DC0D    R   read from address, fix high byte of address

+

         5   yy    $DD0D    R   read from right address

+


+

       ; acknowledge interrupts to CIA 2

+

       LDX #$10

+

       STA $DDFD,X

+


+

       Operational diagram of STA $DDFD,X:

+


+

         #  data  address  R/W  description

+

        --- ----  -------  ---  ---------------------------------

+

         1   9D     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

         3   DC    PC+2     R   fetch address high, add X to address low

+

         4   xx    $DD0D    R   read from address, fix high byte of address

+

         5   ac    $DE0D    W   write to right address

+


+

 With branch instructions:

+


+

       ; acknowledge interrupts to CIA 2

+

               LDA #$00  ; clear N flag

+

               JMP $DD0A

+

       DD0A    BPL $DC9D ; branch

+

       DC9D    BRK       ; return

+


+

       You need the following preparations to initialize the CIA registers:

+


+

               LDA #$91  ; argument of BPL

+

               STA $DD0B

+

               LDA #$10  ; BPL

+

               STA $DD0A

+

               STA $DD08 ; load the ToD values from the latches

+

               LDA $DD0B ; freeze the ToD display

+

               LDA #$7F

+

               STA $DC0D ; assure that $DC0D is $00

+


+

       Operational diagram of BPL $DC9D:

+


+

         #  data  address  R/W  description

+

        --- ----  -------  ---  ---------------------------------

+

         1   10    $DD0A    R   fetch opcode

+

         2   91    $DD0B    R   fetch argument

+

         3   xx    $DD0C    R   fetch opcode, add argument to PCL

+

         4   yy    $DD9D    R   fetch opcode, fix PCH

+

       ( 5   00    $DC9D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 1

+

               LSR       ; clear N flag

+

               JMP $DCFA

+

       DCFA    BPL $DD0D

+

       DD0D    BRK

+


+

       ; Again you need to set the ToD registers of CIA 1 and the

+

       ; Interrupt Control Register of CIA 2 first.

+


+

       Operational diagram of BPL $DD0D:

+


+

         #  data  address  R/W  description

+

        --- ----  -------  ---  ---------------------------------

+

         1   10    $DCFA    R   fetch opcode

+

         2   11    $DCFB    R   fetch argument

+

         3   xx    $DCFC    R   fetch opcode, add argument to PCL

+

         4   yy    $DC0D    R   fetch opcode, fix PCH

+

       ( 5   00    $DD0D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 2 automagically

+

               ; preparations

+

               LDA #$7F

+

               STA $DD0D       ; disable all interrupt sources of CIA2

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$FD

+

               STA $DD0C       ; parameter of BPL

+

               LDA #$10

+

               STA $DD0B       ; BPL

+

               LDA #$40

+

               STA $DD0A       ; RTI/parameter of LSR

+

               LDA #$46

+

               STA $DD09       ; LSR

+

               STA $DD08       ; load the ToD values from the latches

+

               LDA $DD0B       ; freeze the ToD display

+

               LDA #$09

+

               STA $0318

+

               LDA #$DD

+

               STA $0319       ; change NMI vector to $DD09

+

               LDA #$FF        ; Try changing this instruction's operand

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

               LDA #$00        ; To see that the interrupts really occur,

+

               STA $D011       ; use something like this and see how

+

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

+

               BNE LOOP        ; #$FF to #$0F changes the image.

+


+

       When an NMI occurs, the processor jumps to Kernal code, which jumps to

+

       ($0318), which points to the following routine:

+


+

       DD09    LSR $40         ; clear N flag

+

               BPL $DD0A       ; Note: $DD0A contains RTI.

+


+

       Operational diagram of BPL $DD0A:

+


+

         #  data  address  R/W  description

+

        --- ----  -------  ---  ---------------------------------

+

         1   10    $DD0B    R   fetch opcode

+

         2   11    $DD0C    R   fetch argument

+

         3   xx    $DD0D    R   fetch opcode, add argument to PCL

+

         4   40    $DD0A    R   fetch opcode, (fix PCH)

+


+

 With RTI:

+


+

       ; the fastest possible interrupt handler in the 6500 family

+

               ; preparations

+

               SEI

+

               LDA $01         ; disable ROM and enable I/O

+

               AND #$FD

+

               ORA #$05

+

               STA $01

+

               LDA #$7F

+

               STA $DD0D       ; disable CIA 2's all interrupt sources

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$40

+

               STA $DD0C       ; store RTI to $DD0C

+

               LDA #$0C

+

               STA $FFFA

+

               LDA #$DD

+

               STA $FFFB       ; change NMI vector to $DD0C

+

               LDA #$FF        ; Try changing this instruction's operand

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

               STA $DD04       ; set interrupt frequency to 1/65536 cycles

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

               LDA #$00        ; To see that the interrupts really occur,

+

               STA $D011       ; use something like this and see how

+

       LOOP    DEC $D020       ; changing the byte loaded to $DD05 from

+

               BNE LOOP        ; #$FF to #$0F changes the image.

+


       When an NMI occurs, the processor jumps to Kernal code, which

       jumps to ($0318), which points to the following routine:


-

       DD0C    RTI

-


+

       DD0C    RTI

+


       How on earth can this clear the interrupts? Remember, the

       processor always fetches two successive bytes for each

       instruction.

@@ -1576,13 +1576,13 @@

       you used when writing the RTI.


       Or you can combine the latter two methods:

-


-

       DD09    LSR $xx  ; xx is any appropriate BCD value 00-59.

-

               BPL $DCFC

-

       DCFC    RTI

-


+


+

       DD09    LSR $xx  ; xx is any appropriate BCD value 00-59.

+

               BPL $DCFC

+

       DCFC    RTI

+


       This example acknowledges interrupts to both CIAs.

-


+


 If you want to confuse the examiners of your code, you can use any

of these techniques. Although these examples use no undefined opcodes,

they do not necessarily run correctly on CMOS processors. However, the

diff --git a/help/CodeDataLogger.html b/help/CodeDataLogger.html index a351be3f..8af31fff 100644 --- a/help/CodeDataLogger.html +++ b/help/CodeDataLogger.html @@ -82,15 +82,15 @@

Furthermore, while the Code/Data Logger is running, the Hex Editor will color-code ROM bytes depending on whether they were logged as code or data:


For PRG ROM:

-

Dark-yellow - the byte is code

-

Blue - the byte is data

-

Cyan - the byte is PCM audio data

-

Green - the byte is both code and data

+

Dark-yellow - the byte is code

+

Blue - the byte is data

+

Cyan - the byte is PCM audio data

+

Green - the byte is both code and data


For CHR ROM:

-

Yellow - the byte was rendered

-

Light-blue - the byte was read programmatically

-

Light-green - the byte was both rendered and read programmatically

+

Yellow - the byte was rendered

+

Light-blue - the byte was read programmatically

+

Light-green - the byte was both rendered and read programmatically


The Code/Data Logger can also be used to generate a stripped NES ROM.

"Stripped" NES ROM is a ROM in which everything that was not logged by the Code/Data Logger is removed. It can be useful in many ways, for example, you can view the ROM in an external Hex Editor or a Tile Viewer, and you'll see only the parts that were used while playing. Furthermore, you could use it to create a demo ROM by only playing through the parts you would like others to see.

diff --git a/help/Debug.html b/help/Debug.html index a3ee9724..249818e2 100644 --- a/help/Debug.html +++ b/help/Debug.html @@ -56,33 +56,33 @@


Guides for the specific tools and settings under FCEUX's Debug menu.


-

Debugger

+

Debugger


A tool for looking at game instructions in assembly language. With experience,

one can use it to fix game patching errors, or find RAM and Game Genie codes.


-

PPU Viewer

+

PPU Viewer


A tool that displays the current PPU contents and related information. The PPU

viewer allows you to view the graphic squares that make up what's displayed.


-

Name Table Viewer

+

Name Table Viewer


A tool for displaying the current Name Table contents. Helps to isolate PPU

and tile information, which allows the debugger to be used to check PPU coding.


-

Hex Editor

+

Hex Editor


A tool for displaying a game's RAM contents and for memory poking. Also allows

for reading in the raw PPU data, copy/paste-ing RAM, and visually debugging RAM.


-

Trace Logger

+

Trace Logger


Captures assembly code instructions and outputs them to a file or the window. Very

useful for analyzing code, finding crash addresses, fixing transferred routines, and

for comparing routine function between a game and a persistently buggy NSF.


-

Code/Data Logger

+

Code/Data Logger


Allows you to extract the data used by a game. Make patch demos, find data

loaded by a game around a certain point, or just map out a single routine run.

diff --git a/help/Debugger.html b/help/Debugger.html index 1f5507c3..3e697c00 100644 --- a/help/Debugger.html +++ b/help/Debugger.html @@ -59,7 +59,7 @@

Debugger



-

Introduction

+

Introduction


The debugger is a tool for inspecting and manipulating machine instructions and their execution. The debugger window has several components:



-

Execution and CPU State

+

Execution and CPU State


Execution is controlled by the set of buttons at the top-middle of the window. These allow you to break (pause) execution and inspect the current state of the NES.


@@ -95,26 +95,26 @@


- @@ -130,7 +130,7 @@

To the right from the PPU section there's Cycles counter and Instructions counter that keep counting while the game is running. You can use the information for keeping statistics, for code profiling or writing PPU-synchronized code (e.g. raster effects). You can also make the debugger break automatically based on the counters values. The "Reset counters" button resets both counters to 0. You can also access the counters via Lua.



-

Disassembly

+

Disassembly


This large frame takes up the left side of the debugger window. It displays the current contents of memory accessible by the CPU with an automatic disassembly of that data into assembly instructions. The following memory ranges may contain useful data for inspection:

HINT: When entering the address manually, these convenient strings may be used instead of the hexadecimal memory address:

-

NES special addresses:

+

HINT: When entering the address manually, these convenient strings may be used instead of the hexadecimal memory address:

+

NES special addresses:

    -
  • NMI/VBL - non-maskable interrupt vector (at FFFA)
  • -
  • RST     - reset vector (at FFFC)
  • -
  • IRQ     - interrupt vector (at FFFE)
  • +
  • NMI/VBL - non-maskable interrupt vector (at FFFA)
  • +
  • RST     - reset vector (at FFFC)
  • +
  • IRQ     - interrupt vector (at FFFE)
-

FDS special addresses:

+

FDS special addresses:

    -
  • NMI1 - non-maskable interrupt vector (at DFF6)
  • -
  • NMI2 - non-maskable interrupt vector (at DFF8)
  • -
  • NMI3 - non-maskable interrupt vector (at DFFA)
  • -
  • RST  - reset vector (at DFFC)
  • -
  • IRQ  - interrupt vector (at DFFE)
  • +
  • NMI1 - non-maskable interrupt vector (at DFF6)
  • +
  • NMI2 - non-maskable interrupt vector (at DFF8)
  • +
  • NMI3 - non-maskable interrupt vector (at DFFA)
  • +
  • RST  - reset vector (at DFFC)
  • +
  • IRQ  - interrupt vector (at DFFE)
-

NSF special addresses:

+

NSF special addresses:

    -
  • LOAD - NSF LOAD address
  • -
  • INIT - NSF INIT address
  • -
  • PLAY - NSF PLAY address
  • +
  • LOAD - NSF LOAD address
  • +
  • INIT - NSF INIT address
  • +
  • PLAY - NSF PLAY address