diff --git a/help/6502CPU.html b/help/6502CPU.html index f8231737..1abf9f1f 100644 --- a/help/6502CPU.html +++ b/help/6502CPU.html @@ -52,50 +52,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.

@@ -120,45 +120,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.


@@ -333,9 +333,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.

@@ -344,15 +344,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.

@@ -377,7 +377,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

@@ -415,36 +415,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

@@ -457,23 +457,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

@@ -504,10 +504,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'

@@ -599,11 +599,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.

@@ -628,39 +628,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.

@@ -671,14 +671,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

@@ -691,45 +691,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.

@@ -752,13 +752,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

@@ -767,29 +767,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

@@ -950,617 +950,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.

@@ -1572,13 +1572,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/FAQGuides.html b/help/FAQGuides.html index 2c4d94b0..4142992a 100644 --- a/help/FAQGuides.html +++ b/help/FAQGuides.html @@ -52,22 +52,22 @@


Information regarding various concepts such as TAS, ROM Hacking, RAM Mapping.


-

Troubleshooting FAQ

+

Troubleshooting FAQ


A guide to common problems people experience, and what to do about them.



-

Tool Assisted Speedruns (TAS)

+

Tool Assisted Speedruns (TAS)


Information regarding Tool Assisted Speedruns and the TAS community.



-

ROM Hacking

+

ROM Hacking


Information regarding making ROM Hacks and the ROM Hacking community.



-

NES RAM Mapping

+

NES RAM Mapping


A guide to the layout of NES RAM, and how to interpret its contents.


diff --git a/help/LuaFunctionsList.html b/help/LuaFunctionsList.html index 4f0775fd..eb9bfe77 100644 --- a/help/LuaFunctionsList.html +++ b/help/LuaFunctionsList.html @@ -59,13 +59,13 @@


Emu library


-

emu.poweron()

-


-

Executes a power cycle.

-


-

emu.softreset()

-


-

Executes a (soft) reset.

+

emu.poweron()

+


+

Executes a power cycle.

+


+

emu.softreset()

+


+

Executes a (soft) reset.


emu.speedmode(string mode)


@@ -190,11 +190,13 @@


You can avoid getting LUA data by putting the data into a function, and feeding the function name to emu.registerbefore.


+


FCEU library


The FCEU library is the same as the emu library. It is left in for backwards compatibility. However, the emu library is preferred.


-

ROM Library

+


+

ROM Library


rom.readbyte(int address)

rom.readbyteunsigned(int address)

@@ -209,7 +211,8 @@


This includes the header! It's the same as opening the file in a hex-editor.


-

Memory Library

+


+

Memory Library


memory.readbyte(int address)

memory.readbyteunsigned(int address)

@@ -249,6 +252,8 @@


Registers a function to be called immediately whenever the given memory address range is written to.


+

address is the address in CPU address space (0x0000 - 0xFFFF).

+


size is the number of bytes to "watch". For example, if size is 100 and address is 0x0200, then you will register the function across all 100 bytes from 0x0200 to 0x0263. A write to any of those bytes will trigger the function. Having callbacks on a large range of memory addresses can be expensive, so try to use the smallest range that's necessary for whatever it is you're trying to do. If you don't specify any size then it defaults to 1.


The callback function will receive two arguments, (address, size) indicating what write operation triggered the callback. If you don't care about that extra information then you can ignore it and define your callback function to not take any arguments. The value that was written is NOT passed into the callback function, but you can easily use any of the memory.read functions to retrieve it.

@@ -263,9 +268,12 @@


Registers a function to be called immediately whenever the emulated system runs code located in the given memory address range.


-

Besides that, most of the information about memory.register applies to this function as well.

+

Since "address" is the address in CPU address space (0x0000 - 0xFFFF), this doesn't take ROM banking into account, so the callback will be called for any bank, and in some cases you'll have to check current bank in your callback function.


-

Joypad Library

+

The information about memory.register applies to this function as well.

+


+


+

Joypad Library


table joypad.get(int player)

table joypad.read(int player)

@@ -315,7 +323,7 @@

joypad.write left in for backwards compatibility with older versions of FCEU/FCEUX.



-

Zapper Library

+

Zapper Library


table zapper.read()


@@ -330,7 +338,7 @@

Note: The zapper is always controller 2 on the NES so there is no player argument to this function.



-

Input Library

+

Input Library


table input.get()

table input.read()

@@ -343,7 +351,8 @@


Requests input from the user using a multiple-option message box. See gui.popup for complete usage and returns.


-

Savestate Library

+


+

Savestate Library


object savestate.object(int slot = nil)


@@ -390,7 +399,7 @@

Returns the data associated with the given savestate (data that was earlier returned by a registered save callback) without actually loading the rest of that savestate or calling any callbacks. location should be a save slot number.



-

Movie Library

+

Movie Library


bool movie.active()


@@ -491,7 +500,8 @@


Returns the state of read-only. True if in playback mode, false if in record mode.


-

GUI Library

+


+

GUI Library


gui.pixel(int x, int y, type color)

gui.drawpixel(int x, int y, type color)

@@ -544,7 +554,7 @@


This function is provided so as to allow FCEUX to not carry a copy of the gd library itself. If you want raw RGB32 access, skip the first 11 bytes (header) and then read pixels as Alpha (always 0), Red, Green, Blue, left to right then top to bottom, range is 0-255 for all colors.


-

Warning: Storing screen shots in memory is not recommended. Memory usage will blow up pretty quick. One screen shot string eats around 230 KB of RAM.

+

Warning: Storing screen shots in memory is not recommended. Memory usage will blow up pretty quick. One screen shot string eats around 230 KB of RAM.


gui.gdoverlay([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

gui.image([int dx=0, int dy=0,] string str [, sx=0, sy=0, sw, sh] [, float alphamul=1.0])

@@ -590,7 +600,7 @@

Linux users might want to install xmessage to perform the work. Otherwise the dialog will appear on the shell and that's less noticeable.



-

Sound Library

+

Sound Library


table sound.get()


@@ -661,7 +671,7 @@

}



-

TAS Editor Library

+

TAS Editor Library


taseditor.registerauto(function func)

taseditor.registermanual(function func)

@@ -693,27 +703,27 @@


Bitwise Operations


-

All the following functions are left for backward compatibility, since LuaBitOp is embedded in FCEUX.

+

All the following functions are left for backward compatibility, since LuaBitOp is embedded in FCEUX.


-

int AND(int n1, int n2, ..., int nn)

-


+

int AND(int n1, int n2, ..., int nn)

+


Binary logical AND of all the given integers. This function compensates for Lua's lack of it.


-

int OR(int n1, int n2, ..., int nn)

+

int OR(int n1, int n2, ..., int nn)


Binary logical OR of all the given integers. This function compensates for Lua's lack of it.


-

int XOR(int n1, int n2, ..., int nn)

+

int XOR(int n1, int n2, ..., int nn)


Binary logical XOR of all the given integers. This function compensates for Lua's lack of it.


-

int BIT(int n1, int n2, ..., int nn)

+

int BIT(int n1, int n2, ..., int nn)


Returns an integer with the given bits turned on. Parameters should be smaller than 31.


-

Appendix

+

Appendix


-

On drawing

+

On drawing


A general warning about drawing is that it is always one frame behind unless you use gui.register. This is because you tell the emulator to paint something but it will actually paint it when generating the image for the next frame. So you see your painting, except it will be on the image of the next frame. You can prevent this with gui.register because it gives you a quick chance to paint before blitting.


@@ -721,7 +731,7 @@

--320x239, 8bit color (confirm?)

256x224, 8bit color (confirm?)


-

On colors

+

On colors


Colors can be of a few types.

Int: use the a formula to compose the color as a number (depends on color depth)

diff --git a/help/NESRAMMappingFindingValues.html b/help/NESRAMMappingFindingValues.html index 48d2b046..c37f2af2 100644 --- a/help/NESRAMMappingFindingValues.html +++ b/help/NESRAMMappingFindingValues.html @@ -228,7 +228,7 @@

These distinctions are easier to see in a visual example.  This is the enemy/player stats as they are mapped in the game Teenage Mutant Ninja Turtles.


Block 4

-

                           P  W1 W2 W3 E1 E2 E3 E4 E5 E6 E7 E8 X  X  X  X  

+

                           P  W1 W2 W3 E1 E2 E3 E4 E5 E6 E7 E8 X  X  X  X  

Sprite ID:        040x: 09 00 00 00 00 9E 9E 9E 9E 00 00 00 00 00 00 00

ID counter:       041x: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Timer/sp change:  042x: 02 00 00 00 00 03 03 03 03 00 00 00 00 00 00 00

diff --git a/help/NESSound.html b/help/NESSound.html index 91373b53..94440b07 100644 --- a/help/NESSound.html +++ b/help/NESSound.html @@ -255,18 +255,18 @@

************************

This section will describe the internal components making up each individual channel. Each component will then be described in full detail.


-

Device                                 Triangle Noise  Square

-

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

-

triangle step generator                        X

-

linear counter                                X

-

programmable timer                        X      X      X

-

length counter                                X      X      X

-

4-bit DAC                                        X      X      X

-

volume/envelope decay unit                         X      X

-

sweep unit                                                          X

-

duty cycle generator                                          X

-

wavelength converter                                 X

-

random number generator                                 X

+

Device                                 Triangle Noise  Square

+

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

+

triangle step generator                        X

+

linear counter                                X

+

programmable timer                        X      X      X

+

length counter                                X      X      X

+

4-bit DAC                                        X      X      X

+

volume/envelope decay unit                         X      X

+

sweep unit                                                          X

+

duty cycle generator                                          X

+

wavelength converter                                 X

+

random number generator                                 X



+-------------------------+

diff --git a/help/Palette.html b/help/Palette.html index 4971b143..b9c8493e 100644 --- a/help/Palette.html +++ b/help/Palette.html @@ -86,6 +86,9 @@

Restore to Default Palette

Restores the color palette to its default settings.


+

Force Grayscale

+

Applies simple Grayscale filter, no matter what palette is currently used.

+



NTSC Color Emulation


diff --git a/help/WhatsNew216.html b/help/WhatsNew216.html index a315aab5..1294bfc2 100644 --- a/help/WhatsNew216.html +++ b/help/WhatsNew216.html @@ -64,9 +64,9 @@
  • Fixed long savestate messages containing path
  • Soft reset and power switch messages
  • All onscreen messages are now logged to Message Log
  • -
  • Improved HUD text rendering wrapping
  • Fixed wrong default palette entry
  • Fixed bug when loading UNF games
  • +
  • Improved HUD text rendering wrapping
  • Display FPS option

  • @@ -87,6 +87,7 @@

    Movies


    TAS Editor

    @@ -180,16 +187,6 @@
  • Parse cheat files with non-ASCII characters properly

  • -

    GUI

    - -


    -


    -




    Created with the Personal Edition of HelpNDoc: Free Web Help generator

    diff --git a/help/css/hnd.css b/help/css/hnd.css index 8a473f1f..7ef14aa7 100644 --- a/help/css/hnd.css +++ b/help/css/hnd.css @@ -271,82 +271,85 @@ span.rvts51 color: #333399; } span.rvts52 -{ - font-size: 14pt; - font-family: 'Courier New', 'Courier', monospace; - font-weight: bold; -} -span.rvts53 { font-family: 'Courier New', 'Courier', monospace; color: #000080; } -span.rvts54 +span.rvts53 { font-size: 16pt; font-family: 'Courier New', 'Courier', monospace; font-weight: bold; } -span.rvts55 +span.rvts54 { font-size: 11pt; font-family: 'Courier New', 'Courier', monospace; font-weight: bold; } +span.rvts55 +{ + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} span.rvts56 { font-family: 'Courier New', 'Courier', monospace; - font-weight: bold; } span.rvts57 -{ - font-family: 'Courier New', 'Courier', monospace; -} -span.rvts58 { font-size: 12pt; font-family: 'Courier New', 'Courier', monospace; color: #000080; } -a.rvts59, span.rvts59 +a.rvts58, span.rvts58 { font-family: 'Courier New', 'Courier', monospace; color: #0000ff; text-decoration: underline; } -a.rvts59:hover { color: #0000ff; } -a.rvts60, span.rvts60 +a.rvts58:hover { color: #0000ff; } +span.rvts59 +{ + font-size: 14pt; + font-weight: bold; +} +span.rvts60 /* Font Style */ +{ + font-size: 14pt; +} +a.rvts61, span.rvts61 { font-size: 12pt; color: #0000ff; text-decoration: underline; } -a.rvts60:hover { color: #0000ff; } -span.rvts61 +a.rvts61:hover { color: #0000ff; } +span.rvts62 { font-family: 'Lucida Console', 'Monaco', monospace; text-decoration: underline; } -span.rvts62 -{ - font-weight: bold; - text-decoration: underline; -} span.rvts63 { - font-size: 11pt; + font-weight: bold; text-decoration: underline; } span.rvts64 { - font-size: 5pt; + font-size: 11pt; + text-decoration: underline; } span.rvts65 { font-size: 5pt; - font-weight: bold; } span.rvts66 +{ + font-size: 5pt; + font-weight: bold; +} +span.rvts67 { font-size: 11pt; font-weight: bold; @@ -377,3 +380,6 @@ p,ul,ol /* Paragraph Style */ .rvps3 /* Paragraph Style */ { } +.rvps4 /* Paragraph Style */ +{ +} diff --git a/help/fceux.html b/help/fceux.html index c648d97f..a57ca13a 100644 --- a/help/fceux.html +++ b/help/fceux.html @@ -11,7 +11,7 @@ if (top.location.href.lastIndexOf("?") > 0) sTopic = top.location.href.substring(top.location.href.lastIndexOf("?") + 1, top.location.href.length); if (sTopic == "") sTopic = "Introduction.html"; - document.write(''); + document.write(''); document.write(''); document.write(''); document.write(''); @@ -20,7 +20,7 @@