From f1095dc2c3d89695d6a7a1f0e94f2e6eae31952a Mon Sep 17 00:00:00 2001 From: ansstuff Date: Sun, 22 Sep 2013 18:54:01 +0000 Subject: [PATCH] updated docs [[Split portion of a mixed commit.]] --- help/6502CPU.html | 1738 +++++++++++----------- help/AutoFireConfigurations.html | 2 +- help/CodeDataLogger.html | 41 +- help/CustomizingthroughtheConfigFil.html | 21 +- help/Debugger.html | 162 +- help/ExternalInput.html | 74 - help/FAQGuides.html | 8 +- help/GUI.html | 2 +- help/HexEditor.html | 20 +- help/LuaFunctionsList.html | 362 ++--- help/LuaGettingStarted.html | 12 +- help/LuaPerks.html | 24 +- help/LuaScripting.html | 10 +- help/NESRAMMappingFindingValues.html | 2 +- help/NESScrolling2.html | 2 + help/NESSound.html | 24 +- help/NLFilesFormat.html | 117 ++ help/PPUViewer.html | 22 +- help/TextHooker.html | 2 +- help/ToggleSwitchesHideMenuetc.html | 2 +- help/Tools2.html | 9 +- help/TraceLogger.html | 18 +- help/Troubleshooting.html | 14 +- help/Video.html | 2 +- help/WhatsNew222.html | 71 +- help/css/hnd.css | 98 +- help/fm2.html | 38 +- help/js/searchdata.js | 2 +- help/toc.html | 20 +- 29 files changed, 1497 insertions(+), 1422 deletions(-) delete mode 100644 help/ExternalInput.html create mode 100644 help/NLFilesFormat.html diff --git a/help/6502CPU.html b/help/6502CPU.html index c8e3dd78..424257cd 100644 --- a/help/6502CPU.html +++ b/help/6502CPU.html @@ -56,50 +56,50 @@

-

#

-

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

-

#

-

# This file is part of Commodore 64 emulator

-

#      and Program Development System.

-

#

-

# See README for copyright notice

-

#

-

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

-

#

-

#

-

# Written by

-

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

-

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

-

#

-

#

-

# $Log: 6502_cpu.txt,v $

-

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

-

# no message

-

#

-

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

-

# updates

-

#

-

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

-

# Patchlevel 2

-

#

-

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

-

# 65xx Register descriptions added

-

#

-

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

-

#

-

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

-

# X64 version 0.2 PL 1

-

#

-

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

-

#

-

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

-

#  X64 version 0.2 PL 0

-

#

-

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

-

# *** empty log message ***

-

#

-

#

-


+

#

+

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

+

#

+

# This file is part of Commodore 64 emulator

+

#      and Program Development System.

+

#

+

# See README for copyright notice

+

#

+

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

+

#

+

#

+

# Written by

+

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

+

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

+

#

+

#

+

# $Log: 6502_cpu.txt,v $

+

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

+

# no message

+

#

+

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

+

# updates

+

#

+

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

+

# Patchlevel 2

+

#

+

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

+

# 65xx Register descriptions added

+

#

+

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

+

#

+

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

+

# X64 version 0.2 PL 1

+

#

+

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

+

#

+

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

+

#  X64 version 0.2 PL 0

+

#

+

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

+

# *** empty log message ***

+

#

+

#

+


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

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

      which extracts them all at once.

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


6510 Instructions by Addressing Modes


-

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

-

set  00      20      40      60      80      a0      c0      e0      mode

-


-

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

-

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

-

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

-

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

-

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

-

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

-

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

-

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

-


-

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

-

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

-

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

-

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

-

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

-

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

-

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

-

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

-


-

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

-

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

-

+12   t       t       t       t       t       t       t       t         ?

-

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

-

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

-

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

-

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

-

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

-


-

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

-

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

-

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

-

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

-

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

-

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

-

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

-

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

-


+

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

+

set  00      20      40      60      80      a0      c0      e0      mode

+


+

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

+

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

+

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

+

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

+

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

+

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

+

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

+

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

+


+

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

+

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

+

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

+

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

+

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

+

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

+

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

+

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

+


+

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

+

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

+

+12   t       t       t       t       t       t       t       t         ?

+

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

+

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

+

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

+

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

+

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

+


+

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

+

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

+

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

+

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

+

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

+

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

+

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

+

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

+


       ROR intruction is available on MC650x microprocessors after

       June, 1976.


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


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


-

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

-

                       same as

-

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

+

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

+

                       same as

+

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


                       In real 6510/8502 the internal parameter #$11

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

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

                       of the instruction.  The value probably depends

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


-

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

-

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

+

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

+

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


                       TXA and TAX have to be responsible for these.


-

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

-

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

-

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

-

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

+

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

+

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

+

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

+

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


                       Note: The value to be stored is copied also

                       to ADDR_HI if page boundary is crossed.

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

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

simultaneously into both A and X.


-

       $6B  ARR

+

       $6B  ARR


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

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

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

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

illustrates the ARR operation in Decimal mode:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          t,  /* temporary value */

-

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

-


-

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

-


-

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

-

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

-


-

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

-

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

-

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

-


-

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

-

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

-


-

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

-

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

-


-

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

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

          t,  /* temporary value */

+

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

+


+

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

+


+

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

+

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

+


+

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

+

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

+

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

+


+

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

+

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

+


+

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

+

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

+


+

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

+


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

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

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

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


Proof:


-

begin 644 vsbx

-

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

-

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

-

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

-

`

-

end

-


-

and

-


-

begin 644 sbx

-

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

-

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

-

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

-

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

-

`

-

end

-


+

begin 644 vsbx

+

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

+

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

+

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

+

`

+

end

+


+

and

+


+

begin 644 sbx

+

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

+

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

+

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

+

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

+

`

+

end

+


These test programs show if your machine is compatible with ours

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

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

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

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

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


-

begin 644 sbx-c100

-

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

-

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

-

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

+

begin 644 sbx-c100

+

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

+

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

+

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


Other undocumented instructions usually cause two preceding opcodes

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

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


Register selection for load and store


-

  bit1 bit0     A  X  Y

-

   0    0             x

-

   0    1          x

-

   1    0       x

-

   1    1       x  x

+

  bit1 bit0     A  X  Y

+

   0    0             x

+

   0    1          x

+

   1    0       x

+

   1    1       x  x


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

~(bit1|bit0) enables Y.

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

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

the instruction:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-

                                                like in Binary mode. */

-


-

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

-

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

-


-

       N = (AH & 8 != 0);

-

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

-


-

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

-


-

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

-


-

       C = (AH > 15);

-

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

+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+

                                                like in Binary mode. */

+


+

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

+

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

+


+

       N = (AH & 8 != 0);

+

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

+


+

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

+


+

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

+


+

       C = (AH > 15);

+

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


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

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

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

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

      If everything goes well, it ends in RTS.


-

begin 600 dadc

-

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

-

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

-

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

-

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

-

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

-


-

end

+

begin 600 dadc

+

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

+

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

+

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

+

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

+

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

+


+

end


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

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

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


Proof:


-

begin 600 dsbc-cmp-flags

-

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

-

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

-

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

-


-

end

+

begin 600 dsbc-cmp-flags

+

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

+

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

+

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

+


+

end


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

is the result-fixup:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-

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

-

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

-

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

-


-

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

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+

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

+

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

+

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

+


+

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

+


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

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

phase.

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

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

contains the 6502 version of the pseudo code example above.


-

begin 600 dsbc

-

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

-

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

-

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

-

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

-


-

end

+

begin 600 dsbc

+

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

+

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

+

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

+

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

+


+

end


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

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

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

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

affected by the D flag.


-

begin 644 droradc

-

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

-

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

-

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

-

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

-

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

-

`

-

end

-


-

begin 644 dincsbc

-

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

-

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

-

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

-

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

-

`

-

end

-


-

begin 644 dincsbc-deccmp

-

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

-

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

-

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

-

`

-

end

+

begin 644 droradc

+

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

+

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

+

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

+

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

+

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

+

`

+

end

+


+

begin 644 dincsbc

+

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

+

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

+

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

+

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

+

`

+

end

+


+

begin 644 dincsbc-deccmp

+

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

+

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

+

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

+

`

+

end



6510 features

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


 Instructions accessing the stack


-

    BRK

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

                      increment PC

-

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

-

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

-

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

-

       6   $FFFE   R  fetch PCL

-

       7   $FFFF   R  fetch PCH

-


-

    RTI

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

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

-

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

-

       6  $0100,S  R  pull PCH from stack

-


-

    RTS

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

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

-

       5  $0100,S  R  pull PCH from stack

-

       6    PC     R  increment PC

-


-

    PHA, PHP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

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

-


-

    PLA, PLP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull register from stack

-


-

    JSR

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

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

-

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

-

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

-

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

-

                      byte to PCH

-


-

 Accumulator or implied addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-


-

 Immediate addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch value, increment PC

-


-

 Absolute addressing

-


-

    JMP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

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

-

                      byte to PCH

-


-

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

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-


-

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

-

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

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-

       5  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       6  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  W  write register to effective address

-


-

 Zero page addressing

-


-

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

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-


-

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

-

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

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-

       4  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       5  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  W  write register to effective address

-


-

 Zero page indexed addressing

-


-

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

-

                       LAX, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+I* R  read from effective address

-


-

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

-


-

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

-

               i.e. page boundary crossings are not handled.

-


-

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

-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+X* R  read from effective address

-

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

-

                        and do the operation on it

-

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

-


-

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

-

              i.e. page boundary crossings are not handled.

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+I* W  write to effective address

-


-

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

-


-

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

-

               i.e. page boundary crossings are not handled.

-


-

 Absolute indexed addressing

-


-

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

-

                       LAX, LAE, SHS, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

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

-


-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

             + This cycle will be executed only if the effective address

-

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

-


-

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

-

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

-


-

       #   address  R/W description

-

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

-

       1    PC       R  fetch opcode, increment PC

-

       2    PC       R  fetch low byte of address, increment PC

-

       3    PC       R  fetch high byte of address,

-

                        add index register X to low address byte,

-

                        increment PC

-

       4  address+X* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+X  R  re-read from effective address

-

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

-

                        and do the operation on it

-

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

-


-

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

-

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

-


-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+I  W  write to effective address

-


-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-

               the processor cannot undo a write to an invalid

-

               address, it always reads from the address first.

-


-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch operand, increment PC

-

       3     PC      R  Fetch opcode of next instruction,

-

                        If branch is taken, add operand to PCL.

-

                        Otherwise increment PC.

-

       4+    PC*     R  Fetch opcode of next instruction.

-

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

-

       5!    PC      R  Fetch opcode of next instruction,

-

                        increment PC.

-


-

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

-

             this diagram for illustration purposes. When determining

-

             real execution times, remember to subtract the last

-

             cycle.

-


-

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

-

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

-


-

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

-


-

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

-

               executed.

-


-

 Indexed indirect addressing

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-


-

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

-

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

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-

       7    address    W  write the value back to effective address,

-

                          and do the operation on it

-

       8    address    W  write the new value to effective address

-


-

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

-

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

-


-

    Write instructions (STA, SAX)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    W  write to effective address

-


-

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

-

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

-


-

 Indirect indexed addressing

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6+  address+Y   R  read from effective address

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

             + This cycle will be executed only if the effective address

-

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

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   R  read from effective address

-

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

-

                          and do the operation on it

-

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

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

    Write instructions (STA, SHA)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   W  write to effective address

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

 Absolute indirect addressing (JMP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch pointer address low, increment PC

-

       3     PC      R  fetch pointer address high, increment PC

-

       4   pointer   R  fetch low address to latch

-

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

-


-

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

-

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

-


-

               How Real Programmers Acknowledge Interrupts

-


-

 With RMW instructions:

-


-

       ; beginning of combined raster/timer interrupt routine

-

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

-

       BCS raster      ; jump if VIC caused an interrupt

-

       ...             ; timer interrupt routine

-


-

       Operational diagram of LSR $D019:

-


-

         #  data  address  R/W

-

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

-

         1   4E     PC      R   fetch opcode

-

         2   19    PC+1     R   fetch address low

-

         3   D0    PC+2     R   fetch address high

-

         4   xx    $D019    R   read memory

-

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

-

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

-


-

       The 5th cycle acknowledges the interrupt by writing the same

-

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

-

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

-

       other interrupts.)

-


-

 With indexed addressing:

-


-

       ; acknowledge interrupts to both CIAs

-

       LDX #$10

-

       LDA $DCFD,X

-


-

       Operational diagram of LDA $DCFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   BD     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

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

-

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

-

         5   yy    $DD0D    R   read from right address

-


-

       ; acknowledge interrupts to CIA 2

-

       LDX #$10

-

       STA $DDFD,X

-


-

       Operational diagram of STA $DDFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   9D     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

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

-

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

-

         5   ac    $DE0D    W   write to right address

-


-

 With branch instructions:

-


-

       ; acknowledge interrupts to CIA 2

-

               LDA #$00  ; clear N flag

-

               JMP $DD0A

-

       DD0A    BPL $DC9D ; branch

-

       DC9D    BRK       ; return

-


-

       You need the following preparations to initialize the CIA registers:

-


-

               LDA #$91  ; argument of BPL

-

               STA $DD0B

-

               LDA #$10  ; BPL

-

               STA $DD0A

-

               STA $DD08 ; load the ToD values from the latches

-

               LDA $DD0B ; freeze the ToD display

-

               LDA #$7F

-

               STA $DC0D ; assure that $DC0D is $00

-


-

       Operational diagram of BPL $DC9D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0A    R   fetch opcode

-

         2   91    $DD0B    R   fetch argument

-

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

-

         4   yy    $DD9D    R   fetch opcode, fix PCH

-

       ( 5   00    $DC9D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 1

-

               LSR       ; clear N flag

-

               JMP $DCFA

-

       DCFA    BPL $DD0D

-

       DD0D    BRK

-


-

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

-

       ; Interrupt Control Register of CIA 2 first.

-


-

       Operational diagram of BPL $DD0D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DCFA    R   fetch opcode

-

         2   11    $DCFB    R   fetch argument

-

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

-

         4   yy    $DC0D    R   fetch opcode, fix PCH

-

       ( 5   00    $DD0D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 2 automagically

-

               ; preparations

-

               LDA #$7F

-

               STA $DD0D       ; disable all interrupt sources of CIA2

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$FD

-

               STA $DD0C       ; parameter of BPL

-

               LDA #$10

-

               STA $DD0B       ; BPL

-

               LDA #$40

-

               STA $DD0A       ; RTI/parameter of LSR

-

               LDA #$46

-

               STA $DD09       ; LSR

-

               STA $DD08       ; load the ToD values from the latches

-

               LDA $DD0B       ; freeze the ToD display

-

               LDA #$09

-

               STA $0318

-

               LDA #$DD

-

               STA $0319       ; change NMI vector to $DD09

-

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

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

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

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

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

-

               STA $D011       ; use something like this and see how

-

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

-

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

-


-

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

-

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

-


-

       DD09    LSR $40         ; clear N flag

-

               BPL $DD0A       ; Note: $DD0A contains RTI.

-


-

       Operational diagram of BPL $DD0A:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0B    R   fetch opcode

-

         2   11    $DD0C    R   fetch argument

-

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

-

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

-


-

 With RTI:

-


-

       ; the fastest possible interrupt handler in the 6500 family

-

               ; preparations

-

               SEI

-

               LDA $01         ; disable ROM and enable I/O

-

               AND #$FD

-

               ORA #$05

-

               STA $01

-

               LDA #$7F

-

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

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$40

-

               STA $DD0C       ; store RTI to $DD0C

-

               LDA #$0C

-

               STA $FFFA

-

               LDA #$DD

-

               STA $FFFB       ; change NMI vector to $DD0C

-

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

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

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

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

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

-

               STA $D011       ; use something like this and see how

-

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

-

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

-


+

    BRK

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

                      increment PC

+

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

+

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

+

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

+

       6   $FFFE   R  fetch PCL

+

       7   $FFFF   R  fetch PCH

+


+

    RTI

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

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

+

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

+

       6  $0100,S  R  pull PCH from stack

+


+

    RTS

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

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

+

       5  $0100,S  R  pull PCH from stack

+

       6    PC     R  increment PC

+


+

    PHA, PHP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

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

+


+

    PLA, PLP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

       4  $0100,S  R  pull register from stack

+


+

    JSR

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

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

+

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

+

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

+

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

+

                      byte to PCH

+


+

 Accumulator or implied addressing

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+


+

 Immediate addressing

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch value, increment PC

+


+

 Absolute addressing

+


+

    JMP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

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

+

                      byte to PCH

+


+

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

+

                       LAX, NOP)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+


+

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

+

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

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+

       5  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       6  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  W  write register to effective address

+


+

 Zero page addressing

+


+

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

+

                       LAX, NOP)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+


+

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

+

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

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+

       4  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       5  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  W  write register to effective address

+


+

 Zero page indexed addressing

+


+

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

+

                       LAX, NOP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+I* R  read from effective address

+


+

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

+


+

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

+

               i.e. page boundary crossings are not handled.

+


+

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

+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+X* R  read from effective address

+

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

+

                        and do the operation on it

+

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

+


+

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

+

              i.e. page boundary crossings are not handled.

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+I* W  write to effective address

+


+

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

+


+

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

+

               i.e. page boundary crossings are not handled.

+


+

 Absolute indexed addressing

+


+

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

+

                       LAX, LAE, SHS, NOP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

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

+


+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

             + This cycle will be executed only if the effective address

+

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

+


+

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

+

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

+


+

       #   address  R/W description

+

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

+

       1    PC       R  fetch opcode, increment PC

+

       2    PC       R  fetch low byte of address, increment PC

+

       3    PC       R  fetch high byte of address,

+

                        add index register X to low address byte,

+

                        increment PC

+

       4  address+X* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+X  R  re-read from effective address

+

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

+

                        and do the operation on it

+

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

+


+

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

+

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

+


+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+I  W  write to effective address

+


+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+

               the processor cannot undo a write to an invalid

+

               address, it always reads from the address first.

+


+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch operand, increment PC

+

       3     PC      R  Fetch opcode of next instruction,

+

                        If branch is taken, add operand to PCL.

+

                        Otherwise increment PC.

+

       4+    PC*     R  Fetch opcode of next instruction.

+

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

+

       5!    PC      R  Fetch opcode of next instruction,

+

                        increment PC.

+


+

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

+

             this diagram for illustration purposes. When determining

+

             real execution times, remember to subtract the last

+

             cycle.

+


+

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

+

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

+


+

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

+


+

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

+

               executed.

+


+

 Indexed indirect addressing

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+


+

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

+

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

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+

       7    address    W  write the value back to effective address,

+

                          and do the operation on it

+

       8    address    W  write the new value to effective address

+


+

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

+

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

+


+

    Write instructions (STA, SAX)

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    W  write to effective address

+


+

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

+

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

+


+

 Indirect indexed addressing

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6+  address+Y   R  read from effective address

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

             + This cycle will be executed only if the effective address

+

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

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   R  read from effective address

+

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

+

                          and do the operation on it

+

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

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

    Write instructions (STA, SHA)

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   W  write to effective address

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

 Absolute indirect addressing (JMP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch pointer address low, increment PC

+

       3     PC      R  fetch pointer address high, increment PC

+

       4   pointer   R  fetch low address to latch

+

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

+


+

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

+

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

+


+

               How Real Programmers Acknowledge Interrupts

+


+

 With RMW instructions:

+


+

       ; beginning of combined raster/timer interrupt routine

+

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

+

       BCS raster      ; jump if VIC caused an interrupt

+

       ...             ; timer interrupt routine

+


+

       Operational diagram of LSR $D019:

+


+

         #  data  address  R/W

+

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

+

         1   4E     PC      R   fetch opcode

+

         2   19    PC+1     R   fetch address low

+

         3   D0    PC+2     R   fetch address high

+

         4   xx    $D019    R   read memory

+

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

+

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

+


+

       The 5th cycle acknowledges the interrupt by writing the same

+

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

+

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

+

       other interrupts.)

+


+

 With indexed addressing:

+


+

       ; acknowledge interrupts to both CIAs

+

       LDX #$10

+

       LDA $DCFD,X

+


+

       Operational diagram of LDA $DCFD,X:

+


+

         #  data  address  R/W  description

+

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

+

         1   BD     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

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

+

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

+

         5   yy    $DD0D    R   read from right address

+


+

       ; acknowledge interrupts to CIA 2

+

       LDX #$10

+

       STA $DDFD,X

+


+

       Operational diagram of STA $DDFD,X:

+


+

         #  data  address  R/W  description

+

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

+

         1   9D     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

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

+

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

+

         5   ac    $DE0D    W   write to right address

+


+

 With branch instructions:

+


+

       ; acknowledge interrupts to CIA 2

+

               LDA #$00  ; clear N flag

+

               JMP $DD0A

+

       DD0A    BPL $DC9D ; branch

+

       DC9D    BRK       ; return

+


+

       You need the following preparations to initialize the CIA registers:

+


+

               LDA #$91  ; argument of BPL

+

               STA $DD0B

+

               LDA #$10  ; BPL

+

               STA $DD0A

+

               STA $DD08 ; load the ToD values from the latches

+

               LDA $DD0B ; freeze the ToD display

+

               LDA #$7F

+

               STA $DC0D ; assure that $DC0D is $00

+


+

       Operational diagram of BPL $DC9D:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DD0A    R   fetch opcode

+

         2   91    $DD0B    R   fetch argument

+

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

+

         4   yy    $DD9D    R   fetch opcode, fix PCH

+

       ( 5   00    $DC9D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 1

+

               LSR       ; clear N flag

+

               JMP $DCFA

+

       DCFA    BPL $DD0D

+

       DD0D    BRK

+


+

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

+

       ; Interrupt Control Register of CIA 2 first.

+


+

       Operational diagram of BPL $DD0D:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DCFA    R   fetch opcode

+

         2   11    $DCFB    R   fetch argument

+

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

+

         4   yy    $DC0D    R   fetch opcode, fix PCH

+

       ( 5   00    $DD0D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 2 automagically

+

               ; preparations

+

               LDA #$7F

+

               STA $DD0D       ; disable all interrupt sources of CIA2

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$FD

+

               STA $DD0C       ; parameter of BPL

+

               LDA #$10

+

               STA $DD0B       ; BPL

+

               LDA #$40

+

               STA $DD0A       ; RTI/parameter of LSR

+

               LDA #$46

+

               STA $DD09       ; LSR

+

               STA $DD08       ; load the ToD values from the latches

+

               LDA $DD0B       ; freeze the ToD display

+

               LDA #$09

+

               STA $0318

+

               LDA #$DD

+

               STA $0319       ; change NMI vector to $DD09

+

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

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

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

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

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

+

               STA $D011       ; use something like this and see how

+

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

+

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

+


+

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

+

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

+


+

       DD09    LSR $40         ; clear N flag

+

               BPL $DD0A       ; Note: $DD0A contains RTI.

+


+

       Operational diagram of BPL $DD0A:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DD0B    R   fetch opcode

+

         2   11    $DD0C    R   fetch argument

+

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

+

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

+


+

 With RTI:

+


+

       ; the fastest possible interrupt handler in the 6500 family

+

               ; preparations

+

               SEI

+

               LDA $01         ; disable ROM and enable I/O

+

               AND #$FD

+

               ORA #$05

+

               STA $01

+

               LDA #$7F

+

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

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$40

+

               STA $DD0C       ; store RTI to $DD0C

+

               LDA #$0C

+

               STA $FFFA

+

               LDA #$DD

+

               STA $FFFB       ; change NMI vector to $DD0C

+

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

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

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

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

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

+

               STA $D011       ; use something like this and see how

+

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

+

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

+


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

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


-

       DD0C    RTI

-


+

       DD0C    RTI

+


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

       processor always fetches two successive bytes for each

       instruction.

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

       you used when writing the RTI.


       Or you can combine the latter two methods:

-


-

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

-

               BPL $DCFC

-

       DCFC    RTI

-


+


+

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

+

               BPL $DCFC

+

       DCFC    RTI

+


       This example acknowledges interrupts to both CIAs.

-


+


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

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

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

diff --git a/help/AutoFireConfigurations.html b/help/AutoFireConfigurations.html index 16c16f68..9d563599 100644 --- a/help/AutoFireConfigurations.html +++ b/help/AutoFireConfigurations.html @@ -48,7 +48,7 @@ Previous - Next + Next
diff --git a/help/CodeDataLogger.html b/help/CodeDataLogger.html index d653cbb6..fbe3242e 100644 --- a/help/CodeDataLogger.html +++ b/help/CodeDataLogger.html @@ -61,35 +61,36 @@


Introduction


-

The Code/Data Logger makes it much easier to reverse-engineer NES ROMs. The basic idea behind it is that a normal NES disassembler cannot distinguish between code (which is executed) and data (which is read). The Code/Data logger keeps track of what is executed and what is read while the game is played, and then you can save this information into a .cdl file, which is essentially a mask that tells which bytes in the ROM are code and which are data. The file can be used in conjunction with a suitable disassembler to disassemble only the actual game code, resulting in a much cleaner source code, with code and data properly separated.

+

The Code/Data Logger makes it much easier to reverse-engineer NES ROMs. The basic idea behind it is that a normal NES disassembler cannot distinguish between code (which is executed) and data (which is read). The Code/Data Logger keeps track of what is executed and what is read while the game is played, and then you can save this information into a .cdl file, which is essentially a mask that tells which bytes in the ROM are code and which are data. The file can be used in conjunction with a suitable disassembler to disassemble only the actual game code, resulting in a much cleaner source code where code and data are properly separated.


Using the Code/Data Logger


-

The Code/Data Logger keeps track of every byte in the ROM and records whether it's code (is executed) or data (is read). You can combine this logging feature with other tools to make them much more powerful:

+

The Code/Data Logger keeps track of every byte in the ROM and records whether it's code (is executed) or data (is read).

+

You can combine this logging feature with other tools to make them much more powerful:


-

See, it is very useful for finding specific code and data by using it with the Trace Logger.

-

It also makes debugging work more visual, since you can always see which lines of the disassembled code were executed and which weren't.

+

See, it is very useful for finding certain types of data or code branches. It also makes debugging work more visual, since you can always see which lines of the disassembled code were executed and which weren't.


-

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

+

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


For PRG ROM:

-

Dark-yellow - the byte is code

-

Blue - the byte is data

-

Cyan - the byte is PCM audio data

-

Green - the byte is both code and data

+

Dark-yellow - the byte is code

+

Blue - the byte is data

+

Cyan - the byte is PCM audio data

+

Green - the byte is both code and data


For CHR ROM:

-

Yellow - the byte was rendered

-

Light-blue - the byte was read programmatically

-

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

+

Yellow - the byte was rendered

+

Light-blue - the byte was read programmatically

+

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


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

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

@@ -102,8 +103,7 @@


Alternatively, you can save Unused Data (a ROM which is the opposite to the Stripped ROM). For example, you can play through the game, then save Unused Data ROM and watch it in a Tile Viewer to find unused graphics (possibly stumble upon secrets and easter eggs).


-

Some notes:

-

When you "Load" another .cdl file, it does not clear the current log; instead, it combines it with the information in the file. This can be useful if you're trying to obtain a complete log of certain game, as multiple people can play through the game and keep code/data logs, and then the results can be combined. But if you would like to actually clear the code/data log, press the "Reset Log" button.

+

Note: When you "Load" another .cdl file, it does not clear the current log; instead, it combines ("arithmetical OR") it with the information in the file. This can be useful if you're trying to obtain a complete log of certain game, as multiple people can play through the game and keep own code/data logs, and then the results can be combined into an all-encompassing log. But if you would like to actually clear the code/data log, press the "Reset Log" button.




@@ -172,12 +172,13 @@

               (e.g. Argus_(J).nes checks if the bankswitching works by reading the same byte of CHR data before and after switching)

       x = unused.


-




+


CDL files make possible a number of things never done before. First, a PCM data ripper could be created that scans for data that has the 'P' bit set, in order to find/rip/play every PCM sample in a ROM. Also, it is possible for someone to make a more intelligent ROM corruptor that only corrupts data (by checking the 'D' bit). In any case, the Code/Data Logger opens many new possibilities for discovering useful things in games. Another interesting possibility would be to use the Code/Data Logger on an NSF file to create a stripped NSF. Such an NSF would contain nothing but the relevant subroutines and data required by each tune played; this would be helpful to NSF rippers by removing irrelevant information. Thus, an NSF ripper could create a stripped NSF by listening to each track while the Code/Data Logger operates on it, and then saving the stripped NSF. It should be noted that this capability, though tested and working on private builds, is detrimental to the process of fixing broken NSF files. For this reason, data logging is allowed for NSF files, but stripping NSF files of unused data is disabled.


-

The Code/Data Logger becomes the most useful when you need to restore a full source code of a game using e.g. IDA or another disassembler. There you can write a custom IDC script that uses a CDL file and calls MakeCode()/MakeData() functions to help the disassembler distinguish code from data. Making full and working/recompileable disassembly becomes really easy this way.

+

The Code/Data Logger becomes the most useful when you need to restore a full source code of a game using e.g. IDA or another disassembler. There you can write a custom IDC script that uses a CDL file and calls MakeCode()/MakeData() functions to help the disassembler distinguish code from data. Making full and working/reassemblable disassembly becomes really easy this way.

+





diff --git a/help/CustomizingthroughtheConfigFil.html b/help/CustomizingthroughtheConfigFil.html index b5ea3f5f..dfe2ad86 100644 --- a/help/CustomizingthroughtheConfigFil.html +++ b/help/CustomizingthroughtheConfigFil.html @@ -58,8 +58,8 @@

Customizing through the Config File


-

There are some options that can only be done by directly editing the config (fceux.cfg) file.  All of those options are documented here.


+

There are some options that can only be done by directly editing the config (fceux.cfg) file.  All of those options are documented here.

The .cfg file is a text file and can be opened by any text editor (just as wordpad).



@@ -69,12 +69,26 @@


When you disable the backgrounds (Config > Display > Graphics: GB), the default color is black.  You can change that color by modifying this value.  By default it is 255 (black).


+


+

Debugger

+


+

debuggerFontSize 15

+


+

This value determines the size of the "Courier" font used by Debugger and Trace Logger. By default it is 15.

+


+


Hex Editor


+

hexeditorFontSize 15

+


+

This value determines the size of the "Courier" font used by Hex Editor. By default it is 15.

+


+


HexRowHeightBorder 0


This value determines the number of pixels between each row of values in the Hex Editor.  By default it is 0.


+


HexBackColorR 255

HexBackColorG 255

HexBackColorB 255

@@ -87,7 +101,10 @@

HexFreezeColorG 0

HexFreezeColorB 255


-

These values allows are the Hex Editor color scheme values (RGB).  The background color is 255,255,255 (white) by default.  The foreground color (text) is 0,0,0 (black) by default.  When an address is frozen it is 0,0,255 (blue) by default.

+

These values allows are the Hex Editor color scheme values (RGB).  The background color is 255,255,255 (white) by default.  The foreground color (text) is 0,0,0 (black) by default. When an address is frozen it is 0,0,255 (blue) by default.

+


+


+



Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents

diff --git a/help/Debugger.html b/help/Debugger.html index e27bbbc6..082bde98 100644 --- a/help/Debugger.html +++ b/help/Debugger.html @@ -64,22 +64,22 @@

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



Execution and CPU State


-

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

+

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


-

When an NES ROM is opened, it will be normally be running. Most of the debugger window does not update while the game is running. To begin debugging you may click one of the buttons that will break (pause) execution, such as "Step Into", or add a breakpoint.

+

When an NES ROM is opened, it will be normally be running right away (unless you manually pause the emulator before loading). Most of the debugger window does not update while the game is running. To begin debugging you may click one of the buttons that will break (pause) execution, such as "Step Into".



-

The Pause hotkey will break execution or resume it. The Frame Advance hotkey will run the emulator for one frame then break.

+

The Pause hotkey will break execution or resume it. The Frame Advance hotkey will run the emulator for one frame and then break.


-

When execution is paused, the disassembly view will begin with the memory at the current program counter location (PC) at the top of the window. You can scroll the disassembly up or down to observe the code. Then you can click "Seek PC" to return to the program counter at any time.

+

When execution is paused, the disassembly view will begin with the memory near the current program counter location (PC). The ">" mark shows the line which will be executed next. You can scroll the disassembly up or down (using scrollbar or mouse wheel) to observe the code. Then you can click "Seek PC" to return to the program counter at any time.


You can also use "Seek To" button that will navigate to the specified address. Either type a hexadecimal address to the text field or simply left-click on any address in the Disassembly window.

-

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


-

NES special addresses:

+
+ + + +

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

+

NES special addresses:

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


-

FDS special addresses:

+

FDS special addresses:

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


-

NSF special addresses:

+

NSF special addresses:

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


-


+
+
+


While execution is broken (emulation is paused), the program counter (PC) can be edited, as well as the three registers A/X/Y, and the status flags. Normally they should be left as-is, but changing them at runtime can be useful for more advanced debugging.


The contents of memory starting at the stack pointer (somewhere in the range $0100-01FF) is displayed in the Stack frame below the A/X/Y registers.


-

The current PPU memory address, sprite memory address, scanline, and rendering pixel are displayed below the stack and status flags.

+

The current PPU memory address, sprite memory address, scanline, and rendering pixel are displayed below the stack and status flags. Examples of Scanline number: -1 means Prerender time, 240 is Idle scanline, 0-239 are visible scanlines, 241-260/310 are VBlank scanlines.


-

Examples of Scanline number: -1 means Prerender time, 240 is Idle scanline, 0-239 are visible scanlines, 241-260/310 are VBlank scanlines.

-


-

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

+

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



Disassembly


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

-