aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ds/arm7
diff options
context:
space:
mode:
authorMax Horn2006-07-09 11:47:17 +0000
committerMax Horn2006-07-09 11:47:17 +0000
commitbea72e9514a5b3ced091d952762a5fa633e27740 (patch)
treec697df47b449a0952c2bb18f10502cae8ae3d939 /backends/platform/ds/arm7
parent51ad5aa7197b3ced348ae37e2bc1586cb25dff3e (diff)
downloadscummvm-rg350-bea72e9514a5b3ced091d952762a5fa633e27740.tar.gz
scummvm-rg350-bea72e9514a5b3ced091d952762a5fa633e27740.tar.bz2
scummvm-rg350-bea72e9514a5b3ced091d952762a5fa633e27740.zip
Patch #1519399: DS Backend
svn-id: r23452
Diffstat (limited to 'backends/platform/ds/arm7')
-rw-r--r--backends/platform/ds/arm7/Makefile436
-rw-r--r--backends/platform/ds/arm7/source/main.cpp1130
2 files changed, 1566 insertions, 0 deletions
diff --git a/backends/platform/ds/arm7/Makefile b/backends/platform/ds/arm7/Makefile
new file mode 100644
index 0000000000..349de22427
--- /dev/null
+++ b/backends/platform/ds/arm7/Makefile
@@ -0,0 +1,436 @@
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output, if this ends with _mb generates a multiboot image
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# INCLUDES is a list of directories containing extra header files
+#---------------------------------------------------------------------------------
+TARGET := arm7
+BUILD := build
+SOURCES := gfx source data
+INCLUDES := include build
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH := -mthumb-interwork
+
+# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
+# *insists* it has a FPU or VFP, and it won't take no for an answer!
+CFLAGS := -g -Wall -O2\
+ -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
+ -ffast-math \
+ $(ARCH)
+
+CFLAGS += $(INCLUDE) -DARM7
+
+CXXFLAGS := $(CFLAGS) -fno-exceptions -fno-rtti
+ASFLAGS := -g $(ARCH)
+LDFLAGS := -g $(ARCH) -mno-fpu
+
+#---------------------------------------------------------------------------------
+# path to tools - this can be deleted if you set the path in windows
+#---------------------------------------------------------------------------------
+# export PATH := /d/dev/ds/devkitARM_r11/bin:/bin
+
+#---------------------------------------------------------------------------------
+# PATH to ndslib - just make a system variable called NDSLIBPATH and be done with it
+#---------------------------------------------------------------------------------
+# NDSLIBPATH := /d/dev/ds/ndslib/
+
+#---------------------------------------------------------------------------------
+# the prefix on the compiler executables
+#---------------------------------------------------------------------------------
+PREFIX := arm-eabi-
+#---------------------------------------------------------------------------------
+# any extra libraries we wish to link with the project
+#---------------------------------------------------------------------------------
+LIBS := -lnds7
+
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS := $(DEVKITPRO)/libnds
+
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+
+export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
+
+export CC := $(PREFIX)gcc
+export CXX := $(PREFIX)g++
+export AR := $(PREFIX)ar
+export OBJCOPY := $(PREFIX)objcopy
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+export LD := $(CXX)
+#export LD := $(CC)
+
+CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+PCXFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcx)))
+BINFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))
+PALFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pal)))
+RAWFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.raw)))
+MAPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.map)))
+
+export OFILES := $(MAPFILES:.map=.o) $(RAWFILES:.raw=.o) $(PALFILES:.pal=.o) $(BINFILES:.bin=.o) $(PCXFILES:.pcx=.o)\
+ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+
+export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) -I- -I$(CURDIR)/../commoninclude\
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include/NDS)\
+ -I$(CURDIR)/$(BUILD)
+
+export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
+
+.PHONY: $(BUILD) clean
+
+#---------------------------------------------------------------------------------
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+ @echo clean ...$(TARGET)
+ @rm -fr $(BUILD) *.bin
+
+
+#---------------------------------------------------------------------------------
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+
+$(OUTPUT).bin : $(OUTPUT).elf
+
+$(OUTPUT).elf : $(OFILES)
+
+
+
+#---------------------------------------------------------------------------------
+%.bin: %.elf
+ @echo built ... $(notdir $@)
+ @$(OBJCOPY) -O binary $(TARGET).elf $@
+
+#---------------------------------------------------------------------------------
+%.elf:
+ echo ELF
+ @$(LD) $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf
+
+
+
+#---------------------------------------------------------------------------------
+# Compile Targets for C/C++
+#---------------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------------
+%.o : %.cpp
+ @echo $(notdir $<)
+ @echo $(CXX) -MM $(CXXFLAGS) -o $*.d $<
+ @$(CXX) -MM $(CXXFLAGS) -o $*.d $<
+ @$(CXX) $(CXXFLAGS) -c $< -o$@
+
+#---------------------------------------------------------------------------------
+%.o : %.c
+ @echo $(notdir $<)
+ @$(CC) -MM $(CFLAGS) -o $*.d $<
+ @$(CC) $(CFLAGS) -c $< -o$@
+
+#---------------------------------------------------------------------------------
+%.o : %.s
+ @echo $(notdir $<)
+ @$(CC) -MM $(CFLAGS) -o $*.d $<
+ @$(CC) $(ASFLAGS) -c $< -o$@
+
+define bin2o
+ cp $(<) $(*).tmp
+ $(OBJCOPY) -I binary -O elf32-littlearm -B arm \
+ --rename-section .data=.rodata \
+ --redefine-sym _binary_$*_tmp_start=$*\
+ --redefine-sym _binary_$*_tmp_end=$*_end\
+ --redefine-sym _binary_$*_tmp_size=$*_size\
+ $(*).tmp $(@)
+ echo "extern const u8" $(*)"[];" > $(*).h
+ echo "extern const u32" $(*)_size[]";" >> $(*).h
+ rm $(*).tmp
+endef
+
+#---------------------------------------------------------------------------------
+%.o : %.pcx
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.bin
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.raw
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.pal
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.map
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.mdl
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------------
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output, if this ends with _mb generates a multiboot image
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# INCLUDES is a list of directories containing extra header files
+#---------------------------------------------------------------------------------
+TARGET := arm7
+BUILD := build
+SOURCES := gfx source data
+INCLUDES := include build
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH := -mthumb-interwork
+
+# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
+# *insists* it has a FPU or VFP, and it won't take no for an answer!
+CFLAGS := -g -Wall -O2\
+ -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
+ -ffast-math \
+ $(ARCH)
+
+CFLAGS += $(INCLUDE) -DARM7
+
+CXXFLAGS := $(CFLAGS) -fno-exceptions -fno-rtti
+ASFLAGS := -g $(ARCH)
+LDFLAGS := -g $(ARCH) -mno-fpu
+
+#---------------------------------------------------------------------------------
+# path to tools - this can be deleted if you set the path in windows
+#---------------------------------------------------------------------------------
+# export PATH := /d/dev/ds/devkitARM_r11/bin:/bin
+
+#---------------------------------------------------------------------------------
+# PATH to ndslib - just make a system variable called NDSLIBPATH and be done with it
+#---------------------------------------------------------------------------------
+# NDSLIBPATH := /d/dev/ds/ndslib/
+
+#---------------------------------------------------------------------------------
+# the prefix on the compiler executables
+#---------------------------------------------------------------------------------
+PREFIX := arm-eabi-
+#---------------------------------------------------------------------------------
+# any extra libraries we wish to link with the project
+#---------------------------------------------------------------------------------
+LIBS := -lnds7
+
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS := $(DEVKITPRO)/libnds
+
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+
+export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
+
+export CC := $(PREFIX)gcc
+export CXX := $(PREFIX)g++
+export AR := $(PREFIX)ar
+export OBJCOPY := $(PREFIX)objcopy
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+export LD := $(CXX)
+#export LD := $(CC)
+
+CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+PCXFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcx)))
+BINFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin)))
+PALFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pal)))
+RAWFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.raw)))
+MAPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.map)))
+
+export OFILES := $(MAPFILES:.map=.o) $(RAWFILES:.raw=.o) $(PALFILES:.pal=.o) $(BINFILES:.bin=.o) $(PCXFILES:.pcx=.o)\
+ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+
+export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) -I- -I$(CURDIR)/../commoninclude\
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include/NDS)\
+ -I$(CURDIR)/$(BUILD)
+
+export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
+
+.PHONY: $(BUILD) clean
+
+#---------------------------------------------------------------------------------
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+ @echo clean ...$(TARGET)
+ @rm -fr $(BUILD) *.bin
+
+
+#---------------------------------------------------------------------------------
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+
+$(OUTPUT).bin : $(OUTPUT).elf
+
+$(OUTPUT).elf : $(OFILES)
+
+
+
+#---------------------------------------------------------------------------------
+%.bin: %.elf
+ @echo built ... $(notdir $@)
+ @$(OBJCOPY) -O binary $(TARGET).elf $@
+
+#---------------------------------------------------------------------------------
+%.elf:
+ echo ELF
+ @$(LD) $(LDFLAGS) -specs=ds_arm7.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $(TARGET).elf
+
+
+
+#---------------------------------------------------------------------------------
+# Compile Targets for C/C++
+#---------------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------------
+%.o : %.cpp
+ @echo $(notdir $<)
+ @echo $(CXX) -MM $(CXXFLAGS) -o $*.d $<
+ @$(CXX) -MM $(CXXFLAGS) -o $*.d $<
+ @$(CXX) $(CXXFLAGS) -c $< -o$@
+
+#---------------------------------------------------------------------------------
+%.o : %.c
+ @echo $(notdir $<)
+ @$(CC) -MM $(CFLAGS) -o $*.d $<
+ @$(CC) $(CFLAGS) -c $< -o$@
+
+#---------------------------------------------------------------------------------
+%.o : %.s
+ @echo $(notdir $<)
+ @$(CC) -MM $(CFLAGS) -o $*.d $<
+ @$(CC) $(ASFLAGS) -c $< -o$@
+
+define bin2o
+ cp $(<) $(*).tmp
+ $(OBJCOPY) -I binary -O elf32-littlearm -B arm \
+ --rename-section .data=.rodata \
+ --redefine-sym _binary_$*_tmp_start=$*\
+ --redefine-sym _binary_$*_tmp_end=$*_end\
+ --redefine-sym _binary_$*_tmp_size=$*_size\
+ $(*).tmp $(@)
+ echo "extern const u8" $(*)"[];" > $(*).h
+ echo "extern const u32" $(*)_size[]";" >> $(*).h
+ rm $(*).tmp
+endef
+
+#---------------------------------------------------------------------------------
+%.o : %.pcx
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.bin
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.raw
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.pal
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.map
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+#---------------------------------------------------------------------------------
+%.o : %.mdl
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#--------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp
new file mode 100644
index 0000000000..f5518be647
--- /dev/null
+++ b/backends/platform/ds/arm7/source/main.cpp
@@ -0,0 +1,1130 @@
+/* ScummVMDS - Scumm Interpreter DS Port
+ * Copyright (C) 2002-2004 The ScummVM project and Neil Millstone
+ *
+ * This program 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 program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header: /cvsroot/scummvm/scummvm/backends/fs/fs.cpp,v 1.3.2.1 2004/12/18 02:33:52 fingolfin Exp $
+ */
+
+//////////////////////////////////////////////////////////////////////
+// Simple ARM7 stub (sends RTC, TSC, and X/Y data to the ARM 9)
+// -- joat
+// -- modified by Darkain and others
+//////////////////////////////////////////////////////////////////////
+
+
+#include <nds.h>
+
+#include <bios.h>
+#include <arm7/touch.h>
+#include <arm7/clock.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nds/scummvm_ipc.h>
+//////////////////////////////////////////////////////////////////////
+
+
+#define TOUCH_CAL_X1 (*(vs16*)0x027FFCD8)
+#define TOUCH_CAL_Y1 (*(vs16*)0x027FFCDA)
+#define TOUCH_CAL_X2 (*(vs16*)0x027FFCDE)
+#define TOUCH_CAL_Y2 (*(vs16*)0x027FFCE0)
+#define SCREEN_WIDTH 256
+#define SCREEN_HEIGHT 192
+s32 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
+s32 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
+s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH -60) * TOUCH_CAL_X1) / TOUCH_WIDTH ) - 28;
+s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT-60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;
+
+vu8* soundData;
+
+vu8* soundBuffer;
+vu8* arm9Buffer;
+bool soundFilled[4];
+
+int playingSection;
+
+bool needSleep = false;
+int temp;
+
+int adpcmBufferNum = 0;
+
+// those are pixel positions of the two points you click when calibrating
+#define TOUCH_CNTRL_X1 (*(vu8*)0x027FFCDC)
+#define TOUCH_CNTRL_Y1 (*(vu8*)0x027FFCDD)
+#define TOUCH_CNTRL_X2 (*(vu8*)0x027FFCE2)
+#define TOUCH_CNTRL_Y2 (*(vu8*)0x027FFCE3)
+
+
+//////////////////////////////////////////////////////////////////////
+
+/*
+void startSound(int sampleRate, const void* data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = (uint32)data;
+ SCHANNEL_LENGTH(channel) = bytes;
+ SCHANNEL_CR(channel) = SOUND_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
+}
+
+
+s8 getFreeSoundChannel() {
+ for (int i=0; i<16; i++) {
+ if ( (SCHANNEL_CR(i) & SOUND_ENABLE) == 0 ) return i;
+ }
+ return -1;
+}
+*/
+
+
+s8 getFreeSoundChannel() {
+// return 0;
+ for (int i=0; i<16; i++) {
+ if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 ) return i;
+ }
+ return -1;
+}
+
+void startSound(int sampleRate, const void* data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
+ REG_IME = IME_DISABLE;
+
+ channel = getFreeSoundChannel();
+/* if (format == 2) {
+ channel = 1;
+ } else {
+ channel = 0;
+ }*/
+
+ if (channel > 1) channel = 1;
+
+ bytes &= ~7; // Multiple of 4 bytes!
+// bytes += 4;
+
+ SCHANNEL_CR(channel) = 0;
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = ((uint32) (data));
+ SCHANNEL_LENGTH(channel) = ((bytes & 0x7FFFFFFF) >> 2);
+ SCHANNEL_REPEAT_POINT(channel) = 0;
+
+ SCHANNEL_CR(channel + 2) = 0;
+ SCHANNEL_TIMER(channel + 2) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel + 2) = ((uint32) (data));
+ SCHANNEL_LENGTH(channel + 2) = ((bytes & 0x7FFFFFFF) >> 2);
+ SCHANNEL_REPEAT_POINT(channel + 2) = 0;
+
+ uint32 flags = SCHANNEL_ENABLE | SOUND_VOL(vol) | SOUND_PAN(pan);
+
+ switch (format) {
+ case 1: {
+ flags |= SOUND_8BIT;
+ flags |= SOUND_REPEAT;// | (1 << 15);
+ break;
+ }
+
+ case 0: {
+ flags |= SOUND_16BIT;
+ flags |= SOUND_REPEAT;// | (1 << 15);
+ break;
+ }
+
+ case 2: {
+ flags |= SOUND_FORMAT_ADPCM;
+ flags |= SOUND_ONE_SHOT;// | (1 << 15);
+
+ SCHANNEL_SOURCE(channel) = (unsigned int) IPC->adpcm.buffer[0];
+ //bytes += 32;
+ SCHANNEL_LENGTH(channel) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
+
+ SCHANNEL_CR(channel + 1) = 0;
+ SCHANNEL_SOURCE(channel + 1) = (unsigned int) IPC->adpcm.buffer[0];
+ SCHANNEL_LENGTH(channel + 1) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
+ SCHANNEL_TIMER(channel + 1) = SOUND_FREQ(sampleRate);
+ SCHANNEL_REPEAT_POINT(channel + 1) = 0;
+ SCHANNEL_CR(channel + 1) = flags;
+ temp = bytes;
+ adpcmBufferNum = 0;
+ break;
+ }
+ }
+
+
+// if (bytes & 0x80000000) {
+// flags |= SOUND_REPEAT;
+// } else {
+// }
+
+
+
+
+ soundData = (vu8* ) data;
+
+ SCHANNEL_CR(channel) = flags;
+ SCHANNEL_CR(channel + 2) = flags;
+
+
+
+ if (channel == 0) {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
+
+ TIMER0_CR = 0;
+ TIMER0_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER1_CR = 0;
+ TIMER1_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ playingSection = 0;
+ } else {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
+
+ TIMER2_CR = 0;
+ TIMER2_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER2_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER3_CR = 0;
+ TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ for (int r = 0; r < 4; r++) {
+// IPC->streamFillNeeded[r] = true;
+ }
+
+ IPC->streamPlayingSection = 0;
+ }
+
+
+
+// IPC->fillSoundFirstHalf = true;
+// IPC->fillSoundSecondHalf = true;
+// soundFirstHalf = true;
+
+ REG_IME = IME_ENABLE;
+}
+
+void stopSound(int chan) {
+ SCHANNEL_CR(chan) = 0;
+}
+
+void DummyHandler() {
+ REG_IF = REG_IF;
+}
+
+uint16 powerManagerWrite(uint32 command, u32 data, bool enable) {
+
+ uint16 result;
+ SerialWaitBusy();
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command | 0x80;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ result = REG_SPIDATA & 0xFF;
+
+
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = enable? (result | data): (result & ~data);
+ SerialWaitBusy();
+}
+
+/*
+void performSleep() {
+
+ powerManagerWrite(0, 0x30, true);
+
+ // Here, I set up a dummy interrupt handler, then trigger all interrupts.
+ // These are just aknowledged by the handler without doing anything else.
+ // Why? Because without it the sleep mode will only happen once, and then
+ // never again. I got the idea from reading the MoonShell source.
+ IME = 0;
+ u32 irq = (u32) IRQ_HANDLER;
+ IRQ_HANDLER = DummyHandler;
+ IF = ~0;
+ IME = 1;
+
+
+ // Now save which interrupts are enabled, then set only the screens unfolding
+ // interrupt to be enabled, so that the first interrupt that happens is the
+ // one I want.
+ int saveInts = IE;
+
+
+
+ IE = IRQ_TIMER0; // Screens unfolding interrupt
+
+ // Now call the sleep function in the bios
+ bool b;
+ do {
+ TIMER0_CR = 0;
+ TIMER0_DATA = TIMER_FREQ(20);
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_64;
+
+ swiDelay(100);
+
+ swiSleep();
+
+ swiDelay(100);
+
+ powerManagerWrite(0, 0x30, b = !b);
+ } while (!(TIMER0_CR & TIMER_ENABLE));
+
+ TIMER0_CR = 0;
+
+ // We're back from sleep, now restore the interrupt state and IRQ handler
+ IRQ_HANDLER = (void (*)()) irq;
+ IE = saveInts;
+ IF = ~0;
+ IME = 1;
+
+
+
+ powerManagerWrite(0, 0x30, false);
+}
+*/
+
+
+void performSleep() {
+ powerManagerWrite(0, 0x30, true);
+
+ IPC->performArm9SleepMode = true; // Tell ARM9 to sleep
+
+// u32 irq = (u32) IRQ_HANDLER;
+// IRQ_HANDLER = DummyHandler;
+// POWER_CR &= ~POWER_SOUND;
+
+// int saveInts = REG_IE;
+// REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
+// *((u32*) (0x0380FFF8)) = *((u32*) (0x0380FFF8)) | (REG_IE & REG_IF);
+// VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
+
+
+ int r = 0;
+ while ((REG_KEYXY & (1 << 7))) { // Wait for lid to open
+ swiDelay(1000000);
+ r++;
+ }
+
+// IRQ_HANDLER = (void (*)()) irq;
+ IPC->performArm9SleepMode = false; // Tell ARM9 to wake up
+// REG_IE = saveInts;
+
+// POWER_CR |= POWER_SOUND;
+
+ powerManagerWrite(0, 0x30, false);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+
+void InterruptHandler(void) {
+ static int heartbeat = 0;
+
+ if (REG_IF & IRQ_TIMER1) {
+
+ IPC->fillNeeded[playingSection] = true;
+ soundFilled[playingSection] = false;
+
+ if (playingSection == 3) {
+// IME = IME_DISABLED;
+
+ // while (SCHANNEL_CR(0) & SCHANNEL_ENABLE) {
+ // }
+// SCHANNEL_CR(0) &= ~SCHANNEL_ENABLE;
+
+// SCHANNEL_CR(0) |= SCHANNEL_ENABLE;
+// TIMER1_CR = 0;
+// TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ playingSection = 0;
+
+// IME = IME_ENABLED;
+ } else {
+ playingSection++;
+ }
+
+ IPC->playingSection = playingSection;
+
+/* for (int r = 0; r < 4; r++) {
+ //if ((!soundFilled[r]) && (!IPC->fillNeeded[playingSection])) {
+ memcpy((void *) (soundBuffer + (r * 1024)), (void *) (arm9Buffer + (r * 1024)), 1024);
+
+ vu16* p = (vu16 *) (soundBuffer);
+ //for (int t = 0; t < 2048; t++) {
+ // *(p + t) = (t & 1)? 0xF000: 0x0000;
+ //}
+ soundFilled[r] = true;
+ //}
+ }*/
+
+
+ REG_IF = IRQ_TIMER1;
+ }
+
+
+ if (REG_IF & IRQ_TIMER3) {
+ while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
+ IPC->adpcm.semaphore = true; // Lock the buffer structure to prevent clashing with the ARM7
+
+ IPC->streamFillNeeded[IPC->streamPlayingSection] = true;
+
+ if (IPC->streamPlayingSection == 3) {
+ IPC->streamPlayingSection = 0;
+ } else {
+ IPC->streamPlayingSection++;
+ }
+
+ REG_IF = IRQ_TIMER3;
+
+ IPC->adpcm.semaphore = false;
+ }
+
+
+// IPC->performArm9SleepMode = false;
+
+ // precalculate some values
+// static int16 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
+// static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
+// static int16 CNTRL_WIDTH = TOUCH_CNTRL_X2 - (TOUCH_CNTRL_X1 - 8);
+// static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - (TOUCH_CNTRL_Y1 - 8);
+
+
+
+
+
+ if (REG_IF & IRQ_VBLANK) {
+ uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0, batt=0, aux=0;
+ int t1=0, t2=0;
+ uint32 temp=0;
+ uint8 ct[sizeof(IPC->curtime)];
+
+
+ // Update the heartbeat
+ heartbeat++;
+
+ // Read the X/Y buttons and the /PENIRQ line
+ but = REG_KEYXY;
+ if (!(but & 0x40)) {
+ // Read the touch screen
+ touchPosition p = touchReadXY();
+
+// x = touchRead(TSC_MEASURE_X);
+ // y = touchRead(TSC_MEASURE_Y);
+
+ x = p.x;
+ y = p.y;
+
+ xpx = p.px;
+ ypx = p.py;
+
+// xpx = ( ((SCREEN_WIDTH -60) * x) / TOUCH_WIDTH ) - TOUCH_OFFSET_X;
+ // ypx = ( ((SCREEN_HEIGHT-60) * y) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
+
+// xpx = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH / TOUCH_WIDTH + (int16) (TOUCH_CNTRL_X1 - 8);
+ // ypx = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) (TOUCH_CNTRL_Y1 - 8);
+
+
+ z1 = touchRead(TSC_MEASURE_Z1);
+ z2 = touchRead(TSC_MEASURE_Z2);
+ }
+
+ if (but & (1 << 7)) { // Check if screen is folded
+ needSleep = true;
+ }
+
+
+ batt = touchRead(TSC_MEASURE_BATTERY);
+ aux = touchRead(TSC_MEASURE_AUX);
+
+ // Read the time
+ rtcGetTime((uint8 *)ct);
+ BCDToInteger((uint8 *)&(ct[1]), 7);
+
+ // Read the temperature
+ temp = touchReadTemperature(&t1, &t2);
+
+ // Update the IPC struct
+ IPC->heartbeat = heartbeat;
+ IPC->buttons = but;
+ IPC->touchX = x;
+ IPC->touchY = y;
+ IPC->touchXpx = xpx;
+ IPC->touchYpx = ypx;
+ IPC->touchZ1 = z1;
+ IPC->touchZ2 = z2;
+ IPC->battery = batt;
+ IPC->aux = aux;
+
+ for(u32 i=0; i<sizeof(ct); i++) {
+ IPC->curtime[i] = ct[i];
+ }
+
+ IPC->temperature = temp;
+ IPC->tdiode1 = t1;
+ IPC->tdiode2 = t2;
+
+
+
+ //sound code :)
+ TransferSound *snd = IPC->soundData;
+ IPC->soundData = 0;
+ if (snd) {
+ for (int i=0; i<snd->count; i++) {
+ s8 chan = getFreeSoundChannel();
+ if (snd->data[i].rate > 0) {
+ if (chan >= 0) {
+ startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
+ }
+ } else {
+ stopSound(-snd->data[i].rate);
+ }
+ }
+ }
+
+ REG_IF = IRQ_VBLANK;
+ }
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+
+int main(int argc, char ** argv) {
+ // Reset the clock if needed
+ rtcReset();
+
+ //enable sound
+ powerON(POWER_SOUND);
+ SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
+ IPC->soundData = 0;
+ IPC->reset = false;
+
+
+ for (int r = 0; r < 8; r++) {
+ IPC->adpcm.arm7Buffer[r] = (u8 *) malloc(512);
+ }
+
+ for (int r = 0; r < 4; r++) {
+ soundFilled[r] = false;
+ }
+
+
+ // Set up the interrupt handler
+ REG_IME = 0;
+ IRQ_HANDLER = &InterruptHandler;
+ REG_IE = IRQ_VBLANK | IRQ_TIMER1 | IRQ_TIMER3;
+ REG_IF = ~0;
+ DISP_SR = DISP_VBLANK_IRQ;
+ REG_IME = 1;
+
+
+
+ // Keep the ARM7 out of main RAM
+ while (1) {
+ if (needSleep) {
+ performSleep();
+ needSleep = false;
+ }
+// if (IPC->reset) {
+// swiSoftReset();
+// }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+/* ScummVMDS - Scumm Interpreter DS Port
+ * Copyright (C) 2002-2004 The ScummVM project and Neil Millstone
+ *
+ * This program 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 program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header: /cvsroot/scummvm/scummvm/backends/fs/fs.cpp,v 1.3.2.1 2004/12/18 02:33:52 fingolfin Exp $
+ */
+
+//////////////////////////////////////////////////////////////////////
+// Simple ARM7 stub (sends RTC, TSC, and X/Y data to the ARM 9)
+// -- joat
+// -- modified by Darkain and others
+//////////////////////////////////////////////////////////////////////
+
+
+#include <nds.h>
+
+#include <bios.h>
+#include <arm7/touch.h>
+#include <arm7/clock.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nds/scummvm_ipc.h>
+//////////////////////////////////////////////////////////////////////
+
+
+#define TOUCH_CAL_X1 (*(vs16*)0x027FFCD8)
+#define TOUCH_CAL_Y1 (*(vs16*)0x027FFCDA)
+#define TOUCH_CAL_X2 (*(vs16*)0x027FFCDE)
+#define TOUCH_CAL_Y2 (*(vs16*)0x027FFCE0)
+#define SCREEN_WIDTH 256
+#define SCREEN_HEIGHT 192
+s32 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
+s32 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
+s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH -60) * TOUCH_CAL_X1) / TOUCH_WIDTH ) - 28;
+s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT-60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;
+
+vu8* soundData;
+
+vu8* soundBuffer;
+vu8* arm9Buffer;
+bool soundFilled[4];
+
+int playingSection;
+
+bool needSleep = false;
+int temp;
+
+int adpcmBufferNum = 0;
+
+// those are pixel positions of the two points you click when calibrating
+#define TOUCH_CNTRL_X1 (*(vu8*)0x027FFCDC)
+#define TOUCH_CNTRL_Y1 (*(vu8*)0x027FFCDD)
+#define TOUCH_CNTRL_X2 (*(vu8*)0x027FFCE2)
+#define TOUCH_CNTRL_Y2 (*(vu8*)0x027FFCE3)
+
+
+//////////////////////////////////////////////////////////////////////
+
+/*
+void startSound(int sampleRate, const void* data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = (uint32)data;
+ SCHANNEL_LENGTH(channel) = bytes;
+ SCHANNEL_CR(channel) = SOUND_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
+}
+
+
+s8 getFreeSoundChannel() {
+ for (int i=0; i<16; i++) {
+ if ( (SCHANNEL_CR(i) & SOUND_ENABLE) == 0 ) return i;
+ }
+ return -1;
+}
+*/
+
+
+s8 getFreeSoundChannel() {
+// return 0;
+ for (int i=0; i<16; i++) {
+ if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 ) return i;
+ }
+ return -1;
+}
+
+void startSound(int sampleRate, const void* data, uint32 bytes, u8 channel=0, u8 vol=0x7F, u8 pan=63, u8 format=0) {
+ REG_IME = IME_DISABLE;
+
+ channel = getFreeSoundChannel();
+/* if (format == 2) {
+ channel = 1;
+ } else {
+ channel = 0;
+ }*/
+
+ if (channel > 1) channel = 1;
+
+ bytes &= ~7; // Multiple of 4 bytes!
+// bytes += 4;
+
+ SCHANNEL_CR(channel) = 0;
+ SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel) = ((uint32) (data));
+ SCHANNEL_LENGTH(channel) = ((bytes & 0x7FFFFFFF) >> 2);
+ SCHANNEL_REPEAT_POINT(channel) = 0;
+
+ SCHANNEL_CR(channel + 2) = 0;
+ SCHANNEL_TIMER(channel + 2) = SOUND_FREQ(sampleRate);
+ SCHANNEL_SOURCE(channel + 2) = ((uint32) (data));
+ SCHANNEL_LENGTH(channel + 2) = ((bytes & 0x7FFFFFFF) >> 2);
+ SCHANNEL_REPEAT_POINT(channel + 2) = 0;
+
+ uint32 flags = SCHANNEL_ENABLE | SOUND_VOL(vol) | SOUND_PAN(pan);
+
+ switch (format) {
+ case 1: {
+ flags |= SOUND_8BIT;
+ flags |= SOUND_REPEAT;// | (1 << 15);
+ break;
+ }
+
+ case 0: {
+ flags |= SOUND_16BIT;
+ flags |= SOUND_REPEAT;// | (1 << 15);
+ break;
+ }
+
+ case 2: {
+ flags |= SOUND_FORMAT_ADPCM;
+ flags |= SOUND_ONE_SHOT;// | (1 << 15);
+
+ SCHANNEL_SOURCE(channel) = (unsigned int) IPC->adpcm.buffer[0];
+ //bytes += 32;
+ SCHANNEL_LENGTH(channel) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
+
+ SCHANNEL_CR(channel + 1) = 0;
+ SCHANNEL_SOURCE(channel + 1) = (unsigned int) IPC->adpcm.buffer[0];
+ SCHANNEL_LENGTH(channel + 1) = (((bytes + 4) & 0x7FFFFFFF) >> 2);
+ SCHANNEL_TIMER(channel + 1) = SOUND_FREQ(sampleRate);
+ SCHANNEL_REPEAT_POINT(channel + 1) = 0;
+ SCHANNEL_CR(channel + 1) = flags;
+ temp = bytes;
+ adpcmBufferNum = 0;
+ break;
+ }
+ }
+
+
+// if (bytes & 0x80000000) {
+// flags |= SOUND_REPEAT;
+// } else {
+// }
+
+
+
+
+ soundData = (vu8* ) data;
+
+ SCHANNEL_CR(channel) = flags;
+ SCHANNEL_CR(channel + 2) = flags;
+
+
+
+ if (channel == 0) {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
+
+ TIMER0_CR = 0;
+ TIMER0_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER1_CR = 0;
+ TIMER1_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ playingSection = 0;
+ } else {
+ for (volatile int i = 0; i < 16384 * 2; i++) {
+ // Delay loop - this makes everything stay in sync!
+ }
+
+ TIMER2_CR = 0;
+ TIMER2_DATA = SOUND_FREQ(sampleRate) * 2;
+ TIMER2_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER3_CR = 0;
+ TIMER3_DATA = 65536 - ((bytes & 0x7FFFFFFF) >> 3); // Trigger four times during the length of the buffer
+ TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ for (int r = 0; r < 4; r++) {
+// IPC->streamFillNeeded[r] = true;
+ }
+
+ IPC->streamPlayingSection = 0;
+ }
+
+
+
+// IPC->fillSoundFirstHalf = true;
+// IPC->fillSoundSecondHalf = true;
+// soundFirstHalf = true;
+
+ REG_IME = IME_ENABLE;
+}
+
+void stopSound(int chan) {
+ SCHANNEL_CR(chan) = 0;
+}
+
+void DummyHandler() {
+ REG_IF = REG_IF;
+}
+
+uint16 powerManagerWrite(uint32 command, u32 data, bool enable) {
+
+ uint16 result;
+ SerialWaitBusy();
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command | 0x80;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = 0;
+ SerialWaitBusy();
+
+ result = REG_SPIDATA & 0xFF;
+
+
+
+ // Write the command and wait for it to complete
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz | (1 << 11);
+ REG_SPIDATA = command;
+ SerialWaitBusy();
+
+ // Write the second command and clock in the data
+ REG_SPICNT = SPI_ENABLE | SPI_BAUD_1MHz;
+ REG_SPIDATA = enable? (result | data): (result & ~data);
+ SerialWaitBusy();
+}
+
+/*
+void performSleep() {
+
+ powerManagerWrite(0, 0x30, true);
+
+ // Here, I set up a dummy interrupt handler, then trigger all interrupts.
+ // These are just aknowledged by the handler without doing anything else.
+ // Why? Because without it the sleep mode will only happen once, and then
+ // never again. I got the idea from reading the MoonShell source.
+ IME = 0;
+ u32 irq = (u32) IRQ_HANDLER;
+ IRQ_HANDLER = DummyHandler;
+ IF = ~0;
+ IME = 1;
+
+
+ // Now save which interrupts are enabled, then set only the screens unfolding
+ // interrupt to be enabled, so that the first interrupt that happens is the
+ // one I want.
+ int saveInts = IE;
+
+
+
+ IE = IRQ_TIMER0; // Screens unfolding interrupt
+
+ // Now call the sleep function in the bios
+ bool b;
+ do {
+ TIMER0_CR = 0;
+ TIMER0_DATA = TIMER_FREQ(20);
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_64;
+
+ swiDelay(100);
+
+ swiSleep();
+
+ swiDelay(100);
+
+ powerManagerWrite(0, 0x30, b = !b);
+ } while (!(TIMER0_CR & TIMER_ENABLE));
+
+ TIMER0_CR = 0;
+
+ // We're back from sleep, now restore the interrupt state and IRQ handler
+ IRQ_HANDLER = (void (*)()) irq;
+ IE = saveInts;
+ IF = ~0;
+ IME = 1;
+
+
+
+ powerManagerWrite(0, 0x30, false);
+}
+*/
+
+
+void performSleep() {
+ powerManagerWrite(0, 0x30, true);
+
+ IPC->performArm9SleepMode = true; // Tell ARM9 to sleep
+
+// u32 irq = (u32) IRQ_HANDLER;
+// IRQ_HANDLER = DummyHandler;
+// POWER_CR &= ~POWER_SOUND;
+
+// int saveInts = REG_IE;
+// REG_IE = (1 << 22) | IRQ_VBLANK; // Lid open
+// *((u32*) (0x0380FFF8)) = *((u32*) (0x0380FFF8)) | (REG_IE & REG_IF);
+// VBLANK_INTR_WAIT_FLAGS = IRQ_VBLANK;
+
+
+ int r = 0;
+ while ((REG_KEYXY & (1 << 7))) { // Wait for lid to open
+ swiDelay(1000000);
+ r++;
+ }
+
+// IRQ_HANDLER = (void (*)()) irq;
+ IPC->performArm9SleepMode = false; // Tell ARM9 to wake up
+// REG_IE = saveInts;
+
+// POWER_CR |= POWER_SOUND;
+
+ powerManagerWrite(0, 0x30, false);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+
+void InterruptHandler(void) {
+ static int heartbeat = 0;
+
+ if (REG_IF & IRQ_TIMER1) {
+
+ IPC->fillNeeded[playingSection] = true;
+ soundFilled[playingSection] = false;
+
+ if (playingSection == 3) {
+// IME = IME_DISABLED;
+
+ // while (SCHANNEL_CR(0) & SCHANNEL_ENABLE) {
+ // }
+// SCHANNEL_CR(0) &= ~SCHANNEL_ENABLE;
+
+// SCHANNEL_CR(0) |= SCHANNEL_ENABLE;
+// TIMER1_CR = 0;
+// TIMER1_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+
+ playingSection = 0;
+
+// IME = IME_ENABLED;
+ } else {
+ playingSection++;
+ }
+
+ IPC->playingSection = playingSection;
+
+/* for (int r = 0; r < 4; r++) {
+ //if ((!soundFilled[r]) && (!IPC->fillNeeded[playingSection])) {
+ memcpy((void *) (soundBuffer + (r * 1024)), (void *) (arm9Buffer + (r * 1024)), 1024);
+
+ vu16* p = (vu16 *) (soundBuffer);
+ //for (int t = 0; t < 2048; t++) {
+ // *(p + t) = (t & 1)? 0xF000: 0x0000;
+ //}
+ soundFilled[r] = true;
+ //}
+ }*/
+
+
+ REG_IF = IRQ_TIMER1;
+ }
+
+
+ if (REG_IF & IRQ_TIMER3) {
+ while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
+ IPC->adpcm.semaphore = true; // Lock the buffer structure to prevent clashing with the ARM7
+
+ IPC->streamFillNeeded[IPC->streamPlayingSection] = true;
+
+ if (IPC->streamPlayingSection == 3) {
+ IPC->streamPlayingSection = 0;
+ } else {
+ IPC->streamPlayingSection++;
+ }
+
+ REG_IF = IRQ_TIMER3;
+
+ IPC->adpcm.semaphore = false;
+ }
+
+
+// IPC->performArm9SleepMode = false;
+
+ // precalculate some values
+// static int16 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
+// static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
+// static int16 CNTRL_WIDTH = TOUCH_CNTRL_X2 - (TOUCH_CNTRL_X1 - 8);
+// static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - (TOUCH_CNTRL_Y1 - 8);
+
+
+
+
+
+ if (REG_IF & IRQ_VBLANK) {
+ uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0, batt=0, aux=0;
+ int t1=0, t2=0;
+ uint32 temp=0;
+ uint8 ct[sizeof(IPC->curtime)];
+
+
+ // Update the heartbeat
+ heartbeat++;
+
+ // Read the X/Y buttons and the /PENIRQ line
+ but = REG_KEYXY;
+ if (!(but & 0x40)) {
+ // Read the touch screen
+ touchPosition p = touchReadXY();
+
+// x = touchRead(TSC_MEASURE_X);
+ // y = touchRead(TSC_MEASURE_Y);
+
+ x = p.x;
+ y = p.y;
+
+ xpx = p.px;
+ ypx = p.py;
+
+// xpx = ( ((SCREEN_WIDTH -60) * x) / TOUCH_WIDTH ) - TOUCH_OFFSET_X;
+ // ypx = ( ((SCREEN_HEIGHT-60) * y) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
+
+// xpx = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH / TOUCH_WIDTH + (int16) (TOUCH_CNTRL_X1 - 8);
+ // ypx = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) (TOUCH_CNTRL_Y1 - 8);
+
+
+ z1 = touchRead(TSC_MEASURE_Z1);
+ z2 = touchRead(TSC_MEASURE_Z2);
+ }
+
+ if (but & (1 << 7)) { // Check if screen is folded
+ needSleep = true;
+ }
+
+
+ batt = touchRead(TSC_MEASURE_BATTERY);
+ aux = touchRead(TSC_MEASURE_AUX);
+
+ // Read the time
+ rtcGetTime((uint8 *)ct);
+ BCDToInteger((uint8 *)&(ct[1]), 7);
+
+ // Read the temperature
+ temp = touchReadTemperature(&t1, &t2);
+
+ // Update the IPC struct
+ IPC->heartbeat = heartbeat;
+ IPC->buttons = but;
+ IPC->touchX = x;
+ IPC->touchY = y;
+ IPC->touchXpx = xpx;
+ IPC->touchYpx = ypx;
+ IPC->touchZ1 = z1;
+ IPC->touchZ2 = z2;
+ IPC->battery = batt;
+ IPC->aux = aux;
+
+ for(u32 i=0; i<sizeof(ct); i++) {
+ IPC->curtime[i] = ct[i];
+ }
+
+ IPC->temperature = temp;
+ IPC->tdiode1 = t1;
+ IPC->tdiode2 = t2;
+
+
+
+ //sound code :)
+ TransferSound *snd = IPC->soundData;
+ IPC->soundData = 0;
+ if (snd) {
+ for (int i=0; i<snd->count; i++) {
+ s8 chan = getFreeSoundChannel();
+ if (snd->data[i].rate > 0) {
+ if (chan >= 0) {
+ startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
+ }
+ } else {
+ stopSound(-snd->data[i].rate);
+ }
+ }
+ }
+
+ REG_IF = IRQ_VBLANK;
+ }
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+
+int main(int argc, char ** argv) {
+ // Reset the clock if needed
+ rtcReset();
+
+ //enable sound
+ powerON(POWER_SOUND);
+ SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
+ IPC->soundData = 0;
+ IPC->reset = false;
+
+
+ for (int r = 0; r < 8; r++) {
+ IPC->adpcm.arm7Buffer[r] = (u8 *) malloc(512);
+ }
+
+ for (int r = 0; r < 4; r++) {
+ soundFilled[r] = false;
+ }
+
+
+ // Set up the interrupt handler
+ REG_IME = 0;
+ IRQ_HANDLER = &InterruptHandler;
+ REG_IE = IRQ_VBLANK | IRQ_TIMER1 | IRQ_TIMER3;
+ REG_IF = ~0;
+ DISP_SR = DISP_VBLANK_IRQ;
+ REG_IME = 1;
+
+
+
+ // Keep the ARM7 out of main RAM
+ while (1) {
+ if (needSleep) {
+ performSleep();
+ needSleep = false;
+ }
+// if (IPC->reset) {
+// swiSoftReset();
+// }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+