From e7b5bdde81b42190963cce42f39ef52f81b7f790 Mon Sep 17 00:00:00 2001 From: ansstuff Date: Wed, 5 Sep 2012 15:25:10 +0000 Subject: [PATCH] * fixed conditional breakpoints bug #538 * updated the documentation on Debugger according to rainwarrior's edits, removed "Debugger Usage (Intermediate)" [[Split portion of a mixed commit.]] --- help/6502CPU.html | 1738 +++++++++++++------------- help/Debugger.html | 266 +++- help/FAQGuides.html | 12 +- help/Introduction.html | 20 +- help/LuaFunctionsList.html | 348 +++--- help/LuaGettingStarted.html | 12 +- help/LuaScripting.html | 8 +- help/NESRAMMappingFindingValues.html | 4 +- help/NESSound.html | 24 +- help/Technicalinformation.html | 2 +- help/TraceLogger.html | 2 +- help/WhatsNew216.html | 5 +- help/css/hnd.css | 109 +- help/fm2.html | 42 +- help/js/searchdata.js | 2 +- help/toc.html | 6 - 16 files changed, 1384 insertions(+), 1216 deletions(-) diff --git a/help/6502CPU.html b/help/6502CPU.html index 1abf9f1f..4eda9715 100644 --- a/help/6502CPU.html +++ b/help/6502CPU.html @@ -52,50 +52,50 @@
-

#

-

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

-

#

-

# This file is part of Commodore 64 emulator

-

#      and Program Development System.

-

#

-

# See README for copyright notice

-

#

-

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

-

#

-

#

-

# Written by

-

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

-

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

-

#

-

#

-

# $Log: 6502_cpu.txt,v $

-

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

-

# no message

-

#

-

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

-

# updates

-

#

-

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

-

# Patchlevel 2

-

#

-

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

-

# 65xx Register descriptions added

-

#

-

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

-

#

-

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

-

# X64 version 0.2 PL 1

-

#

-

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

-

#

-

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

-

#  X64 version 0.2 PL 0

-

#

-

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

-

# *** empty log message ***

-

#

-

#

-


+

#

+

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

+

#

+

# This file is part of Commodore 64 emulator

+

#      and Program Development System.

+

#

+

# See README for copyright notice

+

#

+

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

+

#

+

#

+

# Written by

+

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

+

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

+

#

+

#

+

# $Log: 6502_cpu.txt,v $

+

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

+

# no message

+

#

+

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

+

# updates

+

#

+

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

+

# Patchlevel 2

+

#

+

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

+

# 65xx Register descriptions added

+

#

+

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

+

#

+

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

+

# X64 version 0.2 PL 1

+

#

+

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

+

#

+

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

+

#  X64 version 0.2 PL 0

+

#

+

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

+

# *** empty log message ***

+

#

+

#

+


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

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

      which extracts them all at once.

@@ -120,45 +120,45 @@


6510 Instructions by Addressing Modes


-

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

-

set  00      20      40      60      80      a0      c0      e0      mode

-


-

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

-

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

-

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

-

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

-

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

-

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

-

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

-

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

-


-

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

-

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

-

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

-

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

-

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

-

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

-

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

-

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

-


-

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

-

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

-

+12   t       t       t       t       t       t       t       t         ?

-

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

-

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

-

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

-

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

-

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

-


-

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

-

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

-

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

-

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

-

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

-

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

-

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

-

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

-


+

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

+

set  00      20      40      60      80      a0      c0      e0      mode

+


+

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

+

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

+

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

+

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

+

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

+

+05  ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     Zeropage

+

+06  ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     Zeropage

+

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

+


+

+08  PHP     PLP     PHA     PLA     DEY     TAY     INY     INX     Implied

+

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

+

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

+

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

+

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

+

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

+

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

+

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

+


+

+10  BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ     Relative

+

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

+

+12   t       t       t       t       t       t       t       t         ?

+

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

+

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

+

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

+

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

+

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

+


+

+18  CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED     Implied

+

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

+

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

+

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

+

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

+

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

+

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

+

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

+


       ROR intruction is available on MC650x microprocessors after

       June, 1976.


@@ -333,9 +333,9 @@


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


-

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

-

                       same as

-

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

+

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

+

                       same as

+

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


                       In real 6510/8502 the internal parameter #$11

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

@@ -344,15 +344,15 @@

                       of the instruction.  The value probably depends

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


-

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

-

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

+

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

+

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


                       TXA and TAX have to be responsible for these.


-

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

-

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

-

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

-

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

+

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

+

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

+

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

+

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


                       Note: The value to be stored is copied also

                       to ADDR_HI if page boundary is crossed.

@@ -377,7 +377,7 @@

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

simultaneously into both A and X.


-

       $6B  ARR

+

       $6B  ARR


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

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

@@ -415,36 +415,36 @@

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

illustrates the ARR operation in Decimal mode:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

          t,  /* temporary value */

-

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

-


-

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

-


-

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

-

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

-


-

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

-

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

-

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

-


-

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

-

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

-


-

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

-

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

-


-

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

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

          t,  /* temporary value */

+

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

+


+

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

+


+

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

+

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

+


+

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

+

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

+

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

+


+

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

+

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

+


+

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

+

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

+


+

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

+


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

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

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

@@ -457,23 +457,23 @@


Proof:


-

begin 644 vsbx

-

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

-

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

-

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

-

`

-

end

-


-

and

-


-

begin 644 sbx

-

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

-

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

-

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

-

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

-

`

-

end

-


+

begin 644 vsbx

+

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

+

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

+

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

+

`

+

end

+


+

and

+


+

begin 644 sbx

+

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

+

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

+

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

+

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

+

`

+

end

+


These test programs show if your machine is compatible with ours

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

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

@@ -504,10 +504,10 @@

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

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


-

begin 644 sbx-c100

-

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

-

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

-

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

+

begin 644 sbx-c100

+

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

+

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

+

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


Other undocumented instructions usually cause two preceding opcodes

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

@@ -599,11 +599,11 @@


Register selection for load and store


-

  bit1 bit0     A  X  Y

-

   0    0             x

-

   0    1          x

-

   1    0       x

-

   1    1       x  x

+

  bit1 bit0     A  X  Y

+

   0    0             x

+

   0    1          x

+

   1    0       x

+

   1    1       x  x


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

~(bit1|bit0) enables Y.

@@ -628,39 +628,39 @@

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

the instruction:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-

                                                like in Binary mode. */

-


-

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

-

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

-


-

       N = (AH & 8 != 0);

-

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

-


-

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

-


-

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

-


-

       C = (AH > 15);

-

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

+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+

                                                like in Binary mode. */

+


+

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

+

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

+


+

       N = (AH & 8 != 0);

+

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

+


+

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

+


+

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

+


+

       C = (AH > 15);

+

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


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

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

@@ -671,14 +671,14 @@

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

      If everything goes well, it ends in RTS.


-

begin 600 dadc

-

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

-

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

-

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

-

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

-

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

-


-

end

+

begin 600 dadc

+

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

+

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

+

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

+

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

+

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

+


+

end


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

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

@@ -691,45 +691,45 @@


Proof:


-

begin 600 dsbc-cmp-flags

-

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

-

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

-

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

-


-

end

+

begin 600 dsbc-cmp-flags

+

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

+

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

+

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

+


+

end


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

is the result-fixup:


-

       unsigned

-

          A,  /* Accumulator */

-

          AL, /* low nybble of accumulator */

-

          AH, /* high nybble of accumulator */

-


-

          C,  /* Carry flag */

-

          Z,  /* Zero flag */

-

          V,  /* oVerflow flag */

-

          N,  /* Negative flag */

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-


-

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

-

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

-

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

-

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

-


-

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

-


+

       unsigned

+

          A,  /* Accumulator */

+

          AL, /* low nybble of accumulator */

+

          AH, /* high nybble of accumulator */

+


+

          C,  /* Carry flag */

+

          Z,  /* Zero flag */

+

          V,  /* oVerflow flag */

+

          N,  /* Negative flag */

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+


+

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

+

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

+

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

+

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

+


+

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

+


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

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

phase.

@@ -752,13 +752,13 @@

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

contains the 6502 version of the pseudo code example above.


-

begin 600 dsbc

-

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

-

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

-

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

-

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

-


-

end

+

begin 600 dsbc

+

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

+

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

+

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

+

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

+


+

end


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

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

@@ -767,29 +767,29 @@

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

affected by the D flag.


-

begin 644 droradc

-

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

-

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

-

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

-

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

-

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

-

`

-

end

-


-

begin 644 dincsbc

-

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

-

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

-

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

-

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

-

`

-

end

-


-

begin 644 dincsbc-deccmp

-

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

-

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

-

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

-

`

-

end

+

begin 644 droradc

+

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

+

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

+

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

+

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

+

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

+

`

+

end

+


+

begin 644 dincsbc

+

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

+

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

+

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

+

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

+

`

+

end

+


+

begin 644 dincsbc-deccmp

+

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

+

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

+

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

+

`

+

end



6510 features

@@ -950,617 +950,617 @@


 Instructions accessing the stack


-

    BRK

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

                      increment PC

-

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

-

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

-

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

-

       6   $FFFE   R  fetch PCL

-

       7   $FFFF   R  fetch PCH

-


-

    RTI

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

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

-

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

-

       6  $0100,S  R  pull PCH from stack

-


-

    RTS

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

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

-

       5  $0100,S  R  pull PCH from stack

-

       6    PC     R  increment PC

-


-

    PHA, PHP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

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

-


-

    PLA, PLP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-

       3  $0100,S  R  increment S

-

       4  $0100,S  R  pull register from stack

-


-

    JSR

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

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

-

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

-

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

-

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

-

                      byte to PCH

-


-

 Accumulator or implied addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

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

-


-

 Immediate addressing

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch value, increment PC

-


-

 Absolute addressing

-


-

    JMP

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low address byte, increment PC

-

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

-

                      byte to PCH

-


-

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

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-


-

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

-

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

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  R  read from effective address

-

       5  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       6  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch low byte of address, increment PC

-

       3    PC     R  fetch high byte of address, increment PC

-

       4  address  W  write register to effective address

-


-

 Zero page addressing

-


-

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

-

                       LAX, NOP)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-


-

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

-

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

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  R  read from effective address

-

       4  address  W  write the value back to effective address,

-

                      and do the operation on it

-

       5  address  W  write the new value to effective address

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #  address R/W description

-

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

-

       1    PC     R  fetch opcode, increment PC

-

       2    PC     R  fetch address, increment PC

-

       3  address  W  write register to effective address

-


-

 Zero page indexed addressing

-


-

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

-

                       LAX, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+I* R  read from effective address

-


-

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

-


-

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

-

               i.e. page boundary crossings are not handled.

-


-

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

-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+X* R  read from effective address

-

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

-

                        and do the operation on it

-

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

-


-

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

-

              i.e. page boundary crossings are not handled.

-


-

    Write instructions (STA, STX, STY, SAX)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch address, increment PC

-

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

-

       4  address+I* W  write to effective address

-


-

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

-


-

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

-

               i.e. page boundary crossings are not handled.

-


-

 Absolute indexed addressing

-


-

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

-

                       LAX, LAE, SHS, NOP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

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

-


-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

             + This cycle will be executed only if the effective address

-

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

-


-

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

-

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

-


-

       #   address  R/W description

-

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

-

       1    PC       R  fetch opcode, increment PC

-

       2    PC       R  fetch low byte of address, increment PC

-

       3    PC       R  fetch high byte of address,

-

                        add index register X to low address byte,

-

                        increment PC

-

       4  address+X* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+X  R  re-read from effective address

-

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

-

                        and do the operation on it

-

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

-


-

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

-

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

-


-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch low byte of address, increment PC

-

       3     PC      R  fetch high byte of address,

-

                        add index register to low address byte,

-

                        increment PC

-

       4  address+I* R  read from effective address,

-

                        fix the high byte of effective address

-

       5  address+I  W  write to effective address

-


-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-

               the processor cannot undo a write to an invalid

-

               address, it always reads from the address first.

-


-

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

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch operand, increment PC

-

       3     PC      R  Fetch opcode of next instruction,

-

                        If branch is taken, add operand to PCL.

-

                        Otherwise increment PC.

-

       4+    PC*     R  Fetch opcode of next instruction.

-

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

-

       5!    PC      R  Fetch opcode of next instruction,

-

                        increment PC.

-


-

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

-

             this diagram for illustration purposes. When determining

-

             real execution times, remember to subtract the last

-

             cycle.

-


-

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

-

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

-


-

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

-


-

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

-

               executed.

-


-

 Indexed indirect addressing

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-


-

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

-

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

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    R  read from effective address

-

       7    address    W  write the value back to effective address,

-

                          and do the operation on it

-

       8    address    W  write the new value to effective address

-


-

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

-

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

-


-

    Write instructions (STA, SAX)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

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

-

       4   pointer+X   R  fetch effective address low

-

       5  pointer+X+1  R  fetch effective address high

-

       6    address    W  write to effective address

-


-

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

-

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

-


-

 Indirect indexed addressing

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6+  address+Y   R  read from effective address

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

             + This cycle will be executed only if the effective address

-

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

-


-

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

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   R  read from effective address

-

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

-

                          and do the operation on it

-

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

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

    Write instructions (STA, SHA)

-


-

       #    address   R/W description

-

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

-

       1      PC       R  fetch opcode, increment PC

-

       2      PC       R  fetch pointer address, increment PC

-

       3    pointer    R  fetch effective address low

-

       4   pointer+1   R  fetch effective address high,

-

                          add Y to low byte of effective address

-

       5   address+Y*  R  read from effective address,

-

                          fix high byte of effective address

-

       6   address+Y   W  write to effective address

-


-

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

-

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

-


-

             * The high byte of the effective address may be invalid

-

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

-


-

 Absolute indirect addressing (JMP)

-


-

       #   address  R/W description

-

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

-

       1     PC      R  fetch opcode, increment PC

-

       2     PC      R  fetch pointer address low, increment PC

-

       3     PC      R  fetch pointer address high, increment PC

-

       4   pointer   R  fetch low address to latch

-

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

-


-

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

-

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

-


-

               How Real Programmers Acknowledge Interrupts

-


-

 With RMW instructions:

-


-

       ; beginning of combined raster/timer interrupt routine

-

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

-

       BCS raster      ; jump if VIC caused an interrupt

-

       ...             ; timer interrupt routine

-


-

       Operational diagram of LSR $D019:

-


-

         #  data  address  R/W

-

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

-

         1   4E     PC      R   fetch opcode

-

         2   19    PC+1     R   fetch address low

-

         3   D0    PC+2     R   fetch address high

-

         4   xx    $D019    R   read memory

-

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

-

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

-


-

       The 5th cycle acknowledges the interrupt by writing the same

-

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

-

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

-

       other interrupts.)

-


-

 With indexed addressing:

-


-

       ; acknowledge interrupts to both CIAs

-

       LDX #$10

-

       LDA $DCFD,X

-


-

       Operational diagram of LDA $DCFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   BD     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

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

-

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

-

         5   yy    $DD0D    R   read from right address

-


-

       ; acknowledge interrupts to CIA 2

-

       LDX #$10

-

       STA $DDFD,X

-


-

       Operational diagram of STA $DDFD,X:

-


-

         #  data  address  R/W  description

-

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

-

         1   9D     PC      R   fetch opcode

-

         2   FD    PC+1     R   fetch address low

-

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

-

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

-

         5   ac    $DE0D    W   write to right address

-


-

 With branch instructions:

-


-

       ; acknowledge interrupts to CIA 2

-

               LDA #$00  ; clear N flag

-

               JMP $DD0A

-

       DD0A    BPL $DC9D ; branch

-

       DC9D    BRK       ; return

-


-

       You need the following preparations to initialize the CIA registers:

-


-

               LDA #$91  ; argument of BPL

-

               STA $DD0B

-

               LDA #$10  ; BPL

-

               STA $DD0A

-

               STA $DD08 ; load the ToD values from the latches

-

               LDA $DD0B ; freeze the ToD display

-

               LDA #$7F

-

               STA $DC0D ; assure that $DC0D is $00

-


-

       Operational diagram of BPL $DC9D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0A    R   fetch opcode

-

         2   91    $DD0B    R   fetch argument

-

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

-

         4   yy    $DD9D    R   fetch opcode, fix PCH

-

       ( 5   00    $DC9D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 1

-

               LSR       ; clear N flag

-

               JMP $DCFA

-

       DCFA    BPL $DD0D

-

       DD0D    BRK

-


-

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

-

       ; Interrupt Control Register of CIA 2 first.

-


-

       Operational diagram of BPL $DD0D:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DCFA    R   fetch opcode

-

         2   11    $DCFB    R   fetch argument

-

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

-

         4   yy    $DC0D    R   fetch opcode, fix PCH

-

       ( 5   00    $DD0D    R   fetch opcode )

-


-

       ; acknowledge interrupts to CIA 2 automagically

-

               ; preparations

-

               LDA #$7F

-

               STA $DD0D       ; disable all interrupt sources of CIA2

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$FD

-

               STA $DD0C       ; parameter of BPL

-

               LDA #$10

-

               STA $DD0B       ; BPL

-

               LDA #$40

-

               STA $DD0A       ; RTI/parameter of LSR

-

               LDA #$46

-

               STA $DD09       ; LSR

-

               STA $DD08       ; load the ToD values from the latches

-

               LDA $DD0B       ; freeze the ToD display

-

               LDA #$09

-

               STA $0318

-

               LDA #$DD

-

               STA $0319       ; change NMI vector to $DD09

-

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

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

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

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

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

-

               STA $D011       ; use something like this and see how

-

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

-

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

-


-

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

-

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

-


-

       DD09    LSR $40         ; clear N flag

-

               BPL $DD0A       ; Note: $DD0A contains RTI.

-


-

       Operational diagram of BPL $DD0A:

-


-

         #  data  address  R/W  description

-

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

-

         1   10    $DD0B    R   fetch opcode

-

         2   11    $DD0C    R   fetch argument

-

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

-

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

-


-

 With RTI:

-


-

       ; the fastest possible interrupt handler in the 6500 family

-

               ; preparations

-

               SEI

-

               LDA $01         ; disable ROM and enable I/O

-

               AND #$FD

-

               ORA #$05

-

               STA $01

-

               LDA #$7F

-

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

-

               LDA $DD0E

-

               AND #$BE        ; ensure that $DD0C remains constant

-

               STA $DD0E       ; and stop the timer

-

               LDA #$40

-

               STA $DD0C       ; store RTI to $DD0C

-

               LDA #$0C

-

               STA $FFFA

-

               LDA #$DD

-

               STA $FFFB       ; change NMI vector to $DD0C

-

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

-

               STA $DD05       ; (see comment below).

-

               LDA #$FF

-

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

-

               LDA $DD0E

-

               AND #$80

-

               ORA #$11

-

               LDX #$81

-

               STX $DD0D       ; enable timer interrupt

-

               STA $DD0E       ; start timer

-


-

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

-

               STA $D011       ; use something like this and see how

-

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

-

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

-


+

    BRK

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

                      increment PC

+

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

+

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

+

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

+

       6   $FFFE   R  fetch PCL

+

       7   $FFFF   R  fetch PCH

+


+

    RTI

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

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

+

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

+

       6  $0100,S  R  pull PCH from stack

+


+

    RTS

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

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

+

       5  $0100,S  R  pull PCH from stack

+

       6    PC     R  increment PC

+


+

    PHA, PHP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

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

+


+

    PLA, PLP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+

       3  $0100,S  R  increment S

+

       4  $0100,S  R  pull register from stack

+


+

    JSR

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

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

+

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

+

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

+

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

+

                      byte to PCH

+


+

 Accumulator or implied addressing

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

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

+


+

 Immediate addressing

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch value, increment PC

+


+

 Absolute addressing

+


+

    JMP

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low address byte, increment PC

+

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

+

                      byte to PCH

+


+

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

+

                       LAX, NOP)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+


+

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

+

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

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  R  read from effective address

+

       5  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       6  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch low byte of address, increment PC

+

       3    PC     R  fetch high byte of address, increment PC

+

       4  address  W  write register to effective address

+


+

 Zero page addressing

+


+

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

+

                       LAX, NOP)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+


+

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

+

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

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  R  read from effective address

+

       4  address  W  write the value back to effective address,

+

                      and do the operation on it

+

       5  address  W  write the new value to effective address

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #  address R/W description

+

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

+

       1    PC     R  fetch opcode, increment PC

+

       2    PC     R  fetch address, increment PC

+

       3  address  W  write register to effective address

+


+

 Zero page indexed addressing

+


+

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

+

                       LAX, NOP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+I* R  read from effective address

+


+

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

+


+

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

+

               i.e. page boundary crossings are not handled.

+


+

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

+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+X* R  read from effective address

+

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

+

                        and do the operation on it

+

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

+


+

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

+

              i.e. page boundary crossings are not handled.

+


+

    Write instructions (STA, STX, STY, SAX)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch address, increment PC

+

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

+

       4  address+I* W  write to effective address

+


+

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

+


+

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

+

               i.e. page boundary crossings are not handled.

+


+

 Absolute indexed addressing

+


+

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

+

                       LAX, LAE, SHS, NOP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

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

+


+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

             + This cycle will be executed only if the effective address

+

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

+


+

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

+

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

+


+

       #   address  R/W description

+

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

+

       1    PC       R  fetch opcode, increment PC

+

       2    PC       R  fetch low byte of address, increment PC

+

       3    PC       R  fetch high byte of address,

+

                        add index register X to low address byte,

+

                        increment PC

+

       4  address+X* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+X  R  re-read from effective address

+

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

+

                        and do the operation on it

+

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

+


+

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

+

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

+


+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch low byte of address, increment PC

+

       3     PC      R  fetch high byte of address,

+

                        add index register to low address byte,

+

                        increment PC

+

       4  address+I* R  read from effective address,

+

                        fix the high byte of effective address

+

       5  address+I  W  write to effective address

+


+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+

               the processor cannot undo a write to an invalid

+

               address, it always reads from the address first.

+


+

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

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch operand, increment PC

+

       3     PC      R  Fetch opcode of next instruction,

+

                        If branch is taken, add operand to PCL.

+

                        Otherwise increment PC.

+

       4+    PC*     R  Fetch opcode of next instruction.

+

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

+

       5!    PC      R  Fetch opcode of next instruction,

+

                        increment PC.

+


+

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

+

             this diagram for illustration purposes. When determining

+

             real execution times, remember to subtract the last

+

             cycle.

+


+

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

+

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

+


+

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

+


+

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

+

               executed.

+


+

 Indexed indirect addressing

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+


+

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

+

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

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    R  read from effective address

+

       7    address    W  write the value back to effective address,

+

                          and do the operation on it

+

       8    address    W  write the new value to effective address

+


+

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

+

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

+


+

    Write instructions (STA, SAX)

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

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

+

       4   pointer+X   R  fetch effective address low

+

       5  pointer+X+1  R  fetch effective address high

+

       6    address    W  write to effective address

+


+

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

+

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

+


+

 Indirect indexed addressing

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6+  address+Y   R  read from effective address

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

             + This cycle will be executed only if the effective address

+

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

+


+

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

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   R  read from effective address

+

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

+

                          and do the operation on it

+

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

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

    Write instructions (STA, SHA)

+


+

       #    address   R/W description

+

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

+

       1      PC       R  fetch opcode, increment PC

+

       2      PC       R  fetch pointer address, increment PC

+

       3    pointer    R  fetch effective address low

+

       4   pointer+1   R  fetch effective address high,

+

                          add Y to low byte of effective address

+

       5   address+Y*  R  read from effective address,

+

                          fix high byte of effective address

+

       6   address+Y   W  write to effective address

+


+

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

+

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

+


+

             * The high byte of the effective address may be invalid

+

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

+


+

 Absolute indirect addressing (JMP)

+


+

       #   address  R/W description

+

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

+

       1     PC      R  fetch opcode, increment PC

+

       2     PC      R  fetch pointer address low, increment PC

+

       3     PC      R  fetch pointer address high, increment PC

+

       4   pointer   R  fetch low address to latch

+

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

+


+

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

+

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

+


+

               How Real Programmers Acknowledge Interrupts

+


+

 With RMW instructions:

+


+

       ; beginning of combined raster/timer interrupt routine

+

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

+

       BCS raster      ; jump if VIC caused an interrupt

+

       ...             ; timer interrupt routine

+


+

       Operational diagram of LSR $D019:

+


+

         #  data  address  R/W

+

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

+

         1   4E     PC      R   fetch opcode

+

         2   19    PC+1     R   fetch address low

+

         3   D0    PC+2     R   fetch address high

+

         4   xx    $D019    R   read memory

+

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

+

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

+


+

       The 5th cycle acknowledges the interrupt by writing the same

+

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

+

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

+

       other interrupts.)

+


+

 With indexed addressing:

+


+

       ; acknowledge interrupts to both CIAs

+

       LDX #$10

+

       LDA $DCFD,X

+


+

       Operational diagram of LDA $DCFD,X:

+


+

         #  data  address  R/W  description

+

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

+

         1   BD     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

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

+

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

+

         5   yy    $DD0D    R   read from right address

+


+

       ; acknowledge interrupts to CIA 2

+

       LDX #$10

+

       STA $DDFD,X

+


+

       Operational diagram of STA $DDFD,X:

+


+

         #  data  address  R/W  description

+

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

+

         1   9D     PC      R   fetch opcode

+

         2   FD    PC+1     R   fetch address low

+

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

+

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

+

         5   ac    $DE0D    W   write to right address

+


+

 With branch instructions:

+


+

       ; acknowledge interrupts to CIA 2

+

               LDA #$00  ; clear N flag

+

               JMP $DD0A

+

       DD0A    BPL $DC9D ; branch

+

       DC9D    BRK       ; return

+


+

       You need the following preparations to initialize the CIA registers:

+


+

               LDA #$91  ; argument of BPL

+

               STA $DD0B

+

               LDA #$10  ; BPL

+

               STA $DD0A

+

               STA $DD08 ; load the ToD values from the latches

+

               LDA $DD0B ; freeze the ToD display

+

               LDA #$7F

+

               STA $DC0D ; assure that $DC0D is $00

+


+

       Operational diagram of BPL $DC9D:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DD0A    R   fetch opcode

+

         2   91    $DD0B    R   fetch argument

+

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

+

         4   yy    $DD9D    R   fetch opcode, fix PCH

+

       ( 5   00    $DC9D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 1

+

               LSR       ; clear N flag

+

               JMP $DCFA

+

       DCFA    BPL $DD0D

+

       DD0D    BRK

+


+

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

+

       ; Interrupt Control Register of CIA 2 first.

+


+

       Operational diagram of BPL $DD0D:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DCFA    R   fetch opcode

+

         2   11    $DCFB    R   fetch argument

+

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

+

         4   yy    $DC0D    R   fetch opcode, fix PCH

+

       ( 5   00    $DD0D    R   fetch opcode )

+


+

       ; acknowledge interrupts to CIA 2 automagically

+

               ; preparations

+

               LDA #$7F

+

               STA $DD0D       ; disable all interrupt sources of CIA2

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$FD

+

               STA $DD0C       ; parameter of BPL

+

               LDA #$10

+

               STA $DD0B       ; BPL

+

               LDA #$40

+

               STA $DD0A       ; RTI/parameter of LSR

+

               LDA #$46

+

               STA $DD09       ; LSR

+

               STA $DD08       ; load the ToD values from the latches

+

               LDA $DD0B       ; freeze the ToD display

+

               LDA #$09

+

               STA $0318

+

               LDA #$DD

+

               STA $0319       ; change NMI vector to $DD09

+

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

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

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

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

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

+

               STA $D011       ; use something like this and see how

+

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

+

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

+


+

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

+

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

+


+

       DD09    LSR $40         ; clear N flag

+

               BPL $DD0A       ; Note: $DD0A contains RTI.

+


+

       Operational diagram of BPL $DD0A:

+


+

         #  data  address  R/W  description

+

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

+

         1   10    $DD0B    R   fetch opcode

+

         2   11    $DD0C    R   fetch argument

+

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

+

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

+


+

 With RTI:

+


+

       ; the fastest possible interrupt handler in the 6500 family

+

               ; preparations

+

               SEI

+

               LDA $01         ; disable ROM and enable I/O

+

               AND #$FD

+

               ORA #$05

+

               STA $01

+

               LDA #$7F

+

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

+

               LDA $DD0E

+

               AND #$BE        ; ensure that $DD0C remains constant

+

               STA $DD0E       ; and stop the timer

+

               LDA #$40

+

               STA $DD0C       ; store RTI to $DD0C

+

               LDA #$0C

+

               STA $FFFA

+

               LDA #$DD

+

               STA $FFFB       ; change NMI vector to $DD0C

+

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

+

               STA $DD05       ; (see comment below).

+

               LDA #$FF

+

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

+

               LDA $DD0E

+

               AND #$80

+

               ORA #$11

+

               LDX #$81

+

               STX $DD0D       ; enable timer interrupt

+

               STA $DD0E       ; start timer

+


+

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

+

               STA $D011       ; use something like this and see how

+

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

+

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

+


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

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


-

       DD0C    RTI

-


+

       DD0C    RTI

+


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

       processor always fetches two successive bytes for each

       instruction.

@@ -1572,13 +1572,13 @@

       you used when writing the RTI.


       Or you can combine the latter two methods:

-


-

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

-

               BPL $DCFC

-

       DCFC    RTI

-


+


+

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

+

               BPL $DCFC

+

       DCFC    RTI

+


       This example acknowledges interrupts to both CIAs.

-


+


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

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

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

diff --git a/help/Debugger.html b/help/Debugger.html index 2a75dfb5..f3bc24f7 100644 --- a/help/Debugger.html +++ b/help/Debugger.html @@ -54,44 +54,203 @@

Debugger


-

Taken from the FCEUXDSP 1.07 documentation.

-

More stuff added by AnS.


-

Introduction

-


-

The debugger is a powerful tool that reads, displays, and manipulates assembly language instructions in a game.

-


-

Debugger Features

+

Introduction


+

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



-

Using Debugger

+

Execution and CPU State


-

Symbolic Debugging

+

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.


-

The most important feature (at least for me) that was introduced in FCEUXD SP is symbolic debugging.  With this new feature it's possible to rename addresses in the disassembly window (like $C022) to easily understandable names (like AddHealthpoints). It's also possible to add comments to lines in the disassembly window.

+

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.


-

To be able to use this feature it's necessary to create so called name list files (*.(bank).nl/*.ram.nl, Ex: NES Test Cart (PD).nes.0.nl, NES Test Cart (PD).nes.ram.nl) which contain all names and comments you wish to display in the disassembly window. These files are plain ASCII files of the following format (example follows):

+ +


+

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

+


+

Just below these buttons is a "Seek To" button that will navigate to the specified address. When execution is paused, the disassembly view will begin with the memory at the currengt 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.

+


+

While execution is broken, 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.

+


+

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

+


+

To the right from 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.

+


+


+

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:

+


+ +


+

Memory contents are displayed in this form:

+


+

0F:C0A8:24 1F     BIT $001F = #$80

+

bb:mmmm:dd dd dd  iiiiiiiiiiiii...

+


+ +


+

When debugging an NSF program, the bank designation will be a 4k NSF bank instead of the 16k iNES bank.

+


+

A single instruction may be one to three bytes, and will all appear on the line before the assembly code description of that instruction. An instruction with "= #$xx" at the end indicates the value currently in memory at the address referenced by the instruction (before it executes).

+


+

There is an empty column to the left of the memory view. Hovering the mouse here will display at the bottom of the window more detailed information about the location of this code in the iNES file. Left clicking on this column will open the Inline Assembler, which allows you to patch the ROM at runtime. Right clicking on this column will open the Hex Editor, which allows you to directly edit the ROM. Middle-clicking on this column will bring up the Game Genie Encoder at that address, so you can easily make Game Genie codes, for example freeze a range of addresses.

+


+


+

Breakpoints

+


+

Breakpoints will break execution when chosen conditions are met. To create a breakpoint, click the Add button in the BreakPoints frame in the upper right corner of the debugger.

+


+

Each breakpoint has an address range to watch (use only the left address field if you wish to watch a single byte address). Check one or more of the options to watch for Read, Write, or Execute at an address. Note that fetching of code from an address will not break as a Read; use the Execute box for this. Breakpoints can be given a name that will appear in the breakpoint window. The condition field can be used to break only on particular conditions; see "Conditional Breakpoints" below.

+


+

Double click on a breakpoint in the BreakPoints list to quickly disable or enable it. So you don't have to delete breakpoints to stop them from causing the debugger to halt the game.

+


+

A special kind of breakpoints with the Forbid option will prevent any breakpoints from occurring within the specified memory address range. This can be enabled and disabled like other breakpoints.

+


+

A quicker way to add PC breakpoints is to double click on the Disassembly where you want to set the breakpoint. Example: when you need to quickly advance emulation to a given line of code, doubleclick on the line in Disassembly window, and the "Add Execute breakpoint here" dialog will appear, click "OK" and then hit "Run", Debugger will break at this line of code.

+


+

There is also an option to "Break on Bad Opcode" which will halt execution if a bad instruction opcode is reached.

+


+

Finally, you can make the debugger break after certain number of instructions or CPU cycles.

+


+

More advanced conditions and automation may be achieved through Lua script breakpoints. See the Lua reference for more information.

+


+

Breakpoints are listed in the following form:

+


+

aaaa: EmRWXF : nnnn

+

aaaa-aaaa: EmRWXF : nnnn

+


+ +


+

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

+


+

NES special addresses:

+ +


+

FDS special addresses:

+ +


+

NSF special addresses:

+ +


+


+

Conditional Breakpoints

+


+

Breakpoints may also have a conditional statement that causes them to execute only if that statement evaluates to true. The conditional breakpoint grammar has this form:

+


+ +


+

The parser is very strict. All numbers are hexadecimal. Always prefix a number with # for an immediate value, or $ for a memory address. If a memory address needs to be calculated use $[] with the calculation inside the brackets.

+


+

Registers A/X/Y are 8-bit unsigned values. Register P is the 16-bit program counter.

+


+

Flags evaluate to 1 if set, 0 if clear.

+


+

Connecting operators || or && combine boolean terms. Parentheses dictate order of operations.

+


+

Example conditions:

+


+

Break if register A is less than value at memory address $0005:

+

A < $0005

+


+

Break if the program counter is 8123:

+

P == #8123

+


+

Break if the value at the indirect address on zeropage $10 is not equal to FF:

+

#FF != $[$10+($11*#100)]

+


+

Break if flag N is clear or A is not equal to 00:

+

(N==#0 || A!=#0)

+


+


+

Bookmarks

+


+

A list of bookmark addresses can be kept in the Bookmark frame to make memory navigation easier. Simply type an address and click "Add" to add it to your bookmarks. Next time you wish to go to this address just double click on the bookmark.

+


+

When you exit the emulator, bookmarks are saved in a .deb file. Next time you return to debugging the list of bookmarks will be automatically loaded from the file.

+


+


+

Inline Assembler

+


+

Open the inline assembler by left-clicking in the empty column to the left of the memory view.

+


+

The starting memory address is displayed in the PC field at the top of the inline assembler window. Type a line of assembly to add in the empty field just below this, and hit enter. The assembled code of your patch will appear below as you enter each line.

+


+

Click Apply to apply your patch to the ROM in memory. Click Undo to remove the last assembled line. After applying a patch, clicking Save will allow you to save this patch directly to the ROM file.

+


+


+

Symbolic Debugging

+


+

This feature makes it possible to rename addresses in the disassembly window (e.g. $C022) to easily understandable names (e.g. AddHealthpoints). You can also add comments to lines in the disassembly window. You can enable symbolic debugging by clicking the checkbox "Symbolic Debugging".

+


+

To use this feature, create name list files (Filename should be like this: *.(bank).nl / *.ram.nl, Example: NES Test Cart (PD).nes.0.nl, NES Test Cart (PD).nes.ram.nl) which contain all names and comments you wish to display in the disassembly window. These are ASCII files.

+

Example of contents of a NL file:


$C000#NewName1#Comment1

$C002##Comment2

@@ -101,47 +260,40 @@

\MultilineComment-Part3

$C008/10#NewName4#


-

Every line contains two # characters which separate the three parts of one line: The first part (starting with a $ character) is the address to be renamed. Optionally you can add a "/number" part which marks the offsets as a beginning of an array of the given size (the size must be specified in hex form).  The second (optional) part is the new name of that address. Whenever the line of that address is shown in the disassembly window an extra line saying "Name: NewName" is shown above it.  Instructions referencing this address, for example JSR $C000 are also changed to JSR NewName1 (in that example).  The third (optional) part is the comment that's also added above the disassembly line the comment refers to. It works exactly like the additional name line, only the prefix of that line is different. Comment lines start with "Comment: " rather than with "Name: ".  Multi-lines comments are possible. Lines starting with a \ character are just appended to the comment of the preceding line. Multi-line comments are also shown in multiple lines in the disassembly window.

+

Every line contains two # characters which separate the three parts of one line: The first part (starting with a $ character) is the address to be renamed. Optionally you can add a "/number" part which marks the offsets as a beginning of an array of the given size (the size must be specified in hex form). The second (optional) part is the new name of that address. Whenever the line of that address is shown in the disassembly window an extra line saying "Name: NewName" is shown above it.  Instructions referencing this address, for example JSR $C000 are also changed to JSR NewName1 (in that example).  The third (optional) part is the comment that's also added above the disassembly line the comment refers to. It works exactly like the additional name line, only the prefix of that line is different. Comment lines start with "Comment: " rather than with "Name: ".  Multi-lines comments are possible. Lines starting with a \ character are just appended to the comment of the preceding line. Multi-line comments are also shown in multiple lines in the disassembly window.


-

Let's get back to the example.

-

The first line contains all three parts. Using this name list file all references to the address

-

$C000 are replaced with NewName1 and whenever line $C000 is shown in the disassembly window an

-

additional comment is also visible right above the actual disassembled line.

-

The second line defines only a comment while the third line defines only a name. Following that

-

there's a multi-line comment definition for address $C006.

-

The last line defines an array called NewName4 of size $10 (= 16) bytes starting at offset $C008.

+

In the example above, the first line contains all three parts. Using this NL file all references to the address $C000 are replaced with NewName1 and whenever line $C000 is shown in the disassembly window an additional comment is also visible right above the actual disassembled line. The second example line defines only a comment while the third line defines only a name. Following that there's a multi-line comment definition for address $C006. The last line defines an array called NewName4 of size 0x10 (= 16) bytes starting at offset $C008.


-

Now you know the format of the nl files but you do not yet know the naming convention for the

-

file names. Due to the bank-swapping nature of the NES it's getting a little bit difficult here.

-

Each bank needs it's own nl file. The naming convention goes like this: Take the name of the ROM

-

file and just add ".X.nl" to it where the X is the hexadecimal representation of the number of the

-

ROM bank. Suppose you have the ROM file "Faxanadu (U).nes" and you want to create a nl file for

-

ROM bank 15. As 15 is 0x0F in hex the name of the nl file would be "Faxanadu (U).nes.F.nl". All

-

nl files go into the same directory as the ROM file itself.

+

NL files must follow a specific naming convention to account for bank swapping. Each bank needs its own NL file with a hexadecimal bank number. RAM can also be given its own NL file. For instance, an NES file named "mygame.nes" that has 4 banks would have these NL files:

+


+

mygame.nes

+

mygame.nes.ram.nl

+

mygame.nes.0.nl

+

mygame.nes.1.nl

+

mygame.nes.2.nl

+

mygame.nes.3.nl

+


+

All NL files must be into the same directory as the ROM file itself.

+


+

In the *.ram.nl file you can name and comment RAM addresses instead of ROM addresses. In this case, you might use a line such as:


-

There is also the *.ram.nl file specification, which allows you to substitute RAM addresses for

-

execution addresses, and have those named as well. In this case, you could use lines of this type:

$00A5#Mic Test OK#00=Not Passed, 01=Passed


-

You can enable and disable symbolic debugging by clicking the checkbox "Symbolic Debugging" in

-

the debugger window. To forcibly reload the nl files of the currently active ROM file press the

-

button with the text "Reload Symbols".

+

To reload the NL files of the currently active ROM file press the "Reload Symbols" button.



-

Arrays

+

Other


-

The array feature is an easy way to group names and comments for sequential offsets.

+

The debugger will automatically save debug settings such as breakpoints and bookmarks in a .deb file alongside the NES ROM. If the "Load .DEB" checkbox is checked, this file will be loaded next time you open the ROM.


-

$C000/5#NewName1#Comment1

+

There is a "Rom Patcher" button that may be used to apply a small patch to a ROM.


-

is equivalent to

+

The "Display ROM offsets" option will display ROM offsets instead of CPU addresses in the Disassembly window.


-

$C000#NewName1#Comment1

-


+

The "Restore Original Window Size" button will restore the original size of the debugger window if you resized it manually.


-

Inline Assembler

+

The "Auto-open" checkbox causes the debugger window to open automatically whenever an NES ROM is opened.


-

The debugger has an Inline Assembler designed by Parasyte.  To activate it, left-click in the left pane of the debugger, beside the assembly display.  To use it, type in some code and press Enter to add it to the patch list. If you make a mistake, press "Undo".  Once the patch is set up the way you want it, press "Apply". Be aware that this cannot be undone unless you reload the ROM.  Parasyte implemented this feature before I had the Hex Editor working, otherwise I would have implemented a way to undo it from there.  Press "Save" to write to the ROM file on disk; note that this will also save any changes you may have done in the Hex Editor.




diff --git a/help/FAQGuides.html b/help/FAQGuides.html index 4142992a..097e1273 100644 --- a/help/FAQGuides.html +++ b/help/FAQGuides.html @@ -52,31 +52,27 @@


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


-

Troubleshooting FAQ

+

Troubleshooting FAQ


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



-

Tool Assisted Speedruns (TAS)

+

Tool Assisted Speedruns (TAS)


Information regarding Tool Assisted Speedruns and the TAS community.



-

ROM Hacking

+

ROM Hacking


Information regarding making ROM Hacks and the ROM Hacking community.



-

NES RAM Mapping

+

NES RAM Mapping


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



-

Debugger Usage Guide (Intermediate)


-

This is a guide that explains some of the debugging features in terms that someone

-

with previous experience with assembly can understand, and delves into the most

-

basic understanding to a degree as well. Likely won't help a beginner too much.

Created with the Personal Edition of HelpNDoc: Free HTML Help documentation generator

diff --git a/help/Introduction.html b/help/Introduction.html index fc11dec7..896256ab 100644 --- a/help/Introduction.html +++ b/help/Introduction.html @@ -60,53 +60,39 @@

Introduction


Basic information about FCEUX and its features.

-


Overview

-


FCE Ultra Version History

-


What's Combined In FCEUX?



Additional Chapters


General

-


Guides for general uses of FCEUX and the FCEUX NES menu.


-


Config

-


Commands under FCEUX Config menu.


-


Tools

-


Commands under FCEUX Tools menu.


-


Debug

-


Commands under FCEUX Debug menu.


-


FAQ / Guides

-


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


-


Technical Information

-


Technical information relating to NES hardware emulation & FCEUX file formats.





-


Help menu created by adelikat.

Updated & recompiled by AnS.

-

Information collected and/or written/edited by adelikat.

-

Minor edits of lua-related text by Leeland Kirwan (FatRatKnight).

+

Information collected and/or written/edited by adelikat and AnS.

+

Minor edits of lua-related text by FatRatKnight.

+

Debugger documentation edits by rainwarrior.


Created with the Personal Edition of HelpNDoc: Free help authoring environment

diff --git a/help/LuaFunctionsList.html b/help/LuaFunctionsList.html index eb9bfe77..f694e9ea 100644 --- a/help/LuaFunctionsList.html +++ b/help/LuaFunctionsList.html @@ -57,17 +57,17 @@

The following functions are available in FCEUX, in addition to standard LUA capabilities:



-

Emu library

+

Emu library


-

emu.poweron()

-


-

Executes a power cycle.

-


-

emu.softreset()

-


-

Executes a (soft) reset.

+

emu.poweron()

+


+

Executes a power cycle.

+


+

emu.softreset()

+


+

Executes a (soft) reset.


-

emu.speedmode(string mode)

+

emu.speedmode(string mode)


Set the emulator to given speed. The mode argument can be one of these:

       - "normal"

@@ -75,64 +75,64 @@

       - "turbo"

       - "maximum"


-

emu.frameadvance()

+

emu.frameadvance()


Advance the emulator by one frame. It's like pressing the frame advance button once.


Most scripts use this function in their main game loop to advance frames. Note that you can also register functions by various methods that run "dead", returning control to the emulator and letting the emulator advance the frame.  For most people, using frame advance in an endless while loop is easier to comprehend so I suggest  starting with that.  This makes more sense when creating bots. Once you move to creating auxillary libraries, try the register() methods.


-

emu.pause()

+

emu.pause()


Pauses the emulator.


-

emu.unpause()

+

emu.unpause()


Unpauses the emulator.


-

emu.exec_count(int count, function func)

+

emu.exec_count(int count, function func)


Calls given function, restricting its working time to given number of lua cycles. Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.


-

emu.exec_time(int time, function func)

+

emu.exec_time(int time, function func)


Windows-only. Calls given function, restricting its working time to given number of milliseconds (approximate). Using this method you can ensure that some heavy operation (like Lua bot) won't freeze FCEUX.


-

emu.setrenderplanes(bool sprites, bool background)

+

emu.setrenderplanes(bool sprites, bool background)


Toggles the drawing of the sprites and background planes. Set to false or nil to disable a pane, anything else will draw them.


-

emu.message(string message)

+

emu.message(string message)


Displays given message on screen in the standard messages position. Use gui.text() when you need to position text.


-

int emu.framecount()

+

int emu.framecount()


Returns the framecount value. The frame counter runs without a movie running so this always returns a value.


-

int emu.lagcount()

+

int emu.lagcount()


Returns the number of lag frames encountered. Lag frames are frames where the game did not poll for input because it missed the vblank. This happens when it has to compute too much within the frame boundary. This returns the number indicated on the lag counter.


-

bool emu.lagged()

+

bool emu.lagged()


Returns true if currently in a lagframe, false otherwise.


-

bool emu.emulating()

+

bool emu.emulating()


Returns true if emulation has started, or false otherwise. Certain operations such as using savestates are invalid to attempt before emulation has started. You probably won't need to use this function unless you want to make your script extra-robust to being started too early.


-

bool emu.paused()

+

bool emu.paused()


Returns true if emulator is paused, false otherwise.


-

bool emu.readonly()

+

bool emu.readonly()

Alias: movie.readonly


Returns whether the emulator is in read-only state.  


While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.


-

emu.setreadonly(bool state)

+

emu.setreadonly(bool state)

Alias: movie.setreadonly


Sets the read-only status to read-only if argument is true and read+write if false.

@@ -140,7 +140,7 @@


While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.


-

emu.registerbefore(function func)

+

emu.registerbefore(function func)


Registers a callback function to run immediately before each frame gets emulated. This runs after the next frame's input is known but before it's used, so this is your only chance to set the next frame's input using the next frame's would-be input. For example, if you want to make a script that filters or modifies ongoing user input, such as making the game think "left" is pressed whenever you press "right", you can do it easily with this.


@@ -148,11 +148,11 @@


Like other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. If you register two callbacks, the second one will replace the first, and the call to emu.registerbefore will return the old callback. You may register nil instead of a function to clear a previously-registered callback. If a script returns while it still has registered callbacks, FCEUX will keep it alive to call those callbacks when appropriate, until either the script is stopped by the user or all of the callbacks are de-registered.


-

emu.registerafter(function func)

+

emu.registerafter(function func)


Registers a callback function to run immediately after each frame gets emulated. It runs at a similar time as (and slightly before) gui.register callbacks, except unlike with gui.register it doesn't also get called again whenever the screen gets redrawn. Similar caveats as those mentioned in emu.registerbefore apply.


-

emu.registerexit(function func)

+

emu.registerexit(function func)


Registers a callback function that runs when the script stops. Whether the script stops on its own or the user tells it to stop, or even if the script crashes or the user tries to close the emulator, FCEUX will try to run whatever Lua code you put in here first. So if you want to make sure some code runs that cleans up some external resources or saves your progress to a file or just says some last words, you could put it here. (Of course, a forceful termination of the application or a crash from inside the registered exit function will still prevent the code from running.)


@@ -160,15 +160,15 @@


Note that restarting a script counts as stopping it and then starting it again, so doing so (either by clicking "Restart" or by editing the script while it is running) will trigger the callback. Note also that returning from a script generally does NOT count as stopping (because your script is still running or waiting to run its callback functions and thus does not stop... see here for more information), even if the exit callback is the only one you have registered.


-

bool emu.addgamegenie(string str)

+

bool emu.addgamegenie(string str)


Adds a Game Genie code to the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be added. Returns true if the code already existed, or if it was added.


Usage: emu.addgamegenie("NUTANT")


Note that the Cheats Dialog Box won't show the code unless you close and reopen it.

-


-

bool emu.delgamegenie(string str)

+


+

bool emu.delgamegenie(string str)


Removes a Game Genie code from the Cheats menu. Returns false and an error message if the code can't be decoded. Returns false if the code couldn't be deleted. Returns true if the code didn't exist, or if it was deleted.


@@ -176,11 +176,11 @@


Note that the Cheats Dialog Box won't show the code unless you close and reopen it.


-

emu.print(string str)

+

emu.print(string str)


Puts a message into the Output Console area of the Lua Script control window. Useful for displaying usage instructions to the user when a script gets run.


-

emu.getscreenpixel(int x, int y, bool getemuscreen)

+

emu.getscreenpixel(int x, int y, bool getemuscreen)


Returns the separate RGB components of the given screen pixel, and the palette. Can be 0-255 by 0-239, but NTSC only displays 0-255 x 8-231 of it. If getemuscreen is false, this gets background colors from either the screen pixel or the LUA pixels set, but LUA data may not match the information used to put the data to the screen. If getemuscreen is true, this gets background colors from anything behind an LUA screen element.


@@ -191,54 +191,54 @@

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



-

FCEU library

+

FCEU library


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



-

ROM Library

+

ROM Library


-

rom.readbyte(int address)

-

rom.readbyteunsigned(int address)

+

rom.readbyte(int address)

+

rom.readbyteunsigned(int address)


Get an unsigned byte from the actual ROM file at the given address.  


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


-

rom.readbytesigned(int address)

+

rom.readbytesigned(int address)


Get a signed byte from the actual ROM file at the given address. Returns a byte that is signed.


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



-

Memory Library

+

Memory Library


-

memory.readbyte(int address)

-

memory.readbyteunsigned(int address)

+

memory.readbyte(int address)

+

memory.readbyteunsigned(int address)


Get an unsigned byte from the RAM at the given address. Returns a byte regardless of emulator. The byte will always be positive.


-

memory.readbyterange(int address, int length)

+

memory.readbyterange(int address, int length)


Get a length bytes starting at the given address and return it as a string. Convert to table to access the individual bytes.


-

memory.readbytesigned(int address)

+

memory.readbytesigned(int address)


Get a signed byte from the RAM at the given address. Returns a byte regardless of emulator. The most significant bit will serve as the sign.


-

memory.writebyte(int address, int value)

+

memory.writebyte(int address, int value)


Write the value to the RAM at the given address. The value is modded with 256 before writing (so writing 257 will actually write 1). Negative values allowed.


-

int memory.getregister(cpuregistername)

+

int memory.getregister(cpuregistername)


Returns the current value of the given hardware register.

For example, memory.getregister("pc") will return the main CPU's current Program Counter.


Valid registers are: "a", "x", "y", "s", "p", and "pc".


-

memory.setregister(string cpuregistername, int value)

+

memory.setregister(string cpuregistername, int value)


Sets the current value of the given hardware register.

For example, memory.setregister("pc",0x200) will change the main CPU's current Program Counter to 0x200.

@@ -246,9 +246,10 @@

Valid registers are: "a", "x", "y", "s", "p", and "pc".


You had better know exactly what you're doing or you're probably just going to crash the game if you try to use this function. That applies to the other memory.write functions as well, but to a lesser extent.

-


-

memory.register(int address, [int size,] function func)

-

memory.registerwrite(int address, [int size,] function func)

+

+

+

memory.register(int address, [int size,] function func)

+

memory.registerwrite(int address, [int size,] function func)


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


@@ -262,9 +263,9 @@


If func is nil that means to de-register any memory write callbacks that the current script has already registered on the given range of bytes.


-

memory.registerexec(int address, [int size,] function func)

-

memory.registerrun(int address, [int size,] function func)

-

memory.registerexecute(int address, [int size,] function func)

+

memory.registerexec(int address, [int size,] function func)

+

memory.registerrun(int address, [int size,] function func)

+

memory.registerexecute(int address, [int size,] function func)


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


@@ -272,11 +273,28 @@


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


+
+ + + +

Example of custom breakpoint:


-

Joypad Library

+

function CounterBreak()

+

ObjCtr = memory.getregister("y")

+

if ObjCtr > 0x16 then

+

gui.text(1,1,string.format("%02X",ObjCtr))

+

emu.pause()

+

end

+

end

+

memory.registerexecute(0x863C, CounterBreak);

+
+


-

table joypad.get(int player)

-

table joypad.read(int player)

+


+

Joypad Library

+


+

table joypad.get(int player)

+

table joypad.read(int player)


Returns a table of every game button, where each entry is true if that button is currently held (as of the last time the emulation checked), or false if it is not held. This takes keyboard inputs, not Lua. The table keys look like this (case sensitive):


@@ -286,25 +304,25 @@


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


-

table joypad.getimmediate(int player)

-

table joypad.readimmediate(int player)

+

table joypad.getimmediate(int player)

+

table joypad.readimmediate(int player)


Returns a table of every game button, where each entry is true if that button is held at the moment of calling the function, or false if it is not held. This function polls keyboard input immediately, allowing Lua to interact with user even when emulator is paused.


As of FCEUX 2.1.6, the function only works in Windows. In Linux this function will return nil.


-

table joypad.getdown(int player)

-

table joypad.readdown(int player)

+

table joypad.getdown(int player)

+

table joypad.readdown(int player)


Returns a table of only the game buttons that are currently held. Each entry is true if that button is currently held (as of the last time the emulation checked), or nil if it is not held.


-

table joypad.getup(int player)

-

table joypad.readup(int player)

+

table joypad.getup(int player)

+

table joypad.readup(int player)


Returns a table of only the game buttons that are not currently held. Each entry is nil if that button is currently held (as of the last time the emulation checked), or false if it is not held.


-

joypad.set(int player, table input)

-

joypad.write(int player, table input)

+

joypad.set(int player, table input)

+

joypad.write(int player, table input)


Set the inputs for the given player. Table keys look like this (case sensitive):


@@ -323,9 +341,9 @@

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



-

Zapper Library

+

Zapper Library


-

table zapper.read()

+

table zapper.read()


Returns the zapper data

When no movie is loaded this input is the same as the internal mouse input (which is used to generate zapper input, as well as the arkanoid paddle).

@@ -338,60 +356,60 @@

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



-

Input Library

+

Input Library


-

table input.get()

-

table input.read()

+

table input.get()

+

table input.read()


Reads input from keyboard and mouse. Returns pressed keys and the position of mouse in pixels on game screen.  The function returns a table with at least two properties; table.xmouse and table.ymouse.  Additionally any of these keys will be set to true if they were held at the time of executing this function:

leftclick, rightclick, middleclick, capslock, numlock, scrolllock, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, F1, F2, F3, F4, F5, F6,  F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, backspace, tab, enter, shift, control, alt, pause, escape, space, pageup, pagedown, end, home, left, up, right, down, numpad0, numpad1, numpad2, numpad3, numpad4, numpad5, numpad6, numpad7, numpad8, numpad9, numpad*, insert, delete, numpad+, numpad-, numpad., numpad/, semicolon, plus, minus, comma, period, slash, backslash, tilde, quote, leftbracket, rightbracket.


-

string input.popup

+

string input.popup

Alias: gui.popup


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



-

Savestate Library

+

Savestate Library


-

object savestate.object(int slot = nil)

+

object savestate.object(int slot = nil)


Create a new savestate object. Optionally you can save the current state to one of the predefined slots(1-10) using the range 1-9 for slots 1-9, and 10 for 0, QWERTY style. Using no number will create an "anonymous" savestate.

Note that this does not actually save the current state! You need to create this value and pass it on to the load and save functions in order to save it.


Anonymous savestates are temporary, memory only states. You can make them persistent by calling memory.persistent(state). Persistent anonymous states are deleted from disk once the script exits.


-

object savestate.create(int slot = nil)

+

object savestate.create(int slot = nil)


savestate.create is identical to savestate.object, except for the numbering for predefined slots(1-10, 1 refers to slot 0, 2-10 refer to 1-9). It's being left in for compatibility with older scripts, and potentially for platforms with different internal predefined slot numbering.


-

savestate.save(object savestate)

+

savestate.save(object savestate)


Save the current state object to the given savestate. The argument is the result of savestate.create(). You can load this state back up by calling savestate.load(savestate) on the same object.


-

savestate.load(object savestate)

+

savestate.load(object savestate)


Load the the given state. The argument is the result of savestate.create() and has been passed to savestate.save() at least once.


If this savestate is not persistent and not one of the predefined states, the state will be deleted after loading.


-

savestate.persist(object savestate)

+

savestate.persist(object savestate)


Set the given savestate to be persistent. It will not be deleted when you load this state but at the exit of this script instead, unless it's one of the predefined states.  If it is one of the predefined savestates it will be saved as a file on disk.


-

savestate.registersave(function func)

+

savestate.registersave(function func)


Registers a callback function that runs whenever the user saves a state. This won't actually be called when the script itself makes a savestate, so none of those endless loops due to a misplaced savestate.save.


As with other callback-registering functions provided by FCEUX, there is only one registered callback at a time per registering function per script. Upon registering a second callback, the first is kicked out to make room for the second. In this case, it will return the first function instead of nil, letting you know what was kicked out. Registering nil will clear the previously-registered callback.


-

savestate.registerload(function func)

+

savestate.registerload(function func)


Registers a callback function that runs whenever the user loads a previously saved state. It's not called when the script itself loads a previous state, so don't worry about your script interrupting itself just because it's loading something.


The state's data is loaded before this function runs, so you can read the RAM immediately after the user loads a state, or check the new framecount. Particularly useful if you want to update lua's display right away instead of showing junk from before the loadstate.


-

savestate.loadscriptdata(int location)

+

savestate.loadscriptdata(int location)


Accuracy not yet confirmed.


@@ -399,17 +417,17 @@

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



-

Movie Library

+

Movie Library


-

bool movie.active()

+

bool movie.active()


Returns true if a movie is currently loaded and false otherwise.  (This should be used to guard against Lua errors when attempting to retrieve movie information).


-

int movie.framecount()

+

int movie.framecount()


Returns the current frame count. (Has the same affect as emu.framecount)


-

string movie.mode()

+

string movie.mode()


Returns the current state of movie playback. Returns one of the following:


@@ -419,41 +437,41 @@

- "taseditor"

- nil


-

movie.rerecordcounting(bool counting)

+

movie.rerecordcounting(bool counting)


Turn the rerecord counter on or off. Allows you to do some brute forcing without inflating the rerecord count.


-

movie.stop()

-

movie.close()

+

movie.stop()

+

movie.close()


Stops movie playback. If no movie is loaded, it throws a Lua error.


-

int movie.length()

+

int movie.length()


Returns the total number of frames of the current movie. Throws a Lua error if no movie is loaded.


-

string movie.name()

-

string movie.getname()

+

string movie.name()

+

string movie.getname()


Returns the filename of the current movie with path. Throws a Lua error if no movie is loaded.


-

movie.getfilename()

+

movie.getfilename()


Returns the filename of the current movie with no path. Throws a Lua error if no movie is loaded.


-

movie.rerecordcount()

+

movie.rerecordcount()


Returns the rerecord count of the current movie. Throws a Lua error if no movie is loaded.


-

movie.replay()

-

movie.playbeginning()

+

movie.replay()

+

movie.playbeginning()


Performs the Play from Beginning function. Movie mode is switched to read-only and the movie loaded will begin playback from frame 1.


If no movie is loaded, no error is thrown and no message appears on screen.


-

bool movie.readonly()

-

bool movie.getreadonly()

+

bool movie.readonly()

+

bool movie.getreadonly()

Alias: emu.getreadonly


FCEUX keeps the read-only status even without a movie loaded.

@@ -462,7 +480,7 @@


While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.


-

movie.setreadonly(bool state)

+

movie.setreadonly(bool state)

Alias: emu.setreadonly


FCEUX keeps the read-only status even without a movie loaded.

@@ -472,45 +490,45 @@


While this variable only applies to movies, it is stored as a global variable and can be modified even without a movie loaded.  Hence, it is in the emu library rather than the movie library.


-

bool movie.recording()

+

bool movie.recording()


Returns true if there is a movie loaded and in record mode.


-

bool movie.playing()

+

bool movie.playing()


Returns true if there is a movie loaded and in play mode.


-

bool movie.ispoweron()

+

bool movie.ispoweron()


Returns true if the movie recording or loaded started from 'Start'.

Returns false if the movie uses a save state.

Opposite of movie.isfromsavestate()


-

bool movie.isfromsavestate()

+

bool movie.isfromsavestate()


Returns true if the movie recording or loaded started from 'Now'.

Returns false if the movie was recorded from a reset.

Opposite of movie.ispoweron()


-

string movie.name()

+

string movie.name()


If a movie is loaded it returns the name of the movie, else it throws an error.


-

bool movie.readonly()

+

bool movie.readonly()


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



-

GUI Library

+

GUI Library


-

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

-

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

-

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

-

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

+

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

+

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

+

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

+

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


Draw one pixel of a given color at the given position on the screen. See drawing notes and color notes at the bottom of the page.  


-

gui.getpixel(int x, int y)

+

gui.getpixel(int x, int y)


Returns the separate RGBA components of the given pixel set by gui.pixel. This only gets LUA pixels set, not background colors.


@@ -518,47 +536,47 @@


See emu.getscreenpixel() for an emulator screen variant.


-

gui.line(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

-

gui.drawline(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

+

gui.line(int x1, int y1, int x2, int y2 [, color [, skipfirst]])

+

gui.drawline(int x1, int y1, int x2, int y2 [, color [, skipfirst]])


Draws a line between the two points. The x1,y1 coordinate specifies one end of the line segment, and the x2,y2 coordinate specifies the other end. If skipfirst is true then this function will not draw anything at the pixel x1,y1, otherwise it will. skipfirst is optional and defaults to false. The default color for the line is solid white, but you may optionally override that using a color of your choice. See also drawing notes and color notes at the bottom of the page.


-

gui.box(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.drawbox(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.rect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

-

gui.drawrect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.box(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.drawbox(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.rect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))

+

gui.drawrect(int x1, int y1, int x2, int y2 [, fillcolor [, outlinecolor]]))


Draws a rectangle between the given coordinates of the emulator screen for one frame. The x1,y1 coordinate specifies any corner of the rectangle (preferably the top-left corner), and the x2,y2 coordinate specifies the opposite corner.


The default color for the box is transparent white with a solid white outline, but you may optionally override those using colors of your choice. Also see drawing notes and color notes.


-

gui.text(int x, int y, string str [, textcolor [, backcolor]])

-

gui.drawtext(int x, int y, string str [, textcolor [, backcolor]])

+

gui.text(int x, int y, string str [, textcolor [, backcolor]])

+

gui.drawtext(int x, int y, string str [, textcolor [, backcolor]])


Draws a given string at the given position. textcolor and backcolor are optional. See 'on colors' at the end of this page for information. Using nil as the input or not including an optional field will make it use the default.


-

gui.parsecolor(color)

+

gui.parsecolor(color)


Returns the separate RGBA components of the given color.

For example, you can say local r,g,b,a = gui.parsecolor('orange') to retrieve the red/green/blue values of the preset color orange. (You could also omit the a in cases like this.) This uses the same conversion method that FCEUX uses internally to support the different representations of colors that the GUI library uses. Overriding this function will not change how FCEUX interprets color values, however.


-

gui.savescreenshot()

+

gui.savescreenshot()

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. Performs identically to pressing the Screenshot hotkey.


-

gui.savescreenshotas(string name)

+

gui.savescreenshotas(string name)

Makes a screenshot of the FCEUX emulated screen, and saves it to the appropriate folder. However, this one receives a file name for the screenshot.

-

string gui.gdscreenshot()

+

string gui.gdscreenshot()


Takes a screen shot of the image and returns it in the form of a string which can be imported by the gd library using the gd.createFromGdStr() function.


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


-

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

+

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


-

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

-

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

-

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

+

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

+

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

+

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


Draws an image on the screen. gdimage must be in truecolor gd string format.


@@ -572,20 +590,20 @@

local gdstr = gd.createFromPng("myimage.png"):gdStr()

gui.gdoverlay(gdstr)


-

gui.opacity(int alpha)

+

gui.opacity(int alpha)


Scales the transparency of subsequent draw calls. An alpha of 0.0 means completely transparent, and an alpha of 1.0 means completely unchanged (opaque). Non-integer values are supported and meaningful, as are values greater than 1.0. It is not necessary to use this function (or the less-recommended gui.transparency) to perform drawing with transparency, because you can provide an alpha value in the color argument of each draw call. However, it can sometimes be convenient to be able to globally modify the drawing transparency.


-

gui.transparency(int trans)

+

gui.transparency(int trans)


Scales the transparency of subsequent draw calls. Exactly the same as gui.opacity, except the range is different: A trans of 4.0 means completely transparent, and a trans of 0.0 means completely unchanged (opaque).


-

function gui.register(function func)

-


+

function gui.register(function func)

+


Register a function to be called between a frame being prepared for displaying on your screen and it actually happening. Used when that 1 frame delay for rendering is not acceptable.


-

string gui.popup(string message [, string type = "ok" [, string icon = "message"]])

-

string input.popup(string message [, string type = "yesno" [, string icon = "question"]])

+

string gui.popup(string message [, string type = "ok" [, string icon = "message"]])

+

string input.popup(string message [, string type = "yesno" [, string icon = "question"]])


Brings up a modal popup dialog box (everything stops until the user dismisses it). The box displays the message tostring(msg). This function returns the name of the button the user clicked on (as a string).


@@ -600,9 +618,9 @@

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



-

Sound Library

+

Sound Library


-

table sound.get()

+

table sound.get()


Returns current state of PSG channels in big array.


@@ -671,59 +689,59 @@

}



-

TAS Editor Library

-


-

taseditor.registerauto(function func)

-

taseditor.registermanual(function func)

-

bool taseditor.engaged()

-

bool taseditor.markedframe(int frame)

-

int taseditor.getmarker(int frame)

-

int taseditor.setmarker(int frame)

-

taseditor.clearmarker(int frame)

-

string taseditor.getnote(int index)

-

taseditor.setnote(int index, string newtext)

-

int taseditor.getcurrentbranch()

-

string taseditor.getrecordermode()

-

int taseditor.getsuperimpose()

-

int taseditor.getlostplayback()

-

int taseditor.getplaybacktarget()

-

taseditor.setplayback(int frame)

-

taseditor.stopseeking()

-

taseditor.getselection()

-

taseditor.setselection()

-

int taseditor.getinput(int frame, int joypad)

-

taseditor.submitinputchange(int frame, int joypad, int input)

-

taseditor.submitinsertframes(int frame, int number)

-

taseditor.submitdeleteframes(int frame, int number)

-

int taseditor.applyinputchanges([string name])

-

taseditor.clearinputchanges()

+

TAS Editor Library

+


+

taseditor.registerauto(function func)

+

taseditor.registermanual(function func)

+

bool taseditor.engaged()

+

bool taseditor.markedframe(int frame)

+

int taseditor.getmarker(int frame)

+

int taseditor.setmarker(int frame)

+

taseditor.clearmarker(int frame)

+

string taseditor.getnote(int index)

+

taseditor.setnote(int index, string newtext)

+

int taseditor.getcurrentbranch()

+

string taseditor.getrecordermode()

+

int taseditor.getsuperimpose()

+

int taseditor.getlostplayback()

+

int taseditor.getplaybacktarget()

+

taseditor.setplayback(int frame)

+

taseditor.stopseeking()

+

taseditor.getselection()

+

taseditor.setselection()

+

int taseditor.getinput(int frame, int joypad)

+

taseditor.submitinputchange(int frame, int joypad, int input)

+

taseditor.submitinsertframes(int frame, int number)

+

taseditor.submitdeleteframes(int frame, int number)

+

int taseditor.applyinputchanges([string name])

+

taseditor.clearinputchanges()


For full description of these functions refer to TAS Editor Manual.



-

Bitwise Operations

+

Bitwise Operations


-

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

+

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


-

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

-


+

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

+


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


-

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

+

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


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


-

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

+

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


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


-

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

+

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


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


-

Appendix

+

Appendix


-

On drawing

+

On drawing


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


@@ -731,7 +749,7 @@

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

256x224, 8bit color (confirm?)


-

On colors

+

On colors


Colors can be of a few types.

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

diff --git a/help/LuaGettingStarted.html b/help/LuaGettingStarted.html index 25c5e5f6..513a08a5 100644 --- a/help/LuaGettingStarted.html +++ b/help/LuaGettingStarted.html @@ -52,19 +52,19 @@
-

Using Lua scripting

+

Using Lua scripting


Lua is built into FCEUX as of 2.1.2, and luapack DLL files are no longer needed in this and later versions.


To run lua scripts in older versions of FCEUX, you will need the lua pack which can be found here. The .dll files must be unzipped in the same folder as fceux.exe.

-


-

Core Lua Documentation

+


+

Core Lua Documentation


If you have never programmed, you will probably want to start by learning the basic of Lua, which is too broad for the scope of this help file.  Try searching on the Internet for "Lua tutorial".  As of this writing, it's official homepage is http://www.lua.org/


If you are familiar with any programming language you will probably not have too much difficulty adjusting to the syntax and structure of Lua.  You will probably also find useful information on the Internet.

-


-

GUI Frontend

+


+

GUI Frontend


To use a Lua script, you need to create one in a text editor.  The name of the file created should end in .lua to indicate that it is a Lua script.


@@ -72,7 +72,7 @@


To end a Lua script, choose "Stop Lua Script" ***from where***.


-

FCEUX Lua Basics

+

FCEUX Lua Basics


Your script will be constructed according to the rules of Lua, but you will use FCEUX-specific functions to interact with the emulator.  For example, one of the most often-used functions is emu.frameadvance() which will tell the emulator to advance exactly one frame, which is the basic unit of time on an NES.


diff --git a/help/LuaScripting.html b/help/LuaScripting.html index 3794afe6..43abc46c 100644 --- a/help/LuaScripting.html +++ b/help/LuaScripting.html @@ -57,19 +57,19 @@

A bit of previous programming knowledge will be useful in taking advantage of this feature, but it is certainly not a requirement.  Lua is specifically written with the intention of being easier than most languages for anyone to understand and use.



-

Getting Started

+

Getting Started


The basics of Lua scripting, its implementation into FCEUX, and how to get started using Lua.


-

Using Lua

+

Using Lua


How to use Lua and basic syntax/commands that are useable under FCEUX.


-

Lua Functions List

+

Lua Functions List


A list of Lua functions available in FCEUX and a brief description of each.


-

Lua Bot

+

Lua Bot


How to use Luau's version of Basic bot.

Created with the Personal Edition of HelpNDoc: Free iPhone documentation generator

diff --git a/help/NESRAMMappingFindingValues.html b/help/NESRAMMappingFindingValues.html index c37f2af2..f9e0e312 100644 --- a/help/NESRAMMappingFindingValues.html +++ b/help/NESRAMMappingFindingValues.html @@ -45,7 +45,7 @@ Previous - Next + Next
@@ -228,7 +228,7 @@

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


Block 4

-

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

+

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

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

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

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

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

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

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


-

Device                                 Triangle Noise  Square

-

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

-

triangle step generator                        X

-

linear counter                                X

-

programmable timer                        X      X      X

-

length counter                                X      X      X

-

4-bit DAC                                        X      X      X

-

volume/envelope decay unit                         X      X

-

sweep unit                                                          X

-

duty cycle generator                                          X

-

wavelength converter                                 X

-

random number generator                                 X

+

Device                                 Triangle Noise  Square

+

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

+

triangle step generator                        X

+

linear counter                                X

+

programmable timer                        X      X      X

+

length counter                                X      X      X

+

4-bit DAC                                        X      X      X

+

volume/envelope decay unit                         X      X

+

sweep unit                                                          X

+

duty cycle generator                                          X

+

wavelength converter                                 X

+

random number generator                                 X



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

diff --git a/help/Technicalinformation.html b/help/Technicalinformation.html index 444df6e7..2f9a6b52 100644 --- a/help/Technicalinformation.html +++ b/help/Technicalinformation.html @@ -39,7 +39,7 @@
- Previous + Previous Next diff --git a/help/TraceLogger.html b/help/TraceLogger.html index 280013d8..6a102e6e 100644 --- a/help/TraceLogger.html +++ b/help/TraceLogger.html @@ -52,7 +52,7 @@
-

Trace Logger

+

Trace Logger


Introduction


diff --git a/help/WhatsNew216.html b/help/WhatsNew216.html index 1294bfc2..69b445c4 100644 --- a/help/WhatsNew216.html +++ b/help/WhatsNew216.html @@ -77,7 +77,7 @@
  • Newppu - fix bug in scroll reg logic causing mis-scrolls in p'radikus conflict
  • A bit of latest mapper changes from fceu-mm
  • Fixed mappers 242, 227, 115, 248, 12, 164, 15, 253, 23, 178
  • -
  • Added mappers 176, 116
  • +
  • Added mappers 176, 116, 156
  • Straighten out bandai m159/m016 handling and add valid null-EEPROM emulation to get those games booting.
  • Add ability for CNROM games to choose whether they have bus conflicts (fixes Colorful Dragon (Unl) (Sachen), since it flakes out if bus conflicts are emulated)
  • Fixed bus conflict emulation, no kage no densetsu bug anymore
  • @@ -87,6 +87,7 @@

    Movies


    Trace Logger

    diff --git a/help/css/hnd.css b/help/css/hnd.css index 7ef14aa7..e53e13dd 100644 --- a/help/css/hnd.css +++ b/help/css/hnd.css @@ -230,128 +230,138 @@ a.rvts44, span.rvts44 text-decoration: underline; } a.rvts44:hover { color: #0000ff; } -span.rvts45 +span.rvts45 /* Font Style */ +{ + font-size: 18pt; +} +span.rvts46 +{ + font-size: 11pt; + font-weight: bold; +} +span.rvts47 { font-size: 22pt; text-decoration: underline; } -a.rvts46, span.rvts46 +a.rvts48, span.rvts48 { font-size: 12pt; color: #0000ff; text-decoration: underline; } -a.rvts46:hover { color: #0000ff; } -span.rvts47 -{ - font-size: 18pt; - font-weight: bold; -} -span.rvts48 -{ - font-size: 12pt; - font-family: 'Courier New', 'Courier', monospace; - font-weight: bold; -} +a.rvts48:hover { color: #0000ff; } span.rvts49 { - font-size: 14pt; + font-size: 18pt; font-weight: bold; } span.rvts50 { font-size: 12pt; font-family: 'Courier New', 'Courier', monospace; - color: #000080; + font-weight: bold; } span.rvts51 { - font-size: 12pt; - font-family: 'Courier New', 'Courier', monospace; - color: #333399; + font-size: 14pt; + font-weight: bold; } span.rvts52 { + font-size: 12pt; font-family: 'Courier New', 'Courier', monospace; color: #000080; } span.rvts53 { - font-size: 16pt; + font-size: 12pt; font-family: 'Courier New', 'Courier', monospace; - font-weight: bold; + color: #333399; } span.rvts54 { - font-size: 11pt; font-family: 'Courier New', 'Courier', monospace; - font-weight: bold; + color: #000080; } span.rvts55 { + font-size: 16pt; font-family: 'Courier New', 'Courier', monospace; font-weight: bold; } span.rvts56 { + font-size: 11pt; font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; } span.rvts57 +{ + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; +} +span.rvts58 +{ + font-family: 'Courier New', 'Courier', monospace; +} +span.rvts59 { font-size: 12pt; font-family: 'Courier New', 'Courier', monospace; color: #000080; } -a.rvts58, span.rvts58 +a.rvts60, span.rvts60 { font-family: 'Courier New', 'Courier', monospace; color: #0000ff; text-decoration: underline; } -a.rvts58:hover { color: #0000ff; } -span.rvts59 +a.rvts60:hover { color: #0000ff; } +span.rvts61 { font-size: 14pt; font-weight: bold; } -span.rvts60 /* Font Style */ +span.rvts62 /* Font Style */ { font-size: 14pt; } -a.rvts61, span.rvts61 +span.rvts63 +{ + font-family: 'Courier New', 'Courier', monospace; + font-weight: bold; + text-decoration: underline; +} +a.rvts64, span.rvts64 { font-size: 12pt; color: #0000ff; text-decoration: underline; } -a.rvts61:hover { color: #0000ff; } -span.rvts62 +a.rvts64:hover { color: #0000ff; } +span.rvts65 { font-family: 'Lucida Console', 'Monaco', monospace; text-decoration: underline; } -span.rvts63 -{ - font-weight: bold; - text-decoration: underline; -} -span.rvts64 -{ - font-size: 11pt; - text-decoration: underline; -} -span.rvts65 -{ - font-size: 5pt; -} span.rvts66 { - font-size: 5pt; font-weight: bold; + text-decoration: underline; } span.rvts67 { font-size: 11pt; + text-decoration: underline; +} +span.rvts68 +{ + font-size: 5pt; +} +span.rvts69 +{ + font-size: 5pt; font-weight: bold; } /* ========== Para Styles ========== */ @@ -383,3 +393,12 @@ p,ul,ol /* Paragraph Style */ .rvps4 /* Paragraph Style */ { } +.rvps5 +{ + text-indent: 48px; +} +.rvps6 +{ + text-indent: 48px; + margin: 0px 0px 0px 48px; +} diff --git a/help/fm2.html b/help/fm2.html index 2299caf5..c050cc2e 100644 --- a/help/fm2.html +++ b/help/fm2.html @@ -86,41 +86,41 @@

    Integer keys (also used for booleans, with a 1 for true and 0 for false) must have a value that can be stored as int32:


    - version (required) - the version of the movie file format; for now it is always 3

    -


    +


    - emuVersion (required) - the version of the emulator used to produce the movie

    -


    +


    - rerecordCount (optional) - the rerecord count

    -


    +


    - palFlag (bool) (optional) - true if the movie uses PAL timing

    -


    +


    - NewPPU (bool) (optional) - true if the movie uses New PPU

    -


    +


    - FDS (bool) (optional) - true if movie was recorded on a Famicom Disk System (FDS) game

    -


    +


    - fourscore (bool) - true if a fourscore was used. If fourscore is not used, then port0 and port1 are required

    -


    +


    - port0 - indicates the type of input device attached to the port 0. Supported values are:

        SI_NONE = 0

        SI_GAMEPAD = 1

        SI_ZAPPER = 2

    -


    +


    - port1 - indicates the type of input device attached to the port 1. Supported values are:

        SI_NONE = 0

        SI_GAMEPAD = 1

        SI_ZAPPER = 2

    -


    +


    - port2 (required) - indicates the type of the FCExp port device which was attached. Supported values are:

        SIFC_NONE = 0

    -


    +


    - binary (bool) (optional) - true if input log is stored in binary format

    -


    -

    - length (optional) - movie size (number of frames in the input log). If this key is specified and the number is >= 0, the input log ends after specified number of records, and any remaining data should not be parsed. This key is used in fm3 format to allow storing extra data after the end of input log

    +


    +

    - length (optional) - movie size (number of frames in the input log). If this key is specified and the number is >= 0, the input log ends after specified number of records, and any remaining data should not be parsed. This key is used in fm3 format to allow storing extra data after the end of input log



    String keys have values that consist of the remainder of the key-value pair line. As a consequence, string values cannot contain newlines.


    - romFilename (required) - the name of the file used to record the movie

    -


    +


    - comment (optional) - simply a memo