diff --git a/desmume/src/addons/slot2_paddle.cpp b/desmume/src/addons/slot2_paddle.cpp
new file mode 100644
index 000000000..c5a19d90d
--- /dev/null
+++ b/desmume/src/addons/slot2_paddle.cpp
@@ -0,0 +1,144 @@
+/* Copyright (C) 2011 DeSmuME team
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the this software. If not, see .
+*/
+
+/*
+this device seems to have a 12bit value (like 20.12 fixed point.. get it?) located at 0x0A000000
+clockwise = right = increases.
+it returns the correct little endian bytes through byte reads.
+through halfword reads, it returns the LSB twice
+through full word reads, it returns the LSB four times.
+after that everything is 0x00.
+if the slot2 timings are wrong, then this device will return glitchy or 0xFF output.
+so this emulation code will attempt to validate that.
+arkanoid was setting REG_EXMEMCNT = 0x082F
+
+the rom returns 0xEFFF for all addresses and should be used to detect this device
+
+writing any byte to SRAM or writing any halfword/word to rom results in a reset or some kind of recalibrate
+the resulting value may be 0x000,0x001, or 0xFFF. seems mostly random, though once it is reset, resetting again won't change it.
+you must wait until the paddle has been moved.
+
+conclusion:
+The emulation in all the handling of erroneous cases is not perfect, and some other users of the paddle (do any other games use it?)
+maybe legally configure the paddle differently, which could be rejected here; in which case this code will need finetuning
+*/
+
+#include "../addons.h"
+#include
+#include "NDSSystem.h"
+
+static BOOL init(void) { return (TRUE); }
+static void reset(void)
+{
+}
+
+static void calibrate()
+{
+ nds.paddle = 0;
+}
+
+static void close(void) {}
+static void config(void) {}
+static void write08(u32 procnum, u32 adr, u8 val)
+{
+ if(adr<0x0A000000) return;
+ calibrate();
+}
+static void write16(u32 procnum, u32 adr, u16 val)
+{
+ if(adr<0x0A000000) { calibrate(); return; }
+}
+static void write32(u32 procnum, u32 adr, u32 val)
+{
+ if(adr<0x0A000000) { calibrate(); return; }
+}
+extern int currFrameCounter;
+
+static bool Validate(u32 procnum, bool rom) {
+ if(rom)
+ return ValidateSlot2Access(procnum,0,0,0,-1);
+ else
+ return ValidateSlot2Access(procnum,18,0,0,1);
+}
+static u8 read08(u32 procnum, u32 adr)
+{
+ //printf("paddle: read 08 at 0x%08X\n", adr);
+ if(!Validate(procnum,adr<0x0A000000))
+ return 0xFF;
+
+ if(adr<0x0A000000)
+ {
+ if(adr&1) return 0xFF;
+ else return 0xEF;
+ }
+
+ if(adr==0x0A000000)
+ {
+ return nds.paddle&0xFF;
+ }
+ if(adr==0x0A000001)
+ {
+ return (nds.paddle>>8)&0x0F;
+ }
+ return 0x00;
+}
+static u16 read16(u32 procnum, u32 adr)
+{
+ //printf("paddle : read 16 at 0x%08X\n", adr);
+ if(!Validate(procnum,adr<0x0A000000))
+ return 0xFFFF;
+
+ if(adr<0x0A000000)
+ return 0xEFFF;
+ if(adr==0x0A000000)
+ {
+ u8 val = nds.paddle&0xFF;
+ return val|(val<<8);
+ }
+
+ return 0x0000;
+}
+static u32 read32(u32 procnum, u32 adr)
+{
+ //printf("paddle: read 32 at 0x%08X\n", adr);
+ if(!Validate(procnum,adr<0x0A000000))
+ return 0xFFFFFFFF;
+
+ if(adr<0x0A000000)
+ return 0xEFFFEFFF;
+ if(adr==0x0A000000)
+ {
+ u8 val = nds.paddle&0xFF;
+ return val|(val<<8)|(val<<16)|(val<<24);
+ }
+
+ return 0x00000000;
+}
+static void info(char *info) { strcpy(info, "Paddle"); }
+
+ADDONINTERFACE addonPaddle = {
+ "Paddle",
+ init,
+ reset,
+ close,
+ config,
+ write08,
+ write16,
+ write32,
+ read08,
+ read16,
+ read32,
+ info};