[Vm-dev] [commit][2675] update sound system to use semaphore signalling, support restarting etc

commits at squeakvm.org commits at squeakvm.org
Mon Jan 28 01:10:17 UTC 2013


Revision: 2675
Author:   rowledge
Date:     2013-01-27 17:10:14 -0800 (Sun, 27 Jan 2013)
Log Message:
-----------
update sound system to use semaphore signalling, support restarting etc

Modified Paths:
--------------
    trunk/platforms/RiscOS/misc/ToCopy/MakeFile
    trunk/platforms/RiscOS/misc/ToCopy/READMERIGHTNOW
    trunk/platforms/RiscOS/plugins/FilePlugin/sqFilePluginBasicPrims.c
    trunk/platforms/RiscOS/plugins/SoundPlugin/sqRPCSound.c
    trunk/platforms/RiscOS/vm/dsc/block
    trunk/platforms/RiscOS/vm/sqRPCEvents.c
    trunk/platforms/RiscOS/vm/sqRPCMain.c

Modified: trunk/platforms/RiscOS/misc/ToCopy/MakeFile
===================================================================
--- trunk/platforms/RiscOS/misc/ToCopy/MakeFile	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/misc/ToCopy/MakeFile	2013-01-28 01:10:14 UTC (rev 2675)
@@ -1,5 +1,5 @@
-# Project:   squeak
-# Make the pluginised VM for v3.9
+# Project:   sq38plugin
+# Make the pluginised VM for v3.8
 # Reworked to use VMMaker non-copying of platform & cross files
 # Add check for Squeak3D dir to optionally compile the Squeak3D plugin
 # Ditto for HostWindow and LocalePlugin
@@ -33,7 +33,7 @@
 HWTestFile= $(SPlug).HostWindowPlugin.dsc.HostWindowPlugin
 LocaleTestFile= $(Plug).LocalePlugin.dsc.LocalePlugin
 
-pluginList=B2DPlugin BitBltPlugin BMPReadWriterPlugin DSAPrims FFTPlugin FilePlugin FileCopyPlugin FloatArrayPlugin GeniePlugin JPEGReaderPlugin  LargeIntegers Matrix2x3Plugin MiscPrimitivePlugin RePlugin SecurityPlugin SocketPlugin SoundPlugin StarSqueakPlugin  SurfacePlugin ZipPlugin
+pluginList= ADPCMCodecPlugin B2DPlugin BitBltPlugin BMPReadWriterPlugin DSAPrims FFTPlugin FilePlugin FileCopyPlugin FloatArrayPlugin  GeniePlugin JPEGReaderPlugin  LargeIntegers Matrix2x3Plugin MiscPrimitivePlugin RePlugin ScratchPlugin SecurityPlugin SocketPlugin SoundCodecPrims SoundGenerationPlugin SoundPlugin StarSqueakPlugin  SurfacePlugin ZipPlugin
 
 # Final targets:
 all: plugins vm
@@ -86,11 +86,13 @@
 @.vm.o.ptrblock:   $(Sqk).ptrblkmap
         rinkptr $(rinkptrflags) $(Sqk).ptrblkmap  @.vm.o.ptrblock
 
-$(Sqk).ptrblkmap:    C:o.stubs @.vm.o.sqRPCMain @.vm.o.sqRPCWindows  $(PVM).dsc.block
+$(Sqk).ptrblkmap:    C:o.stubs @.vm.o.sqRPCMain @.vm.o.sqRPCWindows \
+			 @.vm.o.sqRPCEvents $(PVM).dsc.block
         copy $(PVM).dsc.block $* f~c
         extractsym -e $* C:o.stubs,*
         extractsym -e $* @.vm.o.sqRPCMain
         extractsym -e $* @.vm.o.sqRPCWindows
+        extractsym -e $* @.vm.o.sqRPCEvents
 
 ###########
 # ADPCMCodecPlugin make rule.
@@ -247,7 +249,6 @@
 # FileCopyPlugin.c is generated
 # FileCopyPlugin.h is in Cross
 # sqRPCFileCopy.c is in RiscOS
-
 ###########
 FileCopyPlugin:	$(SqPlugins).FileCopyPlugin
 	@echo done $*
@@ -286,8 +287,26 @@
 $(SPlug).FloatArrayPlugin.o.FloatArrayPlugin: $(SPlug).FloatArrayPlugin.c.FloatArrayPlugin $(PlHdr)
 	cc $(ccflags) -o $@ $*.c
 
+###########
+# FloatMath Plugin make rule.
+# Very simple, only the one source file
+###########
+FloatMathPlugin:	$(SqPlugins).FloatMathPlugin
+	@echo done $*
 
+$(SqPlugins).FloatMathPlugin:	$(SPlug).FloatMathPlugin.o.FloatMathPlugin\
+		$(SPlug).FloatMathPlugin.dsc.FloatMathPlugin \
+		$(Sqk).ptrblkmap
+	rink -o $(SqPlugins).FloatMathPlugin \
+		-h $(SPlug).FloatMathPlugin.dsc.FloatMathPlugin \
+		-m $(Sqk).ptrblkmap \
+		-a $(SPlug).FloatMathPlugin.o.FloatMathPlugin
 
+$(SPlug).FloatMathPlugin.o.FloatMathPlugin: $(SPlug).FloatMathPlugin.c.FloatMathPlugin $(PlHdr)
+	cc $(ccflags) -o $@ $*.c
+
+
+
 ###########
 # Genie Plugin make rule.
 # Very simple, only the one source file
@@ -374,7 +393,6 @@
 # LocalePlugin.c is generated
 # LocalePlugin.h is in Cross
 # sqRPCLocale.c is in RiscOS
-
 ###########
 LocalePlugin:	$(SqPlugins).LocalePlugin
 	@echo done $*
@@ -473,12 +491,36 @@
 
 
 ###########
+# Scratch Plugin make rule.
+# More complex - involves files from several sources
+# ScratchPlugin.c is generated
+# ScratchPlugin.h is in Cross
+# sqRPCScratch.c is in RiscOS
+###########
+ScratchPlugin:	$(SqPlugins).ScratchPlugin
+	@echo done $*
+
+$(SqPlugins).ScratchPlugin:	$(SPlug).ScratchPlugin.o.ScratchPlugin \
+		$(SPlug).ScratchPlugin.o.sqRPCScratchOps  \
+		$(SPlug).ScratchPlugin.dsc.ScratchPlugin \
+		$(Sqk).ptrblkmap
+	rink -o $(SqPlugins).ScratchPlugin \
+		-h $(SPlug).ScratchPlugin.dsc.ScratchPlugin \
+		-m $(Sqk).ptrblkmap \
+		-a $(SPlug).ScratchPlugin.o.ScratchPlugin \
+			$(SPlug).ScratchPlugin.o.sqRPCScratchOps
+
+$(SPlug).ScratchPlugin.o.ScratchPlugin: $(SPlug).ScratchPlugin.c.ScratchPlugin $(PlHdr)
+	cc $(ccflags) -I$(CPlug).ScratchPlugin -o $@ $*.c
+$(SPlug).ScratchPlugin.o.sqRPCScratchOps: $(PPlug).ScratchPlugin.c.sqRPCScratchOps  $(PlHdr)
+	cc $(ccflags) -I$(CPlug).ScratchPlugin -o $@ $(PPlug).ScratchPlugin.c.sqRPCScratchOps
+
+###########
 # Security Plugin make rule.
 # More complex - involves files from several sources
 # SecurityPlugin.c is generated
 # SecurityPlugin.h is in Cross
 # sqRPCSecurity.c is in RiscOS
-
 ###########
 SecurityPlugin:	$(SqPlugins).SecurityPlugin
 	@echo done $*
@@ -533,11 +575,57 @@
 	cc $(ccflags) -I$(PPlug).SocketPlugin,$(CPlug).SocketPlugin,$(Soklib) -o $@ $(PPlug).SocketPlugin.c.sqRPCNetPlugin
 
 ###########
+# SoundCodec Plugin make rule. Bizarrely called SoundCodecPrims in use.
+# More complex - involves files from several sources
+# SoundCodecPrims.c is generated
+# SoundCodecPrims.h is in Cross
+# sqSoundCodecPluginBasicPrims.c is in Cross
+###########
+SoundCodecPrims:	$(SqPlugins).SoundCodecPrims
+	@echo done $*
+
+$(SqPlugins).SoundCodecPrims:	$(SPlug).SoundCodecPrims.o.SoundCodecPrims \
+                $(SPlug).SoundCodecPrims.o.sqSoundCodecPluginBasicPrims \
+		$(SPlug).SoundCodecPrims.dsc.SoundCodecPrims \
+		$(Sqk).ptrblkmap
+	rink -o $(SqPlugins).SoundCodecPrims \
+		-h $(SPlug).SoundCodecPrims.dsc.SoundCodecPrims \
+		-m $(Sqk).ptrblkmap \
+		-a $(SPlug).SoundCodecPrims.o.SoundCodecPrims \
+		       $(SPlug).SoundCodecPrims.o.sqSoundCodecPluginBasicPrims
+
+$(SPlug).SoundCodecPrims.o.SoundCodecPrims: $(SPlug).SoundCodecPrims.c.SoundCodecPrims $(PlHdr)
+	cc $(ccflags) -I$(CPlug).SoundCodecPrims -o $@ $*.c
+$(SPlug).SoundCodecPrims.o.sqSoundCodecPluginBasicPrims: $(CPlug).SoundCodecPrims.c.sqSoundCodecPluginBasicPrims  $(PlHdr)
+	cc $(ccflags) -I$(CPlug).sqSoundCodecPluginBasicPrims -o $@ $(CPlug).SoundCodecPrims.c.sqSoundCodecPluginBasicPrims
+
+###########
+# SoundGeneration Plugin make rule.
+# Very simple, only the one source file
+###########
+SoundGenerationPlugin:	$(SqPlugins).SoundGenerationPlugin
+	@echo done $*
+
+$(SqPlugins).SoundGenerationPlugin:	$(SPlug).SoundGenerationPlugin.o.SoundGenerationPlugin \
+		$(SPlug).SoundGenerationPlugin.dsc.SoundGenerationPlugin \
+		$(Sqk).ptrblkmap
+	rink -o $(SqPlugins).SoundGenerationPlugin \
+		-h $(SPlug).SoundGenerationPlugin.dsc.SoundGenerationPlugin \
+		-m $(Sqk).ptrblkmap \
+		-a $(SPlug).SoundGenerationPlugin.o.SoundGenerationPlugin
+
+$(SPlug).SoundGenerationPlugin.o.SoundGenerationPlugin: $(SPlug).SoundGenerationPlugin.c.SoundGenerationPlugin $(PlHdr)
+	cc $(ccflags) -o $@ $*.c
+
+
+
+###########
 # Sound Plugin make rule.
 # More complex - involves files from several sources
 # SoundPlugin.c is generated
 # SoundPlugin.h is in Cross
 # sqRPCSound.c is in RiscOS
+
 ###########
 SoundPlugin:	$(SqPlugins).SoundPlugin
 	@echo done $*

Modified: trunk/platforms/RiscOS/misc/ToCopy/READMERIGHTNOW
===================================================================
--- trunk/platforms/RiscOS/misc/ToCopy/READMERIGHTNOW	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/misc/ToCopy/READMERIGHTNOW	2013-01-28 01:10:14 UTC (rev 2675)
@@ -1,16 +1,20 @@
 What to do next
 
-This zipfile contains the basic !Squeak application; before you can do anything useful with it you will need to
+This zipfile contains the basic !Squeak application for running Squeak systems from 2.8 up to 4.0; before you can do anything useful with it you will need to -
 
 1) fetch three files
 a) the image and changelog files.
   The image file is the recorded state of a Squeak system and the changelog is a matching audit trail of what code changes have been made since a certain point in time.  You can obtain those two files from the www.squeak.org site and visiting the downloads page and then going to the FTP archive - specifially ftp.squeak.org/4.0/Squeak4.0-basic.zip
 b) the sources file.
-  This is not the C/asm sources for the !Squeak application but the Smalltalk system code. This file is large and has all the Smalltalk code, all the class definitions and comments, for the system. It does not change very often and is not written to by the running system. It too can be obtained from the Squeak site, specifically ftp.squeak.org/4.0/SqueakV40.sources.gz
+  This is *not* the C/asm sources for the !Squeak application but the Smalltalk system code. This file is large and has all the Smalltalk code, all the class definitions and comments, for the system. It does not change very often and is not written to by the running system. It too can be obtained from the Squeak site, specifically ftp.squeak.org/4.0/SqueakV40.sources.gz
 2) unzip the Squeak4.0-basic.zip file.
   You should end up with a file Squeak4/0-basic/image of size 13478196 bytes, and another file Squeak4/0-basic/changes of size 694 bytes. Change the filetype of the Squeak4/0-basic/image file to faa (STimage). If you don't know how to do this you will need to read that fine manual for RISC OS.
 3) unzip the SqueakV40/sources/gz file - depending on exctly how you downloaded it you may find that it has already been decompressed. I don't know why that seems to happen. You should end up with SqueakV40/sources file of size 16748347 bytes.
 4) move the SqueakV40/sources file *into the !Squeak application*. If you don't know how to do this you will need to read that fine manual for RISC OS.
-5) While you have the aplication directory open, take a moment to *read the frickin !Help file*
+5) While you have the application directory open, take a moment to *read the frickin !Help file*
 
+To assist with getting keyboard input more effectively, you should download the DeepKeys module; open deepkeys2/zip and
+If you want to be able to play sounds from Squeak you will have to install the StreamManager & SharedSoundBuffer modules that make it possible; open ssb.zip
+and install it in the usual manner as described in the 'ReadFirst file within the package.
+
 Now, you have an installation that can run. Double-click on the 'Squeak4/0-basic/image' file and wait a moment (it might take ten seconds or depending your disc speed etc) for it to be read in and started up. You should see a medium sized window labelled with the path of the image file and containing a number of slightly odd looking windows. For further help, read the contents of the www.squeak.org site, join the mailing list(s) and ask questions.
\ No newline at end of file

Modified: trunk/platforms/RiscOS/plugins/FilePlugin/sqFilePluginBasicPrims.c
===================================================================
--- trunk/platforms/RiscOS/plugins/FilePlugin/sqFilePluginBasicPrims.c	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/plugins/FilePlugin/sqFilePluginBasicPrims.c	2013-01-28 01:10:14 UTC (rev 2675)
@@ -177,8 +177,7 @@
  * copy the fName into the new entry so the fName string can be freed later
  */
 OpenFileListEntry *entry;
-	entry = (OpenFileListEntry*) calloc(1, sizeof(OpenFileListEntry) + strlen(fN
-ame));
+	entry = (OpenFileListEntry*) calloc(1, sizeof(OpenFileListEntry) + strlen(fName));
 	if ( entry == NULL) {
 		return NULL;
 	}
@@ -233,8 +232,7 @@
 			 */
 			entry->refCt = -1;
 		}
-		PRINTF(("\\t file entry %s (%0x):%d\n",entry->name, entry->handle, entry
-->refCt));
+		PRINTF(("\\t file entry %s (%0x):%d\n",entry->name, entry->handle, entry->refCt));
 		return entry;
 	}
 	/* the file is not open so open it */
@@ -270,8 +268,7 @@
 
 /* primitive support */
 
-sqInt sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeF
-lag) {
+sqInt sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeFlag) {
 /* Opens the given file using the supplied sqFile structure
  * to record its state. Fails with no side effects if f is
  * already open. Files are always opened in binary mode;
@@ -286,8 +283,7 @@
 		FAIL();
 	}
 
-	if (!canonicalizeFilenameToString(sqFileName, sqFileNameSize, cFilename)) FA
-IL();
+	if (!canonicalizeFilenameToString(sqFileName, sqFileNameSize, cFilename)) FAIL();
 
 	PRINTF(("\\t sqFileOpen: canonicalized filename: %s\n", cFilename));
 
@@ -332,8 +328,7 @@
 	PRINTF(("\\t sqFileClose: failed\n"));
 		FAIL();
 	}
-	PRINTF(("\\t close file entry %s (%0x):%d\n",entry->name, entry->handle, ent
-ry->refCt));
+	PRINTF(("\\t close file entry %s (%0x):%d\n",entry->name, entry->handle, entry->refCt));
 	entry->refCt -= 2;
 	if (entry->refCt == 0) {
 		/* all uses closed, so close file and remove entry */
@@ -350,7 +345,6 @@
 
 sqInt sqFileAtEnd(SQFile *f) {
 /* Return true if the file's read/write head is at the end of the file.*/
-int pntr;
 
 	if (!sqFileValid(f)) {
 		PRINTF(("\\t sqFileAtEnd: attempt to query invalid file\n"));
@@ -361,15 +355,12 @@
 
 squeakFileOffsetType sqFileGetPosition(SQFile *f) {
 /* Return the current position of the file's read/write head. */
-int pntr;
-squeakFileOffsetType position;
 
 	if (!sqFileValid(f)) {
 		PRINTF(("\\t sqFileGetPosition: attempt to query invalid file\n"));
 		FAIL();
 	}
-	PRINTF(("\\t sqFileGetPosition: file %x at %d\n", FILE_HANDLE(f), FILE_POSIT
-ION(f)));
+	PRINTF(("\\t sqFileGetPosition: file %x at %d\n", FILE_HANDLE(f), FILE_POSITION(f)));
 	return FILE_POSITION(f);
 }
 
@@ -379,15 +370,13 @@
 		PRINTF(("\\t sqFileSetPosition: attempt to set invalid file\n"));
 		FAIL();
 	}
-	PRINTF(("\\t sqFileSetPosition: file %x to %d\n", FILE_HANDLE(f), position))
-;
+	PRINTF(("\\t sqFileSetPosition: file %x to %d\n", FILE_HANDLE(f), position));
 	FILE_POSITION(f) = position;
 	return true;
 }
 
 squeakFileOffsetType sqFileSize(SQFile *f) {
 /* Return the length of the given file. */
-int extent;
 	if (!sqFileValid(f)) {
 		PRINTF(("\\t sqFileSize: attempt to query invalid file\n"));
 		FAIL();
@@ -414,8 +403,7 @@
 	return true;
 }
 
-size_t sqFileReadIntoAt(SQFile *f, size_t count, char* byteArrayIndex, size_t st
-artIndex) {
+size_t sqFileReadIntoAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) {
 /* Read count bytes from the given file into byteArray starting at
  * startIndex. byteArray is the address of the first byte of a
  * Squeak bytes object (e.g. String or ByteArray). startIndex
@@ -433,13 +421,11 @@
 	xosgbpb_read_atw(FILE_HANDLE(f), dst, count, FILE_POSITION(f), &bytesUnread)
 ;
 	FILE_POSITION(f) += (count - bytesUnread);
-	PRINTF(("\\t sqFileReadIntoAt: read %d bytes of %d from file %x to %0x\n",co
-unt - bytesUnread, count, (int)FILE_HANDLE(f), (int)dst));
+	PRINTF(("\\t sqFileReadIntoAt: read %d bytes of %d from file %x to %0x\n", count - bytesUnread, count, (int)FILE_HANDLE(f), (int)dst));
 	return count - bytesUnread;
 }
 
-size_t sqFileWriteFromAt(SQFile *f, size_t count, char* byteArrayIndex, size_t s
-tartIndex) {
+size_t sqFileWriteFromAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) {
 /* Write count bytes to the given writable file starting at startIndex
  * in the given byteArray. (See comment in sqFileReadIntoAt for interpretation
  * of byteArray and startIndex).
@@ -453,11 +439,9 @@
 		FAIL();
 	}
 	src = (byte *) (byteArrayIndex + startIndex);
-	xosgbpb_write_atw(FILE_HANDLE(f), src, count, FILE_POSITION(f), &bytesUnwrit
-ten);
+	xosgbpb_write_atw(FILE_HANDLE(f), src, count, FILE_POSITION(f), &bytesUnwritten);
 	FILE_POSITION(f) += (count - bytesUnwritten);
-	PRINTF(("\\t sqFileWriteFromAt: wrote %d bytes of %d from %0x to file %x\n",
-count - bytesUnwritten, count, (int)src, (int)f->file));
+	PRINTF(("\\t sqFileWriteFromAt: wrote %d bytes of %d from %0x to file %x\n", count - bytesUnwritten, count, (int)src, (int)f->file));
 
 	xosargs_read_extw(FILE_HANDLE(f), &extent);
 	f->fileSize = extent;
@@ -469,14 +453,11 @@
 	return count;
 }
 
-sqInt sqFileRenameOldSizeNewSize(char* oldNameIndex, sqInt oldNameSize, char* ne
-wNameIndex, sqInt newNameSize) {
+sqInt sqFileRenameOldSizeNewSize(char* oldNameIndex, sqInt oldNameSize, char* newNameIndex, sqInt newNameSize) {
 char cNewName[MAXDIRNAMELENGTH];
 
-	if (!canonicalizeFilenameToString(oldNameIndex, oldNameSize, cFilename)) FAI
-L();
-	if (!canonicalizeFilenameToString(newNameIndex, newNameSize, cNewName)) FAIL
-();
+	if (!canonicalizeFilenameToString(oldNameIndex, oldNameSize, cFilename)) FAIL();
+	if (!canonicalizeFilenameToString(newNameIndex, newNameSize, cNewName)) FAIL();
 
 	if (xosfscontrol_rename(cFilename, cNewName) != NULL) {
 		FAIL();
@@ -491,8 +472,7 @@
 int size;
 fileswitch_attr attr;
 
-	if (!canonicalizeFilenameToString(sqFileName, sqFileNameSize, cFilename)) FA
-IL();;
+	if (!canonicalizeFilenameToString(sqFileName, sqFileNameSize, cFilename)) FAIL();;
 
 	PRINTF(("\\t sqFileDeleteNameSize: canonicalized name %s\n",cFilename));
 
@@ -509,7 +489,7 @@
 	return true;
 }
 
-sqInt sqFileThisSession() {
+sqInt sqFileThisSession(void) {
 	return thisSession;
 }
 

Modified: trunk/platforms/RiscOS/plugins/SoundPlugin/sqRPCSound.c
===================================================================
--- trunk/platforms/RiscOS/plugins/SoundPlugin/sqRPCSound.c	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/plugins/SoundPlugin/sqRPCSound.c	2013-01-28 01:10:14 UTC (rev 2675)
@@ -31,7 +31,7 @@
 // relied on reading Andrew Sellors excellent code for !RDPClient.
 // Thank you both.
 
-#define DEBUG
+// #define DEBUG
 
 #include "sq.h"
 #include "SoundPlugin.h"
@@ -40,16 +40,17 @@
 
 
 
-extern struct VirtualMachine * interpreterProxy;
-static unsigned sound_initialised = false;
-static int sound_handle = 0;
-static int sound_stream = 0;
-static unsigned sound_volume = 0; // this ought to be queriable from system
+extern struct		VirtualMachine * interpreterProxy;
+static unsigned		sound_initialised = false;
+static int			sound_handle = 0;
+static int			sound_stream = 0;
+static unsigned		sound_volume = 0; // this ought to be queriable from system
 static unsigned char *sound_global_buffer_data = NULL;
-static int sound_global_buffer_length = 0;
-static int sound_buffersize = 0;
-static unsigned sound_delayed_start = false;
-static unsigned int sound_delayed_start_time = 0;
+static int			sound_global_buffer_length = 0;
+static int			sound_buffersize = 0;
+static unsigned int * soundPollWordAddr = 0;
+static int			soundPollBit = 0;
+extern int			setupSoundSignalling(unsigned int ** addr, int * flagBit, int semIndex);
 
 
 /*********************/
@@ -129,19 +130,28 @@
 	_kernel_swi(SWI_XOS_Bit | SWI_SharedSoundBuffer_SampleRate, &r, &r);
 }
 
+static void ssb_streamend(int handle) {
+// closes the stream but allows the buffers already filled to play out
+	PRINTF(("ssb_streamend %08X\n", handle));
+	_kernel_swi_regs r;
+
+	r.r[0] = (int)handle;
+
+	_kernel_swi(SWI_XOS_Bit | SWI_SharedSoundBuffer_StreamEnd, &r, &r);
+}
+
 static void ssb_volume(int handle, unsigned int volume) {
 	_kernel_swi_regs r;
 
 	r.r[0] = (int)handle;
 	r.r[1] = (int)volume;
-	sound_volume = volume;
 
 	PRINTF(("ssb setsvolume\n"));
 	_kernel_swi(SWI_XOS_Bit | SWI_SharedSoundBuffer_Volume, &r, &r);
 }
 
 static unsigned ssb_getvolume(int handle) {
-// this really needs to be done with a query SWI
+// this really needs to be done with a query SWI. Currently not implemented though
 	PRINTF(("ssb getvolume\n"));
 	return sound_volume;
 }
@@ -201,6 +211,19 @@
 	_kernel_swi(SWI_XOS_Bit | SWI_StreamManager_SetDALimits, &r, &r);
 }
 
+static int * sm_srcpollword(int stream, int flags, unsigned int * pollwordptr, int bittoset) {
+	_kernel_swi_regs r;
+
+	r.r[0] = stream;
+	r.r[1] = flags; // only bit 0 has any effect
+	r.r[2] = (int)pollwordptr;
+	r.r[3] = bittoset;
+	PRINTF(("sm set src pollword stream: %d flag: %d ptr: %08X bit: %d\n", r.r[0], r.r[1], (int)(r.r[2]), r.r[3]));
+
+	_kernel_swi(SWI_XOS_Bit | SWI_StreamManager_SrcPollWord, &r, &r);
+	return (int *)r.r[0];
+}
+
 /**********************************/
 /* module initialization/shutdown */
 /**********************************/
@@ -214,8 +237,6 @@
 	sound_global_buffer_length = 0;
 	sound_buffersize = 0;
 
-	sound_delayed_start = false;
-	sound_delayed_start_time = 0;
 	PRINTF(("soundInit\n"));
 	return true;
 }
@@ -225,6 +246,7 @@
 	PRINTF(("soundShutdown\n"));
 
 	if(sound_initialised){
+		setupSoundSignalling(NULL, NULL, NULL);
 		ssb_closestream(sound_handle);
 		sound_initialised = false;
 	}
@@ -288,23 +310,25 @@
 int snd_Start(int frameCount, int samplesPerSec, int stereo, int semaIndex) {
 // Start the buffered sound output with the given buffer size, sample rate, stereo flag and semaphore index.
 	extern char sqTaskName[];
+
 	PRINTF(("snd_Start"));
 
-// just for now we won't mess with semaphores
-	if ( semaIndex ) {
-		PRINTF((" fails due to semaphore use\n"));
-		 return false;
-	}
+	// looks a bit strange but first thing we do is shut down any pre-existing sound stream
+	soundShutdown();
 	if(!sound_initialised) {
 		PRINTF((" initialising sound setup\n"));
+		// before bothering the sound sysem we check that RISC OS is ready for it
+		if ( !setupSoundSignalling(&soundPollWordAddr,&soundPollBit, semaIndex)) {
+			return false;
+		}
 		sm_setdalimits(SOUND_DA_MAX_SIZE, SOUND_HEAP_MAX_SIZE);
 		if(ssb_openstream(sqTaskName, true,BYTESFROMSAMPLES(frameCount), &sound_handle)) {
 			if(ssb_returnstreamhandle(sound_handle, &sound_stream)) {
 				sound_buffersize =  SOUND_BUFFER_SIZE(frameCount);
 				sm_setbuffer(sound_stream, sound_buffersize);
 				ssb_volume(sound_handle, 0xFFFFFFFF);
-				ssb_samplerate(sound_handle, samplesPerSec << 10);
-					// uses 1/1024Hz, so multiply given rate by 1024
+				ssb_samplerate(sound_handle, samplesPerSec << 10);// uses 1/1024Hz units
+				sm_srcpollword(sound_stream, 0, soundPollWordAddr, soundPollBit);
 				ssb_pause(sound_handle, true);
 				sound_initialised = true;
 			}
@@ -315,18 +339,28 @@
 		if(!sound_initialised){
 			sound_handle = 0;
 			sound_stream = 0;
+			setupSoundSignalling(NULL, NULL, NULL);
 			PRINTF(("snd_Start failed to init\n"));
 			return false;
 		}
 	}
 	PRINTF(("snd_Start initialised OK\n"));
+
 	return true;
 }
 
 int snd_Stop(void) {
 	PRINTF(("snd_Stop\n"));
-	// soundShutdown();
-	ssb_pause(sound_handle, true);
+	// cancel any further signalling
+	//	setupSoundSignalling(NULL, NULL, NULL);
+	//	// let the stream get to its end and then close
+	//	if ( sound_initialised) {
+	//		ssb_streamend(sound_handle);
+	//		sound_handle = 0;
+	//		sound_stream = 0;
+	//		sound_initialised = false;
+	//	}
+	soundShutdown();
 	return null;
 }
 
@@ -334,12 +368,8 @@
 void snd_Volume(double *left, double *right) {
 // used to GET the volume settings
 unsigned int leftVol, rightVol;
-	if (!sound_initialised) {
-		interpreterProxy->success(false);
-		PRINTF(("snd_Volume failed - sound not initialised\n"));
-		return;
-	}
 // get the volume and make doubles out if it
+// there ought to be a SWI for this but currently we have to simply record it manually
 	leftVol = sound_volume >> 16;
 	rightVol = sound_volume & 0xFFFF;
 	*left = leftVol  / 65535.0;
@@ -350,16 +380,14 @@
 void snd_SetVolume(double left, double right) {
 // used to SET the volume settings
 unsigned int leftVol, rightVol;
-	if (!sound_initialised) {
-		interpreterProxy->success(false);
-		PRINTF(("snd_SetVolume failed - sound not initialised\n"));
-		return;
-	}
 
 	leftVol = (unsigned int)((left > 1.0 ? 1.0 : left) * 0xFFFF) & 0xFFFF;
 	rightVol = (unsigned int)((right > 1.0 ? 1.0 : right) * 0xFFFF) & 0xFFFF;
+	sound_volume = (leftVol << 16) | rightVol;
 	PRINTF(("snd_SetVolume %f:%f\n", left, right));
-	ssb_volume(sound_handle, (leftVol << 16) | rightVol);
+	if (sound_initialised) {
+		ssb_volume(sound_handle, sound_volume) ;
+	}
 }
 
 /***************/

Modified: trunk/platforms/RiscOS/vm/dsc/block
===================================================================
--- trunk/platforms/RiscOS/vm/dsc/block	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/vm/dsc/block	2013-01-28 01:10:14 UTC (rev 2675)
@@ -21,3 +21,4 @@
 xscsifs_drives
 xadfs_drives
 xterritory_read_current_time_zone
+uri_dispatch

Modified: trunk/platforms/RiscOS/vm/sqRPCEvents.c
===================================================================
--- trunk/platforms/RiscOS/vm/sqRPCEvents.c	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/vm/sqRPCEvents.c	2013-01-28 01:10:14 UTC (rev 2675)
@@ -29,11 +29,12 @@
 // and passes them up to Squeak
 // It makes use of the Celerica !!DeepKeys module
 // define this to get lots of debug notifiers
-//#define DEBUG
+// #define DEBUG
 
 #include "oslib/os.h"
 #include "oslib/osbyte.h"
 #include "oslib/osfscontrol.h"
+#include "oslib/osmodule.h"
 #include "oslib/wimp.h"
 #include "oslib/wimpspriteop.h"
 #include "oslib/colourtrans.h"
@@ -42,7 +43,7 @@
 
 wimp_block			wimpPollBlock;
 wimp_event_no		wimpPollEvent;
-int					wimpPollWord;
+int					wimpPollWord = 0;
 int					windowActive = false;
 extern int			pointerBuffer[];
 extern os_coord		pointerOffset;
@@ -114,7 +115,9 @@
 extern int		forceInterruptCheck(void);
 extern int		ioIconiseWindow(wimp_message * wblock);
 
-void (*socketPollFunction)(int delay, int extraFd) = null;
+void			(*socketPollFunction)(int delay, int extraFd) = null;
+int				soundBufferEmptySemaphoreIndex = 0;
+unsigned int *	soundPollWordPtr = 0;
 
 
 /* Squeak expects to get kbd modifiers as the top 4bits of the 8bit char code,
@@ -125,16 +128,16 @@
  * Notice how Macish this is!
 */
 
-#define		MacDownCursor	31
-#define		MacUpCursor	30
-#define		MacLeftCursor	28
-#define		MacRightCursor	29
-#define		MacHomeKey	1
-#define		MacEndKey	4
-#define		MacInsertKey	5
-#define		MacDeleteKey	8
-#define		MacPageUpKey	11
-#define		MacPageDownKey	12
+#define			MacDownCursor	31
+#define			MacUpCursor	30
+#define			MacLeftCursor	28
+#define			MacRightCursor	29
+#define			MacHomeKey	1
+#define			MacEndKey	4
+#define			MacInsertKey	5
+#define			MacDeleteKey	8
+#define			MacPageUpKey	11
+#define			MacPageDownKey	12
 
 unsigned char keymap[0x68] = {
 /* 0x00 Esc */ 0x1b ,
@@ -245,27 +248,27 @@
 
 
 /*** Functions ***/
-	 void DisplayPixmap(wimp_draw * wblock);
-extern	 void DisplayModeChanged(void);
-	 void DoNothing(void);
-	  int HandleEvents(void);
-	 void KeyPressed( wimp_key * wblock);
-	 void KeyBufAppend(int key);
-	 void UserMessage(wimp_message * wblock);
-	 void MouseButtons( wimp_pointer * wblock);
-	 void PointerEnterWindow(wimp_entering *wblock);
-	 void PointerLeaveWindow(wimp_leaving *wblock);
-	 void WindowClose(wimp_close * wblock);
-	 void WindowOpen( wimp_open * wblock);
-extern	 void claimCaret(wimp_pointer * wblock);
-extern	 void receivedClaimEntity(wimp_message * wblock);
-extern	 void receivedDataRequest(wimp_message * wmessage);
-extern	 void receivedDataSave(wimp_message * wblock);
-extern	 void receivedDataSaveAck(wimp_message * wblock);
-	 void EventBufAppendKey( int key, int buttons, int x, int y, int windowIndex);
-	 void EventBufAppendMouse(int buttons, int modifiers, int x, int y, int windowIndex);
-extern	 void platReportError( os_error * e);
-void EventBufAppendWindow( int action, int left, int top, int right, int bottom,int windowIndex);
+void			DisplayPixmap(wimp_draw * wblock);
+extern void		DisplayModeChanged(void);
+void			DoNothing(void);
+int				HandleEvents(void);
+void			KeyPressed( wimp_key * wblock);
+void			KeyBufAppend(int key);
+void			UserMessage(wimp_message * wblock);
+void			MouseButtons( wimp_pointer * wblock);
+void			PointerEnterWindow(wimp_entering *wblock);
+void			PointerLeaveWindow(wimp_leaving *wblock);
+void			WindowClose(wimp_close * wblock);
+void			WindowOpen( wimp_open * wblock);
+extern void		claimCaret(wimp_pointer * wblock);
+extern void		receivedClaimEntity(wimp_message * wblock);
+extern void		receivedDataRequest(wimp_message * wmessage);
+extern void		receivedDataSave(wimp_message * wblock);
+extern void		receivedDataSaveAck(wimp_message * wblock);
+void			EventBufAppendKey( int key, int buttons, int x, int y, int windowIndex);
+void			EventBufAppendMouse(int buttons, int modifiers, int x, int y, int windowIndex);
+extern void		platReportError( os_error * e);
+void			EventBufAppendWindow( int action, int left, int top, int right, int bottom,int windowIndex);
 
 void setSocketPollFunction(int spf ) {
 /* called from SocketPlugin init code */
@@ -273,6 +276,57 @@
 	PRINTF(( "\\t socketPoll %0x\n", (int)socketPollFunction));
 }
 
+void initialiseSoundPollword(void) {
+// create an RMA allocationfor the sound pollword to live in
+os_error *e;
+	if (!soundPollWordPtr) {
+		// we need to allocate some memory in RMA space and 0 it
+		if ((e = xosmodule_alloc(4, (void **)&soundPollWordPtr)) != NULL) {
+			// damn, failed
+			platReportError(e);
+			return;
+		}
+		*soundPollWordPtr = 0;
+		PRINTF(("allocated pollword block %08X (%d)\n", (int)soundPollWordPtr, *soundPollWordPtr));
+	}
+}
+
+void shutdownSoundPollword(void) {
+// free the RMA space used for the sound pollword
+os_error *e;
+	if (soundPollWordPtr) {
+		if ((e = xosmodule_free(soundPollWordPtr)) != NULL) {
+			platReportError(e);
+		};
+		soundPollWordPtr = 0;
+	}
+	return;
+}
+
+int setupSoundSignalling(unsigned int ** addr, int * flagBit, int semIndex) {
+// set the the sound buffer flagword address from an RMA allocation.
+// set the bit in that flaword that the sound system should use (1 will do for now)
+// we also have to keep track of the semaphore to signal when the pollword is
+// triggered. For now, we'll use this fn to let the sound code tell us
+// what it is
+	if (addr == NULL) {
+		// if the passed in addr is NULL, we're not polling anymore
+		soundBufferEmptySemaphoreIndex = 0;
+		return true;
+	}
+
+	if (!soundPollWordPtr) {
+		// we were unabel to make the pollword RMA area, so fail
+		return false;
+	}
+	// pass in the pollword ptr
+	*addr = soundPollWordPtr;
+	*flagBit = 1;
+	soundBufferEmptySemaphoreIndex = semIndex;
+	PRINTF(("setupSoundSignalling ptr: %08X sem: %d\n", soundPollWordPtr, soundBufferEmptySemaphoreIndex));
+	return true;
+}
+
 void setMetaKeyOptions(int swap) {
 	if (swap) {
 		user_LCTL_KEY = wimp_DEEPKEY_RCTL;
@@ -420,33 +474,46 @@
 			/* null means no more interesting events,
 			   so return false*/
 			return false ; break;
-		case wimp_REDRAW_WINDOW_REQUEST	:
+		case wimp_REDRAW_WINDOW_REQUEST:
 			PRINTF(("\\t display\n"));
-			DisplayPixmap(&(pollBlock->redraw)); break;
-		case wimp_OPEN_WINDOW_REQUEST	:
-			WindowOpen(&(pollBlock->open)); break;
-		case wimp_CLOSE_WINDOW_REQUEST	:
-			WindowClose(&(pollBlock->close)); break;
-		case wimp_POINTER_LEAVING_WINDOW :
-			PointerLeaveWindow(&(pollBlock->leaving)); break;
+			DisplayPixmap(&(pollBlock->redraw));
+			break;
+		case wimp_OPEN_WINDOW_REQUEST:
+			WindowOpen(&(pollBlock->open));
+			break;
+		case wimp_CLOSE_WINDOW_REQUEST:
+			WindowClose(&(pollBlock->close));
+			break;
+		case wimp_POINTER_LEAVING_WINDOW:
+			PointerLeaveWindow(&(pollBlock->leaving));
+			break;
 		case wimp_POINTER_ENTERING_WINDOW:
-			PointerEnterWindow(&(pollBlock->entering)); break;
-		case wimp_MOUSE_CLICK			:
-			MouseButtons(&(pollBlock->pointer)); break;
-		case wimp_USER_DRAG_BOX			:
-			DoNothing(); break;
-		case wimp_KEY_PRESSED			:
-			KeyPressed( &(pollBlock->key)); break;
-		case wimp_MENU_SELECTION		:
-			DoNothing(); break;
-		case wimp_SCROLL_REQUEST		:
-			DoNothing(); break;
-		case wimp_USER_MESSAGE			:
-			UserMessage(&(pollBlock->message)); break;
-		case wimp_USER_MESSAGE_RECORDED		:
-			UserMessage(&(pollBlock->message)); break;
-		case wimp_USER_MESSAGE_ACKNOWLEDGE	:
-			UserMessage(&(pollBlock->message)); break;
+			PointerEnterWindow(&(pollBlock->entering));
+			break;
+		case wimp_MOUSE_CLICK:
+			MouseButtons(&(pollBlock->pointer));
+			break;
+		case wimp_USER_DRAG_BOX:
+			DoNothing();
+			break;
+		case wimp_KEY_PRESSED:
+			KeyPressed( &(pollBlock->key));
+			break;
+		case wimp_MENU_SELECTION:
+			DoNothing();
+			break;
+		case wimp_SCROLL_REQUEST:
+			DoNothing();
+			break;
+		case wimp_USER_MESSAGE:
+			UserMessage(&(pollBlock->message));
+			break;
+		case wimp_USER_MESSAGE_RECORDED:
+			UserMessage(&(pollBlock->message));
+			break;
+		case wimp_USER_MESSAGE_ACKNOWLEDGE:
+			UserMessage(&(pollBlock->message));
+			break;
 	}
 	return true;
 }
@@ -460,6 +527,21 @@
 	}
 }
 
+int HandleSoundPoll(void) {
+// if there is a sound semaphore set up and a non-0 sound pollword address and the sound pollword
+// has been tickled, 0 out the pollword and signal the semaphore
+	if ( soundBufferEmptySemaphoreIndex && (int)soundPollWordPtr) {
+		int pollwd;
+		pollwd = *soundPollWordPtr;
+PRINTF(("HandleSoundPoll: %d\n", pollwd));
+		if (pollwd) {
+			*soundPollWordPtr = 0;
+			signalSemaphoreWithIndex(soundBufferEmptySemaphoreIndex);
+			PRINTF(("signal sound semaphore:%d pollword: %d\n", soundBufferEmptySemaphoreIndex, pollwd));
+		}
+	}
+}
+
 #if 0
 /* this is pretty much obsolete - we can't do microsecond delays and
  * anything longer just slows Squeak down horribly */
@@ -495,7 +577,7 @@
 	//PRINTF(("\\t HandleEventsWithWait %d\n", pollDelay));
 	HandleMousePoll();
 	HandleSocketPoll(microSecondsToDelay);
-	do { xwimp_poll_idle((wimp_MASK_POLLWORD
+	do { xwimp_poll_idle(wimp_MASK_POLLWORD
 		| wimp_MASK_GAIN
 		| wimp_MASK_LOSE
 		| wimp_SAVE_FP) ,
@@ -511,6 +593,7 @@
 /* track buttons and pos, send event if any change */
 	HandleMousePoll();
 	HandleSocketPoll(0);
+	HandleSoundPoll();
 	//PRINTF(("\\t HandleEvents\n"));
 	/* One poll to bring them all.
 	 * One poll to find them.
@@ -733,7 +816,11 @@
 	} else {
 		KeyBufAppend(keystate | ((modState)<<8));
 	}
-	PRINTF(("\\t KeyPressed .c%c .d%x keystate(%d-%d) w: %d\n", dblock->c, (dblock->deepkey)>>wimp_DEEPKEY_KEYNUMSHIFT, keystate, modState, thisWindowIndex));
+	PRINTF(("\\t KeyPressed .c%c .d%x keystate(%d-%d) w: %d\n",
+		 dblock->c,
+		 (dblock->deepkey)>>wimp_DEEPKEY_KEYNUMSHIFT,
+		 keystate, modState,
+		 thisWindowIndex));
 }
 
 void UserMessage(wimp_message * wblock) {

Modified: trunk/platforms/RiscOS/vm/sqRPCMain.c
===================================================================
--- trunk/platforms/RiscOS/vm/sqRPCMain.c	2013-01-24 20:08:41 UTC (rev 2674)
+++ trunk/platforms/RiscOS/vm/sqRPCMain.c	2013-01-28 01:10:14 UTC (rev 2675)
@@ -248,8 +248,10 @@
 extern  wimp_icon_create sqIconBarIcon;
 extern void		GetDisplayParameters(void);
 extern void		SetupWindowTitle(void);
-extern void SetDefaultPointer(void);
-extern void InitRootWindow(void);
+extern void		SetDefaultPointer(void);
+extern void		InitRootWindow(void);
+extern int		setupSoundSignalling(unsigned int ** addr, int * flagBit, int semIndex);
+extern void		initialiseSoundPollword(void);
 int width;
 
 	SetDefaultPointer();
@@ -266,7 +268,7 @@
 		strncpy(sqTaskName, taskNameArg, sqTaskNameLength );
 	}
 
-	if ((e = xwimp_initialise (wimp_VERSION_RO35,
+	if ((e = xwimp_initialise (wimp_VERSION_RO38,
 					sqTaskName,
 					(wimp_message_list*)&importantWimpMessages,
 					&actualOSLevel,
@@ -308,8 +310,8 @@
 	SetupWindowTitle();
 
 	setFPStatus(0);
-
 	setTimer();
+	initialiseSoundPollword();
 
 	return true;
 }
@@ -336,6 +338,7 @@
 */
 extern void ioShutdownAllModules(void);
 extern void SetDefaultPointer(void);
+extern void shutdownSoundPollword(void);
 
 	ioShutdownAllModules();
 
@@ -346,11 +349,11 @@
 		xosdynamicarea_delete ( SqueakDisplayDA );
 	PRINTF(("\\t exiting Squeak\n"));
 	if ( (int)logfile > 0) fclose( logfile);
+	shutdownSoundPollword();
 }
 
 usqInt millisecondTimerValue(void) {
 /* return the raw unsigned value of the millsecond time for internal VM use */
-_kernel_swi_regs regs;
 	return (usqInt)*timerValPtr;
 }
 



More information about the Vm-dev mailing list